--- .gitignore | 47 Documentation/DocBook/Makefile | 3 Documentation/DocBook/kgdb.tmpl | 234 Documentation/arm/STM-Nomadik/HOWTO-add_newboard.txt | 111 Documentation/arm/STM-Nomadik/HOWTO-nfsboot.txt | 106 Documentation/arm/STM-Nomadik/debug_strategy.txt | 66 Documentation/arm/STM-Nomadik/dma_user_guide.txt | 420 Documentation/arm/STM-Nomadik/faqs.txt | 53 Documentation/arm/STM-Nomadik/gpio_user_guide.txt | 140 Documentation/arm/STM-Nomadik/irq_usrguide.txt | 171 Documentation/arm/STM-Nomadik/power_management.txt | 122 MAINTAINERS | 9 Makefile | 18 arch/arm/Kconfig | 25 arch/arm/Makefile | 34 arch/arm/common/rtctime.c | 4 arch/arm/configs/ndk10_defconfig | 1205 + arch/arm/configs/ndk15_defconfig | 1221 + arch/arm/configs/ndk15b06_defconfig | 1221 + arch/arm/configs/nhk15_defconfig | 1458 + arch/arm/kernel/Makefile | 1 arch/arm/kernel/armksyms.c | 14 arch/arm/kernel/dma.c | 1 arch/arm/kernel/entry-armv.S | 2 arch/arm/kernel/irq.c | 12 arch/arm/kernel/kgdb-jmp.S | 30 arch/arm/kernel/kgdb.c | 208 arch/arm/kernel/setup.c | 5 arch/arm/kernel/traps.c | 11 arch/arm/lib/Makefile | 2 arch/arm/lib/gcclib.h | 25 arch/arm/lib/longlong.h | 184 arch/arm/lib/udivdi3.c | 246 arch/arm/mach-nomadik/Kconfig-nomadik | 267 arch/arm/mach-nomadik/Makefile | 166 arch/arm/mach-nomadik/Makefile.boot | 4 arch/arm/mach-nomadik/clock.c | 127 arch/arm/mach-nomadik/clock.h | 25 arch/arm/mach-nomadik/cpu.c | 293 arch/arm/mach-nomadik/create_kconfig.pl | 55 arch/arm/mach-nomadik/deep_sleep.S | 655 arch/arm/mach-nomadik/dfs.S | 355 arch/arm/mach-nomadik/dma.c | 1337 + arch/arm/mach-nomadik/fsmc.c | 113 arch/arm/mach-nomadik/gpio.c | 916 + arch/arm/mach-nomadik/irq.c | 231 arch/arm/mach-nomadik/l2cc.c | 152 arch/arm/mach-nomadik/msp.c | 2062 ++ arch/arm/mach-nomadik/msp.h | 383 arch/arm/mach-nomadik/mtu.c | 589 arch/arm/mach-nomadik/ndk10_cut_a1_Kconfig | 28 arch/arm/mach-nomadik/ndk10_cut_b06_Kconfig | 35 arch/arm/mach-nomadik/ndk10_cut_b0_Kconfig | 35 arch/arm/mach-nomadik/ndk10_devices.c | 1225 + arch/arm/mach-nomadik/ndk15_devices.c | 1001 + arch/arm/mach-nomadik/ndk15_rev2_b_03_Kconfig | 37 arch/arm/mach-nomadik/ndk15_rev2_b_05_Kconfig | 37 arch/arm/mach-nomadik/ndk15_rev2_b_06_Kconfig | 42 arch/arm/mach-nomadik/ndk15_rev3_c_02_Kconfig | 42 arch/arm/mach-nomadik/ndk15c02_devices.c | 1023 + arch/arm/mach-nomadik/nhk15_Kconfig | 36 arch/arm/mach-nomadik/nhk15_devices.c | 1009 + arch/arm/mach-nomadik/normal.S | 199 arch/arm/mach-nomadik/pm.c | 79 arch/arm/mach-nomadik/power.c | 1316 + arch/arm/mach-nomadik/rtc.c | 327 arch/arm/mach-nomadik/sleep.c | 280 arch/arm/mach-nomadik/slow.S | 199 arch/arm/mach-nomadik/soft_sleep.S | 206 arch/arm/mach-nomadik/ssp.c | 930 + arch/arm/mach-nomadik/stn8810_devices.c | 1071 + arch/arm/mach-nomadik/stn8815_devices.c | 1971 ++ arch/arm/mach-nomadik/timer.c | 366 arch/arm/mm/Kconfig | 23 arch/arm/mm/extable.c | 7 arch/arm/mm/init.c | 1 arch/arm/mm/proc-arm926.S | 30 arch/arm/oprofile/common.c | 3 drivers/Makefile | 2 drivers/char/keyboard.c | 1 drivers/cpufreq/Kconfig | 4 drivers/hwmon/Kconfig | 13 drivers/hwmon/Makefile | 1 drivers/hwmon/lis3lv02dl.c | 489 drivers/i2c/Kconfig | 1 drivers/i2c/Makefile | 3 drivers/i2c/busses/Kconfig | 10 drivers/i2c/busses/Makefile | 22 drivers/i2c/busses/i2c-nomadik.c | 1250 + drivers/i2c/busses/i2c-nomadik.h | 93 drivers/i2c/busses/i2c-stn8810.c | 1723 ++ drivers/i2c/busses/i2c-stn8815.c | 1817 ++ drivers/i2c/chips/Kconfig | 9 drivers/i2c/chips/Makefile | 6 drivers/i2c/chips/epio-nomadik.c | 195 drivers/input/input.c | 13 drivers/input/keyboard/Kconfig | 13 drivers/input/keyboard/Makefile | 7 drivers/input/keyboard/kpd-nomadik.c | 359 drivers/input/touchscreen/Kconfig | 20 drivers/input/touchscreen/Makefile | 8 drivers/input/touchscreen/touchp-nomadik.c | 755 + drivers/input/touchscreen/touchp2003-nomadik.c | 566 drivers/media/Kconfig | 2 drivers/media/Makefile | 4 drivers/media/nomadik_mm/Kconfig | 23 drivers/media/nomadik_mm/Makefile | 8 drivers/media/nomadik_mm/hcl/hloader/hloader.c | 3632 ++++ drivers/media/nomadik_mm/hcl/hloader/hloader.h | 170 drivers/media/nomadik_mm/hcl/hloader/hloader_p.h | 451 drivers/media/nomadik_mm/hcl/include/debug.h | 316 drivers/media/nomadik_mm/hcl/include/hcl_defs.h | 290 drivers/media/nomadik_mm/hcl/include/hloader.h | 170 drivers/media/nomadik_mm/hcl/include/mupoc_mapping.h | 1761 ++ drivers/media/nomadik_mm/hcl/include/platform_os.h | 72 drivers/media/nomadik_mm/hcl/include/sva.h | 2148 ++ drivers/media/nomadik_mm/hcl/saa/audio_services.c | 142 drivers/media/nomadik_mm/hcl/saa/audio_services.h | 39 drivers/media/nomadik_mm/hcl/saa/ha_api_params.h | 1064 + drivers/media/nomadik_mm/hcl/saa/ha_codec_info.h | 204 drivers/media/nomadik_mm/hcl/saa/ha_codec_params.h | 686 drivers/media/nomadik_mm/hcl/saa/ha_effect_info.h | 122 drivers/media/nomadik_mm/hcl/saa/ha_effect_params.h | 1342 + drivers/media/nomadik_mm/hcl/saa/ha_hcl_fw_interface.h | 163 drivers/media/nomadik_mm/hcl/saa/hti.c | 271 drivers/media/nomadik_mm/hcl/saa/hti.h | 159 drivers/media/nomadik_mm/hcl/saa/hti_protocol.h | 134 drivers/media/nomadik_mm/hcl/saa/saa.c | 2538 +++ drivers/media/nomadik_mm/hcl/saa/saa.h | 306 drivers/media/nomadik_mm/hcl/saa/saa_base.c | 557 drivers/media/nomadik_mm/hcl/saa/saa_hwp.h | 275 drivers/media/nomadik_mm/hcl/saa/saa_irq.c | 432 drivers/media/nomadik_mm/hcl/saa/saap.h | 160 drivers/media/nomadik_mm/hcl/sva/common/sva_capabilities.c | 63 drivers/media/nomadik_mm/hcl/sva/common/sva_capabilities.h | 46 drivers/media/nomadik_mm/hcl/sva/common/sva_fifo.h | 335 drivers/media/nomadik_mm/hcl/sva/common/sva_hwp.h | 646 drivers/media/nomadik_mm/hcl/sva/common/sva_internalneeds.c | 131 drivers/media/nomadik_mm/hcl/sva/common/sva_internalneeds.h | 61 drivers/media/nomadik_mm/hcl/sva/common/sva_service.h | 337 drivers/media/nomadik_mm/hcl/sva/common/sva_timemgt.c | 486 drivers/media/nomadik_mm/hcl/sva/common/sva_timemgt.h | 80 drivers/media/nomadik_mm/hcl/sva/common/sva_timemgtp.h | 49 drivers/media/nomadik_mm/hcl/sva/common/svap.h | 188 drivers/media/nomadik_mm/hcl/sva/decode/h264/sva_dc_h264.c | 3030 ++++ drivers/media/nomadik_mm/hcl/sva/decode/h264/sva_dc_h264.h | 110 drivers/media/nomadik_mm/hcl/sva/decode/h264/sva_dc_h264_dpb.c | 3101 ++++ drivers/media/nomadik_mm/hcl/sva/decode/h264/sva_dc_h264_dpb.h | 232 drivers/media/nomadik_mm/hcl/sva/decode/h264/sva_dc_h264_dpbp.h | 98 drivers/media/nomadik_mm/hcl/sva/decode/h264/sva_dc_h264_slicemap.c | 312 drivers/media/nomadik_mm/hcl/sva/decode/h264/sva_dc_h264_slicemap.h | 53 drivers/media/nomadik_mm/hcl/sva/decode/h264/sva_dc_h264p.h | 156 drivers/media/nomadik_mm/hcl/sva/decode/mpeg2/sva_dc_mpeg2.c | 2126 ++ drivers/media/nomadik_mm/hcl/sva/decode/mpeg2/sva_dc_mpeg2.h | 181 drivers/media/nomadik_mm/hcl/sva/decode/mpeg2/sva_dc_mpeg2p.c | 789 + drivers/media/nomadik_mm/hcl/sva/decode/mpeg2/sva_dc_mpeg2p.h | 35 drivers/media/nomadik_mm/hcl/sva/decode/mpeg4/sva_dc_mpeg4.c | 2211 ++ drivers/media/nomadik_mm/hcl/sva/decode/mpeg4/sva_dc_mpeg4.h | 170 drivers/media/nomadik_mm/hcl/sva/decode/mpeg4/sva_dc_mpeg4p.c | 686 drivers/media/nomadik_mm/hcl/sva/decode/mpeg4/sva_dc_mpeg4p.h | 35 drivers/media/nomadik_mm/hcl/sva/decode/sva.h | 18 drivers/media/nomadik_mm/hcl/sva/decode/sva_dc_algo.h | 135 drivers/media/nomadik_mm/hcl/sva/decode/sva_decode.c | 2357 +++ drivers/media/nomadik_mm/hcl/sva/decode/sva_decode.h | 97 drivers/media/nomadik_mm/hcl/sva/decode/sva_decodep.c | 655 drivers/media/nomadik_mm/hcl/sva/decode/sva_decodep.h | 364 drivers/media/nomadik_mm/hcl/sva/decode/sva_decodepp.h | 40 drivers/media/nomadik_mm/hcl/sva/decode/vc1/sva_dc_vc1.c | 2044 ++ drivers/media/nomadik_mm/hcl/sva/decode/vc1/sva_dc_vc1.h | 194 drivers/media/nomadik_mm/hcl/sva/decode/vc1/sva_dc_vc1p.c | 714 drivers/media/nomadik_mm/hcl/sva/decode/vc1/sva_dc_vc1p.h | 37 drivers/media/nomadik_mm/hcl/sva/display/sva_display.c | 5661 +++++++ drivers/media/nomadik_mm/hcl/sva/display/sva_display.h | 99 drivers/media/nomadik_mm/hcl/sva/display/sva_displayp.h | 424 drivers/media/nomadik_mm/hcl/sva/encode/brc/sva_brc.c | 3648 ++++ drivers/media/nomadik_mm/hcl/sva/encode/brc/sva_brc.h | 112 drivers/media/nomadik_mm/hcl/sva/encode/brc/sva_brcp.h | 262 drivers/media/nomadik_mm/hcl/sva/encode/h264/sva_ec_h264.c | 4739 ++++++ drivers/media/nomadik_mm/hcl/sva/encode/h264/sva_ec_h264.h | 79 drivers/media/nomadik_mm/hcl/sva/encode/h264/sva_ec_h264p.h | 646 drivers/media/nomadik_mm/hcl/sva/encode/mpeg4/sva_ec_mpeg4.c | 2556 +++ drivers/media/nomadik_mm/hcl/sva/encode/mpeg4/sva_ec_mpeg4.h | 69 drivers/media/nomadik_mm/hcl/sva/encode/mpeg4/sva_ec_mpeg4p.h | 246 drivers/media/nomadik_mm/hcl/sva/encode/sva_ec_algo.h | 187 drivers/media/nomadik_mm/hcl/sva/encode/sva_encode.c | 4594 ++++++ drivers/media/nomadik_mm/hcl/sva/encode/sva_encode.h | 90 drivers/media/nomadik_mm/hcl/sva/encode/sva_encodep.h | 340 drivers/media/nomadik_mm/hcl/sva/events_management/sva_eventmgt.c | 896 + drivers/media/nomadik_mm/hcl/sva/events_management/sva_eventmgt.h | 97 drivers/media/nomadik_mm/hcl/sva/events_management/sva_eventmgtp.h | 84 drivers/media/nomadik_mm/hcl/sva/events_management/sva_irqmgt.c | 225 drivers/media/nomadik_mm/hcl/sva/events_management/sva_irqmgt.h | 42 drivers/media/nomadik_mm/hcl/sva/firmware_management/sva_fwmgt.c | 1907 ++ drivers/media/nomadik_mm/hcl/sva/firmware_management/sva_fwmgt.h | 180 drivers/media/nomadik_mm/hcl/sva/firmware_management/sva_fwmgtp.h | 304 drivers/media/nomadik_mm/hcl/sva/grab/sva_grab.c | 3810 +++++ drivers/media/nomadik_mm/hcl/sva/grab/sva_grab.h | 88 drivers/media/nomadik_mm/hcl/sva/grab/sva_grabp.h | 411 drivers/media/nomadik_mm/hcl/sva/include/sva_bufferlistmgt.h | 87 drivers/media/nomadik_mm/hcl/sva/include/sva_buffermgt.h | 111 drivers/media/nomadik_mm/hcl/sva/include/sva_capabilities.h | 46 drivers/media/nomadik_mm/hcl/sva/include/sva_dc_mpeg2.h | 181 drivers/media/nomadik_mm/hcl/sva/include/sva_decode.h | 97 drivers/media/nomadik_mm/hcl/sva/include/sva_display.h | 99 drivers/media/nomadik_mm/hcl/sva/include/sva_encode.h | 90 drivers/media/nomadik_mm/hcl/sva/include/sva_eventmgt.h | 97 drivers/media/nomadik_mm/hcl/sva/include/sva_fifo.h | 335 drivers/media/nomadik_mm/hcl/sva/include/sva_fwmgt.h | 180 drivers/media/nomadik_mm/hcl/sva/include/sva_grab.h | 89 drivers/media/nomadik_mm/hcl/sva/include/sva_host_interface.h | 290 drivers/media/nomadik_mm/hcl/sva/include/sva_internalneeds.h | 60 drivers/media/nomadik_mm/hcl/sva/include/sva_irqmgt.h | 42 drivers/media/nomadik_mm/hcl/sva/include/sva_memorymgt.h | 163 drivers/media/nomadik_mm/hcl/sva/include/sva_openservice.h | 62 drivers/media/nomadik_mm/hcl/sva/include/sva_openservicemgt.h | 71 drivers/media/nomadik_mm/hcl/sva/include/sva_service.h | 337 drivers/media/nomadik_mm/hcl/sva/include/sva_stab.h | 89 drivers/media/nomadik_mm/hcl/sva/include/sva_still_decode.h | 111 drivers/media/nomadik_mm/hcl/sva/include/sva_still_encode.h | 96 drivers/media/nomadik_mm/hcl/sva/include/sva_taskmgt.h | 403 drivers/media/nomadik_mm/hcl/sva/include/sva_timemgt.h | 80 drivers/media/nomadik_mm/hcl/sva/include/sva_tvo.h | 89 drivers/media/nomadik_mm/hcl/sva/include/svap.h | 193 drivers/media/nomadik_mm/hcl/sva/include/t1xhv_host_interface.h | 1725 ++ drivers/media/nomadik_mm/hcl/sva/include/t1xhv_retarget.h | 41 drivers/media/nomadik_mm/hcl/sva/memory_management/sva_bufferlistmgt.c | 541 drivers/media/nomadik_mm/hcl/sva/memory_management/sva_bufferlistmgt.h | 87 drivers/media/nomadik_mm/hcl/sva/memory_management/sva_bufferlistmgtp.h | 73 drivers/media/nomadik_mm/hcl/sva/memory_management/sva_buffermgt.c | 1212 + drivers/media/nomadik_mm/hcl/sva/memory_management/sva_buffermgt.h | 111 drivers/media/nomadik_mm/hcl/sva/memory_management/sva_buffermgtp.h | 83 drivers/media/nomadik_mm/hcl/sva/memory_management/sva_memorymgt.c | 1578 ++ drivers/media/nomadik_mm/hcl/sva/memory_management/sva_memorymgt.h | 163 drivers/media/nomadik_mm/hcl/sva/memory_management/sva_memorymgtp.h | 105 drivers/media/nomadik_mm/hcl/sva/openservice_management/sva_openservice.h | 62 drivers/media/nomadik_mm/hcl/sva/openservice_management/sva_openservicemgt.c | 620 drivers/media/nomadik_mm/hcl/sva/openservice_management/sva_openservicemgt.h | 71 drivers/media/nomadik_mm/hcl/sva/openservice_management/sva_openservicemgtp.h | 56 drivers/media/nomadik_mm/hcl/sva/stab/sva_stab.c | 2855 +++ drivers/media/nomadik_mm/hcl/sva/stab/sva_stab.h | 89 drivers/media/nomadik_mm/hcl/sva/stab/sva_stabp.h | 284 drivers/media/nomadik_mm/hcl/sva/still_decode/jpeg/sva_sdc_jpeg.c | 1047 + drivers/media/nomadik_mm/hcl/sva/still_decode/jpeg/sva_sdc_jpeg.h | 70 drivers/media/nomadik_mm/hcl/sva/still_decode/jpeg/sva_sdc_jpegp.h | 74 drivers/media/nomadik_mm/hcl/sva/still_decode/sva_sdc_algo.h | 96 drivers/media/nomadik_mm/hcl/sva/still_decode/sva_still_decode.c | 3174 ++++ drivers/media/nomadik_mm/hcl/sva/still_decode/sva_still_decode.h | 111 drivers/media/nomadik_mm/hcl/sva/still_decode/sva_still_decodep.h | 267 drivers/media/nomadik_mm/hcl/sva/still_encode/jpeg/sva_sec_jpeg.c | 682 drivers/media/nomadik_mm/hcl/sva/still_encode/jpeg/sva_sec_jpeg.h | 63 drivers/media/nomadik_mm/hcl/sva/still_encode/jpeg/sva_sec_jpegp.h | 62 drivers/media/nomadik_mm/hcl/sva/still_encode/sva_sec_algo.h | 152 drivers/media/nomadik_mm/hcl/sva/still_encode/sva_still_encode.c | 3752 ++++ drivers/media/nomadik_mm/hcl/sva/still_encode/sva_still_encode.h | 96 drivers/media/nomadik_mm/hcl/sva/still_encode/sva_still_encodep.h | 248 drivers/media/nomadik_mm/hcl/sva/sva.c | 1827 ++ drivers/media/nomadik_mm/hcl/sva/sva.h | 2148 ++ drivers/media/nomadik_mm/hcl/sva/tasks_management/sva_hwtaskmgt.c | 1701 ++ drivers/media/nomadik_mm/hcl/sva/tasks_management/sva_hwtaskmgt.h | 93 drivers/media/nomadik_mm/hcl/sva/tasks_management/sva_hwtaskmgtp.h | 134 drivers/media/nomadik_mm/hcl/sva/tasks_management/sva_taskmgt.c | 3573 ++++ drivers/media/nomadik_mm/hcl/sva/tasks_management/sva_taskmgt.h | 403 drivers/media/nomadik_mm/hcl/sva/tasks_management/sva_taskmgtp.h | 359 drivers/media/nomadik_mm/hcl/sva/tasks_management/sva_taskschl.c | 19 drivers/media/nomadik_mm/hcl/sva/tvo/sva_tvo.c | 2478 +++ drivers/media/nomadik_mm/hcl/sva/tvo/sva_tvo.h | 89 drivers/media/nomadik_mm/hcl/sva/tvo/sva_tvop.h | 278 drivers/media/nomadik_mm/opengl/Makefile | 18 drivers/media/nomadik_mm/opengl/ogl.c | 565 drivers/media/nomadik_mm/opengl/ogl.h | 65 drivers/media/nomadik_mm/opengl/ogl_ioctl.h | 56 drivers/media/nomadik_mm/saa/Makefile | 20 drivers/media/nomadik_mm/saa/README | 72 drivers/media/nomadik_mm/saa/nomadik-fwload.c | 229 drivers/media/nomadik_mm/saa/nomadik-fwload.h | 47 drivers/media/nomadik_mm/saa/nomadik-saa.c | 4406 +++++ drivers/media/nomadik_mm/saa/nomadik-saa.h | 204 drivers/media/nomadik_mm/saa/saaioctl.h | 498 drivers/media/nomadik_mm/sva/Makefile | 58 drivers/media/nomadik_mm/sva/nomadik_camera.h | 206 drivers/media/nomadik_mm/sva/nomadik_defs.h | 76 drivers/media/nomadik_mm/sva/nomadik_pepperpot.c | 1189 + drivers/media/nomadik_mm/sva/nomadik_pepperpot.h | 153 drivers/media/nomadik_mm/sva/nomadik_sva.c | 4951 ++++++ drivers/media/nomadik_mm/sva/nomadik_sva.h | 225 drivers/media/nomadik_mm/sva/nomadik_sva_mpeg4.c | 432 drivers/media/nomadik_mm/sva/nomadik_sva_services.h | 3826 +++++ drivers/media/nomadik_mm/sva/nomadik_sva_utils.c | 964 + drivers/media/nomadik_mm/sva/nomadik_sva_utils.h | 49 drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c | 6984 +++++++++ drivers/media/nomadik_mm/sva/nomadik_sva_vpip.h | 589 drivers/media/video/Kconfig | 7 drivers/media/video/Makefile | 8 drivers/media/video/hcl_defs.h | 280 drivers/media/video/nomadik_camera.h | 206 drivers/media/video/nomadik_defs.h | 76 drivers/media/video/nomadik_sva.h | 225 drivers/media/video/nomadik_sva_services.h | 3832 +++++ drivers/media/video/nomadik_sva_utils.h | 49 drivers/media/video/platform_os.h | 55 drivers/media/video/sva.h | 2148 ++ drivers/media/video/v4l2-nomadik.c | 1590 ++ drivers/media/video/v4l2-nomadik.h | 70 drivers/misc/Kconfig | 27 drivers/misc/Makefile | 4 drivers/misc/batt-nomadik.c | 1307 + drivers/misc/etm-nomadik.c | 207 drivers/misc/pexp-nomadik.c | 2847 +++ drivers/misc/sif-nomadik.c | 560 drivers/mmc/Kconfig | 27 drivers/mmc/Makefile | 9 drivers/mmc/mmc-nomadik.c | 1435 + drivers/mtd/maps/Kconfig | 7 drivers/mtd/maps/Makefile | 11 drivers/mtd/maps/norflash-nomadik.c | 411 drivers/mtd/nand/Kconfig | 6 drivers/mtd/nand/Makefile | 5 drivers/mtd/nand/nandflash-nomadik.c | 296 drivers/mtd/onenand/Kconfig | 38 drivers/mtd/onenand/Makefile | 3 drivers/mtd/onenand/generic.c | 62 drivers/mtd/onenand/onenand_base.c | 1139 + drivers/mtd/onenand/onenand_bbt.c | 33 drivers/mtd/onenand/onenand_sim.c | 495 drivers/net/Makefile | 1 drivers/net/kgdboe.c | 294 drivers/net/smc91x.c | 100 drivers/net/smc91x.h | 133 drivers/serial/amba-pl011.c | 101 drivers/spi/Kconfig | 8 drivers/spi/Makefile | 2 drivers/spi/spi-nomadik.c | 1000 + drivers/usb/Kconfig | 2 drivers/usb/Makefile | 1 drivers/usb/gadget/file_storage.c | 15 drivers/usb/nomadik/Kconfig | 176 drivers/usb/nomadik/Makefile | 97 drivers/usb/nomadik/board.h | 58 drivers/usb/nomadik/debug.h | 104 drivers/usb/nomadik/dma.h | 308 drivers/usb/nomadik/g_ep0.c | 858 + drivers/usb/nomadik/logx | 1 drivers/usb/nomadik/musb_bus_direct.c | 371 drivers/usb/nomadik/musb_cross.h | 131 drivers/usb/nomadik/musb_debug.c | 190 drivers/usb/nomadik/musb_epdescriptors.h | 48 drivers/usb/nomadik/musb_epfifocfg.c | 429 drivers/usb/nomadik/musb_hcd.c | 869 + drivers/usb/nomadik/musb_host.c | 2791 +++ drivers/usb/nomadik/musb_host.h | 101 drivers/usb/nomadik/musb_ioctl.c | 321 drivers/usb/nomadik/musb_ioctl.h | 32 drivers/usb/nomadik/musb_plat_uds.c | 2306 +++ drivers/usb/nomadik/musb_procfs.c | 413 drivers/usb/nomadik/musb_virthub.c | 840 + drivers/usb/nomadik/musb_virthub.h | 240 drivers/usb/nomadik/musbdefs.h | 828 + drivers/usb/nomadik/musbhdrc.h | 315 drivers/usb/nomadik/musbhsfc.h | 150 drivers/usb/nomadik/nomadik_udc.c | 2845 +++ drivers/usb/nomadik/nomadik_udc.h | 663 drivers/usb/nomadik/otg_func.c | 196 drivers/usb/nomadik/otg_pwm.c | 46 drivers/usb/nomadik/plat_arc.h | 92 drivers/usb/nomadik/plat_cnf.h | 208 drivers/video/Makefile | 1 drivers/video/amba-clcd.c | 115 drivers/video/fbmem.c | 1 drivers/video/nomadik/Makefile | 15 drivers/video/nomadik/hcl/debug.h | 313 drivers/video/nomadik/hcl/hcl_defs.h | 286 drivers/video/nomadik/hcl/platform_os.h | 79 drivers/video/nomadik/hcl/sga.c | 3161 ++++ drivers/video/nomadik/hcl/sga.h | 937 + drivers/video/nomadik/hcl/sga_irq.c | 206 drivers/video/nomadik/hcl/sga_irq.h | 99 drivers/video/nomadik/hcl/sga_irqp.h | 239 drivers/video/nomadik/hcl/sga_p.h | 175 drivers/video/nomadik/sga_defs.h | 87 drivers/video/nomadik/sga_err.h | 45 drivers/video/nomadik/sga_interface.h | 119 drivers/video/nomadik/sga_ioctlfns.c | 473 drivers/video/nomadik/sga_ioctlfns.h | 50 drivers/video/nomadik/sga_main.c | 651 drivers/video/nomadik/sga_main.h | 123 drivers/video/nomadik/sga_typs.h | 37 fs/Kconfig | 4 fs/Makefile | 3 fs/proc/proc_misc.c | 42 fs/yaffs2/Kconfig | 156 fs/yaffs2/Makefile | 10 fs/yaffs2/devextras.h | 264 fs/yaffs2/moduleconfig.h | 65 fs/yaffs2/yaffs_checkptrw.c | 404 fs/yaffs2/yaffs_checkptrw.h | 35 fs/yaffs2/yaffs_ecc.c | 331 fs/yaffs2/yaffs_ecc.h | 44 fs/yaffs2/yaffs_fs.c | 2297 +++ fs/yaffs2/yaffs_guts.c | 7532 ++++++++++ fs/yaffs2/yaffs_guts.h | 904 + fs/yaffs2/yaffs_mtdif.c | 241 fs/yaffs2/yaffs_mtdif.h | 27 fs/yaffs2/yaffs_mtdif1.c | 369 fs/yaffs2/yaffs_mtdif1.h | 28 fs/yaffs2/yaffs_mtdif2.c | 232 fs/yaffs2/yaffs_mtdif2.h | 29 fs/yaffs2/yaffs_nand.c | 134 fs/yaffs2/yaffs_nand.h | 44 fs/yaffs2/yaffs_nandemul2k.h | 39 fs/yaffs2/yaffs_packedtags1.c | 52 fs/yaffs2/yaffs_packedtags1.h | 37 fs/yaffs2/yaffs_packedtags2.c | 182 fs/yaffs2/yaffs_packedtags2.h | 38 fs/yaffs2/yaffs_qsort.c | 160 fs/yaffs2/yaffs_qsort.h | 23 fs/yaffs2/yaffs_tagscompat.c | 530 fs/yaffs2/yaffs_tagscompat.h | 40 fs/yaffs2/yaffs_tagsvalidity.c | 28 fs/yaffs2/yaffs_tagsvalidity.h | 24 fs/yaffs2/yaffsinterface.h | 21 fs/yaffs2/yportenv.h | 200 include/asm-arm/arch-nomadik/audiocodec.h | 444 include/asm-arm/arch-nomadik/bits.h | 61 include/asm-arm/arch-nomadik/debug-macro.S | 38 include/asm-arm/arch-nomadik/debug.h | 148 include/asm-arm/arch-nomadik/defs.h | 245 include/asm-arm/arch-nomadik/dma.h | 362 include/asm-arm/arch-nomadik/entry-macro.S | 210 include/asm-arm/arch-nomadik/epio.h | 24 include/asm-arm/arch-nomadik/fsmc.h | 203 include/asm-arm/arch-nomadik/gpio.h | 529 include/asm-arm/arch-nomadik/hardware.h | 107 include/asm-arm/arch-nomadik/i2c.h | 419 include/asm-arm/arch-nomadik/io.h | 37 include/asm-arm/arch-nomadik/irqs.h | 137 include/asm-arm/arch-nomadik/kpd.h | 56 include/asm-arm/arch-nomadik/memory.h | 41 include/asm-arm/arch-nomadik/mmc.h | 234 include/asm-arm/arch-nomadik/msp-spi.h | 343 include/asm-arm/arch-nomadik/msp.h | 322 include/asm-arm/arch-nomadik/mtu.h | 90 include/asm-arm/arch-nomadik/nandflash.h | 42 include/asm-arm/arch-nomadik/ndk10_devices.h | 160 include/asm-arm/arch-nomadik/ndk15_devices.h | 248 include/asm-arm/arch-nomadik/ndk15c02_devices.h | 169 include/asm-arm/arch-nomadik/nhk15_devices.h | 131 include/asm-arm/arch-nomadik/param.h | 19 include/asm-arm/arch-nomadik/pexp.h | 355 include/asm-arm/arch-nomadik/power.h | 180 include/asm-arm/arch-nomadik/smp.h | 19 include/asm-arm/arch-nomadik/spi.h | 521 include/asm-arm/arch-nomadik/ssp-spi.h | 280 include/asm-arm/arch-nomadik/stn8810_devices.h | 120 include/asm-arm/arch-nomadik/stn8815_devices.h | 165 include/asm-arm/arch-nomadik/stw5094ap.h | 176 include/asm-arm/arch-nomadik/stw5095.h | 1387 + include/asm-arm/arch-nomadik/sva.h | 43 include/asm-arm/arch-nomadik/system.h | 62 include/asm-arm/arch-nomadik/timex.h | 71 include/asm-arm/arch-nomadik/touchp.h | 145 include/asm-arm/arch-nomadik/touchp2003.h | 42 include/asm-arm/arch-nomadik/udc.h | 490 include/asm-arm/arch-nomadik/uncompress.h | 71 include/asm-arm/arch-nomadik/vmalloc.h | 32 include/asm-arm/kgdb.h | 91 include/asm-arm/system.h | 41 include/asm-generic/kgdb.h | 34 include/linux/amba/clcd.h | 24 include/linux/dwarf2-lang.h | 300 include/linux/dwarf2.h | 775 + include/linux/i2c.h | 13 include/linux/kgdb.h | 271 include/linux/miscdevice.h | 1 include/linux/module.h | 28 include/linux/mtd/bbm.h | 11 include/linux/mtd/mtd.h | 1 include/linux/mtd/nand.h | 52 include/linux/mtd/onenand.h | 31 include/linux/mtd/onenand_regs.h | 8 include/linux/netpoll.h | 2 include/linux/usb.h | 4 include/linux/v4l2-nomadikdefs.h | 12 include/linux/videodev2.h | 11 init/Kconfig | 15 kernel/Makefile | 1 kernel/kgdb.c | 1963 ++ kernel/module.c | 216 kernel/pid.c | 11 kernel/power/main.c | 2 kernel/sched.c | 6 kernel/softlockup.c | 4 kernel/timer.c | 8 lib/Kconfig.debug | 79 net/core/netpoll.c | 5 net/sunrpc/xprtsock.c | 5 scripts/Makefile | 1 scripts/Makefile.modpost | 2 scripts/dwarfh.awk | 19 scripts/kconfig/Makefile | 32 scripts/ksymhash/Makefile | 35 scripts/ksymhash/elflib.c | 164 scripts/ksymhash/elflib.h | 142 scripts/ksymhash/empty.c | 1 scripts/ksymhash/ksymhash.c | 126 scripts/ksymhash/mk_elfconfig.c | 66 scripts/mod/modpost.c | 23 sound/Kconfig | 36 sound/Makefile | 9 sound/arm/Kconfig | 11 sound/arm/Makefile | 3 sound/arm/nomadik_alsa.c | 1038 + sound/arm/nomadik_alsa.h | 83 sound/nomadik_stw5094.c | 2280 +++ sound/nomadik_stw5095.c | 3529 ++++ 514 files changed, 244969 insertions(+), 622 deletions(-) --- linux-2.6.20.orig/.gitignore +++ /dev/null @@ -1,47 +0,0 @@ -# -# NOTE! Don't add files that are generated in specific -# subdirectories here. Add them in the ".gitignore" file -# in that subdirectory instead. -# -# Normal rules -# -.* -*.o -*.a -*.s -*.ko -*.so -*.mod.c -*.i -*.lst -*.symtypes - -# -# Top-level generic files -# -tags -TAGS -vmlinux* -System.map -Module.symvers - -# -# Generated include files -# -include/asm -include/asm-*/asm-offsets.h -include/config -include/linux/autoconf.h -include/linux/compile.h -include/linux/version.h -include/linux/utsrelease.h - -# stgit generated dirs -patches-* - -# quilt's files -patches -series - -# cscope files -cscope.* --- linux-2.6.20.orig/Documentation/DocBook/Makefile +++ linux-2.6.20/Documentation/DocBook/Makefile @@ -9,11 +9,12 @@ DOCBOOKS := wanbook.xml z8530book.xml mcabook.xml videobook.xml \ kernel-hacking.xml kernel-locking.xml deviceiobook.xml \ procfs-guide.xml writing_usb_driver.xml \ kernel-api.xml filesystems.xml lsm.xml usb.xml \ gadget.xml libata.xml mtdnand.xml librs.xml rapidio.xml \ - genericirq.xml + genericirq.xml \ + kgdb.xml ### # The build process is as follows (targets): # (xmldocs) # file.tmpl --> file.xml +--> file.ps (psdocs) --- /dev/null +++ linux-2.6.20/Documentation/DocBook/kgdb.tmpl @@ -0,0 +1,234 @@ + + + + + + KGDB Internals + + + + Tom + Rini + +
+ trini@kernel.crashing.org +
+
+
+
+ + + + Amit S. + Kale + +
+ amitkale@linsyssoft.com +
+
+
+
+ + + 2004-2005 + MontaVista Software, Inc. + + + 2004 + Amit S. Kale + + + + + This file is licensed under the terms of the GNU General Public License + version 2. This program is licensed "as is" without any warranty of any + kind, whether express or implied. + + + +
+ + + + Introduction + + kgdb is a source level debugger for linux kernel. It is used along + with gdb to debug a linux kernel. Kernel developers can debug a kernel + similar to application programs with the use of kgdb. It makes it + possible to place breakpoints in kernel code, step through the code + and observe variables. + + + Two machines are required for using kgdb. One of these machines is a + development machine and the other is a test machine. The machines are + typically connected through a serial line, a null-modem cable which + connects their serial ports. It is also possible however, to use an + ethernet connection between the machines. The kernel to be debugged + runs on the test machine. gdb runs on the development machine. The + serial line or ethernet connection is used by gdb to communicate to + the kernel being debugged. + + + + Compiling a kernel + + To enable CONFIG_KGDB, look under the "Kernel debugging" + and then select "KGDB: kernel debugging with remote gdb". + + + The first choice for I/O is CONFIG_KGDB_ONLY_MODULES. + This means that you will only be able to use KGDB after loading a + kernel module that defines how you want to be able to talk with + KGDB. There are two other choices (more on some architectures) that + can be enabled as modules later, if not picked here. + + The first of these is CONFIG_KGDB_8250_NOMODULE. + This has sub-options such as CONFIG_KGDB_SIMPLE_SERIAL + which toggles choosing the serial port by ttyS number or by specifying + a port and IRQ number. + + + The second of these choices on most systems for I/O is + CONFIG_KGDBOE. This requires that the machine to be + debugged has an ethernet card which supports the netpoll API, such as + the cards supported by CONFIG_E100. There are no + sub-options for this, but a kernel command line option is required. + + + + Booting the kernel + + The Kernel command line option kgdbwait makes kgdb + wait for gdb connection during booting of a kernel. If the + CONFIG_KGDB_8250 driver is used (or if applicable, + another serial driver) this breakpoint will happen very early on, before + console output. If you wish to change serial port information and you + have enabled both CONFIG_KGDB_8250 and + CONFIG_KGDB_SIMPLE_SERIAL then you must pass the option + kgdb8250=<io or mmio>,<address>,<baud + rate>,<irq> before kgdbwait. + The values io or mmio refer to + if the address being passed next needs to be memory mapped + (mmio) or not. The address must + be passed in hex and is the hardware address and will be remapped if + passed as mmio. The value + baud rate and irq are base-10. + The supported values for baud rate are + 9600, 19200, + 38400, 57600, and + 115200. + + + To have KGDB stop the kernel and wait, with the compiled values for the + serial driver, pass in: kgdbwait. + + + To specify the values of the serial port at boot: + kgdb8250=io,3f8,115200,3. + On IA64 this could also be: + kgdb8250=mmio,0xff5e0000,115200,74 + And to have KGDB also stop the kernel and wait for GDB to connect, pass in + kgdbwait after this arguement. + + + To configure the CONFIG_KGDBOE driver, pass in + kgdboe=[src-port]@<src-ip>/[dev],[tgt-port]@<tgt-ip>/[tgt-macaddr] + where: + + src-port (optional): source for UDP packets (defaults to 6443) + src-ip: source IP to use (interface address) + dev (optional): network interface (eth0) + tgt-port (optional): port GDB will use (defaults to 6442) + tgt-ip: IP address GDB will be connecting from + tgt-macaddr (optional): ethernet MAC address for logging agent (default is broadcast) + + + + The CONFIG_KGDBOE driver can be reconfigured at run + time, if CONFIG_SYSFS and + CONFIG_MODULES by echo'ing a new config string to + /sys/module/kgdboe/parameter/kgdboe. The + driver can be unconfigured with the special string + not_configured. + + + + Connecting gdb + + If you have used any of the methods to have KGDB stop and create + an initial breakpoint described in the previous chapter, kgdb prints + the message "Waiting for connection from remote gdb..." on the console + and waits for connection from gdb. At this point you connect gdb to kgdb. + + + Example (serial): + + + % gdb ./vmlinux + (gdb) set remotebaud 115200 + (gdb) target remote /dev/ttyS0 + + + Example (ethernet): + + + % gdb ./vmlinux + (gdb) target remote udp:192.168.2.2:6443 + + + Once connected, you can debug a kernel the way you would debug an + application program. + + + + The common backend (required) + + There are a few flags which must be set on every architecture in + their <asm/kgdb.h> file. These are: + + + + NUMREGBYTES: The size in bytes of all of the registers, so + that we can ensure they will all fit into a packet. + + + BUFMAX: The size in bytes of the buffer GDB will read into. + This must be larger than NUMREGBYTES. + + + CACHE_FLUSH_IS_SAFE: Set to one if it always safe to call + flush_cache_range or flush_icache_range. On some architectures, + these functions may not be safe to call on SMP since we keep other + CPUs in a holding pattern. + + + + + + There are also the following functions for the common backend, + found in kernel/kgdb.c that must be supplied by the + architecture-specific backend. No weak version of these is provided. + +!Iinclude/linux/kgdb.h + + + The common backend (optional) + + These functions are part of the common backend, found in kernel/kgdb.c + and are optionally implemented. Some functions (with _hw_ in the name) + end up being required on arches which use hardware breakpoints. + +!Ikernel/kgdb.c + + + Driver-Specific Functions + + Some of the I/O drivers have additional functions that can be + called, that are specific to the driver. Calls from other places + to these functions must be wrapped in #ifdefs for the driver in + question. + +!Idrivers/serial/8250_kgdb.c + +
--- /dev/null +++ linux-2.6.20/Documentation/arm/STM-Nomadik/HOWTO-add_newboard.txt @@ -0,0 +1,111 @@ +Filename: ./Documentation/arm/STM-Nomadik/HOWTO-add_newboard.txt +Author: Prafulla Wadaskar (prafulla.wadaskar@st.com) +Owner: STMicroelectronics +Purpose: + This HOWTO explains guidlines for addition of new Nomadik + board support to the kernel source code +=============================================================================== + +This document is valid subject to assumption - +1. valid kernel source code with Nomadik support is available + +Nomadik BSP kernel file naming conventions +============================================ +It is strongly recommended to follow below filename conventions while adding +new board support for Nomadik +1. All the Nomadik architecture specific code must be in mach-nomadik and + arch-nomadik folders in a kernel tree. +2. Generic and Nomadik specific device drives may be located into the respective + folder in the kernel source tree (ex. nomadik keypad driver in + drivers/input/keyboard/kpd-nomadik.c) +3. all Nomadik specific files in mach-nomadik and arch-nomadik folders should + be named as .c/h + (ex. gpio.h, msp.c) +4. all Nomadik platform specific files are named as _.c/h + (ex. ndk10_devices.c, ndk15_devices.h) +5. all Nomadik soc specific files are named as _.c/h + (ex. stn8810_devices.h, stn8815_devices.c) + +Important definations +============================== +1. target: It is a unique identity to describe supported board with a specific + board version and specific SOC version. + target is created by combination of board (i.e. platform) and + Nomadik chip version (i.e. soc) + +2. platform: It is refered for board to be supported. + One plaform may be supported by several targets + One plaform may be supported by several socs + +3. soc: It is refered for the Nomadik chip version to be suported. + same soc may be supported on several platforms + +Hence any Nomadik borad is identified as a "target" and supported by "soc" + specific code and "platform" specific code well interfaced with generic + code. + +Device driver Support for Nomadik: +==================================== +1. All the drivers suported on a target can be either SOC or platform specific +2. A platform specific code for all supported driver will be refered from a + single file _devices.c through device specific interface. +3. A Nomadik chip specific code for all supported driver will be refered from a + single file _devices.c through device specific interface. +4. Each device specific header file _devices.h and + _devices.h must be maintained to share a common hardware + parameters across the drivers. Those two files are included in + asm/arch/hardware.h which is further refered through asm/hardware.h + Hence any kernel code seeking for hardware specific information (like + base address, irqnos) can be made available by just including + +5. Each header file described here should have relevent declaration related to + the scope of its usage. ex. _devices.h should only have + platforms specific declration. + +Any Nomadik target can be supported by following set of files:- + arch/arch/mach-nomadik/_devices.c + inclue/asm-arm/arch-nomadik/_devices.h + arch/arch/mach-nomadik/_devices.c + inclue/asm-arm/arch-nomadik/_devices.h + +But Generally, New board support will be added for already suported SOCs +hence, to add support for any new Nomadik target only three files need to be +added, those are:- + arch/arch/mach-nomadik/_Kconfig + arch/arch/mach-nomadik/_devices.c + inclue/asm-arm/arch0-nomadik/_devices.h + +Steps to follow to add new target support for Nomadik +======================================================== +1. Add ./arch/arm/mach-nomadik/_Kconfig file for board + configuration, specified here will reflect as machine name. + + During make config/menuconfig arch/arm/mach-nomadik/Kconfig will be + checked, and if is not found, it will be created automatically using + all _Kconfig files and Kconfig_nomadik file. + 1. _Kconfig file contain board specific configuration + 2. Kconfig_nomadik contains generic configuration for all nomadik + platforms + for details refer provided ndk10_cut_a1_Kconfig file + +2. Add ./arch/arm/mach-nomadik/_devices.c file + This file contains all the platfrom specific functions and data + structures used by rest of the code. Any driver suported for Nomadik + platform must access all the paramters through this file + (for ex. base addres, irq number and other plaform specific data + structures and function) + It is recommended to refer such file for already suported platform + +3. Add ./include/asm-arm/arch-nomadik/_devices.h file + This file must contain all the declarations for this platform + which may be refered by the other drivers and kernel code. + Note that this file is refered by some assembly code hence the + content of this files must be maintained simple, standard and + generic. + It is recommended to refer such file for already suported platform + +With the above addition/modification New target support will be available. +Select newly supported target in kernel configuration, build and execute +the code on new target +=============================================================================== + --- /dev/null +++ linux-2.6.20/Documentation/arm/STM-Nomadik/HOWTO-nfsboot.txt @@ -0,0 +1,106 @@ +This HOWTO esplains mounting the root file system via NFS on Nomadik Platform (nfsroot) + +As you know, all of us spend lot of time in- +1. Unzip/mount initrd to put the modules/application under test +2. Copying modules/applications to initrd +3. Unmount/gzip operation with initrd +4. Then load huge initrd and kernel each time to target board + for execution. + +So for each time even for a small change we need to repeat this process, and +downloading and system re-initialization eats lot of our development time. +Nfsroot is a good solution to overcome above issues. + +Root file system can be mounted via NFS (nfsroot) on host and can be accessed +from your target machin. + +Advantages of this method are:- +=============================== +1. No need to download ramdiks time to time (saves lot of time) +2. Since file system is on NFS, runtime results/logs dooes not vanishes + in case of nomadik-system crash +3. Since file system is on NFS, it is transperant to host and target +4. Making, updating, mounting, unmounting, zipping, unzipping activities + associated with ramdisk can be totally avoided (saves lot of time) +5. Offers comfortable and fast development environment + +Host configuration to enable root NFS:- +======================================== +1. Copy a "target" folder from toolchain at some fixed path on your Linux + host +2. Switch to the dev folder of newly created target folder and create + a node for console with command "mknod console c 5 1" +3. Then swtich to the target folder and create a symbolic link with + command "ln -s /bin/busybox linuxrc +4. FTP and TFTP should be enabled on the host system. You can check the + configuration by issuing the following command + +#> chkconfig --list | grep ftp + +Output should look like :- +vsftpd 0:off 1:off 2:on 3:on 4:on 5:on 6:off + gssftp: off + tftp: on + +Note: Method of enabling FTP can be different for different versions of Linux. + +5. NFS should be enabled. Same can also be checked with the following + command + +#> chkconfig --list | grep nfs + +Output should looklike +nfs 0:off 1:off 2:on 3:on 4:on 5:on 6:off + +6. Also, check the entries of the /etc/xinetd.d/tftp file accordingly. + In our case, it is : + +service tftp +{ + disable = no + socket_type = dgram + protocol = udp + wait = yes + user = root + server = /usr/sbin/in.tftpd + server_args = -T 100000000 -v -c -s +/local_no_backup +# server_args = -s /tftpboot + per_source = 11 + cps = 100 2 + flags = IPv4 +} + +7. Also make the entries in /etc/exports for the file systems that need + to be shared. For options used, please refer the man pages of exports. + In our case, it is : + +/rtrt *(rw,insecure,no_root_squash,async) +/local_no_backup/target *(rw,insecure,no_root_squash,async) + +How to enable NFS feature in your development? +=============================================== +1. Of cource you need to work on ethernet based environment +2. Enable ethernet driver in your kernel image +3. Enable following settings in your kernel image to enable nfsroot +a. Networking options --->IP: kernel level autoconfiguration +b. Networking options --->IP: BOOTP support +c. File systems --->Network File Systems --->NFS file system support +d. File systems --->Network File Systems --->Provide NFSv3 client support +e. File systems --->Network File Systems --->Root file system on NFS +4. Then compile kernel image, prepare uimage and download into the target +5. Set the command line arguments as - + + "set bootargs root=/dev/nfs nfsroot=://ramdisk +ip=:::255.255.255.0:nomadik:: console=ttyAMA1 mac= init=linuxrc" + +for example:- +"set bootargs root=/dev/nfs nfsroot=10.199.3.88:/local_no_backup/target +ip=10.199.32.165:10.199.3.88:10.199.32.254:255.255.255.0:NDK10_165:: +mac=00:0D:88:45:5D:A5 console=ttyAMA1,115200n8 init=linuxrc" + +6. And then boot the kernel with command "bootm 0x100000" + (initrd address not needed since NFS) + +Start enjoying the advantages of root NFS + --- /dev/null +++ linux-2.6.20/Documentation/arm/STM-Nomadik/debug_strategy.txt @@ -0,0 +1,66 @@ + + * 1.1 Nomadik Development Debugging Strategy + * ========================================== + * + * DEBUGGING LEVELS + * 0 To disable all debug messages + * 1 To enable normal debug macro- nmdk_dbg + * 2 To enable flow trace debug macro- nmdk_dbg_ftrace + * 4 To enable interrupt and timer debug macroc- nmdk_dbg2 + * 8 To enable any special debug messages defined by macro- nmdk_dbg3 + * + * + * 1.2 How to use Debuggign strategy in driver development ? + * ========================================================= + * + * 1. include debug-nomadik.h file in c code + * (path: include/asm-arm/arch/nomadik/debug-nomadik.h) + * 2. define NMDK_DEBUG to required debug level (this can be automated + * to pass build time debug levels -as done for keypad driver. + * See driver/input/keypad makefile) + * 3. define NMDK_DEBUG_PFX to a small string to identify debug message + * This is an optional setting, if you don't define NMDK_DEBUG_PFX, + * by default "Nomadik" will be selected. + * 4. define NMDK_DBG to desired Kerlen debug level + * This is an optional setting, if you don't define NMDK_DBG, + * by default KERN_DEBUG will be used + * This generally need to set to KERN_ERR to force debug messages to + * appear on the console + * + * + * 1.3 How to activate debug messages? + *==================================== + * + * Debug messages can be activated during build time by passing desired + * debug level either hardcoding in source file or as a make parameter + * + * 1. Enabling Debug messages by passing additional parameter to make + * This is a recommended method of debug messages implimentation. + * this method give flexibility to enable/disable debug messages + * during build without modifying code + * (a) To enable this you need to updated driver make file with:- + * ex. + * ifdef _DEBUG + * CFLAGS += -_DEBUG=$(_DEBUG) + * endif + * + * (b) Same _DEBUG must be used to define NMDK_DEBUG as + * explained in (1.2.2) + * (c) Debug parameter must be passed to the make with desired debug + * level as explained in (1.1) + * ex. make _DEBUG=1 + * (d) you can AND several debug levels togather to enable respective + * debug mesages + * (e) even you can pass additional parameters to enable debug messages + * of more than one module + * ex. make _DEBUG=1 _DEBUG=4 ... + * + * 2. Enabling Debug messages by hardcoding in source file + * This is simplest implimentation, just define NMDK_DEBUG to + * desired debug level and compile the code, the disadvantage of this + * method is, it does not offer flexibility and code with debug message + * may become part of your release if not taken care properly. + * + */ + + --- /dev/null +++ linux-2.6.20/Documentation/arm/STM-Nomadik/dma_user_guide.txt @@ -0,0 +1,420 @@ +Filename: ./Documentation/arm/STM-Nomadik/dma_user_guide.txt +Author: Prafulla Wadaskar (prafulla.wadaskar@st.com) +Owner: STMicroelectronics +Purpose: + This Users Guide explains DMA implimentation and its usage + for client drivers on Nomadik platforms +============================================================================= + +This document is valid subject to assumption - +1. valid kernel source code with Nomadik support is available +2. you are familier with Kernal DMA interface + (References: ./Documentation/DMA-API.txt) + +DMA Configuration: +=================== +By default Nomadik DMA driver is configured to link staticlly with kernel. +This DMA driver provides low level interface to the kernel DMA interface. +To use DMA APIs, client driver should only include + +Definations: +============ +1. DMA Channel: The logical DMA channel can be used for a DMA transfer +2. Pipe: the physical DMA chanel H/w that is used to a DMA transfer +3. DMAC: Direct Memory Access Controller (Nomadik has two DMACs) + +Brief Architecture: +=================== +DMA dirver is registered as amba device and will be probed only if +matches peripharal ID, the SOC specific data/function iterface is provided +through platfrom_data pointer to allign driver design in sync with multiboard +strategy. +There are two DMA controllers having 8 pipes each, there could be number of +dma channels which will use any one available pipe for dma transfer at run time +Kernel DMA interface defines and controls the interface, whereas the h/w +specific APIs are mapped through methods provided by upper layer (i,e. +arch/arm/kernel/dma.c). The configuration, usage and features provided by this +driver is explained below. + +This Users guide explains- +1. Support for Standard DMA APIs for Nomadik DMA usage +2. Additional DMA APIs to facilitate effieient/flexible DMA usage +3. DMA Channel configuration. + a) Mode of operation: Transfer type + b) Mode of operation: flow control + c) Mode of operation: Double Buffered Transfer + d) Mode of operation: Infinite DMA Transfer + e) Mode of operation: Infinite DMA Transfer + f) Mode of operation: Pipe reservation + g) Mode of operation: Channel Priority + h) Mode of operation: Queueing DMA transfer requests +4. DMA Interrupt hanndling for callback functions. +5. Scatter-gather Support +6. /proc/dma interfce. +7. HOWTO add new DMAable peripharal device support + +1. Support for Standard DMA APIs for Nomadik DMA usage +====================================================== +Standard kernel DMA interface exports APIs out of which request_dma, enable_dma, +disable_dma, free_dma, dma_channel_active, set_dma_sg, __set_dma_addr, set_dma_count, +are supported for Nomadik DMA Usage. +For any DMA transfer you need to follow a sequence- + a) request_dma : to request a DMA channel be to used for transfer, + in this request you need to pass configuration + b) request_irq : to register DMA callback function + c) __set_dma_srcaddr : to set src DMAble address (mapped to __set_dma_addr) + d) __set_dma_destaddr : to set dest DMAble address (mapped to set_dma_speed) + e) set_dma_count : to set transfer size in bytes + f) set_dma_mode : to set/ulter mode of operation (optional) + g) enable_dma : to start transfer + h) dma_channel_active : to know the status of scheduled transfer (optional) + i) disable dma : to stop transfer (optional) + j) free_irq : to free irq used for callback (optional) + k) free_dma : to free requested DMA channel + +2. Additional DMA APIs for effieient/flexible DMA usage +======================================================= +Following additional APIs are provided for effieient/flexible DMA usage + a) request_available_dma + : This is a wrapper over request_dma, + this API will search, allocate and return available + free DMA channel. + b) suspend_DMA : to pause currently active DMA transfer + c) resume_DMA : to resume previously paused DMA transfer + +3. DMA Channel Configureation: +============================== +Durring request_dma system call you need to pass a pointer of pre-filled DMA +Channel configuration structure nmdk_dma_info defined in asm/arch/dma.h +i.e.- +struct nmdk_dma_info { + u32 mode; /* Mode of operation(xfer type/flow cntrl etc)*/ + char *srcdevtype; /* source device type configuration*/ + char *destdevtype; /* desitnation device type configuration*/ + u32 config; /* User programmable dmadev configuration*/ +}; + +Each DMA channle has source DMA device and a destination DMA device, a DMA +channel is a hardware that connects two DMAable devices for data transfer. +So to have a successfull DMA transfer you need to configure all these three. +Below picture gives some idea about it- + + + -------------------- + srcdevtype, src_addr | | destdevtype, dest_addr + def dmadev config | | default dmadev configuration + | | + (Src DMA periph)------>| DMA Channel |--------> (Dest DMA peripharal) + | | + -------------------- + (mode of operation) + (User configuration) + (Xfer Size in bytes) + +DMAable devices and their default configurations are SOC specific and declared +in arch/arm/mach-nomadik/_devices.c file (will be explained latter +in this guide). Each DMAble device is identified by unique name, during +configuration the src and dest dmadev names need to be specified. + +Transfer Size in bytes, src_addr and dest_addr not a part of configuration as +they keeps changing and need to be provided before enable_dma request + +User programmable dmadev configuration: These are optional configuration on +the top of default for the changable paramters (specially Brust size and +transfer width). This will be exmpained latter in this guide + +for ex, to configure a dma chnnel for memory to MSP peripharal DMA transfer +the sructure should be filled as- + + struct nmdk_dma_info test_dma_config = + { + .mode = MEM_TO_MEM, + .srcdevtype = "mem", + .destdevtype = "msp0rx", + .config = NULL, + }; + +Out of all configuration parameter "mode" is very important since it decides +the mode of DMA channel operation, there are several features supported all +are configurable through mode. + + a) Mode of operation: Transfer type + there are four basic modes of operation those are + MEM_TO_MEM, MEM_TO_PERIPH, PERIPH_TO_MEM, PERIPH_TO_PERIPH + you should program any one as per you need. + + for ex. dma_info.mode=MEM_TO_PERIPH; + + b) Mode of operation: flow control + By default flow controller is DMA controller, if you want to program + flow controller as peripharal you can use the provided macros as + + for ex. dma_info.mode=FLOW_CNTRL_DMA(MEM_TO_PERIPH); + To mention the flow controller is DMA controller. + + for ex. dma_info.mode=FLOW_CNTRL_PERIPH(MEM_TO_PERIPH); + To mention the flow controller is peripharal controller. + + Flow controller device cannot be peripharal for MEM_TO_MEM transter + + c) Mode of operation: Double Buffered Transfer + There are some peripharals like SAA(Smart Audio Accelerator) who + requires DMA transfers to be done in double buffer mode, in double + buffered mode of operation the current dma requested in divided in two, + equal sequential transfers before scheduling. + + By default standard single buffered transfer mode is programmed, + to configure Double Buffered Transfer mode a macro DMA_DOUBLE_BUFFERED + should be ORed with other configuration parameters + + for ex. dma_info.mode=DMA_DOUBLE_BUFFERED | + FLOW_CNTRL_DMA(MEM_TO_PERIPH); + + d) Mode of operation: Infinite DMA Transfer + If you want to establish DMA transafer between two DMAble devices + infinitely without CPUs intervention, this means once transfer is + scheduled, it will reschedule it self at completion automatically. + + By default infinite DMA transfer is disabled, + to configure Infinite DMA Transfer mode a macro DMA_INFINITE_XFER + should be ORed with other configuration parameters + + for ex. dma_info.mode=DMA_INFINITE_XFER | + FLOW_CNTRL_DMA(MEM_TO_PERIPH); + + In Infinite DMA transfer mode, you will never receive completion + interrupt and callback interrupt handler cannot be executed + + e) Mode of operation: Pipe reservation + Reserving a pipe will dediate a pipe for a channel + By default pipe is not reserved at the time of configuration. when you + schedule a enable_dma request, system looks for the available pipe and + schedules a transfer on it. This adds more flexibility to system to + handle more channels on limited pipes. In case the all the pipes are + busy the request will be deffered, + if you want to avoid this behavior, i.e. whenever you request enable_dma + pipe must be available to execute it, then you can reserve a pipe during + configuration. + + to reserve a pipe, a macro DMA_PIPE_RESERVED + should be ORed with other configuration parameters + + for ex. dma_info.mode=DMA_PIPE_RESERVED | + FLOW_CNTRL_DMA(MEM_TO_PERIPH); + + g) Mode of operation: Channel Priority + At hardware level there are total 16 DMA pipes (i.e. 8 on each + DMAC) each having its priority (i.e. pipe 0 having highest and 7 with + lowest). but since the pipes are allocated dynamically you never know + which pipe will be assigned to which channel. To take care of this + issue driver has in-built channel priority policy manager + + Priority DMAC0 PIPES DMAC1 PIPES Policy + ----------------------------------------------------- + Highest | 0 | | 1 | HIGH + . | 2 | | 3 | (0->15) + . ----------------------------------------------------- + . | 4 | | 5 | NORMAL + . | 6 | | 7 | (4->15) + . ----------------------------------------------------- + . | 8 | | 9 | LOW + . | 10 | | 11 | (8->15) + . ----------------------------------------------------- + . | 12 | | 13 | UNDEFINED (fm 15->0) + Lowest | 14 | | 15 | For MEM-To MEM Xfer (15->12) + ----------------------------------------------------- + + Channel priority setup during configuration tells additional + information to the driver that the channel under request has a + particular priority. And the pipe allocation policy of a driver + allocates a pipe accordingly for a transfer under schedule. + + By default DMA_EXCH_PRIORITY_UNDEFINED is set for each channel, as + per policy the free and available pipe search will be started from + lowest to highest. + there are three other priorities HIGH, NORMAL and LOW which can be set + by ORing respective macro with other configuration parameters + + for ex. dma_info.mode=DMA_EXCH_PRIORITY_HIGH | + FLOW_CNTRL_DMA(MEM_TO_PERIPH); + + Channel priority setup macros for configurations- + DMA_EXCH_PRIORITY_UNDEFINED + DMA_EXCH_PRIORITY_LOW + DMA_EXCH_PRIORITY_NORMAL + DMA_EXCH_PRIORITY_HIGH + + h) Mode of operation: Queueing DMA transfer requests + In the standard kernel DMA interface channel queueing is not allowed + once enable_dma request is executed system discards all subsequent + enable_dma request untill DMA finishes first scheduled request. + Nomadik DMA driver provides you flexibility to enable and use this + feature if required. Enabling this feature will accept all subsequent + enable_dma requests and queue them in a pipe, as system finishes + current transfer, next pre-scheduled transfer in a queue will be + executed, thus all enable_dma requests can be processed. + + This feature can be enabled by ORing a macro DMA_QUEUE_ENABLED with + other configuration parameters + + for ex. dma_info.mode=DMA_QUEUE_ENABLED | + FLOW_CNTRL_DMA(MEM_TO_PERIPH); + +4. DMA Interrupt hanndling for callback functions. +====================================================== +When you schedule a DMA transfer, there should be a mechanism by which you know +the transfer is finished sucessfully. In Nomadik DMA transfer a terminal +count interrupt will be generated at the end of sucessfull transfer which can +be requested and processed like any other standard interrupt. + +There are S/w decoded IRQs associated with all DMA channels. +the macro IRQNO_FOR_DMACH(dmach) is provided to find irq for a DMA channel and +the macro DMACH_FOR_IRQNO(irq) can be used to find DMA channel for irq number + +The DMA callback functions can be invoked as interrupt handler and requested +through standard system calls i.e request_irq and free_irq. + +It is recommented to use your own tasklets to do deffered processing +since it may block other DMA interuppts being processed in time. + +Below system messages indicates that irqno 188 to 191 are DMA interrupts +root@NDK10_A0:/home/prafulla/alsa# cat /proc/interrupts + CPU0 + 4: 12077:PL02 - Nomadik Timer Tick + 10: 0 - rtc + 11: 0 - ssp + 17: 581:PL08 - uart-pl011 + 19: 6:PL10 - msp + 20: 33 - i2c0 + 21: 296 - i2c1 + 22: 81:PL02 - NMDK_MMC (data) + 26: 1 - SAA0 + 27: 0 - SAA1 +113: 0 - mmc_detect +168: 19176:PL08 - eth0 +188: 46 dummy dmaclbk-sdmmc->mem +189: 0 dummy +190: 10462 dummy dmaclbk-msp0rx->mem +191: 10437 dummy dmaclbk-mem->msp0tx +Err: 0 + +5. Scatter-gather Support +====================================================== +The Nomadik DMA driver supprts scatter-gather transfer for MEM_TO_PERIPH and +PERIPH_TO_MEM type of data transfer. to use scatter gather suport following +sequence must be executed. + a) request_dma, request_irq + b) get the *sg and sg_len form the upper layers + c) execute dma_map_sg with above information + d) set peripharal DMA address (__set_dma_srcaddr / __set_dma_srcaddr) + e) set memory DMA address using set_dma_sg API with sg information + f) set_dma_count for transfer size + g) execute enable_dma + h) wait for transfer complete event through callback + i) unmap sg list using dma_unmap_sg + j) free_dma + +6. /proc/dma interfce. +====================================================== +/proc/dma entry is created to show the information of allocated DMA resources +executing cat /proc/dma will list the allocation of all used DMA channles + +for ex- +root@NDK10_A0:/home/prafulla/alsa# cat /proc/dma + 0: DMACH: sdmmc->mem + 1: DMACH: mem->sdmmc + 2: DMACH: msp0rx->mem + 3: DMACH: mem->msp0tx + +7. HOWTO add new DMA peripharal device support +====================================================== +As per multiboard strategy +(ref : ./Documentation/arm/STM-Nomadik/HOWTO-add_newboard.txt) +for each supported SOC there is an arch/arm/mach-nomadik/_devices.c +In this file there is data structure "dmadev_default_config_tbl" +Add a new entry for the table for new DMA peripharal device +(refer Architecture.DMA Support Chapter fo SOC specification) + +for ex- + {.id = "sdmmc", + .config = ( DMA_AHB_M0 | DMA_ADR_NOINC | DMA_WIDTH_WORD | + DMA_BSIZE_8 | DMA_REQUEST_LINE(21) | + DMA_DEV_BSIZE_CONFIGURABLE | DMA_DEV_WIDTH_CONFIGURABLE | + DMA_DEV_DMAC1_CANBE_USED ),}, + + explaination: + id: This is the unique identification string will be used in + configuration as srcdevtype or destdevtype. + config: This should be ORed value of following selection + a) DMA_AHB_M0 : to select AHB master 0 for this device + or + DMA_AHB_M1 : to select AHB master 1 for this device + + b) DMA_ADR_INC : to indicate DMA address is incremented after + each transfer (memory, buffer case) + or + DMA_ADR_NOINC : to indicate DMA address is not incremented + after each transfer (fifo case) + + c) DMA_WIDTH_WORD : to select word(32bits) as transfer width + or + DMA_WIDTH_HALFWORD: to select halfword(16bits) as transfer width + or + DMA_WIDTH_BYTE : to select byte(8bits) as transfer width + + d) DMA_BSIZE_1 : to indicate 1 byte makes one DMA brust + or + DMA_BSIZE_4 : to indicate 4 bytes makes one DMA brust + or + DMA_BSIZE_8 : to indicate 8 bytes makes one DMA brust + or + DMA_BSIZE_16 : to indicate 16 bytes makes one DMA brust + or + DMA_BSIZE_32 : to indicate 32 bytes makes one DMA brust + or + DMA_BSIZE_64 : to indicate 64 bytes makes one DMA brust + or + DMA_BSIZE_128 : to indicate 128 bytes makes one DMA brust + or + DMA_BSIZE_256 : to indicate 256 bytes makes one DMA brust + + e) DMA_REQUEST_LINE(x) : program peripharal request line number + (x less than 32) + + f) DMA_DEV_BSIZE_CONFIGURABLE: to indicate the burst size can be + probrammed by user + or + DMA_DEV_BSIZE_NOT_CONFIGURABLE: to indicate the burst size can + not be probrammed by user + g) DMA_DEV_DWIDTH_CONFIGURABLE: to indicate the transfer width can + be probrammed by user + or + DMA_DEV_DWIDTH_NOT_CONFIGURABLE: to indicate the transfer width + can not be probrammed by user + + h) DMA_DEV_DMAC1_CANBE_USED: to indicate DMA controller1 can be + used for the transfer + or + DMA_DEV_DMAC0_CANBE_USED: to indicate DMA controller0 can be + used for the transfer + or + DMA_DEV_BOTH_DMACS_CANBE_USED: to indicate both DMA controllers + 0 and 1 can be used for the transfer + +8. System Limitations and Solutions: +===================================== +1. MAX_DMA_CHANNELS: This macro is defined (include/asm-arm/arch-nomadik/dma.h) + that defiens max no. of dma channels that can be used simultenously. if in + complex system scenario these channels are insuffienent, you may increase + this number as per your needs. +2. MAX_DMA_LLIS: This macro is defined (include/asm-arm/arch-nomadik/dma.h) + that defiens max no. of LLIs used internally by dma driver. lli pool is + internally maitained by driver and aquired whenver there is a enable_dma + request and freed at each dma transfer completion. In a dynamic system + usage a run time message "unable to find free lli.. rechecking..." can be + observed, if such case you may increase the defined value for this macro, + Assiging very large value eats free DMAble memory. + +============================================================================== + + --- /dev/null +++ linux-2.6.20/Documentation/arm/STM-Nomadik/faqs.txt @@ -0,0 +1,53 @@ +Filename: ./Documentation/arm/STM-Nomadik/faqs.txt +Author: Prafulla Wadaskar (prafulla.wadaskar@st.com) +Owner: STMicroelectronics +Purpose: + This documents describes frequesnty occuring problems and + their brief solutions while using Nomadik-BSP +============================================================================= + +This document is valid subject to assumption - +1. valid kernel source code with Nomadik support is available + +F.A.Qs +====== +Q: I am not getting console on CLCD even though CLCD is enabled +A: check your command line arguments, there should not be any console related + configuration, in this case by default console will be configured to CLCD. + In this case system will seek console input from standard input device. + +Q: NFS boot is giving messages "server not responding" very frequently +A: This may be due to network congestion, try NFS boot using "tcp" option + (Ex. root=/dev/nfs nfsroot=:,tcp + ip=:::255.255.255.0::: + console=ttyAMA1 mem=64M init=linuxrc) + +Q. How to enable/Disable cursor on CLCD panel? +A. Create a dummy node "mknod /dev/dummy c 4 0 ". + execute a command "echo -e "\033[?1c" > /dev/dummy" to disable the cursor + and "echo -e "\033[?0c" > /dev/dummy" to enable the cursor + You can also use the "setterm" program to control this and other aspects of + the console. "setterm -cursor off > /dev/tty0" will do what you want. + "man setterm" will give a vast list of stuff. + There is more here: + http://linux.bri.st.com/docs/manual/distribution/distribution_guide10.php + +Q. How to disable CLCD screen blanking +A. Create a dummy node "mknod /dev/dummy c 4 0 ". + Execute a command "echo -e "\033[9;0]" > /dev/dummy", this will set + screen blanking interval to 0 and will not blank the screen at all. + +Q. Generally when the kernel is up and running, CLCD is active but after some + time screen gets blanked, How to unblank the already blanked CLCD screen ? +A. Create a dummy node "mknod /dev/dummy c 4 0 ". + Execute a command "echo -e "\033[13]" > /dev/dummy", this will activate + CLCD screen. + +Q. How to enable L2 Cache for Nomadik SOCs +A. Switch to kernel source path, execute "make menuconfig" + Enable option "Enable L2 Cache controller" at location "x -> System Type" + L2CC is not available on STn8810 SOC versions + +============================================================================== + + --- /dev/null +++ linux-2.6.20/Documentation/arm/STM-Nomadik/gpio_user_guide.txt @@ -0,0 +1,140 @@ +Filename: ./Documentation/arm/STM-Nomadik/gpio_user_guide.txt +Author: Prafulla Wadaskar (prafulla.wadaskar@st.com) +Owner: STMicroelectronics +Purpose: + This Users Guide explains GPIO implimentation and its usage + from other drivers for Nomadik platforms +============================================================================= + +This document is valid subject to assumption - +1. valid kernel source code with Nomadik support is available + +GPIO Configuration: +=================== +By default GPIO driver is configured to link staticlly with kernel becasue +it is tightly coupled with irq.c. GPIO is necessary for Nomadik architecture + +Brief Architecture: +GPIO dirver is registered as amba device and will be probed only if +matches peripharal ID, the SOC specific data and function iterface is provided +through platfrom_data pointer to allign driver code in sync with multiboard +strategy. + +GPIO driver mainly provides two kinds of functionality +1. GPIO Interrupt hanndling and control. +2. Exported GPIO APIs + 2.1 Usage of GPIO pins/block for read write APIs + 2.2 Configuration for Alternate functions APIs + +1. GPIO Interrupt hanndling and control:- +============================================== +VIC generates a common interrupt for all 32 pins in a block, there are such +three to four blocks in a SOC, Each GPIO interrupt can be considered as +standard IRQ and can be processed through generic system call (please refer +irq_usrguide.txt). Further GPIO interrupts are softdecoded hence canot be +programmed as priority interrupts individually, + +2. Exported GPIO APIs +===================== +All exported GPIOs are protected against call before initialization. This +means if the GPIO driver cannot be probled due to any reasons and you try to +use GPIO exported APIs, and error will be returned. +APIS nomadik_gpio_readpin and nomadik_gpio_readblock are not protected against +interrupt configuration becasue reading a GPIO does not harm its usage from +other context. Where as all other APIS are protected against interrupt +cnfiguration. This means if the interrupt is already requested on a GPIO pin +the same pin cannot be configured untill you free that interrupt. + +2.1 Usage of GPIO pins/block for read write APIs +================================================ + a) nomadik_gpio_setpinconfig: + Individual pin can be configured for desired operation. + for ex. + mmc_pin.dev_name = "test"; + mmc_pin.mode = GPIO_MODE_SOFTWARE; + mmc_pin.direction = GPIO_DIR_OUTPUT; + mmc_pin.debounce = GPIO_DEBOUNCE_ENABLE; + mmc_pin.debounce_time = GPIO_DEBOUNCE_TIME_60_MICROSEC; + ret = nomadik_gpio_setpinconfig(GPIO_PIN_75, &mmc_pin); + + The above code will configure GPIO_PIN_75 in GPIO mode used as output + pin, enabled debouncing logic and set debounce time to 60 miroseconds. + debounce logic will be enabled if supported by the SOC version. + dev_name is a client device name to which the GPIO will be allocated. + + b) nomadik_gpio_resetpinconfig: + sets the particular pin to its reset state. + + c) nomadik_gpio_writepin; + write HIGN or LOW value on specified pin + + d) nomadik_gpio_readpin; + reads HIGN or LOW value from specified pin + + e) nomadik_gpio_readblock; + write multiple bits on specifed group of GPIOs + ex. + err = nomadik_gpio_writeblock(GPIO_BLOCK_32_BITS_64_TO_95, + , 0x0000aa00, 0x0000fc00); + + The above code writes HIGH on GPIO_PIN_74, LOW on GPIO_PIN_75, + HIGH on GPIO_PIN_76, LOW on GPIO_PIN_77, and HIGN on GPIO_PIN_78 + + f) nomadik_gpio_writeblock; + reads multiple bits on specifed group of GPIOs + +2.2 Configuration for Alternate functions APIs +================================================ + a) nomadik_gpio_altfuncenable: + Sets the group of GPIOs dedicated for spefic alternate mode of + operation. + + for ex. + retval = nomadik_gpio_altfuncenable(GPIO_ALT_I2C_0, "I2C_0"); + + The above code configures GPIOs 62 abd 63 (in case of stn8810) for + altfun_A, the detailed information which pins to be configured in which + mode for specified gpio_alt_function value(GPIO_ALT_I2C_0) is decided by + the gpio_altfun_tbl[] declared in _devices.c. It has table entries + whcih controls altfun configuration. + + for example entry in table + {.altfun = GPIO_ALT_I2C_0,.start = 62,.end = 63,.cont = 0,.type = + GPIO_ALTF_A,}, + states that- for gpio_alt_function value GPIO_ALT_I2C_0, from gpio pins 62 + to 63 needs to be configured for alternate function A. cont=0 specifies that + there are no further pins to be configured for GPIO_ALT_I2C_0. + + example for cont=1 + {.altfun = GPIO_ALT_MM_CARD,.start = 8,.end = 10,.cont = 1,.type = + GPIO_ALTF_A,}, + {.altfun = GPIO_ALT_SD_CARD,.start = 82,.end = 87,.cont = 1,.type = + GPIO_ALTF_A,}, + {.altfun = GPIO_ALT_MM_CARD,.start = 14,.end = 16,.cont = 0,.type = + GPIO_ALTF_A,}, + + In the above example cont=1 in first and second declaration states that there + are additional entries in sequence to configure pins (82 to 87) and (14 to 16) + in altfun A mode for the same gpio_alt_function value GPIO_ALT_MM_CARD + + b) nomadik_gpio_altfuncdisable: + This API reconfigures the group of GPIOs dedicated for specific + alternate mode of operation in to GPIO mode. + +Secured GPIO Access: +=================== +To prevent GPIO resources getting used/altered by unauthorised way, a method +is provided to give secured control. When gpio is requested by setpinconfig, +you need to specify dev_name, GPIO driver records the information that the +particular pin is alloocated the client named "dev_name", while doing +resetpinconfig the same dev_id must be passed. +Simillarly the same should be followed while requesting enabling/disabling altfunction. +When the GPIO is requested for interrupt, the specified devname will be +configured as client name. + +/proc/gpio interface: +==================== +/proc/gpio entry is created to show the information of allocated GPIO resources + +======================================================================================= + --- /dev/null +++ linux-2.6.20/Documentation/arm/STM-Nomadik/irq_usrguide.txt @@ -0,0 +1,171 @@ +Filename: ./Documentation/arm/STM-Nomadik/irq_usrguide.txt +Author: Prafulla Wadaskar (prafulla.wadaskar@st.com) +Owner: STMicroelectronics +Created: 9th June 2007 + +Purpose: +This Users Guide explains interrupts implimentation and its usage from other +client drivers for Nomadik platforms + +This document is valid subject to assumption - +1. valid kernel source code with Nomadik support is available + +Generic: +======== +All the available interrupts can be used in through standard system calls +To use nomadik interrupts, include ONLY in your code +Interrupt numbers generic to all Nomadik cuts are defined in irqs.h +Interrupt numbers specific to Nomadik cut is defined in _devices.h +(refer HOWTO-add_newboard.txt for more information) + +IRQ Description: +================ +for stn8810 chip: + IRQ0 to IRQ31 : IRQ lines provided by the VIC for different + on-chip peripharals. + IRQ32 to IRQ127 : IRQ lines for GPIO interrupts + +for stn8815 chip: + IRQ0 to IRQ63 : IRQ lines provided by the VIC for different + on-chip peripharals. + IRQ64 to IRQ191 : IRQ lines for GPIO interrupts + +Specific: +======== +1. Vectored Interrupt Controller (VIC) Interrupt Priority configuration:- +======================================================================== +Generally whenever there is IRQ request to the VIC it will be processed +immediately, if two or more IRQs active at a time then first in a sequence +(i.e lower in number) will be processed first (this depends how you decode +irqnr in entry-macro.S). + +Vectored interrupt processing hardware on Nomadik SOC is used to detect, +process and service the interrupts in prioritized manner. +This provides faster interrupt processing for comples decision. +This adds more flexibility to the system and to the driver developers to +take complex decision making about which interrupt to be proceesed first +when more than one IRQ goes active at a time. + +also while processing priority interrupt all lower priority interrupts will +be disabled by hardware whereas all higher priority interrupts will be active. +This adds a benefit to use SA_IRQPRIORITY_x over SA_INTERRUPT becasue +SA_INTERRUPT disables all interrupt while processign it. + +Any 15 (maximum) IRQs lines of VIC can be programmed for priority, +GPIO_IRQs cannot be programmed for priority since the are softdecoded. + +How to program a interrupt for desired priority? +================================================ +this can be done in two ways +a. using request_irq + for ex. + err = request_irq(IRQ_UART1, test_inthandle, SA_IRQPRIORITY_4, + "test", test_data); + + will request IRQ with interrupt priority level 4 + +b) using set_irq_type + This call can be used any time after requesting a interrupt to + to enable/disable/change priority level for specific IRQ line + + For ex. + set_irq_type(IRQ_UART1, SA_IRQPRIORITY_10); + + will enable priority level for pre-requested IRQ + if IRQ was requested with different priority level earlier, + this call will change it to specified level + +How to disable interrupt priority for a IRQ? +=========================================== +a) using set_irq_type api + This call can be used any time after requesting a interrupt to + to enable/disable/change priority level for specific IRQ line + + For ex. + set_irq_type(IRQ_UART1, SA_IRQPRIORITY_DISABLE); + + will disable priority level for pre-requested IRQ and will configure + if as normal IRQ + +How to know which IRQs are programmed for priority? +=================================================== +executing cat /proc/interrupts interface will display all interrupt information +if any IRQ is programmed with some priority then it will reflect as- + +# cat /proc/interrupts + CPU0 + 4: 143193 Nomadik Timer Tick + 10: 0 rtc + 11: 0 ssp + 13: 1 dma1 + 15: 0 dma0 + 17: 745 uart-pl011 + 20: 0 i2c0 + 21: 4 i2c1 + 22: 132 NMDK_MMC (data) + 30: 0:PL07 msp1 + 31: 0 msp2 + 72: 122 nmdk-kp + 77: 433 eth0 + 79: 5175 nmdk-tp + 81: 32 mmc_detect +Err: 0 +# + +Above message indicates that IRQ30 for msp1 is programmed as priority interrupt +with level 7. + +2. GPIO Interrupt hanndling and control:- +============================================== +GPIO Interrupt control is handled through standard system calls. The macros +(IRQNO_GPIO(x) and GPIO_PIN_FOR_IRQ(x)) are provided to find out interrupt +number associated with GPIO and vice-versa. +Following system calls are suported for GPIO interrupt control:- +a) request_irq/ free_irq: + works in a standard way to request and free GPIO interrupt. + When request_irq is invoked for GPIO, it first configures GPIO pin + for input operation with debounce disable (if supported). Then it sets + interrupt type for falling edge detection by default if not specified + in interrupt_flags. You can set type of interrupt during request by + passing required SA_TTRIGGER_ flags. GPIO interrupt type will be set + during request_irq call if the requested interrupt is NOT shared. + + for ex. + err = request_irq(IRQNO_GPIO(x), test_inthandle, SA_TRIGGER_RISING, + "test", test_data); + + will request rising edge interrupt for GPIO x + +b) enable_irq/disable_irq: + These are standard system calls can be used to enable or disable GPIO + irqs whenever required. + + for ex. + enable_irq(IRQNO_GPIO(x)); + + will enable interrupt for GPIO x + +c) set_irq_type: + By defult interrupt is requested as falling edge through request_irq call. + If you want to use other type of interrupt detection, this call can be used. + This call will be necessary to configure shared GPIO interrupt + + For ex. + set_irq_type(IRQNO_GPIO(x), SA_TRIGGER_LOW); + sets irq type as low level detection + + set_irq_type(IRQNO_GPIO(x), (SA_TRIGGER_RISING|SA_TRIGGER_FALLING); + sets irq type for both edges detection + + Please note that set_irq_type overwites previous irq_type, hence the GPIO + interrupt behaviour depends upon where you call this API. + + for ex. if you set_irq_type first and then requested interrupt, the + request_irq will overwrite the previously set irq type and vice versa. + +d) enable_irq_wake/disable_irq_wake: + the frame work is provided to handle these call for GPIO interrupt to + enable/disable wakup event generation to the power management unit. + +=============================================================================== + --- /dev/null +++ linux-2.6.20/Documentation/arm/STM-Nomadik/power_management.txt @@ -0,0 +1,122 @@ + + * 1 Nomadik Power Management Strategy + * ========================================== + * Power in nomadik can be saved by following features + * 1. Enable idle tick suppression or dynamic tick + * 2. Frequency scaling + * 3. Voltage scaling + * 4. Take system into soft sleep + * 5. Take system into deep sleep + * 6. Taking individual device (eg. CLCD) into suspend state + * + * + * 1.1 How to Enable idle tick suppression or dynamic tick + * ========================================================= + * + * 1. Select CONFIG_NO_IDLE_HZ in kernel features in kernel configuration + * 2. To enable dynamic tick + * echo -n 1 > /sys/devices/system/timer/timer0/dyn_tick + * 3. Dynamic tick can be disabled by + * echo -n 0 > /sys/devices/system/timer/timer0/dyn_tick + * 4. In idle thread, arm put itself in WFI, hence power is saved. By using + * dynamic tick we can put ARM in WFI for longer duration + * + * 1.2 Scaling frequencies + *==================================== + * 1. Select CONFIG_CPU_FREQ & CONFIG_CPU_FREQ_NOMADIK in kernel configuration + * during compilation + * 2. Check current frequency (In Khz) by + * cat /sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_cur_freq + * 3. Change system freq by + * echo -n /sys/devices/system/cpu/cpu0/cpufreq/scaling_setspeed + * If entered freq is not supported in system then next higher valid + * frequency is set + * 4. For frequencies which require voltage change, new voltage will be + * reflected. It can be checked by voltage sysfs file + * 5. If mapping for frequency and voltage is changed then change is required + * in arch/arm/mach-nomadik/power.c + * 6. If different SDRAM parameters are to be changed then change is required + * in arch/arm/mach-nomadik/power.c + * 7. If frequencies are to be altered then change is required in arch/arm/mach-nomadik/power.c + * + * + * 1.3 Scaling Voltage + *==================================== + * 1. To enable voltage scaling either CONFIG_CPU_FREQ or CONFIG_PM_NOMADIK + * must be selected in configuration + * 2. Current voltage can be checked by + * cat /sys/nomadik/current_voltage + * VOLTAGE will be shown in milli volt + * 3. To change in current voltage without changing frequency use + * echo < voltage in milli volt > > current_voltage + * However directly changing voltage without frequency is not recommended + * but can be used for performance/testing purpose. + * 4. If voltages are to be altered then change is required in arch/arm/mach-nomadik/power.c + * + * + * 1.4 Taking system into soft sleep + *==================================== + * 1. Select CONFIG_PM and CONFIG_NOMADIK_PM and CONFIG_NOMADIK_RTC + * 2. Change required sleep type to softsleep by + * echo -n softsleep > /sys/nomadik/sleep_type + * 3. To take system into sleep use + * echo -n mem > /sys/power/state + * 4. Wakeup can be done by RTC or keypad/touch panel/MMC + * 5. To specify rtc wakeup duration ( sleeping time ) + echo -n >sleep_duration + Default sleep duratioon is 15 seconds + * 6. To take system directly into soft sleep without linux power management + * framework use + * echo 1 > /sys/nomadik/softsleep_enable + * This is to be used when we are sure that no driver is active i.e. + * driver need not be be suspended. This interface can save transition + * time but is not recommended. It can be used for testing purpose. + * + * + * 1.5 Taking system into deep sleep + *==================================== + * 1. Select CONFIG_PM and CONFIG_NOMADIK_PM and CONFIG_NOMADIK_RTC + * 2. Change required sleep type to deepsleep by + * echo -n deepsleep > /sys/nomadik/sleep_type + * 3. To take system into sleep use + * echo -n mem > /sys/power/state + * 4. Wakeup can be done by RTC or keypad/touch panel/MMC + * 5. To specify rtc wakeup duration ( sleeping time ) + * echo -n >sleep_duration + * Default sleep duration is 15 seconds + * + * 1.6 Taking Individual device into suspend/resume state + *======================================================= + * 1. Individual device can be taken into suspended state by writing into sysfs + * file. Similiarly device can be resumed back + * 2. For example to take CLCD into suspend state use + echo -n 2 > /sys/devices/mb:c0/power/state + * 3. For example to take CLCD into resumed state use + echo -n 0 > /sys/devices/mb:c0/power/state + * 4. Similar things can be done for other devices. Few devices such as RTC, + * GPIO should not be takne into suspend state by this interface. + * + * + * 1.7 Enabling/Disabling Individual devices(Keypad, Touchpanel, MMC) as wakeup devices + *=================================================================================== + * 1. To enable a device (for e.g. keypad ) to be able to wakeup system from sleep do + * echo enabled > /sys/devices/platform/nmdk-kp.0/power/wakeup + * 2. To enable a device (for e.g. keypad ) to be able to wakeup system from sleep do + * echo disabled > /sys/devices/platform/nmdk-kp.0/power/wakeup + * If a device's wakeup state is disabled, it cannot be used for waking the + * system from sleep. + * 3. Above steps are applicable for any device that can wakeup the system + * + * + * 1.8 To add a device that can be used to wakeup + *================================================ + * 1. To make a platform device to be able to wakeup a system, change is + * required in board specific file like arch/arm/mach-nomadik/ndk15_devices.c + * 2. To make a amba device to be able to wakeup a system, change is required + * in platform specific file like arch/arm/mach-nomadik/stn8815_devices.c + * + * + * + */ + + --- linux-2.6.20.orig/MAINTAINERS +++ linux-2.6.20/MAINTAINERS @@ -1939,10 +1939,19 @@ M: ebiederm@xmission.com W: http://www.xmission.com/~ebiederm/files/kexec/ L: linux-kernel@vger.kernel.org L: fastboot@osdl.org S: Maintained +KGDB +P: Tom Rini +P: Amit S. Kale +M: trini@kernel.crashing.org +M: amitkale@linsyssoft.com +W: http://sourceforge.net/projects/kgdb +L: kgdb-bugreport@lists.sourceforge.net +S: Maintained + KPROBES P: Prasanna S Panchamukhi M: prasanna@in.ibm.com P: Ananth N Mavinakayanahalli M: ananth@in.ibm.com --- linux-2.6.20.orig/Makefile +++ linux-2.6.20/Makefile @@ -10,11 +10,11 @@ NAME = Homicidal Dwarf Hamster # Comments in this file are targeted only to the developer, do not # expect to learn how to build the kernel reading this file. # Do not: # o use make's built-in rules and variables -# (this increases performance and avoid hard-to-debug behavour); +# (this increases performance and avoids hard-to-debug behaviour); # o print "Entering directory ..."; MAKEFLAGS += -rR --no-print-directory # We are using a recursive build, so we need to do a little thinking # to get the ordering right. @@ -319,11 +319,11 @@ AFLAGS := -D__ASSEMBLY__ # Read KERNELRELEASE from include/config/kernel.release (if it exists) KERNELRELEASE = $(shell cat include/config/kernel.release 2> /dev/null) KERNELVERSION = $(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION) export VERSION PATCHLEVEL SUBLEVEL KERNELRELEASE KERNELVERSION -export ARCH CONFIG_SHELL HOSTCC HOSTCFLAGS CROSS_COMPILE AS LD CC +export ARCH CONFIG_SHELL HOSTCC HOSTCFLAGS CFLAGS CROSS_COMPILE AS LD CC export CPP AR NM STRIP OBJCOPY OBJDUMP MAKE AWK GENKSYMS PERL UTS_MACHINE export HOSTCXX HOSTCXXFLAGS LDFLAGS_MODULE CHECK CHECKFLAGS export CPPFLAGS NOSTDINC_FLAGS LINUXINCLUDE OBJCOPYFLAGS LDFLAGS export CFLAGS CFLAGS_KERNEL CFLAGS_MODULE @@ -495,11 +495,11 @@ CFLAGS += -fno-omit-frame-pointer $(cal else CFLAGS += -fomit-frame-pointer endif ifdef CONFIG_DEBUG_INFO -CFLAGS += -g +CFLAGS += -gdwarf-2 endif # Force gcc to behave correct even for buggy distributions CFLAGS += $(call cc-option, -fno-stack-protector) @@ -528,11 +528,10 @@ export INSTALL_PATH ?= /boot # # INSTALL_MOD_PATH specifies a prefix to MODLIB for module directory # relocations required by build roots. This is not defined in the # makefile but the argument can be passed to make if needed. # - MODLIB = $(INSTALL_MOD_PATH)/lib/modules/$(KERNELRELEASE) export MODLIB # # INSTALL_MOD_STRIP, if defined, will cause modules to be @@ -574,11 +573,11 @@ libs-y := $(libs-y1) $(libs-y2) # Build vmlinux # --------------------------------------------------------------------------- # vmlinux is built from the objects selected by $(vmlinux-init) and # $(vmlinux-main). Most are built-in.o files from top-level directories -# in the kernel tree, others are specified in arch/$(ARCH)Makefile. +# in the kernel tree, others are specified in arch/$(ARCH)/Makefile. # Ordering when linking is important, and $(vmlinux-init) must be first. # # vmlinux # ^ # | @@ -732,18 +731,20 @@ debug_kallsyms: .tmp_map$(last_kallsyms) .tmp_map2: .tmp_map1 endif # ifdef CONFIG_KALLSYMS +include $(srctree)/scripts/ksymhash/Makefile # vmlinux image - including updated kernel symbols vmlinux: $(vmlinux-lds) $(vmlinux-init) $(vmlinux-main) $(kallsyms.o) FORCE ifdef CONFIG_HEADERS_CHECK $(Q)$(MAKE) -f $(srctree)/Makefile headers_check endif $(call if_changed_rule,vmlinux__) $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modpost $@ $(Q)rm -f .old_version + $(rule_ksymhash) # The actual objects are generated when descending, # make sure no implicit rule kicks in $(sort $(vmlinux-init) $(vmlinux-main)) $(vmlinux-lds): $(vmlinux-dirs) ; @@ -1480,11 +1481,16 @@ endif clean := -f $(if $(KBUILD_SRC),$(srctree)/)scripts/Makefile.clean obj endif # skip-makefile PHONY += FORCE -FORCE: +include/linux/dwarf2-defs.h: $(srctree)/include/linux/dwarf2.h $(srctree)/scripts/dwarfh.awk + mkdir -p include/linux/ + awk -f $(srctree)/scripts/dwarfh.awk $(srctree)/include/linux/dwarf2.h > include/linux/dwarf2-defs.h + +FORCE: include/linux/dwarf2-defs.h + # Cancel implicit rules on top Makefile, `-rR' will apply to sub-makes. Makefile: ; # Declare the contents of the .PHONY variable as phony. We keep that --- linux-2.6.20.orig/arch/arm/Kconfig +++ linux-2.6.20/arch/arm/Kconfig @@ -117,11 +117,11 @@ source "init/Kconfig" menu "System Type" choice prompt "ARM system type" - default ARCH_VERSATILE + default ARCH_NOMADIK config ARCH_AAEC2000 bool "Agilent AAEC-2000 based" select ARM_AMBA help @@ -201,10 +201,18 @@ config ARCH_NETX bool "Hilscher NetX based" select ARM_VIC help This enables support for systems based on the Hilscher NetX Soc +config ARCH_NOMADIK + bool "Nomadik" + select ARM_AMBA + select ISA_DMA_API + select ICST525 + help + Support for ARM's NOMADIK platform. + config ARCH_H720X bool "Hynix HMS720x-based" select ISA_DMA_API help This enables support for systems based on the Hynix HMS720x @@ -379,10 +387,11 @@ source "arch/arm/mach-realview/Kconfig" source "arch/arm/mach-at91rm9200/Kconfig" source "arch/arm/mach-netx/Kconfig" +source "arch/arm/mach-nomadik/Kconfig" # Definitions to make life easier config ARCH_ACORN bool config PLAT_IOP @@ -738,11 +747,11 @@ config XIP_PHYS_ADDR be linked for and stored to. This address is dependent on your own flash usage. endmenu -if (ARCH_SA1100 || ARCH_INTEGRATOR || ARCH_OMAP || ARCH_IMX ) +if (ARCH_SA1100 || ARCH_INTEGRATOR || ARCH_OMAP || ARCH_IMX || ARCH_NOMADIK ) menu "CPU Frequency scaling" source "drivers/cpufreq/Kconfig" @@ -774,10 +783,21 @@ config CPU_FREQ_IMX help This enables the CPUfreq driver for i.MX CPUs. If in doubt, say N. +config CPU_FREQ_NOMADIK + tristate "CPUfreq driver for ARM Nomadik CPUs" + depends on ARCH_NOMADIK && CPU_FREQ && NOMADIK_NDK15 + default y + select NOMADIK_DMA + help + This enables the CPUfreq driver for ARM Nomadik CPUs. + + For details, take a look at . + + If in doubt, say Y. endmenu endif menu "Floating point emulation" @@ -908,10 +928,11 @@ if PCMCIA || ARCH_CLPS7500 || ARCH_IOP32 || ARCH_S3C2410 || ARCH_SA1100 || ARCH_SHARK || FOOTBRIDGE \ || ARCH_IXP23XX source "drivers/ide/Kconfig" endif + source "drivers/scsi/Kconfig" source "drivers/ata/Kconfig" source "drivers/md/Kconfig" --- linux-2.6.20.orig/arch/arm/Makefile +++ linux-2.6.20/arch/arm/Makefile @@ -18,11 +18,11 @@ GZFLAGS :=-9 # Explicitly specifiy 32-bit ARM ISA since toolchain default can be -mthumb: CFLAGS +=$(call cc-option,-marm,) # Do not use arch/arm/defconfig - it's always outdated. # Select a platform tht is kept up-to-date -KBUILD_DEFCONFIG := versatile_defconfig +KBUILD_DEFCONFIG := ndk15_defconfig # defines filename extension depending memory manement type. ifeq ($(CONFIG_MMU),) MMUEXT := -nommu endif @@ -87,10 +87,11 @@ CHECKFLAGS += -D__arm__ #Default value head-y := arch/arm/kernel/head$(MMUEXT).o arch/arm/kernel/init_task.o textofs-y := 0x00008000 + machine-$(CONFIG_ARCH_RPC) := rpc machine-$(CONFIG_ARCH_EBSA110) := ebsa110 machine-$(CONFIG_ARCH_CLPS7500) := clps7500 incdir-$(CONFIG_ARCH_CLPS7500) := cl7500 machine-$(CONFIG_FOOTBRIDGE) := footbridge @@ -104,10 +105,11 @@ ifeq ($(CONFIG_ARCH_SA1100),y) textofs-$(CONFIG_SA1111) := 0x00208000 endif machine-$(CONFIG_ARCH_PXA) := pxa machine-$(CONFIG_ARCH_L7200) := l7200 machine-$(CONFIG_ARCH_INTEGRATOR) := integrator + machine-$(CONFIG_ARCH_NOMADIK) := nomadik textofs-$(CONFIG_ARCH_CLPS711X) := 0x00028000 machine-$(CONFIG_ARCH_CLPS711X) := clps711x machine-$(CONFIG_ARCH_IOP32X) := iop32x machine-$(CONFIG_ARCH_IOP33X) := iop33x machine-$(CONFIG_ARCH_IOP13XX) := iop13xx @@ -198,16 +200,25 @@ ifneq ($(KBUILD_SRC),) else $(Q)ln -fsn $(INCDIR) include/asm-arm/arch endif @touch $@ -archprepare: maketools +archprepare: maketools machprepare -PHONY += maketools FORCE +PHONY += maketools machprepare machclean machmrproper FORCE maketools: include/linux/version.h include/asm-arm/.arch FORCE $(Q)$(MAKE) $(build)=arch/arm/tools include/asm-arm/mach-types.h + +# Machine specific preparation if it exists +MACHPREPARE_PATH = $(strip `grep "machprepare:" $(MACHINE)Makefile* | grep -o $(MACHINE)`) + +machprepare: +ifeq ($(wildcard $(TOPDIR)/.config), $(TOPDIR)/.config) + $(Q)set -e; for i in $(MACHPREPARE_PATH); do $(MAKE) -C $$i $@; done +endif + # Convert bzImage to zImage bzImage: zImage zImage Image xipImage bootpImage uImage: vmlinux $(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $(boot)/$@ @@ -216,12 +227,27 @@ zinstall install: vmlinux $(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $@ CLEAN_FILES += include/asm-arm/mach-types.h \ include/asm-arm/arch include/asm-arm/.arch +# Machine specific mrproper operation if it exists +MACHMRPROPER_PATH =`find arch/$(ARCH)/mach-*/ -name Makefile | xargs grep machmrproper: | sed 's/Makefile:machmrproper://g' | sed 's/Makefile://g'` + +machmrproper: + $(Q)set -e; for i in $(MACHMRPROPER_PATH); do $(MAKE) -C $$i $@; done + +# We use MRPROPER_FILES +archmrproper: machmrproper + +# Machine specific clean operation +MACHCLEAN_PATH = `find arch/$(ARCH)/mach-*/ -name Makefile | xargs grep machclean: | sed 's/Makefile:machclean://g' | sed 's/Makefile://g'` + +machclean: + $(Q)set -e; for i in $(MACHCLEAN_PATH); do $(MAKE) -C $$i $@; done + # We use MRPROPER_FILES and CLEAN_FILES now -archclean: +archclean: machclean $(Q)$(MAKE) $(clean)=$(boot) # My testing targets (bypasses dependencies) bp:; $(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $(boot)/bootpImage i zi:; $(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $@ --- linux-2.6.20.orig/arch/arm/common/rtctime.c +++ linux-2.6.20/arch/arm/common/rtctime.c @@ -199,17 +199,17 @@ static int rtc_ioctl(struct inode *inode ret = -EFAULT; break; } alrm.enabled = 0; alrm.pending = 0; - alrm.time.tm_mday = -1; +/* alrm.time.tm_mday = -1; alrm.time.tm_mon = -1; alrm.time.tm_year = -1; alrm.time.tm_wday = -1; alrm.time.tm_yday = -1; alrm.time.tm_isdst = -1; - ret = rtc_arm_set_alarm(ops, &alrm); +*/ ret = rtc_arm_set_alarm(ops, &alrm); break; case RTC_RD_TIME: ret = rtc_arm_read_time(ops, &tm); if (ret) --- /dev/null +++ linux-2.6.20/arch/arm/configs/ndk10_defconfig @@ -0,0 +1,1205 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.20 +# Thu Aug 16 17:17:58 2007 +# +CONFIG_ARM=y +# CONFIG_GENERIC_TIME is not set +CONFIG_MMU=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +CONFIG_HARDIRQS_SW_RESEND=y +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +# CONFIG_ARCH_HAS_ILOG2_U32 is not set +# CONFIG_ARCH_HAS_ILOG2_U64 is not set +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_VECTORS_BASE=0xffff0000 +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_LOCK_KERNEL=y +CONFIG_INIT_ENV_ARG_LIMIT=32 + +# +# General setup +# +CONFIG_LOCALVERSION="" +CONFIG_LOCALVERSION_AUTO=y +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +# CONFIG_IPC_NS is not set +# CONFIG_POSIX_MQUEUE is not set +# CONFIG_BSD_PROCESS_ACCT is not set +# CONFIG_TASKSTATS is not set +# CONFIG_UTS_NS is not set +# CONFIG_AUDIT is not set +# CONFIG_IKCONFIG is not set +CONFIG_SYSFS_DEPRECATED=y +# CONFIG_RELAY is not set +CONFIG_INITRAMFS_SOURCE="" +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SYSCTL=y +CONFIG_EMBEDDED=y +CONFIG_UID16=y +CONFIG_SYSCTL_SYSCALL=y +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_ALL is not set +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_HOTPLUG=y +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_ELF_CORE=y +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_SHMEM=y +CONFIG_SLAB=y +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_RT_MUTEXES=y +# CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 +# CONFIG_SLOB is not set + +# +# Loadable module support +# +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +# CONFIG_MODVERSIONS is not set +# CONFIG_MODULE_SRCVERSION_ALL is not set +# CONFIG_KMOD is not set + +# +# Block layer +# +CONFIG_BLOCK=y +# CONFIG_LBD is not set +# CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_LSF is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +CONFIG_DEFAULT_AS=y +# CONFIG_DEFAULT_DEADLINE is not set +# CONFIG_DEFAULT_CFQ is not set +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="anticipatory" + +# +# System Type +# +# CONFIG_ARCH_AAEC2000 is not set +# CONFIG_ARCH_INTEGRATOR is not set +# CONFIG_ARCH_REALVIEW is not set +# CONFIG_ARCH_VERSATILE is not set +# CONFIG_ARCH_AT91 is not set +# CONFIG_ARCH_CLPS7500 is not set +# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_CO285 is not set +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_EP93XX is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_NETX is not set +CONFIG_ARCH_NOMADIK=y +# CONFIG_ARCH_H720X is not set +# CONFIG_ARCH_IMX is not set +# CONFIG_ARCH_IOP32X is not set +# CONFIG_ARCH_IOP33X is not set +# CONFIG_ARCH_IOP13XX is not set +# CONFIG_ARCH_IXP4XX is not set +# CONFIG_ARCH_IXP2000 is not set +# CONFIG_ARCH_IXP23XX is not set +# CONFIG_ARCH_L7200 is not set +# CONFIG_ARCH_PNX4008 is not set +# CONFIG_ARCH_PXA is not set +# CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_SA1100 is not set +# CONFIG_ARCH_S3C2410 is not set +# CONFIG_ARCH_SHARK is not set +# CONFIG_ARCH_LH7A40X is not set +# CONFIG_ARCH_OMAP is not set +CONFIG_NOMADIK_NDK10_CUT_A1=y +# CONFIG_NOMADIK_NDK10_CUT_B06 is not set +# CONFIG_NOMADIK_NDK10_CUT_B0 is not set +# CONFIG_NOMADIK_NDK15_REV2_B_03 is not set +# CONFIG_NOMADIK_NDK15_REV2_B_05 is not set +# CONFIG_NOMADIK_NDK15_REV2_B_06 is not set +# CONFIG_NOMADIK_NDK15_REV3_C_02 is not set +CONFIG_NOMADIK_TARGET="NDK10_Cut_A1" +CONFIG_NOMADIK_SOC="stn8810" +CONFIG_NOMADIK_PLATFORM="ndk10" +CONFIG_NOMADIK_TARGET_EXTRA_CFLAGS="-D__RELEASE -D__STN_8810=10 -D__PLATFORM_MEVKFULL -D__UART_ELEMENTARY" +CONFIG_NOMADIK_NDK10=y +CONFIG_NOMADIK_NDK10_CUTA=y +CONFIG_NOMADIK_GPIO=y +CONFIG_GPIO_PROC=y +CONFIG_NOMADIK_DMA=y +CONFIG_NOMADIK_SSP=m +CONFIG_NOMADIK_MSP=m +CONFIG_NOMADIK_MTU=m +CONFIG_NOMADIK_MTU_SYSTEM_TICK=y +CONFIG_NOMADIK_RTC=y +# CONFIG_NOMADIK_SVA_INIT_MEM is not set +CONFIG_NOMADIK_SVA_MEM_SIZE=4 +# CONFIG_NOMADIK_SAA_INIT_MEM is not set +# CONFIG_FB_NOMADIK_VGA is not set +# CONFIG_FB_NOMADIK_CRT is not set +CONFIG_FB_NOMADIK_QVGA_PORTRAIT=y +# CONFIG_FB_NOMADIK_QVGA_LANDSCAPE is not set +# CONFIG_FB_NOMADIK_PANEL_8BPP is not set +CONFIG_FB_NOMADIK_PANEL_16BPP=y +# CONFIG_FB_NOMADIK_PANEL_24BPP is not set +CONFIG_SGA_INST_BUFFER_2=y +# CONFIG_SGA_INST_BUFFER_20 is not set +CONFIG_SGA_INST_BUFFER_NUM=2 +CONFIG_FB_NOMADIK_PANEL_BPP=16 +CONFIG_FB_NOMADIK_PANEL_NAME="QVGA_Portrait" +CONFIG_FB_NOMADIK_PANEL_XRES=240 +CONFIG_FB_NOMADIK_PANEL_YRES=320 +CONFIG_FB_NOMADIK_PANEL_LFMARGIN=0x13 +CONFIG_FB_NOMADIK_PANEL_RTMARGIN=0x2f +CONFIG_FB_NOMADIK_PANEL_UPRMARGIN=0x04 +CONFIG_FB_NOMADIK_PANEL_LWRMARGIN=0x0f +CONFIG_FB_NOMADIK_PANEL_HSLEN=0x13 +CONFIG_FB_NOMADIK_PANEL_VSLEN=0x04 +CONFIG_FB_NOMADIK_PANEL_TIM2VAL=0x00ef1804 + +# +# Processor Type +# +CONFIG_CPU_32=y +# CONFIG_CPU_ARM920T is not set +CONFIG_CPU_ARM926T=y +# CONFIG_CPU_ARM1020 is not set +# CONFIG_CPU_ARM1022 is not set +# CONFIG_CPU_ARM1026 is not set +# CONFIG_CPU_V6 is not set +CONFIG_CPU_32v5=y +CONFIG_CPU_ABRT_EV5TJ=y +CONFIG_CPU_CACHE_VIVT=y +CONFIG_CPU_COPY_V4WB=y +CONFIG_CPU_TLB_V4WBI=y +CONFIG_CPU_CP15=y +CONFIG_CPU_CP15_MMU=y + +# +# Processor Features +# +CONFIG_ARM_THUMB=y +# CONFIG_CPU_ICACHE_DISABLE is not set +# CONFIG_CPU_DCACHE_DISABLE is not set +# CONFIG_CPU_DCACHE_WRITETHROUGH is not set +# CONFIG_CPU_CACHE_ROUND_ROBIN is not set +CONFIG_ICST525=y + +# +# Bus support +# +CONFIG_ARM_AMBA=y +CONFIG_ISA_DMA_API=y + +# +# PCCARD (PCMCIA/CardBus) support +# +# CONFIG_PCCARD is not set + +# +# Kernel Features +# +CONFIG_PREEMPT=y +CONFIG_NO_IDLE_HZ=y +CONFIG_HZ=100 +CONFIG_AEABI=y +CONFIG_OABI_COMPAT=y +# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_FLATMEM_MANUAL=y +# CONFIG_DISCONTIGMEM_MANUAL is not set +# CONFIG_SPARSEMEM_MANUAL is not set +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +# CONFIG_SPARSEMEM_STATIC is not set +CONFIG_SPLIT_PTLOCK_CPUS=4096 +# CONFIG_RESOURCES_64BIT is not set +CONFIG_ALIGNMENT_TRAP=y + +# +# Boot options +# +CONFIG_ZBOOT_ROM_TEXT=0x0 +CONFIG_ZBOOT_ROM_BSS=0x0 +CONFIG_CMDLINE="root=/dev/ram0 console=ttyAMA1,115200n8 init=linuxrc" +# CONFIG_XIP_KERNEL is not set + +# +# CPU Frequency scaling +# +# CONFIG_CPU_FREQ is not set + +# +# Floating point emulation +# + +# +# At least one emulation must be selected +# +CONFIG_FPE_NWFPE=y +# CONFIG_FPE_NWFPE_XP is not set +# CONFIG_FPE_FASTFPE is not set +# CONFIG_VFP is not set + +# +# Userspace binary formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_AOUT is not set +# CONFIG_BINFMT_MISC is not set + +# +# Power management options +# +# CONFIG_PM is not set +# CONFIG_APM is not set + +# +# Networking +# +CONFIG_NET=y + +# +# Networking options +# +# CONFIG_NETDEBUG is not set +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +CONFIG_UNIX=y +CONFIG_XFRM=y +# CONFIG_XFRM_USER is not set +# CONFIG_XFRM_SUB_POLICY is not set +# CONFIG_NET_KEY is not set +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_FIB_HASH=y +# CONFIG_IP_PNP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_XFRM_TUNNEL is not set +# CONFIG_INET_TUNNEL is not set +CONFIG_INET_XFRM_MODE_TRANSPORT=y +CONFIG_INET_XFRM_MODE_TUNNEL=y +CONFIG_INET_XFRM_MODE_BEET=y +CONFIG_INET_DIAG=y +CONFIG_INET_TCP_DIAG=y +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_CUBIC=y +CONFIG_DEFAULT_TCP_CONG="cubic" +# CONFIG_TCP_MD5SIG is not set +CONFIG_IPV6=m +# CONFIG_IPV6_PRIVACY is not set +# CONFIG_IPV6_ROUTER_PREF is not set +# CONFIG_INET6_AH is not set +# CONFIG_INET6_ESP is not set +# CONFIG_INET6_IPCOMP is not set +# CONFIG_IPV6_MIP6 is not set +# CONFIG_INET6_XFRM_TUNNEL is not set +# CONFIG_INET6_TUNNEL is not set +CONFIG_INET6_XFRM_MODE_TRANSPORT=m +CONFIG_INET6_XFRM_MODE_TUNNEL=m +CONFIG_INET6_XFRM_MODE_BEET=m +# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set +CONFIG_IPV6_SIT=m +# CONFIG_IPV6_TUNNEL is not set +# CONFIG_IPV6_MULTIPLE_TABLES is not set +# CONFIG_NETWORK_SECMARK is not set +# CONFIG_NETFILTER is not set + +# +# DCCP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_DCCP is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_SCTP is not set + +# +# TIPC Configuration (EXPERIMENTAL) +# +# CONFIG_TIPC is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +# CONFIG_IEEE80211 is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +CONFIG_FW_LOADER=y +# CONFIG_DEBUG_DRIVER is not set +# CONFIG_SYS_HYPERVISOR is not set + +# +# Connector - unified userspace <-> kernelspace linker +# +# CONFIG_CONNECTOR is not set + +# +# Memory Technology Devices (MTD) +# +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +CONFIG_MTD_CONCAT=y +CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_REDBOOT_PARTS is not set +# CONFIG_MTD_CMDLINE_PARTS is not set +# CONFIG_MTD_AFS_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +# CONFIG_MTD_BLKDEVS is not set +# CONFIG_MTD_BLOCK is not set +# CONFIG_MTD_BLOCK_RO is not set +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set +# CONFIG_RFD_FTL is not set +# CONFIG_SSFDC is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_GEN_PROBE=y +# CONFIG_MTD_CFI_ADV_OPTIONS is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +CONFIG_MTD_CFI_INTELEXT=y +# CONFIG_MTD_CFI_AMDSTD is not set +CONFIG_MTD_CFI_STAA=y +CONFIG_MTD_CFI_UTIL=y +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set +# CONFIG_MTD_OBSOLETE_CHIPS is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +# CONFIG_MTD_PHYSMAP is not set +CONFIG_MTD_NOMADIK=y +# CONFIG_MTD_ARM_INTEGRATOR is not set +# CONFIG_MTD_PLATRAM is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_DATAFLASH is not set +# CONFIG_MTD_M25P80 is not set +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLOCK2MTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set + +# +# NAND Flash Device Drivers +# +CONFIG_MTD_NAND=y +CONFIG_MTD_NAND_NOMADIK=y +# CONFIG_MTD_NAND_VERIFY_WRITE is not set +# CONFIG_MTD_NAND_ECC_SMC is not set +CONFIG_MTD_NAND_IDS=y +# CONFIG_MTD_NAND_DISKONCHIP is not set +# CONFIG_MTD_NAND_NANDSIM is not set + +# +# OneNAND Flash Device Drivers +# +# CONFIG_MTD_ONENAND is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play support +# + +# +# Block devices +# +# CONFIG_BLK_DEV_COW_COMMON is not set +# CONFIG_BLK_DEV_LOOP is not set +# CONFIG_BLK_DEV_NBD is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=46080 +CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 +CONFIG_BLK_DEV_INITRD=y +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH is not set + +# +# SCSI device support +# +# CONFIG_RAID_ATTRS is not set +# CONFIG_SCSI is not set +# CONFIG_SCSI_NETLINK is not set + +# +# Serial ATA (prod) and Parallel ATA (experimental) drivers +# +# CONFIG_ATA is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# Fusion MPT device support +# +# CONFIG_FUSION is not set + +# +# IEEE 1394 (FireWire) support +# + +# +# I2O device support +# + +# +# Network device support +# +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set + +# +# PHY device support +# +# CONFIG_PHYLIB is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +CONFIG_MII=m +CONFIG_SMC91X=m +# CONFIG_DM9000 is not set + +# +# Ethernet (1000 Mbit) +# + +# +# Ethernet (10000 Mbit) +# + +# +# Token Ring devices +# + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_SHAPER is not set +# CONFIG_NETCONSOLE is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Input device support +# +CONFIG_INPUT=y +# CONFIG_INPUT_FF_MEMLESS is not set + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=m +CONFIG_INPUT_MOUSEDEV_PSAUX=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=240 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=320 +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set +CONFIG_INPUT_EVDEV=m +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +CONFIG_INPUT_KEYBOARD=y +# CONFIG_KEYBOARD_ATKBD is not set +# CONFIG_KEYBOARD_SUNKBD is not set +# CONFIG_KEYBOARD_LKKBD is not set +# CONFIG_KEYBOARD_XTKBD is not set +# CONFIG_KEYBOARD_NEWTON is not set +# CONFIG_KEYBOARD_STOWAWAY is not set +CONFIG_KEYPAD_NOMADIK=m +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +CONFIG_INPUT_TOUCHSCREEN=y +# CONFIG_TOUCHSCREEN_ADS7846 is not set +# CONFIG_TOUCHSCREEN_GUNZE is not set +# CONFIG_TOUCHSCREEN_ELO is not set +# CONFIG_TOUCHSCREEN_MTOUCH is not set +# CONFIG_TOUCHSCREEN_MK712 is not set +# CONFIG_TOUCHSCREEN_PENMOUNT is not set +# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set +# CONFIG_TOUCHSCREEN_TOUCHWIN is not set +# CONFIG_TOUCHSCREEN_UCB1400 is not set +CONFIG_TOUCHSCREEN_NOMADIK=m +# CONFIG_INPUT_MISC is not set + +# +# Hardware I/O ports +# +# CONFIG_SERIO is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +# CONFIG_VT_HW_CONSOLE_BINDING is not set +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +# CONFIG_SERIAL_8250 is not set + +# +# Non-8250 serial port support +# +# CONFIG_SERIAL_AMBA_PL010 is not set +CONFIG_SERIAL_AMBA_PL011=y +CONFIG_SERIAL_AMBA_PL011_CONSOLE=y +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +CONFIG_HW_RANDOM=m +# CONFIG_NVRAM is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_RAW_DRIVER is not set + +# +# TPM devices +# +# CONFIG_TCG_TPM is not set + +# +# I2C support +# +CONFIG_I2C=y +CONFIG_I2C_CHARDEV=y + +# +# I2C Algorithms +# +# CONFIG_I2C_ALGOBIT is not set +# CONFIG_I2C_ALGOPCF is not set +# CONFIG_I2C_ALGOPCA is not set + +# +# I2C Hardware Bus support +# +CONFIG_I2C_NOMADIK=y +# CONFIG_I2C_OCORES is not set +# CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_I2C_STUB is not set +# CONFIG_I2C_PCA_ISA is not set + +# +# Miscellaneous I2C Chip support +# +# CONFIG_SENSORS_DS1337 is not set +# CONFIG_SENSORS_DS1374 is not set +# CONFIG_SENSORS_EEPROM is not set +# CONFIG_SENSORS_PCF8574 is not set +# CONFIG_SENSORS_PCA9539 is not set +# CONFIG_SENSORS_PCF8591 is not set +# CONFIG_SENSORS_MAX6875 is not set +# CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +# CONFIG_I2C_DEBUG_CHIP is not set + +# +# SPI support +# +CONFIG_SPI=y +# CONFIG_SPI_DEBUG is not set +CONFIG_SPI_MASTER=y + +# +# SPI Master Controller Drivers +# +# CONFIG_SPI_BITBANG is not set +CONFIG_NOMADIK_SPI=m + +# +# SPI Protocol Masters +# + +# +# Dallas's 1-wire bus +# +# CONFIG_W1 is not set + +# +# Hardware Monitoring support +# +CONFIG_HWMON=y +# CONFIG_HWMON_VID is not set +# CONFIG_SENSORS_ABITUGURU is not set +# CONFIG_SENSORS_ADM1021 is not set +# CONFIG_SENSORS_ADM1025 is not set +# CONFIG_SENSORS_ADM1026 is not set +# CONFIG_SENSORS_ADM1031 is not set +# CONFIG_SENSORS_ADM9240 is not set +# CONFIG_SENSORS_ASB100 is not set +# CONFIG_SENSORS_ATXP1 is not set +# CONFIG_SENSORS_DS1621 is not set +# CONFIG_SENSORS_F71805F is not set +# CONFIG_SENSORS_FSCHER is not set +# CONFIG_SENSORS_FSCPOS is not set +# CONFIG_SENSORS_GL518SM is not set +# CONFIG_SENSORS_GL520SM is not set +# CONFIG_SENSORS_IT87 is not set +# CONFIG_SENSORS_LM63 is not set +# CONFIG_SENSORS_LM70 is not set +# CONFIG_SENSORS_LM75 is not set +# CONFIG_SENSORS_LM77 is not set +# CONFIG_SENSORS_LM78 is not set +# CONFIG_SENSORS_LM80 is not set +# CONFIG_SENSORS_LM83 is not set +# CONFIG_SENSORS_LM85 is not set +# CONFIG_SENSORS_LM87 is not set +# CONFIG_SENSORS_LM90 is not set +# CONFIG_SENSORS_LM92 is not set +# CONFIG_SENSORS_MAX1619 is not set +# CONFIG_SENSORS_PC87360 is not set +# CONFIG_SENSORS_PC87427 is not set +# CONFIG_SENSORS_SMSC47M1 is not set +# CONFIG_SENSORS_SMSC47M192 is not set +# CONFIG_SENSORS_SMSC47B397 is not set +# CONFIG_SENSORS_VT1211 is not set +# CONFIG_SENSORS_W83781D is not set +# CONFIG_SENSORS_W83791D is not set +# CONFIG_SENSORS_W83792D is not set +# CONFIG_SENSORS_W83793 is not set +# CONFIG_SENSORS_W83L785TS is not set +# CONFIG_SENSORS_W83627HF is not set +# CONFIG_SENSORS_W83627EHF is not set +# CONFIG_HWMON_DEBUG_CHIP is not set + +# +# Misc devices +# +# CONFIG_TIFM_CORE is not set + +# +# LED devices +# +# CONFIG_NEW_LEDS is not set + +# +# LED drivers +# + +# +# LED Triggers +# + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# +# Graphics support +# +CONFIG_FIRMWARE_EDID=y +CONFIG_FB=y +CONFIG_FB_CFB_FILLRECT=y +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_IMAGEBLIT=y +# CONFIG_FB_MACMODES is not set +# CONFIG_FB_BACKLIGHT is not set +CONFIG_FB_MODE_HELPERS=y +# CONFIG_FB_TILEBLITTING is not set +CONFIG_FB_ARMCLCD=y +# CONFIG_FB_S1D13XXX is not set +# CONFIG_FB_VIRTUAL is not set + +# +# Console display driver support +# +# CONFIG_VGA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE=y +# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set +CONFIG_FONTS=y +CONFIG_FONT_8x8=y +CONFIG_FONT_8x16=y +# CONFIG_FONT_6x11 is not set +# CONFIG_FONT_7x14 is not set +# CONFIG_FONT_PEARL_8x8 is not set +# CONFIG_FONT_ACORN_8x8 is not set +# CONFIG_FONT_MINI_4x6 is not set +# CONFIG_FONT_SUN8x16 is not set +# CONFIG_FONT_SUN12x22 is not set +# CONFIG_FONT_10x18 is not set + +# +# Logo configuration +# +CONFIG_LOGO=y +CONFIG_LOGO_LINUX_MONO=y +CONFIG_LOGO_LINUX_VGA16=y +CONFIG_LOGO_LINUX_CLUT224=y +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set + +# +# Sound +# +CONFIG_NOMADIK_ACODEC=m +CONFIG_NOMADIK_STW5094=y +# CONFIG_NOMADIK_STW5095 is not set +CONFIG_SOUND=m + +# +# Advanced Linux Sound Architecture +# +CONFIG_SND=m +CONFIG_SND_TIMER=m +CONFIG_SND_PCM=m +# CONFIG_SND_SEQUENCER is not set +# CONFIG_SND_MIXER_OSS is not set +# CONFIG_SND_PCM_OSS is not set +# CONFIG_SND_DYNAMIC_MINORS is not set +CONFIG_SND_SUPPORT_OLD_API=y +CONFIG_SND_VERBOSE_PROCFS=y +# CONFIG_SND_VERBOSE_PRINTK is not set +# CONFIG_SND_DEBUG is not set + +# +# Generic devices +# +# CONFIG_SND_DUMMY is not set +# CONFIG_SND_MTPAV is not set +# CONFIG_SND_SERIAL_U16550 is not set +# CONFIG_SND_MPU401 is not set + +# +# ALSA ARM devices +# +CONFIG_SND_NOMADIK_ALSA=m +# CONFIG_SND_ARMAACI is not set + +# +# Open Sound System +# +# CONFIG_SOUND_PRIME is not set + +# +# HID Devices +# +CONFIG_HID=y + +# +# USB support +# +CONFIG_USB_ARCH_HAS_HCD=y +# CONFIG_USB_ARCH_HAS_OHCI is not set +# CONFIG_USB_ARCH_HAS_EHCI is not set +# CONFIG_USB is not set + +# +# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' +# + +# +# USB Gadget Support +# +# CONFIG_USB_GADGET is not set + +# +# MMC/SD Card support +# +CONFIG_MMC=m +# CONFIG_MMC_DEBUG is not set +CONFIG_MMC_BLOCK=m +# CONFIG_MMC_ARMMMCI is not set +# CONFIG_MMC_WBSD is not set +# CONFIG_MMC_TIFM_SD is not set +CONFIG_MMC_NOMADIK=m +CONFIG_NOMADIK_MMC_DMA=y +# CONFIG_NOMADIK_MMC_POLL is not set +# CONFIG_NOMADIK_MMC_INTR is not set + +# +# Real Time Clock +# +CONFIG_RTC_LIB=y +# CONFIG_RTC_CLASS is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT2_FS_XIP is not set +# CONFIG_EXT3_FS is not set +# CONFIG_EXT4DEV_FS is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +# CONFIG_FS_POSIX_ACL is not set +# CONFIG_XFS_FS is not set +# CONFIG_GFS2_FS is not set +# CONFIG_OCFS2_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set +CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y +# CONFIG_QUOTA is not set +CONFIG_DNOTIFY=y +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_FUSE_FS is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=m +# CONFIG_MSDOS_FS is not set +CONFIG_VFAT_FS=m +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="cp437" +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_SYSCTL=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +# CONFIG_TMPFS_POSIX_ACL is not set +# CONFIG_HUGETLB_PAGE is not set +CONFIG_RAMFS=y +# CONFIG_CONFIGFS_FS is not set + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +CONFIG_JFFS2_FS=y +CONFIG_JFFS2_FS_DEBUG=0 +CONFIG_JFFS2_FS_WRITEBUFFER=y +# CONFIG_JFFS2_SUMMARY is not set +# CONFIG_JFFS2_FS_XATTR is not set +# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set +CONFIG_JFFS2_ZLIB=y +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN is not set +# CONFIG_CRAMFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +# CONFIG_NFS_V3_ACL is not set +CONFIG_NFS_V4=y +# CONFIG_NFS_DIRECTIO is not set +# CONFIG_NFSD is not set +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=y +CONFIG_SUNRPC_GSS=y +CONFIG_RPCSEC_GSS_KRB5=y +# CONFIG_RPCSEC_GSS_SPKM3 is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set +# CONFIG_9P_FS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y + +# +# Native Language Support +# +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="cp437" +CONFIG_NLS_CODEPAGE_437=m +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +# CONFIG_NLS_ASCII is not set +# CONFIG_NLS_ISO8859_1 is not set +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +# CONFIG_NLS_UTF8 is not set + +# +# Distributed Lock Manager +# +# CONFIG_DLM is not set + +# +# Profiling support +# +# CONFIG_PROFILING is not set + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +CONFIG_ENABLE_MUST_CHECK=y +CONFIG_MAGIC_SYSRQ=y +# CONFIG_UNUSED_SYMBOLS is not set +# CONFIG_DEBUG_FS is not set +# CONFIG_HEADERS_CHECK is not set +CONFIG_DEBUG_KERNEL=y +CONFIG_LOG_BUF_SHIFT=14 +CONFIG_DETECT_SOFTLOCKUP=y +# CONFIG_SCHEDSTATS is not set +# CONFIG_DEBUG_SLAB is not set +CONFIG_DEBUG_PREEMPT=y +# CONFIG_DEBUG_RT_MUTEXES is not set +# CONFIG_RT_MUTEX_TESTER is not set +# CONFIG_DEBUG_SPINLOCK is not set +CONFIG_DEBUG_MUTEXES=y +# CONFIG_DEBUG_RWSEMS is not set +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set +# CONFIG_DEBUG_KOBJECT is not set +CONFIG_DEBUG_BUGVERBOSE=y +CONFIG_DEBUG_INFO=y +# CONFIG_DEBUG_VM is not set +# CONFIG_DEBUG_LIST is not set +CONFIG_FRAME_POINTER=y +# CONFIG_FORCED_INLINING is not set +# CONFIG_RCU_TORTURE_TEST is not set +# CONFIG_WANT_EXTRA_DEBUG_INFORMATION is not set +# CONFIG_KGDB is not set +# CONFIG_DEBUG_USER is not set +# CONFIG_DEBUG_ERRORS is not set +# CONFIG_DEBUG_LL is not set + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +CONFIG_CRYPTO=y +CONFIG_CRYPTO_ALGAPI=y +CONFIG_CRYPTO_BLKCIPHER=y +CONFIG_CRYPTO_MANAGER=y +# CONFIG_CRYPTO_HMAC is not set +# CONFIG_CRYPTO_XCBC is not set +# CONFIG_CRYPTO_NULL is not set +# CONFIG_CRYPTO_MD4 is not set +CONFIG_CRYPTO_MD5=y +# CONFIG_CRYPTO_SHA1 is not set +# CONFIG_CRYPTO_SHA256 is not set +# CONFIG_CRYPTO_SHA512 is not set +# CONFIG_CRYPTO_WP512 is not set +# CONFIG_CRYPTO_TGR192 is not set +# CONFIG_CRYPTO_GF128MUL is not set +CONFIG_CRYPTO_ECB=m +CONFIG_CRYPTO_CBC=y +# CONFIG_CRYPTO_LRW is not set +CONFIG_CRYPTO_DES=y +# CONFIG_CRYPTO_BLOWFISH is not set +# CONFIG_CRYPTO_TWOFISH is not set +# CONFIG_CRYPTO_SERPENT is not set +# CONFIG_CRYPTO_AES is not set +# CONFIG_CRYPTO_CAST5 is not set +# CONFIG_CRYPTO_CAST6 is not set +# CONFIG_CRYPTO_TEA is not set +# CONFIG_CRYPTO_ARC4 is not set +# CONFIG_CRYPTO_KHAZAD is not set +# CONFIG_CRYPTO_ANUBIS is not set +# CONFIG_CRYPTO_DEFLATE is not set +# CONFIG_CRYPTO_MICHAEL_MIC is not set +# CONFIG_CRYPTO_CRC32C is not set +# CONFIG_CRYPTO_TEST is not set + +# +# Hardware crypto devices +# + +# +# Library routines +# +CONFIG_BITREVERSE=y +# CONFIG_CRC_CCITT is not set +# CONFIG_CRC16 is not set +CONFIG_CRC32=y +CONFIG_LIBCRC32C=m +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y +CONFIG_PLIST=y +CONFIG_IOMAP_COPY=y --- /dev/null +++ linux-2.6.20/arch/arm/configs/ndk15_defconfig @@ -0,0 +1,1221 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.20 +# Thu Aug 16 16:12:48 2007 +# +CONFIG_ARM=y +# CONFIG_GENERIC_TIME is not set +CONFIG_MMU=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +CONFIG_HARDIRQS_SW_RESEND=y +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +# CONFIG_ARCH_HAS_ILOG2_U32 is not set +# CONFIG_ARCH_HAS_ILOG2_U64 is not set +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_VECTORS_BASE=0xffff0000 +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_LOCK_KERNEL=y +CONFIG_INIT_ENV_ARG_LIMIT=32 + +# +# General setup +# +CONFIG_LOCALVERSION="" +CONFIG_LOCALVERSION_AUTO=y +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +# CONFIG_IPC_NS is not set +# CONFIG_POSIX_MQUEUE is not set +# CONFIG_BSD_PROCESS_ACCT is not set +# CONFIG_TASKSTATS is not set +# CONFIG_UTS_NS is not set +# CONFIG_AUDIT is not set +# CONFIG_IKCONFIG is not set +CONFIG_SYSFS_DEPRECATED=y +# CONFIG_RELAY is not set +CONFIG_INITRAMFS_SOURCE="" +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SYSCTL=y +CONFIG_EMBEDDED=y +CONFIG_UID16=y +CONFIG_SYSCTL_SYSCALL=y +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_ALL is not set +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_HOTPLUG=y +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_ELF_CORE=y +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_SHMEM=y +CONFIG_SLAB=y +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_RT_MUTEXES=y +# CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 +# CONFIG_SLOB is not set + +# +# Loadable module support +# +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +# CONFIG_MODVERSIONS is not set +# CONFIG_MODULE_SRCVERSION_ALL is not set +# CONFIG_KMOD is not set + +# +# Block layer +# +CONFIG_BLOCK=y +# CONFIG_LBD is not set +# CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_LSF is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +CONFIG_DEFAULT_AS=y +# CONFIG_DEFAULT_DEADLINE is not set +# CONFIG_DEFAULT_CFQ is not set +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="anticipatory" + +# +# System Type +# +# CONFIG_ARCH_AAEC2000 is not set +# CONFIG_ARCH_INTEGRATOR is not set +# CONFIG_ARCH_REALVIEW is not set +# CONFIG_ARCH_VERSATILE is not set +# CONFIG_ARCH_AT91 is not set +# CONFIG_ARCH_CLPS7500 is not set +# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_CO285 is not set +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_EP93XX is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_NETX is not set +CONFIG_ARCH_NOMADIK=y +# CONFIG_ARCH_H720X is not set +# CONFIG_ARCH_IMX is not set +# CONFIG_ARCH_IOP32X is not set +# CONFIG_ARCH_IOP33X is not set +# CONFIG_ARCH_IOP13XX is not set +# CONFIG_ARCH_IXP4XX is not set +# CONFIG_ARCH_IXP2000 is not set +# CONFIG_ARCH_IXP23XX is not set +# CONFIG_ARCH_L7200 is not set +# CONFIG_ARCH_PNX4008 is not set +# CONFIG_ARCH_PXA is not set +# CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_SA1100 is not set +# CONFIG_ARCH_S3C2410 is not set +# CONFIG_ARCH_SHARK is not set +# CONFIG_ARCH_LH7A40X is not set +# CONFIG_ARCH_OMAP is not set +# CONFIG_NOMADIK_NDK10_CUT_A1 is not set +# CONFIG_NOMADIK_NDK10_CUT_B06 is not set +# CONFIG_NOMADIK_NDK10_CUT_B0 is not set +CONFIG_NOMADIK_NDK15_REV2_B_03=y +# CONFIG_NOMADIK_NDK15_REV2_B_05 is not set +# CONFIG_NOMADIK_NDK15_REV2_B_06 is not set +# CONFIG_NOMADIK_NDK15_REV3_C_02 is not set +CONFIG_NOMADIK_TARGET="NDK15_Rev2_B_03" +CONFIG_NOMADIK_SOC="stn8815" +CONFIG_NOMADIK_PLATFORM="ndk15" +CONFIG_NOMADIK_TARGET_EXTRA_CFLAGS="-D__RELEASE -D__STN_8815=10" + +# +# Nomadik chip used STn8815S22 cut A0 (marked STN8815AAS22) +# + +# +# Target board CPLD version 2.0.1.0 +# +CONFIG_NOMADIK_CPLD_V2010=y +CONFIG_NOMADIK_NDK15=y +CONFIG_NOMADIK_NDK15_REV2_MMC=y +CONFIG_NOMADIK_GPIO=y +CONFIG_GPIO_PROC=y +CONFIG_NOMADIK_DMA=y +CONFIG_NOMADIK_SSP=m +CONFIG_NOMADIK_MSP=m +CONFIG_NOMADIK_MTU=m +CONFIG_NOMADIK_MTU_SYSTEM_TICK=y +CONFIG_NOMADIK_RTC=y +CONFIG_NOMADIK_PM=y +# CONFIG_NOMADIK_SVA_INIT_MEM is not set +CONFIG_NOMADIK_SVA_MEM_SIZE=4 +# CONFIG_NOMADIK_SAA_INIT_MEM is not set +CONFIG_FB_NOMADIK_VGA=y +# CONFIG_FB_NOMADIK_CRT is not set +# CONFIG_FB_NOMADIK_QVGA_PORTRAIT is not set +# CONFIG_FB_NOMADIK_QVGA_LANDSCAPE is not set +# CONFIG_FB_NOMADIK_PANEL_8BPP is not set +CONFIG_FB_NOMADIK_PANEL_16BPP=y +# CONFIG_FB_NOMADIK_PANEL_24BPP is not set +CONFIG_SGA_INST_BUFFER_2=y +# CONFIG_SGA_INST_BUFFER_20 is not set +CONFIG_SGA_INST_BUFFER_NUM=2 +CONFIG_FB_NOMADIK_PANEL_BPP=16 +CONFIG_FB_NOMADIK_PANEL_NAME="VGA" +CONFIG_FB_NOMADIK_PANEL_XRES=640 +CONFIG_FB_NOMADIK_PANEL_YRES=480 +CONFIG_FB_NOMADIK_PANEL_LFMARGIN=0x21 +CONFIG_FB_NOMADIK_PANEL_RTMARGIN=0x40 +CONFIG_FB_NOMADIK_PANEL_UPRMARGIN=0x07 +CONFIG_FB_NOMADIK_PANEL_LWRMARGIN=0x24 +CONFIG_FB_NOMADIK_PANEL_HSLEN=0x40 +CONFIG_FB_NOMADIK_PANEL_VSLEN=0x19 +CONFIG_FB_NOMADIK_PANEL_TIM2VAL=0x027f1800 + +# +# Processor Type +# +CONFIG_CPU_32=y +# CONFIG_CPU_ARM920T is not set +CONFIG_CPU_ARM926T=y +# CONFIG_CPU_ARM1020 is not set +# CONFIG_CPU_ARM1022 is not set +# CONFIG_CPU_ARM1026 is not set +# CONFIG_CPU_V6 is not set +CONFIG_CPU_32v5=y +CONFIG_CPU_ABRT_EV5TJ=y +CONFIG_CPU_CACHE_VIVT=y +CONFIG_CPU_COPY_V4WB=y +CONFIG_CPU_TLB_V4WBI=y +CONFIG_CPU_CP15=y +CONFIG_CPU_CP15_MMU=y + +# +# Processor Features +# +CONFIG_ARM_THUMB=y +# CONFIG_CPU_ICACHE_DISABLE is not set +# CONFIG_CPU_DCACHE_DISABLE is not set +# CONFIG_CPU_DCACHE_WRITETHROUGH is not set +# CONFIG_CPU_CACHE_ROUND_ROBIN is not set +CONFIG_ICST525=y + +# +# Bus support +# +CONFIG_ARM_AMBA=y +CONFIG_ISA_DMA_API=y + +# +# PCCARD (PCMCIA/CardBus) support +# +# CONFIG_PCCARD is not set + +# +# Kernel Features +# +CONFIG_PREEMPT=y +CONFIG_NO_IDLE_HZ=y +CONFIG_HZ=100 +CONFIG_AEABI=y +CONFIG_OABI_COMPAT=y +# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_FLATMEM_MANUAL=y +# CONFIG_DISCONTIGMEM_MANUAL is not set +# CONFIG_SPARSEMEM_MANUAL is not set +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +# CONFIG_SPARSEMEM_STATIC is not set +CONFIG_SPLIT_PTLOCK_CPUS=4096 +# CONFIG_RESOURCES_64BIT is not set +CONFIG_ALIGNMENT_TRAP=y + +# +# Boot options +# +CONFIG_ZBOOT_ROM_TEXT=0x0 +CONFIG_ZBOOT_ROM_BSS=0x0 +CONFIG_CMDLINE="root=/dev/ram0 console=ttyAMA1,115200n8 init=linuxrc" +# CONFIG_XIP_KERNEL is not set + +# +# CPU Frequency scaling +# +CONFIG_CPU_FREQ=y +CONFIG_CPU_FREQ_TABLE=y +# CONFIG_CPU_FREQ_DEBUG is not set +CONFIG_CPU_FREQ_STAT=y +# CONFIG_CPU_FREQ_STAT_DETAILS is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set +CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y +# CONFIG_CPU_FREQ_GOV_PERFORMANCE is not set +# CONFIG_CPU_FREQ_GOV_POWERSAVE is not set +CONFIG_CPU_FREQ_GOV_USERSPACE=y +# CONFIG_CPU_FREQ_GOV_ONDEMAND is not set +# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set +CONFIG_CPU_FREQ_NOMADIK=y + +# +# Floating point emulation +# + +# +# At least one emulation must be selected +# +CONFIG_FPE_NWFPE=y +# CONFIG_FPE_NWFPE_XP is not set +# CONFIG_FPE_FASTFPE is not set +# CONFIG_VFP is not set + +# +# Userspace binary formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_AOUT is not set +# CONFIG_BINFMT_MISC is not set + +# +# Power management options +# +CONFIG_PM=y +# CONFIG_PM_LEGACY is not set +# CONFIG_PM_DEBUG is not set +# CONFIG_PM_SYSFS_DEPRECATED is not set +# CONFIG_APM is not set + +# +# Networking +# +CONFIG_NET=y + +# +# Networking options +# +# CONFIG_NETDEBUG is not set +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +CONFIG_UNIX=y +CONFIG_XFRM=y +# CONFIG_XFRM_USER is not set +# CONFIG_XFRM_SUB_POLICY is not set +# CONFIG_NET_KEY is not set +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_FIB_HASH=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_XFRM_TUNNEL is not set +# CONFIG_INET_TUNNEL is not set +CONFIG_INET_XFRM_MODE_TRANSPORT=y +CONFIG_INET_XFRM_MODE_TUNNEL=y +CONFIG_INET_XFRM_MODE_BEET=y +CONFIG_INET_DIAG=y +CONFIG_INET_TCP_DIAG=y +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_CUBIC=y +CONFIG_DEFAULT_TCP_CONG="cubic" +# CONFIG_TCP_MD5SIG is not set +# CONFIG_IPV6 is not set +# CONFIG_INET6_XFRM_TUNNEL is not set +# CONFIG_INET6_TUNNEL is not set +# CONFIG_NETWORK_SECMARK is not set +# CONFIG_NETFILTER is not set + +# +# DCCP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_DCCP is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_SCTP is not set + +# +# TIPC Configuration (EXPERIMENTAL) +# +# CONFIG_TIPC is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +# CONFIG_IEEE80211 is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +CONFIG_FW_LOADER=y +# CONFIG_DEBUG_DRIVER is not set +# CONFIG_SYS_HYPERVISOR is not set + +# +# Connector - unified userspace <-> kernelspace linker +# +# CONFIG_CONNECTOR is not set + +# +# Memory Technology Devices (MTD) +# +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +CONFIG_MTD_CONCAT=y +CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_REDBOOT_PARTS is not set +CONFIG_MTD_CMDLINE_PARTS=y +# CONFIG_MTD_AFS_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +# CONFIG_MTD_BLKDEVS is not set +# CONFIG_MTD_BLOCK is not set +# CONFIG_MTD_BLOCK_RO is not set +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set +# CONFIG_RFD_FTL is not set +# CONFIG_SSFDC is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_GEN_PROBE=y +# CONFIG_MTD_CFI_ADV_OPTIONS is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +CONFIG_MTD_CFI_INTELEXT=y +# CONFIG_MTD_CFI_AMDSTD is not set +CONFIG_MTD_CFI_STAA=y +CONFIG_MTD_CFI_UTIL=y +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set +# CONFIG_MTD_OBSOLETE_CHIPS is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +# CONFIG_MTD_PHYSMAP is not set +CONFIG_MTD_NOMADIK=y +# CONFIG_MTD_ARM_INTEGRATOR is not set +# CONFIG_MTD_PLATRAM is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_DATAFLASH is not set +# CONFIG_MTD_M25P80 is not set +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLOCK2MTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set + +# +# NAND Flash Device Drivers +# +CONFIG_MTD_NAND=y +CONFIG_MTD_NAND_NOMADIK=y +# CONFIG_MTD_NAND_VERIFY_WRITE is not set +# CONFIG_MTD_NAND_ECC_SMC is not set +CONFIG_MTD_NAND_IDS=y +# CONFIG_MTD_NAND_DISKONCHIP is not set +# CONFIG_MTD_NAND_NANDSIM is not set + +# +# OneNAND Flash Device Drivers +# +# CONFIG_MTD_ONENAND is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play support +# + +# +# Block devices +# +# CONFIG_BLK_DEV_COW_COMMON is not set +# CONFIG_BLK_DEV_LOOP is not set +# CONFIG_BLK_DEV_NBD is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=46080 +CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 +CONFIG_BLK_DEV_INITRD=y +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH is not set + +# +# SCSI device support +# +# CONFIG_RAID_ATTRS is not set +# CONFIG_SCSI is not set +# CONFIG_SCSI_NETLINK is not set + +# +# Serial ATA (prod) and Parallel ATA (experimental) drivers +# +# CONFIG_ATA is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# Fusion MPT device support +# +# CONFIG_FUSION is not set + +# +# IEEE 1394 (FireWire) support +# + +# +# I2O device support +# + +# +# Network device support +# +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set + +# +# PHY device support +# +# CONFIG_PHYLIB is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +CONFIG_MII=y +CONFIG_SMC91X=y +# CONFIG_DM9000 is not set + +# +# Ethernet (1000 Mbit) +# + +# +# Ethernet (10000 Mbit) +# + +# +# Token Ring devices +# + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_SHAPER is not set +# CONFIG_NETCONSOLE is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Input device support +# +CONFIG_INPUT=y +# CONFIG_INPUT_FF_MEMLESS is not set + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=m +CONFIG_INPUT_MOUSEDEV_PSAUX=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=640 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=480 +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set +CONFIG_INPUT_EVDEV=m +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +CONFIG_INPUT_KEYBOARD=y +# CONFIG_KEYBOARD_ATKBD is not set +# CONFIG_KEYBOARD_SUNKBD is not set +# CONFIG_KEYBOARD_LKKBD is not set +# CONFIG_KEYBOARD_XTKBD is not set +# CONFIG_KEYBOARD_NEWTON is not set +# CONFIG_KEYBOARD_STOWAWAY is not set +CONFIG_KEYPAD_NOMADIK=m +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +CONFIG_INPUT_TOUCHSCREEN=y +# CONFIG_TOUCHSCREEN_ADS7846 is not set +# CONFIG_TOUCHSCREEN_GUNZE is not set +# CONFIG_TOUCHSCREEN_ELO is not set +# CONFIG_TOUCHSCREEN_MTOUCH is not set +# CONFIG_TOUCHSCREEN_MK712 is not set +# CONFIG_TOUCHSCREEN_PENMOUNT is not set +# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set +# CONFIG_TOUCHSCREEN_TOUCHWIN is not set +# CONFIG_TOUCHSCREEN_UCB1400 is not set +CONFIG_TOUCHSCREEN_NOMADIK=m +# CONFIG_INPUT_MISC is not set + +# +# Hardware I/O ports +# +# CONFIG_SERIO is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +CONFIG_VT=y +# CONFIG_VT_CONSOLE is not set +CONFIG_HW_CONSOLE=y +# CONFIG_VT_HW_CONSOLE_BINDING is not set +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +# CONFIG_SERIAL_8250 is not set + +# +# Non-8250 serial port support +# +# CONFIG_SERIAL_AMBA_PL010 is not set +CONFIG_SERIAL_AMBA_PL011=y +CONFIG_SERIAL_AMBA_PL011_CONSOLE=y +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +# CONFIG_LEGACY_PTYS is not set + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +CONFIG_HW_RANDOM=m +# CONFIG_NVRAM is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_RAW_DRIVER is not set + +# +# TPM devices +# +# CONFIG_TCG_TPM is not set + +# +# I2C support +# +CONFIG_I2C=y +CONFIG_I2C_CHARDEV=y + +# +# I2C Algorithms +# +# CONFIG_I2C_ALGOBIT is not set +# CONFIG_I2C_ALGOPCF is not set +# CONFIG_I2C_ALGOPCA is not set + +# +# I2C Hardware Bus support +# +CONFIG_I2C_NOMADIK=y +# CONFIG_I2C_OCORES is not set +# CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_I2C_STUB is not set +# CONFIG_I2C_PCA_ISA is not set + +# +# Miscellaneous I2C Chip support +# +# CONFIG_SENSORS_DS1337 is not set +# CONFIG_SENSORS_DS1374 is not set +# CONFIG_SENSORS_EEPROM is not set +# CONFIG_SENSORS_PCF8574 is not set +# CONFIG_SENSORS_PCA9539 is not set +# CONFIG_SENSORS_PCF8591 is not set +# CONFIG_SENSORS_MAX6875 is not set +CONFIG_CPLD_I2C=y +# CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +# CONFIG_I2C_DEBUG_CHIP is not set + +# +# SPI support +# +CONFIG_SPI=y +# CONFIG_SPI_DEBUG is not set +CONFIG_SPI_MASTER=y + +# +# SPI Master Controller Drivers +# +# CONFIG_SPI_BITBANG is not set +CONFIG_NOMADIK_SPI=m + +# +# SPI Protocol Masters +# + +# +# Dallas's 1-wire bus +# +# CONFIG_W1 is not set + +# +# Hardware Monitoring support +# +CONFIG_HWMON=y +# CONFIG_HWMON_VID is not set +# CONFIG_SENSORS_ABITUGURU is not set +# CONFIG_SENSORS_ADM1021 is not set +# CONFIG_SENSORS_ADM1025 is not set +# CONFIG_SENSORS_ADM1026 is not set +# CONFIG_SENSORS_ADM1031 is not set +# CONFIG_SENSORS_ADM9240 is not set +# CONFIG_SENSORS_ASB100 is not set +# CONFIG_SENSORS_ATXP1 is not set +# CONFIG_SENSORS_DS1621 is not set +# CONFIG_SENSORS_F71805F is not set +# CONFIG_SENSORS_FSCHER is not set +# CONFIG_SENSORS_FSCPOS is not set +# CONFIG_SENSORS_GL518SM is not set +# CONFIG_SENSORS_GL520SM is not set +# CONFIG_SENSORS_IT87 is not set +# CONFIG_SENSORS_LM63 is not set +# CONFIG_SENSORS_LM70 is not set +# CONFIG_SENSORS_LM75 is not set +# CONFIG_SENSORS_LM77 is not set +# CONFIG_SENSORS_LM78 is not set +# CONFIG_SENSORS_LM80 is not set +# CONFIG_SENSORS_LM83 is not set +# CONFIG_SENSORS_LM85 is not set +# CONFIG_SENSORS_LM87 is not set +# CONFIG_SENSORS_LM90 is not set +# CONFIG_SENSORS_LM92 is not set +# CONFIG_SENSORS_MAX1619 is not set +# CONFIG_SENSORS_PC87360 is not set +# CONFIG_SENSORS_PC87427 is not set +# CONFIG_SENSORS_SMSC47M1 is not set +# CONFIG_SENSORS_SMSC47M192 is not set +# CONFIG_SENSORS_SMSC47B397 is not set +# CONFIG_SENSORS_VT1211 is not set +# CONFIG_SENSORS_W83781D is not set +# CONFIG_SENSORS_W83791D is not set +# CONFIG_SENSORS_W83792D is not set +# CONFIG_SENSORS_W83793 is not set +# CONFIG_SENSORS_W83L785TS is not set +# CONFIG_SENSORS_W83627HF is not set +# CONFIG_SENSORS_W83627EHF is not set +# CONFIG_HWMON_DEBUG_CHIP is not set + +# +# Misc devices +# +# CONFIG_TIFM_CORE is not set + +# +# LED devices +# +# CONFIG_NEW_LEDS is not set + +# +# LED drivers +# + +# +# LED Triggers +# + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# +# Graphics support +# +CONFIG_FIRMWARE_EDID=y +CONFIG_FB=y +CONFIG_FB_CFB_FILLRECT=y +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_IMAGEBLIT=y +# CONFIG_FB_MACMODES is not set +# CONFIG_FB_BACKLIGHT is not set +CONFIG_FB_MODE_HELPERS=y +# CONFIG_FB_TILEBLITTING is not set +CONFIG_FB_ARMCLCD=y +# CONFIG_FB_S1D13XXX is not set +# CONFIG_FB_VIRTUAL is not set + +# +# Console display driver support +# +# CONFIG_VGA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE=y +# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set +CONFIG_FONTS=y +CONFIG_FONT_8x8=y +CONFIG_FONT_8x16=y +# CONFIG_FONT_6x11 is not set +# CONFIG_FONT_7x14 is not set +# CONFIG_FONT_PEARL_8x8 is not set +# CONFIG_FONT_ACORN_8x8 is not set +# CONFIG_FONT_MINI_4x6 is not set +# CONFIG_FONT_SUN8x16 is not set +# CONFIG_FONT_SUN12x22 is not set +# CONFIG_FONT_10x18 is not set + +# +# Logo configuration +# +CONFIG_LOGO=y +# CONFIG_LOGO_LINUX_MONO is not set +# CONFIG_LOGO_LINUX_VGA16 is not set +CONFIG_LOGO_LINUX_CLUT224=y +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set + +# +# Sound +# +CONFIG_NOMADIK_ACODEC=m +# CONFIG_NOMADIK_STW5094 is not set +CONFIG_NOMADIK_STW5095=y +CONFIG_SOUND=m + +# +# Advanced Linux Sound Architecture +# +CONFIG_SND=m +CONFIG_SND_TIMER=m +CONFIG_SND_PCM=m +# CONFIG_SND_SEQUENCER is not set +# CONFIG_SND_MIXER_OSS is not set +# CONFIG_SND_PCM_OSS is not set +# CONFIG_SND_DYNAMIC_MINORS is not set +CONFIG_SND_SUPPORT_OLD_API=y +CONFIG_SND_VERBOSE_PROCFS=y +# CONFIG_SND_VERBOSE_PRINTK is not set +# CONFIG_SND_DEBUG is not set + +# +# Generic devices +# +# CONFIG_SND_DUMMY is not set +# CONFIG_SND_MTPAV is not set +# CONFIG_SND_SERIAL_U16550 is not set +# CONFIG_SND_MPU401 is not set + +# +# ALSA ARM devices +# +CONFIG_SND_NOMADIK_ALSA=m +# CONFIG_SND_ARMAACI is not set + +# +# Open Sound System +# +# CONFIG_SOUND_PRIME is not set + +# +# HID Devices +# +CONFIG_HID=y + +# +# USB support +# +CONFIG_USB_ARCH_HAS_HCD=y +# CONFIG_USB_ARCH_HAS_OHCI is not set +# CONFIG_USB_ARCH_HAS_EHCI is not set +# CONFIG_USB is not set + +# +# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' +# + +# +# USB Gadget Support +# +# CONFIG_USB_GADGET is not set + +# +# MMC/SD Card support +# +CONFIG_MMC=m +# CONFIG_MMC_DEBUG is not set +CONFIG_MMC_BLOCK=m +# CONFIG_MMC_ARMMMCI is not set +# CONFIG_MMC_WBSD is not set +# CONFIG_MMC_TIFM_SD is not set +CONFIG_MMC_NOMADIK=m +CONFIG_NOMADIK_MMC_DMA=y +# CONFIG_NOMADIK_MMC_POLL is not set +# CONFIG_NOMADIK_MMC_INTR is not set + +# +# Real Time Clock +# +CONFIG_RTC_LIB=y +# CONFIG_RTC_CLASS is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT2_FS_XIP is not set +# CONFIG_EXT3_FS is not set +# CONFIG_EXT4DEV_FS is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +# CONFIG_FS_POSIX_ACL is not set +# CONFIG_XFS_FS is not set +# CONFIG_GFS2_FS is not set +# CONFIG_OCFS2_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set +CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y +# CONFIG_QUOTA is not set +CONFIG_DNOTIFY=y +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_FUSE_FS is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=m +# CONFIG_MSDOS_FS is not set +CONFIG_VFAT_FS=m +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="cp437" +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_SYSCTL=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +# CONFIG_TMPFS_POSIX_ACL is not set +# CONFIG_HUGETLB_PAGE is not set +CONFIG_RAMFS=y +# CONFIG_CONFIGFS_FS is not set + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +CONFIG_JFFS2_FS=y +CONFIG_JFFS2_FS_DEBUG=0 +CONFIG_JFFS2_FS_WRITEBUFFER=y +# CONFIG_JFFS2_SUMMARY is not set +# CONFIG_JFFS2_FS_XATTR is not set +# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set +CONFIG_JFFS2_ZLIB=y +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN is not set +# CONFIG_CRAMFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +# CONFIG_NFS_V3_ACL is not set +CONFIG_NFS_V4=y +# CONFIG_NFS_DIRECTIO is not set +# CONFIG_NFSD is not set +CONFIG_ROOT_NFS=y +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=y +CONFIG_SUNRPC_GSS=y +CONFIG_RPCSEC_GSS_KRB5=y +# CONFIG_RPCSEC_GSS_SPKM3 is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set +# CONFIG_9P_FS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y + +# +# Native Language Support +# +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="cp437" +CONFIG_NLS_CODEPAGE_437=m +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +# CONFIG_NLS_ASCII is not set +# CONFIG_NLS_ISO8859_1 is not set +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +# CONFIG_NLS_UTF8 is not set + +# +# Distributed Lock Manager +# +# CONFIG_DLM is not set + +# +# Profiling support +# +# CONFIG_PROFILING is not set + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +CONFIG_ENABLE_MUST_CHECK=y +CONFIG_MAGIC_SYSRQ=y +# CONFIG_UNUSED_SYMBOLS is not set +# CONFIG_DEBUG_FS is not set +# CONFIG_HEADERS_CHECK is not set +CONFIG_DEBUG_KERNEL=y +CONFIG_LOG_BUF_SHIFT=14 +CONFIG_DETECT_SOFTLOCKUP=y +# CONFIG_SCHEDSTATS is not set +# CONFIG_DEBUG_SLAB is not set +CONFIG_DEBUG_PREEMPT=y +# CONFIG_DEBUG_RT_MUTEXES is not set +# CONFIG_RT_MUTEX_TESTER is not set +# CONFIG_DEBUG_SPINLOCK is not set +CONFIG_DEBUG_MUTEXES=y +# CONFIG_DEBUG_RWSEMS is not set +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set +# CONFIG_DEBUG_KOBJECT is not set +# CONFIG_DEBUG_BUGVERBOSE is not set +CONFIG_DEBUG_INFO=y +# CONFIG_DEBUG_VM is not set +# CONFIG_DEBUG_LIST is not set +CONFIG_FRAME_POINTER=y +CONFIG_FORCED_INLINING=y +# CONFIG_RCU_TORTURE_TEST is not set +# CONFIG_WANT_EXTRA_DEBUG_INFORMATION is not set +# CONFIG_KGDB is not set +# CONFIG_DEBUG_USER is not set +# CONFIG_DEBUG_ERRORS is not set +# CONFIG_DEBUG_LL is not set + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +CONFIG_CRYPTO=y +CONFIG_CRYPTO_ALGAPI=y +CONFIG_CRYPTO_BLKCIPHER=y +CONFIG_CRYPTO_MANAGER=y +# CONFIG_CRYPTO_HMAC is not set +# CONFIG_CRYPTO_XCBC is not set +# CONFIG_CRYPTO_NULL is not set +# CONFIG_CRYPTO_MD4 is not set +CONFIG_CRYPTO_MD5=y +# CONFIG_CRYPTO_SHA1 is not set +# CONFIG_CRYPTO_SHA256 is not set +# CONFIG_CRYPTO_SHA512 is not set +# CONFIG_CRYPTO_WP512 is not set +# CONFIG_CRYPTO_TGR192 is not set +# CONFIG_CRYPTO_GF128MUL is not set +CONFIG_CRYPTO_ECB=m +CONFIG_CRYPTO_CBC=y +# CONFIG_CRYPTO_LRW is not set +CONFIG_CRYPTO_DES=y +# CONFIG_CRYPTO_BLOWFISH is not set +# CONFIG_CRYPTO_TWOFISH is not set +# CONFIG_CRYPTO_SERPENT is not set +# CONFIG_CRYPTO_AES is not set +# CONFIG_CRYPTO_CAST5 is not set +# CONFIG_CRYPTO_CAST6 is not set +# CONFIG_CRYPTO_TEA is not set +# CONFIG_CRYPTO_ARC4 is not set +# CONFIG_CRYPTO_KHAZAD is not set +# CONFIG_CRYPTO_ANUBIS is not set +# CONFIG_CRYPTO_DEFLATE is not set +# CONFIG_CRYPTO_MICHAEL_MIC is not set +# CONFIG_CRYPTO_CRC32C is not set +# CONFIG_CRYPTO_TEST is not set + +# +# Hardware crypto devices +# + +# +# Library routines +# +CONFIG_BITREVERSE=y +# CONFIG_CRC_CCITT is not set +# CONFIG_CRC16 is not set +CONFIG_CRC32=y +CONFIG_LIBCRC32C=m +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y +CONFIG_PLIST=y +CONFIG_IOMAP_COPY=y --- /dev/null +++ linux-2.6.20/arch/arm/configs/ndk15b06_defconfig @@ -0,0 +1,1221 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.20 +# Thu Aug 16 17:22:36 2007 +# +CONFIG_ARM=y +# CONFIG_GENERIC_TIME is not set +CONFIG_MMU=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +CONFIG_HARDIRQS_SW_RESEND=y +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +# CONFIG_ARCH_HAS_ILOG2_U32 is not set +# CONFIG_ARCH_HAS_ILOG2_U64 is not set +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_VECTORS_BASE=0xffff0000 +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_LOCK_KERNEL=y +CONFIG_INIT_ENV_ARG_LIMIT=32 + +# +# General setup +# +CONFIG_LOCALVERSION="" +CONFIG_LOCALVERSION_AUTO=y +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +# CONFIG_IPC_NS is not set +# CONFIG_POSIX_MQUEUE is not set +# CONFIG_BSD_PROCESS_ACCT is not set +# CONFIG_TASKSTATS is not set +# CONFIG_UTS_NS is not set +# CONFIG_AUDIT is not set +# CONFIG_IKCONFIG is not set +CONFIG_SYSFS_DEPRECATED=y +# CONFIG_RELAY is not set +CONFIG_INITRAMFS_SOURCE="" +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SYSCTL=y +CONFIG_EMBEDDED=y +CONFIG_UID16=y +CONFIG_SYSCTL_SYSCALL=y +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_ALL is not set +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_HOTPLUG=y +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_ELF_CORE=y +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_SHMEM=y +CONFIG_SLAB=y +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_RT_MUTEXES=y +# CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 +# CONFIG_SLOB is not set + +# +# Loadable module support +# +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +# CONFIG_MODVERSIONS is not set +# CONFIG_MODULE_SRCVERSION_ALL is not set +# CONFIG_KMOD is not set + +# +# Block layer +# +CONFIG_BLOCK=y +# CONFIG_LBD is not set +# CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_LSF is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +CONFIG_DEFAULT_AS=y +# CONFIG_DEFAULT_DEADLINE is not set +# CONFIG_DEFAULT_CFQ is not set +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="anticipatory" + +# +# System Type +# +# CONFIG_ARCH_AAEC2000 is not set +# CONFIG_ARCH_INTEGRATOR is not set +# CONFIG_ARCH_REALVIEW is not set +# CONFIG_ARCH_VERSATILE is not set +# CONFIG_ARCH_AT91 is not set +# CONFIG_ARCH_CLPS7500 is not set +# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_CO285 is not set +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_EP93XX is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_NETX is not set +CONFIG_ARCH_NOMADIK=y +# CONFIG_ARCH_H720X is not set +# CONFIG_ARCH_IMX is not set +# CONFIG_ARCH_IOP32X is not set +# CONFIG_ARCH_IOP33X is not set +# CONFIG_ARCH_IOP13XX is not set +# CONFIG_ARCH_IXP4XX is not set +# CONFIG_ARCH_IXP2000 is not set +# CONFIG_ARCH_IXP23XX is not set +# CONFIG_ARCH_L7200 is not set +# CONFIG_ARCH_PNX4008 is not set +# CONFIG_ARCH_PXA is not set +# CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_SA1100 is not set +# CONFIG_ARCH_S3C2410 is not set +# CONFIG_ARCH_SHARK is not set +# CONFIG_ARCH_LH7A40X is not set +# CONFIG_ARCH_OMAP is not set +# CONFIG_NOMADIK_NDK10_CUT_A1 is not set +# CONFIG_NOMADIK_NDK10_CUT_B06 is not set +# CONFIG_NOMADIK_NDK10_CUT_B0 is not set +# CONFIG_NOMADIK_NDK15_REV2_B_03 is not set +# CONFIG_NOMADIK_NDK15_REV2_B_05 is not set +CONFIG_NOMADIK_NDK15_REV2_B_06=y +# CONFIG_NOMADIK_NDK15_REV3_C_02 is not set +CONFIG_NOMADIK_TARGET="NDK15_Rev2_B_06" +CONFIG_NOMADIK_SOC="stn8815" +CONFIG_NOMADIK_PLATFORM="ndk15" +CONFIG_NOMADIK_TARGET_EXTRA_CFLAGS="-D__RELEASE -D__STN_8815=20 " +CONFIG_NOMADIK_CPLD_V2010=y +CONFIG_NOMADIK_NDK15=y + +# +# Nomadik chip used STn8815S22 cut B0 (marked STN8815BBS22H11 Secure) +# + +# +# Target board CPLD version 2.0.1.0 +# +CONFIG_NOMADIK_STN8815BBS22H11=y +CONFIG_NOMADIK_GPIO=y +CONFIG_GPIO_PROC=y +CONFIG_NOMADIK_DMA=y +CONFIG_NOMADIK_SSP=m +CONFIG_NOMADIK_MSP=m +CONFIG_NOMADIK_MTU=m +CONFIG_NOMADIK_MTU_SYSTEM_TICK=y +CONFIG_NOMADIK_RTC=y +CONFIG_NOMADIK_PM=y +# CONFIG_NOMADIK_SVA_INIT_MEM is not set +CONFIG_NOMADIK_SVA_MEM_SIZE=4 +# CONFIG_NOMADIK_SAA_INIT_MEM is not set +CONFIG_FB_NOMADIK_VGA=y +# CONFIG_FB_NOMADIK_CRT is not set +# CONFIG_FB_NOMADIK_QVGA_PORTRAIT is not set +# CONFIG_FB_NOMADIK_QVGA_LANDSCAPE is not set +# CONFIG_FB_NOMADIK_PANEL_8BPP is not set +CONFIG_FB_NOMADIK_PANEL_16BPP=y +# CONFIG_FB_NOMADIK_PANEL_24BPP is not set +CONFIG_SGA_INST_BUFFER_2=y +# CONFIG_SGA_INST_BUFFER_20 is not set +CONFIG_SGA_INST_BUFFER_NUM=2 +CONFIG_FB_NOMADIK_PANEL_BPP=16 +CONFIG_FB_NOMADIK_PANEL_NAME="VGA" +CONFIG_FB_NOMADIK_PANEL_XRES=640 +CONFIG_FB_NOMADIK_PANEL_YRES=480 +CONFIG_FB_NOMADIK_PANEL_LFMARGIN=0x21 +CONFIG_FB_NOMADIK_PANEL_RTMARGIN=0x40 +CONFIG_FB_NOMADIK_PANEL_UPRMARGIN=0x07 +CONFIG_FB_NOMADIK_PANEL_LWRMARGIN=0x24 +CONFIG_FB_NOMADIK_PANEL_HSLEN=0x40 +CONFIG_FB_NOMADIK_PANEL_VSLEN=0x19 +CONFIG_FB_NOMADIK_PANEL_TIM2VAL=0x027f1800 + +# +# Processor Type +# +CONFIG_CPU_32=y +# CONFIG_CPU_ARM920T is not set +CONFIG_CPU_ARM926T=y +# CONFIG_CPU_ARM1020 is not set +# CONFIG_CPU_ARM1022 is not set +# CONFIG_CPU_ARM1026 is not set +# CONFIG_CPU_V6 is not set +CONFIG_CPU_32v5=y +CONFIG_CPU_ABRT_EV5TJ=y +CONFIG_CPU_CACHE_VIVT=y +CONFIG_CPU_COPY_V4WB=y +CONFIG_CPU_TLB_V4WBI=y +CONFIG_CPU_CP15=y +CONFIG_CPU_CP15_MMU=y + +# +# Processor Features +# +CONFIG_ARM_THUMB=y +# CONFIG_CPU_ICACHE_DISABLE is not set +# CONFIG_CPU_DCACHE_DISABLE is not set +# CONFIG_CPU_DCACHE_WRITETHROUGH is not set +# CONFIG_CPU_CACHE_ROUND_ROBIN is not set +CONFIG_ICST525=y + +# +# Bus support +# +CONFIG_ARM_AMBA=y +CONFIG_ISA_DMA_API=y + +# +# PCCARD (PCMCIA/CardBus) support +# +# CONFIG_PCCARD is not set + +# +# Kernel Features +# +CONFIG_PREEMPT=y +CONFIG_NO_IDLE_HZ=y +CONFIG_HZ=100 +CONFIG_AEABI=y +CONFIG_OABI_COMPAT=y +# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_FLATMEM_MANUAL=y +# CONFIG_DISCONTIGMEM_MANUAL is not set +# CONFIG_SPARSEMEM_MANUAL is not set +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +# CONFIG_SPARSEMEM_STATIC is not set +CONFIG_SPLIT_PTLOCK_CPUS=4096 +# CONFIG_RESOURCES_64BIT is not set +CONFIG_ALIGNMENT_TRAP=y + +# +# Boot options +# +CONFIG_ZBOOT_ROM_TEXT=0x0 +CONFIG_ZBOOT_ROM_BSS=0x0 +CONFIG_CMDLINE="root=/dev/ram0 console=ttyAMA1,115200n8 init=linuxrc" +# CONFIG_XIP_KERNEL is not set + +# +# CPU Frequency scaling +# +CONFIG_CPU_FREQ=y +CONFIG_CPU_FREQ_TABLE=y +# CONFIG_CPU_FREQ_DEBUG is not set +CONFIG_CPU_FREQ_STAT=y +# CONFIG_CPU_FREQ_STAT_DETAILS is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set +CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y +# CONFIG_CPU_FREQ_GOV_PERFORMANCE is not set +# CONFIG_CPU_FREQ_GOV_POWERSAVE is not set +CONFIG_CPU_FREQ_GOV_USERSPACE=y +# CONFIG_CPU_FREQ_GOV_ONDEMAND is not set +# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set +CONFIG_CPU_FREQ_NOMADIK=y + +# +# Floating point emulation +# + +# +# At least one emulation must be selected +# +CONFIG_FPE_NWFPE=y +# CONFIG_FPE_NWFPE_XP is not set +# CONFIG_FPE_FASTFPE is not set +# CONFIG_VFP is not set + +# +# Userspace binary formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_AOUT is not set +# CONFIG_BINFMT_MISC is not set + +# +# Power management options +# +CONFIG_PM=y +# CONFIG_PM_LEGACY is not set +# CONFIG_PM_DEBUG is not set +# CONFIG_PM_SYSFS_DEPRECATED is not set +# CONFIG_APM is not set + +# +# Networking +# +CONFIG_NET=y + +# +# Networking options +# +# CONFIG_NETDEBUG is not set +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +CONFIG_UNIX=y +CONFIG_XFRM=y +# CONFIG_XFRM_USER is not set +# CONFIG_XFRM_SUB_POLICY is not set +# CONFIG_NET_KEY is not set +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_FIB_HASH=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_XFRM_TUNNEL is not set +# CONFIG_INET_TUNNEL is not set +CONFIG_INET_XFRM_MODE_TRANSPORT=y +CONFIG_INET_XFRM_MODE_TUNNEL=y +CONFIG_INET_XFRM_MODE_BEET=y +CONFIG_INET_DIAG=y +CONFIG_INET_TCP_DIAG=y +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_CUBIC=y +CONFIG_DEFAULT_TCP_CONG="cubic" +# CONFIG_TCP_MD5SIG is not set +# CONFIG_IPV6 is not set +# CONFIG_INET6_XFRM_TUNNEL is not set +# CONFIG_INET6_TUNNEL is not set +# CONFIG_NETWORK_SECMARK is not set +# CONFIG_NETFILTER is not set + +# +# DCCP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_DCCP is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_SCTP is not set + +# +# TIPC Configuration (EXPERIMENTAL) +# +# CONFIG_TIPC is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +# CONFIG_IEEE80211 is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +CONFIG_FW_LOADER=y +# CONFIG_DEBUG_DRIVER is not set +# CONFIG_SYS_HYPERVISOR is not set + +# +# Connector - unified userspace <-> kernelspace linker +# +# CONFIG_CONNECTOR is not set + +# +# Memory Technology Devices (MTD) +# +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +CONFIG_MTD_CONCAT=y +CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_REDBOOT_PARTS is not set +CONFIG_MTD_CMDLINE_PARTS=y +# CONFIG_MTD_AFS_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +# CONFIG_MTD_BLKDEVS is not set +# CONFIG_MTD_BLOCK is not set +# CONFIG_MTD_BLOCK_RO is not set +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set +# CONFIG_RFD_FTL is not set +# CONFIG_SSFDC is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_GEN_PROBE=y +# CONFIG_MTD_CFI_ADV_OPTIONS is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +CONFIG_MTD_CFI_INTELEXT=y +# CONFIG_MTD_CFI_AMDSTD is not set +CONFIG_MTD_CFI_STAA=y +CONFIG_MTD_CFI_UTIL=y +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set +# CONFIG_MTD_OBSOLETE_CHIPS is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +# CONFIG_MTD_PHYSMAP is not set +CONFIG_MTD_NOMADIK=y +# CONFIG_MTD_ARM_INTEGRATOR is not set +# CONFIG_MTD_PLATRAM is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_DATAFLASH is not set +# CONFIG_MTD_M25P80 is not set +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLOCK2MTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set + +# +# NAND Flash Device Drivers +# +CONFIG_MTD_NAND=y +CONFIG_MTD_NAND_NOMADIK=y +# CONFIG_MTD_NAND_VERIFY_WRITE is not set +# CONFIG_MTD_NAND_ECC_SMC is not set +CONFIG_MTD_NAND_IDS=y +# CONFIG_MTD_NAND_DISKONCHIP is not set +# CONFIG_MTD_NAND_NANDSIM is not set + +# +# OneNAND Flash Device Drivers +# +# CONFIG_MTD_ONENAND is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play support +# + +# +# Block devices +# +# CONFIG_BLK_DEV_COW_COMMON is not set +# CONFIG_BLK_DEV_LOOP is not set +# CONFIG_BLK_DEV_NBD is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=46080 +CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 +CONFIG_BLK_DEV_INITRD=y +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH is not set + +# +# SCSI device support +# +# CONFIG_RAID_ATTRS is not set +# CONFIG_SCSI is not set +# CONFIG_SCSI_NETLINK is not set + +# +# Serial ATA (prod) and Parallel ATA (experimental) drivers +# +# CONFIG_ATA is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# Fusion MPT device support +# +# CONFIG_FUSION is not set + +# +# IEEE 1394 (FireWire) support +# + +# +# I2O device support +# + +# +# Network device support +# +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set + +# +# PHY device support +# +# CONFIG_PHYLIB is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +CONFIG_MII=y +CONFIG_SMC91X=y +# CONFIG_DM9000 is not set + +# +# Ethernet (1000 Mbit) +# + +# +# Ethernet (10000 Mbit) +# + +# +# Token Ring devices +# + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_SHAPER is not set +# CONFIG_NETCONSOLE is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Input device support +# +CONFIG_INPUT=y +# CONFIG_INPUT_FF_MEMLESS is not set + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=m +CONFIG_INPUT_MOUSEDEV_PSAUX=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=640 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=480 +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set +CONFIG_INPUT_EVDEV=m +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +CONFIG_INPUT_KEYBOARD=y +# CONFIG_KEYBOARD_ATKBD is not set +# CONFIG_KEYBOARD_SUNKBD is not set +# CONFIG_KEYBOARD_LKKBD is not set +# CONFIG_KEYBOARD_XTKBD is not set +# CONFIG_KEYBOARD_NEWTON is not set +# CONFIG_KEYBOARD_STOWAWAY is not set +CONFIG_KEYPAD_NOMADIK=m +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +CONFIG_INPUT_TOUCHSCREEN=y +# CONFIG_TOUCHSCREEN_ADS7846 is not set +# CONFIG_TOUCHSCREEN_GUNZE is not set +# CONFIG_TOUCHSCREEN_ELO is not set +# CONFIG_TOUCHSCREEN_MTOUCH is not set +# CONFIG_TOUCHSCREEN_MK712 is not set +# CONFIG_TOUCHSCREEN_PENMOUNT is not set +# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set +# CONFIG_TOUCHSCREEN_TOUCHWIN is not set +# CONFIG_TOUCHSCREEN_UCB1400 is not set +CONFIG_TOUCHSCREEN_NOMADIK=m +# CONFIG_INPUT_MISC is not set + +# +# Hardware I/O ports +# +# CONFIG_SERIO is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +CONFIG_VT=y +# CONFIG_VT_CONSOLE is not set +CONFIG_HW_CONSOLE=y +# CONFIG_VT_HW_CONSOLE_BINDING is not set +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +# CONFIG_SERIAL_8250 is not set + +# +# Non-8250 serial port support +# +# CONFIG_SERIAL_AMBA_PL010 is not set +CONFIG_SERIAL_AMBA_PL011=y +CONFIG_SERIAL_AMBA_PL011_CONSOLE=y +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +# CONFIG_LEGACY_PTYS is not set + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +CONFIG_HW_RANDOM=m +# CONFIG_NVRAM is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_RAW_DRIVER is not set + +# +# TPM devices +# +# CONFIG_TCG_TPM is not set + +# +# I2C support +# +CONFIG_I2C=y +CONFIG_I2C_CHARDEV=y + +# +# I2C Algorithms +# +# CONFIG_I2C_ALGOBIT is not set +# CONFIG_I2C_ALGOPCF is not set +# CONFIG_I2C_ALGOPCA is not set + +# +# I2C Hardware Bus support +# +CONFIG_I2C_NOMADIK=y +# CONFIG_I2C_OCORES is not set +# CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_I2C_STUB is not set +# CONFIG_I2C_PCA_ISA is not set + +# +# Miscellaneous I2C Chip support +# +# CONFIG_SENSORS_DS1337 is not set +# CONFIG_SENSORS_DS1374 is not set +# CONFIG_SENSORS_EEPROM is not set +# CONFIG_SENSORS_PCF8574 is not set +# CONFIG_SENSORS_PCA9539 is not set +# CONFIG_SENSORS_PCF8591 is not set +# CONFIG_SENSORS_MAX6875 is not set +CONFIG_CPLD_I2C=y +# CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +# CONFIG_I2C_DEBUG_CHIP is not set + +# +# SPI support +# +CONFIG_SPI=y +# CONFIG_SPI_DEBUG is not set +CONFIG_SPI_MASTER=y + +# +# SPI Master Controller Drivers +# +# CONFIG_SPI_BITBANG is not set +CONFIG_NOMADIK_SPI=m + +# +# SPI Protocol Masters +# + +# +# Dallas's 1-wire bus +# +# CONFIG_W1 is not set + +# +# Hardware Monitoring support +# +CONFIG_HWMON=y +# CONFIG_HWMON_VID is not set +# CONFIG_SENSORS_ABITUGURU is not set +# CONFIG_SENSORS_ADM1021 is not set +# CONFIG_SENSORS_ADM1025 is not set +# CONFIG_SENSORS_ADM1026 is not set +# CONFIG_SENSORS_ADM1031 is not set +# CONFIG_SENSORS_ADM9240 is not set +# CONFIG_SENSORS_ASB100 is not set +# CONFIG_SENSORS_ATXP1 is not set +# CONFIG_SENSORS_DS1621 is not set +# CONFIG_SENSORS_F71805F is not set +# CONFIG_SENSORS_FSCHER is not set +# CONFIG_SENSORS_FSCPOS is not set +# CONFIG_SENSORS_GL518SM is not set +# CONFIG_SENSORS_GL520SM is not set +# CONFIG_SENSORS_IT87 is not set +# CONFIG_SENSORS_LM63 is not set +# CONFIG_SENSORS_LM70 is not set +# CONFIG_SENSORS_LM75 is not set +# CONFIG_SENSORS_LM77 is not set +# CONFIG_SENSORS_LM78 is not set +# CONFIG_SENSORS_LM80 is not set +# CONFIG_SENSORS_LM83 is not set +# CONFIG_SENSORS_LM85 is not set +# CONFIG_SENSORS_LM87 is not set +# CONFIG_SENSORS_LM90 is not set +# CONFIG_SENSORS_LM92 is not set +# CONFIG_SENSORS_MAX1619 is not set +# CONFIG_SENSORS_PC87360 is not set +# CONFIG_SENSORS_PC87427 is not set +# CONFIG_SENSORS_SMSC47M1 is not set +# CONFIG_SENSORS_SMSC47M192 is not set +# CONFIG_SENSORS_SMSC47B397 is not set +# CONFIG_SENSORS_VT1211 is not set +# CONFIG_SENSORS_W83781D is not set +# CONFIG_SENSORS_W83791D is not set +# CONFIG_SENSORS_W83792D is not set +# CONFIG_SENSORS_W83793 is not set +# CONFIG_SENSORS_W83L785TS is not set +# CONFIG_SENSORS_W83627HF is not set +# CONFIG_SENSORS_W83627EHF is not set +# CONFIG_HWMON_DEBUG_CHIP is not set + +# +# Misc devices +# +# CONFIG_TIFM_CORE is not set + +# +# LED devices +# +# CONFIG_NEW_LEDS is not set + +# +# LED drivers +# + +# +# LED Triggers +# + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# +# Graphics support +# +CONFIG_FIRMWARE_EDID=y +CONFIG_FB=y +CONFIG_FB_CFB_FILLRECT=y +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_IMAGEBLIT=y +# CONFIG_FB_MACMODES is not set +# CONFIG_FB_BACKLIGHT is not set +CONFIG_FB_MODE_HELPERS=y +# CONFIG_FB_TILEBLITTING is not set +CONFIG_FB_ARMCLCD=y +# CONFIG_FB_S1D13XXX is not set +# CONFIG_FB_VIRTUAL is not set + +# +# Console display driver support +# +# CONFIG_VGA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE=y +# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set +CONFIG_FONTS=y +CONFIG_FONT_8x8=y +CONFIG_FONT_8x16=y +# CONFIG_FONT_6x11 is not set +# CONFIG_FONT_7x14 is not set +# CONFIG_FONT_PEARL_8x8 is not set +# CONFIG_FONT_ACORN_8x8 is not set +# CONFIG_FONT_MINI_4x6 is not set +# CONFIG_FONT_SUN8x16 is not set +# CONFIG_FONT_SUN12x22 is not set +# CONFIG_FONT_10x18 is not set + +# +# Logo configuration +# +CONFIG_LOGO=y +# CONFIG_LOGO_LINUX_MONO is not set +# CONFIG_LOGO_LINUX_VGA16 is not set +CONFIG_LOGO_LINUX_CLUT224=y +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set + +# +# Sound +# +CONFIG_NOMADIK_ACODEC=m +# CONFIG_NOMADIK_STW5094 is not set +CONFIG_NOMADIK_STW5095=y +CONFIG_SOUND=m + +# +# Advanced Linux Sound Architecture +# +CONFIG_SND=m +CONFIG_SND_TIMER=m +CONFIG_SND_PCM=m +# CONFIG_SND_SEQUENCER is not set +# CONFIG_SND_MIXER_OSS is not set +# CONFIG_SND_PCM_OSS is not set +# CONFIG_SND_DYNAMIC_MINORS is not set +CONFIG_SND_SUPPORT_OLD_API=y +CONFIG_SND_VERBOSE_PROCFS=y +# CONFIG_SND_VERBOSE_PRINTK is not set +# CONFIG_SND_DEBUG is not set + +# +# Generic devices +# +# CONFIG_SND_DUMMY is not set +# CONFIG_SND_MTPAV is not set +# CONFIG_SND_SERIAL_U16550 is not set +# CONFIG_SND_MPU401 is not set + +# +# ALSA ARM devices +# +CONFIG_SND_NOMADIK_ALSA=m +# CONFIG_SND_ARMAACI is not set + +# +# Open Sound System +# +# CONFIG_SOUND_PRIME is not set + +# +# HID Devices +# +CONFIG_HID=y + +# +# USB support +# +CONFIG_USB_ARCH_HAS_HCD=y +# CONFIG_USB_ARCH_HAS_OHCI is not set +# CONFIG_USB_ARCH_HAS_EHCI is not set +# CONFIG_USB is not set + +# +# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' +# + +# +# USB Gadget Support +# +# CONFIG_USB_GADGET is not set + +# +# MMC/SD Card support +# +CONFIG_MMC=m +# CONFIG_MMC_DEBUG is not set +CONFIG_MMC_BLOCK=m +# CONFIG_MMC_ARMMMCI is not set +# CONFIG_MMC_WBSD is not set +# CONFIG_MMC_TIFM_SD is not set +CONFIG_MMC_NOMADIK=m +CONFIG_NOMADIK_MMC_DMA=y +# CONFIG_NOMADIK_MMC_POLL is not set +# CONFIG_NOMADIK_MMC_INTR is not set + +# +# Real Time Clock +# +CONFIG_RTC_LIB=y +# CONFIG_RTC_CLASS is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT2_FS_XIP is not set +# CONFIG_EXT3_FS is not set +# CONFIG_EXT4DEV_FS is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +# CONFIG_FS_POSIX_ACL is not set +# CONFIG_XFS_FS is not set +# CONFIG_GFS2_FS is not set +# CONFIG_OCFS2_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set +CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y +# CONFIG_QUOTA is not set +CONFIG_DNOTIFY=y +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_FUSE_FS is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=m +# CONFIG_MSDOS_FS is not set +CONFIG_VFAT_FS=m +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="cp437" +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_SYSCTL=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +# CONFIG_TMPFS_POSIX_ACL is not set +# CONFIG_HUGETLB_PAGE is not set +CONFIG_RAMFS=y +# CONFIG_CONFIGFS_FS is not set + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +CONFIG_JFFS2_FS=y +CONFIG_JFFS2_FS_DEBUG=0 +CONFIG_JFFS2_FS_WRITEBUFFER=y +# CONFIG_JFFS2_SUMMARY is not set +# CONFIG_JFFS2_FS_XATTR is not set +# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set +CONFIG_JFFS2_ZLIB=y +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN is not set +# CONFIG_CRAMFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +# CONFIG_NFS_V3_ACL is not set +CONFIG_NFS_V4=y +# CONFIG_NFS_DIRECTIO is not set +# CONFIG_NFSD is not set +CONFIG_ROOT_NFS=y +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=y +CONFIG_SUNRPC_GSS=y +CONFIG_RPCSEC_GSS_KRB5=y +# CONFIG_RPCSEC_GSS_SPKM3 is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set +# CONFIG_9P_FS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y + +# +# Native Language Support +# +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="cp437" +CONFIG_NLS_CODEPAGE_437=m +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +# CONFIG_NLS_ASCII is not set +# CONFIG_NLS_ISO8859_1 is not set +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +# CONFIG_NLS_UTF8 is not set + +# +# Distributed Lock Manager +# +# CONFIG_DLM is not set + +# +# Profiling support +# +# CONFIG_PROFILING is not set + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +CONFIG_ENABLE_MUST_CHECK=y +CONFIG_MAGIC_SYSRQ=y +# CONFIG_UNUSED_SYMBOLS is not set +# CONFIG_DEBUG_FS is not set +# CONFIG_HEADERS_CHECK is not set +CONFIG_DEBUG_KERNEL=y +CONFIG_LOG_BUF_SHIFT=14 +CONFIG_DETECT_SOFTLOCKUP=y +# CONFIG_SCHEDSTATS is not set +# CONFIG_DEBUG_SLAB is not set +CONFIG_DEBUG_PREEMPT=y +# CONFIG_DEBUG_RT_MUTEXES is not set +# CONFIG_RT_MUTEX_TESTER is not set +# CONFIG_DEBUG_SPINLOCK is not set +CONFIG_DEBUG_MUTEXES=y +# CONFIG_DEBUG_RWSEMS is not set +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set +# CONFIG_DEBUG_KOBJECT is not set +# CONFIG_DEBUG_BUGVERBOSE is not set +CONFIG_DEBUG_INFO=y +# CONFIG_DEBUG_VM is not set +# CONFIG_DEBUG_LIST is not set +CONFIG_FRAME_POINTER=y +CONFIG_FORCED_INLINING=y +# CONFIG_RCU_TORTURE_TEST is not set +# CONFIG_WANT_EXTRA_DEBUG_INFORMATION is not set +# CONFIG_KGDB is not set +# CONFIG_DEBUG_USER is not set +# CONFIG_DEBUG_ERRORS is not set +# CONFIG_DEBUG_LL is not set + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +CONFIG_CRYPTO=y +CONFIG_CRYPTO_ALGAPI=y +CONFIG_CRYPTO_BLKCIPHER=y +CONFIG_CRYPTO_MANAGER=y +# CONFIG_CRYPTO_HMAC is not set +# CONFIG_CRYPTO_XCBC is not set +# CONFIG_CRYPTO_NULL is not set +# CONFIG_CRYPTO_MD4 is not set +CONFIG_CRYPTO_MD5=y +# CONFIG_CRYPTO_SHA1 is not set +# CONFIG_CRYPTO_SHA256 is not set +# CONFIG_CRYPTO_SHA512 is not set +# CONFIG_CRYPTO_WP512 is not set +# CONFIG_CRYPTO_TGR192 is not set +# CONFIG_CRYPTO_GF128MUL is not set +CONFIG_CRYPTO_ECB=m +CONFIG_CRYPTO_CBC=y +# CONFIG_CRYPTO_LRW is not set +CONFIG_CRYPTO_DES=y +# CONFIG_CRYPTO_BLOWFISH is not set +# CONFIG_CRYPTO_TWOFISH is not set +# CONFIG_CRYPTO_SERPENT is not set +# CONFIG_CRYPTO_AES is not set +# CONFIG_CRYPTO_CAST5 is not set +# CONFIG_CRYPTO_CAST6 is not set +# CONFIG_CRYPTO_TEA is not set +# CONFIG_CRYPTO_ARC4 is not set +# CONFIG_CRYPTO_KHAZAD is not set +# CONFIG_CRYPTO_ANUBIS is not set +# CONFIG_CRYPTO_DEFLATE is not set +# CONFIG_CRYPTO_MICHAEL_MIC is not set +# CONFIG_CRYPTO_CRC32C is not set +# CONFIG_CRYPTO_TEST is not set + +# +# Hardware crypto devices +# + +# +# Library routines +# +CONFIG_BITREVERSE=y +# CONFIG_CRC_CCITT is not set +# CONFIG_CRC16 is not set +CONFIG_CRC32=y +CONFIG_LIBCRC32C=m +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y +CONFIG_PLIST=y +CONFIG_IOMAP_COPY=y --- /dev/null +++ linux-2.6.20/arch/arm/configs/nhk15_defconfig @@ -0,0 +1,1458 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.20 +# Fri Aug 22 11:48:56 2008 +# +CONFIG_ARM=y +# CONFIG_GENERIC_TIME is not set +CONFIG_MMU=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +CONFIG_HARDIRQS_SW_RESEND=y +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +# CONFIG_ARCH_HAS_ILOG2_U32 is not set +# CONFIG_ARCH_HAS_ILOG2_U64 is not set +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_VECTORS_BASE=0xffff0000 +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_LOCK_KERNEL=y +CONFIG_INIT_ENV_ARG_LIMIT=32 + +# +# General setup +# +CONFIG_LOCALVERSION="" +CONFIG_LOCALVERSION_AUTO=y +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +# CONFIG_IPC_NS is not set +# CONFIG_POSIX_MQUEUE is not set +# CONFIG_BSD_PROCESS_ACCT is not set +# CONFIG_TASKSTATS is not set +# CONFIG_UTS_NS is not set +# CONFIG_AUDIT is not set +# CONFIG_IKCONFIG is not set +CONFIG_SYSFS_DEPRECATED=y +# CONFIG_RELAY is not set +CONFIG_INITRAMFS_SOURCE="" +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SYSCTL=y +CONFIG_EMBEDDED=y +CONFIG_UID16=y +CONFIG_SYSCTL_SYSCALL=y +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_HOTPLUG=y +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_ELF_CORE=y +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_SHMEM=y +CONFIG_SLAB=y +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_RT_MUTEXES=y +# CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 +# CONFIG_SLOB is not set + +# +# Loadable module support +# +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +# CONFIG_MODVERSIONS is not set +# CONFIG_MODULE_SRCVERSION_ALL is not set +# CONFIG_KMOD is not set + +# +# Block layer +# +CONFIG_BLOCK=y +# CONFIG_LBD is not set +# CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_LSF is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +CONFIG_DEFAULT_AS=y +# CONFIG_DEFAULT_DEADLINE is not set +# CONFIG_DEFAULT_CFQ is not set +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="anticipatory" + +# +# System Type +# +# CONFIG_ARCH_AAEC2000 is not set +# CONFIG_ARCH_INTEGRATOR is not set +# CONFIG_ARCH_REALVIEW is not set +# CONFIG_ARCH_VERSATILE is not set +# CONFIG_ARCH_AT91 is not set +# CONFIG_ARCH_CLPS7500 is not set +# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_CO285 is not set +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_EP93XX is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_NETX is not set +CONFIG_ARCH_NOMADIK=y +# CONFIG_ARCH_H720X is not set +# CONFIG_ARCH_IMX is not set +# CONFIG_ARCH_IOP32X is not set +# CONFIG_ARCH_IOP33X is not set +# CONFIG_ARCH_IOP13XX is not set +# CONFIG_ARCH_IXP4XX is not set +# CONFIG_ARCH_IXP2000 is not set +# CONFIG_ARCH_IXP23XX is not set +# CONFIG_ARCH_L7200 is not set +# CONFIG_ARCH_PNX4008 is not set +# CONFIG_ARCH_PXA is not set +# CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_SA1100 is not set +# CONFIG_ARCH_S3C2410 is not set +# CONFIG_ARCH_SHARK is not set +# CONFIG_ARCH_LH7A40X is not set +# CONFIG_ARCH_OMAP is not set +# CONFIG_NOMADIK_NDK10_CUT_A1 is not set +# CONFIG_NOMADIK_NDK10_CUT_B06 is not set +# CONFIG_NOMADIK_NDK10_CUT_B0 is not set +# CONFIG_NOMADIK_NDK15_REV2_B_03 is not set +# CONFIG_NOMADIK_NDK15_REV2_B_05 is not set +# CONFIG_NOMADIK_NDK15_REV2_B_06 is not set +# CONFIG_NOMADIK_NDK15_REV3_C_02 is not set +CONFIG_NOMADIK_NHK15=y +CONFIG_NOMADIK_TARGET="NHK15" +CONFIG_NOMADIK_SOC="stn8815" +CONFIG_NOMADIK_PLATFORM="nhk15" +CONFIG_NOMADIK_TARGET_EXTRA_CFLAGS="-D__RELEASE -D__STN_8815=40 " +CONFIG_NOMADIK_STN8815CAS22H11=y + +# +# Nomadik chip used STn8815 +# +CONFIG_NOMADIK_GPIO=y +CONFIG_NOMADIK_ENABLE_L2CACHE=y +CONFIG_GPIO_PROC=y +CONFIG_NOMADIK_DMA=y +CONFIG_NOMADIK_SSP=y +CONFIG_NOMADIK_MSP=y +CONFIG_NOMADIK_MTU=m +CONFIG_NOMADIK_MTU_SYSTEM_TICK=y +CONFIG_NOMADIK_RTC=y +CONFIG_NOMADIK_PM=y +CONFIG_NOMADIK_SVA_INIT_MEM=y +CONFIG_FORCE_MAX_ZONEORDER=13 +CONFIG_NOMADIK_SVA_MEM_SIZE=18 +CONFIG_NOMADIK_SVA_VPIP=y +# CONFIG_NOMADIK_SAA_INIT_MEM is not set +# CONFIG_FB_NOMADIK_VGA is not set +# CONFIG_FB_NOMADIK_CRT is not set +# CONFIG_FB_NOMADIK_QVGA_PORTRAIT is not set +# CONFIG_FB_NOMADIK_QVGA_LANDSCAPE is not set +CONFIG_FB_NOMADIK_WVGA=y +# CONFIG_FB_NOMADIK_PANEL_8BPP is not set +# CONFIG_FB_NOMADIK_PANEL_16BPP is not set +# CONFIG_FB_NOMADIK_PANEL_24BPP is not set +CONFIG_FB_NOMADIK_PANEL_24BPP_PACKED=y +CONFIG_FB_NOMADIK_ACCLN=y +CONFIG_FB_NOMADIK_PANEL_BPP=24 +CONFIG_FB_NOMADIK_PANEL_NAME="WVGA" +CONFIG_FB_NOMADIK_PANEL_XRES=800 +CONFIG_FB_NOMADIK_PANEL_YRES=480 +CONFIG_FB_NOMADIK_PANEL_LFMARGIN=0xD6 +CONFIG_FB_NOMADIK_PANEL_RTMARGIN=0x27 +CONFIG_FB_NOMADIK_PANEL_UPRMARGIN=0x22 +CONFIG_FB_NOMADIK_PANEL_LWRMARGIN=0xA +CONFIG_FB_NOMADIK_PANEL_HSLEN=0x1 +CONFIG_FB_NOMADIK_PANEL_VSLEN=0x1 +CONFIG_FB_NOMADIK_PANEL_TIM2VAL=0x031f1822 + +# +# Processor Type +# +CONFIG_CPU_32=y +# CONFIG_CPU_ARM920T is not set +CONFIG_L2CACHE_ENABLE=y +CONFIG_CPU_ARM926T=y +# CONFIG_CPU_ARM1020 is not set +# CONFIG_CPU_ARM1022 is not set +# CONFIG_CPU_ARM1026 is not set +# CONFIG_CPU_V6 is not set +CONFIG_CPU_32v5=y +CONFIG_CPU_ABRT_EV5TJ=y +CONFIG_CPU_CACHE_VIVT=y +CONFIG_CPU_COPY_V4WB=y +CONFIG_CPU_TLB_V4WBI=y +CONFIG_CPU_CP15=y +CONFIG_CPU_CP15_MMU=y + +# +# Processor Features +# +CONFIG_ARM_THUMB=y +# CONFIG_CPU_ICACHE_DISABLE is not set +# CONFIG_CPU_DCACHE_DISABLE is not set +# CONFIG_CPU_DCACHE_WRITETHROUGH is not set +# CONFIG_CPU_CACHE_ROUND_ROBIN is not set +CONFIG_ICST525=y + +# +# Bus support +# +CONFIG_ARM_AMBA=y +CONFIG_ISA_DMA_API=y + +# +# PCCARD (PCMCIA/CardBus) support +# +# CONFIG_PCCARD is not set + +# +# Kernel Features +# +CONFIG_PREEMPT=y +CONFIG_NO_IDLE_HZ=y +CONFIG_HZ=100 +CONFIG_AEABI=y +CONFIG_OABI_COMPAT=y +# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_FLATMEM_MANUAL=y +# CONFIG_DISCONTIGMEM_MANUAL is not set +# CONFIG_SPARSEMEM_MANUAL is not set +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +# CONFIG_SPARSEMEM_STATIC is not set +CONFIG_SPLIT_PTLOCK_CPUS=4096 +# CONFIG_RESOURCES_64BIT is not set +CONFIG_ALIGNMENT_TRAP=y + +# +# Boot options +# +CONFIG_ZBOOT_ROM_TEXT=0x0 +CONFIG_ZBOOT_ROM_BSS=0x0 +CONFIG_CMDLINE="root=/dev/ram0 console=ttyAMA1,115200n8 init=linuxrc mem=64M" +# CONFIG_XIP_KERNEL is not set + +# +# CPU Frequency scaling +# +CONFIG_CPU_FREQ=y +CONFIG_CPU_FREQ_TABLE=y +# CONFIG_CPU_FREQ_DEBUG is not set +CONFIG_CPU_FREQ_STAT=y +# CONFIG_CPU_FREQ_STAT_DETAILS is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set +CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y +# CONFIG_CPU_FREQ_GOV_PERFORMANCE is not set +# CONFIG_CPU_FREQ_GOV_POWERSAVE is not set +CONFIG_CPU_FREQ_GOV_USERSPACE=y +# CONFIG_CPU_FREQ_GOV_ONDEMAND is not set +# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set +CONFIG_CPU_FREQ_NOMADIK=y + +# +# Floating point emulation +# + +# +# At least one emulation must be selected +# +CONFIG_FPE_NWFPE=y +# CONFIG_FPE_NWFPE_XP is not set +# CONFIG_FPE_FASTFPE is not set +# CONFIG_VFP is not set + +# +# Userspace binary formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_AOUT is not set +# CONFIG_BINFMT_MISC is not set + +# +# Power management options +# +CONFIG_PM=y +# CONFIG_PM_LEGACY is not set +# CONFIG_PM_DEBUG is not set +# CONFIG_PM_SYSFS_DEPRECATED is not set +# CONFIG_APM is not set + +# +# Networking +# +CONFIG_NET=y + +# +# Networking options +# +# CONFIG_NETDEBUG is not set +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +CONFIG_UNIX=y +CONFIG_XFRM=y +# CONFIG_XFRM_USER is not set +# CONFIG_XFRM_SUB_POLICY is not set +CONFIG_NET_KEY=y +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +CONFIG_IP_ADVANCED_ROUTER=y +CONFIG_ASK_IP_FIB_HASH=y +# CONFIG_IP_FIB_TRIE is not set +CONFIG_IP_FIB_HASH=y +# CONFIG_IP_MULTIPLE_TABLES is not set +# CONFIG_IP_ROUTE_MULTIPATH is not set +# CONFIG_IP_ROUTE_VERBOSE is not set +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +# CONFIG_IP_PNP_BOOTP is not set +# CONFIG_IP_PNP_RARP is not set +CONFIG_NET_IPIP=y +CONFIG_NET_IPGRE=y +# CONFIG_NET_IPGRE_BROADCAST is not set +CONFIG_IP_MROUTE=y +# CONFIG_IP_PIMSM_V1 is not set +# CONFIG_IP_PIMSM_V2 is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_XFRM_TUNNEL is not set +CONFIG_INET_TUNNEL=y +CONFIG_INET_XFRM_MODE_TRANSPORT=y +CONFIG_INET_XFRM_MODE_TUNNEL=y +CONFIG_INET_XFRM_MODE_BEET=y +CONFIG_INET_DIAG=y +CONFIG_INET_TCP_DIAG=y +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_CUBIC=y +CONFIG_DEFAULT_TCP_CONG="cubic" +# CONFIG_TCP_MD5SIG is not set +# CONFIG_IPV6 is not set +# CONFIG_INET6_XFRM_TUNNEL is not set +# CONFIG_INET6_TUNNEL is not set +# CONFIG_NETWORK_SECMARK is not set +# CONFIG_NETFILTER is not set + +# +# DCCP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_DCCP is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_SCTP is not set + +# +# TIPC Configuration (EXPERIMENTAL) +# +# CONFIG_TIPC is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +CONFIG_BT=m +CONFIG_BT_L2CAP=m +CONFIG_BT_SCO=m +CONFIG_BT_RFCOMM=m +CONFIG_BT_RFCOMM_TTY=y +CONFIG_BT_BNEP=m +CONFIG_BT_BNEP_MC_FILTER=y +CONFIG_BT_BNEP_PROTO_FILTER=y +CONFIG_BT_HIDP=m + +# +# Bluetooth device drivers +# +# CONFIG_BT_HCIUSB is not set +CONFIG_BT_HCIUART=m +CONFIG_BT_HCIUART_H4=y +CONFIG_BT_HCIUART_BCSP=y +# CONFIG_BT_HCIBCM203X is not set +# CONFIG_BT_HCIBPA10X is not set +# CONFIG_BT_HCIBFUSB is not set +CONFIG_BT_HCIVHCI=m +# CONFIG_IEEE80211 is not set +CONFIG_WIRELESS_EXT=y + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +CONFIG_FW_LOADER=y +# CONFIG_SYS_HYPERVISOR is not set + +# +# Connector - unified userspace <-> kernelspace linker +# +# CONFIG_CONNECTOR is not set + +# +# Memory Technology Devices (MTD) +# +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +CONFIG_MTD_CONCAT=y +CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_REDBOOT_PARTS is not set +CONFIG_MTD_CMDLINE_PARTS=y +# CONFIG_MTD_AFS_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLKDEVS=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set +# CONFIG_RFD_FTL is not set +# CONFIG_SSFDC is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_GEN_PROBE=y +# CONFIG_MTD_CFI_ADV_OPTIONS is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +CONFIG_MTD_CFI_INTELEXT=y +# CONFIG_MTD_CFI_AMDSTD is not set +CONFIG_MTD_CFI_STAA=y +CONFIG_MTD_CFI_UTIL=y +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set +# CONFIG_MTD_OBSOLETE_CHIPS is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +# CONFIG_MTD_PHYSMAP is not set +CONFIG_MTD_NOMADIK=y +# CONFIG_MTD_ARM_INTEGRATOR is not set +# CONFIG_MTD_PLATRAM is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_DATAFLASH is not set +# CONFIG_MTD_M25P80 is not set +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLOCK2MTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set + +# +# NAND Flash Device Drivers +# +CONFIG_MTD_NAND=y +CONFIG_MTD_NAND_NOMADIK=y +# CONFIG_MTD_NAND_VERIFY_WRITE is not set +# CONFIG_MTD_NAND_ECC_SMC is not set +CONFIG_MTD_NAND_IDS=y +# CONFIG_MTD_NAND_DISKONCHIP is not set +# CONFIG_MTD_NAND_NANDSIM is not set +CONFIG_MTD_ONENAND=y +# CONFIG_MTD_ONENAND_VERIFY_WRITE is not set +CONFIG_MTD_ONENAND_GENERIC=y +# CONFIG_MTD_ONENAND_OTP is not set +# CONFIG_MTD_ONENAND_2X_PROGRAM is not set +# CONFIG_MTD_ONENAND_SIM is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play support +# + +# +# Block devices +# +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_LOOP=y +# CONFIG_BLK_DEV_CRYPTOLOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_UB is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=46080 +CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 +CONFIG_BLK_DEV_INITRD=y +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH is not set + +# +# SCSI device support +# +# CONFIG_RAID_ATTRS is not set +CONFIG_SCSI=y +# CONFIG_SCSI_TGT is not set +# CONFIG_SCSI_NETLINK is not set +CONFIG_SCSI_PROC_FS=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=y +# CONFIG_CHR_DEV_ST is not set +# CONFIG_CHR_DEV_OSST is not set +# CONFIG_BLK_DEV_SR is not set +CONFIG_CHR_DEV_SG=y +# CONFIG_CHR_DEV_SCH is not set + +# +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs +# +CONFIG_SCSI_MULTI_LUN=y +CONFIG_SCSI_CONSTANTS=y +CONFIG_SCSI_LOGGING=y +CONFIG_SCSI_SCAN_ASYNC=y + +# +# SCSI Transports +# +# CONFIG_SCSI_SPI_ATTRS is not set +# CONFIG_SCSI_FC_ATTRS is not set +# CONFIG_SCSI_ISCSI_ATTRS is not set +# CONFIG_SCSI_SAS_ATTRS is not set +# CONFIG_SCSI_SAS_LIBSAS is not set + +# +# SCSI low-level drivers +# +# CONFIG_ISCSI_TCP is not set +# CONFIG_SCSI_DEBUG is not set + +# +# Serial ATA (prod) and Parallel ATA (experimental) drivers +# +# CONFIG_ATA is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# Fusion MPT device support +# +# CONFIG_FUSION is not set + +# +# IEEE 1394 (FireWire) support +# + +# +# I2O device support +# + +# +# Network device support +# +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set + +# +# PHY device support +# +# CONFIG_PHYLIB is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +CONFIG_MII=y +CONFIG_SMC91X=y +# CONFIG_DM9000 is not set + +# +# Ethernet (1000 Mbit) +# + +# +# Ethernet (10000 Mbit) +# + +# +# Token Ring devices +# + +# +# Wireless LAN (non-hamradio) +# +CONFIG_NET_RADIO=y +# CONFIG_NET_WIRELESS_RTNETLINK is not set + +# +# Obsolete Wireless cards support (pre-802.11) +# +# CONFIG_STRIP is not set +# CONFIG_USB_ZD1201 is not set +# CONFIG_HOSTAP is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_SHAPER is not set +# CONFIG_NETCONSOLE is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Input device support +# +CONFIG_INPUT=y +# CONFIG_INPUT_FF_MEMLESS is not set + +# +# Userland interfaces +# +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set +CONFIG_INPUT_EVDEV=y +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +CONFIG_INPUT_KEYBOARD=y +# CONFIG_KEYBOARD_ATKBD is not set +# CONFIG_KEYBOARD_SUNKBD is not set +# CONFIG_KEYBOARD_LKKBD is not set +# CONFIG_KEYBOARD_XTKBD is not set +# CONFIG_KEYBOARD_NEWTON is not set +# CONFIG_KEYBOARD_STOWAWAY is not set +CONFIG_KEYPAD_NOMADIK=y +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +CONFIG_INPUT_TOUCHSCREEN=y +# CONFIG_TOUCHSCREEN_ADS7846 is not set +# CONFIG_TOUCHSCREEN_GUNZE is not set +# CONFIG_TOUCHSCREEN_ELO is not set +# CONFIG_TOUCHSCREEN_MTOUCH is not set +# CONFIG_TOUCHSCREEN_MK712 is not set +# CONFIG_TOUCHSCREEN_PENMOUNT is not set +# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set +# CONFIG_TOUCHSCREEN_TOUCHWIN is not set +# CONFIG_TOUCHSCREEN_UCB1400 is not set +# CONFIG_TOUCHSCREEN_NOMADIK is not set +CONFIG_TOUCHSCREEN_NOMADIK_TS2003=y +# CONFIG_INPUT_MISC is not set + +# +# Hardware I/O ports +# +# CONFIG_SERIO is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +CONFIG_VT=y +# CONFIG_VT_CONSOLE is not set +CONFIG_HW_CONSOLE=y +# CONFIG_VT_HW_CONSOLE_BINDING is not set +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +# CONFIG_SERIAL_8250 is not set + +# +# Non-8250 serial port support +# +# CONFIG_SERIAL_AMBA_PL010 is not set +CONFIG_SERIAL_AMBA_PL011=y +CONFIG_SERIAL_AMBA_PL011_CONSOLE=y +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +# CONFIG_LEGACY_PTYS is not set + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +CONFIG_HW_RANDOM=m +# CONFIG_NVRAM is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_RAW_DRIVER is not set + +# +# TPM devices +# +# CONFIG_TCG_TPM is not set + +# +# I2C support +# +CONFIG_I2C=y +CONFIG_I2C_CHARDEV=y + +# +# I2C Algorithms +# +# CONFIG_I2C_ALGOBIT is not set +# CONFIG_I2C_ALGOPCF is not set +# CONFIG_I2C_ALGOPCA is not set + +# +# I2C Hardware Bus support +# +CONFIG_I2C_NOMADIK=y +# CONFIG_I2C_OCORES is not set +# CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_I2C_STUB is not set +# CONFIG_I2C_PCA_ISA is not set + +# +# Miscellaneous I2C Chip support +# +# CONFIG_SENSORS_DS1337 is not set +# CONFIG_SENSORS_DS1374 is not set +# CONFIG_SENSORS_EEPROM is not set +# CONFIG_SENSORS_PCF8574 is not set +# CONFIG_SENSORS_PCA9539 is not set +# CONFIG_SENSORS_PCF8591 is not set +# CONFIG_SENSORS_MAX6875 is not set +# CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +# CONFIG_I2C_DEBUG_CHIP is not set + +# +# SPI support +# +CONFIG_SPI=y +CONFIG_SPI_MASTER=y + +# +# SPI Master Controller Drivers +# +# CONFIG_SPI_BITBANG is not set +CONFIG_NOMADIK_SPI=y + +# +# SPI Protocol Masters +# + +# +# Dallas's 1-wire bus +# +# CONFIG_W1 is not set + +# +# Hardware Monitoring support +# +CONFIG_HWMON=y +# CONFIG_HWMON_VID is not set +# CONFIG_SENSORS_ABITUGURU is not set +# CONFIG_SENSORS_ADM1021 is not set +# CONFIG_SENSORS_ADM1025 is not set +# CONFIG_SENSORS_ADM1026 is not set +# CONFIG_SENSORS_ADM1031 is not set +# CONFIG_SENSORS_ADM9240 is not set +# CONFIG_SENSORS_ASB100 is not set +# CONFIG_SENSORS_ATXP1 is not set +# CONFIG_SENSORS_DS1621 is not set +# CONFIG_SENSORS_F71805F is not set +# CONFIG_SENSORS_FSCHER is not set +# CONFIG_SENSORS_FSCPOS is not set +# CONFIG_SENSORS_GL518SM is not set +# CONFIG_SENSORS_GL520SM is not set +# CONFIG_SENSORS_IT87 is not set +CONFIG_SENSORS_LIS3LV02DL=m +# CONFIG_SENSORS_LM63 is not set +# CONFIG_SENSORS_LM70 is not set +# CONFIG_SENSORS_LM75 is not set +# CONFIG_SENSORS_LM77 is not set +# CONFIG_SENSORS_LM78 is not set +# CONFIG_SENSORS_LM80 is not set +# CONFIG_SENSORS_LM83 is not set +# CONFIG_SENSORS_LM85 is not set +# CONFIG_SENSORS_LM87 is not set +# CONFIG_SENSORS_LM90 is not set +# CONFIG_SENSORS_LM92 is not set +# CONFIG_SENSORS_MAX1619 is not set +# CONFIG_SENSORS_PC87360 is not set +# CONFIG_SENSORS_PC87427 is not set +# CONFIG_SENSORS_SMSC47M1 is not set +# CONFIG_SENSORS_SMSC47M192 is not set +# CONFIG_SENSORS_SMSC47B397 is not set +# CONFIG_SENSORS_VT1211 is not set +# CONFIG_SENSORS_W83781D is not set +# CONFIG_SENSORS_W83791D is not set +# CONFIG_SENSORS_W83792D is not set +# CONFIG_SENSORS_W83793 is not set +# CONFIG_SENSORS_W83L785TS is not set +# CONFIG_SENSORS_W83627HF is not set +# CONFIG_SENSORS_W83627EHF is not set +# CONFIG_HWMON_DEBUG_CHIP is not set + +# +# Misc devices +# +CONFIG_STMPE_NOMADIK=y +CONFIG_SIF_NOMADIK=y +CONFIG_ETM_NOMADIK=m +# CONFIG_TIFM_CORE is not set +CONFIG_BATT_NOMADIK=y +# +# LED devices +# +# CONFIG_NEW_LEDS is not set + +# +# LED drivers +# + +# +# LED Triggers +# + +# +# Multimedia devices +# +CONFIG_VIDEO_DEV=y +# CONFIG_VIDEO_V4L1 is not set +CONFIG_VIDEO_V4L1_COMPAT=y +CONFIG_VIDEO_V4L2=y + +# +# Video Capture Adapters +# + +# +# Video Capture Adapters +# +# CONFIG_VIDEO_ADV_DEBUG is not set +CONFIG_VIDEO_HELPER_CHIPS_AUTO=y +# CONFIG_VIDEO_VIVI is not set +# CONFIG_VIDEO_SAA5246A is not set +# CONFIG_VIDEO_SAA5249 is not set + +# +# V4L USB devices +# +# CONFIG_VIDEO_PVRUSB2 is not set +# CONFIG_VIDEO_USBVISION is not set +CONFIG_VIDEO_NOMADIK=y + +# +# Radio Adapters +# +# CONFIG_USB_DSBR is not set + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# +# NOMADIK Audio Video Drivers(SAA and SVA) +# +CONFIG_NOMADIK_SAA=m +CONFIG_NOMADIK_SVA=m +CONFIG_NOMADIK_OGL=m +# CONFIG_USB_DABUSB is not set + +# +# Graphics support +# +CONFIG_FIRMWARE_EDID=y +CONFIG_FB=y +CONFIG_FB_CFB_FILLRECT=y +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_IMAGEBLIT=y +# CONFIG_FB_MACMODES is not set +# CONFIG_FB_BACKLIGHT is not set +CONFIG_FB_MODE_HELPERS=y +# CONFIG_FB_TILEBLITTING is not set +CONFIG_FB_ARMCLCD=y +# CONFIG_FB_S1D13XXX is not set +# CONFIG_FB_VIRTUAL is not set + +# +# Console display driver support +# +# CONFIG_VGA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE=y +# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set +CONFIG_FONTS=y +CONFIG_FONT_8x8=y +CONFIG_FONT_8x16=y +# CONFIG_FONT_6x11 is not set +# CONFIG_FONT_7x14 is not set +# CONFIG_FONT_PEARL_8x8 is not set +# CONFIG_FONT_ACORN_8x8 is not set +# CONFIG_FONT_MINI_4x6 is not set +# CONFIG_FONT_SUN8x16 is not set +# CONFIG_FONT_SUN12x22 is not set +# CONFIG_FONT_10x18 is not set + +# +# Logo configuration +# +CONFIG_LOGO=y +# CONFIG_LOGO_LINUX_MONO is not set +# CONFIG_LOGO_LINUX_VGA16 is not set +CONFIG_LOGO_LINUX_CLUT224=y +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set + +# +# Sound +# +CONFIG_NOMADIK_ACODEC=y +# CONFIG_NOMADIK_STW5094 is not set +CONFIG_NOMADIK_STW5095=y +CONFIG_SOUND=y + +# +# Advanced Linux Sound Architecture +# +CONFIG_SND=y +CONFIG_SND_TIMER=y +CONFIG_SND_PCM=y +# CONFIG_SND_SEQUENCER is not set +# CONFIG_SND_MIXER_OSS is not set +# CONFIG_SND_PCM_OSS is not set +# CONFIG_SND_DYNAMIC_MINORS is not set +CONFIG_SND_SUPPORT_OLD_API=y +CONFIG_SND_VERBOSE_PROCFS=y +# CONFIG_SND_VERBOSE_PRINTK is not set +# CONFIG_SND_DEBUG is not set + +# +# Generic devices +# +CONFIG_SND_AC97_CODEC=y +# CONFIG_SND_DUMMY is not set +# CONFIG_SND_MTPAV is not set +# CONFIG_SND_SERIAL_U16550 is not set +# CONFIG_SND_MPU401 is not set + +# +# ALSA ARM devices +# +CONFIG_SND_NOMADIK_ALSA=m +CONFIG_SND_ARMAACI=y + +# +# USB devices +# +# CONFIG_SND_USB_AUDIO is not set + +# +# Open Sound System +# +# CONFIG_SOUND_PRIME is not set +CONFIG_AC97_BUS=y + +# +# HID Devices +# +CONFIG_HID=y + +# +# USB support +# +CONFIG_USB_ARCH_HAS_HCD=y +# CONFIG_USB_ARCH_HAS_OHCI is not set +# CONFIG_USB_ARCH_HAS_EHCI is not set +CONFIG_USB=y +#CONFIG_USB_DEBUG is not set + +# +# Miscellaneous USB options +# +CONFIG_USB_DEVICEFS=y +CONFIG_USB_BANDWIDTH=y +CONFIG_USB_DYNAMIC_MINORS=y +# CONFIG_USB_SUSPEND is not set +# CONFIG_USB_OTG is not set + +# +# USB Host Controller Drivers +# +# CONFIG_USB_ISP116X_HCD is not set +# CONFIG_USB_SL811_HCD is not set + +# +# USB Device Class drivers +# +# CONFIG_USB_ACM is not set +# CONFIG_USB_PRINTER is not set + +# +# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' +# + +# +# may also be needed; see USB_STORAGE Help for more information +# +CONFIG_USB_STORAGE=y +#CONFIG_USB_STORAGE_DEBUG is not set +# CONFIG_USB_STORAGE_DATAFAB is not set +# CONFIG_USB_STORAGE_FREECOM is not set +# CONFIG_USB_STORAGE_DPCM is not set +# CONFIG_USB_STORAGE_USBAT is not set +# CONFIG_USB_STORAGE_SDDR09 is not set +# CONFIG_USB_STORAGE_SDDR55 is not set +# CONFIG_USB_STORAGE_JUMPSHOT is not set +# CONFIG_USB_STORAGE_ALAUDA is not set +# CONFIG_USB_STORAGE_KARMA is not set +# CONFIG_USB_LIBUSUAL is not set + +# +# USB Input Devices +# +CONFIG_USB_HID=y +# CONFIG_USB_HIDINPUT_POWERBOOK is not set +# CONFIG_HID_FF is not set +# CONFIG_USB_HIDDEV is not set +# CONFIG_USB_AIPTEK is not set +# CONFIG_USB_WACOM is not set +# CONFIG_USB_ACECAD is not set +# CONFIG_USB_KBTAB is not set +# CONFIG_USB_POWERMATE is not set +# CONFIG_USB_TOUCHSCREEN is not set +# CONFIG_USB_YEALINK is not set +# CONFIG_USB_XPAD is not set +# CONFIG_USB_ATI_REMOTE is not set +# CONFIG_USB_ATI_REMOTE2 is not set +# CONFIG_USB_KEYSPAN_REMOTE is not set +# CONFIG_USB_APPLETOUCH is not set + +# +# USB Imaging devices +# +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_MICROTEK is not set + +# +# USB Network Adapters +# +# CONFIG_USB_CATC is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_PEGASUS is not set +# CONFIG_USB_RTL8150 is not set +# CONFIG_USB_USBNET_MII is not set +# CONFIG_USB_USBNET is not set +CONFIG_USB_MON=y + +# +# USB port drivers +# + +# +# USB Serial Converter support +# +# CONFIG_USB_SERIAL is not set + +# +# USB Miscellaneous drivers +# +# CONFIG_USB_EMI62 is not set +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_ADUTUX is not set +# CONFIG_USB_AUERSWALD is not set +# CONFIG_USB_RIO500 is not set +# CONFIG_USB_LEGOTOWER is not set +# CONFIG_USB_LCD is not set +# CONFIG_USB_LED is not set +# CONFIG_USB_CYPRESS_CY7C63 is not set +# CONFIG_USB_CYTHERM is not set +# CONFIG_USB_PHIDGET is not set +# CONFIG_USB_IDMOUSE is not set +# CONFIG_USB_FTDI_ELAN is not set +# CONFIG_USB_APPLEDISPLAY is not set +# CONFIG_USB_LD is not set +# CONFIG_USB_TRANCEVIBRATOR is not set +CONFIG_USB_TEST=y + +# +# USB DSL modem support +# + +# +# USB Gadget Support +# +CONFIG_USB_GADGET=m +# CONFIG_USB_GADGET_DEBUG_FILES is not set +CONFIG_USB_GADGET_SELECTED=y +# CONFIG_USB_GADGET_NET2280 is not set +# CONFIG_USB_GADGET_PXA2XX is not set +# CONFIG_USB_GADGET_GOKU is not set +# CONFIG_USB_GADGET_LH7A40X is not set +# CONFIG_USB_GADGET_OMAP is not set +# CONFIG_USB_GADGET_AT91 is not set +CONFIG_USB_GADGET_DUMMY_HCD=y +CONFIG_USB_DUMMY_HCD=m +CONFIG_USB_GADGET_DUALSPEED=y +CONFIG_USB_ZERO=m +# CONFIG_USB_ETH is not set +# CONFIG_USB_GADGETFS is not set +CONFIG_USB_FILE_STORAGE=m +# CONFIG_USB_FILE_STORAGE_TEST is not set +# CONFIG_USB_G_SERIAL is not set +# CONFIG_USB_MIDI_GADGET is not set +CONFIG_USB_INVENTRA_HCD=m +CONFIG_USB_INVENTRA_HCD_HOST=y +# CONFIG_USB_INVENTRA_HCD_GADGET_API is not set +# CONFIG_USB_INVENTRA_HCD_OTG is not set +# CONFIG_USB_INVENTRA_HCD_OTG_GSTORAGE is not set +# CONFIG_USB_INVENTRA_STATIC_CONFIG is not set +# CONFIG_USB_INVENTRA_DMA is not set +# CONFIG_USB_INVENTRA_MUSB_HAS_AHB_ID is not set +CONFIG_USB_INVENTRA_MUSB_HDR_CCNF_FILE="" +CONFIG_USB_INVENTRA_MUSB_BOARD_FILE="" +CONFIG_USB_INVENTRA_HCD_CUSTOM_OPTIONS="" +# CONFIG_USB_INVENTRA_HCD_POLLING is not set +CONFIG_USB_INVENTRA_HCD_LOGGING=0 + +# +# MMC/SD Card support +# +# CONFIG_MMC is not set + +# +# Real Time Clock +# +CONFIG_RTC_LIB=y +# CONFIG_RTC_CLASS is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT2_FS_XIP is not set +# CONFIG_EXT3_FS is not set +# CONFIG_EXT4DEV_FS is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +# CONFIG_FS_POSIX_ACL is not set +# CONFIG_XFS_FS is not set +# CONFIG_GFS2_FS is not set +# CONFIG_OCFS2_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set +CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y +# CONFIG_QUOTA is not set +CONFIG_DNOTIFY=y +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +CONFIG_FUSE_FS=y + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=y +CONFIG_MSDOS_FS=y +CONFIG_VFAT_FS=y +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="cp437" +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_SYSCTL=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +# CONFIG_TMPFS_POSIX_ACL is not set +# CONFIG_HUGETLB_PAGE is not set +CONFIG_RAMFS=y +# CONFIG_CONFIGFS_FS is not set + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +CONFIG_YAFFS_FS=y +CONFIG_YAFFS_YAFFS1=y +# CONFIG_YAFFS_9BYTE_TAGS is not set +# CONFIG_YAFFS_DOES_ECC is not set +CONFIG_YAFFS_YAFFS2=y +CONFIG_YAFFS_AUTO_YAFFS2=y +# CONFIG_YAFFS_DISABLE_LAZY_LOAD is not set +# CONFIG_YAFFS_DISABLE_WIDE_TNODES is not set +# CONFIG_YAFFS_ALWAYS_CHECK_CHUNK_ERASED is not set +CONFIG_YAFFS_SHORT_NAMES_IN_RAM=y +CONFIG_JFFS2_FS=y +CONFIG_JFFS2_FS_DEBUG=0 +CONFIG_JFFS2_FS_WRITEBUFFER=y +# CONFIG_JFFS2_SUMMARY is not set +# CONFIG_JFFS2_FS_XATTR is not set +# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set +CONFIG_JFFS2_ZLIB=y +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN is not set +CONFIG_CRAMFS=y +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +# CONFIG_NFS_V3_ACL is not set +CONFIG_NFS_V4=y +# CONFIG_NFS_DIRECTIO is not set +# CONFIG_NFSD is not set +CONFIG_ROOT_NFS=y +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=y +CONFIG_SUNRPC_GSS=y +CONFIG_RPCSEC_GSS_KRB5=y +# CONFIG_RPCSEC_GSS_SPKM3 is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set +# CONFIG_9P_FS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y + +# +# Native Language Support +# +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="cp437" +CONFIG_NLS_CODEPAGE_437=y +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +# CONFIG_NLS_ASCII is not set +CONFIG_NLS_ISO8859_1=y +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +# CONFIG_NLS_UTF8 is not set + +# +# Distributed Lock Manager +# +# CONFIG_DLM is not set + +# +# Profiling support +# +CONFIG_PROFILING=y +CONFIG_OPROFILE=y + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +CONFIG_ENABLE_MUST_CHECK=y +CONFIG_MAGIC_SYSRQ=y +# CONFIG_UNUSED_SYMBOLS is not set +# CONFIG_DEBUG_FS is not set +# CONFIG_HEADERS_CHECK is not set +# CONFIG_DEBUG_KERNEL is not set +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_DEBUG_BUGVERBOSE is not set +CONFIG_FRAME_POINTER=y +# CONFIG_WANT_EXTRA_DEBUG_INFORMATION is not set +# CONFIG_DEBUG_USER is not set + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +CONFIG_CRYPTO=y +CONFIG_CRYPTO_ALGAPI=y +CONFIG_CRYPTO_BLKCIPHER=y +CONFIG_CRYPTO_MANAGER=y +# CONFIG_CRYPTO_HMAC is not set +# CONFIG_CRYPTO_XCBC is not set +# CONFIG_CRYPTO_NULL is not set +# CONFIG_CRYPTO_MD4 is not set +CONFIG_CRYPTO_MD5=y +# CONFIG_CRYPTO_SHA1 is not set +# CONFIG_CRYPTO_SHA256 is not set +# CONFIG_CRYPTO_SHA512 is not set +# CONFIG_CRYPTO_WP512 is not set +# CONFIG_CRYPTO_TGR192 is not set +# CONFIG_CRYPTO_GF128MUL is not set +CONFIG_CRYPTO_ECB=m +CONFIG_CRYPTO_CBC=y +# CONFIG_CRYPTO_LRW is not set +CONFIG_CRYPTO_DES=y +# CONFIG_CRYPTO_BLOWFISH is not set +# CONFIG_CRYPTO_TWOFISH is not set +# CONFIG_CRYPTO_SERPENT is not set +# CONFIG_CRYPTO_AES is not set +# CONFIG_CRYPTO_CAST5 is not set +# CONFIG_CRYPTO_CAST6 is not set +# CONFIG_CRYPTO_TEA is not set +# CONFIG_CRYPTO_ARC4 is not set +# CONFIG_CRYPTO_KHAZAD is not set +# CONFIG_CRYPTO_ANUBIS is not set +# CONFIG_CRYPTO_DEFLATE is not set +# CONFIG_CRYPTO_MICHAEL_MIC is not set +# CONFIG_CRYPTO_CRC32C is not set +# CONFIG_CRYPTO_TEST is not set + +# +# Hardware crypto devices +# + +# +# Library routines +# +CONFIG_BITREVERSE=y +# CONFIG_CRC_CCITT is not set +# CONFIG_CRC16 is not set +CONFIG_CRC32=y +CONFIG_LIBCRC32C=m +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y +CONFIG_PLIST=y +CONFIG_IOMAP_COPY=y --- linux-2.6.20.orig/arch/arm/kernel/Makefile +++ linux-2.6.20/arch/arm/kernel/Makefile @@ -17,10 +17,11 @@ obj-$(CONFIG_FIQ) += fiq.o obj-$(CONFIG_MODULES) += armksyms.o module.o obj-$(CONFIG_ARTHUR) += arthur.o obj-$(CONFIG_ISA_DMA) += dma-isa.o obj-$(CONFIG_PCI) += bios32.o isa.o obj-$(CONFIG_SMP) += smp.o +obj-$(CONFIG_KGDB) += kgdb.o kgdb-jmp.o obj-$(CONFIG_OABI_COMPAT) += sys_oabi-compat.o obj-$(CONFIG_CRUNCH) += crunch.o crunch-bits.o AFLAGS_crunch-bits.o := -Wa,-mcpu=ep9312 --- linux-2.6.20.orig/arch/arm/kernel/armksyms.c +++ linux-2.6.20/arch/arm/kernel/armksyms.c @@ -29,10 +29,17 @@ extern void __ashrdi3(void); extern void __divsi3(void); extern void __lshrdi3(void); extern void __modsi3(void); extern void __muldi3(void); extern void __ucmpdi2(void); +#ifdef CONFIG_AEABI +extern void __aeabi_uldivmod(void); +#else +extern void __udivdi3(void); +#endif +extern void __umoddi3(void); +extern void __udivmoddi4(void); extern void __udivsi3(void); extern void __umodsi3(void); extern void __do_div64(void); extern void __aeabi_idiv(void); @@ -137,10 +144,17 @@ EXPORT_SYMBOL(__divsi3); EXPORT_SYMBOL(__lshrdi3); EXPORT_SYMBOL(__modsi3); EXPORT_SYMBOL(__muldi3); EXPORT_SYMBOL(__ucmpdi2); EXPORT_SYMBOL(__udivsi3); +#ifdef CONFIG_AEABI +EXPORT_SYMBOL(__aeabi_uldivmod); +#else +EXPORT_SYMBOL(__udivdi3); +#endif +EXPORT_SYMBOL(__umoddi3); +EXPORT_SYMBOL(__udivmoddi4); EXPORT_SYMBOL(__umodsi3); EXPORT_SYMBOL(__do_div64); #ifdef CONFIG_AEABI EXPORT_SYMBOL(__aeabi_idiv); --- linux-2.6.20.orig/arch/arm/kernel/dma.c +++ linux-2.6.20/arch/arm/kernel/dma.c @@ -226,10 +226,11 @@ EXPORT_SYMBOL(disable_dma); */ int dma_channel_active(dmach_t channel) { return dma_chan[channel].active; } +EXPORT_SYMBOL(dma_channel_active); void set_dma_page(dmach_t channel, char pagenr) { printk(KERN_ERR "dma%d: trying to set_dma_page\n", channel); } --- linux-2.6.20.orig/arch/arm/kernel/entry-armv.S +++ linux-2.6.20/arch/arm/kernel/entry-armv.S @@ -13,10 +13,11 @@ * * Note: there is a StrongARM bug in the STMIA rn, {regs}^ instruction that causes * it to save wrong values... Be aware! */ +#include #include #include #include #include #include @@ -237,10 +238,11 @@ svc_preempt: ldr r0, [tsk, #TI_FLAGS] @ get new tasks TI_FLAGS tst r0, #_TIF_NEED_RESCHED beq preempt_return @ go again b 1b #endif + CFI_END_FRAME(__irq_svc) .align 5 __und_svc: svc_entry --- linux-2.6.20.orig/arch/arm/kernel/irq.c +++ linux-2.6.20/arch/arm/kernel/irq.c @@ -74,11 +74,23 @@ int show_interrupts(struct seq_file *p, if (!action) goto unlock; seq_printf(p, "%3d: ", i); for_each_present_cpu(cpu) +#ifdef CONFIG_ARCH_NOMADIK + /* + * Outputs Priority Level for irq, if programmed + * refer: ./Documentation/arm/STM-Nomadik/irq_usrguide.txt + */ + if (action->flags & SA_IRQPRIORITY_MASK) + seq_printf(p, "%10u:PL%02d", kstat_cpu(cpu).irqs[i], + (int)(action->flags)>>4 & 0x0f); + else seq_printf(p, "%10u ", kstat_cpu(cpu).irqs[i]); +#else + seq_printf(p, "%10u ", kstat_cpu(cpu).irqs[i]); +#endif seq_printf(p, " %10s", irq_desc[i].chip->name ? : "-"); seq_printf(p, " %s", action->name); for (action = action->next; action; action = action->next) seq_printf(p, ", %s", action->name); --- /dev/null +++ linux-2.6.20/arch/arm/kernel/kgdb-jmp.S @@ -0,0 +1,30 @@ +/* + * arch/arm/kernel/kgdb-jmp.S + * + * Trivial setjmp and longjmp procedures to support bus error recovery + * which may occur during kgdb memory read/write operations. + * + * Author: MontaVista Software, Inc. + * source@mvista.com + * + * 2002-2005 (c) MontaVista Software, Inc. This file is licensed under the + * terms of the GNU General Public License version 2. This program as licensed + * "as is" without any warranty of any kind, whether express or implied. + */ +#include + +ENTRY (kgdb_fault_setjmp) + /* Save registers */ + stmia r0, {r0-r14} + str lr,[r0, #60] + mrs r1,cpsr + str r1,[r0,#64] + ldr r1,[r0,#4] + mov r0, #0 + mov pc,lr + +ENTRY (kgdb_fault_longjmp) + /* Restore registers */ + mov r1,#1 + str r1,[r0] + ldmia r0,{r0-pc}^ --- /dev/null +++ linux-2.6.20/arch/arm/kernel/kgdb.c @@ -0,0 +1,208 @@ +/* + * arch/arm/kernel/kgdb.c + * + * ARM KGDB support + * + * Copyright (c) 2002-2004 MontaVista Software, Inc + * + * Authors: George Davis + * Deepak Saxena + */ +//#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +/* Make a local copy of the registers passed into the handler (bletch) */ +void regs_to_gdb_regs(unsigned long *gdb_regs, struct pt_regs *kernel_regs) +{ + int regno; + + /* Initialize all to zero (??) */ + for (regno = 0; regno < GDB_MAX_REGS; regno++) + gdb_regs[regno] = 0; + + gdb_regs[_R0] = kernel_regs->ARM_r0; + gdb_regs[_R1] = kernel_regs->ARM_r1; + gdb_regs[_R2] = kernel_regs->ARM_r2; + gdb_regs[_R3] = kernel_regs->ARM_r3; + gdb_regs[_R4] = kernel_regs->ARM_r4; + gdb_regs[_R5] = kernel_regs->ARM_r5; + gdb_regs[_R6] = kernel_regs->ARM_r6; + gdb_regs[_R7] = kernel_regs->ARM_r7; + gdb_regs[_R8] = kernel_regs->ARM_r8; + gdb_regs[_R9] = kernel_regs->ARM_r9; + gdb_regs[_R10] = kernel_regs->ARM_r10; + gdb_regs[_FP] = kernel_regs->ARM_fp; + gdb_regs[_IP] = kernel_regs->ARM_ip; + gdb_regs[_SP] = kernel_regs->ARM_sp; + gdb_regs[_LR] = kernel_regs->ARM_lr; + gdb_regs[_PC] = kernel_regs->ARM_pc; + gdb_regs[_CPSR] = kernel_regs->ARM_cpsr; +} + +/* Copy local gdb registers back to kgdb regs, for later copy to kernel */ +void gdb_regs_to_regs(unsigned long *gdb_regs, struct pt_regs *kernel_regs) +{ + kernel_regs->ARM_r0 = gdb_regs[_R0]; + kernel_regs->ARM_r1 = gdb_regs[_R1]; + kernel_regs->ARM_r2 = gdb_regs[_R2]; + kernel_regs->ARM_r3 = gdb_regs[_R3]; + kernel_regs->ARM_r4 = gdb_regs[_R4]; + kernel_regs->ARM_r5 = gdb_regs[_R5]; + kernel_regs->ARM_r6 = gdb_regs[_R6]; + kernel_regs->ARM_r7 = gdb_regs[_R7]; + kernel_regs->ARM_r8 = gdb_regs[_R8]; + kernel_regs->ARM_r9 = gdb_regs[_R9]; + kernel_regs->ARM_r10 = gdb_regs[_R10]; + kernel_regs->ARM_fp = gdb_regs[_FP]; + kernel_regs->ARM_ip = gdb_regs[_IP]; + kernel_regs->ARM_sp = gdb_regs[_SP]; + kernel_regs->ARM_lr = gdb_regs[_LR]; + kernel_regs->ARM_pc = gdb_regs[_PC]; + kernel_regs->ARM_cpsr = gdb_regs[GDB_MAX_REGS - 1]; +} + +static inline struct pt_regs *kgdb_get_user_regs(struct task_struct *task) +{ + return (struct pt_regs *) + ((unsigned long)task->thread_info + THREAD_SIZE - + 8 - sizeof(struct pt_regs)); +} + +void sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, + struct task_struct *task) +{ + int regno; + struct pt_regs *thread_regs; + + /* Just making sure... */ + if (task == NULL) + return; + + /* Initialize to zero */ + for (regno = 0; regno < GDB_MAX_REGS; regno++) + gdb_regs[regno] = 0; + + /* Otherwise, we have only some registers from switch_to() */ + thread_regs = kgdb_get_user_regs(task); + gdb_regs[_R0] = thread_regs->ARM_r0; /* Not really valid? */ + gdb_regs[_R1] = thread_regs->ARM_r1; /* " " */ + gdb_regs[_R2] = thread_regs->ARM_r2; /* " " */ + gdb_regs[_R3] = thread_regs->ARM_r3; /* " " */ + gdb_regs[_R4] = thread_regs->ARM_r4; + gdb_regs[_R5] = thread_regs->ARM_r5; + gdb_regs[_R6] = thread_regs->ARM_r6; + gdb_regs[_R7] = thread_regs->ARM_r7; + gdb_regs[_R8] = thread_regs->ARM_r8; + gdb_regs[_R9] = thread_regs->ARM_r9; + gdb_regs[_R10] = thread_regs->ARM_r10; + gdb_regs[_FP] = thread_regs->ARM_fp; + gdb_regs[_IP] = thread_regs->ARM_ip; + gdb_regs[_SP] = thread_regs->ARM_sp; + gdb_regs[_LR] = thread_regs->ARM_lr; + gdb_regs[_PC] = thread_regs->ARM_pc; + gdb_regs[_CPSR] = thread_regs->ARM_cpsr; +} + +static int compiled_break; + +int kgdb_arch_handle_exception(int exception_vector, int signo, + int err_code, char *remcom_in_buffer, + char *remcom_out_buffer, + struct pt_regs *linux_regs) +{ + long addr; + char *ptr; + + switch (remcom_in_buffer[0]) { + case 'c': + kgdb_contthread = NULL; + + /* + * Try to read optional parameter, pc unchanged if no parm. + * If this was a compiled breakpoint, we need to move + * to the next instruction or we will just breakpoint + * over and over again. + */ + ptr = &remcom_in_buffer[1]; + if (kgdb_hex2long(&ptr, &addr)) { + linux_regs->ARM_pc = addr; + } else if (compiled_break == 1) { + linux_regs->ARM_pc += 4; + } + + compiled_break = 0; + + return 0; + } + + return -1; +} + +static int kgdb_brk_fn(struct pt_regs *regs, unsigned int instr) +{ + kgdb_handle_exception(1, SIGTRAP, 0, regs); + + return 0; +} + +static int kgdb_compiled_brk_fn(struct pt_regs *regs, unsigned int instr) +{ + compiled_break = 1; + kgdb_handle_exception(1, SIGTRAP, 0, regs); + + return 0; +} + +static struct undef_hook kgdb_brkpt_hook = { + .instr_mask = 0xffffffff, + .instr_val = KGDB_BREAKINST, + .fn = kgdb_brk_fn +}; + +static struct undef_hook kgdb_compiled_brkpt_hook = { + .instr_mask = 0xffffffff, + .instr_val = KGDB_COMPILED_BREAK, + .fn = kgdb_compiled_brk_fn +}; + +/* + * Register our undef instruction hooks with ARM undef core. + * We regsiter a hook specifically looking for the KGB break inst + * and we handle the normal undef case within the do_undefinstr + * handler. + */ +int kgdb_arch_init(void) +{ + register_undef_hook(&kgdb_brkpt_hook); + register_undef_hook(&kgdb_compiled_brkpt_hook); + + return 0; +} + +struct kgdb_arch arch_kgdb_ops = { +#ifndef __ARMEB__ + .gdb_bpt_instr = {0xfe, 0xde, 0xff, 0xe7} +#else + .gdb_bpt_instr = {0xe7, 0xff, 0xde, 0xfe} +#endif +}; --- linux-2.6.20.orig/arch/arm/kernel/setup.c +++ linux-2.6.20/arch/arm/kernel/setup.c @@ -827,10 +827,15 @@ void __init setup_arch(char **cmdline_p) conswitchp = &vga_con; #elif defined(CONFIG_DUMMY_CONSOLE) conswitchp = &dummy_con; #endif #endif + +#if defined(CONFIG_KGDB) + extern void __init early_trap_init(void); + early_trap_init(); +#endif } static int __init topology_init(void) { --- linux-2.6.20.orig/arch/arm/kernel/traps.c +++ linux-2.6.20/arch/arm/kernel/traps.c @@ -277,25 +277,29 @@ asmlinkage void do_undefinstr(struct pt_ { unsigned int correction = thumb_mode(regs) ? 2 : 4; unsigned int instr; struct undef_hook *hook; siginfo_t info; + mm_segment_t fs; void __user *pc; /* * According to the ARM ARM, PC is 2 or 4 bytes ahead, * depending whether we're in Thumb mode or not. * Correct this offset. */ regs->ARM_pc -= correction; + fs = get_fs(); + set_fs(KERNEL_DS); pc = (void __user *)instruction_pointer(regs); if (thumb_mode(regs)) { get_user(instr, (u16 __user *)pc); } else { get_user(instr, (u32 __user *)pc); } + set_fs(fs); spin_lock_irq(&undef_lock); list_for_each_entry(hook, &undef_hook, node) { if ((instr & hook->instr_mask) == hook->instr_val && (regs->ARM_cpsr & hook->cpsr_mask) == hook->cpsr_val) { @@ -680,10 +684,17 @@ void abort(void) } EXPORT_SYMBOL(abort); void __init trap_init(void) { +#if defined(CONFIG_KGDB) + return; +} + +void __init early_trap_init(void) +{ +#endif unsigned long vectors = CONFIG_VECTORS_BASE; extern char __stubs_start[], __stubs_end[]; extern char __vectors_start[], __vectors_end[]; extern char __kuser_helper_start[], __kuser_helper_end[]; int kuser_sz = __kuser_helper_end - __kuser_helper_start; --- linux-2.6.20.orig/arch/arm/lib/Makefile +++ linux-2.6.20/arch/arm/lib/Makefile @@ -11,11 +11,11 @@ lib-y := backtrace.o changebit.o csumip strncpy_from_user.o strnlen_user.o \ strchr.o strrchr.o \ testchangebit.o testclearbit.o testsetbit.o \ ashldi3.o ashrdi3.o lshrdi3.o muldi3.o \ ucmpdi2.o lib1funcs.o div64.o sha1.o \ - io-readsb.o io-writesb.o io-readsl.o io-writesl.o + io-readsb.o io-writesb.o io-readsl.o io-writesl.o udivdi3.o \ mmu-y := clear_user.o copy_page.o getuser.o putuser.o # the code in uaccess.S is not preemption safe and # probably faster on ARMv3 only --- /dev/null +++ linux-2.6.20/arch/arm/lib/gcclib.h @@ -0,0 +1,25 @@ +/* gcclib.h -- definitions for various functions 'borrowed' from gcc-2.95.3 */ +/* I Molton 29/07/01 */ + +#define BITS_PER_UNIT 8 +#define SI_TYPE_SIZE (sizeof (SItype) * BITS_PER_UNIT) + +typedef unsigned int UQItype __attribute__ ((mode (QI))); +typedef int SItype __attribute__ ((mode (SI))); +typedef unsigned int USItype __attribute__ ((mode (SI))); +typedef int DItype __attribute__ ((mode (DI))); +typedef int word_type __attribute__ ((mode (__word__))); +typedef unsigned int UDItype __attribute__ ((mode (DI))); + +#ifdef __ARMEB__ + struct DIstruct {SItype high, low;}; +#else + struct DIstruct {SItype low, high;}; +#endif + +typedef union +{ + struct DIstruct s; + DItype ll; +} DIunion; + --- /dev/null +++ linux-2.6.20/arch/arm/lib/longlong.h @@ -0,0 +1,184 @@ +/* longlong.h -- based on code from gcc-2.95.3 + + definitions for mixed size 32/64 bit arithmetic. + Copyright (C) 1991, 92, 94, 95, 96, 1997, 1998 Free Software Foundation, Inc. + + This definition file is free software; you can redistribute it + and/or modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2, or (at your option) any later version. + + This definition file is distributed in the hope that it will be + useful, but WITHOUT ANY WARRANTY; without even the implied + warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +/* Borrowed from GCC 2.95.3, I Molton 29/07/01 */ + +#ifndef SI_TYPE_SIZE +#define SI_TYPE_SIZE 32 +#endif + +#define __BITS4 (SI_TYPE_SIZE / 4) +#define __ll_B (1L << (SI_TYPE_SIZE / 2)) +#define __ll_lowpart(t) ((USItype) (t) % __ll_B) +#define __ll_highpart(t) ((USItype) (t) / __ll_B) + +/* Define auxiliary asm macros. + + 1) umul_ppmm(high_prod, low_prod, multipler, multiplicand) + multiplies two USItype integers MULTIPLER and MULTIPLICAND, + and generates a two-part USItype product in HIGH_PROD and + LOW_PROD. + + 2) __umulsidi3(a,b) multiplies two USItype integers A and B, + and returns a UDItype product. This is just a variant of umul_ppmm. + + 3) udiv_qrnnd(quotient, remainder, high_numerator, low_numerator, + denominator) divides a two-word unsigned integer, composed by the + integers HIGH_NUMERATOR and LOW_NUMERATOR, by DENOMINATOR and + places the quotient in QUOTIENT and the remainder in REMAINDER. + HIGH_NUMERATOR must be less than DENOMINATOR for correct operation. + If, in addition, the most significant bit of DENOMINATOR must be 1, + then the pre-processor symbol UDIV_NEEDS_NORMALIZATION is defined to 1. + + 4) sdiv_qrnnd(quotient, remainder, high_numerator, low_numerator, + denominator). Like udiv_qrnnd but the numbers are signed. The + quotient is rounded towards 0. + + 5) count_leading_zeros(count, x) counts the number of zero-bits from + the msb to the first non-zero bit. This is the number of steps X + needs to be shifted left to set the msb. Undefined for X == 0. + + 6) add_ssaaaa(high_sum, low_sum, high_addend_1, low_addend_1, + high_addend_2, low_addend_2) adds two two-word unsigned integers, + composed by HIGH_ADDEND_1 and LOW_ADDEND_1, and HIGH_ADDEND_2 and + LOW_ADDEND_2 respectively. The result is placed in HIGH_SUM and + LOW_SUM. Overflow (i.e. carry out) is not stored anywhere, and is + lost. + + 7) sub_ddmmss(high_difference, low_difference, high_minuend, + low_minuend, high_subtrahend, low_subtrahend) subtracts two + two-word unsigned integers, composed by HIGH_MINUEND_1 and + LOW_MINUEND_1, and HIGH_SUBTRAHEND_2 and LOW_SUBTRAHEND_2 + respectively. The result is placed in HIGH_DIFFERENCE and + LOW_DIFFERENCE. Overflow (i.e. carry out) is not stored anywhere, + and is lost. + + If any of these macros are left undefined for a particular CPU, + C macros are used. */ + +#if defined (__arm__) +#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ + __asm__ ("adds %1, %4, %5 \n\ + adc %0, %2, %3" \ + : "=r" ((USItype) (sh)), \ + "=&r" ((USItype) (sl)) \ + : "%r" ((USItype) (ah)), \ + "rI" ((USItype) (bh)), \ + "%r" ((USItype) (al)), \ + "rI" ((USItype) (bl))) +#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ + __asm__ ("subs %1, %4, %5 \n\ + sbc %0, %2, %3" \ + : "=r" ((USItype) (sh)), \ + "=&r" ((USItype) (sl)) \ + : "r" ((USItype) (ah)), \ + "rI" ((USItype) (bh)), \ + "r" ((USItype) (al)), \ + "rI" ((USItype) (bl))) +#define umul_ppmm(xh, xl, a, b) \ +{register USItype __t0, __t1, __t2; \ + __asm__ ("%@ Inlined umul_ppmm \n\ + mov %2, %5, lsr #16 \n\ + mov %0, %6, lsr #16 \n\ + bic %3, %5, %2, lsl #16 \n\ + bic %4, %6, %0, lsl #16 \n\ + mul %1, %3, %4 \n\ + mul %4, %2, %4 \n\ + mul %3, %0, %3 \n\ + mul %0, %2, %0 \n\ + adds %3, %4, %3 \n\ + addcs %0, %0, #65536 \n\ + adds %1, %1, %3, lsl #16 \n\ + adc %0, %0, %3, lsr #16" \ + : "=&r" ((USItype) (xh)), \ + "=r" ((USItype) (xl)), \ + "=&r" (__t0), "=&r" (__t1), "=r" (__t2) \ + : "r" ((USItype) (a)), \ + "r" ((USItype) (b)));} +#define UMUL_TIME 20 +#define UDIV_TIME 100 +#endif /* __arm__ */ + +#define __umulsidi3(u, v) \ + ({DIunion __w; \ + umul_ppmm (__w.s.high, __w.s.low, u, v); \ + __w.ll; }) + +#define __udiv_qrnnd_c(q, r, n1, n0, d) \ + do { \ + USItype __d1, __d0, __q1, __q0; \ + USItype __r1, __r0, __m; \ + __d1 = __ll_highpart (d); \ + __d0 = __ll_lowpart (d); \ + \ + __r1 = (n1) % __d1; \ + __q1 = (n1) / __d1; \ + __m = (USItype) __q1 * __d0; \ + __r1 = __r1 * __ll_B | __ll_highpart (n0); \ + if (__r1 < __m) \ + { \ + __q1--, __r1 += (d); \ + if (__r1 >= (d)) /* i.e. we didn't get carry when adding to __r1 */\ + if (__r1 < __m) \ + __q1--, __r1 += (d); \ + } \ + __r1 -= __m; \ + \ + __r0 = __r1 % __d1; \ + __q0 = __r1 / __d1; \ + __m = (USItype) __q0 * __d0; \ + __r0 = __r0 * __ll_B | __ll_lowpart (n0); \ + if (__r0 < __m) \ + { \ + __q0--, __r0 += (d); \ + if (__r0 >= (d)) \ + if (__r0 < __m) \ + __q0--, __r0 += (d); \ + } \ + __r0 -= __m; \ + \ + (q) = (USItype) __q1 * __ll_B | __q0; \ + (r) = __r0; \ + } while (0) + +#define UDIV_NEEDS_NORMALIZATION 1 +#define udiv_qrnnd __udiv_qrnnd_c + +extern const UQItype __clz_tab[]; +#define count_leading_zeros(count, x) \ + do { \ + USItype __xr = (x); \ + USItype __a; \ + \ + if (SI_TYPE_SIZE <= 32) \ + { \ + __a = __xr < ((USItype)1<<2*__BITS4) \ + ? (__xr < ((USItype)1<<__BITS4) ? 0 : __BITS4) \ + : (__xr < ((USItype)1<<3*__BITS4) ? 2*__BITS4 : 3*__BITS4); \ + } \ + else \ + { \ + for (__a = SI_TYPE_SIZE - 8; __a > 0; __a -= 8) \ + if (((__xr >> __a) & 0xff) != 0) \ + break; \ + } \ + \ + (count) = SI_TYPE_SIZE - (__clz_tab[__xr >> __a] + __a); \ + } while (0) --- /dev/null +++ linux-2.6.20/arch/arm/lib/udivdi3.c @@ -0,0 +1,246 @@ +/* More subroutines needed by GCC output code on some machines. */ +/* Compile this one with gcc. */ +/* Copyright (C) 1989, 92-98, 1999 Free Software Foundation, Inc. + +This file is part of GNU CC. + +GNU CC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU CC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU CC; see the file COPYING. If not, write to +the Free Software Foundation, 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. */ + +/* As a special exception, if you link this library with other files, + some of which are compiled with GCC, to produce an executable, + this library does not by itself cause the resulting executable + to be covered by the GNU General Public License. + This exception does not however invalidate any other reasons why + the executable file might be covered by the GNU General Public License. + */ +/* support functions required by the kernel. based on code from gcc-2.95.3 */ +/* I Molton 29/07/01 */ + +#include "gcclib.h" +#include "longlong.h" + +const UQItype __clz_tab[] = +{ + 0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, + 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, +}; + +UDItype +__udivmoddi4 (UDItype n, UDItype d, UDItype *rp) +{ + DIunion ww; + DIunion nn, dd; + DIunion rr; + USItype d0, d1, n0, n1, n2; + USItype q0, q1; + USItype b, bm; + + nn.ll = n; + dd.ll = d; + + d0 = dd.s.low; + d1 = dd.s.high; + n0 = nn.s.low; + n1 = nn.s.high; + + if (d1 == 0) + { + if (d0 > n1) + { + /* 0q = nn / 0D */ + + count_leading_zeros (bm, d0); + + if (bm != 0) + { + /* Normalize, i.e. make the most significant bit of the + denominator set. */ + + d0 = d0 << bm; + n1 = (n1 << bm) | (n0 >> (SI_TYPE_SIZE - bm)); + n0 = n0 << bm; + } + + udiv_qrnnd (q0, n0, n1, n0, d0); + q1 = 0; + + /* Remainder in n0 >> bm. */ + } + else + { + /* qq = NN / 0d */ + + if (d0 == 0) + d0 = 1 / d0; /* Divide intentionally by zero. */ + + count_leading_zeros (bm, d0); + + if (bm == 0) + { + /* From (n1 >= d0) /\ (the most significant bit of d0 is set), + conclude (the most significant bit of n1 is set) /\ (the + leading quotient digit q1 = 1). + + This special case is necessary, not an optimization. + (Shifts counts of SI_TYPE_SIZE are undefined.) */ + + n1 -= d0; + q1 = 1; + } + else + { + /* Normalize. */ + + b = SI_TYPE_SIZE - bm; + + d0 = d0 << bm; + n2 = n1 >> b; + n1 = (n1 << bm) | (n0 >> b); + n0 = n0 << bm; + + udiv_qrnnd (q1, n1, n2, n1, d0); + } + + /* n1 != d0... */ + + udiv_qrnnd (q0, n0, n1, n0, d0); + + /* Remainder in n0 >> bm. */ + } + + if (rp != 0) + { + rr.s.low = n0 >> bm; + rr.s.high = 0; + *rp = rr.ll; + } + } + else + { + if (d1 > n1) + { + /* 00 = nn / DD */ + + q0 = 0; + q1 = 0; + + /* Remainder in n1n0. */ + if (rp != 0) + { + rr.s.low = n0; + rr.s.high = n1; + *rp = rr.ll; + } + } + else + { + /* 0q = NN / dd */ + + count_leading_zeros (bm, d1); + if (bm == 0) + { + /* From (n1 >= d1) /\ (the most significant bit of d1 is set), + conclude (the most significant bit of n1 is set) /\ (the + quotient digit q0 = 0 or 1). + + This special case is necessary, not an optimization. */ + + /* The condition on the next line takes advantage of that + n1 >= d1 (true due to program flow). */ + if (n1 > d1 || n0 >= d0) + { + q0 = 1; + sub_ddmmss (n1, n0, n1, n0, d1, d0); + } + else + q0 = 0; + + q1 = 0; + + if (rp != 0) + { + rr.s.low = n0; + rr.s.high = n1; + *rp = rr.ll; + } + } + else + { + USItype m1, m0; + /* Normalize. */ + + b = SI_TYPE_SIZE - bm; + + d1 = (d1 << bm) | (d0 >> b); + d0 = d0 << bm; + n2 = n1 >> b; + n1 = (n1 << bm) | (n0 >> b); + n0 = n0 << bm; + + udiv_qrnnd (q0, n1, n2, n1, d1); + umul_ppmm (m1, m0, q0, d0); + + if (m1 > n1 || (m1 == n1 && m0 > n0)) + { + q0--; + sub_ddmmss (m1, m0, m1, m0, d1, d0); + } + + q1 = 0; + + /* Remainder in (n1n0 - m1m0) >> bm. */ + if (rp != 0) + { + sub_ddmmss (n1, n0, n1, n0, m1, m0); + rr.s.low = (n1 << b) | (n0 >> bm); + rr.s.high = n1 >> bm; + *rp = rr.ll; + } + } + } + } + + ww.s.low = q0; + ww.s.high = q1; + return ww.ll; +} + +UDItype +#ifdef CONFIG_AEABI +__aeabi_uldivmod (UDItype n, UDItype d) +#else +__udivdi3 (UDItype n, UDItype d) +#endif +{ + return __udivmoddi4 (n, d, (UDItype *) 0); +} + +UDItype +__umoddi3 (UDItype u, UDItype v) +{ + UDItype w; + + (void) __udivmoddi4 (u ,v, &w); + + return w; +} + --- /dev/null +++ linux-2.6.20/arch/arm/mach-nomadik/Kconfig-nomadik @@ -0,0 +1,267 @@ +if ARCH_NOMADIK + +# The GPIO_PIN_23 is shared between MMC and MSP0. +# by default this pin is used for MMC for NOMADIK_NDK15_REV2_B_03 target +# to use this pin for MSP it should be configured 'n' +config NOMADIK_NDK15_REV2_MMC + bool + default y if NOMADIK_NDK15_REV2_B_03 + +config NOMADIK_NDK10_CUTA + bool + default y if NOMADIK_NDK10_CUT_A1 + +config NOMADIK_NDK10_CUTB + bool + default y if (NOMADIK_NDK10_CUT_B0 || NOMADIK_NDK10_CUT_B06) + +config NOMADIK_GPIO + bool + default y + +config NOMADIK_ENABLE_L2CACHE + bool "Enable L2 Cache controller" + depends on (NOMADIK_NDK15 || NOMADIK_NHK15) + default y if NOMADIK_STN8815CAS22H11 + select L2CACHE_ENABLE + help + Nomadik Chip version for this platfrom supports L2 Cache + by default it is enabled, if you want to check system + performanence without L2 Cache, then say no here + +config GPIO_PROC + bool + default y + depends on NOMADIK_GPIO + +config NOMADIK_DMA + tristate "NOMADIK DMA SUPPORT" + depends on ISA_DMA_API + default y + help + Nomadik DMA low level driver for standrd DMA interface + +config NOMADIK_SSP + tristate "NOMADIK SSP SUPPORT" + depends on (NOMADIK_DMA && NOMADIK_SPI) + default m + help + Depends on Nomadik DMA driver and SPI driver + +config NOMADIK_MSP + tristate "NOMADIK MSP SUPPORT" + depends on (NOMADIK_DMA && NOMADIK_SPI) + default m + help + Depends on Nomadik DMA driver and SPI driver + +config NOMADIK_MTU + tristate "NOMADIK MTU SUPPORT" + default m + help + The driver offers 8 MTU units tobe used. + In case of module only MTU1 unit will be + available with 4 timers: + MTU1_T0, MTU1_T1, MTU1_T2 & MTU1_T3 + +config NOMADIK_MTU_SYSTEM_TICK + bool "NOMADIK MTU SYSTEM TICK SUPPORT" + depends on NOMADIK_MTU + help + This will prevent the system tick to be used through MTU. + default y + +config NOMADIK_RTC + bool "NOMADIK RTC/RTT SUPPORT" + default y + help + The driver offers RTC and RTT support. + The RTC can be used through /dev/rtc interface for real + time calculations, alarms, long delays if required + If unsure say Y here. + +config NOMADIK_PM + bool "NOMADIK POWER MANAGEMENT SUPPORT" + depends on ( (NOMADIK_NHK15 || NOMADIK_NDK15) && NOMADIK_RTC ) + default y + select PM if NOMADIK_PM + help + Nomadik Power Management Driver + +config NOMADIK_SVA_INIT_MEM + bool "NOMADIK SVA MEMORY at initialisation" + default n + help + The driver uses physically contiguous memory allocated + at kernel initialisation time. + If unsure say N here. + +config FORCE_MAX_ZONEORDER + int "Maximum zone order" + default "13" + help + For use cases having large memory requirements choosing a + larger memory size is advised. + +config NOMADIK_SVA_MEM_SIZE + int "SVA initial memory size" if NOMADIK_SVA_INIT_MEM + default "4" + help + For use cases having large memory requirements choosing a + larger memory size is advised. + +config NOMADIK_SVA_VPIP + bool "NOMADIK SVA VPIP support" + default y + help + This enables the support for VPIP in SVA driver. This allows to + create IRP services in SVA to grab the images from sensor CCP0. + Warning: This disables Ethernet & MTD devices. + +config NOMADIK_SAA_INIT_MEM + bool "NOMADIK SAA MEMORY at initialisation" + default n + help + The SAA driver uses physically contiguous memory allocated + at kernel initialisation time. + If unsure say N here. + +#Configuration for default display setup +choice + prompt "Default Display Type" + depends on FB + default FB_NOMADIK_QVGA_PORTRAIT + +config FB_NOMADIK_VGA + bool "CLCD VGA" + +config FB_NOMADIK_CRT + bool "CRT VGA" + +config FB_NOMADIK_QVGA_PORTRAIT + bool "CLCD QVGA Portrait" + +config FB_NOMADIK_QVGA_LANDSCAPE + bool "CLCD QVGA Landscape" + +config FB_NOMADIK_WVGA + bool "CLCD WVGA" +endchoice + +choice + prompt "Default Display BPP" + depends on FB + default FB_NOMADIK_PANEL_24BPP_PACKED + +config FB_NOMADIK_PANEL_8BPP + bool "8 BPP" + +config FB_NOMADIK_PANEL_16BPP + bool "16 BPP" + +config FB_NOMADIK_PANEL_24BPP + bool "24 BPP" + +config FB_NOMADIK_PANEL_24BPP_PACKED + bool "24 BPP Packed" + +endchoice + +config FB_NOMADIK_ACCLN + bool "Nomadik Graphics Acceleration" + tristate + depends on FB + default y + help + enable hw accln for graphics on nomadik + +config FB_NOMADIK_PANEL_BPP + int + default 16 if !FB + default 8 if FB_NOMADIK_PANEL_8BPP + default 16 if FB_NOMADIK_PANEL_16BPP + default 24 if FB_NOMADIK_PANEL_24BPP_PACKED + default 32 if FB_NOMADIK_PANEL_24BPP + +config FB_NOMADIK_PANEL_NAME + string + default "VGA" if !FB + default "VGA" if FB_NOMADIK_VGA + default "CRT" if FB_NOMADIK_CRT + default "QVGA_Portrait" if FB_NOMADIK_QVGA_PORTRAIT + default "QVGA_Landscape" if FB_NOMADIK_QVGA_LANDSCAPE + default "WVGA" if FB_NOMADIK_WVGA + +config FB_NOMADIK_PANEL_XRES + int + default 800 if FB_NOMADIK_WVGA + default 640 if !FB + default 640 if ( FB_NOMADIK_VGA || FB_NOMADIK_CRT) + default 240 if FB_NOMADIK_QVGA_PORTRAIT + default 320 if FB_NOMADIK_QVGA_LANDSCAPE + +config FB_NOMADIK_PANEL_YRES + int + default 480 if !FB + default 480 if ( FB_NOMADIK_VGA || FB_NOMADIK_CRT || FB_NOMADIK_WVGA) + default 320 if FB_NOMADIK_QVGA_PORTRAIT + default 240 if FB_NOMADIK_QVGA_LANDSCAPE + +config FB_NOMADIK_PANEL_LFMARGIN + hex + default 0xD6 if FB_NOMADIK_WVGA + default 0x21 if !FB + default 0x21 if FB_NOMADIK_VGA + default 0x29 if FB_NOMADIK_CRT + default 0x13 if (FB_NOMADIK_QVGA_PORTRAIT || FB_NOMADIK_QVGA_LANDSCAPE) + +config FB_NOMADIK_PANEL_RTMARGIN + hex + default 0x27 if FB_NOMADIK_WVGA + default 0x40 if !FB + default 0x40 if FB_NOMADIK_VGA + default 0x09 if FB_NOMADIK_CRT + default 0x2f if (FB_NOMADIK_QVGA_PORTRAIT || FB_NOMADIK_QVGA_LANDSCAPE) + +config FB_NOMADIK_PANEL_UPRMARGIN + hex + default 0x22 if FB_NOMADIK_WVGA + default 0x07 if !FB + default 0x07 if FB_NOMADIK_VGA + default 0x19 if FB_NOMADIK_CRT + default 0x04 if (FB_NOMADIK_QVGA_PORTRAIT || FB_NOMADIK_QVGA_LANDSCAPE) + +config FB_NOMADIK_PANEL_LWRMARGIN + hex + default 0xA if FB_NOMADIK_WVGA + default 0x24 if !FB + default 0x24 if FB_NOMADIK_VGA + default 0x02 if FB_NOMADIK_CRT + default 0x0f if (FB_NOMADIK_QVGA_PORTRAIT || FB_NOMADIK_QVGA_LANDSCAPE) + +config FB_NOMADIK_PANEL_HSLEN + hex + default 0x1 if FB_NOMADIK_WVGA + default 0x40 if !FB + default 0x40 if FB_NOMADIK_VGA + default 0x61 if FB_NOMADIK_CRT + default 0x13 if (FB_NOMADIK_QVGA_PORTRAIT || FB_NOMADIK_QVGA_LANDSCAPE) + +config FB_NOMADIK_PANEL_VSLEN + hex + default 0x1 if FB_NOMADIK_WVGA + default 0x19 if !FB + default 0x19 if FB_NOMADIK_VGA + default 0x02 if FB_NOMADIK_CRT + default 0x04 if (FB_NOMADIK_QVGA_PORTRAIT || FB_NOMADIK_QVGA_LANDSCAPE) + +config FB_NOMADIK_PANEL_TIM2VAL + hex + default 0x031f1822 if FB_NOMADIK_WVGA + default 0x027f1800 if !FB + default 0x027f1800 if (FB_NOMADIK_VGA) + default 0x027f3800 if (FB_NOMADIK_CRT) + default 0x00ef1804 if (FB_NOMADIK_QVGA_PORTRAIT || FB_NOMADIK_QVGA_LANDSCAPE) +#Configuration for default display setup ends here + +endif --- /dev/null +++ linux-2.6.20/arch/arm/mach-nomadik/Makefile @@ -0,0 +1,166 @@ +# +# Makefile for the linux kernel. +# + +ifeq ($(wildcard $(TOPDIR)/.config), $(TOPDIR)/.config) +include $(TOPDIR)/.config +endif + +# Object file lists. + +TARGET_NAME = $(shell echo $(CONFIG_NOMADIK_TARGET)) +SOC_NAME = $(shell echo $(CONFIG_NOMADIK_SOC)) +PLATFORM_NAME = $(shell echo $(CONFIG_NOMADIK_PLATFORM)) +NMDK_EXTRA_CFLAGS = $(shell echo $(CONFIG_NOMADIK_TARGET_EXTRA_CFLAGS)) + +EXTRA_CFLAGS-y := $(NMDK_EXTRA_CFLAGS) +EXTRA_CFLAGS-$(CONFIG_NOMADIK_MTU) += -DCONFIG_MTU0 +CFLAGS += $(EXTRA_CFLAGS-y) + +# NMDKDBG_FLAGS maintainence for all Nomadik debuging strategy +# Add new entry for new component to be supported here +NMDKDBG_FLAGS := + +ifdef VIC_DEBUG +NMDKDBG_FLAGS += -DVIC_DEBUG=$(VIC_DEBUG) +endif + +ifdef RTC_DEBUG +NMDKDBG_FLAGS += -DRTC_DEBUG=$(RTC_DEBUG) +endif + +ifdef GPIO_DEBUG +NMDKDBG_FLAGS += -DGPIO_DEBUG=$(GPIO_DEBUG) +endif + +ifdef DMA_DEBUG +NMDKDBG_FLAGS += -DDMA_DEBUG=$(DMA_DEBUG) +endif + +ifdef EPIO_DEBUG +NMDKDBG_FLAGS += -DEPIO_DEBUG=$(EPIO_DEBUG) +endif + +ifdef SPI_DEBUG +NMDKDBG_FLAGS += -DSPI_DEBUG=$(SPI_DEBUG) +endif + +ifdef SSP_DEBUG +NMDKDBG_FLAGS += -DSSP_DEBUG=$(SSP_DEBUG) +endif + +ifdef MSP_DEBUG +NMDKDBG_FLAGS += -DMSP_DEBUG=$(MSP_DEBUG) +endif + +ifdef KEYPAD_DEBUG +NMDKDBG_FLAGS += -DKEYPAD_DEBUG=$(KEYPAD_DEBUG) +endif + +ifdef TOUCHP_DEBUG +NMDKDBG_FLAGS += -DTOUCHP_DEBUG=$(TOUCHP_DEBUG) +endif + +ifdef POWER_DEBUG +NMDKDBG_FLAGS += -DPOWER_DEBUG=$(POWER_DEBUG) +endif + +ifdef PM_DEBUG +NMDKDBG_FLAGS += -DPM_DEBUG=$(PM_DEBUG) +endif + +ifdef CPUFREQ_DEBUG +NMDKDBG_FLAGS += -DCPUFREQ_DEBUG=$(CPUFREQ_DEBUG) +endif + +ifdef SLEEP_DEBUG +NMDKDBG_FLAGS += -DSLEEP_DEBUG=$(SLEEP_DEBUG) +endif + +ifdef SVA_DEBUG +NMDKDBG_FLAGS += -DSVA_DEBUG=$(SVA_DEBUG) +endif +#export the nomadik debug flags for driver/* build +CFLAGS += $(NMDKDBG_FLAGS) + +obj-y := gpio.o clock.o timer.o irq.o fsmc.o + +obj-y += $(SOC_NAME)_devices.o +obj-y += $(PLATFORM_NAME)_devices.o + +# Soc Specific modules + +obj-$(CONFIG_NOMADIK_PM) += sleep.o deep_sleep.o soft_sleep.o normal.o slow.o pm.o + +ifeq ($(CONFIG_NOMADIK_PM),y) +obj-y += power.o +endif + +ifeq ($(CONFIG_L2CACHE_ENABLE),y) +obj-y += l2cc.o +endif +ifeq ($(CONFIG_CPU_FREQ_NOMADIK),y) +obj-y += power.o slow.o +endif + +obj-$(CONFIG_CPU_FREQ_NOMADIK) += cpu.o dfs.o +obj-$(CONFIG_NOMADIK_DMA) += nmdkmod_DMA.o +obj-$(CONFIG_NOMADIK_SSP) += nmdkmod_ssp.o +obj-$(CONFIG_NOMADIK_MSP) += nmdkmod_msp.o +obj-$(CONFIG_NOMADIK_MTU) += nmdkmod_mtu.o +obj-$(CONFIG_NOMADIK_RTC) += nmdkmod_rtc.o + +nmdkmod_gpio-objs := gpio.o +nmdkmod_DMA-objs := dma.o +nmdkmod_ssp-objs := ssp.o +nmdkmod_msp-objs := msp.o +nmdkmod_mtu-objs := mtu.o +nmdkmod_rtc-objs := rtc.o + +# Auto board configuration/dependency resolution +#include $(TOPDIR)/.config + +SOC_HEADER = include/asm-arm/arch-nomadik/soc_devices.h +PDEV_HEADER = include/asm-arm/arch-nomadik/board_devices.h + +$(TOPDIR)/.platform: + $(Q)echo "Generating $@" + $(Q)echo $(CONFIG_NOMADIK_PLATFORM) > $@ + +$(TOPDIR)/.soc: + $(Q)echo "Generating $@" + $(Q)echo $(CONFIG_NOMADIK_SOC) > $@ + +$(TOPDIR)/.target: + $(Q)echo "Generating $@" + $(Q)echo $(CONFIG_NOMADIK_TARGET) > $@ + +$(TOPDIR)/$(PDEV_HEADER): + $(Q)echo "Generating SYMLINK $(PDEV_HEADER) -> $(PLATFORM_NAME)_devices.h" + $(Q)rm -rf $@ + $(Q)ln -s $(PLATFORM_NAME)_devices.h $@ + +$(TOPDIR)/$(SOC_HEADER): + $(Q)echo "Generating SYMLINK $(SOC_HEADER) -> $(SOC_NAME)_devices.h" + $(Q)rm -rf $@ + $(Q)ln -s $(SOC_NAME)_devices.h $@ + +# machprepare kjhsdk dfsdf +machprepare: $(TOPDIR)/.platform $(TOPDIR)/.soc $(TOPDIR)/.target $(TOPDIR)/$(PDEV_HEADER) $(TOPDIR)/$(SOC_HEADER) + +# machprepare kjhsdk j +machclean: + $(Q)rm -rf *mod.o *.mod.c *.o *.ko + +machmrproper: + $(Q)rm -rf $(TOPDIR)/$(SOC_HEADER) $(TOPDIR)/$(PDEV_HEADER) $(TOPDIR)/arch/arm/mach-nomadik/Kconfig $(TOPDIR)/.soc $(TOPDIR)/.target $(TOPDIR)/.platform + +#This will resolve any machin specific dependency for configuration +#This will generate Kconfig file if not present +machconfig: +ifneq ($(wildcard $(TOPDIR)/arch/arm/mach-nomadik/Kconfig), $(TOPDIR)/arch/arm/mach-nomadik/Kconfig) + @echo "Generating $(TOPDIR)/arch/arm/mach-nomadik/Kconfig" + @./create_kconfig.pl $(TOPDIR)/arch/arm/mach-nomadik +endif + +# end of Auto board configuration/dependency resolution --- /dev/null +++ linux-2.6.20/arch/arm/mach-nomadik/Makefile.boot @@ -0,0 +1,4 @@ + zreladdr-y := 0x00008000 +params_phys-y := 0x00000100 +initrd_phys-y := 0x00800000 + --- /dev/null +++ linux-2.6.20/arch/arm/mach-nomadik/clock.c @@ -0,0 +1,127 @@ +/* + * linux/arch/arm/mach-nomadik/clock.c + * + * Copyright (C) 2004 ARM Limited. + * Written by Deep Blue Solutions Limited. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include "clock.h" + +static LIST_HEAD(clocks); +static DEFINE_MUTEX(clocks_mutex); + +struct clk *clk_get(struct device *dev, const char *id) +{ + struct clk *p, *clk = ERR_PTR(-ENOENT); + + mutex_lock(&clocks_mutex); + list_for_each_entry(p, &clocks, node) { + if (strcmp(id, p->name) == 0 && try_module_get(p->owner)) { + clk = p; + break; + } + } + mutex_unlock(&clocks_mutex); + + return clk; +} + +EXPORT_SYMBOL(clk_get); + +void clk_put(struct clk *clk) +{ + module_put(clk->owner); +} + +EXPORT_SYMBOL(clk_put); + +int clk_enable(struct clk *clk) +{ + return 0; +} + +EXPORT_SYMBOL(clk_enable); + +void clk_disable(struct clk *clk) +{ +} + +EXPORT_SYMBOL(clk_disable); + +unsigned long clk_get_rate(struct clk *clk) +{ + return clk->rate; +} + +EXPORT_SYMBOL(clk_get_rate); + +long clk_round_rate(struct clk *clk, unsigned long rate) +{ + return 0; +} + +EXPORT_SYMBOL(clk_round_rate); + +int clk_set_rate(struct clk *clk, unsigned long rate) +{ + clk->rate = rate; + return 0; +} + +EXPORT_SYMBOL(clk_set_rate); + +/* + * These are fixed clocks. + */ + +static struct clk uart_clk = { + .name = "UARTCLK", + .rate = 48000000, +}; + +static struct clk clcd_clk = { + .name = "CLCDCLK", + .rate = 48000000, +}; + +int clk_register(struct clk *clk) +{ + mutex_lock(&clocks_mutex); + list_add(&clk->node, &clocks); + mutex_unlock(&clocks_mutex); + return 0; +} + +EXPORT_SYMBOL(clk_register); + +void clk_unregister(struct clk *clk) +{ + mutex_lock(&clocks_mutex); + list_del(&clk->node); + mutex_unlock(&clocks_mutex); +} + +EXPORT_SYMBOL(clk_unregister); + +static int __init clk_init(void) +{ + clk_register(&uart_clk); + clk_register(&clcd_clk); + return 0; +} + +arch_initcall(clk_init); --- /dev/null +++ linux-2.6.20/arch/arm/mach-nomadik/clock.h @@ -0,0 +1,25 @@ +/* + * linux/arch/arm/mach-nomadik/clock.h + * + * Copyright (C) 2004 ARM Limited. + * Written by Deep Blue Solutions Limited. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +struct module; +struct icst525_params; + +struct clk { + struct list_head node; + unsigned long rate; + struct module *owner; + const char *name; + const struct icst525_params *params; + void *data; + void (*setvco)(struct clk *, struct icst525_vco vco); +}; + +int clk_register(struct clk *clk); +void clk_unregister(struct clk *clk); --- /dev/null +++ linux-2.6.20/arch/arm/mach-nomadik/cpu.c @@ -0,0 +1,293 @@ +/* + * linux/arch/arm/mach-nomadik/cpu.c + * + * Copyright (C) STMicroelectronics + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * CPU freq driver + */ +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +#define CPUFREQ_NAME "CPUFREQ" + +#ifndef CPUFREQ_DEBUG +#define CPUFREQ_DEBUG 0 +#endif + +#define NMDK_DEBUG CPUFREQ_DEBUG /* enables/disables nmdk_dbg msgs */ +#define NMDK_DEBUG_PFX CPUFREQ_NAME /* msg header represents this module */ +#define NMDK_DBG KERN_ERR /* message level */ + + +#define PLL1_CRYSTAL_FREQ_KHZ (192 * 100) +#define CALC_FREQ(pll1_nmul, pll1_pdiv) (PLL1_CRYSTAL_FREQ_KHZ * (pll1_nmul + 2)) / (1 << pll1_pdiv); + +static struct cpufreq_driver nomadik_driver; +static unsigned int nomadik_get(unsigned int cpu); + +extern unsigned int nomadik_freq_to_idx(unsigned int freq); +extern unsigned int nomadik_idx_to_freq(unsigned int idx); +extern u32 nomadik_setsys_freq(u32 freq_idx); + +/* + * Validate the speed policy. + */ +static int nomadik_verify_policy(struct cpufreq_policy *policy) +{ + + nmdk_dbg_ftrace(); + cpufreq_verify_within_limits(policy, + policy->cpuinfo.min_freq, + policy->cpuinfo.max_freq); + + policy->min = NOMADIK_CPUFREQ_MIN; + policy->max = NOMADIK_CPUFREQ_MAX; + + cpufreq_verify_within_limits(policy, + policy->cpuinfo.min_freq, + policy->cpuinfo.max_freq); + + return 0; +} + +static int nomadik_set_target(struct cpufreq_policy *policy, + unsigned int target_freq, unsigned int relation) +{ + cpumask_t cpus_allowed; + int cpu = policy->cpu; + struct cpufreq_freqs freqs; + unsigned int freq_idx; + unsigned int new_voltage, cur_voltage; + unsigned char vcore_data; + int result; + + nmdk_dbg2("%s called with target_freq = %d relation = %d\n", + (__FUNCTION__), target_freq, relation); + /* + * Save this threads cpus_allowed mask. + */ + cpus_allowed = current->cpus_allowed; + + /* + * Bind to the specified CPU. When this call returns, + * we should be running on the right CPU. + */ + set_cpus_allowed(current, cpumask_of_cpu(cpu)); + BUG_ON(cpu != smp_processor_id()); + + freqs.old = nomadik_get(policy->cpu); + + freq_idx = nomadik_freq_to_idx(target_freq); + + switch (relation) { + case CPUFREQ_RELATION_L: + if (nomadik_idx_to_freq(freq_idx) > policy->max) + freq_idx--; + break; + case CPUFREQ_RELATION_H: + if ((nomadik_idx_to_freq(freq_idx) > target_freq) && + (nomadik_idx_to_freq(freq_idx - 1) >= policy->min)) + freq_idx--; + break; + } + + freqs.new = nomadik_idx_to_freq(freq_idx); + freqs.cpu = policy->cpu; + + nmdk_dbg2(" freqs.new = %d\n", freqs.new); + if (freqs.old == freqs.new) { + set_cpus_allowed(current, cpus_allowed); + return 0; + } + +#if 0 + if ( freq_idx == 0) + { + nomadik_normal_to_slow = 1; + nomadik_slow_to_normal = 0; + } + if (freqs.old == 19200 ) + { + nomadik_slow_to_normal = 1; + nomadik_normal_to_slow = 0; + + } +#endif + + cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); + + new_voltage = nomadik_freq_to_voltage(freqs.new); + cur_voltage = g_nomadik_voltage; + nmdk_dbg2(" new voltage = %d\n", new_voltage); + nmdk_dbg2(" old voltage = %d\n", cur_voltage); + + if (new_voltage > cur_voltage) { + + vcore_data = new_voltage; + + result = + nomadik_i2c_write_register(I2C_TOUAREG_CLIENT, &vcore_data, + 0x1E, 1); + if (unlikely(result)) { + nmdk_error("i2c write error with ret = %d\n", result); + goto err1; + + } else + nmdk_dbg2("i2c write vcore_data = 0x%x\n", vcore_data); + +#ifdef CPUFREQ_DEBUG + vcore_data = 0; + + result = + nomadik_i2c_read_register(I2C_TOUAREG_CLIENT, &vcore_data, + 0x1E, 1); + if (unlikely(result)) { + nmdk_error("i2c read error with ret = %d\n", result); + goto err1; + + } else + nmdk_dbg2("i2c read vcore_data = 0x%x\n", vcore_data); + + if ( vcore_data != new_voltage ) + { + printk("i2c had not written correctly\n"); + goto err1; + } +#endif + g_nomadik_voltage = new_voltage; + } + + nomadik_setsys_freq(freq_idx); + + if (new_voltage < cur_voltage) { + + vcore_data = new_voltage; + result = + nomadik_i2c_write_register(I2C_TOUAREG_CLIENT, &vcore_data, + 0x1E, 1); + /** + * Here even if we are not able to set lower voltage. Still system can + * work with previous voltage + */ + + if (unlikely(result)) { + nmdk_error("i2c write error with ret = %d\n", result); + goto err1; + + } else + nmdk_dbg2("i2c write vcore_data = 0x%x\n", vcore_data); + g_nomadik_voltage = new_voltage; + + } + + err1: + + /* + * Restore the CPUs allowed mask. + */ + set_cpus_allowed(current, cpus_allowed); + + cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); +#if CPUFREQ_DEBUG + { + int j; + for(j=0; j <= 0x124; j+=4) + printk("sdmc[%x] = %x\n", j, readl(0xf0110000 + j )); + } +#endif + + return 0; +} + +#define SRC_PLL_FREQ_OFFSET 0x14 +static unsigned int nomadik_get(unsigned int cpu) +{ + cpumask_t cpus_allowed; + unsigned int current_freq; + unsigned char __iomem *src_base; + unsigned long pll_reg; + unsigned int pll1_nmul, pll1_pdiv; + + nmdk_dbg_ftrace(); + cpus_allowed = current->cpus_allowed; + + set_cpus_allowed(current, cpumask_of_cpu(cpu)); + BUG_ON(cpu != smp_processor_id()); + src_base = (unsigned char *)IO_ADDRESS(NOMADIK_SRC_BASE); + if ( ( readl(src_base) & 0x78 ) == 0x20 ) + { + pll_reg = readl(src_base + SRC_PLL_FREQ_OFFSET); + pll1_pdiv = pll_reg & 0x7; + pll1_nmul = (pll_reg >> 8) & 0x3f; + current_freq = CALC_FREQ(pll1_nmul, pll1_pdiv); + } + else + current_freq = NOMADIK_CPUFREQ_MIN; + + set_cpus_allowed(current, cpus_allowed); + nmdk_dbg2("Current_freq = %d\n", current_freq); + nmdk_dbg2("pll1_nmul = 0x%x pll1_pdiv = 0x%x\n", pll1_nmul, pll1_pdiv); + + g_nomadik_voltage = nomadik_freq_to_voltage(current_freq); + nmdk_dbg2("g_nomadik_voltage = %x\n", g_nomadik_voltage); + return current_freq; +} + +static int nomadik_cpufreq_init(struct cpufreq_policy *policy) +{ + + /* set default policy and cpuinfo */ + policy->governor = CPUFREQ_DEFAULT_GOVERNOR; + policy->cpuinfo.max_freq = NOMADIK_CPUFREQ_MAX; + policy->cpuinfo.min_freq = NOMADIK_CPUFREQ_MIN; + policy->cpuinfo.transition_latency = NOMADIK_CPUFREQ_TRANS_LATENCY; + policy->cur = policy->min = policy->max = nomadik_get(policy->cpu); + nmdk_dbg2("max cpu freq = %d min cpu freq = %d\n", NOMADIK_CPUFREQ_MAX, + NOMADIK_CPUFREQ_MIN); + + return 0; +} + +static struct cpufreq_driver nomadik_driver = { + .verify = nomadik_verify_policy, + .target = nomadik_set_target, + .get = nomadik_get, + .init = nomadik_cpufreq_init, + .name = "nomadik-cpufreq", +}; + +static int __init nomadik_cpu_init(void) +{ + return cpufreq_register_driver(&nomadik_driver); +} + +static void __exit nomadik_cpu_exit(void) +{ + cpufreq_unregister_driver(&nomadik_driver); +} + +MODULE_AUTHOR("Manish Rathi"); +MODULE_DESCRIPTION("cpufreq driver for ARM Nomadik CPUs"); +MODULE_LICENSE("GPL"); + +module_init(nomadik_cpu_init); +module_exit(nomadik_cpu_exit); --- /dev/null +++ linux-2.6.20/arch/arm/mach-nomadik/create_kconfig.pl @@ -0,0 +1,55 @@ +#! /usr/bin/perl +# +# gen_nomadik_kconfig.pl: Generates Kconfig in arch/arm/mach-nomadik/ considering all board specific Kconfig files. + +$VAR=@ARGV; +if (@ARGV != 1) +{ + print "Usage: ./create_kconfig.pl \n"; + print "example: ./create_kconfig.pl arch/arm/mach-nomadik\n"; + exit(1); +} + +$KPATH=@ARGV[0]; + +@temp=split(/mach-/, $KPATH); +@temp1=split(/\//, @temp[1]); +$mach=@temp1[0]; +$machuc=uc($mach); + +if ( -e "$KPATH/Kconfig" ) { + exit(0); +} + +open (KCONFIG, "> $KPATH/Kconfig") || die "Can't open file: $!"; +$Kconfig_data="# Automatically generated Kconfig: don't edit\n# To add new board support create $KPATH/_Kconfig file\n\nif ARCH_$machuc\n\nchoice\n\nprompt \"$mach target board\"\n\n"; +print KCONFIG $Kconfig_data; + +@filenames =qx(ls $KPATH/*_Kconfig); +foreach $filename(@filenames) + { + @temp=split(/mach-$mach\//, $filename); + @temp1=split(/_Kconfig/, @temp[1]); + $filename=@temp1[0]; + chomp($filename); + $filenameuc=uc($filename); + $usc="_"; + print KCONFIG "config $machuc$usc$filenameuc\n\tbool \"$filename\"\n\thelp\n\t\tSupprots $filename target board for $mach platform\n\n"; + }; + +print KCONFIG "endchoice\n\n"; + +@filenames =qx(ls $KPATH/*_Kconfig); +foreach $filename(@filenames) + { + chomp($filename); + print KCONFIG "source \"$filename\"\n\n"; + }; + +if ( -e "$KPATH/Kconfig-$mach" ) { + print KCONFIG "source \"$KPATH/Kconfig-$mach\"\n"; +} + +print KCONFIG "endif\n\n"; +close KCONFIG; + --- /dev/null +++ linux-2.6.20/arch/arm/mach-nomadik/deep_sleep.S @@ -0,0 +1,655 @@ +/* + * arch/arm/mach-nomadik/deep_sleep.S + * + * Copyright 2007, STMicroelectronics + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include +#include + +.global nomadik_deep_sleep +.extern L2dummyPointer + +nomadik_deep_sleep: + /*Store all the general purpose registers along with the link register*/ + stmfd sp!,{r0-r12,lr} + + /* save the first parameter passed to function nomadik_deep_sleep to r12*/ + mov r12,r0 + + /* save the second parameter passed to function nomadik_deep_sleep to the variable addr - mpmc_base*/ + ldr r11, =mpmc_base + str r1,[r11] + + /* save the third parameter passed to function nomadik_deep_sleep to the variable addr - backup_ram_base */ + ldr r11, =backup_ram_base + str r2,[r11] + + + + ldr r11, =backup_ram_store + mov r10,#0x250 + add r10, r2, r10 + str r10, [r11, #0x0] + +#ifdef DEEP_SLEEP_DEBUG + /*Clean entire DCache using test and clean*/ +clean_dcache_start: + mrc p15,0,r15,c7,c14,3 + bne clean_dcache_start + + /* Invalidate I cache and Dcache */ + mov r0,#0 + mcr p15,0,r0,c7,c7,0 + + /*Drain Write Buffers*/ + mov r0,#0 + mcr p15,0,r0,c7,c10,4 +#endif + + /* Storing the enabled values of VIC */ + ldr r0, =vic_base + ldr r0, [r0,#0x0] + + ldr r1, [r0,#0xC] /* Interrupt sslection register */ + ldr r2, [r0, #0x2C] + ldr r3, [r0, #0x10] /* Interrupt Enable register */ + ldr r4, [r0, #0x30] + ldr r5, [r0, #0x54] /* Default VAR */ + stmfd sp!, {r1-r5} + + + + ldr r1,[r0,#0x100] + ldr r2,[r0,#0x104] + ldr r3,[r0,#0x108] + ldr r4,[r0,#0x10C] + ldr r5,[r0,#0x110] + ldr r6,[r0,#0x114] + ldr r7,[r0,#0x118] + ldr r8,[r0,#0x11C] + ldr r9,[r0,#0x120] + ldr r10,[r0,#0x124] + ldr r11,[r0,#0x128] + stmfd sp!,{r1-r11} + + ldr r1,[r0,#0x12C] + ldr r2,[r0,#0x130] + ldr r3,[r0,#0x134] + ldr r4,[r0,#0x138] + ldr r5,[r0,#0x13C] + ldr r6,[r0,#0x200] + ldr r7,[r0,#0x204] + ldr r8,[r0,#0x208] + ldr r9,[r0,#0x20C] + ldr r10,[r0,#0x210] + ldr r11,[r0,#0x214] + stmfd sp!,{r1-r11} + + + ldr r1,[r0,#0x218] + ldr r2,[r0,#0x21C] + ldr r3,[r0,#0x220] + ldr r4,[r0,#0x224] + ldr r5,[r0,#0x228] + ldr r6,[r0,#0x22C] + ldr r7,[r0,#0x230] + ldr r8,[r0,#0x234] + ldr r9,[r0,#0x238] + ldr r10,[r0,#0x23C] + stmfd sp!,{r1-r10} + + + + + + mrc p15,0, r0,c5,c0,0 /* FSR--Domain Fault */ + mrc p15,0, r1,c5,c0,1 /* FSR--Instruction Fault */ + + mrc p15,0, r2,c6,c0,0 /* FAR */ + + mrc p15,0, r3,c9,c0,0 /* Read Dcache Lockdown */ + mrc p15,0, r4,c9,c0,1 /* Read ICache Lockdown */ + + mrc p15,0, r5,c9,c1,0 /* Read Data TLB */ + mrc p15,0, r6,c9,c1,1 /* Read Instruction TCM region register */ + + mrc p15,0, r7,c10,c0,0 /* Data TLB LockDown operation */ + + mrc p15,0, r8,c13,c0,0 /* FCSE--PID */ + mrc p15,0, r9,c13,c0,1 /* Context-ID */ + + /* Save all these registers onto the stack */ + stmfd sp!, {r0-r9} + + /*Move sp to non banked register. sp is not shared in banked modes.*/ + mov r6, sp + + /* Store the two user mode registers*/ + sub r6,r6,#0x8 + stmia r6, {sp, lr}^ + mov r0,r0 + + /* Save current mode with interrupts disabled*/ + mrs r7, cpsr + stmfd r6!, {r7} + bic r7,r7,#0xf + + /* move the first par from r12 to r3 */ + mov r3,r12 + + /** Following are the registers that are used + R6:- Stack Pointer + R7:- CPSR Value [IRQ Disabled , FIQ Disabled, Mode bit Cleared] + R8:- Virtual Address of Backup SRAM (0xA0010250) + R9:- UART1 Base Register [Debug Device Base Register] + R10:- MPMC Base Register + R11:- SRC Base Register + R12:- PMU Base Register + */ + + ldr r8,=backup_ram_store + ldr r8, [r8,#0] + + ldr r9,=uart1_base + ldr r9, [r9,#0] + + ldr r10,=mpmc_base + ldr r10, [r10,#0] + + ldr r11,=src_base + ldr r11, [r11,#0] + + ldr r12,=pmu_base + ldr r12, [r12,#0] + + /*Store the jump back address at this location (physical Address) */ + ldr r0, =backup_ram_base + ldr r0, [r0,#0] + + ldr r1, =after_deep_sleep + mov r2, #0xC0000000 + sub r1, r1, r2 /* Change from VA to PA */ + + str r1, [r0] + + /*Enter FIQ mode-Interrupt disabled and save the banked registers*/ + orr r0,r7,#0x1 + msr cpsr_cxsf,r0 + + mrs r0,spsr + stmfd r6!, {r0,r8-r14} /* store r8 to r14 and spsr */ + + /*Enter IRQ mode-Interrupt disabled Save: r13,r14 and spsr*/ + orr r0,r7,#0x2 + msr cpsr_cxsf,r0 /* enter IRQ mode with IRQ/FIQ disable */ + + mrs r0,spsr + stmfd r6!, {r0,r13,r14} + + + /*Enter Abort mode-IRQ/FIQ disable. Save r13,r14 and spsr */ + orr r0,r7,#0x7 + msr cpsr_cxsf,r0 + + mrs r0,spsr + stmfd r6!, {r0,r13,r14} + + + /*Enter Undef Mode-IRQ/FIQ disable. Save r13,r14 and spsr */ + orr r0,r7,#0xB + msr cpsr_cxsf,r0 + + mrs r0,spsr + stmfd r6!, {r0,r13,r14} + + + /*Store the top of stack [VA] in the Scratch-Pad Register*/ + str r6,[r12,#0x14] + + /*Go back in SVC mode*/ + orr r0,r7,#0x3 + msr cpsr_cxsf,r0 + + /* Store MMU registers */ + /*Domain Register on Back-up RAM structure*/ + mrc p15,0,r0,c3,c0,0 + str r0,[r8] + + /*TTB Register*/ + mrc p15,0,r0,c2,c0,0 + str r0,[r8,#0x4] + + /*MMU Enable Register*/ + mrc p15,0,r0,c1,c0,0 + str r0,[r8,#0x8] + + /* Virtual Address of MMU Enable*/ + adr r0,mmu_enabled + str r0,[r8,#0xC] + + + /*Clear the Remap bit from SRC-Register*/ + ldr r0,[r11] + bic r0,r0,#0x100 + str r0,[r11] + + /*Enable the Mode Status Register*/ + mov r0,#0 + str r0,[r11,#0x8] + + /* Clear the PMU bit - for entering the deep sleep mode instead sleep*/ + ldr r0,[r12] + bic r0,r0,#0x10 + str r0,[r12] + + /*Store the value of Scratch-Pad Register*/ + ldr r0,=backup_ram_base_phys + ldr r0,[r0,#0x0] + str r0,[r12,#0x10] + + /*Program to wake-up in Normal mode*/ + ldr r0,[r11,#0x4] + bic r0,r0,#0xf + orr r0,r0,#0x9 + str r0,[r11,#0x4] + + /*Clean entire DCache using test and clean*/ +clean_dcache: + mrc p15,0,r15,c7,c10,3 + bne clean_dcache + + /*Drain Write Buffers*/ + mov r0,#0 + mcr p15,0,r0,c7,c10,4 + + ldr r0, =L2dummyPointer + ldr r0, [r0] + mov r1, #0 + cmp r1, r0 + stmneia r0!,{r1-r8} + +#ifdef CONFIG_L2CACHE_ENABLE + v_l2_cache_clean_and_invalidate r0, r1 + v_l2_cache_sync r0, r1 + v_l2_cache_disable r0,r1 + +#endif + + + /* Prefetch certain instructions in the cache. */ + adr r4, cache_prefetch_start + adr r5, cache_prefetch_end + mvn r1,#0x1F + ands r4,r1,r4 +fetch_loop: + mcr p15, 0, r4, c7, c13,1 + cmp r4,r5 + addls r4, r4, #0x20 + bls fetch_loop + + +cache_prefetch_start: + ldr r10, =mpmc_base + ldr r10,[r10,#0x0] + +/* Check sdram is idle */ +poll_loop: + ldr r1,[r10, #0x4] + ands r1,r1,#0x1 + cmp r1,#0 + bne poll_loop + + /*Put SDRAM in self-refresh mode*/ + ldr r1,[r10, #0x20] + bic r1,r1,#0x1 + orr r1,r1,#0x04 + str r1,[r10, #0x20] + + /*Wait for SDRAM to go in self-refresh*/ +wait: + ldr r1,[r10,#0x4] + and r1,r1,#0x4 + cmp r1,#0x0 + beq wait + + + + + /*Move system to sleep mode*/ + ldr r1,[r11] + bic r1, r1, #0x7 + str r1,[r11] + +goto_sleep: + ldr r1,[r11] + and r1,r1,#0x78 + cmp r1,#0x0 + bne goto_sleep + + + nop + nop + nop + nop + + + + +/* For deepsleep this much pre-fetch is enough */ +cache_prefetch_end: + mov r0, r0 + mov r0, r0 + mov r0, r0 + mov r0, r0 + + +after_deep_sleep: +/* Restore the MMU registers */ + + + + ldr r8,=backup_ram_store_phys + mov r9, #0xC0000000 + sub r8, r8, r9 /* Change from VA to PA */ + ldr r8, [r8,#0] + + + +out_of_sleep: + /*Domain Register*/ + ldr r0,[r8, #0x0] + mcr p15,0,r0,c3,c0,0 + + /*TTB Register*/ + ldr r0,[r8,#0x4] + mcr p15,0,r0,c2,c0,0 + + + /* Virtual Address of mmu_enabled*/ + ldr r4, [r8, #0xC] + + /*MMU Enable Register*/ + ldr r1, [r8,#0x8] + mcr p15,0,r1,c1,c0,0 + + mov pc,r4 + mov r0, r0 + mov r0, r0 + mov r0, r0 + mov r0, r0 + + + +mmu_enabled: + +#ifdef DEEP_SLEEP_DEBUG + ldr r9, =uart1_base + ldr r9, [r9,#0] +#endif + + ldr r11, =src_base + ldr r11, [r11,#0] + ldr r12, =pmu_base + ldr r12, [r12,#0] + ldr r10, =mpmc_base + ldr r10, [r10,#0] + + + + /* Move system to Normal Mode */ + ldr r1,[r11] + orr r1,r1,#0x4 + bic r1,r1,#0x3 + str r1,[r11] + + + /*Wait for the system to move in normal mode*/ +wait_norm1: + ldr r0,[r11, #0x0] + and r0,r0,#0x78 + cmp r0, #0x20 + bne wait_norm1 + + + /* Remove the chip from Interrupt mode */ + ldr r0,[r11, #0x4] + bic r0,r0,#0x1 + str r0,[r11, #0x4] + + /* Clear the interrupt mode status bit*/ + mov r0, #0x0 + str r0, [r11, #0x8] + + /* For CLCD Refresh issue */ + ldr r1, =0x00000005 /* Loading the value with timeout so as to avoid flickering on CLCD */ + str r1, [r10, #0x408] + + + /* Stack Restoration Routine */ + ldr r6,[r12,#0x14] + + /* Store the value of cpsr in r7*/ + mrs r7,cpsr + orr r7,r7,#0xC0 /*Not Needed*/ + bic r7,r7,#0xf + + /*Move to undef mode and restore everything*/ + orr r0,r7,#0xB + msr cpsr_cxsf,r0 + + ldmfd r6!, {r0,r13,r14} + msr spsr_cxsf,r0 + + /*Enter Abort mode-IRQ/FIQ disable. Save r13,r14 and spsr */ + orr r0,r7,#0x7 + msr cpsr_cxsf,r0 + + ldmfd r6!, {r0,r13,r14} + msr spsr_cxsf,r0 + + /*Enter IRQ mode-Interrupt disabled Save: r13,r14 and spsr*/ + orr r0,r7,#0x2 + msr cpsr_cxsf,r0 + + ldmfd r6!, {r0,r13,r14} + msr spsr_cxsf,r0 + + + /*Enter FIQ mode-Interrupt disabled and save the banked registers. Save: r8-r14 and spsr*/ + orr r0,r7,#0x1 + msr cpsr_cxsf,r0 + + ldmfd r6!, {r0,r8-r14} + msr spsr_cxsf,r0 + + /* Here we will restore our cpsr..IRQ/FIQ Disabled*/ + ldr r0, [r6] + msr cpsr_cxsf, r0 + add r6, r6,#4 + + /*Now only two user-mode registers are left*/ + ldmia r6,{sp, lr}^ + mov r0,r0 + add r6,r6,#8 + + /*Restore sp*/ + mov sp,r6 + + + /*ReStore the remaining items*/ + ldmfd sp!, {r0-r9} + + mcr p15,0, r0,c5,c0,0 /*FSR--Domain Fault */ + mcr p15,0, r1,c5,c0,1 /*FSR--Instruction Fault */ + + mcr p15,0, r2,c6,c0,0 /* FAR */ + + mcr p15,0, r3,c9,c0,0 /* Read Dcache Lockdown */ + mcr p15,0, r4,c9,c0,1 /* Read ICache Lockdown */ + + mcr p15,0, r5,c9,c1,0 /* Read Data TLB */ + mcr p15,0, r6,c9,c1,1 /* Read Instruction Lockdown */ + + mcr p15,0, r7,c10,c0,0 /* Data TLB LockDown operation */ + + mcr p15,0, r8,c13,c0,0 /* FCSE--PID */ + mcr p15,0, r9,c13,c0,1 /* Context-ID */ + + + + + + + /* ReStoring the enabled values of VIC */ + ldr r0, =vic_base + ldr r0, [r0,#0] + + ldmfd sp!,{r1-r10} + str r1,[r0,#0x218] + str r2,[r0,#0x21C] + str r3,[r0,#0x220] + str r4,[r0,#0x224] + str r5,[r0,#0x228] + str r6,[r0,#0x22C] + str r7,[r0,#0x230] + str r8,[r0,#0x234] + str r9,[r0,#0x238] + str r10,[r0,#0x23C] + + + ldmfd sp!,{r1-r11} + str r1,[r0,#0x12C] + str r2,[r0,#0x130] + str r3,[r0,#0x134] + str r4,[r0,#0x138] + str r5,[r0,#0x13C] + str r6,[r0,#0x200] + str r7,[r0,#0x204] + str r8,[r0,#0x208] + str r9,[r0,#0x20C] + str r10,[r0,#0x210] + str r11,[r0,#0x214] + + + + ldmfd sp!,{r1-r11} + str r1,[r0,#0x100] + str r2,[r0,#0x104] + str r3,[r0,#0x108] + str r4,[r0,#0x10C] + str r5,[r0,#0x110] + str r6,[r0,#0x114] + str r7,[r0,#0x118] + str r8,[r0,#0x11C] + str r9,[r0,#0x120] + str r10,[r0,#0x124] + str r11,[r0,#0x128] + + ldmfd sp!, {r1-r5} + str r1, [r0,#0xC] /* Interrupt sslection register */ + str r2, [r0, #0x2C] + str r3, [r0, #0x10] /* Interrupt Enable register */ + str r4, [r0, #0x30] + str r5, [r0, #0x54] /* Default VAR */ + + + + /*Clean entire DCache using test and clean*/ +clean_dcache_end: + mrc p15,0,r15,c7,c14,3 + bne clean_dcache_end + + + /* Invalidate I cache and Dcache */ + mov r0,#0 + mcr p15,0,r0,c7,c7,0 + + /*Drain Write Buffers*/ + mov r0,#0 + mcr p15,0,r0,c7,c10,4 + + mov r0,#0 + mcr p15, 0, r0, c8, c7, 0 @ invalidate I & D TLBs + + mov r0,#0 + mov r0,#0 + mov r0,#0 + mov r0,#0 + + +#ifdef DEEP_SLEEP_DEBUG + ldr r0, =uart1_base + ldr r0, [r0,#0x0] + mov r1, #0x65 + str r1, [r0] + mov r1, #0x66 + str r1, [r0] + mov r1, #0x66 + str r1, [r0] + mov r1, #0x66 + str r1, [r0] + mov r1, #0x66 + str r1, [r0] + mov r1, #0x66 + str r1, [r0] + mov r1, #0x66 + str r1, [r0] + mov r1, #0x66 + str r1, [r0] + mov r1, #0x66 + str r1, [r0] + mov r1, #0x66 + str r1, [r0] + mov r1, #0x66 + str r1, [r0] +#endif + + +/*Try to go back also...FIQ Disabled...IRQ Disabled*/ + ldmfd sp!,{r0-r12,pc} + + +uart1_phys: + .word 0x101FB000 +src_phys: + .word 0x101E0000 +backup_ram_store_phys: + .word 0x80010250 +mtu0_base: + .word 0xf01E2000 + +uart1_base: + .word 0xf01FB000 +src_base: + .word 0xf01E0000 +pmu_base: + .word 0xf01E9000 +fsmc_base: + .word 0xf0100000 +backup_ram_base_phys: + .word 0x80010000 +vic_base: + .word 0xf0140000 +mpmc_base: + .word 0xf0110000 +backup_ram_store: + .word 0x80010250 +backup_ram_base: + .word 0x80010000 +.end --- /dev/null +++ linux-2.6.20/arch/arm/mach-nomadik/dfs.S @@ -0,0 +1,355 @@ +/* + * arch/arm/mach-nomadik/sleep.c + * + * Copyright 2007, STMicroelectronics + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Low-level Nomadik DFS support + */ + +.align 5 +.globl dfs + + +dfs: + stmfd sp!,{r4-r12,lr} + + str r3, bkup_adr_base + add r4, r3, #8 + str r4, bkup_adr + add r4, r3, #0x1c8 + str r4, bkup_data + add r4, r3, #0x388 + str r4, bkup_action + add r4, r3, #0x3f8 + str r4, bkup_size + + ldr r9, bkup_size + ldr r9,[r9] + ldr r10,bkup_adr + ldr r11,bkup_data + ldr r12,bkup_action + + mrc p15, 0, r3, c10, c0, 0 /* read the lockdown register */ + orr r3, r3, #1 /* set the preserved bit */ + mcr p15, 0, r3, c10, c0, 0 /* write to the lockdown register */ + + + + + ldr r4, mpmc_base + mcr p15, 0, r4, c8, c7, 1 + ldr r4, [r4] + mrc p15, 0, r3, c10, c0, 0 + + + ldr r4, src_base + mcr p15, 0, r4, c8, c7, 1 + ldr r4, [r4] + mrc p15, 0, r3, c10, c0, 0 + + ldr r4, bkup_adr_base + mcr p15, 0, r4, c8, c7, 1 + ldr r4, [r4] + mrc p15, 0, r3, c10, c0, 0 + + + bic r3, r3, #1 /* clear preserve bit */ + mcr p15, 0, r3, c10, c0, 0 /* write to the lockdown register */ + + ldr r7,mpmc_base + ldr r8,src_base + +/* + mov r7, #0xf0 + lsl r7, #8 + orr r7, r7, #0x11 + lsl r7, #16 + + mov r8, #0xf0 + lsl r8, #8 + orr r8, r8, #0x1e + lsl r8, #16 +*/ + + + /* Prefetch certain instructions in the cache. */ + adr r4, cache_prefetch_start1 + adr r5, cache_prefetch_end1 + mvn r3,#0x1F + ands r4,r3,r4 +fetch_loop: + mcr p15, 0, r4, c7, c13,1 + cmp r4,r5 + addls r4, r4, #0x20 + bls fetch_loop + +mov r0,r0 +mov r0,r0 +mov r0,r0 +mov r0,r0 + + +cache_prefetch_start1: + + /** + *Put SDRAM in self-refresh mode + */ + ldr r3,[r7, #0x20] + orr r3,r3,#0x04 + str r3,[r7, #0x20] + + + /** + *Wait for SDRAM to go in self-refresh + */ +wait_till_selfrefresh : + ldr r3,[r7,#0x4] + and r3,r3,#0x4 + cmp r3,#0x0 + beq wait_till_selfrefresh + + + /** + * Stop the DLL, leave SDMC on + */ + ldr r3,[r7] + bic r3,r3,#0x2 + str r3,[r7] + + /** + *Move the system in Slow mode + */ + ldr r3,[r8] + bic r3,r3,#0x7 + orr r3,r3,#0x2 + str r3,[r8] + +wait_till_slow_mode: + ldr r3,[r8] + and r3,r3,#0x78 + cmp r3,#0x10 + bne wait_till_slow_mode + + ldr r3,[r8] + bic r3,r3,#0x6000 + orr r3,r3,r2,LSL #13 + str r3,[r8] + + ldr r3,[r8,#0x14] + bic r3,r3,#0x3F00 + bic r3,r3,#0x7 + orr r3,r3,r0 + orr r3,r3,r1,LSL #8 + str r3,[r8,#0x14] + + /** + *Move the system in Normal mode + */ + ldr r0,[r8, #0x0] + ldr r1, =0xfffffff8 + and r0,r0,r1 + orr r0,r0,#0x4 + str r0,[r8, #0x0] + +wait_till_normal_mode: + ldr r0,[r8, #0x0] + and r0,r0,#0x78 + cmp r0, #0x20 + bne wait_till_normal_mode + + +#define ACTION_WRITE 0x01 +#define ACTION_WRITE_AND 0x02 +#define ACTION_WRITE_OR 0x03 +#define ACTION_READ 0x04 +#define ACTION_POLL 0x05 +#define ACTION_POLL_AND 0x06 +#define ACTION_POLL_OR 0x07 +#define ACTION_WAIT 0x08 + +/* + ldr r12,bkup_size + ldr r9,[r12] + + ldr r10,bkup_adr + ldr r11,bkup_data + ldr r12,bkup_action +*/ + + + mov r8,#0x0 +loop1: + cmp r8,r9 + beq end1 + + ldr r7,[r10] + ldr r6,[r11] + ldr r5,[r12] + + mov r2,r8 + and r2,r2,#0x3 + mov r2,r2,LSL #0x3 + mov r5,r5,LSR r2 + and r5,r5,#0xFF + + + /** + Decide action to be taken + */ + ldr r4,=ACTION_WRITE + cmp r5,r4 + beq action_write + ldr r4,=ACTION_WRITE_AND + cmp r5,r4 + beq action_write_and + ldr r4,=ACTION_WRITE_OR + cmp r5,r4 + beq action_write_or + ldr r4,=ACTION_READ + cmp r5,r4 + beq action_read + ldr r4,=ACTION_POLL + cmp r5,r4 + beq action_poll + ldr r4,=ACTION_POLL_AND + cmp r5,r4 + beq action_poll_and + ldr r4,=ACTION_POLL_OR + cmp r5,r4 + beq action_poll_or + ldr r4,=ACTION_WAIT + cmp r5,r4 + beq action_wait + b action_end +action_write: +#if 0 + mov r4, #0xf0 + lsl r4, #8 + orr r4, #0x1f + lsl r4, #8 + orr r4, #0xb0 + lsl r4, #8 + + mov r3, #0x73 + str r3, [r4] +#endif + str r6,[r7] + b action_end +action_write_and: + + b action_end +action_write_or: + ldr r3,[r7] + orr r3,r3,r6 + str r3,[r7] + b action_end +action_read: + ldr r3,[r7] + b action_end +action_poll: + b action_end +action_poll_and: + b action_end +action_poll_or: + b action_end +action_wait: + cmp r6,#0x0 + beq action_end + sub r6,r6,#0x1 + b action_wait +action_end: + + add r10,r10,#0x4 + add r11,r11,#0x4 + /** + * Determine if r8 is multiple of 4 and r12 must be increased + */ + mov r2,r8 + and r2,r2,#0x3 + cmp r2,#0x3 + bne incr8 + add r12,r12,#0x4 +incr8: + add r8,r8,#0x01 + b loop1 +end1: + + mov r10, #0xf0 + lsl r10, #8 + orr r10, r10, #0x11 + lsl r10, #16 + + + + + ldr r1,[r10] + orr r1,r1,#0x2 + str r1,[r10] + + /* Wait for the DLL to lock */ +waitlock: + ldr r1,[r10,#0x4] + and r1,r1,#0x8 + cmp r1,#0x0 + beq waitlock + + /* Exit DDR-SDRAM from self-refresh mode */ + ldr r1,[r10, #0x20] + bic r1,r1,#0x04 + str r1,[r10, #0x20] + + /* Wait for DDR-SDRAM to exit from self-refresh */ +loop_refresh: + ldr r1,[r10,#0x4] + and r1,r1,#0x4 + cmp r1,#0x4 + beq loop_refresh + + + ldmfd sp!,{r4-r12,pc} + +mov r0,r0 +mov r0,r0 +mov r0,r0 +mov r0,r0 + +cache_prefetch_end1 : /* This is the end of the code to be copied into eSRAM */ +mov r0,r0 +mov r0,r0 +mov r0,r0 +mov r0,r0 + +bkup_adr_base : + .word 0x80010000 +bkup_adr : + .word 0x80010008 +bkup_data : + .word 0x800101C8 +bkup_action : + .word 0x80010388 +bkup_size : + .word 0x800103F8 +src_base : + .word 0xf01E0000 +mpmc_base : + .word 0xf0110000 +uart1_base : + .word 0xf01fb000 + + + + --- /dev/null +++ linux-2.6.20/arch/arm/mach-nomadik/dma.c @@ -0,0 +1,1337 @@ +/* + * arch/arm/mach-nomadik/dma.c + * + * Copyright 2007, STMicroelectronics + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Nomadik DMA driver to support standard APIs. + * the API details can be found at ./Documentation/arm/STM-Nomadik/dma_user_guide.txt + * + * Author : Prafulla WADASKAR + */ +#define DMA_VER "2.1.0" + +#include /* module functions */ +#include +#include +#include +#include /* For wait queues */ +#include +#include +#include /* spinlocks */ +#include /* err nos */ +#include /* wait macros */ +#include /* GFP flags */ +#include /* Amba device register */ +#include +#include +#include +#include +#include +#include +#include +#include /* for cli etc */ +#include +#include +#include +#include +#include +#include +#include + +#define DMA_NAME "DMA" + +#ifndef DMA_DEBUG +#define DMA_DEBUG 0 +#endif + +#define NMDK_DEBUG DMA_DEBUG /* enables/disables nmdk_dbg msgs */ +#define NMDK_DEBUG_PFX DMA_NAME /* msg header represents this module */ +#define NMDK_DBG KERN_ERR /* message level */ + +/* Macros used to identify standard dma structure elements for Nomadik implimentation*/ +#define dmaconfig_pipeadr(x) ((x)->dma_base) + +#define dmaconfig_defconfig(x) ((x)->buf.page) +#define dmaconfig_config(x) ((x)->buf.offset) +#define dmaconfig_usrconfig(x) ((x)->buf.dma_address) +#define dmaconfig_mode(x) ((x)->buf.length) + +#define dmaconfig_srcadr(x) ((x)->cur_sg.dma_address) +#define dmaconfig_destadr(x) ((x)->cur_sg.length) + +/* + * Constants used for DMA channel priority processing + */ +#define QUEUE_ID 0x80 +#define POLICY_CHECK_END 0xff +const u8 policy_mem2mem[10] ={15,14,13,12, + QUEUE_ID+15,QUEUE_ID+14,QUEUE_ID+13,QUEUE_ID+12, + POLICY_CHECK_END, POLICY_CHECK_END}; +const u8 policy_undefined[34] ={11,10,9,8,7,6,5,4,3,2,1,0,15,14,13,12, + QUEUE_ID+11,QUEUE_ID+10,QUEUE_ID+9,QUEUE_ID+8, + QUEUE_ID+7,QUEUE_ID+6,QUEUE_ID+5,QUEUE_ID+4, + QUEUE_ID+3,QUEUE_ID+2,QUEUE_ID+1,QUEUE_ID+0, + QUEUE_ID+15,QUEUE_ID+14,QUEUE_ID+13,QUEUE_ID+12, + POLICY_CHECK_END, POLICY_CHECK_END}; +const u8 policy_high[34] ={0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, + QUEUE_ID+0,QUEUE_ID+1,QUEUE_ID+2,QUEUE_ID+3, + QUEUE_ID+4,QUEUE_ID+5,QUEUE_ID+6,QUEUE_ID+7, + QUEUE_ID+8,QUEUE_ID+9,QUEUE_ID+10,QUEUE_ID+11, + QUEUE_ID+12,QUEUE_ID+13,QUEUE_ID+14,QUEUE_ID+15, + POLICY_CHECK_END, POLICY_CHECK_END}; +const u8 policy_normal[34] ={4,5,6,7,8,9,10,11,3,2,1,0,12,13,14,15, + QUEUE_ID+4,QUEUE_ID+5,QUEUE_ID+6,QUEUE_ID+7, + QUEUE_ID+8,QUEUE_ID+9,QUEUE_ID+10,QUEUE_ID+11, + QUEUE_ID+3,QUEUE_ID+2,QUEUE_ID+1,QUEUE_ID+0, + QUEUE_ID+12,QUEUE_ID+13,QUEUE_ID+14,QUEUE_ID+15, + POLICY_CHECK_END, POLICY_CHECK_END}; +const u8 policy_low[34] ={8,9,10,11,7,6,5,4,3,2,1,0,12,13,14,15, + QUEUE_ID+8,QUEUE_ID+9,QUEUE_ID+10,QUEUE_ID+11, + QUEUE_ID+7,QUEUE_ID+6,QUEUE_ID+5,QUEUE_ID+4, + QUEUE_ID+3,QUEUE_ID+2,QUEUE_ID+1,QUEUE_ID+0, + QUEUE_ID+12,QUEUE_ID+13,QUEUE_ID+14,QUEUE_ID+15, + POLICY_CHECK_END, POLICY_CHECK_END}; + + +static char dmach_name[MAX_DMA_CHANNELS * MAX_DMA_CHNAME_SIZE]; +static struct dma_soc_data *socdat; +static struct dmach_lli *p_lli_pipe[MAX_DMA_HWCHANNELS]; +struct dmach_lli *lli_ptr_log = NULL; +struct dmach_lli *lli_ptr_phy = NULL; +#define nomadik_dma_lli_phy_to_logical(x) ((struct dmach_lli *)((u32)(x + (lli_ptr_log - lli_ptr_phy)) & ~0x01)) + +#define nomadik_dmach_is_active_n_enabled(x) (x & 0x00020001) +#define nomadik_dma_is_pipe_busy(pipe) (p_lli_pipe[pipe]) +#define nomadik_dma_mark_pipe_busy(pipe) (p_lli_pipe[pipe] = (void *)0xffffffff) + +/** + * nomadik_dma_channel_of_pipe - To get dma channel irq for provided pipe address + * @pipeadr: pipe address w.r.to which channel irq needs for foundout + * + * finds the pipe number assoicated with channel + * if any transfer is already scheduled on a pipe, returns the channel irq of scheduled DMA + * if pipe is free, returns null + */ +static int nomadik_dma_channel_of_pipe(struct dmach_register *pipeadr) +{ + u32 pipe; + struct dma_struct * dma; + + pipe= (((u32)pipeadr & 0x0fff) - 0x0100)*2/sizeof(struct dmach_register); + if ((u32 *)pipeadr > (u32 *)socdat->dirqdesc[IRQ_DMA1].chip_data) pipe++; + if (p_lli_pipe[pipe]) { + if (p_lli_pipe[pipe]->mem2.dma) { + dma = p_lli_pipe[pipe]->mem2.dma; + return dma->dma_irq; + } else return 0; + } + return 0; +} + +/** + * nomadik_dma_allocate_llis - Allocates requested number of LLIs + * @count: No of LLI buffers requested + * + * reserves the requested number of llis from internal lli poolf + * link them with DMAble LLI addresses so that can be used directly by DMA h/w + * return the point of first lli + */ +static struct dmach_lli *nomadik_dma_allocate_llis(u32 count) +{ + struct dmach_lli *p_lli = lli_ptr_log; + struct dmach_lli *p_lli_phy = lli_ptr_phy; + struct dmach_lli *p_lli_phylast = (struct dmach_lli *)0x01; + unsigned long flags; + + nmdk_dbg_ftrace(); + if (!(p_lli) || !(count)) return (struct dmach_lli *)NULL; + if (count > MAX_DMA_LLIS) return (struct dmach_lli *)NULL; + flags = claim_dma_lock(); + do { + if (p_lli == (lli_ptr_log + MAX_DMA_LLIS-2)) { + nmdk_error("unable to find free lli.. rechecking..."); + p_lli = lli_ptr_log; + p_lli_phy = lli_ptr_phy; + } + p_lli++; p_lli_phy++; + if (!(p_lli->mem3.next)) { + p_lli->mem3.next = p_lli_phylast; + count--; + p_lli_phylast = (struct dmach_lli *)((u32)p_lli_phy + 0x01); + } + } while (count); + release_dma_lock(flags); + return p_lli; +} + +/** + * nomadik_dma_deallocate_llis - deallocates/frees the provided lli list + * @p_lli: pointer to the first lli + * + * frees all llis in the provided lli list + */ +static void nomadik_dma_deallocate_llis(struct dmach_lli *p_lli) +{ + struct dmach_lli *p_lli_bkup; + + nmdk_dbg_ftrace(); + while (p_lli) { + if (!(p_lli)) break; + if (!(p_lli->mem3.next)) break; + if ((u32)p_lli->mem3.next == 0x01) { + p_lli->mem3.next = (struct dmach_lli *)NULL; + break; + } + p_lli_bkup = nomadik_dma_lli_phy_to_logical(p_lli->mem3.next); + p_lli->mem3.next = (struct dmach_lli *)NULL; + p_lli = p_lli_bkup; + } +} + +/** + * nomadik_dma_schedule_xfer_on_pipe - Schedules DMA transfer lli on a pipe + * @p_pipe: pointer to a pipe on which DMA transfer to be scheduled + * @p_lli: pointer to the lli to be scheduled + * + * finds out the pipe no associated with a pipe + * checkes whether pipe is free or busy + * if free then + * Configures the pipe with LLI data + * clears any pending interrupt on a pipe + * marks pipe as busy + * Enables DMA to strat transfer + * if pipe is busy then + * queues the lli on the pipe + */ +static void nomadik_dma_schedule_xfer_on_pipe(volatile struct dmach_register *p_pipe, struct dmach_lli *p_lli) +{ + u32 pipe, i; + struct dmach_lli *p_lli_hw, *p_lli_curr; + volatile struct dma_register *p_dma_reg; + + nmdk_dbg_ftrace(); + i= (((u32)p_pipe & 0x0fff) - 0x0100)/sizeof(struct dmach_register); + pipe = i*2; + if ((u32 *)p_pipe > (u32 *)socdat->dirqdesc[IRQ_DMA1].chip_data) pipe++; + + p_lli->mem1.p_lli_qh = (struct dmach_lli *)NULL; /*Marked this lli as last in queue*/ + p_lli_curr = p_lli_pipe[pipe]; + mb(); + if ((p_lli_curr != (void*)0xffffffff) && (p_lli_curr != NULL) ) { + while (p_lli_curr->mem1.p_lli_qh) { + nmdk_dbg2("currlli(%p) next_lli (%p)", p_lli_curr, p_lli_curr->mem1.p_lli_qh); + p_lli_curr = p_lli_curr->mem1.p_lli_qh; /*go thr lli headers to point last lli head */ + } + p_lli_curr->mem1.p_lli_qh = p_lli; + nmdk_dbg2("lli(%p) is queued on PIPE %d at %p", p_lli, pipe, p_lli_curr); + } else { + /* clear any pending interrupt on this pipe if any */ + p_dma_reg = (void *)((u32)p_pipe & 0xffff0000); + p_dma_reg->tcicr |= 1UL<eicr |= 1UL<mem3.p_lli_hw); + p_pipe->sadr = p_lli_hw->mem1.sadr; + p_pipe->dadr = p_lli_hw->mem2.dadr; + p_pipe->lli = p_lli_hw->mem3.next; + p_pipe->cr = p_lli_hw->mem4.cr; + nmdk_dbg2("lli (%p) dmach(%p) sadr(%08x) dadr(%08x) lli(%p) cr(%08x)", p_lli, p_pipe, + (u32)p_pipe->sadr, (u32)p_pipe->dadr, p_pipe->lli, (u32)p_lli_hw->mem4.cr); + mb(); + p_pipe->cfg = p_lli->mem4.cfg; + } +} + +/** + * nomadik_dma_free_procesed_pipe - Frees processed LLI on a pipe + * @p_pipe: pointer to a pipe on which DMA transfer to be scheduled + * + * finds out the pipe no associated with a pipe + * checkes whether pipe is free or busy, if free then just returns + * frees the allocated llis for a pipe + * checks whether any transfer is queued on a pipe + * if the queue is not empty then + * Configures queues lli as current lli + * Configures the pipe with LLI data + * clears any pending interrupt on a pipe + * marks pipe as busy + * Enables DMA to strat transfer + * if the queue is empty then + * marks the pipe as free if not reserved by requesting DMA Channel + * otherwise marks the pipe as free + */ +static void nomadik_dma_free_procesed_pipe(volatile struct dmach_register *p_pipe) +{ + u32 pipe; + struct dmach_lli *p_lli; + dma_t *dma; + struct dmach_lli *p_lli_hw; + volatile struct dma_register *p_dma_reg; + u32 i; + + nmdk_dbg_ftrace(); + i= (((u32)p_pipe & 0x0fff) - 0x0100)/sizeof(struct dmach_register); + pipe = i*2; + if ((u32 *)p_pipe > (u32 *)socdat->dirqdesc[IRQ_DMA1].chip_data) pipe++; + + /* free lli of processed pipe*/ + if ((p_lli_pipe[pipe] != (void *)0xffffffff) && (p_lli_pipe[pipe] != NULL) ) { + dma = (dma_t *)p_lli_pipe[pipe]->mem2.dma; + p_lli = p_lli_pipe[pipe]->mem1.p_lli_qh; + nomadik_dma_deallocate_llis(p_lli_pipe[pipe]); + mb(); + if (p_lli) { + /* clear any pending interrupt on this pipe if any */ + p_dma_reg = (void *)((u32)p_pipe & 0xffff0000); + /*p_dma_reg->tcicr |= 1UL<eicr |= 1UL<mem3.p_lli_hw); + p_pipe->sadr = p_lli_hw->mem1.sadr; + p_pipe->dadr = p_lli_hw->mem2.dadr; + p_pipe->lli = p_lli_hw->mem3.next; + p_pipe->cr = p_lli_hw->mem4.cr; + nmdk_dbg2("lli (%p) dmach(%p) sadr(%08x) dadr(%08x) lli(%p) cr(%08x)", p_lli, p_pipe, + (u32)p_pipe->sadr, (u32)p_pipe->dadr, p_pipe->lli, (u32)p_lli_hw->mem4.cr); + mb(); + p_pipe->cfg = p_lli->mem4.cfg; + + nmdk_dbg2("Scheduling queued transfer on pipe %d (lli(%p))", pipe, + p_lli_pipe[pipe]); + } else { + if ((u32)dmaconfig_mode(dma) & DMA_PIPE_RESERVED) + p_lli_pipe[pipe] = (struct dmach_lli *)0xffffffff; + else { + p_lli_pipe[pipe] = (struct dmach_lli *)NULL; + dmaconfig_pipeadr(dma) = (u32)0; + } + } + } +} + +/* removes all allocated requests on the pipe */ +/** + * nomadik_dma_flush_pipe - Removes all scheduled and queued transfers on a pipe + * @p_pipe: pointer to a pipe on which DMA transfer to be scheduled + * + * finds out the pipe no associated with a pipe + * stops current transfer + * traverse through lli heads and flush all queued llis including scheduled one + * marks the pipe as free + */ +static void nomadik_dma_flush_pipe(volatile struct dmach_register *p_pipe) +{ + u32 pipe; + struct dmach_lli *p_lli_qh = (struct dmach_lli *)NULL; + dma_t *dma; + + nmdk_dbg_ftrace(); + pipe= (((u32)p_pipe & 0x0fff) - 0x0100)*2/sizeof(struct dmach_register); + if ((u32 *)p_pipe > (u32 *)socdat->dirqdesc[IRQ_DMA1].chip_data) pipe++; + + if ((u32)p_lli_pipe[pipe] == 0xffffffff) goto nextt; + while (p_lli_pipe[pipe] != 0) { + dma = (dma_t *)p_lli_pipe[pipe]->mem2.dma; + p_lli_qh = p_lli_pipe[pipe]->mem1.p_lli_qh; + nomadik_dma_deallocate_llis(p_lli_pipe[pipe]); + p_lli_pipe[pipe] = p_lli_qh; + nmdk_dbg2("Flushed lli (%p) for pipe %d", p_lli_pipe[pipe], pipe); + }; + nextt: +// if ((u32)dmaconfig_mode(dma) & DMA_PIPE_RESERVED) +// p_lli_pipe[pipe] = (struct dmach_lli *)0xffffffff; +// else + p_lli_pipe[pipe] = (struct dmach_lli *)NULL; +} + +/** + * nomadik_dma_check_update_userconfig - updates config as per user configs + * @dma: DMA channel structure pointer + * + * checks the user configuration + * if some use configuration is provided by clinet driver during + * configuration then abstracts it and updates Channel configuration + * data accordingly + */ +static void nomadik_dma_check_update_userconfig(dma_t *dma) +{ + nmdk_dbg_ftrace(); + if ((u32)dmaconfig_usrconfig(dma) & DMA_SRC_BSIZE_CONFIGURED) { + dmaconfig_config(dma) &= ~(DMA_BSIZE_256); + dmaconfig_config(dma) |= ((u32)dmaconfig_usrconfig(dma) & DMA_BSIZE_256); + } + if ((u32)dmaconfig_usrconfig(dma) & DMA_DEST_BSIZE_CONFIGURED) { + dmaconfig_config(dma) &= ~(DMA_BSIZE_256<<3); + dmaconfig_config(dma) |= (u32)dmaconfig_usrconfig(dma) & (DMA_BSIZE_256<<3); + } + if ((u32)dmaconfig_usrconfig(dma) & DMA_SRC_WIDTH_CONFIGURED) { + dmaconfig_config(dma) &= ~(DMA_WIDTH_NA); + dmaconfig_config(dma) |= ((u32)dmaconfig_usrconfig(dma) & DMA_WIDTH_NA); + } + if ((u32)dmaconfig_usrconfig(dma) & DMA_DEST_WIDTH_CONFIGURED) { + dmaconfig_config(dma) &= ~(DMA_WIDTH_NA<<3); + dmaconfig_config(dma) |= (u32)dmaconfig_usrconfig(dma) & (DMA_WIDTH_NA<<3); + } + nmdk_dbg("usrconfig =%08x, config = %08x", (u32)dmaconfig_usrconfig(dma), (u32)dmaconfig_config(dma)); +} + +/** + * nomadik_dma_usrdevconfig - updates user configuration as per type + * @config: user configuration information + * @type: src or destincation peripharal indicator (0= means src) + * + * checks provided configuration and returns configuration converting + * it for soruce or destination peripharal. this API is provided to + * facilitate and mistake proffing the configuration by client driver + */ +u32 __nomadik_dma_usrdevconfig(u32 config, int type) +{ + u32 val =0; + if (type == 0) { /*src*/ + if (config & DMA_DEV_BSIZE_CONFIGURABLE) { + val |= DMA_SRC_BSIZE_CONFIGURED; + val |= (config & DMA_BSIZE_256); + } + if (config & DMA_DEV_WIDTH_CONFIGURABLE) { + val |= DMA_SRC_WIDTH_CONFIGURED; + val |= (config & DMA_WIDTH_NA); + } + } else { /*dest*/ + if (config & DMA_DEV_BSIZE_CONFIGURABLE) { + val |= DMA_DEST_BSIZE_CONFIGURED; + val |= (config & DMA_BSIZE_256)<<3; + } + if (config & DMA_DEV_WIDTH_CONFIGURABLE) { + val |= DMA_DEST_WIDTH_CONFIGURED; + val |= (config & DMA_WIDTH_NA)<<3; + } + } + return (val); +} +EXPORT_SYMBOL(__nomadik_dma_usrdevconfig); + +/** + * nomadik_dmach_configure - configures DMA Channel processing default and user configuration + * @srcdmadev: name of srouce DMAble device IP + * @destdmadev: name of dest DMAble device IP + * @dma: DMA channel data structure pointer + * + * finds out the defult configuration for src and dest devices scanning the config_tbl + * prepares DMA configuration from default config of src and dest dmadevices and user + * configuration + * return 0 on cusess, negative value on failure + */ +static int nomadik_dmach_configure(char *src_dmadev, char *dest_dmadev, dma_t *dma) +{ + int i; + uint8 flag =0; + + nmdk_dbg_ftrace(); + dmaconfig_config(dma) = 0; + + for (i=0; i < socdat->config_tbl_size; i++) { + if (!(strcmp (src_dmadev, (socdat->config_tbl[i].id)))) { + dmaconfig_config(dma) |= (u32) (socdat->config_tbl[i].config & + (DMA_AHB_M1 | DMA_DEV_BOTH_DMACS_CANBE_USED | DMA_ADR_INC | + DMA_WIDTH_NA | DMA_BSIZE_256 | + DMA_REQUEST_LINE(31))); + flag |=0x01; + } + if (!(strcmp(dest_dmadev,(socdat->config_tbl[i].id)))) { + dmaconfig_config(dma) |= (u32)(((socdat->config_tbl[i].config + & DMA_DEV_BOTH_DMACS_CANBE_USED)<<2)); + dmaconfig_config(dma) |= (u32)(((socdat->config_tbl[i].config & DMA_AHB_M1)<<1)); + dmaconfig_config(dma) |= (u32)(((socdat->config_tbl[i].config & DMA_ADR_INC)<<1)); /*DI bit*/ + dmaconfig_config(dma) |= (u32)(((socdat->config_tbl[i].config & DMA_WIDTH_NA)<<3)); + dmaconfig_config(dma) |= (u32)(((socdat->config_tbl[i].config & DMA_BSIZE_256)<<3)); + dmaconfig_config(dma) |= (u32)(((socdat->config_tbl[i].config & DMA_REQUEST_LINE(31))<<5)); + flag |=0x02; + } + if ((flag & 0x03) == 0x03) { + nomadik_dma_check_update_userconfig(dma); + nmdk_dbg("conf(%08x), mode=%08x", dmaconfig_config(dma), dmaconfig_mode(dma)); + return(0); + } + } + nmdk_error("unable to configure dmachanel"); + return(-1); +} + +/** + * nomadik_dma_find_dmahwpipe - Finds and returns free and compatible DMA pipe + * @dma: DMA channel data structure pointer + * + * searches a free pipe as per channel priority policy manager + * (refer ./Documentation//arm/STM-Nomadik/dma_user_guide.txt) + * checks the configuration for the pipe suitability for transfer + * selects the pipe and mark it as busy + * returns pipe address if selected + * returns NULL in case of unavailability of pipe + */ +static struct dmach_register *nomadik_dma_find_dmahwpipe(dma_t *dma) +{ + int i; + u8 *p_pipe; + volatile struct dmach_register *p_dmach_reg; + volatile struct dma_register *p_dma_reg; + unsigned long flags; + + nmdk_dbg_ftrace(); + + flags = claim_dma_lock(); + /* channel priority setup */ + if ( MEM_TO_MEM == (u32)dmaconfig_mode(dma)) { + p_pipe = (void *)policy_mem2mem; + } + else if ( (u32)dmaconfig_mode(dma) & DMA_EXCH_PRIORITY_HIGH) { + p_pipe = (void *)policy_high; + } + else if ( (u32)dmaconfig_mode(dma) & DMA_EXCH_PRIORITY_NORMAL) { + p_pipe = (void *)policy_normal; + } + else if ( (u32)dmaconfig_mode(dma) & DMA_EXCH_PRIORITY_LOW) { + p_pipe = (void *)policy_low; + } + else { /* DMA_EXCH_PRIORITY_UNDEFINED) */ + p_pipe = (void *)policy_undefined; + } + do { + i = *p_pipe & ~QUEUE_ID; + /** Advanced Pipe selection strategy, under development */ + /* skip if pipe is busy and not requested on queued pipe */ + if (nomadik_dma_is_pipe_busy(i) && (!(*p_pipe & QUEUE_ID))) continue; + /* skip if pipe is busy with infinite dma xfer */ + if (nomadik_dma_is_pipe_busy(i) && + ((dmaconfig_config((dma_t *)p_lli_pipe[i]->mem2.dma)) & DMA_INFINITE_XFER)) continue; + if (i & 0x01) { + if (((u32)dmaconfig_config(dma) & (DMA_DEV_DMAC1_CANBE_USED | (DMA_DEV_DMAC1_CANBE_USED<<2))) + != (DMA_DEV_DMAC1_CANBE_USED | (DMA_DEV_DMAC1_CANBE_USED<<2)) ) continue; + p_dma_reg = (struct dma_register *)socdat->dirqdesc[IRQ_DMA1].chip_data; + } else { + if (((u32)dmaconfig_config(dma) & (DMA_DEV_DMAC0_CANBE_USED | (DMA_DEV_DMAC0_CANBE_USED<<2))) + != (DMA_DEV_DMAC0_CANBE_USED | (DMA_DEV_DMAC0_CANBE_USED<<2)) ) continue; + p_dma_reg = (struct dma_register *)socdat->dirqdesc[IRQ_DMA0].chip_data; + } + p_dmach_reg = (struct dmach_register *)&p_dma_reg->dmach[i/2]; + nomadik_dma_mark_pipe_busy(*p_pipe & ~QUEUE_ID); + nmdk_dbg("DMAHW PIPE%d assigned for Dma Channel %d",i, DMACH_FOR_IRQNO(dma->dma_irq)); + release_dma_lock(flags); + return (void *)p_dmach_reg; + } while ((*(++p_pipe)) != POLICY_CHECK_END); + release_dma_lock(flags); + nmdk_error("All HW DMA Chanels busy..."); + return NULL; +} + +/** + * nomadik_dma_req - low level method for request_dma API + * @channel: DMA channel number + * @dma: DMA channel data structure pointer + * + * Check for configuration is passed by client + * prepares basic channel configuration from dma info provided by client + * generate dmach id string from src and dest dmadevtypes + * find and reserved a pipe in case of reserved mode requested by client + * returns NULL in case of sucess, negative value in case for failure + */ +static int nomadik_dma_req(dmach_t channel, dma_t *dma) +{ + struct nmdk_dma_info *dma_info = + (struct nmdk_dma_info *)dma->device_id; + int error; + + nmdk_dbg_ftrace(); + + if (! dma->device_id) { + nmdk_error("nmdk_dma_info structptr not passed"); + return (-DMA_CONFIG_INFO_NOT_PASSED); + } + + dmaconfig_mode(dma) = (u32)dma_info->mode; + dmaconfig_usrconfig(dma) = (u32)dma_info->config; + + /* Prepare dmach configuration form dma_info*/ + switch((u32)dmaconfig_mode(dma) & FLOW_CNTRL_DEST_PERIPH(PERIPH_TO_PERIPH)) { + case MEM_TO_MEM: + dma_info->srcdevtype = "mem"; + dma_info->destdevtype = "mem"; + break; + case FLOW_CNTRL_PERIPH(MEM_TO_PERIPH): + case MEM_TO_PERIPH: + dma_info->srcdevtype = "mem"; + break; + case FLOW_CNTRL_PERIPH(PERIPH_TO_MEM): + case PERIPH_TO_MEM: + dma_info->destdevtype = "mem"; + break; + case FLOW_CNTRL_SRC_PERIPH(PERIPH_TO_PERIPH): + case FLOW_CNTRL_DEST_PERIPH(PERIPH_TO_PERIPH): + case PERIPH_TO_PERIPH: + break; + default: + nmdk_error("Invalid DMA mode"); + error =-1; + goto err_exit; + } + + if (! dma_info->srcdevtype) { + nmdk_error("srcdevtype not specified"); + error =-DMA_SRC_DEVICE_NOT_CONFIGURED; + goto err_exit; + } + if (! dma_info->destdevtype) { + nmdk_error("destdevtype not specified"); + error =-DMA_DEST_DEVICE_NOT_CONFIGURED; + goto err_exit; + } + error = nomadik_dmach_configure(dma_info->srcdevtype, dma_info->destdevtype, dma); + if (error) goto err_exit; + + /* generate dmach id string from src and dest dmadevtypes */ + sprintf(dmach_name + (channel * MAX_DMA_CHNAME_SIZE ), + "dmaclbk-%s->%s", dma_info->srcdevtype, dma_info->destdevtype); + dma->device_id = dmach_name + (channel * MAX_DMA_CHNAME_SIZE) + 8; + + if ((u32)dmaconfig_mode(dma) & DMA_PIPE_RESERVED) { + dmaconfig_pipeadr(dma) = (u32)nomadik_dma_find_dmahwpipe(dma); + if ((u32)dmaconfig_pipeadr(dma)) { + nmdk_dbg("pipe (%p) reserved for channel %d", + (void *)dmaconfig_pipeadr(dma), channel); + } else { + nmdk_error("could not reserve dmach hw pipe"); + error =-1; + goto err_exit; + } + } else dmaconfig_pipeadr(dma) = (u32)NULL; + dma->state = NMDK_DMA_CONFIGURED; + return(0); + + err_exit: + return(error); +} + +/** + * nomadik_dma_en - low level method for enable_dma API + * @channel: DMA channel number + * @dma: DMA channel data structure pointer + * + * Checks for channel configured properly + * allocates llis for transfer + * programm llis for transfer data + * checks if the pipe is already available with channel + * if not the find and allocates a free pipe for a transfer + * program dmach irqname if not set by client + * schedules a transfer on a pipe + */ +static void nomadik_dma_en(dmach_t channel, dma_t *dma) +{ + struct dmach_lli *p_lli_start = (struct dmach_lli *)NULL; + struct dmach_lli *p_lli_curr; + struct dmach_lli *p_lli_next; + + unsigned long flags; + u32 dmacnt, dmacnt_chkval, tmpcnt; + + nmdk_dbg_ftrace(); + +/* if (dma->invalid) { + if (dma->mode) { + if (((u32)dmaconfig_mode(dma) & FLOW_CNTRL_DEST_PERIPH(PERIPH_TO_PERIPH) == + (dma->mode & FLOW_CNTRL_DEST_PERIPH(PERIPH_TO_PERIPH)) { + dmaconfig_mode(dma) = (u32)dma->mode; + } + } + } else { + exit_invl_parms: + nmdk_error("enable request without parameters"); + goto exit_en + } + if (dma->addr) dmaconfig_srcadr(x) = dma->addr; + if (dma->speed) dmaconfig_destadr(x) = (u32)dma->speed; +*/ + + if (!(dma->sg)) { + if (!(dma->addr)) { + nmdk_error("srcadr not set"); + goto exit_en; + } + if (!(dma->speed)) { + nmdk_error("destadr not set"); + goto exit_en; + } + } + + /*set transfer size = count/src_width */ + dmacnt = dma->count/(((u32)dmaconfig_config(dma) & 0x000c0000)>>17); + nmdk_dbg("total count = %d, dma count =%d",(u32)dma->count, dmacnt); + tmpcnt = 0; + dmacnt_chkval = 0x0ff0; + + if (dma->sg) { + /*Scatter gather list implimentation */ + if (dma->sgcount == 0) { + nmdk_error("Empty scatter gather list"); + goto exit_en; + } + if ((((u32)dmaconfig_mode(dma) & 0x03) == MEM_TO_MEM ) || + (((u32)dmaconfig_mode(dma) & 0x03) == PERIPH_TO_PERIPH )) { + nmdk_error("Unsupported mode for scatter gather"); + goto exit_en; + } + p_lli_start = nomadik_dma_allocate_llis(dma->sgcount +1); + p_lli_curr = nomadik_dma_lli_phy_to_logical(p_lli_start->mem3.p_lli_hw); +#ifdef SCATERGATHER_MMC_DEBUG + if (dma->sgcount > 1) { + dmaconfig_config(dma) |= 0x0f0007fe; + nmdk_dbg("sc_count=%d , config=%08x", dma->sgcount, dmaconfig_config(dma)); + if (((u32)dmaconfig_mode(dma) & 0x03) == MEM_TO_PERIPH ) { + printk("===%p", dma_alloc_coherent( NULL , 4096, &dma->speed, GFP_DMA | GFP_KERNEL )); + + } else { + printk("==%p",dma_alloc_coherent( NULL , 4096, &dma->addr, GFP_DMA | GFP_KERNEL )); + } + dmaconfig_mode(dma) = 0; + } +#endif + tmpcnt = dma->count; + while (dma->sgcount) { + nmdk_dbg("tmpcnt %d, sg_len %d", tmpcnt, dma->sg->length); + p_lli_next = nomadik_dma_lli_phy_to_logical(p_lli_curr->mem3.next); + if (!(dma->sg->dma_address)) { + nmdk_error("sg list not dma mapped"); + goto exit_en; + } + if (((u32)dmaconfig_mode(dma) & 0x03) == MEM_TO_PERIPH ) { + p_lli_curr->mem1.sadr = dma->sg->dma_address; + if (!(dma->speed)) { + nmdk_error("destadr not set"); + goto exit_en; + } + p_lli_curr->mem2.dadr = (dma_addr_t)dma->speed; + } else { + if (!(dma->addr)) { + nmdk_error("srcadr not set"); + goto exit_en; + } + p_lli_curr->mem1.sadr = (dma_addr_t)dma->addr; + p_lli_curr->mem2.dadr = dma->sg->dma_address; + } + if (tmpcnt > dma->sg->length) { + p_lli_curr->mem4.cr = (((u32)dmaconfig_config(dma) & 0x0ffff000) | + (dma->sg->length/(((u32)dmaconfig_config(dma) & 0x000c0000)>>17))); + } else { + p_lli_curr->mem4.cr = (((u32)dmaconfig_config(dma) & 0x0ffff000) | + (tmpcnt/(((u32)dmaconfig_config(dma) & 0x000c0000)>>17))); + } + tmpcnt -= dma->sg->length; + dma->sgcount--; dma->sg++; + if (dma->sgcount == 0) p_lli_curr->mem4.cr |= (1<<31); + p_lli_curr = p_lli_next; + } + } else if ((u32)dmaconfig_mode(dma) & DMA_DOUBLE_BUFFERED ) { + p_lli_start = nomadik_dma_allocate_llis(3); + p_lli_curr = nomadik_dma_lli_phy_to_logical(p_lli_start->mem3.p_lli_hw); + p_lli_next = nomadik_dma_lli_phy_to_logical(p_lli_curr->mem3.next); + + dmacnt /= 2; + dmacnt_chkval = dmacnt; + /*fill next lli structure */ + p_lli_curr->mem4.cr = (((u32)dmaconfig_config(dma) & 0x0ffff000) | dmacnt_chkval); + p_lli_curr->mem1.sadr = (unsigned int)dma->addr; + p_lli_curr->mem2.dadr = dma->speed; + p_lli_next->mem4.cr = p_lli_curr->mem4.cr; + p_lli_next->mem1.sadr = p_lli_curr->mem1.sadr; + p_lli_next->mem2.dadr = p_lli_curr->mem2.dadr; + if (p_lli_next->mem4.cr & DMA_ADR_INC) p_lli_next->mem1.sadr += dma->count/2; + if (p_lli_next->mem4.cr & (DMA_ADR_INC<<1)) p_lli_next->mem2.dadr += dma->count/2; + + if ((u32)dmaconfig_mode(dma) & DMA_INFINITE_XFER) { + p_lli_next->mem3.next = p_lli_start->mem3.p_lli_hw; + } else { + p_lli_next->mem4.cr |= (1<<31); + } + } /*mode & DMA_DOUBLE_BUFFERED*/ + else { + tmpcnt = dmacnt/dmacnt_chkval; + p_lli_start = nomadik_dma_allocate_llis(tmpcnt + 2); + p_lli_curr = nomadik_dma_lli_phy_to_logical(p_lli_start->mem3.p_lli_hw); + p_lli_next = p_lli_curr; + + p_lli_curr->mem4.cr = (((u32)dmaconfig_config(dma) & 0x0ffff000) | + ((dmacnt < dmacnt_chkval)?dmacnt:dmacnt_chkval)); + dmacnt -= dmacnt_chkval; + p_lli_curr->mem1.sadr = (unsigned int)dma->addr; + p_lli_curr->mem2.dadr = dma->speed; + while(tmpcnt) { + p_lli_next = nomadik_dma_lli_phy_to_logical(p_lli_curr->mem3.next); + /*fill next lli structure */ + p_lli_next->mem4.cr = (((u32)dmaconfig_config(dma) & 0x0ffff000) | + ((dmacnt < dmacnt_chkval)?dmacnt:dmacnt_chkval)); + p_lli_next->mem1.sadr = p_lli_curr->mem1.sadr; + p_lli_next->mem2.dadr = p_lli_curr->mem2.dadr; + if (p_lli_next->mem4.cr & DMA_ADR_INC) + p_lli_next->mem1.sadr += dmacnt_chkval *(((u32)dmaconfig_config(dma) & 0x000c0000)>>17); + if (p_lli_next->mem4.cr & (DMA_ADR_INC<<1)) + p_lli_next->mem2.dadr += dmacnt_chkval *(((u32)dmaconfig_config(dma) & 0x000c0000)>>17); + + p_lli_curr = p_lli_next; + dmacnt -= dmacnt_chkval; + tmpcnt--; + } + p_lli_curr->mem4.cr |= (1<<31); + if ((u32)dmaconfig_mode(dma) & DMA_INFINITE_XFER) { + p_lli_curr->mem3.next = p_lli_start->mem3.p_lli_hw; + } else { + p_lli_curr->mem4.cr |= (1<<31); + } + } + nmdk_dbg("lli_start(%p)", p_lli_start); + p_lli_start->mem2.dma = (void *)dma; /*dma associated with this lii*/ + p_lli_start->mem4.cfg = (((u32)dmaconfig_config(dma) & 0x000007fe) | /* set src/dest dma periph request line numbers */ + ((u32)dmaconfig_mode(dma)<<11 & (7<<11)) | /* set flow control and xter type*/ + (0x0000c001)); /*enable interrupts and start xfer*/ + + /* if channel is reserved use predefined hwpipe else find free + * h/w pipe to schedule dma + * if h/w pipe is not available the que the request + */ + if (!((u32)dmaconfig_pipeadr(dma))) { + dmaconfig_pipeadr(dma) = (u32)nomadik_dma_find_dmahwpipe(dma); + if (dmaconfig_pipeadr(dma)) { + nmdk_dbg("channel %d allocated pipe p_dmach_reg(%p) ",channel, (void *)dmaconfig_pipeadr(dma)); + } else { + nmdk_error("enable requested aborted...No pipe available..."); + goto exit_en; + } + } + /* program dmach irqname if not set by client */ + if (socdat->dirqdesc[IRQNO_FOR_DMACH(channel)].action) + if (!(socdat->dirqdesc[IRQNO_FOR_DMACH(channel)].action->name)) + socdat->dirqdesc[IRQNO_FOR_DMACH(channel)].action->name = + (dmach_name + (channel * MAX_DMA_CHNAME_SIZE)); + + mb(); + flags = claim_dma_lock(); + nomadik_dma_schedule_xfer_on_pipe((void *)dmaconfig_pipeadr(dma), p_lli_start); + release_dma_lock(flags); + dma->state = NMDK_DMA_ENABLED; + if ((u32)dmaconfig_mode(dma) & DMA_QUEUE_ENABLED) dma->active = 0; + return; + +exit_en: + if (p_lli_start) nomadik_dma_deallocate_llis(p_lli_start); + return; +} + +/** + * nomadik_dma_dis - low level method for disable_dma API + * @channel: DMA channel number + * @dma: DMA channel data structure pointer + * + * disables a transfer on a pipe if associated with a requested channel + */ +static void nomadik_dma_dis(dmach_t channel, dma_t *dma) +{ + struct dmach_register *p_dmach_reg = (struct dmach_register *)dmaconfig_pipeadr(dma); + unsigned long flags; + + nmdk_dbg_ftrace(); + + if ((p_dmach_reg == NULL) || p_dmach_reg == (void *)0xffffffff) return; + /*Reset E (Chanel Enablne) bit of DMAC_CxCFG reg*/ + flags = claim_dma_lock(); + nmdk_dbg("Channel %d disabled on pipe %08x", channel, (u32)dmaconfig_pipeadr(dma)); + p_dmach_reg->cfg &= ~0x0000c001; + release_dma_lock(flags); + dma->state = NMDK_DMA_DISABLED; +} + +static void nomadik_dma_fr(dmach_t channel, dma_t *dma) +{ + nmdk_dbg_ftrace(); + nomadik_dma_dis(channel, dma); + if (socdat->dirqdesc[IRQNO_FOR_DMACH(channel)].action) + free_irq(IRQNO_FOR_DMACH(channel), socdat->dirqdesc[IRQNO_FOR_DMACH(channel)].action->dev_id); + if (dmaconfig_pipeadr(dma)) nomadik_dma_flush_pipe((void *)dmaconfig_pipeadr(dma)); +} + +/* find the available dma chanel and requests the same */ +/** + * request_available_dma - Wrapper over request_dma API + * @dmach_config_info: DMA channel number + * @dma: DMA channel data structure pointer + * + * Wrapper over request_dma API for free and available DMA channel search + * returns DMA Channel number , negative error value in case of failure + */ +int request_available_dma(struct nmdk_dma_info * dmach_config_info) +{ + dmach_t channel; + int error; + + /*removed locks as detected by spinlock debugging on*/ + for (channel = 0; channel < (MAX_DMA_CHANNELS - 1); channel++) { + error = request_dma(channel, (char *)dmach_config_info); + if (-EBUSY == error) continue; + if (error < 0) { + nmdk_error("Request DMA error"); + return error; + } else { + nmdk_dbg("Dma Chanel %d is available and allocated", channel); + return channel; + } + } + nmdk_error("All DMA Channels occupied...."); + return -DMA_ALLCHANELS_OCCUPIED; +} +EXPORT_SYMBOL(request_available_dma); + +/** + * suspend_dma - Pauses DMA transfer for this channel + * @channel: DMA channel number + * + * This API will pause current dma if it is ongoing + * also this API is used to pause all active on going DMA channels involved + * with memory transfer by passing DMA_ALL_MEM_CHANNELS as an argument + */ +void suspend_dma(dmach_t channel) +{ + dma_t *dma; + volatile struct dmach_register *p_dmach_reg; + unsigned long flags; + + nmdk_dbg_ftrace(); + if (!(socdat->dma_chan)) goto inactive_dma; + dma = socdat->dma_chan; + if (DMA_ALL_MEM_CHANNELS == channel) { + for (channel=0; channel< MAX_DMA_CHANNELS; channel++) { + if (!dma->lock) continue; + if (NMDK_DMA_SUSPENDED == dma->state) continue; + if (((u32)dmaconfig_mode(dma)&PERIPH_TO_PERIPH) + == PERIPH_TO_PERIPH) continue; + p_dmach_reg = (struct dmach_register *)dmaconfig_pipeadr(dma); + + if ((p_dmach_reg == NULL) || p_dmach_reg == (void *)0xffffffff) continue; + /*Reset E (Chanel Enablne) bit of DMAC_CxCFG reg*/ + flags = claim_dma_lock(); + nmdk_dbg("Channel %d Suspended on pipe %p", channel, (void *)dmaconfig_pipeadr(dma)); + if (p_dmach_reg->cfg & NMDK_DMACH_ENABLE) { + p_dmach_reg->cfg |= NMDK_DMACH_HALT; + } + release_dma_lock(flags); + dma->state = NMDK_DMA_SUSPENDED; + + dma++; + } + return; + } + if (!(socdat->dma_chan)) goto inactive_dma; + dma += channel; + if (!dma->lock) + goto free_dma; + + if (NMDK_DMA_SUSPENDED == dma->state) return; + p_dmach_reg = (struct dmach_register *)dmaconfig_pipeadr(dma); + + if ((p_dmach_reg == NULL) || p_dmach_reg == (void *)0xffffffff) return; + /*Reset E (Chanel Enablne) bit of DMAC_CxCFG reg*/ + flags = claim_dma_lock(); + nmdk_dbg("Channel %d Suspended on pipe %08x", channel, (u32)dmaconfig_pipeadr(dma)); + if (p_dmach_reg->cfg & NMDK_DMACH_ENABLE) { + p_dmach_reg->cfg |= NMDK_DMACH_HALT; + } + release_dma_lock(flags); + dma->state = NMDK_DMA_SUSPENDED; + return; + +free_dma: + printk(KERN_ERR "dma%d: trying to suspend free DMA\n", channel); + BUG(); + return; +inactive_dma: + printk(KERN_ERR "dma driver not active\n"); + BUG(); +} +EXPORT_SYMBOL(suspend_dma); + + +/** + * nomadik_dma_residue - low level method for get_dma_residue API + * @channel: DMA channel number + * @dma: DMA channel data structure pointer + * + * Pause the channel, read the control register, resume the channel + * May not be an accurate value + * returns bytes remaining on a transfer + */ +static int nomadik_dma_residue(dmach_t channel, dma_t *dma) +{ + volatile unsigned int r = 0; + volatile struct dmach_register *p_dmach_reg = + (struct dmach_register *)dmaconfig_pipeadr(dma); + + if ((p_dmach_reg == NULL) || p_dmach_reg == (void *)0xffffffff) return -1; + suspend_dma(channel); + mb(); + + /*get transfer bytes = src_width * transfer_size */ + r = p_dmach_reg->cr & 0x0fff; + r *= ((p_dmach_reg->cr & 0x000c0000)>>17); + mb(); + resume_dma(channel); + + return r; +} + +/** + * resume_dma - Resume already suspended DMA transfer for this channel + * @channel: DMA channel number + * + * This API will resume current dma if it is suspended previously + * also this API is used to resume all active and paused DMA channels involved + * with memory transfer by passing DMA_ALL_MEM_CHANNELS as an argument + */ +void resume_dma(dmach_t channel) +{ + dma_t *dma; + volatile struct dmach_register *p_dmach_reg; + unsigned long flags; + + nmdk_dbg_ftrace(); + if (!(socdat->dma_chan)) goto inactive_dma; + dma = socdat->dma_chan; + if (DMA_ALL_MEM_CHANNELS == channel) { + for (channel=0; channel< MAX_DMA_CHANNELS; channel++) { + if (!dma->lock) continue; + if (NMDK_DMA_SUSPENDED != dma->state) continue; + if (((u32)dmaconfig_mode(dma)&PERIPH_TO_PERIPH) + == PERIPH_TO_PERIPH) continue; + p_dmach_reg = (struct dmach_register *)dmaconfig_pipeadr(dma); + + if ((p_dmach_reg == NULL) || p_dmach_reg == (void *)0xffffffff) continue; + /*Reset E (Chanel Enablne) bit of DMAC_CxCFG reg*/ + flags = claim_dma_lock(); + if (p_dmach_reg->cfg & NMDK_DMACH_ENABLE) { + p_dmach_reg->cfg &= (u32)~(NMDK_DMACH_HALT); + } + nmdk_dbg("Channel %d Resumed on pipe %08x", channel, (u32)dmaconfig_pipeadr(dma)); + release_dma_lock(flags); + dma->state = NMDK_DMA_RESUMED; + + } + return; + } + dma += channel; + if (!dma->lock) + goto free_dma; + + if (NMDK_DMA_SUSPENDED != dma->state) return; + p_dmach_reg = (struct dmach_register *)dmaconfig_pipeadr(dma); + + if ((p_dmach_reg == NULL) || p_dmach_reg == (void *)0xffffffff) return; + /*Reset E (Chanel Enablne) bit of DMAC_CxCFG reg*/ + flags = claim_dma_lock(); + if (p_dmach_reg->cfg & NMDK_DMACH_ENABLE) { + p_dmach_reg->cfg &= (u32)~(NMDK_DMACH_HALT); + } + nmdk_dbg("Channel %d Resumed on pipe %08x", channel, (u32)dmaconfig_pipeadr(dma)); + release_dma_lock(flags); + dma->state = NMDK_DMA_RESUMED; + return; + +free_dma: + printk(KERN_ERR "dma%d: trying to resume free DMA\n", channel); + BUG(); + return; +inactive_dma: + printk(KERN_ERR "dma driver not active\n"); + BUG(); +} +EXPORT_SYMBOL(resume_dma); + +/** + * nomadik_dma_set_destadr - low level method for set_dma_speed API + * @channel: DMA channel number + * @dma: DMA channel data structure pointer + * @cycle: sonsidered as destination DMA address + * + * Since ther is no API to program destination DMA address. + * set_dma_speed is used to fulfill this need. + * the function returnes the cycle which finally programs dma->spped + * with destination DMA address for nomadik platform + */ +static int nomadik_dma_set_destadr(dmach_t channel, dma_t *dma, int cycle) +{ + /*Speed is used to store destination address*/ + return (cycle); +} + +/** + * nomadik_dma_interrupt - Interrupt handler for DMA controller + * @irq: interrupt request number + * @desc: irq structure pointer + * + * checks and find out the source DMA channel who generated interrupt + * if interrupt generated is Terminal count then + * process the DMA chanel irq associated with a pipe + * if interrupt generated is Bus_error then + * just acknowledge it. + * free processed transfer lli and schedule the queue + */ +static void nomadik_dma_interrupt(unsigned int irq, struct irq_desc *desc, struct pt_regs *regs) +{ + u32 mask; + volatile struct dma_register *p_dma_reg = (struct dma_register *)desc->chip_data; + volatile struct dmach_register *p_dmach_reg; + struct dma_struct *di_dmachan; + do { + p_dmach_reg = &p_dma_reg->dmach[0]; + nmdk_dbg2("dhach addr = %p", p_dmach_reg); + for (mask = 1; mask != 0x100; mask=mask<<1) { + if (p_dma_reg->mis & mask) { + /* To wait for the physical Channel to get disabled(otherwise it may + cause Virtual/Spurious Interrupts) */ + while (nomadik_dmach_is_active_n_enabled(p_dmach_reg->cfg)) ; + if (p_dma_reg->tcmis & mask) { + p_dma_reg->tcicr |= mask; + irq = nomadik_dma_channel_of_pipe((void *)p_dmach_reg); + if (irq != 0) { + desc = socdat->dirqdesc + irq; + di_dmachan = socdat->dma_chan + DMACH_FOR_IRQNO(irq); + /*handle dmachanel interrupt callback*/ + nmdk_dbg3("ch%d tc intr", DMACH_FOR_IRQNO(irq)); + /*flag upper layer to that requested dma is complete*/ + if (di_dmachan->active) di_dmachan->active = 0; + desc_handle_irq(irq, desc); + /*free lli of processed request and schedule if any request in queue*/ + nomadik_dma_free_procesed_pipe(p_dmach_reg); + } + } + if (p_dma_reg->emis & mask) { + p_dma_reg->eicr |= mask; + nmdk_error("Intr buserr for pipe %08x", (u32)p_dmach_reg); + nomadik_dma_free_procesed_pipe(p_dmach_reg); + } + } + p_dmach_reg++; + } + } while (p_dma_reg->mis != 0); + nmdk_dbg2("intr exit"); +} + +struct dma_ops nomadik_dma_ops = { + .type = "DMACH:", + .request = nomadik_dma_req, + .free = nomadik_dma_fr, + .enable = nomadik_dma_en, + .disable = nomadik_dma_dis, + .setspeed = nomadik_dma_set_destadr, + .residue = nomadik_dma_residue, +}; + +/** + * nomadik_dma_probe - driver probe function + * + * checks platfom_data is programmed properly + * ioremaps the DMAC register and updates pointer + * sets DMAC irq handler + * allocates memory for lli pool + * configures DMA channels and DMA channel interrupts + */ +static int nomadik_dma_probe(struct amba_device *dev, void *data) +{ + int i, ret; + uint8 dmac; + struct irq_desc *dirq_desc; + struct dma_struct *dmachan, *dmachan_temp; + volatile struct dma_register *p_dma_reg; + struct irqchip *p_dirqchip; + + nmdk_dbg_ftrace(); + + /* findout dma controller number*/ + if (IRQ_DMA0 == dev->irq[0]) dmac = 0; + else if (IRQ_DMA1 == dev->irq[0]) dmac = 1; + else { + nmdk_error("invalid dma device"); + ret = -EINVAL; + goto res_out; + } + + if (! dev->dev.platform_data) { + nmdk_error("platform specific data no initialized for DMAC%d", dmac); + ret = -ENOMEM; + goto res_out; + } +/* ret = amba_request_regions(dev, NULL); + if (ret) + goto out; + */ + p_dma_reg = (void __iomem *) + ioremap((int)dev->res.start, SZ_4K); + if (!p_dma_reg) { + nmdk_error("ioremap failed for DMAC%d", dmac); + ret = -ENOMEM; + goto res_out; + } + nmdk_dbg("dma_erg prt = %p irq %d", p_dma_reg,dev->irq[0] ); + socdat = (struct dma_soc_data *)dev->dev.platform_data; + dmachan = (struct dma_struct *)socdat->dma_chan; + dirq_desc = socdat->dirqdesc; + p_dirqchip = socdat->dirqchip; + dirq_desc[dev->irq[0]].chip_data = (void *)p_dma_reg; + + memset((void *)p_dma_reg, 0, sizeof(struct dma_register)); /*init h/w register to zero*/ +#ifdef __STN_8810 +#if (__STN_8810 == 10) + p_dma_reg->cr = 0x01; /*enable DMa controller */ +#endif +#endif + + set_irq_chained_handler(dev->irq[0], (void *)nomadik_dma_interrupt); + + if (!(dmac)) { + + lli_ptr_log = (struct dmach_lli *)dma_alloc_coherent(NULL, + MAX_DMA_LLIS * (sizeof(struct dmach_lli)), + (dma_addr_t *) &lli_ptr_phy, + GFP_DMA | GFP_ATOMIC); + if (lli_ptr_log <= 0) { + nmdk_error("unable to request mem for llis"); + ret = -1; + goto bad_dev; + } + nmdk_info("chanel lli physical adr(%08x) logical adr(%08x)", (u32)lli_ptr_phy, (u32)lli_ptr_log); + dmachan_temp = dmachan; + /* dma chanel irq initialization */ + for (i = (MAX_DMA_IRQ-MAX_DMA_CHANNELS); i < MAX_DMA_IRQ; i++) { + /*set_irq_chip(i, &nomadik_dma_chip);*/ + set_irq_handler(i, handle_simple_irq); + set_irq_flags(i, IRQF_VALID); + socdat->dirqdesc[i].chip_data= NULL; //&p_dma_reg->dmach[ret]; + if (i < MAX_DMA_CHANNELS) p_lli_pipe[DMACH_FOR_IRQNO(i)] = NULL; + /* dma chanel data structure initialization */ + dmachan[DMACH_FOR_IRQNO(i)].d_ops = &nomadik_dma_ops; + dmachan[DMACH_FOR_IRQNO(i)].dma_irq = i; + + } + } + nmdk_info("DMA%d Module initialized Ver("DMA_VER")",dmac); + return (0); + +bad_dev: + iounmap(p_dma_reg); +res_out: + return (ret); +} + +/** + * nomadik_dma_remove - driver remove function + * + * resets DMA channels and DMA channel interrupts configureation + * deallocates memory for lli pool + * resets DMAC irq handler + * frees ioremapped memory + */ +static int nomadik_dma_remove(struct amba_device *dev) +{ + uint8 dmac; + int i; + struct irq_desc *dirq_desc; + struct dma_struct *dma_chan; + volatile struct dma_register *p_dma_reg; + struct irqchip *p_dirqchip; + + nmdk_dbg_ftrace(); + + /* findout dma controller number*/ + if (IRQ_DMA0 == dev->irq[0]) dmac = 0; + else if (IRQ_DMA1 == dev->irq[0]) dmac = 1; + else { + nmdk_error("invalide dma device"); + return(-EINVAL); + } + socdat = dev->dev.platform_data; + dma_chan = (struct dma_struct *)socdat->dma_chan; + dirq_desc = socdat->dirqdesc; + p_dma_reg = dirq_desc[dev->irq[0]].chip_data; + + p_dirqchip = socdat->dirqchip; + if (!(dmac)) { + for (i = (MAX_DMA_IRQ-MAX_DMA_CHANNELS); i < MAX_DMA_IRQ; i++) { + //set_irq_chip(i, 0x00); + set_irq_handler(i, handle_bad_irq); + dma_chan[DMACH_FOR_IRQNO(i)].d_ops = NULL; + } + } + + set_irq_handler(dev->irq[0], handle_bad_irq); + + dma_free_coherent(NULL, + ((MAX_DMA_CHANNELS*(sizeof(struct dmach_lli))*8)+256), + (void *)lli_ptr_log, (dma_addr_t)lli_ptr_phy ); + lli_ptr_phy = lli_ptr_log = NULL; + + iounmap(p_dma_reg); + dirq_desc[dev->irq[0]].chip_data = 0x00; + /*amba_release_regions(dev);*/ + + nmdk_info("Module removed"); + return 0; +} + +static struct amba_id nomadik_dma_dev_ids[] __initdata = { + { + .id = DMA_PER_ID, + .mask = DMA_PER_MASK, + }, + {0, 0}, +}; + +static struct amba_driver dma_driver = { + .drv = { + .name = "DMA", + }, + .id_table = nomadik_dma_dev_ids, + .probe = nomadik_dma_probe, + .remove = nomadik_dma_remove +}; + +static int __init nomadik_dma_init(void) +{ + return amba_driver_register(&dma_driver); +} + +static void __exit nomadik_dma_exit(void) +{ + amba_driver_unregister(&dma_driver); +} + +module_init(nomadik_dma_init); +module_exit(nomadik_dma_exit); + +/* Module parameters */ + +MODULE_AUTHOR("ST Microelectronics"); +MODULE_DESCRIPTION("Nomadik DMA Controllers (0 and 1)"); +MODULE_LICENSE("GPL"); --- /dev/null +++ linux-2.6.20/arch/arm/mach-nomadik/fsmc.c @@ -0,0 +1,113 @@ +/* + * linux/arch/arm/mach-nomadik/fsmc.c + * + * Copyright (C) STMicroelectronics + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +struct fsmc_nomadik_info { + unsigned char __iomem *fsmc_reg; +}; + +static int nomadik_fsmc_probe(struct platform_device *pdev) +{ + struct fsmc_platform_data *pdata = pdev->dev.platform_data; + struct fsmc_nomadik_info *data = NULL; + struct resource *res = NULL; + if (!pdata->init) { + printk("FSMC ::: platform init() function is not present\n"); + return (-1); + } + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + + data = kzalloc(sizeof(struct fsmc_nomadik_info), GFP_KERNEL); + data->fsmc_reg = ioremap(res->start, res->end - res->start + 1); + platform_set_drvdata(pdev, data); + + /*do platform specific fsmc init */ + return (pdata->init()); +} + +/* + * Clean up routine + */ +static int nomadik_fsmc_remove(struct platform_device *pdev) +{ + struct fsmc_nomadik_info *data = NULL; + + data = platform_get_drvdata(pdev); + if(data){ + iounmap(data->fsmc_reg); + kfree(data); + } + return 0; +} + +#ifdef CONFIG_PM + +#define FSMC_REG_SIZE 0x78 +static char vect_fsmc[FSMC_REG_SIZE]; +int nomadik_fsmc_suspend(struct platform_device *pdev, pm_message_t state) +{ + struct fsmc_nomadik_info *data = platform_get_drvdata(pdev); + printk("nomadik_fsmc_suspend: called......\n"); + memcpy(vect_fsmc, data->fsmc_reg, FSMC_REG_SIZE); + return 0; +} + +int nomadik_fsmc_resume(struct platform_device *pdev) +{ + struct fsmc_nomadik_info *data = platform_get_drvdata(pdev); + printk("nomadik_fsmc_resume: called......\n"); + memcpy(data->fsmc_reg, vect_fsmc, FSMC_REG_SIZE); + + return 0; +} + +#else +#define nomadik_fsmc_suspend NULL +#define nomadik_fsmc_resume NULL + +#endif + +static struct platform_driver nomadik_fsmc_driver = { + .probe = nomadik_fsmc_probe, + .remove = nomadik_fsmc_remove, + .driver = { + .owner = THIS_MODULE, + .name = "NOMADIK-FSMC", + }, + .suspend = nomadik_fsmc_suspend, + .resume = nomadik_fsmc_resume, +}; + +static int __init nomadik_fsmc_init(void) +{ + return platform_driver_register(&nomadik_fsmc_driver); +} + +module_init(nomadik_fsmc_init); +static void __exit nomadik_fsmc_exit(void) +{ + platform_driver_unregister(&nomadik_fsmc_driver); + return; +} + +module_exit(nomadik_fsmc_exit); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("ST Microelectronics (sachin.verma@st.com)"); +MODULE_DESCRIPTION("FSMC driver for Nomadik Platform"); --- /dev/null +++ linux-2.6.20/arch/arm/mach-nomadik/gpio.c @@ -0,0 +1,916 @@ +/* + * linux/arch/arm/mach-nomadik/gpio.c + * + * Copyright (C) STMicroelectronics + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#define GPIO_VER "2.1.0" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define GPIO_NAME "GPIO" + +#ifndef GPIO_DEBUG +#define GPIO_DEBUG 0 +#endif + +#define NMDK_DEBUG GPIO_DEBUG /* enables/disables nmdk_dbg msgs */ +#define NMDK_DEBUG_PFX GPIO_NAME /* msg header represents this module */ +#define NMDK_DBG KERN_ERR /* message level */ + +const char *gpio_block_name[4] = { + "GPIO_Block0", "GPIO_Block1", "GPIO_Block2", "GPIO_Block3", +}; + +static spinlock_t altfun_lock = SPIN_LOCK_UNLOCKED; +static spinlock_t pinconf_lock = SPIN_LOCK_UNLOCKED; +static struct gpio_soc *socdat = NULL; /*soc specific data ptr */ +extern struct irq_desc irq_desc[]; /* maintain interrupt info */ + +#define CHK_VALID_CALL if (! socdat) { \ + nmdk_error("called %s before initilization", __FUNCTION__); \ + return(-EINVAL); \ + } + +#define CHK_VALID_PIN(pin) if (irq_desc[IRQNO_GPIO(pin)].action) {\ + nmdk_error("%s failed, gpio%d used by irq %d", __FUNCTION__, pin , IRQNO_GPIO(pin));\ + return -EINVAL;\ + } + +static char *nomadik_gpio_owner(gpio_pin pin_id) +{ + if (irq_desc[IRQNO_GPIO(pin_id)].action) { + return (char *)irq_desc[IRQNO_GPIO(pin_id)].action->name; + } + if (irq_desc[IRQNO_GPIO(pin_id)].chip_data) { + return (char *)irq_desc[IRQNO_GPIO(pin_id)].chip_data; + } + return (0); +} + +/** + * nomadik_gpio_chkwr_permission - checks pin permission for write operation + */ +static int nomadik_gpio_chkwr_permission(gpio_pin pin_id, char *dev_name) +{ + char *pin_owner = nomadik_gpio_owner(pin_id); + if (!pin_owner) { + nmdk_error("pin %d not configured", pin_id); + return -1; + } + if (pin_owner != dev_name) + if (!strcmp(pin_owner, dev_name)) { + nmdk_error("pin %d not owned by %s", pin_id, dev_name); + return -1; + } + if (irq_desc[IRQNO_GPIO(pin_id)].action) { + nmdk_error("pin %d used as irq cannot be written", pin_id); + return -1; + } + return 0; +} + +/* + * Static Function declarations + */ +static gpio_error gpio_setpinconfig(gpio_pin pin_id, gpio_config * config) +{ + unsigned long flags; + struct gpio_register *p_gpio_register = + (struct gpio_register *)get_irq_chip_data(GPIO_PIN2BLKIRQ(pin_id)); + uint32 mask = 1UL << (pin_id % GPIO_PINS_PER_BLOCK); + gpio_error gpio_error = GPIO_OK; + + nmdk_dbg_ftrace(); + spin_lock_irqsave(&pinconf_lock, flags); + if (config->dev_name) + irq_desc[IRQNO_GPIO(pin_id)].chip_data = config->dev_name; + else + irq_desc[IRQNO_GPIO(pin_id)].chip_data = "unknown"; + spin_unlock_irqrestore(&pinconf_lock, flags); + + switch (config->mode) { + case GPIO_ALTF_A: + p_gpio_register->gpio_afsa |= mask; + p_gpio_register->gpio_afsb &= ~mask; + break; + case GPIO_ALTF_B: + p_gpio_register->gpio_afsa &= ~mask; + p_gpio_register->gpio_afsb |= mask; + break; + case GPIO_ALTF_C: + p_gpio_register->gpio_afsa |= mask; + p_gpio_register->gpio_afsb |= mask; + break; + case GPIO_MODE_SOFTWARE: + p_gpio_register->gpio_afsa &= ~mask; + p_gpio_register->gpio_afsb &= ~mask; + + switch (config->direction) { + case GPIO_DIR_INPUT: + p_gpio_register->gpio_dirc = mask; + break; + case GPIO_DIR_OUTPUT: + p_gpio_register->gpio_dirs = mask; + break; + case GPIO_DIR_LEAVE_UNCHANGED: + break; + default: + return (GPIO_INVALID_PARAMETER); + } + + if (socdat->dbounce) + gpio_error = + socdat->dbounce(p_gpio_register, mask, + config->debounce, + config->debounce_time); + break; + case GPIO_MODE_LEAVE_UNCHANGED: + break; + default: + return (GPIO_INVALID_PARAMETER); + } + return (gpio_error); +} + +static gpio_error gpio_resetgpiopin(gpio_pin pin_id, char *dev_name) +{ + unsigned long flags; + struct gpio_register *p_gpio_register = + (struct gpio_register *)get_irq_chip_data(GPIO_PIN2BLKIRQ(pin_id)); + uint32 mask = 1UL << (pin_id % GPIO_PINS_PER_BLOCK); + char *pin_dev_name; + gpio_error gpio_error = GPIO_OK; + + nmdk_dbg_ftrace(); + pin_dev_name = nomadik_gpio_owner(pin_id); + if (!pin_dev_name) + return 0; + if (strcmp(dev_name, pin_dev_name)) { + nmdk_error("Unable to free pin%d Current Owner is %s", pin_id, + pin_dev_name); + return (-1); + } + p_gpio_register->gpio_afsa &= ~mask; + p_gpio_register->gpio_afsb &= ~mask; /*software mode*/ + p_gpio_register->gpio_dirc = mask; /*input dir*/ + if (socdat->dbounce) /*disalbe debounce*/ + gpio_error = + socdat->dbounce(p_gpio_register, mask, + GPIO_DEBOUNCE_DISABLE, + (gpio_debounce_time)NULL); + /* mark pin is freed */ + + spin_lock_irqsave(&pinconf_lock, flags); + irq_desc[IRQNO_GPIO(pin_id)].chip_data = NULL; + spin_unlock_irqrestore(&pinconf_lock, flags); + if (irq_desc[IRQNO_GPIO(pin_id)].action) + irq_desc[IRQNO_GPIO(pin_id)].action->name = NULL; + return (gpio_error); +} + +gpio_config altfun_pinconfig; +static gpio_error gpio_altfunction(gpio_alt_function alt_func, + int which_altfunc, char *dev_name) +{ + struct gpio_altfun_data *altfun_table = socdat->altfun_tbl; + int max_altfun = socdat->sz_altfun_tbl; + int i, j, start, end; + unsigned long flags; + u8 check_pins = 1; /*first check availability of all gpio pins */ + gpio_error error = -1; + + nmdk_dbg_ftrace(); + spin_lock_irqsave(&altfun_lock, flags); + for (i = 0; i < max_altfun; i++) { + if (altfun_table[i].altfun != alt_func) + continue; + start = altfun_table[i].start; + end = altfun_table[i].end; + if (start > end) { + j = start; + start = end; + end = j; + } + if (end > GPIO_TOTAL_PINS) { + nmdk_error("range upto pin%d not suported", end); + error = GPIO_INVALID_PARAMETER; + goto exit_altfunc; + } + for (j = start; j <= end; j++) { + if (check_pins) { + if (nomadik_gpio_owner(j) && + (which_altfunc != GPIO_ALTF_DISABLE)) { + nmdk_error("pin%d not free", j); + error = -1; + goto exit_altfunc; + } + if (!nomadik_gpio_owner(j) && + (which_altfunc == GPIO_ALTF_DISABLE)) { + nmdk_error + ("Trying to disable free pin%d", j); + error = -1; + goto exit_altfunc; + } + } else { + if (which_altfunc == GPIO_ALTF_FIND) { + altfun_pinconfig.mode = + altfun_table[i].type; + } else { + altfun_pinconfig.mode = which_altfunc; + } + altfun_pinconfig.direction = GPIO_DIR_OUTPUT; + altfun_pinconfig.debounce = + GPIO_DEBOUNCE_DISABLE; + altfun_pinconfig.dev_name = dev_name; + + if (which_altfunc != GPIO_ALTF_DISABLE) { + error = + gpio_setpinconfig(j, + &altfun_pinconfig); + } else { + error = gpio_resetgpiopin(j, dev_name); + } + if (!error) + continue; + nmdk_error + ("GPIO %d configuration failure (nmdk_error:%d)", + j, error); + error = GPIO_INVALID_PARAMETER; + goto exit_altfunc; + } + } + if (altfun_table[i].cont == 0) { + /*schedule to configure if check sucessfull */ + if (check_pins) { + check_pins = 0; + i = -1; + } else { + error = 0; + goto exit_altfunc; + } + } + } + exit_altfunc: + spin_unlock_irqrestore(&altfun_lock, flags); + return (error); +} + +/** + * exported functions for other drives + */ + +/* + * Get gpio list for /proc/gpio + */ +int get_gpio_list(char *buf) +{ + struct gpio_register *p_gpio_register; + uint32 mask; + char *p = buf; + char *gpiofunc; + char *gpio_client; + int i; + + CHK_VALID_CALL; + p += sprintf(p, "Pin: %s\t%s\n", "mode", "client"); + for (i = 0; i < GPIO_TOTAL_PINS; i++) { + gpio_client = nomadik_gpio_owner(i); + if (gpio_client) { + p_gpio_register = (struct gpio_register *) + get_irq_chip_data(GPIO_PIN2BLKIRQ(i)); + mask = 1UL << (i % GPIO_PINS_PER_BLOCK); + if (irq_desc[IRQNO_GPIO(i)].action) + gpiofunc = "Irq"; + else if ((p_gpio_register->gpio_afsa & mask) + && (p_gpio_register->gpio_afsb & mask)) + gpiofunc = "AltFun_C"; + else if ((p_gpio_register->gpio_afsa & mask) + && !(p_gpio_register->gpio_afsb & mask)) + gpiofunc = "AltFun_A"; + else if (!(p_gpio_register->gpio_afsa & mask) + && (p_gpio_register->gpio_afsb & mask)) + gpiofunc = "AltFun_B"; + else + gpiofunc = "I/O"; + p += sprintf(p, "%3d: %s\t%s\n", i, + gpiofunc, gpio_client); + } + } + return p - buf; +} + +int nomadik_gpio_resetpinconfig(gpio_pin pin_id, char *dev_name) +{ + int error = 0; + + nmdk_dbg_ftrace(); + CHK_VALID_CALL; + CHK_VALID_PIN(pin_id); + + if (0 != nomadik_gpio_owner(pin_id)) + error = gpio_resetgpiopin(pin_id, dev_name); + return (error); +} + +int nomadik_gpio_setpinconfig(gpio_pin pin_id, gpio_config * pin_config) +{ + nmdk_dbg_ftrace(); + CHK_VALID_CALL; + CHK_VALID_PIN(pin_id); + if (!irq_desc[IRQNO_GPIO(pin_id)].action) { + if (nomadik_gpio_owner(pin_id)) { + nmdk_error("pin%d not available.. aquired by %s client", + pin_id, nomadik_gpio_owner(pin_id)); + return -1; + } + return (gpio_setpinconfig(pin_id, pin_config)); + } else { + nmdk_error("Cannot set gpio%d used by irq %d", pin_id, + IRQNO_GPIO(pin_id)); + return -1; + } + return 0; +} + +int nomadik_gpio_writepin(gpio_pin pin_id, gpio_data value, char *dev_name) +{ + struct gpio_register *p_gpio_register = + (struct gpio_register *)get_irq_chip_data(GPIO_PIN2BLKIRQ(pin_id)); + uint32 mask = 1UL << (pin_id % GPIO_PINS_PER_BLOCK); + + nmdk_dbg_ftrace(); + CHK_VALID_CALL; + CHK_VALID_PIN(pin_id); + if (nomadik_gpio_chkwr_permission(pin_id, dev_name)) return -1; + switch (value) { + case GPIO_DATA_HIGH: + p_gpio_register->gpio_dats = mask; + break; + case GPIO_DATA_LOW: + p_gpio_register->gpio_datc = mask; + break; + default: + nmdk_error("Invalid value passed in %s", __FUNCTION__); + return GPIO_INVALID_PARAMETER; + } + return GPIO_OK; +} + +int nomadik_gpio_readpin(gpio_pin pin_id, gpio_data * p_value) +{ + struct gpio_register *p_gpio_register = + (struct gpio_register *)get_irq_chip_data(GPIO_PIN2BLKIRQ(pin_id)); + uint32 mask = 1UL << (pin_id % GPIO_PINS_PER_BLOCK); + + nmdk_dbg_ftrace(); + CHK_VALID_CALL; + if ((p_gpio_register->gpio_dat & mask) != GPIO_ALL_ZERO) { + *p_value = GPIO_DATA_HIGH; + } else { + *p_value = GPIO_DATA_LOW; + } + return GPIO_OK; +} + +int nomadik_gpio_readblock(gpio_block_id block_id, uint32 * p_value, + uint32 mask) +{ + struct gpio_register *p_gpio_register; + + nmdk_dbg_ftrace(); + CHK_VALID_CALL; + if (GPIO_BLOCK_16_BITS_112_TO_123 < block_id) + return GPIO_INVALID_PARAMETER; + + if (GPIO_BLOCK_16_BITS_0_TO_15 > block_id) { + p_gpio_register = + (struct gpio_register *)get_irq_chip_data(block_id - + GPIO_BLOCK_32_BITS_0_TO_31 + + IRQ_GPIO0); + *p_value = p_gpio_register->gpio_dat & (mask & GPIO_32BIT_MASK); + + } else { + p_gpio_register = (struct gpio_register *) + get_irq_chip_data((block_id - + GPIO_BLOCK_16_BITS_0_TO_15) / 4 + + IRQ_GPIO0); + switch ((block_id - GPIO_BLOCK_16_BITS_0_TO_15) & 0x03) { + case 0: + *p_value = + (p_gpio_register->gpio_dat & (mask & 0x0000ffff)); + break; + case 1: + *p_value = + (p_gpio_register-> + gpio_dat & (mask & 0x00ffff00)) >> GPIO_SHIFT8; + break; + case 2: + *p_value = + (p_gpio_register-> + gpio_dat & (mask & 0xffff0000)) >> GPIO_SHIFT16; + break; + case 3: + *p_value = + (p_gpio_register-> + gpio_dat & (mask & 0xff000000)) >> GPIO_SHIFT24; + p_gpio_register += SZ_4K; /* point next bank */ + *p_value |= + (p_gpio_register-> + gpio_dat & (mask & 0x000000ff)) << GPIO_SHIFT8; + break; + } + } + return (GPIO_OK); +} + +int nomadik_gpio_writeblock(gpio_block_id block_id, uint32 p_value, uint32 mask, char *dev_name) +{ + struct gpio_register *p_gpio_register; + int i, bankno, testmask; + + nmdk_dbg_ftrace(); + CHK_VALID_CALL; + if (GPIO_BLOCK_16_BITS_112_TO_123 < block_id) + return GPIO_INVALID_PARAMETER; + + if (GPIO_BLOCK_16_BITS_0_TO_15 > block_id) { + bankno = block_id * GPIO_PINS_PER_BLOCK; + testmask = 0x01; + for (i = bankno; i < (bankno + GPIO_PINS_PER_BLOCK); i++) { + if ((mask & testmask) && + (!nomadik_gpio_chkwr_permission(i, dev_name))){ + return -1; + } + testmask = 1UL << i; + } + + p_gpio_register = + (struct gpio_register *)get_irq_chip_data(block_id - + GPIO_BLOCK_32_BITS_0_TO_31 + + IRQ_GPIO0); + p_gpio_register->gpio_datc = + ~(p_value & (mask & GPIO_32BIT_MASK)); + p_gpio_register->gpio_dats = p_value & (mask & GPIO_32BIT_MASK); + + } else { + bankno = (block_id - GPIO_BLOCK_16_BITS_0_TO_15) * 8; + testmask = 0x01; + for (i = bankno; i < (bankno + (GPIO_PINS_PER_BLOCK / 2)); i++) { + if ((mask & testmask) && + (!nomadik_gpio_chkwr_permission(i, dev_name))){ + return -1; + } + testmask = 1UL << i; + } + p_gpio_register = (struct gpio_register *) + get_irq_chip_data((block_id - + GPIO_BLOCK_16_BITS_0_TO_15) / 4 + + IRQ_GPIO0); + switch ((block_id - GPIO_BLOCK_16_BITS_0_TO_15) & 0x03) { + case 0: + p_gpio_register->gpio_datc = + ~(p_value & (mask & 0x0000ffff)); + p_gpio_register->gpio_dats = + p_value & (mask & 0x0000ffff); + break; + case 1: + p_gpio_register->gpio_datc = + ~(((p_value & mask) << GPIO_SHIFT8) & 0x00ffff00); + p_gpio_register->gpio_dats = + (((p_value & mask) << GPIO_SHIFT8) & 0x00ffff00); + break; + case 2: + p_gpio_register->gpio_datc = + ~(((p_value & mask) << GPIO_SHIFT16) & 0xffff0000); + p_gpio_register->gpio_dats = + (((p_value & mask) << GPIO_SHIFT16) & 0xffff0000); + break; + case 3: + p_gpio_register->gpio_datc = + ~(((p_value & mask) << GPIO_SHIFT24) & 0xff000000); + p_gpio_register->gpio_dats = + (((p_value & mask) << GPIO_SHIFT24) & 0xff000000); + p_gpio_register += SZ_4K; /* point next bank */ + p_gpio_register->gpio_datc = + ~(p_value & (mask & 0x000000ff)); + p_gpio_register->gpio_dats = + p_value & (mask & 0x000000ff); + break; + } + } + return (GPIO_OK); +} + +int nomadik_gpio_altfuncenable(gpio_alt_function altfunc, char *dev_name) +{ + nmdk_dbg_ftrace(); + CHK_VALID_CALL; + return (int)gpio_altfunction(altfunc, GPIO_ALTF_FIND, dev_name); +} + +int nomadik_gpio_altfuncdisable(gpio_alt_function altfunc, char *dev_name) +{ + nmdk_dbg_ftrace(); + CHK_VALID_CALL; + return (int)gpio_altfunction(altfunc, GPIO_ALTF_DISABLE, dev_name); +} + +EXPORT_SYMBOL(nomadik_gpio_setpinconfig); +EXPORT_SYMBOL(nomadik_gpio_resetpinconfig); +EXPORT_SYMBOL(nomadik_gpio_writepin); +EXPORT_SYMBOL(nomadik_gpio_readpin); +EXPORT_SYMBOL(nomadik_gpio_readblock); +EXPORT_SYMBOL(nomadik_gpio_writeblock); +EXPORT_SYMBOL(nomadik_gpio_altfuncenable); +EXPORT_SYMBOL(nomadik_gpio_altfuncdisable); + +/** + * Interrupt handling functions + */ +static void nomadik_gpio_intrenable(struct gpio_register *p_gpio_register, + uint32 mask, uint32 type) +{ + if (socdat->irqen) { + socdat->irqen(p_gpio_register, mask, type); + } else { + nmdk_error("irqen SOC specific function not configured"); + } +} + +static void nomadik_gpio_intrdisable(struct gpio_register *p_gpio_register, + uint32 mask) +{ + if (socdat->irqdis) + socdat->irqdis(p_gpio_register, mask); + else { + nmdk_error("irqdis SOC specific function not configured"); + } +} +/** + * @flag if 1 means enable, 0 means disable + */ +int nomadik_gpio_wakeupconfig(unsigned int irq, unsigned int flag) +{ + struct gpio_register *p_gpio_register = + (struct gpio_register *)get_irq_chip_data(GPIO_PINIRQ2BLKIRQ(irq)); + uint32 mask = 1UL << ((irq - MAX_CHIP_IRQ) % GPIO_PINS_PER_BLOCK); + if (flag) + p_gpio_register->gpio_fwimsc |= mask; + else + p_gpio_register->gpio_fwimsc &= (~mask); + return 0; +} +void nomadik_gpio_slpmreg_config(gpio_pin pin_id) +{ + struct gpio_register *p_gpio_register = + (struct gpio_register *)get_irq_chip_data(GPIO_PIN2BLKIRQ(pin_id)); + uint32 mask = 1UL << (pin_id % GPIO_PINS_PER_BLOCK); + p_gpio_register->gpio_slpm |= mask; +} + +static void nomadik_gpio_mask(unsigned int irq) +{ + struct gpio_register *p_gpio_register = + (struct gpio_register *)get_irq_chip_data(GPIO_PINIRQ2BLKIRQ(irq)); + uint32 mask = 1UL << ((irq - MAX_CHIP_IRQ) % GPIO_PINS_PER_BLOCK); + + nmdk_dbg_ftrace(); + nomadik_gpio_intrdisable(p_gpio_register, mask); +} + +static void nomadik_gpio_unmask(unsigned int irq) +{ + struct gpio_register *p_gpio_register = + (struct gpio_register *)get_irq_chip_data(GPIO_PINIRQ2BLKIRQ(irq)); + uint32 mask = 1UL << ((irq - MAX_CHIP_IRQ) % GPIO_PINS_PER_BLOCK); + + nmdk_dbg_ftrace(); + if (!irq_desc[irq].handler_data) { + nmdk_info + ("for irq%d, configuruing default type as rising edge", + irq); + irq_desc[irq].handler_data = (void *)SA_TRIGGER_RISING; + } + nomadik_gpio_intrenable(p_gpio_register, mask, + (uint32) irq_desc[irq].handler_data); +} + +static void nomadik_gpio_intrack(unsigned int irq) +{ + struct gpio_register *p_gpio_register = + (struct gpio_register *)get_irq_chip_data(GPIO_PINIRQ2BLKIRQ(irq)); + uint32 mask = 1UL << ((irq - MAX_CHIP_IRQ) % GPIO_PINS_PER_BLOCK); + + nmdk_dbg_ftrace(); + p_gpio_register->gpio_ic = mask; +} + +/* + * callback function for gpio specific set_irq_type sys call + * This function will be called in the context of request_irq also + */ +static int nomadik_gpio_intrsettype(unsigned int irq, unsigned int type) +{ + gpio_config settype_config; + char *client_name = nomadik_gpio_owner(GPIO_PIN_FOR_IRQ(irq)); + int ret; + + nmdk_dbg_ftrace(); + type&=SA_TRIGGER_MASK; + /* mistake proofing for invalid entry incase if you try to configure + * gpiopin interrupt for priority/fiq + */ + if ( (type == SA_TRIGGER_MASK) || + (type == (SA_TRIGGER_LOW|SA_TRIGGER_HIGH|SA_TRIGGER_RISING)) || + (type == (SA_TRIGGER_LOW|SA_TRIGGER_HIGH|SA_TRIGGER_FALLING)) || + (type == (SA_TRIGGER_LOW|SA_TRIGGER_HIGH))) { + nmdk_error("Invalid IRQ type requested for irq%d", irq); + return -1; + } + if (!irq_desc[irq].action) { + nmdk_error("Trying to set type for unrequested irq%d", irq); + } + if (irq_desc[irq].handler_data) { + nmdk_info("irq %d type already set by %s", irq, + client_name); + return (0); + } + settype_config.mode = GPIO_MODE_SOFTWARE; + settype_config.direction = GPIO_DIR_INPUT; + settype_config.debounce = GPIO_DEBOUNCE_UNCHANGED; + settype_config.dev_name = client_name; + ret = gpio_setpinconfig(GPIO_PIN_FOR_IRQ(irq), &settype_config); + if (ret < 0) { + nmdk_error("Error in setting irq %d (err %d)", irq, ret); + return (ret); + } + nmdk_dbg("set_irq_type =%d", type); + if (type) { + irq_desc[irq].handler_data = (void *)(type & SA_TRIGGER_MASK); + } else { + nmdk_info + ("%s Configuring default irq type to SA_TRIGGER_RISING", + __FUNCTION__); + irq_desc[irq].handler_data = (void *)SA_TRIGGER_RISING; + } + if ((SA_TRIGGER_RISING == (int)irq_desc[irq].handler_data) || + (SA_TRIGGER_FALLING == (int)irq_desc[irq].handler_data)) + irq_desc[irq].handle_irq = handle_edge_irq; + else if ((SA_TRIGGER_LOW == (int)irq_desc[irq].handler_data) || + (SA_TRIGGER_HIGH == (int)irq_desc[irq].handler_data)) + irq_desc[irq].handle_irq = handle_level_irq; + /* Standard api call set_irq_handler() cannot be used from + the contest of set_irq_type... deadlock occures */ + + return (GPIO_OK); +} + +/** + * callback function for enable_irq_wake and disable_irq_wake system calls + * + * @flag if 1 means enable, 0 means disable + */ +static int nomadik_gpio_intrwake(unsigned int irq, unsigned int flag) +{ + struct gpio_register *p_gpio_register = + (struct gpio_register *)get_irq_chip_data(GPIO_PINIRQ2BLKIRQ(irq)); + uint32 mask = 1UL << ((irq - MAX_CHIP_IRQ) % GPIO_PINS_PER_BLOCK); + unsigned int type = (uint32) irq_desc[irq].handler_data; + + if (socdat->irqwake) { + if (!type) + type = SA_TRIGGER_RISING; + if (!flag) + type = 0xff; /* to disable wakeup irq */ + socdat->irqwake(p_gpio_register, mask, type); + } else { + nmdk_error("irqwake SOC specific function not configured"); + return (-1); + } + return (0); +} + +struct irq_chip nomadik_gpio_chip = { + .ack = nomadik_gpio_intrack, + .mask = nomadik_gpio_mask, + .unmask = nomadik_gpio_unmask, + .set_type = nomadik_gpio_intrsettype, + .set_wake = nomadik_gpio_intrwake, +}; + +static void nomadik_gpio_intr_handler(u32 irq, struct irq_desc *desc) +{ + struct gpio_register *p_gpio_reg = + (struct gpio_register *)get_irq_chip_data(irq); + unsigned long mis = p_gpio_reg->gpio_mis; + + nmdk_dbg2("%d intr desc %p", (irq - IRQ_GPIO0), desc); + irq = IRQNO_GPIO((irq - IRQ_GPIO0) * GPIO_PINS_PER_BLOCK); + desc = irq_desc + irq; + while (mis) { + if (mis & 1) { + nmdk_dbg2("handling irq %d", irq); + desc->handle_irq(irq, desc); + } + irq++; + desc++; + mis >>= 1; + } +} + +static int nomadik_gpio_probe(struct amba_device *dev, void *id) +{ + int i, ret; + struct gpio_register *p_gpio_register; + + nmdk_dbg_ftrace(); + + socdat = dev->dev.platform_data; + + if (!socdat) { + nmdk_error("platform_data struct for %s not initialized", + dev->dev.bus_id); + ret = -1; + goto out; + } + ret = amba_request_regions(dev, NULL); + if (ret) + goto out; + + for (i = 0; i < (dev->irq[1] - dev->irq[0]); i++) { + set_irq_chip_data((i + dev->irq[0]), + (void *)ioremap((int)dev->res.start + + (i * SZ_4K), SZ_4K)); + + p_gpio_register = get_irq_chip_data(i + dev->irq[0]); + + if (!p_gpio_register) { + ret = -ENOMEM; + goto res_out; + } + + set_irq_chained_handler((i + dev->irq[0]), + nomadik_gpio_intr_handler); + } + + for (i = (MAX_GPIO_IRQ - GPIO_TOTAL_PINS); i < MAX_GPIO_IRQ; i++) { + set_irq_chip(i, &nomadik_gpio_chip); + set_irq_handler(i, handle_level_irq); + set_irq_flags(i, IRQF_VALID); + set_irq_chip_data(i, NULL); /*clear gpio client name */ + irq_desc[i].handler_data = NULL; /*clear gpio irq_type */ + } + + nmdk_info("Module initialized Ver(" GPIO_VER ")"); + return 0; + + res_out: + for (; 0 == i; i--) { + p_gpio_register = get_irq_chip_data(i + dev->irq[0]); + + set_irq_handler((i + dev->irq[0]), handle_bad_irq); + if (p_gpio_register) + iounmap((void __iomem *)p_gpio_register); + set_irq_chip_data((i + dev->irq[0]), NULL); + + } + amba_release_regions(dev); + out: + return (ret); +} + +static int nomadik_gpio_remove(struct amba_device *dev) +{ + int i; + + nmdk_dbg_ftrace(); + for (i = (MAX_GPIO_IRQ - GPIO_TOTAL_PINS); i < MAX_GPIO_IRQ; i++) { + set_irq_chip(i, NULL); + set_irq_chip_data(i, NULL); + } + + for (i = dev->irq[0]; i < dev->irq[1]; i++) { + set_irq_handler(i, handle_bad_irq); + iounmap((void __iomem *)get_irq_chip_data(i)); + set_irq_chip_data(i, NULL); + } + amba_release_regions(dev); + socdat = NULL; + nmdk_info("Module removed"); + return 0; +} + +#if (defined CONFIG_PM && defined __STN_8815) +static int nomadik_gpio_suspend(struct amba_device *dev, pm_message_t state) +{ + unsigned int i; + struct gpio_register *p_gpio_register; + struct gpio_pm_context *gpio_pm;; + + nmdk_dbg_ftrace(); + dev->dev.driver_data = + kmalloc(sizeof(struct gpio_pm_context) * GPIO_BLOCKS_COUNT, + GFP_KERNEL); + gpio_pm = (struct gpio_pm_context *)dev->dev.driver_data; + if (!gpio_pm) { + nmdk_error("Unable to alocate memory %s failed...", + __FUNCTION__); + } + for (i = 0; i < GPIO_BLOCKS_COUNT; i++) { + p_gpio_register = + (struct gpio_register *)get_irq_chip_data(i + dev->irq[0]); + gpio_pm[i].slpm = p_gpio_register->gpio_slpm; + gpio_pm[i].rwimsc = p_gpio_register->gpio_rwimsc; + gpio_pm[i].fwimsc = p_gpio_register->gpio_fwimsc; + gpio_pm[i].rimsc = p_gpio_register->gpio_rimsc; + gpio_pm[i].fimsc = p_gpio_register->gpio_fimsc; + } + return 0; +} + +static int nomadik_gpio_resume(struct amba_device *dev) +{ + unsigned int i; + struct gpio_register *p_gpio_register; + struct gpio_pm_context *gpio_pm = + (struct gpio_pm_context *)dev->dev.driver_data; + + nmdk_dbg_ftrace(); + for (i = 0; i < GPIO_BLOCKS_COUNT; i++) { + p_gpio_register = + (struct gpio_register *)get_irq_chip_data(i + dev->irq[0]); + p_gpio_register->gpio_slpm = gpio_pm[i].slpm; + p_gpio_register->gpio_rwimsc = gpio_pm[i].rwimsc; + p_gpio_register->gpio_fwimsc = gpio_pm[i].fwimsc; + p_gpio_register->gpio_rimsc = gpio_pm[i].rimsc; + p_gpio_register->gpio_fimsc = gpio_pm[i].fimsc; + } + kfree(gpio_pm); + return 0; +} +#else +#define nomadik_gpio_suspend NULL +#define nomadik_gpio_resume NULL +#endif + +static struct amba_id nomadik_gpio_ids[] = { + { + .id = GPIO_PER_ID, + .mask = GPIO_PER_MASK, + }, + {0, 0}, +}; + +static struct amba_driver gpio_driver = { + .drv = { + .owner = THIS_MODULE, + .name = "gpio", + }, + .probe = nomadik_gpio_probe, + .remove = nomadik_gpio_remove, + .suspend = nomadik_gpio_suspend, + .resume = nomadik_gpio_resume, + .id_table = nomadik_gpio_ids, +}; + +static int __init nomadik_gpio_init(void) +{ + return amba_driver_register(&gpio_driver); +} + +static void __exit nomadik_gpio_exit(void) +{ + amba_driver_unregister(&gpio_driver); +} + +EXPORT_SYMBOL(nomadik_gpio_intrsettype); +EXPORT_SYMBOL(nomadik_gpio_mask); +EXPORT_SYMBOL(nomadik_gpio_unmask); + +module_init(nomadik_gpio_init); +module_exit(nomadik_gpio_exit); + +MODULE_AUTHOR("Prafulla WADASKAR "); +MODULE_DESCRIPTION("Nomadik GPIO Driver"); +MODULE_LICENSE("GPL"); --- /dev/null +++ linux-2.6.20/arch/arm/mach-nomadik/irq.c @@ -0,0 +1,231 @@ +/* + * linux/arch/arm/mach-nomadik/irq.c + * + * Copyright (C) STMicroelectronics + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Author : Prafulla WADASKAR + * Reference : Documentation/arm/STM-Nomadik/irq_usrguide.txt + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define VIC_VER "2.0.0" +#define VIC_NAME "VIC" + +#ifndef VIC_DEBUG +#define VIC_DEBUG 0 +#endif + +#define NMDK_DEBUG VIC_DEBUG /* enables/disables nmdk_dbg msgs */ +#define NMDK_DEBUG_PFX VIC_NAME /* msg header represents this module */ +#define NMDK_DBG KERN_ERR /* message level */ + +struct vic_basic_registers { + u32 irqsr; /* IRQ Status*/ + u32 fiqsr; /* FIQ Status*/ + u32 ris; /* Raw Interrupt status*/ + u32 isel; /* Interrupt select*/ + u32 iens; /* Interrupt enable set*/ + u32 ienc; /* Interrupt enable clear*/ + u32 swisr; /* Software interrupt*/ + u32 swicr; /* Software interrupt clear*/ +}; + +struct vic_register { + struct vic_basic_registers bank[(MAXIRQNUM/32) +1]; + u32 per; /* Protection enable*/ +#if defined(__STN_8815) + u32 reserved_1[(0x50 - 0x44) >> 2]; /* Reserved*/ + u32 isr_var; /* ISR Vector address*/ + u32 isr_dvar; /* ISR Default vector address*/ + u32 reserved_2[(0x100 - 0x58) >> 2]; /* Reserved*/ +#elif defined(__STN_8810) + u32 reserved_1[(0x30 - 0x24) >> 2]; /* Reserved*/ + u32 isr_var; /* ISR Vector address*/ + u32 isr_dvar; /* ISR Default vector address*/ + u32 reserved_2[(0x100 - 0x38) >> 2]; /* Reserved*/ +#endif + u32 var[VIC_VECTORED_IRQ_NUM]; /* Vector address 0-15*/ + u32 reserved_3[(0x200 - 0x140) >> 2]; /* Reserved*/ + u32 vcr[VIC_VECTORED_IRQ_NUM]; /* Vector control 0-15*/ + u32 reserved_4[(0x300 - 0x240) >> 2]; /* Reserved*/ + u32 itcr; /* Test Control register*/ + u32 itip_1; /* Test input nVICIRQIN/nVICFIQIN*/ + u32 itip_2; /* Test input VICVECADDRIN*/ + u32 itop_1; /* Test output nVICIRQ/nVICFIQ*/ + u32 itop_2; /* Test output VICVECADDROUT*/ + u32 reserved_5[(0xFE0 - 0x314) >> 2]; /* Reserved*/ + u32 periph_id_0; /* Peripheral id: bits 7:0*/ + u32 periph_id_1; /* Peripheral id: bits 15:8*/ + u32 periph_id_2; /* Peripheral id: bits 23:16*/ + u32 periph_id_3; /* Peripheral id: bits 31:24*/ + u32 pcell_id_0; /* PrimeCell id: bits 7:0*/ + u32 pcell_id_1; /* PrimeCell id: bits 15:8*/ + u32 pcell_id_2; /* PrimeCell id: bits 23:16*/ + u32 pcell_id_3; /* PrimeCell id: bits 31:24*/ +}; + +extern struct irq_desc irq_desc[]; /* interrupt description table */ +static volatile struct vic_register *p_vic_register = + (struct vic_register *)IO_ADDRESS(NOMADIK_IC_BASE); + +static int nomadik_vic_set_type(unsigned int irq, unsigned int type); +static DEFINE_SPINLOCK(vic_lock); + +static void nomadik_vic_priority_mask(unsigned int irq) +{ + u8 priority_level = (u8)(((irq_desc[irq].action->flags)>>4) & 0x0f); + u32 mask = 1UL<vcr[priority_level] &= ~VIC_VECTORED_IRQ_EN; + p_vic_register->bank[irq/32].ienc |= mask; +} + +static void nomadik_vic_priority_unmask(unsigned int irq) +{ + u8 priority_level = (u8)(((irq_desc[irq].action->flags)>>4) & 0x0f); + u32 mask = 1UL<vcr[priority_level] |= VIC_VECTORED_IRQ_EN; + p_vic_register->bank[irq/32].iens |= mask; + /* + * Write to the VIC_VAR register. + * This clears the respective interrupt in the internal interrupt + * priority hardware. + */ + p_vic_register->isr_var = (u32)NULL; +} + +static struct irq_chip nomadik_vic_priority_chip = { + .ack = nomadik_vic_priority_mask, + .mask = nomadik_vic_priority_mask, + .unmask = nomadik_vic_priority_unmask, + .set_type = nomadik_vic_set_type +}; + +static void nomadik_vic_mask(unsigned int irq) +{ + u32 mask = 1UL<bank[irq/32].ienc |= mask; +} + +static void nomadik_vic_unmask(unsigned int irq) +{ + u32 mask = 1UL<bank[irq/32].iens |= mask; +} + +static struct irq_chip nomadik_vic_chip = { + .ack = nomadik_vic_mask, + .mask = nomadik_vic_mask, + .unmask = nomadik_vic_unmask, + .set_type = nomadik_vic_set_type +}; + +/** + * nomadik_vic_set_type - To enable/disable/change priority logic + * + * callback function for set_irq_type sys call + * This function will be called in the context of request_irq. + * This function is used to configure the interrupt priotity requested + * through request_irq sytem call + * + * This function can be invoked by set_irq_type sys call ,using which + * you can enable/disable/change preprogrammed priority + * + * Note: this function will NOT be invoked if interrupt is requested as + * shared irq (i.e. SA_SHIRQ is specifed during requerst_irq), + */ +static int nomadik_vic_set_type(unsigned int irq, unsigned int type) +{ + struct irq_desc *desc; + struct irq_chip *vic_chip; + unsigned long flags; + + u8 priority_level; + + nmdk_dbg_ftrace(); + if (!irq_desc[irq].action) return(-1); /*if irq not configured*/ + /* + * Priority logic does not work for interrupt configured with + * SA_TIMER flag, hence exit if SA_TIMER flag is set for irq + */ + if (irq_desc[irq].action->flags & IRQF_TIMER) return(-1); + if ((type & SA_NMDK_PRIORITYIRQ) != SA_NMDK_PRIORITYIRQ) return(-1); + /* + * if this function is invoked by set_irq_type call + * then store input type as flags + */ + if (type > SA_TRIGGER_MASK) irq_desc[irq].action->flags = type; + /*process irq priority configuration*/ + priority_level = (u8)(((irq_desc[irq].action->flags)>>24) & 0x0f); + if (p_vic_register->vcr[priority_level] & VIC_VECTORED_IRQ_EN) { + nmdk_info("priority change for active irq%d", irq); + } + /*configure vic for vectored priority interrupt request*/ + p_vic_register->var[priority_level] = irq; + p_vic_register->vcr[priority_level] = irq; + /* configure appropriate chip pointer*/ + desc = irq_desc + irq; + if (!priority_level) { + p_vic_register->vcr[priority_level] &= ~VIC_VECTORED_IRQ_EN; + vic_chip = &nomadik_vic_chip; + } else + vic_chip = &nomadik_vic_priority_chip; + spin_lock_irqsave(&vic_lock, flags); + desc->chip = vic_chip; + spin_unlock_irqrestore(&vic_lock, flags); + + nmdk_info("Configured PL%2d for irq%d", priority_level, irq); + return (0); +} + +static void nomadik_vic_configure(unsigned int irq) +{ + u32 mask = 1UL<bank[irq/32].isel &= ~mask; +} + +void __init nomadik_vic_init(void) +{ + unsigned int i; + + nmdk_dbg_ftrace(); + /*force default isr value to zero*/ + p_vic_register->isr_dvar = (u32)NULL; + for (i = 0; i < MAX_CHIP_IRQ; i++) { + if (1ULL<vcr[i] = (u32)NULL; + p_vic_register->var[i] = (u32)NULL; + } + } + nmdk_info("Module initialized Ver("VIC_VER")"); +} --- /dev/null +++ linux-2.6.20/arch/arm/mach-nomadik/l2cc.c @@ -0,0 +1,152 @@ +/* + * linux/arch/arm/mach-nomadik/stn8815_devices.c + * + * Copyright (C) STMicroelectronics + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2, as + * published by the Free Software Foundation. + * + * SOC specifc drivers whcih are used as amba devices + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#define L210_CACHE_SYNC 0x730 +#define L210_INV_LINE_PA 0x770 +#define L210_INV_WAY 0x77C +#define L210_CLEAN_LINE_PA 0x7B0 +#define L210_CLEAN_LINE_IDX 0x7B8 +#define L210_CLEAN_WAY 0x7BC +#define L210_CLEAN_INV_LINE_PA 0x7F0 +#define L210_CLEAN_INV_LINE_IDX 0x7F8 +#define L210_CLEAN_INV_WAY 0x7FC + +static void __iomem *l210_base = (void __iomem *)IO_ADDRESS(NOMADIK_L2CC_BASE); +static unsigned long way_size = 0x4000; + +static inline void sync_writel(unsigned long val, unsigned long reg, + unsigned long complete_mask) +{ + writel(val, l210_base + reg); + /* wait for the operation to complete not required for l210 controller */ + //while (readl(l210_base + reg) & complete_mask); +} + +static inline void cache_sync(void) +{ + sync_writel(0, L210_CACHE_SYNC, 1); +} + +static inline void cacheline_index_op(unsigned long addr, unsigned long reg) +{ + unsigned long way, index; + + for (way = 0; way < 8; way++) + for (index = 0; index < way_size; index += PAGE_SIZE) { + unsigned long val = (way << 29) | index | (addr & (PAGE_SIZE - 1)); + sync_writel(val, reg, 1); + } +} + +inline void l210_inv_all(void) +{ + /* invalidate all ways */ + sync_writel(0xff, L210_INV_WAY, 0xff); + cache_sync(); +} +EXPORT_SYMBOL(l210_inv_all); + +inline void l210_clean_all(void) +{ + /* clean all ways */ + sync_writel(0xff, L210_CLEAN_WAY, 0xff); + cache_sync(); +} +EXPORT_SYMBOL(l210_clean_all); + +inline void l210_flush_all(void) +{ + /* clean and invalidate all ways */ + sync_writel(0xff, L210_CLEAN_INV_WAY, 0xff); + cache_sync(); +} +EXPORT_SYMBOL(l210_flush_all); + +void l210_inv_range(unsigned long start, unsigned long end) +{ + l210_inv_all(); +} +EXPORT_SYMBOL(l210_inv_range); + +void l210_clean_range(unsigned long start, unsigned long end) +{ + unsigned long size = end - start; + unsigned long addr; + + if (size >= PAGE_SIZE) { + l210_clean_all(); + return; + } + + /* no physical address information, flush by index/way */ + for (addr = start & ~(32 - 1); addr < end; addr += 32) + cacheline_index_op(addr, L210_CLEAN_LINE_IDX); + cache_sync(); +} +EXPORT_SYMBOL(l210_clean_range); + + +void l210_flush_range(unsigned long start, unsigned long end) +{ + unsigned long addr,way,val; + + //printk("\nl2 flushing hit\n"); + /* no physical address information, flush by index/way */ + for (addr = start & ~(32 - 1); addr < end; addr += 32) + cacheline_index_op(addr, L210_CLEAN_INV_LINE_IDX); + + /*for (addr = start; addr < end; addr += 32) { + for (way = 0; way < 8; way++) { + //val = (way << 29) | ((addr & 0x1ff) << 5); + val = (way << 29) | (addr << 5); + sync_writel(val, L220_CLEAN_INV_LINE_IDX, 1); + } + }*/ + cache_sync(); +} +EXPORT_SYMBOL(l210_flush_range); --- /dev/null +++ linux-2.6.20/arch/arm/mach-nomadik/msp.c @@ -0,0 +1,2062 @@ +/* + * Driver for Nomadik STN8810/STN8815 MSP device. + * + * Copyright 2006 STMicroelectronics Pvt. Ltd. + * + * This program is free sofstware; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#if (defined(CONFIG_NOMADIK_SPI) || defined(CONFIG_NOMADIK_SPI_MODULE)) +#include +#include +#endif + +#include + +#include "msp.h" + +#ifndef MSP_DEBUG +#define MSP_DEBUG 0 +#endif + +#define NMDK_MSP_NAME "NOMADIK_MSP" + +#define NMDK_DEBUG MSP_DEBUG /* enables/disables nmdk_dbg msgs */ +#define NMDK_DEBUG_PFX NMDK_MSP_NAME /* msg header represents this module */ +#define NMDK_DBG KERN_ERR /* message level */ + +char MSP_NAME[] = "msp"; + +static volatile struct msp_register *registers[MSP_COUNT] = { + (struct msp_register *)IO_ADDRESS(NOMADIK_MSP0_BASE), +#if MSP_COUNT > 1 + (struct msp_register *)IO_ADDRESS(NOMADIK_MSP1_BASE), +#endif +#if MSP_COUNT > 2 + (struct msp_register *)IO_ADDRESS(NOMADIK_MSP2_BASE), +#endif +}; + +static int altfunc[MSP_COUNT] = { + GPIO_ALT_MSP_0, +#if MSP_COUNT > 1 + GPIO_ALT_MSP_1, +#endif +#if MSP_COUNT > 2 + GPIO_ALT_MSP_2, +#endif +}; +static int msp_irq = IRQ_MSP0; + +static wait_queue_head_t wait[MSP_COUNT]; +static volatile int msp_io_error[MSP_COUNT]; + +static struct msp_context msp_context[MSP_COUNT]; + +static struct msp_mode_status tx_status[MSP_COUNT]; +static struct msp_mode_status rx_status[MSP_COUNT]; + +static u32 input_clock[MSP_COUNT]; +static u32 spi_clock_mode[MSP_COUNT]; +static u32 spi_burst_mode[MSP_COUNT]; + +/*Usage Flag for MSPs*/ +msp_flag *flag_msp0, *flag_msp1, *flag_msp2; + +static const struct msp_protocol_desc protocol_desc_tab[] = /* Protocol desciptors */ +{ + I2S_PROTOCOL_DESC, + /* PCM_PROTOCOL_DESC */ + { + MSP_SINGLE_PHASE, + MSP_FRAME_LENGTH_1, + MSP_FRAME_LENGTH_1, + MSP_ELEM_LENGTH_16, + MSP_ELEM_LENGTH_16, + /*below three settings are platform specific */ + MSP_DATA_DELAY, + MSP_TX_CLOCK_EDGE, + MSP_RX_CLOCK_EDGE}, + PCM_COMPAND_PROTOCOL_DESC, + AC97_PROTOCOL_DESC, + SPI_MASTER_PROTOCOL_DESC, + SPI_SLAVE_PROTOCOL_DESC +}; +/* local functions */ +static irqreturn_t handle_irq(int irq, void *dev_id); +static int transmit_data(int msp, void *data, size_t bytes); +static int receive_data(int msp, void *data, size_t bytes); +static int transmit_receive_data(int msp, int work_mode, + void *txdata, size_t txbytes, void *rxdata, + size_t rxbytes); +static int configure_clock(int msp, int protocol, u32 input_clock, + u32 frame_freq, int frame_size); +static int configure_protocol(int msp, int protocol, int direction, + enum msp_data_size data_size); + + +/** + * nomadik_msp_configure - configures the MSP controller + * @msp - specifies the msp controller to configure. + * @config - specifies the configuration parameters. + */ +int nomadik_msp_configure(int msp, struct msp_generic_config *config, t_msp_user user) +{ + u32 old_reg; + u32 new_reg; + u32 mask; + int status = 0; + + if (msp < 0 || msp > MSP_COUNT) { + printk(KERN_ERR "Invalid msp specified:%d\n", msp); + return -EINVAL; + } + nmdk_dbg("In nomadik_msp_configure, flag_msp0 is %d, user is %d\n", flag_msp0->user, user); + nmdk_dbg("In nomadik_msp_configure, flag_msp1 is %d\n", flag_msp1->user); + nmdk_dbg("In nomadik_msp_configure, flag_msp2 is %d\n", flag_msp2->user); + + switch(msp) { + case 0: if((flag_msp0->user != MSP_NO_USER) && (flag_msp0->user != user)){ + status = -EINVAL; + printk(KERN_ERR "MSP0 already in use in %d mode", flag_msp0->user); + } + else { + down(&flag_msp0->lock); + flag_msp0->user = user; + up(&flag_msp0->lock); + } + break; + case 1: if((flag_msp1->user != MSP_NO_USER) && (flag_msp1->user != user)){ + status = -EINVAL; + printk(KERN_ERR "MSP1 already in use in %d mode", flag_msp1->user); + } + else { + down(&flag_msp1->lock); + flag_msp1->user = user; + up(&flag_msp1->lock); + } + break; + case 2: if((flag_msp2->user != MSP_NO_USER) && (flag_msp2->user != user)){ + status = -EINVAL; + printk(KERN_ERR "MSP2 already in use in %d mode", flag_msp2->user); + } + else + down(&flag_msp2->lock); + flag_msp2->user = user; + up(&flag_msp2->lock); + break; + } + if(status) { + printk(KERN_ERR "Error in setting flag bit for MSP\n"); + return status; + } + + /* First do the global config register */ + mask = + RX_CLK_SEL_MASK | TX_CLK_SEL_MASK | RX_FRAME_SYNC_MASK | + TX_FRAME_SYNC_MASK | RX_SYNC_SEL_MASK | TX_SYNC_SEL_MASK | + RX_FIFO_ENABLE_MASK | TX_FIFO_ENABLE_MASK | SRG_CLK_SEL_MASK; + + new_reg = + (config->tx_clock_sel | config->rx_clock_sel | config-> + rx_frame_sync_pol | config->tx_frame_sync_pol | config-> + rx_frame_sync_sel | config->tx_frame_sync_sel | config-> + rx_fifo_config | config->tx_fifo_config | config->srg_clock_sel); + + old_reg = (registers[msp]->global_ctrl); + old_reg &= ~mask; + old_reg |= new_reg; + (registers[msp]->global_ctrl) = old_reg; + + /* Now do the tx_config and rx_config registers */ + old_reg = registers[msp]->rx_config; + mask = MSP_NON_MODE_BIT_MASK; + new_reg = config->rx_endianess | config->rx_unexpect_frame_sync; + old_reg &= ~mask; + old_reg |= new_reg; + (registers[msp]->rx_config) = old_reg; + old_reg = registers[msp]->tx_config; + new_reg = config->tx_endianess | config->tx_unexpect_frame_sync; + old_reg &= ~mask; + old_reg |= new_reg; + (registers[msp]->tx_config) = old_reg; + + /* Set global input clock and spi clock mode, needed by other config ops */ + + input_clock[msp] = config->input_clock_freq; + spi_clock_mode[msp] = config->spi_clk_mode; + spi_burst_mode[msp] = config->spi_burst_mode; + return 0; +} + +/** + * nomadik_msp_enable - Enable the msp controller with given configuration + * @msp - specifies the msp controller + * @direction - specifies the transmit/receive direction + * @work_mode - specifies DMA/Interrupt/Polling mode + * @protocol - Either PCM/I2S + * @frame_freq - specifies the frequency. + * @frame_size - specifies frame size + * @data_size - specifies element size + */ +int nomadik_msp_enable(int msp, int direction, int work_mode, int protocol, + int frame_freq, int frame_size, + enum msp_data_size data_size, t_msp_user user) +{ + int status = 0; + int skip_irq; + if (msp < 0 || msp > MSP_COUNT) { + printk(KERN_ERR "Invalid msp specified:%d\n", msp); + return -EINVAL; + } + + nmdk_dbg("In nomadik_msp_enable, flag_msp0 is %d, user is %d\n", flag_msp0->user, user); + switch(msp) { + case 0: if(flag_msp0->user != user) { + status = -EINVAL; + printk(KERN_ERR "MSP0 not usable in Non SPI mode\n"); + } + break; + case 1: if(flag_msp1->user != user) { + status = -EINVAL; + printk(KERN_ERR "MSP1 not usable in Non SPI mode\n"); + } + break; + case 2: if(flag_msp2->user != user) { + status = -EINVAL; + printk(KERN_ERR "MSP2 not usable in Non SPI mode\n"); + } + break; + } + if(status) { + printk(KERN_ERR "Error in setting flag bit for MSP, status is %d\n", status); + return status; + } + + skip_irq = (registers[msp]->global_ctrl) & (TX_ENABLE | RX_ENABLE); + + if(!skip_irq) { + switch (msp) { + case 0: + status = nomadik_gpio_altfuncenable(altfunc[msp], "MSP_0"); + break; + case 1: + status = nomadik_gpio_altfuncenable(altfunc[msp], "MSP_1"); + break; + case 2: + status = nomadik_gpio_altfuncenable(altfunc[msp], "MSP_2"); + break; + } + if (status) { + printk(KERN_ERR "Error in nomadik_gpio_altfuncenable, status is %d\n", status); + return status; + } + } + + /* Store context data for power management */ + msp_context[msp].direction = direction; + msp_context[msp].mode = work_mode; + msp_context[msp].protocol = protocol; + msp_context[msp].frame_freq = frame_freq; + msp_context[msp].frame_size = frame_size; + msp_context[msp].requested_data_size = data_size; + + /* Configure msp with protocol dependent settings */ + configure_protocol(msp, protocol, direction, data_size); + + configure_clock(msp, protocol, input_clock[msp], frame_freq, + frame_size); + + switch (direction) { + case MSP_TRANSMIT_MODE: + registers[msp]->irq_mask |= TRANSMIT_UNDERRUN_ERR_INT; + if (work_mode == MSP_DMA_MODE) { + registers[msp]->dma_ctrl |= TX_DMA_ENABLE; + } + + tx_status[msp].work_mode = work_mode; + if (protocol == MSP_I2S_PROTOCOL) { + tx_status[msp].stereo_mode = MSP_STEREO; + } else { + tx_status[msp].stereo_mode = MSP_MONO; + } + + (registers[msp]->global_ctrl) &= ~RX_ENABLE; + (registers[msp]->global_ctrl) |= TX_ENABLE; + break; + case MSP_RECEIVE_MODE: + registers[msp]->irq_mask |= RECEIVE_OVERRUN_ERROR_INT; + if (work_mode == MSP_DMA_MODE) { + registers[msp]->dma_ctrl |= RX_DMA_ENABLE; + } + + rx_status[msp].work_mode = work_mode; + if (protocol == MSP_I2S_PROTOCOL) { + rx_status[msp].stereo_mode = MSP_STEREO; + } else { + rx_status[msp].stereo_mode = MSP_MONO; + } + + (registers[msp]->global_ctrl) |= RX_ENABLE; + (registers[msp]->global_ctrl) &= ~TX_ENABLE; + break; + case MSP_BOTH_T_R_MODE: + registers[msp]->irq_mask |= + TRANSMIT_UNDERRUN_ERR_INT | RECEIVE_OVERRUN_ERROR_INT; + if (work_mode == MSP_DMA_MODE) { + registers[msp]->dma_ctrl |= + TX_DMA_ENABLE | RX_DMA_ENABLE; + } + + tx_status[msp].work_mode = work_mode; + rx_status[msp].work_mode = work_mode; + if (protocol == MSP_I2S_PROTOCOL) { + tx_status[msp].stereo_mode = MSP_STEREO; + rx_status[msp].stereo_mode = MSP_STEREO; + } else { + tx_status[msp].stereo_mode = MSP_MONO; + rx_status[msp].stereo_mode = MSP_MONO; + } + + (registers[msp]->global_ctrl) |= RX_ENABLE; + (registers[msp]->global_ctrl) |= TX_ENABLE; + break; + default: + printk(KERN_ERR "Invalid direction parameter\n"); + return -EINVAL; + } + + /* enable frame generation logic */ + (registers[msp]->global_ctrl) |= FRAME_GEN_ENABLE; + msp_context[msp].msp_disable = 0; + if (!skip_irq) { + status = request_irq(msp_irq, handle_irq, + SA_INTERRUPT | SA_SHIRQ, MSP_NAME, + (void *)registers[msp]); + if(status) + printk(KERN_ERR "Error while request_irq, err is %d\n", status); + } + return status; +} + +void nomadik_msp_flush_input(int msp) +{ + u32 dummy; + while (!(registers[msp]->status & RX_FIFO_EMPTY)) { + dummy = registers[msp]->fifo; + } +} + +int nomadik_msp_send_data(int msp, void *data, size_t bytes) +{ + int status; + + if (msp < 0 || msp > MSP_COUNT) { + printk(KERN_ERR "Invalid msp specified:%d\n", msp); + return -EINVAL; + } + + if (!((registers[msp]->global_ctrl) & TX_ENABLE)) { + printk(KERN_ERR + "Trying to transmit with transmit not enabled\n"); + return -EPERM; + } + + switch (tx_status[msp].work_mode) { + case MSP_DMA_MODE: + printk(KERN_WARNING "Function not authorized in DMA mode\n"); + return -ENOSYS; + break; + case MSP_POLLING_MODE: + case MSP_INTERRUPT_MODE: + status = transmit_data(msp, data, bytes); + break; + default: + printk(KERN_ERR "tx work mode invalid: %d\n", + tx_status[msp].work_mode); + return -EINVAL; + break; + } + + return status; +} + +int nomadik_msp_receive_data(int msp, void *data, size_t bytes) +{ + int status; + + if (msp < 0 || msp > MSP_COUNT) { + printk(KERN_ERR "Invalid msp specified:%d\n", msp); + return -EINVAL; + } + + if (!((registers[msp]->global_ctrl) & RX_ENABLE)) { + printk(KERN_ERR "Trying to receive with receive not enabled\n"); + return -EPERM; + } + + switch (rx_status[msp].work_mode) { + case MSP_DMA_MODE: + printk(KERN_WARNING "Function not authorized in DMA mode\n"); + return -ENOSYS; + break; + case MSP_POLLING_MODE: + case MSP_INTERRUPT_MODE: + status = receive_data(msp, data, bytes); + break; + default: + printk(KERN_ERR "rx work mode invalid: %d\n", + rx_status[msp].work_mode); + return -EINVAL; + break; + } + + return status; +} + +int nomadik_msp_transceive_data(int msp, void *txdata, size_t txbytes, + void *rxdata, size_t rxbytes) +{ + int status; + + if (msp < 0 || msp > MSP_COUNT) { + printk(KERN_ERR "Invalid msp specified:%d\n", msp); + return -EINVAL; + } + + if (!((registers[msp]->global_ctrl) & RX_ENABLE)) { + printk(KERN_ERR "Trying to receive with receive not enabled\n"); + return -EPERM; + } + + if (!((registers[msp]->global_ctrl) & TX_ENABLE)) { + printk(KERN_ERR + "Trying to transmit with transmit not enabled\n"); + return -EPERM; + } + + if (tx_status[msp].work_mode != rx_status[msp].work_mode) { + printk(KERN_ERR "Inconsistent transmit/reveive modes\n"); + return -EINVAL; + } + + switch (tx_status[msp].work_mode) { + case MSP_DMA_MODE: + printk(KERN_WARNING "Function not authorized in DMA mode\n"); + return -ENOSYS; + break; + case MSP_POLLING_MODE: + case MSP_INTERRUPT_MODE: + status = transmit_receive_data(msp, tx_status[msp].work_mode, + txdata, txbytes, + rxdata, rxbytes); + break; + default: + printk(KERN_ERR "work mode invalid: %d\n", + tx_status[msp].work_mode); + return -EINVAL; + break; + } + + return status; +} + +static int nomadik_msp_wait_for_tx_complete(int msp) +{ + while (!(registers[msp]->status & TX_FIFO_EMPTY)); + return 0; +} + +/** + * nomadik_msp_disable - disable the given msp controller + * @msp - specifies the msp contoller + * @direction - specifies the transmit/receive direction + */ +int nomadik_msp_disable(int msp, int direction, t_msp_user user) +{ + int status = 0; + if (msp < 0 || msp > MSP_COUNT) { + printk(KERN_ERR "Invalid msp specified:%d\n", msp); + return -EINVAL; + } + + nmdk_dbg("In nomadik_msp_disable, flag_msp0 is %d, user is %d\n", flag_msp0->user, user); + /*Set global flag to free state*/ + switch(msp) { + case 0: if(flag_msp0->user == user) { + down(&flag_msp0->lock); + flag_msp0->user = MSP_NO_USER; + up(&flag_msp0->lock); + nmdk_dbg("Flag cleanup for MSP0\n"); + } + else { + nmdk_dbg("Trying to free MSP from NON-SPI-mode , already configured in mode%d\n", flag_msp0->user); + status = -EFAULT; + } + break; + case 1: if(flag_msp1->user == user) { + down(&flag_msp1->lock); + flag_msp1->user = MSP_NO_USER; + up(&flag_msp1->lock); + nmdk_dbg("Flag cleanup for MSP1\n"); + } + else { + nmdk_dbg("Trying to free MSP from NON-SPI-mode , already configured in mode%d\n", flag_msp1->user); + status = -EFAULT; + } + break; + case 2: if(flag_msp2->user == user) { + down(&flag_msp2->lock); + flag_msp2->user = MSP_NO_USER; + up(&flag_msp2->lock); + nmdk_dbg("Flag cleanup for MSP2\n"); + } + else { + nmdk_dbg("Trying to free MSP from NON-SPI-mode , already configured in mode%d\n", flag_msp2->user); + status = -EFAULT; + } + break; + } + if(status) + return status; + + if (!(registers[msp]->global_ctrl & (TX_ENABLE | RX_ENABLE))) { + goto disable_alt; + } + + if (direction != MSP_RECEIVE_MODE) { + int status = nomadik_msp_wait_for_tx_complete(msp); + if (status) { + goto disable_alt; + } + } + switch (direction) { + case MSP_RECEIVE_MODE: + registers[msp]->global_ctrl &= ~RX_ENABLE; + registers[msp]->dma_ctrl &= ~RX_DMA_ENABLE; + registers[msp]->irq_mask &= ~(RECEIVE_SERVICE_INT | + RECEIVE_OVERRUN_ERROR_INT); + rx_status[msp].flow_error_count = 0; + break; + case MSP_TRANSMIT_MODE: + registers[msp]->global_ctrl &= ~TX_ENABLE; + registers[msp]->dma_ctrl &= ~TX_DMA_ENABLE; + registers[msp]->irq_mask &= ~(TRANSMIT_SERVICE_INT | + TRANSMIT_UNDERRUN_ERR_INT); + tx_status[msp].flow_error_count = 0; + break; + case MSP_BOTH_T_R_MODE: + registers[msp]->global_ctrl &= ~(TX_ENABLE | RX_ENABLE); + registers[msp]->dma_ctrl &= ~(TX_DMA_ENABLE | RX_DMA_ENABLE); + registers[msp]->irq_mask &= ~ALL_INT; + tx_status[msp].flow_error_count = 0; + rx_status[msp].flow_error_count = 0; + break; + default: + printk(KERN_ERR "Invalid direction param\n"); + status = -EINVAL; + goto disable_alt; + } + + msp_context[msp].msp_disable = 1; + + if (!(registers[msp]->global_ctrl & (TX_ENABLE | RX_ENABLE))) { + /* disable sample rate and frame generators */ + registers[msp]->global_ctrl &= ~(FRAME_GEN_ENABLE | SRG_ENABLE); + + free_irq(msp_irq, (void *)registers[msp]); + } + + +disable_alt: + switch (msp) { + case 0: + nomadik_gpio_altfuncdisable(altfunc[msp], "MSP_0"); + break; + case 1: + nomadik_gpio_altfuncdisable(altfunc[msp], "MSP_1"); + break; + case 2: + nomadik_gpio_altfuncdisable(altfunc[msp], "MSP_2"); + break; + } + + return status; +} + +static int configure_protocol(int msp, int protocol, int direction, + enum msp_data_size data_size) +{ + u32 temp_reg; + + if ((protocol < 0) || (protocol >= MSP_INVALID_PROTOCOL)) { + printk(KERN_ERR + "invalid protocol requested in configure_protocol()\n"); + return -EINVAL; + } + + if (data_size < MSP_DATA_SIZE_DEFAULT + || data_size > MSP_DATA_SIZE_32BIT) { + printk(KERN_ERR + "invalid data size requested in configure_protocol()\n"); + return -EINVAL; + } + + switch (direction) { + case MSP_TRANSMIT_MODE: + tx_status[msp].phase_mode = + protocol_desc_tab[protocol].phase_mode; + + /* Use a temp for setup. Clear everything except the two non-mode + * dependent bits, then add back the bits for the selected protocol + */ + temp_reg = (registers[msp]->tx_config) & MSP_NON_MODE_BIT_MASK; + + temp_reg |= + msp_p2_enable_bit(protocol_desc_tab[protocol].phase_mode); + temp_reg |= + msp_p1_frame_len_bits(protocol_desc_tab[protocol]. + frame_len_1); + temp_reg |= + msp_p2_frame_len_bits(protocol_desc_tab[protocol]. + frame_len_2); + if (data_size == MSP_DATA_SIZE_DEFAULT) { + temp_reg |= + msp_p1_elem_len_bits(protocol_desc_tab[protocol]. + element_len_1); + temp_reg |= + msp_p2_elem_len_bits(protocol_desc_tab[protocol]. + element_len_2); + if (protocol_desc_tab[protocol].element_len_1 == + protocol_desc_tab[protocol].element_len_2) { + msp_context[msp].actual_data_size = + protocol_desc_tab[protocol].element_len_1; + } else { + msp_context[msp].actual_data_size = data_size; + } + } else { + temp_reg |= msp_p1_elem_len_bits(data_size); + temp_reg |= msp_p2_elem_len_bits(data_size); + msp_context[msp].actual_data_size = data_size; + } + temp_reg |= + msp_data_delay_bits(protocol_desc_tab[protocol].data_delay); + + (registers[msp]->tx_config) = temp_reg; + + /* The tx_config register is done, now set the clock mode (rising + * or falling edge). We first clear the bit using the ~RISING value. + */ + temp_reg = (registers[msp]->global_ctrl) & ~TX_CLK_POL_RISING; + temp_reg |= + msp_tx_clkpol_bit(protocol_desc_tab[protocol]. + tx_clock_edge); + temp_reg |= TX_EXTRA_DELAY_ENABLE; + temp_reg |= msp_data_delay_bits(MSP_DELAY_1); + + (registers[msp]->global_ctrl) = temp_reg; + break; + case MSP_RECEIVE_MODE: + rx_status[msp].phase_mode = + protocol_desc_tab[protocol].phase_mode; + + /* Use a temp for setup. Clear everything except the two non-mode + * dependent bits, then add back the bits for the selected protocol + */ + temp_reg = (registers[msp]->rx_config) & MSP_NON_MODE_BIT_MASK; + + temp_reg |= + msp_p2_enable_bit(protocol_desc_tab[protocol].phase_mode); + temp_reg |= + msp_p1_frame_len_bits(protocol_desc_tab[protocol]. + frame_len_1); + temp_reg |= + msp_p2_frame_len_bits(protocol_desc_tab[protocol]. + frame_len_2); + if (data_size == MSP_DATA_SIZE_DEFAULT) { + temp_reg |= + msp_p1_elem_len_bits(protocol_desc_tab[protocol]. + element_len_1); + temp_reg |= + msp_p2_elem_len_bits(protocol_desc_tab[protocol]. + element_len_2); + if (protocol_desc_tab[protocol].element_len_1 == + protocol_desc_tab[protocol].element_len_2) { + msp_context[msp].actual_data_size = + protocol_desc_tab[protocol].element_len_1; + } else { + msp_context[msp].actual_data_size = data_size; + } + } else { + temp_reg |= msp_p1_elem_len_bits(data_size); + temp_reg |= msp_p2_elem_len_bits(data_size); + msp_context[msp].actual_data_size = data_size; + } + temp_reg |= + msp_data_delay_bits(protocol_desc_tab[protocol].data_delay); + + (registers[msp]->rx_config) = temp_reg; + + /* The rx_config register is done, now set the clock mode (rising + * or falling edge). We first clear the bit using the ~RISING value. + */ + temp_reg = (registers[msp]->global_ctrl) & ~RX_CLK_POL_RISING; + temp_reg |= + msp_rx_clkpol_bit(protocol_desc_tab[protocol]. + rx_clock_edge); + + (registers[msp]->global_ctrl) = temp_reg; + break; + case MSP_BOTH_T_R_MODE: + rx_status[msp].phase_mode = + protocol_desc_tab[protocol].phase_mode; + tx_status[msp].phase_mode = + protocol_desc_tab[protocol].phase_mode; + + /* Use a temp for setup. Clear everything except the two non-mode + * dependent bits, then add back the bits for the selected protocol + * do rx_config first + */ + temp_reg = (registers[msp]->rx_config) & MSP_NON_MODE_BIT_MASK; + + temp_reg |= + msp_p2_enable_bit(protocol_desc_tab[protocol].phase_mode); + temp_reg |= + msp_p1_frame_len_bits(protocol_desc_tab[protocol]. + frame_len_1); + temp_reg |= + msp_p2_frame_len_bits(protocol_desc_tab[protocol]. + frame_len_2); + if (data_size == MSP_DATA_SIZE_DEFAULT) { + temp_reg |= + msp_p1_elem_len_bits(protocol_desc_tab[protocol]. + element_len_1); + temp_reg |= + msp_p2_elem_len_bits(protocol_desc_tab[protocol]. + element_len_2); + if (protocol_desc_tab[protocol].element_len_1 == + protocol_desc_tab[protocol].element_len_2) { + msp_context[msp].actual_data_size = + protocol_desc_tab[protocol].element_len_1; + } else { + msp_context[msp].actual_data_size = data_size; + } + } else { + temp_reg |= msp_p1_elem_len_bits(data_size); + temp_reg |= msp_p2_elem_len_bits(data_size); + msp_context[msp].actual_data_size = data_size; + } + temp_reg |= + msp_data_delay_bits(protocol_desc_tab[protocol].data_delay); + + (registers[msp]->rx_config) = temp_reg; + + /* Now tx_config */ + temp_reg = (registers[msp]->tx_config) & MSP_NON_MODE_BIT_MASK; + + temp_reg |= + msp_p2_enable_bit(protocol_desc_tab[protocol].phase_mode); + temp_reg |= + msp_p1_frame_len_bits(protocol_desc_tab[protocol]. + frame_len_1); + temp_reg |= + msp_p2_frame_len_bits(protocol_desc_tab[protocol]. + frame_len_2); + if (data_size == MSP_DATA_SIZE_DEFAULT) { + temp_reg |= + msp_p1_elem_len_bits(protocol_desc_tab[protocol]. + element_len_1); + temp_reg |= + msp_p2_elem_len_bits(protocol_desc_tab[protocol]. + element_len_2); + } else { + temp_reg |= msp_p1_elem_len_bits(data_size); + temp_reg |= msp_p2_elem_len_bits(data_size); + } + temp_reg |= + msp_data_delay_bits(protocol_desc_tab[protocol].data_delay); + + (registers[msp]->tx_config) = temp_reg; + /* The [rt]x_config register is done, now set the clock mode (rising + * or falling edge). We first clear the bit using the ~RISING value. + */ + temp_reg = + (registers[msp]-> + global_ctrl) & ~(TX_CLK_POL_RISING | RX_CLK_POL_RISING); + temp_reg |= + msp_rx_clkpol_bit(protocol_desc_tab[protocol]. + rx_clock_edge); + temp_reg |= + msp_tx_clkpol_bit(protocol_desc_tab[protocol]. + tx_clock_edge); + + (registers[msp]->global_ctrl) = temp_reg; + break; + default: + printk(KERN_ERR "Invalid direction given\n"); + return -EINVAL; + } + + return 0; +} + +static int configure_clock(int msp, int protocol, u32 input_clock, + u32 frame_freq, int frame_size) +{ + u32 dummy; + u32 frame_per = 0; + u32 sck_div = 0; + u32 frame_width = 0; + u32 temp_reg = 0; + u32 data_size; + + (registers[msp]->global_ctrl) &= ~SRG_ENABLE; + + switch (msp_context[msp].actual_data_size) { + case MSP_DATA_SIZE_8BIT: + data_size = 8; + break; + case MSP_DATA_SIZE_10BIT: + data_size = 10; + break; + case MSP_DATA_SIZE_12BIT: + data_size = 12; + break; + case MSP_DATA_SIZE_14BIT: + data_size = 14; + break; + case MSP_DATA_SIZE_16BIT: + data_size = 16; + break; + case MSP_DATA_SIZE_20BIT: + data_size = 20; + break; + case MSP_DATA_SIZE_24BIT: + data_size = 24; + break; + case MSP_DATA_SIZE_32BIT: + data_size = 32; + break; + default: + printk(KERN_ERR + "Unable to determine data size in configure_clock\n"); + return -EINVAL; + } + + switch (protocol) { + case MSP_PCM_PROTOCOL: + case MSP_PCM_COMPAND_PROTOCOL: + case MSP_MASTER_SPI_PROTOCOL: + if (frame_size < 0) { + frame_per = data_size; + if (protocol == MSP_MASTER_SPI_PROTOCOL) { + /* Need 1 clock between start of frame and start + * of data, and 1 clock to indicate end of frame + */ + frame_per += 2; + } + } else { + frame_per = data_size; + } + if (frame_per < data_size) { + printk(KERN_ERR + "Frame size too small in configure_clock\n"); + return -EINVAL; + } + frame_width = 1; + + sck_div = input_clock / (frame_freq << 8); + frame_per = MSP_FRAME_PERIOD_IN_MONO_MODE; + + break; + case MSP_I2S_PROTOCOL: + sck_div = input_clock / (frame_freq << 5); + frame_per = MSP_FRAME_PERIOD_IN_STEREO_MODE; + frame_width = MSP_FRAME_WIDTH_IN_STEREO_MODE; + + break; + case MSP_AC97_PROTOCOL: + /* Not supported */ + printk(KERN_WARNING "AC97 protocol not supported\n"); + return -ENOSYS; + case MSP_SLAVE_SPI_PROTOCOL: + sck_div = 1; + break; + default: + printk(KERN_ERR "Invalid mode attempted for setting clocks\n"); + return -EINVAL; + } + + temp_reg = (sck_div - 1) & SCK_DIV_MASK; + temp_reg |= frame_width_bits(frame_width - 1); + temp_reg |= frame_period_bits(frame_per - 1); + registers[msp]->srg_ctrl = temp_reg; + + /* Wait a bit */ + dummy = ((registers[msp]->srg_ctrl) >> FRWID_BIT) & 0x0000003F; + + /* Enable clock */ + registers[msp]->global_ctrl |= SRG_ENABLE; + + /* Another wait */ + dummy = ((registers[msp]->srg_ctrl) >> FRWID_BIT) & 0x0000003F; + /* reconfigure spi clock mode */ + temp_reg = registers[msp]->global_ctrl; + temp_reg &= ~SPI_CLK_MODE_MASK; + temp_reg |= spi_clock_mode[msp]; + temp_reg &= ~SPI_BURST_MODE_MASK; + temp_reg |= spi_burst_mode[msp]; + + registers[msp]->global_ctrl = temp_reg; + return 0; +} + +static irqreturn_t handle_irq(int irq, void *dev_id) +{ + int msp; + u32 irq_status; + + /* dev_id should be the register base address, find out which MSP + * we are dealing with. */ + for (msp = 0; msp < MSP_COUNT; msp++) { + if (dev_id == registers[msp]) { + break; + } + } + + if (msp == MSP_COUNT) { + /* Didn't find the MSP, this must not be our interrupt */ + return -1; + } + + irq_status = registers[msp]->masked_irq_status; + + /* Disable the interrupt to prevent immediate recurrence */ + registers[msp]->irq_mask &= ~irq_status; + + /* Clear the interrupt */ + registers[msp]->irq_clear = irq_status; + + /* Check for an error condition */ + msp_io_error[msp] |= irq_status & (RECEIVE_OVERRUN_ERROR_INT | + RECEIVE_FRAME_SYNC_ERR_INT | + TRANSMIT_UNDERRUN_ERR_INT | + TRANSMIT_FRAME_SYNC_ERR_INT); + + /* Wake up the reader/writer */ + wake_up_interruptible(&wait[msp]); + return IRQ_HANDLED; + +} + +static int transmit_data(int msp, void *data, size_t bytes) +{ + return transmit_receive_data(msp, tx_status[msp].work_mode, + data, bytes, NULL, 0); +} + +static int receive_data(int msp, void *data, size_t bytes) +{ + return transmit_receive_data(msp, rx_status[msp].work_mode, + NULL, 0, data, bytes); +} + +static int transmit_receive_data(int msp, int work_mode, + void *txdata, size_t txbytes, + void *rxdata, size_t rxbytes) +{ + int status; + u32 tx_offset = 0; + u32 rx_offset = 0; + u8 *data_src_8bit, *data_dst_8bit; + u16 *data_src_16bit, *data_dst_16bit; + u32 *data_src_32bit, *data_dst_32bit; + + if (txdata == NULL && txbytes > 0) { + printk(KERN_ERR + "transmit_receive_data received a NULL transmit buffer with bytes to transmit\n"); + return -EINVAL; + } + + if (rxdata == NULL && rxbytes > 0) { + printk(KERN_ERR + "transmit_receive_data received a NULL receive buffer with bytes to receive\n"); + return -EINVAL; + } + + data_src_8bit = (u8 *) txdata; + data_src_16bit = (u16 *) txdata; + data_src_32bit = (u32 *) txdata; + + data_dst_8bit = (u8 *) rxdata; + data_dst_16bit = (u16 *) rxdata; + data_dst_32bit = (u32 *) rxdata; + + msp_io_error[msp] = 0; + + while (tx_offset < txbytes || rx_offset < rxbytes) { + if (msp_io_error[msp]) { + return -EIO; + } + + if (rx_offset < rxbytes && + !((registers[msp]->status) & RX_FIFO_EMPTY)) { + switch (msp_context[msp].actual_data_size) { + case MSP_DATA_SIZE_8BIT: + rx_offset += sizeof(*data_dst_8bit); + *data_dst_8bit++ = registers[msp]->fifo; + break; + case MSP_DATA_SIZE_10BIT: + case MSP_DATA_SIZE_12BIT: + case MSP_DATA_SIZE_14BIT: + case MSP_DATA_SIZE_16BIT: + rx_offset += sizeof(*data_dst_16bit); + *data_dst_16bit++ = registers[msp]->fifo; + break; + case MSP_DATA_SIZE_20BIT: + case MSP_DATA_SIZE_24BIT: + case MSP_DATA_SIZE_32BIT: + rx_offset += sizeof(*data_dst_32bit); + *data_dst_32bit++ = registers[msp]->fifo; + break; + default: + printk(KERN_ERR + "Unable to determine data size in transmit_receive_data\n"); + return -EIO; + } + } + + if (tx_offset < txbytes && + !((registers[msp]->status) & TX_FIFO_FULL)) { + switch (msp_context[msp].actual_data_size) { + case MSP_DATA_SIZE_8BIT: + tx_offset += sizeof(*data_src_8bit); + registers[msp]->fifo = *data_src_8bit++; + break; + case MSP_DATA_SIZE_10BIT: + case MSP_DATA_SIZE_12BIT: + case MSP_DATA_SIZE_14BIT: + case MSP_DATA_SIZE_16BIT: + tx_offset += sizeof(*data_src_16bit); + registers[msp]->fifo = *data_src_16bit++; + break; + case MSP_DATA_SIZE_20BIT: + case MSP_DATA_SIZE_24BIT: + case MSP_DATA_SIZE_32BIT: + tx_offset += sizeof(*data_src_32bit); + registers[msp]->fifo = *data_src_32bit++; + break; + default: + printk(KERN_ERR + "Unable to determine data size in transmit_receive_data\n"); + return -EIO; + } + } + + if (work_mode == MSP_INTERRUPT_MODE && + (tx_offset < txbytes || rx_offset < rxbytes)) { + u32 status_mask = 0; + u32 irq_mask = 0; + if (tx_offset < txbytes) { + status_mask |= TX_FIFO_FULL; + irq_mask |= TRANSMIT_SERVICE_INT; + if (!(registers[msp]->status & TX_FIFO_FULL)) { + continue; + } + } + if (rx_offset < rxbytes) { + status_mask |= RX_FIFO_EMPTY; + irq_mask |= RECEIVE_SERVICE_INT; + if (!(registers[msp]->status & RX_FIFO_EMPTY)) { + continue; + } + } + registers[msp]->irq_mask |= irq_mask; + status = wait_event_interruptible(wait[msp], + !(registers[msp]-> + status & + status_mask) + && msp_io_error[msp] + == 0); + if (status) { + return status; + } + } + } + + return txbytes + rxbytes; +} + +#if (defined(CONFIG_NOMADIK_SPI) || defined(CONFIG_NOMADIK_SPI_MODULE)) + +/** + * msp_controller_cmd - To execute controller specific commands for MSP + * @drv_data: SPI driver private data structure + * @cmd: Command which is to be executed on the controller + * + * + */ +static int msp_controller_cmd(struct driver_data *drv_data, int cmd) +{ + int retval = 0; + nmdk_dbg_ftrace(); + switch (cmd) + { + case DISABLE_CONTROLLER: + { + nmdk_dbg2(":::: DISABLE_CONTROLLER\n"); + writel((readl(MSP_GCR(drv_data->regs)) & (~(MSP_GCR_MASK_TXEN | MSP_GCR_MASK_RXEN ))), MSP_GCR(drv_data->regs)); + break; + } + case ENABLE_CONTROLLER: + { + nmdk_dbg2(":::: ENABLE_CONTROLLER\n"); + writel((readl(MSP_GCR(drv_data->regs)) | (MSP_GCR_MASK_TXEN | MSP_GCR_MASK_RXEN )), MSP_GCR(drv_data->regs)); + break; + } + case DISABLE_DMA: + { + nmdk_dbg2(":::: DISABLE_DMA\n"); + writel(DEFAULT_MSP_REG_DMACR, MSP_DMACR(drv_data->regs)); + break; + } + case ENABLE_DMA: + { + nmdk_dbg2(":::: ENABLE_DMA\n"); + writel(drv_data->cur_chip->regs.mspr.dmacr, MSP_DMACR(drv_data->regs)); + break; + } + case DISABLE_ALL_INTERRUPT: + { + nmdk_dbg2(":::: DISABLE_ALL_INTERRUPT\n"); + writel(DISABLE_ALL_MSP_INTERRUPTS, MSP_IMSC(drv_data->regs)); + break; + } + case ENABLE_ALL_INTERRUPT: + { + nmdk_dbg2(":::: ENABLE_ALL_INTERRUPT\n"); + writel( ENABLE_ALL_MSP_INTERRUPTS, MSP_IMSC(drv_data->regs)); + break; + } + case CLEAR_ALL_INTERRUPT: + { + nmdk_dbg2(":::: CLEAR_ALL_INTERRUPT\n"); + writel(CLEAR_ALL_MSP_INTERRUPTS, MSP_ICR(drv_data->regs)); + break; + } + case FLUSH_FIFO: + { + unsigned long limit = loops_per_jiffy << 1; + nmdk_dbg2(":::: DATA FIFO is flushed\n"); + do { + while( ! (readl(MSP_FLR(drv_data->regs)) & MSP_FLR_MASK_RFE)) + readl(MSP_DR(drv_data->regs)); + } while ((readl(MSP_FLR(drv_data->regs)) & (MSP_FLR_MASK_TBUSY | MSP_FLR_MASK_RBUSY)) && limit--); + retval = limit; + break; + } + case RESTORE_STATE: + { + struct chip_data *chip = drv_data->cur_chip; + nmdk_dbg2(":::: RESTORE_STATE\n"); + writel(chip->regs.mspr.gcr, MSP_GCR(drv_data->regs)); + writel(chip->regs.mspr.tcf, MSP_TCF(drv_data->regs)); + writel(chip->regs.mspr.rcf, MSP_RCF(drv_data->regs)); + writel(chip->regs.mspr.srg, MSP_SRG(drv_data->regs)); + writel(chip->regs.mspr.dmacr, MSP_DMACR(drv_data->regs)); + writel(DISABLE_ALL_MSP_INTERRUPTS, MSP_IMSC(drv_data->regs)); + writel(CLEAR_ALL_MSP_INTERRUPTS, MSP_ICR(drv_data->regs)); + break; + } + case LOAD_DEFAULT_CONFIG: + { + nmdk_dbg2(":::: LOAD_DEFAULT_CONFIG\n"); + writel(DEFAULT_MSP_REG_GCR, MSP_GCR(drv_data->regs)); + writel(DEFAULT_MSP_REG_TCF, MSP_TCF(drv_data->regs)); + writel(DEFAULT_MSP_REG_RCF, MSP_RCF(drv_data->regs)); + writel(DEFAULT_MSP_REG_SRG, MSP_SRG(drv_data->regs)); + writel(DEFAULT_MSP_REG_DMACR, MSP_DMACR(drv_data->regs)); + writel(DISABLE_ALL_MSP_INTERRUPTS, MSP_IMSC(drv_data->regs)); + writel(CLEAR_ALL_MSP_INTERRUPTS, MSP_ICR(drv_data->regs)); + break; + } + default: + { + nmdk_dbg2(":::: unknown command\n"); + retval = -1; + break; + } + } + return retval; +} + +void msp_u8_writer(struct driver_data *drv_data) +{ + u32 cur_write = 0; + u32 status; + while(1){ + status = readl(MSP_FLR(drv_data->regs)); + if((status & MSP_FLR_MASK_TFU) || (drv_data->tx >= drv_data->tx_end)) + return; + writel((u32) (*(u8 *) (drv_data->tx)), MSP_DR(drv_data->regs)); + drv_data->tx += (drv_data->cur_chip->n_bytes); + cur_write ++; + if(cur_write == 8) + return; + } +} +void msp_u8_reader(struct driver_data *drv_data) +{ + u32 status; + while(1){ + status = readl(MSP_FLR(drv_data->regs)); + if( (status & MSP_FLR_MASK_RFE) || ( drv_data->rx >= drv_data->rx_end)) + return; + *(u8 *) (drv_data->rx) = (u8) readl(MSP_DR(drv_data->regs)); + drv_data->rx += (drv_data->cur_chip->n_bytes); + } +} +void msp_u16_writer(struct driver_data *drv_data) +{ + u32 cur_write = 0; + u32 status; + while(1){ + status = readl(MSP_FLR(drv_data->regs)); + + if((status & MSP_FLR_MASK_TFU) || (drv_data->tx >= drv_data->tx_end)) + return; + writel((u32) (*(u16 *) (drv_data->tx)), MSP_DR(drv_data->regs)); + drv_data->tx += (drv_data->cur_chip->n_bytes); + cur_write ++; + if(cur_write == 8) + return; + } +} +void msp_u16_reader(struct driver_data *drv_data) +{ + u32 status; + while(1){ + status = readl(MSP_FLR(drv_data->regs)); + if( (status & MSP_FLR_MASK_RFE) || ( drv_data->rx >= drv_data->rx_end)) + return; + *(u16 *) (drv_data->rx) = (u16) readl(MSP_DR(drv_data->regs)); + drv_data->rx += (drv_data->cur_chip->n_bytes); + } +} + +void msp_u32_writer(struct driver_data *drv_data) +{ + u32 cur_write = 0; + u32 status; + while(1){ + status = readl(MSP_FLR(drv_data->regs)); + + if((status & MSP_FLR_MASK_TFU) || (drv_data->tx >= drv_data->tx_end)) + return; + /*Write Data to Data Register */ + writel(*(u32 *) (drv_data->tx), MSP_DR(drv_data->regs)); + drv_data->tx += (drv_data->cur_chip->n_bytes); + cur_write ++; + if(cur_write == 8) + return; + } +} +void msp_u32_reader(struct driver_data *drv_data) +{ + u32 status; + while(1){ + status = readl(MSP_FLR(drv_data->regs)); + if( (status & MSP_FLR_MASK_RFE) || ( drv_data->rx >= drv_data->rx_end)) + return; + *(u32 *) (drv_data->rx) = readl(MSP_DR(drv_data->regs)); + drv_data->rx += (drv_data->cur_chip->n_bytes); + } +} + +static irqreturn_t nomadik_msp_interrupt_handler(int irq, void *dev_id) +{ + struct driver_data *drv_data = (struct driver_data *)dev_id; + struct spi_message *msg = drv_data->cur_msg; + u32 irq_status = 0; + u32 flag = 0; + if (!msg) { + dev_err(&drv_data->adev->dev, + "bad message state in interrupt handler"); + /* Never fail */ + return IRQ_HANDLED; + } + /*Read the Interrupt Status Register */ + irq_status = readl(MSP_MIS(drv_data->regs)); + + if (irq_status) { + if (irq_status & MSP_MIS_MASK_ROEMIS) { /*Overrun interrupt */ + /*Bail-out our Data has been corrupted */ + nmdk_dbg3(":::: Received ROR interrupt\n"); + drv_data->execute_cmd(drv_data, DISABLE_ALL_INTERRUPT); + drv_data->execute_cmd(drv_data, CLEAR_ALL_INTERRUPT); + drv_data->execute_cmd(drv_data, DISABLE_CONTROLLER); + msg->state = ERROR_STATE; + tasklet_schedule(&drv_data->pump_transfers); + return IRQ_HANDLED; + } + + drv_data->read(drv_data); + drv_data->write(drv_data); + + if ((drv_data->tx == drv_data->tx_end) && (flag == 0)) { + flag = 1; + /*Disable Transmit interrupt */ + writel(readl(MSP_IMSC(drv_data->regs)) & (~MSP_IMSC_MASK_TXIM) & (~MSP_IMSC_MASK_TFOIM), (drv_data->regs + 0x14)); + } + /*Clearing any Transmit underrun error. overrun already handled*/ + drv_data->execute_cmd(drv_data, CLEAR_ALL_INTERRUPT); + + if (drv_data->rx == drv_data->rx_end) { + drv_data->execute_cmd(drv_data, DISABLE_ALL_INTERRUPT); + drv_data->execute_cmd(drv_data, CLEAR_ALL_INTERRUPT); + nmdk_dbg3(":::: Interrupt transfer Completed...\n"); + /* Update total bytes transfered */ + msg->actual_length += drv_data->cur_transfer->len; + if (drv_data->cur_transfer->cs_change) + drv_data->cur_chip-> + cs_control(SPI_CHIP_DESELECT); + /* Move to next transfer */ + msg->state = next_transfer(drv_data); + tasklet_schedule(&drv_data->pump_transfers); + return IRQ_HANDLED; + } + } + return IRQ_HANDLED; +} + +static int verify_msp_controller_parameters(struct nmdk_spi_config_chip *chip_info) +{ + nmdk_dbg_ftrace(); + /*FIXME: check clock params*/ + if ((chip_info->lbm != LOOPBACK_ENABLED) + && (chip_info->lbm != LOOPBACK_DISABLED)) { + nmdk_dbg(":::: Loopback Mode is configured incorrectly\n"); + return -1; + } + if (chip_info->iface != SPI_INTERFACE_MOTOROLA_SPI){ + nmdk_dbg(":::: Interface is configured incorrectly. This controller supports only MOTOROLA SPI\n"); + return -1; + } + if ((chip_info->hierarchy != SPI_MASTER) + && (chip_info->hierarchy != SPI_SLAVE)) { + nmdk_dbg(":::: hierarchy is configured incorrectly\n"); + return -1; + } + if ((chip_info->endian_rx != SPI_FIFO_MSB) + && (chip_info->endian_rx != SPI_FIFO_LSB)) { + nmdk_dbg(":::: Rx FIFO endianess is configured incorrectly\n"); + return -1; + } + if ((chip_info->endian_tx != SPI_FIFO_MSB) + && (chip_info->endian_tx != SPI_FIFO_LSB)) { + nmdk_dbg(":::: Tx FIFO endianess is configured incorrectly\n"); + return -1; + } + if (((chip_info->controller).msp.data_size < MSP_DATA_BITS_8) || ((chip_info->controller).msp.data_size > MSP_DATA_BITS_32)) { + nmdk_dbg(":::: MSP DATA Size is configured incorrectly\n"); + return -1; + } + if ((chip_info->com_mode != INTERRUPT_TRANSFER) + && (chip_info->com_mode != DMA_TRANSFER) + && (chip_info->com_mode != POLLING_TRANSFER)) { + nmdk_dbg(":::: Communication mode is configured incorrectly\n"); + return -1; + } + if (chip_info->iface == SPI_INTERFACE_MOTOROLA_SPI) { + if (((chip_info->proto_params).moto.clk_phase != SPI_CLK_ZERO_CYCLE_DELAY) + && ((chip_info->proto_params).moto.clk_phase != SPI_CLK_HALF_CYCLE_DELAY)) { + nmdk_dbg(":::: Clock Phase is configured incorrectly\n"); + return -1; + } + if (((chip_info->proto_params).moto.clk_pol != SPI_CLK_POL_IDLE_LOW) + && ((chip_info->proto_params).moto.clk_pol != SPI_CLK_POL_IDLE_HIGH)) { + nmdk_dbg(":::: Clock Polarity is configured incorrectly\n"); + return -1; + } + } + if (chip_info->cs_control == NULL) { + nmdk_dbg("::::Chip Select Function is NULL for this chip\n"); + chip_info->cs_control = null_cs_control; + } + return 0; +} + +/** + * nomadik_msp_setup - setup function registered to SPI master framework + * @spi: spi device which is requesting setup + * + * This function is registered to the SPI framework for this SPI master + * controller. If it is the first time when setup is called by this device + * , this function will initialize the runtime state for this chip and save + * the same in the device structure. Else it will update the runtime info + * with the updated chip info. + */ + +static int nomadik_msp_setup(struct spi_device *spi) +{ + struct nmdk_spi_config_chip *chip_info; + struct chip_data *chip; + struct spi_master *master; + int status = 0; + u16 sckdiv = 0; + struct driver_data *drv_data = spi_master_get_devdata(spi->master); + nmdk_dbg_ftrace(); + master = drv_data->master; + + switch(master->bus_num) { + case MSP_0_CONTROLLER: + if((drv_data->flag_msp0->user != MSP_NO_USER) && (drv_data->flag_msp0->user != MSP_USER_SPI)){ + status = -EINVAL; + printk(KERN_ERR "MSP0 already in use in %d mode", drv_data->flag_msp0->user); + } + else { + down(&drv_data->flag_msp0->lock); + drv_data->flag_msp0->user = MSP_USER_SPI; + up(&drv_data->flag_msp0->lock); + nmdk_dbg("Flag set to MSP_USER_SPI for MSP0\n"); + } + break; + case MSP_1_CONTROLLER: + if((drv_data->flag_msp1->user != MSP_NO_USER) && (drv_data->flag_msp1->user != MSP_USER_SPI)){ + status = -EINVAL; + printk(KERN_ERR "MSP1 already in use in %d mode", drv_data->flag_msp1->user); + } + else { + down(&drv_data->flag_msp1->lock); + drv_data->flag_msp1->user = MSP_USER_SPI; + up(&drv_data->flag_msp1->lock); + nmdk_dbg("Flag set to MSP_USER_SPI for MSP1\n"); + } + break; + case MSP_2_CONTROLLER: + if((drv_data->flag_msp2->user != MSP_NO_USER) && (drv_data->flag_msp2->user != MSP_USER_SPI)){ + status = -EINVAL; + printk(KERN_ERR "MSP2 already in use in %d mode", drv_data->flag_msp2->user); + } + else { + down(&drv_data->flag_msp2->lock); + drv_data->flag_msp2->user = MSP_USER_SPI; + up(&drv_data->flag_msp2->lock); + nmdk_dbg("Flag set to MSP_USER_SPI for MSP2\n"); + } + break; + } + if(status) + return status; + + status = nomadik_gpio_altfuncenable(drv_data->master_info->gpio_alt_func, drv_data->master_info->device_name); + if (status < 0) { + dev_err(&drv_data->adev->dev, "probe - unable to set GPIO Altfunc, %d\n", drv_data->master_info->gpio_alt_func); + status = -ENODEV; + goto err_out; + } + + status = request_irq(drv_data->adev->irq[0], nomadik_msp_interrupt_handler, 0, drv_data->master_info->device_name , drv_data); + if (status < 0) { + dev_err(&drv_data->adev->dev, "probe - cannot get IRQ (%d)\n", status); + goto err_altfunc_enable; + } + + /* Get controller data */ + chip_info = spi->controller_data; + /* Get controller_state */ + chip = spi_get_ctldata(spi); + if (chip == NULL) { + chip = kzalloc(sizeof(struct chip_data), GFP_KERNEL); + if (!chip) { + dev_err(&spi->dev, + "setup - cannot allocate controller state"); + goto err_request_irq; + } + chip->chip_id = spi->chip_select; + + nmdk_dbg(":::: chip Id for this client = %d\n", chip->chip_id); + nmdk_dbg(":::: Allocated Memory for controller's runtime state\n"); + + if (chip_info == NULL) { + /* spi_board_info.controller_data not is supplied */ + chip_info = + kzalloc(sizeof(struct nmdk_spi_config_chip), GFP_KERNEL); + if (!chip_info) { + dev_err(&spi->dev, + "setup - cannot allocate controller data"); + status = -ENOMEM; + goto err_first_setup; + } + nmdk_dbg(":::: Allocated Memory for controller data\n"); + + /* FIXME: Set controller data default value for MSP*/ + chip_info->lbm = LOOPBACK_DISABLED; + chip_info->com_mode = POLLING_TRANSFER; + chip_info->iface = SPI_INTERFACE_MOTOROLA_SPI; + chip_info->hierarchy = SPI_MASTER; + chip_info->endian_tx = SPI_FIFO_LSB; + chip_info->endian_rx = SPI_FIFO_LSB; + (chip_info->controller).msp.data_size = MSP_DATA_BITS_32; + + if(spi->max_speed_hz != 0) + chip_info->freq = spi->max_speed_hz; + else + chip_info->freq = 48000; + + (chip_info->proto_params).moto.clk_phase = SPI_CLK_HALF_CYCLE_DELAY; + (chip_info->proto_params).moto.clk_pol = SPI_CLK_POL_IDLE_LOW; + chip_info->cs_control = null_cs_control; + } + } + + if(chip_info->freq == 0){ + /*Calculate Specific Freq.*/ + if ( (MSP_INTERNAL_CLK == (chip_info->controller).msp.clk_freq.clk_src) + || ( MSP_EXTERNAL_CLK == (chip_info->controller).msp.clk_freq.clk_src)){ + sckdiv = (chip_info->controller).msp.clk_freq.sckdiv; + + }else{ + status = -1; + dev_err(&spi->dev, "setup - controller clock data is incorrect"); + goto err_config_params; + } + }else{ + /*Calculate Effective Freq.*/ + sckdiv =((DEFAULT_MSP_CLK) / (chip_info->freq)) - 1; + if(sckdiv > MAX_SCKDIV){ + printk("SPI: Cannot set frequency less than 48Khz, setting lowest(48 Khz)\n"); + sckdiv = MAX_SCKDIV; + } + } + + + status = verify_msp_controller_parameters(chip_info); + if (status) { + dev_err(&spi->dev, "setup - controller data is incorrect"); + goto err_config_params; + } + + /* Now set controller state based on controller data */ + chip->xfer_type = chip_info->com_mode; + chip->cs_control = chip_info->cs_control; + + + /*FIXME: write all 8 & 16 bit functions*/ + if ((chip_info->controller).msp.data_size <= MSP_DATA_BITS_8) { + nmdk_dbg(":::: Less than 8 bits per word....\n"); + chip->n_bytes = 1; + chip->read = msp_u8_reader; + chip->write = msp_u8_writer; + } else if ((chip_info->controller).msp.data_size <= MSP_DATA_BITS_16) { + nmdk_dbg(":::: Less than 16 bits per word....\n"); + chip->n_bytes = 2; + chip->read = msp_u16_reader; + chip->write = msp_u16_writer; + } else { + nmdk_dbg(":::: Less than 32 bits per word....\n"); + chip->n_bytes = 4; + chip->read = msp_u32_reader; + chip->write = msp_u32_writer; + } + + /*Now Initialize all register settings reqd. for this chip */ + + chip->regs.mspr.gcr = 0x0; + chip->regs.mspr.tcf = 0x0; + chip->regs.mspr.rcf = 0x0; + chip->regs.mspr.srg = 0x0; + chip->regs.mspr.dmacr = 0x0; + + if ((chip_info->com_mode == DMA_TRANSFER) + && ((drv_data->master_info)->enable_dma)) { + chip->enable_dma = 1; + chip->dma_info = kzalloc(sizeof(struct spi_dma_info), GFP_KERNEL); + if(!chip->dma_info){ + nmdk_dbg("Could not allocate memory for dma info of chip_data\n"); + goto err_first_setup; + } + chip->dma_info->dma_xfer_type = chip_info->dma_xfer_type; + nmdk_dbg(":::: DMA mode set in controller state\n"); + status = process_dma_info(chip_info, chip, (void *)drv_data); + if (status < 0) + goto err_config_params; + SPI_REG_WRITE_BITS(chip->regs.mspr.dmacr, 0x1, MSP_DMACR_MASK_RDMAE, 0); + SPI_REG_WRITE_BITS(chip->regs.mspr.dmacr, 0x1, MSP_DMACR_MASK_TDMAE, 1); + + /* find and request free dma chanel */ + chip->dma_info->rx_dmach = request_available_dma(&(chip->dma_info->rx_dma_info)); + if (chip->dma_info->rx_dmach < 0) { + nmdk_dbg(":::: Rx pipe request Failed: %d\n", chip->dma_info->rx_dmach); + goto err_rx_dmach_request; + } + nmdk_dbg(":::: Rx pipe Allocated = %d\n", chip->dma_info->rx_dmach); + + status = request_irq(IRQNO_FOR_DMACH(chip->dma_info->rx_dmach), + spi_dma_callback_handler, 0, 0, + (void *)drv_data); + if (status) { + nmdk_error("Error requesting rx callback dmach intr handler %d", status); + goto err_rx_clbk_request; + } + + /* find and request free dma chanel */ + chip->dma_info->tx_dmach = request_available_dma(&(chip->dma_info->tx_dma_info)); + if (chip->dma_info->tx_dmach < 0) { + nmdk_dbg(":::: Tx pipe request Failed: %d\n", status); + goto err_tx_dmach_request; + } + nmdk_dbg(":::: Tx pipe Allocated = %d\n", chip->dma_info->tx_dmach); + + status = request_irq(IRQNO_FOR_DMACH(chip->dma_info->tx_dmach), + spi_dma_callback_handler, 0, 0, + (void *)drv_data); + if (status) { + nmdk_error("Error requesting callback dmach intr handler %d", status); + goto err_tx_clbk_request; + } + } else { + chip->enable_dma = 0; + nmdk_dbg(":::: DMA mode NOT set in controller state\n"); + SPI_REG_WRITE_BITS(chip->regs.mspr.dmacr, 0x0, MSP_DMACR_MASK_RDMAE, 0); + SPI_REG_WRITE_BITS(chip->regs.mspr.dmacr, 0x0, MSP_DMACR_MASK_TDMAE, 1); + } + + + /**** GCR Reg Config *****/ + + SPI_REG_WRITE_BITS(chip->regs.mspr.gcr, MSP_RECEIVER_DISABLED, MSP_GCR_MASK_RXEN,0); + SPI_REG_WRITE_BITS(chip->regs.mspr.gcr, MSP_RX_FIFO_ENABLED, MSP_GCR_MASK_RFFEN,1); + SPI_REG_WRITE_BITS(chip->regs.mspr.gcr, MSP_TRANSMITTER_DISABLED, MSP_GCR_MASK_TXEN,8); + SPI_REG_WRITE_BITS(chip->regs.mspr.gcr, MSP_TX_FIFO_ENABLED, MSP_GCR_MASK_TFFEN,9); + SPI_REG_WRITE_BITS(chip->regs.mspr.gcr, MSP_TX_FRAME_SYNC_POL_LOW, MSP_GCR_MASK_TFSPOL,10); + SPI_REG_WRITE_BITS(chip->regs.mspr.gcr, MSP_TX_FRAME_SYNC_INT, MSP_GCR_MASK_TFSSEL,11); + SPI_REG_WRITE_BITS(chip->regs.mspr.gcr, MSP_TRANSMIT_DATA_WITH_DELAY, MSP_GCR_MASK_TXDDL,15); + SPI_REG_WRITE_BITS(chip->regs.mspr.gcr, MSP_SAMPLE_RATE_GEN_ENABLE, MSP_GCR_MASK_SGEN,16); + SPI_REG_WRITE_BITS(chip->regs.mspr.gcr, MSP_CLOCK_INTERNAL, MSP_GCR_MASK_SCKSEL,18); + SPI_REG_WRITE_BITS(chip->regs.mspr.gcr, MSP_FRAME_GEN_ENABLE, MSP_GCR_MASK_FGEN,20); + SPI_REG_WRITE_BITS(chip->regs.mspr.gcr, SPI_BURST_MODE_DISABLE, MSP_GCR_MASK_SPIBME,23); + + + if(chip_info->lbm == LOOPBACK_ENABLED) + SPI_REG_WRITE_BITS(chip->regs.mspr.gcr, MSP_LOOPBACK_ENABLED, MSP_GCR_MASK_LBM, 7); + else + SPI_REG_WRITE_BITS(chip->regs.mspr.gcr, MSP_LOOPBACK_DISABLED, MSP_GCR_MASK_LBM, 7); + + + if(chip_info->hierarchy == SPI_MASTER) + SPI_REG_WRITE_BITS(chip->regs.mspr.gcr, MSP_IS_SPI_MASTER, MSP_GCR_MASK_TCKSEL, 14); + else + SPI_REG_WRITE_BITS(chip->regs.mspr.gcr, MSP_IS_SPI_SLAVE, MSP_GCR_MASK_TCKSEL, 14); + + + if(chip_info->proto_params.moto.clk_phase == SPI_CLK_ZERO_CYCLE_DELAY) + SPI_REG_WRITE_BITS(chip->regs.mspr.gcr, MSP_SPI_PHASE_ZERO_CYCLE_DELAY , MSP_GCR_MASK_SPICKM, 21); + else + SPI_REG_WRITE_BITS(chip->regs.mspr.gcr, MSP_SPI_PHASE_HALF_CYCLE_DELAY , MSP_GCR_MASK_SPICKM, 21); + + if(chip_info->proto_params.moto.clk_pol == SPI_CLK_POL_IDLE_HIGH) + SPI_REG_WRITE_BITS(chip->regs.mspr.gcr, MSP_TX_CLOCK_POL_HIGH, MSP_GCR_MASK_TCKPOL,13); + else + SPI_REG_WRITE_BITS(chip->regs.mspr.gcr, MSP_TX_CLOCK_POL_LOW, MSP_GCR_MASK_TCKPOL,13); + + + /**** RCF Reg Config *****/ + SPI_REG_WRITE_BITS(chip->regs.mspr.rcf, MSP_IGNORE_RX_FRAME_SYNC_PULSE, MSP_RCF_MASK_RFSIG, 15); + SPI_REG_WRITE_BITS(chip->regs.mspr.rcf, MSP_RX_1BIT_DATA_DELAY, MSP_RCF_MASK_RDDLY, 13); + if(chip_info->endian_rx == SPI_FIFO_LSB) + SPI_REG_WRITE_BITS(chip->regs.mspr.rcf, MSP_RX_ENDIANESS_LSB , MSP_RCF_MASK_RENDN, 12); + else + SPI_REG_WRITE_BITS(chip->regs.mspr.rcf, MSP_RX_ENDIANESS_MSB , MSP_RCF_MASK_RENDN, 12); + + SPI_REG_WRITE_BITS(chip->regs.mspr.rcf, chip_info->controller.msp.data_size , MSP_RCF_MASK_RP1ELEN, 0); + + /**** TCF Reg Config *****/ + SPI_REG_WRITE_BITS(chip->regs.mspr.tcf, MSP_IGNORE_TX_FRAME_SYNC_PULSE, MSP_TCF_MASK_TFSIG, 15); + SPI_REG_WRITE_BITS(chip->regs.mspr.tcf, MSP_TX_1BIT_DATA_DELAY, MSP_TCF_MASK_TDDLY, 13); + if(chip_info->endian_rx == SPI_FIFO_LSB) + SPI_REG_WRITE_BITS(chip->regs.mspr.tcf, MSP_TX_ENDIANESS_LSB , MSP_TCF_MASK_TENDN, 12); + else + SPI_REG_WRITE_BITS(chip->regs.mspr.tcf, MSP_TX_ENDIANESS_MSB , MSP_TCF_MASK_TENDN, 12); + SPI_REG_WRITE_BITS(chip->regs.mspr.tcf, chip_info->controller.msp.data_size , MSP_TCF_MASK_TP1ELEN, 0); + + /**** SRG Reg Config *****/ + SPI_REG_WRITE_BITS(chip->regs.mspr.srg, sckdiv , MSP_SRG_MASK_SCKDIV , 0); + + /* Save controller_state */ + spi_set_ctldata(spi, chip); + return status; + +err_tx_clbk_request: + if (chip->dma_info->tx_dmach != -1) { + free_dma(chip->dma_info->tx_dmach); + } +err_tx_dmach_request: +err_rx_clbk_request: + if (chip->dma_info->rx_dmach != -1) { + free_dma(chip->dma_info->rx_dmach); + } +err_rx_dmach_request: + chip->dma_info->tx_dmach = -1; + chip->dma_info->rx_dmach = -1; +err_config_params: +err_first_setup: + if(chip->dma_info) + kfree(chip->dma_info); + kfree(chip); +err_request_irq: + free_irq(drv_data->adev->irq[0], drv_data); +err_altfunc_enable: + nomadik_gpio_altfuncdisable(drv_data->master_info->gpio_alt_func, drv_data->master_info->device_name); +err_out: + switch(master->bus_num) { + case MSP_0_CONTROLLER: if(drv_data->flag_msp0->user == MSP_USER_SPI) { + down(&drv_data->flag_msp0->lock); + drv_data->flag_msp0->user = MSP_NO_USER; + up(&drv_data->flag_msp0->lock); + nmdk_dbg("Flag cleanup for MSP0\n"); + } + else { + printk("Error in nomadik_spi_cleanup Trying to free MSP from SPI-mode , already configured in mode%d\n", drv_data->flag_msp0->user); + status = -EFAULT; + } + break; + case MSP_1_CONTROLLER: if(drv_data->flag_msp1->user == MSP_USER_SPI) { + down(&drv_data->flag_msp1->lock); + drv_data->flag_msp1->user = MSP_NO_USER; + up(&drv_data->flag_msp1->lock); + nmdk_dbg("Flag cleanup for MSP1\n"); + } + else { + printk("Error in nomadik_spi_cleanup Trying to free MSP from SPI-mode , already configured in mode%d\n", drv_data->flag_msp1->user); + status = -EFAULT; + } + break; + case MSP_2_CONTROLLER: if(drv_data->flag_msp2->user == MSP_USER_SPI) { + down(&drv_data->flag_msp2->lock); + drv_data->flag_msp2->user = MSP_NO_USER; + up(&drv_data->flag_msp2->lock); + nmdk_dbg("Flag cleanup for MSP2\n"); + } + else { + printk("Error in nomadik_spi_cleanup Trying to free MSP from SPI-mode , already configured in mode%d\n", drv_data->flag_msp2->user); + status = -EFAULT; + } + break; + } + + return status; +} + +#endif + + +int msp_probe(struct amba_device *adev, void *data) +{ + int status = 0; + struct device *dev; + struct nmdk_spi_master_cntlr *platform_info; + +#if (defined(CONFIG_NOMADIK_SPI) || defined(CONFIG_NOMADIK_SPI_MODULE)) + struct spi_master *master; + struct driver_data *drv_data = NULL; /*Data for this driver */ + struct resource *res; + int irq; +#endif + dev = &adev->dev; + platform_info = (struct nmdk_spi_master_cntlr *)(dev->platform_data); + if (platform_info == NULL) { + dev_err(&adev->dev, "probe - no platform data supplied\n"); + status = -ENODEV; + goto err_no_pdata; + } + + if(platform_info->id == MSP_0_CONTROLLER) { + flag_msp0= kmalloc(sizeof(msp_flag), GFP_KERNEL); + if(!flag_msp0) { + status = -ENOMEM; + printk(KERN_ERR "No mem available for MSP0 flag\n"); + goto err_msp0; + } + flag_msp0->user = MSP_NO_USER; + init_MUTEX(&flag_msp0->lock); + init_waitqueue_head(&wait[0]); + nmdk_dbg("In msp_probe flag_msp0 is %d\n", flag_msp0->user); + } + if(platform_info->id == MSP_1_CONTROLLER) { + flag_msp1= kmalloc(sizeof(msp_flag), GFP_KERNEL); + if(!flag_msp1) { + status = -ENOMEM; + printk(KERN_ERR "No mem available for MSP1 flag\n"); + goto err_msp1; + } + flag_msp1->user = MSP_NO_USER; + init_MUTEX(&flag_msp1->lock); + init_waitqueue_head(&wait[1]); + nmdk_dbg("In msp_probe flag_msp1 is %d\n", flag_msp1->user); + } + if(platform_info->id == MSP_2_CONTROLLER) { + flag_msp2= kmalloc(sizeof(msp_flag), GFP_KERNEL); + if(!flag_msp2) { + status = -ENOMEM; + printk(KERN_ERR "No mem available for MSP2 flag\n"); + goto err_msp2; + } + flag_msp2->user = MSP_NO_USER; + init_MUTEX(&flag_msp2->lock); + init_waitqueue_head(&wait[2]); + nmdk_dbg("In msp_probe flag_msp2 is %d\n", flag_msp2->user); + } + nmdk_dbg_ftrace(); + +#if (defined(CONFIG_NOMADIK_SPI) || defined(CONFIG_NOMADIK_SPI_MODULE)) + /* Allocate master with space for drv_data */ + master = spi_alloc_master(dev, sizeof(struct driver_data)); + if (master == NULL) { + dev_err(&adev->dev, "probe - cannot alloc spi_master\n"); + status = -ENOMEM; + goto err_no_mem; + } + + drv_data = spi_master_get_devdata(master); + drv_data->master = master; + drv_data->master_info = platform_info; + drv_data->adev = adev; + + drv_data->dma_ongoing = 0; + + /*Fetch the Resources, using platform data */ + + res = &(adev->res); + if (res == NULL) { + dev_err(&adev->dev, "probe - MEM resources not defined\n"); + status = -ENODEV; + goto err_no_iores; + } + /*Get Hold of Device Register Area... */ + drv_data->regs = ioremap(res->start, (res->end - res->start)); + if (drv_data->regs == NULL) { + status = -ENODEV; + goto err_no_iores; + } + irq = adev->irq[0]; + if (irq <= 0) { + status = -ENODEV; + goto err_no_iores; + } + + /*Set flag for MSPx*/ + switch(platform_info->id) { + case MSP_0_CONTROLLER: + drv_data->flag_msp0 = (spi_msp_user *)flag_msp0; + break; + case MSP_1_CONTROLLER: + drv_data->flag_msp1 = (spi_msp_user *)flag_msp1; + break; + case MSP_2_CONTROLLER: + drv_data->flag_msp2 = (spi_msp_user *)flag_msp2; + break; + default: + dev_err(&adev->dev, "unknown controller Id %d\n", platform_info->id); + status = -EINVAL; + break; + } + + if(status == -EINVAL) + goto err_no_irqres; + + nmdk_dbg(":::: MSP Controller = %d\n", platform_info->id); + drv_data->execute_cmd = msp_controller_cmd; + drv_data->execute_cmd(drv_data, LOAD_DEFAULT_CONFIG); + master->setup = nomadik_msp_setup; + + /*Required Info for an SPI controller */ + /*Bus Number Which has been Assigned to this SPI controller on this board */ + master->bus_num = (u16) platform_info->id; + master->num_chipselect = platform_info->num_chipselect; + master->cleanup = nomadik_spi_cleanup; + master->transfer = nomadik_spi_transfer; + + nmdk_dbg(":::: BUSNO: %d\n", master->bus_num); + /* Initialize and start queue */ + status = init_queue(drv_data); + if (status != 0) { + dev_err(&adev->dev, "probe - problem initializing queue\n"); + goto err_init_queue; + } + status = start_queue(drv_data); + if (status != 0) { + dev_err(&adev->dev, "probe - problem starting queue\n"); + goto err_start_queue; + } + /*Initialize tasklet for DMA transfer*/ + tasklet_init(&drv_data->spi_dma_tasklet, nomadik_spi_tasklet, + (unsigned long)drv_data); + + /* Register with the SPI framework */ + platform_set_drvdata(adev, drv_data); + status = spi_register_master(master); + if (status != 0) { + dev_err(&adev->dev, "probe - problem registering spi master\n"); + goto err_spi_register; + } + dev_dbg(dev, "probe succeded\n"); + nmdk_dbg(" Bus Number = %d, IRQ Line = %d, Virtual Addr: %x\n", master->bus_num, irq, (u32)(drv_data->regs) ); + return 0; +#endif + return status; + +#if (defined(CONFIG_NOMADIK_SPI) || defined(CONFIG_NOMADIK_SPI_MODULE)) + err_init_queue: + err_start_queue: + err_spi_register: + destroy_queue(drv_data); + err_no_irqres: + err_no_iores: + spi_master_put(master); + err_no_mem: +#endif + if((flag_msp2) && (platform_info->id == MSP_2_CONTROLLER)) + kfree(flag_msp2); + err_msp2: + if((flag_msp1) && (platform_info->id == MSP_1_CONTROLLER)) + kfree(flag_msp1); + err_msp1: + if((flag_msp0) && (platform_info->id == MSP_0_CONTROLLER)) + kfree(flag_msp0); + err_msp0: + err_no_pdata: + return status; + +} + +static int msp_remove(struct amba_device *adev) +{ + struct driver_data *drv_data = platform_get_drvdata(adev); + struct device *dev = &adev->dev; + struct nmdk_spi_master_cntlr *platform_info; + int irq; + int status = 0; + if (!drv_data) + return 0; + + platform_info = dev->platform_data; + +#if (defined(CONFIG_NOMADIK_SPI) || defined(CONFIG_NOMADIK_SPI_MODULE)) + /* Remove the queue */ + status = destroy_queue(drv_data); + if (status != 0) { + dev_err(&adev->dev, "queue remove failed (%d)\n", status); + return status; + } + drv_data->execute_cmd(drv_data, LOAD_DEFAULT_CONFIG); + + irq = adev->irq[0]; + if (irq >= 0) + free_irq(irq, drv_data); + + /* Release map resources */ + iounmap(drv_data->regs); + tasklet_disable(&drv_data->pump_transfers); + tasklet_kill(&drv_data->spi_dma_tasklet); + nomadik_gpio_altfuncdisable(platform_info->gpio_alt_func, platform_info->device_name); + + /* Disconnect from the SPI framework */ + spi_unregister_master(drv_data->master); + spi_master_put(drv_data->master); + + /* Prevent double remove */ + platform_set_drvdata(adev, NULL); + dev_dbg(&adev->dev, "remove succeded\n"); +#endif + if(platform_info->id == MSP_0_CONTROLLER) { + if(flag_msp0) + kfree(flag_msp0); + else + printk("MSP Error:why flag_msp0==NULL???"); + } + if(platform_info->id == MSP_1_CONTROLLER) { + if(flag_msp1) + kfree(flag_msp1); + else + printk("MSP Error:why flag_msp1==NULL???"); + } + if(platform_info->id == MSP_2_CONTROLLER) { + if(flag_msp2) + kfree(flag_msp2); + else + printk("MSP Error:why flag_msp2==NULL???"); + } + + return 0; +} + +static struct amba_id msp_ids[] = { + { + .id = MSP_PER_ID, + .mask = MSP_PER_MASK, + }, + {0, 0}, +}; + +static struct amba_driver msp_driver = { + .drv = { + .name = "MSP", + }, + .id_table = msp_ids, + .probe = msp_probe, + .remove = msp_remove +}; + +EXPORT_SYMBOL(nomadik_msp_configure); +EXPORT_SYMBOL(nomadik_msp_send_data); +EXPORT_SYMBOL(nomadik_msp_receive_data); +EXPORT_SYMBOL(nomadik_msp_transceive_data); +EXPORT_SYMBOL(nomadik_msp_enable); +EXPORT_SYMBOL(nomadik_msp_disable); +EXPORT_SYMBOL(nomadik_msp_flush_input); + +static int __init nomadik_msp_mod_init(void) +{ + return amba_driver_register(&msp_driver); +} + +static void __exit nomadik_msp_exit(void) +{ + amba_driver_unregister(&msp_driver); + return; +} +module_init(nomadik_msp_mod_init); +module_exit(nomadik_msp_exit); + +MODULE_AUTHOR("STMicroelectronics Pvt Ltd"); +MODULE_DESCRIPTION("NOMADIK MSP driver"); +MODULE_LICENSE("GPL"); --- /dev/null +++ linux-2.6.20/arch/arm/mach-nomadik/msp.h @@ -0,0 +1,383 @@ +/*linux/drivers/char/nomadik-msp.h + * + * Driver for Nomadik STN8810 MSP device. Note that this module MUST NOT + * attempt to load before the i2c and gpio drivers are loaded. + * + * Copyright 2006 STMicroelectronics Pvt. Ltd. + * + * This program is free sofstware; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + */ + +#ifndef NMDK_MSP_HEADER +#define NMDK_MSP_HEADER + +struct msp_register +{ + u32 fifo; + u32 global_ctrl; + u32 tx_config; + u32 rx_config; + u32 srg_ctrl; + u32 status; + u32 dma_ctrl; + u32 reserved0; + u32 irq_mask; + u32 raw_irq_status; + u32 masked_irq_status; + u32 irq_clear; + u32 multichannel_ctrl; + u32 rx_compare_val; + u32 rx_compare_mask; + u32 reserved1; + u32 tx_enable_ch0; + u32 tx_enable_ch1; + u32 tx_enable_ch2; + u32 tx_enable_ch3; + u32 reserved2[4]; + u32 rx_enable_ch0; + u32 rx_enable_ch1; + u32 rx_enable_ch2; + u32 rx_enable_ch3; + u32 reserved3[4]; + u32 test_ctrl; + u32 integration_test_input; + u32 integration_test_output; + u32 test_data; +}; + +struct msp_context { + u8 direction; + u8 mode; + u8 protocol; + int frame_freq; + int frame_size; + enum msp_data_size requested_data_size; + enum msp_data_size actual_data_size; + + u32 rx_channel_0_enable; + u32 rx_channel_1_enable; + u32 rx_channel_2_enable; + u32 rx_channel_3_enable; + u32 tx_channel_0_enable; + u32 tx_channel_1_enable; + u32 tx_channel_2_enable; + u32 tx_channel_3_enable; + u32 multichannel_ctrl_reg; + u32 rx_compare_mask_reg; + u32 irq_mask_reg; + + u8 compression_mode; + u8 expansion_mode; + u8 coprocessor_mode; + int msp_disable; +}; + + struct msp_mode_status +{ + int work_mode; + int phase_mode; + int stereo_mode; + volatile u16 *it_mono_data_flow; + volatile u32 *it_stereo_data_flow; + volatile u32 it_halfwords_count; + volatile u32 flow_error_count; +} msp_mode_status; + + +/* Single or dual phase mode */ +enum +{ + MSP_SINGLE_PHASE, + MSP_DUAL_PHASE +}; + + +/* Transmit/Receive shifter status +-----------------------------------*/ +enum +{ + MSP_SxHIFTER_IDLE = 0, + MSP_SHIFTER_WORKING = 1 +}; + + +/* Transmit/Receive FIFO status +---------------------------------*/ +enum +{ + MSP_FIFO_FULL, + MSP_FIFO_PART_FILLED, + MSP_FIFO_EMPTY +}; + + +/* Frame length +------------------*/ +enum +{ + MSP_FRAME_LENGTH_1 = 0, + MSP_FRAME_LENGTH_2 = 1, + MSP_FRAME_LENGTH_4 = 3, + MSP_FRAME_LENGTH_8 = 7, + MSP_FRAME_LENGTH_12 = 11, + MSP_FRAME_LENGTH_16 = 15, + MSP_FRAME_LENGTH_20 = 19, + MSP_FRAME_LENGTH_32 = 31, + MSP_FRAME_LENGTH_48 = 47, + MSP_FRAME_LENGTH_64 = 63 +}; + +/* Element length */ +enum +{ + MSP_ELEM_LENGTH_8 = 0, + MSP_ELEM_LENGTH_10 = 1, + MSP_ELEM_LENGTH_12 = 2, + MSP_ELEM_LENGTH_14 = 3, + MSP_ELEM_LENGTH_16 = 4, + MSP_ELEM_LENGTH_20 = 5, + MSP_ELEM_LENGTH_24 = 6, + MSP_ELEM_LENGTH_32 = 7 +}; + + +/* Data delay (in bit clock cycles) +---------------------------------------*/ +enum +{ + MSP_DELAY_0 = 0, + MSP_DELAY_1 = 1, + MSP_DELAY_2 = 2, + MSP_DELAY_3 = 3 +}; + + +/* Configurations of clocks (transmit, receive or sample rate generator) +-------------------------------------------------------------------------*/ +enum +{ + MSP_RISING_EDGE = 0, + MSP_FALLING_EDGE = 1 +}; + +/* Protocol dependant parameters list */ +struct msp_protocol_desc +{ + u32 phase_mode; + u32 frame_len_1; + u32 frame_len_2; + u32 element_len_1; + u32 element_len_2; + u32 data_delay; + u32 tx_clock_edge; + u32 rx_clock_edge; +}; + +#define RX_ENABLE_MASK 0x00000001 +#define RX_FIFO_ENABLE_MASK 0x00000002 +#define RX_FRAME_SYNC_MASK 0x00000004 +#define DIRECT_COMPANDING_MASK 0x00000008 +#define RX_SYNC_SEL_MASK 0x00000010 +#define RX_CLK_POL_MASK 0x00000020 +#define RX_CLK_SEL_MASK 0x00000040 +#define LOOPBACK_MASK 0x00000080 +#define TX_ENABLE_MASK 0x00000100 +#define TX_FIFO_ENABLE_MASK 0x00000200 +#define TX_FRAME_SYNC_MASK 0x00000400 +#define TX_SYNC_SEL_MASK 0x00001800 +#define TX_CLK_POL_MASK 0x00002000 +#define TX_CLK_SEL_MASK 0x00004000 +#define TX_EXTRA_DELAY_MASK 0x00008000 +#define SRG_ENABLE_MASK 0x00010000 +#define SRG_CLK_POL_MASK 0x00020000 +#define SRG_CLK_SEL_MASK 0x000C0000 +#define FRAME_GEN_EN_MASK 0x00100000 +#define SPI_CLK_MODE_MASK 0x00600000 +#define SPI_BURST_MODE_MASK 0x00800000 + +#define RXEN_BIT 0 +#define RFFEN_BIT 1 +#define RFSPOL_BIT 2 +#define DCM_BIT 3 +#define RFSSEL_BIT 4 +#define RCKPOL_BIT 5 +#define RCKSEL_BIT 6 +#define LBM_BIT 7 +#define TXEN_BIT 8 +#define TFFEN_BIT 9 +#define TFSPOL_BIT 10 +#define TFSSEL_BIT 11 +#define TCKPOL_BIT 13 +#define TCKSEL_BIT 14 +#define TXDDL_BIT 15 +#define SGEN_BIT 16 +#define SCKPOL_BIT 17 +#define SCKSEL_BIT 18 +#define FGEN_BIT 20 +#define SPICKM_BIT 21 + +#define msp_rx_clkpol_bit(n) ((n & 1) << RCKPOL_BIT) +#define msp_tx_clkpol_bit(n) ((n & 1) << TCKPOL_BIT) +#define msp_spi_clk_mode_bits(n) ((n & 3) << SPICKM_BIT) + + +/* Use this to clear the clock mode bits to non-spi */ +#define MSP_NON_SPI_CLK_MASK 0x00600000 + +#define P1ELEN_BIT 0 +#define P1FLEN_BIT 3 +#define DTYP_BIT 10 +#define ENDN_BIT 12 +#define DDLY_BIT 13 +#define FSIG_BIT 15 +#define P2ELEN_BIT 16 +#define P2FLEN_BIT 19 +#define P2SM_BIT 26 +#define P2EN_BIT 27 + +#define msp_p1_elem_len_bits(n) (n & 0x00000007) +#define msp_p2_elem_len_bits(n) (((n) << P2ELEN_BIT) & 0x00070000) +#define msp_p1_frame_len_bits(n) (((n) << P1FLEN_BIT) & 0x00000378) +#define msp_p2_frame_len_bits(n) (((n) << P2FLEN_BIT) & 0x03780000) +#define msp_data_delay_bits(n) (((n) << DDLY_BIT) & 0x00003000) +#define msp_data_type_bits(n) (((n) << DTYP_BIT) & 0x00000600) +#define msp_p2_start_mode_bit(n) (n << P2SM_BIT) +#define msp_p2_enable_bit(n) (n << P2EN_BIT) + +/* Flag register +--------------------*/ +#define RX_BUSY 0x00000001 +#define RX_FIFO_EMPTY 0x00000002 +#define RX_FIFO_FULL 0x00000004 +#define TX_BUSY 0x00000008 +#define TX_FIFO_EMPTY 0x00000010 +#define TX_FIFO_FULL 0x00000020 + +#define RBUSY_BIT 0 +#define RFE_BIT 1 +#define RFU_BIT 2 +#define TBUSY_BIT 3 +#define TFE_BIT 4 +#define TFU_BIT 5 + +/* Multichannel control register +---------------------------------*/ +#define RMCEN_BIT 0 +#define RMCSF_BIT 1 +#define RCMPM_BIT 3 +#define TMCEN_BIT 5 +#define TNCSF_BIT 6 + +/* Sample rate generator register +------------------------------------*/ +#define SCKDIV_BIT 0 +#define FRWID_BIT 10 +#define FRPER_BIT 16 + +#define SCK_DIV_MASK 0x0000003FF +#define frame_width_bits(n) (((n) << FRWID_BIT) &0x0000FC00) +#define frame_period_bits(n) (((n) << FRPER_BIT) &0x1FFF0000) + + +/* DMA controller register +---------------------------*/ +#define RX_DMA_ENABLE 0x00000001 +#define TX_DMA_ENABLE 0x00000002 + +#define RDMAE_BIT 0 +#define TDMAE_BIT 1 + +/*Interrupt Register +-----------------------------------------*/ +#define RECEIVE_SERVICE_INT 0x00000001 +#define RECEIVE_OVERRUN_ERROR_INT 0x00000002 +#define RECEIVE_FRAME_SYNC_ERR_INT 0x00000004 +#define RECEIVE_FRAME_SYNC_INT 0x00000008 +#define TRANSMIT_SERVICE_INT 0x00000010 +#define TRANSMIT_UNDERRUN_ERR_INT 0x00000020 +#define TRANSMIT_FRAME_SYNC_ERR_INT 0x00000040 +#define TRANSMIT_FRAME_SYNC_INT 0x00000080 +#define ALL_INT 0x000000ff + +/* Protocol configuration values +* I2S: Single phase, 16 bits, 2 words per frame +-----------------------------------------------*/ +#define I2S_PROTOCOL_DESC \ +{ \ + MSP_SINGLE_PHASE, \ + MSP_FRAME_LENGTH_1, \ + MSP_FRAME_LENGTH_1, \ + MSP_ELEM_LENGTH_32, \ + MSP_ELEM_LENGTH_32, \ + MSP_DELAY_1, \ + MSP_FALLING_EDGE, \ + MSP_FALLING_EDGE \ +} + +/* Companded PCM: Single phase, 8 bits, 1 word per frame +--------------------------------------------------------*/ +#define PCM_COMPAND_PROTOCOL_DESC \ +{ \ + MSP_SINGLE_PHASE, \ + MSP_FRAME_LENGTH_1, \ + MSP_FRAME_LENGTH_1, \ + MSP_ELEM_LENGTH_8, \ + MSP_ELEM_LENGTH_8, \ + MSP_DELAY_0, \ + MSP_RISING_EDGE, \ + MSP_FALLING_EDGE \ +} + +/* AC97: Double phase, 1 element of 16 bits during first phase, +* 12 elements of 20 bits in second phase. +--------------------------------------------------------------*/ +#define AC97_PROTOCOL_DESC \ +{ \ + MSP_DUAL_PHASE, \ + MSP_FRAME_LENGTH_1, \ + MSP_FRAME_LENGTH_12, \ + MSP_ELEM_LENGTH_16, \ + MSP_ELEM_LENGTH_20, \ + MSP_DELAY_1, \ + MSP_RISING_EDGE, \ + MSP_FALLING_EDGE \ +} + +#define SPI_MASTER_PROTOCOL_DESC \ +{ \ + MSP_SINGLE_PHASE, \ + MSP_FRAME_LENGTH_1, \ + MSP_FRAME_LENGTH_1, \ + MSP_ELEM_LENGTH_8, \ + MSP_ELEM_LENGTH_8, \ + MSP_DELAY_1, \ + MSP_FALLING_EDGE, \ + MSP_RISING_EDGE \ +} +#define SPI_SLAVE_PROTOCOL_DESC \ +{ \ + MSP_SINGLE_PHASE, \ + MSP_FRAME_LENGTH_1, \ + MSP_FRAME_LENGTH_1, \ + MSP_ELEM_LENGTH_8, \ + MSP_ELEM_LENGTH_8, \ + MSP_DELAY_1, \ + MSP_FALLING_EDGE, \ + MSP_RISING_EDGE \ +} +#define FUNC_MSP0 GPIO_ALT_MSP_0 +#define FUNC_MSP1 GPIO_ALT_MSP_1 +#define FUNC_MSP2 GPIO_ALT_MSP_2 + +#define MSP_FRAME_PERIOD_IN_MONO_MODE 256 +#define MSP_FRAME_PERIOD_IN_STEREO_MODE 32 +#define MSP_FRAME_WIDTH_IN_STEREO_MODE 16 + +#define MSP_COUNT 3 + +#endif + --- /dev/null +++ linux-2.6.20/arch/arm/mach-nomadik/mtu.c @@ -0,0 +1,589 @@ +/* + * Multiple Timer Unit (MTU) driver. + * Written by Vinayak Pane + * + * Nomadik MTU driver. + * + * This driver provides an interface for device drivers to utilize both MTUs. + * which includes total 8 timers, Those can be registered against various purposes + * within kernel. + * It keeps track of used & unused timer units. It handles MTU interrupts + * & their respective multiplexing. + * + * NOTE: + * This device is NOT registered with amba bus device -: + * Even though this driver should be registered with AMBA bus devices, + * we cant do this becasue of Amba driver initialised/probed sequence issue. + * MTU is used as underlying part of system timer. The system timer + * is initialised and used very early before the actual Amba devices + * are initialised/probed. Therefore this probe function is not invoked + * before the system timer is initialised!! + * However we can catergories this driver in platform/system drivers. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +#ifdef DEBUG_MTU +#define dbg_mtu(format, arg...) printk(KERN_WARNING "" format "\n", ##arg) +#else +#define dbg_mtu(format, arg...) do { } while (0) +#endif + +static irqreturn_t(*mtu_irqs[MTU_MAX_TIMERS + 1]) (mtu_timer_t timer_id) = { +NULL}; +unsigned char mtu_inuse = 0; +static spinlock_t mtu_inuse_lock; + +static spinlock_t mtu0_spinlock, mtu1_spinlock; + + /* functions to read/write control registers */ +static inline unsigned long mtu_readl(unsigned int timer, + unsigned long ctrl_register) +{ + unsigned long value, r_address = MTU_CTRL_REG(timer, ctrl_register); + value = readl(r_address); + return value; +} + +static inline void mtu_writel(unsigned int timer, long value, + unsigned long ctrl_register) +{ + unsigned long w_address = MTU_CTRL_REG(timer, ctrl_register); + writel(value, w_address); +} + + /* functions to read/write interrupt registers */ +inline unsigned long mtu_intr_reg_readl(unsigned int timer, + unsigned long ctrl_register) +{ + unsigned long value, r_address = MTU_INTR_REG(timer, ctrl_register); + value = readl(r_address); + return value; +} + +static inline void mtu_intr_reg_writel(unsigned int timer, long value, + unsigned long ctrl_register) +{ + unsigned long w_address = MTU_INTR_REG(timer, ctrl_register); + writel(value, w_address); +} + +static +void mtu_set_timer_mode(mtu_timer_t timer, mtu_timer_mode_t mode) +{ + unsigned long timer_cr = 0; + + timer_cr = mtu_readl(timer, TyCR); /* read original control register */ + switch (mode) { + case MTU_PERIODIC: + timer_cr &= ~MTU_ONE_SHOT; /* clear the one-shot mode */ + timer_cr = timer_cr | MTU_PERIODIC; + break; + + case MTU_FREE_RUN: + timer_cr = timer_cr & MTU_FREE_RUN; + break; + case MTU_ONE_SHOT: + timer_cr = timer_cr | MTU_ONE_SHOT; + break; + } + mtu_writel(timer, timer_cr, TyCR); /* write back CR */ + dbg_mtu("MTU: timer_mode : after CR = %ld\n", timer_cr); +} + +#define TyEN 0x0080 +static int mtu_enable_timer(mtu_timer_t timer) +{ + unsigned long timer_cr = 0; + if (timer > MTU_MAX_TIMERS) + return -1; + timer_cr = mtu_readl(timer, TyCR); + timer_cr |= TyEN; + mtu_writel(timer, timer_cr, TyCR); + dbg_mtu("MTU: After enable timer CR = %ld\n", timer_cr); + return 0; +} + +static void mtu_disable_timer(mtu_timer_t timer) +{ + unsigned long timer_cr; + timer_cr = mtu_readl(timer, TyCR); + timer_cr &= ~(unsigned long)TyEN; + mtu_writel(timer, timer_cr, TyCR); +} + +#define TySZ 0x0002 +static int mtu_change_counter_size(mtu_timer_t timer) +{ + /* by default the timer counter is 16-bit only, + we can change its size to 32-bit here. */ + + unsigned long timer_cr = 0; + timer_cr = mtu_readl(timer, TyCR); + timer_cr |= TySZ; + mtu_writel(timer, timer_cr, TyCR); + dbg_mtu("MTU: after change_counter_size CR = %ld\n", timer_cr); + return 0; +} + +#define DIVIDE_BY_ONE 0xfffffff3 +#define DIVIDE_BY_SIXTEEN 0x00000004 +#define DIVIDE_BY_256 0x00000008 + +static int mtu_change_timer_prescaler(unsigned int timer, + mtu_prescale_t prescaler_factor) +{ + unsigned long timer_prescaler = 0; + timer_prescaler = mtu_readl(timer, TyCR); + + switch (prescaler_factor) { + case MTU_PRESCALE_BY_ONE: + timer_prescaler &= DIVIDE_BY_ONE; + break; + case MTU_PRESCALE_BY_SIXTEEN: + timer_prescaler &= DIVIDE_BY_ONE; /* reset first */ + timer_prescaler |= DIVIDE_BY_SIXTEEN; /* set it to 01b now */ + break; + case MTU_PRESCALE_BY_256: + timer_prescaler &= DIVIDE_BY_ONE; + timer_prescaler |= DIVIDE_BY_256; + break; + } + mtu_writel(timer, timer_prescaler, TyCR); + return 0; +} +unsigned long mtu_get_decrementing_counter_value(mtu_timer_t timer) +{ + unsigned long decrementing_counter = 0; + decrementing_counter = mtu_readl(timer, TyVAL); + return decrementing_counter; +} + +EXPORT_SYMBOL(mtu_get_decrementing_counter_value); + +static inline void mtu_load_counter(mtu_timer_t timer, + unsigned long timer_load_register) +{ + mtu_writel(timer, timer_load_register, TyLR); +} + +inline void mtu_bg_load_counter(mtu_timer_t timer, + unsigned long timer_load_register) +{ + mtu_writel(timer, timer_load_register, TyBGLR); +} + +EXPORT_SYMBOL(mtu_bg_load_counter); + +/*************************************************************** + * functiion : mtu0_timer_interrupt_handler + * Description: + * Interrupt of MTU Unit 0 is handled. + * With the priority as MTU0_T0, MTU0_T1, + * MTU0_T2, MTU0_T3. And then the corrosponding + * timer unit's interrupt handler will be called. + * Returns: + * IRQ_HANDLED - ret val from the sub-irq + * IRQ_HANDLED - if the corrosponding irq is not present. + ****************************************************************/ + +static irqreturn_t mtu0_timer_interrupt_handler(int irq, void *dev_id) +{ + unsigned long status; + unsigned long icr_flag = 0; + mtu_timer_t timer = 0; + + spin_lock(&mtu0_spinlock); + status = mtu_intr_reg_readl(MTU0_T0, TxRIS); + timer = ffs(status); + if ( timer != 1) + { + icr_flag |= 1UL << (timer - 1); + mtu_intr_reg_writel(timer, icr_flag, TxICR); /* clear ICR bit */ + } + spin_unlock(&mtu0_spinlock); + + if (likely(mtu_irqs[timer])) + return mtu_irqs[timer] (timer); + else { + dbg_mtu("MTU0:Interrupt on this timer[%d] is not handled.\n", + timer); + return IRQ_HANDLED; + } + + return IRQ_HANDLED; +} + +static irqreturn_t mtu1_timer_interrupt_handler(int irq, void *dev_id) +{ + unsigned long status; + unsigned long icr_flag = 0; + mtu_timer_t timer = 0; + + spin_lock(&mtu1_spinlock); + status = mtu_intr_reg_readl(MTU1_T0, TxRIS); + /* which timer the interrupt is for */ + timer = ffs(status); + icr_flag |= 1UL << (timer - 1); + timer = timer + 4; + mtu_intr_reg_writel(timer, icr_flag, TxICR); /* clear ICR bit */ + + spin_unlock(&mtu1_spinlock); + /* call corrsponding Irq handler */ + if (likely(mtu_irqs[timer])) + return mtu_irqs[timer] (timer); + else { + dbg_mtu("MTU1:Interrupt on this timer[%d] is not handled.\n", + timer); + return IRQ_HANDLED; + } + + return IRQ_HANDLED; +} + +struct irqaction mtu0_timer_irq = { + .name = "MTU0 Timer Tick", + .flags = SA_INTERRUPT | IRQF_TIMER, + .handler = mtu0_timer_interrupt_handler, + .dev_id = NULL, +}; + +struct irqaction mtu1_timer_irq = { + .name = "MTU1 Timer Tick", + .flags = SA_INTERRUPT | IRQF_TIMER, + .handler = mtu1_timer_interrupt_handler, + .dev_id = NULL, +}; + +static int mtu_irq_initialize(mtu_timer_t timer, + irqreturn_t(*mtu_sub_irq) (mtu_timer_t timer_id)) +{ + unsigned long icr_flag = 0, clean_icrs = 0; + unsigned long imsc = 0; + unsigned long flags; + + if (mtu_sub_irq == NULL) + return -1; + + spin_lock(&mtu_inuse_lock); + /* make sure that unregistered timer interrupts are cleared + icr_flag = mtu_intr_reg_readl(timer, TxICR); + : returns Zero always. */ + if (timer > 4) + clean_icrs = mtu_inuse >> 4; + else + clean_icrs = mtu_inuse; + /* register the irq sub-handler */ + mtu_irqs[timer] = mtu_sub_irq; + spin_unlock(&mtu_inuse_lock); + + /* the INTR bits/registers will be affected here */ + if (timer > 4) + spin_lock_irqsave(&mtu1_spinlock, flags); + else + spin_lock_irqsave(&mtu0_spinlock, flags); + + icr_flag = ~clean_icrs; + icr_flag |= 1UL << (timer > 4 ? (timer - 5) : (timer - 1)); + mtu_intr_reg_writel(timer, icr_flag, TxICR); + + /* enable interrupt */ + imsc = mtu_intr_reg_readl(timer, TxIMSC); + imsc |= 1UL << (timer > 4 ? (timer - 5) : (timer - 1)); + mtu_intr_reg_writel(timer, imsc, TxIMSC); + + if (timer > 4) + spin_unlock_irqrestore(&mtu1_spinlock, flags); + else + spin_unlock_irqrestore(&mtu0_spinlock, flags); + return 0; +} + +int mtu_register_timer(struct mtu_struct *mtu) +{ + u64 mtu_interval_ns; + mtu_prescale_t mtu_prescale; + if (mtu == NULL) + return -EINVAL; + if (mtu->timer > MTU_MAX_TIMERS) + return -EINVAL; + +#ifndef CONFIG_NOMADIK_MTU_SYSTEM_TICK + /* if the MTU0 IRQ is not set here, we cant use the timers: + * MTU0_T0, MTU0_T1, MTU0_T2 & MTU0_T3 + */ + if (mtu->timer <= 4) { + printk(KERN_WARNING + "MTU: Can not register, since MTU0 support is absent.\n"); + return -EINVAL; + } +#endif + + spin_lock(&mtu_inuse_lock); + if (mtu_inuse & ((unsigned char)0x1 << (mtu->timer - 1))) { + printk(KERN_WARNING + "MTU: This timer unit is already in use.\n"); + spin_unlock(&mtu_inuse_lock); + return -EBUSY; + } else { + mtu_inuse |= (unsigned char)0x1 << (mtu->timer - 1); + } + spin_unlock(&mtu_inuse_lock); + + if (mtu->mtu_irq) { + mtu_irq_initialize(mtu->timer, mtu->mtu_irq); + } else { + printk(KERN_WARNING + "MTU: Must specify the action handler for timer.\n"); + return -EINVAL; + } + + mtu_set_timer_mode(mtu->timer, mtu->mode); + mtu_interval_ns = ktime_to_ns(mtu->interval); + + /* calculate the timer load register value from ktime(sec,nsec) format */ +#if BITS_PER_LONG != 64 + /* XXX the arithmatic part shall be replaced by ktime_ns-ops */ + dbg_mtu("MTU: nano second interval passed is : %lld \n", + mtu_interval_ns); + + if (mtu_interval_ns / USEC_PER_SEC < (0x6FA * MSEC_PER_SEC)) { + mtu_prescale = MTU_PRESCALE_BY_ONE; + mtu_interval_ns = mtu_interval_ns * 24 * MSEC_PER_SEC; + do_div(mtu_interval_ns, 10); + } else { + if (mtu_interval_ns / USEC_PER_SEC < (0xB2F * MSEC_PER_SEC)) { + mtu_prescale = MTU_PRESCALE_BY_SIXTEEN; + mtu_interval_ns = mtu_interval_ns * 15 * MSEC_PER_SEC; + do_div(mtu_interval_ns, 100); + } else { + mtu_prescale = MTU_PRESCALE_BY_256; + mtu_interval_ns = mtu_interval_ns * 93 * MSEC_PER_SEC; + do_div(mtu_interval_ns, 10000); + } + } + + do_div(mtu_interval_ns, USEC_PER_SEC); + + if (mtu_interval_ns >> 32) { + printk(KERN_WARNING + "MTU: The interval specified is too big to fit in reload value.\n"); + spin_lock(&mtu_inuse_lock); + mtu_irqs[mtu->timer] = NULL; + spin_unlock(&mtu_inuse_lock); + return -EINVAL; + } + + dbg_mtu("MTU: setting the prescaler of timer to [%x]\n", mtu_prescale); + mtu_change_timer_prescaler(mtu->timer, mtu_prescale); + + if (mtu_interval_ns >> 16) { + dbg_mtu("MTU: changing the counter size to 32 bits\n"); + mtu_change_counter_size(mtu->timer); + } + + dbg_mtu("MTU:Using %lld as calculated interval for timer\n", + mtu_interval_ns); + /* lets ignore the LSB part now, MTU supports 32bit counter regi only */ + mtu_load_counter(mtu->timer, mtu_interval_ns); + + /* XXX: if BG-load-register is passed we have to calculate the + * mtu_bg_interval_ns load value and then load it. */ + if (mtu->bg_interval.tv64 == mtu->interval.tv64) /* right now, this much is supported */ + mtu_bg_load_counter(mtu->timer, mtu_interval_ns); + + /* finally enable and start the timer */ + mtu_enable_timer(mtu->timer); +#else + printk(KERN_WARNING "MTU:Functionality is not implemented!\n"); +#endif + + return 0; +} + +EXPORT_SYMBOL(mtu_register_timer); + +int mtu_unregister_timer(struct mtu_struct *mtu) +{ + unsigned long icr_clear = 0, imsc; + unsigned long flags; + icr_clear |= + 1UL << (mtu->timer > 4 ? (mtu->timer - 5) : (mtu->timer - 1)); + + spin_lock(&mtu_inuse_lock); + + /* check if the caller has right to unregister this timer */ + if (mtu->mtu_irq != mtu_irqs[mtu->timer]) { + unregister_failed: + spin_unlock(&mtu_inuse_lock); + return -EINVAL; + } + + if ((mtu_inuse & ((unsigned char)0x1 << (mtu->timer - 1))) == 0) { + /* if the timer unit was not registered successfully */ + goto unregister_failed; + } else + /* clear the inuse bit */ + mtu_inuse &= ~((unsigned char)0x1 << (mtu->timer - 1)); + spin_unlock(&mtu_inuse_lock); + + if (mtu->timer > 4) + spin_lock_irqsave(&mtu1_spinlock, flags); + else + spin_lock_irqsave(&mtu0_spinlock, flags); + + mtu_disable_timer(mtu->timer); + + /* disable the interrupt */ + imsc = mtu_intr_reg_readl(mtu->timer, TxIMSC); + imsc &= + ~(1UL << (mtu->timer > 4 ? (mtu->timer - 5) : (mtu->timer - 1))); + mtu_intr_reg_writel(mtu->timer, imsc, TxIMSC); + + /* clear the interrupt of this timer */ + mtu_intr_reg_writel(mtu->timer, icr_clear, TxICR); + + mtu_load_counter(mtu->timer, 0); + + spin_lock(&mtu_inuse_lock); + mtu_irqs[mtu->timer] = NULL; + spin_unlock(&mtu_inuse_lock); + + if (mtu->timer > 4) + spin_unlock_irqrestore(&mtu1_spinlock, flags); + else + spin_unlock_irqrestore(&mtu0_spinlock, flags); + + return 0; +} + +EXPORT_SYMBOL(mtu_unregister_timer); + +static struct { + u32 tmr_value; + u32 tmr_control; + u32 tmr_bgload; +}mtu_tmr_context[8]; + +static u32 nomadik_mtu0_imsc[2]; + +int nomadik_mtu_suspend(void) +{ + /* Use spin lock */ + int inuse = mtu_inuse & ~1; + int tmr_no; + + nomadik_mtu0_imsc[0] = mtu_intr_reg_readl(MTU0_T0, TxIMSC); + nomadik_mtu0_imsc[1] = mtu_intr_reg_readl(MTU1_T0, TxIMSC); + while(inuse) + { + tmr_no = ffs(inuse); + mtu_tmr_context[tmr_no-1].tmr_value = mtu_readl(tmr_no, TyVAL); + mtu_tmr_context[tmr_no-1].tmr_control = mtu_readl(tmr_no, TyCR); + mtu_tmr_context[tmr_no-1].tmr_bgload = mtu_readl(tmr_no, TyBGLR); + inuse = inuse & ~(1 << ( tmr_no - 1 )); + } + return 0; +} + +int nomadik_mtu_resume(void) +{ + /* Use spin lock */ + int inuse = mtu_inuse & ~1; + int tmr_no; + + mtu_intr_reg_writel(MTU0_T0, nomadik_mtu0_imsc[0], TxIMSC); + mtu_intr_reg_writel(MTU1_T0, nomadik_mtu0_imsc[1], TxIMSC); + while(inuse) + { + tmr_no = ffs(inuse); + mtu_writel(tmr_no, mtu_tmr_context[tmr_no - 1].tmr_value, TyLR); + mtu_writel(tmr_no, mtu_tmr_context[tmr_no - 1].tmr_control, TyCR); + mtu_writel(tmr_no, mtu_tmr_context[tmr_no - 1].tmr_bgload, TyBGLR); + inuse = inuse & ~(1 << ( tmr_no - 1 )); + } + return 0; +} + + +int __init nomadik_mtu_init(void) +{ + unsigned long all_icr_clear = 0xf; + volatile unsigned long *psrc_cr = + (volatile unsigned long *)IO_ADDRESS(NOMADIK_SRC_BASE); + unsigned long src_cr; + src_cr = *psrc_cr; + src_cr |= 0x2AAA8000; + *psrc_cr = src_cr; + + spin_lock_init(&mtu0_spinlock); + spin_lock_init(&mtu1_spinlock); + + mtu_irqs[0] = NULL; + /* clear the interrupts */ + + mtu_intr_reg_writel(MTU1_T0, all_icr_clear, TxICR); + + /* + * setup an interrupt for the Timer units + */ +#if defined(CONFIG_MTU0) && defined(CONFIG_NOMADIK_MTU_SYSTEM_TICK) + /* Cannt use if module! It might screw the system "timer_tick" */ + mtu_intr_reg_writel(MTU0_T0, all_icr_clear, TxICR); + + setup_irq(IRQ_MTU0, &mtu0_timer_irq); + printk(KERN_INFO "MTU: Registered MTU0 timer unit.\n"); + + setup_irq(IRQ_MTU1, &mtu1_timer_irq); + printk(KERN_INFO "MTU: Registered MTU1 timer unit.\n"); +#else + request_irq(IRQ_MTU1, mtu1_timer_irq.handler, mtu1_timer_irq.flags, + mtu1_timer_irq.name, NULL); + printk(KERN_INFO "MTU: Registered MTU1 timer unit.\n"); +#endif + + return 0; +} + +void __exit nomadik_mtu_exit(void) +{ + mtu_timer_t timer; + /* disabling the registered timers */ + while (mtu_inuse) { + timer = ffs(mtu_inuse); + mtu_disable_timer(timer); + mtu_inuse &= ~((unsigned char)0x1 << timer); + } + + free_irq(IRQ_MTU1, NULL); + +#if defined(CONFIG_MTU0) && defined(CONFIG_NOMADIK_MTU_SYSTEM_TICK) + free_irq(IRQ_MTU0, NULL); +#endif +} + +#ifndef CONFIG_MTU0 +module_init(nomadik_mtu_init); +#endif +module_exit(nomadik_mtu_exit); + +MODULE_LICENSE("Proprietary"); +MODULE_DESCRIPTION("Nomadik MTU Driver"); +MODULE_AUTHOR("ST Microelectronics"); + +/* vim: set ts=4 noet sw=4 */ --- /dev/null +++ linux-2.6.20/arch/arm/mach-nomadik/ndk10_cut_a1_Kconfig @@ -0,0 +1,28 @@ +if NOMADIK_NDK10_CUT_A1 + +#target name configuration +config NOMADIK_TARGET + string + default NDK10_Cut_A1 + +# nomadik soc chip name configuration for this target +config NOMADIK_SOC + string + default stn8810 + +# nomadik platform name configuration for this target +config NOMADIK_PLATFORM + string + default ndk10 + +# EXTRA_CFLAGS configuration for this target +config NOMADIK_TARGET_EXTRA_CFLAGS + string + default "-D__RELEASE -D__STN_8810=10 -D__PLATFORM_MEVKFULL -D__UART_ELEMENTARY" + +# Basic platform type configuration for this target (optional will be removed latter) +config NOMADIK_NDK10 + bool + default y + +endif --- /dev/null +++ linux-2.6.20/arch/arm/mach-nomadik/ndk10_cut_b06_Kconfig @@ -0,0 +1,35 @@ +if NOMADIK_NDK10_CUT_B06 + +comment "Nomadik chip used STRn8810B2S12HPB cut B (chip secure)" + +#target name configuration for this target +config NOMADIK_TARGET + string + default NDK10_Cut_B06 + +# nomadik soc chip name configuration for this target +config NOMADIK_SOC + string + default stn8810 + +# nomadik soc chip cut name configuration for this targe only +config NOMADIK_STRn8810B2S12HPB + bool + default y + +# nomadik platform name configuration for this target +config NOMADIK_PLATFORM + string + default ndk10 + +# EXTRA_CFLAGS configuration for this target +config NOMADIK_TARGET_EXTRA_CFLAGS + string + default "-D__RELEASE -D__STN_8810=20 -D__PLATFORM_MEVKFULL -D__UART_ELEMENTARY" + +# Basic platform type configuration for this target +config NOMADIK_NDK10 + bool + default y + +endif --- /dev/null +++ linux-2.6.20/arch/arm/mach-nomadik/ndk10_cut_b0_Kconfig @@ -0,0 +1,35 @@ +if NOMADIK_NDK10_CUT_B0 + +comment "Nomadik chip used STRn8810B2S12 cut B" + +#target name configuration for this target +config NOMADIK_TARGET + string + default NDK10_Cut_B0 + +# nomadik soc chip name configuration for this target +config NOMADIK_SOC + string + default stn8810 + +# nomadik soc chip cut name configuration for this targe only +config NOMADIK_STRn8810B2S12 + bool + default y + +# nomadik platform name configuration for this target +config NOMADIK_PLATFORM + string + default ndk10 + +# EXTRA_CFLAGS configuration for this target +config NOMADIK_TARGET_EXTRA_CFLAGS + string + default "-D__RELEASE -D__STN_8810=20 -D__PLATFORM_MEVKFULL -D__UART_ELEMENTARY" + +# Basic platform type configuration for this target +config NOMADIK_NDK10 + bool + default y + +endif --- /dev/null +++ linux-2.6.20/arch/arm/mach-nomadik/ndk10_devices.c @@ -0,0 +1,1225 @@ +/* + * linux/arch/arm/mach-nomadik/ndk10_devices.c + * + * Copyright (C) 2000-2003 Deep Blue Solutions Ltd + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef CONFIG_MTD +#include +#include +#include +#include +#include +#include +#include +#endif +#include + +/* + * epio + */ +#define EPIO_NAME "EPIO" + +#ifndef EPIO_DEBUG +#define EPIO_DEBUG 0 +#endif + +#define NMDK_DEBUG EPIO_DEBUG /* enables/disables nmdk_dbg msgs */ +#define NMDK_DEBUG_PFX EPIO_NAME /* msg header represents this module */ +#define NMDK_DBG KERN_ERR /* message level */ + +static spinlock_t epio_cob_ctl_read = SPIN_LOCK_UNLOCKED; +static spinlock_t epio_cob_ctl_write = SPIN_LOCK_UNLOCKED; +static spinlock_t epio_kp_read = SPIN_LOCK_UNLOCKED; +static spinlock_t epio_kp_write = SPIN_LOCK_UNLOCKED; + +static unsigned long epio_lgcl_addr_cob_ident_reg; +static unsigned long epio_lgcl_addr_cob_ctl_reg; +static unsigned long epio_lgcl_addr_kp_reg; +static unsigned long epio_lgcl_addr_exp_ctrl_reg; +static spinlock_t epio_exp_ctrl_read = SPIN_LOCK_UNLOCKED; +static spinlock_t epio_exp_ctrl_write = SPIN_LOCK_UNLOCKED; + +/* + * nomadik_epio_read_cob_ident - reads COB_IDENT register of CPLD + * + * Reads the core bord version and CPLD version information stored in + * COB_IDENT register of CPLD on NDK10 + */ +static short nomadik_epio_read_cob_ident(void) +{ + return ((short) + *((volatile unsigned short *)epio_lgcl_addr_cob_ident_reg)); +} + +/** + * nomadik_epio_read_cob_ctl - reads COB_CTL register of CPLD + * + * Reads the present value of the core-board-configuration register of CPLD + * on NDK10 board + */ +short nomadik_epio_read_cob_ctl(void) +{ + short i; + + spin_lock(&epio_cob_ctl_read); + i = *((volatile unsigned short *)epio_lgcl_addr_cob_ctl_reg); + spin_unlock(&epio_cob_ctl_read); + return (i); +} + +/** + * nomadik_epio_write_cob_ctl - writes COB_CTL register of CPLD + * @expctrlval: value to be written + * + * Write the provided 16bit value into the core-board-configuration register + * of CPLD on NDK10 board + */ +void nomadik_epio_write_cob_ctl(unsigned short expctrlval) +{ + spin_lock(&epio_cob_ctl_write); + *((volatile unsigned short *)epio_lgcl_addr_cob_ctl_reg) = expctrlval; + spin_unlock(&epio_cob_ctl_write); +} + +/** + * nomadik_epio_read_keypad - reads KEYPAD register of CPLD + * + * Reads the present value of the keypad assignment register of CPLD on NDK10 + */ +short nomadik_epio_read_keypad(void) +{ + short i; + + spin_lock(&epio_kp_read); + i = (0x07FF & *((volatile unsigned short *)epio_lgcl_addr_kp_reg)); + spin_unlock(&epio_kp_read); + return (i); +} + +/** + * nomadik_epio_write_keypad - writes KEYPAD register of CPLD + * @keypadval: value to be written + * + * Writes the provided value to the keypad assignment reg of CPLD on NDK10 + */ +void nomadik_epio_write_keypad(unsigned short kpdval) +{ + unsigned short i; + + spin_lock(&epio_kp_write); + i = *((volatile unsigned short *)epio_lgcl_addr_kp_reg); + i &= 0xF800; + i |= kpdval & 0x07ff; + *((volatile unsigned short *)epio_lgcl_addr_kp_reg) = i; + spin_unlock(&epio_kp_write); +} + +/** + * nomadik_epio_read_exp_ctrl - reads exp ctrl register of CPLD + * + * Reads the 16bit value of the expansion-board-control register of CPLD on NDK10 + */ +short nomadik_epio_read_exp_ctrl(void) +{ + short i = 0; + spin_lock(&epio_exp_ctrl_read); + i = *((volatile unsigned short *)epio_lgcl_addr_exp_ctrl_reg); + spin_unlock(&epio_exp_ctrl_read); + return (i); +} + +/** + * nomadik_epio_write_exp_ctrl - writes exp ctrl register of CPLD + * @expctrlval: value to be written + * + * Writes the provided 16bit value into the expansion-board-control register + * of CPLD on NDK10 + */ +void nomadik_epio_write_exp_ctrl(unsigned short expctrlval) +{ + spin_lock(&epio_exp_ctrl_write); + *((volatile unsigned short *)epio_lgcl_addr_exp_ctrl_reg) = expctrlval; + spin_unlock(&epio_exp_ctrl_write); +} + +/** + * nomadik_epio_init - epio module init call. + */ +static int __init nomadik_epio_init(void) +{ + unsigned short i; + + nmdk_dbg_ftrace(); + epio_lgcl_addr_cob_ident_reg = + (unsigned long)ioremap(NOMADIK_CPLD_BASE + 0x000, (unsigned long)2); + epio_lgcl_addr_cob_ctl_reg = + (unsigned long)ioremap(NOMADIK_CPLD_BASE + 0x002, (unsigned long)2); + epio_lgcl_addr_kp_reg = + (unsigned long)ioremap(NOMADIK_CPLD_BASE + 0x004, (unsigned long)2); + epio_lgcl_addr_exp_ctrl_reg = + (unsigned long)ioremap(NOMADIK_CPLD_BASE + 0x006, (unsigned long)2); + + i = nomadik_epio_read_cob_ident(); + nmdk_info("Core Board Revision %d.%d, CPLD Code Revision %d.%d", + (i & COB_REV_BITS) >> COB_REV_BITS_POS, + (i & COB_REV_SUBBITS) >> COB_REV_SUBBITS_POS, + (i & CPLD_REV_BITS) >> CPLD_REV_BITS_POS, + (i & CPLD_REV_SUBBITS)); + return 0; +} +#undef NMDK_DEBUG /*epio*/ +#undef NMDK_DEBUG_PFX +#undef NMDK_DBG + +/* + * board init + */ +#define BOARD_NAME CONFIG_NOMADIK_PLATFORM +#ifndef BOARD_DEBUG +#define BOARD_DEBUG 0 +#endif + +#define NMDK_DEBUG BOARD_DEBUG /* enables/disables nmdk_dbg msgs */ +#define NMDK_DEBUG_PFX BOARD_NAME /* msg header represents this module */ +#define NMDK_DBG KERN_ERR /* message level */ + +void __init nomadik_pepperpot_board_init(void) +{ + int err; + nomadik_epio_write_cob_ctl(nomadik_epio_read_cob_ctl() | CAM_SHDNnot | + CAM_RSTnot); + err = 0; + while (err < 0xffffff) + err++; + nomadik_epio_write_exp_ctrl(nomadik_epio_read_exp_ctrl() | 0x1000); + err = 0; + while (err < 0xffffff) + err++; +} + +void __init nomadik_platform_board_init(void) +{ + unsigned char __iomem *gpio0_base; + unsigned char __iomem *gpio1_base; + unsigned char __iomem *cpld_base; + unsigned char __iomem *rgpo1_base; + unsigned char __iomem *pmu_base; + unsigned char __iomem *base; + + gpio0_base = (unsigned char *)IO_ADDRESS(NOMADIK_GPIO0_BASE); + gpio1_base = (unsigned char *)IO_ADDRESS(NOMADIK_GPIO1_BASE); + + rgpo1_base = (unsigned char *)IO_ADDRESS(NOMADIK_CPLD_RGPO1_BASE); + cpld_base = ioremap(NOMADIK_CPLD_BASE, SZ_4K); + base = ioremap(0x36400000, SZ_4K); + + /* + * Set Display control LCD* + * Set bit 26 of pmu->ctrl register to 0. CLCD/DIF selection + */ + pmu_base = (unsigned char *)IO_ADDRESS(NOMADIK_PMU_BASE); + writel((0xFBBFFFFF & readl(pmu_base)), pmu_base); + + /* + * Enabling alt func A for gpio0-gpio7 :UART0 + */ + writel(0xff, gpio0_base + 0x20); + + /* + * Enabling alt func A for gpio51,52,56,57 :UART1 + */ + writel(0x3180000, gpio1_base + 0x20); + + /* + * Enabling alt func B for gpio32-39 + */ + writel(0xff, gpio1_base + 0x24); + + /* + * Change in cpld register on cob10 + * UART1 trasnceiver enable, uart0 enable + */ + writew((0x218 | (readw(cpld_base + 02) & ~(0x238))), (cpld_base + 02)); + + /* + * CPLD setting for pepperport camera poweron + * + */ + writew((0xc00 | readw(cpld_base + 02)), (cpld_base + 02)); + + /* + * Setting as copied from CMM file (backlite disabled) + */ + writew(0xc000, base); + writew(0x900f, rgpo1_base); + writew(0x53ff, cpld_base + 6); + writew(0xdfff, rgpo1_base); + writew(0x8001, rgpo1_base); + + writew(readw(cpld_base + 0x6) | 0x1000, cpld_base + 6); + + /* + * Change in cpld uib register + * Enable uart0 + */ + writew((0x8000 | readw(rgpo1_base)), rgpo1_base); + + iounmap(cpld_base); + iounmap(base); + printk("%s done\n", __FUNCTION__); +} + +/** + * nomadik_clcd_board_enable - enables board specific clcd prameters + * + * Settings to enable backlight and pannel voltage regulator for NDK10 + * bit 10 to set backlight on, bit 11 to set LCD power regulator on + */ +void nomadik_clcd_enable(void *fbp) +{ +#if defined (CONFIG_FB_NOMADIK_QVGA_PORTRAIT) + nomadik_epio_write_exp_ctrl(nomadik_epio_read_exp_ctrl() | 0x0c00); +#endif +} + +/** + * nomadik_clcd_board_disable - disables board specific clcd prameters + * + * Settings to disable backlight and pannel voltage regulator for NDK10 + * bit 10 to reset backlight off, bit 11 to reset LCD power regulator off + */ +void nomadik_clcd_disable(void *fbp) +{ +#if defined (CONFIG_FB_NOMADIK_QVGA_PORTRAIT) + nomadik_epio_write_exp_ctrl(nomadik_epio_read_exp_ctrl() & (~0x0c00)); +#endif +} + +/* + * Settings to configure MMC controller for NDK10 + */ +int nomadik_mmc_configure(struct amba_device *dev) +{ + int ret; + gpio_config mmc_pin; + char x = val_volt; + + nomadik_epio_write_exp_ctrl(nomadik_epio_read_exp_ctrl() | + MASK_MMC_EPIO); + mmc_pin.dev_name = "mmc"; + mmc_pin.mode = GPIO_MODE_SOFTWARE; + mmc_pin.direction = GPIO_DIR_OUTPUT; + mmc_pin.trig = GPIO_TRIG_DISABLE; + mmc_pin.debounce = GPIO_DEBOUNCE_DISABLE; + + ret = nomadik_gpio_setpinconfig(GPIO_PIN_75, &mmc_pin); + if (ret) { + nmdk_error("Error in setting GPIO_PIN_75"); + goto exit_last; + } + /* this enables power path from toureg to mmc */ + ret = nomadik_gpio_writepin(GPIO_PIN_75, GPIO_DATA_HIGH, "mmc"); + if (ret) { + nmdk_error("Error in setting GPIO_PIN_75 value to HIGH"); + goto deallocate_pin_75; + } + + ret = nomadik_i2c_write_register(I2C_TOUAREG_CLIENT, &x, 0x11, 1); + if (ret) { + nmdk_error("Error in writing value to touareg register"); + goto deallocate_pin_75; + } + + ret = nomadik_gpio_altfuncenable(GPIO_ALT_SD_CARD, "mmc"); + if (ret) { + nmdk_error("Error in gpio Altfunction enable"); + goto deallocate_pin_75; + } + return ret; + + deallocate_pin_75: + nomadik_gpio_resetpinconfig(GPIO_PIN_75, "mmc"); + nomadik_epio_write_exp_ctrl(nomadik_epio_read_exp_ctrl() & + ~MASK_MMC_EPIO); + exit_last: + return ret; + +} + +void nomadik_mmc_restore_default(struct amba_device *dev) +{ + nomadik_gpio_altfuncdisable(GPIO_ALT_SD_CARD, "mmc"); + nomadik_gpio_resetpinconfig(GPIO_PIN_75, "mmc"); + + nomadik_epio_write_exp_ctrl(nomadik_epio_read_exp_ctrl() & + ~MASK_MMC_EPIO); +} + +/* + * nomadik_fsmc_init - fsmc initialization on system start + */ +static __init void nomadik_fsmc_init(void) +{ + unsigned char __iomem *fsmc_base; + + nmdk_dbg_ftrace(); + /*Following Settings done for NAND flash protect off */ + fsmc_base = (unsigned char *)IO_ADDRESS(NOMADIK_FSMC_BASE); + + /* for NOR accesss */ + /* Initialize the fsmc bank 0 */ + *((volatile u32 *)(NOMADIK_FSMC_VA + FSMC_BCR0)) = 0x10db; + *((volatile u32 *)(NOMADIK_FSMC_VA + FSMC_BTR0)) = 0x03333333; + /* Initialize the fsmc bank 1 */ + *((volatile u32 *)(NOMADIK_FSMC_VA + FSMC_BCR1)) = 0x10db; + *((volatile u32 *)(NOMADIK_FSMC_VA + FSMC_BTR1)) = 0x00000702; + + *((volatile u32 *)(NOMADIK_FSMC_VA + FSMC_BCR0)) |= 0x80; + /* Above Settings done for NAND flash protect off */ +} + +int nomadik_pepperpot_init(void) +{ + int err; + nomadik_epio_write_cob_ctl(nomadik_epio_read_cob_ctl() | CAM_SHDNnot | + CAM_RSTnot); + err = 0; + while (err < 0xffffff) + err++; + nomadik_epio_write_exp_ctrl(nomadik_epio_read_exp_ctrl() | 0x1000); + err = 0; + while (err < 0xffffff) + err++; + + return 0; +} + +EXPORT_SYMBOL(nomadik_pepperpot_init); + +#ifdef CONFIG_MTD + +static struct resource nandflash_resources[] = { + [0] = { + .name = "cmem_address", + .start = NAND_B0_CMEM_ADDR, + .end = (NAND_B0_CMEM_ADDR + SZ_1K - 1), + .flags = IORESOURCE_MEM, + }, + [1] = { + .name = "cmem_command", + .start = NAND_B0_CMEM_CMD, + .end = (NAND_B0_CMEM_CMD + SZ_1K - 1), + .flags = IORESOURCE_MEM, + }, + [2] = { + .name = "cmem_data", + .start = NAND_B0_CMEM_DATA, + .end = (NAND_B0_CMEM_DATA + SZ_1K - 1), + .flags = IORESOURCE_MEM, + }, +}; + +#define NAND_STM_LP_OPTIONS \ + (NAND_BUSWIDTH_16 | NAND_COPYBACK | NAND_CACHEPRG | NAND_NO_PADDING) + +int nomadik_nandflash_exit(void) +{ + if(nomadik_gpio_resetpinconfig(NAND_GPIO, "nand")) + return -1; + return 0; +} + +void nomadik_nandflash_init(void) +{ + /* + * FSMC initialization + * 0x0000001e => PCR0 + * 0x000d0a00 => PMEM0 + * 0x00100a00 => PATT0 + */ + +/* pcr0.address_low = 0;*/ + gpio_config nmdknand_pin_config; + nmdknand_pin_config.dev_name = "nand"; + nmdknand_pin_config.mode = GPIO_MODE_SOFTWARE; + nmdknand_pin_config.direction = GPIO_DIR_OUTPUT; + nmdknand_pin_config.trig = GPIO_TRIG_DISABLE; + nmdknand_pin_config.debounce = GPIO_DEBOUNCE_UNCHANGED; + if(nomadik_gpio_setpinconfig(NAND_GPIO, &nmdknand_pin_config)) + return -1; + if(nomadik_gpio_writepin(NAND_GPIO, 1, "nand")) + return -1; + + + *((volatile unsigned long *)(NOMADIK_FSMC_VA + FSMC_PCR0)) = + DEFAULT_PCR0_VALUE; + *((volatile unsigned long *)(NOMADIK_FSMC_VA + FSMC_PMEM0)) = + DEFAULT_PMEM0_VALUE; + *((volatile unsigned long *)(NOMADIK_FSMC_VA + FSMC_PATT0)) = + DEFAULT_PATT0_VALUE; + return 0; +} + +static const unsigned char lookup_t[256] = { + 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, + 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, + 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, + 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, + 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, + 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, + 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, + 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, + 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, + 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, + 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, + 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, + 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, + 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, + 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, + 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0 +}; + +int nmdknand_compute_ecc512(struct mtd_info *mtd, unsigned char *data, + unsigned char ecc[3]) +{ + unsigned int sumCol = 0; + unsigned int datum, temp; + unsigned int glob_parity; + const int ecc_n_bytes = 512; + int i; + + unsigned int parit1_1, parit1_2, parit2_1, parit2_2, parit4_1, parit4_2; + unsigned int parit8_1 = 0, parit8_2 = 0, parit16_1 = 0, parit16_2 = + 0, parit32_1 = 0, parit32_2 = 0; + unsigned int parit64_1 = 0, parit64_2 = 0, parit128_1 = 0, parit128_2 = + 0, parit256_1 = 0, parit256_2 = 0; + unsigned int parit512_1 = 0, parit512_2 = 0, parit1024_1 = + 0, parit1024_2 = 0, parit2048_1 = 0, parit2048_2 = 0; + + for (i = ecc_n_bytes - 1; i >= 0; --i) { + datum = data[i]; + sumCol ^= datum; + temp = lookup_t[datum]; + + if (i & 0x01) + parit8_1 ^= temp; + if (i & 0x02) + parit16_1 ^= temp; + if (i & 0x04) + parit32_1 ^= temp; + if (i & 0x08) + parit64_1 ^= temp; + if (i & 0x10) + parit128_1 ^= temp; + if (i & 0x20) + parit256_1 ^= temp; + if (i & 0x40) + parit512_1 ^= temp; + if (i & 0x80) + parit1024_1 ^= temp; + if (i & 0x100) + parit2048_1 ^= temp; + } + + glob_parity = lookup_t[sumCol]; + + parit1_1 = + ((sumCol >> 1) ^ (sumCol >> 3) ^ (sumCol >> 5) ^ (sumCol >> 7)) & 1; + parit1_2 = + ((sumCol >> 0) ^ (sumCol >> 2) ^ (sumCol >> 4) ^ (sumCol >> 6)) & 1; + parit2_1 = + ((sumCol >> 2) ^ (sumCol >> 3) ^ (sumCol >> 6) ^ (sumCol >> 7)) & 1; + parit2_2 = + ((sumCol >> 0) ^ (sumCol >> 1) ^ (sumCol >> 4) ^ (sumCol >> 5)) & 1; + parit4_1 = + ((sumCol >> 4) ^ (sumCol >> 5) ^ (sumCol >> 6) ^ (sumCol >> 7)) & 1; + parit4_2 = + ((sumCol >> 0) ^ (sumCol >> 1) ^ (sumCol >> 2) ^ (sumCol >> 3)) & 1; + + parit8_2 = glob_parity ^ parit8_1; + parit16_2 = glob_parity ^ parit16_1; + parit32_2 = glob_parity ^ parit32_1; + parit64_2 = glob_parity ^ parit64_1; + parit128_2 = glob_parity ^ parit128_1; + parit256_2 = glob_parity ^ parit256_1; + parit512_2 = glob_parity ^ parit512_1; + parit1024_2 = glob_parity ^ parit1024_1; + parit2048_2 = glob_parity ^ parit2048_1; + + /* Pack bits */ + ecc[0] = + ~((parit64_1 << 7) | (parit64_2 << 6) | (parit32_1 << 5) | + (parit32_2 << 4) | (parit16_1 << 3) | (parit16_2 << 2) | (parit8_1 + << 1) | + parit8_2); + ecc[1] = + ~((parit1024_1 << 7) | (parit1024_2 << 6) | (parit512_1 << 5) | + (parit512_2 << 4) | (parit256_1 << 3) | (parit256_2 << 2) | + (parit128_1 << 1) | parit128_2); + ecc[2] = + ~((parit4_1 << 7) | (parit4_2 << 6) | (parit2_1 << 5) | + (parit2_2 << 4) | (parit1_1 << 3) | (parit1_2 << 2) | (parit2048_1 + << 1) | + parit2048_2); + + return 0; +} + +static struct nand_ecclayout nand_oob = { + .eccbytes = 6, + .eccpos = {2, 3, 4, 5, 6, 7}, + .oobavail = MTD_NANDECC_AUTOPLACE, + .oobfree = { + { .offset = 8, + .length = 8, + }, + }, +}; + +#ifdef CONFIG_NOMADIK_NDK10_CUT_B06 +static struct mtd_partition nandflash_main_partitions[] = { + + {.name = "X-Loader(NAND)", + .offset = 0, + .size = 2 * 0x000020000}, /*256 Kbytes */ + {.name = "MemInit(NAND)", + .offset = 2 * 0x000020000, + .size = 2 * 0x000020000}, /*128 KBytes */ + {.name = "BootLoader(NAND)", + .offset = 4 * 0x000020000, + .size = 16 * 0x00020000}, /*2Mbytes */ + {.name = "Kernel zImage(NAND)", + .offset = 20 * 0x000020000, + .size = 24 * 0x000020000}, /*3Mbytes */ + {.name = "Root Filesystem(NAND)", + .offset = 44 * 0x000020000, + .size = 176 * 0x000020000}, /*22 Mbytes */ + {.name = "User Filesystem(NAND)", + .offset = 220 * 0x000020000, + .size = 800 * 0x000020000}, /*100 Mbytes */ +}; +#else +static const struct mtd_partition nandflash_main_partitions[] = { + {.name = "X-Loader(NAND)", + .offset = 0, + .size = 4 * 0x00004000}, + {.name = "MemInit(NAND)", + .offset = 4 * 0x00004000, + .size = 1 * 0x00004000}, + {.name = "BootLoader(NAND)", + .offset = 5 * 0x00004000, + .size = 16 * 0x0004000}, + {.name = "Kernel zImage(NAND)", + .offset = 21 * 0x00004000, + .size = 3 * 0x00100000}, + {.name = "Root Filesystem(NAND)", + .offset = 0x354000, + .size = 0x0a00000}, + {.name = "User Filesystem(NAND)", + .offset = 0xd54000, + .size = 0x12aC000}, +}; + +#endif + +static uint8_t scan_ff_pattern[] = { 0xff, 0xff }; + +static struct nand_bbt_descr bbt_desc = { + .options = 0, + .offs = 0, + .len = 2, + .pattern = scan_ff_pattern +}; + +static void nmdknand_hwcontrol(struct mtd_info *mtd, int cmd, + unsigned int ctrl) +{ + struct nomadik_nand_info *drvdata = + container_of(mtd, struct nomadik_nand_info, mtd); + + if (cmd == NAND_CMD_NONE) + return; + + if (ctrl & NAND_NCE) { + *((volatile unsigned long *)(IO_ADDRESS(NOMADIK_FSMC_BASE) + + 0x40)) |= 0x04; + } + if (ctrl & NAND_CLE) { + writeb(cmd,drvdata->cmemc_va); + } + if (ctrl & NAND_ALE) { + writeb(cmd,drvdata->cmema_va); + } +} + +static struct nomadik_nand_platform_data nomadik_nand_flash_data = { + .parts = nandflash_main_partitions, + .num_parts = ARRAY_SIZE(nandflash_main_partitions), + .lp_options = NAND_STM_LP_OPTIONS, + .eccsize = 512, + .eccsteps = 1, + .badblockpos = 1, + .init = nomadik_nandflash_init, + .exit = nomadik_nandflash_exit, + .nand_oob = &nand_oob, + .bbt_desc = &bbt_desc, + .compute_ecc = nmdknand_compute_ecc512, + .hwcontrol = nmdknand_hwcontrol, +}; + +static struct platform_device nomadik_nand_flash = { + .name = "NOMADIK-NAND", + .id = 0, + .dev = { + .platform_data = &nomadik_nand_flash_data, + }, + .num_resources = ARRAY_SIZE(nandflash_resources), + .resource = nandflash_resources, +}; + +static struct mtd_partition nmdkflash_main_partitions[] = { + {.name = "BootLoader(NOR)", + .size = 0x00040000, /*256K */ + .offset = 0,}, + {.name = "Kernel zImage(NOR)", + .size = 0x001C0000, /*1.75MB */ + .offset = MTDPART_OFS_APPEND,}, + {.name = "Root Filesystem(NOR)", + .size = 0x01200000, /*18MB */ + .offset = MTDPART_OFS_APPEND,}, + {.name = "User Filesystem(NOR)", + .size = 0x00800000, /*8MB */ + .offset = MTDPART_OFS_APPEND,}, + {.name = "initrd(NOR)", + .size = 0x00200000, /*4MB */ + .offset = MTDPART_OFS_APPEND,} +}; + +static struct flash_platform_data nomadik_nor_flash_data = { + .name = "nomadik_nor", + .map_name = "cfi_probe", + //.width = NMDK_FLASH_BUSWIDTH, + .parts = nmdkflash_main_partitions, + .nr_parts = ARRAY_SIZE(nmdkflash_main_partitions), +}; + +static struct resource norflash_resources[] = { + [0] = { + .name = "norflash-regs", + .start = NMDK_FLASH_BASE, + .end = (NMDK_FLASH_BASE + SZ_16M - 1), + .flags = IORESOURCE_MEM, + }, + [1] = { + .name = "norflash-regs", + .start = NMDK_FLASH_BASE + SZ_16M, + .end = (NMDK_FLASH_BASE + SZ_32M - 1), + .flags = IORESOURCE_MEM, + }, +}; + +static struct platform_device nomadik_nor_flash = { + .name = "NOMADIK-NOR", + .id = 0, + .dev = { + .platform_data = &nomadik_nor_flash_data, + }, + .num_resources = ARRAY_SIZE(norflash_resources), + .resource = norflash_resources, +}; + +#endif + +static void nomadik_smc91x_irq_init(void) +{ + int err; + gpio_config smx91x_clkpin; + + smx91x_clkpin.dev_name = "smc91x"; + smx91x_clkpin.mode = GPIO_ALTF_A; + err = nomadik_gpio_setpinconfig(GPIO_PIN_55, &smx91x_clkpin); + if (err) { + nmdk_error("Error in configuring pin%d for clkout", GPIO_PIN_55); + } + + /* disable NOR flash write protection */ + /* CHECK if this clashes with NOR and NAND settings of FSMC */ + *((volatile unsigned short *)(NOMADIK_CPLD_RGPO1_VA)) |= + ETH_DAUGHTER_CARD_RESET; + + set_irq_type(IRQNO_GPIO(SMC91111_IRQ), SA_TRIGGER_RISING); +} + +static struct resource smc91x_resources[] = { + [0] = { + + .name = "smc91x-regs", + .start = (NOMADIK_ETH0_BASE + 0x300), + .end = (NOMADIK_ETH0_BASE + SZ_64M - 1), + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQNO_GPIO(SMC91111_IRQ), + .end = IRQNO_GPIO(SMC91111_IRQ), + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device smc91x_device = { + .name = "smc91x", + .id = 0, + .num_resources = ARRAY_SIZE(smc91x_resources), + .resource = smc91x_resources, +}; + +/* + * touchpanel + */ +#ifndef TOUCHP_DEBUG +#define TOUCHP_DEBUG 0 /* default debug messages are disabled */ +#endif /* */ + +#undef NMDK_DEBUG +#undef NMDK_DEBUG_PFX +#undef NMDK_DBG +#define NMDK_DEBUG TOUCHP_DEBUG /* enables/disables debug msgs */ +#define NMDK_DEBUG_PFX TPDRVNAME /* msg header represents this module */ +#define NMDK_DBG KERN_ERR /* message level */ + +/** + * nomadik_tp_ssp_board_init - board specific ssp data path setup + * + * This routine initializes the SSP for touchpanel operation + * SSP is interfaced with ADS7843 through CPLD hence respective + * interface need to be enabled for NDK10 + * make bit COB_CTL(MSP2_SSP_SWAP) low to connect STn8810 SSP to EXP SSP + * make bit COB_CTL(SSP_EN) high to enable SSP on STn8810 side + */ +int nomadik_tp_ssp_board_init(struct t_adsContext *p_adsContext) +{ + nmdk_dbg_ftrace(); + nomadik_epio_write_cob_ctl((nomadik_epio_read_cob_ctl() & + (~MSP2_SSP_SWAP)) | SSP_EN); + return (0); +} + +/** + * nomadik_tp_gpio_board_init - board specific gpio initialization + * @mode: mode of operation (polling[0] or interrupt[<0] + * + * This routine initializes the GPIO for touchpanel operation + * RETURN: GPIO nmdk_error code + */ +gpio_error nomadik_tp_gpio_board_init(struct t_adsContext * p_adsContext) +{ + gpio_error status = GPIO_OK; + nmdk_dbg_ftrace(); + + /* Set PENIRQ pin configuration */ + set_irq_type(p_adsContext->irq, SA_TRIGGER_RISING); + /* Enable GPIOs through CPLD for access/interrupts on ndk10 */ + nomadik_epio_write_cob_ctl(nomadik_epio_read_cob_ctl() | GPIO_EN); + + return status; +} + +/** + * nomadik_tp_pen_down - returns pen touch status + */ +t_bool nomadik_tp_pen_down(struct t_adsContext * p_adsContext) +{ + gpio_data pen_down; + + nmdk_dbg_ftrace(); + nomadik_gpio_readpin(GPIO_PIN_FOR_IRQ(p_adsContext->irq), &pen_down); + nmdk_dbg2("%s(): pen_down = 0x%d", __FUNCTION__, pen_down); + return ((t_bool) pen_down); +} + +/** + * nomadik_tp_pen_down_irq_enable - enables pen interrupt + */ +void nomadik_tp_pen_down_irq_enable(struct t_adsContext *p_adsContext) +{ + nmdk_dbg_ftrace(); +// enable_irq(p_adsContext->irq); +} + +/** + * nomadik_tp_pen_down_irq_disable - disables pen interrupt + */ +void nomadik_tp_pen_down_irq_disable(struct t_adsContext *p_adsContext) +{ + nmdk_dbg_ftrace(); +// disable_irq(p_adsContext->irq); +} + +/** + * nomadik_tp_spi_cs_disable - disables the chip select for ads7843 + * + * set TOUCHP_SSP_CS pin high to disable SSP chip select for ads7843 + */ +void nomadik_tp_spi_cs_disable(void) +{ + nmdk_dbg_ftrace(); + nomadik_epio_write_exp_ctrl(nomadik_epio_read_exp_ctrl() | + TOUCHP_SSP_CS); +} + +/** + * nomadik_tp_spi_cs_enaable - enables the chip select for ads7843 + * + * set TOUCHP_SSP_CS pin low to enable SSP chip select for ads7843 + */ +void nomadik_tp_spi_cs_enable(void) +{ + nmdk_dbg_ftrace(); + nomadik_epio_write_exp_ctrl(nomadik_epio_read_exp_ctrl() & + (~TOUCHP_SSP_CS)); +} + +static struct touchp_device touchp_board = { + .ssp_init = nomadik_tp_ssp_board_init, + .gpio_init = nomadik_tp_gpio_board_init, + .pdown = nomadik_tp_pen_down, + .pirq_en = nomadik_tp_pen_down_irq_enable, + .pirq_dis = nomadik_tp_pen_down_irq_disable, + .cs_en = nomadik_tp_spi_cs_disable, + .cs_dis = nomadik_tp_spi_cs_enable, + .samples = 100, /*samples per second*/ + .pollsamples = 10, /*polling per second*/ +}; + +static struct resource touchp_resources[] = { + [0] = { + .start = IRQNO_GPIO(TOUCHP_IRQ), + .end = IRQNO_GPIO(TOUCHP_IRQ), + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device touchp_device = { + .name = "nmdk-tp", + .id = 0, + .dev = { + .platform_data = &touchp_board, + }, + .num_resources = ARRAY_SIZE(touchp_resources), + .resource = touchp_resources, +}; + +/* + *********************************************************************** + */ +#define KEYPAD_NAME "KEYPAD" + +#ifndef KEYPAD_DEBUG +#define KEYPAD_DEBUG 0 +#endif + +#undef NMDK_DEBUG +#undef NMDK_DEBUG_PFX +#undef NMDK_DBG +#define NMDK_DEBUG KEYPAD_DEBUG /* enables/disables nmdk_dbg msgs */ +#define NMDK_DEBUG_PFX KEYPAD_NAME /* msg header represents this module */ +#define NMDK_DBG KERN_ERR /* message level */ + +/*key scan constants*/ +#define KSCAN_ALLROWS 0x001F +#define KSCAN_ALLCOLS 0x07E0 +#define KSCAN_ROW0 0x0001 +#define KSCAN_ROW1 0x0002 +#define KSCAN_ROW2 0x0004 +#define KSCAN_ROW3 0x0008 +#define KSCAN_ROW4 0x0010 +#define KSCAN_COL0 0x0020 +#define KSCAN_COL1 0x0040 +#define KSCAN_COL2 0x0080 +#define KSCAN_COL3 0x0100 +#define KSCAN_COL4 0x0200 +#define KSCAN_AUX 0x0400 /* this line needs to set to get keypad intr */ + +unsigned short const keychkval_set[] = { + (unsigned short)~KSCAN_COL0 | KSCAN_ALLROWS, + (unsigned short)~KSCAN_COL1 | KSCAN_ALLROWS, + (unsigned short)~KSCAN_COL2 | KSCAN_ALLROWS, + (unsigned short)~KSCAN_COL3 | KSCAN_ALLROWS, + (unsigned short)~KSCAN_COL4 | KSCAN_ALLROWS +}; + +unsigned short const keychkval_read[] = { + KSCAN_ROW0, KSCAN_ROW1, KSCAN_ROW2, KSCAN_ROW3, KSCAN_ROW4 +}; + +/** + * nomadik_kp_ghostkey_detect - ghost key detect function + * @rowval: row in which ghost key to be detected + * + * when more than one key is pressed in the same row the keypad logic cannot + * detect proper key press, the logic here detects multiple keypress on a + * single row and returns error + */ +int nomadik_kp_ghostkey_detect(short rowval) +{ + int row; + int ghcnt = 0; + + for (row = 0; row < MAX_KPROW; row++) { + if (0 == (rowval & keychkval_read[row])) { + /*keypr detected */ + ghcnt++; + } + /* return error if more than one keys are pressed in a row */ + if (1 < ghcnt) + return (-1); + } + return (0); +} + +/** + * nomadik_kp_key_scan - keypad scan and report event function + * + * Scans through keypad hardware and updates the key status for key press + * or key release event to upper layer + */ +int nomadik_kp_key_scan(struct keypad_t *kp) +{ + short val; + u8 row, col; + int keyp_cnt = 0; + u8 *p_kcode;; + + nmdk_dbg_ftrace(); + for (col = 0; col < MAX_KPCOL; col++) { + p_kcode = kp->board->kcode_tbl + col; + nomadik_epio_write_keypad(keychkval_set[col]); + val = nomadik_epio_read_keypad(); + val &= KSCAN_ALLROWS; + if (0 == nomadik_kp_ghostkey_detect(val)) { + for (row = 0; row < MAX_KPROW; row++) { + if (0 == (val & keychkval_read[row])) { + /*keypr detected */ + keyp_cnt++; + if (kp->key_state[row][col] == + KEYPAD_STATE_DEFAULT) { + input_report_key(kp->inp_dev, + *p_kcode, 1); + nmdk_dbg("P:%d ", *p_kcode); + kp->key_state[row][col] = + KEYPAD_STATE_PRESSACK; + } + } else { + /*key not pressed detected */ + if (kp->key_state[row][col] == + KEYPAD_STATE_PRESSACK) { + input_report_key(kp->inp_dev, + *p_kcode, 0); + nmdk_dbg("R:%d ", *p_kcode); + kp->key_state[row][col] = + KEYPAD_STATE_DEFAULT; + } + } + p_kcode += MAX_KPROW; + } + } else + keyp_cnt += 0x100; /* to flag ghost keypress detection */ + } + /* pull down all rows to detect any keypress */ + nomadik_epio_write_keypad(KSCAN_ALLROWS); + return (keyp_cnt); +} + +/** + * nomadik_kp_init_key_hardware - keypad hardware initialization + * + * Initializes the keypad hardware specific parameters. + * This function will be called by nomadik_keypad_init function during init + * Initialize keypad interrupt handler for interrupt mode operation if enabled + * Initialize Keyscan matrix + **************************************************************************** + */ +int nomadik_kp_init_key_hardware(struct keypad_t *kp) +{ + int err; + gpio_data pin; + + nmdk_dbg_ftrace(); + nomadik_epio_write_keypad(KSCAN_ALLROWS | KSCAN_ALLCOLS); + nomadik_epio_read_keypad(); + if ((KSCAN_ALLROWS | KSCAN_ALLCOLS) != nomadik_epio_read_keypad()) { + /*check wrong key */ + nmdk_error("H/w error...."); + goto kphwiniterr_hwer; + } + if (!kp->mode) { /* true if interrupt mode operation */ + /* Enable keypad interrupt generation logic in CPLD on ndk10 */ + nomadik_epio_write_keypad(KSCAN_AUX | KSCAN_ALLROWS); + nomadik_epio_write_cob_ctl(nomadik_epio_read_cob_ctl() | + GPIO_EN); + nmdk_dbg("keypad interrupt CPLD logic enabled"); + + if (!kp->irq) { + nmdk_error("keypad_irq cannot get in kpinit"); + err = -1; + goto kphwiniterr_pinconfig; + } + set_irq_type(kp->irq, SA_TRIGGER_FALLING); + nomadik_gpio_readpin(GPIO_PIN_FOR_IRQ(kp->irq), &pin); + if (!pin) { + /*check wrong configuration */ + nmdk_error("H/w error...(check sw8 on board)"); + goto kphwiniterr_itpin; + } + } + return 0; + + kphwiniterr_itpin: + kphwiniterr_pinconfig: + kphwiniterr_hwer: + return -1; +} + +/** + * nomadik_kp_exit_key_hardware- keypad hardware exit function + * + * This function will be called by nomadik_keypad_exit function during module + * exit, frees keypad interrupt if enabled + */ +int nomadik_kp_exit_key_hardware(struct keypad_t *kp) +{ + nmdk_dbg_ftrace(); + return 0; +} + +/** + * nomadik_kp_key_irqen- enables keypad interrupt + * + * enables keypad interrupt through CPLD logic + */ +int nomadik_kp_key_irqen(struct keypad_t *kp) +{ + nmdk_dbg_ftrace(); + nomadik_epio_write_keypad(KSCAN_AUX | KSCAN_ALLROWS); + return 0; +} + +/** + * nomadik_kp_key_irqdis- disables keypad interrupt + * + * disables keypad interrupt through CPLD logic + */ +int nomadik_kp_key_irqdis(struct keypad_t *kp) +{ + nmdk_dbg_ftrace(); + nomadik_epio_write_keypad(KSCAN_ALLROWS); + return 0; +} + +/* + * Initializes the key scan table (lookup table) as per pre-defined the scan + * codes to be passed to upper layer with respective key codes + */ +static u8 kpd_lookup_tbl[MAX_KPROW][MAX_KPROW] = { + {KEY_DOWN, KEY_END, KEY_KPASTERISK, KEY_0, KEY_COMMA}, + {KEY_RIGHT, KEY_F5, KEY_7, KEY_8, KEY_9}, + {KEY_ENTER, KEY_LEFT, KEY_4, KEY_5, KEY_6}, + {KEY_RIGHTMETA, KEY_F4, KEY_1, KEY_2, KEY_3}, + {KEY_LEFTMETA, KEY_UP, KEY_F1, KEY_F2, KEY_F3} +}; + +static struct keypad_device keypad_board = { + .init = nomadik_kp_init_key_hardware, + .exit = nomadik_kp_exit_key_hardware, + .scan = nomadik_kp_key_scan, + .irqen = nomadik_kp_key_irqen, + .irqdis = nomadik_kp_key_irqdis, + .kcode_tbl = (u8 *) kpd_lookup_tbl, + .krow = 8, + .kcol = 8, +}; + +static struct resource keypad_resources[] = { + [0] = { + .start = IRQNO_GPIO(KEYPAD_IRQ), + .end = IRQNO_GPIO(KEYPAD_IRQ), + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device keypad_device = { + .name = "nmdk-kp", + .id = 0, + .dev = { + .platform_data = &keypad_board, + }, + .num_resources = ARRAY_SIZE(keypad_resources), + .resource = keypad_resources, +}; + +/* + *********************************************************************** + */ +static struct platform_device *nmdk_platform_devices[] __initdata = { + &smc91x_device, + &keypad_device, + &touchp_device, +#ifdef CONFIG_MTD + &nomadik_nand_flash, + &nomadik_nor_flash, +#endif +}; + +void add_nmdk_platform_devices(void) +{ + platform_add_devices(nmdk_platform_devices, + ARRAY_SIZE(nmdk_platform_devices)); + nomadik_epio_init(); + nomadik_platform_board_init(); + nomadik_fsmc_init(); + nomadik_pepperpot_board_init(); + nomadik_smc91x_irq_init(); +} + + --- /dev/null +++ linux-2.6.20/arch/arm/mach-nomadik/ndk15_devices.c @@ -0,0 +1,1001 @@ +/* + * linux/arch/arm/mach-nomadik/ndk15_devices.c + * + * + * Copyright (C) STMicroelectronics + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2, as + * published by the Free Software Foundation. + * + * NDK15B0x board specifc driver defination + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef CONFIG_MTD +#include +#include +#include +#include +#include +#include +#include +#endif +#include + +#define BOARD_NAME CONFIG_NOMADIK_PLATFORM +#ifndef BOARD_DEBUG +#define BOARD_DEBUG 0 +#endif + +#define NMDK_DEBUG BOARD_DEBUG /* enables/disables nmdk_dbg msgs */ +#define NMDK_DEBUG_PFX BOARD_NAME /* msg header represents this module */ +#define NMDK_DBG KERN_ERR /* message level */ + +/** + * nomadik_clcd_board_enable - enables board specific clcd prameters + * + * Settings to enable backlight and pannel voltage regulator for NDK15 + */ +void nomadik_clcd_enable(void *fbp) +{ + /* not implimented for this board */ +} + +/** + * nomadik_clcd_board_disable - disables board specific clcd prameters + * + * Settings to disable backlight and pannel voltage regulator for NDK10 + */ +void nomadik_clcd_disable(void *fbp) +{ + /* not implimented for this board */ +} + +/* + * Settings to configure MMC controller for NDK10 + */ +int nomadik_mmc_configure(struct amba_device *dev) +{ + int ret; + gpio_config mmc_pin; + char x = val_volt; + + mmc_pin.dev_name = dev->dev.bus_id; + mmc_pin.mode = GPIO_MODE_SOFTWARE; + mmc_pin.direction = GPIO_DIR_OUTPUT; + mmc_pin.trig = GPIO_TRIG_DISABLE; + mmc_pin.debounce = GPIO_DEBOUNCE_DISABLE; + + ret = nomadik_gpio_setpinconfig(GPIO_PIN_75, &mmc_pin); + if (ret) { + nmdk_error("Error in setting GPIO_PIN_75"); + goto mmcconf_exit; + } + /* this enables power path from toureg to mmc */ + ret = nomadik_gpio_writepin(GPIO_PIN_75, GPIO_DATA_HIGH, dev->dev.bus_id); + if (ret) { + nmdk_error("Error in setting GPIO_PIN_75 value to HIGH"); + goto deallocate_pin_75; + } + + ret = nomadik_i2c_write_register(I2C_TOUAREG_CLIENT, &x, 0x11, 1); + if (ret) { + nmdk_error("Error in writing value to touareg register"); + goto deallocate_pin_75; + } + + ret = nomadik_gpio_altfuncenable(GPIO_ALT_SD_CARD, dev->dev.bus_id); + if (ret) { + nmdk_error("Error in gpio Altfunction enable"); + goto deallocate_pin_75; + } + return ret; + + deallocate_pin_75: + nomadik_gpio_resetpinconfig(GPIO_PIN_75, dev->dev.bus_id); + mmcconf_exit: + return ret; + +} + +void nomadik_mmc_restore_default(struct amba_device *dev) +{ + nomadik_gpio_altfuncdisable(GPIO_ALT_SD_CARD, dev->dev.bus_id); + nomadik_gpio_resetpinconfig(GPIO_PIN_75, dev->dev.bus_id); +} + +#ifdef CONFIG_MTD + +static struct resource nandflash_resources[] = { + [0] = { + .name = "cmem_address", + .start = NAND_B0_CMEM_ADDR, + .end = (NAND_B0_CMEM_ADDR + SZ_1K - 1), + .flags = IORESOURCE_MEM, + }, + [1] = { + .name = "cmem_command", + .start = NAND_B0_CMEM_CMD, + .end = (NAND_B0_CMEM_CMD + SZ_1K - 1), + .flags = IORESOURCE_MEM, + }, + [2] = { + .name = "cmem_data", + .start = NAND_B0_CMEM_DATA, + .end = (NAND_B0_CMEM_DATA + SZ_1K - 1), + .flags = IORESOURCE_MEM, + }, +}; + +#define NAND_STM_LP_OPTIONS \ + (NAND_BUSWIDTH_16 | NAND_COPYBACK | NAND_CACHEPRG | NAND_NO_PADDING) + +static int nomadik_nandflash_exit(void) +{ + return 0; + +} +static int nomadik_nandflash_init(void) +{ + /* + * FSMC initialization + * 0x0000001e => PCR0 + * 0x000d0a00 => PMEM0 + * 0x00100a00 => PATT0 + */ + +/* pcr0.address_low = 0;*/ + gpio_config nmdknand_pin_config; + nmdknand_pin_config.mode = GPIO_MODE_SOFTWARE; + nmdknand_pin_config.direction = GPIO_DIR_OUTPUT; + nmdknand_pin_config.trig = GPIO_TRIG_DISABLE; + nmdknand_pin_config.debounce = GPIO_DEBOUNCE_UNCHANGED; + nmdknand_pin_config.dev_name = "nand"; + /*nomadik_gpio_allocatepin(NAND_GPIO, &nand_handle);ppw */ + if(nomadik_gpio_setpinconfig(NAND_GPIO, &nmdknand_pin_config)) + return -1; + if(nomadik_gpio_writepin(NAND_GPIO, 1, nmdknand_pin_config.dev_name)) + return -1; + + + /*Following Settings done for NAND flash protect off */ + /* this was moved from board init to here */ + /* This pin Conflicts with touchpanel TOUCHP_CS0*/ + if(nomadik_gpio_setpinconfig(NAND_FLASH_PROTOFF, &nmdknand_pin_config)) + return -1; + if(nomadik_gpio_writepin(NAND_FLASH_PROTOFF, 1, nmdknand_pin_config.dev_name)) + return -1; + if(nomadik_gpio_resetpinconfig(NAND_FLASH_PROTOFF, nmdknand_pin_config.dev_name )) + return -1; + + + *((volatile unsigned long *)(NOMADIK_FSMC_VA + FSMC_PCR0)) = + DEFAULT_PCR0_VALUE; + *((volatile unsigned long *)(NOMADIK_FSMC_VA + FSMC_PMEM0)) = + DEFAULT_PMEM0_VALUE; + *((volatile unsigned long *)(NOMADIK_FSMC_VA + FSMC_PATT0)) = + DEFAULT_PATT0_VALUE; + return 0; +} + +static const unsigned char lookup_t[256] = { + 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, + 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, + 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, + 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, + 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, + 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, + 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, + 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, + 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, + 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, + 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, + 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, + 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, + 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, + 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, + 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0 +}; + +int nmdknand_compute_ecc512(struct mtd_info *mtd, const u_char * data, + u_char * ecc) +{ + unsigned int sumCol = 0; + unsigned int datum, temp; + unsigned int glob_parity; + const int ecc_n_bytes = 512; + int i; + + unsigned int parit1_1, parit1_2, parit2_1, parit2_2, parit4_1, parit4_2; + unsigned int parit8_1 = 0, parit8_2 = 0, parit16_1 = 0, parit16_2 = + 0, parit32_1 = 0, parit32_2 = 0; + unsigned int parit64_1 = 0, parit64_2 = 0, parit128_1 = 0, parit128_2 = + 0, parit256_1 = 0, parit256_2 = 0; + unsigned int parit512_1 = 0, parit512_2 = 0, parit1024_1 = + 0, parit1024_2 = 0, parit2048_1 = 0, parit2048_2 = 0; + + for (i = ecc_n_bytes - 1; i >= 0; --i) { + datum = data[i]; + sumCol ^= datum; + temp = lookup_t[datum]; + + if (i & 0x01) + parit8_1 ^= temp; + if (i & 0x02) + parit16_1 ^= temp; + if (i & 0x04) + parit32_1 ^= temp; + if (i & 0x08) + parit64_1 ^= temp; + if (i & 0x10) + parit128_1 ^= temp; + if (i & 0x20) + parit256_1 ^= temp; + if (i & 0x40) + parit512_1 ^= temp; + if (i & 0x80) + parit1024_1 ^= temp; + if (i & 0x100) + parit2048_1 ^= temp; + } + + glob_parity = lookup_t[sumCol]; + + parit1_1 = + ((sumCol >> 1) ^ (sumCol >> 3) ^ (sumCol >> 5) ^ (sumCol >> 7)) & 1; + parit1_2 = + ((sumCol >> 0) ^ (sumCol >> 2) ^ (sumCol >> 4) ^ (sumCol >> 6)) & 1; + parit2_1 = + ((sumCol >> 2) ^ (sumCol >> 3) ^ (sumCol >> 6) ^ (sumCol >> 7)) & 1; + parit2_2 = + ((sumCol >> 0) ^ (sumCol >> 1) ^ (sumCol >> 4) ^ (sumCol >> 5)) & 1; + parit4_1 = + ((sumCol >> 4) ^ (sumCol >> 5) ^ (sumCol >> 6) ^ (sumCol >> 7)) & 1; + parit4_2 = + ((sumCol >> 0) ^ (sumCol >> 1) ^ (sumCol >> 2) ^ (sumCol >> 3)) & 1; + + parit8_2 = glob_parity ^ parit8_1; + parit16_2 = glob_parity ^ parit16_1; + parit32_2 = glob_parity ^ parit32_1; + parit64_2 = glob_parity ^ parit64_1; + parit128_2 = glob_parity ^ parit128_1; + parit256_2 = glob_parity ^ parit256_1; + parit512_2 = glob_parity ^ parit512_1; + parit1024_2 = glob_parity ^ parit1024_1; + parit2048_2 = glob_parity ^ parit2048_1; + + /* Pack bits */ + ecc[0] = + ~((parit64_1 << 7) | (parit64_2 << 6) | (parit32_1 << 5) | + (parit32_2 << 4) | (parit16_1 << 3) | (parit16_2 << 2) | (parit8_1 + << 1) | + parit8_2); + ecc[1] = + ~((parit1024_1 << 7) | (parit1024_2 << 6) | (parit512_1 << 5) | + (parit512_2 << 4) | (parit256_1 << 3) | (parit256_2 << 2) | + (parit128_1 << 1) | parit128_2); + ecc[2] = + ~((parit4_1 << 7) | (parit4_2 << 6) | (parit2_1 << 5) | + (parit2_2 << 4) | (parit1_1 << 3) | (parit1_2 << 2) | (parit2048_1 + << 1) | + parit2048_2); + + return 0; +} + +static struct nand_ecclayout nand_oob = { + .eccbytes = 12, + .eccpos = {2, 3, 4, 18, 19, 20, 34, 35, 36, 50, 51, 52}, + .oobavail = MTD_NANDECC_AUTOPLACE, + .oobfree = { + { .offset = 8, + .length = 8, + }, + { .offset = 24, + .length = 8, + }, + { .offset = 40, + .length = 8, + }, + { .offset = 56, + .length = 8, + }, + }, +}; + +static struct mtd_partition nandflash_main_partitions[] = { + + {.name = "X-Loader(NAND)", + .offset = 0, + .size = 2 * 0x000020000}, /*256 Kbytes */ + {.name = "MemInit(NAND)", + .offset = 2 * 0x000020000, + .size = 2 * 0x000020000}, /*128 KBytes */ + {.name = "BootLoader(NAND)", + .offset = 4 * 0x000020000, + .size = 16 * 0x00020000}, /*2Mbytes */ + {.name = "Kernel zImage(NAND)", + .offset = 20 * 0x000020000, + .size = 24 * 0x000020000}, /*3Mbytes */ + {.name = "Root Filesystem(NAND)", + .offset = 44 * 0x000020000, + .size = 176 * 0x000020000}, /*22 Mbytes */ + {.name = "User Filesystem(NAND)", + .offset = 220 * 0x000020000, + .size = 800 * 0x000020000}, /*100 Mbytes */ +}; + +static uint8_t scan_ff_pattern[] = { 0xff, 0xff }; + +static struct nand_bbt_descr bbt_desc = { + .options = 0, + .offs = 0, + .len = 2, + .pattern = scan_ff_pattern +}; + +static void nmdknand_hwcontrol(struct mtd_info *mtd, int cmd, + unsigned int ctrl) +{ + struct nomadik_nand_info *drvdata = + container_of(mtd, struct nomadik_nand_info, mtd); + + if (cmd == NAND_CMD_NONE) + return; + + if (ctrl & NAND_NCE) { + *((volatile unsigned long *)(IO_ADDRESS(NOMADIK_FSMC_BASE) + + 0x40)) |= 0x04; + } + if (ctrl & NAND_CLE) { + writeb(cmd,drvdata->cmemc_va); + } + if (ctrl & NAND_ALE) { + writeb(cmd,drvdata->cmema_va); + } +} + +static struct nomadik_nand_platform_data nomadik_nand_flash_data = { + .parts = nandflash_main_partitions, + .num_parts = ARRAY_SIZE(nandflash_main_partitions), + .lp_options = NAND_STM_LP_OPTIONS, + .eccsize = 512, + .eccsteps = 4, + .badblockpos = 5, + .init = nomadik_nandflash_init, + .exit = nomadik_nandflash_exit, + .nand_oob = &nand_oob, + .bbt_desc = &bbt_desc, + .compute_ecc = nmdknand_compute_ecc512, + .hwcontrol = nmdknand_hwcontrol, +}; + +static struct platform_device nomadik_nand_flash = { + .name = "NOMADIK-NAND", + .id = 0, + .dev = { + .platform_data = &nomadik_nand_flash_data, + }, + .num_resources = ARRAY_SIZE(nandflash_resources), + .resource = nandflash_resources, +}; + +static struct mtd_partition nmdkflash_main_partitions[] = { + {.name = "BootLoader(NOR)", + .size = 0x00040000, /*256K */ + .offset = 0,}, + {.name = "zImage+initrd(NOR)", + .size = 0x001C0000, /*1.75MB */ + .offset = MTDPART_OFS_APPEND,}, + {.name = "Root Filesystem(NOR)", + .size = 0x01200000, /*18MB */ + .offset = MTDPART_OFS_APPEND,}, + {.name = "User Filesystem(NOR)", + .size = 0x00800000, /*8MB */ + .offset = MTDPART_OFS_APPEND,}, + {.name = "initrd(NOR)", + .size = 0x00200000, /*4MB */ + .offset = MTDPART_OFS_APPEND,} +}; + +static struct flash_platform_data nomadik_nor_flash_data = { + .name = "nomadik_nor", + .map_name = "cfi_probe", + /*.width = NMDK_FLASH_BUSWIDTH, */ + .parts = nmdkflash_main_partitions, + .nr_parts = ARRAY_SIZE(nmdkflash_main_partitions), +}; + +static struct resource norflash_resources[] = { + [0] = { + .name = "norflash-regs", + .start = NMDK_FLASH_BASE, + .end = (NMDK_FLASH_BASE + SZ_32M - 1), + .flags = IORESOURCE_MEM, + }, +}; + +static struct platform_device nomadik_nor_flash = { + .name = "NOMADIK-NOR", + .id = 0, + .dev = { + .platform_data = &nomadik_nor_flash_data, + }, + .num_resources = ARRAY_SIZE(norflash_resources), + .resource = norflash_resources, +}; + +#endif + +static struct resource smc91x_resources[] = { + [0] = { + .name = "smc91x-regs", + .start = (NOMADIK_ETH0_BASE + 0x300), + .end = (NOMADIK_ETH0_BASE + SZ_64M - 1), + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQNO_GPIO(SMC91111_IRQ), + .end = IRQNO_GPIO(SMC91111_IRQ), + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device smc91x_device = { + .name = "smc91x", + .id = 0, + .num_resources = ARRAY_SIZE(smc91x_resources), + .resource = smc91x_resources, +}; + +/* + * touchpanel + */ +#ifndef TOUCHP_DEBUG +#define TOUCHP_DEBUG 0 /* default debug messages are disabled */ +#endif /* */ + +#undef NMDK_DEBUG +#undef NMDK_DEBUG_PFX +#undef NMDK_DBG +#define NMDK_DEBUG TOUCHP_DEBUG /* enables/disables debug msgs */ +#define NMDK_DEBUG_PFX TPDRVNAME /* msg header represents this module */ +#define NMDK_DBG KERN_ERR /* message level */ + +/** + * nomadik_tp_ssp_board_init - board specific ssp data path setup + * @p_adsContext: device data structure pointer + * + * This routine initializes the SSP for touchpanel operation + * Selects the SSP source for the EXP_SSP and SPI3V interfaces + */ +int nomadik_tp_ssp_board_init(struct t_adsContext *p_adsContext) +{ + nmdk_dbg_ftrace(); + nomadik_epio_write_ssp_conf(EXP_SSP); + return (0); +} + +/** + * nomadik_tp_gpio_board_init - board specific gpio initialization + * @p_adsContext: device data structure pointer + * + * This routine initializes the GPIO for touchpanel operation + * RETURN: GPIO nmdk_error code + * SSP is interfaced with ADS7843 through CPLD hence respective + * interface need to be enabled for NDK10 + * BIOS/TCHSCR: BIOS EEPROM and Touch Screen have the same SPI + * chip select, this bit allows the selection between the two + * peripherals. setting this bit Touch screen selected + */ +gpio_error nomadik_tp_gpio_board_init(struct t_adsContext * p_adsContext) +{ + gpio_error status = GPIO_OK; + gpio_config config_cspin; + gpio_data touchp_cs1; + nmdk_dbg_ftrace(); + + nomadik_epio_write_cob_ctl(nomadik_epio_read_cob_ctl() | BIOS_TCHSCR); + + /* Set SPICSn_TCHSCR pin configuration */ + config_cspin.mode = GPIO_MODE_SOFTWARE; + config_cspin.direction = GPIO_DIR_OUTPUT; + config_cspin.debounce = GPIO_DEBOUNCE_DISABLE; + config_cspin.dev_name = "Touchp"; + /* + * TOUCHP_CS1 need to be high always to select ad7843 cs properly + * this pin will be set high by nand_init(NAND_PROT_OFF) + * if this pin is not high and set it high + */ + status |= nomadik_gpio_readpin(TOUCHP_CS1, &touchp_cs1); + if (!touchp_cs1) { + status |= nomadik_gpio_setpinconfig(TOUCHP_CS1, &config_cspin); + status |= nomadik_gpio_writepin(TOUCHP_CS1, 1, config_cspin.dev_name); + status |= nomadik_gpio_resetpinconfig(TOUCHP_CS1, config_cspin.dev_name); + } + status |= nomadik_gpio_setpinconfig(TOUCHP_CS0, &config_cspin); + if (status) { + nmdk_error("GPIO %d configuration failure (nmdk_error:%d)", + TOUCHP_CS0, status); + return (status); + } + /* Set PENIRQ pin configuration */ + set_irq_type(p_adsContext->irq, SA_TRIGGER_RISING); + return status; +} + +/** + * nomadik_tp_gpio_board_exit - board specific gpio exit + * @p_adsContext: device data structure pointer + * + * This routine performs revers action of init + */ +gpio_error nomadik_tp_gpio_board_exit(struct t_adsContext * p_adsContext) +{ + gpio_error status = GPIO_OK; + + nmdk_dbg_ftrace(); + /* Enable CPLD logic for access/interrupts on ndk15 in case of int mode */ + if (!p_adsContext->mode) { + nomadik_epio_write_it_mngt(nomadik_epio_read_it_mngt() & + (u16)~TSIT_MSK); + } + status |= nomadik_gpio_resetpinconfig(TOUCHP_CS0, "Touchp"); + nomadik_epio_write_cob_ctl(nomadik_epio_read_cob_ctl() & (u16)~BIOS_TCHSCR); + return status; +} + +/** + * nomadik_tp_pen_down - returns pen touch status + */ +t_bool nomadik_tp_pen_down(struct t_adsContext * p_adsContext) +{ + gpio_data pen_down; + nmdk_dbg_ftrace(); + pen_down = nomadik_epio_read_aux_gpi1(); + pen_down &= TCHSCR_PENIRQ; + nmdk_dbg2("pen_down = 0x%d", pen_down); + return ((t_bool) pen_down); +} + +/** + * nomadik_tp_pen_down_irq_enable - enables pen interrupt + */ +void nomadik_tp_pen_down_irq_enable(struct t_adsContext *p_adsContext) +{ + nmdk_dbg_ftrace(); + nomadik_epio_write_it_mngt(nomadik_epio_read_it_mngt() | TSIT_MSK); +} + +/** + * nomadik_tp_pen_down_irq_disable - disables pen interrupt + */ +void nomadik_tp_pen_down_irq_disable(struct t_adsContext *p_adsContext) +{ + nmdk_dbg_ftrace(); + nomadik_epio_write_it_mngt(nomadik_epio_read_it_mngt() & + (unsigned short)(~TSIT_MSK)); +} + +/** + * nomadik_tp_spi_cs_disable - disables the chip select for ads7843 + * + * sets GPIOS to to provid inputs to CPLD to disable chip select + */ +void nomadik_tp_spi_cs_disable(void) +{ + nmdk_dbg_ftrace(); + nomadik_gpio_writepin(TOUCHP_CS0, 1, "Touchp"); +} + +/** + * nomadik_tp_spi_cs_enaable - enables the chip select for ads7843 + * + * sets GPIOS to to provid inputs to CPLD to enable chip select + */ +void nomadik_tp_spi_cs_enable(void) +{ + nmdk_dbg_ftrace(); + nomadik_gpio_writepin(TOUCHP_CS0, 0, "Touchp"); +} + +static struct touchp_device touchp_board = { + .ssp_init = nomadik_tp_ssp_board_init, + .gpio_init = nomadik_tp_gpio_board_init, + .gpio_exit = nomadik_tp_gpio_board_exit, + .pdown = nomadik_tp_pen_down, + .pirq_en = nomadik_tp_pen_down_irq_enable, + .pirq_dis = nomadik_tp_pen_down_irq_disable, + .cs_en = nomadik_tp_spi_cs_disable, + .cs_dis = nomadik_tp_spi_cs_enable, + .samples = 20, /*samples per second*/ + .pollsamples = 10, /*polling per second*/ +}; + +static struct resource touchp_resources[] = { + [0] = { + .start = IRQNO_GPIO(TOUCHP_IRQ), + .end = IRQNO_GPIO(TOUCHP_IRQ), + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device touchp_device = { + .name = "nmdk-tp", + .id = 0, + .dev = { + .platform_data = &touchp_board, + }, + .num_resources = ARRAY_SIZE(touchp_resources), + .resource = touchp_resources, +}; + +#define KEYPAD_NAME "KEYPAD" +#ifndef KEYPAD_DEBUG +#define KEYPAD_DEBUG 0 +#endif + +#undef NMDK_DEBUG +#undef NMDK_DEBUG_PFX +#undef NMDK_DBG +#define NMDK_DEBUG KEYPAD_DEBUG /* enables/disables nmdk_dbg msgs */ +#define NMDK_DEBUG_PFX KEYPAD_NAME /* msg header represents this module */ +#define NMDK_DBG KERN_ERR /* message level */ + +/*key scan constants*/ +#define KSCAN_ALLROWS 0x00FF +#define KSCAN_ALLCOLS 0xFF00 +#define KSCAN_ROW0 0x0001 +#define KSCAN_ROW1 0x0002 +#define KSCAN_ROW2 0x0004 +#define KSCAN_ROW3 0x0008 +#define KSCAN_ROW4 0x0010 +#define KSCAN_ROW5 0x0020 +#define KSCAN_ROW6 0x0040 +#define KSCAN_ROW7 0x0080 +#define KSCAN_COL0 0x0100 +#define KSCAN_COL1 0x0200 +#define KSCAN_COL2 0x0400 +#define KSCAN_COL3 0x0800 +#define KSCAN_COL4 0x1000 +#define KSCAN_COL5 0x2000 +#define KSCAN_COL6 0x4000 +#define KSCAN_COL7 0x8000 + +unsigned short const keychkval_set[] = { + (unsigned short)~KSCAN_COL0 | KSCAN_ALLROWS, + (unsigned short)~KSCAN_COL1 | KSCAN_ALLROWS, + (unsigned short)~KSCAN_COL2 | KSCAN_ALLROWS, + (unsigned short)~KSCAN_COL3 | KSCAN_ALLROWS, + (unsigned short)~KSCAN_COL4 | KSCAN_ALLROWS, + (unsigned short)~KSCAN_COL5 | KSCAN_ALLROWS, + (unsigned short)~KSCAN_COL6 | KSCAN_ALLROWS, + (unsigned short)~KSCAN_COL7 | KSCAN_ALLROWS, +}; + +unsigned short const keychkval_read[] = { + KSCAN_ROW0, KSCAN_ROW1, KSCAN_ROW2, KSCAN_ROW3, KSCAN_ROW4, KSCAN_ROW5, + KSCAN_ROW6, KSCAN_ROW7, +}; + +/** + * nomadik_kp_ghostkey_detect - ghost key detect function + * @rowval: row in which ghost key to be detected + * + * when more than one key is pressed in the same row the keypad logic cannot + * detect proper key press, the logic here detects multiple keypress on a + * single row and returns error + */ +int nomadik_kp_ghostkey_detect(short rowval) +{ + int row; + int ghcnt = 0; + + for (row = 0; row < MAX_KPROW; row++) { + if (0 == (rowval & keychkval_read[row])) { + /*keypr detected */ + ghcnt++; + } + if (1 < ghcnt) + /*return error if more than one keys are pressed in a row */ + return (-1); + } + return (0); +} + +/** + * nomadik_kp_key_scan - keypad scan and report event function + * + * Scans through keypad hardware and updates the key status for key press + * or key release event to upper layer + */ +int nomadik_kp_key_scan(struct keypad_t *kp) +{ + short val; + u8 row, col; + int keyp_cnt = 0; + u8 *p_kcode; + + nmdk_dbg_ftrace(); + for (col = 0; col < MAX_KPCOL; col++) { + p_kcode = kp->board->kcode_tbl + col; + nomadik_epio_write_keypad(keychkval_set[col]); + val = nomadik_epio_read_keypad(); + val &= KSCAN_ALLROWS; + if (0 == nomadik_kp_ghostkey_detect(val)) { + for (row = 0; row < MAX_KPROW; row++) { + if (0 == (val & keychkval_read[row])) { /*keypr detected */ + keyp_cnt++; + if (kp->key_state[row][col] == + KEYPAD_STATE_DEFAULT) { + input_report_key(kp->inp_dev, + *p_kcode, 1); + nmdk_dbg("P:%d ", *p_kcode); + kp->key_state[row][col] = + KEYPAD_STATE_PRESSACK; + } + } else { /*key not pressed detected */ + if (kp->key_state[row][col] == + KEYPAD_STATE_PRESSACK) { + input_report_key(kp->inp_dev, + *p_kcode, 0); + nmdk_dbg("R:%d ", *p_kcode); + kp->key_state[row][col] = + KEYPAD_STATE_DEFAULT; + } + } + p_kcode += MAX_KPROW; + } + } else + keyp_cnt += 0x100; /* to flag ghost keypress detection */ + } + /* pull down all rows to detect any keypress */ + nomadik_epio_write_keypad(KSCAN_ALLCOLS & KSCAN_ALLROWS); + return (keyp_cnt); +} + +/** + * nomadik_kp_init_key_hardware - keypad hardware initialization + * + * Initializes the keypad hardware specific parameters. + * This function will be called by nomadik_keypad_init function during init + * Initialize keypad interrupt handler for interrupt mode operation if enabled + * Initialize Keyscan matrix + **************************************************************************** + */ +int nomadik_kp_init_key_hardware(struct keypad_t *kp) +{ + nmdk_dbg_ftrace(); + nomadik_epio_write_keypad(KSCAN_ALLCOLS); + if ((KSCAN_ALLCOLS | KSCAN_ALLROWS) != (u16) nomadik_epio_read_keypad()) { + /*check wrong key */ + nmdk_error("Keypad H/w error...."); + return (-1); + } + if (!kp->mode) { /* true if interrupt mode operation */ + /* pull down all rows to detect any keypress */ + nomadik_epio_write_keypad(0x00); + /* enable keypad interrupt through CPLD logic */ + nomadik_epio_write_it_mngt(nomadik_epio_read_it_mngt() | + KEYP_MSK); + set_irq_type(kp->irq, SA_TRIGGER_RISING); + /* + * TBD logic should be added to detect proper switch settings + * on a board to detect valid interrupt + */ + } + return 0; +} + +/** + * nomadik_kp_exit_key_hardware- keypad hardware exit function + * + * This function will be called by nomadik_keypad_exit function during module + * exit, frees keypad interrupt if enabled + */ +int nomadik_kp_exit_key_hardware(struct keypad_t *kp) +{ + nmdk_dbg_ftrace(); + return 0; +} + +/** + * nomadik_kp_key_irqen- enables keypad interrupt + * + * enables keypad interrupt through CPLD logic + */ +int nomadik_kp_key_irqen(struct keypad_t *kp) +{ + nomadik_epio_write_it_mngt(nomadik_epio_read_it_mngt() | KEYP_MSK); + return 0; +} + +/** + * nomadik_kp_key_irqdis- disables keypad interrupt + * + * disables keypad interrupt through CPLD logic + */ +int nomadik_kp_key_irqdis(struct keypad_t *kp) +{ + nomadik_epio_write_it_mngt(nomadik_epio_read_it_mngt() & + (unsigned short)(~KEYP_MSK)); + return 0; +} + +/* + * Initializes the key scan table (lookup table) as per pre-defined the scan + * codes to be passed to upper layer with respective key codes + */ +u8 const kpd_lookup_tbl[MAX_KPROW][MAX_KPROW] = { + {KEY_ESC, KEY_F1, KEY_F2, KEY_F3, KEY_F4, KEY_F5, KEY_F6, KEY_SPACE}, + {KEY_GRAVE, KEY_1, KEY_2, KEY_3, KEY_4, KEY_5, KEY_6, KEY_7}, + {KEY_8, KEY_9, KEY_0, KEY_MINUS, KEY_EQUAL, KEY_BACKSPACE, KEY_INSERT, + KEY_HOME}, + {KEY_TAB, KEY_Q, KEY_W, KEY_E, KEY_R, KEY_T, KEY_Y, KEY_U}, + {KEY_I, KEY_O, KEY_P, KEY_LEFTBRACE, KEY_RIGHTBRACE, KEY_BACKSLASH, + KEY_DELETE, KEY_END}, + {KEY_CAPSLOCK, KEY_A, KEY_S, KEY_D, KEY_F, KEY_G, KEY_H, KEY_J}, + {KEY_K, KEY_L, KEY_SEMICOLON, KEY_APOSTROPHE, KEY_ENTER, KEY_DOT, + KEY_COMMA, KEY_SLASH}, + {KEY_LEFTSHIFT, KEY_Z, KEY_X, KEY_C, KEY_V, KEY_B, KEY_N, KEY_M} +}; + +static struct keypad_device keypad_board = { + .init = nomadik_kp_init_key_hardware, + .exit = nomadik_kp_exit_key_hardware, + .scan = nomadik_kp_key_scan, + .irqen = nomadik_kp_key_irqen, + .irqdis = nomadik_kp_key_irqdis, + .kcode_tbl = (u8 *) kpd_lookup_tbl, + .krow = 8, + .kcol = 8, +}; + +static struct resource keypad_resources[] = { + [0] = { + .start = IRQNO_GPIO(KEYPAD_IRQ), + .end = IRQNO_GPIO(KEYPAD_IRQ), + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device keypad_device = { + .name = "nmdk-kp", + .id = 0, + .dev = { + .platform_data = &keypad_board, + }, + .num_resources = ARRAY_SIZE(keypad_resources), + .resource = keypad_resources, +}; + +static struct resource fsmc_resources[] = { + [0] = { + .start = NOMADIK_FSMC_BASE, + .end = NOMADIK_FSMC_BASE + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, +}; + +static int fsmc_platform_init(void) +{ + unsigned char __iomem *fsmc_base; + + nmdk_dbg_ftrace(); + /*Following Settings done for NAND flash protect off */ + fsmc_base = (unsigned char *)IO_ADDRESS(NOMADIK_FSMC_BASE); + + /* for NOR accesss */ + /* Initialize the fsmc bank 0 */ + *((volatile u32 *)(NOMADIK_FSMC_VA + FSMC_BCR0)) = 0x10db; + *((volatile u32 *)(NOMADIK_FSMC_VA + FSMC_BTR0)) = 0x03333333; + /* Initialize the fsmc bank 1 used for ethernet controller */ + *((volatile u32 *)(NOMADIK_FSMC_VA + FSMC_BCR1)) = 0x10db; + *((volatile u32 *)(NOMADIK_FSMC_VA + FSMC_BTR1)) = 0x00000702; /*old 00000702 */ + + *((volatile u32 *)(NOMADIK_FSMC_VA + FSMC_BCR0)) |= 0x80; + /* Above Settings done for NAND flash protect off */ + return 0; +} + +struct fsmc_platform_data fsmc_data = { + .init = fsmc_platform_init, +}; + +static struct platform_device fsmc_device = { + .name = "NOMADIK-FSMC", + .id = 0, + .dev = { + .platform_data = &fsmc_data, + }, + .num_resources = ARRAY_SIZE(fsmc_resources), + .resource = fsmc_resources, +}; + +#ifdef CONFIG_CPLD_I2C +static void nomadik_smc91x_irq_init(void) +{ + nmdk_dbg_ftrace(); + /* Reset ethernet controller */ + nomadik_epio_write_aux_gpo1(nomadik_epio_read_aux_gpo1() & + (unsigned long)(~LAN_RST)); + /* Enabling ethernet interrupts */ + nomadik_epio_write_it_mngt(nomadik_epio_read_it_mngt() | LAN_MSK); + /*type need to be set in case of shared irq */ + set_irq_type(IRQNO_GPIO(SMC91111_IRQ), SA_TRIGGER_RISING); +} + +static void nomadik_epio_plat_init(void) +{ + nmdk_dbg_ftrace(); + /* Initializing CPLD registers for initial values */ + nomadik_epio_write_cob_ctl(0x0001); /* reset value led on */ + nomadik_epio_write_keypad(0xff00); /* COL7:0 set to high Z */ + //nomadik_epio_write_msp_conf(0x0000); /* reset value */ + nomadik_epio_write_msp_conf(CDC_MSP0); /* reset value */ + nomadik_epio_write_uart_conf(DBG_UART1);/* UART1 enabled for rs232 port*/ + nomadik_epio_write_ssp_conf(0x0000); /* reset value */ + nomadik_epio_write_aux_gpo1(0x6888); /* reset value */ + nomadik_epio_write_aux_gpi1(0x0000); /* reset value */ + nomadik_epio_write_it_mngt(0x0000); /* all interrupts masked */ + + nomadik_smc91x_irq_init(); +} + +static struct platform_device epio_device = { + .name = "NOMADIK-EPIO", + .id = 0, + .dev = { + .platform_data = nomadik_epio_plat_init, + }, +}; +#endif + +static struct platform_device *nmdk_platform_devices[] __initdata = { + &fsmc_device, +#ifdef CONFIG_CPLD_I2C + &epio_device, +#endif + &keypad_device, + &smc91x_device, + &touchp_device, +#ifdef CONFIG_MTD + &nomadik_nand_flash, + &nomadik_nor_flash, +#endif +}; + +void add_nmdk_platform_devices(void) +{ + platform_add_devices(nmdk_platform_devices, + ARRAY_SIZE(nmdk_platform_devices)); + device_init_wakeup(&keypad_device.dev, 1); + device_init_wakeup(&touchp_device.dev, 1); +} --- /dev/null +++ linux-2.6.20/arch/arm/mach-nomadik/ndk15_rev2_b_03_Kconfig @@ -0,0 +1,37 @@ +if NOMADIK_NDK15_REV2_B_03 + +comment "Nomadik chip used STn8815S22 cut A0 (marked STN8815AAS22)" +comment "Target board CPLD version 2.0.1.0" + +#target name configuration for this target +config NOMADIK_TARGET + string + default NDK15_Rev2_B_03 + +# nomadik cpld identification name for this target +config NOMADIK_CPLD_V2010 + bool + default y + +# nomadik soc chip name configuration for this targe +config NOMADIK_SOC + string + default stn8815 + +# nomadik platform name configuration for this targe +config NOMADIK_PLATFORM + string + default ndk15 + +# EXTRA_CFLAGS configuration for this target +config NOMADIK_TARGET_EXTRA_CFLAGS + string + default "-D__RELEASE -D__STN_8815=10" + + +# Basic platform type configuration for this targe +config NOMADIK_NDK15 + bool + default y + +endif --- /dev/null +++ linux-2.6.20/arch/arm/mach-nomadik/ndk15_rev2_b_05_Kconfig @@ -0,0 +1,37 @@ +if NOMADIK_NDK15_REV2_B_05 + +comment "Nomadik chip used STn8815S22 cut A0 (marked STN8815AAS22H11 Secure)" +comment "Target board CPLD version 2.0.1.0" + +#target name configuration for this target +config NOMADIK_TARGET + string + default NDK15_Rev2_B_05 + +# nomadik cpld identification name for this target +config NOMADIK_CPLD_V2010 + bool + default y + +# nomadik soc chip name configuration for this targe +config NOMADIK_SOC + string + default stn8815 + +# nomadik platform name configuration for this targe +config NOMADIK_PLATFORM + string + default ndk15 + +# EXTRA_CFLAGS configuration for this target +config NOMADIK_TARGET_EXTRA_CFLAGS + string + default "-D__RELEASE -D__STN_8815=10" + + +# Basic platform type configuration for this targe +config NOMADIK_NDK15 + bool + default y + +endif --- /dev/null +++ linux-2.6.20/arch/arm/mach-nomadik/ndk15_rev2_b_06_Kconfig @@ -0,0 +1,42 @@ +if NOMADIK_NDK15_REV2_B_06 + +comment "Nomadik chip used STn8815S22 cut B0 (marked STN8815BBS22H11 Secure)" +comment "Target board CPLD version 2.0.1.0" + +#target name configuration for this target +config NOMADIK_TARGET + string + default NDK15_Rev2_B_06 + +# nomadik cpld identification name for this target +config NOMADIK_CPLD_V2010 + bool + default y + +# nomadik soc chip name configuration for this targe +config NOMADIK_SOC + string + default stn8815 + +# nomadik soc chip cut name configuration for this targe only +config NOMADIK_STN8815BBS22H11 + bool + default y + +# nomadik platform name configuration for this targe +config NOMADIK_PLATFORM + string + default ndk15 + +# EXTRA_CFLAGS configuration for this target +config NOMADIK_TARGET_EXTRA_CFLAGS + string + default "-D__RELEASE -D__STN_8815=20 " + + +# Basic platform type configuration for this targe +config NOMADIK_NDK15 + bool + default y + +endif --- /dev/null +++ linux-2.6.20/arch/arm/mach-nomadik/ndk15_rev3_c_02_Kconfig @@ -0,0 +1,42 @@ +if NOMADIK_NDK15_REV3_C_02 + +comment "Nomadik chip used STn8815 cutC0 (marked STN8815CAS22H11 Secure)" +comment "Target board CPLD version 3.0.1.2" + +#target name configuration for this target +config NOMADIK_TARGET + string + default NDK15_Rev3_C_02 + +# nomadik cpld identification name for this target +config NOMADIK_CPLD_V3012 + bool + default y + +# nomadik soc chip name configuration for this target +config NOMADIK_SOC + string + default stn8815 + +# nomadik soc chip cut name configuration for this targe only +config NOMADIK_STN8815CAS22H11 + bool + default y + +# nomadik platform name configuration for this targe +config NOMADIK_PLATFORM + string + default ndk15c02 + +# EXTRA_CFLAGS configuration for this target +config NOMADIK_TARGET_EXTRA_CFLAGS + string + default "-D__RELEASE -D__STN_8815=30 " + + +# Basic platform type configuration for this targe +config NOMADIK_NDK15 + bool + default y + +endif --- /dev/null +++ linux-2.6.20/arch/arm/mach-nomadik/ndk15c02_devices.c @@ -0,0 +1,1023 @@ +/* + * linux/arch/arm/mach-nomadik/ndk15c02_devices.c + * + * Copyright (C) STMicroelectronics + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2, as + * published by the Free Software Foundation. + * + * NDK15C02 board specifc driver defination + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef CONFIG_MTD +#include +#include +#include +#include +#include +#include +#include +#endif +#include + +#define BOARD_NAME CONFIG_NOMADIK_PLATFORM +#ifndef BOARD_DEBUG +#define BOARD_DEBUG 0 +#endif + +#define NMDK_DEBUG BOARD_DEBUG /* enables/disables nmdk_dbg msgs */ +#define NMDK_DEBUG_PFX BOARD_NAME /* msg header represents this module */ +#define NMDK_DBG KERN_ERR /* message level */ + +/** + * nomadik_clcd_board_enable - enables board specific clcd prameters + * + * Settings to enable backlight and pannel voltage regulator for NDK15 + */ +void nomadik_clcd_enable(void *fbp) +{ + /* not implimented for this board */ +} + +/** + * nomadik_clcd_board_disable - disables board specific clcd prameters + * + * Settings to disable backlight and pannel voltage regulator for NDK10 + */ +void nomadik_clcd_disable(void *fbp) +{ + /* not implimented for this board */ +} + +//#ifdef CONFIG_MMC_NOMADIK +/* + * Settings to configure MMC controller for NDK10 + */ +int nomadik_mmc_configure(struct amba_device *dev) +{ + int ret; + gpio_config mmc_pin; + char x = val_volt; + + mmc_pin.dev_name = dev->dev.bus_id; + mmc_pin.mode = GPIO_MODE_SOFTWARE; + mmc_pin.direction = GPIO_DIR_OUTPUT; + mmc_pin.trig = GPIO_TRIG_DISABLE; + mmc_pin.debounce = GPIO_DEBOUNCE_DISABLE; + + ret = nomadik_gpio_setpinconfig(GPIO_PIN_75, &mmc_pin); + if (ret) { + nmdk_error("Error in setting GPIO_PIN_75"); + goto mmcconf_exit; + } + /* this enables power path from toureg to mmc */ + ret = nomadik_gpio_writepin(GPIO_PIN_75, GPIO_DATA_HIGH, dev->dev.bus_id); + if (ret) { + nmdk_error("Error in setting GPIO_PIN_75 value to HIGH"); + goto deallocate_pin_75; + } + + ret = nomadik_i2c_write_register(I2C_TOUAREG_CLIENT, &x, 0x11, 1); + if (ret) { + nmdk_error("Error in writing value to touareg register"); + goto deallocate_pin_75; + } + + ret = nomadik_gpio_altfuncenable(GPIO_ALT_SD_CARD, dev->dev.bus_id); + if (ret) { + nmdk_error("Error in gpio Altfunction enable"); + goto deallocate_pin_75; + } + return ret; + + deallocate_pin_75: + nomadik_gpio_resetpinconfig(GPIO_PIN_75, dev->dev.bus_id); + mmcconf_exit: + return ret; + +} + +void nomadik_mmc_restore_default(struct amba_device *dev) +{ + nomadik_gpio_altfuncdisable(GPIO_ALT_SD_CARD, dev->dev.bus_id); + nomadik_gpio_resetpinconfig(GPIO_PIN_75, dev->dev.bus_id); +} +//#endif + +static int fsmc_platform_init(void) +{ + unsigned char __iomem *fsmc_base; + + nmdk_dbg_ftrace(); + /*Following Settings done for NAND flash protect off */ + fsmc_base = (unsigned char *)IO_ADDRESS(NOMADIK_FSMC_BASE); + + /* for NOR accesss */ + /* Initialize the fsmc bank 0 */ + *((volatile u32 *)(NOMADIK_FSMC_VA + FSMC_BCR0)) = 0x10db; + *((volatile u32 *)(NOMADIK_FSMC_VA + FSMC_BTR0)) = 0x03333333; + /* Initialize the fsmc bank 1 used for ethernet controller */ + *((volatile u32 *)(NOMADIK_FSMC_VA + FSMC_BCR1)) = 0x10db; + *((volatile u32 *)(NOMADIK_FSMC_VA + FSMC_BTR1)) = 0x00000702; /*old 00000702 */ + + *((volatile u32 *)(NOMADIK_FSMC_VA + FSMC_BCR0)) |= 0x80; + /* Above Settings done for NAND flash protect off */ + return 0; +} + +static struct resource fsmc_resources[] = { + [0] = { + .start = NOMADIK_FSMC_BASE, + .end = NOMADIK_FSMC_BASE + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, +}; + +struct fsmc_platform_data fsmc_data = { + .init = fsmc_platform_init, +}; + +static struct platform_device fsmc_device = { + .name = "NOMADIK-FSMC", + .id = 0, + .dev = { + .platform_data = &fsmc_data, + }, + .num_resources = ARRAY_SIZE(fsmc_resources), + .resource = fsmc_resources, +}; + +#ifdef CONFIG_MTD +static struct resource nandflash_resources[] = { + [0] = { + .name = "cmem_address", + .start = NAND_B0_CMEM_ADDR, + .end = (NAND_B0_CMEM_ADDR + SZ_1K - 1), + .flags = IORESOURCE_MEM, + }, + [1] = { + .name = "cmem_command", + .start = NAND_B0_CMEM_CMD, + .end = (NAND_B0_CMEM_CMD + SZ_1K - 1), + .flags = IORESOURCE_MEM, + }, + [2] = { + .name = "cmem_data", + .start = NAND_B0_CMEM_DATA, + .end = (NAND_B0_CMEM_DATA + SZ_1K - 1), + .flags = IORESOURCE_MEM, + }, +}; + +#define NAND_STM_LP_OPTIONS \ + (NAND_BUSWIDTH_16 | NAND_COPYBACK | NAND_CACHEPRG | NAND_NO_PADDING) + +int nomadik_nandflash_exit(void) +{ + return 0; + +} +int nomadik_nandflash_init(void) +{ + /* + * FSMC initialization + * 0x0000001e => PCR0 + * 0x000d0a00 => PMEM0 + * 0x00100a00 => PATT0 + */ + +/* pcr0.address_low = 0;*/ + gpio_config nmdknand_pin_config; + nmdknand_pin_config.mode = GPIO_MODE_SOFTWARE; + nmdknand_pin_config.direction = GPIO_DIR_OUTPUT; + nmdknand_pin_config.trig = GPIO_TRIG_DISABLE; + nmdknand_pin_config.debounce = GPIO_DEBOUNCE_UNCHANGED; + nmdknand_pin_config.dev_name = "nand"; + /*nomadik_gpio_allocatepin(NAND_GPIO, &nand_handle);ppw */ + nomadik_gpio_setpinconfig(NAND_GPIO, &nmdknand_pin_config); + nomadik_gpio_writepin(NAND_GPIO, 1, nmdknand_pin_config.dev_name); + /*Following Settings done for NAND flash protect off */ + nomadik_gpio_setpinconfig(NAND_FLASH_PROTOFF, &nmdknand_pin_config); + nomadik_gpio_writepin(NAND_FLASH_PROTOFF, 1, nmdknand_pin_config.dev_name); + nomadik_gpio_resetpinconfig(NAND_FLASH_PROTOFF, nmdknand_pin_config.dev_name); + + *((volatile unsigned long *)(NOMADIK_FSMC_VA + FSMC_PCR0)) = + DEFAULT_PCR0_VALUE; + *((volatile unsigned long *)(NOMADIK_FSMC_VA + FSMC_PMEM0)) = + DEFAULT_PMEM0_VALUE; + *((volatile unsigned long *)(NOMADIK_FSMC_VA + FSMC_PATT0)) = + DEFAULT_PATT0_VALUE; + return 0; +} + +const unsigned char lookup_t[256] = { + 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, + 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, + 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, + 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, + 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, + 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, + 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, + 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, + 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, + 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, + 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, + 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, + 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, + 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, + 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, + 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0 +}; + +int nmdknand_compute_ecc512(struct mtd_info *mtd, const u_char * data, + u_char * ecc) +{ + unsigned int sumCol = 0; + unsigned int datum, temp; + unsigned int glob_parity; + const int ecc_n_bytes = 512; + int i; + + unsigned int parit1_1, parit1_2, parit2_1, parit2_2, parit4_1, parit4_2; + unsigned int parit8_1 = 0, parit8_2 = 0, parit16_1 = 0, parit16_2 = + 0, parit32_1 = 0, parit32_2 = 0; + unsigned int parit64_1 = 0, parit64_2 = 0, parit128_1 = 0, parit128_2 = + 0, parit256_1 = 0, parit256_2 = 0; + unsigned int parit512_1 = 0, parit512_2 = 0, parit1024_1 = + 0, parit1024_2 = 0, parit2048_1 = 0, parit2048_2 = 0; + + for (i = ecc_n_bytes - 1; i >= 0; --i) { + datum = data[i]; + sumCol ^= datum; + temp = lookup_t[datum]; + + if (i & 0x01) + parit8_1 ^= temp; + if (i & 0x02) + parit16_1 ^= temp; + if (i & 0x04) + parit32_1 ^= temp; + if (i & 0x08) + parit64_1 ^= temp; + if (i & 0x10) + parit128_1 ^= temp; + if (i & 0x20) + parit256_1 ^= temp; + if (i & 0x40) + parit512_1 ^= temp; + if (i & 0x80) + parit1024_1 ^= temp; + if (i & 0x100) + parit2048_1 ^= temp; + } + + glob_parity = lookup_t[sumCol]; + + parit1_1 = + ((sumCol >> 1) ^ (sumCol >> 3) ^ (sumCol >> 5) ^ (sumCol >> 7)) & 1; + parit1_2 = + ((sumCol >> 0) ^ (sumCol >> 2) ^ (sumCol >> 4) ^ (sumCol >> 6)) & 1; + parit2_1 = + ((sumCol >> 2) ^ (sumCol >> 3) ^ (sumCol >> 6) ^ (sumCol >> 7)) & 1; + parit2_2 = + ((sumCol >> 0) ^ (sumCol >> 1) ^ (sumCol >> 4) ^ (sumCol >> 5)) & 1; + parit4_1 = + ((sumCol >> 4) ^ (sumCol >> 5) ^ (sumCol >> 6) ^ (sumCol >> 7)) & 1; + parit4_2 = + ((sumCol >> 0) ^ (sumCol >> 1) ^ (sumCol >> 2) ^ (sumCol >> 3)) & 1; + + parit8_2 = glob_parity ^ parit8_1; + parit16_2 = glob_parity ^ parit16_1; + parit32_2 = glob_parity ^ parit32_1; + parit64_2 = glob_parity ^ parit64_1; + parit128_2 = glob_parity ^ parit128_1; + parit256_2 = glob_parity ^ parit256_1; + parit512_2 = glob_parity ^ parit512_1; + parit1024_2 = glob_parity ^ parit1024_1; + parit2048_2 = glob_parity ^ parit2048_1; + + /* Pack bits */ + ecc[0] = + ~((parit64_1 << 7) | (parit64_2 << 6) | (parit32_1 << 5) | + (parit32_2 << 4) | (parit16_1 << 3) | (parit16_2 << 2) | (parit8_1 + << 1) | + parit8_2); + ecc[1] = + ~((parit1024_1 << 7) | (parit1024_2 << 6) | (parit512_1 << 5) | + (parit512_2 << 4) | (parit256_1 << 3) | (parit256_2 << 2) | + (parit128_1 << 1) | parit128_2); + ecc[2] = + ~((parit4_1 << 7) | (parit4_2 << 6) | (parit2_1 << 5) | + (parit2_2 << 4) | (parit1_1 << 3) | (parit1_2 << 2) | (parit2048_1 + << 1) | + parit2048_2); + + return 0; +} + +static struct nand_ecclayout nand_oob = { + + .eccbytes = 12, + + + + .eccpos = {2, 3, 4, 18, 19, 20, 34, 35, 36, 50, 51, 52}, + .oobavail = MTD_NANDECC_AUTOPLACE, + .oobfree = { + { .offset = 8, + .length = 8, + }, + }, +}; + +static struct mtd_partition nandflash_main_partitions[] = { + + {.name = "X-Loader(NAND)", + .offset = 0, + .size = 2 * 0x000020000}, /*256 Kbytes */ + {.name = "MemInit(NAND)", + .offset = 2 * 0x000020000, + .size = 2 * 0x000020000}, /*128 KBytes */ + {.name = "BootLoader(NAND)", + .offset = 4 * 0x000020000, + .size = 16 * 0x00020000}, /*2Mbytes */ + {.name = "Kernel zImage(NAND)", + .offset = 20 * 0x000020000, + .size = 24 * 0x000020000}, /*3Mbytes */ + {.name = "Root Filesystem(NAND)", + .offset = 44 * 0x000020000, + .size = 176 * 0x000020000}, /*22 Mbytes */ + {.name = "User Filesystem(NAND)", + .offset = 220 * 0x000020000, + .size = 800 * 0x000020000}, /*100 Mbytes */ +}; + +uint8_t scan_ff_pattern[] = { 0xff, 0xff }; + +struct nand_bbt_descr bbt_desc = { + .options = 0, + .offs = 0, + .len = 2, + .pattern = scan_ff_pattern +}; + +static void nmdknand_hwcontrol(struct mtd_info *mtd, int cmd, + unsigned int ctrl) +{ + struct nomadik_nand_info *drvdata = + container_of(mtd, struct nomadik_nand_info, mtd); + + if (cmd == NAND_CMD_NONE) + return; + + if (ctrl & NAND_NCE) { + *((volatile unsigned long *)(IO_ADDRESS(NOMADIK_FSMC_BASE) + + 0x40)) |= 0x04; + } + if (ctrl & NAND_CLE) { + writeb(cmd,drvdata->cmemc_va); + } + if (ctrl & NAND_ALE) { + writeb(cmd,drvdata->cmema_va); + } +} + +static struct nomadik_nand_platform_data nomadik_nand_flash_data = { + .parts = nandflash_main_partitions, + .num_parts = ARRAY_SIZE(nandflash_main_partitions), + .lp_options = NAND_STM_LP_OPTIONS, + .eccsize = 512, + .eccsteps = 4, + .badblockpos = 5, + .init = nomadik_nandflash_init, + .exit = nomadik_nandflash_exit, + .nand_oob = &nand_oob, + .bbt_desc = &bbt_desc, + .compute_ecc = nmdknand_compute_ecc512, + .hwcontrol = nmdknand_hwcontrol, +}; + +static struct platform_device nomadik_nand_flash = { + .name = "NOMADIK-NAND", + .id = 0, + .dev = { + .platform_data = &nomadik_nand_flash_data, + }, + .num_resources = ARRAY_SIZE(nandflash_resources), + .resource = nandflash_resources, +}; + +static struct mtd_partition nmdkflash_main_partitions[] = { + {.name = "BootLoader(NOR)", + .size = 0x00040000, /*256K */ + .offset = 0,}, + {.name = "zImage+initrd(NOR)", + .size = 0x001C0000, /*1.75MB */ + .offset = MTDPART_OFS_APPEND,}, + {.name = "Root Filesystem(NOR)", + .size = 0x01200000, /*18MB */ + .offset = MTDPART_OFS_APPEND,}, + {.name = "User Filesystem(NOR)", + .size = 0x00800000, /*8MB */ + .offset = MTDPART_OFS_APPEND,}, + {.name = "initrd(NOR)", + .size = 0x00200000, /*4MB */ + .offset = MTDPART_OFS_APPEND,} +}; + +static struct flash_platform_data nomadik_nor_flash_data = { + .name = "nomadik_nor", + .map_name = "cfi_probe", + /*.width = NMDK_FLASH_BUSWIDTH, */ + .parts = nmdkflash_main_partitions, + .nr_parts = ARRAY_SIZE(nmdkflash_main_partitions), +}; + +static struct resource norflash_resources[] = { + [0] = { + .name = "norflash-regs", + .start = NMDK_FLASH_BASE, + .end = (NMDK_FLASH_BASE + SZ_32M - 1), + .flags = IORESOURCE_MEM, + }, +}; + +static struct platform_device nomadik_nor_flash = { + .name = "NOMADIK-NOR", + .id = 0, + .dev = { + .platform_data = &nomadik_nor_flash_data, + }, + .num_resources = ARRAY_SIZE(norflash_resources), + .resource = norflash_resources, +}; + +#endif + +#undef NMDK_DEBUG /*board*/ +#undef NMDK_DEBUG_PFX +#undef NMDK_DBG + + +#ifdef CONFIG_SMC91X +static void nomadik_smc91x_irq_init(void) +{ + /* Reset ethernet controller */ + nomadik_epio_write_aux_gpo1(nomadik_epio_read_aux_gpo1() & + (unsigned long)(~LAN_RST)); + /* Enabling ethernet interrupts */ + nomadik_epio_write_cob_ctl(nomadik_epio_read_cob_ctl() & (u16)(~GPIO106_LAN_IT)); + /*type need to be set in case of shared irq */ + set_irq_type(IRQNO_GPIO(SMC91111_IRQ), SA_TRIGGER_RISING); +} + +static struct resource smc91x_resources[] = { + [0] = { + .name = "smc91x-regs", + .start = (NOMADIK_ETH0_BASE + 0x300), + .end = (NOMADIK_ETH0_BASE + SZ_64M - 1), + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQNO_GPIO(SMC91111_IRQ), + .end = IRQNO_GPIO(SMC91111_IRQ), + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device smc91x_device = { + .name = "smc91x", + .id = 0, + .num_resources = ARRAY_SIZE(smc91x_resources), + .resource = smc91x_resources, +}; +#endif + +/* + * touchpanel + */ +#ifdef CONFIG_TOUCHSCREEN_NOMADIK +#ifndef TOUCHP_DEBUG +#define TOUCHP_DEBUG 0 /* default debug messages are disabled */ +#endif /* */ + +#undef NMDK_DEBUG +#undef NMDK_DEBUG_PFX +#undef NMDK_DBG +#define NMDK_DEBUG TOUCHP_DEBUG /* enables/disables debug msgs */ +#define NMDK_DEBUG_PFX TPDRVNAME /* msg header represents this module */ +#define NMDK_DBG KERN_ERR /* message level */ + +/** + * nomadik_tp_ssp_board_init - board specific ssp data path setup + * @p_adsContext: device data structure pointer + * + * This routine initializes the SSP for touchpanel operation + * Selects the SSP source for the EXP_SSP and SPI3V interfaces + */ +int nomadik_tp_ssp_board_init(struct t_adsContext *p_adsContext) +{ + nmdk_dbg_ftrace(); + nomadik_epio_write_ssp_conf(EXP_SSP); + return (0); +} + +/** + * nomadik_tp_gpio_board_init - board specific gpio initialization + * @p_adsContext: device data structure pointer + * + * This routine initializes the GPIO for touchpanel operation + * RETURN: GPIO nmdk_error code + * SSP is interfaced with ADS7843 through CPLD hence respective + * interface need to be enabled for NDK10 + * BIOS/TCHSCR: BIOS EEPROM and Touch Screen have the same SPI + * chip select, this bit allows the selection between the two + * peripherals. setting this bit Touch screen selected + */ +gpio_error nomadik_tp_gpio_board_init(struct t_adsContext * p_adsContext) +{ + gpio_error status = GPIO_OK; + + nmdk_dbg_ftrace(); + nomadik_epio_write_cob_ctl(nomadik_epio_read_cob_ctl() | BIOS_TCHSCR); + +#if defined TOUCHP_CS0 && defined TOUCHP_CS1 + { + gpio_config config_cspin; + /* Set SPICSn_TCHSCR pin configuration */ + config_cspin.mode = GPIO_MODE_SOFTWARE; + config_cspin.direction = GPIO_DIR_OUTPUT; + config_cspin.debounce = GPIO_DEBOUNCE_DISABLE; + config_cspin.dev_name = "Touchp"; + status = nomadik_gpio_setpinconfig(TOUCHP_CS0, &config_cspin); + if (status) { + nmdk_error("GPIO %d configuration failure (nmdk_error:%d)", + TOUCHP_CS0, status); + goto err_TOUCHP_CS0; + } + + status = nomadik_gpio_setpinconfig(TOUCHP_CS1, &config_cspin); + if (status) { + nmdk_error("GPIO %d configuration failure (nmdk_error:%d)", + TOUCHP_CS1, status); + goto err_TOUCHP_CS1; + } + } +#endif + /* Set PENIRQ pin configuration */ + set_irq_type(p_adsContext->irq, SA_TRIGGER_FALLING); + + return status; + +#if defined TOUCHP_CS0 && defined TOUCHP_CS1 + err_TOUCHP_CS1: + nomadik_gpio_resetpinconfig(TOUCHP_CS1, "Touchp"); + err_TOUCHP_CS0: + return status; +#endif +} + +/** + * nomadik_tp_gpio_board_exit - board specific gpio exit + * @p_adsContext: device data structure pointer + * + * This routine performs revers action of init + */ +gpio_error nomadik_tp_gpio_board_exit(struct t_adsContext * p_adsContext) +{ + gpio_error status = GPIO_OK; + + nmdk_dbg_ftrace(); +#if defined TOUCHP_CS0 && defined TOUCHP_CS1 + status |= nomadik_gpio_resetpinconfig(TOUCHP_CS0, "Touchp"); + status |= nomadik_gpio_resetpinconfig(TOUCHP_CS1, "Touchp"); +#endif + nomadik_epio_write_cob_ctl(nomadik_epio_read_cob_ctl() & (u16)~BIOS_TCHSCR); + return status; +} + +/** + * nomadik_tp_pen_down - returns pen touch status + */ +t_bool nomadik_tp_pen_down(struct t_adsContext * p_adsContext) +{ + gpio_data pen_down; + + nmdk_dbg_ftrace(); + nomadik_gpio_readpin(GPIO_PIN_FOR_IRQ(p_adsContext->irq), &pen_down); + nmdk_dbg2("pen_down = 0x%d (pin%d)", + pen_down, GPIO_PIN_FOR_IRQ(p_adsContext->irq)); + return ((t_bool) pen_down); +} + +/** + * nomadik_tp_pen_down_irq_enable - enables pen interrupt + */ +void nomadik_tp_pen_down_irq_enable(struct t_adsContext *p_adsContext) +{ + nmdk_dbg_ftrace(); + enable_irq(p_adsContext->irq); +} + +/** + * nomadik_tp_pen_down_irq_disable - disables pen interrupt + */ +void nomadik_tp_pen_down_irq_disable(struct t_adsContext *p_adsContext) +{ + nmdk_dbg_ftrace(); + disable_irq(p_adsContext->irq); +} + +/** + * nomadik_tp_spi_cs_disable - disables the chip select for ads7843 + * + * sets GPIOS to to provid inputs to CPLD to disable chip select + */ +void nomadik_tp_spi_cs_disable(void) +{ + nmdk_dbg_ftrace(); +#if defined TOUCHP_CS0 && defined TOUCHP_CS1 + nomadik_gpio_writepin(TOUCHP_CS0, 1, "Touchp"); + nomadik_gpio_writepin(TOUCHP_CS1, 1, "Touchp"); +#endif +} + +/** + * nomadik_tp_spi_cs_enaable - enables the chip select for ads7843 + * + * sets GPIOS to to provid inputs to CPLD to enable chip select + */ +void nomadik_tp_spi_cs_enable(void) +{ + nmdk_dbg_ftrace(); +#if defined TOUCHP_CS0 && defined TOUCHP_CS1 + nomadik_gpio_writepin(TOUCHP_CS0, 0, "Touchp"); + nomadik_gpio_writepin(TOUCHP_CS1, 1, "Touchp"); +#endif +} + +static struct touchp_device touchp_board = { + .ssp_init = nomadik_tp_ssp_board_init, + .gpio_init = nomadik_tp_gpio_board_init, + .gpio_exit = nomadik_tp_gpio_board_exit, + .pdown = nomadik_tp_pen_down, + .pirq_en = nomadik_tp_pen_down_irq_enable, + .pirq_dis = nomadik_tp_pen_down_irq_disable, + .cs_en = nomadik_tp_spi_cs_disable, + .cs_dis = nomadik_tp_spi_cs_enable, + .samples = 100, /*samples per second*/ + .pollsamples = 10, /*polling per second*/ +}; + +static struct resource touchp_resources[] = { + [0] = { + .start = IRQNO_GPIO(TOUCHP_IRQ), + .end = IRQNO_GPIO(TOUCHP_IRQ), + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device touchp_device = { + .name = "nmdk-tp", + .id = 0, + .dev = { + .platform_data = &touchp_board, + }, + .num_resources = ARRAY_SIZE(touchp_resources), + .resource = touchp_resources, +}; +#undef NMDK_DEBUG +#undef NMDK_DEBUG_PFX +#undef NMDK_DBG +#endif + +#ifdef CONFIG_KEYPAD_NOMADIK +#define KEYPAD_NAME "KEYPAD" +#ifndef KEYPAD_DEBUG +#define KEYPAD_DEBUG 0 +#endif + +#define NMDK_DEBUG KEYPAD_DEBUG /* enables/disables nmdk_dbg msgs */ +#define NMDK_DEBUG_PFX KEYPAD_NAME /* msg header represents this module */ +#define NMDK_DBG KERN_ERR /* message level */ + +/*key scan constants*/ +#define KSCAN_ALLROWS 0x00FF +#define KSCAN_ALLCOLS 0xFF00 +#define KSCAN_ROW0 0x0001 +#define KSCAN_ROW1 0x0002 +#define KSCAN_ROW2 0x0004 +#define KSCAN_ROW3 0x0008 +#define KSCAN_ROW4 0x0010 +#define KSCAN_ROW5 0x0020 +#define KSCAN_ROW6 0x0040 +#define KSCAN_ROW7 0x0080 +#define KSCAN_COL0 0x0100 +#define KSCAN_COL1 0x0200 +#define KSCAN_COL2 0x0400 +#define KSCAN_COL3 0x0800 +#define KSCAN_COL4 0x1000 +#define KSCAN_COL5 0x2000 +#define KSCAN_COL6 0x4000 +#define KSCAN_COL7 0x8000 + +unsigned short const keychkval_set[] = { + (unsigned short)~KSCAN_COL0 | KSCAN_ALLROWS, + (unsigned short)~KSCAN_COL1 | KSCAN_ALLROWS, + (unsigned short)~KSCAN_COL2 | KSCAN_ALLROWS, + (unsigned short)~KSCAN_COL3 | KSCAN_ALLROWS, + (unsigned short)~KSCAN_COL4 | KSCAN_ALLROWS, + (unsigned short)~KSCAN_COL5 | KSCAN_ALLROWS, + (unsigned short)~KSCAN_COL6 | KSCAN_ALLROWS, + (unsigned short)~KSCAN_COL7 | KSCAN_ALLROWS, +}; + +unsigned short const keychkval_read[] = { + KSCAN_ROW0, KSCAN_ROW1, KSCAN_ROW2, KSCAN_ROW3, KSCAN_ROW4, KSCAN_ROW5, + KSCAN_ROW6, KSCAN_ROW7, +}; + +/** + * nomadik_kp_ghostkey_detect - ghost key detect function + * @rowval: row in which ghost key to be detected + * + * when more than one key is pressed in the same row the keypad logic cannot + * detect proper key press, the logic here detects multiple keypress on a + * single row and returns error + */ +int nomadik_kp_ghostkey_detect(short rowval) +{ + int row; + int ghcnt = 0; + + for (row = 0; row < MAX_KPROW; row++) { + if (0 == (rowval & keychkval_read[row])) { + /*keypr detected */ + ghcnt++; + } + if (1 < ghcnt) + /*return error if more than one keys are pressed in a row */ + return (-1); + } + return (0); +} + +/** + * nomadik_kp_key_scan - keypad scan and report event function + * + * Scans through keypad hardware and updates the key status for key press + * or key release event to upper layer + */ +int nomadik_kp_key_scan(struct keypad_t *kp) +{ + short val; + u8 row, col; + int keyp_cnt = 0; + u8 *p_kcode; + + nmdk_dbg_ftrace(); + for (col = 0; col < MAX_KPCOL; col++) { + p_kcode = kp->board->kcode_tbl + col; + nomadik_epio_write_keypad(keychkval_set[col]); + val = nomadik_epio_read_keypad(); + val &= KSCAN_ALLROWS; + if (0 == nomadik_kp_ghostkey_detect(val)) { + for (row = 0; row < MAX_KPROW; row++) { + if (0 == (val & keychkval_read[row])) { /*keypr detected */ + keyp_cnt++; + if (kp->key_state[row][col] == + KEYPAD_STATE_DEFAULT) { + input_report_key(kp->inp_dev, + *p_kcode, 1); + nmdk_dbg("P:%d ", *p_kcode); + kp->key_state[row][col] = + KEYPAD_STATE_PRESSACK; + } + } else { /*key not pressed detected */ + if (kp->key_state[row][col] == + KEYPAD_STATE_PRESSACK) { + input_report_key(kp->inp_dev, + *p_kcode, 0); + nmdk_dbg("R:%d ", *p_kcode); + kp->key_state[row][col] = + KEYPAD_STATE_DEFAULT; + } + } + p_kcode += MAX_KPROW; + } + } else + keyp_cnt += 0x100; /* to flag ghost keypress detection */ + } + /* pull down all rows to detect any keypress */ + nomadik_epio_write_keypad(KSCAN_ALLCOLS & KSCAN_ALLROWS); + return (keyp_cnt); +} + +/** + * nomadik_kp_init_key_hardware - keypad hardware initialization + * + * Initializes the keypad hardware specific parameters. + * This function will be called by nomadik_keypad_init function during init + * Initialize keypad interrupt handler for interrupt mode operation if enabled + * Initialize Keyscan matrix + **************************************************************************** + */ +int nomadik_kp_init_key_hardware(struct keypad_t *kp) +{ + nmdk_dbg_ftrace(); + nomadik_epio_write_keypad(KSCAN_ALLCOLS); + if ((KSCAN_ALLCOLS | KSCAN_ALLROWS) != (u16) nomadik_epio_read_keypad()) { + /*check wrong key */ + nmdk_error("Keypad H/w error...."); + return (-1); + } + if (!kp->mode) { /* true if interrupt mode operation */ + /* pull down all rows to detect any keypress */ + nomadik_epio_write_keypad(KSCAN_ALLROWS); + set_irq_type(kp->irq, SA_TRIGGER_FALLING); + /* + * TBD logic should be added to detect proper switch settings + * on a board to detect valid interrupt + */ + } + return 0; +} + +/** + * nomadik_kp_exit_key_hardware- keypad hardware exit function + * + * This function will be called by nomadik_keypad_exit function during module + * exit, frees keypad interrupt if enabled + */ +int nomadik_kp_exit_key_hardware(struct keypad_t *kp) +{ + nmdk_dbg_ftrace(); + /* pull up all columns so that interrupt will not be raised*/ + nomadik_epio_write_keypad(KSCAN_ALLCOLS |KSCAN_ALLCOLS); + return 0; +} + +/** + * nomadik_kp_key_irqen- enables keypad interrupt + * + * enables keypad interrupt through CPLD logic + */ +int nomadik_kp_key_irqen(struct keypad_t *kp) +{ + /*enable_irq(kp->irq);*/ + return 0; +} + +/** + * nomadik_kp_key_irqdis- disables keypad interrupt + * + * disables keypad interrupt through CPLD logic + */ +int nomadik_kp_key_irqdis(struct keypad_t *kp) +{ + /*disable_irq(kp->irq);*/ + return 0; +} + +/* + * Initializes the key scan table (lookup table) as per pre-defined the scan + * codes to be passed to upper layer with respective key codes + */ +u8 const kpd_lookup_tbl[MAX_KPROW][MAX_KPROW] = { + {KEY_ESC, KEY_F1, KEY_F2, KEY_F3, KEY_F4, KEY_F5, KEY_F6, KEY_SPACE}, + {KEY_GRAVE, KEY_1, KEY_2, KEY_3, KEY_4, KEY_5, KEY_6, KEY_7}, + {KEY_8, KEY_9, KEY_0, KEY_MINUS, KEY_EQUAL, KEY_BACKSPACE, KEY_INSERT, + KEY_HOME}, + {KEY_TAB, KEY_Q, KEY_W, KEY_E, KEY_R, KEY_T, KEY_Y, KEY_U}, + {KEY_I, KEY_O, KEY_P, KEY_LEFTBRACE, KEY_RIGHTBRACE, KEY_BACKSLASH, + KEY_DELETE, KEY_END}, + {KEY_CAPSLOCK, KEY_A, KEY_S, KEY_D, KEY_F, KEY_G, KEY_H, KEY_J}, + {KEY_K, KEY_L, KEY_SEMICOLON, KEY_APOSTROPHE, KEY_ENTER, KEY_DOT, + KEY_COMMA, KEY_SLASH}, + {KEY_LEFTSHIFT, KEY_Z, KEY_X, KEY_C, KEY_V, KEY_B, KEY_N, KEY_M} +}; + +static struct keypad_device keypad_board = { + .init = nomadik_kp_init_key_hardware, + .exit = nomadik_kp_exit_key_hardware, + .scan = nomadik_kp_key_scan, + .irqen = nomadik_kp_key_irqen, + .irqdis = nomadik_kp_key_irqdis, + .kcode_tbl = (u8 *) kpd_lookup_tbl, + .krow = 8, + .kcol = 8, +}; + +static struct resource keypad_resources[] = { + [0] = { + .start = IRQNO_GPIO(KEYPAD_IRQ), + .end = IRQNO_GPIO(KEYPAD_IRQ), + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device keypad_device = { + .name = "nmdk-kp", + .id = 0, + .dev = { + .platform_data = &keypad_board, + }, + .num_resources = ARRAY_SIZE(keypad_resources), + .resource = keypad_resources, +}; +#undef NMDK_DEBUG +#undef NMDK_DEBUG_PFX +#undef NMDK_DBG +#endif + +#ifdef CONFIG_CPLD_I2C +#define EPIO_NAME "EPIO" +#ifndef EPIO_DEBUG +#define EPIO_DEBUG 0 +#endif + +#define NMDK_DEBUG EPIO_DEBUG /* enables/disables nmdk_dbg msgs */ +#define NMDK_DEBUG_PFX EPIO_NAME /* msg header represents this module */ +#define NMDK_DBG KERN_ERR /* message level */ + +static void nomadik_epio_plat_init(void) +{ + nmdk_dbg_ftrace(); + /* Initializing CPLD registers for initial values */ + nomadik_epio_write_cob_ctl(0x0030); /* reset value */ + nomadik_epio_write_keypad(0xff00); /* COL7:0 set to high Z */ + nomadik_epio_write_msp_conf(0x794); /* reset value */ + nomadik_epio_write_uart_conf(0x0694); /* UART1 enabled for rs232 port*/ + nomadik_epio_write_ssp_conf(0x0124); /* reset value */ + nomadik_epio_write_aux_gpo1(0x2880); /* reset value */ + nomadik_epio_write_aux_gpo2(0x018a); /* reset value */ +#ifdef CONFIG_SMC91X + nomadik_smc91x_irq_init(); +#endif +} + +static struct platform_device epio_device = { + .name = "NOMADIK-EPIO", + .id = 0, + .dev = { + .platform_data = nomadik_epio_plat_init, + }, +}; +#undef NMDK_DEBUG +#undef NMDK_DEBUG_PFX +#undef NMDK_DBG +#endif /*CONFIG_CPLD_I2C*/ + +static struct platform_device *nmdk_platform_devices[] __initdata = { + &fsmc_device, +#ifdef CONFIG_CPLD_I2C + &epio_device, +#endif +#ifdef CONFIG_KEYPAD_NOMADIK + &keypad_device, +#endif +#ifdef CONFIG_SMC91X + &smc91x_device, +#endif +#ifdef CONFIG_TOUCHSCREEN_NOMADIK + &touchp_device, +#endif +#ifdef CONFIG_MTD + &nomadik_nand_flash, + &nomadik_nor_flash, +#endif +}; + +void add_nmdk_platform_devices(void) +{ + platform_add_devices(nmdk_platform_devices, + ARRAY_SIZE(nmdk_platform_devices)); +} --- /dev/null +++ linux-2.6.20/arch/arm/mach-nomadik/nhk15_Kconfig @@ -0,0 +1,36 @@ +if NOMADIK_NHK15 + +comment "Nomadik chip used STn8815" + +#target name configuration for this target +config NOMADIK_TARGET + string + default NHK15 + +# nomadik soc chip name configuration for this target +config NOMADIK_SOC + string + default stn8815 + +# nomadik soc chip cut name configuration for this targe only +config NOMADIK_STN8815CAS22H11 + bool + default y + +# nomadik platform name configuration for this targe +config NOMADIK_PLATFORM + string + default nhk15 + +# EXTRA_CFLAGS configuration for this target +config NOMADIK_TARGET_EXTRA_CFLAGS + string + default "-D__RELEASE -D__STN_8815=40 " + + +# Basic platform type configuration for this targe +config NOMADIK_NHK15 + bool + default y + +endif --- /dev/null +++ linux-2.6.20/arch/arm/mach-nomadik/nhk15_devices.c @@ -0,0 +1,1009 @@ +/* + * linux/arch/arm/mach-nomadik/nhk15_devices.c + * + * Copyright (C) STMicroelectronics + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2, as + * published by the Free Software Foundation. + * + * NHK15 board specifc driver definition + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef CONFIG_MTD +#include +#include +#include +#include +#include +#include +#include +#endif +#include +#include +#include + +#define DEBUG_KP(x) printk x +#define DEBUG_TS(x) printk x + +#define BOARD_NAME CONFIG_NOMADIK_PLATFORM +#ifndef BOARD_DEBUG +#define BOARD_DEBUG 0 +#endif + +#define NMDK_DEBUG BOARD_DEBUG /* enables/disables nmdk_dbg msgs */ +#define NMDK_DEBUG_PFX BOARD_NAME /* msg header represents this module */ +#define NMDK_DBG KERN_ERR /* message level */ + +#define INT_USBOTG 23 +#define NOMADIK_USB_BASE 0x10170000 +#ifdef CONFIG_SMC91X +static void nomadik_smc91x_irq_init(void); +#endif + +/** + * nomadik_clcd_board_enable - enables board specific clcd prameters + * + * Settings to enable backlight and pannel voltage regulator for NDK15 + */ +void nomadik_clcd_enable(void *fbp) +{ + /* not implimented for this board */ +} + +/** + * nomadik_clcd_board_disable - disables board specific clcd prameters + * + * Settings to disable backlight and pannel voltage regulator for NDK10 + */ +void nomadik_clcd_disable(void *fbp) +{ + /* not implimented for this board */ +} + +/* + * Settings to configure MMC controller for NDK10 + */ +int nomadik_mmc_configure(struct amba_device *dev) +{ + /* not implimented for this board */ + int ret; + char x = val_volt; + ret = nomadik_i2c_write_register(I2C_TOUAREG_CLIENT, &x, 0x11, 1); + if (ret) { + nmdk_error("Error in writing value to touareg register"); + + } + + ret = nomadik_gpio_altfuncenable(GPIO_ALT_SD_CARD, dev->dev.bus_id); + if (ret) { + nmdk_error("Error in gpio Altfunction enable"); + + } + return ret; + + return 0; +} + +void nomadik_mmc_restore_default(struct amba_device *dev) +{ + /* not implimented for this board */ + nomadik_gpio_altfuncdisable(GPIO_ALT_SD_CARD, dev->dev.bus_id); +} + +static int fsmc_platform_init(void) +{ + unsigned char __iomem *fsmc_base; + + nmdk_dbg_ftrace(); + /*Following Settings done for NAND flash protect off */ + fsmc_base = (unsigned char *)IO_ADDRESS(NOMADIK_FSMC_BASE); + + /* for NOR accesss */ + /* Initialize the fsmc bank 0 */ + *((volatile u32 *)(NOMADIK_FSMC_VA + FSMC_BCR0)) = 0x10db; + *((volatile u32 *)(NOMADIK_FSMC_VA + FSMC_BTR0)) = 0x03333333; + /* Initialize the fsmc bank 1 used for ethernet controller */ + *((volatile u32 *)(NOMADIK_FSMC_VA + FSMC_BCR1)) = 0x305B; + *((volatile u32 *)(NOMADIK_FSMC_VA + FSMC_BTR1)) = 0x033F33; /*old 00000702 */ + + *((volatile u32 *)(NOMADIK_FSMC_VA + FSMC_BCR0)) |= 0x80; + /* Above Settings done for NAND flash protect off */ + return 0; +} + +static struct resource fsmc_resources[] = { + [0] = { + .start = NOMADIK_FSMC_BASE, + .end = NOMADIK_FSMC_BASE + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, +}; + +struct fsmc_platform_data fsmc_data = { + .init = fsmc_platform_init, +}; + +static struct platform_device fsmc_device = { + .name = "NOMADIK-FSMC", + .id = 0, + .dev = { + .platform_data = &fsmc_data, + }, + .num_resources = ARRAY_SIZE(fsmc_resources), + .resource = fsmc_resources, +}; + +#ifdef CONFIG_MTD +#ifdef CONFIG_MTD_NAND +static struct resource nandflash_resources[] = { + [0] = { + .name = "cmem_address", + .start = NAND_B0_CMEM_ADDR, + .end = (NAND_B0_CMEM_ADDR + SZ_1K - 1), + .flags = IORESOURCE_MEM, + }, + [1] = { + .name = "cmem_command", + .start = NAND_B0_CMEM_CMD, + .end = (NAND_B0_CMEM_CMD + SZ_1K - 1), + .flags = IORESOURCE_MEM, + }, + [2] = { + .name = "cmem_data", + .start = NAND_B0_CMEM_DATA, + .end = (NAND_B0_CMEM_DATA + SZ_1K - 1), + .flags = IORESOURCE_MEM, + }, +}; + +/*NHK15 is 8-bit NAND*/ +#define NAND_STM_LP_OPTIONS \ + ( NAND_COPYBACK | NAND_CACHEPRG | NAND_NO_PADDING | NAND_NO_READRDY | NAND_NO_AUTOINCR) + +int nomadik_nandflash_exit(void) +{ + return 0; + +} +int nomadik_nandflash_init(void) +{ +#if 1 + /* + * FSMC initialization + * 0x0000000e => PCR0 + * 0x000d0a00 => PMEM0 + * 0x00100a00 => PATT0 + */ + *((volatile unsigned long *)(NOMADIK_FSMC_VA + FSMC_PCR0)) = + 0x0000000E; /* NHK15 is 8-bit NAND */ + *((volatile unsigned long *)(NOMADIK_FSMC_VA + FSMC_PMEM0)) = + DEFAULT_PMEM0_VALUE; + *((volatile unsigned long *)(NOMADIK_FSMC_VA + FSMC_PATT0)) = + DEFAULT_PATT0_VALUE; +#endif + return 0; +} + +const unsigned char lookup_t[256] = { + 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, + 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, + 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, + 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, + 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, + 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, + 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, + 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, + 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, + 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, + 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, + 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, + 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, + 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, + 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, + 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0 +}; + +int nmdknand_compute_ecc512(struct mtd_info *mtd, const u_char * data, + u_char * ecc) +{ + unsigned int sumCol = 0; + unsigned int datum, temp; + unsigned int glob_parity; + const int ecc_n_bytes = 512; + int i; + + unsigned int parit1_1, parit1_2, parit2_1, parit2_2, parit4_1, parit4_2; + unsigned int parit8_1 = 0, parit8_2 = 0, parit16_1 = 0, parit16_2 = + 0, parit32_1 = 0, parit32_2 = 0; + unsigned int parit64_1 = 0, parit64_2 = 0, parit128_1 = 0, parit128_2 = + 0, parit256_1 = 0, parit256_2 = 0; + unsigned int parit512_1 = 0, parit512_2 = 0, parit1024_1 = + 0, parit1024_2 = 0, parit2048_1 = 0, parit2048_2 = 0; + + for (i = ecc_n_bytes - 1; i >= 0; --i) { + datum = data[i]; + sumCol ^= datum; + temp = lookup_t[datum]; + + if (i & 0x01) + parit8_1 ^= temp; + if (i & 0x02) + parit16_1 ^= temp; + if (i & 0x04) + parit32_1 ^= temp; + if (i & 0x08) + parit64_1 ^= temp; + if (i & 0x10) + parit128_1 ^= temp; + if (i & 0x20) + parit256_1 ^= temp; + if (i & 0x40) + parit512_1 ^= temp; + if (i & 0x80) + parit1024_1 ^= temp; + if (i & 0x100) + parit2048_1 ^= temp; + } + + glob_parity = lookup_t[sumCol]; + + parit1_1 = + ((sumCol >> 1) ^ (sumCol >> 3) ^ (sumCol >> 5) ^ (sumCol >> 7)) & 1; + parit1_2 = + ((sumCol >> 0) ^ (sumCol >> 2) ^ (sumCol >> 4) ^ (sumCol >> 6)) & 1; + parit2_1 = + ((sumCol >> 2) ^ (sumCol >> 3) ^ (sumCol >> 6) ^ (sumCol >> 7)) & 1; + parit2_2 = + ((sumCol >> 0) ^ (sumCol >> 1) ^ (sumCol >> 4) ^ (sumCol >> 5)) & 1; + parit4_1 = + ((sumCol >> 4) ^ (sumCol >> 5) ^ (sumCol >> 6) ^ (sumCol >> 7)) & 1; + parit4_2 = + ((sumCol >> 0) ^ (sumCol >> 1) ^ (sumCol >> 2) ^ (sumCol >> 3)) & 1; + + parit8_2 = glob_parity ^ parit8_1; + parit16_2 = glob_parity ^ parit16_1; + parit32_2 = glob_parity ^ parit32_1; + parit64_2 = glob_parity ^ parit64_1; + parit128_2 = glob_parity ^ parit128_1; + parit256_2 = glob_parity ^ parit256_1; + parit512_2 = glob_parity ^ parit512_1; + parit1024_2 = glob_parity ^ parit1024_1; + parit2048_2 = glob_parity ^ parit2048_1; + + /* Pack bits */ + ecc[0] = + ~((parit64_1 << 7) | (parit64_2 << 6) | (parit32_1 << 5) | + (parit32_2 << 4) | (parit16_1 << 3) | (parit16_2 << 2) | (parit8_1 + << 1) | + parit8_2); + ecc[1] = + ~((parit1024_1 << 7) | (parit1024_2 << 6) | (parit512_1 << 5) | + (parit512_2 << 4) | (parit256_1 << 3) | (parit256_2 << 2) | + (parit128_1 << 1) | parit128_2); + ecc[2] = + ~((parit4_1 << 7) | (parit4_2 << 6) | (parit2_1 << 5) | + (parit2_2 << 4) | (parit1_1 << 3) | (parit1_2 << 2) | (parit2048_1 + << 1) | + parit2048_2); + + return 0; +} + +static struct nand_ecclayout nand_oob = { + .eccbytes = 12, + .eccpos = {2, 3, 4, 18, 19, 20, 34, 35, 36, 50, 51, 52}, + .oobavail = MTD_NANDECC_AUTOPLACE, + .oobfree = { + { .offset = 8, + .length = 8, + }, + { .offset = 24, + .length = 8, + }, + { .offset = 40, + .length = 8, + }, + { .offset = 56, + .length = 8, + }, + }, +}; +static struct mtd_partition nandflash_main_partitions[] = { + + {.name = "X-Loader(NAND)", + .offset = 0, + .size = 2 * 0x000020000}, /*256 Kbytes */ + {.name = "MemInit(NAND)", + .offset = 2 * 0x000020000, + .size = 2 * 0x000020000}, /*128 KBytes */ + {.name = "BootLoader(NAND)", + .offset = 4 * 0x000020000, + .size = 16 * 0x00020000}, /*2Mbytes */ + {.name = "Kernel zImage(NAND)", + .offset = 20 * 0x000020000, + .size = 24 * 0x000020000}, /*3Mbytes */ + {.name = "Root Filesystem(NAND)", + .offset = 44 * 0x000020000, + .size = 176 * 0x000020000}, /*22 Mbytes */ + {.name = "User Filesystem(NAND)", + .offset = 220 * 0x000020000, + .size = 800 * 0x000020000}, /*100 Mbytes */ +}; + +uint8_t scan_ff_pattern[] = { 0xff, 0xff }; + +struct nand_bbt_descr bbt_desc = { + .options = 0, + .offs = 0, + .len = 2, + .pattern = scan_ff_pattern +}; + +static void nmdknand_hwcontrol(struct mtd_info *mtd, int cmd, + unsigned int ctrl) +{ + struct nomadik_nand_info *drvdata = + container_of(mtd, struct nomadik_nand_info, mtd); + + if (cmd == NAND_CMD_NONE) + return; + + if (ctrl & NAND_NCE) { + *((volatile unsigned long *)(IO_ADDRESS(NOMADIK_FSMC_BASE) + + 0x40)) |= 0x04; + } + if (ctrl & NAND_CLE) { + writeb(cmd,drvdata->cmemc_va); + } + if (ctrl & NAND_ALE) { + writeb(cmd,drvdata->cmema_va); + } +} + +static struct nomadik_nand_platform_data nomadik_nand_flash_data = { + .parts = nandflash_main_partitions, + .num_parts = ARRAY_SIZE(nandflash_main_partitions), + .lp_options = NAND_STM_LP_OPTIONS, + .eccsize = 512, + .eccsteps = 4, + /*.badblockpos = 5,*/ + .badblockpos = 6, + .init = nomadik_nandflash_init, + .exit = nomadik_nandflash_exit, + .nand_oob = &nand_oob, + .bbt_desc = &bbt_desc, + .compute_ecc = nmdknand_compute_ecc512, + .hwcontrol = nmdknand_hwcontrol, +}; + +static struct platform_device nomadik_nand_flash = { + .name = "NOMADIK-NAND", + .id = 0, + .dev = { + .platform_data = &nomadik_nand_flash_data, + }, + .num_resources = ARRAY_SIZE(nandflash_resources), + .resource = nandflash_resources, +}; +#endif //CONFIG_MTD_NAND + +#ifdef CONFIG_MTD_ONENAND +static int nomadik_1nand_init(void) +{ int ret=0; + int fsmc_err=1; + int board=8820; + + /*Set the reset signal to high*/ + ret = STMPE2401_SetGpioAltFunction(STMPE1,EGPIO_PIN_9,STMPE2401_PRIMARY_FUNCTION); + if (ret != STMPE2401_OK) + nmdk_error("Couldn't set STMPE1 %d as primary function\n",EGPIO_PIN_9); + ret = STMPE2401_SetGpioDir( STMPE1,EGPIO_PIN_9,STMPE2401_GPIO_OUT); + if (ret != STMPE2401_OK) + nmdk_error("Couldn't set STMPE1 :%d in Output direction\n", EGPIO_PIN_9); + ret = STMPE2401_SetGpioVal( STMPE1, EGPIO_PIN_9, 1); + + /*Configure other GPIO pins to ALT FUNC A*/ + ret = nomadik_gpio_altfuncenable(GPIO_ALT_ONENAND, "onenand"); + if (ret) + { nmdk_error("Could not set oneNAND GPIO alternate function correctly\n"); + printk("\n>ERROR to config GPIO %d", ret); + return -1; + } + *((volatile unsigned long *)(NOMADIK_FSMC_VA + FSMC_BCR0)) = DEFAULT_BCR0_VALUE; + *((volatile unsigned long *)(NOMADIK_FSMC_VA + FSMC_BTR0)) = DEFAULT_BTR0_VALUE; + return 0; +} + +void nomadik_1nand_exit(void) +{ int ret=0; + ret=nomadik_gpio_altfuncdisable(GPIO_ALT_ONENAND, "onenand"); + if(!ret) + return; + else + { printk("Could not Disable ST ONENAND GPIO alternate function \n"); + } +} + + + +static struct resource nomadik_1nand_resource[] = { + [0] = { + .start = NOMADIK_1NAND_BASE, + .end = NOMADIK_1NAND_BASE + SZ_128K - 1, + .flags = IORESOURCE_MEM, + }, +}; +static struct mtd_partition onenandflash_main_partitions[] = { + {.name = "X-Loader(ONENAND)", + .offset = 0, + .size = 2 * 0x000020000}, /*256 Kbytes */ + {.name = "MemInit(ONENAND)", + .offset = 2 * 0x000020000, + .size = 2 * 0x000020000}, /*256 KBytes */ + {.name = "BootLoader(ONENAND)", + .offset = 4 * 0x000020000, + .size = 16 * 0x00020000}, /*2Mbytes */ + {.name = "Kernel zImage(ONENAND)", + .offset = 20 * 0x000020000, + .size = 32 * 0x000020000}, /*4Mbytes */ + {.name = "Root Filesystem(ONENAND)", + .offset = 52 * 0x000020000, + .size = 176 * 0x000020000}, /*22 Mbytes */ + {.name = "User Filesystem(ONENAND)", + .offset = 228 * 0x000020000, + .size = 1820 * 0x000020000}, /*227.5 Mbytes */ +}; + +static struct flash_platform_data nomadik_1nand_flash_data={ + .init=nomadik_1nand_init, + .exit=nomadik_1nand_exit, + .name="onenand", + .parts=onenandflash_main_partitions, + .nr_parts=ARRAY_SIZE(onenandflash_main_partitions), +}; + +static struct platform_device nomadik_1nand_flash = { + .name = "onenand", + .id = 0, + .dev = { + .bus_id = "1nand", + .platform_data = &nomadik_1nand_flash_data, + }, + .num_resources = ARRAY_SIZE(nomadik_1nand_resource), + .resource = nomadik_1nand_resource, +}; +#endif //CONFIG_MTD_ONENAND +#endif + +#undef NMDK_DEBUG /*board*/ +#undef NMDK_DEBUG_PFX +#undef NMDK_DBG + +static void nomadik_st2590_init(void) +{ + t_STMPE2401_error err; + + nomadik_gpio_altfuncenable(GPIO_ALT_UART_0_MODEM, "BT"); + nomadik_gpio_altfuncenable(GPIO_ALT_MSP_2, "BT"); + /*reset the bt controller which is conected thro port expander 0*/ + err = STMPE2401_SetGpioAltFunction(STMPE0,EGPIO_PIN_16,STMPE2401_PRIMARY_FUNCTION); + if (err != STMPE2401_OK) + { + printk("Couldn't set STMPE%d %d as primary function\n",STMPE0,EGPIO_PIN_16); + } + err = STMPE2401_SetGpioDir( STMPE0,EGPIO_PIN_16,STMPE2401_GPIO_OUT ); + if (err != STMPE2401_OK) + { + printk("Couldn't set STMPE0 EGPIO:%d in Output direction\n", EGPIO_PIN_16); + } + err = STMPE2401_SetGpioVal(STMPE0,EGPIO_PIN_16,0); + if (err != STMPE2401_OK) + { + printk("Couldn't set STMPE0 GPIO16\n"); + } + msleep(100); + err = STMPE2401_SetGpioVal(STMPE0,EGPIO_PIN_16,1); + if (err != STMPE2401_OK) + { + printk("Couldn't set STMPE0 GPIO16\n"); + } + printk("BT Reset Applied !!\n"); +} +#ifdef CONFIG_SMC91X +static void nomadik_smc91x_irq_init(void) +{ + t_STMPE2401_error err; + + nomadik_gpio_altfuncenable(GPIO_ALT_ETHERNET, "ETH"); + /*reset the ethernet controller which is conected thro port expander 1*/ + err = STMPE2401_SetGpioAltFunction(STMPE1,EGPIO_PIN_10,STMPE2401_PRIMARY_FUNCTION); + if (err != STMPE2401_OK) + { + printk("Couldn't set STMPE%d %d as primary function\n",STMPE1,EGPIO_PIN_10); + } + err = STMPE2401_SetGpioDir( STMPE1,EGPIO_PIN_10,STMPE2401_GPIO_OUT ); + if (err != STMPE2401_OK) + { + printk("Couldn't set STMPE EGPIO:%d in Output direction\n", EGPIO_PIN_10); + } + err = STMPE2401_SetGpioVal(STMPE1,EGPIO_PIN_10,0); + if (err != STMPE2401_OK) + { + printk("Couldn't set STMPE GPIO10\n"); + } + mdelay(200); +} + +static struct resource smc91x_resources[] = { + [0] = { + .name = "smc91x-regs", + .start = (NOMADIK_ETH0_BASE + 0x300), + .end = (NOMADIK_ETH0_BASE + SZ_64M - 1), + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQNO_GPIO(SMC91111_IRQ), + .end = IRQNO_GPIO(SMC91111_IRQ), + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device smc91x_device = { + .name = "smc91x", + .id = 0, + .num_resources = ARRAY_SIZE(smc91x_resources), + .resource = smc91x_resources, +}; +#endif + +#define NMDK_DEBUG BOARD_DEBUG /* enables/disables nmdk_dbg msgs */ +#define NMDK_DEBUG_PFX BOARD_NAME /* msg header represents this module */ +#define NMDK_DBG KERN_ERR /* message level */ + +#ifdef CONFIG_STMPE_NOMADIK + +/*initialize the pins which are connected thro stmpe devices + *This is not stmpe platform init function - FIXME + */ +static int nomadik_stmpe_plat_init(void) +{ + int err,ret; + + /* Access the STMPE2401, and make the signal EXP1_GPIO8 as high + * for NAND flash write protet off + */ + err = STMPE2401_SetGpioAltFunction(STMPE1,EGPIO_PIN_8,STMPE2401_PRIMARY_FUNCTION); + if (err != STMPE2401_OK) + nmdk_error("Couldn't set STMPE1 %d as primary function\n",EGPIO_PIN_8); + err = STMPE2401_SetGpioDir( STMPE1,EGPIO_PIN_8,STMPE2401_GPIO_OUT); + if (err != STMPE2401_OK) + nmdk_error("Couldn't set STMPE1 :%d in Output direction\n", EGPIO_PIN_8); + err = STMPE2401_SetGpioVal( STMPE1, EGPIO_PIN_8, 1); + if (err != STMPE2401_OK) + nmdk_error("Couldn't set STMPE GPIO8\n"); + + /*reset the WVGA display which is conected thro port expander 1*/ + err = STMPE2401_SetGpioAltFunction(STMPE1,EGPIO_PIN_5,STMPE2401_PRIMARY_FUNCTION); + if (err != STMPE2401_OK) + nmdk_error("Couldn't set STMPE%d %d as primary function\n",STMPE1,EGPIO_PIN_5); + err = STMPE2401_SetGpioDir( STMPE1,EGPIO_PIN_5,STMPE2401_GPIO_OUT ); + if (err != STMPE2401_OK) + nmdk_error("Couldn't set STMPE EGPIO:%d in Output direction\n", EGPIO_PIN_5); + err = STMPE2401_SetGpioVal( STMPE1, EGPIO_PIN_5, 1); + if (err != STMPE2401_OK) + nmdk_error("Couldn't set STMPE GPIO5\n"); + +#ifdef CONFIG_SMC91X + nomadik_smc91x_irq_init(); + udelay(1000); /*1ms*/ +#endif + nomadik_st2590_init(); + + return 0; +} + +/*not yet implemented*/ +int nomadik_stmpe_plat_exit(void) +{ + return 0; +} + +static struct resource stmpe_resources[] = { + [0] = { + .name = "STMPE", + .start = IRQNO_GPIO(76), + .end = IRQNO_GPIO(76), + .flags = IORESOURCE_IRQ, + }, + [1] = { + .name = "STMPE", + .start = IRQNO_GPIO(78), + .end = IRQNO_GPIO(78), + .flags = IORESOURCE_IRQ, + }, +}; +static struct resource nomadik_udc_resources[] = { + [0] = { + .name = "udc-mem", + .start = IO_ADDRESS(NOMADIK_USB_BASE), + .end = (IO_ADDRESS(NOMADIK_USB_BASE) + SZ_1M -1), + .flags = IORESOURCE_MEM, + }, + + [1] = { + .name = "udc-irq", + .start = INT_USBOTG, + .end = INT_USBOTG, + .flags = IORESOURCE_IRQ, + }, +}; +static struct platform_device nomadik_udc_device = { + .name = "NOMADIK USBDEV", + .id = 0, + .num_resources = ARRAY_SIZE(nomadik_udc_resources), + .resource = nomadik_udc_resources, +}; + +static struct nomadik_stmpe_platform_data nomadik_stmpe_data = { + .init = nomadik_stmpe_plat_init, + .exit = nomadik_stmpe_plat_exit, +}; + +static struct platform_device nomadik_stmpe_device = { + .name = "NOMADIK-STMPE", + .id = 0, + .dev = { + .platform_data = &nomadik_stmpe_data, + }, + .num_resources = ARRAY_SIZE(stmpe_resources), + .resource = stmpe_resources, +}; + +#endif + +#undef NMDK_DEBUG /*board*/ +#undef NMDK_DEBUG_PFX +#undef NMDK_DBG + +/* + * touchpanel + */ + +static int nomadik_tsc2003_init_irq (void (*callback)(void* parameter), void * p) +{ + t_STMPE2401_error err; + DEBUG_TS(("nomadik_tsc2003_init_irq\n")); + err = STMPE2401_SetGpioAltFunction( STMPE1 , EGPIO_PIN_6 , STMPE2401_PRIMARY_FUNCTION ); + err |= STMPE2401_SetGpioDir( STMPE1,EGPIO_PIN_6,STMPE2401_GPIO_IN ); + err |= STMPE2401_SetGpioPull(STMPE1,EGPIO_PIN_6,STMPE2401_FLOATING ); + + err = STMPE2401_Install_Callback(STMPE1, STMPE2401_GPIO_IRQ(6), callback,(void*)p); + if (err != STMPE2401_OK) { + printk("Couldn't setup touch screen callback\n"); + } + err |= STMPE2401_SetGpioEdgeDetect( STMPE1, EGPIO_PIN_6, STMPE2401_FALL_EDGE); + if (err != STMPE2401_OK) { + printk("Couldn't set touch screen edge detection\n"); + } + err = STMPE2401_ClearGpioEdgeStatus(STMPE1,(0x1<board->kcode_tbl[(keys.button[i]&0x3)*4 + ((keys.button[i]>>3)&0x3)]; + input_report_key(kp->inp_dev,kcode, 1); + } + } + if(keys.buttonReleased) + { + for(i=0;iboard->kcode_tbl[(keys.released[i]&0x3)*4 + ((keys.released[i]>>3)&0x3)]; + input_report_key(kp->inp_dev,kcode, 0); + } + } +} + +/** + * nomadik_kp_init_key_hardware - keypad hardware initialization + * + **************************************************************************** + */ +int nomadik_kp_init_key_hardware(struct keypad_t *kp) +{ + t_STMPE2401_error err; + t_STMPE2401_key_config kpconfig; + + DEBUG_KP(("nomadik_kp_init_key_hardware\n")); + nmdk_dbg_ftrace(); + /*setup Columns GPIOs (inputs)*/ + kpconfig.columns = 0xF; //4 columns + kpconfig.rows = 0xF; //4 rows + kpconfig.nCycles = 8; //number of cycles for key data updating + kpconfig.debounce = 64; //de-bounce time 64 ms + kpconfig.scan = STMPE2401_SCAN_OFF; + err = STMPE2401_Keypad_init(STMPE0, kpconfig); + if (err != STMPE2401_OK) + { + printk("Couldn't setup keypad configuration\n"); + } + if (!kp->mode) + { /* true if interrupt mode operation */ + DEBUG_KP(("\tsetting up keypad interrupt stuff\n")); + err = STMPE2401_Install_Callback(STMPE0, STMPE2401_KEYPAD_IRQ,kp_callback,(void*)kp); + if (err != STMPE2401_OK) + { + printk("Couldn't setup keypad callback\n"); + } + err = STMPE2401_InterruptSourceAbilitation(STMPE0, STMPE2401_KEYPAD_IRQ, STMPE2401_ENABLE_INTERRUPT ); + if (err != STMPE2401_OK) + { + printk("Couldn't abilitate the keypad source interrupt\n"); + } + /*err = STMPE2401_InterruptAbilitation(STMPE0, STMPE2401_ENABLE_INTERRUPT ); + if (err != STMPE2401_OK) + { + printk("Couldn't enable the keypad source interrupt\n"); + }*/ + } + err = STMPE2401_Keypad_scan(STMPE0, STMPE2401_SCAN_ON); + if (err != STMPE2401_OK) + { + printk("Couldn't enable keypad scan\n"); + } + return 0; +} + +/** + * nomadik_kp_exit_key_hardware- keypad hardware exit function + * + */ +int nomadik_kp_exit_key_hardware(struct keypad_t *kp) +{ + t_STMPE2401_error err; + + DEBUG_KP(("nomadik_kp_exit_key_hardware\n")); + err = STMPE2401_Keypad_scan(STMPE0, STMPE2401_SCAN_OFF); + if (err != STMPE2401_OK) + { + printk("Couldn't enable keypad scan\n"); + } + if (!kp->mode) + { /* true if interrupt mode operation */ + err = STMPE2401_InterruptAbilitation(STMPE0, STMPE2401_DISABLE_INTERRUPT ); + if (err != STMPE2401_OK) + { + printk("Couldn't disable keypad callback\n"); + } + err = STMPE2401_Remove_Callback(STMPE0, STMPE2401_KEYPAD_IRQ); + if (err != STMPE2401_OK) + { + printk("Couldn't remove keypad callback\n"); + } + } + nmdk_dbg_ftrace(); + return 0; +} + +/** + * nomadik_kp_key_scan - keypad scan and report event function + * + */ +int nomadik_kp_key_scan(struct keypad_t *kp) +{ + DEBUG_KP(("nomadik_kp_key_scan\n")); + kp_callback ((void *) kp); + return 0; +} + +/** + * nomadik_kp_key_irqen- enables keypad interrupt + * + * enables keypad interrupt through CPLD logic + */ +int nomadik_kp_key_irqen(struct keypad_t *kp) +{ + t_STMPE2401_error err; + DEBUG_KP(("nomadik_kp_key_irqen\n")); + err = STMPE2401_InterruptSourceAbilitation(STMPE0, STMPE2401_KEYPAD_IRQ, STMPE2401_ENABLE_INTERRUPT ); + return (err != STMPE2401_OK); +} + +/** + * nomadik_kp_key_irqdis- disables keypad interrupt + * + * disables keypad interrupt through CPLD logic + */ +int nomadik_kp_key_irqdis(struct keypad_t *kp) +{ + t_STMPE2401_error err; + DEBUG_KP(("nomadik_kp_key_irqdis\n")); + err = STMPE2401_InterruptSourceAbilitation(STMPE0, STMPE2401_KEYPAD_IRQ, STMPE2401_DISABLE_INTERRUPT ); + return (err != STMPE2401_OK); +} + +/* + * Initializes the key scan table (lookup table) as per pre-defined the scan + * codes to be passed to upper layer with respective key codes + */ +u8 const kpd_lookup_tbl[4*4] = { + KEY_RESERVED, KEY_RESERVED, KEY_VOLUMEDOWN, KEY_VOLUMEUP, + KEY_F1, KEY_F8, KEY_F3, KEY_F4, + KEY_F5, KEY_F6, KEY_F7, KEY_ENTER, + KEY_LEFT, KEY_RIGHT, KEY_UP, KEY_DOWN +}; + +static struct keypad_device keypad_board = { + .init = nomadik_kp_init_key_hardware, + .exit = nomadik_kp_exit_key_hardware, + .scan = nomadik_kp_key_scan, + .irqen = nomadik_kp_key_irqen, + .irqdis = nomadik_kp_key_irqdis, + .kcode_tbl = (u8 *) kpd_lookup_tbl, + .krow = 4, + .kcol = 4, +}; + +#undef NMDK_DEBUG /*board*/ +#undef NMDK_DEBUG_PFX +#undef NMDK_DBG + + +/*static struct resource keypad_resources[] = { + [0] = { + }, +};*/ + +static struct platform_device keypad_device = { + .name = "nmdk-kp", + .id = 0, + .dev = { + .platform_data = &keypad_board, + }, + .num_resources = 0, + .resource = NULL, +}; + +static struct platform_device *nmdk_platform_devices[] __initdata = { + &fsmc_device, + &nomadik_udc_device, +#ifdef CONFIG_MTD +#ifdef CONFIG_MTD_NAND + &nomadik_nand_flash, +#endif +#ifdef CONFIG_MTD_ONENAND + &nomadik_1nand_flash, +#endif +#endif +#ifdef CONFIG_SMC91X + &smc91x_device, +#endif +#ifdef CONFIG_STMPE_NOMADIK + &nomadik_stmpe_device, +#endif + &keypad_device, + &touchp_tsc2003_device, +}; + +void add_nmdk_platform_devices(void) +{ + platform_add_devices(nmdk_platform_devices, + ARRAY_SIZE(nmdk_platform_devices)); +} --- /dev/null +++ linux-2.6.20/arch/arm/mach-nomadik/normal.S @@ -0,0 +1,199 @@ +/* + * arch/arm/mach-nomadik/normal.S + * + * Copyright 2007, STMicroelectronics + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#define NORMAL_DEBUG 0 +#define mpmc_base 0xF0110000 +#define src_base 0xf01e0000 +#define pmu_base 0xf01e9000 +#define uart_base 0xcc85e000 + + + + +.align 5 +.globl nomadik_normal_mode + +nomadik_normal_mode: + + + stmfd sp!,{r0-r12,lr} + + ldr r10,=mpmc_base + ldr r11,=src_base + ldr r12,=pmu_base + ldr r9,=uart_base + + + ldr r2, [r11] + +#if NORMAL_DEBUG + mov r0, #97 + str r0, [r9] +#endif + + /* Prefetch certain instructions in the cache. */ + adr r4, cache_prefetch_start + adr r5, cache_prefetch_end + mvn r1,#0x1F + ands r4,r1,r4 +pfetch: + mcr p15, 0, r4, c7, c13,1 + cmp r4,r5 + addls r4, r4, #0x20 + bls pfetch + +.align 5 + +cache_prefetch_start: + ldr r10, =mpmc_base + +poll_status: + /* Check sdram is not busy */ + ldr r1,[r10, #0x4] + ands r1,r1,#0x1 + cmp r1,#0 + bne poll_status + + /* Put SDRAM in self-refresh mode*/ + ldr r1,[r10, #0x20] + bic r1,r1,#0x1 + orr r1,r1,#0x04 + str r1,[r10, #0x20] + + + /*Wait for SDRAM to go in self-refresh*/ +wait_self_refresh: + ldr r1,[r10,#0x4] + and r1,r1,#0x4 + cmp r1,#0x0 + beq wait_self_refresh + + /** + * Stop the DLL, leave SDMC on + Moving 0xff9 into sdmc control register for stopping and adding dll + cmd value + */ + mov r1, #0xff0 + mov r2, #0x9 + orr r1, r1, r2 + str r1,[r10] + + +wait_dll_lock: + ldr r1,[r10,#0x4] + and r1,r1,#0x8 + cmp r1,#0 + bne wait_dll_lock + +#if NORMAL_DEBUG + mov r0, #98 + str r0, [r9] +#endif + /* Prog sdmc refresh period */ + mov r1,#41 + str r1,[r10,#0x24] + + + /* Prog ras and cas delay for bank 0 and bank 1 */ + ldr r1,[r10,#0x104] + add r1, r1, #0x100 + str r1,[r10,#0x104] + + ldr r1,[r10,#0x124] + add r1, r1, #0x100 + str r1,[r10,#0x124] + + + + +#if NORMAL_DEBUG + mov r0, #99 + str r0, [r9] +#endif + + + + ldr r1,[r11] +/** Routine to put the chip in normal Mode + bic r1, r1, #0x7 + orr r1, r1, #0x4 + str r1,[r11] +*/ + ldr r2, =0xfffffff8 + and r1, r1, r2 + orr r1, r1, #0x4 + str r1, [r11] + + +wait_normal_mode: + ldr r1, [r11] + and r1, r1, #0x78 + cmp r1, #0x20 + bne wait_normal_mode + + +#if NORMAL_DEBUG + mov r0, #100 + str r0, [r9] +#endif + + + /* Exit DDR-SDRAM from self-refresh mode */ + ldr r1,[r10, #0x20] + bic r1,r1,#0x04 + str r1,[r10, #0x20] + + + /* Wait for DDR-SDRAM to exit from self-refresh */ +loop_refresh: + ldr r1,[r10,#0x4] + and r1,r1,#0x4 + cmp r1,#0x4 + beq loop_refresh + +#if NORMAL_DEBUG + mov r0, #101 + str r0, [r9] +#endif + + + + mov r0,r0 + mov r0,r0 + mov r0,r0 + mov r0,r0 + +cache_prefetch_end: + mov r0,r0 + mov r0,r0 + mov r0,r0 + mov r0,r0 + + +#if NORMAL_DEBUG + + mov r0, #102 + str r0, [r9] +#endif + + ldmfd sp!,{r0-r12,pc} + + --- /dev/null +++ linux-2.6.20/arch/arm/mach-nomadik/pm.c @@ -0,0 +1,79 @@ +/* + * NOMADIK Power Management Routines + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License. + */ +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +/* + * Debug macros + */ +#define PM_NAME "NMDK_PM" + +#ifndef PM_DEBUG +#define PM_DEBUG 0 +#endif + +#define NMDK_DEBUG PM_DEBUG /* enables/disables nmdk_dbg msgs */ +#define NMDK_DEBUG_PFX PM_NAME /* msg header represents this module */ +#define NMDK_DBG KERN_ERR /* message level */ + +int nomadik_pm_enter(suspend_state_t state) +{ + extern int nomadik_cpu_pm_enter(suspend_state_t state); + nmdk_dbg_ftrace(); + if ( nomadik_cpu_pm_enter(state)) + return -1; + cpu_init(); + nmdk_dbg2("back from wakeup\n"); + return 0; +} + +EXPORT_SYMBOL_GPL(nomadik_pm_enter); + +/* + * Called after processes are frozen, but before we shut down devices. + */ +int nomadik_pm_prepare(suspend_state_t state) +{ + extern int nomadik_cpu_pm_prepare(suspend_state_t state); + + return nomadik_cpu_pm_prepare(state); +} + +EXPORT_SYMBOL_GPL(nomadik_pm_prepare); + +/* + * Called after devices are re-setup, but before processes are thawed. + */ +int nomadik_pm_finish(suspend_state_t state) +{ + return 0; +} + +EXPORT_SYMBOL_GPL(nomadik_pm_finish); + +static struct pm_ops nomadik_pm_ops = { + .prepare = nomadik_pm_prepare, + .enter = nomadik_pm_enter, + .finish = nomadik_pm_finish, +}; + +static int __init nomadik_pm_init(void) +{ + pm_set_ops(&nomadik_pm_ops); + return 0; +} + +device_initcall(nomadik_pm_init); --- /dev/null +++ linux-2.6.20/arch/arm/mach-nomadik/power.c @@ -0,0 +1,1316 @@ +/* + * linux/arch/arm/mach-nomadik/power.c + * + * Copyright (C) STMicroelectronics + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Nomadik Power driver + */ + +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define POWER_NAME "NMDK_POWER" + +#ifndef POWER_DEBUG +#define POWER_DEBUG 0 +#endif + +#define NMDK_DEBUG POWER_DEBUG /* enables/disables nmdk_dbg msgs */ +#define NMDK_DEBUG_PFX POWER_NAME /* msg header represents this module */ +#define NMDK_DBG KERN_ERR /* message level */ + +#ifdef CONFIG_NOMADIK_PM + +#define RTC_LR (0x08) +#define RTC_DR (0x0) +#define RTC_MR (0x04) +#define RTC_IMSC (0x10) +#define RTC_ICR (0x1C) +#define RTT_DR (0x20) +#define RTT_LR (0x24) +#define RTT_CR (0x28) + +#define RTT_CLK (32768) +#define RTT_PER_CNT_NSEC (1000000000/RTT_CLK) +#define MAX_RTT_SLEEP (0x7fffffff/RTT_CLK) + +#define DEFAULT_SLEEP_DURATION (5 ) + +#define DEFAULT_SLEEP_TYPE DEEP_SLEEP + +unsigned int *L2dummyPointer = NULL; + +int g_nomadik_sleep_mode = DEFAULT_SLEEP_TYPE; +EXPORT_SYMBOL(g_nomadik_sleep_mode); +int g_nomadik_sleep_duration = DEFAULT_SLEEP_DURATION; +char *nomadik_sleep_types[2] = { + "softsleep", + "deepsleep" +}; +#endif + +int g_nomadik_voltage = VOLT_1_20; + +#define nomadik_attr(_name) \ +static struct subsys_attribute _name##_attr = { \ + .attr = { \ + .name = __stringify(_name), \ + .mode = 0644, \ + }, \ + .show = _name##_show, \ + .store = _name##_store, \ +} + +#ifdef CONFIG_CPU_FREQ_NOMADIK +/* + * This table is setup for a 19.2 MHz Crystal. + */ +static t_sdmc_config nomadik_sdmc_config[] = { + { /* 19.2 Mhz */ + .sdmc_cr = 0x3 /* sdmc_cr */ , + .sdmc_dyrdcfr = 0x1111 /* Dyn Read Config register : CMD & delay */ , + .sdmc_dyref = + 0x9 /* Dynamic memory refresh timer : Auto Refresh period */ , + .sdmc_gcfr = 0x0, /* SDMC Global Configuration register : Prog little endian */ + .sdmc_dyrp = 0x2, /* Dynamic memory precharge command period : Prog tRP timing */ + .sdmc_dyras = 0x5, /* Dynamic memory precharge period (tRAS) */ + .sdmc_dysrex = 0xf, /* Dynamic memory Self Refresh Exit time (tSREX) */ + .sdmc_dywr = 0x1, /* Dynamic memory write recovery time (tWR,tDPL, tRWL or tRDL) */ + .sdmc_dyrc = 0x9, /* Dynamic memory Active to Active command period= (tRC) */ + .sdmc_dyrfc = 0xe, /* Dynamic mem Autorefresh period & Autorefresh to Active cmd period (tRFC) */ + .sdmc_dyxsr = 0xf, /* tXSR */ + .sdmc_dyrrd = 0x1, /* tRRD */ + .sdmc_dymrd = 0x1, /* tMRD */ + .sdmc_dycdlr = 0x1, /* tCDLR */ + .sdmc_dyrascas0 = 0x204, /* Dynamic memory RAS and CAS delay, chip select 0 */ + .sdmc_dycfg0 = 0x884, /* BRC for CS0 */ + .sdmc_dyrascas1 = 0x204, /* Dynamic memory RAS and CAS delay, chip select 1 */ + .sdmc_dycfg1 = 0x884 /* BRC for CS1 */ + }, + + { /* 100.8 Mhz */ + .sdmc_cr = 0x3 /* sdmc_cr */ , + .sdmc_dyrdcfr = 0x1111 /* Dyn Read Config register : CMD & delay */ , + .sdmc_dyref = + 0x31 /* Dynamic memory refresh timer : Auto Refresh period */ , + .sdmc_gcfr = 0x0, /* SDMC Global Configuration register : Prog little endian */ + .sdmc_dyrp = 0x2, /* Dynamic memory precharge command period : Prog tRP timing */ + .sdmc_dyras = 0x4, /* Dynamic memory precharge period (tRAS) */ + .sdmc_dysrex = 0xb, /* Dynamic memory Self Refresh Exit time (tSREX) */ + .sdmc_dywr = 0x1, /* Dynamic memory write recovery time (tWR,tDPL, tRWL or tRDL) */ + .sdmc_dyrc = 0x8, /* Dynamic memory Active to Active command period= (tRC) */ + .sdmc_dyrfc = 0xa, /* Dynamic mem Autorefresh period & Autorefresh to Active cmd period (tRFC) */ + .sdmc_dyxsr = 0xb, /* tXSR */ + .sdmc_dyrrd = 0x1, /* tRRD */ + .sdmc_dymrd = 0x1, /* tMRD */ + .sdmc_dycdlr = 0x1, /* tCDLR */ + .sdmc_dyrascas0 = 0x304, /* Dynamic memory RAS and CAS delay, chip select 0 */ + .sdmc_dycfg0 = 0x884, /* BRC for CS0 */ + .sdmc_dyrascas1 = 0x304, /* Dynamic memory RAS and CAS delay, chip select 1 */ + .sdmc_dycfg1 = 0x884 /* BRC for CS1 */ + }, + + { /* 201.6 Mhz */ + .sdmc_cr = 0x3 /* sdmc_cr */ , + .sdmc_dyrdcfr = 0x1111 /* Dyn Read Config register : CMD & delay */ , + .sdmc_dyref = + 0x31 /* Dynamic memory refresh timer : Auto Refresh period */ , + .sdmc_gcfr = 0x0, /* SDMC Global Configuration register : Prog little endian */ + .sdmc_dyrp = 0x2, /* Dynamic memory precharge command period : Prog tRP timing */ + .sdmc_dyras = 0x4, /* Dynamic memory precharge period (tRAS) */ + .sdmc_dysrex = 0xb, /* Dynamic memory Self Refresh Exit time (tSREX) */ + .sdmc_dywr = 0x1, /* Dynamic memory write recovery time (tWR,tDPL, tRWL or tRDL) */ + .sdmc_dyrc = 0x8, /* Dynamic memory Active to Active command period= (tRC) */ + .sdmc_dyrfc = 0xa, /* Dynamic mem Autorefresh period & Autorefresh to Active cmd period (tRFC) */ + .sdmc_dyxsr = 0xb, /* tXSR */ + .sdmc_dyrrd = 0x1, /* tRRD */ + .sdmc_dymrd = 0x1, /* tMRD */ + .sdmc_dycdlr = 0x1, /* tCDLR */ + .sdmc_dyrascas0 = 0x304, /* Dynamic memory RAS and CAS delay, chip select 0 */ + .sdmc_dycfg0 = 0x884, /* BRC for CS0 */ + .sdmc_dyrascas1 = 0x304, /* Dynamic memory RAS and CAS delay, chip select 1 */ + .sdmc_dycfg1 = 0x884 /* BRC for CS1 */ + }, + + { /* 264 Mhz */ + .sdmc_cr = 0xf00003 /* sdmc_cr */ , + .sdmc_dyrdcfr = 0x1111 /* Dyn Read Config register : CMD & delay */ , + .sdmc_dyref = + 0x41 /* Dynamic memory refresh timer : Auto Refresh period */ , + .sdmc_gcfr = 0x0, /* SDMC Global Configuration register : Prog little endian */ + .sdmc_dyrp = 0x2, /* Dynamic memory precharge command period : Prog tRP timing */ + .sdmc_dyras = 0x5, /* Dynamic memory precharge period (tRAS) */ + .sdmc_dysrex = 0xf, /* Dynamic memory Self Refresh Exit time (tSREX) */ + .sdmc_dywr = 0x1, /* Dynamic memory write recovery time (tWR,tDPL, tRWL or tRDL) */ + .sdmc_dyrc = 0x9, /* Dynamic memory Active to Active command period= (tRC) */ + .sdmc_dyrfc = 0xe, /* Dynamic mem Autorefresh period & Autorefresh to Active cmd period (tRFC) */ + .sdmc_dyxsr = 0xf, /* tXSR */ + .sdmc_dyrrd = 0x1, /* tRRD */ + .sdmc_dymrd = 0x1, /* tMRD */ + .sdmc_dycdlr = 0x1, /* tCDLR */ + .sdmc_dyrascas0 = 0x304, /* Dynamic memory RAS and CAS delay, chip select 0 */ + .sdmc_dycfg0 = 0x884, /* BRC for CS0 */ + .sdmc_dyrascas1 = 0x304, /* Dynamic memory RAS and CAS delay, chip select 1 */ + .sdmc_dycfg1 = 0x884 /* BRC for CS1 */ + }, + + { /* 302.4 Mhz */ + .sdmc_cr = 0x3 /* sdmc_cr */ , + .sdmc_dyrdcfr = 0x1111 /* Dyn Read Config register : CMD & delay */ , + .sdmc_dyref = + 0x14 /* Dynamic memory refresh timer : Auto Refresh period */ , + .sdmc_gcfr = 0x0, /* SDMC Global Configuration register : Prog little endian */ + .sdmc_dyrp = 0x3, /* Dynamic memory precharge command period : Prog tRP timing */ + .sdmc_dyras = 0x8, /* Dynamic memory precharge period (tRAS) */ + .sdmc_dysrex = 0x1a, /* Dynamic memory Self Refresh Exit time (tSREX) */ + .sdmc_dywr = 0x2, /* Dynamic memory write recovery time (tWR,tDPL, tRWL or tRDL) */ + .sdmc_dyrc = 0xd, /* Dynamic memory Active to Active command period= (tRC) */ + .sdmc_dyrfc = 0x18, /* Dynamic mem Autorefresh period & Autorefresh to Active cmd period (tRFC) */ + .sdmc_dyxsr = 0x1a, /* tXSR */ + .sdmc_dyrrd = 0x2, /* tRRD */ + .sdmc_dymrd = 0x1, /* tMRD */ + .sdmc_dycdlr = 0x1, /* tCDLR */ + .sdmc_dyrascas0 = 0x304, /* Dynamic memory RAS and CAS delay, chip select 0 */ + .sdmc_dycfg0 = 0x884, /* BRC for CS0 */ + .sdmc_dyrascas1 = 0x304, /* Dynamic memory RAS and CAS delay, chip select 1 */ + .sdmc_dycfg1 = 0x884 /* BRC for CS1 */ + }, + /*ADDED NEW CONFIGURATION*/ + { /* 326.4 Mhz */ + .sdmc_cr = 0x3 /* sdmc_cr */ , + .sdmc_dyrdcfr = 0x1111 /* Dyn Read Config register : CMD & delay */ , + .sdmc_dyref = 0x4F, /* Dynamic memory refresh timer : Auto Refresh period */ + .sdmc_gcfr = 0x0, /* SDMC Global Configuration register : Prog little endian */ + .sdmc_dyrp = 0x2, /* Dynamic memory precharge command period : Prog tRP timing */ + .sdmc_dyras = 0x6, /* Dynamic memory precharge period (tRAS) */ + .sdmc_dysrex = 0x13, /* Dynamic memory Self Refresh Exit time (tSREX) */ + .sdmc_dywr = 0x2, /* Dynamic memory write recovery time (tWR,tDPL, tRWL or tRDL) */ + .sdmc_dyrc = 0x9, /* Dynamic memory Active to Active command period= (tRC) */ + .sdmc_dyrfc = 0x0E, /* Dynamic mem Autorefresh period & Autorefresh to Active cmd period (tRFC) */ + .sdmc_dyxsr = 0x13, /* tXSR */ + .sdmc_dyrrd = 0x1, /* tRRD */ + .sdmc_dymrd = 0x1, /* tMRD */ + .sdmc_dycdlr = 0x1, /* tCDLR */ + .sdmc_dyrascas0 = 0x304, /* Dynamic memory RAS and CAS delay, chip select 0 */ + .sdmc_dycfg0 = 0x886, /* BRC for CS0 */ + .sdmc_dyrascas1 = 0x304, /* Dynamic memory RAS and CAS delay, chip select 1 */ + .sdmc_dycfg1 = 0x886 /* BRC for CS1 */ + }, + + { /* 374 Mhz */ + .sdmc_cr = 0x3 /* sdmc_cr */ , + .sdmc_dyrdcfr = 0x1111 /* Dyn Read Config register : CMD & delay */ , + .sdmc_dyref = + 0x14 /* Dynamic memory refresh timer : Auto Refresh period */ , + .sdmc_gcfr = 0x0, /* SDMC Global Configuration register : Prog little endian */ + .sdmc_dyrp = 0x3, /* Dynamic memory precharge command period : Prog tRP timing */ + .sdmc_dyras = 0x8, /* Dynamic memory precharge period (tRAS) */ + .sdmc_dysrex = 0x1a, /* Dynamic memory Self Refresh Exit time (tSREX) */ + .sdmc_dywr = 0x2, /* Dynamic memory write recovery time (tWR,tDPL, tRWL or tRDL) */ + .sdmc_dyrc = 0xd, /* Dynamic memory Active to Active command period= (tRC) */ + .sdmc_dyrfc = 0x18, /* Dynamic mem Autorefresh period & Autorefresh to Active cmd period (tRFC) */ + .sdmc_dyxsr = 0x1a, /* tXSR */ + .sdmc_dyrrd = 0x2, /* tRRD */ + .sdmc_dymrd = 0x1, /* tMRD */ + .sdmc_dycdlr = 0x1, /* tCDLR */ + .sdmc_dyrascas0 = 0x304, /* Dynamic memory RAS and CAS delay, chip select 0 */ + .sdmc_dycfg0 = 0x884, /* BRC for CS0 */ + .sdmc_dyrascas1 = 0x304, /* Dynamic memory RAS and CAS delay, chip select 1 */ + .sdmc_dycfg1 = 0x884 /* BRC for CS1 */ + }, + + { /* 384 Mhz */ + + .sdmc_cr = 0x3 /* sdmc_cr */ , + .sdmc_dyrdcfr = 0x1111 /* Dyn Read Config register : CMD & delay */ , + .sdmc_dyref = + 0x14 /* Dynamic memory refresh timer : Auto Refresh period */ , + .sdmc_gcfr = 0x0, /* SDMC Global Configuration register : Prog little endian */ + .sdmc_dyrp = 0x3, /* Dynamic memory precharge command period : Prog tRP timing */ + .sdmc_dyras = 0x8, /* Dynamic memory precharge period (tRAS) */ + .sdmc_dysrex = 0x1a, /* Dynamic memory Self Refresh Exit time (tSREX) */ + .sdmc_dywr = 0x2, /* Dynamic memory write recovery time (tWR,tDPL, tRWL or tRDL) */ + .sdmc_dyrc = 0xd, /* Dynamic memory Active to Active command period= (tRC) */ + .sdmc_dyrfc = 0x18, /* Dynamic mem Autorefresh period & Autorefresh to Active cmd period (tRFC) */ + .sdmc_dyxsr = 0x1a, /* tXSR */ + .sdmc_dyrrd = 0x2, /* tRRD */ + .sdmc_dymrd = 0x1, /* tMRD */ + .sdmc_dycdlr = 0x1, /* tCDLR */ + .sdmc_dyrascas0 = 0x304, /* Dynamic memory RAS and CAS delay, chip select 0 */ + .sdmc_dycfg0 = 0x884, /* BRC for CS0 */ + .sdmc_dyrascas1 = 0x304, /* Dynamic memory RAS and CAS delay, chip select 1 */ + .sdmc_dycfg1 = 0x884 /* BRC for CS1 */ + }, + + { /* 393 Mhz */ + + .sdmc_cr = 0x3 /* sdmc_cr */ , + .sdmc_dyrdcfr = 0x1111 /* Dyn Read Config register : CMD & delay */ , + .sdmc_dyref = + 0x14 /* Dynamic memory refresh timer : Auto Refresh period */ , + .sdmc_gcfr = 0x0, /* SDMC Global Configuration register : Prog little endian */ + .sdmc_dyrp = 0x3, /* Dynamic memory precharge command period : Prog tRP timing */ + .sdmc_dyras = 0x8, /* Dynamic memory precharge period (tRAS) */ + .sdmc_dysrex = 0x1a, /* Dynamic memory Self Refresh Exit time (tSREX) */ + .sdmc_dywr = 0x2, /* Dynamic memory write recovery time (tWR,tDPL, tRWL or tRDL) */ + .sdmc_dyrc = 0xd, /* Dynamic memory Active to Active command period= (tRC) */ + .sdmc_dyrfc = 0x18, /* Dynamic mem Autorefresh period & Autorefresh to Active cmd period (tRFC) */ + .sdmc_dyxsr = 0x1a, /* tXSR */ + .sdmc_dyrrd = 0x2, /* tRRD */ + .sdmc_dymrd = 0x1, /* tMRD */ + .sdmc_dycdlr = 0x1, /* tCDLR */ + .sdmc_dyrascas0 = 0x304, /* Dynamic memory RAS and CAS delay, chip select 0 */ + .sdmc_dycfg0 = 0x884, /* BRC for CS0 */ + .sdmc_dyrascas1 = 0x304, /* Dynamic memory RAS and CAS delay, chip select 1 */ + .sdmc_dycfg1 = 0x884 /* BRC for CS1 */ + }, + + { /* 451.2 Mhz */ + + .sdmc_cr = 0x3 /* sdmc_cr */ , + .sdmc_dyrdcfr = 0x1111 /* Dyn Read Config register : CMD & delay */ , + .sdmc_dyref = + 0x14 /* Dynamic memory refresh timer : Auto Refresh period */ , + .sdmc_gcfr = 0x0, /* SDMC Global Configuration register : Prog little endian */ + .sdmc_dyrp = 0x3, /* Dynamic memory precharge command period : Prog tRP timing */ + .sdmc_dyras = 0x8, /* Dynamic memory precharge period (tRAS) */ + .sdmc_dysrex = 0x1a, /* Dynamic memory Self Refresh Exit time (tSREX) */ + .sdmc_dywr = 0x2, /* Dynamic memory write recovery time (tWR,tDPL, tRWL or tRDL) */ + .sdmc_dyrc = 0xd, /* Dynamic memory Active to Active command period= (tRC) */ + .sdmc_dyrfc = 0x18, /* Dynamic mem Autorefresh period & Autorefresh to Active cmd period (tRFC) */ + .sdmc_dyxsr = 0x1a, /* tXSR */ + .sdmc_dyrrd = 0x2, /* tRRD */ + .sdmc_dymrd = 0x1, /* tMRD */ + .sdmc_dycdlr = 0x1, /* tCDLR */ + .sdmc_dyrascas0 = 0x304, /* Dynamic memory RAS and CAS delay, chip select 0 */ + .sdmc_dycfg0 = 0x884, /* BRC for CS0 */ + .sdmc_dyrascas1 = 0x304, /* Dynamic memory RAS and CAS delay, chip select 1 */ + .sdmc_dycfg1 = 0x884 /* BRC for CS1 */ + }, + /* SDMC confg. at 489.6 Mhz */ + { /* 489.6 Mhz */ + .sdmc_cr = 0x03, // 0x00F00003, /* sdmc_cr */ + .sdmc_dyrdcfr = 0x1111, /* Dyn Read Config register : CMD & delay */ + .sdmc_dyref = 0x4F, /* Dynamic memory refresh timer : Auto Refresh period */ + .sdmc_gcfr = 0x0, /* SDMC Global Configuration register : Prog little endian */ + .sdmc_dyrp = 0x2, /* Dynamic memory precharge command period : Prog tRP timing */ + .sdmc_dyras = 0x6, /* Dynamic memory precharge period (tRAS) */ + .sdmc_dysrex =0x13, /* Dynamic memory Self Refresh Exit time (tSREX) */ + .sdmc_dywr = 0x2, /* Dynamic memory write recovery time (tWR,tDPL, tRWL or tRDL) */ + .sdmc_dyrc = 0x9, /* Dynamic memory Active to Active command period= (tRC) */ + .sdmc_dyrfc = 0x0E, /* Dynamic mem Autorefresh period & Autorefresh to Active cmd period (tRFC)*/ + .sdmc_dyxsr = 0x13, /* tXSR */ + .sdmc_dyrrd = 0x1, /* tRRD */ + .sdmc_dymrd = 0x1, /* tMRD */ + .sdmc_dycdlr = 0x1, /* tCDLR */ + .sdmc_dyrascas0 = 0x304, /* Dynamic memory RAS and CAS delay, chip select 0 */ + .sdmc_dycfg0 = 0x884, /* BRC for CS0 */ + .sdmc_dyrascas1 = 0x304, /* Dynamic memory RAS and CAS delay, chip select 1 */ + .sdmc_dycfg1 = 0x884 /* BRC for CS1 */ + }, + + + +}; + +/*freq (CLK) = 19.2 * (pll1mul+2)/ 2^pll1pdiv */ +static t_freq_config nomadik_freq_config[] = { + /* core freq in khz pll1pdiv pll1nmul clkdiv voltage */ + {19200, 4, 53, 0, VOLT_1_20}, + {100800, 3, 40, 0, VOLT_1_26}, + {201600, 2, 40, 1, VOLT_1_20}, + {264000, 2, 53, 1, VOLT_1_26}, + {302400, 2, 61, 2, VOLT_1_20}, + {326400, 1, 32, 1, VOLT_1_38}, /*from 1.36->1.38*/ + {374000, 1, 37, 2, VOLT_1_34}, + {384000, 1, 38, 2, VOLT_1_34}, + {393600, 1, 39, 2, VOLT_1_34}, /*with 1.45 scling reboots the system*/ + {451200, 1, 45, 2, VOLT_1_34}, + {489600, 1, 49, 2, VOLT_1_45}, +}; + +#define NR_FREQS (sizeof(nomadik_freq_config)/ sizeof(nomadik_freq_config[0])) + +#endif + +static t_volt_config nomadik_volt_config[] = { + /* voltage value value in milli volt */ + {VOLT_1_20, VOLT_1_20_MV}, + {VOLT_1_22, VOLT_1_22_MV}, + {VOLT_1_26, VOLT_1_26_MV}, + {VOLT_1_28, VOLT_1_28_MV}, + {VOLT_1_34, VOLT_1_34_MV}, + {VOLT_1_36, VOLT_1_36_MV}, /*for 326*/ + {VOLT_1_38, VOLT_1_38_MV}, + {VOLT_1_4, VOLT_1_4_MV}, + {VOLT_1_45, VOLT_1_45_MV}, +}; + +struct nomadik_clock_gating { + char *name; + int id; +}; +static struct nomadik_clock_gating nomadik_clock_gating_pcken[]= { + + {"HCLK_DMA0",0}, // 0 bit position of PCKEN0 + {"HCLK_SMC",1}, + {"HCLK_SDRAM",2}, + {"HCLK_DMA1",3}, + {"HCLK_CLCD",4}, + {"PCLK_IRDA",5}, + {"PCLK_SSP",6}, + {"HCLK_UART0",7}, + {"PCLK_SDI",8}, + {"PCLK_I2C0",9}, + {"PCLK_I2C1",10}, + {"PCLK_UART1",11}, + {"PCLK_MSP0",12}, + {"HCLK_USB",13}, + {"HCLK_DIF",14}, + {"HCLK_SAA",15}, + {"HCLK_SVA",16}, + {"PCLK_SSI",17}, + {"PCLK_XTI",18}, + {"PCLK_UART2",19}, + {"PCLK_MSP1",20}, + {"PCLK_MSP2",21}, + {"PCLK_OWM",22}, + {"HCLK_HPI",23}, + {"PCLK_SKE",24}, + {"PCLK_HSEM",25}, + {"HCLK_3D",26}, + {"HCLK_HASH",27}, + {"HCLK_CRYP",28}, + {"PCLK_MSHC",29}, + {"HCLK_USBM",30}, + {"HCLK_RNG",31}, //31 bit position + + {"CLK_SDRAM",2+32}, //2 bit position of PCKEN1 + {"CLCD_CLK",4+32}, + {"IRDA_CLK",5+32} , + {"SSP_ICLK",6+32}, + {"UART0_CLK",7+32}, + {"SDI_CLK",8+32}, + {"I2C0_CLK",9+32}, + {"I2C1_CLK",10+32}, + {"UART1_CLK",11+32}, + {"MSP_CLK0",12+32}, + {"USB_CLK",13+32}, + {"DIF_CLK",14+32}, + {"IPI2_CCLK",15+32}, + {"IPBM_CCLK",16+32}, + {"SSI_CLKRX",17+32}, + {"SSI_CLKTX",18+32}, + {"UART2_CLK",19+32}, + {"MSP_CLK1",20+32}, + {"MSP_CLK2",21+32}, + {"OWM_CLK",22+32}, + {"SKE_CLK",24+32}, + {"3D_CLK",26+32}, + {"MSH_CCLK",29+32}, + {"USBM_CLK",30+32}, + {"RNG_CCLK",31+32} + +}; +#define NR_VOLTS (sizeof(nomadik_volt_config)/ sizeof(nomadik_volt_config[0])) + +/*this assumes cpu0 - FIXME*/ +u32 nomadik_busfreq_get(char *buf) +{ + u32 src_base; + u32 hclkdiv; + char *p = buf; + unsigned long flags; + unsigned int cur_freq; + cur_freq = cpufreq_get(0); + src_base = (u32) IO_ADDRESS(NOMADIK_SRC_BASE); + hclkdiv = ((readl(src_base)& 0xf000) >> 13)&3; + switch(hclkdiv) { + case 0: + p += sprintf(p, "bus frequency:%d\n",cur_freq); + break; + case 1: + p += sprintf(p, "bus frequency: %d\n",cur_freq/2); + break; + case 2: + p += sprintf(p, "bus frequency: %d\n",cur_freq/3); + break; + case 3: + p += sprintf(p, "bus frequency:%d\n",cur_freq/4); + break; + default: + break; + } + return p - buf; +} + +static u32 nomadik_volt_get(unsigned int value) +{ + int i; + for (i = 0; i < NR_VOLTS; i++) { + if (nomadik_volt_config[i].value == value) + return nomadik_volt_config[i].volt_mv; + } + return nomadik_volt_config[NR_VOLTS].volt_mv; +} + +static u32 nomadik_volt_put(unsigned int value) +{ + unsigned int i; + + for (i = 0; i < NR_VOLTS; i++) { + if (nomadik_volt_config[i].volt_mv >= value) + return nomadik_volt_config[i].value; + } + return nomadik_volt_config[NR_VOLTS - 1].value; +} + +#ifdef CONFIG_CPU_FREQ_NOMADIK + +unsigned int nomadik_freq_to_idx(unsigned int freq) +{ + unsigned int i; + + for (i = 0; i < NR_FREQS; i++) + if (nomadik_freq_config[i].freq >= freq) + return i; + + return NR_FREQS - 1; +} + +unsigned int nomadik_freq_to_voltage(unsigned int freq) +{ + unsigned int i; + + for (i = 0; i < NR_FREQS; i++) + if (nomadik_freq_config[i].freq >= freq) + return nomadik_freq_config[i].voltage; + + return nomadik_freq_config[NR_FREQS - 1].voltage; +} + +unsigned int nomadik_idx_to_freq(unsigned int idx) +{ + return nomadik_freq_config[idx].freq; +} + +void store_freq_sdmc_par(u32 backup_sram_start, u32 sdram_base, + unsigned int freq_index) +{ + + t_backup_data *backup_data; + + backup_data = ((t_backup_data *) backup_sram_start); + + nmdk_dbg2("backup_sram_start-%X , sdram_base - %X\n", backup_sram_start, + sdram_base); + + backup_data->magic = BACKUP_MAGIC_NUMBER_DFS; + + /* Enable SDMC */ + backup_data->reg_addr[0] = sdram_base; + backup_data->data[0] = nomadik_sdmc_config[freq_index].sdmc_cr; + backup_data->action[0] = ACTION_WRITE; + + /* Program the command and delay strategy */ + backup_data->reg_addr[1] = sdram_base + 0x028; + backup_data->data[1] = nomadik_sdmc_config[freq_index].sdmc_dyrdcfr; + backup_data->action[1] = ACTION_WRITE; + + /* Prog the Auto-refresh period = 7.8µs @ SDRAM Clock = 132 MHz */ + backup_data->reg_addr[2] = sdram_base + 0x024; + backup_data->data[2] = nomadik_sdmc_config[freq_index].sdmc_dyref; + backup_data->action[2] = ACTION_WRITE; + + /* program little endian */ + backup_data->reg_addr[3] = sdram_base + 0x008; + backup_data->data[3] = nomadik_sdmc_config[freq_index].sdmc_gcfr; + backup_data->action[3] = ACTION_WRITE; + + /* Prog tRP timing */ + backup_data->reg_addr[4] = sdram_base + 0x030; + backup_data->data[4] = nomadik_sdmc_config[freq_index].sdmc_dyrp; + backup_data->action[4] = ACTION_WRITE; + + /* Prog tRAS timing */ + backup_data->reg_addr[5] = sdram_base + 0x034; + backup_data->data[5] = nomadik_sdmc_config[freq_index].sdmc_dyras; + backup_data->action[5] = ACTION_WRITE; + + /* Prog tSREX timing */ + backup_data->reg_addr[6] = sdram_base + 0x038; + backup_data->data[6] = nomadik_sdmc_config[freq_index].sdmc_dysrex; + backup_data->action[6] = ACTION_WRITE; + + /* Prog tWR timing */ + backup_data->reg_addr[7] = sdram_base + 0x044; + backup_data->data[7] = nomadik_sdmc_config[freq_index].sdmc_dywr; + backup_data->action[7] = ACTION_WRITE; + + /* Prog tRC timing */ + backup_data->reg_addr[8] = sdram_base + 0x048; + backup_data->data[8] = nomadik_sdmc_config[freq_index].sdmc_dyrc; + backup_data->action[8] = ACTION_WRITE; + + /* Prog tRFC timing */ + backup_data->reg_addr[9] = sdram_base + 0x04C; + backup_data->data[9] = nomadik_sdmc_config[freq_index].sdmc_dyrfc; + backup_data->action[9] = ACTION_WRITE; + + /* Prog tXSR timing */ + backup_data->reg_addr[10] = sdram_base + 0x050; + backup_data->data[10] = nomadik_sdmc_config[freq_index].sdmc_dyxsr; + backup_data->action[10] = ACTION_WRITE; + + /* Prog tRRD timing */ + backup_data->reg_addr[11] = sdram_base + 0x054; + backup_data->data[11] = nomadik_sdmc_config[freq_index].sdmc_dyrrd; + backup_data->action[11] = ACTION_WRITE; + + /* Prog tMRD timing */ + backup_data->reg_addr[12] = sdram_base + 0x058; + backup_data->data[12] = nomadik_sdmc_config[freq_index].sdmc_dymrd; + backup_data->action[12] = ACTION_WRITE; + + /* Prog tCDLR timing */ + backup_data->reg_addr[13] = sdram_base + 0x05C; + backup_data->data[13] = nomadik_sdmc_config[freq_index].sdmc_dycdlr; + backup_data->action[13] = ACTION_WRITE; + + /* Prog RAS and CAS for Chip Select 0 */ + backup_data->reg_addr[14] = sdram_base + 0x104; + backup_data->data[14] = nomadik_sdmc_config[freq_index].sdmc_dyrascas0; + backup_data->action[14] = ACTION_WRITE; + + /* Prog config register in BRC for Chip Select 0 */ + backup_data->reg_addr[15] = sdram_base + 0x100; + backup_data->data[15] = nomadik_sdmc_config[freq_index].sdmc_dycfg0; + backup_data->action[15] = ACTION_WRITE; + + backup_data->reg_addr[16] = sdram_base + 0x124; + backup_data->data[16] = nomadik_sdmc_config[freq_index].sdmc_dyrascas1; + backup_data->action[16] = ACTION_WRITE; + + backup_data->reg_addr[17] = sdram_base + 0x120; + backup_data->data[17] = nomadik_sdmc_config[freq_index].sdmc_dycfg1; + backup_data->action[17] = ACTION_WRITE; + + backup_data->Size = 18; + +} + +static u32 clcd_conf; +static u32 clcd_base = (u32) IO_ADDRESS(NOMADIK_CLCDC_BASE); + +#define RIS_VCMPRIS 8 +int nomadik_halt_masters(void) +{ + volatile u32 clcd_stat; + +#if 0 + u32 config; + u32 src_base; + u32 src_enable; + src_base = (u32) IO_ADDRESS(NOMADIK_SRC_BASE); + src_enable = (1 << 16) | (1 << 15); + writel(src_enable, src_base + 0x28); +#endif + + clcd_conf = readl(clcd_base + CLCD_CNTL); + if (clcd_conf) { + //config = clcd_conf | CNTL_LCDVCOMP(0x3); + // config = clcd_conf | CNTL_LCDVCOMP(0x0); + // writel(config, clcd_base + CLCD_CNTL); + + clcd_stat = readl(clcd_base + CLCD_STAT); + writel(clcd_stat & ~RIS_VCMPRIS, clcd_base + CLCD_STAT); + do { + clcd_stat = readl(clcd_base + CLCD_STAT); + } while (!(clcd_stat & RIS_VCMPRIS)); + + // writel(0x1e, clcd_base + 0x20); + writel(clcd_conf & ~CNTL_LCDEN, clcd_base + CLCD_CNTL); + } + + return 0; +} + +int nomadik_resume_masters(void) +{ + u32 src_base; + + src_base = (u32) IO_ADDRESS(NOMADIK_SRC_BASE); + + if (clcd_conf) { + // writel(clcd_conf, clcd_base + CLCD_CNTL); + if ( ( readl(src_base) & 0x78 ) == 0x10 ) + { + writel(0x027F1804, clcd_base+8); + } + else + { + writel(CONFIG_FB_NOMADIK_PANEL_TIM2VAL, clcd_base+8); + } + writel(clcd_conf | CNTL_LCDEN, clcd_base + CLCD_CNTL); + writel(0x1e, clcd_base + CLCD_STAT); + } + +#if 0 + src_enable = (1 << 16) | (1 << 15); + writel(src_enable, src_base + 0x24); +#endif + return 0; +} +u32 nomadik_setsys_freq(u32 freq_idx) +{ + + u32 sdram_base; + u32 backup_sram_start; + u32 src_base; + unsigned long flags; + + sdram_base = (u32) IO_ADDRESS(NOMADIK_SDRAMC_BASE); + src_base = (u32) IO_ADDRESS(NOMADIK_SRC_BASE); + backup_sram_start = (u32) ioremap(NOMADIK_BACKUP_RAM, BACKUP_RAM_SIZE); + + nmdk_dbg2("nomadik_setsys_freq is called with %d\n", freq_idx); + nmdk_dbg2("\n sdram_base: %x\n", sdram_base); + nmdk_dbg2("\n backup_sram_start: %x\n", backup_sram_start); + + store_freq_sdmc_par(backup_sram_start, sdram_base, freq_idx); + + local_irq_save(flags); +// nomadik_halt_memdma(); + nomadik_halt_masters(); + if ( freq_idx == 0 ) + { + nomadik_slow_mode(); + } + else + { + dfs(nomadik_freq_config[freq_idx].pll1_pdiv, + nomadik_freq_config[freq_idx].pll1_nmul, + nomadik_freq_config[freq_idx].hclkdiv, backup_sram_start); + } + + nmdk_dbg2("pll1_pdiv = 0x%x pll1_nmul = 0x%x hclkdiv = 0x%x\n", + nomadik_freq_config[freq_idx].pll1_pdiv, + nomadik_freq_config[freq_idx].pll1_nmul, + nomadik_freq_config[freq_idx].hclkdiv); + + + nomadik_resume_masters(); +// nomadik_resume_memdma(); + + local_irq_restore(flags); + + iounmap((void *)backup_sram_start); + nmdk_dbg2("Control Back from the function %s\n", __FUNCTION__); + return 0; +} +#endif + +#ifdef CONFIG_NOMADIK_PM + +#define MTU0_LR 0x10 +#define MTU0_CTRL 0x18 +#define MTU0_VAL 0x14 +#define MTU0_IMSC 0x0 +#define MTU0_BGLR 0x1c +#define MTU0_RIS 0x4 + +static struct timespec rtc_delta; +static u32 mtu0_base = (u32) IO_ADDRESS(NOMADIK_MTU0_BASE); +static u32 nomadik_mtu0_val, nomadik_mtu0_ctrl, nomadik_mtu0_intr_cnt; +static int nomadik_rtc_afterwakeup(void) +{ + void __iomem *rtc_base; + struct timespec rtc; + u32 dr, sec, nsec; + + rtc_base = (void __iomem *)IO_ADDRESS(NOMADIK_RTC_BASE); + + if (g_nomadik_sleep_duration >= MAX_RTT_SLEEP) { + mdelay(1010); + writel(readl(mtu0_base + MTU0_IMSC) | 1, mtu0_base); + writel(nomadik_mtu0_ctrl, mtu0_base + MTU0_CTRL); + writel(nomadik_mtu0_val, mtu0_base + MTU0_LR); + writel(24000, mtu0_base + MTU0_BGLR); + + rtc.tv_sec = readl(rtc_base + RTC_DR); + rtc.tv_nsec = 0; + restore_time_delta(&rtc_delta, &rtc); + /* Clear rtc intr src */ + writel(1, rtc_base + RTC_ICR); + } else { + writel(readl(mtu0_base + MTU0_IMSC) | 1, mtu0_base); + writel(nomadik_mtu0_ctrl, mtu0_base + MTU0_CTRL); + writel(nomadik_mtu0_val, mtu0_base + MTU0_LR); + writel(24000, mtu0_base + MTU0_BGLR); + dr = readl(rtc_base + RTT_DR); + dr = g_nomadik_sleep_duration * RTT_CLK - dr; + dr = dr + nomadik_mtu0_intr_cnt * (RTT_CLK/100); + + sec = dr / RTT_CLK; + dr = dr - sec * RTT_CLK; + nsec = dr * RTT_PER_CNT_NSEC; + rtc.tv_sec = sec; + rtc.tv_nsec = nsec; + + restore_time_delta(&rtc_delta, &rtc); + /* Clear rtt intr src */ + writel(2, rtc_base + RTC_ICR); + } + + /* Disable RTC intr */ + writel(0, rtc_base + RTC_IMSC); + + return 0; +} + +static int nomadik_rtc_wakeup(void) +{ + void __iomem *rtc_base; + struct timespec rtc; + u32 rtc_val; + + rtc_base = (void __iomem *)IO_ADDRESS(NOMADIK_RTC_BASE); + + if (g_nomadik_sleep_duration >= MAX_RTT_SLEEP) { + writel(1, rtc_base + RTC_ICR); + rtc_val = readl(rtc_base + RTC_DR); + rtc.tv_sec = rtc_val; + rtc.tv_nsec = 0; + save_time_delta(&rtc_delta, &rtc); + writel(rtc_val + g_nomadik_sleep_duration + 1, + rtc_base + RTC_MR); + nomadik_mtu0_val = readl(mtu0_base + MTU0_VAL); + nomadik_mtu0_ctrl = readl(mtu0_base + MTU0_CTRL); + /* Enable RTC intr */ + writel(1, rtc_base + RTC_IMSC); + udelay(50); + } else { + if ( readl(mtu0_base + MTU0_RIS) & 1 ) + { + nomadik_mtu0_intr_cnt = 1; + } + else + { + nomadik_mtu0_intr_cnt = 0; + } + + writel(2, rtc_base + RTC_ICR); + writel(1, rtc_base + RTT_CR); + udelay(100); + nomadik_mtu0_val = readl(mtu0_base + MTU0_VAL); + nomadik_mtu0_ctrl = readl(mtu0_base + MTU0_CTRL); + writel(RTT_CLK * g_nomadik_sleep_duration, rtc_base + RTT_LR); + rtc.tv_sec = 0; + rtc.tv_nsec = 0; + save_time_delta(&rtc_delta, &rtc); + /* Enable RTT intr */ + writel(2, rtc_base + RTC_IMSC); + } + return 0; +} + +extern void nomadik_sdmc_prio(void); + +extern void l210_inv_all(void); +int nomadik_cpu_pm_enter(suspend_state_t state) +{ + int reason; + volatile u32 l2_acr; + + nomadik_rtc_wakeup(); + state = g_nomadik_sleep_mode; + if (state == SOFT_SLEEP) + nomadik_halt_masters(); +#ifdef CONFIG_L2CACHE_ENABLE + if (state == DEEP_SLEEP) + l2_acr = readl(IO_ADDRESS(NOMADIK_L2CC_BASE+0x104)); +#endif + if (nomadik_sleep(state, &reason)) + return -1; + if (state == SOFT_SLEEP) + nomadik_resume_masters(); + else + nomadik_sdmc_prio(); + nomadik_rtc_afterwakeup(); + + nmdk_dbg2("Come out of state %s\n", nomadik_sleep_types[state]); +#ifdef CONFIG_L2CACHE_ENABLE + if (state == DEEP_SLEEP) + { + writel(l2_acr,IO_ADDRESS(NOMADIK_L2CC_BASE+0x104)); + l210_inv_all(); + writel(1,IO_ADDRESS(NOMADIK_L2CC_BASE+0x100)); + } +#endif + return 0; +} + +int nomadik_cpu_pm_prepare(suspend_state_t state) +{ + return 0; +} + +static int power_wakeup_callback_platform_en(struct device *dev, void *data) +{ + struct platform_device *pdev = to_platform_device(dev); + if (device_may_wakeup(dev)) { + enable_irq_wake(platform_get_irq(pdev, 0)); + } + return 0; +} + +static int power_wakeup_callback_platform_dis(struct device *dev, void *data) +{ + struct platform_device *pdev = to_platform_device(dev); + if (device_may_wakeup(dev)) { + disable_irq_wake(platform_get_irq(pdev, 0)); + } + return 0; +} + +#define to_amba_device(d) container_of(d, struct amba_device, dev) +static int power_wakeup_callback_amba_en(struct device *dev, void *data) +{ + struct amba_device *amba_dev = to_amba_device(dev); + if (device_may_wakeup(dev)) { + if (amba_dev->irq[1] != NO_IRQ) + enable_irq_wake(amba_dev->irq[1]); + } + return 0; +} + +static int power_wakeup_callback_amba_dis(struct device *dev, void *data) +{ + struct amba_device *amba_dev = to_amba_device(dev); + if (device_may_wakeup(dev)) { + if (amba_dev->irq[1] != NO_IRQ) + disable_irq_wake(amba_dev->irq[1]); + } + return 0; +} + +extern struct bus_type *amba_bustype; +void nomadik_wakeup_enable() +{ + bus_for_each_dev(&platform_bus_type, NULL, NULL, + power_wakeup_callback_platform_en); + bus_for_each_dev(amba_bustype, NULL, NULL, power_wakeup_callback_amba_en); + +} + +void nomadik_wakeup_disable() +{ + + bus_for_each_dev(&platform_bus_type, NULL, NULL, + power_wakeup_callback_platform_dis); + bus_for_each_dev(amba_bustype, NULL, NULL, power_wakeup_callback_amba_dis); +} + +#endif + +decl_subsys(nomadik, NULL, NULL); + +#ifdef CONFIG_NOMADIK_PM + +static ssize_t sleep_duration_show(struct subsystem *subsys, char *buf) +{ + char *s = buf; + + s += sprintf(s, "%d (seconds)\n", g_nomadik_sleep_duration); + + return (s - buf); +} + +static ssize_t sleep_duration_store(struct subsystem *subsys, const char *buf, + size_t n) +{ + int error = 0; + + if (*buf) { + error = sscanf(buf, "%d", &g_nomadik_sleep_duration); + if (error == 1) + return n; + } + return -EINVAL; +} + +static ssize_t sleep_type_show(struct subsystem *subsys, char *buf) +{ + char *s = buf; + + s += sprintf(s, "%s\n", nomadik_sleep_types[g_nomadik_sleep_mode]); + return (s - buf); +} + +static ssize_t sleep_type_store(struct subsystem *subsys, const char *buf, + size_t n) +{ + int mode = 0; + char **s; + char *p; + int error = 0; + int len; + + p = memchr(buf, '\n', n); + len = p ? p - buf : n; + + for (s = &nomadik_sleep_types[mode]; mode < 2; s++, mode++) { + if (*s && !strncmp(buf, *s, len)) + break; + } + if (*s) { + g_nomadik_sleep_mode = mode; + } else + error = -EINVAL; + return error ? error : n; +} + +static ssize_t softsleep_enable_show(struct subsystem *subsys, char *buf) +{ + char *s = buf; + + s += sprintf(s, "%d\n", 0); + return (s - buf); +} + +static ssize_t softsleep_enable_store(struct subsystem *subsys, const char *buf, + size_t n) +{ + unsigned long flags; + unsigned int val; + int reason; + int error = 0; + + + if (*buf) { + error = sscanf(buf, "%u", &val); + if (error == 1) { + if (val > 0) { + local_irq_save(flags); + nomadik_rtc_wakeup(); + nomadik_sleep(SOFT_SLEEP, &reason); + nomadik_rtc_afterwakeup(); + local_irq_restore(flags); + } + return n; + } + } + return -EINVAL; +} + +static ssize_t slowmode_enable_show(struct subsystem *subsys, char *buf) +{ + char *s = buf; + + s += sprintf(s, "%d\n", 0); + return (s - buf); +} + +static ssize_t slowmode_enable_store(struct subsystem *subsys, const char *buf, + size_t n) +{ + unsigned long flags; + unsigned int val; + int error = 0; + + if (*buf) { + error = sscanf(buf, "%u", &val); + if (error == 1) { + if (val > 0) { + local_irq_save(flags); + // nomadik_halt_memdma(); + nomadik_halt_masters(); + nomadik_slow_mode(); + nomadik_resume_masters(); + // nomadik_resume_memdma(); + local_irq_restore(flags); + } + else { + local_irq_save(flags); + // nomadik_halt_memdma(); + nomadik_halt_masters(); + nomadik_normal_mode(); + nomadik_resume_masters(); + // nomadik_resume_memdma(); + local_irq_restore(flags); + + } + return n; + } + } + return -EINVAL; +} + +nomadik_attr(slowmode_enable); +nomadik_attr(softsleep_enable); +nomadik_attr(sleep_duration); +nomadik_attr(sleep_type); + +#endif + +static ssize_t current_voltage_show(struct subsystem *subsys, char *buf) +{ + char *s = buf; + + s += sprintf(s, "%d (in Milli Volts)\n", + nomadik_volt_get(g_nomadik_voltage)); + return (s - buf); +} + +static ssize_t current_voltage_store(struct subsystem *subsys, const char *buf, + size_t n) +{ + int error = 0; + int result; + u32 mv; + u32 new_volt; + + if (*buf) { + error = sscanf(buf, "%u", &mv); + new_volt = nomadik_volt_put(mv); + result = + nomadik_i2c_write_register(I2C_TOUAREG_CLIENT, + (char *)&new_volt, 0x1E, 1); + if (unlikely(result)) { + nmdk_error("i2c write error with ret = %d\n", result); + return -EINVAL; + + } else + nmdk_dbg2("i2c write vcore_data = 0x%x\n", new_volt); + + g_nomadik_voltage = new_volt; + + if (error == 1) + return n; + } + return -EINVAL; +} + +nomadik_attr(current_voltage); +#define SRC_CLOCK_PKEN0 32 + +static int reserved_bits_pcken1[]={0,1,3,23,25,27,28}; + +inline int nomadik_clock_enable(u32 clock_name) +{ + int i; + unsigned long flags; + u32 src_base = (u32) IO_ADDRESS(NOMADIK_SRC_BASE); + + if(clock_name <0 || clock_name >63) { + printk("Invalid clock ID\n"); + return -EINVAL; + } + local_irq_save(flags); + + if(clock_name 63) { + printk("Invalid clock ID\n"); + return -EINVAL; + } + local_irq_save(flags); + if(clock_name +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define RTC_NAME "RTC" + +#ifndef RTC_DEBUG +#define RTC_DEBUG 0 +#endif + +#define NMDK_DEBUG RTC_DEBUG /* enables/disables nmdk_dbg msgs */ +#define NMDK_DEBUG_PFX RTC_NAME /* msg header represents this module */ +#define NMDK_DBG KERN_ERR /* message level */ + +#define RTC_DR (0x00) +#define RTC_MR (0x04) +#define RTC_LR (0x08) +#define RTC_TCR (0x0C) +#define RTC_IMSC (0x10) +#define RTC_RIS (0x14) +#define RTC_MIS (0x18) +#define RTC_ICR (0x1C) +#define RTT_DR (0x20) +#define RTT_LR (0x24) +#define RTT_CR (0x28) + +/*bits defination of RTC registers*/ +#define RTTEN 0x0002 +#define RTTIMSC 0x0002 +#define RTCIMSC 0x0001 +#define KHZ32 32768 + +extern int (*set_rtc) (void); + +static void __iomem *rtc_base; + +/** + * nomadik_rtc_set - Sets the rtc from system time + * + */ +static int nomadik_rtc_set(void) +{ + nmdk_dbg_ftrace(); + writel(xtime.tv_sec, rtc_base + RTC_LR); + return 0; +} + +/** + * nomadik_rtc_read_alarm - reads alarm time from rtc registers + * @alrm: alarm data sructure + * + */ +static int nomadik_rtc_read_alarm(struct rtc_wkalrm *alrm) +{ + nmdk_dbg_ftrace(); + rtc_time_to_tm(readl(rtc_base + RTC_MR), &alrm->time); + return 0; +} + +/** + * nomadik_rtc_set_alarm - sets rtc alarm registers using provided value + * @alrm: alarm data sructure + * + */ +static inline int nomadik_rtc_set_alarm(struct rtc_wkalrm *alrm) +{ + unsigned long time; + int ret; + + nmdk_dbg_ftrace(); + /* + * At the moment, we can only deal with non-wildcarded alarm times. + */ + ret = rtc_valid_tm(&alrm->time); + if (ret == 0) { + rtc_tm_to_time(&alrm->time, &time); + writel(time, rtc_base + RTC_MR); + } + return ret; +} + +/** + * nomadik_rtc_read_time - reads rtc time from rtc registers + * @tm: time data sructure + * + */ +static int nomadik_rtc_read_time(struct rtc_time *tm) +{ + nmdk_dbg_ftrace(); + rtc_time_to_tm(readl(rtc_base + RTC_DR), tm); + return 0; +} + +/** + * nomadik_rtc_set_time - sets rtc time registers using provided value + * @tm: time data sructure + * + * Set the RTC time. Unfortunately, we can't accurately set + * the point at which the counter updates. + * + * Also, since RTC_LR is transferred to RTC_TCR on next rising + * edge of the 1Hz clock, we must write the time one second + * in advance. + */ +static inline int nomadik_rtc_set_time(struct rtc_time *tm) +{ + unsigned long time; + int ret; + + nmdk_dbg_ftrace(); + ret = rtc_tm_to_time(tm, &time); + if (ret == 0) + writel(time + 1, rtc_base + RTC_LR); + + return ret; +} + +/** + * nomadik_rtc_ioctl - supports possible RTC ioctls + * @cmd: ioctl to be processed + * + */ +static int nomadik_rtc_ioctl(unsigned int cmd, unsigned long arg) +{ + nmdk_dbg_ftrace(); + switch (cmd) { + case RTC_AIE_ON: /*Make Alarm Interrupt on */ + writel(readl(rtc_base + RTC_IMSC) | RTCIMSC, + rtc_base + RTC_IMSC); + return (0); + case RTC_AIE_OFF: /*Make Alarm Interrupt off */ + writel(readl(rtc_base + RTC_IMSC) & (~RTCIMSC), + rtc_base + RTC_IMSC); + return (0); + case RTC_PIE_ON: /*Make Periodic (RTT) Interrupt on */ + writel(readl(rtc_base + RTC_IMSC) | RTTIMSC, + rtc_base + RTC_IMSC); + return (0); + case RTC_PIE_OFF: /*Make Periodic (RTT) Interrupt off */ + writel(readl(rtc_base + RTC_IMSC) & (~RTTIMSC), + rtc_base + RTC_IMSC); + return (0); + case RTC_IRQP_READ: /* Read the periodic IRQ rate. */ + { + return put_user(KHZ32 / readl(rtc_base + RTT_LR), + (unsigned long __user *)arg); + } + case RTC_IRQP_SET: + { + int tmp = 0; + + /* + * The max we can do is 8192Hz. + */ + if ((arg < 2) || (arg > 8192)) + return -EINVAL; + + while (arg > (1 << tmp)) + tmp++; + + /* + * Check that the input was really a power of 2. + */ + if (arg != (1 << tmp)) + return -EINVAL; + + writel(0, rtc_base + RTT_CR); + writel(KHZ32 / arg, rtc_base + RTT_LR); + return 0; + } + default: + return -EINVAL; + }; +} + +static struct rtc_ops rtc_ops = { + .owner = THIS_MODULE, + .read_time = nomadik_rtc_read_time, + .set_time = nomadik_rtc_set_time, + .read_alarm = nomadik_rtc_read_alarm, + .set_alarm = nomadik_rtc_set_alarm, + .ioctl = nomadik_rtc_ioctl, +}; + +/** + * nomadik_rtc_interrupt - RTC interrupt handler + * + * this handler willbe called in both the cases i.e. alarm hit or RTT + * overflow + */ +static irqreturn_t nomadik_rtc_interrupt(int irq, void *dev_id) +{ + unsigned long event; + + nmdk_dbg2("RTC/RTT int"); + event = readl(rtc_base + RTC_RIS) & 0x03; + event |= readl(rtc_base + RTC_MIS) & 0x03; + writel(event, rtc_base + RTC_ICR); + rtc_update(irq, event); + return IRQ_HANDLED; +} + +static int nomadik_rtc_probe(struct amba_device *dev, void *id) +{ + int ret; + + nmdk_dbg_ftrace(); + if (rtc_base) + return -EBUSY; + + ret = amba_request_regions(dev, NULL); + if (ret) + goto out; + + rtc_base = (void __iomem *)IO_ADDRESS(dev->res.start); + if (!rtc_base) { + ret = -ENOMEM; + goto res_out; + } + + writel(0, rtc_base + RTC_LR); + writel(0, rtc_base + RTC_IMSC); + writel(0xc007fff, rtc_base + RTC_TCR); + writel(KHZ32, rtc_base + RTT_LR); + writel(0, rtc_base + RTT_CR); + + xtime.tv_sec = readl(rtc_base + RTC_DR); + + ret = request_irq(dev->irq[0], nomadik_rtc_interrupt, 0, "rtc", dev); + if (ret) + goto map_out; + + ret = register_rtc(&rtc_ops); + if (ret) + goto irq_out; + + set_rtc = nomadik_rtc_set; + nmdk_info("Module initialized Ver(" RTC_VER ")"); + writel(3, rtc_base + RTC_ICR); + return 0; + + irq_out: + free_irq(dev->irq[0], dev); + map_out: + rtc_base = NULL; + res_out: + amba_release_regions(dev); + out: + return ret; +} + +static int nomadik_rtc_remove(struct amba_device *dev) +{ + set_rtc = NULL; + + nmdk_dbg_ftrace(); + writel(0, rtc_base + RTC_TCR); + + free_irq(dev->irq[0], dev); + unregister_rtc(&rtc_ops); + + iounmap(rtc_base); + rtc_base = NULL; + amba_release_regions(dev); + + nmdk_info("Module removed"); + return 0; +} + +static struct amba_id nomadik_rtc_ids[] = { + { + .id = RTC_PER_ID, + .mask = RTC_PER_MASK, + }, + {0, 0}, +}; + +static struct amba_driver rtc_driver = { + .drv = { + .name = "rtc", + }, + .probe = nomadik_rtc_probe, + .remove = nomadik_rtc_remove, + .id_table = nomadik_rtc_ids, +}; + +static int __init nomadik_rtc_init(void) +{ + return amba_driver_register(&rtc_driver); +} + +static void __exit nomadik_rtc_exit(void) +{ + amba_driver_unregister(&rtc_driver); +} + +module_init(nomadik_rtc_init); +module_exit(nomadik_rtc_exit); + +MODULE_AUTHOR("Prafulla WADASKAR "); +MODULE_DESCRIPTION("Nomadik RTC/RTT driver"); +MODULE_LICENSE("GPL v2"); --- /dev/null +++ linux-2.6.20/arch/arm/mach-nomadik/sleep.c @@ -0,0 +1,280 @@ +/* + * arch/arm/mach-nomadik/sleep.c + * + * Copyright 2007, STMicroelectronics + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#define SLEEP_NAME "SLEEP" + +#ifndef SLEEP_DEBUG +#define SLEEP_DEBUG 0 +#endif + +#define TRUE 1 +#define FALSE 0 + +#define NMDK_DEBUG SLEEP_DEBUG /* enables/disables nmdk_dbg msgs */ +#define NMDK_DEBUG_PFX SLEEP_NAME /* msg header represents this module */ +#define NMDK_DBG KERN_ERR /* message level */ + +#define GPIO_BASE 0x101E6000 +#define GPIO_SLPM_REG (GPIO_BASE + 0x01C) +#define GPIO_FALLINGEDGE_WAKEUP (GPIO_BASE + 0x054) +#define GPIO_RAISINGEDGE_WAKEUP (GPIO_BASE + 0x050) + +static u32 sdram_base = (u32) IO_ADDRESS(NOMADIK_SDRAMC_BASE); +static u32 backup_sram_start; + +static void save_sdmc_par(void) +{ + t_backup_data *backup_data; + + backup_data = ((t_backup_data *) backup_sram_start); + + backup_data->magic = BACKUP_MAGIC_NUMBER_DEEP_SLEEP; + + /* Enable SDMC */ + backup_data->reg_addr[0] = NOMADIK_SDRAMC_BASE; + backup_data->data[0] = *(u32 *) (sdram_base); + backup_data->action[0] = ACTION_WRITE; + + /* Program the command and delay strategy */ + backup_data->reg_addr[1] = NOMADIK_SDRAMC_BASE + 0x028; + backup_data->data[1] = *(u32 *) (sdram_base + 0x028); + backup_data->action[1] = ACTION_WRITE; + + /* Added for DDR-Ram - NOP command */ + backup_data->reg_addr[2] = NOMADIK_SDRAMC_BASE + 0x020; + backup_data->data[2] = *(u32 *) (sdram_base + 0x020); + backup_data->action[2] = ACTION_WRITE; + + /*Added for DDR-Ram - PALL command */ + backup_data->reg_addr[3] = NOMADIK_SDRAMC_BASE + 0x020; + backup_data->data[3] = *(u32 *) (sdram_base + 0x020); + backup_data->action[3] = ACTION_WRITE; + + /* To do at least two auto refresh */ + backup_data->reg_addr[4] = NOMADIK_SDRAMC_BASE + 0x024; + backup_data->data[4] = *(u32 *) (sdram_base + 0x024); + backup_data->action[4] = ACTION_WRITE; + + /* Prog the Auto-refresh period = 7.8µs @ SDRAM Clock = 100.8 MHz */ + backup_data->reg_addr[5] = NOMADIK_SDRAMC_BASE + 0x024; + //backup_data->data[5] = 0x31; + backup_data->data[5] = *(u32 *) (sdram_base + 0x024); + backup_data->action[5] = ACTION_WRITE; + + /* program little endian */ + backup_data->reg_addr[6] = NOMADIK_SDRAMC_BASE + 0x008; + backup_data->data[6] = *(u32 *) (sdram_base + 0x008); + backup_data->action[6] = ACTION_WRITE; + + /* Prog tRP timing */ + backup_data->reg_addr[7] = NOMADIK_SDRAMC_BASE + 0x030; + backup_data->data[7] = *(u32 *) (sdram_base + 0x030); + backup_data->action[7] = ACTION_WRITE; + + /* Prog tRAS timing */ + backup_data->reg_addr[8] = NOMADIK_SDRAMC_BASE + 0x034; + backup_data->data[8] = *(u32 *) (sdram_base + 0x034); + backup_data->action[8] = ACTION_WRITE; + + /* Prog tSREX timing */ + backup_data->reg_addr[9] = NOMADIK_SDRAMC_BASE + 0x038; + backup_data->data[9] = *(u32 *) (sdram_base + 0x038); + backup_data->action[9] = ACTION_WRITE; + + /* Prog tWR timing */ + backup_data->reg_addr[10] = NOMADIK_SDRAMC_BASE + 0x044; + backup_data->data[10] = *(u32 *) (sdram_base + 0x044); + backup_data->action[10] = ACTION_WRITE; + + /* Prog tRC timing */ + backup_data->reg_addr[11] = NOMADIK_SDRAMC_BASE + 0x048; + backup_data->data[11] = *(u32 *) (sdram_base + 0x048); + backup_data->action[11] = ACTION_WRITE; + + /* Prog tRFC timing */ + backup_data->reg_addr[12] = NOMADIK_SDRAMC_BASE + 0x04C; + backup_data->data[12] = *(u32 *) (sdram_base + 0x04C); + backup_data->action[12] = ACTION_WRITE; + + /* Prog tXSR timing */ + backup_data->reg_addr[13] = NOMADIK_SDRAMC_BASE + 0x050; + backup_data->data[13] = *(u32 *) (sdram_base + 0x050); + backup_data->action[13] = ACTION_WRITE; + + /* Prog tRRD timing */ + backup_data->reg_addr[14] = NOMADIK_SDRAMC_BASE + 0x054; + backup_data->data[14] = *(u32 *) (sdram_base + 0x054); + backup_data->action[14] = ACTION_WRITE; + + /* Prog tMRD timing */ + backup_data->reg_addr[15] = NOMADIK_SDRAMC_BASE + 0x058; + backup_data->data[15] = *(u32 *) (sdram_base + 0x058); + backup_data->action[15] = ACTION_WRITE; + + /* Prog tCDLR timing */ + backup_data->reg_addr[16] = NOMADIK_SDRAMC_BASE + 0x05C; + backup_data->data[16] = *(u32 *) (sdram_base + 0x05C); + backup_data->action[16] = ACTION_WRITE; + + /* Prog RAS and CAS for Chip Select 0 */ /*TBD*/ + backup_data->reg_addr[17] = NOMADIK_SDRAMC_BASE + 0x104; + backup_data->data[17] = *(u32 *) (sdram_base + 0x104); + backup_data->action[17] = ACTION_WRITE; + + /* Prog RAS and CAS for Chip Select 1 */ + backup_data->reg_addr[18] = NOMADIK_SDRAMC_BASE + 0x124; + backup_data->data[18] = *(u32 *) (sdram_base + 0x124); + backup_data->action[18] = ACTION_WRITE; + + /* Prog config register in BRC for Chip Select 0 */ + backup_data->reg_addr[19] = NOMADIK_SDRAMC_BASE + 0x100; + backup_data->data[19] = *(u32 *) (sdram_base + 0x100); + backup_data->action[19] = ACTION_WRITE; + + /* Prog config register in BRC for Chip Select 1 */ + backup_data->reg_addr[20] = NOMADIK_SDRAMC_BASE + 0x120; + backup_data->data[20] = *(u32 *) (sdram_base + 0x120); + backup_data->action[20] = ACTION_WRITE; + + /* For DDR-RAM - MODE command */ + backup_data->reg_addr[21] = NOMADIK_SDRAMC_BASE + 0x020; + backup_data->data[21] = *(u32 *) (sdram_base + 0x020); + backup_data->action[21] = ACTION_WRITE; + + /* ENABLE ALL THE BUFFER FOR EACH AHB PORT */ + backup_data->reg_addr[22] = NOMADIK_SDRAMC_BASE + 0x400; + backup_data->data[22] = *(u32 *) (sdram_base + 0x400); + backup_data->action[22] = ACTION_WRITE; + + backup_data->reg_addr[23] = NOMADIK_SDRAMC_BASE + 0x420; + backup_data->data[23] = *(u32 *) (sdram_base + 0x420); + backup_data->action[23] = ACTION_WRITE; + + backup_data->reg_addr[24] = NOMADIK_SDRAMC_BASE + 0x440; + backup_data->data[24] = *(u32 *) (sdram_base + 0x440); + backup_data->action[24] = ACTION_WRITE; + + backup_data->reg_addr[25] = NOMADIK_SDRAMC_BASE + 0x460; + backup_data->data[25] = *(u32 *) (sdram_base + 0x460); + backup_data->action[25] = ACTION_WRITE; + + backup_data->reg_addr[26] = NOMADIK_SDRAMC_BASE + 0x480; + backup_data->data[26] = *(u32 *) (sdram_base + 0x480); + backup_data->action[26] = ACTION_WRITE; + + backup_data->reg_addr[27] = NOMADIK_SDRAMC_BASE + 0x4A0; + backup_data->data[27] = *(u32 *) (sdram_base + 0x4A0); + backup_data->action[27] = ACTION_WRITE; + + /* GPIO force release and PMU_CTRL SDMCHLD bit release */ + backup_data->reg_addr[28] = NOMADIK_PMU_BASE; + backup_data->data[28] = *(u32 *) IO_ADDRESS(NOMADIK_PMU_BASE); + backup_data->action[28] = ACTION_WRITE_OR; + + /* MPMC init (end) */ + backup_data->reg_addr[29] = NOMADIK_SDRAMC_BASE + 0x020; + backup_data->data[29] = *(u32 *) (sdram_base + 0x020); + backup_data->action[29] = ACTION_WRITE; + + /* Clear REMAP */ + backup_data->reg_addr[30] = NOMADIK_SRC_BASE; + backup_data->data[30] = *(u32 *) IO_ADDRESS(NOMADIK_SRC_BASE); + backup_data->action[30] = ACTION_WRITE; + + /* New Changes */ + + backup_data->reg_addr[31] = NOMADIK_SDRAMC_BASE + 0x408; + backup_data->data[31] = 0x41e; + backup_data->action[31] = ACTION_WRITE; + + backup_data->reg_addr[32] = NOMADIK_SDRAMC_BASE + 0x428; + backup_data->data[32] = 0x414; + backup_data->action[32] = ACTION_WRITE; + + backup_data->reg_addr[33] = NOMADIK_SDRAMC_BASE + 0x448; + backup_data->data[33] = 0x40d; + backup_data->action[33] = ACTION_WRITE; + + backup_data->reg_addr[34] = NOMADIK_SDRAMC_BASE + 0x468; + backup_data->data[34] = 0x429; + backup_data->action[34] = ACTION_WRITE; + + backup_data->reg_addr[35] = NOMADIK_SDRAMC_BASE + 0x488; + backup_data->data[35] = 0x435; + backup_data->action[35] = ACTION_WRITE; + + backup_data->reg_addr[36] = NOMADIK_SDRAMC_BASE + 0x4a8; + backup_data->data[36] = 0x435; + backup_data->action[36] = ACTION_WRITE; + + backup_data->Size = 37; + +} + +int nomadik_sleep(unsigned int sleep_mode, unsigned int *wakeup_reason) +{ + backup_sram_start = (u32) ioremap(NOMADIK_BACKUP_RAM, BACKUP_RAM_SIZE); + if (!backup_sram_start) { + nmdk_error("failure in ioremap for NOMADIK_BACKUP_RAM\n"); + return -1; + } + nomadik_gpio_wakeupconfig(IRQNO_GPIO(GPIO_PIN_76), TRUE); + if (sleep_mode == DEEP_SLEEP) { + save_sdmc_par(); + } + + if (sleep_mode == DEEP_SLEEP) + nomadik_deep_sleep(sleep_mode, sdram_base, backup_sram_start); + else + nomadik_soft_sleep(); + nomadik_gpio_wakeupconfig(IRQNO_GPIO(GPIO_PIN_76), FALSE); + iounmap((void *)backup_sram_start); + + return 0; +} --- /dev/null +++ linux-2.6.20/arch/arm/mach-nomadik/slow.S @@ -0,0 +1,199 @@ +/* + * arch/arm/mach-nomadik/slow.S + * + * Copyright 2007, STMicroelectronics + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#define SLOW_DEBUG 0 +#define mpmc_base 0xF0110000 +#define src_base 0xf01e0000 +#define pmu_base 0xf01e9000 +#define uart_base 0xcc85e000 + + + + +.align 5 +.globl nomadik_slow_mode + +nomadik_slow_mode: + + + stmfd sp!,{r0-r12,lr} + + ldr r10,=mpmc_base + ldr r11,=src_base + ldr r12,=pmu_base + ldr r9,=uart_base + + + ldr r2, [r11] + +#if SLOW_DEBUG + mov r0, #97 + str r0, [r9] +#endif + + /* Prefetch certain instructions in the cache. */ + adr r4, cache_prefetch_start + adr r5, cache_prefetch_end + mvn r1,#0x1F + ands r4,r1,r4 +pfetch: + mcr p15, 0, r4, c7, c13,1 + cmp r4,r5 + addls r4, r4, #0x20 + bls pfetch + +.align 5 + +cache_prefetch_start: + ldr r10, =mpmc_base + +poll_status: + /* Check sdram is not busy */ + ldr r1,[r10, #0x4] + ands r1,r1,#0x1 + cmp r1,#0 + bne poll_status + + /* Put SDRAM in self-refresh mode*/ + ldr r1,[r10, #0x20] + bic r1,r1,#0x1 + orr r1,r1,#0x04 + str r1,[r10, #0x20] + + + /*Wait for SDRAM to go in self-refresh*/ +wait_self_refresh: + ldr r1,[r10,#0x4] + and r1,r1,#0x4 + cmp r1,#0x0 + beq wait_self_refresh + + /** + * Stop the DLL, leave SDMC on + Moving 0xff9 into sdmc control register for stopping and adding dll + cmd value + */ + mov r1, #0xff0 + mov r2, #0x9 + orr r1, r1, r2 + str r1,[r10] + + +wait_dll_lock: + ldr r1,[r10,#0x4] + and r1,r1,#0x8 + cmp r1,#0 + bne wait_dll_lock + +#if SLOW_DEBUG + mov r0, #98 + str r0, [r9] +#endif + /* Prog sdmc refresh period */ + mov r1,#9 + str r1,[r10,#0x24] + + + /* Prog ras and cas delay for bank 0 and bank 1 */ + ldr r1,[r10,#0x104] + sub r1, r1, #0x100 + str r1,[r10,#0x104] + + ldr r1,[r10,#0x124] + sub r1, r1, #0x100 + str r1,[r10,#0x124] + + + + +#if SLOW_DEBUG + mov r0, #99 + str r0, [r9] +#endif + + +#if 1 + + ldr r1,[r11] +/** Routine to put the chip in Slow Mode +*/ + + + bic r1, r1, #0x7 + orr r1, r1, #0x2 + str r1,[r11] + + +wait_slow_mode: + ldr r1, [r11] + and r1, r1, #0x78 + cmp r1, #0x10 + bne wait_slow_mode + +#endif + +#if SLOW_DEBUG + mov r0, #100 + str r0, [r9] +#endif + + + /* Exit DDR-SDRAM from self-refresh mode */ + ldr r1,[r10, #0x20] + bic r1,r1,#0x04 + str r1,[r10, #0x20] + + + /* Wait for DDR-SDRAM to exit from self-refresh */ +loop_refresh: + ldr r1,[r10,#0x4] + and r1,r1,#0x4 + cmp r1,#0x4 + beq loop_refresh + +#if SLOW_DEBUG + mov r0, #101 + str r0, [r9] +#endif + + + + mov r0,r0 + mov r0,r0 + mov r0,r0 + mov r0,r0 + +cache_prefetch_end: + mov r0,r0 + mov r0,r0 + mov r0,r0 + mov r0,r0 + + +#if SLOW_DEBUG + + mov r0, #102 + str r0, [r9] +#endif + + ldmfd sp!,{r0-r12,pc} + + --- /dev/null +++ linux-2.6.20/arch/arm/mach-nomadik/soft_sleep.S @@ -0,0 +1,206 @@ +/* + * arch/arm/mach-nomadik/soft_sleep.S + * + * Copyright 2007, STMicroelectronics + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#define mpmc_base 0xF0110000 +#define src_base 0xf01e0000 +#define pmu_base 0xf01e9000 + + + + +.align 5 +.globl nomadik_soft_sleep + +nomadik_soft_sleep: + + + + stmfd sp!,{r0-r12,lr} + + + mrs r7, cpsr + stmfd sp!, {r7} + bic r7,r7,#0xf + + + + ldr r10,=mpmc_base + ldr r11,=src_base + ldr r12,=pmu_base + + + /* Go back in SVC mode*/ + orr r0,r7,#0x3 + msr cpsr_cxsf,r0 + + /* Drain Write Buffers*/ + mov r0,#0 + mcr p15,0,r0,c7,c10,4 + + + /* Program to wake-up in Normal mode*/ + ldr r0,[r11,#0x4] + bic r0,r0,#0xf + orr r0,r0,#0x9 + str r0,[r11,#0x4] + + /* Set the PMU bit - disable entering to deep-sleep from sleep*/ + ldr r0,[r12] + orr r0,r0,#0x10 + str r0,[r12] + + /* Prefetch certain instructions in the cache. */ + adr r4, cache_prefetch_start + adr r5, cache_prefetch_end + mvn r1,#0x1F + ands r4,r1,r4 +pfetch: + mcr p15, 0, r4, c7, c13,1 + cmp r4,r5 + addls r4, r4, #0x20 + bls pfetch + +.align 5 + + +cache_prefetch_start: + ldr r10, =mpmc_base + +poll_status: + ldr r1,[r10, #0x4] + ands r1,r1,#0x1 + cmp r1,#0 + bne poll_status + + /* Put SDRAM in self-refresh mode*/ + ldr r1,[r10, #0x20] + bic r1,r1,#0x1 + orr r1,r1,#0x04 + str r1,[r10, #0x20] + + /*Wait for SDRAM to go in self-refresh*/ +wait_self_refresh: + ldr r1,[r10,#0x4] + and r1,r1,#0x4 + cmp r1,#0x0 + beq wait_self_refresh + +/** Routine to put the chip in Sleep Mode +*/ + ldr r11,=src_base + + /* Move the system in mode >=Normal mode*/ + ldr r1,[r11] + bic r1,r1,#0x3 + str r1,[r11] + + /*Move system to sleep mode*/ + ldr r1,[r11] + bic r1, r1, #0x7 + str r1,[r11] + + nop + nop + nop + nop + + +/* Wakeup from This address */ + +/* Move the system in mode >=Normal mode*/ + ldr r1,[r11] + orr r1,r1,#0x4 + bic r1,r1,#0x3 + orr r1,r1,#0x2000 + str r1,[r11] + + /*Wait for the system to move in normal mode*/ +exit_sleepm: + ldr r0,[r11, #0x0] + and r0,r0,#0x78 + cmp r0, #0x20 + bne exit_sleepm + + + /* SDMC hold bit*/ + ldr r1,[r12] + orr r1,r1,#0x1C + str r1,[r12] + + + +/* Bring out the SDRAM from self refresh */ + /*Put SDRAM in self-refresh mode*/ + ldr r1,[r10, #0x20] + bic r1,r1,#0x04 + str r1,[r10, #0x20] + orr r1,r1,#0x3 + str r1,[r10, #0x20] + + + /*wait for sdram out of self-refresh */ +sdram_out_refresh: + ldr r1,[r10, #0x4] + and r1,r1,#0x4 + cmp r1,#0x0 + bne sdram_out_refresh + + +cache_prefetch_end: + mov r0,r0 + mov r0,r0 + mov r0,r0 + mov r0,r0 + +/* This is to add some delay */ + mov r0, #0 +while_loop: + add r0, r0, #0x100 + cmp r0, #0x100000 + bne while_loop + + + + /* Remove the chip from Interrupt mode */ + ldr r0,[r11, #0x4] + bic r0,r0,#0x1 + str r0,[r11, #0x4] + + /* Clear the interrupt mode status bit*/ + mov r0, #0x0 + str r0, [r11, #0x8] + + + /* Store the value of cpsr in r7*/ + mrs r7,cpsr + orr r7,r7,#0xC0 /*Not Needed*/ + bic r7,r7,#0xf + + + ldr r0, [sp] + msr cpsr_cxsf, r0 + add sp, sp,#4 + + + + ldmfd sp!,{r0-r12,pc} + + --- /dev/null +++ linux-2.6.20/arch/arm/mach-nomadik/ssp.c @@ -0,0 +1,930 @@ +/* + * arch/arm/mach-nomadik/ssp.c + * + * Copyright (C) 2006 STMicroelectronics Pvt. Ltd. + * + * Author: Sachin Verma + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +/***************************************************************************/ +#define SPI_DRIVER_VERSION "2.3.0" + +#define NMDK_SSP_NAME "NOMADIK_SSP" + +#ifndef SSP_DEBUG +#define SSP_DEBUG 0 +#endif + +#define NMDK_DEBUG SSP_DEBUG /* enables/disables nmdk_dbg msgs */ +#define NMDK_DEBUG_PFX NMDK_SSP_NAME /* msg header represents this module */ +#define NMDK_DBG KERN_ERR /* message level */ + +/***************************************************************************/ + +#define FALSE (0) +#define TRUE (1) + +#define DO_NOT_QUEUE_DMA (0) +#define QUEUE_DMA (1) + +/** + * ssp_controller_cmd - To execute controller specific commands + * @drv_data: SSP driver private data structure + * @cmd: Command which is to be executed on the controller + * + * + */ +static int ssp_controller_cmd(struct driver_data *drv_data, int cmd) +{ + int retval = 0; + nmdk_dbg_ftrace(); + switch (cmd) + { + case DISABLE_CONTROLLER: + { + nmdk_dbg2(":::: DISABLE_CONTROLLER\n"); + writel((readl(SSP_CR1(drv_data->regs)) & (~SSP_CR1_MASK_SSE)), SSP_CR1(drv_data->regs)); + break; + } + case ENABLE_CONTROLLER: + { + nmdk_dbg2(":::: ENABLE_CONTROLLER\n"); + writel((readl(SSP_CR1(drv_data->regs)) | SSP_CR1_MASK_SSE), SSP_CR1(drv_data->regs)); + break; + } + case DISABLE_DMA: + { + nmdk_dbg2(":::: DISABLE_DMA\n"); + /*As DEFAULT_SSP_REG_DMACR has DMA disabled*/ + writel(DEFAULT_SSP_REG_DMACR, SSP_DMACR(drv_data->regs)); + break; + } + case ENABLE_DMA: + { + nmdk_dbg2(":::: ENABLE_CONTROLLER\n"); + writel(drv_data->cur_chip->regs.sspr.dmacr, SSP_DMACR(drv_data->regs)); + break; + } + case DISABLE_ALL_INTERRUPT: + { + nmdk_dbg2(":::: DISABLE_ALL_INTERRUPT\n"); + writel(DISABLE_ALL_SSP_INTERRUPTS, SSP_IMSC(drv_data->regs)); + break; + } + case ENABLE_ALL_INTERRUPT: + { + nmdk_dbg2(":::: ENABLE_ALL_INTERRUPT\n"); + writel(ENABLE_ALL_SSP_INTERRUPTS, SSP_IMSC(drv_data->regs)); + break; + } + case CLEAR_ALL_INTERRUPT: + { + writel(CLEAR_ALL_SSP_INTERRUPTS, SSP_ICR(drv_data->regs)); + break; + } + case FLUSH_FIFO: + { + unsigned long limit = loops_per_jiffy << 1; + nmdk_dbg2("::: DATA FIFO is flushed\n"); + do { + while (readl(SSP_SR(drv_data->regs)) & SSP_SR_MASK_RNE) + readl(SSP_DR(drv_data->regs)); + } while ((readl(SSP_SR(drv_data->regs)) & SSP_SR_MASK_BSY) && limit--); + retval = limit; + break; + } + case RESTORE_STATE: + { + struct chip_data *chip = drv_data->cur_chip; + nmdk_dbg2(":::: RESTORE_STATE\n"); + writel(chip->regs.sspr.cr0, SSP_CR0(drv_data->regs)); + writel(chip->regs.sspr.cr1, SSP_CR1(drv_data->regs)); + writel(chip->regs.sspr.dmacr, SSP_DMACR(drv_data->regs)); + writel(chip->regs.sspr.cpsr, SSP_CPSR(drv_data->regs)); + writel(DISABLE_ALL_SSP_INTERRUPTS, SSP_IMSC(drv_data->regs)); + writel(CLEAR_ALL_SSP_INTERRUPTS, SSP_ICR(drv_data->regs)); + break; + } + case LOAD_DEFAULT_CONFIG: + { + nmdk_dbg2(":::: LOAD_DEFAULT_CONFIG\n"); + writel(DEFAULT_SSP_REG_CR0, SSP_CR0(drv_data->regs)); + writel(DEFAULT_SSP_REG_CR1, SSP_CR1(drv_data->regs)); + writel(DEFAULT_SSP_REG_DMACR, SSP_DMACR(drv_data->regs)); + writel(DEFAULT_SSP_REG_CPSR, SSP_CPSR(drv_data->regs)); + writel(DISABLE_ALL_SSP_INTERRUPTS, SSP_IMSC(drv_data->regs)); + writel(CLEAR_ALL_SSP_INTERRUPTS, SSP_ICR(drv_data->regs)); + break; + } + default: + { + nmdk_dbg2(":::: unknown command\n"); + retval = -1; + break; + } + } + return retval; +} + +/** + * ssp_u8_writer - Write FIFO data in Data register as a 8 Bit Data + * @drv_data: spi driver private data structure + * + * This function writes data in Tx FIFO till it is not full + * which is indicated by the status register or our transfer is complete. + * It also updates the temporary write ptr tx in drv_data which maintains + * current write position in transfer buffer + */ +static void ssp_u8_writer(struct driver_data *drv_data) +{ + /*While Transmit Fifo is not Full(bit SSP_SR_MASK_TNF == 0 in status Reg) or our data to transmit is finished */ + while ((readl(SSP_SR(drv_data->regs)) & SSP_SR_MASK_TNF) + && (drv_data->tx < drv_data->tx_end)) { + /*Write Data to Data Register */ + writel(*(u8 *) (drv_data->tx), SSP_DR(drv_data->regs)); + drv_data->tx += (drv_data->cur_chip->n_bytes); + } +} + +/** + * ssp_u8_reader - Read FIFO data in Data register as a 8 Bit Data + * @drv_data: spi driver private data structure + * + * This function reads data in Rx FIFO till it is not empty + * which is indicated by the status register or our transfer is complete. + * It also updates the temporary Read ptr rx in drv_data which maintains + * current read position in transfer buffer + */ +static void ssp_u8_reader(struct driver_data *drv_data) +{ + /*While Receive Fifo is not Empty(bit SSP_SR_MASK_RNE == 0 in status Reg) or We have received Data we wanted to receive */ + while ((readl(SSP_SR(drv_data->regs)) & SSP_SR_MASK_RNE) + && (drv_data->rx < drv_data->rx_end)) { + *(u8 *) (drv_data->rx) = readl(SSP_DR(drv_data->regs)); + drv_data->rx += (drv_data->cur_chip->n_bytes); + } +} + +/** + * ssp_u16_writer - Write FIFO data in Data register as a 16 Bit Data + * @drv_data: spi driver private data structure + * + * This function writes data in Tx FIFO till it is not full + * which is indicated by the status register or our transfer is complete. + * It also updates the temporary write ptr tx in drv_data which maintains + * current write position in transfer buffer + */ +static void ssp_u16_writer(struct driver_data *drv_data) +{ + /*While Transmit Fifo is not Full(bit SSP_SR_MASK_TNF == 0 in status Reg) or our data to transmit is finished */ + while ((readl(SSP_SR(drv_data->regs)) & SSP_SR_MASK_TNF) + && (drv_data->tx < drv_data->tx_end)) { + /*Write Data to Data Register */ + writel((u32) (*(u16 *) (drv_data->tx)), SSP_DR(drv_data->regs)); + drv_data->tx += (drv_data->cur_chip->n_bytes); + } +} + +/** + * ssp_u16_reader - Read FIFO data in Data register as a 16 Bit Data + * @drv_data: spi driver private data structure + * + * This function reads data in Rx FIFO till it is not empty + * which is indicated by the status register or our transfer is complete. + * It also updates the temporary Read ptr rx in drv_data which maintains + * current read position in transfer buffer + */ +static void ssp_u16_reader(struct driver_data *drv_data) +{ + /*While Receive Fifo is not Empty(bit SSP_SR_MASK_RNE == 0 in status Reg) or We have received Data we wanted to receive */ + while ((readl(SSP_SR(drv_data->regs)) & SSP_SR_MASK_RNE) + && (drv_data->rx < drv_data->rx_end)) { + *(u16 *) (drv_data->rx) = (u16) readl(SSP_DR(drv_data->regs)); + drv_data->rx += (drv_data->cur_chip->n_bytes); + } +} + +/** + * ssp_u32_writer - Write FIFO data in Data register as a 32 Bit Data + * @drv_data: spi driver private data structure + * + * This function writes data in Tx FIFO till it is not full + * which is indicated by the status register or our transfer is complete. + * It also updates the temporary write ptr tx in drv_data which maintains + * current write position in transfer buffer + */ +static void ssp_u32_writer(struct driver_data *drv_data) +{ + /*While Transmit Fifo is not Full(bit SSP_SR_MASK_TNF == 0 in status Reg) or our data to transmit is finished */ + while ((readl(SSP_SR(drv_data->regs)) & SSP_SR_MASK_TNF) + && (drv_data->tx < drv_data->tx_end)) { + /*Write Data to Data Register */ + writel(*(u32 *) (drv_data->tx), SSP_DR(drv_data->regs)); + drv_data->tx += (drv_data->cur_chip->n_bytes); + } +} + +/** + * ssp_u32_reader - Read FIFO data in Data register as a 32 Bit Data + * @drv_data: spi driver private data structure + * + * This function reads data in Rx FIFO till it is not empty + * which is indicated by the status register or our transfer is complete. + * It also updates the temporary Read ptr rx in drv_data which maintains + * current read position in transfer buffer + */ +static void ssp_u32_reader(struct driver_data *drv_data) +{ + /*While Receive Fifo is not Empty(bit SSP_SR_MASK_RNE == 0 in status Reg) or We have received Data we wanted to receive */ + while ((readl(SSP_SR(drv_data->regs)) & SSP_SR_MASK_RNE) + && (drv_data->rx < drv_data->rx_end)) { + *(u32 *) (drv_data->rx) = readl(SSP_DR(drv_data->regs)); + drv_data->rx += (drv_data->cur_chip->n_bytes); + } +} + +/** + * nomadik_ssp_interrupt_handler - Interrupt handler for spi controller + * + * + * This function handles interrupts generated for an interrupt based transfer. + * If a receive overrun (ROR) interrupt is there then we disable SSP, flag the + * current message's state as ERROR_STATE and schedule the tasklet pump_transfers + * which will do the postprocessing of the current message by calling giveback(). + * Otherwise it reads data from Rx FIFO till there is no more data, and writes data + * in Tx FIFO till it is not full. If we complete the transfer we move to the next + * transfer and schedule the tasklet + * + */ +static irqreturn_t nomadik_ssp_interrupt_handler(int irq, void *dev_id) +{ + struct driver_data *drv_data = (struct driver_data *)dev_id; + struct spi_message *msg = drv_data->cur_msg; + u32 irq_status = 0; + u32 flag = 0; + if (!msg) { + dev_err(&drv_data->adev->dev, + "bad message state in interrupt handler"); + /* Never fail */ + return IRQ_HANDLED; + } + /*Read the Interrupt Status Register */ + irq_status = readl(SSP_MIS(drv_data->regs)); + + if (irq_status) { + if (irq_status & SSP_MIS_MASK_RORMIS) { /*Overrun interrupt */ + /*Bail-out our Data has been corrupted */ + nmdk_dbg3(":::: Received ROR interrupt\n"); + drv_data->execute_cmd(drv_data, DISABLE_ALL_INTERRUPT); + drv_data->execute_cmd(drv_data, CLEAR_ALL_INTERRUPT); + drv_data->execute_cmd(drv_data, DISABLE_CONTROLLER); + msg->state = ERROR_STATE; + tasklet_schedule(&drv_data->pump_transfers); + return IRQ_HANDLED; + } + drv_data->read(drv_data); + drv_data->write(drv_data); + + if ((drv_data->tx == drv_data->tx_end) && (flag == 0)) { + flag = 1; + /*Disable Transmit interrupt */ + writel(readl(SSP_IMSC(drv_data->regs)) & + (~SSP_IMSC_MASK_TXIM), SSP_IMSC(drv_data->regs)); + } + if (drv_data->rx == drv_data->rx_end) { + drv_data->execute_cmd(drv_data, DISABLE_ALL_INTERRUPT); + drv_data->execute_cmd(drv_data, CLEAR_ALL_INTERRUPT); + nmdk_dbg3(":::: Interrupt transfer Completed...\n"); + /* Update total bytes transfered */ + msg->actual_length += drv_data->cur_transfer->len; + if (drv_data->cur_transfer->cs_change) + drv_data->cur_chip-> + cs_control(SPI_CHIP_DESELECT); + /* Move to next transfer */ + msg->state = next_transfer(drv_data); + tasklet_schedule(&drv_data->pump_transfers); + return IRQ_HANDLED; + } + } + return IRQ_HANDLED; +} + +int verify_ssp_controller_parameters(struct nmdk_spi_config_chip *chip_info) +{ + nmdk_dbg_ftrace(); + if ((chip_info->lbm != LOOPBACK_ENABLED) + && (chip_info->lbm != LOOPBACK_DISABLED)) { + nmdk_dbg(":::: Loopback Mode is configured incorrectly\n"); + return -1; + } + if ((chip_info->iface < SPI_INTERFACE_MOTOROLA_SPI) + || (chip_info->iface > SPI_INTERFACE_UNIDIRECTIONAL)) { + nmdk_dbg(":::: Interface is configured incorrectly\n"); + return -1; + } + if ((chip_info->hierarchy != SPI_MASTER) + && (chip_info->hierarchy != SPI_SLAVE)) { + nmdk_dbg(":::: hierarchy is configured incorrectly\n"); + return -1; + } + if (((chip_info->controller).ssp.clk_freq.cpsdvsr < MIN_CPSDVR) || ((chip_info->controller).ssp.clk_freq.cpsdvsr > MAX_CPSDVR)) { + nmdk_dbg(":::: cpsdvsr is configured incorrectly\n"); + return -1; + } + if ((chip_info->endian_rx != SPI_FIFO_MSB) + && (chip_info->endian_rx != SPI_FIFO_LSB)) { + nmdk_dbg(":::: Rx FIFO endianess is configured incorrectly\n"); + return -1; + } + if ((chip_info->endian_tx != SPI_FIFO_MSB) + && (chip_info->endian_tx != SPI_FIFO_LSB)) { + nmdk_dbg(":::: Tx FIFO endianess is configured incorrectly\n"); + return -1; + } + if (((chip_info->controller).ssp.data_size < SSP_DATA_BITS_4) || ((chip_info->controller).ssp.data_size > SSP_DATA_BITS_32)) { + nmdk_dbg(":::: DATA Size is configured incorrectly\n"); + return -1; + } + if ((chip_info->com_mode != INTERRUPT_TRANSFER) + && (chip_info->com_mode != DMA_TRANSFER) + && (chip_info->com_mode != POLLING_TRANSFER)) { + nmdk_dbg(":::: Communication mode is configured incorrectly\n"); + return -1; + } + + if ((chip_info->dma_xfer_type != SPI_WITH_PERIPH) + && (chip_info->dma_xfer_type != SPI_WITH_MEM)) { + nmdk_dbg(":::: DMA xfer type is configured incorrectly\n"); + return -1; + } + + + if (((chip_info->controller).ssp.rx_lev_trig < SSP_RX_1_OR_MORE_ELEM) || ((chip_info->controller).ssp.rx_lev_trig > SSP_RX_32_OR_MORE_ELEM)) { + nmdk_dbg(":::: Rx FIFO Trigger Level is configured incorrectly\n"); + return -1; + } + if (((chip_info->controller).ssp.tx_lev_trig < SSP_TX_1_OR_MORE_EMPTY_LOC) || ((chip_info->controller).ssp.tx_lev_trig > SSP_TX_32_OR_MORE_EMPTY_LOC)) { + nmdk_dbg(":::: Tx FIFO Trigger Level is configured incorrectly\n"); + return -1; + } + if (chip_info->iface == SPI_INTERFACE_MOTOROLA_SPI) { + if (((chip_info->proto_params).moto.clk_phase != SPI_CLK_ZERO_CYCLE_DELAY) + && ((chip_info->proto_params).moto.clk_phase != SPI_CLK_HALF_CYCLE_DELAY)) { + nmdk_dbg(":::: Clock Phase is configured incorrectly\n"); + return -1; + } + if (((chip_info->proto_params).moto.clk_pol != SPI_CLK_POL_IDLE_LOW) + && ((chip_info->proto_params).moto.clk_pol != SPI_CLK_POL_IDLE_HIGH)) { + nmdk_dbg(":::: Clock Polarity is configured incorrectly\n"); + return -1; + } + } + if (chip_info->iface == SPI_INTERFACE_NATIONAL_MICROWIRE) { + if (((chip_info->proto_params).micro.ctrl_len < SSP_BITS_4) + || ((chip_info->proto_params).micro.ctrl_len > SSP_BITS_32)) { + nmdk_dbg(":::: CTRL LEN is configured incorrectly\n"); + return -1; + } + if (((chip_info->proto_params).micro.wait_state != SSP_MWIRE_WAIT_ZERO) + && ((chip_info->proto_params).micro.wait_state != SSP_MWIRE_WAIT_ONE)) { + nmdk_dbg(":::: Wait State is configured incorrectly\n"); + return -1; + } + if (((chip_info->proto_params).micro.duplex != SSP_MICROWIRE_CHANNEL_FULL_DUPLEX) + && ((chip_info->proto_params).micro.duplex != SSP_MICROWIRE_CHANNEL_HALF_DUPLEX)) { + nmdk_dbg(":::: DUPLEX is configured incorrectly\n"); + return -1; + } + } + if (chip_info->cs_control == NULL) { + nmdk_dbg("::::Chip Select Function is NULL for this chip\n"); + chip_info->cs_control = null_cs_control; + } + return 0; +} + +int nomadik_spi_suspend(struct amba_device *adev, pm_message_t state); +int nomadik_spi_resume(struct amba_device *adev); + +/** + * nomadik_ssp_setup - setup function registered to SPI master framework + * @spi: spi device which is requesting setup + * + * This function is registered to the SPI framework for this SPI master + * controller. If it is the first time when setup is called by this device + * , this function will initialize the runtime state for this chip and save + * the same in the device structure. Else it will update the runtime info + * with the updated chip info. + */ +static int nomadik_ssp_setup(struct spi_device *spi) +{ + struct nmdk_spi_config_chip *chip_info; + struct chip_data *chip; + int status = 0; + struct driver_data *drv_data = spi_master_get_devdata(spi->master); + nmdk_dbg_ftrace(); + + /* Get controller data */ + chip_info = spi->controller_data; + /* Get controller_state */ + chip = spi_get_ctldata(spi); + if (chip == NULL) { + chip = kzalloc(sizeof(struct chip_data), GFP_KERNEL); + if (!chip) { + dev_err(&spi->dev, + "setup - cannot allocate controller state"); + return -ENOMEM; + } + chip->chip_id = spi->chip_select; + nmdk_dbg(":::: chip Id = %d\n", chip->chip_id); + nmdk_dbg(":::: Allocated Memory for controller's runtime state\n"); + + if (chip_info == NULL) { + /* spi_board_info.controller_data not is supplied */ + chip_info = + kzalloc(sizeof(struct nmdk_spi_config_chip), GFP_KERNEL); + if (!chip_info) { + dev_err(&spi->dev, + "setup - cannot allocate controller data"); + status = -ENOMEM; + goto err_first_setup; + } + nmdk_dbg(":::: Allocated Memory for controller data\n"); + + /*FIXME: Set controller data default value: Polling is supported by Default */ + chip_info->lbm = LOOPBACK_DISABLED; + chip_info->com_mode = POLLING_TRANSFER; + chip_info->iface = SPI_INTERFACE_MOTOROLA_SPI; + chip_info->hierarchy = SPI_MASTER; + (chip_info->controller).ssp.slave_tx_disable = DO_NOT_DRIVE_TX; + chip_info->endian_tx = SPI_FIFO_LSB; + chip_info->endian_rx = SPI_FIFO_LSB; + (chip_info->controller).ssp.data_size = SSP_DATA_BITS_12; + + if(spi->max_speed_hz != 0){ + chip_info->freq = spi->max_speed_hz; + (chip_info->controller).ssp.clk_freq.cpsdvsr = 0; + (chip_info->controller).ssp.clk_freq.scr = 0; + } + else{ + chip_info->freq = 0; + (chip_info->controller).ssp.clk_freq.cpsdvsr = NMDK_SSP_DEFAULT_PRESCALE; + (chip_info->controller).ssp.clk_freq.scr = NMDK_SSP_DEFAULT_CLKRATE; + } + (chip_info->controller).ssp.rx_lev_trig = SSP_RX_1_OR_MORE_ELEM; + (chip_info->controller).ssp.tx_lev_trig = SSP_TX_1_OR_MORE_EMPTY_LOC; + (chip_info->proto_params).moto.clk_phase = SPI_CLK_HALF_CYCLE_DELAY; + (chip_info->proto_params).moto.clk_pol = SPI_CLK_POL_IDLE_LOW; + chip_info->cs_control = null_cs_control; + spi->controller_data = chip_info; + } + } + if ((0 == (chip_info->controller).ssp.clk_freq.cpsdvsr) + && (0 == (chip_info->controller).ssp.clk_freq.scr)) { + status = + calculate_effective_freq(chip_info->freq, + &((chip_info->controller).ssp).clk_freq); + if (status < 0) + goto err_config_params; + } else { + if (((chip_info->controller).ssp.clk_freq.cpsdvsr % 2) != 0) + (chip_info->controller).ssp.clk_freq.cpsdvsr = (chip_info->controller).ssp.clk_freq.cpsdvsr - 1; + } + status = verify_ssp_controller_parameters(chip_info); + if (status) { + dev_err(&spi->dev, "setup - controller data is incorrect"); + goto err_config_params; + } + /* Now set controller state based on controller data */ + chip->xfer_type = chip_info->com_mode; + chip->cs_control = chip_info->cs_control; + + if ((chip_info->controller).ssp.data_size <= 8) { + nmdk_dbg(":::: Less than 8 bits per word....\n"); + chip->n_bytes = 1; + chip->read = ssp_u8_reader; + chip->write = ssp_u8_writer; + } else if ((chip_info->controller).ssp.data_size <= 16) { + nmdk_dbg(":::: Less than 16 bits per word....\n"); + chip->n_bytes = 2; + chip->read = ssp_u16_reader; + chip->write = ssp_u16_writer; + } else { + nmdk_dbg(":::: Less than 32 bits per word....\n"); + chip->n_bytes = 4; + chip->read = ssp_u32_reader; + chip->write = ssp_u32_writer; + } + + /*Now Initialize all register settings reqd. for this chip */ + chip->regs.sspr.cr0 = 0; + chip->regs.sspr.cr1 = 0; + chip->regs.sspr.dmacr = 0; + chip->regs.sspr.cpsr = 0; + + if ((chip_info->com_mode == DMA_TRANSFER) + && ((drv_data->master_info)->enable_dma)) { + chip->enable_dma = 1; + chip->dma_info = kzalloc(sizeof(struct spi_dma_info), GFP_KERNEL); + if(!chip->dma_info){ + nmdk_dbg("Could not allocate memory for dma info of chip_data\n"); + goto err_first_setup; + } + chip->dma_info->dma_xfer_type = chip_info->dma_xfer_type; + status = process_dma_info(chip_info, chip, (void *)drv_data); + if (status < 0) + goto err_config_params; + SPI_REG_WRITE_BITS(chip->regs.sspr.dmacr, SSP_DMA_ENABLED, + SSP_DMACR_MASK_RXDMAE, 0); + SPI_REG_WRITE_BITS(chip->regs.sspr.dmacr, SSP_DMA_ENABLED, + SSP_DMACR_MASK_TXDMAE, 1); + nmdk_dbg(":::: DMA mode set in controller state\n"); + + + /* find and request free dma chanel */ + chip->dma_info->rx_dmach = request_available_dma(&(chip->dma_info->rx_dma_info)); + if (chip->dma_info->rx_dmach < 0) { + nmdk_dbg(":::: Rx pipe request Failed: %d\n", chip->dma_info->rx_dmach); + goto err_rx_dmach_request; + } + nmdk_dbg(":::: Rx pipe Allocated = %d\n", chip->dma_info->rx_dmach); + + status = request_irq(IRQNO_FOR_DMACH(chip->dma_info->rx_dmach), + spi_dma_callback_handler, 0, 0, + (void *)drv_data); + if (status) { + nmdk_error("Error requesting rx callback dmach intr handler %d", status); + goto err_rx_clbk_request; + } + + /* find and request free dma chanel */ + chip->dma_info->tx_dmach = request_available_dma(&(chip->dma_info->tx_dma_info)); + if (chip->dma_info->tx_dmach < 0) { + nmdk_dbg(":::: Tx pipe request Failed: %d\n", status); + goto err_tx_dmach_request; + } + nmdk_dbg(":::: Tx pipe Allocated = %d\n", chip->dma_info->tx_dmach); + + status = request_irq(IRQNO_FOR_DMACH(chip->dma_info->tx_dmach), + spi_dma_callback_handler, 0, 0, + (void *)drv_data); + if (status) { + nmdk_error("Error requesting callback dmach intr handler %d", status); + goto err_tx_clbk_request; + } + + } else{ + chip->enable_dma = 0; + nmdk_dbg(":::: DMA mode NOT set in controller state ::::::::::%d\n",status); + SPI_REG_WRITE_BITS(chip->regs.sspr.dmacr, SSP_DMA_DISABLED, + SSP_DMACR_MASK_RXDMAE, 0); + SPI_REG_WRITE_BITS(chip->regs.sspr.dmacr, SSP_DMA_DISABLED, + SSP_DMACR_MASK_TXDMAE, 1); + } + + chip->regs.sspr.cpsr = (chip_info->controller).ssp.clk_freq.cpsdvsr; + + SPI_REG_WRITE_BITS(chip->regs.sspr.cr0, (chip_info->controller).ssp.data_size, SSP_CR0_MASK_DSS, 0); + SPI_REG_WRITE_BITS(chip->regs.sspr.cr0, (chip_info->proto_params).micro.duplex, SSP_CR0_MASK_HALFDUP, 5); + SPI_REG_WRITE_BITS(chip->regs.sspr.cr0, (chip_info->proto_params).moto.clk_pol, SSP_CR0_MASK_SPO, 6); + SPI_REG_WRITE_BITS(chip->regs.sspr.cr0, (chip_info->proto_params).moto.clk_phase, SSP_CR0_MASK_SPH, 7); + SPI_REG_WRITE_BITS(chip->regs.sspr.cr0, (chip_info->controller).ssp.clk_freq.scr, SSP_CR0_MASK_SCR, 8); + SPI_REG_WRITE_BITS(chip->regs.sspr.cr0, (chip_info->proto_params).micro.ctrl_len, SSP_CR0_MASK_CSS, 16); + SPI_REG_WRITE_BITS(chip->regs.sspr.cr0, chip_info->iface, SSP_CR0_MASK_FRF, 21); + + SPI_REG_WRITE_BITS(chip->regs.sspr.cr1, chip_info->lbm, SSP_CR1_MASK_LBM, 0); + SPI_REG_WRITE_BITS(chip->regs.sspr.cr1, SSP_DISABLED, SSP_CR1_MASK_SSE, 1); + SPI_REG_WRITE_BITS(chip->regs.sspr.cr1, chip_info->hierarchy, SSP_CR1_MASK_MS, 2); + SPI_REG_WRITE_BITS(chip->regs.sspr.cr1, (chip_info->controller).ssp.slave_tx_disable, SSP_CR1_MASK_SOD, + 3); + SPI_REG_WRITE_BITS(chip->regs.sspr.cr1, chip_info->endian_rx, SSP_CR1_MASK_RENDN, 4); + SPI_REG_WRITE_BITS(chip->regs.sspr.cr1, chip_info->endian_tx, SSP_CR1_MASK_TENDN, 5); + SPI_REG_WRITE_BITS(chip->regs.sspr.cr1, (chip_info->proto_params).micro.wait_state, SSP_CR1_MASK_MWAIT, 6); + SPI_REG_WRITE_BITS(chip->regs.sspr.cr1, (chip_info->controller).ssp.rx_lev_trig, SSP_CR1_MASK_RXIFLSEL,7); + SPI_REG_WRITE_BITS(chip->regs.sspr.cr1, (chip_info->controller).ssp.tx_lev_trig, SSP_CR1_MASK_TXIFLSEL, 10); + + /* Save controller_state */ + spi_set_ctldata(spi, chip); + return status; + +err_tx_clbk_request: + if (chip->dma_info->tx_dmach != -1) { + free_dma(chip->dma_info->tx_dmach); + } +err_tx_dmach_request: +err_rx_clbk_request: + if (chip->dma_info->rx_dmach != -1) { + free_dma(chip->dma_info->rx_dmach); + } +err_rx_dmach_request: + chip->dma_info->tx_dmach = -1; + chip->dma_info->rx_dmach = -1; +err_config_params: +err_first_setup: + if(chip->dma_info) + kfree(chip->dma_info); + kfree(chip); + return status; +} + +static int nomadik_spi_probe(struct amba_device *adev, void *data) +{ + struct device *dev = &adev->dev; + struct nmdk_spi_master_cntlr *platform_info; + struct spi_master *master; + struct driver_data *drv_data = NULL; /*Data for this driver */ + struct resource *res; + int irq, status = 0; + + nmdk_dbg_ftrace(); + + platform_info = (struct nmdk_spi_master_cntlr *)(dev->platform_data); + if (platform_info == NULL) { + dev_err(&adev->dev, "probe - no platform data supplied\n"); + status = -ENODEV; + goto err_no_pdata; + } + /* Allocate master with space for drv_data */ + master = spi_alloc_master(dev, sizeof(struct driver_data)); + if (master == NULL) { + dev_err(&adev->dev, "probe - cannot alloc spi_master\n"); + status = -ENOMEM; + goto err_no_mem; + } + + drv_data = spi_master_get_devdata(master); + drv_data->master = master; + drv_data->master_info = platform_info; + drv_data->adev = adev; + + drv_data->dma_ongoing = 0; + + /*Fetch the Resources, using platform data */ + res = &(adev->res); + if (res == NULL) { + dev_err(&adev->dev, "probe - MEM resources not defined\n"); + status = -ENODEV; + goto err_no_iores; + } + /*Get Hold of Device Register Area... */ + drv_data->regs = ioremap(res->start, (res->end - res->start)); + if (drv_data->regs == NULL) { + status = -ENODEV; + goto err_no_iores; + } + irq = adev->irq[0]; + if (irq <= 0) { + status = -ENODEV; + goto err_no_iores; + } + + if(platform_info->id == SSP_CONTROLLER){ + nmdk_dbg(":::: SSP Controller %d\n", platform_info->id); + drv_data->execute_cmd = ssp_controller_cmd; + drv_data->execute_cmd(drv_data, LOAD_DEFAULT_CONFIG); + + master->setup = nomadik_ssp_setup; + } + else{ + dev_err(&adev->dev, "unknown controller Id %d\n", platform_info->id); + goto err_no_irqres; + } + + /*Required Info for an SPI controller */ + /*Bus Number Which has been Assigned to this SPI controller on this board */ + master->bus_num = (u16) platform_info->id; + master->num_chipselect = platform_info->num_chipselect; + master->cleanup = nomadik_spi_cleanup; + master->transfer = nomadik_spi_transfer; + + nmdk_dbg(":::: BUSNO: %d\n", master->bus_num); + /* Initialize and start queue */ + status = init_queue(drv_data); + if (status != 0) { + dev_err(&adev->dev, "probe - problem initializing queue\n"); + goto err_init_queue; + } + status = start_queue(drv_data); + if (status != 0) { + dev_err(&adev->dev, "probe - problem starting queue\n"); + goto err_start_queue; + } + + /*Initialize tasklet for DMA transfer*/ + tasklet_init(&drv_data->spi_dma_tasklet, nomadik_spi_tasklet, + (unsigned long)drv_data); + + /* Register with the SPI framework */ + platform_set_drvdata(adev, drv_data); + status = spi_register_master(master); + if (status != 0) { + dev_err(&adev->dev, "probe - problem registering spi master\n"); + goto err_spi_register; + } + dev_dbg(dev, "probe succeded\n"); + nmdk_dbg(" Bus Number = %d, IRQ Line = %d, Virtual Addr: %x\n", master->bus_num, irq, (u32)(drv_data->regs) ); + + status = nomadik_gpio_altfuncenable(drv_data->master_info->gpio_alt_func, drv_data->master_info->device_name); + if (status < 0) { + dev_err(&drv_data->adev->dev, "probe - unable to set GPIO Altfunc, %d\n", drv_data->master_info->gpio_alt_func); + status = -ENODEV; + goto err_init_queue; + } + status = request_irq(drv_data->adev->irq[0], nomadik_ssp_interrupt_handler, 0, drv_data->master_info->device_name , drv_data); + if (status < 0) { + dev_err(&drv_data->adev->dev, "probe - cannot get IRQ (%d)\n", status); + goto err_irq; + } + + + return 0; + + err_irq: + nomadik_gpio_altfuncdisable(drv_data->master_info->gpio_alt_func, drv_data->master_info->device_name); + err_init_queue: + err_start_queue: + err_spi_register: + destroy_queue(drv_data); + err_no_irqres: + err_no_iores: + spi_master_put(master); + err_no_mem: + err_no_pdata: + return status; +} + +static int __devexit nomadik_spi_remove(struct amba_device *adev) +{ + struct driver_data *drv_data = platform_get_drvdata(adev); + struct device *dev = &adev->dev; + struct nmdk_spi_master_cntlr *platform_info; + int status = 0; + if (!drv_data) + return 0; + + platform_info = dev->platform_data; + + /* Remove the queue */ + status = destroy_queue(drv_data); + if (status != 0) { + dev_err(&adev->dev, "queue remove failed (%d)\n", status); + return status; + } + drv_data->execute_cmd(drv_data, LOAD_DEFAULT_CONFIG); + + /* Release map resources */ + iounmap(drv_data->regs); + tasklet_disable(&drv_data->pump_transfers); + tasklet_kill(&drv_data->spi_dma_tasklet); + + nomadik_gpio_altfuncdisable(platform_info->gpio_alt_func, platform_info->device_name); + free_irq(drv_data->adev->irq[0], drv_data); + + /* Disconnect from the SPI framework */ + spi_unregister_master(drv_data->master); + spi_master_put(drv_data->master); + + /* Prevent double remove */ + platform_set_drvdata(adev, NULL); + dev_dbg(&adev->dev, "remove succeded\n"); + return 0; +} + + +#ifdef CONFIG_PM +#if 0 +static int suspend_devices(struct device *dev, void *pm_message) +{ + pm_message_t *state = pm_message; + + if (dev->power.power_state.event != state->event) { + dev_warn(dev, "pm state does not match request\n"); + return -1; + } + return 0; +} +#endif + +int nomadik_spi_suspend(struct amba_device *adev, pm_message_t state) +{ + struct driver_data *drv_data = platform_get_drvdata(adev); + int status = 0; + nmdk_dbg_ftrace(); +#if 0 + /* Check all childern for current power state */ + if (device_for_each_child(&pdev->dev, &state, suspend_devices) != 0) { + dev_warn(&pdev->dev, "suspend aborted\n"); + return -1; + } +#endif + + status = stop_queue(drv_data); + if (status != 0) { + dev_warn(&adev->dev, "suspend cannot stop queue\n"); + return status; + } + + dev_dbg(&adev->dev, "suspended\n"); + return 0; +} + +int nomadik_spi_resume(struct amba_device *pdev) +{ + struct driver_data *drv_data = platform_get_drvdata(pdev); + int status = 0; + + nmdk_dbg_ftrace(); + /* Start the queue running */ + status = start_queue(drv_data); + if (status != 0) + dev_err(&pdev->dev, "problem starting queue (%d)\n", status); + else + dev_dbg(&pdev->dev, "resumed\n"); + + return status; +} + +#else +#define nomadik_spi_suspend NULL +#define nomadik_spi_resume NULL +#endif /* CONFIG_PM */ + +static struct amba_id ssp_ids[] = { + { + .id = SSP_PER_ID, + .mask = SSP_PER_MASK, + }, + {0, 0}, +}; + +static struct amba_driver spi_driver = { + + .drv = { + .name = "SSP", + }, + .id_table = ssp_ids, + .probe = nomadik_spi_probe, + .remove = nomadik_spi_remove, + .suspend = nomadik_spi_suspend, + .resume = nomadik_spi_resume, +}; + + +static int __init nomadik_spi_init(void) +{ + int retval = 0; + printk("\nLoading SSP Controller Driver Version " SPI_DRIVER_VERSION + "\n"); + retval = amba_driver_register(&spi_driver); + if(retval){ + printk("SSP Registration error\n"); + } + return retval; +} + +module_init(nomadik_spi_init); + +static void __exit nomadik_spi_exit(void) +{ + printk("\nExiting SSP Controller Driver Version " SPI_DRIVER_VERSION "\n"); + amba_driver_unregister(&spi_driver); + return; +} + +module_exit(nomadik_spi_exit); + +MODULE_AUTHOR("Sachin Verma, "); +MODULE_DESCRIPTION("NOMADIK SPI Controller Driver"); +MODULE_LICENSE("GPL"); --- /dev/null +++ linux-2.6.20/arch/arm/mach-nomadik/stn8810_devices.c @@ -0,0 +1,1071 @@ +/* + * linux/arch/arm/mach-nomadik/stn8810_devices.c + * + * Copyright (C) 2000-2003 Deep Blue Solutions Ltd + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2, as + * published by the Free Software Foundation. + * + * SOC specific devices which are registered as amba devices + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +extern struct irq_desc irq_desc[]; /* required for dma.c */ + +/* + * CLCD support + */ +static struct clcd_panel nmdk_clcd_panel = { + .mode = { + .name = CONFIG_FB_NOMADIK_PANEL_NAME, + .refresh = 60, + .xres = CONFIG_FB_NOMADIK_PANEL_XRES, + .yres = CONFIG_FB_NOMADIK_PANEL_YRES, + .pixclock = 40000, + .left_margin = CONFIG_FB_NOMADIK_PANEL_LFMARGIN, + .right_margin = CONFIG_FB_NOMADIK_PANEL_RTMARGIN, + .upper_margin = CONFIG_FB_NOMADIK_PANEL_UPRMARGIN, + .lower_margin = CONFIG_FB_NOMADIK_PANEL_LWRMARGIN, + .hsync_len = CONFIG_FB_NOMADIK_PANEL_HSLEN, + .vsync_len = CONFIG_FB_NOMADIK_PANEL_VSLEN, + .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, + .vmode = FB_VMODE_NONINTERLACED, + }, + .width = -1, + .height = -1, + .tim2 = CONFIG_FB_NOMADIK_PANEL_TIM2VAL, + .tim3 = 0x00000000, /* done for ndk15 */ + .cntl = + CNTL_LCDTFT | CNTL_LCDVCOMP(1) | CNTL_1XBPP_15 | CNTL_CDWID_18 | + CNTL_WATERMARK /*| CNTL_BGR */ , + .bpp = CONFIG_FB_NOMADIK_PANEL_BPP, + .grayscale = 0, +}; + +#define FRAMESIZE (CONFIG_FB_NOMADIK_PANEL_BPP * \ + CONFIG_FB_NOMADIK_PANEL_XRES * \ + CONFIG_FB_NOMADIK_PANEL_YRES / 8) + +static unsigned long framesize = (FRAMESIZE+PAGE_SIZE-1)/PAGE_SIZE*PAGE_SIZE; + +static int nomadik_clcd_setup(struct clcd_fb *fb) +{ + dma_addr_t dma; + + nomadik_gpio_altfuncenable(GPIO_ALT_LCD_PANEL, "CLCD"); + fb->panel = &nmdk_clcd_panel; + fb->fb.screen_base = dma_alloc_coherent(&fb->dev->dev, framesize, + &dma, GFP_KERNEL | GFP_DMA); + if (!fb->fb.screen_base) { + printk(KERN_ERR "CLCD: unable to map framebuffer\n"); + return -ENOMEM; + } + fb->fb.fix.smem_start = dma; + fb->fb.fix.smem_len = framesize; + return 0; +} + +static void nomadik_clcd_remove(struct clcd_fb *fb) +{ + dma_free_coherent(&fb->dev->dev, fb->fb.fix.smem_len, + fb->fb.screen_base, fb->fb.fix.smem_start); +} + +static int nomadik_clcd_mmap(struct clcd_fb *fb, struct vm_area_struct *vma) +{ + return dma_mmap_coherent(&fb->dev->dev, vma, + fb->fb.screen_base, + fb->fb.fix.smem_start, fb->fb.fix.smem_len); +} + +/* platform specific functions from _devices.c */ +extern void nomadik_clcd_enable(struct clcd_fb *); +extern void nomadik_clcd_disable(struct clcd_fb *); + +static struct clcd_board clcd_data = { + .name = "Nomadik", + .check = clcdfb_check, + .decode = clcdfb_decode, + .enable = nomadik_clcd_enable, + .disable = nomadik_clcd_disable, + .setup = nomadik_clcd_setup, + .mmap = nomadik_clcd_mmap, + .remove = nomadik_clcd_remove, +}; + +/* + * GPIO............... + */ +#include + +#define GPIO_NAME "GPIO" + +#ifndef GPIO_DEBUG +#define GPIO_DEBUG 0 +#endif + +#define NMDK_DEBUG GPIO_DEBUG /* enables/disables nmdk_dbg msgs */ +#define NMDK_DEBUG_PFX GPIO_NAME /* msg header represents this module */ +#define NMDK_DBG KERN_ERR /* message level */ + +void nomadik_gpio_intrwake(struct gpio_register *bnkptr, uint32 mask, + uint32 type) +{ + nmdk_dbg_ftrace(); + switch (type & SA_TRIGGER_MASK) { + case SA_TRIGGER_RISING: + case SA_TRIGGER_FALLING: + case (SA_TRIGGER_FALLING | SA_TRIGGER_RISING): + nmdk_error("wakeup mode %d not supported", (int)type); + break; + case SA_TRIGGER_LOW: + bnkptr->gpio_wklev &= mask; + bnkptr->gpio_wken |= mask; + break; + case SA_TRIGGER_HIGH: + bnkptr->gpio_wklev |= mask; + bnkptr->gpio_wken |= mask; + break; + default: /* used to disable wakeup */ + bnkptr->gpio_wken &= mask; + break; + } +} + +void nomadik_gpio_intren(struct gpio_register *bnkptr, uint32 mask, uint32 type) +{ + nmdk_dbg_ftrace(); + switch (type & SA_TRIGGER_MASK) { + case SA_TRIGGER_RISING: + bnkptr->gpio_is &= ~mask; + bnkptr->gpio_ibe &= ~mask; + bnkptr->gpio_iev |= mask; + nmdk_dbg2("%s rising edge\n", __FUNCTION__); + break; + case SA_TRIGGER_FALLING: + bnkptr->gpio_is &= ~mask; + bnkptr->gpio_ibe &= ~mask; + bnkptr->gpio_iev &= ~mask; + nmdk_dbg2("%s falling edge\n", __FUNCTION__); + break; + case (SA_TRIGGER_FALLING | SA_TRIGGER_RISING): + bnkptr->gpio_is &= ~mask; + bnkptr->gpio_ibe |= mask; + nmdk_dbg2("%s both edge\n", __FUNCTION__); + break; + case SA_TRIGGER_LOW: + bnkptr->gpio_is |= mask; + bnkptr->gpio_iev &= ~mask; + nmdk_dbg2("%s low level\n", __FUNCTION__); + break; + case SA_TRIGGER_HIGH: + bnkptr->gpio_is |= mask; + bnkptr->gpio_iev |= mask; + nmdk_dbg2("%s high level\n", __FUNCTION__); + break; + } + bnkptr->gpio_imsc |= mask; +} + +void nomadik_gpio_intrdis(struct gpio_register *bnkptr, uint32 mask) +{ + nmdk_dbg_ftrace(); + bnkptr->gpio_imsc &= ~mask; +} + +int nomadik_gpio_dbounce(struct gpio_register *bnkptr, uint32 mask, + gpio_debounce debounce, + gpio_debounce_time debounce_time) +{ + nmdk_dbg_ftrace(); + switch (debounce) { + case GPIO_DEBOUNCE_ENABLE: + bnkptr->gpio_dben |= mask; + break; + case GPIO_DEBOUNCE_DISABLE: + bnkptr->gpio_dben &= ~mask; + break; + case GPIO_DEBOUNCE_UNCHANGED: + break; + default: + return (GPIO_INVALID_PARAMETER); + } + if (GPIO_DEBOUNCE_ENABLE == debounce) { + bnkptr->gpio_dbdiv = (uint32) debounce_time; + /**debounce_time = bnkptr->gpio_dbdiv;*/ + } + return (GPIO_OK); +} + +static struct gpio_altfun_data gpio_altfun_tbl[] = { + {.altfun = GPIO_ALT_UART_0_MODEM,.start = 0,.end = 2,.cont = 1,.type = + GPIO_ALTF_A,}, + {.altfun = GPIO_ALT_UART_0_MODEM,.start = 7,.end = 7,.cont = 0,.type = + GPIO_ALTF_A,}, + {.altfun = GPIO_ALT_UART_1,.start = 51,.end = 52,.cont = 1,.type = + GPIO_ALTF_A,}, + {.altfun = GPIO_ALT_UART_1,.start = 56,.end = 57,.cont = 0,.type = + GPIO_ALTF_A,}, + {.altfun = GPIO_ALT_UART_2,.start = 36,.end = 39,.cont = 0,.type = + GPIO_ALTF_A,}, + {.altfun = GPIO_ALT_I2C_0,.start = 62,.end = 63,.cont = 0,.type = + GPIO_ALTF_A,}, + {.altfun = GPIO_ALT_I2C_1,.start = 53,.end = 54,.cont = 0,.type = + GPIO_ALTF_A,}, + {.altfun = GPIO_ALT_MSP_0,.start = 17,.end = 22,.cont = 0,.type = + GPIO_ALTF_A,}, + {.altfun = GPIO_ALT_MSP_1,.start = 77,.end = 81,.cont = 0,.type = + GPIO_ALTF_B,}, + {.altfun = GPIO_ALT_MSP_2,.start = 64,.end = 67,.cont = 0,.type = + GPIO_ALTF_C,}, + {.altfun = GPIO_ALT_SSP,.start = 58,.end = 61,.cont = 0,.type = + GPIO_ALTF_A,}, + {.altfun = GPIO_ALT_MM_CARD,.start = 8,.end = 10,.cont = 1,.type = + GPIO_ALTF_A,}, + {.altfun = GPIO_ALT_MM_CARD,.start = 14,.end = 16,.cont = 0,.type = + GPIO_ALTF_A,}, + {.altfun = GPIO_ALT_SD_CARD,.start = 8,.end = 16,.cont = 1,.type = + GPIO_ALTF_A,}, + {.altfun = GPIO_ALT_SD_CARD,.start = 24,.end = 24,.cont = 0,.type = + GPIO_ALTF_A,}, + {.altfun = GPIO_ALT_DMA_0,.start = 36,.end = 37,.cont = 0,.type = + GPIO_ALTF_C,}, + {.altfun = GPIO_ALT_DMA_1,.start = 38,.end = 39,.cont = 0,.type = + GPIO_ALTF_C,}, + {.altfun = GPIO_ALT_HSI0,.start = 77,.end = 82,.cont = 0,.type = + GPIO_ALTF_B,}, + {.altfun = GPIO_ALT_CCIR656_INPUT,.start = 48,.end = 48,.cont = + 1,.type = GPIO_ALTF_A,}, + {.altfun = GPIO_ALT_CCIR656_INPUT,.start = 50,.end = 50,.cont = + 1,.type = GPIO_ALTF_A,}, + {.altfun = GPIO_ALT_CCIR656_INPUT,.start = 83,.end = 90,.cont = + 0,.type = GPIO_ALTF_A,}, + {.altfun = GPIO_ALT_CCIR656_OUTPUT,.start = 48,.end = 48,.cont = + 1,.type = GPIO_ALTF_B,}, + {.altfun = GPIO_ALT_CCIR656_OUTPUT,.start = 55,.end = 55,.cont = + 1,.type = GPIO_ALTF_B,}, + {.altfun = GPIO_ALT_CCIR656_OUTPUT,.start = 83,.end = 90,.cont = + 0,.type = GPIO_ALTF_B,}, + {.altfun = GPIO_ALT_LCD_PANEL,.start = 32,.end = 39,.cont = 0,.type = + GPIO_ALTF_B,}, + {.altfun = GPIO_ALT_MDIF,.start = 32,.end = 33,.cont = 0,.type = + GPIO_ALTF_B,}, + {.altfun = GPIO_ALT_HAMAC_AUDIO_DBG,.start = 40,.end = 47,.cont = + 1,.type = GPIO_ALTF_B,}, + {.altfun = GPIO_ALT_HAMAC_AUDIO_DBG,.start = 62,.end = 62,.cont = + 0,.type = GPIO_ALTF_C,}, + {.altfun = GPIO_ALT_HAMAC_VIDEO_DBG,.start = 40,.end = 47,.cont = + 1,.type = GPIO_ALTF_A,}, + {.altfun = GPIO_ALT_HAMAC_VIDEO_DBG,.start = 62,.end = 62,.cont = + 0,.type = GPIO_ALTF_A,}, + {.altfun = GPIO_ALT_CLOCK_RESET,.start = 25,.end = 26,.cont = 1,.type = + GPIO_ALTF_A,}, + {.altfun = GPIO_ALT_CLOCK_RESET,.start = 55,.end = 56,.cont = 0,.type = + GPIO_ALTF_A,}, + {.altfun = GPIO_ALT_TSP,.start = 91,.end = 95,.cont = 0,.type = + GPIO_ALTF_A,}, + {.altfun = GPIO_ALT_IRDA,.start = 28,.end = 29,.cont = 0,.type = + GPIO_ALTF_A,}, + {.altfun = GPIO_ALT_USB_MINIMUM,.start = 68,.end = 74,.cont = 0,.type = + GPIO_ALTF_A,}, + {.altfun = GPIO_ALT_USB_I2C,.start = 68,.end = 74,.cont = 0,.type = + GPIO_ALTF_B,}, + {.altfun = GPIO_ALT_OWM,.start = 76,.end = 76,.cont = 0,.type = + GPIO_ALTF_A,}, + {.altfun = GPIO_ALT_PWL,.start = 75,.end = 75,.cont = 0,.type = + GPIO_ALTF_A,}, + {.altfun = GPIO_ALT_FSMC,.start = 30,.end = 30,.cont = 0,.type = + GPIO_ALTF_A,}, + {.altfun = GPIO_ALT_SRAM_NOR_FLASH,.start = 64,.end = 67,.cont = + 0,.type = GPIO_ALTF_B,}, + {.altfun = GPIO_ALT_COMP_FLASH,.start = 64,.end = 67,.cont = 1,.type = + GPIO_ALTF_C,}, + {.altfun = GPIO_ALT_COMP_FLASH,.start = 31,.end = 31,.cont = 1,.type = + GPIO_ALTF_C,}, + {.altfun = GPIO_ALT_COMP_FLASH,.start = 27,.end = 27,.cont = 0,.type = + GPIO_ALTF_C,}, + {.altfun = GPIO_ALT_USB_OTG,.start = 26,.end = 27,.cont = 1,.type = + GPIO_ALTF_A,}, + {.altfun = GPIO_ALT_USB_OTG,.start = 30,.end = 31,.cont = 1,.type = + GPIO_ALTF_A,}, + {.altfun = GPIO_ALT_USB_OTG,.start = 68,.end = 75,.cont = 0,.type = GPIO_ALTF_A,}, /*68,75TBC */ + {.altfun = GPIO_ALT_FSMC_ADDLINE_0_TO_15,.start = 48,.end = 50,.cont = + 1,.type = GPIO_ALTF_A,}, + {.altfun = GPIO_ALT_FSMC_ADDLINE_0_TO_15,.start = 83,.end = 95,.cont = + 0,.type = GPIO_ALTF_A,}, +}; + +static struct gpio_soc gpio_socdata = { + .altfun_tbl = gpio_altfun_tbl, + .sz_altfun_tbl = sizeof(gpio_altfun_tbl) / sizeof(gpio_altfun_tbl[0]), + .irqwake = nomadik_gpio_intrwake, + .irqen = nomadik_gpio_intren, + .irqdis = nomadik_gpio_intrdis, + .dbounce = nomadik_gpio_dbounce, +}; + +static struct amba_device gpio_device = { + .dev = { + .bus_id = "gpio", + .platform_data = &gpio_socdata, + }, + .res = { + .start = NOMADIK_GPIO0_BASE, + .end = NOMADIK_GPIO0_BASE + (SZ_4K * 4) - 1, + .flags = IORESOURCE_MEM, + }, + .irq = {IRQ_GPIO0, (IRQ_GPIO0 + 3)}, /*second param tells no of gpio banks */ + .periphid = GPIO_PER_ID, +}; + +static struct amba_device rtc_device = { + .dev = { + .bus_id = "mb:15", + }, + .res = { + .start = NOMADIK_RTC_BASE, + .end = NOMADIK_RTC_BASE + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + .irq = {IRQ_RTC_RTT, NO_IRQ}, + .periphid = RTC_PER_ID, +}; + +static struct amba_device uart0_device = { + .dev = { + .bus_id = "mb:16", + }, + .res = { + .start = NOMADIK_UART0_BASE, + .end = NOMADIK_UART0_BASE + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + .irq = {IRQ_UART0, NO_IRQ}, + .periphid = UART_PER_ID, +}; + +static struct amba_device uart1_device = { + .dev = { + .bus_id = "mb:17", + }, + .res = { + .start = NOMADIK_UART1_BASE, + .end = NOMADIK_UART1_BASE + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + .irq = {IRQ_UART1, NO_IRQ}, + .periphid = UART_PER_ID, +}; + +extern int nomadik_mmc_configure(struct amba_device *dev); +extern void nomadik_mmc_restore_default(struct amba_device *dev); + +static struct mmc_board mmc_data = { + .init = nomadik_mmc_configure, + .exit = nomadik_mmc_restore_default, +}; + +static struct amba_device mmc_device = { + .dev = { + .bus_id = "MMC", + .platform_data = &mmc_data, + }, + .res = { + .start = NOMADIK_SDI_BASE, + .end = NOMADIK_SDI_BASE + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + .irq = {IRQ_SDMMC, IRQNO_GPIO(MMCDETECT_IRQ)}, + .periphid = SDI_PER_ID, +}; + +static struct amba_device clcd_device = { + .dev = { + .bus_id = "mb:c0", + .coherent_dma_mask = ~0, + .platform_data = &clcd_data, + }, + .res = { + .start = NOMADIK_CLCDC_BASE, + .end = NOMADIK_CLCDC_BASE + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + .dma_mask = ~0, + .irq = {IRQ_CLCD_MDIF, NO_IRQ}, + .periphid = CLCD_PER_ID, +}; + +/** + * dmadev_default_config_tbl - Deffault dma device configuration table + * To support new dmadevice, add new default confiuration to this table + * refer /Documentation/arm/STM-Nomadik/dma_user_guide.txt for the same + */ +static struct dmadev_description dmadev_default_config_tbl[] = { + {.id = "mem", + .config = ( DMA_AHB_M1 | DMA_ADR_INC | DMA_WIDTH_WORD | + DMA_BSIZE_4 | DMA_REQUEST_LINE(31) | + DMA_DEV_BSIZE_CONFIGURABLE | DMA_DEV_WIDTH_CONFIGURABLE | + DMA_DEV_BOTH_DMACS_CANBE_USED ),}, + {.id = "sdmmc", + .config = ( DMA_AHB_M0 | DMA_ADR_NOINC | DMA_WIDTH_WORD | + DMA_BSIZE_8 | DMA_REQUEST_LINE(21) | + DMA_DEV_BSIZE_CONFIGURABLE | DMA_DEV_WIDTH_CONFIGURABLE | + DMA_DEV_DMAC1_CANBE_USED ),}, + {.id = "ssptx", + .config = ( DMA_AHB_M0 | DMA_ADR_NOINC | DMA_WIDTH_WORD | + DMA_BSIZE_4 | DMA_REQUEST_LINE(13) | + DMA_DEV_BSIZE_CONFIGURABLE | DMA_DEV_WIDTH_CONFIGURABLE | + DMA_DEV_BOTH_DMACS_CANBE_USED ),}, + {.id = "ssprx", + .config = ( DMA_AHB_M0 | DMA_ADR_NOINC | DMA_WIDTH_WORD | + DMA_BSIZE_4 | DMA_REQUEST_LINE(12) | + DMA_DEV_BSIZE_CONFIGURABLE | DMA_DEV_WIDTH_CONFIGURABLE | + DMA_DEV_BOTH_DMACS_CANBE_USED ),}, + {.id = "msp0tx", + .config = ( DMA_AHB_M0 | DMA_ADR_NOINC | DMA_WIDTH_WORD | + DMA_BSIZE_4 | DMA_REQUEST_LINE(11) | + DMA_DEV_WIDTH_CONFIGURABLE | DMA_DEV_BSIZE_NOT_CONFIGURABLE | + DMA_DEV_BOTH_DMACS_CANBE_USED ),}, + {.id = "msp0rx", + .config = ( DMA_AHB_M0 | DMA_ADR_NOINC | DMA_WIDTH_WORD | + DMA_BSIZE_4 | DMA_REQUEST_LINE(10) | + DMA_DEV_WIDTH_CONFIGURABLE | DMA_DEV_BSIZE_NOT_CONFIGURABLE | + DMA_DEV_BOTH_DMACS_CANBE_USED ),}, + {.id = "msp1tx", + .config = ( DMA_AHB_M0 | DMA_ADR_NOINC | DMA_WIDTH_WORD | + DMA_BSIZE_4 | DMA_REQUEST_LINE(31) | + DMA_DEV_WIDTH_CONFIGURABLE | DMA_DEV_BSIZE_NOT_CONFIGURABLE | + DMA_DEV_DMAC0_CANBE_USED ),}, + {.id = "msp1rx", + .config = ( DMA_AHB_M0 | DMA_ADR_NOINC | DMA_WIDTH_WORD | + DMA_BSIZE_4 | DMA_REQUEST_LINE(30) | + DMA_DEV_WIDTH_CONFIGURABLE | DMA_DEV_BSIZE_NOT_CONFIGURABLE | + DMA_DEV_DMAC0_CANBE_USED ),}, + {.id = "msp2tx", + .config = ( DMA_AHB_M0 | DMA_ADR_NOINC | DMA_WIDTH_WORD | + DMA_BSIZE_4 | DMA_REQUEST_LINE(23) | + DMA_DEV_WIDTH_CONFIGURABLE | DMA_DEV_BSIZE_NOT_CONFIGURABLE | + DMA_DEV_DMAC0_CANBE_USED ),}, + {.id = "msp2rx", + .config = ( DMA_AHB_M0 | DMA_ADR_NOINC | DMA_WIDTH_WORD | + DMA_BSIZE_4 | DMA_REQUEST_LINE(22) | + DMA_DEV_WIDTH_CONFIGURABLE | DMA_DEV_BSIZE_NOT_CONFIGURABLE | + DMA_DEV_DMAC0_CANBE_USED ),}, + {.id = "saa0", + .config = ( DMA_AHB_M1 | DMA_ADR_INC | DMA_WIDTH_HALFWORD | + DMA_BSIZE_4 | DMA_REQUEST_LINE(0) | + DMA_DEV_BSIZE_NOT_CONFIGURABLE|DMA_DEV_WIDTH_NOT_CONFIGURABLE | + DMA_DEV_BOTH_DMACS_CANBE_USED ),}, + {.id = "saa1", + .config = ( DMA_AHB_M1 | DMA_ADR_INC | DMA_WIDTH_HALFWORD | + DMA_BSIZE_4 | DMA_REQUEST_LINE(1) | + DMA_DEV_BSIZE_NOT_CONFIGURABLE|DMA_DEV_WIDTH_NOT_CONFIGURABLE | + DMA_DEV_BOTH_DMACS_CANBE_USED ),}, + {.id = "saa2", + .config = ( DMA_AHB_M1 | DMA_ADR_INC | DMA_WIDTH_HALFWORD | + DMA_BSIZE_4 | DMA_REQUEST_LINE(2) | + DMA_DEV_BSIZE_NOT_CONFIGURABLE|DMA_DEV_WIDTH_NOT_CONFIGURABLE | + DMA_DEV_BOTH_DMACS_CANBE_USED ),}, + {.id = "saa3", + .config = ( DMA_AHB_M1 | DMA_ADR_INC | DMA_WIDTH_HALFWORD | + DMA_BSIZE_4 | DMA_REQUEST_LINE(3) | + DMA_DEV_BSIZE_NOT_CONFIGURABLE|DMA_DEV_WIDTH_NOT_CONFIGURABLE | + DMA_DEV_BOTH_DMACS_CANBE_USED ),}, + {.id = "saa4", + .config = ( DMA_AHB_M1 | DMA_ADR_INC | DMA_WIDTH_HALFWORD | + DMA_BSIZE_4 | DMA_REQUEST_LINE(4) | + DMA_DEV_BSIZE_NOT_CONFIGURABLE|DMA_DEV_WIDTH_NOT_CONFIGURABLE | + DMA_DEV_BOTH_DMACS_CANBE_USED ),}, + {.id = "saa5", + .config = ( DMA_AHB_M1 | DMA_ADR_INC | DMA_WIDTH_HALFWORD | + DMA_BSIZE_4 | DMA_REQUEST_LINE(5) | + DMA_DEV_BSIZE_NOT_CONFIGURABLE|DMA_DEV_WIDTH_NOT_CONFIGURABLE | + DMA_DEV_BOTH_DMACS_CANBE_USED ),}, + {.id = "saa6", + .config = ( DMA_AHB_M1 | DMA_ADR_INC | DMA_WIDTH_HALFWORD | + DMA_BSIZE_4 | DMA_REQUEST_LINE(6) | + DMA_DEV_BSIZE_NOT_CONFIGURABLE|DMA_DEV_WIDTH_NOT_CONFIGURABLE | + DMA_DEV_BOTH_DMACS_CANBE_USED ),}, + {.id = "saa7", + .config = ( DMA_AHB_M1 | DMA_ADR_INC | DMA_WIDTH_HALFWORD | + DMA_BSIZE_4 | DMA_REQUEST_LINE(7) | + DMA_DEV_BSIZE_NOT_CONFIGURABLE|DMA_DEV_WIDTH_NOT_CONFIGURABLE | + DMA_DEV_BOTH_DMACS_CANBE_USED ),}, +}; + +static struct dma_soc_data dma_data = { + .dirqdesc = irq_desc, + .config_tbl = dmadev_default_config_tbl, + .config_tbl_size = sizeof(dmadev_default_config_tbl)/ + sizeof(dmadev_default_config_tbl[0]), +}; + +void __init arch_dma_init(struct dma_t *dma) +{ + dma_data.dma_chan = dma; +}; + +static struct amba_device dma0_device = { + .dev = { + .bus_id = "DMA0", + .platform_data = &dma_data, + }, + .res = { + .start = NOMADIK_DMA0_BASE, + .end = NOMADIK_DMA0_BASE + SZ_64K - 1, + .flags = IORESOURCE_MEM, + }, + .irq = {IRQ_DMA0, NO_IRQ}, + .periphid = DMA_PER_ID, +}; + +static struct amba_device dma1_device = { + .dev = { + .bus_id = "DMA1", + .platform_data = &dma_data, + }, + .res = { + .start = NOMADIK_DMA1_BASE, + .end = NOMADIK_DMA1_BASE + SZ_64K - 1, + .flags = IORESOURCE_MEM, + }, + .irq = {IRQ_DMA1, NO_IRQ}, + .periphid = DMA_PER_ID, +}; + +#define NUM_SSP_CLIENTS 10 +#define SPI_BUS_NUMBER 2 + +static struct nmdk_spi_master_cntlr msp0_platform_data = { + .enable_dma = 1, + .id = MSP_0_CONTROLLER, + .num_chipselect = NUM_SSP_CLIENTS, + .base_addr = NOMADIK_MSP0_BASE, + .dma_srcaddr = NOMADIK_MSP0_BASE+MSP_TX_RX_REG_OFFSET, + .dma_srcdevtype = "msp0rx", + .dma_destaddr = NOMADIK_MSP0_BASE+MSP_TX_RX_REG_OFFSET, + .dma_destdevtype = "msp0tx", + .gpio_alt_func = GPIO_ALT_MSP_0, + .device_name = "msp0", +}; + +static struct amba_device msp0_device = { + .dev = { + .bus_id = "msp0", + .platform_data = &msp0_platform_data, + }, + .res = { + .start = NOMADIK_MSP0_BASE, + .end = NOMADIK_MSP0_BASE + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + .dma_mask = ~0, + .irq = {IRQ_MSP0, NO_IRQ}, + .periphid = MSP_PER_ID, +}; + +static struct nmdk_spi_master_cntlr msp1_platform_data = { + .enable_dma = 1, + .id = MSP_1_CONTROLLER, + .num_chipselect = NUM_SSP_CLIENTS, + .base_addr = NOMADIK_MSP1_BASE, + .dma_srcaddr = NOMADIK_MSP1_BASE+MSP_TX_RX_REG_OFFSET, + .dma_srcdevtype = "msp1rx", + .dma_destaddr = NOMADIK_MSP1_BASE+MSP_TX_RX_REG_OFFSET, + .dma_destdevtype = "msp1tx", + .gpio_alt_func = GPIO_ALT_MSP_1, + .device_name = "msp1", +}; + +static struct amba_device msp1_device = { + .dev = { + .bus_id = "msp1", + .platform_data = &msp1_platform_data, + }, + .res = { + .start = NOMADIK_MSP1_BASE, + .end = NOMADIK_MSP1_BASE + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + .dma_mask = ~0, + .irq = {IRQ_MSP1, NO_IRQ}, + .periphid = MSP_PER_ID, +}; + +static struct nmdk_spi_master_cntlr msp2_platform_data = { + .enable_dma = 1, + .id = MSP_2_CONTROLLER, + .num_chipselect = NUM_SSP_CLIENTS, + .base_addr = NOMADIK_MSP2_BASE, + .dma_srcaddr = NOMADIK_MSP2_BASE+MSP_TX_RX_REG_OFFSET, + .dma_srcdevtype = "msp2rx", + .dma_destaddr = NOMADIK_MSP2_BASE+MSP_TX_RX_REG_OFFSET, + .dma_destdevtype = "msp2tx", + .gpio_alt_func = GPIO_ALT_MSP_2, + .device_name = "msp2", +}; + +static struct amba_device msp2_device = { + .dev = { + .bus_id = "msp2", + .platform_data = &msp2_platform_data, + }, + .res = { + .start = NOMADIK_MSP2_BASE, + .end = NOMADIK_MSP2_BASE + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + .dma_mask = ~0, + .irq = {IRQ_MSP2, NO_IRQ}, + .periphid = MSP_PER_ID, +}; + +#if defined(CONFIG_NOMADIK_SSP) +static struct nmdk_spi_master_cntlr ssp_platform_data = { + .enable_dma = 1, + .id = SSP_CONTROLLER, + .num_chipselect = NUM_SSP_CLIENTS, + .base_addr = NOMADIK_SSP_BASE, + .dma_srcaddr = NOMADIK_SSP_BASE+SSP_TX_RX_REG_OFFSET, + .dma_srcdevtype = "ssprx", + .dma_destaddr = NOMADIK_SSP_BASE+SSP_TX_RX_REG_OFFSET, + .dma_destdevtype = "ssptx", + .gpio_alt_func = GPIO_ALT_SSP, + .device_name = "ssp", +}; + +static struct amba_device ssp_device = { + .dev = { + .bus_id = "ssp", + .platform_data = &ssp_platform_data, + }, + .res = { + .start = NOMADIK_SSP_BASE, + .end = NOMADIK_SSP_BASE + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + .dma_mask = ~0, + .irq = {IRQ_SSP, NO_IRQ}, + .periphid = SSP_PER_ID, +}; + +#endif +static struct amba_device *amba_devs[] __initdata = { + &gpio_device, + &rtc_device, + &uart0_device, + &uart1_device, + &clcd_device, + &mmc_device, + &dma0_device, + &dma1_device, +#if defined(CONFIG_NOMADIK_SSP) + &ssp_device, +#endif + &msp0_device, + &msp1_device, + &msp2_device, +}; + +struct clcd_fb *nomadik_get_paneltype(void) +{ + struct amba_device *dev = &clcd_device; + struct clcd_fb *fb = amba_get_drvdata(dev); + + return fb; +} + +unsigned int reg_virtual = 0; +irqreturn_t vert_int(int irq, void *x) +{ + volatile unsigned int *regp; + unsigned char src_id; + + if (unlikely(!reg_virtual)) { + printk("CLCD:Interrupt not handled\n"); + return IRQ_NONE; + } + /* Clear all interrupt bits */ + regp = (unsigned int *)(reg_virtual + CLCD_STAT); + *regp |= 0x1E; + + regp = (unsigned int *)(reg_virtual + CLCD_INTR); + src_id = (unsigned char)*regp; + if (src_id) + printk(KERN_ERR "CLCD:Error in clearing the interrupt\n"); + + return IRQ_HANDLED; +} + +int enable_vertical_synchro(void) +{ + int err; + volatile unsigned int *regp; + struct clcd_fb *fb = nomadik_get_paneltype();; + + reg_virtual = (unsigned int)fb->regs; + if (unlikely(!reg_virtual)) + return -EINVAL; + + err = request_irq(IRQ_CLCD_MDIF, vert_int, 0, "clcd-vertical-interrupt", 0); + if (err) { + printk(KERN_ERR "CLCD:Error! Failed to register IRQ %i\n", + IRQ_CLCD_MDIF); + return err; + } + + /* Set vertical IT event */ + regp = (unsigned int *)(reg_virtual + 0x01C); + *regp &= 0xffffcfff; + + /* Enable vertical synchro interrupts */ + regp = (unsigned int *)(reg_virtual + 0x18); + *regp |= 0x08; + + return 0; +} + +void disable_vertical_synchro(void) +{ + volatile unsigned int *regp; + + if (unlikely(!reg_virtual)) + return; + /* Disable vertical synchro interrupts */ + regp = (unsigned int *)(reg_virtual + 0x18); + *regp &= ~0x08; + + reg_virtual = 0; + + free_irq(IRQ_CLCD_MDIF, 0); + return; +} + +static int __init nomadik_init(void) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(amba_devs); i++) { + struct amba_device *d = amba_devs[i]; + amba_device_register(d, &iomem_resource); + } + return 0; +} + +arch_initcall(nomadik_init); + +/* + * SOC specific devices which are registered as platform devices + */ + +extern void __init nomadik_vic_init(void); +extern void nomadik_time_init(void); +extern unsigned long nomadik_gettimeoffset(void); + +static struct map_desc nomadik_io_desc[] __initdata = { + {IO_ADDRESS(NOMADIK_SRC_BASE), __phys_to_pfn(NOMADIK_SRC_BASE), SZ_4K, + MT_DEVICE}, + {IO_ADDRESS(NOMADIK_WDOG_BASE), __phys_to_pfn(NOMADIK_WDOG_BASE), SZ_4K, + MT_DEVICE}, + {IO_ADDRESS(NOMADIK_FSMC_BASE), __phys_to_pfn(NOMADIK_FSMC_BASE), SZ_4K, + MT_DEVICE}, + {IO_ADDRESS(NOMADIK_MTU0_BASE), __phys_to_pfn(NOMADIK_MTU0_BASE), SZ_4K, + MT_DEVICE}, + {IO_ADDRESS(NOMADIK_MTU1_BASE), __phys_to_pfn(NOMADIK_MTU1_BASE), SZ_4K, + MT_DEVICE}, + {IO_ADDRESS(NOMADIK_IC_BASE), __phys_to_pfn(NOMADIK_IC_BASE), SZ_4K, + MT_DEVICE}, + {IO_ADDRESS(NOMADIK_RTC_BASE), __phys_to_pfn(NOMADIK_RTC_BASE), SZ_4K, + MT_DEVICE}, + {IO_ADDRESS(NOMADIK_PMU_BASE), __phys_to_pfn(NOMADIK_PMU_BASE), SZ_4K, + MT_DEVICE}, + {IO_ADDRESS(NOMADIK_SSP_BASE), __phys_to_pfn(NOMADIK_SSP_BASE), SZ_4K, + MT_DEVICE}, + {IO_ADDRESS(NOMADIK_MSP0_BASE), __phys_to_pfn(NOMADIK_MSP0_BASE), SZ_4K, + MT_DEVICE}, + {IO_ADDRESS(NOMADIK_MSP1_BASE), __phys_to_pfn(NOMADIK_MSP1_BASE), SZ_4K, + MT_DEVICE}, + {IO_ADDRESS(NOMADIK_MSP2_BASE), __phys_to_pfn(NOMADIK_MSP2_BASE), SZ_4K, + MT_DEVICE}, + {IO_ADDRESS(NOMADIK_I2C0_BASE), __phys_to_pfn(NOMADIK_I2C0_BASE), SZ_4K, + MT_DEVICE}, + {IO_ADDRESS(NOMADIK_I2C1_BASE), __phys_to_pfn(NOMADIK_I2C1_BASE), SZ_4K, + MT_DEVICE}, + {IO_ADDRESS(NOMADIK_GPIO0_BASE), __phys_to_pfn(NOMADIK_GPIO0_BASE), + SZ_4K, MT_DEVICE}, + {IO_ADDRESS(NOMADIK_GPIO1_BASE), __phys_to_pfn(NOMADIK_GPIO1_BASE), + SZ_4K, MT_DEVICE}, + {IO_ADDRESS(NOMADIK_GPIO2_BASE), __phys_to_pfn(NOMADIK_GPIO2_BASE), + SZ_4K, MT_DEVICE}, + {IO_ADDRESS(NOMADIK_DMA0_BASE), __phys_to_pfn(NOMADIK_DMA0_BASE), SZ_4K, + MT_DEVICE}, + {IO_ADDRESS(NOMADIK_DMA1_BASE), __phys_to_pfn(NOMADIK_DMA1_BASE), SZ_4K, + MT_DEVICE}, + {IO_ADDRESS(NOMADIK_SSIRx_BASE), __phys_to_pfn(NOMADIK_SSIRx_BASE), + SZ_4K, MT_DEVICE}, + {IO_ADDRESS(NOMADIK_SSITx_BASE), __phys_to_pfn(NOMADIK_SSITx_BASE), + SZ_4K, MT_DEVICE}, + {IO_ADDRESS(NOMADIK_CLCDC_BASE), __phys_to_pfn(NOMADIK_CLCDC_BASE), + SZ_4K, MT_DEVICE}, + {IO_ADDRESS(NOMADIK_SDRAMC_BASE), __phys_to_pfn(NOMADIK_SDRAMC_BASE), + SZ_4K, MT_DEVICE}, + SOC_IO_DESC BOARD_IO_DESC +}; + +static void __init nomadik_map_io(void) +{ + iotable_init(nomadik_io_desc, ARRAY_SIZE(nomadik_io_desc)); +} + +static struct resource nomadik_i2c_0_resources[] = { + [0] = { + .start = NOMADIK_I2C0_BASE, + .end = NOMADIK_I2C0_BASE + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_I2C0, + .end = IRQ_I2C0, + .flags = IORESOURCE_IRQ} +}; + +static struct resource nomadik_i2c_1_resources[] = { + [0] = { + .start = NOMADIK_I2C1_BASE, + .end = NOMADIK_I2C1_BASE + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_I2C1, + .end = IRQ_I2C1, + .flags = IORESOURCE_IRQ} +}; + +static struct platform_device nomadik_i2c_0_controller = { + .name = "NOMADIK-I2C", + .id = 0, + .num_resources = 2, + .resource = nomadik_i2c_0_resources +}; + +static struct platform_device nomadik_i2c_1_controller = { + .name = "NOMADIK-I2C", + .id = 1, + .num_resources = 2, + .resource = nomadik_i2c_1_resources +}; + +static struct resource nomadik_saa_resources[] = { + [0] = { + .name = "saa-data-mem", + .start = NOMADIK_HAMACA_DMEM, + .end = (NOMADIK_HAMACA_DMEM + SZ_1M - 1), + .flags = IORESOURCE_MEM, + }, + + [1] = { + .name = "saa-irq0", + .start = IRQ_SAA_IT0, + .end = IRQ_SAA_IT0, + .flags = IORESOURCE_IRQ, + }, + + [2] = { + .name = "saa-irq1", + .start = IRQ_SAA_IT1, + .end = IRQ_SAA_IT1, + .flags = IORESOURCE_IRQ, + }, +}; + +#ifdef CONFIG_NOMADIK_SAA_INIT_MEM + +dma_addr_t saa_init_physical_address; +void *saa_init_logical_address; + +dma_addr_t saa_get_physical_address(void) +{ + return saa_init_physical_address; +} + +void* saa_get_logical_address(void) +{ + return saa_init_logical_address; +} +EXPORT_SYMBOL(saa_get_physical_address); +EXPORT_SYMBOL(saa_get_logical_address); + +#endif + +static struct platform_device nomadik_saa_device = { + .name = "saa", + .id = 0, + .num_resources = ARRAY_SIZE(nomadik_saa_resources), + .resource = nomadik_saa_resources, +}; + +static struct resource nomadik_sva_resources[] = { + [0] = { + .name = "sva-reg-mem", + .start = NOMADIK_HAMACV_REG_BASE, + .end = NOMADIK_HAMACV_REG_END, + .flags = IORESOURCE_MEM, + }, + [1] = { + .name = "sva-data-mem", + .start = NOMADIK_HAMACV_DMEM_BASE, + .end = NOMADIK_HAMACV_DMEM_END, + .flags = IORESOURCE_MEM, + }, + [2] = { + .name = "sva-esram-mem", + .start = NOMADIK_ESRAM_BASE, + .end = NOMADIK_ESRAM_END, + .flags = IORESOURCE_MEM, + }, + [3] = { + .name = "sva-irq0", + .start = IRQ_SVA_IT0, + .end = IRQ_SVA_IT0, + .flags = IORESOURCE_IRQ, + }, + + [4] = { + .name = "sva-irq1", + .start = IRQ_SVA_IT1, + .end = IRQ_SVA_IT1, + .flags = IORESOURCE_IRQ, + }, +}; + +struct sva_board sva_data = { + .get_paneltype = nomadik_get_paneltype, + .camera_init = NULL, + .camera_deinit = NULL, + .denc_init = NULL, + .denc_deinit = NULL, + .enable_synchro = enable_vertical_synchro, + .disable_synchro = disable_vertical_synchro, + .init_bus_address = 0UL, + .init_logical_address = 0UL, +}; + +static struct platform_device nomadik_sva_device = { + .name = "SVA", + .id = 0, + .num_resources = ARRAY_SIZE(nomadik_sva_resources), + .resource = nomadik_sva_resources, + .dev = { + .coherent_dma_mask = 0xffffffffUL, + .platform_data = &sva_data, + }, +}; + +static struct platform_device *core_devices[] __initdata = { + &nomadik_i2c_0_controller, + &nomadik_i2c_1_controller, + &nomadik_saa_device, + &nomadik_sva_device +}; + +static void __init nomadik_platform_init_irq(void) +{ + nomadik_vic_init(); + printk("%s done\n", (__FUNCTION__)); +} + +extern void add_nmdk_platform_devices(void); + +static void __init nomadik_platform_init(void) +{ + __u32 address; + +#ifdef CONFIG_NOMADIK_SVA_INIT_MEM + + unsigned long gfp_address = 0; + + gfp_address = __get_free_pages(GFP_KERNEL, get_order(CONFIG_NOMADIK_SVA_MEM_SIZE * SZ_1M)); + if(gfp_address) { + sva_data.init_bus_address = (__u32) gfp_address - PAGE_OFFSET; + sva_data.init_logical_address = ioremap(sva_data.init_bus_address, + CONFIG_NOMADIK_SVA_MEM_SIZE * SZ_1M); + } + if(!sva_data.init_logical_address) { + printk(KERN_ERR"SVA driver %d MB memory boot memory allocation failed\n",CONFIG_NOMADIK_SVA_MEM_SIZE); + + } + +#endif + + platform_add_devices(core_devices, ARRAY_SIZE(core_devices)); + +#ifdef CONFIG_NOMADIK_SAA_INIT_MEM + saa_init_logical_address = + dma_alloc_coherent(NULL, SAA_HCL_INIT_MEM_SIZE, + &saa_init_physical_address, GFP_KERNEL); +#endif + + address = (__u32 ) IO_ADDRESS(NOMADIK_SDRAMC_BASE); + if(address) { + /* Configure SDRAMC port timeouts for 201000 MHz */ + *(__u32 *)(address + 0x408) = 0x00000004; + *(__u32 *)(address + 0x428) = 0x0000000d; + *(__u32 *)(address + 0x448) = 0x00000029; + *(__u32 *)(address + 0x468) = 0x00000029; + *(__u32 *)(address + 0x488) = 0x0000001D; + *(__u32 *)(address + 0x4A8) = 0x0000001D; + } + + + add_nmdk_platform_devices(); +} + +extern struct sys_timer nomadik_timer; + +MACHINE_START(NOMADIK, CONFIG_NOMADIK_TARGET ) + /* Maintainer: ST MicroElectronics */ + .phys_io = NOMADIK_UART0_BASE, + .io_pg_offst = (IO_ADDRESS(NOMADIK_UART0_BASE) >> 18) & 0xfffc, + .boot_params = 0x00000100,.map_io = nomadik_map_io, + .init_irq = nomadik_platform_init_irq, + .timer = &nomadik_timer, + .init_machine = nomadik_platform_init, +MACHINE_END + --- /dev/null +++ linux-2.6.20/arch/arm/mach-nomadik/stn8815_devices.c @@ -0,0 +1,1971 @@ +/*--------------------------------------------------------------------------------------------------*/ +/*© copyright STMicroelectronics, 2007. */ +/* */ +/*This program is free software; you can redistribute it and/or modify it under */ +/*the terms of the GNU General Public License as published by the Free */ +/*Software Foundation; either version 2.1 of the License, or (at your option) */ +/*any later version. */ +/* */ +/*This program is distributed in the hope that it will be useful, but WITHOUT */ +/*ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU General Public License for more details. */ +/* */ +/*You should have received a copy of the GNU General Public License */ +/*along with this program. If not, see . */ +/*--------------------------------------------------------------------------------------------------*/ + + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +extern struct irq_desc irq_desc[]; /* required for dma.c */ + +/* + * CLCD support + */ +static struct clcd_panel nmdk_clcd_panel = { + .mode = { + .name = CONFIG_FB_NOMADIK_PANEL_NAME, + .refresh = 60, + .xres = CONFIG_FB_NOMADIK_PANEL_XRES, + .yres = CONFIG_FB_NOMADIK_PANEL_YRES, + .pixclock = 40000, + .left_margin = CONFIG_FB_NOMADIK_PANEL_LFMARGIN, + .right_margin = CONFIG_FB_NOMADIK_PANEL_RTMARGIN, + .upper_margin = CONFIG_FB_NOMADIK_PANEL_UPRMARGIN, + .lower_margin = CONFIG_FB_NOMADIK_PANEL_LWRMARGIN, + .hsync_len = CONFIG_FB_NOMADIK_PANEL_HSLEN, + .vsync_len = CONFIG_FB_NOMADIK_PANEL_VSLEN, + .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, + .vmode = FB_VMODE_NONINTERLACED, + }, + .width = -1, + .height = -1, + .tim2 = CONFIG_FB_NOMADIK_PANEL_TIM2VAL, + .tim3 = 0x00000000, /* done for ndk15 */ +#if !defined (CONFIG_NOMADIK_NHK15) + .cntl = + CNTL_LCDTFT | CNTL_LCDVCOMP(1) | CNTL_1XBPP_15 | CNTL_CDWID_18 | + CNTL_WATERMARK /*| CNTL_BGR */ , +#else + #define CNTL_CDWID_24 (3 << 19) + #define CNTL_LCDBPP24_P (6 << 1) + +#if CONFIG_FB_NOMADIK_PANEL_BPP == 24 + .cntl = + CNTL_LCDTFT | CNTL_LCDVCOMP(1) | CNTL_CDWID_24 | CNTL_LCDBPP24_P | + CNTL_WATERMARK /*| CNTL_BGR */ , + +#elif CONFIG_FB_NOMADIK_PANEL_BPP == 16 + .cntl = + CNTL_LCDTFT | CNTL_LCDVCOMP(1) | CNTL_CDWID_24 | CNTL_LCDBPP16 | + CNTL_WATERMARK | CNTL_1XBPP_15, +#elif CONFIG_FB_NOMADIK_PANEL_BPP == 8 + .cntl = + CNTL_LCDTFT | CNTL_LCDVCOMP(1) | CNTL_CDWID_24 | CNTL_LCDBPP8 | + CNTL_WATERMARK, +#elif CONFIG_FB_NOMADIK_PANEL_BPP == 32 + .cntl = + CNTL_LCDTFT | CNTL_LCDVCOMP(1) | CNTL_CDWID_24 | CNTL_LCDBPP24 | + CNTL_WATERMARK, +#endif +#endif + .bpp = CONFIG_FB_NOMADIK_PANEL_BPP, + .grayscale = 0, +}; + +#define FB_SIZE (CONFIG_FB_NOMADIK_PANEL_BPP * \ + CONFIG_FB_NOMADIK_PANEL_XRES * \ + CONFIG_FB_NOMADIK_PANEL_YRES / 8) + +/* Additional offscreen memory is reserved for Graphics requirement */ +#define FRAMESIZE (FB_SIZE + (FB_SIZE*2/3)) + +static unsigned long framesize = (FRAMESIZE+PAGE_SIZE-1)/PAGE_SIZE*PAGE_SIZE; + +static int nomadik_clcd_setup(struct clcd_fb *fb) +{ + dma_addr_t dma; + + nomadik_gpio_altfuncenable(GPIO_ALT_LCD_PANEL, "CLCD"); + fb->panel = &nmdk_clcd_panel; + fb->fb.screen_base = dma_alloc_coherent(&fb->dev->dev, framesize, + &dma, GFP_KERNEL | GFP_DMA); + if (!fb->fb.screen_base) { + printk(KERN_ERR "CLCD: unable to map framebuffer\n"); + return -ENOMEM; + } + fb->fb.fix.smem_start = dma; + fb->fb.fix.smem_len = framesize; + + + return 0; +} + +static void nomadik_clcd_remove(struct clcd_fb *fb) +{ + dma_free_coherent(&fb->dev->dev, fb->fb.fix.smem_len, + fb->fb.screen_base, fb->fb.fix.smem_start); + +} + +static int nomadik_clcd_mmap(struct clcd_fb *fb, struct vm_area_struct *vma) +{ + return dma_mmap_coherent(&fb->dev->dev, vma, + fb->fb.screen_base, + fb->fb.fix.smem_start, fb->fb.fix.smem_len); +} + +/* platform specific code from _devices.c */ +extern void nomadik_clcd_enable(struct clcd_fb *); +extern void nomadik_clcd_disable(struct clcd_fb *); + +static struct clcd_board clcd_data = { + .name = "Nomadik", + .check = clcdfb_check, + .decode = clcdfb_decode, + .enable = nomadik_clcd_enable, + .disable = nomadik_clcd_disable, + .setup = nomadik_clcd_setup, + .mmap = nomadik_clcd_mmap, + .remove = nomadik_clcd_remove, +}; + + + +/* + * GPIO............... + */ +#define GPIO_NAME "GPIO" + +#ifndef GPIO_DEBUG +#define GPIO_DEBUG 0 +#endif + +#define NMDK_DEBUG GPIO_DEBUG /* enables/disables nmdk_dbg msgs */ +#define NMDK_DEBUG_PFX GPIO_NAME /* msg header represents this module */ +#define NMDK_DBG KERN_ERR /* message level */ + +void nomadik_gpio_intrwake(struct gpio_register *bnkptr, uint32 mask, + uint32 type) +{ + nmdk_dbg_ftrace(); + switch (type & SA_TRIGGER_MASK) { + case SA_TRIGGER_RISING: + bnkptr->gpio_rwimsc |= mask; + bnkptr->gpio_fwimsc &= ~mask; + break; + case SA_TRIGGER_FALLING: + bnkptr->gpio_rwimsc &= ~mask; + bnkptr->gpio_fwimsc |= mask; + break; + case (SA_TRIGGER_FALLING | SA_TRIGGER_RISING): + bnkptr->gpio_rwimsc |= mask; + bnkptr->gpio_fwimsc |= mask; + break; + case SA_TRIGGER_LOW: + case SA_TRIGGER_HIGH: + nmdk_error("wakeup mode %d not supported", (int)type); + break; + default: /* used to disable wakeup */ + bnkptr->gpio_rwimsc &= mask; + bnkptr->gpio_fwimsc &= mask; + break; + } +} + +void nomadik_gpio_intren(struct gpio_register *bnkptr, uint32 mask, uint32 type) +{ + nmdk_dbg_ftrace(); + switch (type & SA_TRIGGER_MASK) { + case SA_TRIGGER_RISING: + bnkptr->gpio_rimsc |= mask; + bnkptr->gpio_fimsc &= ~mask; + nmdk_dbg2("%s rising edge\n", __FUNCTION__); + break; + case SA_TRIGGER_FALLING: + bnkptr->gpio_rimsc &= ~mask; + bnkptr->gpio_fimsc |= mask; + nmdk_dbg2("%s falling edge\n", __FUNCTION__); + break; + case (SA_TRIGGER_FALLING | SA_TRIGGER_RISING): + bnkptr->gpio_rimsc |= mask; + bnkptr->gpio_fimsc |= mask; + nmdk_dbg2("%s both edge\n", __FUNCTION__); + break; + case SA_TRIGGER_LOW: + case SA_TRIGGER_HIGH: + nmdk_error("Interuupt modes not supported"); + break; + } +} + +void nomadik_gpio_intrdis(struct gpio_register *bnkptr, uint32 mask) +{ + nmdk_dbg_ftrace(); + bnkptr->gpio_rimsc &= ~mask; + bnkptr->gpio_fimsc &= ~mask; +} + +void nomadik_gpio_rstpin(struct gpio_register *bnkptr, uint32 mask) +{ + nmdk_dbg_ftrace(); + bnkptr->gpio_ic |= mask; /*Clear interrupt. */ + bnkptr->gpio_rimsc &= ~mask; + bnkptr->gpio_fimsc &= ~mask; + bnkptr->gpio_afsa &= ~mask; /*set mode to gpio. */ + bnkptr->gpio_afsb &= ~mask; + bnkptr->gpio_dirs = mask; /*clear data on gpio line & configure to input */ + bnkptr->gpio_datc = mask; + bnkptr->gpio_dirc = mask; /* and GPIO_DIR for gpio_dirc */ + bnkptr->gpio_pdis &= ~mask; /*pull-up or pull-down enable. */ + bnkptr->gpio_slpm &= ~mask; /*gpio pin is switched to input in sleep mode. */ + bnkptr->gpio_rwimsc &= ~mask; /*wakeup is not enabled. */ + bnkptr->gpio_fwimsc &= ~mask; + bnkptr->gpio_ic &= ~mask; +} + +static struct gpio_altfun_data gpio_altfun_tbl[] = { + {.altfun = GPIO_ALT_UART_0_MODEM,.start = 0,.end = 2,.cont = 1,.type = + GPIO_ALTF_A,}, + {.altfun = GPIO_ALT_UART_0_MODEM,.start = 7,.end = 7,.cont = 0,.type = + GPIO_ALTF_A,}, + {.altfun = GPIO_ALT_UART_1,.start = 51,.end = 52,.cont = 1,.type = + GPIO_ALTF_A,}, + {.altfun = GPIO_ALT_UART_1,.start = 56,.end = 57,.cont = 0,.type = + GPIO_ALTF_A,}, + {.altfun = GPIO_ALT_UART_2,.start = 36,.end = 39,.cont = 0,.type = + GPIO_ALTF_A,}, + {.altfun = GPIO_ALT_I2C_0,.start = 62,.end = 63,.cont = 0,.type = + GPIO_ALTF_A,}, + {.altfun = GPIO_ALT_I2C_1,.start = 53,.end = 54,.cont = 0,.type = + GPIO_ALTF_A,}, + {.altfun = GPIO_ALT_MSP_0,.start = 17,.end = 22,.cont = 0,.type = + GPIO_ALTF_A,}, + {.altfun = GPIO_ALT_MSP_1,.start = 36,.end = 39,.cont = 0,.type = + GPIO_ALTF_B,}, + {.altfun = GPIO_ALT_MSP_2,.start = 64,.end = 67,.cont = 0,.type = + GPIO_ALTF_C,}, + {.altfun = GPIO_ALT_SSP,.start = 58,.end = 61,.cont = 0,.type = + GPIO_ALTF_A,}, + {.altfun = GPIO_ALT_MM_CARD,.start = 8,.end = 10,.cont = 1,.type = + GPIO_ALTF_A,}, + {.altfun = GPIO_ALT_MM_CARD,.start = 14,.end = 16,.cont = 0,.type = + GPIO_ALTF_A,}, + {.altfun = GPIO_ALT_SD_CARD,.start = 8,.end = 16,.cont = 1,.type = + GPIO_ALTF_A,}, + {.altfun = GPIO_ALT_SD_CARD,.start = 23,.end = 23,.cont = 1,.type = + GPIO_ALTF_B,}, + {.altfun = GPIO_ALT_SD_CARD,.start = 24,.end = 24,.cont = 0,.type = + GPIO_ALTF_A,}, + {.altfun = GPIO_ALT_DMA_0,.start = 36,.end = 37,.cont = 0,.type = + GPIO_ALTF_C,}, + {.altfun = GPIO_ALT_DMA_1,.start = 38,.end = 39,.cont = 0,.type = + GPIO_ALTF_C,}, + {.altfun = GPIO_ALT_HSI0,.start = 77,.end = 82,.cont = 0,.type = + GPIO_ALTF_B,}, + {.altfun = GPIO_ALT_CCIR656_INPUT,.start = 48,.end = 48,.cont = + 1,.type = GPIO_ALTF_A,}, + {.altfun = GPIO_ALT_CCIR656_INPUT,.start = 50,.end = 50,.cont = + 1,.type = GPIO_ALTF_A,}, + {.altfun = GPIO_ALT_CCIR656_INPUT,.start = 83,.end = 90,.cont = + 0,.type = GPIO_ALTF_A,}, + {.altfun = GPIO_ALT_CCIR656_OUTPUT,.start = 48,.end = 48,.cont = + 1,.type = GPIO_ALTF_B,}, + {.altfun = GPIO_ALT_CCIR656_OUTPUT,.start = 83,.end = 90,.cont = + 0,.type = GPIO_ALTF_B,}, +#if defined(CONFIG_NOMADIK_NHK15) + /*added for ETM*/ + {.altfun = GPIO_ALT_ETM,.start = 51,.end = 55,.cont = 1,.type = + GPIO_ALTF_A,}, + {.altfun = GPIO_ALT_ETM,.start = 83,.end = 95,.cont = 0,.type = + GPIO_ALTF_A,}, + /**/ +#endif + {.altfun = GPIO_ALT_LCD_PANEL,.start = 32,.end = 39,.cont = 0,.type = + GPIO_ALTF_B,}, + {.altfun = GPIO_ALT_MDIF,.start = 32,.end = 33,.cont = 0,.type = + GPIO_ALTF_B,}, + {.altfun = GPIO_ALT_HAMAC_AUDIO_DBG,.start = 40,.end = 47,.cont = + 1,.type = GPIO_ALTF_B,}, + {.altfun = GPIO_ALT_HAMAC_AUDIO_DBG,.start = 62,.end = 62,.cont = + 0,.type = GPIO_ALTF_C,}, + {.altfun = GPIO_ALT_HAMAC_VIDEO_DBG,.start = 40,.end = 47,.cont = + 1,.type = GPIO_ALTF_A,}, + {.altfun = GPIO_ALT_HAMAC_VIDEO_DBG,.start = 62,.end = 62,.cont = + 0,.type = GPIO_ALTF_A,}, + {.altfun = GPIO_ALT_CLOCK_RESET,.start = 25,.end = 26,.cont = 1,.type = + GPIO_ALTF_A,}, + {.altfun = GPIO_ALT_CLOCK_RESET,.start = 55,.end = 56,.cont = 0,.type = + GPIO_ALTF_A,}, + {.altfun = GPIO_ALT_TSP,.start = 91,.end = 95,.cont = 0,.type = + GPIO_ALTF_A,}, + {.altfun = GPIO_ALT_IRDA,.start = 28,.end = 29,.cont = 0,.type = + GPIO_ALTF_A,}, + {.altfun = GPIO_ALT_USB_MINIMUM,.start = 68,.end = 74,.cont = 0,.type = + GPIO_ALTF_A,}, + {.altfun = GPIO_ALT_USB_I2C,.start = 68,.end = 74,.cont = 0,.type = + GPIO_ALTF_B,}, + {.altfun = GPIO_ALT_OWM,.start = 76,.end = 76,.cont = 0,.type = + GPIO_ALTF_A,}, + {.altfun = GPIO_ALT_PWL,.start = 75,.end = 75,.cont = 0,.type = + GPIO_ALTF_A,}, + {.altfun = GPIO_ALT_FSMC,.start = 30,.end = 30,.cont = 0,.type = + GPIO_ALTF_A,}, + {.altfun = GPIO_ALT_SRAM_NOR_FLASH,.start = 64,.end = 67,.cont = + 0,.type = GPIO_ALTF_B,}, + {.altfun = GPIO_ALT_COMP_FLASH,.start = 64,.end = 67,.cont = 1,.type = + GPIO_ALTF_C,}, + {.altfun = GPIO_ALT_COMP_FLASH,.start = 31,.end = 31,.cont = 1,.type = + GPIO_ALTF_C,}, + {.altfun = GPIO_ALT_COMP_FLASH,.start = 27,.end = 27,.cont = 0,.type = + GPIO_ALTF_C,}, + {.altfun = GPIO_ALT_USB_OTG,.start = 26,.end = 27,.cont = 1,.type = + GPIO_ALTF_C,}, + {.altfun = GPIO_ALT_USB_OTG,.start = 30,.end = 31,.cont = 1,.type = + GPIO_ALTF_C,}, + {.altfun = GPIO_ALT_USB_OTG,.start = 68,.end = 75,.cont = 0,.type = GPIO_ALTF_C,}, /*68,75TBC */ + {.altfun = GPIO_ALT_FSMC_ADDLINE_0_TO_15,.start = 48,.end = 50,.cont = + 1,.type = GPIO_ALTF_A,}, + {.altfun = GPIO_ALT_FSMC_ADDLINE_0_TO_15,.start = 83,.end = 95,.cont = + 0,.type = GPIO_ALTF_A,}, + {.altfun = GPIO_ALT_SCROLL_KEY,.start = 6,.end = 3,.cont = 0,.type = + GPIO_ALTF_B,}, + {.altfun = GPIO_ALT_MSHC,.start = 24,.end = 24,.cont = 1,.type = + GPIO_ALTF_B,}, + {.altfun = GPIO_ALT_MSHC,.start = 16,.end = 8,.cont = 0,.type = + GPIO_ALTF_B,}, + {.altfun = GPIO_ALT_HPI,.start = 95,.end = 91,.cont = 1,.type = + GPIO_ALTF_B,}, + {.altfun = GPIO_ALT_HPI,.start = 61,.end = 56,.cont = 0,.type = + GPIO_ALTF_B,}, +/* GPIO[54:51,47:40 TBC] */ + {.altfun = GPIO_ALT_USB_OTG,.start = 74,.end = 68,.cont = 1,.type = + GPIO_ALTF_C,}, + {.altfun = GPIO_ALT_USB_OTG,.start = 31,.end = 30,.cont = 1,.type = + GPIO_ALTF_C,}, + {.altfun = GPIO_ALT_USB_OTG,.start = 27,.end = 26,.cont = 0,.type = + GPIO_ALTF_C,}, + {.altfun = GPIO_ALT_SDIO,.start = 24,.end = 23,.cont = 1,.type = + GPIO_ALTF_A,}, + {.altfun = GPIO_ALT_SDIO,.start = 16,.end = 8,.cont = 0,.type = + GPIO_ALTF_B,}, /*TBC*/ {.altfun = GPIO_ALT_HSMMC,.start = 31,.end = + 30,.cont = 1,.type = GPIO_ALTF_A,}, + {.altfun = GPIO_ALT_HSMMC,.start = 27,.end = 26,.cont = 1,.type = + GPIO_ALTF_A,}, + {.altfun = GPIO_ALT_HSMMC,.start = 16,.end = 8,.cont = 0,.type = + GPIO_ALTF_B,}, /*TBC*/ {.altfun = + GPIO_ALT_FSMC_ADD_DATA_0_TO_25,.start = + 118,.end = 110,.cont = 1,.type = GPIO_ALTF_B,}, + {.altfun = GPIO_ALT_FSMC_ADD_DATA_0_TO_25,.start = 107,.end = + 107,.cont = 1,.type = GPIO_ALTF_B,}, + {.altfun = GPIO_ALT_FSMC_ADD_DATA_0_TO_25,.start = 103,.end = 96,.cont = + 0,.type = GPIO_ALTF_B,}, + {.altfun = GPIO_ALT_HSI1,.start = 103,.end = 101,.cont = 1,.type = + GPIO_ALTF_B,}, + {.altfun = GPIO_ALT_HSI1,.start = 98,.end = 96,.cont = 0,.type = + GPIO_ALTF_B,}, + {.altfun = GPIO_ALT_NOR,.start = 109,.end = 108,.cont = 1,.type = + GPIO_ALTF_B,}, + {.altfun = GPIO_ALT_NOR,.start = 106,.end = 104,.cont = 0,.type = + GPIO_ALTF_B,}, + {.altfun = GPIO_ALT_NAND,.start = 123,.end = 119,.cont = 0,.type = + GPIO_ALTF_B,}, + {.altfun = GPIO_ALT_KEYPAD,.start = 115,.end = 108,.cont = 0,.type = + GPIO_ALTF_B,}, +#if !defined (CONFIG_NOMADIK_NHK15) + {.altfun = GPIO_ALT_VPIP,.start = 76,.end = 76,.cont = 1,.type = + GPIO_ALTF_B,}, + {.altfun = GPIO_ALT_VPIP,.start = 109,.end = 109,.cont = 0,.type = + GPIO_ALTF_B,}, +#else + {.altfun = GPIO_ALT_VPIP,.start = 53,.end = 53,.cont = 1,.type = + GPIO_ALTF_B,}, + {.altfun = GPIO_ALT_VPIP,.start = 54,.end = 54,.cont = 0,.type = + GPIO_ALTF_B,}, +#endif + {.altfun = GPIO_ALT_CAM,.start = 25,.end = 25,.cont = 0,.type = + GPIO_ALTF_A,}, + {.altfun = GPIO_ALT_CCP1,.start = 3,.end = 6,.cont = 0,.type= + GPIO_ALTF_C,}, +#ifdef CONFIG_MTD_ONENAND + {.altfun = GPIO_ALT_ONENAND,.start = 96,.end = 103,.cont = 1,.type = + GPIO_ALTF_A,}, + + {.altfun = GPIO_ALT_ONENAND,.start = 105,.end = 108,.cont = 1,.type = + GPIO_ALTF_A,}, + + {.altfun = GPIO_ALT_ONENAND,.start = 121,.end = 123,.cont = 0,.type = + GPIO_ALTF_A,}, +#endif +}; + +static struct gpio_soc gpio_socdata = { + .altfun_tbl = gpio_altfun_tbl, + .sz_altfun_tbl = sizeof(gpio_altfun_tbl) / sizeof(gpio_altfun_tbl[0]), + .irqwake = nomadik_gpio_intrwake, + .irqen = nomadik_gpio_intren, + .irqdis = nomadik_gpio_intrdis, + .rstpin = nomadik_gpio_rstpin, +}; + +static struct amba_device gpio_device = { + .dev = { + .bus_id = "gpio", + .platform_data = &gpio_socdata, + }, + .res = { + .start = NOMADIK_GPIO0_BASE, + .end = NOMADIK_GPIO0_BASE + (SZ_4K * 4) - 1, + .flags = IORESOURCE_MEM, + }, + .irq = {IRQ_GPIO0, (IRQ_GPIO0 + 4)}, /*second param tells no of gpio banks */ + .periphid = GPIO_PER_ID, +}; + +static struct amba_device rtc_device = { + .dev = { + .bus_id = "mb:15", + }, + .res = { + .start = NOMADIK_RTC_BASE, + .end = NOMADIK_RTC_BASE + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + .irq = {IRQ_RTC_RTT, NO_IRQ}, + .periphid = RTC_PER_ID, +}; + +static struct amba_device uart0_device = { + .dev = { + .bus_id = "mb:16", + }, + .res = { + .start = NOMADIK_UART0_BASE, + .end = NOMADIK_UART0_BASE + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + .irq = {IRQ_UART0, NO_IRQ}, + .periphid = UART_PER_ID, +}; + +static struct amba_device uart1_device = { + .dev = { + .bus_id = "mb:17", + }, + .res = { + .start = NOMADIK_UART1_BASE, + .end = NOMADIK_UART1_BASE + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + .irq = {IRQ_UART1, NO_IRQ}, + .periphid = UART_PER_ID, +}; + +extern int nomadik_mmc_configure(struct amba_device *dev); +extern void nomadik_mmc_restore_default(struct amba_device *dev); + +static struct mmc_board mmc_data = { + .init = nomadik_mmc_configure, + .exit = nomadik_mmc_restore_default, +}; + +static struct amba_device mmc_device = { + .dev = { + .bus_id = "MMC", + .platform_data = &mmc_data, + }, + .res = { + .start = NOMADIK_SDI_BASE, + .end = NOMADIK_SDI_BASE + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + .irq = {IRQ_SDMMC, IRQNO_GPIO(MMCDETECT_IRQ)}, + .periphid = SDI_PER_ID, +}; + +static struct amba_device clcd_device = { + .dev = { + .bus_id = "mb:c0", + .coherent_dma_mask = ~0, + .platform_data = &clcd_data, + }, + .res = { + .start = NOMADIK_CLCDC_BASE, + .end = NOMADIK_CLCDC_BASE + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + .dma_mask = ~0, + .irq = {IRQ_CLCD_MDIF, NO_IRQ}, + .periphid = CLCD_PER_ID, +}; + +/** + * dmadev_default_config_tbl - Deffault dma device configuration table + * To support new dmadevice, add new default confiuration to this table + * refer /Documentation/arm/STM-Nomadik/dma_user_guide.txt for the same + */ +static struct dmadev_description dmadev_default_config_tbl[] = { + {.id = "mem", + .config = ( DMA_AHB_M1 | DMA_ADR_INC | DMA_WIDTH_WORD | + DMA_BSIZE_4 | DMA_REQUEST_LINE(31) | + DMA_DEV_BSIZE_CONFIGURABLE | DMA_DEV_WIDTH_CONFIGURABLE | + DMA_DEV_BOTH_DMACS_CANBE_USED ),}, + {.id = "sdmmc", + .config = ( DMA_AHB_M0 | DMA_ADR_NOINC | DMA_WIDTH_WORD | + DMA_BSIZE_8 | DMA_REQUEST_LINE(21) | + DMA_DEV_BSIZE_CONFIGURABLE | DMA_DEV_WIDTH_CONFIGURABLE | + DMA_DEV_DMAC1_CANBE_USED ),}, + {.id = "ssptx", + .config = ( DMA_AHB_M0 | DMA_ADR_NOINC | DMA_WIDTH_WORD | + DMA_BSIZE_4 | DMA_REQUEST_LINE(13) | + DMA_DEV_BSIZE_CONFIGURABLE | DMA_DEV_WIDTH_CONFIGURABLE | + DMA_DEV_BOTH_DMACS_CANBE_USED ),}, + {.id = "ssprx", + .config = ( DMA_AHB_M0 | DMA_ADR_NOINC | DMA_WIDTH_WORD | + DMA_BSIZE_4 | DMA_REQUEST_LINE(12) | + DMA_DEV_BSIZE_CONFIGURABLE | DMA_DEV_WIDTH_CONFIGURABLE | + DMA_DEV_BOTH_DMACS_CANBE_USED ),}, + {.id = "msp0tx", + .config = ( DMA_AHB_M0 | DMA_ADR_NOINC | DMA_WIDTH_WORD | + DMA_BSIZE_4 | DMA_REQUEST_LINE(11) | + DMA_DEV_WIDTH_CONFIGURABLE | DMA_DEV_BSIZE_NOT_CONFIGURABLE | + DMA_DEV_BOTH_DMACS_CANBE_USED ),}, + {.id = "msp0rx", + .config = ( DMA_AHB_M0 | DMA_ADR_NOINC | DMA_WIDTH_WORD | + DMA_BSIZE_4 | DMA_REQUEST_LINE(10) | + DMA_DEV_WIDTH_CONFIGURABLE | DMA_DEV_BSIZE_NOT_CONFIGURABLE | + DMA_DEV_BOTH_DMACS_CANBE_USED ),}, + {.id = "msp1tx", + .config = ( DMA_AHB_M0 | DMA_ADR_NOINC | DMA_WIDTH_WORD | + DMA_BSIZE_4 | DMA_REQUEST_LINE(31) | + DMA_DEV_WIDTH_CONFIGURABLE | DMA_DEV_BSIZE_NOT_CONFIGURABLE | + DMA_DEV_DMAC0_CANBE_USED ),}, + {.id = "msp1rx", + .config = ( DMA_AHB_M0 | DMA_ADR_NOINC | DMA_WIDTH_WORD | + DMA_BSIZE_4 | DMA_REQUEST_LINE(30) | + DMA_DEV_WIDTH_CONFIGURABLE | DMA_DEV_BSIZE_NOT_CONFIGURABLE | + DMA_DEV_DMAC0_CANBE_USED ),}, + {.id = "msp2tx", + .config = ( DMA_AHB_M0 | DMA_ADR_NOINC | DMA_WIDTH_WORD | + DMA_BSIZE_4 | DMA_REQUEST_LINE(23) | + DMA_DEV_WIDTH_CONFIGURABLE | DMA_DEV_BSIZE_NOT_CONFIGURABLE | + DMA_DEV_DMAC0_CANBE_USED ),}, + {.id = "msp2rx", + .config = ( DMA_AHB_M0 | DMA_ADR_NOINC | DMA_WIDTH_WORD | + DMA_BSIZE_4 | DMA_REQUEST_LINE(22) | + DMA_DEV_WIDTH_CONFIGURABLE | DMA_DEV_BSIZE_NOT_CONFIGURABLE | + DMA_DEV_DMAC0_CANBE_USED ),}, + {.id = "saa0", + .config = ( DMA_AHB_M1 | DMA_ADR_INC | DMA_WIDTH_HALFWORD | + DMA_BSIZE_4 | DMA_REQUEST_LINE(0) | + DMA_DEV_BSIZE_NOT_CONFIGURABLE|DMA_DEV_WIDTH_NOT_CONFIGURABLE | + DMA_DEV_BOTH_DMACS_CANBE_USED ),}, + {.id = "saa1", + .config = ( DMA_AHB_M1 | DMA_ADR_INC | DMA_WIDTH_HALFWORD | + DMA_BSIZE_4 | DMA_REQUEST_LINE(1) | + DMA_DEV_BSIZE_NOT_CONFIGURABLE|DMA_DEV_WIDTH_NOT_CONFIGURABLE | + DMA_DEV_BOTH_DMACS_CANBE_USED ),}, + {.id = "saa2", + .config = ( DMA_AHB_M1 | DMA_ADR_INC | DMA_WIDTH_HALFWORD | + DMA_BSIZE_4 | DMA_REQUEST_LINE(2) | + DMA_DEV_BSIZE_NOT_CONFIGURABLE|DMA_DEV_WIDTH_NOT_CONFIGURABLE | + DMA_DEV_BOTH_DMACS_CANBE_USED ),}, + {.id = "saa3", + .config = ( DMA_AHB_M1 | DMA_ADR_INC | DMA_WIDTH_HALFWORD | + DMA_BSIZE_4 | DMA_REQUEST_LINE(3) | + DMA_DEV_BSIZE_NOT_CONFIGURABLE|DMA_DEV_WIDTH_NOT_CONFIGURABLE | + DMA_DEV_BOTH_DMACS_CANBE_USED ),}, + {.id = "saa4", + .config = ( DMA_AHB_M1 | DMA_ADR_INC | DMA_WIDTH_HALFWORD | + DMA_BSIZE_4 | DMA_REQUEST_LINE(4) | + DMA_DEV_BSIZE_NOT_CONFIGURABLE|DMA_DEV_WIDTH_NOT_CONFIGURABLE | + DMA_DEV_BOTH_DMACS_CANBE_USED ),}, + {.id = "saa5", + .config = ( DMA_AHB_M1 | DMA_ADR_INC | DMA_WIDTH_HALFWORD | + DMA_BSIZE_4 | DMA_REQUEST_LINE(5) | + DMA_DEV_BSIZE_NOT_CONFIGURABLE|DMA_DEV_WIDTH_NOT_CONFIGURABLE | + DMA_DEV_BOTH_DMACS_CANBE_USED ),}, + {.id = "saa6", + .config = ( DMA_AHB_M1 | DMA_ADR_INC | DMA_WIDTH_HALFWORD | + DMA_BSIZE_4 | DMA_REQUEST_LINE(6) | + DMA_DEV_BSIZE_NOT_CONFIGURABLE|DMA_DEV_WIDTH_NOT_CONFIGURABLE | + DMA_DEV_BOTH_DMACS_CANBE_USED ),}, + {.id = "saa7", + .config = ( DMA_AHB_M1 | DMA_ADR_INC | DMA_WIDTH_HALFWORD | + DMA_BSIZE_4 | DMA_REQUEST_LINE(7) | + DMA_DEV_BSIZE_NOT_CONFIGURABLE|DMA_DEV_WIDTH_NOT_CONFIGURABLE | + DMA_DEV_BOTH_DMACS_CANBE_USED ),}, +}; + +static struct dma_soc_data dma_data = { + .dirqdesc = irq_desc, + .config_tbl = dmadev_default_config_tbl, + .config_tbl_size = sizeof(dmadev_default_config_tbl)/ + sizeof(dmadev_default_config_tbl[0]), +}; + +void __init arch_dma_init(struct dma_struct *dma) +{ + dma_data.dma_chan = dma; +}; + +static struct amba_device dma0_device = { + .dev = { + .bus_id = "DMA0", + .platform_data = &dma_data, + }, + .res = { + .start = NOMADIK_DMA0_BASE, + .end = NOMADIK_DMA0_BASE + SZ_64K - 1, + .flags = IORESOURCE_MEM, + }, + .irq = {IRQ_DMA0, NO_IRQ}, + .periphid = DMA_PER_ID, +}; + +static struct amba_device dma1_device = { + .dev = { + .bus_id = "DMA1", + .platform_data = &dma_data, + }, + .res = { + .start = NOMADIK_DMA1_BASE, + .end = NOMADIK_DMA1_BASE + SZ_64K - 1, + .flags = IORESOURCE_MEM, + }, + .irq = {IRQ_DMA1, NO_IRQ}, + .periphid = DMA_PER_ID, +}; + +#define NUM_SSP_CLIENTS 10 +#define SPI_BUS_NUMBER 2 + +static struct nmdk_spi_master_cntlr msp0_platform_data = { + .enable_dma = 1, + .id = MSP_0_CONTROLLER, + .num_chipselect = NUM_SSP_CLIENTS, + .base_addr = NOMADIK_MSP0_BASE, + .dma_srcaddr = NOMADIK_MSP0_BASE+MSP_TX_RX_REG_OFFSET, + .dma_srcdevtype = "msp0rx", + .dma_destaddr = NOMADIK_MSP0_BASE+MSP_TX_RX_REG_OFFSET, + .dma_destdevtype = "msp0tx", + .gpio_alt_func = GPIO_ALT_MSP_0, + .device_name = "msp0", +}; + +static struct amba_device msp0_device = { + .dev = { + .bus_id = "msp0", + .platform_data = &msp0_platform_data, + }, + .res = { + .start = NOMADIK_MSP0_BASE, + .end = NOMADIK_MSP0_BASE + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + .dma_mask = ~0, + .irq = {IRQ_MSP0, NO_IRQ}, + .periphid = MSP_PER_ID, +}; + +static struct nmdk_spi_master_cntlr msp1_platform_data = { + .enable_dma = 1, + .id = MSP_1_CONTROLLER, + .num_chipselect = NUM_SSP_CLIENTS, + .base_addr = NOMADIK_MSP1_BASE, + .dma_srcaddr = NOMADIK_MSP1_BASE+MSP_TX_RX_REG_OFFSET, + .dma_srcdevtype = "msp1rx", + .dma_destaddr = NOMADIK_MSP1_BASE+MSP_TX_RX_REG_OFFSET, + .dma_destdevtype = "msp1tx", + .gpio_alt_func = GPIO_ALT_MSP_1, + .device_name = "msp1", +}; + +static struct amba_device msp1_device = { + .dev = { + .bus_id = "msp1", + .platform_data = &msp1_platform_data, + }, + .res = { + .start = NOMADIK_MSP1_BASE, + .end = NOMADIK_MSP1_BASE + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + .dma_mask = ~0, + .irq = {IRQ_MSP1, NO_IRQ}, + .periphid = MSP_PER_ID, +}; + +static struct nmdk_spi_master_cntlr msp2_platform_data = { + .enable_dma = 1, + .id = MSP_2_CONTROLLER, + .num_chipselect = NUM_SSP_CLIENTS, + .base_addr = NOMADIK_MSP2_BASE, + .dma_srcaddr = NOMADIK_MSP2_BASE+MSP_TX_RX_REG_OFFSET, + .dma_srcdevtype = "msp2rx", + .dma_destaddr = NOMADIK_MSP2_BASE+MSP_TX_RX_REG_OFFSET, + .dma_destdevtype = "msp2tx", + .gpio_alt_func = GPIO_ALT_MSP_2, + .device_name = "msp2", +}; + +static struct amba_device msp2_device = { + .dev = { + .bus_id = "msp2", + .platform_data = &msp2_platform_data, + }, + .res = { + .start = NOMADIK_MSP2_BASE, + .end = NOMADIK_MSP2_BASE + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + .dma_mask = ~0, + .irq = {IRQ_MSP2, NO_IRQ}, + .periphid = MSP_PER_ID, +}; + +#if 0 +static struct nmdk_spi_master_cntlr msp3_platform_data = { + .enable_dma = 1, + .num_chipselect = NUM_SSP_CLIENTS, + .base_addr = NOMADIK_MSP3_BASE, + .cntlr_rx_dma_dev_id = DMA_MSP_RX_3_DEVICE, + .cntlr_tx_dma_dev_id = DMA_MSP_TX_3_DEVICE, + .gpio_alt_func = GPIO_ALT_MSP_3, + .device_name = "msp3", +}; + +static struct amba_device msp3_device = { + .dev = { + .bus_id = "mb:28", + .platform_data = &msp3_platform_data, + }, + .res = { + .start = NOMADIK_MSP3_BASE, + .end = NOMADIK_MSP3_BASE + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + .dma_mask = ~0, + .irq = {IRQ_MSP3, NO_IRQ}, + .periphid = MSP_PER_ID, +}; +#endif + + +#if (defined(CONFIG_NOMADIK_SSP) || defined(CONFIG_NOMADIK_SPI_MODULE)) +static struct nmdk_spi_master_cntlr ssp_platform_data = { + .enable_dma = 1, + .id = SSP_CONTROLLER, + .num_chipselect = NUM_SSP_CLIENTS, + .base_addr = NOMADIK_SSP_BASE, + .dma_srcaddr = NOMADIK_SSP_BASE+SSP_TX_RX_REG_OFFSET, + .dma_srcdevtype = "ssprx", + .dma_destaddr = NOMADIK_SSP_BASE+SSP_TX_RX_REG_OFFSET, + .dma_destdevtype = "ssptx", + .gpio_alt_func = GPIO_ALT_SSP, + .device_name = "ssp", +}; + +static struct amba_device ssp_device = { + .dev = { + .bus_id = "ssp", + .platform_data = &ssp_platform_data, + }, + .res = { + .start = NOMADIK_SSP_BASE, + .end = NOMADIK_SSP_BASE + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + .dma_mask = ~0, + .irq = {IRQ_SSP, NO_IRQ}, + .periphid = SSP_PER_ID, +}; + +#endif + +static struct amba_device sga_device = { + .dev = { + .bus_id = "SGA", + .coherent_dma_mask = ~0, + }, + .res = { + .start = NOMADIK_SGA_BASE, + .end = NOMADIK_SGA_BASE + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + .dma_mask = ~0, + .irq = {IRQ_SGA_IT, NO_IRQ}, + .periphid = SGA_PER_MASK, +}; + +static struct amba_device *amba_devs[] __initdata = { + &gpio_device, + &rtc_device, + &uart0_device, + &uart1_device, + &clcd_device, + &mmc_device, + &dma0_device, + &dma1_device, +#if (defined(CONFIG_NOMADIK_SSP) || defined(CONFIG_NOMADIK_SPI_MODULE)) + &ssp_device, +#endif + &msp0_device, + &msp1_device, + &msp2_device, + &sga_device, +}; + +struct clcd_fb *nomadik_get_paneltype(void) +{ + struct amba_device *dev = &clcd_device; + struct clcd_fb *fb = amba_get_drvdata(dev); + + return fb; +} + +struct device *nomadik_get_sgadevice(void) +{ + return &sga_device.dev; +} +EXPORT_SYMBOL(nomadik_get_sgadevice); + +unsigned int reg_virtual = 0; +irqreturn_t vert_int(int irq, void *x) +{ + volatile unsigned int *regp; + unsigned char src_id; + + if (unlikely(!reg_virtual)) { + printk("CLCD:Interrupt not handled\n"); + return IRQ_NONE; + } + /* Clear all interrupt bits */ + regp = (unsigned int *)(reg_virtual + CLCD_STAT); + *regp |= 0x1E; + + regp = (unsigned int *)(reg_virtual + CLCD_INTR); + src_id = (unsigned char)*regp; + if (src_id) + printk(KERN_ERR "CLCD:Error in clearing the interrupt\n"); + + return IRQ_HANDLED; +} + +int enable_vertical_synchro(void) +{ + int err; + volatile unsigned int *regp; + struct clcd_fb *fb = nomadik_get_paneltype();; + + reg_virtual = (unsigned int)fb->regs; + if (unlikely(!reg_virtual)) + return -EINVAL; + + err = request_irq(IRQ_CLCD_MDIF, vert_int, 0, "clcd-vertical-interrupt", 0); + if (err) { + printk(KERN_ERR "CLCD:Error! Failed to register IRQ %i, freeing...\n", + IRQ_CLCD_MDIF); + free_irq(IRQ_CLCD_MDIF, 0); + } + + /* Set vertical IT event */ + regp = (unsigned int *)(reg_virtual + 0x01C); + *regp &= 0xffffcfff; + + /* Enable vertical synchro interrupts */ + regp = (unsigned int *)(reg_virtual + 0x18); + *regp |= 0x08; + + return 0; +} + +void disable_vertical_synchro(void) +{ + volatile unsigned int *regp; + + if (unlikely(!reg_virtual)) + return; + /* Disable vertical synchro interrupts */ + regp = (unsigned int *)(reg_virtual + 0x18); + *regp &= ~0x08; + + reg_virtual = 0; + + free_irq(IRQ_CLCD_MDIF, 0); + return; +} + +struct bus_type *amba_bustype; + +static int __init nomadik_init(void) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(amba_devs); i++) { + struct amba_device *d = amba_devs[i]; + amba_device_register(d, &iomem_resource); + } + device_init_wakeup(&mmc_device.dev, 1); + return 0; +} + +arch_initcall(nomadik_init); + +/* + * SOC specifc drivers whcih are used as platform devices + */ + +extern void __init nomadik_vic_init(void); +extern void nomadik_time_init(void); +extern unsigned long nomadik_gettimeoffset(void); + +static struct map_desc nomadik_io_desc[] __initdata = { + {IO_ADDRESS(NOMADIK_SRC_BASE), __phys_to_pfn(NOMADIK_SRC_BASE), SZ_4K, + MT_DEVICE}, + {IO_ADDRESS(NOMADIK_WDOG_BASE), __phys_to_pfn(NOMADIK_WDOG_BASE), SZ_4K, + MT_DEVICE}, + {IO_ADDRESS(NOMADIK_FSMC_BASE), __phys_to_pfn(NOMADIK_FSMC_BASE), SZ_4K, + MT_DEVICE}, + {IO_ADDRESS(NOMADIK_MTU0_BASE), __phys_to_pfn(NOMADIK_MTU0_BASE), SZ_4K, + MT_DEVICE}, + {IO_ADDRESS(NOMADIK_MTU1_BASE), __phys_to_pfn(NOMADIK_MTU1_BASE), SZ_4K, + MT_DEVICE}, + {IO_ADDRESS(NOMADIK_IC_BASE), __phys_to_pfn(NOMADIK_IC_BASE), SZ_4K, + MT_DEVICE}, + {IO_ADDRESS(NOMADIK_RTC_BASE), __phys_to_pfn(NOMADIK_RTC_BASE), SZ_4K, + MT_DEVICE}, + {IO_ADDRESS(NOMADIK_PMU_BASE), __phys_to_pfn(NOMADIK_PMU_BASE), SZ_4K, + MT_DEVICE}, + {IO_ADDRESS(NOMADIK_SSP_BASE), __phys_to_pfn(NOMADIK_SSP_BASE), SZ_4K, + MT_DEVICE}, + {IO_ADDRESS(NOMADIK_MSP0_BASE), __phys_to_pfn(NOMADIK_MSP0_BASE), SZ_4K, + MT_DEVICE}, + {IO_ADDRESS(NOMADIK_MSP1_BASE), __phys_to_pfn(NOMADIK_MSP1_BASE), SZ_4K, + MT_DEVICE}, + {IO_ADDRESS(NOMADIK_MSP2_BASE), __phys_to_pfn(NOMADIK_MSP2_BASE), SZ_4K, + MT_DEVICE}, + {IO_ADDRESS(NOMADIK_I2C0_BASE), __phys_to_pfn(NOMADIK_I2C0_BASE), SZ_4K, + MT_DEVICE}, + {IO_ADDRESS(NOMADIK_I2C1_BASE), __phys_to_pfn(NOMADIK_I2C1_BASE), SZ_4K, + MT_DEVICE}, + {IO_ADDRESS(NOMADIK_GPIO0_BASE), __phys_to_pfn(NOMADIK_GPIO0_BASE), + SZ_4K, MT_DEVICE}, + {IO_ADDRESS(NOMADIK_GPIO1_BASE), __phys_to_pfn(NOMADIK_GPIO1_BASE), + SZ_4K, MT_DEVICE}, + {IO_ADDRESS(NOMADIK_GPIO2_BASE), __phys_to_pfn(NOMADIK_GPIO2_BASE), + SZ_4K, MT_DEVICE}, + {IO_ADDRESS(NOMADIK_DMA0_BASE), __phys_to_pfn(NOMADIK_DMA0_BASE), SZ_4K, + MT_DEVICE}, + {IO_ADDRESS(NOMADIK_DMA1_BASE), __phys_to_pfn(NOMADIK_DMA1_BASE), SZ_4K, + MT_DEVICE}, + {IO_ADDRESS(NOMADIK_SSIRx_BASE), __phys_to_pfn(NOMADIK_SSIRx_BASE), + SZ_4K, MT_DEVICE}, + {IO_ADDRESS(NOMADIK_SSITx_BASE), __phys_to_pfn(NOMADIK_SSITx_BASE), + SZ_4K, MT_DEVICE}, + {IO_ADDRESS(NOMADIK_CLCDC_BASE), __phys_to_pfn(NOMADIK_CLCDC_BASE), + SZ_4K, MT_DEVICE}, + {IO_ADDRESS(NOMADIK_SDRAMC_BASE), __phys_to_pfn(NOMADIK_SDRAMC_BASE), + SZ_4K, MT_DEVICE}, + {IO_ADDRESS(NOMADIK_SGA_BASE), __phys_to_pfn(NOMADIK_SGA_BASE), + SZ_4K, MT_DEVICE}, + {IO_ADDRESS(NOMADIK_SDI_BASE), __phys_to_pfn(NOMADIK_SDI_BASE), + SZ_4K, MT_DEVICE}, + {IO_ADDRESS(NOMADIK_L2CC_BASE), __phys_to_pfn(NOMADIK_L2CC_BASE), + SZ_4K, MT_DEVICE}, + + SOC_IO_DESC BOARD_IO_DESC +}; + +static void __init nomadik_map_io(void) +{ + iotable_init(nomadik_io_desc, ARRAY_SIZE(nomadik_io_desc)); +} + +static struct resource nomadik_i2c_0_resources[] = { + [0] = { + .start = NOMADIK_I2C0_BASE, + .end = NOMADIK_I2C0_BASE + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_I2C0, + .end = IRQ_I2C0, + .flags = IORESOURCE_IRQ} +}; + +static struct resource nomadik_i2c_1_resources[] = { + [0] = { + .start = NOMADIK_I2C1_BASE, + .end = NOMADIK_I2C1_BASE + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_I2C1, + .end = IRQ_I2C1, + .flags = IORESOURCE_IRQ} +}; + +static struct platform_device nomadik_i2c_0_controller = { + .name = "NOMADIK-I2C", + .id = 0, + .num_resources = 2, + .resource = nomadik_i2c_0_resources +}; + +static struct platform_device nomadik_i2c_1_controller = { + .name = "NOMADIK-I2C", + .id = 1, + .num_resources = 2, + .resource = nomadik_i2c_1_resources +}; + +static struct resource nomadik_saa_resources[] = { + [0] = { + .name = "saa-data-mem", + .start = NOMADIK_HAMACA_DMEM, + .end = (NOMADIK_HAMACA_DMEM + SZ_1M - 1), + .flags = IORESOURCE_MEM, + }, + + [1] = { + .name = "saa-irq0", + .start = IRQ_SAA_IT0, + .end = IRQ_SAA_IT0, + .flags = IORESOURCE_IRQ, + }, + + [2] = { + .name = "saa-irq1", + .start = IRQ_SAA_IT1, + .end = IRQ_SAA_IT1, + .flags = IORESOURCE_IRQ, + }, +}; + +#undef DEVICES_NAME +#define DEVICES_NAME "SVA" + +#ifndef SVA_DEBUG +#define SVA_DEBUG 0 +#endif + +#undef NMDK_DEBUG +#undef NMDK_DEBUG_PFX +#define NMDK_DEBUG SVA_DEBUG /* enables/disables nmdk_dbg msgs */ +#define NMDK_DEBUG_PFX DEVICES_NAME /* msg header represents this module */ +#define NMDK_DBG KERN_ERR /* message level */ + + +int nomadik_denc_deinit(void) +{ + __u8 data[2]; + int status,ret_val = 0; + + nmdk_dbg_ftrace(); +#if !defined(CONFIG_NOMADIK_NHK15) + ret_val = nomadik_i2c_read_register(I2C_CPLD_CLIENT, data, 0x20, 2); + if (ret_val) + return ret_val; + + data[0] &= ~0x70; + ret_val = nomadik_i2c_write_register(I2C_CPLD_CLIENT, data, 0x20, 2); + if (ret_val) + return ret_val; +#else + data[0] = 0x00; + ret_val = nomadik_i2c_write_register(I2C_DENC_CLIENT, data, 0x81, 1); + if (ret_val) + return ret_val; + + data[0] = 0x00; + ret_val = nomadik_i2c_write_register(I2C_DENC_CLIENT, data, 0x82, 1); + if (ret_val) + return ret_val; + data[0] = 0x00; + ret_val = nomadik_i2c_write_register(I2C_DENC_CLIENT, data, 0x83, 1); + if (ret_val) + return ret_val; + + status = STMPE2401_SetGpioVal(STMPE0,EGPIO_PIN_4,0); + if(status != STMPE2401_OK ) + printk( " writing STMPE0 EGPIO_PIN_5 5 FAIL\n"); + status = STMPE2401_SetGpioVal(STMPE0,EGPIO_PIN_5,0); + if(status != STMPE2401_OK ) + printk( " writing STMPE0 EGPIO_PIN_5 5 FAIL\n"); + +#endif + nomadik_gpio_resetpinconfig(GPIO_PIN_49, "sva"); + nomadik_gpio_resetpinconfig(GPIO_PIN_50, "sva"); + return ret_val; + +} + +int nomadik_denc_init(int mode) +{ + gpio_config pin_config; + __u32 *address,status; + __u8 *address8; + int ret_val = 0; + __u8 data[2]; + + nmdk_dbg_ftrace(); + address = (__u32 *) IO_ADDRESS(NOMADIK_GPIO1_BASE); + address += 8; + *address |= 0x00040000; + pin_config.dev_name = "sva"; + pin_config.mode = GPIO_MODE_SOFTWARE; + pin_config.direction = GPIO_DIR_OUTPUT; + ret_val = nomadik_gpio_setpinconfig(GPIO_PIN_49, &pin_config); + if (ret_val == 0) { + nmdk_dbg("setpinconfig pin 49 successfully"); + } else { + switch (ret_val) { + case -EINVAL: + nmdk_dbg("\ninvalid pin\n"); + return -EINVAL; + case -EIO: + nmdk_dbg("\ninternal HCL error\n"); + return -EINVAL; + } + } + + mdelay(1); + nomadik_gpio_writepin(GPIO_PIN_49, GPIO_DATA_LOW, "sva"); + mdelay(1); + nomadik_gpio_writepin(GPIO_PIN_49, GPIO_DATA_HIGH, "sva"); + + ret_val = nomadik_gpio_setpinconfig(GPIO_PIN_50, &pin_config); + if (ret_val == 0) { + nmdk_dbg("\nsetpinconfig successfully\n"); + } else { + switch (ret_val) { + case -EINVAL: + nmdk_dbg("\ninvalid pin\n"); + return -EINVAL; + + case -EIO: + nmdk_dbg("\ninternal HCL error\n"); + return -EINVAL; + } + } + + address = (__u32 *) IO_ADDRESS(NOMADIK_GPIO1_BASE); + address8 = (__u8 *) address; + + address = (__u32 *) IO_ADDRESS(NOMADIK_GPIO2_BASE); + address8 = (__u8 *) address; + + mdelay(1); + nomadik_gpio_writepin(GPIO_PIN_50, GPIO_DATA_LOW, "sva"); + mdelay(1); + nomadik_gpio_writepin(GPIO_PIN_50, GPIO_DATA_HIGH, "sva"); + mdelay(1); + nomadik_gpio_writepin(GPIO_PIN_50, GPIO_DATA_LOW, "sva"); +#if !defined(CONFIG_NOMADIK_NHK15) + ret_val = nomadik_i2c_read_register(I2C_CPLD_CLIENT, data, 0x20, 2); + if (ret_val) + return ret_val; + nmdk_dbg("Value read %X\n", *((__u16 *) data)); + + data[0] |= 0x30; + ret_val = nomadik_i2c_write_register(I2C_CPLD_CLIENT, data, 0x20, 2); + if (ret_val) + return ret_val; + + ret_val = nomadik_i2c_read_register(I2C_CPLD_CLIENT, data, 0x20, 2); + if (ret_val) + return ret_val; + nmdk_dbg("Value read %X\n", *((__u16 *) data)); + + data[0] &= ~0x70; + data[0] |= 0x10; + ret_val = nomadik_i2c_write_register(I2C_CPLD_CLIENT, data, 0x20, 2); + if (ret_val) + return ret_val; + + ret_val = nomadik_i2c_read_register(I2C_CPLD_CLIENT, data, 0x20, 2); + if (ret_val) + return ret_val; + nmdk_dbg("Value read %X\n", *((__u16 *) data)); + + data[0] &= ~0x70; + data[0] |= 0x30; + ret_val = nomadik_i2c_write_register(I2C_CPLD_CLIENT, data, 0x20, 2); + if (ret_val) + return ret_val; + + ret_val = nomadik_i2c_read_register(I2C_CPLD_CLIENT, data, 0x20, 2); + if (ret_val) + return ret_val; + nmdk_dbg("Value read %X\n", *((__u16 *) data)); + + data[0] &= ~0x70; + data[0] |= 0x20; + ret_val = nomadik_i2c_write_register(I2C_CPLD_CLIENT, data, 0x20, 2); + if (ret_val) + return ret_val; + + ret_val = nomadik_i2c_read_register(I2C_CPLD_CLIENT, data, 0x20, 2); + if (ret_val) + return ret_val; + nmdk_dbg("Value read %X\n", *((__u16 *) data)); + + /* Configure DENC chip */ +#else + status=STMPE2401_SetGpioAltFunction(STMPE0 ,EGPIO_PIN_5, STMPE2401_PRIMARY_FUNCTION ); + if (status != STMPE2401_OK) + printk("Couldn't set STMPE0 %d as STMPE2401_PRIMARY_FUNCTION \n",EGPIO_PIN_5); + status=STMPE2401_SetGpioAltFunction(STMPE0 ,EGPIO_PIN_4, STMPE2401_PRIMARY_FUNCTION ); + if (status != STMPE2401_OK) + printk("Couldn't set STMPE0 %d as STMPE2401_PRIMARY_FUNCTION \n",EGPIO_PIN_4); + status = STMPE2401_SetGpioDir(STMPE0,EGPIO_PIN_5,STMPE2401_GPIO_OUT); + if (status != STMPE2401_OK) + printk("Couldn't set STMPE0 %d as GPIO direction \n",EGPIO_PIN_5); + status=STMPE2401_SetGpioDir(STMPE0,EGPIO_PIN_4,STMPE2401_GPIO_OUT); + + if (status != STMPE2401_OK) + printk("Couldn't set STMPE0 %d as GPIO direction \n",EGPIO_PIN_4); + status = STMPE2401_SetGpioVal(STMPE0,EGPIO_PIN_5,1); + if(status != STMPE2401_OK ) + printk( " writing STMPE0 EGPIO_PIN_5 5 FAIL\n"); + + status = STMPE2401_SetGpioVal(STMPE0,EGPIO_PIN_4,1); + if(status != STMPE2401_OK ) + printk( " writing STMPE0 EGPIO_PIN_4 1 FAIL\n"); + + mdelay(10); + status = STMPE2401_SetGpioVal(STMPE0,EGPIO_PIN_4,0); + if(status != STMPE2401_OK ) + printk( " writing STMPE0 EGPIO_PIN_4 1 FAIL\n"); + mdelay(10); + status = STMPE2401_SetGpioVal(STMPE0,EGPIO_PIN_4,1); + if(status != STMPE2401_OK ) + printk( " writing STMPE0 EGPIO_PIN_4 1 FAIL\n"); + mdelay(5); + status = STMPE2401_SetGpioVal(STMPE0,EGPIO_PIN_5,0); + if(status != STMPE2401_OK ) + printk( " writing STMPE0 EGPIO_PIN_5 1 FAIL\n"); +#endif +#if !defined(CONFIG_NOMADIK_NHK15) + data[0] = 0x20; + ret_val = nomadik_i2c_write_register(I2C_DENC_CLIENT, data, 0x5f, 1); + if (ret_val) + return ret_val; +#else + data[0] = 0x21; // NHK15 + ret_val = nomadik_i2c_write_register(I2C_DENC_CLIENT, data, 0x5f, 1); + if (ret_val) + return ret_val; +#endif + data[0] = 0x02; + ret_val = nomadik_i2c_write_register(I2C_DENC_CLIENT, data, 0x82, 1); + if (ret_val) + return ret_val; + + data[0] = 0x02; + ret_val = nomadik_i2c_write_register(I2C_DENC_CLIENT, data, 0x83, 1); + if (ret_val) + return ret_val; + + data[0] = 0x00; + ret_val = nomadik_i2c_write_register(I2C_DENC_CLIENT, data, 0x80, 1); + if (ret_val) + return ret_val; +#if defined (CONFIG_NOMADIK_NHK15) +/*Added as per btp */ + data[0] = 0x02; + ret_val = nomadik_i2c_write_register(I2C_DENC_CLIENT, data, 0x130, 1); + if (ret_val) + return ret_val; +#endif + switch (mode) { + case DENC_MODE_NTSC: + data[0] = 0xba; + ret_val = + nomadik_i2c_write_register(I2C_DENC_CLIENT, data, 0x00, 1); + if (ret_val) + return ret_val; + + data[0] = 0x30; + ret_val = + nomadik_i2c_write_register(I2C_DENC_CLIENT, data, 0x08, 1); + if (ret_val) + return ret_val; + + data[0] = 0x8a; + ret_val = + nomadik_i2c_write_register(I2C_DENC_CLIENT, data, 0x00, 1); + if (ret_val) + return ret_val; + + break; + + case DENC_MODE_PAL: + /* standard PAL BDGHI sync: SLAVE mode */ + data[0] = 0x3a; + ret_val = + nomadik_i2c_write_register(I2C_DENC_CLIENT, data, 0x00, 1); + if (ret_val) + return ret_val; + + data[0] = 0x30; + ret_val = + nomadik_i2c_write_register(I2C_DENC_CLIENT, data, 0x08, 1); + if (ret_val) + return ret_val; + + /* standard PAL BDGHI sync: SLAVE mode */ + data[0] = 0x0a; + ret_val = + nomadik_i2c_write_register(I2C_DENC_CLIENT, data, 0x00, 1); + if (ret_val) + return ret_val; + + break; + default: + nmdk_dbg("DENC:Unsupported mode\n"); + ret_val = -EINVAL; + + } + return ret_val; +} + +#ifdef CONFIG_NOMADIK_NDK15 +void nomadik_pepperpot_deinit(void) +{ + nomadik_gpio_altfuncdisable(GPIO_ALT_CAM, "sva"); + nomadik_gpio_resetpinconfig(GPIO_PIN_73, "sva"); + nomadik_gpio_resetpinconfig(GPIO_PIN_110, "sva"); + nomadik_gpio_resetpinconfig(GPIO_PIN_115, "sva"); + +} + +int nomadik_pepperpot_init(void) +{ + unsigned char wr_buff2[16], wr_buff3[16], wr_buff4[16]; + volatile __u32 *address; + __u32 address_data; + int ret_val = 0; + + nmdk_dbg_ftrace(); + address = ioremap(0x101E0044, 4); + if (!address) { + nmdk_dbg("Ioremap failed\n"); + return -EINVAL; + } + address_data = readl(address); + address_data &= ~0xFFFFUL; + address_data |= (0x0103 & 0xFFFFUL); + writel(address_data, address); + + iounmap((void *)address); + wr_buff3[0] = 0x00; + wr_buff2[0] = 0x85; + + ret_val = + nomadik_i2c_write_register(I2C_TOUAREG_CLIENT, wr_buff3, 0x1F, 1); + nmdk_dbg("Transfer to touareg 0x1F STATUS %d\n", ret_val); + + wr_buff4[0] = 0xdd; + ret_val = + nomadik_i2c_write_register(I2C_TOUAREG_CLIENT, wr_buff4, 0x1E, 1); + nmdk_dbg("Transfer to touareg 0x1E STATUS %d\n", ret_val); + + ret_val = + nomadik_i2c_write_register(I2C_TOUAREG_CLIENT, wr_buff3, 0x1F, 1); + nmdk_dbg("Transfer to touareg 0x1F STATUS %d\n", ret_val); + + wr_buff4[0] = 0xdd; + ret_val = + nomadik_i2c_write_register(I2C_TOUAREG_CLIENT, wr_buff4, 0x1E, 1); + nmdk_dbg("Transfer to touareg 0x1E STATUS %d\n", ret_val); + + nmdk_dbg("Transfer to touareg 0x11\n"); + ret_val = + nomadik_i2c_write_register(I2C_TOUAREG_CLIENT, wr_buff2, 0x11, 1); + + return 0; +} +#endif +int nomadik_pepperpot_gpio_alloc() +{ + gpio_config pin_config; + int ret_val = 0; + + ret_val = nomadik_gpio_altfuncenable(GPIO_ALT_CAM, "sva"); + if (ret_val) { + printk("Alt func for PIN 25 enable failed\n"); + return ret_val; + } + + pin_config.dev_name = "sva"; + pin_config.mode = GPIO_MODE_SOFTWARE; + pin_config.direction = GPIO_DIR_OUTPUT; + ret_val = nomadik_gpio_setpinconfig(GPIO_PIN_73, &pin_config); + if (ret_val == 0) { + nmdk_dbg("\nsetpinconfig successfully\n"); + } else { + printk("\nInternal GPIO error\n"); + nomadik_gpio_altfuncdisable(GPIO_ALT_CAM, "sva"); + return -EINVAL; + } + + nomadik_gpio_writepin(GPIO_PIN_73, GPIO_DATA_HIGH, "sva"); + mdelay(1); + nomadik_gpio_writepin(GPIO_PIN_73, GPIO_DATA_LOW, "sva"); + mdelay(1); + nomadik_gpio_writepin(GPIO_PIN_73, GPIO_DATA_HIGH, "sva"); + mdelay(1); + + ret_val = nomadik_gpio_setpinconfig(GPIO_PIN_110, &pin_config); + if (ret_val == 0) { + nmdk_dbg("\nsetpinconfig successfully\n"); + } else { + printk("\nInternal GPIO error\n"); + nomadik_gpio_altfuncdisable(GPIO_ALT_CAM, "sva"); + nomadik_gpio_resetpinconfig(GPIO_PIN_73, "sva"); + return -EINVAL; + } + + nomadik_gpio_writepin(GPIO_PIN_110, GPIO_DATA_HIGH, "sva"); + mdelay(1); + nomadik_gpio_writepin(GPIO_PIN_110, GPIO_DATA_LOW, "sva"); + mdelay(1); + nomadik_gpio_writepin(GPIO_PIN_110, GPIO_DATA_HIGH, "sva"); + mdelay(1); + + ret_val = nomadik_gpio_setpinconfig(GPIO_PIN_115, &pin_config); + if (ret_val == 0) { + nmdk_dbg("\nsetpinconfig successfully\n"); + } else { + printk("\nInternal GPIO error\n"); + nomadik_gpio_altfuncdisable(GPIO_ALT_CAM, "sva"); + nomadik_gpio_resetpinconfig(GPIO_PIN_73, "sva"); + nomadik_gpio_resetpinconfig(GPIO_PIN_110, "sva"); + return -EINVAL; + } + nomadik_gpio_writepin(GPIO_PIN_115, GPIO_DATA_HIGH, "sva"); + mdelay(1); + nomadik_gpio_writepin(GPIO_PIN_115, GPIO_DATA_LOW, "sva"); + mdelay(1); + nomadik_gpio_writepin(GPIO_PIN_115, GPIO_DATA_HIGH, "sva"); + mdelay(1); + return 0; +} + +#define VPIP_DEVICE_NAME "VPIP" +static short int irp_aquired_gpio=0; + +int irp_init_sensor(irp_sensor_t itf_type) +{ + short int i2c_err; + u8 data; + volatile unsigned long *src_clk0cr = (volatile unsigned long *) IO_ADDRESS(NOMADIK_SRC_CLK0CR); + volatile unsigned long *src_pcken1 = (volatile unsigned long *) IO_ADDRESS(NOMADIK_SRC_PCKEN1); + static short int sensor_init_done=0; + + if(itf_type == IRP_CAMERA_SENSOR_CCIR){ + nmdk_error("CCIR interface is not supported by vpip\n"); + return -EAGAIN; + } + if(sensor_init_done==1) + return 0; + + /* power up sensor */ + nmdk_dbg("vpip: enabling the touareg index. \n"); + data = 0x0; + i2c_err = nomadik_i2c_write_register(I2C_TOUAREG_CLIENT, &data, 0x1f,1); + if(i2c_err <0) + goto i2c_error; + data = 0xdd; + i2c_err = nomadik_i2c_write_register(I2C_TOUAREG_CLIENT, &data, 0x1e,1); + if(i2c_err <0) + goto i2c_error; + data = 0x85; + i2c_err = nomadik_i2c_write_register(I2C_TOUAREG_CLIENT, &data, 0x11,1); + if(i2c_err <0) + goto i2c_error; + + + /* configure gpio to set ClOUT0 at 12Mhz, as camera external clock ?? + */ + *src_clk0cr = 0x0103; + + // XXX enable clock signal of vpip + *src_pcken1 |= PERIPH_CLK_EN1_44; + + sensor_init_done=1; + return 0; + +i2c_error: + nmdk_error("VPIP: i2c write to touareg registers failed\n"); + return -EAGAIN; +} + + +int irp_free_gpio_pins(irp_sensor_t itf_type) +{ + gpio_error gpio_err=0; + unsigned int pin_no=-1; + + if(irp_aquired_gpio==0) + return 0; + + nmdk_dbg("vpip: disabling the gpio altfunc GPIO_ALT_CLOCK_RESET \n"); + gpio_err = nomadik_gpio_altfuncdisable(GPIO_ALT_CAM, VPIP_DEVICE_NAME); + if(gpio_err != GPIO_OK) { + nmdk_error("Failed to disable GPIO altf A for pin 25 \n"); + return -1; + } + + nmdk_dbg("vpip: disabling the gpio altfunc GPIO_ALT_VPIP \n"); + gpio_err = nomadik_gpio_altfuncdisable(GPIO_ALT_VPIP, VPIP_DEVICE_NAME); + if(gpio_err != GPIO_OK) { + nmdk_error("Failed to disable GPIO altf A for 76,109 \n"); + return -1; + } + + if(itf_type == IRP_CAMERA_SENSOR_CCP1) { + /* using pin 115 to reset ccp1 */ + pin_no= GPIO_PIN_104; + if( nomadik_gpio_resetpinconfig(GPIO_PIN_104, VPIP_DEVICE_NAME)) + goto gpio_error; + } + else { +#if !defined (CONFIG_NOMADIK_NHK15) + /* using pin 110 to reset ccp0 */ + nmdk_dbg("vpip: resetting the pin config GPIO-110 \n"); + pin_no = GPIO_PIN_110; + if(nomadik_gpio_resetpinconfig(GPIO_PIN_110, VPIP_DEVICE_NAME)) + goto gpio_error; +#else + /* using pin 104 to reset on NHK15 */ + nmdk_dbg("vpip: resetting the pin config GPIO-104 \n"); + pin_no = GPIO_PIN_104; + if(nomadik_gpio_resetpinconfig(GPIO_PIN_104, VPIP_DEVICE_NAME)) + goto gpio_error; +#endif + } + + irp_aquired_gpio=0; + return 0; +gpio_error: + nmdk_error("vpip: error while resetting gpio pin config of %d\n", pin_no); + return -1; +} + +int irp_alloc_gpio_pins(irp_sensor_t itf_type) +{ + gpio_error gpio_err=0; + gpio_config gpio_cfg; + unsigned int pin_no=-1; + + if(irp_aquired_gpio ==1) + return 0; + + nmdk_dbg("VPIP: enabling the gpio altfunc A for pin 25 .\n"); + gpio_err = nomadik_gpio_altfuncenable(GPIO_ALT_CAM, VPIP_DEVICE_NAME); + if(gpio_err != GPIO_OK) { + nmdk_error("Failed to enable GPIO altf A for pin 25 \n"); + return -1; + } + + /* gpio 76 & 109 alternate fun B so eWarp can communicate to + sensor through i2c data & clock respectively: pg-621 */ + + /* GPIO-76 & 109 are working on NDK15_B06 + May have to use I2C_1 lines 53,54 for NDK15_B05/3 + */ + + gpio_err = nomadik_gpio_altfuncenable(GPIO_ALT_VPIP, VPIP_DEVICE_NAME); + if (gpio_err) { + nmdk_error("Error in gpio Altfunction enable for SVA_I2C\n"); + return -1; + } + + if(itf_type == IRP_CAMERA_SENSOR_CCP1) { + /* TODO not tested */ + gpio_config gpio_vpip_cfg; + gpio_vpip_cfg.mode= GPIO_ALTF_C; + gpio_vpip_cfg.direction = GPIO_DIR_LEAVE_UNCHANGED; + gpio_vpip_cfg.trig = GPIO_TRIG_LEAVE_UNCHANGED; + gpio_vpip_cfg.debounce = GPIO_DEBOUNCE_UNCHANGED; + nmdk_dbg("vpip: enabling GPIO lines 3,4,5 &6 for CCP1 port \n"); + gpio_err = nomadik_gpio_altfuncenable(GPIO_ALT_CCP1, VPIP_DEVICE_NAME); + if (gpio_err) { + nmdk_error("Error in gpio Altfunction enable for CCP1\n"); + return -1; + } + } + /* reset the sensor */ + gpio_cfg.mode = GPIO_MODE_SOFTWARE; + gpio_cfg.direction = GPIO_DIR_OUTPUT; + gpio_cfg.trig = GPIO_TRIG_DISABLE; + gpio_cfg.debounce = GPIO_DEBOUNCE_DISABLE; + gpio_cfg.dev_name = VPIP_DEVICE_NAME; + + if(itf_type == IRP_CAMERA_SENSOR_CCP1) { + /* using pin 115 to reset ccp1 */ + pin_no= GPIO_PIN_104; + if( nomadik_gpio_setpinconfig(GPIO_PIN_104, &gpio_cfg) || + nomadik_gpio_writepin(GPIO_PIN_104, GPIO_DATA_HIGH, VPIP_DEVICE_NAME) || + nomadik_gpio_writepin(GPIO_PIN_104, GPIO_DATA_LOW, VPIP_DEVICE_NAME) || + nomadik_gpio_writepin(GPIO_PIN_104, GPIO_DATA_HIGH, VPIP_DEVICE_NAME)) + goto gpio_error; + + } + else { +#if !defined (CONFIG_NOMADIK_NHK15) + /* using pin 110 to reset ccp0 */ + nmdk_dbg("vpip: resetting the GPIO-110:High for ccp0 \n"); + pin_no = GPIO_PIN_110; + if(nomadik_gpio_setpinconfig(GPIO_PIN_110, &gpio_cfg)) + goto gpio_error; + mdelay(1); + if(nomadik_gpio_writepin(GPIO_PIN_110, GPIO_DATA_HIGH, VPIP_DEVICE_NAME)) + goto gpio_error; + mdelay(1); + if(nomadik_gpio_writepin(GPIO_PIN_110, GPIO_DATA_LOW, VPIP_DEVICE_NAME)) + goto gpio_error; + mdelay(1); + if(nomadik_gpio_writepin(GPIO_PIN_110, GPIO_DATA_HIGH, VPIP_DEVICE_NAME)) + goto gpio_error; +#else + /* using pin 104 to reset on NHK15 */ + nmdk_dbg("vpip: resetting the GPIO-104:High for ccp0 \n"); + pin_no = GPIO_PIN_104; + if(nomadik_gpio_setpinconfig(GPIO_PIN_104, &gpio_cfg)) + goto gpio_error; + mdelay(1); + if(nomadik_gpio_writepin(GPIO_PIN_104, GPIO_DATA_HIGH, VPIP_DEVICE_NAME)) + goto gpio_error; + mdelay(1); + if(nomadik_gpio_writepin(GPIO_PIN_104, GPIO_DATA_LOW, VPIP_DEVICE_NAME)) + goto gpio_error; + mdelay(1); + if(nomadik_gpio_writepin(GPIO_PIN_104, GPIO_DATA_HIGH, VPIP_DEVICE_NAME)) + goto gpio_error; +#endif + } + irp_aquired_gpio=1; + return 0; + +gpio_error: + nmdk_error("vpip: error while setting gpio pin config of %d\n", pin_no); + return -1; +} + +int irp_shutdown_sensor_via_gpio_pin(irp_sensor_t itf_type) +{ + gpio_pin pin_no=-1; + + if(itf_type == IRP_CAMERA_SENSOR_CCP1) { + pin_no = GPIO_PIN_115; + if(nomadik_gpio_writepin(GPIO_PIN_115, GPIO_DATA_HIGH, VPIP_DEVICE_NAME)) + goto gpio_error; + mdelay(1); + if(nomadik_gpio_writepin(GPIO_PIN_115, GPIO_DATA_LOW, VPIP_DEVICE_NAME)) + goto gpio_error; + mdelay(1); + if(nomadik_gpio_writepin(GPIO_PIN_115, GPIO_DATA_HIGH, VPIP_DEVICE_NAME)) + goto gpio_error; + } + else if(itf_type == IRP_CAMERA_SENSOR_CCP0){ +#if !defined (CONFIG_NOMADIK_NHK15) + pin_no = GPIO_PIN_110; + if(nomadik_gpio_writepin(GPIO_PIN_110, GPIO_DATA_HIGH, VPIP_DEVICE_NAME)) + goto gpio_error; + mdelay(1); + if(nomadik_gpio_writepin(GPIO_PIN_110, GPIO_DATA_LOW, VPIP_DEVICE_NAME)) + goto gpio_error; + mdelay(1); + if(nomadik_gpio_writepin(GPIO_PIN_110, GPIO_DATA_HIGH, VPIP_DEVICE_NAME)) + goto gpio_error; +#else + pin_no = GPIO_PIN_104; + if(nomadik_gpio_writepin(GPIO_PIN_104, GPIO_DATA_HIGH, VPIP_DEVICE_NAME)) + goto gpio_error; + mdelay(1); + if(nomadik_gpio_writepin(GPIO_PIN_104, GPIO_DATA_LOW, VPIP_DEVICE_NAME)) + goto gpio_error; + mdelay(1); + if(nomadik_gpio_writepin(GPIO_PIN_104, GPIO_DATA_HIGH, VPIP_DEVICE_NAME)) + goto gpio_error; +#endif + } + return 0; + +gpio_error: + nmdk_error("vpip: error while writepin to gpio pin %d", pin_no); + return -1; +} + +#ifdef CONFIG_NOMADIK_SAA_INIT_MEM + +dma_addr_t saa_init_physical_address; +void *saa_init_logical_address; + +dma_addr_t saa_get_physical_address(void) +{ + return saa_init_physical_address; +} + +void* saa_get_logical_address(void) +{ + return saa_init_logical_address; +} +EXPORT_SYMBOL(saa_get_physical_address); +EXPORT_SYMBOL(saa_get_logical_address); + +#endif + +static struct platform_device nomadik_saa_device = { + .name = "saa", + .id = 0, + .num_resources = ARRAY_SIZE(nomadik_saa_resources), + .resource = nomadik_saa_resources, +}; + +static struct resource nomadik_sva_resources[] = { + [0] = { + .name = "sva-reg-mem", + .start = NOMADIK_HAMACV_REG_BASE, + .end = NOMADIK_HAMACV_REG_END, + .flags = IORESOURCE_MEM, + }, + [1] = { + .name = "sva-data-mem", + .start = NOMADIK_HAMACV_DMEM_BASE, + .end = NOMADIK_HAMACV_DMEM_END, + .flags = IORESOURCE_MEM, + }, + [2] = { + .name = "sva-esram-mem", + .start = NOMADIK_ESRAM_BASE, + .end = NOMADIK_ESRAM_END, + .flags = IORESOURCE_MEM, + }, + [3] = { + .name = "sva-irq0", + .start = IRQ_SVA_IT0, + .end = IRQ_SVA_IT0, + .flags = IORESOURCE_IRQ, + }, + + [4] = { + .name = "sva-irq1", + .start = IRQ_SVA_IT1, + .end = IRQ_SVA_IT1, + .flags = IORESOURCE_IRQ, + }, +}; + +struct sva_board sva_data = { + .get_paneltype = nomadik_get_paneltype, +#if defined (CONFIG_NOMADIK_NDK15) + .camera_init = nomadik_pepperpot_init, + .camera_gpio_init = nomadik_pepperpot_gpio_alloc, + .camera_deinit = nomadik_pepperpot_deinit, +#endif + .denc_init = nomadik_denc_init, + .denc_deinit = nomadik_denc_deinit, + + .enable_synchro = enable_vertical_synchro, + .disable_synchro = disable_vertical_synchro, + .init_bus_address = 0UL, + .init_logical_address = 0UL, + .sensor_init = irp_init_sensor, + .sensor_gpio_init =irp_alloc_gpio_pins, + .sensor_gpio_deinit =irp_free_gpio_pins, + .sensor_shutdown = irp_shutdown_sensor_via_gpio_pin, +}; + +static struct platform_device nomadik_sva_device = { + .name = "SVA", + .id = 0, + .num_resources = ARRAY_SIZE(nomadik_sva_resources), + .resource = nomadik_sva_resources, + .dev = { + .coherent_dma_mask = 0xffffffffUL, + .platform_data = &sva_data, + }, +}; + +static struct resource nomadik_ogles_resources[] = { + [0] = { + .name = "ogles-sva-reg-mem", + .start = NOMADIK_HAMACV_REG_BASE, + .end = NOMADIK_HAMACV_REG_END, + .flags = IORESOURCE_MEM, + }, + [1] = { + .name = "ogles-sva-data-mem", + .start = NOMADIK_HAMACV_DMEM_BASE, + .end = NOMADIK_HAMACV_DMEM_END, + .flags = IORESOURCE_MEM, + }, + [2] = { + .name = "ogles-sva-esram-mem", + .start = NOMADIK_ESRAM_BASE, + .end = NOMADIK_ESRAM_END, + .flags = IORESOURCE_MEM, + }, + [3] = { + .name = "ogles-sva-irq0", + .start = IRQ_SVA_IT0, + .end = IRQ_SVA_IT0, + .flags = IORESOURCE_IRQ, + }, + + [4] = { + .name = "ogles-sva-irq1", + .start = IRQ_SVA_IT1, + .end = IRQ_SVA_IT1, + .flags = IORESOURCE_IRQ, + }, +}; +static struct platform_device nomadik_ogles_device = { + .name = "OGLES", + .id = 0, + .num_resources = ARRAY_SIZE(nomadik_ogles_resources), + .resource = nomadik_ogles_resources, +}; + +static struct platform_device *core_devices[] __initdata = { + &nomadik_i2c_0_controller, + &nomadik_i2c_1_controller, + &nomadik_saa_device, + &nomadik_sva_device, + &nomadik_ogles_device, +}; + +static void __init nomadik_platform_init_irq(void) +{ + nomadik_vic_init(); + printk("%s done\n", (__FUNCTION__)); +} + +extern void nomadik_sdmc_prio(void); +void nomadik_sdmc_prio(void) +{ + __u32 address; + address = (__u32 ) IO_ADDRESS(NOMADIK_SDRAMC_BASE); + if(address) { + /* Configure SDRAMC port timeouts for 264000 MHz */ + *(__u32 *)(address + 0x408) = 0x0000041E; + *(__u32 *)(address + 0x428) = 0x00000414; + *(__u32 *)(address + 0x448) = 0x0000040D; + *(__u32 *)(address + 0x468) = 0x00000429; + *(__u32 *)(address + 0x488) = 0x00000435; + *(__u32 *)(address + 0x4A8) = 0x00000435; + } +} +extern void add_nmdk_platform_devices(void); + +static void __init nomadik_platform_init(void) +{ + + int ret = 0; +#ifdef CONFIG_NOMADIK_SVA_INIT_MEM + + unsigned long gfp_address = 0; + /* Static memory for sva */ + #ifdef NOMADIK_MM_STATIC_MEM + + sva_data.init_bus_address = NOMADIK_SVA_BASE; + sva_data.init_logical_address = ioremap_nocache(sva_data.init_bus_address, + CONFIG_NOMADIK_SVA_MEM_SIZE * SZ_1M); + + if(!sva_data.init_logical_address) { + printk(KERN_ERR"SVA driver %d MB memory boot memory allocation failed\n",CONFIG_NOMADIK_SVA_MEM_SIZE); + } + + #else + + gfp_address = __get_free_pages(GFP_KERNEL, get_order(CONFIG_NOMADIK_SVA_MEM_SIZE * SZ_1M)); + if(gfp_address) { + sva_data.init_bus_address = (__u32) gfp_address - PAGE_OFFSET; + sva_data.init_logical_address = ioremap(sva_data.init_bus_address, + CONFIG_NOMADIK_SVA_MEM_SIZE * SZ_1M); + } + if(!sva_data.init_logical_address) { + printk(KERN_ERR"SVA driver %d MB memory boot memory allocation failed\n",CONFIG_NOMADIK_SVA_MEM_SIZE); + + } + #endif + +#endif + + platform_add_devices(core_devices, ARRAY_SIZE(core_devices)); + +#ifdef CONFIG_NOMADIK_SAA_INIT_MEM + saa_init_logical_address = + dma_alloc_coherent(NULL, SAA_HCL_INIT_MEM_SIZE, + &saa_init_physical_address, GFP_KERNEL); +#endif + + nomadik_sdmc_prio(); + + ret = nomadik_clock_disable(NOMADIK_HCLK_SAA); + if(ret < 0) + printk(KERN_ERR "Disabling of HCLK_SAA failed\n"); + + ret = nomadik_clock_disable(NOMADIK_HCLK_SVA); + if(ret < 0) + printk(KERN_ERR "Disabling of HCLK_SVA failed\n"); + add_nmdk_platform_devices(); +} + +extern struct sys_timer nomadik_timer; + +MACHINE_START(NOMADIK, CONFIG_NOMADIK_TARGET) + /* Maintainer: ST MicroElectronics */ + .phys_io = NOMADIK_UART0_BASE,.io_pg_offst = + (IO_ADDRESS(NOMADIK_UART0_BASE) >> 18) & 0xfffc,.boot_params = + 0x00000100,.map_io = nomadik_map_io,.init_irq = + nomadik_platform_init_irq,.timer = &nomadik_timer,.init_machine = + nomadik_platform_init, MACHINE_END --- /dev/null +++ linux-2.6.20/arch/arm/mach-nomadik/timer.c @@ -0,0 +1,366 @@ +/* + * linux/arch/arm/mach-nomadik/timer.c + * + * Copyright (C) STMicroelectronics + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2, as + * published by the Free Software Foundation. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(CONFIG_MTU0) && defined(CONFIG_NOMADIK_MTU_SYSTEM_TICK) +#include +#define TIMER_PERIOD 10*USEC_PER_SEC /* 10ms timer period = 10,000,000 nano secs */ +#endif + +#define TIMER_RELOAD LATCH /* one 10ms=24000 ticks */ +#define TIMER_CTRL 0x80 /* No divisor */ +#define TIMER_PERIODIC 0x40 +#define TIMER_SZ32BIT 0x02 +#define __CLOCK_TICK_RATE (CLOCK_TICK_RATE/1000) +#define TICKS2USECS(x) ((x) * 1000 / __CLOCK_TICK_RATE) /* Clock is 2.4 MHz */ +#define CR_INIT_VAL 0x2AAA8000 + +static mtu_struct_t *mtu_reg = (volatile mtu_struct_t *)NOMADIK_MTU0_VA; + +extern void timer_tick(void); + +/* + * Returns number of ms since last clock interrupt. Note that interrupts + * will have been disabled by do_gettimeoffset() + */ +unsigned long nomadik_gettimeoffset(void) +{ + + unsigned long ticks1, ticks2, status; +#if defined(CONFIG_MTU0) && defined(CONFIG_NOMADIK_MTU_SYSTEM_TICK) + mtu_timer_t mtimer = MTU0_T0; + ticks2 = mtu_get_decrementing_counter_value(mtimer); + do { + ticks1 = ticks2; + status = mtu_intr_reg_readl(mtimer, TxRIS); + ticks2 = mtu_get_decrementing_counter_value(mtimer); + } while (ticks2 > ticks1); + +#else + /* + * Get the current number of ticks. Note that there is a race + * condition between us reading the timer and checking for + * an interrupt. We get around this by ensuring that the + * counter has not reloaded between our two reads. + */ + + ticks2 = mtu_reg->tmr_value1 & 0xffff; + do { + ticks1 = ticks2; + status = mtu_reg->tmr_mis & 1; + ticks2 = mtu_reg->tmr_value1 & 0xffff; + } while (ticks2 > ticks1); +#endif + + /* + * Number of ticks since last interrupt. + */ + if (ticks2 > TIMER_RELOAD) { + printk("UNLIKELY\n"); + ticks2 = ticks2 % TIMER_RELOAD; + } + ticks1 = TIMER_RELOAD - ticks2; + + /* + * Interrupt pending? If so, we've reloaded once already. + */ + if (status) + ticks1 += TIMER_RELOAD; + + /* + * Convert the ticks to usecs + */ + return TICKS2USECS(ticks1); +} + +#ifdef CONFIG_NO_IDLE_HZ +volatile static unsigned long last_load_value = TIMER_RELOAD; +volatile static unsigned long nomadik_idle_ticks; +static int dynamic_tick_started; +#endif + +/* + * IRQ handler for the timer + */ +#if defined(CONFIG_MTU0) && defined(CONFIG_NOMADIK_MTU_SYSTEM_TICK) +static irqreturn_t nomadik_timer_interrupt(mtu_timer_t timer_id) +#else +static irqreturn_t +nomadik_timer_interrupt(int irq, void *dev_id) +#endif +{ + long value2; + long elapsed_time, extra_time = 0; + unsigned long next_match = TIMER_RELOAD; + + write_seqlock(&xtime_lock); + +#ifdef CONFIG_NO_IDLE_HZ + if (dynamic_tick_started) { + do { + /* + * the clock tick routines are only processed on the + * primary CPU + */ + if (hard_smp_processor_id() == 0) { + timer_tick(); +#ifdef CONFIG_SMP + smp_send_timer(); +#endif + } +#ifdef CONFIG_SMP + /* + * this is the ARM equivalent of the APIC timer interrupt + */ + update_process_times(user_mode(get_irq_regs())); +#endif /* CONFIG_SMP */ + value2 = mtu_reg->tmr_value1; + if (mtu_reg->tmr_mis & 0x1) { + mtu_reg->tmr_icr |= 1; + value2 = mtu_reg->tmr_value1; + extra_time = + extra_time + TIMER_RELOAD + + nomadik_idle_ticks; + last_load_value = TIMER_RELOAD; + nomadik_idle_ticks = 0; + + } + elapsed_time = extra_time + last_load_value - value2; + next_match += TIMER_RELOAD; + } while (next_match < elapsed_time); + + dynamic_tick_started = 0; + + if (last_load_value != TIMER_RELOAD) { + mtu_reg->tmr_load1 = mtu_reg->tmr_value1 % TIMER_RELOAD; + mtu_reg->tmr_bgload1 = TIMER_RELOAD; + } + last_load_value = TIMER_RELOAD; + nomadik_idle_ticks = 0; + + } else +#endif + { + mtu_reg->tmr_icr |= 1; + + /* + * the clock tick routines are only processed on the + * primary CPU + */ + if (hard_smp_processor_id() == 0) { + timer_tick(); +#ifdef CONFIG_SMP + smp_send_timer(); +#endif + } +#ifdef CONFIG_SMP + /* + * this is the ARM equivalent of the APIC timer interrupt + */ + update_process_times(user_mode(get_irq_regs())); +#endif /* CONFIG_SMP */ + + } + + write_sequnlock(&xtime_lock); + + return IRQ_HANDLED; +} + +#if defined(CONFIG_MTU0) && defined(CONFIG_NOMADIK_MTU_SYSTEM_TICK) + +static struct mtu_struct mtu_timer_tick = { + .timer = MTU0_T0, + .mode = MTU_PERIODIC, + .name = "Nomadik Timer Tick", +}; + +static void __init nomadik_time_init(void) +{ + ktime_t sys_timer_period = ktime_set(0, TIMER_PERIOD); + nomadik_mtu_init(); /* there is no better way to call this init function */ + + mtu_timer_tick.interval = sys_timer_period; + mtu_timer_tick.mtu_irq = nomadik_timer_interrupt; + + if (mtu_register_timer(&mtu_timer_tick) < 0) { + panic("Could not initialize system timer.\n"); + } +} +#else +/* + * Set up timer interrupt, and return the current time in seconds. + */ + +static struct irqaction nomadik_timer_irq = { + .name = "Nomadik Timer Tick", + .flags = SA_INTERRUPT | IRQF_TIMER, + .handler = nomadik_timer_interrupt, +}; + +static void __init nomadik_time_init(void) +{ + + unsigned long *psrc_cr = (unsigned long *)IO_ADDRESS(NOMADIK_SRC_BASE); + unsigned long src_cr; + + src_cr = *psrc_cr; + src_cr |= CR_INIT_VAL; + *psrc_cr = src_cr; + + mtu_reg->tmr_control1 = 0; + + mtu_reg->tmr_load1 = TIMER_RELOAD; + mtu_reg->tmr_bgload1 = TIMER_RELOAD; + mtu_reg->tmr_control1 = (TIMER_CTRL | TIMER_PERIODIC | TIMER_SZ32BIT); + mtu_reg->tmr_imsc |= 1; + mtu_reg->tmr_control1 |= (1 << 7); /* enable timer */ + + /* + * Make irqs happen for the system timer + */ + setup_irq(IRQ_MTU0, &nomadik_timer_irq); +} +#endif + +#ifdef CONFIG_PM + +#if defined(CONFIG_NOMADIK_MTU) +extern int nomadik_mtu_suspend(void); +#endif + +static void nomadik_time_suspend(void) +{ +#if defined(CONFIG_NOMADIK_MTU) + nomadik_mtu_suspend(); +#endif + +} + +static void nomadik_time_resume(void) +{ +#if defined(CONFIG_NOMADIK_MTU) + extern int nomadik_mtu_resume(void); + nomadik_mtu_resume(); +#endif + +} +#else +#define nomadik_time_suspend NULL +#define nomadik_time_resume NULL + +#endif + +#ifdef CONFIG_NO_IDLE_HZ +static int nomadik_dyn_tick_enable_disable(void) +{ + return 0; +} + +static void nomadik_dyn_tick_reprogram(unsigned long ticks) +{ + volatile unsigned long val; + + if (ticks > 1) { + val = mtu_reg->tmr_value1; + + /* + * Conservatively assuming that max. 2 timer counts can be + * taken in this processing. Below condition looks unlikely + */ + if ((mtu_reg->tmr_mis & 0x1) || (val <= 2)) { + /* + while (mtu_reg->tmr_value1 < 2) ; + mtu_reg->tmr_icr |= 1; + */ + + return; + } + ticks--; + last_load_value = ticks * TIMER_RELOAD + val; + mtu_reg->tmr_load1 = last_load_value; + mtu_reg->tmr_bgload1 = TIMER_RELOAD; + nomadik_idle_ticks = last_load_value - val; + dynamic_tick_started = 1; + } +} + +static irqreturn_t +nomadik_dyn_tick_handler(int irq, void *dev_id) +{ + long elapsed_time; + + if (dynamic_tick_started) { + + if ((mtu_reg->tmr_mis & 0x1) || (mtu_reg->tmr_value1 < 2)) { + do { + } while (mtu_reg->tmr_value1 < 2); +#if defined(CONFIG_MTU0) && defined(CONFIG_NOMADIK_MTU_SYSTEM_TICK) + return nomadik_timer_interrupt(MTU0_T0); +#else + return nomadik_timer_interrupt(irq, dev_id); +#endif + } else { + elapsed_time = last_load_value - mtu_reg->tmr_value1; + } + + if (elapsed_time >= TIMER_RELOAD) { +#if defined(CONFIG_MTU0) && defined(CONFIG_NOMADIK_MTU_SYSTEM_TICK) + return nomadik_timer_interrupt(MTU0_T0); +#else + return nomadik_timer_interrupt(irq, dev_id); +#endif + } else { + dynamic_tick_started = 0; + mtu_reg->tmr_load1 = mtu_reg->tmr_value1 % TIMER_RELOAD; + mtu_reg->tmr_bgload1 = TIMER_RELOAD; + last_load_value = TIMER_RELOAD; + nomadik_idle_ticks = 0; + return IRQ_HANDLED; + } + } + return IRQ_NONE; +} + +struct dyn_tick_timer nomadik_dyn_tick = { + .enable = nomadik_dyn_tick_enable_disable, + .disable = nomadik_dyn_tick_enable_disable, + .reprogram = nomadik_dyn_tick_reprogram, + .handler = nomadik_dyn_tick_handler, +}; +#endif + +struct sys_timer nomadik_timer = { + .init = nomadik_time_init, + .offset = nomadik_gettimeoffset, + .suspend = nomadik_time_suspend, + .resume = nomadik_time_resume, +#ifdef CONFIG_NO_IDLE_HZ + .dyn_tick = &nomadik_dyn_tick, +#endif +}; --- linux-2.6.20.orig/arch/arm/mm/Kconfig +++ linux-2.6.20/arch/arm/mm/Kconfig @@ -58,11 +58,11 @@ config CPU_ARM710 Say Y if you want support for the ARM710 processor. Otherwise, say N. # ARM720T config CPU_ARM720T - bool "Support ARM720T processor" if !ARCH_CLPS711X && !ARCH_L7200 && !ARCH_CDB89712 && ARCH_INTEGRATOR + bool "Support ARM720T processor" if !ARCH_CLPS711X && !ARCH_L7200 && !ARCH_CDB89712 && ARCH_INTEGRATOR && ARCH_NOMADIK default y if ARCH_CLPS711X || ARCH_L7200 || ARCH_CDB89712 || ARCH_H720X select CPU_32v4T select CPU_ABRT_LV4T select CPU_CACHE_V4 select CPU_CACHE_VIVT @@ -107,11 +107,11 @@ config CPU_ARM9TDMI Otherwise, say N. # ARM920T config CPU_ARM920T bool "Support ARM920T processor" - depends on ARCH_EP93XX || ARCH_INTEGRATOR || CPU_S3C2410 || CPU_S3C2440 || CPU_S3C2442 || ARCH_IMX || ARCH_AAEC2000 || ARCH_AT91RM9200 + depends on ARCH_EP93XX || ARCH_INTEGRATOR || ARCH_NOMADIK || CPU_S3C2410 || CPU_S3C2440 || CPU_S3C2442 || ARCH_IMX || ARCH_AAEC2000 || ARCH_AT91RM9200 default y if CPU_S3C2410 || CPU_S3C2440 || CPU_S3C2442 || ARCH_AT91RM9200 select CPU_32v4T select CPU_ABRT_EV4T select CPU_CACHE_V4WT select CPU_CACHE_VIVT @@ -129,11 +129,11 @@ config CPU_ARM920T Otherwise, say N. # ARM922T config CPU_ARM922T bool "Support ARM922T processor" if ARCH_INTEGRATOR - depends on ARCH_LH7A40X || ARCH_INTEGRATOR + depends on ARCH_LH7A40X || ARCH_INTEGRATOR || ARCH_NOMADIK default y if ARCH_LH7A40X select CPU_32v4T select CPU_ABRT_EV4T select CPU_CACHE_V4WT select CPU_CACHE_VIVT @@ -166,14 +166,19 @@ config CPU_ARM925T device family. Say Y if you want support for the ARM925T processor. Otherwise, say N. +# L2 cache can be enabled in processor specific configuration if required +config L2CACHE_ENABLE + bool + default n + # ARM926T config CPU_ARM926T bool "Support ARM926T processor" - depends on ARCH_INTEGRATOR || ARCH_VERSATILE_PB || MACH_VERSATILE_AB || ARCH_OMAP730 || ARCH_OMAP16XX || MACH_REALVIEW_EB || ARCH_PNX4008 || ARCH_NETX || CPU_S3C2412 || ARCH_AT91SAM9260 || ARCH_AT91SAM9261 + depends on ARCH_NOMADIK || ARCH_INTEGRATOR || ARCH_VERSATILE_PB || MACH_VERSATILE_AB || ARCH_OMAP730 || ARCH_OMAP16XX || MACH_REALVIEW_EB || ARCH_PNX4008 || ARCH_NETX || CPU_S3C2412 || ARCH_AT91SAM9260 || ARCH_AT91SAM9261 default y if ARCH_VERSATILE_PB || MACH_VERSATILE_AB || ARCH_OMAP730 || ARCH_OMAP16XX || ARCH_PNX4008 || ARCH_NETX || CPU_S3C2412 || ARCH_AT91SAM9260 || ARCH_AT91SAM9261 select CPU_32v5 select CPU_ABRT_EV5TJ select CPU_CACHE_VIVT select CPU_CP15_MMU @@ -221,11 +226,11 @@ config CPU_ARM946E Otherwise, say N. # ARM1020 - needs validating config CPU_ARM1020 bool "Support ARM1020T (rev 0) processor" - depends on ARCH_INTEGRATOR + depends on ARCH_INTEGRATOR || ARCH_NOMADIK select CPU_32v5 select CPU_ABRT_EV4T select CPU_CACHE_V4WT select CPU_CACHE_VIVT select CPU_CP15_MMU @@ -239,11 +244,11 @@ config CPU_ARM1020 Otherwise, say N. # ARM1020E - needs validating config CPU_ARM1020E bool "Support ARM1020E processor" - depends on ARCH_INTEGRATOR + depends on ARCH_INTEGRATOR || ARCH_NOMADIK select CPU_32v5 select CPU_ABRT_EV4T select CPU_CACHE_V4WT select CPU_CACHE_VIVT select CPU_CP15_MMU @@ -252,11 +257,11 @@ config CPU_ARM1020E depends on n # ARM1022E config CPU_ARM1022 bool "Support ARM1022E processor" - depends on ARCH_INTEGRATOR + depends on ARCH_INTEGRATOR || ARCH_NOMADIK select CPU_32v5 select CPU_ABRT_EV4T select CPU_CACHE_VIVT select CPU_CP15_MMU select CPU_COPY_V4WB if MMU # can probably do better @@ -270,11 +275,11 @@ config CPU_ARM1022 Otherwise, say N. # ARM1026EJ-S config CPU_ARM1026 bool "Support ARM1026EJ-S processor" - depends on ARCH_INTEGRATOR + depends on ARCH_INTEGRATOR || ARCH_NOMADIK select CPU_32v5 select CPU_ABRT_EV5T # But need Jazelle, but EV5TJ ignores bit 10 select CPU_CACHE_VIVT select CPU_CP15_MMU select CPU_COPY_V4WB if MMU # can probably do better @@ -343,11 +348,11 @@ config CPU_XSC3 select IO_36 # ARMv6 config CPU_V6 bool "Support ARM V6 processor" - depends on ARCH_INTEGRATOR || MACH_REALVIEW_EB || ARCH_OMAP2 + depends on ARCH_NOMADIK || ARCH_INTEGRATOR || MACH_REALVIEW_EB || ARCH_OMAP2 select CPU_32v6 select CPU_ABRT_EV6 select CPU_CACHE_V6 select CPU_CACHE_VIPT select CPU_CP15_MMU --- linux-2.6.20.orig/arch/arm/mm/extable.c +++ linux-2.6.20/arch/arm/mm/extable.c @@ -1,16 +1,23 @@ /* * linux/arch/arm/mm/extable.c */ #include +#include #include int fixup_exception(struct pt_regs *regs) { const struct exception_table_entry *fixup; fixup = search_exception_tables(instruction_pointer(regs)); if (fixup) regs->ARM_pc = fixup->fixup; +#ifdef CONFIG_KGDB + if (atomic_read(&debugger_active) && kgdb_may_fault) + /* Restore our previous state. */ + kgdb_fault_longjmp(kgdb_fault_jmp_regs); + /* Not reached. */ +#endif return fixup != NULL; } --- linux-2.6.20.orig/arch/arm/mm/init.c +++ linux-2.6.20/arch/arm/mm/init.c @@ -87,11 +87,10 @@ void show_mem(void) printk("%d reserved pages\n", reserved); printk("%d slab pages\n", slab); printk("%d pages shared\n", shared); printk("%d pages swap cached\n", cached); } - /* * FIXME: We really want to avoid allocating the bootmap bitmap * over the top of the initrd. Hopefully, this is located towards * the start of a bank, so if we allocate the bootmap bitmap at * the end, we won't clash. --- linux-2.6.20.orig/arch/arm/mm/proc-arm926.S +++ linux-2.6.20/arch/arm/mm/proc-arm926.S @@ -22,19 +22,24 @@ * * These are the low level assembler for performing cache and TLB * functions on the arm926. * * CONFIG_CPU_ARM926_CPU_IDLE -> nohlt + * + * History: + * 03/09/2007 Purpose: Macros added to support L2 Cache + * Author: STMicroelectronics */ #include #include #include #include #include #include #include #include +#include #include "proc-macros.S" /* * This is the maximum size of an area which will be invalidated * using the single invalidate entry instructions. Anything larger @@ -63,13 +68,19 @@ ENTRY(cpu_arm926_proc_init) ENTRY(cpu_arm926_proc_fin) stmfd sp!, {lr} mov ip, #PSR_F_BIT | PSR_I_BIT | SVC_MODE msr cpsr_c, ip bl arm926_flush_kern_cache_all +#ifdef CONFIG_L2CACHE_ENABLE + v_l2_cache_clean_and_invalidate r0, r1 + v_l2_cache_sync r0, r1 + v_l2_cache_disable r0,r1 +#endif mrc p15, 0, r0, c1, c0, 0 @ ctrl register bic r0, r0, #0x1000 @ ...i............ bic r0, r0, #0x000e @ ............wca. + mcr p15, 0, r0, c1, c0, 0 @ disable caches ldmfd sp!, {pc} /* * cpu_arm926_reset(loc) @@ -251,10 +262,13 @@ ENTRY(arm926_dma_inv_range) bic r0, r0, #CACHE_DLINESIZE - 1 1: mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry add r0, r0, #CACHE_DLINESIZE cmp r0, r1 blo 1b +#ifdef CONFIG_L2CACHE_ENABLE + /*l2_cache_clean_and_invalidate r2, r3*/ +#endif mcr p15, 0, r0, c7, c10, 4 @ drain WB mov pc, lr /* * dma_clean_range(start, end) @@ -272,10 +286,13 @@ ENTRY(arm926_dma_clean_range) 1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry add r0, r0, #CACHE_DLINESIZE cmp r0, r1 blo 1b #endif +#ifdef CONFIG_L2CACHE_ENABLE + /*l2_cache_clean r2, r3*/ +#endif mcr p15, 0, r0, c7, c10, 4 @ drain WB mov pc, lr /* * dma_flush_range(start, end) @@ -294,10 +311,13 @@ ENTRY(arm926_dma_flush_range) mcr p15, 0, r0, c7, c10, 1 @ clean D entry #endif add r0, r0, #CACHE_DLINESIZE cmp r0, r1 blo 1b +#ifdef CONFIG_L2CACHE_ENABLE + /*l2_cache_clean_and_invalidate r2, r3*/ +#endif mcr p15, 0, r0, c7, c10, 4 @ drain WB mov pc, lr ENTRY(arm926_cache_fns) .long arm926_flush_kern_cache_all @@ -339,10 +359,14 @@ ENTRY(cpu_arm926_switch_mm) @ && 'Clean & Invalidate whole DCache' 1: mrc p15, 0, r15, c7, c14, 3 @ test,clean,invalidate bne 1b #endif mcr p15, 0, ip, c7, c5, 0 @ invalidate I cache +#ifdef CONFIG_L2CACHE_ENABLE + /*l2_cache_clean r2, r3 + l2_cache_invalidate r2, r3*/ +#endif mcr p15, 0, ip, c7, c10, 4 @ drain WB mcr p15, 0, r0, c2, c0, 0 @ load page table pointer mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs #endif mov pc, lr @@ -409,10 +433,16 @@ __arm926_setup: bic r0, r0, r5 orr r0, r0, r6 #ifdef CONFIG_CPU_CACHE_ROUND_ROBIN orr r0, r0, #0x4000 @ .1.. .... .... .... #endif +#if CONFIG_L2CACHE_ENABLE + l2_cache_disable r2, r3 @disable L2 Cache + l2_cache_configure r2, r3 @configures L2 Cache Controller + l2_cache_invalidate r2, r3 + l2_cache_enable r2, r3 @enable L2 Cache +#endif mov pc, lr .size __arm926_setup, . - __arm926_setup /* * R --- linux-2.6.20.orig/arch/arm/oprofile/common.c +++ linux-2.6.20/arch/arm/oprofile/common.c @@ -151,14 +151,15 @@ int __init oprofile_arch_init(struct opr ops->setup = op_arm_setup; ops->shutdown = op_arm_stop; ops->start = op_arm_start; ops->stop = op_arm_stop; ops->cpu_type = op_arm_model->name; - ops->backtrace = arm_backtrace; printk(KERN_INFO "oprofile: using %s\n", spec->name); } + ops->backtrace = arm_backtrace; + return ret; } void oprofile_arch_exit(void) { --- linux-2.6.20.orig/drivers/Makefile +++ linux-2.6.20/drivers/Makefile @@ -3,10 +3,11 @@ # # 15 Sep 2000, Christoph Hellwig # Rewritten to use lists instead of if-statements. # +obj-$(CONFIG_I2C) += i2c/ obj-$(CONFIG_PCI) += pci/ obj-$(CONFIG_PARISC) += parisc/ obj-$(CONFIG_RAPIDIO) += rapidio/ obj-y += video/ obj-$(CONFIG_ACPI) += acpi/ @@ -55,11 +56,10 @@ obj-$(CONFIG_USB_GADGET) += usb/gadget/ obj-$(CONFIG_SERIO) += input/serio/ obj-$(CONFIG_GAMEPORT) += input/gameport/ obj-$(CONFIG_INPUT) += input/ obj-$(CONFIG_I2O) += message/ obj-$(CONFIG_RTC_LIB) += rtc/ -obj-$(CONFIG_I2C) += i2c/ obj-$(CONFIG_W1) += w1/ obj-$(CONFIG_HWMON) += hwmon/ obj-$(CONFIG_PHONE) += telephony/ obj-$(CONFIG_MD) += md/ obj-$(CONFIG_BT) += bluetooth/ --- linux-2.6.20.orig/drivers/char/keyboard.c +++ linux-2.6.20/drivers/char/keyboard.c @@ -1181,10 +1181,11 @@ static void kbd_keycode(unsigned int key } if (sysrq_down && !down && keycode == sysrq_alt_use) sysrq_down = 0; if (sysrq_down && down && !rep) { handle_sysrq(kbd_sysrq_xlate[keycode], tty); + sysrq_down = 0; /* In case we miss the 'up' event. */ return; } #endif #ifdef CONFIG_SPARC if (keycode == KEY_A && sparc_l1_a_state) { --- linux-2.6.20.orig/drivers/cpufreq/Kconfig +++ linux-2.6.20/drivers/cpufreq/Kconfig @@ -138,6 +138,10 @@ config CPU_FREQ_GOV_CONSERVATIVE For details, take a look at linux/Documentation/cpu-freq. If in doubt, say N. +config CPU_FREQ_NOMADIK + tristate "cpu freq scaling support for nomadik" + depends on CPU_FREQ + endif # CPU_FREQ --- linux-2.6.20.orig/drivers/hwmon/Kconfig +++ linux-2.6.20/drivers/hwmon/Kconfig @@ -228,10 +228,23 @@ config SENSORS_IT87 IT8716F and IT8718F sensor chips, and the SiS960 clone. This driver can also be built as a module. If so, the module will be called it87. +config SENSORS_LIS3LV02DL + tristate "LIS3LV02DL MEMS three-axis accelerometer I2C driver" + depends on HWMON && I2C && EXPERIMENTAL + default n + help + This driver provides support for the ST microelectronics LIS3LV02DL + MEMS inertial sensor which provides a three-axis, I2C controlled + ± 2g/± 6g digital output linear accelerometer. The accelerometer + data is readable via sysfs. + + This driver can also be built as a module. If so, the module + will be called lis3vl02dl. + config SENSORS_LM63 tristate "National Semiconductor LM63" depends on HWMON && I2C help If you say yes here you get support for the National Semiconductor --- linux-2.6.20.orig/drivers/hwmon/Makefile +++ linux-2.6.20/drivers/hwmon/Makefile @@ -28,10 +28,11 @@ obj-$(CONFIG_SENSORS_FSCPOS) += fscpos.o obj-$(CONFIG_SENSORS_GL518SM) += gl518sm.o obj-$(CONFIG_SENSORS_GL520SM) += gl520sm.o obj-$(CONFIG_SENSORS_HDAPS) += hdaps.o obj-$(CONFIG_SENSORS_IT87) += it87.o obj-$(CONFIG_SENSORS_K8TEMP) += k8temp.o +obj-$(CONFIG_SENSORS_LIS3LV02DL)+= lis3lv02dl.o obj-$(CONFIG_SENSORS_LM63) += lm63.o obj-$(CONFIG_SENSORS_LM70) += lm70.o obj-$(CONFIG_SENSORS_LM75) += lm75.o obj-$(CONFIG_SENSORS_LM77) += lm77.o obj-$(CONFIG_SENSORS_LM78) += lm78.o --- /dev/null +++ linux-2.6.20/drivers/hwmon/lis3lv02dl.c @@ -0,0 +1,489 @@ +/* + stmems.c + + Copyright (c) 2008 Nicholas Angelo Crespi + + LIS3LV02DL MEMS inertial sensor is a 3-axis - ± 2g/± 6g digital output + low voltage linear accelerometer. + http://www.st.com/stonline/products/literature/ds/12094/lis3lv02dl.htm + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + * Compile this driver with: + + echo "obj-m := tiny_i2c_chip.o" > Makefile + make -C SUBDIRS=$PWD modules + */ + +#define DEBUG 1 +#define VERSION "0.2" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define stmems_perror(format, arg...) +//printk( KERN_ERR "STMEMS: %s " format, __func__, ## arg) +#define stmems_pinfo(format, arg...) +//printk( KERN_INFO "STMEMS: %s " format, __func__, ## arg) + +/* Addresses to scan */ + +//static unsigned short normal_i2c[] = { 0x3A, I2C_CLIENT_END }; +static unsigned short normal_i2c[] = { 0x1D, I2C_CLIENT_END }; + +//static unsigned short normal_i2c_range[] = { 0x00, 0xff, I2C_CLIENT_END }; + +/* Insmod parameters */ +I2C_CLIENT_INSMOD_1(stmems); + +/* Each client has this additional data */ +struct stmems_data { + struct i2c_client client; + struct class_device *class_dev; + struct mutex update_lock; + char valid; /* !=0 if following fields are valid */ + unsigned long last_updated; /* In jiffies */ + int acc_x; /* Register values */ + int acc_y; + int acc_z; + u8 divisor; + u8 fullscale; + u8 BDU; +}; + +/* stmems registers mnemonics */ +/* mnemonic hex r/w default */ +#define MEMS_WHO_AM_I 0x0F /*r 00111010 */ +#define MEMS_OFFSET_X 0x16 /*rw calib */ +#define MEMS_OFFSET_Y 0x17 /*rw calib */ +#define MEMS_OFFSET_Z 0x18 /*rw calib */ +#define MEMS_GAIN_X 0x19 /*rw calib */ +#define MEMS_GAIN_Y 0x1A /*rw calib */ +#define MEMS_GAIN_Z 0x1B /*rw calib */ +#define MEMS_CTRL_REG1 0x20 /*rw 00000111 */ +#define MEMS_CTRL_REG2 0x21 /*rw 00000000 */ +#define MEMS_CTRL_REG3 0x22 /*rw 00001000 */ +#define MEMS_HP_FILTER RESET 0x23 /*r dummy */ +#define MEMS_STATUS_REG 0x27 /*rw 00000000 */ +#define MEMS_OUTX_L 0x28 /*r */ +#define MEMS_OUTX_H 0x29 /*r */ +#define MEMS_OUTY_L 0x2A /*r */ +#define MEMS_OUTY_H 0x2B /*r */ +#define MEMS_OUTZ_L 0x2C /*r */ +#define MEMS_OUTZ_H 0x2D /*r */ +#define MEMS_FF_WU_CFG 0x30 /*rw 00000000 */ +#define MEMS_FF_WU_SRC 0x31 /*rw 00000000 */ +#define MEMS_FF_WU_ACK 0x32 /*r */ +#define MEMS_FF_WU_THS_L 0x34 /*rw 00000000 */ +#define MEMS_FF_WU_THS_H 0x35 /*rw 00000000 */ +#define MEMS_FF_WU_DURATION 0x36 /*rw 00000000 */ +#define MEMS_DD_CFG 0x38 /*rw 00000000 */ +#define MEMS_DD_SRC 0x39 /*rw 00000000 */ +#define MEMS_DD_ACK 0x3A /*r */ +#define MEMS_DD_THSI_L 0x3C /*rw 00000000 */ +#define MEMS_DD_THSI_H 0x3D /*rw 00000000 */ +#define MEMS_DD_THSE_L 0x3E /*rw 00000000 */ +#define MEMS_DD_THSE_H 0x3F /*rw 00000000 */ + + +static int stmems_attach_adapter(struct i2c_adapter *adapter); +static int stmems_detect(struct i2c_adapter *adapter, int address, int kind); +static int stmems_detach_client(struct i2c_client *client); +static void stmems_init_sensor(struct i2c_client *client); +static inline u8 stmems_read_value(struct i2c_client *client, u8 reg); +static inline u8 stmems_write_value(struct i2c_client *client, u8 reg, u8 value); +static inline int stmems_join(u8 LSB, u8 MSB); +static struct stmems_data *stmems_update_device(struct device *dev); + +/* This is the driver that will be inserted */ +static struct i2c_driver stmems_driver = { + .driver = { + .name = "stmems", + }, + .attach_adapter = stmems_attach_adapter, + .detach_client = stmems_detach_client, +}; + +/* read routines for accelerations */ +#define show(value) \ +static ssize_t show_##value(struct device *dev, struct device_attribute *attr, char *buf) \ +{ \ + struct stmems_data *data = stmems_update_device(dev); \ + return sprintf(buf, "%d\n", data->value); \ +} +show(acc_x); +show(acc_y); +show(acc_z); + +/* read routines for divisor, BDU and fullscale */ +static ssize_t show_divisor(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct stmems_data *data = i2c_get_clientdata(client); + if (!(data->valid)) + data = stmems_update_device(dev); + return sprintf(buf, "%d\n", data->divisor); +} + +static ssize_t show_fullscale(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct stmems_data *data = i2c_get_clientdata(client); + if (!(data->valid)) + data=stmems_update_device(dev); + return sprintf(buf, "%d\n", data->fullscale); +} +static ssize_t show_BDU(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct stmems_data *data = i2c_get_clientdata(client); + if (!(data->valid)) + data=stmems_update_device(dev); + return sprintf(buf, "%d\n", data->BDU); +} + +/* this macro is useless! */ +#define set(value, reg) \ +static ssize_t set_##value(struct device *dev, const char *buf, size_t count) \ +{ \ + struct i2c_client *client = to_i2c_client(dev); \ + struct stmems_data *data = i2c_get_clientdata(client); \ + int temp = simple_strtoul(buf, NULL, 10); \ + \ + mutex_lock(&data->update_lock); \ + data->value = temp; \ + mutex_unlock(&data->update_lock); \ + return count; \ +} + +/* Write routines for divisor, BDU and fullscale */ +static ssize_t set_divisor(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) +{ + struct i2c_client *client = to_i2c_client(dev); + struct stmems_data *data = i2c_get_clientdata(client); + u8 ctrl_reg; + int temp = simple_strtoul(buf, NULL, 10); + /* the divisor input can only be 512,128,32 or 8 */ + if ((temp!= 8) && (temp!= 32) && (temp!= 128) && (temp!= 512)) return 0; + mutex_lock(&data->update_lock); + data->divisor = temp; + ctrl_reg = stmems_read_value(client,MEMS_CTRL_REG1); + if (temp == 8) {ctrl_reg |= 0x30;} + else if (temp == 32) {ctrl_reg |= 0x20; ctrl_reg &= 0xEF;} + else if (temp == 128) {ctrl_reg |= 0x10; ctrl_reg &= 0xDF;} + else {ctrl_reg &= 0xCF; } + stmems_write_value(client,MEMS_CTRL_REG1,ctrl_reg); + mutex_unlock(&data->update_lock); + return count; +} + +static ssize_t set_fullscale(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) +{ + struct i2c_client *client = to_i2c_client(dev); + struct stmems_data *data = i2c_get_clientdata(client); + u8 ctrl_reg; + int temp = simple_strtoul(buf, NULL, 10); + if ((temp!= 1) && (temp!= 0)) return 0; + mutex_lock(&data->update_lock); + data->fullscale = temp; + ctrl_reg = stmems_read_value(client,MEMS_CTRL_REG2); + if (temp) {ctrl_reg |= 0x80;} + else {ctrl_reg &= 0x7F; } + stmems_write_value(client,MEMS_CTRL_REG2,ctrl_reg); + mutex_unlock(&data->update_lock); + return count; +} + +static ssize_t set_BDU(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) +{ + struct i2c_client *client = to_i2c_client(dev); + struct stmems_data *data = i2c_get_clientdata(client); + u8 ctrl_reg; + int temp = simple_strtoul(buf, NULL, 10); + if ((temp!= 1) && (temp!= 0)) return 0; + mutex_lock(&data->update_lock); + data->BDU = temp; + ctrl_reg = stmems_read_value(client,MEMS_CTRL_REG2); + if (temp) {ctrl_reg |= 0x40;} + else {ctrl_reg &= 0xBF; } + stmems_write_value(client,MEMS_CTRL_REG2,ctrl_reg); + mutex_unlock(&data->update_lock); + return count; +} + +static DEVICE_ATTR(acc_x, S_IRUGO, + show_acc_x, NULL); +static DEVICE_ATTR(acc_y, S_IRUGO, + show_acc_y, NULL); +static DEVICE_ATTR(acc_z, S_IRUGO, + show_acc_z, NULL); + +static DEVICE_ATTR(fullscale, S_IWUSR | S_IRUGO, + show_fullscale, set_fullscale); +static DEVICE_ATTR(divisor, S_IWUSR | S_IRUGO, + show_divisor, set_divisor); +static DEVICE_ATTR(BDU, S_IWUSR | S_IRUGO, + show_BDU, set_BDU); + +static int stmems_attach_adapter(struct i2c_adapter *adapter) +{ + int err; + + stmems_pinfo("entered\n"); + stmems_pinfo("adapter class: %d\n", adapter->class); + + if (!(adapter->class & I2C_CLASS_HWMON)) + { + stmems_perror("adapter class is not HWMON skip\n"); + return 0; + } + + err = i2c_probe(adapter, &addr_data, stmems_detect); + + return err; +} + + +/* This function is called by i2c_probe */ +static int stmems_detect(struct i2c_adapter *adapter, int address, int kind) +{ + struct i2c_client *new_client = NULL; + struct stmems_data *data = NULL; + int err = 0; + u8 temp_reg; + int ret; + + + stmems_pinfo("entered\n"); + + stmems_pinfo("kind: %d\n", kind); + stmems_pinfo("address: %d\n", address); + + if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) + { + stmems_perror("no SMBUS BYTE functionality detected\n"); + goto error; + } + + if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_READ_BYTE)) + { + stmems_perror("no SMBUS READ BYTE DATA functionality detected\n"); + goto error; + } + + if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_READ_BYTE_DATA)) + { + stmems_perror("no SMBUS READ BYTE functionality detected\n"); + goto error; + } + + if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WRITE_BYTE)) + { + stmems_perror("no SMBUS WRITE BYTE DATA functionality detected\n"); + goto error; + } + + if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WRITE_BYTE_DATA)) + { + stmems_perror("no SMBUS WRITE BYTE functionality detected\n"); + goto error; + } + + /* OK. For now, we presume we have a valid client. We now create the + client structure, even though we cannot fill it completely yet. + But it allows us to access stmems_{read,write}_value. */ + data = kzalloc(sizeof(struct stmems_data), GFP_KERNEL); + if (!data) { + err = -ENOMEM; + goto error; + } + + memset(data, 0x00, sizeof(*data)); + + new_client = &data->client; + i2c_set_clientdata(new_client, data); + new_client->addr = address; + new_client->adapter = adapter; + new_client->driver = &stmems_driver; + new_client->flags = 0; + + /* Chip detection: + since the chip has a register that holds its hardware address, + we use that as an identification field. */ + if (kind < 0){ + temp_reg = stmems_read_value(new_client, MEMS_WHO_AM_I); + //if ( (int)temp_reg != address) + // goto free_error; + } + + /* Fill in the remaining client fields */ + strncpy(new_client->name, "stmems", I2C_NAME_SIZE); + data->valid = 0; + mutex_init(&data->update_lock); + + /* Tell the I2C layer a new client has arrived */ + err = i2c_attach_client(new_client); + if (err) + goto error; + + /* Initialize the chip */ + stmems_init_sensor(new_client); + + /* Register sysfs hooks */ + data->class_dev = hwmon_device_register(&new_client->dev); + if (IS_ERR(data->class_dev)) { + err = PTR_ERR(data->class_dev); + goto detach_error; + } + + ret = device_create_file(&new_client->dev, &dev_attr_acc_x); + ret = device_create_file(&new_client->dev, &dev_attr_acc_y); + ret = device_create_file(&new_client->dev, &dev_attr_acc_z); + ret = device_create_file(&new_client->dev, &dev_attr_divisor); + ret = device_create_file(&new_client->dev, &dev_attr_fullscale); + ret = device_create_file(&new_client->dev, &dev_attr_BDU); + return 0; + +detach_error: + i2c_detach_client(new_client); +//free_error: + kfree(data); +error: + return err; +} + +//TODO: powerdown +static int stmems_detach_client(struct i2c_client *client) +{ + struct stmems_data *data = i2c_get_clientdata(client); + hwmon_device_unregister(data->class_dev); + i2c_detach_client(client); + kfree(data); + return 0; +} + +/* Configure the chip, mainly with default values */ +static void stmems_init_sensor(struct i2c_client *client){ + u8 conf_reg; + /* CTRL_REG1: enable axis, turn down powerdown mode, freq divisor 512 */ + + conf_reg = 0xC7; + + stmems_pinfo("entered\n"); + + stmems_write_value(client, MEMS_CTRL_REG1, conf_reg); + /* CTRL_REG2: fullscale 2g, batch update, big endian, disable INT, + 12bit right-justified, */ + conf_reg = stmems_read_value(client, MEMS_CTRL_REG2); + conf_reg = 0x60; + + stmems_write_value(client, MEMS_CTRL_REG2, conf_reg); + /* CTRL_REG3: disable interrupts generation, leave others values*/ + conf_reg = stmems_read_value(client, MEMS_CTRL_REG3); + conf_reg &= 0x8F; + stmems_write_value(client, MEMS_CTRL_REG3, conf_reg); + return; +} + +static struct stmems_data *stmems_update_device(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct stmems_data *data = i2c_get_clientdata(client); + u8 status_reg; + + stmems_pinfo("entered\n"); + + mutex_lock(&data->update_lock); + dev_dbg(&client->dev, "%s\n", __FUNCTION__); + status_reg = stmems_read_value(client, MEMS_STATUS_REG); + //TODO: we're assuming big endianess + //TODO: use 0x08 instead + if (status_reg & 0x01) + data->acc_x = stmems_join(stmems_read_value(client, MEMS_OUTX_H), stmems_read_value(client, MEMS_OUTX_L)); + if (status_reg & 0x02) + data->acc_y = stmems_join(stmems_read_value(client, MEMS_OUTY_H), stmems_read_value(client, MEMS_OUTY_L)); + if (status_reg & 0x04) + data->acc_z = stmems_join(stmems_read_value(client, MEMS_OUTZ_H), stmems_read_value(client, MEMS_OUTZ_L)); + data->last_updated = jiffies; + data->valid = 1; + mutex_unlock(&data->update_lock); + + if (data) + { + stmems_pinfo("acc_x: %d\n", data->acc_x); + stmems_pinfo("acc_y: %d\n", data->acc_y); + stmems_pinfo("acc_z: %d\n", data->acc_z); + } + + return data; +} + +/* All registers are byte-sized */ +static inline u8 stmems_read_value(struct i2c_client *client, u8 reg) +{ + u8 temp; + + stmems_pinfo("reading: 0x%02X\n", reg); + temp = i2c_smbus_read_byte_data(client, reg); + //nomadik_i2c_read_register(I2C_MEMS_CLIENT,&temp,reg,1); + stmems_pinfo("read: 0x%02X, value: 0x%02X\n", reg, temp); + + return temp; +} + +static inline u8 stmems_write_value(struct i2c_client *client, u8 reg, u8 value) +{ + stmems_pinfo("writing: 0x%02X, value: 0x%02X\n", reg, value); + + return i2c_smbus_write_byte_data(client, reg, value); + //return nomadik_i2c_write_register(I2C_MEMS_CLIENT,&value,reg,1); +} + +static int __init stmems_init(void) +{ + stmems_pinfo("entered\n"); + + return i2c_add_driver(&stmems_driver); +} + +static void __exit stmems_exit(void) +{ + stmems_pinfo("entered\n"); + + i2c_del_driver(&stmems_driver); +} + +static inline int stmems_join(u8 LSB, u8 MSB) +{ + /* In "12 bit right justified" mode, bit 6, bit 7, bit 8 = bit 5 */ + if (MSB & 0x10) + MSB |= 0xE0; + return (s16)(LSB | ((MSB << 8))); +} + +MODULE_AUTHOR("Nicholas Angelo Crespi "); +MODULE_DESCRIPTION("LIS3LV02DL MEMS three-axis accelerometer I2C driver"); +MODULE_VERSION(VERSION); +MODULE_LICENSE("GPL"); + +module_init(stmems_init); +module_exit(stmems_exit); --- linux-2.6.20.orig/drivers/i2c/Kconfig +++ linux-2.6.20/drivers/i2c/Kconfig @@ -32,10 +32,11 @@ config I2C_CHARDEV contained in the file . This support is also available as a module. If so, the module will be called i2c-dev. + source drivers/i2c/algos/Kconfig source drivers/i2c/busses/Kconfig source drivers/i2c/chips/Kconfig config I2C_DEBUG_CORE --- linux-2.6.20.orig/drivers/i2c/Makefile +++ linux-2.6.20/drivers/i2c/Makefile @@ -1,11 +1,12 @@ # -# Makefile for the i2c core. +# Makefile for the kernel i2c bus driver. # obj-$(CONFIG_I2C) += i2c-core.o obj-$(CONFIG_I2C_CHARDEV) += i2c-dev.o + obj-y += busses/ chips/ algos/ ifeq ($(CONFIG_I2C_DEBUG_CORE),y) EXTRA_CFLAGS += -DDEBUG endif --- linux-2.6.20.orig/drivers/i2c/busses/Kconfig +++ linux-2.6.20/drivers/i2c/busses/Kconfig @@ -15,10 +15,20 @@ config I2C_ALI1535 Power Management Unit (PMU). This driver can also be built as a module. If so, the module will be called i2c-ali1535. +config I2C_NOMADIK + tristate "I2C nomadik support" + depends on I2C + help + If you say yes to this option, support will be included for the i2c + controller on STn8810 . + This driver can also be built as a module. If so, the module + will be called nmdkmod_i2c. + + config I2C_ALI1563 tristate "ALI 1563" depends on I2C && PCI && EXPERIMENTAL help If you say yes to this option, support will be included for the SMB --- linux-2.6.20.orig/drivers/i2c/busses/Makefile +++ linux-2.6.20/drivers/i2c/busses/Makefile @@ -1,9 +1,26 @@ # # Makefile for the i2c bus drivers. # +TARGET_NAME = $(shell echo $(CONFIG_NOMADIK_TARGET)) +SOC_NAME = $(shell echo $(CONFIG_NOMADIK_SOC)) +PLATFORM_NAME = $(shell echo $(CONFIG_NOMADIK_PLATFORM)) + +ifeq ($(CONFIG_NOMADIK_NDK10),y) +EXTRA_CFLAGS := -D__I2C_ENHANCED -D__RELEASE -D__NOMADIK_I2C -D__I2C_8810 -D__STN_8810 +endif + +ifeq ($(CONFIG_NOMADIK_NDK15),y) +EXTRA_CFLAGS := -D__I2C_ENHANCED -D__RELEASE -D__NOMADIK_I2C -D__STN_8815=10 +endif + +ifeq ($(CONFIG_NOMADIK_NHK15),y) +EXTRA_CFLAGS := -D__I2C_ENHANCED -D__RELEASE -D__NOMADIK_I2C -D__STN_8815=10 +endif + +obj-$(CONFIG_I2C_NOMADIK) += nmdkmod_i2c.o obj-$(CONFIG_I2C_ALI1535) += i2c-ali1535.o obj-$(CONFIG_I2C_ALI1563) += i2c-ali1563.o obj-$(CONFIG_I2C_ALI15X3) += i2c-ali15x3.o obj-$(CONFIG_I2C_AMD756) += i2c-amd756.o obj-$(CONFIG_I2C_AMD756_S4882) += i2c-amd756-s4882.o @@ -48,5 +65,10 @@ obj-$(CONFIG_SCx200_ACB) += scx200_acb.o obj-$(CONFIG_SCx200_I2C) += scx200_i2c.o ifeq ($(CONFIG_I2C_DEBUG_BUS),y) EXTRA_CFLAGS += -DDEBUG endif + +nmdkmod_i2c-objs := i2c-nomadik.o +nmdkmod_i2c-objs += i2c-$(SOC_NAME).o + + --- /dev/null +++ linux-2.6.20/drivers/i2c/busses/i2c-nomadik.c @@ -0,0 +1,1250 @@ + +/* drivers/i2c/busses/i2c-nomadik.c + * + * Support for i2c bus on STn8800/8810/8815 (Nomadik) chips. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "i2c-nomadik.h" +#include +#define DRIVER_VERSION "2.0.0" +#define width 0 +#define BUSID 1 +#define error(format, arg...) printk( KERN_ERR "I2C: " format , ## arg) +#define info(format, arg...) +/*printk( KERN_INFO "I2C: %s " format, __func__, ## arg)*/ + +static unsigned int nomadik_i2c_func(struct i2c_adapter *adap); +static int nomadik_i2c_xfer_byte(struct i2c_adapter *i2c_adap, + struct i2c_msg msgs[], int num); +static int nomadik_i2c_xfer(struct i2c_adapter *i2c_adap, + struct i2c_msg msgs[], int num); + +/* Other variables indexed by bus */ +static struct nomadik_i2c_private i2c_driver[2]; + +static struct i2c_algorithm nomadik_i2c_algo = { + master_xfer:nomadik_i2c_xfer, + smbus_xfer:NULL, + algo_control:NULL, + functionality:nomadik_i2c_func +}; + +static struct i2c_adapter nomadik_i2c[2] = { { + name: "i2c0", + id: I2C_ALGO_NOMADIK | + I2C_HW_NOMADIK, + algo: &nomadik_i2c_algo, + data: &i2c_driver[0], + class: I2C_CLASS_HWMON + + }, +{ + name:"i2c1", + id:I2C_ALGO_NOMADIK | I2C_HW_NOMADIK, + algo:&nomadik_i2c_algo, + data:&i2c_driver[1], + } +}; + +#if !defined (CONFIG_NOMADIK_NHK15) +static struct i2c_client nomadik_i2c_clients[] = { + { + name:"motherboard", + id:I2C_MB_CLIENT, + flags:0, + addr:I2C_ADDR_MB, + adapter:&nomadik_i2c[BUSID] + }, + { + name:"ui db", + id:I2C_UI_DB_CLIENT, + flags:0, + addr:I2C_ADDR_UI_DB, + adapter:&nomadik_i2c[BUSID] + }, + { + name:"io expansion db1", + id:I2C_IO_EXP_DB1_CLIENT, + flags:0, + addr:I2C_ADDR_IO_DB1, + adapter:&nomadik_i2c[BUSID] + }, + { + name:"io expansion db2", + id:I2C_IO_EXP_DB2_CLIENT, + flags:0, + addr:I2C_ADDR_IO_DB2, + adapter:&nomadik_i2c[BUSID] + }, + { + name:"Matisse camera", + id:I2C_CIF_CAM_CLIENT, + flags:0, + addr:I2C_ADDR_CIF_CAM, + adapter:&nomadik_i2c[BUSID] + }, + { + name:"mem exp", + id:I2C_MEM_EXP_CLIENT, + flags:0, + addr:I2C_ADDR_MEM_EXP, + adapter:&nomadik_i2c[BUSID] + }, + { + name:"audio codec", + id:I2C_AUDIO_CODEC_CLIENT, + flags:0, + addr:I2C_ADDR_AC, + adapter:&nomadik_i2c[BUSID] + }, + { + name:"FM tuner", + id:I2C_FM_TUNER_CLIENT, + flags:0, + addr:I2C_ADDR_FM_TUNER, + adapter:&nomadik_i2c[BUSID] + }, + { + name:"Gas Gauge", + id:I2C_GAS_GAUGE_CLIENT, + flags:0, + addr:I2C_ADDR_GAS_GAUGE, + adapter:&nomadik_i2c[BUSID] + }, + { + name:"Matiise for litea cam", + id:I2C_LITEA_CAM_MOD_CLIENT, + flags:0, + addr:I2C_ADDR_CAM_MOD, + adapter:&nomadik_i2c[BUSID] + }, + { + name:"i2c0 loopback", + id:I2C0_LOOP_CLIENT, + flags:0, + addr:I2C0_LP_OWNADDR, + adapter:&nomadik_i2c[0] + }, + { + name:"i2c1 loopback", + id:I2C1_LOOP_CLIENT, + flags:0, + addr:I2C1_LP_OWNADDR, + adapter:&nomadik_i2c[1] + }, + { + name:"Pepperpot camera", + id:I2C_PP_CAM_CLIENT, + flags:0, + addr:I2C_ADDR_PP_CAM, + adapter:&nomadik_i2c[BUSID] + }, + { + name:"Touareg", + id:I2C_TOUAREG_CLIENT, + adapter:&nomadik_i2c[I2C_TOUAREG_ADAPTER], + flags:0, + addr:I2C_ADDR_TOUAREG, + } + +}; +#else +static struct i2c_client nomadik_i2c_clients[] = { + {//0x42 + name:"Denc", + id:I2C_DENC_CLIENT, + flags:0, + addr:I2C_ADDR_DENC, + adapter:&nomadik_i2c[0] + }, + {//0x34 + name:"audio codec", + id:I2C_AUDIO_CODEC_CLIENT, + flags:0, + addr:I2C_ADDR_AC, + adapter:&nomadik_i2c[0] + }, + {//0x20 + name:"FM tuner", + id:I2C_FM_TUNER_CLIENT, + flags:0, + addr:I2C_ADDR_FM_TUNER, + adapter:&nomadik_i2c[0] + }, + {//FIXME + name:"Matiise for litea cam", + id:I2C_LITEA_CAM_MOD_CLIENT, + flags:0, + addr:I2C_ADDR_CAM_MOD, + adapter:&nomadik_i2c[BUSID] + }, + {//0x3A + name:"mems", + id:I2C_MEMS_CLIENT, + flags:0, + addr:I2C_ADDR_MEMS, + adapter:&nomadik_i2c[0] + }, + {//0x44, 0x46 + name:"SIM card", + id:I2C_SIM_CLIENT, + flags:0, + addr:I2C_ADDR_SIM, + adapter:&nomadik_i2c[0] + }, + {//0x90 + name:"touch screen", + id:I2C_TOUCH_CLIENT, + flags:0, + addr:I2C_ADDR_TOUCH, + adapter:&nomadik_i2c[0] + }, + {//0x86 + name: "PEXP0", + id:I2C_STMPE0_CLIENT, + flags:0, + addr:I2C_ADDR_STMPE0, + adapter:&nomadik_i2c[0], + }, + {//0x88 + name: "PEXP1", + id:I2C_STMPE1_CLIENT, + flags:0, + addr:I2C_ADDR_STMPE1, + adapter:&nomadik_i2c[0], + }, + {//0xE0 + name:"Gas Gauge", + id:I2C_GAS_GAUGE_CLIENT, + flags:0, + addr:I2C_ADDR_GAS_GAUGE, + adapter:&nomadik_i2c[0] + }, + {//0x5A FIXME - MMC + name:"Power manager", + id:I2C_TOUAREG_CLIENT, + flags:0, + addr:I2C_ADDR_POWER, + adapter:&nomadik_i2c[0] + }, + { + name:"i2c0 loopback", + id:I2C0_LOOP_CLIENT, + flags:0, + addr:I2C0_LP_OWNADDR, + adapter:&nomadik_i2c[0] + }, + { + name:"i2c1 loopback", + id:I2C1_LOOP_CLIENT, + flags:0, + addr:I2C1_LP_OWNADDR, + adapter:&nomadik_i2c[1] + }, + +}; +#endif + +#if !defined(CONFIG_NOMADIK_NHK15) + +/* This is an array of bus ids indexed by client id. They MUST be in the + sam order as the client structs above + */ +static __u32 nomadik_client_bus_id[] = + { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, I2C_CLIENT_BUSID13 }; + +static struct nomadik_i2c_client priv_client[] = { + { + id:I2C_MB_CLIENT, + bus_id:BUSID, + addr:I2C_ADDR_MB, + endianness:LITTLE_END, + index_width:0}, + { + id:I2C_UI_DB_CLIENT, + bus_id:BUSID, + addr:I2C_ADDR_UI_DB, + endianness:LITTLE_END, + index_width:0}, + { + id:I2C_IO_EXP_DB1_CLIENT, + bus_id:BUSID, + addr:I2C_ADDR_IO_DB1, + endianness:LITTLE_END, + index_width:0}, + { + id:I2C_IO_EXP_DB2_CLIENT, + bus_id:BUSID, + addr:I2C_ADDR_IO_DB2, + endianness:LITTLE_END, + index_width:0}, + { + id:I2C_CIF_CAM_CLIENT, + bus_id:BUSID, + addr:I2C_ADDR_CIF_CAM, + endianness:LITTLE_END, + index_width:REG8}, + { + id:I2C_MEM_EXP_CLIENT, + bus_id:BUSID, + addr:I2C_ADDR_MEM_EXP, + endianness:LITTLE_END, + index_width:0}, + { + id:I2C_AUDIO_CODEC_CLIENT, + bus_id:1, + addr:I2C_ADDR_AC, + endianness:LITTLE_END, + index_width:REG8}, + { + id:I2C_FM_TUNER_CLIENT, + bus_id:BUSID, + addr:I2C_ADDR_FM_TUNER, + endianness:LITTLE_END, + index_width:0}, + { + id:I2C_GAS_GAUGE_CLIENT, + bus_id:BUSID, + addr:I2C_ADDR_GAS_GAUGE, + endianness:LITTLE_END, + index_width:0}, + { + id:I2C_LITEA_CAM_MOD_CLIENT, + bus_id:BUSID, + addr:I2C_ADDR_CAM_MOD, + endianness:LITTLE_END, + index_width:REG16}, + { + id:I2C0_LOOP_CLIENT, + bus_id:0, + addr:I2C0_LP_OWNADDR, + endianness:LITTLE_END, + index_width:0}, + { + id:I2C1_LOOP_CLIENT, + bus_id:1, + addr:I2C1_LP_OWNADDR, + endianness:LITTLE_END, + index_width:0}, + { + id:I2C_PP_CAM_CLIENT, + /* added for Pepperpot camera */ + bus_id:1, + addr:I2C_ADDR_PP_CAM, + endianness:BIG_END, + index_width:REG16}, + { + id:I2C_TOUAREG_CLIENT, + /* added for Touareg chip for power mgmt */ + bus_id:I2C_TOUREG_CLIENT_BUSID, + addr:I2C_ADDR_TOUAREG, + endianness:LITTLE_END, + index_width:REG8 +#ifdef CONFIG_NOMADIK_NDK15 + }, + { + id:I2C_CPLD_CLIENT, + /* added for CPLD */ + bus_id:I2C_CPLD_CLIENT_BUSID, + addr:I2C_ADDR_CPLD, + endianness:LITTLE_END, + /* check */ + index_width:REG8 +#endif + }, + { + id:I2C_DENC_CLIENT, + bus_id:1, + addr:I2C_ADDR_DENC, + endianness:LITTLE_END, + index_width:REG8} + +}; + +#else +/* This is an array of bus ids indexed by client id. They MUST be in the + sam order as the client structs above + */ +static __u32 nomadik_client_bus_id[] = + { 0, 0, 0, 0, 0, 0, 0, 0, 0 , 0, 0, 0, 1}; + +static struct nomadik_i2c_client priv_client[] = { + { + id:I2C_DENC_CLIENT, + bus_id:0, + addr:I2C_ADDR_DENC, + endianness:LITTLE_END, + index_width:REG8}, + { + id:I2C_AUDIO_CODEC_CLIENT, + bus_id:0, + addr:I2C_ADDR_AC, + endianness:LITTLE_END, + index_width:REG8}, + { + id:I2C_FM_TUNER_CLIENT, + bus_id:0, + addr:I2C_ADDR_FM_TUNER, + endianness:LITTLE_END, + index_width:0}, + { + id:I2C_LITEA_CAM_MOD_CLIENT, + bus_id:0, + addr:I2C_ADDR_CAM_MOD, + endianness:LITTLE_END, + index_width:0}, + { + id:I2C_MEMS_CLIENT, + bus_id:0, + addr:I2C_ADDR_MEMS, + endianness:LITTLE_END, + index_width:REG8}, + { + id:I2C_SIM_CLIENT, + bus_id:0, + addr:I2C_ADDR_SIM, + endianness:LITTLE_END, + index_width:0}, + { + id:I2C_TOUCH_CLIENT, + bus_id:0, + addr:I2C_ADDR_TOUCH, + endianness:LITTLE_END, + index_width:0}, + { + id:I2C_STMPE0_CLIENT, + bus_id:0, + addr:I2C_ADDR_STMPE0, + endianness:LITTLE_END, + index_width:REG8 + }, + { + id:I2C_STMPE1_CLIENT, + bus_id:0, + addr:I2C_ADDR_STMPE1, + endianness:LITTLE_END, + index_width:REG8 + }, + { + id:I2C_GAS_GAUGE_CLIENT, + bus_id:0, + addr:I2C_ADDR_GAS_GAUGE, + endianness:LITTLE_END, + index_width:REG8}, + { + id:I2C_TOUAREG_CLIENT, + bus_id:0, + addr:I2C_ADDR_POWER, + endianness:LITTLE_END, + index_width:REG8}, + { + id:I2C0_LOOP_CLIENT, + bus_id:0, + addr:I2C0_LP_OWNADDR, + endianness:LITTLE_END, + index_width:0}, + { + id:I2C1_LOOP_CLIENT, + bus_id:1, + addr:I2C1_LP_OWNADDR, + endianness:LITTLE_END, + index_width:0}, + +}; +#endif /*CONFIG_NOMADIK_NHK15*/ +static int i2c_initialize(struct nomadik_i2c_private *priv) +{ + /* Transfer configuration */ + priv->config.freq_scl = STD_SPEED_IN_HZ; + priv->config.i2c_transmit_interrupt_threshold = 4; + priv->config.i2c_receive_interrupt_threshold = 4; + + priv->config.bus_control_mode = I2C_BUS_MASTER_MODE; + priv->config.index_transfer_mode = I2C_TRANSFER_MODE_INTERRUPT; + priv->config.data_transfer_mode = I2C_TRANSFER_MODE_INTERRUPT; + + /* Device configuration */ + priv->config.freq_input = STD_F_IN_HZ; + + if (priv->id) + priv->config.own_address = I2C1_LP_OWNADDR; + else + priv->config.own_address = I2C0_LP_OWNADDR; + + if (setup_i2c_controller(priv) != 0) { + error("i2c device config 0 failed init\n"); + return -EIO; + } + + return 0; +} + +/** + * nomadik_i2c_get_info - Get status information of I2C controller + * + * @bus_id - The controller id. + * info - Info pointer describing the controller status. + * + * Return an info struct with current bus parameters. + **/ + +int nomadik_i2c_get_info(__u32 bus_id, i2c_info_t * info) +{ + struct nomadik_i2c_private *priv; + priv = &i2c_driver[bus_id]; + info->baseAddress = (__u32) priv->regs; + info->id = priv->id; + info->mode = priv->config.mode; + info->enabled = priv->config.enabled; + info->fSCL = priv->config.freq_scl; + info->fIn = priv->config.freq_input; + info->ownAddress = priv->config.own_address; + + return 0; +} + +/** + * nomadik_get_client - Get client information + * + * @client_id - Client id for the I2C device. + * + * This function returns the address of the client struct identified by + * client_id + **/ + +struct i2c_client *nomadik_i2c_get_client(__u32 client_id) +{ + if ((client_id < 0) || (client_id >= I2C_NUM_CLIENTS)) { + error("error: nomadik get_client: client = %d\n", client_id); + return 0; + } + return &nomadik_i2c_clients[client_id]; +} + +/** + * nomadik_i2c_is_busy - Check if the client is busy in an operation. + * + * @client_id - Identifier for the client whose status is required. + * + * This function checks the status of an event_type I2C_NO_EVENT. If this is + * the current active event, the controller is not busy, and the function + * returns false (0). If this is not the current event type, then the bus is + * in the process of doing something, so we return true -EBUSY. Note that there + * is no guarantee that the bus will not become busy between this call and + * a transfer request, so calls to the transfer functions should + * check the return - it will be -EBUSY if the bus is in use. -EINVAL + * is returned for an invalid client_id. + **/ + +int nomadik_i2c_is_busy(__u32 client_id) +{ + int retval; + + if ((retval = nomadik_i2c_check_client_id(client_id)) < 0) + return retval; + + if (i2c_driver[nomadik_client_bus_id[client_id]].config.active_event. + type == I2C_NO_EVENT) + return 0; + return -EBUSY; +} + +static irqreturn_t nomadik_i2c_irq_handler(int irq, + void *arg) +{ + __u32 id = ((struct nomadik_i2c_private *)arg)->id; + disable_irq(irq); + process_interrupt(&i2c_driver[id]); + + enable_irq(i2c_driver[id].irq); + return IRQ_HANDLED; +} + +/** + * nomadik_i2c_wait_msg + * + * @nomadik_i2c_private - Private data for the controller + * @len - Amount of data in bytes to be transferred + * + * Poll until the event we've started is finished. + * Wait 1000 microseconds for each byte transferred. + * Here we have not used wait_event_interruptible_timeout() + * as this would cause a schedule in interrupt context in case I2C routines + * called by client drivers in interrupt handlers + * + * This function should be called ONLY by this driver. + **/ +#define WAIT_CONDITION (priv->config.active_event.type > I2C_NO_EVENT && priv->config.active_event.type <= I2C_BUS_ERROR_EVENT) + +static int nomadik_i2c_wait_msg(struct nomadik_i2c_private *priv, int len) +{ + if(wait_event_interruptible(priv->event_wq, WAIT_CONDITION)) + return -EINVAL; + + return 0; +} + +/** + * nomadik_i2c_xfer_byte - I2C transfer function used by nomadik_i2c_xfer to + * transfer a single byte + * @i2c_adapter - Adapter pointer to the controller + * @msgs[] - Pointer to data to be written. + * @num - Num messages + * + **/ + +static int nomadik_i2c_xfer_byte(struct i2c_adapter *i2c_adap, + struct i2c_msg msgs[], int num) +{ + int m, mm; + int status; + unsigned int addr; + struct nomadik_i2c_private *priv = + (struct nomadik_i2c_private *)i2c_adap->data; + __u32 bus_id = priv->id; + int read = 0; + + if (msgs[0].len <= 0) + return 0; + + addr = msgs[0].addr; + + if (msgs[0].flags & I2C_M_TEN) + { + error("10 bit addressing not yet supported\n"); + return -EINVAL; + } + + if (down_interruptible(&nomadik_i2c[bus_id].lock)) + return -ERESTARTSYS; + + for (m = 0; m < num; m++) + { + info("message: %d, addr: %d\n", m, msgs[m].addr); + info("message: %d, flags: %d\n", m, msgs[m].flags); + info("message: %d, len: %d\n", m, msgs[m].len); + + for(mm = 0; mm < msgs[m].len; mm++) + info("message: %d, buf[%d]: 0x%02X\n", m, mm, msgs[m].buf[mm]); + + info("message: %d, bus id: 0x%02X\n", m, bus_id); + } + +#if !defined(CONFIG_NOMADIK_NHK15) + reset_i2c(priv); +#endif + + /* Save parameters. */ + priv->config.slave_address = addr; + priv->config.status = I2C_STATUS_SLAVE_MODE; + priv->config.index_format = I2C_BYTE_INDEX; + priv->config.active_event.type = I2C_NO_EVENT; + priv->config.multi_operation = NOMADIK_TRUE; + + if (i2c_initialize(priv)) { + up(&nomadik_i2c[bus_id].lock); + return -EINVAL; + } + + if (verify_parameters(priv)) + { + error("Error in parameters\n"); + up(&nomadik_i2c[bus_id].lock); + return -EINVAL; + } + + if (num > 1) + { + if (msgs[1].flags & I2C_M_RD) + { + read = 1; + } + } + + if (read != 0) + { + + /* Save parameters. */ + priv->config.databuffer = &(msgs[1].buf[0]); + priv->config.count_data = msgs[1].len; + priv->config.register_index = msgs[0].buf[0]; + /* Do the read */ + priv->config.operation = I2C_READ; + + status = read_i2c(priv); + + if (status) + { + error("Error in read_register: %d\n", status); + up(&nomadik_i2c[bus_id].lock); + return status; + } + else if (status == 0) + { + + if (priv->config.data_transfer_mode != I2C_TRANSFER_MODE_POLLING) + { + status = nomadik_i2c_wait_msg(priv, msgs[0].len); + if (status) + { + error("Message timeout with no handled event\n"); + error("error waiting for i2c read: %d\n", status); + up(&nomadik_i2c[bus_id].lock); + return status; + } + } + } + + info("ret message: 0, buf[0]: 0x%02X\n", msgs[0].buf[0]); + info("ret message: 1, buf[0]: 0x%02X\n", msgs[1].buf[0]); + + mdelay(1); + priv->config.active_event.type = I2C_NO_EVENT; + + up(&nomadik_i2c[bus_id].lock); + } + else + { + /* Save parameters. */ + priv->config.databuffer = &(msgs[0].buf[1]); + priv->config.count_data = 1; + priv->config.register_index = msgs[0].buf[0]; + + /* Do the write */ + priv->config.operation = I2C_WRITE; + status = write_i2c(priv); + if (status) + { + error("Error in write_register: %d\n", status); + up(&nomadik_i2c[bus_id].lock); + return status; + } + else if (status == 0) + { + if (priv->config.data_transfer_mode != I2C_TRANSFER_MODE_POLLING) + { + status = nomadik_i2c_wait_msg(priv, msgs[0].len - 1); + if (status) + { + error("Message timeout with no handled event\n"); + error("error waiting for i2c write: %d\n", status); + up(&nomadik_i2c[bus_id].lock); + return status; + } + } + } + mdelay(1); + priv->config.active_event.type = I2C_NO_EVENT; + up(&nomadik_i2c[bus_id].lock); + } + + return 0; + +} + +/** + * nomadik_i2c_xfer - I2C transfer function used by kernel framework + * @i2c_adapter - Adapter pointer to the controller + * @msgs[] - Pointer to data to be written. + * @num - Amount of data in bytes to be written + * + * This is the function called by the generic kernel i2c API calls. Note that + * this code is protected by the semaphore set in the kernel i2c_transfer() + * function. + * Retrive the client specific information from the client id and feed it to + * the controller specific configuration. Then call the respective board + * specific routine. + **/ + +static int nomadik_i2c_xfer(struct i2c_adapter *i2c_adap, + struct i2c_msg msgs[], int num) +{ + int i; + int status; + unsigned int addr; + struct nomadik_i2c_private *priv = + (struct nomadik_i2c_private *)i2c_adap->data; + __u32 bus_id = priv->id; + /*read byte or write byte, SMBus emulated (see i2c_smbus_xfer_emulated)*/ + if ((num == 2 && msgs[0].len == 1 && msgs[1].len == 1 && (msgs[1].flags & I2C_M_RD)) || + (num == 1 && msgs[0].len == 2 && ((msgs[0].flags & I2C_M_RD) == 0))) + { + return nomadik_i2c_xfer_byte(i2c_adap, msgs, num); + } + + for (i = 0; i < num; i++) { /* deal with message i */ + if (msgs[i].len > 0) { /*sanity check - message length */ + /*prepare address */ + addr = msgs[i].addr; + if (msgs[i].flags & I2C_M_RD) + addr |= 0x1; + + if (msgs[i].flags & I2C_M_TEN) { + error("10 bit addressing not yet supported\n"); + return -EINVAL; + } + + if (down_interruptible(&nomadik_i2c[bus_id].lock)) + return -ERESTARTSYS; + + reset_i2c(priv); + + /* Save parameters. */ + priv->config.slave_address = addr; + priv->config.status = I2C_STATUS_SLAVE_MODE; + priv->config.index_format = I2C_NO_INDEX; + priv->config.databuffer = msgs[i].buf; + priv->config.count_data = msgs[i].len; + priv->config.multi_operation = NOMADIK_TRUE; + + if (i2c_initialize(priv)) { + up(&nomadik_i2c[bus_id].lock); + return -EINVAL; + } + + if (verify_parameters(priv)) { + error("Error in parameters\n"); + up(&nomadik_i2c[bus_id].lock); + return -EINVAL; + } + + if (addr & 1) { + /* Do the read */ + priv->config.operation = I2C_READ; + /* read */ + status = read_i2c(priv); + if (status) { + error("Error in read_register: %d\n", + status); + up(&nomadik_i2c[bus_id].lock); + return status; + } else if (status == 0) { + + if (priv->config.data_transfer_mode != + I2C_TRANSFER_MODE_POLLING) { + status = + nomadik_i2c_wait_msg(priv, + msgs + [i]. + len); + if (status) { + error + ("Message timeout with no handled event\n"); + error + ("error waiting for i2c read: %d\n", + status); + up(&nomadik_i2c[bus_id]. + lock); + return status; + } + } + } + /* mdelay(1); */ /* NM */ + priv->config.active_event.type = I2C_NO_EVENT; + up(&nomadik_i2c[bus_id].lock); + + } else { + /* Do the write */ + priv->config.operation = I2C_WRITE; + status = write_i2c(priv); + if (status) { + error("Error in write_register: %d\n", + status); + up(&nomadik_i2c[bus_id].lock); + return status; + } else if (status == 0) { + + if (priv->config.data_transfer_mode != + I2C_TRANSFER_MODE_POLLING) { + status = + nomadik_i2c_wait_msg(priv, + msgs + [i]. + len); + if (status) { + error + ("Message timeout with no handled event\n"); + error + ("error waiting for i2c write: %d\n", + status); + up(&nomadik_i2c[bus_id]. + lock); + return status; + } + } + } + /* mdelay(1); */ /* NM */ + priv->config.active_event.type = I2C_NO_EVENT; + up(&nomadik_i2c[bus_id].lock); + } + + } + } + return 0; +} + +/** + * nomadik_i2c_write_register + * + * nomadik_i2c_write_register - Write data to I2C client + * @client_id - Identifier for the client + * @data - Pointer to data to be written. + * @index - Register index of the client + * @count - Amount of data in bytes to be written + * + * Handle all register index type writes. Using the client structs for + * the client_id, we can call the correct register write function and + * ensure a two byte index has the correct byte order. + * Retrive the client specific information from the client id and feed it to + * the controller specific configuration. Then call the respective board + * specific routine. + **/ + +int nomadik_i2c_write_register(__u32 client_id, + __u8 * data, int index, int count) +{ + int bus_id; + int retval; + __u16 addr; + struct nomadik_i2c_client *client; + struct nomadik_i2c_private *priv; + + if ((retval = nomadik_i2c_check_client_id(client_id)) < 0) + return retval; + + client = &priv_client[client_id]; + bus_id = client->bus_id; + priv = &i2c_driver[bus_id]; + addr = client->addr; + + if (down_interruptible(&nomadik_i2c[bus_id].lock)) + return -ERESTARTSYS; + +// reset_i2c(priv); + + /* Save parameters. */ + priv->config.slave_address = addr; + priv->config.status = I2C_STATUS_SLAVE_MODE; + priv->config.register_index = index; +#if !defined(CONFIG_TOUCHSCREEN_NOMADIK_TS2003) + priv->config.index_format = + ((client->index_width == + REG8) ? I2C_BYTE_INDEX : (client-> + endianness ? I2C_HALF_WORD_LITTLE_ENDIAN + : I2C_HALF_WORD_BIG_ENDIAN)); +#else + priv->config.index_format = + ((client->index_width == 0)?I2C_NO_INDEX: + (client->index_width == REG8) ? I2C_BYTE_INDEX : (client-> + endianness ? I2C_HALF_WORD_LITTLE_ENDIAN + : I2C_HALF_WORD_BIG_ENDIAN)); +#endif + priv->config.databuffer = data; + priv->config.count_data = count; + priv->config.active_event.type = I2C_NO_EVENT; + priv->config.multi_operation = NOMADIK_TRUE; + /* Do the write */ + priv->config.operation = I2C_WRITE; + + if (i2c_initialize(priv)) { + up(&nomadik_i2c[bus_id].lock); + return -EINVAL; + } + + if (verify_parameters(priv)) { + error("Error in parameters\n"); + up(&nomadik_i2c[bus_id].lock); + return -EINVAL; + } + + retval = write_i2c(priv); + + if (retval) { + error("Error in write_register: %d\n", retval); + } else if (retval == 0) { + + if (priv->config.data_transfer_mode != + I2C_TRANSFER_MODE_POLLING) { + retval = nomadik_i2c_wait_msg(priv, count); + if (retval) { + error + ("Message timeout with no handled event\n"); + error("error waiting for i2c read: %d\n", + retval); + up(&nomadik_i2c[bus_id].lock); + return retval; + } + } + else mdelay(1); + priv->config.active_event.type = I2C_NO_EVENT; + up(&nomadik_i2c[bus_id].lock); + return retval; + } + + up(&nomadik_i2c[bus_id].lock); + + /* Neither register mode for this client, return an error */ + return -EINVAL; +} + +/** + * nomadik_i2c_read_register - Read data from I2C client + * @client_id - Identifier for the client + * @data - Pointer where the read data will be written. + * @index - Register index of the client + * @count - Amount of data in bytes to be read + * + * Handle all register index type writes. Using the client structs for + * the client_id, we can call the correct register write function and + * ensure a two byte index has the correct byte order. + * Retrive the client specific information from the client id and feed it to + * the controller specific configuration. Then call the respective board + * specific routine. + **/ + +int nomadik_i2c_read_register(__u32 client_id, + __u8 * data, int index, int count) +{ + int bus_id; + int retval; + __u16 addr; + struct nomadik_i2c_client *client; + struct nomadik_i2c_private *priv; + + if ((retval = nomadik_i2c_check_client_id(client_id)) < 0) + return retval; + + client = &priv_client[client_id]; + bus_id = client->bus_id; + priv = &i2c_driver[bus_id]; + addr = client->addr; + + if (down_interruptible(&nomadik_i2c[bus_id].lock)) + return -ERESTARTSYS; + +// reset_i2c(priv); + + /* Save parameters. */ + priv->config.slave_address = addr; + priv->config.status = I2C_STATUS_SLAVE_MODE; + priv->config.register_index = index; +#if !defined(CONFIG_TOUCHSCREEN_NOMADIK_TS2003) + priv->config.index_format = + ((client->index_width == + REG8) ? I2C_BYTE_INDEX : (client-> + endianness ? I2C_HALF_WORD_LITTLE_ENDIAN + : I2C_HALF_WORD_BIG_ENDIAN)); + +#else + + priv->config.index_format = + ((client->index_width == 0)?I2C_NO_INDEX: + (client->index_width == + REG8) ? I2C_BYTE_INDEX : (client-> + endianness ? I2C_HALF_WORD_LITTLE_ENDIAN + : I2C_HALF_WORD_BIG_ENDIAN)); + +#endif + priv->config.databuffer = data; + priv->config.count_data = count; + priv->config.active_event.type = I2C_NO_EVENT; + priv->config.multi_operation = NOMADIK_TRUE; + /* Do the read operation */ + priv->config.operation = I2C_READ; + + if (i2c_initialize(priv)) { + up(&nomadik_i2c[bus_id].lock); + return -EINVAL; + } + + if (verify_parameters(priv)) { + error("Error in parameters\n"); + up(&nomadik_i2c[bus_id].lock); + return -EINVAL; + } + + retval = read_i2c(priv); + + if (retval) { + error("Error in read register: %d\n", retval); + } else if (retval == 0) { + + if (priv->config.data_transfer_mode != + I2C_TRANSFER_MODE_POLLING) { + retval = nomadik_i2c_wait_msg(priv, count); + if (retval) { + error + ("Message timeout with no handled event\n"); + error("error waiting for i2c read: %d\n", + retval); + up(&nomadik_i2c[bus_id].lock); + return retval; + } + } + else mdelay(1); + priv->config.active_event.type = I2C_NO_EVENT; + up(&nomadik_i2c[bus_id].lock); + return 0; + } + + up(&nomadik_i2c[bus_id].lock); + + /* Neither register mode for this client, return an error */ + return -EINVAL; +} + +static unsigned int nomadik_i2c_func(struct i2c_adapter *adap) +{ + return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | I2C_FUNC_SMBUS_QUICK; + //return I2C_FUNC_I2C; +} + +static int nomadik_i2c_remove(struct platform_device *pdev) +{ + + int retval; + i2c_del_adapter(&nomadik_i2c[pdev->id]); + + free_irq(i2c_driver[pdev->id].irq, &i2c_driver[pdev->id]); + + disable_i2c(&i2c_driver[pdev->id]); + + retval = + nomadik_gpio_altfuncdisable(GPIO_ALT_I2C_0 + pdev->id, (char *)pdev->name); + if (retval) { + error("GPIO Disable Alt Function(%d) failed with %d\n", + pdev->id, retval); + return retval; + } + + return 0; +} + +static int nomadik_i2c_probe(struct platform_device *pdev) +{ + int irq; + int retval = -EINVAL; + struct resource *res = NULL; + + /*Fetch the Resources, using platform data */ + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (NULL == res) { + dev_err(&pdev->dev, "probe - MEM resources not defined\n"); + return -ENODEV; + } + + irq = platform_get_irq(pdev, 0); + if (irq < 0) { + dev_err(&pdev->dev, "probe - IRQ resource not defined\n"); + return -ENODEV; + } + + i2c_driver[pdev->id].regs = (void *)IO_ADDRESS(res->start); + i2c_driver[pdev->id].id = pdev->id; + i2c_driver[pdev->id].irq = irq; + i2c_driver[pdev->id].adap = &nomadik_i2c[pdev->id]; + + nomadik_i2c[pdev->id].data = (void *)&i2c_driver[pdev->id]; + nomadik_i2c[pdev->id].dev.parent = &pdev->dev; + + retval = i2c_add_adapter(&nomadik_i2c[pdev->id]); + if (retval) { + error("Nomadik I2C[%d] Error: failed to add adapter\n", + pdev->id); + return retval; + } + + /* Initialize semaphores */ + sema_init(&nomadik_i2c[pdev->id].lock, 1); + + retval = request_irq(i2c_driver[pdev->id].irq, + nomadik_i2c_irq_handler, + 0, + nomadik_i2c[pdev->id].name, &i2c_driver[pdev->id]); + if (retval < 0) { + error("i2c[%d] can't get requested irq %d\n", + pdev->id, i2c_driver[pdev->id].irq); + return retval; + } + + if (pdev->id == 0) { + retval = nomadik_gpio_altfuncenable(GPIO_ALT_I2C_0, "I2C_0"); + if (retval) { + error + ("GPIO Enable Alt Function(%d) failed with return = %d\n", + pdev->id, retval); + return (-EIO); + } + } else {/* + retval = nomadik_gpio_altfuncenable(GPIO_ALT_I2C_1, "I2C_1"); + if (retval) { + error + ("GPIO Enable Alt Function(%d) failed with return = %d\n", + pdev->id, retval); + return (-EIO); + }*/ + } + init_waitqueue_head(&i2c_driver[pdev->id].event_wq); + reset_i2c(&i2c_driver[pdev->id]); + return 0; +} + +static struct platform_driver nomadik_i2c_driver = { + .probe = nomadik_i2c_probe, + .remove = nomadik_i2c_remove, + .driver = { + .owner = THIS_MODULE, + .name = "NOMADIK-I2C", + }, +}; + +static int __init i2c_nomadik_init(void) +{ + return platform_driver_register(&nomadik_i2c_driver); +} + +static void __exit i2c_nomadik_exit(void) +{ + platform_driver_unregister(&nomadik_i2c_driver); + return; +} + +EXPORT_SYMBOL(nomadik_i2c_get_info); +EXPORT_SYMBOL(nomadik_i2c_is_busy); +EXPORT_SYMBOL(nomadik_i2c_read_register); +EXPORT_SYMBOL(nomadik_i2c_write_register); +EXPORT_SYMBOL(nomadik_i2c_get_client); + +module_init(i2c_nomadik_init); +module_exit(i2c_nomadik_exit); + +MODULE_DESCRIPTION("Nomadik IIC driver v" DRIVER_VERSION); +MODULE_LICENSE("GPL"); --- /dev/null +++ linux-2.6.20/drivers/i2c/busses/i2c-nomadik.h @@ -0,0 +1,93 @@ +/* drivers/i2c/busses/i2c-nomadik.h + * + * This is the non-public header file for the nomadik i2c driver. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * $Id$ + */ + +#ifndef I2C_NOMADIC_PRIV_HEADER +#define I2C_NOMADIC_PRIV_HEADER + +#ifndef _NOMADIK_DEFS_H +#include +#endif + +#ifndef I2C_NOMADIC_HEADER +#include +#endif + +#define I2C_ALGO_NOMADIK 0x15000000 +#define I2C_HW_NOMADIK 0x01 +#define I2C_DRIVERID_NOMADIK 0xF000 + +#define I2C0_IOSIZE 0x00000FFF +#define I2C1_IOSIZE 0x00000FFF + +#define MSG_WAIT_USEC 500 // Wait 500 uSecs to test active event again. +#define MAX_WIAT_TIMEOUTS 100 + +/*** + * Other structs + ***/ +struct nomadik_i2c_client { + __u32 id; + __u32 bus_id; + __u8 addr; + __u8 endianness; // This indicates endianness of device's register index + __u8 index_width; // 8 or 16 bits; +}; + +#define BIG_END 0 +#define LITTLE_END 1 +#define REG8 8 +#define REG16 16 + +struct nomadik_i2c_private { + __u32 id; // bus id + struct i2c_adapter *adap; + int irq; + struct semaphore sema; // Use for blocking on aa message completion + int fast_mode; + void __iomem *regs; + wait_queue_head_t event_wq; + struct i2c_controller_config config; +}; + +static inline int nomadik_i2c_check_client_id(__u32 id) +{ + if ((id < 0) || (id >= I2C_NUM_CLIENTS)) { + return -EINVAL; + } + return 0; +} + +/*----------------------------------------------------------------------------- + Configuration functions +-----------------------------------------------------------------------------*/ +int setup_i2c_controller(struct nomadik_i2c_private *priv); + +int write_i2c(struct nomadik_i2c_private *priv); + +int read_i2c(struct nomadik_i2c_private *priv); + +int process_interrupt(struct nomadik_i2c_private *priv); +int verify_parameters(struct nomadik_i2c_private *priv); +void reset_i2c(struct nomadik_i2c_private *priv); +void disable_i2c(struct nomadik_i2c_private *priv); +void stn_cut_mdelay(int dlytime); + +#endif --- /dev/null +++ linux-2.6.20/drivers/i2c/busses/i2c-stn8810.c @@ -0,0 +1,1723 @@ + +/* drivers/i2c/busses/i2c-nmdk8810.c + * + * Support for i2c bus on STn8810 (Nomadik) chips. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Author: Melwyn LOBO + *----------------------------------------------------------------------------- + */ + + +#include +#include + +#include "i2c-nomadik.h" +#include + +#define I2C_ENDAD_COUNTER 50000 +#define I2C_INT_ENDED_COUNTER 50000 +#define I2C_BTF_COUNTER 50000 +#define I2C_BTF_COUNTER_POLLING 50000 +#define I2C_FIFO_FLUSH_COUNTER 500 +#define I2C_LOWER_SLAVE 127 +#define I2C_UPPER_SLAVE 1024 + +/*####################################################################### + Macros to access I2C Registers with their offsets +######################################################################### +*/ + +#define I2C_REG_OFFSET_CR 0x00 +#define I2C_REG_OFFSET_SR1 0x04 +#define I2C_REG_OFFSET_SR2 0x08 +#define I2C_REG_OFFSET_CCR 0x0C +#define I2C_REG_OFFSET_OAR1 0x10 +#define I2C_REG_OFFSET_OAR2 0x14 +#define I2C_REG_OFFSET_DR 0x18 +#define I2C_REG_OFFSET_ECCR 0x1C + +/*####################################################################### + Macros to access I2C Interrupt Registers event +######################################################################### +*/ + +#define I2C0_IRQ_SRC_ALL 0 +#define I2C1_IRQ_SRC_ALL 1 + +#define I2C_IT_BTF STD_MASK_BIT0 +#define I2C_IT_ADSL STD_MASK_BIT1 +#define I2C_IT_SB STD_MASK_BIT2 +#define I2C_IT_AF STD_MASK_BIT3 +#define I2C_IT_STOPF STD_MASK_BIT4 +#define I2C_IT_ARLO STD_MASK_BIT5 +#define I2C_IT_BERR STD_MASK_BIT6 +#define I2C_IT_ADD10 STD_MASK_BIT7 +#define I2C_IT_SCLFAL STD_MASK_BIT8 +#define I2C_IT_ENDAD STD_MASK_BIT9 + +/*####################################################################### + I2C Control Register +######################################################################### +*/ + +#define I2C_ITE STD_MASK_BIT0 +#define I2C_STOP STD_MASK_BIT1 +#define I2C_ACK STD_MASK_BIT2 +#define I2C_START STD_MASK_BIT3 +#define I2C_ENGC STD_MASK_BIT4 +#define I2C_PE STD_MASK_BIT5 +#define I2C_TRANS STD_MASK_BIT6 +#define I2C_DDC1EN STD_MASK_BIT7 +#define I2C_SHIFT_ITE 0 +#define I2C_SHIFT_STOP 1 +#define I2C_SHIFT_ACK 2 +#define I2C_SHIFT_START 3 +#define I2C_SHIFT_ENGC 4 +#define I2C_SHIFT_PE 5 +#define I2C_SHIFT_TRANS 6 +#define I2C_SHIFT_DDC1EN 7 + +/*####################################################################### + I2C Status Register1 +######################################################################### +*/ + +#define I2C_SB STD_MASK_BIT0 +#define I2C_MASTER STD_MASK_BIT1 +#define I2C_ADSL STD_MASK_BIT2 +#define I2C_BTF STD_MASK_BIT3 +#define I2C_BUSY STD_MASK_BIT4 +#define I2C_TRA STD_MASK_BIT5 +#define I2C_ADD10 STD_MASK_BIT6 +#define I2C_EVF STD_MASK_BIT7 +#define I2C_SHIFT_SB 0 +#define I2C_SHIFT_MASTER 1 +#define I2C_SHIFT_ADSL 2 +#define I2C_SHIFT_BTF 3 +#define I2C_SHIFT_BUSY 4 +#define I2C_SHIFT_TRA 5 +#define I2C_SHIFT_ADD10 6 +#define I2C_SHIFT_EVF 7 + +/*####################################################################### + I2C Status Register2 +######################################################################### +*/ + +#define I2C_GCAL STD_MASK_BIT0 +#define I2C_BERR STD_MASK_BIT1 +#define I2C_ARLO STD_MASK_BIT2 +#define I2C_STOPF STD_MASK_BIT3 +#define I2C_AF STD_MASK_BIT4 +#define I2C_ENDAD STD_MASK_BIT5 +#define I2C_SCLFAL STD_MASK_BIT7 +#define I2C_SHIFT_GCAL 0 +#define I2C_SHIFT_BERR 1 +#define I2C_SHIFT_ARLO 2 +#define I2C_SHIFT_STOPF 3 +#define I2C_SHIFT_AF 4 +#define I2C_SHIFT_ENDAD 5 +#define I2C_SHIFT_SCLFAL 7 + +/*####################################################################### + I2C Clock Control Register +######################################################################### +*/ + +#define I2C_CLOCK_MASK 0x7F +#define I2C_FM_SM_MASK 0x80 + +/*####################################################################### + Default I2C Register Values +######################################################################### +*/ + +#define DEFAULT_CR_REG (GEN_MASK(0UL,I2C_ENGC,I2C_SHIFT_ENGC) | \ + GEN_MASK(0UL,I2C_DDC1EN,I2C_SHIFT_DDC1EN) \ + ) + +#define DEFAULT_OAR1_REG(address) ( GEN_MASK(((address)<<1),0xFF,0) \ + ) +#define DEFAULT_OAR2_REG(address, index) ( GEN_MASK(((address)>>7),0x6,0) | \ + GEN_MASK(((index)<<5),0xE0,0)\ + ) + +#define DEFAULT_CCR_REG(input,scl) ( GEN_MASK(((((input / (4 * scl)) - 14))),I2C_CLOCK_MASK,0) \ + ) + +#define DEFAULT_ECCR_REG(input,scl) (GEN_MASK(((((input / (4*scl)) - 14))>>7),0x1F,0) \ + ) + +#define GENERATE_START_CONDITION(regs) I2C_SET_BIT(regs + I2C_REG_OFFSET_CR, I2C_START) + +#define DISABLE_IRQSRC(regs) I2C_CLR_BIT(regs + I2C_REG_OFFSET_CR, I2C_ITE); +#define ENABLE_IRQSRC(regs) I2C_SET_BIT(regs + I2C_REG_OFFSET_CR, I2C_ITE); + +#define WAIT_FOR_STOPF(priv) \ +{ \ + __u32 loop_counter_macro=0; \ + while \ + ( \ + !(I2C_READ_FIELD(priv->regs + I2C_REG_OFFSET_SR1, I2C_EVF, I2C_SHIFT_EVF) \ + && I2C_READ_FIELD(priv->regs + I2C_REG_OFFSET_SR2, I2C_STOPF, I2C_SHIFT_STOPF)) \ + && loop_counter_macro < I2C_ENDAD_COUNTER \ + ) \ + loop_counter_macro++; \ + if (loop_counter_macro >= I2C_ENDAD_COUNTER) { \ + i2c_abort(priv); \ + return -EINVAL; \ + }\ +} + +#define WAIT_FOR_START(priv) \ +{ \ + __u32 loop_counter_macro=0; \ + while \ + ( \ + !(I2C_READ_FIELD(priv->regs + I2C_REG_OFFSET_SR1, I2C_EVF, I2C_SHIFT_EVF) \ + && I2C_READ_FIELD(priv->regs + I2C_REG_OFFSET_SR1, I2C_SB, I2C_SHIFT_SB)) \ + && loop_counter_macro < I2C_ENDAD_COUNTER \ + ) \ + loop_counter_macro++; \ + if (loop_counter_macro >= I2C_ENDAD_COUNTER) { \ + i2c_abort(priv); \ + return -EINVAL; \ + }\ +} + +#define WAIT_FOR_BTF(priv) \ +{ \ + __u32 loop_counter_macro=0; \ + while \ + ( \ + !(I2C_READ_FIELD(priv->regs + I2C_REG_OFFSET_SR1, I2C_EVF, I2C_SHIFT_EVF) \ + && I2C_READ_FIELD(priv->regs + I2C_REG_OFFSET_SR1, I2C_BTF, I2C_SHIFT_BTF)) \ + && loop_counter_macro < I2C_ENDAD_COUNTER \ + ) \ + loop_counter_macro++; \ + if (loop_counter_macro >= I2C_ENDAD_COUNTER) { \ + i2c_abort(priv); \ + return -EINVAL; \ + }\ +} + +#define WAIT_FOR_ENDAD(priv) \ +{ \ + __u32 loop_counter_macro=0; \ + while \ + ( \ + !(I2C_READ_FIELD(priv->regs + I2C_REG_OFFSET_SR1, I2C_EVF, I2C_SHIFT_EVF) \ + && I2C_READ_FIELD(priv->regs + I2C_REG_OFFSET_SR2, I2C_ENDAD, I2C_SHIFT_ENDAD)) \ + && loop_counter_macro < I2C_ENDAD_COUNTER \ + ) \ + loop_counter_macro++; \ + if (loop_counter_macro >= I2C_ENDAD_COUNTER) { \ + i2c_abort(priv); \ + return -EINVAL; \ + }\ +} + +int loop_till_clear(void *reg_offset, int mask, int shift, int end_counter) +{ + int loop = 0; + while ((I2C_READ_FIELD((reg_offset), (mask), (shift))) + && (loop < end_counter)) + loop++; + + if (loop >= end_counter) + return 1; + else + return 0; +} + +int loop_till_set(void *reg_offset, int mask, int shift, int end_counter) +{ + int loop = 0; + while (!(I2C_READ_FIELD((reg_offset), (mask), (shift))) + && (loop < end_counter)) + loop++; + + if (loop >= end_counter) + return 1; + else + return 0; +} + +int verify_parameters(struct nomadik_i2c_private *priv) +{ + if ((I2C_HARDWARE_GENERAL_CALL_HANDLING == + priv->config.general_call_mode_handling) + || (I2C_TRANSFER_MODE_POLLING != priv->config.index_transfer_mode + && I2C_TRANSFER_MODE_POLLING == priv->config.data_transfer_mode) + || (I2C_TRANSFER_MODE_DMA == priv->config.index_transfer_mode) + || (I2C_BUS_MASTER_SLAVE_MODE == priv->config.bus_control_mode) + || (I2C_TRANSFER_MODE_DMA == priv->config.data_transfer_mode) + ) + return -EINVAL; + + if (priv->config.slave_address > 1023 + || (priv->config.slave_address < 256 + && !(priv->config.slave_address == 0 + || priv->config.slave_address == 0x4))) + if ((priv->config.slave_address < 16) + || (priv->config.slave_address > 239)) + return -EINVAL; + + if ((I2C_BUS_MASTER_MODE != priv->config.bus_control_mode) + && (I2C_NO_INDEX != priv->config.index_format)) + return -EINVAL; + + if (I2C_TEST_BIT(priv->regs + I2C_REG_OFFSET_SR1, I2C_BUSY)) + return -EBUSY; + + return 0; +} + +void i2c_abort(struct nomadik_i2c_private *priv) +{ + __u32 dummy; + + I2C_CLR_BIT(priv->regs + I2C_REG_OFFSET_CR, I2C_ACK); + I2C_SET_BIT(priv->regs + I2C_REG_OFFSET_CR, I2C_STOP); + + dummy = I2C_READ_REG(priv->regs + I2C_REG_OFFSET_DR); + dummy = dummy; + + if (I2C_TEST_BIT(priv->regs + I2C_REG_OFFSET_CR, I2C_PE)) { + I2C_CLR_BIT(priv->regs + I2C_REG_OFFSET_CR, I2C_PE); + + I2C_SET_BIT(priv->regs + I2C_REG_OFFSET_CR, I2C_PE); + + if (priv->config.irq_enabled) + ENABLE_IRQSRC(priv->regs); + + if (priv->config.general_call_mode_handling) + I2C_SET_BIT(priv->regs + I2C_REG_OFFSET_CR, I2C_ENGC); + else + I2C_CLR_BIT(priv->regs + I2C_REG_OFFSET_CR, I2C_ENGC); + + I2C_SET_BIT(priv->regs + I2C_REG_OFFSET_CR, I2C_PE); + + priv->config.enabled = NOMADIK_TRUE; + } + + priv->config.status = I2C_STATUS_SLAVE_MODE; + priv->config.operation = I2C_NO_OPERATION; + + priv->config.operation = (i2c_operation_t) I2C_NO_OPERATION; + +} + +int setup_i2c_controller(struct nomadik_i2c_private *priv) +{ + int dummy; + I2C_CLR_BIT(priv->regs + I2C_REG_OFFSET_CR, I2C_PE); + priv->config.enabled = NOMADIK_FALSE; + priv->config.active_event.type = I2C_NO_EVENT; + + I2C_WRITE_REG(priv->regs + I2C_REG_OFFSET_CR, I2C_CLEAR); + I2C_WRITE_REG(priv->regs + I2C_REG_OFFSET_SR1, I2C_CLEAR); + I2C_WRITE_REG(priv->regs + I2C_REG_OFFSET_SR2, I2C_CLEAR); + I2C_WRITE_REG(priv->regs + I2C_REG_OFFSET_CCR, I2C_CLEAR); + I2C_WRITE_REG(priv->regs + I2C_REG_OFFSET_OAR1, I2C_CLEAR); + I2C_WRITE_REG(priv->regs + I2C_REG_OFFSET_OAR2, I2C_CLEAR); + I2C_WRITE_REG(priv->regs + I2C_REG_OFFSET_DR, I2C_CLEAR); + I2C_WRITE_REG(priv->regs + I2C_REG_OFFSET_ECCR, I2C_CLEAR); + + I2C_WRITE_REG(priv->regs + I2C_REG_OFFSET_CR, DEFAULT_CR_REG); + I2C_WRITE_REG(priv->regs + I2C_REG_OFFSET_OAR1, + DEFAULT_OAR1_REG(priv->config.own_address)); + I2C_WRITE_REG(priv->regs + I2C_REG_OFFSET_OAR2, + DEFAULT_OAR2_REG(priv->config.own_address, 4)); + I2C_SET_BIT(priv->regs + I2C_REG_OFFSET_CR, I2C_PE); + I2C_WRITE_REG(priv->regs + I2C_REG_OFFSET_CCR, + DEFAULT_CCR_REG(priv->config.freq_input, + priv->config.freq_scl)); + I2C_WRITE_REG(priv->regs + I2C_REG_OFFSET_ECCR, + DEFAULT_ECCR_REG(priv->config.freq_input, + priv->config.freq_scl)); + I2C_WRITE_REG(priv->regs + I2C_REG_OFFSET_CR, DEFAULT_CR_REG); + if (I2C_TRANSFER_MODE_POLLING == priv->config.index_transfer_mode) + DISABLE_IRQSRC(priv->regs); + + I2C_CLR_BIT(priv->regs + I2C_REG_OFFSET_CR, I2C_PE); + dummy = I2C_READ_REG(priv->regs + I2C_REG_OFFSET_SR1); + dummy = I2C_READ_REG(priv->regs + I2C_REG_OFFSET_SR2); + dummy = I2C_READ_REG(priv->regs + I2C_REG_OFFSET_DR); + dummy = dummy; + + I2C_SET_BIT(priv->regs + I2C_REG_OFFSET_CR, I2C_PE); + priv->config.enabled = NOMADIK_TRUE; + + return (0); +} + +void disable_i2c(struct nomadik_i2c_private *priv) +{ + I2C_CLR_BIT(priv->regs + I2C_REG_OFFSET_CR, I2C_PE); + priv->config.enabled = NOMADIK_FALSE; +} + +int send_slave_address(struct nomadik_i2c_private *priv, __u32 operation) +{ + __u8 address; + + if (priv->config.slave_address < I2C_UPPER_SLAVE + && priv->config.slave_address > I2C_LOWER_SLAVE) { + address = + (__u8) (0xf0 | (0x06 & (priv->config.slave_address >> 7))); + + if ((I2C_STATUS_MASTER_RECEIVER_MODE == priv->config.status) + && (I2C_READ == operation)) { + address = (__u8) (address | (__u8) operation); + } + } else { + address = + (__u8) ((0xfe & (__u32) (priv->config.slave_address << 1)) | + (__u32) operation); + } + + I2C_WRITE_REG(priv->regs + I2C_REG_OFFSET_DR, address); + + return 0; +} + +int slave_index_receive(struct nomadik_i2c_private *priv) +{ + __u32 loop_counter = 0, dummy; + + loop_counter = 0; + if (loop_till_set(priv->regs + I2C_REG_OFFSET_SR1, I2C_ADSL, + I2C_SHIFT_ADSL, I2C_ENDAD_COUNTER)) { + i2c_abort(priv); + return -EINVAL; + } + + dummy = readl(priv->regs + I2C_REG_OFFSET_SR1); + + if (I2C_READ == priv->config.operation) { + priv->config.status = I2C_STATUS_SLAVE_RECEIVER_MODE; + priv->config.active_event.type = I2C_DATA_RX_EVENT; + + } else { + if ((I2C_STATUS_SLAVE_MODE == priv->config.status) + && (priv->config.own_address < 1024 + && priv->config.own_address > 127) + ) + I2C_SET_BIT(priv->regs + I2C_REG_OFFSET_CR, I2C_ACK); + else + I2C_CLR_BIT(priv->regs + I2C_REG_OFFSET_CR, I2C_ACK); + + priv->config.status = I2C_STATUS_SLAVE_TRANSMITTER_MODE; + priv->config.active_event.type = I2C_DATA_TX_EVENT; + } + + if (I2C_READ == priv->config.operation) + priv->config.status = I2C_STATUS_SLAVE_RECEIVER_MODE; + else + priv->config.status = I2C_STATUS_SLAVE_TRANSMITTER_MODE; + + return (0); + +} + +int transmit_data_polling(struct nomadik_i2c_private *priv) +{ + __u32 loop_counter = 0; + __u32 dummy = 0; + __u8 *p_data = priv->config.databuffer; + + if (I2C_BUS_SLAVE_MODE == priv->config.bus_control_mode) { + /* SLAVE TRANSMITTER */ + while (priv->config.count_data > 1) { + writel(*p_data, priv->regs + I2C_REG_OFFSET_DR); + priv->config.transfer_data++; + priv->config.count_data--; + p_data++; + priv->config.active_event.type = I2C_DATA_TX_EVENT; + + loop_counter = 0; + + WAIT_FOR_BTF(priv); + + dummy = I2C_READ_REG(priv->regs + I2C_REG_OFFSET_SR1); + }; + if (priv->config.count_data == 1) { /* transmit last data byte */ + writel(*(__u32 *) p_data, + priv->regs + I2C_REG_OFFSET_DR); + priv->config.transfer_data++; + priv->config.count_data--; + loop_counter = 0; + while + (!(I2C_READ_FIELD + (priv->regs + I2C_REG_OFFSET_SR1, I2C_BTF, + I2C_SHIFT_BTF) + && I2C_READ_FIELD(priv->regs + + I2C_REG_OFFSET_SR2, I2C_AF, + I2C_SHIFT_AF) + && I2C_READ_FIELD(priv->regs + + I2C_REG_OFFSET_SR1, I2C_EVF, + I2C_SHIFT_EVF) + ) + && loop_counter < I2C_ENDAD_COUNTER) + loop_counter++; + if (loop_counter >= I2C_ENDAD_COUNTER) { + i2c_abort(priv); + return -EIO; + } + + priv->config.status = I2C_STATUS_SLAVE_MODE; + + priv->config.active_event.type = I2C_DATA_TX_EVENT; + + dummy = I2C_READ_REG(priv->regs + I2C_REG_OFFSET_SR2); + + dummy = I2C_READ_REG(priv->regs + I2C_REG_OFFSET_DR); + I2C_SET_BIT(priv->regs + I2C_REG_OFFSET_CR, I2C_STOP); + + dummy = dummy; + dummy = I2C_READ_REG(priv->regs + I2C_REG_OFFSET_DR); + dummy = dummy; + + I2C_CLR_BIT(priv->regs + I2C_REG_OFFSET_CR, I2C_STOP); + + WAIT_FOR_STOPF(priv); + priv->config.status = I2C_STATUS_SLAVE_MODE; + priv->config.active_event.type = I2C_TRANSFER_OK_EVENT; + + dummy = I2C_READ_REG(priv->regs + I2C_REG_OFFSET_SR2); + } + } else { + /* MASTER TRANSMITTER */ + while (priv->config.count_data > 0) { + writel(*p_data, priv->regs + I2C_REG_OFFSET_DR); + + loop_counter = 0; + while (loop_counter < I2C_BTF_COUNTER_POLLING) + loop_counter++; + + priv->config.transfer_data++; + priv->config.count_data--; + p_data++; + priv->config.active_event.type = I2C_DATA_TX_EVENT; + + loop_counter = 0; + WAIT_FOR_BTF(priv); + } + + I2C_SET_BIT(priv->regs + I2C_REG_OFFSET_CR, I2C_STOP); + + dummy = I2C_READ_REG(priv->regs + I2C_REG_OFFSET_DR); + + } + + priv->config.operation = I2C_NO_OPERATION; + return 0; + +} + +int receive_data_polling(struct nomadik_i2c_private *priv) +{ + __u32 loop_counter = 0; + __u32 dummy = 0; + + __u8 *p_data = priv->config.databuffer; + I2C_SET_BIT(priv->regs + I2C_REG_OFFSET_CR, I2C_ACK); + + if (I2C_BUS_SLAVE_MODE == priv->config.bus_control_mode) { + /* SLAVE RECEIVER */ + while (priv->config.count_data > 1) { + loop_counter = 0; + WAIT_FOR_BTF(priv); + + *p_data = (__u8) readl(priv->regs + I2C_REG_OFFSET_DR); + + priv->config.transfer_data++; + priv->config.count_data--; + p_data++; + priv->config.active_event.type = I2C_DATA_RX_EVENT; + }; + if (priv->config.count_data == 1) { + I2C_CLR_BIT(priv->regs + I2C_REG_OFFSET_CR, I2C_ACK); + + loop_counter = 0; + WAIT_FOR_BTF(priv); + + *p_data = (__u8) readl(priv->regs + I2C_REG_OFFSET_DR); + + priv->config.transfer_data++; + priv->config.count_data--; + priv->config.status = I2C_STATUS_SLAVE_MODE; + priv->config.active_event.type = I2C_TRANSFER_OK_EVENT; + + WAIT_FOR_STOPF(priv); + + dummy = I2C_READ_REG(priv->regs + I2C_REG_OFFSET_SR2); + } + } else { + /* MASTER RECEIVER */ + while (priv->config.count_data > 1) { + loop_counter = 0; + WAIT_FOR_BTF(priv); + + *p_data = (__u8) readl(priv->regs + I2C_REG_OFFSET_DR); + + priv->config.transfer_data++; + priv->config.count_data--; + p_data++; + priv->config.active_event.type = I2C_DATA_RX_EVENT; + }; + if (priv->config.count_data == 1) { + + loop_counter = 0; + WAIT_FOR_BTF(priv); + I2C_CLR_BIT(priv->regs + I2C_REG_OFFSET_CR, I2C_ACK); + + *p_data = (__u8) readl(priv->regs + I2C_REG_OFFSET_DR); + + I2C_SET_BIT(priv->regs + I2C_REG_OFFSET_CR, I2C_STOP); + + priv->config.transfer_data++; + priv->config.count_data--; + } + + loop_counter = 0; + while (I2C_READ_FIELD + (priv->regs + I2C_REG_OFFSET_CR, I2C_STOP, + I2C_SHIFT_STOP) + && loop_counter < I2C_ENDAD_COUNTER) { + loop_counter++; + }; + + dummy = (__u8) readl(priv->regs + I2C_REG_OFFSET_DR); + dummy = (__u8) readl(priv->regs + I2C_REG_OFFSET_SR1); + dummy = (__u8) readl(priv->regs + I2C_REG_OFFSET_SR2); + priv->config.active_event.type = I2C_TRANSFER_OK_EVENT; + priv->config.status = I2C_STATUS_SLAVE_MODE; + + } + + priv->config.operation = I2C_NO_OPERATION; + + return (0); + +} + +int master_index_transmit(struct nomadik_i2c_private *priv) +{ + __u32 dummy, loop_counter = 0; + __u8 send_index = 0; + int error_status = 0; + + GENERATE_START_CONDITION(priv->regs); + priv->config.active_event.type = I2C_START_EVENT; + + WAIT_FOR_START(priv); + + priv->config.status = I2C_STATUS_MASTER_MODE; + + I2C_SET_BIT(priv->regs + I2C_REG_OFFSET_CR, I2C_ACK); + + if ((priv->config.index_format > I2C_NO_INDEX) + || (I2C_WRITE == priv->config.operation) + || (priv->config.slave_address < 1024 + && priv->config.slave_address > 127) + ) { + error_status = send_slave_address(priv, I2C_WRITE); + } else { + error_status = send_slave_address(priv, I2C_READ); + } + + if (error_status) + return (error_status); + + WAIT_FOR_ENDAD(priv); + + dummy = readl(priv->regs + I2C_REG_OFFSET_SR2); + I2C_SET_BIT(priv->regs + I2C_REG_OFFSET_CR, I2C_PE); + I2C_SET_BIT(priv->regs + I2C_REG_OFFSET_CR, I2C_PE); + + loop_counter = 0; + if (loop_till_clear + (priv->regs + I2C_REG_OFFSET_SR2, I2C_ENDAD, I2C_SHIFT_ENDAD, + I2C_ENDAD_COUNTER)) { + i2c_abort(priv); + return -EIO; + } + + if (priv->config.index_format > I2C_NO_INDEX) { + switch (priv->config.index_format) { + case I2C_BYTE_INDEX: + send_index = + (__u8) (0xFF & priv->config.register_index); + priv->config.index_format = I2C_NO_INDEX; + + writel(send_index, priv->regs + I2C_REG_OFFSET_DR); + + loop_counter = 0; + loop_till_clear(priv->regs + I2C_REG_OFFSET_SR1, + I2C_BTF, I2C_SHIFT_BTF, + I2C_BTF_COUNTER); + + break; + + case I2C_HALF_WORD_LITTLE_ENDIAN: + send_index = + (__u8) (0xFF & priv->config.register_index); + + writel(send_index, priv->regs + I2C_REG_OFFSET_DR); + + loop_counter = 0; + loop_till_clear(priv->regs + I2C_REG_OFFSET_SR1, + I2C_BTF, I2C_SHIFT_BTF, + I2C_BTF_COUNTER); + + WAIT_FOR_BTF(priv); + + send_index = + (__u8) (0xFF & (priv->config.register_index >> 8)); + + writel(send_index, priv->regs + I2C_REG_OFFSET_DR); + priv->config.index_format = I2C_NO_INDEX; + break; + + case I2C_HALF_WORD_BIG_ENDIAN: + send_index = + (__u8) (0xFF & (priv->config.register_index >> 8)); + + writel(send_index, priv->regs + I2C_REG_OFFSET_DR); + + loop_counter = 0; + loop_till_clear(priv->regs + I2C_REG_OFFSET_SR1, + I2C_BTF, I2C_SHIFT_BTF, + I2C_BTF_COUNTER); + WAIT_FOR_BTF(priv); + + send_index = + (__u8) (0xFF & priv->config.register_index); + + writel(send_index, priv->regs + I2C_REG_OFFSET_DR); + priv->config.index_format = I2C_NO_INDEX; + break; + default: + return -EINVAL; + } /* end of switch */ + + loop_counter = 0; + WAIT_FOR_BTF(priv); + + udelay(1200); + + if (I2C_READ == priv->config.operation) { + + I2C_SET_BIT(priv->regs + I2C_REG_OFFSET_CR, I2C_START); + + WAIT_FOR_START(priv); + + priv->config.status = I2C_STATUS_MASTER_MODE; + error_status = + send_slave_address(priv, priv->config.operation); + if (error_status) + return (error_status); + + WAIT_FOR_ENDAD(priv); + + dummy = readl(priv->regs + I2C_REG_OFFSET_SR2); + I2C_SET_BIT(priv->regs + I2C_REG_OFFSET_CR, I2C_PE); + I2C_SET_BIT(priv->regs + I2C_REG_OFFSET_CR, I2C_PE); + + loop_counter = 0; + while (I2C_READ_FIELD + (priv->regs + I2C_REG_OFFSET_SR2, I2C_ENDAD, + I2C_SHIFT_ENDAD) + && loop_counter < I2C_ENDAD_COUNTER) + loop_counter++; + if (loop_counter >= I2C_ENDAD_COUNTER) { + i2c_abort(priv); + return -EIO; + } + } + } + if ((I2C_READ == priv->config.operation) + && (priv->config.slave_address < 1024 + && priv->config.slave_address > 127) + ) { + I2C_SET_BIT(priv->regs + I2C_REG_OFFSET_CR, I2C_START); + priv->config.active_event.type = I2C_START_EVENT; + + WAIT_FOR_START(priv); + + priv->config.status = I2C_STATUS_MASTER_RECEIVER_MODE; + + error_status = send_slave_address(priv, I2C_READ); + + WAIT_FOR_ENDAD(priv); + + dummy = readl(priv->regs + I2C_REG_OFFSET_SR2); + I2C_SET_BIT(priv->regs + I2C_REG_OFFSET_CR, I2C_PE); + I2C_SET_BIT(priv->regs + I2C_REG_OFFSET_CR, I2C_PE); + + } + + dummy = dummy; + + error_status = error_status; + + if (I2C_READ == priv->config.operation) { + priv->config.status = I2C_STATUS_MASTER_RECEIVER_MODE; + } else { + priv->config.status = I2C_STATUS_MASTER_TRANSMITTER_MODE; + } + + return (0); + +} + +int write_i2c(struct nomadik_i2c_private *priv) { + int error_status = 0; + + switch (priv->config.index_transfer_mode) { + case I2C_TRANSFER_MODE_POLLING: + /* + Index Transfer + */ + if (I2C_BUS_SLAVE_MODE == priv->config.bus_control_mode) { + I2C_SET_BIT(priv->regs + I2C_REG_OFFSET_CR, I2C_ACK); + error_status = slave_index_receive(priv); + if (0 != error_status) + return (error_status); + } else { + error_status = master_index_transmit(priv); + if (0 != error_status) + return (error_status); + } + + /* + Data Transfer + */ + switch (priv->config.data_transfer_mode) { + case I2C_TRANSFER_MODE_POLLING: + error_status = transmit_data_polling(priv); + if (0 != error_status) + return (error_status); + + break; + + case I2C_TRANSFER_MODE_INTERRUPT: + I2C_SET_BIT(priv->regs + I2C_REG_OFFSET_CR, I2C_ITE); + break; + + default: + break; + } + break; + + case I2C_TRANSFER_MODE_INTERRUPT: + I2C_SET_BIT(priv->regs + I2C_REG_OFFSET_CR, I2C_ITE); + if (I2C_BUS_MASTER_MODE == + (i2c_bus_control_mode_t) priv->config.bus_control_mode) { + GENERATE_START_CONDITION(priv->regs); + } else { + I2C_SET_BIT(priv->regs + I2C_REG_OFFSET_CR, I2C_ACK); + } + break; + + case I2C_TRANSFER_MODE_DMA: + default: + return -EINVAL; + } + + return 0; + +} + +int read_i2c(struct nomadik_i2c_private *priv) { + int error_status; + + switch (priv->config.index_transfer_mode) { + case I2C_TRANSFER_MODE_POLLING: + /* + Index Transfer + */ + if (I2C_BUS_SLAVE_MODE == priv->config.bus_control_mode) { + I2C_SET_BIT(priv->regs + I2C_REG_OFFSET_CR, I2C_ACK); + error_status = slave_index_receive(priv); + if (error_status) + return (error_status); + } else { + error_status = master_index_transmit(priv); + if (error_status) + return (error_status); + } + + /* + Data Transfer + */ + switch (priv->config.data_transfer_mode) { + case I2C_TRANSFER_MODE_POLLING: + error_status = receive_data_polling(priv); + if (error_status) + return (error_status); + + break; + + case I2C_TRANSFER_MODE_INTERRUPT: + I2C_SET_BIT(priv->regs + I2C_REG_OFFSET_CR, I2C_ITE); + break; + + default: + break; + } + break; + + case I2C_TRANSFER_MODE_INTERRUPT: + I2C_SET_BIT(priv->regs + I2C_REG_OFFSET_CR, I2C_ITE); + + if (I2C_BUS_MASTER_MODE == + (i2c_bus_control_mode_t) priv->config.bus_control_mode) { + GENERATE_START_CONDITION(priv->regs); + } else { + I2C_SET_BIT(priv->regs + I2C_REG_OFFSET_CR, I2C_ACK); + } + break; + + case I2C_TRANSFER_MODE_DMA: + default: + return -EINVAL; + } + + return 0; + +} + +void reset_i2c(struct nomadik_i2c_private *priv) +{ + + /* Clear registers. */ + I2C_WRITE_REG(priv->regs + I2C_REG_OFFSET_CR, I2C_CLEAR); + I2C_WRITE_REG(priv->regs + I2C_REG_OFFSET_SR1, I2C_CLEAR); + I2C_WRITE_REG(priv->regs + I2C_REG_OFFSET_SR2, I2C_CLEAR); + I2C_WRITE_REG(priv->regs + I2C_REG_OFFSET_CCR, I2C_CLEAR); + I2C_WRITE_REG(priv->regs + I2C_REG_OFFSET_OAR1, I2C_CLEAR); + I2C_WRITE_REG(priv->regs + I2C_REG_OFFSET_OAR2, I2C_CLEAR); + I2C_WRITE_REG(priv->regs + I2C_REG_OFFSET_DR, I2C_CLEAR); + I2C_WRITE_REG(priv->regs + I2C_REG_OFFSET_ECCR, I2C_CLEAR); + + memset(&priv->config, 0, sizeof(priv->config)); + + priv->config.operation = I2C_NO_OPERATION; + priv->config.active_event.type = I2C_NO_EVENT; + priv->config.i2c_transmit_interrupt_threshold = 1; + priv->config.i2c_receive_interrupt_threshold = 1; +} + +int process_interrupt(struct nomadik_i2c_private *priv) +{ + int err_status; + volatile __u32 sr1 = 0; + volatile __u32 sr2 = 0; + __u8 send_index = 0; + volatile __u32 dummy, loop_counter; + + int interrupt_source = 0; + + priv->config.active_event.type = I2C_NO_EVENT; + + dummy = readl(priv->regs + I2C_REG_OFFSET_CR); + dummy = dummy; + + sr1 = readl(priv->regs + I2C_REG_OFFSET_SR1); + sr2 = readl(priv->regs + I2C_REG_OFFSET_SR2); + + if (NOMADIK_READ_BITS(sr1, I2C_EVF)) { + if (NOMADIK_READ_BITS(sr2, I2C_BERR)) + interrupt_source = I2C_IT_BERR; + else if (NOMADIK_READ_BITS(sr2, I2C_SCLFAL)) + interrupt_source = I2C_IT_SCLFAL; + else if (NOMADIK_READ_BITS(sr2, I2C_ARLO)) + interrupt_source = I2C_IT_ARLO; + else if (NOMADIK_READ_BITS(sr2, I2C_AF)) + interrupt_source = I2C_IT_AF; + else if (NOMADIK_READ_BITS(sr1, I2C_SB)) + interrupt_source = I2C_IT_SB; + else if (NOMADIK_READ_BITS(sr1, I2C_ADSL)) + interrupt_source = I2C_IT_ADSL; + else if (NOMADIK_READ_BITS(sr2, I2C_STOPF)) + interrupt_source = I2C_IT_STOPF; + else if (NOMADIK_READ_BITS(sr2, I2C_ENDAD)) + interrupt_source = I2C_IT_ENDAD; + else if (NOMADIK_READ_BITS(sr1, I2C_BTF)) + interrupt_source = I2C_IT_BTF; + else if (NOMADIK_READ_BITS(sr1, I2C_ADD10)) + interrupt_source = I2C_IT_ADD10; + } + + switch (interrupt_source) { + case I2C_IT_BTF: + { + if (I2C_STATUS_SLAVE_RECEIVER_MODE == + priv->config.status) { + *(priv->config.databuffer) = + (__u8) I2C_READ_REG(priv->regs + + I2C_REG_OFFSET_DR); + + priv->config.transfer_data++; + priv->config.count_data--; + + if (priv->config.count_data > 0) { + priv->config.active_event.type = + I2C_DATA_RX_EVENT; + priv->config.databuffer++; + } else { + I2C_CLR_BIT(priv->regs + + I2C_REG_OFFSET_CR, I2C_ACK); + priv->config.active_event.type = + I2C_DATA_RX_EVENT; + } + } + + else if (I2C_STATUS_MASTER_TRANSMITTER_MODE == + priv->config.status) { + switch (priv->config.index_format) { + case I2C_HALF_WORD_LITTLE_ENDIAN: + case I2C_HALF_WORD_BIG_ENDIAN: + I2C_WRITE_REG(priv->regs + + I2C_REG_OFFSET_DR, + (__u8) (priv->config. + register_index)); + + priv->config.index_format = + I2C_BYTE_INDEX; + priv->config.active_event.type = + I2C_INDEX_TX_EVENT; + + break; + + case I2C_BYTE_INDEX: + if (priv->config.multi_operation) { + I2C_WRITE_REG(priv->regs + + I2C_REG_OFFSET_DR, + *priv->config. + databuffer); + + priv->config.databuffer++; + } else { + I2C_WRITE_REG(priv->regs + + I2C_REG_OFFSET_DR, + priv->config. + data); + + } + + priv->config.index_format = + I2C_NO_INDEX; + priv->config.transfer_data++; + priv->config.count_data--; + + priv->config.active_event.type = + I2C_DATA_TX_EVENT; + break; + + case I2C_NO_INDEX: + if (priv->config.count_data > 0) { + if (NOMADIK_FALSE == + priv->config. + multi_operation) { + I2C_WRITE_REG(priv-> + regs + + I2C_REG_OFFSET_DR, + priv-> + config. + data); + } else { + I2C_WRITE_REG(priv-> + regs + + I2C_REG_OFFSET_DR, + *priv-> + config. + databuffer); + } + + priv->config.databuffer++; + priv->config.transfer_data++; + priv->config.count_data--; + + priv->config.active_event.type = + I2C_DATA_TX_EVENT; + } else { + dummy = + I2C_READ_REG(priv->regs + + I2C_REG_OFFSET_DR); + + I2C_SET_BIT(priv->regs + + I2C_REG_OFFSET_CR, + I2C_STOP); + I2C_CLR_BIT(priv->regs + + I2C_REG_OFFSET_CR, + I2C_ITE); + + priv->config.status = + I2C_STATUS_SLAVE_MODE; + priv->config.active_event.type = + I2C_TRANSFER_OK_EVENT; + + } + } + } + else if (I2C_STATUS_MASTER_RECEIVER_MODE == + priv->config.status) { + switch (priv->config.index_format) { + case I2C_HALF_WORD_LITTLE_ENDIAN: + case I2C_HALF_WORD_BIG_ENDIAN: + I2C_WRITE_REG(priv->regs + + I2C_REG_OFFSET_DR, + (__u8) (priv->config. + register_index)); + + priv->config.index_format = + I2C_BYTE_INDEX; + priv->config.active_event.type = + I2C_INDEX_TX_EVENT; + + break; + + case I2C_BYTE_INDEX: + priv->config.index_format = + I2C_NO_INDEX; + + priv->config.active_event.type = + I2C_INDEX_TX_EVENT; + + GENERATE_START_CONDITION(priv->regs); + break; + + case I2C_NO_INDEX: + if (!priv->config.multi_operation) { + I2C_SET_BIT(priv->regs + + I2C_REG_OFFSET_CR, + I2C_STOP); + *priv->config.databuffer = + (__u8) readl(priv->regs + + I2C_REG_OFFSET_DR); + priv->config.count_data--; + priv->config.transfer_data++; + + priv->config.active_event.type = + I2C_DATA_RX_EVENT; + + I2C_CLR_BIT(priv->regs + + I2C_REG_OFFSET_CR, + I2C_ITE); + + priv->config.active_event.type = + I2C_TRANSFER_OK_EVENT; + priv->config.status = + I2C_STATUS_SLAVE_MODE; + } else { + priv->config.count_data--; + if (priv->config.count_data > 1) { + *priv->config. + databuffer = + (__u8) readl(priv-> + regs + + I2C_REG_OFFSET_DR); + + priv->config. + transfer_data++; + priv->config. + databuffer++; + priv->config. + active_event.type = + I2C_DATA_RX_EVENT; + } else if (1 == + priv->config. + count_data) { + I2C_CLR_BIT(priv->regs + + I2C_REG_OFFSET_CR, + I2C_ACK); + + *priv->config. + databuffer = + (__u8) readl(priv-> + regs + + I2C_REG_OFFSET_DR); + + I2C_SET_BIT(priv->regs + + I2C_REG_OFFSET_CR, + I2C_STOP); + + priv->config. + transfer_data++; + priv->config. + databuffer++; + priv->config. + active_event.type = + I2C_DATA_RX_EVENT; + } else { + *priv->config. + databuffer = + (__u8) readl(priv-> + regs + + I2C_REG_OFFSET_DR); + + priv->config. + transfer_data++; + + I2C_SET_BIT(priv->regs + + I2C_REG_OFFSET_CR, + I2C_STOP); + I2C_CLR_BIT(priv->regs + + I2C_REG_OFFSET_CR, + I2C_ITE); + + priv->config. + active_event.type = + I2C_TRANSFER_OK_EVENT; + priv->config.status = + I2C_STATUS_SLAVE_MODE; + + } + } /*End of Multi Operation */ + } /*End Of switch */ + } /*End Of Master Receiver */ + + else if (I2C_STATUS_SLAVE_TRANSMITTER_MODE == + priv->config.status) { + if (priv->config.count_data > 0) { + if (priv->config.multi_operation) { + I2C_WRITE_REG(priv->regs + + I2C_REG_OFFSET_DR, + *priv->config. + databuffer); + + priv->config.databuffer++; + priv->config.transfer_data++; + priv->config.count_data--; + + priv->config.active_event.type = + I2C_DATA_TX_EVENT; + } else { + I2C_WRITE_REG(priv->regs + + I2C_REG_OFFSET_DR, + priv->config. + data); + priv->config.transfer_data++; + priv->config.count_data--; + + priv->config.active_event.type = + I2C_DATA_TX_EVENT; + + } + } else { + I2C_WRITE_REG(priv->regs + + I2C_REG_OFFSET_DR, 0xFF); + + priv->config.active_event.type = + I2C_DATA_TX_EVENT; + + } + } + + if ((I2C_STATUS_SLAVE_MODE == priv->config.status) + && (priv->config.count_data == 0) + ) { + dummy = + I2C_READ_REG(priv->regs + + I2C_REG_OFFSET_DR); + dummy = dummy; + + I2C_SET_BIT(priv->regs + I2C_REG_OFFSET_CR, + I2C_STOP); + I2C_CLR_BIT(priv->regs + I2C_REG_OFFSET_CR, + I2C_ITE); + dummy = + I2C_READ_REG(priv->regs + + I2C_REG_OFFSET_SR1); + dummy = + I2C_READ_REG(priv->regs + + I2C_REG_OFFSET_SR2); + dummy = dummy; + + priv->config.active_event.type = + I2C_TRANSFER_OK_EVENT; + } + break; + } + + case I2C_IT_ADSL: /* Slave addressed. */ + { + if (I2C_READ == priv->config.operation) { + priv->config.status = + I2C_STATUS_SLAVE_RECEIVER_MODE; + } else { + if ((I2C_STATUS_SLAVE_MODE == + priv->config.status) + && (priv->config.own_address < 1024 + && priv->config.own_address > 127) + ) { + I2C_SET_BIT(priv->regs + + I2C_REG_OFFSET_CR, I2C_ACK); + } else { + I2C_CLR_BIT(priv->regs + + I2C_REG_OFFSET_CR, I2C_ACK); + } + + priv->config.status = + I2C_STATUS_SLAVE_TRANSMITTER_MODE; + } + + priv->config.active_event.type = I2C_INDEX_TX_EVENT; + break; + } /* End I2C_IT_ADSL */ + + case I2C_IT_SB: /* Start condition generated. */ + { + + if (!NOMADIK_READ_BITS(sr1, I2C_MASTER) + || I2C_BUS_MASTER_MODE != + priv->config.bus_control_mode) { + priv->config.active_event.type = + I2C_INTERNAL_ERROR_EVENT; + break; + } + + if (priv->config.status != + I2C_STATUS_MASTER_RECEIVER_MODE) { + priv->config.status = I2C_STATUS_MASTER_MODE; + } + + if (I2C_READ == priv->config.operation) { + if (I2C_NO_INDEX == priv->config.index_format) { + err_status = + send_slave_address(priv, I2C_READ); + if (err_status) { + i2c_abort(priv); + return (err_status); + } + } else { + err_status = + send_slave_address(priv, I2C_WRITE); + if (err_status) { + i2c_abort(priv); + return (err_status); + } + } + } else { + err_status = + send_slave_address(priv, I2C_WRITE); + if (0 != err_status) { + i2c_abort(priv); + return (err_status); + } + } + + priv->config.active_event.type = I2C_START_EVENT; + + break; + } /* End I2C_IT_SB. */ + + case I2C_IT_AF: /* Acknowledge Failure. */ + { + + if ((I2C_STATUS_SLAVE_TRANSMITTER_MODE == + priv->config.status) + && (0 == priv->config.count_data) + ) { + priv->config.status = I2C_STATUS_SLAVE_MODE; + + priv->config.active_event.type = + I2C_TRANSFER_OK_EVENT; + + dummy = + I2C_TEST_BIT(priv->regs + + I2C_REG_OFFSET_SR2, I2C_AF); + + dummy = + I2C_READ_REG(priv->regs + + I2C_REG_OFFSET_DR); + I2C_SET_BIT(priv->regs + I2C_REG_OFFSET_CR, + I2C_STOP); + + dummy = dummy; + dummy = + I2C_READ_REG(priv->regs + + I2C_REG_OFFSET_DR); + dummy = dummy; + + I2C_CLR_BIT(priv->regs + I2C_REG_OFFSET_CR, + I2C_STOP); + + } else { + i2c_abort(priv); + priv->config.active_event.type = + I2C_AF_ERROR_EVENT; + + } + + dummy = I2C_READ_REG(priv->regs + I2C_REG_OFFSET_CR); + dummy = I2C_READ_REG(priv->regs + I2C_REG_OFFSET_CR); + break; + } /* End I2C_IT_AF. */ + + case I2C_IT_STOPF: + { + priv->config.status = I2C_STATUS_SLAVE_MODE; + priv->config.active_event.type = I2C_TRANSFER_OK_EVENT; + + if (I2C_STATUS_SLAVE_TRANSMITTER_MODE == + priv->config.status) { + I2C_CLR_BIT(priv->regs + I2C_REG_OFFSET_CR, + I2C_STOP); + } + + dummy = I2C_READ_REG(priv->regs + I2C_REG_OFFSET_SR2); + dummy = I2C_READ_REG(priv->regs + I2C_REG_OFFSET_CR); + dummy = I2C_READ_REG(priv->regs + I2C_REG_OFFSET_CR); + I2C_CLR_BIT(priv->regs + I2C_REG_OFFSET_CR, I2C_ITE); + + break; + } /* End I2C_IT_STOPF. */ + + case I2C_IT_BERR: + case I2C_IT_ARLO: + { + i2c_abort(priv); + priv->config.active_event.type = + I2C_ARBITRATION_LOST_ERROR_EVENT; + + break; + } /* End I2C_IT_ARLO. */ + + case I2C_IT_ADD10: + { + I2C_WRITE_REG(priv->regs + I2C_REG_OFFSET_DR, + (__u8) (0xFF & priv->config. + slave_address)); + + priv->config.active_event.type = I2C_INDEX_TX_EVENT; + + break; + } /* End I2C_IT_ADD10. */ + + case I2C_IT_SCLFAL: + { + i2c_abort(priv); + + break; + } /* End I2C_IT_SCLFAL. */ + + case I2C_IT_ENDAD: /* End of address transmission. */ + { + if (!NOMADIK_READ_BITS(sr1, I2C_MASTER)) { + priv->config.active_event.type = + I2C_INTERNAL_ERROR_EVENT; + break; + } + + if (I2C_WRITE == priv->config.operation) { + /* Clear ENDAD. */ + I2C_SET_BIT(priv->regs + I2C_REG_OFFSET_CR, + I2C_PE); + + loop_counter = 0; + while (I2C_TEST_BIT + (priv->regs + I2C_REG_OFFSET_SR2, + I2C_ENDAD) + && loop_counter < I2C_INT_ENDED_COUNTER) + loop_counter++; + + if (loop_counter < I2C_INT_ENDED_COUNTER) { + priv->config.status = + I2C_STATUS_MASTER_TRANSMITTER_MODE; + + if (priv->config.index_format > + I2C_NO_INDEX) { + switch (priv->config. + index_format) { + case I2C_BYTE_INDEX: + send_index = + (__u8) (0xFF & + priv-> + config. + register_index); + break; + + case I2C_HALF_WORD_LITTLE_ENDIAN: + send_index = + (__u8) (0xFF & + priv-> + config. + register_index); + priv->config. + register_index = + (__u16) (priv-> + config. + register_index + >> 8); + break; + + case I2C_HALF_WORD_BIG_ENDIAN: + + send_index = + (__u8) (0xFF & + (priv-> + config. + register_index + >> 8)); + priv->config. + register_index &= + 0xff; + break; + + default: + break; + } + + I2C_WRITE_REG(priv->regs + + I2C_REG_OFFSET_DR, + send_index); + + loop_counter = 0; + while + (I2C_TEST_BIT + (priv->regs + + I2C_REG_OFFSET_SR1, + I2C_BTF) + && loop_counter < + I2C_BTF_COUNTER) + loop_counter++; + + priv->config.active_event.type = + I2C_INDEX_TX_EVENT; + } else { + if (priv->config. + multi_operation) { + I2C_WRITE_REG(priv-> + regs + + I2C_REG_OFFSET_DR, + *priv-> + config. + databuffer); + priv->config. + databuffer++; + + } else { + I2C_WRITE_REG(priv-> + regs + + I2C_REG_OFFSET_DR, + priv-> + config. + data); + + } + + loop_counter = 0; + while + (I2C_TEST_BIT + (priv->regs + + I2C_REG_OFFSET_SR1, + I2C_BTF) + && loop_counter < + I2C_BTF_COUNTER) { + loop_counter++; + }; + + priv->config.transfer_data++; + priv->config.count_data--; + + priv->config.active_event.type = + I2C_DATA_TX_EVENT; + } + } else { + priv->config.active_event.type = + I2C_INDEX_TX_EVENT; + } + } else { + if (priv->config.index_format > I2C_NO_INDEX) { + I2C_SET_BIT(priv->regs + + I2C_REG_OFFSET_CR, I2C_PE); + + loop_counter = 0; + while (I2C_TEST_BIT + (priv->regs + I2C_REG_OFFSET_SR2, + I2C_ENDAD) + && loop_counter < + I2C_INT_ENDED_COUNTER) { + loop_counter++; + }; + if (loop_counter < + I2C_INT_ENDED_COUNTER) { + priv->config.status = + I2C_STATUS_MASTER_RECEIVER_MODE; + + switch (priv->config. + index_format) { + case I2C_BYTE_INDEX: + send_index = + (__u8) (0xFF & + priv-> + config. + register_index); + break; + + case I2C_HALF_WORD_LITTLE_ENDIAN: + send_index = + (__u8) (0xFF & + priv-> + config. + register_index); + priv->config. + register_index = + (__u16) (priv-> + config. + register_index + >> 8); + break; + + case I2C_HALF_WORD_BIG_ENDIAN: + send_index = + (__u8) (0xFF & + (priv-> + config. + register_index + >> 8)); + priv->config. + register_index &= + 0xff; + + break; + + default: + break; + } + + I2C_WRITE_REG(priv->regs + + I2C_REG_OFFSET_DR, + send_index); + + loop_counter = 0; + while (I2C_TEST_BIT + (priv->regs + + I2C_REG_OFFSET_SR1, + I2C_BTF) + && loop_counter < + I2C_BTF_COUNTER) + loop_counter++; + } + + priv->config.active_event.type = + I2C_INDEX_TX_EVENT; + } else { + if (I2C_STATUS_MASTER_MODE == + priv->config.status + && (priv->config.slave_address < + 1024 + && priv->config.slave_address > + 127) + ) { + I2C_SET_BIT(priv->regs + + I2C_REG_OFFSET_CR, + I2C_PE); + + loop_counter = 0; + while (I2C_TEST_BIT + (priv->regs + + I2C_REG_OFFSET_SR2, + I2C_ENDAD) + && loop_counter < + I2C_INT_ENDED_COUNTER) + loop_counter++; + if (loop_counter < + I2C_INT_ENDED_COUNTER) { + GENERATE_START_CONDITION + (priv->regs); + + priv->config.status = + I2C_STATUS_MASTER_RECEIVER_MODE; + priv->config. + active_event.type = + I2C_WAITING_DATA_RX_EVENT; + } + } else { + if (priv->config.count_data > 1) { + I2C_SET_BIT(priv->regs + + I2C_REG_OFFSET_CR, + I2C_ACK); + } else { + I2C_CLR_BIT(priv->regs + + I2C_REG_OFFSET_CR, + I2C_ACK); + } + + I2C_SET_BIT(priv->regs + + I2C_REG_OFFSET_CR, + I2C_PE); + + loop_counter = 0; + while (I2C_TEST_BIT + (priv->regs + + I2C_REG_OFFSET_SR2, + I2C_ENDAD) + && loop_counter < + I2C_INT_ENDED_COUNTER) { + loop_counter++; + }; + if (loop_counter < + I2C_INT_ENDED_COUNTER) { + priv->config.status = + I2C_STATUS_MASTER_RECEIVER_MODE; + priv->config. + active_event.type = + I2C_WAITING_DATA_RX_EVENT; + } else { + priv->config. + active_event.type = + I2C_INDEX_TX_EVENT; + } + } + } + + } /* End of MASTER RECEIVER. */ + break; + } /* End I2C_IT_ENDAD. */ + + default: + { + i2c_abort(priv); + priv->config.active_event.type = + I2C_INTERNAL_ERROR_EVENT; + + break; + } /* End default. */ + } /* End switch. */ + + if (I2C_TRANSFER_OK_EVENT == priv->config.active_event.type) { + priv->config.operation = I2C_NO_OPERATION; + I2C_CLR_BIT(priv->regs + I2C_REG_OFFSET_CR, I2C_STOP); + } + + return 0; + +} + +/* stn8810 cut specific i2c needs to insert some delay in execution*/ +void stn_cut_mdelay(int dlytime) +{ + mdelay(dlytime); +} + + --- /dev/null +++ linux-2.6.20/drivers/i2c/busses/i2c-stn8815.c @@ -0,0 +1,1817 @@ + +/* drivers/i2c/busses/i2c-nmdk8815.c + * + * Support for i2c bus on STn8815 (Nomadik) chips. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Author: Melwyn LOBO + *----------------------------------------------------------------------------- + */ + +#include +#include + +#include +#include +#include "i2c-nomadik.h" +#include + +/*####################################################################### + Macros to access I2C Registers with their offsets +######################################################################### +*/ + +#define I2C_REG_OFFSET_CR 0x00 +#define I2C_REG_OFFSET_SCR 0x04 +#define I2C_REG_OFFSET_HSMCR 0x08 +#define I2C_REG_OFFSET_MCR 0x0C +#define I2C_REG_OFFSET_TFR 0x10 +#define I2C_REG_OFFSET_SR 0x14 +#define I2C_REG_OFFSET_RFR 0x18 +#define I2C_REG_OFFSET_TFTR 0x1C +#define I2C_REG_OFFSET_RFTR 0x20 +#define I2C_REG_OFFSET_DMAR 0x24 +#define I2C_REG_OFFSET_BRCR 0x28 +#define I2C_REG_OFFSET_IMSCR 0x2C +#define I2C_REG_OFFSET_RISR 0x30 +#define I2C_REG_OFFSET_MISR 0x34 +#define I2C_REG_OFFSET_ICR 0x38 + +/*####################################################################### + Macros for Bitmasks for interrupt registers +######################################################################### +*/ + +#define I2C_IT_TXFE STD_MASK_BIT0 +#define I2C_IT_TXFNE STD_MASK_BIT1 +#define I2C_IT_TXFF STD_MASK_BIT2 +#define I2C_IT_TXOVR STD_MASK_BIT3 +#define I2C_IT_RXFE STD_MASK_BIT4 +#define I2C_IT_RXFNF STD_MASK_BIT5 +#define I2C_IT_RXFF STD_MASK_BIT6 +#define I2C_IT_RFSR STD_MASK_BIT16 +#define I2C_IT_RFSE STD_MASK_BIT17 +#define I2C_IT_WTSR STD_MASK_BIT18 +#define I2C_IT_MTD STD_MASK_BIT19 +#define I2C_IT_STD STD_MASK_BIT20 +#define I2C_IT_MAL STD_MASK_BIT24 +#define I2C_IT_BERR STD_MASK_BIT25 + +#define I2C0_IRQ_SRC_TRANSMIT_FIFO_EMPTY STD_MASK_BIT0 +#define I2C0_IRQ_SRC_TRANSMIT_FIFO_NEARLY_EMPTY STD_MASK_BIT1 +#define I2C0_IRQ_SRC_TRANSMIT_FIFO_FULL STD_MASK_BIT2 +#define I2C0_IRQ_SRC_TRANSMIT_FIFO_OVERRUN STD_MASK_BIT3 +#define I2C0_IRQ_SRC_RECEIVE_FIFO_EMPTY STD_MASK_BIT4 +#define I2C0_IRQ_SRC_RECEIVE_FIFO_NEARLY_FULL STD_MASK_BIT5 +#define I2C0_IRQ_SRC_RECEIVE_FIFO_FULL STD_MASK_BIT6 +#define I2C0_IRQ_SRC_READ_FROM_SLAVE_REQUEST STD_MASK_BIT16 +#define I2C0_IRQ_SRC_READ_FROM_SLAVE_EMPTY STD_MASK_BIT17 +#define I2C0_IRQ_SRC_WRITE_TO_SLAVE_REQUEST STD_MASK_BIT18 +#define I2C0_IRQ_SRC_MASTER_TRANSACTION_DONE STD_MASK_BIT19 +#define I2C0_IRQ_SRC_SLAVE_TRANSACTION_DONE STD_MASK_BIT20 +#define I2C0_IRQ_SRC_MASTER_ARBITRATION_LOST STD_MASK_BIT24 +#define I2C0_IRQ_SRC_BUS_ERROR STD_MASK_BIT25 +#define I2C0_IRQ_SRC_ALL 0x31F003F +#define I2C_IRQ_SRC_ALL I2C0_IRQ_SRC_ALL + +#define I2C1_IRQ_SRC_TRANSMIT_FIFO_EMPTY (STD_MASK_BIT29 | STD_MASK_BIT0) +#define I2C1_IRQ_SRC_TRANSMIT_FIFO_NEARLY_EMPTY (STD_MASK_BIT29 | STD_MASK_BIT1) +#define I2C1_IRQ_SRC_TRANSMIT_FIFO_FULL (STD_MASK_BIT29 | STD_MASK_BIT2) +#define I2C1_IRQ_SRC_TRANSMIT_FIFO_OVERRUN (STD_MASK_BIT29 | STD_MASK_BIT3) +#define I2C1_IRQ_SRC_RECEIVE_FIFO_EMPTY (STD_MASK_BIT29 | STD_MASK_BIT4) +#define I2C1_IRQ_SRC_RECEIVE_FIFO_NEARLY_FULL (STD_MASK_BIT29 | STD_MASK_BIT5) +#define I2C1_IRQ_SRC_RECEIVE_FIFO_FULL (STD_MASK_BIT29 | STD_MASK_BIT6) +#define I2C1_IRQ_SRC_READ_FROM_SLAVE_REQUEST (STD_MASK_BIT29 | STD_MASK_BIT16) +#define I2C1_IRQ_SRC_READ_FROM_SLAVE_EMPTY (STD_MASK_BIT29 | STD_MASK_BIT17) +#define I2C1_IRQ_SRC_WRITE_TO_SLAVE_REQUEST (STD_MASK_BIT29 | STD_MASK_BIT18) +#define I2C1_IRQ_SRC_MASTER_TRANSACTION_DONE (STD_MASK_BIT29 | STD_MASK_BIT19) +#define I2C1_IRQ_SRC_SLAVE_TRANSACTION_DONE (STD_MASK_BIT29 | STD_MASK_BIT20) +#define I2C1_IRQ_SRC_MASTER_ARBITRATION_LOST (STD_MASK_BIT29 | STD_MASK_BIT24) +#define I2C1_IRQ_SRC_BUS_ERROR (STD_MASK_BIT29 | STD_MASK_BIT25) +#define I2C1_IRQ_SRC_ALL (STD_MASK_BIT29 | 0x31F003F) + + /*####################################################################### + I2C Control Register + ######################################################################### + */ + +#define I2C_CR_PE STD_MASK_BIT0 +#define I2C_CR_OM 0x6 +#define I2C_CR_SAM STD_MASK_BIT3 +#define I2C_CR_SM 0x30 +#define I2C_CR_SGCM STD_MASK_BIT6 +#define I2C_CR_FTX STD_MASK_BIT7 +#define I2C_CR_FRX STD_MASK_BIT8 +#define I2C_CR_DMA_TX_EN STD_MASK_BIT9 +#define I2C_CR_DMA_RX_EN STD_MASK_BIT10 +#define I2C_CR_DMA_SLE STD_MASK_BIT11 +#define I2C_CR_LM STD_MASK_BIT12 +#define I2C_CR_FON 0x6000 + +#define I2C_CR_SHIFT_PE 0 +#define I2C_CR_SHIFT_OM 1 +#define I2C_CR_SHIFT_SAM 3 +#define I2C_CR_SHIFT_SM 4 +#define I2C_CR_SHIFT_SGCM 6 +#define I2C_CR_SHIFT_FTX 7 +#define I2C_CR_SHIFT_FRX 8 +#define I2C_CR_SHIFT_DMA_TX_EN 9 +#define I2C_CR_SHIFT_DMA_RX_EN 10 +#define I2C_CR_SHIFT_DMA_SLE 11 +#define I2C_CR_SHIFT_LM 12 +#define I2C_CR_SHIFT_FON 13 + + /*####################################################################### + I2C Slave Control Register + ######################################################################### + */ + +#define I2C_SCR_ADDR 0x3FF +#define I2C_SCR_DATA_SETUP_TIME 0xFFFF0000 + +#define I2C_SCR_SHIFT_ADDR 0 +#define I2C_SCR_SHIFT_DATA_SETUP_TIME 16 + + /*####################################################################### + I2C Master Control Register + ######################################################################### + */ + +#define I2C_MCR_OP STD_MASK_BIT0 +#define I2C_MCR_A7 0xFE +#define I2C_MCR_EA10 0x700 +#define I2C_MCR_SB STD_MASK_BIT11 +#define I2C_MCR_AM 0x3000 +#define I2C_MCR_STOP STD_MASK_BIT14 +#define I2C_MCR_LENGTH 0x3FF8000 +#define I2C_MCR_A10 0x7FE +#define I2C_MCR_LENGTH_STOP_OP 0x3FFC001 + +#define I2C_MCR_SHIFT_OP 0 +#define I2C_MCR_SHIFT_A7 1 +#define I2C_MCR_SHIFT_EA10 8 +#define I2C_MCR_SHIFT_SB 11 +#define I2C_MCR_SHIFT_AM 12 +#define I2C_MCR_SHIFT_STOP 14 +#define I2C_MCR_SHIFT_LENGTH 15 +#define I2C_MCR_SHIFT_A10 1 +#define I2C_MCR_SHIFT_LENGTH_STOP_OP 0 + +/*####################################################################### + I2C Status Register +######################################################################### +*/ + +#define I2C_SR_OP 0x3 +#define I2C_SR_STATUS 0xC +#define I2C_SR_CAUSE 0x70 +#define I2C_SR_TYPE 0x180 +#define I2C_SR_LENGTH 0xFF700 + +#define I2C_SR_SHIFT_OP 0 +#define I2C_SR_SHIFT_STATUS 2 +#define I2C_SR_SHIFT_CAUSE 4 +#define I2C_SR_SHIFT_TYPE 7 +#define I2C_SR_SHIFT_LENGTH 9 + +/*####################################################################### + I2C DMA Register +######################################################################### +*/ + +#define I2C_DMA_SBSIZE_RX 0x7 +#define I2C_DMA_BURST_RX STD_MASK_BIT3 +#define I2C_DMA_DBSIZE_TX 0x700 +#define I2C_DMA_BURST_TX STD_MASK_BIT11 + +#define I2C_DMA_SHIFT_SBSIZE_RX 0 +#define I2C_DMA_SHIFT_BURST_RX 3 +#define I2C_DMA_SHIFT_DBSIZE_TX 8 +#define I2C_DMA_SHIFT_BURST_TX 11 + +/*####################################################################### + I2C Baud Rate Control Register +######################################################################### +*/ + +#define I2C_BRCR_BRCNT2 0xFFFF +#define I2C_BRCR_BRCNT1 0xFFFF0000 + +#define I2C_BRCR_SHIFT_BRCNT2 0 +#define I2C_BRCR_SHIFT_BRCNT1 16 + +/*####################################################################### + I2C Interrupt Register +######################################################################### +*/ +#define I2C_INT_TXFE STD_MASK_BIT0 +#define I2C_INT_TXFNE STD_MASK_BIT1 +#define I2C_INT_TXFF STD_MASK_BIT2 +#define I2C_INT_TXFOVR STD_MASK_BIT3 +#define I2C_INT_RXFE STD_MASK_BIT4 +#define I2C_INT_RXFNF STD_MASK_BIT5 +#define I2C_INT_RXFF STD_MASK_BIT6 +#define I2C_INT_RFSR STD_MASK_BIT16 +#define I2C_INT_RFSE STD_MASK_BIT17 +#define I2C_INT_WTSR STD_MASK_BIT18 +#define I2C_INT_MTD STD_MASK_BIT19 +#define I2C_INT_STD STD_MASK_BIT20 +#define I2C_INT_MAL STD_MASK_BIT24 +#define I2C_INT_BERR STD_MASK_BIT25 + +#define I2C_INT_SHIFT_TXFE 0 +#define I2C_INT_SHIFT_TXFNE 1 +#define I2C_INT_SHIFT_TXFF 2 +#define I2C_INT_SHIFT_TXFOVR 3 +#define I2C_INT_SHIFT_RXFE 4 +#define I2C_INT_SHIFT_RXFNF 5 +#define I2C_INT_SHIFT_RXFF 6 +#define I2C_INT_SHIFT_RFSR 16 +#define I2C_INT_SHIFT_RFSE 17 +#define I2C_INT_SHIFT_WTSR 18 +#define I2C_INT_SHIFT_MTD 19 +#define I2C_INT_SHIFT_STD 20 +#define I2C_INT_SHIFT_MAL 24 +#define I2C_INT_SHIFT_BERR 25 + +/*####################################################################### + Default I2C Register Values +######################################################################### + */ + +#define DEFAULT_BRCNT_REG (GEN_MASK((__u32)(STD_F_IN_HZ/(STD_SPEED_IN_HZ*2)),I2C_BRCR_BRCNT2,I2C_BRCR_SHIFT_BRCNT2)|\ + GEN_MASK(0,I2C_BRCR_BRCNT1, I2C_BRCR_SHIFT_BRCNT1) \ + ) + +#define DEFAULT_MCR_REG(address) ( GEN_MASK(0,I2C_MCR_OP,I2C_MCR_SHIFT_OP) |\ + GEN_MASK(0,I2C_MCR_SB,I2C_MCR_SHIFT_SB) | \ + GEN_MASK(1,I2C_MCR_AM,I2C_MCR_SHIFT_AM) | \ + GEN_MASK(address,I2C_MCR_A10,I2C_MCR_SHIFT_A10) | \ + GEN_MASK(1,I2C_MCR_STOP,I2C_MCR_SHIFT_STOP) \ + ) + +#define DEFAULT_CR_REG ( GEN_MASK(0,I2C_CR_SM,I2C_CR_SHIFT_SM) | \ + GEN_MASK(0,I2C_CR_LM, I2C_CR_SHIFT_LM) |\ + GEN_MASK(0,I2C_CR_SGCM, I2C_CR_SHIFT_SGCM) |\ + GEN_MASK(0,I2C_CR_DMA_TX_EN, I2C_CR_SHIFT_DMA_TX_EN) |\ + GEN_MASK(0,I2C_CR_DMA_RX_EN, I2C_CR_SHIFT_DMA_RX_EN) |\ + GEN_MASK(0,I2C_DMA_BURST_TX, I2C_DMA_SHIFT_BURST_TX)|\ + GEN_MASK(0,I2C_DMA_BURST_RX, I2C_DMA_SHIFT_BURST_RX) |\ + GEN_MASK(1,I2C_CR_OM, I2C_CR_SHIFT_OM) |\ + GEN_MASK(0,I2C_CR_DMA_SLE, I2C_CR_SHIFT_DMA_SLE) |\ + GEN_MASK(0,I2C_CR_FON, I2C_CR_SHIFT_FON)\ + ) + +#define DEFAULT_SCR_REG(address) ( GEN_MASK(address,I2C_SCR_ADDR,I2C_SCR_SHIFT_ADDR) |\ + GEN_MASK(0,I2C_SCR_DATA_SETUP_TIME, I2C_SCR_SHIFT_DATA_SETUP_TIME)\ + ) + +#define DISABLE_ALL_INTERRUPTS(id) ~((__u32)I2C_IRQ_SRC_ALL & (__u32)(((id << I2CID_SHIFT) | I2C_IRQ_SRC_ALL))) + +#define ENABLE_ALL_INTERRUPTS_I2C0 ((__u32)I2C_IRQ_SRC_ALL & \ + ( \ + (__u32) I2C0_IRQ_SRC_TRANSMIT_FIFO_NEARLY_EMPTY | \ + (__u32) I2C0_IRQ_SRC_TRANSMIT_FIFO_OVERRUN | \ + (__u32) I2C0_IRQ_SRC_RECEIVE_FIFO_NEARLY_FULL | \ + (__u32) I2C0_IRQ_SRC_RECEIVE_FIFO_FULL | \ + (__u32) I2C0_IRQ_SRC_READ_FROM_SLAVE_REQUEST | \ + (__u32) I2C0_IRQ_SRC_WRITE_TO_SLAVE_REQUEST | \ + (__u32) I2C0_IRQ_SRC_MASTER_TRANSACTION_DONE | \ + (__u32) I2C0_IRQ_SRC_SLAVE_TRANSACTION_DONE | \ + (__u32) I2C0_IRQ_SRC_MASTER_ARBITRATION_LOST | \ + (__u32) I2C0_IRQ_SRC_BUS_ERROR \ + ) ) + +#define ENABLE_ALL_INTERRUPTS_I2C1 ((__u32)I2C_IRQ_SRC_ALL & \ + ( \ + (__u32) I2C1_IRQ_SRC_TRANSMIT_FIFO_NEARLY_EMPTY | \ + (__u32) I2C1_IRQ_SRC_TRANSMIT_FIFO_OVERRUN | \ + (__u32) I2C1_IRQ_SRC_RECEIVE_FIFO_NEARLY_FULL | \ + (__u32) I2C1_IRQ_SRC_RECEIVE_FIFO_FULL | \ + (__u32) I2C1_IRQ_SRC_READ_FROM_SLAVE_REQUEST | \ + (__u32) I2C1_IRQ_SRC_WRITE_TO_SLAVE_REQUEST | \ + (__u32) I2C1_IRQ_SRC_MASTER_TRANSACTION_DONE | \ + (__u32) I2C1_IRQ_SRC_SLAVE_TRANSACTION_DONE | \ + (__u32) I2C1_IRQ_SRC_MASTER_ARBITRATION_LOST | \ + (__u32) I2C1_IRQ_SRC_BUS_ERROR \ + ) ) + +#define ENABLE_ALL_I2C0_INTERRUPTS ((__u32)I2C_IRQ_SRC_ALL & \ + ( \ + (__u32) I2C0_IRQ_SRC_TRANSMIT_FIFO_NEARLY_EMPTY | \ + (__u32) I2C0_IRQ_SRC_TRANSMIT_FIFO_OVERRUN | \ + (__u32) I2C0_IRQ_SRC_RECEIVE_FIFO_NEARLY_FULL | \ + (__u32) I2C0_IRQ_SRC_RECEIVE_FIFO_FULL | \ + (__u32) I2C0_IRQ_SRC_READ_FROM_SLAVE_REQUEST | \ + (__u32) I2C0_IRQ_SRC_WRITE_TO_SLAVE_REQUEST | \ + (__u32) I2C0_IRQ_SRC_MASTER_TRANSACTION_DONE | \ + (__u32) I2C0_IRQ_SRC_SLAVE_TRANSACTION_DONE | \ + (__u32) I2C0_IRQ_SRC_MASTER_ARBITRATION_LOST | \ + (__u32) I2C0_IRQ_SRC_BUS_ERROR \ + ) ) + +#define WRITE_FIELD(reg_name,mask,shift,value) \ + (reg_name = ((reg_name & ~mask) | (value << shift))) + +#define READ_FIELD(reg_name,mask,shift) ((reg_name & mask) >> shift ) + +/*####################################################################### + Defines used various operations +######################################################################### +*/ +#define I2C_ENDAD_COUNTER 50000 +#define I2C_INT_ENDED_COUNTER 5 +#define I2C_BTF_COUNTER 5 +#define I2C_BTF_COUNTER_POLLING 50000 +#define I2C_FIFO_FLUSH_COUNTER 500 +#define I2C_LOWER_SLAVE 127 +#define I2C_UPPER_SLAVE 1024 +#define ENABLE_IRQSRC(regs, irq_id) writel(readl(regs + I2C_REG_OFFSET_IMSCR)|(I2C_IRQ_SRC_ALL & irq_id),regs + I2C_REG_OFFSET_IMSCR) +#define DISABLE_IRQSRC(regs, irq_id) writel(readl(regs + I2C_REG_OFFSET_IMSCR) & ~(I2C_IRQ_SRC_ALL & irq_id),regs + I2C_REG_OFFSET_IMSCR) + +int loop_till_clear(void *reg_offset, int mask, int shift, int end_counter) +{ + int loop = 0; + while ((I2C_READ_FIELD((reg_offset), (mask), (shift))) + && (loop < end_counter)) + loop++; + + if (loop >= end_counter) + return 1; + else + return 0; +} + +int loop_till_set(void *reg_offset, int mask, int shift, int end_counter) +{ + int loop = 0; + while (!(I2C_READ_FIELD((reg_offset), (mask), (shift))) + && (loop < end_counter)) + loop++; + + if (loop >= end_counter) + return 1; + else + return 0; +} + +int verify_parameters(struct nomadik_i2c_private *priv) +{ + + if ((I2C_TRANSFER_MODE_POLLING != priv->config.index_transfer_mode + && I2C_TRANSFER_MODE_POLLING == priv->config.data_transfer_mode) + || (I2C_TRANSFER_MODE_DMA == priv->config.index_transfer_mode) + ) + return -EINVAL; + + if (priv->config.slave_address > 1023 + || (priv->config.slave_address < 256 + && !(priv->config.slave_address == 0 + || priv->config.slave_address == 0x4))) + if ((priv->config.slave_address < 16) + || (priv->config.slave_address > 239)) + return -EINVAL; + + if ((I2C_BUS_MASTER_MODE != priv->config.bus_control_mode) + && (I2C_NO_INDEX != priv->config.index_format)) + return -EINVAL; + +#if (__STN_8815 != 10) + if (I2C_READ_FIELD + ((priv->regs + I2C_REG_OFFSET_SR), I2C_SR_STATUS, + I2C_SR_SHIFT_STATUS) + ) + return -EBUSY; +#endif + + return 0; + +} + +void reset_i2c(struct nomadik_i2c_private *priv) +{ + I2C_WRITE_REG((priv->regs + I2C_REG_OFFSET_CR), I2C_CLEAR); + I2C_WRITE_REG((priv->regs + I2C_REG_OFFSET_SCR), I2C_CLEAR); + I2C_WRITE_REG((priv->regs + I2C_REG_OFFSET_HSMCR), I2C_CLEAR); + I2C_WRITE_REG((priv->regs + I2C_REG_OFFSET_MCR), I2C_CLEAR); + I2C_WRITE_REG((priv->regs + I2C_REG_OFFSET_TFTR), I2C_CLEAR); + I2C_WRITE_REG((priv->regs + I2C_REG_OFFSET_RFTR), I2C_CLEAR); + I2C_WRITE_REG((priv->regs + I2C_REG_OFFSET_DMAR), I2C_CLEAR); + I2C_WRITE_REG((priv->regs + I2C_REG_OFFSET_ICR), 0x31F0008); + I2C_WRITE_REG((priv->regs + I2C_REG_OFFSET_IMSCR), I2C_CLEAR); + + I2C_SET_BIT((priv->regs + I2C_REG_OFFSET_CR), I2C_CR_FTX); + I2C_SET_BIT((priv->regs + I2C_REG_OFFSET_CR), I2C_CR_FRX); + + memset(&priv->config, 0, sizeof(priv->config)); + priv->config.operation = I2C_NO_OPERATION; + priv->config.i2c_transmit_interrupt_threshold = 1; + priv->config.i2c_receive_interrupt_threshold = 1; + priv->config.active_event.type = I2C_NO_EVENT; +} + +int setup_i2c_controller(struct nomadik_i2c_private *priv) +{ + + priv->config.mode = I2C_FREQ_MODE_STANDARD; + I2C_CLR_BIT((priv->regs + I2C_REG_OFFSET_CR), I2C_CR_PE); + + priv->config.enabled = NOMADIK_FALSE; + + writel(I2C_CLEAR, (priv->regs + I2C_REG_OFFSET_CR)); + writel(I2C_CLEAR, (priv->regs + I2C_REG_OFFSET_SCR)); + writel(I2C_CLEAR, (priv->regs + I2C_REG_OFFSET_HSMCR)); + writel(I2C_CLEAR, (priv->regs + I2C_REG_OFFSET_TFTR)); + writel(I2C_CLEAR, (priv->regs + I2C_REG_OFFSET_RFTR)); + writel(I2C_CLEAR, (priv->regs + I2C_REG_OFFSET_DMAR)); + + writel(DISABLE_ALL_INTERRUPTS(priv->id), + priv->regs + I2C_REG_OFFSET_IMSCR); + + writel(DEFAULT_CR_REG, (priv->regs + I2C_REG_OFFSET_CR)); + writel(DEFAULT_SCR_REG(priv->config.own_address), + (priv->regs + I2C_REG_OFFSET_SCR)); + writel(DEFAULT_BRCNT_REG, (priv->regs + I2C_REG_OFFSET_BRCR)); + writel(priv->config.i2c_transmit_interrupt_threshold, + (priv->regs + I2C_REG_OFFSET_TFTR)); + writel(priv->config.i2c_receive_interrupt_threshold, + (priv->regs + I2C_REG_OFFSET_RFTR)); + + if (I2C_TRANSFER_MODE_POLLING == priv->config.index_transfer_mode) + writel(DISABLE_ALL_INTERRUPTS(priv->id), + priv->regs + I2C_REG_OFFSET_IMSCR); + + I2C_SET_BIT((priv->regs + I2C_REG_OFFSET_CR), I2C_CR_PE); + priv->config.enabled = NOMADIK_TRUE; + + /* mdelay(1); */ /* NM */ + udelay(400); /* NM */ + return 0; + +} + +int enable_i2c(struct nomadik_i2c_private *priv) +{ + I2C_SET_BIT((priv->regs + I2C_REG_OFFSET_CR), I2C_CR_PE); + priv->config.enabled = NOMADIK_TRUE; + return 0; + +} + +void disable_i2c(struct nomadik_i2c_private *priv) +{ + I2C_CLR_BIT((priv->regs + I2C_REG_OFFSET_CR), I2C_CR_PE); + priv->config.enabled = NOMADIK_FALSE; +} + +void i2c_abort(struct nomadik_i2c_private *priv) +{ + writel(DISABLE_ALL_INTERRUPTS(priv->id), + (priv->regs + I2C_REG_OFFSET_IMSCR)); + + I2C_CLR_BIT((priv->regs + I2C_REG_OFFSET_CR), I2C_CR_PE); + + I2C_SET_BIT((priv->regs + I2C_REG_OFFSET_CR), I2C_CR_PE); + + priv->config.operation = I2C_NO_OPERATION; + +} + +int slave_index_receive(struct nomadik_i2c_private *priv) +{ + __u32 loop_counter = 0; + + if (I2C_WRITE == priv->config.operation) { + /* SLAVE TRANSMITTER */ + loop_counter = 0; + if (loop_till_set + ((priv->regs + I2C_REG_OFFSET_RISR), I2C_INT_RFSR, + I2C_INT_SHIFT_RFSR, I2C_ENDAD_COUNTER)) { + i2c_abort(priv); + return -EINVAL; + } + I2C_SET_BIT((priv->regs + I2C_REG_OFFSET_ICR), I2C_INT_RFSR); + + I2C_SET_BIT((priv->regs + I2C_REG_OFFSET_CR), I2C_CR_FTX); + loop_counter = 0; + if (loop_till_clear + ((priv->regs + I2C_REG_OFFSET_CR), I2C_CR_FTX, + I2C_CR_SHIFT_FTX, I2C_FIFO_FLUSH_COUNTER)) { + return -EIO; + } + priv->config.status = I2C_STATUS_SLAVE_TRANSMITTER_MODE; + priv->config.active_event.type = + I2C_READ_FROM_SLAVE_REQUEST_EVENT; + priv->config.current_bus_config = + I2C_CURRENT_BUS_SLAVE_TRANSMITTER; + + } else { + /* SLAVE RECEIVER */ + loop_counter = 0; + if (loop_till_set + ((priv->regs + I2C_REG_OFFSET_CR), I2C_INT_WTSR, + I2C_INT_SHIFT_WTSR, I2C_ENDAD_COUNTER)) { + i2c_abort(priv); + return -EIO; + } + + I2C_SET_BIT((priv->regs + I2C_REG_OFFSET_ICR), I2C_INT_WTSR); + + priv->config.status = I2C_STATUS_SLAVE_TRANSMITTER_MODE; + priv->config.active_event.type = + I2C_WRITE_TO_SLAVE_REQUEST_EVENT; + priv->config.current_bus_config = + I2C_CURRENT_BUS_SLAVE_RECEIVER; + + } + + priv->config.status = I2C_READ == priv->config.operation ? + I2C_STATUS_SLAVE_RECEIVER_MODE : I2C_STATUS_SLAVE_TRANSMITTER_MODE; + return 0; +} + +int transmit_data_polling(struct nomadik_i2c_private *priv) +{ + __u32 loop_counter = 0; + volatile __u8 *p_data; + + p_data = priv->config.databuffer; + if (I2C_BUS_SLAVE_MODE == priv->config.bus_control_mode) { + /* Slave tranmitter */ + while (priv->config.count_data != 0) { + loop_counter = 0; + if (loop_till_clear + ((priv->regs + I2C_REG_OFFSET_RISR), I2C_INT_TXFF, + I2C_INT_SHIFT_TXFF, I2C_ENDAD_COUNTER)) { + i2c_abort(priv); + return -EIO; + } + + writeb(*p_data, (priv->regs + I2C_REG_OFFSET_TFR)); + + p_data++; + priv->config.transfer_data++; + priv->config.count_data--; + priv->config.active_event.type = I2C_DATA_TX_EVENT; + } + + loop_counter = 0; + if (loop_till_set + ((priv->regs + I2C_REG_OFFSET_RISR), I2C_INT_STD, + I2C_INT_SHIFT_STD, I2C_ENDAD_COUNTER)) { + i2c_abort(priv); + return -EIO; + } + I2C_SET_BIT((priv->regs + I2C_REG_OFFSET_ICR), I2C_INT_STD); + + priv->config.active_event.type = I2C_TRANSFER_OK_EVENT; + return 0; + } else { + while (priv->config.count_data != 0) { + loop_counter = 0; + if (loop_till_clear + ((priv->regs + I2C_REG_OFFSET_RISR), I2C_INT_TXFF, + I2C_INT_SHIFT_TXFF, I2C_ENDAD_COUNTER)) { + i2c_abort(priv); + return -EIO; + } + + writeb(*p_data, (priv->regs + I2C_REG_OFFSET_TFR)); + + priv->config.transfer_data++; + priv->config.count_data--; + p_data++; + priv->config.active_event.type = I2C_DATA_TX_EVENT; + } + + loop_counter = 0; + if (loop_till_set + ((priv->regs + I2C_REG_OFFSET_RISR), I2C_INT_MTD, + I2C_INT_SHIFT_MTD, I2C_ENDAD_COUNTER)) { + i2c_abort(priv); + return -EIO; + } + + I2C_SET_BIT((priv->regs + I2C_REG_OFFSET_ICR), I2C_INT_MTD); + + priv->config.active_event.type = I2C_TRANSFER_OK_EVENT; + + priv->config.operation = I2C_NO_OPERATION; + return 0; + } + +} + +int receive_data_polling(struct nomadik_i2c_private *priv) +{ + __u32 loop_counter = 0; + volatile __u8 *p_data; + + p_data = priv->config.databuffer; + if (I2C_BUS_SLAVE_MODE == priv->config.bus_control_mode) { + /* Slave Receiver */ + while (priv->config.count_data != 0) { + loop_counter = 0; + if (loop_till_clear + ((priv->regs + I2C_REG_OFFSET_RISR), I2C_INT_RXFE, + I2C_INT_SHIFT_RXFE, I2C_ENDAD_COUNTER)) { + i2c_abort(priv); + return -EIO; + } + + *p_data = readb(priv->regs + I2C_REG_OFFSET_RFR); + p_data++; + + priv->config.transfer_data++; + priv->config.count_data--; + priv->config.active_event.type = I2C_DATA_RX_EVENT; + } + + loop_counter = 0; + if (loop_till_set + ((priv->regs + I2C_REG_OFFSET_RISR), I2C_INT_STD, + I2C_INT_SHIFT_STD, I2C_ENDAD_COUNTER)) { + i2c_abort(priv); + return -EIO; + } + + I2C_SET_BIT((priv->regs + I2C_REG_OFFSET_ICR), I2C_INT_STD); + priv->config.active_event.type = I2C_TRANSFER_OK_EVENT; + priv->config.operation = I2C_NO_OPERATION; + + return 0; + } else { + /* Master Receiver */ + while (priv->config.count_data != 0) { + loop_counter = 0; + if (loop_till_clear + ((priv->regs + I2C_REG_OFFSET_RISR), I2C_INT_RXFE, + I2C_INT_SHIFT_RXFE, I2C_ENDAD_COUNTER)) { + i2c_abort(priv); + return -EIO; + } + + *p_data = readb(priv->regs + I2C_REG_OFFSET_RFR); + p_data++; + + priv->config.transfer_data++; + priv->config.count_data--; + priv->config.active_event.type = I2C_DATA_RX_EVENT; + } + + loop_counter = 0; + if (loop_till_set + ((priv->regs + I2C_REG_OFFSET_RISR), I2C_INT_MTD, + I2C_INT_SHIFT_MTD, I2C_ENDAD_COUNTER)) { + i2c_abort(priv); + return -EIO; + } + + I2C_SET_BIT((priv->regs + I2C_REG_OFFSET_ICR), I2C_INT_MTD); + + priv->config.active_event.type = I2C_TRANSFER_OK_EVENT; + priv->config.operation = I2C_NO_OPERATION; + + } + return 0; + +} + +int master_index_transmit(struct nomadik_i2c_private *priv) +{ + volatile __u32 mcr = 0; + __u32 loop_counter = 0; + + loop_counter = 0; + if (loop_till_clear((priv->regs + I2C_REG_OFFSET_RISR), I2C_INT_TXFF, + I2C_INT_SHIFT_TXFF, I2C_ENDAD_COUNTER)) { + i2c_abort(priv); + return -EBUSY; + } + + switch (priv->config.index_format) { + case I2C_NO_INDEX: + return 0; + + case I2C_BYTE_INDEX: + + writeb((0xFF & priv->config.register_index), + (priv->regs + I2C_REG_OFFSET_TFR)); + + priv->config.active_event.type = I2C_INDEX_TX_EVENT; + priv->config.index_format = I2C_NO_INDEX; + + break; + + case I2C_HALF_WORD_LITTLE_ENDIAN: + writeb((0xFF & priv->config.register_index), + (priv->regs + I2C_REG_OFFSET_TFR)); + writeb((priv->config.register_index >> 8), + (priv->regs + I2C_REG_OFFSET_TFR)); + + priv->config.index_format = I2C_NO_INDEX; + priv->config.active_event.type = I2C_INDEX_TX_EVENT; + break; + + case I2C_HALF_WORD_BIG_ENDIAN: + + writeb((priv->config.register_index >> 8), + (priv->regs + I2C_REG_OFFSET_TFR)); + writeb((0xFF & priv->config.register_index), + (priv->regs + I2C_REG_OFFSET_TFR)); + + priv->config.index_format = I2C_NO_INDEX; + priv->config.active_event.type = I2C_INDEX_TX_EVENT; + break; + + default: + break; + } + + if (priv->config.operation == I2C_READ) { + loop_counter = 0; + if (loop_till_set + ((priv->regs + I2C_REG_OFFSET_RISR), I2C_INT_MTD, + I2C_INT_SHIFT_MTD, I2C_ENDAD_COUNTER)) { + i2c_abort(priv); + return -EBUSY; + } + + I2C_SET_BIT((priv->regs + I2C_REG_OFFSET_ICR), I2C_INT_MTD); + + NOMADIK_SET_BITS(mcr, I2C_MCR_OP); + + NOMADIK_SET_BITS(mcr, I2C_MCR_STOP); + + WRITE_FIELD(mcr, I2C_MCR_LENGTH, I2C_MCR_SHIFT_LENGTH, + priv->config.count_data); + + I2C_WRITE_FIELD((priv->regs + I2C_REG_OFFSET_MCR), + I2C_MCR_LENGTH_STOP_OP, + I2C_MCR_SHIFT_LENGTH_STOP_OP, mcr); + + } + + if (priv->config.operation == I2C_READ) + priv->config.status = I2C_STATUS_MASTER_RECEIVER_MODE; + else + priv->config.status = I2C_STATUS_MASTER_TRANSMITTER_MODE; + + return 0; + +} + +int write_i2c(struct nomadik_i2c_private *priv) { + volatile __u32 mcr = 0; + + writel(DISABLE_ALL_INTERRUPTS(priv->id), + priv->regs + I2C_REG_OFFSET_IMSCR); + + if (I2C_BUS_MASTER_MODE == priv->config.bus_control_mode) { + int count = 0; + mcr = DEFAULT_MCR_REG(priv->config.slave_address); + if (I2C_FREQ_MODE_HIGH_SPEED == priv->config.mode) + writel(priv->config.high_speed_master_code, + (priv->regs + I2C_REG_OFFSET_HSMCR)); + + count = + priv->config.count_data + (int)priv->config.index_format; + if (priv->config.index_format == I2C_HALF_WORD_BIG_ENDIAN) + count--; + + WRITE_FIELD(mcr, I2C_MCR_LENGTH, I2C_MCR_SHIFT_LENGTH, count); + writel(mcr, (priv->regs + I2C_REG_OFFSET_MCR)); + + } + + switch (priv->config.index_transfer_mode) { + int error_status = 0; + + case I2C_TRANSFER_MODE_POLLING: + /* + Index Transfer + */ + if (I2C_BUS_SLAVE_MODE == priv->config.bus_control_mode) { + error_status = slave_index_receive(priv); + if (error_status) { + return (error_status); + } + } else { + error_status = master_index_transmit(priv); + if (error_status) { + return (error_status); + } + } + + /* + Data Transfer + */ + switch (priv->config.data_transfer_mode) { + case I2C_TRANSFER_MODE_POLLING: + error_status = transmit_data_polling(priv); + if (error_status) { + return (error_status); + } + break; + + case I2C_TRANSFER_MODE_INTERRUPT: + switch (priv->id) { + case 0: + ENABLE_IRQSRC + (priv->regs, + ((__u32) I2C_IRQ_SRC_ALL & + ((__u32) + I2C0_IRQ_SRC_TRANSMIT_FIFO_NEARLY_EMPTY | + (__u32) + I2C0_IRQ_SRC_TRANSMIT_FIFO_OVERRUN | + (__u32) + I2C0_IRQ_SRC_RECEIVE_FIFO_NEARLY_FULL | + (__u32) I2C0_IRQ_SRC_RECEIVE_FIFO_FULL | + (__u32) + I2C0_IRQ_SRC_READ_FROM_SLAVE_REQUEST | + (__u32) + I2C0_IRQ_SRC_WRITE_TO_SLAVE_REQUEST | + (__u32) + I2C0_IRQ_SRC_MASTER_TRANSACTION_DONE | + (__u32) + I2C0_IRQ_SRC_SLAVE_TRANSACTION_DONE | + (__u32) + I2C0_IRQ_SRC_MASTER_ARBITRATION_LOST | + (__u32) I2C0_IRQ_SRC_BUS_ERROR)) + ); + + break; + + case 1: + ENABLE_IRQSRC + (priv->regs, + ((__u32) I2C_IRQ_SRC_ALL & + ((__u32) + I2C1_IRQ_SRC_TRANSMIT_FIFO_NEARLY_EMPTY | + (__u32) + I2C1_IRQ_SRC_TRANSMIT_FIFO_OVERRUN | + (__u32) + I2C1_IRQ_SRC_RECEIVE_FIFO_NEARLY_FULL | + (__u32) I2C1_IRQ_SRC_RECEIVE_FIFO_FULL | + (__u32) + I2C1_IRQ_SRC_READ_FROM_SLAVE_REQUEST | + (__u32) + I2C1_IRQ_SRC_WRITE_TO_SLAVE_REQUEST | + (__u32) + I2C1_IRQ_SRC_MASTER_TRANSACTION_DONE | + (__u32) + I2C1_IRQ_SRC_SLAVE_TRANSACTION_DONE | + (__u32) + I2C1_IRQ_SRC_MASTER_ARBITRATION_LOST | + (__u32) I2C1_IRQ_SRC_BUS_ERROR)) + ); + + break; + + default: + break; + } + break; + + case I2C_TRANSFER_MODE_DMA: + I2C_SET_BIT((priv->regs + I2C_REG_OFFSET_CR), + I2C_CR_DMA_TX_EN); + writel(readl((priv->regs + I2C_REG_OFFSET_CR)) | + I2C_CR_DMA_TX_EN, + (priv->regs + I2C_REG_OFFSET_CR)); + priv->config.operation = I2C_NO_OPERATION; + break; + + default: + break; + } + break; + + case I2C_TRANSFER_MODE_INTERRUPT: + switch (priv->id) { + case 0: + if (I2C_BUS_SLAVE_MODE == priv->config.bus_control_mode) { + ENABLE_IRQSRC + (priv->regs, + ((__u32) I2C_IRQ_SRC_ALL & + ((__u32) + I2C0_IRQ_SRC_TRANSMIT_FIFO_OVERRUN | + (__u32) + I2C0_IRQ_SRC_RECEIVE_FIFO_NEARLY_FULL | + (__u32) I2C0_IRQ_SRC_RECEIVE_FIFO_FULL | + (__u32) + I2C0_IRQ_SRC_READ_FROM_SLAVE_REQUEST | + (__u32) + I2C0_IRQ_SRC_READ_FROM_SLAVE_EMPTY | + (__u32) + I2C0_IRQ_SRC_WRITE_TO_SLAVE_REQUEST | + (__u32) + I2C0_IRQ_SRC_MASTER_TRANSACTION_DONE | + (__u32) + I2C0_IRQ_SRC_SLAVE_TRANSACTION_DONE | + (__u32) + I2C0_IRQ_SRC_MASTER_ARBITRATION_LOST | + (__u32) I2C0_IRQ_SRC_BUS_ERROR)) + ); + } else { + ENABLE_IRQSRC + (priv->regs, + ((__u32) I2C_IRQ_SRC_ALL & + ((__u32) + I2C0_IRQ_SRC_TRANSMIT_FIFO_NEARLY_EMPTY | + (__u32) + I2C0_IRQ_SRC_TRANSMIT_FIFO_OVERRUN | + (__u32) + I2C0_IRQ_SRC_RECEIVE_FIFO_NEARLY_FULL | + (__u32) I2C0_IRQ_SRC_RECEIVE_FIFO_FULL | + (__u32) + I2C0_IRQ_SRC_READ_FROM_SLAVE_REQUEST | + (__u32) + I2C0_IRQ_SRC_READ_FROM_SLAVE_EMPTY | + (__u32) + I2C0_IRQ_SRC_WRITE_TO_SLAVE_REQUEST | + (__u32) + I2C0_IRQ_SRC_MASTER_TRANSACTION_DONE | + (__u32) + I2C0_IRQ_SRC_SLAVE_TRANSACTION_DONE | + (__u32) + I2C0_IRQ_SRC_MASTER_ARBITRATION_LOST | + (__u32) I2C0_IRQ_SRC_BUS_ERROR)) + ); + } + break; + + case 1: + if (I2C_BUS_SLAVE_MODE == priv->config.bus_control_mode) { + ENABLE_IRQSRC + (priv->regs, + ((__u32) I2C_IRQ_SRC_ALL & + ((__u32) + I2C1_IRQ_SRC_TRANSMIT_FIFO_OVERRUN | + (__u32) + I2C1_IRQ_SRC_RECEIVE_FIFO_NEARLY_FULL | + (__u32) I2C1_IRQ_SRC_RECEIVE_FIFO_FULL | + (__u32) + I2C1_IRQ_SRC_READ_FROM_SLAVE_REQUEST | + (__u32) + I2C1_IRQ_SRC_READ_FROM_SLAVE_EMPTY | + (__u32) + I2C1_IRQ_SRC_WRITE_TO_SLAVE_REQUEST | + (__u32) + I2C1_IRQ_SRC_MASTER_TRANSACTION_DONE | + (__u32) + I2C1_IRQ_SRC_SLAVE_TRANSACTION_DONE | + (__u32) + I2C1_IRQ_SRC_MASTER_ARBITRATION_LOST | + (__u32) I2C1_IRQ_SRC_BUS_ERROR)) + ); + } else { + ENABLE_IRQSRC + (priv->regs, + ((__u32) I2C_IRQ_SRC_ALL & + ((__u32) + I2C1_IRQ_SRC_TRANSMIT_FIFO_NEARLY_EMPTY | + (__u32) + I2C1_IRQ_SRC_TRANSMIT_FIFO_OVERRUN | + (__u32) + I2C1_IRQ_SRC_RECEIVE_FIFO_NEARLY_FULL | + (__u32) I2C1_IRQ_SRC_RECEIVE_FIFO_FULL | + (__u32) + I2C1_IRQ_SRC_READ_FROM_SLAVE_REQUEST | + (__u32) + I2C1_IRQ_SRC_READ_FROM_SLAVE_EMPTY | + (__u32) + I2C1_IRQ_SRC_WRITE_TO_SLAVE_REQUEST | + (__u32) + I2C1_IRQ_SRC_MASTER_TRANSACTION_DONE | + (__u32) + I2C1_IRQ_SRC_SLAVE_TRANSACTION_DONE | + (__u32) + I2C1_IRQ_SRC_MASTER_ARBITRATION_LOST | + (__u32) I2C1_IRQ_SRC_BUS_ERROR)) + ); + } + break; + + default: + break; + } + break; + + case I2C_TRANSFER_MODE_DMA: + default: + return -EINVAL; + } + + return 0; +} + +int read_i2c(struct nomadik_i2c_private *priv) { + volatile __u32 mcr = 0; + + writel(DISABLE_ALL_INTERRUPTS(priv->id), + priv->regs + I2C_REG_OFFSET_IMSCR); + + if (I2C_BUS_MASTER_MODE == priv->config.bus_control_mode) { + + mcr = DEFAULT_MCR_REG(priv->config.slave_address); + if (I2C_FREQ_MODE_HIGH_SPEED == priv->config.mode) + writel(priv->config.high_speed_master_code, + priv->regs + I2C_REG_OFFSET_HSMCR); + + if ((priv->config.slave_address < 1024 + && priv->config.slave_address > 127) + && (I2C_NO_INDEX == priv->config.index_format) + ) { + NOMADIK_CLEAR_BITS(mcr, I2C_MCR_OP); + + WRITE_FIELD(mcr, I2C_MCR_LENGTH, I2C_MCR_SHIFT_LENGTH, + 0); + + NOMADIK_CLEAR_BITS(mcr, I2C_MCR_STOP); + + writel(mcr, priv->regs + I2C_REG_OFFSET_MCR); + + I2C_SET_BIT(priv->regs + I2C_REG_OFFSET_CR, I2C_CR_PE); + } else { + if (I2C_NO_INDEX != priv->config.index_format) { + NOMADIK_CLEAR_BITS(mcr, I2C_MCR_OP); + } else { + NOMADIK_SET_BITS(mcr, I2C_MCR_OP); + } + switch (priv->config.index_format) { + case I2C_NO_INDEX: + WRITE_FIELD(mcr, I2C_MCR_LENGTH, + I2C_MCR_SHIFT_LENGTH, + priv->config.count_data); + + NOMADIK_SET_BITS(mcr, I2C_MCR_STOP); + break; + + case I2C_BYTE_INDEX: + WRITE_FIELD(mcr, I2C_MCR_LENGTH, + I2C_MCR_SHIFT_LENGTH, 1); + + NOMADIK_CLEAR_BITS(mcr, I2C_MCR_STOP); + break; + + case I2C_HALF_WORD_LITTLE_ENDIAN: + case I2C_HALF_WORD_BIG_ENDIAN: + WRITE_FIELD(mcr, I2C_MCR_LENGTH, + I2C_MCR_SHIFT_LENGTH, 2); + + NOMADIK_CLEAR_BITS(mcr, I2C_MCR_STOP); + break; + + default: + break; + } + + writel(mcr, (priv->regs + I2C_REG_OFFSET_MCR)); + + } + } + + switch (priv->config.index_transfer_mode) { + int error_status = 0; + case I2C_TRANSFER_MODE_POLLING: + /* + Index Transfer + */ + if (I2C_BUS_SLAVE_MODE == priv->config.bus_control_mode) { + error_status = slave_index_receive(priv); + if (error_status) { + return (error_status); + } + } else { + error_status = master_index_transmit(priv); + if (error_status) { + return (error_status); + } + } + + /* + Data Transfer + */ + switch (priv->config.data_transfer_mode) { + case I2C_TRANSFER_MODE_POLLING: + error_status = receive_data_polling(priv); + if (error_status) { + return (error_status); + } + break; + + case I2C_TRANSFER_MODE_INTERRUPT: + switch (priv->id) { + case 0: + ENABLE_IRQSRC + (priv->regs, + (((__u32) + I2C0_IRQ_SRC_RECEIVE_FIFO_NEARLY_FULL | + (__u32) I2C0_IRQ_SRC_RECEIVE_FIFO_FULL | + (__u32) + I2C0_IRQ_SRC_READ_FROM_SLAVE_REQUEST | + (__u32) + I2C0_IRQ_SRC_READ_FROM_SLAVE_EMPTY | + (__u32) + I2C0_IRQ_SRC_WRITE_TO_SLAVE_REQUEST | + (__u32) + I2C0_IRQ_SRC_MASTER_TRANSACTION_DONE | + (__u32) + I2C0_IRQ_SRC_SLAVE_TRANSACTION_DONE | + (__u32) + I2C0_IRQ_SRC_MASTER_ARBITRATION_LOST | + (__u32) I2C0_IRQ_SRC_BUS_ERROR)) + ); + + break; + + case 1: + ENABLE_IRQSRC + (priv->regs, + (((__u32) + I2C1_IRQ_SRC_RECEIVE_FIFO_NEARLY_FULL | + (__u32) I2C1_IRQ_SRC_RECEIVE_FIFO_FULL | + (__u32) + I2C1_IRQ_SRC_READ_FROM_SLAVE_REQUEST | + (__u32) + I2C1_IRQ_SRC_READ_FROM_SLAVE_EMPTY | + (__u32) + I2C1_IRQ_SRC_WRITE_TO_SLAVE_REQUEST | + (__u32) + I2C1_IRQ_SRC_MASTER_TRANSACTION_DONE | + (__u32) + I2C1_IRQ_SRC_SLAVE_TRANSACTION_DONE | + (__u32) + I2C1_IRQ_SRC_MASTER_ARBITRATION_LOST | + (__u32) I2C1_IRQ_SRC_BUS_ERROR)) + ); + + break; + + default: + break; + } + break; + + case I2C_TRANSFER_MODE_DMA: + I2C_SET_BIT(priv->regs + I2C_REG_OFFSET_CR, + I2C_CR_DMA_RX_EN); + priv->config.operation = I2C_NO_OPERATION; + break; + + default: + break; + } + break; + + case I2C_TRANSFER_MODE_INTERRUPT: + switch (priv->id) { + case 0: + if (priv->config.index_format > I2C_NO_INDEX) { + ENABLE_IRQSRC + (priv->regs, + ((__u32) + I2C0_IRQ_SRC_TRANSMIT_FIFO_NEARLY_EMPTY | + (__u32) I2C0_IRQ_SRC_TRANSMIT_FIFO_OVERRUN + | (__u32) + I2C0_IRQ_SRC_RECEIVE_FIFO_NEARLY_FULL | + (__u32) I2C0_IRQ_SRC_RECEIVE_FIFO_FULL | + (__u32) + I2C0_IRQ_SRC_READ_FROM_SLAVE_REQUEST | + (__u32) I2C0_IRQ_SRC_READ_FROM_SLAVE_EMPTY + | (__u32) + I2C0_IRQ_SRC_WRITE_TO_SLAVE_REQUEST | + (__u32) + I2C0_IRQ_SRC_MASTER_TRANSACTION_DONE | + (__u32) + I2C0_IRQ_SRC_SLAVE_TRANSACTION_DONE | + (__u32) + I2C0_IRQ_SRC_MASTER_ARBITRATION_LOST | + (__u32) I2C0_IRQ_SRC_BUS_ERROR) + ); + } else { + ENABLE_IRQSRC + (priv->regs, + ((__u32) + I2C0_IRQ_SRC_RECEIVE_FIFO_NEARLY_FULL | + (__u32) I2C0_IRQ_SRC_RECEIVE_FIFO_FULL | + (__u32) + I2C0_IRQ_SRC_READ_FROM_SLAVE_REQUEST | + (__u32) I2C0_IRQ_SRC_READ_FROM_SLAVE_EMPTY + | (__u32) + I2C0_IRQ_SRC_WRITE_TO_SLAVE_REQUEST | + (__u32) + I2C0_IRQ_SRC_MASTER_TRANSACTION_DONE | + (__u32) + I2C0_IRQ_SRC_SLAVE_TRANSACTION_DONE | + (__u32) + I2C0_IRQ_SRC_MASTER_ARBITRATION_LOST | + (__u32) I2C0_IRQ_SRC_BUS_ERROR) + ); + } + break; + + case 1: + if (priv->config.index_format > I2C_NO_INDEX) { + ENABLE_IRQSRC + (priv->regs, + ((__u32) + I2C1_IRQ_SRC_TRANSMIT_FIFO_NEARLY_EMPTY | + (__u32) I2C1_IRQ_SRC_TRANSMIT_FIFO_OVERRUN + | (__u32) + I2C1_IRQ_SRC_RECEIVE_FIFO_NEARLY_FULL | + (__u32) I2C1_IRQ_SRC_RECEIVE_FIFO_FULL | + (__u32) + I2C1_IRQ_SRC_READ_FROM_SLAVE_REQUEST | + (__u32) I2C1_IRQ_SRC_READ_FROM_SLAVE_EMPTY + | (__u32) + I2C1_IRQ_SRC_WRITE_TO_SLAVE_REQUEST | + (__u32) + I2C1_IRQ_SRC_MASTER_TRANSACTION_DONE | + (__u32) + I2C1_IRQ_SRC_SLAVE_TRANSACTION_DONE | + (__u32) + I2C1_IRQ_SRC_MASTER_ARBITRATION_LOST | + (__u32) I2C1_IRQ_SRC_BUS_ERROR) + ); + } else { + ENABLE_IRQSRC + (priv->regs, + ((__u32) + I2C1_IRQ_SRC_RECEIVE_FIFO_NEARLY_FULL | + (__u32) I2C1_IRQ_SRC_RECEIVE_FIFO_FULL | + (__u32) + I2C1_IRQ_SRC_READ_FROM_SLAVE_REQUEST | + (__u32) I2C1_IRQ_SRC_READ_FROM_SLAVE_EMPTY + | (__u32) + I2C1_IRQ_SRC_WRITE_TO_SLAVE_REQUEST | + (__u32) + I2C1_IRQ_SRC_MASTER_TRANSACTION_DONE | + (__u32) + I2C1_IRQ_SRC_SLAVE_TRANSACTION_DONE | + (__u32) + I2C1_IRQ_SRC_MASTER_ARBITRATION_LOST | + (__u32) I2C1_IRQ_SRC_BUS_ERROR) + ); + } + break; + + default: + break; + } + break; + + case I2C_TRANSFER_MODE_DMA: + default: + return -EINVAL; + } + + return 0; + +} + +void clear_irqsrc_i2c(struct nomadik_i2c_private *priv, int irq_id) +{ + writel(readl(priv->regs + I2C_REG_OFFSET_ICR) | + ((__u32) I2C_IRQ_SRC_ALL & (__u32) irq_id), + priv->regs + I2C_REG_OFFSET_ICR); +} + +int process_interrupt(struct nomadik_i2c_private *priv) +{ + volatile __u32 mcr = 0; + __u32 misr; + __u32 txthreshold, rxthreshold, maxthreshold, loop_counter; + volatile __u32 count; + int interrupt_source = 0; + + priv->config.active_event.type = I2C_NO_EVENT; + misr = readl(priv->regs + I2C_REG_OFFSET_MISR); + txthreshold = readl(priv->regs + I2C_REG_OFFSET_TFTR); + rxthreshold = readl(priv->regs + I2C_REG_OFFSET_RFTR); + maxthreshold = 15; + + if (NOMADIK_READ_BITS(misr, I2C_INT_BERR)) + interrupt_source = I2C_IT_BERR; + else if (NOMADIK_READ_BITS(misr, I2C_INT_MAL)) + interrupt_source = I2C_IT_MAL; + else if (NOMADIK_READ_BITS(misr, I2C_INT_STD)) + interrupt_source = I2C_IT_STD; + else if (NOMADIK_READ_BITS(misr, I2C_INT_MTD)) + interrupt_source = I2C_IT_MTD; + else if (NOMADIK_READ_BITS(misr, I2C_INT_WTSR)) + interrupt_source = I2C_IT_WTSR; + else if (NOMADIK_READ_BITS(misr, I2C_INT_RFSR)) + interrupt_source = I2C_IT_RFSR; + else if (NOMADIK_READ_BITS(misr, I2C_INT_RFSE)) + interrupt_source = I2C_IT_RFSE; + else if (NOMADIK_READ_BITS(misr, I2C_INT_TXFE)) + interrupt_source = I2C_IT_TXFE; + else if (NOMADIK_READ_BITS(misr, I2C_INT_TXFNE)) + interrupt_source = I2C_IT_TXFNE; + else if (NOMADIK_READ_BITS(misr, I2C_INT_TXFF)) + interrupt_source = I2C_IT_TXFF; + else if (NOMADIK_READ_BITS(misr, I2C_INT_TXFOVR)) + interrupt_source = I2C_IT_TXOVR; + else if (NOMADIK_READ_BITS(misr, I2C_INT_RXFE)) + interrupt_source = I2C_IT_RXFE; + else if (NOMADIK_READ_BITS(misr, I2C_INT_RXFNF)) + interrupt_source = I2C_IT_RXFNF; + else if (NOMADIK_READ_BITS(misr, I2C_INT_RXFF)) + interrupt_source = I2C_IT_RXFF; + + /* Processing interrupt */ + switch (interrupt_source) { + case I2C_IT_TXFE: + case I2C_IT_TXFNE: + + if ((I2C_BUS_MASTER_MODE == priv->config.bus_control_mode) + && (priv->config.index_format > I2C_NO_INDEX) + ) { + switch (priv->config.index_format) { + case I2C_BYTE_INDEX: + writel((0xFF & priv->config.register_index), + priv->regs + I2C_REG_OFFSET_TFR); + priv->config.index_format = I2C_NO_INDEX; + priv->config.active_event.type = + I2C_INDEX_TX_EVENT; + break; + + case I2C_HALF_WORD_LITTLE_ENDIAN: + writel((0xFF & priv->config.register_index), + priv->regs + I2C_REG_OFFSET_TFR); + writel((priv->config.register_index >> 8), + priv->regs + I2C_REG_OFFSET_TFR); + priv->config.index_format = I2C_NO_INDEX; + priv->config.active_event.type = + I2C_INDEX_TX_EVENT; + break; + + case I2C_HALF_WORD_BIG_ENDIAN: + writel((priv->config.register_index >> 8), + priv->regs + I2C_REG_OFFSET_TFR); + writel((0xFF & priv->config.register_index), + priv->regs + I2C_REG_OFFSET_TFR); + priv->config.index_format = I2C_NO_INDEX; + priv->config.active_event.type = + I2C_INDEX_TX_EVENT; + break; + + default: + break; + } + + if (I2C_READ == priv->config.operation) { + DISABLE_IRQSRC(priv->regs, priv->id ? + I2C1_IRQ_SRC_TRANSMIT_FIFO_NEARLY_EMPTY + : + I2C0_IRQ_SRC_TRANSMIT_FIFO_NEARLY_EMPTY); + } + + if (I2C_WRITE == priv->config.operation) { + if (NOMADIK_FALSE == + priv->config.multi_operation) { + writel(priv->config.data, + (priv->regs + + I2C_REG_OFFSET_TFR)); + priv->config.transfer_data++; + priv->config.count_data--; + } else { + for (count = + (maxthreshold - txthreshold - 2); + count > 0 + && (0 != priv->config.count_data); + count--) { + writel(*priv->config.databuffer, + (priv->regs + + I2C_REG_OFFSET_TFR)); + priv->config.databuffer++; + priv->config.count_data--; + priv->config.transfer_data++; + } + } + + if (0 == priv->config.count_data) { + DISABLE_IRQSRC(priv->regs, priv->id ? + I2C1_IRQ_SRC_TRANSMIT_FIFO_NEARLY_EMPTY + : + I2C0_IRQ_SRC_TRANSMIT_FIFO_NEARLY_EMPTY); + } + + priv->config.active_event.type = + I2C_DATA_TX_EVENT; + } + /* mdelay(1); */ /* NM */ + } else { + if (NOMADIK_FALSE == priv->config.multi_operation) { + writel(priv->config.data, + priv->regs + I2C_REG_OFFSET_TFR); + + priv->config.transfer_data++; + priv->config.count_data--; + } else { + for (count = (maxthreshold - txthreshold); + count > 0 + && (0 != priv->config.count_data); + count--) { + writel(*priv->config.databuffer, + priv->regs + I2C_REG_OFFSET_TFR); + + priv->config.databuffer++; + priv->config.count_data--; + priv->config.transfer_data++; + } + } + + if (0 == priv->config.count_data) { + DISABLE_IRQSRC(priv->regs, + priv-> + id ? + I2C1_IRQ_SRC_TRANSMIT_FIFO_NEARLY_EMPTY + : + I2C0_IRQ_SRC_TRANSMIT_FIFO_NEARLY_EMPTY); + } + + priv->config.active_event.type = I2C_DATA_TX_EVENT; + /* mdelay(1); */ /* NM */ + } + break; + + case I2C_IT_TXFF: + priv->config.active_event.type = I2C_TRANSMIT_FIFO_FULL_EVENT; + + break; + + case I2C_IT_TXOVR: + priv->config.active_event.type = + I2C_TRANSMIT_FIFO_OVERRUN_EVENT; + break; + + case I2C_IT_RXFE: + priv->config.active_event.type = I2C_RECEIVE_FIFO_EMPTY_EVENT; + + break; + + case I2C_IT_RXFNF: + for (count = rxthreshold; count > 0; count--) { + *priv->config.databuffer = + readl(priv->regs + I2C_REG_OFFSET_RFR); + priv->config.databuffer++; + } + + priv->config.count_data -= rxthreshold; + priv->config.transfer_data += rxthreshold; + + priv->config.active_event.type = + I2C_RECEIVE_FIFO_NEARLY_FULL_EVENT; + + break; + + case I2C_IT_RXFF: + for (count = maxthreshold; count > 0; count--) { + *priv->config.databuffer = + readl(priv->regs + I2C_REG_OFFSET_RFR); + priv->config.databuffer++; + } + + priv->config.count_data -= maxthreshold; + priv->config.transfer_data += maxthreshold; + + priv->config.active_event.type = I2C_RECEIVE_FIFO_FULL_EVENT; + break; + + case I2C_IT_RFSR: + /* Slave Transmitter */ + I2C_SET_BIT((priv->regs + I2C_REG_OFFSET_CR), I2C_CR_FTX); + + loop_counter = 0; + while + (I2C_READ_FIELD + ((priv->regs + I2C_REG_OFFSET_CR), I2C_CR_FTX, + I2C_CR_SHIFT_FTX) + && loop_counter < I2C_FIFO_FLUSH_COUNTER) { + loop_counter++; + }; + if (loop_counter >= I2C_FIFO_FLUSH_COUNTER) { + return -EIO; + } + + priv->config.status = I2C_STATUS_SLAVE_TRANSMITTER_MODE; + priv->config.current_bus_config = + I2C_CURRENT_BUS_SLAVE_TRANSMITTER; + I2C_SET_BIT((priv->regs + I2C_REG_OFFSET_ICR), I2C_INT_RFSR); + + if (I2C_TRANSFER_MODE_DMA == priv->config.data_transfer_mode) { + I2C_SET_BIT((priv->regs + I2C_REG_OFFSET_CR), + I2C_CR_DMA_TX_EN); + + if (priv->config.transmit_burst_length != 1) { + I2C_SET_BIT((priv->regs + I2C_REG_OFFSET_DMAR), + I2C_DMA_BURST_TX); + + I2C_WRITE_FIELD + ((priv->regs + I2C_REG_OFFSET_DMAR), + I2C_DMA_DBSIZE_TX, + I2C_DMA_SHIFT_DBSIZE_TX, + priv->config.transmit_burst_length); + } else { + I2C_CLR_BIT((priv->regs + I2C_REG_OFFSET_DMAR), + I2C_DMA_BURST_TX); + } + } + + priv->config.active_event.type = + I2C_READ_FROM_SLAVE_REQUEST_EVENT; + break; + + case I2C_IT_RFSE: + if (0 == priv->config.count_data) { + i2c_abort(priv); + return -EINVAL; + } else { + if (NOMADIK_FALSE == priv->config.multi_operation) { + if (1 == priv->config.count_data) { + writel(priv->config.data, + (priv->regs + + I2C_REG_OFFSET_TFR)); + + priv->config.transfer_data++; + priv->config.count_data--; + + if (0 == priv->id) { + DISABLE_IRQSRC(priv->regs, + I2C0_IRQ_SRC_READ_FROM_SLAVE_EMPTY); + } else { + DISABLE_IRQSRC(priv->regs, + I2C1_IRQ_SRC_READ_FROM_SLAVE_EMPTY); + } + } + } else { + for (count = txthreshold; + count > 0 + && (0 != priv->config.count_data); + count--) { + writel(*priv->config.databuffer, + (priv->regs + + I2C_REG_OFFSET_TFR)); + + priv->config.databuffer++; + priv->config.count_data--; + priv->config.transfer_data++; + } + } + } + + if (priv->config.count_data > 0) { + if (0 == priv->id) { + ENABLE_IRQSRC(priv->regs, + I2C0_IRQ_SRC_TRANSMIT_FIFO_NEARLY_EMPTY); + DISABLE_IRQSRC(priv->regs, + I2C0_IRQ_SRC_READ_FROM_SLAVE_EMPTY); + } else { + ENABLE_IRQSRC(priv->regs, + I2C1_IRQ_SRC_TRANSMIT_FIFO_NEARLY_EMPTY); + DISABLE_IRQSRC(priv->regs, + I2C1_IRQ_SRC_READ_FROM_SLAVE_EMPTY); + + } + } + + priv->config.active_event.type = + I2C_READ_FROM_SLAVE_EMPTY_EVENT; + break; + + case I2C_IT_WTSR: + priv->config.status = I2C_STATUS_SLAVE_RECEIVER_MODE; + priv->config.current_bus_config = + I2C_CURRENT_BUS_SLAVE_RECEIVER; + + I2C_SET_BIT((priv->regs + I2C_REG_OFFSET_ICR), I2C_INT_WTSR); + priv->config.active_event.type = + I2C_WRITE_TO_SLAVE_REQUEST_EVENT; + + break; + + case I2C_IT_MTD: + if (I2C_READ == priv->config.operation) { + while (!I2C_TEST_BIT + ((priv->regs + I2C_REG_OFFSET_RISR), + I2C_INT_RXFE)) { + if (0 == priv->config.count_data) { + break; + } + *priv->config.databuffer = + readl(priv->regs + I2C_REG_OFFSET_RFR); + + priv->config.databuffer++; + priv->config.count_data--; + priv->config.transfer_data++; + } + } + + I2C_SET_BIT((priv->regs + I2C_REG_OFFSET_ICR), I2C_INT_MTD); + + if ((priv->config.operation == I2C_READ) + && (priv->config.count_data > 0)) { + NOMADIK_SET_BITS(mcr, I2C_MCR_OP); + WRITE_FIELD(mcr, I2C_MCR_LENGTH, I2C_MCR_SHIFT_LENGTH, + priv->config.count_data); + NOMADIK_SET_BITS(mcr, I2C_MCR_STOP); + priv->config.index_format = I2C_NO_INDEX; + I2C_WRITE_FIELD((priv->regs + I2C_REG_OFFSET_MCR), + I2C_MCR_LENGTH_STOP_OP, + I2C_MCR_SHIFT_LENGTH_STOP_OP, mcr); + if (0 == priv->id) { + DISABLE_IRQSRC(priv->regs, + ((__u32) + I2C0_IRQ_SRC_TRANSMIT_FIFO_EMPTY + | (__u32) + I2C0_IRQ_SRC_TRANSMIT_FIFO_NEARLY_EMPTY + | (__u32) + I2C0_IRQ_SRC_TRANSMIT_FIFO_FULL + | (__u32) + I2C0_IRQ_SRC_TRANSMIT_FIFO_OVERRUN) + ); + } else { + DISABLE_IRQSRC(priv->regs, + ((__u32) + I2C1_IRQ_SRC_TRANSMIT_FIFO_EMPTY + | (__u32) + I2C1_IRQ_SRC_TRANSMIT_FIFO_NEARLY_EMPTY + | (__u32) + I2C1_IRQ_SRC_TRANSMIT_FIFO_FULL + | (__u32) + I2C1_IRQ_SRC_TRANSMIT_FIFO_OVERRUN) + ); + } + priv->config.active_event.type = I2C_DATA_RX_EVENT; + /* mdelay(1); */ /* NM */ + } else { + + priv->config.active_event.type = I2C_TRANSFER_OK_EVENT; + if (0 == priv->id) { + DISABLE_IRQSRC(priv->regs, + ((__u32) + I2C0_IRQ_SRC_TRANSMIT_FIFO_EMPTY + | (__u32) + I2C0_IRQ_SRC_TRANSMIT_FIFO_NEARLY_EMPTY + | (__u32) + I2C0_IRQ_SRC_TRANSMIT_FIFO_FULL + | (__u32) + I2C0_IRQ_SRC_TRANSMIT_FIFO_OVERRUN + | (__u32) + I2C0_IRQ_SRC_RECEIVE_FIFO_EMPTY + | (__u32) + I2C0_IRQ_SRC_RECEIVE_FIFO_NEARLY_FULL + | (__u32) + I2C0_IRQ_SRC_RECEIVE_FIFO_FULL) + ); + + clear_irqsrc_i2c(priv, I2C0_IRQ_SRC_ALL); + } else { + DISABLE_IRQSRC(priv->regs, + ((__u32) + I2C1_IRQ_SRC_TRANSMIT_FIFO_EMPTY + | (__u32) + I2C1_IRQ_SRC_TRANSMIT_FIFO_NEARLY_EMPTY + | (__u32) + I2C1_IRQ_SRC_TRANSMIT_FIFO_FULL + | (__u32) + I2C1_IRQ_SRC_TRANSMIT_FIFO_OVERRUN + | (__u32) + I2C1_IRQ_SRC_RECEIVE_FIFO_EMPTY + | (__u32) + I2C1_IRQ_SRC_RECEIVE_FIFO_NEARLY_FULL + | (__u32) + I2C1_IRQ_SRC_RECEIVE_FIFO_FULL) + ); + clear_irqsrc_i2c(priv, I2C1_IRQ_SRC_ALL); + + } + wake_up_interruptible(&priv->event_wq); + + /* mdelay(1); */ /* NM */ + } + break; + + case I2C_IT_STD: + if (I2C_READ == priv->config.operation) { + while (!I2C_TEST_BIT + (priv->regs + I2C_REG_OFFSET_RISR, + I2C_INT_RXFE)) { + *priv->config.databuffer = + readl(priv->regs + I2C_REG_OFFSET_RFR); + priv->config.databuffer++; + priv->config.count_data--; + priv->config.transfer_data++; + } + } + + I2C_SET_BIT(priv->regs + I2C_REG_OFFSET_ICR, I2C_INT_STD); + + if ((priv->config.own_address > 127) + && (I2C_WRITE == priv->config.operation) + && (NOMADIK_FALSE == priv->config.std)) { + priv->config.active_event.type = + I2C_SLAVE_TRANSACTION_DONE_EVENT; + priv->config.std = NOMADIK_TRUE; + } else { + priv->config.active_event.type = I2C_TRANSFER_OK_EVENT; + priv->config.std = NOMADIK_FALSE; + } + + if (0 == priv->id) { + DISABLE_IRQSRC(priv->regs, + ((__u32) I2C0_IRQ_SRC_TRANSMIT_FIFO_EMPTY + | (__u32) + I2C0_IRQ_SRC_TRANSMIT_FIFO_NEARLY_EMPTY + | (__u32) + I2C0_IRQ_SRC_TRANSMIT_FIFO_FULL | + (__u32) + I2C0_IRQ_SRC_TRANSMIT_FIFO_OVERRUN | + (__u32) I2C0_IRQ_SRC_RECEIVE_FIFO_EMPTY + | (__u32) + I2C0_IRQ_SRC_RECEIVE_FIFO_NEARLY_FULL | + (__u32) I2C0_IRQ_SRC_RECEIVE_FIFO_FULL) + ); + clear_irqsrc_i2c(priv, I2C0_IRQ_SRC_ALL); + } else { + DISABLE_IRQSRC(priv->regs, + ((__u32) I2C1_IRQ_SRC_TRANSMIT_FIFO_EMPTY + | (__u32) + I2C1_IRQ_SRC_TRANSMIT_FIFO_NEARLY_EMPTY + | (__u32) + I2C1_IRQ_SRC_TRANSMIT_FIFO_FULL | + (__u32) + I2C1_IRQ_SRC_TRANSMIT_FIFO_OVERRUN | + (__u32) I2C1_IRQ_SRC_RECEIVE_FIFO_EMPTY + | (__u32) + I2C1_IRQ_SRC_RECEIVE_FIFO_NEARLY_FULL | + (__u32) I2C1_IRQ_SRC_RECEIVE_FIFO_FULL) + ); + clear_irqsrc_i2c(priv, I2C1_IRQ_SRC_ALL); + } + break; + + case I2C_IT_MAL: + i2c_abort(priv); + + I2C_SET_BIT((priv->regs + I2C_REG_OFFSET_ICR), I2C_INT_MAL); + priv->config.active_event.type = + I2C_ARBITRATION_LOST_ERROR_EVENT; + + break; + + case I2C_IT_BERR: + if (3 == + I2C_READ_FIELD((priv->regs + I2C_REG_OFFSET_SR), + I2C_SR_STATUS, I2C_SR_SHIFT_STATUS)) { + i2c_abort(priv); + priv->config.active_event.type = I2C_BUS_ERROR_EVENT; + } else { + if (I2C_WRITE == priv->config.operation) { + priv->config.active_event.type = + I2C_DATA_TX_EVENT; + } else { + priv->config.active_event.type = + I2C_DATA_RX_EVENT; + } + } + + I2C_SET_BIT((priv->regs + I2C_REG_OFFSET_ICR), I2C_INT_BERR); + break; + + default: + break; + } + + priv->config.active_event.id = priv->id; + priv->config.active_event.transfer_data = priv->config.transfer_data; + if (I2C_TRANSFER_OK_EVENT == priv->config.active_event.type) { + priv->config.operation = I2C_NO_OPERATION; + } + + return 0; + +} + +/* stn8815 cut specific i2c does not need any delay in execution hence empty*/ +void stn_cut_mdelay(int dlytime) +{ +} + + --- linux-2.6.20.orig/drivers/i2c/chips/Kconfig +++ linux-2.6.20/drivers/i2c/chips/Kconfig @@ -123,6 +123,15 @@ config SENSORS_MAX6875 sequencer/supervisor if found at a compatible address. This driver can also be built as a module. If so, the module will be called max6875. +config CPLD_I2C + tristate "NOMADIK NDK15 CPLD" + depends on I2C && NOMADIK_NDK15 + default y + help + If you say yes here you get support for the cpld chip. + + This driver can also be built as a module. If so, the module + will be called epio-nomadik. endmenu --- linux-2.6.20.orig/drivers/i2c/chips/Makefile +++ linux-2.6.20/drivers/i2c/chips/Makefile @@ -10,10 +10,16 @@ obj-$(CONFIG_SENSORS_M41T00) += m41t00.o obj-$(CONFIG_SENSORS_PCA9539) += pca9539.o obj-$(CONFIG_SENSORS_PCF8574) += pcf8574.o obj-$(CONFIG_SENSORS_PCF8591) += pcf8591.o obj-$(CONFIG_ISP1301_OMAP) += isp1301_omap.o obj-$(CONFIG_TPS65010) += tps65010.o +obj-$(CONFIG_CPLD_I2C) += epio-nomadik.o ifeq ($(CONFIG_I2C_DEBUG_CHIP),y) EXTRA_CFLAGS += -DDEBUG endif +ifdef EPIO_DEBUG +EXTRA_CFLAGS += -DEPIO_DEBUG=$(EPIO_DEBUG) +endif + + --- /dev/null +++ linux-2.6.20/drivers/i2c/chips/epio-nomadik.c @@ -0,0 +1,195 @@ + +/* + * drivers/i2c/busses/chips/epio-nomadik.c + * + * Copyright (C) ST Microelectronics + * + * Nomadik EPIO driver. + * + * This driver provides an API for device drivers to utilize the NOMADIK EPIO + * EPIO is accesses theu i2c + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +/* + * epio constants + */ +#define EPIO_NAME "EPIO" +#ifndef EPIO_DEBUG +#define EPIO_DEBUG 0 +#endif + +#undef NMDK_DEBUG +#undef NMDK_DEBUG_PFX +#undef NMDK_DBG +#define NMDK_DEBUG EPIO_DEBUG /* enables/disables nmdk_dbg msgs */ +#define NMDK_DEBUG_PFX EPIO_NAME /* msg header represents this module */ +#define NMDK_DBG KERN_ERR /* message level */ + +/** + * Two byte Access mode - + * By default Single byte i2c access mode is enabled + * . i.e. the CPLD read/write is performed using single i2c operation + * + * You can enable Two bytes access mode for system debug purpose + * In this mode two i2c operations will be performed for each CPLD register + * read/write operation + * + * 2Byte Access mode can be enabled duirng make vmlinux by providing + * additional command line parameter "EPIO_DEBUG=0x80000000" + */ + +#define EPIO_2BYTE_I2C_ACCESS (EPIO_DEBUG & 0x80000000UL) ? (1) :(0) + +static spinlock_t epio_rd_lock = SPIN_LOCK_UNLOCKED; +static spinlock_t epio_wr_lock = SPIN_LOCK_UNLOCKED; + +/** + * nomadik_epio_read_i2c - reads specified CPLD register value + * + * Reads the present value of the specified core board register of CPLD + */ +u16 nomadik_epio_read_i2c(int reg) +{ + u16 data; + + nmdk_dbg2("%s reg %d",__FUNCTION__, reg); + //spin_lock(&epio_rd_lock); +#if EPIO_2BYTE_I2C_ACCESS >= 1 + nomadik_i2c_read_register(I2C_CPLD_CLIENT, (u8 *)&data, reg, 1); + nomadik_i2c_read_register(I2C_CPLD_CLIENT, ((u8 *)&data+1), reg+1, 1); +#else + nomadik_i2c_read_register(I2C_CPLD_CLIENT, (u8 *)&data, reg,2); +#endif + //spin_unlock(&epio_rd_lock); + return(data); +} + +/** + * nomadik_epio_write_i2c - writes specificed register of CPLD + * @expctrlval: value to be written + * + * Write the provided 16bit value into the specified core board register + * of CPLD + */ +int nomadik_epio_write_i2c(u16 data, int reg) +{ + int err; + + nmdk_dbg2("%s reg %d",__FUNCTION__, reg); + //spin_lock(&epio_wr_lock); +#if EPIO_2BYTE_I2C_ACCESS >= 1 + err = nomadik_i2c_write_register(I2C_CPLD_CLIENT, (u8 *)&data, reg, 1); + err |= nomadik_i2c_write_register(I2C_CPLD_CLIENT, ((u8 *)&data +1), reg+1, 1); +#else + err = nomadik_i2c_write_register(I2C_CPLD_CLIENT, (u8 *)&data, reg, 2); +#endif + //spin_unlock(&epio_wr_lock); + return(err); +} + +static int epio_drv_probe(struct platform_device *pdev) +{ + u16 cob_id; + int err; + void (*plat_init)(void); + + /*test write operation to check i2c functionality*/ + err = nomadik_epio_write_keypad(0); + if (err) { + nmdk_error("CPLD i2c write error(%d)", err); + return -1; + } + + /*platform specific initalization if any */ + plat_init = pdev->dev.platform_data; + if (plat_init) plat_init(); + + cob_id = nomadik_epio_read_cob_id(); + nmdk_info("module initialized Version(%d.%d.%d.%d)", + (cob_id & COB_REV_BITS) >> COB_REV_BITS_POS, + (cob_id & COB_REV_SUBBITS) >> COB_REV_SUBBITS_POS, + (cob_id & CPLD_REV_BITS) >> CPLD_REV_BITS_POS, + (cob_id & CPLD_REV_SUBBITS)); +#if EPIO_2BYTE_I2C_ACCESS >= 1 + nmdk_info("Two byte i2c access mode enabled"); +#endif + return 0; +} + +static int epio_drv_remove(struct platform_device *pdev) +{ + return 0; +} + +static struct platform_driver epio_driver = { + .probe = epio_drv_probe, + .remove = epio_drv_remove, + .driver = { + .name = "NOMADIK-EPIO", + }, +}; + +/** + * nomadik_epio_init - epio module init call. + */ +static int __init nomadik_epio_init(void) +{ + return platform_driver_register(&epio_driver); +} + +/* + * nomadik_epio_exit - epio module exit call. + */ +static void __exit nomadik_epio_exit(void) +{ + platform_driver_unregister(&epio_driver); +} + +module_init(nomadik_epio_init); +module_exit(nomadik_epio_exit); + +MODULE_AUTHOR("Prafulla WADASKAR "); +MODULE_DESCRIPTION("Nomadik Platform CPLD driver"); +MODULE_LICENSE("GPL v2"); + + --- linux-2.6.20.orig/drivers/input/input.c +++ linux-2.6.20/drivers/input/input.c @@ -926,10 +926,23 @@ struct input_dev *input_allocate_device( return dev; } EXPORT_SYMBOL(input_allocate_device); +#if defined(CONFIG_TOUCHSCREEN_NOMADIK_TS2003) +/* HASSAN */ +void init_ts_input_dev(struct input_dev *dev) +{ + dev->cdev.class = &input_class; + class_device_initialize(&dev->cdev); + mutex_init(&dev->mutex); + INIT_LIST_HEAD(&dev->h_list); + INIT_LIST_HEAD(&dev->node); +} +EXPORT_SYMBOL(init_ts_input_dev); /* HASSAN */ +#endif + /** * input_free_device - free memory occupied by input_dev structure * @dev: input device to free * * This function should only be used if input_register_device() --- linux-2.6.20.orig/drivers/input/keyboard/Kconfig +++ linux-2.6.20/drivers/input/keyboard/Kconfig @@ -212,6 +212,19 @@ config KEYBOARD_AAED2000 development board. To compile this driver as a module, choose M here: the module will be called aaed2000_kbd. +config KEYPAD_NOMADIK + tristate "Nomadik keypad support" + depends on ARCH_NOMADIK + default n + help + Say Y here if you want to use a keypad provided on Nomadik + Development Kit. + + If unsure, say N. + + To compile this driver as a module, choose M here: the + module will be called nomadik_kpd. + endif --- linux-2.6.20.orig/drivers/input/keyboard/Makefile +++ linux-2.6.20/drivers/input/keyboard/Makefile @@ -2,10 +2,14 @@ # Makefile for the input core drivers. # # Each configuration option enables a list of files. +ifdef KEYPAD_DEBUG +CFLAGS += -DKEYPAD_DEBUG=$(KEYPAD_DEBUG) +endif + obj-$(CONFIG_KEYBOARD_ATKBD) += atkbd.o obj-$(CONFIG_KEYBOARD_SUNKBD) += sunkbd.o obj-$(CONFIG_KEYBOARD_LKKBD) += lkkbd.o obj-$(CONFIG_KEYBOARD_XTKBD) += xtkbd.o obj-$(CONFIG_KEYBOARD_AMIGA) += amikbd.o @@ -16,6 +20,9 @@ obj-$(CONFIG_KEYBOARD_CORGI) += corgikb obj-$(CONFIG_KEYBOARD_SPITZ) += spitzkbd.o obj-$(CONFIG_KEYBOARD_HIL) += hil_kbd.o obj-$(CONFIG_KEYBOARD_HIL_OLD) += hilkbd.o obj-$(CONFIG_KEYBOARD_OMAP) += omap-keypad.o obj-$(CONFIG_KEYBOARD_AAED2000) += aaed2000_kbd.o +obj-$(CONFIG_KEYPAD_NOMADIK) += nmdkmod_kpd.o + +nmdkmod_kpd-objs := kpd-nomadik.o --- /dev/null +++ linux-2.6.20/drivers/input/keyboard/kpd-nomadik.c @@ -0,0 +1,359 @@ +/* + * linux/drivers/input/keyboard/kpd-nomadik.c + * + * Copyright (C) STMicroelectronics + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Keypad driver for nomadik platforms + */ + +/* Keypad driver Version */ +#define KEYPAD_VER_X 3 +#define KEYPAD_VER_Y 0 +#define KEYPAD_VER_Z 0 + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define KEYPAD_NAME "KEYPAD" + +#ifndef KEYPAD_DEBUG +#define KEYPAD_DEBUG 0 +#endif + +#define NMDK_DEBUG KEYPAD_DEBUG /* enables/disables nmdk_dbg msgs */ +#define NMDK_DEBUG_PFX KEYPAD_NAME /* msg header represents this module */ +#define NMDK_DBG KERN_ERR /* message level */ + +/*function declarations h/w independent*/ +irqreturn_t nomadik_kp_intrhandler(int irq, void *dev_id); +static void nomadik_kp_wq_kscan(struct work_struct *work); + +/* + * Module parameter defination to pass mode of operation + * 0 = to initialize driver in Interrupt mode (default mode) + * 1 = to Intialize driver in polling mode of operation + */ +int kpmode = 0; +module_param(kpmode, int, 0); +MODULE_PARM_DESC(kpmode, "Keypad Operating mode (INT/POLL)=(0/1)"); + +/** + * nomadik_kp_intrhandler - keypad interrupt handler + * + * checks for valid interrupt, disables interrupt to avoid any nested interrupt + * starts work queue for further key processing with debouncing logic + */ +irqreturn_t nomadik_kp_intrhandler(int irq, void *dev_id) +{ + struct keypad_t *kp = (struct keypad_t *)dev_id; + + if (irq != kp->irq) return IRQ_NONE; + if (!(test_bit(KPINTR_LKBIT, &kp->lockbits))) { + nmdk_dbg2("Kp int"); + ____atomic_set_bit(KPINTR_LKBIT, &kp->lockbits); + schedule_delayed_work(&kp->kscan_work, KEYPAD_DEBOUNCE_PERIOD); + } + return IRQ_HANDLED; +} + +/** + * nomadik_kp_wq_kscan - work queue for keypad scanning + * + * Executes at each scan tick, execute the key press/release function, + * Generates key press/release event message for input subsystem for valid key + * events, enables keypad interrupts (for int mode) + */ +static void nomadik_kp_wq_kscan(struct work_struct *work) +{ + int err = 0; + struct keypad_t *kp = container_of((struct delayed_work *)work, struct keypad_t, kscan_work); + + nmdk_dbg2("%s called", (__FUNCTION__)); + + if (!kp->mode && kp->board->irqdis) + kp->board->irqdis(kp); + + if (kp->board->scan) { + err = kp->board->scan(kp); + } else + nmdk_error("key scan function not found"); + + if (0 == err) { + if (kp->mode) { + /*if no key is pressed and polling mode */ + schedule_delayed_work(&kp->kscan_work, + KEYPAD_SCAN_PERIOD); + } else { + if (kp->board->irqen) + kp->board->irqen(kp); + clear_bit(KPINTR_LKBIT, &kp->lockbits); + } + } else { + /*if key is pressed and hold condition */ + schedule_delayed_work(&kp->kscan_work, KEYPAD_RELEASE_PERIOD); + } +} + +/** + * nomadik_kp_init_keypad - keypad parameter initialization + * + * Initializes Keybits to enable keyevents + * Initializes Initial keypress status to default + * Calls the keypad platform specific init function. + */ +int __init nomadik_kp_init_keypad(struct keypad_t *kp) +{ + int row, column, err = 0; + u8 *p_kcode = kp->board->kcode_tbl; + + nmdk_dbg_ftrace(); + + if (kp->board->init) { + err = kp->board->init(kp); + } + if (err) + return (err); + + for (row = 0; row < MAX_KPROW; row++) { + for (column = 0; column < MAX_KPCOL; column++) { + /*set keybits for the keycodes in use */ + set_bit(*p_kcode, kp->inp_dev->keybit); + /*set key status to default value */ + kp->key_state[row][column] = KEYPAD_STATE_DEFAULT; + p_kcode++; + } + } + return (err); +} + + + +#ifdef CONFIG_PM +int nomadik_kp_suspend(struct platform_device *pdev, pm_message_t state) +{ +#if 0 + struct keypad_t *kp = platform_get_drvdata(pdev); + if ( kpmode ) + kp->board->irqen(kp); + if ( !device_may_wakeup(&pdev->dev) ) + kp->board->irqdis(kp); +#endif + return 0; +} + +int nomadik_kp_resume(struct platform_device *pdev) +{ +#if 0 + struct keypad_t *kp = platform_get_drvdata(pdev); + if ( kpmode ) + kp->board->irqdis(kp); + if ( !device_may_wakeup(&pdev->dev) ) + kp->board->irqen(kp); +#endif + return 0; +} + +#else +#define nomadik_kp_suspend NULL +#define nomadik_kp_resume NULL +#endif /* CONFIG_PM */ + +/** + * nomadik_kp_probe - keypad module probe function + * + * Allocates data memory, registers the module with input subsystem, + * initializes keypad default condition, initializes keypad interrupt handler + * for interrupt mode operation, initializes keypad work queues functions for + * polling mode operation + */ +static int __init nomadik_kp_probe(struct platform_device *pdev) +{ + struct keypad_t *kp; + int err = 0; + struct keypad_device *keypad_board = pdev->dev.platform_data; + + nmdk_dbg_ftrace(); + + kp = kzalloc(sizeof(struct keypad_t), GFP_KERNEL); + if (!kp) { + err = -ENOMEM; + goto err_kzalloc; + } + platform_set_drvdata(pdev, kp); + kp = platform_get_drvdata(pdev); +#if !defined (CONFIG_NOMADIK_NHK15) + kp->irq = platform_get_irq(pdev, 0); + if (!kp->irq) { + nmdk_error("keypad irq not defined"); + err = -1; + goto err_board; + } +#endif + if (!keypad_board) { + nmdk_error("keypad platform data not defined"); + err = -1; + goto err_board; + } + kp->board = keypad_board; + kp->mode = kpmode; + + kp->inp_dev = input_allocate_device(); + if (!kp->inp_dev) { + nmdk_error("Could not allocate memory for the device"); + err = -1; + goto err_inp_devalloc; + } + + kp->inp_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP); + kp->inp_dev->name = pdev->name; + kp->inp_dev->phys = "stkpd/input0"; + + kp->inp_dev->id.product = KEYPAD_VER_X; + kp->inp_dev->id.version = KEYPAD_VER_Y * 0x0ff + KEYPAD_VER_Z; + kp->inp_dev->private = kp; + + clear_bit(KPINTR_LKBIT, &kp->lockbits); + + err = nomadik_kp_init_keypad(kp); + if (err) { + goto err_init_kpd; + } + + if (input_register_device(kp->inp_dev) < 0) { + nmdk_error("Could not register input device"); + err = -1; + goto err_inp_reg; + } else { + nmdk_dbg("Registered keypad module with input subsystem"); + } +/* FRED : no IRQ */ +#if !defined (CONFIG_NOMADIK_NHK15) + INIT_DELAYED_WORK(&kp->kscan_work, nomadik_kp_wq_kscan); + /* Initialize keypad interrupt handler */ + if (!kp->mode) { /* true if interrupt mode operation */ + err = request_irq(kp->irq, nomadik_kp_intrhandler, SA_SHIRQ, + kp->inp_dev->name, kp); + if (err) { + nmdk_error("Could not allocate irq %d for keypad", + kp->irq); + goto err_req_irq; + } + } else { + /* Schedule workqueue for polling mode operaion. */ + schedule_delayed_work(&kp->kscan_work, KEYPAD_SCAN_PERIOD); + nmdk_info("Keypad polling started"); + } +#else + /* FRED : only for polling mode */ + if(kp->mode) + { + INIT_DELAYED_WORK(&kp->kscan_work, nomadik_kp_wq_kscan); + schedule_delayed_work(&kp->kscan_work, KEYPAD_SCAN_PERIOD); + nmdk_info("Keypad polling started"); + } + + +#endif + nmdk_info("Module initialized Ver(%d.%d.%d)", + KEYPAD_VER_X, KEYPAD_VER_Y, KEYPAD_VER_Z); + return 0; + + err_req_irq: + err_inp_reg: +#if !defined (CONFIG_NOMADIK_NHK15) + if (!kp->mode) + free_irq(kp->irq, kp); +#endif + input_free_device(kp->inp_dev); + err_init_kpd: + err_inp_devalloc: + err_board: + kfree(kp); + err_kzalloc: + return err; +} + +/** + * nomadik_kp_remove - keypad module remove function + * + * Disables Keypad interrupt if any, frees allocated keypad interrupt if any, + * cancles keypad work queues if any, deallocate used GPIO pin, unregisters the + * module, frees the used memory + */ +static int nomadik_kp_remove(struct platform_device *pdev) +{ + struct keypad_t *kp = platform_get_drvdata(pdev); + + nmdk_dbg_ftrace(); + /*Frees allocated keypad interrupt if any */ + if (kp->board->exit) + kp->board->exit(kp); +#if !defined (CONFIG_NOMADIK_NHK15) + if (!kp->mode) + free_irq(kp->irq, kp); + + /* cancle and flush keypad work queues if any */ + cancel_delayed_work(&kp->kscan_work); + + /* this call may take long to execute (to be checked) */ + flush_scheduled_work(); +#else + if (kp->mode) { + /* cancle and flush keypad work queues if any */ + cancel_delayed_work(&kp->kscan_work); + + /* this call may take long to execute (to be checked) */ + flush_scheduled_work(); + } +#endif + input_unregister_device(kp->inp_dev); + nmdk_info("Module removed...."); + return (0); +} + +struct platform_driver nmdkkpd_driver = { + .probe = nomadik_kp_probe, + .remove = nomadik_kp_remove, + .driver = { + .name = "nmdk-kp", + }, + .suspend = nomadik_kp_suspend, + .resume = nomadik_kp_resume, +}; + +static int __devinit nomadik_kp_init(void) +{ + return platform_driver_register(&nmdkkpd_driver); +} + +static void __exit nomadik_kp_exit(void) +{ + platform_driver_unregister(&nmdkkpd_driver); +} + +module_init(nomadik_kp_init); +module_exit(nomadik_kp_exit); + +MODULE_AUTHOR("Prafulla Wadaskar (prafulla.wadaskar@st.com)"); +MODULE_DESCRIPTION("Nomadik keyboard driver"); +MODULE_LICENSE("GPL v2"); --- linux-2.6.20.orig/drivers/input/touchscreen/Kconfig +++ linux-2.6.20/drivers/input/touchscreen/Kconfig @@ -157,6 +157,26 @@ config TOUCHSCREEN_UCB1400 modular) for this driver to work. To compile this driver as a module, choose M here: the module will be called ucb1400_ts. +config TOUCHSCREEN_NOMADIK + tristate "ADS 7846 based touchscreens for... Nomadik-board" + depends on NOMADIK_SPI + default m + help + Say Y here if you have a touchscreen interface using the + ADS7846 controller for Nomadik platform. + + If unsure, say N (but it's safe to say "Y"). + + To compile this driver as a module, choose M here: the + module will be called nomadik_tp. + +config TOUCHSCREEN_NOMADIK_TS2003 + tristate "2003 based touchscreens for Nomadik-board" + depends on NOMADIK_NHK15 + help + Say Y here if you have a touchscreen interface using the + TS2003 controller for Nomadik platform. + endif --- linux-2.6.20.orig/drivers/input/touchscreen/Makefile +++ linux-2.6.20/drivers/input/touchscreen/Makefile @@ -1,9 +1,13 @@ # # Makefile for the mouse drivers. # +ifdef TOUCHP_DEBUG +CFLAGS += -DTOUCHP_DEBUG=$(TOUCHP_DEBUG) +endif + # Each configuration option enables a list of files. obj-$(CONFIG_TOUCHSCREEN_ADS7846) += ads7846.o obj-$(CONFIG_TOUCHSCREEN_BITSY) += h3600_ts_input.o obj-$(CONFIG_TOUCHSCREEN_CORGI) += corgi_ts.o @@ -14,5 +18,9 @@ obj-$(CONFIG_TOUCHSCREEN_MK712) += mk712 obj-$(CONFIG_TOUCHSCREEN_HP600) += hp680_ts_input.o obj-$(CONFIG_TOUCHSCREEN_PENMOUNT) += penmount.o obj-$(CONFIG_TOUCHSCREEN_TOUCHRIGHT) += touchright.o obj-$(CONFIG_TOUCHSCREEN_TOUCHWIN) += touchwin.o obj-$(CONFIG_TOUCHSCREEN_UCB1400) += ucb1400_ts.o +obj-$(CONFIG_TOUCHSCREEN_NOMADIK) += nmdkmod_tp.o +obj-$(CONFIG_TOUCHSCREEN_NOMADIK_TS2003) += touchp2003-nomadik.o + +nmdkmod_tp-objs := touchp-nomadik.o --- /dev/null +++ linux-2.6.20/drivers/input/touchscreen/touchp-nomadik.c @@ -0,0 +1,755 @@ +/* + * drivers/misc/touchp-nomadik.c + * + * Copyright (C) STMicroelectronics + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Nomadik Touchpanel driver. + * ----------------------------- + * The driver sleeps when there is no pen on the screen. When a pen_down + * interrupt occurs, the pen_down interrupt handler wakes the polling thread. + * The polling thread polls the ADS chip SAMPLES_PER_SECOND. When the polling + * thread polls the ADS chip and the pen is no longer down, the polling + * thread goes to sleep and the pen_down interrupt handler is enabled. + * + * In polling mode operation of this driver, driver never sleeps, whereas + * it is rescheduled to poll periodically as per POLL_SAMPLES_PER_SECOND + * + * The driver is interfaced with Input Subsystem and passes the events for + * pen touch/untouch, presure, x and y co-rodinates + */ + +#ifndef TOUCHP_DEBUG +#define TOUCHP_DEBUG 0 /* default debug messages are disabled */ +#endif + +#define NMDK_DEBUG TOUCHP_DEBUG /* enables/disables debug msgs */ +#define NMDK_DEBUG_PFX TPDRVNAME /* msg header represents this module */ +#define NMDK_DBG KERN_ERR /* message level */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +/* figurative Constants used for Driver */ +#define MAX_X 0x7FF /*Initialzation limits */ +#define MAX_Y 0x7FF +#define MIN_X 0x000 +#define MIN_Y 0x000 + +/********************************************************************** +* Macro: TSDATA_PENDING +**********************************************************************/ +#define TSDATA_PENDING(adsContext) \ + ((adsContext)->tsDataHead != (adsContext)->tsDataTail) + +/********************************************************************** +* Macro: TSDATA_PULL +**********************************************************************/ +#define TSDATA_PULL(adsContext) ((adsContext)->tsDataTail = \ + ((adsContext)->tsDataTail + 1) & (MAX_TS_DATA - 1)) + +/********************************************************************** +* Macro: TSDATA_FLUSH +**********************************************************************/ +#define TSDATA_FLUSH(adsContext) \ + ((adsContext)->tsDataTail = (adsContext)->tsDataHead) + +/********************************************************************** +* Define our ADS context structure +**********************************************************************/ +/* function declaration (generic) */ +static void nomadik_tp_read_data(struct t_adsContext *p_adsContext); +irqreturn_t nomadik_tp_irq_handler(int irq, void *_adsContext); +static int nomadik_tp_ads_784x_thread(void *_adsContext); + +/* Veriables defination */ +struct t_adsContext *adsContext; + +static t_TP_VERSION nomadik_tp_version; +/*struct nomadik_gpio_int_handle gpio_penirq_handle;*/ + +/** + * Module parameter defination to pass mode of operation + * 0 = to initialize driver in Interrupt mode (default mode) + * 1 = to Intialize driver in polling mode of operation + */ +int tpmode = 0; +module_param(tpmode, int, 0); +MODULE_PARM_DESC(tpmode, "Touch panel Operating mode (INT/POLL)=(0/1)"); + +/** + * nomadik_tp_spi_cs_control - callback function for ssp + * @comand: flag decides chip select/deselect operation + */ +void nomadik_tp_spi_cs_control(u32 command) +{ + struct t_adsContext *p_adsContext = adsContext; + if (!p_adsContext) + return; + if (!p_adsContext->board) + return; + nmdk_dbg_ftrace(); + if (SPI_CHIP_SELECT != command) { + if (!p_adsContext->board->cs_dis) { + p_adsContext->board->cs_dis(); + nmdk_dbg2("spi_touchp_chip_deselect"); + } + } else { + if (!p_adsContext->board->cs_en) { + p_adsContext->board->cs_en(); + nmdk_dbg2("spi_touchp_chip_select"); + } + } +} + +/** + * nomadik_tp_ssp_init - ssp init function + * @p_adsContext: device structure + * + * configures and Initializes ssp to use for topuchpanel data transfer, + * returns 0 on sucss, negavie value on failure + */ +int nomadik_tp_ssp_init(struct t_adsContext *p_adsContext) +{ + int status = -1; + const char mod_name[20] = "touchpanel"; + + struct nmdk_spi_config_chip ssp_tp_spi_config = { + .lbm = LOOPBACK_DISABLED, + .com_mode = POLLING_TRANSFER, + .iface = SPI_INTERFACE_MOTOROLA_SPI, + .hierarchy = SPI_MASTER, + .endian_rx = SPI_FIFO_MSB, + .endian_tx = SPI_FIFO_MSB, + .controller = { + .ssp = { + .data_size = SSP_DATA_BITS_32, + .slave_tx_disable = 0, + .rx_lev_trig = SSP_RX_1_OR_MORE_ELEM, + .tx_lev_trig = + SSP_TX_1_OR_MORE_EMPTY_LOC, + .clk_freq = { + .cpsdvsr = 12, + .scr = 128, + }, + }, + }, + .proto_params = { + .moto = { + .clk_phase = SPI_CLK_ZERO_CYCLE_DELAY, + .clk_pol = SPI_CLK_POL_IDLE_LOW, + }, + }, + .dma_config = NULL, + .cs_control = nomadik_tp_spi_cs_control, + .freq = 0 + }; + + nmdk_dbg_ftrace(); + p_adsContext->tp_master = spi_busnum_to_master((u16) SSP_CONTROLLER); + if (NULL == p_adsContext->tp_master) { + nmdk_error("ssp init error - ssp2 bus not found "); + return -1; + } + + p_adsContext->tp_xfer = + kzalloc(sizeof(struct spi_transfer), GFP_KERNEL); + p_adsContext->tp_msg = kzalloc(sizeof(struct spi_message), GFP_KERNEL); + p_adsContext->tp_board_info = + kzalloc(sizeof(struct spi_board_info), GFP_KERNEL); + if (!p_adsContext->tp_xfer || !p_adsContext->tp_msg + || !p_adsContext->tp_board_info) { + kfree(p_adsContext->tp_xfer); + kfree(p_adsContext->tp_msg); + kfree(p_adsContext->tp_board_info); + nmdk_error("kzalloc filed in %s", __FUNCTION__); + return -1; + } + + (p_adsContext->tp_board_info)->controller_data = &ssp_tp_spi_config; + (p_adsContext->tp_board_info)->bus_num = SSP_CONTROLLER, + (p_adsContext->tp_board_info)->chip_select = 0, + strncpy((p_adsContext->tp_board_info)->modalias, mod_name, 20); + p_adsContext->tp_spi = + spi_new_device(p_adsContext->tp_master, + p_adsContext->tp_board_info); + + INIT_LIST_HEAD(&(p_adsContext->tp_msg)->transfers); + + if (p_adsContext->board->ssp_init) + return (p_adsContext->board->ssp_init(p_adsContext)); + else + return (status); +} + +/** + * int nomadik_tp_read_ssp - writes & reads tp adc data using SSP + * @p_adsContext: device structure + * + * Returns 0 on sucess, negavive on failure + */ +static int nomadik_tp_read_ssp(struct t_adsContext *p_adsContext, int pensts) +{ + nmdk_dbg_ftrace(); + if (!pensts) { + p_adsContext->ssp_wrbuf[0] = 0x00126000; /* to read x */ + p_adsContext->ssp_wrbuf[1] = 0x001a6000; /* to read y */ + p_adsContext->ssp_wrbuf[2] = 0x00126000; /* to read x */ + p_adsContext->ssp_wrbuf[3] = 0x001a6000; /* to read y */ + } else { + p_adsContext->ssp_wrbuf[0] = 0x00126000; /* to read x */ + p_adsContext->ssp_wrbuf[1] = 0x001a6000; /* to read y */ + p_adsContext->ssp_wrbuf[2] = 0x00126000; /* to read x */ + p_adsContext->ssp_wrbuf[3] = 0x001a0000; /* to read y */ + nmdk_dbg2("Touchp controller enabled for pensts"); + } + + INIT_LIST_HEAD(&(p_adsContext->tp_msg)->transfers); + (p_adsContext->tp_xfer)->tx_buf = p_adsContext->ssp_wrbuf; + (p_adsContext->tp_xfer)->rx_buf = p_adsContext->ssp_rdbuf; + (p_adsContext->tp_xfer)->len = 4 * sizeof(u32); + + spi_message_add_tail(p_adsContext->tp_xfer, p_adsContext->tp_msg); + spi_sync(p_adsContext->tp_spi, p_adsContext->tp_msg); + + nmdk_dbg3("SSP read= %08x,%08x,%08x,%08x\n", + p_adsContext->ssp_rdbuf[0], p_adsContext->ssp_rdbuf[1], + p_adsContext->ssp_rdbuf[2], p_adsContext->ssp_rdbuf[3]); + return (0); +} + +/** + * int nomadik_tp_ssp_close - closes SSP + * @p_adsContext: device structure + * + * Returns 0 on sucess, negavive on failure + */ +static void nomadik_tp_ssp_close(struct t_adsContext *p_adsContext) +{ + p_adsContext->board->cs_dis(); + spi_unregister_device(p_adsContext->tp_spi); + nmdk_info("freeing allocated memory"); + kfree(p_adsContext->tp_xfer); + kfree(p_adsContext->tp_msg); + kfree(p_adsContext->tp_board_info); +} + +/** + * void nomadik_tp_read_data - reads a set of coordinate data from the SSP + * @p_adsContext: device structur + * + */ +static void nomadik_tp_read_data(struct t_adsContext *p_adsContext) +{ + unsigned int x = 0, x_1 = 0, x_2 = 0; + unsigned int y = 0, y_1 = 0, y_2 = 0; + unsigned int i; + unsigned short x_sum; + unsigned short y_sum; + nmdk_dbg_ftrace(); + + i = 0; + do { + nomadik_tp_read_ssp(p_adsContext, 0); + x_1 = (p_adsContext->ssp_rdbuf[0] & 0xFFF); + y_1 = (p_adsContext->ssp_rdbuf[1] & 0xFFF); + x_2 = (p_adsContext->ssp_rdbuf[2] & 0xFFF); + y_2 = (p_adsContext->ssp_rdbuf[3] & 0xFFF); + i++; + if (i > 100) { + nmdk_dbg2("Could not read SSP for valid ADC values"); + break; + } + } while ((x_1 > (x_2 + X_DELTA_MAX)) + || (x_2 > (x_1 + X_DELTA_MAX)) + || (y_1 > (y_2 + Y_DELTA_MAX)) + || (y_2 > (y_1 + Y_DELTA_MAX))); + + x = (unsigned short)(x_1 + x_2) / 2; + y = (unsigned short)(y_1 + y_2) / 2; + +#if 1 + /* Replace nmdk_error condition with last data set */ + if ((x & 0x7ff) && (y == 0)) { + x = p_adsContext->last_x; + y = p_adsContext->last_y; + } + + /* Circular buffers containing the last SAMP_AVG data sets */ + p_adsContext->x_data_q[p_adsContext->tail] = x; + p_adsContext->y_data_q[p_adsContext->tail] = y; + p_adsContext->tail++; + /* Reset buffer pointer at end of array */ + if (p_adsContext->tail == SAMP_AVG) { + p_adsContext->tail = 0; + } + x_sum = 0; + y_sum = 0; + /* Calculate average of last SAMP_AVG data sets */ + for (i = 0; i < SAMP_AVG; i++) { + x_sum += p_adsContext->x_data_q[i]; + y_sum += p_adsContext->y_data_q[i]; + } + p_adsContext->x_avg = x_sum / SAMP_AVG; + p_adsContext->y_avg = y_sum / SAMP_AVG; + + if ((((int)x - (int)p_adsContext->x_avg) > NU_AVG_X) || (p_adsContext->new_event.p == 0x0ff) || + (((int)p_adsContext->x_avg - (int)x) > NU_AVG_X)) { + for (i = 0; i < SAMP_AVG; i++) { + p_adsContext->x_data_q[i] = x; + } + p_adsContext->x_ret = x; + p_adsContext->last_y = x; + } else if ((((int)x - (int)p_adsContext->x_avg) > JIT_X) || + (((int)p_adsContext->x_avg - (int)x) > JIT_X)) { + p_adsContext->x_ret = p_adsContext->x_avg; + } else { + p_adsContext->x_ret = p_adsContext->last_x; + } + + if ((((int)y - (int)p_adsContext->y_avg) > NU_AVG_Y) || (p_adsContext->new_event.p == 0x0ff) || + (((int)p_adsContext->y_avg - (int)y) > NU_AVG_Y)) { + for (i = 0; i < SAMP_AVG; i++) { + p_adsContext->y_data_q[i] = y; + } + p_adsContext->y_ret = y; + p_adsContext->last_y = y; + } else if ((((int)y - (int)p_adsContext->y_avg) > JIT_Y) || + (((int)p_adsContext->y_avg - (int)y) > JIT_Y)) { + p_adsContext->y_ret = p_adsContext->y_avg; + } else { + p_adsContext->y_ret = p_adsContext->last_y; + } + + p_adsContext->last_x = p_adsContext->x_ret; + p_adsContext->last_y = p_adsContext->y_ret; +#endif + nomadik_tp_read_ssp(p_adsContext, 1); +} + +/** + * nomadik_tp_irq_handler - PENIRW interrupt handler + * @_adsContext: pointer to the device structure + * + * This routine is executed upon the receipt of a touchpanel interrupt. + * It selects the touchscreen controller, clears the interrupt, and wakes up + * the polling thread. + */ +irqreturn_t nomadik_tp_irq_handler(int irq, void *_adsContext) +{ + struct t_adsContext *p_adsContext = (struct t_adsContext *)_adsContext; + + if (irq != p_adsContext->irq ) return IRQ_NONE; + /* Wake up polling thread */ + if (!test_bit(INTR_LOCKBIT, &p_adsContext->lockbits)) { + nmdk_dbg2("Intr rcvd"); + ____atomic_set_bit(INTR_LOCKBIT, &p_adsContext->lockbits); + wake_up(&p_adsContext->irq_wait); + } + return IRQ_HANDLED; +} + +/** + * nomadik_tp_ads_784x_thread - handles the ADC accesses + * @_adsContext: pointer to the device structure + * + * This is a kernel thread that handles the ADC accesses,it sleeps in + * interrupt mode operation and reschedules itself after specific time + * for polling mode operation + * This function does not return until the thread is killed. + **************************************************************************** + */ +static int nomadik_tp_ads_784x_thread(void *_adsContext) +{ + struct t_adsContext *p_adsContext = _adsContext; + struct task_struct *tsk = current; + DECLARE_WAITQUEUE(wait, tsk); +// t_bool pen_down = TRUE; + + nmdk_dbg_ftrace(); + + daemonize("touchpanel"); + + p_adsContext->rtask = tsk; + strcpy(tsk->comm, "ktsd"); + + /* Set up to receive SIGKILL only */ + siginitsetinv(&tsk->blocked, sigmask(SIGKILL)); + recalc_sigpending(); + + current->flags |= PF_NOFREEZE; + + /* Add thread to wait queue */ + add_wait_queue(&p_adsContext->irq_wait, &wait); + + /* Wake up init */ + complete(&p_adsContext->complete); + + /* disable irq before polling in int mode */ + if (!p_adsContext->mode) { + if (p_adsContext->board->pirq_dis) { + p_adsContext->board->pirq_dis(p_adsContext); + } + } + + /* Pen-down polling loop */ + for (;;) { + + /* Set task to interrupt mode */ + set_task_state(tsk, TASK_INTERRUPTIBLE); + + p_adsContext->old_event.p = p_adsContext->new_event.p; + /* Read the pen_down data first as it jitters after the other reads */ + if (p_adsContext->board->pdown) { + if (!p_adsContext->board->pdown(p_adsContext)) { + /* If pen down, sleep for one sample interval, then + process touchscreen. */ + nomadik_tp_read_data(p_adsContext); + if (!p_adsContext->board->pdown(p_adsContext)) { + p_adsContext->new_event.p =0; + p_adsContext->old_event.x = p_adsContext->new_event.x; + p_adsContext->old_event.y = p_adsContext->new_event.y; + p_adsContext->new_event.x = p_adsContext->x_ret; + p_adsContext->new_event.y = p_adsContext->y_ret; + } + } else { + p_adsContext->new_event.p =1; + } + } + + if (p_adsContext->old_event.p == 0 && p_adsContext->new_event.p == 0) { + nmdk_dbg("%s(): p = %d, x=%d, y=%d", __FUNCTION__, + (unsigned int)p_adsContext->new_event.p, (unsigned int)p_adsContext->new_event.x, + (unsigned int)p_adsContext->new_event.y); + + /* Report Tp event to Input subsystem layer */ + input_report_key(p_adsContext->input, BTN_TOUCH, p_adsContext->new_event.p); + input_report_abs(p_adsContext->input, ABS_X, X_CORR(p_adsContext->new_event.x, p_adsContext->new_event.y)); + input_report_abs(p_adsContext->input, ABS_Y, Y_CORR(p_adsContext->new_event.x, p_adsContext->new_event.y)); +// input_report_abs(p_adsContext->input, ABS_PRESSURE, p); + input_sync(p_adsContext->input); + p_adsContext->debounce_flag = 0x1; + + /* schedule for next ssp read */ + nmdk_dbg2("%s(): scheduling next poll ", + __FUNCTION__); + schedule_timeout(HZ / p_adsContext->board->samples); + } else + if (p_adsContext->old_event.p == 1 && p_adsContext->new_event.p == 1) { + if (p_adsContext->debounce_flag == 0x01) { + p_adsContext->debounce_flag = 0x00; + nmdk_dbg("%s(): p = %d, x=%d, y=%d", __FUNCTION__, + (unsigned int)p_adsContext->new_event.p, (unsigned int)p_adsContext->new_event.x, + (unsigned int)p_adsContext->new_event.y); + + /* Report Tp event to Input subsystem layer */ + input_report_key(p_adsContext->input, BTN_TOUCH,p_adsContext->new_event.p); + input_report_abs(p_adsContext->input, ABS_X, X_CORR(p_adsContext->new_event.x, p_adsContext->new_event.y)); + input_report_abs(p_adsContext->input, ABS_Y, Y_CORR(p_adsContext->new_event.x, p_adsContext->new_event.y)); + // input_report_abs(p_adsContext->input, ABS_PRESSURE, p); + input_sync(p_adsContext->input); + } + + /* reset presure data to sense next valid touch */ + p_adsContext->new_event.p = 0x0ff; + p_adsContext->old_event.p = 0x0ff; + + /* Enable interrupt */ + if (!p_adsContext->mode) { + nmdk_dbg2("%s(): sleeping", __FUNCTION__); + if (p_adsContext->board->pirq_en) { + p_adsContext->board-> + pirq_en(p_adsContext); + } + clear_bit(INTR_LOCKBIT, + &p_adsContext->lockbits); + schedule(); + if (p_adsContext->board->pirq_dis) { + p_adsContext->board-> + pirq_dis(p_adsContext); + } + nmdk_dbg2("%s(): waking up", __FUNCTION__); + } else { + nmdk_dbg2("%s(): scheduling next poll ", + __FUNCTION__); + schedule_timeout(HZ / p_adsContext->board->pollsamples); + } + } else { + /* schedule for next ssp read */ + nmdk_dbg2("%s(): scheduling next poll for debounce ", + __FUNCTION__); + schedule_timeout(HZ / 100); //p_adsContext->board->samples); + } + + /* Check for SIGKILL */ + if (signal_pending(tsk)) + break; + } + + + remove_wait_queue(&p_adsContext->irq_wait, &wait); + p_adsContext->rtask = NULL; + + return (0); +} + +/** + * nomadik_tp_init - initializes the module + * + * This function registers and initializes the module. + * RETURN: Zero or negative nmdk_error code + */ +static int __init nomadik_tp_probe(struct platform_device *pdev) +{ + struct input_dev *input_dev; + struct t_adsContext *p_adsContext; + struct touchp_device *touchp_board = pdev->dev.platform_data; + int result = 0; + + nmdk_dbg_ftrace(); + + if (!touchp_board) { + nmdk_error("platform data not defined"); + result = -1; + goto err_kzalloc; + } + p_adsContext = kzalloc(sizeof(struct t_adsContext), GFP_KERNEL); + if (!p_adsContext) { + result = -ENOMEM; + goto err_kzalloc; + } + platform_set_drvdata(pdev, p_adsContext); + p_adsContext = platform_get_drvdata(pdev); + adsContext = p_adsContext; + + input_dev = input_allocate_device(); + if (!input_dev) { + result = -ENOMEM; + goto err_ssp_init_fail; + } + p_adsContext->input = input_dev; + input_dev->name = "ADS784x Touchscreen"; + input_dev->phys = "ST-tp/input0"; + /*input_dev->cdev.dev = (void *)p_adsContext;*/ + input_dev->private = p_adsContext; + + input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); + input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH); + input_set_abs_params(input_dev, ABS_X, 0, MAX_12BIT, 0, 0); + input_set_abs_params(input_dev, ABS_Y, 0, MAX_12BIT, 0, 0); + input_set_abs_params(input_dev, ABS_PRESSURE, 0, 1, 0, 0); + + p_adsContext->irq = platform_get_irq(pdev, 0); + if (!p_adsContext->irq) { + nmdk_error("Cannot find touchpanel irq"); + result = -1; + goto err_ssp_init_fail; + } + p_adsContext->board = touchp_board; + p_adsContext->mode = tpmode; + + init_waitqueue_head(&p_adsContext->read_wait); + + if (nomadik_tp_ssp_init(p_adsContext)) { + result = -EINTR; + goto err_ssp_init_fail; + } + if (p_adsContext->board->gpio_init) { + if (p_adsContext->board->gpio_init(p_adsContext)) { + result = -EINTR; + goto err_gpio_init_fail; + } + } + /* disable touchpanel cs initially */ + if (p_adsContext->board->cs_dis) + p_adsContext->board->cs_dis(); + + /* write data on ssp to enable penirq stastus */ + nomadik_tp_read_ssp(p_adsContext, 1); + + p_adsContext->tsData_lock = RW_LOCK_UNLOCKED; + clear_bit(INTR_LOCKBIT, &p_adsContext->lockbits); + + /* reset presure data to sense next valid touch */ + p_adsContext->new_event.p = 0x0ff; + p_adsContext->old_event.p = 0x0ff; + p_adsContext->debounce_flag = 0; + + /* Start the ADS polling thread */ + if (p_adsContext->rtask == NULL) { + init_completion(&p_adsContext->complete); + init_waitqueue_head(&p_adsContext->irq_wait); + result = kernel_thread(nomadik_tp_ads_784x_thread, p_adsContext, + CLONE_FS | CLONE_FILES); + if (result >= 0) { + /* Sleep until thread has started correctly */ + wait_for_completion(&p_adsContext->complete); + result = 0; + } else { + nmdk_error("%s: could not start thread", __FILE__); + goto err_poll_thread_fail; + } + } + + if (!p_adsContext->mode) { + /* Set PENIRQ interrupt handler */ + result = + request_irq(p_adsContext->irq, nomadik_tp_irq_handler, + SA_SHIRQ, pdev->name, p_adsContext); + if (result) { + nmdk_error("Could not allocate irq %d for penirq", + p_adsContext->irq); + goto err_request_irq; + } else { + nmdk_info("touhpanel interrupt allocatated"); + } + } else { + nmdk_info("module started in polling mode"); + } + + result = input_register_device(input_dev); + if (result) { + nmdk_error("%s: could not register ads_784x erro =%d", __FILE__, + result); + goto err_input_register; + } + + sprintf(nomadik_tp_version, "%d.%d.%d", + TOUCHP_VER_X, TOUCHP_VER_Y, TOUCHP_VER_Z); + nmdk_info("module initialized Version(%s)", nomadik_tp_version); + + return result; + + err_request_irq: + err_input_register: + err_poll_thread_fail: + if (p_adsContext->rtask) { + send_sig(SIGKILL, p_adsContext->rtask, 1); + schedule(); + } + err_gpio_init_fail: + nomadik_tp_ssp_close(p_adsContext); + err_ssp_init_fail: + input_free_device(input_dev); + kfree(p_adsContext); + err_kzalloc: + return result; +} + +/** + * nomadik_tp_exit - cleans up the module + * + * This function unregisters and cleans up the module + */ +static int nomadik_tp_remove(struct platform_device *pdev) +{ + struct t_adsContext *p_adsContext = platform_get_drvdata(pdev); + int status = 0; + + nmdk_dbg_ftrace(); + if (!p_adsContext->mode) + free_irq(p_adsContext->irq, (void *)p_adsContext); + /* Kill ADS polling thread */ + if (p_adsContext->rtask) { + send_sig(SIGKILL, p_adsContext->rtask, 1); + schedule(); + } + nomadik_tp_ssp_close(p_adsContext); + if (p_adsContext->board->gpio_exit) { + if (p_adsContext->board->gpio_exit(p_adsContext)){ + status = 1; + nmdk_error("Gpio free for touchpanel failed.."); + } + } + /*input_free_device(p_adsContext->input);*/ + input_unregister_device(p_adsContext->input); + kfree(p_adsContext); + nmdk_info("module removed"); + if (status){ + return -1; + } + return (0); +} + +#ifdef CONFIG_PM +int nomadik_tp_suspend(struct platform_device *pdev, pm_message_t state) +{ + struct t_adsContext *p_adsContext = platform_get_drvdata(pdev); + if ( tpmode ) + if (p_adsContext->board->pirq_en) + p_adsContext->board->pirq_en(p_adsContext); + if ( !device_may_wakeup(&pdev->dev) ) + if (p_adsContext->board->pirq_dis) + p_adsContext->board->pirq_dis(p_adsContext); + return 0; +} + +int nomadik_tp_resume(struct platform_device *pdev) +{ + struct t_adsContext *p_adsContext = platform_get_drvdata(pdev); + if ( tpmode ) + if (p_adsContext->board->pirq_dis) + p_adsContext->board->pirq_dis(p_adsContext); + if ( !device_may_wakeup(&pdev->dev) ) + if (p_adsContext->board->pirq_en) + p_adsContext->board->pirq_en(p_adsContext); + return 0; +} + +#else +#define nomadik_tp_suspend NULL +#define nomadik_tp_resume NULL +#endif /* CONFIG_PM */ + +struct platform_driver nmdktp_driver = { + .probe = nomadik_tp_probe, + .remove = nomadik_tp_remove, + .driver = { + .name = "nmdk-tp", + }, + + .suspend = nomadik_tp_suspend, + .resume = nomadik_tp_resume, +}; + +static int __devinit nomadik_tp_init(void) +{ + return platform_driver_register(&nmdktp_driver); +} + +static void __exit nomadik_tp_exit(void) +{ + platform_driver_unregister(&nmdktp_driver); +} + +module_init(nomadik_tp_init); +module_exit(nomadik_tp_exit); + +MODULE_AUTHOR + ("Prafulla Wadaskar , ST Microelectronics"); +MODULE_DESCRIPTION("Nomadik Touchpanel Driver"); +MODULE_LICENSE("GPL"); --- /dev/null +++ linux-2.6.20/drivers/input/touchscreen/touchp2003-nomadik.c @@ -0,0 +1,566 @@ +/* + * linux/drivers/i2c/chips/tsc2003.c + * + * Copyright (C) 2005 Bill Gatliff + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Driver for TI's TSC2003 I2C Touch Screen Controller + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DEBUG_TS(x) printk x + +/* + * Insmod parameters + */ + +#define DRIVER_NAME "tsc2003" + +enum tsc2003_pd { + PD_POWERDOWN = 0, /* penirq */ + PD_IREFOFF_ADCON = 1, /* no penirq */ + PD_IREFON_ADCOFF = 2, /* penirq */ + PD_IREFON_ADCON = 3, /* no penirq */ + PD_PENIRQ_ARM = PD_IREFON_ADCOFF, + PD_PENIRQ_DISARM = PD_IREFON_ADCON, +}; + +enum tsc2003_m { + M_12BIT = 0, + M_8BIT = 1 +}; + +enum tsc2003_cmd { + MEAS_TEMP0 = 0, + MEAS_VBAT1 = 1, + MEAS_IN1 = 2, + MEAS_TEMP1 = 4, + MEAS_VBAT2 = 5, + MEAS_IN2 = 6, + ACTIVATE_NX_DRIVERS = 8, + ACTIVATE_NY_DRIVERS = 9, + ACTIVATE_YNX_DRIVERS = 10, + MEAS_XPOS = 12, + MEAS_YPOS = 13, + MEAS_Z1POS = 14, + MEAS_Z2POS = 15 +}; + +#define TSC2003_CMD(cn,pdn,m) (((cn) << 4) | ((pdn) << 2) | ((m) << 1)) + +#define ADC_MAX ((1 << 12) - 1) + +struct tsc2003_data { + struct i2c_client client; + + /*struct device_driver driver; FRED*/ + struct platform_driver driver; + struct touchp_tsc2003_device * board; + + struct input_dev idev; + struct timer_list penirq_timer; + struct semaphore sem; + int is_opened; + enum tsc2003_pd pd; + enum tsc2003_m m; + int penirq; + struct work_struct workq; + int vbat1; + int vbat2; + int temp0; + int temp1; + int in1; + int in2; +}; + +static void ReactivatePenIRQ (struct tsc2003_data *data); +static void tsc2003ts_task (void *v); + +static inline int tsc2003_command (struct tsc2003_data *data, + enum tsc2003_cmd cmd, + enum tsc2003_pd pd) +{ + char c; + int ret; + //down(&data->sem); + c = TSC2003_CMD(cmd, pd, data->m); + //ret = i2c_master_send(&data->client, &c, 1); + ret = nomadik_i2c_write_register(I2C_TOUCH_CLIENT,&c,0,1); + + //up(&data->sem); + return ret; +} + +static int tsc2003_read (struct tsc2003_data *data, + enum tsc2003_cmd cmd, + enum tsc2003_pd pd, + int *val) +{ + char c; + char d_read[2]; + int ret; + + c = TSC2003_CMD(cmd, pd, data->m); + //ret = i2c_master_send(&data->client, &c, 1); + ret = nomadik_i2c_write_register(I2C_TOUCH_CLIENT,&c,0,1); + if (ret) goto err; + + udelay(20); + //ret = i2c_master_recv(&data->client, d, data->m == M_12BIT ? 2 : 1); + ret = nomadik_i2c_read_register(I2C_TOUCH_CLIENT,d_read,0,data->m == M_12BIT ? 2 : 1); + if (ret) goto err; + + if (val) + { + *val = d_read[0]; + *val <<= 4; + if (data->m == M_12BIT) + *val += (d_read[1] >> 4); + } + +#if defined(CONFIG_I2C_DEBUG_CHIP) + printk(KERN_ERR "%s: val[%x] = %d\n", + __FUNCTION__, cmd, (((int)d_read[0]) << 8) + d_read[1]); +#endif + + return 0; + err: + if (!ret) ret = -ENODEV; + return ret; +} + +static int send_command (struct tsc2003_data *data, + unsigned char command_byte, unsigned short *val) +{ + char d_read[2]; + int ret; + + ret = nomadik_i2c_write_register(I2C_TOUCH_CLIENT,&command_byte,0,1); + if (ret) goto err; + + udelay(20); + ret = nomadik_i2c_read_register(I2C_TOUCH_CLIENT,d_read,0,data->m == M_12BIT ? 2 : 1); + if (ret) goto err; + + if (val) + { + *val = d_read[0]; + *val <<= 4; + if (data->m == M_12BIT) + *val += (d_read[1] >> 4); + } + + return 0; + err: + if (!ret) ret = -ENODEV; + return ret; +} + +static inline int tsc2003_read_temp0 (struct tsc2003_data *d, enum +tsc2003_pd pd, int *t) +{ + return tsc2003_read(d, MEAS_TEMP0, pd, t); +} + +static inline int tsc2003_read_temp1 (struct tsc2003_data *d, enum +tsc2003_pd pd, int *t) +{ + return tsc2003_read(d, MEAS_TEMP1, pd, t); +} + +static inline int tsc2003_read_xpos (struct tsc2003_data *d, enum +tsc2003_pd pd, int *x) +{ + return tsc2003_read(d, MEAS_XPOS, pd, x); +} + +static inline int tsc2003_read_ypos (struct tsc2003_data *d, enum +tsc2003_pd pd, int *y) +{ + return tsc2003_read(d, MEAS_YPOS, pd, y); +} + +static inline int tsc2003_read_pressure (struct tsc2003_data *d, enum +tsc2003_pd pd, int *p) +{ + return tsc2003_read(d, MEAS_Z1POS, pd, p); +} + +static inline int tsc2003_read_in1 (struct tsc2003_data *d, enum +tsc2003_pd pd, int *t) +{ + return tsc2003_read(d, MEAS_IN1, pd, t); +} + +static inline int tsc2003_read_in2 (struct tsc2003_data *d, enum +tsc2003_pd pd, int *t) +{ + return tsc2003_read(d, MEAS_IN2, pd, t); +} + +static inline int tsc2003_read_vbat1 (struct tsc2003_data *d, enum +tsc2003_pd pd, int *t) +{ + return tsc2003_read(d, MEAS_VBAT1, pd, t); +} + +static inline int tsc2003_read_vbat2 (struct tsc2003_data *d, enum +tsc2003_pd pd, int *t) +{ + return tsc2003_read(d, MEAS_VBAT2, pd, t); +} + +static inline int tsc2003_powerdown (struct tsc2003_data *d) +{ + /* we don't have a distinct powerdown command, + so do a benign read with the PD bits cleared */ + return tsc2003_read(d, MEAS_IN1, PD_POWERDOWN, 0); +} + + +#define PENUP_TIMEOUT 50 /* msec */ + +/*static irqreturn_t tsc2003_penirq (int irq, void *v, struct pt_regs *regs) +{ + struct tsc2003_data *d = v; + DEBUG_TS(("tsc2003_penirq\n")); + complete(&d->penirq_completion); + return IRQ_HANDLED; +}*/ + +/* Fred : replaced by callback */ +static void ts2003_callback (void * parameter) +{ + struct tsc2003_data *d = (struct tsc2003_data *)parameter; + //DEBUG_TS(("ts2003_callback\n")); + + tsc2003ts_task(d); +} + +static int tsc2003_remove(struct platform_device *pdev) +{ + struct tsc2003_data *data; + + data = platform_get_drvdata(pdev); + //input_free_device(&data->idev); + input_unregister_device(&data->idev); + kfree(data); + + return 0; +} + +static inline void tsc2003_restart_pen_up_timer (struct tsc2003_data *d) +{ + mod_timer(&d->penirq_timer, jiffies + (PENUP_TIMEOUT * HZ) / 1000); +} + + +static void tsc2003_timer_callback (unsigned long v) +{ + struct tsc2003_data *d = (struct tsc2003_data *)v; + schedule_work(&d->workq); +} + +static void tsc2003_timer_callback1(struct work_struct *work) +{ + /*struct tsc2003_data *d = (struct tsc2003_data *)v;*/ + struct tsc2003_data *d = container_of(work, struct tsc2003_data, workq); + unsigned char pin_value ; + unsigned int x, y, p; + + struct task_struct *tsk = current; + set_task_state(tsk, TASK_INTERRUPTIBLE); + + d->board->pirq_read_val(&pin_value); + if( pin_value == 1) + { + /* The pen is up */ + /*printk("pen is up....\n"); */ + input_report_abs(&d->idev, ABS_PRESSURE, 0); + input_sync(&d->idev); + /*schedule_timeout(HZ/20);*/ + return ; + } + + tsc2003_read_xpos(d, PD_PENIRQ_DISARM, &x); + tsc2003_read_ypos(d, PD_PENIRQ_DISARM, &y); + tsc2003_read_pressure(d, PD_PENIRQ_DISARM, &p); + ReactivatePenIRQ(d); + + input_report_abs(&d->idev, ABS_X, x); + input_report_abs(&d->idev, ABS_Y, y); + input_report_abs(&d->idev, ABS_PRESSURE, p); + input_sync(&d->idev); + + /*d->board->pirq_read_val(&pin_value); */ + if( pin_value == 0) + { + /* pen down event, (re)start the pen up timer */ + tsc2003_restart_pen_up_timer(d); + } +#if 0 + else + { + /* The pen is up */ + /*printk("pen is up again ....\n");*/ + input_report_abs(&d->idev, ABS_PRESSURE, 0); + input_sync(&d->idev); + /*schedule_timeout(HZ/20); */ + } +#endif + return; +} + +static void ReactivatePenIRQ (struct tsc2003_data *data) +{ + unsigned char command_byte; + unsigned short dummy ; + + /* Send I2C command to reactivate PENIRQn */ + /* C3=1, C2=1, C1=0, C0=0, PD1=0, PD2=0, M=0 */ + command_byte = 0xC0; + send_command(data, command_byte, &dummy); + + // acknowledge possible pending interrupt + //data->board->pirq_ack(); +} + +static void tsc2003ts_task (void *v) +{ + struct tsc2003_data *d = v; + unsigned int x, y, p; + + tsc2003_read_xpos(d, PD_PENIRQ_DISARM, &x); + tsc2003_read_ypos(d, PD_PENIRQ_DISARM, &y); + tsc2003_read_pressure(d, PD_PENIRQ_DISARM, &p); + ReactivatePenIRQ(d); + + input_report_abs(&d->idev, ABS_X, x); + input_report_abs(&d->idev, ABS_Y, y); + input_report_abs(&d->idev, ABS_PRESSURE, p); + input_sync(&d->idev); + + /* pen down event, (re)start the pen up timer */ + tsc2003_restart_pen_up_timer(d); + + d->board->pirq_ack(); + d->board->pirq_en(); +} + +static int tsc2003_idev_open (struct input_dev *i_dev) +{ + struct tsc2003_data *d = container_of(i_dev, struct tsc2003_data, idev); + int ret = 0; + + DEBUG_TS(("tsc2003_idev_open\n")); + if (down_interruptible(&d->sem)) + return -EINTR; + + if (d->is_opened) + panic(DRIVER_NAME "tsd already running (!). abort."); + + if (d->board->irq_init) + { + if (d->board->irq_init(ts2003_callback,(void*)d)) + { + return -1; + } + d->board->pirq_en(); + } + DEBUG_TS(("\tcallback setup\n")); + d->penirq_timer.data = (unsigned long)d; + d->penirq_timer.function = tsc2003_timer_callback; + + d->is_opened = 1 ; + up(&d->sem); + + return 0; +} + +static void tsc2003_idev_close (struct input_dev *i_dev) +{ + struct tsc2003_data *d = container_of(i_dev, struct tsc2003_data, idev); + DEBUG_TS(("tsc2003_idev_close\n")); + down_interruptible(&d->sem); + + d->is_opened = 0 ; + //free_irq(d->penirq, d); + if (d->board->irq_exit) + { + d->board->irq_exit(); + } + + if (timer_pending(&d->penirq_timer)) + del_timer(&d->penirq_timer); + + up(&d->sem); + return; +} + +static int tsc2003_driver_register (struct tsc2003_data *data) +{ + int ret = 0; + DEBUG_TS(("tsc2003_driver_register\n")); + + init_MUTEX(&data->sem); + init_timer(&data->penirq_timer); + data->is_opened = 0 ; + data->penirq_timer.data = (unsigned long)data; + data->penirq_timer.function = tsc2003_timer_callback; + +INIT_WORK(&data->workq, tsc2003_timer_callback1); + + //init_input_dev(&data->idev); + init_ts_input_dev(&data->idev); + data->idev.name = DRIVER_NAME; + data->idev.evbit[0] = BIT(EV_ABS); + data->idev.open = tsc2003_idev_open; + data->idev.close = tsc2003_idev_close; + data->idev.absbit[LONG(ABS_X)] = BIT(ABS_X); + data->idev.absbit[LONG(ABS_Y)] = BIT(ABS_Y); + data->idev.absbit[LONG(ABS_PRESSURE)] = BIT(ABS_PRESSURE); + + input_set_abs_params(&data->idev, ABS_X, 0, ADC_MAX, 0, 0); + input_set_abs_params(&data->idev, ABS_Y, 0, ADC_MAX, 0, 0); + + ret = input_register_device(&data->idev); + + return ret; +} + + +static int __init tsc2003_probe(struct platform_device *pdev) +{ + struct tsc2003_data *d; + int err; + struct touchp_tsc2003_device *touchp_board = pdev->dev.platform_data; + + DEBUG_TS(("tsc2003_probe\n")); + + d = kcalloc(1, sizeof(*d), GFP_KERNEL); + if (!d) + { + err = -ENOMEM; + goto err_kzalloc; + } + + DEBUG_TS(("\tdata allocated(%x)\n",(unsigned int)d)); + platform_set_drvdata(pdev, d); + d = platform_get_drvdata(pdev); + + if (!touchp_board) { + printk("touchp platform data not defined"); + err = -1; + goto err_board; + } + d->board = touchp_board; + + DEBUG_TS(("Probing TSC2003\n")); + err = tsc2003_powerdown(d); + if (err >= 0) + { + DEBUG_TS(("\tpowerdown ok\n")); + d->pd = PD_PENIRQ_DISARM; + d->m = M_8BIT; + err = tsc2003_driver_register(d); + if (err) { + goto err_init_tsc2003; + } + printk("\tTSC2003 Module initialized\n"); + return 0; + } + + err_init_tsc2003: + err_board: + kfree(d); + err_kzalloc: + return err; +} + +#ifdef CONFIG_PM +int nomadik_tsc2003_suspend(struct platform_device *pdev, pm_message_t state) +{ +#if 0 + struct tsc2003_data *d = platform_get_drvdata(pdev); + + if (d->board->pirq_en) { + /*printk("touchscreen suspend: enabling interrupt...\n");*/ + d->board->pirq_en(); + } + + if ( !device_may_wakeup(&pdev->dev) ) + if (d->board->pirq_dis) { + /*printk("touchscreen suspend: disabling interrupt...\n");*/ + d->board->pirq_dis(); + } +#endif + return 0; +} + +int nomadik_tsc2003_resume(struct platform_device *pdev) +{ +#if 0 + struct tsc2003_data *d = platform_get_drvdata(pdev); + + if (d->board->pirq_dis) { + /*printk("touchscreen resume: disabling interrupt...\n");*/ + d->board->pirq_dis(); + } + + if ( !device_may_wakeup(&pdev->dev) ) + if (d->board->pirq_en) { + /*printk("touchscreen resume: enabling interrupt...\n");*/ + d->board->pirq_en(); + } +#endif + return 0; +} + +#else +#define nomadik_tsc2003_suspend NULL +#define nomadik_tsc2003_resume NULL +#endif /* CONFIG_PM */ + +static struct platform_driver tsc2003_driver = { + .probe = tsc2003_probe, + .remove = tsc2003_remove, + .driver = { + .name = "tsc2003", + }, + .suspend = nomadik_tsc2003_suspend, + .resume = nomadik_tsc2003_resume, +}; + +static int __devinit tsc2003_init(void) +{ + return platform_driver_register(&tsc2003_driver); +} + +static void __exit tsc2003_exit(void) +{ + platform_driver_unregister(&tsc2003_driver); +} + +MODULE_AUTHOR("Bill Gatliff "); +MODULE_DESCRIPTION("TSC2003 Touch Screen Controller driver"); +MODULE_LICENSE("GPL"); + +module_init(tsc2003_init); +module_exit(tsc2003_exit); --- linux-2.6.20.orig/drivers/media/Kconfig +++ linux-2.6.20/drivers/media/Kconfig @@ -63,10 +63,12 @@ source "drivers/media/radio/Kconfig" source "drivers/media/dvb/Kconfig" source "drivers/media/common/Kconfig" +source "drivers/media/nomadik_mm/Kconfig" + config VIDEO_TUNER tristate depends on I2C config VIDEO_BUF --- linux-2.6.20.orig/drivers/media/Makefile +++ linux-2.6.20/drivers/media/Makefile @@ -4,5 +4,9 @@ obj-y := common/ obj-$(CONFIG_VIDEO_DEV) += video/ obj-$(CONFIG_VIDEO_DEV) += radio/ obj-$(CONFIG_DVB) += dvb/ +#obj-y += nomadik_mm/ +obj-$(CONFIG_NOMADIK_SVA) += nomadik_mm/sva/ +obj-$(CONFIG_NOMADIK_SAA) += nomadik_mm/saa/ +obj-$(CONFIG_NOMADIK_OGL) += nomadik_mm/opengl/ --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/Kconfig @@ -0,0 +1,23 @@ +# +# Nomadik Multimedia Audio/Video device configuration +# + +menu "NOMADIK Audio Video Graphic Drivers(SAA SVA and OPENGL) " + +config NOMADIK_SAA + tristate "Nomadik SAA Support" + depends on ARCH_NOMADIK && NOMADIK_MSP && I2C_NOMADIK + ---help--- + Support for Nomadik SAA DSP + +config NOMADIK_SVA + tristate "Nomadik SVA Support" + depends on ARCH_NOMADIK && VIDEO_V4L2 && I2C_NOMADIK + ---help--- + Support for Nomadik SVA DSP + +config NOMADIK_OGL + tristate "Nomadik OGL Support" + ---help--- + Support for Nomadik OGL DSP +endmenu --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/Makefile @@ -0,0 +1,8 @@ +# +# Makefile for the kernel multimedia device drivers. +#kefile for the kernel multimedia device drivers. +# + +obj-$(CONFIG_NOMADIK_SAA) += saa/ +obj-$(CONFIG_NOMADIK_SVA) += sva/ +obj-$(CONFIG_NOMADIK_OGL) += opengl/ --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/hcl/hloader/hloader.c @@ -0,0 +1,3632 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ + +/*--------------------------------------------------------------------------* + * Includes * + *--------------------------------------------------------------------------*/ +#include "hloader_p.h" +/*--------------------------------------------------------------------------* + * Public functions * + *--------------------------------------------------------------------------*/ + +/****************************************************************************/ +/* NAME : HLOADER_GetMemSizes */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION : Fill the struct pointed by t_loader_config with mem */ +/* sizes of the firmware and some infos on the firmware */ +/* file. Parses the firmware located at */ +/* p_hloader_config->FirmwareAddr, and fills the Size */ +/* members of the following members: ProgramZone1, */ +/* ProgramZone2, Data16Zone1, Data16Zone2, Data24Zone1, */ +/* Data24Zone2 */ +/* PARAMETERS : */ +/* IN : None */ +/* OUT : p_hloader_config : Configuration with correctly */ +/* filled structure members */ +/* */ +/* RETURN : */ +/* LOADER_INTERNAL : If file header or p_hloader_config */ +/* are NULL */ +/* LOADER_OK : Returns this if no error is detected */ +/* error_status : Any other error value */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY : NA */ +/****************************************************************************/ +PUBLIC t_loader_error HLOADER_GetMemSizes(OUT t_loader_config *p_hloader_config) +{ + t_file_header *p_file_header; + t_sint8 *p_temp_f_fw_ver; + t_sint32 count; + t_loader_error error_status; + t_uint16 f_nsections; + t_uint16 f_sh_size; + t_uint16 f_sht_offset; + t_uint16 f_flags; + t_uint32 f_tools_ver; + + /* To point on the first section address */ + p_file_header = (t_file_header *) p_hloader_config->FirmwareBaseAddr; + + if ((NULL == p_file_header) || (NULL == p_hloader_config)) + { + return(LOADER_INTERNAL); + } + + f_nsections = p_file_header->f_nsections; + f_sh_size = p_file_header->f_sh_size; + f_sht_offset = p_file_header->f_sht_offset; + f_flags = p_file_header->f_flags; + f_tools_ver = p_file_header->f_tools_ver; + + SWAPENDIANNESS16(f_nsections); + SWAPENDIANNESS16(f_sh_size); + SWAPENDIANNESS16(f_sht_offset); + SWAPENDIANNESS16(f_flags); + SWAPENDIANNESS32(f_tools_ver); + + if (LOADER_OK != (error_status = hloader_CheckFileHeader(p_file_header))) + { + return(error_status); + } + + p_hloader_config->Machine = (t_uint16) (f_flags & MMF_MACHINE_MASK); + + /* Tools version flags was introduced in version MMF_VER_11 */ + if (HLOADER_MMF_F_VER10 != (f_flags & MMF_VERSION_MASK)) + { + p_hloader_config->ToolsVersion = f_tools_ver; + } else + { + p_hloader_config->ToolsVersion = 0; + } + + /* Firmware version was introduced in version MMF_VER_12 */ + if ((HLOADER_MMF_F_VER11 != (f_flags & MMF_VERSION_MASK)) && (HLOADER_MMF_F_VER10 != (f_flags & MMF_VERSION_MASK))) + { + p_temp_f_fw_ver = (t_sint8*) p_file_header->f_fw_ver; + for (count=0;count<8;count++) + { + *(p_hloader_config->FwVersion+count) = *(p_temp_f_fw_ver+count); + } + } else + { + p_hloader_config->FwVersion[0] = '\0'; + } + + /* Firmware sections processing */ + for (count = 0; count < f_nsections; count++) + { + error_status = hloader_GetSectionSize + ( + p_hloader_config, + (t_uint32 *) ((t_sint8 *) p_hloader_config->FirmwareBaseAddr + f_sht_offset + (count * f_sh_size)) + ); + if (LOADER_OK != error_status) + { + return(error_status); + } + } + + return(LOADER_OK); +} + +/****************************************************************************/ +/* NAME : HLOADER_Init */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION : Initialize the loader internal structures, connects and */ +/* identifies the accelerator at */ +/* p_hloader_config->HamacBaseAddr */ +/* PARAMETERS : */ +/* IN : p_hloader_config : Configuration with correctly */ +/* filled HamacBaseAddr member */ +/* OUT : None */ +/* */ +/* RETURN : */ +/* LOADER_BAD_MACHINE : Error detected */ +/* LOADER_INTERNAL : If p_hloader_config is NULL */ +/* LOADER_OK : Returns this if no error is */ +/* detected */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY : NA */ +/****************************************************************************/ +PUBLIC t_loader_error HLOADER_Init(IN t_loader_config *p_hloader_config) +{ + t_loader_error error_status; + + if (NULL == p_hloader_config) + { + return(LOADER_INTERNAL); + } + + /* Initialize context structure */ + p_hloader_config->Context.compression = NO_COMPRESSION; + p_hloader_config->Context.ahb_master_init = NULL; + p_hloader_config->Context.ahb_base_init = NULL; + p_hloader_config->Context.core_id = TA_UNKNOWN; + p_hloader_config->Context.compat = (t_compat) 0; + p_hloader_config->Context.nb_code_sections = 0; + p_hloader_config->ProgramZone1.Size = 0; + p_hloader_config->ProgramZone2.Size = 0; + p_hloader_config->Data16Zone1.Size = 0; + p_hloader_config->Data16Zone2.Size = 0; + p_hloader_config->Data24Zone1.Size = 0; + p_hloader_config->Data24Zone2.Size = 0; + + if (LOADER_OK != (error_status = hloader_IdentifyHamac(p_hloader_config))) + { + return(error_status); + } + + switch (p_hloader_config->Context.core_id) + { + case TA_8815A_A0: + case TA_8815V_A0: + case TA_8815A_B0: + case TA_8815V_B0: + p_hloader_config->Context.ahb_master_init = hloader_AhbMasterInit8815; + p_hloader_config->Context.ahb_base_init = hloader_AhbBaseInit8815; + break; + case TA_8800A_8810A: + p_hloader_config->Context.ahb_master_init = hloader_AhbMasterInit8800And8810; + p_hloader_config->Context.ahb_base_init = hloader_AhbBaseInit8800And8810; + break; + case TA_8810A_B0: + case TA_8810V_B0: + p_hloader_config->Context.ahb_master_init = hloader_AhbMasterInit8810B0; + p_hloader_config->Context.ahb_base_init = hloader_AhbBaseInit8810B0; + break; + default: + p_hloader_config->Context.ahb_master_init = NULL; + p_hloader_config->Context.ahb_base_init = NULL; + break; + } + + return(LOADER_OK); +} + +/****************************************************************************/ +/* NAME : HLOADER_GetVersion */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION : Gives the current version of the HLOADER HCL */ +/* */ +/* PARAMETERS : */ +/* IN : None */ +/* OUT : p_version : Structure which will consist of */ +/* the version of the current HCL */ +/* RETURN : LOADER_OK : Returns this if no error */ +/* deteceted */ +/* LOADER_INTERNAL : If p_version is NULL */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY : Re-entrant */ +/* REENTRANCY ISSUES: No Issues */ +/****************************************************************************/ +PUBLIC t_loader_error HLOADER_GetVersion(OUT t_version *p_version) +{ + if (NULL != p_version) + { + p_version->version = HLOADER_HCL_VERSION_ID; + p_version->major = HLOADER_HCL_MAJOR_ID; + p_version->minor = HLOADER_HCL_MINOR_ID; + return(LOADER_OK); + } else + { + return(LOADER_INTERNAL); + } +} + +/****************************************************************************/ +/* NAME : HLOADER_FirmwareLoad */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION : Load the firmware from the config given in parameter */ +/* PARAMETERS : */ +/* IN : p_hloader_config : Firmware configuration */ +/* OUT : None */ +/* */ +/* RETURN : */ +/* LOADER_INTERNAL : If file header or p_hloader_config */ +/* are NULL */ +/* LOADER_OK : Returns this if no error is detected */ +/* error_status : Any other error value */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY : NA */ +/****************************************************************************/ +PUBLIC t_loader_error HLOADER_FirmwareLoad(IN t_loader_config *p_hloader_config) +{ + t_file_header *p_file_header; + t_sint32 count; + t_loader_error error_status; + t_uint16 f_nsections; + t_uint16 f_sh_size; + t_uint16 f_sht_offset; + t_uint16 f_flags; + t_uint32 f_tools_ver; + t_sint32 func_dummy_ret_val = 0; + + if (LOADER_OK != (error_status = hloader_CheckSizes(p_hloader_config))) + { + return(error_status); + } + + /* To point on the first section address. */ + p_file_header = (t_file_header *) p_hloader_config->FirmwareBaseAddr; + + if ((NULL == p_file_header) || (NULL == p_hloader_config)) + { + return(LOADER_INTERNAL); + } + + f_nsections = p_file_header->f_nsections; + f_sh_size = p_file_header->f_sh_size; + f_sht_offset = p_file_header->f_sht_offset; + f_flags = p_file_header->f_flags; + f_tools_ver = p_file_header->f_tools_ver; + f_flags = f_flags; /* To remove RVCT warning */ + f_tools_ver = f_tools_ver; /* To remove RVCT warning */ + + SWAPENDIANNESS16(f_nsections); + SWAPENDIANNESS16(f_sh_size); + SWAPENDIANNESS16(f_sht_offset); + SWAPENDIANNESS16(f_flags); + SWAPENDIANNESS32(f_tools_ver); + + /* Verify compatibility between firmware and hardware */ + if (LOADER_OK != (error_status = hloader_CheckAndSetCompat(p_hloader_config))) + { + return(error_status); + } + + /* hloader_CheckSizes has called HLOADER_GetMemSizes which does some checks */ + /* on the file and fills some infos on the struct */ +#ifdef MMDSPTOOLS + if ((t_uint32) p_hloader_config->LoadingInstr & HLOADER_DUMP_VAL) + { + func_dummy_ret_val = fprintf(stdout, "FILE HEADER\n"); + func_dummy_ret_val = fprintf(stdout, "\tMMF version: %d\n", (f_flags & MMF_VERSION_MASK) >> 4); + func_dummy_ret_val = fprintf(stdout, "\tTools version = %ld\n", p_hloader_config->ToolsVersion); + func_dummy_ret_val = fprintf(stdout, "\tnb sections = %d\n", f_nsections); + func_dummy_ret_val = fprintf(stdout, "\tsection hdr size = %d\n", f_sh_size); + func_dummy_ret_val = fprintf(stdout, "\tsection hdr offset = %d\n", f_sht_offset); + func_dummy_ret_val = fprintf(stdout, "\tMachine = %s\n", hloader_MmfGetMachineStr(p_hloader_config->Machine)); + } +#endif /* End MMDSPTOOLS */ + + /* To remove the PC lint warning */ + func_dummy_ret_val = func_dummy_ret_val; + + p_hloader_config->Context.nb_code_sections = 0; + +#ifndef MMDSPTOOLS + /* Stop core clock */ + error_status = HLOADER_StopClock(p_hloader_config); +#endif /* End MMDSPTOOLS */ + + /* Firmware sections processing */ + for (count = 0; count < f_nsections; count++) + { + error_status = hloader_ProcessSection( + p_hloader_config, + (t_uint32 *) ((t_sint8 *) p_hloader_config->FirmwareBaseAddr + f_sht_offset + (count * f_sh_size)) + ); + if (LOADER_OK != error_status) + { + return(error_status); + } + } + + return(LOADER_OK); +} +/***************************************************************************/ +/*NAME : HLOADER_GetEsramSaaSectionSize */ +/*-------------------------------------------------------------------------*/ +/*DESCRIPTION : Get the size of esram and saa sections of the firmware */ +/* */ +/*PARAMETERS : */ +/* IN : p_hloader_config : Firmware configuration */ +/* OUT : t_uint32 */ +/* */ +/*RETURN : */ +/* size : Sum of sizes of all ESRAM and SAA Sections */ +/*-------------------------------------------------------------------------*/ +/*REENTRANCY : NA */ +/***************************************************************************/ + +PUBLIC t_uint32 HLOADER_GetEsramSaaSectionSize(IN t_loader_config *p_hloader_config) +{ + t_file_header *p_file_header; + t_section_header *p_section_header; + t_loader_error error_status; + t_uint32 f_count; + t_uint16 f_nsections; + t_uint16 f_sh_size; + t_uint16 f_sht_offset; + t_uint32 esram_saa_fw_size = 0; + + if (LOADER_OK != (error_status = hloader_CheckSizes(p_hloader_config))) + return(0); + + error_status = error_status; /* to remove pclint warning*/ + + /* To point on the file header */ + p_file_header = (t_file_header *) p_hloader_config->FirmwareBaseAddr; + + if ((NULL == p_file_header) || (NULL == p_hloader_config)) + return(0); + + f_nsections = p_file_header->f_nsections; + f_sh_size = p_file_header->f_sh_size; + f_sht_offset = p_file_header->f_sht_offset; + + SWAPENDIANNESS16(f_nsections); + SWAPENDIANNESS16(f_sh_size); + SWAPENDIANNESS16(f_sht_offset); + + /* Verify compatibility between firmware and hardware */ + if (LOADER_OK != hloader_CheckAndSetCompat(p_hloader_config)) + return(0); + + esram_saa_fw_size = esram_saa_fw_size + f_sht_offset; + + for (f_count = 0; f_count < f_nsections; f_count++) + { + p_section_header = (t_section_header *) ((t_sint8 *) p_hloader_config->FirmwareBaseAddr + f_sht_offset + (f_count * f_sh_size)); + + if (p_section_header == NULL) + return(0); + + SWAPENDIANNESS16(p_section_header->s_type); + SWAPENDIANNESS16(p_section_header->s_memtype); + SWAPENDIANNESS32(p_section_header->s_size); + + + if (p_section_header->s_type != MMF_SHT_NOBITS) + { + switch (p_section_header->s_memtype) + { + case MMF_MT_PROGRAM_MEM: /*Bypass SDRAM Code Section and Data*/ + break; + case MMF_MT_ESRAM_PMEM: + + /*Add section header size*/ + esram_saa_fw_size = esram_saa_fw_size + f_sh_size; + /*Add section data size*/ + esram_saa_fw_size = esram_saa_fw_size + p_section_header->s_size; + break; + + case MMF_MT_X_MEM: + case MMF_MT_Y_MEM: + case MMF_MT_ESRAM_EXT24: + case MMF_MT_ESRAM_EXT16: + + /*Add section header size*/ + esram_saa_fw_size = esram_saa_fw_size + f_sh_size; + /*Add section data size*/ + esram_saa_fw_size = esram_saa_fw_size + p_section_header->s_size; + break; + + case MMF_MT_WS_MEM: + case MMF_MT_HOST_MEM: + case MMF_MT_HA_EXT24: + case MMF_MT_HA_EXT16: + case MMF_MT_HA_VLC_CODE: + case MMF_MT_HA_VLC_LUT: + case MMF_MT_HV_COMP_CODE: + case MMF_MT_HV_DICT: + break; + + default: + return(0); + } + } + } + + return(esram_saa_fw_size); +} + +/***************************************************************************/ +/*NAME : HLOADER_SaveEsramSaaSection */ +/*-------------------------------------------------------------------------*/ +/*DESCRIPTION : Saves the esram and saa sections of the firmware at the */ +/* back up location from the config given in parameter */ +/*PARAMETERS : */ +/* IN : p_hloader_config : Firmware configuration */ +/* IN p_backup_config : Backup configuration */ +/* OUT : None */ +/* */ +/*RETURN : */ +/* LOADER_INTERNAL : If file header or p_hloader_config */ +/* are NULL */ +/* LOADER_OK : Returns this if no error is detected */ +/* error_status : Any other error value */ +/*-------------------------------------------------------------------------*/ +/*REENTRANCY : NA */ +/***************************************************************************/ +PUBLIC t_loader_error HLOADER_SaveEsramSaaSection(IN t_loader_config *p_hloader_config, IN t_backup_config *p_backup_config) +{ + t_file_header *p_file_header; + t_section_header *p_section_header; + t_sint32 f_count; + t_sint32 count; + t_loader_error error_status; + t_uint16 f_nsections; + t_uint16 f_sh_size; + t_uint16 f_sht_offset; + t_uint16 f_flags; + t_uint32 f_tools_ver; + t_sint32 func_dummy_ret_val = 0; + t_uint32 *p_src_index; + t_uint32 *p_dest_index; + t_uint16 b_nsections = 0; + + if (LOADER_OK != (error_status = hloader_CheckSizes(p_hloader_config))) + { + return(error_status); + } + + /* To point on the file header */ + p_file_header = (t_file_header *) p_hloader_config->FirmwareBaseAddr; + + if ((NULL == p_file_header) || (NULL == p_hloader_config) || (NULL == p_backup_config)) + { + return(LOADER_INTERNAL); + } + + f_nsections = p_file_header->f_nsections; + f_sh_size = p_file_header->f_sh_size; + f_sht_offset = p_file_header->f_sht_offset; + f_flags = p_file_header->f_flags; + f_tools_ver = p_file_header->f_tools_ver; + f_flags = f_flags; /* To remove RVCT warning */ + f_tools_ver = f_tools_ver; /* To remove RVCT warning */ + + SWAPENDIANNESS16(f_nsections); + SWAPENDIANNESS16(f_sh_size); + SWAPENDIANNESS16(f_sht_offset); + SWAPENDIANNESS16(f_flags); + SWAPENDIANNESS32(f_tools_ver); + + /* Verify compatibility between firmware and hardware */ + if (LOADER_OK != (error_status = hloader_CheckAndSetCompat(p_hloader_config))) + { + return(error_status); + } + + /* hloader_CheckSizes has called HLOADER_GetMemSizes which does some checks */ + /* on the file and fills some infos on the struct */ +#ifdef MMDSPTOOLS + if ((t_uint32) p_hloader_config->LoadingInstr & HLOADER_DUMP_VAL) + { + func_dummy_ret_val = fprintf(stdout, "FILE HEADER\n"); + func_dummy_ret_val = fprintf(stdout, "\tMMF version: %d\n", (f_flags & MMF_VERSION_MASK) >> 4); + func_dummy_ret_val = fprintf(stdout, "\tTools version = %ld\n", p_hloader_config->ToolsVersion); + func_dummy_ret_val = fprintf(stdout, "\tnb sections = %d\n", f_nsections); + func_dummy_ret_val = fprintf(stdout, "\tsection hdr size = %d\n", f_sh_size); + func_dummy_ret_val = fprintf(stdout, "\tsection hdr offset = %d\n", f_sht_offset); + func_dummy_ret_val = fprintf(stdout, "\tMachine = %s\n", hloader_MmfGetMachineStr(p_hloader_config->Machine)); + } +#endif /* End MMDSPTOOLS */ + + /* To remove the PC lint warning */ + func_dummy_ret_val = func_dummy_ret_val; + + p_hloader_config->Context.nb_code_sections = 0; + + p_dest_index = (t_uint32 *)(p_backup_config->BaseAddr); + p_src_index = (t_uint32 *)((t_sint8 *)p_hloader_config->FirmwareBaseAddr); + + /* Save File Header*/ + for (count = 0; count < (f_sht_offset)/ 4 ; count++) + *p_dest_index++ = *p_src_index++; + + /* Firmware sections copying */ + for (f_count = 0; f_count < f_nsections; f_count++) + { + p_section_header = (t_section_header *) ((t_sint8 *) p_hloader_config->FirmwareBaseAddr + f_sht_offset + (f_count * f_sh_size)); + + if ((p_section_header == NULL) || (p_hloader_config == NULL)) + { + return(LOADER_INTERNAL); + } + + SWAPENDIANNESS16(p_section_header->s_type); + SWAPENDIANNESS16(p_section_header->s_memtype); + SWAPENDIANNESS16(p_section_header->s_flags); + SWAPENDIANNESS16(p_section_header->s_bpw); + SWAPENDIANNESS32(p_section_header->s_size); + SWAPENDIANNESS32(p_section_header->s_offset); + SWAPENDIANNESS32(p_section_header->s_addr); + +#ifdef MMDSPTOOLS + if ((t_uint32) p_hloader_config->LoadingInstr & HLOADER_DUMP_VAL) + { + hloader_MmDspDisplaySectionHeader(p_section_header); + } +#endif /* End MMDSPTOOLS */ + + if (p_section_header->s_type != MMF_SHT_NOBITS) + { + switch (p_section_header->s_memtype) + { + case MMF_MT_PROGRAM_MEM: /*Bypass SDRAM Code Section and Data*/ + break; + case MMF_MT_ESRAM_PMEM: /*Save ESRAM Code Section Header and Data*/ + p_hloader_config->Context.nb_code_sections++; + + if ((t_uint32) p_hloader_config->LoadingInstr & HLOADER_LOAD_CODE_VAL) + { + /*change the file offset to the section data*/ +// p_section_header->s_offset = ((t_uint32*)p_section_header - (t_uint32*)p_hloader_config->FirmwareBaseAddr) + f_sh_size; +// SWAPENDIANNESS32(p_section_header->s_offset); + + /*Save section header*/ + p_src_index = (t_uint32 *)p_section_header; + for (count = 0; count < f_sh_size / (t_uint16)4; count++) + *p_dest_index++ = *p_src_index++; + + /*Save Section Data*/ + p_src_index = (t_uint32 *) ((t_sint8 *) p_hloader_config->FirmwareBaseAddr + p_section_header->s_offset); + + for (count = 0; (t_uint32) count < p_section_header->s_size/4; count++) + *p_dest_index++ = *p_src_index++; + + b_nsections++; + } + +#ifdef MMDSPTOOLS + if ((t_uint32) p_hloader_config->LoadingInstr & HLOADER_CHECK_CODE_VAL) + { + error_status = hloader_CheckCodeSection(p_hloader_config, p_section_header); + if (error_status != LOADER_OK) + { + return(error_status); + } + } + if ((t_uint32) p_hloader_config->LoadingInstr & HLOADER_DUMP_SECTION_VAL) + { + error_status = hloader_DumpCodeSection(p_hloader_config, p_section_header); + if (error_status != LOADER_OK) + { + return(error_status); + } + } +#endif /* End MMDSPTOOLS */ + + if + ( + (((t_uint32) p_hloader_config->LoadingInstr & HLOADER_LOAD_CODE_VAL) == 0) + && (p_hloader_config->Context.nb_code_sections > 1) + ) + { + /* We were instructed not to copy the code, but there are more * + * than one code sec, so we don't guarantee the code is loaded */ + return(LOADER_CODE_NOT_LOADED); + } + break; + + case MMF_MT_X_MEM: /*Save SAA X_MEM Data Section Header and Data*/ + case MMF_MT_Y_MEM: /*Save SAA X_MEM Data Section Header and Data*/ + case MMF_MT_ESRAM_EXT24: /*Save ESRAM EXT_24 Data Section Header and Data*/ + case MMF_MT_ESRAM_EXT16: /*Save ESRAM EXT_16 Data Section Header and Data*/ + + if ((t_uint32) p_hloader_config->LoadingInstr & HLOADER_LOAD_DATA_VAL) + { + /*Save section header*/ + p_src_index = (t_uint32 *)p_section_header; + for (count = 0; count < f_sh_size/ (t_uint16)4; count++) + *p_dest_index++ = *p_src_index++; + + /*Save Section Data*/ + p_src_index = (t_uint32 *) ((t_sint8 *) p_hloader_config->FirmwareBaseAddr + p_section_header->s_offset); + for (count = 0; (t_uint32) count < p_section_header->s_size/4; count++) + *p_dest_index++ = *p_src_index++; + + b_nsections++; + } + +#ifdef MMDSPTOOLS + if ((t_uint32) p_hloader_config->LoadingInstr & HLOADER_CHECK_DATA_VAL) + { + error_status = hloader_CheckDataSection(p_hloader_config, p_section_header); + if (error_status != LOADER_OK) + { + return(error_status); + } + } + + if ((t_uint32) p_hloader_config->LoadingInstr & HLOADER_DUMP_SECTION_VAL) + { + error_status = hloader_DumpDataSection(p_hloader_config, p_section_header); + if (error_status != LOADER_OK) + { + return(error_status); + } + } +#endif /* End MMDSPTOOLS */ + break; + + case MMF_MT_WS_MEM: + case MMF_MT_HOST_MEM: + case MMF_MT_HA_EXT24: + case MMF_MT_HA_EXT16: + case MMF_MT_HA_VLC_CODE: + case MMF_MT_HA_VLC_LUT: + case MMF_MT_HV_COMP_CODE: + case MMF_MT_HV_DICT: + break; + + default: + return(LOADER_UKN_MEMTYPE); + } + } + } + + /* Since this function does not copies sdram sections, the number of sections will reduce.*/ + + p_file_header = (t_file_header *) p_backup_config->BaseAddr; + SWAPENDIANNESS16(b_nsections); + p_file_header->f_nsections = b_nsections; + + return(LOADER_OK); +} + + +/***************************************************************************/ +/*NAME : HLOADER_LoadEsramSaaSection */ +/*-------------------------------------------------------------------------*/ +/*DESCRIPTION : Reloads the saa and esram sections of the firmware from */ +/* the backup location. */ +/*PARAMETERS : */ +/* IN : p_hloader_config : Firmware configuration */ +/* IN : p_backup_config : BackUp configuration */ +/* OUT : None */ +/* */ +/*RETURN : */ +/* LOADER_INTERNAL : If file header or p_hloader_config */ +/* are NULL */ +/* LOADER_OK : Returns this if no error is detected */ +/* error_status : Any other error value */ +/*-------------------------------------------------------------------------*/ +/*REENTRANCY : NA */ +/***************************************************************************/ + +PUBLIC t_loader_error HLOADER_LoadEsramSaaSection(IN t_loader_config *p_hloader_config, IN t_backup_config *p_backup_config) +{ + t_file_header *p_file_header; + t_section_header *p_section_header; + t_sint32 f_count; + t_uint32 count; + t_loader_error error_status; + t_uint16 f_nsections; + t_uint16 f_sh_size; + t_uint16 f_sht_offset; + t_uint16 f_flags; + t_uint32 f_tools_ver; + t_sint32 func_dummy_ret_val = 0; + t_uint32 *p_src_index; + t_uint16 *p_short_src_index; + t_uint32 *p_dest_index; + t_uint16 *p_short_dest_index; + t_uint32 *p_cur_section_addr; + + /* To point on the file header */ + p_file_header = (t_file_header *) p_backup_config->BaseAddr; + + if ((NULL == p_file_header) || (p_hloader_config == NULL) || (NULL == p_backup_config)) + { + return(LOADER_INTERNAL); + } + + f_nsections = p_file_header->f_nsections; + f_sh_size = p_file_header->f_sh_size; + f_sht_offset = p_file_header->f_sht_offset; + f_flags = p_file_header->f_flags; + f_tools_ver = p_file_header->f_tools_ver; + f_flags = f_flags; /* To remove RVCT warning */ + f_tools_ver = f_tools_ver; /* To remove RVCT warning */ + + SWAPENDIANNESS16(f_nsections); + SWAPENDIANNESS16(f_sh_size); + SWAPENDIANNESS16(f_sht_offset); + SWAPENDIANNESS16(f_flags); + SWAPENDIANNESS32(f_tools_ver); + + + /* on the file and fills some infos on the struct */ +#ifdef MMDSPTOOLS + if ((t_uint32) p_hloader_config->LoadingInstr & HLOADER_DUMP_VAL) + { + func_dummy_ret_val = fprintf(stdout, "FILE HEADER\n"); + func_dummy_ret_val = fprintf(stdout, "\tMMF version: %d\n", (f_flags & MMF_VERSION_MASK) >> 4); + func_dummy_ret_val = fprintf(stdout, "\tTools version = %ld\n", p_hloader_config->ToolsVersion); + func_dummy_ret_val = fprintf(stdout, "\tnb sections = %d\n", f_nsections); + func_dummy_ret_val = fprintf(stdout, "\tsection hdr size = %d\n", f_sh_size); + func_dummy_ret_val = fprintf(stdout, "\tsection hdr offset = %d\n", f_sht_offset); + func_dummy_ret_val = fprintf(stdout, "\tMachine = %s\n", hloader_MmfGetMachineStr(p_hloader_config->Machine)); + } +#endif /* End MMDSPTOOLS */ + + /* To remove the PC lint warning */ + func_dummy_ret_val = func_dummy_ret_val; + + p_hloader_config->Context.nb_code_sections = 0; + +#ifndef MMDSPTOOLS + /* Stop core clock */ + error_status = HLOADER_StopClock(p_hloader_config); +#endif /* End MMDSPTOOLS */ + + /* Firmware sections copying */ + p_cur_section_addr = (t_uint32 *) ((t_sint8 *) p_backup_config->BaseAddr + f_sht_offset); + + for (f_count = 0; f_count < f_nsections; f_count++) + { + p_section_header = (t_section_header *) p_cur_section_addr; + + if ((p_section_header == NULL) || (p_hloader_config == NULL)) + { + return(LOADER_INTERNAL); + } + + SWAPENDIANNESS16(p_section_header->s_type); + SWAPENDIANNESS16(p_section_header->s_memtype); + SWAPENDIANNESS16(p_section_header->s_flags); + SWAPENDIANNESS16(p_section_header->s_bpw); + SWAPENDIANNESS32(p_section_header->s_size); + SWAPENDIANNESS32(p_section_header->s_offset); + SWAPENDIANNESS32(p_section_header->s_addr); + +#ifdef MMDSPTOOLS + if ((t_uint32) p_hloader_config->LoadingInstr & HLOADER_DUMP_VAL) + { + hloader_MmDspDisplaySectionHeader(p_section_header); + } +#endif /* End MMDSPTOOLS */ + + if (p_section_header->s_type != MMF_SHT_NOBITS) + { + switch (p_section_header->s_memtype) + { + case MMF_MT_ESRAM_PMEM: + p_hloader_config->Context.nb_code_sections++; + + if ((t_uint32) p_hloader_config->LoadingInstr & HLOADER_LOAD_CODE_VAL) + { + /*Load ESRAM Code Section */ + p_src_index = (t_uint32 *)((t_uint32)p_section_header + f_sh_size); + p_dest_index = (t_uint32 *)(p_hloader_config->ProgramZone2.Base.logical + ((p_section_header->s_addr - 0xE0000) * 8)); + + if ((p_src_index == NULL) || (p_dest_index == NULL)) + { + return(LOADER_INTERNAL); + } + + for (count = 0; count < p_section_header->s_size/4; count++) + { + *p_dest_index++ = *p_src_index++; + } + p_cur_section_addr = p_src_index; + } + + + + if + ( + (((t_uint32) p_hloader_config->LoadingInstr & HLOADER_LOAD_CODE_VAL) == 0) + && (p_hloader_config->Context.nb_code_sections > 1) + ) + { + /* We were instructed not to copy the code, but there are more * + * than one code sec, so we don't guarantee the code is loaded */ + return(LOADER_CODE_NOT_LOADED); + } + break; + + case MMF_MT_X_MEM: /*Save SAA X_MEM Data Section Header and Data*/ + case MMF_MT_Y_MEM: /*Save SAA X_MEM Data Section Header and Data*/ + case MMF_MT_ESRAM_EXT24: /*Save ESRAM EXT_24 Data Section Header and Data*/ + case MMF_MT_ESRAM_EXT16: /*Save ESRAM EXT_16 Data Section Header and Data*/ + + if ((t_uint32) p_hloader_config->LoadingInstr & HLOADER_LOAD_DATA_VAL) + { + + p_src_index = (t_uint32 *)((t_uint32)p_section_header + f_sh_size); + p_short_src_index = (t_uint16 *)((t_uint32)p_section_header + f_sh_size);; + + if + ( + ( + error_status = hloader_CalculateDestIndex + ( + p_hloader_config, + p_section_header, + &p_dest_index, + &p_short_dest_index + ) + ) != LOADER_OK + ) + { + return(error_status); + } + + if ((p_short_src_index == NULL) || (p_short_dest_index == NULL)) + { + return(LOADER_INTERNAL); + } + + if ((p_src_index == NULL) || (p_dest_index == NULL)) + { + return(LOADER_INTERNAL); + } + + if + ( + ((t_uint16) THREE_BYTES_PER_WORD == p_section_header->s_bpw) + && (HLOADER_MMF_F_HAMACV != p_hloader_config->Machine) + && (HLOADER_MMF_F_HV_FULL != p_hloader_config->Machine) + && (!(IS_HA_EXT_MEMORY16(p_section_header->s_memtype))) + && (!(IS_ESRAM_EXT_MEMORY16(p_section_header->s_memtype))) + ) + { + for (count = 0; count < p_section_header->s_size / 4; count++) + { + *p_dest_index++ = *p_src_index++; + } + } else if (p_section_header->s_bpw == (t_uint16) THREE_BYTES_PER_WORD) + { + for (count = 0; count < p_section_header->s_size / 4; count++) + { + *p_short_dest_index = *p_short_src_index; + p_short_dest_index++; + p_short_src_index++; + p_short_src_index++; /* To discard two bytes */ + } + } else if (p_section_header->s_bpw == (t_uint16) TWO_BYTES_PER_WORD) + { + for (count = 0; count < p_section_header->s_size / 4; count++) + { + *p_dest_index++ = *p_src_index++; + } + } + p_cur_section_addr = p_src_index; + } + + break; + + default: + return(LOADER_UKN_MEMTYPE); + } + } + } + + return(LOADER_OK); + +} + + + +/****************************************************************************/ +/* NAME : HLOADER_PartialLoad */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION : Reload the saa and esram section from the main */ +/* firmware */ +/* PARAMETERS : */ +/* IN : p_hloader_config : Firmware configuration */ +/* OUT : None */ +/* */ +/* RETURN : */ +/* LOADER_INTERNAL : If file header or p_hloader_config */ +/* are NULL */ +/* LOADER_OK : Returns this if no error is detected */ +/* error_status : Any other error value */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY : NA */ +/****************************************************************************/ +PUBLIC t_loader_error HLOADER_PartialLoad(IN t_loader_config *p_hloader_config) +{ + t_file_header *p_file_header; + t_uint32 count; + t_loader_error error_status; + t_uint16 f_nsections; + t_uint16 f_sh_size; + t_uint16 f_sht_offset; + t_uint16 f_flags; + t_uint32 f_tools_ver; + t_sint32 func_dummy_ret_val = 0; + + if (LOADER_OK != (error_status = hloader_CheckSizes(p_hloader_config))) + { + return(error_status); + } + + /* To point on the first section address. */ + p_file_header = (t_file_header *) p_hloader_config->FirmwareBaseAddr; + + if ((NULL == p_file_header) || (NULL == p_hloader_config)) + { + return(LOADER_INTERNAL); + } + + f_nsections = p_file_header->f_nsections; + f_sh_size = p_file_header->f_sh_size; + f_sht_offset = p_file_header->f_sht_offset; + f_flags = p_file_header->f_flags; + f_tools_ver = p_file_header->f_tools_ver; + f_flags = f_flags; /* To remove RVCT warning */ + f_tools_ver = f_tools_ver; /* To remove RVCT warning */ + + SWAPENDIANNESS16(f_nsections); + SWAPENDIANNESS16(f_sh_size); + SWAPENDIANNESS16(f_sht_offset); + SWAPENDIANNESS16(f_flags); + SWAPENDIANNESS32(f_tools_ver); + + /* Verify compatibility between firmware and hardware */ + if (LOADER_OK != (error_status = hloader_CheckAndSetCompat(p_hloader_config))) + { + return(error_status); + } + + /* hloader_CheckSizes has called HLOADER_GetMemSizes which does some checks */ + /* on the file and fills some infos on the struct */ +#ifdef MMDSPTOOLS + if ((t_uint32) p_hloader_config->LoadingInstr & HLOADER_DUMP_VAL) + { + func_dummy_ret_val = fprintf(stdout, "FILE HEADER\n"); + func_dummy_ret_val = fprintf(stdout, "\tMMF version: %d\n", (f_flags & MMF_VERSION_MASK) >> 4); + func_dummy_ret_val = fprintf(stdout, "\tTools version = %ld\n", p_hloader_config->ToolsVersion); + func_dummy_ret_val = fprintf(stdout, "\tnb sections = %d\n", f_nsections); + func_dummy_ret_val = fprintf(stdout, "\tsection hdr size = %d\n", f_sh_size); + func_dummy_ret_val = fprintf(stdout, "\tsection hdr offset = %d\n", f_sht_offset); + func_dummy_ret_val = fprintf(stdout, "\tMachine = %s\n", hloader_MmfGetMachineStr(p_hloader_config->Machine)); + } +#endif /* End MMDSPTOOLS */ + + /* To remove the PC lint warning */ + func_dummy_ret_val = func_dummy_ret_val; + + p_hloader_config->Context.nb_code_sections = 0; + +#ifndef MMDSPTOOLS + /* Stop core clock */ + error_status = HLOADER_StopClock(p_hloader_config); +#endif /* End MMDSPTOOLS */ + + /* Firmware sections processing */ + for (count = 0; count < f_nsections; count++) + { + error_status = hloader_PartialProcessSection( + p_hloader_config, + (t_uint32 *) ((t_sint8 *) p_hloader_config->FirmwareBaseAddr + f_sht_offset + (count * f_sh_size)) + ); + if (LOADER_OK != error_status) + { + return(error_status); + } + } + + return(LOADER_OK); +} + + +/****************************************************************************/ +/* NAME : HLOADER_AHB_base_init */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION : Initialize the AHB master bases registers of the hamac */ +/* PARAMETERS : */ +/* IN : p_hloader_config : Device configuration */ +/* OUT : None */ +/* */ +/* RETURN : */ +/* LOADER_INTERNAL : If p_hloader_config is NULL */ +/* LOADER_OK : Returns this if no error is detected */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY : NA */ +/****************************************************************************/ +PUBLIC t_loader_error HLOADER_AHB_base_init(IN t_loader_config *p_hloader_config) +{ + if (NULL == p_hloader_config) + { + return(LOADER_INTERNAL); + } + + if (NULL != p_hloader_config->Context.ahb_base_init) + { + return(p_hloader_config->Context.ahb_base_init(p_hloader_config)); + } + + return(LOADER_OK); +} + +/****************************************************************************/ +/* NAME : HLOADER_Boot */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION : Configure the DSP to match the firmware req, reset and */ +/* boot. Configures and boots the DSP using values in */ +/* p_hloader_config (some of which are set by */ +/* HLOADER_FirmwareLoad). */ +/* PARAMETERS : */ +/* IN : p_hloader_config : Device configuration */ +/* OUT : None */ +/* */ +/* RETURN : */ +/* LOADER_INTERNAL : If p_hloader_config is NULL */ +/* LOADER_OK : Returns this if no error is detected */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY : NA */ +/****************************************************************************/ +PUBLIC t_loader_error HLOADER_Boot(IN t_loader_config *p_hloader_config) +{ + t_loader_error error_status = LOADER_OK; + if (NULL == p_hloader_config) + { + return(LOADER_INTERNAL); + } + + if (NULL != p_hloader_config->Context.ahb_master_init) + { + error_status = p_hloader_config->Context.ahb_master_init(p_hloader_config); + } + + error_status = hloader_SoftReset(p_hloader_config); + + error_status = HLOADER_StartClock(p_hloader_config); + + return(error_status); +} + +/****************************************************************************/ +/* NAME : HLOADER_StopClock */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION : Stops the DSP clock. */ +/* PARAMETERS : */ +/* IN : p_hloader_config : Device configuration */ +/* OUT : None */ +/* */ +/* RETURN : */ +/* LOADER_INTERNAL : If p_hloader_config is NULL */ +/* LOADER_OK : Returns this if no error is detected */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY : NA */ +/****************************************************************************/ +PUBLIC t_loader_error HLOADER_StopClock(IN t_loader_config *p_hloader_config) +{ + if (NULL == p_hloader_config) + { + return(LOADER_INTERNAL); + } + + hloader_SetReg(p_hloader_config, HALHA_REG_CLKCMD, 1); + + return(LOADER_OK); +} + +/****************************************************************************/ +/* NAME : HLOADER_StartClock */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION : Start the DSP clock. The DSP to start is identified by */ +/* the t_loader_config passed in parameter */ +/* PARAMETERS : */ +/* IN : p_hloader_config : Device configuration */ +/* OUT : None */ +/* */ +/* RETURN : */ +/* LOADER_INTERNAL : If p_hloader_config is NULL */ +/* LOADER_OK : Returns this if no error is detected */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY : NA */ +/****************************************************************************/ +PUBLIC t_loader_error HLOADER_StartClock(IN t_loader_config *p_hloader_config) +{ + if (NULL == p_hloader_config) + { + return(LOADER_INTERNAL); + } + + hloader_SetReg(p_hloader_config, HALHA_REG_CLKCMD, 0); + + return(LOADER_OK); +} + +/****************************************************************************/ +/* NAME : HLOADER_CacheConfig */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION : Writes the I-cache configuration */ +/* */ +/* PARAMETERS : */ +/* IN : p_hloader_config : Device configuration */ +/* OUT : None */ +/* */ +/* RETURN : */ +/* LOADER_INTERNAL : If p_hloader_config is NULL */ +/* LOADER_OK : Returns this if no error is detected */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY : NA */ +/****************************************************************************/ +PUBLIC t_loader_error HLOADER_CacheConfig(IN t_loader_config *p_hloader_config , t_uint64 cache_mode) +{ + if (NULL == p_hloader_config) + { + return(LOADER_INTERNAL); + } + + /* write I-cache configuration */ + hloader_HamacWriteCtrl(p_hloader_config, HALHA_REG_CACHE_MODE, cache_mode); + +return(LOADER_OK); +} + +/*--------------------------------------------------------------------------* + * Private functions * + *--------------------------------------------------------------------------*/ +/****************************************************************************/ +/* NAME : hloader_CheckAndSetCompat */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION : Check if the firmware can be loaded on the current */ +/* hamac gives the needed compatibility register value. */ +/* if HLOADER_ALLOW_FORCED_COMPAT_VAL is not set in */ +/* p_hloader_config->LoadingInstr then strict match */ +/* between compile architecture and target is required */ +/* PARAMETERS : */ +/* IN : None */ +/* OUT : None */ +/* INOUT : p_hloader_config : Firmware configuration */ +/* RETURN : */ +/* LOADER_BAD_ARCHI: Retun if error is detected */ +/* LOADER_INTERNAL : Retun if core ID doesn't match */ +/* LOADER_OK : Returns this if no error is detected */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY : NA */ +/****************************************************************************/ + +/* Degraded version of the debugger version : we don't treat all cases */ +PRIVATE t_loader_error hloader_CheckAndSetCompat(IN t_loader_config *p_hloader_config) +{ + switch (p_hloader_config->Context.core_id) + { + case TA_8800A_8810A: + case TA_8810A_B0: + if ((HLOADER_MMF_F_HA_FULL == p_hloader_config->Machine) || (HLOADER_MMF_F_HAMACA == p_hloader_config->Machine)) + { + p_hloader_config->Context.compat = COMPAT_DFT_8800; + } else + { + return(LOADER_BAD_ARCHI); + } + break; + + case TA_8800V: + case TA_8810V_A0: + case TA_8810V_B0: + if ((HLOADER_MMF_F_HV_FULL == p_hloader_config->Machine) || (HLOADER_MMF_F_HAMACV == p_hloader_config->Machine)) + { + p_hloader_config->Context.compat = COMPAT_DFT_8800; + } else + { + return(LOADER_BAD_ARCHI); + } + break; + + case TA_8815A_A0: + case TA_8815V_A0: + case TA_8815A_B0: + case TA_8815V_B0: + if (HLOADER_MMF_F_STN8815 == p_hloader_config->Machine) + { + p_hloader_config->Context.compat = COMPAT_DFT_8815_A0; + } else if (HLOADER_MMF_F_HA_FULL == p_hloader_config->Machine) + { + /* Code compiled for 8810 audio can run on the 8815 */ + if (0 == ((t_uint32) p_hloader_config->LoadingInstr & HLOADER_ALLOW_FORCED_COMPAT_VAL)) + { + return(LOADER_BAD_ARCHI); + } else + { + p_hloader_config->Context.compat = COMPAT_8810_8815; + } + } else + { + return(LOADER_BAD_ARCHI); + } + break; + + default: + return(LOADER_INTERNAL); + } + + return(LOADER_OK); +} + +/****************************************************************************/ +/* NAME : hloader_IdentifyHamac */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: Reads the hamac identity registers and identify the version */ +/* PARAMETERS: */ +/* IN : Firmware config */ +/* OUT : p_hloader_config->Context.core_id */ +/* RETURN: */ +/* error_status: LOADER_OK or LOADER_BAD_MACHINE */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PRIVATE t_loader_error hloader_IdentifyHamac(t_loader_config *p_hloader_config) +{ + t_uint8 host0, host1, host2, host3, host4; + + /* Identify target hardware */ + host0 = hloader_GetReg(p_hloader_config, HALHA_REG_IDENT); + host1 = hloader_GetReg(p_hloader_config, HALHA_REG_IDENT0); + host2 = hloader_GetReg(p_hloader_config, HALHA_REG_IDENT1); + host3 = hloader_GetReg(p_hloader_config, HALHA_REG_IDENT2); + host4 = hloader_GetReg(p_hloader_config, HALHA_REG_IDENT3); + + /* Hamac Audio STn8800 audio or Audio STn8810 cut A0 */ + if ((host0 == 0xac) && (host1 == 0xaa) && (host2 == 0x0a) && (host3 == 0x08)) + { + p_hloader_config->Context.core_id = TA_8800A_8810A; + } + + /* Hamac Audio STn8810 cut 2.0 (STn8810 B0) */ + else if ((host0 == 0xac) && (host1 == 0xaa) && (host2 == 0x0a) && (host3 == 0x18)) + { + p_hloader_config->Context.core_id = TA_8810A_B0; + } + + /* Hamac video STn8800 */ + else if ((host0 == 0xac) && (host1 == 0x14) && (host2 == 0x43) && (host3 == 0x15)) + { + p_hloader_config->Context.core_id = TA_8800V; + } + + /* Hamac video full STn8810 A0 */ + else if ((host0 == 0xac) && (host1 == 0x14) && (host2 == 0x43) && (host3 == 0x25)) + { + p_hloader_config->Context.core_id = TA_8810V_A0; + } + + /* Hamac video full cut 2.0 */ + else if ((host0 == 0xac) && (host1 == 0x14) && (host2 == 0x43) && (host3 == 0x35)) + { + p_hloader_config->Context.core_id = TA_8810V_B0; + } + + /* Hamac Audio STn8815 cut 1.0 (STn8815 A0) */ + else if ((host0 == 0xac) && (host1 == 0xaa) && (host2 == 0x0a) && (host3 == 0x28) && (host4 == 0x47)) + { + p_hloader_config->Context.core_id = TA_8815A_A0; + } + + /* Hamac Video STn8815 cut 1.0 (STn8815 A0) */ + else if ((host0 == 0xac) && (host1 == 0xaa) && (host2 == 0x0a) && (host3 == 0x28) && (host4 == 0x57)) + { + p_hloader_config->Context.core_id = TA_8815V_A0; + } + + /* Hamac Audio STn8815 cut 2.0 (STn8815 B0) */ + else if ((host0 == 0xac) && (host1 == 0xaa) && (host2 == 0x0a) && (host3 == 0x38) && (host4 == 0x47)) + { + p_hloader_config->Context.core_id = TA_8815A_B0; + } + + /* Hamac Video STn8815 cut 2.0 (STn8815 B0) */ + else if ((host0 == 0xac) && (host1 == 0xaa) && (host2 == 0x0a) && (host3 == 0x38) && (host4 == 0x57)) + { + p_hloader_config->Context.core_id = TA_8815V_B0; + } + + else + { + p_hloader_config->Context.core_id = TA_UNKNOWN; + return(LOADER_BAD_MACHINE); + } + + return(LOADER_OK); +} + +/****************************************************************************/ +/* NAME : hloader_CheckZoneSize */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: Checks if AHB zone is wide enough to contain the firmware */ +/* section it should contain */ +/* PARAMETERS: */ +/* IN : zone to check */ +/* OUT : */ +/* RETURN: */ +/* error_status: LOADER_OK or LOADER_BAD_BASE */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PRIVATE t_loader_error hloader_CheckZoneSize(t_ahb_zone *p_ahb_zone) +{ + if (0 != p_ahb_zone->Top.logical) + { + if (p_ahb_zone->Size > (p_ahb_zone->Top.logical - p_ahb_zone->Base.logical + 1)) + { + return(LOADER_BAD_BASE); + } + } + + return(LOADER_OK); +} + +/****************************************************************************/ +/* NAME: t_loader_error hloader_CheckSizes( t_loader_config* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: Checks if all zones are wide enough to contain the firmware */ +/* */ +/* PARAMETERS: */ +/* IN : Firmware config */ +/* OUT : */ +/* RETURN: */ +/* error_status: LOADER_OK or LOADER_BAD_BASE */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PRIVATE t_loader_error hloader_CheckSizes(t_loader_config *p_hloader_config) +{ + t_loader_error error_status; + + if (LOADER_OK != (error_status = HLOADER_GetMemSizes(p_hloader_config))) + { + return(error_status); + } + + if (LOADER_OK != (error_status = hloader_CheckZoneSize(&(p_hloader_config->ProgramZone1)))) + { + return(error_status); + } + + if (LOADER_OK != (error_status = hloader_CheckZoneSize(&(p_hloader_config->ProgramZone2)))) + { + return(error_status); + } + + if (LOADER_OK != (error_status = hloader_CheckZoneSize(&(p_hloader_config->Data24Zone1)))) + { + return(error_status); + } + + if (LOADER_OK != (error_status = hloader_CheckZoneSize(&(p_hloader_config->Data24Zone2)))) + { + return(error_status); + } + + if (LOADER_OK != (error_status = hloader_CheckZoneSize(&(p_hloader_config->Data16Zone1)))) + { + return(error_status); + } + + if (LOADER_OK != (error_status = hloader_CheckZoneSize(&(p_hloader_config->Data16Zone2)))) + { + return(error_status); + } + + return(LOADER_OK); +} + +/****************************************************************************/ +/* NAME : hloader_HamacWriteCtrl */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: Writes data to the instruction cache register address */ +/* */ +/* PARAMETERS: */ +/* IN : Firmware config */ +/* OUT : */ +/* RETURN: */ +/* error_status: LOADER_OK or LOADER_BAD_BASE */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PRIVATE void hloader_HamacWriteCtrl(t_loader_config *p_hloader_config, t_uint16 address, t_uint64 data) +{ + t_uint32 count; + + hloader_SetReg(p_hloader_config, HALHA_REG_EMU_UADDRL, (t_uint8) address); + hloader_SetReg(p_hloader_config, HALHA_REG_EMU_UADDRM, 0); + hloader_SetReg(p_hloader_config, HALHA_REG_EMU_UADDRH, 0); + + for (count = 0; count < 8; count++) + { + hloader_SetReg(p_hloader_config, HALHA_REG_EMU_UDATA0 + count, (U8) ((data >> (count * 8)) & 0xFF)); + } + + hloader_SetReg(p_hloader_config, (U8) (HALHA_REG_UCMD), 16); +} + +/* ------------------------------------------------------------------ + * function : hloader_AhbBaseInit8800And8810 + * parameters: Memory Start Address, Memory End Address + * returned value: + * Initialize AHB master bases of 8800 audio, 8810 audio + * -----------------------------------------------------------------*/ +PRIVATE t_loader_error hloader_AhbBaseInit8800And8810(t_loader_config *p_hloader_config) +{ + t_uint32 ext_prg_base_add = p_hloader_config->ProgramZone1.Base.physical; + t_uint32 ext_data24_base_add = p_hloader_config->Data24Zone1.Base.physical; + t_uint32 ext_data16_base_add = p_hloader_config->Data16Zone1.Base.physical; + t_uint32 ext_mmio_base_add = p_hloader_config->MmioZone.Base.physical; + t_uint32 ext_mmio_top_add = p_hloader_config->MmioZone.Top.physical; + + /* Configure Memory base address for program in the ARM memory space */ + hloader_HamacWriteCtrl(p_hloader_config, HALHA_REG_CACHE_PRGBASEADD, ext_prg_base_add); + + /* Configure 24-bit Memory base address for data in the ARM memory space */ + hloader_HamacWriteCtrl + ( + p_hloader_config, + HALHA_REG_CACHE_DATABASEADD, + (((t_uint64) ext_data16_base_add << 32ULL) | ext_data24_base_add) + ); + +#if defined(__STN_8800) + /* Fix for bug VI2212 */ + ext_mmio_top_add = 0xFFFFFFFF; +#endif /* End __STN_8800 */ + + /* Configure 24-bit Memory top address for data in the ARM memory space */ + hloader_HamacWriteCtrl + ( + p_hloader_config, + HALHA_REG_CACHE_DATATOPADD, + (((t_uint64) ext_mmio_base_add << 32ULL) | ext_mmio_top_add) + ); + + return(LOADER_OK); +} + +/* ------------------------------------------------------------------ + * function : hloader_AhbMasterInit8800And8810 + * parameters: Memory Start Address, Memory End Address + * returned value: + * Initialize AHB master of 8800 audio, 8810 audio + * -----------------------------------------------------------------*/ +PRIVATE t_loader_error hloader_AhbMasterInit8800And8810(t_loader_config *p_hloader_config) +{ + U8 value; + t_uint16 vlc_mode = 1; + t_loader_error error_status = LOADER_OK; +#if (defined __EMUL) + t_uint32 count; + t_sint32 delay = 0; +#endif /* End __EMUL */ + + /* Configure bases */ + error_status = hloader_AhbBaseInit8800And8810(p_hloader_config); + + /* Configure The type of access for the I cache */ + hloader_HamacWriteCtrl(p_hloader_config, HALHA_REG_CACHE_PRGAHBCONF, 2); + + /* Configure The type of access for the data buffer */ + hloader_HamacWriteCtrl(p_hloader_config, HALHA_REG_CACHE_DATAAHBCONF, 2); + + /* Configure Timeout */ + hloader_HamacWriteCtrl(p_hloader_config, HALHA_REG_CACHE_TIMEOUT, 1); + + /* Set compression type */ + if (p_hloader_config->Context.compression == HA_VLC_COMPRESSION) + { + vlc_mode = 3; + } else if (p_hloader_config->Machine == HLOADER_MMF_F_HAMACA) + { + vlc_mode = 1; + } else if (p_hloader_config->Machine == HLOADER_MMF_F_HA_FULL) + { + vlc_mode = 5; + } + + if ((p_hloader_config->Machine == HLOADER_MMF_F_HAMACA) || (p_hloader_config->Machine == HLOADER_MMF_F_HA_FULL)) + { + hloader_HamacWriteCtrl(p_hloader_config, HALHA_REG_CACHE_VLCMODE, vlc_mode); + } + + /* necessary to flush Icache : disable memory access from the emulation unit (set bit 3 of bkcmd) */ + value = hloader_GetReg(p_hloader_config, HALHA_REG_BKCMD); + hloader_SetReg(p_hloader_config, HALHA_REG_BKCMD, (t_uint8) (value | 0x8)); + + /* Flush the cache */ + hloader_HamacWriteCtrl(p_hloader_config, HALHA_REG_CACHE_FLUSH, 1); + +#if defined(__EMUL) + for (count = 0; count < 3000; count++) + { + delay = delay + 1; + } +#endif /* End __EMUL */ + hloader_SetReg(p_hloader_config, HALHA_REG_BKCMD, value); + + return(error_status); +} + +/* ------------------------------------------------------------------ + * function : hloader_AhbBaseInit8810B0 + * parameters: Memory Start Address, Memory End Address + * returned value: + * Initialize AHB master bases of hamac in STn8810 cut B0 + * -----------------------------------------------------------------*/ +PRIVATE t_loader_error hloader_AhbBaseInit8810B0(t_loader_config *p_hloader_config) +{ + t_uint32 ext_prg_base_add = p_hloader_config->ProgramZone1.Base.physical ; + t_uint32 ext_prg_base_add2 = p_hloader_config->ProgramZone2.Base.physical ; + + t_uint32 ext_data24_base_add = p_hloader_config->Data24Zone1.Base.physical ; + t_uint32 ext_data24_top_add = p_hloader_config->Data24Zone1.Top.physical ; + + t_uint32 ext_data16_base_add = p_hloader_config->Data16Zone1.Base.physical ; + t_uint32 ext_data16_top_add = p_hloader_config->Data16Zone1.Top.physical ; + + t_uint32 ext_mmio_base_add = p_hloader_config->MmioZone.Base.physical ; + t_uint32 ext_mmio_top_add = p_hloader_config->MmioZone.Top.physical ; + + /* Configure Memory base address for program in the ARM memory space */ + hloader_HamacWriteCtrl(p_hloader_config, HALHA_REG_CACHE_PRGBASEADD, + (((t_uint64)ext_prg_base_add2 << 32ULL) | ext_prg_base_add)); + + /* activate second program base if needed */ + hloader_HamacWriteCtrl(p_hloader_config, HALHA_REG_CACHE_PRGBASE2ACTIVE, + (ext_prg_base_add2 != 0) ? 1 : 0); + + /* Configure 24-bit Memory base address for data in the ARM memory space */ + hloader_HamacWriteCtrl(p_hloader_config, HALHA_REG_CACHE_DATABASEADD, + (((t_uint64)ext_data16_base_add << 32ULL) | ext_data24_base_add)); + + /* Configure 24-bit Memory top address for data in the ARM memory space */ + hloader_HamacWriteCtrl(p_hloader_config, HALHA_REG_CACHE_DATATOPADD, + (((t_uint64)ext_mmio_base_add << 32ULL) | ext_mmio_top_add)); + + /* Configure Base24 Base16 top */ + hloader_HamacWriteCtrl(p_hloader_config, HALHA_REG_DATA_AHB_TOP_16_24, + (((t_uint64) ext_data16_top_add << 32ULL) | ext_data24_top_add)); + + /* activate data top check if needed */ + if (ext_data16_top_add != 0 || ext_data24_top_add != 0) + { + hloader_HamacWriteCtrl(p_hloader_config, HALHA_REG_DATA_TOP1624_CHECK_8810B0, 1); + } + + return(LOADER_OK); +} + +/* ---------------------------------------------------------------------* + * function : hloader_AhbMasterInit8810B0 * + * parameters: Memory Start Address, Memory End Address * + * returned value: * + * Initialize AHB master of hamac in STn8810_B0 * + * ---------------------------------------------------------------------*/ +PRIVATE t_loader_error hloader_AhbMasterInit8810B0(t_loader_config *p_hloader_config) +{ + U8 tmp; + t_uint16 vlc_mode = 1; + t_loader_error error_status = LOADER_OK; +#if (defined __EMUL) + t_uint32 count; + t_sint32 delay = 0; +#endif /* End __EMUL */ + + /* Configure bases */ + error_status = hloader_AhbBaseInit8810B0(p_hloader_config); + + /* Configure The type of access for the I cache */ + hloader_HamacWriteCtrl(p_hloader_config, HALHA_REG_CACHE_PRGAHBCONF, 2); + + + /* Configure The type of access for the data buffer */ + hloader_HamacWriteCtrl(p_hloader_config, HALHA_REG_CACHE_DATAAHBCONF, 2); + + /* Configure Timeout */ + hloader_HamacWriteCtrl(p_hloader_config, HALHA_REG_CACHE_TIMEOUT, 1); + + /* Set compression type */ + if (p_hloader_config->Context.compression == HA_VLC_COMPRESSION) + { + vlc_mode = 3; + } else if (p_hloader_config->Machine == HLOADER_MMF_F_HAMACA) + { + vlc_mode = 1; + } else if (p_hloader_config->Machine == HLOADER_MMF_F_HA_FULL) + { + vlc_mode = 5; + } + + if ((p_hloader_config->Machine == HLOADER_MMF_F_HAMACA) || (p_hloader_config->Machine == HLOADER_MMF_F_HA_FULL)) + { + hloader_HamacWriteCtrl(p_hloader_config, HALHA_REG_CACHE_VLCMODE, vlc_mode); + } + + /* necessary to flush Icache : disable memory access from the emulation unit (set bit 3 of bkcmd) */ + tmp = hloader_GetReg(p_hloader_config, HALHA_REG_BKCMD); + hloader_SetReg (p_hloader_config, HALHA_REG_BKCMD, tmp|0x8); + + /* Flush the cache */ + hloader_HamacWriteCtrl(p_hloader_config, HALHA_REG_CACHE_FLUSH, 1); + +#if defined(__EMUL) + for (count = 0; count < 3000; count++) + { + delay = delay + 1; + } +#endif /* End __EMUL */ + + hloader_SetReg(p_hloader_config, HALHA_REG_BKCMD, tmp); + return(error_status); +} + +/* ------------------------------------------------------------------ + * function : hloader_AhbBaseInit8815 + * parameters: Memory Start Address, Memory End Address + * returned value: + * Initialize AHB master bases of hamac in STn8815 + * -----------------------------------------------------------------*/ +PRIVATE t_loader_error hloader_AhbBaseInit8815(t_loader_config *p_hloader_config) +{ +/* t_uint32 ext_prg_base_add = p_hloader_config->ProgramZone1.Base.physical; + t_uint32 ext_prg_base_add2 = p_hloader_config->ProgramZone2.Base.physical; + + t_uint32 ext_data24_base_add = p_hloader_config->Data24Zone1.Base.physical; + t_uint32 ext_data24_top_add = p_hloader_config->Data24Zone1.Top.physical; + + t_uint32 ext_data16_base_add = p_hloader_config->Data16Zone1.Base.physical; + t_uint32 ext_data16_top_add = p_hloader_config->Data16Zone1.Top.physical; + + t_uint32 ext_data24_base_add2 = p_hloader_config->Data24Zone2.Base.physical; + t_uint32 ext_data24_top_add2 = p_hloader_config->Data24Zone2.Top.physical; + + t_uint32 ext_data16_base_add2 = p_hloader_config->Data16Zone2.Base.physical; + t_uint32 ext_data16_top_add2 = p_hloader_config->Data16Zone2.Top.physical; + + t_uint32 ext_mmio_base_add = p_hloader_config->MmioZone.Base.physical; + t_uint32 ext_mmio_top_add = p_hloader_config->MmioZone.Top.physical; +*/ + t_uint32 ext_prg_base_add; + t_uint32 ext_prg_base_add2 ; + + t_uint32 ext_data24_base_add; + t_uint32 ext_data24_top_add; + + t_uint32 ext_data16_base_add; + t_uint32 ext_data16_top_add; + + t_uint32 ext_data24_base_add2; + t_uint32 ext_data24_top_add2; + + t_uint32 ext_data16_base_add2; + t_uint32 ext_data16_top_add2; + + t_uint32 ext_mmio_base_add; + t_uint32 ext_mmio_top_add; + + + + if (~(p_hloader_config->ProgramZone1.Base.physical & BASE_ALIGNMENT_CHECK_64_BYTE)) + { + ext_prg_base_add = p_hloader_config->ProgramZone1.Base.physical; + } else + { + return(LOADER_BAD_BASE); + } + + if (~(p_hloader_config->ProgramZone2.Base.physical & BASE_ALIGNMENT_CHECK_64_BYTE)) + { + ext_prg_base_add2 = p_hloader_config->ProgramZone2.Base.physical; + } else + { + return(LOADER_BAD_BASE); + } + + if (~(p_hloader_config->Data24Zone1.Base.physical & BASE_ALIGNMENT_CHECK_32_BYTE)) + { + ext_data24_base_add = p_hloader_config->Data24Zone1.Base.physical; + ext_data24_top_add = p_hloader_config->Data24Zone1.Top.physical; + } else + { + return(LOADER_BAD_BASE); + } + + if (~(p_hloader_config->Data16Zone1.Base.physical & BASE_ALIGNMENT_CHECK_32_BYTE)) + { + ext_data16_base_add = p_hloader_config->Data16Zone1.Base.physical; + ext_data16_top_add = p_hloader_config->Data16Zone1.Top.physical; + } else + { + return(LOADER_BAD_BASE); + } + + if (~(p_hloader_config->Data24Zone2.Base.physical & BASE_ALIGNMENT_CHECK_32_BYTE)) + { + ext_data24_base_add2 = p_hloader_config->Data24Zone2.Base.physical; + ext_data24_top_add2 = p_hloader_config->Data24Zone2.Top.physical; + } else + { + return(LOADER_BAD_BASE); + } + + if (~(p_hloader_config->Data16Zone2.Base.physical & BASE_ALIGNMENT_CHECK_32_BYTE)) + { + ext_data16_base_add2 = p_hloader_config->Data16Zone2.Base.physical; + ext_data16_top_add2 = p_hloader_config->Data16Zone2.Top.physical; + } else + { + return(LOADER_BAD_BASE); + } + if (~(p_hloader_config->MmioZone.Base.physical & BASE_ALIGNMENT_CHECK_32_BYTE)) + { + ext_mmio_base_add = p_hloader_config->MmioZone.Base.physical; + ext_mmio_top_add = p_hloader_config->MmioZone.Top.physical; + } else + { + return(LOADER_BAD_BASE); + } + + /* Configure Memory base address for program in the ARM memory space */ + hloader_HamacWriteCtrl + ( + p_hloader_config, + HALHA_REG_CACHE_PRGBASEADD, + (((t_uint64) ext_prg_base_add2 << 32ULL) | ext_prg_base_add) + ); + + /* activate second program base if needed */ + hloader_HamacWriteCtrl(p_hloader_config, HALHA_REG_CACHE_PRGBASE2ACTIVE, (ext_prg_base_add2 != 0) ? 1 : 0); + + /* Configure 24-bit Memory base address for data in the ARM memory space */ + hloader_HamacWriteCtrl + ( + p_hloader_config, + HALHA_REG_CACHE_DATABASEADD, + (((t_uint64) ext_data16_base_add << 32ULL) | ext_data24_base_add) + ); + + /* Configure 24-bit Memory top address for data in the ARM memory space */ + hloader_HamacWriteCtrl + ( + p_hloader_config, + HALHA_REG_CACHE_DATATOPADD, + (((t_uint64) ext_mmio_base_add << 32ULL) | ext_mmio_top_add) + ); + + /* Configure Base24 Base16 top */ + hloader_HamacWriteCtrl + ( + p_hloader_config, + HALHA_REG_DATA_AHB_TOP_16_24, + (((t_uint64) ext_data16_top_add << 32ULL) | ext_data24_top_add) + ); + + /* Configure internal SRAM Base16 Base24 */ + hloader_HamacWriteCtrl + ( + p_hloader_config, + HALHA_REG_CACHE_DATABASEADD2, + (((t_uint64) ext_data16_base_add2 << 32ULL) | ext_data24_base_add2) + ); + + /* activate internal SRAM if needed */ + hloader_HamacWriteCtrl + ( + p_hloader_config, + HALHA_REG_CACHE_DATABASE2ACTIVE, + ((ext_data16_base_add2 != 0) || (ext_data24_base_add2 != 0)) ? 1 : 0 + ); + + /* Configure internal SRAM Base24 Base16 top */ + hloader_HamacWriteCtrl + ( + p_hloader_config, + HALHA_REG_DATA_AHB_TOP2_16_24, + (((t_uint64) ext_data16_top_add2 << 32ULL) | ext_data24_top_add2) + ); + + /* activate data top check if needed */ + if (ext_data16_top_add != 0 || ext_data24_top_add != 0 || ext_data16_top_add2 != 0 || ext_data24_top_add2 != 0) + { + hloader_HamacWriteCtrl(p_hloader_config, HALHA_REG_DATA_TOP1624_CHECK, 1); + } + + /* Change I-Cache burst size */ + hloader_HamacWriteCtrl(p_hloader_config, HALHA_REG_CACHE_PRG_BURST_SIZE, 0x0); + + /* Configure XRAM partitioning between ESRAM and SDRAM */ + hloader_HamacWriteCtrl + ( + p_hloader_config, + HALHA_REG_DATA2_1624_XA_BASE, + (((HAMAC_XBUS_EXT_DATA16_2_BASE & 0xFF0000) >> 16) << 32ULL) | + ((HAMAC_XBUS_EXT_DATA24_2_BASE & 0xFF0000) >> 16) + ); + + return(LOADER_OK); +} + +/* ------------------------------------------------------------------ + * function : hloader_AhbBaseInit8815 + * parameters: Memory Start Address, Memory End Address + * returned value: + * Initialize AHB master of hamac in STn8815 + * -----------------------------------------------------------------*/ +PRIVATE t_loader_error hloader_AhbMasterInit8815(t_loader_config *p_hloader_config) +{ + U8 value; + t_loader_error error_status = LOADER_OK; +#if defined(__EMUL) + t_uint32 count; + t_sint32 delay = 0; +#endif /* End __EMUL */ + error_status = hloader_AhbBaseInit8815(p_hloader_config); + + /* Configure The type of access for the I cache */ + hloader_HamacWriteCtrl(p_hloader_config, HALHA_REG_CACHE_PRGAHBCONF, 2); + + /* Configure The type of access for the data buffer */ + hloader_HamacWriteCtrl(p_hloader_config, HALHA_REG_CACHE_DATAAHBCONF, 2); + + /* Configure Timeout */ + hloader_HamacWriteCtrl(p_hloader_config, HALHA_REG_CACHE_TIMEOUT, 1); + + /* necessary to flush Icache : disable memory access from the emulation unit (set bit 3 of bkcmd) */ + value = hloader_GetReg(p_hloader_config, HALHA_REG_BKCMD); + hloader_SetReg(p_hloader_config, HALHA_REG_BKCMD, (t_uint8) (value | 0x8)); + + /* Flush the cache */ + hloader_HamacWriteCtrl(p_hloader_config, HALHA_REG_CACHE_FLUSH, 1); + +#if defined(__EMUL) + for (count = 0; count < 3000000; count++) + { + delay = delay + 1; + } +#endif /* End __EMUL */ + hloader_SetReg(p_hloader_config, HALHA_REG_BKCMD, value); + + return(error_status); +} + +/* ------------------------------------------------------------------ + * function : hloader_SoftReset + * parameters: loader config + * returned value: none + * Description: + * Performs a software reset of the audio or video decoder + * audio decoder goes back to idle mode + -----------------------------------------------------------------*/ +PRIVATE t_loader_error hloader_SoftReset(t_loader_config *p_hloader_config) +{ + U8 value; + + /* Soft reset of the PC */ + hloader_SetReg(p_hloader_config, HALHA_REG_SOFTRESET, 1); + + /* Disable memory access from the emulation unit (set bit 3 of bkcmd) */ + value = hloader_GetReg(p_hloader_config, HALHA_REG_BKCMD); + hloader_SetReg(p_hloader_config, HALHA_REG_BKCMD, (t_uint8) (value | 0x8)); + + /* Hamac Video requires a 16 bits access */ + *( + (volatile U16 *) + ( + (HAMAC_MMIO_COMPATIBILITY_32 * 2) + + p_hloader_config->HamacBaseAddr.logical + + HAMACV_DATA_BASE_16_OFFSET + ) + ) = (t_uint16) p_hloader_config->Context.compat; + + /* Enabling Data Cache in Data cache conf. registers */ + *( + (volatile U16 *) + ((HLOADER_MMIO_DATA_CACHE * 2) + p_hloader_config->HamacBaseAddr.logical + HAMACV_DATA_BASE_16_OFFSET) + ) |= (t_uint16) HLOADER_MMIO_DATA_CACHE_EN_VAL; + + return(LOADER_OK); +} + +/****************************************************************************/ +/* NAME : hloader_CheckFileHeader */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION : Reads the file header located at *p_file_header and */ +/* check that its magic number and file version are OK. */ +/* */ +/* PARAMETERS: */ +/* IN : p_file_header : File header to check. */ +/* */ +/* */ +/* */ +/* RETURN : LOADER_OK : If OK */ +/* LOADER_BAD_MAGIC_CODE : If magic code is incorrect */ +/* LOADER_BAD_FILE_VERSION : If MMF version is not */ +/* supported by this loader */ +/* version */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PRIVATE t_loader_error hloader_CheckFileHeader(t_file_header *p_file_header) +{ + t_uint32 f_magic; + t_uint16 f_flags; + + if (p_file_header == NULL) + { + return(LOADER_INTERNAL); + } + + /* Magic code checking */ + f_magic = p_file_header->f_magic; + f_flags = p_file_header->f_flags; + + SWAPENDIANNESS32(f_magic); + SWAPENDIANNESS16(f_flags); + + if (f_magic != HLOADER_F_MAGIC) + { + return(LOADER_BAD_MAGIC_CODE); + } + + /* MMF version checking: This loader support * + * current version and version MMF_VER_10 */ + if + ( + ((f_flags & MMF_VERSION_MASK) != HLOADER_MMF_F_CURVER) + && ((f_flags & MMF_VERSION_MASK) != HLOADER_MMF_F_VER11) + && ((f_flags & MMF_VERSION_MASK) != HLOADER_MMF_F_VER10) + ) + { + return(LOADER_BAD_FILE_VERSION); + } + + return(LOADER_OK); +} + +/****************************************************************************/ +/* NAME : hloader_GetSectionSize */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION : Get section size */ +/* PARAMETERS : */ +/* IN : None */ +/* OUT : None */ +/* INOUT : p_hloader_config : Device configuration */ +/* p_cur_section_addr : Pointer to current section */ +/* RETURN : */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY : NA */ +/****************************************************************************/ +PRIVATE t_loader_error hloader_GetSectionSize(t_loader_config *p_hloader_config, t_uint32 *p_cur_section_addr) +{ + t_section_header *p_section_header; + t_uint16 s_memtype; + t_uint32 s_size; + t_uint32 s_addr; + + p_section_header = (t_section_header *) p_cur_section_addr; + + if ((p_section_header == NULL) || (p_hloader_config == NULL)) + { + return(LOADER_INTERNAL); + } + + s_memtype = p_section_header->s_memtype; + s_size = p_section_header->s_size; + s_addr = p_section_header->s_addr; + + SWAPENDIANNESS16(s_memtype); + SWAPENDIANNESS32(s_size); + SWAPENDIANNESS32(s_addr); + + switch (s_memtype) + { + case MMF_MT_PROGRAM_MEM: + case MMF_MT_HA_VLC_CODE: + case MMF_MT_HV_COMP_CODE: + p_hloader_config->ProgramZone1.Size = MAX(p_hloader_config->ProgramZone1.Size, ((s_addr * 8) + s_size)); + break; + + case MMF_MT_ESRAM_PMEM: + p_hloader_config->ProgramZone2.Size = MAX + ( + p_hloader_config->ProgramZone2.Size, + (((s_addr - 0xE0000) * 8) + s_size) + ); + break; + + case MMF_MT_HA_EXT16: + p_hloader_config->Data16Zone1.Size = MAX + ( + p_hloader_config->Data16Zone1.Size, + ((s_addr - 0x800000) * 2) + s_size / 2 + ); + break; + + case MMF_MT_HA_EXT24: + p_hloader_config->Data24Zone1.Size = MAX(p_hloader_config->Data24Zone1.Size, ((s_addr - 0x10000) * 4) + s_size); + break; + + case MMF_MT_ESRAM_EXT16: + p_hloader_config->Data16Zone2.Size = MAX + ( + p_hloader_config->Data16Zone2.Size, + ((s_addr - HAMAC_XBUS_EXT_DATA16_2_BASE) * 2) + s_size / 2 + ); + break; + + case MMF_MT_ESRAM_EXT24: + p_hloader_config->Data24Zone2.Size = MAX + ( + p_hloader_config->Data24Zone2.Size, + ((s_addr - 0x400000) * 4) + s_size + ); + break; + + case MMF_MT_X_MEM: + case MMF_MT_Y_MEM: + case MMF_MT_WS_MEM: + case MMF_MT_HOST_MEM: + case MMF_MT_HA_VLC_LUT: + case MMF_MT_HV_DICT: + break; + + default: + return(LOADER_UKN_MEMTYPE); + } + + return(LOADER_OK); +} + +/****************************************************************************/ +/* NAME : hloader_ProcessSection */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: Reads the section header located at CurSecAddr, and performs*/ +/* the treatment according to p_hloader_config. */ +/* */ +/* PARAMETERS: */ +/* IN : p_hloader_config: Loader input parameters. */ +/* Filled by API user. */ +/* IN/OUT : p_cur_section_addr: Current section descriptor address. */ +/* */ +/* RETURN: t_loader_error: LOADER_OK or any error code */ +/* */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PRIVATE t_loader_error hloader_ProcessSection(t_loader_config *p_hloader_config, t_uint32 *p_cur_section_addr) +{ + t_section_header *p_section_header; + t_loader_error error_status; + + p_section_header = (t_section_header *) p_cur_section_addr; + + if ((p_section_header == NULL) || (p_hloader_config == NULL)) + { + return(LOADER_INTERNAL); + } + + SWAPENDIANNESS16(p_section_header->s_type); + SWAPENDIANNESS16(p_section_header->s_memtype); + SWAPENDIANNESS16(p_section_header->s_flags); + SWAPENDIANNESS16(p_section_header->s_bpw); + SWAPENDIANNESS32(p_section_header->s_size); + SWAPENDIANNESS32(p_section_header->s_offset); + SWAPENDIANNESS32(p_section_header->s_addr); + +#ifdef MMDSPTOOLS + if ((t_uint32) p_hloader_config->LoadingInstr & HLOADER_DUMP_VAL) + { + hloader_MmDspDisplaySectionHeader(p_section_header); + } +#endif /* End MMDSPTOOLS */ + if (p_section_header->s_type != MMF_SHT_NOBITS) + { + switch (p_section_header->s_memtype) + { + case MMF_MT_PROGRAM_MEM: //SDRAM + case MMF_MT_ESRAM_PMEM: //ESRAM + p_hloader_config->Context.nb_code_sections++; + + if ((t_uint32) p_hloader_config->LoadingInstr & HLOADER_LOAD_CODE_VAL) + { + error_status = hloader_CopyCodeSection(p_hloader_config, p_section_header); + if (error_status != LOADER_OK) + { + return(error_status); + } + } + +#ifdef MMDSPTOOLS + if ((t_uint32) p_hloader_config->LoadingInstr & HLOADER_CHECK_CODE_VAL) + { + error_status = hloader_CheckCodeSection(p_hloader_config, p_section_header); + if (error_status != LOADER_OK) + { + return(error_status); + } + } + + if ((t_uint32) p_hloader_config->LoadingInstr & HLOADER_DUMP_SECTION_VAL) + { + error_status = hloader_DumpCodeSection(p_hloader_config, p_section_header); + if (error_status != LOADER_OK) + { + return(error_status); + } + } +#endif /* End MMDSPTOOLS */ + if + ( + (((t_uint32) p_hloader_config->LoadingInstr & HLOADER_LOAD_CODE_VAL) == 0) + && (p_hloader_config->Context.nb_code_sections > 1) + ) + { + /* We were instructed not to copy the code, but there are more * + * than one code sec, so we don't garantee the code is loaded */ + return(LOADER_CODE_NOT_LOADED); + } + break; + + case MMF_MT_X_MEM: //LOCAL SAA + case MMF_MT_Y_MEM: //LOCAL SAA + case MMF_MT_HA_EXT16: //SDRAM + case MMF_MT_HA_EXT24: //SDRAM + case MMF_MT_ESRAM_EXT24: //ESRAM + case MMF_MT_ESRAM_EXT16: //ESRAM + if ((t_uint32) p_hloader_config->LoadingInstr & HLOADER_LOAD_DATA_VAL) + { + error_status = hloader_CopyDataSection(p_hloader_config, p_section_header); + if (error_status != LOADER_OK) + { + return(error_status); + } + } + +#ifdef MMDSPTOOLS + if ((t_uint32) p_hloader_config->LoadingInstr & HLOADER_CHECK_DATA_VAL) + { + error_status = hloader_CheckDataSection(p_hloader_config, p_section_header); + if (error_status != LOADER_OK) + { + return(error_status); + } + } + + if ((t_uint32) p_hloader_config->LoadingInstr & HLOADER_DUMP_SECTION_VAL) + { + error_status = hloader_DumpDataSection(p_hloader_config, p_section_header); + if (error_status != LOADER_OK) + { + return(error_status); + } + } +#endif /* End MMDSPTOOLS */ + break; + + case MMF_MT_HA_VLC_CODE: + /* Set compression */ + p_hloader_config->Context.compression = HA_VLC_COMPRESSION; + p_hloader_config->Context.nb_code_sections++; + + if ((t_uint32) p_hloader_config->LoadingInstr & HLOADER_LOAD_CODE_VAL) + { + error_status = hloader_CopySaaVlcSection(p_hloader_config, p_section_header); + if (error_status != LOADER_OK) + { + return(error_status); + } + } + +#ifdef MMDSPTOOLS + if ((t_uint32) p_hloader_config->LoadingInstr & HLOADER_CHECK_CODE_VAL) + { + error_status = hloader_CheckSaaVlcSection(p_hloader_config, p_section_header); + if (error_status != LOADER_OK) + { + return(error_status); + } + } + + if ((t_uint32) p_hloader_config->LoadingInstr & HLOADER_DUMP_SECTION_VAL) + { + error_status = hloader_DumpSaaVlcSection(p_hloader_config, p_section_header); + if (error_status != LOADER_OK) + { + return(error_status); + } + } +#endif /* End MMDSPTOOLS */ + if (p_hloader_config->Context.nb_code_sections > 1) + { /* By construction a MMF file should not contain more * + * than one code section when it has VLC compression */ + return(LOADER_INTERNAL); + } + break; + + case MMF_MT_HA_VLC_LUT: + /* LUT needs to be loaded even if we don't copy the * + * code section, so don't check against HLOADER_LOAD_CODE_VAL. * + * However don't load if we actually just dump */ + /* if ( (t_uint32)p_hloader_config->LoadingInstr & HLOADER_LOAD_CODE_VAL ) { */ + if (((t_uint32) p_hloader_config->LoadingInstr & (HLOADER_DUMP_VAL | HLOADER_DUMP_SECTION_VAL)) == 0) + { + error_status = hloader_CopySaaLutSection(p_hloader_config, p_section_header); + if (error_status != LOADER_OK) + { + return(error_status); + } + } + + /* } */ +#ifdef MMDSPTOOLS + if ((t_uint32) p_hloader_config->LoadingInstr & HLOADER_CHECK_CODE_VAL) + { + error_status = hloader_CheckSaaLutSection(p_hloader_config, p_section_header); + if (error_status != LOADER_OK) + { + return(error_status); + } + } + + if ((t_uint32) p_hloader_config->LoadingInstr & HLOADER_DUMP_SECTION_VAL) + { + error_status = hloader_DumpSaaVlcSection(p_hloader_config, p_section_header); + if (error_status != LOADER_OK) + { + return(error_status); + } + } +#endif /* End MMDSPTOOLS */ + break; + + case MMF_MT_HV_COMP_CODE: + p_hloader_config->Context.nb_code_sections++; + p_hloader_config->Context.compression = HV_DICT_COMPRESSION; + + /* Inst. needs to be loaded even if we don't copy * + * the code section, so don't check against HLOADER_LOAD_CODE_VAL. * + * However don't load if we actually just dump */ + /* if ( (t_uint32)p_hloader_config->LoadingInstr & HLOADER_LOAD_CODE_VAL ) { */ + if (((t_uint32) p_hloader_config->LoadingInstr & (HLOADER_DUMP_VAL | HLOADER_DUMP_SECTION_VAL)) == 0) + { + error_status = hloader_CopySvaCodeSection(p_hloader_config, p_section_header); + if (error_status != LOADER_OK) + { + return(error_status); + } + } + + /* } */ +#ifdef MMDSPTOOLS + if ((t_uint32) p_hloader_config->LoadingInstr & HLOADER_CHECK_CODE_VAL) + { + error_status = hloader_CheckSvaCodeSection(p_hloader_config, p_section_header); + if (error_status != LOADER_OK) + { + return(error_status); + } + } + + if ((t_uint32) p_hloader_config->LoadingInstr & HLOADER_DUMP_SECTION_VAL) + { + error_status = hloader_DumpSaaVlcSection(p_hloader_config, p_section_header); + if (error_status != LOADER_OK) + { + return(error_status); + } + } +#endif /* End MMDSPTOOLS */ + break; + + case MMF_MT_HV_DICT: + /* Inst. needs to be loaded even if we don't copy * + * the code section, so don't check against HLOADER_LOAD_CODE_VAL. * + * However don't load if we actually just dump */ + /* if ( (t_uint32)p_hloader_config->LoadingInstr & HLOADER_LOAD_CODE_VAL ) { */ + if (0 == ((t_uint32) p_hloader_config->LoadingInstr & (HLOADER_DUMP_VAL | HLOADER_DUMP_SECTION_VAL))) + { + error_status = hloader_CopySvaDictSection(p_hloader_config, p_section_header); + if (error_status != LOADER_OK) + { + return(error_status); + } + } + + /* } */ +#ifdef MMDSPTOOLS + if ((t_uint32) p_hloader_config->LoadingInstr & HLOADER_CHECK_CODE_VAL) + { + error_status = hloader_CheckSvaDictSection(p_hloader_config, p_section_header); + if (error_status != LOADER_OK) + { + return(error_status); + } + } + + if ((t_uint32) p_hloader_config->LoadingInstr & HLOADER_DUMP_SECTION_VAL) + { + error_status = hloader_DumpCodeSection(p_hloader_config, p_section_header); + if (error_status != LOADER_OK) + { + return(error_status); + } + } +#endif /* End MMDSPTOOLS */ + break; + + default: + return(LOADER_UKN_MEMTYPE); + } + } + + /* No error detected within this function. */ + return(LOADER_OK); +} + +PRIVATE t_loader_error hloader_PartialProcessSection(t_loader_config *p_hloader_config, t_uint32 *p_cur_section_addr) +{ + t_section_header *p_section_header; + t_loader_error error_status; + + p_section_header = (t_section_header *) p_cur_section_addr; + + if ((p_section_header == NULL) || (p_hloader_config == NULL)) + { + return(LOADER_INTERNAL); + } + + SWAPENDIANNESS16(p_section_header->s_type); + SWAPENDIANNESS16(p_section_header->s_memtype); + SWAPENDIANNESS16(p_section_header->s_flags); + SWAPENDIANNESS16(p_section_header->s_bpw); + SWAPENDIANNESS32(p_section_header->s_size); + SWAPENDIANNESS32(p_section_header->s_offset); + SWAPENDIANNESS32(p_section_header->s_addr); + +#ifdef MMDSPTOOLS + if ((t_uint32) p_hloader_config->LoadingInstr & HLOADER_DUMP_VAL) + { + hloader_MmDspDisplaySectionHeader(p_section_header); + } +#endif /* End MMDSPTOOLS */ + if (p_section_header->s_type != MMF_SHT_NOBITS) + { + switch (p_section_header->s_memtype) + { + case MMF_MT_PROGRAM_MEM: + return(LOADER_OK); + + case MMF_MT_ESRAM_PMEM: + p_hloader_config->Context.nb_code_sections++; + + if ((t_uint32) p_hloader_config->LoadingInstr & HLOADER_LOAD_CODE_VAL) + { + error_status = hloader_CopyCodeSection(p_hloader_config, p_section_header); + if (error_status != LOADER_OK) + { + return(error_status); + } + } + +#ifdef MMDSPTOOLS + if ((t_uint32) p_hloader_config->LoadingInstr & HLOADER_CHECK_CODE_VAL) + { + error_status = hloader_CheckCodeSection(p_hloader_config, p_section_header); + if (error_status != LOADER_OK) + { + return(error_status); + } + } + + if ((t_uint32) p_hloader_config->LoadingInstr & HLOADER_DUMP_SECTION_VAL) + { + error_status = hloader_DumpCodeSection(p_hloader_config, p_section_header); + if (error_status != LOADER_OK) + { + return(error_status); + } + } +#endif /* End MMDSPTOOLS */ + if + ( + (((t_uint32) p_hloader_config->LoadingInstr & HLOADER_LOAD_CODE_VAL) == 0) + && (p_hloader_config->Context.nb_code_sections > 1) + ) + { + /* We were instructed not to copy the code, but there are more * + * than one code sec, so we don't garantee the code is loaded */ + return(LOADER_CODE_NOT_LOADED); + } + break; + + case MMF_MT_X_MEM: + case MMF_MT_Y_MEM: + case MMF_MT_ESRAM_EXT24: + case MMF_MT_ESRAM_EXT16: + if ((t_uint32) p_hloader_config->LoadingInstr & HLOADER_LOAD_DATA_VAL) + { + error_status = hloader_CopyDataSection(p_hloader_config, p_section_header); + if (error_status != LOADER_OK) + { + return(error_status); + } + } + +#ifdef MMDSPTOOLS + if ((t_uint32) p_hloader_config->LoadingInstr & HLOADER_CHECK_DATA_VAL) + { + error_status = hloader_CheckDataSection(p_hloader_config, p_section_header); + if (error_status != LOADER_OK) + { + return(error_status); + } + } + + if ((t_uint32) p_hloader_config->LoadingInstr & HLOADER_DUMP_SECTION_VAL) + { + error_status = hloader_DumpDataSection(p_hloader_config, p_section_header); + if (error_status != LOADER_OK) + { + return(error_status); + } + } +#endif /* End MMDSPTOOLS */ + break; + + case MMF_MT_WS_MEM: + case MMF_MT_HOST_MEM: + case MMF_MT_HA_EXT24: + case MMF_MT_HA_EXT16: + case MMF_MT_HA_VLC_CODE: + case MMF_MT_HA_VLC_LUT: + case MMF_MT_HV_COMP_CODE: + case MMF_MT_HV_DICT: + return(LOADER_OK); + + default: + return(LOADER_UKN_MEMTYPE); + } + } + + /* No error detected within this function. */ + return(LOADER_OK); +} + +/****************************************************************************/ +/* NAME : hloader_CopyCodeSection */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: Copy the current code section following the configuration */ +/* of the loader and the current section header. */ +/* PARAMETERS: */ +/* IN : *p_hloader_config: Loader input parameters. */ +/* Filled by API user. */ +/* *p_section_header: Pointer on current section header. */ +/* OUT: None */ +/* RETURN: t_loader_error: always LOADER_OK */ +/* */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PRIVATE t_loader_error hloader_CopyCodeSection(t_loader_config *p_hloader_config, t_section_header *p_section_header) +{ + /* FIXME why cast to t_sint8* ??? */ + t_uint32 count; + t_uint32 *p_src_index; + t_uint32 *p_dest_index; + + if ((p_section_header == NULL) || (p_hloader_config == NULL)) + { + return(LOADER_INTERNAL); + } + + p_src_index = (t_uint32 *) ((t_sint8 *) p_hloader_config->FirmwareBaseAddr + p_section_header->s_offset); + if (HLOADER_MT_PROGRAM_MEM_VAL == p_section_header->s_memtype) + { + p_dest_index = (t_uint32 *) (p_hloader_config->ProgramZone1.Base.logical + (p_section_header->s_addr * 8)); + } else + { + p_dest_index = (t_uint32 *) (p_hloader_config->ProgramZone2.Base.logical + ((p_section_header->s_addr - 0xE0000) * 8)); + } + + if ((p_src_index == NULL) || (p_dest_index == NULL)) + { + return(LOADER_INTERNAL); + } + + for (count = 0; count < p_section_header->s_size / 8; count++) + { + *p_dest_index++ = *p_src_index++; + *p_dest_index++ = *p_src_index++; + } + + /* No error detected within this function. */ + return(LOADER_OK); +} + +/****************************************************************************/ +/* NAME : hloader_CalculateDestIndex */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: Calculate the address in ARM space of the given section */ +/* */ +/* PARAMETERS: */ +/* IN : *p_hloader_config: Loader input parameters. */ +/* */ +/* *p_section_header: Pointer on current section header. */ +/* OUT: p_dest_index, p_short_dest_index */ +/* RETURN: t_loader_error: LOADER_BAD_BASE if bases for the section*/ +/* are not configured */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PRIVATE t_loader_error hloader_CalculateDestIndex +( +t_loader_config *p_hloader_config, +t_section_header *p_section_header, +t_uint32 **p_dest_index, +t_uint16 **p_short_dest_index +) +{ + /* pointer for long accesses */ + if (IS_HA_EXT_MEMORY16(p_section_header->s_memtype)) + { + if (p_hloader_config->Data16Zone1.Base.logical == 0) + { + return(LOADER_BAD_BASE); + } + + *p_dest_index = (t_uint32 *) (p_hloader_config->Data16Zone1.Base.logical + ((p_section_header->s_addr - 0x800000) * 4)); + *p_short_dest_index = (t_uint16 *) (p_hloader_config->Data16Zone1.Base.logical + ((p_section_header->s_addr - 0x800000) * 2)); + } else if (IS_HA_EXT_MEMORY24(p_section_header->s_memtype)) + { + if (p_hloader_config->Data24Zone1.Base.logical == 0) + { + return(LOADER_BAD_BASE); + } + + *p_dest_index = (t_uint32 *) (p_hloader_config->Data24Zone1.Base.logical + ((p_section_header->s_addr - 0x10000) * 4)); + *p_short_dest_index = (t_uint16 *) (p_hloader_config->Data24Zone1.Base.logical + ((p_section_header->s_addr - 0x10000) * 2)); + } else if (IS_ESRAM_EXT_MEMORY16(p_section_header->s_memtype)) + { + if (p_hloader_config->Data16Zone2.Base.logical == 0) + { + return(LOADER_BAD_BASE); + } + + *p_dest_index = (t_uint32 *) (p_hloader_config->Data16Zone2.Base.logical + ((p_section_header->s_addr - (t_uint32) HAMAC_XBUS_EXT_DATA16_2_BASE) * 4)); + *p_short_dest_index = (t_uint16 *) (p_hloader_config->Data16Zone2.Base.logical + ((p_section_header->s_addr - (t_uint32) HAMAC_XBUS_EXT_DATA16_2_BASE) * 2)); + } else if (IS_ESRAM_EXT_MEMORY24(p_section_header->s_memtype)) + { + if (p_hloader_config->Data24Zone2.Base.logical == 0) + { + return(LOADER_BAD_BASE); + } + + *p_dest_index = (t_uint32 *) (p_hloader_config->Data24Zone2.Base.logical + ((p_section_header->s_addr - 0x400000) * 4)); + *p_short_dest_index = (t_uint16 *) (p_hloader_config->Data24Zone2.Base.logical + ((p_section_header->s_addr - 0x400000) * 2)); + } else + { + *p_dest_index = (t_uint32 *) (p_hloader_config->HamacBaseAddr.logical + (p_section_header->s_addr * 4)); + *p_short_dest_index = (t_uint16 *) (p_hloader_config->HamacBaseAddr.logical + (p_section_header->s_addr * 2) + HAMACA_DATA_BASE_16_OFFSET); + } + + return(LOADER_OK); +} + +/****************************************************************************/ +/* NAME : hloader_CopyDataSection */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: Copy the current data section following the configuration */ +/* of the loader and the current section header. */ +/* PARAMETERS: */ +/* IN : *p_hloader_config: Loader input parameters. */ +/* Filled by API user. */ +/* *p_section_header: Pointer on current section header. */ +/* OUT: None */ +/* RETURN: t_loader_error: */ +/* */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PRIVATE t_loader_error hloader_CopyDataSection(t_loader_config *p_hloader_config, t_section_header *p_section_header) +{ + t_uint32 *p_src_index, *p_dest_index = 0; + t_uint16 *p_short_src_index, *p_short_dest_index = 0; + t_uint32 count; + t_loader_error error_status; + + if ((p_section_header == NULL) || (p_hloader_config == NULL)) + { + return(LOADER_INTERNAL); + } + + p_src_index = (t_uint32 *) ((t_sint8 *) p_hloader_config->FirmwareBaseAddr + p_section_header->s_offset); + p_short_src_index = (t_uint16 *) ((t_sint8 *) p_hloader_config->FirmwareBaseAddr + p_section_header->s_offset); + + if + ( + ( + error_status = hloader_CalculateDestIndex + ( + p_hloader_config, + p_section_header, + &p_dest_index, + &p_short_dest_index + ) + ) != LOADER_OK + ) + { + return(error_status); + } + + if ((p_short_src_index == NULL) || (p_short_dest_index == NULL)) + { + return(LOADER_INTERNAL); + } + + if ((p_src_index == NULL) || (p_dest_index == NULL)) + { + return(LOADER_INTERNAL); + } + + if + ( + ((t_uint16) THREE_BYTES_PER_WORD == p_section_header->s_bpw) + && (HLOADER_MMF_F_HAMACV != p_hloader_config->Machine) + && (HLOADER_MMF_F_HV_FULL != p_hloader_config->Machine) + && (!(IS_HA_EXT_MEMORY16(p_section_header->s_memtype))) + && (!(IS_ESRAM_EXT_MEMORY16(p_section_header->s_memtype))) + ) + { + for (count = 0; count < p_section_header->s_size / 4; count++) + { + *p_dest_index++ = *p_src_index++; + } + } else if (p_section_header->s_bpw == (t_uint16) THREE_BYTES_PER_WORD) + { + for (count = 0; count < p_section_header->s_size / 4; count++) + { + *p_short_dest_index = *p_short_src_index; + p_short_dest_index++; + p_short_src_index++; + p_short_src_index++; /* To discard two bytes */ + } + } else if (p_section_header->s_bpw == (t_uint16) TWO_BYTES_PER_WORD) + { + for (count = 0; count < p_section_header->s_size / 4; count++) + { + *p_dest_index++ = *p_src_index++; + } + } + + /* No error detected within this function. */ + return(LOADER_OK); +} + +/****************************************************************************/ +/* NAME : hloader_CopySaaLutSection */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: Copy the current ha lut section following the configuration */ +/* of the loader and the current section header. */ +/* PARAMETERS: */ +/* IN : *p_hloader_config: Loader input parameters. */ +/* Filled by API user. */ +/* *p_section_header: Pointer on current section header. */ +/* OUT: None */ +/* RETURN: t_loader_error: LOADER_OK */ +/* */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PRIVATE t_loader_error hloader_CopySaaLutSection(t_loader_config *p_hloader_config, t_section_header *p_section_header) +{ + t_uint32 count; + t_uint32 *p_src_index; + U8 value; + + if ((p_section_header == NULL) || (p_hloader_config == NULL)) + { + return(LOADER_INTERNAL); + } + + /* Enable memory access from the emulation unit (clear bit 3 of bkcmd) */ + value = hloader_GetReg(p_hloader_config, HALHA_REG_BKCMD); + hloader_SetReg(p_hloader_config, HALHA_REG_BKCMD, (t_uint8) (value & 0x7)); + + p_src_index = (t_uint32 *) ((t_sint8 *) p_hloader_config->FirmwareBaseAddr + p_section_header->s_offset); + + if (p_src_index == NULL) + { + return(LOADER_INTERNAL); + } + + hloader_SetReg(p_hloader_config, HALHA_REG_EMU_UADDRL, 0); + hloader_SetReg(p_hloader_config, HALHA_REG_EMU_UADDRM, 0); + hloader_SetReg(p_hloader_config, HALHA_REG_EMU_UADDRH, 0); + + for (count = 0; count < p_section_header->s_size / 8; count++) + { + t_uint32 load_data; + + load_data = *p_src_index++; + hloader_SetReg(p_hloader_config, HALHA_REG_EMU_UDATA0, (t_uint8) (load_data & 0xFFL)); + hloader_SetReg(p_hloader_config, HALHA_REG_EMU_UDATA1, (t_uint8) ((load_data >> 8) & 0xFFL)); + hloader_SetReg(p_hloader_config, HALHA_REG_EMU_UDATA2, (t_uint8) ((load_data >> 16) & 0xFFL)); + hloader_SetReg(p_hloader_config, HALHA_REG_EMU_UDATA3, (t_uint8) ((load_data >> 24) & 0XFFL)); + + load_data = *p_src_index++; + hloader_SetReg(p_hloader_config, HALHA_REG_EMU_UDATA4, (t_uint8) (load_data & 0xFFL)); + hloader_SetReg(p_hloader_config, HALHA_REG_EMU_UDATA5, (t_uint8) ((load_data >> 8) & 0xFFL)); + + hloader_SetReg + ( + p_hloader_config, + HALHA_REG_UCMD, + HALHA_REG_EMU_UCMD_WRITE | HALHA_REG_EMU_UCMD_LUT | HALHA_REG_EMU_UCMD_AUTOINCR + ); + } + + return(LOADER_OK); +} + +/* hloader_CopySaaVlcSection API */ +PRIVATE t_loader_error hloader_CopySaaVlcSection(t_loader_config *p_hloader_config, t_section_header *p_section_header) +{ + t_uint32 count; + t_uint32 *p_src_index; + t_uint32 *p_dest_index; + + if ((p_section_header == NULL) || (p_hloader_config == NULL)) + { + return(LOADER_INTERNAL); + } + + p_src_index = (t_uint32 *) ((t_sint8 *) p_hloader_config->FirmwareBaseAddr + p_section_header->s_offset); + p_dest_index = (t_uint32 *) (p_hloader_config->ProgramZone1.Base.logical + (p_section_header->s_addr * 8)); + + if ((p_src_index == NULL) || (p_dest_index == NULL)) + { + return(LOADER_INTERNAL); + } + + for (count = 0; count < p_section_header->s_size / 4; count++) + { + *p_dest_index++ = *p_src_index++; + } + + /* No error detected within this function. */ + return(LOADER_OK); +} + +/****************************************************************************/ +/* NAME : hloader_CopySvaCodeSection */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: Copy the current hv compressed code section following the */ +/* configuration of the loader and the current section header. */ +/* PARAMETERS: */ +/* IN : *p_hloader_config: Loader input parameters. */ +/* Filled by API user. */ +/* *p_section_header: Pointer on current section header. */ +/* OUT: None */ +/* RETURN: t_loader_error: LOADER_OK */ +/* */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PRIVATE t_loader_error hloader_CopySvaCodeSection(t_loader_config *p_hloader_config, t_section_header *p_section_header) +{ + t_uint32 count; + t_uint32 *p_src_index; + t_uint32 *p_dest_index; + + if ((p_section_header == NULL) || (p_hloader_config == NULL)) + { + return(LOADER_INTERNAL); + } + + p_src_index = (t_uint32 *) ((t_sint8 *) p_hloader_config->FirmwareBaseAddr + p_section_header->s_offset); + p_dest_index = (t_uint32 *) (p_hloader_config->HamacBaseAddr.logical + HAMACV_CODE_RAM_OFFSET + (p_section_header->s_addr * 8)); + + if ((p_src_index == NULL) || (p_dest_index == NULL)) + { + return(LOADER_INTERNAL); + } + + for (count = 0; count < p_section_header->s_size / 4; count++) + { + p_dest_index++; /* skip lsb word (cf. hamac doc) */ + *p_dest_index++ = *p_src_index++; + } + + /* No error detected within this function. */ + return(LOADER_OK); +} + +/****************************************************************************/ +/* NAME : hloader_CopySvaDictSection */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: Copy the current hv dictionnary section following the */ +/* configuration of the loader and the current section header. */ +/* PARAMETERS: */ +/* IN : *p_hloader_config: Loader input parameters. */ +/* Filled by API user. */ +/* *p_section_header: Pointer on current section header. */ +/* OUT: None */ +/* RETURN: t_loader_error: LOADER_OK */ +/* */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PRIVATE t_loader_error hloader_CopySvaDictSection(t_loader_config *p_hloader_config, t_section_header *p_section_header) +{ + t_uint32 count; + t_uint32 *p_src_index; + t_uint32 *p_dest_index; + + if ((p_section_header == NULL) || (p_hloader_config == NULL)) + { + return(LOADER_INTERNAL); + } + + p_src_index = (t_uint32 *) ((t_sint8 *) p_hloader_config->FirmwareBaseAddr + p_section_header->s_offset); + p_dest_index = (t_uint32 *) (p_hloader_config->HamacBaseAddr.logical + HAMACV_DICT_RAM_OFFSET + (p_section_header->s_addr * 8)); + + if ((p_src_index == NULL) || (p_dest_index == NULL)) + { + return(LOADER_INTERNAL); + } + + for (count = 0; count < p_section_header->s_size / 8; count++) + { + *p_dest_index++ = *p_src_index++; + *p_dest_index++ = *p_src_index++; + } + + /* No error detected within this function. */ + return(LOADER_OK); +} + +/* ------------------------------------------------------------------ + * function : hloader_SetReg + * parameters: t_sint32 address + * U8 value + * returned value: none + * writes the data : value in audio register located at address: address + -----------------------------------------------------------------*/ +PRIVATE void hloader_SetReg(t_loader_config *p_hloader_config, t_sint32 address, U8 value) +{ + *((volatile U16 *) ((address * 2) + p_hloader_config->HamacBaseAddr.logical + 0x60000)) = value; +} + +/* ------------------------------------------------------------------ + * function : hloader_GetReg + * parameters: t_sint32 address + * returned value: U8 value + * returns the contents of the audio register located at address: address + -----------------------------------------------------------------*/ +PRIVATE U8 hloader_GetReg(t_loader_config *p_hloader_config, t_sint32 address) +{ + PRIVATE volatile U16 value; + + value = *((volatile U16 *) ((address * 2) + p_hloader_config->HamacBaseAddr.logical + 0x60000)); + return((U8) value); +} + +#ifdef MMDSPTOOLS + +/****************************************************************************/ +/* NAME : hloader_CheckCodeSection */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: Check the current code section following the configuration */ +/* of the loader and the current section header. */ +/* PARAMETERS: */ +/* IN : *p_hloader_config: Loader input parameters. */ +/* Filled by API user. */ +/* *p_section_header: Pointer on current section header. */ +/* OUT: None */ +/* RETURN: t_loader_error: LOADER_OK or LOADER_CHECK_ERROR */ +/* */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PRIVATE t_loader_error hloader_CheckCodeSection(t_loader_config *p_hloader_config, t_section_header *p_section_header) +{ + t_uint32 count; + t_uint32 *p_src_index; + t_uint32 *p_dest_index; + + if ((p_section_header == NULL) || (p_hloader_config == NULL)) + { + return(LOADER_INTERNAL); + } + + p_src_index = (t_uint32 *) ((t_sint8 *) p_hloader_config->FirmwareBaseAddr + p_section_header->s_offset); + if (p_section_header->s_memtype == (t_uint16) MMF_MT_PROGRAM_MEM) + { + p_dest_index = (t_uint32 *) (p_hloader_config->ProgramZone1.Base.logical + (p_section_header->s_addr * 8)); + } else + { + p_dest_index = (t_uint32 *) (p_hloader_config->ProgramZone2.Base.logical + ((p_section_header->s_addr - 0xE0000) * 8)); + } + + if ((p_src_index == NULL) || (p_dest_index == NULL)) + { + return(LOADER_INTERNAL); + } + + for (count = 0; count < p_section_header->s_size / 4; count++) + { + if (*p_dest_index++ != *p_src_index++) + { + return(LOADER_CHECK_ERROR); + } + } + + /* No error detected within this function. */ + return(LOADER_OK); +} + +/****************************************************************************/ +/* NAME : hloader_CheckDataSection */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: Check the current data section following the configuration */ +/* of the loader and the current section header. */ +/* PARAMETERS: */ +/* IN : *p_hloader_config: Loader input parameters. */ +/* Filled by API user. */ +/* *p_section_header: Pointer on current section header. */ +/* OUT: None */ +/* RETURN: t_loader_error: LOADER_OK or LOADER_CHECK_ERROR */ +/* */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PRIVATE t_loader_error hloader_CheckDataSection(t_loader_config *p_hloader_config, t_section_header *p_section_header) +{ + t_uint32 *p_src_index, *p_dest_index; + t_uint16 *p_short_src_index, *p_short_dest_index; + t_uint32 count; + t_loader_error error_status; + + if ((p_section_header == NULL) || (p_hloader_config == NULL)) + { + return(LOADER_INTERNAL); + } + + p_src_index = (t_uint32 *) ((t_sint8 *) p_hloader_config->FirmwareBaseAddr + p_section_header->s_offset); + p_short_src_index = (t_uint16 *) ((t_sint8 *) p_hloader_config->FirmwareBaseAddr + p_section_header->s_offset); + + if + ( + ( + error_status = hloader_CalculateDestIndex + ( + p_hloader_config, + p_section_header, + &p_dest_index, + &p_short_dest_index + ) + ) != LOADER_OK + ) + { + return(error_status); + } + + if ((p_short_src_index == NULL) || (p_short_dest_index == NULL)) + { + return(LOADER_INTERNAL); + } + + if + ( + (p_section_header->s_bpw == (t_uint16) THREE_BYTES_PER_WORD) + && (p_hloader_config->Machine != HLOADER_MMF_F_HAMACV) + && (p_hloader_config->Machine != HLOADER_MMF_F_HV_FULL) + && (!(IS_HA_EXT_MEMORY16(p_section_header->s_memtype))) + && (!(IS_ESRAM_EXT_MEMORY16(p_section_header->s_memtype))) + ) + { + for (count = 0; count < p_section_header->s_size / 4; count++) + { + if ((*p_dest_index++ &0xFFFFFF) != (*p_src_index++ &0xFFFFFF)) + { + return(LOADER_CHECK_ERROR); + } + } + } else if (p_section_header->s_bpw == (t_uint16) THREE_BYTES_PER_WORD) + { + for (count = 0; count < p_section_header->s_size / 4; count++) + { + if ((*p_short_dest_index++ &0xFFFFFF) != (*p_short_src_index++ &0xFFFFFF)) + { + return(LOADER_CHECK_ERROR); + } + + p_short_src_index++; /* To discard two bytes */ + } + } else if (p_section_header->s_bpw == (t_uint16) TWO_BYTES_PER_WORD) + { + for (count = 0; count < p_section_header->s_size / 4; count++) + { + if ((*p_dest_index++ &0xFFFF) != (*p_src_index++ &0xFFFF)) + { + return(LOADER_CHECK_ERROR); + } + } + } + + /* No error detected within this function. */ + return(LOADER_OK); +} + +/****************************************************************************/ +/* NAME : hloader_CheckSaaLutSection */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: Copy the current hamac audio lut section following the */ +/* configuration of the loader and the current section header. */ +/* PARAMETERS: */ +/* IN : *p_hloader_config: Loader input parameters. */ +/* Filled by API user. */ +/* *p_section_header: Pointer on current section header. */ +/* OUT: None */ +/* RETURN: t_loader_error: LOADER_OK or LOADER_CHECK_ERROR */ +/* */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PRIVATE t_loader_error hloader_CheckSaaLutSection(t_loader_config *p_hloader_config, t_section_header *p_section_header) +{ + t_uint32 count; + t_sint32 error_status; + t_uint32 *p_src_index; + U8 value; + + if ((p_section_header == NULL) || (p_hloader_config == NULL)) + { + return(LOADER_INTERNAL); + } + + p_src_index = (t_uint32 *) ((t_sint8 *) p_hloader_config->FirmwareBaseAddr + p_section_header->s_offset); + + if (p_src_index == NULL) + { + return(LOADER_INTERNAL); + } + + /* Enable memory access from the emulation unit (clear bit 3 of bkcmd) */ + value = hloader_GetReg(p_hloader_config, HALHA_REG_BKCMD); + hloader_SetReg(p_hloader_config, HALHA_REG_BKCMD, (t_uint8) (value & 0x7)); + + hloader_SetReg(p_hloader_config, HALHA_REG_EMU_UADDRL, 0); + hloader_SetReg(p_hloader_config, HALHA_REG_EMU_UADDRM, 0); + hloader_SetReg(p_hloader_config, HALHA_REG_EMU_UADDRH, 0); + + error_status = 0; + + for (count = 0; count < p_section_header->s_size / 8; count++) + { + t_uint32 load_data; + + hloader_SetReg + ( + p_hloader_config, + HALHA_REG_UCMD, + HALHA_REG_EMU_UCMD_READ | HALHA_REG_EMU_UCMD_LUT | HALHA_REG_EMU_UCMD_AUTOINCR + ); + + load_data = *p_src_index++; + error_status += (t_sint32) ((hloader_GetReg(p_hloader_config, HALHA_REG_EMU_UDATA0) != (load_data & 0xFFL))); + error_status += (t_sint32) ((hloader_GetReg(p_hloader_config, HALHA_REG_EMU_UDATA1) != ((load_data >> 8) & 0xFFL))); + error_status += (t_sint32) ((hloader_GetReg(p_hloader_config, HALHA_REG_EMU_UDATA2) != ((load_data >> 16) & 0xFFL))); + error_status += (t_sint32) ((hloader_GetReg(p_hloader_config, HALHA_REG_EMU_UDATA3) != ((load_data >> 24) & 0XFFL))); + + load_data = *p_src_index++; + error_status += (t_sint32) ((hloader_GetReg(p_hloader_config, HALHA_REG_EMU_UDATA4) != (load_data & 0xFFL))); + error_status += (t_sint32) ((hloader_GetReg(p_hloader_config, HALHA_REG_EMU_UDATA5) != ((load_data >> 8) & 0xFFL))); + + if (error_status != 0) + { + return(LOADER_CHECK_ERROR); + } + } + + return(LOADER_OK); +} + +/* hloader_CheckSaaVlcSection API */ +PRIVATE t_loader_error hloader_CheckSaaVlcSection(t_loader_config *p_hloader_config, t_section_header *p_section_header) +{ + t_uint32 count; + t_uint32 *p_src_index; + t_uint32 *p_dest_index; + + if ((p_section_header == NULL) || (p_hloader_config == NULL)) + { + return(LOADER_INTERNAL); + } + + p_src_index = (t_uint32 *) ((t_sint8 *) p_hloader_config->FirmwareBaseAddr + p_section_header->s_offset); + p_dest_index = (t_uint32 *) (p_hloader_config->ProgramZone1.Base.logical + (p_section_header->s_addr * 8)); + + if ((p_src_index == NULL) || (p_dest_index == NULL)) + { + return(LOADER_INTERNAL); + } + + for (count = 0; count < p_section_header->s_size / 4; count++) + { + if (*p_dest_index++ != *p_src_index++) + { + return(LOADER_CHECK_ERROR); + } + } + + /* No error detected within this function. */ + return(LOADER_OK); +} + +/****************************************************************************/ +/* NAME : hloader_CheckSvaCodeSection */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: Check the current hamac video code section following the */ +/* configuration of the loader and the current section header. */ +/* PARAMETERS: */ +/* IN : *p_hloader_config: Loader input parameters. */ +/* Filled by API user. */ +/* *p_section_header: Pointer on current section header. */ +/* OUT: None */ +/* RETURN: t_loader_error: LOADER_OK or LOADER_CHECK_ERROR */ +/* */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PRIVATE t_loader_error hloader_CheckSvaCodeSection +( +t_loader_config *p_hloader_config, +t_section_header *p_section_header +) +{ + t_uint32 count; + t_sint32 error_status; + t_uint32 *p_src_index; + + if ((p_section_header == NULL) || (p_hloader_config == NULL)) + { + return(LOADER_INTERNAL); + } + + p_src_index = (t_uint32 *) ((t_sint8 *) p_hloader_config->FirmwareBaseAddr + p_section_header->s_offset); + + if (p_src_index == NULL) + { + return(LOADER_INTERNAL); + } + + hloader_SetReg(p_hloader_config, HALHA_REG_EMU_UADDRL, 0); + hloader_SetReg(p_hloader_config, HALHA_REG_EMU_UADDRM, 0); + hloader_SetReg(p_hloader_config, HALHA_REG_EMU_UADDRH, 0); + + error_status = 0; + + for (count = 0; count < p_section_header->s_size / 4; count++) + { + t_uint32 load_data; + + hloader_SetReg + ( + p_hloader_config, + HALHA_REG_UCMD, + HALHA_REG_EMU_UCMD_READ | HALHA_REG_EMU_UCMD_HV_INST | HALHA_REG_EMU_UCMD_AUTOINCR + ); + + load_data = *p_src_index++; + error_status += (t_sint32) ((hloader_GetReg(p_hloader_config, HALHA_REG_EMU_UDATA0) != (load_data & 0xFFL))); + error_status += (t_sint32) ((hloader_GetReg(p_hloader_config, HALHA_REG_EMU_UDATA1) != ((load_data >> 8) & 0xFFL))); + error_status += (t_sint32) ((hloader_GetReg(p_hloader_config, HALHA_REG_EMU_UDATA2) != ((load_data >> 16) & 0xFFL))); + error_status += (t_sint32) ((hloader_GetReg(p_hloader_config, HALHA_REG_EMU_UDATA3) != ((load_data >> 24) & 0XFFL))); + + if (error_status != 0) + { + return(LOADER_CHECK_ERROR); + } + } + + return(LOADER_OK); +} + +/****************************************************************************/ +/* NAME : hloader_CheckSvaDictSection */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: Check the current hamac video code section following the */ +/* configuration of the loader and the current section header. */ +/* PARAMETERS: */ +/* IN : *p_hloader_config: Loader input parameters. */ +/* Filled by API user. */ +/* *p_section_header: Pointer on current section header. */ +/* OUT: None */ +/* RETURN: t_loader_error: LOADER_OK or LOADER_CHECK_ERROR */ +/* */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PRIVATE t_loader_error hloader_CheckSvaDictSection +( +t_loader_config *p_hloader_config, +t_section_header *p_section_header +) +{ + t_uint32 count; + t_sint32 error_status; + t_uint32 *p_src_index; + + if ((p_section_header == NULL) || (p_hloader_config == NULL)) + { + return(LOADER_INTERNAL); + } + + p_src_index = (t_uint32 *) ((t_sint8 *) p_hloader_config->FirmwareBaseAddr + p_section_header->s_offset); + + if (p_src_index == NULL) + { + return(LOADER_INTERNAL); + } + + hloader_SetReg(p_hloader_config, HALHA_REG_EMU_UADDRL, 0); + hloader_SetReg(p_hloader_config, HALHA_REG_EMU_UADDRM, 0); + hloader_SetReg(p_hloader_config, HALHA_REG_EMU_UADDRH, 0); + + error_status = 0; + + for (count = 0; count < p_section_header->s_size / 8; count++) + { + t_uint32 load_data; + + hloader_SetReg + ( + p_hloader_config, + HALHA_REG_UCMD, + HALHA_REG_EMU_UCMD_READ | HALHA_REG_EMU_UCMD_HV_DICT | HALHA_REG_EMU_UCMD_AUTOINCR + ); + + load_data = *p_src_index++; + error_status += (t_sint32) ((hloader_GetReg(p_hloader_config, HALHA_REG_EMU_UDATA0) != (load_data & 0xFFL))); + error_status += (t_sint32) ((hloader_GetReg(p_hloader_config, HALHA_REG_EMU_UDATA1) != ((load_data >> 8) & 0xFFL))); + error_status += (t_sint32) ((hloader_GetReg(p_hloader_config, HALHA_REG_EMU_UDATA2) != ((load_data >> 16) & 0xFFL))); + error_status += (t_sint32) ((hloader_GetReg(p_hloader_config, HALHA_REG_EMU_UDATA3) != ((load_data >> 24) & 0xFFL))); + + load_data = *p_src_index++; + error_status += (t_sint32) ((hloader_GetReg(p_hloader_config, HALHA_REG_EMU_UDATA4) != (load_data & 0xFFL))); + error_status += (t_sint32) ((hloader_GetReg(p_hloader_config, HALHA_REG_EMU_UDATA5) != ((load_data >> 8) & 0xFFL))); + + if (error_status != 0) + { + return(LOADER_CHECK_ERROR); + } + } + + return(LOADER_OK); +} + +/****************************************************************************/ +/* NAME : hloader_DumpCodeSection */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION : Dump the current code section following the configuration */ +/* of the loader and the current section header. */ +/* PARAMETERS : */ +/* IN : *p_hloader_config: Loader input parameters. */ +/* Filled by API user. */ +/* *p_section_header: Pointer on current section header. */ +/* OUT: None */ +/* RETURN: t_loader_error: LOADER_OK */ +/* */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PRIVATE t_loader_error hloader_DumpCodeSection(t_loader_config *p_hloader_config, t_section_header *p_section_header) +{ + t_sint32 count; + t_uint32 msb, lsb; + t_sint32 func_dummy_ret_val; + t_uint32 *p_src_index; + + if ((p_section_header == NULL) || (p_hloader_config == NULL)) + { + return(LOADER_INTERNAL); + } + + p_src_index = (t_uint32 *) ((t_sint8 *) p_hloader_config->FirmwareBaseAddr + p_section_header->s_offset); + + if (p_src_index == NULL) + { + return(LOADER_INTERNAL); + } + + for (count = 0; count < (t_sint32) p_section_header->s_size / 8; count++) + { + lsb = *p_src_index++; + msb = *p_src_index++; + SWAPENDIANNESS32(msb); + SWAPENDIANNESS32(lsb); + func_dummy_ret_val = fprintf(stdout, "%08ld %08lx%08lx\n", count + p_section_header->s_addr, msb, lsb); + } + + /* To remove the PC Lint warning */ + func_dummy_ret_val = func_dummy_ret_val; + + /* No error detected within this function. */ + return(LOADER_OK); +} + +/****************************************************************************/ +/* NAME : hloader_DumpDataSection */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: Dump the current data section following the configuration */ +/* of the loader and the current section header. */ +/* PARAMETERS: */ +/* IN : *p_hloader_config: Loader input parameters. */ +/* Filled by API user. */ +/* *p_section_header: Pointer on current section header. */ +/* OUT: None */ +/* RETURN: t_loader_error: LOADER_OK */ +/* */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PRIVATE t_loader_error hloader_DumpDataSection(t_loader_config *p_hloader_config, t_section_header *p_section_header) +{ + t_uint32 *p_src_index; + t_uint16 *p_short_src_index; + t_uint32 data; + t_uint16 sdata; + t_uint32 count; + t_sint32 func_dummy_ret_val; + + if ((p_section_header == NULL) || (p_hloader_config == NULL)) + { + return(LOADER_INTERNAL); + } + + /* Pointers for 32 bits accesses. */ + p_src_index = (t_uint32 *) ((t_sint8 *) p_hloader_config->FirmwareBaseAddr + p_section_header->s_offset); + + /* Pointers for 16 bits accesses. */ + p_short_src_index = (t_uint16 *) ((t_sint8 *) p_hloader_config->FirmwareBaseAddr + p_section_header->s_offset); + + if ((NULL == p_src_index) || (NULL == p_short_src_index)) + { + return(LOADER_INTERNAL); + } + + if + ( + (p_section_header->s_bpw == (t_uint16) THREE_BYTES_PER_WORD) + && (p_hloader_config->Machine != HLOADER_MMF_F_HAMACV) + && (p_hloader_config->Machine != HLOADER_MMF_F_HV_FULL) + && (!(IS_HA_EXT_MEMORY16(p_section_header->s_memtype))) + && (!(IS_ESRAM_EXT_MEMORY16(p_section_header->s_memtype))) + ) + { + for (count = 0; count < p_section_header->s_size / 4; count++) + { + data = *p_src_index++; + SWAPENDIANNESS32(data); + func_dummy_ret_val = fprintf(stdout, "%8ld %08lx\n", count + p_section_header->s_addr, data & 0xffffff); + } + } else if (p_section_header->s_bpw == (t_uint16) THREE_BYTES_PER_WORD) + { + for (count = 0; count < p_section_header->s_size / 4; count++) + { + sdata = *p_short_src_index++; + SWAPENDIANNESS16(sdata); + func_dummy_ret_val = fprintf(stdout, "%8ld %04x\n", count + p_section_header->s_addr, sdata & 0xffff); + p_short_src_index++; /* discard two bytes */ + } + } else if (p_section_header->s_bpw == (t_uint16) TWO_BYTES_PER_WORD) + { + for (count = 0; count < p_section_header->s_size / 4; count++) + { + data = *p_src_index++; + func_dummy_ret_val = fprintf(stdout, "%8ld %04lx\n", 2 * count + p_section_header->s_addr, data & 0xffff); + func_dummy_ret_val = fprintf + ( + stdout, + "%8ld %04lx\n", + 2 * count + 1 + p_section_header->s_addr, + (data >> 16) & 0xffff + ); + } + } else + { + func_dummy_ret_val = 0; + } + + /* To remove the PC Lint warning */ + func_dummy_ret_val = func_dummy_ret_val; + + /* No error detected within this function. */ + return(LOADER_OK); +} + +/****************************************************************************/ +/* NAME : hloader_DumpSaaVlcSection */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: Dump the current hamac audio lut section following the */ +/* configuration of the loader and the current section header. */ +/* PARAMETERS: */ +/* IN : *p_hloader_config: Loader input parameters. */ +/* Filled by API user. */ +/* *p_section_header: Pointer on current section header. */ +/* OUT: None */ +/* RETURN: t_loader_error: LOADER_OK */ +/* */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PRIVATE t_loader_error hloader_DumpSaaVlcSection(t_loader_config *p_hloader_config, t_section_header *p_section_header) +{ + t_uint32 count; + t_uint32 data; + t_sint32 func_dummy_ret_val; + t_uint32 *p_src_index; + + if ((p_section_header == NULL) || (p_hloader_config == NULL)) + { + return(LOADER_INTERNAL); + } + + p_src_index = (t_uint32 *) ((t_sint8 *) p_hloader_config->FirmwareBaseAddr + p_section_header->s_offset); + + if (p_src_index == NULL) + { + return(LOADER_INTERNAL); + } + + for (count = 0; count < p_section_header->s_size / 4; count++) + { + data = *p_src_index++; + SWAPENDIANNESS32(data); + func_dummy_ret_val = fprintf(stdout, "%08ld %08lx\n", count + p_section_header->s_addr, data); + } + + /* To remove the PC lint warning */ + func_dummy_ret_val = func_dummy_ret_val; + + /* No error detected within this function. */ + return(LOADER_OK); +} + +/* hloader_MmfGetTypeStr API */ +PRIVATE t_sint8 *hloader_MmfGetTypeStr(t_uint16 type) +{ + t_sint32 func_dummy_ret_val1; + char *func_dummy_ret_val2; + PRIVATE t_sint8 str[128]; + + /* Used char instead of t_sint8, to remove the error/warning * + * implicit cast of pointer to non-equal pointer */ + func_dummy_ret_val1 = sprintf((char *) str, "%u: ", type); + switch (type) + { + case MMF_SHT_PROGBITS: + func_dummy_ret_val2 = strcat((char *) str, "MMF_SHT_PROGBITS"); + break; + + case MMF_SHT_NOBITS: + func_dummy_ret_val2 = strcat((char *) str, "MMF_SHT_NOBITS"); + break; + + default: + func_dummy_ret_val2 = strcat((char *) str, "UNKNOWN"); + break; + } + + /* To remove the PC lint warning */ + func_dummy_ret_val1 = func_dummy_ret_val1; + func_dummy_ret_val2 = func_dummy_ret_val2; + + return(str); +} + +/* hloader_MmfGetFlagsStr API */ +PRIVATE t_sint8 *hloader_MmfGetFlagsStr(t_uint16 flags) +{ + t_sint32 func_dummy_ret_val1; + char *func_dummy_ret_val2 = 0; + PRIVATE t_sint8 str[128]; + + /* Used char instead of t_sint8, to remove the error/warning * + * implicit cast of pointer to non-equal pointer */ + func_dummy_ret_val1 = sprintf((char *) str, "%u: ", flags); + + if (flags & MMF_SHF_WRITE) + { + func_dummy_ret_val2 = strcat((char *) str, "W"); + } + + if (flags & MMF_SHF_ALLOC) + { + func_dummy_ret_val2 = strcat((char *) str, "A"); + } + + /* To remove the PC lint warning */ + func_dummy_ret_val1 = func_dummy_ret_val1; + func_dummy_ret_val2 = func_dummy_ret_val2; + + return((t_sint8 *) str); +} + +/* hloader_MmfGetMachineStr API */ +PRIVATE t_sint8 *hloader_MmfGetMachineStr(t_uint16 flags) +{ + t_sint32 func_dummy_ret_val; + PRIVATE t_sint8 str[128]; + + switch (flags) + { + case HLOADER_MMF_F_UNSPEC: + /* Used char instead of t_sint8, to remove the error/warning * + * implicit cast of pointer to non-equal pointer */ + func_dummy_ret_val = sprintf((char *) str, "unspecified"); + break; + + case HLOADER_MMF_F_HAMACA: + func_dummy_ret_val = sprintf((char *) str, "Hamac Audio Lite"); + break; + + case HLOADER_MMF_F_OP9FPU: + func_dummy_ret_val = sprintf((char *) str, "OP9 FPU"); + break; + + case HLOADER_MMF_F_HA_FULL: + func_dummy_ret_val = sprintf((char *) str, "Hamac Audio Full"); + break; + + case HLOADER_MMF_F_STN8815: + func_dummy_ret_val = sprintf((char *) str, "Hamac Audio Stn8815"); + break; + + case HLOADER_MMF_F_HV_FULL: + func_dummy_ret_val = sprintf((char *) str, "Hamac Video Full"); + break; + + case HLOADER_MMF_F_HAMACV: + func_dummy_ret_val = sprintf((char *) str, "Hamac Video"); + break; + + default: + func_dummy_ret_val = sprintf((char *) str, "Unknown"); + break; + } + + /* To remove the PC lint warning */ + func_dummy_ret_val = func_dummy_ret_val; + + return(str); +} + +/* hloader_MmDspDisplaySectionHeader API */ +PRIVATE void hloader_MmDspDisplaySectionHeader(t_section_header *p_section_header) +{ + t_sint32 func_dummy_ret_val; + PRIVATE t_sint32 number_of_sections = 0; + + func_dummy_ret_val = fprintf(stdout, "[%ld] SECTION HEADER\n", number_of_sections++); + func_dummy_ret_val = fprintf(stdout, "\tname = %s\n", (t_sint8 *) p_section_header->s_name); + func_dummy_ret_val = fprintf(stdout, "\ttype = %s\n", hloader_MmfGetTypeStr(p_section_header->s_type)); + func_dummy_ret_val = fprintf(stdout, "\tmemtype = %d\n", p_section_header->s_memtype); + func_dummy_ret_val = fprintf(stdout, "\tflags = %s\n", hloader_MmfGetFlagsStr(p_section_header->s_flags)); + func_dummy_ret_val = fprintf(stdout, "\tbyte per mau = %d\n", p_section_header->s_bpw); + func_dummy_ret_val = fprintf(stdout, "\tmau base = %lu\n", p_section_header->s_addr); + func_dummy_ret_val = fprintf(stdout, "\tfile section offset = %ld\n", p_section_header->s_offset); + func_dummy_ret_val = fprintf(stdout, "\tsection size = %ld\n", p_section_header->s_size); + + /* To remove the PC lint warning */ + func_dummy_ret_val = func_dummy_ret_val; +} +#endif /* End MMDSPTOOLS */ + +/* End of file - hloader.c */ + --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/hcl/hloader/hloader.h @@ -0,0 +1,170 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ + +#ifndef _HLOADER_H_ +#define _HLOADER_H_ + +#ifdef __cplusplus +extern "C" +{ +#endif + +/*--------------------------------------------------------------------------* + * Includes * + *--------------------------------------------------------------------------*/ +#include "hcl_defs.h" + +/*--------------------------------------------------------------------------* + * Defines * + *--------------------------------------------------------------------------*/ +/* To signify that the while binary file has to be copied */ +#define WHOLE_FILE 0 + +#define BASE_ALIGNMENT_CHECK_32_BYTE 31 +#define BASE_ALIGNMENT_CHECK_64_BYTE 63 + +/* Errors types */ +typedef enum +{ + LOADER_OK = 0, + LOADER_NOT_ENOUGH_MEM = -1, + LOADER_BAD_MAGIC_CODE = -2, + LOADER_BAD_FILE_VERSION = -3, + LOADER_BAD_MACHINE = -4, + LOADER_UKN_MEMTYPE = -5, + LOADER_NO_DSP = -6, + LOADER_CHECK_ERROR = -7, + LOADER_INTERNAL = -8, + LOADER_CODE_NOT_LOADED = -9, + LOADER_BAD_BASE = -10, + LOADER_UNFINISHED = -11, + LOADER_BAD_ARCHI = -12 +} t_loader_error; + +/* Loader instruction masks */ +typedef enum +{ + LOAD_CODE = 0x1, + LOAD_DATA = 0x2, + CHECK_CODE = 0x4, + CHECK_DATA = 0x8, + DUMP = 0x10, + DUMP_SECTION = 0x20, + ALLOW_FORCED_COMPAT = 0x40, + ALLOW_DATAZONE_CHANGE = 0x80 +} t_loader_instr; + +/* Hamac code compression */ +typedef enum +{ + NO_COMPRESSION, + HA_VLC_COMPRESSION, + HV_DICT_COMPRESSION +} t_hamac_comp; + +typedef struct +{ + t_system_address Base; + t_system_address Top; + t_uint32 Size; +} t_ahb_zone; + +typedef enum +{ + TA_UNKNOWN = 0, + TA_8800A_8810A, /* 8800 audio any cut, 8810 audio cut 1.x */ + TA_8810A_B0, /* 8810 audio cut 2 */ + TA_8800V, /* 8800 video */ + TA_8810V_A0, /* 8810 video cut 1.x */ + TA_8810V_B0, /* 8810 video cut 2 */ + TA_8815A_A0, /* 8815 audio cut 1 */ + TA_8815V_A0, /* 8815 video cut 1 */ + TA_8815A_B0, /* 8815 audio cut 2 */ + TA_8815V_B0 /* 8815 video cut 2 */ +} t_core_id; + +typedef enum +{ + COMPAT_DFT_8800 = 0xF8, + COMPAT_8810_8815 = 0x1CF8, + COMPAT_DFT_8815_A0 = 0x10F8 +} t_compat; + +typedef struct loader_config t_loader_config; +typedef t_loader_error (*t_ahb_init_func) (t_loader_config * p_hloader_config); + +typedef struct +{ + t_hamac_comp compression; + t_ahb_init_func ahb_master_init; + t_ahb_init_func ahb_base_init; + t_core_id core_id; + t_compat compat; + t_uint16 nb_code_sections; +} t_loader_context; + +/* Loader configuration */ +struct loader_config +{ + t_uint32 *FirmwareBaseAddr; + t_uint32 FirmwareSize; + t_system_address HamacBaseAddr; + t_loader_instr LoadingInstr; + t_ahb_zone ProgramZone1; + t_ahb_zone ProgramZone2; + t_ahb_zone Data16Zone1; + t_ahb_zone Data16Zone2; + t_ahb_zone Data24Zone1; + t_ahb_zone Data24Zone2; + t_ahb_zone MmioZone; + t_uint16 Machine; + t_uint32 ToolsVersion; + t_sint8 FwVersion[8]; + t_loader_context Context; +}; + +typedef struct +{ + t_uint32 *BaseAddr; +} t_backup_config; + +/*--------------------------------------------------------------------------* + * Public functions declaration * + *--------------------------------------------------------------------------*/ +PUBLIC t_loader_error HLOADER_GetMemSizes(OUT t_loader_config *p_hloader_config); +PUBLIC t_loader_error HLOADER_Init(IN t_loader_config *p_hloader_config); +PUBLIC t_loader_error HLOADER_GetVersion(OUT t_version *p_version); +PUBLIC t_loader_error HLOADER_FirmwareLoad(IN t_loader_config *p_hloader_config); +PUBLIC t_loader_error HLOADER_PartialLoad(IN t_loader_config *p_hloader_config); +PUBLIC t_uint32 HLOADER_GetEsramSaaSectionSize(IN t_loader_config *p_hloader_config); +PUBLIC t_loader_error HLOADER_SaveEsramSaaSection(IN t_loader_config *p_hloader_config, IN t_backup_config *p_backup_config); +PUBLIC t_loader_error HLOADER_LoadEsramSaaSection(IN t_loader_config *p_hloader_config, IN t_backup_config *p_backup_config); +PUBLIC t_loader_error HLOADER_AHB_base_init(IN t_loader_config *p_hloader_config); +PUBLIC t_loader_error HLOADER_Boot(IN t_loader_config *p_hloader_config); +PUBLIC t_loader_error HLOADER_StopClock(IN t_loader_config *p_hloader_config); +PUBLIC t_loader_error HLOADER_StartClock(IN t_loader_config *p_hloader_config); +PUBLIC t_loader_error HLOADER_CacheConfig(IN t_loader_config *p_hloader_config , t_uint64 cache_mode); + +#ifdef __cplusplus +} /* allow C++ to use these headers */ +#endif /* __cplusplus */ +#endif /* _HLOADER_H_ */ + +/* End of file - hloader.h */ + --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/hcl/hloader/hloader_p.h @@ -0,0 +1,451 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ + +#ifndef _HLOADER_P_H_ +#define _HLOADER_P_H_ + +#ifdef __cplusplus +extern "C" +{ +#endif + +/*--------------------------------------------------------------------------* + * Includes * + *--------------------------------------------------------------------------*/ +#include "hloader.h" + +/*--------------------------------------------------------------------------* + * Defines * + *--------------------------------------------------------------------------*/ +/* Defines for Version */ +#define HLOADER_HCL_VERSION_ID 3 +#define HLOADER_HCL_MAJOR_ID 1 +#define HLOADER_HCL_MINOR_ID 5 + +#define U8 t_uint8 +#define U16 t_uint16 +#define U32 t_uint32 + +/* Magic number for a MMDSP+ executable */ +#define HLOADER_F_MAGIC ((t_uint32) 0xAC4D4D46) + +/* File flags */ +#define HLOADER_MMF_F_NONE 0 +#define HLOADER_MMF_F_REL 1 +#define HLOADER_MMF_F_EXEC 2 + +#define HLOADER_MMF_F_UNSPEC (0 << 8) +#define HLOADER_MMF_F_HAMACA (1 << 8) +#define HLOADER_MMF_F_HAMACV (2 << 8) +#define HLOADER_MMF_F_OP9FPU (3 << 8) +#define HLOADER_MMF_F_HA_FULL (4 << 8) +#define HLOADER_MMF_F_HV_FULL (5 << 8) +#define HLOADER_MMF_F_STN8815 (6 << 8) +#define HLOADER_MMF_F_CURVER HLOADER_MMF_F_VER12 +#define HLOADER_MMF_F_VER10 (1 << 4) +#define HLOADER_MMF_F_VER11 (2 << 4) +#define HLOADER_MMF_F_VER12 (3 << 4) +#define MMF_VERSION_MASK 0x00F0 +#define MMF_MACHINE_MASK 0xFF00 +#define MMF_FILETYPE_MASK 0x000F + +/* Section data types */ +#define MMF_SHT_PROGBITS 1 /* contains raw data to be loaded */ +#define MMF_SHT_NOBITS 2 /* no data to be loaded (e.g. bss) */ + +/* Section flags */ +/* The section is writeable */ +#define MMF_SHF_WRITE (1 << 0) + +/* space has to be allocated at run time for the section */ +#define MMF_SHF_ALLOC (1 << 1) + +/* Endianness */ +#define MMF_BIG_ENDIAN 1 +#define MMF_LITTLE_ENDIAN 2 + +#define HAMAC_XBUS_EXT_DATA24_BASE 0x10000 +#define HAMAC_XBUS_EXT_DATA16_BASE 0x800000 +#define HAMAC_XBUS_EXT_MEM_TOP 0xFFFFFF + +#define HAMAC_XBUS_EXT_DATA24_2_BASE 0x400000ULL +#define HAMAC_XBUS_EXT_DATA16_2_BASE 0xF60000ULL + +#define HAMACA_DATA_BASE_16_OFFSET 0x40000 + +#define HAMACV_CODE_RAM_OFFSET 0x80000 +#define HAMACV_DICT_RAM_OFFSET 0xC0000 +#define HAMACV_DATA_BASE_16_OFFSET 0x40000 + +#define HAMACA_DCACHE_MODE 0xEC05 +#define HAMACA_DCACHE_CTL 0xEC06 +#define HAMACA_DCACHE_CMD 0xEC09 +#define HAMACA_DCACHE_CNT1_LSB 0xEC0B +#define HAMACA_DCACHE_CNT1_MSB 0xEC0C +#define HAMACA_DCACHE_CNT2_LSB 0xEC0D +#define HAMACA_DCACHE_CNT2_MSB 0xEC0E +#define HAMACA_DCACHE_CNT3_LSB 0xEC0F +#define HAMACA_DCACHE_CNT3_MSB 0xEC10 +#define HAMACA_DCACHE_CNT_SEL 0xEC11 + +#define HAMACA_MMIO_REG_IPEN 0xF228 +#define HAMACA_MMIO_REG_ITIP_L 0xF22A +#define HAMACA_MMIO_REG_ITIP_H 0xF22B +#define HAMACA_MMIO_REG_ITOP_0 0xF22C +#define HAMACA_MMIO_REG_ITOP_1 0xF22D +#define HAMACA_MMIO_REG_ITOP_2 0xF22E +#define HAMACA_MMIO_REG_ITOP_3 0xF22F + +#define HAMACA_MMIO_REG_ID0 0xF3F0 +#define HAMACA_MMIO_REG_ID1 0xF3F2 +#define HAMACA_MMIO_REG_ID2 0xF3F4 +#define HAMACA_MMIO_REG_ID3 0xF3F6 +#define HAMACA_MMIO_REG_IDP0 0xF3F8 +#define HAMACA_MMIO_REG_IDP1 0xF3FA +#define HAMACA_MMIO_REG_IDP2 0xF3FC +#define HAMACA_MMIO_REG_IDP3 0xF3FE + +#define HAMACA_MMIO_ARM_DMA0_SREQ 0xF400 +#define HAMACA_MMIO_ARM_DMA0_IT 0xF405 +#define HAMACA_MMIO_ARM_DMA1_IT 0xF415 +#define HAMACA_MMIO_ARM_DMA2_IT 0xF425 +#define HAMACA_MMIO_ARM_DMA3_IT 0xF435 +#define HAMACA_MMIO_ARM_DMA4_IT 0xF445 +#define HAMACA_MMIO_ARM_DMA5_IT 0xF455 +#define HAMACA_MMIO_ARM_DMA6_IT 0xF465 +#define HAMACA_MMIO_ARM_DMA7_IT 0xF475 + +#define HAMAC_MMIO_COMPATIBILITY_32 0xF60A +#define HAMAC_MMIO_IO_ALL 0xF024 +#define HAMAC_AHB_IF_CONFIG 0xF800 +#define HAMAC_AHB_IF_MODE 0xF801 +#define HAMAC_AHB_IF_STATUS 0xF802 +#define HAMAC_AHB_IF_SECURITY 0xF803 +#define HAMAC_AHB_IF_FLUSHE 0xF804 + +#define HALHA_REG_IDENT 0x00 +#define HALHA_REG_IDENT0 0x01 +#define HALHA_REG_IDENT1 0x02 +#define HALHA_REG_IDENT2 0x03 +#define HALHA_REG_IDENT3 0x04 + +#define HALHA_REG_INTE0 0x07 +#define HALHA_REG_INTE1 0x08 +#define HALHA_REG_INT0 0x09 +#define HALHA_REG_INT1 0x0A + +#define HALHA_REG_INTEL HALHA_REG_INTE0 +#define HALHA_REG_INTEH HALHA_REG_INTE1 +#define HALHA_REG_INTL HALHA_REG_INT0 +#define HALHA_REG_INTH HALHA_REG_INT1 + +#define HALHA_REG_SOFTRESET 0x10 +#define HALHA_REG_I2CDIV 0x1C + +#define HALHA_REG_EMU_UDATA0 0x20 +#define HALHA_REG_EMU_UDATA1 0x21 +#define HALHA_REG_EMU_UDATA2 0x22 +#define HALHA_REG_EMU_UDATA3 0x23 +#define HALHA_REG_EMU_UDATA4 0x24 +#define HALHA_REG_EMU_UDATA5 0x25 +#define HALHA_REG_EMU_UDATA6 0x26 +#define HALHA_REG_EMU_UDATA7 0x27 + +#define HALHA_REG_EMU_UADDRL 0x28 +#define HALHA_REG_EMU_UADDRM 0x29 +#define HALHA_REG_EMU_UADDRH 0x36 + +#define HALHA_REG_UCMD 0x2A +#define HALHA_REG_BKCMD 0x2B + +#define HALHA_REG_EMU_MDATA0 0x2F +#define HALHA_REG_EMU_MDATA1 0x30 +#define HALHA_REG_EMU_MDATA2 0x31 +#define HALHA_REG_EMU_MADDRL 0x32 +#define HALHA_REG_EMU_MADDRM 0x33 +#define HALHA_REG_EMU_MCMD 0x34 +#define HALHA_REG_EMU_MADDRH 0x35 + +#define HALHA_REG_EMU_UCMD_WRITE 0x0 +#define HALHA_REG_EMU_UCMD_READ 0x4 +#define HALHA_REG_EMU_UCMD_LUT 0x11 +#define HALHA_REG_EMU_UCMD_HV_INST 0x0 +#define HALHA_REG_EMU_UCMD_HV_DICT 0x1 +#define HALHA_REG_EMU_UCMD_AUTOINCR 0x2 + +#define HALHA_REG_CLKCMD 0x3A + +#define HALHA_REG_CACHE_FLUSH 0x00 +#define HALHA_REG_CACHE_LOCKV 0x01 +#define HALHA_REG_CACHE_MODE 0x02 +#define HALHA_REG_CACHE_CLRPF 0x03 +#define HALHA_REG_CACHE_PFHIT 0x04 +#define HALHA_REG_CACHE_PFMISSL1 0x05 +#define HALHA_REG_CACHE_FSW 0x06 +#define HALHA_REG_CACHE_PRGBASEADD 0x07 +#define HALHA_REG_CACHE_PRGAHBCONF 0x08 +#define HALHA_REG_CACHE_DATAAHBCONF 0x09 +#define HALHA_REG_CACHE_DATABASEADD 0x0A +#define HALHA_REG_CACHE_DATATOPADD 0x0B +#define HALHA_REG_CACHE_VLCMODE 0x0C +#define HALHA_REG_CACHE_STATE 0x0D +#define HALHA_REG_CACHE_TIMEOUT 0x0E +#define HALHA_REG_CACHE_PFM_MODE 0x10 + +#define HALHA_REG_CACHE_PRG_BURST_SIZE 0x18 + +#define HALHA_REG_DATA_AHB_TOP_16_24 0x14 +#define HALHA_REG_DATA_AHB_TOP2_16_24 0x15 +#define HALHA_REG_CACHE_PRGBASE2ACTIVE 0x13 +#define HALHA_REG_CACHE_DATABASEADD2 0xC +#define HALHA_REG_DATA_TOP1624_CHECK 0x16 +#define HALHA_REG_DATA_TOP1624_CHECK_8810B0 0x16 +#define HALHA_REG_CACHE_DATABASE2ACTIVE 0x17 +#define HALHA_REG_DATA2_1624_XA_BASE 0xF + +#define HALHA_AUTOTEST_CMD0 0x40 +#define HALHA_AUTOTEST_CMD1 0x41 +#define HALHA_AUTOTEST_STATUS0 0x42 +#define HALHA_AUTOTEST_STATUS1 0x43 +#define HALHA_AUTOTEST_CONFIRM 0x44 + +#define HAMACA_MMIO_VALUE_ID0 0xAA +#define HAMACA_MMIO_VALUE_ID1 0x0A +#define HAMACA_MMIO_VALUE_ID2 0x08 +#define HAMACA_MMIO_VALUE_ID3 0x47 +#define HAMACA_MMIO_VALUE_IDP0 0x0D +#define HAMACA_MMIO_VALUE_IDP1 0xF0 +#define HAMACA_MMIO_VALUE_IDP2 0x05 +#define HAMACA_MMIO_VALUE_IDP3 0xB1 + +/* Loader instruction masks values */ +#define HLOADER_LOAD_CODE_VAL 0x1 +#define HLOADER_LOAD_DATA_VAL 0x2 +#define HLOADER_CHECK_CODE_VAL 0x4 +#define HLOADER_CHECK_DATA_VAL 0x8 +#define HLOADER_DUMP_VAL 0x10 +#define HLOADER_DUMP_SECTION_VAL 0x20 +#define HLOADER_ALLOW_FORCED_COMPAT_VAL 0x40 +#define HLOADER_ALLOW_DATAZONE_CHANGE_VAL 0x80 + +/* Memory types mask values */ +#define HLOADER_MT_PROGRAM_MEM_VAL 0 +#define HLOADER_MT_HA_EXT24_VAL 5 +#define HLOADER_MT_HA_EXT16_VAL 6 +#define HLOADER_MT_ESRAM_EXT24_VAL 12 +#define HLOADER_MT_ESRAM_EXT16_VAL 13 + +/* Data Cache conf. register mask */ +#define HLOADER_MMIO_DATA_CACHE 0xEC05 +#define HLOADER_MMIO_DATA_CACHE_EN_VAL 0x01 + +/* Memory types */ +typedef enum +{ + MMF_MT_PROGRAM_MEM = 0, + MMF_MT_X_MEM = 1, + MMF_MT_Y_MEM = 2, + MMF_MT_WS_MEM = 3, + MMF_MT_HOST_MEM = 4, + MMF_MT_HA_EXT24 = 5, + MMF_MT_HA_EXT16 = 6, + MMF_MT_HA_VLC_CODE = 7, + MMF_MT_HA_VLC_LUT = 8, + MMF_MT_HV_COMP_CODE = 9, + MMF_MT_HV_DICT = 10, + MMF_MT_ESRAM_PMEM = 11, + MMF_MT_ESRAM_EXT24 = 12, + MMF_MT_ESRAM_EXT16 = 13 +} t_mem_type; + +#define IS_HA_EXT_MEMORY(x) ((x) == HLOADER_MT_HA_EXT16_VAL || (x) == HLOADER_MT_HA_EXT24_VAL) +#define IS_HA_EXT_MEMORY16(x) ((x) == HLOADER_MT_HA_EXT16_VAL) +#define IS_HA_EXT_MEMORY24(x) ((x) == HLOADER_MT_HA_EXT24_VAL) +#define IS_ESRAM_EXT_MEMORY16(x) ((x) == HLOADER_MT_ESRAM_EXT16_VAL) +#define IS_ESRAM_EXT_MEMORY24(x) ((x) == HLOADER_MT_ESRAM_EXT24_VAL) + +/* Data types */ +typedef enum +{ + ONE_BYTE_PER_WORD = 1, + TWO_BYTES_PER_WORD = 2, + THREE_BYTES_PER_WORD= 3, + FOUR_BYTES_PER_WORD = 4 +} t_data_type; + +/* File header */ +typedef struct +{ + t_uint32 f_magic; /* file magic number */ + t_uint16 f_flags; /* file description flags. (RFU) */ + t_uint16 f_nsections; /* number of section headers */ + t_uint16 f_sh_size; /* section header size */ + t_uint16 f_sht_offset; /* section table offset */ + t_uint32 f_tools_ver; /* MMDSP+ tools release number */ + t_uint16 f_fw_ver[4]; /* firmware version name (added in v1.2) */ +} t_file_header; + +/* Section header description */ +/* s_type: */ +/* Section data type. Possible values are: */ +/* - MMF_SHT_PROGBITS: It holds information defined by the program (can be code or data). */ +/* - MMF_SHT_NOBITS: It occupies no space in the file. Used typically for bss section, */ +/* which have to be allocated by the loader and filled with zeroes. */ +/* s_memtype: */ +/* Memory bank where data should be copied. */ +/* If s_type is not 0, value is not relevant. Possible values are: */ +/* - 0: Program memory */ +/* - 1: X memory */ +/* - 2: Y memory */ +/* - 3: External memory */ +/* s_flags: */ +/* Sections support 1-bit flags that describe miscellaneous attributes. Flag definition are: */ +/* - MMF_SHF_WRITE : the section is writeable */ +/* - MMF_SHF_ALLOC : the section occupies memory space during the process execution */ +/* s_bpw: */ +/* Bytes number contained in a data element. */ +/* s_size */ +/* Section total (in bytes). MAU section size is \f$s\_size / s\_bpw \f$. */ +/* s_addr */ +/* Section start address expressed in MAU (in the MMDSP address space). */ + +typedef struct +{ + t_uint16 s_name[4]; /* section name */ + t_uint16 s_type; /* type of data */ + t_uint16 s_memtype; /* memory bank */ + t_uint16 s_flags; /* section flags */ + t_uint16 s_bpw; /* bytes number in a data word */ + t_uint32 s_size; /* size of the section in bytes */ + t_uint32 s_offset; /* file offset to the raw data */ + t_uint32 s_addr; /* base address in MMDSP MAUs */ +} t_section_header; + + + + + + +#define b3(a) (((a) >> 24) & 0xff) +#define b2(a) (((a) >> 16) & 0xff) +#define b1(a) (((a) >> 8) & 0xff) +#define b0(a) (((a) >> 0) & 0xff) +#ifdef __arm +#define SWAPENDIANNESS16(a) +#define SWAPENDIANNESS32(a) +#else +#define SWAPENDIANNESS16(a) a = (b1(a) + (b0(a) << 8)) +#define SWAPENDIANNESS32(a) a = (b3(a) + (b2(a) << 8) + (b1(a) << 16) + (b0(a) << 24)) +#endif +#define MAX(a, b) (((a) >= (b)) ? (a) : (b)) + +/*--------------------------------------------------------------------------* + * Private functions declaration * + *--------------------------------------------------------------------------*/ +PRIVATE t_loader_error hloader_CheckAndSetCompat(t_loader_config * p_hloader_config); +PRIVATE t_loader_error hloader_IdentifyHamac(t_loader_config *p_hloader_config); +PRIVATE t_loader_error hloader_CheckZoneSize(t_ahb_zone *p_ahb_zone); +PRIVATE t_loader_error hloader_CheckSizes(t_loader_config *p_hloader_config); +PRIVATE void hloader_HamacWriteCtrl(t_loader_config *p_hloader_config, t_uint16 address, t_uint64 data); +PRIVATE t_loader_error hloader_AhbBaseInit8800And8810(t_loader_config *p_hloader_config); +PRIVATE t_loader_error hloader_AhbMasterInit8800And8810(t_loader_config *p_hloader_config); +PRIVATE t_loader_error hloader_AhbBaseInit8810B0(t_loader_config *p_hloader_config); +PRIVATE t_loader_error hloader_AhbMasterInit8810B0(t_loader_config *p_hloader_config); +PRIVATE t_loader_error hloader_AhbBaseInit8815(t_loader_config *p_hloader_config); +PRIVATE t_loader_error hloader_AhbMasterInit8815(t_loader_config *p_hloader_config); +PRIVATE t_loader_error hloader_SoftReset(t_loader_config *p_hloader_config); +PRIVATE t_loader_error hloader_CheckFileHeader(t_file_header *p_file_header); +PRIVATE t_loader_error hloader_GetSectionSize(t_loader_config *p_hloader_config, t_uint32 *p_cur_section_addr); +PRIVATE t_loader_error hloader_ProcessSection(t_loader_config *p_hloader_config, t_uint32 *p_cur_section_addr); +PRIVATE t_loader_error hloader_PartialProcessSection(t_loader_config *p_hloader_config, t_uint32 *p_cur_section_addr); +PRIVATE t_loader_error hloader_CopyCodeSection(t_loader_config *p_hloader_config, t_section_header *p_section_header); +PRIVATE t_loader_error hloader_CalculateDestIndex + ( + t_loader_config *p_hloader_config, + t_section_header *p_section_header, + t_uint32 **p_dest_index, + t_uint16 **p_short_dest_index + ); +PRIVATE t_loader_error hloader_CopyDataSection(t_loader_config *p_hloader_config, t_section_header *p_section_header); +PRIVATE t_loader_error hloader_CopySaaLutSection + ( + t_loader_config *p_hloader_config, + t_section_header *p_section_header + ); +PRIVATE t_loader_error hloader_CopySaaVlcSection + ( + t_loader_config *p_hloader_config, + t_section_header *p_section_header + ); +PRIVATE t_loader_error hloader_CopySvaCodeSection + ( + t_loader_config *p_hloader_config, + t_section_header *p_section_header + ); +PRIVATE t_loader_error hloader_CopySvaDictSection + ( + t_loader_config *p_hloader_config, + t_section_header *p_section_header + ); +PRIVATE void hloader_SetReg(t_loader_config *p_hloader_config, t_sint32 address, U8 value); +PRIVATE U8 hloader_GetReg(t_loader_config *p_hloader_config, t_sint32 address); + +#ifdef MMDSPTOOLS +PRIVATE t_loader_error hloader_CheckCodeSection(t_loader_config *p_hloader_config, t_section_header *p_section_header); +PRIVATE t_loader_error hloader_CheckDataSection(t_loader_config *p_hloader_config, t_section_header *p_section_header); +PRIVATE t_loader_error hloader_CheckSaaLutSection + ( + t_loader_config *p_hloader_config, + t_section_header *p_section_header + ); +PRIVATE t_loader_error hloader_CheckSaaVlcSection + ( + t_loader_config *p_hloader_config, + t_section_header *p_section_header + ); +PRIVATE t_loader_error hloader_CheckSvaCodeSection + ( + t_loader_config *p_hloader_config, + t_section_header *p_section_header + ); +PRIVATE t_loader_error hloader_CheckSvaDictSection + ( + t_loader_config *p_hloader_config, + t_section_header *p_section_header + ); +PRIVATE t_loader_error hloader_DumpCodeSection(t_loader_config *p_hloader_config, t_section_header *p_section_header); +PRIVATE t_loader_error hloader_DumpDataSection(t_loader_config *p_hloader_config, t_section_header *p_section_header); +PRIVATE t_loader_error hloader_DumpSaaVlcSection + ( + t_loader_config *p_hloader_config, + t_section_header *p_section_header + ); +PRIVATE t_sint8 * hloader_MmfGetTypeStr(t_uint16 type); +PRIVATE t_sint8 * hloader_MmfGetFlagsStr(t_uint16 flags); +PRIVATE t_sint8 * hloader_MmfGetMachineStr(t_uint16 flags); +PRIVATE void hloader_MmDspDisplaySectionHeader(t_section_header *p_section_header); +#endif /* MMDSPTOOLS */ + +#ifdef __cplusplus +} /* allow C++ to use these headers */ +#endif /* __cplusplus */ +#endif /* _HLOADER_P_H_ */ + +/* End of file - hloader_p.h */ + --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/hcl/include/debug.h @@ -0,0 +1,316 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ + + +#ifndef __INC_DEBUG_H +#define __INC_DEBUG_H + +/*--------------------------------------------------------------------------* + * Includes * + *--------------------------------------------------------------------------*/ +#include "hcl_defs.h" + +/*--------------------------------------------------------------------------* + * C++ * + *--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/*--------------------------------------------------------------------------* + * Constants and new types * + *--------------------------------------------------------------------------*/ + +/*Defines for Version */ +#define DBG_HCL_VERSION_ID 3 +#define DBG_HCL_MAJOR_ID 2 +#define DBG_HCL_MINOR_ID 0 + + +/* Store a submitter ID, unique for each HCL. */ + +typedef enum +{ + UNKNOWN_HCL_DBG_ID, + APPLI_DBG_ID, + TEST_DBG_ID, + DEBUG_HCL_DBG_ID, + UART_HCL_DBG_ID, + VIC_HCL_DBG_ID, + DMA_HCL_DBG_ID, + HA_HCL_DBG_ID, + SAA_HCL_DBG_ID, + RTC_HCL_DBG_ID, + TIMER_HCL_DBG_ID, + WATCHDOG_HCL_DBG_ID, + I2C_HCL_DBG_ID, + CODEC_HCL_DBG_ID, + MSP_HCL_DBG_ID, + HV_HCL_DBG_ID, + SVA_HCL_DBG_ID, + FLASH_HCL_DBG_ID, + SDRAM_HCL_DBG_ID, + GPIO_HCL_DBG_ID, + POWER_HCL_DBG_ID, + PLL_HCL_DBG_ID, + HSI_HCL_DBG_ID, + DIF_HCL_DBG_ID, + SDMM_HCL_DBG_ID, + FIRDA_HCL_DBG_ID, + SSP_HCL_DBG_ID, + CLCD_HCL_DBG_ID, + SRC_HCL_DBG_ID, + RTT_HCL_DBG_ID, + USB_HCL_DBG_ID, + PWL_HCL_DBG_ID, + OWM_HCL_DBG_ID, + TSP_HCL_DBG_ID, + SSM_HCL_DBG_ID, + SECR_HCL_DBG_ID, + TDES_HCL_DBG_ID, + /*SHA1_HCL_DBG_ID,*/ + HASH_HCL_DBG_ID, + RNG_HCL_DBG_ID, + MSHC_HCL_DBG_ID, + SKE_HCL_DBG_ID, + SGA_HCL_DBG_ID, + CRYP_HCL_DBG_ID, + HPI_HCL_DBG_ID +} t_dbg_id; +/* Define the debug level. */ + +#define DEBUG_LEVEL0 DBGL_OFF +#define DEBUG_LEVEL1 ((t_uint32)DBGL_PUBLIC_FUNC_IN|(t_uint32)DBGL_PUBLIC_FUNC_OUT|(t_uint32)DBGL_ERROR|(t_uint32)DBGL_WARNING) +#define DEBUG_LEVEL2 ((t_uint32)DBGL_IN_ARGS|(t_uint32)DBGL_OUT_ARGS|(t_uint32)DBGL_RET_CODE) +#define DEBUG_LEVEL3 DBGL_INTERNAL +#define DEBUG_LEVEL4 DBGL_HCL_DEV + + +typedef enum +{ + DBGL_OFF = 0, + DBGL_PUBLIC_FUNC_IN = MASK_BIT0, + DBGL_PUBLIC_FUNC_OUT = MASK_BIT1, + DBGL_ERROR = MASK_BIT2, + DBGL_WARNING = MASK_BIT3, + DBGL_IN_ARGS = MASK_BIT4, + DBGL_OUT_ARGS = MASK_BIT5, + DBGL_RET_CODE = MASK_BIT6, + DBGL_INTERNAL = MASK_BIT7, + DBGL_HCL_DEV = MASK_BIT8, + DBGL_PRIV_FUNC_IN = MASK_BIT9, + DBGL_PRIV_FUNC_OUT = MASK_BIT10, + DBGL_PRIV_IN_ARGS = MASK_BIT11, + DBGL_PRIV_OUT_ARGS = MASK_BIT12, + DBGL_USER_1 = MASK_BIT13, + DBGL_USER_2 = MASK_BIT14, + DBGL_USER_3 = MASK_BIT15, + DBGL_USER_4 = MASK_BIT16, + DBGL_USER_5 = MASK_BIT17, + DBGL_USER_6 = MASK_BIT18, + DBGL_USER_7 = MASK_BIT19, + DBGL_USER_8 = MASK_BIT20, + DBGL_USER_9 = MASK_BIT21, + DBGL_RESERVED_0 = MASK_BIT22, + DBGL_RESERVED_1 = MASK_BIT23, + DBGL_RESERVED_2 = MASK_BIT24, + DBGL_RESERVED_3 = MASK_BIT25, + DBGL_RESERVED_4 = MASK_BIT26, + DBGL_RESERVED_5 = MASK_BIT27, + DBGL_RESERVED_6 = MASK_BIT28, + DBGL_RESERVED_7 = MASK_BIT29, + DBGL_RESERVED_8 = MASK_BIT30 +} t_dbg_level; + + + +#ifdef __DEBUG + +/*--------------------------------------------------------------------------* + * Macro * + *--------------------------------------------------------------------------*/ + +/* Begin of Private definitions */ + +/* + * Compiler define __ARMCC_VERSION returns PVtbbb where: + * P is the major version (1 for ADS and 2 for RVCT v2.1) + * V is the minor version + * t is the patch release + * bbb is the build +*/ +#if ((__ARMCC_VERSION >= 100000) && (__ARMCC_VERSION < 200000)) +/* ADS Compiler */ +#define DBGFUNCNAME __func__ +#elif (__ARMCC_VERSION < 300000) +/* RVCT Compiler */ +#define DBGFUNCNAME __FILE__ +#else +/* To be added - depends on the compiler to be used. Currently is left as empty */ +#define DBGFUNCNAME "" +#endif + + +/* End of Private definitions */ + + +/* Exit Macros */ + +#define DBGEXIT0(cr) \ + ((DBGL_PUBLIC_FUNC_OUT & MY_DEBUG_LEVEL_VAR_NAME) != DBGL_OFF)? \ + logMsg(MY_DEBUG_ID, DBGFUNCNAME, 0, "Exiting",0, 0, 0, 0, 0, 0, (unsigned long)(cr)): \ + (0) + +#define DBGEXIT1(cr,ch,p1) \ + ((DBGL_PUBLIC_FUNC_OUT & MY_DEBUG_LEVEL_VAR_NAME) != DBGL_OFF)? \ + logMsg(MY_DEBUG_ID, DBGFUNCNAME, ch, "Exiting",(unsigned long)(p1), 0, 0, 0, 0, 0, (unsigned long)(cr)): \ + (0) + +#define DBGEXIT2(cr,ch,p1,p2) \ + ((DBGL_PUBLIC_FUNC_OUT & MY_DEBUG_LEVEL_VAR_NAME) != DBGL_OFF)? \ + logMsg(MY_DEBUG_ID, DBGFUNCNAME, ch, "Exiting",(unsigned long)(p1), (unsigned long)(p2), 0, 0, 0, 0, (unsigned long)(cr)): \ + (0) + +#define DBGEXIT3(cr,ch,p1,p2,p3) \ + ((DBGL_PUBLIC_FUNC_OUT & MY_DEBUG_LEVEL_VAR_NAME) != DBGL_OFF)? \ + logMsg(MY_DEBUG_ID, DBGFUNCNAME, ch, "Exiting",(unsigned long)(p1), (unsigned long)(p2), (unsigned long)(p3), 0, 0, 0, (unsigned long)(cr)): \ + (0) + +#define DBGEXIT4(cr,ch,p1,p2,p3,p4) \ + ((DBGL_PUBLIC_FUNC_OUT & MY_DEBUG_LEVEL_VAR_NAME) != DBGL_OFF)? \ + logMsg(MY_DEBUG_ID, DBGFUNCNAME, ch, "Exiting",(unsigned long)(p1), (unsigned long)(p2), (unsigned long)(p3), (unsigned long)(p4), 0, 0, (unsigned long)(cr)): \ + (0) + + +#define DBGEXIT5(cr,ch,p1,p2,p3,p4,p5) \ + ((DBGL_PUBLIC_FUNC_OUT & MY_DEBUG_LEVEL_VAR_NAME) != DBGL_OFF)? \ + logMsg(MY_DEBUG_ID, DBGFUNCNAME, ch, "Exiting",(unsigned long)(p1), (unsigned long)(p2), (unsigned long)(p3), (unsigned long)(p4), (unsigned long)(p5), 0, (unsigned long)(cr)): \ + (0) + +#define DBGEXIT6(cr,ch,p1,p2,p3,p4,p5,p6) \ + ((DBGL_PUBLIC_FUNC_OUT & MY_DEBUG_LEVEL_VAR_NAME) != DBGL_OFF)? \ + logMsg(MY_DEBUG_ID, DBGFUNCNAME, ch, "Exiting",(unsigned long)(p1), (unsigned long)(p2), (unsigned long)(p3), (unsigned long)(p4), (unsigned long)(p5), (unsigned long)(p6), (unsigned long)(cr)): \ + (0) + +/* Enter macro's */ + +#define DBGENTER0() \ + ((DBGL_PUBLIC_FUNC_IN & MY_DEBUG_LEVEL_VAR_NAME) != DBGL_OFF)? \ + logMsg(MY_DEBUG_ID, DBGFUNCNAME, 0, "Entering Function",0, 0, 0, 0, 0, 0, 0): \ + (0) + +#define DBGENTER1(ch,p1) \ + ((DBGL_PUBLIC_FUNC_IN & MY_DEBUG_LEVEL_VAR_NAME) != DBGL_OFF)? \ + logMsg(MY_DEBUG_ID, DBGFUNCNAME, ch, "Entering Function",(unsigned long)(p1), 0, 0, 0, 0, 0,0): \ + (0) + +#define DBGENTER2(ch,p1,p2) \ + ((DBGL_PUBLIC_FUNC_IN & MY_DEBUG_LEVEL_VAR_NAME) != DBGL_OFF)? \ + logMsg(MY_DEBUG_ID, DBGFUNCNAME, ch, "Entering Function",(unsigned long)(p1), (unsigned long)(p2), 0, 0, 0, 0, 0): \ + (0) + +#define DBGENTER3(ch,p1,p2,p3) \ + ((DBGL_PUBLIC_FUNC_IN & MY_DEBUG_LEVEL_VAR_NAME) != DBGL_OFF)? \ + logMsg(MY_DEBUG_ID, DBGFUNCNAME, ch, "Entering Function",(unsigned long)(p1), (unsigned long)(p2), (unsigned long)(p3), 0, 0, 0, 0): \ + (0) + +#define DBGENTER4(ch,p1,p2,p3,p4) \ + ((DBGL_PUBLIC_FUNC_IN & MY_DEBUG_LEVEL_VAR_NAME) != DBGL_OFF)? \ + logMsg(MY_DEBUG_ID, DBGFUNCNAME, ch, "Entering Function",(unsigned long)(p1), (unsigned long)(p2), (unsigned long)(p3), (unsigned long)(p4), 0, 0, 0):\ + (0) + +#define DBGENTER5(ch,p1,p2,p3,p4,p5) \ + ((DBGL_PUBLIC_FUNC_IN & MY_DEBUG_LEVEL_VAR_NAME) != DBGL_OFF)? \ + logMsg(MY_DEBUG_ID, DBGFUNCNAME, ch, "Entering Function",(unsigned long)(p1), (unsigned long)(p2), (unsigned long)(p3), (unsigned long)(p4), (unsigned long)(p5), 0, 0):\ + (0) + +#define DBGENTER6(ch,p1,p2,p3,p4,p5,p6) \ + ((DBGL_PUBLIC_FUNC_IN & MY_DEBUG_LEVEL_VAR_NAME) != DBGL_OFF)? \ + logMsg(MY_DEBUG_ID, DBGFUNCNAME, ch, "Entering Function",(unsigned long)(p1), (unsigned long)(p2), (unsigned long)(p3), (unsigned long)(p4), (unsigned long)(p5), (unsigned long)(p6), 0):\ + (0) + + +#define DBGEXIT DBGEXIT0 +#define DBGENTER DBGENTER0 + +#define DBGPRINT(dbg_level,ch) \ + ((dbg_level & MY_DEBUG_LEVEL_VAR_NAME) != DBGL_OFF)? \ + logMsg(MY_DEBUG_ID, DBGFUNCNAME, ch, "",0, 0, 0, 0, 0, 0, 0): \ + (0) + +#define DBGPRINTHEX(dbg_level,ch, uint32) \ + ((dbg_level & MY_DEBUG_LEVEL_VAR_NAME) != DBGL_OFF)? \ + logMsg(MY_DEBUG_ID, DBGFUNCNAME, ch, "",(unsigned long)uint32, 0, 0, 0, 0, 0, 0): \ + (0) + +#define DBGPRINTDEC(dbg_level,ch, uint32) \ + ((dbg_level & MY_DEBUG_LEVEL_VAR_NAME) != DBGL_OFF)? \ + logMsg(MY_DEBUG_ID, DBGFUNCNAME, ch, "",(unsigned long)uint32, 0, 0, 0, 0, 0, 0): \ + (0) + +#endif /* __DEBUG */ + +#ifdef __RELEASE + +#define DBGEXIT(cr) +#define DBGEXIT0(cr) +#define DBGEXIT1(cr,ch,p1) +#define DBGEXIT2(cr,ch,p1,p2) +#define DBGEXIT3(cr,ch,p1,p2,p3) +#define DBGEXIT4(cr,ch,p1,p2,p3,p4) +#define DBGEXIT5(cr,ch,p1,p2,p3,p4,p5) +#define DBGEXIT6(cr,ch,p1,p2,p3,p4,p5,p6) + +#define DBGENTER() +#define DBGENTER0() +#define DBGENTER1(ch,p1) +#define DBGENTER2(ch,p1,p2) +#define DBGENTER3(ch,p1,p2,p3) +#define DBGENTER4(ch,p1,p2,p3,p4) +#define DBGENTER5(ch,p1,p2,p3,p4,p5) +#define DBGENTER6(ch,p1,p2,p3,p4,p5,p6) + +#define DBGENT1(ch,p1) +#define DBGENT2(ch,p1,p2) +#define DBGENT3(ch,p1,p2,p3) +#define DBGENT5(ch,p1,p2,p3,p4,p5) +#define DBGENT6(ch,p1,p2,p3,p4,p5,p6) + + + +#define DBGPRINT(dbg_level,dbg_string) +#define DBGPRINTHEX(dbg_level,dbg_string,uint32) +#define DBGPRINTDEC(dbg_level,dbg_string,uint32) + +#endif /* __RELEASE */ + + +/*--------------------------------------------------------------------------* + * C++ * + *--------------------------------------------------------------------------*/ +#ifdef __cplusplus +} /* allow C++ to use these headers */ +#endif /* __cplusplus */ + + +#endif /* __INC_DBG_H */ + +/* End of file - debug.h */ + + --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/hcl/include/hcl_defs.h @@ -0,0 +1,290 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ + + + + +#ifndef _HCL_DEFS_H +#define _HCL_DEFS_H + +#include "platform_os.h" + +/*----------------------------------------------------------------------------- + * Type definition + *---------------------------------------------------------------------------*/ +typedef unsigned char t_uint8; +typedef signed char t_sint8; +typedef unsigned short t_uint16; +typedef signed short t_sint16; +typedef unsigned long t_uint32; +typedef signed long t_sint32; + +#ifdef _WIN32_WCE +typedef unsigned __int64 t_uint64; +typedef __int64 t_sint64; +#else +/* typedef unsigned long long t_uint64; move to platform_os.h */ +/* typedef signed long long t_sint64; move to platform_os.h */ +#endif + +typedef unsigned int t_bitfield; + +#if !defined(FALSE) && !defined(TRUE) +typedef enum {FALSE, TRUE} t_bool; +#else /* FALSE & TRUE already defined */ +typedef enum {BOOL_FALSE, BOOL_TRUE} t_bool; +#endif /* !defined(FALSE) && !defined(TRUE) */ + +/* + * Definition of the different kind of addresses manipulated into a system with MMU + * (handle physical AND logical addresses) + */ +typedef t_uint32 t_physical_address; +typedef t_uint32 t_logical_address; + + + +/* + * Global frequency enumuration + * Added to avoid frequency conversion function which is required to convert one HCL + * frequency enumuration values to another HCL frequency enumuration values. + */ + +typedef enum { + HCL_FREQ_NOT_SUPPORTED=-1, + HCL_FREQ_8KHZ , + HCL_FREQ_11_25KHZ, + HCL_FREQ_12KHZ, + HCL_FREQ_16KHZ, + HCL_FREQ_22_05KHZ, + HCL_FREQ_22_5KHZ, + HCL_FREQ_24KHZ, + HCL_FREQ_32KHZ, + HCL_FREQ_44KHZ, + HCL_FREQ_44_1KHZ, + HCL_FREQ_48KHZ, + HCL_FREQ_64KHZ, + HCL_FREQ_88KHZ, + HCL_FREQ_88_2KHZ, + HCL_FREQ_96KHZ, + HCL_FREQ_128KHZ, + HCL_FREQ_176_4KHZ, + HCL_FREQ_192KHZ, + HCL_FREQ_1MHZ, + HCL_FREQ_2MHZ, + HCL_FREQ_3MHZ, + HCL_FREQ_4MHZ, + HCL_FREQ_5MHZ, + HCL_FREQ_6MHZ, + HCL_FREQ_8MHZ, + HCL_FREQ_11MHZ, + HCL_FREQ_12MHZ, + HCL_FREQ_16MHZ, + HCL_FREQ_22MHZ, + HCL_FREQ_24MHZ, + HCL_FREQ_48MHZ +} t_frequency; + + + +typedef struct { + t_physical_address physical; + t_logical_address logical; +} t_system_address; + + +/* + * Define a type used to manipulate size of various buffers + */ +typedef t_uint32 t_size; + +typedef struct { + t_bitfield minor:8; + t_bitfield major:8; + t_bitfield version:16; +} t_version; + + + + +/*----------------------------------------------------------------------------- + * Keyword definition + *---------------------------------------------------------------------------*/ +#define PUBLIC /* Extern by default */ +#define PRIVATE static + +#ifndef NULL +#define NULL (0) +#endif /* ndef NULL */ + +#define HCL_INTERNAL_ERROR (-8) +#define HCL_NOT_CONFIGURED (-7) +#define HCL_REQUEST_PENDING (-6) +#define HCL_REQUEST_NOT_APPLICABLE (-5) +#define HCL_INVALID_PARAMETER (-4) +#define HCL_UNSUPPORTED_FEATURE (-3) +#define HCL_UNSUPPORTED_HW (-2) +#define HCL_ERROR (-1) +#define HCL_OK ( 0) +#define HCL_INTERNAL_EVENT ( 1) +#define HCL_REMAINING_PENDING_EVENTS ( 2) +#define HCL_REMAINING_FILTER_PENDING_EVENTS ( 3) +#define HCL_NO_MORE_PENDING_EVENT ( 4) +#define HCL_NO_MORE_FILTER_PENDING_EVENT ( 5) +#define HCL_NO_PENDING_EVENT_ERROR ( 7) + + +#define HCL_MAX_ERROR_VALUE (-65) /* HCL specific error codes + * should start from this offset + */ + +/*----------------------------------------------------------------------------- + * Bit setting or clearing + *---------------------------------------------------------------------------*/ +#define HCL_SET_BITS(reg,mask) ((reg) |= (mask)) +#define HCL_CLEAR_BITS(reg,mask) ((reg) &= ~(mask)) +#define HCL_READ_BITS(reg,mask) ((reg) & (mask)) +#define HCL_WRITE_BITS(reg,val,mask) ((reg) = (((reg) & ~(mask)) | ((val) & (mask)))) +#define HCL_READ_REG(reg) (reg) +#define HCL_WRITE_REG(reg,val) ((reg) = (val)) + +/*----------------------------------------------------------------------------- + * field offset extraction from a structure + *---------------------------------------------------------------------------*/ +#define FIELD_OFFSET(typeName, fieldName) (t_uint32)(&(((typeName *)0)->fieldName)) +#define HCL_BITFIELD_OFFSET(typeName, fieldName) (t_uint32)(&(((typeName *)0)->fieldName)) + +/*----------------------------------------------------------------------------- + * Bit mask definition + *---------------------------------------------------------------------------*/ +#define MASK_NULL8 0x00 +#define MASK_NULL16 0x0000 +#define MASK_NULL32 0x00000000 +#define MASK_ALL8 0xFF +#define MASK_ALL16 0xFFFF +#define MASK_ALL32 0xFFFFFFFF + +#define MASK_BIT0 (1UL<<0) +#define MASK_BIT1 (1UL<<1) +#define MASK_BIT2 (1UL<<2) +#define MASK_BIT3 (1UL<<3) +#define MASK_BIT4 (1UL<<4) +#define MASK_BIT5 (1UL<<5) +#define MASK_BIT6 (1UL<<6) +#define MASK_BIT7 (1UL<<7) +#define MASK_BIT8 (1UL<<8) +#define MASK_BIT9 (1UL<<9) +#define MASK_BIT10 (1UL<<10) +#define MASK_BIT11 (1UL<<11) +#define MASK_BIT12 (1UL<<12) +#define MASK_BIT13 (1UL<<13) +#define MASK_BIT14 (1UL<<14) +#define MASK_BIT15 (1UL<<15) +#define MASK_BIT16 (1UL<<16) +#define MASK_BIT17 (1UL<<17) +#define MASK_BIT18 (1UL<<18) +#define MASK_BIT19 (1UL<<19) +#define MASK_BIT20 (1UL<<20) +#define MASK_BIT21 (1UL<<21) +#define MASK_BIT22 (1UL<<22) +#define MASK_BIT23 (1UL<<23) +#define MASK_BIT24 (1UL<<24) +#define MASK_BIT25 (1UL<<25) +#define MASK_BIT26 (1UL<<26) +#define MASK_BIT27 (1UL<<27) +#define MASK_BIT28 (1UL<<28) +#define MASK_BIT29 (1UL<<29) +#define MASK_BIT30 (1UL<<30) +#define MASK_BIT31 (1UL<<31) + +/*----------------------------------------------------------------------------- + * quartet shift definition + *---------------------------------------------------------------------------*/ +#define MASK_QUARTET (0xFUL) +#define SHIFT_QUARTET0 0 +#define SHIFT_QUARTET1 4 +#define SHIFT_QUARTET2 8 +#define SHIFT_QUARTET3 12 +#define SHIFT_QUARTET4 16 +#define SHIFT_QUARTET5 20 +#define SHIFT_QUARTET6 24 +#define SHIFT_QUARTET7 28 +#define MASK_QUARTET0 (MASK_QUARTET << SHIFT_QUARTET0) +#define MASK_QUARTET1 (MASK_QUARTET << SHIFT_QUARTET1) +#define MASK_QUARTET2 (MASK_QUARTET << SHIFT_QUARTET2) +#define MASK_QUARTET3 (MASK_QUARTET << SHIFT_QUARTET3) +#define MASK_QUARTET4 (MASK_QUARTET << SHIFT_QUARTET4) +#define MASK_QUARTET5 (MASK_QUARTET << SHIFT_QUARTET5) +#define MASK_QUARTET6 (MASK_QUARTET << SHIFT_QUARTET6) +#define MASK_QUARTET7 (MASK_QUARTET << SHIFT_QUARTET7) + +/*----------------------------------------------------------------------------- + * Byte shift definition + *---------------------------------------------------------------------------*/ +#define MASK_BYTE (0xFFUL) +#define SHIFT_BYTE0 0 +#define SHIFT_BYTE1 8 +#define SHIFT_BYTE2 16 +#define SHIFT_BYTE3 24 +#define MASK_BYTE0 (MASK_BYTE << SHIFT_BYTE0) +#define MASK_BYTE1 (MASK_BYTE << SHIFT_BYTE1) +#define MASK_BYTE2 (MASK_BYTE << SHIFT_BYTE2) +#define MASK_BYTE3 (MASK_BYTE << SHIFT_BYTE3) + +/*----------------------------------------------------------------------------- + * Halfword shift definition + *---------------------------------------------------------------------------*/ +#define MASK_HALFWORD (0xFFFFUL) +#define SHIFT_HALFWORD0 0 +#define SHIFT_HALFWORD1 16 +#define MASK_HALFWORD0 (MASK_HALFWORD << SHIFT_HALFWORD0) +#define MASK_HALFWORD1 (MASK_HALFWORD << SHIFT_HALFWORD1) + +/*----------------------------------------------------------------------------- + * Global constants definition + *---------------------------------------------------------------------------*/ + #define ONE_KB (1024) + #define ONE_MB (ONE_KB * ONE_KB) + + +/*----------------------------------------------------------------------------- + * Address translation macros declaration + *---------------------------------------------------------------------------*/ +#if defined(__EMUL) + +#define ARM_TO_AHB_ADDR(addr) (addr | MASK_BIT31) +#define AHB_TO_ARM_ADDR(addr) (addr & ~MASK_BIT31) +#endif /* efined(__EMUL) */ + +#if defined(__STN_8800) || defined(__STN_8810) || defined(__STN_8815) +#define ARM_TO_AHB_ADDR(addr) (addr) +#define AHB_TO_ARM_ADDR(addr) (addr) +#endif /* defined(__STN_8800) || defined(__STN_8810) || defined(__STN_8815) */ + +/* For input parameters - would not be changed by the API */ +#define IN +/* For output parameters - would be changes by the API */ +#define OUT +/* For input-output parameters - provides input to the API but would be changed by the API */ +#define INOUT + +#endif /* _HCL_DEFS_H */ + +/* End of file hcl_defs.h */ + --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/hcl/include/hloader.h @@ -0,0 +1,170 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ + +#ifndef _HLOADER_H_ +#define _HLOADER_H_ + +#ifdef __cplusplus +extern "C" +{ +#endif + +/*--------------------------------------------------------------------------* + * Includes * + *--------------------------------------------------------------------------*/ +#include "hcl_defs.h" + +/*--------------------------------------------------------------------------* + * Defines * + *--------------------------------------------------------------------------*/ +/* To signify that the while binary file has to be copied */ +#define WHOLE_FILE 0 + +#define BASE_ALIGNMENT_CHECK_32_BYTE 31 +#define BASE_ALIGNMENT_CHECK_64_BYTE 63 + +/* Errors types */ +typedef enum +{ + LOADER_OK = 0, + LOADER_NOT_ENOUGH_MEM = -1, + LOADER_BAD_MAGIC_CODE = -2, + LOADER_BAD_FILE_VERSION = -3, + LOADER_BAD_MACHINE = -4, + LOADER_UKN_MEMTYPE = -5, + LOADER_NO_DSP = -6, + LOADER_CHECK_ERROR = -7, + LOADER_INTERNAL = -8, + LOADER_CODE_NOT_LOADED = -9, + LOADER_BAD_BASE = -10, + LOADER_UNFINISHED = -11, + LOADER_BAD_ARCHI = -12 +} t_loader_error; + +/* Loader instruction masks */ +typedef enum +{ + LOAD_CODE = 0x1, + LOAD_DATA = 0x2, + CHECK_CODE = 0x4, + CHECK_DATA = 0x8, + DUMP = 0x10, + DUMP_SECTION = 0x20, + ALLOW_FORCED_COMPAT = 0x40, + ALLOW_DATAZONE_CHANGE = 0x80 +} t_loader_instr; + +/* Hamac code compression */ +typedef enum +{ + NO_COMPRESSION, + HA_VLC_COMPRESSION, + HV_DICT_COMPRESSION +} t_hamac_comp; + +typedef struct +{ + t_system_address Base; + t_system_address Top; + t_uint32 Size; +} t_ahb_zone; + +typedef enum +{ + TA_UNKNOWN = 0, + TA_8800A_8810A, /* 8800 audio any cut, 8810 audio cut 1.x */ + TA_8810A_B0, /* 8810 audio cut 2 */ + TA_8800V, /* 8800 video */ + TA_8810V_A0, /* 8810 video cut 1.x */ + TA_8810V_B0, /* 8810 video cut 2 */ + TA_8815A_A0, /* 8815 audio cut 1 */ + TA_8815V_A0, /* 8815 video cut 1 */ + TA_8815A_B0, /* 8815 audio cut 2 */ + TA_8815V_B0 /* 8815 video cut 2 */ +} t_core_id; + +typedef enum +{ + COMPAT_DFT_8800 = 0xF8, + COMPAT_8810_8815 = 0x1CF8, + COMPAT_DFT_8815_A0 = 0x10F8 +} t_compat; + +typedef struct loader_config t_loader_config; +typedef t_loader_error (*t_ahb_init_func) (t_loader_config * p_hloader_config); + +typedef struct +{ + t_hamac_comp compression; + t_ahb_init_func ahb_master_init; + t_ahb_init_func ahb_base_init; + t_core_id core_id; + t_compat compat; + t_uint16 nb_code_sections; +} t_loader_context; + +/* Loader configuration */ +struct loader_config +{ + t_uint32 *FirmwareBaseAddr; + t_uint32 FirmwareSize; + t_system_address HamacBaseAddr; + t_loader_instr LoadingInstr; + t_ahb_zone ProgramZone1; + t_ahb_zone ProgramZone2; + t_ahb_zone Data16Zone1; + t_ahb_zone Data16Zone2; + t_ahb_zone Data24Zone1; + t_ahb_zone Data24Zone2; + t_ahb_zone MmioZone; + t_uint16 Machine; + t_uint32 ToolsVersion; + t_sint8 FwVersion[8]; + t_loader_context Context; +}; + +typedef struct +{ + t_uint32 *BaseAddr; +} t_backup_config; + +/*--------------------------------------------------------------------------* + * Public functions declaration * + *--------------------------------------------------------------------------*/ +PUBLIC t_loader_error HLOADER_GetMemSizes(OUT t_loader_config *p_hloader_config); +PUBLIC t_loader_error HLOADER_Init(IN t_loader_config *p_hloader_config); +PUBLIC t_loader_error HLOADER_GetVersion(OUT t_version *p_version); +PUBLIC t_loader_error HLOADER_FirmwareLoad(IN t_loader_config *p_hloader_config); +PUBLIC t_loader_error HLOADER_PartialLoad(IN t_loader_config *p_hloader_config); +PUBLIC t_uint32 HLOADER_GetEsramSaaSectionSize(IN t_loader_config *p_hloader_config); +PUBLIC t_loader_error HLOADER_SaveEsramSaaSection(IN t_loader_config *p_hloader_config, IN t_backup_config *p_backup_config); +PUBLIC t_loader_error HLOADER_LoadEsramSaaSection(IN t_loader_config *p_hloader_config, IN t_backup_config *p_backup_config); +PUBLIC t_loader_error HLOADER_AHB_base_init(IN t_loader_config *p_hloader_config); +PUBLIC t_loader_error HLOADER_Boot(IN t_loader_config *p_hloader_config); +PUBLIC t_loader_error HLOADER_StopClock(IN t_loader_config *p_hloader_config); +PUBLIC t_loader_error HLOADER_StartClock(IN t_loader_config *p_hloader_config); +PUBLIC t_loader_error HLOADER_CacheConfig(IN t_loader_config *p_hloader_config , t_uint64 cache_mode); + +#ifdef __cplusplus +} /* allow C++ to use these headers */ +#endif /* __cplusplus */ +#endif /* _HLOADER_H_ */ + +/* End of file - hloader.h */ + --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/hcl/include/mupoc_mapping.h @@ -0,0 +1,1761 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ + +#ifndef __INC_MUPOC_MAPPING_H +#define __INC_MUPOC_MAPPING_H + +/*--------------------------------------------------------------------------*/ +#if defined (__EMUL) && (__EMUL < 100) + +/* VIC Controller configuration registers */ +#define VIC_CTRL_REG_BASE_ADDR 0xC3000000 +#define VIC_CTRL_REG_END_ADDR 0xC3FFFFFF + +/* CLCD Controller Configuration registers */ +#define CLCD_REG_BASE_ADDR 0xC1000000 +#define CLCD_REG_END_ADDR 0xC1FFFFFF + +/* CLCD Controller Share Ram */ +#define CLCD_RAM_BASE_ADDR 0xC2000000 +#define CLCD_RAM_END_ADDR 0xC2FFFFFF + +/* DMA0 Controller configuration registers */ +#define DMA0_REG_BASE_ADDR 0xD0000000 +#define DMA0_REG_END_ADDR 0xDFFFFFFF + +/* DMA1 Controller configuration registers */ +#define DMA1_CTRL_REG_BASE_ADDR 0x00000000 +#define DMA1_CTRL_REG_END_ADDR 0xFFFFFFFF + +/* Dual Timer Unit 0 registers (Timers 1 & 2) */ +#define DTU_0_REG_BASE_ADDR 0xC0600000 +#define DTU_0_REG_END_ADDR 0xC06FFFFF + +/* Dual Timer Unit 1 registers (Timers 3 & 4) */ +#define DTU_1_REG_BASE_ADDR 0xC0900000 +#define DTU_1_REG_END_ADDR 0xC09FFFFF + +/* UART 0 Interface Registers */ +#define UART_0_REG_BASE_ADDR 0xC0100000 +#define UART_0_REG_END_ADDR 0xC01FFFFF + +/* UART 1 Interface Registers */ +#define UART_1_REG_BASE_ADDR 0xC0200000 +#define UART_1_REG_END_ADDR 0xC02FFFFF + +/* Real Time Clock Registers */ +#define RTC_REG_BASE_ADDR 0xC0700000 +#define RTC_REG_END_ADDR 0xC0700FFF + +/* SSP Controller Configuration Registers */ +#define SSP_REG_BASE_ADDR 0xC0300000 +#define SSP_REG_END_ADDR 0xC03FFFFF + +#endif /* defined (__EMUL) && (__EMUL < 100) */ + +/*--------------------------------------------------------------------------*/ +#if defined (__EMUL) && (__EMUL >= 100) && (__EMUL < 200) + +/* VIC Controller configuration registers */ +#define VIC_CTRL_REG_BASE_ADDR 0xC3000000 +#define VIC_CTRL_REG_END_ADDR 0xC3FFFFFF + +/* CLCD Controller Configuration registers */ +#define CLCD_REG_BASE_ADDR 0xC1000000 +#define CLCD_REG_END_ADDR 0xC1FFFFFF + +/* CLCD Controller Share Ram */ +#define CLCD_RAM_BASE_ADDR 0xC2000000 +#define CLCD_RAM_END_ADDR 0xC2FFFFFF + +/* DMA0 Controller configuration registers */ +#define DMA0_CTRL_REG_BASE_ADDR 0xD0000000 +#define DMA0_CTRL_REG_END_ADDR 0xDFFFFFFF + +/* DMA1 Controller configuration registers */ +#define DMA1_CTRL_REG_BASE_ADDR 0x00000000 +#define DMA1_CTRL_REG_END_ADDR 0xFFFFFFFF + +/* Dual Timer Unit 0 registers (Timers 1 & 2) */ +#define DTU_0_REG_BASE_ADDR 0xC0600000 +#define DTU_0_REG_END_ADDR 0xC06FFFFF + +/* Dual Timer Unit 1 registers (Timers 3 & 4) */ +#define DTU_1_REG_BASE_ADDR 0xC0900000 +#define DTU_1_REG_END_ADDR 0xC09FFFFF + +/* UART 0 Interface Registers */ +#define UART_0_REG_BASE_ADDR 0xC0100000 +#define UART_0_REG_END_ADDR 0xC01FFFFF + +/* UART 1 Interface Registers */ +#define UART_1_REG_BASE_ADDR 0xC0200000 +#define UART_1_REG_END_ADDR 0xC02FFFFF + +/* Real Time Clock Registers */ +#define RTC_REG_BASE_ADDR 0xC0700000 +#define RTC_REG_END_ADDR 0xC0700FFF + +/* SSP Controller Configuration Registers */ +#define SSP_REG_BASE_ADDR 0xC0300000 +#define SSP_REG_END_ADDR 0xC03FFFFF + +#endif /* defined (__EMUL) && (__EMUL >= 100) && (__EMUL < 200) */ + +/*--------------------------------------------------------------------------*/ +#if defined (__EMUL) && (__EMUL >= 200) && (__EMUL < 300) + +/* VIC Controller configuration registers */ +#define VIC_CTRL_REG_BASE_ADDR 0xC3000000 +#define VIC_CTRL_REG_END_ADDR 0xC3FFFFFF + +/* CLCD Controller Configuration registers */ +#define CLCD_REG_BASE_ADDR 0xC1000000 +#define CLCD_REG_END_ADDR 0xC1FFFFFF + +/* CLCD Controller Share Ram */ +#define CLCD_RAM_BASE_ADDR 0xC2000000 +#define CLCD_RAM_END_ADDR 0xC2FFFFFF + +/* Dual Timer Unit 0 registers (Timers 1 & 2) */ +#define DTU_0_REG_BASE_ADDR 0xC0600000 +#define DTU_0_REG_END_ADDR 0xC06FFFFF + +/* Dual Timer Unit 1 registers (Timers 3 & 4) */ +#define DTU_1_REG_BASE_ADDR 0xC0900000 +#define DTU_1_REG_END_ADDR 0xC09FFFFF + +/* UART 0 Interface Registers */ +#define UART_0_REG_BASE_ADDR 0xC0100000 +#define UART_0_REG_END_ADDR 0xC01FFFFF + +/* UART 1 Interface Registers */ +#define UART_1_REG_BASE_ADDR 0xC0200000 +#define UART_1_REG_END_ADDR 0xC02FFFFF + +/* Real Time Clock Registers */ +#define RTC_REG_BASE_ADDR 0xC0700000 +#define RTC_REG_END_ADDR 0xC0700FFF + +/* SSP Controller Configuration Registers */ +#define SSP_REG_BASE_ADDR 0xC0300000 +#define SSP_REG_END_ADDR 0xC03FFFFF + +/* DMA0 Controller configuration registers */ +#define DMA0_CTRL_REG_BASE_ADDR 0xD0000000 +#define DMA0_CTRL_REG_END_ADDR 0xD7FFFFFF + +/* MEVB Control Registers */ +#define MEVB_CTRL_REG_BASE_ADDR 0xE0000000 +#define MEVB_CTRL_REG_END_ADDR 0xE01FFFFF + +/* I2C 0 Controller configuration registers */ +#define I2C_0_REG_BASE_ADDR 0xE0200000 +#define I2C_0_REG_END_ADDR 0xE02FFFFF + +/* ESIA (I2S) Controller configuration registers */ +#define ESIA_REG_BASE_ADDR 0xE0300000 +#define ESIA_REG_END_ADDR 0xE03FFFFF + +/* Audio Clock Prescaler configuration registers */ +#define AUDIO_PRESCALER_REG_BASE_ADDR 0xE0400000 +#define AUDIO_PRESCALER_REG_END_ADDR 0xE04FFFFF + +/* Display Interface configuration registers */ +#define DIF_REG_BASE_ADDR 0xE0600000 +#define DIF_REG_END_ADDR 0xE0FFFFFF + +/* MEVB Interrupt Registers */ +#define MEVB_IT_REG_BASE_ADDR 0xE1000000 +#define MEVB_IT_REG_END_ADDR 0xE1FFFFFF + +/* MEVB Embedded RAM */ +#define MEVB_RAM_BASE_ADDR 0xE2000000 +#define MEVB_RAM_END_ADDR 0xE3FFFFFF + +/* HAMAC Audio Memory Map */ +#define HA_BASE_ADDR 0xE4000000 +#define HA_END_ADDR 0xE4FFFFFF + +/* HAMAC Video Controller configuration registers */ +#define HV_REG_BASE_ADDR 0xE5000000 +#define HV_REG_END_ADDR 0xE50FFFFF + +/* HAMAC Video Data Memory Space */ +#define HV_MEM_BASE_ADDR 0xE5100000 +#define HV_MEM_END_ADDR 0xE51FFFFF + +/* DMA1 Controller configuration registers */ +#define DMA1_CTRL_REG_BASE_ADDR 0x00000000 +#define DMA1_CTRL_REG_END_ADDR 0xFFFFFFFF + +#define GPIO_0_REG_BASE_ADDRS 0xC0400000 +#define GPIO_1_REG_BASE_ADDRS 0xC0A00000 +#define GPIO_2_REG_BASE_ADDRS 0xC0C00000 + +#endif /* defined (__EMUL) && (__EMUL >= 200) && (__EMUL < 300) */ + +/*--------------------------------------------------------------------------*/ +#if defined (__EMUL) && (__EMUL >= 300) && (__EMUL < 400) + +/* VIC Controller configuration registers */ +#define VIC_CTRL_REG_BASE_ADDR 0xC3000000 +#define VIC_CTRL_REG_END_ADDR 0xC3FFFFFF + +/* CLCD Controller Configuration registers */ +#define CLCD_REG_BASE_ADDR 0xC1000000 +#define CLCD_REG_END_ADDR 0xC1FFFFFF + +/* CLCD Controller Share Ram */ +#define CLCD_RAM_BASE_ADDR 0xC2000000 +#define CLCD_RAM_END_ADDR 0xC2FFFFFF + +/* Dual Timer Unit 0 registers (Timers 1 & 2) */ +#define DTU_0_REG_BASE_ADDR 0xC0600000 +#define DTU_0_REG_END_ADDR 0xC06FFFFF + +/* Dual Timer Unit 1 registers (Timers 3 & 4) */ +#define DTU_1_REG_BASE_ADDR 0xC0900000 +#define DTU_1_REG_END_ADDR 0xC09FFFFF + +/* LM0 Control registers */ +#define LM0_CTRL_REG_BASE_ADDR 0xC0000000 +#define LM0_CTRL_REG_END_ADDR 0xC00FFFFF + +/* UART 0 Interface Registers */ +#define UART_0_REG_BASE_ADDR 0xC0100000 +#define UART_0_REG_END_ADDR 0xC01FFFFF + +/* UART 1 Interface Registers */ +#define UART_1_REG_BASE_ADDR 0xC0200000 +#define UART_1_REG_END_ADDR 0xC02FFFFF + +/* Real Time Clock Registers */ +#define RTC_REG_BASE_ADDR 0xC0700000 +#define RTC_REG_END_ADDR 0xC0700FFF + +/* SSP Controller Configuration Registers */ +#define SSP_REG_BASE_ADDR 0xC0300000 +#define SSP_REG_END_ADDR 0xC03FFFFF + +/* DMA0 Controller configuration registers */ +#define DMA0_CTRL_REG_BASE_ADDR 0xD0000000 +#define DMA0_CTRL_REG_END_ADDR 0xD0FFFFFF + +/* HSI Rx Configuration registers */ +#define HSI_RX_REG_BASE_ADDR 0xD1000000 +#define HSI_RX_REG_END_ADDR 0xD11FFFFF + +/* HSI Tx Configuration registers */ +#define HSI_TX_REG_BASE_ADDR 0xD1200000 +#define HSI_TX_REG_END_ADDR 0xD13FFFFF + +/* LM1 Control registers */ +#define LM1_CTRL_REG_BASE_ADDR 0xD1300000 +#define LM1_CTRL_REG_END_ADDR 0xD7FFFFFF + +/* MEVB Control Registers */ +#define MEVB_CTRL_REG_BASE_ADDR 0xE0000000 +#define MEVB_CTRL_REG_END_ADDR 0xE01FFFFF + +/* I2C 0 Controller configuration registers */ +#define I2C_0_REG_BASE_ADDR 0xE0200000 +#define I2C_0_REG_END_ADDR 0xE02FFFFF + +/* MSP (I2S) Controller configuration registers */ +#define MSP_REG_BASE_ADDR 0xE0300000 +#define MSP_REG_END_ADDR 0xE03FFFFF + +/* Display Interface configuration registers */ +#define DIF_REG_BASE_ADDR 0xE0600000 +#define DIF_REG_END_ADDR 0xE0FFFFFF + +/* I2C 1 Controller configuration registers */ +#define I2C_1_REG_BASE_ADDR 0xE0700000 +#define I2C_1_REG_END_ADDR 0xE07FFFFF + +/* MEVB Interrupt Registers */ +#define MEVB_IT_REG_BASE_ADDR 0xE1000000 +#define MEVB_IT_REG_END_ADDR 0xE1FFFFFF + +/* MEVB Embedded RAM */ +#define MEVB_RAM_BASE_ADDR 0xE2000000 +#define MEVB_RAM_END_ADDR 0xE3FFFFFF + +/* HAMAC Audio Memory Map */ +#define HA_BASE_ADDR 0xE4000000 +#define HA_END_ADDR 0xE4FFFFFF + +/* HAMAC Video Controller configuration registers */ +#define HV_REG_BASE_ADDR 0xE5000000 +#define HV_REG_END_ADDR 0xE50FFFFF + +/* HAMAC Video Data Memory Space */ +#define HV_MEM_BASE_ADDR 0xE5100000 +#define HV_MEM_END_ADDR 0xE51FFFFF + +/* DMA1 Controller configuration registers */ +#define DMA1_CTRL_REG_BASE_ADDR 0xE6000000 +#define DMA1_CTRL_REG_END_ADDR 0xE6FFFFFF + +#define GPIO_0_REG_BASE_ADDRS 0xC0400000 +#define GPIO_1_REG_BASE_ADDRS 0xC0A00000 +#define GPIO_2_REG_BASE_ADDRS 0xC0C00000 + + +#endif /* defined (__EMUL) && (__EMUL >= 300) && (__EMUL < 400) */ + + +/*--------------------------------------------------------------------------*/ +#if defined(__STN_8800) + +/* SDRAM bank 0 */ +#define SDRAM_BANK_0_BASE_ADDR 0x00000000 +#define SDRAM_BANK_0_END_ADDR 0x07FFFFFF + +/* SDRAM bank 1 */ +#define SDRAM_BANK_1_BASE_ADDR 0x08000000 +#define SDRAM_BANK_1_END_ADDR 0x0FFFFFFF + +/* Static Memory Controller configuration registers */ +#define SMC_CTRL_REG_BASE_ADDR 0x10100000 +#define SMC_CTRL_REG_END_ADDR 0x1010FFFF + +/* SDRAM Controller configuration registers */ +#define SDRAM_CTRL_REG_BASE_ADDR 0x10110000 +#define SDRAM_CTRL_REG_END_ADDR 0x1011FFFF + +/* CLCD Controller configuration registers */ +#define CLCD_REG_BASE_ADDR 0x10120000 +#define CLCD_REG_END_ADDR 0x1012FFFF + +/* DMA0 Controller configuration registers */ +#define DMA0_CTRL_REG_BASE_ADDR 0x10130000 +#define DMA0_CTRL_REG_END_ADDR 0x1013FFFF + +/* VIC Controller configuration registers */ +#define VIC_CTRL_REG_BASE_ADDR 0x10140000 +#define VIC_CTRL_REG_END_ADDR 0x1014FFFF + +/* DMA1 Controller configuration registers */ +#define DMA1_CTRL_REG_BASE_ADDR 0x10150000 +#define DMA1_CTRL_REG_END_ADDR 0x1015FFFF + +/* HAMAC Video Controller configuration registers */ +#define HV_REG_BASE_ADDR 0x10160000 +#define HV_REG_END_ADDR 0x1016FFFF + +/* Core APB Peripherals */ +#define CORE_APB_BASE_ADDR 0x101E0000 +#define CORE_APB_END_ADDR 0x101EFFFF + +/* System Controller registers */ +#define SYSCTRL_REG_BASE_ADDR 0x101E0000 +#define SYSCTRL_REG_END_ADDR 0x101E0FFF + +/* Watchdog registers */ +#define WDT_REG_BASE_ADDR 0x101E1000 +#define WDT_REG_END_ADDR 0x101E1FFF + +/* Dual Timer Unit 0 registers (Timers 1...2) */ +#define DTU_0_REG_BASE_ADDR 0x101E2000 +#define DTU_0_REG_END_ADDR 0x101E2FFF + +/* Dual Timer Unit 1 registers (Timers 3...4) */ +#define DTU_1_REG_BASE_ADDR 0x101E3000 +#define DTU_1_REG_END_ADDR 0x101E3FFF + +/* General Purpose I/Os registers (GPIO0: 0...15) */ +#define GPIO_0_REG_BASE_ADDR 0x101E4000 +#define GPIO_0_REG_END_ADDR 0x101E4FFF + +/* General Purpose I/Os registers (GPIO1: 16...31) */ +#define GPIO_1_REG_BASE_ADDR 0x101E5000 +#define GPIO_1_REG_END_ADDR 0x101E5FFF + +/* General Purpose I/Os registers (GPIO2: 32...47) */ +#define GPIO_2_REG_BASE_ADDR 0x101E6000 +#define GPIO_2_REG_END_ADDR 0x101E6FFF + +/* General Purpose I/Os registers (GPIO3: 48...63) */ +#define GPIO_3_REG_BASE_ADDR 0x101E7000 +#define GPIO_3_REG_END_ADDR 0x101E7FFF + +/* Real Time Clock Registers */ +#define RTC_REG_BASE_ADDR 0x101E8000 +#define RTC_REG_END_ADDR 0x101E8FFF + +/* Power Management Unit Registers */ +#define PMU_REG_BASE_ADDR 0x101E9000 +#define PMU_REG_END_ADDR 0x101E9FFF + +/* General Purpose I/Os registers (GPIO4) */ +#define GPIO_4_REG_BASE_ADDR 0x101EA000 +#define GPIO_4_REG_END_ADDR 0x101EAFFF + +/* General Purpose I/Os registers (GPIO5) */ +#define GPIO_5_REG_BASE_ADDR 0x101EB000 +#define GPIO_5_REG_END_ADDR 0x101EBFFF + +/* General Purpose I/Os registers (GPIO6) */ +#define GPIO_6_REG_BASE_ADDR 0x101EC000 +#define GPIO_6_REG_END_ADDR 0x101ECFFF + +/* General Purpose I/Os registers (GPIO7) */ +#define GPIO_7_REG_BASE_ADDR 0x101ED000 +#define GPIO_7_REG_END_ADDR 0x101EDFFF + +/* DMA APB Peripherals */ +#define DMA_APB_BASE_ADDR 0x101F0000 +#define DMA_APB_END_ADDR 0x101FFFFF + +/* HSI 8-ch Receive Interface Registers */ +#define HSI_RX_REG_BASE_ADDR 0x101F3000 +#define HSI_RX_REG_END_ADDR 0x101F3FFF + +/* HSI 8-ch Transmit Interface Registers */ +#define HSI_TX_REG_BASE_ADDR 0x101F4000 +#define HSI_TX_REG_END_ADDR 0x101F4FFF + +/* Display Interface */ +#define DIF_REG_BASE_ADDR 0x101F5000 +#define DIF_REG_END_ADDR 0x101F5FFF + +/* MM-Card/SD-Card Interface Registers */ +#define MCI_REG_BASE_ADDR 0x101F6000 +#define MCI_REG_END_ADDR 0x101F6FFF + +/* I2C 1 Interface Registers */ +#define I2C_1_REG_BASE_ADDR 0x101F7000 +#define I2C_1_REG_END_ADDR 0x101F7FFF + +/* I2C 0 Interface Registers */ +#define I2C_0_REG_BASE_ADDR 0x101F8000 +#define I2C_0_REG_END_ADDR 0x101F8FFF + +/* MSP (I2S) Interface Registers */ +#define MSP_REG_BASE_ADDR 0x101F9000 +#define MSP_REG_END_ADDR 0x101F9FFF + +/* UART 1 Interface Registers */ +#define UART_1_REG_BASE_ADDR 0x101FB000 +#define UART_1_REG_END_ADDR 0x101FBFFF + +/* SSP Interface Registers */ +#define SSP_REG_BASE_ADDR 0x101FC000 +#define SSP_REG_END_ADDR 0x101FCFFF + +/* UART 0 Interface Registers */ +#define UART_0_REG_BASE_ADDR 0x101FD000 +#define UART_0_REG_END_ADDR 0x101FDFFF + +/* Static Memory Controller Bank 0 */ +#define SMC_BANK_0_BASE_ADDR 0x30000000 +#define SMC_BANK_0_END_ADDR 0x33FFFFFF + +/* Static Memory Controller Bank 1 */ +#define SMC_BANK_1_BASE_ADDR 0x34000000 +#define SMC_BANK_1_END_ADDR 0x37FFFFFF + +/* (PC-Card)/NAND Flash Controller Bank 0 */ +#define NAND_FLASH_BANK_0_BASE_ADDR 0x40000000 +#define NAND_FLASH_BANK_0_END_ADDR 0x4FFFFFFF + +/* (PC-Card)/NAND Flash Controller Bank 1 */ +#define NAND_FLASH_BANK_1_BASE_ADDR 0x50000000 +#define NAND_FLASH_BANK_1_END_ADDR 0x5FFFFFFF + +/* Embedded boot ROM (32KBytes mapped only) */ +#define BOOT_ROM_BASE_ADDR 0x80000000 +#define BOOT_ROM_END_ADDR 0x8FFFFFFF + +/* Embedded secured SRAM (16KBytes mapped only) */ +#define SECURED_SRAM_BASE_ADDR 0x90000000 +#define SECURED_SRAM_END_ADDR 0x9FFFFFFF + +/* Embedded buffer SRAM (48KBytes mapped only) */ +#define EMBEDDED_SRAM_BASE_ADDR 0xA0000000 +#define EMBEDDED_SRAM_END_ADDR 0xA00FFFFF + +/* HAMAC Video Data Memory Space */ +#define HV_MEM_BASE_ADDR 0xA0100000 +#define HV_MEM_END_ADDR 0xA01FFFFF + +/* HAMAC Audio Data Memory Space */ +#define HA_BASE_ADDR 0xA0200000 +#define HA_END_ADDR 0xA02FFFFF + +/* Embedded secured ROM (64KBytes mapped only) */ +#define SECURED_ROM_BASE_ADDR 0xFFFF0000 +#define SECURED_ROM_END_ADDR 0xFFFFFFFF +#endif /* defined(__STN_8800) */ + +/*--------------------------------------------------------------------------*/ +#if defined(__STN_8810) + +/* SDRAM bank 0 */ +#define SDRAM_BANK_0_BASE_ADDR 0x00000000 +#define SDRAM_BANK_0_END_ADDR 0x07FFFFFF + +/* SDRAM bank 1 */ +#define SDRAM_BANK_1_BASE_ADDR 0x08000000 +#define SDRAM_BANK_1_END_ADDR 0x0FFFFFFF + +/* TSP (CPU OSMO/OSMOT address space) */ +#define TSP_BASE_ADDR 0x10000000 +#define TSP_END_ADDR 0x100FFFFF + +/* Static Memory Controller configuration registers */ +#define SMC_CTRL_REG_BASE_ADDR 0x10100000 +#define SMC_CTRL_REG_END_ADDR 0x1010FFFF + +/* SDRAM Controller configuration registers */ +#define SDRAM_CTRL_REG_BASE_ADDR 0x10110000 +#define SDRAM_CTRL_REG_END_ADDR 0x1011FFFF + +/* CLCD Controller configuration registers */ +#define CLCD_REG_BASE_ADDR 0x10120000 +#define CLCD_REG_END_ADDR 0x1012FFFF + +/* MDIF Controller configuration registers */ +#define MDIF_CTRL_REG_BASE_ADDR 0x10120000 +#define MDIF_CTRL_REG_END_ADDR 0x1012FFFF + +/* DMA0 Controller configuration registers */ +#define DMA0_CTRL_REG_BASE_ADDR 0x10130000 +#define DMA0_CTRL_REG_END_ADDR 0x1013FFFF + +/* VIC Controller configuration registers */ +#define VIC_CTRL_REG_BASE_ADDR 0x10140000 +#define VIC_CTRL_REG_END_ADDR 0x1014FFFF + +/* DMA1 Controller configuration registers */ +#define DMA1_CTRL_REG_BASE_ADDR 0x10150000 +#define DMA1_CTRL_REG_END_ADDR 0x1015FFFF + +/* HAMAC Video Controller configuration registers */ +#define HV_REG_BASE_ADDR 0x10160000 +#define HV_REG_END_ADDR 0x1016FFFF + +/* TDES configuration/data registers */ +#define TDES_REG_BASE_ADDR 0x10180000 +#define TDES_REG_END_ADDR 0x1018FFFF + +/* SHA-1 processor */ +#define SHA1_BASE_ADDR 0x10190000 +#define SHA1_END_ADDR 0x1019FFFF + +/* TSP configuration registers */ +#define TSP_CFG_REG_BASE_ADDR 0x101A0000 +#define TSP_CFG_REG_END_ADDR 0x101AFFFF + +/* RNG configuration registers */ +#define RNG_CFG_REG_BASE_ADDR 0x101B0000 +#define RNG_CFG_REG_END_ADDR 0x101BFFFF + +/* Core APB Peripherals */ +#define CORE_APB_BASE_ADDR 0x101E0000 +#define CORE_APB_END_ADDR 0x101EFFFF + +/* System Controller registers */ +#define SYSCTRL_REG_BASE_ADDR 0x101E0000 +#define SYSCTRL_REG_END_ADDR 0x101E0FFF + +/* Watchdog registers */ +#define WDT_REG_BASE_ADDR 0x101E1000 +#define WDT_REG_END_ADDR 0x101E1FFF + +/* Multi Timer Unit 0 registers (Timers 1...3) */ +#define MTU_0_REG_BASE_ADDR 0x101E2000 +#define MTU_0_REG_END_ADDR 0x101E2FFF + +/* Multi Timer Unit 1 registers (Timers 4...7) */ +#define MTU_1_REG_BASE_ADDR 0x101E3000 +#define MTU_1_REG_END_ADDR 0x101E3FFF + +/* General Purpose I/Os registers (GPIO0: 0...31) */ +#define GPIO_0_REG_BASE_ADDR 0x101E4000 +#define GPIO_0_REG_END_ADDR 0x101E4FFF + +/* General Purpose I/Os registers (GPIO1: 32...63) */ +#define GPIO_1_REG_BASE_ADDR 0x101E5000 +#define GPIO_1_REG_END_ADDR 0x101E5FFF + +/* General Purpose I/Os registers (GPIO2: 64...95) */ +#define GPIO_2_REG_BASE_ADDR 0x101E6000 +#define GPIO_2_REG_END_ADDR 0x101E6FFF + +/* Real Time Clock Registers */ +#define RTC_REG_BASE_ADDR 0x101E8000 +#define RTC_REG_END_ADDR 0x101E8FFF + +/* Real Time Clock Registers */ +#define PWL_REG_BASE_ADDR 0x101E8100 +#define PWL_REG_END_ADDR 0x101E8FFF + + +/* Real Time Clock Registers */ +#define RTT_REG_BASE_ADDR 0x101E8010 +#define RTT_REG_END_ADDR 0x101E8FFF + + +/* Power Management Unit Registers */ +#define PMU_REG_BASE_ADDR 0x101E9000 +#define PMU_REG_END_ADDR 0x101E9FFF + +/* One Wire Master Registers */ +#define OWM_REG_BASE_ADDR 0x101EA000 +#define OWM_REG_END_ADDR 0x101EAFFF + +/* Secure registers */ +#define SECURE_REG_BASE_ADDR 0x101EF000 +#define SECURE_REG_END_ADDR 0x101EFFFF + + +/* DMA APB Peripherals */ +#define DMA_APB_BASE_ADDR 0x101F0000 +#define DMA_APB_END_ADDR 0x101FFFFF + +/* MSP 2(I2S) Interface Registers */ +#define MSP_2_REG_BASE_ADDR 0x101F0000 +#define MSP_2_REG_END_ADDR 0x101F0FFF + +/* MSP 1(I2S) Interface Registers */ +#define MSP_1_REG_BASE_ADDR 0x101F1000 +#define MSP_1_REG_END_ADDR 0x101F1FFF + +/* UART 2 Interface Registers */ +#define UART_2_REG_BASE_ADDR 0x101F2000 +#define UART_2_REG_END_ADDR 0x101F2FFF + +/* HSI 8-ch Receive Interface Registers */ +#define HSI_RX_REG_BASE_ADDR 0x101F3000 +#define HSI_RX_REG_END_ADDR 0x101F3FFF + +/* HSI 8-ch Transmit Interface Registers */ +#define HSI_TX_REG_BASE_ADDR 0x101F4000 +#define HSI_TX_REG_END_ADDR 0x101F4FFF + +/* MM-Card/SD-Card Interface Registers */ +#define MCI_REG_BASE_ADDR 0x101F6000 +#define MCI_REG_END_ADDR 0x101F6FFF + +/* I2C 1 Interface Registers */ +#define I2C_1_REG_BASE_ADDR 0x101F7000 +#define I2C_1_REG_END_ADDR 0x101F7FFF + +/* I2C 0 Interface Registers */ +#define I2C_0_REG_BASE_ADDR 0x101F8000 +#define I2C_0_REG_END_ADDR 0x101F8FFF + +/* MSP 0(I2S) Interface Registers */ +#define MSP_0_REG_BASE_ADDR 0x101F9000 +#define MSP_0_REG_END_ADDR 0x101F9FFF + +/* FIrDA Interface Registers */ +#define FIRDA_REG_BASE_ADDR 0x101FA000 +#define FIRDA_REG_END_ADDR 0x101FAFFF + +/* UART 1 Interface Registers */ +#define UART_1_REG_BASE_ADDR 0x101FB000 +#define UART_1_REG_END_ADDR 0x101FBFFF + +/* SSP Interface Registers */ +#define SSP_REG_BASE_ADDR 0x101FC000 +#define SSP_REG_END_ADDR 0x101FCFFF + +/* UART 0 Interface Registers */ +#define UART_0_REG_BASE_ADDR 0x101FD000 +#define UART_0_REG_END_ADDR 0x101FDFFF + +#if defined(__MUSIK) +/* USB OTG configuration/data registers */ +#define USB_REG_BASE_ADDR 0x37E00000 +#define USB_REG_END_ADDR 0x37E4FFFF +#else +/* USB OTG configuration/data registers */ +#define USB_REG_BASE_ADDR 0x10300000 +#define USB_REG_END_ADDR 0x1034FFFF +#endif + +/* Static Memory Controller Bank 0 */ +#define SMC_BANK_0_BASE_ADDR 0x30000000 +#define SMC_BANK_0_END_ADDR 0x33FFFFFF + +/* Static Memory Controller Bank 1 */ +#define SMC_BANK_1_BASE_ADDR 0x34000000 +#define SMC_BANK_1_END_ADDR 0x37FFFFFF + +/* Static Memory Controller Bank 2 */ +#define SMC_BANK_2_BASE_ADDR 0x38000000 +#define SMC_BANK_2_END_ADDR 0x3BFFFFFF + +/* Static Memory Controller Bank 3 */ +#define SMC_BANK_3_BASE_ADDR 0x3C000000 +#define SMC_BANK_3_END_ADDR 0x3FFFFFFF + + +/* (PC-Card)/NAND Flash Controller Bank 0 */ +#define NAND_FLASH_BANK_0_BASE_ADDR 0x40000000 +#define NAND_FLASH_BANK_0_END_ADDR 0x4FFFFFFF + +/* (PC-Card)/NAND Flash Controller Bank 1 */ +#define NAND_FLASH_BANK_1_BASE_ADDR 0x50000000 +#define NAND_FLASH_BANK_1_END_ADDR 0x5FFFFFFF + +/* Embedded boot ROM (32KBytes mapped only) */ +#define BOOT_ROM_BASE_ADDR 0x80000000 +#define BOOT_ROM_END_ADDR 0x8000FFFF + +/* Embedded backup RAM (1KBytes mapped only) */ +#define BACKUP_RAM_BASE_ADDR 0x80010000 +#define BACKUP_RAM_END_ADDR 0x8001FFFF + +/* Embedded buffer SRAM (48KBytes mapped only) */ +#define EMBEDDED_SRAM_BASE_ADDR 0xA0000000 +#define EMBEDDED_SRAM_END_ADDR 0xA00FFFFF + +/* HAMAC Video Data Memory Space */ +#define HV_MEM_BASE_ADDR 0xA0100000 +#define HV_MEM_END_ADDR 0xA01FFFFF + +/* HAMAC Audio Data Memory Space */ +#define HA_BASE_ADDR 0xA0200000 +#define HA_END_ADDR 0xA02FFFFF + +/* Embedded secured SRAM (16KBytes mapped only) */ +#define SECURED_SRAM_BASE_ADDR 0xFFFE0000 +#define SECURED_SRAM_END_ADDR 0xFFFE3FFF + +/* Embedded secured ROM (64KBytes mapped only) */ +#define SECURED_ROM_BASE_ADDR 0xFFFF0000 +#define SECURED_ROM_END_ADDR 0xFFFFFFFF + +#endif /* defined(__STN_8810) */ + +/*--------------------------------------------------------------------------*/ +#if defined (__EMUL) && (__EMUL >= 400) && (__EMUL < 500) + +/* System Controller configuration registers */ +#define SYSCTRL_REG_BASE_ADDR 0xC0B00000 +// #define SYSCTRL_REG_BASE_ADDRR + +/* Power Management Unit Registers */ +#define PMU_REG_BASE_ADDR 0xC0F00000 +// #define PMU_REG_END_ADDR + +/* UART 0 Interface Registers */ +#define UART_0_REG_BASE_ADDR 0xC0100000 +// #define UART_0_REG_END_ADDR 0xC01FFFFF + +/* UART 1 Interface Registers */ +#define UART_1_REG_BASE_ADDR 0xC0200000 +// #define UART_1_REG_END_ADDR 0xC02FFFFF + +/* UART 2 Interface Registers */ +#define UART_2_REG_BASE_ADDR 0x16000000 +// #define UART_2_REG_END_ADDR + +/* UART 3 Interface Registers */ +#define UART_3_REG_BASE_ADDR 0x17000000 +// #define UART_3_REG_END_ADDR + +/* SSP Controller Configuration Registers */ +#define SSP_REG_BASE_ADDR 0xC0300000 +#define SSP_REG_END_ADDR 0xC03FFFFF + +/* GPIO Controller Configuration Registers */ +#define GPIO_0_REG_BASE_ADDR 0xC0400000 +#define GPIO_1_REG_BASE_ADDR 0xC0A00000 +#define GPIO_2_REG_BASE_ADDR 0xC0C00000 + +/* Real Time Controller Configuration Registers */ +#define RTC_REG_BASE_ADDR 0xC0700000 +#define RTC_REG_END_ADDR 0xC0700FFF + +/* Real Time Timer Configuration Registers */ +#define RTT_REG_BASE_ADDR 0xC0700010 +#define RTT_REG_END_ADDR 0xC0700FFF + +/* Dual Timer Unit 0 registers (Timers 1 & 2) ,correct*/ +#define MTU_0_REG_BASE_ADDR 0xC0600000 +#define MTU_0_REG_END_ADDR 0xC06FFFFF + +/* Dual Timer Unit 1 registers (Timers 3 & 4) ,correct*/ +#define MTU_1_REG_BASE_ADDR 0xC0900000 +#define MTU_1_REG_END_ADDR 0xC09FFFFF + +/* Watchdog registers */ +#define WDT_REG_BASE_ADDR 0xC0500000 +//#define WDT_REG_END_ADDR 0x101E1FFF + +/* CLCD Controller Configuration registers */ +#define CLCD_REG_BASE_ADDR 0xC1000000 +#define CLCD_REG_END_ADDR 0xC1FFFFFF + +/* CLCD Controller Share Ram */ +#define CLCD_RAM_BASE_ADDR 0xC2000000 +#define CLCD_RAM_END_ADDR 0xC2FFFFFF + + +/* VIC Controller configuration registers ,correct*/ +#define VIC_CTRL_REG_BASE_ADDR 0xC3000000 +#define VIC_CTRL_REG_END_ADDR 0xC3FFFFFF + +/* MM-Card/SD-Card Interface Registers */ +#define MCI_REG_BASE_ADDR 0xC0D00000 +//#define MCI_REG_END_ADDR 0x101F6FFF + +/* SHA-1 processor */ +#define SHA1_BASE_ADDR 0xC4000000 +//#define SHA1_END_ADDR 0x1019FFFF + +/* TDES configuration/data registers */ +#define TDES_REG_BASE_ADDR 0xC4001000 +//#define TDES_REG_END_ADDR 0x1018FFFF + +/* RNG configuration registers */ +#define RNG_CFG_REG_BASE_ADDR 0xC4002000 +//#define RNG_CFG_REG_END_ADDR 0x101BFFFF + +/* Secure registers */ +#define SECURE_REG_BASE_ADDR 0xC0E00000 +//#define SECURE_REG_END_ADDR 0x101EFFFF + +/* DMA0 Controller configuration registers */ +#define DMA0_CTRL_REG_BASE_ADDR 0xD0000000 +#define DMA0_CTRL_REG_END_ADDR 0xD0FFFFFF + +#if (__EMUL == 410) +/* HSI Rx Configuration registers */ +#define HSI_RX_REG_BASE_ADDR 0xD1000000 +#define HSI_RX_REG_END_ADDR 0xD11FFFFF + +/* HSI Tx Configuration registers */ +#define HSI_TX_REG_BASE_ADDR 0xD1200000 +#define HSI_TX_REG_END_ADDR 0xD13FFFFF +#endif + +#if (__EMUL == 420) +/* HSI Rx Configuration registers */ +#define HSI_RX_REG_BASE_ADDR 0xD1030000 +//#define HSI_RX_REG_END_ADDR 0xD11FFFFF + +/* HSI Tx Configuration registers */ +#define HSI_TX_REG_BASE_ADDR 0xD1040000 +//#define HSI_TX_REG_END_ADDR 0xD13FFFFF +#endif + +/* TSP configuration registers */ +#define TSP_CFG_REG_BASE_ADDR 0xD2000000 +//#define TSP_CFG_REG_END_ADDR 0x101AFFFF + +/* LM1 Control registers */ +#define LM1_CTRL_REG_BASE_ADDR 0xD1300000 +#define LM1_CTRL_REG_END_ADDR 0xD7FFFFFF + +/* HAMAC Audio Memory Map */ +#define HA_BASE_ADDR 0xE4000000 +#define HA_END_ADDR 0xE4FFFFFF + +/* HAMAC Video Controller configuration registers */ +#define HV_REG_BASE_ADDR 0xE5000000 +#define HV_REG_END_ADDR 0xE50FFFFF + +/* HAMAC Video Data Memory Space */ +#define HV_MEM_BASE_ADDR 0xE5100000 +#define HV_MEM_END_ADDR 0xE51FFFFF + +/* Display Interface configuration registers */ +#define DIF_REG_BASE_ADDR 0xE0600000 +#define DIF_REG_END_ADDR 0xE0FFFFFF + + +/* MSP (I2S) Controller configuration registers */ +#define MSP_REG_BASE_ADDR 0xE0300000 +#define MSP_REG_END_ADDR 0xE03FFFFF + +/* I2C0 Controller configuration registers */ +#define I2C_0_REG_BASE_ADDR 0xE0200000 +#define I2C_0_REG_END_ADDR 0xE02FFFFF + + +/* I2C1 Controller configuration registers */ +#define I2C_1_REG_BASE_ADDR 0xE0700000 +#define I2C_1_REG_END_ADDR 0xE07FFFFF + +/* DMA1 Controller configuration registers */ +#define DMA1_CTRL_REG_BASE_ADDR 0xE6000000 +#define DMA1_CTRL_REG_END_ADDR 0xE6FFFFFF + +/* MEVB Control Registers */ +#define MEVB_CTRL_REG_BASE_ADDR 0xE0000000 +#define MEVB_CTRL_REG_END_ADDR 0xE01FFFFF + + +/* MEVB Interrupt Registers */ +#define MEVB_IT_REG_BASE_ADDR 0xE1000000 +#define MEVB_IT_REG_END_ADDR 0xE1FFFFFF + +/* MEVB Embedded RAM */ +#define MEVB_RAM_BASE_ADDR 0xE2000000 +#define MEVB_RAM_END_ADDR 0xE3FFFFFF + +/* USB OTG configuration/data registers */ +#define USB_REG_BASE_ADDR 0xE7000000 +//#define USB_REG_END_ADDR 0x1017FFFF + +/* Static Memory Controller configuration registers */ +#define SMC_CTRL_REG_BASE_ADDR 0xE7100000 +#define SMC_CTRL_REG_END_ADDR 0xE7FFFFFF + +/* (PC-Card)/NAND Flash Controller Bank 0 */ +#define NAND_FLASH_BANK_0_BASE_ADDR 0xE8000000 +#define NAND_FLASH_BANK_0_END_ADDR 0xEFFFFFFF + + +#endif /* defined (__EMUL) && (__EMUL >= 400) && (__EMUL < 500) */ + +#if defined(__EMUL) && (__EMUL >= 500) + +/* System Controller configuration registers */ +#define SYSCTRL_REG_BASE_ADDR 0xC0C00000 +#define SYSCTRL_REG_END_ADDR 0xC0CFFFFF + +/* Power Management Unit Registers */ +#define PMU_REG_BASE_ADDR 0xC0F00000 +#define PMU_REG_END_ADDR 0xC0FFFFFF + +/* UART 0 Interface Registers */ +#define UART_0_REG_BASE_ADDR 0xC0100000 +#define UART_0_REG_END_ADDR 0xC01FFFFF + +/* UART 1 Interface Registers */ +#define UART_1_REG_BASE_ADDR 0xC0200000 +#define UART_1_REG_END_ADDR 0xC02FFFFF + +/* UART 2 Interface Registers */ +#define UART_2_REG_BASE_ADDR 0x16000000 +#define UART_2_REG_END_ADDR 0x16FFFFFF + +/* UART 3 Interface Registers */ +#define UART_3_REG_BASE_ADDR 0x17000000 +#define UART_3_REG_END_ADDR 0x17FFFFFF + +/* SSP Controller Configuration Registers */ +#define SSP_REG_BASE_ADDR 0xC0300000 +#define SSP_REG_END_ADDR 0xC03FFFFF + +/* GPIO Controller Configuration Registers */ +#define GPIO_0_REG_BASE_ADDR 0xC0400000 +#define GPIO_1_REG_BASE_ADDR 0xC0A00000 +#define GPIO_2_REG_BASE_ADDR 0xC0C00000 + +/* Real Time Controller Configuration Registers */ +#define RTC_REG_BASE_ADDR 0xC0700000 +#define RTC_REG_END_ADDR 0xC07FFFFF + +/* Real Time Timer Configuration Registers */ +#define RTT_REG_BASE_ADDR 0xC0700010 +#define RTT_REG_END_ADDR 0xC07FFFFF + +/* Dual Timer Unit 0 registers (Timers 1 & 2) ,correct*/ +#define MTU_0_REG_BASE_ADDR 0xC0600000 +#define MTU_0_REG_END_ADDR 0xC06FFFFF + +/* Dual Timer Unit 1 registers (Timers 3 & 4) ,correct*/ +#define MTU_1_REG_BASE_ADDR 0xC0900000 +#define MTU_1_REG_END_ADDR 0xC09FFFFF + +/* Watchdog registers */ +#define WDT_REG_BASE_ADDR 0xC0500000 +#define WDT_REG_END_ADDR 0xC057FFFF + +/* CLCD Controller Configuration registers */ +#define CLCD_REG_BASE_ADDR 0xC1000000 +#define CLCD_REG_END_ADDR 0xC1FFFFFF + +/* CLCD Controller Share Ram */ +#define CLCD_RAM_BASE_ADDR 0xC2000000 +#define CLCD_RAM_END_ADDR 0xC2FFFFFF + + +/* VIC Controller configuration registers ,correct*/ +#define VIC_CTRL_REG_BASE_ADDR 0xC3000000 +#define VIC_CTRL_REG_END_ADDR 0xC3FFFFFF + +/* MM-Card/SD-Card Interface Registers */ +#define MCI_REG_BASE_ADDR 0xC0D00000 +#define MCI_REG_END_ADDR 0xC0DFFFFF + +/* SHA-1 processor */ +#define SHA1_BASE_ADDR 0xC4000000 +#define SHA1_END_ADDR 0xC4000FFF + +/* TDES configuration/data registers */ +#define TDES_REG_BASE_ADDR 0xC4001000 +#define TDES_REG_END_ADDR 0xC4001FFF + +/* RNG configuration registers */ +#define RNG_CFG_REG_BASE_ADDR 0xC4002000 +#define RNG_CFG_REG_END_ADDR 0xC4002FFF + +/* Secure registers */ +#define SECURE_REG_BASE_ADDR 0xC0E00000 +#define SECURE_REG_END_ADDR 0xC0FFFFFF + +/* DMA0 Controller configuration registers */ +#define DMA0_CTRL_REG_BASE_ADDR 0xD0000000 +#define DMA0_CTRL_REG_END_ADDR 0xD102FFFF + +/* HSI Rx Configuration registers */ +#define HSI_RX_REG_BASE_ADDR 0xD1030000 +#define HSI_RX_REG_END_ADDR 0xD103FFFF + +/* HSI Tx Configuration registers */ +#define HSI_TX_REG_BASE_ADDR 0xD1040000 +#define HSI_TX_REG_END_ADDR 0xD11FFFFF + +/* TSP configuration registers */ +#define TSP_CFG_REG_BASE_ADDR 0xD2000000 +#define TSP_CFG_REG_END_ADDR 0xD2FFFFFF + +/* LM1 Control registers */ +#define LM1_CTRL_REG_BASE_ADDR 0xD1300000 +#define LM1_CTRL_REG_END_ADDR 0xD1FFFFFF + +/* HAMAC Audio Memory Map */ +#define HA_BASE_ADDR 0xE4000000 +#define HA_END_ADDR 0xE4FFFFFF + +/* HAMAC Video Controller configuration registers */ +#define HV_REG_BASE_ADDR 0xE5000000 +#define HV_REG_END_ADDR 0xE50FFFFF + +/* HAMAC Video Data Memory Space */ +#define HV_MEM_BASE_ADDR 0xE5100000 +#define HV_MEM_END_ADDR 0xE51FFFFF + +/* Display Interface configuration registers */ +#define DIF_REG_BASE_ADDR 0xE0600000 +#define DIF_REG_END_ADDR 0xE06FFFFF + +/* MSP (I2S) Controller configuration registers */ +#define MSP_REG_BASE_ADDR 0xE0300000 +#define MSP_REG_END_ADDR 0xE03FFFFF + +/* I2C0 Controller configuration registers */ +#define I2C_0_REG_BASE_ADDR 0xE0200000 +#define I2C_0_REG_END_ADDR 0xE02FFFFF + + +/* I2C1 Controller configuration registers */ +#define I2C_1_REG_BASE_ADDR 0xE0700000 +#define I2C_1_REG_END_ADDR 0xE07FFFFF + +/* DMA1 Controller configuration registers */ +#define DMA1_CTRL_REG_BASE_ADDR 0xE6000000 +#define DMA1_CTRL_REG_END_ADDR 0xE6FFFFFF + +/* MEVB Control Registers */ +#define MEVB_CTRL_REG_BASE_ADDR 0xE0000000 +#define MEVB_CTRL_REG_END_ADDR 0xE01FFFFF + + +/* MEVB Interrupt Registers */ +#define MEVB_IT_REG_BASE_ADDR 0xE1000000 +#define MEVB_IT_REG_END_ADDR 0xE1FFFFFF + +/* MEVB Embedded RAM */ +#define MEVB_RAM_BASE_ADDR 0xE3000000 +#define MEVB_RAM_END_ADDR 0xE30FFFFF + +/* USB OTG configuration/data registers */ +#define USB_REG_BASE_ADDR 0xE7000000 +#define USB_REG_END_ADDR 0xE70FFFFF + +/* Static Memory Controller configuration registers */ +#define SMC_CTRL_REG_BASE_ADDR 0xE7100000 +#define SMC_CTRL_REG_END_ADDR 0xE7FFFFFF + +/* (PC-Card)/NAND Flash Controller Bank 0 */ +#define NAND_FLASH_BANK_0_BASE_ADDR 0xE8000000 +#define NAND_FLASH_BANK_0_END_ADDR 0xEFFFFFFF + +/* MDIF Controller configuration registers */ +#define MDIF_CTRL_REG_BASE_ADDR 0xE3100000 +#define MDIF_CTRL_REG_END_ADDR 0xE3FFFFFF + +/* Scroll Key Encoder Registers */ +#define SKE_REG_BASE_ADDR 0xD1200000 +#define SKE_REG_END_ADDR 0xD12FFFFF + +/* Memory Stick(Pro) Host Controller Registers */ +#define MSHC_REG_BASE_ADDR 0xC0580000 +#define MSHC_REG_END_ADDR 0xC0580FFF + +/* SGA Interface Registers */ +#define SGA_REG_BASE_ADDR 0xE6100000 +#define SGA_REG_END_ADDR 0xE6100FFF + +#endif /* defined(__EMUL) */ + +/*--------------------------------------------------------------------------*/ +#if defined(__STN_8815) + +/* SDRAM bank 0 */ +#define SDRAM_BANK_0_BASE_ADDR 0x00000000 +#define SDRAM_BANK_0_END_ADDR 0x07FFFFFF + +/* SDRAM bank 1 */ +#define SDRAM_BANK_1_BASE_ADDR 0x08000000 +#define SDRAM_BANK_1_END_ADDR 0x0FFFFFFF + +/* TSP (CPU OSMO/OSMOT address space) */ +#define TSP_BASE_ADDR 0x10000000 +#define TSP_END_ADDR 0x100FFFFF + +/* Static Memory Controller configuration registers */ +#define SMC_CTRL_REG_BASE_ADDR 0x10100000 +#define SMC_CTRL_REG_END_ADDR 0x1010FFFF + +/* SDRAM Controller configuration registers */ +#define SDRAM_CTRL_REG_BASE_ADDR 0x10110000 +#define SDRAM_CTRL_REG_END_ADDR 0x1011FFFF + +/* CLCD Controller configuration registers */ +#define CLCD_REG_BASE_ADDR 0x10120000 +#define CLCD_REG_END_ADDR 0x1012FFFF + +/* MDIF Controller configuration registers */ +#define MDIF_CTRL_REG_BASE_ADDR 0x10120000 +#define MDIF_CTRL_REG_END_ADDR 0x1012FFFF + +/* DMA0 Controller configuration registers */ +#define DMA0_CTRL_REG_BASE_ADDR 0x10130000 +#define DMA0_CTRL_REG_END_ADDR 0x1013FFFF + +/* VIC Controller configuration registers */ +#define VIC_CTRL_REG_BASE_ADDR 0x10140000 +#define VIC_CTRL_REG_END_ADDR 0x1014FFFF + +/* DMA1 Controller configuration registers */ +#define DMA1_CTRL_REG_BASE_ADDR 0x10150000 +#define DMA1_CTRL_REG_END_ADDR 0x1015FFFF + +/* HAMAC Video Controller configuration registers */ +#define HV_REG_BASE_ADDR 0xA0140000 +#define HV_REG_END_ADDR 0xA01603FF + +/* USB OTG configuration/data registers */ +#define USB_REG_BASE_ADDR 0x10170000 +#define USB_REG_END_ADDR 0x1017FFFF + +/* Cryptographic processor configuration/data registers */ +#define CRYP_REG_BASE_ADDR 0x10180000 +#define CRYP_REG_END_ADDR 0x1018FFFF + +/* HASH processor */ +#define HASH_BASE_ADDR 0x10190000 +#define HASH_END_ADDR 0x1019FFFF + + +/* TSP configuration registers */ +#define TSP_CFG_REG_BASE_ADDR 0x101A0000 +#define TSP_CFG_REG_END_ADDR 0x101AFFFF + +/* RNG configuration registers */ +#define RNG_CFG_REG_BASE_ADDR 0x101B0000 +#define RNG_CFG_REG_END_ADDR 0x101BFFFF + +#if (__STN_8815>10) /* changes to support STN_8815 cut B0 */ +/* DMA APB Peripherals */ +#define DMA_APB_BASE_ADDR_1 0x101C0000 +#define DMA_APB_END_ADDR_1 0x101DFFFF + +/* MSP 3(I2S) Interface Registers */ +#define MSP_3_REG_BASE_ADDR 0x101C0000 +#define MSP_3_REG_END_ADDR 0x101CFFFF + +#endif + +/* Core APB Peripherals */ +#define CORE_APB_BASE_ADDR 0x101E0000 +#define CORE_APB_END_ADDR 0x101EFFFF + +/* System Controller registers */ +#define SYSCTRL_REG_BASE_ADDR 0x101E0000 +#define SYSCTRL_REG_END_ADDR 0x101E0FFF + +/* Watchdog registers */ +#define WDT_REG_BASE_ADDR 0x101E1000 +#define WDT_REG_END_ADDR 0x101E1FFF + +/* Multi Timer Unit 0 registers (Timers 1...3) */ +#define MTU_0_REG_BASE_ADDR 0x101E2000 +#define MTU_0_REG_END_ADDR 0x101E2FFF + +/* Multi Timer Unit 1 registers (Timers 4...7) */ +#define MTU_1_REG_BASE_ADDR 0x101E3000 +#define MTU_1_REG_END_ADDR 0x101E3FFF + +/* General Purpose I/Os registers (GPIO0: 0...31) */ +#define GPIO_0_REG_BASE_ADDR 0x101E4000 +#define GPIO_0_REG_END_ADDR 0x101E4FFF + +/* General Purpose I/Os registers (GPIO1: 32...63) */ +#define GPIO_1_REG_BASE_ADDR 0x101E5000 +#define GPIO_1_REG_END_ADDR 0x101E5FFF + +/* General Purpose I/Os registers (GPIO2: 64...95) */ +#define GPIO_2_REG_BASE_ADDR 0x101E6000 +#define GPIO_2_REG_END_ADDR 0x101E6FFF + +/* General Purpose I/Os registers (GPIO3: 96...123) */ +#define GPIO_3_REG_BASE_ADDR 0x101E7000 +#define GPIO_3_REG_END_ADDR 0x101E7FFF + +/* Real Time Clock Registers */ +#define RTC_REG_BASE_ADDR 0x101E8000 +#define RTC_REG_END_ADDR 0x101E8FFF + +/* Real Time Clock Registers */ +#define PWL_REG_BASE_ADDR 0x101E8100 +#define PWL_REG_END_ADDR 0x101E8FFF + +/* Real Time Clock Registers */ +#define RTT_REG_BASE_ADDR 0x101E8010 +#define RTT_REG_END_ADDR 0x101E8FFF + + +/* Power Management Unit Registers */ +#define PMU_REG_BASE_ADDR 0x101E9000 +#define PMU_REG_END_ADDR 0x101E9FFF + +/* One Wire Master Registers */ +#define OWM_REG_BASE_ADDR 0x101EA000 +#define OWM_REG_END_ADDR 0x101EAFFF + +/* Scroll Key Encoder Registers */ +#define SKE_REG_BASE_ADDR 0x101EB000 +#define SKE_REG_END_ADDR 0x101EBFFF + +/* HPI mailbox */ +#define HPI_REG_BASE_ADDR 0x101EC000 +#define HPI_REG_END_ADDR 0x101ECFFF + +/* Secure registers */ +#define SECURE_REG_BASE_ADDR 0x101EF000 +#define SECURE_REG_END_ADDR 0x101EFFFF + +/* DMA APB Peripherals */ +#define DMA_APB_BASE_ADDR 0x101F0000 +#define DMA_APB_END_ADDR 0x101FFFFF + +/* MSP 2(I2S) Interface Registers */ +#define MSP_2_REG_BASE_ADDR 0x101F0000 +#define MSP_2_REG_END_ADDR 0x101F0FFF + +/* MSP 1(I2S) Interface Registers */ +#define MSP_1_REG_BASE_ADDR 0x101F1000 +#define MSP_1_REG_END_ADDR 0x101F1FFF + +/* UART 2 Interface Registers */ +#define UART_2_REG_BASE_ADDR 0x101F2000 +#define UART_2_REG_END_ADDR 0x101F2FFF + +/* HSI 8-ch Receive Interface Registers */ +#define HSI_RX_REG_BASE_ADDR 0x101F3000 +#define HSI_RX_REG_END_ADDR 0x101F3FFF + +/* HSI 8-ch Transmit Interface Registers */ +#define HSI_TX_REG_BASE_ADDR 0x101F4000 +#define HSI_TX_REG_END_ADDR 0x101F4FFF + +/* Memory Stick(Pro) Host Controller Registers */ +#define MSHC_REG_BASE_ADDR 0x101F5000 +#define MSHC_REG_END_ADDR 0x101F5FFF + +/* MM-Card/SD-Card Interface Registers */ +#define MCI_REG_BASE_ADDR 0x101F6000 +#define MCI_REG_END_ADDR 0x101F6FFF + +/* I2C 1 Interface Registers */ +#define I2C_1_REG_BASE_ADDR 0x101F7000 +#define I2C_1_REG_END_ADDR 0x101F7FFF + +/* I2C 0 Interface Registers */ +#define I2C_0_REG_BASE_ADDR 0x101F8000 +#define I2C_0_REG_END_ADDR 0x101F8FFF + +/* MSP 0(I2S) Interface Registers */ +#define MSP_0_REG_BASE_ADDR 0x101F9000 +#define MSP_0_REG_END_ADDR 0x101F9FFF + +/* FIrDA Interface Registers */ +#define FIRDA_REG_BASE_ADDR 0x101FA000 +#define FIRDA_REG_END_ADDR 0x101FAFFF + +/* UART 1 Interface Registers */ +#define UART_1_REG_BASE_ADDR 0x101FB000 +#define UART_1_REG_END_ADDR 0x101FBFFF + +/* SSP Interface Registers */ +#define SSP_REG_BASE_ADDR 0x101FC000 +#define SSP_REG_END_ADDR 0x101FCFFF + +/* UART 0 Interface Registers */ +#define UART_0_REG_BASE_ADDR 0x101FD000 +#define UART_0_REG_END_ADDR 0x101FDFFF + +/* SGA Interface Registers */ +#define SGA_REG_BASE_ADDR 0x101FE000 +#define SGA_REG_END_ADDR 0x101FEFFF + +/* L2CC Interface Registers */ +#define L2CC_REG_BASE_ADDR 0x10210000 +#define L2CC_REG_END_ADDR 0x1021FFFF + +/* Static Memory Controller Bank 0 */ +#define SMC_BANK_0_BASE_ADDR 0x30000000 +#define SMC_BANK_0_END_ADDR 0x33FFFFFF + +/* Static Memory Controller Bank 1 */ +#define SMC_BANK_1_BASE_ADDR 0x34000000 +#define SMC_BANK_1_END_ADDR 0x37FFFFFF + +/* Static Memory Controller Bank 2 */ +#define SMC_BANK_2_BASE_ADDR 0x38000000 +#define SMC_BANK_2_END_ADDR 0x3BFFFFFF + +/* Static Memory Controller Bank 3 */ +#define SMC_BANK_3_BASE_ADDR 0x3C000000 +#define SMC_BANK_3_END_ADDR 0x3FFFFFFF + + +/* (PC-Card)/NAND Flash Controller Bank 0 */ +#define NAND_FLASH_BANK_0_BASE_ADDR 0x40000000 +#define NAND_FLASH_BANK_0_END_ADDR 0x4FFFFFFF + +/* (PC-Card)/NAND Flash Controller Bank 1 */ +#define NAND_FLASH_BANK_1_BASE_ADDR 0x50000000 +#define NAND_FLASH_BANK_1_END_ADDR 0x5FFFFFFF + +/* Embedded boot ROM (32KBytes mapped only) */ +#define BOOT_ROM_BASE_ADDR 0x80000000 +#define BOOT_ROM_END_ADDR 0x8000FFFF + +/* Embedded backup RAM (1KBytes mapped only) */ +#define BACKUP_RAM_BASE_ADDR 0x80010000 +#define BACKUP_RAM_END_ADDR 0x8001FFFF + +/* Embedded buffer SRAM (48KBytes mapped only) */ +#define EMBEDDED_SRAM_BASE_ADDR 0xA0000000 +#define EMBEDDED_SRAM_END_ADDR 0xA007FFFF + +#define EMBEDDED_SRAM_BANK_0_BASE_ADDR 0xA0000000 +#define EMBEDDED_SRAM_BANK_0_END_ADDR 0xA001FFFF + +#define EMBEDDED_SRAM_BANK_1_BASE_ADDR 0xA0020000 +#define EMBEDDED_SRAM_BANK_1_END_ADDR 0xA003FFFF + +#define EMBEDDED_SRAM_BANK_2_BASE_ADDR 0xA0040000 +#define EMBEDDED_SRAM_BANK_2_END_ADDR 0xA005FFFF + +#define EMBEDDED_SRAM_BANK_3_BASE_ADDR 0xA0060000 +#define EMBEDDED_SRAM_BANK_3_END_ADDR 0xA007FFFF + +/* HAMAC Video Data Memory Space */ +#define HV_MEM_BASE_ADDR 0xA0100000 +#define HV_MEM_END_ADDR 0xA01FFFFF + +/* HAMAC Audio Data Memory Space */ +#define HA_BASE_ADDR 0xA0200000 +#define HA_END_ADDR 0xA02FFFFF + +/* Embedded secured SRAM (16KBytes mapped only) */ +#define SECURED_SRAM_BASE_ADDR 0xFFFE0000 +#define SECURED_SRAM_END_ADDR 0xFFFE3FFF + +/* Embedded secured ROM (64KBytes mapped only) */ +#define SECURED_ROM_BASE_ADDR 0xFFFF0000 +#define SECURED_ROM_END_ADDR 0xFFFFFFFF + + +#endif /* defined(__STN_8815) */ + +/*--------------------------------------------------------------------------*/ +#if defined(__STN_8820) + +/* SDRAM bank 0 */ +#define SDRAM_BANK_0_BASE_ADDR 0x00000000 +#define SDRAM_BANK_0_END_ADDR 0x0FFFFFFF + +/* SDRAM bank 1 */ +#define SDRAM_BANK_1_BASE_ADDR 0x10000000 +#define SDRAM_BANK_1_END_ADDR 0x1FFFFFFF + +/* Embedded buffer SRAM (1024KBytes) */ +#define EMBEDDED_SRAM_BASE_ADDR 0x20000000 +#define EMBEDDED_SRAM_END_ADDR 0x200FFFFF + +/* Static Memory Controller Bank 0 */ +#define SMC_BANK_0_BASE_ADDR 0x30000000 +#define SMC_BANK_0_END_ADDR 0x33FFFFFF + +/* Static Memory Controller Bank 1 */ +#define SMC_BANK_1_BASE_ADDR 0x34000000 +#define SMC_BANK_1_END_ADDR 0x37FFFFFF + +/* Static Memory Controller Bank 2 */ +#define SMC_BANK_2_BASE_ADDR 0x38000000 +#define SMC_BANK_2_END_ADDR 0x3BFFFFFF + +/* Static Memory Controller Bank 3 */ +#define SMC_BANK_3_BASE_ADDR 0x3C000000 +#define SMC_BANK_3_END_ADDR 0x3FFFFFFF + +/* (PC-Card)/NAND Flash Controller Bank 0 */ +#define NAND_FLASH_BANK_0_BASE_ADDR 0x40000000 +#define NAND_FLASH_BANK_0_END_ADDR 0x4FFFFFFF + +/* (PC-Card)/NAND Flash Controller Bank 1 */ +#define NAND_FLASH_BANK_1_BASE_ADDR 0x50000000 +#define NAND_FLASH_BANK_1_END_ADDR 0x5FFFFFFF + +/* Static Memory Controller configuration registers */ +#define SMC_CTRL_REG_BASE_ADDR 0x60000000 +#define SMC_CTRL_REG_END_ADDR 0x60000FFF + +/* TSP (CPU OSMO/OSMOT address space) */ +#define TSP_BASE_ADDR 0x70000000 +#define TSP_END_ADDR 0x700FFFFF + +/* Core AHB 2 Peripherals */ +#define CORE_AHB_2_BASE_ADDR 0x70100000 +#define CORE_AHB_2_END_ADDR 0x7010FFFF + +/* RNG configuration registers */ +#define RNG_CFG_REG_BASE_ADDR 0x70100000 +#define RNG_CFG_REG_END_ADDR 0x70100FFF + +/* Cryptographic processor configuration/data registers */ +#define CRYP_REG_BASE_ADDR 0x70101000 +#define CRYP_REG_END_ADDR 0x70101FFF + +/* HASH processor */ +#define HASH_BASE_ADDR 0x70102000 +#define HASH_END_ADDR 0x70102FFF + +/* Public Key Accelerator registers */ +#define PKA_REG_BASE_ADDR 0x70104000 +#define PKA_REG_END_ADDR 0x70104FFF + +/* Public Key Accelerator memory */ +#define PKA_MEM_BASE_ADDR 0x70105000 +#define PKA_MEM_END_ADDR 0x70105FFF + +/* USB Modem configuration registers */ +#define USB_MODEM_BASE_ADDR 0x70108000 +#define USB_MODEM_END_ADDR 0x70108FFF + +/* Core APB 2 Peripherals */ +#define CORE_APB_2_BASE_ADDR 0x70110000 +#define CORE_APB_2_END_ADDR 0x7011FFFF + +/* Hardware Semaphores */ +#define HSEM_BASE_ADDR 0x70110000 +#define HSEM_END_ADDR 0x70110FFF + +/* I2C 2 Interface Registers */ +#define I2C_2_REG_BASE_ADDR 0x70111000 +#define I2C_2_REG_END_ADDR 0x70111FFF + +/* I2C 3 Interface Registers */ +#define I2C_3_REG_BASE_ADDR 0x70112000 +#define I2C_3_REG_END_ADDR 0x70112FFF + +/* MSP 4 Interface Registers */ +#define MSP_4_REG_BASE_ADDR 0x70113000 +#define MSP_4_REG_END_ADDR 0x70113FFF + +/* MSP 5 Interface Registers */ +#define MSP_5_REG_BASE_ADDR 0x70114000 +#define MSP_5_REG_END_ADDR 0x70114FFF + +/* UART 2 Interface Registers */ +#define UART_2_REG_BASE_ADDR 0x70115000 +#define UART_2_REG_END_ADDR 0x70115FFF + +/* SPDIF Controller configuration registers */ +#define SPDIF_REG_BASE_ADDR 0x70116000 +#define SPDIF_REG_END_ADDR 0x70116FFF + +/* Memory Stick(Pro) Host Controller Registers */ +#define MSHC_REG_BASE_ADDR 0x70118000 +#define MSHC_REG_END_ADDR 0x70118FFF + +/* MM-Card/SD-Card0 Interface Registers */ +#define SDI_0_REG_BASE_ADDR 0x70119000 +#define SDI_0_REG_END_ADDR 0x70119FFF + +/* MM-Card/SD-Card2 Interface Registers */ +#define SDI_2_REG_BASE_ADDR 0x7011A000 +#define SDI_2_REG_END_ADDR 0x7011AFFF + +/* HPI configuration registers */ +#define HPI_REG_BASE_ADDR 0x7011E000 +#define HPI_REG_END_ADDR 0x7011EFFF + +/* FIrDA Interface Registers */ +#define FIRDA_REG_BASE_ADDR 0x7011F000 +#define FIRDA_REG_END_ADDR 0x7011FFFF + +/* Core APB 1 Peripherals */ +#define CORE_APB_1_BASE_ADDR 0x70120000 +#define CORE_APB_1_END_ADDR 0x7012FFFF + +/* I2C 0 Interface Registers */ +#define I2C_0_REG_BASE_ADDR 0x70120000 +#define I2C_0_REG_END_ADDR 0x70120FFF + +/* I2C 1 Interface Registers */ +#define I2C_1_REG_BASE_ADDR 0x70121000 +#define I2C_1_REG_END_ADDR 0x70121FFF + +/* HSI 8-ch Receive Interface Registers */ +#define HSI_RX_REG_BASE_ADDR 0x70123000 +#define HSI_RX_REG_END_ADDR 0x70123FFF + +/* HSI 8-ch Transmit Interface Registers */ +#define HSI_TX_REG_BASE_ADDR 0x70124000 +#define HSI_TX_REG_END_ADDR 0x70124FFF + +/* MM-Card/SD-Card1 Interface Registers */ +#define SDI_1_REG_BASE_ADDR 0x70126000 +#define SDI_1_REG_END_ADDR 0x70126FFF + +/* MSP 0 Interface Registers */ +#define MSP_0_REG_BASE_ADDR 0x70127000 +#define MSP_0_REG_END_ADDR 0x70127FFF + +/* MSP 1 Interface Registers */ +#define MSP_1_REG_BASE_ADDR 0x70128000 +#define MSP_1_REG_END_ADDR 0x70128FFF + +/* MSP 2 Interface Registers */ +#define MSP_2_REG_BASE_ADDR 0x70129000 +#define MSP_2_REG_END_ADDR 0x70129FFF + +/* MSP 3 Interface Registers */ +#define MSP_3_REG_BASE_ADDR 0x7012A000 +#define MSP_3_REG_END_ADDR 0x7012AFFF + +/* SSP 0 Interface Registers */ +#define SSP_0_REG_BASE_ADDR 0x7012B000 +#define SSP_0_REG_END_ADDR 0x7012BFFF + +/* SSP 1 Interface Registers */ +#define SSP_1_REG_BASE_ADDR 0x7012C000 +#define SSP_1_REG_END_ADDR 0x7012CFFF + +/* UART 0 Interface Registers */ +#define UART_0_REG_BASE_ADDR 0x7012D000 +#define UART_0_REG_END_ADDR 0x7012DFFF + +/* UART 1 Interface Registers */ +#define UART_1_REG_BASE_ADDR 0x7012E000 +#define UART_1_REG_END_ADDR 0x7012EFFF + +/* Nand-Flash and Smart Panel(NDSP) */ +#define NDSP_BASE_ADDR 0x70130000 +#define NDSP_END_ADDR 0x7013FFFF + +/* Main ICN Crossbar Configuration registers */ +#define ICN_CROSSBAR_REG_BASE_ADDR 0x70150000 +#define ICN_CROSSBAR_REG_END_ADDR 0x701500AF + +/* Embedded boot ROM (128KBytes) */ +#define BOOT_ROM_BASE_ADDR 0x80000000 +#define BOOT_ROM_END_ADDR 0x8001FFFF + +/* Smart Audio Acc. Data Memory Space */ +#define SAA_MEM_BASE_ADDR 0x90000000 +#define SAA_MEM_END_ADDR 0x900FFFFF + +/* Smart Video Acc. Data Memory Space */ +#define SVA_MEM_BASE_ADDR 0x90100000 +#define SVA_MEM_END_ADDR 0x901FFFFF + +/* Smart Imaging Acc. Data Memory Space */ +#define SIA_MEM_BASE_ADDR 0x90200000 +#define SIA_MEM_END_ADDR 0x902FFFFF + +#define HCL_UNDEF_BASE_ADDR 0x90300000 + +/* SGA Configuration Registers */ +#define SGA_REG_BASE_ADDR 0x90310000 +#define SGA_REG_END_ADDR 0x9031FFFF + +/* Display Controller Configuration registers */ +#define DISPLAY_CTRL_REG_BASE_ADDR 0x90360000 +#define DISPLAY_CTRL_REG_END_ADDR 0x90360FFF + +/* DMA Controller configuration registers */ +#define DMA_CTRL_REG_BASE_ADDR 0x90361000 +#define DMA_CTRL_REG_END_ADDR 0x90361FFF + +/* B2R2 configutation registers */ +#define B2R2_BASE_ADDR 0x90380000 +#define B2R2_END_ADDR 0x9038FFFF + +/* Core APB 4 Peripherals */ +#define CORE_APB_4_BASE_ADDR 0x903B0000 +#define CORE_APB_4_END_ADDR 0x903BFFFF + +/* Intelligemt Energy Management */ +#define IEC_BASE_ADDR 0x903B4000 +#define IEC_END_ADDR 0x903B4FFF + +/* Fuse Registers */ +#define FUSE_REG_BASE_ADDR 0x903B5000 +#define FUSE_REG_END_ADDR 0x903B5FFF + +/* General Purpose I/Os registers (GPIO0: 0...31) */ +#define GPIO_0_REG_BASE_ADDR 0x903B6000 +#define GPIO_0_REG_END_ADDR 0x903B6FFF + +/* General Purpose I/Os registers (GPIO1: 32...63) */ +#define GPIO_1_REG_BASE_ADDR 0x903B7000 +#define GPIO_1_REG_END_ADDR 0x903B7FFF + +/* General Purpose I/Os registers (GPIO2: 64...95) */ +#define GPIO_2_REG_BASE_ADDR 0x903B8000 +#define GPIO_2_REG_END_ADDR 0x903B8FFF + +/* General Purpose I/Os registers (GPIO3: 96...127) */ +#define GPIO_3_REG_BASE_ADDR 0x903B9000 +#define GPIO_3_REG_END_ADDR 0x903B9FFF + +/* General Purpose I/Os registers (GPIO4: 128...159) */ +#define GPIO_4_REG_BASE_ADDR 0x903BA000 +#define GPIO_4_REG_END_ADDR 0x903BAFFF + +/* General Purpose I/Os registers (GPIO5: 160...191) */ +#define GPIO_5_REG_BASE_ADDR 0x903BB000 +#define GPIO_5_REG_END_ADDR 0x903BBFFF + +/* General Purpose I/Os registers (GPIO6: 192...203) */ +#define GPIO_6_REG_BASE_ADDR 0x903BC000 +#define GPIO_6_REG_END_ADDR 0x903BCFFF + +/* Real Time Clock/Real Time Timer Registers */ +#define RTC_REG_BASE_ADDR 0x903BD000 +#define RTC_REG_END_ADDR 0x903BDFFF + +/* Power Management Unit Registers */ +#define PMU_REG_BASE_ADDR 0x903BE000 +#define PMU_REG_END_ADDR 0x903BEFFF + +/* System Controller registers */ +#define SYSCTRL_REG_BASE_ADDR 0x903BF000 +#define SYSCTRL_REG_END_ADDR 0x903BFFFF + +/* Core APB 3 Peripherals */ +#define CORE_APB_3_BASE_ADDR 0x903C0000 +#define CORE_APB_3_END_ADDR 0x903CFFFF + +/* Watchdog registers */ +#define WDT_REG_BASE_ADDR 0x903C1000 +#define WDT_REG_END_ADDR 0x903C1FFF + +/* Multi Timer Unit 0 registers (Timers 0...3) */ +#define MTU_0_REG_BASE_ADDR 0x903C2000 +#define MTU_0_REG_END_ADDR 0x903C2FFF + +/* Multi Timer Unit 1 registers (Timers 4...7) */ +#define MTU_1_REG_BASE_ADDR 0x903C3000 +#define MTU_1_REG_END_ADDR 0x903C3FFF + +/* Trustzone Protection Controller 1 */ +#define TZPC_1_BASE_ADDR 0x903C7000 +#define TZPC_1_END_ADDR 0x903C7FFF + +/* Trustzone Protection Controller 2 */ +#define TZPC_2_BASE_ADDR 0x903C8000 +#define TZPC_2_END_ADDR 0x903C8FFF + +/* Multi Timer Unit 2 registers (Timers 8...11) */ +#define MTU_2_REG_BASE_ADDR 0x903C9000 +#define MTU_2_REG_END_ADDR 0x903C9FFF + +/* Multi Timer Unit 3 registers (Timers 12...15) */ +#define MTU_3_REG_BASE_ADDR 0x903CA000 +#define MTU_3_REG_END_ADDR 0x903CAFFF + +/* Scroll Key Encoder Registers */ +#define SKE_REG_BASE_ADDR 0x903CB000 +#define SKE_REG_END_ADDR 0x903CBFFF + +/* PWL Registers */ +#define PWL_REG_BASE_ADDR 0x903CC000 +#define PWL_REG_END_ADDR 0x903CCFFF + +/* One Wire Master Registers */ +#define OWM_REG_BASE_ADDR 0x903CD000 +#define OWM_REG_END_ADDR 0x903CDFFF + +/* TSP configuration registers */ +#define TSP_CFG_REG_BASE_ADDR 0x903CE000 +#define TSP_CFG_REG_END_ADDR 0x903CEFFF + +/* Dynamic Memory Controller Configuration registers */ +#define DMC_REG_BASE_ADDR 0x903CF000 +#define DMC_REG_END_ADDR 0x903CFFFF + +/* USB OTG configuration/data registers */ +#define USB_REG_BASE_ADDR 0x903E0000 +#define USB_REG_END_ADDR 0x903EFFFF + +/* ETM configuration registers */ +#define ETM_REG_BASE_ADDR 0x90400000 +#define ETM_REG_END_ADDR 0x9040FFFF + +/* VIC0 Controller configuration registers */ +#define VIC_0_CTRL_REG_BASE_ADDR 0x90410000 +#define VIC_0_CTRL_REG_END_ADDR 0x90410FFF + +/* VIC1 Controller configuration registers */ +#define VIC_1_CTRL_REG_BASE_ADDR 0x90411000 +#define VIC_1_CTRL_REG_END_ADDR 0x90411FFF + +/* TZIC0 Controller configuration registers */ +#define TZIC_0_CTRL_REG_BASE_ADDR 0x90412000 +#define TZIC_0_CTRL_REG_END_ADDR 0x90412FFF + +/* TZIC1 Controller configuration registers */ +#define TZIC_1_CTRL_REG_BASE_ADDR 0x90413000 +#define TZIC_1_CTRL_REG_END_ADDR 0x90413FFF + +#endif /* defined(__STN_8820) */ + + +#endif /*__INC_MUPOC_MAPPING_H */ + + --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/hcl/include/platform_os.h @@ -0,0 +1,72 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ + +#ifndef __INC_PLATFORM_OS_H +#define __INC_PLATFORM_OS_H + +#include +#undef NULL + +/* + * Define alignment macro + */ +#undef ALIGN +#if defined(__CC_ARM) +#define ALIGN(a) /* __align(a) */ __attribute__ ((aligned (a))) +#elif defined(__GNUC__) +#define ALIGN(a) __attribute__ ((aligned (a))) +#else +#define ALIGN(a) +#endif + +/* + * Define assertion macro + */ +#define HCL_ASSERT(a) if(a) {(void)0 ;} else { printk("SVA:ERROR: HCL FAILED AT %s, %d\n",__FUNCTION__,__LINE__); return -1;} + +/* + * Define assertion macro for debug only + */ +//#ifdef __DEBUG +// #define HCL_DEBUG_ASSERT(a) HCL_ASSERT(a) +//#else + #define HCL_DEBUG_ASSERT(a) if(a){(void)0;} else {printk("SVA:ERROR: IGNORING HCL DEBUG FAILED AT %s, %d\n",__FUNCTION__,__LINE__);} +//#endif + +/* + * Define the SPRINTF macro use inside hv_XX_debugPrintf functions + * This routine SHALL support a format parameter with %d, %x, %s and width qualifiers + * AND return the number of bytes written in the output string + */ +#define SPRINTF(current, max, buffer, ...) \ + { \ + if ((current + 80) > max) {break;} \ + current += sprintf(buffer, __VA_ARGS__); \ + } + +/* + * Define extended ANSI C unsigned long long type + * could be redefine for each OS + * typedef unsigned __int64 t_uint64; + * typedef __int64 t_sint64; + */ +typedef unsigned long long t_uint64; +typedef signed long long t_sint64; + +#endif /* __INC_PLATFORM_OS_H */ --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/hcl/include/sva.h @@ -0,0 +1,2148 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ + +#ifndef __INC_SVA_H +#define __INC_SVA_H + +#include "hcl_defs.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* + * Definition of the HCL SVA Version numbers + */ +#define SVA_HCL_VERSION_ID 8 +#define SVA_HCL_MAJOR_ID 0 +#define SVA_HCL_MINOR_ID 0 + +/* + * Definition of unknown version number + + */ +#define UNDEFINED_VERSION {MASK_ALL8,MASK_ALL8,MASK_ALL16} + +/* + * define symbol to disallow grab sync line generation + */ +#define SVA_NO_GRABSYNC_LINE 0x3ff + +/* + * define search window size in ESRAM (encode and stab) + */ + +#define SVA_EC_SEARCHWINDOW_SIZE (48*1024) + +/* Maximum number of video packets generated by Firmware per frame */ +/**<\brief positions of the first video packets (up to 32) +* that have been written by an MPEG4encode subtask. It is +* used only when flag_short_header=0. The positions are +* given in bytes,relatively to the beginning of the +* bitstream that has been written,including the header. +*/ +#define SVA_EC_MPEG4_VP_POS_COUNT 32 + +/* Maximum number of video slices generated by Firmware per frame */ +/* Positions of the 1st slices (up to 32) */ +#define SVA_EC_H263_SLICE_POS_COUNT 32 + +/* Maximum number of video slices generated by Firmware Per frame */ +/**<\brief positions of the first slices (up to 1320 enough for SDTV) that have been written by an H264 encode subtask. */ +//\/ Sarvesh: This size has been increased from 32 to 1320 for H264 Encode and to 1620 with FW 3.6.0 +#define SVA_EC_H264_SLICE_POS_COUNT 1620 + +#define SVA_LAST_IAD_EOT_ERR_RESET_VAL 0x45524F52UL + +typedef enum { + SVA_IRQ +} t_sva_irq_src; + +/* + * Define type used to memorize the current status of the IRQ sources + */ +typedef struct { + t_uint32 dummy_tab[30]; +}t_sva_irq_status; + +typedef enum { +SVA_LAST_ERROR = -64, +/* Internal HCL errors */ +SVA_INTERNAL_MEMORY_MGT_ERROR, +SVA_INTERNAL_VIDEO_DECODER_ERROR, +SVA_INTERNAL_VIDEO_ENCODER_ERROR, +SVA_INTERNAL_STILL_DECODER_ERROR, +SVA_INTERNAL_STILL_ENCODER_ERROR, +SVA_INTERNAL_POSTPROCESSOR_ERROR, +SVA_INTERNAL_PREPROCESSOR_ERROR, +SVA_INTERNAL_TV_OUTPUT_ERROR, +SVA_INTERNAL_SWPROCESSOR_ERROR, +SVA_INTERNAL_EVENT_MGT_ERROR, +SVA_INTERNAL_NEEDS_ERROR, +SVA_INTERNAL_TASK_MGT_ERROR, +/* Wrong HCL usage */ +SVA_IMAGE_BUFFER_TOO_SMALL, +SVA_INCOHERENT_CONFIGURATION, +SVA_UNEXPECTED_API_CALL, +SVA_MISALIGNED_BUFFER, +SVA_BUFFER_IS_IN_USE, +SVA_UNKNOWN_SERVICE_ID, +SVA_INCOHERENT_SERVICE_TYPE, +SVA_UNKNOWN_CMD_ID, +SVA_UNKNOWN_BUFFER_ID, +SVA_INVALID_BUFFER_TYPE, +SVA_OUT_OF_MEMORY, +SVA_NO_MORE_CHUNK, +SVA_NO_MORE_FW_ID, +SVA_UNKNOWN_FW_ID, +SVA_FW_CONFLICT, +SVA_FW_NOT_PROVIDED, +SVA_INCOHERENT_FW_PROVIDED, +SVA_NOT_SUPPORTED_YET, +SVA_UNREGISTERED_FIRMWARE_ID, +SVA_NO_MORE_FIRMWARE_ID, +SVA_FATAL_ERROR = -4, +SVA_INTERNAL_FIFOS_FULL, +SVA_FW_DOWNLOAD_NEEDED, +SVA_OK = HCL_OK, +SVA_REMAINING_PENDING_EVENTS = HCL_REMAINING_PENDING_EVENTS, +SVA_NO_MORE_PENDING_EVENT = HCL_NO_MORE_PENDING_EVENT, +SVA_NO_PENDING_EVENT_ERROR = HCL_NO_PENDING_EVENT_ERROR, +SVA_IMMEDIATE_UPDATE, +SVA_DELAYED_UPDATE, +SVA_FW_SWITCH_OCCURED, +SVA_FW_SWITCH_DELAYED, +SVA_CONFIGURATION_IN_PROGRESS, +SVA_VIDEO_DECODER_IMAGE_BUFFER_NEEDED, +SVA_VIDEO_ENCODER_DATA_ERROR, +SVA_INSUFFICIENT_MEMORY, +} t_sva_error; + + +typedef enum { +SVA_IRQ_0, +SVA_IRQ_1 +}t_sva_irq_num; + + +typedef enum { +SVA_SERVICE_NONE = 0, +SVA_PREPROCESSOR = 1, +SVA_VIDEO_DECODER = 2, +SVA_VIDEO_ENCODER = 3, +SVA_POSTPROCESSOR = 4, +SVA_STILL_IMAGE_ENCODER = 5, +SVA_STILL_IMAGE_DECODER = 6, +SVA_TV_OUTPUT = 7, +SVA_SW_PROCESSING = 8, +SVA_OPEN_SERVICE_0 = 128, +SVA_OPEN_SERVICE_1 = 129, +SVA_OPEN_SERVICE_2 = 130, +SVA_OPEN_SERVICE_3 = 131, +SVA_OPEN_SERVICE_4 = 132, +SVA_OPEN_SERVICE_5 = 133, +SVA_OPEN_SERVICE_6 = 134, +SVA_OPEN_SERVICE_7 = 135 +}t_sva_service_type; + + +typedef enum { +SVA_REALTIME_SERVICE, +SVA_NON_REALTIME_SERVICE +} t_sva_service_mode; + + +typedef enum { +SVA_SERVICE_NOT_INITIALIZED = MASK_BIT0, +SVA_SERVICE_WAIT_FOR_CONFIGURATION = MASK_BIT1, +SVA_SERVICE_WAIT_FOR_INTERNAL_NEEDS = MASK_BIT2, +SVA_SERVICE_WAIT_FOR_ACTIVATE = MASK_BIT3, +SVA_SERVICE_WAIT_FOR_START = MASK_BIT4, +SVA_SERVICE_FLUSHING = MASK_BIT5, +SVA_SERVICE_WAIT_FOR_DATA = MASK_BIT6, +SVA_SERVICE_RUNNING = MASK_BIT7, +SVA_SERVICE_ABORT_REQUESTED = MASK_BIT8, +SVA_SERVICE_STOP_REQUESTED = MASK_BIT9, +SVA_SERVICE_ERROR = MASK_BIT10 +} t_sva_service_state; + + +typedef enum { +SVA_UNKNOWN_BUFFER_TYPE = 0, +SVA_BITSTREAM_BUFFER_TYPE, +SVA_IMAGE_BUFFER_TYPE, +SVA_INFOS_BUFFER_TYPE, +SVA_PARAMS_BUFFER_TYPE, +SVA_INTERNAL_BUFFER_TYPE +} t_sva_buffer_type; + +typedef enum { +SVA_VC1_DEDICATED_BUFFER, +SVA_GB_HQ_DEDICATED_BUFFER +} t_sva_buffer_usage; + +typedef enum { +SVA_BUFFER_NOT_INIT, +SVA_BUFFER_NOT_USED, +SVA_BUFFER_IN_USE, +SVA_BUFFER_VOIDED, +SVA_BUFFER_FILLED +} t_sva_buffer_state; + + +typedef enum { +SVA_PUSH_IN, +SVA_PUSH_OUT +} t_sva_push_mode; + + +typedef enum { +SVA_INOUT_STREAM, +SVA_INOUT_BITSTREAM_BUFFER, +SVA_INOUT_IMAGE_BUFFER, +SVA_INOUT_INFOS_BUFFER, +SVA_INOUT_PARAMS_BUFFER +} t_sva_inout_type; + + +typedef enum { +SVA_INOUT_BINARY, // this format will be used for buffer whose internal organization is +// unknown or contain data of a unique type (Y/U/V) (JPEG case) +SVA_INOUT_YUV422, +SVA_INOUT_YUV420, +SVA_INOUT_RGB444, +SVA_INOUT_RGB555, +SVA_INOUT_RGB565, +SVA_INOUT_RGB888_PACKED, +SVA_INOUT_RGB888_UNPACKED, +SVA_INOUT_PARAMS_DEBLOCKING, //identify a buffer containing the deblocking filter parameters +SVA_INOUT_PARAMS_ACE, //identify a buffer containing the ACE offset from JPEG decode +// List various type of info buffer those could be provided by the various services +SVA_INOUT_INFO_VIDEO_ENCODER, // linked to the codec (MPEG4/H263/...) +SVA_INOUT_INFO_VIDEO_DECODER // linked to the codec (MPEG4/H263/...) +} t_sva_inout_format; + + +typedef enum { +SVA_PREPROCESSOR_RAW, +SVA_PREPROCESSOR_YUV420_MB, +SVA_PREPROCESSOR_YUV420_SEP_COMP_MB, +SVA_PREPROCESSOR_YUV422_SEP_COMP_MB, +SVA_PREPROCESSOR_YUV420_RASTER_OUT, +SVA_PREPROCESSOR_SENSOR_YUV420_MB, +SVA_PREPROCESSOR_SENSOR_YUV420_SEP_COMP_MB, +SVA_PREPROCESSOR_SENSOR_YUV422_SEP_COMP_MB, +SVA_PREPROCESSOR_SENSOR_YUV420_RASTER_OUT, +SVA_PREPROCESSOR_SENSOR_HIGHQUALITY_YUV420_MB +} t_sva_preprocessor_capability_id; + + +typedef enum { +SVA_POSTPROCESSOR_RGB=0, // YUV420 Macroblock tiled to RGB +SVA_POSTPROCESSOR_YUV=1, // YUV422 format (used as TVO input) + +SVA_POSTPROCESSOR_YUV420PL_TO_RGB=2, // YUV420 planar raster to RGB +SVA_POSTPROCESSOR_YUV420MB_TO_YUV420MB=3, // YUV420 MB tiled to YUV420 MB tiled +SVA_POSTPROCESSOR_YUV420PL_TO_YUV422PL=4, +SVA_POSTPROCESSOR_YUV422PL_TO_RGB=5, // NOT SUPPORTED!!!! +SVA_POSTPROCESSOR_YUV420MB_TO_RGB = SVA_POSTPROCESSOR_RGB, // YUV420 Macroblock tiled to RGB +SVA_POSTPROCESSOR_YUV420MB_TO_YUV422PL = SVA_POSTPROCESSOR_YUV, // YUV420 MB tiled to YUV422 planar raster (TVO input) +SVA_POSTPROCESSOR_YUV420MB_TO_YUV420_SEP_COMP_MB=6, +SVA_POSTPROCESSOR_YUV420MB_TO_YUV422_SEP_COMP_MB=7, +} t_sva_postprocessor_capability_id; + + +typedef enum { +SVA_DECODER_H263_P0_L10, +SVA_DECODER_H263_P0_L30, +SVA_DECODER_H263_P3_L10, +SVA_DECODER_H263_P3_L30, +SVA_DECODER_MPEG4_SP_L4A, +SVA_DECODER_H264, +SVA_DECODER_VC1_MP_LL, +SVA_DECODER_MPEG2_MP_ML +} t_sva_video_decoder_capability_id; + + +typedef enum { +SVA_ENCODER_H263_P0_L10, +SVA_ENCODER_H263_P0_L30, +SVA_ENCODER_H263_P3_L10, +SVA_ENCODER_H263_P3_L30, +SVA_ENCODER_MPEG4_SP_L4A, +SVA_ENCODER_H264 +} t_sva_video_encoder_capability_id; + + +typedef enum { + SVA_IMAGE_STABILIZATION +} t_sva_sw_processing_capability_id; + + +typedef enum { +SVA_ENCODER_JPEG_MONOCHROME, +SVA_ENCODER_JPEG_420_SEP_COMP_MB, +SVA_ENCODER_JPEG_422_SEP_COMP_MB, +SVA_ENCODER_JPEG_444_SEP_COMP_MB, +SVA_ENCODER_JPEG_420_MB +} t_sva_still_image_encoder_capability_id; + + +typedef enum { +SVA_DECODER_PROGRESSIVE_JPEG, +SVA_DECODER_SEQUENTIAL_JPEG +} t_sva_still_image_decoder_capability_id; + + +typedef enum { +SVA_NO_MIRRORING, +SVA_HORIZONTAL_MIRRORING, +SVA_VERTICAL_MIRRORING +} t_sva_mirroring_mode; + + +typedef enum { +SVA_NO_ROTATION, +SVA_ROTATION_90, +SVA_ROTATION_180, +SVA_ROTATION_270 +} t_sva_rotation_mode; + + +#define NUMBER_OF_DEBLOCKING_FILTER_MODE 4 +typedef enum { +SVA_NONE_DEBLOCKING_FILTER, +SVA_MPEG4_DEBLOCKING_FILTER, +SVA_H263_DEBLOCKING_FILTER, +SVA_H264_DEBLOCKING_FILTER, +SVA_MPEG2_DEBLOCKING_FILTER +} t_sva_deblocking_filter_mode; + + +#define NUMBER_OF_DERINGING_FILTER_MODE 3 +typedef enum { +SVA_NONE_DERINGING_FILTER, +SVA_MPEG4_DERINGING_FILTER, +SVA_H264_DERINGING_FILTER, +SVA_MPEG2_DERINGING_FILTER +} t_sva_deringing_filter_mode; + + +typedef enum { +SVA_CODEC_IMAGE_MODE, +SVA_CODEC_SEGMENTED_MODE, +SVA_CODEC_STREAM_MODE +//SVA_CODEC_CIRCULAR_MODE +} t_sva_codec_mode; + +typedef enum { +SVA_VC1_IMAGE_BUFFER_AREA, +SVA_H264_INTERNAL_AREA, +SVA_H264_ENC_FW_PROG_ZONE1_AREA, +SVA_SW_PREPROC_BUFFER_AREA +}t_sva_dedicated_area_purpose; + +/* + * Define the type used to provide parameters related to a given algorithm + * when configuring a Codec (decoder or encoder) + * (static parameters (bitstream related vs frame related)). + * For each kind of codec supported (MPEG4, H263,..), we provide + * a specific t_sva__algo__configuration_params type. + */ +typedef void * tp_sva_codec_algo_configuration_params; + +typedef enum { +SVA_PREPROCESSING_RESIZE = MASK_BIT0, +SVA_PREPROCESSING_CROP = MASK_BIT1 +} t_sva_preprocessing_transform_type; + + +typedef enum { +SVA_ENCODING_CROP = MASK_BIT0 +} t_sva_encoding_transform_type; + +typedef enum { +SVA_POSTPROCESSING_RESIZE = MASK_BIT0, +SVA_POSTPROCESSING_CROP = MASK_BIT1, +SVA_POSTPROCESSING_CLIP = MASK_BIT2, +SVA_POSTPROCESSING_MIRROR_H = MASK_BIT3, +SVA_POSTPROCESSING_MIRROR_V = MASK_BIT4, +SVA_POSTPROCESSING_ROTATE_90 = MASK_BIT5, +SVA_POSTPROCESSING_ROTATE_180 = MASK_BIT6, +SVA_POSTPROCESSING_ROTATE_270 = MASK_BIT7, +SVA_POSTPROCESSING_DITHERING = MASK_BIT8, +SVA_POSTPROCESSING_DEBLOCKING_FILTER = MASK_BIT9, +SVA_POSTPROCESSING_DERINGING_FILTER = MASK_BIT10 +} t_sva_postprocessing_transform_type; + + +typedef enum { +SVA_SERVICE_RESET = 1, +SVA_SERVICE_ABORT, +SVA_SERVICE_STOP, +SVA_SERVICE_START, +SVA_SERVICE_FLUSH_IN, +SVA_SERVICE_FLUSH_OUT +} t_sva_service_cmd_id; + + +typedef enum { +SVA_UPDATE_MULTIPLE, +SVA_UPDATE_LAST, +SVA_UPDATE_REVERT +} t_sva_update_cmd_type; + + +typedef enum { +/* no dynamic param identified today */ +SVA_VIDEO_DECODER_PARAM_DUMMY +} t_sva_video_decoder_param_id; + + +typedef enum { +SVA_ENCODER_REQUEST_INTRA, //parameter: a pointer to a structure t_sva_intra_request +SVA_ENCODER_BITRATE, // parameter : new bitrate in bit/s +SVA_ENCODER_FRAME_RATE, // parameter : value of new source frame rate => use only as info whensource frame rate change +SVA_ENCODER_SPATIAL_QUALITY, // parameter : t_sva_spatial_quality value +SVA_ENCODER_MIN_FRAME_RATE, // parameter : new mininum output frame rate +SVA_ENCODER_PICTURE_INTRA_REFRESH, // parameter : new interval between two I pictures +SVA_ENCODER_HEADER_FREQUENCY, // parameter : new gobHeaderFrequency in short header / newhecFreq in simple profile +SVA_ENCODER_AIR_MB_NUM, // parameter : new air macroblock number +SVA_ENCODER_CIR_PERIOD, // parameter : new refresh period for cir mode +SVA_ENCODER_PACKET_SIZE, // parameter : new packet size in bit +SVA_ENCODER_PACKET_SIZE_INFO // added for cr 190 +} t_sva_video_encoder_param_id; + +typedef enum { +SVA_PREPROCESSOR_CROPPING, /* parameter: a pointer to a t_sva_window_desc structure */ +SVA_PREPROCESSOR_RESIZE, /* parameter: a pointer to a t_sva_image_desc structure */ +SVA_PREPROCESSOR_GRAB_LINE_NUMBER_SYNC, /* parameter: line number */ +SVA_PREPROCESSOR_ACE_ENABLE, /* parameter : a boolean : TRUE => enable ace / FALSE => disable ace */ +SVA_PREPROCESSOR_ACE_STRENGTH, /* parameter : a t_sva_ace_strength value */ +SVA_PREPROCESSOR_ACE_RANGE, /* parameter : a t_sva_color_range value */ +SVA_PREPROCESSOR_OUTPUT_RANGE, /* parameter : a t_sva_color_range value */ +SVA_PREPROCESSOR_ACE_OFFSET, /* parameter: a pointer to a t_sva_ace_offset structure */ +SVA_PREPROCESSOR_PACKET_WRITE, /* parameter: a pointer to a t_sva_packet structure */ +SVA_PREPROCESSOR_PACKET_READ, /* parameter: a pointer to a t_sva_packet structure */ +SVA_PREPROCESSOR_HQ_STATUS_READ, /* Gives the status of HQ Grab substask, parameter: a pointer to a t_sva_gb_hq_status structure */ +SVA_PREPROCESSOR_HQ_STATUS_TST, /* Used to test geabHQ, set this to one when you need to stop at each stage */ +SVA_PREPROCESSOR_HQ_PREPROC, /* Dynamic update of grabhq preproc params */ +SVA_PREPROCESSOR_HQ_READ_NB_FAILURE_BML_PROCESS /* Read status of BML retries made for a BML process, Parameter: A pointer to a t_uint32 value */ +} t_sva_preprocessor_param_id; + +typedef enum { +SVA_POSTPROCESSOR_PPP_TILE, +SVA_POSTPROCESSOR_PIP, // parameter: a pointer to a t_sva_window_desc structure +// (if pointer NULL, then PIP disabled) +SVA_POSTPROCESSOR_CONTRAST, // a pointer to t_uint32 value which points to contrast range [0, 100] +SVA_POSTPROCESSOR_BRIGHTNESS, // a pointer to t_uint32 value which points to brightness in range [0, 100] +SVA_POSTPROCESSOR_DITHERING, // a pointer to t_uint32 value which points to Dithering 0: off - 1: on +SVA_POSTPROCESSOR_MIRRORING, // a pointer to t_uint32 value 0:off-1(SVA_HORIZONTAL_MIRRORING)-2(SVA_VERTICAL_MIRRORING) +SVA_POSTPROCESSOR_ROTATION, //a pointer to t_uint32 value 0:off-90(SVA_ROTATE_90)-180(SVA_ROTATE_180)-270(SVA_ROTATE_270) +SVA_POSTPROCESSOR_FRAME_ALPHAKEY, //a pointer to t_uint32 value,new alpha key value +SVA_POSTPROCESSOR_CROPPING, // parameter: a pointer to a t_sva_window_desc structure (input) +SVA_POSTPROCESSOR_RESIZE, // parameter: a pointer to a t_sva_image_desc structure +SVA_POSTPROCESSOR_CLIPPING, // parameter: a pointer to a t_sva_window_desc structure (output) +SVA_POSTPROCESSOR_SOURCEFRAME_SIZE,//NOT IMPLEMENTED YET // parameter: a pointer to t_sva_image_desc (input) +SVA_POSTPROCESSOR_VIDEOFRAME_SIZE,//NOT IMPLEMENTED YET // parameter: a pointer to t_sva_image_desc (output) +SVA_POSTPROCESSOR_SCREEN_WINDOW_OFFSET,// parameter: pointer to t_sva_offset_desc structure +SVA_POSTPROCESSOR_SCREEN_BUFFER_ADDR, // parameter: a t_physical_address value +SVA_POSTPROCESSOR_ALT_SCREEN_BUFFER_ADDR, // parameter: a t_physical_address value +SVA_POSTPROCESSOR_MATRIX_COEFF, // parameter: a pointer to t_sva_postprocessor_color_matrix +SVA_POSTPROCESSOR_ANTI_TEARING_EFFECT, // parameter: 0: off - 1: on +SVA_POSTPROCESSOR_ACE_ENABLE, // not used anymore +SVA_POSTPROCESSOR_ACE_STRENGTH, // parameter : a t_sva_ace_strength value +SVA_POSTPROCESSOR_ACE_RANGE, // parameter : a t_sva_color_range value +SVA_POSTPROCESSOR_ACE_OFFSET, // parameter: a pointer to a t_sva_ace_offset structure (see §4.38) +SVA_POSTPROCESSOR_OUTPUT_RANGE, // parameter : a t_sva_color_range value +SVA_POSTPROCESSOR_REDBLUESWAP +} t_sva_postprocessor_param_id; + + +typedef enum { +/* no dynamic param identified today */ +SVA_SW_PROCESSING_PARAM_DUMMY +} t_sva_sw_processing_param_id; + + +typedef enum { +/* no dynamic param identified today */ +SVA_STILL_ENCODER_PARAM_DUMMY +} t_sva_still_encoder_param_id; + + +typedef enum { +/* no dynamic param identified today */ +SVA_STILL_DECODER_PARAM_DUMMY +} t_sva_still_decoder_param_id; + + +typedef enum { +SVA_TVO_CROPPING, // parameter: a pointer to a t_sva_window_desc structure +SVA_TVO_WINDOW_OFFSET, // parameter: pointer to t_sva_offset_desc structure +SVA_TVO_BACKGROUND_COLOR // parameter: pointer to t_sva_yuv_color structure +} t_sva_tvo_param_id; + + +typedef enum { +SVA_NO_TIMESTAMP, +SVA_PRESENTATION_TIMESTAMP, +SVA_DECODING_TIMESTAMP, +SVA_GRABBING_TIMESTAMP +} t_sva_timestamp_type; + + +typedef enum { +SVA_COLOR_12BITS, +SVA_COLOR_15BITS, +SVA_COLOR_16BITS, +SVA_COLOR_24BITS, +SVA_COLOR_32BITS +} t_sva_color_depth; + +typedef enum { +SVA_FULL_RANGE, +SVA_BT601_RANGE +} t_sva_color_range; + +typedef enum { +SVA_DEFAULT_SAMPLING_FORMAT = 0, +SVA_MPEG2_4_SAMPLING_FORMAT = 1, +SVA_MPEG1_SAMPLING_FORMAT = 2 +} t_sva_sampling_format; + + +typedef enum { +SVA_MONOCHROME = 1, +SVA_COLOR = 3 +} t_sva_still_image_color_mode; + + +typedef enum { +SVA_DOWNSAMPLING_FACTOR_1, +SVA_DOWNSAMPLING_FACTOR_2, +SVA_DOWNSAMPLING_FACTOR_4, +SVA_DOWNSAMPLING_FACTOR_8 +} t_sva_downsampling_factor; + + +typedef enum { +SVA_ACE_STRENGTH_1 = 1, +SVA_ACE_STRENGTH_2, +SVA_ACE_STRENGTH_3, +SVA_ACE_STRENGTH_4, +SVA_ACE_STRENGTH_5, +SVA_ACE_STRENGTH_6, +SVA_ACE_STRENGTH_7, +SVA_ACE_STRENGTH_8 +} t_sva_ace_strength; + + +typedef enum { +SVA_POSTPROCESSOR_ACE_DISABLE, +SVA_POSTPROCESSOR_ACE_INTERNAL, +SVA_POSTPROCESSOR_ACE_EXTERNAL // when using with Still Image Decoder +} t_sva_postprocessor_ace_mode; + +typedef enum { +SVA_POSPROCESSOR_NO_EXT_SYNC, +SVA_POSTPROCESSOR_EXT_DISPLAY_SYNC // The external DISPLAY_SYNC signal is used. That means the display is synchronized by + // external hardware signal mainly provided by display engine. + // WARNING : To be used ONLY with valid hardware synchro, otherwise, display will be + // stucked !!! +} t_sva_postprocessor_external_sync_mode; + + +typedef enum { +SVA_PREPROCESSOR_RAW_8BPP, +SVA_PREPROCESSOR_RAW_10BPP +} t_sva_preprocessor_ccir_raw_bpp; + + +typedef enum { +SVA_PREPROCESSOR_SYNC_EMBEDDED_CODES, /* 0x0 */ +SVA_PREPROCESSOR_SYNC_EXTERNAL_MODE1, /* 0x1 */ +SVA_PREPROCESSOR_SYNC_EXTERNAL_MODE2 /* 0x2 */ +} t_sva_preprocessor_ccir_input_sync_mode; + +typedef enum { +SVA_PREPROCESSOR_CCP0_INTERFACE_RISING_EDGE, /* 0x0 */ +SVA_PREPROCESSOR_CCIR656_INTERFACE_RISING_EDGE, /* 0x1 */ +SVA_PREPROCESSOR_CCP0_INTERFACE_FALLING_EDGE, /* 0x2 */ +SVA_PREPROCESSOR_CCIR656_INTERFACE_FALLING_EDGE, /* 0x3 */ +SVA_PREPROCESSOR_CCP0_INTERFACE_RISING_EDGE_STROBE_ENABLE, /* 0x4 */ +SVA_PREPROCESSOR_CCP0_INTERFACE_FALLING_EDGE_STROBE_ENABLE, /* 0x5 */ +SVA_PREPROCESSOR_CCP1_INTERFACE_RISING_EDGE, /* 0x6 */ +SVA_PREPROCESSOR_CCP1_INTERFACE_FALLING_EDGE, /* 0x7 */ +SVA_PREPROCESSOR_CCP1_INTERFACE_RISING_EDGE_STROBE_ENABLE, /* 0x8 */ +SVA_PREPROCESSOR_CCP1_INTERFACE_FALLING_EDGE_STROBE_ENABLE, /* 0x9 */ +SVA_PREPROCESSOR_CCP_INTERFACE_RISING_EDGE = SVA_PREPROCESSOR_CCP0_INTERFACE_RISING_EDGE, /* 0x0 */ +SVA_PREPROCESSOR_CCP_INTERFACE_FALLING_EDGE = SVA_PREPROCESSOR_CCP0_INTERFACE_FALLING_EDGE, /* 0x2 */ +SVA_PREPROCESSOR_CCP_INTERFACE_RISING_EDGE_STROBE_ENABLE = SVA_PREPROCESSOR_CCP0_INTERFACE_RISING_EDGE_STROBE_ENABLE, /* 0x4 */ +SVA_PREPROCESSOR_CCP_INTERFACE_FALLING_EDGE_STROBE_ENABLE = SVA_PREPROCESSOR_CCP0_INTERFACE_FALLING_EDGE_STROBE_ENABLE /* 0x5 */ +} t_sva_preprocessor_input_mode; + + +typedef enum { +SVA_TVO_EXTERNAL_CLOCK_FALLING_EDGE, +SVA_TVO_EXTERNAL_CLOCK_RISING_EDGE, +SVA_TVO_INTERNAL_CLOCK_FALLING_EDGE, +SVA_TVO_INTERNAL_CLOCK_RISING_EDGE +} t_sva_tvo_clock_mode; + + +typedef enum { +SVA_BASIC_ERC, /* for h264 : file does not contain any error */ +SVA_FULL_ERC /* for h264, file contain error */ +} t_sva_erc_mode; + + +typedef enum { +SVA_QP_CONSTANT=0, +SVA_FRAME_BASE, /* user provide frame size for each picture to encode */ +SVA_CBR, +SVA_VBR +} t_sva_brc_mode; + + +typedef enum { +SVA_SPATIAL_QUALITY_NONE, +SVA_SPATIAL_QUALITY_LOW, +SVA_SPATIAL_QUALITY_MEDIUM, +SVA_SPATIAL_QUALITY_HIGH +} t_sva_brc_spatial_quality; + +typedef enum { +SVA_BUFFERING_NONE, +SVA_BUFFERING_VBV, +SVA_BUFFERING_HRD, +SVA_BUFFERING_ANNEXG +} t_sva_brc_buffering_model; + +typedef enum { +SVA_AIR_DISABLED_CIR_DISABLED=0, +SVA_AIR_ENABLED_CIR_DISABLED, +SVA_AIR_DISABLED_CIR_ENABLED, +SVA_AIR_ENABLED_CIR_ENABLED +} t_sva_brc_intra_refresh_mode; + + +typedef enum { +SVA_RTYPE_MODE_CONSTANT_ZERO, +SVA_RTYPE_MODE_CONSTANT_ONE, +SVA_RTYPE_MODE_TOGGLING +} t_sva_rtype_mode; + + +#define NUMBER_OF_FILTER_MODE 5 +typedef enum { +SVA_NONE_FILTER, +SVA_DEBLOCKING_FILTER, +SVA_DERINGING_FILTER , +SVA_DEBLOCKING_DERINGING_FILTER, +SVA_H264_DEBLOCKING_OPTIMIZED_FILTER = SVA_DEBLOCKING_DERINGING_FILTER + +} t_sva_filter_mode; + +typedef enum { +SVA_H264_FULL_FRAME_DEBLOCKING_FILTER, +SVA_H264_NONE_FILTER, +SVA_H264_SLICE_BOUNDRIES_DEBLOCKING_FILTER, +} t_sva_h264_filter_mode; + +typedef enum { +// TO BE COMPLETED +SVA_DECODER_TASK_PARAMETER_ERROR = -1, +SVA_DECODER_NO_ERROR = 0 +} t_sva_video_decoder_error_id; + + +typedef enum { +// TO BE COMPLETED +SVA_VIDEO_ENCODER_ERROR_DUMMY +} t_sva_video_encoder_error_id; + + +typedef enum { +SVA_PREPROCESSOR_TASK_PARAMETER_ERROR = -1, +SVA_PREPROCESSOR_NO_ERROR = 0 +// TO BE COMPLETED +} t_sva_preprocessor_error_id; + + +typedef enum { +SVA_POSTPROCESSOR_TASK_PARAMETER_ERROR = -1, +SVA_POSTPROCESSOR_NO_ERROR = 0 +// TO BE COMPLETED +} t_sva_postprocessor_error_id; + +typedef enum { +// TO BE COMPLETED +SVA_SW_PROCESSING_ERROR_DUMMY +} t_sva_sw_processing_error_id; + +typedef enum { +SVA_JPEG_ENCODER_ERROR, +SVA_STILL_ENCODER_NO_ERROR = 0 +} t_sva_still_image_encoder_error_id; + +typedef enum { +SVA_STILL_DECODER_TASK_PARAMETER_ERROR = -1, +SVA_STILL_DECODER_NO_ERROR = 0 +} t_sva_still_image_decoder_error_id; + +typedef enum { +// TO BE COMPLETED +SVA_TVO_ERROR +} t_sva_tvo_error_id; + + +typedef enum { +SVA_EVENT_BUFFER_VOIDED = 1,// the buffer has been read and is under user control +SVA_EVENT_BUFFER_FILLED, // the buffer has been written and is under user control +SVA_EVENT_BUFFER_PARTLY_FILLED, // the buffer has been partly written +// but remains under HCL control in order to continue to fill it +SVA_EVENT_BUFFER_FILLED_READ_ONLY, // the buffer has been written but remains under HCL control +SVA_EVENT_SERVICE_STOPPED, // the given service is stopped +SVA_EVENT_SERVICE_ACTIVATED, // the given service has been activated +SVA_EVENT_SERVICE_INACTIVATED, // the given service has been inactivated +SVA_EVENT_SERVICE_FLUSHED_IN, // the given service has been flushed (input bufferization) +SVA_EVENT_SERVICE_FLUSHED_OUT, // the given service has been flushed (output bufferization) +SVA_EVENT_SERVICE_ERROR, // the given service is in error state +SVA_EVENT_UNDERFLOW, // lack of data in input +SVA_EVENT_OVERFLOW, // lack of buffer in output +SVA_EVENT_PREPROCESSOR_LINE_SYNCHRO, // see t_sva_preprocessor_configuration type description +SVA_EVENT_POSTPROCESSOR_LINE_SYNCHRO, // see t_sva_postprocessor_configuration type description +SVA_EVENT_POSTPROCESSOR_SYNCHRO, // see t_sva_postprocessor_configuration type description +SVA_EVENT_POSTPROCESSOR_ALT_SYNCHRO, // see t_sva_postprocessor_configuration type description +SVA_EVENT_FW_NO_MORE_NEEDED, // the given firmware can be removed from the shared memory +SVA_EVENT_PACKET_READ, // an irp packet read is finish +SVA_EVENT_PACKET_WRITE, // an irp packet write is finish +SVA_EVENT_PACKET_ERROR // an irp packet error occur +} t_sva_event_id; + + + + +typedef t_uint32 t_sva_service_id; +typedef t_uint32 t_sva_fw_id; +typedef t_uint32 t_sva_buffer_id; +typedef t_uint32 t_sva_timestamp_value; +typedef void * tp_sva_codec_algo_static_params; +typedef void * tp_sva_brc_configuration_params; +typedef void * tp_sva_still_algo_configuration_params; +typedef void * tp_sva_open_service_methods; + +/* + * Define the constant value used to flag an invalid buffer identifier + */ +#define INVALID_BUFFER_ID MASK_ALL32 + +typedef struct { +t_sva_timestamp_type type; +t_sva_timestamp_value value; +} t_sva_timestamp; + +/* ------------------------ */ +/* Structure */ +/* -------------------------*/ + +typedef struct { +t_uint16 vpBitSize; +t_uint16 vpMbSize; +t_uint16 vpSizeMax; +t_uint16 vpSizeType; +}t_sva_ec_mp4_packetsize_info; + + +typedef struct { +t_version hclVersion; +t_version fwVersion; +t_version hwVersion; +} t_sva_version; + +typedef struct { +t_uint16 height; +t_uint16 width; +} t_sva_image_desc; + + +typedef struct { +t_uint16 offsetX; +t_uint16 offsetY; +} t_sva_offset_desc; + +typedef struct{ +t_sva_image_desc image; +t_sva_offset_desc imageOffset; +void* next_tile; // it is treated as (t_sva_ppp_tile_info*) +}t_sva_ppp_tile_info; + +typedef struct { +t_sva_image_desc image; +t_sva_offset_desc imageOffset; +} t_sva_window_desc; + + +typedef struct { +t_sva_image_desc frame; +t_sva_window_desc window; +} t_sva_windowed_frame_desc; + +/* BML clock diviser for FW Version >= 3.14.1.1 */ +typedef enum { +SVA_GRAB_HQ_BML_FREQ_CLK72_DIV2 = 2, +SVA_GRAB_HQ_BML_FREQ_CLK72_DIV3 = 3, +SVA_GRAB_HQ_BML_FREQ_CLK72_DIV4 = 4 +} t_sva_grab_hq_bml_clock_divisor; + +/* Configuration parameters related to GrabHQ only, Added after CR133 implementation */ +typedef struct { +t_bool isChannelOffsetEnabled; /* Channel Offset On/Off switch */ +t_bool isGridironEnabled; /* Gridiron On/Off switch */ +t_bool isScorpioEnabled; /* Scorpio On/Off switch */ +t_uint16 scorpioStrength; /* Scorpio strength */ +t_uint32 castDay; +t_uint32 castCool; +t_uint32 castInc; +t_uint32 castHorizon; +t_sint32 gridHSize; +t_sva_grab_hq_bml_clock_divisor bmlClockDivisor; /* BML Clock diviser */ +/* nbMaxBmlRetiesOnFailure is only valid if FW>=3.14.1.2 */ +t_uint32 nbMaxBmlRetiesOnFailure; /* Number of maximum BML reties to be made, if all the these reties have failed then FW will through and error */ +} t_sva_preprocessor_grabhq_configuration; + +typedef struct { +t_uint16 errorType; +t_uint16 pictureLoss; +t_uint16 sliceLossFirstMb[8]; +t_uint16 sliceLossMbNum[8]; +t_uint16 concealedMbNum; +t_uint16 concealedVpSliceNum; +t_uint16 decodedVpSliceNum; +t_uint16 reserved_1; +t_uint32 reserved_2; +} t_sva_video_decoder_infos; + +typedef struct +{ + t_uint16 error_type; + t_uint16 picture_loss; + t_uint16 slice_loss_first_mb[8]; + t_uint16 slice_loss_mb_num[8]; + t_uint16 concealed_mb_num; + t_uint16 concealed_vp_num; + t_uint16 decoded_vp_num; + + t_uint16 reserved_1; + t_uint32 reserved_2; +} t_sva_video_decoder_mpeg4_infos; + +typedef struct +{ + t_uint16 error_type; + t_uint16 reserved_1; + t_uint32 reserved_2; + t_uint32 reserved_3; + t_uint32 reserved_4; +} t_sva_video_decoder_Mpeg2_infos; +typedef struct +{ + t_uint16 error_type; + t_uint16 picture_loss; + t_uint16 slice_loss_first_mb[8]; + t_uint16 slice_loss_mb_num[8]; + t_uint16 concealed_mb_num; + t_uint16 concealed_vp_num; + t_uint16 decoded_vp_num; + t_uint16 reserved_1; + t_uint32 reserved_2; +} t_sva_video_decoder_h263_infos; + +typedef struct +{ + t_uint16 picture_loss; + t_uint16 mb_count; + t_uint32 reserved_2; + t_uint32 reserved_3; + t_uint32 reserved_4; + t_uint16 slice_loss_first_mb[8]; + t_uint16 slice_loss_mb_num[8]; +} t_sva_video_decoder_h264_infos; + +typedef struct +{ + t_uint16 error_type; + t_uint16 frame_interpolation_hint_enabled; + t_uint16 range_reduction_frame_enabled; + t_uint16 b_fraction_numerator; + t_uint16 b_fraction_denominator; + t_uint16 buffer_fullness; + t_uint16 picture_res; + t_uint16 max_picture_width; + t_uint16 max_picture_height; + t_uint16 picture_width; + t_uint16 picture_height; + t_uint16 picture_type; + t_uint32 padding1; + t_uint32 padding2; +} t_sva_video_decoder_vc1_infos; + + +typedef struct +{ + t_uint16 error_type; + t_uint16 reserved_1; + t_uint16 ace_offset0; + t_uint16 ace_offset1; + t_uint16 ace_offset2; + t_uint16 ace_offset3; + t_uint32 reserved_2; +} t_sva_still_decoder_jpeg_infos; + +/* Status of the GrabHQ subtask for FW Version >= 3.13.0 */ +typedef enum { +SVA_GRAB_HQ_SUBTASK_NOT_STARTED = 0, +SVA_GRAB_HQ_FIRST_STRIPE_FISRT_BML_DONE = 1, +SVA_GRAB_HQ_BMS_ENDED = 2, +SVA_GRAB_HQ_PREPROCESSING_STARTED = 2, +SVA_GRAB_HQ_PREPROCESSING_ENDED = 3, +SVA_GRAB_HQ_FIRST_BML_STARTED = 4, +SVA_GRAB_HQ_SUBTASK_ENDED = 5, +SVA_GRAB_HQ_SECOND_BML_STARTED = 6, +SVA_GRAB_HQ_SECOND_STRIPE_FIRST_BML_DONE = 6, +SVA_GRAB_HQ_FIRST_STRIPE_SECOND_BML_DONE = 7, +} t_sva_grab_hq_subtask_status; + +typedef struct { + t_bool isGrabHqTestModeEnabled; + t_sva_grab_hq_subtask_status grabHqSubtaskStatus; + t_uint16 cfgIrpGrabhqGridcastL; + t_uint16 cfgIrpGrabhqGridcastH; + t_uint16 cfgIrpGrabhqGridG1; + t_uint16 cfgIrpGrabhqGridG2; + t_uint16 cfgIrpGrabhqGridR; + t_uint16 cfgIrpGrabhqGridB; +} t_sva_gb_hq_status; + +#ifdef SVA_USE_GENERIC_ENCODER_INFOS +/******************************************************************************** + * SARVESH: Beware of using t_sva_video_encoder_infos instead of using codec * + * specific infos structure e.g. t_sva_video_encoder_mpeg4_infos or * + * t_sva_video_encoder_h264_infos. May lead to code break if you don't take care* + * of enough memory allocation. It is recommended to use service specific infos * + ********************************************************************************/ +typedef struct { +t_uint32 encodedFrameSize; /* size (in byte) of the encoded frame */ +/*(including header and stuffing bits) */ +t_uint32 vpSliceNum; +t_uint32 vpSlicePos[1620]; //\/ This size has been increased from 32 to 1320 for H264 Encode and to 1620 with FW 3.6.0 +} t_sva_video_encoder_infos; +#else /* SVA_USE_GENERIC_ENCODER_INFOS */ +typedef struct { +t_uint32 encodedFrameSize; /* size (in byte) of the encoded frame */ +/*(including header and stuffing bits) */ +t_uint32 vpSliceNum; +t_uint32 vpSlicePos[SVA_EC_MPEG4_VP_POS_COUNT]; +} t_sva_video_encoder_mpeg4_infos; + +typedef struct { +t_uint32 encodedFrameSize; /* size (in byte) of the encoded frame */ +/*(including header and stuffing bits) */ +t_uint32 sliceNum; +t_uint32 slicePos[SVA_EC_H263_SLICE_POS_COUNT]; +} t_sva_video_encoder_h263_infos; + +typedef struct { +t_uint32 encodedFrameSize; /* size (in byte) of the encoded frame */ +/*(including header and stuffing bits) */ +t_uint32 sliceNum; +t_uint32 slicePos[SVA_EC_H264_SLICE_POS_COUNT]; //\/ This size has been increased from 32 to 1320 for H264 Encode and to 1620 with FW 3.6.0 +t_uint32 stuffingBits; /* Number of stuffing bits(INOUT_OUT param from FW side) added in the bitstream during the encode subtask. It is not used if brc_method=0/1/3. */ +} t_sva_video_encoder_h264_infos; +#endif /* SVA_USE_GENERIC_ENCODER_INFOS */ + +typedef struct { +t_sva_inout_type type; +t_sva_inout_format format; +t_sva_image_desc maxSize; +} t_sva_inout_desc; + +typedef struct { +t_uint16 pictureCodingType; /* 0: intra / 1: inter */ +t_uint16 frameTargetSize; /* frame base target size (in byte) */ +} t_sva_brc_user_request; + +typedef struct { +t_uint32 minScaleFactor; // scaleFactor = (1/minScaleFactor) +t_uint32 maxScaleFactor; // scaleFactor = (maxScaleFactor) +t_uint32 scaleStep; // if ZERO (0) then continous resizing +} t_sva_resize_desc; + +typedef struct { +t_uint32 voidedCounter; // Buffer Voided event counter +t_uint32 filledCounter; // Buffer Filled event counter +t_uint32 partlyCounter; // Buffer Partly Filled event counter +t_uint32 readOnlyCounter; // Buffer Filled Read Only event counter +t_uint32 underflowCounter; // Underflow event counter +t_uint32 overflowCounter; // Overflow event counter +t_uint32 errorCounter; // Service Error event counter +} t_sva_service_event_stats; + + +typedef struct { +t_uint32 inLevel; // level of bufferization at input of a given service +t_uint32 outLevel; // level of bufferization at output of a given service +} t_sva_service_bufferization_stats; + + +typedef struct { +t_sva_preprocessor_capability_id capabilityId; +t_sva_inout_desc input; // camera interface +t_sva_inout_desc output[2]; // grabbed image and infos +t_sva_preprocessing_transform_type supportedTransformation; +t_sva_resize_desc resizeEngineFactors; +} t_sva_preprocessor_capabilities; + + +typedef struct { +t_sva_video_decoder_capability_id capabilityId; +t_sva_inout_desc input; // bitstream +t_sva_inout_desc output[3]; // decoded image and infos +// [and optional deblocking filter parameters] +} t_sva_video_decoder_capabilities; + + +typedef struct { +t_sva_video_encoder_capability_id capabilityId; +t_sva_inout_desc input; // image to encode +t_sva_inout_desc output[3]; // bitstream and infos [and optional deblocking filter parameters] +t_sva_encoding_transform_type supportedTransformation; +} t_sva_video_encoder_capabilities; + + +typedef struct { +t_sva_postprocessor_capability_id capabilityId; +t_sva_inout_desc input[2]; // image to postprocess [and optional deblocking filter parameters] +t_sva_inout_desc output; // postprocessed image +t_sva_postprocessing_transform_type supportedTransformation; +t_sva_resize_desc resizeEngineFactors; +} t_sva_postprocessor_capabilities; + + +typedef struct { +t_sva_sw_processing_capability_id capabilityId; +t_sva_inout_desc input[2]; // two grabbed images +t_sva_inout_desc output; // stabilization vector (infos) +} t_sva_sw_processing_capabilities; + +typedef struct { +t_sva_still_image_decoder_capability_id capabilityId; +t_sva_inout_desc input[3]; // three separate component image +t_sva_inout_desc output; // encoded image +} t_sva_still_decoder_capabilities; + +typedef struct { +t_sva_still_image_encoder_capability_id capabilityId; +t_sva_inout_desc input[3]; // three separate component image +t_sva_inout_desc output; // encoded image +t_sva_encoding_transform_type supportedTransformation; +} t_sva_still_encoder_capabilities; + +typedef const struct ts_sva_capabilities{ +t_uint8 nbSupportedPreprocessorTransforms; +t_sva_preprocessor_capabilities *preprocessorCapabilitiesArray; +t_uint8 nbSupportedDecoderTransforms; +t_sva_video_decoder_capabilities *decoderCapabilitiesArray; +t_uint8 nbSupportedSwProcessingTransforms; +t_sva_sw_processing_capabilities *swProcessingCapabilitiesArray; +t_uint8 nbSupportedEncoderTransforms; +t_sva_video_encoder_capabilities *encoderCapabilitiesArray; +t_uint8 nbSupportedPostprocessorTransforms; +t_sva_postprocessor_capabilities *postprocessorCapabilitiesArray; +t_uint8 nbSupportedStillDecoderTransforms; +t_sva_still_decoder_capabilities *stillDecoderCapabilitiesArray; +t_uint8 nbSupportedStillEncoderTransforms; +t_sva_still_encoder_capabilities *stillEncoderCapabilitiesArray; +} t_sva_capabilities, *tp_sva_capabilities; + +/********************************************/ +/* Common decoder structures */ +/********************************************/ +typedef struct { +t_sva_video_decoder_capability_id transformId; +t_bool areInfosRequested; // TRUE => User wants for each decoded image the related infos buffer +// The user SHALL provide all Infos buffers through SVA_PushInfosBuffer() +// FALSE => Infos buffers are not exported +t_sva_erc_mode ercMode; // The user SHALL provide all Infos buffers through SVA_PushInfosBuffer() +t_sva_codec_mode mode; // see §2.9: decoder => bitstream buffer as input +/*choose filter to use. Not all combinaison are possible*/ +t_sva_filter_mode inTheLoopFilter; +t_sva_filter_mode outTheLoopFilter; +t_sva_image_desc imageDesc; +t_bool raster_out_format; +tp_sva_codec_algo_configuration_params pAlgoConfig; +} t_sva_video_decoder_configuration; + + +typedef struct { +t_sva_service_state state; +t_sva_video_decoder_error_id errorId; +t_uint32 nbBytesDecoded; +t_uint32 nbImagesDecoded; +t_uint32 nbCompressedDataBufferized; // number of bytes inside input bitstream fifo +t_sva_service_event_stats eventStats; +t_sva_service_bufferization_stats bufferizationStats; +} t_sva_video_decoder_status; + +/********************************************/ +/* Codecs-dependant decoder structures */ +/********************************************/ +///////////// MPEG4 /////////////////// +typedef struct { +t_bool flagShortHeader; +t_uint16 vopTimeIncrementResolution; // range value: 1 to 65535 +t_bool isResyncMarkerDisable; +t_bool isDataPartitioned; +t_bool isReversibleVlc; +t_bool isInterlaced; +t_uint16 low_delay; +t_uint16 quant_type; +t_uint16 intra_quant_mat[64] ; +t_uint16 nonintra_quant_mat[64]; +t_uint8 profile; +} t_sva_video_decoder_algo_mpeg4_configuration_params; + +/*t_sva_video_decoder_algo_mpeg4_header_infos*/ +typedef struct { +t_uint16 pictureCodingType; // 0: Intra-coded, 1: Predictive-coded +t_uint16 quant; // value range: 1 to 31 +t_uint16 roundingType; // if used, value range: 0 to 1 +t_uint16 intraDcVlcThr; // if used, value range: 0 to 7 +t_uint16 vopFcodeForward; // if used, value range: 1 to 7 +t_uint16 vopFcodeBackward; +t_uint16 vop_time_increment; +t_uint16 modulo_time_base; + +} t_sva_video_decoder_algo_mpeg4_header_infos; + + +/********************************************/ +/* Codecs-dependant decoder structures */ +/********************************************/ +///////////// Start MPEG2 /////////////////// + +//Added for mpeg2 field picture support +typedef enum { + PICTURE_STRUCTURE_FRAME = 3, /** Frame picture structure*/ + PICTURE_STRUCTURE_BOTTOMFIELD = 2, /** Bottom Field */ + PICTURE_STRUCTURE_TOPFIELD = 1, /** Top Field */ + PICTURE_STRUCTURE_NONE = 0, /** Not applicable */ + } t_sva_Mpeg2_picture_structure; + +typedef struct { +t_bool load_intra_quantiser_matrix; +t_bool load_nonintra_quantiser_matrix; +t_bool progressive_sequence; +t_uint8 profile_level_indication; +t_uint8 chroma_format; +t_uint32 bit_rate; +} t_sva_video_decoder_algo_Mpeg2_configuration_params; + +/*t_sva_video_decoder_algo_mpeg4_header_infos*/ +typedef struct { +// not used t_ushort_value horizontal_size; + t_uint16 vertical_size; + t_uint16 mb_width; + t_uint16 mb_height; + // not used t_ushort_value progressive_sequence; + // not used t_ushort_value low_delay; + + t_uint16 intra_quantizer_matrix[64]; + t_uint16 non_intra_quantizer_matrix[64]; + + // not used t_ulong_value frame_rate; + // not used t_ulong_value bit_rate_value; + + // not used t_ulong_value vbv_buffer_size; + // not used t_ushort_value gop_flag; + // not used t_ushort_value closed_gop; + + // not used t_ushort_value broken_link; + // not used t_ushort_value temporal_reference; + t_uint16 picture_coding_type; + // not used t_ushort_value vbv_delay; + + t_uint16 full_pel_forward_vector; + t_uint16 forward_f_code; + t_uint16 full_pel_backward_vector; + t_uint16 backward_f_code; + + t_uint16 f_code[2][2]; + + t_uint16 intra_dc_precision; + t_uint16 picture_structure; + t_uint16 top_field_first; + t_uint16 frame_pred_frame_dct; + t_uint16 concealment_motion_vectors; + t_uint16 q_scale_type; + t_uint16 intra_vlc_format; + t_uint16 alternate_scan; + + // not used t_ushort_value repeat_first_field; + // not used t_ushort_value chroma_420_type; + // not used t_ushort_value progressive_frame; + t_uint16 scalable_mode; + t_uint16 MPEG2_Flag; + +} t_sva_video_decoder_algo_Mpeg2_header_infos; + +typedef enum { + PICTURE_SLICE_I = 1, /** I Picture / Field - can be used as a reference */ + PICTURE_SLICE_P = 2, /** P Picture / Field - can be used as a reference */ + PICTURE_SLICE_B = 3, /** B Picture / Field */ + PICTURE_SLICE_D = 4, /** D Picture / Field */ + PICTURE_SLICE_SKIPPED = 5 /** Picture Skipped / Field */ +} t_sva_Mpeg2_picture_type; + + +////////////// VC1 ///////////////////// +typedef enum { + PICTURE_TYPE_I = 0, /** I Picture / Field - can be used as a reference */ + PICTURE_TYPE_P = 1, /** P Picture / Field - can be used as a reference */ + PICTURE_TYPE_B = 2, /** B Picture / Field */ + PICTURE_TYPE_BI = 3, /** BI Picture / Field */ + PICTURE_SKIPPED = 4 /** Picture Skipped / Field */ +} t_sva_vc1_picture_type; + +typedef enum +{ + PICTURE_CODE_I = 0, /** I-Intra Picture */ + PICTURE_CODE_P = 1, /** P- Predictive Picture can be used as a reference */ + PICTURE_CODE_B = 2, /** B-Bidirectional Picture / Field */ +} t_sva_mp4_picture_type; + +typedef struct { // Sequence Layer parameters + t_uint8 profile; /** See standard */ + t_uint8 level; /** See standard */ + + t_uint8 quantizer; /** See standard */ + t_uint8 dquant; /** See standard */ + t_uint8 max_b_frames; /** See standard */ + t_uint8 qFramerateForPostproc; /** See standard */ + t_uint8 qBitrateForPostproc; /** See standard */ + + t_bool loopFilterEnabled; /** See standard */ + t_bool multiresCodingEnabled; /** See standard */ + t_bool fastUvmcEnabled; /** See standard */ + t_bool extendedMVEnabled; /** See standard */ + t_bool variableSizeTransformEnabled; /** See standard */ + t_bool overlapTransformEnabled; /** See standard */ + t_bool syncmarkerEnabled; /** See standard */ + t_bool rangeredEnabled; /** See standard */ + t_bool frameInterpolationEnabled; /** See standard */ + t_bool is_smpte_conformant; /** See standard */ + t_bool overboost; /** flag activating maximum performance decoding. 0=normal decode, 1=deblocking+overlap disabled with MB output instead of raster */ + t_bool simplified_filter; /** enable this flag if you want to use Intra filter for inter pictures as well. This improves performance for low bitrates. Output is raster in this case */ +} t_sva_video_decoder_algo_vc1_configuration_params; + +typedef struct { + t_uint32 frameSize; + t_sva_vc1_picture_type pictureCodingType; +} t_sva_video_decoder_algo_vc1_header_infos; + +////////////// H.264 /////////////////////// +typedef struct +{ + // size we have it in imageDesc. + t_uint16 levelIdc; + t_uint16 numRefFrames; + t_uint16 gapsInFrameNumValueFlag; + t_uint16 picOrderCntType; + t_uint16 log2MaxFrameNumMinus4; + t_uint16 log2MaxPicOrderCntLsbMinus4; + t_sint32 offsetForNonRefPic; /*t_sint32 ok */ + t_uint16 numRefFramesInPicOrderCntCycle; + t_sint32 offsetForRefFrame[256]; /*t_sint32 ok */ + t_sint32 offsetForTopToBottomField; +}t_sva_video_decoder_algo_h264_configuration_params; + +/* MMCO type operations */ +typedef enum +{ + SVA_DC_H264_DPB_END_MMCO=0, + SVA_DC_H264_DPB_UNMARK_SHORT_REF =1, + SVA_DC_H264_DPB_UNMARK_LONG_REF, + SVA_DC_H264_DPB_ASSIGN_LONG_TO_SHORT, + SVA_DC_H264_DPB_UNMARK_LONG_REF_GREATER, + SVA_DC_H264_DPB_UNMARK_LONG, + SVA_DC_H264_DPB_ASSIGN_LONG_TO_CURRENT +}t_sva_video_decoder_algo_h264_mmco_type; + +/* params to be given for each slice and taken from active pps, sps, slice header */ +typedef struct st_sva_video_decoder_algo_h264_slice_header_infos { + /* these are obtained by parsing */ + t_uint16 nut; + t_uint16 nri; + t_system_address sliceStartAddress; + t_uint32 sliceOffset;//bit position at sliceStartAdress + t_size sliceSize; + /* then taken from active pps, sps, slice header */ + t_uint16 sliceBetaOffsetDiv2; /*t_sint16 but ushort ProgModel*/ + t_uint16 firstMbInSlice; + t_uint16 sliceType; + t_uint16 numRefIdx10ActiveMinus1; + t_sint16 sliceQpDelta; /* t_sint16 ok */ + t_uint16 disableDeblockingFilterIdc; + t_uint16 sliceAlphaC0OffsetDiv2; /*t_sint16 but ushort in Progmodel */ + t_uint16 sliceNum; + t_uint16 sliceQp ; /*t_sint16 but ushort in Progmodel */ + /* to generate list0*/ + t_uint16 numRefIdxActiveOverrideFlag; + t_uint16 refPicListReorderingFlagl0; + t_uint16 frameNum; + t_uint16 reorderingOfPicNumsIdc[16]; + t_uint16 absDiffPicNumMinus1[16]; + t_uint16 longTermPicNum[16]; + struct st_sva_video_decoder_algo_h264_slice_header_infos *pNextHeader; +}t_sva_video_decoder_algo_h264_slice_header_infos; + +/*t_sva_video_decoder_algo_h264_header_infos*/ +typedef struct +{ + /* from PPS for vdc_h264_slice */ + t_uint16 chromaQpIndex; /*t_sint16 but ushort in Progmodel */ + t_uint16 constrIntraPredFlag; + t_uint16 numRefIdxl0ActiveMinus1; + /* from PPS and slice0 to compute sliceMap */ + t_uint16 slice0SliceGroupChangeCycle; + t_uint16 numSliceGroupsMinus1; + t_uint16 sliceGroupMapType; + t_uint16 runLenghtMinus1[8]; + t_uint16 topLeft[8]; + t_uint16 bottomRight[8]; + t_uint16 sliceGroupChangeDirFlag; + t_uint16 sliceGroupChangeRateMinus1; + t_uint16 sliceGroupId[1620]; + /* from active SPS: to be given to DPB */ + /* + t_uint16 numRefFrames; + t_uint16 gapsInFrameNumValueFlag; + t_uint16 picOrderCntType; + t_uint16 log2MaxFrameNumMinus4; + t_uint16 log2MaxPicOrderCntLsbMinus4; + t_sint32 offsetForNonRefPic; //t_sint32 + t_uint16 numRefFramesInPicOrderCntCycle; + t_sint32 offsetForRefFrame[256]; //t_sint32 + t_sint32 offsetForTopToBottomField; + */ + + /*from slice0: to be given to DPB */ + t_uint16 slice0Nut; + t_uint16 slice0Nri; + t_uint16 slice0FrameNum; + t_uint16 slice0PicOrderCntLsb; + t_sint32 slice0DeltaPicOrderCnt[2]; + t_sint32 slice0DeltaPicOrderCntBottom; + t_uint16 slice0LongTermReferenceFlag; + t_uint16 slice0NoOutputOfPriorPicsFlag; + t_uint16 slice0AdaptiveRefPicMarkingModeFlag; + t_sva_video_decoder_algo_h264_mmco_type slice0MemoryManagementControlOperation[16]; + t_uint16 slice0DifferenceOfPicNumsMinus1[16]; + t_uint16 slice0MarkingLongTermPicNum[16]; + t_uint16 slice0LongTermFrameIdx[16]; + t_uint16 slice0MaxLongTermFrameIdxPlus1[16]; + t_uint16 nbSlicesInFrame; + t_sva_video_decoder_algo_h264_slice_header_infos *pHeader; /* from each slice headers */ +}t_sva_video_decoder_algo_h264_header_infos; + +///////////// H.263 /////////////////////// +typedef struct { +/* today none configuration parameter is identified */ + t_uint32 dummy; +} t_sva_video_decoder_algo_h263_configuration_params; + +/*t_sva_video_decoder_algo_h263_header_infos*/ +typedef struct { +t_uint16 pictureCodingType; +t_uint16 quant; +t_uint16 roundingType; +t_uint16 enableAnnexes; +} t_sva_video_decoder_algo_h263_header_infos; + +////////////// End of decoder structures /////////////////// + + +typedef struct { +t_sva_video_encoder_capability_id transformId; +t_bool areInfosRequested; // TRUE => User wants for each encoded image the related infos buffer +// The user SHALL provide all Infos buffers through SVA_PushInfosBuffer() +// FALSE => Infos buffers are not exported +t_bool isCroppingVectorEnabled; // TRUE => User must provide for each image a cropping vector +// FALSE => No buffer of this type should be provide +t_bool isDestinationBufferRequested; // TRUE => User has to provide destination buffers for each image +// FALSE => No buffer of this type should be provide +t_sva_codec_mode mode; // see §2.9: encoder => bitstream buffer as output +t_sva_windowed_frame_desc sourceFrameDesc; +/*choose filter to use. Not all combinaison are possible*/ +t_sva_filter_mode inTheLoopFilter; +t_sva_filter_mode outTheLoopFilter; +/*choose brc to use. Not all combinaison allowed between brcMode/bufferingModel/algo */ +t_sva_brc_mode brcMode; +t_sva_brc_buffering_model bufferingModel; +tp_sva_brc_configuration_params pBrcConfig; +t_bool raster_in_format; +t_bool no_search_window; +tp_sva_codec_algo_configuration_params pAlgoConfig; +} t_sva_video_encoder_configuration; + + +typedef struct { +t_sva_service_state state; +t_sva_video_encoder_error_id errorId; +t_uint32 nbBytesEncoded; +t_uint32 nbImagesEncoded; +t_uint32 nbImagesSkipped; +t_sva_service_event_stats eventStats; +t_sva_service_bufferization_stats bufferizationStats; +} t_sva_video_encoder_status; + + +typedef struct { +t_bool flagShortHeader; +t_uint16 gobHeaderFrequency;/*when 0 then gob header insertion is disable*/ +t_bool isDataPartitionedEnable; +t_bool isReversibleVlcEnable; +t_uint16 hecFreq; // if used, value range: 0(HEC information disabled) to SourceWindowWidth*SourceWindowHeight/256 +t_uint16 vpSizeType; // if used, value range: 0 to 3 +t_uint16 vpSizeMax; // if used, value range: 0 to 2048(for Simple Profile Level=0/1) or 4096 (for SPL=2) or 8192 (for SPL=3) +t_uint16 vpBitSize; // if used, value range: 0 to vpSizeMax +t_uint16 vpMbSize; // if used, value range: 0 to window_width*window_height/256 +t_sva_brc_intra_refresh_mode irMode; +t_uint16 airMbNum; +t_uint16 cirPeriodMax; +t_sva_rtype_mode rtypeMode; +t_bool isSystemHeaderAddBeforeIntra; +t_uint8 profileAndLevel;// profile_and_level_indication field of VOS. Only use in SP and when +// isSystemHeaderAddBeforeIntra is true. This value will be copy in VOS header. +t_uint16 vopTimeIncrement; +t_uint16 vopTimeIncrementResolution; +} t_sva_video_encoder_algo_mpeg4_configuration_params; + + +#define FILE_NAME_SIZE 200 + +typedef struct { + t_sint32 ProfileIDC; /* profile idc */ + t_sint32 level_idc; /* level idc */ + +//\/ t_sint32 no_frames; /* number of frames to be encoded */ + t_sint32 QPISlice; /* QP of I pictures in case of no BRC (fix Qp encoding) */ + t_sint32 QPPSlice; /* QP of P pictures in case of no BRC (fix Qp encoding) */ + /* t_sint32 hadamard; */ /*!< 0: 'normal' SAD in 1/3 pixel search. 1: use 4x4 Haphazard transform and ' + Sum of absolute transform difference' in 1/3 pixel search */ + /* t_sint32 search_range; */ /*!< search range - integer pel search and 16x16 blocks. The search window is + generally around the predicted vector. Max vector is 2xmcrange. For 8x8 + and 4x4 block sizes the search range is 1/2 of that for 16x16 blocks. */ +//\/ t_sint32 Log2MaxFrameNum; + t_sint32 Log2MaxFNumMinus4; + + t_uint16 algo_config; /**<\brief 0b11 for performances (> 15 fps) , + unsetting bit 0 for complex intra in P slices , + unsetting bit 1 for complex inter in P slices */ +//\/ t_uint16 frame_width; /* image width (must be a multiple of 16 pels) */ +//\/ t_uint16 frame_height; /* image height (must be a multiple of 16 pels) */ +//\/ t_sint32 width_cr; /* HCL: We can remove this parameter from input parametrs */ +//\/ t_sint32 height_cr; /* HCL: We can remove this parameter from input parametrs */ + + + t_sint16 slice_size_type; /* Indicate what algorithm to use for setting slices */ + t_sint16 slice_mb_size; /* Argument when fixed # of MB in slice selected */ + t_sint16 slice_bit_size; /* Argument when fixed # of bytes in slice selected */ + t_sint32 use_constrained_intra_flag; /* 0: Inter MB pixels are allowed for intra prediction 1: Not allowed */ +//\/ t_sint32 infile_header; /* If input file has a header set this to the length of the header */ +//\/ char infile[FILE_NAME_SIZE]; /* YUV 4:2:0 input format */ +//\/ char outfile[FILE_NAME_SIZE]; /* H.264 compressed output bitstream */ +//\/ char ReconFile[FILE_NAME_SIZE]; /* Reconstructed Pictures */ +//\/ char TraceFile[FILE_NAME_SIZE]; /* Trace Outputs */ + t_sint32 intra_period; /* Random Access period though intra */ + + t_sint32 idr_enable; /* Encode intra slices as IDR */ +//\/ t_sint32 start_frame; /* Encode sequence starting from Frame start_frame */ + + t_sint32 annexb; /* Specifies the mode of the output file */ + +//\/ t_sint32 InterSearch16x16; +//\/ t_sint32 InterSearch16x8; +//\/ t_sint32 InterSearch8x16; +//\/ t_sint32 InterSearch8x8; +//\/ t_sint32 InterSearch8x4; +//\/ t_sint32 InterSearch4x8; +//\/ t_sint32 InterSearch4x4; + + t_sint32 IntraDisableInterOnly; + t_sint32 Intra4x4ParDisable; + t_sint32 Intra4x4DiagDisable; + t_sint32 Intra4x4DirDisable; + t_sint32 Intra16x16ParDisable; + t_sint32 Intra16x16PlaneDisable; + t_sint32 ChromaIntraDisable; + t_uint16 intra_disable; + + t_uint16 FrameRate; +//\/ double FrameRate_parser; + + t_sint32 chroma_qp_index_offset; +//\/#ifdef _FULL_SEARCH_RANGE_ +//\/ t_sint32 full_search; +//\/#endif + + t_sint32 pic_order_cnt_type; /* POC200301 */ + + /* Rate Control on JVT standard */ +//\/ t_sint16 brc_type; + t_sint32 bit_rate; + t_sint32 SeinitialQP; + t_uint16 me_type; /* M.E. Algorithm selection */ + + t_sint32 HrdSendMessages; + t_uint32 CpbBufferSize; + +//\/ char DynoptFileName[FILE_NAME_SIZE]; +//\/ char TimeStampsFileName[FILE_NAME_SIZE]; + + t_uint16 intra_refresh_type; /* 0=disabled 1=AIR */ + t_uint16 air_mb_num; +//\/ t_sint16 slice_loss_first_mb_parser; /* first MB lost (to be forced INTRA) JUST for parser use */ +//\/ t_sint16 slice_loss_mb_num_parser; /* number MBs lost (to be forced INTRA) JUST for parser use */ +//\/ t_sint16 slice_loss_first_mb[8]; /* first MB lost (to be forced INTRA) */ +//\/ t_sint16 slice_loss_mb_num[8]; /* number MBs lost (to be forced INTRA) */ + + /* pixel aspect ratio input parameters */ + t_sint32 aspect_ratio_info_present_flag;/* enable aspect ratio stuff in VUI */ + t_sint32 aspect_ratio_idc; /* aspect ratio idc */ + t_sint32 sar_width; /* used defined pixel width for aspect ratio */ + t_sint32 sar_height; /* used defined pixel height for aspect ratio */ + + /* deblocking filter stuff */ + t_sint32 disable_deblocking_filter_idc; + t_sint32 slice_alpha_c0_offset_div2; + t_sint32 slice_beta_offset_div2; + + t_sint32 video_signal_type_present_flag; + t_sint32 video_format; + t_sint32 video_full_range_flag; + t_sint32 colour_description_present_flag; + t_sint32 colour_primaries; + t_sint32 transfer_characteristics; + t_sint32 matrix_coefficients; + + t_sint32 IntraForced; /* force an Intra at this frame */ +} t_sva_video_encoder_algo_h264_configuration_params; + +typedef struct { +t_uint16 enableAnnexes; +t_uint16 gobHeaderFrequency;/*when 0 then gob header insertion is disable*/ +t_uint16 sliceSizeType; +t_uint16 sliceSizeMax; +t_uint16 sliceBitSize; +t_uint16 sliceMbSize; +t_sva_brc_intra_refresh_mode irMode; +t_uint16 airMbNum; +t_uint16 cirPeriodMax; +t_sva_rtype_mode rtypeMode; +} t_sva_video_encoder_algo_h263_configuration_params; + + +typedef struct { +t_uint32 pictureIntraRefresh;/*Give number of P picture between 2 I.*/ +t_uint8 IPictureQp;/*give the quantification value to use for I picture (2<=IPictureQp<=31)*/ +t_uint8 PPictureQp;/*give the quantification value to use for P picture (2<=PPictureQp<=31)*/ +/* Following field are only need when buffering model is different of SVA_BUFFERING_NONE*/ +t_uint32 bitRate;/*target bit rate in bits/s*/ +t_uint32 vbvBufferSize;/*vbv buffer size in bits*/ +t_uint32 vbvOccupancy;/*initial vbv occupancy in bits*/ +t_uint32 swissBuffer;/*swiss buffer in bits*/ +} t_sva_brc_qpConstant_configuration_params; + + +typedef struct { + t_uint32 dummy; +} t_sva_brc_frameBase_configuration_params; + + +typedef struct { +t_uint32 pictureIntraRefresh;/*Give number of P picture between 2 I.*/ +t_uint32 bitRate;/*target bit rate in bits/s*/ +t_uint32 vbvBufferSize;/*vbv buffer size in bits*/ +t_uint32 vbvOccupancy;/*initial vbv occupancy in bits*/ +t_uint32 swissBuffer;/*swiss buffer in bits*/ +} t_sva_brc_cbr_configuration_params; + + +typedef struct { +t_uint32 pictureIntraRefresh;/*Give number of P picture between 2 I.*/ +t_uint32 bitRate;/*target bit rate in bits/s*/ +t_sva_brc_spatial_quality spatialQuality; +t_uint32 minFrameRate;/*minimum output frame rate*/ +t_uint32 vbvBufferSize;/*vbv buffer size in bits*/ +t_uint32 vbvOccupancy;/*initial vbv occupancy in bits*/ +t_uint32 swissBuffer;/*swiss buffer in bits*/ +} t_sva_brc_vbr_configuration_params; + + +typedef struct { +t_bool isIntraFullPicture; // if true then request for an I picture, +// else only some Mb are request to be intra coded +t_uint16 sliceIntraFirstMb[8]; +t_uint16 sliceIntraMbNumber[8]; +} t_sva_intra_request; + + +typedef struct { +t_uint16 ace_offset_0; +t_uint16 ace_offset_1; +t_uint16 ace_offset_2; +t_uint16 ace_offset_3; +} t_sva_ace_offset; + +typedef struct { + t_uint16 address; + t_uint16 value; /* Not use for a read access */ +} t_sva_packet; + +typedef struct { +t_sva_preprocessor_capability_id transformId; +t_sva_windowed_frame_desc sourceFrameDesc; +t_sva_image_desc resizedWindowDesc; +t_sva_image_desc snapshotImageDesc; +t_sva_preprocessor_input_mode interfaceCConfiguration; /* CCP or CCIR656 */ +t_sva_preprocessor_ccir_input_sync_mode interfaceSyncMode; /* External or embedded synchronisation */ +t_bool isInputInterlaced; +t_bool isOutputFrame; +t_sva_preprocessor_ccir_raw_bpp rawBpp; /* If CCIR data bus is in 10 bits */ +/* This allow to grab raw data using full bus width */ +/* Only valid with transformId == SVA_PREPROCESSOR_RAW */ +/* and interfaceSyncMode != SVA_PREPROCESSOR_SYNC_EMBEDDED_CODES */ +t_uint32 grabSyncLine; /* define the grabbed line when raising the SVA_EVENT_PREPROCESSOR_SYNCHRO */ +/* to disable event generation please use SVA_NO_GRABSYNC_LINE (1023=0x3FF) value; value range: 0 to 1023 */ +t_sva_color_range outputRange; +t_bool isAceEnable; /* Enable or disable automatic contrast enhancement */ +t_sva_ace_strength aceStrength; +t_sva_color_range aceRange; +t_sva_preprocessor_grabhq_configuration grabhqConfig; +} t_sva_preprocessor_configuration; + +typedef struct { +t_sva_service_state state; +t_sva_preprocessor_error_id errorId; +t_uint32 nbGrabbedImage; +t_bool isAceEnable; +t_sva_ace_offset aceOffset; +t_sva_service_event_stats eventStats; +t_sva_service_bufferization_stats bufferizationStats; +} t_sva_preprocessor_status; + + +typedef struct { +t_sint16 matrix_coef1; +t_sint16 matrix_coef2; +t_sint16 matrix_coef3; +t_sint16 matrix_coef4; +} t_sva_postprocessor_color_matrix; + +typedef struct { +t_uint16 quant_y[64]; // value range for quant_y/cb/cr params: 1 to 255 +t_uint16 quant_cb[64]; +t_uint16 quant_cr[64]; +} t_sva_quantization_table; + + +typedef struct { +t_uint16 huffmanYCodeDc[12]; +t_uint16 huffmanYSizeDc[12]; // value range for huffman-Y/Cb/Cr-Size-Dc/Ac params: 1 to 16 (if 0 it will not be used) +t_uint16 huffmanYCodeAc[256]; +t_uint16 huffmanYSizeAc[256]; +t_uint16 huffmanCbCodeDc[12]; +t_uint16 huffmanCbSizeDc[12]; +t_uint16 huffmanCbCodeAc[256]; +t_uint16 huffmanCbSizeAc[256]; +t_uint16 huffmanCrCodeDc[12]; +t_uint16 huffmanCrSizeDc[12]; +t_uint16 huffmanCrCodeAc[256]; +t_uint16 huffmanCrSizeAc[256]; +} t_sva_huffman_table; + +typedef struct { +t_sva_postprocessor_capability_id transformId; +t_sva_postprocessor_external_sync_mode syncMode; +t_bool isDirectScreenAccess; // TRUE => screenFrameBufferBaseAddr SHALL be provided +// FALSE => the output buffer(s) will be provided one by one +// through SVA_PushImageBuffer() call +t_bool isDoubleBufferMode; // Only meaning if isDirectScreenAccess == TRUE +// TRUE => toggle between the 2 next frame buffers +// FALSE => use only the first one +// N.B: if isDirectScreenAccess == TRUE and isDoubleBufferMode == TRUE +// then the HCL will raised alternatively SVA_EVENT_POSTPROCESSOR_SYNCHRO and SVA_EVENT_POSTPROCESSOR_ALT_SYNCHRO events +// else (isDoubleBufferMode == FALSE) only SVA_EVENT_POSTPROCESSOR_SYNCHRO will be raised +t_physical_address screenFrameBufferBaseAddr; +t_physical_address screenAlternateFrameBufferBaseAddr; +t_sva_windowed_frame_desc sourceFrameDesc; +t_sva_image_desc resizedImageDesc; +t_sva_window_desc clippedWindowDesc; +t_sva_windowed_frame_desc videoFrameBufferDesc; +t_uint32 displaySyncLine; // SVA_EVENT_POSTPROCESSOR_LINE_SYNCHRO event will be raised +// when displaying the displaySyncLine line +// to disable event generation please use SVA_NO_GRABSYNC_LINE (1023=0x3FF) value +// if enable (!=1023) must be multiple of 16 and value range: 16 to source_window_height +t_sva_postprocessor_color_matrix colorMatrix; // matrix coef range: -1024 to 1023 +t_sva_color_range outputRange; +t_sva_postprocessor_ace_mode aceMode; +t_sva_ace_strength aceStrength; +t_sva_color_range aceRange; +t_sva_color_depth bitsPerPixel; +t_sva_mirroring_mode mirrorMode; +t_sva_rotation_mode rotationMode; +t_uint8 contrast; // values in [0..100] range. 50 is the standard value +t_uint8 brightness; // values in [0..100] range. 50 is the standard value +t_bool isDithering; +t_sva_deblocking_filter_mode deblockingFilterMode; +t_sva_deringing_filter_mode deringingFilterMode; +t_sva_sampling_format chromaSamplingFormat; +t_uint8 alphaKey; +t_bool redBlueSwap; +t_bool raster_in_format; +} t_sva_postprocessor_configuration; + + +typedef struct { +t_sva_service_state state; +t_sva_postprocessor_error_id errorId; +t_uint32 nbInputImagesPostProcessed; +t_uint32 nbOutputImagesDisplayed; +t_bool isAceEnable; +t_sva_ace_offset aceOffset; +t_sva_service_event_stats eventStats; +t_sva_service_bufferization_stats bufferizationStats; +} t_sva_postprocessor_status; + +typedef struct { +t_sva_sw_processing_capability_id transformId; +t_sva_image_desc originalPicture; +t_bool isUsingCustomZoneOfInterestBitmap; +t_sva_offset_desc startCroppingOffset; +t_uint32 horizontalThreshold; +t_uint32 verticalThreshold; +t_uint16 customZoneOfInterestBitmap[84]; +t_bool raster_in_format; +t_bool no_search_window; +} t_sva_sw_processing_configuration; + + +typedef struct { +t_sva_service_state state; +t_sva_sw_processing_error_id errorId; +t_uint32 nbImagesStabilized; +t_sva_service_event_stats eventStats; +t_sva_service_bufferization_stats bufferizationStats; +} t_sva_sw_processing_status; + + + +typedef enum { +SVA_NON_THUMBNAIL, +SVA_THUMBNAIL_DC_420MB /* Specific image buffer will have to be pushed out */ +} t_sva_thumbnail_mode; + + +typedef struct { +t_sva_still_image_encoder_capability_id transformId; +t_sva_codec_mode mode; // see §2.9: encoder => bitstream buffer as output +t_bool isSliceMode; +t_sva_thumbnail_mode thumbnailMode; +t_sva_windowed_frame_desc sourceFrameDesc; // if isSliceMode === TRUE, then no cropping possible +// sourceFrameDesc.window "==" sourceFrameDesc.frame +t_bool raster_in_format; +tp_sva_still_algo_configuration_params pAlgoConfig; +} t_sva_still_encoder_configuration; + +typedef enum +{ + SVA_JPEG_ENCODE_ROTATION_NONE, + SVA_JPEG_ENCODE_ROTATION_ANTICLOCKWISE, + SVA_JPEG_ENCODE_ROTATION_CLOCKWISE + }t_sva_jpeg_encode_on_fly_rotation; + +typedef struct { +t_uint16 restartInterval; +t_bool isOptimizeQuantTableEnable; +t_sva_jpeg_encode_on_fly_rotation rotation; +t_bool isOptimizeHuffmanTableEnable; +t_uint16 targetBpp; /* unit is 1/256 bpp */ +t_sva_quantization_table quantizationTable; /* WARNING: encoder use only one chroma table */ +/* (here quant_cb) */ +/* could be undefined if isOptimizeQuantTableEnable==TRUE */ +// value range for quant_y/cb/cr params: 1 to 255 +t_sva_huffman_table huffmanTable; /* could be undefined if isOptimizeHuffmanTableEnable==TRUE */ +// value range for huffman-Y/Cb/Cr-Size-Dc/Ac params: 1 to 16 (if 0 it will not be used) +} t_sva_still_algo_jpeg_configuration_params; + + +typedef struct { +t_sva_service_state state; +t_sva_still_image_encoder_error_id errorId; +t_uint32 nbBytesEncoded; +t_uint32 nbImagesEncoded; +t_sva_service_event_stats eventStats; +t_sva_service_bufferization_stats bufferizationStats; +} t_sva_still_encoder_status; + + +typedef struct { +t_uint16 hSamplingFactorY; +t_uint16 vSamplingFactorY; +t_uint16 hSamplingFactorCb; +t_uint16 vSamplingFactorCb; +t_uint16 hSamplingFactorCr; +t_uint16 vSamplingFactorCr;// param SamplingFactor-xx value: 1, 2 or 4 if used +//(used if componentSelector-xx = 1: if color_mode = monochrome only xSamplingFactorY used) +} t_sva_sampling_factor; + + +typedef struct { +t_uint16 restartInterval; +t_sva_huffman_table huffmanTable; +t_sva_quantization_table quantizationTable; +} t_sva_still_decoder_algo_sequential_jpeg_header_infos; + + +typedef struct { +t_uint16 nbScanComponents; +t_uint16 componentSelectorY; //value: 0 = the Y component is not present in the current scan; 1 = present +t_uint16 componentSelectorCb; //value: 0 = the Cb component is not present in the current scan; 1 = present +t_uint16 componentSelectorCr; //value: 0 = the Cr component is not present in the current scan; 1 = present +t_uint16 startSpectralSelection; // value range: 0 to 63 +t_uint16 endSpectralSelection; // value range: startSpectralSelection to 63 +t_uint16 successiveApproxPosition; +t_uint16 restartInterval; +t_sva_huffman_table huffmanTable; +t_sva_quantization_table quantizationTable; +} t_sva_still_decoder_algo_progressive_jpeg_header_infos; + + +typedef struct { +t_sva_still_image_decoder_capability_id transformId; +t_sva_codec_mode mode; // see §2.9: decoder => bitstream buffer as input +t_sva_image_desc decodedFrameDesc; +t_sva_window_desc crop_window; /*cropping is only supported from FW 3.6.0 onwards and HCL 3.4.0 onwards */ +t_sva_ace_strength aceStrength; +t_bool is_cropping_enabled; +t_bool no_slice_mode; +tp_sva_still_algo_configuration_params pAlgoConfig; +} t_sva_still_decoder_configuration; + + +typedef struct { +t_sva_still_image_color_mode colorMode; +t_sva_sampling_factor samplingFactor; // param SamplingFactor-xx value: 1, 2 or 4 if used +//(used if componentSelector-xx = 1: if colormode = monochrome only SamplingFactorY used) +t_sva_downsampling_factor downsamplingFactor; +} t_sva_still_algo_jpeg_decoder_configuration_params; + + +typedef struct { +t_sva_service_state state; +t_sva_still_image_decoder_error_id errorId; +t_uint32 nbBytesDecoded; +t_uint32 nbImagesDecoded; +t_sva_service_event_stats eventStats; +t_sva_service_bufferization_stats bufferizationStats; +} t_sva_still_decoder_status; + + +typedef struct { +t_bool isInterlacedEnabled; +t_uint16 numberOfLines ;// 6<=numberOfLines<=2047 +t_uint16 field1BlankingStartLine ; //FSB1: 1<=FBS1<=numberOfLines +//if isInterlacedEnabled=FALSE: FBS1!=FBE1 +//if isInterlacedEnabled=TRUE: (FBS1. */ +/*---------------------------------------------------------------------------*/ + + +/*--------------------------------------------------------------------------* + * Includes * + *--------------------------------------------------------------------------*/ + +#include "hcl_defs.h" +#include "mupoc_mapping.h" +#include "services.h" +#include "audio_services.h" +#include "vic.h" +#include "saa.h" + + +t_uint32 g_saa_oldHandler[2]; + + +/****************************************************************************/ +/* NAME: saaIrqHandler0 */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: Interrupt handler for Audio services / IRQ 0 line */ +/* PARAMETERS: NONE */ +/* RETURN: NONE */ +/****************************************************************************/ + +void saaIrqHandler0(void) +{ + t_saa_irq_src irq_src = SAA_GetIRQSrc(ESAA_IRQ_0); + t_saa_error error; + + SAA_ClearIRQSrc(irq_src); + error = SAA_GetIRQSrcStatus(irq_src); + (void)VIC_AcknowledgeItLine(VIC_SAA_0_LINE); + (void)error; +} + + + +/****************************************************************************/ +/* NAME: saaIrqHandler1 */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: Interrupt handler for Audio services / IRQ 1 line */ +/* PARAMETERS: NONE */ +/* RETURN: NONE */ +/****************************************************************************/ + +void saaIrqHandler1(void) +{ + t_saa_irq_src irq_src = SAA_GetIRQSrc(ESAA_IRQ_1); + t_saa_error error; + + SAA_ClearIRQSrc(irq_src); + error = SAA_GetIRQSrcStatus(irq_src); + (void)VIC_AcknowledgeItLine(VIC_SAA_1_LINE); + (void)error; +} + + + +/****************************************************************************/ +/* NAME: SER_AUDIO_Init */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: This routine initializes the Audio services */ +/* PARAMETERS: mask */ +/* RETURN: NONE */ +/****************************************************************************/ + +PUBLIC void SER_AUDIO_Init(IN t_uint8 mask) +{ + t_version version; + t_saa_init SaaInit; + t_saa_error error; + t_vic_error vic_error; + + (void)SAA_GetVersion(&version); + PRINT(" Version %d.%d.%d ", version.version, version.major, version.minor); + + SaaInit.SAABaseAddress = HA_BASE_ADDR; + + error = SAA_Init(&SaaInit); + if (error != ESAA_ERROR_NONE) + { + PRINT("FATAL: SAA_Init failed with error %u! ", error); + return; + } + + vic_error = VIC_ChangeDatum(VIC_SAA_0_LINE, (t_uint32)saaIrqHandler0, &g_saa_oldHandler[0]); + if (vic_error != VIC_OK) + PRINT("FATAL: Unable to install IRQ handler 0 (error %u)! ", vic_error); + else + vic_error = VIC_EnableItLine(VIC_SAA_0_LINE); + + vic_error = VIC_ChangeDatum(VIC_SAA_1_LINE, (t_uint32)saaIrqHandler1, &g_saa_oldHandler[1]); + if (vic_error != VIC_OK) + PRINT("FATAL: Unable to install IRQ handler 1 (error %u)! ", vic_error); + else + vic_error = VIC_EnableItLine(VIC_SAA_1_LINE); +} + + + +/****************************************************************************/ +/* NAME: SER_AUDIO_Close */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: This routine stops the audio services */ +/* PARAMETERS: NONE */ +/* RETURN: NONE */ +/****************************************************************************/ + +PUBLIC void SER_AUDIO_Close(void) +{ + t_uint32 dummy; + t_vic_error vic_error; + + vic_error = VIC_DisableItLine(VIC_SAA_0_LINE); + vic_error = VIC_ChangeDatum(VIC_SAA_0_LINE, g_saa_oldHandler[0], &dummy); + if (vic_error != VIC_OK) + PRINT("FATAL: Unable to uninstall IRQ handler 0 (error %u)! ", vic_error); + + vic_error = VIC_DisableItLine(VIC_SAA_1_LINE); + vic_error = VIC_ChangeDatum(VIC_SAA_1_LINE, g_saa_oldHandler[1], &dummy); + if (vic_error != VIC_OK) + PRINT("FATAL: Unable to uninstall IRQ handler 1 (error %u)! ", vic_error); +} --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/audio_services.h @@ -0,0 +1,39 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ + +#ifndef _SERVICES_AUDIO_H +#define _SERVICES_AUDIO_H + +#include "hcl_defs.h" +#include "mupoc_mapping.h" +#include "services.h" +#include "saa.h" + + +/*************** Function Prototypes *********************/ + +PUBLIC void saaIrqHandler0(void); +PUBLIC void saaIrqHandler1(void); + +PUBLIC void SER_AUDIO_Init(IN t_uint8 mask); +PUBLIC void SER_AUDIO_Close(void); + + +#endif /* _SERVICES_AUDIO_H */ + --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/ha_api_params.h @@ -0,0 +1,1064 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ + +#ifndef _ha_api_params_h_ +#define _ha_api_params_h_ +#include "ha_hcl_fw_interface.h" +#include "ha_codec_params.h" +#include "ha_effect_params.h" +#include "ha_codec_info.h" +#include "ha_effect_info.h" +/***************************************/ +// Enum of supported sample frequencies. +/***************************************/ +typedef enum +{ + ESAA_FREQ_UNKNOWNKHZ, + ESAA_FREQ_192KHZ, + ESAA_FREQ_176_4KHZ, + ESAA_FREQ_128KHZ, + ESAA_FREQ_96KHZ, + ESAA_FREQ_88_2KHZ, + ESAA_FREQ_64KHZ, + ESAA_FREQ_48KHZ, + ESAA_FREQ_44_1KHZ, + ESAA_FREQ_32KHZ, + ESAA_FREQ_24KHZ, + ESAA_FREQ_22_05KHZ, + ESAA_FREQ_16KHZ, + ESAA_FREQ_12KHZ, + ESAA_FREQ_11_025KHZ, + ESAA_FREQ_8KHZ, + ESAA_FREQ_7_2KHZ, + ESAA_FREQ_LAST_IN_LIST +} t_saa_sample_freq; + +/*****************************************************/ +// Enum of memory preset +/*****************************************************/ +typedef enum { + ESAA_MEM_DEFAULT, + ESAA_MEM_ALL_DDR, + ESAA_MEM_ALL_TCM, + ESAA_MEM_MIX_DDR_TCM_1, + ESAA_MEM_MIX_DDR_TCM_2, + ESAA_MEM_MIX_DDR_TCM_3, + ESAA_MEM_MIX_DDR_TCM_4, + ESAA_MEM_MIX_DDR_TCM_5, + ESAA_MEM_ALL_ESRAM, + ESAA_MEM_MIX_ESRAM_DDR, + ESAA_MEM_MIX_ESRAM_TCM, + ESAA_MEM_MIX_ESRAM_OTHER_1, + ESAA_MEM_MIX_ESRAM_OTHER_2, + ESAA_MEM_MIX_ESRAM_OTHER_3, + ESAA_MEM_MIX_ESRAM_OTHER_4, + ESAA_MEM_MIX_ESRAM_OTHER_5 +}t_saa_memory_preset; + +/****************************/ +// Enum of supported codecs. +/****************************/ +typedef enum +{ + ESAA_NO_CODEC = 10, // ESAA_BLOCK_LAST_IN_LIST (helpful for debug) + ESAA_DEC_AMR, + ESAA_ENC_AMR, + ESAA_DEC_AMRWB, + ESAA_ENC_AMRWB, + ESAA_DEC_SBC, + ESAA_ENC_SBC, + ESAA_DEC_MP3, + ESAA_ENC_MP3, + ESAA_DEC_AAC, + ESAA_ENC_AAC, + ESAA_DEC_G729, + ESAA_ENC_G729, + ESAA_DEC_G723_1, + ESAA_ENC_G723_1, + ESAA_DEC_G711, + ESAA_ENC_G711, + ESAA_DEC_G722, + ESAA_ENC_G722, + ESAA_DEC_QCELP, + ESAA_ENC_QCELP, + ESAA_DEC_EVRC, + ESAA_ENC_EVRC, + ESAA_ENC_STMPEG, + ESAA_DEC_WMA, + ESAA_ENC_EAAC, + ESAA_DEC_MPEG2, + ESAA_DEC_AWP, + ESAA_DEC_iLBC, + ESAA_ENC_iLBC, + ESAA_ENC_AWP, + ESAA_ENC_IMAADPCM, + ESAA_DEC_IMAADPCM, + ESAA_DEC_G726, + ESAA_ENC_G726, + ESAA_DEC_G722_FTRD, + ESAA_ENC_G722_FTRD, + ESAA_DEC_OGGVORBIS, + ESAA_CODEC_LAST_IN_LIST +} t_saa_codec_type; + +#define HA_PROCESS_LIST_SIZE ESAA_CODEC_LAST_IN_LIST + + +/****************************/ +// Enum of supported effects. +/****************************/ +typedef enum +{ + ESAA_AEP_COMP_RESERVED_1, // 0 + ESAA_AEP_COMP_RESERVED_2, // 1 + ESAA_AEP_COMP_ENH, // 2 + ESAA_AEP_COMP_VOLCTRL, // 3 + ESAA_AEP_COMP_MIXER, // 4 + ESAA_AEP_COMP_TYPE2, // 5 + ESAA_AEP_COMP_RESERVED1, // 6 + ESAA_AEP_COMP_SRC, // 7 + ESAA_AEP_COMP_COMPRESSOR, // 8 + ESAA_AEP_COMP_DTMF, // 9 + ESAA_AEP_COMP_RESERVED2, // 10 + ESAA_AEP_COMP_COMPANDER, // 11 + ESAA_AEP_COMP_LEC, // 12 + ESAA_AEP_COMP_SPLITTER, // 13 + ESAA_AEP_COMP_FLOWMINATOR, // 14 + ESAA_AEP_COMP_OP_1, // 15 + ESAA_AEP_COMP_OP_2, // 16 + ESAA_AEP_COMP_OP_3, // 17 + ESAA_AEP_COMP_OP_4, // 18 + ESAA_AEP_COMP_OP_5, // 19 + ESAA_AEP_COMP_OP_6, // 20 + ESAA_AEP_COMP_TONEGENERATOR, // 21 + ESAA_AEP_COMP_TYPE2_MDRC, // 22 + ESAA_AEP_COMP_STEREOENHANCER, // 23 + ESAA_AEP_COMP_RESERVED3, // 24 : should be removed + ESAA_AEP_COMP_TYPE2_HDHX20, // 25 + ESAA_AEP_COMP_TYPE2_HDSX20, // 26 + ESAA_AEP_COMP_TYPE2_HDHX3D, // 27 + ESAA_AEP_COMP_TYPE2_HDSX3D, // 28 + ESAA_AEP_COMP_TYPE2_HDDOPPLER, // 29 + ESAA_AEP_COMP_TYPE2_HDBB, // 30 + ESAA_AEP_COMP_TYPE2_HDTB, // 31 + ESAA_AEP_COMP_TYPE2_HDDC, // 32 + ESAA_AEP_COMP_TYPE2_HDEQ, // 33 + ESAA_AEP_COMP_OP_7, // 34 + ESAA_AEP_COMP_OP_9, // 35 + ESAA_AEP_COMP_DOPPLER, // 36 + ESAA_AEP_COMP_EQUALIZER, // 37 + ESAA_AEP_COMP_TYPE1_STWID_HD, // 38 + ESAA_AEP_COMP_TYPE1_STWID_LS, // 39 + ESAA_AEP_COMP_REVERB, // 40 + ESAA_AEP_COMP_RESERVED4, // 41 + ESAA_AEP_COMP_RESERVED5, // 42 + ESAA_AEP_COMP_WBNB_NAEC, // 43 + ESAA_AEP_COMP_AUDIOVISUALIZATION, // 44 + ESAA_AEP_COMP_TYPE2_HD3D, // 45 + ESAA_AEP_COMP_OP_8, // 46 + ESAA_AEP_COMP_ST_MDRC, // 47 + ESAA_AEP_COMP_ST3D, // 48 + ESAA_AEP_COMP_EMPTY, // 49 + ESAA_AEP_COMP_NOISE_REDUCTOR_LC, // 50 + ESAA_AEP_COMP_TRANSDUCER_EQUALIZER, // 51 + ESAA_AEP_COMP_SWITCH, // 52 + ESAA_AEP_COMP_SW_LS_FTRD, // 53 + ESAA_AEP_COMP_SW_HS_FTRD, + ESAA_AEP_COMP_LAST_IN_LIST //should always be the last of the list +} t_saa_aep_comp; +/***************************/ +// Enum of supported blocks. +/***************************/ +typedef enum +{ + ESAA_BLOCK_NONE, // 0 + ESAA_BLOCK_CODEC, // 1 + ESAA_BLOCK_DMA, // 2 + ESAA_BLOCK_HSI, // 3 + ESAA_BLOCK_AEP, // 4 + ESAA_BLOCK_SHM, // 5 + ESAA_BLOCK_RESERVED_6, // 6 + ESAA_BLOCK_RESERVED_7, // 7 + ESAA_BLOCK_RESERVED_8, // 8 + ESAA_BLOCK_RESERVED_9, // 9 + ESAA_BLOCK_LAST_IN_LIST // 10 +} t_saa_block_type; + +/*******************************/ +// Enum of supported port types. +/*******************************/ +typedef enum +{ + ESAA_PORT_TYPE_UNKNOWN, + ESAA_PORT_TYPE_IN, + ESAA_PORT_TYPE_OUT, + ESAA_PORT_TYPE_LAST_IN_LIST +} t_saa_port_type; + +/************************************/ +// Enum of supported port data types. +/************************************/ +typedef enum +{ + ESAA_PORT_DATA_TYPE_UNKNOWN, + ESAA_PORT_DATA_TYPE_SAMPLE, + ESAA_PORT_DATA_TYPE_BITSTREAM, + ESAA_PORT_DATA_TYPE_LAST_IN_LIST +} t_saa_port_data_type; + +/*************************************/ +// Enum of supported endianness. +/*************************************/ +typedef enum +{ + ESAA_ENDIANESS_UNKNOWN, + ESAA_ENDIANESS_BIG_ENDIAN, // need byte swap by MMDSP (try to avoid it because use MIPS!) + ESAA_ENDIANESS_LITTLE_ENDIAN, // no byte swap by MMDSP + ESAA_ENDIANESS_LAST_IN_LIST +} t_saa_endianess_type; + +/*************************************/ +// Enum of supported number of channel. +/*************************************/ +typedef enum +{ + ESAA_SAMPLE_CHANNEL_UNKNOWN, + ESAA_SAMPLE_CHANNEL_MONO, + ESAA_SAMPLE_CHANNEL_STEREO, + ESAA_SAMPLE_CHANNEL_LAST_IN_LIST +} t_saa_sample_channel_nb; + +/**************************************************/ +// Enum of supported interleaving type for samples. +/**************************************************/ +typedef enum +{ + ESAA_SAMPLE_INTERLEAVING_UNKNOWN, + ESAA_SAMPLE_INTERLEAVED, + ESAA_SAMPLE_NOT_INTERLEAVED, + ESAA_SAMPLE_INTERLEAVING_LAST_IN_LIST +} t_saa_sample_interleaving_type; + +/******************************************/ +// Enum of block priority levels. +/******************************************/ +typedef enum { + ESAA_PRIORITY_NORMAL, // TBD + ESAA_PRIORITY_BACKGROUND +} t_saa_priority_level; + +/*************************************************/ +// Enum of Real Time mode +/*************************************************/ +typedef enum +{ + ESAA_NO_REAL_TIME = 0, + ESAA_REAL_TIME_WO_ALERT, + ESAA_REAL_TIME_WITH_ALERT +} t_saa_real_time_activation; + +/*************************************************/ +// Enum of alert activation for underflow mgt +/*************************************************/ +typedef enum +{ + ESAA_NO_UNDERFLOW_MGT_ALERT = 0, + ESAA_UNDERLOW_MGT_ALERT +} t_saa_underflow_mgt_alert; + +/*****************************************************/ +// Enum for selection of memory bank. +/*****************************************************/ +typedef enum +{ + ESAA_MEMORY_BANK_DEFAULT, + ESAA_MEMORY_BANK_INTX, + ESAA_MEMORY_BANK_INTY, + ESAA_MEMORY_BANK_EXT16, + ESAA_MEMORY_BANK_EXT24, + ESAA_MEMORY_BANK_ESRAM, + ESAA_MEMORY_BANK_ESRAM16, + ESAA_MEMORY_BANK_LAST_IN_LIST +} t_saa_memory_bank; + +/*****************************************************/ +// Enum of STOP mode. (stop command parameter added within FW-2.5.0) +/*****************************************************/ +typedef enum +{ + ESAA_DEFAULT_STOP, // for backward compatibility + ESAA_NORMAL_STOP, // normal STOP + ESAA_EOF_STOP // transform STOP in EOF +} t_saa_stop_mode; + +/*****************************************************/ +// Enum of data memory management and EOF alert mode. +/*****************************************************/ +typedef enum +{ + ESAA_BASIC_MEMORY_EOF_MGT, + ESAA_SPECIFIC_MEMORY_EOF_MGT, + ESAA_DATA_MGT_LAST_IN_LIST +} t_saa_eof_mode; + + +/*****************************************************/ +// Enum of origin of EOF alert mode. +/*****************************************************/ +typedef enum +{ + ESAA_EOF_OUTPUT_BLOCK, + ESAA_EOF_NETWORK +} t_saa_eof_origin; + +/*****************************************************/ +// Enum of data behavior when mixing +/*****************************************************/ +typedef enum { + ESAA_DATA_MIXED, + ESAA_DATA_MUTED +}t_saa_data_mixing; + +/*****************************************/ +// DMA config command struct +/*****************************************/ +typedef struct t_saa_dma_params +{ + t_saa_endianess_type endianess; + t_saa_sample_freq sample_freq; + t_saa_sample_channel_nb channel_nb; + t_saa_sample_interleaving_type interleaving; + t_uint16 sample_size; + t_saa_real_time_activation real_time; + t_uint16 buffer_size; + t_saa_eof_mode eof_mode; + t_saa_memory_bank memory_bank; + t_uint16 shm_underflow_mgt; +} t_saa_dma_params; + +/*****************************************/ +// HSI data mode +/*****************************************/ +typedef enum +{ + ESAA_HSI_SPEECH, + ESAA_HSI_AUDIO +} t_saa_hsi_mode; + +/*****************************************/ +// HSI sample bit size +/*****************************************/ + +typedef enum { + ESAA_SAMPLE_SIZE_UNDEFINED = 0, + ESAA_SAMPLE_SIZE_8 = 8, + ESAA_SAMPLE_SIZE_16 = 16, + ESAA_SAMPLE_SIZE_24 = 24, + ESAA_SAMPLE_SIZE_32 = 32 +} t_saa_sample_bitsize; + +/*****************************************/ +// HSI burst size +/*****************************************/ +#define ESAA_HSI_BURST_SIZE_1 1 +#define ESAA_HSI_BURST_MAX_SIZE 32 +/*****************************************/ +// HSI alert gap +/*****************************************/ +typedef enum { + ESAA_HSI_ALERT_GAP_UNDEFINED = 1, + ESAA_HSI_ALERT_GAP_2 = 2, // 2* 5 ms = 25 ms + ESAA_HSI_ALERT_GAP_5 = 5, // 5* 5 ms = 25 ms + ESAA_HSI_ALERT_GAP_10 = 10, // 10*5 ms = 50 ms + ESAA_HSI_ALERT_GAP_20 = 20, // 20*5 ms = 100 ms + ESAA_HSI_ALERT_GAP_40 = 40, // 40*5 ms = 200 ms + ESAA_HSI_ALERT_GAP_60 = 60 // 60*5 ms = 300 ms +}t_saa_alert_gap ; + +/*****************************************/ +// HSI port config struct +/*****************************************/ +typedef struct +{ + t_uint16 nb_channels; + t_saa_hsi_mode mode; + t_saa_sample_freq sample_freq; + t_uint16 port_id; + t_saa_sample_bitsize sample_bitsize; + t_uint16 burst_size; + t_uint16 underflow_trigger; // Value of the guard timer in micro second + t_saa_alert_gap alert1_group_duration; // Duration in between two alert (base unit: 5ms) + t_saa_alert_gap alert2_group_duration; // Duration in between two alert (base unit: 5ms) + t_uint16 shm_underflow_mgt; // BlockId of the SHM input block to adress HA_HEADER_SHM_UNDERFLOW_MGT msg +} t_saa_hsi_params; + +/*****************************************/ +// AEP init command struct +/*****************************************/ +typedef struct t_saa_aep_params +{ + t_uint16 block_size; + t_saa_sample_channel_nb aep_type; + t_uint16 nb_position_max; +} t_saa_aep_params; + +/*****************************************/ +// SHM config command struct +/*****************************************/ +typedef struct t_saa_shm_params +{ + t_saa_endianess_type endianess; + t_uint16 buffer_size; + t_uint16 nb_buffers; + t_saa_eof_mode eof_mode; + t_saa_memory_bank memory_bank; + t_saa_sample_channel_nb channel_nb; + t_saa_underflow_mgt_alert underflow_mgt_alert; +} t_saa_shm_params; + +/******************/ +// Enum for alerts. +/******************/ +typedef enum +{ + ESAA_FW_ALERT_UNKNOWN = 0x3000, //12288 + ESAA_FW_ALERT_BOOT_FINISHED= HA_ALERT_BOOT_FINISHED , + ESAA_FW_ALERT_ERROR_DETECTED= HA_ALERT_ERROR_DETECTED, + ESAA_FW_ALERT_CHANGE_DATA_FORMAT= HA_ALERT_CHANGE_DATA_FORMAT, + ESAA_FW_ALERT_EOF= HA_ALERT_EOF, + ESAA_FW_ALERT_HSI_RESET_CONNECTION_BB= HA_ALERT_HSI_RESET_CONNECTION_BB, + ESAA_FW_ALERT_AEP_DTMF= HA_ALERT_AEP_DTMF, + ESAA_FW_ALERT_CODEC_INFO= HA_ALERT_CODEC_INFO, + ESAA_FW_ALERT_SHM_BUFFER_READY= HA_CMD_SHM_BUFFER_READY, + ESAA_FW_ALERT_SHM_BUFFER_RELEASED= HA_CMD_SHM_BUFFER_RELEASED, + ESAA_FW_ALERT_NEED_NORMAL_SPEED= HA_ALERT_NEED_NORMAL_SPEED, + ESAA_FW_ALERT_READY_FOR_SLOW_SPEED= HA_ALERT_READY_FOR_SLOW_SPEED, + ESAA_FW_ALERT_AEP_AUDIO_VISU= HA_ALERT_AEP_AUDIO_VISU, + ESAA_FW_ALERT_HSI_BURST_COMPLETE= HA_ALERT_HSI_BURST_COMPLETE, + ESAA_FW_ALERT_HSI_ALLOW_SLEEP_MODE= HA_ALERT_HSI_ALLOW_SLEEP_MODE, + ESAA_FW_ALERT_AEP_TRANSDUCER_EQ= HA_ALERT_AEP_TRANSDUCER_EQ, + ESAA_FW_ALERT_AEP_WBNB_NAEC= HA_ALERT_AEP_WBNB_NAEC, + ESAA_FW_ALERT_LAST_IN_LIST // Must always be last in list. +} t_saa_alert_id; + +/***************************************************/ +// Enum for param1 of alert SAA_FW_ALERT_CODEC_ERROR. +/***************************************************/ +// !!! this enum has to be aligned with RETURN_STATUS_LEVEL_T enum defined into comon_interface.h file +typedef enum +{ + ESAA_CODEC_ERROR_LEVEL_NONE, + ESAA_CODEC_ERROR_LEVEL_WARNING, + ESAA_CODEC_ERROR_LEVEL_ERROR, + ESAA_CODEC_ERROR_LEVEL_FATAL_ERROR +} t_saa_codec_error_level; + +/***********************************************************/ +// Enum for param1 (error level) "error" of an answer/alert. +/***********************************************************/ + +typedef enum +{ + ESAA_FW_ERROR_NONE = 0, + + /* Warnings */ + ESAA_FW_ERROR_LEVEL_WARNING = 0x100, + ESAA_FW_WARNING_UNDERFLOW, + ESAA_FW_WARNING_ERC_ON, + ESAA_FW_WARNING_STREAM_CORRUPT, + ESAA_FW_WARNING_LEFT_MEM, + ESAA_FW_WARNING_ERC_FRAME_GENERATED, + + /* resources */ + ESAA_FW_ERROR_LEVEL_RESOURCES = 0x200, + ESAA_FW_RESOURCES_NO_MORE_FREE_DTIO, + ESAA_FW_RESOURCES_NOT_ENOUGH_MEMORY, + ESAA_FW_RESOURCES_MAX_CMD_REACHED_TRY_LATER, + ESAA_FW_RESOURCES_PIPE_FULL, + ESAA_FW_RESOURCES_TOO_MANY_ITEMS, + ESAA_FW_RESOURCES_DISABLE_CYCLE_ESTIMATION, + + /* bad used */ + ESAA_FW_ERROR_LEVEL_BAD_USED = 0x300, + ESAA_FW_BAD_USED_BAD_SERVER_ID, + ESAA_FW_BAD_USED_BAD_ID, + ESAA_FW_BAD_USED_BAD_CONNECTION, + ESAA_FW_BAD_USED_PORT_CONNECTED, + ESAA_FW_BAD_USED_PORT_DISCONNECTED, + ESAA_FW_BAD_USED_WRONG_CONFIG, + ESAA_FW_BAD_USED_FREEZE_CMD_NEEDED, + ESAA_FW_BAD_USED_CONFIG_CMD_NEEDED, + ESAA_FW_BAD_USED_NOT_ENOUGH_PORT, + ESAA_FW_BAD_USED_TOO_MANY_PORTS, + ESAA_FW_BAD_USED_SER_NOT_AVAILABLE, + ESAA_FW_BAD_USED_INFO_NOT_AVAILABLE, + ESAA_FW_BAD_USED_CMD_REFUSED, + ESAA_FW_BAD_USED_AEP_INCONSISTENT_FRAMEWORK, + ESAA_FW_BAD_USED_UNKNOWN_CMD, + ESAA_FW_BAD_USED_PDT_HSI_POWER_MODE, + ESAA_FW_BAD_USED_PDT_HSI_BURST_SIZE, + ESAA_FW_BAD_USED_PDT_HSI_BAD_DATA_FORMAT, + + /* protocol */ + ESAA_FW_ERROR_LEVEL_PROTOCOL = 0x400, + ESAA_FW_PROTOCOL_LOST_SYNC, + ESAA_FW_PROTOCOL_SHM_BUF_TOO_SMALL, + ESAA_FW_PROTOCOL_CODEC_ERROR, + ESAA_FW_PROTOCOL_EFFECT_ERROR, + ESAA_FW_PROTOCOL_PDT_HSI_POWER_MODE, + + /* fatal */ + ESAA_FW_ERROR_LEVEL_FATAL = 0x500, + /* fatal error into hamaca module */ + ESAA_FW_FATAL_HA_BAD_FIFO_ID, + ESAA_FW_FATAL_HA_BAD_PIPE_ID, + ESAA_FW_FATAL_HA_PIPE_ERROR, + ESAA_FW_FATAL_HA_BAD_CREATE_BLOCK_ANS, + ESAA_FW_FATAL_HA_BAD_DELETE_BLOCK_ANS, + ESAA_FW_FATAL_HA_BAD_CREATE_PORT_ANS, + ESAA_FW_FATAL_HA_FREEZE_CMD_LOST, + ESAA_FW_FATAL_HA_BAD_FREEZE_ANS, + ESAA_FW_FATAL_HA_CONNECT_CMD_LOST, + ESAA_FW_FATAL_HA_BAD_CONNECT_ANS, + ESAA_FW_FATAL_HA_DISCONNECT_CMD_LOST, + ESAA_FW_FATAL_HA_BAD_DISCONNECT_ANS, + ESAA_FW_FATAL_HA_UPDATE_CMD_LOST, + ESAA_FW_FATAL_HA_BAD_UPDATE_ANS, + ESAA_FW_FATAL_HA_PORT_LIST_LOST, + ESAA_FW_FATAL_HA_UNKNOWN_CMD_ANS, + ESAA_FW_FATAL_HA_PIPE1_NOT_CREATED, + ESAA_FW_FATAL_HA_PIPE_SERVER_NOT_CREATED, + ESAA_FW_FATAL_HA_SEMA_TABLE_NOT_CREATED, + ESAA_FW_FATAL_HA_BAD_DYNAMIC_MEM_ALLOC, + ESAA_FW_FATAL_HA_TOO_MANY_PROCESS, + ESAA_FW_FATAL_HA_UPLINK_MAILBOX_FULL, + /* fatal error into periph module */ + ESAA_FW_FATAL_PDT_BAD_BIRTH_CMD = ESAA_FW_ERROR_LEVEL_FATAL + 0x20, + ESAA_FW_FATAL_PDT_SHM_UNDERFLOW_MGT, + ESAA_FW_FATAL_PDT_DMA_SLOWMODE_DISABLE, + /* error into aep module */ + ESAA_FW_FATAL_AEP_CHECK_INPUT = ESAA_FW_ERROR_LEVEL_FATAL + 0x30, + ESAA_FW_FATAL_AEP_CHECK_OUTPUT, + ESAA_FW_FATAL_AEP_WRITE_OUTPUT, + ESAA_FW_FATAL_AEP_FIFO_DATA, + ESAA_FW_FATAL_AEP_DELETE_POSITION, + ESAA_FW_FATAL_AEP_FREE_PACKET, + /* error into rtil/fe module */ + ESAA_FW_FATAL_FE_BAD_BIRTH_CMD = ESAA_FW_ERROR_LEVEL_FATAL + 0x40, + ESAA_FW_FATAL_FE_FIFO_DATA_BAD_PARAM, + ESAA_FW_FATAL_FE_BAD_DESCRIPTION, + ESAA_FW_FATAL_FE_TOO_MANY_SAMPLES, + ESAA_FW_FATAL_FE_TOO_MANY_BITS, + ESAA_FW_FATAL_FE_LOST_MSG, + ESAA_FW_FATAL_FE_CODEC_ERROR, + /* stack oveflow */ + ESAA_FW_FATAL_STACK_OVERFLOW = ESAA_FW_ERROR_LEVEL_FATAL + 0x50 // +} t_saa_fw_error_type; + +// Firmware zone +/****************************************************************/ +typedef struct +{ + int idV; + int idBUILD; + int ram_size; + int mips; + int nb_idS; + int tab_service_available[ESAA_CODEC_LAST_IN_LIST]; +} HA_FIRMWARE_ZONE_T; + +/***************************************************/ +// Struct of params of message between HCL and DSP. +/***************************************************/ + +/*****************************************/ +// Answer and Alert +/*****************************************/ + +/* create block answer */ +typedef struct +{ + t_uint16 error_type; // range is enum t_saa_fw_error + t_uint16 block_id; +} t_saa_ans_create_block; + +/* delete block answer */ +typedef struct +{ + t_uint16 error_type; // range is enum t_saa_fw_error +} t_saa_ans_delete_block; + +/* create port answer */ +typedef struct +{ + t_uint16 error_type; // range is enum t_saa_fw_error + t_uint16 port_id; +} t_saa_ans_create_port; + +/* delete port answer */ +typedef struct +{ + t_uint16 error_type; // range is enum t_saa_fw_error +} t_saa_ans_delete_port; + +/* freeze block answer */ +typedef struct +{ + t_uint16 error_type; // range is enum t_saa_fw_error +} t_saa_ans_freeze_block; + +/* connect port answer */ +typedef struct +{ + t_uint16 error_type; // range is enum t_saa_fw_error +} t_saa_ans_connect_port; + +/* disconnect port answer */ +typedef struct +{ + t_uint16 error_type; // range is enum t_saa_fw_error +} t_saa_ans_disconnect_port; + +/* update network answer */ +typedef struct +{ + t_uint16 error_type; // range is enum t_saa_fw_error +} t_saa_ans_update_network; + +/* dma config answer */ +typedef struct +{ + t_uint16 error_type; // range is enum t_saa_fw_error + t_uint16 channel_id; + t_uint16 buffer_add_msb; + t_uint16 buffer_add_lsb; + t_uint16 av_zone_add_msb; + t_uint16 av_zone_add_lsb; + t_uint16 buffer_size; +} t_saa_ans_dma_config; + +/* codec config answer */ +typedef struct +{ + t_uint16 error_type; + t_uint16 av_zone_add_msb; + t_uint16 av_zone_add_lsb; +} t_saa_ans_codec_config; + +/* shm config answer */ +typedef struct +{ + t_uint16 error_type; // range is enum t_saa_fw_error + t_uint16 buffer1_add_msb; + t_uint16 buffer1_add_lsb; + t_uint16 buffer2_add_msb; + t_uint16 buffer2_add_lsb; + t_uint16 nb_buffer; + t_uint16 memory_bank; + t_uint16 av_zone_add_msb; + t_uint16 av_zone_add_lsb; +} t_saa_ans_shm_config; + +/* flow control answer */ +typedef struct +{ + t_uint16 error_type; // range is enum t_saa_fw_error +} t_saa_ans_flow_control; // Apply to all flow commands: PAUSE/UNPAUSE/PLAY/STOP/SET_EOF + +/* codec info answer */ +typedef struct +{ + t_uint16 error_type; // range is enum t_saa_fw_error + t_saa_codec_info codec_info; +} t_saa_ans_codec_info; + +/* HSI reset answer */ +typedef struct +{ t_uint16 error_type; // range is enum t_saa_fw_error +} t_saa_ans_reset_hsi; + +/* HSI Config port answer */ +typedef struct +{ t_uint16 error_type; // range is enum t_saa_fw_error + t_uint16 dma_channel_id; + t_uint16 buffer_size; + t_uint16 buffer_add_msb; + t_uint16 buffer_add_lsb; + t_uint16 av_zone_add_msb; + t_uint16 av_zone_add_lsb; + t_uint16 port_id; + t_uint16 burst_size; +} t_saa_ans_config_port_hsi; + +/* server info answer */ +typedef struct +{ t_uint16 error_type; // range is enum t_saa_fw_error + t_uint16 x_free; + t_uint16 y_free; + t_uint16 e16_free; + t_uint16 e24_free; + t_uint16 cpu_free; + t_uint16 x_avail; + t_uint16 y_avail; + t_uint16 e16_avail; + t_uint16 e24_avail; + t_uint16 cpu_avail; +} t_saa_ans_server_info; + +/* AEP config answer */ +typedef struct +{ t_uint16 error_type; // range is enum t_saa_fw_error +} t_saa_ans_aep_init; + +/* AEP create component answer */ +typedef struct +{ t_uint16 error_type; // range is enum t_saa_fw_error + t_uint16 effect_id; + t_uint16 param_add_msb; + t_uint16 param_add_lsb; + t_uint16 av_zone_add_msb; // av zone only for splitter + t_uint16 av_zone_add_lsb; + t_uint16 param_size; +} t_saa_ans_create_component; + +/* AEP delete component answer */ +typedef struct +{ t_uint16 error_type; // range is enum t_saa_fw_error +} t_saa_ans_delete_component; + +/* AEP connect component answer */ +typedef struct +{ t_uint16 error_type; // range is enum t_saa_fw_error +} t_saa_ans_connect_component; + +/* AEP disconnect component answer */ +typedef struct +{ t_uint16 error_type; // range is enum t_saa_fw_error +} t_saa_ans_disconnect_component; + +/* AEP config component answer */ +typedef struct +{ t_uint16 error_type; // range is enum t_saa_fw_error + t_uint16 effect_id; +}t_saa_ans_config_component; + +/* AEP get info about component answer */ +typedef struct +{ + t_uint16 error_type; + t_saa_aep_component_info component_info; +} t_saa_ans_aepcomponent_get_info; + +/* Locate_Debug_Zone answer */ +typedef struct +{ + t_uint16 error_type; + t_uint16 add_msb; // address msb part + t_uint16 add_lsb; // address lsb part + t_uint16 size; // size +}t_saa_ans_locate_debug_zone; + +/* Get cycle estimation answer */ +typedef struct +{ + t_uint16 error_type; + t_uint16 min_msb; + t_uint16 min_mid; + t_uint16 min_lsb; + t_uint16 max_msb; + t_uint16 max_mid; + t_uint16 max_lsb; + t_uint16 avg_msb; + t_uint16 avg_mid; + t_uint16 avg_lsb; +}t_saa_ans_get_cycle_estimation; + +/* Add block cycle estimation answer */ +typedef struct +{ + t_uint16 error_type; +}t_saa_ans_add_block_cycle_estimation; + +/* Remove block cycle estimation answer */ +typedef struct +{ + t_uint16 error_type; +}t_saa_ans_remove_block_cycle_estimation; + +/* Reset cycle estimation answer */ +typedef struct +{ + t_uint16 error_type; +}t_saa_ans_reset_cycle_estimation; + +/* Get performances estimation answer */ +typedef struct +{ + t_uint16 error_type; + t_uint16 min; + t_uint16 max; + t_uint16 avg; +}t_saa_ans_perf_estimation; + +/* memory footprint answer*/ +typedef struct +{ + t_uint32 all_X; + t_uint32 all_Y; + t_uint32 all_esr24; + t_uint32 all_esr16; + t_uint32 all_ext24; + t_uint32 all_ext16; + t_uint32 biggest_X; + t_uint32 biggest_Y; + t_uint32 biggest_esr24; + t_uint32 biggest_esr16; + t_uint32 biggest_ext24; + t_uint32 biggest_ext16; +}t_saa_memory_footprint_params; + +typedef struct +{ + t_uint16 error_type; + t_uint16 add_msb; + t_uint16 add_lsb; +}t_saa_ans_get_memory_footprint; + +/* Set block priority answer */ +typedef struct +{ + t_uint16 error_type; +}t_saa_ans_set_block_priority; + +/* Activate Trace answer */ +typedef struct +{ t_uint16 error_type; // range is enum t_saa_fw_error +} t_saa_ans_enable_trace; + +/* Deactivate Trace command */ +typedef struct +{ + t_uint16 error_type; // range is enum t_saa_fw_error +} t_saa_ans_disable_trace; + +/* Wake up core answer */ +typedef struct +{ + t_uint16 error_type; // range is enum t_saa_fw_error +} t_saa_ans_hsi_wake_up_core; + +/* Use Low Power Mode answer */ +typedef struct +{ + t_uint16 error_type; // range is enum t_saa_fw_error +} t_saa_ans_hsi_use_low_power_mode; + +/* error detected alert*/ +typedef struct +{ + t_uint16 error_id; +} t_saa_alert_error_detected; + +/* dma underflow alert */ +typedef struct +{ + t_uint16 port_id; +} t_saa_alert_dma_underflow; + +/* change data format alert*/ +typedef struct +{ + t_uint16 channel_id; + t_uint16 endianess; // range is enum t_saa_endianess_type + t_uint16 sample_freq; // range is enum t_saa_sample_freq + t_uint16 channel_nb; // range is enum t_saa_sample_channel_nb + t_uint16 interleaving; // range is enum t_saa_sample_interleaving_type + t_uint16 sample_size; + t_uint16 port_id; +} t_saa_alert_change_data_format; + +/* eof reached alert */ +typedef struct +{ + t_uint16 origin; // range is t_saa_eof_origin + t_uint16 source_id; + t_uint16 source_port_id; + t_uint16 port_id; + t_uint16 file_size_high; + t_uint16 file_size_mid; + t_uint16 file_size_low; +} t_saa_alert_eof_reached; + +/* aep dtmf alert */ +typedef struct +{ + t_uint16 component_id; + t_uint16 dtmf_code; +} t_saa_alert_aep_dtmf; + +/* codec info alert */ +typedef struct +{ + t_uint16 sample_freq; + t_uint16 channel_nb; +} t_saa_alert_codec_info; + +/* SHM message */ +typedef struct +{ + t_uint16 transfer_nb; + t_uint16 buffer_add_msb; + t_uint16 buffer_add_lsb; + t_uint16 frame_size; + t_uint16 bfi; +} t_saa_shm_transfer_params; + +/* aep audio visu alert */ +typedef struct +{ + t_uint16 component_id; + t_uint16 alert_type; // range is enum t_visu_alert_type + t_uint16 add_msb; // address of data area of type t_visu_alert (MSB part) + t_uint16 add_lsb; // address of data area of type t_visu_alert (LSB part) +} t_saa_alert_aep_audio_visu; + +/* aep transducer eq alert */ +typedef struct +{ + t_uint16 component_id; + t_uint16 sample_freq; + t_uint16 chan_nb; +} t_saa_alert_aep_transducer_eq; + +/* aep WB/NB NAEC alert */ +typedef struct +{ + t_uint16 component_id; + t_uint16 alert_type; // range is enum t_wbnb_naec_alert_type + t_uint16 add_msb; // address of data area of type t_wbnb_naec_alert (MSB part) + t_uint16 add_lsb; // address of data area of type t_wbnb_naec_alert (LSB part) +} t_saa_alert_aep_wbnb_naec; + +/* hsi underflow alert */ +typedef struct +{ + t_uint16 port_id; // Port id on which underflow occurs + t_uint16 alert_type; // Underflow Alert level 1 or level 2 +} t_saa_alert_hsi_underflow; + +/* hsi overflow alert */ +typedef struct +{ + t_uint16 port_id; // Port id on which overflow occurs +} t_saa_alert_hsi_overflow; + +/* hsi burst complete alert */ +typedef struct +{ + t_uint16 port_id; +} t_saa_alert_hsi_burst_complete; + +/* hsi allow sleep mode alert */ +typedef struct +{ + t_uint16 port_id; +} t_saa_alert_hsi_allow_sleep_mode; + +/* hsi bad data format alert */ +typedef struct +{ + t_uint16 port_id; +} t_saa_alert_hsi_bad_data_format; + +/* not enough memory error */ +typedef struct +{ + t_uint16 error_type; + t_uint16 memory_bank; + t_uint16 size_requested; + t_uint16 size_available; +} t_saa_error_not_enough_memory; + + +typedef union { + t_uint16 iGenericParams[SAA_MSG_NB_PARAM]; + t_saa_ans_create_block iAnsCreateBlockParams; + t_saa_ans_delete_block iAnsDeleteBlockParams; + t_saa_ans_create_port iAnsCreatePortParams; + t_saa_ans_delete_port iAnsDeletePortParams; + t_saa_ans_freeze_block iAnsFreezeBlockParams; + t_saa_ans_connect_port iAnsConnectPortParams; + t_saa_ans_disconnect_port iAnsDisconnectPortParams; + t_saa_ans_update_network iAnsUpdateNetworkParams; + t_saa_ans_dma_config iAnsDmaConfigParams; + t_saa_ans_codec_config iAnsCodecConfigParams; + t_saa_ans_shm_config iAnsShmConfigParams; + t_saa_ans_flow_control iAnsFlowControlParams; + t_saa_ans_codec_info iAnsCodecInfoParams; + t_saa_ans_reset_hsi iAnsResetHsiParams; + t_saa_ans_config_port_hsi iAnsConfigPortHsiParams; + t_saa_ans_hsi_wake_up_core iAnsHsiWakeUpCore; + t_saa_ans_hsi_use_low_power_mode iAnsHsiUseLowPowerMode; + t_saa_ans_server_info iAnsServerInfoParams; + t_saa_ans_aep_init iAnsAepInitParams; + t_saa_ans_create_component iAnsCreateComponentParams; + t_saa_ans_delete_component iAnsDeleteComponentParams; + t_saa_ans_connect_component iAnsConnectComponentParams; + t_saa_ans_disconnect_component iAnsDisconnectComponentParams; + t_saa_ans_config_component iAnsConfigComponentParams; + t_saa_ans_locate_debug_zone iAnsLocateDebugZoneParams; + t_saa_ans_get_cycle_estimation iAnsGetCycleEstimationParams; + t_saa_ans_add_block_cycle_estimation iAnsAddBlockCycleEstimationParams; + t_saa_ans_remove_block_cycle_estimation iAnsRemoveBlockCycleEstimationParams; + t_saa_ans_reset_cycle_estimation iAnsResetCycleEstimationParams; + t_saa_ans_set_block_priority iAnsSetBlockPriorityParams; + t_saa_ans_enable_trace iAnsEnableTraceParams; + t_saa_ans_disable_trace iAnsDisableTraceParams; + t_saa_alert_eof_reached iAlertEofReachedParams; + t_saa_alert_error_detected iAlertErrorDetectedParams; + t_saa_alert_dma_underflow iAlertDmaUnderflowParams; + t_saa_alert_hsi_underflow iAlertHsiUnderflowParams; + t_saa_alert_hsi_overflow iAlertHsiOverflowParams; + t_saa_alert_hsi_burst_complete iAlertHsiBurstComplete; + t_saa_alert_hsi_allow_sleep_mode iAlertHsiAllowSleepMode; + t_saa_alert_hsi_bad_data_format iAlertHsiBadDataFormat; + t_saa_alert_change_data_format iAlertChangeDataFormatParams; + t_saa_alert_aep_dtmf iAlertAepDtmfParams; + t_saa_alert_codec_info iAlertCodecInfoParams; + t_saa_shm_transfer_params iAlertShmBufferReadyParams; + t_saa_shm_transfer_params iAlertShmBufferReleasedParams; + t_saa_alert_aep_audio_visu iAlertAepAudioVisuParams; + t_saa_alert_aep_transducer_eq iAlertAepTransducerEqParams; + t_saa_alert_aep_wbnb_naec iAlertAepWbnbnaecParams; + t_saa_ans_get_memory_footprint iAnsGetMemoryFootprintParams; + t_saa_ans_aepcomponent_get_info iAnsAepComponentGetInfoParams; + t_saa_ans_perf_estimation iAnsPerfEstimationParams; + + t_saa_error_not_enough_memory iErrNotEnoughMemoryParams; + +} t_saa_event_params; + +typedef struct { + t_uint16 cmd_nb; + t_uint16 server_id; + t_uint16 alert_id; // range is t_saa_alert_id + t_saa_event_params params; +} t_saa_event_map; + +#endif // _ha_api_params_h_ --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/ha_codec_info.h @@ -0,0 +1,204 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ + +// Note that t_uint16 type must be define by the user of this file as a 16 bit long type. + +#ifndef _ha_codec_info_h_ +#define _ha_codec_info_h_ +//---------------------------------------------------------------------- + + +/* aac dec */ +typedef struct { + t_uint16 bitrate; // Not available yet + t_uint16 tns; // Always set to 1 + t_uint16 objectType; /* LC/LTP */ + t_uint16 bsac_on; /* don't use simultaneously sbr=1 and bsac_on=1 */ + t_uint16 sbr; +} t_dec_aac_info; + + + + +//---------------------------------------------------------------------- + +/* aac encoder*/ +typedef struct { + t_uint16 bitrate; + t_uint16 tns; + t_uint16 bandwidth; +} t_enc_aac_info; + + + +//---------------------------------------------------------------------- +typedef struct { + t_uint16 bitrate; +} t_dec_amr_info; + +/* amr enc */ +typedef struct { + t_uint16 bitrate; +} t_enc_amr_info; + + +//---------------------------------------------------------------------- + +/* amr-wb dec */ +typedef struct { + t_uint16 bitrate; +} t_dec_amrwb_info; + +/* amr-wb enc */ +typedef struct { + t_uint16 bitrate; +} t_enc_amrwb_info; + + +//---------------------------------------------------------------------- +typedef struct { + t_uint16 bitrate; +} t_dec_awp_info; + +/* amr enc */ +typedef struct { + t_uint16 bitrate; +} t_enc_awp_info; + + + + +//---------------------------------------------------------------------- + +/* G711 dec */ +typedef struct { + t_uint16 reserved; +} t_dec_g711_info; + +/* G711 enc */ +typedef struct { + t_uint16 reserved; +} t_enc_g711_info; + + +//---------------------------------------------------------------------- +/* + =========================================================================== + File: CIL_G722_FTRD_INFO.H v.1.0 - .Nov.2007 + =========================================================================== + + + CIL Information + + + Copyright (C) France Telecom 2007 History: + .Nov.07 v1.0 Creation. C. TERRIEN + ============================================================================ +*/ + + + +/* G722_FTRD decoder */ +typedef struct +{ + t_uint16 bitrate; /* Bitrate in Kbit/s. Possible value : + 48, 56 and 64. */ +} t_dec_G722_FTRD_info; + + + +/* G722_FTRD encoder */ +typedef struct +{ + t_uint16 bitrate; +} t_enc_G722_FTRD_info; + + + + +//---------------------------------------------------------------------- + +/* G729 dec*/ +typedef struct { + t_uint16 bitrate; +} t_dec_g729_info; + +/* G729 enc*/ +typedef struct { + t_uint16 bitrate; +} t_enc_g729_info; + + +//---------------------------------------------------------------------- + +/* iLBC dec */ +typedef struct { + t_uint16 use_enhancer; + t_uint16 sample_frame_size; +} t_dec_iLBC_info; + +/* iLBC enc */ +typedef struct { + t_uint16 sample_frame_size; +} t_enc_iLBC_info; + + +//---------------------------------------------------------------------- + +/* mp3 decoder */ +typedef struct { + t_uint16 bitrate; +} t_dec_mp3_info; + + +//---------------------------------------------------------------------- +/* sbc encoder */ +typedef struct { + t_uint16 nb_blocks; // STATIC, values 4,8,12,16 blocks, default 16 + t_uint16 nb_subbands; // STATIC, values 4,8 subbands, default 8 + t_uint16 bitpool; // DYNAMIC, range [1,255], default 35 + t_uint16 nb_channels_out;// STATIC, values 0(mono), 1(dual-mono), 2(stereo), 3(joint) +} t_enc_sbc_info; + + + + + +typedef union { + t_dec_aac_info iAacDecParams; + t_enc_aac_info iAacEncParams; + t_dec_amr_info iAmrDecParams; + t_enc_amr_info iAmrEncParams; + t_dec_amrwb_info iAmrwbDecParams; + t_enc_amrwb_info iAmrwbEncParams; + t_dec_awp_info iAwpDecParams; + t_enc_awp_info iAwpEncParams; + t_dec_g711_info iG711DecParams; + t_enc_g711_info iG711EncParams; + t_dec_G722_FTRD_info iG722FTRDDecParams; + t_enc_G722_FTRD_info iG722FTRDEncParams; + t_dec_g729_info iG729DecParams; + t_enc_g729_info iG729EncParams; + t_dec_iLBC_info iILBCDecParams; + t_enc_iLBC_info iILBCEncParams; + t_dec_mp3_info iMp3DecParams; + t_enc_sbc_info iSbcEncParams; +} t_saa_codec_info; + +#endif // _ha_codec_info_h_ --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/ha_codec_params.h @@ -0,0 +1,686 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ + +// Note that t_uint16 type must be define by the user of this file as a 16 bit long type. + +#ifndef _ha_codec_params_h_ +#define _ha_codec_params_h_ +//---------------------------------------------------------------------- + + +/* aac dec */ +typedef struct { + t_uint16 iSyntax; // STATIC range 0(ADTS),1(ADIF),2(RAW),3(RAW_STREAMING), 4(AutoDetect ADIF or ADTS), 5(AutoDetect ADIF/ADTS/RAW) ( default 0(ADTS) ) + t_uint16 iObjectType; // STATIC: values 2(LC),4(LTP), default 2(LC) - Value 1(Main) is not supported. However the Bit 7 may be used to force Main Profile as LC (value 0x81) - autodetection in case of Autodetect Syntax + t_uint16 iFrequency; // STATIC: 8->96kHz (t_saa_sample_freq enumeration) - autodetection in case of ADIF/ADTS, anyway initialization must reach authorized range of values!! + //t_uint16 iMaxInputChannels; // STATIC range [1,6], default 2(stereo) - NOT USED + t_uint16 iMemoryPreset; // STATIC + // 0(MEM_DEFAULT) 1(MEM_ALL_DDR) 2(MEM_ALL_TCM) + // 8(MEM_ALL_ESRAM) 9(MEM_MIX_ESRAM_DDR) 11(MEM_MIX_ESRAM_OTHER_1) +// t_uint16 iMaxBlocksPerFrame; STATIC (needed for ADTS syntax only) range [1,4], default 1 - NOT USED + t_uint16 icrc_ignore; // STATIC default 1 crc errors are ignored instead of muting the output + t_uint16 iDownSample; // STATIC range [0,1], default 0, down_sample (decimate by 2) if needed for freqs > 48kHz + t_uint16 iEnableSBR; // STATIC range [0,1,2,3] + // --------------------------------------------------------------------------------------- + // 0(default)=sbr not decoded with fs_out=fs_aac_core if iDownSample=0 + // else fs_out=fs_aac_core/2 if iDownSample=1; + // --------------------------------------------------------------------------------------- + // 1=sbr decoded with fs_out=2*fs_aac_core if iDownSample=0 else 1*fs_aac_core if + // iDownSample=1 + // --------------------------------------------------------------------------------------- + // 2=same as 0 above + // --------------------------------------------------------------------------------------- + // 3=sbr decoded with fs_out=2*fs_aac_core only if (fs_aac_core<=24kHz and iDownSample ==0) + // --------------------------------------------------------------------------------------- + t_uint16 iErrorConcealment; // STATIC values 0(off), 1(mute), 2(repeat), 3(adaptive), 4(3gpp), default 0(off) + t_uint16 ibsac_on; // STATCC rangw[0,1], default 0 + t_uint16 ibsac_nch; // STATIC (needed if bsac_on = 1) : range [1, 2] + t_uint16 ibsac_layer; // STATIC (needed if bsac_on and bsac_use_max_layer=0): range [0, 48] + t_uint16 ibsac_usemaxlayer; // STATIC (needed if bsac_on) : range [0, 1] +} t_dec_aac_params; + + +#define ESAA_AAC_MAX_BITSTREAM_SIZE_IN_BIT (15544) // theory is 12288 but we need to increase size to pass some corrupted stream +#define ESAA_AAC_SAMPLE_FRAME_SIZE_IN_WORD 1024*2 +#define ESAA_EAACPLUS_SAMPLE_FRAME_SIZE_IN_WORD 2048*2 + + +//---------------------------------------------------------------------- + +/* aac encoder*/ +typedef struct { + //status + t_uint16 iBitRateMsb; // STATIC literal value, default is 128000 bit/s (0x1 <<16 | 0xF400) + t_uint16 iBitRateLsb; // STATIC bitrate is iBitRate_msb<<16|iBitRate_lsb + t_uint16 iFrequency; // STATIC, 8-> 48 kHz, (t_saa_sample_freq enumeration) + t_uint16 iNbChannelsIn; // STATIC range [1,2] default 2; + t_uint16 iNbChannelsOut; // STATIC range [1,2]default 2; + t_uint16 iBandWidth; // STATIC range [0, 20000] default 0 + t_uint16 iUseTns; // STATIC range [0,1] if 0:tns masked (default 1) + t_uint16 iUseAdts; // STATIC range [0,1] default 1 + t_uint16 iDualMono; // STATIC range [0,1] default 0 + t_uint16 iCalcCrc; // STATIC range [0,1] default 0 + t_uint16 iCopyright_Original;// static range [0,1] default 0, Copyright and Original bytes share the same word + // |xxxxxxxC|xxxxxxxO| msbyte=Copyright lsbyte=Original + t_uint16 iMemoryPreset; // STATIC 0(MEM_DEFAULT=ALL_TCM) 1(MEM_ALL_DDR) 3 (MEM_MIX_DDR_TCM_1) + // 8(MEM_ALL_ESRAM) 9(MEM_MIX_ESRAM_DDR) 11(MEM_MIX_ESRAM_OTHER_1) + +} t_enc_aac_params; + +#define ESAA_AAC_ENC_MAX_BITSTREAM_SIZE_IN_BIT (12288) +#define ESAA_AAC_ENC_SAMPLE_FRAME_SIZE_IN_WORD 1024*2 + + +//---------------------------------------------------------------------- + + +/* amr dec */ +typedef struct { + t_uint16 iNoHeader; // STATIC, range [0,1], default 0, magic number present in bitstream + t_uint16 iErrorConcealment; // STATIC, range [0,1] default is 0 (off) + t_uint16 iMemoryPreset; // STATIC + // 0(MEM_DEFAULT) 1(MEM_ALL_DDR) 2(MEM_ALL_TCM) + // 8(MEM_ALL_ESRAM) 3(MEM_MIX_DDR_TCM_1) 11(MEM_MIX_ESRAM_OTHER_1) + t_uint16 iPayloadFormat; // STATIC, range [0,1]: 0 (rfc3267), 1 (IF2) - Default 0 +} t_dec_amr_params; + +/* amr enc */ +typedef struct { + t_uint16 iRateEnum; // DYNAMIC, range [0,7], default 7 (12.2kb/s) + t_uint16 iDtxEnable; // DYNAMIC, range [0,1], default 1, dtx active + t_uint16 iNoHeader; // STATIC, range [0,1], default 0, magic number present + t_uint16 iMemoryPreset; // STATIC + // 0(MEM_DEFAULT) 1(MEM_ALL_DDR) 2(MEM_ALL_TCM) + // 8(MEM_ALL_ESRAM) 3(MEM_MIX_DDR_TCM_1) 11(MEM_MIX_ESRAM_OTHER_1) + t_uint16 iPayloadFormat; // STATIC, range [0,1]: 0 (rfc3267), 1 (IF2) - Default 0 +} t_enc_amr_params; + + +#define ESAA_AMR_MAX_BITSTREAM_SIZE_IN_BIT (304) // 48 bits magic number + 8bit header + 248 bits +#define ESAA_AMR_SAMPLE_FRAME_SIZE_IN_WORD 160 + + +//---------------------------------------------------------------------- + +/* amr-wb dec */ +typedef struct { + t_uint16 iNoHeader; // STATIC, range [0,1], default 0, magic number present + t_uint16 iMemoryPreset; // STATIC, + // 0(MEM_DEFAULT=MEM_ALL_TCM) 1(MEM_ALL_DDR) 2(MEM_ALL_TCM) 3(MEM_MIX_DDR_TCM_1) 8(MEM_ALL_ESRAM) 11(MEM_MIX_ESRAM_OTHER_1) + t_uint16 iErrorConcealment; // STATIC, range [0,1] default is 0 (off) +} t_dec_amrwb_params; + +/* amr-wb enc */ +typedef struct { + t_uint16 iRateEnum; // DYNAMIC, range [0,9], default 8 (23.85kb/s) + t_uint16 iDtxEnable; // DYNAMIC, range [0,1], default 1, dtx active + t_uint16 iNoHeader; // STATIC, range [0,1], default 0, magic number present + t_uint16 iMemoryPreset; // STATIC, + // 0(MEM_DEFAULT=MEM_ALL_TCM) 1(MEM_ALL_DDR) 2(MEM_ALL_TCM) 3(MEM_MIX_DDR_TCM_1) 8(MEM_ALL_ESRAM) 11(MEM_MIX_ESRAM_OTHER_1) +} t_enc_amrwb_params; + + +#define ESAA_AMRWB_MAX_FRAME_SIZE_IN_BIT (560) // 72 bits magic number + 8bit header + 480 bits +#define ESAA_AMRWB_SAMPLE_FRAME_SIZE_IN_WORD 320 + + +//---------------------------------------------------------------------- + +/* amrwb+ dec */ +typedef struct { + t_uint16 iSamplingRate; //STATIC, default: 48KHz, values: 8, 16, 24, 32, 44.1, 48 kHz (t_saa_sample_freq enumeration) + t_uint16 iMono; //STATIC, default: 0; range: [0(stereo), 1(mono)] + t_uint16 iLimiter; //STATIC, default: 1; range: [0(off), 1(on)] + t_uint16 imemory_preset;// STATIC, default 0(MEM_DEFAULT=MEM_ALL_DDR), 3(MEM_MIX_DDR_TCM_1), 11(MEM_MIX_ESRAM_OTHER_1), 12(MEM_MIX_ESRAM_OTHER_2) + t_uint16 iErrorConcealment; //STATIC default: 0; range: [0(off), 1(on)] +} t_dec_awp_params; + +/* amrwb+ enc */ +typedef struct { + t_uint16 iMono; //static, default 0 + t_uint16 iEnableLC; //static ,default 0 + t_uint16 iRate; //static, default -1 + t_uint16 iAllowDtx; //static, default 0 + t_uint16 iSamplingRate; //static, Sampling Rate range [8khz....48khz] + t_uint16 iISF; //dynamic, default: 1.0; range: [0.5, 1.5] + t_uint16 iModeIndex; //dynamic, range: [0, 47] + t_uint16 iExtension; // dynamic, default 1, This is to set AMRWB+ or AMR-WB mode + t_uint16 imemory_preset;// STATIC, default 0(MEM_DEFAULT=MEM_MIX_DDR_TCM_1), 3(MEM_MIX_DDR_TCM_1), 11(MEM_MIX_ESRAM_OTHER_1), 12(MEM_MIX_ESRAM_OTHER_2) +} t_enc_awp_params; + +#define ESAA_AWP_ENC_MAX_BITSTREAM_SIZE_IN_BIT (3840+64) // define the buffer size at 32kbps i.e maximum output size and 64 bit header per frame +#define ESAA_AWP_ENC_SAMPLE_FRAME_SIZE_IN_WORD 7680*2 +#define ESAA_AWP_DEC_MAX_FRAME_SIZE_IN_BIT (3840*16) +#define ESAA_AWP_DEC_SAMPLE_FRAME_SIZE_IN_WORD 7680*2 + + +//---------------------------------------------------------------------- + + + +/* eaac+ encoder*/ +typedef struct { + t_uint16 iSampleRate; // STATIC default 48KHz + t_uint16 iBitRateMsb; // STATIC literal value, default is 128000 bit/s (0x1 <<16 | 0xF400) + t_uint16 iBitRateLsb; // STATIC bitrate is iBitRate_msb<<16|iBitRate_lsb + t_uint16 iNbChannelsIn; // STATIC range [1,2] default 2 + t_uint16 iMode; // STATIC stereo or mono + t_uint16 iSbrenable; // STATIC range [0,1] default 1 + t_uint16 iBandWidth; // STATIC range [0, 20000] default 0 + t_uint16 iUseAdts; // STATIC range [0,1] default 0 + t_uint16 iUseCrc; // STATIC range [0,1] default 0 + t_uint16 iCopyright; // static range [0,1] default 0 + t_uint16 iOriginal; // static range [0,1] default 0 + t_uint16 iQuality; // STATIC range [0, 1, 2] default 0 + t_uint16 iMemoryPreset; // not yet implemented +} t_enc_eaac_plus_params; + +#define ESAA_AAC_ENC_MAX_BITSTREAM_SIZE_IN_BIT (12288) // 15544 // theory is 12288 but we need to increase size to pass some corrupted stream +#define ESAA_AAC_SAMPLE_FRAME_SIZE_IN_WORD 1024*2 +#define ESAA_EAACPLUS_SAMPLE_FRAME_SIZE_IN_WORD 2048*2 + + +//---------------------------------------------------------------------- + +/* EVRC */ +typedef struct { + t_uint16 iPostFilter; // STATIC, apply or not post filter / range [0,1] / default 1 + t_uint16 iErrorConcealment; // STATIC, range [0(off),1(on)] default is 0 (off) + t_uint16 iMemoryPreset; // STATIC, default 0(MEM_DEFAULT=MEM_ALL_DDR),1(MEM_ALL_DDR), 2(MEM_ALL_TCM), 8(MEM_ALL_ESRAM), 9(MEM_MIX_ESRAM_DDR), 10(MEM_MIX_ESRAM_TCM) +} t_dec_evrc_params; + +typedef struct { + t_uint16 iNoiseSuppression; // STATIC 1 (enable), 0 (disable) (default 1) + t_uint16 iMaxRate; // STATIC, 1 (eighth), 3 (half) or 4 (full) (default 4) + t_uint16 iMinRate; // STATIC, 1 (eighth), 3 (half) or 4 (full) (default 1) + t_uint16 iMemoryPreset; // implemented +} t_enc_evrc_params; + +#define ESAA_EVRC_MAX_BITSTREAM_SIZE_IN_BIT (192) +#define ESAA_EVRC_SAMPLE_FRAME_SIZE_IN_WORD 160 + + +//---------------------------------------------------------------------- + +/* G711 dec */ +typedef struct { + t_uint16 iMode; // STATIC, 0-> A-Law, 1-> mu-Law, default A-Law + t_uint16 iErrorConcealment; // STATIC, range [0,1] default is 0 (off) + t_uint16 iMemoryPreset; + // STATIC 0(MEM_DEFAULT) 1(MEM_ALL_DDR) 2(MEM_ALL_TCM) 8(MEM_ALL_ESRAM) 9(MEM_MIX_ESRAM_DDR) 11(MEM_MIX_ESRAM_OTHER_1) + t_uint16 ileng; // STATIC number of samples per frame default is 80. 160 and 240 are the other possibilities + t_uint16 iPayloadFormat; //STATIC 0 coded files have 2-byte S60 header 1 coded files have no header +} t_dec_g711_params; + +/* G711 enc */ +typedef struct { + t_uint16 iMode; // STATIC, 0-> A-Law, 1-> mu-Law, default A-Law + t_uint16 iDtxEnable; // STATIC, enables DTX (default 0) + t_uint16 iMemoryPreset; + // STATIC 0(MEM_DEFAULT) 1(MEM_ALL_DDR) 2(MEM_ALL_TCM) 8(MEM_ALL_ESRAM) 9(MEM_MIX_ESRAM_DDR) 11(MEM_MIX_ESRAM_OTHER_1) + t_uint16 ileng; // STATIC number of samples per frame default is 80. 160 and 240 are the other possibilities + t_uint16 iPayloadFormat; //STATIC 0 coded files have 2-byte S60 header 1 coded files have no header +} t_enc_g711_params; + +#define ESAA_G711_MAX_BITSTREAM_SIZE_IN_BIT (242*8) +#define ESAA_G711_SAMPLE_FRAME_SIZE_IN_WORD 160 + + +//---------------------------------------------------------------------- + + +/* G722 dec */ +typedef struct { + t_uint16 iMode; // STATIC, (1->64kbps, 2->56kbps or 3->48kbps), default 3. + t_uint16 iErrorConcealment; // STATIC, (0->OFF, 1->ON), default is 0 (off) + t_uint16 iPackBit; // STATIC, (0->OFF, 1->ON), default 0 concatenate 7 bit for iMode=2 and 6 bit for iMode=3. + t_uint16 iMemoryPreset; // STATIC, (0 TCM/DDR,1 DDR, 2 TCM, 8 ESRAM, 9 DDR/ESRAM, 11 TCM/ESRAM), default 0 + t_uint16 ileng; // STATIC, (160->10ms, 320->20ms), default number of samples per frame is 160. + t_uint16 iPayloadFormat; // STATIC, (0->OFF, 1->ON), default is 0 (off) +} t_dec_g722_params; + +/* G722 enc */ +typedef struct { + t_uint16 iMode; // STATIC, (1->64kbps, 2->56kbps or 3->48kbps), default 1. + t_uint16 iDtxEnable; // STATIC, (0->OFF, 1->ON), default 0 disable DTX. + t_uint16 iPackBit; // STATIC, (0->OFF, 1->ON), default 0 concatenate 7 bit for iMode=2 and 6 bit for iMode=3. + t_uint16 iMemoryPreset; // STATIC, (0 TCM/DDR,1 DDR, 2 TCM, 8 ESRAM, 9 DDR/ESRAM, 11 TCM/ESRAM), default 0 + t_uint16 ileng; // STATIC, (160->10ms, 320->20ms), default number of samples per frame is 160. + t_uint16 iPayloadFormat; // STATIC, (0->OFF, 1->ON), default is 0 (off) +} t_enc_g722_params; + + + +#define ESAA_G722_MAX_BITSTREAM_SIZE_IN_BIT (1280) +#define ESAA_G722_SAMPLE_FRAME_SIZE_IN_WORD 160 + + +//---------------------------------------------------------------------- +/* + =========================================================================== + File: CIL_G722_FTRD_PARAMS.H v.1.0 - .Oct.2007 + =========================================================================== + + UGST/ITU-T G722 MODULE SPECIFIC AT STN8810 TARGET + + CIL parameters + + + Copyright (C) France Telecom 2007 History: + .Oct.07 v1.0 Creation. C. TERRIEN + ============================================================================ +*/ + +/* G722_FTRD dec */ +typedef struct +{ + + t_uint16 iConcealmentOn; /* DYNAMIC : enable error concealment (1) + or disable (0) */ + t_uint16 iFrameSize; /* STATIC, size of the frame after + decoding. range: [ 160 : 10 ms, + 320 : 20 ms ] */ + t_uint16 iOutBufferLength; /* STATIC, Size of output buffer, defined + by the private project. Max value: + CIL_G722_FTRD_PARAMS_SPEECH_BUFFER_MAX_SIZE + */ + t_uint16 iMemoryPreset; /* STATIC, Allocation of G722 decoder + resources. Range is + [ MEM_DEFAULT, + ALL_DDR, + ALL_TCM, + MIX_DDR_TCM_1, all in DDR except G722 + dec status and PLC + structure in TCM. + MIX_DDR_TCM_2, all in DDR except G722 + dec status structure in + TCM. + ALL_ESRAM, + MIX_ESRAM_DDR, all in DDR except G722 + dec status and PLC + structure in ESRAM. + MEM_MIX_ESRAM_TCM, all in ESRAM except + G722 dec status and + PLC structures in + TCM. + MIX_ESRAM_OTHER_1 ] all in DDR except + G722 dec status + structure in TCM and + PLC structures in + ESRAM. + */ +} t_dec_G722_FTRD_params; + + +/* G722_FTRD enc */ +typedef struct +{ + t_uint16 iFrameSize; /* DYNAMIC, size of the frame to + process. range: [ 160 : 10 ms, + 320 : 20 ms ] */ + + t_uint16 iInBufferLength; /* STATIC, Size of input buffer. Max value: + CIL_G722_FTRD_PARAMS_SPEECH_BUFFER_MAX_SIZE + */ + t_uint16 iMemoryPreset; /* STATIC, Allocation of G722 encoder + resources. Range is + [ MEM_DEFAULT, + ALL_DDR, + ALL_TCM, + MIX_DDR_TCM_1, all in DDR except G722 + enc status structures + in TCM. + ALL_ESRAM, + MIX_ESRAM_DDR, all in DDR except G722 + enc status structure + in ESRAM. + MEM_MIX_ESRAM_TCM ] all in ESRAM except + G722 enc status + structure in TCM. + */ +} t_enc_G722_FTRD_params; + + +/* Maximum of samples of the speech frame that private buffers support. + It is taken from G722_COM_MAX_INPUT_SP_BUFFER (G722_COMMON_const.h). */ +#define CIL_G722_FTRD_PARAMS_SPEECH_BUFFER_MAX_SIZE 320 + +/* Maximum of coded samples that private buffers support. + It is taken from G722_COM_MAX_BYTESTREAM_BUFFER (G722_COMMON_const.h). */ +#define CIL_G722_FTRD_PARAMS_CODED_BUFFER_MAX_SIZE \ + ( CIL_G722_FTRD_PARAMS_SPEECH_BUFFER_MAX_SIZE / 2) + + +//---------------------------------------------------------------------- + + +/* G723.1 dec */ +typedef struct { + t_uint16 iPostFilter; // STATIC, range [0,1], default 1, post_filter enabled + t_uint16 iMemoryPreset; // STATIC, Default config = ALL_DDR, available configs = ALL_DDR, ALL_TCM, ALL_ESRAM, MIX_DDR_TCM_1, MIX_ESRAM_TCM + t_uint16 iErrorConcealment; // STATIC, default 0, range [0,1] +} t_dec_g723_params; + +/* G723.1 enc */ +typedef struct { + + t_uint16 iRateEnum; // DYNAMIC, range [0,1], default 0 6.3 kb/s + t_uint16 iDtxEnable; // DYNAMIC, range [0,1], default 1, dtx active + t_uint16 iHighPassFilter; // STATIC, range [0,1], default 1, high_pass_filter enabled + t_uint16 iMemoryPreset; //// STATIC, Default config = ALL_DDR, available configs = ALL_DDR, ALL_TCM, ALL_ESRAM, MIX_DDR_TCM_1, MIX_ESRAM_TCM +} t_enc_g723_params; + +#define ESAA_G723_1_MAX_BITSTREAM_SIZE_IN_BIT (192) +#define ESAA_G723_1_SAMPLE_FRAME_SIZE_IN_WORD 240 + + +//---------------------------------------------------------------------- + + +/* G726 */ +typedef struct { + t_uint16 iMemoryPreset; //STATIC + t_uint16 iErrorConcealment; //STATIC, range [0, 1], default is 0 (off) + t_uint16 iReset; //STATIC, range [0, 1], default is 1 + t_uint16 iLaw; //STATIC, range [0, 1, 2], default 1, 0= u law, 1 = A law, 2 = Linear PCM + t_uint16 iRate; //DYNAMIC, value (2,3,4,5) corresponds to (16,24,32,40) kbps + t_uint16 iFrameSize; //STATIC, default 256 +} t_dec_g726_params; + +typedef struct { + t_uint16 iMemoryPreset; //STATIC + t_uint16 iReset; //STATIC, range [0, 1], default is 1 + t_uint16 iLaw; //STATIC, range [0, 1, 2], default 1, 0= u law, 1 = A law, 2 = Linear PCM + t_uint16 iFrameSize; //STATIC, default 256 + t_uint16 iRate; //DYNAMIC, value (2,3,4,5) corresponds to (16,24,32,40) kbps +} t_enc_g726_params; + +#define ESAA_G726_MAX_BITSTREAM_SIZE_IN_BIT 800 //(4096) //256 * 16 +#define ESAA_G726_SAMPLE_FRAME_SIZE_IN_WORD 160 + + +//---------------------------------------------------------------------- + + +/* G729 */ +typedef struct { + t_uint16 iMode; // DYNAMIC, values 0(6.4 kb/s), 1(8 kb/s), 2(11.2 kb/s) (0,2) are for AnnexI + t_uint16 iErrorConcealment; // STATIC, range [0,1] default is 0 (off) + t_uint16 iMemoryPreset; // STATIC, Default config = 0(ALL_DDR), available configs = 1(ALL_DDR), 2(ALL_TCM), 3(MIX_DDR_TCM_1), 8(ALL_ESRAM), 10(MIX_ESRAM_TCM) + t_uint16 iPayloadFormat; // STATIC, 0 (original), 1(Series 60); default = 1 +} t_dec_g729_params; + +typedef struct { + t_uint16 iRateEnum; // DYNAMIC, values 0(6.4 kb/s), 1(8 kb/s), 2(11.2 kb/s) (0,2) are for AnnexI + t_uint16 iDtxEnable; // DYNAMIC, range [0,1], default 0, dtx off + t_uint16 iMemoryPreset; // STATIC, Default config = 0(ALL_DDR), available configs = 1(ALL_DDR), 2(ALL_TCM), 3(MIX_DDR_TCM_1), 8(ALL_ESRAM), 10(MIX_ESRAM_TCM) + t_uint16 iPayloadFormat; // STATIC, 0 (original), 1(Series 60); default = 1 +} t_enc_g729_params; + +#define ESAA_G729_MAX_FRAME_SIZE_IN_BIT (1920) +#define ESAA_G729_SAMPLE_FRAME_SIZE_IN_WORD 80 + + +//---------------------------------------------------------------------- + +/* iLBC dec */ +typedef struct { + t_uint16 ileng;// STATIC frame length in msec either 20 or 30 def 30 + t_uint16 iuse_enhancer;// STATIC default 1 and 0 disables the enhancer + // The enhancement unit increases the + // perceptual quality of the reconstructed signal by reducing the + // speech-correlated noise in the voiced speech segments. + t_uint16 iconcealment_on; // STATIC 0=inactive(def) 1=active authorizes iLBC packet loss algorithm in case of bfi (bad frame indicator) coming from the application + t_uint16 iMemoryPreset; // STATIC 0(MEM_DEFAULT) 1(MEM_ALL_DDR) 2(MEM_ALL_TCM) 8(MEM_ALL_ESRAM) 9(MEM_MIX_ESRAM_DDR) 11(MEM_MIX_ESRAM_OTHER_1) +} t_dec_iLBC_params; + +/* iLBC enc */ +typedef struct { + t_uint16 ileng;// STATIC frame length in msec either 20 or 30 def 30 + t_uint16 iuse_vad; // STATIC normally 0 and 1 will enable the VAD algorithm in the encoder enabling + // possible reduced bit rates when speech is not detected, possible frame lengths + // are 50(30ms) 38(20ms) and 11(sid) or 0(DTX) bytes if VAD is enabled + t_uint16 iMemoryPreset; // STATIC 0(MEM_DEFAULT) 1(MEM_ALL_DDR) 2(MEM_ALL_TCM) 8(MEM_ALL_ESRAM) 9(MEM_MIX_ESRAM_DDR) 11(MEM_MIX_ESRAM_OTHER_1) +} t_enc_iLBC_params; + +#define ESAA_iLBC_MAX_BITSTREAM_SIZE_IN_BIT (416) +#define ESAA_iLBC_SAMPLE_FRAME_SIZE_IN_WORD 240 + + +//---------------------------------------------------------------------- + +/* IMA adpcm dec */ +typedef struct { + t_uint16 iMemoryPreset; // STATIC, Default config = 0(ALL_DDR), available configs = 1(ALL_DDR), 2(ALL_TCM), 8(ALL_ESRAM) + t_uint16 iChannels; // STATIC, 1 or 2. Default = 2. + t_uint16 iFrequency; // STATIC, (t_saa_sample_freq enumeration) + t_uint16 iNo_WavHeader; // STATIC, 0 or 1. Default = 0 + t_uint16 iBlockLength; // STATIC, Default = 504 + t_uint16 iErrorConcealment; // STATIC, default 0, range [0,1] +} t_dec_adpcm_params; + +/* IMA adpcm enc */ +typedef struct { + t_uint16 iChannels; // STATIC, 1 or 2. Default = 2. + t_uint16 iFrequency; // STATIC, (t_saa_sample_freq enumeration) + t_uint16 iMemoryPreset; // STATIC, Default config = 0(ALL_DDR), available configs = 1(ALL_DDR), 2(ALL_TCM), 8(ALL_ESRAM) + t_uint16 iWriteWavHeader; // STATIC, 0 or 1. Default = 0 +} t_enc_adpcm_params; + +#define ESAA_IMA_ADPCM_MAX_BITSTREAM_SIZE_IN_BIT (4512) +#define ESAA_IMA_ADPCM_SAMPLE_FRAME_SIZE_IN_WORD 504*2 + + +//---------------------------------------------------------------------- + + +/* mp3 encoder */ +typedef struct { + t_uint16 iPayloadFormat; // STATIC, reserved for future packet modes + t_uint16 iFrequency; // STATIC, 8-> 48 kHz, (t_saa_sample_freq enumeration) + t_uint16 iNbChannelsIn; // STATIC, range [1,2], default 2, stereo + t_uint16 iBitRateMsb; // STATIC literal value, default is 128000 bit/s (0x1 <<16 | 0xF400) + t_uint16 iBitRateLsb; // STATIC bitrate is iBitRate_msb<<16|iBitRate_lsb + t_uint16 iVbr; // STATIC range [0,1], default 0, variable bit-rate off + t_uint16 iMemoryPreset; // not yet implemented +} t_enc_mp3_params; + +#define ESAA_MPEG_MAX_BITSTREAM_SIZE_IN_BIT (13824) + +#define ESAA_MP3_MAX_BITSTREAM_SIZE_IN_BIT ESAA_MPEG_MAX_BITSTREAM_SIZE_IN_BIT +#define ESAA_MP3_SAMPLE_FRAME_SIZE_IN_WORD 576*2 + + +//---------------------------------------------------------------------- + +/* mp3 decoder */ +typedef struct { + t_uint16 iMemoryPreset; // STATIC, 0(MEM_DEFAULT=MEM_ALL_DDR), 1(MEM_ALL_DDR), 2(MEM_ALL_TCM), 9(MEM_MIX_ESRAM_DDR) + t_uint16 iErrorConcealment; // STATIC, default 0, range [0,1] +} t_dec_mp3_params; + + +#define ESAA_MPEG_MAX_BITSTREAM_SIZE_IN_BIT (13824) +#define ESAA_MP3_MAX_BITSTREAM_SIZE_IN_BIT ESAA_MPEG_MAX_BITSTREAM_SIZE_IN_BIT +#define ESAA_MP3_SAMPLE_FRAME_SIZE_IN_WORD 576*2 + + +//---------------------------------------------------------------------- + + +/* MPEG2 decoder */ +typedef struct { + t_uint16 iMode; // STATIC values 0 (MPEG) or 1 (MPEG-DAB), default 0 + t_uint16 iErrorConcealment; // STATIC values 0(off), 1(mute), default 0(off) + t_uint16 iMemoryPreset; // STATIC values = 0,1,2,3,8,10, default = 0 +} t_dec_mpeg2_params; + +#define ESAA_MPEG_MAX_BITSTREAM_SIZE_IN_BIT (13824) +#define ESAA_MPEG_DEC_SAMPLE_FRAME_SIZE_IN_WORD 384*2 +#define ESAA_MPEG_ENC_SAMPLE_FRAME_SIZE_IN_WORD 1152*2 + + +//---------------------------------------------------------------------- + +/* oggvorbis dec */ +typedef struct { + t_uint16 iMemoryPreset; /* Not yet implemented */ +} t_dec_oggvorbis_params; + + +#define ESAA_OGGVORBIS_MAX_BITSTREAM_SIZE_IN_BIT 2841*24//3000*24 +#define ESAA_OGGVORBIS_SAMPLE_FRAME_SIZE_IN_WORD 4096 +#define OGGVORBIS_DEC_SAMPLE_SIZE 16 + + +//---------------------------------------------------------------------- +/* QCELP13 */ +typedef struct { + t_uint16 iMode; + t_uint16 iErrorConcealment; //STATIC, 0=off (default), 1=on + t_uint16 iMemoryPreset; // implemented +} t_dec_qcelp13_params; + +typedef struct { + t_uint16 iMode; + t_uint16 iMemoryPreset; // implemented +} t_enc_qcelp13_params; + + +/* CDMA codecs */ +#define ESAA_QCELP_MAX_BITSTREAM_SIZE_IN_BIT (288) +#define ESAA_QCELP_SAMPLE_FRAME_SIZE_IN_WORD 160 + + + +//---------------------------------------------------------------------- + +/* sbc (no configuration needed yet for decoder) */ +typedef struct { + t_uint16 iMemoryPreset; // STATIC + // 0(MEM_DEFAULT=MEM_ALL_TCM) 1(MEM_ALL_DDR) 2(MEM_ALL_TCM) 8(MEM_ALL_ESRAM) +} t_dec_sbc_params; + +/* sbc encoder */ +typedef struct { + t_uint16 iNrOfBlocks; // STATIC, values 4,8,12,16 blocks, default 16 + t_uint16 iNrOfSubbands; // STATIC, values 4,8 subbands, default 8 + t_uint16 iFrequency; // STATIC, 16, 32,44.1, 48 kHz (t_saa_sample_freq enumeration) + t_uint16 iAllocMethod; // DYNAMIC, values 0(LOUDNESS), 1(SNR), default 0(LOUDNESS) + t_uint16 iBitpool; // DYNAMIC, range [1,255], default 35 + t_uint16 iChannelMode; // STATIC, values 0(mono), 1(dual-mono), 2(stereo) + t_uint16 iBitrateMsb; // DYNAMIC default 384 kBits/s (0x5<<16|0xDC00) + t_uint16 iBitrateLsb; // sent to firmware as msb, lsb + t_uint16 iBitrateDisable; // STATIC, range[0,1], default 1, use bitpool (1) instead of bitrate (0) + t_uint16 iMemoryPreset; // STATIC, + // 0(MEM_DEFAULT=MEM_ALL_TCM) 1(MEM_ALL_DDR) 2(MEM_ALL_TCM) 8(MEM_ALL_ESRAM) +} t_enc_sbc_params; + + +#define ESAA_SBC_MAX_BITSTREAM_SIZE_IN_BIT (525*8) +#define ESAA_SBC_MAX_SAMPLE_FRAME_SIZE_IN_WORD 16*8*2 // SBC_MAX_BLOCKS*SBC_MAX_SUBBANDS*SBC_MAX_CHANNELS; + + +//---------------------------------------------------------------------- + + + +/* ST mpeg1 encoder*/ +typedef struct { + t_uint16 iCodecVersion; //STATIC, range[0,1] corresponding to [MPEG1 LAYER1, MPEG1 LAYER2], default 1(MPEG1 LAYER2) + t_uint16 iFrequency; //STATIC, range [44100, 48000, 32000],default 44100 (t_saa_sample_freq enumeration) + t_uint16 iBitrate; /* STATIC, default: 256, values + * Layer 1: 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448 + * Layer 2: 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384 + */ + t_uint16 iChannelMode; //STATIC, range[0,3] corresponding to [stereo, joint-stereo, dual-channel, mono] , default 0(stereo) + t_uint16 iModeExtension; //DYNAMIC, range[0,3], default 0 + t_uint16 iCrcCheck; //STATIC, range[0,1] corresponding to CRC check disabled/enabled, default: 0 (disabled) + t_uint16 iMemoryPreset; //STATIC, Default = (0)MEM_DEFAULT, (2)MEM_ALL_TCM, (1)MEM_ALL_DDR,(8)MEM_ALL_ESRAM, (3)MEM_MIX_DDR_TCM_1, (10)MEM_MIX_ESRAM_TCM + +} t_enc_stmpeg_params; + +#define ESAA_MPEG_MAX_BITSTREAM_SIZE_IN_BIT (13824) +#define ESAA_MPEG_DEC_SAMPLE_FRAME_SIZE_IN_WORD 384*2 +#define ESAA_MPEG_ENC_SAMPLE_FRAME_SIZE_IN_WORD 1152*2 + + +//---------------------------------------------------------------------- + +/* WMA (configuration needed for decoder) */ +typedef struct { + t_uint16 iVersion; + t_uint16 inChannels; + t_uint16 inBlockAlign; + t_uint16 inEncodeOpt; + t_uint16 inAvgBytesPerSec; + t_uint16 inSamplesPerSec; + t_uint16 iMemoryPreset; // STATIC, Default config = 0(MIX_DDR_TCM_1) + +} t_dec_wma_params; + +#define ESAA_WMA_MAX_BITSTREAM_SIZE_IN_BIT (118888) +#define ESAA_WMA_SAMPLE_FRAME_SIZE_IN_WORD 2048*2 // initially 6144 + + + + + +typedef union { + t_uint16 iGenericParams[SAA_MSG_NB_PARAM]; + t_dec_aac_params iAacDecParams; + t_enc_aac_params iAacEncParams; + t_dec_amr_params iAmrDecParams; + t_enc_amr_params iAmrEncParams; + t_dec_amrwb_params iAmrwbDecParams; + t_enc_amrwb_params iAmrwbEncParams; + t_dec_awp_params iAwpDecParams; + t_enc_awp_params iAwpEncParams; + t_enc_eaac_plus_params iEaacPlusEncParams; + t_dec_evrc_params iEvrcDecParams; + t_enc_evrc_params iEvrcEncParams; + t_dec_g711_params iG711DecParams; + t_enc_g711_params iG711EncParams; + t_dec_g722_params iG722DecParams; + t_enc_g722_params iG722EncParams; + t_dec_G722_FTRD_params iG722FTRDDecParams; + t_enc_G722_FTRD_params iG722FTRDEncParams; + t_dec_g723_params iG723DecParams; + t_enc_g723_params iG723EncParams; + t_dec_g726_params iG726DecParams; + t_enc_g726_params iG726EncParams; + t_dec_g729_params iG729DecParams; + t_enc_g729_params iG729EncParams; + t_dec_iLBC_params iILBCDecParams; + t_enc_iLBC_params iILBCEncParams; + t_dec_adpcm_params iAdpcmDecParams; + t_enc_adpcm_params iAdpcmEncParams; + t_enc_mp3_params iMp3EncParams; + t_dec_mp3_params iMp3DecParams; + t_dec_mpeg2_params iMpeg2DecParams; + t_dec_oggvorbis_params iOggvorbisDecParams; + t_dec_qcelp13_params iQcelp13DecParams; + t_enc_qcelp13_params iQcelp13EncParams; + t_dec_sbc_params iSbcDecParams; + t_enc_sbc_params iSbcEncParams; + t_enc_stmpeg_params iStmpegEncParams; + t_dec_wma_params iWmaDecParams; +} t_saa_codec_params; + +#endif // _ha_codec_params_h_ --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/ha_effect_info.h @@ -0,0 +1,122 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ + +// Note that t_uint16 type must be define by the user of this file as a 16 bit long type. + +#ifndef _ha_effect_info_h_ +#define _ha_effect_info_h_ +//---------------------------------------------------------------------- + +/* ST 3D POSITIONING */ +typedef struct{ + t_uint16 nb_inputs; /* Number of virtual source to processed */ + t_uint16 speaker_headphone_mode; /* SPEAKER : 1, HEADPHONE : 2 */ +} t_aep_st3d_info; + + +//---------------------------------------------------------------------- + + +/* TYPE2 HD3D */ +typedef struct{ + t_uint16 nb_inputs; /* Number of virtual source to processed */ + t_uint16 speaker_headphone_mode; /* SPEAKER : 1, HEADPHONE : 2 */ +} t_aep_type2_lib_HD3D_info; + + + +//---------------------------------------------------------------------- + +/* TYPE2 MDRC_eX */ +typedef struct{ + t_uint16 nb_bands; /* Number EQ's band */ + t_uint16 by_pass; /* Used to bypass(1) or processed the effect(0) */ + t_uint16 by_pass_limiter; /* Bypass boolean */ +} t_aep_type2_lib_MDRC_eX_info; + + +//---------------------------------------------------------------------- + +/* AUDIO VISUALISATION */ +typedef struct +{ + t_uint16 nb_channel_out; /* Number of output channels, range is enum t_visu_nb_chan_out, default : visu_mono */ + t_uint16 ifreq_data; /* 0 : OFF, 1 : ON, default 0, visualisation of frequencial data */ + t_uint16 ienable; /* 0 : DISABLED, 1 : ENABLED, default 0 */ +} t_aep_audiovisualization_info; + + +//---------------------------------------------------------------------- + +/* EQUALIZER */ +typedef struct { + t_uint16 i_nb_bands; /* always 8 bands, hard coded */ +}t_aep_equalizer_info; + + +//---------------------------------------------------------------------- + +/* MIXER */ +typedef struct { + t_uint16 nb_inputs; /* 1 to 4 */ +} t_aep_mixer_info; + + +//---------------------------------------------------------------------- +/* SAMPLE RATE CONVERTER */ +typedef struct{ + t_uint16 freq_out; /* range is enum t_saa_sample_freq */ + t_uint16 low_complexity_to_out48; /* 0 : standard SRC, 1: special low mips mode is used */ +} t_aep_samplerateconv_info; + + + +//---------------------------------------------------------------------- + +/* SPLITTER */ +typedef struct{ + t_uint16 nb_outputs; /* 1 to 4 */ +} t_aep_splitter_info; + + +//---------------------------------------------------------------------- + +/* VOLUME CONTROL */ +typedef struct { + t_uint16 nb_gains; /* 1 to 4 */ + t_uint16 downmix; /* stereo to dual mono */ +} t_aep_volctrl_info; + + + + + +typedef union { + t_aep_st3d_info iSt3dParams; + t_aep_type2_lib_HD3D_info iType2LibHD3DParams; + t_aep_type2_lib_MDRC_eX_info iType2LibMDRCEXParams; + t_aep_audiovisualization_info iAudiovisualizationParams; + t_aep_equalizer_info iEqualizerParams; + t_aep_mixer_info iMixerParams; + t_aep_samplerateconv_info iSamplerateconvParams; + t_aep_splitter_info iSplitterParams; + t_aep_volctrl_info iVolctrlParams; +} t_saa_aep_component_info; + +#endif // _ha_effect_info_h_ --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/ha_effect_params.h @@ -0,0 +1,1342 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ + +// Note that t_uint16 type must be define by the user of this file as a 16 bit long type. + +#ifndef _ha_effect_params_h_ +#define _ha_effect_params_h_ +//---------------------------------------------------------------------- + + +typedef struct { + t_uint16 iMemoryPreset; + t_uint16 iDelay3DLength; + t_uint16 iDelayReverbLength; +}t_aep_st3d_static_params; + + +typedef struct { +t_uint16 iStereoMono; +t_uint16 iDelay3DEnable; +t_uint16 iDelayReverbEnable; +t_uint16 iSpeakerHeadphoneMode; +t_uint16 iReverbOutputEnable; +}t_aep_st3d_global_setting; + +typedef struct { + t_uint16 iRMin; + t_uint16 iRMax; + t_uint16 iMuteAfterMax; + t_uint16 iRolloff; + t_uint16 iReverbRolloff; +}t_aep_st3d_distance_attenuation; + +typedef struct { + t_uint16 iPortId; + t_uint16 iMute; + t_uint16 iAzimuth; + t_uint16 iElevation; + t_uint16 iDistance; +}t_aep_st3d_source_position; + +typedef union { + t_aep_st3d_global_setting iGlobalSetting; + t_aep_st3d_distance_attenuation iDistanceAttenuation; + t_aep_st3d_source_position iSourcePosition[4]; +}t_aep_st3d; + +typedef struct { + t_uint16 iParamType; + t_aep_st3d iSt3dSettings; +}t_aep_st3d_dynamic_params; + + +//---------------------------------------------------------------------- + +/************************** + * TYPE2 HD3D + ************************/ +typedef struct{ + t_uint16 iMemoryPreset; + t_uint16 idelay_3D_length; + t_uint16 idelay_reverb_length; +} t_aep_type2_lib_HD3D_static_params; + +typedef struct { + t_uint16 iRMin; + t_uint16 iRMax; + t_uint16 iMuteAfterMax; + t_uint16 iRolloff; + t_uint16 iReverb_Rolloff; +}t_aep_Distance_Attenuation; + +typedef struct { + t_uint16 iPortId; + t_uint16 iMute; + t_uint16 iAzimuth; + short iElevation; + t_uint16 iDistance; +}t_aep_Source_Position; + +typedef struct { + t_uint16 imono_stereo; + t_uint16 idelay_3D_enable; + t_uint16 idelay_reverb_enable; + t_uint16 ispeakers_headphones_mode; + t_uint16 ireverb_output_enable; +}t_aep_Global_Setting; + +typedef union { + t_aep_Global_Setting Global_Setting; // ParamType = 0 + t_aep_Distance_Attenuation Distance_Attenuation; // ParamType = 1 + t_aep_Source_Position Source_Position[4]; // ParamType = 2 +}t_aep_HD3D; + +typedef struct { + t_uint16 iParamType; // DistanceAttenuation or Source_Position + t_aep_HD3D iHD3D_settings; +}t_aep_type2_lib_HD3D_dynamic_params; + + +//---------------------------------------------------------------------- + +/****************************** + * TYPE2 HDDC_eX + *****************************/ +typedef struct{ + t_uint16 iMemoryPreset; + t_uint16 i_nb_points; // Compression Points = [2,5] +} t_aep_type2_lib_HDDC_eX_static_params; + + +typedef struct { + short ithreshold_in; + short ithreshold_out; + short islope1; + short islope2; +}t_aep_HDDC_eX_point_config; + + +typedef struct { + t_uint16 ibypass; + t_uint16 iattack_time; + t_uint16 irelease_time; + short imakeup; + short ilimit_level; + t_aep_HDDC_eX_point_config point[5]; +}t_aep_type2_lib_HDDC_eX_dynamic_params; + + +//---------------------------------------------------------------------- + + +/************************* + * TYPE2 MDRC_eX + **************************/ +typedef struct{ + t_uint16 iMemoryPreset; + t_uint16 i_nb_bands; // Spectral Bands = [2,4] + t_uint16 i_nb_points; // Compression Points = [2,5] +} t_aep_type2_lib_MDRC_eX_static_params; + + +typedef struct { + t_uint16 ibypass; + t_aep_type2_lib_HDDC_eX_dynamic_params iband[4]; + t_uint16 ilimiter_bypass; + t_uint16 ilimiter_release_time; + short ilimiter_makeup; + short ilimiter_threshold; +}t_aep_type2_lib_MDRC_eX_dynamic_params; + + +//---------------------------------------------------------------------- + + +/* Audio Visualization */ +#define ESAA_VISU_MIN_DATA_RATE_HZ 1 +#define ESAA_VISU_MAX_DATA_RATE_HZ 20 +#define ESAA_VISU_DEFAULT_DATA_RATE_HZ 10 + +#define ESAA_VISU_MIN_WAVE_DATA_LENGTH 16 +#define ESAA_VISU_MAX_WAVE_DATA_LENGTH 512 +#define ESAA_VISU_DEFAULT_WAVE_DATA_LENGTH 64 + +#define ESAA_VISU_MIN_FREQ_BAND_COUNT 1 +#define ESAA_VISU_MAX_FREQ_BAND_COUNT 256 +#define ESAA_VISU_DEFAULT_FREQ_BAND_COUNT 32 + +typedef enum +{ + ESAA_VISU_CHANNEL_INPUT, + ESAA_VISU_CHANNEL_MONO, + ESAA_VISU_CHANNEL_STEREO +} t_visu_nb_chan_out; + +typedef enum +{ + ESAA_VISU_ALERT_NONE = 0, + ESAA_VISU_ALERT_LEVEL_LEFT = 1, + ESAA_VISU_ALERT_WAVE_LEFT = 2, + ESAA_VISU_ALERT_FREQ_LEFT = 4, + ESAA_VISU_ALERT_LEVEL_RIGHT = 8, + ESAA_VISU_ALERT_WAVE_RIGHT = 16, + ESAA_VISU_ALERT_FREQ_RIGHT = 32, + ESAA_VISU_ALERT_WAVE_FREQ_LEFT = ESAA_VISU_ALERT_WAVE_LEFT + ESAA_VISU_ALERT_FREQ_LEFT, + ESAA_VISU_ALERT_WAVE_FREQ_RIGHT = ESAA_VISU_ALERT_WAVE_RIGHT + ESAA_VISU_ALERT_FREQ_RIGHT, + ESAA_VISU_ALERT_LEVEL_STEREO = ESAA_VISU_ALERT_LEVEL_LEFT + ESAA_VISU_ALERT_LEVEL_RIGHT, + ESAA_VISU_ALERT_WAVE_STEREO = ESAA_VISU_ALERT_WAVE_LEFT + ESAA_VISU_ALERT_WAVE_RIGHT, + ESAA_VISU_ALERT_FREQ_STEREO = ESAA_VISU_ALERT_FREQ_LEFT + ESAA_VISU_ALERT_FREQ_RIGHT, + ESAA_VISU_ALERT_WAVE_FREQ_STEREO = ESAA_VISU_ALERT_WAVE_STEREO + ESAA_VISU_ALERT_FREQ_STEREO +} t_visu_alert_type; + +typedef union +{ + struct + { + t_uint16 lsb; + t_uint16 msb; + } dsp_word32; + t_uint32 arm_word32; +} t_visu_alert_32bits_data_type; + +typedef struct +{ + t_uint16 data_rate; + t_uint16 nb_samples; + t_uint16 nb_bands; + t_uint16 reserved; // mandatory for 32-bit alignment of next field + t_visu_alert_32bits_data_type peak_level[2]; // 2 channels + t_visu_alert_32bits_data_type rms_level[2]; // 2 channels + t_visu_alert_32bits_data_type wave_buf[2][ESAA_VISU_MAX_WAVE_DATA_LENGTH]; // 2 channels + t_visu_alert_32bits_data_type freq_buf[2][ESAA_VISU_MAX_FREQ_BAND_COUNT]; // 2 channels + t_visu_alert_32bits_data_type freq_bands[ESAA_VISU_MAX_FREQ_BAND_COUNT]; +} t_visu_alert; + +typedef struct +{ + t_uint16 inb_chan_out; /* STATIC t_visu_nb_chan_out; default : visu_mono */ + t_uint16 iMemoryPreset; +} t_aep_audiovisualization_static_params; + +typedef struct +{ + t_uint16 idata_rate_Hz; /* DYNAMIC, range [1..20], default 10 */ + t_uint16 iwave_data_length; /* DYNAMIC, range [16...512], default 64 */ + t_uint16 ifreq_band_count; /* DYNAMIC, range [1..256], default 32 */ + t_uint16 ilevel_data; /* DYNAMIC, 0 : OFF, 1 : ON, default 0 */ + t_uint16 iwave_data; /* DYNAMIC, 0 : OFF, 1 : ON, default 0 */ + t_uint16 ifreq_data; /* DYNAMIC, 0 : OFF, 1 : ON, default 0 */ + t_uint16 ifreq_band_log; /* DYNAMIC, 0 : OFF, 1 : ON, default 0 */ + t_uint16 ifreq_level_log; /* DYNAMIC, 0 : OFF, 1 : ON, default 0 */ + t_uint16 ienable; /* DYNAMIC, 0 : DISABLED, 1 : ENABLED, default 0 */ +} t_aep_audiovisualization_dynamic_params; + + +//---------------------------------------------------------------------- + +/* COMPANDER */ +typedef struct{ + t_uint16 isamtau; /* STATIC, not implemented yet */ + t_uint16 ipdlm_c; /* STATIC, not implemented yet */ + t_uint16 ipdlm2; /* STATIC, not implemented yet */ + t_uint16 idlmpause; /* STATIC, not implemented yet */ + t_uint16 iminpause; /* STATIC, not implemented yet */ + t_uint16 ispeech_act; /* STATIC, not implemented yet */ + t_uint16 ispeech_c2; /* STATIC, not implemented yet */ + t_uint16 ilock_time; /* STATIC, not implemented yet */ + t_uint16 im_search; /* STATIC, not implemented yet */ + t_uint16 iMemoryPreset; +} t_aep_compander_static_params; + +typedef struct{ + t_uint16 ivlc_level_x2; /* DYNAMIC, not implemented yet */ + t_uint16 ivlc_erle_x2; /* DYNAMIC, not implemented yet */ + t_uint16 ivlc_nr_x2; /* DYNAMIC, not implemented yet */ + t_uint16 ivlc_erle_sc; /* DYNAMIC, not implemented yet */ + t_uint16 ivlc_nr_sc; /* DYNAMIC, not implemented yet */ + t_uint16 ithres_0; /* DYNAMIC, not implemented yet */ + t_uint16 ithres_2; /* DYNAMIC, not implemented yet */ + t_uint16 id_erl_nr; /* DYNAMIC, not implemented yet */ + t_uint16 imindlm; /* DYNAMIC, not implemented yet */ + t_uint16 inoise_corr; /* DYNAMIC, not implemented yet */ +} t_aep_compander_dynamic_params; + + + +//---------------------------------------------------------------------- + +/* COMPRESSOR */ +typedef struct{ + t_uint16 ipoly_order; /* STATIC, not implemented yet */ + t_uint16 iMemoryPreset; + t_uint16 iReserved1; + t_uint16 iReserved2; + t_uint16 iReserved3; + t_uint16 iReserved4; + t_uint16 iReserved5; + t_uint16 iReserved6; + t_uint16 iReserved7; +} t_aep_compressor_static_params; + +typedef struct{ + t_uint16 ialpha_dw; /* DYNAMIC, range [0,0x7fff] fract in Q15, default 0x7e5e = 0.98725 */ + t_uint16 ialpha_up; /* DYNAMIC, range [0,0x7fff] fract in Q15, default 0x7fd7 = 0.99873 */ + t_uint16 ithreshold; /* DYNAMIC, range [0,0x7fff] fract in Q15, default 0x4e20 */ + t_uint16 isub_sampling_ratio; /* DYNAMIC, range [0,40], default 40 */ + t_uint16 ivolume; /* DYNAMIC, linear gain range [1 ..], default 8*/ + t_uint16 iReserved0; + t_uint16 iReserved1; +} t_aep_compressor_dynamic_params; + + +//---------------------------------------------------------------------- + + +/************************ +* Doppler * +*************************/ + +typedef struct { + t_uint16 iMemoryPreset; +}t_aep_doppler_static_params; + +typedef struct { + t_uint16 iUpdate; + t_uint16 iFactor; + t_uint16 iSourceCoordX; + t_uint16 iSourceCoordY; + t_uint16 iSourceCoordZ; + t_uint16 iSourceVelX; + t_uint16 iSourceVelY; + t_uint16 iSourceVelZ; + t_uint16 iListenerCoordX; + t_uint16 iListenerCoordY; + t_uint16 iListenerCoordZ; + t_uint16 iListenerVelX; + t_uint16 iListenerVelY; + t_uint16 iListenerVelZ; +}t_aep_doppler_dynamic_params; + + +//---------------------------------------------------------------------- + +/* DTMF */ +typedef struct { + t_uint16 iMemoryPreset; + t_uint16 iReserved1; +} t_aep_dtmf_static_params; + + +typedef struct { + t_uint16 iReserved0; + t_uint16 iReserved1; +} t_aep_dtmf_dynamic_params; + + +//---------------------------------------------------------------------- + +/* effect OP parameters + Important : ALL parameters are 16 bits large +*/ + +/* static parameters */ +typedef struct { + t_uint16 iMemoryPreset; // supported preset are MEM_ALL_TCM (default), MEM_ALL_DDR, MEM_ALL_ESRAM, MEM_MIX_DDR_TCM_1, MEM_MIX_ESRAM_DDR + t_uint16 iDelaySize; // delay in sample range=[0,0xFFFF], +}t_aep_empty_effect_static_params; + + + +/* dynamic parameters */ +typedef struct { + t_uint16 iGain; // gain seen as a Q15 fract, range=[0,0x7FFF], default = 0x7FFF +}t_aep_empty_effect_dynamic_params; + + + +//---------------------------------------------------------------------- + +/* Equalizer */ +typedef struct { + t_uint16 iMemoryPreset; + t_uint16 iReserved1; + t_uint16 iReserved2; +}t_aep_equalizer_static_params; + +typedef struct { + t_uint16 iGainBand1; /* DYNAMIC, in Q8 unsigned + 128dB, default 0dB , range is [-100dB(7168) 24dB(38912)] */ + t_uint16 iGainBand2; /* DYNAMIC, in Q8 unsigned + 128dB, default 0dB , range is [-100dB(7168) 24dB(38912)] */ + t_uint16 iGainBand3; /* DYNAMIC, in Q8 unsigned + 128dB, default 0dB , range is [-100dB(7168) 24dB(38912)] */ + t_uint16 iGainBand4; /* DYNAMIC, in Q8 unsigned + 128dB, default 0dB , range is [-100dB(7168) 24dB(38912)] */ + t_uint16 iGainBand5; /* DYNAMIC, in Q8 unsigned + 128dB, default 0dB , range is [-100dB(7168) 24dB(38912)] */ + t_uint16 iGainBand6; /* DYNAMIC, in Q8 unsigned + 128dB, default 0dB , range is [-100dB(7168) 24dB(38912)] */ + t_uint16 iGainBand7; /* DYNAMIC, in Q8 unsigned + 128dB, default 0dB , range is [-100dB(7168) 24dB(38912)] */ + t_uint16 iGainBand8; /* DYNAMIC, in Q8 unsigned + 128dB, default 0dB , range is [-100dB(7168) 24dB(38912)] */ +}t_aep_equalizer_dynamic_params; + + + +//---------------------------------------------------------------------- +/* FLOWMINATOR : Flow killer */ +typedef struct { + t_uint16 iMemoryPreset; + t_uint16 iReserved1; +}t_aep_flowminator_static_params; + +typedef struct { + t_uint16 iDirectCommand; + t_uint16 iReserved0; +}t_aep_flowminator_dynamic_params; + + +//---------------------------------------------------------------------- + + + +/* LEC */ +typedef struct { + t_uint16 ifilter_delay; /* STATIC, filter delay, default 0 */ + t_uint16 ifilter_length; /* STATIC, length of adaptative Filter, default 128 */ + t_uint16 ifilter_shift; /* STATIC, default 4 */ + t_uint16 imu_shift; /* STATIC, adaptation step shift, default -3 */ + t_uint16 itrig_shift; /* STATIC, only if LEC_USE_FIX_FILTER, default 6 */ + t_uint16 inb_obs_coef; /* STATIC, only if LEC_USE_FIX_FILTER, default 30 */ + t_uint16 ish_end_r; /* STATIC, Max_Nrg_r to noise ratio used to define th_end_r, default 3 */ + t_uint16 ish_snr_r; /* STATIC, Deviation to noise ratio used when updating deviation, default 1 */ + t_uint16 ith_min_r; /* STATIC, Minimum deviation during initialisation phase (~0.0000008 in Q31), default 1700 */ + t_uint16 iMemoryPreset; +} t_aep_lec_static_params; + +typedef struct { + t_uint16 iReserved0; + t_uint16 iReserved1; +} t_aep_lec_dynamic_params; + + + +//---------------------------------------------------------------------- + + +/************************ +* MDRC * +*************************/ +typedef struct { + t_uint16 iMemoryPreset; +}t_aep_st_mdrc_static_params; + +typedef struct { + t_uint16 iBypass; + t_uint16 iThreshold; + t_uint16 iMakeup; +}t_aep_st_mdrc_band_config; + +typedef struct { + t_uint16 iBypass; + t_uint16 iFC1; + t_uint16 iFC2; + t_aep_st_mdrc_band_config iBand[3]; +}t_aep_st_mdrc_dynamic_params; + + +//---------------------------------------------------------------------- + + +/************************ +* MDRC * +*************************/ +typedef struct { + t_uint16 iMemoryPreset; + t_uint16 iNumBands; +}t_aep_st_mdrc5b_static_params; + +typedef struct { + t_uint16 iBypass; + t_uint16 iThresholdL; + t_uint16 iRatioL; + t_uint16 iThresholdH; + t_uint16 iRatioH; + t_uint16 iAttackTime; + t_uint16 iReleaseTime; +}t_aep_st_mdrc5b_band_config; + +/* DO NOT CHANGE THE ORDER OF THE ELEMENTS IN THE STRUCTURE!!! */ +typedef struct { + t_uint16 iBypass; + t_uint16 iFC[4]; + t_aep_st_mdrc5b_band_config iBand[5]; + t_aep_st_mdrc5b_band_config iGlobalCompressor; + t_uint16 iMakeup[5]; + t_uint16 iGlobalMakeup; +}t_aep_st_mdrc5b_dynamic_params; + + +//---------------------------------------------------------------------- + +/* MIXER */ +typedef struct { + t_uint16 iMemoryPreset; +} t_aep_mixer_static_params; + +typedef struct{ + t_uint16 iNoCompression; // disactivate(1)/activate(0) compression. Default is 0. + t_uint16 iPowerNormalised; // disactivate(1)/activate(0) power normalization during mono to stereo conversion. Default is 1 + t_uint16 iForceDownmix; // force mono ouput. Default is 0 +} t_aep_mixer_dynamic_params; + + +//---------------------------------------------------------------------- + +/* TRANSDUCER EQUALIZER */ +typedef struct +{ + t_uint16 iMemoryPreset; +} t_aep_noise_reductor_LC_static_params; + + +typedef struct +{ + t_uint16 ialpha_nrj1; + t_uint16 ialpha_nrj2; + t_uint16 ialpha_nrj3; + t_uint16 inrj_thres_mant; + t_uint16 inrj_thres_exp; + t_uint16 inrj_ratio_thres1; + t_uint16 inrj_ratio_thres2; + t_uint16 inrj_ratio_thres3; + t_uint16 igain1; + t_uint16 igain2; + t_uint16 ialpha_up; + t_uint16 ialpha_down; + t_uint16 inb_samples_init; +} t_aep_noise_reductor_LC_dynamic_params; + + +//---------------------------------------------------------------------- + +/* stwhd: Stereo widening for headphones */ +typedef struct { + t_uint16 iMemoryPreset; + t_uint16 iSampleRate; +} t_aep_type1_stwhd_static_params; + +typedef struct { + t_uint16 iEnable; + t_uint16 iStrength; +} t_aep_type1_stwhd_dynamic_params; + + +//---------------------------------------------------------------------- + +/* stwls: Stereo widening for loudspeakers */ +typedef struct { + t_uint16 iMemoryPreset; + t_uint16 iSampleRate; +} t_aep_type1_stwls_static_params; + +typedef struct { + t_uint16 iTuningParams; + t_uint16 iDelay; + t_uint16 iCrossTalkGain; +} t_aep_type1_stwls_tuning_params; + +typedef struct { + t_uint16 iTuningParams; + t_uint16 iEnable; + t_uint16 iStrength; +} t_aep_type1_stwls_user_params; + +typedef union { + t_uint16 iTuningParams; + t_aep_type1_stwls_tuning_params iTuning; + t_aep_type1_stwls_user_params iUser; +} t_aep_type1_stwls_dynamic_params; + + +//---------------------------------------------------------------------- + +/* Reverb */ +typedef struct { + t_uint16 iMemoryPreset; + t_uint16 iReserved0; +}t_aep_reverb_static_params; + +typedef struct { + t_uint16 iFakeStereo; // True if Lout = Rout for stereo output + t_uint16 iOutputMode; // 0: output mode = input mode, 1: output is mono, 2: output is stereo, 3 output is dual mono + t_uint16 iSLDistance; // source listener distance in mm + t_uint16 iMINDistance; // in mm + t_uint16 iMAXDistance; // in mm + t_uint16 iPreset; // [0 30] + t_uint16 ilRoom; // [0, 10000] + t_uint16 ilRoomHF; // [0, 10000] + t_uint16 iflRoomRolloffFactor; // [0, 10000] + t_uint16 iflDecayTime; // [100, 20000] + t_uint16 iflDecayHFRatio; // [1000, 20000] + t_uint16 ilReflections; // [0, 11000] + t_uint16 iflReflectionsDelay; // [0, 30000] + t_uint16 ilReverb; // [0, 12000] + t_uint16 iflReverbDelay; // [0, 10000] + t_uint16 iflDiffusion ; // [0, 10000] + t_uint16 iflDensity; // [0, 10000] + t_uint16 iflHFReference; // [20, 20000] +}t_aep_reverb_dynamic_params; + + +//---------------------------------------------------------------------- + +/* SAMPLE RATE CONVERTER */ +typedef struct{ + t_uint16 iConversionType; /* STATIC, range[0-Unknown,1-Up,2-Down] default */ + t_uint16 iFreq_out; /* STATIC, range[7-16] in enum t_saa_sample_freq, default */ + t_uint16 iFreq_in; /* STATIC, range[0,4..16]in enum t_saa_sample_freq, if different than zero force freq_in to the corresponding freq, default 0*/ + t_uint16 iMemoryPreset; //0=MEM_DEFAULT,1=MEM_ALL_DDR,2=MEM_ALL_TCM,8=MEM_ALL_ESRAM,all others default to MEM_DEFAULT + t_uint16 ilomips_to_out48; //was iReserved1, now 0=standard src, 1=lower mips & perf for upsampling cases to 48kHz; +} t_aep_samplerateconv_static_params; + +typedef struct { + t_uint16 iFreq_out; +} t_aep_samplerateconv_dynamic_params; + + +//---------------------------------------------------------------------- + +/* SPLITTER */ +typedef struct{ + t_uint16 iMemoryPreset; + t_uint16 iReserved1; +} t_aep_splitter_static_params; + +typedef struct{ + t_uint16 iReserved0; + t_uint16 iReserved1; +} t_aep_splitter_dynamic_params; + + + +//---------------------------------------------------------------------- + + +/* Stereo Enhancer */ +typedef struct { + t_uint16 iMemoryPreset; + t_uint16 iReserved1; +}t_aep_stereoenhancer_static_params; + +typedef struct { + t_uint16 iEnable; + t_uint16 iOutputMode; + t_uint16 iHeadphoneMode; + t_uint16 iStrength; +}t_aep_stereoenhancer_dynamic_params; + + +//---------------------------------------------------------------------- + +/* SWITCH */ +typedef struct +{ + t_uint16 iMemoryPreset; +} t_aep_switch_static_params; + +typedef struct +{ + t_uint16 inum_input; +} t_aep_switch_dynamic_params; + + +//---------------------------------------------------------------------- +/* + =========================================================================== + File: UAEP_SW_LS_FTRD_PARAMS.H v.1.0 - 24.Jan.2008 + =========================================================================== + + SW LS MODULE SPECIFIC AT STN8815 TARGET + + EIL parameters + + + Copyright (C) France Telecom 2008 + History: + 24.Jan.08 v1.0 Creation. C. TERRIEN + ============================================================================ +*/ + +/* SW LS parameters + Important : ALL parameters are 16 bits large +*/ + +/* static parameters */ +typedef struct +{ + t_uint16 iMemoryPreset; /* Allocation of G722 decoder resources. + Range is [ MEM_DEFAULT + ALL_DDR + ALL_TCM + ALL ESRAM ] */ + t_uint16 iNbSamplesInABlock; /* Number of samples (left & right) to be + treated in a same call of the ESL + process function. Range is [0, 0x7FFF] */ + t_uint16 iSampleRate; /* Sample rate of the input stream. + range is [ 0, 0x7FFF ] */ +}t_aep_SW_LS_FTRD_static_params; + + + +/* dynamic parameters */ +typedef struct +{ + t_uint16 iGain; /* gain applies during calculation. + range is [ 0, 0xFFFF ] */ + t_uint16 iInputGain; /* gain applies on input samples. + range is [ 0, 0xFFFF ] */ + t_uint16 iDelaySize; /* Delay in sample. range is [ 0, 60 ] */ + t_uint16 iLowPassFreq; /* Low frequency of filter. range is + [ 0, 0x7FFFFFFF ] */ + t_uint16 iHighPassFreq; /* High frequency of filter. range is + [ 0, 0x7FFFFFFF ] */ +}t_aep_SW_LS_FTRD_dynamic_params; + + + +//---------------------------------------------------------------------- + + + +// Tone Generator +typedef struct { + t_uint16 iFs; // Sampling frequency + t_uint16 iMemoryPreset; +}t_aep_ToneGene_static_params; + +typedef struct { + t_uint16 iFreq1; // Sine Freq 1 in Hz + t_uint16 iFreq2; // Sine Freq 2 in Hz + t_uint16 iLevel1; // Sine Level 1 + t_uint16 iLevel2; // Sine Level 2 + t_uint16 iToneDuration; // Duration of the tone in ms + t_uint16 iSilenceDuration; // Duration of the silence in ms + t_uint16 iRepeatNumber; // Number of repetition; 0 = infinite +}t_aep_ToneGene; + + +#define SAA_TONEGENE_MAX_DTMF_CODE 80 + +typedef struct { + t_uint16 iDtmfToneOnLength; + t_uint16 iDtmfToneOffLength; + t_uint16 iDtmfPauseLength; + t_uint16 Code[(SAA_TONEGENE_MAX_DTMF_CODE >> 1)]; // 2 dtmf code per index +}t_aep_Dtmf; + +typedef union { + t_aep_ToneGene ToneGene; + t_aep_Dtmf Dtmf; +}t_aep_Tone_Dtmf; + +typedef struct { + t_uint16 iMixToneMode; // Mix or Mute sample; Mode : single sime, Dual Sine, DTMF + t_aep_Tone_Dtmf iToneDtmf; // Union : Tone and DTMF haven't the same interface +}t_aep_ToneGene_dynamic_params; + + +//---------------------------------------------------------------------- + +/* TRANSDUCER EQUALIZER */ +typedef struct +{ + t_uint16 iMemoryPreset; + t_uint16 istereo; /* STATIC, 0 : mono, 1 : stereo, default 0 */ + t_uint16 inb_biquad_cells; /* [0..NB_MAX_TRANSDUCER_EQUALIZER_BIQUAD_CELLS] */ +} t_aep_transducer_equalizer_static_params; + + +typedef struct +{ + t_uint16 b_exp; + t_uint16 b0_low; // 16 LSB + t_uint16 b0_high; // 8 MSB + t_uint16 b1_low; // 16 LSB + t_uint16 b1_high; // 8 MSB + t_uint16 b2_low; // 16 LSB + t_uint16 b2_high; // 8 MSB + t_uint16 a1_low; // 16 LSB + t_uint16 a1_high; // 8 MSB + t_uint16 a2_low; // 16 LSB + t_uint16 a2_high; // 8 MSB +} t_transducer_equalizer_biquad_cell_params; + + +#define NB_MAX_TRANSDUCER_EQUALIZER_BIQUAD_CELLS 20 + +typedef struct +{ + t_uint16 igain_exp; + t_uint16 igain_mant_low; // 16 LSB + t_uint16 igain_mant_high; // 8 MSB + t_transducer_equalizer_biquad_cell_params ibiquad_cells[NB_MAX_TRANSDUCER_EQUALIZER_BIQUAD_CELLS]; +} t_aep_transducer_equalizer_dynamic_params; + + +//---------------------------------------------------------------------- + +typedef struct { + t_uint16 iMemoryPreset; +} t_aep_volctrl_static_params; + +typedef struct{ + t_uint16 iDownMix; /* DYNAMIC, range [0,1], default 0 */ + t_uint16 igll; /* DYNAMIC, in Q8 unsigned + 128dB, default 0dB */ + t_uint16 iglr; /* DYNAMIC, in Q8 unsigned + 128dB, default -infinity dB */ + t_uint16 igrl; /* DYNAMIC, in Q8 unsigned + 128dB, default -infinity dB */ + t_uint16 igrr; /* DYNAMIC, in Q8 unsigned + 128dB, default 0dB */ + t_uint16 ialpha; /* DYNAMIC, range [0,0xFFFE], integer, default 0 */ +} t_aep_volctrl_dynamic_params; + + + +//---------------------------------------------------------------------- + +/* AEC */ +typedef struct +{ + t_uint16 ifilter_allocated_AEC; /* STATIC, integer value range [1,1022], default 256 */ + t_uint16 idelay_allocated_AEC; /* STATIC, integer value range [1,1022], default 256 */ +} t_aec_static_params; + +typedef struct +{ + t_uint16 iMemoryPreset; + t_uint16 istereo; /* STATIC, 0 : mono, 1 : stereo, default 0 */ + t_aec_static_params aec_static_params; +} t_aep_aec_static_params; + +typedef struct +{ + t_uint16 ia_AEC; /* DYNAMIC, range [1,..] , default 1 */ + t_uint16 ib_AEC; /* DYNAMIC, range [1,..] , default 3 */ + t_uint16 ic_AEC; /* DYNAMIC, range [1,..], for good adaptation a~=b and c >> a , default 100 */ + t_uint16 ialgo_AEC; /* DYNAMIC, 0=APA2, 1=NLMS, 2=BYPASS, default 0 */ + t_uint16 inrgxmin_AEC; /* DYNAMIC, range [0,0x7FFF], default 384 */ + t_uint16 ifilter_length_AEC; /* DYNAMIC, range [1,ifilter_allocated], default 256 */ + t_uint16 igll_AEC; /* DYNAMIC, range [0,0x7FFF] , default 0x7FFF */ + t_uint16 iglr_AEC; /* DYNAMIC, range [0,0x7FFF] , default 0x0000 */ + t_uint16 igrl_AEC; /* DYNAMIC, range [0,0x7FFF] , default 0x0000 */ + t_uint16 igrr_AEC; /* DYNAMIC, range [0,0x7FFF] , default 0x7FFF */ + t_uint16 idll_AEC; /* DYNAMIC, range [0,ifilter_allocated], default 0 */ + t_uint16 idlr_AEC; /* DYNAMIC, range [0,ifilter_allocated], default 0 */ + t_uint16 idrl_AEC; /* DYNAMIC, range [0,ifilter_allocated], default 0 */ + t_uint16 idrr_AEC; /* DYNAMIC, range [0,ifilter_allocated], default 0 */ +} t_aep_aec_dynamic_params; + + +//---------------------------------------------------------------------- + +/* AES */ +typedef struct +{ + t_uint16 iMemoryPreset; + t_uint16 istereo; /* STATIC, 0 : mono, 1 : stereo, default 0 */ + t_uint16 icomfort_noise_substitution; +} t_aep_aes_static_params; + +typedef struct +{ + t_uint16 ia_AES; /* DYNAMIC, Q15 fract range [0,0x7FFF], default 0x1388 = 0.152588 */ + t_uint16 ib_AES; /* DYNAMIC, Q15 fract range [0,0x7FFF], default 0x0271 = 0.019073 */ + t_uint16 ic_AES; /* DYNAMIC, Q15 fract range [0,0x7FFF], default 0x04E2 = 0.038147 */ + t_uint16 inrxmin_AES; /* DYNAMIC, Q15 fract range [0,0x7FFF], default 0x0010 = 0.0005 */ + t_uint16 imumax_AES; /* DYNAMIC, Q15 fract range [0,0x7FFF], default 0x7FFF = 0.99999 */ + t_uint16 imumin_AES; /* DYNAMIC, Q15 fract range [0,0x7FFF], default 0x0000 = 0.0 */ + t_uint16 iGmin_AES; /* DYNAMIC, Q15 fract range [0,0x7FFF], default 0x0000 = 0.0 */ + t_uint16 ialpha_dw_AES; /* DYNAMIC, Q15 fract range [0,0x7FFF], default 0x4000 = 0.5 */ + t_uint16 ialpha_up_AES; /* DYNAMIC, Q15 fract range [0,0x7FFF], default 0x7F77 = 0.995819 */ + t_uint16 imode_AES; /* DYNAMIC, 0=normal, 1=bypass with processing, 2=bypass without processing, default 0 */ + t_uint16 icomfort_noise_gain_AES; /* DYNAMIC, Q13 fract range [0,0x7FFF], default 0x0000 = 0.0 */ +} t_aep_aes_dynamic_params; + + +//---------------------------------------------------------------------- + +#define NB_SPECTRAL_AES_PARAMS_SETS 4 + +/* ENH (noise reductor) */ +typedef struct +{ + t_uint16 iMemoryPreset; + t_uint16 istereo; /* STATIC, 0 : mono, 1 : stereo, default 0 */ + t_uint16 icomfort_noise_generation; /* STATIC, 0 : comfort noise generation ON, 1 : comfort noise generation OFF, default 0 */ + t_uint16 ilow_latency; /* STATIC, 0 : low-latency OFF, 1 : low-latency ON, default 0 */ + t_uint16 ispectral_AES; /* STATIC, 0 : spectral AES OFF, 1 : spectral AES ON, default 0 */ +} t_aep_enh_static_params; + +typedef struct +{ + t_uint16 ia_SAES; /* DYNAMIC, Q15 fract range [0,0x7FFF], default 0x1388 = 0.152588 */ + t_uint16 ib_SAES; /* DYNAMIC, Q15 fract range [0,0x7FFF], default 0x0271 = 0.019073 */ + t_uint16 ic_SAES; /* DYNAMIC, Q15 fract range [0,0x7FFF], default 0x04E2 = 0.038147 */ + t_uint16 inrxmin_SAES; /* DYNAMIC, Q15 fract range [0,0x7FFF], default 0x0010 = 0.0005 */ + t_uint16 imumax_SAES; /* DYNAMIC, Q15 fract range [0,0x7FFF], default 0x7FFF = 0.99999 */ + t_uint16 imumin_SAES; /* DYNAMIC, Q15 fract range [0,0x7FFF], default 0x0000 = 0.0 */ + t_uint16 iGmin_SAES; /* DYNAMIC, Q15 fract range [0,0x7FFF], default 0x0000 = 0.0 */ + t_uint16 ialpha_dw_SAES; /* DYNAMIC, Q15 fract range [0,0x7FFF], default 0x4000 = 0.5 */ + t_uint16 ialpha_up_SAES; /* DYNAMIC, Q15 fract range [0,0x7FFF], default 0x7F77 = 0.995819 */ +} t_spectral_AES_dynamic_params; + +typedef struct +{ + // noise reductor param + t_uint16 imin_noise_mean_exp_ENH; + + // spectral AES params + t_uint16 ispectral_AES_mode; + t_spectral_AES_dynamic_params spectral_AES_dynamic_params[NB_SPECTRAL_AES_PARAMS_SETS]; +} t_aep_enh_dynamic_params; + + +//---------------------------------------------------------------------- + + +/* NAEC config */ +typedef enum +{ + NAEC_STEREO_ON = 1, + NAEC_AEC_ON = NAEC_STEREO_ON << 1, + NAEC_ENH_ON = NAEC_AEC_ON << 1, + NAEC_AES_ON = NAEC_ENH_ON << 1, + NAEC_SPECTRAL_AES_ON = NAEC_AES_ON << 1, + NAEC_COMFORT_NOISE_ON = NAEC_SPECTRAL_AES_ON << 1, + NAEC_ENH_LOW_LATENCY_ON = NAEC_COMFORT_NOISE_ON << 1, + NAEC_ALGO_MASK = ( NAEC_AEC_ON + | NAEC_ENH_ON + | NAEC_AES_ON), + NAEC_CONFIG1_MASK = ( NAEC_ALGO_MASK + | NAEC_SPECTRAL_AES_ON + | NAEC_COMFORT_NOISE_ON + | NAEC_ENH_LOW_LATENCY_ON), + NAEC_CONFIG2_MASK = ( NAEC_STEREO_ON + | NAEC_CONFIG1_MASK) +} +t_naec_config; + +typedef struct +{ + t_aec_static_params aec_static_params; + //t_enh_static_params enh_static_params; + //t_aes_static_params aes_static_params; +} t_naec_static_params; + +typedef struct +{ + t_uint16 iMemoryPreset; + t_uint16 iconfig; // t_naec_config + t_naec_static_params naec_static_params; +} t_aep_naec_static_params; + +typedef struct +{ + t_aep_aec_dynamic_params aec_dynamic_params; + t_aep_enh_dynamic_params enh_dynamic_params; + t_aep_aes_dynamic_params aes_dynamic_params; +} t_aep_naec_dynamic_params; + + +//---------------------------------------------------------------------- + + +/* WB_NAEC config */ +#define CONFIG_SHIFT_LOW_WB 0 +#define CONFIG_SHIFT_HIGH_WB 6 +typedef enum +{ + WB_NAEC_STEREO_ON = (NAEC_STEREO_ON << CONFIG_SHIFT_LOW_WB), + WB_NAEC_LOW_AEC_ON = (NAEC_AEC_ON << CONFIG_SHIFT_LOW_WB), + WB_NAEC_LOW_ENH_ON = (NAEC_ENH_ON << CONFIG_SHIFT_LOW_WB), + WB_NAEC_LOW_AES_ON = (NAEC_AES_ON << CONFIG_SHIFT_LOW_WB), + WB_NAEC_LOW_SPECTRAL_AES_ON = (NAEC_SPECTRAL_AES_ON << CONFIG_SHIFT_LOW_WB), + WB_NAEC_LOW_COMFORT_NOISE_ON = (NAEC_COMFORT_NOISE_ON << CONFIG_SHIFT_LOW_WB), + WB_NAEC_LOW_ENH_LOW_LATENCY_ON = (NAEC_ENH_LOW_LATENCY_ON << CONFIG_SHIFT_LOW_WB), + WB_NAEC_HIGH_AEC_ON = (NAEC_AEC_ON << CONFIG_SHIFT_HIGH_WB), + WB_NAEC_HIGH_ENH_ON = (NAEC_ENH_ON << CONFIG_SHIFT_HIGH_WB), + WB_NAEC_HIGH_AES_ON = (NAEC_AES_ON << CONFIG_SHIFT_HIGH_WB), + WB_NAEC_HIGH_SPECTRAL_AES_ON = (NAEC_SPECTRAL_AES_ON << CONFIG_SHIFT_HIGH_WB), + WB_NAEC_HIGH_COMFORT_NOISE_ON = (NAEC_COMFORT_NOISE_ON << CONFIG_SHIFT_HIGH_WB), + WB_NAEC_HIGH_ENH_LOW_LATENCY_ON = (NAEC_ENH_LOW_LATENCY_ON << CONFIG_SHIFT_HIGH_WB), + WB_NAEC_CONFIG_MASK = ( WB_NAEC_STEREO_ON + | WB_NAEC_LOW_AEC_ON + | WB_NAEC_LOW_ENH_ON + | WB_NAEC_LOW_AES_ON + | WB_NAEC_LOW_SPECTRAL_AES_ON + | WB_NAEC_LOW_COMFORT_NOISE_ON + | WB_NAEC_LOW_ENH_LOW_LATENCY_ON + | WB_NAEC_HIGH_AEC_ON + | WB_NAEC_HIGH_ENH_ON + | WB_NAEC_HIGH_AES_ON + | WB_NAEC_HIGH_SPECTRAL_AES_ON + | WB_NAEC_HIGH_COMFORT_NOISE_ON + | WB_NAEC_HIGH_ENH_LOW_LATENCY_ON) +} +t_wb_naec_config; + +/* WB NAEC */ +typedef struct +{ + t_naec_static_params naec_static_params_low; + t_naec_static_params naec_static_params_high; +} t_wb_naec_static_params; + +typedef struct +{ + t_uint16 iMemoryPreset; + t_uint16 iconfig; // t_wb_naec_config + t_wb_naec_static_params wb_naec_static_params; +} t_aep_wb_naec_static_params; + +typedef struct +{ + t_aep_naec_dynamic_params naec_dynamic_params_low; + t_aep_naec_dynamic_params naec_dynamic_params_high; +} t_aep_wb_naec_dynamic_params; + + +//---------------------------------------------------------------------- + + + +/* WBNB_NAEC config */ +#define CONFIG_SHIFT_WB_WBNB 1 +typedef enum +{ + WBNB_NAEC_WIDE_BAND_ON = 1, // 0x0001 + WBNB_NAEC_STEREO_ON = (WB_NAEC_STEREO_ON << CONFIG_SHIFT_WB_WBNB), // 0x0002 + WBNB_NAEC_LOW_AEC_ON = (WB_NAEC_LOW_AEC_ON << CONFIG_SHIFT_WB_WBNB), // 0x0004 + WBNB_NAEC_LOW_ENH_ON = (WB_NAEC_LOW_ENH_ON << CONFIG_SHIFT_WB_WBNB), // 0x0008 + WBNB_NAEC_LOW_AES_ON = (WB_NAEC_LOW_AES_ON << CONFIG_SHIFT_WB_WBNB), // 0x0010 + WBNB_NAEC_LOW_SPECTRAL_AES_ON = (WB_NAEC_LOW_SPECTRAL_AES_ON << CONFIG_SHIFT_WB_WBNB), // 0x0020 + WBNB_NAEC_LOW_COMFORT_NOISE_ON = (WB_NAEC_LOW_COMFORT_NOISE_ON << CONFIG_SHIFT_WB_WBNB), // 0x0040 + WBNB_NAEC_LOW_ENH_LOW_LATENCY_ON = (WB_NAEC_LOW_ENH_LOW_LATENCY_ON << CONFIG_SHIFT_WB_WBNB), // 0x0080 + WBNB_NAEC_HIGH_AEC_ON = (WB_NAEC_HIGH_AEC_ON << CONFIG_SHIFT_WB_WBNB), // 0x0100 + WBNB_NAEC_HIGH_ENH_ON = (WB_NAEC_HIGH_ENH_ON << CONFIG_SHIFT_WB_WBNB), // 0x0200 + WBNB_NAEC_HIGH_AES_ON = (WB_NAEC_HIGH_AES_ON << CONFIG_SHIFT_WB_WBNB), // 0x0400 + WBNB_NAEC_HIGH_SPECTRAL_AES_ON = (WB_NAEC_HIGH_SPECTRAL_AES_ON << CONFIG_SHIFT_WB_WBNB), // 0x0800 + WBNB_NAEC_HIGH_COMFORT_NOISE_ON = (WB_NAEC_HIGH_COMFORT_NOISE_ON << CONFIG_SHIFT_WB_WBNB), // 0x1000 + WBNB_NAEC_HIGH_ENH_LOW_LATENCY_ON = (WB_NAEC_HIGH_ENH_LOW_LATENCY_ON << CONFIG_SHIFT_WB_WBNB), // 0x2000 + WBNB_NAEC_CONFIG_MASK = ( WBNB_NAEC_WIDE_BAND_ON + | WBNB_NAEC_STEREO_ON + | WBNB_NAEC_LOW_AEC_ON + | WBNB_NAEC_LOW_ENH_ON + | WBNB_NAEC_LOW_AES_ON + | WBNB_NAEC_LOW_SPECTRAL_AES_ON + | WBNB_NAEC_LOW_COMFORT_NOISE_ON + | WBNB_NAEC_LOW_ENH_LOW_LATENCY_ON + | WBNB_NAEC_HIGH_AEC_ON + | WBNB_NAEC_HIGH_ENH_ON + | WBNB_NAEC_HIGH_AES_ON + | WBNB_NAEC_HIGH_SPECTRAL_AES_ON + | WBNB_NAEC_HIGH_COMFORT_NOISE_ON + | WBNB_NAEC_HIGH_ENH_LOW_LATENCY_ON) +} +t_wbnb_naec_config; + +typedef struct +{ + t_uint16 iMemoryPreset; + t_uint16 iconfig; // t_wbnb_naec_config + t_wb_naec_static_params wb_naec_static_params; +} t_aep_wbnb_naec_static_params; + +typedef enum +{ + WBNB_NAEC_MODE_NORMAL, + WBNB_NAEC_MODE_NORMAL_ALERT, + WBNB_NAEC_MODE_NORMAL_READ_FILTER, + WBNB_NAEC_MODE_NORMAL_READ_FILTER_ALERT, + WBNB_NAEC_MODE_TUNING_DELAY_RX_IN_TX_IN, + WBNB_NAEC_MODE_TUNING_DELAY_RX_OUT_TX_IN, + WBNB_NAEC_MODE_TUNING_DELAY_RX_OUT_RX_IN, + WBNB_NAEC_MODE_TUNING_ECHO_NOISE, + WBNB_NAEC_MODE_TUNING_ECHO_SIGNAL +} +t_wbnb_naec_mode; + +typedef struct +{ + t_aep_wb_naec_dynamic_params wb_naec_dynamic_params; + + t_uint16 imode; // t_wbnb_naec_mode + + t_uint16 ifilter_write_alert_rate; // number of blocks between 2 filtre write alerts + + t_uint16 ifltr_low_left_ptr_read_lsb; // address to read filter low left coefficients + t_uint16 ifltr_low_left_ptr_read_msb; + + t_uint16 ifltr_low_right_ptr_read_lsb; // address to read filter low right coefficients + t_uint16 ifltr_low_right_ptr_read_msb; + + t_uint16 ifltr_high_left_ptr_read_lsb; // address to read filter high left coefficients + t_uint16 ifltr_high_left_ptr_read_msb; + + t_uint16 ifltr_high_right_ptr_read_lsb; // address to read filter high right coefficients + t_uint16 ifltr_high_right_ptr_read_msb; + + t_uint16 ifltr_low_left_ptr_write_lsb; // address to write filter low left coefficients + t_uint16 ifltr_low_left_ptr_write_msb; + + t_uint16 ifltr_low_right_ptr_write_lsb; // address to write filter low right coefficients + t_uint16 ifltr_low_right_ptr_write_msb; + + t_uint16 ifltr_high_left_ptr_write_lsb; // address to write filter high left coefficients + t_uint16 ifltr_high_left_ptr_write_msb; + + t_uint16 ifltr_high_right_ptr_write_lsb; // address to write filter high right coefficients + t_uint16 ifltr_high_right_ptr_write_msb; + + t_uint16 irx_out_ptr_read_lsb; // address to read rx out samples + t_uint16 irx_out_ptr_read_msb; + + t_uint16 irx_in_ptr_write_lsb; // address to write rx in samples + t_uint16 irx_in_ptr_write_msb; + + t_uint16 itx_in_ptr_write_lsb; // address to write tx in samples + t_uint16 itx_in_ptr_write_msb; + + t_uint16 irx_out_ptr_write_lsb; // address to write rx out samples + t_uint16 irx_out_ptr_write_msb; + + t_uint16 itx_out_ptr_write_lsb; // address to write tx out samples + t_uint16 itx_out_ptr_write_msb; + + t_uint16 irx_in_low_ptr_write_lsb; // address to write rx in low samples + t_uint16 irx_in_low_ptr_write_msb; + + t_uint16 itx_in_low_ptr_write_lsb; // address to write tx in low samples + t_uint16 itx_in_low_ptr_write_msb; + + t_uint16 iobs_low_ptr_write_lsb; // address to write obs low samples + t_uint16 iobs_low_ptr_write_msb; + + t_uint16 iAEC_out_low_ptr_write_lsb; // address to write AEC out low samples + t_uint16 iAEC_out_low_ptr_write_msb; + + t_uint16 iENH_out_low_ptr_write_lsb; // address to write ENH out low samples + t_uint16 iENH_out_low_ptr_write_msb; + + t_uint16 iAES_out_low_ptr_write_lsb; // address to write AES out low samples + t_uint16 iAES_out_low_ptr_write_msb; + + t_uint16 irx_in_high_ptr_write_lsb; // address to write rx in high samples + t_uint16 irx_in_high_ptr_write_msb; + + t_uint16 itx_in_high_ptr_write_lsb; // address to write tx in high samples + t_uint16 itx_in_high_ptr_write_msb; + + t_uint16 iobs_high_ptr_write_lsb; // address to write obs high samples + t_uint16 iobs_high_ptr_write_msb; + + t_uint16 iAEC_out_high_ptr_write_lsb; // address to write AEC out high samples + t_uint16 iAEC_out_high_ptr_write_msb; + + t_uint16 iENH_out_high_ptr_write_lsb; // address to write ENH out high samples + t_uint16 iENH_out_high_ptr_write_msb; + + t_uint16 iAES_out_high_ptr_write_lsb; // address to write AES out high samples + t_uint16 iAES_out_high_ptr_write_msb; + + t_uint16 ialert_delay_ptr_write_lsb; // address to write alert delay + t_uint16 ialert_delay_ptr_write_msb; + + t_uint16 ivolctrl_local_struct_ptr_lsb; // address of volctrl effect local structure + t_uint16 ivolctrl_local_struct_ptr_msb; + + t_uint16 ivolctrl_effect_desc_ptr_lsb; // address of volctrl effect description structure + t_uint16 ivolctrl_effect_desc_ptr_msb; + + t_uint16 iswitch_local_struct_ptr_lsb; // address of switch effect local structure + t_uint16 iswitch_local_struct_ptr_msb; + + t_uint16 iswitch_effect_desc_ptr_lsb; // address of switch effect description structure + t_uint16 iswitch_effect_desc_ptr_msb; +} t_aep_wbnb_naec_dynamic_params; + + + +typedef enum +{ + ESAA_WBNB_NAEC_ALERT_DELAY_FOUND = 0x0001, + ESAA_WBNB_NAEC_ALERT_RX_IN_WRITE_ALMOST_FULL = 0x0002, + ESAA_WBNB_NAEC_ALERT_RX_IN_WRITE_OVERRUN = 0x0004, + ESAA_WBNB_NAEC_ALERT_TX_IN_WRITE_ALMOST_FULL = 0x0008, + ESAA_WBNB_NAEC_ALERT_TX_IN_WRITE_OVERRUN = 0x0010, + ESAA_WBNB_NAEC_ALERT_RX_OUT_WRITE_ALMOST_FULL = 0x0020, + ESAA_WBNB_NAEC_ALERT_RX_OUT_WRITE_OVERRUN = 0x0040, + ESAA_WBNB_NAEC_ALERT_TX_OUT_WRITE_ALMOST_FULL = 0x0080, + ESAA_WBNB_NAEC_ALERT_TX_OUT_WRITE_OVERRUN = 0x0100, + ESAA_WBNB_NAEC_ALERT_RX_OUT_READ_ALMOST_EMPTY = 0x0200, + ESAA_WBNB_NAEC_ALERT_RX_OUT_READ_UNDERRUN = 0x0400, + ESAA_WBNB_NAEC_ALERT_FILTER_WRITE = 0x0800, + ESAA_WBNB_NAEC_ALERT_FILTER_READ = 0x1000 +} t_wbnb_naec_alert_type; + +typedef enum +{ + ESAA_WBNB_NAEC_ALERT_NB_RX_IN_WRITE_ALMOST_FULL = 0x0001, + ESAA_WBNB_NAEC_ALERT_NB_RX_IN_WRITE_OVERRUN = 0x0002, + ESAA_WBNB_NAEC_ALERT_NB_TX_IN_WRITE_ALMOST_FULL = 0x0004, + ESAA_WBNB_NAEC_ALERT_NB_TX_IN_WRITE_OVERRUN = 0x0008, + ESAA_WBNB_NAEC_ALERT_NB_OBS_WRITE_ALMOST_FULL = 0x0010, + ESAA_WBNB_NAEC_ALERT_NB_OBS_WRITE_OVERRUN = 0x0020, + ESAA_WBNB_NAEC_ALERT_NB_AEC_OUT_WRITE_ALMOST_FULL = 0x0040, + ESAA_WBNB_NAEC_ALERT_NB_AEC_OUT_WRITE_OVERRUN = 0x0080, + ESAA_WBNB_NAEC_ALERT_NB_ENH_OUT_WRITE_ALMOST_FULL = 0x0100, + ESAA_WBNB_NAEC_ALERT_NB_ENH_OUT_WRITE_OVERRUN = 0x0200, + ESAA_WBNB_NAEC_ALERT_NB_AES_OUT_WRITE_ALMOST_FULL = 0x0400, + ESAA_WBNB_NAEC_ALERT_NB_AES_OUT_WRITE_OVERRUN = 0x0800 +} t_wbnb_naec_alert_low_high_sample_type; + +typedef struct +{ + int wbnb_naec_alert_type; + int wbnb_naec_alert_low_sample; + int wbnb_naec_alert_high_sample; + int alert_counter; + int cpt_buf; +} t_wbnb_naec_alert; + +typedef struct +{ + t_uint16 bits_0_15; + t_uint16 bits_16_31; + t_uint16 bits_32_47; +} t_word48; + +typedef struct +{ + t_uint16 dll; + t_uint16 dlr; + t_uint16 drl; + t_uint16 drr; + t_uint16 gll; + t_uint16 glr; + t_uint16 grl; + t_uint16 grr; + t_uint16 offset_src[2]; + t_uint16 offset_dst[2][2]; + t_word48 nrj_src[2]; + t_word48 nrj_dst[2][2]; +} t_wbnb_naec_alert_delay; + +// circular buffer : empty if (ind_read == ind_write), full if (((ind_write - ind_read) % nb_samples) == 1) +typedef struct +{ + t_uint16 nb_samples; + t_uint16 ind_read; + t_uint16 ind_write; + t_uint16 samples_table; // table of samples +} t_wbnb_naec_alert_sample; + +typedef struct +{ + t_uint16 shift; + t_uint16 nb_coef; + t_uint16 coef_table; // table of coefficients +} t_wbnb_naec_alert_filter; + + + + + + +typedef union { + t_uint16 iGenericParams[SAA_MSG_NB_PARAM]; + t_aep_st3d_static_params iSt3dStaticParams; + t_aep_type2_lib_HD3D_static_params iType2LibHD3DStaticParams; + t_aep_type2_lib_HDDC_eX_static_params iType2LibHDDCEXStaticParams; + t_aep_type2_lib_MDRC_eX_static_params iType2LibMDRCEXStaticParams; + t_aep_audiovisualization_static_params iAudiovisualizationStaticParams; + t_aep_compander_static_params iCompanderStaticParams; + t_aep_compressor_static_params iCompressorStaticParams; + t_aep_doppler_static_params iDopplerStaticParams; + t_aep_dtmf_static_params iDtmfStaticParams; + t_aep_empty_effect_static_params iEmptyEffectStaticParams; + t_aep_equalizer_static_params iEqualizerStaticParams; + t_aep_flowminator_static_params iFlowminatorStaticParams; + t_aep_lec_static_params iLecStaticParams; + t_aep_st_mdrc_static_params iStMdrcStaticParams; + t_aep_st_mdrc5b_static_params iStMdrc5bStaticParams; + t_aep_mixer_static_params iMixerStaticParams; + t_aep_noise_reductor_LC_static_params iNoiseReductorLCStaticParams; + t_aep_type1_stwhd_static_params iType1StwhdStaticParams; + t_aep_type1_stwls_static_params iType1StwlsStaticParams; + t_aep_reverb_static_params iReverbStaticParams; + t_aep_samplerateconv_static_params iSamplerateconvStaticParams; + t_aep_splitter_static_params iSplitterStaticParams; + t_aep_stereoenhancer_static_params iStereoenhancerStaticParams; + t_aep_switch_static_params iSwitchStaticParams; + t_aep_SW_LS_FTRD_static_params iSWLSFTRDStaticParams; + t_aep_ToneGene_static_params iToneGeneStaticParams; + t_aep_transducer_equalizer_static_params iTransducerEqualizerStaticParams; + t_aep_volctrl_static_params iVolctrlStaticParams; + t_aep_aec_static_params iAecStaticParams; + t_aep_aes_static_params iAesStaticParams; + t_aep_enh_static_params iEnhStaticParams; + t_aep_naec_static_params iNaecStaticParams; + t_aep_wb_naec_static_params iWbNaecStaticParams; + t_aep_wbnb_naec_static_params iWbnbNaecStaticParams; +} t_saa_component_static_params; + + +typedef union { + t_uint16 iGenericParams[SAA_MSG_NB_PARAM]; + t_aep_st3d_dynamic_params iSt3dDynamicParams; + t_aep_type2_lib_HD3D_dynamic_params iType2LibHD3DDynamicParams; + t_aep_type2_lib_HDDC_eX_dynamic_params iType2LibHDDCEXDynamicParams; + t_aep_type2_lib_MDRC_eX_dynamic_params iType2LibMDRCEXDynamicParams; + t_aep_audiovisualization_dynamic_params iAudiovisualizationDynamicParams; + t_aep_compander_dynamic_params iCompanderDynamicParams; + t_aep_compressor_dynamic_params iCompressorDynamicParams; + t_aep_doppler_dynamic_params iDopplerDynamicParams; + t_aep_dtmf_dynamic_params iDtmfDynamicParams; + t_aep_empty_effect_dynamic_params iEmptyEffectDynamicParams; + t_aep_equalizer_dynamic_params iEqualizerDynamicParams; + t_aep_flowminator_dynamic_params iFlowminatorDynamicParams; + t_aep_lec_dynamic_params iLecDynamicParams; + t_aep_st_mdrc_dynamic_params iStMdrcDynamicParams; + t_aep_st_mdrc5b_dynamic_params iStMdrc5bDynamicParams; + t_aep_mixer_dynamic_params iMixerDynamicParams; + t_aep_noise_reductor_LC_dynamic_params iNoiseReductorLCDynamicParams; + t_aep_type1_stwhd_dynamic_params iType1StwhdDynamicParams; + t_aep_type1_stwls_dynamic_params iType1StwlsDynamicParams; + t_aep_reverb_dynamic_params iReverbDynamicParams; + t_aep_samplerateconv_dynamic_params iSamplerateconvDynamicParams; + t_aep_splitter_dynamic_params iSplitterDynamicParams; + t_aep_stereoenhancer_dynamic_params iStereoenhancerDynamicParams; + t_aep_switch_dynamic_params iSwitchDynamicParams; + t_aep_SW_LS_FTRD_dynamic_params iSWLSFTRDDynamicParams; + t_aep_ToneGene_dynamic_params iToneGeneDynamicParams; + t_aep_transducer_equalizer_dynamic_params iTransducerEqualizerDynamicParams; + t_aep_volctrl_dynamic_params iVolctrlDynamicParams; + t_aep_aec_dynamic_params iAecDynamicParams; + t_aep_aes_dynamic_params iAesDynamicParams; + t_aep_enh_dynamic_params iEnhDynamicParams; + t_aep_naec_dynamic_params iNaecDynamicParams; + t_aep_wb_naec_dynamic_params iWbNaecDynamicParams; + t_aep_wbnb_naec_dynamic_params iWbnbNaecDynamicParams; +} t_saa_component_dynamic_params; + +#endif // _ha_effect_params_h_ --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/ha_hcl_fw_interface.h @@ -0,0 +1,163 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ + +#ifndef _ha_hcl_fw_interface_h_ +#define _ha_hcl_fw_interface_h_ + +/************************/ +// Versionning of the FW. +/************************/ +#define HA_IDV 0x0006 // means developpement version +#define HOST_HA_IDV_1 200 +#define HOST_HA_IDV_2 201 + +/***********************************/ +// Define to retrieve answers/alerts +/***********************************/ +#define SAA_MSG_NB_PARAM 12 +#define SAA_MBX_UP_SIZE 10 +//#define SAA_MBX_UP_SIZE 1 // DEBUG DOUBLE IT MAILBOX +#define SAA_MSG_SIZE 16 + +/************************/ +// Define for mailboxes. +/************************/ +#define SAA_MBX_DOWN_SIZE 5 +//#define SAA_MBX_DOWN_SIZE 1 // DEBUG DOUBLE IT MAILBOX +#define HOST_HA_MBX_DOWN_ADD_1 202 //0x0194 +#define HOST_HA_MBX_DOWN_ADD_2 203 //0x0196 +#define HOST_HA_MBX_DOWN_ADD_3 204 //0x0198 +#define HOST_HA_MBX_UP_ADD_1 205 //0x019A +#define HOST_HA_MBX_UP_ADD_2 206 //0x019C +#define HOST_HA_MBX_UP_ADD_3 207 //0x019E +#define HOST_HA_MBX_DOWN_SIZE 208 +#define HOST_SAA_MBX_UP_SIZE 209 +#define HOST_HA_CMD1_SEM 210 + +/****************************************************************/ +/* HOST define for dynamic memory size */ +/****************************************************************/ +#define HOST_SAA_EXT16_SIZE_MSB 0x50 +#define HOST_SAA_EXT16_SIZE_LSB 0x51 +#define HOST_SAA_EXT24_SIZE_MSB 0x52 +#define HOST_SAA_EXT24_SIZE_LSB 0x53 +#define HOST_SAA_ESRAM16_SIZE_MSB 0x54 +#define HOST_SAA_ESRAM16_SIZE_LSB 0x55 +#define HOST_SAA_ESRAM24_SIZE_MSB 0x56 +#define HOST_SAA_ESRAM24_SIZE_LSB 0x57 + +/********************/ +// Enum for commands. +/********************/ +typedef enum +{ + HA_CMD_UNKNOWN = 0, +/* General commands from 0x0001 to 0x0fff */ + ha_cmd_suppressed, + HA_CMD_DELETE_BLOCK, + HA_CMD_CREATE_PORT, + HA_CMD_DELETE_PORT, + HA_CMD_FREEZE_BLOCK, + HA_CMD_CONNECT_PORT, + HA_CMD_DISCONNECT_PORT, + HA_CMD_UPDATE_NETWORK, + ESAA_CMD_CREATE_BLOCK, + +/* Specific commands from 0x1001 to 0x1fff */ + HA_CMD_DMA_CONFIG = 0x1001, //4097 + HA_CMD_CODEC_CONFIG, + HA_CMD_CODEC_INFO, + HA_CMD_RESET_HSI, + HA_CMD_CONFIG_PORT_HSI, + HA_CMD_SERVER_INFO, + HA_CMD_AEP_CONFIG, + HA_CMD_SHM_CONFIG, + +/* Flow commands from 0x2001 to 0x2fff */ + HA_CMD_SET_FLOW_PAUSE = 0x2001, //8193 + HA_CMD_SET_FLOW_UNPAUSE, + HA_CMD_SET_FLOW_STOP, + HA_CMD_SET_FLOW_PLAY, + HA_CMD_SET_FLOW_FILE, + HA_CMD_RESET_DMA_OUT, + HA_CMD_SET_FLOW_PLAY_RESET_EOF, + +/* from 0x3001 to 0x3fff reserved (Alert), redefine id for debug */ + HA_ALERT_BOOT_FINISHED = 0x3001, + HA_ALERT_ERROR_DETECTED, + HA_ALERT_CHANGE_DATA_FORMAT, + HA_ALERT_EOF, + HA_ALERT_HSI_RESET_CONNECTION_BB, + HA_ALERT_AEP_DTMF, + HA_ALERT_CODEC_INFO, + HA_CMD_SHM_BUFFER_READY, + HA_CMD_SHM_BUFFER_RELEASED, + HA_ALERT_NEED_NORMAL_SPEED, + HA_ALERT_READY_FOR_SLOW_SPEED, + HA_ALERT_AEP_AUDIO_VISU, + HA_ALERT_HSI_BURST_COMPLETE, + HA_ALERT_HSI_ALLOW_SLEEP_MODE, + HA_ALERT_AEP_TRANSDUCER_EQ, + HA_ALERT_AEP_WBNB_NAEC, + +/* AEP command from 0x4001 to 0x4fff */ + HA_CMD_CREATE_COMPONENT = 0x4001, + HA_CMD_DELETE_COMPONENT, + HA_CMD_CONNECT_COMPONENT, + HA_CMD_DISCONNECT_COMPONENT, + HA_CMD_CONFIG_COMPONENT, + HA_CMD_COMPONENT_INFO, + +/* Performance command from 0x5001 to 0x5fff */ + HA_CMD_ENABLE_LOW_POWER = 0x5001, + HA_CMD_DISABLE_LOW_POWER, + HA_CMD_SLEEP_CORE, + HA_CMD_WAKE_UP_CORE, + HA_CMD_LOCATE_DEBUG_ZONE, + HA_CMD_ENABLE_CYCLE_ESTIMATION, + HA_CMD_INIT_CYCLE_ESTIMATION, + HA_CMD_START_CYCLE_ESTIMATION, + HA_CMD_STOP_CYCLE_ESTIMATION, + HA_CMD_GET_CYCLE_ESTIMATION, + HA_CMD_RESET_CYCLE_ESTIMATION, + HA_CMD_DISABLE_CYCLE_ESTIMATION, + HA_CMD_ADD_BLOCK_CYCLE_ESTIMATION, + HA_CMD_REMOVE_BLOCK_CYCLE_ESTIMATION, + HA_CMD_SET_BLOCK_PRIORITY, + HA_CMD_GET_MEMORY_FOOTPRINT, + HA_CMD_CHECK_MEMORY, + HA_CMD_GET_PERF_ESTIMATION, + HA_CMD_GET_MMRM_MEMORY_FOOTPRINT, + +/* Low Power command from 0x6001 to 0x6fff */ + HA_CMD_ENABLE_SLOW_MODE = 0x6001, + HA_CMD_DISABLE_SLOW_MODE, + HA_CMD_SWITCH_SPEED, + HA_CMD_NORMAL_SPEED_REACHED = HA_ALERT_NEED_NORMAL_SPEED, + HA_CMD_SLOW_SPEED_REACHED = HA_ALERT_READY_FOR_SLOW_SPEED, + +/* SAA Trace command from 0x7001 to 0x7fff */ + HA_CMD_ENABLE_TRACE = 0x7001, + HA_CMD_DISABLE_TRACE, + +/* Last in list */ + HA_CMD_LAST_IN_LIST = 0xffff +} t_ha_command_id; + +#endif /* _ha_hcl_fw_interface_h_ */ --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/hti.c @@ -0,0 +1,271 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ + +#include "hcl_defs.h" +#include "hti.h" +#include "hti_protocol.h" + +#ifdef HTI_PROTOCOL_STT + int __hti_message_counter=0; +#endif + +s_HTI_OSMO * asicHTI_CPU; //hti osmo for CPU + +/** + * Initialise the base adress of Hti_cpu structur + * \param *base_addr : The base address versus mapping of the hti + */ +void HTI_Init_BaseAddr(s_HTI_OSMO * base_addr) +//*************************************************************************************** +{ + asicHTI_CPU = base_addr; +} + +/** + * Compute the size of a string like strlen do + * \param *ptr : '\0' delimited string + * \return : The amount of char read whithout the null char + */ +int hti_strlen(const char *ptr) +//*************************************************************************************** +{ + int nb=0; + while (*ptr!=0) + { + ++ptr; + ++nb; + } + return(nb); +} + +#if defined(_MSC_VER) // For win CE + #include "stdlib.h" +#else + #ifndef va_end + typedef struct __va_list { void *__ap; } va_list; + #define va_end(ap) ((void)0) + #define va_start(ap, parmN) (__va_start(ap, parmN)) + #define va_arg(ap, type) (__va_arg(ap, type)) + #endif //va_end +#endif + +/** + * Unformated printf. Data is send in binary and the host is responsible to format the string + * \param channel : Hti channel + * \param *Format : String format description (like for printf) + * \param ... : List of parameters like for printf + * \return : 0 if OK, negative value if errors + */ +int Hti_Printf(const unsigned int channel, const char *Format, ...) +//*************************************************************************************** +{ //unformated printf. Send the const string and parameters. Formating will be done by the target + enum + { eRegular, + ePourcent, + }; + unsigned char cVal=0; + const char *cptr; + int iVal; + double D; + int *ptr; + int len; + int state = eRegular; + int nb=0; + int error=0; + + va_list list; + +#ifdef _MSC_VER // For win CE + list.__ap=NULL; +#endif + //const char * list; + va_start( list, Format ); // Initialize variable arguments. + //ptr=((int *)list.__ap); + len =hti_strlen(Format); + HTI_CMD_PRINTF(channel); + HtiSendn_8(channel, (const HTI_U8 *)Format, len+1); // Must send the null char + + while (*Format !='\0') + { + switch(state) + { + case eRegular: + switch(*Format) + { + case '%': + state =ePourcent; + nb=0; + break; + } + break; + case ePourcent: + switch(*Format) + { + case '%': // %% return to global + if (nb==0) + state =eRegular; + else + { + ++error; + } + break; + case 'i': + case 'u': + case 'o': + case 'd': + case 'x': + case 'X': + state=eRegular; // return to normal mode + iVal= va_arg(list, int); + HtiSend_32(channel, iVal); + break; + case 'p': //pointer + state=eRegular; // return to normal mode + ptr= va_arg(list, int *); + HtiSend_32(channel, (HTI_U32)ptr); + break; + case 'g': + case 'G': + case 'e': + case 'E': + case 'f': + state=eRegular; // return to normal mode + D=va_arg(list, double); + ptr=(int *)&D; + HtiSend_32(channel, *(const HTI_U32 *)(ptr+1)); + HtiSend_32(channel, *(const HTI_U32 *)ptr); + break; + case 'c': + cVal= (char)va_arg(list, int); + HtiSend_8(channel, ( char)cVal); + state=eRegular; // return to normal mode + break; + case 's': + state=eRegular; // return to normal mode + cptr= va_arg(list, const char *); + HtiSendn_8(channel, (const HTI_U8 *)cptr, hti_strlen(cptr)+1); + break; + case '*': //special feature the precision is gived by args + iVal= va_arg(list, int); + HtiSend_32(channel, iVal); + break; + case '#': + case ' ': + case '-': + case '+': + case '.': + ++nb; + break; + default: + ++nb; + break; + } + break; + } + ++Format; + } + HTI_CMD_END_OF_CHANNEL(channel); + va_end( list ); // Reset variable arguments. + return(error); +} + +/** + * Send a '\0' delimited string + * \param channel : Hti channel + * \param *ptr : pointer to '\0' delimited string + */ +int Hti_String(const unsigned int channel, const char *ptr) +//*************************************************************************************** +{ + HTI_CMD_STRING(channel); + while (*ptr) + { + HtiSend_8(channel, (HTI_U8 )*ptr); + ++ptr; + } + HtiSend_8(channel, 0); // Send the final + HTI_CMD_END_OF_CHANNEL(channel); + return(0); +} + + +/** + * Send an array of 32 bits values in raw format + * \param channel : Hti channel + * \param *ptr : Array of 32 bits values + * \param nbr32 : Number of 32 bits elements to send + */ +int Hti_Binary (const unsigned int channel, const HTI_U32 *ptr, unsigned int nbr32) +//*************************************************************************************** +{ // Send an array of UI32 + HTI_CMD_RAW(channel); + for (; nbr32 > 0; --nbr32) + { + *(HTI_U32*)asicHTI_CPU->OSMO[channel] = *(ptr++); + } + HTI_CMD_END_OF_CHANNEL(channel); + return(0); +} + +/** + * Send an array of 32 bits values without any protocol + * \param channel : Hti channel + * \param *ptr : Array of 32 bits values + * \param nbr32 : Number of 32 bits elements to send + */ +void hti_raw32 (const unsigned int channel, const HTI_U32 *ptr, unsigned int nbr32) +//*************************************************************************************** +{ // Send an array of UI32 + for (; nbr32 > 0; --nbr32) + { + *(HTI_U32*)asicHTI_CPU->OSMO[channel] = *(ptr++); + } +} + +#ifdef _USE_HTI_PRINTF_FORMATED + +#ifndef HTI_PRINTF_BUFFER_SIZE + #define HTI_PRINTF_BUFFER_SIZE 2048 +#endif + +static char _gPrintf_buff[HTI_PRINTF_BUFFER_SIZE]; // static buffer for formating + +/** + * Formated printf. Formating is done on the target + * \param channel : Hti channel + * \param *Format : String format description (like for printf) + * \param ... : List of parameters like for printf + * \return : 0 if OK, negative value if errors + */ +int Hti_PrintfFmt(const unsigned int channel, const char *Format, ...) +//*************************************************************************************** +{ //formated printf. Formating is done by the ARM. Consume lot of CPU times + int len; + va_list list; + va_start( list, Format ); // Initialize variable arguments. + int res=vsprintf(_gPrintf_buff, Format, list); + len =hti_strlen(_gPrintf_buff)+1; + HTI_CMD_PRINTF_FMT(channel); + HtiSendn_8(channel, (const HTI_U8*)_gPrintf_buff, len); + HTI_CMD_END_OF_CHANNEL(channel); + va_end( list ); // Reset variable arguments. + return(res); +} +#endif + --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/hti.h @@ -0,0 +1,159 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ + +#ifndef _HTI_H +#define _HTI_H + +#ifdef __cplusplus + extern "C" { +#endif + +typedef unsigned char HTI_U8 ; +typedef unsigned short HTI_U16; +typedef unsigned int HTI_U32; +typedef unsigned HTI_OSMO_MSG[16]; + +typedef volatile struct HTI_OSMO +{ + HTI_OSMO_MSG OSMO[256]; + HTI_OSMO_MSG OSMOT[256]; +}s_HTI_OSMO; + +typedef enum { + HTI_SAA, + HTI_SVA +} t_hti_select; + +extern s_HTI_OSMO * asicHTI_CPU; +extern s_HTI_OSMO * const asicHTI_DSP; + +#define HTICR_FAHBCLK_2 0x0 +#define HTICR_FAHBCLK_4 0x1 +#define HTICR_FAHBCLK_8 0x2 +#define HTICR_FAHBCLK_16 0x3 +#define HTICR_FAHBCLK_32 0x4 +#define HTICR_FAHBCLK_64 0x5 +#define HTICR_FAHBCLK_128 0x6 +#define HTICR_FAHBCLK_256 0x7 + +#define CPU_OSMO 1 +#define CPU_OSMOT 2 +#define DSP_OSMO 3 +#define DSP_OSMOT 4 + +/* HTI OSMO(T) DSP registers */ +#if defined (__STN_8810) + #define HTI_OSMO_DSP_REG_BASE_ADDR 0x10200000 + #define HTI_OSMO_DSP_REG_END_ADDR 0x1020FFFF +#elif defined (__STN_8815) + #define HTI_OSMO_DSP_REG_BASE_ADDR 0x10220000 + #define HTI_OSMO_DSP_REG_END_ADDR 0x1022FFFF +#endif + +int hti_strlen(const char *ptr); + +/**************************** FUNCTIONS ***************************/ +void HTI_Init_BaseAddr(s_HTI_OSMO * base_addr); + +//Basic +static __inline void HtiSend_8(const unsigned int channel, const HTI_U8 val); +static __inline void HtiSend_16(const unsigned int channel, const HTI_U16 val); +static __inline void HtiSend_32(const unsigned int channel, const HTI_U32 val); + +// Timestamped version +static __inline void HtiSend_8T(const unsigned int channel, const HTI_U8 val); +static __inline void HtiSend_16T(const unsigned int channel, const HTI_U16 val); +static __inline void HtiSend_32T(const unsigned int channel, const HTI_U32 val); + +// Buffer version +static __inline void HtiSendn_8(const unsigned int channel, const HTI_U8 *ptr, unsigned int nbr8); +static __inline void HtiSendn_16(const unsigned int channel, const HTI_U16 *ptr, unsigned int nbr16); +static __inline void HtiSendn_32(const unsigned int channel, const HTI_U32 *ptr, unsigned int nbr32); + + +int SendHtiString(const unsigned int channel, const char *ptr); +void HtiMsg (const unsigned int channel, const HTI_U32 *ptr, unsigned int Nbr); + +static __inline void HtiSend_8(const unsigned int channel, const HTI_U8 val) +{ + *((HTI_U8*)(asicHTI_CPU->OSMO[channel])) = val; +} + +static __inline void HtiSend_16(const unsigned int channel, const HTI_U16 val) +{ + *(HTI_U16*)asicHTI_CPU->OSMO[channel] = val; +} + +static __inline void HtiSend_32(const unsigned int channel, const HTI_U32 val) +{ + *(HTI_U32*)asicHTI_CPU->OSMO[channel] = val; +} + +static __inline void HtiSendn_8(const unsigned int channel, const HTI_U8 *ptr, unsigned int nbr8) +{ + for (; nbr8 > 0; --nbr8) + { + *(HTI_U8*)asicHTI_CPU->OSMO[channel] = *(ptr++); + } +} + +static __inline void HtiSendn_16(const unsigned int channel, const HTI_U16 *ptr, unsigned int nbr16) +{ + for (; nbr16 > 0; --nbr16) + { + *(HTI_U16*)asicHTI_CPU->OSMO[channel] = *(ptr++); + } +} + +static __inline void HtiSendn_32(const unsigned int channel, const HTI_U32 *ptr, unsigned int nbr32) +{ + for (; nbr32 > 0; --nbr32) + { + *(HTI_U32*)asicHTI_CPU->OSMO[channel] = *(ptr++); + } +} + +// Timestamped version +static __inline void HtiSend_8T(const unsigned int channel, const HTI_U8 val) +{ + *(HTI_U8*)asicHTI_CPU->OSMOT[channel] = val; +} + +static __inline void HtiSend_16T(const unsigned int channel, const HTI_U16 val) +{ + *(HTI_U16*)asicHTI_CPU->OSMOT[channel] = val; +} + +static __inline void HtiSend_32T(const unsigned int channel, const HTI_U32 val) +{ + *(HTI_U32*)asicHTI_CPU->OSMOT[channel] = val; +} + + +// XXXX/ST protocol +int Hti_Printf(const unsigned int channel, const char *Format, ...); +int Hti_String(const unsigned int channel, const char *ptr); +int Hti_Binary (const unsigned int channel, const HTI_U32 *ptr, unsigned int nbr32); + +#ifdef __cplusplus +}; +#endif + +#endif // _HTI_H + --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/hti_protocol.h @@ -0,0 +1,134 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ + +#ifndef _STT_PROTOCOL_H +#define _STT_PROTOCOL_H + // Use new ST Trace protocol + extern int __hti_message_counter; + +#define STT_END_CHANNEL 250 + +#define SET_BIT_STT_RESERVED 0x80 +#define SET_BIT_VECTOR 0x40 +#define SET_BIT_SIGNED 0x20 + +#define STT_PRLG_VERSION (SET_BIT_STT_RESERVED | 0x00) +#define STT_PRLG_UNF_PRINTF (SET_BIT_STT_RESERVED | 0x01) +#define STT_PRLG_STR (SET_BIT_STT_RESERVED | 0x02) +#define STT_PRLG_SAAHCL (SET_BIT_STT_RESERVED | 0x04) +#define STT_PRLG_PCM_DUMP (SET_BIT_STT_RESERVED | 0x05) +#define STT_PRLG_MEM_DUMP (SET_BIT_STT_RESERVED | 0x06) + +#define STT_PRLG_T_U8 (SET_BIT_STT_RESERVED | SET_BIT_VECTOR | 0x01) +#define STT_PRLG_T_U16 (SET_BIT_STT_RESERVED | SET_BIT_VECTOR | 0x02) +#define STT_PRLG_T_U32 (SET_BIT_STT_RESERVED | SET_BIT_VECTOR | 0x03) +#define STT_PRLG_T_U64 (SET_BIT_STT_RESERVED | SET_BIT_VECTOR | 0x04) +#define STT_PRLG_T_U16_8 (SET_BIT_STT_RESERVED | SET_BIT_VECTOR | 0x05) +#define STT_PRLG_T_U32_U32_24 (SET_BIT_STT_RESERVED | SET_BIT_VECTOR | 0x06) +#define STT_PRLG_T_U32_U32 (SET_BIT_STT_RESERVED | SET_BIT_VECTOR | 0x07) +#define STT_PRLG_T_U32_U16_8 (SET_BIT_STT_RESERVED | SET_BIT_VECTOR | 0x08) +#define STT_PRLG_T_U32_U16 (SET_BIT_STT_RESERVED | SET_BIT_VECTOR | 0x09) +#define STT_PRLG_T_U32_24 (SET_BIT_STT_RESERVED | SET_BIT_VECTOR | 0x0A) +#define STT_PRLG_T_U32_U16_U16_8 (SET_BIT_STT_RESERVED | SET_BIT_VECTOR | 0x0B) + +#define STT_PRLG_T_S8 (SET_BIT_STT_RESERVED | SET_BIT_VECTOR | SET_BIT_SIGNED | 0x01) +#define STT_PRLG_T_S16 (SET_BIT_STT_RESERVED | SET_BIT_VECTOR | SET_BIT_SIGNED | 0x02) +#define STT_PRLG_T_S32 (SET_BIT_STT_RESERVED | SET_BIT_VECTOR | SET_BIT_SIGNED | 0x03) +#define STT_PRLG_T_S64 (SET_BIT_STT_RESERVED | SET_BIT_VECTOR | SET_BIT_SIGNED | 0x04) +#define STT_PRLG_T_S16_8 (SET_BIT_STT_RESERVED | SET_BIT_VECTOR | SET_BIT_SIGNED | 0x05) +#define STT_PRLG_T_S32_S32_24 (SET_BIT_STT_RESERVED | SET_BIT_VECTOR | SET_BIT_SIGNED | 0x06) +#define STT_PRLG_T_S32_S32 (SET_BIT_STT_RESERVED | SET_BIT_VECTOR | SET_BIT_SIGNED | 0x07) +#define STT_PRLG_T_S32_S16_8 (SET_BIT_STT_RESERVED | SET_BIT_VECTOR | SET_BIT_SIGNED | 0x08) +#define STT_PRLG_T_S32_S16 (SET_BIT_STT_RESERVED | SET_BIT_VECTOR | SET_BIT_SIGNED | 0x09) +#define STT_PRLG_T_S32_24 (SET_BIT_STT_RESERVED | SET_BIT_VECTOR | SET_BIT_SIGNED | 0x0A) +#define STT_PRLG_T_S32_S16_S16_8 (SET_BIT_STT_RESERVED | SET_BIT_VECTOR | SET_BIT_SIGNED | 0x0B) + +enum +{ + eSTT_Printf = STT_PRLG_UNF_PRINTF, + eSTT_String = STT_PRLG_STR, + reserved, + eSTT_Printf_Fmt = STT_PRLG_STR, + + eSTT_Int8_n = STT_PRLG_T_S16_8, + eSTT_UInt8_n = STT_PRLG_T_U16_8, + eSTT_Int16_n = STT_PRLG_T_S16, + eSTT_UInt16_n = STT_PRLG_T_U16, + eSTT_Int24_n = STT_PRLG_T_S32_24, + eSTT_UInt24_n = STT_PRLG_T_U32_24, + eSTT_Int32_n = STT_PRLG_T_S32, + eSTT_UInt32_n = STT_PRLG_T_U32, + eSTT_Int56 = STT_PRLG_T_S32_S16_S16_8, // C'est quoi + eSTT_UInt56 = STT_PRLG_T_U32_U16_U16_8, // C'est quoi + eSTT_Int48_n = STT_PRLG_T_S32_S16_8, + eSTT_UInt48_n = STT_PRLG_T_U32_U16_8, + eSTT_Int48_n_bis = STT_PRLG_T_S32_S16, // C'est quoi + eSTT_UInt48_n_bis = STT_PRLG_T_U32_U16, // C'est quoi + + eSTT_Saa_hcl = STT_PRLG_SAAHCL, // 0x84 + eSTT_Pcm_Dump = STT_PRLG_PCM_DUMP, // 0x85 + eSTT_Mem_Dump = STT_PRLG_MEM_DUMP, // 0x86 + + eSTT_Binary , + + eUnsuported =0x10000, + + eSTT_Char , + eSTT_Int8 , + eSTT_UInt8 , + eSTT_Int16 , + eSTT_UInt16 , + eSTT_Int32 , + eSTT_UInt32 , + eSTT_Int48 , + eSTT_UInt48 , + eSTT_Int64 , + eSTT_UInt64 , + eSTT_Double , + eSTT_Float , + + + + eSTT_Int64_n , + eSTT_UInt64_n , + eSTT_Double_n , + eSTT_Float_n , + + + eSTT_Bad_start_value =0x10000 /* eXXXX_BAD_START_VALUE +*/ , // When channel is valid but start value not recognized + eSTT_Betty_lost_data =0x20000 /* eXXXX_BETTY_LOST_DATA +*/ , // When Betty lost data +}; + + + + #define HTI_CMD_END_OF_CHANNEL(channel) { HtiSend_16(STT_END_CHANNEL, channel+ __hti_message_counter); __hti_message_counter+=0x100; if (__hti_message_counter>=0x10000) __hti_message_counter=0x100; } + + #define HTI_CMD_PRINTF_FMT(channel) HtiSend_8(channel, eSTT_Printf_Fmt) + #define HTI_CMD_PRINTF(channel) HtiSend_8(channel, eSTT_Printf ) + #define HTI_CMD_STRING(channel) HtiSend_8(channel, eSTT_String) + #define HTI_CMD_RAW(channel) HtiSend_8(channel, eSTT_Binary ) + #define HTI_CMD_SAA_HCL(channel) HtiSend_8(channel, eSTT_Saa_hcl ) + #define HTI_CMD_PCM_DUMP(channel) HtiSend_8(channel, eSTT_Pcm_Dump ) + #define HTI_CMD_MEM_DUMP(channel) HtiSend_8(channel, eSTT_Mem_Dump ) + + #define HTI_PROTOCOL_STT + +#endif //_STT_PROTOCOL_H --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/saa.c @@ -0,0 +1,2538 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ + +/*--------------------------------------------------------------------------* + * Includes * + *--------------------------------------------------------------------------*/ +#include "debug.h" +#include "saap.h" +#include "hti.h" + +/*--------------------------------------------------------------------------* + * Global variables * + *--------------------------------------------------------------------------*/ +#ifdef __DEBUG +#define MY_DEBUG_LEVEL_VAR_NAME myDebugLevel_SAA +#define MY_DEBUG_ID myDebugID_SAA +t_dbg_level MY_DEBUG_LEVEL_VAR_NAME = DEBUG_LEVEL0; +t_dbg_id MY_DEBUG_ID = SAA_HCL_DBG_ID; +#endif + + +/*--------------------------------------------------------------------------* + * Private data * + *--------------------------------------------------------------------------*/ + + +/*--------------------------------------------------------------------------* + * Public functions * + *--------------------------------------------------------------------------*/ + +/****************************************************************************/ +/* NAME: SAA_Init */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: Initialize this HCL. */ +/* */ +/* PARAMETERS: */ +/* IN: pInit: pointer to the initialization structure */ +/* OUT: - */ +/* RETURN: */ +/* Error code */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_saa_error SAA_Init(t_saa_init* pInit) { + +/* + 8810 A0: + HW_ID = AA 0A 08 47 0D F0 15 BB + HW_Host_ID = AC AA 0A 08 47 + + 8810 B0: + HW_ID = AA 0A 18 47 0D F0 15 BB + HW_Host_ID = AC AA 0A 18 47 + + 8815 A0: + HW_ID = AA 0A 28 47 0D F0 15 BB + HW_Host_ID = AC AA 0A 28 47 + + 8815 B0: + HW_ID = AA 0A 38 47 0D F0 15 BB + HW_Host_ID = AC AA 0A 38 47 + + 8815 C0: + HW_ID = AA 0A 48 47 0D F0 15 BB + HW_Host_ID = AC AA 0A 38 47 +*/ + t_uint8 hw_id[8] = { 0xAA, 0x0A, 0x08, 0x47, 0x0D, 0xF0, 0x15, 0xBB }; + t_uint8 hw_host_id[5] = { 0xAC, 0xAA, 0x0A, 0x08, 0x47 }; + + t_uint8 hw_id_msk[8] = { 0xFF, 0xFF, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; + t_uint8 hw_host_id_msk[5] = { 0xFF, 0xFF, 0xFF, 0x0F, 0xFF }; + + t_uint8 cut_version; + + #if defined(__STN_8810) + t_uint8 cut_version_min = 0; // 8810 A0 + t_uint8 cut_version_max = 1; // 8810 B0 + #elif defined(__STN_8815) + t_uint8 cut_version_min = 2; // 8815 A0 + t_uint8 cut_version_max = 5; // 8815 D0 + #endif + + unsigned int i; + t_uint16 data_size_kB; + + DBGENTER6("pInit @=0x%08lX, SAABaseAddress=0x%08lX, useHSEM=%u, HSEMBaseAddress=0x%08lX, ul=%u, dl=%u", (t_uint32)pInit, pInit->SAABaseAddress, pInit->useHSEM, pInit->HSEMBaseAddress, pInit->ul, pInit->dl); + + (void)SAA_SetDbgLevel(DEBUG_LEVEL0); + + saa_system.saa_base_address = pInit->SAABaseAddress; + + saa_system.sdram = pInit->sdram; + saa_system.esram = pInit->esram; + + // map SAA registers + saa_system.pSAA_HW = (t_saa_hw*)(pInit->SAABaseAddress + 0x40000); + + // check hardware ID + for (i=0; iid[i] & hw_id_msk[i]) != hw_id[i]) + { + DBGEXIT(ESAA_ERROR_BAD_HW_ID); + return ESAA_ERROR_BAD_HW_ID; + } + } + cut_version = saa_system.pSAA_HW->id[2] >> 4; + if (cut_version < cut_version_min || cut_version > cut_version_max) + { + DBGEXIT(ESAA_ERROR_BAD_HW_ID); + return ESAA_ERROR_BAD_HW_ID; + } + + // check hardware host ID + for (i=0; ihost_reg.ident[i] & hw_host_id_msk[i]) != hw_host_id[i]) + { + DBGEXIT(ESAA_ERROR_BAD_HW_ID); + return ESAA_ERROR_BAD_HW_ID; + } + } + cut_version = saa_system.pSAA_HW->host_reg.ident[3] >> 4; + if (cut_version < cut_version_min || cut_version > cut_version_max) + { + DBGEXIT(ESAA_ERROR_BAD_HW_ID); + return ESAA_ERROR_BAD_HW_ID; + } + + // set the size of each dynamic data section (in kBytes) + data_size_kB = (t_uint16)(saa_system.sdram.Data16DynamicSize / 1024); + saa_system.pSAA_HW->host_reg.user_area[SAA_HOST_REG_USER_EXT16_SIZE_MSB] = (t_uint8)(data_size_kB >> 8); + saa_system.pSAA_HW->host_reg.user_area[SAA_HOST_REG_USER_EXT16_SIZE_LSB] = (t_uint8)(data_size_kB); + data_size_kB = (t_uint16)(saa_system.sdram.Data24DynamicSize / 1024); + saa_system.pSAA_HW->host_reg.user_area[SAA_HOST_REG_USER_EXT24_SIZE_MSB] = (t_uint8)(data_size_kB >> 8); + saa_system.pSAA_HW->host_reg.user_area[SAA_HOST_REG_USER_EXT24_SIZE_LSB] = (t_uint8)(data_size_kB); + data_size_kB = (t_uint16)(saa_system.esram.Data16DynamicSize / 1024); + saa_system.pSAA_HW->host_reg.user_area[SAA_HOST_REG_USER_ESRAM16_SIZE_MSB] = (t_uint8)(data_size_kB >> 8); + saa_system.pSAA_HW->host_reg.user_area[SAA_HOST_REG_USER_ESRAM16_SIZE_LSB] = (t_uint8)(data_size_kB); + data_size_kB = (t_uint16)(saa_system.esram.Data24DynamicSize / 1024); + saa_system.pSAA_HW->host_reg.user_area[SAA_HOST_REG_USER_ESRAM24_SIZE_MSB] = (t_uint8)(data_size_kB >> 8); + saa_system.pSAA_HW->host_reg.user_area[SAA_HOST_REG_USER_ESRAM24_SIZE_LSB] = (t_uint8) data_size_kB; + + saa_system.ready = FALSE; + saa_system.fw_version.version = 0; + saa_system.fw_version.major = 0; + saa_system.fw_version.minor = 0; + saa_system.pSAA_FWConfig = NULL; + + saa_system.mailbox_dl.pMsg = NULL; + saa_system.mailbox_dl.index = 0; + + saa_system.mailbox_ul.pMsg = NULL; + saa_system.mailbox_ul.index = 0; + + #ifdef SAA_USE_DOUBLE_IT + saa_system.rf_it_received = TRUE; + + saa_system.fifo_dl.unsent_msg_counter = 0; + saa_system.fifo_dl.wr_position = 0; + saa_system.fifo_dl.rd_position = 0; + #endif + + saa_system.fifo_ul.unread_msg_counter = 0; + saa_system.fifo_ul.wr_position = 0; + saa_system.fifo_ul.rd_position = 0; + + saa_system.command_number = 0; + + // STS trace library init + HTI_Init_BaseAddr((s_HTI_OSMO *)pInit->HTIBaseAddress); + + DBGEXIT(ESAA_ERROR_NONE); + + return ESAA_ERROR_NONE; +} + +/****************************************************************************/ +/* NAME: SAA_GetVersion */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: Give the current development version of this HCL. */ +/* */ +/* PARAMETERS: */ +/* IN: - */ +/* OUT: pVersion: Pointer to the version structure */ +/* RETURN: */ +/* Error code */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_saa_error SAA_GetVersion(t_version* pVersion) { + + DBGENTER1("pVersion @=0x%08lX", (t_uint32)pVersion); + + pVersion->version = SAA_HCL_VERSION_ID; + pVersion->major = SAA_HCL_MAJOR_ID; + pVersion->minor = SAA_HCL_MINOR_ID; + + DBGEXIT(ESAA_ERROR_NONE); + + return ESAA_ERROR_NONE; +} + +/****************************************************************************/ +/* NAME: SAA_GetFirmwareVersion */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: Give the current development version of the SAA firmware. */ +/* */ +/* PARAMETERS: */ +/* IN: - */ +/* OUT: pVersion: Pointer to the version structure */ +/* RETURN: */ +/* Error code */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_saa_error SAA_GetFirmwareVersion(t_version* pVersion) { + + DBGENTER1("pVersion @=0x%08lX", (t_uint32)pVersion); + + pVersion->version = saa_system.fw_version.version; + pVersion->major = saa_system.fw_version.major; + pVersion->minor = saa_system.fw_version.minor; + + DBGEXIT(ESAA_ERROR_NONE); + + return ESAA_ERROR_NONE; +} + +/****************************************************************************/ +/* NAME: SAA_GetHardwareVersion */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: Give the current development version of the SAA hardware. */ +/* */ +/* PARAMETERS: */ +/* IN: - */ +/* OUT: pVersion: Pointer to the version structure */ +/* RETURN: */ +/* Error code */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_saa_error SAA_GetHardwareVersion(t_version* pVersion) { + + DBGENTER1("pVersion @=0x%08lX", (t_uint32)pVersion); + + pVersion->version = (t_uint16)saa_system.pSAA_HW->id[0]; // TBD +// pVersion->major = ; +// pVersion->minor = ; + + DBGEXIT(ESAA_ERROR_NONE); + + return ESAA_ERROR_NONE; +} + +/****************************************************************************/ +/* NAME: SAA_SetDbgLevel */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: Set the debug output trace level. */ +/* */ +/* PARAMETERS: */ +/* IN: level: requested debug level */ +/* OUT: - */ +/* RETURN: */ +/* ESAA_ERROR_NONE */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_saa_error SAA_SetDbgLevel(t_dbg_level level) { + + DBGENTER1("level=%u", level); + + #ifdef __DEBUG + MY_DEBUG_LEVEL_VAR_NAME = level; + MY_DEBUG_ID = SAA_HCL_DBG_ID; + #endif + + DBGEXIT(ESAA_ERROR_NONE); + + return ESAA_ERROR_NONE; +} + +/****************************************************************************/ +/* NAME: SAA_DspToArmAddress */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: Convert DSP addresses into ARM adresses. */ +/* */ +/* PARAMETERS: */ +/* IN: DspAddress: DSP address to convert */ +/* OUT: - */ +/* RETURN: DSP address converted into ARM memory space */ +/* */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_uint32 SAA_DspToArmAddress(t_uint32 DspAddress) { + +#ifdef __STN_8815 + if (DspAddress >= SAA_ESRAM16_BASE) + return saa_system.esram.Data16BaseAddress + 2*(DspAddress - SAA_ESRAM16_BASE); // external memory 16 bit (ESRAM) + else if (DspAddress >= 0x800000) + return saa_system.sdram.Data16BaseAddress + 2*(DspAddress - 0x800000); // external memory 16 bit (SDRAM) + else if (DspAddress >= SAA_ESRAM24_BASE) + return saa_system.esram.Data24BaseAddress + 4*(DspAddress - SAA_ESRAM24_BASE); // external memory 24 bit (ESRAM) + else if (DspAddress >= 0x10000) + return saa_system.sdram.Data24BaseAddress + 4*(DspAddress - 0x10000); // external memory 24 bit (SDRAM) +#else + if (DspAddress >= 0x800000) + return saa_system.sdram.Data16BaseAddress + 2*(DspAddress - 0x800000); // external memory 16 bit (SDRAM) + else if (DspAddress >= 0x10000) + return saa_system.sdram.Data24BaseAddress + 4*(DspAddress - 0x10000); // external memory 24 bit (SDRAM) +#endif + else + return (t_uint32)saa_system.pSAA_HW->ram + 2*DspAddress; // internal memory +} + +/****************************************************************************/ +/* NAME: SAA_GetBankFromDspAddress */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: Give the memory bank of a DSP address. */ +/* */ +/* PARAMETERS: */ +/* IN: DspAddress: DSP address to convert */ +/* OUT: - */ +/* RETURN: Memory bank type */ +/* */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_saa_memory_bank SAA_GetBankFromDspAddress(t_uint32 DspAddress) { + +#ifdef __STN_8815 + if (DspAddress >= SAA_ESRAM16_BASE) + return ESAA_MEMORY_BANK_ESRAM; // external memory 16 bit (ESRAM) + else if (DspAddress >= 0x800000) + return ESAA_MEMORY_BANK_EXT16; // external memory 16 bit (SDRAM) + else if (DspAddress >= SAA_ESRAM24_BASE) + return ESAA_MEMORY_BANK_ESRAM; // external memory 24 bit (ESRAM) + else if (DspAddress >= 0x10000) + return ESAA_MEMORY_BANK_EXT24; // external memory 24 bit (SDRAM) +#else + if (DspAddress >= 0x800000) + return ESAA_MEMORY_BANK_EXT16; // external memory 16 bit (SDRAM) + else if (DspAddress >= 0x10000) + return ESAA_MEMORY_BANK_EXT24; // external memory 24 bit (SDRAM) +#endif + else + return ESAA_MEMORY_BANK_INTX; // internal memory +} + +/****************************************************************************/ +/* NAME: SAA_ArmToDspAddress */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: Convert ARM addresses into DSP adresses. */ +/* */ +/* PARAMETERS: */ +/* IN: ArmAddress: ARM address to convert */ +/* OUT: - */ +/* RETURN: ARM address converted into DSP memory space */ +/* */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_uint32 SAA_ArmToDspAddress(t_uint32 ArmAddress) { +#ifdef __STN_8815 + t_uint32 topEsr24; + t_uint32 topEsr16; +#endif + t_uint32 topDdr24; + t_uint32 topDdr16; + +#ifdef __STN_8815 + topEsr24 = saa_system.esram.Data24BaseAddress + ((saa_system.esram24Top - SAA_ESRAM24_BASE)*4); + topEsr16 = saa_system.esram.Data16BaseAddress + ((saa_system.esram16Top - SAA_ESRAM16_BASE)*2); +#endif + topDdr24 = saa_system.sdram.Data24BaseAddress + ((saa_system.sdram24Top - 0x10000)*4); + topDdr16 = saa_system.sdram.Data16BaseAddress + ((saa_system.sdram16Top - 0x800000)*2); + + if (ArmAddress >= (t_uint32)saa_system.pSAA_HW->ram) + return (ArmAddress - (t_uint32)saa_system.pSAA_HW->ram)/2; // internal memory +#ifdef __STN_8815 + else if (ArmAddress >= saa_system.esram.Data24BaseAddress && ArmAddress < topEsr24) + return (ArmAddress - saa_system.esram.Data24BaseAddress)/4 + SAA_ESRAM24_BASE; // external memory 24 bit (ESRAM) + else if (ArmAddress >= saa_system.esram.Data16BaseAddress && ArmAddress < topEsr16) + return (ArmAddress - saa_system.esram.Data16BaseAddress)/2 + SAA_ESRAM16_BASE; // external memory 16 bit (ESRAM) +#endif + else if (ArmAddress >= saa_system.sdram.Data24BaseAddress && ArmAddress < topDdr24) + return (ArmAddress - saa_system.sdram.Data24BaseAddress)/4 + 0x10000; // external memory 24 bit (SDRAM) + else if (ArmAddress >= saa_system.sdram.Data16BaseAddress && ArmAddress < topDdr16) + return (ArmAddress - saa_system.sdram.Data16BaseAddress)/2 + 0x800000; // external memory 16 bit (SDRAM) + else + return 0; // ??? should not get there... +} + +/****************************************************************************/ +/* NAME: SAA_GetMemoryFootprint */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: Get information about the DSP memory available in each bank.*/ +/* */ +/* PARAMETERS: */ +/* IN: - */ +/* OUT: pCmd: pointer to the command number */ +/* RETURN: */ +/* ESAA_ERROR_NONE */ +/* ESAA_ERROR_MAILBOX_DL_FIFO_OVERFLOW */ +/* ESAA_ERROR_ARM_DL_FIFO_OVERFLOW */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_saa_error SAA_GetMemoryFootprint(t_saa_cmd* pCmd) { + + t_saa_error error = ESAA_ERROR_NONE; + t_saa_cmd_desc cmd = { HA_CMD_GET_MEMORY_FOOTPRINT }; + int i; + + DBGENTER1("pCmd @=0x%08lX", (t_uint32)pCmd); + + for (i=0; iiBlockType, (t_uint32)pCmd); + + for (i=0; iiBlockType; + cmd.params[1] = (t_uint16)pBlock->params.codec.iCodecType; // iMemoryPreset in case of AEP + cmd.params[2] = (t_uint16)pBlock->iMemoryBank; + *pCmd = SAA_SendCommand(&cmd); + + DBGEXIT1(error, " (%u)", *pCmd); + + return error; +} + +/****************************************************************************/ +/* NAME: SAA_ServerBlockDelete */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: Delete an existing block. */ +/* */ +/* PARAMETERS: */ +/* IN: block_id: identifier of the block to delete */ +/* OUT: pCmd: pointer to the command number */ +/* RETURN: */ +/* ESAA_ERROR_NONE */ +/* ESAA_ERROR_MAILBOX_DL_FIFO_OVERFLOW */ +/* ESAA_ERROR_ARM_DL_FIFO_OVERFLOW */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_saa_error SAA_ServerBlockDelete(t_saa_block_id block_id, t_saa_cmd* pCmd) { + + t_saa_error error = ESAA_ERROR_NONE; + t_saa_cmd_desc cmd = { HA_CMD_DELETE_BLOCK }; + int i; + + DBGENTER2("block_id=%u, pCmd @=0x%08lX", block_id, (t_uint32)pCmd); + + for (i=0; iblock_id, pPort->direction, pPort->format, (t_uint32)pCmd); + + for (i=0; iblock_id; + cmd.params[1] = (t_uint16)pPort->direction; + cmd.params[2] = (t_uint16)pPort->format; + *pCmd = SAA_SendCommand(&cmd); + + DBGEXIT1(error, " (%u)", *pCmd); + + return error; +} + +/****************************************************************************/ +/* NAME: SAA_ServerPortDelete */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: Delete an existing port on a given block. */ +/* */ +/* PARAMETERS: */ +/* IN: block_id: identifier of the block attached to the port */ +/* IN: port_id: identifier of the port to delete */ +/* OUT: pCmd: pointer to the command number */ +/* RETURN: */ +/* ESAA_ERROR_NONE */ +/* ESAA_ERROR_MAILBOX_DL_FIFO_OVERFLOW */ +/* ESAA_ERROR_ARM_DL_FIFO_OVERFLOW */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_saa_error SAA_ServerPortDelete(t_saa_block_id block_id, t_saa_port_id port_id, t_saa_cmd* pCmd) { + + t_saa_error error = ESAA_ERROR_NONE; + t_saa_cmd_desc cmd = { HA_CMD_DELETE_PORT }; + int i; + + DBGENTER3("block_id=%u, port_id=%u, pCmd @=0x%08lX", block_id, port_id, (t_uint32)pCmd); + + for (i=0; iblock_id, (t_uint32)pCmd); + + for (i=0; iblock_id; + cmd.params[0] = (t_uint16)pConfig->params.endianess; + cmd.params[1] = (t_uint16)pConfig->params.sample_freq; + cmd.params[2] = (t_uint16)pConfig->params.channel_nb; + cmd.params[3] = (t_uint16)pConfig->params.interleaving; + cmd.params[4] = (t_uint16)pConfig->params.sample_size; + cmd.params[5] = (t_uint16)pConfig->params.real_time; + cmd.params[6] = (t_uint16)pConfig->params.buffer_size; + cmd.params[7] = (t_uint16)pConfig->params.eof_mode; + cmd.params[8] = (t_uint16)pConfig->params.memory_bank; + cmd.params[9] = (t_uint16)pConfig->params.shm_underflow_mgt; + *pCmd = SAA_SendCommand(&cmd); + + DBGEXIT1(error, " (%u)", *pCmd); + + return error; +} + +/****************************************************************************/ +/* NAME: SAA_SHMConfig */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: Configure an SHM block. */ +/* */ +/* PARAMETERS: */ +/* IN: pConfig: pointer to the SHM configuration */ +/* OUT: pCmd: pointer to the command number */ +/* RETURN: */ +/* ESAA_ERROR_NONE */ +/* ESAA_ERROR_MAILBOX_DL_FIFO_OVERFLOW */ +/* ESAA_ERROR_ARM_DL_FIFO_OVERFLOW */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_saa_error SAA_SHMConfig(t_saa_shm_config* pConfig, t_saa_cmd* pCmd) { + + t_saa_error error = ESAA_ERROR_NONE; + t_saa_cmd_desc cmd = { HA_CMD_SHM_CONFIG }; + int i; + + DBGENTER3("pConfig @=0x%08lX, block_id=%u, pCmd @=0x%08lX", (t_uint32)pConfig, pConfig->block_id, (t_uint32)pCmd); + + for (i=0; iblock_id; + cmd.params[0] = (t_uint16)pConfig->params.endianess; + cmd.params[1] = (t_uint16)pConfig->params.buffer_size; + cmd.params[2] = (t_uint16)pConfig->params.nb_buffers; + cmd.params[3] = (t_uint16)pConfig->params.eof_mode; + cmd.params[4] = (t_uint16)pConfig->params.memory_bank; + cmd.params[5] = (t_uint16)pConfig->params.channel_nb; + cmd.params[6] = (t_uint16)pConfig->params.underflow_mgt_alert; + *pCmd = SAA_SendCommand(&cmd); + + DBGEXIT1(error, " (%u)", *pCmd); + + return error; +} + +/****************************************************************************/ +/* NAME: SAA_CodecConfig */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: Configure a codec block. */ +/* */ +/* PARAMETERS: */ +/* IN: pConfig: pointer to the codec configuration */ +/* OUT: pCmd: pointer to the command number */ +/* RETURN: */ +/* ESAA_ERROR_NONE */ +/* ESAA_ERROR_MAILBOX_DL_FIFO_OVERFLOW */ +/* ESAA_ERROR_ARM_DL_FIFO_OVERFLOW */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_saa_error SAA_CodecConfig(t_saa_codec_config* pConfig, t_saa_cmd* pCmd) { + + t_saa_error error = ESAA_ERROR_NONE; + t_saa_cmd_desc cmd = { HA_CMD_CODEC_CONFIG }; + int i; + + DBGENTER3("pConfig @=0x%08lX, block_id=%u, pCmd @=0x%08lX", (t_uint32)pConfig, pConfig->block_id, (t_uint32)pCmd); + + cmd.server_id = (t_uint16)pConfig->block_id; + for (i=0; iparams.iGenericParams[i]; + } + *pCmd = SAA_SendCommand(&cmd); + + DBGEXIT1(error, " (%u)", *pCmd); + + return error; +} + +/****************************************************************************/ +/* NAME: SAA_CodecGetInfo */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: Give information about a codec block */ +/* */ +/* PARAMETERS: */ +/* IN: block_id: identifier of the codec block */ +/* OUT: pCmd: pointer to the command number */ +/* RETURN: */ +/* ESAA_ERROR_NONE */ +/* ESAA_ERROR_MAILBOX_DL_FIFO_OVERFLOW */ +/* ESAA_ERROR_ARM_DL_FIFO_OVERFLOW */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_saa_error SAA_CodecGetInfo(t_saa_block_id block_id, t_saa_cmd* pCmd) { + + t_saa_error error = ESAA_ERROR_NONE; + t_saa_cmd_desc cmd = { HA_CMD_CODEC_INFO }; + int i; + + DBGENTER2("block_id=%u, pCmd @=0x%08lX", block_id, (t_uint32)pCmd); + + for (i=0; iblock_id; + cmd.params[0] = (t_uint16)pConfig->params.mode; + cmd.params[1] = (t_uint16)pConfig->params.nb_channels; + cmd.params[2] = (t_uint16)pConfig->params.sample_freq; + cmd.params[3] = (t_uint16)pConfig->params.port_id; + cmd.params[4] = (t_uint16)pConfig->params.sample_bitsize; + cmd.params[5] = (t_uint16)pConfig->params.burst_size; + cmd.params[6] = (t_uint16)pConfig->params.underflow_trigger; + cmd.params[7] = (t_uint16)pConfig->params.alert1_group_duration; + cmd.params[8] = (t_uint16)pConfig->params.alert2_group_duration; + cmd.params[9] = (t_uint16)pConfig->params.shm_underflow_mgt; + *pCmd = SAA_SendCommand(&cmd); + + DBGEXIT1(error, " (%u)", *pCmd); + + return error; +} + +/****************************************************************************/ +/* NAME: SAA_HSIWakeUpCore */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: Request HSI to resume Audio playback bloc transmission */ +/* */ +/* PARAMETERS: */ +/* IN: block_id : HSI bloc number */ +/* port_id : Audio playback port id */ +/* OUT: pCmd: pointer to the command number */ +/* RETURN: */ +/* ESAA_ERROR_NONE */ +/* ESAA_ERROR_MAILBOX_DL_FIFO_OVERFLOW */ +/* ESAA_ERROR_ARM_DL_FIFO_OVERFLOW */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_saa_error SAA_HSIWakeUpCore(t_saa_block_id block_id, t_saa_port_id port_id, t_saa_cmd* pCmd) { + + t_saa_error error = ESAA_ERROR_NONE; + t_saa_cmd_desc cmd = { HA_CMD_WAKE_UP_CORE }; + int i; + + DBGENTER1("pCmd @=0x%08lX", (t_uint32)pCmd); + + for (i=0; imode) ? \ + HA_CMD_ENABLE_LOW_POWER : HA_CMD_DISABLE_LOW_POWER; + + cmd.params[0] = (t_uint16)pConfig->port_id; + cmd.server_id = (t_uint16)pConfig->block_id; + *pCmd = SAA_SendCommand(&cmd); + + DBGEXIT1(error, " (%u)", *pCmd); + + return error; +} + +/****************************************************************************/ +/* NAME: SAA_AEPInit */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: Initialize an AEP block */ +/* */ +/* PARAMETERS: */ +/* IN: pInit: pointer to the AEP block initialization */ +/* OUT: pCmd: pointer to the command number */ +/* RETURN: */ +/* ESAA_ERROR_NONE */ +/* ESAA_ERROR_MAILBOX_DL_FIFO_OVERFLOW */ +/* ESAA_ERROR_ARM_DL_FIFO_OVERFLOW */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_saa_error SAA_AEPInit(t_saa_aep_init* pInit, t_saa_cmd* pCmd) { + + t_saa_error error = ESAA_ERROR_NONE; + t_saa_cmd_desc cmd = { HA_CMD_AEP_CONFIG }; + int i; + + DBGENTER3("pInit @=0x%08lX, block_id=%u, pCmd @=0x%08lX", (t_uint32)pInit, pInit->block_id, (t_uint32)pCmd); + + for (i=0; iblock_id; + cmd.params[0] = (t_uint16)pInit->params.block_size; + cmd.params[1] = (t_uint16)pInit->params.aep_type; + *pCmd = SAA_SendCommand(&cmd); + + DBGEXIT1(error, " (%u)", *pCmd); + + return error; +} + +/****************************************************************************/ +/* NAME: SAA_AEPComponentCreate */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: Create a new component inside an AEP block */ +/* */ +/* PARAMETERS: */ +/* IN: pComponent: pointer to the component description */ +/* OUT: pCmd: pointer to the command number */ +/* RETURN: */ +/* ESAA_ERROR_NONE */ +/* ESAA_ERROR_MAILBOX_DL_FIFO_OVERFLOW */ +/* ESAA_ERROR_ARM_DL_FIFO_OVERFLOW */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_saa_error SAA_AEPComponentCreate(t_saa_component_desc* pComponent, t_saa_cmd* pCmd) { + + t_saa_error error = ESAA_ERROR_NONE; + t_saa_cmd_desc cmd = { HA_CMD_CREATE_COMPONENT }; + int i; + + DBGENTER4("pComponent @=0x%08lX, block_id=%u, component_type=%u, pCmd @=0x%08lX", (t_uint32)pComponent, pComponent->block_id, pComponent->component_type, (t_uint32)pCmd); + + cmd.server_id = (t_uint16)pComponent->block_id; + cmd.params[0] = (t_uint16)pComponent->component_type; + for (i=0; iparams.iGenericParams[i]; + } + *pCmd = SAA_SendCommand(&cmd); + + DBGEXIT1(error, " (%u)", *pCmd); + + return error; +} + +/****************************************************************************/ +/* NAME: SAA_AEPComponentDelete */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: Delete a component inside an AEP block */ +/* */ +/* PARAMETERS: */ +/* IN: block_id: identifier of the AEP block */ +/* IN: component_id: identifier of the component */ +/* OUT: pCmd: pointer to the command number */ +/* RETURN: */ +/* ESAA_ERROR_NONE */ +/* ESAA_ERROR_MAILBOX_DL_FIFO_OVERFLOW */ +/* ESAA_ERROR_ARM_DL_FIFO_OVERFLOW */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_saa_error SAA_AEPComponentDelete(t_saa_block_id block_id, t_saa_component_id component_id, t_saa_cmd* pCmd) { + + t_saa_error error = ESAA_ERROR_NONE; + t_saa_cmd_desc cmd = { HA_CMD_DELETE_COMPONENT }; + int i; + + DBGENTER3("block_id=%u, component_id=%u, pCmd @=0x%08lX", block_id, component_id, (t_uint32)pCmd); + + for (i=0; iblock_id, pConfig->component_id, pConfig->timestamp, (t_uint32)pCmd); + + cmd.server_id = (t_uint16)pConfig->block_id; + cmd.params[0] = (t_uint16)pConfig->component_id; + cmd.params[1] = (t_uint16)pConfig->timestamp; + + pComponent = SAA_FindComponent(pConfig->block_id, pConfig->component_id); + if (pComponent != NULL) + { + if (pComponent->dynamic_params_nb != 0) + { + pParams = (t_uint16*)pComponent->dynamic_params_address; + if (pParams != NULL) + { + for (i=0; idynamic_params_nb; i++) + *pParams++ = pConfig->params.iGenericParams[i]; + } + else + error = ESAA_ERROR_INTERNAL; // buffer could not be allocated by FW + } + } + else + error = ESAA_ERROR_INTERNAL; // component not found + + // Fill structure with extra info so that SAA_XtiTraceMsg can extract dynamic params + cmd.params[2] = (t_uint16)(pComponent->dynamic_params_address); + cmd.params[3] = (t_uint16)(pComponent->dynamic_params_address>>16); + cmd.params[4] = (t_uint16)(pComponent->dynamic_params_nb); + + *pCmd = SAA_SendCommand(&cmd); + + DBGEXIT1(error, " (%u)", *pCmd); + + return error; +} + +/****************************************************************************/ +/* NAME: SAA_AepComponentGetInfo */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: Give information about a component of an AEP block */ +/* */ +/* PARAMETERS: */ +/* IN: block_id: identifier of the codec block */ +/* IN: component_id: identifier of the component */ +/* OUT: pCmd: pointer to the command number */ +/* RETURN: */ +/* ESAA_ERROR_NONE */ +/* ESAA_ERROR_MAILBOX_DL_FIFO_OVERFLOW */ +/* ESAA_ERROR_ARM_DL_FIFO_OVERFLOW */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_saa_error SAA_AEPComponentGetInfo(t_saa_block_id block_id, t_saa_component_id component_id, t_saa_cmd* pCmd) { + + t_saa_error error = ESAA_ERROR_NONE; + t_saa_cmd_desc cmd = { HA_CMD_COMPONENT_INFO }; + int i; + + DBGENTER3("block_id=%u, component_id=%u, pCmd @=0x%08lX", block_id, component_id, (t_uint32)pCmd); + + for (i=0; i>32); + cmd.params[2] = (t_uint16)(size>>16); + cmd.params[3] = (t_uint16)size; + *pCmd = SAA_SendCommand(&cmd); + + DBGEXIT1(error, " (%u)", *pCmd); + + return error; +} + +/****************************************************************************/ +/* NAME: SAA_GetSampleCount */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: Give the total number of samples per channel in output (or */ +/* input for record) since the latest Start or Stop. */ +/* */ +/* PARAMETERS: */ +/* IN: address: address in the ARM memory space where the counters */ +/* are stored */ +/* OUT: pCount: pointer to the sample count */ +/* pFreq : pointer to the sample frequency */ +/* RETURN: */ +/* ESAA_ERROR_NONE */ +/* ESAA_ERROR_AV_UNAVAILABLE */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_saa_error SAA_GetSampleCount(t_uint32 address, t_uint32* pCount, t_saa_sample_freq* pFreq) { + + t_saa_error error = ESAA_ERROR_NONE; + t_saa_fw_av_zone* pAVZone = (t_saa_fw_av_zone*)address; + t_saa_fw_av_zone32* pAVZone32 = (t_saa_fw_av_zone32*)address; + t_uint64 value[2]; + t_uint32 dsp_address = SAA_ArmToDspAddress(address); + t_saa_memory_bank memory_bank = SAA_GetBankFromDspAddress(dsp_address); + + DBGENTER3("address=%lu, pCount @=0x%08lX, pFreq @=0x%08lX", address, (t_uint32)pCount, (t_uint32)pFreq); + + switch (memory_bank) + { + case ESAA_MEMORY_BANK_INTX: + case ESAA_MEMORY_BANK_INTY: + case ESAA_MEMORY_BANK_EXT16: + value[0] = ((t_uint64)pAVZone->sample_counter.high << 32) | ((t_uint32)pAVZone->sample_counter.mid << 16) | pAVZone->sample_counter.low; + // read twice (no semaphore to protect the counter zone !) + value[1] = ((t_uint64)pAVZone->sample_counter.high << 32) | ((t_uint32)pAVZone->sample_counter.mid << 16) | pAVZone->sample_counter.low; + + if (value[0] == value[1]) { + *pCount = (t_uint32)value[1]; + if (pAVZone->nb_channels != 0) + *pCount /= pAVZone->nb_channels; + } + else error = ESAA_ERROR_AV_UNAVAILABLE; // value has been modified by firmware + + *pFreq = (t_saa_sample_freq)pAVZone->sample_freq; + break; + + case ESAA_MEMORY_BANK_EXT24: + case ESAA_MEMORY_BANK_ESRAM: // ESRAM24 is assumed + value[0] = ((t_uint64)pAVZone32->sample_counter.high << 32) | ((t_uint32)pAVZone32->sample_counter.mid << 16) | pAVZone32->sample_counter.low; + // read twice (no semaphore to protect the counter zone !) + value[1] = ((t_uint64)pAVZone32->sample_counter.high << 32) | ((t_uint32)pAVZone32->sample_counter.mid << 16) | pAVZone32->sample_counter.low; + + if (value[0] == value[1]) { + *pCount = (t_uint32)value[1]; + if (pAVZone32->nb_channels != 0) + *pCount /= pAVZone32->nb_channels; + } + else error = ESAA_ERROR_AV_UNAVAILABLE; // value has been modified by firmware + + *pFreq = (t_saa_sample_freq)pAVZone32->sample_freq; + break; + + default: + error = ESAA_ERROR_AV_UNAVAILABLE; // unknown memory bank => access method undefined + } + + DBGEXIT1(error, " (%lu)", *pCount); + + return error; +} + +/****************************************************************************/ +/* NAME: SAA_LocateDebugZone */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: Retrieve the address and size of the firmware debug zone. */ +/* */ +/* PARAMETERS: */ +/* OUT: pCmd: pointer to the command number */ +/* RETURN: */ +/* ESAA_ERROR_NONE */ +/* ESAA_ERROR_MAILBOX_DL_FIFO_OVERFLOW */ +/* ESAA_ERROR_ARM_DL_FIFO_OVERFLOW */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_saa_error SAA_LocateDebugZone(t_saa_cmd* pCmd) +{ + t_saa_error error = ESAA_ERROR_NONE; + t_saa_cmd_desc cmd = { HA_CMD_LOCATE_DEBUG_ZONE }; + int i; + + DBGENTER1("pCmd @=0x%08lX", (t_uint32)pCmd); + + for (i=0; i> 16); + cmd.params[1] = (t_uint16)core_freq; + cmd.params[2] = time_slice; + cmd.params[3] = auto_reset; + *pCmd = SAA_SendCommand(&cmd); + + DBGEXIT1(error, " (%u)", *pCmd); + + return error; +} + +/****************************************************************************/ +/* NAME: SAA_CycleEstimationStart */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: Start the timer used to compute cycle consumption and */ +/* enable the flag to save the results. */ +/* */ +/* PARAMETERS: */ +/* OUT: pCmd: pointer to the command number */ +/* RETURN: */ +/* ESAA_ERROR_NONE */ +/* ESAA_ERROR_MAILBOX_DL_FIFO_OVERFLOW */ +/* ESAA_ERROR_ARM_DL_FIFO_OVERFLOW */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_saa_error SAA_CycleEstimationStart(t_saa_cmd* pCmd) +{ + t_saa_error error = ESAA_ERROR_NONE; + t_saa_cmd_desc cmd = { HA_CMD_START_CYCLE_ESTIMATION }; + int i; + + DBGENTER1("pCmd @=0x%08lX", (t_uint32)pCmd); + + for (i=0; i> 16); + cmd.params[2] = (t_uint16)buffer_address; + cmd.params[3] = (t_uint16)frame_size; + cmd.params[4] = (t_uint16)bfi; + cmd_nb = SAA_SendCommand(&cmd); + (void)cmd_nb; + + DBGEXIT1(error, " (%u)", cmd_nb); + + return error; +} + +/****************************************************************************/ +/* NAME: SAA_SHMBufferReleased */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: Signal to the SAA firmware that the buffer has been used. */ +/* */ +/* PARAMETERS: */ +/* IN: block_id: identifier of the block */ +/* IN: transfer_nb: transfer number */ +/* IN: buffer_address: address of buffer in shared memory */ +/* IN: frame_size: size of useful data frame in the buffer */ +/* RETURN: */ +/* ESAA_ERROR_NONE */ +/* ESAA_ERROR_MAILBOX_DL_FIFO_OVERFLOW */ +/* ESAA_ERROR_ARM_DL_FIFO_OVERFLOW */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_saa_error SAA_SHMBufferReleased(t_saa_block_id block_id, t_uint16 transfer_nb, t_uint32 buffer_address, t_uint16 frame_size) +{ + t_saa_error error = ESAA_ERROR_NONE; + t_saa_cmd_desc cmd = { HA_CMD_SHM_BUFFER_RELEASED }; + t_saa_cmd cmd_nb; + int i; + + DBGENTER4("block_id=%u, transfer_nb=%u, buffer_address=%lu, frame_size=%u", block_id, transfer_nb, buffer_address, frame_size); + + for (i=0; i> 16); + cmd.params[2] = (t_uint16)buffer_address; + cmd.params[3] = (t_uint16)frame_size; + cmd_nb = SAA_SendCommand(&cmd); + (void)cmd_nb; + + DBGEXIT1(error, " (%u)", cmd_nb); + + return error; +} + +/****************************************************************************/ +/* NAME: SAA_SlowModeEnable */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: Request Low Power mode to the SAA. */ +/* */ +/* PARAMETERS: */ +/* IN: block_id: identifier of the output block */ +/* IN: buffer_size: size of the transfer buffer */ +/* IN: watermark_level: number of bytes in the transfer buffer */ +/* that when reached, triggers the switch back to normal mode */ +/* OUT: pCmd: pointer to the command number */ +/* RETURN: */ +/* ESAA_ERROR_NONE */ +/* ESAA_ERROR_MAILBOX_DL_FIFO_OVERFLOW */ +/* ESAA_ERROR_ARM_DL_FIFO_OVERFLOW */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_saa_error SAA_SlowModeEnable(t_saa_block_id block_id, t_uint32 buffer_size, t_uint16 watermark_level, t_saa_cmd* pCmd) +{ + t_saa_error error = ESAA_ERROR_NONE; + t_saa_cmd_desc cmd = { HA_CMD_ENABLE_SLOW_MODE }; + int i; + + DBGENTER3("block_id=%u, buffer_size=%lu, watermark_level=%u", block_id, buffer_size, watermark_level); + + for (i=0; i>16); + cmd.params[1] = (t_uint16)buffer_size; + cmd.params[2] = (t_uint16)watermark_level; + *pCmd = SAA_SendCommand(&cmd); + + DBGEXIT1(error, " (%u)", *pCmd); + + return error; +} + +/****************************************************************************/ +/* NAME: SAA_SlowModeDisable */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: Request switch to Normal mode to the SAA. */ +/* */ +/* PARAMETERS: */ +/* IN: block_id: identifier of the output block */ +/* OUT: pCmd: pointer to the command number */ +/* RETURN: */ +/* ESAA_ERROR_NONE */ +/* ESAA_ERROR_MAILBOX_DL_FIFO_OVERFLOW */ +/* ESAA_ERROR_ARM_DL_FIFO_OVERFLOW */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_saa_error SAA_SlowModeDisable(t_saa_block_id block_id, t_saa_cmd* pCmd) +{ + t_saa_error error = ESAA_ERROR_NONE; + t_saa_cmd_desc cmd = { HA_CMD_DISABLE_SLOW_MODE }; + int i; + + DBGENTER1("pCmd @=0x%08lX", (t_uint32)pCmd); + + for (i=0; i. */ +/*---------------------------------------------------------------------------*/ + +#ifndef __INC_SAA_H +#define __INC_SAA_H + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +/*--------------------------------------------------------------------------* + * Includes * + *--------------------------------------------------------------------------*/ +#include "hcl_defs.h" +#include "debug.h" +#include "ha_api_params.h" +#include "ha_codec_params.h" +#include "ha_effect_params.h" + + +/*--------------------------------------------------------------------------* + * Defines * + *--------------------------------------------------------------------------*/ +#define SAA_HCL_VERSION_ID 2 +#define SAA_HCL_MAJOR_ID 11 +#define SAA_HCL_MINOR_ID 0 + +#define SAA_ESRAM16_BASE 0xF60000UL +#define SAA_ESRAM24_BASE 0x400000UL +/*--------------------------------------------------------------------------* + * Exported types * +*--------------------------------------------------------------------------*/ +typedef t_uint16 t_hsem_id; + +typedef struct { + t_logical_address Data16BaseAddress; + t_uint32 Data16DynamicSize; + t_logical_address Data24BaseAddress; + t_uint32 Data24DynamicSize; +} t_saa_memory_map; + +typedef struct { + t_logical_address SAABaseAddress; + + t_saa_memory_map sdram; + t_saa_memory_map esram; + + t_bool useHSEM; + t_logical_address HSEMBaseAddress; + t_hsem_id ul; + t_hsem_id dl; + + t_logical_address HTIBaseAddress; + +} t_saa_init; + +typedef t_uint16 t_saa_cmd; + +typedef t_uint16 t_saa_command_id; + +typedef t_uint16 t_saa_server_id; + +typedef t_uint16 t_saa_block_id; + +typedef t_uint16 t_saa_port_id; + +typedef struct { + t_saa_block_type iBlockType; + union { + struct { + t_saa_codec_type iCodecType; + } codec; + struct { + t_saa_memory_preset iMemoryPreset; + } aep; + } params; + t_saa_memory_bank iMemoryBank; +} t_saa_block_desc; + +typedef struct { + t_saa_block_id block_id; + t_saa_codec_params params; +} t_saa_codec_config; + +typedef enum { + ESAA_IRQ_UNKNOWN, + ESAA_IRQ_0, + ESAA_IRQ_1, + ESAA_HSEM_UL, + ESAA_HSEM_DL +} t_saa_irq_num; + +typedef enum { + ESAA_SRC_UNKNOWN, + ESAA_SRC_IRQ_0, + ESAA_SRC_IRQ_1, + ESAA_SRC_HSEM_UL, + ESAA_SRC_HSEM_DL +} t_saa_irq_src; + +typedef struct { + t_saa_block_id block_id; + t_saa_port_type direction; + t_saa_port_data_type format; +} t_saa_port_desc; + +typedef struct { + t_saa_block_id block_id; + t_saa_dma_params params; +} t_saa_dma_config; + +typedef struct { + t_saa_block_id block_id; + t_saa_shm_params params; +} t_saa_shm_config; + +typedef struct { + t_saa_block_id block_id; + t_saa_shm_transfer_params params; +} t_saa_shm_transfer; + +typedef struct { + t_saa_block_id block_id; + t_saa_hsi_params params; +} t_saa_hsi_port_config; + +typedef struct { + t_saa_block_id block_id; + t_uint16 port_id; + t_uint16 mode; +} t_saa_hsi_use_low_power_mode; + +typedef struct { + t_saa_block_id block_id; + t_saa_aep_params params; +} t_saa_aep_init; + +typedef t_uint16 t_saa_component_id; + +typedef struct { + t_saa_block_id block_id; + t_saa_aep_comp component_type; + t_saa_component_static_params params; +} t_saa_component_desc; + +typedef struct { + t_saa_block_id block_id; + t_saa_component_id component_id; + t_uint16 timestamp; + t_saa_component_dynamic_params params; +} t_saa_component_config; + +typedef struct { + t_saa_command_id command_id; + t_saa_server_id server_id; + t_uint16 params[SAA_MSG_NB_PARAM]; +} t_saa_cmd_desc; + +typedef struct { + t_uint16 params[SAA_MSG_SIZE - 1]; +} t_saa_event_desc; + +typedef enum { + ESAA_ERROR_NONE = 0, + ESAA_ERROR_BAD_HW_ID, + ESAA_ERROR_BAD_HSEM, + ESAA_ERROR_COMPATIBILITY, + ESAA_ERROR_NO_MORE_PENDING_EVENT, + ESAA_ERROR_NO_PENDING_EVENT, + ESAA_ERROR_ARM_DL_FIFO_OVERFLOW, + ESAA_ERROR_ARM_UL_FIFO_OVERFLOW, + ESAA_ERROR_MAILBOX_DL_FIFO_OVERFLOW, + ESAA_ERROR_AV_UNAVAILABLE, + ESAA_ERROR_INTERNAL, + ESAA_ERROR_INIT_MEMORY +} t_saa_error; + + +/*--------------------------------------------------------------------------* + * Exported functions * + *--------------------------------------------------------------------------*/ + +// Initialization, Close, Versioning, Debug +PUBLIC t_saa_error SAA_Init(t_saa_init* pInit); +PUBLIC t_saa_error SAA_GetVersion(t_version* pVersion); +PUBLIC t_saa_error SAA_GetFirmwareVersion(t_version* pVersion); +PUBLIC t_saa_error SAA_GetHardwareVersion(t_version* pVersion); +PUBLIC t_saa_error SAA_SetDbgLevel(t_dbg_level level); +PUBLIC t_saa_error SAA_Close(void); + +// Memory management +PUBLIC t_uint32 SAA_DspToArmAddress(t_uint32 DspAddress); +PUBLIC t_saa_memory_bank SAA_GetBankFromDspAddress(t_uint32 DspAddress); +PUBLIC t_uint32 SAA_ArmToDspAddress(t_uint32 ArmAddress); +PUBLIC t_saa_error SAA_GetMemoryFootprint(t_saa_cmd* pCmd); + +// Network creation +PUBLIC t_saa_error SAA_ServerBlockCreate(t_saa_block_desc* pBlock, t_saa_cmd* pCmd); +PUBLIC t_saa_error SAA_ServerBlockDelete(t_saa_block_id block_id, t_saa_cmd* pCmd); +PUBLIC t_saa_error SAA_ServerPortCreate(t_saa_port_desc* pPort, t_saa_cmd* pCmd); +PUBLIC t_saa_error SAA_ServerPortDelete(t_saa_block_id block_id, t_saa_port_id port_id, t_saa_cmd* pCmd); +PUBLIC t_saa_error SAA_ServerBlockFreeze(t_saa_block_id block_id, t_saa_cmd* pCmd); +PUBLIC t_saa_error SAA_ServerPortConnect(t_saa_block_id block_id_src, t_saa_port_id port_id_src, t_saa_block_id block_id_dest, t_saa_port_id port_id_dest, t_saa_memory_bank memory_bank, t_saa_cmd* pCmd); +PUBLIC t_saa_error SAA_ServerPortDisconnect(t_saa_block_id block_id_src, t_saa_port_id port_id_src, t_saa_block_id block_id_dest, t_saa_port_id port_id_dest, t_saa_cmd* pCmd); +PUBLIC t_saa_error SAA_ServerNetworkUpdate(t_saa_cmd* pCmd); +PUBLIC t_saa_error SAA_ServerBlockPrioritySet(t_saa_block_id block_id, t_saa_priority_level priority, t_saa_cmd* pCmd); + +// Server information +PUBLIC t_saa_error SAA_ServerGetCapabilities(/*TBD*/ t_saa_cmd* pCmd); + +// Configuration +PUBLIC t_saa_error SAA_DMAConfig(t_saa_dma_config* pConfig, t_saa_cmd* pCmd); +PUBLIC t_saa_error SAA_SHMConfig(t_saa_shm_config* pConfig, t_saa_cmd* pCmd); +PUBLIC t_saa_error SAA_CodecConfig(t_saa_codec_config* pConfig, t_saa_cmd* pCmd); +PUBLIC t_saa_error SAA_CodecGetInfo(t_saa_block_id block_id, t_saa_cmd* pCmd); +PUBLIC t_saa_error SAA_HSIReset(t_saa_block_id block_id, t_saa_cmd* pCmd); +PUBLIC t_saa_error SAA_HSIPortConfig(t_saa_hsi_port_config* pConfig, t_saa_cmd* pCmd); +PUBLIC t_saa_error SAA_HSIUseLowPowerMode(t_saa_hsi_use_low_power_mode* pConfig, t_saa_cmd* pCmd); + +// AEP handling +PUBLIC t_saa_error SAA_AEPInit(t_saa_aep_init* pInit, t_saa_cmd* pCmd); +PUBLIC t_saa_error SAA_AEPComponentCreate(t_saa_component_desc* pComponent, t_saa_cmd* pCmd); +PUBLIC t_saa_error SAA_AEPComponentDelete(t_saa_block_id block_id, t_saa_component_id component_id, t_saa_cmd* pCmd); +PUBLIC t_saa_error SAA_AEPComponentConnect(t_saa_block_id block_id, t_saa_component_id cp_id_src, t_saa_component_id cp_id_dest, t_saa_cmd* pCmd); +PUBLIC t_saa_error SAA_AEPComponentDisconnect(t_saa_block_id block_id, t_saa_component_id cp_id_src, t_saa_component_id cp_id_dest, t_saa_cmd* pCmd); +PUBLIC t_saa_error SAA_AEPComponentConfig(t_saa_component_config* pConfig, t_saa_cmd* pCmd); +PUBLIC t_saa_error SAA_AEPComponentGetInfo(t_saa_block_id block_id, t_saa_component_id component_id, t_saa_cmd* pCmd); + +// Flow processing +PUBLIC t_saa_error SAA_FlowStart(t_saa_block_id block_id, t_saa_port_id port_id, t_saa_cmd* pCmd); +PUBLIC t_saa_error SAA_FlowStartResetEof(t_saa_block_id block_id, t_saa_port_id port_id, t_saa_cmd* pCmd); +PUBLIC t_saa_error SAA_FlowPause(t_saa_block_id block_id, t_saa_port_id port_id, t_saa_cmd* pCmd); +PUBLIC t_saa_error SAA_FlowUnPause(t_saa_block_id block_id, t_saa_port_id port_id, t_saa_cmd* pCmd); +PUBLIC t_saa_error SAA_FlowStop(t_saa_block_id block_id, t_saa_port_id port_id, t_saa_stop_mode stop_mode, t_saa_cmd* pCmd); +PUBLIC t_saa_error SAA_FlowSetEofSize(t_saa_block_id block_id, t_saa_port_id port_id, t_uint64 size, t_saa_cmd* pCmd); + +PUBLIC t_saa_error SAA_GetSampleCount(t_uint32 address, t_uint32* pCount, t_saa_sample_freq* pFreq); + +// Interrupt and event management +PUBLIC t_saa_irq_src SAA_GetIRQSrc(t_saa_irq_num irq_num); +PUBLIC void SAA_ClearIRQSrc(t_saa_irq_src irq_src); +PUBLIC void SAA_EnableIRQSrc(t_saa_irq_src irq_src); +PUBLIC void SAA_DisableIRQSrc(t_saa_irq_src irq_src); +PUBLIC t_bool SAA_IsPendingIRQSrc(t_saa_irq_src irq_src); +PUBLIC t_saa_irq_num SAA_GetDeviceId(t_saa_irq_src irq_src); +PUBLIC t_bool SAA_IsIRQSrcActive(t_saa_irq_src irq_src); +PUBLIC t_saa_error SAA_GetIRQSrcStatus(t_saa_irq_src irq_src); +PUBLIC t_saa_error SAA_GetPendingEvent(t_saa_event_desc* pEvent, t_uint16* pNbMsgStored); + +// HSI Low power management +PUBLIC t_saa_error SAA_HSIWakeUpCore(t_saa_block_id block_id, t_saa_port_id port_id, t_saa_cmd* pCmd); + +PUBLIC t_uint16 SAA_SendCommand(t_saa_cmd_desc* pCmd); + +// Performance measurement +PUBLIC t_saa_error SAA_LocateDebugZone(t_saa_cmd* pCmd); +PUBLIC t_saa_error SAA_CycleEstimationEnable(t_saa_cmd* pCmd); +PUBLIC t_saa_error SAA_CycleEstimationInit(t_uint32 core_freq, t_uint16 time_slice, t_uint16 auto_reset, t_saa_cmd* pCmd); +PUBLIC t_saa_error SAA_CycleEstimationStart(t_saa_cmd* pCmd); +PUBLIC t_saa_error SAA_CycleEstimationStop(t_saa_cmd* pCmd); +PUBLIC t_saa_error SAA_CycleEstimationGetInfo(t_saa_block_id block_id, t_saa_cmd* pCmd); +PUBLIC t_saa_error SAA_CycleEstimationReset(t_saa_block_id block_id, t_saa_cmd* pCmd); +PUBLIC t_saa_error SAA_CycleEstimationDisable(t_saa_cmd* pCmd); +PUBLIC t_saa_error SAA_CycleEstimationAddBlock(t_saa_block_id block_id, t_saa_cmd* pCmd); +PUBLIC t_saa_error SAA_CycleEstimationRemoveBlock(t_saa_block_id block_id, t_saa_cmd* pCmd); +PUBLIC t_saa_error SAA_PerformancesEstimation(t_saa_block_id block_id, t_uint16 unit, t_saa_cmd* pCmd); + +// HTI Trace +PUBLIC t_saa_error SAA_TraceHclEnable(void); +PUBLIC t_saa_error SAA_TraceHclDisable(void); +PUBLIC t_saa_error SAA_TraceHcl(t_bool enable); +PUBLIC t_saa_error SAA_TraceFwEnable(t_saa_block_id block_id, t_uint8 aep_comp_mask, t_uint8 mask, t_saa_cmd* pCmd); +PUBLIC t_saa_error SAA_TraceFwDisable(t_saa_block_id block_id, t_uint8 aep_comp_mask, t_uint8 mask, t_saa_cmd* pCmd); + +// Shared memory management +PUBLIC t_saa_error SAA_SHMBufferReady(t_saa_block_id block_id, t_uint16 transfer_nb, t_uint32 buffer_address, t_uint16 frame_size, t_uint16 bfi); +PUBLIC t_saa_error SAA_SHMBufferReleased(t_saa_block_id block_id, t_uint16 transfer_nb, t_uint32 buffer_address, t_uint16 frame_size); + +// SAA Low power management +PUBLIC t_saa_error SAA_SlowModeEnable(t_saa_block_id block_id, t_uint32 buffer_size, t_uint16 watermark_level, t_saa_cmd* pCmd); +PUBLIC t_saa_error SAA_SlowModeDisable(t_saa_block_id block_id, t_saa_cmd* pCmd); +PUBLIC t_saa_error SAA_SlowSpeedReached(t_saa_block_id block_id); +PUBLIC t_saa_error SAA_NormalSpeedReached(t_saa_block_id block_id); +PUBLIC t_saa_error SAA_SwitchSpeed(t_saa_block_id block_id, t_saa_cmd* pCmd); + +#ifdef __cplusplus +} +#endif // __cplusplus + +#endif // __INC_SAA_H --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/saa_base.c @@ -0,0 +1,557 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ + +/*--------------------------------------------------------------------------* + * Includes * + *--------------------------------------------------------------------------*/ +#include "saa_hwp.h" +#include "saap.h" +#include "hti.h" +#include "hti_protocol.h" + + +/*--------------------------------------------------------------------------* + * Global variables * + *--------------------------------------------------------------------------*/ +t_saa_system saa_system; +t_bool saa_hcl_hti_trace = FALSE; + + +/*--------------------------------------------------------------------------* + * Private data * + *--------------------------------------------------------------------------*/ + +/*--------------------------------------------------------------------------* + * Public functions * + *--------------------------------------------------------------------------*/ + +/****************************************************************************/ +/* NAME: SAA_InitSharedMailboxes */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: Set the address of the shared uplink & downlink mailboxes. */ +/* Called once when the first interrupt is received. */ +/* */ +/* PARAMETERS: */ +/* IN: - */ +/* OUT: - */ +/* RETURN: */ +/* None */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC void SAA_InitSharedMailboxes(void) { + + volatile t_uint16* ptr; + t_uint32 offset; + t_uint32 host_address = (t_uint32)&saa_system.pSAA_HW->host_reg; + t_uint32 ram_address = (t_uint32)saa_system.pSAA_HW->ram; + + // build the uplink shared mailbox address + ptr = (t_uint16*)(host_address + 2*HOST_HA_MBX_UP_ADD_1); + offset = (t_uint32)(*ptr) & 0xFF; + ptr = (t_uint16*)(host_address + 2*HOST_HA_MBX_UP_ADD_2); + offset <<= 8; + offset |= (t_uint32)(*ptr) & 0xFF; + ptr = (t_uint16*)(host_address + 2*HOST_HA_MBX_UP_ADD_3); + offset <<= 8; + offset |= (t_uint32)(*ptr) & 0xFF; + offset <<= 1; + saa_system.mailbox_ul.pMsg = (t_saa_message*)(ram_address + offset); + + // build the downlink shared mailbox address + ptr = (t_uint16*)(host_address + 2*HOST_HA_MBX_DOWN_ADD_1); + offset = (t_uint32)(*ptr) & 0xFF; + ptr = (t_uint16*)(host_address + 2*HOST_HA_MBX_DOWN_ADD_2); + offset <<= 8; + offset |= (t_uint32)(*ptr) & 0xFF; + ptr = (t_uint16*)(host_address + 2*HOST_HA_MBX_DOWN_ADD_3); + offset <<= 8; + offset |= (t_uint32)(*ptr) & 0xFF; + offset <<= 1; + saa_system.mailbox_dl.pMsg = (t_saa_message*)(ram_address + offset); +} + +/****************************************************************************/ +/* NAME: SAA_SendCommand */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: Send a command to the SAA/MMDSP. */ +/* */ +/* PARAMETERS: */ +/* IN: pCmd: pointer to the command description */ +/* OUT: - */ +/* RETURN: */ +/* command number>0 if successful, 0 otherwise */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_uint16 SAA_SendCommand(t_saa_cmd_desc* pCmd) { + + t_saa_message new_message; + #ifdef SAA_USE_DOUBLE_IT + t_saa_message message; + int nb_msg_sent = 0; + #endif + int i; + + new_message.command_number = (t_uint16)(saa_system.command_number + 1); + new_message.command_id = pCmd->command_id; + new_message.server_id = pCmd->server_id; + + for (i=0; iparams[i]; + } + + if (++saa_system.command_number == 0xFFFF) + saa_system.command_number = 0; // avoid 16-bit roll-over of next command number (answer/alert mismatch) + + #ifndef SAA_USE_DOUBLE_IT + if (SAA_PutMessage(&new_message)) + { + // send the write finished interrupt to SAA/MMDSP + saa_system.pSAA_HW->host_reg.cmd[1] ^= 1; + + return new_message.command_number; + } + #else + SAA_DisableIRQSrc(ESAA_SRC_IRQ_1); + // check if ARM is waiting for a read finished interrupt + if(saa_system.rf_it_received){ + // copy all messages from ARM downlink local FIFO to downlink shared mailbox + while ((nb_msg_sent < SAA_MBX_DOWN_SIZE)&&(SAA_PopFromLocalFifoDL(&message))){ + (void)SAA_PutMessage(&message); + nb_msg_sent ++; + } + + if (SAA_PutMessage(&new_message)){ + // a read finished interrupt will be received + saa_system.rf_it_received = FALSE; + + // send the write finished interrupt to SAA/MMDSP + saa_system.pSAA_HW->host_reg.cmd[1] ^= 1; + SAA_EnableIRQSrc(ESAA_SRC_IRQ_1); + return new_message.command_number; + } + + if(nb_msg_sent != 0){ + // a read finished interrupt will be received + saa_system.rf_it_received = FALSE; + + // send the write finished interrupt to SAA/MMDSP + saa_system.pSAA_HW->host_reg.cmd[1] ^= 1; + } + } + + // write new message to ARM downlink local FIFO + if (SAA_PushToLocalFifoDL(&new_message)){ + SAA_EnableIRQSrc(ESAA_SRC_IRQ_1); + return new_message.command_number; + } + SAA_EnableIRQSrc(ESAA_SRC_IRQ_1); + #endif + + return 0; +} + +/****************************************************************************/ +/* NAME: SAA_PutMessage */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: Put a message in the shared downlink mailbox. */ +/* */ +/* PARAMETERS: */ +/* IN: pMsg: pointer to the message description */ +/* OUT: - */ +/* RETURN: */ +/* TRUE if successful, FALSE otherwise */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_bool SAA_PutMessage(t_saa_message* pMsg) { + + t_saa_message* pNewMsg; + int i; + #ifndef SAA_USE_DOUBLE_IT + volatile t_uint32 *host_address = (t_uint32 *)&saa_system.pSAA_HW->host_reg; + #endif + + if (saa_system.mailbox_dl.pMsg == NULL) + return FALSE; + + pNewMsg = saa_system.mailbox_dl.pMsg + saa_system.mailbox_dl.index; + + if ((pNewMsg->semaphore & 0x00FF) == 0) { + pNewMsg->command_number = pMsg->command_number; + pNewMsg->command_id = pMsg->command_id; + pNewMsg->server_id = pMsg->server_id; + + for (i=0; iparams[i] = pMsg->params[i]; + } + + if (++saa_system.mailbox_dl.index == SAA_MBX_DOWN_SIZE) + saa_system.mailbox_dl.index = 0; + + #ifndef SAA_USE_DOUBLE_IT + while (host_address[HOST_HA_CMD1_SEM] != 0) {} + host_address[HOST_HA_CMD1_SEM] = 1; + #endif + + pNewMsg->semaphore |= 0x0001; + + if (saa_hcl_hti_trace) + SAA_HtiTraceMsg(ESAA_DOWN_MSG, pMsg); + + return TRUE; + } + + return FALSE; +} + +/****************************************************************************/ +/* NAME: SAA_GetMessage */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: Get a message from the shared uplink mailbox. */ +/* */ +/* PARAMETERS: */ +/* IN: - */ +/* OUT: pMsg: pointer to the message description */ +/* RETURN: */ +/* TRUE if successful, FALSE otherwise */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_bool SAA_GetMessage(t_saa_message* pMsg) { + + t_saa_message* pNextMsg; + int i; + + if (saa_system.mailbox_ul.pMsg == NULL) + return FALSE; + + pNextMsg = saa_system.mailbox_ul.pMsg + saa_system.mailbox_ul.index; + + if ((pNextMsg->semaphore & 0x00FF) == 0) + return FALSE; + + if (++saa_system.mailbox_ul.index == SAA_MBX_UP_SIZE) + saa_system.mailbox_ul.index = 0; + + pMsg->command_number = pNextMsg->command_number; + pMsg->command_id = pNextMsg->command_id; + pMsg->semaphore = pNextMsg->semaphore; + pMsg->server_id = pNextMsg->server_id; + + for (i=0; iparams[i] = pNextMsg->params[i]; + } + + pNextMsg->semaphore &= 0xFF00; + + return TRUE; +} + +/****************************************************************************/ +/* NAME: SAA_PushToLocalFifoUL */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: Push a message to the ARM uplink local FIFO. */ +/* */ +/* PARAMETERS: */ +/* IN: pMsg: pointer to the message description */ +/* OUT: - */ +/* RETURN: */ +/* TRUE if successful, FALSE otherwise */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_bool SAA_PushToLocalFifoUL(t_saa_message* pMsg) { + + t_saa_fifo_ul* pFifoUL = &saa_system.fifo_ul; + + // check if FIFO is not full + if (pFifoUL->unread_msg_counter < SAA_FIFO_UL_SIZE) { + pFifoUL->message[pFifoUL->wr_position] = *pMsg; + + pFifoUL->unread_msg_counter++; + + if (++pFifoUL->wr_position == SAA_FIFO_UL_SIZE) + pFifoUL->wr_position = 0; + + return TRUE; + } + + return FALSE; +} + +/****************************************************************************/ +/* NAME: SAA_PopFromLocalFifoUL */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: Pop a message from the ARM uplink local FIFO. */ +/* */ +/* PARAMETERS: */ +/* IN: - */ +/* OUT: pMsg: pointer to the message description */ +/* RETURN: */ +/* TRUE if successful, FALSE otherwise */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_bool SAA_PopFromLocalFifoUL(t_saa_message* pMsg) { + + t_saa_fifo_ul* pFifoUL = &saa_system.fifo_ul; + + // check if FIFO is not empty + if (pFifoUL->unread_msg_counter) { + *pMsg = pFifoUL->message[pFifoUL->rd_position]; + + pFifoUL->unread_msg_counter--; + + if (++pFifoUL->rd_position == SAA_FIFO_UL_SIZE) + pFifoUL->rd_position = 0; + + if (saa_hcl_hti_trace) + SAA_HtiTraceMsg(ESAA_UP_MSG, pMsg); + + return TRUE; + } + + return FALSE; +} + +#ifdef SAA_USE_DOUBLE_IT +/****************************************************************************/ +/* NAME: SAA_PushToLocalFifoDL */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: Push a message to the ARM local downlink FIFO. */ +/* */ +/* PARAMETERS: */ +/* IN: pMsg: pointer to the message description */ +/* OUT: - */ +/* RETURN: */ +/* TRUE if successful, FALSE otherwise */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_bool SAA_PushToLocalFifoDL(t_saa_message* pMsg) { + + t_saa_fifo_dl* pFifoDL = &saa_system.fifo_dl; + + // check if FIFO is not full + if (pFifoDL->unsent_msg_counter < SAA_FIFO_DL_SIZE) { + pFifoDL->message[pFifoDL->wr_position] = *pMsg; + + pFifoDL->unsent_msg_counter++; + + if (++pFifoDL->wr_position == SAA_FIFO_DL_SIZE) + pFifoDL->wr_position = 0; + + return TRUE; + } + + return FALSE; +} + +/****************************************************************************/ +/* NAME: SAA_PopFromLocalFifoDL */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: Pop a message from the ARM local downlink FIFO. */ +/* */ +/* PARAMETERS: */ +/* IN: - */ +/* OUT: pMsg: pointer to the message description */ +/* RETURN: */ +/* TRUE if successful, FALSE otherwise */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_bool SAA_PopFromLocalFifoDL(t_saa_message* pMsg) { + + t_saa_fifo_dl* pFifoDL = &saa_system.fifo_dl; + + // check if FIFO is not empty + if (pFifoDL->unsent_msg_counter) { + *pMsg = pFifoDL->message[pFifoDL->rd_position]; + + pFifoDL->unsent_msg_counter--; + + if (++pFifoDL->rd_position == SAA_FIFO_DL_SIZE) + pFifoDL->rd_position = 0; + + return TRUE; + } + + return FALSE; +} +#endif + +/****************************************************************************/ +/* NAME: SAA_NewComponent */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: Find a new entry in the component table. */ +/* */ +/* PARAMETERS: */ +/* IN: - */ +/* OUT: - */ +/* RETURN: */ +/* pointer to new entry if successful, NULL otherwise */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_saa_component_entry* SAA_NewComponent(void) { + + t_saa_component_entry* pComponent = saa_system.component; + int i; + + for (i=0; iblock_id == 0) + return pComponent; + } + + return NULL; +} + +/****************************************************************************/ +/* NAME: SAA_FindComponent */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: Find a given component. */ +/* */ +/* PARAMETERS: */ +/* IN: block_id: identifier of the block */ +/* component_id: identifier of the component */ +/* OUT: - */ +/* RETURN: */ +/* pointer to entry if successful, NULL otherwise */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_saa_component_entry* SAA_FindComponent(t_saa_block_id block_id, t_saa_component_id component_id) { + + t_saa_component_entry* pComponent = saa_system.component; + int i; + + for (i=0; iblock_id == block_id && pComponent->component_id == component_id) + { + return pComponent; + } + } + + return NULL; +} + +/****************************************************************************/ +/* NAME: SAA_FreeComponent */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: Free an existing component. */ +/* */ +/* PARAMETERS: */ +/* IN: block_id: identifier of the block */ +/* component_id: identifier of the component */ +/* OUT: - */ +/* RETURN: */ +/* pointer to old entry if successful, NULL otherwise */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_saa_component_entry* SAA_FreeComponent(t_saa_block_id block_id, t_saa_component_id component_id) { + + t_saa_component_entry* pComponent = saa_system.component; + int i; + + for (i=0; iblock_id == block_id && pComponent->component_id == component_id) + { + pComponent->block_id = 0; + return pComponent; + } + } + + return NULL; +} + +/****************************************************************************/ +/* NAME: SAA_FreeAllComponents */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: Free all components of an existing block. */ +/* */ +/* PARAMETERS: */ +/* IN: block_id: identifier of the block */ +/* OUT: - */ +/* RETURN: */ +/* Number of components freed */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_uint16 SAA_FreeAllComponents(t_saa_block_id block_id) { + + t_saa_component_entry* pComponent = saa_system.component; + t_uint16 nb_components = 0; + int i; + + for (i=0; iblock_id == block_id) + { + pComponent->block_id = 0; + nb_components++; + } + } + + return nb_components; +} + +/****************************************************************************/ +/* NAME: SAA_HtiTraceMsg */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: Sends a message to the HTI debug port. */ +/* */ +/* PARAMETERS: */ +/* IN: msg_dir: direction of message (uplink/downlink) */ +/* pMsg: pointer to the message to be sent */ +/* OUT: - */ +/* RETURN: void */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ + + +PUBLIC void SAA_HtiTraceMsg(t_saa_msg_dir msg_dir, t_saa_message* pMsg) +{ + t_uint16* pDynParams; + + HTI_CMD_SAA_HCL(SAA_HCL_HTI_CHANNEL); + + if ((pMsg->command_id==HA_CMD_CONFIG_COMPONENT) && (msg_dir==ESAA_DOWN_MSG)){ + HtiSend_8(SAA_HCL_HTI_CHANNEL, msg_dir + 0XF0); // specify not standart message + HtiSendn_32(SAA_HCL_HTI_CHANNEL,(const HTI_U32 *)pMsg, 3); //semaphore command_number server_id command_id params[0] params[1] + pDynParams = (t_uint16*)(((t_uint32)pMsg->params[3])<<16 | pMsg->params[2]); // param address + HtiSend_16(SAA_HCL_HTI_CHANNEL, pMsg->params[4]); // nb param + HtiSendn_16(SAA_HCL_HTI_CHANNEL, pDynParams, pMsg->params[4]); + } + else{ + HtiSend_8(SAA_HCL_HTI_CHANNEL, msg_dir); + HtiSendn_32(SAA_HCL_HTI_CHANNEL, (const HTI_U32 *)pMsg, sizeof(t_saa_message)/ sizeof(int)); + + } + HTI_CMD_END_OF_CHANNEL(SAA_HCL_HTI_CHANNEL); + + +} + --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/saa_hwp.h @@ -0,0 +1,275 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ + +#ifndef __INC_SAA_HWP_H +#define __INC_SAA_HWP_H + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +/*--------------------------------------------------------------------------* + * Includes * + *--------------------------------------------------------------------------*/ +#include "hcl_defs.h" +#include "ha_api_params.h" + + +/*--------------------------------------------------------------------------* + * Defines * + *--------------------------------------------------------------------------*/ +#define SAA_NB_BLOCK_RAM 8 +#define SAA_RAM_BLOCK_SIZE 4096 /* 0x1000 */ +#define SAA_NB_IO 8 +#define SAA_NB_TIMER 2 +#define SAA_NB_BIT_SEM 8 +#define SAA_NB_DMA 8 +#define SAA_NB_ITREMAP_REG 32 +#define SAA_HOST_USER_SIZE 192 /* 0xC0 */ + +// macro to convert host register index from absolute to user_area relative (array of t_saa_host_reg) +#define SAA_HOST_REG_USER_INDEX(reg_offset) (reg_offset - 0x40) + +// user host registers for memory available +#define SAA_HOST_REG_USER_EXT16_SIZE_MSB SAA_HOST_REG_USER_INDEX(HOST_SAA_EXT16_SIZE_MSB) +#define SAA_HOST_REG_USER_EXT16_SIZE_LSB SAA_HOST_REG_USER_INDEX(HOST_SAA_EXT16_SIZE_LSB) +#define SAA_HOST_REG_USER_EXT24_SIZE_MSB SAA_HOST_REG_USER_INDEX(HOST_SAA_EXT24_SIZE_MSB) +#define SAA_HOST_REG_USER_EXT24_SIZE_LSB SAA_HOST_REG_USER_INDEX(HOST_SAA_EXT24_SIZE_LSB) +#define SAA_HOST_REG_USER_ESRAM16_SIZE_MSB SAA_HOST_REG_USER_INDEX(HOST_SAA_ESRAM16_SIZE_MSB) +#define SAA_HOST_REG_USER_ESRAM16_SIZE_LSB SAA_HOST_REG_USER_INDEX(HOST_SAA_ESRAM16_SIZE_LSB) +#define SAA_HOST_REG_USER_ESRAM24_SIZE_MSB SAA_HOST_REG_USER_INDEX(HOST_SAA_ESRAM24_SIZE_MSB) +#define SAA_HOST_REG_USER_ESRAM24_SIZE_LSB SAA_HOST_REG_USER_INDEX(HOST_SAA_ESRAM24_SIZE_LSB) + + +/*--------------------------------------------------------------------------* + * Exported types * + *--------------------------------------------------------------------------*/ + +/* TIMER Registers */ + typedef volatile struct { + t_uint32 timer_msb; + t_uint32 timer_lsb; +} t_saa_timer_reg; + + +/* DMA interface Registers */ +typedef volatile struct { + t_uint16 arm_dma_sreq; /* dma0: 5e800, dma1: +0x20 ...*/ + t_uint16 arm_dma_breq; /* ... 5e802 */ + t_uint16 arm_dma_lsreq; /* ... 5e804 */ + t_uint16 arm_dma_lbreq; + t_uint16 arm_dma_maskit; + t_uint16 arm_dma_it; + t_uint16 arm_dma_auto; + t_uint16 arm_dma_lauto; + t_uint16 dma_reserved[8]; +} t_saa_dma_reg; + + +/* HOST Registers */ +typedef volatile struct { + t_uint16 ident[5]; /*0x...60000*/ + t_uint16 r5; /*0x...6000a*/ + t_uint16 r6; /*0x...6000c*/ + t_uint16 inte0; /*0x...6000e*/ + t_uint16 inte1; /*0x...60010*/ + t_uint16 int0; /*0x...60012*/ + t_uint16 int1; /*0x...60014*/ + t_uint16 int_ris0; /*0x...60016*/ + t_uint16 int_ris1; /*0x...60018*/ + t_uint16 intpol; /*0x...6001a*/ + t_uint16 RESERVED0; /*0x...6001c*/ + t_uint16 reserved1; /*0x...6001e*/ + t_uint16 softreset; /*0x...60020*/ + t_uint16 int_icr0; /*0x...60022*/ + t_uint16 int_icr1; /*0x...60024*/ + t_uint16 cmd[4]; /*0x...60026*/ + t_uint16 RESERVED4; + t_uint16 int_mis0; /*0x...60030*/ + t_uint16 RESERVED5; + t_uint16 RESERVED6; + t_uint16 RESERVED7; + t_uint16 i2cdiv; /*0x...60038*/ + t_uint16 int_mis1; /*0x...6003a*/ + t_uint16 RESERVED8; + t_uint16 RESERVED9; + t_uint16 emul_udata[8]; /*0x...60040*/ + t_uint16 emul_uaddrl; /*0x...60050*/ + t_uint16 emul_uaddrh; /*0x...60052*/ + t_uint16 emul_ucmd; /*0x...60054*/ + t_uint16 emul_ubkcmd; /*0x...60056*/ + t_uint16 emul_bk2addl; /*0x...60058*/ + t_uint16 emul_bk2addh; /*0x...6005a*/ + t_uint16 emul_pc_stack; /*0x...6005c*/ + t_uint16 emul_mdata0; /*0x...6005e*/ + t_uint16 emul_mdata1; /*0x...60060*/ + t_uint16 emul_mdata2; /*0x...60062*/ + t_uint16 emul_maddl; /*0x...60064*/ + t_uint16 emul_maddh; /*0x...60066*/ + t_uint16 emul_mcmd; /*0x...60068*/ + t_uint16 emul_bk_ref_src; /*0x...6006a*/ + t_uint16 emul_bk_ref_dst; /*0x...6006c*/ + t_uint16 emul_bk_eql; /*0x...6006e*/ + t_uint16 emul_bk_eqh; /*0x...60070*/ + t_uint16 emul_bk_combi; /*0x...60072*/ + t_uint16 emul_clockcmd; /*0x...60074*/ + t_uint16 emul_stepcmd; /*0x...60076*/ + t_uint16 emul_scanreg; /*0x...60078*/ + t_uint16 emul_breakcountl; /*0x...6007a*/ + t_uint16 emul_breakcounth; /*0x...6007c*/ + t_uint16 emul_forcescan; /*0x...6007e*/ + t_uint16 user_area[SAA_HOST_USER_SIZE]; +} t_saa_host_reg; + + +/* Smart Audio Accelerator Hardware memory map */ +typedef volatile struct { + t_uint16 ram[SAA_NB_BLOCK_RAM][SAA_RAM_BLOCK_SIZE]; /* ... 40000 -> 4fffe */ + + t_uint16 RESERVED_1[(0x5e000 - (0x40000 + 2*SAA_NB_BLOCK_RAM*SAA_RAM_BLOCK_SIZE))/2]; + + t_uint32 io_bit[SAA_NB_IO]; /* ... 5e000 -> 5e01c */ + + t_uint16 RESERVED_2[(0x5e048 - (0x5e000 + 4*SAA_NB_IO))/2]; + + t_uint32 io_all; /* ... 5e048 */ + t_uint32 io_en; /* ... 5e04c */ + + t_uint16 RESERVED_3[(0x5e060 - (0x5e04c + 4))/2]; + + t_saa_timer_reg timer[SAA_NB_TIMER]; /* ... 5e060 -> 5e074 */ + + t_uint16 RESERVED_4[(0x5e400 - (0x5e060 + sizeof(t_saa_timer_reg)*SAA_NB_TIMER))/2]; + + t_uint16 cfg_tim_low; /* ... 5e400 */ + t_uint16 cfg_tim_high; /* ... 5e402 */ + t_uint16 tim_low; /* ... 5e404 */ + t_uint16 tim_high; /* ... 5e406 */ + t_uint16 rtc_comp0_low; /* ... 5e408 */ + t_uint16 rtc_comp0_high; /* ... 5e40a */ + t_uint32 rtc_enable_it; /* ... 5e40c */ + t_uint32 sem_bit[SAA_NB_BIT_SEM]; /* ... 5e410 -> 5e42c */ + + t_uint16 RESERVED_5[(0x5e450 - (0x5e410 + 4*SAA_NB_BIT_SEM))/2]; + + t_uint32 hamaca_ipen; /* ... 5e450 */ + t_uint16 hamaca_itip[4]; /* ... 5e454 -> 5e45a */ + t_uint16 hamaca_itop[4]; /* ... 5e45c -> 5e462 */ + + t_uint16 RESERVED_6[(0x5e7e0 - (0x5e45c + 2*4))/2]; + + t_uint32 id[8]; /* ... 5e7e0 */ + t_saa_dma_reg dma[SAA_NB_DMA]; /* ... 5e800 -> 5e8ee */ + + t_uint16 RESERVED_7[(0x5ec00 - (0x5e800 + sizeof(t_saa_dma_reg)*SAA_NB_DMA))/2]; + + t_uint16 emu_unit_maskit; /* ... 5ec00 */ + + t_uint16 RESERVED_8[(0x5ec10 - (0x5ec00 + 2))/2]; + + t_uint32 config_data_mem; /* ... 5ec10 */ + t_uint16 compatibility; /* ... 5ec14 */ + + t_uint16 RESERVED_9[(0x5f000 - (0x5ec14 + 2))/2]; + + t_uint16 ahb_if_config; /* ... 5f000 */ + t_uint16 ahb_if_mode; /* ... 5f002 */ + t_uint16 ahb_if_status; /* ... 5f004 */ + t_uint16 ahb_if_security; /* ... 5f006 */ + + t_uint16 RESERVED_10[(0x5fc00 - (0x5f006 + 2))/2]; + + t_uint32 itremap_reg[SAA_NB_ITREMAP_REG]; /* ... 5fc00 -> 5fc7c */ + t_uint32 itmsk_l_reg; /* ... 5fc80 */ + t_uint32 itmsk_h_reg; /* ... 5fc84 */ + + t_uint16 RESERVED_11[(0x5fc9c - (0x5fc84 + 4))/2]; + + t_uint32 itmemo_l_reg; /* ... 5fc9c */ + t_uint32 itmeme_h_reg; /* ... 5fca0 */ + + t_uint16 RESERVED_12[(0x60000 - (0x5fca0 + 4))/2]; + + t_saa_host_reg host_reg; /* ... 60000 */ + +} t_saa_hw; + + +/* Communication zone with firmware: Message format */ +typedef volatile struct { + t_uint16 semaphore; // header + t_uint16 command_number; // tag + t_uint16 server_id; + t_uint16 command_id; + t_uint16 params[SAA_MSG_NB_PARAM]; +} t_saa_message; +#define T_SAA_MESSAGE_SIZE (sizeof(t_uint16) * (4 + SAA_MSG_NB_PARAM)) // avoid gcc alignment issue + + +/* Communication zone with SAA firmware: General configuration */ +typedef volatile struct { + t_uint16 id_version; + t_uint16 id_build; + t_uint16 ram_size; + t_uint16 mips; + t_uint16 nb_services; + t_uint16 first_service; +} t_saa_fw_config_zone; + + +/* Communication zone with SAA firmware: Audio/Video synchronization */ +typedef volatile struct { + + struct { + t_uint16 high; + t_uint16 mid; + t_uint16 low; + } sample_counter; + + t_uint16 nb_channels; + + t_uint16 sample_freq; + +} t_saa_fw_av_zone; + +typedef volatile struct { + + struct { + t_uint16 high; + t_uint16 reserved0; + t_uint16 mid; + t_uint16 reserved1; + t_uint16 low; + t_uint16 reserved2; + } sample_counter; + + t_uint16 nb_channels; + t_uint16 reserved3; + + t_uint16 sample_freq; + t_uint16 reserved4; + +} t_saa_fw_av_zone32; + + +#ifdef __cplusplus +} +#endif // __cplusplus + +#endif // __INC_SAA_HWP_H --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/saa_irq.c @@ -0,0 +1,432 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ + +/*--------------------------------------------------------------------------* + * Includes * + *--------------------------------------------------------------------------*/ +#include "saap.h" + + +/*--------------------------------------------------------------------------* + * Global variables * + *--------------------------------------------------------------------------*/ + + +/*--------------------------------------------------------------------------* + * Private data * + *--------------------------------------------------------------------------*/ + + +/*--------------------------------------------------------------------------* + * Public functions * + *--------------------------------------------------------------------------*/ + +/****************************************************************************/ +/* NAME: SAA_GetIRQSrc */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: Gets the first IRQ source identifier available. */ +/* */ +/* PARAMETERS: */ +/* IN: irq_num: SAA or HSEM IRQ identifier */ +/* OUT: - */ +/* RETURN: */ +/* SAA IRQ source identifier */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_saa_irq_src SAA_GetIRQSrc(t_saa_irq_num irq_num) { + + switch (irq_num) { + case ESAA_IRQ_0: + return ESAA_SRC_IRQ_0; + + case ESAA_IRQ_1: + return ESAA_SRC_IRQ_1; + + case ESAA_HSEM_UL: + return ESAA_SRC_HSEM_UL; + + case ESAA_HSEM_DL: + return ESAA_SRC_HSEM_DL; + + default: + return ESAA_SRC_UNKNOWN; + } +} + +/****************************************************************************/ +/* NAME: SAA_ClearIRQSrc */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: Acknowledges an interrupt source. */ +/* */ +/* PARAMETERS: */ +/* IN: irq_src: SAA IRQ source identifier */ +/* OUT: - */ +/* RETURN: */ +/* None */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC void SAA_ClearIRQSrc(t_saa_irq_src irq_src) { + + switch (irq_src) { + case ESAA_SRC_IRQ_0: + (void)saa_system.pSAA_HW->host_reg.int0; + break; + + case ESAA_SRC_IRQ_1: + (void)saa_system.pSAA_HW->host_reg.int1; + break; + + default: + // do nothing + break; + } +} + +/****************************************************************************/ +/* NAME: SAA_EnableIRQSrc */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: Enables a given interrupt source (HW level mask). */ +/* */ +/* PARAMETERS: */ +/* IN: irq_src: SAA IRQ source identifier */ +/* OUT: - */ +/* RETURN: */ +/* None */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC void SAA_EnableIRQSrc(t_saa_irq_src irq_src) { + + switch (irq_src) { + case ESAA_SRC_IRQ_0: + saa_system.pSAA_HW->host_reg.inte0 |= 1<<0; + break; + + case ESAA_SRC_IRQ_1: + saa_system.pSAA_HW->host_reg.inte1 |= 1<<0; + break; + + default: + // do nothing + break; + } +} + +/****************************************************************************/ +/* NAME: SAA_DisableIRQSrc */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: Disables a given interrupt source (HW level mask). */ +/* */ +/* PARAMETERS: */ +/* IN: irq_src: SAA IRQ source identifier */ +/* OUT: - */ +/* RETURN: */ +/* None */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC void SAA_DisableIRQSrc(t_saa_irq_src irq_src) { + + switch (irq_src) { + case ESAA_SRC_IRQ_0: + saa_system.pSAA_HW->host_reg.inte0 &= ~(1<<0); + break; + + case ESAA_SRC_IRQ_1: + saa_system.pSAA_HW->host_reg.inte1 &= ~(1<<0); + break; + + default: + // do nothing + break; + } +} + +/****************************************************************************/ +/* NAME: SAA_IsPendingIRQSrc */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: Checks whether a given interrupt source is pending or not. */ +/* */ +/* PARAMETERS: */ +/* IN: irq_src: SAA IRQ source identifier */ +/* OUT: - */ +/* RETURN: */ +/* TRUE if the interrupt source is pending */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_bool SAA_IsPendingIRQSrc(t_saa_irq_src irq_src) { + + switch (irq_src) { + case ESAA_SRC_IRQ_0: + return (t_bool)(saa_system.pSAA_HW->host_reg.int_ris0 & (1<<0)); + + case ESAA_SRC_IRQ_1: + return (t_bool)(saa_system.pSAA_HW->host_reg.int_ris1 & (1<<0)); + + default: + // do nothing + break; + } + + return FALSE; +} + +/****************************************************************************/ +/* NAME: SAA_GetDeviceId */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: Gets the device identifier that have raised a given */ +/* interrupt source. */ +/* */ +/* PARAMETERS: */ +/* IN: irq_src: SAA IRQ source identifier */ +/* OUT: - */ +/* RETURN: */ +/* SAA or HSEM IRQ identifier */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_saa_irq_num SAA_GetDeviceId(t_saa_irq_src irq_src) { + + switch (irq_src) { + case ESAA_SRC_IRQ_0: + return ESAA_IRQ_0; + + case ESAA_SRC_IRQ_1: + return ESAA_IRQ_1; + + case ESAA_SRC_HSEM_UL: + return ESAA_HSEM_UL; + + case ESAA_SRC_HSEM_DL: + return ESAA_HSEM_DL; + + default: + return ESAA_IRQ_UNKNOWN; + } +} + +/****************************************************************************/ +/* NAME: SAA_IsIRQSrcActive */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: Checks whether an interrupt source is active or not. */ +/* */ +/* PARAMETERS: */ +/* IN: irq_src: SAA IRQ source identifier */ +/* OUT: - */ +/* RETURN: */ +/* TRUE if the interrupt source is active */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_bool SAA_IsIRQSrcActive(t_saa_irq_src irq_src) { + + // TBD + + return TRUE; +} + +/****************************************************************************/ +/* NAME: SAA_GetIRQSrcStatus */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: Manages and updates the ARM uplink/downlink FIFOs. */ +/* */ +/* PARAMETERS: */ +/* IN: irq_src: SAA IRQ source identifier */ +/* OUT: - */ +/* RETURN: */ +/* ESAA_ERROR_NONE */ +/* ESAA_ERROR_MAILBOX_DL_FIFO_OVERFLOW */ +/* ESAA_ERROR_ARM_UL_FIFO_OVERFLOW */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_saa_error SAA_GetIRQSrcStatus(t_saa_irq_src irq_src) { + + t_saa_error error = ESAA_ERROR_NONE; + t_saa_message message; + t_saa_component_entry* pComponent; + int nb_msg_sent = 0; + + DBGENTER1("irq_src=%u", irq_src); + + switch (irq_src) { + case ESAA_SRC_IRQ_0: + if (saa_system.mailbox_dl.pMsg == NULL || saa_system.mailbox_ul.pMsg == NULL) + SAA_InitSharedMailboxes(); + + // get the new message(s) from the shared uplink mailbox + while (SAA_GetMessage(&message)) { + // push the message to the ARM uplink FIFO + if (SAA_PushToLocalFifoUL(&message)) { + // handle the message contents + if (message.command_number != 0) { + // this is an answer to a command + switch (message.command_id) { + case HA_CMD_CREATE_COMPONENT: + pComponent = SAA_NewComponent(); + if (pComponent != NULL) + { + pComponent->block_id = message.server_id; + pComponent->component_id = message.params[1]; + pComponent->dynamic_params_address = SAA_DspToArmAddress(((t_uint32)message.params[2] << 16) | message.params[3]); + pComponent->dynamic_params_nb = message.params[6] / 2; // size of buffer is in bytes + } + else + error = ESAA_ERROR_INTERNAL; + break; + + default: + // do nothing + break; + } + } else { + // this is an alert + switch (message.command_id) { + case ESAA_FW_ALERT_BOOT_FINISHED: + saa_system.ready = TRUE; + saa_system.pSAA_FWConfig = (t_saa_fw_config_zone*)SAA_DspToArmAddress(((t_uint32)message.params[0] << 16) | message.params[1]); + saa_system.fw_version.version = ((message.params[2])>>11) & 0x1F; + saa_system.fw_version.major = ((message.params[2])>>6) & 0x1F; + saa_system.fw_version.minor = (message.params[2]) & 0x2F; + saa_system.sdram24Top = ((message.params[3]) << 16) | (message.params[4] & 0xFFFF); + saa_system.sdram16Top = ((message.params[5]) << 16) | (message.params[6] & 0xFFFF); + saa_system.esram24Top = ((message.params[7]) << 16) | (message.params[8] & 0xFFFF); + saa_system.esram16Top = ((message.params[9]) << 16) | (message.params[10] & 0xFFFF); + // TO BE REMOVED if OS do not use this + message.params[6] = saa_system.fw_version.minor; + message.params[5] = saa_system.fw_version.major; + message.params[4] = saa_system.fw_version.version; + message.params[3] = message.params[1]; + message.params[2] = message.params[0]; + message.params[1] = 0; +#ifdef __STN_8815 + if((!saa_system.sdram24Top) || (!saa_system.sdram16Top) || (!saa_system.esram24Top) || (!saa_system.esram16Top)){ +#else + if((!saa_system.sdram24Top) || (!saa_system.sdram16Top)){ +#endif + error = ESAA_ERROR_INIT_MEMORY; + } + message.params[0] = error; + break; + + default: + // do nothing + break; + } + } + } + else error = ESAA_ERROR_ARM_UL_FIFO_OVERFLOW; + } + + #ifdef SAA_USE_DOUBLE_IT + // send the read finished interrupt to SAA/MMDSP + saa_system.pSAA_HW->host_reg.cmd[2] ^= 1; + #endif + + break; + + case ESAA_SRC_IRQ_1: + #ifdef SAA_USE_DOUBLE_IT + // if FIFO not empty, copy all messages from ARM downlink local FIFO to downlink shared mailbox + while ((nb_msg_sent < SAA_MBX_DOWN_SIZE)&&(SAA_PopFromLocalFifoDL(&message))){ + (void)SAA_PutMessage(&message); + nb_msg_sent ++; + } + if(nb_msg_sent != 0){ + // a read finished interrupt will be received + saa_system.rf_it_received = FALSE; + + // send the write finished interrupt to SAA/MMDSP + saa_system.pSAA_HW->host_reg.cmd[1] ^= 1; + } + else{ + // no more read finished interrupt to receive + saa_system.rf_it_received = TRUE; + } + #endif + break; + + default: + // do nothing + break; + } + + DBGEXIT0(error); + + return error; +} + +/****************************************************************************/ +/* NAME: SAA_GetPendingEvent */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: Provides (one by one) all the pending events by popping the */ +/* oldest event from the ARM uplink FIFO. */ +/* */ +/* PARAMETERS: */ +/* IN: - */ +/* OUT: pEvent: pointer to the event description */ +/* OUT: pNbMsgStored: pointer to the number of messages stored in */ +/* the ARM uplink FIFO */ +/* RETURN: */ +/* ESAA_ERROR_NONE */ +/* ESAA_ERROR_NO_MORE_PENDING_EVENT */ +/* ESAA_ERROR_NO_PENDING_EVENT */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_saa_error SAA_GetPendingEvent(t_saa_event_desc* pEvent, t_uint16* pNbMsgStored) { + + t_saa_error error = ESAA_ERROR_NONE; + t_saa_fifo_ul* pFifoUL = &saa_system.fifo_ul; + t_uint16* pParam = &pEvent->params[0]; + t_saa_message message; + unsigned int i; + + DBGENTER2("pEvent @=0x%08lX, pNbMsgStored @=0x%08lX", (t_uint32)pEvent, (t_uint32)pNbMsgStored); + + *pNbMsgStored = pFifoUL->unread_msg_counter; + + if (*pNbMsgStored == 1) + error = ESAA_ERROR_NO_MORE_PENDING_EVENT; + + // pop the oldest message from the ARM uplink FIFO + if (SAA_PopFromLocalFifoUL(&message)) { + // copy message to event + *pParam++ = message.command_number; + *pParam++ = message.server_id; + *pParam++ = message.command_id; + for (i=0; i. */ +/*---------------------------------------------------------------------------*/ + +#ifndef __INC_SAAP_H +#define __INC_SAAP_H + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + + +/*--------------------------------------------------------------------------* + * Includes * + *--------------------------------------------------------------------------*/ +#include "hcl_defs.h" +#include "saa_hwp.h" +#include "ha_hcl_fw_interface.h" +#include "saa.h" + + +/*--------------------------------------------------------------------------* + * Defines * + *--------------------------------------------------------------------------*/ +#define SAA_SERVER_ID 0 + +#define SAA_FIFO_DL_SIZE 10 // maximum number of messages for the ARM downlink FIFO +#define SAA_FIFO_UL_SIZE 30 // maximum number of messages for the ARM uplink FIFO + +#define SAA_USE_DOUBLE_IT + +#define SAA_NB_MAX_COMPONENT 100 + +#define SAA_HCL_HTI_CHANNEL 235 + +/*--------------------------------------------------------------------------* + * Macros * + *--------------------------------------------------------------------------*/ + + +/*--------------------------------------------------------------------------* + * Exported types * + *--------------------------------------------------------------------------*/ + +typedef enum { + ESAA_UP_MSG, + ESAA_DOWN_MSG +} t_saa_msg_dir; + +typedef struct { + t_saa_message* pMsg; // pointer to current message in the shared mailbox + t_uint16 index; +} t_saa_shared_mailbox; + +typedef struct { + t_saa_message message[SAA_FIFO_DL_SIZE]; + t_uint16 unsent_msg_counter; + t_uint16 wr_position; // index of next message to write + t_uint16 rd_position; // index of next message to read +} t_saa_fifo_dl; + +typedef struct { + t_saa_message message[SAA_FIFO_UL_SIZE]; + t_uint16 unread_msg_counter; + t_uint16 wr_position; // index of next message to write + t_uint16 rd_position; // index of next message to read +} t_saa_fifo_ul; + +typedef struct { + t_saa_block_id block_id; // ID of EAP block (0 if not used) + t_saa_component_id component_id; // ID of component + t_uint32 dynamic_params_address; // address of buffer (in ARM memory space) + t_uint16 dynamic_params_nb; // number of parameters in buffer (16-bit each) +} t_saa_component_entry; + +typedef struct { + t_uint32 saa_base_address; + + t_saa_memory_map sdram; + t_saa_memory_map esram; + + t_saa_hw* pSAA_HW; + volatile t_bool ready; + t_version fw_version; + t_saa_fw_config_zone* pSAA_FWConfig; + + t_saa_shared_mailbox mailbox_dl; // downlink shared mailbox: from ARM to SAA + t_saa_shared_mailbox mailbox_ul; // uplink shared mailbox: from SAA to ARM + + #ifdef SAA_USE_DOUBLE_IT + t_bool rf_it_received; // read finished interrupt flag + t_saa_fifo_dl fifo_dl; // ARM downlink local FIFO + #endif + t_saa_fifo_ul fifo_ul; // ARM uplink local FIFO + + t_uint16 command_number; + + t_saa_component_entry component[SAA_NB_MAX_COMPONENT]; + t_uint32 sdram24Top; // last valid address dsp side + t_uint32 sdram16Top; // last valid address dsp side + t_uint32 esram24Top; // last valid address dsp side + t_uint32 esram16Top; // last valid address dsp side +} t_saa_system; + + +/*--------------------------------------------------------------------------* + * Exported variables * + *--------------------------------------------------------------------------*/ +#define MY_DEBUG_LEVEL_VAR_NAME myDebugLevel_SAA +#define MY_DEBUG_ID myDebugID_SAA + +extern t_dbg_level MY_DEBUG_LEVEL_VAR_NAME; +extern t_dbg_id MY_DEBUG_ID; + +extern t_saa_system saa_system; +extern t_bool saa_hcl_hti_trace; + + +/*--------------------------------------------------------------------------* + * Exported functions * + *--------------------------------------------------------------------------*/ +PUBLIC void SAA_InitSharedMailboxes(void); +PUBLIC t_uint16 SAA_SendCommand(t_saa_cmd_desc* pCmd); + +PUBLIC t_bool SAA_PutMessage(t_saa_message* pMsg); +PUBLIC t_bool SAA_GetMessage(t_saa_message* pMsg); + +PUBLIC t_bool SAA_PushToLocalFifoUL(t_saa_message* pMsg); +PUBLIC t_bool SAA_PopFromLocalFifoUL(t_saa_message* pMsg); +#ifdef SAA_USE_DOUBLE_IT +PUBLIC t_bool SAA_PushToLocalFifoDL(t_saa_message* pMsg); +PUBLIC t_bool SAA_PopFromLocalFifoDL(t_saa_message* pMsg); +#endif +PUBLIC t_saa_component_entry* SAA_NewComponent(void); +PUBLIC t_saa_component_entry* SAA_FindComponent(t_saa_block_id block_id, t_saa_component_id component_id); +PUBLIC t_saa_component_entry* SAA_FreeComponent(t_saa_block_id block_id, t_saa_component_id component_id); +PUBLIC t_uint16 SAA_FreeAllComponents(t_saa_block_id block_id); + +PUBLIC void SAA_HtiTraceMsg(t_saa_msg_dir msg_dir, t_saa_message* pMsg); + +#ifdef __cplusplus +} +#endif // __cplusplus + +#endif // __INC_SAAP_H --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/common/sva_capabilities.c @@ -0,0 +1,63 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ + +#include "hcl_defs.h" +#include "sva.h" +#include "sva_capabilities.h" + +/*------------------------------------------------------------------------ + * Private Macros + *----------------------------------------------------------------------*/ + + +/*------------------------------------------------------------------------ + * Global Variables + *----------------------------------------------------------------------*/ + + +/****************************************************************************/ +/* NAME: t_sva_error SVA_GetCapabilities( */ +/* tp_sva_capabilities *pCapabilities */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine provides the capabilities of the sva (HW/FW/HCL) */ +/* */ +/* PARAMETERS: */ +/* IN : none */ +/* */ +/* OUT : */ +/* - pCapabilities: return address of capabilities structure */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/* - SVA_OK */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_sva_error SVA_GetCapabilities( +tp_sva_capabilities *pCapabilities +) +{ + HCL_ASSERT(pCapabilities!=NULL); + + return SVA_OK; +} + +// End of file - sva_capabilities.c --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/common/sva_capabilities.h @@ -0,0 +1,46 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ + +#ifndef __INC_SVA_CAPABILITIES_H +#define __INC_SVA_CAPABILITIES_H + +#include "hcl_defs.h" +#include "sva.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/******************************************************************************/ +/* Types definitions */ +/******************************************************************************/ + + +/******************************************************************************* +* PUBLIC Functions +*******************************************************************************/ + + + +#ifdef __cplusplus +} /* allow C++ to use these headers */ +#endif /* __cplusplus */ + +#endif /* __INC_HV_CAPABILITIES_H */ +/* End of file - sva_capabilities.h */ --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/common/sva_fifo.h @@ -0,0 +1,335 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ + +#ifndef __INC_SVA_FIFO_H +#define __INC_SVA_FIFO_H + +#include "hcl_defs.h" +#include "sva_internalneeds.h" +#include "svap.h" + +/******************************************************************************/ +/* Constants definitions */ +/******************************************************************************/ +/* + * Definition of the macro providing the memory needs + * to build a fifo of elements with the type + * Takes 3 params: + * - typeName: C type of the fifo element (width of the fifo) + * - nbElem: size (depth/height) of the fifo + * - (output) computed memory needs size + */ +#define GET_FIFO_MEMORY_NEEDS(typeName, nbElem, memoryNeedsSize) \ + do { \ + t_uint16 mask = MASK_BIT10; \ + while(((t_uint16)(nbElem) & mask) == 0) {mask >>=1;} \ + if ((nbElem) > mask) {mask <<= 1;} \ + memoryNeedsSize = (t_uint16)(mask * sizeof(typeName)); \ + /* align on word boundary */ \ + if ((memoryNeedsSize % 4)!=0) \ + {memoryNeedsSize += (4-(memoryNeedsSize % 4));} \ + } while(0) + +/* + * Definition of the macro allowing to define a fifo descriptor to its default value + * Takes 1 param: + * - fifoDesc: Fifo descriptor to init + */ +#define INIT_FIFO(fifoDesc) \ + do { \ + fifoDesc.readIndex = 0; \ + fifoDesc.writeIndex = 0; \ + fifoDesc.elemCount = 0; \ + fifoDesc.indexMask = 0; \ + fifoDesc.baseAddr = (t_logical_address)0; \ + } while(0) + +/* + * Definition of the macro allowing to create a new fifo (dynamically allocated) + * Takes 4 params: + * - typeName: C type of the fifo element (width of the fifo) + * - nbElem: size (depth/height) of the fifo + * - fifoDesc: Fifo descriptor to update + * - (output) error: raised error or SVA_FIFO_OK + */ +#define CREATE_FIFO(typeName, nbElem, fifoDesc, error) \ + do { \ + t_uint16 mask = MASK_BIT10; \ + fifoDesc.readIndex = 0; \ + fifoDesc.writeIndex = 0; \ + fifoDesc.elemCount = 0; \ + fifoDesc.indexMask = 0; \ + fifoDesc.baseAddr = (t_logical_address)0; \ + error=SVA_FIFO_ERROR; \ + if ((nbElem) !=0) \ + { \ + t_sva_in_error inError; \ + while(((t_uint16)(nbElem) & mask) == 0) {mask >>=1;} \ + if ((nbElem) > mask) {mask <<= 1;} \ + inError = sva_IN_AllocMemory(((t_uint32)mask * sizeof(typeName)), \ + &fifoDesc.baseAddr); \ + error = (t_sva_ff_error)((inError == SVA_IN_ERROR)?SVA_FIFO_ERROR:SVA_FIFO_OK); \ + fifoDesc.indexMask = (t_uint16)(mask - 1); \ + } \ + } while(0) + +/* + * Definition of the macro allowing to check if the given Fifo is EMPTY + */ +#define IS_FIFO_EMPTY(fifoDesc) \ + ((fifoDesc.elemCount == 0)?TRUE:FALSE) + +/* + * Definition of the macro allowing to check if the given Fifo is FULL + */ +#define IS_FIFO_FULL(fifoDesc) \ + ((fifoDesc.elemCount == (fifoDesc.indexMask + 1))?TRUE:FALSE) + + +/* + * Definition of the macro allowing to get the number of Fifo elems + */ +#define GET_FIFO_NB_ELEMS(fifoDesc) \ + (fifoDesc.elemCount) + +/* + * Definition of the macro allowing to add (push/write) a new elem into the given fifo + * Takes 3 params: + * - fifoDesc: Fifo descriptor + * - typeName: C type of the fifo element (use to cast pointer) + * - newFirstElem: new element to add to the fifo + * + * In order to provide a return value, we use multi-statement expressions + * (the last one is evaluated as return value) + */ +#define PUSH_FIFO_ELEM(fifoDesc, typeName, newFirstElem) \ + (t_sva_ff_error) ( \ + (fifoDesc.elemCount == (fifoDesc.indexMask + 1)) \ + ?SVA_FIFO_FULL \ + : \ + ( \ + ((typeName *)fifoDesc.baseAddr)[fifoDesc.writeIndex] = newFirstElem, \ + fifoDesc.writeIndex = (t_uint16)((fifoDesc.writeIndex + 1) & fifoDesc.indexMask), \ + fifoDesc.elemCount++, \ + SVA_FIFO_OK \ + ) \ + ) + +/* + * Definition of the macro allowing to read the first element of the given fifo + * N.B: This macro does not modify the Fifo, i.e the element remains into the fifo + * Takes 3 params: + * - fifoDesc: Fifo descriptor + * - typeName: C type of the fifo element (use to cast pointer) + * - elem: element to update with the read value + * + * In order to provide a return value, we use multi-statement expressions + * (the last one is evaluated as return value) + */ +#define READ_FIFO_ELEM(fifoDesc, typeName, elem) \ + (t_sva_ff_error) ( \ + elem = ((typeName *)fifoDesc.baseAddr)[fifoDesc.readIndex], \ + (fifoDesc.elemCount ==0)?SVA_FIFO_EMPTY:SVA_FIFO_OK \ + ) + +/* + * Definition of the macro allowing to update the first element of the given fifo + * This macro SHALL be used only for structured element + * Takes 4 params: + * - fifoDesc: Fifo descriptor + * - typeName: C type of the fifo element (use to cast pointer) + * - fieldName: name of the field to update ('.fieldName' format mandatory) + * - newFieldValue: new value to store into the given field + * + * In order to provide a return value, we use multi-statement expressions + * (the last one is evaluated as return value) + */ +#define UPDATE_FIFO_ELEM_FIELD(fifoDesc, typeName, fieldName, newFieldValue) \ + (t_sva_ff_error) ( \ + (fifoDesc.elemCount == 0) \ + ?SVA_FIFO_EMPTY \ + : \ + ( \ + ((typeName *)fifoDesc.baseAddr)[fifoDesc.readIndex]fieldName = newFieldValue, \ + SVA_FIFO_OK \ + ) \ + ) + +/* + * Definition of the macro allowing to pop (read/extract) the first element of the given fifo + * N.B: This macro modifies the Fifo, i.e the element is removed from the Fifo + * Takes 3 params: + * - fifoDesc: Fifo descriptor + * - typeName: C type of the fifo element (use to cast pointer) + * - elem: element to update with the read value + * + * In order to provide a return value, we use multi-statement expressions + * (the last one is evaluated as return value) + */ +#define POP_FIFO_ELEM(fifoDesc, typeName, elem) \ + (t_sva_ff_error) ( \ + (fifoDesc.elemCount == 0) \ + ?SVA_FIFO_EMPTY \ + : \ + ( \ + elem = ((typeName *)fifoDesc.baseAddr)[fifoDesc.readIndex], \ + fifoDesc.readIndex = (t_uint16)((fifoDesc.readIndex + 1) & fifoDesc.indexMask), \ + fifoDesc.elemCount--, \ + SVA_FIFO_OK \ + ) \ + ) + +/* + * Definition of the macro allowing to flush a fifo + * Takes 1 param: + * - fifoDesc: Fifo descriptor to flush + */ +#define FLUSH_FIFO(fifoDesc) \ + do { \ + fifoDesc.readIndex = 0; \ + fifoDesc.writeIndex = 0; \ + fifoDesc.elemCount = 0; \ + } while(0) + +/* + * Definition of the macro allowing to delete (desallocate) a previously created fifo + * Takes 1 param: + * - fifoDesc: Fifo descriptor + */ +#define DELETE_FIFO(fifoDesc) \ + ( \ + fifoDesc.readIndex = 0, \ + fifoDesc.writeIndex = 0, \ + fifoDesc.elemCount = 0, \ + fifoDesc.baseAddr = 0, \ + fifoDesc.indexMask = 0 \ + ) + + +/* + * Definition of the macro allowing to add (push/write) a new elem into the given fifo seen as a Lifo + * N.B: This macro manages the FIFO like a LIFO, i.e the new elem is added in order to be the first one to be poped + * Takes 3 params: + * - fifoDesc: Fifo descriptor + * - typeName: C type of the fifo element (use to cast pointer) + * - newFirstElem: new element to add to the fifo + * + * In order to provide a return value, we use multi-statement expressions + * (the last one is evaluated as return value) + */ +#define PUSH_REVERSE_FIFO_ELEM(fifoDesc, typeName, newFirstElem) \ + (t_sva_ff_error) ( \ + (fifoDesc.elemCount == (fifoDesc.indexMask + 1)) \ + ?SVA_FIFO_FULL \ + : \ + ( \ + fifoDesc.readIndex = (t_uint16)((fifoDesc.readIndex - 1) & fifoDesc.indexMask), \ + ((typeName *)fifoDesc.baseAddr)[fifoDesc.readIndex] = newFirstElem, \ + fifoDesc.elemCount++, \ + SVA_FIFO_OK \ + ) \ + ) + +/* + * Definition of the macro allowing to read the last element of the given fifo seen as a lifo + * N.B: This macro does not modify the Fifo, i.e the element remains into the fifo + * Takes 3 params: + * - fifoDesc: Fifo descriptor + * - typeName: C type of the fifo element (use to cast pointer) + * - elem: element to update with the read value + * + * In order to provide a return value, we use multi-statement expressions + * (the last one is evaluated as return value) + */ +#define READ_REVERSE_FIFO_ELEM(fifoDesc, typeName, elem) \ + (t_sva_ff_error) ( \ + (fifoDesc.elemCount == 0) \ + ?SVA_FIFO_EMPTY \ + : \ + ( \ + elem = ((typeName *)fifoDesc.baseAddr)[(t_uint16)((fifoDesc.writeIndex - 1) & fifoDesc.indexMask)], \ + SVA_FIFO_OK \ + ) \ + ) + +/* + * Definition of the macro allowing to pop (read/extract) the last element of the given fifo seen as a lifo + * N.B: This macro modifies the Fifo, i.e the element is removed from the Fifo + * Takes 3 params: + * - fifoDesc: Fifo descriptor + * - typeName: C type of the fifo element (use to cast pointer) + * - elem: element to update with the read value + * + * In order to provide a return value, we use multi-statement expressions + * (the last one is evaluated as return value) + */ +#define POP_REVERSE_FIFO_ELEM(fifoDesc, typeName, elem) \ + (t_sva_ff_error) ( \ + (fifoDesc.elemCount == 0) \ + ?SVA_FIFO_EMPTY \ + : \ + ( \ + fifoDesc.writeIndex = (t_uint16)((fifoDesc.writeIndex - 1) & fifoDesc.indexMask), \ + elem = ((typeName *)fifoDesc.baseAddr)[fifoDesc.writeIndex], \ + fifoDesc.elemCount--, \ + SVA_FIFO_OK \ + ) \ + ) + +/******************************************************************************/ +/* Macros definitions */ +/******************************************************************************/ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/******************************************************************************/ +/* Types definitions */ +/******************************************************************************/ +/* + * Definition of symbol used to return error related to Fifo management + */ +typedef enum { + SVA_FIFO_ERROR = SVA_FF_LAST_ERROR, + SVA_FIFO_FULL, + SVA_FIFO_EMPTY, + SVA_FIFO_OK = HCL_OK +} t_sva_ff_error; +/* + * Definition of the structure used to manage a Fifo + */ +typedef struct { +t_uint16 elemCount; +t_uint16 indexMask; +t_uint16 readIndex; +t_uint16 writeIndex; +t_logical_address baseAddr; +} t_sva_fifo; + +/******************************************************************************* +* PUBLIC Functions +*******************************************************************************/ + +#ifdef __cplusplus +} /* allow C++ to use these headers */ +#endif /* __cplusplus */ + +#endif /* __INC_SVA_FIFO_H */ +/* End of file - sva_fifo.h */ --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/common/sva_hwp.h @@ -0,0 +1,646 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ + +#ifndef __INC_SVA_HWP_H +#define __INC_SVA_HWP_H + +#include "hcl_defs.h" +#include "sva_host_interface.h" + +//rename t1xhv_host_interface types to be compliant with OSI coding rules +//typedef ts_t1xhv_subtask_link t_sva_subtask_link; +//typedef ts_t1xhv_vdc_subtask_param t_sva_dec_subtask_param; +//typedef ts_t1xhv_vec_subtask_param t_sva_enc_subtask_param; +//typedef ts_t1xhv_dpl_subtask_param t_sva_dis_subtask_param; +//typedef ts_t1xhv_grb_subtask_param t_sva_grb_subtask_param; + +/******************************************************************************/ +/* Constants definitions */ +/******************************************************************************/ + +/*------------------------------------------------------------------------ + * Defines + *----------------------------------------------------------------------*/ + +/* + * Define MMDSP host registers and MMIO IPs + */ +#define HOST_SOFT_RESET 0x10 +#define HOST_BK_CMD 0x2B +#define HOST_STOP_CLOCK 0x3A + +#define MMIO_COMPATIBLE_MODE 0x160A +#define MMIO_GPIO_OUT2 0x1004 +#define MMIO_GPIO_OUT3 0x1006 +#define MMIO_GPIO_OUT4 0x1008 +#define MMIO_GPIO_OUT8 0x1010 +#define MMIO_GPIO_OUT9 0x1012 +#define MMIO_GPIO_OUT10 0x1014 +#define MMIO_GPIO_OUT11 0x1016 +#define MMIO_GPIO_OUT12 0x1018 +#define MMIO_GPIO_EN 0x1026 + +//for new FW switch +#define MMIO_DCACHE_CMD 0xEC09 +#define MMIO_DCAHE_MODE 0xEC05 +#define MMIO_ICACHE_EMUL_UDATA0 0x40 +#define MMIO_ICACHE_EMUL_UADDRL 0x50 +/* + * Define the various masks used for the interrupt management + */ +/* + * CFG_ISR masks + */ +#define MASK_VEC_IRQ MASK_BIT0 +#define MASK_VDC_IRQ MASK_BIT1 +#define MASK_GRB_IRQ MASK_BIT2 +#define MASK_DPL_IRQ MASK_BIT3 +#define MASK_TVO_IRQ MASK_BIT4 +#define MASK_IRQ1 MASK_BIT5 + +/* + * CFG_IIS masks + */ +#define IIS_EOI_MASK MASK_BIT0 +#define IIS_BE_MASK MASK_BIT1 + +/* + * Common xxx_ISR masks + */ +#define ISR_BOT_MASK MASK_BIT0 +#define ISR_EOT_MASK MASK_BIT1 +#define ISR_ACK_MASK MASK_BIT2 +#define ISR_EOW_MASK MASK_BIT3 +#define ISR_BOF_MASK MASK_BIT3 +#define ISR_EOF1_MASK MASK_BIT3 +#define ISR_UBU_MASK MASK_BIT4 +#define ISR_GS_MASK MASK_BIT4 +#define ISR_DS_MASK MASK_BIT4 +#define ISR_EOF2_MASK MASK_BIT4 +#define ISR_BOW_MASK MASK_BIT5 +#define ISR_CER_MASK MASK_BIT5 +#define ISR_BRC_MASK MASK_BIT5 +#define ISR_ERR_MASK MASK_BIT6 +#define ISR_EOK_MASK MASK_BIT7 + + +/* + * Define the symbol used to identify/reference the four different SVA tasks + */ +typedef enum { + ENCODE_TID = 0, + DECODE_TID, + GRAB_TID, + DISPLAY_TID, + TVO_TID, + DUMMY_TID +} t_sva_hw_task_id; +#define SVA_NUM_TASKS DUMMY_TID + + +/******************************************************************************/ +/* Types definitions */ +/******************************************************************************/ +#ifdef __STN_8810 /* Case STn8810 (cut A and B - same memory mapping) */ + +/* ************************** SVA Memory Mapping ************************** */ +typedef struct { + t_uint32 not_mapped_1[(0x40000>>2)]; + t_uint32 dataMem[(0x48000-0x40000)>>2]; /* MMDSP+ Data Memory (Word or Halfword Access) */ + t_uint32 not_mapped_2[(0x5C000-0x48000)>>2]; + t_uint16 mmioSpace[(0x60000-0x5C000)>>1]; /* MMDSP+ MMIO Peripherals (Word or Halfword Access) */ + t_uint16 hostRegs[(0x60200-0x60000)>>1]; /* MMDSP+ Host Registers (only Halfword Access) */ + t_uint32 not_mapped_3[(0x80000-0x60200)>>2]; + t_uint32 codeMem[(0x90000-0x80000)>>2]; /* MMDSP+ Instruction (Code) Memory (only Word Access) */ + t_uint32 not_mapped_4[(0xC0000-0x90000)>>2]; + t_uint32 dictMem[(0xC4000-0xC0000)>>2]; /* MMDSP+ Instruction (Dictionnary) Memory (only Word Access) */ + t_uint32 not_mapped_5[(0x100000-0xC4000)>>2]; +} t_sva_mem_mapping; + +/* ************************* SVA Registers Mapping ************************ */ + +/* ************************** CONFIGURATION PART ************************** */ +typedef volatile struct { + t_uint32 cfg_psa; /* Subtask parameter Start Address register */ /*0x000*/ + t_uint32 cfg_pea; /* Subtask parameter Stop Address register */ /*0x004*/ + t_uint32 cfg_ice; /* Idle Cycle Enable register */ /*0x008*/ + t_uint32 cfg_csc; /* CCP synchronization codes register */ /*0x00c*/ + t_uint32 cfg_cgc; /* clock gating control register */ /*0x010*/ + + t_uint32 unused_1[(0x80-0x14)>>2]; + + t_uint32 cfg_tim; /* Timer Initialization value register */ /*0x080*/ + t_uint32 cfg_tic; /* Timer Current value register */ /*0x084*/ + + t_uint32 unused_2[(0xA0-0x88)>>2]; + + t_uint32 cfg_iis; /* IRQ1 Interrupt Status register */ /*0x0A0*/ + t_uint32 cfg_isr; /* Global Interrupt status register */ /*0x0A4*/ + t_uint32 cfg_imr; /* Global Interrupt mask register */ /*0x0A8*/ + + t_uint32 unused_3[(0xC0-0xAC)>>2]; + + t_uint32 cfg_clk; /* Clock generation register */ /*0x0C0*/ + t_uint32 cfg_rst; /* Reset register */ /*0x0C4*/ + + t_uint32 unused_4[(0x1000-0xC8)>>2]; + +} t_sva_config_regs_mapping; + +/* ************************** IDENTIFICATION PART ************************* */ +typedef volatile struct { + t_uint32 unused_4[(0xF00-0x00)>>2]; + + t_uint32 idn_frv; /* Firmware Revision register */ /*0xF00*/ + t_uint32 idn_rrv; /* Register Revision register */ /*0xF04*/ + + t_uint32 unused_7[(0x0FC0-0xF08)>>2]; + + t_uint32 idn_hrv; /* Hardware Revision register */ /*0xFC0*/ + + t_uint32 unused_8[(0x0FE0-0xFC4)>>2]; + + t_uint32 idn_pid0; /* Peripheral Id 0 register */ /*0xFE0*/ + t_uint32 idn_pid1; /* Peripheral Id 1 register */ /*0xFE4*/ + t_uint32 idn_pid2; /* Peripheral Id 2 register */ /*0xFE8*/ + t_uint32 idn_pid3; /* Peripheral Id 3 register */ /*0xFEC*/ + t_uint32 idn_pcid0; /* PCell Id 0 register */ /*0xFF0*/ + t_uint32 idn_pcid1; /* PCell Id 1 register */ /*0xFF4*/ + t_uint32 idn_pcid2; /* PCell Id 2 register */ /*0xFF8*/ + t_uint32 idn_pcid3; /* PCell Id 3 register */ /*0xFFC*/ + +} t_sva_ident_regs_mapping; + +/* ************************** TASKS SPECIFIC PART ************************* */ +typedef struct { + /* Warning !!! */ + /* This structure must contain the common register set of all subtask */ + /* registers. It'll be accessed via genTask structure element !!! */ + + t_uint32 nad; /* Next Subtask Address register */ + t_uint32 nty; /* Next Subtask Type register */ + t_uint32 nts; /* Next Subtask Exec. Time stamp register */ + t_uint32 nrs; /* Next Subtask Dependency register */ + + t_uint32 cad; /* Current Subtask Address register */ + t_uint32 cty; /* Current Subtask Type register */ + t_uint32 cts; /* Current Subtask Exec. Time stamp register */ + t_uint32 crs; /* Current Subtask Dependency register */ + + t_uint32 iad; /* Interrupt Subtask Address register */ + t_uint32 ity; /* Interrupt Subtask Type register */ + t_uint32 its; /* Interrupt Subtask Exec. Time stamp register */ + t_uint32 irs; /* Interrupt Subtask Dependency register */ + + t_uint32 cnt; /* Subtask Counter Register */ + t_uint32 unused_1[(0x80-0x34)>>2]; + t_uint32 ctl; /* Subtask Control Register */ + t_uint32 sem; /* Subtask Semaphor Register */ + t_uint32 unused_2[(0xA0-0x88)>>2]; + t_uint32 sta; /* Subtask Status Register */ + t_uint32 isr; /* Subtask Interrupt Status Register */ + t_uint32 imr; /* Subtask Interrupt Mask Register */ + + /* Used space until next taskId's parameters. */ + t_uint32 unused_3[(0x100-0xAC)>>2]; +} t_sva_task_hw_regs; + +/* For STn8810, all tasks registers are the same */ +typedef t_sva_task_hw_regs t_sva_vec_task_hw_regs; +typedef t_sva_task_hw_regs t_sva_vdc_task_hw_regs; +typedef t_sva_task_hw_regs t_sva_grb_task_hw_regs; +typedef t_sva_task_hw_regs t_sva_dsp_task_hw_regs; +typedef t_sva_task_hw_regs t_sva_tvd_task_hw_regs; + +typedef union { + t_sva_task_hw_regs genTask; + t_sva_vec_task_hw_regs vecTask; + t_sva_vdc_task_hw_regs vdcTask; + t_sva_grb_task_hw_regs grbTask; + t_sva_dsp_task_hw_regs dspTask; + t_sva_tvd_task_hw_regs tvdTask; +} t_sva_task_regs; + +typedef struct { + /* Offest between HAMAC video register base address and first task's */ + /* regsiter (i.e. 0x200). */ + t_uint32 unused_1[(0x200-0x000)>>2]; + + t_sva_task_hw_regs vecTask; + t_sva_task_hw_regs vdcTask; + t_sva_task_hw_regs grbTask; + t_sva_task_hw_regs dspTask; + t_sva_task_hw_regs tvdTask; +}t_sva_tasks_reg_mapping; + +typedef struct { + t_uint32 unused_1[(0x200-0x000)>>2]; + t_sva_task_hw_regs taskRegs[SVA_NUM_TASKS]; +} t_sva_genTasks_reg_mapping; + +#elif defined __STN_8815 /* Case STn8815 (cut A) */ + +/* ************************** SVA Memory Mapping ************************** */ +typedef struct { + t_uint32 dataMem24_block_0[(0x04000-0x00000)>>2]; /* MMDSP+ Data Memory Block0(Word or Halfword Access) */ + t_uint32 dataMem24_block_1[(0x08000-0x04000)>>2]; /* MMDSP+ Data Memory Block1(Word or Halfword Access) */ + t_uint32 dataMem24_block_2[(0x0C000-0x08000)>>2]; /* MMDSP+ Data Memory Block2(Word or Halfword Access) */ + t_uint32 dataMem24_block_3[(0x10000-0x0C000)>>2]; /* MMDSP+ Data Memory Block3(Word or Halfword Access) */ + t_uint32 reserved_0[(0x40000-0x10000)>>2]; + t_uint32 dataMem16_block_0[(0x42000-0x40000)>>2]; /* MMDSP+ Data Memory Block0(Word or Halfword Access) */ + t_uint32 dataMem16_block_1[(0x44000-0x42000)>>2]; /* MMDSP+ Data Memory Block1(Word or Halfword Access) */ + t_uint32 dataMem16_block_2[(0x46000-0x44000)>>2]; /* MMDSP+ Data Memory Block2(Word or Halfword Access) */ + t_uint32 dataMem16_block_3[(0x48000-0x46000)>>2]; /* MMDSP+ Data Memory Block3(Word or Halfword Access) */ + t_uint32 reserved_1[(0x52000-0x48000)>>2]; + t_uint32 mmioSpace[(0x5C000-0x52000)>>2]; + t_uint32 reserved_2[(0x5D400-0x5C000)>>2]; + t_uint32 dmaBus[(0x5D800-0x5D400)>>2]; + t_uint32 dataCacheConfigReg[(0x5DC00-0x5D800)>>2]; + t_uint32 reserved_3[(0x5E000-0x5DC00)>>2]; + t_uint32 timers[(0x5E400-0x5E000)>>2]; + t_uint32 sem[(0x5E800-0x5E400)>>2]; + t_uint32 dmaInterface[(0x5EC00-0x5E800)>>2]; + t_uint32 emul[(0x5F000-0x5EC00)>>2]; + t_uint32 ahbMasterInterface[(0x5F400-0x5F000)>>2]; + t_uint32 reserved_4[(0x5FC00-0x5F400)>>2]; + t_uint32 hostRegs[(0x60200-0x60000)>>2]; + t_uint32 hostReg32[(0x60400-0x60200)>>2]; + t_uint32 reserved_5[(0x100000-0x60400)>>2]; +} t_sva_mem_mapping; + +/* ************************* SVA Registers Mapping ************************ */ + +/* ************************** CONFIGURATION PART ************************** */ +typedef volatile struct { + //t_uint32 unused_1[(0x40000-0x00000)>>2]; /* not to be used if we put the right reg_base_address: ie MEM+0x40000 */ + + t_uint32 cfg_psa; /* Subtask parameter Start Address register */ /*0x40000*/ + t_uint32 cfg_pea; /* Subtask parameter Stop Address register */ /*0x40004*/ + t_uint32 cfg_ice; /* Idle Cycle Enable register */ /*0x40008*/ + t_uint32 cfg_csc; /* CCP synchronization codes register */ /*0x4000C*/ + t_uint32 cfg_cgc; /* clock gating control register */ /*0x40010*/ + t_uint32 cfg_irp_act; /* allow to boot or not irp */ /*0x40014*/ /* Sarvesh: Not required for FW version >= V3.13.2.1 */ + t_uint32 cfg_irp_fw_addr; /* start address eWarp firmware */ /*0x40018*/ + t_uint32 cfg_irp_fw_size; /* size in bytes of eWarp firmware */ /*0x4001C*/ + t_uint32 unused_0[(0x40024-0x40020)>>2]; + t_uint32 cfg_irp_save_addr; /* State save address register */ /*0x40024*/ + + t_uint16 cfg_irp_grabhq_status; /*Status of HQ grab*/ /*0x40028*/ + t_uint16 unused_0_1; /*0x4002A*/ + t_uint32 unused_0_2[(0x40030-0x4002C)>>2]; + t_uint16 cfg_irp_grabhq_gridcast_l; /*0x40030*/ + t_uint16 cfg_irp_grabhq_gridcast_h; /*0x40032*/ + t_uint32 unused_0_3[(0x40050-0x40034)>>2]; + t_uint16 cfg_irp_grabhq_grid_g1; /*0x40050*/ + t_uint16 cfg_irp_grabhq_grid_g2; /*0x40052*/ + t_uint16 cfg_irp_grabhq_grid_r; /*0x40054*/ + t_uint16 cfg_irp_grabhq_grid_b; /*0x40056*/ + + t_uint32 unused_1[(0x40234-0x40058)>>2]; + t_uint32 cfg_irp_state; /* current state of mmdsp firmware */ /*0x40234*/ + t_uint32 cfg_irp_rw; /* status of the current rw operation */ /*0x40238*/ + t_uint32 cfg_irp_error; /* error code */ /*0x4023C*/ + t_uint32 cfg_irp_bs; /* start of circular buffer for rw packet */ /*0x40240*/ /* Sarvesh: Not used any more */ + t_uint32 cfg_irp_be; /* end of circular buffer for rw packet */ /*0x40244*/ /* Sarvesh: Not used any more */ + t_uint32 cfg_irp_ptr; /* ptr of circular buffer for rw packet */ /*0x40248*/ + t_uint32 unused_2[(0x5A000-0x4024C)>>2]; + t_uint32 cfg_clk; /* Clock generation register */ /*0x5A000*/ + t_uint32 cfg_rst; /* Reset register */ /*0x5A004*/ + t_uint32 ckg_cken; /* Added */ /*0x5A008*/ /* Sarvesh: Probably Not used any more */ + t_uint32 unused_3[(0x5BC00-0x5A00C)>>2]; + t_uint32 cfg_tim; /* Timer Initialization value register */ /*0x5BC00*/ + t_uint32 cfg_tic; /* Timer Current value register */ /*0x5BC04*/ + t_uint32 unused_4[(0x5BC20-0x5BC08)>>2]; + t_uint32 cfg_iis; /* IRQ1 Interrupt Status register */ /*0x5BC20*/ + t_uint32 cfg_isr; /* Global Interrupt status register */ /*0x5BC24*/ + t_uint32 cfg_imr; /* Global Interrupt mask register */ /*0x5BC28*/ + + t_uint32 unused_5[(0x5BDAC-0x5BC2C)>>2]; +} t_sva_config_regs_mapping; + +/* ************************** IDENTIFICATION PART ************************* */ +typedef volatile struct { + t_uint32 unused_1[(0x40380-0x40000)>>2]; + + t_uint32 idn_frv; /* Firmware Revision register */ /*0x40380*/ + t_uint32 idn_rrv; /* Register Revision register */ /*0x40384*/ + + t_uint32 unused_2[(0x5A1C0-0x40388)>>2]; + + t_uint32 idn_hrv; /* Hardware Revision register */ /*0x5A1C0*/ + + t_uint32 unused_3[(0x5A1E0-0x5A1C4)>>2]; + + t_uint32 idn_pid0; /* Peripheral Id 0 register */ /*0x5A1E0*/ + t_uint32 idn_pid1; /* Peripheral Id 1 register */ /*0x5A1E4*/ + t_uint32 idn_pid2; /* Peripheral Id 2 register */ /*0x5A1E8*/ + t_uint32 idn_pid3; /* Peripheral Id 3 register */ /*0x5A1EC*/ + t_uint32 idn_pcid0; /* PCell Id 0 register */ /*0x5A1F0*/ + t_uint32 idn_pcid1; /* PCell Id 1 register */ /*0x5A1F4*/ + t_uint32 idn_pcid2; /* PCell Id 2 register */ /*0x5A1F8*/ + t_uint32 idn_pcid3; /* PCell Id 3 register */ /*0x5A1FC*/ + + t_uint32 unused_4[(0x5BDAC-0x5A200)>>2]; + +} t_sva_ident_regs_mapping; + +/* ************************** TASKS SPECIFIC PART ************************* */ +typedef struct { + /* Warning !!! */ + /* This structure must contain the common register set of all subtask */ + /* registers. It'll be accessed via genTask structure element !!! */ + + + t_uint32 nad; /* Next Subtask Address register */ + t_uint32 nty; /* Next Subtask Type register */ + t_uint32 nts; /* Next Subtask Exec. Time stamp register */ + t_uint32 nrs; /* Next Subtask Dependency register */ + + t_uint32 cad; /* Current Subtask Address register */ + t_uint32 cty; /* Current Subtask Type register */ + t_uint32 cts; /* Current Subtask Exec. Time stamp register */ + t_uint32 crs; /* Current Subtask Dependency register */ + + t_uint32 iad; /* Interrupt Subtask Address register */ + t_uint32 ity; /* Interrupt Subtask Type register */ + t_uint32 its; /* Interrupt Subtask Exec. Time stamp register */ + t_uint32 irs; /* Interrupt Subtask Dependency register */ + + t_uint32 cnt; /* Subtask Counter Register */ + + /* Used space until next taskId's parameters. */ + t_uint32 unused_1[(0x80-0x34)>>2]; + +} t_sva_task_hw_regs; + +typedef struct { + t_uint32 nad; /* Next Subtask Address register */ + t_uint32 nty; /* Next Subtask Type register */ + t_uint32 nts; /* Next Subtask Exec. Time stamp register */ + t_uint32 nrs; /* Next Subtask Dependency register */ + + t_uint32 cad; /* Current Subtask Address register */ + t_uint32 cty; /* Current Subtask Type register */ + t_uint32 cts; /* Current Subtask Exec. Time stamp register */ + t_uint32 crs; /* Current Subtask Dependency register */ + + t_uint32 iad; /* Interrupt Subtask Address register */ + t_uint32 ity; /* Interrupt Subtask Type register */ + t_uint32 its; /* Interrupt Subtask Exec. Time stamp register */ + t_uint32 irs; /* Interrupt Subtask Dependency register */ + t_uint32 cnt; /* Subtask Counter Register */ + //t_uint32 unused_1[(0x5BC80-0x40134)>>2]; + t_uint32 unused_1_0[(0x4014C-0x40134)>>2]; + t_uint32 iad_err; /* Interrupt Subtask Address register ERROR */ + t_uint32 ity_err; /* Interrupt Subtask Type register ERROR */ + t_uint32 its_err; /* Interrupt Subtask Exec. Time stamp register ERROR */ + t_uint32 dur; + t_uint32 unused_1_1[(0x5BC80-0x4015C)>>2]; + t_uint32 ctl; /* Subtask Control Register */ + t_uint32 sem; /* Subtask Semaphor Register */ + t_uint32 unused_2[(0x5BCA0-0x5BC88)>>2]; + t_uint32 sta; /* Subtask Status Register */ + t_uint32 isr; /* Subtask Interrupt Status Register */ + t_uint32 imr; /* Subtask Interrupt Mask Register */ + t_uint32 unused_3[(0x5BDAC-0x5BCAC)>>2]; +} t_sva_vec_task_hw_regs; + +typedef struct { + t_uint32 nad; /* Next Subtask Address register */ + t_uint32 nty; /* Next Subtask Type register */ + t_uint32 nts; /* Next Subtask Exec. Time stamp register */ + t_uint32 nrs; /* Next Subtask Dependency register */ + + t_uint32 cad; /* Current Subtask Address register */ + t_uint32 cty; /* Current Subtask Type register */ + t_uint32 cts; /* Current Subtask Exec. Time stamp register */ + t_uint32 crs; /* Current Subtask Dependency register */ + + t_uint32 iad; /* Interrupt Subtask Address register */ + t_uint32 ity; /* Interrupt Subtask Type register */ + t_uint32 its; /* Interrupt Subtask Exec. Time stamp register */ + t_uint32 irs; /* Interrupt Subtask Dependency register */ + t_uint32 cnt; /* Subtask Counter Register */ +// t_uint32 unused_1[(0x5BCC0-0x401B4)>>2]; + t_uint32 unused_1_0[(0x401CC-0x401B4)>>2]; + t_uint32 iad_err; /* Interrupt Subtask Address register ERROR */ + t_uint32 ity_err; /* Interrupt Subtask Type register ERROR */ + t_uint32 its_err; /* Interrupt Subtask Exec. Time stamp register ERROR */ + t_uint32 dur; + t_uint32 unused_1_1[(0x5BCC0-0x401DC)>>2]; + t_uint32 ctl; /* Subtask Control Register */ + t_uint32 sem; /* Subtask Semaphor Register */ + t_uint32 unused_2[(0x5BCE0-0x5BCC8)>>2]; + t_uint32 sta; /* Subtask Status Register */ + t_uint32 isr; /* Subtask Interrupt Status Register */ + t_uint32 imr; /* Subtask Interrupt Mask Register */ + t_uint32 unused_3[(0x5BDAC-0x5BCEC)>>2]; +} t_sva_vdc_task_hw_regs; + +typedef struct { + t_uint32 nad; /* Next Subtask Address register */ + t_uint32 nty; /* Next Subtask Type register */ + t_uint32 nts; /* Next Subtask Exec. Time stamp register */ + t_uint32 nrs; /* Next Subtask Dependency register */ + + t_uint32 cad; /* Current Subtask Address register */ + t_uint32 cty; /* Current Subtask Type register */ + t_uint32 cts; /* Current Subtask Exec. Time stamp register */ + t_uint32 crs; /* Current Subtask Dependency register */ + + t_uint32 iad; /* Interrupt Subtask Address register */ + t_uint32 ity; /* Interrupt Subtask Type register */ + t_uint32 its; /* Interrupt Subtask Exec. Time stamp register */ + t_uint32 irs; /* Interrupt Subtask Dependency register */ + t_uint32 cnt; /* Subtask Counter Register */ +// t_uint32 unused_1[(0x5BD00-0x40234)>>2]; + t_uint32 unused_1_0[(0x4024C-0x40234)>>2]; + t_uint32 iad_err; /* Interrupt Subtask Address register ERROR */ + t_uint32 ity_err; /* Interrupt Subtask Type register ERROR */ + t_uint32 its_err; /* Interrupt Subtask Exec. Time stamp register ERROR */ + t_uint32 dur; + t_uint32 unused_1_1[(0x5BD00-0x4025C)>>2]; + t_uint32 ctl; /* Subtask Control Register */ + t_uint32 sem; /* Subtask Semaphor Register */ + t_uint32 unused_2[(0x5BD20-0x5BD08)>>2]; + t_uint32 sta; /* Subtask Status Register */ + t_uint32 isr; /* Subtask Interrupt Status Register */ + t_uint32 imr; /* Subtask Interrupt Mask Register */ + t_uint32 unused_3[(0x5BDAC-0x5BD2C)>>2]; +} t_sva_grb_task_hw_regs; + +typedef struct { + t_uint32 nad; /* Next Subtask Address register */ + t_uint32 nty; /* Next Subtask Type register */ + t_uint32 nts; /* Next Subtask Exec. Time stamp register */ + t_uint32 nrs; /* Next Subtask Dependency register */ + + t_uint32 cad; /* Current Subtask Address register */ + t_uint32 cty; /* Current Subtask Type register */ + t_uint32 cts; /* Current Subtask Exec. Time stamp register */ + t_uint32 crs; /* Current Subtask Dependency register */ + + t_uint32 iad; /* Interrupt Subtask Address register */ + t_uint32 ity; /* Interrupt Subtask Type register */ + t_uint32 its; /* Interrupt Subtask Exec. Time stamp register */ + t_uint32 irs; /* Interrupt Subtask Dependency register */ + t_uint32 cnt; /* Subtask Counter Register */ +// t_uint32 unused_1[(0x5BD40-0x402B4)>>2]; + t_uint32 unused_1_0[(0x402CC-0x402B4)>>2]; + t_uint32 iad_err; /* Interrupt Subtask Address register ERROR */ + t_uint32 ity_err; /* Interrupt Subtask Type register ERROR */ + t_uint32 its_err; /* Interrupt Subtask Exec. Time stamp register ERROR */ + t_uint32 dur; + t_uint32 unused_1_1[(0x5BD40-0x402DC)>>2]; + t_uint32 ctl; /* Subtask Control Register */ + t_uint32 sem; /* Subtask Semaphor Register */ + t_uint32 unused_2[(0x5BD60-0x5BD48)>>2]; + t_uint32 sta; /* Subtask Status Register */ + t_uint32 isr; /* Subtask Interrupt Status Register */ + t_uint32 imr; /* Subtask Interrupt Mask Register */ + t_uint32 unused_3[(0x5BDAC-0x5BD6C)>>2]; +} t_sva_dsp_task_hw_regs; + +typedef struct { + t_uint32 nad; /* Next Subtask Address register */ + t_uint32 nty; /* Next Subtask Type register */ + t_uint32 nts; /* Next Subtask Exec. Time stamp register */ + t_uint32 nrs; /* Next Subtask Dependency register */ + + t_uint32 cad; /* Current Subtask Address register */ + t_uint32 cty; /* Current Subtask Type register */ + t_uint32 cts; /* Current Subtask Exec. Time stamp register */ + t_uint32 crs; /* Current Subtask Dependency register */ + + t_uint32 iad; /* Interrupt Subtask Address register */ + t_uint32 ity; /* Interrupt Subtask Type register */ + t_uint32 its; /* Interrupt Subtask Exec. Time stamp register */ + t_uint32 irs; /* Interrupt Subtask Dependency register */ + t_uint32 cnt; /* Subtask Counter Register */ + //t_uint32 unused_1[(0x5BD80-0x40334)>>2]; + t_uint32 unused_1_0[(0x4034C-0x40334)>>2]; + t_uint32 iad_err; /* Interrupt Subtask Address register ERROR */ + t_uint32 ity_err; /* Interrupt Subtask Type register ERROR */ + t_uint32 its_err; /* Interrupt Subtask Exec. Time stamp register ERROR */ + t_uint32 unused_1_1[(0x5BD80-0x40358)>>2]; + t_uint32 ctl; /* Subtask Control Register */ + t_uint32 sem; /* Subtask Semaphor Register */ + t_uint32 unused_2[(0x5BDA0-0x5BD88)>>2]; + t_uint32 sta; /* Subtask Status Register */ + t_uint32 isr; /* Subtask Interrupt Status Register */ + t_uint32 imr; /* Subtask Interrupt Mask Register */ +} t_sva_tvd_task_hw_regs; + +typedef union { + t_sva_task_hw_regs genTask; + t_sva_vec_task_hw_regs vecTask; + t_sva_vdc_task_hw_regs vdcTask; + t_sva_grb_task_hw_regs grbTask; + t_sva_dsp_task_hw_regs dspTask; + t_sva_tvd_task_hw_regs tvdTask; +} t_sva_task_regs; + +typedef struct { + /* Offest between HAMAC video register base address and first task's */ + /* regsiter (i.e. 0x40100). */ + t_uint32 unused_1[(0x40100-0x40000)>>2]; + + t_sva_task_hw_regs vecTask; + t_sva_task_hw_regs vdcTask; + t_sva_task_hw_regs grbTask; + t_sva_task_hw_regs dspTask; + t_sva_task_hw_regs tvdTask; +}t_sva_tasks_reg_mapping; + +typedef struct { + t_uint32 unused_1[(0x40100-0x40000)>>2]; + t_sva_task_hw_regs taskRegs[SVA_NUM_TASKS]; +} t_sva_genTasks_reg_mapping; + +#else +# error Version of chip not defined !!!! +#endif + + +/* ************************* SVA Registers Mapping ************************ */ +typedef volatile union { + t_sva_config_regs_mapping cfg; /* Configuration registers. */ + t_sva_ident_regs_mapping idn; /* Indentification registers. */ + t_sva_tasks_reg_mapping task; /* Specific Tasks registers. */ + t_sva_genTasks_reg_mapping genTask;/* Generic Tasks registers. */ + t_sva_grb_task_hw_regs grbTask; +} t_sva_regs_mapping; + + +/* * MACRO to extract registers according to component */ +#ifdef __STN_8810 + +/* Macro that define a Read/Write regsiter access according to taskId. */ +/* As structures are identical depending on taskId, genTask (generic task) */ +/* is used instead of vecTask, vdcTask,... */ +# define SVA_HW_REG_R(taskId,fieldName) \ + (pTasksRegs->genTask.fieldName) + +# define SVA_HW_REG_W(taskId,fieldName,value) \ + {(pTasksRegs->genTask.fieldName) = (value);} + +#else /* __STN_8810 */ + +/* Macro that define a Read/Write regsiter access according to taskId. */ +/* As structures are differents depending on taskId, vecTask, ... are used */ +/* to get the field at the right position in structure. */ +# define SVA_HW_REG_R(taskId,fieldName) \ + (taskId == ENCODE_TID ? (pTasksRegs->vecTask.fieldName) : \ + taskId == DECODE_TID ? (pTasksRegs->vdcTask.fieldName) : \ + taskId == GRAB_TID ? (pTasksRegs->grbTask.fieldName) : \ + taskId == DISPLAY_TID? (pTasksRegs->dspTask.fieldName) : \ + (pTasksRegs->tvdTask.fieldName) ) + + +# define SVA_HW_REG_W(taskId,fieldName,value) \ + { if(taskId == ENCODE_TID ){(pTasksRegs->vecTask.fieldName)=value;} \ + else if(taskId == DECODE_TID ){(pTasksRegs->vdcTask.fieldName)=value;} \ + else if(taskId == GRAB_TID ){(pTasksRegs->grbTask.fieldName)=value;} \ + else if(taskId == DISPLAY_TID){(pTasksRegs->dspTask.fieldName)=value;} \ + else {(pTasksRegs->tvdTask.fieldName)=value;}} +#endif /* __STN_8810 */ + +/* + * Define macro to write irp registers. This macro will do nothing when + * irp hardware not present. This avoid ugly ifdef in c code +*/ +#ifdef __STN_8815 + #define SVA_HW_WRITE_IRP(reg,value) (reg) = (value) +#else + #define SVA_HW_WRITE_IRP(reg,value) (void)0 +#endif +/* + * Define macro to read irp registers. This macro will return 0 when + * irp hardware not present. This avoid ugly ifdef in c code +*/ +#ifdef __STN_8815 + #define SVA_HW_READ_IRP(reg) (reg) +#else + #define SVA_HW_READ_IRP(reg) 0 +#endif + + +#endif /* __INC_SVA_HWP_H */ + +// End of file - sva_hwP.h --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/common/sva_internalneeds.c @@ -0,0 +1,131 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ + +#include "hcl_defs.h" +#include "sva_internalneeds.h" + +PRIVATE t_sva_internal_needs_desc internalNeedsDesc; + +/****************************************************************************/ +/* NAME: t_sva_error sva_IN_Init ( void ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine initializes the SVA HCL Internal Needs management */ +/* */ +/* PARAMETERS: */ +/* IN : none */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_sva_error sva_IN_Init(void) +{ + internalNeedsDesc.baseAddr = 0; + internalNeedsDesc.currentPointer = 0; + internalNeedsDesc.endAddr = 0; + + return SVA_OK; +} + + + +/****************************************************************************/ +/* NAME: t_sva_in_error sva_IN_ProvideInternalNeeds( */ +/* t_logical_address logicalBaseAddr,*/ +/* t_size size */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine provide some memory to this module */ +/* This module will manage this last one in order to alloc some memory */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - logicalBaseAddr: logical base address of the provided memory block*/ +/* - size: size (in bytes) of the provided memory block */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_in_error */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_sva_in_error sva_IN_ProvideInternalNeeds( +t_logical_address logicalBaseAddr, +t_size size +) +{ + internalNeedsDesc.baseAddr = logicalBaseAddr; + internalNeedsDesc.endAddr = (internalNeedsDesc.baseAddr + size); + internalNeedsDesc.currentPointer = internalNeedsDesc.baseAddr; + return SVA_IN_OK; +} + + +/****************************************************************************/ +/* NAME: t_sva_in_error sva_IN_AllocMemory( */ +/* t_size size, */ +/* t_logical_address *pLogicalBaseAddr */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine allocates some memory from the previously provided block */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - size: size (in bytes) of the provided memory block */ +/* */ +/* OUT : */ +/* - pLogicalBaseAddr: logical base address of the allocated block */ +/* */ +/* RETURN: */ +/* t_sva_in_error */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_sva_in_error sva_IN_AllocMemory( +t_size size, +t_logical_address *pLogicalBaseAddr +) +{ + HCL_DEBUG_ASSERT(pLogicalBaseAddr!=NULL); + + + if (internalNeedsDesc.baseAddr == 0 || + ((internalNeedsDesc.currentPointer + size) > internalNeedsDesc.endAddr)) + { + return SVA_IN_ERROR; + } + + *pLogicalBaseAddr = internalNeedsDesc.currentPointer; + internalNeedsDesc.currentPointer += size; + + /* insure word alignment */ + if ((internalNeedsDesc.currentPointer%4)!=0) + { + internalNeedsDesc.currentPointer += (4 - (internalNeedsDesc.currentPointer%4)); + } + + return SVA_IN_OK; +} --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/common/sva_internalneeds.h @@ -0,0 +1,61 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ + + +#ifndef __INC_SVA_IN_H +#define __INC_SVA_IN_H + +#include "hcl_defs.h" +#include "sva.h" +#include "svap.h" + +typedef struct { + t_logical_address baseAddr; + t_logical_address currentPointer; + t_logical_address endAddr; +} t_sva_internal_needs_desc; + + +typedef enum { + SVA_IN_ERROR = SVA_IN_LAST_ERROR, + SVA_IN_OK = HCL_OK +} t_sva_in_error; + + +/* ------------------------------------ */ +/* Internal Needs Module initialization */ +/* ------------------------------------ */ +PUBLIC t_sva_error sva_IN_Init(void); + +/* ------------------------------------------------ */ +/* Provide piece of memory to Internal Needs Module */ +/* ------------------------------------------------ */ +PUBLIC t_sva_in_error sva_IN_ProvideInternalNeeds(t_logical_address, t_size); +// ###: to be added service_id as parameter + + +/* ----------------------------------------------------------- */ +/* Allocate inside the Internal Needs memory a piece of memory */ +/* ----------------------------------------------------------- */ +PUBLIC t_sva_in_error sva_IN_AllocMemory(t_size, t_logical_address *); + + + +#endif /* __INC_SVA_IN_H */ + --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/common/sva_service.h @@ -0,0 +1,337 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ + +#ifndef __INC_SVA_SERVICE_H +#define __INC_SVA_SERVICE_H + +#include "hcl_defs.h" +#include "sva.h" +#include "sva_taskmgt.h" +#include "platform_os.h" + + +/******************************************************************************/ +/* Constants definitions */ +/******************************************************************************/ + + +/*----------------------------------------------------------------------* + * Defines : general subtask * + *----------------------------------------------------------------------*/ + +/* number max of subtask for one instance */ +#define SUBTASK_NMAX 256 + +/* define number of sub task a service must create by default */ +#define SUBTASK_DEFAULT_NUMBER 2 + +/*----------------------------------------------------------------------* + * Defines : grab instances and subtasks * + *----------------------------------------------------------------------*/ + +/* Define the number of subtask use by grab. It's fix to 4. Reason is to have an even number to ease interlace support */ +#define SUBTASK_GRAB_NUMBER 4 + +/* define maximum number of grab supported */ +#define NUM_MAX_GRAB 4 + +/* define maximum number of started grab supported */ +#define NUM_MAX_STARTED_GRAB 1 + +/*----------------------------------------------------------------------* + * Defines : video encode instances and subtasks * + *----------------------------------------------------------------------*/ + +/* Define the number of subtask use by encode. It's different from default service value and is equal to brc pipedepth */ +#define SUBTASK_ENCODE_NUMBER 2 + +/* define maximum number of encode supported */ +#define NUM_MAX_ENCODE 4 + +/* define maximum number of active encode supported */ +#define NUM_MAX_ACTIVE_ENCODE 1 + +/*----------------------------------------------------------------------* + * Defines : video decode instances and subtasks * + *----------------------------------------------------------------------*/ + +/* SUBTASK_DECODE_NUMBER => SUBTASK_DEFAULT_NUMBER */ + +/* define maximum number of decode supported */ +#define NUM_MAX_DECODE 4 + +/* define maximum number of active decode supported */ +#define NUM_MAX_ACTIVE_DECODE 1 + +/*----------------------------------------------------------------------* + * Defines : still encode instances and subtasks * + *----------------------------------------------------------------------*/ + +/* Define subtask number */ +#define STILL_ENCODE_SUBTASK_DEFAULT_NUMBER 1 + +/* Define the maximum number of still encode instance those can be run in parallel */ +#define NUM_MAX_STILL_ENCODE 4 + +/*----------------------------------------------------------------------* + * Defines : still decode instances and subtasks * + *----------------------------------------------------------------------*/ + +/* STILL_DECODE_SUBTASK_DEFAULT_NUMBER => SUBTASK_DEFAULT_NUMBER */ + +/* Define the maximum number of still-image decode instance those can be run in parallel */ +#define NUM_MAX_STILL_DECODE 8 + +/*----------------------------------------------------------------------* + * Defines : stab instances and subtasks * + *----------------------------------------------------------------------*/ + +/* define maximum number of stab supported */ +#define NUM_MAX_STAB 4 + +/*----------------------------------------------------------------------* + * Defines : display instances and subtasks * + *----------------------------------------------------------------------*/ + +/* Define the maximum number of display instance those can be run in parallel */ +#define NUM_MAX_POSTPROCESSOR 4 + +/* Define the maximum number of display instance those can be run in parallel */ +#define NUM_MAX_DISPLAY 4 + +/*----------------------------------------------------------------------* + * Defines : tvo instances and subtasks * + *----------------------------------------------------------------------*/ + +/* Define the number of subtask use by TVO. */ + +#define SUBTASK_TVO_NUMBER 1 + +/* define maximum number of tvo supported */ +#define NUM_MAX_TV 1 + + + +/*define default fifo depth for buffer*/ +#define PUSH_FIFO_DEFAULT_SIZE 16 +#define STREAMING_FIFO_DEFAULT_SIZE 256 + +/******************************************************************************/ +/* Types definitions */ +/******************************************************************************/ + +/* +Structure of Service_ID: + + 31 23 15 7 0 + / FIFOEVT_INDEX / TASK_ID / OPENSERVICE / INSTANCE / + +Instance and TASK_ID are handled by Service module +*/ + +#define WRITE_INSTANCE_NUM_IN_SERVICE_ID(instanceNb,serviceId) \ +(serviceId = ((serviceId & ~MASK_BYTE0) | ((t_sva_service_id)instanceNb & MASK_BYTE0))) + +#define READ_INSTANCE_NUM_IN_SERVICE_ID(serviceId) \ +((t_sva_service_instance_num) (serviceId & MASK_BYTE)) + +#define WRITE_OPEN_SERVICE_NUM_IN_SERVICE_ID(serviceType,serviceId) \ +(serviceId = ((serviceId & ~MASK_BYTE1) | (((t_sva_service_id)serviceType & MASK_BYTE0)<>SHIFT_BYTE1)) + +#define WRITE_TASK_ID_IN_SERVICE_ID(taskId,serviceId) \ +(serviceId = ((serviceId & ~MASK_BYTE2) | (((t_sva_service_id)taskId & MASK_BYTE0)<>SHIFT_BYTE2)) + + +#define WRITE_FIFO_ID_IN_SERVICE_ID(fifoId,serviceId) \ +(serviceId = ((serviceId & ~MASK_BYTE3) | (((t_sva_service_id)fifoId & MASK_BYTE0)<>SHIFT_BYTE3)) + + +#define CHECK_NULL_POINTER(pointer) \ +do {if (pointer==NULL) {return SVA_NULL_POINTER_PARAMETER;}} while(0) + +/* + * Define a macro that compute the given mask linked to a structure field corresponding to a field (16 or 32 bits access) + * i.e mask used to update it (for exemple: PARAM_ONE_FIELD16_MASK(source_frame_height,t_sva_dpl_param_in) gives 0x02 + */ +#define PARAM_ONE_FIELD16_MASK(structureType,fieldName) \ + (1 << (HCL_BITHCL_BITFIELD_OFFSET(structureType, fieldName)/sizeof(t_uint16))) + +#define PARAM_ONE_FIELD32_MASK(structureType,fieldName) \ + (1 << (HCL_BITHCL_BITFIELD_OFFSET(structureType, fieldName)/sizeof(t_uint32))) + +#define PARAM_ALL_FIELDS16_MASK(structureType) \ + ((1 << (sizeof(structureType)/sizeof(t_uint16)))-1) + +#define PARAM_ALL_FIELDS32_MASK(structureType) \ + ((1 << (sizeof(structureType)/sizeof(t_uint32)))-1) + +/* + * Define the macro used to test if the first parameter is in the correct range + */ +#define TEST_RANGE(param, valMin, valMax) \ + (((param) >= (valMin)) && ((param) <= (valMax))) + +#define TEST_RANGE0(param, valMin, valMax) \ + ((param) <= (valMax)) + +/* + * Define the macro used to test if the first parameter has the correct alignment constraint + */ +#define TEST_ALIGNMENT(param, value) \ + (((param)%(value)) == 0) + +/* + * Define the macro used to check if the first parameter is in the correct range + * if it is not the case then return FALSE + */ +#define CHECK_RANGE(param, valMin, valMax) \ + do { \ + if (!TEST_RANGE(param, valMin, valMax)) {return FALSE;} \ + } while(0) + +#define CHECK_RANGE0(param, valMin, valMax) \ + do { \ + if (!TEST_RANGE0(param, valMin, valMax)) {return FALSE;} \ + } while(0) + +/* + * Define the macro used to check if the first parameter has the correct alignment constraint + * if it is not the case then return FALSE + */ +#define CHECK_ALIGNMENT(param, value) \ + do { \ + if (!TEST_ALIGNMENT(param, value)) {return FALSE;} \ + } while(0) + + +/* + * Define a macro used to test a critical condition in order to prevent an array overflow + */ +#define CHECK_TABLE_OVERFLOW(nextIndex, maxIndex, errorCode) \ + {if (nextIndex>=maxIndex) { \ + HCL_DEBUG_ASSERT(1==0); \ + return(errorCode);}} + +/* + * Definition of the type used to link together a buffer and its related timestamp + */ +typedef struct { + t_sva_buffer_id bufferId; + t_sva_timestamp timestamp; +} t_sva_timestamped_buffer_id; + +typedef enum { +SVA_SV_ERROR =-1, +SVA_SV_OK = HCL_OK, +SVA_SV_VP_DISPATCH_REQUESTED = 15 +}t_sva_sv_error; + +typedef enum { +SVA_SV_MPEG4_ALGO =0, +SVA_SV_H264_ALGO =1, +SVA_SV_VC1_ALGO =2, +SVA_SV_MPEG2_ALGO =3, +SVA_SV_H263_ALGO =4 +}t_sva_sv_algo; + + +typedef enum { +SVA_SV_JPEG_ALGO =0, +SVA_SV_XXX_ALGO = 1 +}t_sva_sv_still_algo; + + + +typedef t_sva_sv_error (*tp_sva_sv_DispatchHwEvent) ( t_sva_tm_virtual_hw_event_id, t_sva_service_id, t_sva_tm_subtask_id, t_uint32, t_uint32, t_uint8,t_sva_event_desc *,t_uint32* ); + + +/* + * Define the symbols used to identify the various services + * supported inside the HCL + */ +typedef enum { + SVA_SV_GRAB_TID = 1, + SVA_SV_DECODE_TID = 2, + SVA_SV_ENCODE_TID = 3, + SVA_SV_DISPLAY_TID = 4, + SVA_SV_STILL_ENCODE_TID = 5, + SVA_SV_STILL_DECODE_TID = 6, + SVA_SV_TVO_TID = 7, + SVA_SV_STAB_TID = 8, + SVA_SV_OPEN_SERVICE=128 +} t_sva_sv_task_id; + +/* + * Define type to handle instance number + */ +typedef t_uint8 t_sva_service_instance_num; + +/******************************************************************************* +* PUBLIC Functions +*******************************************************************************/ + + +/* +t_sva__error SVA__Init( t_logical_address ); + +t_sva__error SVA__Reset( t_sva_service_id ); + +t_sva__error SVA__Create( t_sva_service_id *); + +#### Name to be discussed : +#t_sva_error SVA_Configure( t_sva_service_id, t_sva__configuration); + +### Added: +#t_sva__error SVA__ProvideInternalNeeds( t_sva_service_id); + +t_sva__error SVA__Control(t_sva_service_id, t_sva_cmd_id, t_sva_timestamp ); + +#### Name to be discussed : +#t_sva__error SVA__UpdateParams(t_sva_service_id, t_sva_update_cmd_type, t_sva__param_id, t_uint32); + +t_sva__error SVA__Push(t_sva_service_id, t_sva_buffer_id, t_sva_push_mode, t_sva_buffer_type, t_sva_timestamp ); + +t_sva__error SVA__Status(t_sva_service_id, t_sva__status * ); + +t_sva__error SVA__DispatchVirtualHwEvent(t_sva_virtual_hw_event_id, t_sva_service_id, t_sva_subtask_id, t_sva_ticks, t_uint8, t_sva_event_desc *, t_uint32 *); + +#### Added: +#t_sva__error SVA__GetInternalNeeds(t_sva_service_id, t_size *) + +t_sva__error SVA__Activate(t_sva_service_id); + +t_sva__error SVA__Deactivate(t_sva_service_id); + +t_sva__error SVA__Delete(t_sva_service_id ); +*/ + + + + +#endif /* __INC_SVA_SERVICE_H */ +/* End of file - SVA.h */ --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/common/sva_timemgt.c @@ -0,0 +1,486 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ + +/*------------------------------------------------------------------------ + * Includes + *----------------------------------------------------------------------*/ +#include "hcl_defs.h" +#include "sva.h" +#include "sva_hwp.h" +#include "sva_timemgt.h" +#include "sva_timemgtp.h" +#include "sva_service.h" + +/*------------------------------------------------------------------------ + * Global Variables + *----------------------------------------------------------------------*/ + +PRIVATE t_sva_regs_mapping *pSVARegs; //sva_hwp.h +PRIVATE t_uint32 inputTimerClkInHz; +t_sva_ti_system_time systemTimeDesc[SVA_NB_MAX_SERVICE]; + +/*------------------------------------------------------------------------ + * Private Macros + *----------------------------------------------------------------------*/ +#define SYSTEM_TIME_NORMALIZE(systemTime) \ + (t_uint32)(((t_uint64)systemTime*(t_uint64)inputTimerClkInHz)/(t_uint64)SYSTEM_TIME_FREQUENCY) + +#define TICKS_NORMALIZE(ticks) \ + (t_uint32)(((t_uint64)ticks*(t_uint64)SYSTEM_TIME_FREQUENCY)/(t_uint64)inputTimerClkInHz) + +/*------------------------------------------------------------------------ + * PRIVATE Functions Prototypes + *----------------------------------------------------------------------*/ + +/*------------------------------------------------------------------------ + * PUBLIC Functions Prototypes + *----------------------------------------------------------------------*/ + +/****************************************************************************/ +/* NAME: sva_TI_Init ( */ +/* t_logical_address RegLogicalBaseAddr, */ +/* t_logical_address MemLogicalBaseAddr, */ +/* t_uint32 timerClkInHz) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine initializes the HV HCL Time management */ +/* */ +/* PARAMETERS: */ +/* IN : - RegLogicalBaseAddr : SVA Registers base address */ +/* - MemLogicalBaseAddr : SVA Memory base address */ +/* - timerClkInHz : frequency of the input clock */ +/* */ +/* OUT: none */ +/* */ +/* RETURN: */ +/* t_sva_error: SVA_OK */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: no */ +/****************************************************************************/ +PUBLIC t_sva_error sva_TI_Init(t_logical_address RegLogicalBaseAddr, + t_logical_address MemLogicalBaseAddr, + t_uint32 timerClkInHz) +{ + + t_uint8 i=0; + (void)MemLogicalBaseAddr; + pSVARegs = (t_sva_regs_mapping *)RegLogicalBaseAddr; + inputTimerClkInHz = timerClkInHz; + for(i=0; icfg.cfg_tic; + + return SVA_OK; +} /* End of sva_TI_GetCurrentTicksValue() function. */ + +/****************************************************************************/ +/* NAME: sva_TI_ConvertHzToTicks( */ +/* t_uint32 frequencyInHz) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine computes the equivalent number of ticks of a given freq. */ +/* */ +/* PARAMETERS: */ +/* IN : - frequencyInHz: frequency in Hz to convert */ +/* */ +/* OUT: none */ +/* */ +/* RETURN: */ +/* t_sva_ticks: Number of ticks */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: no */ +/****************************************************************************/ +PUBLIC t_sva_ticks sva_TI_ConvertHzToTicks(t_uint32 frequencyInHz) +{ + t_sva_ticks value = 0; + HCL_DEBUG_ASSERT(frequencyInHz != 0); + value = (inputTimerClkInHz/frequencyInHz) + + (((inputTimerClkInHz%frequencyInHz) > (frequencyInHz>>1))?1:0); + + return value; +} /* End of sva_TI_ConvertHzToTicks() function. */ + +/****************************************************************************/ +/* NAME: sva_TI_ConvertSystemTimeToTicks( */ +/* t_uint32 systemTimeValue) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine computes the equivalent number of ticks of given a system */ +/* time value. */ +/* */ +/* PARAMETERS: */ +/* IN : - systemTimeValue: System Time value to convert */ +/* */ +/* OUT: none */ +/* */ +/* RETURN: */ +/* t_sva_ticks: Number of ticks */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: no */ +/****************************************************************************/ +PUBLIC t_sva_ticks sva_TI_ConvertSystemTimeToTicks(t_uint32 serviceId, t_uint32 systemTimeValue) +{ + t_sva_ticks value = 0; + t_uint8 index; + + systemTimeValue = SYSTEM_TIME_NORMALIZE(systemTimeValue); + index = READ_FIFO_ID_IN_SERVICE_ID(serviceId); + value = systemTimeValue - systemTimeDesc[index].systemTimeOffsetInTicks; + return value; + +} /* End of sva_TI_ConvertSystemTimeToTicks() function. */ + +/****************************************************************************/ +/* NAME: sva_TI_ConvertTicksToSystemTime( */ +/* t_sva_ticks ticksValue) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine computes the equivalent system time value of a given */ +/* number of ticks. */ +/* */ +/* PARAMETERS: */ +/* IN : - ticksValue: Ticks value to convert */ +/* */ +/* OUT: none */ +/* */ +/* RETURN: */ +/* t_uint32: System time value */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: no */ +/****************************************************************************/ +PUBLIC t_uint32 sva_TI_ConvertTicksToSystemTime(t_sva_service_id serviceId, t_sva_ticks ticksValue ) +{ + + t_uint32 value; + t_uint8 index = 0; + + index = READ_FIFO_ID_IN_SERVICE_ID(serviceId); + value = ticksValue + systemTimeDesc[index].systemTimeOffsetInTicks; + if((systemTimeDesc[index].systemTimeOffsetInTicks < 0) && ((t_uint32)-systemTimeDesc[index].systemTimeOffsetInTicks > ticksValue)) + { + value = systemTimeDesc[index].newTimeValue; + } + value = TICKS_NORMALIZE(value); + return value; + +} /* End of sva_TI_ConvertTicksToSystemTime() funtion. */ + +/****************************************************************************/ +/* NAME: sva_TI_SaveSystemTimeContext( */ +/* t_sva_service_id serviceId) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine saves all current System Times of a given service in order*/ +/* to restore them later */ +/* */ +/* PARAMETERS: */ +/* IN : - serviceId : service identifier */ +/* */ +/* OUT: none */ +/* */ +/* RETURN: */ +/* t_sva_error: SVA_OK */ +/* SVA_UNKNOWN_SERVICE_ID */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: no */ +/****************************************************************************/ +PUBLIC t_sva_error sva_TI_SaveSystemTimeContext(void) +{ + t_uint8 index; + t_sva_ticks value; + t_uint32 ticksTimeValue; + + sva_TI_GetCurrentTicksValue(&value); + + for (index = 0; index. */ +/*---------------------------------------------------------------------------*/ + +#ifndef __INC_SVA_TI_H +#define __INC_SVA_TI_H + +#include "hcl_defs.h" +#include "sva.h" + +/******************************************************************************/ +/* Constants definitions */ +/******************************************************************************/ + +/* + * Definition of the Nb Max of Services: to be put in a common.h file + */ + +#define SVA_NB_MAX_SERVICE 64 + + +/* + * Definition of the System Time frequency + */ +#define SYSTEM_TIME_FREQUENCY 90000 + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/******************************************************************************/ +/* Types definitions */ +/******************************************************************************/ +/* + * Define the type use to manage HV internal timer ticks + */ +typedef t_uint32 t_sva_ticks; + + +/******************************************************************************* +* PUBLIC Functions +*******************************************************************************/ +PUBLIC t_sva_error sva_TI_Init(t_logical_address, t_logical_address, t_uint32); + +/* Time/synchronization Management */ +/* Implemented here but prototyped into sva.h */ +/*PUBLIC t_sva_error SVA_SetServiceSystemTime(t_sva_service_id, t_uint32); see sva.h */ +/*PUBLIC t_sva_error SVA_GetServiceSystemTime(t_sva_service_id, t_uint32 *); see sva.h */ + + + +PUBLIC t_sva_error sva_TI_GetCurrentTicksValue(t_sva_ticks * ); +PUBLIC t_sva_ticks sva_TI_ConvertHzToTicks( t_uint32 ); +PUBLIC t_sva_ticks sva_TI_ConvertSystemTimeToTicks(t_sva_service_id, t_uint32 ); +PUBLIC t_uint32 sva_TI_ConvertTicksToSystemTime( t_sva_service_id, t_sva_ticks ); +PUBLIC t_sva_error sva_TI_SaveSystemTimeContext(void); +PUBLIC t_sva_error sva_TI_RestoreSystemTimeContext(void); +t_bool sva_IsServiceTimeRunning(t_sva_service_id); + +#ifdef __cplusplus +} /* allow C++ to use these headers */ +#endif /* __cplusplus */ + +#endif /* __INC_SVA_TI_H */ +/* End of file - sva_timemgt.h */ --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/common/sva_timemgtp.h @@ -0,0 +1,49 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ + +#ifndef __INC_SVA_TIP_H +#define __INC_SVA_TIP_H + +#include "hcl_defs.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* + * Define the structure used to identify system_time per service + */ + +typedef struct { + t_sva_service_id serviceId; + t_sint32 systemTimeOffsetInTicks; + t_uint32 savedSystemTime; + t_bool is_service_time_running; + t_uint32 savedSystemTimeAtStopping; /*saved time when service system time was stopped*/ + t_uint32 newTimeValue; +}t_sva_ti_system_time; + + +#ifdef __cplusplus +} /* allow C++ to use these headers */ +#endif /* __cplusplus */ + +#endif /* __INC_SVA_TIP_H */ +/* End of file - sva_timemgt.h */ + --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/common/svap.h @@ -0,0 +1,188 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ + +#ifndef __INC_SVAP_H +#define __INC_SVAP_H + +#include "hcl_defs.h" + +/******************************************************************************/ +/* Constants definitions */ +/******************************************************************************/ +/* + * Define various conditonnal compilation flags in order to include or not any SW workarounds + */ +/*#define WORK_AROUND_AHB*/ + +/* + * Define the maximum number of error defined per module + */ +#define SVA_MODULE_ERROR_RANGE 0x20 + +/* + * Define an Id related to each module of the SVA HCL + * The Id = 1 is reserved for SVA HCL itself + */ +typedef enum { + SVA_EM_ID = 2, /* Events Mgt */ + SVA_MM_ID, /* Memory Mgt */ + SVA_BM_ID, /* Buffers Mgt */ + SVA_BLM_ID, /* Buffers ListMgt */ + SVA_TM_ID, /* Tasks Mgt */ + SVA_FM_ID, /* Firmware Mgt */ + SVA_TI_ID, /* Time Mgt */ + SVA_VP_ID, /* Video Pipeline */ + SVA_FF_ID, /* FIFO macros */ + SVA_IN_ID, /* Internal Needs Mgt */ + SVA_SV_ID, /* Common Service */ + SVA_DP_ID, /* Display Service */ + SVA_DC_ID, /* Decode Service */ + SVA_EC_ID, /* Encode Service */ + SVA_GB_ID, /* Grab Service */ + SVA_DC_ERC_ID, /* Decode Error Concealment */ + SVA_DC_MP4_ID, /* Decode MPEG4 Algo */ + SVA_DC_H263_ID, /* Decode H263 Algo */ + SVA_DC_H264_ID, /* Decode H263 Algo */ + SVA_EC_BRC_ID, /* Encode Bit Rate Control */ + SVA_EC_MP4_ID, /* Encode MPEG4 Algo */ + SVA_EC_H263_ID, /* Encode H263 Algo */ + SVA_EC_H264_ID, /* Encode H264 Algo */ + SVA_EC_STAB_ID, /* Encode Stabilization */ + SVA_SEC_JPEG_ID, /* Still Encode JPEG ALgo */ + SVA_SEC_ID, /* still Encode service */ + SVA_TV_ID /* TVO Service */ +} sva_module_id; + +/* ************************** CONFIGURATION PART ************************** */ +typedef struct { + t_uint32 cfg_psa; /* Subtask parameter Start Address register */ + t_uint32 cfg_pea; /* Subtask parameter Stop Address register */ + t_uint32 cfg_ice; /* Idle Cycle Enable register */ + t_uint32 cfg_csc; /* CCP synchronization codes register */ + t_uint32 cfg_cgc; /* clock gating control register */ + t_uint32 cfg_irp_fw_addr; /* start address eWarp firmware */ + t_uint32 cfg_irp_fw_size; /* size in bytes of eWarp firmware */ + t_uint32 cfg_irp_rw; /* status of the current rw operation */ + t_uint32 cfg_irp_error; /* error code */ + t_uint32 cfg_irp_bs; /* start of circular buffer for rw packet */ + t_uint32 cfg_irp_be; /* end of circular buffer for rw packet */ + t_uint32 cfg_irp_ptr; /* ptr of circular buffer for rw packet */ + t_uint32 cfg_clk; /* Clock generation register */ + t_uint32 ckg_cken; /* added*/ + t_uint32 cfg_tim; /* Timer Initialization value register */ + t_uint32 cfg_iis; /* IRQ1 Interrupt Status register */ + t_uint32 cfg_isr; /* Global Interrupt status register */ + t_uint32 cfg_imr; /* Global Interrupt mask register */ +// t_uint32 wasDeepSleepEntered; + t_uint32 temp_idn_frv; + t_sva_fw_id fwId; + t_uint32 sva_context_magic_number; +} t_sva_config_regs_mapping1; + +#define SVA_CONTEXT_MAGIC_NUMBER 0x53415645UL + +#define SVA_EM_LAST_ERROR (-(SVA_EM_ID * SVA_MODULE_ERROR_RANGE)) +#define SVA_EM_FIRST_INFO (+((SVA_DP_ID - 1) * SVA_MODULE_ERROR_RANGE)) + +#define SVA_MM_LAST_ERROR (-(SVA_MM_ID * SVA_MODULE_ERROR_RANGE)) +#define SVA_MM_FIRST_INFO (+((SVA_MM_ID - 1) * SVA_MODULE_ERROR_RANGE)) + +#define SVA_BM_LAST_ERROR (-(SVA_BM_ID * SVA_MODULE_ERROR_RANGE)) +#define SVA_BM_FIRST_INFO (+((SVA_BM_ID - 1) * SVA_MODULE_ERROR_RANGE)) + +#define SVA_BLM_LAST_ERROR (-(SVA_BLM_ID * SVA_MODULE_ERROR_RANGE)) +#define SVA_BLM_FIRST_INFO (+((SVA_BLM_ID - 1) * SVA_MODULE_ERROR_RANGE)) + +#define SVA_TM_LAST_ERROR (-(SVA_TM_ID * SVA_MODULE_ERROR_RANGE)) +#define SVA_TM_FIRST_INFO (+((SVA_TM_ID - 1) * SVA_MODULE_ERROR_RANGE)) + +#define SVA_FM_LAST_ERROR (-(SVA_FM_ID * SVA_MODULE_ERROR_RANGE)) +#define SVA_FM_FIRST_INFO (+((SVA_FM_ID - 1) * SVA_MODULE_ERROR_RANGE)) + +#define SVA_TI_LAST_ERROR (-(SVA_TI_ID * SVA_MODULE_ERROR_RANGE)) +#define SVA_TI_FIRST_INFO (+((SVA_TI_ID - 1) * SVA_MODULE_ERROR_RANGE)) + +#define SVA_FF_LAST_ERROR (-(SVA_FF_ID * SVA_MODULE_ERROR_RANGE)) +#define SVA_FF_FIRST_INFO (+((SVA_FF_ID - 1) * SVA_MODULE_ERROR_RANGE)) + +#define SVA_IN_LAST_ERROR (-(SVA_IN_ID * SVA_MODULE_ERROR_RANGE)) +#define SVA_IN_FIRST_INFO (+((SVA_IN_ID - 1) * SVA_MODULE_ERROR_RANGE)) + +#define SVA_SV_LAST_ERROR (-(SVA_SV_ID * SVA_MODULE_ERROR_RANGE)) +#define SVA_SV_FIRST_INFO (+((SVA_SV_ID - 1) * SVA_MODULE_ERROR_RANGE)) + +#define SVA_DP_LAST_ERROR (-(SVA_DP_ID * SVA_MODULE_ERROR_RANGE)) +#define SVA_DP_FIRST_INFO (+((SVA_DP_ID - 1) * SVA_MODULE_ERROR_RANGE)) + +#define SVA_DC_LAST_ERROR (-(SVA_DC_ID * SVA_MODULE_ERROR_RANGE)) +#define SVA_DC_FIRST_INFO (+((SVA_DC_ID - 1) * SVA_MODULE_ERROR_RANGE)) + +#define SVA_EC_LAST_ERROR (-(SVA_EC_ID * SVA_MODULE_ERROR_RANGE)) +#define SVA_EC_FIRST_INFO (+((SVA_EC_ID - 1) * SVA_MODULE_ERROR_RANGE)) + +#define SVA_GB_LAST_ERROR (-(SVA_GB_ID * SVA_MODULE_ERROR_RANGE)) +#define SVA_GB_FIRST_INFO (+((SVA_GB_ID - 1) * SVA_MODULE_ERROR_RANGE)) + +#define SVA_DC_ERC_LAST_ERROR (-(SVA_DC_ERC_ID * SVA_MODULE_ERROR_RANGE)) +#define SVA_DC_ERC_FIRST_INFO (+((SVA_DC_ERC_ID - 1) * SVA_MODULE_ERROR_RANGE)) + +#define SVA_DC_MP4_LAST_ERROR (-(SVA_DC_MP4_ID * SVA_MODULE_ERROR_RANGE)) +#define SVA_DC_MP4_FIRST_INFO (+((SVA_DC_MP4_ID - 1) * SVA_MODULE_ERROR_RANGE)) + +#define SVA_DC_H263_LAST_ERROR (-(SVA_DC_H263_ID * SVA_MODULE_ERROR_RANGE)) +#define SVA_DC_H263_FIRST_INFO (+((SVA_DC_H263_ID - 1) * SVA_MODULE_ERROR_RANGE)) + +#define SVA_DC_H264_LAST_ERROR (-(SVA_DC_H264_ID * SVA_MODULE_ERROR_RANGE)) +#define SVA_DC_H264_FIRST_INFO (+((SVA_DC_H264_ID - 1) * SVA_MODULE_ERROR_RANGE)) + + +#define SVA_EC_BRC_LAST_ERROR (-(SVA_EC_BRC_ID * SVA_MODULE_ERROR_RANGE)) +#define SVA_EC_BRC_FIRST_INFO (+((SVA_EC_BRC_ID - 1) * SVA_MODULE_ERROR_RANGE)) + +#define SVA_EC_MP4_LAST_ERROR (-(SVA_EC_MP4_ID * SVA_MODULE_ERROR_RANGE)) +#define SVA_EC_MP4_FIRST_INFO (+((SVA_EC_MP4_ID - 1) * SVA_MODULE_ERROR_RANGE)) + +#define SVA_EC_H263_LAST_ERROR (-(SVA_EC_H263_ID * SVA_MODULE_ERROR_RANGE)) +#define SVA_EC_H263_FIRST_INFO (+((SVA_EC_H263_ID - 1) * SVA_MODULE_ERROR_RANGE)) + +#define SVA_EC_H264_LAST_ERROR (-(SVA_EC_H264_ID * SVA_MODULE_ERROR_RANGE)) +#define SVA_EC_H264_FIRST_INFO (+((SVA_EC_H264_ID - 1) * SVA_MODULE_ERROR_RANGE)) + +#define SVA_EC_STAB_LAST_ERROR (-(SVA_EC_STAB_ID * SVA_MODULE_ERROR_RANGE)) +#define SVA_EC_STAB_FIRST_INFO (+((SVA_EC_STAB_ID - 1) * SVA_MODULE_ERROR_RANGE)) + +#define SVA_SEC_JPEG_LAST_ERROR (-(SVA_SEC_JPEG_ID * SVA_MODULE_ERROR_RANGE)) +#define SVA_SEC_JPEG_FIRST_INFO (+((SVA_SEC_JPEG_ID - 1) * SVA_MODULE_ERROR_RANGE)) + +#define SVA_SEC_LAST_ERROR (-(SVA_SEC_ID * SVA_MODULE_ERROR_RANGE)) +#define SVA_SEC_FIRST_INFO (+((SVA_SEC_ID - 1) * SVA_MODULE_ERROR_RANGE)) + +#define SVA_TV_LAST_ERROR (-(SVA_TV_ID * SVA_MODULE_ERROR_RANGE)) +#define SVA_TV_FIRST_ERROR (+((SVA_TV_ID - 1) * SVA_MODULE_ERROR_RANGE)) + +/******************************************************************************/ +/* Types definitions */ +/******************************************************************************/ + +#ifdef __cplusplus +} /* allow C++ to use these headers */ +#endif /* __cplusplus */ + +#endif /* __INC_SVAP_H */ +/* End of file - hvP.h */ --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/h264/sva_dc_h264.c @@ -0,0 +1,3030 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ +/*------------------------------------------------------------------------ + * Includes + *----------------------------------------------------------------------*/ +#include "hcl_defs.h" +#include "sva_decodep.h" //for NUM_MAX_DECODE +#include "sva_decodepp.h" // for sva_DC_func +#include "sva_fifo.h" +#include "sva_dc_h264.h" +#include "sva_dc_h264p.h" +#include "sva_dc_h264_dpb.h" + +#include "sva_dc_h264_slicemap.h" +#include "sva_buffermgt.h" + +/*private prototypes */ +PRIVATE t_sva_error sva_DC_H264_GetSliceMapBlockSize(t_sva_service_instance_num , t_size* ); +PRIVATE t_sva_error sva_DC_H264_GetInfoBlockSize(t_sva_service_instance_num , t_size* ); +PRIVATE t_sva_error sva_DC_H264_GetH4DSize(t_sva_service_instance_num , t_size* ); +PRIVATE t_sva_error sva_DC_H264_GetDeblockingSize(t_sva_service_instance_num , t_size* ); +PRIVATE t_sva_error sva_DC_H264_GetSlicesBlockSize(t_sva_service_instance_num , t_size* ); +PRIVATE t_sva_error sva_DC_H264_ComputeDPBSize(t_sva_service_instance_num, t_size*); +PRIVATE t_sva_error sva_DC_H264_SetParamsHeaderInfo(t_sva_service_instance_num, const t_sva_video_decoder_algo_h264_header_infos*, t_logical_address, t_size); +PRIVATE t_sva_error sva_DC_H264_GetNextSliceInfo(t_sva_service_instance_num, t_sva_h264_params_slice * , t_sva_block_id, t_uint32, t_uint32 * ); +//PRIVATE t_sva_error sva_DC_H264_ResetH264Desc(void); +PRIVATE t_sva_error sva_DC_H264_ResetH264Instance(t_sva_service_instance_num); +PRIVATE t_sva_error sva_DC_H264_GetFWFeatures (t_sva_service_instance_num, t_sva_fw_features* ); +PRIVATE t_sva_error sva_DC_H264_GetSubTaskType(t_sva_service_instance_num , t_sva_tm_subtask_type* ); +PRIVATE t_sva_error sva_DC_H264_GetPPPType(t_sva_service_instance_num, t_sva_tm_postprocessing_type*); +PRIVATE t_sva_error sva_DC_H264_GetNBMaxSlicePerFrame(t_sva_service_instance_num, t_uint32* ); +PRIVATE t_sva_error sva_DC_H264_TryToInitParamInFields(t_sva_service_instance_num ); +PRIVATE t_sva_error sva_DC_H264_SetParamIn(t_sva_service_instance_num, t_sva_block_id, t_sva_buffer_list_id, t_sva_buffer_id *, t_uint16*, t_uint16*); +PRIVATE t_sva_error sva_DC_H264_GetBlockIdFromPhysicalAddr(t_sva_service_instance_num, t_physical_address, t_sva_block_id*); +PRIVATE t_sva_error sva_DC_H264_GetSliceMapBlockIdFromPhysicalAddr(t_sva_service_instance_num, t_physical_address, t_sva_block_id*); +PRIVATE t_sva_error sva_DC_H264_GetInfoBlockIdFromPhysicalAddr(t_sva_service_instance_num, t_physical_address, t_sva_block_id*); +PRIVATE t_sva_error sva_DC_H264_GetPPS_SPSInfo(t_sva_service_instance_num, t_sva_h264_active_pps *, t_uint16*, t_sva_block_id ); +PRIVATE t_sva_error sva_DC_H264_FillParamIn(t_sva_service_instance_num, t_bool, t_sva_block_id ,t_uint32, t_sva_h264_params_slice , t_sva_h264_active_pps,t_sva_buffer_id *, t_sva_buffer_list_id ) ; +PRIVATE t_sva_error sva_DC_H264_ResetBlockInfo(t_sva_block_id, t_size); +PRIVATE t_bool sva_DC_H264_AreAllDependanciesResolved(t_sva_dc_subtask_dependencies); +PRIVATE t_sva_error sva_DC_H264_ResetBlock(t_system_address, t_size); + + +/* public global structure : shared with sva_dc_h264_slicemap.c*/ +PUBLIC t_sva_h264_desc h264Desc[NUM_MAX_DECODE]; + + +/* extern from decode.c */ +extern PUBLIC t_sva_dc_descriptor decodeDesc[NUM_MAX_DECODE]; +extern PUBLIC const t_sva_tm_field_ctrl_desc defaultDecodeFieldDescArray[NUMBER_OF_DECODE_ALGO_SUPPORTED][DECODE_FIELD_NUMBER]; +#ifdef SVA_H264_USER_MEMSET_NEEDED +extern void* memset(void* , t_sint32 , t_uint32 ); +#endif + +/****************************************************************************/ +/* NAME: sva_DC_H264_Init() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: This routine enables to store all statical parameters */ +/* PARAMETERS: */ +/* IN : */ +/* */ +/* */ +/* */ +/* OUT : */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/*--------------------------------------------------------------------------*/ +/* USE: NA */ +/* USED BY: NA */ +/****************************************************************************/ +PUBLIC t_sva_error sva_DC_H264_Init( + t_sva_service_instance_num instanceNum, + t_sva_codec_mode codecMode, + t_sva_image_desc imageDesc, + const t_sva_dc_algo_configuration_params *pconfParams) +{ + + t_sva_error svaError = SVA_OK; + t_size size; + t_sva_video_decoder_algo_h264_configuration_params *pH264ConfParams; + HCL_ASSERT(pconfParams!=NULL); + + sva_DC_H264_ResetH264Instance(instanceNum); + + /* store info */ + h264Desc[instanceNum].codecMode=codecMode; + h264Desc[instanceNum].picWidthInMbsMinus1=((imageDesc.width)>>4) -1; + h264Desc[instanceNum].picHeightInMapUnitsMinus1=((imageDesc.height)>>4) -1; + +#ifdef __DEBUG + h264Desc[instanceNum].dbgSliceCounter = 0; + h264Desc[instanceNum].dbgSliceIndex = 0; + h264Desc[instanceNum].dbgNbEvent = 0; + +#endif + + //Store static parameters (only levelIdc) + pH264ConfParams=(t_sva_video_decoder_algo_h264_configuration_params *)pconfParams; + h264Desc[instanceNum].staticParams=*pH264ConfParams; + + // INit Fifo + INIT_FIFO(h264Desc[instanceNum].sliceMapFifo.push); + INIT_FIFO(h264Desc[instanceNum].sliceMapFifo.inUse); + INIT_FIFO(h264Desc[instanceNum].slicesDescBlockIdFifo.push); + INIT_FIFO(h264Desc[instanceNum].slicesDescBlockIdFifo.inUse); + + + /* Init DPB Management block */ + /* ------------------------- */ + sva_DC_H264_DPB_InitInstance(instanceNum); + + /* SetDPBSize */ + svaError = sva_DC_H264_ComputeDPBSize(instanceNum, &size); + if(svaError!=SVA_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR; } + + sva_DC_H264_DPB_SetDPBSize(instanceNum, size); + + return svaError; +} + + +/****************************************************************************/ +/* NAME: sva_DC_H264_GetMemoryNeeds() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* OUT : */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/*--------------------------------------------------------------------------*/ +/* USE: NA */ +/* USED BY: NA */ +/****************************************************************************/ +PUBLIC t_sva_error sva_DC_H264_GetMemoryNeeds( + t_sva_service_instance_num instanceNum, + t_size *pMemNeeds) +{ + + t_sva_h264_dpb_error dpbError=SVA_DC_H264_DPB_OK; + t_sva_error svaError = SVA_OK; + t_size size; + + HCL_ASSERT(pMemNeeds!=NULL); + + *pMemNeeds = 0; + + /* pH264Desc->slicesDescBlockIdFifo */ + /* blockId FIFO for the following SetHeaderInfos parameters: slices descriptor */ + /* we do not know the frame size now thus we cannot create a fifo of t_sva_h264_slice since autorefered struct */ + /* thus on each setheaderinfo we'll create blocks with the right size to store these parameters */ + /* and we ll push it in this fifo */ + GET_FIFO_MEMORY_NEEDS(t_sva_block_id, PUSH_FIFO_DEFAULT_SIZE, size); + *pMemNeeds += size; + + GET_FIFO_MEMORY_NEEDS(t_sva_block_id, SUBTASK_DEFAULT_NUMBER, size); + *pMemNeeds += size; + + /* pH264Desc->sliceMapFifo */ + GET_FIFO_MEMORY_NEEDS(t_sva_h264_slicemap_info, PUSH_FIFO_DEFAULT_SIZE, size); + *pMemNeeds += size; + + GET_FIFO_MEMORY_NEEDS(t_sva_h264_slicemap_info, SUBTASK_DEFAULT_NUMBER, size); + *pMemNeeds += size; + + + /* GetInternalNeeds for DPB */ + /* ------------------------ */ + dpbError = sva_DC_H264_DPB_GetInternalNeeds(instanceNum, &size); + if(dpbError != SVA_DC_H264_DPB_OK) { svaError = SVA_INTERNAL_VIDEO_DECODER_ERROR;} + + *pMemNeeds += size; + + return svaError; + +} + + + +/****************************************************************************/ +/* NAME: sva_DC_H264_ProvideMemoryNeeds() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* OUT : */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/*--------------------------------------------------------------------------*/ +/* USE: NA */ +/* USED BY: NA */ +/****************************************************************************/ +PUBLIC t_sva_error sva_DC_H264_ProvideMemoryNeeds(t_sva_service_instance_num instanceNum ) +{ + t_sva_error svaError=SVA_OK; + t_sva_ff_error ffError=SVA_FIFO_OK; + t_sva_h264_dpb_error dpbError=SVA_DC_H264_DPB_OK; + t_sva_mm_error mmError = SVA_MM_OK; + t_sva_h264_desc * pH264Desc = &h264Desc[instanceNum]; + t_size infoSize=0, sliceMapSize=0, h4dSize=0, size=0; + t_uint32 i=0; + + +/* CREATE FIFO */ +/* ----------- */ + + /* pH264Desc->slicesDescBlockIdFifo */ + CREATE_FIFO(t_sva_block_id, PUSH_FIFO_DEFAULT_SIZE, pH264Desc->slicesDescBlockIdFifo.push, ffError); + if(ffError!=SVA_FIFO_OK) { return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + + CREATE_FIFO(t_sva_block_id, SUBTASK_DEFAULT_NUMBER, pH264Desc->slicesDescBlockIdFifo.inUse, ffError); + if(ffError!=SVA_FIFO_OK) { return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + + + /* pH264Desc->sliceMapFifo */ + CREATE_FIFO(t_sva_h264_slicemap_info, PUSH_FIFO_DEFAULT_SIZE, pH264Desc->sliceMapFifo.push, ffError); + if(ffError!=SVA_FIFO_OK) { return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + + CREATE_FIFO(t_sva_h264_slicemap_info, SUBTASK_DEFAULT_NUMBER, pH264Desc->sliceMapFifo.inUse, ffError); + if(ffError!=SVA_FIFO_OK) { return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + + +/* subtasks programming */ +/* -------------------- */ +/* alloc blocks for vdc_internal_buffer : FwSliceMap, FwBlockInfo and FwAux(h4d_buffer) */ +/* also alloc block deblocking_param_buffer in vdc_frame_buf_out */ + + + svaError=sva_DC_H264_GetInfoBlockSize (instanceNum, &infoSize); + if(svaError!=SVA_OK) { return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + pH264Desc->blockInfoSize = infoSize; + svaError=sva_DC_H264_GetSliceMapBlockSize (instanceNum, &sliceMapSize); + if(svaError!=SVA_OK) { return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + svaError=sva_DC_H264_GetH4DSize (instanceNum, &h4dSize); + if(svaError!=SVA_OK) { return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + + for(i=0; iblockInfoId[i]); + mmError=sva_MM_AllocDedicatedBlock(infoSize,SVA_MM_ALIGN_WORD, &pH264Desc->blockInfoId[i]); + if (mmError!= SVA_MM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + mmError=sva_MM_GetDedicatedBlockSystemAddress(pH264Desc->blockInfoId[i],&pH264Desc->blockInfoAddr[i]); + if (mmError!= SVA_MM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + + //sva_DC_H264_ResetBlock(pH264Desc->blockInfoAddr[i],infoSize); + + //mmError=sva_MM_AllocBlock(SDRAM_ID, sliceMapSize, SVA_MM_ALIGN_WORD, &pH264Desc->blockSliceMapId[i]); + mmError=sva_MM_AllocDedicatedBlock(sliceMapSize,SVA_MM_ALIGN_WORD, &pH264Desc->blockSliceMapId[i]); + if (mmError!= SVA_MM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + mmError=sva_MM_GetDedicatedBlockSystemAddress(pH264Desc->blockSliceMapId[i],&pH264Desc->blockSliceMapAddr[i]); + if (mmError!= SVA_MM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + + //sva_DC_H264_ResetBlock(pH264Desc->blockSliceMapAddr[i],sliceMapSize ); + + mmError= sva_MM_AllocBlock(ESRAM_ID, h4dSize, SVA_MM_ALIGN_256BYTES, &pH264Desc->blockH4DId[i]); + if (mmError!= SVA_MM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + mmError=sva_MM_GetBlockSystemAddress(pH264Desc->blockH4DId[i],&pH264Desc->blockH4DAddr[i]); + if (mmError!= SVA_MM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + + //sva_DC_H264_ResetBlock(pH264Desc->blockH4DAddr[i], h4dSize); + + } + + svaError=sva_DC_H264_GetDeblockingSize (instanceNum, &size); + if(svaError!=SVA_OK) { return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + mmError= sva_MM_AllocBlock(ESRAM_ID, size, SVA_MM_ALIGN_WORD, &pH264Desc->blockDeblockId); + if (mmError!= SVA_MM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + mmError=sva_MM_GetBlockSystemAddress(pH264Desc->blockDeblockId,&pH264Desc->blockDeblockAddr); + if (mmError!= SVA_MM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + + + svaError=sva_DC_H264_ResetBlock(pH264Desc->blockDeblockAddr, size); + if(svaError!=SVA_OK) { return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + + +/* alloc SUBTASK_DEFAULT_NUMBER blocks for NB MAX vdc_h264_slice*/ +/* We have to do it here with the max number of slices/frame (=nb of macroblocks) */ + svaError=sva_DC_H264_GetSlicesBlockSize (instanceNum, &size); + if(svaError!=SVA_OK) { return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + + for(i=0; iblockSlicesId[i]); + if (mmError!= SVA_MM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + mmError=sva_MM_GetBlockSystemAddress(pH264Desc->blockSlicesId[i],&pH264Desc->blockSlicesAddr[i]); + if (mmError!= SVA_MM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + } + + + + +/* Storing setHeaderInfos parameters*/ +/* ---------------------------------*/ +/* TBC: should it be done here with the MaxNbOfSlices/Frame?*/ +/* for now, it is done dynamically in the setHeaderInfo with right nbSlice/frame */ + + +/* ProvideInternalNeeds for DPB */ +/* ---------------------------- */ + dpbError = sva_DC_H264_DPB_ProvideInternalNeeds(instanceNum); + if(dpbError != SVA_DC_H264_DPB_OK) { svaError = SVA_INTERNAL_VIDEO_DECODER_ERROR;} + + + return svaError; +} + +/****************************************************************************/ +/* NAME: sva_DC_H264_CreateAndConfigSubtasksList() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* PARAMETERS: */ +/* IN : t */ +/* */ +/* OUT :none */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/*--------------------------------------------------------------------------*/ +/* USE: NA */ +/* USED BY: NA */ +/****************************************************************************/ +t_sva_error sva_DC_H264_CreateAndConfigSubtasksList(t_sva_service_instance_num instanceNum, t_sva_service_id serviceId) +{ + t_sva_error svaError=SVA_OK; + t_sva_tm_error tmError=SVA_TM_OK; + t_sva_ff_error ffError=SVA_FIFO_OK; + + + t_sva_dc_descriptor *pDesc=&decodeDesc[instanceNum]; + t_sva_video_decoder_configuration *pConf=&pDesc->confHandle.currentConf; + t_sva_h264_desc * pH264Desc = &h264Desc[instanceNum]; + + t_sva_tm_task_ctrl_desc decodeTaskDesc; + t_sva_tm_subtask_type subtaskType; + t_sva_tm_postprocessing_type pppType; + t_sva_fw_features fwFeature; + t_uint32 nbSlicePerFrame=1; + t_uint32 i, j; + + t_sva_vdc_internal_buf internalBuffer; + t_sva_vdc_frame_buffer_out frameBufferOut; + t_sva_vdc_h264_param_in paramIn; + + + /* create bitstream buffer list */ + /* ---------------------------- */ + + if(pConf->mode != SVA_CODEC_IMAGE_MODE) + { // one slice can belong to several buffers thus we have one bufferLIst by slice + // the max number of bufferLIst to allocate is the max number of slices in a frame. + svaError=sva_DC_H264_GetNBMaxSlicePerFrame(instanceNum, &nbSlicePerFrame ); + if(svaError != SVA_OK) { return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + } + // in image mode, one slice belongs to only one buffer. + + + for(i=0;ibufferListIdArray[i][j]); + } + + } + + /*create subtasks */ + /* -------------- */ + decodeTaskDesc.memId=DECODE_DEFAULT_MEMORY_ID; + decodeTaskDesc.fieldnb=DECODE_FIELD_NUMBER; + decodeTaskDesc.pfieldctrldesc=(t_sva_tm_field_ctrl_desc *)defaultDecodeFieldDescArray; + + svaError=sva_DC_H264_GetPPPType(instanceNum, &pppType); + if(svaError != SVA_OK) { return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + + svaError=sva_DC_H264_GetSubTaskType(instanceNum, &subtaskType); + if(svaError != SVA_OK) { return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + + + for(i=0;isubtasksIdArray[i]); + if (tmError != SVA_TM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + } + + /*create subtasklist */ + /* ----------------- */ + svaError=sva_DC_H264_GetFWFeatures(instanceNum, &fwFeature); + if(svaError != SVA_OK) { return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + + tmError=sva_TM_CreateSubTaskList(SVA_TM_DECODE,serviceId,fwFeature,&pDesc->subtasksListId); + if (tmError != SVA_TM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + + + /* init subtasksfields that are already OK */ + /* --------------------------------------- */ + /* t_sva_vdc_internal_buf */ + + + for(i=0; iblockInfoId[i], pH264Desc->blockInfoSize); + if (svaError!= SVA_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + + internalBuffer.addr_h264d_H4D_buffer = pH264Desc->blockH4DAddr[i].physical; + internalBuffer.addr_h264d_block_info = pH264Desc->blockInfoAddr[i].physical; + internalBuffer.addr_h264d_mb_slice_map = pH264Desc->blockSliceMapAddr[i].physical; + tmError=sva_TM_InitSubTaskField(pDesc->subtasksIdArray[i],SVA_TM_DEC_ADDR_INTERNAL_BUFFER,(t_uint32)&internalBuffer,sizeof(t_sva_vdc_internal_buf)); + if (tmError!= SVA_TM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + } + + /* t_sva_vdc_frame_buffer_out */ + frameBufferOut.addr_deblocking_param_buffer = pH264Desc->blockDeblockAddr.physical; + for(i=0; isubtasksIdArray[i],SVA_TM_DEC_ADDR_OUT_FRAME_BUFFER, (t_uint32)&frameBufferOut,sizeof(t_sva_vdc_frame_buffer_out)); + if (tmError!= SVA_TM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + } + + /* t_sva_vdc_h264_param_in : allows to link the SliceDesc block with the subtask */ + for(i=0; iblockSlicesAddr[i].physical)|0x1; + paramIn.DBLK_flag = pConf->inTheLoopFilter; + paramIn.ERC_used = pConf->ercMode; + tmError=sva_TM_InitSubTaskField(pDesc->subtasksIdArray[i],SVA_TM_DEC_ADDR_IN_PARAMETERS,(t_uint32)¶mIn,sizeof(t_sva_vdc_h264_param_in)); + if (tmError!= SVA_TM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + } + + + /* Set default dependencies */ + /* ------------------------ */ + pDesc->defaultDep.outputImageDep=NOT_RESOLVED_DEPENDENCY; + pDesc->defaultDep.inputBitstreamDep=NOT_RESOLVED_DEPENDENCY; + if(pConf->areInfosRequested == FALSE) pDesc->defaultDep.infosDep =INTERNAL_DEPENDENCY; + else pDesc->defaultDep.infosDep=NOT_RESOLVED_DEPENDENCY; + + /* Push subtask in subtasksDependencyFifo since they are ready to be solved */ + /* ------------------------------------------------------------------------ */ + for(i=0;isubtasksIdArray[i]; + subtaskDep.bitstreamBufferListId=pDesc->bufferListIdArray[i][0]; + subtaskDep.dependencies=pDesc->defaultDep; + ffError=PUSH_FIFO_ELEM(pDesc->subtasksDependencyFifo.push, t_sva_dc_subtask_dependencies, subtaskDep); + if (ffError!=SVA_FIFO_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + } + + + + return svaError; + +} + + +/****************************************************************************/ +/* NAME: sva_DC_H264_Close() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* PARAMETERS: */ +/* IN : t */ +/* */ +/* OUT :none */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/*--------------------------------------------------------------------------*/ +/* USE: NA */ +/* USED BY: NA */ +/****************************************************************************/ +PUBLIC t_sva_error sva_DC_H264_Close(t_sva_service_instance_num instanceNum) +{ + t_sva_error svaError=SVA_OK; + t_sva_mm_error mmError = SVA_MM_OK; + t_sva_h264_dpb_error dpbError=SVA_DC_H264_DPB_OK; + t_sva_h264_desc * pH264Desc = &h264Desc[instanceNum]; + t_uint16 i; + +/* Free blocks from internal needs */ + for(i=0; iblockInfoId[i]); + if (mmError!= SVA_MM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + + + mmError=sva_MM_FreeDedicatedBlock(pH264Desc->blockSliceMapId[i]); + if (mmError!= SVA_MM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + + + mmError= sva_MM_FreeBlock(pH264Desc->blockH4DId[i]); + if (mmError!= SVA_MM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + + mmError= sva_MM_FreeBlock(pH264Desc->blockSlicesId[i]); + if (mmError!= SVA_MM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + + } + + mmError= sva_MM_FreeBlock(pH264Desc->blockDeblockId); + if (mmError!= SVA_MM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + + //sva_MM_ResetDedicatedMemory(); + +/* delete fifo */ + + DELETE_FIFO(pH264Desc->slicesDescBlockIdFifo.push); + DELETE_FIFO(pH264Desc->slicesDescBlockIdFifo.inUse); + DELETE_FIFO(pH264Desc->sliceMapFifo.push); + DELETE_FIFO(pH264Desc->sliceMapFifo.inUse); + + + +/* call close dpb management block */ + dpbError = sva_DC_H264_DPB_Close(instanceNum); + if(dpbError!=SVA_DC_H264_DPB_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + + + + + + return svaError; +} + + +/****************************************************************************/ +/* NAME: sva_DC_H264_InitHeaderInfo(t_sva_service_instance_num) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/*****************************************************************************/ +PUBLIC t_sva_error sva_DC_H264_InitHeaderInfos(t_sva_service_instance_num instanceNum) +{ + t_sva_error svaError=SVA_OK; + + return svaError; +} + +/****************************************************************************/ +/* NAME: sva_DC_H264_SetHeaderInfos() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* PARAMETERS: */ +/* IN : */ +/* OUT : */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/*--------------------------------------------------------------------------*/ +/* USE: NA */ +/* USED BY: NA */ +/****************************************************************************/ +PUBLIC t_sva_error sva_DC_H264_SetHeaderInfos( + t_sva_service_instance_num instanceNum, + t_sva_service_id serviceId, + t_sva_buffer_id bufferId, + t_uint32 dummy0, + t_uint32 dummy1, + const t_sva_header_infos *pHeaderInfos) +{ + t_sva_error svaError=SVA_OK; + t_sva_ff_error ffError=SVA_FIFO_OK; + t_sva_mm_error mmError = SVA_MM_OK; + t_sva_h264_dpb_error dpbError = SVA_DC_H264_DPB_OK; + t_sva_block_id blockId; + t_sva_buffer_id destBufferId; + t_uint32 size; + t_logical_address destAddr; + t_sva_h264_dpb_desc dpb; + t_uint16 i; + //t_sva_h264_slicemap_info sliceMap; + //t_sva_h264_dpb_sps_utils spsForDpb; + //t_sva_h264_dpb_slice0_utils slice0ForDpb; + + t_sva_h264_desc * pH264Desc = &h264Desc[instanceNum]; + t_sva_dc_descriptor *pDesc=&decodeDesc[instanceNum]; + t_sva_video_decoder_algo_h264_header_infos *pH264HeaderInfos = (t_sva_video_decoder_algo_h264_header_infos *)(pHeaderInfos);; + + + +/* push SliceMap related parameters in its fifo */ +/* -------------------------------------------- */ + pH264Desc->sliceMap.slice0SliceGroupChangeCycle = pH264HeaderInfos->slice0SliceGroupChangeCycle; + + pH264Desc->sliceMap.sliceGroupMapType = pH264HeaderInfos->sliceGroupMapType; + pH264Desc->sliceMap.numSliceGroupsMinus1 = pH264HeaderInfos->numSliceGroupsMinus1; + pH264Desc->sliceMap.sliceGroupChangeDirFlag = pH264HeaderInfos->sliceGroupChangeDirFlag; + pH264Desc->sliceMap.sliceGroupChangeRateMinus1 = pH264HeaderInfos->sliceGroupChangeRateMinus1; + for(i=0;i<8;i++) + { + pH264Desc->sliceMap.runLenghtMinus1[i] = pH264HeaderInfos->runLenghtMinus1[i]; + pH264Desc->sliceMap.bottomRight[i] = pH264HeaderInfos->bottomRight[i]; + pH264Desc->sliceMap.topLeft[i] = pH264HeaderInfos->topLeft[i]; + } + for(i=0;i<1620;i++) + pH264Desc->sliceMap.sliceGroupId[i] = pH264HeaderInfos->sliceGroupId[i] ; + + ffError = PUSH_FIFO_ELEM(pH264Desc->sliceMapFifo.push, t_sva_h264_slicemap, pH264Desc->sliceMap); + if(ffError!=SVA_FIFO_OK) { return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + +/* alloc blocks with the right size, store parameters and push blockId in the fifo */ +/* --------------------------------------------------------------------------------- */ + + /* size of the block to be allocated- in bytes*/ + size = sizeof(pH264HeaderInfos->nbSlicesInFrame) + sizeof(pH264Desc->staticParams.log2MaxFrameNumMinus4) + sizeof(t_sva_h264_active_pps) + sizeof(t_uint16) + + pH264HeaderInfos->nbSlicesInFrame * sizeof(t_sva_h264_params_slice); /* dummy has been added to be aligned */ + + mmError = sva_MM_AllocBlock(SDRAM_ID, size, SVA_MM_ALIGN_WORD, &blockId); + if (mmError!= SVA_MM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + mmError=sva_MM_GetBlockLogicalAddress(blockId,&destAddr); + if (mmError!= SVA_MM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + + svaError = sva_DC_H264_SetParamsHeaderInfo(instanceNum, pH264HeaderInfos, destAddr, size); + if(svaError!= SVA_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + + ffError = PUSH_FIFO_ELEM(pH264Desc->slicesDescBlockIdFifo.push, t_sva_block_id, blockId); + if(ffError!=SVA_FIFO_OK) { return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + + +/* Provide dpb params to dpb Management Block */ +/* ------------------------------------------- */ + + pH264Desc->spsForDpb.numRefFrames = pH264Desc->staticParams.numRefFrames; //pH264HeaderInfos->numRefFrames; + pH264Desc->spsForDpb.gapsInFrameNumValueFlag = pH264Desc->staticParams.gapsInFrameNumValueFlag;//pH264HeaderInfos->gapsInFrameNumValueFlag; + pH264Desc->spsForDpb.picOrderCntType = pH264Desc->staticParams.picOrderCntType;//pH264HeaderInfos->picOrderCntType; + pH264Desc->spsForDpb.log2MaxFrameNumMinus4 =pH264Desc->staticParams.log2MaxFrameNumMinus4;//pH264HeaderInfos->log2MaxFrameNumMinus4; + pH264Desc->spsForDpb.log2MaxPicOrderCntLsbMinus4 =pH264Desc->staticParams.log2MaxPicOrderCntLsbMinus4;//pH264HeaderInfos->log2MaxPicOrderCntLsbMinus4; + pH264Desc->spsForDpb.offsetForNonRefPic = pH264Desc->staticParams.offsetForNonRefPic;//pH264HeaderInfos->offsetForNonRefPic; + pH264Desc->spsForDpb.numRefFramesInPicOrderCntCycle =pH264Desc->staticParams.numRefFramesInPicOrderCntCycle;//pH264HeaderInfos->numRefFramesInPicOrderCntCycle; + pH264Desc->spsForDpb.offsetForTopToBottomField=pH264Desc->staticParams.offsetForTopToBottomField;//pH264HeaderInfos->numRefFramesInPicOrderCntCycle ; + pH264Desc->spsForDpb.picWidthInMbsMinus1=pH264Desc->picWidthInMbsMinus1; + pH264Desc->spsForDpb.picHeightInMapUnitsMinus1=pH264Desc->picHeightInMapUnitsMinus1; + for(i=0; i<256; i++) + pH264Desc->spsForDpb.offsetForRefFrame[i]=pH264Desc->staticParams.offsetForRefFrame[i];//pH264HeaderInfos->offsetForRefFrame[i]; + + dpbError = sva_DC_H264_DPB_SetActiveSPSUtils(instanceNum, &pH264Desc->spsForDpb); + if(dpbError != SVA_DC_H264_DPB_OK) { return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + + + pH264Desc->slice0ForDpb.nut=pH264HeaderInfos->slice0Nut; + pH264Desc->slice0ForDpb.nri=pH264HeaderInfos->slice0Nri; + pH264Desc->slice0ForDpb.frameNum=pH264HeaderInfos->slice0FrameNum; + pH264Desc->slice0ForDpb.picOrderCntLsb=pH264HeaderInfos->slice0PicOrderCntLsb; + pH264Desc->slice0ForDpb.deltaPicOrderCnt[0]=pH264HeaderInfos->slice0DeltaPicOrderCnt[0]; + pH264Desc->slice0ForDpb.deltaPicOrderCnt[1]=pH264HeaderInfos->slice0DeltaPicOrderCnt[1]; + pH264Desc->slice0ForDpb.deltaPicOrderCntBottom=pH264HeaderInfos->slice0DeltaPicOrderCntBottom; + pH264Desc->slice0ForDpb.longTermReferenceFlag=pH264HeaderInfos->slice0LongTermReferenceFlag; + pH264Desc->slice0ForDpb.noOutputOfPriorPicsFlag=pH264HeaderInfos->slice0NoOutputOfPriorPicsFlag; + pH264Desc->slice0ForDpb.adaptiveRefPicMarkingModeFlag=pH264HeaderInfos->slice0AdaptiveRefPicMarkingModeFlag; + for(i=0; i<16; i++) + { + pH264Desc->slice0ForDpb.memoryManagementControlOperation[i]=pH264HeaderInfos->slice0MemoryManagementControlOperation[i]; + pH264Desc->slice0ForDpb.differenceOfPicNumsMinus1[i]=pH264HeaderInfos->slice0DifferenceOfPicNumsMinus1[i]; + pH264Desc->slice0ForDpb.markingLongTermPicNum[i]=pH264HeaderInfos->slice0MarkingLongTermPicNum[i]; + pH264Desc->slice0ForDpb.longTermFrameIdx[i]=pH264HeaderInfos->slice0LongTermFrameIdx[i]; + pH264Desc->slice0ForDpb.maxLongTermFrameIdxPlus1[i]=pH264HeaderInfos->slice0MaxLongTermFrameIdxPlus1[i]; + } + dpbError = sva_DC_H264_DPB_SetSlice0Utils(instanceNum, &pH264Desc->slice0ForDpb); + if(dpbError != SVA_DC_H264_DPB_OK) { return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + + + + /* Compute DPbStart and DPBEnd and identify bufferId in which frame will be decoded */ + /* -------------------------------------------------------------------------------- */ + + dpbError = sva_DC_H264_DPB_ComputeDPBStart(instanceNum, &destBufferId, &dpb); + if(dpbError !=SVA_DC_H264_DPB_OK) + { + if((dpbError == SVA_DC_H264_DPB_MISSING_BUFFERS_IN_DPB)||(dpbError == SVA_DC_H264_DPB_PICTURE_LOSS_NOT_SUPPORTED)) + { + + POP_REVERSE_FIFO_ELEM(pH264Desc->sliceMapFifo.push, t_sva_h264_slicemap, pH264Desc->sliceMap); + + POP_REVERSE_FIFO_ELEM(pH264Desc->slicesDescBlockIdFifo.push, t_sva_block_id, blockId); + sva_MM_FreeBlock(blockId); + + + sva_DC_H264_DPB_RemoveLastActiveSPSUtils(instanceNum, &pH264Desc->spsForDpb); + + sva_DC_H264_DPB_RemoveLastSlice0Utils(instanceNum, &pH264Desc->slice0ForDpb); + + if(dpbError == SVA_DC_H264_DPB_MISSING_BUFFERS_IN_DPB) + { + pH264Desc->h264Error = SVA_DC_H264_DPB_START_MISSING_BUFFER_ERROR; + return SVA_VIDEO_DECODER_IMAGE_BUFFER_NEEDED; + } + else + { + pH264Desc->h264Error = SVA_DC_H264_DPB_START_PICTURELOSS_NOT_SUPPORTED; + return SVA_NOT_SUPPORTED_YET; + } + + } + else if (dpbError == SVA_DC_H264_DPB_INTERNAL_FIFOS_FULL) + { + pH264Desc->h264Error = SVA_DC_H264_DPB_START_ERROR; + return SVA_INTERNAL_FIFOS_FULL; + } + else + { + pH264Desc->h264Error = SVA_DC_H264_DPB_START_ERROR; + return SVA_INTERNAL_VIDEO_DECODER_ERROR; + } + } + + + dpbError = sva_DC_H264_DPB_ComputeDPBEnd(instanceNum, dpb); + if(dpbError != SVA_DC_H264_DPB_OK) + { + if(dpbError == SVA_DC_H264_DPB_INTERNAL_FIFOS_FULL) + { + pH264Desc->h264Error = SVA_DC_H264_DPB_END_ERROR; + return SVA_INTERNAL_FIFOS_FULL; + } + else + { + pH264Desc->h264Error = SVA_DC_H264_DPB_END_ERROR; + return SVA_INTERNAL_VIDEO_DECODER_ERROR; + } + + } + + //Push in Fifos outputImageFifos.push + ffError=PUSH_FIFO_ELEM(pDesc->outputImageFifos.push, t_sva_buffer_id, destBufferId); + if (ffError!=SVA_FIFO_OK) {return SVA_INTERNAL_FIFOS_FULL;} + + + + return svaError; + +} + + +/****************************************************************************/ +/* NAME: sva_DC_H264_AssertEndOfBitstream() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* OUT : */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/****************************************************************************/ +PUBLIC t_sva_error sva_DC_H264_AssertEndOfBitstream(t_sva_service_instance_num instanceNum, t_sva_service_id serviceId) +{ + t_sva_error svaError=SVA_OK; + + + return svaError; +} + + + +/****************************************************************************/ +/* NAME: sva_DC_H264_Push() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* OUT :none */ +/* */ +/* RETURN: */ +/* */ +/****************************************************************************/ +PUBLIC t_sva_error sva_DC_H264_Push( + t_sva_service_instance_num instanceNum, + t_sva_buffer_type bufferType, + t_sva_buffer_id bufferId) +{ + t_sva_error svaError=SVA_OK; + t_sva_h264_dpb_error dpbError= SVA_DC_H264_DPB_OK; + t_sva_bm_error bmError= SVA_BM_OK; + t_sva_ff_error ffError = SVA_FIFO_OK; + + t_sva_dc_descriptor *pDesc=&decodeDesc[instanceNum]; + t_sva_h264_desc * pH264Desc = &h264Desc[instanceNum]; + t_size bufferSize=0; + t_size minSize=0; + + t_uint32 mbx=pH264Desc->picWidthInMbsMinus1+1; + t_uint32 mby=pH264Desc->picHeightInMapUnitsMinus1+1; + + switch(bufferType) + { + + case SVA_BITSTREAM_BUFFER_TYPE: + //Store buffer in bitstream buffer fifo + ffError=PUSH_FIFO_ELEM(pDesc->inputBitstreamFifos.push,t_sva_buffer_id,bufferId); + if (ffError!= SVA_FIFO_OK) {return SVA_INTERNAL_FIFOS_FULL;} + //log byte number of compressed data provided by user + bmError=sva_BM_GetBufferSize(bufferId,&bufferSize); + if (bmError!=SVA_BM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + pDesc->status.nbCompressedDataBufferized+=bufferSize; + break; + + case SVA_IMAGE_BUFFER_TYPE: + /*compute minimum size of buffer according to current configuration*/ + minSize=((t_uint32)(mbx *16 * mby *16 *3 ) / 2); + /*read buffer size*/ + bmError=sva_BM_GetBufferSize(bufferId,&bufferSize); + if (bmError!=SVA_BM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + /*check buffer has enought space*/ + if (bufferSize>=minSize) + { + // Push it in DPB Management Block (tobepushedindpbFifo) + dpbError = sva_DC_H264_DPB_Push(instanceNum, bufferId); + if(dpbError != SVA_DC_H264_DPB_OK) { + pH264Desc->h264Error = SVA_DC_H264_DPB_PUSH_ERROR; + return SVA_INTERNAL_FIFOS_FULL; + } + + } + else {svaError=SVA_INTERNAL_VIDEO_DECODER_ERROR;} + break; + case SVA_INFOS_BUFFER_TYPE: + if (pDesc->confHandle.currentConf.areInfosRequested == FALSE) return SVA_UNEXPECTED_API_CALL; + /*compute minimum size of buffer according to current configuration*/ + minSize=sva_DC_H264_GetOutputParamsSize(instanceNum); + /*read buffer size*/ + bmError=sva_BM_GetBufferSize(bufferId,&bufferSize); + if (bmError!=SVA_BM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + /*check buffer has enought space*/ + if (bufferSize>=minSize) + { + ffError=PUSH_FIFO_ELEM(pDesc->outputInfosFifos.push, t_sva_buffer_id, bufferId); + if (ffError!=SVA_FIFO_OK) {return SVA_INTERNAL_FIFOS_FULL;} + else {svaError=SVA_OK;} + } + else {svaError=SVA_INTERNAL_VIDEO_DECODER_ERROR;} + break; + default: + svaError=SVA_INVALID_BUFFER_TYPE; + break; + } + + + return svaError; +} + + + +/****************************************************************************/ +/* NAME: sva_DC_H264_DispatchEOT() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* OUT :none */ +/* */ +/* RETURN: */ +/* */ +/****************************************************************************/ +PUBLIC t_sva_error sva_DC_H264_DispatchEOT( + t_sva_service_instance_num instanceNum, + t_sva_tm_subtask_id subtaskId, + t_sva_event_desc* pEventDesc, + t_sva_service_id serviceId, + t_uint32 eventTimestamp, + t_uint32 eventDate, + t_uint32 *pNbEventsRaised, + t_uint32 maxOfEvent, + t_sva_buffer_list_id bitstreamBufferListId ) +{ + t_sva_error svaError=SVA_OK; + t_sva_ff_error ffError=SVA_FIFO_OK; + t_sva_blm_error blmError = SVA_BLM_OK; + t_sva_h264_dpb_error dpbError = SVA_DC_H264_DPB_OK; + t_sva_mm_error mmError = SVA_MM_OK; + t_sva_tm_error tmError = SVA_TM_OK; + + t_sva_buffer_id bufferId=INVALID_BUFFER_ID; + t_sva_buffer_id outputImageBufferId=INVALID_BUFFER_ID; + t_sva_block_id blockId= INVALID_SDRAM_BLOCK_ID; + t_bool isEmpty=FALSE; + + + t_sva_dc_descriptor *pDesc=&decodeDesc[instanceNum]; + t_sva_video_decoder_configuration *pConf=&pDesc->confHandle.currentConf; + t_sva_h264_desc * pH264Desc = &h264Desc[instanceNum]; + t_sva_vdc_internal_buf internalBuf; + t_sva_block_id infoBlockId; + + + t_uint32 nbEvents = *pNbEventsRaised; + t_sva_event_desc *pEvent; + +#ifdef __DEBUG + t_uint32 dbgIndex = 0; +#endif + + pEvent = &pEventDesc[nbEvents]; + + + /* release inUSe dpbstates */ + dpbError = sva_DC_H264_DPB_ResetDPBStates(instanceNum); + if(dpbError != SVA_DC_H264_DPB_OK) { return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + + //free allocated block to store setheaderinfoparams used for that subtask + ffError = POP_FIFO_ELEM(pH264Desc->slicesDescBlockIdFifo.inUse, t_sva_block_id, blockId); + if(ffError!=SVA_FIFO_OK) { return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + + mmError = sva_MM_FreeBlock(blockId); + if(mmError!=SVA_MM_OK) { return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + + + // resetblocinof + tmError = sva_TM_GetSubTaskField( subtaskId, + SVA_TM_ENC_ADDR_INTERNAL_BUFFER, + (t_logical_address) &internalBuf, + 0, + sizeof(t_sva_vdc_internal_buf), + FALSE); + if (tmError!= SVA_TM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + + svaError = sva_DC_H264_GetInfoBlockIdFromPhysicalAddr(instanceNum, internalBuf.addr_h264d_block_info, &infoBlockId); + if (svaError!= SVA_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + + svaError = sva_DC_H264_ResetBlockInfo(infoBlockId, pH264Desc->blockInfoSize); + if (svaError!= SVA_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + + + /* if infos needed */ + if (pConf->areInfosRequested == TRUE) + { + t_logical_address paramOutAddr; + ffError=POP_FIFO_ELEM(pDesc->outputInfosFifos.inUse,t_sva_buffer_id,bufferId); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + //set paramOutAddr + sva_BM_GetBufferLogicalAddress(bufferId, ¶mOutAddr); + //the buffer is then filled + CHECK_TABLE_OVERFLOW(*pNbEventsRaised, maxOfEvent, SVA_INTERNAL_VIDEO_DECODER_ERROR); + pEvent->eventId = SVA_EVENT_BUFFER_FILLED; + pEvent->bufferId = bufferId; + pEvent->serviceId = serviceId; + pEvent->eventTimestamp = (t_sva_timestamp_value) eventTimestamp; + pEvent->eventDate = (t_sva_timestamp_value) eventDate; + pEvent->extraInfo= 0; + pDesc->status.eventStats.filledCounter++; + /*update buffer status*/ + sva_BM_UpdateBufferStatus(pEvent->bufferId,SVA_BUFFER_FILLED,eventTimestamp); + nbEvents++; + //*pNbEventsRaised=nbEvents; + pEvent = &pEventDesc[nbEvents]; + + + } + + + + //generate inputBitstreamBuffer related events + switch (pConf->mode) { + + case SVA_CODEC_IMAGE_MODE : + + ffError=POP_FIFO_ELEM(pDesc->inputBitstreamFifos.inUse,t_sva_buffer_id,pEvent->bufferId); + bufferId = pEvent->bufferId; + if (ffError!=SVA_FIFO_OK) return SVA_INTERNAL_VIDEO_DECODER_ERROR; + //the buffer is then voided + CHECK_TABLE_OVERFLOW(*pNbEventsRaised, maxOfEvent, SVA_INTERNAL_VIDEO_DECODER_ERROR); + pEvent->eventId = SVA_EVENT_BUFFER_VOIDED; + pEvent->serviceId = serviceId; + pEvent->eventTimestamp = (t_sva_timestamp_value) eventTimestamp; + pEvent->eventDate = (t_sva_timestamp_value) eventDate; + pEvent->extraInfo= 0; + +#ifdef __DEBUG + pH264Desc->eventTraces[pH264Desc->dbgNbEvent][dbgIndex] = *pEvent; + dbgIndex++; +#endif + + pDesc->status.eventStats.voidedCounter++; + /*update buffer status*/ + sva_BM_UpdateBufferStatus(pEvent->bufferId,SVA_BUFFER_VOIDED,eventTimestamp); + nbEvents++; + //*pNbEventsRaised=nbEvents; + pEvent = &pEventDesc[nbEvents]; + + + + //Flush user bitstream buffer + blmError=sva_BLM_RemoveBufferFromList(bitstreamBufferListId,&bufferId); + if (blmError!=SVA_BLM_OK) return SVA_INTERNAL_VIDEO_DECODER_ERROR; + + break; + + case SVA_CODEC_SEGMENTED_MODE : + case SVA_CODEC_STREAM_MODE : + default : + return SVA_NOT_SUPPORTED_YET; + /* break; PCLint warning removal ...(unreachable) */ + + } + + // buffer available as read only: SVA_EVENT_BUFFER_FILLED_READ_ONLY + ffError=POP_FIFO_ELEM(pDesc->outputImageFifos.inUse,t_sva_buffer_id,outputImageBufferId); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + + //the buffer is then filled read only + + + CHECK_TABLE_OVERFLOW(*pNbEventsRaised, maxOfEvent, SVA_INTERNAL_VIDEO_DECODER_ERROR); + pEvent->eventId = SVA_EVENT_BUFFER_FILLED_READ_ONLY; + pEvent->bufferId= outputImageBufferId; + pEvent->serviceId = serviceId; + pEvent->eventTimestamp = (t_sva_timestamp_value) eventTimestamp; + pEvent->eventDate = (t_sva_timestamp_value) eventDate; + pEvent->extraInfo= 0; +// pDesc->status.eventStats.readOnlyCounter++; + +#ifdef __DEBUG + pH264Desc->eventTraces[pH264Desc->dbgNbEvent][dbgIndex] = *pEvent; +#endif + + nbEvents++; + pEvent = &pEventDesc[nbEvents]; +// } + pDesc->status.eventStats.readOnlyCounter++; + + // send all bufferFilled events for that subtask + while(isEmpty == FALSE) + { + // get buffer filled bufferId from DPB + dpbError = sva_DC_H264_DPB_GetBufferFilled(instanceNum, &bufferId, &isEmpty); + if (dpbError!=SVA_DC_H264_DPB_OK) return SVA_INTERNAL_VIDEO_DECODER_ERROR; + + + if(isEmpty == TRUE) break; + //the buffer is then filled filled + CHECK_TABLE_OVERFLOW(*pNbEventsRaised, maxOfEvent, SVA_INTERNAL_VIDEO_DECODER_ERROR); + pEvent->eventId = SVA_EVENT_BUFFER_FILLED; + pEvent->bufferId = bufferId; + pEvent->serviceId = serviceId; + pEvent->eventTimestamp = (t_sva_timestamp_value) eventTimestamp; + pEvent->eventDate = (t_sva_timestamp_value) eventDate; + pEvent->extraInfo= 0; + pDesc->status.eventStats.filledCounter++; + + +#ifdef __DEBUG + pH264Desc->eventTraces[pH264Desc->dbgNbEvent][dbgIndex] = *pEvent; + dbgIndex++; +#endif + + sva_BM_UpdateBufferStatus(pEvent->bufferId,SVA_BUFFER_FILLED,eventTimestamp); + + nbEvents++; + //*pNbEventsRaised=nbEvents; + pEvent = &pEventDesc[nbEvents]; + + pDesc->status.nbImagesDecoded++; + } + + + + + *pNbEventsRaised=nbEvents; + + +#ifdef __DEBUG + pH264Desc->dbgNbEvent ++; + if(pH264Desc->dbgNbEvent == SVA_DC_H264_MAX_DBG_DEPTH) pH264Desc->dbgNbEvent = 0; + +#endif + + + return svaError; + +} + + + + + + +/****************************************************************************/ +/* NAME: t_sva_error sva_DC_H264_ResolveDependencies( */ +/* t_sva_service_instance_num instanceNum */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* */ +/* */ +/* PARAMETERS: */ +/* IN : t_sva_service_instance_num */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: t_sva_error */ +/****************************************************************************/ +PUBLIC t_sva_error sva_DC_H264_ResolveDependencies(t_sva_service_instance_num instanceNum ) +{ + t_sva_error svaError=SVA_OK; + t_sva_bm_error bmError= SVA_BM_OK; + t_sva_ff_error ffError = SVA_FIFO_OK; + t_sva_tm_error tmError = SVA_TM_OK; + t_sva_vdc_frame_buffer_out frameBufferOut; + t_bool dependencyNotSolved=FALSE; + t_sva_buffer_id bufferId; + t_sva_dc_subtask_dependencies subtaskDep; + t_physical_address phyAddr; + t_logical_address logAddr; + t_sva_dc_descriptor *pDesc=&decodeDesc[instanceNum]; + t_sva_h264_desc * pH264Desc = &h264Desc[instanceNum]; + + /*enter loop where we try to solve dep for a maximum of subtasks*/ + while(IS_FIFO_EMPTY(pDesc->subtasksDependencyFifo.push)==FALSE && dependencyNotSolved==FALSE) + { + /*read subtask for which we will try to solve dependencies*/ + ffError=READ_FIFO_ELEM(pDesc->subtasksDependencyFifo.push,t_sva_dc_subtask_dependencies,subtaskDep); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + + + if(subtaskDep.dependencies.outputImageDep==NOT_RESOLVED_DEPENDENCY) //try to resolve image dep. + { + if(IS_FIFO_EMPTY(pDesc->outputImageFifos.push)==FALSE) //1 image buffer available => resolve + { + //Transfer elem from outputimage fifo push to inUse + ffError=POP_FIFO_ELEM(pDesc->outputImageFifos.push,t_sva_buffer_id,bufferId); + if (ffError!= SVA_FIFO_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + ffError=PUSH_FIFO_ELEM(pDesc->outputImageFifos.inUse,t_sva_buffer_id,bufferId); + if (ffError!= SVA_FIFO_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + + //update dependancy infos regarding image buffer + ffError=UPDATE_FIFO_ELEM_FIELD(pDesc->subtasksDependencyFifo.push,t_sva_dc_subtask_dependencies,.dependencies.outputImageDep,RESOLVED_DEPENDENCY); + + //update subtask to take into account new buffer: update addroutframebuf/dest buffer part field + bmError=sva_BM_GetBufferPhysicalAddress(bufferId,&phyAddr); + if (bmError!= SVA_MM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + + //Update subtask Field + frameBufferOut.addr_dest_buffer=phyAddr; + tmError=sva_TM_UpdateSubTaskField( + SVA_TM_INTERMEDIATE_FIELD_TO_UPDATE, + subtaskDep.subtaskId, + SVA_TM_DEC_ADDR_OUT_FRAME_BUFFER, + FCMD_COPY, + (t_uint32)&frameBufferOut, + 0, + 4); + + if (tmError!= SVA_TM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + } + } + + if(subtaskDep.dependencies.inputBitstreamDep==NOT_RESOLVED_DEPENDENCY) + { + svaError=sva_DC_H264_TryToInitParamInFields(instanceNum); // +FrameBufIn (ref_frame in case there is */ + if (svaError!= SVA_OK) { + pH264Desc->h264Error = SVA_DC_H264_PARAMIN_ERROR; + return SVA_INTERNAL_VIDEO_DECODER_ERROR; + } + } + + if(subtaskDep.dependencies.infosDep == NOT_RESOLVED_DEPENDENCY) + { + if(IS_FIFO_EMPTY(pDesc->outputInfosFifos.push)==FALSE) //1 infos buffer available => resolve + { + t_sva_vdc_h264_param_out * pParamOut; + + //Transfer elem from outputimage fifo push to inUse + ffError=POP_FIFO_ELEM(pDesc->outputInfosFifos.push,t_sva_buffer_id,bufferId); + if (ffError!= SVA_FIFO_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + ffError=PUSH_FIFO_ELEM(pDesc->outputInfosFifos.inUse,t_sva_buffer_id,bufferId); + if (ffError!= SVA_FIFO_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + + //update dependancy infos regarding infos buffer + ffError=UPDATE_FIFO_ELEM_FIELD(pDesc->subtasksDependencyFifo.push,t_sva_dc_subtask_dependencies,.dependencies.infosDep,RESOLVED_DEPENDENCY); + //update subtask to take into account new buffer: update addroutframebuf/dest buffer part field + + bmError=sva_BM_GetBufferLogicalAddress(bufferId,&logAddr); + HCL_DEBUG_ASSERT(bmError==SVA_BM_OK); + pParamOut = (t_sva_vdc_h264_param_out*)logAddr; + pParamOut->mb_count = 0; + + + bmError=sva_BM_GetBufferPhysicalAddress(bufferId,&phyAddr); + HCL_DEBUG_ASSERT(bmError==SVA_BM_OK); + //Warning: in this case, should take into account ext bit + phyAddr=phyAddr+EXTERNAL_MEM_EXT_BIT; + + + + + //Update subtask Field by address for paramout buffer + tmError=sva_TM_UpdateSubTaskField( SVA_TM_INTERMEDIATE_FIELD_TO_UPDATE, + subtaskDep.subtaskId, + SVA_TM_DEC_ADDR_OUT_PARAMETERS, + FCMD_NEW_ADDRESS, + phyAddr, + 0, + sizeof(t_sva_vdc_h264_param_out)); + if (tmError!= SVA_TM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + } + } + + //Are all subtask dep resolved? + ffError = READ_FIFO_ELEM(decodeDesc[instanceNum].subtasksDependencyFifo.push,t_sva_dc_subtask_dependencies,subtaskDep);//update infosDep + if(sva_DC_H264_AreAllDependanciesResolved(subtaskDep)==TRUE) + { + t_sva_tm_timestamp immediateTimeStamp={SVA_TM_IMMEDIATE,0}; + + /*pop subtask from list of subtask for which dep has to be solved*/ + ffError=POP_FIFO_ELEM(pDesc->subtasksDependencyFifo.push,t_sva_dc_subtask_dependencies,subtaskDep); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + ffError=PUSH_FIFO_ELEM(pDesc->subtasksDependencyFifo.inUse,t_sva_dc_subtask_dependencies,subtaskDep); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + + /*update state machine*/ + sva_DC_UpdateInstanceStateMachine(instanceNum,SVA_DC_ALL_DEPENDENCIES_RESOLVED); + + /*add subtask to list of schedulable subtasks*/ + tmError=sva_TM_AddElemToSubTaskList(pDesc->subtasksListId,subtaskDep.subtaskId,&immediateTimeStamp,1); + HCL_DEBUG_ASSERT(tmError==SVA_TM_OK); + + } + else + { + dependencyNotSolved=TRUE; + } + + } + + + + + return svaError; +} + +/****************************************************************************/ +/* NAME: sva_DC_H264_HandleFakeEvent() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: This routine handle the fake event triggered after */ +/* a flush in or out command */ +/* PARAMETERS: */ +/* IN : t_sva_service_instance_num */ +/* OUT :none */ +/* */ +/* RETURN: */ +/* t_bool */ +/*--------------------------------------------------------------------------*/ +/* USE: NA */ +/* USED BY: NA */ +/****************************************************************************/ +PUBLIC t_sva_error sva_DC_H264_HandleFakeEvent( t_sva_tm_virtual_hw_event_id eventId, + t_sva_service_id serviceId, + t_sva_tm_subtask_id subtaskId, + t_uint32 eventTimestamp, + t_uint32 eventDate, + t_uint8 maxOfEvent, + t_uint32 *pNbEventsRaised, + t_sva_event_desc *pEventDesc) { + + t_sva_h264_dpb_error dpbError = SVA_DC_H264_DPB_OK; + t_bool isEmpty = FALSE; + t_sva_buffer_id bufferId=INVALID_BUFFER_ID; + t_sva_service_instance_num instanceNum = READ_INSTANCE_NUM_IN_SERVICE_ID(serviceId); + t_sva_dc_descriptor *pDesc=&decodeDesc[instanceNum]; + + t_uint32 nbEvents = *pNbEventsRaised; + t_sva_event_desc *pEvent; + + pEvent = &pEventDesc[nbEvents]; + + if (pDesc->state == SVA_DC_FLUSHING_OUT) + { + + // send all bufferFilled events for that subtask + while(isEmpty == FALSE) + { + // get buffer filled bufferId from DPB + dpbError = sva_DC_H264_DPB_GetBufferFilled(instanceNum, &bufferId, &isEmpty); + if (dpbError!=SVA_DC_H264_DPB_OK) return SVA_INTERNAL_VIDEO_DECODER_ERROR; + + + if(isEmpty == TRUE) break; + //the buffer is then filled filled + CHECK_TABLE_OVERFLOW(*pNbEventsRaised, maxOfEvent, SVA_INTERNAL_VIDEO_DECODER_ERROR); + pEvent->eventId = SVA_EVENT_BUFFER_FILLED; + pEvent->bufferId = bufferId; + pEvent->serviceId = serviceId; + pEvent->eventTimestamp = (t_sva_timestamp_value) eventTimestamp; + pEvent->eventDate = (t_sva_timestamp_value) eventDate; + pEvent->extraInfo= 0; + pDesc->status.eventStats.filledCounter++; + + sva_BM_UpdateBufferStatus(pEvent->bufferId,SVA_BUFFER_FILLED,eventTimestamp); + + nbEvents++; + //*pNbEventsRaised=nbEvents; + pEvent = &pEventDesc[nbEvents]; + + pDesc->status.nbImagesDecoded++; + } + + + + + *pNbEventsRaised=nbEvents; + + } + + return SVA_OK; + +} + +/****************************************************************************/ +/* NAME: sva_DC_H264_FlushFifos() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* OUT : */ +/* */ +/* RETURN: */ +/* */ +/****************************************************************************/ +PUBLIC t_sva_error sva_DC_H264_FlushFifos(t_sva_service_instance_num instanceNum) +{ + + + t_sva_h264_dpb_error dpbError = SVA_DC_H264_DPB_OK; + t_sva_error svaError = SVA_OK; + t_sva_tm_error tmError = SVA_TM_OK; + t_sva_ff_error ffError = SVA_FIFO_OK; + t_sva_bm_error bmError = SVA_BM_OK; + + t_sva_dc_subtask_dependencies subtaskDep; + t_sva_dc_descriptor *pDesc=&decodeDesc[instanceNum]; + t_sva_h264_desc * pH264Desc = &h264Desc[instanceNum]; + + t_uint32 nbElems, i, systemTime; + t_sva_block_id blockId; + t_sva_buffer_id bufferId; + + + blockId = (t_sva_block_id)0; //For removing compiler warning + /* */ + do + { + tmError=sva_TM_RemoveElemFromSubTaskList(pDesc->subtasksListId,&subtaskDep.subtaskId); + if (tmError==SVA_TM_OK) + { + + ffError=POP_FIFO_ELEM(pDesc->subtasksDependencyFifo.inUse,t_sva_dc_subtask_dependencies,subtaskDep); + if (ffError!=SVA_FIFO_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + subtaskDep.dependencies = pDesc->defaultDep; + ffError=PUSH_FIFO_ELEM(pDesc->subtasksDependencyFifo.push,t_sva_dc_subtask_dependencies,subtaskDep); + if (ffError!=SVA_FIFO_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + } + } while (tmError==SVA_TM_OK); + + /*get time*/ + svaError=SVA_GetServiceSystemTime(pDesc->serviceId ,&systemTime); + if (svaError != SVA_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + + + /* do it with h264 fifos */ + /* ---------------------- */ + + FLUSH_FIFO(pH264Desc->sliceMapFifo.push); + FLUSH_FIFO(pH264Desc->sliceMapFifo.inUse); + + + nbElems = GET_FIFO_NB_ELEMS(pH264Desc->slicesDescBlockIdFifo.push); + for(i=0; islicesDescBlockIdFifo.push, t_sva_block_id, blockId); + sva_MM_FreeBlock(blockId); + } + + nbElems = GET_FIFO_NB_ELEMS(pH264Desc->slicesDescBlockIdFifo.inUse); + for(i=0; islicesDescBlockIdFifo.inUse, t_sva_block_id, blockId); + sva_MM_FreeBlock(blockId); + } + + + /* do it with decode fifos */ + /* ----------------------- */ + + //fifo outputImageFifo + + while(POP_FIFO_ELEM(pDesc->outputImageFifos.push,t_sva_buffer_id,bufferId) != SVA_FIFO_EMPTY) + { + bmError=sva_BM_UpdateBufferStatus(bufferId,SVA_BUFFER_NOT_USED,systemTime); + if (bmError!=SVA_BM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + } + while(POP_FIFO_ELEM(pDesc->outputImageFifos.inUse,t_sva_buffer_id,bufferId) != SVA_FIFO_EMPTY) + { + bmError=sva_BM_UpdateBufferStatus(bufferId,SVA_BUFFER_NOT_USED,systemTime); + if (bmError!=SVA_BM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + } + + + //fifos inputBitstreamFifos + + while(POP_FIFO_ELEM(pDesc->inputBitstreamFifos.inUse,t_sva_buffer_id,bufferId) != SVA_FIFO_EMPTY) + { + bmError=sva_BM_UpdateBufferStatus(bufferId,SVA_BUFFER_NOT_USED,systemTime); + if (bmError!=SVA_BM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + } + while(POP_FIFO_ELEM(pDesc->inputBitstreamFifos.push,t_sva_buffer_id,bufferId) != SVA_FIFO_EMPTY) + { + bmError=sva_BM_UpdateBufferStatus(bufferId,SVA_BUFFER_NOT_USED,systemTime); + if (bmError!=SVA_BM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + } + + + + while(POP_FIFO_ELEM(pDesc->outputInfosFifos.inUse,t_sva_buffer_id,bufferId) != SVA_FIFO_EMPTY) + { + bmError=sva_BM_UpdateBufferStatus(bufferId,SVA_BUFFER_NOT_USED,systemTime); + if (bmError!=SVA_BM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + } + while(POP_FIFO_ELEM(pDesc->outputInfosFifos.push,t_sva_buffer_id,bufferId) != SVA_FIFO_EMPTY) + { + bmError=sva_BM_UpdateBufferStatus(bufferId,SVA_BUFFER_NOT_USED,systemTime); + if (bmError!=SVA_BM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + } + + + /* dpb fifo */ + /* -------- */ + dpbError = sva_DC_H264_DPB_FlushFifos(pDesc->serviceId); + if(dpbError == SVA_DC_H264_DPB_INTERNAL_FIFOS_FULL ) return SVA_INTERNAL_FIFOS_FULL; + if(dpbError != SVA_DC_H264_DPB_OK) return SVA_INTERNAL_VIDEO_DECODER_ERROR ; + + + svaError = sva_DC_H264_ResetH264Instance(instanceNum); + + + + return svaError; +} + + +/****************************************************************************/ +/* NAME: sva_DC_H264_FlushBitstreams() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* OUT : */ +/* */ +/* RETURN: */ +/* */ +/****************************************************************************/ +PUBLIC t_sva_error sva_DC_H264_FlushBitstreams(t_sva_service_instance_num instanceNum) +{ + + t_sva_blm_error blmError = SVA_BLM_OK; +// t_sva_buffer_id bufferId = INVALID_BUFFER_ID; //For removing compiler warning + t_uint16 i; + t_sva_dc_descriptor *pDesc=&decodeDesc[instanceNum]; + + for(i=0;iconfHandle.currentConf.mode) { + + case SVA_CODEC_IMAGE_MODE : + //update user buffer status if any + blmError=sva_BLM_RemoveBufferFromList(pDesc->bufferListIdArray[i][0],&removeBufferId); + /* if(blmError==SVA_BLM_OK) + { + //Flush fake bitstream buffer if any + blmError=sva_BLM_RemoveBufferFromList(pDesc->bufferListIdArray[i][0],&bufferId); + HCL_DEBUG_ASSERT(blmError == SVA_BLM_OK); + + + }*/ + break; + } + }while(blmError == SVA_BLM_OK); + if(blmError != SVA_BLM_LIST_EMPTY) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + } + + return SVA_OK; +} + + +/****************************************************************************/ +/* NAME: sva_DC_H264_CheckInputDep() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: This routine enables to check all input dependancies related*/ +/* to a subtask */ +/* PARAMETERS: */ +/* IN : t_sva_service_instance_num */ +/* OUT :none */ +/* */ +/* RETURN: */ +/* t_bool */ +/*--------------------------------------------------------------------------*/ +/* USE: NA */ +/* USED BY: NA */ +/****************************************************************************/ +PUBLIC t_bool sva_DC_H264_CheckInputDep(t_sva_service_instance_num instanceNum) { + + t_sva_dc_descriptor *pDesc=&decodeDesc[instanceNum]; + t_bool inputDepResolved; + t_sva_ff_error ffError; + t_sva_dc_subtask_dependencies infosDep; + + ffError = READ_FIFO_ELEM(pDesc->subtasksDependencyFifo.push,t_sva_dc_subtask_dependencies,infosDep); + HCL_ASSERT(ffError == SVA_FIFO_OK); + + if (infosDep.dependencies.inputBitstreamDep == RESOLVED_DEPENDENCY) + inputDepResolved = TRUE; + else + inputDepResolved = FALSE; + + return inputDepResolved; +} + +/****************************************************************************/ +/* NAME: sva_DC_H264_CheckOutputDep() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: This routine enables to check all output dependancies related*/ +/* to a subtask */ +/* PARAMETERS: */ +/* IN : t_sva_service_instance_num */ +/* OUT :none */ +/* */ +/* RETURN: */ +/* t_bool */ +/*--------------------------------------------------------------------------*/ +/* USE: NA */ +/* USED BY: NA */ +/****************************************************************************/ +PUBLIC t_bool sva_DC_H264_CheckOutputDep(t_sva_service_instance_num instanceNum) { + + t_sva_dc_descriptor *pDesc=&decodeDesc[instanceNum]; + t_bool outputDepResolved; + t_sva_ff_error ffError; + t_sva_dc_subtask_dependencies infosDep; + + ffError = READ_FIFO_ELEM(pDesc->subtasksDependencyFifo.push,t_sva_dc_subtask_dependencies,infosDep); + HCL_ASSERT(ffError == SVA_FIFO_OK); + + if (infosDep.dependencies.outputImageDep == RESOLVED_DEPENDENCY) + outputDepResolved = TRUE; + else + outputDepResolved = FALSE; + + return outputDepResolved; +} + + + +/* private */ +/* ------- */ + +/****************************************************************************/ +/* NAME: t_sva_error sva_DC_H264_FillParamIn( */ +/* t_sva_block_id paramInBlockId, */ +/* t_sva_h264_params_slice storedSliceDesc, */ +/* t_sva_buffer_id * pList0, */ +/* t_sva_buffer_list_id bitstreamBufferListId) */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* */ +/* */ +/* PARAMETERS: */ +/* IN : t_sva_service_instance_num */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: t_sva_error */ +/****************************************************************************/ +PRIVATE t_sva_error sva_DC_H264_FillParamIn( + t_sva_service_instance_num instanceNum, + t_bool last, + t_sva_block_id paramInBlockId, + t_uint32 offset, + t_sva_h264_params_slice storedSliceDesc, + t_sva_h264_active_pps pps, + t_sva_buffer_id list0[], + t_sva_buffer_list_id bitstreamBufferListId) +{ + t_sva_error svaError=SVA_OK; + t_sva_blm_error blmError = SVA_BLM_OK; + t_sva_bm_error bmError = SVA_BM_OK; + t_sva_mm_error mmError = SVA_MM_OK; + t_sva_vdc_h264_slice * pOneSlice; + t_sva_h264_desc * pH264Desc = &h264Desc[instanceNum]; + t_physical_address addrBitstreamBufStruct; + t_system_address paramInSystemAddress; + t_uint16 i; + + + + /* get physical address of the buffer list */ + /* --------------------------------------- */ + /* will be used for ecah slice */ + blmError=sva_BLM_GetBufferListPhysicalAddress (bitstreamBufferListId, &addrBitstreamBufStruct); + if (blmError!=SVA_BLM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + + + /* GetLogicalAdress and Physical address of blockId */ + /* ------------------------------------------------ */ + mmError = sva_MM_GetBlockSystemAddress(paramInBlockId, ¶mInSystemAddress); + if (mmError!=SVA_MM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + + /* Fill piece of that block */ + /* ------------------------ */ + pOneSlice = (t_sva_vdc_h264_slice *)(paramInSystemAddress.logical + offset*sizeof(t_sva_vdc_h264_slice)); + pOneSlice->num_ref_idx_l0_active_minus1 = storedSliceDesc.numRefIdx10ActiveMinus1; + pOneSlice->first_mb_in_slice = storedSliceDesc.firstMbInSlice; + pOneSlice->discarded_slice = 0; //TBChecked + pOneSlice->constr_intra_pred_flag = pps.constrIntraPredFlag; + pOneSlice->chroma_qp_index_offset = pps.chromaQpIndex; + pOneSlice->pic_height_in_map_units = pH264Desc->picHeightInMapUnitsMinus1 + 1; + pOneSlice->pic_width_in_mbs=pH264Desc->picWidthInMbsMinus1 + 1; + pOneSlice->slice_num = storedSliceDesc.sliceNum; + pOneSlice->slice_type = storedSliceDesc.sliceType; + pOneSlice->slice_qp = storedSliceDesc.sliceQp; + pOneSlice->s_info_alpha_c0_offset_div2 = storedSliceDesc.sliceAlphaC0OffsetDiv2; + pOneSlice->s_info_beta_offset_div2 = storedSliceDesc.sliceBetaOffsetDiv2; + pOneSlice->s_info_disable_filter = storedSliceDesc.disableDeblockingFilterIdc; //TBChecked + + if (list0 != NULL) + { + + pOneSlice->num_ref_idx_l0_active_minus1 = storedSliceDesc.numRefIdxActiveOverrideFlag ? storedSliceDesc.numRefIdx10ActiveMinus1 + : pps.numRefIdxl0ActiveMinus1; + + for(i=0;inum_ref_idx_l0_active_minus1+1;i++) + { + if(list0[i] != SVA_DC_H264_DPB_INSERTED_BUFFER) + { + bmError = sva_BM_GetBufferPhysicalAddress(list0[i], &pOneSlice->addr_list0[i]); + if(bmError!= SVA_BM_OK) { + pH264Desc->h264Error = SVA_DC_H264_LIST0_ERROR; + return SVA_INTERNAL_VIDEO_DECODER_ERROR; + } + } + else + { + /* do we have to give a real address or not? */ + pOneSlice->addr_list0[i] = MASK_NULL32; + } + + + + } + for(i=pOneSlice->num_ref_idx_l0_active_minus1+1;i<17;i++) + { + pOneSlice->addr_list0[i] = MASK_NULL32; + } + + + } + else + { + for(i=0;i<17;i++) + pOneSlice->addr_list0[i] = MASK_NULL32; + + } + + if(last != TRUE) + pOneSlice->addr_next_h264_slice = (paramInSystemAddress.physical + (offset+1)*sizeof(t_sva_vdc_h264_slice))|0x1; + else + { + pOneSlice->addr_next_h264_slice = 0; + } + + + + pOneSlice->addr_bitstream_buf_struct= addrBitstreamBufStruct; + pOneSlice->addr_bitstream_start=storedSliceDesc.sliceStartAddress.physical; + pOneSlice->bitstream_offset=storedSliceDesc.sliceOffset; + pOneSlice->bitstream_size_in_bytes=storedSliceDesc.sliceSize; + + + + + +#ifdef __DEBUG + + //pH264Desc->slicesTrace[pH264Desc->dbgSliceCounter][pH264Desc->dbgSliceIndex ]= *pOneSlice; + + pH264Desc->dbgSliceIndex ++; + + if(last == TRUE) + { + pH264Desc->dbgSliceIndex = 0; + pH264Desc->dbgSliceCounter++; + } + if(pH264Desc->dbgSliceCounter == SVA_DC_H264_MAX_DBG_DEPTH) pH264Desc->dbgSliceCounter = 0; +#endif + + + + return svaError; +} + + + +/****************************************************************************/ +/* NAME: t_sva_error sva_DC_H264_SetParamIn( */ +/* t_sva_service_instance_num instanceNum, */ +/* t_sva_buffer_list_id listId */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* */ +/* */ +/* PARAMETERS: */ +/* IN : t_sva_service_instance_num */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: t_sva_error */ +/****************************************************************************/ +PRIVATE t_sva_error sva_DC_H264_SetParamIn(t_sva_service_instance_num instanceNum, t_sva_block_id paramInBlockId, t_sva_buffer_list_id bitstreamBufferListId, t_sva_buffer_id* pList0, t_uint16 *pSlice0Nut, t_uint16 *pSlice0Type) +{ + t_sva_error svaError=SVA_OK; + t_sva_ff_error ffError = SVA_FIFO_OK; + t_sva_h264_dpb_error dpbError=SVA_DC_H264_DPB_OK; + t_sva_block_id blockId = INVALID_SDRAM_BLOCK_ID; + t_uint32 nbSlices, dummy; + t_sva_h264_params_slice storedSliceDesc; + t_sva_h264_active_pps pps; + t_uint16 usedSps; + t_sva_h264_desc * pH264Desc = &h264Desc[instanceNum]; + t_sva_h264_dpb_params_slice * pDpbStoredSliceDesc = (t_sva_h264_dpb_params_slice *)&storedSliceDesc; + t_uint16 i; + + + /* init list0 varaiable */ + sva_DC_H264_DPB_InitList0(pList0); + + /* get blockId in which is stored slices parameters */ + ffError = POP_FIFO_ELEM(pH264Desc->slicesDescBlockIdFifo.push, t_sva_block_id, blockId); + if(ffError!=SVA_FIFO_OK) { return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + /* and push it in the in-use fifo */ + ffError = PUSH_FIFO_ELEM(pH264Desc->slicesDescBlockIdFifo.inUse, t_sva_block_id, blockId); + if(ffError!=SVA_FIFO_OK) { return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + + + /* take first slice in storage-block to get the numberOfSlices in frame*/ + svaError = sva_DC_H264_GetNextSliceInfo(instanceNum, &storedSliceDesc, blockId, 0, &nbSlices); + if(svaError!=SVA_OK) { return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + + *pSlice0Nut = storedSliceDesc.nut; + *pSlice0Type = storedSliceDesc.sliceType; + + /* get sps and pps used field */ + svaError=sva_DC_H264_GetPPS_SPSInfo(instanceNum,&pps,&usedSps,blockId); + if(svaError!=SVA_OK) { return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + /* genetateList0 for that slice */ + dpbError = sva_DC_H264_DPB_ProvideList0(instanceNum,usedSps, pps.numRefIdxl0ActiveMinus1, pDpbStoredSliceDesc, pList0); + if((dpbError!=SVA_DC_H264_DPB_OK)&&(dpbError!=SVA_DC_H264_DPB_NO_LIST0)) { return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + + if(nbSlices==1) + { + /* fill paramIn Block : first slice is also last slice*/ + if(dpbError==SVA_DC_H264_DPB_NO_LIST0) + { + svaError = sva_DC_H264_FillParamIn(instanceNum, TRUE, paramInBlockId,0, storedSliceDesc, pps, 0, bitstreamBufferListId); + if(svaError!=SVA_OK) { return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + } + else + { + svaError = sva_DC_H264_FillParamIn(instanceNum, TRUE, paramInBlockId,0, storedSliceDesc, pps, pList0, bitstreamBufferListId); + if(svaError!=SVA_OK) { return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + } + } + else + { + /* fill paramIn Block of the first slice*/ + if(dpbError==SVA_DC_H264_DPB_NO_LIST0) + { + svaError = sva_DC_H264_FillParamIn(instanceNum, FALSE, paramInBlockId,0, storedSliceDesc, pps, 0, bitstreamBufferListId); + if(svaError!=SVA_OK) { return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + } + else + { + svaError = sva_DC_H264_FillParamIn(instanceNum, FALSE, paramInBlockId,0, storedSliceDesc, pps, pList0, bitstreamBufferListId); + if(svaError!=SVA_OK) { return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + } + + + /* do the same for the NbSlices -2 other slices */ + for(i=0; iconfHandle.currentConf; + t_sva_h264_desc * pH264Desc = &h264Desc[instanceNum]; + t_bool infosAvailable; + t_sva_dc_subtask_dependencies subtaskDep; + t_sva_buffer_id bufferId=INVALID_BUFFER_ID; + t_sva_vdc_h264_param_in paramIn; + t_sva_block_id paramInBlockId, sliceMapBlockId; + t_sva_vdc_internal_buf internalBuffer; + //t_sva_h264_slicemap_info sliceMapInfo; + t_sva_buffer_id list0[17]; + t_uint16 slice0Nut, slice0Type; + t_sva_vdc_frame_buffer_in frameBufferIn; + //t_sva_vdc_h264_param_inout paramInOut; + t_sva_buffer_id refBufferId; + t_uint16 intraConc; + t_system_address sliceMapBlockSysAddr; + t_sva_bm_error bmError = SVA_BM_OK; + + + dpbError =sva_DC_H264_DPB_AreDPBStatesAvailable(instanceNum,&infosAvailable); + if(dpbError != SVA_OK){return SVA_INTERNAL_VIDEO_DECODER_ERROR ;} + + if(infosAvailable==TRUE) + { + + /* use right dpb in inUse fifo */ + dpbError =sva_DC_H264_DPB_GetDPBStates(instanceNum); + if(dpbError != SVA_OK){return SVA_INTERNAL_VIDEO_DECODER_ERROR ;} + //Find suitable subtask + ffError=READ_FIFO_ELEM(pDesc->subtasksDependencyFifo.push,t_sva_dc_subtask_dependencies,subtaskDep); + if(ffError != SVA_FIFO_OK){return SVA_INTERNAL_VIDEO_DECODER_ERROR ;} + + /* init list0*/ + + switch (pConf->mode) { + case SVA_CODEC_IMAGE_MODE : + //Transfer elem from inputBitstreamFifo push to inUse + ffError=POP_FIFO_ELEM(pDesc->inputBitstreamFifos.push,t_sva_buffer_id,bufferId); + if (ffError!= SVA_FIFO_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + ffError=PUSH_FIFO_ELEM(pDesc->inputBitstreamFifos.inUse,t_sva_buffer_id,bufferId); + if (ffError!= SVA_FIFO_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + + // we'll use the same bitstreamBufferList for all slices of the bitstream buffer */ + blmError = sva_BLM_AddBufferInList(subtaskDep.bitstreamBufferListId, bufferId); + if (blmError != SVA_BLM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + + + //update dependancy infos regarding bitstream buffer(and paramin) + ffError=UPDATE_FIFO_ELEM_FIELD(pDesc->subtasksDependencyFifo.push,t_sva_dc_subtask_dependencies,.dependencies.inputBitstreamDep,RESOLVED_DEPENDENCY); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + + + /* get paramInBlockId to SetParamIn */ + /* -------------------------------- */ + tmError = sva_TM_GetSubTaskField( subtaskDep.subtaskId, + SVA_TM_DEC_ADDR_IN_PARAMETERS, + (t_logical_address) ¶mIn, + 0, + sizeof(t_sva_vdc_h264_param_in), + FALSE); + if (tmError!= SVA_TM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + + paramIn.addr_first_slice &= 0xFFFFFFFE; + svaError = sva_DC_H264_GetBlockIdFromPhysicalAddr(instanceNum, paramIn.addr_first_slice, ¶mInBlockId); + if (svaError!= SVA_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + + + /* we use them + others to program paramIn */ + svaError = sva_DC_H264_SetParamIn(instanceNum, paramInBlockId, subtaskDep.bitstreamBufferListId, list0, &slice0Nut, &slice0Type); + if(svaError!=SVA_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + + /* Get adresses from internal_buf to set sliceMap (Could it be an other dependancies that could be resolved before?) */ + /* ----------------------------------------------------------------------------------------------------------------- */ + + tmError = sva_TM_GetSubTaskField( subtaskDep.subtaskId, + SVA_TM_DEC_ADDR_INTERNAL_BUFFER, + (t_logical_address) &internalBuffer, + 0, + sizeof(t_sva_vdc_internal_buf), + FALSE); + if (tmError!= SVA_TM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + + /* Get sliceMapInfoBlockId to set sliceMap */ + ffError=POP_FIFO_ELEM(pH264Desc->sliceMapFifo.push,t_sva_h264_slicemap_info, pH264Desc->sliceMap); + if (ffError!= SVA_FIFO_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + ffError=PUSH_FIFO_ELEM(pH264Desc-> sliceMapFifo.inUse,t_sva_buffer_id,bufferId); + if (ffError!= SVA_FIFO_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + /* Compute SliceMap and fill sliceMapBlockId, dont set internalBuffer.addr_h264d_mb_slice_map to &sliceMapBlockId*/ + /*transform physical address in logical!!!! */ + svaError = sva_DC_H264_GetSliceMapBlockIdFromPhysicalAddr(instanceNum, internalBuffer.addr_h264d_mb_slice_map, &sliceMapBlockId); + if (svaError!= SVA_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + + mmError = sva_MM_GetDedicatedBlockSystemAddress(sliceMapBlockId, &sliceMapBlockSysAddr); + if(mmError != SVA_MM_OK){return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + + sva_DC_H264_SM_MbSliceMap(instanceNum, &pH264Desc->sliceMap, &sliceMapBlockSysAddr.logical); + /* No need to Program subtask since address already given in CreateAndConfigSubtasks*/ + /* only the content of the block has been updated */ + + /* bufferId is not needed anymore */ + ffError=POP_FIFO_ELEM(pH264Desc-> sliceMapFifo.inUse,t_sva_buffer_id,bufferId); + if (ffError!= SVA_FIFO_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + + + /* do it with ref_frame for error concealment */ + /* ------------------------------------------ */ + dpbError = sva_DC_H264_DPB_GetConcealmentInfo(instanceNum, list0, slice0Nut, slice0Type, &refBufferId, &intraConc); + if ((dpbError!= SVA_DC_H264_DPB_OK)&&(dpbError!=SVA_DC_H264_DPB_NO_LIST0)) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + + if(dpbError == SVA_DC_H264_DPB_NO_LIST0) + { + frameBufferIn.addr_fwd_ref_buffer = 0; + } + else + { + bmError = sva_BM_GetBufferPhysicalAddress(refBufferId,&frameBufferIn.addr_fwd_ref_buffer); + if (bmError!= SVA_MM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + } + + /* program ref_frame */ + tmError=sva_TM_UpdateSubTaskField(SVA_TM_INTERMEDIATE_FIELD_TO_UPDATE, subtaskDep.subtaskId,SVA_TM_DEC_ADDR_IN_FRAME_BUFFER, FCMD_COPY, (t_uint32)&frameBufferIn,0, 4); + if (tmError!= SVA_TM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + /* program paramInOut */ + + + /* + paramInOut.intra_conc = intraConc; + paramInOut.mb_count = 0; + tmError=sva_TM_InitSubTaskField(subtaskDep.subtaskId, SVA_TM_DEC_ADDR_IN_FRAME_PARAMETERS, (t_uint32)¶mInOut,sizeof(t_sva_vdc_h264_param_inout)); + if (tmError!= SVA_TM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + */ + + /* modified for 3.4.0 */ + + paramIn.intra_conc = intraConc; + { + t_uint32 offset_val=10; + t_uint32 offsetted_addr_param_in= (t_uint32)¶mIn; + offsetted_addr_param_in += offset_val; + tmError=sva_TM_UpdateSubTaskField(SVA_TM_INTERMEDIATE_FIELD_TO_UPDATE, subtaskDep.subtaskId,SVA_TM_DEC_ADDR_IN_PARAMETERS, FCMD_COPY, (t_uint32)(offsetted_addr_param_in),offset_val, 2); + if (tmError!= SVA_TM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + } + + + + break; + case SVA_CODEC_SEGMENTED_MODE: + case SVA_CODEC_STREAM_MODE: + /* TBD */ + break; + default: + break; + + } + + } + + return svaError; + +} + +/****************************************************************************/ +/* NAME: t_sva_error sva_DC_H264_SetParamsHeaderInfo( */ +/* t_sva_video_decoder_algo_h264_header_infos */ +/* t_logical_address */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/****************************************************************************/ +PRIVATE t_sva_error sva_DC_H264_SetParamsHeaderInfo( + t_sva_service_instance_num instanceNum, + const t_sva_video_decoder_algo_h264_header_infos * pSource, + t_logical_address destAddr, + t_size maxSize) +{ + t_sva_error svaError=SVA_OK; + t_sva_h264_desc * pH264Desc = &h264Desc[instanceNum]; + t_uint32 nbLoop = pSource->nbSlicesInFrame; + t_uint32 i,j; + + t_uint16* pEndDest = (t_uint16*)(destAddr+maxSize); + t_uint16* pDest = (t_uint16*)destAddr; + t_uint32* pDest32; + t_sva_video_decoder_algo_h264_slice_header_infos * pHeader; + + *pDest++ = (t_uint16)pSource->nbSlicesInFrame; + *pDest++ = (t_uint16)pH264Desc->staticParams.log2MaxFrameNumMinus4; + + + *pDest++ = (t_uint16)pSource->chromaQpIndex; + *pDest++ = (t_uint16)pSource->constrIntraPredFlag; + *pDest++ = (t_uint16)pSource->numRefIdxl0ActiveMinus1; + + /* dummy 16 */ + *pDest++ = (t_uint16)0xFFFF; + + pHeader = pSource->pHeader; + for(j=0; jnut; + *pDest++=(t_uint16)pHeader->nri; + + pDest32 = (t_uint32*)pDest; + + pDest++; + pDest++; + *pDest32++ = (t_uint32)pHeader->sliceStartAddress.logical; + + pDest++; + pDest++; + *pDest32++ = (t_uint32)pHeader->sliceStartAddress.physical; + + pDest++; + pDest++; + *pDest32++ = (t_uint32)pHeader->sliceOffset; + + pDest++; + pDest++; + *pDest32++ = (t_uint32)pHeader->sliceSize; + + + + *pDest++=(t_uint16)pHeader->sliceBetaOffsetDiv2; + *pDest++=(t_uint16)pHeader->firstMbInSlice; + *pDest++=(t_uint16)pHeader->sliceType; + *pDest++=(t_uint16)pHeader->numRefIdx10ActiveMinus1; + *pDest++=(t_uint16)pHeader->sliceQpDelta; + *pDest++=(t_uint16)pHeader->disableDeblockingFilterIdc; + *pDest++=(t_uint16)pHeader->sliceAlphaC0OffsetDiv2; + *pDest++=(t_uint16)pHeader->sliceNum; + *pDest++=(t_uint16)pHeader->sliceQp; + *pDest++=(t_uint16)pHeader->numRefIdxActiveOverrideFlag; + *pDest++=(t_uint16)pHeader->refPicListReorderingFlagl0; + *pDest++=(t_bool)pHeader->frameNum; + + + + for(i=0; i<16; i++) + { + *pDest++=(t_uint16)pHeader->reorderingOfPicNumsIdc[i]; + *pDest++=(t_uint16)pHeader->absDiffPicNumMinus1[i]; + *pDest++=(t_uint16)pHeader->longTermPicNum[i]; + } + + pHeader = pHeader->pNextHeader; + } + + if(pEndDest != pDest) + svaError = SVA_OUT_OF_MEMORY; + + return svaError; +} + + +/****************************************************************************/ +/* NAME: t_sva_error sva_DC_H264_GetPPSInfo( */ +/* t_sva_service_instance_num instanceNum, */ +/* t_sva_h264_active_pps * */ +/* t_sva_block_id */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/****************************************************************************/ +PRIVATE t_sva_error sva_DC_H264_GetPPS_SPSInfo( + t_sva_service_instance_num instanceNum, + t_sva_h264_active_pps * pPps, + t_uint16 *pSPSlog2MaxFrameNumMinus4, + t_sva_block_id blockId) +{ + t_sva_mm_error mmError = SVA_MM_OK; + t_sva_error svaError = SVA_OK; + t_logical_address startAddr; + t_uint16* pStart; + + /* address of the block in which are stored setHeaderInfo params */ + mmError=sva_MM_GetBlockLogicalAddress(blockId,&startAddr); + if (mmError!= SVA_MM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + + startAddr = startAddr + 1*sizeof(t_uint16); + pStart = (t_uint16*)startAddr; + + *pSPSlog2MaxFrameNumMinus4 = *pStart++; + pPps->chromaQpIndex = (t_uint16)(*pStart++); + //pStart++; + pPps->constrIntraPredFlag = (t_uint16)(*pStart++); + pPps->numRefIdxl0ActiveMinus1 = (t_uint16)(*pStart++); + + return svaError; +} + +/****************************************************************************/ +/* NAME: t_sva_error sva_DC_H264_GetNextSlice( */ +/* t_sva_service_instance_num instanceNum, */ +/* t_sva_h264_slice_params* */ +/* t_sva_block_id */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/****************************************************************************/ +PRIVATE t_sva_error sva_DC_H264_GetNextSliceInfo( + t_sva_service_instance_num instanceNum, + t_sva_h264_params_slice * pSlice, + t_sva_block_id blockId, + t_uint32 sliceNumber, + t_uint32 *pNbSlicesInFrame) +{ + t_sva_mm_error mmError = SVA_MM_OK; + t_sva_error svaError = SVA_OK; + t_uint32 i; + t_logical_address startAddr; + t_uint16* pStart=NULL; + t_uint32* pStart32; + + + + + /* address of the block in which are stored setHeaderInfo params */ + mmError=sva_MM_GetBlockLogicalAddress(blockId,&startAddr); + if (mmError!= SVA_MM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + + pStart = (t_uint16*)startAddr; + if(sliceNumber == 0) + *pNbSlicesInFrame = *pStart; /*nbSliceINFrames*/ + else + *pNbSlicesInFrame = 0; + + /**/ /**/ /* dummy*/ + startAddr = startAddr + 2*sizeof(t_uint16) + sizeof(t_sva_h264_active_pps) + sizeof(t_uint16)+ sizeof(t_sva_h264_params_slice) * sliceNumber; + pStart = (t_uint16*)startAddr; + + + pSlice->nut = *pStart++; + pSlice->nri = *pStart++; + + pStart32 = (t_uint32*)pStart; + pStart++; + pStart++; + pSlice->sliceStartAddress.logical = (t_uint32)*pStart32++; + + + pStart++; + pStart++; + pSlice->sliceStartAddress.physical = (t_uint32)*pStart32++; + + pStart++; + pStart++; + pSlice->sliceOffset = *pStart32++; + + pStart++; + pStart++; + pSlice->sliceSize = *pStart32++; + + pSlice->sliceBetaOffsetDiv2 = *pStart++; + pSlice->firstMbInSlice = *pStart++; + pSlice->sliceType= *pStart++; + pSlice->numRefIdx10ActiveMinus1= *pStart++; + pSlice->sliceQpDelta= *pStart++; + pSlice->disableDeblockingFilterIdc = *pStart++; + pSlice->sliceAlphaC0OffsetDiv2= *pStart++; + pSlice->sliceNum= *pStart++; + pSlice->sliceQp= *pStart++; + pSlice->numRefIdxActiveOverrideFlag= *pStart++; + pSlice->refPicListReorderingFlagl0= *pStart++; + + pSlice->frameNum = *pStart++; + for(i=0; i<16; i++) + { + pSlice->reorderingOfPicNumsIdc[i] = *pStart++; + pSlice->absDiffPicNumMinus1[i]= *pStart++; + pSlice->longTermPicNum[i]= *pStart++; + } + + + + return svaError; +} + + + +/****************************************************************************/ +/* NAME: t_sva_error sva_DC_H264_GetFWFeatures( */ +/* t_sva_service_instance_num instanceNum */ +/* t_sva_fw_features* */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/****************************************************************************/ +PRIVATE t_sva_error sva_DC_H264_GetFWFeatures (t_sva_service_instance_num instanceNum, t_sva_fw_features* pFwFeat) +{ + t_sva_error svaError = SVA_OK; + *pFwFeat = SVA_FW_FEAT_H264_DECODER; + + return svaError; + + +} + +/****************************************************************************/ +/* NAME: t_sva_error sva_DC_H264_GetSubTaskType( */ +/* t_sva_service_instance_num instanceNum */ +/* t_sva_tm_subtask_type* */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/****************************************************************************/ +PRIVATE t_sva_error sva_DC_H264_GetSubTaskType(t_sva_service_instance_num instanceNum, t_sva_tm_subtask_type* pSubTask) +{ + t_sva_error svaError = SVA_OK; + + *pSubTask=SVA_TM_DECODE_H264; + + return svaError; + +} + + +/****************************************************************************/ +/* NAME: t_sva_error sva_DC_H264_GetPPPType( */ +/* t_sva_service_instance_num instanceNum */ +/* t_sva_tm_postprocessing_type* */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/****************************************************************************/ +PRIVATE t_sva_error sva_DC_H264_GetPPPType(t_sva_service_instance_num instanceNum, t_sva_tm_postprocessing_type* pPostProc) +{ + t_sva_error svaError = SVA_OK; + + *pPostProc= SVA_TM_NO_POST_PROCESSING; + + return svaError; + +} + + + +/****************************************************************************/ +/* NAME: t_sva_error sva_DC_H264_GetSliceMapBlockSize( */ +/* t_sva_service_instance_num instanceNum */ +/* t_size* */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PRIVATE t_sva_error sva_DC_H264_GetSliceMapBlockSize(t_sva_service_instance_num instanceNum, t_size* pSize ) +{ + t_sva_error svaError=SVA_OK; + t_sva_h264_desc * pH264Desc = &h264Desc[instanceNum]; + + *pSize = (pH264Desc->picWidthInMbsMinus1+1) * (pH264Desc->picHeightInMapUnitsMinus1+1) * sizeof(t_uint16); + + return svaError; +} + +/****************************************************************************/ +/* NAME: t_sva_error sva_DC_H264_GetInfoBlockSize( */ +/* t_sva_service_instance_num instanceNum */ +/* t_size* */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PRIVATE t_sva_error sva_DC_H264_GetInfoBlockSize(t_sva_service_instance_num instanceNum, t_size* pSize ) +{ + t_sva_error svaError=SVA_OK; + t_sva_h264_desc * pH264Desc = &h264Desc[instanceNum]; + + *pSize = (pH264Desc->picWidthInMbsMinus1+1) * (pH264Desc->picHeightInMapUnitsMinus1+1) * sizeof(t_sva_h264_mblock_info); + + return svaError; +} + + +/****************************************************************************/ +/* NAME: t_sva_error sva_DC_H264_GetInfoBlockSize( */ +/* t_sva_service_instance_num instanceNum */ +/* t_size* */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PRIVATE t_sva_error sva_DC_H264_GetH4DSize(t_sva_service_instance_num instanceNum, t_size* pSize ) +{ + t_sva_error svaError=SVA_OK; + t_sva_h264_desc * pH264Desc = &h264Desc[instanceNum]; + + /* formule magique Cyril */ + *pSize = ((pH264Desc->picWidthInMbsMinus1+1)<<4) * 8 + 320; + + return svaError; +} + +/****************************************************************************/ +/* NAME: t_sva_error sva_DC_H264_GetDeblockingSize( */ +/* t_sva_service_instance_num instanceNum */ +/* t_size* */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PRIVATE t_sva_error sva_DC_H264_GetDeblockingSize(t_sva_service_instance_num instanceNum, t_size* pSize ) +{ + t_sva_error svaError=SVA_OK; + t_sva_h264_desc * pH264Desc = &h264Desc[instanceNum]; + + *pSize = (pH264Desc->picWidthInMbsMinus1+1) * (pH264Desc->picHeightInMapUnitsMinus1+1)* sizeof(t_sva_h264_h4d_param); + + return svaError; +} + + +/****************************************************************************/ +/* NAME: t_sva_error sva_DC_H264_GetSlicesBlockSize( */ +/* t_sva_service_instance_num instanceNum */ +/* t_size* */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/****************************************************************************/ +PRIVATE t_sva_error sva_DC_H264_GetSlicesBlockSize(t_sva_service_instance_num instanceNum, t_size* pSize ) +{ + t_sva_error svaError=SVA_OK; + t_sva_h264_desc * pH264Desc = &h264Desc[instanceNum]; + + *pSize = (pH264Desc->picWidthInMbsMinus1+1) * (pH264Desc->picHeightInMapUnitsMinus1+1) * sizeof(t_sva_vdc_h264_slice); + + return svaError; +} + + +/****************************************************************************/ +/* NAME: t_sva_error sva_DC_H264_GetSlicesBlockSize( */ +/* t_sva_service_instance_num instanceNum */ +/* t_size* */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/****************************************************************************/ +PRIVATE t_sva_error sva_DC_H264_GetNBMaxSlicePerFrame(t_sva_service_instance_num instanceNum, t_uint32* pNbMax ) +{ + t_sva_error svaError=SVA_OK; + t_sva_h264_desc * pH264Desc = &h264Desc[instanceNum]; + + *pNbMax = (pH264Desc->picWidthInMbsMinus1+1) * (pH264Desc->picHeightInMapUnitsMinus1+1); + + return svaError; +} + +/****************************************************************************/ +/* NAME: t_sva_error sva_DC_H264_ComputeDPBSize( */ +/* t_sva_service_instance_num instanceNum */ +/* t_size* */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/****************************************************************************/ +PRIVATE t_sva_error sva_DC_H264_ComputeDPBSize(t_sva_service_instance_num instanceNum, t_size* pSize) +{ + + t_sva_error svaError=SVA_OK; + t_sva_h264_desc * pH264Desc = &h264Desc[instanceNum]; + + t_uint32 pic_size = (pH264Desc->picWidthInMbsMinus1 + 1) * (pH264Desc->picHeightInMapUnitsMinus1 + 1) * 384; + + + switch (pH264Desc->staticParams.levelIdc) + { + case 10: + *pSize = 152064; + break; + + case 11: + *pSize = 345600; + break; + + case 12: + *pSize = 912384; + break; + + case 13: + *pSize = 912384; + break; + + case 20: + *pSize = 912384; + break; + + case 21: + *pSize = 1824768; + break; + + case 22: + *pSize = 3110400; + break; + + case 30: + *pSize = 3110400; + break; + // According to Hamac specs. level upto 3.0 is supported + /* + case 31: + *pSize = 6912000; + break; + + case 32: + *pSize = 7864320; + break; + + case 40: + *pSize = 12582912; + break; + + case 41: + *pSize = 12582912; + break; + + case 42: + *pSize = 12582912; + break; + + case 50: + *pSize = 42393600; + break; + + case 51: + *pSize = 70778880; + break; + */ + default: + svaError = SVA_INCOHERENT_CONFIGURATION; + break; + } + + *pSize /= pic_size; + + *pSize = H264MIN(*pSize, 16); + + return svaError; +} + + + + +//Currently not used, +//For removing compiler warning +#if 0 + +/****************************************************************************/ +/* NAME: t_sva_error sva_DC_H264_ResetH264Desc( */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/****************************************************************************/ +PRIVATE t_sva_error sva_DC_H264_ResetH264Desc(void) +{ + t_uint32 instanceNum=0; + t_sva_error svaError = SVA_OK; + + /* init global variable */ + for(instanceNum=0; instanceNumblockSlicesAddr[i].physical == phyAddr) + { + *pBlockId = pH264Desc->blockSlicesId[i]; + break; + } + + } + if((i==SUBTASK_DEFAULT_NUMBER)&&(*pBlockId == INVALID_SDRAM_BLOCK_ID)) + svaError = SVA_INTERNAL_VIDEO_DECODER_ERROR; + + return svaError; + +} + + +/****************************************************************************/ +/* NAME: t_sva_error sva_DC_H264_GetBlockIdFromPhysicalAddr( */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/****************************************************************************/ +PRIVATE t_sva_error sva_DC_H264_GetSliceMapBlockIdFromPhysicalAddr(t_sva_service_instance_num instanceNum, t_physical_address phyAddr, t_sva_block_id * pBlockId) +{ + t_sva_error svaError = SVA_OK; + t_sva_h264_desc * pH264Desc = &h264Desc[instanceNum]; + t_uint16 i; + + *pBlockId = INVALID_SDRAM_BLOCK_ID; + for(i=0; iblockSliceMapAddr[i].physical == phyAddr) + { + *pBlockId = pH264Desc->blockSliceMapId[i]; + break; + } + + } + if((i==SUBTASK_DEFAULT_NUMBER)&&(*pBlockId == INVALID_SDRAM_BLOCK_ID)) + svaError = SVA_INTERNAL_VIDEO_DECODER_ERROR; + + return svaError; + +} + +/****************************************************************************/ +/* NAME: t_sva_error sva_DC_H264_GetInfoBlockIdFromPhysicalAddr( */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/****************************************************************************/ +PRIVATE t_sva_error sva_DC_H264_GetInfoBlockIdFromPhysicalAddr(t_sva_service_instance_num instanceNum, t_physical_address phyAddr, t_sva_block_id * pBlockId) +{ + t_sva_error svaError = SVA_OK; + t_sva_h264_desc * pH264Desc = &h264Desc[instanceNum]; + t_uint16 i; + + *pBlockId = INVALID_SDRAM_BLOCK_ID; + for(i=0; iblockInfoAddr[i].physical == phyAddr) + { + *pBlockId = pH264Desc->blockInfoId[i]; + break; + } + + } + if((i==SUBTASK_DEFAULT_NUMBER)&&(*pBlockId == INVALID_SDRAM_BLOCK_ID)) + svaError = SVA_INTERNAL_VIDEO_DECODER_ERROR; + + return svaError; + +} + + +/****************************************************************************/ +/* NAME: t_sva_error sva_DC_H264_ResetBlockInfo( */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/****************************************************************************/ +PRIVATE t_sva_error sva_DC_H264_ResetBlockInfo(t_sva_block_id mblockInfoId, t_size mblockSize) +{ + t_uint32 i, j; + t_sva_error svaError = SVA_OK; + t_sva_mm_error mmError = SVA_MM_OK; + t_system_address mblockInfoAddr; + t_sva_h264_mblock_info * mblockInfoStructPtr; + t_uint32 nbMBlocks = mblockSize/sizeof(t_sva_h264_mblock_info); + + + mmError = sva_MM_GetDedicatedBlockSystemAddress(mblockInfoId, &mblockInfoAddr); + if(mmError!=SVA_MM_OK) { return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + + mblockInfoStructPtr = (t_sva_h264_mblock_info *)mblockInfoAddr.logical; + #ifdef SVA_H264_USER_MEMSET_NEEDED + for (i=0; i nslice = -1; + } + #else + + for (i=0; i nslice = -1; + (mblockInfoStructPtr + i)->concealed = 0; + (mblockInfoStructPtr + i)->QP[0]=0; + (mblockInfoStructPtr + i)->QP[1]=0; + + for(j=0; j<16; j++) + { + (mblockInfoStructPtr + i)->block4x4Info[j].non_zero = 0; + (mblockInfoStructPtr + i)->block4x4Info[j].BKType=0; + (mblockInfoStructPtr + i)->block4x4Info[j].mv[0]=0; + (mblockInfoStructPtr + i)->block4x4Info[j].mv[1]=0; + } + + } + #endif + return svaError; +} + + + +/****************************************************************************/ +/* NAME: sva_DC_H264_AreAllDependanciesResolved() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: This routine enables to check all dependancies related */ +/* to a subtask */ +/* PARAMETERS: */ +/* IN : t_sva_dc_subtask_dependencies subtaskDep : Subtask to check */ +/* OUT :none */ +/* */ +/* RETURN: */ +/* t_bool */ +/****************************************************************************/ +PRIVATE t_bool sva_DC_H264_AreAllDependanciesResolved(t_sva_dc_subtask_dependencies subtaskDep) +{ + + if((subtaskDep.dependencies.outputImageDep !=NOT_RESOLVED_DEPENDENCY)&& + (subtaskDep.dependencies.inputBitstreamDep !=NOT_RESOLVED_DEPENDENCY)&& + (subtaskDep.dependencies.infosDep !=NOT_RESOLVED_DEPENDENCY)) + {return TRUE;} + else {return FALSE;} +} + + + + +/* Not used */ +/* --------- */ + +PUBLIC t_sva_error sva_DC_H264_GetLastErrorType (t_sva_service_instance_num instanceNum, t_uint16 * param) +{ + return SVA_OK; +} + +PUBLIC t_sva_error sva_DC_H264_DeleteFake(t_sva_service_instance_num instanceNum) +{ + return SVA_OK; +} + + +PUBLIC t_sva_error sva_DC_H264_GetParamsBufferSize( + t_sva_service_instance_num instanceNum, t_sva_push_mode pushMode, t_sva_filter_mode filtermode, t_uint32 dummy0, t_uint32 dummy1, t_size * pSize) +{ + return SVA_OK; +} + + + + + + + + +/****************************************************************************/ +/* NAME: sva_DC_H264_ResetBlock() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* */ +/* PARAMETERS: */ +/* IN : t_sva_service_instance_num */ +/* OUT :none */ +/* */ +/* RETURN: */ +/* t_bool */ +/*--------------------------------------------------------------------------*/ +/* USE: NA */ +/* USED BY: NA */ +/****************************************************************************/ + +PRIVATE t_sva_error sva_DC_H264_ResetBlock(t_system_address systemAddress, t_size size) +{ + //t_uint16 i; + //t_uint32 logaddress = systemAddress.logical; + //t_uint8 * ptr = (t_uint8*)logaddress; + /* + for (i=0; i. */ +/*---------------------------------------------------------------------------*/ + +#ifndef __INC_SVA_DC_H264_H +#define __INC_SVA_DC_H264_H + +#include "hcl_defs.h" +#include "sva_service.h" +#include "sva_dc_h264_dpb.h" +#include "sva_dc_h264_slicemap.h" + + + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#ifdef __DEBUG +#define SVA_DC_H264_MAX_DBG_DEPTH 30 +#define SVA_DC_H264_MAX_DBG_SLICESPERFRAME 9 +#define SVA_DC_H264_MAX_DBG_EVENTS 12 +#endif + +/* macros */ +#define H264MIN(a,b) (((a)<(b))?a:b) +#define H264MAX(a,b) (((a)>(b))?a:b) +#define H264_MAX_UINT_16 65535 +#define H264_MAX_SINT_32 2147483647 +#define H264_MIN_SINT_32 -H264_MAX_SINT_32-1 +#define H264_MAX_UINT_32 4294967295 + +/* extracted from each slice headers of the frame and required to program vdc_h264_slice */ +typedef t_sva_h264_dpb_params_slice t_sva_h264_params_slice; + + +/* used as parameter for SetHeaderInfo */ +typedef struct +{ /* from active PPS */ + t_uint16 chromaQpIndex; + t_uint16 constrIntraPredFlag; + t_uint16 numRefIdxl0ActiveMinus1; +}t_sva_h264_active_pps; + + +/* extracted from active PPS and first slice Header, used to compute sliceMap */ +typedef t_sva_h264_slicemap t_sva_h264_slicemap_info; + + + +/* public fonctions */ +PUBLIC t_sva_error sva_DC_H264_Init( t_sva_service_instance_num , t_sva_codec_mode , t_sva_image_desc , const t_sva_dc_algo_configuration_params *); +PUBLIC t_sva_error sva_DC_H264_GetMemoryNeeds( t_sva_service_instance_num , t_size *); +PUBLIC t_sva_error sva_DC_H264_ProvideMemoryNeeds(t_sva_service_instance_num ); +PUBLIC t_sva_error sva_DC_H264_CreateAndConfigSubtasksList(t_sva_service_instance_num, t_sva_service_id); +PUBLIC t_sva_error sva_DC_H264_Close(t_sva_service_instance_num ); +PUBLIC t_sva_error sva_DC_H264_InitHeaderInfos(t_sva_service_instance_num ); +PUBLIC t_sva_error sva_DC_H264_SetHeaderInfos(t_sva_service_instance_num , t_sva_service_id ,t_sva_buffer_id, t_uint32, t_uint32, const t_sva_header_infos *) ; +PUBLIC t_sva_error sva_DC_H264_AssertEndOfBitstream(t_sva_service_instance_num , t_sva_service_id ) ; +PUBLIC t_sva_error sva_DC_H264_Push(t_sva_service_instance_num , t_sva_buffer_type , t_sva_buffer_id ) ; +PUBLIC t_sva_error sva_DC_H264_DispatchEOT(t_sva_service_instance_num ,t_sva_tm_subtask_id , t_sva_event_desc* ,t_sva_service_id ,t_uint32 , t_uint32 ,t_uint32 *,t_uint32 ,t_sva_buffer_list_id); +PUBLIC t_sva_error sva_DC_H264_HandleFakeEvent( t_sva_tm_virtual_hw_event_id , + t_sva_service_id , + t_sva_tm_subtask_id , + t_uint32 , + t_uint32 , + t_uint8 , + t_uint32 *, + t_sva_event_desc *); +PUBLIC t_sva_error sva_DC_H264_ResolveDependencies(t_sva_service_instance_num ); +PUBLIC t_bool sva_DC_H264_CheckInputDep(t_sva_service_instance_num); +PUBLIC t_bool sva_DC_H264_CheckOutputDep(t_sva_service_instance_num); + + +/* not usefull but needed to be existing */ + +PUBLIC t_sva_error sva_DC_H264_FlushBitstreams(t_sva_service_instance_num); +PUBLIC t_sva_error sva_DC_H264_GetLastErrorType (t_sva_service_instance_num, t_uint16 *); +PUBLIC t_sva_error sva_DC_H264_FlushFifos(t_sva_service_instance_num); +PUBLIC t_sva_error sva_DC_H264_DeleteFake(t_sva_service_instance_num); +PUBLIC t_sva_error sva_DC_H264_SetOutputParams(t_sva_service_instance_num, const t_sva_dc_algo_params_out *); +PUBLIC t_size sva_DC_H264_GetOutputParamsSize(t_sva_service_instance_num); +PUBLIC t_sva_error sva_DC_H264_GetParamsBufferSize(t_sva_service_instance_num, t_sva_push_mode, t_sva_filter_mode, t_uint32, t_uint32, t_size *); +PUBLIC t_sva_h264_dpb_error sva_DC_H264_DPB_InitInstance(t_sva_service_instance_num instanceNum); + + + + +#ifdef __cplusplus +} /* allow C++ to use these headers */ +#endif /* __cplusplus */ + + + +#endif --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/h264/sva_dc_h264_dpb.c @@ -0,0 +1,3101 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ +/*------------------------------------------------------------------------ + * Includes + *----------------------------------------------------------------------*/ +#include "hcl_defs.h" +//#include "sva_decodep.h" //for NUM_MAX_DECODE +#include "sva_fifo.h" +#include "sva_dc_h264_dpb.h" +#include "sva_dc_h264_dpbp.h" +#include "sva_dc_h264.h" + +PRIVATE t_sva_h264_dpb_block_desc DPBDesc[NUM_MAX_DECODE]; +extern PUBLIC t_sva_dc_descriptor decodeDesc[NUM_MAX_DECODE]; + +/*private functions: not used by any other than sva_dc_H264_dpb.c */ +PRIVATE t_sva_h264_dpb_error sva_DC_H264_DPB_DecodePOC( t_sva_h264_dpb_sps_utils*, t_sva_h264_dpb_slice0_utils* ,t_sva_h264_dpb_poc*, t_sint32 * ); +PRIVATE t_sva_h264_dpb_error sva_DC_H264_DPB_FlushDPB(t_sva_service_instance_num, t_sva_h264_dpb_desc *, t_uint16); +PRIVATE t_sva_h264_dpb_error sva_DC_H264_DPB_BumpFrame(t_sva_service_instance_num, t_sva_h264_dpb_desc *, t_uint32 *); +PRIVATE t_sva_h264_dpb_error sva_DC_H264_DPB_ConcealNewFrame(t_uint8,t_uint16 , t_uint32 , t_sva_h264_dpb_sps_utils * , t_sva_h264_dpb_desc* ); +PRIVATE t_sva_h264_dpb_error sva_DC_H264_DPB_ConcealGetAllImageBuffer(t_uint8,t_uint32); +PRIVATE t_sva_h264_dpb_error sva_DC_H264_DPB_GetIndexForNewFrame(t_sva_service_instance_num,t_uint16, t_uint32, t_sva_h264_dpb_sps_utils *, t_sva_h264_dpb_desc*, t_uint32* ); +PRIVATE t_sva_h264_dpb_error sva_DC_H264_DPB_MarkDecodedFrame(t_sva_service_instance_num,t_sva_h264_dpb_sps_utils * , t_sva_h264_dpb_slice0_utils * ,t_sva_h264_dpb_poc *, t_sva_h264_dpb_desc *); +PRIVATE t_sva_h264_dpb_error sva_DC_H264_DPB_PerformMMCOOperation(t_sva_service_instance_num, t_sva_h264_dpb_sps_utils * , t_sva_h264_dpb_slice0_utils * ,t_sva_h264_dpb_poc *, t_sva_h264_dpb_desc *); +PRIVATE t_sva_h264_dpb_error sva_DC_H264_DPB_RemoveUnusedFrame(t_sva_service_instance_num, t_sva_h264_dpb_desc *); +PRIVATE t_sva_h264_dpb_error sva_DC_H264_DPB_FindLong(t_uint16, t_uint16, t_sva_h264_dpb_decoded_buffer_info *, t_uint32 *); +PRIVATE t_sva_h264_dpb_error sva_DC_H264_DPB_FindShort(t_uint16, t_sint32, t_sva_h264_dpb_decoded_buffer_info *, t_uint32 *); +PRIVATE t_sva_h264_dpb_error sva_DC_H264_DPB_InitDPB(t_sva_service_instance_num,t_sva_h264_dpb_desc *); +PRIVATE t_bool sva_DC_H264_isPSlice(const t_sva_h264_dpb_params_slice * ); +PRIVATE t_sva_h264_dpb_error sva_DC_H264_DPB_ResetDPBDesc(void); +PRIVATE t_sva_h264_dpb_error sva_DC_H264_DPB_CheckBufferId(t_sva_service_instance_num, t_sva_h264_dpb_desc *, t_uint32); +PRIVATE t_sva_h264_dpb_error sva_DC_H264_DPB_FillBufferFilledFifo(t_sva_service_instance_num ); +PRIVATE t_sva_h264_dpb_error sva_DC_H264_DPB_ResetDPBDescInstance(t_sva_service_instance_num ); + +/* public implementation */ +/****************************************************************************/ +/* NAME: t_sva_h264_dpb_error sva_DC_H264_DPB_Init() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: This routine initialises the DPB Management Block */ +/* PARAMETERS: */ +/* IN : */ +/* OUT : */ +/* */ +/* RETURN: */ +/* t_sva_h264_dpb_error */ +/****************************************************************************/ +PUBLIC t_sva_h264_dpb_error sva_DC_H264_DPB_Init() +{ + t_sva_h264_dpb_error dpbError = SVA_DC_H264_DPB_OK; + t_uint8 i; + + sva_DC_H264_DPB_ResetDPBDesc(); + + for(i=0; idpbStartFifo.push, ffError); + if (ffError != SVA_FIFO_OK) {return SVA_DC_H264_DPB_FF_ERROR;} + + CREATE_FIFO(t_sva_h264_dpb_desc, SUBTASK_DEFAULT_NUMBER, pDPBBlock->dpbStartFifo.inUse, ffError); + if (ffError != SVA_FIFO_OK) {return SVA_DC_H264_DPB_FF_ERROR;} + +/*dpbEnd*/ + CREATE_FIFO(t_sva_h264_dpb_desc, PUSH_FIFO_DEFAULT_SIZE, pDPBBlock->dpbEndFifo.push, ffError); + if (ffError != SVA_FIFO_OK) {return SVA_DC_H264_DPB_FF_ERROR;} + + CREATE_FIFO(t_sva_h264_dpb_desc, SUBTASK_DEFAULT_NUMBER, pDPBBlock->dpbEndFifo.inUse, ffError); + if (ffError != SVA_FIFO_OK) {return SVA_DC_H264_DPB_FF_ERROR;} + +/* lastdpbfifo*/ + CREATE_FIFO(t_sva_h264_dpb_desc, PUSH_FIFO_DEFAULT_SIZE, pDPBBlock->lastDpbFifo, ffError); + if (ffError != SVA_FIFO_OK) {return SVA_DC_H264_DPB_FF_ERROR;} + + + +/*spsUtilsFifo*/ + CREATE_FIFO(t_sva_h264_dpb_sps_utils, SUBTASK_DEFAULT_NUMBER, pDPBBlock->spsUtilsFifo.inUse, ffError); + if (ffError != SVA_FIFO_OK) {return SVA_DC_H264_DPB_FF_ERROR;} + + CREATE_FIFO(t_sva_h264_dpb_sps_utils, PUSH_FIFO_DEFAULT_SIZE, pDPBBlock->spsUtilsFifo.push, ffError); + if (ffError != SVA_FIFO_OK) {return SVA_DC_H264_DPB_FF_ERROR;} + +/* slice0UtilsFifo */ + CREATE_FIFO(t_sva_h264_dpb_slice0_utils, SUBTASK_DEFAULT_NUMBER, pDPBBlock->slice0UtilsFifo.inUse, ffError); + if (ffError != SVA_FIFO_OK) {return SVA_DC_H264_DPB_FF_ERROR;} + + CREATE_FIFO(t_sva_h264_dpb_slice0_utils, PUSH_FIFO_DEFAULT_SIZE, pDPBBlock->slice0UtilsFifo.push, ffError); + if (ffError != SVA_FIFO_OK) {return SVA_DC_H264_DPB_FF_ERROR;} + + +/* bufferIdToBePushedInDPBFifo */ + CREATE_FIFO(t_sva_dpb_buffer_id, DPB_PUSH_FIFO_DEFAULT_SIZE, pDPBBlock->bufferIdToBePushedInDpbFifo, ffError); + if (ffError != SVA_FIFO_OK) {return SVA_DC_H264_DPB_FF_ERROR;} + +/* bufferIdToBeRemovedFromDPBFifo */ + CREATE_FIFO(t_sva_dpb_buffer_id, DPB_PUSH_FIFO_DEFAULT_SIZE, pDPBBlock->bufferIdToBeRemovedFromDPBFifo, ffError); + if (ffError != SVA_FIFO_OK) {return SVA_DC_H264_DPB_FF_ERROR;} + +/* sendBufferFilledFifo */ + CREATE_FIFO(t_sva_dpb_buffer_id, DPB_PUSH_FIFO_DEFAULT_SIZE, pDPBBlock->sendBufferFilledFifo, ffError); + if (ffError != SVA_FIFO_OK) {return SVA_DC_H264_DPB_FF_ERROR;} + +/* bufferIdToBeWritten */ + CREATE_FIFO(t_sva_dpb_buffer_id, DPB_PUSH_FIFO_DEFAULT_SIZE, pDPBBlock->bufferIdToBeOutputedFifo, ffError); + if (ffError != SVA_FIFO_OK) {return SVA_DC_H264_DPB_FF_ERROR;} + + + + return dpbError; +} + + + +/****************************************************************************/ +/* NAME: t_sva_h264_dpb_error sva_DC_H264_DPB_Close */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* PARAMETERS: */ +/* IN : */ +/* OUT : */ +/* */ +/* RETURN: */ +/* t_sva_h264_dpb_error */ +/****************************************************************************/ +PUBLIC t_sva_h264_dpb_error sva_DC_H264_DPB_Close(t_sva_service_instance_num instanceNum) +{ + t_sva_h264_dpb_error dpbError = SVA_DC_H264_DPB_OK; + t_sva_h264_dpb_block_desc * pDPBBlock = &DPBDesc[instanceNum]; + + DELETE_FIFO(pDPBBlock->dpbStartFifo.push); + DELETE_FIFO(pDPBBlock->dpbStartFifo.inUse ); + DELETE_FIFO(pDPBBlock->dpbEndFifo.push); + DELETE_FIFO(pDPBBlock->dpbEndFifo.inUse); + DELETE_FIFO(pDPBBlock->lastDpbFifo); + DELETE_FIFO(pDPBBlock->spsUtilsFifo.inUse); + DELETE_FIFO(pDPBBlock->spsUtilsFifo.push); + DELETE_FIFO(pDPBBlock->slice0UtilsFifo.inUse); + DELETE_FIFO(pDPBBlock->slice0UtilsFifo.push); + DELETE_FIFO(pDPBBlock->bufferIdToBePushedInDpbFifo); + DELETE_FIFO(pDPBBlock->bufferIdToBeRemovedFromDPBFifo); + DELETE_FIFO(pDPBBlock->sendBufferFilledFifo); + DELETE_FIFO(pDPBBlock->bufferIdToBeOutputedFifo); + + + return dpbError; +} + + + + +/****************************************************************************/ +/* NAME: t_sva_h264_dpb_error sva_DC_H264_DPB_SetActiveSPSUtils */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* PARAMETERS: */ +/* IN : */ +/* OUT : */ +/* */ +/* RETURN: */ +/* t_sva_h264_dpb_error */ +/****************************************************************************/ +PUBLIC t_sva_h264_dpb_error sva_DC_H264_DPB_SetActiveSPSUtils(t_sva_service_instance_num instanceNum, const t_sva_h264_dpb_sps_utils * pSPSUtils) +{ + t_sva_h264_dpb_error dpbError = SVA_DC_H264_DPB_OK; + t_sva_ff_error ffError = SVA_FIFO_OK; + t_sva_h264_dpb_block_desc * pDPBBlock = &DPBDesc[instanceNum]; + + + ffError=PUSH_FIFO_ELEM(pDPBBlock->spsUtilsFifo.push,t_sva_h264_dpb_sps_utils,*pSPSUtils); + if (ffError!= SVA_FIFO_OK) { + pDPBBlock->dpbError = SVA_DC_H264_DPB_ACTIVE_SPS_KO; + return SVA_DC_H264_DPB_FF_ERROR; + } + + + return dpbError; +} + + +/****************************************************************************/ +/* NAME: t_sva_h264_dpb_error sva_DC_H264_DPB_RemoveLastActiveSPSUtils */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* PARAMETERS: */ +/* IN : */ +/* OUT : */ +/* */ +/* RETURN: */ +/* t_sva_h264_dpb_error */ +/****************************************************************************/ +PUBLIC t_sva_h264_dpb_error sva_DC_H264_DPB_RemoveLastActiveSPSUtils(t_sva_service_instance_num instanceNum, t_sva_h264_dpb_sps_utils * pSPSUtils) +{ + t_sva_h264_dpb_error dpbError = SVA_DC_H264_DPB_OK; + t_sva_ff_error ffError = SVA_FIFO_OK; + t_sva_h264_dpb_block_desc * pDPBBlock = &DPBDesc[instanceNum]; + + + ffError=POP_REVERSE_FIFO_ELEM(pDPBBlock->spsUtilsFifo.push,t_sva_h264_dpb_sps_utils,*pSPSUtils); + if (ffError!= SVA_FIFO_OK) { + pDPBBlock->dpbError = SVA_DC_H264_DPB_ACTIVE_SPS_KO; + return SVA_DC_H264_DPB_FF_ERROR; + } + + + return dpbError; +} + +/****************************************************************************/ +/* NAME: t_sva_h264_dpb_error sva_DC_H264_DPB_SetSlice0Utils */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* PARAMETERS: */ +/* IN : */ +/* OUT : */ +/* */ +/* RETURN: */ +/* t_sva_h264_dpb_error */ +/****************************************************************************/ +PUBLIC t_sva_h264_dpb_error sva_DC_H264_DPB_SetSlice0Utils(t_sva_service_instance_num instanceNum, const t_sva_h264_dpb_slice0_utils * pSlice0Utils) +{ + t_sva_h264_dpb_error dpbError = SVA_DC_H264_DPB_OK; + t_sva_ff_error ffError = SVA_FIFO_OK; + t_sva_h264_dpb_block_desc * pDPBBlock = &DPBDesc[instanceNum]; + + ffError=PUSH_FIFO_ELEM(pDPBBlock->slice0UtilsFifo.push,t_sva_h264_dpb_slice0_utils,*pSlice0Utils); + if (ffError!= SVA_FIFO_OK) { + pDPBBlock->dpbError = SVA_DC_H264_DPB_SLICE0_KO; + return SVA_DC_H264_DPB_FF_ERROR; + } + + + return dpbError; + +} + +/****************************************************************************/ +/* NAME: t_sva_h264_dpb_error sva_DC_H264_DPB_REmoveLastSlice0Utils */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* PARAMETERS: */ +/* IN : */ +/* OUT : */ +/* */ +/* RETURN: */ +/* t_sva_h264_dpb_error */ +/****************************************************************************/ +PUBLIC t_sva_h264_dpb_error sva_DC_H264_DPB_RemoveLastSlice0Utils(t_sva_service_instance_num instanceNum, t_sva_h264_dpb_slice0_utils * pSlice0Utils) +{ + t_sva_h264_dpb_error dpbError = SVA_DC_H264_DPB_OK; + t_sva_ff_error ffError = SVA_FIFO_OK; + t_sva_h264_dpb_block_desc * pDPBBlock = &DPBDesc[instanceNum]; + + ffError=POP_REVERSE_FIFO_ELEM(pDPBBlock->slice0UtilsFifo.push,t_sva_h264_dpb_slice0_utils,*pSlice0Utils); + if (ffError!= SVA_FIFO_OK) { + pDPBBlock->dpbError = SVA_DC_H264_DPB_SLICE0_KO; + return SVA_DC_H264_DPB_FF_ERROR; + } + + + return dpbError; + +} + +/****************************************************************************/ +/* NAME: t_sva_h264_dpb_error sva_DC_H264_DPB_SetDPBSize */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* PARAMETERS: */ +/* IN : */ +/* OUT : */ +/* */ +/* RETURN: */ +/* t_sva_h264_dpb_error */ +/****************************************************************************/ +PUBLIC t_sva_h264_dpb_error sva_DC_H264_DPB_SetDPBSize(t_sva_service_instance_num instanceNum, t_size size) +{ + + t_sva_h264_dpb_error dpbError = SVA_DC_H264_DPB_OK; + t_sva_h264_dpb_block_desc * pDPBBlock = &DPBDesc[instanceNum]; + + pDPBBlock->dpbSize = size; + + return dpbError; +} + + +/****************************************************************************/ +/* NAME: t_sva_h264_dpb_error sva_DC_H264_DPB_Push */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* PARAMETERS: */ +/* IN : */ +/* OUT : */ +/* */ +/* RETURN: */ +/* t_sva_h264_dpb_error */ +/****************************************************************************/ +PUBLIC t_sva_h264_dpb_error sva_DC_H264_DPB_Push(t_sva_service_instance_num instanceNum, t_sva_buffer_id bufferId) +{ + t_sva_h264_dpb_error dpbError = SVA_DC_H264_DPB_OK; + t_sva_h264_dpb_block_desc * pDPBBlock = &DPBDesc[instanceNum]; + t_sva_ff_error ffError = SVA_FIFO_OK; + t_sva_dpb_buffer_id dpbBufferId; + + dpbBufferId.bufferId = bufferId; + dpbBufferId.dpbIndex = 0xFF; + + ffError=PUSH_FIFO_ELEM(pDPBBlock->bufferIdToBePushedInDpbFifo,t_sva_dpb_buffer_id,dpbBufferId); + if (ffError!= SVA_FIFO_OK) { + pDPBBlock->dpbError = SVA_DC_H264_DPB_PUSH_KO; + return SVA_DC_H264_DPB_INTERNAL_FIFOS_FULL; + } + + //pDPBBlock->dpbError = SVA_DC_H264_DPB_PUSH_OK; + return dpbError; +} + + + +/****************************************************************************/ +/* NAME: t_sva_h264_dpb_error sva_DC_H264_DPB_ComputeDPBStart */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* PARAMETERS: */ +/* IN : */ +/* OUT : */ +/* */ +/* RETURN: */ +/* t_sva_h264_dpb_error */ +/****************************************************************************/ +PUBLIC t_sva_h264_dpb_error sva_DC_H264_DPB_ComputeDPBStart(t_sva_service_instance_num instanceNum, t_sva_buffer_id *pBufferId, t_sva_h264_dpb_desc * pDpb) +{ + t_sva_h264_dpb_error dpbError = SVA_DC_H264_DPB_OK; + t_sva_ff_error ffError = SVA_FIFO_OK; + t_sva_h264_dpb_block_desc * pDPBBlock = &DPBDesc[instanceNum]; + + +// t_sva_h264_dpb_sps_utils spsUtils; +// t_sva_h264_dpb_slice0_utils slice0Utils; + t_sva_h264_dpb_desc dpbStart; + + t_sva_h264_dpb_sps_utils *p_sps = &pDPBBlock->spsUtils; + t_sva_h264_dpb_slice0_utils *p_slice0= &pDPBBlock->slice0Utils; + t_sva_h264_dpb_poc *p_poc; + t_sva_h264_dpb_desc *p_dpbStart = &dpbStart; + +#ifdef __DEBUG + volatile t_bool debugbool = FALSE; +#endif + + dpbStart = pDPBBlock->newDpbStart; + + /* take spsUtils */ + ffError=POP_FIFO_ELEM(pDPBBlock->spsUtilsFifo.push,t_sva_h264_dpb_sps_utils,pDPBBlock->spsUtils); + if (ffError!= SVA_FIFO_OK) { + + + pDPBBlock->dpbError = SVA_DC_H264_DPB_START_FF_ERROR; + return SVA_DC_H264_DPB_FF_ERROR; + } + + ffError=PUSH_FIFO_ELEM(pDPBBlock->spsUtilsFifo.inUse,t_sva_h264_dpb_sps_utils,pDPBBlock->spsUtils); + if (ffError!= SVA_FIFO_OK) { + + pDPBBlock->dpbError = SVA_DC_H264_DPB_START_FF_ERROR; + return SVA_DC_H264_DPB_FF_ERROR; + } + + + + /* take slice0Utils */ + ffError=POP_FIFO_ELEM(pDPBBlock->slice0UtilsFifo.push,t_sva_h264_dpb_slice0_utils,pDPBBlock->slice0Utils); + if (ffError!= SVA_FIFO_OK) { + pDPBBlock->dpbError = SVA_DC_H264_DPB_START_FF_ERROR; + return SVA_DC_H264_DPB_FF_ERROR; + } + + + ffError=PUSH_FIFO_ELEM(pDPBBlock->slice0UtilsFifo.inUse,t_sva_h264_dpb_slice0_utils,pDPBBlock->slice0Utils); + if (ffError!= SVA_FIFO_OK) { + pDPBBlock->dpbError = SVA_DC_H264_DPB_START_FF_ERROR; + return SVA_DC_H264_DPB_FF_ERROR; + } + + + p_poc = &p_dpbStart->pocUtils; + + + if(p_slice0->nut == 5) + { + + /* check if newIDR can be done */ + if(GET_FIFO_NB_ELEMS(pDPBBlock->bufferIdToBePushedInDpbFifo) < 1) + { + /* cannot be done then : */ + /* take spsUtils */ + POP_REVERSE_FIFO_ELEM(pDPBBlock->spsUtilsFifo.inUse,t_sva_h264_dpb_sps_utils,pDPBBlock->spsUtils); + PUSH_REVERSE_FIFO_ELEM(pDPBBlock->spsUtilsFifo.push,t_sva_h264_dpb_sps_utils,pDPBBlock->spsUtils); + + /* take slice0Utils */ + POP_REVERSE_FIFO_ELEM(pDPBBlock->slice0UtilsFifo.inUse,t_sva_h264_dpb_slice0_utils,pDPBBlock->slice0Utils); + PUSH_REVERSE_FIFO_ELEM(pDPBBlock->slice0UtilsFifo.push,t_sva_h264_dpb_slice0_utils,pDPBBlock->slice0Utils); + + return SVA_DC_H264_DPB_MISSING_BUFFERS_IN_DPB; + } + + + /* can be done :*/ + + p_poc->previousFrameNum = -1; + + /* ------- */ + /* New IDR */ + /* ------- */ + /* This performs all operations needed when a new IDR frame is being decoded */ + + if ((p_slice0->noOutputOfPriorPicsFlag)||(pDPBBlock->first == TRUE)) + { + sva_DC_H264_DPB_InitDPB(instanceNum, p_dpbStart); + } + else + { + dpbError = sva_DC_H264_DPB_FlushDPB(instanceNum, p_dpbStart,256); + if(dpbError!= SVA_DC_H264_DPB_OK) return dpbError; + + } + + /* Update informations for POC decoding */ + + p_poc->frameNumOffset = 0; + p_poc->prevPicOrderCntMsb = 0; + p_poc->prevPicOrderCntLsb = 0; + + + /* Initialize current frame infos */ + p_dpbStart->curDecodedIndex = 0; + + + + dpbError = sva_DC_H264_DPB_CheckBufferId(instanceNum, p_dpbStart, 0); + pDPBBlock->dpbError = dpbError; /* cannot be MISSING_BUFFER */ + + + + p_dpbStart->pCurDecodedInfo = &p_dpbStart->decodedBuffer[0]; + p_dpbStart->decodedBuffer[0].frameNum = p_slice0->frameNum; + + + sva_DC_H264_DPB_DecodePOC( + p_sps, + p_slice0, + p_poc, + &p_dpbStart->decodedBuffer[0].poc); + + p_dpbStart->decodedBuffer[0].markedShort = FALSE; + p_dpbStart->decodedBuffer[0].picNum = 0; + p_dpbStart->decodedBuffer[0].markedLong = FALSE; + p_dpbStart->decodedBuffer[0].needDisplay = TRUE; + + p_dpbStart->fullness++; + + + } + else + { + /* --------- */ + /* New Frame */ + /* --------- */ + /* This initializes DPB for a new frame. Decoding of gaps in frame number is also performed. */ + t_uint32 maxFrameNum = (1 << (p_sps->log2MaxFrameNumMinus4 + 4)); + t_uint16 prevNum = (t_uint16)((p_poc->previousFrameNum + 1) % maxFrameNum); + t_uint32 missing; + t_uint32 index, ind; + t_bool isAddedNonEx = FALSE; + + + /* Check for gaps in frame number */ + if ((p_slice0->frameNum != p_poc->previousFrameNum) && (p_slice0->frameNum != prevNum)) + { + if (!p_sps->gapsInFrameNumValueFlag) + { + + + + // Check number of missing frames + + missing = (p_slice0->frameNum < prevNum) ? maxFrameNum - prevNum + (t_uint32)p_slice0->frameNum : (t_uint32)p_slice0->frameNum - prevNum; + + if (missing > (t_uint32)H264MAX(p_sps->numRefFrames, 2)) + { + pDPBBlock->dpbError = SVA_DC_H264_DPB_START_RESYNCH_NEW_FRAME; + return SVA_DC_H264_DPB_RESYNCH_NEW_FRAME; + } + + dpbError=sva_DC_H264_DPB_ConcealGetAllImageBuffer(instanceNum,missing+1);//+1 for taking care ofnext frame after concealment + if(dpbError == SVA_DC_H264_DPB_MISSING_BUFFERS_IN_DPB) + { + pDPBBlock->dpbError = SVA_DC_H264_DPB_MISSING_BUFFERS_IN_DPB; + return SVA_DC_H264_DPB_MISSING_BUFFERS_IN_DPB; + } + + + do + { + dpbError = sva_DC_H264_DPB_GetIndexForNewFrame(instanceNum, prevNum, maxFrameNum, p_sps, p_dpbStart, &index); + if(dpbError != SVA_DC_H264_DPB_OK) + { + pDPBBlock->dpbError = dpbError; + return dpbError; + } + + // Conceal missing frame + dpbError=sva_DC_H264_DPB_ConcealNewFrame(instanceNum,prevNum, index, p_sps, p_dpbStart); + if ( dpbError == SVA_DC_H264_DPB_UNABLE_TO_CONCEAL_FRAME) + { + pDPBBlock->dpbError = SVA_DC_H264_DPB_START_RESYNCH_NEW_FRAME; + return SVA_DC_H264_DPB_RESYNCH_NEW_FRAME; + } + if(dpbError == SVA_DC_H264_DPB_MISSING_BUFFERS_IN_DPB) + { + pDPBBlock->dpbError = SVA_DC_H264_DPB_MISSING_BUFFERS_IN_DPB; + return SVA_DC_H264_DPB_MISSING_BUFFERS_IN_DPB; + } + + dpbError = sva_DC_H264_DPB_CheckBufferId(instanceNum, p_dpbStart, index); + pDPBBlock->dpbError = dpbError; /* cannot be MISSING_BUFFER */ + + prevNum = (t_uint16)((prevNum + 1) % maxFrameNum); + + } + while (prevNum != p_slice0->frameNum); + + + + } + else + { + + + t_uint32 checkMaxFrameNum = maxFrameNum; + t_uint16 checkPrevNum = prevNum; + t_uint32 nonExistingFrameNbPlus1=1; + + /* check if next process will be possible or not (from buffer availability point of view) */ + do + { + nonExistingFrameNbPlus1 ++; + checkPrevNum = (t_uint16)((checkPrevNum + 1) % checkMaxFrameNum); + } + while (checkPrevNum != p_slice0->frameNum); + + if(GET_FIFO_NB_ELEMS(pDPBBlock->bufferIdToBePushedInDpbFifo) < nonExistingFrameNbPlus1) + { + + /* take spsUtils */ + POP_REVERSE_FIFO_ELEM(pDPBBlock->spsUtilsFifo.inUse,t_sva_h264_dpb_sps_utils,pDPBBlock->spsUtils); + PUSH_REVERSE_FIFO_ELEM(pDPBBlock->spsUtilsFifo.push,t_sva_h264_dpb_sps_utils,pDPBBlock->spsUtils); + + /* take slice0Utils */ + POP_REVERSE_FIFO_ELEM(pDPBBlock->slice0UtilsFifo.inUse,t_sva_h264_dpb_slice0_utils,pDPBBlock->slice0Utils); + PUSH_REVERSE_FIFO_ELEM(pDPBBlock->slice0UtilsFifo.push,t_sva_h264_dpb_slice0_utils,pDPBBlock->slice0Utils); + + return SVA_DC_H264_DPB_MISSING_BUFFERS_IN_DPB; + + + + } + + isAddedNonEx = TRUE; + + + /* Insert non-existing frame to fill gap */ + do + { + dpbError = sva_DC_H264_DPB_GetIndexForNewFrame(instanceNum, prevNum, maxFrameNum, p_sps, p_dpbStart, &index); + if(dpbError != SVA_DC_H264_DPB_OK) + { + pDPBBlock->dpbError = dpbError; + return dpbError; + } + + dpbError = sva_DC_H264_DPB_CheckBufferId(instanceNum, p_dpbStart, index); + pDPBBlock->dpbError = dpbError; /* cannot be MISSING_BUFFER */ + + /* modify frame infos */ + p_dpbStart->decodedBuffer[index].frameNum = prevNum; + p_dpbStart->decodedBuffer[index].frameNumWrap = p_dpbStart->decodedBuffer[index].picNum = p_dpbStart->decodedBuffer[index].frameNum; + p_dpbStart->decodedBuffer[index].markedShort = TRUE; + p_dpbStart->decodedBuffer[index].markedLong = FALSE; + p_dpbStart->decodedBuffer[index].needDisplay = FALSE; + + p_dpbStart->numShortRef++; + p_dpbStart->fullness++; + + prevNum = (t_uint16)((prevNum + 1) % maxFrameNum); + } + while (prevNum != p_slice0->frameNum); + } + + + + } + + + /* check if following process can be done */ + if((GET_FIFO_NB_ELEMS(pDPBBlock->bufferIdToBePushedInDpbFifo) < 1)&&(!isAddedNonEx)) + { + /* no */ + + + /* take spsUtils */ + POP_REVERSE_FIFO_ELEM(pDPBBlock->spsUtilsFifo.inUse,t_sva_h264_dpb_sps_utils,pDPBBlock->spsUtils); + PUSH_REVERSE_FIFO_ELEM(pDPBBlock->spsUtilsFifo.push,t_sva_h264_dpb_sps_utils,pDPBBlock->spsUtils); + + /* take slice0Utils */ + POP_REVERSE_FIFO_ELEM(pDPBBlock->slice0UtilsFifo.inUse,t_sva_h264_dpb_slice0_utils,pDPBBlock->slice0Utils); + PUSH_REVERSE_FIFO_ELEM(pDPBBlock->slice0UtilsFifo.push,t_sva_h264_dpb_slice0_utils,pDPBBlock->slice0Utils); + + return SVA_DC_H264_DPB_MISSING_BUFFERS_IN_DPB; + + } + + + /* yes */ + + if ((sva_DC_H264_DPB_FindShort((t_uint16)p_dpbStart->size, p_slice0->frameNum, p_dpbStart->decodedBuffer, &ind) != SVA_DC_H264_DPB_NO_MORE_SHORT_REF) && (p_slice0->nri > 0)) + { + pDPBBlock->dpbError = SVA_DC_H264_DPB_START_DROP_NEW_FRAME; + return SVA_DC_H264_DPB_DROP_NEW_FRAME; + } + + + + dpbError = sva_DC_H264_DPB_GetIndexForNewFrame(instanceNum, prevNum, maxFrameNum, p_sps, p_dpbStart, &index); + if(dpbError != SVA_DC_H264_DPB_OK) + { + + pDPBBlock->dpbError = dpbError; + return dpbError; + } + + /* Initialize frame infos */ + p_dpbStart->curDecodedIndex = (t_uint16)index; + + + dpbError = sva_DC_H264_DPB_CheckBufferId(instanceNum, p_dpbStart, index); + pDPBBlock->dpbError = dpbError; /* cannot be MISSING_BUFFER */ + + + p_dpbStart->pCurDecodedInfo = &p_dpbStart->decodedBuffer[index]; + + p_dpbStart->pCurDecodedInfo->frameNum = p_slice0->frameNum; + p_dpbStart->pCurDecodedInfo->frameNumWrap = p_dpbStart->pCurDecodedInfo->picNum = p_dpbStart->pCurDecodedInfo->frameNum; + + + + sva_DC_H264_DPB_DecodePOC( + p_sps, + p_slice0, + p_poc, + &p_dpbStart->pCurDecodedInfo->poc); + + p_dpbStart->pCurDecodedInfo->markedShort = FALSE; + p_dpbStart->pCurDecodedInfo->markedLong = FALSE; + p_dpbStart->pCurDecodedInfo->needDisplay = TRUE; + + p_dpbStart->fullness++; + + + } + + + + + *pBufferId = p_dpbStart->pCurDecodedInfo->bufferId; + + /* push DpbStart as it is ready to get used */ + ffError=PUSH_FIFO_ELEM(pDPBBlock->dpbStartFifo.push,t_sva_h264_dpb_desc,dpbStart); + if (ffError!= SVA_FIFO_OK) { + pDPBBlock->dpbError = SVA_DC_H264_DPB_INTERNAL_FIFOS_FULL; + return SVA_DC_H264_DPB_FF_ERROR; + } + + *pDpb = dpbStart; + +#ifdef __DEBUG + + pDPBBlock->dpbStartTrace[pDPBBlock->dbgDpbStartCounter] = dpbStart; + //pDPBBlock->dbgDestBufferId[pDPBBlock->dbgDpbStartCounter]= p_dpbStart->pCurDecodedInfo->bufferId; + pDPBBlock->dbgDpbStartCounter ++; + if (pDPBBlock->dbgDpbStartCounter == SVA_DC_H264_MAX_DBG_DEPTH) + { + pDPBBlock->dbgDpbStartCounter = 0; + pDPBBlock->dbgInc ++; + } + + + + + + + +#endif + + + + //pDPBBlock->dpbError = SVA_DC_H264_DPB_START_OK; + return dpbError; +} + +/****************************************************************************/ +/* NAME: t_sva_h264_dpb_error sva_DC_H264_DPB_ComputeDPBEnd */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* PARAMETERS: */ +/* IN : */ +/* OUT : */ +/* */ +/* RETURN: */ +/* t_sva_h264_dpb_error */ +/****************************************************************************/ +PUBLIC t_sva_h264_dpb_error sva_DC_H264_DPB_ComputeDPBEnd(t_sva_service_instance_num instanceNum,t_sva_h264_dpb_desc dpb) +{ + t_sva_h264_dpb_error dpbError = SVA_DC_H264_DPB_OK; + t_sva_ff_error ffError = SVA_FIFO_OK; + t_sva_h264_dpb_block_desc * pDPBBlock = &DPBDesc[instanceNum]; + t_sva_h264_dpb_desc dpbEnd; +// t_sva_h264_dpb_sps_utils spsUtils; +// t_sva_h264_dpb_slice0_utils slice0Utils; + t_sva_h264_dpb_desc * p_dpbEnd = &dpbEnd; + t_sva_h264_dpb_sps_utils * p_sps = &pDPBBlock->spsUtils; + t_sva_h264_dpb_slice0_utils * p_slice0 = &pDPBBlock->slice0Utils; + t_sva_h264_dpb_poc * p_poc; + + + /* pop utils: wont be used after */ + ffError=POP_FIFO_ELEM(pDPBBlock->spsUtilsFifo.inUse,t_sva_h264_dpb_sps_utils,pDPBBlock->spsUtils); + if (ffError!= SVA_FIFO_OK) { + pDPBBlock->dpbError = SVA_DC_H264_DPB_END_FF_ERROR; + return SVA_DC_H264_DPB_FF_ERROR; + } + + ffError=POP_FIFO_ELEM(pDPBBlock->slice0UtilsFifo.inUse,t_sva_h264_dpb_slice0_utils,pDPBBlock->slice0Utils); + if (ffError!= SVA_FIFO_OK) { + pDPBBlock->dpbError = SVA_DC_H264_DPB_END_FF_ERROR; + return SVA_DC_H264_DPB_FF_ERROR; + } + + + /* new dpbEnd is coming from last dpbStart*/ + /* + ffError=READ_FIFO_ELEM(pDPBBlock->dpbStartFifo.push,t_sva_h264_dpb_desc,dpbEnd); + if (ffError!= SVA_FIFO_OK) { + pDPBBlock->dpbError = SVA_DC_H264_DPB_END_FF_ERROR; + return SVA_DC_H264_DPB_FF_ERROR; + } + */ + + dpbEnd = dpb; + + + + p_poc = &dpbEnd.pocUtils; + + + p_poc->previousFrameNum = p_slice0->frameNum; + + dpbError=sva_DC_H264_DPB_MarkDecodedFrame(instanceNum, p_sps, p_slice0, p_poc, p_dpbEnd); + if(dpbError!=SVA_DC_H264_DPB_OK) + { + pDPBBlock->dpbError = SVA_DC_H264_DPB_END_MARK_ERROR; + return dpbError; + } + + + /* push DpbEnd as it is ready to get used */ + ffError=PUSH_FIFO_ELEM(pDPBBlock->dpbEndFifo.push,t_sva_h264_dpb_desc,dpbEnd); + if (ffError!= SVA_FIFO_OK) { + pDPBBlock->dpbError = SVA_DC_H264_DPB_END_FF_ERROR; + return SVA_DC_H264_DPB_FF_ERROR; + } + + pDPBBlock->newDpbStart = dpbEnd; + + //pDPBBlock->dpbError = SVA_DC_H264_DPB_END_OK; + return dpbError; +} + + +/****************************************************************************/ +/* NAME: t_sva_h264_dpb_error sva_DC_H264_DPB_FlushToBeDisplayedFifo */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* PARAMETERS: */ +/* IN : */ +/* OUT : */ +/* */ +/* RETURN: */ +/* t_sva_h264_dpb_error */ +/****************************************************************************/ + +PUBLIC t_sva_h264_dpb_error sva_DC_H264_DPB_FlushToBeDisplayedFifo(t_sva_service_instance_num instanceNum ) +{ + t_sva_h264_dpb_error dpbError = SVA_DC_H264_DPB_OK; + t_sva_ff_error ffError = SVA_FIFO_OK; + t_sva_h264_dpb_block_desc * pDPBBlock = &DPBDesc[instanceNum]; + + t_uint32 nbElems, i; + t_sva_dpb_buffer_id dpbBufferId; + + nbElems = GET_FIFO_NB_ELEMS(pDPBBlock->bufferIdToBeRemovedFromDPBFifo); + for(i=0; ibufferIdToBeRemovedFromDPBFifo, t_sva_dpb_buffer_id, dpbBufferId); + if (ffError!= SVA_FIFO_OK) { + pDPBBlock->dpbError = SVA_DC_H264_DPB_FLUSH_TO_BE_DISPLAYED_KO; + return SVA_DC_H264_DPB_FF_ERROR; + } + + + ffError = PUSH_FIFO_ELEM(pDPBBlock->sendBufferFilledFifo, t_sva_dpb_buffer_id, dpbBufferId); + if (ffError!= SVA_FIFO_OK) { + pDPBBlock->dpbError = SVA_DC_H264_DPB_INTERNAL_FIFOS_FULL; + return SVA_DC_H264_DPB_INTERNAL_FIFOS_FULL; + } + dpbBufferId.bufferId = INVALID_BUFFER_ID; +// pDpb->fullness--; + + + + } + + //pDPBBlock->dpbError = SVA_DC_H264_DPB_FLUSH_TO_BE_DISPLAYED_OK; + return dpbError; +} + + +/****************************************************************************/ +/* NAME: t_sva_h264_dpb_error sva_DC_H264_DPB_GetBufferFilled */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* PARAMETERS: */ +/* IN : */ +/* OUT : */ +/* */ +/* RETURN: */ +/* t_sva_h264_dpb_error */ +/****************************************************************************/ +PUBLIC t_sva_h264_dpb_error sva_DC_H264_DPB_GetBufferFilled(t_sva_service_instance_num instanceNum, t_sva_buffer_id * pBufferId, t_bool * pEnded) +{ + t_sva_h264_dpb_error dpbError = SVA_DC_H264_DPB_OK; + t_sva_ff_error ffError = SVA_FIFO_OK; + t_sva_h264_dpb_block_desc * pDPBBlock = &DPBDesc[instanceNum]; + t_sva_dpb_buffer_id dpbBufferId; + + if(IS_FIFO_EMPTY(pDPBBlock->sendBufferFilledFifo)) *pEnded = TRUE; + else + { + + *pEnded = FALSE; + + ffError = POP_FIFO_ELEM(pDPBBlock->sendBufferFilledFifo, t_sva_dpb_buffer_id, dpbBufferId); + *pBufferId = dpbBufferId.bufferId; + + #ifdef __DEBUG + pDPBBlock->dbgBufferFilled[pDPBBlock->dbgBufferFilledCounter]= dpbBufferId; + pDPBBlock->dbgBufferFilledCounter ++; + if (pDPBBlock->dbgBufferFilledCounter == SVA_DC_H264_MAX_DBG_DEPTH) pDPBBlock->dbgBufferFilledCounter = 0; + + #endif + + + if (ffError!= SVA_FIFO_OK) { *pEnded = TRUE;} + } + + return dpbError; + +} + +PUBLIC t_sva_h264_dpb_error sva_DC_H264_DPB_GetBufferFilledRead(t_sva_service_instance_num instanceNum, t_sva_buffer_id * pBufferId, t_bool * pEnded) +{ + t_sva_h264_dpb_error dpbError = SVA_DC_H264_DPB_OK; + t_sva_ff_error ffError = SVA_FIFO_OK; + t_sva_h264_dpb_block_desc * pDPBBlock = &DPBDesc[instanceNum]; + t_sva_dpb_buffer_id dpbBufferId; + + if(IS_FIFO_EMPTY(pDPBBlock->bufferIdToBeOutputedFifo)) *pEnded = TRUE; + else + { + + *pEnded = FALSE; + + ffError = POP_FIFO_ELEM(pDPBBlock->bufferIdToBeOutputedFifo, t_sva_dpb_buffer_id, dpbBufferId); + *pBufferId = dpbBufferId.bufferId; + + if (ffError!= SVA_FIFO_OK) {*pEnded = TRUE;} + } + + return dpbError; + +} + + + +/****************************************************************************/ +/* NAME: t_sva_h264_dpb_error sva_DC_H264_DPB_FlushFifos */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* PARAMETERS: */ +/* IN : */ +/* OUT : */ +/* */ +/* RETURN: */ +/* t_sva_h264_dpb_error */ +/****************************************************************************/ +PUBLIC t_sva_h264_dpb_error sva_DC_H264_DPB_FlushFifos(t_sva_service_id serviceId) +{ + + t_sva_h264_dpb_error dpbError = SVA_DC_H264_DPB_OK; + t_sva_error svaError = SVA_OK; + t_sva_bm_error bmError = SVA_BM_OK; + t_sva_service_instance_num instanceNum = READ_INSTANCE_NUM_IN_SERVICE_ID(serviceId); + t_sva_h264_dpb_block_desc * pDPBBlock = &DPBDesc[instanceNum]; + t_uint32 systemTime; + //t_sva_buffer_id bufferId = INVALID_BUFFER_ID; + t_sva_h264_dpb_desc curDpb; + t_uint16 i=0; + //t_uint32 index=0; + t_sva_dpb_buffer_id dpbBufferId; + + /*get time*/ + svaError=SVA_GetServiceSystemTime(serviceId ,&systemTime); + if (svaError != SVA_OK) {return SVA_DC_H264_DPB_ERROR;} + + FLUSH_FIFO(pDPBBlock->dpbStartFifo.push); + FLUSH_FIFO(pDPBBlock->dpbEndFifo.push); + FLUSH_FIFO(pDPBBlock->dpbStartFifo.inUse); + FLUSH_FIFO(pDPBBlock->dpbEndFifo.inUse); + FLUSH_FIFO(pDPBBlock->spsUtilsFifo.inUse); + FLUSH_FIFO(pDPBBlock->spsUtilsFifo.push); + FLUSH_FIFO(pDPBBlock->slice0UtilsFifo.inUse); + FLUSH_FIFO(pDPBBlock->slice0UtilsFifo.push); + + //FLUSH_FIFO(pDPBBlock->bufferIdToBeOutputedFifo); + + + /* bufferIdToBeRemovedFromDPBFifo and sendBufferFilledFifo done in another way */ + /* lastdpbFifo also*/ + if(POP_FIFO_ELEM(pDPBBlock->lastDpbFifo, t_sva_h264_dpb_desc, curDpb) != SVA_FIFO_EMPTY) + { + + + dpbError = sva_DC_H264_DPB_FlushDPB(instanceNum, &curDpb,256); + if((dpbError !=SVA_DC_H264_DPB_OK )&&(dpbError !=SVA_DC_H264_DPB_BUMPING_ENDED)) + { + pDPBBlock->dpbError = SVA_DC_H264_DPB_FLUSH_FIFOS_KO; + return dpbError; + } + + + dpbError = sva_DC_H264_DPB_FlushToBeDisplayedFifo(instanceNum); + if(dpbError !=SVA_DC_H264_DPB_OK ) + { + pDPBBlock->dpbError = SVA_DC_H264_DPB_FLUSH_FIFOS_KO; + return dpbError; + } + + } + + while(POP_FIFO_ELEM(pDPBBlock->bufferIdToBePushedInDpbFifo,t_sva_dpb_buffer_id,dpbBufferId) != SVA_FIFO_EMPTY) + { + bmError=sva_BM_UpdateBufferStatus(dpbBufferId.bufferId,SVA_BUFFER_NOT_USED,systemTime); + if (bmError!=SVA_BM_OK) { + pDPBBlock->dpbError = SVA_DC_H264_DPB_FLUSH_FIFOS_KO; + return SVA_DC_H264_DPB_ERROR; + } + } + + + + for(i=0; idpbError = SVA_DC_H264_DPB_FLUSH_FIFOS_OK; + return dpbError; + +} + +/****************************************************************************/ +/* NAME: t_sva_h264_dpb_error sva_DC_H264_DPB_AreDPBStatesAvailable */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* PARAMETERS: */ +/* IN : */ +/* OUT : */ +/* */ +/* RETURN: */ +/* t_sva_h264_dpb_error */ +/****************************************************************************/ +PUBLIC t_sva_h264_dpb_error sva_DC_H264_DPB_AreDPBStatesAvailable(t_sva_service_instance_num instanceNum, t_bool *infosAvailable) +{ + t_sva_h264_dpb_error dpbError = SVA_DC_H264_DPB_OK; + t_sva_h264_dpb_block_desc * pDPBBlock = &DPBDesc[instanceNum]; + t_bool IsDpbStartFifoEmpty; + t_bool IsDpbEndFifoEmpty; + + HCL_ASSERT(infosAvailable!=NULL); + + IsDpbStartFifoEmpty=(t_bool)IS_FIFO_EMPTY(pDPBBlock->dpbStartFifo.push); + IsDpbEndFifoEmpty=(t_bool)IS_FIFO_EMPTY(pDPBBlock->dpbEndFifo.push); + + *infosAvailable= (t_bool)!(IsDpbStartFifoEmpty || IsDpbEndFifoEmpty); + + //pDPBBlock->dpbError = SVA_DC_H264_DPB_STATES_OK; + return dpbError; +} + +/****************************************************************************/ +/* NAME: t_sva_h264_dpb_error sva_DC_H264_DPB_GetDPBStates */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* PARAMETERS: */ +/* IN : */ +/* OUT : */ +/* */ +/* RETURN: */ +/* t_sva_h264_dpb_error */ +/****************************************************************************/ +PUBLIC t_sva_h264_dpb_error sva_DC_H264_DPB_GetDPBStates(t_sva_service_instance_num instanceNum) +{ + t_sva_h264_dpb_error dpbError = SVA_DC_H264_DPB_OK; + t_sva_h264_dpb_block_desc * pDPBBlock = &DPBDesc[instanceNum]; + t_sva_ff_error ffError = SVA_FIFO_OK; + t_sva_h264_dpb_desc dpbStart, dpbEnd; + + + ffError = POP_FIFO_ELEM(pDPBBlock->dpbStartFifo.push, t_sva_h264_dpb_desc, dpbStart); + if(ffError != SVA_FIFO_OK) + { + pDPBBlock->dpbError = SVA_DC_H264_DPB_GET_STATES_KO; + return SVA_DC_H264_DPB_FF_ERROR; + } + + ffError =PUSH_FIFO_ELEM(pDPBBlock->dpbStartFifo.inUse, t_sva_h264_dpb_desc, dpbStart); + if(ffError != SVA_FIFO_OK) + { + pDPBBlock->dpbError = SVA_DC_H264_DPB_GET_STATES_KO; + return SVA_DC_H264_DPB_FF_ERROR; + } + + ffError =POP_FIFO_ELEM(pDPBBlock->dpbEndFifo.push, t_sva_h264_dpb_desc, dpbEnd); + if(ffError != SVA_FIFO_OK) + { + pDPBBlock->dpbError = SVA_DC_H264_DPB_GET_STATES_KO; + return SVA_DC_H264_DPB_FF_ERROR; + } + + ffError =PUSH_FIFO_ELEM(pDPBBlock->dpbEndFifo.inUse, t_sva_h264_dpb_desc, dpbEnd); + if(ffError != SVA_FIFO_OK) + { + pDPBBlock->dpbError = SVA_DC_H264_DPB_GET_STATES_KO; + return SVA_DC_H264_DPB_FF_ERROR; + } + + //pDPBBlock->dpbError = SVA_DC_H264_DPB_GET_STATES_OK; + return dpbError; +} + +/****************************************************************************/ +/* NAME: t_sva_h264_dpb_error sva_DC_H264_DPB_PesetDPBStates */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* PARAMETERS: */ +/* IN : */ +/* OUT : */ +/* */ +/* RETURN: */ +/* t_sva_h264_dpb_error */ +/****************************************************************************/ +PUBLIC t_sva_h264_dpb_error sva_DC_H264_DPB_ResetDPBStates(t_sva_service_instance_num instanceNum) +{ + t_sva_h264_dpb_error dpbError = SVA_DC_H264_DPB_OK; + t_sva_h264_dpb_block_desc * pDPBBlock = &DPBDesc[instanceNum]; + t_sva_ff_error ffError = SVA_FIFO_OK; + t_sva_h264_dpb_desc dpbEnd; + + if(!IS_FIFO_EMPTY(pDPBBlock->lastDpbFifo)) + { + ffError = POP_FIFO_ELEM(pDPBBlock->lastDpbFifo, t_sva_h264_dpb_desc, dpbEnd); + if(ffError != SVA_FIFO_OK) + { + pDPBBlock->dpbError = SVA_DC_H264_DPB_RESET_STATES_KO; + return SVA_DC_H264_DPB_FF_ERROR; + } + } + + + ffError = POP_FIFO_ELEM(pDPBBlock->dpbEndFifo.inUse, t_sva_h264_dpb_desc, dpbEnd); + if(ffError != SVA_FIFO_OK) + { + pDPBBlock->dpbError = SVA_DC_H264_DPB_RESET_STATES_KO; + return SVA_DC_H264_DPB_FF_ERROR; + } + + + ffError = PUSH_FIFO_ELEM(pDPBBlock->lastDpbFifo, t_sva_h264_dpb_desc, dpbEnd); + if(ffError != SVA_FIFO_OK) + { + pDPBBlock->dpbError = SVA_DC_H264_DPB_RESET_STATES_KO; + return SVA_DC_H264_DPB_FF_ERROR; + } + + + return dpbError; +} + + + +/****************************************************************************/ +/* NAME: t_sva_h264_dpb_error sva_DC_H264_DPB_GetConcealmentInfo */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* PARAMETERS: */ +/* IN : */ +/* OUT : */ +/* */ +/* RETURN: */ +/* t_sva_h264_dpb_error */ +/****************************************************************************/ +PUBLIC t_sva_h264_dpb_error sva_DC_H264_DPB_GetConcealmentInfo( + t_sva_service_instance_num instanceNum, + t_sva_buffer_id * pList0, + t_uint16 slice0Nut, + t_uint16 slice0Type, + t_sva_buffer_id * pRefBufferId, + t_uint16* pIntraConc + ) +{ + + t_sva_h264_dpb_error dpbError = SVA_DC_H264_DPB_NO_LIST0; + t_sva_ff_error ffError=SVA_FIFO_OK; + t_sva_h264_dpb_block_desc * pDPBBlock = &DPBDesc[instanceNum]; + t_sint32 i, index; + t_sint32 poc = H264_MIN_SINT_32; + t_sva_h264_dpb_desc currentDpb; + + + /* use right dpbstart!!! */ + /* last access to DPB Start, wont be used after : can be popped from fifo now */ + + ffError = POP_FIFO_ELEM(pDPBBlock->dpbStartFifo.inUse, t_sva_h264_dpb_desc, currentDpb); + if (ffError!= SVA_FIFO_OK) { + pDPBBlock->dpbError = SVA_DC_H264_DPB_CONCEALMENT_KO; + return SVA_DC_H264_DPB_FF_ERROR; + } + + + + *pIntraConc = 1; + * pRefBufferId = INVALID_BUFFER_ID; + + if (slice0Nut != 5) + { + dpbError = SVA_DC_H264_DPB_OK; + + if ((slice0Type == 0) || (slice0Type == 5)) + { + /* If P slice use list0 first entry */ + * pRefBufferId = pList0[0]; + + /* Says that hamac has to check for scene change I */ + *pIntraConc = 2; + + + } + else + { + /* If I slice search for highest POC in DPB */ + index = -1; + for (i = 0; i < (t_sint32)currentDpb.size+1; i++) + { + if (((currentDpb.decodedBuffer[i].markedShort) || (currentDpb.decodedBuffer[i].markedLong)) && (currentDpb.decodedBuffer[i].poc > poc)) + { + poc = currentDpb.decodedBuffer[i].poc; + index = i; + } + } + + if (index > -1) + { + * pRefBufferId = currentDpb.decodedBuffer[index].bufferId; + + /* Says that hamac has to check for scene change P*/ + *pIntraConc = 3; + } + } + } + return dpbError; + +} + +/****************************************************************************/ +/* NAME: t_sva_h264_dpb_error sva_DC_H264_DPB_InitList0 */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* PARAMETERS: */ +/* IN : */ +/* OUT : */ +/* */ +/* RETURN: */ +/* t_sva_h264_dpb_error */ +/****************************************************************************/ +PUBLIC t_sva_h264_dpb_error sva_DC_H264_DPB_InitList0(t_sva_buffer_id * pList0) +{ + t_uint16 i=0; + + for(i=0; i<17; i++) + { + pList0[i] = SVA_DC_H264_DPB_UNUSED_BUFFER; + + } + return SVA_DC_H264_DPB_OK; + +} + + +/****************************************************************************/ +/* NAME: t_sva_h264_dpb_error sva_DC_H264_DPB_ProvideList0 */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* PARAMETERS: */ +/* IN : */ +/* OUT : */ +/* */ +/* RETURN: */ +/* t_sva_h264_dpb_error */ +/****************************************************************************/ +PUBLIC t_sva_h264_dpb_error sva_DC_H264_DPB_ProvideList0( + t_sva_service_instance_num instanceNum, + t_uint16 SPSLog2MaxFrameNumMinus4, + t_uint16 PPSNumRefIdx10ActiveMinus1, + const t_sva_h264_dpb_params_slice * pSlice, + t_sva_buffer_id * pList0) +{ + + t_sva_h264_dpb_error dpbError = SVA_DC_H264_DPB_OK; + t_sva_h264_dpb_block_desc * pDPBBlock = &DPBDesc[instanceNum]; + + +/* If the slice is a P slice */ +/* ------------------------- */ + if (sva_DC_H264_isPSlice(pSlice) == TRUE) + { + + t_uint32 i, j; + t_sint16 index, status; + t_sint32 val; + t_uint16 num_active_ref; + t_uint32 MaxFrameNum = (1 << (SPSLog2MaxFrameNumMinus4 + 4)); + t_sint16 indexes[17]; + t_sva_h264_dpb_desc currentDpb; + t_sva_h264_dpb_desc * pDpb = ¤tDpb; + t_sva_ff_error ffError = SVA_FIFO_OK; + t_sva_h264_dpb_error dpbError = SVA_DC_H264_DPB_OK; + + + /* use right dpbstart */ + ffError = READ_FIFO_ELEM(pDPBBlock->dpbStartFifo.inUse, t_sva_h264_dpb_desc, currentDpb); + if (ffError!= SVA_FIFO_OK) { + pDPBBlock->dpbError = SVA_DC_H264_DPB_LIST0_ERROR; + return SVA_DC_H264_DPB_FF_ERROR; + } + + + /* init */ + num_active_ref = pSlice->numRefIdxActiveOverrideFlag ? pSlice->numRefIdx10ActiveMinus1 + 1 + : PPSNumRefIdx10ActiveMinus1 + 1; + for(i=0; i < pDpb->size+1; i++) + { + pDpb->decodedBuffer[i].order = 1; + } + + j = 0; + + /* Short reference ordering */ + /* ------------------------ */ + do + { + status = 0; + index = -1; + val = H264_MIN_SINT_32; + + for (i=0; i < pDpb->size+1; i++) + { + if (pDpb->decodedBuffer[i].order && pDpb->decodedBuffer[i].markedShort) + if ((pDpb->decodedBuffer[i].picNum > val)) + { + val = pDpb->decodedBuffer[i].picNum; + index = (t_sint16)i; + } + } + + if (index > -1) + { + indexes[j] = index; + pList0[j++] = pDpb->decodedBuffer[index].bufferId; + pDpb->decodedBuffer[index].order = 0; + status = 1; + } + + } while (status && (j < pDpb->numShortRef) && (j < num_active_ref)); + + + /* Long reference ordering */ + /* ----------------------- */ + status = 1; + + while (status && (j < num_active_ref)) + { + status = 0; + val = pDpb->maxLongTermFrameIdx+1; + + for (i=0; i < pDpb->size+1; i++) + { + if (pDpb->decodedBuffer[i].order && pDpb->decodedBuffer[i].markedLong && (pDpb->decodedBuffer[i].longRefId < val)) + { + val = pDpb->decodedBuffer[i].longRefId; + index = (t_sint16)i; + } + } + + if (val < pDpb->maxLongTermFrameIdx+1) + { + indexes[j] = index; + pList0[j++] = pDpb->decodedBuffer[index].bufferId; + pDpb->decodedBuffer[index].order = 0; + status = 1; + } + } + + if (j == 0) + { + index = 0; + val = pDpb->decodedBuffer[0].picNum; + + for(i = 1; i < pDpb->size+1; i++) + { + pDpb->pCurDecodedInfo =&pDpb->decodedBuffer[pDpb->curDecodedIndex]; + + if ((pDpb->decodedBuffer[i].picNum > val) && (pDpb->decodedBuffer[i].frameNum != pDpb->pCurDecodedInfo->frameNum)) + { + val = pDpb->decodedBuffer[i].picNum; + index = (t_sint16)i; + } + } + + pList0[0] = pDpb->decodedBuffer[index].bufferId; + + //printf("WARNING: list0 is empty. Using last reference frame\n"); + + } + else if (j < num_active_ref) + { + t_uint16 k = (t_uint16)j; + + while (k < num_active_ref) + { + pList0[k] = NULL; + indexes[k] = -1; + k++; + } + + } + + + /* List0 reordering */ + /* ---------------- */ + if (pSlice->refPicListReorderingFlagl0 == 1) + { + t_uint16 cIdx, nIdx; + t_uint16 picNumPred = pSlice->frameNum; + + index = 0; + + while (pSlice->reorderingOfPicNumsIdc[index] != 3) + { + if (pSlice->reorderingOfPicNumsIdc[index] == 2) + { + dpbError = sva_DC_H264_DPB_FindLong((t_uint16)pDpb->size, pSlice->longTermPicNum[index], pDpb->decodedBuffer, &i); + if (dpbError != SVA_DC_H264_DPB_NO_MORE_LONG_REF) + { + for (cIdx = num_active_ref; cIdx > index; cIdx--) + { + pList0[cIdx] = pList0[cIdx-1]; + indexes[cIdx] = indexes[cIdx-1]; + } + + pList0[index] = pDpb->decodedBuffer[i].bufferId; + indexes[index] = (t_sint16)i; + + nIdx = index+1; + for (cIdx = index+1; cIdx <= num_active_ref; cIdx++) + if ((indexes[cIdx] != -1) && + (!pDpb->decodedBuffer[indexes[cIdx]].markedLong + || (pDpb->decodedBuffer[indexes[cIdx]].longRefId != pSlice->longTermPicNum[index]))) + { + pList0[nIdx] = pList0[cIdx]; + indexes[nIdx++] = indexes[cIdx]; + } + } + else + { + + pDPBBlock->dpbError = SVA_DC_H264_DPB_LIST0_ERROR; + return SVA_DC_H264_DPB_LIST0_ERROR; + + + } + } + else + { + t_sint32 picNumNoWrap, picNum; + + if (pSlice->reorderingOfPicNumsIdc[index] == 0) + { + if ((picNumPred - (pSlice->absDiffPicNumMinus1[index] + 1)) < 0) + picNumNoWrap = picNumPred - (pSlice->absDiffPicNumMinus1[index] + 1) + MaxFrameNum; + else + picNumNoWrap = picNumPred - (pSlice->absDiffPicNumMinus1[index] + 1); + } + else + { + if ((t_uint32)(picNumPred + (pSlice->absDiffPicNumMinus1[index] + 1)) >= MaxFrameNum) + picNumNoWrap = picNumPred + (pSlice->absDiffPicNumMinus1[index] + 1) - MaxFrameNum; + else + picNumNoWrap = picNumPred + (pSlice->absDiffPicNumMinus1[index] + 1); + } + + if (picNumNoWrap > pSlice->frameNum) + picNum = picNumNoWrap - MaxFrameNum; + else + picNum = picNumNoWrap; + + picNumPred = (t_uint16)picNumNoWrap; + + dpbError = sva_DC_H264_DPB_FindShort((t_uint16)pDpb->size, picNum, pDpb->decodedBuffer, &i); + if (dpbError != SVA_DC_H264_DPB_NO_MORE_SHORT_REF) + { + for (cIdx = num_active_ref; cIdx > index; cIdx--) + { + pList0[cIdx] = pList0[cIdx-1]; + indexes[cIdx] = indexes[cIdx-1]; + } + + pList0[index] = pDpb->decodedBuffer[i].bufferId; + indexes[index] = (t_sint16)i; + + nIdx = index+1; + for (cIdx = index+1; cIdx <= num_active_ref; cIdx++) + if ((indexes[cIdx] != -1) && + (pDpb->decodedBuffer[indexes[cIdx]].markedLong || (pDpb->decodedBuffer[indexes[cIdx]].picNum != picNum))) + { + pList0[nIdx] = pList0[cIdx]; + indexes[nIdx++] = indexes[cIdx]; + } + } + else + { + + pDPBBlock->dpbError = SVA_DC_H264_DPB_LIST0_ERROR; + return SVA_DC_H264_DPB_LIST0_ERROR; + + } + } + + index++; + } + + } + + num_active_ref = pSlice->numRefIdxActiveOverrideFlag ? pSlice->numRefIdx10ActiveMinus1 + 1 + : PPSNumRefIdx10ActiveMinus1 + 1; + + + + + } + else /* the slice is not a P slice */ + { + dpbError = SVA_DC_H264_DPB_NO_LIST0; + + } + + + return dpbError; + +} + +/* private implementation */ + +/****************************************************************************/ +/* NAME: t_sva_h264_dpb_error sva_DC_H264_isPSlice */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* PARAMETERS: */ +/* IN : */ +/* OUT : */ +/* */ +/* RETURN: */ +/* t_sva_h264_dpb_error */ +/****************************************************************************/ +PRIVATE t_bool sva_DC_H264_isPSlice(const t_sva_h264_dpb_params_slice * pSlice) +{ + if((pSlice->sliceType == 0)||(pSlice->sliceType == 5)) + return TRUE; + else + return FALSE; +} + + +/****************************************************************************/ +/* NAME: t_sva_h264_dpb_error sva_DC_H264_DPB_InitDPB */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* PARAMETERS: */ +/* IN : */ +/* OUT : */ +/* */ +/* RETURN: */ +/* t_sva_h264_dpb_error */ +/****************************************************************************/ +PRIVATE t_sva_h264_dpb_error sva_DC_H264_DPB_InitDPB(t_sva_service_instance_num instanceNum, t_sva_h264_dpb_desc * pDpb) +{ + + t_sva_h264_dpb_error dpbError = SVA_DC_H264_DPB_OK; + t_sva_h264_dpb_block_desc * pDPBBlock = &DPBDesc[instanceNum]; + t_uint16 i; + + + pDpb->size = pDPBBlock->dpbSize; + + + + for (i=0; i < pDpb->size+1; i++) + { + + pDpb->decodedBuffer[i].bufferId = INVALID_BUFFER_ID; + pDpb->decodedBuffer[i].markedShort = FALSE; + pDpb->decodedBuffer[i].markedLong = FALSE; + pDpb->decodedBuffer[i].needDisplay = FALSE; + pDpb->decodedBuffer[i].picNum = H264_MIN_SINT_32; + } + + //storeBufferId=FALSE; + pDpb->fullness = 0; + pDpb->maxLongTermFrameIdx = -1; + pDpb->numShortRef = 0; + pDpb->numLongRef = 0; + pDpb->initialized = TRUE; + + + pDPBBlock->first=FALSE; + + + + return dpbError; +} + +/****************************************************************************/ +/* NAME: t_sva_h264_dpb_error sva_DC_H264_DPB_DecodePOC */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* PARAMETERS: */ +/* IN : */ +/* OUT : */ +/* */ +/* RETURN: */ +/* t_sva_h264_dpb_error */ +/****************************************************************************/ +PRIVATE t_sva_h264_dpb_error sva_DC_H264_DPB_DecodePOC( + t_sva_h264_dpb_sps_utils * p_sps, + t_sva_h264_dpb_slice0_utils * p_slice0, + t_sva_h264_dpb_poc * p_poc, + t_sint32 * pRetPoc ) +{ + t_sva_h264_dpb_error dpbError = SVA_DC_H264_DPB_OK; + t_uint16 i; + t_uint32 MaxPicOrderCntLsb, AbsFrameNum, FrameNumInPicOrderCntCycle, PicOrderCntCycleCnt; + + t_sint32 poc, toppoc, bottompoc, PicOrderCntMsb, ExpectedDeltaPerPicOrderCntCycle, ExpectedPicOrderCnt; + + poc = 0; //For removing compiler warning + switch (p_sps->picOrderCntType) + { + case 0: + MaxPicOrderCntLsb = (1 << (p_sps->log2MaxPicOrderCntLsbMinus4 + 4)); + + if( p_slice0->picOrderCntLsb < p_poc->prevPicOrderCntLsb && + ( p_poc->prevPicOrderCntLsb - p_slice0->picOrderCntLsb ) >= (t_uint16)( MaxPicOrderCntLsb >> 1 ) ) + PicOrderCntMsb = p_poc->prevPicOrderCntMsb + MaxPicOrderCntLsb; + else if ( p_slice0->picOrderCntLsb > p_poc->prevPicOrderCntLsb && + ( p_slice0->picOrderCntLsb - p_poc->prevPicOrderCntLsb ) > (t_uint16)( MaxPicOrderCntLsb >> 1 ) ) + PicOrderCntMsb = p_poc->prevPicOrderCntMsb - MaxPicOrderCntLsb; + else + PicOrderCntMsb = p_poc->prevPicOrderCntMsb; + + toppoc = PicOrderCntMsb + p_slice0->picOrderCntLsb; + bottompoc = toppoc + p_slice0->deltaPicOrderCntBottom; + + poc = H264MIN(toppoc, bottompoc); + + if (p_slice0->nri != 0) + { + p_poc->prevPicOrderCntLsb = p_slice0->picOrderCntLsb; + p_poc->prevPicOrderCntMsb = PicOrderCntMsb; + } + break; + + case 1: + if (p_poc->previousFrameNum > p_slice0->frameNum) + p_poc->frameNumOffset += (1 << (p_sps->log2MaxFrameNumMinus4 + 4)); + + if(p_sps->numRefFramesInPicOrderCntCycle) + AbsFrameNum = p_poc->frameNumOffset + p_slice0->frameNum; + else + AbsFrameNum = 0; + + if((p_slice0->nri == 0) && (AbsFrameNum > 0)) + AbsFrameNum--; + + ExpectedDeltaPerPicOrderCntCycle = 0; + + if(p_sps->numRefFramesInPicOrderCntCycle) + for(i = 0; i < p_sps->numRefFramesInPicOrderCntCycle; i++) + ExpectedDeltaPerPicOrderCntCycle += p_sps->offsetForRefFrame[i]; + + if(AbsFrameNum) + { + PicOrderCntCycleCnt = (AbsFrameNum - 1) / p_sps->numRefFramesInPicOrderCntCycle; + FrameNumInPicOrderCntCycle = (AbsFrameNum - 1) % p_sps->numRefFramesInPicOrderCntCycle; + ExpectedPicOrderCnt = PicOrderCntCycleCnt * ExpectedDeltaPerPicOrderCntCycle; + + for(i = 0; i <= FrameNumInPicOrderCntCycle; i++) + ExpectedPicOrderCnt += p_sps->offsetForRefFrame[i]; + } + else + ExpectedPicOrderCnt = 0; + + if(p_slice0->nri == 0) + ExpectedPicOrderCnt += p_sps->offsetForNonRefPic; + + toppoc = ExpectedPicOrderCnt + p_slice0->deltaPicOrderCnt[0]; + bottompoc = toppoc + p_sps->offsetForTopToBottomField + p_slice0->deltaPicOrderCnt[1]; + + poc = (toppoc < bottompoc) ? toppoc : bottompoc; + break; + + case 2: + if (p_poc->previousFrameNum > p_slice0->frameNum) + p_poc->frameNumOffset += (1 << (p_sps->log2MaxFrameNumMinus4 + 4)); + + if (p_slice0->nut == 5) + poc = 0; + else if (p_slice0->nri == 0) + poc = 2 * (p_poc->frameNumOffset + p_slice0->frameNum) - 1; + else + poc = 2 * (p_poc->frameNumOffset + p_slice0->frameNum); + break; + + default: + break; + } + + *pRetPoc = poc; + return dpbError; +} + +/****************************************************************************/ +/* NAME: t_sva_h264_dpb_error sva_DC_H264_DPB_FlushDPB */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* PARAMETERS: */ +/* IN : */ +/* OUT : */ +/* */ +/* RETURN: */ +/* t_sva_h264_dpb_error */ +/****************************************************************************/ +PRIVATE t_sva_h264_dpb_error sva_DC_H264_DPB_FlushDPB(t_sva_service_instance_num instanceNum, t_sva_h264_dpb_desc *pDpb, t_uint16 idx) +{ + t_sva_h264_dpb_error dpbError = SVA_DC_H264_DPB_OK; + t_sva_h264_dpb_block_desc * pDPBBlock = &DPBDesc[instanceNum]; + t_uint16 i; + t_uint32 index; + //t_sva_dpb_buffer_id dpbBufferId; //For removing compiler warning + + pDpb->size = pDPBBlock->dpbSize; + + /* Mark all frames as unused for reference */ + for (i=0; i < pDpb->size+1; i++) + { + pDpb->decodedBuffer[i].markedShort = FALSE; + pDpb->decodedBuffer[i].markedLong = FALSE; + } + + pDpb->numShortRef = 0; + pDpb->numLongRef = 0; + pDpb->maxLongTermFrameIdx = -1; + + /* Output frames in POC order */ + while (dpbError != SVA_DC_H264_DPB_BUMPING_ENDED) + { + dpbError = sva_DC_H264_DPB_BumpFrame(instanceNum, pDpb, &index); + if((dpbError != SVA_DC_H264_DPB_OK)&&(dpbError !=SVA_DC_H264_DPB_BUMPING_ENDED)) + { + pDPBBlock->dpbError = dpbError; + return dpbError; + } + } + /* nbElems = GET_FIFO_NB_ELEMS(pDPBBlock->bufferIdToBeRemovedFromDPBFifo); + + for(j=0; jbufferIdToBeRemovedFromDPBFifo, t_sva_dpb_buffer_id, dpbBufferId); + + PUSH_FIFO_ELEM(pDPBBlock->sendBufferFilledFifo , t_sva_dpb_buffer_id, dpbBufferId); + + pDpb->fullness--; + + dpbBufferId.bufferId = INVALID_BUFFER_ID; + + + } +*/ + + /*for test*/ + + if(idx != 256) pDpb->decodedBuffer[idx].needDisplay = TRUE; + + do + { + dpbError = sva_DC_H264_DPB_RemoveUnusedFrame(instanceNum,pDpb); + if((dpbError != SVA_DC_H264_DPB_ONE_FRAME_REMOVED)&&(dpbError!=SVA_DC_H264_DPB_OK)) return dpbError; + + }while (dpbError == SVA_DC_H264_DPB_ONE_FRAME_REMOVED); + + + + + /* also flush lastDpbFifo */ + FLUSH_FIFO(pDPBBlock->lastDpbFifo); + + dpbError = SVA_DC_H264_DPB_OK; + + return dpbError; +} + +/****************************************************************************/ +/* NAME: t_sva_h264_dpb_error sva_DC_H264_DPB_RemoveOneUnused */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* PARAMETERS: */ +/* IN : */ +/* OUT : */ +/* */ +/* RETURN: */ +/* t_sva_h264_dpb_error */ +/****************************************************************************/ +PRIVATE t_sva_h264_dpb_error sva_DC_H264_DPB_RemoveOneUnused(t_sva_service_instance_num instanceNum, t_uint16 pos, t_sva_h264_dpb_desc *pDpb) +{ + + t_sva_h264_dpb_error dpbError = SVA_DC_H264_DPB_OK; + t_sva_h264_dpb_block_desc * pDPBBlock = &DPBDesc[instanceNum]; + t_sva_ff_error ffError=SVA_FIFO_OK; + t_bool tobedisplayed = FALSE; + t_uint32 j; + t_uint32 nbElems; + t_sva_dpb_buffer_id dpbBufferId; + dpbBufferId.bufferId = INVALID_BUFFER_ID; + +/* implicit: bufferId != INVALID_BUFFER_ID and unsused for ref: need_display=0, marked_short=0;marked_long=0*/ + + + + /* look for bufferId in bufferIdToBeOutputedFifo */ + nbElems = GET_FIFO_NB_ELEMS(pDPBBlock->bufferIdToBeRemovedFromDPBFifo); + + for(j=0; jbufferIdToBeRemovedFromDPBFifo, t_sva_dpb_buffer_id, dpbBufferId); + if(dpbBufferId.bufferId == pDpb->decodedBuffer[pos].bufferId) + { + tobedisplayed = TRUE; + } + else + { + PUSH_FIFO_ELEM(pDPBBlock->bufferIdToBeRemovedFromDPBFifo, t_sva_dpb_buffer_id, dpbBufferId); + } + + + } + + + /* if this bufferId is in the bufferIdToBeOutputedFifo then do this: */ + if(tobedisplayed == TRUE) + { + dpbBufferId.bufferId = pDpb->decodedBuffer[pos].bufferId; + dpbBufferId.dpbIndex = pos; + ffError=PUSH_FIFO_ELEM(pDPBBlock->sendBufferFilledFifo, t_sva_dpb_buffer_id, dpbBufferId); + if(ffError!= SVA_FIFO_OK) { + pDPBBlock->dpbError = SVA_DC_H264_DPB_REMOVE_UNUSED_KO; + return SVA_DC_H264_DPB_INTERNAL_FIFOS_FULL; + } + + } + /* else simply push again the bufferId in the tobepushedindpbfifo */ + else + { + + + dpbBufferId.bufferId= pDpb->decodedBuffer[pos].bufferId; + dpbBufferId.dpbIndex = pos; + ffError=PUSH_FIFO_ELEM(pDPBBlock->bufferIdToBePushedInDpbFifo, t_sva_dpb_buffer_id, dpbBufferId); + if(ffError!= SVA_FIFO_OK) { + pDPBBlock->dpbError = SVA_DC_H264_DPB_REMOVE_UNUSED_KO; + return SVA_DC_H264_DPB_INTERNAL_FIFOS_FULL; + } + + } + + + pDpb->decodedBuffer[pos].bufferId = INVALID_BUFFER_ID; + + pDpb->fullness--; + /* + dpbError = sva_DC_H264_DPB_FillBufferFilledFifo(instanceNum); + if(dpbError != SVA_DC_H264_DPB_OK) + { + pDPBBlock->dpbError = SVA_DC_H264_DPB_BUMP_ERROR; + return SVA_DC_H264_DPB_BUFER_FILLED_ERROR; + } + */ + + + + return dpbError; +} + +/****************************************************************************/ +/* NAME: t_sva_h264_dpb_error sva_DC_H264_DPB_CheckBufferId */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* PARAMETERS: */ +/* IN : */ +/* OUT : */ +/* */ +/* RETURN: */ +/* t_sva_h264_dpb_error */ +/****************************************************************************/ +PRIVATE t_sva_h264_dpb_error sva_DC_H264_DPB_CheckBufferId(t_sva_service_instance_num instanceNum, t_sva_h264_dpb_desc *pDpb, t_uint32 index) +{ + t_sva_h264_dpb_block_desc * pDPBBlock = &DPBDesc[instanceNum]; + t_sva_dpb_buffer_id replacementBufferId;// bufferId; + t_sva_bm_error bmError = SVA_BM_OK; + + + + /*for test */ + /* + if (pDpb->decodedBuffer[index].bufferId != INVALID_BUFFER_ID) + sva_DC_H264_DPB_RemoveOneUnused(instanceNum,index,pDpb); + */ + /**/ + + if (pDpb->decodedBuffer[index].bufferId == INVALID_BUFFER_ID) + { + if(POP_FIFO_ELEM(pDPBBlock->bufferIdToBePushedInDpbFifo, t_sva_dpb_buffer_id, replacementBufferId)!=SVA_OK) + { + pDPBBlock->dpbError = SVA_DC_H264_DPB_MISSING_BUFFERS_IN_DPB; + return SVA_DC_H264_DPB_MISSING_BUFFERS_IN_DPB; + } + + pDpb->decodedBuffer[index].bufferId = replacementBufferId.bufferId; + bmError = sva_BM_GetBufferSystemAddress(replacementBufferId.bufferId,&pDpb->decodedBuffer[index].address); + if(bmError != SVA_BM_OK) + { + pDPBBlock->dpbError = SVA_DC_H264_DPB_MISSING_BUFFERS_IN_DPB; + return SVA_DC_H264_DPB_MISSING_BUFFERS_IN_DPB; + } + } + + return SVA_DC_H264_DPB_OK; + +} + +//Currently not used +//For removing compiler warning +#if 0 +/****************************************************************************/ +/* NAME: t_sva_h264_dpb_error sva_DC_H264_DPB_FillBufferFilledFifo */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* PARAMETERS: */ +/* IN : */ +/* OUT : */ +/* */ +/* RETURN: */ +/* t_sva_h264_dpb_error */ +/****************************************************************************/ +PRIVATE t_sva_h264_dpb_error sva_DC_H264_DPB_FillBufferFilledFifo( + t_sva_service_instance_num instanceNum) +{ + + + t_sva_h264_dpb_block_desc * pDPBBlock = &DPBDesc[instanceNum]; + t_sva_ff_error ffError=SVA_FIFO_OK; + t_bool tobesentasbufferfilled=FALSE; + t_sva_dpb_buffer_id dpbBufferId; + t_sva_dpb_buffer_id firstbuffIdToBeOutputed,lastfirstbuffIdToBeOutputed; + t_uint32 nbElems; + t_uint16 j; + + dpbBufferId.bufferId = INVALID_BUFFER_ID; + firstbuffIdToBeOutputed.bufferId = INVALID_BUFFER_ID; + lastfirstbuffIdToBeOutputed.bufferId = INVALID_BUFFER_ID; + + while(!IS_FIFO_EMPTY(pDPBBlock->bufferIdToBeOutputedFifo)) + { + /* read first elem to be outputed */ + READ_FIFO_ELEM(pDPBBlock->bufferIdToBeOutputedFifo, t_sva_dpb_buffer_id, firstbuffIdToBeOutputed); + + if(firstbuffIdToBeOutputed.bufferId!=lastfirstbuffIdToBeOutputed.bufferId) + { + + tobesentasbufferfilled = FALSE; + + lastfirstbuffIdToBeOutputed.bufferId = firstbuffIdToBeOutputed.bufferId; + + /* look into toberemovedfromDPBFifo the buffId that corresponds to the first of tobeoutputedfifo */ + nbElems = GET_FIFO_NB_ELEMS(pDPBBlock->bufferIdToBeRemovedFromDPBFifo); + for(j=0; jbufferIdToBeRemovedFromDPBFifo, t_sva_dpb_buffer_id, dpbBufferId); + if(dpbBufferId.bufferId != firstbuffIdToBeOutputed.bufferId) + PUSH_FIFO_ELEM(pDPBBlock->bufferIdToBeRemovedFromDPBFifo, t_sva_dpb_buffer_id, dpbBufferId); + else + tobesentasbufferfilled = TRUE; + } + if(tobesentasbufferfilled) + { + + POP_FIFO_ELEM(pDPBBlock->bufferIdToBeOutputedFifo, t_sva_dpb_buffer_id, firstbuffIdToBeOutputed); + + ffError = PUSH_FIFO_ELEM(pDPBBlock->sendBufferFilledFifo, t_sva_dpb_buffer_id, firstbuffIdToBeOutputed); + if (ffError != SVA_FIFO_OK) + { + pDPBBlock->dpbError = SVA_DC_H264_DPB_BUFER_FILLED_ERROR; + return SVA_DC_H264_DPB_INTERNAL_FIFOS_FULL; + } + + } + } + else + break; + + } + return SVA_DC_H264_DPB_OK; + + +} +#endif + +/****************************************************************************/ +/* NAME: t_sva_h264_dpb_error sva_DC_H264_DPB_BumpFrame */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* PARAMETERS: */ +/* IN : */ +/* OUT : */ +/* */ +/* RETURN: */ +/* t_sva_h264_dpb_error */ +/****************************************************************************/ +PRIVATE t_sva_h264_dpb_error sva_DC_H264_DPB_BumpFrame(t_sva_service_instance_num instanceNum, t_sva_h264_dpb_desc *pDpb, t_uint32* pIndex) +{ + t_sva_h264_dpb_error dpbError = SVA_DC_H264_DPB_OK; + t_sva_h264_dpb_block_desc * pDPBBlock = &DPBDesc[instanceNum]; + t_sint32 poc = H264_MAX_SINT_32; + t_uint16 i; + t_sint16 pos = -1; + t_sva_ff_error ffError=SVA_FIFO_OK; + t_sva_dpb_buffer_id dpbBufferId; + + /* Find smallest POC in the DPB */ + for (i=0; i < pDpb->size+1; i++) + { + if ((pDpb->decodedBuffer[i].needDisplay) && (poc > pDpb->decodedBuffer[i].poc)) + { + poc = pDpb->decodedBuffer[i].poc; + pos = i; + } + } + if (pos < 0) + return SVA_DC_H264_DPB_BUMPING_ENDED; + + pDpb->decodedBuffer[pos].needDisplay = FALSE; + + /* put this bufferId in a fifo bufferIdToBeOutputedFifo */ + dpbBufferId.bufferId = pDpb->decodedBuffer[pos].bufferId; + dpbBufferId.dpbIndex = pos; + + + + if ((!pDpb->decodedBuffer[pos].markedShort) && (!pDpb->decodedBuffer[pos].markedLong)) + { + + /* Output selected frame */ + dpbBufferId.bufferId = pDpb->decodedBuffer[pos].bufferId; + ffError=PUSH_FIFO_ELEM(pDPBBlock->sendBufferFilledFifo, t_sva_dpb_buffer_id, dpbBufferId); + if(ffError!= SVA_FIFO_OK) { + pDPBBlock->dpbError = SVA_DC_H264_DPB_BUMP_ERROR; + return SVA_DC_H264_DPB_INTERNAL_FIFOS_FULL; + } + + pDpb->decodedBuffer[pos].bufferId = INVALID_BUFFER_ID; + + pDpb->fullness--; + /* + dpbError = sva_DC_H264_DPB_FillBufferFilledFifo(instanceNum); + if(dpbError != SVA_DC_H264_DPB_OK) + { + pDPBBlock->dpbError = SVA_DC_H264_DPB_BUMP_ERROR; + return SVA_DC_H264_DPB_BUFER_FILLED_ERROR; + }*/ + + } + else + { + + ffError=PUSH_FIFO_ELEM(pDPBBlock->bufferIdToBeRemovedFromDPBFifo, t_sva_dpb_buffer_id, dpbBufferId); + if(ffError!= SVA_FIFO_OK) { + pDPBBlock->dpbError = SVA_DC_H264_DPB_BUMP_ERROR; + return SVA_DC_H264_DPB_INTERNAL_FIFOS_FULL; + } + + + + } + + *pIndex = pos; + + return dpbError; +} + + + + + + +/****************************************************************************/ +/* NAME: t_sva_h264_dpb_error sva_DC_H264_DPB_RemoveUnusedFrame */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* PARAMETERS: */ +/* IN : */ +/* OUT : */ +/* */ +/* RETURN: */ +/* t_sva_h264_dpb_error */ +/****************************************************************************/ +PRIVATE t_sva_h264_dpb_error sva_DC_H264_DPB_RemoveUnusedFrame(t_sva_service_instance_num instanceNum, t_sva_h264_dpb_desc *pDpb) +{ + t_sva_h264_dpb_error dpbError = SVA_DC_H264_DPB_OK; + t_sva_h264_dpb_block_desc * pDPBBlock = &DPBDesc[instanceNum]; + t_sva_ff_error ffError=SVA_FIFO_OK; + t_uint16 i; + t_sva_dpb_buffer_id dpbBufferId; + dpbBufferId.bufferId = INVALID_BUFFER_ID; + + + /* Remove frames that were already output and are no longer marked as used for reference */ + for (i=0; i < pDpb->size+1; i++) + { + if ((!pDpb->decodedBuffer[i].needDisplay) && (!pDpb->decodedBuffer[i].markedShort) && (!pDpb->decodedBuffer[i].markedLong)) + { + + t_bool tobedisplayed = FALSE; + t_uint32 j; + + /* look for bufferId in bufferIdToBeOutputedFifo */ + t_uint32 nbElems = GET_FIFO_NB_ELEMS(pDPBBlock->bufferIdToBeRemovedFromDPBFifo); + + for(j=0; jbufferIdToBeRemovedFromDPBFifo, t_sva_dpb_buffer_id, dpbBufferId); + if(dpbBufferId.bufferId == pDpb->decodedBuffer[i].bufferId) + { + tobedisplayed = TRUE; + + } + else + { + PUSH_FIFO_ELEM(pDPBBlock->bufferIdToBeRemovedFromDPBFifo, t_sva_dpb_buffer_id, dpbBufferId); + } + + + } + + + /* if this bufferId is in the bufferIdToBeOutputedFifo then do this: */ + if(tobedisplayed == TRUE) + { + dpbBufferId.bufferId = pDpb->decodedBuffer[i].bufferId; + dpbBufferId.dpbIndex = i; + ffError=PUSH_FIFO_ELEM(pDPBBlock->sendBufferFilledFifo, t_sva_dpb_buffer_id, dpbBufferId); + + if(ffError!= SVA_FIFO_OK) { + pDPBBlock->dpbError = SVA_DC_H264_DPB_REMOVE_UNUSED_KO; + return SVA_DC_H264_DPB_INTERNAL_FIFOS_FULL; + } + pDpb->fullness--; + pDpb->decodedBuffer[i].bufferId = INVALID_BUFFER_ID; + + + + } + /* else simply push again the bufferId in the tobepushedindpbfifo */ + else if (pDpb->decodedBuffer[i].bufferId != INVALID_BUFFER_ID) + { + + + dpbBufferId.bufferId= pDpb->decodedBuffer[i].bufferId; + dpbBufferId.dpbIndex = i; + ffError=PUSH_FIFO_ELEM(pDPBBlock->bufferIdToBePushedInDpbFifo, t_sva_dpb_buffer_id, dpbBufferId); + if(ffError!= SVA_FIFO_OK) { + pDPBBlock->dpbError = SVA_DC_H264_DPB_REMOVE_UNUSED_KO; + return SVA_DC_H264_DPB_INTERNAL_FIFOS_FULL; + } + + pDpb->decodedBuffer[i].bufferId = INVALID_BUFFER_ID; + pDpb->fullness--; + + + } + // + + if((tobedisplayed == TRUE)||(pDpb->decodedBuffer[i].bufferId != INVALID_BUFFER_ID)) + { + pDpb->decodedBuffer[i].bufferId = INVALID_BUFFER_ID; + // pDpb->fullness--; + + /* + dpbError = sva_DC_H264_DPB_FillBufferFilledFifo(instanceNum); + if(dpbError != SVA_DC_H264_DPB_OK) + { + pDPBBlock->dpbError = SVA_DC_H264_DPB_BUMP_ERROR; + return SVA_DC_H264_DPB_BUFER_FILLED_ERROR; + } + */ + return SVA_DC_H264_DPB_ONE_FRAME_REMOVED; + } + } + } + + return dpbError; +} + + + +/****************************************************************************/ +/* NAME: t_sva_h264_dpb_error sva_DC_H264_DPB_ConcealGaps */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* PARAMETERS: */ +/* IN : */ +/* OUT : */ +/* */ +/* RETURN: */ +/* t_sva_h264_dpb_error */ +/****************************************************************************/ + +PRIVATE t_sva_h264_dpb_error sva_DC_H264_DPB_ConcealNewFrame( + t_uint8 instanceNum, + t_uint16 prevNum, + t_uint32 pos, + t_sva_h264_dpb_sps_utils * p_sps, + t_sva_h264_dpb_desc* pDpb) +{ + t_sva_h264_dpb_error dpbError = SVA_DC_H264_DPB_OK; + t_sva_bm_error bmError = SVA_BM_OK; + t_sint32 poc = H264_MIN_SINT_32; + t_sint16 index; + t_uint16 i; + t_sva_h264_dpb_decoded_buffer_info *p_dpi; + t_uint8 * pSource, *pDest; +t_sva_dpb_buffer_id replacementBufferId;// bufferId; +t_sva_h264_dpb_block_desc * pDPBBlock = &DPBDesc[instanceNum]; + + t_uint32 size = ((p_sps->picWidthInMbsMinus1+1) * (p_sps->picHeightInMapUnitsMinus1+1)) << 8; + + index = -1; + for (i = 0; i < pDpb->size+1; i++) + { + if (((pDpb->decodedBuffer[i].markedShort) || (pDpb->decodedBuffer[i].markedLong)) && (pDpb->decodedBuffer[i].poc > poc)) + { + poc = pDpb->decodedBuffer[i].poc; + index = i; + } + } + + if (index == -1) + { + return SVA_DC_H264_DPB_UNABLE_TO_CONCEAL_FRAME; + } + /*************************************************/ + + + if (pDpb->decodedBuffer[pos].bufferId == INVALID_BUFFER_ID) + { + if(POP_FIFO_ELEM(pDPBBlock->bufferIdToBePushedInDpbFifo, t_sva_dpb_buffer_id, replacementBufferId)!=SVA_OK) + { + pDPBBlock->dpbError = SVA_DC_H264_DPB_MISSING_BUFFERS_IN_DPB; + return SVA_DC_H264_DPB_MISSING_BUFFERS_IN_DPB; + } + + pDpb->decodedBuffer[pos].bufferId = replacementBufferId.bufferId; + bmError = sva_BM_GetBufferSystemAddress(replacementBufferId.bufferId,&pDpb->decodedBuffer[pos].address); + if(bmError != SVA_BM_OK) + { + pDPBBlock->dpbError = SVA_DC_H264_DPB_MISSING_BUFFERS_IN_DPB; + return SVA_DC_H264_DPB_MISSING_BUFFERS_IN_DPB; + } + } + + + // Set frame infos + p_dpi = &pDpb->decodedBuffer[pos]; + + + // copy frame + pSource = (t_uint8*)pDpb->decodedBuffer[index].address.logical; + pDest = (t_uint8*)pDpb->decodedBuffer[pos].address.logical; + for(i=0; i<(3*size)/2; i++) + { + pDest[i] = pSource[i]; + } + + // Initialize frame infos + p_dpi->frameNum = prevNum; + p_dpi->frameNumWrap = p_dpi->picNum = p_dpi->frameNum; + p_dpi->markedShort = TRUE; + p_dpi->markedLong = FALSE; + p_dpi->needDisplay = TRUE; + p_dpi->poc = poc + 1; + + pDpb->numShortRef++; + pDpb->fullness++; + + + return dpbError; +} +//sva_DC_H264_DPB_ConcealGetAllImageBuffer : Get all image buffers b4r concealment algo. +//not all i/p params required //remove unused paramters +PRIVATE t_sva_h264_dpb_error sva_DC_H264_DPB_ConcealGetAllImageBuffer( + t_uint8 instanceNum, + t_uint32 missing) +{ + +t_sva_h264_dpb_block_desc * pDPBBlock = &DPBDesc[instanceNum]; + +if(GET_FIFO_NB_ELEMS(pDPBBlock->bufferIdToBePushedInDpbFifo)spsUtilsFifo.inUse,t_sva_h264_dpb_sps_utils,pDPBBlock->spsUtils); + PUSH_REVERSE_FIFO_ELEM(pDPBBlock->spsUtilsFifo.push,t_sva_h264_dpb_sps_utils,pDPBBlock->spsUtils); + + /* take slice0Utils */ + POP_REVERSE_FIFO_ELEM(pDPBBlock->slice0UtilsFifo.inUse,t_sva_h264_dpb_slice0_utils,pDPBBlock->slice0Utils); + PUSH_REVERSE_FIFO_ELEM(pDPBBlock->slice0UtilsFifo.push,t_sva_h264_dpb_slice0_utils,pDPBBlock->slice0Utils); + pDPBBlock->dpbError = SVA_DC_H264_DPB_MISSING_BUFFERS_IN_DPB; + return SVA_DC_H264_DPB_MISSING_BUFFERS_IN_DPB; +} +return SVA_DC_H264_DPB_OK; +} + +/****************************************************************************/ +/* NAME: t_sva_h264_dpb_error sva_DC_H264_DPB_GetBufferIdForNewFrame */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* PARAMETERS: */ +/* IN : */ +/* OUT : */ +/* */ +/* RETURN: */ +/* t_sva_h264_dpb_error */ +/****************************************************************************/ +PRIVATE t_sva_h264_dpb_error sva_DC_H264_DPB_GetIndexForNewFrame(t_sva_service_instance_num instanceNum, t_uint16 frameNum, t_uint32 maxFrameNum, t_sva_h264_dpb_sps_utils * p_sps, t_sva_h264_dpb_desc* pDpb, t_uint32* pIndex) +{ + t_sva_h264_dpb_error dpbError = SVA_DC_H264_DPB_OK; + t_uint16 i = 0; + t_uint32 index, temp; + + /* Update frame_num_wrap if necessary */ + for(i=0; i < pDpb->size+1; i++) + { + if (pDpb->decodedBuffer[i].markedShort) + { + if (pDpb->decodedBuffer[i].frameNum > frameNum) + pDpb->decodedBuffer[i].frameNumWrap = pDpb->decodedBuffer[i].frameNum - maxFrameNum; + else + pDpb->decodedBuffer[i].frameNumWrap = pDpb->decodedBuffer[i].frameNum; + + pDpb->decodedBuffer[i].picNum = pDpb->decodedBuffer[i].frameNumWrap; + } + } + + index = INVALID_BUFFER_ID; + + if ((pDpb->numLongRef + pDpb->numShortRef) == (p_sps->numRefFrames+1)) /* Sliding window */ + { + /* Find smaller short ref id and mark as unused for short ref*/ + for (i = 0; i < pDpb->size+1; i++) + { + if (pDpb->decodedBuffer[i].markedShort) + { + if (index == INVALID_BUFFER_ID) + { + index = i; + } + else if (pDpb->decodedBuffer[i].picNum < pDpb->decodedBuffer[index].picNum) + { + index = i; + } + } + } + + pDpb->decodedBuffer[index].markedShort = FALSE; + pDpb->numShortRef--; + } + + /* Check if DPB is full and try to remove unused frame */ +// if (pDpb->fullness == (pDpb->size+1)) + { + do + { + dpbError = sva_DC_H264_DPB_RemoveUnusedFrame(instanceNum, pDpb); + if((dpbError != SVA_DC_H264_DPB_ONE_FRAME_REMOVED)&&(dpbError!=SVA_DC_H264_DPB_OK)) return dpbError; + }while(dpbError==SVA_DC_H264_DPB_ONE_FRAME_REMOVED); + } + + /* Check if DPB is still full and apply bumping process */ + + while (pDpb->fullness == (pDpb->size+1)) + { + dpbError = sva_DC_H264_DPB_BumpFrame(instanceNum, pDpb, &temp); + if ( dpbError == SVA_DC_H264_DPB_BUMPING_ENDED) + break; + else if(dpbError != SVA_DC_H264_DPB_OK) + return dpbError; + } + + /* If at this point the DPB is still full there must be an error */ + if (pDpb->fullness == (pDpb->size+1)) + { + /* Try to perform again RemoveUnusedFrame */ + dpbError = sva_DC_H264_DPB_RemoveUnusedFrame(instanceNum, pDpb); + if((dpbError != SVA_DC_H264_DPB_ONE_FRAME_REMOVED)&&(dpbError!=SVA_DC_H264_DPB_OK)) return dpbError; + + + if (pDpb->fullness == (pDpb->size+1)) + { + /* Remove frame with lowest frame number */ + index = INVALID_BUFFER_ID; + + for (i = 0; i < pDpb->size+1; i++) + { + if (pDpb->decodedBuffer[i].markedShort) + { + if (index == INVALID_BUFFER_ID) + { + index = i; + } + else if (pDpb->decodedBuffer[i].picNum < pDpb->decodedBuffer[index].picNum) + { + index = i; + } + } + } + + pDpb->decodedBuffer[index].markedShort = FALSE; + pDpb->numShortRef--; + } + + if (pDpb->fullness == (pDpb->size+1)) + { + + + dpbError = sva_DC_H264_DPB_FlushDPB(instanceNum, pDpb,256); + if(dpbError != SVA_DC_H264_DPB_OK) return dpbError; + } + } + + /* Find a free position in the DPB */ + index= INVALID_BUFFER_ID; + i = 0; + do + { + if (!pDpb->decodedBuffer[i].needDisplay && !pDpb->decodedBuffer[i].markedShort && !pDpb->decodedBuffer[i].markedLong) + index = i; + + i++; + + } while ((i < pDpb->size+1) && (index == INVALID_BUFFER_ID)); + + /* Check for errors */ + if (index == INVALID_BUFFER_ID) + { + /* If we are here there are some frames that are not marked as used for reference but need display */ + + t_uint16 dpbFulness = pDpb->fullness; + // added by AA + while(dpbFulness == pDpb->fullness) + { + dpbError = sva_DC_H264_DPB_BumpFrame(instanceNum, pDpb, &index); + if((dpbError != SVA_DC_H264_DPB_OK)&&(dpbError!= SVA_DC_H264_DPB_BUMPING_ENDED)) return dpbError; + } + } + + // added by AA + if(pDpb->decodedBuffer[index].bufferId != INVALID_BUFFER_ID) + { + + dpbError = sva_DC_H264_DPB_RemoveOneUnused(instanceNum, (t_uint16)index,pDpb); + if(dpbError!=SVA_DC_H264_DPB_OK) return dpbError; + } + + + + *pIndex=index; + + return SVA_DC_H264_DPB_OK; +} + + + + +/****************************************************************************/ +/* NAME: t_sva_h264_dpb_error sva_DC_H264_DPB_FindShort */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: The function find a frame with */ +/* the selected short reference id in the DPB. */ +/* PARAMETERS: */ +/* IN : */ +/* OUT : */ +/* */ +/* RETURN: */ +/* t_sva_h264_dpb_error */ +/****************************************************************************/ +PRIVATE t_sva_h264_dpb_error sva_DC_H264_DPB_FindShort(t_uint16 size, t_sint32 shortId, t_sva_h264_dpb_decoded_buffer_info *decodedBuffer, t_uint32 *pIndex) +{ + t_uint16 i; + t_sva_h264_dpb_error dpbError = SVA_DC_H264_DPB_NO_MORE_SHORT_REF; + + for (i = 0; i < size+1; i++) + { + if (decodedBuffer[i].markedShort && (decodedBuffer[i].picNum == shortId)) + { + *pIndex= i; + dpbError = SVA_DC_H264_DPB_OK; + + } + } + + return dpbError; +} + + +/****************************************************************************/ +/* NAME: t_sva_h264_dpb_error sva_DC_H264_DPB_FindLong */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: The function find a frame with */ +/* the selected long reference id in the DPB. */ +/* PARAMETERS: */ +/* IN : */ +/* OUT : */ +/* */ +/* RETURN: */ +/* t_sva_h264_dpb_error */ +/****************************************************************************/ +PRIVATE t_sva_h264_dpb_error sva_DC_H264_DPB_FindLong(t_uint16 size, t_uint16 longId, t_sva_h264_dpb_decoded_buffer_info *decodedBuffer, t_uint32 *pIndex) +{ + t_uint16 i; + t_sva_h264_dpb_error dpbError =SVA_DC_H264_DPB_NO_MORE_LONG_REF; + + for (i = 0; i < size+1; i++) + { + if (decodedBuffer[i].markedLong && (decodedBuffer[i].longRefId == longId)) + { + *pIndex= i; + dpbError = SVA_DC_H264_DPB_OK; + } + + + } + + + return dpbError; +} + + +/****************************************************************************/ +/* NAME: t_sva_h264_dpb_error sva_DC_H264_DPB_MarkDecodedFrame */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* PARAMETERS: */ +/* IN : */ +/* OUT : */ +/* */ +/* RETURN: */ +/* t_sva_h264_dpb_error */ +/****************************************************************************/ +PRIVATE t_sva_h264_dpb_error sva_DC_H264_DPB_MarkDecodedFrame( + t_sva_service_instance_num instanceNum, + t_sva_h264_dpb_sps_utils * p_sps, + t_sva_h264_dpb_slice0_utils * p_slice0, + t_sva_h264_dpb_poc *p_poc, + t_sva_h264_dpb_desc *pDpb + ) +{ + t_sva_h264_dpb_error dpbError = SVA_DC_H264_DPB_OK; + + pDpb->pCurDecodedInfo = &pDpb->decodedBuffer[pDpb->curDecodedIndex]; + /* IDR picture */ + if (p_slice0->nut == 5) + { + if (p_slice0->longTermReferenceFlag == 0) + { + pDpb->pCurDecodedInfo->markedShort = TRUE; + pDpb->maxLongTermFrameIdx = -1; + pDpb->numShortRef++; + } + else + { + pDpb->pCurDecodedInfo->markedLong = TRUE; + pDpb->pCurDecodedInfo->longRefId = pDpb->maxLongTermFrameIdx = 0; + pDpb->numLongRef++; + } + + return dpbError; + } + + /* Non IDR picture */ + if (p_slice0->nri == 0) /* Picture unused for reference */ + return dpbError; + + if (p_slice0->adaptiveRefPicMarkingModeFlag == 0) /* Sliding window */ + { + pDpb->pCurDecodedInfo->markedShort = TRUE; + pDpb->numShortRef++; + return dpbError; + } + + + /* perform MMCO operations */ + dpbError = sva_DC_H264_DPB_PerformMMCOOperation( + instanceNum, + p_sps, + p_slice0, + p_poc, + pDpb); + + if(dpbError!= SVA_DC_H264_DPB_OK) return dpbError; + + + /* end mark picture */ + if (!pDpb->pCurDecodedInfo->markedLong) + { + pDpb->pCurDecodedInfo->markedShort = TRUE; + pDpb->numShortRef++; + } + + + return dpbError; +} + + +/****************************************************************************/ +/* NAME: t_sva_h264_dpb_error sva_DC_H264_DPB_PerformMMCOOperation */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* PARAMETERS: */ +/* IN : */ +/* OUT : */ +/* */ +/* RETURN: */ +/* t_sva_h264_dpb_error */ +/****************************************************************************/ +PRIVATE t_sva_h264_dpb_error sva_DC_H264_DPB_PerformMMCOOperation( + t_sva_service_instance_num instanceNum, + t_sva_h264_dpb_sps_utils * p_sps, + t_sva_h264_dpb_slice0_utils * p_slice0, + t_sva_h264_dpb_poc *p_poc, + t_sva_h264_dpb_desc *pDpb + ) +{ + + t_sva_h264_dpb_error dpbError = SVA_DC_H264_DPB_OK; + t_uint16 index = 0; + t_uint32 i; + + pDpb->pCurDecodedInfo = &pDpb->decodedBuffer[pDpb->curDecodedIndex]; + + + while (p_slice0->memoryManagementControlOperation[index] != 0) + { + switch (p_slice0->memoryManagementControlOperation[index]) + { + case SVA_DC_H264_DPB_UNMARK_SHORT_REF: + dpbError= sva_DC_H264_DPB_FindShort( + (t_uint16)pDpb->size, + p_slice0->frameNum - (p_slice0->differenceOfPicNumsMinus1[index] + 1), + pDpb->decodedBuffer, + &i); + if (dpbError != SVA_DC_H264_DPB_NO_MORE_SHORT_REF) + { + pDpb->decodedBuffer[i].markedShort = FALSE; + pDpb->numShortRef--; + dpbError = SVA_DC_H264_DPB_OK; + } + else + { + return SVA_DC_H264_DPB_MMCO_ERROR; + } + break; + + case SVA_DC_H264_DPB_UNMARK_LONG_REF: + dpbError = sva_DC_H264_DPB_FindLong( + (t_uint16)pDpb->size, + p_slice0->markingLongTermPicNum[index], + pDpb->decodedBuffer, + &i); + if (dpbError != SVA_DC_H264_DPB_NO_MORE_LONG_REF) + { + pDpb->decodedBuffer[i].markedLong = FALSE; + pDpb->numLongRef--; + dpbError = SVA_DC_H264_DPB_OK; + } + else + { + return SVA_DC_H264_DPB_MMCO_ERROR; + } + break; + + case SVA_DC_H264_DPB_ASSIGN_LONG_TO_SHORT: + dpbError = sva_DC_H264_DPB_FindLong( + (t_uint16)pDpb->size, + p_slice0->longTermFrameIdx[index], + pDpb->decodedBuffer, + &i); + if (dpbError != SVA_DC_H264_DPB_NO_MORE_LONG_REF) + { + pDpb->decodedBuffer[i].markedLong = FALSE; + pDpb->numLongRef--; + dpbError = SVA_DC_H264_DPB_OK; + } + + dpbError = sva_DC_H264_DPB_FindShort( + (t_uint16)pDpb->size, + p_slice0->frameNum - (p_slice0->differenceOfPicNumsMinus1[index] + 1), + pDpb->decodedBuffer, + &i); + if (dpbError != SVA_DC_H264_DPB_NO_MORE_SHORT_REF) + { + pDpb->decodedBuffer[i].markedShort = FALSE; + pDpb->decodedBuffer[i].markedLong = TRUE; + pDpb->decodedBuffer[i].longRefId = p_slice0->longTermFrameIdx[index]; + pDpb->numShortRef--; + pDpb->numLongRef++; + dpbError = SVA_DC_H264_DPB_OK; + } + else + { + return SVA_DC_H264_DPB_MMCO_ERROR; + } + break; + + case SVA_DC_H264_DPB_UNMARK_LONG_REF_GREATER: + for (i = 0; i < pDpb->size+1; i++) + { + if (pDpb->decodedBuffer[i].markedLong + && (pDpb->decodedBuffer[i].longRefId > (p_slice0->maxLongTermFrameIdxPlus1[index]-1))) + { + pDpb->decodedBuffer[i].markedLong = FALSE; + pDpb->numLongRef--; + } + } + + pDpb->maxLongTermFrameIdx = p_slice0->maxLongTermFrameIdxPlus1[index]-1; + break; + + case SVA_DC_H264_DPB_UNMARK_LONG: + pDpb->pCurDecodedInfo->needDisplay = FALSE; /* Don't display this picture yet */ + dpbError = sva_DC_H264_DPB_FlushDPB(instanceNum, pDpb,pDpb->curDecodedIndex); + if(dpbError!= SVA_DC_H264_DPB_OK) return dpbError; + //pDpb->pCurDecodedInfo->needDisplay = TRUE; + //pDpb->fullness++; /* Count this picture in the DPB */ + + pDpb->pCurDecodedInfo->frameNum = 0; + pDpb->pCurDecodedInfo->poc = 0; + p_poc->previousFrameNum = 0; + p_poc->prevPicOrderCntMsb = 0; + p_poc->prevPicOrderCntLsb = 0; /* p_buff->curr_info->poc; */ + p_poc->frameNumOffset = 0; + break; + + case SVA_DC_H264_DPB_ASSIGN_LONG_TO_CURRENT: + dpbError = sva_DC_H264_DPB_FindLong( + (t_uint16)pDpb->size, + p_slice0->longTermFrameIdx[index], + pDpb->decodedBuffer, + &i); + if (dpbError != SVA_DC_H264_DPB_NO_MORE_LONG_REF) + { + pDpb->decodedBuffer[i].markedLong = FALSE; + pDpb->numLongRef--; + dpbError = SVA_DC_H264_DPB_OK; + } + + pDpb->pCurDecodedInfo->markedLong = TRUE; + pDpb->pCurDecodedInfo->longRefId = p_slice0->longTermFrameIdx[index]; + pDpb->numLongRef++; + break; + + default: + break; + } + + index++; + } + + + return dpbError; +} + + +/****************************************************************************/ +/* NAME: t_sva_h264_dpb_error sva_DC_H264_DPB_GetDPBIndexForBufferId */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* PARAMETERS: */ +/* IN : */ +/* OUT : */ +/* */ +/* RETURN: */ +/* t_sva_h264_dpb_error */ +/****************************************************************************/ +/* +PRIVATE t_sva_h264_dpb_error sva_DC_H264_DPB_GetDPBIndexForBufferId(t_sva_h264_dpb_desc *pDpb, t_sva_buffer_id bufferId, t_uint16* pIndex) +{ + + t_sva_h264_dpb_error dpbError = SVA_DC_H264_DPB_OK; + t_uint8 i; + t_sint16 index=-1; + + + for(i=0; isize+1; i++) + { + if(pDpb->decodedBuffer[i].bufferId == bufferId) + { + index = i; + *pIndex = i; + break; + } + } + if((i==pDpb->size)&&(index==-1)) + { + *pIndex = pDpb->size+1; + dpbError=SVA_DC_H264_DPB_MISSING_BUFFERID; + } + + + return dpbError; +} +*/ + + +/****************************************************************************/ +/* NAME: t_sva_h264_dpb_error sva_DC_H264_DPB_SetBufferIdAtDPBIndex */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* PARAMETERS: */ +/* IN : */ +/* OUT : */ +/* */ +/* RETURN: */ +/* t_sva_h264_dpb_error */ +/****************************************************************************/ +/* +PRIVATE t_sva_h264_dpb_error sva_DC_H264_DPB_SetBufferIdAtDPBIndex(t_sva_h264_dpb_desc *pDpb, t_sva_buffer_id bufferId, t_uint16 index) +{ + t_sva_h264_dpb_error dpbError = SVA_DC_H264_DPB_OK; + + pDpb->decodedBuffer[index].bufferId = bufferId; + + return dpbError; +} +*/ + +/****************************************************************************/ +/* NAME: t_sva_h264_dpb_error sva_DC_H264_DPB_ResetDPBDesc */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* PARAMETERS: */ +/* IN : */ +/* OUT : */ +/* */ +/* RETURN: */ +/* t_sva_h264_dpb_error */ +/****************************************************************************/ +PRIVATE t_sva_h264_dpb_error sva_DC_H264_DPB_ResetDPBDesc(void) +{ + t_uint16 i=0; + + for(i=0; ispsUtils.picOrderCntType == 2) //for poc_type 2 only + { + ffError = PUSH_FIFO_ELEM(pDPBBlock->bufferIdToBeOutputedFifoRead, t_sva_buffer_id, bufferId); + HCL_ASSERT (ffError== SVA_FIFO_OK); + *isReadOnlyEvent = TRUE; + } + + return SVA_DC_H264_DPB_OK; +} + --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/h264/sva_dc_h264_dpb.h @@ -0,0 +1,232 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ + +#ifndef __INC_SVA_DC_H264_DPB_H +#define __INC_SVA_DC_H264_DPB_H + +#include "hcl_defs.h" +#include "sva_service.h" + + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + +#define SVA_DC_H264_DPB_UNUSED_BUFFER 0x80008000 +#define SVA_DC_H264_DPB_INSERTED_BUFFER 0x88008800 + +/* errors from DPB Management Block */ +typedef enum +{ + SVA_DC_H264_DPB_ERROR = SVA_DC_H264_LAST_ERROR, + + /* + */ + SVA_DC_H264_DPB_EXTERNAL_FIFOS_FULL, + SVA_DC_H264_DPB_ACTIVE_SPS_KO, + SVA_DC_H264_DPB_SLICE0_KO, + SVA_DC_H264_DPB_PUSH_KO, + SVA_DC_H264_DPB_INTERNAL_FIFOS_FULL, + SVA_DC_H264_DPB_INTERNAL_FIFOS_EMPTY, + SVA_DC_H264_DPB_START_FF_ERROR, + SVA_DC_H264_DPB_START_RESYNCH_NEW_FRAME, + SVA_DC_H264_DPB_START_DROP_NEW_FRAME, + SVA_DC_H264_DPB_END_FF_ERROR, + SVA_DC_H264_DPB_END_MARK_ERROR, + SVA_DC_H264_DPB_FLUSH_TO_BE_DISPLAYED_KO, + SVA_DC_H264_DPB_FLUSH_FIFOS_KO, + SVA_DC_H264_DPB_GET_STATES_KO, + SVA_DC_H264_DPB_RESET_STATES_KO, + SVA_DC_H264_DPB_CONCEALMENT_KO, + SVA_DC_H264_DPB_FLUSHDPB_ERROR, + SVA_DC_H264_DPB_BUMP_ERROR, + SVA_DC_H264_DPB_BUFER_FILLED_ERROR, + SVA_DC_H264_DPB_REMOVE_UNUSED_KO, + /* + */ + + + SVA_DC_H264_DPB_FF_ERROR, + SVA_DC_H264_DPB_MISSING_BUFFERID, + SVA_DC_H264_DPB_ONE_FRAME_REMOVED, + SVA_DC_H264_DPB_BUMPING_ENDED, + SVA_DC_H264_DPB_NO_MORE_SHORT_REF, + SVA_DC_H264_DPB_NO_MORE_LONG_REF, + SVA_DC_H264_DPB_MMCO_ERROR, + SVA_DC_H264_DPB_RESYNCH_NEW_FRAME, + SVA_DC_H264_DPB_DROP_NEW_FRAME, + SVA_DC_H264_DPB_UNABLE_TO_CONCEAL_FRAME, + SVA_DC_H264_DPB_MISSING_BUFFERS_IN_DPB, + SVA_DC_H264_DPB_PICTURE_LOSS_NOT_SUPPORTED, + SVA_DC_H264_DPB_LIST0_ERROR, + SVA_DC_H264_DPB_NO_LIST0, + SVA_DC_H264_DPB_OK = HCL_OK +}t_sva_h264_dpb_error; + +typedef t_sva_video_decoder_algo_h264_mmco_type t_sva_h264_dpb_mmco_type ; + + +/* gather the parameters from active SPS that are used */ +/* in the DPBManagement Block (computing POC for example) */ +typedef struct +{ + t_uint16 numRefFrames; + t_uint16 gapsInFrameNumValueFlag; + t_uint16 picOrderCntType; + t_uint16 log2MaxFrameNumMinus4; + t_uint16 log2MaxPicOrderCntLsbMinus4; + t_sint32 offsetForNonRefPic; + t_uint16 numRefFramesInPicOrderCntCycle; + t_sint32 offsetForRefFrame[256]; + t_sint32 offsetForTopToBottomField ; + t_uint16 picWidthInMbsMinus1; + t_uint16 picHeightInMapUnitsMinus1; +}t_sva_h264_dpb_sps_utils; + + +/* gather the parameters from slice hedaer of the first slice of the frame */ +/* that are used in the DPBManagement Block */ +typedef struct +{ + t_uint16 nut; + t_uint16 nri; + t_uint16 frameNum; + t_uint16 picOrderCntLsb; + t_sint32 deltaPicOrderCnt[2]; + t_sint32 deltaPicOrderCntBottom; + t_uint16 longTermReferenceFlag; + t_uint16 noOutputOfPriorPicsFlag; + t_uint16 adaptiveRefPicMarkingModeFlag; + t_sva_h264_dpb_mmco_type memoryManagementControlOperation[16]; + t_uint16 differenceOfPicNumsMinus1[16]; + t_uint16 markingLongTermPicNum[16]; + t_uint16 longTermFrameIdx[16]; + t_uint16 maxLongTermFrameIdxPlus1[16]; +}t_sva_h264_dpb_slice0_utils; + +/* extracted from slice header */ +typedef struct { + t_uint16 nut; + t_uint16 nri; + t_system_address sliceStartAddress; + t_uint32 sliceOffset; + t_size sliceSize; + t_uint16 sliceBetaOffsetDiv2; + t_uint16 firstMbInSlice; + t_uint16 sliceType; + t_uint16 numRefIdx10ActiveMinus1; + t_uint16 sliceQpDelta; + t_uint16 disableDeblockingFilterIdc; + t_uint16 sliceAlphaC0OffsetDiv2; + t_uint16 sliceNum; + t_uint16 sliceQp; + t_uint16 numRefIdxActiveOverrideFlag; + t_uint16 refPicListReorderingFlagl0; + t_uint16 frameNum; + t_uint16 reorderingOfPicNumsIdc[16]; + t_uint16 absDiffPicNumMinus1[16]; + t_uint16 longTermPicNum[16]; +}t_sva_h264_dpb_params_slice; + + +/* define the max number of buffer in DPB */ +#define SVA_DC_H264_DPB_MAX_SIZE 17 + +/* specify the state of one buffer in the DPB */ +typedef struct +{ + t_sva_buffer_id bufferId; + t_system_address address; + t_bool markedLong; + t_bool markedShort; + t_bool needDisplay; + t_bool picDecoded; + t_bool unusedForReference; + t_sint32 picNum; + t_uint16 frameNum; + t_uint32 frameNumWrap; + t_sint32 poc; + t_uint16 order; + t_uint16 longRefId; +}t_sva_h264_dpb_decoded_buffer_info; + + +/* utils for POC Computing */ +typedef struct +{ + t_uint32 frameNumOffset; + t_sint32 prevPicOrderCntMsb; + t_uint16 prevPicOrderCntLsb; + t_sint32 previousFrameNum; +}t_sva_h264_dpb_poc; + +/* is the DPB */ +typedef struct +{ + t_size size; + t_uint16 fullness; + t_bool initialized; + t_sint16 maxLongTermFrameIdx; + t_uint16 numShortRef; + t_uint16 numLongRef; + t_sva_h264_dpb_decoded_buffer_info decodedBuffer[SVA_DC_H264_DPB_MAX_SIZE]; + t_uint16 curDecodedIndex; //or curBufferId + t_sva_h264_dpb_poc pocUtils; + t_sva_h264_dpb_decoded_buffer_info *pCurDecodedInfo; +}t_sva_h264_dpb_desc; + + + + +/* fonctions exported and used by sva_dc_h264.c */ +PUBLIC t_sva_h264_dpb_error sva_DC_H264_DPB_Init(void); +PUBLIC t_sva_h264_dpb_error sva_DC_H264_DPB_GetInternalNeeds(t_sva_service_instance_num, t_size*); +PUBLIC t_sva_h264_dpb_error sva_DC_H264_DPB_ProvideInternalNeeds(t_sva_service_instance_num); +PUBLIC t_sva_h264_dpb_error sva_DC_H264_DPB_SetActiveSPSUtils(t_sva_service_instance_num, const t_sva_h264_dpb_sps_utils *); +PUBLIC t_sva_h264_dpb_error sva_DC_H264_DPB_SetSlice0Utils(t_sva_service_instance_num, const t_sva_h264_dpb_slice0_utils *); +PUBLIC t_sva_h264_dpb_error sva_DC_H264_DPB_RemoveLastActiveSPSUtils(t_sva_service_instance_num, t_sva_h264_dpb_sps_utils *); +PUBLIC t_sva_h264_dpb_error sva_DC_H264_DPB_RemoveLastSlice0Utils(t_sva_service_instance_num, t_sva_h264_dpb_slice0_utils *); +PUBLIC t_sva_h264_dpb_error sva_DC_H264_DPB_SetDPBSize(t_sva_service_instance_num, t_size); +PUBLIC t_sva_h264_dpb_error sva_DC_H264_DPB_ComputeDPBStart(t_sva_service_instance_num, t_sva_buffer_id *, t_sva_h264_dpb_desc *); +PUBLIC t_sva_h264_dpb_error sva_DC_H264_DPB_ComputeDPBEnd(t_sva_service_instance_num, t_sva_h264_dpb_desc); +PUBLIC t_sva_h264_dpb_error sva_DC_H264_DPB_AreDPBStatesAvailable(t_sva_service_instance_num, t_bool*); +PUBLIC t_sva_h264_dpb_error sva_DC_H264_DPB_Push(t_sva_service_instance_num , t_sva_buffer_id ); +PUBLIC t_sva_h264_dpb_error sva_DC_H264_DPB_ProvideList0(t_sva_service_instance_num ,t_uint16 ,t_uint16 ,const t_sva_h264_dpb_params_slice * ,t_sva_buffer_id * ); +PUBLIC t_sva_h264_dpb_error sva_DC_H264_DPB_GetConcealmentInfo(t_sva_service_instance_num ,t_sva_buffer_id * ,t_uint16 ,t_uint16 ,t_sva_buffer_id * ,t_uint16* ); +PUBLIC t_sva_h264_dpb_error sva_DC_H264_DPB_GetBufferFilled(t_sva_service_instance_num, t_sva_buffer_id *, t_bool *); +PUBLIC t_sva_h264_dpb_error sva_DC_H264_DPB_GetBufferFilledRead(t_sva_service_instance_num, t_sva_buffer_id *, t_bool *); +PUBLIC t_sva_h264_dpb_error sva_DC_H264_DPB_InitList0(t_sva_buffer_id *); +PUBLIC t_sva_h264_dpb_error sva_DC_H264_DPB_FlushToBeDisplayedFifo(t_sva_service_instance_num); +PUBLIC t_sva_h264_dpb_error sva_DC_H264_DPB_FlushFifos(t_sva_service_id ); +PUBLIC t_sva_h264_dpb_error sva_DC_H264_DPB_GetDPBStates(t_sva_service_instance_num); +PUBLIC t_sva_h264_dpb_error sva_DC_H264_DPB_ResetDPBStates(t_sva_service_instance_num); +PUBLIC t_sva_h264_dpb_error sva_DC_H264_DPB_Close(t_sva_service_instance_num ); +PUBLIC t_sva_h264_dpb_error sva_DC_H264_DPB_EarlyReadOnlyGeneration(t_sva_service_instance_num instanceNum, t_sva_buffer_id bufferId, t_bool * isReadOnlyEvent); + +//PUBLIC UpdateDPB? + + +#ifdef __cplusplus +} /* allow C++ to use these headers */ +#endif /* __cplusplus */ + + + +#endif --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/h264/sva_dc_h264_dpbp.h @@ -0,0 +1,98 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ + +#ifndef __INC_SVA_DC_H264_DPBP_H +#define __INC_SVA_DC_H264_DPBP_H + +#include "hcl_defs.h" +#include "sva.h" +#include "sva_decodep.h" +#include "sva_dc_h264.h" +#include "sva_dc_h264_dpb.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + + +#define DPB_PUSH_FIFO_DEFAULT_SIZE 3*SVA_DC_H264_DPB_MAX_SIZE +#define DPB_PUSH_FIFO_THRESOLD 6 + + + + +typedef struct +{ + t_sva_buffer_id bufferId; + t_uint16 dpbIndex; +}t_sva_dpb_buffer_id; + +/* big structure managing the DPBManagement Block */ +typedef struct +{ + t_sva_dc_fifo_dep dpbStartFifo; // fifo of t_sva_h264_dpb_desc for dpbStart + t_sva_dc_fifo_dep dpbEndFifo; // fifo of t_sva_h264_dpb_desc for dpbEnd + t_sva_dc_fifo_dep spsUtilsFifo; // fifo of t_sva_h264_dpb_sps_utils for spsUtils + t_sva_dc_fifo_dep slice0UtilsFifo; // fifo of t_sva_h264_dpb_slice0_utils for slice0Utils + t_sva_fifo bufferIdToBePushedInDpbFifo; + t_sva_fifo bufferIdToBeRemovedFromDPBFifo; + t_sva_fifo bufferIdToBeOutputedFifo; + t_sva_fifo bufferIdToBeOutputedFifoRead; + t_sva_fifo bufferIdToBeOutputedFifod; + t_sva_fifo sendBufferFilledFifo; + t_size dpbSize; + volatile t_uint8 nbBufferInDPB; + t_bool first; + t_sva_h264_dpb_desc newDpbStart; + t_sva_fifo lastDpbFifo; + t_sva_h264_dpb_error dpbError; + t_uint32 debugError; + t_bool isFirstNonExisting; + t_system_address nonExistingBufferSystemAddress; + t_sva_buffer_id nonExistingBufferBufId; + +#ifdef __DEBUG + t_uint32 dbgDpbStartCounter; + t_uint32 dbgInc; + t_sva_h264_dpb_desc dpbStartTrace[SVA_DC_H264_MAX_DBG_DEPTH]; + //t_sva_buffer_id dbgDestBufferId[SVA_DC_H264_MAX_DBG_DEPTH]; + + t_uint32 dbgBufferFilledCounter; + t_sva_dpb_buffer_id dbgBufferFilled[SVA_DC_H264_MAX_DBG_DEPTH]; +#endif + + + t_sva_h264_dpb_sps_utils spsUtils; + t_sva_h264_dpb_slice0_utils slice0Utils; + +}t_sva_h264_dpb_block_desc; + + + + + + +#ifdef __cplusplus +} /* allow C++ to use these headers */ +#endif /* __cplusplus */ + + + +#endif --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/h264/sva_dc_h264_slicemap.c @@ -0,0 +1,312 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ + + + +/*------------------------------------------------------------------------ + * Includes + *----------------------------------------------------------------------*/ +#include "hcl_defs.h" +#include "sva_decodep.h" //for NUM_MAX_DECODE +#include "sva_fifo.h" +#include "sva_dc_h264.h" +#include "sva_dc_h264p.h" +#include "sva_dc_h264_slicemap.h" + +/* from sva_dc_h264.c */ +extern PUBLIC t_sva_h264_desc h264Desc[NUM_MAX_DECODE]; + + +/* Local functions prototypes */ +PRIVATE void sva_DC_H264_SM_Interleaved(t_uint16 , t_sva_h264_slicemap *, t_uint16 *); +PRIVATE void sva_DC_H264_SM_Dispersed(t_sva_service_instance_num, t_uint16 ,t_sva_h264_slicemap * , t_uint16 *); +PRIVATE void sva_DC_H264_SM_ForeGround(t_sva_service_instance_num, t_uint16 , t_sva_h264_slicemap *, t_uint16 *); +PRIVATE void sva_DC_H264_SM_BoxOut(t_sva_service_instance_num, t_uint16 ,t_sva_h264_slicemap * , t_uint16 *); +PRIVATE void sva_DC_H264_SM_Raster(t_uint16 , t_sva_h264_slicemap *, t_uint16 *); +PRIVATE void sva_DC_H264_SM_Wipe(t_sva_service_instance_num, t_uint16 , t_sva_h264_slicemap *, t_uint16 *); +PRIVATE void sva_DC_H264_SM_Explicit(t_uint16 , t_sva_h264_slicemap *, t_uint16 *); + + + + +/* + * + * Perform decoding of macroblock to slice group map. + */ + +PUBLIC void sva_DC_H264_SM_MbSliceMap(t_sva_service_instance_num instanceNum, t_sva_h264_slicemap *pSliceMapBuildInfo, t_physical_address *pSliceMapAddr) +{ + t_uint16 i; + t_sva_h264_desc * pH264Desc = &h264Desc[instanceNum]; + t_uint16 PicSizeInMapUnits = (pH264Desc->picWidthInMbsMinus1+1) * (pH264Desc->picHeightInMapUnitsMinus1+1); + t_uint16 * pSliceMap = (t_uint16*)(*pSliceMapAddr); + + + + if (pSliceMapBuildInfo->numSliceGroupsMinus1 == 0) + { + for (i=0; i < PicSizeInMapUnits; i++) + pSliceMap[i] = 0; + + return; + } + + switch (pSliceMapBuildInfo->sliceGroupMapType) + { + case 0: + sva_DC_H264_SM_Interleaved(PicSizeInMapUnits, pSliceMapBuildInfo, pSliceMap); + break; + + case 1: + sva_DC_H264_SM_Dispersed(instanceNum, PicSizeInMapUnits, pSliceMapBuildInfo, pSliceMap); + break; + + case 2: + sva_DC_H264_SM_ForeGround(instanceNum, PicSizeInMapUnits, pSliceMapBuildInfo, pSliceMap); + break; + + case 3: + sva_DC_H264_SM_BoxOut(instanceNum, PicSizeInMapUnits, pSliceMapBuildInfo, pSliceMap); + break; + + case 4: + sva_DC_H264_SM_Raster(PicSizeInMapUnits, pSliceMapBuildInfo, pSliceMap); + break; + + case 5: + sva_DC_H264_SM_Wipe(instanceNum, PicSizeInMapUnits, pSliceMapBuildInfo, pSliceMap); + break; + + case 6: + sva_DC_H264_SM_Explicit(PicSizeInMapUnits, pSliceMapBuildInfo, pSliceMap); + break; + + default: + break; + } + + return; +} + + + +/* + * Perform decoding of interleaved map type. + */ + +PRIVATE void sva_DC_H264_SM_Interleaved(t_uint16 PicSizeInMapUnits, t_sva_h264_slicemap *pSliceMapBuildInfo, t_uint16 *p_mb_slice_map) +{ + t_uint16 i, j, igrp; + + i = 0; + + do + { + for(igrp = 0; (igrp <= pSliceMapBuildInfo->numSliceGroupsMinus1) && (i < PicSizeInMapUnits); i+= pSliceMapBuildInfo->runLenghtMinus1[igrp++] + 1) + for (j = 0; (j <= pSliceMapBuildInfo->runLenghtMinus1[igrp]) && ((i+j) < PicSizeInMapUnits); j++) + p_mb_slice_map[i+j] = igrp; + } + while (i < PicSizeInMapUnits); + +} + + + +/* + * Perform decoding of dispersed map type. + */ + +PRIVATE void sva_DC_H264_SM_Dispersed(t_sva_service_instance_num instanceNum, t_uint16 PicSizeInMapUnits, t_sva_h264_slicemap *pSliceMapBuildInfo, t_uint16 *p_mb_slice_map) +{ + t_uint16 i; + t_sva_h264_desc * pH264Desc = &h264Desc[instanceNum]; + + + for (i = 0; i < PicSizeInMapUnits; i++) + { + p_mb_slice_map[i] = ((i % (pH264Desc->picWidthInMbsMinus1+1)) + + (((i / (pH264Desc->picWidthInMbsMinus1+1)) * (pSliceMapBuildInfo->numSliceGroupsMinus1 + 1)) / 2)) + % (pSliceMapBuildInfo->numSliceGroupsMinus1 + 1); + } +} + + + +/* + * Perform decoding of foreground-background map type. + */ + +PRIVATE void sva_DC_H264_SM_ForeGround(t_sva_service_instance_num instanceNum, t_uint16 PicSizeInMapUnits, t_sva_h264_slicemap *pSliceMapBuildInfo, t_uint16 *p_mb_slice_map) +{ + t_uint16 i, x, y; + t_sint16 iGroup; + t_uint16 xTopLeft, yTopLeft, xBottomRight, yBottomRight; + t_sva_h264_desc * pH264Desc = &h264Desc[instanceNum]; + + + + for (i = 0; i < PicSizeInMapUnits; i++) + p_mb_slice_map[i] = pSliceMapBuildInfo->numSliceGroupsMinus1; + + for (iGroup = pSliceMapBuildInfo->numSliceGroupsMinus1 - 1; iGroup >= 0; iGroup--) + { + yTopLeft = pSliceMapBuildInfo->topLeft[iGroup] / (pH264Desc->picWidthInMbsMinus1+1); + xTopLeft = pSliceMapBuildInfo->topLeft[iGroup] % (pH264Desc->picWidthInMbsMinus1+1); + yBottomRight = pSliceMapBuildInfo->bottomRight[iGroup] / (pH264Desc->picWidthInMbsMinus1+1); + xBottomRight = pSliceMapBuildInfo->bottomRight[iGroup] % (pH264Desc->picWidthInMbsMinus1+1); + + for (y = yTopLeft; y <= yBottomRight; y++) + for (x = xTopLeft; x <= xBottomRight; x++) + p_mb_slice_map[y * (pH264Desc->picWidthInMbsMinus1+1) + x] = iGroup; + + } +} + + + + +/* + * Perform decoding of box-out map type. + */ + +PRIVATE void sva_DC_H264_SM_BoxOut(t_sva_service_instance_num instanceNum, t_uint16 PicSizeInMapUnits, t_sva_h264_slicemap *pSliceMapBuildInfo, t_uint16 *p_mb_slice_map) +{ + t_uint16 i, k; + t_sint16 leftBound, topBound, rightBound, bottomBound; + t_sint16 x, y, xDir, yDir; + t_sint16 mapUnitVacant; + t_sva_h264_desc * pH264Desc = &h264Desc[instanceNum]; + + t_uint16 mapUnitsInSliceGroup0 = H264MIN((pSliceMapBuildInfo->sliceGroupChangeRateMinus1 + 1) * pSliceMapBuildInfo->slice0SliceGroupChangeCycle, PicSizeInMapUnits); + + for( i = 0; i < PicSizeInMapUnits; i++ ) + p_mb_slice_map[i] = 2; + + x = (pH264Desc->picWidthInMbsMinus1 + 1 - pSliceMapBuildInfo->sliceGroupChangeDirFlag) / 2; + y = (pH264Desc->picHeightInMapUnitsMinus1 + 1 - pSliceMapBuildInfo->sliceGroupChangeDirFlag) / 2; + + leftBound = x; + topBound = y; + rightBound = x; + bottomBound = y; + + xDir = pSliceMapBuildInfo->sliceGroupChangeDirFlag - 1; + yDir = pSliceMapBuildInfo->sliceGroupChangeDirFlag; + + for(k = 0; k < PicSizeInMapUnits; k += mapUnitVacant) + { + mapUnitVacant = (p_mb_slice_map[y * (pH264Desc->picWidthInMbsMinus1 + 1) + x] == 2); + + if(mapUnitVacant) + p_mb_slice_map[y * (pH264Desc->picWidthInMbsMinus1 + 1) + x] = (k >= mapUnitsInSliceGroup0); + + if((xDir == -1) && (x == leftBound)) + { + leftBound = H264MAX(leftBound - 1, 0); + x = leftBound; + xDir = 0; + yDir = 2 * pSliceMapBuildInfo->sliceGroupChangeDirFlag - 1; + } + else if((xDir == 1) && (x == rightBound)) + { + rightBound = H264MIN(rightBound + 1, pH264Desc->picWidthInMbsMinus1); + x = rightBound; + xDir = 0; + yDir = 1 - 2 * pSliceMapBuildInfo->sliceGroupChangeDirFlag; + } + else if((yDir == -1) && (y == topBound)) + { + topBound = H264MAX(topBound - 1, 0); + y = topBound; + xDir = 1 - 2 * pSliceMapBuildInfo->sliceGroupChangeDirFlag; + yDir = 0; + } + else if((yDir == 1) && (y == bottomBound)) + { + bottomBound = H264MIN(bottomBound + 1, pH264Desc->picHeightInMapUnitsMinus1); + y = bottomBound; + xDir = 2 * pSliceMapBuildInfo->sliceGroupChangeDirFlag - 1; + yDir = 0; + } + else + { + x = x + xDir; + y = y + yDir; + } + } +} + + + +/* + * Perform decoding of raster scan map type. + */ + +PRIVATE void sva_DC_H264_SM_Raster(t_uint16 PicSizeInMapUnits, t_sva_h264_slicemap *pSliceMapBuildInfo, t_uint16 *p_mb_slice_map) +{ + t_uint16 mapUnitsInSliceGroup0 = H264MIN((pSliceMapBuildInfo->sliceGroupChangeRateMinus1 + 1) * pSliceMapBuildInfo->slice0SliceGroupChangeCycle, PicSizeInMapUnits); + t_uint16 sizeOfUpperLeftGroup = pSliceMapBuildInfo->sliceGroupChangeDirFlag ? (PicSizeInMapUnits - mapUnitsInSliceGroup0) : mapUnitsInSliceGroup0; + + t_uint16 i; + + for(i = 0; i < PicSizeInMapUnits; i++) + if( i < sizeOfUpperLeftGroup ) + p_mb_slice_map[i] = pSliceMapBuildInfo->sliceGroupChangeDirFlag; + else + p_mb_slice_map[i] = 1 - pSliceMapBuildInfo->sliceGroupChangeDirFlag; +} + + + +/* + * Perform decoding of wipe map type. + */ + +PRIVATE void sva_DC_H264_SM_Wipe(t_sva_service_instance_num instanceNum, t_uint16 PicSizeInMapUnits, t_sva_h264_slicemap *pSliceMapBuildInfo, t_uint16 *p_mb_slice_map) +{ + + t_sva_h264_desc * pH264Desc = &h264Desc[instanceNum]; + t_uint16 mapUnitsInSliceGroup0 = H264MIN((pSliceMapBuildInfo->sliceGroupChangeRateMinus1 + 1) * pSliceMapBuildInfo->slice0SliceGroupChangeCycle, PicSizeInMapUnits); + t_uint16 sizeOfUpperLeftGroup = pSliceMapBuildInfo->sliceGroupChangeDirFlag ? (PicSizeInMapUnits - mapUnitsInSliceGroup0) : mapUnitsInSliceGroup0; + + t_uint16 i, j, k = 0; + + for(j = 0; j < (pH264Desc->picWidthInMbsMinus1 + 1); j++) + for(i = 0; i < (pH264Desc->picHeightInMapUnitsMinus1 + 1); i++) + if(k++ < sizeOfUpperLeftGroup) + p_mb_slice_map[i * (pH264Desc->picWidthInMbsMinus1 + 1) + j] = 1 - pSliceMapBuildInfo->sliceGroupChangeDirFlag; + else + p_mb_slice_map[i * (pH264Desc->picWidthInMbsMinus1 + 1) + j] = pSliceMapBuildInfo->sliceGroupChangeDirFlag; + +} + + + +/* + * Perform decoding of explicit map type. + */ + +PRIVATE void sva_DC_H264_SM_Explicit(t_uint16 PicSizeInMapUnits, t_sva_h264_slicemap *pSliceMapBuildInfo, t_uint16 *p_mb_slice_map) +{ + t_uint16 i; + + for (i = 0; i < PicSizeInMapUnits; i++) + p_mb_slice_map[i] = pSliceMapBuildInfo->sliceGroupId[i]; + +} --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/h264/sva_dc_h264_slicemap.h @@ -0,0 +1,53 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ + +#ifndef __INC_SVA_DC_H264_SLICEMAP_H +#define __INC_SVA_DC_H264_SLICEMAP_H + +#include "hcl_defs.h" + + + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +typedef struct +{ + t_uint16 slice0SliceGroupChangeCycle; + t_uint16 numSliceGroupsMinus1; + t_uint16 sliceGroupMapType; + t_uint16 runLenghtMinus1[8]; + t_uint16 bottomRight[8]; + t_uint16 topLeft[8]; + t_uint16 sliceGroupChangeDirFlag; + t_uint16 sliceGroupChangeRateMinus1; + t_uint16 sliceGroupId[1620]; +}t_sva_h264_slicemap; + + +PUBLIC void sva_DC_H264_SM_MbSliceMap(t_sva_service_instance_num, t_sva_h264_slicemap *, t_physical_address *); + + + +#ifdef __cplusplus +} /* allow C++ to use these headers */ +#endif /* __cplusplus */ + +#endif --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/h264/sva_dc_h264p.h @@ -0,0 +1,156 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ + +#ifndef __INC_SVA_DC_H264_P_H +#define __INC_SVA_DC_H264_P_H + +#include "hcl_defs.h" +#include "sva_service.h" +#include "sva.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + +/* enum error : remains internal, used for debug */ +typedef enum +{ + SVA_DC_H264_DPB_START_PICTURELOSS_NOT_SUPPORTED, + SVA_DC_H264_DPB_START_MISSING_BUFFER_ERROR, + SVA_DC_H264_DPB_START_ERROR, + SVA_DC_H264_DPB_END_ERROR, + SVA_DC_H264_DPB_PUSH_ERROR, + SVA_DC_H264_PARAMIN_ERROR, + SVA_DC_H264_LIST0_ERROR +}t_sva_dc_h264_error; + + + +typedef struct +{ + t_uint16 non_zero; + t_uint16 BKType; + t_sint16 mv[2]; +}t_sva_h264_block4x4_info; +/* from t_block_info structure from ref code */ + +typedef struct +{ + t_sint16 nslice; /* -1 not decoded */ + t_uint16 concealed; + t_uint16 QP[2]; + t_uint16 reserved1; + t_uint16 reserved2; + t_uint16 reserved3; + t_uint16 reserved4; + t_sva_h264_block4x4_info block4x4Info[16]; +} t_sva_h264_mblock_info; + + +/* from tps_h4d_param structure from ref code: */ +typedef struct +{ + unsigned _0 : 2; unsigned A_l : 6; + unsigned _1 : 2; unsigned B_l : 6; + unsigned _2 : 2; unsigned A_c : 6; + unsigned _3 : 2; unsigned B_c : 6; + +} t_sva_h264_ab_index; + + + +typedef struct +{ + unsigned _0 : 2; unsigned h0 : 3; unsigned v0 : 3; + unsigned _1 : 2; unsigned h1 : 3; unsigned v1 : 3; + unsigned _2 : 2; unsigned h2 : 3; unsigned v2 : 3; + unsigned _3 : 2; unsigned h3 : 3; unsigned v3 : 3; + +} t_sva_h264_strength; + + + +typedef struct +{ + t_sva_h264_ab_index index[3]; + t_uint32 loc; + t_sva_h264_strength bs[4]; + +} t_sva_h264_h4d_param; + + + + +/* descriptor of internal variable*/ +typedef struct{ + t_sva_codec_mode codecMode; + t_uint16 picWidthInMbsMinus1; + t_uint16 picHeightInMapUnitsMinus1; + t_sva_video_decoder_algo_h264_configuration_params staticParams; + + t_sva_dc_fifo_dep slicesDescBlockIdFifo; //BlockId Fifo + t_sva_dc_fifo_dep sliceMapFifo; //Fifo of t_sva_h264_slicemap + + /* vdc_internal_buf */ + t_size blockInfoSize; + t_sva_block_id blockInfoId[SUBTASK_DEFAULT_NUMBER]; + t_system_address blockInfoAddr[SUBTASK_DEFAULT_NUMBER]; + t_sva_block_id blockSliceMapId[SUBTASK_DEFAULT_NUMBER]; + t_system_address blockSliceMapAddr[SUBTASK_DEFAULT_NUMBER]; + t_sva_block_id blockH4DId[SUBTASK_DEFAULT_NUMBER]; + t_system_address blockH4DAddr[SUBTASK_DEFAULT_NUMBER]; + /* vdc_frame_buf_out : addr_deblocking_param_buffer */ + t_sva_block_id blockDeblockId; + t_system_address blockDeblockAddr; + + + /* vdc_h264_slice */ + t_sva_block_id blockSlicesId[SUBTASK_DEFAULT_NUMBER]; + t_system_address blockSlicesAddr[SUBTASK_DEFAULT_NUMBER]; + t_uint32 currentNbSlices; + t_sva_dc_h264_error h264Error; + + + t_sva_h264_dpb_sps_utils spsForDpb; + t_sva_h264_dpb_slice0_utils slice0ForDpb; + + + +#ifdef __DEBUG + t_uint32 dbgSliceCounter; + t_uint32 dbgSliceIndex; + //t_sva_vdc_h264_slice slicesTrace[SVA_DC_H264_MAX_DBG_DEPTH][SVA_DC_H264_MAX_DBG_SLICESPERFRAME]; + t_uint32 dbgNbEvent; + t_sva_event_desc eventTraces[SVA_DC_H264_MAX_DBG_DEPTH][SVA_DC_H264_MAX_DBG_EVENTS]; +#endif + + t_bool isToDo; + t_sva_h264_slicemap_info sliceMap; +}t_sva_h264_desc; + + + +#ifdef __cplusplus +} /* allow C++ to use these headers */ +#endif /* __cplusplus */ + + + +#endif --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/mpeg2/sva_dc_mpeg2.c @@ -0,0 +1,2126 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ + + +/*------------------------------------------------------------------------ + * Includes + *----------------------------------------------------------------------*/ + +#include "hcl_defs.h" +#include "sva_host_interface.h" +#include "sva_buffermgt.h" +#include "sva_fifo.h" +#include "sva_decode.h" +#include "../sva_decodep.h" +#include "../sva_decodepp.h" +#include "sva_service.h" + +#include "../sva_dc_algo.h" +#include "sva_dc_mpeg2.h" +#include "sva_dc_mpeg2p.h" + + +/*------------------------------------------------------------------------ + * Global Variables + *----------------------------------------------------------------------*/ +#ifdef __DEBUG +extern PUBLIC t_sva_dc_debug_events eventDecodeDebugTable[NUM_MAX_DECODE]; +extern PUBLIC t_sva_dc_debug_commands commandDecodeDebugTable[NUM_MAX_DECODE]; +extern PUBLIC t_sva_dc_debug_transitions transitionDecodeDebugTable[NUM_MAX_DECODE]; +#endif + +/*instance descriptors*/ +extern PUBLIC t_sva_dc_descriptor decodeDesc[NUM_MAX_DECODE]; +extern PUBLIC const t_sva_tm_field_ctrl_desc defaultDecodeFieldDescArray[NUMBER_OF_DECODE_ALGO_SUPPORTED][DECODE_FIELD_NUMBER]; + + +/* private */ +PUBLIC t_sva_Mpeg2_desc Mpeg2Desc[NUM_MAX_DECODE]; + + +PRIVATE t_sva_Mpeg2_SetHeaderInfosParam setHeaderInfosParam[NUM_MAX_DECODE]; + +// added for field picture support +t_sva_vdc_frame_buffer_in fieldBufferIn; +t_sva_buffer_id btFieldBufferId; +t_sva_Mpeg2_picture_structure fieldStreamType; + +/*------------------------------------------------------------------------ + * Private functions prototype + *----------------------------------------------------------------------*/ +PRIVATE t_bool sva_DC_Mpeg2_IsConfigurationValid(t_sva_video_decoder_algo_Mpeg2_configuration_params *,t_sva_image_desc ); + + +/****************************************************************************/ +/* NAME: sva_DC_Mpeg2_Init() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: This routine enables to store all statical parameters */ +/* PARAMETERS: */ +/* IN : t_sva_service_instance_num instanceNum */ +/* t_sva_codec_mode codecMode */ +/* t_sva_image_desc imageDesc */ +/* t_sva_codec_algo_configuration_params *confParams */ +/* OUT : */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/*--------------------------------------------------------------------------*/ +/* USE: NA */ +/* USED BY: NA */ +/****************************************************************************/ +PUBLIC t_sva_error sva_DC_Mpeg2_Init( + t_sva_service_instance_num instanceNum, + t_sva_codec_mode codecMode, + t_sva_image_desc imageDesc, + const t_sva_dc_algo_configuration_params *pconfParams) +{ + + t_sva_error svaError; + t_sva_video_decoder_algo_Mpeg2_configuration_params *pMpeg2ConfParams; + + + HCL_ASSERT(pconfParams!=NULL); + + if(sva_DC_Mpeg2_IsConfigurationValid((t_sva_video_decoder_algo_Mpeg2_configuration_params *)pconfParams,imageDesc)!= TRUE) + { + return SVA_INCOHERENT_CONFIGURATION; + } + + Mpeg2Desc[instanceNum].codecMode=codecMode; + Mpeg2Desc[instanceNum].imageDesc=imageDesc; + //Store static parameters + pMpeg2ConfParams=(t_sva_video_decoder_algo_Mpeg2_configuration_params *)pconfParams; + Mpeg2Desc[instanceNum].staticParams=*pMpeg2ConfParams; + + + //initialize the global parameters for field picture support + fieldStreamType = PICTURE_STRUCTURE_NONE; + btFieldBufferId = 0xffffffff; + fieldBufferIn.addr_fwd_ref_buffer=NULL; + fieldBufferIn.addr_bwd_ref_buffer=NULL; + + //init globag structure for segmented and stream modes + if (Mpeg2Desc[instanceNum].codecMode != SVA_CODEC_IMAGE_MODE) { + svaError = sva_DC_Mpeg2_InitHeaderInfos(instanceNum); + if (svaError!=SVA_OK) return svaError; + } + + return SVA_OK; +} + + +/****************************************************************************/ +/* NAME: sva_DC_Mpeg2_GetMemoryNeeds() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: This routine enables to determine also cachable memory needs for software process */ +/* PARAMETERS: */ +/* IN : t_sva_service_instance_num instanceNum */ +/* OUT :t_size *pMemNeeds */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/*--------------------------------------------------------------------------*/ +/* USE: NA */ +/* USED BY: NA */ +/****************************************************************************/ +PUBLIC t_sva_error sva_DC_Mpeg2_GetMemoryNeeds( + t_sva_service_instance_num instanceNum, + t_size *pMemNeeds) +{ + + t_size fifoSize; + + HCL_ASSERT(pMemNeeds!=NULL); + + //Dynamic Params Fifo Fifo + GET_FIFO_MEMORY_NEEDS(t_sva_video_decoder_algo_Mpeg2_header_infos, MPEG2_DECODE_MAX_FIFO_SIZE, fifoSize); + *pMemNeeds = fifoSize; + //Bitstream position fifo + GET_FIFO_MEMORY_NEEDS(t_sva_bitstream_desc, MPEG2_DECODE_MAX_FIFO_SIZE, fifoSize); + *pMemNeeds = *pMemNeeds + fifoSize; + + /* fake bistream buffer: was inside decode.c */ + GET_FIFO_MEMORY_NEEDS(t_sva_buffer_id, SUBTASK_DEFAULT_NUMBER, fifoSize); + *pMemNeeds = *pMemNeeds + fifoSize; + //reference(s) handler fifo + GET_FIFO_MEMORY_NEEDS(t_sva_Mpeg2_reference_handler, MPEG2_DECODE_MAX_FIFO_SIZE, fifoSize); + *pMemNeeds = *pMemNeeds + fifoSize; + //reference(s) handler Out fifo to handle frame reordering + GET_FIFO_MEMORY_NEEDS(t_sva_Mpeg2_reference_handler, MPEG2_DECODE_MAX_FIFO_SIZE, fifoSize); + *pMemNeeds = *pMemNeeds + fifoSize; + //to handle frame reordering + GET_FIFO_MEMORY_NEEDS(t_sva_buffer_id, MPEG2_DECODE_MAX_FIFO_SIZE, fifoSize); + *pMemNeeds = *pMemNeeds + fifoSize; + //reference Images fifo (Ref and prevRef) + GET_FIFO_MEMORY_NEEDS(t_sva_buffer_id, MPEG2_DECODE_MAX_FIFO_SIZE, fifoSize); + *pMemNeeds = *pMemNeeds + fifoSize; + GET_FIFO_MEMORY_NEEDS(t_sva_buffer_id, MPEG2_DECODE_MAX_FIFO_SIZE, fifoSize); + *pMemNeeds = *pMemNeeds + fifoSize; + /* Mpeg2 dependency fifo (.push and .inUse) */ + GET_FIFO_MEMORY_NEEDS(t_sva_dc_Mpeg2_dependencies_desc, SUBTASK_DEFAULT_NUMBER, fifoSize); + *pMemNeeds = *pMemNeeds + fifoSize; + GET_FIFO_MEMORY_NEEDS(t_sva_dc_Mpeg2_dependencies_desc, SUBTASK_DEFAULT_NUMBER, fifoSize); + *pMemNeeds = *pMemNeeds + fifoSize; + + return SVA_OK; + +} + + + +/****************************************************************************/ +/* NAME: sva_DC_Mpeg2_ProvideMemoryNeeds() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: This routine enables to provide cachable memory needs */ +/* for decode fifos */ +/* PARAMETERS: */ +/* IN : t_sva_service_instance_num instanceNum */ +/* OUT : */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/*--------------------------------------------------------------------------*/ +/* USE: NA */ +/* USED BY: NA */ +/****************************************************************************/ +PUBLIC t_sva_error sva_DC_Mpeg2_ProvideMemoryNeeds(t_sva_service_instance_num instanceNum ) +{ + t_sva_ff_error ffError; + t_uint16 i; + t_system_address fakeBufferSystemAddr; + t_sva_buffer_id fakeBitstreamBufferId; + t_sva_error svaError; + t_sva_mm_error mmError; + t_system_address paramInOutAddress; + t_sva_block_id paramInOutBlockId; + + //Create all internal fifos + //Dynamic Params Fifo Fifo + CREATE_FIFO(t_sva_video_decoder_algo_Mpeg2_header_infos,MPEG2_DECODE_MAX_FIFO_SIZE,Mpeg2Desc[instanceNum].fifoDynamicParams,ffError); + if (ffError!= SVA_FIFO_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + //Bitstream position fifosva + CREATE_FIFO(t_sva_bitstream_desc,MPEG2_DECODE_MAX_FIFO_SIZE,Mpeg2Desc[instanceNum].fifoBitstream,ffError); + if (ffError!= SVA_FIFO_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + + //fakeBitstreamFifo + CREATE_FIFO(t_sva_buffer_id, SUBTASK_DEFAULT_NUMBER, Mpeg2Desc[instanceNum].fakeBitstreamFifo, ffError); + if (ffError != SVA_FIFO_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + //reference(s) handler fifo + CREATE_FIFO(t_sva_Mpeg2_reference_handler, MPEG2_DECODE_MAX_FIFO_SIZE, Mpeg2Desc[instanceNum].referenceHandlerFifo, ffError); + if (ffError != SVA_FIFO_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + + //reference(s) handler Out fifo + CREATE_FIFO(t_sva_Mpeg2_reference_handler, MPEG2_DECODE_MAX_FIFO_SIZE,Mpeg2Desc[instanceNum].referenceHandlerOutFifo, ffError); + if (ffError != SVA_FIFO_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + + //reference Images fifo (Ref and prevRef) + CREATE_FIFO(t_sva_buffer_id,MPEG2_DECODE_MAX_FIFO_SIZE,Mpeg2Desc[instanceNum].refImageFifo, ffError); + if (ffError!= SVA_FIFO_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + CREATE_FIFO(t_sva_buffer_id,MPEG2_DECODE_MAX_FIFO_SIZE,Mpeg2Desc[instanceNum].prevRefImageFifo, ffError); + if (ffError!= SVA_FIFO_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + //Mpeg2 dependency fifos + CREATE_FIFO(t_sva_dc_Mpeg2_dependencies_desc, SUBTASK_DEFAULT_NUMBER, Mpeg2Desc[instanceNum].Mpeg2Dep.push, ffError); + if (ffError != SVA_FIFO_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + CREATE_FIFO(t_sva_dc_Mpeg2_dependencies_desc, SUBTASK_DEFAULT_NUMBER, Mpeg2Desc[instanceNum].Mpeg2Dep.inUse, ffError); + if (ffError != SVA_FIFO_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + + // Allocate the paramInOut structure within the not cachable sva memory chunk + mmError = sva_MM_AllocBlock(SDRAM_ID, sizeof(t_sva_vdc_Mpeg2_param_inout), SVA_MM_ALIGN_32BYTES, ¶mInOutBlockId); + if (mmError!=SVA_MM_OK) return SVA_INTERNAL_VIDEO_DECODER_ERROR; + mmError = sva_MM_GetBlockSystemAddress(paramInOutBlockId, ¶mInOutAddress); + if (mmError!=SVA_MM_OK) return SVA_INTERNAL_VIDEO_DECODER_ERROR; + Mpeg2Desc[instanceNum].paramInOutAddress = paramInOutAddress; + Mpeg2Desc[instanceNum].paramInOutBlockId = paramInOutBlockId; + /* alloc fake buffer and push it in the fifo */ + for(i=0;iconfHandle.currentConf; + t_sva_Mpeg2_SetHeaderInfosParam *pSetHeaderInfosParams = &setHeaderInfosParam[instanceNum]; + //t_sva_error algoError; + t_sva_video_decoder_algo_Mpeg2_header_infos *pMpeg2HeaderInfos; + t_sva_bitstream_desc bitstreamDesc; + t_sva_buffer_status bufferStatus; + t_physical_address bufferStartAddr; + t_sva_error svaError; + t_sva_ff_error ffError; + t_sva_bm_error bmError; + t_sva_Mpeg2_reference_handler referenceHandler; + + HCL_ASSERT(pHeaderInfos!=NULL); + + pMpeg2HeaderInfos=(t_sva_video_decoder_algo_Mpeg2_header_infos *)(pHeaderInfos); + + + switch(pConf->mode) { + case SVA_CODEC_IMAGE_MODE : + + //check that buffer is already pushed: ie is in "sva_BUFFER_IN_USE" state + svaError=SVA_GetBufferStatus(bitstreamBuffer,&bufferStatus); + if (svaError != SVA_OK) {return SVA_UNEXPECTED_API_CALL; } + + HCL_DEBUG_ASSERT(bufferStatus.state == SVA_BUFFER_IN_USE); + if (bufferStatus.state != SVA_BUFFER_IN_USE) { return SVA_UNEXPECTED_API_CALL; } + + pMpeg2HeaderInfos=(t_sva_video_decoder_algo_Mpeg2_header_infos *)(pHeaderInfos); + + referenceHandler.bitstreamBuffer = bitstreamBuffer; + referenceHandler.fwdReferenceImage = INVALID_BUFFER_ID; // both fwd and bwd ref will be set up when resolving dependencies + referenceHandler.bwdReferenceImage = INVALID_BUFFER_ID; + referenceHandler.pictureType = (t_sva_Mpeg2_picture_type)pMpeg2HeaderInfos->picture_coding_type; + referenceHandler.pictureStructure = pMpeg2HeaderInfos->picture_structure; + if (fieldStreamType == PICTURE_STRUCTURE_NONE /*&& fieldStreamType != PICTURE_STRUCTURE_FRAME*/) + { + fieldStreamType = (t_sva_Mpeg2_picture_structure)pMpeg2HeaderInfos->picture_structure; + + } + ffError=PUSH_FIFO_ELEM(Mpeg2Desc[instanceNum].referenceHandlerFifo, t_sva_Mpeg2_reference_handler, referenceHandler); + if (ffError!= SVA_FIFO_OK) {return SVA_INTERNAL_FIFOS_FULL;} + + ffError=PUSH_FIFO_ELEM(Mpeg2Desc[instanceNum].referenceHandlerOutFifo, t_sva_Mpeg2_reference_handler, referenceHandler); + if (ffError!= SVA_FIFO_OK) {return SVA_INTERNAL_FIFOS_FULL;} + + bmError=sva_BM_GetBufferPhysicalAddress(bitstreamBuffer,&bufferStartAddr); + if (bmError != SVA_BM_OK) {return SVA_UNEXPECTED_API_CALL; } + + //Store Dynamic params in fifo fifoDynamicParams + ffError=PUSH_FIFO_ELEM(Mpeg2Desc[instanceNum].fifoDynamicParams,t_sva_video_decoder_algo_Mpeg2_header_infos,*pMpeg2HeaderInfos); + if (ffError!= SVA_FIFO_OK) {return SVA_INTERNAL_FIFOS_FULL;} + + /*Store bitstream position in fifoBitstream*/ + //This field will be setted in sva_DC_TryToInitBitstreamFields as decode module manages bitstrem buffer list + bitstreamDesc.bitstreamPosition.addr_bitstream_buf_struct= 0;//address of bitstream buffer list will be updated by ResolveDependancies() (should be multiple of 16) + bitstreamDesc.bitstreamPosition.addr_bitstream_start= ((byteOffset >> 4) <<4) + bufferStartAddr; //in bytes (Should be aligned on 16 bytes + absolute address) + bitstreamDesc.bitstreamPosition.bitstream_offset= (byteOffset - ((byteOffset >> 4) <<4)) * 8 + bitOffset; //Is the offset in bits between aligned address and provided no aligned address in byte + user offset + bitstreamDesc.relatedBufferId=bitstreamBuffer; + ffError=PUSH_FIFO_ELEM(Mpeg2Desc[instanceNum].fifoBitstream,t_sva_bitstream_desc,bitstreamDesc); + if (ffError!= SVA_FIFO_OK) {return SVA_INTERNAL_FIFOS_FULL;} + + break; + + case SVA_CODEC_SEGMENTED_MODE : + case SVA_CODEC_STREAM_MODE : + + if (pSetHeaderInfosParams->bitstreamBuffer != INVALID_BUFFER_ID) { + ffError=PUSH_FIFO_ELEM(pDesc->lastPushedBufferFifo.push,t_sva_buffer_id,bitstreamBuffer); + if (ffError!= SVA_FIFO_OK) {return SVA_INTERNAL_FIFOS_FULL;} + + //check that buffer is already pushed: ie is in "sva_BUFFER_IN_USE" state + svaError=SVA_GetBufferStatus(pSetHeaderInfosParams->bitstreamBuffer,&bufferStatus); + if (svaError != SVA_OK) {return SVA_UNEXPECTED_API_CALL; } + + if (bufferStatus.state != SVA_BUFFER_IN_USE) { return SVA_UNEXPECTED_API_CALL; } + + pMpeg2HeaderInfos = &pSetHeaderInfosParams->headerInfos; + + bmError=sva_BM_GetBufferPhysicalAddress(pSetHeaderInfosParams->bitstreamBuffer,&bufferStartAddr); + if (bmError != SVA_BM_OK) {return SVA_UNEXPECTED_API_CALL; } + + //Store the last picture Type + referenceHandler.bitstreamBuffer = pSetHeaderInfosParams->bitstreamBuffer; + referenceHandler.fwdReferenceImage = INVALID_BUFFER_ID; // both fwd and bwd ref will be set up when resolving dependencies + referenceHandler.bwdReferenceImage = INVALID_BUFFER_ID; + referenceHandler.pictureType = (t_sva_Mpeg2_picture_type)pMpeg2HeaderInfos->picture_coding_type; + PUSH_FIFO_ELEM(Mpeg2Desc[instanceNum].referenceHandlerFifo, t_sva_Mpeg2_reference_handler, referenceHandler); + + ffError=PUSH_FIFO_ELEM(Mpeg2Desc[instanceNum].referenceHandlerOutFifo, t_sva_Mpeg2_reference_handler, referenceHandler); + if (ffError!= SVA_FIFO_OK) {return SVA_INTERNAL_FIFOS_FULL;} + + //Store Dynamic params in fifo fifoDynamicParams + ffError=PUSH_FIFO_ELEM(Mpeg2Desc[instanceNum].fifoDynamicParams,t_sva_video_decoder_algo_Mpeg2_header_infos,*pMpeg2HeaderInfos); + if (ffError!= SVA_FIFO_OK) {return SVA_INTERNAL_FIFOS_FULL;} + + /*Store bitstream position in fifoBitstream*/ + //This field will be setted in sva_DC_TryToInitBitstreamFields as decode module manages bitstrem buffer list + bitstreamDesc.bitstreamPosition.addr_bitstream_buf_struct= 0;//address of bitstream buffer list will be updated by ResolveDependancies() (should be multiple of 16) + bitstreamDesc.bitstreamPosition.addr_bitstream_start= ((pSetHeaderInfosParams->byteOffset >> 4) <<4) + bufferStartAddr; //in bytes (Should be aligned on 16 bytes + absolute address) + bitstreamDesc.bitstreamPosition.bitstream_offset= (pSetHeaderInfosParams->byteOffset - ((pSetHeaderInfosParams->byteOffset >> 4) <<4)) * 8 + pSetHeaderInfosParams->bitOffset; //Is the offset in bits between aligned address and provided no aligned address in byte + user offset + bitstreamDesc.relatedBufferId=pSetHeaderInfosParams->bitstreamBuffer; + ffError=PUSH_FIFO_ELEM(Mpeg2Desc[instanceNum].fifoBitstream,t_sva_bitstream_desc,bitstreamDesc); + if (ffError!= SVA_FIFO_OK) {return SVA_INTERNAL_FIFOS_FULL;} + } + + + // stack up current parameters to be used at the end of the frame (next call of sva_DC_SetHeaderInfos) + pSetHeaderInfosParams->serviceId = serviceId; + pSetHeaderInfosParams->bitstreamBuffer = bitstreamBuffer; + pSetHeaderInfosParams->byteOffset = byteOffset; + pSetHeaderInfosParams->bitOffset = bitOffset; + pMpeg2HeaderInfos = (t_sva_video_decoder_algo_Mpeg2_header_infos*)pHeaderInfos; + pSetHeaderInfosParams->headerInfos = *pMpeg2HeaderInfos; + + break; + + default : + return SVA_INTERNAL_VIDEO_DECODER_ERROR; + // break; PCLint warning removal ... + } + + return SVA_OK; + +} + + +/****************************************************************************/ +/* NAME: sva_DC_Mpeg2_AssertEndOfBitstream() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: Assert the immediate end of bitstream. Leads to a */ +/* non-delayed setHeaderInfos execution */ +/* */ +/* PARAMETERS: */ +/* IN : t_sva_service_id serviceId */ +/* OUT :none */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/* - SVA_OK : Last subtask sucessfully lined up. */ +/* - SVA_INTERNAL_VIDEO_DECODER_ERROR : Error */ +/****************************************************************************/ +PUBLIC t_sva_error sva_DC_Mpeg2_AssertEndOfBitstream(t_sva_service_instance_num instanceNum, t_sva_service_id serviceId) +{ + + t_sva_dc_descriptor *pDesc=&decodeDesc[instanceNum]; + t_sva_video_decoder_configuration *pConf=&pDesc->confHandle.currentConf; + t_sva_Mpeg2_SetHeaderInfosParam *pSetHeaderInfosParams = &setHeaderInfosParam[instanceNum]; + t_sva_video_decoder_algo_Mpeg2_header_infos *pMpeg2HeaderInfos; + t_sva_bitstream_desc bitstreamDesc; + t_sva_buffer_status bufferStatus; + t_physical_address bufferStartAddr; + t_sva_ff_error ffError; + t_sva_error svaError; + t_sva_bm_error bmError; + t_sva_Mpeg2_reference_handler referenceHandler; + + switch(pConf->mode) { + case SVA_CODEC_IMAGE_MODE : + + return SVA_OK; // nothing to do in Image mode - End of bitstream trigerred by SetHeaderInfos + + case SVA_CODEC_SEGMENTED_MODE : + case SVA_CODEC_STREAM_MODE : + + //check that transition is allowed + if (sva_DC_isTransitionValid(instanceNum,SVA_DC_PUSH)==FALSE) {return SVA_UNEXPECTED_API_CALL;} + + // trigger the execution of the last SetHeaderInfos + if (pSetHeaderInfosParams->bitstreamBuffer != INVALID_BUFFER_ID) { + // valid buffer ID means this is not the first call to SVA_SetHeaderInfos : process here + // last call parameters + + //check that buffer is already pushed: ie is in "sva_BUFFER_IN_USE" state + svaError=SVA_GetBufferStatus(pSetHeaderInfosParams->bitstreamBuffer,&bufferStatus); + if (svaError != SVA_OK) {return SVA_UNEXPECTED_API_CALL; } + + HCL_DEBUG_ASSERT(bufferStatus.state == SVA_BUFFER_IN_USE); + if (bufferStatus.state != SVA_BUFFER_IN_USE) { return SVA_UNEXPECTED_API_CALL; } + + pMpeg2HeaderInfos = &pSetHeaderInfosParams->headerInfos; + + bmError=sva_BM_GetBufferPhysicalAddress(pSetHeaderInfosParams->bitstreamBuffer,&bufferStartAddr); + if (bmError != SVA_BM_OK) {return SVA_UNEXPECTED_API_CALL; } + + // get the type of the frame to handle references + referenceHandler.bitstreamBuffer = pSetHeaderInfosParams->bitstreamBuffer; + referenceHandler.fwdReferenceImage = INVALID_BUFFER_ID; // both fwd and bwd ref will be set up when resolving dependencies + referenceHandler.bwdReferenceImage = INVALID_BUFFER_ID; + referenceHandler.pictureType = (t_sva_Mpeg2_picture_type)pMpeg2HeaderInfos->picture_coding_type; + ffError=PUSH_FIFO_ELEM(Mpeg2Desc[instanceNum].referenceHandlerFifo, t_sva_Mpeg2_reference_handler, referenceHandler); + if (ffError!= SVA_FIFO_OK) {return SVA_INTERNAL_FIFOS_FULL;} + + ffError=PUSH_FIFO_ELEM(Mpeg2Desc[instanceNum].referenceHandlerOutFifo, t_sva_Mpeg2_reference_handler, referenceHandler); + if (ffError!= SVA_FIFO_OK) {return SVA_INTERNAL_FIFOS_FULL;} + + //Store Dynamic params in fifo fifoDynamicParams + ffError=PUSH_FIFO_ELEM(Mpeg2Desc[instanceNum].fifoDynamicParams,t_sva_video_decoder_algo_Mpeg2_header_infos,*pMpeg2HeaderInfos); + if (ffError!= SVA_FIFO_OK) {return SVA_INTERNAL_FIFOS_FULL;} + + /*Store bitstream position in fifoBitstream*/ + //This field will be setted in sva_DC_TryToInitBitstreamFields as decode module manages bitstrem buffer list + bitstreamDesc.bitstreamPosition.addr_bitstream_buf_struct= 0;//address of bitstream buffer list will be updated by ResolveDependancies() (should be multiple of 16) + bitstreamDesc.bitstreamPosition.addr_bitstream_start= ((pSetHeaderInfosParams->byteOffset >> 4) <<4) + bufferStartAddr; //in bytes (Should be aligned on 16 bytes + absolute address) + bitstreamDesc.bitstreamPosition.bitstream_offset= (pSetHeaderInfosParams->byteOffset - ((pSetHeaderInfosParams->byteOffset >> 4) <<4)) * 8 + pSetHeaderInfosParams->bitOffset; //Is the offset in bits between aligned address and provided no aligned address in byte + user offset + bitstreamDesc.relatedBufferId=pSetHeaderInfosParams->bitstreamBuffer; + ffError=PUSH_FIFO_ELEM(Mpeg2Desc[instanceNum].fifoBitstream,t_sva_bitstream_desc,bitstreamDesc); + if (ffError!= SVA_FIFO_OK) {return SVA_INTERNAL_FIFOS_FULL;} + + sva_DC_UpdateInstanceStateMachine(instanceNum,SVA_DC_PUSH); + + } else return SVA_INTERNAL_VIDEO_DECODER_ERROR; + + break; + + default : + return SVA_INTERNAL_VIDEO_DECODER_ERROR; + //break; PCLint warning removal ... + } + + return SVA_OK; + +} + + + + + +/****************************************************************************/ +/* NAME: sva_DC_Mpeg2_GetOutputParamsSize() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: This routine enables user to know the size of Paramout */ +/* structure: depends on algo used (and FW release) */ +/* PARAMETERS: */ +/* IN : t_sva_service_instance_num instanceNum */ +/* OUT : */ +/* */ +/* RETURN: */ +/* size in byte */ +/*--------------------------------------------------------------------------*/ +/* USE: NA */ +/* USED BY: NA */ +/****************************************************************************/ +PUBLIC t_size sva_DC_Mpeg2_GetOutputParamsSize( + t_sva_service_instance_num instanceNum + ) +{ + (void) instanceNum;/*discard instanceNum*/ + + return (sizeof(t_sva_vdc_Mpeg2_param_out)); +} + + + +/****************************************************************************/ +/* NAME: sva_DC_Mpeg2_SetOutputParams() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: This routine enables to synthetize all infos provided by */ +/* a subtask through the paramout field */ +/* Called when EOT,It computes paramout data and stores results*/ +/* in a global variable */ +/* PARAMETERS: */ +/* IN : t_sva_service_instance_num instanceNum */ +/* OUT :t_bool *infosAvailable */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/*--------------------------------------------------------------------------*/ +/* USE: NA */ +/* USED BY: NA */ +/****************************************************************************/ +PUBLIC t_sva_error sva_DC_Mpeg2_SetOutputParams( + t_sva_service_instance_num instanceNum, + const t_sva_dc_algo_params_out *algoParamsOutAddr + ) +{ + t_sva_vdc_Mpeg2_param_out *pNewParamOut; + + HCL_ASSERT(algoParamsOutAddr!=NULL); + + pNewParamOut=(t_sva_vdc_Mpeg2_param_out *) algoParamsOutAddr; + + + Mpeg2Desc[instanceNum].lastFrameMpeg2ParamOut.error_type=pNewParamOut->error_type; + return SVA_OK; +} + + + + +/****************************************************************************/ +/* NAME: sva_DC_Mpeg2_GetStatus() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: This routine gives access to Mpeg2Desc[instanceNum].Mpeg2ParamOut*/ +/* global */ +/* This is called inside sva_DC_Status() */ +/* PARAMETERS: */ +/* IN : t_sva_service_instance_num instanceNum */ +/* OUT :t_sva_dc_algo_status * */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/*--------------------------------------------------------------------------*/ +/* USE: NA */ +/* USED BY: NA */ +/****************************************************************************/ +t_sva_error sva_DC_Mpeg2_GetStatus ( + t_sva_service_instance_num instanceNum, + t_sva_dc_algo_status *lastFrameAlgoStatus, + t_sva_dc_algo_status *statisticalAlgoStatus ) +{ + t_sva_vdc_Mpeg2_param_out *plastFrameMpeg2ParamOut; + t_sva_vdc_Mpeg2_param_out *pstatisticalMpeg2ParamOut; + + HCL_ASSERT(lastFrameAlgoStatus!=NULL); + HCL_ASSERT(statisticalAlgoStatus!=NULL); + + plastFrameMpeg2ParamOut=(t_sva_vdc_Mpeg2_param_out *)lastFrameAlgoStatus; + pstatisticalMpeg2ParamOut=(t_sva_vdc_Mpeg2_param_out *)statisticalAlgoStatus; + + *plastFrameMpeg2ParamOut=Mpeg2Desc[instanceNum].lastFrameMpeg2ParamOut; + *pstatisticalMpeg2ParamOut=Mpeg2Desc[instanceNum].statisticalMpeg2ParamOut; + + return SVA_OK; +} + + +/****************************************************************************/ +/* NAME: sva_DC_Mpeg2_FlushFifos() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: This routine enables to flush all Mpeg2 fifos */ +/* */ +/* PARAMETERS: */ +/* IN : t_sva_service_instance_num instanceNum */ +/* OUT : */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/*--------------------------------------------------------------------------*/ +/* USE: NA */ +/* USED BY: NA */ +/****************************************************************************/ +t_sva_error sva_DC_Mpeg2_FlushFifos (t_sva_service_instance_num instanceNum) { + + t_sva_dc_descriptor *pDesc=&decodeDesc[instanceNum]; + t_sva_Mpeg2_desc *pMpeg2Desc = &Mpeg2Desc[instanceNum]; + t_sva_dc_subtask_dependencies subtaskDep; + t_sva_dc_Mpeg2_dependencies_desc Mpeg2Dep; + t_sva_buffer_id bufferId; + t_uint32 systemTime; + t_sva_error svaError; + t_sva_tm_error tmError; + t_sva_ff_error ffError; + t_sva_bm_error bmError; + t_uint32 i; + + // flush all scheduled subtasks + do { + tmError=sva_TM_RemoveElemFromSubTaskList(pDesc->subtasksListId,&subtaskDep.subtaskId); + } while (tmError==SVA_TM_OK); + + // flush dependencies + while(POP_FIFO_ELEM(pDesc->subtasksDependencyFifo.inUse,t_sva_dc_subtask_dependencies,subtaskDep) != SVA_FIFO_EMPTY); + while(POP_FIFO_ELEM(pDesc->subtasksDependencyFifo.push,t_sva_dc_subtask_dependencies,subtaskDep) != SVA_FIFO_EMPTY); + while(POP_FIFO_ELEM(pMpeg2Desc->Mpeg2Dep.inUse,t_sva_dc_Mpeg2_dependencies_desc,Mpeg2Dep) != SVA_FIFO_EMPTY); + while(POP_FIFO_ELEM(pMpeg2Desc->Mpeg2Dep.push,t_sva_dc_Mpeg2_dependencies_desc,Mpeg2Dep) != SVA_FIFO_EMPTY); + + /* Push back reset subtaskdeps in the .push fifos */ + for(i=0;isubtasksIdArray[i]; + subtaskDep.bitstreamBufferListId=pDesc->bufferListIdArray[i][0]; + subtaskDep.dependencies=pDesc->defaultDep; + Mpeg2Dep = pMpeg2Desc->defaultDep; + ffError=PUSH_FIFO_ELEM(pDesc->subtasksDependencyFifo.push, t_sva_dc_subtask_dependencies, subtaskDep); + if (ffError!=SVA_FIFO_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + ffError=PUSH_FIFO_ELEM(pMpeg2Desc->Mpeg2Dep.push, t_sva_dc_Mpeg2_dependencies_desc, Mpeg2Dep); + if (ffError!=SVA_FIFO_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + } + + /*get time*/ + svaError=SVA_GetServiceSystemTime(pDesc->serviceId ,&systemTime); + if (svaError != SVA_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + + /************/ + /*flush fifo*/ + /************/ + + //fifo outputImageFifo + //-------------------- + while(POP_FIFO_ELEM(pDesc->outputImageFifos.push,t_sva_buffer_id,bufferId) != SVA_FIFO_EMPTY) + { + bmError=sva_BM_UpdateBufferStatus(bufferId,SVA_BUFFER_NOT_USED,systemTime); + if (bmError!=SVA_BM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + } + while(POP_FIFO_ELEM(pDesc->outputImageFifos.inUse,t_sva_buffer_id,bufferId) != SVA_FIFO_EMPTY) + { + bmError=sva_BM_UpdateBufferStatus(bufferId,SVA_BUFFER_NOT_USED,systemTime); + if (bmError!=SVA_BM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + } + + + //optional fifos outputDeblockingFifos + //------------------------------------ + if(pDesc->confHandle.currentConf.outTheLoopFilter != SVA_NONE_FILTER) + { + while(POP_FIFO_ELEM(pDesc->outputDeblockingFifos.push,t_sva_buffer_id,bufferId) != SVA_FIFO_EMPTY) + { + bmError=sva_BM_UpdateBufferStatus(bufferId,SVA_BUFFER_NOT_USED,systemTime); + if (bmError!=SVA_BM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + } + while(POP_FIFO_ELEM(pDesc->outputDeblockingFifos.inUse,t_sva_buffer_id,bufferId) != SVA_FIFO_EMPTY) + { + bmError=sva_BM_UpdateBufferStatus(bufferId,SVA_BUFFER_NOT_USED,systemTime); + if (bmError!=SVA_BM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + } + } + //optional fifos outputInfosFifos + //------------------------------- + if(pDesc->confHandle.currentConf.areInfosRequested == TRUE) + { + while(POP_FIFO_ELEM(pDesc->outputInfosFifos.push,t_sva_buffer_id,bufferId) != SVA_FIFO_EMPTY) + { + bmError=sva_BM_UpdateBufferStatus(bufferId,SVA_BUFFER_NOT_USED,systemTime); + if (bmError!=SVA_BM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + } + while(POP_FIFO_ELEM(pDesc->outputInfosFifos.inUse,t_sva_buffer_id,bufferId) != SVA_FIFO_EMPTY) + { + bmError=sva_BM_UpdateBufferStatus(bufferId,SVA_BUFFER_NOT_USED,systemTime); + if (bmError!=SVA_BM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + } + } + //fifo inputBitstreamfifo + //-------------------- + while(POP_FIFO_ELEM(pDesc->inputBitstreamFifos.push,t_sva_buffer_id,bufferId) != SVA_FIFO_EMPTY) + { + bmError=sva_BM_UpdateBufferStatus(bufferId,SVA_BUFFER_NOT_USED,systemTime); + if (bmError!=SVA_BM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + } + while(POP_FIFO_ELEM(pDesc->inputBitstreamFifos.inUse,t_sva_buffer_id,bufferId) != SVA_FIFO_EMPTY) + { + bmError=sva_BM_UpdateBufferStatus(bufferId,SVA_BUFFER_NOT_USED,systemTime); + if (bmError!=SVA_BM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + } + + //internal fifos + //-------------- + FLUSH_FIFO(Mpeg2Desc[instanceNum].fifoDynamicParams); + FLUSH_FIFO(Mpeg2Desc[instanceNum].fifoBitstream); + FLUSH_FIFO(Mpeg2Desc[instanceNum].referenceHandlerFifo); + FLUSH_FIFO(Mpeg2Desc[instanceNum].referenceHandlerOutFifo); + FLUSH_FIFO(Mpeg2Desc[instanceNum].refImageFifo); + FLUSH_FIFO(Mpeg2Desc[instanceNum].prevRefImageFifo); + return SVA_OK; +} + + + + +/****************************************************************************/ +/* NAME: sva_DC_Mpeg2_DeleteFake() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* */ +/* */ +/* PARAMETERS: */ +/* IN : t_sva_service_instance_num instanceNum */ +/* OUT : */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/****************************************************************************/ +t_sva_error sva_DC_Mpeg2_DeleteFake ( + t_sva_service_instance_num instanceNum + ) +{ + + t_sva_ff_error ffError; + t_uint16 i; + t_sva_buffer_id fakeBitstreamBufferId=INVALID_BUFFER_ID; + + for(i=0;iconfHandle.currentConf; + t_sva_error status=SVA_OK; + t_sva_bm_error bmError; + t_sva_ff_error ffError; + t_size bufferSize; + t_size minSize=0; + + switch(bufferType) + { + case SVA_PARAMS_BUFFER_TYPE: + //if (pConf->outTheLoopFilter == SVA_NONE_FILTER) return SVA_UNEXPECTED_API_CALL; + /*compute minimum size of buffer according to current configuration*/ + minSize=((((t_uint32)pConf->imageDesc.height/16)+2) * (((t_uint32)pConf->imageDesc.width/16)+2))*4; + + /*read buffer size*/ + bmError=sva_BM_GetBufferSize(bufferId,&bufferSize); + if (bmError!=SVA_BM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + /*check buffer has enought space*/ + if (bufferSize>=minSize) + { + ffError=PUSH_FIFO_ELEM(pDesc->outputDeblockingFifos.push, t_sva_buffer_id, bufferId); + if (ffError!=SVA_FIFO_OK) {status=SVA_INTERNAL_FIFOS_FULL;} + else {status=SVA_OK;} + } + else {status=SVA_INTERNAL_VIDEO_DECODER_ERROR;} + break; + + case SVA_INFOS_BUFFER_TYPE: + if (pConf->areInfosRequested == FALSE) return SVA_UNEXPECTED_API_CALL; + /*compute minimum size of buffer according to current configuration*/ + minSize=sva_DC_Mpeg2_GetOutputParamsSize(instanceNum); + /*read buffer size*/ + bmError=sva_BM_GetBufferSize(bufferId,&bufferSize); + if (bmError!=SVA_BM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + /*check buffer has enought space*/ + if (bufferSize>=minSize) + { + ffError=PUSH_FIFO_ELEM(pDesc->outputInfosFifos.push, t_sva_buffer_id, bufferId); + if (ffError!=SVA_FIFO_OK) {status=SVA_INTERNAL_FIFOS_FULL;} + else {status=SVA_OK;} + } + else {status=SVA_INTERNAL_VIDEO_DECODER_ERROR;} + break; + + case SVA_BITSTREAM_BUFFER_TYPE: + //Store buffer in bitstream buffer fifo + ffError=PUSH_FIFO_ELEM(pDesc->inputBitstreamFifos.push,t_sva_buffer_id,bufferId); + if (ffError!= SVA_FIFO_OK) {return SVA_INTERNAL_FIFOS_FULL;} + //log byte number of compressed data provided by user + bmError=sva_BM_GetBufferSize(bufferId,&bufferSize); + if (bmError!=SVA_BM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + pDesc->status.nbCompressedDataBufferized+=bufferSize; + + break; + + case SVA_IMAGE_BUFFER_TYPE: + /*compute minimum size of buffer according to current configuration*/ + minSize=((((t_uint32)pConf->imageDesc.height * (t_uint32)pConf->imageDesc.width)*3)/2); + /*read buffer size*/ + bmError=sva_BM_GetBufferSize(bufferId,&bufferSize); + if (bmError!=SVA_BM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + /*check buffer has enought space*/ + if (bufferSize>=minSize) + { + //Push in both Fifos outputImageFifos.push and inputFwdImageFifos.push + ffError=PUSH_FIFO_ELEM(pDesc->outputImageFifos.push, t_sva_buffer_id, bufferId); + if (ffError!=SVA_FIFO_OK) {status=SVA_INTERNAL_FIFOS_FULL;} + else {status=SVA_OK;} + } + else {status=SVA_INTERNAL_VIDEO_DECODER_ERROR;} + break; + + default: + status=SVA_INVALID_BUFFER_TYPE; + break; + } + + return status; +} + + + +/****************************************************************************/ +/* NAME: sva_DC_Mpeg2_DispatchEOT() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* OUT :none */ +/* */ +/* RETURN: */ +/* */ +/****************************************************************************/ +t_sva_error sva_DC_Mpeg2_DispatchEOT( + t_sva_service_instance_num instanceNum, + t_sva_tm_subtask_id subtaskId, + t_sva_event_desc* pEventDesc, + t_sva_service_id serviceId, + t_uint32 eventTimestamp, + t_uint32 eventDate, + t_uint32 *pNbEventsRaised, + t_uint32 maxOfEvent, + t_sva_buffer_list_id bitstreamBufferListId ) +{ + + t_sva_dc_descriptor *pDesc=&decodeDesc[instanceNum]; + t_sva_Mpeg2_desc *pMpeg2Desc = &Mpeg2Desc[instanceNum]; + t_sva_video_decoder_configuration *pConf=&pDesc->confHandle.currentConf; + t_size size; + t_sva_tm_error tmError; + t_sva_ff_error ffError; + t_logical_address paramOutAddr; + t_uint16 errorType; + t_sva_error algoError; + t_sva_blm_error blmError; + t_sva_buffer_id infoBuffer = INVALID_BUFFER_ID; + t_sva_buffer_id outputImageBuffer = INVALID_BUFFER_ID; + t_sva_buffer_id bufferId, lastBufferId; + t_sva_dc_Mpeg2_dependencies_desc Mpeg2Dep; + t_sva_Mpeg2_reference_handler referenceHandlerOut; + + t_uint32 nbEvents = *pNbEventsRaised; + t_sva_event_desc *pEvent; + pEvent = &pEventDesc[nbEvents]; + + // remove dependencies from the last executed subtask and reset it to defaultDep value + ffError = POP_FIFO_ELEM(pMpeg2Desc->Mpeg2Dep.inUse, t_sva_dc_Mpeg2_dependencies_desc, Mpeg2Dep); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + Mpeg2Dep = pMpeg2Desc->defaultDep; + ffError = PUSH_FIFO_ELEM(pMpeg2Desc->Mpeg2Dep.push, t_sva_dc_Mpeg2_dependencies_desc, Mpeg2Dep); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + + if(pDesc->confHandle.currentConf.areInfosRequested == FALSE) + { + paramOutAddr=pDesc->paramOutAddr; //Address of blockId that is intended to contain paramOut + size=sva_DC_Mpeg2_GetOutputParamsSize (instanceNum); + /*transfer paramout to internal block*/ + tmError=sva_TM_GetSubTaskField(subtaskId, SVA_TM_DEC_ADDR_OUT_PARAMETERS,paramOutAddr, + 0, size, FALSE); + HCL_DEBUG_ASSERT(tmError==SVA_TM_OK); + } + //infos buffer + else + { + ffError=POP_FIFO_ELEM(pDesc->outputInfosFifos.inUse,t_sva_buffer_id,infoBuffer); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + //set paramOutAddr + sva_BM_GetBufferLogicalAddress(infoBuffer, ¶mOutAddr); + // get the related image buffer id + ffError=READ_FIFO_ELEM(pDesc->outputImageFifos.inUse,t_sva_buffer_id,bufferId); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + //the buffer is then filled + CHECK_TABLE_OVERFLOW(*pNbEventsRaised, maxOfEvent, SVA_INTERNAL_VIDEO_DECODER_ERROR); + pEvent->eventId = SVA_EVENT_BUFFER_FILLED; + pEvent->bufferId = infoBuffer; + pEvent->serviceId = serviceId; + pEvent->eventTimestamp = (t_sva_timestamp_value) eventTimestamp; + pEvent->eventDate = (t_sva_timestamp_value) eventDate; + pEvent->extraInfo= bufferId; + pDesc->status.eventStats.filledCounter++; + /*update buffer status*/ + sva_BM_UpdateBufferStatus(pEvent->bufferId,SVA_BUFFER_FILLED,eventTimestamp); + nbEvents++; + //*pNbEventsRaised=nbEvents; + pEvent = &pEventDesc[nbEvents]; + + } + //provide to algo module for computing statistical data + record + algoError=sva_DC_Mpeg2_SetOutputParams(instanceNum, (void *)paramOutAddr); + HCL_DEBUG_ASSERT(algoError == SVA_OK); + //Retrieve corresponding errorType value + algoError=sva_DC_Mpeg2_GetLastErrorType(instanceNum, &errorType); + HCL_DEBUG_ASSERT(algoError == SVA_OK); + + switch (pConf->mode) { + + case SVA_CODEC_IMAGE_MODE : + + //generate inputBitstreamBuffer related events + ffError=POP_FIFO_ELEM(pDesc->inputBitstreamFifos.inUse,t_sva_buffer_id,pEvent->bufferId); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + //the buffer is then voided + CHECK_TABLE_OVERFLOW(*pNbEventsRaised, maxOfEvent, SVA_INTERNAL_VIDEO_DECODER_ERROR); + pEvent->eventId = SVA_EVENT_BUFFER_VOIDED; + pEvent->serviceId = serviceId; + pEvent->eventTimestamp = (t_sva_timestamp_value) eventTimestamp; + pEvent->eventDate = (t_sva_timestamp_value) eventDate; + pEvent->extraInfo= 0; + pDesc->status.eventStats.voidedCounter++; + /*update buffer status*/ + sva_BM_UpdateBufferStatus(pEvent->bufferId,SVA_BUFFER_VOIDED,eventTimestamp); + nbEvents++; + //*pNbEventsRaised=nbEvents; + pEvent = &pEventDesc[nbEvents]; + + //Flush user bitstream buffer + blmError=sva_BLM_RemoveBufferFromList(bitstreamBufferListId,&bufferId); + HCL_DEBUG_ASSERT(blmError == SVA_BLM_OK); + + + //Flush fake bitstream buffer if any + blmError=sva_BLM_RemoveBufferFromList(bitstreamBufferListId,&bufferId); + HCL_DEBUG_ASSERT(blmError == SVA_BLM_OK); + + //Push fake buffer in its fifo + ffError=PUSH_FIFO_ELEM(Mpeg2Desc[instanceNum].fakeBitstreamFifo,t_sva_buffer_id,bufferId); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + break; + + case SVA_CODEC_SEGMENTED_MODE : + + lastBufferId = INVALID_BUFFER_ID; + POP_FIFO_ELEM(pDesc->lastPushedBufferFifo.inUse,t_sva_buffer_id,lastBufferId); + + //generate inputBitstreamBuffer related events + while(IS_FIFO_EMPTY(pDesc->inputBitstreamFifos.inUse) == FALSE) { + + ffError=READ_FIFO_ELEM(pDesc->inputBitstreamFifos.inUse,t_sva_buffer_id,bufferId); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + + if (bufferId != lastBufferId) { + + ffError=POP_FIFO_ELEM(pDesc->inputBitstreamFifos.inUse,t_sva_buffer_id,bufferId); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + + //Flush all bitstream buffers of the frame + blmError=sva_BLM_RemoveBufferFromList(bitstreamBufferListId,&bufferId); + HCL_DEBUG_ASSERT(blmError==SVA_BLM_OK); + + //the buffer is then voided + CHECK_TABLE_OVERFLOW(*pNbEventsRaised, maxOfEvent, SVA_INTERNAL_VIDEO_DECODER_ERROR); + pEvent->bufferId = bufferId; + pEvent->eventId = SVA_EVENT_BUFFER_VOIDED; + pEvent->serviceId = serviceId; + pEvent->eventTimestamp = (t_sva_timestamp_value) eventTimestamp; + pEvent->eventDate = (t_sva_timestamp_value) eventDate; + pEvent->extraInfo= 0; + pDesc->status.eventStats.voidedCounter++; + /*update buffer status*/ + sva_BM_UpdateBufferStatus(pEvent->bufferId,SVA_BUFFER_VOIDED,eventTimestamp); + + nbEvents++; + //*pNbEventsRaised=nbEvents; + pEvent = &pEventDesc[nbEvents]; + } + else break; + } + //Flush fake bitstream buffer if any + blmError=sva_BLM_RemoveBufferFromList(bitstreamBufferListId,&bufferId); + HCL_DEBUG_ASSERT(blmError == SVA_BLM_OK); + //Push fake buffer in its fifo + ffError=PUSH_FIFO_ELEM(Mpeg2Desc[instanceNum].fakeBitstreamFifo,t_sva_buffer_id,bufferId); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + + break; + + case SVA_CODEC_STREAM_MODE : + + //generate inputBitstreamBuffer related events + lastBufferId = INVALID_BUFFER_ID; + POP_FIFO_ELEM(pDesc->lastPushedBufferFifo.inUse,t_sva_buffer_id,lastBufferId); + + do { + if (IS_FIFO_EMPTY(pDesc->inputBitstreamFifos.inUse)==TRUE) break; + ffError=POP_FIFO_ELEM(pDesc->inputBitstreamFifos.inUse, t_sva_buffer_id, bufferId); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + + if (bufferId != lastBufferId) { + //the buffer is then voided + CHECK_TABLE_OVERFLOW(*pNbEventsRaised, maxOfEvent, SVA_INTERNAL_VIDEO_DECODER_ERROR); + pEvent->eventId = SVA_EVENT_BUFFER_VOIDED; + pEvent->bufferId = bufferId; + pEvent->serviceId = serviceId; + pEvent->eventTimestamp = (t_sva_timestamp_value) eventTimestamp; + pEvent->eventDate = (t_sva_timestamp_value) eventDate; + pEvent->extraInfo= 0; + pDesc->status.eventStats.voidedCounter++; + /*update buffer status*/ + sva_BM_UpdateBufferStatus(pEvent->bufferId,SVA_BUFFER_VOIDED,eventTimestamp); + + nbEvents++; + //*pNbEventsRaised=nbEvents; + pEvent = &pEventDesc[nbEvents]; + } + + blmError=sva_BLM_RemoveBufferFromList(bitstreamBufferListId,&bufferId); + HCL_DEBUG_ASSERT(blmError!=SVA_BLM_LIST_EMPTY); + + } while (bufferId != lastBufferId); + + + //Flush fake bitstream buffer if any + blmError=sva_BLM_RemoveBufferFromList(bitstreamBufferListId,&bufferId); + HCL_DEBUG_ASSERT(blmError == SVA_BLM_OK); + + //Push fake buffer in its fifo + ffError=PUSH_FIFO_ELEM(Mpeg2Desc[instanceNum].fakeBitstreamFifo,t_sva_buffer_id,bufferId); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + break; + + default : + return SVA_NOT_SUPPORTED_YET; + /* break; PCLint warning removal ...(unreachable) */ + + } + /*update status descriptor*/ + + if (errorType!=0) + { + pDesc->status.errorId=SVA_DECODER_TASK_PARAMETER_ERROR; + pDesc->status.eventStats.errorCounter++; + } + else {pDesc->status.errorId=SVA_DECODER_NO_ERROR;} + + + ffError=POP_FIFO_ELEM(pMpeg2Desc->referenceHandlerOutFifo,t_sva_Mpeg2_reference_handler, referenceHandlerOut); + if (ffError!= SVA_FIFO_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + + if (referenceHandlerOut.pictureStructure == PICTURE_STRUCTURE_FRAME || referenceHandlerOut.pictureStructure != fieldStreamType) + { + + //Fwd image buffer available as read only: HV_EVENT_BUFFER_FILLED_READ_ONLY + ffError=POP_FIFO_ELEM(pDesc->outputImageFifos.inUse,t_sva_buffer_id,outputImageBuffer); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + + + switch(referenceHandlerOut.pictureType) { + case PICTURE_SLICE_I: + case PICTURE_SLICE_P: + if (pMpeg2Desc->lastPrevRefBuffer != INVALID_BUFFER_ID) + { + CHECK_TABLE_OVERFLOW(nbEvents, maxOfEvent, SVA_INTERNAL_VIDEO_DECODER_ERROR); + pEvent->eventId = SVA_EVENT_BUFFER_FILLED; + pEvent->bufferId= pMpeg2Desc->lastPrevRefBuffer; + pEvent->serviceId = serviceId; + pEvent->eventTimestamp = (t_sva_timestamp_value) eventTimestamp; + pEvent->eventDate = (t_sva_timestamp_value) eventDate; + pEvent->extraInfo= referenceHandlerOut.pictureStructure;//0; + pDesc->status.eventStats.filledCounter++; + /*update buffer status*/ + sva_BM_UpdateBufferStatus(pEvent->bufferId,SVA_BUFFER_FILLED,eventTimestamp); + nbEvents++; + pEvent = &pEventDesc[nbEvents]; + + pMpeg2Desc->lastPrevRefBuffer = INVALID_BUFFER_ID; + } + + if (pMpeg2Desc->lastRefBuffer != INVALID_BUFFER_ID) + { + CHECK_TABLE_OVERFLOW(nbEvents, maxOfEvent, SVA_INTERNAL_VIDEO_DECODER_ERROR); + pEvent->eventId = SVA_EVENT_BUFFER_FILLED_READ_ONLY; + pEvent->bufferId= pMpeg2Desc->lastRefBuffer; + pEvent->serviceId = serviceId; + pEvent->eventTimestamp = (t_sva_timestamp_value) eventTimestamp; + pEvent->eventDate = (t_sva_timestamp_value) eventDate; + pEvent->extraInfo= referenceHandlerOut.pictureStructure;//0; + pDesc->status.eventStats.readOnlyCounter++; + // no status update at this point - buffer stays locked up for HCL use + nbEvents++; + pEvent = &pEventDesc[nbEvents]; + + + pMpeg2Desc->lastPrevRefBuffer = pMpeg2Desc->lastRefBuffer; + } + + pMpeg2Desc->lastRefBuffer = outputImageBuffer; + break; + + default: // B, BI or skipped frames are not used as references + CHECK_TABLE_OVERFLOW(nbEvents, maxOfEvent, SVA_INTERNAL_VIDEO_DECODER_ERROR); + pEvent->eventId = SVA_EVENT_BUFFER_FILLED_READ_ONLY; + pEvent->bufferId= outputImageBuffer; + pEvent->serviceId = serviceId; + pEvent->eventTimestamp = (t_sva_timestamp_value) eventTimestamp; + pEvent->eventDate = (t_sva_timestamp_value) eventDate; + pEvent->extraInfo= referenceHandlerOut.pictureStructure;//0; + pDesc->status.eventStats.readOnlyCounter++; + // no status update at this point - buffer stays locked up for HCL use + nbEvents++; + pEvent = &pEventDesc[nbEvents]; + + CHECK_TABLE_OVERFLOW(nbEvents, maxOfEvent, SVA_INTERNAL_VIDEO_DECODER_ERROR); + pEvent->eventId = SVA_EVENT_BUFFER_FILLED; + pEvent->bufferId= outputImageBuffer; + pEvent->serviceId = serviceId; + pEvent->eventTimestamp = (t_sva_timestamp_value) eventTimestamp; + pEvent->eventDate = (t_sva_timestamp_value) eventDate; + pEvent->extraInfo= referenceHandlerOut.pictureStructure;//0; + pDesc->status.eventStats.filledCounter++; + /*update buffer status*/ + sva_BM_UpdateBufferStatus(pEvent->bufferId,SVA_BUFFER_FILLED,eventTimestamp); + nbEvents++; + pEvent = &pEventDesc[nbEvents]; + } + } + pDesc->status.nbImagesDecoded++; + + //deblocking buffer : HV_EVENT_BUFFER_FILLED + if(pDesc->confHandle.currentConf.outTheLoopFilter != SVA_NONE_FILTER) + { + ffError=POP_FIFO_ELEM(pDesc->outputDeblockingFifos.inUse,t_sva_buffer_id,pEvent->bufferId); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + //the buffer is then voided + CHECK_TABLE_OVERFLOW(nbEvents, maxOfEvent, SVA_INTERNAL_VIDEO_DECODER_ERROR); + pEvent->eventId = SVA_EVENT_BUFFER_FILLED; + pEvent->serviceId = serviceId; + pEvent->eventTimestamp = (t_sva_timestamp_value) eventTimestamp; + pEvent->eventDate = (t_sva_timestamp_value) eventDate; + pEvent->extraInfo= 0; + pDesc->status.eventStats.filledCounter++; + /*update buffer status*/ + sva_BM_UpdateBufferStatus(pEvent->bufferId,SVA_BUFFER_FILLED,eventTimestamp); + + nbEvents++; + //*pNbEventsRaised=nbEvents; + pEvent = &pEventDesc[nbEvents]; + } + + + *pNbEventsRaised=nbEvents; + + + return SVA_OK; + +} + + + + + +/****************************************************************************/ +/* NAME: sva_DC_Mpeg2_FlushBitstreams() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* OUT :none */ +/* */ +/* RETURN: */ +/* */ +/****************************************************************************/ +t_sva_error sva_DC_Mpeg2_FlushBitstreams(t_sva_service_instance_num instanceNum) +{ + + t_uint16 i=0; + t_sva_dc_descriptor *pDesc=&decodeDesc[instanceNum]; + t_sva_buffer_id bufferId; + t_sva_blm_error blmError; + t_sva_ff_error ffError; + + + for(i=0;iconfHandle.currentConf.mode) { + + case SVA_CODEC_IMAGE_MODE : + //update user buffer status if any + blmError=sva_BLM_RemoveBufferFromList(pDesc->bufferListIdArray[i][0],&removeBufferId); + if(blmError==SVA_BLM_OK) + { + //Flush fake bitstream buffer if any + blmError=sva_BLM_RemoveBufferFromList(pDesc->bufferListIdArray[i][0],&bufferId); + HCL_DEBUG_ASSERT(blmError == SVA_BLM_OK); + + //Push fake buffer in its fifo + ffError=PUSH_FIFO_ELEM(Mpeg2Desc[instanceNum].fakeBitstreamFifo,t_sva_buffer_id,bufferId); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + + } + break; + + case SVA_CODEC_SEGMENTED_MODE : + case SVA_CODEC_STREAM_MODE : + + // Flush LastPushedBuffer Fifos (push & inUse) + while (IS_FIFO_EMPTY(pDesc->lastPushedBufferFifo.push) == FALSE) { + ffError=POP_FIFO_ELEM(pDesc->lastPushedBufferFifo.push,t_sva_buffer_id,bufferId); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + } + + while (IS_FIFO_EMPTY(pDesc->lastPushedBufferFifo.inUse) == FALSE) { + ffError=POP_FIFO_ELEM(pDesc->lastPushedBufferFifo.inUse,t_sva_buffer_id,bufferId); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + } + + // Flush buffer list for every subtasks + bufferId = INVALID_BUFFER_ID; + do { + blmError=sva_BLM_RemoveBufferFromList(pDesc->bufferListIdArray[i][0],&bufferId); + } while (blmError==SVA_BLM_OK); + + // keep last valid buffer ID in the list because it's a fake buffer in case of Mpeg2 + if (bufferId != INVALID_BUFFER_ID) { + ffError=PUSH_FIFO_ELEM(Mpeg2Desc[instanceNum].fakeBitstreamFifo,t_sva_buffer_id,bufferId); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + } + + break; + + default : + return SVA_UNEXPECTED_API_CALL; + } + + } while(blmError == SVA_BLM_OK); + if(blmError != SVA_BLM_LIST_EMPTY) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + + } + + return SVA_OK; +} + + + +/****************************************************************************/ +/* NAME: t_sva_error sva_DC_Mpeg2_ResolveDependencies( */ +/* t_sva_service_instance_num instanceNum */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* */ +/* */ +/* PARAMETERS: */ +/* IN : t_sva_service_instance_num */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: t_sva_error */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_sva_error sva_DC_Mpeg2_ResolveDependencies(t_sva_service_instance_num instanceNum ) +{ + + + t_sva_dc_descriptor *pDesc=&decodeDesc[instanceNum]; + t_sva_Mpeg2_desc *pMpeg2Desc = &Mpeg2Desc[instanceNum]; + t_bool dependencyNotSolved=FALSE; + t_sva_buffer_id bufferId; + t_sva_buffer_id btBufferId; + t_sva_buffer_id prevRefBuffer = INVALID_BUFFER_ID; + t_sva_buffer_id refBuffer = INVALID_BUFFER_ID; + t_sva_dc_subtask_dependencies subtaskDep; + t_sva_dc_Mpeg2_dependencies_desc Mpeg2Dep; + t_sva_vdc_frame_buffer_in frameBufferIn; + t_sva_vdc_frame_buffer_out frameBufferOut; + t_sva_ff_error ffError; + t_sva_tm_error tmError; + t_sva_dc_error dcError; + t_sva_bm_error bmError; + t_physical_address phyAddr; + t_sva_error svaError; + t_sva_Mpeg2_reference_handler referenceHandler; + + /*enter loop where we try to solve dep for a maximum of subtasks*/ + while(IS_FIFO_EMPTY(pDesc->subtasksDependencyFifo.push)==FALSE && dependencyNotSolved==FALSE) + { + /*read subtask for which we will try to solve dependencies*/ + ffError=READ_FIFO_ELEM(pDesc->subtasksDependencyFifo.push,t_sva_dc_subtask_dependencies,subtaskDep); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + // read Mpeg2 dependency + ffError=READ_FIFO_ELEM(pMpeg2Desc->Mpeg2Dep.push,t_sva_dc_Mpeg2_dependencies_desc,Mpeg2Dep); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + /*******************************************/ + /* BITSTREAM Dependency */ + /*******************************************/ + if(subtaskDep.dependencies.inputBitstreamDep==NOT_RESOLVED_DEPENDENCY) //try to resolve bitstream dep. + { + svaError=sva_DC_Mpeg2_TryToInitBitstreamFields(instanceNum,&btBufferId); //Warning: this is a bitstream init and not an update + HCL_DEBUG_ASSERT(svaError==SVA_OK); + + decodeDesc[instanceNum].currentProgrammedBitstreamBuffer=btBufferId; + } + + /*read subtask for which we will try to solve dependencies*/ + ffError=READ_FIFO_ELEM(pDesc->subtasksDependencyFifo.push,t_sva_dc_subtask_dependencies,subtaskDep); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + + /*******************************************/ + /* OUTPUT IMAGE Dependency */ + /*******************************************/ + if( (subtaskDep.dependencies.outputImageDep==NOT_RESOLVED_DEPENDENCY) && //try to resolve image dep. + (subtaskDep.dependencies.inputBitstreamDep==RESOLVED_DEPENDENCY)) + { + if(IS_FIFO_EMPTY(pDesc->outputImageFifos.push)==FALSE) //1 image buffer available => resolve + { + //handle reference images + ffError=READ_FIFO_ELEM(pMpeg2Desc->referenceHandlerFifo,t_sva_Mpeg2_reference_handler, referenceHandler); + if (ffError!= SVA_FIFO_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + if(referenceHandler.pictureStructure == PICTURE_STRUCTURE_FRAME || referenceHandler.pictureStructure == fieldStreamType) + { + //Transfer elem from outputimage fifo push to inUse + dcError=sva_DC_TransferElemFromFifoToInUseFifo(instanceNum,SVA_IMAGE_BUFFER_TYPE, &bufferId ); + if (dcError!= SVA_DC_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + btFieldBufferId = bufferId; + + switch(referenceHandler.pictureType) { + case PICTURE_SLICE_I : + prevRefBuffer = INVALID_BUFFER_ID; + while ((IS_FIFO_EMPTY(pMpeg2Desc->refImageFifo) == FALSE) && (IS_FIFO_EMPTY(pMpeg2Desc->prevRefImageFifo)) == FALSE) + { + POP_FIFO_ELEM(pMpeg2Desc->refImageFifo, t_sva_buffer_id, prevRefBuffer); // ref becomes previous ref + POP_FIFO_ELEM(pMpeg2Desc->prevRefImageFifo, t_sva_buffer_id, refBuffer); // dummy pop, to keep fifos lined up + } + + ffError = PUSH_FIFO_ELEM(pMpeg2Desc->refImageFifo,t_sva_buffer_id,bufferId); + if (ffError!=SVA_FIFO_OK) return SVA_INTERNAL_FIFOS_FULL; + + ffError = PUSH_FIFO_ELEM(pMpeg2Desc->prevRefImageFifo,t_sva_buffer_id,prevRefBuffer); + if (ffError!=SVA_FIFO_OK) return SVA_INTERNAL_FIFOS_FULL; + + break; + case PICTURE_SLICE_P : // I and P pictures may be used as references + prevRefBuffer = INVALID_BUFFER_ID; + + if (IS_FIFO_EMPTY(pMpeg2Desc->refImageFifo) == FALSE) + READ_FIFO_ELEM(pMpeg2Desc->refImageFifo, t_sva_buffer_id, prevRefBuffer); + + ffError = PUSH_FIFO_ELEM(pMpeg2Desc->refImageFifo,t_sva_buffer_id,bufferId); + if (ffError!=SVA_FIFO_OK) return SVA_INTERNAL_FIFOS_FULL; + + ffError = PUSH_FIFO_ELEM(pMpeg2Desc->prevRefImageFifo,t_sva_buffer_id,prevRefBuffer); + if (ffError!=SVA_FIFO_OK) return SVA_INTERNAL_FIFOS_FULL; + break; // outputImage -> reference -> previous reference + + default: + // other picture type : B do nothing + break; + } + } + //update dependancy infos regarding image buffer + ffError=UPDATE_FIFO_ELEM_FIELD(pDesc->subtasksDependencyFifo.push,t_sva_dc_subtask_dependencies,.dependencies.outputImageDep,RESOLVED_DEPENDENCY); + if(referenceHandler.pictureStructure != PICTURE_STRUCTURE_FRAME && referenceHandler.pictureStructure != fieldStreamType) + { + bufferId = btFieldBufferId; + } + + + //update subtask to take into account new buffer: update addroutframebuf/dest buffer part field + bmError=sva_BM_GetBufferPhysicalAddress(bufferId,&phyAddr); + HCL_DEBUG_ASSERT(bmError==SVA_BM_OK); + + + + //Init subtask Field + tmError = sva_TM_GetSubTaskField( subtaskDep.subtaskId, + SVA_TM_DEC_ADDR_OUT_FRAME_BUFFER, + (t_logical_address) &frameBufferOut, + 0, + sizeof(t_sva_vdc_frame_buffer_out), + FALSE); + if (tmError!= SVA_TM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + frameBufferOut.addr_dest_buffer=phyAddr; + tmError=sva_TM_InitSubTaskField( subtaskDep.subtaskId, + SVA_TM_DEC_ADDR_OUT_FRAME_BUFFER, + (t_logical_address) &frameBufferOut, + sizeof(t_sva_vdc_frame_buffer_out)); + if (tmError!= SVA_TM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + + } + + + } + /*read subtask for which we will try to solve dependencies*/ + ffError=READ_FIFO_ELEM(pDesc->subtasksDependencyFifo.push,t_sva_dc_subtask_dependencies,subtaskDep); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + /*******************************************/ + /* REFERENCE Dependency */ + /*******************************************/ + if ( (Mpeg2Dep.referenceDep==NOT_RESOLVED_DEPENDENCY) && //try to resolve fwd and bwd ref buffer dep. + (subtaskDep.dependencies.inputBitstreamDep==RESOLVED_DEPENDENCY) && //input bitstr dep must be resolved to know the frame type + (subtaskDep.dependencies.outputImageDep==RESOLVED_DEPENDENCY)) { // image dep should be resolved to use it as a future ref + if(IS_FIFO_EMPTY(pMpeg2Desc->referenceHandlerFifo)==FALSE) + { // image dep should be resolved to use it as a future ref + //handle reference images + ffError=POP_FIFO_ELEM(pMpeg2Desc->referenceHandlerFifo,t_sva_Mpeg2_reference_handler, referenceHandler); + if (ffError!= SVA_FIFO_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + if(referenceHandler.pictureStructure == PICTURE_STRUCTURE_FRAME || referenceHandler.pictureStructure == fieldStreamType) + { + switch(referenceHandler.pictureType) { + case PICTURE_SLICE_I : // use no reference + frameBufferIn.addr_fwd_ref_buffer=NULL; + frameBufferIn.addr_bwd_ref_buffer=NULL; + fieldBufferIn.addr_fwd_ref_buffer=NULL; + fieldBufferIn.addr_bwd_ref_buffer=NULL; + break; + + case PICTURE_SLICE_P : // use only a fwd reference + ffError=POP_FIFO_ELEM(pMpeg2Desc->refImageFifo, t_sva_buffer_id, refBuffer); + if (ffError!= SVA_FIFO_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + bmError=sva_BM_GetBufferPhysicalAddress(refBuffer,&phyAddr); // get the address of the last decoded I- or P- picture + HCL_DEBUG_ASSERT(bmError==SVA_BM_OK); + frameBufferIn.addr_fwd_ref_buffer=phyAddr; // fill out the HAMAC structure with it + ffError=POP_FIFO_ELEM(pMpeg2Desc->prevRefImageFifo, t_sva_buffer_id, prevRefBuffer); // line up prevRef Fifo with Ref Fifo + if (ffError!= SVA_FIFO_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + frameBufferIn.addr_bwd_ref_buffer=NULL; // no backward ref needed to decode P frames + fieldBufferIn.addr_fwd_ref_buffer=phyAddr; + fieldBufferIn.addr_bwd_ref_buffer=NULL; + break; + + case PICTURE_SLICE_B : + ffError=READ_FIFO_ELEM(pMpeg2Desc->prevRefImageFifo, t_sva_buffer_id, prevRefBuffer); + if (ffError!= SVA_FIFO_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + bmError=sva_BM_GetBufferPhysicalAddress(prevRefBuffer,&phyAddr); // get the address of the previous ref I- or P- picture + HCL_DEBUG_ASSERT(bmError==SVA_BM_OK); + frameBufferIn.addr_fwd_ref_buffer=phyAddr; // fill out the HAMAC structure with it + + fieldBufferIn.addr_fwd_ref_buffer=phyAddr; + ffError=READ_FIFO_ELEM(pMpeg2Desc->refImageFifo, t_sva_buffer_id, refBuffer); + if (ffError!= SVA_FIFO_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + bmError=sva_BM_GetBufferPhysicalAddress(refBuffer,&phyAddr); // get the address of the last decoded I- or P- picture + HCL_DEBUG_ASSERT(bmError==SVA_BM_OK); + frameBufferIn.addr_bwd_ref_buffer=phyAddr; // to provide the backward reference image + fieldBufferIn.addr_bwd_ref_buffer=phyAddr; + break; + + default: + return SVA_NOT_SUPPORTED_YET; + } + } + if(referenceHandler.pictureStructure != PICTURE_STRUCTURE_FRAME && referenceHandler.pictureStructure != fieldStreamType) + { + frameBufferIn.addr_fwd_ref_buffer = fieldBufferIn.addr_fwd_ref_buffer; + frameBufferIn.addr_bwd_ref_buffer = fieldBufferIn.addr_bwd_ref_buffer; + } + //update dependancy infos regarding image buffer + ffError=UPDATE_FIFO_ELEM_FIELD(pMpeg2Desc->Mpeg2Dep.push,t_sva_dc_Mpeg2_dependencies_desc,.referenceDep,RESOLVED_DEPENDENCY); + + //update subtask to take into account new buffer: update addroutframebuf/dest buffer part field + tmError=sva_TM_InitSubTaskField(subtaskDep.subtaskId, + SVA_TM_DEC_ADDR_IN_FRAME_BUFFER, + (t_logical_address) &frameBufferIn, + sizeof(t_sva_vdc_frame_buffer_in)); + + } + } + /*******************************************/ + /* DEBLOCKING PARAM Dependency */ + /*******************************************/ + if(Mpeg2Dep.outputDeblockingDep==NOT_RESOLVED_DEPENDENCY) //try to resolve deblocking dep. + { + if(IS_FIFO_EMPTY(pDesc->outputDeblockingFifos.push)==FALSE) //1 deblocking buffer available => resolve + { + //Remove Deblocking buffer from fifo and stores it as bufferId + !! transfer to InUse fifo !! + dcError=sva_DC_TransferElemFromFifoToInUseFifo(instanceNum,SVA_PARAMS_BUFFER_TYPE, &bufferId ); + if (dcError!= SVA_DC_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + + //update dependancy infos regarding image buffer + ffError=UPDATE_FIFO_ELEM_FIELD(pMpeg2Desc->Mpeg2Dep.push,t_sva_dc_Mpeg2_dependencies_desc,.outputDeblockingDep,RESOLVED_DEPENDENCY); + + //update subtask to take into account new buffer: update addroutframebuf/dest buffer part field + bmError=sva_BM_GetBufferPhysicalAddress(bufferId,&phyAddr); + HCL_DEBUG_ASSERT(bmError==SVA_BM_OK); + + //Init subtask Field + tmError = sva_TM_GetSubTaskField( subtaskDep.subtaskId, + SVA_TM_DEC_ADDR_OUT_FRAME_BUFFER, + (t_logical_address) &frameBufferOut, + 0, + sizeof(t_sva_vdc_frame_buffer_out), + FALSE); + if (tmError!= SVA_TM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + frameBufferOut.addr_deblocking_param_buffer=phyAddr; + tmError=sva_TM_InitSubTaskField( subtaskDep.subtaskId, + SVA_TM_DEC_ADDR_OUT_FRAME_BUFFER, + (t_logical_address) &frameBufferOut, + sizeof(t_sva_vdc_frame_buffer_out)); + if (tmError!= SVA_TM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + } + } + + if(Mpeg2Dep.outputInfosDep==NOT_RESOLVED_DEPENDENCY) //try to resolve infos dep. + { + if(IS_FIFO_EMPTY(pDesc->outputInfosFifos.push)==FALSE) //1 infos buffer available => resolve + { + //Remove Info buffer from fifo and stores it as bufferId + !! transfer to InUse fifo !! + dcError=sva_DC_TransferElemFromFifoToInUseFifo(instanceNum,SVA_INFOS_BUFFER_TYPE, &bufferId ); + if (dcError!= SVA_DC_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + + //update dependancy infos regarding infos buffer + ffError=UPDATE_FIFO_ELEM_FIELD(pMpeg2Desc->Mpeg2Dep.push,t_sva_dc_Mpeg2_dependencies_desc,.outputInfosDep,RESOLVED_DEPENDENCY); + + //update subtask to take into account new buffer: update addroutframebuf/dest buffer part field + bmError=sva_BM_GetBufferPhysicalAddress(bufferId,&phyAddr); + HCL_DEBUG_ASSERT(bmError==SVA_BM_OK); + //Warning: in this case, should take into account ext bit + phyAddr=phyAddr+EXTERNAL_MEM_EXT_BIT; + + //Update subtask Field by address for paramout buffer + tmError=sva_TM_UpdateSubTaskField( SVA_TM_INTERMEDIATE_FIELD_TO_UPDATE, + subtaskDep.subtaskId, + SVA_TM_DEC_ADDR_OUT_PARAMETERS, + FCMD_NEW_ADDRESS, + phyAddr, + 0, + 0); + if (tmError!= SVA_TM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + } + } + + //Are all subtask dep resolved? + ffError = READ_FIFO_ELEM(decodeDesc[instanceNum].subtasksDependencyFifo.push,t_sva_dc_subtask_dependencies,subtaskDep);//update infosDep + ffError = READ_FIFO_ELEM(Mpeg2Desc[instanceNum].Mpeg2Dep.push,t_sva_dc_Mpeg2_dependencies_desc,Mpeg2Dep); + + if(sva_DC_Mpeg2_AreAllDependanciesResolved(&subtaskDep.dependencies, &Mpeg2Dep)==TRUE) + { + t_sva_tm_timestamp immediateTimeStamp={SVA_TM_IMMEDIATE,0}; + + /*pop subtask from list of subtask for which dep has to be solved*/ + ffError=POP_FIFO_ELEM(pDesc->subtasksDependencyFifo.push,t_sva_dc_subtask_dependencies,subtaskDep); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + ffError=PUSH_FIFO_ELEM(pDesc->subtasksDependencyFifo.inUse,t_sva_dc_subtask_dependencies,subtaskDep); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + + ffError=POP_FIFO_ELEM(pMpeg2Desc->Mpeg2Dep.push,t_sva_dc_Mpeg2_dependencies_desc,Mpeg2Dep); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + ffError=PUSH_FIFO_ELEM(pMpeg2Desc->Mpeg2Dep.inUse,t_sva_dc_Mpeg2_dependencies_desc,Mpeg2Dep); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + + /*update state machine*/ + sva_DC_UpdateInstanceStateMachine(instanceNum,SVA_DC_ALL_DEPENDENCIES_RESOLVED); + + /*add subtask to list of schedulable subtasks*/ + tmError=sva_TM_AddElemToSubTaskList(pDesc->subtasksListId,subtaskDep.subtaskId,&immediateTimeStamp,1); + HCL_DEBUG_ASSERT(tmError==SVA_TM_OK); + + } + else + { + dependencyNotSolved=TRUE; + } + + } + + + return SVA_OK; +} + + + + +/****************************************************************************/ +/* NAME: t_sva_error sva_DC_Mpeg2_CreateAndConfigSubtasksList( */ +/* t_sva_service_instance_num instanceNum */ +/* t_sva_service_id serviceId */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* create and configure the subtask list */ +/* */ +/* PARAMETERS: */ +/* IN : t_sva_service_instance_num */ +/* t_sva_service_id */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: t_sva_error */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_sva_error sva_DC_Mpeg2_CreateAndConfigSubtasksList(t_sva_service_instance_num instanceNum, t_sva_service_id serviceId) +{ + + t_sva_dc_descriptor *pDesc=&decodeDesc[instanceNum]; + t_sva_Mpeg2_desc *pMpeg2Desc = &Mpeg2Desc[instanceNum]; + t_sva_video_decoder_configuration *pConf=&pDesc->confHandle.currentConf; + t_sva_tm_task_ctrl_desc decodeTaskDesc; + t_sva_tm_error tmError; + t_sva_blm_error blmError; + t_sva_tm_subtask_type subtaskType; + t_sva_tm_postprocessing_type pppType; + t_sva_fw_features fwFeature; + t_uint32 i, j; + t_sva_block_id NewParamOutBlockId; + t_logical_address paramOutAddr; + t_sva_mm_error mmError=SVA_MM_OK; + t_sva_error svaError; + t_sva_vdc_internal_buf internalBuffer; + + t_uint32 nbBufferList=0; + t_size size; + t_sva_error status=SVA_OK; + t_sva_ff_error ffError; + //t_size imageSize=((((t_uint32)pConf->imageDesc.height)*((t_uint32)pConf->imageDesc.width)*3)/2); + t_size imageSize=128; + + imageSize=imageSize; + svaError=sva_DC_Mpeg2_GetNbBufferListByFrame(&nbBufferList); + HCL_DEBUG_ASSERT(svaError==SVA_OK); + /*create bitstream buffer list*/ + for(i=0;ibufferListIdArray[i][j]); + if (blmError!=SVA_BLM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + } + + } + + /*create subtasks*/ + decodeTaskDesc.memId=DECODE_DEFAULT_MEMORY_ID; + decodeTaskDesc.fieldnb=DECODE_FIELD_NUMBER; + decodeTaskDesc.pfieldctrldesc=(t_sva_tm_field_ctrl_desc *)defaultDecodeFieldDescArray; + + + svaError=sva_DC_Mpeg2_GetPPPType(instanceNum, &pppType); + HCL_DEBUG_ASSERT(svaError==SVA_OK); + + svaError=sva_DC_Mpeg2_GetSubTaskType(instanceNum, &subtaskType); + HCL_DEBUG_ASSERT(svaError==SVA_OK); + + for(i=0;isubtasksIdArray[i]); + + internalBuffer.addr_mv_history_buffer = pMpeg2Desc->addr_mv_history_buffer.physical; + + tmError=sva_TM_InitSubTaskField(pDesc->subtasksIdArray[i],SVA_TM_DEC_ADDR_INTERNAL_BUFFER,(t_uint32)&internalBuffer,sizeof(t_sva_vdc_internal_buf)); + if (tmError != SVA_TM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + + } + + /*create subtasklist*/ + { + + svaError=sva_DC_Mpeg2_GetFWFeatures(instanceNum, &fwFeature); + HCL_DEBUG_ASSERT(svaError==SVA_OK); + + tmError=sva_TM_CreateSubTaskList(SVA_TM_DECODE,serviceId,fwFeature,&pDesc->subtasksListId); + if (tmError != SVA_TM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + } + + /*Alloc and push paramout block*/ + size=sva_DC_Mpeg2_GetOutputParamsSize (instanceNum); + sva_MM_AllocBlock(SDRAM_ID, size, SVA_MM_ALIGN_WORD, &NewParamOutBlockId); + ffError=PUSH_FIFO_ELEM(decodeDesc[instanceNum].blockIdFifo,t_sva_block_id,NewParamOutBlockId); + if (ffError!= SVA_FIFO_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + mmError=sva_MM_GetBlockLogicalAddress(NewParamOutBlockId,¶mOutAddr); + if (mmError!= SVA_MM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + decodeDesc[instanceNum].paramOutAddr=paramOutAddr; + + + /* reset last used references */ //RAM: Different + pMpeg2Desc->lastRefBuffer = INVALID_BUFFER_ID; + pMpeg2Desc->lastPrevRefBuffer = INVALID_BUFFER_ID; + + + /* Set default common dependencies*/ + pDesc->defaultDep.outputImageDep=NOT_RESOLVED_DEPENDENCY; + pDesc->defaultDep.inputBitstreamDep=NOT_RESOLVED_DEPENDENCY; + //reference dependancy to handle B frames + pMpeg2Desc->defaultDep.referenceDep = NOT_RESOLVED_DEPENDENCY; + /* Set default Mpeg2 dependencies*/ + if(pConf->outTheLoopFilter != SVA_NONE_FILTER) + pMpeg2Desc->defaultDep.outputDeblockingDep=NOT_RESOLVED_DEPENDENCY; + else + pMpeg2Desc->defaultDep.outputDeblockingDep=INTERNAL_DEPENDENCY; + if(pConf->areInfosRequested == TRUE) + pMpeg2Desc->defaultDep.outputInfosDep=NOT_RESOLVED_DEPENDENCY; + else + pMpeg2Desc->defaultDep.outputInfosDep=INTERNAL_DEPENDENCY; + + /* Push subtask in subtasksDependencyFifo since they are ready to be solved*/ + for(i=0;isubtasksIdArray[i]; + subtaskDep.bitstreamBufferListId=pDesc->bufferListIdArray[i][0]; + subtaskDep.dependencies=pDesc->defaultDep; + Mpeg2DefaultDep = pMpeg2Desc->defaultDep; + ffError=PUSH_FIFO_ELEM(pDesc->subtasksDependencyFifo.push, t_sva_dc_subtask_dependencies, subtaskDep); + if (ffError!=SVA_FIFO_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + ffError=PUSH_FIFO_ELEM(pMpeg2Desc->Mpeg2Dep.push, t_sva_dc_Mpeg2_dependencies_desc, Mpeg2DefaultDep); + if (ffError!=SVA_FIFO_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + } + + return status; +} + +/****************************************************************************/ +/* NAME: sva_DC_Mpeg2_AreAllDependanciesResolved() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: This routine enables to check all dependancies related */ +/* to a subtask */ +/* PARAMETERS: */ +/* IN : t_sva_dc_subtask_dependencies subtaskDep : Subtask to check */ +/* OUT :none */ +/* */ +/* RETURN: */ +/* t_bool */ +/*--------------------------------------------------------------------------*/ +/* USE: NA */ +/* USED BY: NA */ +/****************************************************************************/ +PUBLIC t_bool sva_DC_Mpeg2_AreAllDependanciesResolved(t_sva_dc_dependencies_desc * commonDep, t_sva_dc_Mpeg2_dependencies_desc * Mpeg2Dep) +{ + + if((commonDep->outputImageDep !=NOT_RESOLVED_DEPENDENCY)&& + (Mpeg2Dep->outputInfosDep !=NOT_RESOLVED_DEPENDENCY)&& + (Mpeg2Dep->referenceDep !=NOT_RESOLVED_DEPENDENCY)&& + (commonDep->inputBitstreamDep !=NOT_RESOLVED_DEPENDENCY)&& + (Mpeg2Dep->outputDeblockingDep!=NOT_RESOLVED_DEPENDENCY)) + {return TRUE;} + else {return FALSE;} +} + +/****************************************************************************/ +/* NAME: sva_DC_Mpeg2_CheckInputDep() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: This routine enables to check all input dependancies related*/ +/* to a subtask */ +/* PARAMETERS: */ +/* IN : t_sva_service_instance_num */ +/* OUT :none */ +/* */ +/* RETURN: */ +/* t_bool */ +/*--------------------------------------------------------------------------*/ +/* USE: NA */ +/* USED BY: NA */ +/****************************************************************************/ +PUBLIC t_bool sva_DC_Mpeg2_CheckInputDep(t_sva_service_instance_num instanceNum) { + + t_sva_dc_descriptor *pDesc=&decodeDesc[instanceNum]; + t_bool inputDepResolved; + t_sva_ff_error ffError; + t_sva_dc_subtask_dependencies infosDep; + + ffError = READ_FIFO_ELEM(pDesc->subtasksDependencyFifo.push,t_sva_dc_subtask_dependencies,infosDep); + HCL_ASSERT(ffError == SVA_FIFO_OK); + + if (infosDep.dependencies.inputBitstreamDep == RESOLVED_DEPENDENCY) + inputDepResolved = TRUE; + else + inputDepResolved = FALSE; + + return inputDepResolved; +} + +/****************************************************************************/ +/* NAME: sva_DC_Mpeg2_CheckOutputDep() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: This routine enables to check all output dependancies */ +/* related to a subtask */ +/* PARAMETERS: */ +/* IN : t_sva_service_instance_num */ +/* OUT :none */ +/* */ +/* RETURN: */ +/* t_bool */ +/*--------------------------------------------------------------------------*/ +/* USE: NA */ +/* USED BY: NA */ +/****************************************************************************/ +PUBLIC t_bool sva_DC_Mpeg2_CheckOutputDep(t_sva_service_instance_num instanceNum) { + + t_sva_dc_descriptor *pDesc=&decodeDesc[instanceNum]; + t_sva_Mpeg2_desc *pMpeg2Desc = &Mpeg2Desc[instanceNum]; + t_bool outputDepResolved; + t_sva_ff_error ffError; + t_sva_dc_subtask_dependencies infosDep; + t_sva_dc_Mpeg2_dependencies_desc Mpeg2Dep; + + ffError = READ_FIFO_ELEM(pDesc->subtasksDependencyFifo.push,t_sva_dc_subtask_dependencies,infosDep); + HCL_ASSERT(ffError == SVA_FIFO_OK); + ffError = READ_FIFO_ELEM(pMpeg2Desc->Mpeg2Dep.push,t_sva_dc_Mpeg2_dependencies_desc, Mpeg2Dep); + HCL_ASSERT(ffError == SVA_FIFO_OK); + + if ( (Mpeg2Dep.outputInfosDep == RESOLVED_DEPENDENCY) || + (infosDep.dependencies.outputImageDep == RESOLVED_DEPENDENCY) || + (Mpeg2Dep.outputDeblockingDep == RESOLVED_DEPENDENCY)) + + outputDepResolved = TRUE; + else + outputDepResolved = FALSE; + + return outputDepResolved; +} + +/****************************************************************************/ +/* NAME: sva_DC_Mpeg2_HandleFakeEvent() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: This routine handle the fake event triggered after */ +/* a flush in or out command */ +/* PARAMETERS: */ +/* IN : t_sva_service_instance_num */ +/* OUT :none */ +/* */ +/* RETURN: */ +/* t_bool */ +/*--------------------------------------------------------------------------*/ +/* USE: NA */ +/* USED BY: NA */ +/****************************************************************************/ +PUBLIC t_sva_error sva_DC_Mpeg2_HandleFakeEvent( t_sva_tm_virtual_hw_event_id eventId, + t_sva_service_id serviceId, + t_sva_tm_subtask_id subtaskId, + t_uint32 eventTimestamp, + t_uint32 eventDate, + t_uint8 maxOfEvent, + t_uint32 *pNbEventsRaised, + t_sva_event_desc *pEventDesc) { + + t_sva_service_instance_num instanceNum = READ_INSTANCE_NUM_IN_SERVICE_ID(serviceId); + t_sva_dc_descriptor *pDesc=&decodeDesc[instanceNum]; + t_sva_Mpeg2_desc *pMpeg2Desc = &Mpeg2Desc[instanceNum]; + t_uint32 nbEvents = *pNbEventsRaised; + + // upon Flush out, free up reference buffers, otherwise keep them. + if (pDesc->state == SVA_DC_FLUSHING_OUT) { + + if (pMpeg2Desc->lastPrevRefBuffer != INVALID_BUFFER_ID) { + CHECK_TABLE_OVERFLOW(nbEvents, maxOfEvent, SVA_INTERNAL_VIDEO_DECODER_ERROR); + pEventDesc[nbEvents].eventId = SVA_EVENT_BUFFER_FILLED; + pEventDesc[nbEvents].serviceId = serviceId; + pEventDesc[nbEvents].bufferId = pMpeg2Desc->lastPrevRefBuffer; + pEventDesc[nbEvents].eventTimestamp = (t_sva_timestamp_value) eventTimestamp; + pEventDesc[nbEvents].eventDate = (t_sva_timestamp_value) eventDate; + pEventDesc[nbEvents].extraInfo=0; + pDesc->status.eventStats.filledCounter++; + /*update buffer status*/ + sva_BM_UpdateBufferStatus(pEventDesc[nbEvents].bufferId,SVA_BUFFER_FILLED,eventTimestamp); + nbEvents++; + } + + if (pMpeg2Desc->lastRefBuffer != INVALID_BUFFER_ID) { + CHECK_TABLE_OVERFLOW(nbEvents, maxOfEvent, SVA_INTERNAL_VIDEO_DECODER_ERROR); + pEventDesc[nbEvents].eventId = SVA_EVENT_BUFFER_FILLED_READ_ONLY; + pEventDesc[nbEvents].bufferId= pMpeg2Desc->lastRefBuffer; + pEventDesc[nbEvents].serviceId = serviceId; + pEventDesc[nbEvents].eventTimestamp = (t_sva_timestamp_value) eventTimestamp; + pEventDesc[nbEvents].eventDate = (t_sva_timestamp_value) eventDate; + pEventDesc[nbEvents].extraInfo= 0; + pDesc->status.eventStats.readOnlyCounter++; + // no status update at this point - buffer stays locked up for HCL use + nbEvents++; + + + CHECK_TABLE_OVERFLOW(nbEvents, maxOfEvent, SVA_INTERNAL_VIDEO_DECODER_ERROR); + pEventDesc[nbEvents].eventId = SVA_EVENT_BUFFER_FILLED; + pEventDesc[nbEvents].serviceId = serviceId; + pEventDesc[nbEvents].bufferId = pMpeg2Desc->lastRefBuffer; + pEventDesc[nbEvents].eventTimestamp = (t_sva_timestamp_value) eventTimestamp; + pEventDesc[nbEvents].eventDate = (t_sva_timestamp_value) eventDate; + pEventDesc[nbEvents].extraInfo=0; + pDesc->status.eventStats.filledCounter++; + /*update buffer status*/ + sva_BM_UpdateBufferStatus(pEventDesc[nbEvents].bufferId,SVA_BUFFER_FILLED,eventTimestamp); + nbEvents++; + } + + // resets reference buffers + pMpeg2Desc->lastPrevRefBuffer = INVALID_BUFFER_ID; + pMpeg2Desc->lastRefBuffer = INVALID_BUFFER_ID; + } + + *pNbEventsRaised = nbEvents; + + return SVA_OK; +} + +/****************************************************************************/ +/* NAME: sva_DC_Mpeg2_IsConfigurationValid() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: This routine checks is configuration is valid */ +/* PARAMETERS: */ +/* IN : */ +/* - pMpeg2Conf: configuration to check validity */ +/* - imageDesc: decoder image config to check */ +/* OUT :none */ +/* */ +/* RETURN: */ +/* - t_bool: configuration validity */ +/*--------------------------------------------------------------------------*/ +/* USE: NA */ +/* USED BY: NA */ +/****************************************************************************/ + +PRIVATE t_bool sva_DC_Mpeg2_IsConfigurationValid( +t_sva_video_decoder_algo_Mpeg2_configuration_params *pMpeg2Conf, +t_sva_image_desc imageDesc +) +{ + t_uint16 width; + t_uint16 height; + + HCL_ASSERT(pMpeg2Conf!=NULL); + + width = (imageDesc.width>>4)&0x1FF; + height = (imageDesc.height>>4)&0x1FF; + + /* The following relations must hold for Mpeg2/H263: + 1<=DFW[12:4]<=396 ; 1<=DFH[12:4]<=396; DFW[12:4]*DFH[12:4]<=1200 */ + CHECK_RANGE(width, 1, 396); + CHECK_RANGE(height, 1, 396); + if(width*height>1620) { return FALSE; } + + return TRUE; +} + +// End of file - sva_dc_Mpeg2.c --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/mpeg2/sva_dc_mpeg2.h @@ -0,0 +1,181 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ + +#ifndef __INC_SVA_DC_Mpeg2_H +#define __INC_SVA_DC_Mpeg2_H + +#include "hcl_defs.h" +#include "sva_decode.h" +#include "../sva_dc_algo.h" +#include "sva.h" +#include "sva_decodep.h" + +/******************************************************************************/ +/* Constants definitions */ +/******************************************************************************/ + +#define START_CODE_VALUE_SEQUENCE_HEADER 0x000001B3 +#define START_CODE_VALUE_SEQUENCE_EXTENSION 0x000001B5 +#define START_CODE_VALUE_PICTURE_HEADER 0x00000100 +#define START_CODE_VALUE_GOP 0x000001B8 + + +#define OFFSET_VIDEOSTARTMARKER_GOBLAYER 7 //6 bytes 50bits +#define MPEG2_DECODE_MAX_FIFO_SIZE DECODE_MAX_FIFO_SIZE + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/******************************************************************************/ +/* Types definitions */ +/******************************************************************************/ + +/***********************************/ +/*** Structure definition ***/ +/***********************************/ +typedef struct { + t_sva_buffer_id bitstreamBuffer; + t_sva_buffer_id fwdReferenceImage; + t_sva_buffer_id bwdReferenceImage; + t_sva_Mpeg2_picture_type pictureType; + t_uint16 pictureStructure; +} t_sva_Mpeg2_reference_handler; +/* + * Define the structure used to manage the subtasks dependency + */ +typedef struct { + t_sva_dc_dependencies_state referenceDep;//reference dependency + t_sva_dc_dependencies_state outputDeblockingDep; + t_sva_dc_dependencies_state outputInfosDep; +} t_sva_dc_Mpeg2_dependencies_desc; + +typedef struct { + t_sva_image_desc imageDesc; + t_sva_codec_mode codecMode; + t_sva_video_decoder_algo_Mpeg2_configuration_params staticParams; + t_sva_fifo fifoDynamicParams; //type: t_sva_decoder_algo_mpeg2_header_infos + t_sva_fifo fifoBitstream; //type: t_sva_bitstream_desc + t_sva_fifo referenceHandlerFifo; + t_sva_fifo referenceHandlerOutFifo; + t_sva_fifo refImageFifo; // Current reference Image FIFO + t_sva_fifo prevRefImageFifo; // Previous reference Image FIFO + t_sva_fifo fakeBitstreamFifo; + t_sva_dc_Mpeg2_dependencies_desc defaultDep; // default mpeg2 dependencies + t_sva_dc_fifo_dep Mpeg2Dep; + t_sva_vdc_Mpeg2_param_out lastFrameMpeg2ParamOut; + t_sva_vdc_Mpeg2_param_out statisticalMpeg2ParamOut; + t_system_address paramInOutAddress; + t_sva_block_id paramInOutBlockId; + t_sva_buffer_id lastRefBuffer; // Last reference Buffer ID + t_sva_buffer_id lastPrevRefBuffer; // Last Previous reference Buffer ID + t_system_address addr_mv_history_buffer; + t_sva_buffer_id addr_mv_history_buffer_id; +} t_sva_Mpeg2_desc; + +typedef enum { + SVA_DC_MPEG2_XXXX = SVA_LAST_ERROR, + SVA_DC_MPEG2_FIFO_LINKED_ERROR, + SVA_DC_MPEG2_FIFO_FULL_ERROR, + SVA_DC_MPEG2_YYYY, + SVA_DC_MPEG2_UNEXPECTED_API_CALL, + SVA_DC__MPEG2_ALGO_OK = HCL_OK +} t_sva_dc_mpeg2_algo_error; + +typedef struct { + t_uint32 Mpeg2SeqHeaderStartCode; + t_uint32 Mpeg2SeqExtensionStartCode; + t_uint32 Mpeg2GropuofpictureStartCode; + t_uint32 Mpeg2PicHeaderStartCode; +} t_Mpeg2_start_code; + +typedef struct { + t_sva_service_id serviceId; + t_sva_buffer_id bitstreamBuffer; + t_uint32 byteOffset; + t_uint32 bitOffset; + t_sva_video_decoder_algo_Mpeg2_header_infos headerInfos; +} t_sva_Mpeg2_SetHeaderInfosParam; + + +/******************************************************************************/ +/* PUBLIC Functions */ +/******************************************************************************/ +PUBLIC t_sva_error sva_DC_Mpeg2_Init(t_sva_service_instance_num, t_sva_codec_mode, t_sva_image_desc, const t_sva_dc_algo_configuration_params *); +PUBLIC t_sva_error sva_DC_Mpeg2_GetMemoryNeeds(t_sva_service_instance_num, t_size *); + +PUBLIC t_sva_error sva_DC_Mpeg2_ProvideMemoryNeeds( t_sva_service_instance_num ); +PUBLIC t_sva_error sva_DC_Mpeg2_Close(t_sva_service_instance_num); +PUBLIC t_sva_error sva_DC_Mpeg2_GetNextFrameParamsIn(t_sva_service_instance_num, t_sva_dc_algo_params_in *); +PUBLIC t_sva_error sva_DC_Mpeg2_GetNextFrameParamsInOut(t_sva_service_instance_num, t_sva_dc_algo_params_inout *); +PUBLIC t_sva_error sva_DC_Mpeg2_SetOutputParams(t_sva_service_instance_num, const t_sva_dc_algo_params_out *); +PUBLIC t_sva_error sva_DC_Mpeg2_GetNextFrameAddr(t_sva_service_instance_num, t_physical_address *, t_uint32 *, t_sva_buffer_id *); +PUBLIC t_sva_error sva_DC_Mpeg2_GetStatus(t_sva_service_instance_num, t_sva_dc_algo_status *, t_sva_dc_algo_status *); +PUBLIC t_sva_error sva_DC_Mpeg2_AreNextFrameInfosAvailable(t_sva_service_instance_num, t_bool *); +PUBLIC t_size sva_DC_Mpeg2_GetNextFrameParamsInSize(t_sva_service_instance_num); +PUBLIC t_size sva_DC_Mpeg2_GetNextFrameParamsInOutSize(t_sva_service_instance_num); +PUBLIC t_size sva_DC_Mpeg2_GetOutputParamsSize(t_sva_service_instance_num); + +PUBLIC t_sva_error sva_DC_Mpeg2_PushBitstreamBuffer(t_sva_service_instance_num, t_sva_buffer_id); +PUBLIC t_sva_error sva_DC_Mpeg2_GetStartCodeValue(t_uint32 *); +PUBLIC t_sva_error sva_DC_Mpeg2_GetLastErrorType (t_sva_service_instance_num, t_uint16 *); +PUBLIC t_sva_error sva_DC_Mpeg2_FlushFifos(t_sva_service_instance_num); +PUBLIC t_sva_error sva_DC_Mpeg2_DeleteFake(t_sva_service_instance_num); +PUBLIC t_sva_error sva_DC_Mpeg2_SubTaskFieldsFullUpdate ( t_sva_service_instance_num, t_sva_buffer_id *); +PUBLIC t_sva_error sva_DC_Mpeg2_GetParamsBufferSize(t_sva_service_instance_num, t_sva_push_mode, t_sva_filter_mode, t_uint32, t_uint32, t_size *); +PUBLIC t_sva_error sva_DC_Mpeg2_Push(t_sva_service_instance_num, t_sva_buffer_type, t_sva_buffer_id ); +PUBLIC t_sva_error sva_DC_Mpeg2_DispatchEOT( + t_sva_service_instance_num, + t_sva_tm_subtask_id, + t_sva_event_desc*, + t_sva_service_id, + t_uint32, + t_uint32, + t_uint32 *, + t_uint32, + t_sva_buffer_list_id); +PUBLIC t_sva_error sva_DC_Mpeg2_HandleFakeEvent( t_sva_tm_virtual_hw_event_id , + t_sva_service_id , + t_sva_tm_subtask_id , + t_uint32 , + t_uint32 , + t_uint8 , + t_uint32 *, + t_sva_event_desc *); +PUBLIC t_sva_error sva_DC_Mpeg2_TryToInitBitstreamFields(t_sva_service_instance_num, t_sva_buffer_id *); +PUBLIC t_sva_error sva_DC_Mpeg2_FlushBitstreams(t_sva_service_instance_num); +PUBLIC t_sva_error sva_DC_Mpeg2_InitHeaderInfos(t_sva_service_instance_num); +PUBLIC t_sva_error sva_DC_Mpeg2_GSetHeaderInfos(t_sva_service_instance_num, t_sva_service_id, t_sva_buffer_id, t_uint32, t_uint32, const t_sva_header_infos *); +PUBLIC t_sva_error sva_DC_Mpeg2_AssertEndOfBitstream(t_sva_service_instance_num, t_sva_service_id); +PUBLIC t_sva_error sva_DC_Mpeg2_ResolveDependencies(t_sva_service_instance_num); +PUBLIC t_sva_error sva_DC_Mpeg2_GetFWFeatures (t_sva_service_instance_num, t_sva_fw_features*); +PUBLIC t_sva_error sva_DC_Mpeg2_GetSubTaskType(t_sva_service_instance_num, t_sva_tm_subtask_type*); +PUBLIC t_sva_error sva_DC_Mpeg2_GetPPPType(t_sva_service_instance_num, t_sva_tm_postprocessing_type*); +PUBLIC t_sva_error sva_DC_Mpeg2_GetNbBufferListByFrame(t_uint32*); +PUBLIC t_sva_error sva_DC_Mpeg2_CreateAndConfigSubtasksList(t_sva_service_instance_num, t_sva_service_id ); +PUBLIC t_bool sva_DC_Mpeg2_AreAllDependanciesResolved(t_sva_dc_dependencies_desc *, t_sva_dc_Mpeg2_dependencies_desc *); +PUBLIC t_bool sva_DC_Mpeg2_CheckInputDep(t_sva_service_instance_num); +PUBLIC t_bool sva_DC_Mpeg2_CheckOutputDep(t_sva_service_instance_num); + +#ifdef __cplusplus +} /* allow C++ to use these headers */ +#endif /* __cplusplus */ + +#endif /* __INC_sva_DC_Mpeg2_H */ +/* End of file - sva_dc_mpeg2.h */ --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/mpeg2/sva_dc_mpeg2p.c @@ -0,0 +1,789 @@ +//*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ + + +/*------------------------------------------------------------------------ + * Includes + *----------------------------------------------------------------------*/ + +#include "hcl_defs.h" +#include "sva_host_interface.h" +#include "sva_memorymgt.h" +#include "sva_buffermgt.h" +#include "sva_fifo.h" + +#include "../sva_decodep.h" +#include "../sva_decodepp.h" +#include "sva_service.h" + +#include "../sva_dc_algo.h" +#include "sva_dc_mpeg2.h" +#include "sva_dc_mpeg2p.h" +#include "sva_buffermgtp.h" + + + +extern PUBLIC t_sva_dc_descriptor decodeDesc[NUM_MAX_DECODE]; + +PRIVATE t_sva_vdc_Mpeg2_param_in Mpeg2ParamIn[NUM_MAX_DECODE]; +PRIVATE t_sva_vdc_Mpeg2_param_inout Mpeg2ParamInOut[NUM_MAX_DECODE]; +extern PUBLIC t_sva_Mpeg2_desc Mpeg2Desc[NUM_MAX_DECODE]; + + + +/****************************************************************************/ +/* NAME: sva_DC_Mpeg2_GetFWFeatures() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: return the requested fw feature for a Mpeg2 decoder */ +/* PARAMETERS: */ +/* IN : t_sva_service_instance_num instanceNum */ +/* OUT :t_sva_fw_features* pFwFeat */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/*--------------------------------------------------------------------------*/ +/* USE: NA */ +/* USED BY: NA */ +/****************************************************************************/ +PUBLIC t_sva_error sva_DC_Mpeg2_GetFWFeatures (t_sva_service_instance_num instanceNum, t_sva_fw_features* pFwFeat) +{ + + t_sva_fw_features fwFeature; + + fwFeature = SVA_FW_FEAT_MPEG2_DECODER; + + *pFwFeat = fwFeature; + return SVA_OK; +} + +/****************************************************************************/ +/* NAME: sva_DC_Mpeg2_GetSubTaskType() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: return the subtask type for Mpeg2 */ +/* PARAMETERS: */ +/* IN : t_sva_service_instance_num instanceNum */ +/* OUT :t_sva_tm_subtask_type* */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/*--------------------------------------------------------------------------*/ +/* USE: NA */ +/* USED BY: NA */ +/****************************************************************************/ +PUBLIC t_sva_error sva_DC_Mpeg2_GetSubTaskType(t_sva_service_instance_num instanceNum, t_sva_tm_subtask_type* pSubTask) +{ + t_sva_dc_descriptor *pDesc=&decodeDesc[instanceNum]; + t_sva_video_decoder_configuration *pConf=&pDesc->confHandle.currentConf; + if(pConf->transformId==SVA_DECODER_MPEG2_MP_ML) + { + *pSubTask=SVA_TM_DECODE_MPEG2; + } + return SVA_OK; + +} +/****************************************************************************/ +/* NAME: sva_DC_Mpeg2_GetPPPType() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: return the post processor parameter type */ +/* PARAMETERS: */ +/* IN : t_sva_service_instance_num instanceNum */ +/* OUT :t_sva_tm_postprocessing_type * */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/*--------------------------------------------------------------------------*/ +/* USE: NA */ +/* USED BY: NA */ +/****************************************************************************/ +PUBLIC t_sva_error sva_DC_Mpeg2_GetPPPType(t_sva_service_instance_num instanceNum, t_sva_tm_postprocessing_type* pPostProc) +{ + + t_sva_dc_descriptor *pDesc=&decodeDesc[instanceNum]; + t_sva_video_decoder_configuration *pConf=&pDesc->confHandle.currentConf; + + if (pConf->outTheLoopFilter == SVA_NONE_FILTER) + *pPostProc= SVA_TM_NO_POST_PROCESSING; + else + *pPostProc= SVA_TM_DEBLOCKING_DERINGING_OUT_LOOP; + + return SVA_OK; + +} +/****************************************************************************/ +/* NAME: sva_DC_Mpeg2_GetNbBufferListByFrame() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: return the number of buffer list per decode subtask */ +/* PARAMETERS: */ +/* IN : --- */ +/* OUT : constant 1 value */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/*--------------------------------------------------------------------------*/ +/* USE: NA */ +/* USED BY: NA */ +/****************************************************************************/ + +PUBLIC t_sva_error sva_DC_Mpeg2_GetNbBufferListByFrame(t_uint32* pNbBUfferList) +{ + * pNbBUfferList = 1; + return SVA_OK; +} + + +/****************************************************************************/ +/* NAME: sva_DC_Mpeg2_GetNextFrameParamsIn() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: This routine provides t_sva_vdc_Mpeg2_param_in data */ +/* that will be used by decode module to update in_param fields*/ +/* PARAMETERS: */ +/* IN : t_sva_service_instance_num instanceNum */ +/* OUT :t_sva_algo_params *algoParamsIn */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/*--------------------------------------------------------------------------*/ +/* USE: NA */ +/* USED BY: NA */ +/****************************************************************************/ +PUBLIC t_sva_error sva_DC_Mpeg2_GetNextFrameParamsIn( + t_sva_service_instance_num instanceNum, + t_sva_dc_algo_params_in *algoParamsIn) +{ + t_uint32 i; + t_sva_ff_error ffError; + t_sva_video_decoder_algo_Mpeg2_header_infos dynamicParams; + t_logical_address * inParameters = (t_logical_address *)algoParamsIn; + + HCL_ASSERT(algoParamsIn!=NULL); + + //Dynamic param + ffError=POP_FIFO_ELEM(Mpeg2Desc[instanceNum].fifoDynamicParams,t_sva_video_decoder_algo_Mpeg2_header_infos,dynamicParams); + if (ffError!= SVA_FIFO_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + + Mpeg2ParamIn[instanceNum].vertical_size = dynamicParams.vertical_size; + Mpeg2ParamIn[instanceNum].mb_width = dynamicParams.mb_width; + Mpeg2ParamIn[instanceNum].mb_height = dynamicParams.mb_height; + + + for(i=0;i<64;i++) + { + Mpeg2ParamIn[instanceNum].intra_quantizer_matrix[i]=dynamicParams.intra_quantizer_matrix[i]; + Mpeg2ParamIn[instanceNum].non_intra_quantizer_matrix[i]=dynamicParams.non_intra_quantizer_matrix[i]; + //Mpeg2ParamIn[instanceNum].intra_quantizer_matrix[i ] = (t_sva_param_subfield)Mpeg2Desc[instanceNum].dynamicParams.intra_quantizer_matrix[i]; + //Mpeg2ParamIn[instanceNum].non_intra_quantizer_matrix[i] = (t_sva_param_subfield)Mpeg2Desc[instanceNum].dynamicParams.intra_quantizer_matrix[i]; + } + /* memcpy( Mpeg2ParamIn[instanceNum].intra_quantizer_matrix, + dynamicParams.intra_quantizer_matrix, + sizeof(t_ushort_value)*64); + memcpy( Mpeg2ParamIn[instanceNum].non_intra_quantizer_matrix, + dynamicParams.non_intra_quantizer_matrix, + sizeof(t_ushort_value)*64);*/ + + Mpeg2ParamIn[instanceNum].picture_coding_type = dynamicParams.picture_coding_type; + Mpeg2ParamIn[instanceNum].full_pel_forward_vector = dynamicParams.full_pel_forward_vector; + Mpeg2ParamIn[instanceNum].forward_f_code = dynamicParams.forward_f_code; + Mpeg2ParamIn[instanceNum].full_pel_backward_vector = dynamicParams.full_pel_backward_vector; + Mpeg2ParamIn[instanceNum].backward_f_code = dynamicParams.backward_f_code; + + Mpeg2ParamIn[instanceNum].f_code[0][0] = dynamicParams.f_code[0][0]; + Mpeg2ParamIn[instanceNum].f_code[0][1] = dynamicParams.f_code[0][1]; + Mpeg2ParamIn[instanceNum].f_code[1][0] = dynamicParams.f_code[1][0]; + Mpeg2ParamIn[instanceNum].f_code[1][1] = dynamicParams.f_code[1][1]; + + Mpeg2ParamIn[instanceNum].intra_dc_precision = dynamicParams.intra_dc_precision; + Mpeg2ParamIn[instanceNum].picture_structure = dynamicParams.picture_structure; + Mpeg2ParamIn[instanceNum].top_field_first = dynamicParams.top_field_first; + Mpeg2ParamIn[instanceNum].frame_pred_frame_dct = dynamicParams.frame_pred_frame_dct; + + Mpeg2ParamIn[instanceNum].concealment_motion_vectors = dynamicParams.concealment_motion_vectors; + Mpeg2ParamIn[instanceNum].q_scale_type = dynamicParams.q_scale_type; + Mpeg2ParamIn[instanceNum].intra_vlc_format = dynamicParams.intra_vlc_format; + Mpeg2ParamIn[instanceNum].alternate_scan = dynamicParams.alternate_scan; + + Mpeg2ParamIn[instanceNum].scalable_mode = dynamicParams.scalable_mode; + + Mpeg2ParamIn[instanceNum].MPEG2_Flag = dynamicParams.MPEG2_Flag; + Mpeg2ParamIn[instanceNum].reserved1 = 0; + + + *inParameters = (t_logical_address)(&Mpeg2ParamIn[instanceNum]); + + return SVA_OK; +} + +/****************************************************************************/ +/* NAME: sva_DC_Mpeg2_GetNextFrameParamsInOut() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: This routine provides t_sva_vdc_Mpeg2_param_inout data */ +/* that will be used by decode module to update inout_param fields*/ +/* PARAMETERS: */ +/* IN : t_sva_service_instance_num instanceNum */ +/* OUT :t_sva_algo_params *algoParamsInOut */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/*--------------------------------------------------------------------------*/ +/* USE: NA */ +/* USED BY: NA */ +/****************************************************************************/ +PUBLIC t_sva_error sva_DC_Mpeg2_GetNextFrameParamsInOut( + t_sva_service_instance_num instanceNum, + t_sva_dc_algo_params_inout *algoParamsInOut) +{ + t_logical_address * inOutParameters = (t_logical_address *)algoParamsInOut; + + HCL_ASSERT(algoParamsInOut!=NULL); + + Mpeg2ParamInOut[instanceNum].reserved_1 = 0; + Mpeg2ParamInOut[instanceNum].reserved_2 = 0; + Mpeg2ParamInOut[instanceNum].reserved_3 = 0; + Mpeg2ParamInOut[instanceNum].reserved_4 = 0; + + + *inOutParameters = (t_logical_address)(&Mpeg2ParamInOut[instanceNum]); + + return SVA_OK; +} + + +/****************************************************************************/ +/* NAME: sva_DC_Mpeg2_GetNextFrameAddr() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: This routine provides infos to fill bitstream_buf_position */ +/* subtask subfields */ +/* PARAMETERS: */ +/* IN : t_sva_service_instance_num instanceNum */ +/* OUT :t_physical_address *bitstreamStart */ +/* t_uint32 *bitstreamOffset */ +/* t_sva_buffer_id *bitstreamBufferId */ +/* t_bool *botEnable */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/*--------------------------------------------------------------------------*/ +/* USE: NA */ +/* USED BY: NA */ +/****************************************************************************/ +PUBLIC t_sva_error sva_DC_Mpeg2_GetNextFrameAddr( + t_sva_service_instance_num instanceNum, + t_physical_address *bitstreamStart, + t_uint32 *bitstreamOffset, + t_sva_buffer_id *bitstreamBufferId + ) +{ + t_sva_ff_error ffError; + t_sva_bitstream_desc bitstreamDesc; + + HCL_ASSERT(bitstreamStart!=NULL); + HCL_ASSERT(bitstreamOffset!=NULL); + HCL_ASSERT(bitstreamBufferId!=NULL); + + ffError=POP_FIFO_ELEM(Mpeg2Desc[instanceNum].fifoBitstream,t_sva_bitstream_desc,bitstreamDesc); + if (ffError!= SVA_FIFO_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + + *bitstreamStart = bitstreamDesc.bitstreamPosition.addr_bitstream_start ; //in bytes + Should be aligned on 16 bytes + *bitstreamOffset = bitstreamDesc.bitstreamPosition.bitstream_offset; //Is the offset in bits between aligned address and provided no aligned address in byte + *bitstreamBufferId = bitstreamDesc.relatedBufferId; + + return SVA_OK; +} + + + +/****************************************************************************/ +/* NAME: sva_DC_Mpeg2_AreNextFrameInfosAvailable() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: This routine enables user to have a status on availability */ +/* of Bt buffer and also associated param */ +/* corresponds to FifoBitstream NOT Empty && */ +/* fifoDynamicParams NOT Empty */ +/* PARAMETERS: */ +/* IN : t_sva_service_instance_num instanceNum */ +/* OUT :t_bool *infosAvailable */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/*--------------------------------------------------------------------------*/ +/* USE: NA */ +/* USED BY: NA */ +/****************************************************************************/ +PUBLIC t_sva_error sva_DC_Mpeg2_AreNextFrameInfosAvailable( + t_sva_service_instance_num instanceNum, + t_bool *infosAvailable) +{ + t_bool IsFifoBtEmpty; + t_bool IsFifoParamEmpty; + + HCL_ASSERT(infosAvailable!=NULL); + + IsFifoBtEmpty=(t_bool)IS_FIFO_EMPTY(Mpeg2Desc[instanceNum].fifoBitstream); + IsFifoParamEmpty=(t_bool)IS_FIFO_EMPTY(Mpeg2Desc[instanceNum].fifoDynamicParams); + + *infosAvailable= (t_bool)!(IsFifoBtEmpty || IsFifoParamEmpty); + + return SVA_OK; +} + + +/****************************************************************************/ +/* NAME: sva_DC_Mpeg2_GetLastErrorType() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: This routine gives the value of the error type of last Mpeg2*/ +/* decode subtask: should be called after sva_DC_Mpeg2_SetOutputParams*/ +/* This is called inside sva_DC_DispatchHWVirtualEvent() */ +/* PARAMETERS: */ +/* OUT :t_uint16 *errorType */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/*--------------------------------------------------------------------------*/ +/* USE: NA */ +/* USED BY: NA */ +/****************************************************************************/ +PUBLIC t_sva_error sva_DC_Mpeg2_GetLastErrorType (t_sva_service_instance_num instanceNum, t_uint16 *pErrorType ) +{ + HCL_ASSERT(pErrorType!=NULL); + + *pErrorType= Mpeg2Desc[instanceNum].lastFrameMpeg2ParamOut.error_type; + + return SVA_OK; +} + + +/****************************************************************************/ +/* NAME: sva_DC_Mpeg2_GetStartCodeValue() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: This routine gives the value of the start code to be used by*/ +/* fake bitstream buffer for ERC */ +/* This is called inside sva_DC_ProvideInternalNeeds() */ +/* PARAMETERS: */ +/* OUT :t_Mpeg2_start_code *startCodeValue */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/*--------------------------------------------------------------------------*/ +/* USE: NA */ +/* USED BY: NA */ +/****************************************************************************/ +PUBLIC t_sva_error sva_DC_Mpeg2_GetStartCodeValue ( t_uint32 *pStartCodeValue ) +{ + t_Mpeg2_start_code StartCode; + + HCL_ASSERT(pStartCodeValue!=NULL); + + StartCode.Mpeg2PicHeaderStartCode = 0x01;//START_CODE_VALUE_PICTURE_HEADER; + + *pStartCodeValue = (t_uint32)(&StartCode); + + return SVA_OK; +} + + + +/****************************************************************************/ +/* NAME: sva_DC_Mpeg2_SubTaskFieldsFullUpdate() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: - This routine tries to init ParamIn (algo specific), */ +/* ParamInOut, BitstreamBufInit of subtask in top of dep fifo */ +/* - turns the bitstream dependency flag to RESOLVED_DEPENDENCY*/ +/* PARAMETERS: */ +/* IN : t_uint8 instanceNum */ +/* OUT :none */ +/* */ +/* RETURN: */ +/* t_sva_dc_error */ +/*--------------------------------------------------------------------------*/ +/* USE: NA */ +/* USED BY: NA */ +/****************************************************************************/ +PUBLIC t_sva_error sva_DC_Mpeg2_SubTaskFieldsFullUpdate (t_sva_service_instance_num instanceNum, t_sva_buffer_id *pBitstreamBufferId) +{ + t_sva_blm_error blmError; + t_sva_bitstream_buffer_pos bitstreamPos; + t_physical_address bitstreamBufferStartAddr=0; + t_sva_buffer_id bitstreamBufferId; + t_sva_ff_error ffError=SVA_FIFO_OK; + t_sva_tm_error tmError; + + t_sva_dc_subtask_dependencies subtaskDep; + t_sva_buffer_list_id bitstreamBufferListId; + t_physical_address bitstreamStartAddr; + t_uint32 bitstreamOffset; + + + t_sva_error algoError=SVA_OK; +// t_logical_address algoParamsInAddr=0; + t_logical_address algoParamsInOutAddr=0; + t_sva_dc_algo_params_in * algoParamsInAddr; + + t_sva_dc_descriptor *pDesc=&decodeDesc[instanceNum]; + + //Find suitable subtask and bitstream buffer list + ffError=READ_FIFO_ELEM(pDesc->subtasksDependencyFifo.push,t_sva_dc_subtask_dependencies,subtaskDep); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + bitstreamBufferListId=subtaskDep.bitstreamBufferListId; + + algoError=sva_DC_Mpeg2_GetNextFrameAddr(instanceNum, &bitstreamStartAddr, &bitstreamOffset, &bitstreamBufferId); + HCL_DEBUG_ASSERT(algoError == SVA_OK); + *pBitstreamBufferId=bitstreamBufferId; + + //Program add_bitstream_buf_struct field of v_bitstream_buf_pos structure + //Warning: there should be at least one buffer in list to ask for list physical address + blmError=sva_BLM_GetBufferListPhysicalAddress (bitstreamBufferListId, &bitstreamBufferStartAddr); + if (blmError!=SVA_BLM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + bitstreamPos.addr_bitstream_buf_struct=bitstreamBufferStartAddr; + bitstreamPos.addr_bitstream_start=bitstreamStartAddr; + bitstreamPos.bitstream_offset=bitstreamOffset; + + //update dependancy infos regarding bitstream buffer(and paramin) + ffError=UPDATE_FIFO_ELEM_FIELD(pDesc->subtasksDependencyFifo.push,t_sva_dc_subtask_dependencies,.dependencies.inputBitstreamDep,RESOLVED_DEPENDENCY); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + + /*update subtask */ + //BITSTREAM part + tmError=sva_TM_UpdateSubTaskField( SVA_TM_INTERMEDIATE_FIELD_TO_UPDATE, + subtaskDep.subtaskId, + SVA_TM_DEC_ADDR_IN_BITSTREAM_BUFFER, + FCMD_COPY, + (t_uint32) &bitstreamPos, + 0, + sizeof(t_sva_bitstream_buffer_pos)); + if (tmError!= SVA_TM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + //IN_PARAMETER part: should be done only one time for each subtask, ie one time as referenced by other subtasks + //FIXME: could be optimized as each subtask may be initialized just one time as static parameters + + algoError=sva_DC_Mpeg2_GetNextFrameParamsIn(instanceNum, (t_sva_dc_algo_params_in *)&algoParamsInAddr); + HCL_DEBUG_ASSERT(algoError == SVA_OK); + tmError=sva_TM_UpdateSubTaskField( SVA_TM_INTERMEDIATE_FIELD_TO_UPDATE, + subtaskDep.subtaskId, + SVA_TM_DEC_ADDR_IN_PARAMETERS, + FCMD_COPY, + (t_uint32) algoParamsInAddr, + 0, + sizeof(t_sva_vdc_Mpeg2_param_in)); + if (tmError!= SVA_TM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + + //IN_FRAME_PARAMETER part + algoError=sva_DC_Mpeg2_GetNextFrameParamsInOut(instanceNum, (t_sva_dc_algo_params_inout *)&algoParamsInOutAddr); + HCL_DEBUG_ASSERT(algoError == SVA_OK); + tmError=sva_TM_UpdateSubTaskField( SVA_TM_INTERMEDIATE_FIELD_TO_UPDATE, + subtaskDep.subtaskId, + SVA_TM_DEC_ADDR_IN_FRAME_PARAMETERS, + FCMD_COPY, + (t_uint32) algoParamsInOutAddr, + 0, + sizeof(t_sva_vdc_Mpeg2_param_inout)); + if (tmError!= SVA_TM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + +#if 0 + // program both SVA_TM_DEC_ADDR_OUT_FRAME_PARAMETERS and SVA_TM_DEC_ADDR_IN_FRAME_PARAMETERS registers + algoError = sva_DC_Mpeg2_SetupParamInOut(instanceNum, subtaskDep.subtaskId); + HCL_DEBUG_ASSERT(algoError == SVA_OK); +#endif + return SVA_OK; +} + + +/****************************************************************************/ +/* NAME: sva_DC_Mpeg2_TryToInitBitstreamFields() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: this function prepares the input bitstream buffer list, */ +/* based upon the bitstream mode : FRAME, SEGMENTED or STREAM */ +/* */ +/* PARAMETERS: */ +/* IN : t_uint8 instanceNum, */ +/* t_sva_buffer_id *pBitstreamBufferId */ +/* OUT :none */ +/* */ +/* RETURN: */ +/* t_sva_dc_error */ +/*--------------------------------------------------------------------------*/ +/* USE: NA */ +/* USED BY: NA */ +/****************************************************************************/ +PUBLIC t_sva_error sva_DC_Mpeg2_TryToInitBitstreamFields( + t_uint8 instanceNum, + t_sva_buffer_id *pBitstreamBufferId + ) +{ + t_sva_buffer_id bufferId, lastPushedBufferId; + t_sva_dc_descriptor *pDesc=&decodeDesc[instanceNum]; + t_sva_dc_subtask_dependencies subtaskDep; + t_bool infosAvailable; + + t_sva_ff_error ffError=SVA_FIFO_OK; + t_sva_blm_error blmError; + t_sva_bm_error bmError; + t_sva_dc_error dcError; + + t_sva_error algoError=SVA_OK; + + t_sva_video_decoder_configuration *pConf=&pDesc->confHandle.currentConf; + t_sva_buffer_list_id bitstreamBufferListId; + t_size bufferSize; + + HCL_ASSERT(pBitstreamBufferId!=NULL); + + algoError=sva_DC_Mpeg2_AreNextFrameInfosAvailable(instanceNum,&infosAvailable); + HCL_DEBUG_ASSERT(algoError == SVA_OK); + if(infosAvailable==TRUE) + { + //Find suitable subtask and bitstream buffer list + ffError=READ_FIFO_ELEM(pDesc->subtasksDependencyFifo.push,t_sva_dc_subtask_dependencies,subtaskDep); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + bitstreamBufferListId=subtaskDep.bitstreamBufferListId; + + //Bitstream buffer list management + switch (pConf->mode) { + case SVA_CODEC_IMAGE_MODE : + //Remove Bitstream buffer from fifo "push" and stores it in fifo "inUse" + dcError=sva_DC_TransferElemFromFifoToInUseFifo(instanceNum,SVA_BITSTREAM_BUFFER_TYPE, &bufferId ); + if (dcError!= SVA_DC_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + + //Add bitstream buffer as 1st elem of the list + blmError=sva_BLM_AddBufferInList(bitstreamBufferListId, bufferId); + if (blmError!=SVA_BLM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + + + //re-init first link->addr_buffer_start address (refer fw doc), subtracting -48 was leading modification in first address of physical address, VI9780 + { + t_sva_bm_buffer_list_desc *pBufferListInfo; + t_physical_address physicalAddress; + t_sva_bm_list_elem *pBufferInfo; + t_uint32 bufferListIndex; + pBufferListInfo = (t_sva_bm_buffer_list_desc *)(bitstreamBufferListId); + + //((t_sva_bm_buffer_desc*)bufferId)->bufferListInfo[0].bufferLink.addr_buffer_start = ((t_sva_bm_buffer_desc*)bufferId)->bufferSystemAddress.physical; + + if (sva_BM_GetBufferLinkInformation( pBufferListInfo->firstBufferId, &pBufferInfo, &physicalAddress) != SVA_BM_OK) + return(SVA_INTERNAL_VIDEO_DECODER_ERROR); + + if (sva_BLM_GetBufferListIndex(bitstreamBufferListId, pBufferListInfo->firstBufferId, &bufferListIndex) != SVA_BLM_OK) + return SVA_INTERNAL_VIDEO_DECODER_ERROR; + + pBufferInfo[bufferListIndex].bufferLink.addr_buffer_start = ((t_sva_bm_buffer_desc*)pBufferListInfo->firstBufferId)->bufferSystemAddress.physical; + } + + //extension of buffer start for ERC (and avoid fake BOW) + //48 bytes, ie 36 bytes aligned 16 to take into account internal bufferisation of SVA + blmError=sva_BLM_UpdateBufferMemoryBoundaryInBufferList (bitstreamBufferListId, BEGIN_OF_FIRST_BUFFER , -48); + if (blmError!=SVA_BLM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + + //add fake buffer (only a Start code) as 2nd element so as ERC could find a resync marker if requiered + //and avoid also fake EOW + ffError=POP_FIFO_ELEM(Mpeg2Desc[instanceNum].fakeBitstreamFifo,t_sva_buffer_id,bufferId); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + blmError=sva_BLM_AddBufferInList(bitstreamBufferListId, bufferId); + if (blmError!=SVA_BLM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + + + algoError = sva_DC_Mpeg2_SubTaskFieldsFullUpdate(instanceNum, pBitstreamBufferId); + HCL_DEBUG_ASSERT(algoError == SVA_OK); + + break; + + case SVA_CODEC_SEGMENTED_MODE : + + lastPushedBufferId = INVALID_BUFFER_ID; + ffError=POP_FIFO_ELEM(pDesc->lastPushedBufferFifo.push,t_sva_buffer_id,lastPushedBufferId); + if (ffError == SVA_FIFO_OK) + PUSH_FIFO_ELEM(pDesc->lastPushedBufferFifo.inUse,t_sva_buffer_id,lastPushedBufferId); + + do { + //Take all Bitstream buffers out of the "push" fifo and stores them into "inUse" fifo + dcError=sva_DC_TransferElemFromFifoToInUseFifo(instanceNum,SVA_BITSTREAM_BUFFER_TYPE, &bufferId ); + if (dcError!= SVA_DC_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + + //Add bitstream buffer as 1st elem of the list + blmError=sva_BLM_AddBufferInList(bitstreamBufferListId, bufferId); + if (blmError!=SVA_BLM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + + ffError = READ_FIFO_ELEM(pDesc->inputBitstreamFifos.push, t_sva_buffer_id, bufferId); + + } while ((bufferId != lastPushedBufferId) && (ffError != SVA_FIFO_EMPTY)); + + //re-init first link->addr_buffer_start address (refer fw doc), subtracting -48 was leading modification in first address of physical address, VI9780 + { + t_sva_bm_buffer_list_desc *pBufferListInfo; + t_physical_address physicalAddress; + t_sva_bm_list_elem *pBufferInfo; + t_uint32 bufferListIndex; + pBufferListInfo = (t_sva_bm_buffer_list_desc *)(bitstreamBufferListId); + + //((t_sva_bm_buffer_desc*)bufferId)->bufferListInfo[0].bufferLink.addr_buffer_start = ((t_sva_bm_buffer_desc*)bufferId)->bufferSystemAddress.physical; + + if (sva_BM_GetBufferLinkInformation( pBufferListInfo->firstBufferId, &pBufferInfo, &physicalAddress) != SVA_BM_OK) + return(SVA_INTERNAL_VIDEO_DECODER_ERROR); + + if (sva_BLM_GetBufferListIndex(bitstreamBufferListId, pBufferListInfo->firstBufferId, &bufferListIndex) != SVA_BLM_OK) + return SVA_INTERNAL_VIDEO_DECODER_ERROR; + + pBufferInfo[bufferListIndex].bufferLink.addr_buffer_start = ((t_sva_bm_buffer_desc*)pBufferListInfo->firstBufferId)->bufferSystemAddress.physical; + } + //extension of buffer start for ERC (and avoid fake BOW) + //48 bytes, ie 36 bytes aligned 16 to take into account internal bufferisation of SVA + //following lines should be removed when starting the buffer list with a fake buffer + blmError=sva_BLM_UpdateBufferMemoryBoundaryInBufferList (bitstreamBufferListId, BEGIN_OF_FIRST_BUFFER , -48); + if (blmError!=SVA_BLM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + + // Append a fake buffer at the end of the list if necessary + ffError=POP_FIFO_ELEM(Mpeg2Desc[instanceNum].fakeBitstreamFifo,t_sva_buffer_id,bufferId); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + blmError=sva_BLM_AddBufferInList(bitstreamBufferListId, bufferId); + if (blmError!=SVA_BLM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + + // program the subtask with all its dependencies + algoError = sva_DC_Mpeg2_SubTaskFieldsFullUpdate(instanceNum, pBitstreamBufferId); + HCL_DEBUG_ASSERT(algoError == SVA_OK); + + break; + + case SVA_CODEC_STREAM_MODE : + + lastPushedBufferId = INVALID_BUFFER_ID; + ffError=POP_FIFO_ELEM(pDesc->lastPushedBufferFifo.push,t_sva_buffer_id,lastPushedBufferId); + if (ffError == SVA_FIFO_OK) + PUSH_FIFO_ELEM(pDesc->lastPushedBufferFifo.inUse,t_sva_buffer_id,lastPushedBufferId); + + do { + // When an end of bitstream occurs, there is no lastPushedBuffer ID available + // -> push all the buffer left to the subtask's buffer list + if (IS_FIFO_EMPTY(pDesc->inputBitstreamFifos.push) == TRUE) break; + // Take Bitstream buffers out of the "push" fifo and stores them into "inUse" fifo + dcError=sva_DC_TransferElemFromFifoToInUseFifo(instanceNum,SVA_BITSTREAM_BUFFER_TYPE, &bufferId ); + if (dcError!= SVA_DC_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + + //Add bitstream buffer in the list + blmError=sva_BLM_AddBufferInList(bitstreamBufferListId, bufferId); + if (blmError!=SVA_BLM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + } while (bufferId != lastPushedBufferId); + + //re-init first link->addr_buffer_start address (refer fw doc), subtracting -48 was leading modification in first address of physical address, VI9780 + { + t_sva_bm_buffer_list_desc *pBufferListInfo; + t_physical_address physicalAddress; + t_sva_bm_list_elem *pBufferInfo; + t_uint32 bufferListIndex; + pBufferListInfo = (t_sva_bm_buffer_list_desc *)(bitstreamBufferListId); + + //((t_sva_bm_buffer_desc*)bufferId)->bufferListInfo[0].bufferLink.addr_buffer_start = ((t_sva_bm_buffer_desc*)bufferId)->bufferSystemAddress.physical; + + if (sva_BM_GetBufferLinkInformation( pBufferListInfo->firstBufferId, &pBufferInfo, &physicalAddress) != SVA_BM_OK) + return(SVA_INTERNAL_VIDEO_DECODER_ERROR); + + if (sva_BLM_GetBufferListIndex(bitstreamBufferListId, pBufferListInfo->firstBufferId, &bufferListIndex) != SVA_BLM_OK) + return SVA_INTERNAL_VIDEO_DECODER_ERROR; + + pBufferInfo[bufferListIndex].bufferLink.addr_buffer_start = ((t_sva_bm_buffer_desc*)pBufferListInfo->firstBufferId)->bufferSystemAddress.physical; + } + //extension of buffer start for ERC (and avoid fake BOW) + //48 bytes, ie 36 bytes aligned 16 to take into account internal bufferisation of SVA + //following lines should be removed when starting the buffer list with a fake buffer + blmError=sva_BLM_UpdateBufferMemoryBoundaryInBufferList (bitstreamBufferListId, BEGIN_OF_FIRST_BUFFER , -48); + if (blmError!=SVA_BLM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + + // Append a fake buffer at the end of the list if necessary + ffError=POP_FIFO_ELEM(Mpeg2Desc[instanceNum].fakeBitstreamFifo,t_sva_buffer_id,bufferId); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + blmError=sva_BLM_AddBufferInList(bitstreamBufferListId, bufferId); + if (blmError!=SVA_BLM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + + // push back the first frame buffer into the .push fifo at the first position + if (lastPushedBufferId != INVALID_BUFFER_ID) { + ffError = PUSH_REVERSE_FIFO_ELEM(pDesc->inputBitstreamFifos.push, t_sva_buffer_id, lastPushedBufferId); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + bmError=sva_BM_GetBufferSize(lastPushedBufferId,&bufferSize); + if (bmError!=SVA_BM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + pDesc->status.nbCompressedDataBufferized+=bufferSize; + } + + /*update state machine*/ + sva_DC_UpdateInstanceStateMachine(instanceNum,SVA_DC_PUSH); + + // program the subtask with all its dependencies + algoError = sva_DC_Mpeg2_SubTaskFieldsFullUpdate(instanceNum, pBitstreamBufferId); + HCL_DEBUG_ASSERT(algoError == SVA_OK); + + break; + + default: + return SVA_INTERNAL_VIDEO_DECODER_ERROR; + /* break; PCLint warning removal ...*/ + } + } + return SVA_OK; +} + + +/****************************************************************************/ +/* NAME: sva_DC_Mpeg2_SetupParamInOut() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: this function programs both */ +/* SVA_TM_DEC_ADDR_OUT_FRAME_PARAMETERS and */ +/* SVA_TM_DEC_ADDR_IN_FRAME_PARAMETERS registers */ +/* */ +/* PARAMETERS: */ +/* IN : t_uint8 instanceNum, */ +/* t_sva_tm_subtask_id subtaskId */ +/* OUT :none */ +/* */ +/* RETURN: */ +/* t_sva_dc_error */ +/*--------------------------------------------------------------------------*/ +/* USE: NA */ +/* USED BY: NA */ +/****************************************************************************/ +t_sva_error sva_DC_Mpeg2_SetupParamInOut(t_sva_service_instance_num instanceNum, t_sva_tm_subtask_id subtaskId) { + + t_sva_dc_algo_params_inout * algoParamsInOutAddr; + t_sva_error algoError; + t_sva_tm_error tmError; + t_sva_mm_error mmError; + t_sva_memory_id memoryId; + + //IN_FRAME_PARAMETER part + algoError=sva_DC_Mpeg2_GetNextFrameParamsInOut(instanceNum, &algoParamsInOutAddr); + HCL_DEBUG_ASSERT(algoError == SVA_OK); + mmError = sva_MM_GetBlockMemoryId(Mpeg2Desc[instanceNum].paramInOutBlockId, &memoryId); + HCL_DEBUG_ASSERT(mmError == SVA_MM_OK); + if (memoryId == SDRAM_ID) algoParamsInOutAddr = (t_sva_dc_algo_params_inout *)((t_uint32)algoParamsInOutAddr | MASK_BIT0); // toggle the exeternal flag + + // program both SVA_TM_DEC_ADDR_OUT_FRAME_PARAMETERS and SVA_TM_DEC_ADDR_IN_FRAME_PARAMETERS registers + tmError=sva_TM_UpdateSubTaskField( SVA_TM_INTERMEDIATE_FIELD_TO_UPDATE, + subtaskId, + SVA_TM_DEC_ADDR_OUT_FRAME_PARAMETERS, + FCMD_NEW_ADDRESS, + (t_uint32) algoParamsInOutAddr, + 0, + sizeof(t_sva_vdc_Mpeg2_param_inout)); + if (tmError!= SVA_TM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + + tmError=sva_TM_UpdateSubTaskField( SVA_TM_INTERMEDIATE_FIELD_TO_UPDATE, + subtaskId, + SVA_TM_DEC_ADDR_IN_FRAME_PARAMETERS, + FCMD_NEW_ADDRESS, + (t_uint32) algoParamsInOutAddr, + 0, + sizeof(t_sva_vdc_Mpeg2_param_inout)); + if (tmError!= SVA_TM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + + return SVA_OK; +} + --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/mpeg2/sva_dc_mpeg2p.h @@ -0,0 +1,35 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ + +#ifndef __INC_SVA_DC_Mpeg2P_H +#define __INC_SVA_DC_Mpeg2P_H + +#include "hcl_defs.h" +#include "sva_decode.h" +#include "../sva_dc_algo.h" +#include "sva.h" + +PUBLIC t_sva_error sva_DC_Mpeg2_GetNextFrameParamsInOut( t_sva_service_instance_num, t_sva_dc_algo_params_inout *); +PUBLIC t_sva_error sva_DC_Mpeg2_GetNextFrameParamsIn( t_sva_service_instance_num, t_sva_dc_algo_params_in *); +PUBLIC t_sva_error sva_DC_Mpeg2_GetNextFrameAddr(t_sva_service_instance_num , t_physical_address *, t_uint32 *, t_sva_buffer_id * ); +PUBLIC t_sva_error sva_DC_Mpeg2_AreNextFrameInfosAvailable(t_sva_service_instance_num , t_bool *); +PUBLIC t_sva_error sva_DC_Mpeg2_GetLastErrorType (t_sva_service_instance_num, t_uint16 * ); +PUBLIC t_sva_error sva_DC_Mpeg2_GetStartCodeValue ( t_uint32 * ); +PUBLIC t_sva_error sva_DC_Mpeg2_SetupParamInOut(t_sva_service_instance_num,t_sva_tm_subtask_id); +#endif --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/mpeg4/sva_dc_mpeg4.c @@ -0,0 +1,2211 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ + + +/*------------------------------------------------------------------------ + * Includes + *----------------------------------------------------------------------*/ + +#include "hcl_defs.h" +#include "sva_host_interface.h" +#include "sva_buffermgt.h" +#include "sva_fifo.h" +#include "sva_decode.h" +#include "../sva_decodep.h" +#include "../sva_decodepp.h" +#include "sva_service.h" + +#include "../sva_dc_algo.h" +#include "sva_dc_mpeg4.h" +#include "sva_dc_mpeg4p.h" + + +/*------------------------------------------------------------------------ + * Global Variables + *----------------------------------------------------------------------*/ +#ifdef __DEBUG +extern PUBLIC t_sva_dc_debug_events eventDecodeDebugTable[NUM_MAX_DECODE]; +extern PUBLIC t_sva_dc_debug_commands commandDecodeDebugTable[NUM_MAX_DECODE]; +extern PUBLIC t_sva_dc_debug_transitions transitionDecodeDebugTable[NUM_MAX_DECODE]; +#endif + +/*instance descriptors*/ +extern PUBLIC t_sva_dc_descriptor decodeDesc[NUM_MAX_DECODE]; +extern PUBLIC const t_sva_tm_field_ctrl_desc defaultDecodeFieldDescArray[NUMBER_OF_DECODE_ALGO_SUPPORTED][DECODE_FIELD_NUMBER]; + + +/* private */ +PUBLIC t_sva_mp4_desc mp4Desc[NUM_MAX_DECODE]; + + +PRIVATE t_sva_SetHeaderInfosParam setHeaderInfosParam[NUM_MAX_DECODE]; + +/*------------------------------------------------------------------------ + * Private functions prototype + *----------------------------------------------------------------------*/ +PRIVATE t_bool sva_DC_MP4_IsConfigurationValid(t_sva_video_decoder_algo_mpeg4_configuration_params *,t_sva_image_desc ); + + +/****************************************************************************/ +/* NAME: sva_DC_MP4_InitAndGetMemoryNeeds() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: This routine enables to store all statical parameters */ +/* PARAMETERS: */ +/* IN : t_sva_service_instance_num instanceNum */ +/* t_sva_codec_mode codecMode */ +/* t_sva_image_desc imageDesc */ +/* t_sva_codec_algo_configuration_params *confParams */ +/* OUT : */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/*--------------------------------------------------------------------------*/ +/* USE: NA */ +/* USED BY: NA */ +/****************************************************************************/ +PUBLIC t_sva_error sva_DC_MP4_Init( + t_sva_service_instance_num instanceNum, + t_sva_codec_mode codecMode, + t_sva_image_desc imageDesc, + const t_sva_dc_algo_configuration_params *pconfParams) +{ + + t_sva_video_decoder_algo_mpeg4_configuration_params *pMp4ConfParams; + t_sva_error svaError; + + HCL_ASSERT(pconfParams!=NULL); + + if(sva_DC_MP4_IsConfigurationValid((t_sva_video_decoder_algo_mpeg4_configuration_params *)pconfParams,imageDesc)!= TRUE) + { + return SVA_INCOHERENT_CONFIGURATION; + } + + mp4Desc[instanceNum].codecMode=codecMode; + mp4Desc[instanceNum].imageDesc=imageDesc; + //Store static parameters + pMp4ConfParams=(t_sva_video_decoder_algo_mpeg4_configuration_params *)pconfParams; + mp4Desc[instanceNum].staticParams=*pMp4ConfParams; + + //init globag structure for segmented and stream modes + if (mp4Desc[instanceNum].codecMode != SVA_CODEC_IMAGE_MODE) { + svaError = sva_DC_MP4_InitHeaderInfos(instanceNum); + if (svaError!=SVA_OK) return svaError; + } + + return SVA_OK; +} + + +/****************************************************************************/ +/* NAME: sva_DC_MP4_GetMemoryNeeds() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: This routine enables to determine also cachable memory needs for software process */ +/* PARAMETERS: */ +/* IN : t_sva_service_instance_num instanceNum */ +/* OUT :t_size *pMemNeeds */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/*--------------------------------------------------------------------------*/ +/* USE: NA */ +/* USED BY: NA */ +/****************************************************************************/ +PUBLIC t_sva_error sva_DC_MP4_GetMemoryNeeds( + t_sva_service_instance_num instanceNum, + t_size *pMemNeeds) +{ + + t_size fifoSize; + + HCL_ASSERT(pMemNeeds!=NULL); + + //Dynamic Params Fifo Fifo + GET_FIFO_MEMORY_NEEDS(t_sva_video_decoder_algo_mpeg4_header_infos, MP4_DECODE_MAX_FIFO_SIZE, fifoSize); + *pMemNeeds = fifoSize; + //Bitstream position fifo + GET_FIFO_MEMORY_NEEDS(t_sva_bitstream_desc, MP4_DECODE_MAX_FIFO_SIZE, fifoSize); + *pMemNeeds = *pMemNeeds + fifoSize; + + /* fake bistream buffer: was inside decode.c */ + GET_FIFO_MEMORY_NEEDS(t_sva_buffer_id, SUBTASK_DEFAULT_NUMBER, fifoSize); + *pMemNeeds = *pMemNeeds + fifoSize; + + /* mpeg4 dependency fifo (.push and .inUse) */ + GET_FIFO_MEMORY_NEEDS(t_sva_dc_mp4_dependencies_desc, SUBTASK_DEFAULT_NUMBER, fifoSize); + *pMemNeeds = *pMemNeeds + fifoSize; + GET_FIFO_MEMORY_NEEDS(t_sva_dc_mp4_dependencies_desc, SUBTASK_DEFAULT_NUMBER, fifoSize); + *pMemNeeds = *pMemNeeds + fifoSize; + + //reference(s) handler fifo + GET_FIFO_MEMORY_NEEDS(t_sva_mp4_reference_handler, MP4_DECODE_MAX_FIFO_SIZE, fifoSize); + *pMemNeeds = *pMemNeeds + fifoSize; + //reference(s) handler Out fifo to handle frame reordering + GET_FIFO_MEMORY_NEEDS(t_sva_mp4_reference_handler, MP4_DECODE_MAX_FIFO_SIZE, fifoSize); + *pMemNeeds = *pMemNeeds + fifoSize; + //reference Images fifo (Ref and prevRef) + GET_FIFO_MEMORY_NEEDS(t_sva_buffer_id, MP4_DECODE_MAX_FIFO_SIZE, fifoSize); + *pMemNeeds = *pMemNeeds + fifoSize; + GET_FIFO_MEMORY_NEEDS(t_sva_buffer_id, MP4_DECODE_MAX_FIFO_SIZE, fifoSize); + *pMemNeeds = *pMemNeeds + fifoSize; + + + return SVA_OK; + +} + + + +/****************************************************************************/ +/* NAME: sva_DC_MP4_ProvideMemoryNeeds() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: This routine enables to provide cachable memory needs */ +/* for decode fifos */ +/* PARAMETERS: */ +/* IN : t_sva_service_instance_num instanceNum */ +/* OUT : */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/*--------------------------------------------------------------------------*/ +/* USE: NA */ +/* USED BY: NA */ +/****************************************************************************/ +PUBLIC t_sva_error sva_DC_MP4_ProvideMemoryNeeds(t_sva_service_instance_num instanceNum ) +{ + t_sva_ff_error ffError; + t_uint16 i; + t_system_address fakeBufferSystemAddr; + t_uint32 scPosition; + t_uint32 *pValue=NULL; + t_sva_buffer_id fakeBitstreamBufferId; + t_sva_error svaError; + + //Create all internal fifos + //Dynamic Params Fifo Fifo + CREATE_FIFO(t_sva_video_decoder_algo_mpeg4_header_infos,MP4_DECODE_MAX_FIFO_SIZE,mp4Desc[instanceNum].fifoDynamicParams,ffError); + if (ffError!= SVA_FIFO_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + //Bitstream position fifosva + CREATE_FIFO(t_sva_bitstream_desc,MP4_DECODE_MAX_FIFO_SIZE,mp4Desc[instanceNum].fifoBitstream,ffError); + if (ffError!= SVA_FIFO_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + + //fakeBitstreamFifo + CREATE_FIFO(t_sva_buffer_id, SUBTASK_DEFAULT_NUMBER, mp4Desc[instanceNum].fakeBitstreamFifo, ffError); + if (ffError != SVA_FIFO_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + /********************************* start ************************************************************************/ + //reference(s) handler fifo + CREATE_FIFO(t_sva_mp4_reference_handler, MP4_DECODE_MAX_FIFO_SIZE,mp4Desc[instanceNum].referenceHandlerFifo, ffError); + if (ffError != SVA_FIFO_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + //reference(s) handler Out fifo + CREATE_FIFO(t_sva_mp4_reference_handler, MP4_DECODE_MAX_FIFO_SIZE,mp4Desc[instanceNum].referenceHandlerOutFifo, ffError); + if (ffError != SVA_FIFO_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + + //reference Images fifo (Ref and prevRef) + CREATE_FIFO(t_sva_buffer_id,MP4_DECODE_MAX_FIFO_SIZE,mp4Desc[instanceNum].refImageFifo, ffError); + if (ffError!= SVA_FIFO_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + CREATE_FIFO(t_sva_buffer_id,MP4_DECODE_MAX_FIFO_SIZE,mp4Desc[instanceNum].prevRefImageFifo, ffError); + if (ffError!= SVA_FIFO_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + +/********************************* end ************************************************************************/ + + //mpeg4 dependency fifos + CREATE_FIFO(t_sva_dc_mp4_dependencies_desc, SUBTASK_DEFAULT_NUMBER, mp4Desc[instanceNum].mp4Dep.push, ffError); + if (ffError != SVA_FIFO_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + CREATE_FIFO(t_sva_dc_mp4_dependencies_desc, SUBTASK_DEFAULT_NUMBER, mp4Desc[instanceNum].mp4Dep.inUse, ffError); + if (ffError != SVA_FIFO_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + + /* alloc fake buffer and push it in the fifo */ + for(i=0;i> 4; + pValue[scPosition] = START_CODE_VALUE_SH; + pValue[scPosition+1] = START_CODE_VALUE_SP; + + ffError=PUSH_FIFO_ELEM(mp4Desc[instanceNum].fakeBitstreamFifo,t_sva_buffer_id,fakeBitstreamBufferId); + if (ffError!= SVA_FIFO_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + } + + + + return SVA_OK; +} + +/****************************************************************************/ +/* NAME: sva_DC_MP4_Close() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: This routine allows to unallocate any fifos */ +/* PARAMETERS: */ +/* IN : t_sva_service_instance_num instanceNum */ +/* */ +/* OUT :none */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/*--------------------------------------------------------------------------*/ +/* USE: NA */ +/* USED BY: NA */ +/****************************************************************************/ +PUBLIC t_sva_error sva_DC_MP4_Close(t_sva_service_instance_num instanceNum) +{ + //Delete all internal fifos + //Dynamic Params Fifo Fifo + DELETE_FIFO(mp4Desc[instanceNum].fifoDynamicParams); + + //Bitstream position fifo + DELETE_FIFO(mp4Desc[instanceNum].fifoBitstream); + + //delete the created reference(s) handler fifo + DELETE_FIFO (mp4Desc[instanceNum].referenceHandlerFifo); + + //delete the created reference(s) handler fifo + DELETE_FIFO (mp4Desc[instanceNum].referenceHandlerOutFifo); + + + // delete the created reference Images fifo (Ref and prevRef) + DELETE_FIFO(mp4Desc[instanceNum].refImageFifo); + DELETE_FIFO(mp4Desc[instanceNum].prevRefImageFifo); + //Dependency fifos + DELETE_FIFO(mp4Desc[instanceNum].mp4Dep.push); + DELETE_FIFO(mp4Desc[instanceNum].mp4Dep.inUse); + + return SVA_OK; +} + + +/****************************************************************************/ +/* NAME: sva_DC_MP4_InitHeaderInfo(t_sva_service_instance_num) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: This routine initializes the headerInfo struct */ +/* */ +/* PARAMETERS: */ +/* IN : t_sva_service_instance_num instanceNum */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/*****************************************************************************/ +PUBLIC t_sva_error sva_DC_MP4_InitHeaderInfos(t_sva_service_instance_num instanceNum) +{ + setHeaderInfosParam[instanceNum].serviceId = MASK_ALL32; + setHeaderInfosParam[instanceNum].bitstreamBuffer = INVALID_BUFFER_ID; + setHeaderInfosParam[instanceNum].byteOffset = 0; + setHeaderInfosParam[instanceNum].bitOffset = 0; + + return SVA_OK; +} + +/****************************************************************************/ +/* NAME: sva_DC_MP4_GSetHeaderInfos() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: This routine enables user to manage Header Infos to the module*/ +/* PARAMETERS: */ +/* IN : t_sva_service_instance_num instanceNum */ +/* t_sva_buffer_id bufferId */ +/* t_uint32 byteOffset */ +/* t_uint32 bitOffset */ +/* const t_sva_header_infos *headerInfos */ +/* OUT :none */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/*--------------------------------------------------------------------------*/ +/* USE: NA */ +/* USED BY: NA */ +/****************************************************************************/ +PUBLIC t_sva_error sva_DC_MP4_GSetHeaderInfos( + t_sva_service_instance_num instanceNum, + t_sva_service_id serviceId, + t_sva_buffer_id bitstreamBuffer, + t_uint32 byteOffset, + t_uint32 bitOffset, + const t_sva_header_infos *pHeaderInfos) +{ + + t_sva_dc_descriptor *pDesc=&decodeDesc[instanceNum]; + t_sva_video_decoder_configuration *pConf=&pDesc->confHandle.currentConf; + t_sva_SetHeaderInfosParam *pSetHeaderInfosParams = &setHeaderInfosParam[instanceNum]; + //t_sva_error algoError; + t_sva_video_decoder_algo_mpeg4_header_infos *pMpeg4HeaderInfos; + t_sva_bitstream_desc bitstreamDesc; + t_sva_buffer_status bufferStatus; + t_physical_address bufferStartAddr; + t_sva_error svaError; + t_sva_ff_error ffError; + t_sva_bm_error bmError; + t_sva_mp4_reference_handler referenceHandler; + HCL_ASSERT(pHeaderInfos!=NULL); + + pMpeg4HeaderInfos=(t_sva_video_decoder_algo_mpeg4_header_infos *)(pHeaderInfos); + /* Check Header Info params */ + // pictureCodingType: 0: Intra-coded, 1: Predictive-coded + if(pMpeg4HeaderInfos->pictureCodingType>2) {return SVA_INCOHERENT_CONFIGURATION;} + // Quant value range: 1 to 31 + if(pMpeg4HeaderInfos->quant==0 || pMpeg4HeaderInfos->quant>31) {return SVA_INCOHERENT_CONFIGURATION;} + // value range: 0 to 7 + if(pMpeg4HeaderInfos->intraDcVlcThr>7) {return SVA_INCOHERENT_CONFIGURATION;} + if(pMpeg4HeaderInfos->pictureCodingType != 0) + { + // roundingType value range: 0 to 1 + if(pMpeg4HeaderInfos->roundingType>1) {return SVA_INCOHERENT_CONFIGURATION;} + // vopFcodeForward value range: 1 to 7 + if(pMpeg4HeaderInfos->vopFcodeForward==0 || pMpeg4HeaderInfos->vopFcodeForward>7) {return SVA_INCOHERENT_CONFIGURATION;} + } + + //if(pMpeg4HeaderInfos->vopFcodeBackward==0 || pMpeg4HeaderInfos->vopFcodeBackward>7) {return SVA_INCOHERENT_CONFIGURATION;} + + switch(pConf->mode) { + case SVA_CODEC_IMAGE_MODE : + + //check that buffer is already pushed: ie is in "sva_BUFFER_IN_USE" state + svaError=SVA_GetBufferStatus(bitstreamBuffer,&bufferStatus); + if (svaError != SVA_OK) {return SVA_UNEXPECTED_API_CALL; } + + HCL_DEBUG_ASSERT(bufferStatus.state == SVA_BUFFER_IN_USE); + if (bufferStatus.state != SVA_BUFFER_IN_USE) { return SVA_UNEXPECTED_API_CALL; } + + pMpeg4HeaderInfos=(t_sva_video_decoder_algo_mpeg4_header_infos *)(pHeaderInfos); + + referenceHandler.bitstreamBuffer = bitstreamBuffer; + referenceHandler.fwdReferenceImage = INVALID_BUFFER_ID; // both fwd and bwd ref will be set up when resolving dependencies + referenceHandler.bwdReferenceImage = INVALID_BUFFER_ID; + referenceHandler.pictureType = (t_sva_mp4_picture_type)pMpeg4HeaderInfos->pictureCodingType; + ffError=PUSH_FIFO_ELEM(mp4Desc[instanceNum].referenceHandlerFifo, t_sva_mp4_reference_handler, referenceHandler); + if (ffError!= SVA_FIFO_OK) {return SVA_INTERNAL_FIFOS_FULL;} + + ffError=PUSH_FIFO_ELEM(mp4Desc[instanceNum].referenceHandlerOutFifo, t_sva_mp4_reference_handler, referenceHandler); + if (ffError!= SVA_FIFO_OK) {return SVA_INTERNAL_FIFOS_FULL;} + + + bmError=sva_BM_GetBufferPhysicalAddress(bitstreamBuffer,&bufferStartAddr); + if (bmError != SVA_BM_OK) {return SVA_UNEXPECTED_API_CALL; } + + //Store Dynamic params in fifo fifoDynamicParams + ffError=PUSH_FIFO_ELEM(mp4Desc[instanceNum].fifoDynamicParams,t_sva_video_decoder_algo_mpeg4_header_infos,*pMpeg4HeaderInfos); + if (ffError!= SVA_FIFO_OK) {return SVA_INTERNAL_FIFOS_FULL;} + + /*Store bitstream position in fifoBitstream*/ + //This field will be setted in sva_DC_TryToInitBitstreamFields as decode module manages bitstrem buffer list + bitstreamDesc.bitstreamPosition.addr_bitstream_buf_struct= 0;//address of bitstream buffer list will be updated by ResolveDependancies() (should be multiple of 16) + bitstreamDesc.bitstreamPosition.addr_bitstream_start= ((byteOffset >> 4) <<4) + bufferStartAddr; //in bytes (Should be aligned on 16 bytes + absolute address) + bitstreamDesc.bitstreamPosition.bitstream_offset= (byteOffset - ((byteOffset >> 4) <<4)) * 8 + bitOffset; //Is the offset in bits between aligned address and provided no aligned address in byte + user offset + bitstreamDesc.relatedBufferId=bitstreamBuffer; + ffError=PUSH_FIFO_ELEM(mp4Desc[instanceNum].fifoBitstream,t_sva_bitstream_desc,bitstreamDesc); + if (ffError!= SVA_FIFO_OK) {return SVA_INTERNAL_FIFOS_FULL;} + + break; + + case SVA_CODEC_SEGMENTED_MODE : + case SVA_CODEC_STREAM_MODE : + + if (pSetHeaderInfosParams->bitstreamBuffer != INVALID_BUFFER_ID) { + ffError=PUSH_FIFO_ELEM(pDesc->lastPushedBufferFifo.push,t_sva_buffer_id,bitstreamBuffer); + if (ffError!= SVA_FIFO_OK) {return SVA_INTERNAL_FIFOS_FULL;} + + //check that buffer is already pushed: ie is in "sva_BUFFER_IN_USE" state + svaError=SVA_GetBufferStatus(pSetHeaderInfosParams->bitstreamBuffer,&bufferStatus); + if (svaError != SVA_OK) {return SVA_UNEXPECTED_API_CALL; } + + if (bufferStatus.state != SVA_BUFFER_IN_USE) { return SVA_UNEXPECTED_API_CALL; } + + pMpeg4HeaderInfos = &pSetHeaderInfosParams->headerInfos; + + //Store the last picture Type + referenceHandler.bitstreamBuffer = pSetHeaderInfosParams->bitstreamBuffer; + referenceHandler.fwdReferenceImage = INVALID_BUFFER_ID; // both fwd and bwd ref will be set up when resolving dependencies + referenceHandler.bwdReferenceImage = INVALID_BUFFER_ID; + referenceHandler.pictureType = (t_sva_mp4_picture_type)pMpeg4HeaderInfos->pictureCodingType; + PUSH_FIFO_ELEM(mp4Desc[instanceNum].referenceHandlerFifo, t_sva_mp4_reference_handler, referenceHandler); + + ffError=PUSH_FIFO_ELEM(mp4Desc[instanceNum].referenceHandlerOutFifo,t_sva_mp4_reference_handler, referenceHandler); + if (ffError!= SVA_FIFO_OK) {return SVA_INTERNAL_FIFOS_FULL;} + + + bmError=sva_BM_GetBufferPhysicalAddress(pSetHeaderInfosParams->bitstreamBuffer,&bufferStartAddr); + if (bmError != SVA_BM_OK) {return SVA_UNEXPECTED_API_CALL; } + + //Store Dynamic params in fifo fifoDynamicParams + ffError=PUSH_FIFO_ELEM(mp4Desc[instanceNum].fifoDynamicParams,t_sva_video_decoder_algo_mpeg4_header_infos,*pMpeg4HeaderInfos); + if (ffError!= SVA_FIFO_OK) {return SVA_INTERNAL_FIFOS_FULL;} + + /*Store bitstream position in fifoBitstream*/ + //This field will be setted in sva_DC_TryToInitBitstreamFields as decode module manages bitstrem buffer list + bitstreamDesc.bitstreamPosition.addr_bitstream_buf_struct= 0;//address of bitstream buffer list will be updated by ResolveDependancies() (should be multiple of 16) + bitstreamDesc.bitstreamPosition.addr_bitstream_start= ((pSetHeaderInfosParams->byteOffset >> 4) <<4) + bufferStartAddr; //in bytes (Should be aligned on 16 bytes + absolute address) + bitstreamDesc.bitstreamPosition.bitstream_offset= (pSetHeaderInfosParams->byteOffset - ((pSetHeaderInfosParams->byteOffset >> 4) <<4)) * 8 + pSetHeaderInfosParams->bitOffset; //Is the offset in bits between aligned address and provided no aligned address in byte + user offset + bitstreamDesc.relatedBufferId=pSetHeaderInfosParams->bitstreamBuffer; + ffError=PUSH_FIFO_ELEM(mp4Desc[instanceNum].fifoBitstream,t_sva_bitstream_desc,bitstreamDesc); + if (ffError!= SVA_FIFO_OK) {return SVA_INTERNAL_FIFOS_FULL;} + } + + + // stack up current parameters to be used at the end of the frame (next call of sva_DC_SetHeaderInfos) + pSetHeaderInfosParams->serviceId = serviceId; + pSetHeaderInfosParams->bitstreamBuffer = bitstreamBuffer; + pSetHeaderInfosParams->byteOffset = byteOffset; + pSetHeaderInfosParams->bitOffset = bitOffset; + pMpeg4HeaderInfos = (t_sva_video_decoder_algo_mpeg4_header_infos*)pHeaderInfos; + pSetHeaderInfosParams->headerInfos = *pMpeg4HeaderInfos; + + break; + + default : + return SVA_INTERNAL_VIDEO_DECODER_ERROR; + // break; PCLint warning removal ... + } + + return SVA_OK; + +} + + +/****************************************************************************/ +/* NAME: sva_DC_MP4_AssertEndOfBitstream() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: Assert the immediate end of bitstream. Leads to a */ +/* non-delayed setHeaderInfos execution */ +/* */ +/* PARAMETERS: */ +/* IN : t_sva_service_id serviceId */ +/* OUT :none */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/* - SVA_OK : Last subtask sucessfully lined up. */ +/* - SVA_INTERNAL_VIDEO_DECODER_ERROR : Error */ +/****************************************************************************/ +PUBLIC t_sva_error sva_DC_MP4_AssertEndOfBitstream(t_sva_service_instance_num instanceNum, t_sva_service_id serviceId) +{ + + t_sva_dc_descriptor *pDesc=&decodeDesc[instanceNum]; + t_sva_video_decoder_configuration *pConf=&pDesc->confHandle.currentConf; + t_sva_SetHeaderInfosParam *pSetHeaderInfosParams = &setHeaderInfosParam[instanceNum]; + t_sva_video_decoder_algo_mpeg4_header_infos *pMpeg4HeaderInfos; + t_sva_bitstream_desc bitstreamDesc; + t_sva_buffer_status bufferStatus; + t_physical_address bufferStartAddr; + t_sva_ff_error ffError; + t_sva_error svaError; + t_sva_bm_error bmError; + t_sva_mp4_reference_handler referenceHandler; + + switch(pConf->mode) { + case SVA_CODEC_IMAGE_MODE : + + return SVA_OK; // nothing to do in Image mode - End of bitstream trigerred by SetHeaderInfos + + case SVA_CODEC_SEGMENTED_MODE : + case SVA_CODEC_STREAM_MODE : + + //check that transition is allowed + if (sva_DC_isTransitionValid(instanceNum,SVA_DC_PUSH)==FALSE) {return SVA_UNEXPECTED_API_CALL;} + + // trigger the execution of the last SetHeaderInfos + if (pSetHeaderInfosParams->bitstreamBuffer != INVALID_BUFFER_ID) { + // valid buffer ID means this is not the first call to SVA_SetHeaderInfos : process here + // last call parameters + + //check that buffer is already pushed: ie is in "sva_BUFFER_IN_USE" state + svaError=SVA_GetBufferStatus(pSetHeaderInfosParams->bitstreamBuffer,&bufferStatus); + if (svaError != SVA_OK) {return SVA_UNEXPECTED_API_CALL; } + + HCL_DEBUG_ASSERT(bufferStatus.state == SVA_BUFFER_IN_USE); + if (bufferStatus.state != SVA_BUFFER_IN_USE) { return SVA_UNEXPECTED_API_CALL; } + + pMpeg4HeaderInfos = &pSetHeaderInfosParams->headerInfos; + + bmError=sva_BM_GetBufferPhysicalAddress(pSetHeaderInfosParams->bitstreamBuffer,&bufferStartAddr); + if (bmError != SVA_BM_OK) {return SVA_UNEXPECTED_API_CALL; } + + // get the type of the frame to handle references + referenceHandler.bitstreamBuffer = pSetHeaderInfosParams->bitstreamBuffer; + referenceHandler.fwdReferenceImage = INVALID_BUFFER_ID; // both fwd and bwd ref will be set up when resolving dependencies + referenceHandler.bwdReferenceImage = INVALID_BUFFER_ID; + referenceHandler.pictureType = (t_sva_mp4_picture_type)pMpeg4HeaderInfos->pictureCodingType; + ffError=PUSH_FIFO_ELEM(mp4Desc[instanceNum].referenceHandlerFifo, t_sva_mp4_reference_handler, referenceHandler); + if (ffError!= SVA_FIFO_OK) {return SVA_INTERNAL_FIFOS_FULL;} + + ffError=PUSH_FIFO_ELEM(mp4Desc[instanceNum].referenceHandlerOutFifo,t_sva_mp4_reference_handler, referenceHandler); + if (ffError!= SVA_FIFO_OK) {return SVA_INTERNAL_FIFOS_FULL;} + + + //Store Dynamic params in fifo fifoDynamicParams + ffError=PUSH_FIFO_ELEM(mp4Desc[instanceNum].fifoDynamicParams,t_sva_video_decoder_algo_mpeg4_header_infos,*pMpeg4HeaderInfos); + if (ffError!= SVA_FIFO_OK) {return SVA_INTERNAL_FIFOS_FULL;} + + /*Store bitstream position in fifoBitstream*/ + //This field will be setted in sva_DC_TryToInitBitstreamFields as decode module manages bitstrem buffer list + bitstreamDesc.bitstreamPosition.addr_bitstream_buf_struct= 0;//address of bitstream buffer list will be updated by ResolveDependancies() (should be multiple of 16) + bitstreamDesc.bitstreamPosition.addr_bitstream_start= ((pSetHeaderInfosParams->byteOffset >> 4) <<4) + bufferStartAddr; //in bytes (Should be aligned on 16 bytes + absolute address) + bitstreamDesc.bitstreamPosition.bitstream_offset= (pSetHeaderInfosParams->byteOffset - ((pSetHeaderInfosParams->byteOffset >> 4) <<4)) * 8 + pSetHeaderInfosParams->bitOffset; //Is the offset in bits between aligned address and provided no aligned address in byte + user offset + bitstreamDesc.relatedBufferId=pSetHeaderInfosParams->bitstreamBuffer; + ffError=PUSH_FIFO_ELEM(mp4Desc[instanceNum].fifoBitstream,t_sva_bitstream_desc,bitstreamDesc); + if (ffError!= SVA_FIFO_OK) {return SVA_INTERNAL_FIFOS_FULL;} + + sva_DC_UpdateInstanceStateMachine(instanceNum,SVA_DC_PUSH); + + } else return SVA_INTERNAL_VIDEO_DECODER_ERROR; + + break; + + default : + return SVA_INTERNAL_VIDEO_DECODER_ERROR; + //break; PCLint warning removal ... + } + + return SVA_OK; + +} + + + + + +/****************************************************************************/ +/* NAME: sva_DC_MP4_GetOutputParamsSize() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: This routine enables user to know the size of Paramout */ +/* structure: depends on algo used (and FW release) */ +/* PARAMETERS: */ +/* IN : t_sva_service_instance_num instanceNum */ +/* OUT : */ +/* */ +/* RETURN: */ +/* size in byte */ +/*--------------------------------------------------------------------------*/ +/* USE: NA */ +/* USED BY: NA */ +/****************************************************************************/ +PUBLIC t_size sva_DC_MP4_GetOutputParamsSize( + t_sva_service_instance_num instanceNum + ) +{ + (void) instanceNum;/*discard instanceNum*/ + + return (sizeof(t_sva_vdc_mpeg4_param_out)); +} + + + +/****************************************************************************/ +/* NAME: sva_DC_MP4_SetOutputParams() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: This routine enables to synthetize all infos provided by */ +/* a subtask through the paramout field */ +/* Called when EOT,It computes paramout data and stores results*/ +/* in a global variable */ +/* PARAMETERS: */ +/* IN : t_sva_service_instance_num instanceNum */ +/* OUT :t_bool *infosAvailable */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/*--------------------------------------------------------------------------*/ +/* USE: NA */ +/* USED BY: NA */ +/****************************************************************************/ +PUBLIC t_sva_error sva_DC_MP4_SetOutputParams( + t_sva_service_instance_num instanceNum, + const t_sva_dc_algo_params_out *algoParamsOutAddr + ) +{ + t_sva_vdc_mpeg4_param_out *pNewParamOut; + + HCL_ASSERT(algoParamsOutAddr!=NULL); + + pNewParamOut=(t_sva_vdc_mpeg4_param_out *) algoParamsOutAddr; + + + mp4Desc[instanceNum].lastFrameMp4ParamOut.error_type=pNewParamOut->error_type; + //mp4Desc[instanceNum].lastFrameMp4ParamOut.picture_loss=pNewParamOut->picture_loss; + + //Futhermore, structure for statistical data not yet implmented : mp4Desc[instanceNum].statisticalMp4ParamOut + + return SVA_OK; +} + + + + +/****************************************************************************/ +/* NAME: sva_DC_MP4_GetStatus() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: This routine gives access to mp4Desc[instanceNum].Mp4ParamOut*/ +/* global */ +/* This is called inside sva_DC_Status() */ +/* PARAMETERS: */ +/* IN : t_sva_service_instance_num instanceNum */ +/* OUT :t_sva_dc_algo_status * */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/*--------------------------------------------------------------------------*/ +/* USE: NA */ +/* USED BY: NA */ +/****************************************************************************/ +t_sva_error sva_DC_MP4_GetStatus ( + t_sva_service_instance_num instanceNum, + t_sva_dc_algo_status *lastFrameAlgoStatus, + t_sva_dc_algo_status *statisticalAlgoStatus ) +{ + t_sva_vdc_mpeg4_param_out *plastFrameMp4ParamOut; + t_sva_vdc_mpeg4_param_out *pstatisticalMp4ParamOut; + + HCL_ASSERT(lastFrameAlgoStatus!=NULL); + HCL_ASSERT(statisticalAlgoStatus!=NULL); + + plastFrameMp4ParamOut=(t_sva_vdc_mpeg4_param_out *)lastFrameAlgoStatus; + pstatisticalMp4ParamOut=(t_sva_vdc_mpeg4_param_out *)statisticalAlgoStatus; + + *plastFrameMp4ParamOut=mp4Desc[instanceNum].lastFrameMp4ParamOut; + *pstatisticalMp4ParamOut=mp4Desc[instanceNum].statisticalMp4ParamOut; + + return SVA_OK; +} + + +/****************************************************************************/ +/* NAME: sva_DC_MP4_FlushFifos() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: This routine enables to flush all mp4 fifos */ +/* */ +/* PARAMETERS: */ +/* IN : t_sva_service_instance_num instanceNum */ +/* OUT : */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/*--------------------------------------------------------------------------*/ +/* USE: NA */ +/* USED BY: NA */ +/****************************************************************************/ +t_sva_error sva_DC_MP4_FlushFifos (t_sva_service_instance_num instanceNum) { + + t_sva_dc_descriptor *pDesc=&decodeDesc[instanceNum]; + t_sva_mp4_desc *pmp4Desc = &mp4Desc[instanceNum]; + t_sva_dc_subtask_dependencies subtaskDep; + t_sva_dc_mp4_dependencies_desc mp4Dep; + t_sva_buffer_id bufferId = 0; + t_uint32 systemTime; + t_sva_error svaError; + t_sva_tm_error tmError; + t_sva_ff_error ffError; + t_sva_bm_error bmError; + t_uint32 i; + + // flush all scheduled subtasks + do { + tmError=sva_TM_RemoveElemFromSubTaskList(pDesc->subtasksListId,&subtaskDep.subtaskId); + } while (tmError==SVA_TM_OK); + + // flush dependencies + while(POP_FIFO_ELEM(pDesc->subtasksDependencyFifo.inUse,t_sva_dc_subtask_dependencies,subtaskDep) != SVA_FIFO_EMPTY); + while(POP_FIFO_ELEM(pDesc->subtasksDependencyFifo.push,t_sva_dc_subtask_dependencies,subtaskDep) != SVA_FIFO_EMPTY); + while(POP_FIFO_ELEM(pmp4Desc->mp4Dep.inUse,t_sva_dc_mp4_dependencies_desc,mp4Dep) != SVA_FIFO_EMPTY); + while(POP_FIFO_ELEM(pmp4Desc->mp4Dep.push,t_sva_dc_mp4_dependencies_desc,mp4Dep) != SVA_FIFO_EMPTY); + + /* Push back reset subtaskdeps in the .push fifos */ + for(i=0;isubtasksIdArray[i]; + subtaskDep.bitstreamBufferListId=pDesc->bufferListIdArray[i][0]; + subtaskDep.dependencies=pDesc->defaultDep; + mp4Dep = pmp4Desc->defaultDep; + ffError=PUSH_FIFO_ELEM(pDesc->subtasksDependencyFifo.push, t_sva_dc_subtask_dependencies, subtaskDep); + if (ffError!=SVA_FIFO_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + ffError=PUSH_FIFO_ELEM(pmp4Desc->mp4Dep.push, t_sva_dc_mp4_dependencies_desc, mp4Dep); + if (ffError!=SVA_FIFO_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + } + + /*get time*/ + svaError=SVA_GetServiceSystemTime(pDesc->serviceId ,&systemTime); + if (svaError != SVA_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + + /************/ + /*flush fifo*/ + /************/ + //fifos inputFwdImageFifos + //------------------------ + /* while(POP_FIFO_ELEM(pDesc->inputFwdImageFifos.inUse,t_sva_buffer_id,bufferId) != SVA_FIFO_EMPTY) + { + bmError=sva_BM_UpdateBufferStatus(bufferId,SVA_BUFFER_NOT_USED,systemTime); + if (bmError!=SVA_BM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + } + + while(POP_FIFO_ELEM(pDesc->inputFwdImageFifos.push,t_sva_buffer_id,bufferId) != SVA_FIFO_EMPTY) + { + bmError=sva_BM_UpdateBufferStatus(bufferId,SVA_BUFFER_NOT_USED,systemTime); + if (bmError!=SVA_BM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + } */ + + /*push fake Fwd ref buffer in inputFwdImageFifos.push to put the fifo in a "idle" state*/ + // ffError=PUSH_FIFO_ELEM(pDesc->inputFwdImageFifos.push,t_sva_buffer_id,pDesc->fakeFwdImageBufferId); + // if (ffError!= SVA_FIFO_OK) return SVA_INTERNAL_VIDEO_DECODER_ERROR; + + + //fifo outputImageFifo + //-------------------- + while(POP_FIFO_ELEM(pDesc->outputImageFifos.push,t_sva_buffer_id,bufferId) != SVA_FIFO_EMPTY) + { + bmError=sva_BM_UpdateBufferStatus(bufferId,SVA_BUFFER_NOT_USED,systemTime); + if (bmError!=SVA_BM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + } + while(POP_FIFO_ELEM(pDesc->outputImageFifos.inUse,t_sva_buffer_id,bufferId) != SVA_FIFO_EMPTY) + { + bmError=sva_BM_UpdateBufferStatus(bufferId,SVA_BUFFER_NOT_USED,systemTime); + if (bmError!=SVA_BM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + } + + //fifo inputBitstreamfifo + //-------------------- + while(POP_FIFO_ELEM(pDesc->inputBitstreamFifos.push,t_sva_buffer_id,bufferId) != SVA_FIFO_EMPTY) + { + bmError=sva_BM_UpdateBufferStatus(bufferId,SVA_BUFFER_NOT_USED,systemTime); + if (bmError!=SVA_BM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + } + while(POP_FIFO_ELEM(pDesc->inputBitstreamFifos.inUse,t_sva_buffer_id,bufferId) != SVA_FIFO_EMPTY) + { + bmError=sva_BM_UpdateBufferStatus(bufferId,SVA_BUFFER_NOT_USED,systemTime); + if (bmError!=SVA_BM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + } + + //optional fifos outputDeblockingFifos + //------------------------------------ + if(pDesc->confHandle.currentConf.outTheLoopFilter != SVA_NONE_FILTER) + { + while(POP_FIFO_ELEM(pDesc->outputDeblockingFifos.push,t_sva_buffer_id,bufferId) != SVA_FIFO_EMPTY) + { + bmError=sva_BM_UpdateBufferStatus(bufferId,SVA_BUFFER_NOT_USED,systemTime); + if (bmError!=SVA_BM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + } + while(POP_FIFO_ELEM(pDesc->outputDeblockingFifos.inUse,t_sva_buffer_id,bufferId) != SVA_FIFO_EMPTY) + { + bmError=sva_BM_UpdateBufferStatus(bufferId,SVA_BUFFER_NOT_USED,systemTime); + if (bmError!=SVA_BM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + } + } + //optional fifos outputInfosFifos + //------------------------------- + if(pDesc->confHandle.currentConf.areInfosRequested == TRUE) + { + while(POP_FIFO_ELEM(pDesc->outputInfosFifos.push,t_sva_buffer_id,bufferId) != SVA_FIFO_EMPTY) + { + bmError=sva_BM_UpdateBufferStatus(bufferId,SVA_BUFFER_NOT_USED,systemTime); + if (bmError!=SVA_BM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + } + while(POP_FIFO_ELEM(pDesc->outputInfosFifos.inUse,t_sva_buffer_id,bufferId) != SVA_FIFO_EMPTY) + { + bmError=sva_BM_UpdateBufferStatus(bufferId,SVA_BUFFER_NOT_USED,systemTime); + if (bmError!=SVA_BM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + } + } + + //internal fifos + //-------------- + FLUSH_FIFO(mp4Desc[instanceNum].fifoDynamicParams); + FLUSH_FIFO(mp4Desc[instanceNum].fifoBitstream); + FLUSH_FIFO(mp4Desc[instanceNum].referenceHandlerFifo); + FLUSH_FIFO(mp4Desc[instanceNum].referenceHandlerOutFifo); + FLUSH_FIFO(mp4Desc[instanceNum].refImageFifo); + FLUSH_FIFO(mp4Desc[instanceNum].prevRefImageFifo); + + return SVA_OK; +} + + + + +/****************************************************************************/ +/* NAME: sva_DC_MP4_DeleteFake() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* */ +/* */ +/* PARAMETERS: */ +/* IN : t_sva_service_instance_num instanceNum */ +/* OUT : */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/****************************************************************************/ +t_sva_error sva_DC_MP4_DeleteFake ( + t_sva_service_instance_num instanceNum + ) +{ + + t_sva_ff_error ffError; + t_uint16 i; + t_sva_buffer_id fakeBitstreamBufferId=INVALID_BUFFER_ID; + + for(i=0;iconfHandle.currentConf; + t_sva_error status=SVA_OK; + t_sva_bm_error bmError; + t_sva_ff_error ffError; + t_size bufferSize; + t_size minSize=0; + + switch(bufferType) + { + case SVA_PARAMS_BUFFER_TYPE: + if (pConf->outTheLoopFilter == SVA_NONE_FILTER) return SVA_UNEXPECTED_API_CALL; + /*compute minimum size of buffer according to current configuration*/ + minSize=((((t_uint32)pConf->imageDesc.height/16)+2) * (((t_uint32)pConf->imageDesc.width/16)+2))*4; + + /*read buffer size*/ + bmError=sva_BM_GetBufferSize(bufferId,&bufferSize); + if (bmError!=SVA_BM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + /*check buffer has enought space*/ + if (bufferSize>=minSize) + { + ffError=PUSH_FIFO_ELEM(pDesc->outputDeblockingFifos.push, t_sva_buffer_id, bufferId); + if (ffError!=SVA_FIFO_OK) {status=SVA_INTERNAL_FIFOS_FULL;} + else {status=SVA_OK;} + } + else {status=SVA_INTERNAL_VIDEO_DECODER_ERROR;} + break; + + case SVA_INFOS_BUFFER_TYPE: + if (pConf->areInfosRequested == FALSE) return SVA_UNEXPECTED_API_CALL; + /*compute minimum size of buffer according to current configuration*/ + minSize=sva_DC_MP4_GetOutputParamsSize(instanceNum); + /*read buffer size*/ + bmError=sva_BM_GetBufferSize(bufferId,&bufferSize); + if (bmError!=SVA_BM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + /*check buffer has enought space*/ + if (bufferSize>=minSize) + { + ffError=PUSH_FIFO_ELEM(pDesc->outputInfosFifos.push, t_sva_buffer_id, bufferId); + if (ffError!=SVA_FIFO_OK) {status=SVA_INTERNAL_FIFOS_FULL;} + else {status=SVA_OK;} + } + else {status=SVA_INTERNAL_VIDEO_DECODER_ERROR;} + break; + + case SVA_BITSTREAM_BUFFER_TYPE: + //Store buffer in bitstream buffer fifo + ffError=PUSH_FIFO_ELEM(pDesc->inputBitstreamFifos.push,t_sva_buffer_id,bufferId); + if (ffError!= SVA_FIFO_OK) {return SVA_INTERNAL_FIFOS_FULL;} + //log byte number of compressed data provided by user + bmError=sva_BM_GetBufferSize(bufferId,&bufferSize); + if (bmError!=SVA_BM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + pDesc->status.nbCompressedDataBufferized+=bufferSize; + + break; + + case SVA_IMAGE_BUFFER_TYPE: + /*compute minimum size of buffer according to current configuration*/ + minSize=((((t_uint32)pConf->imageDesc.height * (t_uint32)pConf->imageDesc.width)*3)/2); + /*read buffer size*/ + bmError=sva_BM_GetBufferSize(bufferId,&bufferSize); + if (bmError!=SVA_BM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + /*check buffer has enought space*/ + if (bufferSize>=minSize) + { + //Push in both Fifos outputImageFifos.push and inputFwdImageFifos.push + ffError=PUSH_FIFO_ELEM(pDesc->outputImageFifos.push, t_sva_buffer_id, bufferId); + if (ffError!=SVA_FIFO_OK) {status=SVA_INTERNAL_FIFOS_FULL;} + else {status=SVA_OK;} + // ffError=PUSH_FIFO_ELEM(pDesc->inputFwdImageFifos.push, t_sva_buffer_id, bufferId); + // if (ffError!=SVA_FIFO_OK) {status=SVA_INTERNAL_FIFOS_FULL;} + // else {status=SVA_OK;} + } + else {status=SVA_INTERNAL_VIDEO_DECODER_ERROR;} + break; + + default: + status=SVA_INVALID_BUFFER_TYPE; + break; + } + + return status; +} + + + +/****************************************************************************/ +/* NAME: sva_DC_MP4_DispatchEOT() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* OUT :none */ +/* */ +/* RETURN: */ +/* */ +/****************************************************************************/ +t_sva_error sva_DC_MP4_DispatchEOT( + t_sva_service_instance_num instanceNum, + t_sva_tm_subtask_id subtaskId, + t_sva_event_desc* pEventDesc, + t_sva_service_id serviceId, + t_uint32 eventTimestamp, + t_uint32 eventDate, + t_uint32 *pNbEventsRaised, + t_uint32 maxOfEvent, + t_sva_buffer_list_id bitstreamBufferListId ) +{ + + t_sva_dc_descriptor *pDesc=&decodeDesc[instanceNum]; + t_sva_mp4_desc *pmp4Desc = &mp4Desc[instanceNum]; + t_sva_video_decoder_configuration *pConf=&pDesc->confHandle.currentConf; + t_size size; + t_sva_tm_error tmError; + t_sva_ff_error ffError; + t_logical_address paramOutAddr; + t_sva_vdc_mpeg4_param_out paramOut; + t_uint16 errorType; + t_sva_error algoError; + t_sva_blm_error blmError; + t_sva_buffer_id infoBuffer = INVALID_BUFFER_ID; + t_sva_buffer_id fwdImageBuffer = INVALID_BUFFER_ID; + t_sva_buffer_id outputImageBuffer = INVALID_BUFFER_ID; + t_sva_buffer_id bufferId = 0, lastBufferId = 0; + t_sva_dc_mp4_dependencies_desc mp4Dep; + t_sva_mp4_reference_handler referenceHandlerOut; + t_uint32 nbEvents = *pNbEventsRaised; + t_sva_event_desc *pEvent; + pEvent = &pEventDesc[nbEvents]; + + fwdImageBuffer=fwdImageBuffer; + paramOut=paramOut; + // remove dependencies from the last executed subtask and reset it to defaultDep value + ffError = POP_FIFO_ELEM(pmp4Desc->mp4Dep.inUse, t_sva_dc_mp4_dependencies_desc, mp4Dep); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + + if(pDesc->confHandle.currentConf.areInfosRequested == FALSE) + { + paramOutAddr=pDesc->paramOutAddr; //Address of blockId that is intended to contain paramOut + size=sva_DC_MP4_GetOutputParamsSize (instanceNum); + /*transfer paramout to internal block*/ + tmError=sva_TM_GetSubTaskField(subtaskId, SVA_TM_DEC_ADDR_OUT_PARAMETERS,paramOutAddr, + 0, size, FALSE); + HCL_DEBUG_ASSERT(tmError==SVA_TM_OK); + } + //infos buffer + else + { + ffError=POP_FIFO_ELEM(pDesc->outputInfosFifos.inUse,t_sva_buffer_id,infoBuffer); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + //set paramOutAddr + sva_BM_GetBufferLogicalAddress(infoBuffer, ¶mOutAddr); + //the buffer is then filled + CHECK_TABLE_OVERFLOW(*pNbEventsRaised, maxOfEvent, SVA_INTERNAL_VIDEO_DECODER_ERROR); + pEvent->eventId = SVA_EVENT_BUFFER_FILLED; + pEvent->bufferId = infoBuffer; + pEvent->serviceId = serviceId; + pEvent->eventTimestamp = (t_sva_timestamp_value) eventTimestamp; + pEvent->eventDate = (t_sva_timestamp_value) eventDate; + pEvent->extraInfo= 0; + pDesc->status.eventStats.filledCounter++; + /*update buffer status*/ + sva_BM_UpdateBufferStatus(pEvent->bufferId,SVA_BUFFER_FILLED,eventTimestamp); + nbEvents++; + //*pNbEventsRaised=nbEvents; + pEvent = &pEventDesc[nbEvents]; + + } + //provide to algo module for computing statistical data + record + algoError=sva_DC_MP4_SetOutputParams(instanceNum, (void *)paramOutAddr); + HCL_DEBUG_ASSERT(algoError == SVA_OK); + //Retrieve corresponding errorType value + algoError=sva_DC_MP4_GetLastErrorType(instanceNum, &errorType); + HCL_DEBUG_ASSERT(algoError == SVA_OK); + + switch (pConf->mode) { + + case SVA_CODEC_IMAGE_MODE : + + //generate inputBitstreamBuffer related events + ffError=POP_FIFO_ELEM(pDesc->inputBitstreamFifos.inUse,t_sva_buffer_id,pEvent->bufferId); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + //the buffer is then voided + CHECK_TABLE_OVERFLOW(*pNbEventsRaised, maxOfEvent, SVA_INTERNAL_VIDEO_DECODER_ERROR); + pEvent->eventId = SVA_EVENT_BUFFER_VOIDED; + pEvent->serviceId = serviceId; + pEvent->eventTimestamp = (t_sva_timestamp_value) eventTimestamp; + pEvent->eventDate = (t_sva_timestamp_value) eventDate; + pEvent->extraInfo= 0; + pDesc->status.eventStats.voidedCounter++; + /*update buffer status*/ + sva_BM_UpdateBufferStatus(pEvent->bufferId,SVA_BUFFER_VOIDED,eventTimestamp); + nbEvents++; + //*pNbEventsRaised=nbEvents; + pEvent = &pEventDesc[nbEvents]; + + //Flush user bitstream buffer + blmError=sva_BLM_RemoveBufferFromList(bitstreamBufferListId,&bufferId); + HCL_DEBUG_ASSERT(blmError == SVA_BLM_OK); + + + //Flush fake bitstream buffer if any + blmError=sva_BLM_RemoveBufferFromList(bitstreamBufferListId,&bufferId); + HCL_DEBUG_ASSERT(blmError == SVA_BLM_OK); + + //Push fake buffer in its fifo + ffError=PUSH_FIFO_ELEM(mp4Desc[instanceNum].fakeBitstreamFifo,t_sva_buffer_id,bufferId); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + break; + + case SVA_CODEC_SEGMENTED_MODE : + + lastBufferId = INVALID_BUFFER_ID; + POP_FIFO_ELEM(pDesc->lastPushedBufferFifo.inUse,t_sva_buffer_id,lastBufferId); + + //generate inputBitstreamBuffer related events + while(IS_FIFO_EMPTY(pDesc->inputBitstreamFifos.inUse) == FALSE) { + + ffError=READ_FIFO_ELEM(pDesc->inputBitstreamFifos.inUse,t_sva_buffer_id,bufferId); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + + if (bufferId != lastBufferId) { + + ffError=POP_FIFO_ELEM(pDesc->inputBitstreamFifos.inUse,t_sva_buffer_id,bufferId); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + + //Flush all bitstream buffers of the frame + blmError=sva_BLM_RemoveBufferFromList(bitstreamBufferListId,&bufferId); + HCL_DEBUG_ASSERT(blmError==SVA_BLM_OK); + + //the buffer is then voided + CHECK_TABLE_OVERFLOW(*pNbEventsRaised, maxOfEvent, SVA_INTERNAL_VIDEO_DECODER_ERROR); + pEvent->bufferId = bufferId; + pEvent->eventId = SVA_EVENT_BUFFER_VOIDED; + pEvent->serviceId = serviceId; + pEvent->eventTimestamp = (t_sva_timestamp_value) eventTimestamp; + pEvent->eventDate = (t_sva_timestamp_value) eventDate; + pEvent->extraInfo= 0; + pDesc->status.eventStats.voidedCounter++; + /*update buffer status*/ + sva_BM_UpdateBufferStatus(pEvent->bufferId,SVA_BUFFER_VOIDED,eventTimestamp); + + nbEvents++; + //*pNbEventsRaised=nbEvents; + pEvent = &pEventDesc[nbEvents]; + } + else break; + } + //Flush fake bitstream buffer if any + blmError=sva_BLM_RemoveBufferFromList(bitstreamBufferListId,&bufferId); + HCL_DEBUG_ASSERT(blmError == SVA_BLM_OK); + //Push fake buffer in its fifo + ffError=PUSH_FIFO_ELEM(mp4Desc[instanceNum].fakeBitstreamFifo,t_sva_buffer_id,bufferId); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + + break; + + case SVA_CODEC_STREAM_MODE : + + //generate inputBitstreamBuffer related events + lastBufferId = INVALID_BUFFER_ID; + POP_FIFO_ELEM(pDesc->lastPushedBufferFifo.inUse,t_sva_buffer_id,lastBufferId); + + do { + if (IS_FIFO_EMPTY(pDesc->inputBitstreamFifos.inUse)==TRUE) break; + ffError=POP_FIFO_ELEM(pDesc->inputBitstreamFifos.inUse, t_sva_buffer_id, bufferId); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + + if (bufferId != lastBufferId) { + //the buffer is then voided + CHECK_TABLE_OVERFLOW(*pNbEventsRaised, maxOfEvent, SVA_INTERNAL_VIDEO_DECODER_ERROR); + pEvent->eventId = SVA_EVENT_BUFFER_VOIDED; + pEvent->bufferId = bufferId; + pEvent->serviceId = serviceId; + pEvent->eventTimestamp = (t_sva_timestamp_value) eventTimestamp; + pEvent->eventDate = (t_sva_timestamp_value) eventDate; + pEvent->extraInfo= 0; + pDesc->status.eventStats.voidedCounter++; + /*update buffer status*/ + sva_BM_UpdateBufferStatus(pEvent->bufferId,SVA_BUFFER_VOIDED,eventTimestamp); + + nbEvents++; + //*pNbEventsRaised=nbEvents; + pEvent = &pEventDesc[nbEvents]; + } + + blmError=sva_BLM_RemoveBufferFromList(bitstreamBufferListId,&bufferId); + HCL_DEBUG_ASSERT(blmError!=SVA_BLM_LIST_EMPTY); + + } while (bufferId != lastBufferId); + + + //Flush fake bitstream buffer if any + blmError=sva_BLM_RemoveBufferFromList(bitstreamBufferListId,&bufferId); + HCL_DEBUG_ASSERT(blmError == SVA_BLM_OK); + + //Push fake buffer in its fifo + ffError=PUSH_FIFO_ELEM(mp4Desc[instanceNum].fakeBitstreamFifo,t_sva_buffer_id,bufferId); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + break; + + default : + return SVA_NOT_SUPPORTED_YET; + /* break; PCLint warning removal ...(unreachable) */ + + } + /*update status descriptor*/ + + if (errorType!=0) + { + pDesc->status.errorId=SVA_DECODER_TASK_PARAMETER_ERROR; + pDesc->status.eventStats.errorCounter++; + } + else {pDesc->status.errorId=SVA_DECODER_NO_ERROR;} + + + //image buffer available: HV_EVENT_BUFFER_FILLED in fact on Fwd Ref buffer + //output image buffer is only available as read only + // ffError=POP_FIFO_ELEM(pDesc->inputFwdImageFifos.inUse,t_sva_buffer_id,fwdImageBuffer); + // HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + /* //If first EOT image buffer corresponds to fake Fwd buffer => ignore + if(pDesc->firstSubtaskExecuted==TRUE) + { + //the buffer is then filled + CHECK_TABLE_OVERFLOW(*pNbEventsRaised, maxOfEvent, SVA_INTERNAL_VIDEO_DECODER_ERROR); + pEvent->eventId = SVA_EVENT_BUFFER_FILLED; + pEvent->bufferId = fwdImageBuffer; + pEvent->serviceId = serviceId; + pEvent->eventTimestamp = (t_sva_timestamp_value) eventTimestamp; + pEvent->eventDate = (t_sva_timestamp_value) eventDate; + pEvent->extraInfo= 0; + pDesc->status.eventStats.filledCounter++; + // update buffer status + sva_BM_UpdateBufferStatus(pEvent->bufferId,SVA_BUFFER_FILLED,eventTimestamp); + + nbEvents++; + *pNbEventsRaised=nbEvents; + pEvent = &pEventDesc[nbEvents]; + } + */ + + //Fwd image buffer available as read only: HV_EVENT_BUFFER_FILLED_READ_ONLY + ffError=POP_FIFO_ELEM(pDesc->outputImageFifos.inUse,t_sva_buffer_id,outputImageBuffer); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); +/**********************************************added *****************************************************/ + ffError=POP_FIFO_ELEM(pmp4Desc->referenceHandlerOutFifo,t_sva_mp4_reference_handler, referenceHandlerOut); + if (ffError!= SVA_FIFO_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + switch(referenceHandlerOut.pictureType) { + case PICTURE_CODE_I: + case PICTURE_CODE_P: + if (pmp4Desc->lastPrevRefBuffer != INVALID_BUFFER_ID) + { + CHECK_TABLE_OVERFLOW(nbEvents, maxOfEvent, SVA_INTERNAL_VIDEO_DECODER_ERROR); + pEvent->eventId = SVA_EVENT_BUFFER_FILLED; + pEvent->bufferId= pmp4Desc->lastPrevRefBuffer; + pEvent->serviceId = serviceId; + pEvent->eventTimestamp = (t_sva_timestamp_value) eventTimestamp; + pEvent->eventDate = (t_sva_timestamp_value) eventDate; + pEvent->extraInfo= 0; + pDesc->status.eventStats.filledCounter++; + /*update buffer status*/ + sva_BM_UpdateBufferStatus(pEvent->bufferId,SVA_BUFFER_FILLED,eventTimestamp); + nbEvents++; + pEvent = &pEventDesc[nbEvents]; + + pmp4Desc->lastPrevRefBuffer = INVALID_BUFFER_ID; + } + + if (pmp4Desc->lastRefBuffer != INVALID_BUFFER_ID) + { + CHECK_TABLE_OVERFLOW(nbEvents, maxOfEvent, SVA_INTERNAL_VIDEO_DECODER_ERROR); + pEvent->eventId = SVA_EVENT_BUFFER_FILLED_READ_ONLY; + pEvent->bufferId= pmp4Desc->lastRefBuffer; + pEvent->serviceId = serviceId; + pEvent->eventTimestamp = (t_sva_timestamp_value) eventTimestamp; + pEvent->eventDate = (t_sva_timestamp_value) eventDate; + pEvent->extraInfo= 0; + pDesc->status.eventStats.readOnlyCounter++; + // no status update at this point - buffer stays locked up for HCL use + nbEvents++; + pEvent = &pEventDesc[nbEvents]; + + + pmp4Desc->lastPrevRefBuffer = pmp4Desc->lastRefBuffer; + } + + pmp4Desc->lastRefBuffer = outputImageBuffer; + break; + + default: // B, + CHECK_TABLE_OVERFLOW(nbEvents, maxOfEvent, SVA_INTERNAL_VIDEO_DECODER_ERROR); + pEvent->eventId = SVA_EVENT_BUFFER_FILLED_READ_ONLY; + pEvent->bufferId= outputImageBuffer; + pEvent->serviceId = serviceId; + pEvent->eventTimestamp = (t_sva_timestamp_value) eventTimestamp; + pEvent->eventDate = (t_sva_timestamp_value) eventDate; + pEvent->extraInfo= 0; + pDesc->status.eventStats.readOnlyCounter++; + // no status update at this point - buffer stays locked up for HCL use + nbEvents++; + pEvent = &pEventDesc[nbEvents]; + + CHECK_TABLE_OVERFLOW(nbEvents, maxOfEvent, SVA_INTERNAL_VIDEO_DECODER_ERROR); + pEvent->eventId = SVA_EVENT_BUFFER_FILLED; + pEvent->bufferId= outputImageBuffer; + pEvent->serviceId = serviceId; + pEvent->eventTimestamp = (t_sva_timestamp_value) eventTimestamp; + pEvent->eventDate = (t_sva_timestamp_value) eventDate; + pEvent->extraInfo= 0; + pDesc->status.eventStats.filledCounter++; + /*update buffer status*/ + sva_BM_UpdateBufferStatus(pEvent->bufferId,SVA_BUFFER_FILLED,eventTimestamp); + nbEvents++; + pEvent = &pEventDesc[nbEvents]; + } + pDesc->status.nbImagesDecoded++; + /*********************************************** end ************************************************** + //the buffer is then filled read only + CHECK_TABLE_OVERFLOW(*pNbEventsRaised, maxOfEvent, SVA_INTERNAL_VIDEO_DECODER_ERROR); + pEvent->eventId = SVA_EVENT_BUFFER_FILLED_READ_ONLY; + pEvent->bufferId= outputImageBuffer; + pEvent->serviceId = serviceId; + pEvent->eventTimestamp = (t_sva_timestamp_value) eventTimestamp; + pEvent->eventDate = (t_sva_timestamp_value) eventDate; + pEvent->extraInfo= 0; + pDesc->status.eventStats.readOnlyCounter++; + //Tag latest FWd ref image to rise a BUFFER_FILLED_EVENT on it + pmp4Desc->lastFwdRefImageBufferId=outputImageBuffer; + + nbEvents++; + /pNbEventsRaised=nbEvents; + pEvent = &pEventDesc[nbEvents]; + + pDesc->status.nbImagesDecoded++; + */ + + //deblocking buffer : HV_EVENT_BUFFER_FILLED + if(pDesc->confHandle.currentConf.outTheLoopFilter != SVA_NONE_FILTER) + { + ffError=POP_FIFO_ELEM(pDesc->outputDeblockingFifos.inUse,t_sva_buffer_id,pEvent->bufferId); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + //the buffer is then voided + CHECK_TABLE_OVERFLOW(*pNbEventsRaised, maxOfEvent, SVA_INTERNAL_VIDEO_DECODER_ERROR); + pEvent->eventId = SVA_EVENT_BUFFER_FILLED; + pEvent->serviceId = serviceId; + pEvent->eventTimestamp = (t_sva_timestamp_value) eventTimestamp; + pEvent->eventDate = (t_sva_timestamp_value) eventDate; + pEvent->extraInfo= 0; + pDesc->status.eventStats.filledCounter++; + /*update buffer status*/ + sva_BM_UpdateBufferStatus(pEvent->bufferId,SVA_BUFFER_FILLED,eventTimestamp); + + nbEvents++; + //*pNbEventsRaised=nbEvents; + pEvent = &pEventDesc[nbEvents]; + } + + + *pNbEventsRaised=nbEvents; + + // resets MP4 dependencies + mp4Dep = pmp4Desc->defaultDep; + ffError = PUSH_FIFO_ELEM(pmp4Desc->mp4Dep.push, t_sva_dc_mp4_dependencies_desc, mp4Dep); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + + return SVA_OK; + +} + + + + + +/****************************************************************************/ +/* NAME: sva_DC_MP4_FlushBitstreams() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* OUT :none */ +/* */ +/* RETURN: */ +/* */ +/****************************************************************************/ +t_sva_error sva_DC_MP4_FlushBitstreams(t_sva_service_instance_num instanceNum) +{ + + t_uint16 i=0; + t_sva_dc_descriptor *pDesc=&decodeDesc[instanceNum]; + t_sva_buffer_id bufferId; + t_sva_blm_error blmError; + t_sva_ff_error ffError; + + + for(i=0;iconfHandle.currentConf.mode) { + + case SVA_CODEC_IMAGE_MODE : + //update user buffer status if any + blmError=sva_BLM_RemoveBufferFromList(pDesc->bufferListIdArray[i][0],&removeBufferId); + if(blmError==SVA_BLM_OK) + { + //Flush fake bitstream buffer if any + blmError=sva_BLM_RemoveBufferFromList(pDesc->bufferListIdArray[i][0],&bufferId); + HCL_DEBUG_ASSERT(blmError == SVA_BLM_OK); + + //Push fake buffer in its fifo + ffError=PUSH_FIFO_ELEM(mp4Desc[instanceNum].fakeBitstreamFifo,t_sva_buffer_id,bufferId); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + + } + break; + + case SVA_CODEC_SEGMENTED_MODE : + case SVA_CODEC_STREAM_MODE : + + // Flush LastPushedBuffer Fifos (push & inUse) + while (IS_FIFO_EMPTY(pDesc->lastPushedBufferFifo.push) == FALSE) { + ffError=POP_FIFO_ELEM(pDesc->lastPushedBufferFifo.push,t_sva_buffer_id,bufferId); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + } + + while (IS_FIFO_EMPTY(pDesc->lastPushedBufferFifo.inUse) == FALSE) { + ffError=POP_FIFO_ELEM(pDesc->lastPushedBufferFifo.inUse,t_sva_buffer_id,bufferId); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + } + + // Flush buffer list for every subtasks + bufferId = INVALID_BUFFER_ID; + do { + blmError=sva_BLM_RemoveBufferFromList(pDesc->bufferListIdArray[i][0],&bufferId); + } while (blmError==SVA_BLM_OK); + + // keep last valid buffer ID in the list because it's a fake buffer in case of mpeg4 + if (bufferId != INVALID_BUFFER_ID) { + ffError=PUSH_FIFO_ELEM(mp4Desc[instanceNum].fakeBitstreamFifo,t_sva_buffer_id,bufferId); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + } + + break; + + default : + return SVA_UNEXPECTED_API_CALL; + } + + } while(blmError == SVA_BLM_OK); + if(blmError != SVA_BLM_LIST_EMPTY) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + + } + + return SVA_OK; +} + + + +/****************************************************************************/ +/* NAME: t_sva_error sva_DC_MP4_ResolveDependencies( */ +/* t_sva_service_instance_num instanceNum */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* */ +/* */ +/* PARAMETERS: */ +/* IN : t_sva_service_instance_num */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: t_sva_error */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_sva_error sva_DC_MP4_ResolveDependencies(t_sva_service_instance_num instanceNum ) +{ + + + t_sva_dc_descriptor *pDesc=&decodeDesc[instanceNum]; + t_sva_mp4_desc *pmp4Desc = &mp4Desc[instanceNum]; + t_bool dependencyNotSolved=FALSE; + t_sva_buffer_id bufferId; + t_sva_buffer_id btBufferId; + t_sva_buffer_id prevRefBuffer = INVALID_BUFFER_ID; + t_sva_buffer_id refBuffer = INVALID_BUFFER_ID; + t_sva_dc_subtask_dependencies subtaskDep; + t_sva_dc_mp4_dependencies_desc mp4Dep; + t_sva_vdc_frame_buffer_in frameBufferIn; + t_sva_vdc_frame_buffer_out frameBufferOut; + t_sva_ff_error ffError; + t_sva_tm_error tmError; + t_sva_dc_error dcError; + t_sva_bm_error bmError; + t_physical_address phyAddr; + t_sva_error svaError; + t_sva_mp4_reference_handler referenceHandler; + + + /*enter loop where we try to solve dep for a maximum of subtasks*/ + while( (IS_FIFO_EMPTY(pDesc->subtasksDependencyFifo.push)==FALSE) && + (IS_FIFO_EMPTY(pmp4Desc->mp4Dep.push)==FALSE) && + dependencyNotSolved==FALSE) { + + /*read subtask for which we will try to solve dependencies*/ + ffError=READ_FIFO_ELEM(pDesc->subtasksDependencyFifo.push,t_sva_dc_subtask_dependencies,subtaskDep); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + // read mpeg4 dependency + ffError=READ_FIFO_ELEM(pmp4Desc->mp4Dep.push,t_sva_dc_mp4_dependencies_desc,mp4Dep); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + + if(subtaskDep.dependencies.inputBitstreamDep==NOT_RESOLVED_DEPENDENCY) //try to resolve bitstream dep. + { + svaError=sva_DC_MP4_TryToInitBitstreamFields(instanceNum,&btBufferId); //Warning: this is a bitstream init and not an update + HCL_DEBUG_ASSERT(svaError==SVA_OK); + + decodeDesc[instanceNum].currentProgrammedBitstreamBuffer=btBufferId; + } + + if((subtaskDep.dependencies.outputImageDep==NOT_RESOLVED_DEPENDENCY)&& //try to resolve image dep. + (subtaskDep.dependencies.inputBitstreamDep==RESOLVED_DEPENDENCY)) + { + if(IS_FIFO_EMPTY(pDesc->outputImageFifos.push)==FALSE) //1 image buffer available => resolve + { + //Transfer elem from outputimage fifo push to inUse + dcError=sva_DC_TransferElemFromFifoToInUseFifo(instanceNum,SVA_IMAGE_BUFFER_TYPE, &bufferId ); + if (dcError!= SVA_DC_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} +/**********************************************added**********************************************************/ + ffError=READ_FIFO_ELEM(pmp4Desc->referenceHandlerFifo,t_sva_mp4_reference_handler, referenceHandler); + if (ffError!= SVA_FIFO_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + switch(referenceHandler.pictureType) { + case PICTURE_CODE_I : + prevRefBuffer = INVALID_BUFFER_ID; //not required + if ((IS_FIFO_EMPTY(pmp4Desc->refImageFifo) == FALSE) && (IS_FIFO_EMPTY(pmp4Desc->prevRefImageFifo)) == FALSE) + { + POP_FIFO_ELEM(pmp4Desc->refImageFifo, t_sva_buffer_id, prevRefBuffer); // ref becomes previous ref + POP_FIFO_ELEM(pmp4Desc->prevRefImageFifo, t_sva_buffer_id, refBuffer); // dummy pop, to keep fifos lined up + } + + ffError = PUSH_FIFO_ELEM(pmp4Desc->refImageFifo,t_sva_buffer_id,bufferId); + if (ffError!=SVA_FIFO_OK) return SVA_INTERNAL_FIFOS_FULL; + + ffError = PUSH_FIFO_ELEM(pmp4Desc->prevRefImageFifo,t_sva_buffer_id,prevRefBuffer); + if (ffError!=SVA_FIFO_OK) return SVA_INTERNAL_FIFOS_FULL; + + break; + case PICTURE_CODE_P : // I and P pictures may be used as references + prevRefBuffer = INVALID_BUFFER_ID; + + if (IS_FIFO_EMPTY(pmp4Desc->refImageFifo) == FALSE) + READ_FIFO_ELEM(pmp4Desc->refImageFifo, t_sva_buffer_id, prevRefBuffer); + + ffError = PUSH_FIFO_ELEM(pmp4Desc->refImageFifo,t_sva_buffer_id,bufferId); + if (ffError!=SVA_FIFO_OK) return SVA_INTERNAL_FIFOS_FULL; + + ffError = PUSH_FIFO_ELEM(pmp4Desc->prevRefImageFifo,t_sva_buffer_id,prevRefBuffer); + if (ffError!=SVA_FIFO_OK) return SVA_INTERNAL_FIFOS_FULL; + break; // outputImage -> reference -> previous reference + + default: + // other picture type : B do nothing + break; + } +/**********************************************end**********************************************************/ + //update dependancy infos regarding image buffer + ffError=UPDATE_FIFO_ELEM_FIELD(pDesc->subtasksDependencyFifo.push,t_sva_dc_subtask_dependencies,.dependencies.outputImageDep,RESOLVED_DEPENDENCY); + //update subtask to take into account new buffer: update addroutframebuf/dest buffer part field + bmError=sva_BM_GetBufferPhysicalAddress(bufferId,&phyAddr); + HCL_DEBUG_ASSERT(bmError==SVA_BM_OK); + + //Init subtask Field + tmError = sva_TM_GetSubTaskField( subtaskDep.subtaskId, + SVA_TM_DEC_ADDR_OUT_FRAME_BUFFER, + (t_logical_address) &frameBufferOut, + 0, + sizeof(t_sva_vdc_frame_buffer_out), + FALSE); + if (tmError!= SVA_TM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + frameBufferOut.addr_dest_buffer=phyAddr; + tmError=sva_TM_InitSubTaskField( subtaskDep.subtaskId, + SVA_TM_DEC_ADDR_OUT_FRAME_BUFFER, + (t_logical_address) &frameBufferOut, + sizeof(t_sva_vdc_frame_buffer_out)); + if (tmError!= SVA_TM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + + //Transfer Fwd Image buffer from fifo push to fifo in use and stores it as bufferId + // ffError=POP_FIFO_ELEM(decodeDesc[instanceNum].inputFwdImageFifos.push,t_sva_buffer_id,bufferId); + // if (ffError!= SVA_FIFO_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + // ffError=PUSH_FIFO_ELEM(decodeDesc[instanceNum].inputFwdImageFifos.inUse,t_sva_buffer_id,bufferId); + // if (ffError!= SVA_FIFO_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + + // bmError=sva_BM_GetBufferPhysicalAddress(bufferId,&phyAddr); + // HCL_DEBUG_ASSERT(bmError==SVA_BM_OK); + //Init subtask Field + // frameBufferIn.addr_fwd_ref_buffer=phyAddr; + + // tmError=sva_TM_InitSubTaskField( subtaskDep.subtaskId, + // SVA_TM_DEC_ADDR_IN_FRAME_BUFFER, + // (t_logical_address) &frameBufferIn, + // sizeof(t_sva_vdc_frame_buffer_in)); + } + } + + +/************************************************************start***********************************************/ + if ( (mp4Dep.referenceDep==NOT_RESOLVED_DEPENDENCY) && //try to resolve fwd and bwd ref buffer dep. + (subtaskDep.dependencies.inputBitstreamDep==RESOLVED_DEPENDENCY) && //input bitstr dep must be resolved to know the frame type + (subtaskDep.dependencies.outputImageDep==RESOLVED_DEPENDENCY)) { // image dep should be resolved to use it as a future ref + if(IS_FIFO_EMPTY(pmp4Desc->referenceHandlerFifo)==FALSE) + { // image dep should be resolved to use it as a future ref + //handle reference images + ffError=POP_FIFO_ELEM(pmp4Desc->referenceHandlerFifo,t_sva_mp4_reference_handler, referenceHandler); + if (ffError!= SVA_FIFO_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + + switch(referenceHandler.pictureType) { + case PICTURE_CODE_I : // use no reference + frameBufferIn.addr_fwd_ref_buffer=NULL; + frameBufferIn.addr_bwd_ref_buffer=NULL; + break; + + case PICTURE_CODE_P : // use only a fwd reference + ffError=POP_FIFO_ELEM(pmp4Desc->refImageFifo, t_sva_buffer_id, refBuffer); + if (ffError!= SVA_FIFO_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + bmError=sva_BM_GetBufferPhysicalAddress(refBuffer,&phyAddr); // get the address of the last decoded I- or P- picture + HCL_DEBUG_ASSERT(bmError==SVA_BM_OK); + frameBufferIn.addr_fwd_ref_buffer=phyAddr; // fill out the HAMAC structure with it + ffError=POP_FIFO_ELEM(pmp4Desc->prevRefImageFifo, t_sva_buffer_id, prevRefBuffer); // line up prevRef Fifo with Ref Fifo + if (ffError!= SVA_FIFO_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + frameBufferIn.addr_bwd_ref_buffer=NULL; // no backward ref needed to decode P frames + break; + + case PICTURE_CODE_B : + ffError=READ_FIFO_ELEM(pmp4Desc->prevRefImageFifo, t_sva_buffer_id, prevRefBuffer); + if (ffError!= SVA_FIFO_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + bmError=sva_BM_GetBufferPhysicalAddress(prevRefBuffer,&phyAddr); // get the address of the previous ref I- or P- picture + HCL_DEBUG_ASSERT(bmError==SVA_BM_OK); + frameBufferIn.addr_fwd_ref_buffer=phyAddr; // fill out the HAMAC structure with it + + ffError=READ_FIFO_ELEM(pmp4Desc->refImageFifo, t_sva_buffer_id, refBuffer); + if (ffError!= SVA_FIFO_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + bmError=sva_BM_GetBufferPhysicalAddress(refBuffer,&phyAddr); // get the address of the last decoded I- or P- picture + HCL_DEBUG_ASSERT(bmError==SVA_BM_OK); + frameBufferIn.addr_bwd_ref_buffer=phyAddr; // to provide the backward reference image + break; + + default: + return SVA_NOT_SUPPORTED_YET; + } + //update dependancy infos regarding image buffer + ffError=UPDATE_FIFO_ELEM_FIELD(pmp4Desc->mp4Dep.push,t_sva_dc_mp4_dependencies_desc,.referenceDep,RESOLVED_DEPENDENCY); + + //update subtask to take into account new buffer: update addroutframebuf/dest buffer part field + tmError=sva_TM_InitSubTaskField(subtaskDep.subtaskId, + SVA_TM_DEC_ADDR_IN_FRAME_BUFFER, + (t_logical_address) &frameBufferIn, + sizeof(t_sva_vdc_frame_buffer_in)); + } + } + + /******************************************************* end*****************************************************/ + if(mp4Dep.outputDeblockingDep==NOT_RESOLVED_DEPENDENCY) //try to resolve deblocking dep. + { + if(IS_FIFO_EMPTY(pDesc->outputDeblockingFifos.push)==FALSE) //1 deblocking buffer available => resolve + { + //Remove Deblocking buffer from fifo and stores it as bufferId + !! transfer to InUse fifo !! + dcError=sva_DC_TransferElemFromFifoToInUseFifo(instanceNum,SVA_PARAMS_BUFFER_TYPE, &bufferId ); + if (dcError!= SVA_DC_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + + //update dependancy infos regarding image buffer + ffError=UPDATE_FIFO_ELEM_FIELD(pmp4Desc->mp4Dep.push,t_sva_dc_mp4_dependencies_desc,.outputDeblockingDep,RESOLVED_DEPENDENCY); + + //update subtask to take into account new buffer: update addroutframebuf/dest buffer part field + bmError=sva_BM_GetBufferPhysicalAddress(bufferId,&phyAddr); + HCL_DEBUG_ASSERT(bmError==SVA_BM_OK); + + //Init subtask Field + tmError = sva_TM_GetSubTaskField( subtaskDep.subtaskId, + SVA_TM_DEC_ADDR_OUT_FRAME_BUFFER, + (t_logical_address) &frameBufferOut, + 0, + sizeof(t_sva_vdc_frame_buffer_out), + FALSE); + if (tmError!= SVA_TM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + frameBufferOut.addr_deblocking_param_buffer=phyAddr; + tmError=sva_TM_InitSubTaskField( subtaskDep.subtaskId, + SVA_TM_DEC_ADDR_OUT_FRAME_BUFFER, + (t_logical_address) &frameBufferOut, + sizeof(t_sva_vdc_frame_buffer_out)); + if (tmError!= SVA_TM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + } + } + + if(mp4Dep.outputInfosDep==NOT_RESOLVED_DEPENDENCY) //try to resolve infos dep. + { + if(IS_FIFO_EMPTY(pDesc->outputInfosFifos.push)==FALSE) //1 infos buffer available => resolve + { + //Remove Info buffer from fifo and stores it as bufferId + !! transfer to InUse fifo !! + dcError=sva_DC_TransferElemFromFifoToInUseFifo(instanceNum,SVA_INFOS_BUFFER_TYPE, &bufferId ); + if (dcError!= SVA_DC_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + + //update dependancy infos regarding infos buffer + ffError=UPDATE_FIFO_ELEM_FIELD(pmp4Desc->mp4Dep.push,t_sva_dc_mp4_dependencies_desc,.outputInfosDep,RESOLVED_DEPENDENCY); + + //update subtask to take into account new buffer: update addroutframebuf/dest buffer part field + bmError=sva_BM_GetBufferPhysicalAddress(bufferId,&phyAddr); + HCL_DEBUG_ASSERT(bmError==SVA_BM_OK); + //Warning: in this case, should take into account ext bit + phyAddr=phyAddr+EXTERNAL_MEM_EXT_BIT; + + //Update subtask Field by address for paramout buffer + tmError=sva_TM_UpdateSubTaskField( SVA_TM_INTERMEDIATE_FIELD_TO_UPDATE, + subtaskDep.subtaskId, + SVA_TM_DEC_ADDR_OUT_PARAMETERS, + FCMD_NEW_ADDRESS, + phyAddr, + 0, + 0); + if (tmError!= SVA_TM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + } + } + + + //Are all subtask dep resolved? + ffError = READ_FIFO_ELEM(decodeDesc[instanceNum].subtasksDependencyFifo.push,t_sva_dc_subtask_dependencies,subtaskDep);//update infosDep + ffError = READ_FIFO_ELEM(mp4Desc[instanceNum].mp4Dep.push,t_sva_dc_mp4_dependencies_desc,mp4Dep); + + if(sva_DC_MP4_AreAllDependanciesResolved(&subtaskDep.dependencies, &mp4Dep)==TRUE) + { + t_sva_tm_timestamp immediateTimeStamp={SVA_TM_IMMEDIATE,0}; + + /*pop subtask from list of subtask for which dep has to be solved*/ + ffError=POP_FIFO_ELEM(pDesc->subtasksDependencyFifo.push,t_sva_dc_subtask_dependencies,subtaskDep); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + ffError=PUSH_FIFO_ELEM(pDesc->subtasksDependencyFifo.inUse,t_sva_dc_subtask_dependencies,subtaskDep); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + + ffError=POP_FIFO_ELEM(pmp4Desc->mp4Dep.push,t_sva_dc_mp4_dependencies_desc,mp4Dep); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + ffError=PUSH_FIFO_ELEM(pmp4Desc->mp4Dep.inUse,t_sva_dc_mp4_dependencies_desc,mp4Dep); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + + /*update state machine*/ + sva_DC_UpdateInstanceStateMachine(instanceNum,SVA_DC_ALL_DEPENDENCIES_RESOLVED); + + /*add subtask to list of schedulable subtasks*/ + tmError=sva_TM_AddElemToSubTaskList(pDesc->subtasksListId,subtaskDep.subtaskId,&immediateTimeStamp,1); + HCL_DEBUG_ASSERT(tmError==SVA_TM_OK); + + } + else + { + dependencyNotSolved=TRUE; + } + + } + + + return SVA_OK; +} + + + + +/****************************************************************************/ +/* NAME: t_sva_error sva_DC_MP4_CreateAndConfigSubtasksList( */ +/* t_sva_service_instance_num instanceNum */ +/* t_sva_service_id serviceId */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* create and configure the subtask list */ +/* */ +/* PARAMETERS: */ +/* IN : t_sva_service_instance_num */ +/* t_sva_service_id */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: t_sva_error */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_sva_error sva_DC_MP4_CreateAndConfigSubtasksList(t_sva_service_instance_num instanceNum, t_sva_service_id serviceId) +{ + + t_sva_dc_descriptor *pDesc=&decodeDesc[instanceNum]; + t_sva_mp4_desc *pmp4Desc = &mp4Desc[instanceNum]; + t_sva_video_decoder_configuration *pConf=&pDesc->confHandle.currentConf; + t_sva_tm_task_ctrl_desc decodeTaskDesc; + t_sva_tm_error tmError; + t_sva_blm_error blmError; + t_sva_tm_subtask_type subtaskType; + t_sva_tm_postprocessing_type pppType; + t_sva_fw_features fwFeature; + t_system_address fakeBufferSystemAddr; + t_sva_buffer_id fakeFwdImageBufferId; + t_uint32 i, j; + t_sva_block_id NewParamOutBlockId; + t_logical_address paramOutAddr; + t_sva_mm_error mmError=SVA_MM_OK; + t_sva_error svaError; + + t_uint32 nbBufferList=0; + t_size size; + t_sva_error status; + t_sva_ff_error ffError; + //t_size imageSize=((((t_uint32)pConf->imageDesc.height)*((t_uint32)pConf->imageDesc.width)*3)/2); + t_size imageSize=128; + + + svaError=sva_DC_MP4_GetNbBufferListByFrame(&nbBufferList); + HCL_DEBUG_ASSERT(svaError==SVA_OK); + /*create bitstream buffer list*/ + for(i=0;ibufferListIdArray[i][j]); + if (blmError!=SVA_BLM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + } + + } + + /*create subtasks*/ + decodeTaskDesc.memId=DECODE_DEFAULT_MEMORY_ID; + decodeTaskDesc.fieldnb=DECODE_FIELD_NUMBER; + decodeTaskDesc.pfieldctrldesc=(t_sva_tm_field_ctrl_desc *)defaultDecodeFieldDescArray; + + + svaError=sva_DC_MP4_GetPPPType(instanceNum, &pppType); + HCL_DEBUG_ASSERT(svaError==SVA_OK); + + svaError=sva_DC_MP4_GetSubTaskType(instanceNum, &subtaskType); + HCL_DEBUG_ASSERT(svaError==SVA_OK); + + for(i=0;isubtasksIdArray[i]); + if (tmError != SVA_TM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + } + + /*create subtasklist*/ + { + + svaError=sva_DC_MP4_GetFWFeatures(instanceNum, &fwFeature); + HCL_DEBUG_ASSERT(svaError==SVA_OK); + + tmError=sva_TM_CreateSubTaskList(SVA_TM_DECODE,serviceId,fwFeature,&pDesc->subtasksListId); + if (tmError != SVA_TM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + } + + /*Alloc and push paramout block*/ + size=sva_DC_MP4_GetOutputParamsSize (instanceNum); + sva_MM_AllocBlock(SDRAM_ID, size, SVA_MM_ALIGN_WORD, &NewParamOutBlockId); + ffError=PUSH_FIFO_ELEM(decodeDesc[instanceNum].blockIdFifo,t_sva_block_id,NewParamOutBlockId); + if (ffError!= SVA_FIFO_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + mmError=sva_MM_GetBlockLogicalAddress(NewParamOutBlockId,¶mOutAddr); + if (mmError!= SVA_MM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + decodeDesc[instanceNum].paramOutAddr=paramOutAddr; +#if 0 + /*Alloc and push First (Fake) forward reference image buffer*/ + status = SVA_AllocBuffer(SVA_IMAGE_BUFFER_TYPE, imageSize, &fakeBufferSystemAddr, &fakeFwdImageBufferId); + if (status!=SVA_OK) {return status;} +#else + { + t_uint32 loop_count; + t_uint8 *dstPtr=NULL; + t_logical_address dstAddr; + t_sva_bm_error bmError; + + imageSize = (pConf->imageDesc.height*pConf->imageDesc.width*3)/2; + /*Alloc and push First (Fake) forward reference image buffer*/ + status = SVA_AllocBuffer(SVA_IMAGE_BUFFER_TYPE, imageSize, &fakeBufferSystemAddr, &fakeFwdImageBufferId); + if (status!=SVA_OK) {return status;} + + bmError=sva_BM_GetBufferLogicalAddress(fakeFwdImageBufferId,&dstAddr); + if (bmError!=SVA_BM_OK) {return SVA_INTERNAL_NEEDS_ERROR;} + + dstPtr = (t_uint8 *)dstAddr; + for (loop_count=0;loop_count<(pConf->imageDesc.height*pConf->imageDesc.width);loop_count++) + { + *dstPtr++ = 0x0; /* Initialize luma part of fake buffer with 0x0 so that P frame is predicted black: VI15170 */ + } + for (loop_count=0;loop_count<((pConf->imageDesc.height*pConf->imageDesc.width)/2);loop_count++) + { + *dstPtr++ = 0x80; /* Initialize chroma part of fake buffer with 0x80 so that P frame is predicted black: VI15170 */ + } + dstPtr = NULL; /* Reset pointer */ + } +#endif + pDesc->fakeFwdImageBufferId=fakeFwdImageBufferId; + pmp4Desc->lastFwdRefImageBufferId=fakeFwdImageBufferId; + //Possible Upgrade: Init Fwd ref buffer to 0 + + //And stores it in FwdImageBuffer Fifo + // ffError=PUSH_FIFO_ELEM(pDesc->inputFwdImageFifos.push,t_sva_buffer_id,fakeFwdImageBufferId); + // if (ffError!= SVA_FIFO_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + //Next elem Fwd buffer will be provided when a push image buffer occur + + pmp4Desc->lastRefBuffer = INVALID_BUFFER_ID; + pmp4Desc->lastPrevRefBuffer = INVALID_BUFFER_ID; + /* Set default common dependencies*/ + pDesc->defaultDep.outputImageDep=NOT_RESOLVED_DEPENDENCY; + pDesc->defaultDep.inputBitstreamDep=NOT_RESOLVED_DEPENDENCY; + pmp4Desc->defaultDep.referenceDep=NOT_RESOLVED_DEPENDENCY; + /* Set default mpeg4 dependencies*/ + if(pConf->outTheLoopFilter != SVA_NONE_FILTER) + pmp4Desc->defaultDep.outputDeblockingDep=NOT_RESOLVED_DEPENDENCY; + else + pmp4Desc->defaultDep.outputDeblockingDep=INTERNAL_DEPENDENCY; + if(pConf->areInfosRequested == TRUE) + pmp4Desc->defaultDep.outputInfosDep=NOT_RESOLVED_DEPENDENCY; + else + pmp4Desc->defaultDep.outputInfosDep=INTERNAL_DEPENDENCY; + + /* Push subtask in subtasksDependencyFifo since they are ready to be solved*/ + for(i=0;isubtasksIdArray[i]; + subtaskDep.bitstreamBufferListId=pDesc->bufferListIdArray[i][0]; + subtaskDep.dependencies=pDesc->defaultDep; + mp4DefaultDep = pmp4Desc->defaultDep; + ffError=PUSH_FIFO_ELEM(pDesc->subtasksDependencyFifo.push, t_sva_dc_subtask_dependencies, subtaskDep); + if (ffError!=SVA_FIFO_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + ffError=PUSH_FIFO_ELEM(pmp4Desc->mp4Dep.push, t_sva_dc_mp4_dependencies_desc, mp4DefaultDep); + if (ffError!=SVA_FIFO_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + } + + return status; +} + +/****************************************************************************/ +/* NAME: sva_DC_MP4_AreAllDependanciesResolved() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: This routine enables to check all dependancies related */ +/* to a subtask */ +/* PARAMETERS: */ +/* IN : t_sva_dc_subtask_dependencies subtaskDep : Subtask to check */ +/* OUT :none */ +/* */ +/* RETURN: */ +/* t_bool */ +/*--------------------------------------------------------------------------*/ +/* USE: NA */ +/* USED BY: NA */ +/****************************************************************************/ +PUBLIC t_bool sva_DC_MP4_AreAllDependanciesResolved(t_sva_dc_dependencies_desc * commonDep, t_sva_dc_mp4_dependencies_desc * mp4Dep) +{ + + if((commonDep->outputImageDep !=NOT_RESOLVED_DEPENDENCY)&& + ( mp4Dep->referenceDep !=NOT_RESOLVED_DEPENDENCY)&& + (mp4Dep->outputInfosDep !=NOT_RESOLVED_DEPENDENCY)&& + (commonDep->inputBitstreamDep !=NOT_RESOLVED_DEPENDENCY)&& + (mp4Dep->outputDeblockingDep!=NOT_RESOLVED_DEPENDENCY)) + {return TRUE;} + else {return FALSE;} +} + +/****************************************************************************/ +/* NAME: sva_DC_MP4_CheckInputDep() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: This routine enables to check all input dependancies related*/ +/* to a subtask */ +/* PARAMETERS: */ +/* IN : t_sva_service_instance_num */ +/* OUT :none */ +/* */ +/* RETURN: */ +/* t_bool */ +/*--------------------------------------------------------------------------*/ +/* USE: NA */ +/* USED BY: NA */ +/****************************************************************************/ +PUBLIC t_bool sva_DC_MP4_CheckInputDep(t_sva_service_instance_num instanceNum) { + + //t_sva_dc_descriptor *pDesc=&decodeDesc[instanceNum]; + t_bool inputDepResolved; + t_sva_ff_error ffError; + t_sva_dc_subtask_dependencies subtaskDep; + + ffError = READ_FIFO_ELEM(decodeDesc[instanceNum].subtasksDependencyFifo.push,t_sva_dc_subtask_dependencies,subtaskDep);//update infosDep + if (ffError != SVA_FIFO_OK) + { + return FALSE; + } + + if(subtaskDep.dependencies.inputBitstreamDep !=NOT_RESOLVED_DEPENDENCY) + inputDepResolved = TRUE; + else + inputDepResolved = FALSE; + + return inputDepResolved; +} + +/****************************************************************************/ +/* NAME: sva_DC_MP4_CheckOutputDep() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: This routine enables to check all output dependancies */ +/* related to a subtask */ +/* PARAMETERS: */ +/* IN : t_sva_service_instance_num */ +/* OUT :none */ +/* */ +/* RETURN: */ +/* t_bool */ +/*--------------------------------------------------------------------------*/ +/* USE: NA */ +/* USED BY: NA */ +/****************************************************************************/ +PUBLIC t_bool sva_DC_MP4_CheckOutputDep(t_sva_service_instance_num instanceNum) { + + //t_sva_dc_descriptor *pDesc=&decodeDesc[instanceNum]; + //t_sva_mp4_desc *pMP4Desc = &mp4Desc[instanceNum]; + t_sva_mp4_desc *pmp4Desc = &mp4Desc[instanceNum]; + t_bool outputDepResolved; + t_sva_ff_error ffError; + t_sva_dc_subtask_dependencies subtaskDep; + t_sva_dc_mp4_dependencies_desc mp4Dep; + + ffError = READ_FIFO_ELEM(decodeDesc[instanceNum].subtasksDependencyFifo.push,t_sva_dc_subtask_dependencies,subtaskDep);//update infosDep + if (ffError != SVA_FIFO_OK) + { + return FALSE; + } + + ffError = READ_FIFO_ELEM(mp4Desc[instanceNum].mp4Dep.push,t_sva_dc_mp4_dependencies_desc,mp4Dep); + if (ffError != SVA_FIFO_OK) + { + return FALSE; + } + + if((subtaskDep.dependencies.outputImageDep !=NOT_RESOLVED_DEPENDENCY)&& + (mp4Dep.outputInfosDep !=NOT_RESOLVED_DEPENDENCY)&& + (mp4Dep.outputDeblockingDep!=NOT_RESOLVED_DEPENDENCY)) + { + ffError = READ_FIFO_ELEM(pmp4Desc->mp4Dep.push,t_sva_dc_mp4_dependencies_desc, mp4Dep); + outputDepResolved = TRUE; + } + else + outputDepResolved = FALSE; + + return outputDepResolved; +} + +/****************************************************************************/ +/* NAME: sva_DC_MP4_HandleFakeEvent() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: This routine handle the fake event triggered after */ +/* a flush in or out command */ +/* PARAMETERS: */ +/* IN : t_sva_service_instance_num */ +/* OUT :none */ +/* */ +/* RETURN: */ +/* t_bool */ +/*--------------------------------------------------------------------------*/ +/* USE: NA */ +/* USED BY: NA */ +/****************************************************************************/ +PUBLIC t_sva_error sva_DC_MP4_HandleFakeEvent( t_sva_tm_virtual_hw_event_id eventId, + t_sva_service_id serviceId, + t_sva_tm_subtask_id subtaskId, + t_uint32 eventTimestamp, + t_uint32 eventDate, + t_uint8 maxOfEvent, + t_uint32 *pNbEventsRaised, + t_sva_event_desc *pEventDesc) { + + t_sva_service_instance_num instanceNum = READ_INSTANCE_NUM_IN_SERVICE_ID(serviceId); + t_sva_dc_descriptor *pDesc=&decodeDesc[instanceNum]; + t_sva_mp4_desc *pmp4Desc = &mp4Desc[instanceNum]; + t_uint32 nbEvents = *pNbEventsRaised; + + if (pDesc->state == SVA_DC_FLUSHING_OUT) { + if (pmp4Desc->lastPrevRefBuffer != INVALID_BUFFER_ID) { + CHECK_TABLE_OVERFLOW(nbEvents, maxOfEvent, SVA_INTERNAL_VIDEO_DECODER_ERROR); + pEventDesc[nbEvents].eventId = SVA_EVENT_BUFFER_FILLED; + pEventDesc[nbEvents].serviceId = serviceId; + pEventDesc[nbEvents].bufferId = pmp4Desc->lastPrevRefBuffer; + pEventDesc[nbEvents].eventTimestamp = (t_sva_timestamp_value) eventTimestamp; + pEventDesc[nbEvents].eventDate = (t_sva_timestamp_value) eventDate; + pEventDesc[nbEvents].extraInfo=0; + pDesc->status.eventStats.filledCounter++; + /*update buffer status*/ + sva_BM_UpdateBufferStatus(pEventDesc[nbEvents].bufferId,SVA_BUFFER_FILLED,eventTimestamp); + nbEvents++; + } + + if (pmp4Desc->lastRefBuffer != INVALID_BUFFER_ID) { + CHECK_TABLE_OVERFLOW(nbEvents, maxOfEvent, SVA_INTERNAL_VIDEO_DECODER_ERROR); + pEventDesc[nbEvents].eventId = SVA_EVENT_BUFFER_FILLED_READ_ONLY; + pEventDesc[nbEvents].bufferId= pmp4Desc->lastRefBuffer; + pEventDesc[nbEvents].serviceId = serviceId; + pEventDesc[nbEvents].eventTimestamp = (t_sva_timestamp_value) eventTimestamp; + pEventDesc[nbEvents].eventDate = (t_sva_timestamp_value) eventDate; + pEventDesc[nbEvents].extraInfo= 0; + pDesc->status.eventStats.readOnlyCounter++; + // no status update at this point - buffer stays locked up for HCL use + nbEvents++; + + + CHECK_TABLE_OVERFLOW(nbEvents, maxOfEvent, SVA_INTERNAL_VIDEO_DECODER_ERROR); + pEventDesc[nbEvents].eventId = SVA_EVENT_BUFFER_FILLED; + pEventDesc[nbEvents].serviceId = serviceId; + pEventDesc[nbEvents].bufferId = pmp4Desc->lastRefBuffer; + pEventDesc[nbEvents].eventTimestamp = (t_sva_timestamp_value) eventTimestamp; + pEventDesc[nbEvents].eventDate = (t_sva_timestamp_value) eventDate; + pEventDesc[nbEvents].extraInfo=0; + pDesc->status.eventStats.filledCounter++; + /*update buffer status*/ + sva_BM_UpdateBufferStatus(pEventDesc[nbEvents].bufferId,SVA_BUFFER_FILLED,eventTimestamp); + nbEvents++; + } + + // resets reference buffers + pmp4Desc->lastPrevRefBuffer = INVALID_BUFFER_ID; + pmp4Desc->lastRefBuffer = INVALID_BUFFER_ID; + } + + + *pNbEventsRaised = nbEvents; + + return SVA_OK; +} + +/****************************************************************************/ +/* NAME: sva_DC_MP4_IsConfigurationValid() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: This routine checks is configuration is valid */ +/* PARAMETERS: */ +/* IN : */ +/* - pMP4Conf: configuration to check validity */ +/* - imageDesc: decoder image config to check */ +/* OUT :none */ +/* */ +/* RETURN: */ +/* - t_bool: configuration validity */ +/*--------------------------------------------------------------------------*/ +/* USE: NA */ +/* USED BY: NA */ +/****************************************************************************/ + +PRIVATE t_bool sva_DC_MP4_IsConfigurationValid( +t_sva_video_decoder_algo_mpeg4_configuration_params *pMp4Conf, +t_sva_image_desc imageDesc +) +{ + t_uint16 width; + t_uint16 height; + + HCL_ASSERT(pMp4Conf!=NULL); + + width = (imageDesc.width>>4)&0x1FF; + height = (imageDesc.height>>4)&0x1FF; + + /* The following relations must hold for MPEG4/H263: + 1<=DFW[12:4]<=396 ; 1<=DFH[12:4]<=396; DFW[12:4]*DFH[12:4]<=1200 */ + CHECK_RANGE(width, 1, 396); + CHECK_RANGE(height, 1, 396); + if(width*height>1620) { return FALSE; } + + + /* VOP Time Increment Resolution + It must be different from 0, 1 to 65535 = value of vop_time_increment_resolution + */ + if (pMp4Conf->vopTimeIncrementResolution < 1) { return FALSE; } + if (pMp4Conf->isInterlaced !=0) { return FALSE; } + return TRUE; +} + +// End of file - sva_dc_mpeg4.c --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/mpeg4/sva_dc_mpeg4.h @@ -0,0 +1,170 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ + +#ifndef __INC_SVA_DC_MP4_H +#define __INC_SVA_DC_MP4_H + +#include "hcl_defs.h" +#include "sva_decode.h" +#include "../sva_dc_algo.h" +#include "sva.h" +#include "sva_decodep.h" + +/******************************************************************************/ +/* Constants definitions */ +/******************************************************************************/ +#define START_CODE_VALUE_SH 0x02800000 +#define START_CODE_VALUE_SP 0xB6010000 + +#define OFFSET_VIDEOSTARTMARKER_GOBLAYER 7 //6 bytes 50bits +#define MP4_DECODE_MAX_FIFO_SIZE DECODE_MAX_FIFO_SIZE + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/******************************************************************************/ +/* Types definitions */ +/******************************************************************************/ + +/* + * Define the structure used to manage the subtasks dependency + */ +typedef struct { + t_sva_buffer_id bitstreamBuffer; + t_sva_buffer_id fwdReferenceImage; + t_sva_buffer_id bwdReferenceImage; + t_sva_mp4_picture_type pictureType; +} t_sva_mp4_reference_handler; + + +typedef struct { + t_sva_dc_dependencies_state outputDeblockingDep; + t_sva_dc_dependencies_state outputInfosDep; + t_sva_dc_dependencies_state referenceDep;//reference dependency +} t_sva_dc_mp4_dependencies_desc; + + +typedef struct { + t_sva_image_desc imageDesc; + t_sva_codec_mode codecMode; + t_sva_video_decoder_algo_mpeg4_configuration_params staticParams; + t_sva_fifo fifoDynamicParams; //type: t_sva_decoder_algo_mpeg4_header_infos + t_sva_fifo fifoBitstream; //type: t_sva_bitstream_desc + t_sva_fifo referenceHandlerFifo; + t_sva_fifo referenceHandlerOutFifo; + t_sva_fifo refImageFifo; // Current reference Image FIFO + t_sva_fifo prevRefImageFifo; // Previous reference Image FIFO + t_sva_fifo fakeBitstreamFifo; + t_sva_dc_mp4_dependencies_desc defaultDep; // default mpeg4 dependencies + t_sva_dc_fifo_dep mp4Dep; + t_sva_vdc_mpeg4_param_out lastFrameMp4ParamOut; + t_sva_vdc_mpeg4_param_out statisticalMp4ParamOut; + t_sva_buffer_id lastFwdRefImageBufferId; + t_sva_buffer_id lastRefBuffer; // Last reference Buffer ID + t_sva_buffer_id lastPrevRefBuffer; // Last Previous reference Buffer ID +} t_sva_mp4_desc; + +typedef enum { + SVA_DC_MP4_XXXX = SVA_DC_MP4_LAST_ERROR, + SVA_DC_MP4_FIFO_LINKED_ERROR, + SVA_DC_MP4_FIFO_FULL_ERROR, + SVA_DC_MP4_YYYY, + SVA_DC_UNEXPECTED_API_CALL, + SVA_DC_ALGO_OK = HCL_OK +} t_sva_dc_algo_error; + +typedef struct { + t_uint32 mp4SHStartCode; + t_uint32 mp4SPStartCode; +} t_mp4_start_code; + +typedef struct { + t_sva_service_id serviceId; + t_sva_buffer_id bitstreamBuffer; + t_uint32 byteOffset; + t_uint32 bitOffset; + t_sva_video_decoder_algo_mpeg4_header_infos headerInfos; +} t_sva_SetHeaderInfosParam; + + +/******************************************************************************/ +/* PUBLIC Functions */ +/******************************************************************************/ +PUBLIC t_sva_error sva_DC_MP4_Init(t_sva_service_instance_num, t_sva_codec_mode, t_sva_image_desc, const t_sva_dc_algo_configuration_params *); +PUBLIC t_sva_error sva_DC_MP4_GetMemoryNeeds(t_sva_service_instance_num, t_size *); + +PUBLIC t_sva_error sva_DC_MP4_ProvideMemoryNeeds( t_sva_service_instance_num ); +PUBLIC t_sva_error sva_DC_MP4_Close(t_sva_service_instance_num); +PUBLIC t_sva_error sva_DC_MP4_GetNextFrameParamsIn(t_sva_service_instance_num, t_sva_dc_algo_params_in *); +PUBLIC t_sva_error sva_DC_MP4_GetNextFrameParamsInOut(t_sva_service_instance_num, t_sva_dc_algo_params_inout *); +PUBLIC t_sva_error sva_DC_MP4_SetOutputParams(t_sva_service_instance_num, const t_sva_dc_algo_params_out *); +PUBLIC t_sva_error sva_DC_MP4_GetNextFrameAddr(t_sva_service_instance_num, t_physical_address *, t_uint32 *, t_sva_buffer_id *); +PUBLIC t_sva_error sva_DC_MP4_GetStatus(t_sva_service_instance_num, t_sva_dc_algo_status *, t_sva_dc_algo_status *); +PUBLIC t_sva_error sva_DC_MP4_AreNextFrameInfosAvailable(t_sva_service_instance_num, t_bool *); +PUBLIC t_size sva_DC_MP4_GetNextFrameParamsInSize(t_sva_service_instance_num); +PUBLIC t_size sva_DC_MP4_GetNextFrameParamsInOutSize(t_sva_service_instance_num); +PUBLIC t_size sva_DC_MP4_GetOutputParamsSize(t_sva_service_instance_num); + +PUBLIC t_sva_error sva_DC_MP4_PushBitstreamBuffer(t_sva_service_instance_num, t_sva_buffer_id); +PUBLIC t_sva_error sva_DC_MP4_GetLastErrorType (t_sva_service_instance_num, t_uint16 *); +PUBLIC t_sva_error sva_DC_MP4_FlushFifos(t_sva_service_instance_num); +PUBLIC t_sva_error sva_DC_MP4_DeleteFake(t_sva_service_instance_num); +PUBLIC t_sva_error sva_DC_MP4_SubTaskFieldsFullUpdate ( t_sva_service_instance_num, t_sva_buffer_id *); +PUBLIC t_sva_error sva_DC_MP4_GetParamsBufferSize(t_sva_service_instance_num, t_sva_push_mode, t_sva_filter_mode, t_uint32, t_uint32, t_size *); +PUBLIC t_sva_error sva_DC_MP4_Push(t_sva_service_instance_num, t_sva_buffer_type, t_sva_buffer_id ); +PUBLIC t_sva_error sva_DC_MP4_DispatchEOT( + t_sva_service_instance_num, + t_sva_tm_subtask_id, + t_sva_event_desc*, + t_sva_service_id, + t_uint32, + t_uint32, + t_uint32 *, + t_uint32, + t_sva_buffer_list_id); +PUBLIC t_sva_error sva_DC_MP4_HandleFakeEvent( t_sva_tm_virtual_hw_event_id , + t_sva_service_id , + t_sva_tm_subtask_id , + t_uint32 , + t_uint32 , + t_uint8 , + t_uint32 *, + t_sva_event_desc *); +PUBLIC t_sva_error sva_DC_MP4_TryToInitBitstreamFields(t_sva_service_instance_num, t_sva_buffer_id *); +PUBLIC t_sva_error sva_DC_MP4_FlushBitstreams(t_sva_service_instance_num); +PUBLIC t_sva_error sva_DC_MP4_InitHeaderInfos(t_sva_service_instance_num); +PUBLIC t_sva_error sva_DC_MP4_GSetHeaderInfos(t_sva_service_instance_num, t_sva_service_id, t_sva_buffer_id, t_uint32, t_uint32, const t_sva_header_infos *); +PUBLIC t_sva_error sva_DC_MP4_AssertEndOfBitstream(t_sva_service_instance_num, t_sva_service_id); +PUBLIC t_sva_error sva_DC_MP4_ResolveDependencies(t_sva_service_instance_num); +PUBLIC t_sva_error sva_DC_MP4_GetFWFeatures (t_sva_service_instance_num, t_sva_fw_features*); +PUBLIC t_sva_error sva_DC_MP4_GetSubTaskType(t_sva_service_instance_num, t_sva_tm_subtask_type*); +PUBLIC t_sva_error sva_DC_MP4_GetPPPType(t_sva_service_instance_num, t_sva_tm_postprocessing_type*); +PUBLIC t_sva_error sva_DC_MP4_GetNbBufferListByFrame(t_uint32*); +PUBLIC t_sva_error sva_DC_MP4_CreateAndConfigSubtasksList(t_sva_service_instance_num, t_sva_service_id ); +PUBLIC t_bool sva_DC_MP4_AreAllDependanciesResolved(t_sva_dc_dependencies_desc *, t_sva_dc_mp4_dependencies_desc *); +PUBLIC t_bool sva_DC_MP4_CheckInputDep(t_sva_service_instance_num); +PUBLIC t_bool sva_DC_MP4_CheckOutputDep(t_sva_service_instance_num); + +#ifdef __cplusplus +} /* allow C++ to use these headers */ +#endif /* __cplusplus */ + +#endif /* __INC_sva_DC_MP4_H */ +/* End of file - sva_dc_mpeg4.h */ --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/mpeg4/sva_dc_mpeg4p.c @@ -0,0 +1,686 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ + + +/*------------------------------------------------------------------------ + * Includes + *----------------------------------------------------------------------*/ + +#include "hcl_defs.h" +#include "sva_host_interface.h" +#include "sva_buffermgt.h" +#include "sva_fifo.h" + +#include "../sva_decodep.h" +#include "../sva_decodepp.h" +#include "sva_service.h" + +#include "../sva_dc_algo.h" +#include "sva_dc_mpeg4.h" +#include "sva_dc_mpeg4p.h" +#include "sva_buffermgtp.h" + + + +extern PUBLIC t_sva_dc_descriptor decodeDesc[NUM_MAX_DECODE]; + +PRIVATE t_sva_vdc_mpeg4_param_in mp4ParamIn[NUM_MAX_DECODE]; +PRIVATE t_sva_vdc_mpeg4_param_inout mp4ParamInOut[NUM_MAX_DECODE]; +extern PUBLIC t_sva_mp4_desc mp4Desc[NUM_MAX_DECODE]; + + + +PUBLIC t_sva_error sva_DC_MP4_GetFWFeatures (t_sva_service_instance_num instanceNum, t_sva_fw_features* pFwFeat) +{ + + t_sva_dc_descriptor *pDesc=&decodeDesc[instanceNum]; + t_sva_video_decoder_configuration *pConf=&pDesc->confHandle.currentConf; + t_sva_video_decoder_algo_mpeg4_configuration_params * algoConfig; + t_sva_fw_features fwFeature; + + /* TBD : This part should be done in codec independant part of the video decoder */ + + algoConfig = (t_sva_video_decoder_algo_mpeg4_configuration_params *)pConf->pAlgoConfig; + + /* Test flag Short Header */ + if(algoConfig->flagShortHeader == TRUE) + fwFeature = SVA_FW_FEAT_MPEG4_SH_DECODER; + else + fwFeature = SVA_FW_FEAT_MPEG4_SP_DECODER; + + if ( (pConf->imageDesc.height > QCIF_H) || (pConf->imageDesc.width > QCIF_W) ) + /* Case for resolution higher than QCIF (excluded) */ + fwFeature += SVA_FW_FEAT_MPEG4_DECODER_CIF; + + if ((pConf->imageDesc.height > CIF_H) || (pConf->imageDesc.width > CIF_W)) + /* Case for resolution lower or equal to CIF */ + fwFeature += SVA_FW_FEAT_MPEG4_DECODER_CIF_VGA; + + if ((pConf->ercMode == SVA_FULL_ERC) || (algoConfig->isDataPartitioned == TRUE)) fwFeature += SVA_FW_FEAT_MPEG4_DECODER_ERC; // ERC enabled ? + + // returns final combination of resolution, SP/SH and ERC + *pFwFeat = fwFeature; + + return SVA_OK; +} + + +PUBLIC t_sva_error sva_DC_MP4_GetSubTaskType(t_sva_service_instance_num instanceNum, t_sva_tm_subtask_type* pSubTask) +{ + t_sva_dc_descriptor *pDesc=&decodeDesc[instanceNum]; + t_sva_video_decoder_configuration *pConf=&pDesc->confHandle.currentConf; + if(pConf->transformId==SVA_DECODER_MPEG4_SP_L4A) + { + if (pConf->raster_out_format == TRUE) + { + *pSubTask=SVA_TM_DECODE_MPEG4_RASTER_OUT; + } + else + { + *pSubTask=SVA_TM_DECODE_MPEG4; + } + } + return SVA_OK; + +} + + +PUBLIC t_sva_error sva_DC_MP4_GetPPPType(t_sva_service_instance_num instanceNum, t_sva_tm_postprocessing_type* pPostProc) +{ + + t_sva_dc_descriptor *pDesc=&decodeDesc[instanceNum]; + t_sva_video_decoder_configuration *pConf=&pDesc->confHandle.currentConf; + + if (pConf->outTheLoopFilter == SVA_NONE_FILTER) + *pPostProc= SVA_TM_NO_POST_PROCESSING; + else + *pPostProc= SVA_TM_DEBLOCKING_DERINGING_OUT_LOOP; + + return SVA_OK; + +} + + +PUBLIC t_sva_error sva_DC_MP4_GetNbBufferListByFrame(t_uint32* pNbBUfferList) +{ + * pNbBUfferList = 1; + return SVA_OK; +} + + +/****************************************************************************/ +/* NAME: sva_DC_MP4_GetNextFrameParamsIn() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: This routine provides t_sva_vdc_mpeg4_param_in data */ +/* that will be used by decode module to update in_param fields*/ +/* PARAMETERS: */ +/* IN : t_sva_service_instance_num instanceNum */ +/* OUT :t_sva_algo_params *algoParamsIn */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/*--------------------------------------------------------------------------*/ +/* USE: NA */ +/* USED BY: NA */ +/****************************************************************************/ +PUBLIC t_sva_error sva_DC_MP4_GetNextFrameParamsIn( + t_sva_service_instance_num instanceNum, + t_sva_dc_algo_params_in *algoParamsIn) +{ t_uint32 i=0; + t_sva_ff_error ffError; + t_sva_video_decoder_algo_mpeg4_header_infos dynamicParams; + t_logical_address * inParameters = (t_logical_address *)algoParamsIn; + t_sva_param_subfield errorConcealmentConfig; + HCL_ASSERT(algoParamsIn!=NULL); + + //Dynamic param + ffError=POP_FIFO_ELEM(mp4Desc[instanceNum].fifoDynamicParams,t_sva_video_decoder_algo_mpeg4_header_infos,dynamicParams); + if (ffError!= SVA_FIFO_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + + mp4ParamIn[instanceNum].picture_coding_type = dynamicParams.pictureCodingType; + mp4ParamIn[instanceNum].quant = dynamicParams.quant; + mp4ParamIn[instanceNum].rounding_type = dynamicParams.roundingType; + mp4ParamIn[instanceNum].intra_dc_vlc_thr = dynamicParams.intraDcVlcThr; + mp4ParamIn[instanceNum].vop_fcode_forward = dynamicParams.vopFcodeForward; + mp4ParamIn[instanceNum].vop_fcode_backward = dynamicParams.vopFcodeBackward; + mp4ParamIn[instanceNum].vop_time_increment = dynamicParams.vop_time_increment; + mp4ParamIn[instanceNum].modulo_time_base = dynamicParams.modulo_time_base; + + //Static param + + mp4ParamIn[instanceNum].flag_short_header = (t_sva_param_subfield)mp4Desc[instanceNum].staticParams.flagShortHeader; + mp4ParamIn[instanceNum].vop_time_increment_resolution= (t_sva_param_subfield)mp4Desc[instanceNum].staticParams.vopTimeIncrementResolution; + mp4ParamIn[instanceNum].resync_marker_disable = (t_sva_param_subfield)mp4Desc[instanceNum].staticParams.isResyncMarkerDisable; + mp4ParamIn[instanceNum].data_partitioned = (t_sva_param_subfield)mp4Desc[instanceNum].staticParams.isDataPartitioned; + mp4ParamIn[instanceNum].reversible_vlc = (t_sva_param_subfield)mp4Desc[instanceNum].staticParams.isReversibleVlc; + + mp4ParamIn[instanceNum].frame_width = (t_sva_param_subfield)mp4Desc[instanceNum].imageDesc.width; + mp4ParamIn[instanceNum].frame_height = (t_sva_param_subfield)mp4Desc[instanceNum].imageDesc.height; + +//Static param + if (decodeDesc[instanceNum].confHandle.currentConf.ercMode == SVA_BASIC_ERC) + { + errorConcealmentConfig = 0x0000; + } + else // == SVA_FULL_ERC + { + errorConcealmentConfig = 0x003D;// turn on bit (IFI, RES, DMA, MCE) -- bit 5 (RVL) & IQZ // based on mail from FW Team + + } + /* { + if( (mp4ParamIn[instanceNum].frame_width <=352) &&( mp4ParamIn[instanceNum].frame_height<=288)) + { + errorConcealmentConfig = 0x003D; // turn on bit 0 to 4 (IFI, RES, DMA, IQZ, MCE) -- bit 5 (RVL) shall also be turned on for 8815B0 + } + else + { + errorConcealmentConfig = 0x003C; + } + }*/ + + + +mp4ParamIn[instanceNum].error_concealment_config = errorConcealmentConfig; + mp4ParamIn[instanceNum].interlaced = (t_sva_param_subfield)mp4Desc[instanceNum].staticParams.isInterlaced; + /* Sarvesh: Changes done after FW 3.9.0, * + * As suggested by Maurizio Colombo: * + * For normal MPEG4 decode, * + * quant_type must be forced to 0. * + * low_delay must be forced to 1. */ + mp4ParamIn[instanceNum].low_delay = (t_sva_param_subfield)mp4Desc[instanceNum].staticParams.low_delay; //for divx + mp4ParamIn[instanceNum].quant_type = (t_sva_param_subfield)mp4Desc[instanceNum].staticParams.quant_type; // for divx + if(mp4ParamIn[instanceNum].quant_type ) + { + for(i=0;i<64;i++) + { + mp4ParamIn[instanceNum].intra_quant_mat[i ] = (t_sva_param_subfield)mp4Desc[instanceNum].staticParams.intra_quant_mat[i]; + mp4ParamIn[instanceNum].nonintra_quant_mat[i] = (t_sva_param_subfield)mp4Desc[instanceNum].staticParams.nonintra_quant_mat[i]; + } + } + *inParameters = (t_logical_address)(&mp4ParamIn[instanceNum]); + + return SVA_OK; +} + +/****************************************************************************/ +/* NAME: sva_DC_MP4_GetNextFrameParamsInOut() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: This routine provides t_sva_vdc_mpeg4_param_inout data */ +/* that will be used by decode module to update inout_param fields*/ +/* PARAMETERS: */ +/* IN : t_sva_service_instance_num instanceNum */ +/* OUT :t_sva_algo_params *algoParamsInOut */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/*--------------------------------------------------------------------------*/ +/* USE: NA */ +/* USED BY: NA */ +/****************************************************************************/ +PUBLIC t_sva_error sva_DC_MP4_GetNextFrameParamsInOut( + t_sva_service_instance_num instanceNum, + t_sva_dc_algo_params_inout *algoParamsInOut) +{ + t_logical_address * inOutParameters = (t_logical_address *)algoParamsInOut; + + HCL_ASSERT(algoParamsInOut!=NULL); + + mp4ParamInOut[instanceNum].reserved_1 = 0; + mp4ParamInOut[instanceNum].reserved_2 = 0; + mp4ParamInOut[instanceNum].reserved_3 = 0; + mp4ParamInOut[instanceNum].reserved_4 = 0; + + *inOutParameters = (t_logical_address)(&mp4ParamInOut[instanceNum]); + + return SVA_OK; +} + + +/****************************************************************************/ +/* NAME: sva_DC_MP4_GetNextFrameAddr() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: This routine provides infos to fill bitstream_buf_position */ +/* subtask subfields */ +/* PARAMETERS: */ +/* IN : t_sva_service_instance_num instanceNum */ +/* OUT :t_physical_address *bitstreamStart */ +/* t_uint32 *bitstreamOffset */ +/* t_sva_buffer_id *bitstreamBufferId */ +/* t_bool *botEnable */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/*--------------------------------------------------------------------------*/ +/* USE: NA */ +/* USED BY: NA */ +/****************************************************************************/ +PUBLIC t_sva_error sva_DC_MP4_GetNextFrameAddr( + t_sva_service_instance_num instanceNum, + t_physical_address *bitstreamStart, + t_uint32 *bitstreamOffset, + t_sva_buffer_id *bitstreamBufferId + ) +{ + t_sva_ff_error ffError; + t_sva_bitstream_desc bitstreamDesc; + + HCL_ASSERT(bitstreamStart!=NULL); + HCL_ASSERT(bitstreamOffset!=NULL); + HCL_ASSERT(bitstreamBufferId!=NULL); + + ffError=POP_FIFO_ELEM(mp4Desc[instanceNum].fifoBitstream,t_sva_bitstream_desc,bitstreamDesc); + if (ffError!= SVA_FIFO_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + + *bitstreamStart = bitstreamDesc.bitstreamPosition.addr_bitstream_start ; //in bytes + Should be aligned on 16 bytes + *bitstreamOffset = bitstreamDesc.bitstreamPosition.bitstream_offset; //Is the offset in bits between aligned address and provided no aligned address in byte + *bitstreamBufferId = bitstreamDesc.relatedBufferId; + + return SVA_OK; +} + + + +/****************************************************************************/ +/* NAME: sva_DC_MP4_AreNextFrameInfosAvailable() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: This routine enables user to have a status on availability */ +/* of Bt buffer and also associated param */ +/* corresponds to FifoBitstream NOT Empty && */ +/* fifoDynamicParams NOT Empty */ +/* PARAMETERS: */ +/* IN : t_sva_service_instance_num instanceNum */ +/* OUT :t_bool *infosAvailable */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/*--------------------------------------------------------------------------*/ +/* USE: NA */ +/* USED BY: NA */ +/****************************************************************************/ +PUBLIC t_sva_error sva_DC_MP4_AreNextFrameInfosAvailable( + t_sva_service_instance_num instanceNum, + t_bool *infosAvailable) +{ + t_bool IsFifoBtEmpty; + t_bool IsFifoParamEmpty; + + HCL_ASSERT(infosAvailable!=NULL); + + IsFifoBtEmpty=(t_bool)IS_FIFO_EMPTY(mp4Desc[instanceNum].fifoBitstream); + IsFifoParamEmpty=(t_bool)IS_FIFO_EMPTY(mp4Desc[instanceNum].fifoDynamicParams); + + *infosAvailable= (t_bool)!(IsFifoBtEmpty || IsFifoParamEmpty); + + return SVA_OK; +} + + +/****************************************************************************/ +/* NAME: sva_DC_MP4_GetLastErrorType() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: This routine gives the value of the error type of last MPEG4*/ +/* decode subtask: should be called after sva_DC_MP4_SetOutputParams*/ +/* This is called inside sva_DC_DispatchHWVirtualEvent() */ +/* PARAMETERS: */ +/* OUT :t_uint16 *errorType */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/*--------------------------------------------------------------------------*/ +/* USE: NA */ +/* USED BY: NA */ +/****************************************************************************/ +PUBLIC t_sva_error sva_DC_MP4_GetLastErrorType (t_sva_service_instance_num instanceNum, t_uint16 *pErrorType ) +{ + HCL_ASSERT(pErrorType!=NULL); + + *pErrorType= mp4Desc[instanceNum].lastFrameMp4ParamOut.error_type; + + return SVA_OK; +} + +/****************************************************************************/ +/* NAME: sva_DC_MP4_SubTaskFieldsFullUpdate() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: - This routine tries to init ParamIn (algo specific), */ +/* ParamInOut, BitstreamBufInit of subtask in top of dep fifo */ +/* - turns the bitstream dependency flag to RESOLVED_DEPENDENCY*/ +/* PARAMETERS: */ +/* IN : t_uint8 instanceNum */ +/* OUT :none */ +/* */ +/* RETURN: */ +/* t_sva_dc_error */ +/*--------------------------------------------------------------------------*/ +/* USE: NA */ +/* USED BY: NA */ +/****************************************************************************/ +PUBLIC t_sva_error sva_DC_MP4_SubTaskFieldsFullUpdate (t_sva_service_instance_num instanceNum, t_sva_buffer_id *pBitstreamBufferId) +{ + t_sva_blm_error blmError; + t_sva_bitstream_buffer_pos bitstreamPos; + t_physical_address bitstreamBufferStartAddr=0; + t_sva_buffer_id bitstreamBufferId; + t_sva_ff_error ffError=SVA_FIFO_OK; + t_sva_tm_error tmError; + + t_sva_dc_subtask_dependencies subtaskDep; + t_sva_buffer_list_id bitstreamBufferListId; + t_physical_address bitstreamStartAddr; + t_uint32 bitstreamOffset; + + + t_sva_error algoError=SVA_OK; + t_logical_address algoParamsInAddr=0; + t_logical_address algoParamsInOutAddr=0; + + t_sva_dc_descriptor *pDesc=&decodeDesc[instanceNum]; + + //Find suitable subtask and bitstream buffer list + ffError=READ_FIFO_ELEM(pDesc->subtasksDependencyFifo.push,t_sva_dc_subtask_dependencies,subtaskDep); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + bitstreamBufferListId=subtaskDep.bitstreamBufferListId; + + algoError=sva_DC_MP4_GetNextFrameAddr(instanceNum, &bitstreamStartAddr, &bitstreamOffset, &bitstreamBufferId); + HCL_DEBUG_ASSERT(algoError == SVA_OK); + *pBitstreamBufferId=bitstreamBufferId; + + //Program add_bitstream_buf_struct field of v_bitstream_buf_pos structure + //Warning: there should be at least one buffer in list to ask for list physical address + blmError=sva_BLM_GetBufferListPhysicalAddress (bitstreamBufferListId, &bitstreamBufferStartAddr); + if (blmError!=SVA_BLM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + bitstreamPos.addr_bitstream_buf_struct=bitstreamBufferStartAddr; + bitstreamPos.addr_bitstream_start=bitstreamStartAddr; + bitstreamPos.bitstream_offset=bitstreamOffset; + + //update dependancy infos regarding bitstream buffer(and paramin) + ffError=UPDATE_FIFO_ELEM_FIELD(pDesc->subtasksDependencyFifo.push,t_sva_dc_subtask_dependencies,.dependencies.inputBitstreamDep,RESOLVED_DEPENDENCY); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + + /*update subtask */ + //BITSTREAM part + tmError=sva_TM_UpdateSubTaskField( SVA_TM_INTERMEDIATE_FIELD_TO_UPDATE, + subtaskDep.subtaskId, + SVA_TM_DEC_ADDR_IN_BITSTREAM_BUFFER, + FCMD_COPY, + (t_uint32) &bitstreamPos, + 0, + sizeof(t_sva_bitstream_buffer_pos)); + if (tmError!= SVA_TM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + //IN_PARAMETER part: should be done only one time for each subtask, ie one time as referenced by other subtasks + + + algoError=sva_DC_MP4_GetNextFrameParamsIn(instanceNum, (t_sva_dc_algo_params_in *)&algoParamsInAddr); + HCL_DEBUG_ASSERT(algoError == SVA_OK); + tmError=sva_TM_UpdateSubTaskField( SVA_TM_INTERMEDIATE_FIELD_TO_UPDATE, + subtaskDep.subtaskId, + SVA_TM_DEC_ADDR_IN_PARAMETERS, + FCMD_COPY, + (t_uint32) algoParamsInAddr, + 0, + sizeof(t_sva_vdc_mpeg4_param_in)); + if (tmError!= SVA_TM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + + //IN_FRAME_PARAMETER part + algoError=sva_DC_MP4_GetNextFrameParamsInOut(instanceNum, (t_sva_dc_algo_params_inout *)&algoParamsInOutAddr); + HCL_DEBUG_ASSERT(algoError == SVA_OK); + tmError=sva_TM_UpdateSubTaskField( SVA_TM_INTERMEDIATE_FIELD_TO_UPDATE, + subtaskDep.subtaskId, + SVA_TM_DEC_ADDR_IN_FRAME_PARAMETERS, + FCMD_COPY, + (t_uint32) algoParamsInOutAddr, + 0, + sizeof(t_sva_vdc_mpeg4_param_inout)); + if (tmError!= SVA_TM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + + return SVA_OK; +} + + +/****************************************************************************/ +/* NAME: sva_DC_MP4_TryToInitBitstreamFields() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: this function prepares the input bitstream buffer list, */ +/* based upon the bitstream mode : FRAME, SEGMENTED or STREAM */ +/* */ +/* PARAMETERS: */ +/* IN : t_uint8 instanceNum, */ +/* t_sva_buffer_id *pBitstreamBufferId */ +/* OUT :none */ +/* */ +/* RETURN: */ +/* t_sva_dc_error */ +/*--------------------------------------------------------------------------*/ +/* USE: NA */ +/* USED BY: NA */ +/****************************************************************************/ +PUBLIC t_sva_error sva_DC_MP4_TryToInitBitstreamFields( + t_uint8 instanceNum, + t_sva_buffer_id *pBitstreamBufferId + ) +{ + t_sva_buffer_id bufferId, lastPushedBufferId; + t_sva_dc_descriptor *pDesc=&decodeDesc[instanceNum]; + t_sva_dc_subtask_dependencies subtaskDep; + t_bool infosAvailable; + + t_sva_ff_error ffError=SVA_FIFO_OK; + t_sva_blm_error blmError; + t_sva_bm_error bmError; + t_sva_dc_error dcError; + + t_sva_error algoError=SVA_OK; + + t_sva_video_decoder_configuration *pConf=&pDesc->confHandle.currentConf; + t_sva_buffer_list_id bitstreamBufferListId; + t_size bufferSize; + + HCL_ASSERT(pBitstreamBufferId!=NULL); + + algoError=sva_DC_MP4_AreNextFrameInfosAvailable(instanceNum,&infosAvailable); + HCL_DEBUG_ASSERT(algoError == SVA_OK); + if(infosAvailable==TRUE) + { + //Find suitable subtask and bitstream buffer list + ffError=READ_FIFO_ELEM(pDesc->subtasksDependencyFifo.push,t_sva_dc_subtask_dependencies,subtaskDep); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + bitstreamBufferListId=subtaskDep.bitstreamBufferListId; + + //Bitstream buffer list management + switch (pConf->mode) { + case SVA_CODEC_IMAGE_MODE : + //Remove Bitstream buffer from fifo "push" and stores it in fifo "inUse" + dcError=sva_DC_TransferElemFromFifoToInUseFifo(instanceNum,SVA_BITSTREAM_BUFFER_TYPE, &bufferId ); + if (dcError!= SVA_DC_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + + //Add bitstream buffer as 1st elem of the list + blmError=sva_BLM_AddBufferInList(bitstreamBufferListId, bufferId); + if (blmError!=SVA_BLM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + + //re-init first link->addr_buffer_start address (refer fw doc), subtracting -48 was leading modification in first address of physical address, VI9780 + { + t_sva_bm_buffer_list_desc *pBufferListInfo; + t_physical_address physicalAddress; + t_sva_bm_list_elem *pBufferInfo; + t_uint32 bufferListIndex; + pBufferListInfo = (t_sva_bm_buffer_list_desc *)(bitstreamBufferListId); + + //((t_sva_bm_buffer_desc*)bufferId)->bufferListInfo[0].bufferLink.addr_buffer_start = ((t_sva_bm_buffer_desc*)bufferId)->bufferSystemAddress.physical; + + if (sva_BM_GetBufferLinkInformation( pBufferListInfo->firstBufferId, &pBufferInfo, &physicalAddress) != SVA_BM_OK) + return(SVA_INTERNAL_VIDEO_DECODER_ERROR); + + if (sva_BLM_GetBufferListIndex(bitstreamBufferListId, pBufferListInfo->firstBufferId, &bufferListIndex) != SVA_BLM_OK) + return SVA_INTERNAL_VIDEO_DECODER_ERROR; + + pBufferInfo[bufferListIndex].bufferLink.addr_buffer_start = ((t_sva_bm_buffer_desc*)pBufferListInfo->firstBufferId)->bufferSystemAddress.physical; + } + + //extension of buffer start for ERC (and avoid fake BOW) + //48 bytes, ie 36 bytes aligned 16 to take into account internal bufferisation of SVA + blmError=sva_BLM_UpdateBufferMemoryBoundaryInBufferList (bitstreamBufferListId, BEGIN_OF_FIRST_BUFFER , -48); + if (blmError!=SVA_BLM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + + //add fake buffer (only a Start code) as 2nd element so as ERC could find a resync marker if requiered + //and avoid also fake EOW + ffError=POP_FIFO_ELEM(mp4Desc[instanceNum].fakeBitstreamFifo,t_sva_buffer_id,bufferId); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + blmError=sva_BLM_AddBufferInList(bitstreamBufferListId, bufferId); + if (blmError!=SVA_BLM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + + + algoError = sva_DC_MP4_SubTaskFieldsFullUpdate(instanceNum, pBitstreamBufferId); + HCL_DEBUG_ASSERT(algoError == SVA_OK); + + break; + + case SVA_CODEC_SEGMENTED_MODE : + + lastPushedBufferId = INVALID_BUFFER_ID; + ffError=POP_FIFO_ELEM(pDesc->lastPushedBufferFifo.push,t_sva_buffer_id,lastPushedBufferId); + if (ffError == SVA_FIFO_OK) + PUSH_FIFO_ELEM(pDesc->lastPushedBufferFifo.inUse,t_sva_buffer_id,lastPushedBufferId); + + do { + //Take all Bitstream buffers out of the "push" fifo and stores them into "inUse" fifo + dcError=sva_DC_TransferElemFromFifoToInUseFifo(instanceNum,SVA_BITSTREAM_BUFFER_TYPE, &bufferId ); + if (dcError!= SVA_DC_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + + //Add bitstream buffer as 1st elem of the list + blmError=sva_BLM_AddBufferInList(bitstreamBufferListId, bufferId); + if (blmError!=SVA_BLM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + + ffError = READ_FIFO_ELEM(pDesc->inputBitstreamFifos.push, t_sva_buffer_id, bufferId); + + } while ((bufferId != lastPushedBufferId) && (ffError != SVA_FIFO_EMPTY)); + + //re-init first link->addr_buffer_start address (refer fw doc), subtracting -48 was leading modification in first address of physical address, VI9780 + { + t_sva_bm_buffer_list_desc *pBufferListInfo; + t_physical_address physicalAddress; + t_sva_bm_list_elem *pBufferInfo; + t_uint32 bufferListIndex; + pBufferListInfo = (t_sva_bm_buffer_list_desc *)(bitstreamBufferListId); + + //((t_sva_bm_buffer_desc*)bufferId)->bufferListInfo[0].bufferLink.addr_buffer_start = ((t_sva_bm_buffer_desc*)bufferId)->bufferSystemAddress.physical; + + if (sva_BM_GetBufferLinkInformation( pBufferListInfo->firstBufferId, &pBufferInfo, &physicalAddress) != SVA_BM_OK) + return(SVA_INTERNAL_VIDEO_DECODER_ERROR); + + if (sva_BLM_GetBufferListIndex(bitstreamBufferListId, pBufferListInfo->firstBufferId, &bufferListIndex) != SVA_BLM_OK) + return SVA_INTERNAL_VIDEO_DECODER_ERROR; + + pBufferInfo[bufferListIndex].bufferLink.addr_buffer_start = ((t_sva_bm_buffer_desc*)pBufferListInfo->firstBufferId)->bufferSystemAddress.physical; + } + //extension of buffer start for ERC (and avoid fake BOW) + //48 bytes, ie 36 bytes aligned 16 to take into account internal bufferisation of SVA + //following lines should be removed when starting the buffer list with a fake buffer + blmError=sva_BLM_UpdateBufferMemoryBoundaryInBufferList (bitstreamBufferListId, BEGIN_OF_FIRST_BUFFER , -48); + if (blmError!=SVA_BLM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + + // Append a fake buffer at the end of the list if necessary + ffError=POP_FIFO_ELEM(mp4Desc[instanceNum].fakeBitstreamFifo,t_sva_buffer_id,bufferId); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + blmError=sva_BLM_AddBufferInList(bitstreamBufferListId, bufferId); + if (blmError!=SVA_BLM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + + // program the subtask with all its dependencies + algoError = sva_DC_MP4_SubTaskFieldsFullUpdate(instanceNum, pBitstreamBufferId); + HCL_DEBUG_ASSERT(algoError == SVA_OK); + + break; + + case SVA_CODEC_STREAM_MODE : + + lastPushedBufferId = INVALID_BUFFER_ID; + ffError=POP_FIFO_ELEM(pDesc->lastPushedBufferFifo.push,t_sva_buffer_id,lastPushedBufferId); + if (ffError == SVA_FIFO_OK) + PUSH_FIFO_ELEM(pDesc->lastPushedBufferFifo.inUse,t_sva_buffer_id,lastPushedBufferId); + + do { + // When an end of bitstream occurs, there is no lastPushedBuffer ID available + // -> push all the buffer left to the subtask's buffer list + if (IS_FIFO_EMPTY(pDesc->inputBitstreamFifos.push) == TRUE) break; + // Take Bitstream buffers out of the "push" fifo and stores them into "inUse" fifo + dcError=sva_DC_TransferElemFromFifoToInUseFifo(instanceNum,SVA_BITSTREAM_BUFFER_TYPE, &bufferId ); + if (dcError!= SVA_DC_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + + //Add bitstream buffer in the list + blmError=sva_BLM_AddBufferInList(bitstreamBufferListId, bufferId); + if (blmError!=SVA_BLM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + } while (bufferId != lastPushedBufferId); + + //re-init first link->addr_buffer_start address (refer fw doc), subtracting -48 was leading modification in first address of physical address, VI9780 + { + t_sva_bm_buffer_list_desc *pBufferListInfo; + t_physical_address physicalAddress; + t_sva_bm_list_elem *pBufferInfo; + t_uint32 bufferListIndex; + pBufferListInfo = (t_sva_bm_buffer_list_desc *)(bitstreamBufferListId); + + //((t_sva_bm_buffer_desc*)bufferId)->bufferListInfo[0].bufferLink.addr_buffer_start = ((t_sva_bm_buffer_desc*)bufferId)->bufferSystemAddress.physical; + + if (sva_BM_GetBufferLinkInformation( pBufferListInfo->firstBufferId, &pBufferInfo, &physicalAddress) != SVA_BM_OK) + return(SVA_INTERNAL_VIDEO_DECODER_ERROR); + + if (sva_BLM_GetBufferListIndex(bitstreamBufferListId, pBufferListInfo->firstBufferId, &bufferListIndex) != SVA_BLM_OK) + return SVA_INTERNAL_VIDEO_DECODER_ERROR; + + pBufferInfo[bufferListIndex].bufferLink.addr_buffer_start = ((t_sva_bm_buffer_desc*)pBufferListInfo->firstBufferId)->bufferSystemAddress.physical; + } + //extension of buffer start for ERC (and avoid fake BOW) + //48 bytes, ie 36 bytes aligned 16 to take into account internal bufferisation of SVA + //following lines should be removed when starting the buffer list with a fake buffer + blmError=sva_BLM_UpdateBufferMemoryBoundaryInBufferList (bitstreamBufferListId, BEGIN_OF_FIRST_BUFFER , -48); + if (blmError!=SVA_BLM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + + // Append a fake buffer at the end of the list if necessary + ffError=POP_FIFO_ELEM(mp4Desc[instanceNum].fakeBitstreamFifo,t_sva_buffer_id,bufferId); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + blmError=sva_BLM_AddBufferInList(bitstreamBufferListId, bufferId); + if (blmError!=SVA_BLM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + + // push back the first frame buffer into the .push fifo at the first position + if (lastPushedBufferId != INVALID_BUFFER_ID) { + ffError = PUSH_REVERSE_FIFO_ELEM(pDesc->inputBitstreamFifos.push, t_sva_buffer_id, lastPushedBufferId); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + bmError=sva_BM_GetBufferSize(lastPushedBufferId,&bufferSize); + if (bmError!=SVA_BM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + pDesc->status.nbCompressedDataBufferized+=bufferSize; + } + + /*update state machine*/ + sva_DC_UpdateInstanceStateMachine(instanceNum,SVA_DC_PUSH); + + // program the subtask with all its dependencies + algoError = sva_DC_MP4_SubTaskFieldsFullUpdate(instanceNum, pBitstreamBufferId); + HCL_DEBUG_ASSERT(algoError == SVA_OK); + + break; + + default: + return SVA_INTERNAL_VIDEO_DECODER_ERROR; + /* break; PCLint warning removal ...*/ + } + } + return SVA_OK; +} + + + --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/mpeg4/sva_dc_mpeg4p.h @@ -0,0 +1,35 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ + +#ifndef __INC_SVA_DC_MP4P_H +#define __INC_SVA_DC_MP4P_H + +#include "hcl_defs.h" +#include "sva_decode.h" +#include "../sva_dc_algo.h" +#include "sva.h" + +PUBLIC t_sva_error sva_DC_MP4_GetNextFrameParamsInOut( t_sva_service_instance_num, t_sva_dc_algo_params_inout *); +PUBLIC t_sva_error sva_DC_MP4_GetNextFrameParamsIn( t_sva_service_instance_num, t_sva_dc_algo_params_in *); +PUBLIC t_sva_error sva_DC_MP4_GetNextFrameAddr(t_sva_service_instance_num , t_physical_address *, t_uint32 *, t_sva_buffer_id * ); +PUBLIC t_sva_error sva_DC_MP4_AreNextFrameInfosAvailable(t_sva_service_instance_num , t_bool *); +PUBLIC t_sva_error sva_DC_MP4_GetLastErrorType (t_sva_service_instance_num, t_uint16 * ); + +#endif + --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/sva.h @@ -0,0 +1,18 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ \ No newline at end of file --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/sva_dc_algo.h @@ -0,0 +1,135 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ + +#ifndef __INC_SVA_DC_ALGO_H +#define __INC_SVA_DC_ALGO_H + +#include "hcl_defs.h" +#include "sva.h" +#include "sva_decode.h" + +/******************************************************************************/ +/* Constants definitions */ +/******************************************************************************/ + +/******************************************************************************/ +/* Types definitions */ +/******************************************************************************/ +typedef struct { + t_sva_bitstream_buffer_pos bitstreamPosition; + t_sva_buffer_id relatedBufferId; +} t_sva_bitstream_desc; + +typedef struct{ + /* + * Shall be called at initialization step + * Allows to set the static parameter of a given decoder + */ + t_sva_error (*pInit) (t_sva_service_instance_num, t_sva_codec_mode, t_sva_image_desc, const t_sva_dc_algo_configuration_params *); + + t_sva_error (*pGetMemoryNeeds) (t_sva_service_instance_num, t_size *); + + /* + * + * Allows to get the internal decode module memory needs of a given decoder + */ + t_sva_error (*pProvideMemoryNeeds) (t_sva_service_instance_num ); + + /* + * Shall be called at close step + * Allows to unallocate any fifos of a given decoder + */ + t_sva_error (*pDecodeAlgoClose) (t_sva_service_instance_num); + + /* + * This function allows to transmit the output params (vdc_xxx_param_out) data + * in order to be processed by the given algorithm module and update the given Frame status + */ + t_sva_error (*pSetFrameParamOut) (t_sva_service_instance_num, const t_sva_dc_algo_params_out * ); + + /* + * The two next functions provide the sizes of the given structures in order to be allocated by the user. + * The user does not known the content of this structure. He (she) only dispatch them to the HW (task mgt module) + */ + + t_size (*pGetOutputParamsSize) (t_sva_service_instance_num); + + /* + * This function enables to know error type field of last executed + * decode subtask + */ + t_sva_error (*pGetLastErrorType) (t_sva_service_instance_num, t_uint16 *); + + /* + * This function enables to flush algo specific fifos + * It is used when end of stream is detected. + */ + t_sva_error (*pFlushFifos) (t_sva_service_instance_num); + + t_sva_error (*pDeleteFake)(t_sva_service_instance_num); + + t_sva_error (*pGetParamsBufferSize)(t_sva_service_instance_num, t_sva_push_mode, t_sva_filter_mode, t_uint32, t_uint32, t_size *); + + t_sva_error (*pPush)( t_sva_service_instance_num, t_sva_buffer_type, t_sva_buffer_id); + + t_sva_error (*pDispatchEOT)( t_sva_service_instance_num, + t_sva_tm_subtask_id, + t_sva_event_desc*, + t_sva_service_id, + t_uint32, + t_uint32, + t_uint32 *, + t_uint32, + t_sva_buffer_list_id); + + t_sva_error (*pHandleFakeEvent)(t_sva_tm_virtual_hw_event_id , + t_sva_service_id , + t_sva_tm_subtask_id , + t_uint32 , + t_uint32 , + t_uint8 , + t_uint32 *, + t_sva_event_desc *); + + t_sva_error (*pFlushBitstreams)(t_sva_service_instance_num); + + t_sva_error (*pInitHeaderInfos)(t_sva_service_instance_num); + + t_sva_error (*pGSetHeaderInfos)(t_sva_service_instance_num, t_sva_service_id, t_sva_buffer_id, t_uint32, t_uint32, const t_sva_header_infos *); + + t_sva_error (*pAssertEndOfBitstream)(t_sva_service_instance_num, t_sva_service_id); + + t_sva_error (*pResolveDependencies)(t_sva_service_instance_num); + + t_sva_error (*pCreateAndConfigSubtasksList)(t_sva_service_instance_num, t_sva_service_id); + + // Check if Input dependencies are resolved + t_bool (*pCheckInputDep)(t_sva_service_instance_num); + // Check if Output dependencies are resolved + t_bool (*pCheckOutputDep)(t_sva_service_instance_num); + + +} t_sva_algo_decode_fct_array; + +#ifdef __cplusplus +} /* allow C++ to use these headers */ +#endif /* __cplusplus */ + +#endif /* __INC_SVA_DC_ALGO_H */ +/* End of file - sva_dc_algo.h */ --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/sva_decode.c @@ -0,0 +1,2357 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ +/*------------------------------------------------------------------------ + * Includes + *----------------------------------------------------------------------*/ +#include "hcl_defs.h" +#include "sva_decode.h" +#include "sva_decodep.h" +#include "sva_decodepp.h" +#include "sva_eventmgt.h" +#include "sva_dc_algo.h" +#include "mpeg4/sva_dc_mpeg4.h" +#include "mpeg2/sva_dc_mpeg2.h" +#include "h264/sva_dc_h264.h" +#include "vc1/sva_dc_vc1.h" +#include "sva_dc_h264_dpbp.h" + + +/*------------------------------------------------------------------------ + * Private macro + *----------------------------------------------------------------------*/ + + /*------------------------------------------------------------------------ + * Global Variables + *----------------------------------------------------------------------*/ +#ifdef __DEBUG +ALIGN(32) PUBLIC t_sva_dc_debug_events eventDecodeDebugTable[NUM_MAX_DECODE]; +ALIGN(32) PUBLIC t_sva_dc_debug_commands commandDecodeDebugTable[NUM_MAX_DECODE]; +ALIGN(32) PUBLIC t_sva_dc_debug_transitions transitionDecodeDebugTable[NUM_MAX_DECODE]; +#endif + +/*instance descriptors*/ +PUBLIC t_sva_dc_descriptor decodeDesc[NUM_MAX_DECODE]; + + +/*table that describe memory allocation for decode*/ +PUBLIC const t_sva_tm_field_ctrl_desc defaultDecodeFieldDescArray[NUMBER_OF_DECODE_ALGO_SUPPORTED][DECODE_FIELD_NUMBER]= +{ + {{ SVA_TM_DCMD_ALLOCATE, {{sizeof(t_sva_vdc_frame_buffer_in), DECODE_DEFAULT_INFOS_MEMORY_ID}}}, + { SVA_TM_DCMD_ALLOCATE, {{sizeof(t_sva_vdc_frame_buffer_out), DECODE_DEFAULT_INFOS_MEMORY_ID}}}, + { SVA_TM_DCMD_ALLOCATE, {{sizeof(t_sva_vdc_internal_buf), DECODE_DEFAULT_INFOS_MEMORY_ID}}}, + //bitstream buffer list allocated by BLM module + { SVA_TM_DCMD_ALLOCATE, {{sizeof(t_sva_bitstream_buffer_pos), DECODE_DEFAULT_INFOS_MEMORY_ID}}}, + { SVA_TM_DCMD_ALLOCATE, {{sizeof(t_sva_bitstream_buffer_pos), DECODE_DEFAULT_INFOS_MEMORY_ID}}}, + { SVA_TM_DCMD_ALLOCATE, {{sizeof(t_sva_vdc_mpeg4_param_in), DECODE_DEFAULT_INFOS_MEMORY_ID}}}, + { SVA_TM_DCMD_ALLOCATE, {{sizeof(t_sva_vdc_mpeg4_param_out), DECODE_DEFAULT_INFOS_MEMORY_ID}}}, + { SVA_TM_DCMD_ALLOCATE, {{sizeof(t_sva_vdc_mpeg4_param_inout), DECODE_DEFAULT_INFOS_MEMORY_ID}}}, + { SVA_TM_DCMD_ALLOCATE, {{sizeof(t_sva_vdc_mpeg4_param_inout), DECODE_DEFAULT_INFOS_MEMORY_ID}}} + },//MPEG4 + {{SVA_TM_DCMD_ALLOCATE, {{sizeof(t_sva_vdc_frame_buffer_in), DECODE_DEFAULT_INFOS_MEMORY_ID}}}, + {SVA_TM_DCMD_ALLOCATE, {{sizeof(t_sva_vdc_frame_buffer_out), DECODE_DEFAULT_INFOS_MEMORY_ID}}}, + {SVA_TM_DCMD_ALLOCATE, {{sizeof(t_sva_vdc_internal_buf), DECODE_DEFAULT_INFOS_MEMORY_ID}}}, + //slice_info allocated in ProvideInternalNeeds + {SVA_TM_DCMD_ALLOCATE, {{sizeof(t_sva_vdc_h264_param_in), DECODE_DEFAULT_INFOS_MEMORY_ID}}}, + {SVA_TM_DCMD_ALLOCATE, {{sizeof(t_sva_vdc_h264_param_out), DECODE_DEFAULT_INFOS_MEMORY_ID}}}, + {SVA_TM_DCMD_ALLOCATE, {{sizeof(t_sva_vdc_h264_param_inout), DECODE_DEFAULT_INFOS_MEMORY_ID}}} + },//H264 + {{ SVA_TM_DCMD_ALLOCATE, {{sizeof(t_sva_vdc_frame_buffer_in), DECODE_DEFAULT_INFOS_MEMORY_ID}}}, + { SVA_TM_DCMD_ALLOCATE, {{sizeof(t_sva_vdc_frame_buffer_out), DECODE_DEFAULT_INFOS_MEMORY_ID}}}, + { SVA_TM_DCMD_ALLOCATE, {{sizeof(t_sva_vdc_internal_buf), DECODE_DEFAULT_INFOS_MEMORY_ID}}}, + //bitstream buffer list allocated by BLM module + { SVA_TM_DCMD_ALLOCATE, {{sizeof(t_sva_bitstream_buffer_pos), DECODE_DEFAULT_INFOS_MEMORY_ID}}}, + { SVA_TM_DCMD_ALLOCATE, {{sizeof(t_sva_bitstream_buffer_pos), DECODE_DEFAULT_INFOS_MEMORY_ID}}}, + { SVA_TM_DCMD_ALLOCATE, {{sizeof(t_sva_vdc_vc1_param_in), DECODE_DEFAULT_INFOS_MEMORY_ID}}}, + { SVA_TM_DCMD_ALLOCATE, {{sizeof(t_sva_vdc_vc1_param_out), DECODE_DEFAULT_INFOS_MEMORY_ID}}}, + { SVA_TM_DCMD_ALLOCATE, {{sizeof(t_sva_vdc_vc1_param_inout), DECODE_DEFAULT_INFOS_MEMORY_ID}}}, + { SVA_TM_DCMD_ALLOCATE, {{sizeof(t_sva_vdc_vc1_param_inout), DECODE_DEFAULT_INFOS_MEMORY_ID}}} + },//VC1 + {{ SVA_TM_DCMD_ALLOCATE, {{sizeof(t_sva_vdc_frame_buffer_in), DECODE_DEFAULT_INFOS_MEMORY_ID}}}, + { SVA_TM_DCMD_ALLOCATE, {{sizeof(t_sva_vdc_frame_buffer_out), DECODE_DEFAULT_INFOS_MEMORY_ID}}}, + { SVA_TM_DCMD_ALLOCATE, {{sizeof(t_sva_vdc_internal_buf), DECODE_DEFAULT_INFOS_MEMORY_ID}}}, + //bitstream buffer list allocated by BLM module + { SVA_TM_DCMD_ALLOCATE, {{sizeof(t_sva_bitstream_buffer_pos), DECODE_DEFAULT_INFOS_MEMORY_ID}}}, + { SVA_TM_DCMD_ALLOCATE, {{sizeof(t_sva_bitstream_buffer_pos), DECODE_DEFAULT_INFOS_MEMORY_ID}}}, + { SVA_TM_DCMD_ALLOCATE, {{sizeof(t_sva_vdc_Mpeg2_param_in), DECODE_DEFAULT_INFOS_MEMORY_ID}}}, + { SVA_TM_DCMD_ALLOCATE, {{sizeof(t_sva_vdc_Mpeg2_param_out), DECODE_DEFAULT_INFOS_MEMORY_ID}}}, + { SVA_TM_DCMD_ALLOCATE, {{sizeof(t_sva_vdc_Mpeg2_param_inout), DECODE_DEFAULT_INFOS_MEMORY_ID}}}, + { SVA_TM_DCMD_ALLOCATE, {{sizeof(t_sva_vdc_Mpeg2_param_inout), DECODE_DEFAULT_INFOS_MEMORY_ID}}} + }//MPEG2 +}; + +t_sva_algo_decode_fct_array decodeAlgoDesc[NUMBER_OF_DECODE_ALGO_SUPPORTED]={ + //MPEG4 + { + sva_DC_MP4_Init, //2 + sva_DC_MP4_GetMemoryNeeds, //3 + sva_DC_MP4_ProvideMemoryNeeds, //4 + sva_DC_MP4_Close, //11 + sva_DC_MP4_SetOutputParams, //9 + sva_DC_MP4_GetOutputParamsSize, //8 + sva_DC_MP4_GetLastErrorType, //10 + sva_DC_MP4_FlushFifos, //17 + sva_DC_MP4_DeleteFake, //12 + sva_DC_MP4_GetParamsBufferSize,//15 + sva_DC_MP4_Push, //6 + sva_DC_MP4_DispatchEOT, //7 + sva_DC_MP4_HandleFakeEvent, + sva_DC_MP4_FlushBitstreams, //18 + sva_DC_MP4_InitHeaderInfos, //1 + sva_DC_MP4_GSetHeaderInfos, //13 + sva_DC_MP4_AssertEndOfBitstream,//14 + sva_DC_MP4_ResolveDependencies,//16 + sva_DC_MP4_CreateAndConfigSubtasksList, //5 + sva_DC_MP4_CheckInputDep, + sva_DC_MP4_CheckOutputDep + }, + //H264 + { + sva_DC_H264_Init, //2 + sva_DC_H264_GetMemoryNeeds, //3 + sva_DC_H264_ProvideMemoryNeeds, //4 + sva_DC_H264_Close, //11 + sva_DC_H264_SetOutputParams, //9->not used + sva_DC_H264_GetOutputParamsSize, //8->not used + sva_DC_H264_GetLastErrorType, //10->not used + sva_DC_H264_FlushFifos, //17->not used + sva_DC_H264_DeleteFake, //12->not used + sva_DC_H264_GetParamsBufferSize,//15->not used + sva_DC_H264_Push, //6 + sva_DC_H264_DispatchEOT, //7 + sva_DC_H264_HandleFakeEvent, + sva_DC_H264_FlushBitstreams, //18->not used + sva_DC_H264_InitHeaderInfos, //1 + sva_DC_H264_SetHeaderInfos, //13 + sva_DC_H264_AssertEndOfBitstream,//14 + sva_DC_H264_ResolveDependencies,//16 + sva_DC_H264_CreateAndConfigSubtasksList, //5 + sva_DC_H264_CheckInputDep, + sva_DC_H264_CheckOutputDep + }, + //VC1 + { + sva_DC_VC1_Init, //2 + sva_DC_VC1_GetMemoryNeeds, //3 + sva_DC_VC1_ProvideMemoryNeeds, //4 + sva_DC_VC1_Close, //11 + sva_DC_VC1_SetOutputParams, //9 + sva_DC_VC1_GetOutputParamsSize, //8 + sva_DC_VC1_GetLastErrorType, //10 + sva_DC_VC1_FlushFifos, //17 + sva_DC_VC1_DeleteFake, //12 + sva_DC_VC1_GetParamsBufferSize,//15 + sva_DC_VC1_Push, //6 + sva_DC_VC1_DispatchEOT, //7 + sva_DC_VC1_HandleFakeEvent, + sva_DC_VC1_FlushBitstreams, //18 + sva_DC_VC1_InitHeaderInfos, //1 + sva_DC_VC1_GSetHeaderInfos, //13 + sva_DC_VC1_AssertEndOfBitstream,//14 + sva_DC_VC1_ResolveDependencies,//16 + sva_DC_VC1_CreateAndConfigSubtasksList, //5 + sva_DC_VC1_CheckInputDep, + sva_DC_VC1_CheckOutputDep + }, + //MPEG2 + { + sva_DC_Mpeg2_Init, //2 + sva_DC_Mpeg2_GetMemoryNeeds, //3 + sva_DC_Mpeg2_ProvideMemoryNeeds, //4 + sva_DC_Mpeg2_Close, //11 + sva_DC_Mpeg2_SetOutputParams, //9 + sva_DC_Mpeg2_GetOutputParamsSize, //8 + sva_DC_Mpeg2_GetLastErrorType, //10 + sva_DC_Mpeg2_FlushFifos, //17 + sva_DC_Mpeg2_DeleteFake, //12 + sva_DC_Mpeg2_GetParamsBufferSize,//15 + sva_DC_Mpeg2_Push, //6 + sva_DC_Mpeg2_DispatchEOT, //7 + sva_DC_Mpeg2_HandleFakeEvent, + sva_DC_Mpeg2_FlushBitstreams, //18 + sva_DC_Mpeg2_InitHeaderInfos, //1 + sva_DC_Mpeg2_GSetHeaderInfos, //13 + sva_DC_Mpeg2_AssertEndOfBitstream,//14 + sva_DC_Mpeg2_ResolveDependencies,//16 + sva_DC_Mpeg2_CreateAndConfigSubtasksList, //5 + sva_DC_Mpeg2_CheckInputDep, + sva_DC_Mpeg2_CheckOutputDep + }, + +}; + + + +/*------------------------------------------------------------------------ + * Private functions prototype + *----------------------------------------------------------------------*/ +PRIVATE t_sva_dc_error sva_DC_ResolveDependencies(t_sva_service_instance_num ); +PRIVATE t_bool sva_DC_IsConfigurationValid(const t_sva_video_decoder_configuration *); +//PRIVATE t_sva_error sva_DC_CheckServiceId(t_sva_service_id ); +PRIVATE t_sva_error sva_DC_DoReset(t_sva_service_id ); +PRIVATE t_sva_error sva_DC_DoFlushIn(t_sva_service_id ); +PRIVATE t_sva_error sva_DC_DoFlushOut(t_sva_service_id ); +PRIVATE void sva_DC_ResetStatus(t_sva_video_decoder_status *); +PRIVATE void sva_DC_ResetInstance(t_sva_service_id ); + + +/****************************************************************************/ +/* NAME: t_sva_DC_error sva_DC_Init ( void ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine initialize the Decode Management module. */ +/* 1) Set state of instance to SVA_SERVICE_NOT_INITIALIZED */ +/* 2) init fifos */ +/* */ +/* PARAMETERS: */ +/* IN : none */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/* - always SVA_OK */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_sva_error sva_DC_Init(void) +{ + t_uint32 i; + + /*init all grab instances*/ + for(i=0;i= 20 + #else + if (pConf->raster_out_format == TRUE) + { + return SVA_INCOHERENT_CONFIGURATION; + } + #endif + #endif + + /*check that transition is allowed*/ + if (sva_DC_isTransitionValid(instanceNum,SVA_DC_CONFIGURE)==FALSE) {return SVA_UNEXPECTED_API_CALL;} + + /*check pointer validity*/ + DC_CHECK_NULL_POINTER(pConf); + + /*check configuration validity*/ + if (sva_DC_IsConfigurationValid(pConf)==FALSE) + { + return SVA_INCOHERENT_CONFIGURATION; + } + + /*copy it internally*/ + pDesc->confHandle.currentConf=*pConf; + + //stores algo specific needs + if(pConf->transformId==SVA_DECODER_MPEG4_SP_L4A) + { + pDesc->algo=SVA_SV_MPEG4_ALGO; + } + else if(pConf->transformId==SVA_DECODER_H264) + { + pDesc->algo = SVA_SV_H264_ALGO; + } + else if(pConf->transformId==SVA_DECODER_VC1_MP_LL) + { + pDesc->algo = SVA_SV_VC1_ALGO; + } + else if(pConf->transformId==SVA_DECODER_MPEG2_MP_ML) + { + pDesc->algo = SVA_SV_MPEG2_ALGO; + } + else + { + pDesc->algo=SVA_SV_H263_ALGO; + } + + if (pConf->raster_out_format == TRUE) + { + /* raster out is only supported for following */ + if (!(pDesc->algo == SVA_SV_MPEG4_ALGO || pDesc->algo == SVA_SV_H263_ALGO)) + { + return SVA_INCOHERENT_CONFIGURATION; + } + } + + status = decodeAlgoDesc[pDesc->algo].pInit(instanceNum,pConf->mode,pConf->imageDesc,pConf->pAlgoConfig); + if (status!=SVA_OK) {return status;} + + /* Update the state machine */ + sva_DC_UpdateInstanceStateMachine(instanceNum,SVA_DC_CONFIGURE); + + return SVA_OK; +} + +/****************************************************************************/ +/* NAME: t_sva_error sva_DC_GetInternalNeeds( */ +/* t_sva_service_id serviceId, */ +/* t_size* pNeedsSize */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine returns the size of the memory needed for Decode */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - serviceId: identifier of the service */ +/* - pNeedsSize: size needed */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/* - SVA_OK : Command taken into account */ +/* - SVA_UNKNOWN_SERVICE_ID : service id is not correct */ +/* */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_sva_error sva_DC_GetInternalNeeds( + t_sva_service_id serviceId, + t_size *pNeedsSize +) +{ + t_sva_error status; + t_uint32 fifoSize; + t_sva_sv_algo algo; + t_size algoNeeds; + t_sva_error algoError; + + t_sva_service_instance_num instanceNum = READ_INSTANCE_NUM_IN_SERVICE_ID(serviceId); + t_sva_video_decoder_configuration currentConf=decodeDesc[instanceNum].confHandle.currentConf; + t_sva_dc_descriptor *pDesc=&decodeDesc[instanceNum]; + + /*check for service id validity*/ + status=sva_DC_CheckServiceId(serviceId); + if (status!=SVA_OK) {return status;} + + /*check pointer validity*/ + DC_CHECK_NULL_POINTER(pNeedsSize); + + /*compute memory size need*/ + *pNeedsSize = 0; + /*memory need by event management*/ + status=sva_EM_GetInternalNeeds(pNeedsSize); + if (status!=SVA_OK) {return status;} + + algo=pDesc->algo; + + //Stores in algo specific module static parameters in so as to be able + //to fill paramin subtask fields as we get dynamic parameters through a GetAlgoNextParamin + algoError=decodeAlgoDesc[algo].pGetMemoryNeeds(instanceNum,&algoNeeds); + HCL_DEBUG_ASSERT(algoError == SVA_OK); + + if(currentConf.mode == SVA_CODEC_IMAGE_MODE) + { + //Evaluate Internal needs (fifo needs) depending on configuration + /* inputBitstreamFifos push fifo */ + GET_FIFO_MEMORY_NEEDS(t_sva_buffer_id, PUSH_FIFO_DEFAULT_SIZE, fifoSize); + *pNeedsSize = (*pNeedsSize) + fifoSize; + /* inputBitstreamFifos inUse Fifo */ + GET_FIFO_MEMORY_NEEDS(t_sva_buffer_id, PUSH_FIFO_DEFAULT_SIZE, fifoSize); + *pNeedsSize = (*pNeedsSize) + fifoSize; + } + else // Segmented or Stream modes + { + //Evaluate Internal needs (fifo needs) depending on configuration + /* inputBitstreamFifos push fifo */ + GET_FIFO_MEMORY_NEEDS(t_sva_buffer_id, STREAMING_FIFO_DEFAULT_SIZE, fifoSize); + *pNeedsSize = (*pNeedsSize) + fifoSize; + /* inputBitstreamFifos inUse Fifo */ + GET_FIFO_MEMORY_NEEDS(t_sva_buffer_id, STREAMING_FIFO_DEFAULT_SIZE, fifoSize); + *pNeedsSize = (*pNeedsSize) + fifoSize; + + /* transition buffer fifo (push & inUse) */ + GET_FIFO_MEMORY_NEEDS(t_sva_buffer_id, DECODE_MAX_FIFO_SIZE, fifoSize); + *pNeedsSize = (*pNeedsSize) + fifoSize; + GET_FIFO_MEMORY_NEEDS(t_sva_buffer_id, DECODE_MAX_FIFO_SIZE, fifoSize); + *pNeedsSize = (*pNeedsSize) + fifoSize; + } + + /* blockIdFifo Fifo for temp paramout */ + GET_FIFO_MEMORY_NEEDS(t_sva_block_id, 1, fifoSize); + *pNeedsSize = (*pNeedsSize) + fifoSize; + /* outputImageFifo push Fifo */ + GET_FIFO_MEMORY_NEEDS(t_sva_buffer_id, PUSH_FIFO_DEFAULT_SIZE, fifoSize); + *pNeedsSize = (*pNeedsSize) + fifoSize; + /* outputImageFifo inUse Fifo */ + GET_FIFO_MEMORY_NEEDS(t_sva_buffer_id, SUBTASK_DEFAULT_NUMBER, fifoSize); + *pNeedsSize = (*pNeedsSize) + fifoSize; + /* h264DecReadOnlyFifo push Fifo */ + GET_FIFO_MEMORY_NEEDS(t_sva_buffer_id, DPB_PUSH_FIFO_DEFAULT_SIZE, fifoSize); + *pNeedsSize = (*pNeedsSize) + fifoSize; + /* inputFwdImageFifos push Fifo */ + GET_FIFO_MEMORY_NEEDS(t_sva_buffer_id, PUSH_FIFO_DEFAULT_SIZE, fifoSize); + *pNeedsSize = (*pNeedsSize) + fifoSize; + /* inputFwdImageFifos inUse Fifo */ + GET_FIFO_MEMORY_NEEDS(t_sva_buffer_id, SUBTASK_DEFAULT_NUMBER, fifoSize); + *pNeedsSize = (*pNeedsSize) + fifoSize; + + if(currentConf.areInfosRequested == TRUE) + { + /* outputInfosFifos push Fifo */ + GET_FIFO_MEMORY_NEEDS(t_sva_buffer_id, PUSH_FIFO_DEFAULT_SIZE, fifoSize); + *pNeedsSize = (*pNeedsSize) + fifoSize; + /* outputInfosFifos inUse Fifo */ + GET_FIFO_MEMORY_NEEDS(t_sva_buffer_id, SUBTASK_DEFAULT_NUMBER, fifoSize); + *pNeedsSize = (*pNeedsSize) + fifoSize; + + } + + if(currentConf.outTheLoopFilter != SVA_NONE_FILTER) + { + /* outputDeblockingFifos push Fifo */ + GET_FIFO_MEMORY_NEEDS(t_sva_buffer_id, PUSH_FIFO_DEFAULT_SIZE, fifoSize); + *pNeedsSize = (*pNeedsSize) + fifoSize; + /* outputDeblockingFifos inUse Fifo */ + GET_FIFO_MEMORY_NEEDS(t_sva_buffer_id, SUBTASK_DEFAULT_NUMBER, fifoSize); + *pNeedsSize = (*pNeedsSize) + fifoSize; + } + + /* fifoDependencies fifos */ + GET_FIFO_MEMORY_NEEDS(t_sva_dc_subtask_dependencies, SUBTASK_DEFAULT_NUMBER, fifoSize); + *pNeedsSize = (*pNeedsSize) + fifoSize; + GET_FIFO_MEMORY_NEEDS(t_sva_dc_subtask_dependencies, SUBTASK_DEFAULT_NUMBER, fifoSize); + *pNeedsSize = (*pNeedsSize) + fifoSize; + + //take into account algo Needs + *pNeedsSize = (*pNeedsSize) + algoNeeds; + + return SVA_OK; +} + +/****************************************************************************/ +/* NAME: t_sva_error sva_DC_ProvideInternalNeeds ( */ +/* t_sva_service_id serviceId */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine allows to end the configuration of the service since */ +/* memory need has been provided by user. */ +/* - create fifos */ +/* - create subtasks */ +/* - create subtasklist */ +/* - create bitstream buffer list */ +/* - enable events */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - serviceId: identifier of the service */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/* - SVA_OK : Command taken into account */ +/* - SVA_UNKNOWN_SERVICE_ID : service id is not correct */ +/* - SVA_UNEXPECTED_API_CALL : Command cannot be excecuted in */ +/* current context. */ +/* - SVA_INTERNAL_VIDEO_DECODER_ERROR : internal error */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + DONE +*/ +PUBLIC t_sva_error sva_DC_ProvideInternalNeeds(t_sva_service_id serviceId) +{ + t_sva_error status; + t_sva_service_instance_num instanceNum = READ_INSTANCE_NUM_IN_SERVICE_ID(serviceId); + t_sva_dc_descriptor *pDesc=&decodeDesc[instanceNum]; + t_sva_ff_error ffError; + t_sva_sv_algo algo=pDesc->algo; + t_sva_tm_error tmError; + + /*check for service id validity*/ + status=sva_DC_CheckServiceId(serviceId); + if (status!=SVA_OK) {return status;} + + /*check that transition is allowed*/ + if (sva_DC_isTransitionValid(instanceNum,SVA_DC_INTERNAL_NEEDS)==FALSE) {return SVA_UNEXPECTED_API_CALL;} + + /*provide some memory to event management*/ + status=sva_EM_ProvideInternalNeeds(serviceId); + if (status!=SVA_OK) {return status;} + + /*create fifo*/ + + //create algo specific fifos + status=decodeAlgoDesc[algo].pProvideMemoryNeeds(instanceNum); + if (status!=SVA_OK) {return status;} + + if(pDesc->confHandle.currentConf.mode == SVA_CODEC_IMAGE_MODE) + { + // inputBitstreamFifos push fifo + CREATE_FIFO(t_sva_buffer_id, PUSH_FIFO_DEFAULT_SIZE, pDesc->inputBitstreamFifos.push, ffError); + if (ffError != SVA_FIFO_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + // inputBitstreamFifos inUse Fifo + CREATE_FIFO(t_sva_buffer_id, PUSH_FIFO_DEFAULT_SIZE, pDesc->inputBitstreamFifos.inUse, ffError); + if (ffError != SVA_FIFO_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + + } + else // Segmented and Stream modes + { + // inputBitstreamFifos push fifo + CREATE_FIFO(t_sva_buffer_id, STREAMING_FIFO_DEFAULT_SIZE, pDesc->inputBitstreamFifos.push, ffError); + if (ffError != SVA_FIFO_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + // inputBitstreamFifos inUse Fifo + CREATE_FIFO(t_sva_buffer_id, STREAMING_FIFO_DEFAULT_SIZE, pDesc->inputBitstreamFifos.inUse, ffError); + if (ffError != SVA_FIFO_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + + //Transition buffer + CREATE_FIFO(t_sva_buffer_id, DECODE_MAX_FIFO_SIZE, pDesc->lastPushedBufferFifo.push, ffError); + if (ffError != SVA_FIFO_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + CREATE_FIFO(t_sva_buffer_id, DECODE_MAX_FIFO_SIZE, pDesc->lastPushedBufferFifo.inUse, ffError); + if (ffError != SVA_FIFO_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + } + + + // blockIdFifo Fifo to store paramout whose structure is algo dependant + CREATE_FIFO(t_sva_block_id, 1, pDesc->blockIdFifo, ffError); + if (ffError != SVA_FIFO_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + + // outputImageFifos push Fifo + CREATE_FIFO(t_sva_buffer_id, PUSH_FIFO_DEFAULT_SIZE, pDesc->outputImageFifos.push, ffError); + if (ffError != SVA_FIFO_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + // outputImageFifos inUse Fifo + CREATE_FIFO(t_sva_buffer_id, SUBTASK_DEFAULT_NUMBER, pDesc->outputImageFifos.inUse, ffError); + if (ffError != SVA_FIFO_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + // h264DecReadOnlyFifo Fifo + CREATE_FIFO(t_sva_buffer_id, DPB_PUSH_FIFO_DEFAULT_SIZE, pDesc->h264DecReadOnlyFifo, ffError); + if (ffError != SVA_FIFO_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + // inputFwdImageFifos push Fifo + // CREATE_FIFO(t_sva_buffer_id, PUSH_FIFO_DEFAULT_SIZE, pDesc->inputFwdImageFifos.push, ffError); + // if (ffError != SVA_FIFO_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + // inputFwdImageFifos inUse Fifo + // CREATE_FIFO(t_sva_buffer_id, SUBTASK_DEFAULT_NUMBER, pDesc->inputFwdImageFifos.inUse, ffError); + // if (ffError != SVA_FIFO_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + + if(pDesc->confHandle.currentConf.outTheLoopFilter != SVA_NONE_FILTER) + { + // outputDeblockingFifos push Fifo + CREATE_FIFO(t_sva_buffer_id, PUSH_FIFO_DEFAULT_SIZE, pDesc->outputDeblockingFifos.push, ffError); + if (ffError != SVA_FIFO_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + // outputDeblockingFifos inUse Fifo + CREATE_FIFO(t_sva_buffer_id, SUBTASK_DEFAULT_NUMBER, pDesc->outputDeblockingFifos.inUse, ffError); + if (ffError != SVA_FIFO_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + } + + if(pDesc->confHandle.currentConf.areInfosRequested == TRUE) + { + // outputInfosFifos Fifo + CREATE_FIFO(t_sva_buffer_id, PUSH_FIFO_DEFAULT_SIZE, pDesc->outputInfosFifos.push, ffError); + if (ffError != SVA_FIFO_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + // outputInfosFifos Fifo + CREATE_FIFO(t_sva_buffer_id, SUBTASK_DEFAULT_NUMBER, pDesc->outputInfosFifos.inUse, ffError); + if (ffError != SVA_FIFO_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + } + + // fifoDependencies fifo + CREATE_FIFO(t_sva_dc_subtask_dependencies, SUBTASK_DEFAULT_NUMBER, pDesc->subtasksDependencyFifo.push, ffError); + if (ffError != SVA_FIFO_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + CREATE_FIFO(t_sva_dc_subtask_dependencies, SUBTASK_DEFAULT_NUMBER, pDesc->subtasksDependencyFifo.inUse, ffError); + if (ffError != SVA_FIFO_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + + status = decodeAlgoDesc[pDesc->algo].pCreateAndConfigSubtasksList(instanceNum, serviceId); + if (status!=SVA_OK) {return status;} + + /* enable events for subtask list*/ + /* we enable EOT, UBU, BOW, EOW, ERR and EOK event*/ + /* we also enable activate, inactivate and fake event*/ + tmError=sva_TM_DisableAllVirtualHwEvents(pDesc->subtasksListId); + if (tmError != SVA_TM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + tmError=sva_TM_EnableVirtualHwEvents(pDesc->subtasksListId,SVA_TM_EOT_HW_EVENT); + if (tmError != SVA_TM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + tmError=sva_TM_EnableVirtualHwEvents(pDesc->subtasksListId,SVA_TM_EOK_HW_EVENT); + if (tmError != SVA_TM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + tmError=sva_TM_EnableVirtualHwEvents(pDesc->subtasksListId,SVA_TM_UBU_HW_EVENT); + if (tmError != SVA_TM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + tmError=sva_TM_EnableVirtualHwEvents(pDesc->subtasksListId,SVA_TM_BOW_HW_EVENT); + if (tmError != SVA_TM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + tmError=sva_TM_EnableVirtualHwEvents(pDesc->subtasksListId,SVA_TM_EOW_HW_EVENT); + if (tmError != SVA_TM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + tmError=sva_TM_EnableVirtualHwEvents(pDesc->subtasksListId,SVA_TM_ERR_HW_EVENT); + if (tmError != SVA_TM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + tmError=sva_TM_EnableVirtualHwEvents(pDesc->subtasksListId,SVA_TM_INACTIVE_HW_EVENT); + if (tmError != SVA_TM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + tmError=sva_TM_EnableVirtualHwEvents(pDesc->subtasksListId,SVA_TM_ACTIVE_HW_EVENT); + if (tmError != SVA_TM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + tmError=sva_TM_EnableVirtualHwEvents(pDesc->subtasksListId,SVA_TM_FAKE_HW_EVENT); + if (tmError != SVA_TM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + + + + + + /* Update the state machine */ + sva_DC_UpdateInstanceStateMachine(instanceNum,SVA_DC_INTERNAL_NEEDS); + + return SVA_OK; +} + +/****************************************************************************/ +/* NAME: t_sva_error sva_DC_Activate( */ +/* t_sva_service_id serviceId, */ +/* t_sva_service_mode serviceMode, */ +/* t_sva_fw_id *pFwId */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine activates the Decode service */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - serviceId: identifier of the service */ +/* - serviceMode : set service to real_time or not */ +/* */ +/* OUT : */ +/* - pFwId : identifier of firmware id for which user shall provide location*/ +/* */ +/* RETURN: */ +/* t_sva_error */ +/* - SVA_OK : Command taken into account */ +/* - SVA_UNKNOWN_SERVICE_ID : service id is not correct */ +/* - SVA_UNEXPECTED_API_CALL : Command cannot be excecuted in */ +/* current context. */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + TO DO : + - error code ???? of sva_TM_ActivateSubTaskList +*/ +PUBLIC t_sva_error sva_DC_Activate( + t_sva_service_id serviceId, + t_sva_service_mode serviceMode, + t_sva_fw_id *pFwId +) +{ + t_sva_error status; + t_sva_service_instance_num instanceNum = READ_INSTANCE_NUM_IN_SERVICE_ID(serviceId); + t_sva_dc_descriptor *pDesc=&decodeDesc[instanceNum]; + + /*check for service id validity*/ + status=sva_DC_CheckServiceId(serviceId); + if (status!=SVA_OK) {return status;} + + /*check that transition is allowed*/ + if (sva_DC_isTransitionValid(instanceNum,SVA_DC_ACTIVATE)==FALSE) {return SVA_UNEXPECTED_API_CALL;} + + /* Update the state machine */ + /* Update state machine before command is send to task management to avoid race condition */ + sva_DC_UpdateInstanceStateMachine(instanceNum,SVA_DC_ACTIVATE); + + /*activate subTaskList*/ + /*handle informative error code*/ + status=sva_TM_ActivateSubTaskList(pDesc->subtasksListId,serviceMode,pFwId); + if (status != SVA_OK && status != SVA_FW_SWITCH_OCCURED && status != SVA_FW_SWITCH_DELAYED) + { + sva_DC_UpdateInstanceStateMachine(instanceNum,SVA_DC_CANCEL); + + return status; + } + + return status; +} + +/****************************************************************************/ +/* NAME: t_sva_error sva_DC_Inactivate( */ +/* t_sva_service_id serviceId */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine deactivates the decode service */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - serviceId: identifier of the service */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/* - SVA_OK : Command taken into account */ +/* - SVA_UNKNOWN_SERVICE_ID : service id is not correct */ +/* - SVA_UNEXPECTED_API_CALL : Command cannot be excecuted in */ +/* current context. */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + TO DO : + - error code ???? of sva_TM_InActivateSubTaskList +*/ +PUBLIC t_sva_error sva_DC_Inactivate(t_sva_service_id serviceId) +{ + t_sva_error status; + t_sva_service_instance_num instanceNum = READ_INSTANCE_NUM_IN_SERVICE_ID(serviceId); + t_sva_dc_descriptor *pDesc=&decodeDesc[instanceNum]; + t_sva_tm_error tmError; + + /*check for service id validity*/ + status=sva_DC_CheckServiceId(serviceId); + if (status!=SVA_OK) {return status;} + + /*check that transition is allowed*/ + if (sva_DC_isTransitionValid(instanceNum,SVA_DC_INACTIVATE)==FALSE) {return SVA_UNEXPECTED_API_CALL;} + + /* Update the state machine */ + /* Update state machine before command is send to task management to avoid race condition */ + sva_DC_UpdateInstanceStateMachine(instanceNum,SVA_DC_INACTIVATE); + + /*inactivate subTaskList*/ + /*handle informative error code*/ + tmError=sva_TM_InActivateSubTaskList(pDesc->subtasksListId); + if (tmError != SVA_TM_OK) + { + sva_DC_UpdateInstanceStateMachine(instanceNum,SVA_DC_CANCEL); + + return SVA_INTERNAL_VIDEO_DECODER_ERROR; + } + + return SVA_OK; +} + +/****************************************************************************/ +/* NAME: t_sva_error sva_DC_Control ( */ +/* t_sva_service_id serviceId, */ +/* t_sva_service_cmd_id cmdId, */ +/* t_uint32 param */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine allows to control an instance of a Decode Service */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - serviceId: identifier of the given service */ +/* - cmdId: command to apply to the decode */ +/* - param: parameter use by command */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/* - SVA_OK : Command taken into account */ +/* - SVA_UNKNOWN_SERVICE_ID : service id is not correct */ +/* - SVA_UNEXPECTED_API_CALL : Command cannot be excecuted in */ +/* current context. */ +/* - SVA_UNKNOWN_CMD_ID : Command to execute is unknown */ +/* - SVA_INTERNAL_VIDEO_DECODER_ERROR : internal error */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + DONE +*/ +PUBLIC t_sva_error sva_DC_Control( + t_sva_service_id serviceId, + t_sva_service_cmd_id cmdId, + t_uint32 param +) +{ + t_sva_service_instance_num instanceNum = READ_INSTANCE_NUM_IN_SERVICE_ID(serviceId); + t_sva_dc_descriptor *pDesc=&decodeDesc[instanceNum]; + t_sva_error status = SVA_UNEXPECTED_API_CALL; + t_sva_error error; + t_sva_tm_error tmError; + + /*check for service id validity*/ + error=sva_DC_CheckServiceId(serviceId); + if (error!=SVA_OK) {return error;} + +#ifdef __DEBUG + { + t_uint32 systemTime; + + SVA_GetServiceSystemTime(serviceId,&systemTime); + commandDecodeDebugTable[instanceNum].commandDebugDesc[commandDecodeDebugTable[instanceNum].nbOfCommandReceived%LOG_DEPTH].command=cmdId; + commandDecodeDebugTable[instanceNum].commandDebugDesc[commandDecodeDebugTable[instanceNum].nbOfCommandReceived%LOG_DEPTH].systemTime=systemTime; + commandDecodeDebugTable[instanceNum].commandDebugDesc[commandDecodeDebugTable[instanceNum].nbOfCommandReceived%LOG_DEPTH].parameter=param; + commandDecodeDebugTable[instanceNum].nbOfCommandReceived++; + } +#endif + + /*handle command*/ + switch(cmdId) + { + case SVA_SERVICE_START: + if (sva_DC_isTransitionValid(instanceNum,SVA_DC_CONTROL_START)==TRUE) + { + /* transition are force before sending task command to avoid race condition*/ + sva_DC_UpdateInstanceStateMachine(instanceNum,SVA_DC_CONTROL_START); + /* as we accepted some push before (or after a restart) some dependencies are perhaps + already scheduled + */ + if (GET_FIFO_NB_ELEMS(pDesc->subtasksDependencyFifo.push)!=SUBTASK_DEFAULT_NUMBER) + { + sva_DC_UpdateInstanceStateMachine(instanceNum,SVA_DC_ALL_DEPENDENCIES_RESOLVED); + } + /*now send start command*/ + tmError=sva_TM_SendTaskCommand(pDesc->subtasksListId,SVA_TM_TCMD_START,param); + HCL_DEBUG_ASSERT(tmError==SVA_TM_OK); + + status = SVA_OK; + } + break; + case SVA_SERVICE_STOP: + if (sva_DC_isTransitionValid(instanceNum,SVA_DC_CONTROL_STOP)==TRUE) + { + /* transition are force before sending task command to avoid race condition*/ + sva_DC_UpdateInstanceStateMachine(instanceNum,SVA_DC_CONTROL_STOP); + /*stop subtask list*/ + tmError=sva_TM_SendTaskCommand(pDesc->subtasksListId,SVA_TM_TCMD_STOP,param); + HCL_DEBUG_ASSERT(tmError==SVA_TM_OK); + + status = SVA_OK; + } + break; + case SVA_SERVICE_ABORT: + if (sva_DC_isTransitionValid(instanceNum,SVA_DC_CONTROL_ABORT)==TRUE) + { + /* transition are force before sending task command to avoid race condition*/ + sva_DC_UpdateInstanceStateMachine(instanceNum,SVA_DC_CONTROL_ABORT); + /*abort subtask list*/ + tmError=sva_TM_SendTaskCommand(pDesc->subtasksListId,SVA_TM_TCMD_ABORT,param); + HCL_DEBUG_ASSERT(tmError==SVA_TM_OK); + + status = SVA_OK; + } + break; + case SVA_SERVICE_RESET: + if (sva_DC_isTransitionValid(instanceNum,SVA_DC_RESET)==TRUE) + { + /*do instance clean-up so service can restart*/ + status = sva_DC_DoReset(serviceId); + if (status == SVA_OK) + sva_DC_UpdateInstanceStateMachine(instanceNum,SVA_DC_RESET); + + {} + } + break; + case SVA_SERVICE_FLUSH_IN: + if (sva_DC_isTransitionValid(instanceNum,SVA_DC_FLUSH_IN)==TRUE) + { + /*flush input buffer if necessary*/ + status = sva_DC_DoFlushIn(serviceId); + if (status == SVA_OK) + { + sva_DC_UpdateInstanceStateMachine(instanceNum,SVA_DC_FLUSH_IN); + /*generate a fake event since flush command is asynchronous*/ + sva_TM_SendTaskCommand(pDesc->subtasksListId,SVA_TM_TCMD_FAKE_EVENT,param); + } + } + break; + case SVA_SERVICE_FLUSH_OUT: + if (sva_DC_isTransitionValid(instanceNum,SVA_DC_FLUSH_OUT)==TRUE) + { + /*flush output buffer if necessary*/ + status = sva_DC_DoFlushOut(serviceId); + if (status == SVA_OK) + { + sva_DC_UpdateInstanceStateMachine(instanceNum,SVA_DC_FLUSH_OUT); + /*generate a fake event since flush command is asynchronous*/ + sva_TM_SendTaskCommand(pDesc->subtasksListId,SVA_TM_TCMD_FAKE_EVENT,param); + } + } + break; + /*unknown command*/ + default: + status = SVA_UNKNOWN_CMD_ID; + break; + } + + return status; +} + +/****************************************************************************/ +/* NAME: t_sva_error SVA_UpdateVideoDecoderParams( */ +/* t_sva_service_id serviceId, */ +/* t_sva_update_cmd_type updateCmdType, */ +/* t_sva_preprocessor_param_id paramId, */ +/* t_uint32 param */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine allows to update params for an instance of a Decode */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - serviceId: identifier of the given service */ +/* - updateCmdType: command to apply to the DECODE */ +/* - paramd: value of timeStamp */ +/* - param: parameter for the cmdType */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/* - SVA_OK : Command taken into account */ +/* - SVA_UNKNOWN_SERVICE_ID : service id is not correct */ +/* - SVA_UNEXPECTED_API_CALL : Command cannot be excecuted in */ +/* current context. */ +/* - SVA_INTERNAL_VIDEO_DECODER_ERROR : internal error */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + No dynamic parameter for decode identified at this time +*/ + +PUBLIC t_sva_error SVA_UpdateVideoDecoderParams( + t_sva_service_id serviceId, + t_sva_update_cmd_type updateCmdType, + t_sva_video_decoder_param_id paramId, + t_uint32 param + ) +{ + (void)(serviceId); + (void)(updateCmdType); + (void)(paramId); + (void)(param); + + return SVA_OK; +} + + +/****************************************************************************/ +/* NAME: t_sva_error sva_DC_Push ( */ +/* t_sva_service_id serviceId, */ +/* t_sva_buffer_id bufferId, */ +/* t_sva_push_mode pushMode, */ +/* t_sva_buffer_type bufferType */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine allows to push data in a Decode service */ +/* - it will check buffer has enought size according to conf */ +/* - it will push it in the corresponding pushFifo fifo */ +/* - update status of buffer */ +/* - try to resolve some dependencies */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - serviceId: identifier of the service */ +/* - bufferId: identifier of the buffer */ +/* - pushMode: PUSH_IN/PUSH_OUT */ +/* - bufferType: */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/* - SVA_OK : Command taken into account */ +/* - SVA_UNKNOWN_SERVICE_ID : service id is not correct */ +/* - SVA_UNEXPECTED_API_CALL : Command cannot be excecuted in */ +/* current context. */ +/* - SVA_INTERNAL_VIDEO_DECODER_ERROR : internal error */ +/* - SVA_INVALID_BUFFER_TYPE : buffer type is not handle by grab */ +/* - SVA_INTERNAL_FIFOS_FULL : internal fifos are full */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + DONE +*/ +PUBLIC t_sva_error sva_DC_Push( + t_sva_service_id serviceId, + t_sva_buffer_id bufferId, + t_sva_push_mode pushMode, + t_sva_buffer_type bufferType +) +{ + t_sva_service_instance_num instanceNum = READ_INSTANCE_NUM_IN_SERVICE_ID(serviceId); + t_sva_dc_descriptor *pDesc=&decodeDesc[instanceNum]; + t_sva_error status=SVA_OK; + t_sva_bm_error bmError; + t_sva_dc_error dcError; + + (void)(pushMode); + + /*check for service id validity*/ + status=sva_DC_CheckServiceId(serviceId); + if (status!=SVA_OK) {return status;} + + /*check that transition is allowed*/ + if (sva_DC_isTransitionValid(instanceNum,SVA_DC_PUSH)==FALSE) {return SVA_UNEXPECTED_API_CALL;} + + switch(bufferType) { + case SVA_BITSTREAM_BUFFER_TYPE: // bitstream buffer can be only pushed in + if (pushMode == SVA_PUSH_OUT) return SVA_UNEXPECTED_API_CALL; + break; + + case SVA_IMAGE_BUFFER_TYPE: + case SVA_INFOS_BUFFER_TYPE: + case SVA_PARAMS_BUFFER_TYPE: // image, infos and param buffers can be only pushed out + if (pushMode == SVA_PUSH_IN) return SVA_UNEXPECTED_API_CALL; + break; + + default: + return SVA_INVALID_BUFFER_TYPE; // buffer type not recognized + } + + /*handle provided buffer*/ + status=decodeAlgoDesc[pDesc->algo].pPush(instanceNum, bufferType, bufferId); + if(status!=SVA_OK) { return status;} + + /*update state machine*/ + sva_DC_UpdateInstanceStateMachine(instanceNum,SVA_DC_PUSH); + + /*update buffer status if we have succeeded to push it and try to solve dependencies*/ + if (status == SVA_OK) + { + t_uint32 systemTime; + t_sva_error svaError; + + svaError=SVA_GetServiceSystemTime(serviceId,&systemTime); + if (svaError!=SVA_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + bmError=sva_BM_UpdateBufferStatus(bufferId, SVA_BUFFER_IN_USE, systemTime); + if (bmError!=SVA_BM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + dcError=sva_DC_ResolveDependencies(instanceNum); + if (dcError!=SVA_DC_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + } + + return status; +} + +/****************************************************************************/ +/* NAME: t_sva_error sva_DC_GetVideoDecoderStatus ( */ +/* t_sva_service_id serviceId, */ +/* t_sva_decoder_status * pStatus */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine allows to get status of the Decode service */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - serviceId: identifier of the service */ +/* - pStatus: status for the decode service */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/* - SVA_OK : Command taken into account */ +/* - SVA_UNKNOWN_SERVICE_ID : service id is not correct */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + DONE +*/ +PUBLIC t_sva_error SVA_GetVideoDecoderStatus( + t_sva_service_id serviceId, + t_sva_video_decoder_status * pStatus +) +{ + t_sva_service_instance_num instanceNum = READ_INSTANCE_NUM_IN_SERVICE_ID(serviceId); + t_sva_dc_descriptor *pDesc=&decodeDesc[instanceNum]; + t_sva_error status; + + /*check for service id validity*/ + status=sva_DC_CheckServiceId(serviceId); + if (status!=SVA_OK) {return status;} + + /*check pointers*/ + DC_CHECK_NULL_POINTER(pStatus); + + //update bufferizationStats fields of decoder status + pDesc->status.bufferizationStats.inLevel=pDesc->inputBitstreamFifos.push.elemCount; + pDesc->status.bufferizationStats.outLevel=pDesc->outputImageFifos.push.elemCount; + + /*copy status*/ + *pStatus=pDesc->status; + + return SVA_OK; +} + +/****************************************************************************/ +/* NAME: t_sva_dc_error sva_DC_DispatchVirtualHwEvent( */ +/* t_sva_virtual_hw_event_id eventId, */ +/* t_sva_service_id serviceId, */ +/* t_sva_tm_subtask_id subtaskId, */ +/* t_uint32 eventTimestamp, */ +/* t_uint32 eventDate, */ +/* t_uint8 maxOfEvent, */ +/* t_sva_event_desc *pEventDesc, */ +/* t_uint32 *pNbEvent */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine allows to dispatch event of the Decode service */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - eventId: event identifier */ +/* - serviceId: identifier of the service */ +/* - subtaskId: identifier of the subtask for which is the event */ +/* - eventTimestamp: time at which the event occur (system time unit) */ +/* - eventDate: time at which the event occur (ticks time unit) */ +/* - maxOfEvent: nb of event max contained in EventDesc */ +/* - pEventDesc: structure of Events */ +/* - pNbEvent: nb of event into EventDesc */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_DC_error */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ + +PUBLIC t_sva_error sva_DC_DispatchVirtualHwEvent( + t_sva_tm_virtual_hw_event_id eventId, + t_sva_service_id serviceId, + t_sva_tm_subtask_id subtaskId, + t_uint32 eventTimestamp, + t_uint32 eventDate, + t_uint8 maxOfEvent, + t_sva_event_desc *pEventDesc, + t_uint32 *pNbEvent +) +{ + t_sva_service_instance_num instanceNum = READ_INSTANCE_NUM_IN_SERVICE_ID(serviceId); + t_sva_dc_descriptor *pDesc=&decodeDesc[instanceNum]; + t_size size; + t_sva_dc_subtask_dependencies subtaskDep; + t_sva_tm_error tmError; + t_sva_ff_error ffError; + t_sva_error status; + t_uint32 nbEventsRaised = 0; + t_logical_address paramOutAddr; + t_uint16 errorType; + t_sva_error algoError; + t_bool isUpdateStateNeed=FALSE; + t_sva_buffer_list_id bitstreamBufferListId; + + + /*check pointers*/ + DC_CHECK_NULL_POINTER(pNbEvent); + + *pNbEvent=0; + + /*check for service id validity*/ + status=sva_DC_CheckServiceId(serviceId); + if (status!=SVA_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + + /*check pointers*/ + DC_CHECK_NULL_POINTER(pEventDesc); + DC_CHECK_NULL_POINTER(pNbEvent); + +#ifdef __DEBUG + eventDecodeDebugTable[instanceNum].eventDebugDesc[eventDecodeDebugTable[instanceNum].nbOfEventReceived%LOG_DEPTH].event=eventId; + eventDecodeDebugTable[instanceNum].eventDebugDesc[eventDecodeDebugTable[instanceNum].nbOfEventReceived%LOG_DEPTH].systemTime=eventTimestamp; + eventDecodeDebugTable[instanceNum].eventDebugDesc[eventDecodeDebugTable[instanceNum].nbOfEventReceived%LOG_DEPTH].subtaskId=subtaskId; + eventDecodeDebugTable[instanceNum].nbOfEventReceived++; +#endif + + switch(eventId) + { + case SVA_TM_EOT_HW_EVENT: + + //incremente eot Counter + pDesc->internalEventStatus.eotCounter++; + + //Manage subtasksDependencyFifo.inUse fifo and get suitable bitstream buffer list + ffError=POP_FIFO_ELEM(pDesc->subtasksDependencyFifo.inUse,t_sva_dc_subtask_dependencies,subtaskDep); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + bitstreamBufferListId=subtaskDep.bitstreamBufferListId; + + //HandleEOT + algoError=decodeAlgoDesc[pDesc->algo].pDispatchEOT(instanceNum, + subtaskId, + pEventDesc, + serviceId, + eventTimestamp, + eventDate, + &nbEventsRaised, + maxOfEvent, + bitstreamBufferListId); + + + /*repush subtask with default dependencies so it can be programmed and then re-excecuted*/ + subtaskDep.dependencies = pDesc->defaultDep; + ffError=PUSH_FIFO_ELEM(pDesc->subtasksDependencyFifo.push,t_sva_dc_subtask_dependencies,subtaskDep); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + + //We are sure to leave the state "first subtask not executed" + pDesc->firstSubtaskExecuted=TRUE; + + break; + + case SVA_TM_EOK_HW_EVENT: + /* We can reveive an EOK for the three following reason : + * 1) no more subtask scheduled => OVERFLOW or UNDERFLOW event + * 2) a stop has been requested + * 3) an abort has been requested + * Note than reason 1 can arrive at the same time as 2 or 3 + + */ + + //eok Counter + pDesc->internalEventStatus.eokCounter++; + + if (pDesc->state==SVA_DC_STOP_REQUESTED) + { + //generate a stop event + CHECK_TABLE_OVERFLOW(nbEventsRaised, maxOfEvent, SVA_INTERNAL_VIDEO_DECODER_ERROR); + pEventDesc[nbEventsRaised].eventId = SVA_EVENT_SERVICE_STOPPED; + pEventDesc[nbEventsRaised].serviceId = serviceId; + pEventDesc[nbEventsRaised].bufferId = INVALID_BUFFER_ID; + pEventDesc[nbEventsRaised].eventTimestamp = (t_sva_timestamp_value) eventTimestamp; + pEventDesc[nbEventsRaised].eventDate = (t_sva_timestamp_value) eventDate; + pEventDesc[nbEventsRaised].extraInfo=0; + nbEventsRaised++; + /*update state*/ + isUpdateStateNeed=TRUE; + } + //check no subtask are scheduled: dependency mgt may have been called before and dependency resolved + if (GET_FIFO_NB_ELEMS(pDesc->subtasksDependencyFifo.push)==SUBTASK_DEFAULT_NUMBER) + { + //Discriminate Overflow or underflow event + if (decodeAlgoDesc[pDesc->algo].pCheckInputDep(instanceNum) != TRUE) + { + //generate an underflow + CHECK_TABLE_OVERFLOW(nbEventsRaised, maxOfEvent, SVA_INTERNAL_VIDEO_DECODER_ERROR); + pEventDesc[nbEventsRaised].eventId = SVA_EVENT_UNDERFLOW; + pEventDesc[nbEventsRaised].serviceId = serviceId; + pEventDesc[nbEventsRaised].bufferId = INVALID_BUFFER_ID; + pEventDesc[nbEventsRaised].eventTimestamp = (t_sva_timestamp_value) eventTimestamp; + pEventDesc[nbEventsRaised].eventDate = (t_sva_timestamp_value) eventDate; + pEventDesc[nbEventsRaised].extraInfo=0; + nbEventsRaised++; + //update status + pDesc->status.eventStats.underflowCounter++; + /*update state*/ + isUpdateStateNeed=TRUE; + } + + if (decodeAlgoDesc[pDesc->algo].pCheckOutputDep(instanceNum) != TRUE) + { + //generate an overflow + CHECK_TABLE_OVERFLOW(nbEventsRaised, maxOfEvent, SVA_INTERNAL_VIDEO_DECODER_ERROR); + pEventDesc[nbEventsRaised].eventId = SVA_EVENT_OVERFLOW; + pEventDesc[nbEventsRaised].serviceId = serviceId; + pEventDesc[nbEventsRaised].bufferId = INVALID_BUFFER_ID; + pEventDesc[nbEventsRaised].eventTimestamp = (t_sva_timestamp_value) eventTimestamp; + pEventDesc[nbEventsRaised].eventDate = (t_sva_timestamp_value) eventDate; + pEventDesc[nbEventsRaised].extraInfo=0; + nbEventsRaised++; + //update status + pDesc->status.eventStats.overflowCounter++; + /*update state*/ + isUpdateStateNeed=TRUE; + } + } + if (isUpdateStateNeed==TRUE) //some EOK are ignored if subtask programmed in the mean time + { + /*update state*/ + sva_DC_UpdateInstanceStateMachine(instanceNum,SVA_DC_EVENT_EOK); + } + + break; + + case SVA_TM_FAKE_HW_EVENT: + //incremente fake Counter + pDesc->internalEventStatus.fakeCounter++; + + // perform algo specific operations for a fake event + decodeAlgoDesc[pDesc->algo].pHandleFakeEvent( eventId, + serviceId, + subtaskId, + eventTimestamp, + eventDate, + maxOfEvent, + &nbEventsRaised, + pEventDesc); + + //Fake event is used for asynchronous flush + /*add flush event*/ + if (pDesc->state == SVA_DC_FLUSHING_IN) + { + /*Flush in event*/ + CHECK_TABLE_OVERFLOW(nbEventsRaised, maxOfEvent, SVA_INTERNAL_VIDEO_DECODER_ERROR); + pEventDesc[nbEventsRaised].eventId = SVA_EVENT_SERVICE_FLUSHED_IN; + pEventDesc[nbEventsRaised].serviceId = serviceId; + pEventDesc[nbEventsRaised].bufferId = INVALID_BUFFER_ID; + pEventDesc[nbEventsRaised].eventTimestamp = (t_sva_timestamp_value) eventTimestamp; + pEventDesc[nbEventsRaised].eventDate = (t_sva_timestamp_value) eventDate; + pEventDesc[nbEventsRaised].extraInfo=0; + nbEventsRaised++; + } + if (pDesc->state == SVA_DC_FLUSHING_OUT) + { + /*flush out event*/ + CHECK_TABLE_OVERFLOW(nbEventsRaised, maxOfEvent, SVA_INTERNAL_VIDEO_DECODER_ERROR); + pEventDesc[nbEventsRaised].eventId = SVA_EVENT_SERVICE_FLUSHED_OUT; + pEventDesc[nbEventsRaised].serviceId = serviceId; + pEventDesc[nbEventsRaised].bufferId = INVALID_BUFFER_ID; + pEventDesc[nbEventsRaised].eventTimestamp = (t_sva_timestamp_value) eventTimestamp; + pEventDesc[nbEventsRaised].eventDate = (t_sva_timestamp_value) eventDate; + pEventDesc[nbEventsRaised].extraInfo=0; + nbEventsRaised++; + + // avoid any BUFFER_FILLED event to get triggered on a fakeFwdImageBufferId + pDesc->firstSubtaskExecuted=FALSE; + } + + /*update state machine*/ + sva_DC_UpdateInstanceStateMachine(instanceNum,SVA_DC_EVENT_FAKE); + break; + + case SVA_TM_ACTIVE_HW_EVENT: + //incremente activate Counter + pDesc->internalEventStatus.activeCounter++; + + /*add activate event*/ + CHECK_TABLE_OVERFLOW(nbEventsRaised, maxOfEvent, SVA_INTERNAL_VIDEO_DECODER_ERROR); + pEventDesc[nbEventsRaised].eventId = SVA_EVENT_SERVICE_ACTIVATED; + pEventDesc[nbEventsRaised].serviceId = serviceId; + pEventDesc[nbEventsRaised].bufferId = INVALID_BUFFER_ID; + pEventDesc[nbEventsRaised].eventTimestamp = (t_sva_timestamp_value) eventTimestamp; + pEventDesc[nbEventsRaised].eventDate = (t_sva_timestamp_value) eventDate; + pEventDesc[nbEventsRaised].extraInfo=0; + nbEventsRaised++; + /*update state machine*/ + sva_DC_UpdateInstanceStateMachine(instanceNum,SVA_DC_EVENT_ACTIVE); + + break; + + case SVA_TM_INACTIVE_HW_EVENT: + //incremente inactivate Counter + pDesc->internalEventStatus.inactiveCounter++; + + /*add inactivate event*/ + CHECK_TABLE_OVERFLOW(nbEventsRaised, maxOfEvent, SVA_INTERNAL_VIDEO_DECODER_ERROR); + pEventDesc[nbEventsRaised].eventId = SVA_EVENT_SERVICE_INACTIVATED; + pEventDesc[nbEventsRaised].serviceId = serviceId; + pEventDesc[nbEventsRaised].bufferId = INVALID_BUFFER_ID; + pEventDesc[nbEventsRaised].eventTimestamp = (t_sva_timestamp_value) eventTimestamp; + pEventDesc[nbEventsRaised].eventDate = (t_sva_timestamp_value) eventDate; + pEventDesc[nbEventsRaised].extraInfo=0; + nbEventsRaised++; + /*update state machine*/ + sva_DC_UpdateInstanceStateMachine(instanceNum,SVA_DC_EVENT_INACTIVE); + + break; + + case SVA_TM_ERR_HW_EVENT: + //incremente error Counter + pDesc->internalEventStatus.errCounter++; + + /*read param out*/ + paramOutAddr=pDesc->paramOutAddr; //Address of blockId that is intended to contain paramOut + size=decodeAlgoDesc[pDesc->algo].pGetOutputParamsSize (instanceNum); + + /*transfer paramout to internal block*/ + tmError=sva_TM_GetSubTaskField(subtaskId, SVA_TM_DEC_ADDR_OUT_PARAMETERS,paramOutAddr, + 0, size, FALSE); + HCL_DEBUG_ASSERT(tmError==SVA_TM_OK); + //provide to algo module for computing statistical data + record + algoError=decodeAlgoDesc[pDesc->algo].pSetFrameParamOut(instanceNum, (void *)paramOutAddr); + HCL_DEBUG_ASSERT(algoError == SVA_OK); + //Retrieve corresponding errorType value + algoError=decodeAlgoDesc[pDesc->algo].pGetLastErrorType(instanceNum, &errorType); + HCL_DEBUG_ASSERT(algoError == SVA_OK); + + + /*add error event*/ + CHECK_TABLE_OVERFLOW(nbEventsRaised, maxOfEvent, SVA_INTERNAL_VIDEO_DECODER_ERROR); + pEventDesc[nbEventsRaised].eventId = SVA_EVENT_SERVICE_ERROR; + pEventDesc[nbEventsRaised].serviceId = serviceId; + pEventDesc[nbEventsRaised].bufferId = INVALID_BUFFER_ID; + pEventDesc[nbEventsRaised].eventTimestamp = (t_sva_timestamp_value) eventTimestamp; + pEventDesc[nbEventsRaised].eventDate = (t_sva_timestamp_value) eventDate; + if (pDesc->state==SVA_DC_ABORT_REQUESTED) + { + pEventDesc[nbEventsRaised].extraInfo=0; + pEventDesc[nbEventsRaised].extraInfo2=0; + } + else + { + pEventDesc[nbEventsRaised].extraInfo=(t_uint32)errorType; + } + nbEventsRaised++; + /*update status*/ + pDesc->status.eventStats.errorCounter++; + /*update state machine*/ + sva_DC_UpdateInstanceStateMachine(instanceNum,SVA_DC_EVENT_ERROR); + + break; + + case SVA_TM_EOW_HW_EVENT: + //incremente eot Counter + pDesc->internalEventStatus.eowCounter++; + + /*add error event*/ + CHECK_TABLE_OVERFLOW(nbEventsRaised, maxOfEvent, SVA_INTERNAL_VIDEO_DECODER_ERROR); + pEventDesc[nbEventsRaised].eventId = SVA_EVENT_SERVICE_ERROR; + pEventDesc[nbEventsRaised].serviceId = serviceId; + pEventDesc[nbEventsRaised].bufferId = INVALID_BUFFER_ID; + pEventDesc[nbEventsRaised].eventTimestamp = (t_sva_timestamp_value) eventTimestamp; + pEventDesc[nbEventsRaised].eventDate = (t_sva_timestamp_value) eventDate; + pEventDesc[nbEventsRaised].extraInfo=0; + nbEventsRaised++; + + break; + + case SVA_TM_BOW_HW_EVENT: + //incremente eot Counter + pDesc->internalEventStatus.bowCounter++; + + /*add error event*/ + CHECK_TABLE_OVERFLOW(nbEventsRaised, maxOfEvent, SVA_INTERNAL_VIDEO_DECODER_ERROR); + pEventDesc[nbEventsRaised].eventId = SVA_EVENT_SERVICE_ERROR; + pEventDesc[nbEventsRaised].serviceId = serviceId; + pEventDesc[nbEventsRaised].bufferId = INVALID_BUFFER_ID; + pEventDesc[nbEventsRaised].eventTimestamp = (t_sva_timestamp_value) eventTimestamp; + pEventDesc[nbEventsRaised].eventDate = (t_sva_timestamp_value) eventDate; + pEventDesc[nbEventsRaised].extraInfo=0; + nbEventsRaised++; + + break; + + case SVA_TM_UBU_HW_EVENT: + //incremente eot Counter + pDesc->internalEventStatus.ubuCounter++; + + /*add error event*/ + CHECK_TABLE_OVERFLOW(nbEventsRaised, maxOfEvent, SVA_INTERNAL_VIDEO_DECODER_ERROR); + pEventDesc[nbEventsRaised].eventId = SVA_EVENT_SERVICE_ERROR; + pEventDesc[nbEventsRaised].serviceId = serviceId; + pEventDesc[nbEventsRaised].bufferId = INVALID_BUFFER_ID; + pEventDesc[nbEventsRaised].eventTimestamp = (t_sva_timestamp_value) eventTimestamp; + pEventDesc[nbEventsRaised].eventDate = (t_sva_timestamp_value) eventDate; + pEventDesc[nbEventsRaised].extraInfo=0; + nbEventsRaised++; + + break; + default: + break; + } + + /*try to solve some dependencies*/ + sva_DC_ResolveDependencies(instanceNum); + + /*return number of generated events*/ + *pNbEvent=nbEventsRaised; + + return SVA_OK; +} + +/****************************************************************************/ +/* NAME: t_sva_error sva_DC_Delete ( */ +/* t_sva_service_id serviceId */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine deletes a Decode service */ +/* a SVA_SERVICE_FLUSH_IN and a SVA_SERVICE_FLUSH_OUT command should */ +/* be done previously */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - serviceId: identifier of the service */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/* - SVA_OK : Command taken into account */ +/* - SVA_UNKNOWN_SERVICE_ID : service id is not correct */ +/* - SVA_UNEXPECTED_API_CALL : Command cannot be excecuted in */ +/* current context. */ +/* - SVA_INTERNAL_VIDEO_DECODER_ERROR : internal error */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + DONE +*/ +PUBLIC t_sva_error sva_DC_Delete(t_sva_service_id serviceId) +{ + t_sva_service_instance_num instanceNum = READ_INSTANCE_NUM_IN_SERVICE_ID(serviceId); + t_sva_dc_descriptor *pDesc=&decodeDesc[instanceNum]; + t_sva_video_decoder_configuration *pConf=&pDesc->confHandle.currentConf; + t_uint32 i; + t_sva_tm_error tmError; + t_sva_error svaError; + t_sva_error algoError; + t_sva_blm_error blmError; + t_sva_ff_error ffError; + t_sva_buffer_id fakeImageBuffer = INVALID_BUFFER_ID; + t_sva_error status; + t_sva_mm_error mmError; + + /*check for service id validity*/ + status=sva_DC_CheckServiceId(serviceId); + if (status!=SVA_OK) {return status;} + + /*check that transition is allowed*/ + if (sva_DC_isTransitionValid(instanceNum,SVA_DC_CONTROL_DELETE)==FALSE) {return SVA_UNEXPECTED_API_CALL;} + + /*check that flush has been done in all fifos*/ + //image fifos + if (IS_FIFO_EMPTY(pDesc->outputImageFifos.push)==FALSE) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + if (IS_FIFO_EMPTY(pDesc->outputImageFifos.inUse)==FALSE) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + //Read only fifos + if (IS_FIFO_EMPTY(pDesc->h264DecReadOnlyFifo)==FALSE) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + //bitstream fifos + if (IS_FIFO_EMPTY(pDesc->inputBitstreamFifos.push)==FALSE) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + if (IS_FIFO_EMPTY(pDesc->inputBitstreamFifos.inUse)==FALSE) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + //lastPushedBuffer Fifos + if (IS_FIFO_EMPTY(pDesc->lastPushedBufferFifo.push)==FALSE) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + if (IS_FIFO_EMPTY(pDesc->lastPushedBufferFifo.inUse)==FALSE) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + //deblocking fifos if any + if(pConf->outTheLoopFilter != SVA_NONE_FILTER) + { + if (IS_FIFO_EMPTY(pDesc->outputDeblockingFifos.push)==FALSE) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + if (IS_FIFO_EMPTY(pDesc->outputDeblockingFifos.inUse)==FALSE) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + } + //infos fifos if any + if(pConf->areInfosRequested == TRUE) + { + if (IS_FIFO_EMPTY(pDesc->outputInfosFifos.push)==FALSE) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + if (IS_FIFO_EMPTY(pDesc->outputInfosFifos.inUse)==FALSE) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + } + + /*start to delete. Things to do depend of current state*/ + if (pDesc->state==SVA_DC_WAIT_FOR_ACTIVATE || pDesc->state==SVA_DC_WAIT_FOR_START) + { + /*delete fifos*/ + //image fifos + //while (IS_FIFO_EMPTY(pDesc->inputFwdImageFifos.push) == FALSE) POP_FIFO_ELEM(pDesc->inputFwdImageFifos.push,t_sva_buffer_id,fakeImageBuffer); + // while (IS_FIFO_EMPTY(pDesc->inputFwdImageFifos.inUse) == FALSE) POP_FIFO_ELEM(pDesc->inputFwdImageFifos.inUse,t_sva_buffer_id,fakeImageBuffer); + // DELETE_FIFO(pDesc->inputFwdImageFifos.push); + // DELETE_FIFO(pDesc->inputFwdImageFifos.inUse); + DELETE_FIFO(pDesc->outputImageFifos.push); + DELETE_FIFO(pDesc->outputImageFifos.inUse); + DELETE_FIFO(pDesc->h264DecReadOnlyFifo); + //bitstream fifos + DELETE_FIFO(pDesc->inputBitstreamFifos.push); + DELETE_FIFO(pDesc->inputBitstreamFifos.inUse); + if (pConf->mode != SVA_CODEC_IMAGE_MODE) { + //lastPushedBuffer Fifos + DELETE_FIFO(pDesc->lastPushedBufferFifo.push); + DELETE_FIFO(pDesc->lastPushedBufferFifo.inUse); + } + //deblocking fifos if any + if(pConf->outTheLoopFilter != SVA_NONE_FILTER) + { + DELETE_FIFO(pDesc->outputDeblockingFifos.push); + DELETE_FIFO(pDesc->outputDeblockingFifos.inUse); + } + //infos fifo if any + if(pConf->areInfosRequested == TRUE) + { + DELETE_FIFO(pDesc->outputInfosFifos.push); + DELETE_FIFO(pDesc->outputInfosFifos.inUse); + } + /*delete subtask dependancy fifo push and inUse: fifo push is supposed to be full at this step*/ + DELETE_FIFO(pDesc->subtasksDependencyFifo.push); + DELETE_FIFO(pDesc->subtasksDependencyFifo.inUse); + + /*algo specific fifos*/ + algoError=decodeAlgoDesc[decodeDesc[instanceNum].algo].pDecodeAlgoClose(instanceNum); + HCL_DEBUG_ASSERT(algoError == SVA_OK); + + /*delete subtasklist*/ + tmError=sva_TM_DeleteSubTaskList(pDesc->subtasksListId); + if (tmError!=SVA_TM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + + /* delete fake buffer and fifo */ + algoError=decodeAlgoDesc[decodeDesc[instanceNum].algo].pDeleteFake(instanceNum); + HCL_DEBUG_ASSERT(algoError == SVA_OK); + + + /*delete bitstream buffer list*/ + for(i=0;ibufferListIdArray[i][0]); + if (blmError!=SVA_BLM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + } + + + //Fake Fwd ref image Buffer + if(fakeImageBuffer != INVALID_BUFFER_ID) + { + svaError=SVA_FreeBuffer(fakeImageBuffer); + if (svaError!= SVA_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + } + + + //Temporary ParamOut buffer + { + t_sva_block_id NewParamOutBlockId=INVALID_SDRAM_BLOCK_ID; + + if (!IS_FIFO_EMPTY(pDesc->blockIdFifo)) + { + ffError=POP_FIFO_ELEM(pDesc->blockIdFifo,t_sva_block_id,NewParamOutBlockId); + if (ffError!= SVA_FIFO_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + mmError=sva_MM_FreeBlock(NewParamOutBlockId); + if (mmError!= SVA_MM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + } + + //delete Temporary ParamOut fifo + DELETE_FIFO(pDesc->blockIdFifo); + } + + /*delete subtasks*/ + for(i=0;isubtasksIdArray[i]); + if (tmError!=SVA_TM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + } + } + + /*delete descriptor use by memory management*/ + status=sva_EM_Delete(serviceId); + if (status!=SVA_OK) {return status;} + + /*reset instance descriptor*/ + sva_DC_ResetInstance(serviceId); + + /* Update the state machine */ + sva_DC_UpdateInstanceStateMachine(instanceNum,SVA_DC_CONTROL_DELETE); + + return SVA_OK; +} + + +/****************************************************************************/ +/* NAME: sva_DC_SetHeaderInfos() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: This routine enables to give Header infos (dynamic params) */ +/* related to a given bitstream buffer and also */ +/* the address of the first byte of coded data taken into account by SVA */ +/* (relative to buffer start) */ +/* MPEG4 SH: first byte of first gob layer (after short video start marker) */ +/* MPEG4 SP: first byte of first motion texture in VOP */ +/* */ +/* PARAMETERS: */ +/* IN : t_sva_service_id serviceId : */ +/* t_sva_buffer_id bitstreamBufferId: */ +/* t_uint32 byteOffset (in bytes ) */ +/* t_uint32 bitOffset (in bits) */ +/* const t_sva_header_infos *pHeaderInfos */ +/* OUT :none */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/* - SVA_OK : header provided successfully */ +/* - SVA_NOT_BITSTREAM_BUFFER : buffer id provided does not correpond*/ +/* to a bitstream buffer */ +/* - SVA_FIFO_FULL: header is rejected has internal fifo is full */ +/*--------------------------------------------------------------------------*/ +/* USE: NA */ +/* USED BY: NA */ +/****************************************************************************/ +PUBLIC t_sva_error sva_DC_SetHeaderInfos +( + t_sva_service_id serviceId, + t_sva_buffer_id bitstreamBuffer, + t_uint32 byteOffset, + t_uint32 bitOffset, + const t_sva_header_infos *pHeaderInfos + ) +{ + t_sva_service_instance_num instanceNum = READ_INSTANCE_NUM_IN_SERVICE_ID(serviceId); + t_sva_dc_descriptor *pDesc=&decodeDesc[instanceNum]; + t_sva_error status; + t_sva_dc_error dcError; + t_sva_bm_error bmError; + t_sva_buffer_type bufferType; + t_sva_error algoError =SVA_OK; + + /*check for service id validity*/ + status=sva_DC_CheckServiceId(serviceId); + if (status!=SVA_OK) {return status;} + + /*check pointers*/ + DC_CHECK_NULL_POINTER(pHeaderInfos); + + /*check that transition is allowed*/ + if (sva_DC_isTransitionValid(instanceNum,SVA_DC_PUSH)==FALSE) {return SVA_UNEXPECTED_API_CALL;} + + bmError = sva_BM_GetBufferType(bitstreamBuffer, &bufferType); + HCL_DEBUG_ASSERT(bmError == SVA_BM_OK); + if (bufferType != SVA_BITSTREAM_BUFFER_TYPE) return SVA_INVALID_BUFFER_TYPE; + + + algoError = decodeAlgoDesc[pDesc->algo].pGSetHeaderInfos(instanceNum, serviceId, bitstreamBuffer, byteOffset, bitOffset, pHeaderInfos); + if (algoError!=SVA_OK) {return algoError;} + + sva_DC_UpdateInstanceStateMachine(instanceNum,SVA_DC_PUSH); + + dcError=sva_DC_ResolveDependencies(instanceNum); + if (dcError!=SVA_DC_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + + return SVA_OK; +} + +/****************************************************************************/ +/* NAME: sva_DC_AssertEndOfBitstream() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: Assert the immediate end of bitstream. Leads to a */ +/* non-delayed setHeaderInfos execution */ +/* */ +/* PARAMETERS: */ +/* IN : t_sva_service_id serviceId */ +/* OUT :none */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/* - SVA_OK : Last subtask sucessfully lined up. */ +/* - SVA_INTERNAL_VIDEO_DECODER_ERROR : Error */ +/*--------------------------------------------------------------------------*/ +/* USE: NA */ +/* USED BY: NA */ +/****************************************************************************/ +PUBLIC t_sva_error sva_DC_AssertEndOfBitstream(t_sva_service_id serviceId) { + + + t_sva_service_instance_num instanceNum = READ_INSTANCE_NUM_IN_SERVICE_ID(serviceId); + t_sva_dc_descriptor *pDesc=&decodeDesc[instanceNum]; + //t_sva_video_decoder_configuration *pConf=&pDesc->confHandle.currentConf; + t_sva_error status; + //t_sva_SetHeaderInfosParam *pSetHeaderInfosParams = &setHeaderInfosParam[instanceNum]; + t_sva_error algoError; + t_sva_dc_error dcError; + + + /*check for service id validity*/ + status=sva_DC_CheckServiceId(serviceId); + if (status!=SVA_OK) {return status;} + + algoError=decodeAlgoDesc[pDesc->algo].pAssertEndOfBitstream(instanceNum, serviceId); + if(algoError!=SVA_OK) {return algoError;} + + dcError=sva_DC_ResolveDependencies(instanceNum); + if (dcError!=SVA_DC_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + + return SVA_OK; +} + + + +/****************************************************************************/ +/* NAME: t_sva_error sva_DC_GetParamsBufferSize ( */ +/* t_sva_service_id serviceId, */ +/* t_sva_push_mode mode, */ +/* t_size *pSize */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* returns the size of the deblocking parameters if relevant; else 0 */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - serviceId: identifier of the service */ +/* - mode: allow to differentiate in and out buffers */ +/* */ +/* OUT : */ +/* - pSize: needed size in bytes for buffers in in or out */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/* - SVA_OK : Command taken into account */ +/* - SVA_UNKNOWN_SERVICE_ID : service id is not correct */ +/* - SVA_UNEXPECTED_API_CALL : Command cannot be excecuted in */ +/* current context. */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_sva_error sva_DC_GetParamsBufferSize( + t_sva_service_id serviceId, + t_sva_push_mode mode, + t_size *pSize +) +{ + t_sva_service_instance_num instanceNum = READ_INSTANCE_NUM_IN_SERVICE_ID(serviceId); + t_sva_dc_descriptor *pDesc=&decodeDesc[instanceNum]; + t_sva_video_decoder_configuration *pConf = &pDesc->confHandle.currentConf; + t_sva_error status; + t_sva_sv_algo algo = pDesc->algo; + t_uint32 size=0, height=0, width=0; + t_sva_push_mode pushMode; + t_sva_filter_mode filterMode; + + + HCL_ASSERT(pSize!=NULL); + + /*check for service id validity*/ + status=sva_DC_CheckServiceId(serviceId); + if (status!=SVA_OK) {return status;} + + /*check that transition is allowed*/ + if (sva_DC_isTransitionValid(instanceNum,SVA_DC_GET_PARAM_SIZE)==FALSE) {return SVA_UNEXPECTED_API_CALL;} + + height =pConf->imageDesc.height; + width =pConf->imageDesc.width; + pushMode=mode; + filterMode = pConf->outTheLoopFilter; + + /*get size to return in bytes*/ + decodeAlgoDesc[algo].pGetParamsBufferSize(instanceNum, pushMode, filterMode, height, width, &size); + *pSize= size; + + /* Update the state machine */ + sva_DC_UpdateInstanceStateMachine(instanceNum,SVA_DC_GET_PARAM_SIZE); + + return SVA_OK; +} + + + + +/****************************************************************************/ +/* Private functions */ +/****************************************************************************/ + + +/****************************************************************************/ +/* NAME: t_sva_DC_error sva_DC_ResolveDependencies( */ +/* t_sva_service_instance_num instanceNum */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* */ +/* This routine is called in sva_DC_Push, SVA_SetHeaderInfos() */ +/* and after specific event like EOT */ +/* */ +/* PARAMETERS: */ +/* IN : none */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: t_sva_dc_error */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PRIVATE t_sva_dc_error sva_DC_ResolveDependencies +( + t_sva_service_instance_num instanceNum +) +{ + + t_sva_dc_descriptor *pDesc=&decodeDesc[instanceNum]; + t_sva_error svaError=SVA_OK; + + /*check that transition is valid*/ + if (sva_DC_isTransitionValid(instanceNum,SVA_DC_ALL_DEPENDENCIES_RESOLVED)==FALSE) {return SVA_DC_INVALID_TRANSITION;} + + svaError = decodeAlgoDesc[pDesc->algo].pResolveDependencies(instanceNum); + if(svaError!=SVA_OK){ return SVA_DC_TM_LINKED_ERROR;} + + return SVA_DC_OK; +} + + + + +/****************************************************************************/ +/* NAME: t_bool sva_DC_IsConfigurationValid( */ +/* const t_sva_preprocessor_configuration *pConf */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will check that given configuration given to grab is */ +/* valid. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - pConf: a pointer to the configuration to check */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: t_bool */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + TO DO : + - check if some others value can be check +*/ +PRIVATE t_bool sva_DC_IsConfigurationValid +( + const t_sva_video_decoder_configuration *pConf +) +{ + HCL_DEBUG_ASSERT(pConf != NULL); + + /* Check param enum value range*/ + CHECK_RANGE0(pConf->inTheLoopFilter, SVA_NONE_FILTER,SVA_DEBLOCKING_DERINGING_FILTER); + CHECK_RANGE0(pConf->outTheLoopFilter, SVA_NONE_FILTER,SVA_DEBLOCKING_DERINGING_FILTER); + CHECK_RANGE0(pConf->ercMode,SVA_BASIC_ERC, SVA_FULL_ERC); + CHECK_RANGE0(pConf->mode,SVA_CODEC_IMAGE_MODE, SVA_CODEC_STREAM_MODE); + + /* check image desc alignment*/ + /* Check on the resolution of the frame (i.e. width and height neef not be multiple of 16)is not required to be a multiple of 16, take care for pp !!! Refer +to VI 10809 */ +// CHECK_ALIGNMENT(pConf->imageDesc.height,16); +// CHECK_ALIGNMENT(pConf->imageDesc.width,16); + +// if (pConf->transformId != SVA_DECODER_MPEG4_SP_L4A) {return FALSE;} + + return TRUE; +} + + + + +/****************************************************************************/ +/* NAME: t_sva_error sva_DC_CheckServiceId(t_sva_service_id serviceId) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will check that task_id and instance number of servideId*/ +/* are both valid */ +/* */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - serviceId: service id to check */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: t_sva_DC_error */ +/* - SVA_UNKNOWN_SERVICE_ID : Invalid service id. Either due to an */ +/* invalid task id or invalid instance number. */ +/* - SVA_OK : Service id is valid */ +/* */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + DONE +*/ +PUBLIC t_sva_error sva_DC_CheckServiceId(t_sva_service_id serviceId) +{ + t_sva_service_instance_num instanceNum = READ_INSTANCE_NUM_IN_SERVICE_ID(serviceId); + t_sva_sv_task_id taskId = READ_TASK_ID_IN_SERVICE_ID(serviceId); + + if (taskId!=SVA_SV_DECODE_TID) {return SVA_UNKNOWN_SERVICE_ID;} + if (instanceNum>=NUM_MAX_DECODE) {return SVA_UNKNOWN_SERVICE_ID;} + + return SVA_OK; +} + + +/****************************************************************************/ +/* NAME: t_sva_error sva_DC_DoReset( */ +/* t_sva_service_id serviceId */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will reset a service so it can restart after an error. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - serviceId: service identifier */ +/* */ +/* OUT: none */ +/* */ +/* RETURN: t_sva_error */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + DONE +*/ +PRIVATE t_sva_error sva_DC_DoReset +( + t_sva_service_id serviceId +) +{ + t_sva_service_instance_num instanceNum = READ_INSTANCE_NUM_IN_SERVICE_ID(serviceId); + t_sva_dc_descriptor *pDesc=&decodeDesc[instanceNum]; + + /* update error counter*/ + pDesc->status.eventStats.errorCounter++; + + return SVA_OK; +} + +/****************************************************************************/ +/* NAME: t_sva_error sva_DC_DoFlushIn( */ +/* t_sva_service_id serviceId */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will flush all fifos. */ +/* PARAMETERS: */ +/* IN : */ +/* - serviceId: service identifier */ +/* */ +/* OUT: none */ +/* */ +/* RETURN: t_sva_error */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + DONE +*/ +PRIVATE t_sva_error sva_DC_DoFlushIn +( + t_sva_service_id serviceId +) +{ + t_sva_service_instance_num instanceNum = READ_INSTANCE_NUM_IN_SERVICE_ID(serviceId); + t_sva_error algoError; + t_sva_dc_descriptor *pDesc=&decodeDesc[instanceNum]; + + + /*flush algo specific fifo*/ + //-------------------------- + algoError=decodeAlgoDesc[pDesc->algo].pFlushFifos(instanceNum); + HCL_DEBUG_ASSERT(algoError == SVA_OK); + + + //Flush bitstream buffer list: + //---------------------------- + algoError=decodeAlgoDesc[pDesc->algo].pFlushBitstreams(instanceNum); + HCL_DEBUG_ASSERT(algoError == SVA_OK); + + + return SVA_OK; +} + + +/****************************************************************************/ +/* NAME: t_sva_error sva_DC_DoFlushOut( */ +/* t_sva_service_id serviceId */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will flush all fifos. */ +/* PARAMETERS: */ +/* IN : */ +/* - serviceId: service identifier */ +/* */ +/* OUT: none */ +/* */ +/* RETURN: t_sva_error */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + DONE +*/ +PRIVATE t_sva_error sva_DC_DoFlushOut +( + t_sva_service_id serviceId +) +{ + t_sva_service_instance_num instanceNum = READ_INSTANCE_NUM_IN_SERVICE_ID(serviceId); + t_sva_error algoError; + t_sva_dc_descriptor *pDesc=&decodeDesc[instanceNum]; + + + /*flush algo specific fifo*/ + //-------------------------- + algoError=decodeAlgoDesc[pDesc->algo].pFlushFifos(instanceNum); + HCL_DEBUG_ASSERT(algoError == SVA_OK); + + + //Flush bitstream buffer list: + //---------------------------- + algoError=decodeAlgoDesc[pDesc->algo].pFlushBitstreams(instanceNum); + HCL_DEBUG_ASSERT(algoError == SVA_OK); + + return SVA_OK; +} + + +/****************************************************************************/ +/* NAME: void sva_DC_ResetStatus( */ +/* t_sva_preprocessor_status *pStatus */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will reset status descriptor. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - pStatus: status descriptor to reset */ +/* */ +/* OUT: none */ +/* */ +/* RETURN: t_sva_DC_error */ +/* - SVA_DC_OK */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + DONE +*/ +PRIVATE void sva_DC_ResetStatus +( + t_sva_video_decoder_status *pStatus +) +{ + /*check pointers*/ + DC_CHECK_NULL_POINTER(pStatus); + + pStatus->state=SVA_SERVICE_NOT_INITIALIZED; + pStatus->errorId=SVA_DECODER_NO_ERROR; + pStatus->nbBytesDecoded=0; + pStatus->nbImagesDecoded=0; + pStatus->nbCompressedDataBufferized=0; + //user events + pStatus->eventStats.voidedCounter=0; + pStatus->eventStats.filledCounter=0; + pStatus->eventStats.partlyCounter=0; + pStatus->eventStats.readOnlyCounter=0; + pStatus->eventStats.underflowCounter=0; + pStatus->eventStats.overflowCounter=0; + pStatus->eventStats.errorCounter=0; + pStatus->bufferizationStats.inLevel=0; + pStatus->bufferizationStats.outLevel=0; + +} + +/****************************************************************************/ +/* NAME: t_sva_error sva_DC_ResetInstance ( void ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine initialize one service instance of Decode */ +/* 1) Set state of instance to SVA_SERVICE_NOT_INITIALIZED */ +/* 2) init fifos */ +/* */ +/* PARAMETERS: */ +/* IN : none */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/* - always SVA_OK */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + TO DO : + - add debug data init +*/ +PRIVATE void sva_DC_ResetInstance(t_sva_service_id serviceId) +{ + t_sva_service_instance_num i = READ_INSTANCE_NUM_IN_SERVICE_ID(serviceId); + + /*init instance states*/ + decodeDesc[i].state=SVA_DC_NOT_INITIALIZED; + decodeDesc[i].serviceId=0; + decodeDesc[i].activateState=SVA_DC_INACTIVE; + /*init fifo use*/ + INIT_FIFO(decodeDesc[i].inputBitstreamFifos.push); + INIT_FIFO(decodeDesc[i].inputBitstreamFifos.inUse); + //INIT_FIFO(decodeDesc[i].fakeBitstreamFifo); + INIT_FIFO(decodeDesc[i].lastPushedBufferFifo.push); + INIT_FIFO(decodeDesc[i].lastPushedBufferFifo.inUse); + // INIT_FIFO(decodeDesc[i].inputFwdImageFifos.push); + // INIT_FIFO(decodeDesc[i].inputFwdImageFifos.inUse); + INIT_FIFO(decodeDesc[i].outputImageFifos.push); + INIT_FIFO(decodeDesc[i].outputImageFifos.inUse); + INIT_FIFO(decodeDesc[i].h264DecReadOnlyFifo); + INIT_FIFO(decodeDesc[i].outputDeblockingFifos.push); + INIT_FIFO(decodeDesc[i].outputDeblockingFifos.inUse); + INIT_FIFO(decodeDesc[i].outputInfosFifos.push); + INIT_FIFO(decodeDesc[i].outputInfosFifos.inUse); + INIT_FIFO(decodeDesc[i].subtasksDependencyFifo.push); + INIT_FIFO(decodeDesc[i].subtasksDependencyFifo.inUse); + decodeDesc[i].firstSubtaskExecuted=FALSE; + /*init others value linked to decoder status*/ + sva_DC_ResetStatus(&(decodeDesc[i].status)); + //internal events + decodeDesc[i].internalEventStatus.eotCounter=0; + decodeDesc[i].internalEventStatus.eokCounter=0; + decodeDesc[i].internalEventStatus.fakeCounter=0; + decodeDesc[i].internalEventStatus.activeCounter=0; + decodeDesc[i].internalEventStatus.inactiveCounter=0; + decodeDesc[i].internalEventStatus.errCounter=0; + decodeDesc[i].internalEventStatus.eowCounter=0; + decodeDesc[i].internalEventStatus.bowCounter=0; + decodeDesc[i].internalEventStatus.ubuCounter=0; + + decodeAlgoDesc[decodeDesc[i].algo].pInitHeaderInfos(i); + + + +#ifdef __DEBUG + /*init debug counters*/ + eventDecodeDebugTable[i].nbOfEventReceived=0; + commandDecodeDebugTable[i].nbOfCommandReceived=0; + transitionDecodeDebugTable[i].nbOfTransitionReceived=0; +#endif + +} + +// end of decode.c + + + --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/sva_decode.h @@ -0,0 +1,97 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ + +#ifndef __INC_SVA_DECODE_H +#define __INC_SVA_DECODE_H + +#include "sva.h" +#include "svap.h" +#include "sva_taskmgt.h" + +/******************************************************************************/ +/* Constants definitions */ +/******************************************************************************/ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +// max number of setHeaderInfos consecutive calls +#define DECODE_MAX_FIFO_SIZE 16 + +/* + * Define the symbols used to identify the various errors of the Decode Module + */ +typedef enum { + SVA_DC_INVALID_TRANSITION = SVA_DC_LAST_ERROR, + SVA_DC_NO_MORE_AVAILABLE_INSTANCE, + SVA_DC_INVALID_INSTANCE_NB, + SVA_DC_INVALID_TASK_ID_NB, + SVA_DC_NOT_SUPPORTED, + SVA_DC_INVALID_CONTROL_PARAM, + SVA_DC_INVALID_PUSH, + SVA_DC_INVALID_BUFFER_TYPE, + SVA_DC_INVALID_BUFFER_SIZE, + SVA_DC_INVALID_CONFIGURATION, + SVA_DC_UNKNOWN_CMD_ID, + SVA_DC_UNEXPECTED_HW_EVENT, + SVA_DC_TI_LINKED_ERROR, + SVA_DC_BLM_LINKED_ERROR, + SVA_DC_BM_LINKED_ERROR, + SVA_DC_MM_LINKED_ERROR, + SVA_DC_FF_LINKED_ERROR, + SVA_DC_TM_LINKED_ERROR, + SVA_DC_NULL_POINTER_PARAMETER, + SVA_DC_FIFO_NOT_EMPTY, + SVA_DC_OK = HCL_OK +} t_sva_dc_error; + + + +/******************************************************************************* +* PUBLIC Functions +*******************************************************************************/ + +PUBLIC t_sva_error sva_DC_Init( void ); +PUBLIC t_sva_error sva_DC_Reset( t_sva_service_id ); +PUBLIC t_sva_error sva_DC_Create( t_sva_service_id *); +PUBLIC t_sva_error sva_DC_Control(t_sva_service_id, t_sva_service_cmd_id, t_uint32 ); +PUBLIC t_sva_error sva_DC_Push(t_sva_service_id, t_sva_buffer_id, t_sva_push_mode, t_sva_buffer_type ); +PUBLIC t_sva_error sva_DC_DispatchVirtualHwEvent(t_sva_tm_virtual_hw_event_id, t_sva_service_id, t_sva_tm_subtask_id, t_uint32, t_uint32, t_uint8, t_sva_event_desc *, t_uint32 *); +PUBLIC t_sva_error sva_DC_ProvideInternalNeeds( t_sva_service_id); +PUBLIC t_sva_error sva_DC_GetInternalNeeds(t_sva_service_id, t_size *); +PUBLIC t_sva_error sva_DC_Activate(t_sva_service_id, t_sva_service_mode, t_sva_fw_id *); +PUBLIC t_sva_error sva_DC_Inactivate(t_sva_service_id); +PUBLIC t_sva_error sva_DC_Delete(t_sva_service_id ); +PUBLIC t_sva_error sva_DC_SetHeaderInfos( t_sva_service_id, t_sva_buffer_id, t_uint32, t_uint32, const t_sva_header_infos *); +PUBLIC t_sva_error sva_DC_AssertEndOfBitstream(t_sva_service_id); +PUBLIC t_sva_error sva_DC_GetParamsBufferSize(t_sva_service_id ,t_sva_push_mode ,t_size *); +PUBLIC t_sva_error sva_DC_CheckServiceId(t_sva_service_id ); +//t_sva_decoder_configuration is in sva.h +// function is sva.h +//PUBLIC t_sva_error sva_DC_ConfigureVideoDecoder( t_sva_service_id, t_sva_decoder_configuration); +//PUBLIC t_sva_error sva_DC_GetVideoDecoderStatus(t_sva_service_id, t_sva_decoder_status *); +//PUBLIC t_sva_error sva_DC_UpdateVideoDecoderParams(t_sva_service_id, t_sva_update_cmd_type, t_sva_decoder_param_id, t_uint32 ); + +#ifdef __cplusplus +} /* allow C++ to use these headers */ +#endif /* __cplusplus */ + +#endif /* __INC_SVA_DECODE_H */ +/* End of file - sva_decode.h */ --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/sva_decodep.c @@ -0,0 +1,655 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ +/*------------------------------------------------------------------------ + * Includes + *----------------------------------------------------------------------*/ +#include "hcl_defs.h" +#include "sva_decodep.h" +#include "sva_decodepp.h" +#include "sva_eventmgt.h" + + + /*------------------------------------------------------------------------ + * Global Variables + *----------------------------------------------------------------------*/ +#ifdef __DEBUG +extern PUBLIC t_sva_dc_debug_events eventDecodeDebugTable[NUM_MAX_DECODE]; +extern PUBLIC t_sva_dc_debug_commands commandDecodeDebugTable[NUM_MAX_DECODE]; +extern PUBLIC t_sva_dc_debug_transitions transitionDecodeDebugTable[NUM_MAX_DECODE]; +#endif + +/*instance descriptors*/ +extern PUBLIC t_sva_dc_descriptor decodeDesc[NUM_MAX_DECODE]; + + +/*table that translate decode state into service state*/ +PRIVATE const t_sva_service_state decodeState2ServiceState[SVA_DC_LAST_DUMMY_STATE]= { + SVA_SERVICE_NOT_INITIALIZED, /*SVA_DC_NOT_INITIALIZED*/ + SVA_SERVICE_WAIT_FOR_CONFIGURATION, /*SVA_DC_WAIT_FOR_CONFIGURATION*/ + SVA_SERVICE_WAIT_FOR_INTERNAL_NEEDS, /*SVA_DC_WAIT_FOR_INTERNAL_NEEDS*/ + SVA_SERVICE_WAIT_FOR_ACTIVATE, /*SVA_DC_WAIT_FOR_ACTIVATE*/ + SVA_SERVICE_WAIT_FOR_START, /*SVA_DC_WAIT_FOR_START*/ + SVA_SERVICE_FLUSHING, /*SVA_DC_FLUSHING_IN*/ + SVA_SERVICE_FLUSHING, /*SVA_DC_FLUSHING_OUT*/ + SVA_SERVICE_WAIT_FOR_DATA, /*SVA_DC_WAIT_FOR_DATA*/ + SVA_SERVICE_RUNNING, /*SVA_DC_RUNNING*/ + SVA_SERVICE_ABORT_REQUESTED, /*SVA_DC_ABORT_REQUESTED*/ + SVA_SERVICE_STOP_REQUESTED, /*SVA_DC_STOP_REQUESTED*/ + SVA_SERVICE_ERROR /*SVA_DC_ERROR*/ +}; + +/*main state machine description*/ +PRIVATE const t_sva_dc_state stateMachine[SVA_DC_LAST_DUMMY_STATE][SVA_DC_LAST_DUMMY_TRANSITION]= { + /* Current State = SVA_DC_NOT_INITIALIZED */ + { + SVA_DC_WAIT_FOR_CONFIGURATION, /*SVA_DC_CREATE*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_CONFIGURE*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_INTERNAL_NEEDS*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_ACTIVATE*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_INACTIVATE*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_CONTROL_START*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_CONTROL_STOP*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_CONTROL_ABORT*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_ALL_DEPENDENCIES_RESOLVED*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_PUSH*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_EVENT_EOK*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_EVENT_FAKE*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_EVENT_ACTIVE*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_EVENT_INACTIVE*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_RESET*/ + SVA_DC_NOT_INITIALIZED, /*SVA_DC_CONTROL_DELETE*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_EVENT_ERROR*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_FLUSH_IN*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_FLUSH_OUT*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_CANCEL*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_UPDATE_PARAM*/ + SVA_DC_TRANSITION_REJECTED /*SVA_DC_GET_PARAM_SIZE*/ + + }, + /* Current State = SVA_DC_WAIT_FOR_CONFIGURATION */ + { + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_CREATE*/ + SVA_DC_WAIT_FOR_INTERNAL_NEEDS, /*SVA_DC_CONFIGURE*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_INTERNAL_NEEDS*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_ACTIVATE*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_INACTIVATE*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_CONTROL_START*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_CONTROL_STOP*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_CONTROL_ABORT*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_ALL_DEPENDENCIES_RESOLVED*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_PUSH*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_EVENT_EOK*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_EVENT_FAKE*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_EVENT_ACTIVE*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_EVENT_INACTIVE*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_RESET*/ + SVA_DC_NOT_INITIALIZED, /*SVA_DC_CONTROL_DELETE*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_EVENT_ERROR*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_FLUSH_IN*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_FLUSH_OUT*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_CANCEL*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_UPDATE_PARAM*/ + SVA_DC_TRANSITION_REJECTED /*SVA_DC_GET_PARAM_SIZE*/ + }, + /* Current State = SVA_DC_WAIT_FOR_INTERNAL_NEEDS */ + { + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_CREATE*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_CONFIGURE*/ + SVA_DC_WAIT_FOR_ACTIVATE, /*SVA_DC_INTERNAL_NEEDS*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_ACTIVATE*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_INACTIVATE*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_CONTROL_START*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_CONTROL_STOP*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_CONTROL_ABORT*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_ALL_DEPENDENCIES_RESOLVED*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_PUSH*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_EVENT_EOK*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_EVENT_FAKE*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_EVENT_ACTIVE*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_EVENT_INACTIVE*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_RESET*/ + SVA_DC_NOT_INITIALIZED, /*SVA_DC_CONTROL_DELETE*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_EVENT_ERROR*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_FLUSH_IN*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_FLUSH_OUT*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_CANCEL*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_UPDATE_PARAM*/ + SVA_DC_WAIT_FOR_INTERNAL_NEEDS /*SVA_DC_GET_PARAM_SIZE*/ + }, + /* Current State = SVA_DC_WAIT_FOR_ACTIVATE */ + { + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_CREATE*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_CONFIGURE*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_INTERNAL_NEEDS*/ + SVA_DC_WAIT_FOR_ACTIVATE, /*SVA_DC_ACTIVATE*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_INACTIVATE*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_CONTROL_START*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_CONTROL_STOP*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_CONTROL_ABORT*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_ALL_DEPENDENCIES_RESOLVED*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_PUSH*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_EVENT_EOK*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_EVENT_FAKE*/ + SVA_DC_WAIT_FOR_START, /*SVA_DC_EVENT_ACTIVE*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_EVENT_INACTIVE*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_RESET*/ + SVA_DC_NOT_INITIALIZED, /*SVA_DC_CONTROL_DELETE*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_EVENT_ERROR*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_FLUSH_IN*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_FLUSH_OUT*/ + SVA_DC_WAIT_FOR_ACTIVATE, /*SVA_DC_CANCEL*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_UPDATE_PARAM*/ + SVA_DC_WAIT_FOR_ACTIVATE /*SVA_DC_GET_PARAM_SIZE*/ + }, + /* Current State = SVA_DC_WAIT_FOR_START */ + { + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_CREATE*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_CONFIGURE*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_INTERNAL_NEEDS*/ + SVA_DC_WAIT_FOR_START, /*SVA_DC_ACTIVATE*/ + SVA_DC_WAIT_FOR_START, /*SVA_DC_INACTIVATE*/ + SVA_DC_WAIT_FOR_DATA, /*SVA_DC_CONTROL_START*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_CONTROL_STOP*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_CONTROL_ABORT*/ + SVA_DC_WAIT_FOR_START, /*SVA_DC_ALL_DEPENDENCIES_RESOLVED*/ + SVA_DC_WAIT_FOR_START, /*SVA_DC_PUSH*/ + SVA_DC_ERROR, /*SVA_DC_EVENT_EOK*/ + SVA_DC_ERROR, /*SVA_DC_EVENT_FAKE*/ + SVA_DC_WAIT_FOR_START, /*SVA_DC_EVENT_ACTIVE*/ + SVA_DC_WAIT_FOR_START, /*SVA_DC_EVENT_INACTIVE*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_RESET*/ + SVA_DC_NOT_INITIALIZED, /*SVA_DC_CONTROL_DELETE*/ + SVA_DC_ERROR, /*SVA_DC_EVENT_ERROR*/ + SVA_DC_FLUSHING_IN, /*SVA_DC_FLUSH_IN*/ + SVA_DC_FLUSHING_OUT, /*SVA_DC_FLUSH_OUT*/ + SVA_DC_WAIT_FOR_START, /*SVA_DC_CANCEL*/ + SVA_DC_WAIT_FOR_START, /*SVA_DC_UPDATE_PARAM*/ + SVA_DC_WAIT_FOR_START /*SVA_DC_GET_PARAM_SIZE*/ + }, + /* Current State = SVA_DC_FLUSHING_IN */ + { + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_CREATE*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_CONFIGURE*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_INTERNAL_NEEDS*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_ACTIVATE*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_INACTIVATE*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_CONTROL_START*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_CONTROL_STOP*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_CONTROL_ABORT*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_ALL_DEPENDENCIES_RESOLVED*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_PUSH*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_EVENT_EOK*/ + SVA_DC_WAIT_FOR_START, /*SVA_DC_EVENT_FAKE*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_EVENT_ACTIVE*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_EVENT_INACTIVE*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_RESET*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_CONTROL_DELETE*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_EVENT_ERROR*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_FLUSH_IN*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_FLUSH_OUT*/ + SVA_DC_FLUSHING_IN, /*SVA_DC_CANCEL*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_UPDATE_PARAM*/ + SVA_DC_FLUSHING_IN /*SVA_DC_GET_PARAM_SIZE*/ + }, + /* Current State = SVA_DC_FLUSHING_OUT */ + { + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_CREATE*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_CONFIGURE*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_INTERNAL_NEEDS*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_ACTIVATE*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_INACTIVATE*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_CONTROL_START*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_CONTROL_STOP*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_CONTROL_ABORT*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_ALL_DEPENDENCIES_RESOLVED*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_PUSH*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_EVENT_EOK*/ + SVA_DC_WAIT_FOR_START, /*SVA_DC_EVENT_FAKE*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_EVENT_ACTIVE*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_EVENT_INACTIVE*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_RESET*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_CONTROL_DELETE*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_EVENT_ERROR*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_FLUSH_IN*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_FLUSH_OUT*/ + SVA_DC_FLUSHING_OUT, /*SVA_DC_CANCEL*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_UPDATE_PARAM*/ + SVA_DC_FLUSHING_OUT /*SVA_DC_GET_PARAM_SIZE*/ + }, + /* Current State = SVA_DC_WAIT_FOR_DATA */ + { + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_CREATE*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_CONFIGURE*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_INTERNAL_NEEDS*/ + SVA_DC_WAIT_FOR_DATA, /*SVA_DC_ACTIVATE*/ + SVA_DC_WAIT_FOR_DATA, /*SVA_DC_INACTIVATE*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_CONTROL_START*/ + SVA_DC_STOP_REQUESTED, /*SVA_DC_CONTROL_STOP*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_CONTROL_ABORT*/ + SVA_DC_RUNNING, /*SVA_DC_ALL_DEPENDENCIES_RESOLVED*/ + SVA_DC_WAIT_FOR_DATA, /*SVA_DC_PUSH*/ + SVA_DC_ERROR, /*SVA_DC_EVENT_EOK*/ + SVA_DC_ERROR, /*SVA_DC_EVENT_FAKE*/ + SVA_DC_WAIT_FOR_DATA, /*SVA_DC_EVENT_ACTIVE*/ + SVA_DC_WAIT_FOR_DATA, /*SVA_DC_EVENT_INACTIVE*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_RESET*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_CONTROL_DELETE*/ + SVA_DC_ERROR, /*SVA_DC_EVENT_ERROR*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_FLUSH_IN*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_FLUSH_OUT*/ + SVA_DC_WAIT_FOR_DATA, /*SVA_DC_CANCEL*/ + SVA_DC_WAIT_FOR_DATA, /*SVA_DC_UPDATE_PARAM*/ + SVA_DC_WAIT_FOR_DATA /*SVA_DC_GET_PARAM_SIZE*/ + }, + /* Current State = SVA_DC_RUNNING */ + { + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_CREATE*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_CONFIGURE*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_INTERNAL_NEEDS*/ + SVA_DC_RUNNING, /*SVA_DC_ACTIVATE*/ + SVA_DC_RUNNING, /*SVA_DC_INACTIVATE*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_CONTROL_START*/ + SVA_DC_STOP_REQUESTED, /*SVA_DC_CONTROL_STOP*/ + SVA_DC_ABORT_REQUESTED, /*SVA_DC_CONTROL_ABORT*/ + SVA_DC_RUNNING, /*SVA_DC_ALL_DEPENDENCIES_RESOLVED*/ + SVA_DC_RUNNING, /*SVA_DC_PUSH*/ + SVA_DC_WAIT_FOR_DATA, /*SVA_DC_EVENT_EOK*/ + SVA_DC_ERROR, /*SVA_DC_EVENT_FAKE*/ + SVA_DC_RUNNING, /*SVA_DC_EVENT_ACTIVE*/ + SVA_DC_RUNNING, /*SVA_DC_EVENT_INACTIVE*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_RESET*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_CONTROL_DELETE*/ + SVA_DC_ERROR, /*SVA_DC_EVENT_ERROR*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_FLUSH_IN*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_FLUSH_OUT*/ + SVA_DC_RUNNING, /*SVA_DC_CANCEL*/ + SVA_DC_RUNNING, /*SVA_DC_UPDATE_PARAM*/ + SVA_DC_RUNNING /*SVA_DC_GET_PARAM_SIZE*/ + }, + /* Current State = SVA_DC_ABORT_REQUESTED */ + { + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_CREATE*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_CONFIGURE*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_INTERNAL_NEEDS*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_ACTIVATE*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_INACTIVATE*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_CONTROL_START*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_CONTROL_STOP*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_CONTROL_ABORT*/ + SVA_DC_ABORT_REQUESTED, /*SVA_DC_ALL_DEPENDENCIES_RESOLVED*/ + SVA_DC_ABORT_REQUESTED, /*SVA_DC_PUSH*/ + SVA_DC_ERROR, /*SVA_DC_EVENT_EOK*/ + SVA_DC_ERROR, /*SVA_DC_EVENT_FAKE*/ + SVA_DC_ERROR, /*SVA_DC_EVENT_ACTIVE*/ + SVA_DC_ERROR, /*SVA_DC_EVENT_INACTIVE*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_RESET*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_CONTROL_DELETE*/ + SVA_DC_ERROR, /*SVA_DC_EVENT_ERROR*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_FLUSH_IN*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_FLUSH_OUT*/ + SVA_DC_ABORT_REQUESTED, /*SVA_DC_CANCEL*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_UPDATE_PARAM*/ + SVA_DC_ABORT_REQUESTED /*SVA_DC_GET_PARAM_SIZE*/ + }, + /* Current State = SVA_DC_STOP_REQUESTED */ + { + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_CREATE*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_CONFIGURE*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_INTERNAL_NEEDS*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_ACTIVATE*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_INACTIVATE*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_CONTROL_START*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_CONTROL_STOP*/ + SVA_DC_ABORT_REQUESTED, /*SVA_DC_CONTROL_ABORT*/ + SVA_DC_STOP_REQUESTED, /*SVA_DC_ALL_DEPENDENCIES_RESOLVED*/ + SVA_DC_STOP_REQUESTED, /*SVA_DC_PUSH*/ + SVA_DC_WAIT_FOR_START, /*SVA_DC_EVENT_EOK*/ + SVA_DC_ERROR, /*SVA_DC_EVENT_FAKE*/ + SVA_DC_ERROR, /*SVA_DC_EVENT_ACTIVE*/ + SVA_DC_ERROR, /*SVA_DC_EVENT_INACTIVE*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_RESET*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_CONTROL_DELETE*/ + SVA_DC_ERROR, /*SVA_DC_EVENT_ERROR*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_FLUSH_IN*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_FLUSH_OUT*/ + SVA_DC_STOP_REQUESTED, /*SVA_DC_CANCEL*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_UPDATE_PARAM*/ + SVA_DC_STOP_REQUESTED /*SVA_DC_GET_PARAM_SIZE*/ + }, + /* Current State = SVA_DC_ERROR */ + { + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_CREATE*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_CONFIGURE*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_INTERNAL_NEEDS*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_ACTIVATE*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_INACTIVATE*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_CONTROL_START*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_CONTROL_STOP*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_CONTROL_ABORT*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_ALL_DEPENDENCIES_RESOLVED*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_PUSH*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_EVENT_EOK*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_EVENT_FAKE*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_EVENT_ACTIVE*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_EVENT_INACTIVE*/ + SVA_DC_WAIT_FOR_START, /*SVA_DC_RESET*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_CONTROL_DELETE*/ + SVA_DC_ERROR, /*SVA_DC_EVENT_ERROR*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_FLUSH_IN*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_FLUSH_OUT*/ + SVA_DC_ERROR, /*SVA_DC_CANCEL*/ + SVA_DC_TRANSITION_REJECTED, /*SVA_DC_UPDATE_PARAM*/ + SVA_DC_ERROR /*SVA_DC_GET_PARAM_SIZE*/ + } +}; + +/*activate state machine description*/ +PRIVATE const t_sva_dc_activate_state activateStateMachine[SVA_DC_LAST_ACTIVATE_DUMMY_STATE][SVA_DC_LAST_DUMMY_TRANSITION]= { + /* Current State = SVA_DC_INACTIVE */ + { + SVA_DC_INACTIVE, /*SVA_DC_CREATE*/ + SVA_DC_INACTIVE, /*SVA_DC_CONFIGURE*/ + SVA_DC_INACTIVE, /*SVA_DC_INTERNAL_NEEDS*/ + SVA_DC_IN_ACTIVATION, /*SVA_DC_ACTIVATE*/ + SVA_DC_ACTIVATE_TRANSITION_REJECTED, /*SVA_DC_INACTIVATE*/ + SVA_DC_ACTIVATE_TRANSITION_REJECTED, /*SVA_DC_CONTROL_START*/ + SVA_DC_ACTIVATE_TRANSITION_REJECTED, /*SVA_DC_CONTROL_STOP*/ + SVA_DC_ACTIVATE_TRANSITION_REJECTED, /*SVA_DC_CONTROL_ABORT*/ + SVA_DC_INACTIVE, /*SVA_DC_ALL_DEPENDENCIES_RESOLVED*/ + SVA_DC_INACTIVE, /*SVA_DC_PUSH*/ + SVA_DC_INACTIVE, /*SVA_DC_EVENT_EOK*/ + SVA_DC_INACTIVE, /*SVA_DC_EVENT_FAKE*/ + SVA_DC_INACTIVE, /*SVA_DC_EVENT_ACTIVE*/ + SVA_DC_INACTIVE, /*SVA_DC_EVENT_INACTIVE*/ + SVA_DC_INACTIVE, /*SVA_DC_RESET*/ + SVA_DC_INACTIVE, /*SVA_DC_CONTROL_DELETE*/ + SVA_DC_INACTIVE, /*SVA_DC_EVENT_ERROR*/ + SVA_DC_INACTIVE, /*SVA_DC_FLUSH_IN*/ + SVA_DC_INACTIVE, /*SVA_DC_FLUSH_OUT*/ + SVA_DC_ACTIVATE_TRANSITION_REJECTED, /*SVA_DC_CANCEL*/ + SVA_DC_INACTIVE, /*SVA_DC_UPDATE_PARAM*/ + SVA_DC_INACTIVE /*SVA_DC_GET_PARAM_SIZE*/ + }, + /* Current State = SVA_DC_IN_ACTIVATION */ + { + SVA_DC_ACTIVATE_TRANSITION_REJECTED, /*SVA_DC_CREATE*/ + SVA_DC_ACTIVATE_TRANSITION_REJECTED, /*SVA_DC_CONFIGURE*/ + SVA_DC_ACTIVATE_TRANSITION_REJECTED, /*SVA_DC_INTERNAL_NEEDS*/ + SVA_DC_ACTIVATE_TRANSITION_REJECTED, /*SVA_DC_ACTIVATE*/ + SVA_DC_ACTIVATE_TRANSITION_REJECTED, /*SVA_DC_INACTIVATE*/ + SVA_DC_ACTIVATE_TRANSITION_REJECTED, /*SVA_DC_CONTROL_START*/ + SVA_DC_ACTIVATE_TRANSITION_REJECTED, /*SVA_DC_CONTROL_STOP*/ + SVA_DC_ACTIVATE_TRANSITION_REJECTED, /*SVA_DC_CONTROL_ABORT*/ + SVA_DC_IN_ACTIVATION, /*SVA_DC_ALL_DEPENDENCIES_RESOLVED*/ + SVA_DC_IN_ACTIVATION, /*SVA_DC_PUSH*/ + SVA_DC_IN_ACTIVATION, /*SVA_DC_EVENT_EOK*/ + SVA_DC_IN_ACTIVATION, /*SVA_DC_EVENT_FAKE*/ + SVA_DC_ACTIVE, /*SVA_DC_EVENT_ACTIVE*/ + SVA_DC_IN_ACTIVATION, /*SVA_DC_EVENT_INACTIVE*/ + SVA_DC_IN_ACTIVATION, /*SVA_DC_RESET*/ + SVA_DC_ACTIVATE_TRANSITION_REJECTED, /*SVA_DC_CONTROL_DELETE*/ + SVA_DC_IN_ACTIVATION, /*SVA_DC_EVENT_ERROR*/ + SVA_DC_IN_ACTIVATION, /*SVA_DC_FLUSH_IN*/ + SVA_DC_IN_ACTIVATION, /*SVA_DC_FLUSH_OUT*/ + SVA_DC_INACTIVE, /*SVA_DC_CANCEL*/ + SVA_DC_IN_ACTIVATION, /*SVA_DC_UPDATE_PARAM*/ + SVA_DC_IN_ACTIVATION /*SVA_DC_GET_PARAM_SIZE*/ + }, + /* Current State = SVA_DC_ACTIVE */ + { + SVA_DC_ACTIVATE_TRANSITION_REJECTED, /*SVA_DC_CREATE*/ + SVA_DC_ACTIVATE_TRANSITION_REJECTED, /*SVA_DC_CONFIGURE*/ + SVA_DC_ACTIVATE_TRANSITION_REJECTED, /*SVA_DC_INTERNAL_NEEDS*/ + SVA_DC_ACTIVATE_TRANSITION_REJECTED, /*SVA_DC_ACTIVATE*/ + SVA_DC_IN_INACTIVATION, /*SVA_DC_INACTIVATE*/ + SVA_DC_ACTIVE, /*SVA_DC_CONTROL_START*/ + SVA_DC_ACTIVE, /*SVA_DC_CONTROL_STOP*/ + SVA_DC_ACTIVE, /*SVA_DC_CONTROL_ABORT*/ + SVA_DC_ACTIVE, /*SVA_DC_ALL_DEPENDENCIES_RESOLVED*/ + SVA_DC_ACTIVE, /*SVA_DC_PUSH*/ + SVA_DC_ACTIVE, /*SVA_DC_EVENT_EOK*/ + SVA_DC_ACTIVE, /*SVA_DC_EVENT_FAKE*/ + SVA_DC_ACTIVE, /*SVA_DC_EVENT_ACTIVE*/ + SVA_DC_ACTIVE, /*SVA_DC_EVENT_INACTIVE*/ + SVA_DC_ACTIVE, /*SVA_DC_RESET*/ + SVA_DC_INACTIVE, /*SVA_DC_CONTROL_DELETE*/ + SVA_DC_ACTIVE, /*SVA_DC_EVENT_ERROR*/ + SVA_DC_ACTIVE, /*SVA_DC_FLUSH_IN*/ + SVA_DC_ACTIVE, /*SVA_DC_FLUSH_OUT*/ + SVA_DC_ACTIVATE_TRANSITION_REJECTED, /*SVA_DC_CANCEL*/ + SVA_DC_ACTIVE, /*SVA_DC_UPDATE_PARAM*/ + SVA_DC_ACTIVE /*SVA_DC_GET_PARAM_SIZE*/ + }, + /* Current State = SVA_DC_IN_INACTIVATION */ + { + SVA_DC_ACTIVATE_TRANSITION_REJECTED, /*SVA_DC_CREATE*/ + SVA_DC_ACTIVATE_TRANSITION_REJECTED, /*SVA_DC_CONFIGURE*/ + SVA_DC_ACTIVATE_TRANSITION_REJECTED, /*SVA_DC_INTERNAL_NEEDS*/ + SVA_DC_ACTIVATE_TRANSITION_REJECTED, /*SVA_DC_ACTIVATE*/ + SVA_DC_ACTIVATE_TRANSITION_REJECTED, /*SVA_DC_INACTIVATE*/ + SVA_DC_ACTIVATE_TRANSITION_REJECTED, /*SVA_DC_CONTROL_START*/ + SVA_DC_ACTIVATE_TRANSITION_REJECTED, /*SVA_DC_CONTROL_STOP*/ + SVA_DC_ACTIVATE_TRANSITION_REJECTED, /*SVA_DC_CONTROL_ABORT*/ + SVA_DC_IN_INACTIVATION, /*SVA_DC_ALL_DEPENDENCIES_RESOLVED*/ + SVA_DC_IN_INACTIVATION, /*SVA_DC_PUSH*/ + SVA_DC_IN_INACTIVATION, /*SVA_DC_EVENT_EOK*/ + SVA_DC_IN_INACTIVATION, /*SVA_DC_EVENT_FAKE*/ + SVA_DC_IN_INACTIVATION, /*SVA_DC_EVENT_ACTIVE*/ + SVA_DC_INACTIVE, /*SVA_DC_EVENT_INACTIVE*/ + SVA_DC_INACTIVE, /*SVA_DC_RESET*/ + SVA_DC_ACTIVATE_TRANSITION_REJECTED, /*SVA_DC_CONTROL_DELETE*/ + SVA_DC_IN_INACTIVATION, /*SVA_DC_EVENT_ERROR*/ + SVA_DC_IN_INACTIVATION, /*SVA_DC_FLUSH_IN*/ + SVA_DC_IN_INACTIVATION, /*SVA_DC_FLUSH_OUT*/ + SVA_DC_ACTIVE, /*SVA_DC_CANCEL*/ + SVA_DC_IN_INACTIVATION, /*SVA_DC_UPDATE_PARAM*/ + SVA_DC_IN_INACTIVATION /*SVA_DC_GET_PARAM_SIZE*/ + } +}; + +/****************************************************************************/ +/* NAME: t_sva_DC_state sva_DC_UpdateInstanceStateMachine( */ +/* t_sva_service_instance_num instanceNum, */ +/* t_sva_DC_transition requestedTransition */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine allows to update both state machine */ +/* following the given requestedTransition */ +/* */ +/* N.B: This routine returns the new state after the requested transition */ +/* A special return state (SVA_DC_TRANSITION_REJECTED) is used to check */ +/* the validity of a transition request */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - instanceNum : instance number for which state must be updated */ +/* - requestedTransition: identifier of the requested transition */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: t_sva_DC_state */ +/* - one of the t_sva_DC_state */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + DONE +*/ +PUBLIC t_sva_dc_state sva_DC_UpdateInstanceStateMachine +( + t_sva_service_instance_num instanceNum, + t_sva_dc_transition requestedTransition +) +{ + t_sva_dc_descriptor *pDesc=&decodeDesc[instanceNum]; + t_sva_dc_state nextState; + t_sva_dc_activate_state nextActivateState; + + +#ifdef __DEBUG + { + t_uint32 systemTime; + + SVA_GetServiceSystemTime(pDesc->serviceId,&systemTime); + transitionDecodeDebugTable[instanceNum].transitionDebugDesc[transitionDecodeDebugTable[instanceNum].nbOfTransitionReceived%LOG_DEPTH].state=pDesc->state; + transitionDecodeDebugTable[instanceNum].transitionDebugDesc[transitionDecodeDebugTable[instanceNum].nbOfTransitionReceived%LOG_DEPTH].transition=requestedTransition; + transitionDecodeDebugTable[instanceNum].transitionDebugDesc[transitionDecodeDebugTable[instanceNum].nbOfTransitionReceived%LOG_DEPTH].systemTime=systemTime; + transitionDecodeDebugTable[instanceNum].transitionDebugDesc[transitionDecodeDebugTable[instanceNum].nbOfTransitionReceived%LOG_DEPTH].activateState=pDesc->activateState; + transitionDecodeDebugTable[instanceNum].nbOfTransitionReceived++; + + } +#endif + + /* Compute the next state */ + nextState=stateMachine[pDesc->state][requestedTransition]; + nextActivateState=activateStateMachine[pDesc->activateState][requestedTransition]; + + /* Check if the transition is valid */ + if (nextState != SVA_DC_TRANSITION_REJECTED && nextActivateState!=SVA_DC_ACTIVATE_TRANSITION_REJECTED) + { + /* Update both current state of the instance */ + pDesc->state = nextState; + pDesc->activateState = nextActivateState; + /* Update status*/ + pDesc->status.state=decodeState2ServiceState[pDesc->state]; + } + + return nextState; +} + +/****************************************************************************/ +/* NAME: t_bool sva_DC_isTransitionValid( */ +/* t_sva_service_instance_num instanceNum, */ +/* t_sva_DC_transition requestedTransition */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine checks if the requestedTransition is valid for both */ +/* state machine */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - instanceNum : instance number for which transition check must be done*/ +/* - requestedTransition: identifier of the requested transition */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: t_bool */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + DONE +*/ +PUBLIC t_bool sva_DC_isTransitionValid +( + t_sva_service_instance_num instanceNum, + t_sva_dc_transition requestedTransition +) +{ + t_sva_dc_descriptor *pDesc=&decodeDesc[instanceNum]; + t_sva_dc_state nextState; + t_sva_dc_activate_state nextActivateState; + + /* Compute the next state for both state machine*/ + nextState=stateMachine[pDesc->state][requestedTransition]; + nextActivateState=activateStateMachine[pDesc->activateState][requestedTransition]; + + /*return false in case of invalid transition for at least one state machine*/ + if (nextState != SVA_DC_TRANSITION_REJECTED && nextActivateState!=SVA_DC_ACTIVATE_TRANSITION_REJECTED) {return TRUE;} + else {return FALSE;} +} + + +/****************************************************************************/ +/* NAME: sva_DC_TransferElemFromFifoToInUseFifo() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: This routine enables to transfer first elem of fifo */ +/* to related fifoInUse */ +/* NB:for image, buffer type, concerns in fact forward image */ +/* equivalent to POP_FIFO followed by PUSH_FIFO_INUSE */ +/* Applicable for fifoFwdImageBufferId, fifoBitstreamBufferId */ +/* fifoDeblockingBufferId, fifoInfosBufferId */ +/* WARNING: User is supposed to check that source fifo is NOT EMPTY */ +/* PARAMETERS: */ +/* IN : t_sva_service_instance_num instanceNum : */ +/* t_sva_buffer_type bufferType */ +/* OUT :t_sva_buffer_id *pBufferId */ +/* */ +/* RETURN: */ +/* t_sva_dc_error */ +/*--------------------------------------------------------------------------*/ +/* USE: NA */ +/* USED BY: NA */ +/****************************************************************************/ +PUBLIC t_sva_dc_error sva_DC_TransferElemFromFifoToInUseFifo(t_sva_service_instance_num instanceNum,t_sva_buffer_type bufferType, t_sva_buffer_id *pBufferId ) +{ + t_sva_ff_error ffError; + + HCL_ASSERT(pBufferId!=NULL); + + switch(bufferType) + { + case SVA_IMAGE_BUFFER_TYPE: //Target in fact Fwd ref image buffer + ffError=POP_FIFO_ELEM(decodeDesc[instanceNum].outputImageFifos.push,t_sva_buffer_id,*pBufferId); + if (ffError!= SVA_FIFO_OK) {return SVA_DC_FF_LINKED_ERROR;} + ffError=PUSH_FIFO_ELEM(decodeDesc[instanceNum].outputImageFifos.inUse,t_sva_buffer_id,*pBufferId); + if (ffError!= SVA_FIFO_OK) { + // In case of error, push back the last poped bufferId into its fifos + PUSH_REVERSE_FIFO_ELEM(decodeDesc[instanceNum].outputImageFifos.push,t_sva_buffer_id,*pBufferId); + return SVA_DC_FF_LINKED_ERROR; + } + break; + case SVA_BITSTREAM_BUFFER_TYPE: + ffError=POP_FIFO_ELEM(decodeDesc[instanceNum].inputBitstreamFifos.push,t_sva_buffer_id,*pBufferId); + if (ffError!= SVA_FIFO_OK) {return SVA_DC_FF_LINKED_ERROR;} + ffError=PUSH_FIFO_ELEM(decodeDesc[instanceNum].inputBitstreamFifos.inUse,t_sva_buffer_id,*pBufferId); + if (ffError!= SVA_FIFO_OK) { + // In case of error, push back the last poped bufferId into its fifos + PUSH_REVERSE_FIFO_ELEM(decodeDesc[instanceNum].inputBitstreamFifos.push,t_sva_buffer_id,*pBufferId); + return SVA_DC_FF_LINKED_ERROR; + } + break; + case SVA_PARAMS_BUFFER_TYPE: + ffError=POP_FIFO_ELEM(decodeDesc[instanceNum].outputDeblockingFifos.push,t_sva_buffer_id,*pBufferId); + if (ffError!= SVA_FIFO_OK) {return SVA_DC_FF_LINKED_ERROR;} + ffError=PUSH_FIFO_ELEM(decodeDesc[instanceNum].outputDeblockingFifos.inUse,t_sva_buffer_id,*pBufferId); + if (ffError!= SVA_FIFO_OK) { + // In case of error, push back the last poped bufferId into its fifos + PUSH_REVERSE_FIFO_ELEM(decodeDesc[instanceNum].outputDeblockingFifos.push,t_sva_buffer_id,*pBufferId); + return SVA_DC_FF_LINKED_ERROR; + } + break; + case SVA_INFOS_BUFFER_TYPE: + ffError=POP_FIFO_ELEM(decodeDesc[instanceNum].outputInfosFifos.push,t_sva_buffer_id,*pBufferId); + if (ffError!= SVA_FIFO_OK) {return SVA_DC_FF_LINKED_ERROR;} + ffError=PUSH_FIFO_ELEM(decodeDesc[instanceNum].outputInfosFifos.inUse,t_sva_buffer_id,*pBufferId); + if (ffError!= SVA_FIFO_OK) { + // In case of error, push back the last poped bufferId into its fifos + PUSH_REVERSE_FIFO_ELEM(decodeDesc[instanceNum].outputInfosFifos.push,t_sva_buffer_id,*pBufferId); + return SVA_DC_FF_LINKED_ERROR; + } + break; + default: + break; + } + return SVA_DC_OK; + +} --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/sva_decodep.h @@ -0,0 +1,364 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ + +#ifndef __INC_SVA_DECODEP_H +#define __INC_SVA_DECODEP_H + +#include "hcl_defs.h" +#include "sva_decode.h" +#include "sva_taskmgt.h" +#include "sva_buffermgt.h" +#include "sva_bufferlistmgt.h" +#include "sva_fifo.h" +#include "sva_service.h" + +/******************************************************************************/ +/* Constants definitions */ +/******************************************************************************/ +#ifdef __DEBUG + /* + * Define number of event to log + */ + #define LOG_DEPTH 16 +#endif + + +/* + * Define the max number of bufferList by frame + */ +#define NB_MAX_BUFFER_LIST_BY_FRAME 396 //CIF + + +/* + * Define the number of decode algo supported (ie MPEG4, H263...) + */ +#define NUMBER_OF_DECODE_ALGO_SUPPORTED 4 // MPEG4, H264, VC1, MPEG2 + +/* + * Define the number of field inside a Decode Subtask descriptor (spec v0.96) + */ +#define DECODE_FIELD_NUMBER 12 + +/* + * Define the default memory used to store subtasks descriptors + */ +#define DECODE_DEFAULT_MEMORY_ID SDRAM_ID + +/* + * Define the default memory used to store param_out (infos) data + */ +#define DECODE_DEFAULT_INFOS_MEMORY_ID SDRAM_ID + +/* + * Define fake bistream buffer size (in bytes) + * must be greater or equal to 48 + */ +#define FAKE_BITSTREAM_BUFFER_SIZE 256 + +/* + * Define macro to handle null pointer +*/ +#define DC_CHECK_NULL_POINTER(pointer) HCL_ASSERT(pointer!=NULL) + + +/* + * Define various configuration limits for decode +*/ +//define support of transforms + + +#define VGA_H 480 +#define VGA_W 640 + +#define QVGA_H 240 +#define QVGA_W 320 + +#define CIF_H 288 +#define CIF_W 352 + +#define DIF_H 208 +#define DIF_W 176 + +#define QCIF_H 144 +#define QCIF_W 176 + +#define SQCIF_H 96 +#define SQCIF_W 128 + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/******************************************************************************/ +/* Types definitions */ +/******************************************************************************/ + +typedef void t_sva_dc_algo_configuration_params; +typedef void t_sva_dc_algo_params_in; +typedef void t_sva_dc_algo_params_inout; +typedef void t_sva_dc_algo_params_out; +typedef void t_sva_dc_algo_status; + + +/* + * Define the various state of a Decode instance service + */ +typedef enum { + SVA_DC_NOT_INITIALIZED, + SVA_DC_WAIT_FOR_CONFIGURATION, + SVA_DC_WAIT_FOR_INTERNAL_NEEDS, + SVA_DC_WAIT_FOR_ACTIVATE, + SVA_DC_WAIT_FOR_START, + SVA_DC_FLUSHING_IN, + SVA_DC_FLUSHING_OUT, + SVA_DC_WAIT_FOR_DATA, + SVA_DC_RUNNING, + SVA_DC_ABORT_REQUESTED, + SVA_DC_STOP_REQUESTED, + SVA_DC_ERROR, + SVA_DC_LAST_DUMMY_STATE, + SVA_DC_TRANSITION_REJECTED +} t_sva_dc_state; + +/* + * Define the various activate state of a Decode instance service + */ +typedef enum { + SVA_DC_INACTIVE, + SVA_DC_IN_ACTIVATION, + SVA_DC_ACTIVE, + SVA_DC_IN_INACTIVATION, + SVA_DC_LAST_ACTIVATE_DUMMY_STATE, + SVA_DC_ACTIVATE_TRANSITION_REJECTED +} t_sva_dc_activate_state; + +/* + * Define the various transitions of the decode service + */ +typedef enum { + SVA_DC_CREATE, + SVA_DC_CONFIGURE, + SVA_DC_INTERNAL_NEEDS, + SVA_DC_ACTIVATE, + SVA_DC_INACTIVATE, + SVA_DC_CONTROL_START, + SVA_DC_CONTROL_STOP, + SVA_DC_CONTROL_ABORT, + SVA_DC_ALL_DEPENDENCIES_RESOLVED, + SVA_DC_PUSH, + SVA_DC_EVENT_EOK, + SVA_DC_EVENT_FAKE, + SVA_DC_EVENT_ACTIVE, + SVA_DC_EVENT_INACTIVE, + SVA_DC_RESET, + SVA_DC_CONTROL_DELETE, + SVA_DC_EVENT_ERROR, + SVA_DC_FLUSH_IN, + SVA_DC_FLUSH_OUT, + SVA_DC_CANCEL, + SVA_DC_UPDATE_PARAM, + SVA_DC_GET_PARAM_SIZE, + SVA_DC_LAST_DUMMY_TRANSITION +} t_sva_dc_transition; + +/* + * Define the symbol used to qualify the state of the dependency + * for a given type of buffer + */ +typedef enum { + INTERNAL_DEPENDENCY, + NOT_RESOLVED_DEPENDENCY, + RESOLVED_DEPENDENCY +} t_sva_dc_dependencies_state; + +/* + * Define the structure used to manage the subtasks dependency + */ +typedef struct { + t_sva_dc_dependencies_state outputImageDep; + t_sva_dc_dependencies_state inputBitstreamDep; // common dependencies for all codecs (Mpeg4, H264, VC1) + t_sva_dc_dependencies_state infosDep; +} t_sva_dc_dependencies_desc; + +/* + * Define the structure used to manage the dependencies of each subtasks + */ +typedef struct { + t_sva_tm_subtask_id subtaskId; + t_sva_buffer_list_id bitstreamBufferListId; + t_sva_dc_dependencies_desc dependencies; +} t_sva_dc_subtask_dependencies; + +/* + * Define the fifos used to manage the dependency + * The buffers, provided though the Push routine, are buffered inside the pushFifo + * When programming them (using them) into a subtask, then they are considered as used, + * as so pushed inside th inUseFifo + */ +typedef struct { + t_sva_fifo push; + t_sva_fifo inUse; +} t_sva_dc_fifo_dep; + +/* + * Define state machine use to synchronize configuration update + */ +typedef enum { + SVA_DC_NO_CONF_CHANGE_NEED, + SVA_DC_IMMEDIATE_CONF_CHANGE_NEED, + SVA_DC_WAIT_FOR_BUFFER, + SVA_DC_WAIT_FOR_BUFFER_ID, + SVA_DC_SYNC_CONF_CHANGE_NEED +} t_sva_dc_conf_state; + +typedef struct { +t_uint32 eotCounter; // Buffer Voided event counter +t_uint32 eokCounter; // Buffer Filled event counter +t_uint32 fakeCounter; // Buffer Partly Filled event counter +t_uint32 activeCounter; // Buffer Filled Read Only event counter +t_uint32 inactiveCounter; // Underflow event counter +t_uint32 errCounter; // Overflow event counter +t_uint32 eowCounter; // Service Error event counter +t_uint32 bowCounter; // Service Error event counter +t_uint32 ubuCounter; // Service Error event counter +} t_sva_decode_internal_event_stats; + + +/* + * Define structure that handle all stuff need to manipulate configuration change + */ +typedef struct { + t_sva_video_decoder_configuration currentConf; + //t_sva_video_decoder_configuration nextConf; + //t_uint32 currentConfCounter; + t_uint32 subTaskCounter[SUBTASK_DEFAULT_NUMBER]; + t_sva_buffer_type bufferType; + t_sva_push_mode pushMode; + t_sva_buffer_id bufferId; + //t_sva_dc_conf_state confState; +} t_sva_dc_conf_handle; + +/* + * Define structure that handle all stuff need to manipulate configuration change + */ +/* +typedef struct { +t_sva_tm_subtask_id subtaskId; +t_sva_buffer_list_id bitstreamBufferList; +} t_sva_dc_subtask_info; +*/ + +/* + * sva_DC_SetHeaderInfos parameters structure + */ + + +typedef void * tp_sva_video_decoder_algo_header_infos; + + +/* + * Define the descriptor of a Decode service instance + */ +typedef struct { + t_sva_dc_state state; + t_sva_service_id serviceId; + t_sva_dc_activate_state activateState; + t_sva_dc_conf_handle confHandle; + t_sva_sv_algo algo; + t_sva_tm_subtask_id subtasksIdArray[SUBTASK_DEFAULT_NUMBER]; + t_bool firstSubtaskExecuted; + t_sva_tm_subtask_list_id subtasksListId; + t_sva_video_decoder_status status; + t_sva_decode_internal_event_stats internalEventStatus; + //dependancies + t_sva_dc_fifo_dep subtasksDependencyFifo; + t_sva_dc_dependencies_desc defaultDep; + t_sva_fifo blockIdFifo; //for temporary paramout + t_logical_address paramOutAddr; //corresponds to adress of blockId used for Paramout update in EOT + //bitstream + t_sva_dc_fifo_dep inputBitstreamFifos; + //t_sva_fifo fakeBitstreamFifo; + t_sva_buffer_list_id bufferListIdArray[SUBTASK_DEFAULT_NUMBER][NB_MAX_BUFFER_LIST_BY_FRAME]; + //t_sva_buffer_list_id bitstreamBufferList; + t_sva_buffer_id currentProgrammedBitstreamBuffer; + t_sva_dc_fifo_dep lastPushedBufferFifo; + //fwd image + // t_sva_dc_fifo_dep inputFwdImageFifos; + t_sva_buffer_id fakeFwdImageBufferId; //one only element + //image + t_sva_dc_fifo_dep outputImageFifos; + //deblocking parameters + t_sva_dc_fifo_dep outputDeblockingFifos; + //infos + t_sva_dc_fifo_dep outputInfosFifos; + t_sva_fifo h264DecReadOnlyFifo; +} t_sva_dc_descriptor; + +/* + * Define the various transitions of the grab instance internal state machine + */ + + +#ifdef __DEBUG + /******************************************************************************/ + /* Trace Types definitions */ + /******************************************************************************/ + typedef struct { + t_sva_tm_virtual_hw_event_id event; + t_uint32 systemTime; + t_sva_tm_subtask_id subtaskId; + t_uint32 padding; + } t_sva_dc_debug_event_desc; + typedef struct { + t_uint32 padding[3]; + t_uint32 nbOfEventReceived; + t_sva_dc_debug_event_desc eventDebugDesc[LOG_DEPTH]; + } t_sva_dc_debug_events; + + typedef struct { + t_sva_service_cmd_id command; + t_uint32 systemTime; + t_uint32 parameter; + t_uint32 padding; + } t_sva_dc_debug_command_desc; + typedef struct { + t_uint32 padding[3]; + t_uint32 nbOfCommandReceived; + t_sva_dc_debug_command_desc commandDebugDesc[LOG_DEPTH]; + } t_sva_dc_debug_commands; + + typedef struct { + t_sva_dc_state state;/*state before transition occur*/ + t_sva_dc_transition transition; + t_uint32 systemTime; + t_sva_dc_activate_state activateState;/*state before transition occur*/ + } t_sva_dc_debug_transition_desc; + typedef struct { + t_uint32 padding[3]; + t_uint32 nbOfTransitionReceived; + t_sva_dc_debug_transition_desc transitionDebugDesc[LOG_DEPTH]; + } t_sva_dc_debug_transitions; +#endif + +#ifdef __cplusplus +} /* allow C++ to use these headers */ +#endif /* __cplusplus */ + +#endif /* __INC_SVA_DECODEP_H */ +/* End of file - sva_decodeP.h */ --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/sva_decodepp.h @@ -0,0 +1,40 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ + + +#ifndef __INC_SVA_DECODEPP_H +#define __INC_SVA_DECODEPP_H + + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "hcl_defs.h" + + +PUBLIC t_sva_dc_state sva_DC_UpdateInstanceStateMachine(t_sva_service_instance_num ,t_sva_dc_transition ); +PUBLIC t_bool sva_DC_isTransitionValid(t_sva_service_instance_num ,t_sva_dc_transition ); +PUBLIC t_sva_dc_error sva_DC_TransferElemFromFifoToInUseFifo(t_sva_service_instance_num,t_sva_buffer_type , t_sva_buffer_id * ); + +#ifdef __cplusplus +} /* allow C++ to use these headers */ +#endif /* __cplusplus */ + +#endif --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/vc1/sva_dc_vc1.c @@ -0,0 +1,2044 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ + + +/*------------------------------------------------------------------------ + * Includes + *----------------------------------------------------------------------*/ + +#include "hcl_defs.h" +#include "sva_host_interface.h" +#include "sva_buffermgt.h" +#include "sva_fifo.h" +#include "sva_decode.h" +#include "../sva_decodep.h" +#include "../sva_decodepp.h" +#include "sva_service.h" + +#include "../sva_dc_algo.h" +#include "sva_dc_vc1.h" +#include "sva_dc_vc1p.h" +#include "sva_fwmgtp.h" // required for t_sva_fm_internal_desc type (VC1 add-on) + + + /*------------------------------------------------------------------------ + * Global Variables + *----------------------------------------------------------------------*/ +#ifdef __DEBUG +extern PUBLIC t_sva_dc_debug_events eventDecodeDebugTable[NUM_MAX_DECODE]; +extern PUBLIC t_sva_dc_debug_commands commandDecodeDebugTable[NUM_MAX_DECODE]; +extern PUBLIC t_sva_dc_debug_transitions transitionDecodeDebugTable[NUM_MAX_DECODE]; +#endif + +/*instance descriptors*/ +extern PUBLIC t_sva_dc_descriptor decodeDesc[NUM_MAX_DECODE]; +extern PUBLIC const t_sva_tm_field_ctrl_desc defaultDecodeFieldDescArray[NUMBER_OF_DECODE_ALGO_SUPPORTED][DECODE_FIELD_NUMBER]; + +PUBLIC t_sva_vc1_desc VC1Desc[NUM_MAX_DECODE]; + +/* private */ +PRIVATE t_sva_vc1_SetHeaderInfosParam vc1HeaderInfosParam[NUM_MAX_DECODE]; + + +/****************************************************************************/ +/* NAME: sva_DC_VC1_InitAndGetMemoryNeeds() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: This routine enables to store all statical parameters */ +/* PARAMETERS: */ +/* IN : t_sva_service_instance_num instanceNum */ +/* t_sva_codec_mode codecMode */ +/* t_sva_image_desc imageDesc */ +/* t_sva_codec_algo_configuration_params *confParams */ +/* OUT : */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/*--------------------------------------------------------------------------*/ +/* USE: NA */ +/* USED BY: NA */ +/****************************************************************************/ +PUBLIC t_sva_error sva_DC_VC1_Init( + t_sva_service_instance_num instanceNum, + t_sva_codec_mode codecMode, + t_sva_image_desc imageDesc, + const t_sva_dc_algo_configuration_params *pconfParams) +{ + + t_sva_video_decoder_algo_vc1_configuration_params *pVC1ConfParams; + t_sva_error svaError; + + HCL_ASSERT(pconfParams!=NULL); + + + VC1Desc[instanceNum].codecMode=codecMode; + VC1Desc[instanceNum].imageDesc=imageDesc; + //Store Sequence Layer parameters + pVC1ConfParams=(t_sva_video_decoder_algo_vc1_configuration_params *)pconfParams; + VC1Desc[instanceNum].seqLayerParams=*pVC1ConfParams; + VC1Desc[instanceNum].max_b_frames = pVC1ConfParams->max_b_frames; // useful to handle references + + //init globag structure for segmented and stream modes + if (VC1Desc[instanceNum].codecMode != SVA_CODEC_IMAGE_MODE) { + svaError = sva_DC_VC1_InitHeaderInfos(instanceNum); + if (svaError!=SVA_OK) return svaError; + } + + return SVA_OK; +} + + +/****************************************************************************/ +/* NAME: sva_DC_VC1_GetMemoryNeeds() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: This routine enables to determine also cachable memory needs for software process */ +/* PARAMETERS: */ +/* IN : t_sva_service_instance_num instanceNum */ +/* OUT :t_size *pMemNeeds */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/*--------------------------------------------------------------------------*/ +/* USE: NA */ +/* USED BY: NA */ +/****************************************************************************/ +PUBLIC t_sva_error sva_DC_VC1_GetMemoryNeeds( + t_sva_service_instance_num instanceNum, + t_size *pMemNeeds) +{ + + t_size fifoSize; + + HCL_ASSERT(pMemNeeds!=NULL); + + //Picture Layer Params Fifo + GET_FIFO_MEMORY_NEEDS(t_sva_video_decoder_algo_vc1_header_infos, VC1_DECODE_MAX_FIFO_SIZE, fifoSize); + *pMemNeeds = fifoSize; + //Bitstream position fifo + GET_FIFO_MEMORY_NEEDS(t_sva_bitstream_desc, VC1_DECODE_MAX_FIFO_SIZE, fifoSize); + *pMemNeeds = *pMemNeeds + fifoSize; + /* fake bistream buffer */ + GET_FIFO_MEMORY_NEEDS(t_sva_buffer_id, SUBTASK_DEFAULT_NUMBER, fifoSize); + *pMemNeeds = *pMemNeeds + fifoSize; + //reference(s) handler fifo + GET_FIFO_MEMORY_NEEDS(t_sva_vc1_reference_handler, VC1_DECODE_MAX_FIFO_SIZE, fifoSize); + *pMemNeeds = *pMemNeeds + fifoSize; + //to handle frame reordering + GET_FIFO_MEMORY_NEEDS(t_sva_buffer_id, VC1_DECODE_MAX_FIFO_SIZE, fifoSize); + *pMemNeeds = *pMemNeeds + fifoSize; + //reference Images fifo (Ref and prevRef) + GET_FIFO_MEMORY_NEEDS(t_sva_buffer_id, VC1_DECODE_MAX_FIFO_SIZE, fifoSize); + *pMemNeeds = *pMemNeeds + fifoSize; + GET_FIFO_MEMORY_NEEDS(t_sva_buffer_id, VC1_DECODE_MAX_FIFO_SIZE, fifoSize); + *pMemNeeds = *pMemNeeds + fifoSize; + //VC1 dependency fifo + GET_FIFO_MEMORY_NEEDS(t_sva_dc_vc1_dependencies_desc, SUBTASK_DEFAULT_NUMBER, fifoSize); + *pMemNeeds = *pMemNeeds + fifoSize; + GET_FIFO_MEMORY_NEEDS(t_sva_dc_vc1_dependencies_desc, SUBTASK_DEFAULT_NUMBER, fifoSize); + *pMemNeeds = *pMemNeeds + fifoSize; + + return SVA_OK; + +} + + + +/****************************************************************************/ +/* NAME: sva_DC_VC1_ProvideMemoryNeeds() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: This routine enables to provide cachable memory needs */ +/* for decode fifos */ +/* PARAMETERS: */ +/* IN : t_sva_service_instance_num instanceNum */ +/* OUT : */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/*--------------------------------------------------------------------------*/ +/* USE: NA */ +/* USED BY: NA */ +/****************************************************************************/ +PUBLIC t_sva_error sva_DC_VC1_ProvideMemoryNeeds(t_sva_service_instance_num instanceNum) +{ + t_sva_ff_error ffError; + t_uint16 i; + t_system_address fakeBufferSystemAddr; + t_sva_buffer_id fakeBitstreamBufferId; + t_sva_error svaError; + t_sva_mm_error mmError; + t_system_address paramInOutAddress; + t_sva_block_id paramInOutBlockId; + + //Create all internal fifos + //Picture Layer Params Fifo + CREATE_FIFO(t_sva_video_decoder_algo_vc1_header_infos,VC1_DECODE_MAX_FIFO_SIZE,VC1Desc[instanceNum].picLayerParamsFifo,ffError); + if (ffError!= SVA_FIFO_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + //Bitstream position fifosva + CREATE_FIFO(t_sva_bitstream_desc,VC1_DECODE_MAX_FIFO_SIZE,VC1Desc[instanceNum].fifoBitstream,ffError); + if (ffError!= SVA_FIFO_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + //fakeBitstreamFifo + CREATE_FIFO(t_sva_buffer_id, SUBTASK_DEFAULT_NUMBER, VC1Desc[instanceNum].fakeBitstreamFifo, ffError); + if (ffError != SVA_FIFO_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + //reference(s) handler fifo + CREATE_FIFO(t_sva_vc1_reference_handler, VC1_DECODE_MAX_FIFO_SIZE, VC1Desc[instanceNum].referenceHandlerFifo, ffError); + if (ffError != SVA_FIFO_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + //reference Images fifo (Ref and prevRef) + CREATE_FIFO(t_sva_buffer_id,VC1_DECODE_MAX_FIFO_SIZE,VC1Desc[instanceNum].refImage,ffError); + if (ffError!= SVA_FIFO_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + CREATE_FIFO(t_sva_buffer_id,VC1_DECODE_MAX_FIFO_SIZE,VC1Desc[instanceNum].prevRefImage,ffError); + if (ffError!= SVA_FIFO_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + //VC1 dependency fifos + CREATE_FIFO(t_sva_dc_vc1_dependencies_desc, SUBTASK_DEFAULT_NUMBER, VC1Desc[instanceNum].vc1Dep.push, ffError); + if (ffError != SVA_FIFO_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + CREATE_FIFO(t_sva_dc_vc1_dependencies_desc, SUBTASK_DEFAULT_NUMBER, VC1Desc[instanceNum].vc1Dep.inUse, ffError); + if (ffError != SVA_FIFO_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + + // Allocate the paramInOut structure within the not cachable sva memory chunk + mmError = sva_MM_AllocBlock(SDRAM_ID, sizeof(t_sva_vdc_vc1_param_inout), SVA_MM_ALIGN_32BYTES, ¶mInOutBlockId); + if (mmError!=SVA_MM_OK) return SVA_INTERNAL_VIDEO_DECODER_ERROR; + mmError = sva_MM_GetBlockSystemAddress(paramInOutBlockId, ¶mInOutAddress); + if (mmError!=SVA_MM_OK) return SVA_INTERNAL_VIDEO_DECODER_ERROR; + VC1Desc[instanceNum].paramInOutAddress = paramInOutAddress; + VC1Desc[instanceNum].paramInOutBlockId = paramInOutBlockId; + + /* alloc fake buffer and push it in the fifo */ + for(i=0;iconfHandle.currentConf; + t_sva_vc1_SetHeaderInfosParam *pSetVC1HeaderInfosParams = &vc1HeaderInfosParam[instanceNum]; + //t_sva_error algoError; + t_sva_video_decoder_algo_vc1_header_infos *pVc1HeaderInfos; + t_sva_bitstream_desc bitstreamDesc; + t_sva_buffer_status bufferStatus; + t_physical_address bufferStartAddr; + t_sva_error svaError; + t_sva_ff_error ffError; + t_sva_bm_error bmError; + t_sva_vc1_reference_handler referenceHandler; + + HCL_ASSERT(pHeaderInfos!=NULL); + + // check whether the current picture type is supported + // Fw v3.1.3.7 supports types : I,P,BI and skipped + pVc1HeaderInfos=(t_sva_video_decoder_algo_vc1_header_infos *)(pHeaderInfos); + //if (pVc1HeaderInfos->pictureCodingType == PICTURE_TYPE_B) return SVA_NOT_SUPPORTED_YET; + + switch(pConf->mode) { + case SVA_CODEC_IMAGE_MODE : + + //check that buffer is already pushed: ie is in "sva_BUFFER_IN_USE" state + svaError=SVA_GetBufferStatus(bitstreamBuffer,&bufferStatus); + if (svaError != SVA_OK) {return SVA_UNEXPECTED_API_CALL; } + + HCL_DEBUG_ASSERT(bufferStatus.state == SVA_BUFFER_IN_USE); + if (bufferStatus.state != SVA_BUFFER_IN_USE) { return SVA_UNEXPECTED_API_CALL; } + + // get the type of the frame to handle references + pVc1HeaderInfos=(t_sva_video_decoder_algo_vc1_header_infos *)(pHeaderInfos); + + referenceHandler.bitstreamBuffer = bitstreamBuffer; + referenceHandler.fwdReferenceImage = INVALID_BUFFER_ID; // both fwd and bwd ref will be set up when resolving dependencies + referenceHandler.bwdReferenceImage = INVALID_BUFFER_ID; + referenceHandler.pictureType = pVc1HeaderInfos->pictureCodingType; + ffError=PUSH_FIFO_ELEM(VC1Desc[instanceNum].referenceHandlerFifo, t_sva_vc1_reference_handler, referenceHandler); + if (ffError!= SVA_FIFO_OK) {return SVA_INTERNAL_FIFOS_FULL;} + + bmError=sva_BM_GetBufferPhysicalAddress(bitstreamBuffer,&bufferStartAddr); + if (bmError != SVA_BM_OK) {return SVA_UNEXPECTED_API_CALL; } + + //Store Pic Layer params in fifo + ffError=PUSH_FIFO_ELEM(VC1Desc[instanceNum].picLayerParamsFifo,t_sva_video_decoder_algo_vc1_header_infos,*pVc1HeaderInfos); + if (ffError!= SVA_FIFO_OK) {return SVA_INTERNAL_FIFOS_FULL;} + + /*Store bitstream position in fifoBitstream*/ + //This field will be setted in sva_DC_TryToInitBitstreamFields as decode module manages bitstrem buffer list + bitstreamDesc.bitstreamPosition.addr_bitstream_buf_struct= 0;//address of bitstream buffer list will be updated by ResolveDependancies() (should be multiple of 16) + bitstreamDesc.bitstreamPosition.addr_bitstream_start= ((byteOffset >> 4) <<4) + bufferStartAddr; //in bytes (Should be aligned on 16 bytes + absolute address) + bitstreamDesc.bitstreamPosition.bitstream_offset= (byteOffset - ((byteOffset >> 4) <<4)) * 8 + bitOffset; //Is the offset in bits between aligned address and provided no aligned address in byte + user offset + bitstreamDesc.relatedBufferId=bitstreamBuffer; + ffError=PUSH_FIFO_ELEM(VC1Desc[instanceNum].fifoBitstream,t_sva_bitstream_desc,bitstreamDesc); + if (ffError!= SVA_FIFO_OK) {return SVA_INTERNAL_FIFOS_FULL;} + + break; + + case SVA_CODEC_SEGMENTED_MODE : + case SVA_CODEC_STREAM_MODE : + + if (pSetVC1HeaderInfosParams->bitstreamBuffer != INVALID_BUFFER_ID) { + if ( (IS_FIFO_FULL(pDesc->lastPushedBufferFifo.push) == TRUE) || + (IS_FIFO_FULL(VC1Desc[instanceNum].referenceHandlerFifo) == TRUE) || + (IS_FIFO_FULL(VC1Desc[instanceNum].picLayerParamsFifo) == TRUE) || + (IS_FIFO_FULL(VC1Desc[instanceNum].fifoBitstream) == TRUE)) + return SVA_INTERNAL_FIFOS_FULL; // check all fifos. ask for a retry if needed + + PUSH_FIFO_ELEM(pDesc->lastPushedBufferFifo.push,t_sva_buffer_id,bitstreamBuffer); + + //check that buffer is already pushed: ie is in "sva_BUFFER_IN_USE" state + svaError=SVA_GetBufferStatus(pSetVC1HeaderInfosParams->bitstreamBuffer,&bufferStatus); + if (svaError != SVA_OK) {return SVA_UNEXPECTED_API_CALL; } + + if (bufferStatus.state != SVA_BUFFER_IN_USE) { return SVA_UNEXPECTED_API_CALL; } + + pVc1HeaderInfos = &pSetVC1HeaderInfosParams->headerInfos; + + bmError=sva_BM_GetBufferPhysicalAddress(pSetVC1HeaderInfosParams->bitstreamBuffer,&bufferStartAddr); + if (bmError != SVA_BM_OK) {return SVA_UNEXPECTED_API_CALL; } + + // get the type of the frame to handle references + referenceHandler.bitstreamBuffer = pSetVC1HeaderInfosParams->bitstreamBuffer; + referenceHandler.fwdReferenceImage = INVALID_BUFFER_ID; // both fwd and bwd ref will be set up when resolving dependencies + referenceHandler.bwdReferenceImage = INVALID_BUFFER_ID; + referenceHandler.pictureType = pVc1HeaderInfos->pictureCodingType; + PUSH_FIFO_ELEM(VC1Desc[instanceNum].referenceHandlerFifo, t_sva_vc1_reference_handler, referenceHandler); + + //Store Pic Layer params in fifo + PUSH_FIFO_ELEM(VC1Desc[instanceNum].picLayerParamsFifo,t_sva_video_decoder_algo_vc1_header_infos,*pVc1HeaderInfos); + + /*Store bitstream position in fifoBitstream*/ + //This field will be setted in sva_DC_TryToInitBitstreamFields as decode module manages bitstrem buffer list + bitstreamDesc.bitstreamPosition.addr_bitstream_buf_struct= 0;//address of bitstream buffer list will be updated by ResolveDependancies() (should be multiple of 16) + bitstreamDesc.bitstreamPosition.addr_bitstream_start= ((pSetVC1HeaderInfosParams->byteOffset >> 4) <<4) + bufferStartAddr; //in bytes (Should be aligned on 16 bytes + absolute address) + bitstreamDesc.bitstreamPosition.bitstream_offset= (pSetVC1HeaderInfosParams->byteOffset - ((pSetVC1HeaderInfosParams->byteOffset >> 4) <<4)) * 8 + pSetVC1HeaderInfosParams->bitOffset; //Is the offset in bits between aligned address and provided no aligned address in byte + user offset + bitstreamDesc.relatedBufferId=pSetVC1HeaderInfosParams->bitstreamBuffer; + PUSH_FIFO_ELEM(VC1Desc[instanceNum].fifoBitstream,t_sva_bitstream_desc,bitstreamDesc); + } + + + // stack up current parameters to be used at the end of the frame (next call of sva_DC_SetHeaderInfos) + pSetVC1HeaderInfosParams->serviceId = serviceId; + pSetVC1HeaderInfosParams->bitstreamBuffer = bitstreamBuffer; + pSetVC1HeaderInfosParams->byteOffset = byteOffset; + pSetVC1HeaderInfosParams->bitOffset = bitOffset; + pVc1HeaderInfos = (t_sva_video_decoder_algo_vc1_header_infos*)pHeaderInfos; + pSetVC1HeaderInfosParams->headerInfos = *pVc1HeaderInfos; + + break; + + default : + return SVA_INTERNAL_VIDEO_DECODER_ERROR; + // break; PCLint warning removal ... + } + + return SVA_OK; + +} + + +/****************************************************************************/ +/* NAME: sva_DC_VC1_AssertEndOfBitstream() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: Assert the immediate end of bitstream. Leads to a */ +/* non-delayed setHeaderInfos execution */ +/* */ +/* PARAMETERS: */ +/* IN : t_sva_service_id serviceId */ +/* OUT :none */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/* - SVA_OK : Last subtask sucessfully lined up. */ +/* - SVA_INTERNAL_VIDEO_DECODER_ERROR : Error */ +/****************************************************************************/ +PUBLIC t_sva_error sva_DC_VC1_AssertEndOfBitstream(t_sva_service_instance_num instanceNum, t_sva_service_id serviceId) +{ + t_sva_dc_descriptor *pDesc=&decodeDesc[instanceNum]; + t_sva_video_decoder_configuration *pConf=&pDesc->confHandle.currentConf; + t_sva_vc1_SetHeaderInfosParam *pSetVC1HeaderInfosParams = &vc1HeaderInfosParam[instanceNum]; + t_sva_video_decoder_algo_vc1_header_infos *pVc1HeaderInfos; + t_sva_bitstream_desc bitstreamDesc; + t_sva_buffer_status bufferStatus; + t_physical_address bufferStartAddr; + t_sva_ff_error ffError; + t_sva_error svaError; + t_sva_bm_error bmError; + t_sva_vc1_reference_handler referenceHandler; + + switch(pConf->mode) { + case SVA_CODEC_IMAGE_MODE : + + return SVA_OK; // nothing to do in Image mode - End of bitstream trigerred by SetHeaderInfos + + case SVA_CODEC_SEGMENTED_MODE : + case SVA_CODEC_STREAM_MODE : + + //check that transition is allowed + if (sva_DC_isTransitionValid(instanceNum,SVA_DC_PUSH)==FALSE) {return SVA_UNEXPECTED_API_CALL;} + + // trigger the execution of the last SetHeaderInfos + if (pSetVC1HeaderInfosParams->bitstreamBuffer != INVALID_BUFFER_ID) { + // valid buffer ID means this is not the first call to SVA_SetHeaderInfos : process here + // last call parameters + + //check that buffer is already pushed: ie is in "sva_BUFFER_IN_USE" state + svaError=SVA_GetBufferStatus(pSetVC1HeaderInfosParams->bitstreamBuffer,&bufferStatus); + if (svaError != SVA_OK) {return SVA_UNEXPECTED_API_CALL; } + + HCL_DEBUG_ASSERT(bufferStatus.state == SVA_BUFFER_IN_USE); + if (bufferStatus.state != SVA_BUFFER_IN_USE) { return SVA_UNEXPECTED_API_CALL; } + + pVc1HeaderInfos = &pSetVC1HeaderInfosParams->headerInfos; + + bmError=sva_BM_GetBufferPhysicalAddress(pSetVC1HeaderInfosParams->bitstreamBuffer,&bufferStartAddr); + if (bmError != SVA_BM_OK) {return SVA_UNEXPECTED_API_CALL; } + + // get the type of the frame to handle references + referenceHandler.bitstreamBuffer = pSetVC1HeaderInfosParams->bitstreamBuffer; + referenceHandler.fwdReferenceImage = INVALID_BUFFER_ID; // both fwd and bwd ref will be set up when resolving dependencies + referenceHandler.bwdReferenceImage = INVALID_BUFFER_ID; + referenceHandler.pictureType = pVc1HeaderInfos->pictureCodingType; + ffError=PUSH_FIFO_ELEM(VC1Desc[instanceNum].referenceHandlerFifo, t_sva_vc1_reference_handler, referenceHandler); + if (ffError!= SVA_FIFO_OK) {return SVA_INTERNAL_FIFOS_FULL;} + + //Store Pic Layer params in fifo fifoDynamicParams + ffError=PUSH_FIFO_ELEM(VC1Desc[instanceNum].picLayerParamsFifo,t_sva_video_decoder_algo_vc1_header_infos,*pVc1HeaderInfos); + if (ffError!= SVA_FIFO_OK) {return SVA_INTERNAL_FIFOS_FULL;} + + /*Store bitstream position in fifoBitstream*/ + //This field will be setted in sva_DC_TryToInitBitstreamFields as decode module manages bitstrem buffer list + bitstreamDesc.bitstreamPosition.addr_bitstream_buf_struct= 0;//address of bitstream buffer list will be updated by ResolveDependancies() (should be multiple of 16) + bitstreamDesc.bitstreamPosition.addr_bitstream_start= ((pSetVC1HeaderInfosParams->byteOffset >> 4) <<4) + bufferStartAddr; //in bytes (Should be aligned on 16 bytes + absolute address) + bitstreamDesc.bitstreamPosition.bitstream_offset= (pSetVC1HeaderInfosParams->byteOffset - ((pSetVC1HeaderInfosParams->byteOffset >> 4) <<4)) * 8 + pSetVC1HeaderInfosParams->bitOffset; //Is the offset in bits between aligned address and provided no aligned address in byte + user offset + bitstreamDesc.relatedBufferId=pSetVC1HeaderInfosParams->bitstreamBuffer; + ffError=PUSH_FIFO_ELEM(VC1Desc[instanceNum].fifoBitstream,t_sva_bitstream_desc,bitstreamDesc); + if (ffError!= SVA_FIFO_OK) {return SVA_INTERNAL_FIFOS_FULL;} + + sva_DC_UpdateInstanceStateMachine(instanceNum,SVA_DC_PUSH); + + } else return SVA_INTERNAL_VIDEO_DECODER_ERROR; + + break; + + default : + return SVA_INTERNAL_VIDEO_DECODER_ERROR; + //break; PCLint warning removal ... + } + + return SVA_OK; + +} + + + + + +/****************************************************************************/ +/* NAME: sva_DC_VC1_GetOutputParamsSize() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: This routine enables user to know the size of Paramout */ +/* structure: depends on algo used (and FW release) */ +/* PARAMETERS: */ +/* IN : t_sva_service_instance_num instanceNum */ +/* OUT : */ +/* */ +/* RETURN: */ +/* size in byte */ +/*--------------------------------------------------------------------------*/ +/* USE: NA */ +/* USED BY: NA */ +/****************************************************************************/ +PUBLIC t_size sva_DC_VC1_GetOutputParamsSize( + t_sva_service_instance_num instanceNum + ) +{ + (void) instanceNum;/*discard instanceNum*/ + + return (sizeof(t_sva_vdc_vc1_param_out)); +} + + + +/****************************************************************************/ +/* NAME: sva_DC_VC1_SetOutputParams() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: This routine enables to synthetize all infos provided by */ +/* a subtask through the paramout field */ +/* Called when EOT,It computes paramout data and stores results*/ +/* in a global variable */ +/* PARAMETERS: */ +/* IN : t_sva_service_instance_num instanceNum */ +/* OUT :t_bool *infosAvailable */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/*--------------------------------------------------------------------------*/ +/* USE: NA */ +/* USED BY: NA */ +/****************************************************************************/ +PUBLIC t_sva_error sva_DC_VC1_SetOutputParams( + t_sva_service_instance_num instanceNum, + const t_sva_dc_algo_params_out *algoParamsOutAddr + ) +{ + HCL_ASSERT(algoParamsOutAddr!=NULL); + + return SVA_OK; +} + + + + +/****************************************************************************/ +/* NAME: sva_DC_VC1_GetStatus() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: This routine gives access to VC1Desc[instanceNum].VC1ParamOut*/ +/* global */ +/* This is called inside sva_DC_Status() */ +/* PARAMETERS: */ +/* IN : t_sva_service_instance_num instanceNum */ +/* OUT :t_sva_dc_algo_status * */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/*--------------------------------------------------------------------------*/ +/* USE: NA */ +/* USED BY: NA */ +/****************************************************************************/ +t_sva_error sva_DC_VC1_GetStatus ( + t_sva_service_instance_num instanceNum, + t_sva_dc_algo_status *lastFrameAlgoStatus, + t_sva_dc_algo_status *statisticalAlgoStatus ) +{ + t_sva_vdc_vc1_param_out *plastFrameVC1ParamOut; + t_sva_vdc_vc1_param_out *pstatisticalVC1ParamOut; + + HCL_ASSERT(lastFrameAlgoStatus!=NULL); + HCL_ASSERT(statisticalAlgoStatus!=NULL); + + plastFrameVC1ParamOut=(t_sva_vdc_vc1_param_out *)lastFrameAlgoStatus; + pstatisticalVC1ParamOut=(t_sva_vdc_vc1_param_out *)statisticalAlgoStatus; + + *plastFrameVC1ParamOut=VC1Desc[instanceNum].lastFrameVC1ParamOut; + *pstatisticalVC1ParamOut=VC1Desc[instanceNum].statisticalVC1ParamOut; + + return SVA_OK; +} + + +/****************************************************************************/ +/* NAME: sva_DC_VC1_FlushFifos() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: This routine enables to flush both VC1 fifos related to SC */ +/* and header */ +/* */ +/* PARAMETERS: */ +/* IN : t_sva_service_instance_num instanceNum */ +/* OUT : */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/*--------------------------------------------------------------------------*/ +/* USE: NA */ +/* USED BY: NA */ +/****************************************************************************/ +t_sva_error sva_DC_VC1_FlushFifos (t_sva_service_instance_num instanceNum) { + + t_sva_dc_descriptor *pDesc=&decodeDesc[instanceNum]; + t_sva_vc1_desc *pVC1Desc = &VC1Desc[instanceNum]; + t_sva_dc_subtask_dependencies subtaskDep; + t_sva_dc_vc1_dependencies_desc vc1Dep; + t_sva_buffer_id bufferId; + t_uint32 systemTime; + t_sva_error svaError; + t_sva_tm_error tmError; + t_sva_ff_error ffError; + t_sva_bm_error bmError; + t_uint32 i; + + // flush all scheduled subtasks + do { + tmError=sva_TM_RemoveElemFromSubTaskList(pDesc->subtasksListId,&subtaskDep.subtaskId); + } while (tmError==SVA_TM_OK); + + // flush dependencies + while(POP_FIFO_ELEM(pDesc->subtasksDependencyFifo.inUse,t_sva_dc_subtask_dependencies,subtaskDep) != SVA_FIFO_EMPTY); + while(POP_FIFO_ELEM(pDesc->subtasksDependencyFifo.push,t_sva_dc_subtask_dependencies,subtaskDep) != SVA_FIFO_EMPTY); + while(POP_FIFO_ELEM(pVC1Desc->vc1Dep.inUse,t_sva_dc_vc1_dependencies_desc,vc1Dep) != SVA_FIFO_EMPTY); + while(POP_FIFO_ELEM(pVC1Desc->vc1Dep.push,t_sva_dc_vc1_dependencies_desc,vc1Dep) != SVA_FIFO_EMPTY); + + /* Push back reset subtaskdeps in the .push fifos */ + for(i=0;isubtasksIdArray[i]; + subtaskDep.bitstreamBufferListId=pDesc->bufferListIdArray[i][0]; + subtaskDep.dependencies=pDesc->defaultDep; + vc1Dep = pVC1Desc->defaultDep; + ffError=PUSH_FIFO_ELEM(pDesc->subtasksDependencyFifo.push, t_sva_dc_subtask_dependencies, subtaskDep); + if (ffError!=SVA_FIFO_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + ffError=PUSH_FIFO_ELEM(pVC1Desc->vc1Dep.push, t_sva_dc_vc1_dependencies_desc, vc1Dep); + if (ffError!=SVA_FIFO_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + } + + /*get time*/ + svaError=SVA_GetServiceSystemTime(pDesc->serviceId ,&systemTime); + if (svaError != SVA_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + + /************/ + /*flush fifo*/ + /************/ + //fifo outputImageFifo + //-------------------- + while(POP_FIFO_ELEM(pDesc->outputImageFifos.push,t_sva_buffer_id,bufferId) != SVA_FIFO_EMPTY) + { + bmError=sva_BM_UpdateBufferStatus(bufferId,SVA_BUFFER_NOT_USED,systemTime); + if (bmError!=SVA_BM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + } + while(POP_FIFO_ELEM(pDesc->outputImageFifos.inUse,t_sva_buffer_id,bufferId) != SVA_FIFO_EMPTY) + { + bmError=sva_BM_UpdateBufferStatus(bufferId,SVA_BUFFER_NOT_USED,systemTime); + if (bmError!=SVA_BM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + } + + //optional fifos outputDeblockingFifos + //------------------------------------ + if(pDesc->confHandle.currentConf.outTheLoopFilter != SVA_NONE_FILTER) + { + while(POP_FIFO_ELEM(pDesc->outputDeblockingFifos.push,t_sva_buffer_id,bufferId) != SVA_FIFO_EMPTY) + { + bmError=sva_BM_UpdateBufferStatus(bufferId,SVA_BUFFER_NOT_USED,systemTime); + if (bmError!=SVA_BM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + } + while(POP_FIFO_ELEM(pDesc->outputDeblockingFifos.inUse,t_sva_buffer_id,bufferId) != SVA_FIFO_EMPTY) + { + bmError=sva_BM_UpdateBufferStatus(bufferId,SVA_BUFFER_NOT_USED,systemTime); + if (bmError!=SVA_BM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + } + } + //optional fifos outputInfosFifos + //------------------------------- + if(pDesc->confHandle.currentConf.areInfosRequested == TRUE) + { + while(POP_FIFO_ELEM(pDesc->outputInfosFifos.push,t_sva_buffer_id,bufferId) != SVA_FIFO_EMPTY) + { + bmError=sva_BM_UpdateBufferStatus(bufferId,SVA_BUFFER_NOT_USED,systemTime); + if (bmError!=SVA_BM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + } + while(POP_FIFO_ELEM(pDesc->outputInfosFifos.inUse,t_sva_buffer_id,bufferId) != SVA_FIFO_EMPTY) + { + bmError=sva_BM_UpdateBufferStatus(bufferId,SVA_BUFFER_NOT_USED,systemTime); + if (bmError!=SVA_BM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + } + } + //fifos inputBitstreamFifos + //------------------------- + while(POP_FIFO_ELEM(pDesc->inputBitstreamFifos.inUse,t_sva_buffer_id,bufferId) != SVA_FIFO_EMPTY) + { + bmError=sva_BM_UpdateBufferStatus(bufferId,SVA_BUFFER_NOT_USED,systemTime); + if (bmError!=SVA_BM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + } + while(POP_FIFO_ELEM(pDesc->inputBitstreamFifos.push,t_sva_buffer_id,bufferId) != SVA_FIFO_EMPTY) + { + bmError=sva_BM_UpdateBufferStatus(bufferId,SVA_BUFFER_NOT_USED,systemTime); + if (bmError!=SVA_BM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + } + + //internal fifos + //-------------- + FLUSH_FIFO(VC1Desc[instanceNum].picLayerParamsFifo); + FLUSH_FIFO(VC1Desc[instanceNum].fifoBitstream); + FLUSH_FIFO(VC1Desc[instanceNum].referenceHandlerFifo); + FLUSH_FIFO(VC1Desc[instanceNum].refImage); + FLUSH_FIFO(VC1Desc[instanceNum].prevRefImage); + + return SVA_OK; +} + + + + +/****************************************************************************/ +/* NAME: sva_DC_VC1_DeleteFake() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* */ +/* */ +/* PARAMETERS: */ +/* IN : t_sva_service_instance_num instanceNum */ +/* OUT : */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/****************************************************************************/ +t_sva_error sva_DC_VC1_DeleteFake ( + t_sva_service_instance_num instanceNum + ) +{ + + t_sva_ff_error ffError; + t_uint16 i; + t_sva_buffer_id fakeBitstreamBufferId=INVALID_BUFFER_ID; + + for(i=0;i TO BE UPDATED FOR VC1 !! + *pSize=(((height/16)+2)*((width/16)+2)*4+15)&0xFFF0; + } + else *pSize=0; + } + + return SVA_OK; +} + +/****************************************************************************/ +/* NAME: sva_DC_VC1_Push() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* OUT :none */ +/* */ +/* RETURN: */ +/* */ +/****************************************************************************/ +PUBLIC t_sva_error sva_DC_VC1_Push(t_sva_service_instance_num instanceNum, t_sva_buffer_type bufferType, t_sva_buffer_id bufferId) +{ + t_sva_dc_descriptor *pDesc=&decodeDesc[instanceNum]; + t_sva_video_decoder_configuration *pConf=&pDesc->confHandle.currentConf; + t_sva_error status=SVA_OK; + t_sva_bm_error bmError; + t_sva_ff_error ffError; + t_size bufferSize; + t_size minSize=0; + + switch(bufferType) + { + case SVA_PARAMS_BUFFER_TYPE: // NEED TO BE UPDATED FOR VC1 !! + /*compute minimum size of buffer according to current configuration*/ + minSize=((((t_uint32)pConf->imageDesc.height/16)+2) * (((t_uint32)pConf->imageDesc.width/16)+2))*4; + + /*read buffer size*/ + bmError=sva_BM_GetBufferSize(bufferId,&bufferSize); + if (bmError!=SVA_BM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + /*check buffer has enough space*/ + if (bufferSize>=minSize) + { + ffError=PUSH_FIFO_ELEM(pDesc->outputDeblockingFifos.push, t_sva_buffer_id, bufferId); + if (ffError!=SVA_FIFO_OK) {status=SVA_INTERNAL_FIFOS_FULL;} + else {status=SVA_OK;} + } + else {status=SVA_INTERNAL_VIDEO_DECODER_ERROR;} + break; + + case SVA_INFOS_BUFFER_TYPE: + /*compute minimum size of buffer according to current configuration*/ + minSize=sva_DC_VC1_GetOutputParamsSize(instanceNum); + /*read buffer size*/ + bmError=sva_BM_GetBufferSize(bufferId,&bufferSize); + if (bmError!=SVA_BM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + /*check buffer has enough space*/ + if (bufferSize>=minSize) + { + ffError=PUSH_FIFO_ELEM(pDesc->outputInfosFifos.push, t_sva_buffer_id, bufferId); + if (ffError!=SVA_FIFO_OK) {status=SVA_INTERNAL_FIFOS_FULL;} + else {status=SVA_OK;} + } + else {status=SVA_INTERNAL_VIDEO_DECODER_ERROR;} + break; + + case SVA_BITSTREAM_BUFFER_TYPE: + //Store buffer in bitstream buffer fifo + ffError=PUSH_FIFO_ELEM(pDesc->inputBitstreamFifos.push,t_sva_buffer_id,bufferId); + if (ffError!= SVA_FIFO_OK) {return SVA_INTERNAL_FIFOS_FULL;} + //log byte number of compressed data provided by user + bmError=sva_BM_GetBufferSize(bufferId,&bufferSize); + if (bmError!=SVA_BM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + pDesc->status.nbCompressedDataBufferized+=bufferSize; + + break; + + case SVA_IMAGE_BUFFER_TYPE: + /*compute minimum size of buffer according to current configuration*/ + minSize=((((t_uint32)pConf->imageDesc.height * (t_uint32)pConf->imageDesc.width)*3)/2); + /*read buffer size*/ + bmError=sva_BM_GetBufferSize(bufferId,&bufferSize); + if (bmError!=SVA_BM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + /*check buffer has enough space*/ + if (bufferSize>=minSize) + { + ffError=PUSH_FIFO_ELEM(pDesc->outputImageFifos.push, t_sva_buffer_id, bufferId); + if (ffError!=SVA_FIFO_OK) {status=SVA_INTERNAL_FIFOS_FULL;} + else {status=SVA_OK;} + } + else {status=SVA_INTERNAL_VIDEO_DECODER_ERROR;} + break; + + default: + status=SVA_INVALID_BUFFER_TYPE; + break; + } + + return status; +} + + + +/****************************************************************************/ +/* NAME: sva_DC_VC1_DispatchEOT() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* OUT :none */ +/* */ +/* RETURN: */ +/* */ +/****************************************************************************/ +t_sva_error sva_DC_VC1_DispatchEOT( + t_sva_service_instance_num instanceNum, + t_sva_tm_subtask_id subtaskId, + t_sva_event_desc* pEventDesc, + t_sva_service_id serviceId, + t_uint32 eventTimestamp, + t_uint32 eventDate, + t_uint32 *pNbEventsRaised, + t_uint32 maxOfEvent, + t_sva_buffer_list_id bitstreamBufferListId ) +{ + + t_sva_dc_descriptor *pDesc=&decodeDesc[instanceNum]; + t_sva_vc1_desc *pVC1Desc = &VC1Desc[instanceNum]; + t_sva_video_decoder_configuration *pConf=&pDesc->confHandle.currentConf; + t_size size; + t_sva_tm_error tmError; + t_sva_ff_error ffError; + t_logical_address paramOutAddr; + t_sva_vdc_vc1_param_out *paramOut; + t_uint16 errorType; + t_sva_error algoError; + t_sva_blm_error blmError; + t_sva_buffer_id infoBuffer = INVALID_BUFFER_ID; + t_sva_buffer_id outputImageBuffer = INVALID_BUFFER_ID; + t_sva_buffer_id bufferId, lastBufferId; + t_sva_dc_vc1_dependencies_desc vc1Dep; + + + t_uint32 nbEvents = *pNbEventsRaised; + t_sva_event_desc *pEvent; + pEvent = &pEventDesc[nbEvents]; + + + // remove dependencies from the last executed subtask and reset it to defaultDep value + ffError = POP_FIFO_ELEM(pVC1Desc->vc1Dep.inUse, t_sva_dc_vc1_dependencies_desc, vc1Dep); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + vc1Dep = pVC1Desc->defaultDep; + ffError = PUSH_FIFO_ELEM(pVC1Desc->vc1Dep.push, t_sva_dc_vc1_dependencies_desc, vc1Dep); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + + if(pDesc->confHandle.currentConf.areInfosRequested == FALSE) { + paramOutAddr=pDesc->paramOutAddr; //Address of blockId that is intended to contain paramOut + size=sva_DC_VC1_GetOutputParamsSize (instanceNum); + /*transfer paramout to internal block*/ + tmError=sva_TM_GetSubTaskField(subtaskId, SVA_TM_DEC_ADDR_OUT_PARAMETERS,paramOutAddr, + 0, size, FALSE); + HCL_DEBUG_ASSERT(tmError==SVA_TM_OK); + } else { + ffError=POP_FIFO_ELEM(pDesc->outputInfosFifos.inUse,t_sva_buffer_id,infoBuffer); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + //set paramOutAddr + sva_BM_GetBufferLogicalAddress(infoBuffer, ¶mOutAddr); + // get the related image buffer id + ffError=READ_FIFO_ELEM(pDesc->outputImageFifos.inUse,t_sva_buffer_id,bufferId); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + //the buffer is then filled + CHECK_TABLE_OVERFLOW(nbEvents, maxOfEvent, SVA_INTERNAL_VIDEO_DECODER_ERROR); + pEvent->eventId = SVA_EVENT_BUFFER_FILLED; + pEvent->bufferId = infoBuffer; + pEvent->serviceId = serviceId; + pEvent->eventTimestamp = (t_sva_timestamp_value) eventTimestamp; + pEvent->eventDate = (t_sva_timestamp_value) eventDate; + pEvent->extraInfo= bufferId; + pDesc->status.eventStats.filledCounter++; + /*update buffer status*/ + sva_BM_UpdateBufferStatus(pEvent->bufferId,SVA_BUFFER_FILLED,eventTimestamp); + nbEvents++; + + pEvent = &pEventDesc[nbEvents]; + + } + //provide to algo module for computing statistical data + record + algoError=sva_DC_VC1_SetOutputParams(instanceNum, (void *)paramOutAddr); + HCL_DEBUG_ASSERT(algoError == SVA_OK); + //Retrieve corresponding errorType value + algoError=sva_DC_VC1_GetLastErrorType(instanceNum, &errorType); + HCL_DEBUG_ASSERT(algoError == SVA_OK); + + switch (pConf->mode) { + + case SVA_CODEC_IMAGE_MODE : + + //generate inputBitstreamBuffer related events + ffError=POP_FIFO_ELEM(pDesc->inputBitstreamFifos.inUse,t_sva_buffer_id,pEvent->bufferId); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + //the buffer is then voided + CHECK_TABLE_OVERFLOW(nbEvents, maxOfEvent, SVA_INTERNAL_VIDEO_DECODER_ERROR); + pEvent->eventId = SVA_EVENT_BUFFER_VOIDED; + pEvent->serviceId = serviceId; + pEvent->eventTimestamp = (t_sva_timestamp_value) eventTimestamp; + pEvent->eventDate = (t_sva_timestamp_value) eventDate; + pEvent->extraInfo= 0; + pDesc->status.eventStats.voidedCounter++; + /*update buffer status*/ + sva_BM_UpdateBufferStatus(pEvent->bufferId,SVA_BUFFER_VOIDED,eventTimestamp); + nbEvents++; + + pEvent = &pEventDesc[nbEvents]; + + //Flush user bitstream buffer + blmError=sva_BLM_RemoveBufferFromList(bitstreamBufferListId,&bufferId); + HCL_DEBUG_ASSERT(blmError == SVA_BLM_OK); + + + //Flush fake bitstream buffer if any + blmError=sva_BLM_RemoveBufferFromList(bitstreamBufferListId,&bufferId); + HCL_DEBUG_ASSERT(blmError == SVA_BLM_OK); + + //Push fake buffer in its fifo + ffError=PUSH_FIFO_ELEM(VC1Desc[instanceNum].fakeBitstreamFifo,t_sva_buffer_id,bufferId); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + break; + + case SVA_CODEC_SEGMENTED_MODE : + + lastBufferId = INVALID_BUFFER_ID; + POP_FIFO_ELEM(pDesc->lastPushedBufferFifo.inUse,t_sva_buffer_id,lastBufferId); + + //generate inputBitstreamBuffer related events + while(IS_FIFO_EMPTY(pDesc->inputBitstreamFifos.inUse) == FALSE) { + + ffError=READ_FIFO_ELEM(pDesc->inputBitstreamFifos.inUse,t_sva_buffer_id,bufferId); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + + if (bufferId != lastBufferId) { + + ffError=POP_FIFO_ELEM(pDesc->inputBitstreamFifos.inUse,t_sva_buffer_id,bufferId); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + + //Flush all bitstream buffers of the frame + blmError=sva_BLM_RemoveBufferFromList(bitstreamBufferListId,&bufferId); + HCL_DEBUG_ASSERT(blmError==SVA_BLM_OK); + + //the buffer is then voided + CHECK_TABLE_OVERFLOW(nbEvents, maxOfEvent, SVA_INTERNAL_VIDEO_DECODER_ERROR); + pEvent->bufferId = bufferId; + pEvent->eventId = SVA_EVENT_BUFFER_VOIDED; + pEvent->serviceId = serviceId; + pEvent->eventTimestamp = (t_sva_timestamp_value) eventTimestamp; + pEvent->eventDate = (t_sva_timestamp_value) eventDate; + pEvent->extraInfo= 0; + pDesc->status.eventStats.voidedCounter++; + /*update buffer status*/ + sva_BM_UpdateBufferStatus(pEvent->bufferId,SVA_BUFFER_VOIDED,eventTimestamp); + + nbEvents++; + + pEvent = &pEventDesc[nbEvents]; + } + else break; + } + //Flush fake bitstream buffer if any + blmError=sva_BLM_RemoveBufferFromList(bitstreamBufferListId,&bufferId); + HCL_DEBUG_ASSERT(blmError == SVA_BLM_OK); + //Push fake buffer in its fifo + ffError=PUSH_FIFO_ELEM(VC1Desc[instanceNum].fakeBitstreamFifo,t_sva_buffer_id,bufferId); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + + break; + + case SVA_CODEC_STREAM_MODE : + + //generate inputBitstreamBuffer related events + lastBufferId = INVALID_BUFFER_ID; + POP_FIFO_ELEM(pDesc->lastPushedBufferFifo.inUse,t_sva_buffer_id,lastBufferId); + + do { + if (IS_FIFO_EMPTY(pDesc->inputBitstreamFifos.inUse)==TRUE) break; + ffError=POP_FIFO_ELEM(pDesc->inputBitstreamFifos.inUse, t_sva_buffer_id, bufferId); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + + if (bufferId != lastBufferId) { + //the buffer is then voided + CHECK_TABLE_OVERFLOW(nbEvents, maxOfEvent, SVA_INTERNAL_VIDEO_DECODER_ERROR); + pEvent->eventId = SVA_EVENT_BUFFER_VOIDED; + pEvent->bufferId = bufferId; + pEvent->serviceId = serviceId; + pEvent->eventTimestamp = (t_sva_timestamp_value) eventTimestamp; + pEvent->eventDate = (t_sva_timestamp_value) eventDate; + pEvent->extraInfo= 0; + pDesc->status.eventStats.voidedCounter++; + /*update buffer status*/ + sva_BM_UpdateBufferStatus(pEvent->bufferId,SVA_BUFFER_VOIDED,eventTimestamp); + + nbEvents++; + + pEvent = &pEventDesc[nbEvents]; + } + + blmError=sva_BLM_RemoveBufferFromList(bitstreamBufferListId,&bufferId); + HCL_DEBUG_ASSERT(blmError!=SVA_BLM_LIST_EMPTY); + + } while (bufferId != lastBufferId); + + + //Flush fake bitstream buffer if any + blmError=sva_BLM_RemoveBufferFromList(bitstreamBufferListId,&bufferId); + HCL_DEBUG_ASSERT(blmError == SVA_BLM_OK); + + //Push fake buffer in its fifo + ffError=PUSH_FIFO_ELEM(VC1Desc[instanceNum].fakeBitstreamFifo,t_sva_buffer_id,bufferId); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + break; + + default : + return SVA_NOT_SUPPORTED_YET; + /* break; PCLint warning removal ...(unreachable) */ + + } + /*update status descriptor*/ + + if (errorType!=0) + { + pDesc->status.errorId=SVA_DECODER_TASK_PARAMETER_ERROR; + pDesc->status.eventStats.errorCounter++; + } + else {pDesc->status.errorId=SVA_DECODER_NO_ERROR;} + + + ffError=POP_FIFO_ELEM(pDesc->outputImageFifos.inUse,t_sva_buffer_id,outputImageBuffer); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + + paramOut = (t_sva_vdc_vc1_param_out *)paramOutAddr; // read param to know the value of the field picture_type + switch (paramOut->picture_type) + { + case PICTURE_TYPE_I: + case PICTURE_TYPE_P: + if (pVC1Desc->lastPrevRefBuffer != INVALID_BUFFER_ID) + { + CHECK_TABLE_OVERFLOW(nbEvents, maxOfEvent, SVA_INTERNAL_VIDEO_DECODER_ERROR); + pEvent->eventId = SVA_EVENT_BUFFER_FILLED; + pEvent->bufferId= pVC1Desc->lastPrevRefBuffer; + pEvent->serviceId = serviceId; + pEvent->eventTimestamp = (t_sva_timestamp_value) eventTimestamp; + pEvent->eventDate = (t_sva_timestamp_value) eventDate; + pEvent->extraInfo= 0; + pDesc->status.eventStats.filledCounter++; + /*update buffer status*/ + sva_BM_UpdateBufferStatus(pEvent->bufferId,SVA_BUFFER_FILLED,eventTimestamp); + nbEvents++; + pEvent = &pEventDesc[nbEvents]; + + pVC1Desc->lastPrevRefBuffer = INVALID_BUFFER_ID; + } + + if (pVC1Desc->max_b_frames == 0) + { + CHECK_TABLE_OVERFLOW(nbEvents, maxOfEvent, SVA_INTERNAL_VIDEO_DECODER_ERROR); + pEvent->eventId = SVA_EVENT_BUFFER_FILLED_READ_ONLY; + pEvent->bufferId= outputImageBuffer; + pEvent->serviceId = serviceId; + pEvent->eventTimestamp = (t_sva_timestamp_value) eventTimestamp; + pEvent->eventDate = (t_sva_timestamp_value) eventDate; + pEvent->extraInfo= 0; + pDesc->status.eventStats.readOnlyCounter++; + // no status update at this point - buffer stays locked up for HCL use + nbEvents++; + pEvent = &pEventDesc[nbEvents]; + + // No B frames in the stream -> only one reference is kept by the HCL + if (pVC1Desc->lastRefBuffer != INVALID_BUFFER_ID) + { + CHECK_TABLE_OVERFLOW(nbEvents, maxOfEvent, SVA_INTERNAL_VIDEO_DECODER_ERROR); + pEvent->eventId = SVA_EVENT_BUFFER_FILLED; + pEvent->bufferId= pVC1Desc->lastRefBuffer; + pEvent->serviceId = serviceId; + pEvent->eventTimestamp = (t_sva_timestamp_value) eventTimestamp; + pEvent->eventDate = (t_sva_timestamp_value) eventDate; + pEvent->extraInfo= 0; + pDesc->status.eventStats.filledCounter++; + /*update buffer status*/ + sva_BM_UpdateBufferStatus(pEvent->bufferId,SVA_BUFFER_FILLED,eventTimestamp); + nbEvents++; + pEvent = &pEventDesc[nbEvents]; + } + + pVC1Desc->lastPrevRefBuffer = INVALID_BUFFER_ID; + } + else + { + if (pVC1Desc->lastRefBuffer != INVALID_BUFFER_ID) + { + CHECK_TABLE_OVERFLOW(nbEvents, maxOfEvent, SVA_INTERNAL_VIDEO_DECODER_ERROR); + pEvent->eventId = SVA_EVENT_BUFFER_FILLED_READ_ONLY; + pEvent->bufferId= pVC1Desc->lastRefBuffer; + pEvent->serviceId = serviceId; + pEvent->eventTimestamp = (t_sva_timestamp_value) eventTimestamp; + pEvent->eventDate = (t_sva_timestamp_value) eventDate; + pEvent->extraInfo= 0; + pDesc->status.eventStats.readOnlyCounter++; + // no status update at this point - buffer stays locked up for HCL use + nbEvents++; + pEvent = &pEventDesc[nbEvents]; + } + + pVC1Desc->lastPrevRefBuffer = pVC1Desc->lastRefBuffer; + } + + pVC1Desc->lastRefBuffer = outputImageBuffer; + break; + + default: // B, BI or skipped frames are not used as references + CHECK_TABLE_OVERFLOW(nbEvents, maxOfEvent, SVA_INTERNAL_VIDEO_DECODER_ERROR); + pEvent->eventId = SVA_EVENT_BUFFER_FILLED_READ_ONLY; + pEvent->bufferId= outputImageBuffer; + pEvent->serviceId = serviceId; + pEvent->eventTimestamp = (t_sva_timestamp_value) eventTimestamp; + pEvent->eventDate = (t_sva_timestamp_value) eventDate; + pEvent->extraInfo= 0; + pDesc->status.eventStats.readOnlyCounter++; + // no status update at this point - buffer stays locked up for HCL use + nbEvents++; + pEvent = &pEventDesc[nbEvents]; + + CHECK_TABLE_OVERFLOW(nbEvents, maxOfEvent, SVA_INTERNAL_VIDEO_DECODER_ERROR); + pEvent->eventId = SVA_EVENT_BUFFER_FILLED; + pEvent->bufferId= outputImageBuffer; + pEvent->serviceId = serviceId; + pEvent->eventTimestamp = (t_sva_timestamp_value) eventTimestamp; + pEvent->eventDate = (t_sva_timestamp_value) eventDate; + pEvent->extraInfo= 0; + pDesc->status.eventStats.filledCounter++; + /*update buffer status*/ + sva_BM_UpdateBufferStatus(pEvent->bufferId,SVA_BUFFER_FILLED,eventTimestamp); + nbEvents++; + pEvent = &pEventDesc[nbEvents]; + } + + pDesc->status.nbImagesDecoded++; + + //deblocking buffer : HV_EVENT_BUFFER_FILLED + if(pDesc->confHandle.currentConf.outTheLoopFilter != SVA_NONE_FILTER) + { + ffError=POP_FIFO_ELEM(pDesc->outputDeblockingFifos.inUse,t_sva_buffer_id,pEvent->bufferId); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + //the buffer is then voided + CHECK_TABLE_OVERFLOW(nbEvents, maxOfEvent, SVA_INTERNAL_VIDEO_DECODER_ERROR); + pEvent->eventId = SVA_EVENT_BUFFER_FILLED; + pEvent->serviceId = serviceId; + pEvent->eventTimestamp = (t_sva_timestamp_value) eventTimestamp; + pEvent->eventDate = (t_sva_timestamp_value) eventDate; + pEvent->extraInfo= 0; + pDesc->status.eventStats.filledCounter++; + /*update buffer status*/ + sva_BM_UpdateBufferStatus(pEvent->bufferId,SVA_BUFFER_FILLED,eventTimestamp); + + nbEvents++; + + pEvent = &pEventDesc[nbEvents]; + } + + + *pNbEventsRaised=nbEvents; + + return SVA_OK; + +} + + + + + +/****************************************************************************/ +/* NAME: sva_DC_VC1_FlushBitstreams() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* OUT :none */ +/* */ +/* RETURN: */ +/* */ +/****************************************************************************/ +t_sva_error sva_DC_VC1_FlushBitstreams(t_sva_service_instance_num instanceNum) +{ + + t_uint16 i=0; + t_sva_dc_descriptor *pDesc=&decodeDesc[instanceNum]; + t_sva_buffer_id bufferId; + t_sva_blm_error blmError; + t_sva_ff_error ffError; + + + for(i=0;iconfHandle.currentConf.mode) { + + case SVA_CODEC_IMAGE_MODE : + //update user buffer status if any + blmError=sva_BLM_RemoveBufferFromList(pDesc->bufferListIdArray[i][0],&removeBufferId); + if(blmError==SVA_BLM_OK) + { + //Flush fake bitstream buffer if any + blmError=sva_BLM_RemoveBufferFromList(pDesc->bufferListIdArray[i][0],&bufferId); + HCL_DEBUG_ASSERT(blmError == SVA_BLM_OK); + + //Push fake buffer in its fifo + ffError=PUSH_FIFO_ELEM(VC1Desc[instanceNum].fakeBitstreamFifo,t_sva_buffer_id,bufferId); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + + } + break; + + case SVA_CODEC_SEGMENTED_MODE : + case SVA_CODEC_STREAM_MODE : + + // Flush LastPushedBuffer Fifos (push & inUse) + while (IS_FIFO_EMPTY(pDesc->lastPushedBufferFifo.push) == FALSE) { + ffError=POP_FIFO_ELEM(pDesc->lastPushedBufferFifo.push,t_sva_buffer_id,bufferId); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + } + + while (IS_FIFO_EMPTY(pDesc->lastPushedBufferFifo.inUse) == FALSE) { + ffError=POP_FIFO_ELEM(pDesc->lastPushedBufferFifo.inUse,t_sva_buffer_id,bufferId); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + } + + // Flush buffer list for every subtasks + bufferId = INVALID_BUFFER_ID; + do { + blmError=sva_BLM_RemoveBufferFromList(pDesc->bufferListIdArray[i][0],&bufferId); + } while (blmError==SVA_BLM_OK); + + // keep last valid buffer ID in the list because it's a fake buffer in case of mpeg4 + if (bufferId != INVALID_BUFFER_ID) { + ffError=PUSH_FIFO_ELEM(VC1Desc[instanceNum].fakeBitstreamFifo,t_sva_buffer_id,bufferId); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + } + + break; + + default : + return SVA_UNEXPECTED_API_CALL; + } + + } while(blmError == SVA_BLM_OK); + if(blmError != SVA_BLM_LIST_EMPTY) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + + } + + return SVA_OK; +} + + + +/****************************************************************************/ +/* NAME: t_sva_error sva_DC_VC1_ResolveDependencies( */ +/* t_sva_service_instance_num instanceNum */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* */ +/* */ +/* PARAMETERS: */ +/* IN : t_sva_service_instance_num */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: t_sva_error */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_sva_error sva_DC_VC1_ResolveDependencies(t_sva_service_instance_num instanceNum ) +{ + + + t_sva_dc_descriptor *pDesc=&decodeDesc[instanceNum]; + t_sva_vc1_desc *pVC1Desc = &VC1Desc[instanceNum]; + t_bool dependencyNotSolved=FALSE; + t_sva_buffer_id bufferId; + t_sva_buffer_id btBufferId; + t_sva_buffer_id prevRefBuffer = INVALID_BUFFER_ID; + t_sva_buffer_id refBuffer = INVALID_BUFFER_ID; + t_sva_dc_subtask_dependencies subtaskDep; + t_sva_dc_vc1_dependencies_desc vc1Dep; + t_sva_vdc_frame_buffer_in frameBufferIn; + t_sva_vdc_frame_buffer_out frameBufferOut; + t_sva_ff_error ffError; + t_sva_tm_error tmError; + t_sva_dc_error dcError; + t_sva_bm_error bmError; + t_physical_address phyAddr; + t_sva_error svaError; + t_sva_vc1_reference_handler referenceHandler; + + + /*enter loop where we try to solve dep for a maximum of subtasks*/ + while(IS_FIFO_EMPTY(pDesc->subtasksDependencyFifo.push)==FALSE && dependencyNotSolved==FALSE) + { + /*read subtask for which we will try to solve dependencies*/ + ffError=READ_FIFO_ELEM(pDesc->subtasksDependencyFifo.push,t_sva_dc_subtask_dependencies,subtaskDep); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + ffError=READ_FIFO_ELEM(pVC1Desc->vc1Dep.push,t_sva_dc_vc1_dependencies_desc,vc1Dep); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + + /*******************************************/ + /* BITSTREAM Dependency */ + /*******************************************/ + if(subtaskDep.dependencies.inputBitstreamDep==NOT_RESOLVED_DEPENDENCY) //try to resolve bitstream dep. + { + svaError=sva_DC_VC1_TryToInitBitstreamFields(instanceNum,&btBufferId); //Warning: this is a bitstream init and not an update + HCL_DEBUG_ASSERT(svaError==SVA_OK); + + decodeDesc[instanceNum].currentProgrammedBitstreamBuffer=btBufferId; + } + + /*read subtask for which we will try to solve dependencies*/ + ffError=READ_FIFO_ELEM(pDesc->subtasksDependencyFifo.push,t_sva_dc_subtask_dependencies,subtaskDep); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + + /*******************************************/ + /* OUTPUT IMAGE Dependency */ + /*******************************************/ + if( (subtaskDep.dependencies.outputImageDep==NOT_RESOLVED_DEPENDENCY) && //try to resolve image dep. + (subtaskDep.dependencies.inputBitstreamDep==RESOLVED_DEPENDENCY)) + { + if(IS_FIFO_EMPTY(pDesc->outputImageFifos.push)==FALSE) //1 image buffer available => resolve + { + //Transfer elem from outputimage fifo push to inUse + dcError=sva_DC_TransferElemFromFifoToInUseFifo(instanceNum,SVA_IMAGE_BUFFER_TYPE, &bufferId ); + if (dcError!= SVA_DC_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + + //handle reference images + ffError=READ_FIFO_ELEM(pVC1Desc->referenceHandlerFifo,t_sva_vc1_reference_handler, referenceHandler); + if (ffError!= SVA_FIFO_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + switch(referenceHandler.pictureType) { + case PICTURE_TYPE_I : + prevRefBuffer = INVALID_BUFFER_ID; + if ((IS_FIFO_EMPTY(pVC1Desc->refImage) == FALSE) && (IS_FIFO_EMPTY(pVC1Desc->prevRefImage)) == FALSE) { + POP_FIFO_ELEM(pVC1Desc->refImage, t_sva_buffer_id, prevRefBuffer); // ref becomes previous ref + POP_FIFO_ELEM(pVC1Desc->prevRefImage, t_sva_buffer_id, refBuffer); // dummy pop, to keep fifos lined up + } + ffError = PUSH_FIFO_ELEM(pVC1Desc->refImage,t_sva_buffer_id,bufferId); + if (ffError!=SVA_FIFO_OK) return SVA_INTERNAL_FIFOS_FULL; + ffError = PUSH_FIFO_ELEM(pVC1Desc->prevRefImage,t_sva_buffer_id,prevRefBuffer); + if (ffError!=SVA_FIFO_OK) return SVA_INTERNAL_FIFOS_FULL; + break; // outputImage -> reference -> previous reference + + case PICTURE_TYPE_P : // I and P pictures may be used as references + prevRefBuffer = INVALID_BUFFER_ID; + if (IS_FIFO_EMPTY(pVC1Desc->refImage) == FALSE) + READ_FIFO_ELEM(pVC1Desc->refImage, t_sva_buffer_id, prevRefBuffer); + ffError = PUSH_FIFO_ELEM(pVC1Desc->refImage,t_sva_buffer_id,bufferId); + if (ffError!=SVA_FIFO_OK) return SVA_INTERNAL_FIFOS_FULL; + ffError = PUSH_FIFO_ELEM(pVC1Desc->prevRefImage,t_sva_buffer_id,prevRefBuffer); + if (ffError!=SVA_FIFO_OK) return SVA_INTERNAL_FIFOS_FULL; + break; // outputImage -> reference -> previous reference + + default: // other picture types : B, BI, Skipped -> do nothing + break; + } + //update dependancy infos regarding image buffer + ffError=UPDATE_FIFO_ELEM_FIELD(pDesc->subtasksDependencyFifo.push,t_sva_dc_subtask_dependencies,.dependencies.outputImageDep,RESOLVED_DEPENDENCY); + //update subtask to take into account new buffer: update addroutframebuf/dest buffer part field + bmError=sva_BM_GetBufferPhysicalAddress(bufferId,&phyAddr); + HCL_DEBUG_ASSERT(bmError==SVA_BM_OK); + + //Init subtask Field + tmError = sva_TM_GetSubTaskField( subtaskDep.subtaskId, + SVA_TM_DEC_ADDR_OUT_FRAME_BUFFER, + (t_logical_address) &frameBufferOut, + 0, + sizeof(t_sva_vdc_frame_buffer_out), + FALSE); + if (tmError!= SVA_TM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + frameBufferOut.addr_dest_buffer=phyAddr; + tmError=sva_TM_InitSubTaskField( subtaskDep.subtaskId, + SVA_TM_DEC_ADDR_OUT_FRAME_BUFFER, + (t_logical_address) &frameBufferOut, + sizeof(t_sva_vdc_frame_buffer_out)); + if (tmError!= SVA_TM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + } + } + + /*read subtask for which we will try to solve dependencies*/ + ffError=READ_FIFO_ELEM(pDesc->subtasksDependencyFifo.push,t_sva_dc_subtask_dependencies,subtaskDep); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + + /*******************************************/ + /* REFERENCE Dependency */ + /*******************************************/ + if ( (vc1Dep.referenceDep==NOT_RESOLVED_DEPENDENCY) && //try to resolve fwd and bwd ref buffer dep. + (subtaskDep.dependencies.inputBitstreamDep==RESOLVED_DEPENDENCY) && //input bitstr dep must be resolved to know the frame type + (subtaskDep.dependencies.outputImageDep==RESOLVED_DEPENDENCY)) { // image dep should be resolved to use it as a future ref + if(IS_FIFO_EMPTY(pVC1Desc->referenceHandlerFifo)==FALSE) + { + //handle reference images + ffError=POP_FIFO_ELEM(pVC1Desc->referenceHandlerFifo,t_sva_vc1_reference_handler, referenceHandler); + if (ffError!= SVA_FIFO_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + switch(referenceHandler.pictureType) { + case PICTURE_TYPE_I : // use no reference + case PICTURE_TYPE_BI: + frameBufferIn.addr_fwd_ref_buffer=NULL; + frameBufferIn.addr_bwd_ref_buffer=NULL; + break; + + case PICTURE_TYPE_P : // use only a fwd reference + ffError=POP_FIFO_ELEM(pVC1Desc->refImage, t_sva_buffer_id, refBuffer); + if (ffError!= SVA_FIFO_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + bmError=sva_BM_GetBufferPhysicalAddress(refBuffer,&phyAddr); // get the address of the last decoded I- or P- picture + HCL_DEBUG_ASSERT(bmError==SVA_BM_OK); + frameBufferIn.addr_fwd_ref_buffer=phyAddr; // fill out the HAMAC structure with it + ffError=POP_FIFO_ELEM(pVC1Desc->prevRefImage, t_sva_buffer_id, prevRefBuffer); // line up prevRef Fifo with Ref Fifo + if (ffError!= SVA_FIFO_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + frameBufferIn.addr_bwd_ref_buffer=NULL; // no backward ref needed to decode P frames + break; + + case PICTURE_TYPE_B : + ffError=READ_FIFO_ELEM(pVC1Desc->prevRefImage, t_sva_buffer_id, prevRefBuffer); + if (ffError!= SVA_FIFO_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + bmError=sva_BM_GetBufferPhysicalAddress(prevRefBuffer,&phyAddr); // get the address of the previous ref I- or P- picture + HCL_DEBUG_ASSERT(bmError==SVA_BM_OK); + frameBufferIn.addr_fwd_ref_buffer=phyAddr; // fill out the HAMAC structure with it + + ffError=READ_FIFO_ELEM(pVC1Desc->refImage, t_sva_buffer_id, refBuffer); + if (ffError!= SVA_FIFO_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + bmError=sva_BM_GetBufferPhysicalAddress(refBuffer,&phyAddr); // get the address of the last decoded I- or P- picture + HCL_DEBUG_ASSERT(bmError==SVA_BM_OK); + frameBufferIn.addr_bwd_ref_buffer=phyAddr; // to provide the backward reference image + break; + + default: + return SVA_NOT_SUPPORTED_YET; + } + //update dependancy infos regarding image buffer + ffError=UPDATE_FIFO_ELEM_FIELD(pVC1Desc->vc1Dep.push,t_sva_dc_vc1_dependencies_desc,.referenceDep,RESOLVED_DEPENDENCY); + + //update subtask to take into account new buffer: update addroutframebuf/dest buffer part field + tmError=sva_TM_InitSubTaskField( subtaskDep.subtaskId, + SVA_TM_DEC_ADDR_IN_FRAME_BUFFER, + (t_logical_address) &frameBufferIn, + sizeof(t_sva_vdc_frame_buffer_in)); + } + } + + /*******************************************/ + /* DEBLOCKING PARAM Dependency */ + /*******************************************/ + if(vc1Dep.outputDeblockingDep==NOT_RESOLVED_DEPENDENCY) //try to resolve deblocking dep. + { + if(IS_FIFO_EMPTY(pDesc->outputDeblockingFifos.push)==FALSE) //1 deblocking buffer available => resolve + { + //Remove Deblocking buffer from fifo and stores it as bufferId + !! transfer to InUse fifo !! + dcError=sva_DC_TransferElemFromFifoToInUseFifo(instanceNum,SVA_PARAMS_BUFFER_TYPE, &bufferId ); + if (dcError!= SVA_DC_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + + //update dependancy infos regarding image buffer + ffError=UPDATE_FIFO_ELEM_FIELD(pVC1Desc->vc1Dep.push,t_sva_dc_vc1_dependencies_desc,.outputDeblockingDep,RESOLVED_DEPENDENCY); + + //update subtask to take into account new buffer: update addroutframebuf/dest buffer part field + bmError=sva_BM_GetBufferPhysicalAddress(bufferId,&phyAddr); + HCL_DEBUG_ASSERT(bmError==SVA_BM_OK); + + //Init subtask Field + tmError = sva_TM_GetSubTaskField( subtaskDep.subtaskId, + SVA_TM_DEC_ADDR_OUT_FRAME_BUFFER, + (t_logical_address) &frameBufferOut, + 0, + sizeof(t_sva_vdc_frame_buffer_out), + FALSE); + if (tmError!= SVA_TM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + frameBufferOut.addr_deblocking_param_buffer=phyAddr; + tmError=sva_TM_InitSubTaskField( subtaskDep.subtaskId, + SVA_TM_DEC_ADDR_OUT_FRAME_BUFFER, + (t_logical_address) &frameBufferOut, + sizeof(t_sva_vdc_frame_buffer_out)); + if (tmError!= SVA_TM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + } + } + + /*******************************************/ + /* PARAM OUT Dependency */ + /*******************************************/ + if(vc1Dep.outputInfosDep==NOT_RESOLVED_DEPENDENCY) //try to resolve infos dep. + { + if(IS_FIFO_EMPTY(pDesc->outputInfosFifos.push)==FALSE) //1 infos buffer available => resolve + { + //Remove Info buffer from fifo and stores it as bufferId + !! transfer to InUse fifo !! + dcError=sva_DC_TransferElemFromFifoToInUseFifo(instanceNum,SVA_INFOS_BUFFER_TYPE, &bufferId ); + if (dcError!= SVA_DC_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + + //update dependancy infos regarding infos buffer + ffError=UPDATE_FIFO_ELEM_FIELD(pVC1Desc->vc1Dep.push,t_sva_dc_vc1_dependencies_desc,.outputInfosDep,RESOLVED_DEPENDENCY); + + //update subtask to take into account new buffer: update addroutframebuf/dest buffer part field + bmError=sva_BM_GetBufferPhysicalAddress(bufferId,&phyAddr); + HCL_DEBUG_ASSERT(bmError==SVA_BM_OK); + //Warning: in this case, should take into account ext bit + phyAddr=phyAddr+EXTERNAL_MEM_EXT_BIT; + + //Update subtask Field by address for paramout buffer + tmError=sva_TM_UpdateSubTaskField( SVA_TM_INTERMEDIATE_FIELD_TO_UPDATE, + subtaskDep.subtaskId, + SVA_TM_DEC_ADDR_OUT_PARAMETERS, + FCMD_NEW_ADDRESS, + phyAddr, + 0, + 0); + if (tmError!= SVA_TM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + } + } + + + + + //Are all subtask dep resolved? + //----------------------------- + ffError = READ_FIFO_ELEM(decodeDesc[instanceNum].subtasksDependencyFifo.push,t_sva_dc_subtask_dependencies,subtaskDep);//update infosDep + ffError = READ_FIFO_ELEM(VC1Desc[instanceNum].vc1Dep.push,t_sva_dc_vc1_dependencies_desc,vc1Dep); + + if(sva_DC_VC1_AreAllDependanciesResolved(subtaskDep.dependencies, vc1Dep)==TRUE) + { + t_sva_tm_timestamp immediateTimeStamp={SVA_TM_IMMEDIATE,0}; + + /*pop subtask from list of subtask for which dep has to be solved*/ + ffError=POP_FIFO_ELEM(pDesc->subtasksDependencyFifo.push,t_sva_dc_subtask_dependencies,subtaskDep); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + ffError=PUSH_FIFO_ELEM(pDesc->subtasksDependencyFifo.inUse,t_sva_dc_subtask_dependencies,subtaskDep); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + + ffError=POP_FIFO_ELEM(pVC1Desc->vc1Dep.push,t_sva_dc_vc1_dependencies_desc,vc1Dep); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + ffError=PUSH_FIFO_ELEM(pVC1Desc->vc1Dep.inUse,t_sva_dc_vc1_dependencies_desc,vc1Dep); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + + /*update state machine*/ + sva_DC_UpdateInstanceStateMachine(instanceNum,SVA_DC_ALL_DEPENDENCIES_RESOLVED); + + /*add subtask to list of schedulable subtasks*/ + tmError=sva_TM_AddElemToSubTaskList(pDesc->subtasksListId,subtaskDep.subtaskId,&immediateTimeStamp,1); + HCL_DEBUG_ASSERT(tmError==SVA_TM_OK); + + } + else + { + dependencyNotSolved=TRUE; + } + + } + + + return SVA_OK; +} + + + + +/****************************************************************************/ +/* NAME: t_sva_error sva_DC_VC1_CreateAndConfigSubtasksList( */ +/* t_sva_service_instance_num instanceNum */ +/* t_sva_service_id serviceId */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* create and configure the subtask list */ +/* */ +/* PARAMETERS: */ +/* IN : t_sva_service_instance_num */ +/* t_sva_service_id */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: t_sva_error */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_sva_error sva_DC_VC1_CreateAndConfigSubtasksList(t_sva_service_instance_num instanceNum, t_sva_service_id serviceId) +{ + + t_sva_dc_descriptor *pDesc=&decodeDesc[instanceNum]; + t_sva_vc1_desc *pVC1Desc = &VC1Desc[instanceNum]; + t_sva_video_decoder_configuration *pConf=&pDesc->confHandle.currentConf; + t_sva_tm_task_ctrl_desc decodeTaskDesc; + t_sva_tm_error tmError; + t_sva_blm_error blmError=SVA_BLM_OK; + t_sva_tm_subtask_type subtaskType; + t_sva_tm_postprocessing_type pppType; + t_sva_fw_features fwFeature; + t_uint32 i, j; + t_sva_block_id NewParamOutBlockId; + t_logical_address paramOutAddr; + t_sva_mm_error mmError=SVA_MM_OK; + t_sva_error svaError; + t_sva_vdc_internal_buf internalBuffer; + + t_uint32 nbBufferList=0; + t_size size; + t_sva_error status = SVA_OK; + t_sva_ff_error ffError; + + + svaError=sva_DC_VC1_GetNbBufferListByFrame(&nbBufferList); + HCL_DEBUG_ASSERT(svaError==SVA_OK); + /*create bitstream buffer list*/ + for(i=0;ibufferListIdArray[i][j]); + if (blmError!=SVA_BLM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + } + + } + + /*create subtasks*/ + decodeTaskDesc.memId=DECODE_DEFAULT_MEMORY_ID; + decodeTaskDesc.fieldnb=DECODE_FIELD_NUMBER; + decodeTaskDesc.pfieldctrldesc=(t_sva_tm_field_ctrl_desc *)defaultDecodeFieldDescArray; + + + svaError=sva_DC_VC1_GetPPPType(instanceNum, &pppType); + HCL_DEBUG_ASSERT(svaError==SVA_OK); + + svaError=sva_DC_VC1_GetSubTaskType(instanceNum, &subtaskType); + HCL_DEBUG_ASSERT(svaError==SVA_OK); + + for(i=0;isubtasksIdArray[i]); + + internalBuffer.addr_mv_history_buffer = pVC1Desc->addr_mv_history_buffer.physical; + + tmError=sva_TM_InitSubTaskField(pDesc->subtasksIdArray[i],SVA_TM_DEC_ADDR_INTERNAL_BUFFER,(t_uint32)&internalBuffer,sizeof(t_sva_vdc_internal_buf)); + if (tmError!= SVA_TM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + } + + /*create subtasklist*/ + { + + svaError=sva_DC_VC1_GetFWFeatures(instanceNum, &fwFeature); + HCL_DEBUG_ASSERT(svaError==SVA_OK); + + tmError=sva_TM_CreateSubTaskList(SVA_TM_DECODE,serviceId,fwFeature,&pDesc->subtasksListId); + if (tmError != SVA_TM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + } + + + /*Alloc and push paramout block*/ + size=sva_DC_VC1_GetOutputParamsSize (instanceNum); + sva_MM_AllocBlock(SDRAM_ID, size, SVA_MM_ALIGN_WORD, &NewParamOutBlockId); + ffError=PUSH_FIFO_ELEM(decodeDesc[instanceNum].blockIdFifo,t_sva_block_id,NewParamOutBlockId); + if (ffError!= SVA_FIFO_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + mmError=sva_MM_GetBlockLogicalAddress(NewParamOutBlockId,¶mOutAddr); + if (mmError!= SVA_MM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + decodeDesc[instanceNum].paramOutAddr=paramOutAddr; + + /* reset last used references */ + pVC1Desc->lastRefBuffer = INVALID_BUFFER_ID; + pVC1Desc->lastPrevRefBuffer = INVALID_BUFFER_ID; + + /* Set default common dependencies*/ + pDesc->defaultDep.outputImageDep=NOT_RESOLVED_DEPENDENCY; + pDesc->defaultDep.inputBitstreamDep=NOT_RESOLVED_DEPENDENCY; + /* Set default VC1 dependencies*/ + pVC1Desc->defaultDep.referenceDep=NOT_RESOLVED_DEPENDENCY; + if(pConf->outTheLoopFilter != SVA_NONE_FILTER) + pVC1Desc->defaultDep.outputDeblockingDep=NOT_RESOLVED_DEPENDENCY; + else + pVC1Desc->defaultDep.outputDeblockingDep=INTERNAL_DEPENDENCY; + if(pConf->areInfosRequested == TRUE) + pVC1Desc->defaultDep.outputInfosDep=NOT_RESOLVED_DEPENDENCY; + else + pVC1Desc->defaultDep.outputInfosDep=INTERNAL_DEPENDENCY; + + /* Push subtask in subtasksDependencyFifo since they are ready to be solved*/ + for(i=0;isubtasksIdArray[i]; + subtaskDep.bitstreamBufferListId=pDesc->bufferListIdArray[i][0]; + subtaskDep.dependencies=pDesc->defaultDep; + vc1Dep = pVC1Desc->defaultDep; + + ffError=PUSH_FIFO_ELEM(pDesc->subtasksDependencyFifo.push, t_sva_dc_subtask_dependencies, subtaskDep); + if (ffError!=SVA_FIFO_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + ffError=PUSH_FIFO_ELEM(pVC1Desc->vc1Dep.push, t_sva_dc_vc1_dependencies_desc, vc1Dep); + if (ffError!=SVA_FIFO_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + } + + return status; +} + +/****************************************************************************/ +/* NAME: sva_DC_VC1_AreAllDependanciesResolved() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: This routine enables to check all dependancies related */ +/* to a subtask */ +/* PARAMETERS: */ +/* IN : t_sva_dc_subtask_dependencies subtaskDep : Subtask to check */ +/* OUT :none */ +/* */ +/* RETURN: */ +/* t_bool */ +/*--------------------------------------------------------------------------*/ +/* USE: NA */ +/* USED BY: NA */ +/****************************************************************************/ +PUBLIC t_bool sva_DC_VC1_AreAllDependanciesResolved(t_sva_dc_dependencies_desc commonDep, t_sva_dc_vc1_dependencies_desc vc1Dep) +{ + + if((commonDep.outputImageDep !=NOT_RESOLVED_DEPENDENCY)&& + (vc1Dep.referenceDep !=NOT_RESOLVED_DEPENDENCY)&& + (vc1Dep.outputInfosDep !=NOT_RESOLVED_DEPENDENCY)&& + (commonDep.inputBitstreamDep !=NOT_RESOLVED_DEPENDENCY)&& + (vc1Dep.outputDeblockingDep!=NOT_RESOLVED_DEPENDENCY)) + {return TRUE;} + else {return FALSE;} +} + +/****************************************************************************/ +/* NAME: sva_DC_VC1_CheckInputDep() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: This routine enables to check all input dependancies related*/ +/* to a subtask */ +/* PARAMETERS: */ +/* IN : t_sva_service_instance_num */ +/* OUT :none */ +/* */ +/* RETURN: */ +/* t_bool */ +/*--------------------------------------------------------------------------*/ +/* USE: NA */ +/* USED BY: NA */ +/****************************************************************************/ +PUBLIC t_bool sva_DC_VC1_CheckInputDep(t_sva_service_instance_num instanceNum) { + + t_sva_dc_descriptor *pDesc=&decodeDesc[instanceNum]; + t_bool inputDepResolved; + t_sva_ff_error ffError; + t_sva_dc_subtask_dependencies infosDep; + + ffError = READ_FIFO_ELEM(pDesc->subtasksDependencyFifo.push,t_sva_dc_subtask_dependencies,infosDep); + HCL_ASSERT(ffError == SVA_FIFO_OK); + + if (infosDep.dependencies.inputBitstreamDep == RESOLVED_DEPENDENCY) + inputDepResolved = TRUE; + else + inputDepResolved = FALSE; + + return inputDepResolved; +} + +/****************************************************************************/ +/* NAME: sva_DC_VC1_CheckOutputDep() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: This routine enables to check all output dependancies */ +/* related to a subtask */ +/* PARAMETERS: */ +/* IN : t_sva_service_instance_num */ +/* OUT :none */ +/* */ +/* RETURN: */ +/* t_bool */ +/*--------------------------------------------------------------------------*/ +/* USE: NA */ +/* USED BY: NA */ +/****************************************************************************/ +PUBLIC t_bool sva_DC_VC1_CheckOutputDep(t_sva_service_instance_num instanceNum) { + + t_sva_dc_descriptor *pDesc=&decodeDesc[instanceNum]; + t_sva_dc_subtask_dependencies infosDep; + t_sva_ff_error ffError; + t_bool isOutputDep; + + ffError = READ_FIFO_ELEM(pDesc->subtasksDependencyFifo.push,t_sva_dc_subtask_dependencies,infosDep); + if(ffError != SVA_FIFO_OK) + { + return FALSE; + } + + if (infosDep.dependencies.infosDep == NOT_RESOLVED_DEPENDENCY) + { + return FALSE; + } + + if ((IS_FIFO_EMPTY(pDesc->outputImageFifos.push) == FALSE) || (IS_FIFO_EMPTY(pDesc->outputImageFifos.inUse) == FALSE)) + isOutputDep = TRUE; + else + isOutputDep = FALSE; + + return isOutputDep; +} + +/****************************************************************************/ +/* NAME: sva_DC_VC1_HandleFakeEvent() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: This routine handle the fake event triggered after */ +/* a flush in or out command */ +/* PARAMETERS: */ +/* IN : t_sva_service_instance_num */ +/* OUT :none */ +/* */ +/* RETURN: */ +/* t_bool */ +/*--------------------------------------------------------------------------*/ +/* USE: NA */ +/* USED BY: NA */ +/****************************************************************************/ +PUBLIC t_sva_error sva_DC_VC1_HandleFakeEvent( t_sva_tm_virtual_hw_event_id eventId, + t_sva_service_id serviceId, + t_sva_tm_subtask_id subtaskId, + t_uint32 eventTimestamp, + t_uint32 eventDate, + t_uint8 maxOfEvent, + t_uint32 *pNbEventsRaised, + t_sva_event_desc *pEventDesc) { + + t_sva_service_instance_num instanceNum = READ_INSTANCE_NUM_IN_SERVICE_ID(serviceId); + t_sva_dc_descriptor *pDesc=&decodeDesc[instanceNum]; + t_sva_vc1_desc *pVC1Desc = &VC1Desc[instanceNum]; + t_uint32 nbEvents = *pNbEventsRaised; + + // upon Flush out, free up reference buffers, otherwise keep them. + if (pDesc->state == SVA_DC_FLUSHING_OUT) { + + if (pVC1Desc->lastPrevRefBuffer != INVALID_BUFFER_ID) { + CHECK_TABLE_OVERFLOW(nbEvents, maxOfEvent, SVA_INTERNAL_VIDEO_DECODER_ERROR); + pEventDesc[nbEvents].eventId = SVA_EVENT_BUFFER_FILLED; + pEventDesc[nbEvents].serviceId = serviceId; + pEventDesc[nbEvents].bufferId = pVC1Desc->lastPrevRefBuffer; + pEventDesc[nbEvents].eventTimestamp = (t_sva_timestamp_value) eventTimestamp; + pEventDesc[nbEvents].eventDate = (t_sva_timestamp_value) eventDate; + pEventDesc[nbEvents].extraInfo=0; + pDesc->status.eventStats.filledCounter++; + /*update buffer status*/ + sva_BM_UpdateBufferStatus(pEventDesc[nbEvents].bufferId,SVA_BUFFER_FILLED,eventTimestamp); + nbEvents++; + } + + if (pVC1Desc->lastRefBuffer != INVALID_BUFFER_ID) { + if (pVC1Desc->max_b_frames!=0) + { + CHECK_TABLE_OVERFLOW(nbEvents, maxOfEvent, SVA_INTERNAL_VIDEO_DECODER_ERROR); + pEventDesc[nbEvents].eventId = SVA_EVENT_BUFFER_FILLED_READ_ONLY; + pEventDesc[nbEvents].bufferId= pVC1Desc->lastRefBuffer; + pEventDesc[nbEvents].serviceId = serviceId; + pEventDesc[nbEvents].eventTimestamp = (t_sva_timestamp_value) eventTimestamp; + pEventDesc[nbEvents].eventDate = (t_sva_timestamp_value) eventDate; + pEventDesc[nbEvents].extraInfo= 0; + pDesc->status.eventStats.readOnlyCounter++; + // no status update at this point - buffer stays locked up for HCL use + nbEvents++; + } + + + CHECK_TABLE_OVERFLOW(nbEvents, maxOfEvent, SVA_INTERNAL_VIDEO_DECODER_ERROR); + pEventDesc[nbEvents].eventId = SVA_EVENT_BUFFER_FILLED; + pEventDesc[nbEvents].serviceId = serviceId; + pEventDesc[nbEvents].bufferId = pVC1Desc->lastRefBuffer; + pEventDesc[nbEvents].eventTimestamp = (t_sva_timestamp_value) eventTimestamp; + pEventDesc[nbEvents].eventDate = (t_sva_timestamp_value) eventDate; + pEventDesc[nbEvents].extraInfo=0; + pDesc->status.eventStats.filledCounter++; + /*update buffer status*/ + sva_BM_UpdateBufferStatus(pEventDesc[nbEvents].bufferId,SVA_BUFFER_FILLED,eventTimestamp); + nbEvents++; + } + + // resets reference buffers + pVC1Desc->lastPrevRefBuffer = INVALID_BUFFER_ID; + pVC1Desc->lastRefBuffer = INVALID_BUFFER_ID; + } + + *pNbEventsRaised = nbEvents; + + return SVA_OK; +} + +// End of file - sva_dc_vc1.c --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/vc1/sva_dc_vc1.h @@ -0,0 +1,194 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ + +#ifndef __INC_SVA_DC_VC1_H +#define __INC_SVA_DC_VC1_H + +#include "hcl_defs.h" +#include "sva_decode.h" +#include "../sva_dc_algo.h" +#include "sva.h" + +/******************************************************************************/ +/* Constants definitions */ +/******************************************************************************/ +#define VC1_DECODE_MAX_FIFO_SIZE DECODE_MAX_FIFO_SIZE + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/******************************************************************************/ +/* Types definitions */ +/******************************************************************************/ +typedef enum +{ + MVRANGE_64_32 = 0, /* x=-64 to 63.f by y=-32 to 31.f */ + MVRANGE_128_64 = 1, + MVRANGE_512_128 = 2, + MVRANGE_1024_256 = 3 +} t_sva_vc1_mv_range; + + +/** + * Description: Scaling to be applied to decoded picture before display + */ +typedef enum +{ + PICTURE_RES_1X1=0, /** No scaling */ + PICTURE_RES_2X1, /** Scale horizontally */ + PICTURE_RES_1X2, /** SCALE VERTICALLY */ + PICTURE_RES_2X2 /** Scale horizontally and vertically */ +} t_sva_vc1_picture_resolution; + + +/** + * Description: + * Motion vector mode enumeration + */ + +typedef enum +{ + MVMODE_1MV_HALF_PEL_BILINEAR = 0, /** 1MV 0.50 pel bilinear */ + MVMODE_1MV_HALF_PEL = 1, /** 1MV 0.50 pel bicubic */ + MVMODE_1MV = 2, /** 1MV 0.25 pel bicubic */ + MVMODE_MIXED_MV = 3, /** MixedMV 0.25 pel bicubic */ + MVMODE_INTENSITY_COMPENSATION /** VARIABLE LENGTH CODE escape flag */ +} t_sva_vc1_mv_mode; + + +/***********************************/ +/*** Structure definition ***/ +/***********************************/ +typedef struct { + t_sva_buffer_id bitstreamBuffer; + t_sva_buffer_id fwdReferenceImage; + t_sva_buffer_id bwdReferenceImage; + t_sva_vc1_picture_type pictureType; +} t_sva_vc1_reference_handler; + +typedef struct { + t_sva_service_id serviceId; + t_sva_buffer_id bitstreamBuffer; + t_uint32 byteOffset; + t_uint32 bitOffset; + t_sva_video_decoder_algo_vc1_header_infos headerInfos; +} t_sva_vc1_SetHeaderInfosParam; + + +/* + * Define the structure used to manage the subtasks dependency + */ +typedef struct { + t_sva_dc_dependencies_state referenceDep; + t_sva_dc_dependencies_state outputDeblockingDep; + t_sva_dc_dependencies_state outputInfosDep; +} t_sva_dc_vc1_dependencies_desc; + +/*** VC1Desc ***/ +typedef struct { + t_sva_image_desc imageDesc; + t_sva_codec_mode codecMode; + t_sva_video_decoder_algo_vc1_configuration_params seqLayerParams; + t_sva_fifo picLayerParamsFifo; //type: t_sva_decoder_algo_mpeg4_header_infos + t_sva_fifo fifoBitstream; //type: t_sva_bitstream_desc + t_sva_fifo fakeBitstreamFifo; + t_sva_fifo referenceHandlerFifo; + t_sva_fifo refImage; + t_sva_fifo prevRefImage; + t_uint8 max_b_frames; + t_sva_dc_vc1_dependencies_desc defaultDep; // default vc1 dependencies + t_sva_dc_fifo_dep vc1Dep; + t_sva_vdc_vc1_param_out lastFrameVC1ParamOut; + t_sva_vdc_vc1_param_out statisticalVC1ParamOut; + t_system_address paramInOutAddress; + t_sva_block_id paramInOutBlockId; + t_sva_buffer_id lastRefBuffer; + t_sva_buffer_id lastPrevRefBuffer; + t_system_address addr_mv_history_buffer; + t_sva_buffer_id addr_mv_history_buffer_id; +} t_sva_vc1_desc; + + + +/******************************************************************************/ +/* PUBLIC Functions */ +/******************************************************************************/ +PUBLIC t_sva_error sva_DC_VC1_Init(t_sva_service_instance_num, t_sva_codec_mode, t_sva_image_desc, const t_sva_dc_algo_configuration_params *); +PUBLIC t_sva_error sva_DC_VC1_GetMemoryNeeds(t_sva_service_instance_num, t_size *); + +PUBLIC t_sva_error sva_DC_VC1_ProvideMemoryNeeds( t_sva_service_instance_num ); +PUBLIC t_sva_error sva_DC_VC1_Close(t_sva_service_instance_num); +PUBLIC t_sva_error sva_DC_VC1_GetNextFrameParamsIn(t_sva_service_instance_num, t_sva_dc_algo_params_in *); +PUBLIC t_sva_error sva_DC_VC1_GetNextFrameParamsInOut(t_sva_service_instance_num, t_sva_dc_algo_params_inout *); +PUBLIC t_sva_error sva_DC_VC1_SetOutputParams(t_sva_service_instance_num, const t_sva_dc_algo_params_out *); +PUBLIC t_sva_error sva_DC_VC1_GetNextFrameAddr(t_sva_service_instance_num, t_physical_address *, t_uint32 *, t_sva_buffer_id *); +PUBLIC t_sva_error sva_DC_VC1_GetStatus(t_sva_service_instance_num, t_sva_dc_algo_status *, t_sva_dc_algo_status *); +PUBLIC t_sva_error sva_DC_VC1_AreNextFrameInfosAvailable(t_sva_service_instance_num, t_bool *); +PUBLIC t_size sva_DC_VC1_GetNextFrameParamsInSize(t_sva_service_instance_num); +PUBLIC t_size sva_DC_VC1_GetNextFrameParamsInOutSize(t_sva_service_instance_num); +PUBLIC t_size sva_DC_VC1_GetOutputParamsSize(t_sva_service_instance_num); + +PUBLIC t_sva_error sva_DC_VC1_PushBitstreamBuffer(t_sva_service_instance_num, t_sva_buffer_id); +PUBLIC t_sva_error sva_DC_VC1_GetStartCodeValue(t_uint32 *); +PUBLIC t_sva_error sva_DC_VC1_GetLastErrorType (t_sva_service_instance_num, t_uint16 *); +PUBLIC t_sva_error sva_DC_VC1_FlushFifos(t_sva_service_instance_num); +PUBLIC t_sva_error sva_DC_VC1_DeleteFake(t_sva_service_instance_num); +PUBLIC t_sva_error sva_DC_VC1_SubTaskFieldsFullUpdate ( t_sva_service_instance_num, t_sva_buffer_id *); +PUBLIC t_sva_error sva_DC_VC1_GetParamsBufferSize(t_sva_service_instance_num, t_sva_push_mode, t_sva_filter_mode, t_uint32, t_uint32, t_size *); +PUBLIC t_sva_error sva_DC_VC1_Push(t_sva_service_instance_num, t_sva_buffer_type, t_sva_buffer_id ); +PUBLIC t_sva_error sva_DC_VC1_DispatchEOT( + t_sva_service_instance_num, + t_sva_tm_subtask_id, + t_sva_event_desc*, + t_sva_service_id, + t_uint32, + t_uint32, + t_uint32 *, + t_uint32, + t_sva_buffer_list_id); +PUBLIC t_sva_error sva_DC_VC1_HandleFakeEvent( t_sva_tm_virtual_hw_event_id , + t_sva_service_id , + t_sva_tm_subtask_id , + t_uint32 , + t_uint32 , + t_uint8 , + t_uint32 *, + t_sva_event_desc *); +PUBLIC t_sva_error sva_DC_VC1_TryToInitBitstreamFields(t_sva_service_instance_num, t_sva_buffer_id *); +PUBLIC t_sva_error sva_DC_VC1_FlushBitstreams(t_sva_service_instance_num); +PUBLIC t_sva_error sva_DC_VC1_InitHeaderInfos(t_sva_service_instance_num); +PUBLIC t_sva_error sva_DC_VC1_GSetHeaderInfos(t_sva_service_instance_num, t_sva_service_id, t_sva_buffer_id, t_uint32, t_uint32, const t_sva_header_infos *); +PUBLIC t_sva_error sva_DC_VC1_AssertEndOfBitstream(t_sva_service_instance_num, t_sva_service_id); +PUBLIC t_sva_error sva_DC_VC1_ResolveDependencies(t_sva_service_instance_num); +PUBLIC t_sva_error sva_DC_VC1_GetFWFeatures (t_sva_service_instance_num, t_sva_fw_features*); +PUBLIC t_sva_error sva_DC_VC1_GetSubTaskType(t_sva_service_instance_num, t_sva_tm_subtask_type*); +PUBLIC t_sva_error sva_DC_VC1_GetPPPType(t_sva_service_instance_num, t_sva_tm_postprocessing_type*); +PUBLIC t_sva_error sva_DC_VC1_GetNbBufferListByFrame(t_uint32*); +PUBLIC t_sva_error sva_DC_VC1_CreateAndConfigSubtasksList(t_sva_service_instance_num, t_sva_service_id ); +PUBLIC t_bool sva_DC_VC1_AreAllDependanciesResolved(t_sva_dc_dependencies_desc , t_sva_dc_vc1_dependencies_desc ); +PUBLIC t_bool sva_DC_VC1_CheckInputDep(t_sva_service_instance_num); +PUBLIC t_bool sva_DC_VC1_CheckOutputDep(t_sva_service_instance_num); + +#ifdef __cplusplus +} /* allow C++ to use these headers */ +#endif /* __cplusplus */ + +#endif /* __INC_sva_DC_VC1_H */ +/* End of file - sva_dc_mpeg4.h */ --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/vc1/sva_dc_vc1p.c @@ -0,0 +1,714 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ + + + +/*------------------------------------------------------------------------ + * Includes + *----------------------------------------------------------------------*/ + +#include "hcl_defs.h" +#include "sva_host_interface.h" +#include "sva_memorymgt.h" +#include "sva_buffermgt.h" +#include "sva_fifo.h" + +#include "../sva_decodep.h" +#include "../sva_decodepp.h" +#include "sva_service.h" + +#include "../sva_dc_algo.h" +#include "sva_dc_vc1p.h" +#include "sva_dc_vc1.h" +#include "sva_buffermgtp.h" + +extern PUBLIC t_sva_dc_descriptor decodeDesc[NUM_MAX_DECODE]; +extern PUBLIC t_sva_vc1_desc VC1Desc[NUM_MAX_DECODE]; + +PRIVATE t_sva_vdc_vc1_param_in VC1ParamIn[NUM_MAX_DECODE]; + +/****************************************************************************/ +/* NAME: sva_DC_VC1_GetFWFeatures() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: return the requested fw feature for a VC1 decoder */ +/* PARAMETERS: */ +/* IN : t_sva_service_instance_num instanceNum */ +/* OUT :t_sva_fw_features* pFwFeat */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/*--------------------------------------------------------------------------*/ +/* USE: NA */ +/* USED BY: NA */ +/****************************************************************************/ +PUBLIC t_sva_error sva_DC_VC1_GetFWFeatures (t_sva_service_instance_num instanceNum, t_sva_fw_features* pFwFeat) +{ + + t_sva_fw_features fwFeature; + + fwFeature = SVA_FW_FEAT_WMV9_DECODER; + + *pFwFeat = fwFeature; + + return SVA_OK; + + +} + +/****************************************************************************/ +/* NAME: sva_DC_VC1_GetSubTaskType() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: return the subtask type for VC1 */ +/* PARAMETERS: */ +/* IN : t_sva_service_instance_num instanceNum */ +/* OUT :t_sva_tm_subtask_type* */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/*--------------------------------------------------------------------------*/ +/* USE: NA */ +/* USED BY: NA */ +/****************************************************************************/ +PUBLIC t_sva_error sva_DC_VC1_GetSubTaskType(t_sva_service_instance_num instanceNum, t_sva_tm_subtask_type* pSubTask) +{ + t_sva_dc_descriptor *pDesc=&decodeDesc[instanceNum]; + t_sva_video_decoder_configuration *pConf=&pDesc->confHandle.currentConf; + if(pConf->transformId==SVA_DECODER_VC1_MP_LL) + { + *pSubTask=SVA_TM_DECODE_VC1; + + } + return SVA_OK; + +} + + +/****************************************************************************/ +/* NAME: sva_DC_VC1_GetPPPType() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: return the post processor parameter type */ +/* PARAMETERS: */ +/* IN : t_sva_service_instance_num instanceNum */ +/* OUT :t_sva_tm_postprocessing_type * */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/*--------------------------------------------------------------------------*/ +/* USE: NA */ +/* USED BY: NA */ +/****************************************************************************/ +PUBLIC t_sva_error sva_DC_VC1_GetPPPType(t_sva_service_instance_num instanceNum, t_sva_tm_postprocessing_type* pPostProc) +{ + + t_sva_dc_descriptor *pDesc=&decodeDesc[instanceNum]; + t_sva_video_decoder_configuration *pConf=&pDesc->confHandle.currentConf; + + if (pConf->outTheLoopFilter == SVA_NONE_FILTER) + *pPostProc= SVA_TM_NO_POST_PROCESSING; + else + *pPostProc= SVA_TM_DEBLOCKING_DERINGING_OUT_LOOP; + + return SVA_OK; + +} + + +/****************************************************************************/ +/* NAME: sva_DC_VC1_GetNbBufferListByFrame() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: return the number of buffer list per decode subtask */ +/* PARAMETERS: */ +/* IN : --- */ +/* OUT : constant 1 value */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/*--------------------------------------------------------------------------*/ +/* USE: NA */ +/* USED BY: NA */ +/****************************************************************************/ +PUBLIC t_sva_error sva_DC_VC1_GetNbBufferListByFrame(t_uint32* pNbBUfferList) +{ + * pNbBUfferList = 1; + return SVA_OK; +} + + +/****************************************************************************/ +/* NAME: sva_DC_VC1_GetNextFrameParamsIn() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: This routine provides t_sva_vdc_vc1_param_in data */ +/* that will be used by decode module to update in_param fields*/ +/* PARAMETERS: */ +/* IN : t_sva_service_instance_num instanceNum */ +/* OUT :t_sva_algo_params *algoParamsIn */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/*--------------------------------------------------------------------------*/ +/* USE: NA */ +/* USED BY: NA */ +/****************************************************************************/ +PUBLIC t_sva_error sva_DC_VC1_GetNextFrameParamsIn( + t_sva_service_instance_num instanceNum, + t_sva_dc_algo_params_in *algoParamsIn) +{ + t_sva_ff_error ffError; + t_sva_video_decoder_algo_vc1_header_infos picLayerParams; + t_logical_address * inParameters = (t_logical_address *)algoParamsIn; + + HCL_ASSERT(algoParamsIn!=NULL); + + //Picture Layer param + ffError=POP_FIFO_ELEM(VC1Desc[instanceNum].picLayerParamsFifo,t_sva_video_decoder_algo_vc1_header_infos,picLayerParams); + if (ffError!= SVA_FIFO_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + + VC1ParamIn[instanceNum].frame_size = picLayerParams.frameSize; //32-bit value for FW v3.1.3.7 and above + + //Sequence Layer params + VC1ParamIn[instanceNum].quantizer = (t_sva_param_subfield)VC1Desc[instanceNum].seqLayerParams.quantizer; + VC1ParamIn[instanceNum].dquant = (t_sva_param_subfield)VC1Desc[instanceNum].seqLayerParams.dquant; + VC1ParamIn[instanceNum].extended_mv_enabled = (t_sva_param_subfield)VC1Desc[instanceNum].seqLayerParams.extendedMVEnabled; + VC1ParamIn[instanceNum].frame_interpolation_enabled = (t_sva_param_subfield)VC1Desc[instanceNum].seqLayerParams.frameInterpolationEnabled; + VC1ParamIn[instanceNum].loop_filter_enabled = (t_sva_param_subfield)VC1Desc[instanceNum].seqLayerParams.loopFilterEnabled; + VC1ParamIn[instanceNum].max_b_frames = (t_sva_param_subfield)VC1Desc[instanceNum].seqLayerParams.max_b_frames; + VC1ParamIn[instanceNum].max_picture_height = (t_sva_param_subfield)VC1Desc[instanceNum].imageDesc.height; + VC1ParamIn[instanceNum].max_picture_width = (t_sva_param_subfield)VC1Desc[instanceNum].imageDesc.width; + VC1ParamIn[instanceNum].multires_coding_enabled = (t_sva_param_subfield)VC1Desc[instanceNum].seqLayerParams.multiresCodingEnabled; + VC1ParamIn[instanceNum].overlap_transform_enabled = (t_sva_param_subfield)VC1Desc[instanceNum].seqLayerParams.overlapTransformEnabled; + VC1ParamIn[instanceNum].profile = (t_sva_param_subfield)VC1Desc[instanceNum].seqLayerParams.profile; + VC1ParamIn[instanceNum].rangered_enabled = (t_sva_param_subfield)VC1Desc[instanceNum].seqLayerParams.rangeredEnabled; + VC1ParamIn[instanceNum].syncmarker_enabled = (t_sva_param_subfield)VC1Desc[instanceNum].seqLayerParams.syncmarkerEnabled; + VC1ParamIn[instanceNum].variable_size_transform_enabled = (t_sva_param_subfield)VC1Desc[instanceNum].seqLayerParams.variableSizeTransformEnabled; + VC1ParamIn[instanceNum].fast_uvmc_enabled = (t_sva_param_subfield)VC1Desc[instanceNum].seqLayerParams.fastUvmcEnabled; + VC1ParamIn[instanceNum].is_smpte_conformant = (t_sva_param_subfield)VC1Desc[instanceNum].seqLayerParams.is_smpte_conformant; + VC1ParamIn[instanceNum].overboost = (t_sva_param_subfield)VC1Desc[instanceNum].seqLayerParams.overboost; + VC1ParamIn[instanceNum].simplified_filter = (t_sva_param_subfield)VC1Desc[instanceNum].seqLayerParams.simplified_filter; + + *inParameters = (t_logical_address)(&VC1ParamIn[instanceNum]); + + return SVA_OK; +} + + +/****************************************************************************/ +/* NAME: sva_DC_VC1_GetNextFrameParamsInOut() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: returns the address of the ParamInOut structure */ +/* PARAMETERS: */ +/* IN : t_sva_service_instance_num instanceNum */ +/* OUT :t_sva_algo_params *algoParamsInOut */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/*--------------------------------------------------------------------------*/ +/* USE: NA */ +/* USED BY: NA */ +/****************************************************************************/ +PUBLIC t_sva_error sva_DC_VC1_GetNextFrameParamsInOut( + t_sva_service_instance_num instanceNum, + t_sva_dc_algo_params_inout *algoParamsInOut) +{ + t_logical_address * inOutParameters = (t_logical_address *)algoParamsInOut; + + *inOutParameters = VC1Desc[instanceNum].paramInOutAddress.physical; + + return SVA_OK; +} + + +/****************************************************************************/ +/* NAME: sva_DC_VC1_GetNextFrameAddr() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: This routine provides infos to fill bitstream_buf_position */ +/* subtask subfields */ +/* PARAMETERS: */ +/* IN : t_sva_service_instance_num instanceNum */ +/* OUT :t_physical_address *bitstreamStart */ +/* t_uint32 *bitstreamOffset */ +/* t_sva_buffer_id *bitstreamBufferId */ +/* t_bool *botEnable */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/*--------------------------------------------------------------------------*/ +/* USE: NA */ +/* USED BY: NA */ +/****************************************************************************/ +PUBLIC t_sva_error sva_DC_VC1_GetNextFrameAddr( + t_sva_service_instance_num instanceNum, + t_physical_address *bitstreamStart, + t_uint32 *bitstreamOffset, + t_sva_buffer_id *bitstreamBufferId + ) +{ + t_sva_ff_error ffError; + t_sva_bitstream_desc bitstreamDesc; + + HCL_ASSERT(bitstreamStart!=NULL); + HCL_ASSERT(bitstreamOffset!=NULL); + HCL_ASSERT(bitstreamBufferId!=NULL); + + ffError=POP_FIFO_ELEM(VC1Desc[instanceNum].fifoBitstream,t_sva_bitstream_desc,bitstreamDesc); + if (ffError!= SVA_FIFO_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + + *bitstreamStart = bitstreamDesc.bitstreamPosition.addr_bitstream_start ; //in bytes + Should be aligned on 16 bytes + *bitstreamOffset = bitstreamDesc.bitstreamPosition.bitstream_offset; //Is the offset in bits between aligned address and provided no aligned address in byte + *bitstreamBufferId = bitstreamDesc.relatedBufferId; + + return SVA_OK; +} + + + +/****************************************************************************/ +/* NAME: sva_DC_VC1_AreNextFrameInfosAvailable() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: This routine enables user to have a status on availability */ +/* of Bt buffer and also associated param */ +/* corresponds to FifoBitstream NOT Empty && */ +/* fifoDynamicParams NOT Empty */ +/* PARAMETERS: */ +/* IN : t_sva_service_instance_num instanceNum */ +/* OUT :t_bool *infosAvailable */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/*--------------------------------------------------------------------------*/ +/* USE: NA */ +/* USED BY: NA */ +/****************************************************************************/ +PUBLIC t_sva_error sva_DC_VC1_AreNextFrameInfosAvailable( + t_sva_service_instance_num instanceNum, + t_bool *infosAvailable) +{ + t_bool IsFifoBtEmpty; + t_bool IsPicLayerParamsFifoEmpty; + + HCL_ASSERT(infosAvailable!=NULL); + + IsFifoBtEmpty=(t_bool)IS_FIFO_EMPTY(VC1Desc[instanceNum].fifoBitstream); + IsPicLayerParamsFifoEmpty=(t_bool)IS_FIFO_EMPTY(VC1Desc[instanceNum].picLayerParamsFifo); + + *infosAvailable= (t_bool)!(IsFifoBtEmpty || IsPicLayerParamsFifoEmpty); + + return SVA_OK; +} + + +/****************************************************************************/ +/* NAME: sva_DC_VC1_GetLastErrorType() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: This routine gives the value of the error type of last vc1*/ +/* decode subtask: should be called after sva_DC_VC1_SetOutputParams*/ +/* This is called inside sva_DC_DispatchHWVirtualEvent() */ +/* PARAMETERS: */ +/* OUT :t_uint16 *errorType */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/*--------------------------------------------------------------------------*/ +/* USE: NA */ +/* USED BY: NA */ +/****************************************************************************/ +PUBLIC t_sva_error sva_DC_VC1_GetLastErrorType (t_sva_service_instance_num instanceNum, t_uint16 *pErrorType ) +{ + HCL_ASSERT(pErrorType!=NULL); + + *pErrorType= VC1Desc[instanceNum].lastFrameVC1ParamOut.error_type; + + return SVA_OK; +} + + + +/****************************************************************************/ +/* NAME: sva_DC_VC1_SubTaskFieldsFullUpdate() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: - This routine tries to init ParamIn (algo specific), */ +/* ParamInOut, BitstreamBufInit of subtask in top of dep fifo */ +/* - turns the bitstream dependency flag to RESOLVED_DEPENDENCY*/ +/* PARAMETERS: */ +/* IN : t_uint8 instanceNum */ +/* OUT :none */ +/* */ +/* RETURN: */ +/* t_sva_dc_error */ +/*--------------------------------------------------------------------------*/ +/* USE: NA */ +/* USED BY: NA */ +/****************************************************************************/ +PUBLIC t_sva_error sva_DC_VC1_SubTaskFieldsFullUpdate (t_sva_service_instance_num instanceNum, t_sva_buffer_id *pBitstreamBufferId) +{ + t_sva_blm_error blmError; + t_sva_bitstream_buffer_pos bitstreamPos; + t_physical_address bitstreamBufferStartAddr=0; + t_sva_buffer_id bitstreamBufferId; + t_sva_ff_error ffError=SVA_FIFO_OK; + t_sva_tm_error tmError; + + t_sva_dc_subtask_dependencies subtaskDep; + t_sva_buffer_list_id bitstreamBufferListId; + t_physical_address bitstreamStartAddr; + t_uint32 bitstreamOffset; + + + t_sva_error algoError=SVA_OK; + t_sva_dc_algo_params_in * algoParamsInAddr; + + t_sva_dc_descriptor *pDesc=&decodeDesc[instanceNum]; + + //Find suitable subtask and bitstream buffer list + ffError=READ_FIFO_ELEM(pDesc->subtasksDependencyFifo.push,t_sva_dc_subtask_dependencies,subtaskDep); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + bitstreamBufferListId=subtaskDep.bitstreamBufferListId; + + algoError=sva_DC_VC1_GetNextFrameAddr(instanceNum, &bitstreamStartAddr, &bitstreamOffset, &bitstreamBufferId); + HCL_DEBUG_ASSERT(algoError == SVA_OK); + *pBitstreamBufferId=bitstreamBufferId; + + //Program add_bitstream_buf_struct field of v_bitstream_buf_pos structure + //Warning: there should be at least one buffer in list to ask for list physical address + blmError=sva_BLM_GetBufferListPhysicalAddress (bitstreamBufferListId, &bitstreamBufferStartAddr); + if (blmError!=SVA_BLM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + bitstreamPos.addr_bitstream_buf_struct=bitstreamBufferStartAddr; + bitstreamPos.addr_bitstream_start=bitstreamStartAddr; + bitstreamPos.bitstream_offset=bitstreamOffset; + + //update dependancy infos regarding bitstream buffer(and paramin) + ffError=UPDATE_FIFO_ELEM_FIELD(pDesc->subtasksDependencyFifo.push,t_sva_dc_subtask_dependencies,.dependencies.inputBitstreamDep,RESOLVED_DEPENDENCY); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + + /*update subtask */ + //BITSTREAM part + tmError=sva_TM_UpdateSubTaskField( SVA_TM_INTERMEDIATE_FIELD_TO_UPDATE, + subtaskDep.subtaskId, + SVA_TM_DEC_ADDR_IN_BITSTREAM_BUFFER, + FCMD_COPY, + (t_uint32) &bitstreamPos, + 0, + sizeof(t_sva_bitstream_buffer_pos)); + if (tmError!= SVA_TM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + //IN_PARAMETER part: should be done only one time for each subtask, ie one time as referenced by other subtasks + + + algoError=sva_DC_VC1_GetNextFrameParamsIn(instanceNum, &algoParamsInAddr); + HCL_DEBUG_ASSERT(algoError == SVA_OK); + tmError=sva_TM_UpdateSubTaskField( SVA_TM_INTERMEDIATE_FIELD_TO_UPDATE, + subtaskDep.subtaskId, + SVA_TM_DEC_ADDR_IN_PARAMETERS, + FCMD_COPY, + (t_uint32) algoParamsInAddr, + 0, + sizeof(t_sva_vdc_vc1_param_in)); + if (tmError!= SVA_TM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + + // program both SVA_TM_DEC_ADDR_OUT_FRAME_PARAMETERS and SVA_TM_DEC_ADDR_IN_FRAME_PARAMETERS registers + algoError = sva_DC_VC1_SetupParamInOut(instanceNum, subtaskDep.subtaskId); + HCL_DEBUG_ASSERT(algoError == SVA_OK); + + + return SVA_OK; +} + + +/****************************************************************************/ +/* NAME: sva_DC_VC1_TryToInitBitstreamFields() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: this function prepares the input bitstream buffer list, */ +/* based upon the bitstream mode : FRAME, SEGMENTED or STREAM */ +/* */ +/* PARAMETERS: */ +/* IN : t_uint8 instanceNum, */ +/* t_sva_buffer_id *pBitstreamBufferId */ +/* OUT :none */ +/* */ +/* RETURN: */ +/* t_sva_dc_error */ +/*--------------------------------------------------------------------------*/ +/* USE: NA */ +/* USED BY: NA */ +/****************************************************************************/ +PUBLIC t_sva_error sva_DC_VC1_TryToInitBitstreamFields( + t_uint8 instanceNum, + t_sva_buffer_id *pBitstreamBufferId + ) +{ + t_sva_buffer_id bufferId, lastPushedBufferId; + t_sva_dc_descriptor *pDesc=&decodeDesc[instanceNum]; + t_sva_dc_subtask_dependencies subtaskDep; + t_bool infosAvailable; + + t_sva_ff_error ffError=SVA_FIFO_OK; + t_sva_blm_error blmError; + t_sva_bm_error bmError; + t_sva_dc_error dcError; + + t_sva_error algoError=SVA_OK; + + t_sva_video_decoder_configuration *pConf=&pDesc->confHandle.currentConf; + t_sva_buffer_list_id bitstreamBufferListId; + t_size bufferSize; + + HCL_ASSERT(pBitstreamBufferId!=NULL); + + algoError=sva_DC_VC1_AreNextFrameInfosAvailable(instanceNum,&infosAvailable); + HCL_DEBUG_ASSERT(algoError == SVA_OK); + if(infosAvailable==TRUE) + { + //Find suitable subtask and bitstream buffer list + ffError=READ_FIFO_ELEM(pDesc->subtasksDependencyFifo.push,t_sva_dc_subtask_dependencies,subtaskDep); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + bitstreamBufferListId=subtaskDep.bitstreamBufferListId; + + //Bitstream buffer list management + switch (pConf->mode) { + case SVA_CODEC_IMAGE_MODE : + //Remove Bitstream buffer from fifo "push" and stores it in fifo "inUse" + dcError=sva_DC_TransferElemFromFifoToInUseFifo(instanceNum,SVA_BITSTREAM_BUFFER_TYPE, &bufferId ); + if (dcError!= SVA_DC_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + + //Add bitstream buffer as 1st elem of the list + blmError=sva_BLM_AddBufferInList(bitstreamBufferListId, bufferId); + if (blmError!=SVA_BLM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + + //re-init first link->addr_buffer_start address (refer fw doc), subtracting -48 was leading modification in first address of physical address, VI9780 + { + t_sva_bm_buffer_list_desc *pBufferListInfo; + t_physical_address physicalAddress; + t_sva_bm_list_elem *pBufferInfo; + t_uint32 bufferListIndex; + pBufferListInfo = (t_sva_bm_buffer_list_desc *)(bitstreamBufferListId); + + //((t_sva_bm_buffer_desc*)bufferId)->bufferListInfo[0].bufferLink.addr_buffer_start = ((t_sva_bm_buffer_desc*)bufferId)->bufferSystemAddress.physical; + + if (sva_BM_GetBufferLinkInformation( pBufferListInfo->firstBufferId, &pBufferInfo, &physicalAddress) != SVA_BM_OK) + return(SVA_INTERNAL_VIDEO_DECODER_ERROR); + + if (sva_BLM_GetBufferListIndex(bitstreamBufferListId, pBufferListInfo->firstBufferId, &bufferListIndex) != SVA_BLM_OK) + return SVA_INTERNAL_VIDEO_DECODER_ERROR; + + pBufferInfo[bufferListIndex].bufferLink.addr_buffer_start = ((t_sva_bm_buffer_desc*)pBufferListInfo->firstBufferId)->bufferSystemAddress.physical; + } + //extension of buffer start for ERC (and avoid fake BOW) + //48 bytes, ie 36 bytes aligned 16 to take into account internal bufferisation of SVA + blmError=sva_BLM_UpdateBufferMemoryBoundaryInBufferList (bitstreamBufferListId, BEGIN_OF_FIRST_BUFFER , -48); + if (blmError!=SVA_BLM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + + //add fake buffer (only a Start code) as 2nd element so as ERC could find a resync marker if requiered + //and avoid also fake EOW + ffError=POP_FIFO_ELEM(VC1Desc[instanceNum].fakeBitstreamFifo,t_sva_buffer_id,bufferId); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + blmError=sva_BLM_AddBufferInList(bitstreamBufferListId, bufferId); + if (blmError!=SVA_BLM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + + + algoError = sva_DC_VC1_SubTaskFieldsFullUpdate(instanceNum, pBitstreamBufferId); + HCL_DEBUG_ASSERT(algoError == SVA_OK); + + break; + + case SVA_CODEC_SEGMENTED_MODE : + + lastPushedBufferId = INVALID_BUFFER_ID; + ffError=POP_FIFO_ELEM(pDesc->lastPushedBufferFifo.push,t_sva_buffer_id,lastPushedBufferId); + if (ffError == SVA_FIFO_OK) + PUSH_FIFO_ELEM(pDesc->lastPushedBufferFifo.inUse,t_sva_buffer_id,lastPushedBufferId); + + do { + //Take all Bitstream buffers out of the "push" fifo and stores them into "inUse" fifo + dcError=sva_DC_TransferElemFromFifoToInUseFifo(instanceNum,SVA_BITSTREAM_BUFFER_TYPE, &bufferId ); + if (dcError!= SVA_DC_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + + //Add bitstream buffer as 1st elem of the list + blmError=sva_BLM_AddBufferInList(bitstreamBufferListId, bufferId); + if (blmError!=SVA_BLM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + + ffError = READ_FIFO_ELEM(pDesc->inputBitstreamFifos.push, t_sva_buffer_id, bufferId); + + } while ((bufferId != lastPushedBufferId) && (ffError != SVA_FIFO_EMPTY)); + + //re-init first link->addr_buffer_start address (refer fw doc), subtracting -48 was leading modification in first address of physical address, VI9780 + { + t_sva_bm_buffer_list_desc *pBufferListInfo; + t_physical_address physicalAddress; + t_sva_bm_list_elem *pBufferInfo; + t_uint32 bufferListIndex; + pBufferListInfo = (t_sva_bm_buffer_list_desc *)(bitstreamBufferListId); + + //((t_sva_bm_buffer_desc*)bufferId)->bufferListInfo[0].bufferLink.addr_buffer_start = ((t_sva_bm_buffer_desc*)bufferId)->bufferSystemAddress.physical; + + if (sva_BM_GetBufferLinkInformation( pBufferListInfo->firstBufferId, &pBufferInfo, &physicalAddress) != SVA_BM_OK) + return(SVA_INTERNAL_VIDEO_DECODER_ERROR); + + if (sva_BLM_GetBufferListIndex(bitstreamBufferListId, pBufferListInfo->firstBufferId, &bufferListIndex) != SVA_BLM_OK) + return SVA_INTERNAL_VIDEO_DECODER_ERROR; + + pBufferInfo[bufferListIndex].bufferLink.addr_buffer_start = ((t_sva_bm_buffer_desc*)pBufferListInfo->firstBufferId)->bufferSystemAddress.physical; + } + //extension of buffer start for ERC (and avoid fake BOW) + //48 bytes, ie 36 bytes aligned 16 to take into account internal bufferisation of SVA + //following lines should be removed when starting the buffer list with a fake buffer + blmError=sva_BLM_UpdateBufferMemoryBoundaryInBufferList (bitstreamBufferListId, BEGIN_OF_FIRST_BUFFER , -48); + if (blmError!=SVA_BLM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + + // Append a fake buffer at the end of the list if necessary + ffError=POP_FIFO_ELEM(VC1Desc[instanceNum].fakeBitstreamFifo,t_sva_buffer_id,bufferId); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + blmError=sva_BLM_AddBufferInList(bitstreamBufferListId, bufferId); + if (blmError!=SVA_BLM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + + // program the subtask with all its dependencies + algoError = sva_DC_VC1_SubTaskFieldsFullUpdate(instanceNum, pBitstreamBufferId); + HCL_DEBUG_ASSERT(algoError == SVA_OK); + + break; + + case SVA_CODEC_STREAM_MODE : + + lastPushedBufferId = INVALID_BUFFER_ID; + ffError=POP_FIFO_ELEM(pDesc->lastPushedBufferFifo.push,t_sva_buffer_id,lastPushedBufferId); + if (ffError == SVA_FIFO_OK) + PUSH_FIFO_ELEM(pDesc->lastPushedBufferFifo.inUse,t_sva_buffer_id,lastPushedBufferId); + + do { + // When an end of bitstream occurs, there is no lastPushedBuffer ID available + // -> push all the buffer left to the subtask's buffer list + if (IS_FIFO_EMPTY(pDesc->inputBitstreamFifos.push) == TRUE) break; + // Take Bitstream buffers out of the "push" fifo and stores them into "inUse" fifo + dcError=sva_DC_TransferElemFromFifoToInUseFifo(instanceNum,SVA_BITSTREAM_BUFFER_TYPE, &bufferId ); + if (dcError!= SVA_DC_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + + //Add bitstream buffer in the list + blmError=sva_BLM_AddBufferInList(bitstreamBufferListId, bufferId); + if (blmError!=SVA_BLM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + } while (bufferId != lastPushedBufferId); + + //re-init first link->addr_buffer_start address (refer fw doc), subtracting -48 was leading modification in first address of physical address, VI9780 + { + t_sva_bm_buffer_list_desc *pBufferListInfo; + t_physical_address physicalAddress; + t_sva_bm_list_elem *pBufferInfo; + t_uint32 bufferListIndex; + pBufferListInfo = (t_sva_bm_buffer_list_desc *)(bitstreamBufferListId); + + //((t_sva_bm_buffer_desc*)bufferId)->bufferListInfo[0].bufferLink.addr_buffer_start = ((t_sva_bm_buffer_desc*)bufferId)->bufferSystemAddress.physical; + + if (sva_BM_GetBufferLinkInformation( pBufferListInfo->firstBufferId, &pBufferInfo, &physicalAddress) != SVA_BM_OK) + return(SVA_INTERNAL_VIDEO_DECODER_ERROR); + + if (sva_BLM_GetBufferListIndex(bitstreamBufferListId, pBufferListInfo->firstBufferId, &bufferListIndex) != SVA_BLM_OK) + return SVA_INTERNAL_VIDEO_DECODER_ERROR; + + pBufferInfo[bufferListIndex].bufferLink.addr_buffer_start = ((t_sva_bm_buffer_desc*)pBufferListInfo->firstBufferId)->bufferSystemAddress.physical; + } + //extension of buffer start for ERC (and avoid fake BOW) + //48 bytes, ie 36 bytes aligned 16 to take into account internal bufferisation of SVA + //following lines should be removed when starting the buffer list with a fake buffer + blmError=sva_BLM_UpdateBufferMemoryBoundaryInBufferList (bitstreamBufferListId, BEGIN_OF_FIRST_BUFFER , -48); + if (blmError!=SVA_BLM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + + // Append a fake buffer at the end of the list if necessary + ffError=POP_FIFO_ELEM(VC1Desc[instanceNum].fakeBitstreamFifo,t_sva_buffer_id,bufferId); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + blmError=sva_BLM_AddBufferInList(bitstreamBufferListId, bufferId); + if (blmError!=SVA_BLM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + + // push back the first frame buffer into the .push fifo at the first position + if (lastPushedBufferId != INVALID_BUFFER_ID) { + ffError = PUSH_REVERSE_FIFO_ELEM(pDesc->inputBitstreamFifos.push, t_sva_buffer_id, lastPushedBufferId); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + bmError=sva_BM_GetBufferSize(lastPushedBufferId,&bufferSize); + if (bmError!=SVA_BM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + pDesc->status.nbCompressedDataBufferized+=bufferSize; + } + + /*update state machine*/ + sva_DC_UpdateInstanceStateMachine(instanceNum,SVA_DC_PUSH); + + // program the subtask with all its dependencies + algoError = sva_DC_VC1_SubTaskFieldsFullUpdate(instanceNum, pBitstreamBufferId); + HCL_DEBUG_ASSERT(algoError == SVA_OK); + + break; + + default: + return SVA_INTERNAL_VIDEO_DECODER_ERROR; + /* break; PCLint warning removal ...*/ + } + } + return SVA_OK; +} + + +/****************************************************************************/ +/* NAME: sva_DC_VC1_SetupParamInOut() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: this function programs both */ +/* SVA_TM_DEC_ADDR_OUT_FRAME_PARAMETERS and */ +/* SVA_TM_DEC_ADDR_IN_FRAME_PARAMETERS registers */ +/* */ +/* PARAMETERS: */ +/* IN : t_uint8 instanceNum, */ +/* t_sva_tm_subtask_id subtaskId */ +/* OUT :none */ +/* */ +/* RETURN: */ +/* t_sva_dc_error */ +/*--------------------------------------------------------------------------*/ +/* USE: NA */ +/* USED BY: NA */ +/****************************************************************************/ +t_sva_error sva_DC_VC1_SetupParamInOut(t_sva_service_instance_num instanceNum, t_sva_tm_subtask_id subtaskId) { + + t_sva_dc_algo_params_inout * algoParamsInOutAddr; + t_sva_error algoError; + t_sva_tm_error tmError; + t_sva_mm_error mmError; + t_sva_memory_id memoryId; + + //IN_FRAME_PARAMETER part + algoError=sva_DC_VC1_GetNextFrameParamsInOut(instanceNum, &algoParamsInOutAddr); + HCL_DEBUG_ASSERT(algoError == SVA_OK); + mmError = sva_MM_GetBlockMemoryId(VC1Desc[instanceNum].paramInOutBlockId, &memoryId); + HCL_DEBUG_ASSERT(mmError == SVA_MM_OK); + if (memoryId == SDRAM_ID) algoParamsInOutAddr = (t_sva_dc_algo_params_inout *)((t_uint32)algoParamsInOutAddr | MASK_BIT0); // toggle the exeternal flag + + // program both SVA_TM_DEC_ADDR_OUT_FRAME_PARAMETERS and SVA_TM_DEC_ADDR_IN_FRAME_PARAMETERS registers + tmError=sva_TM_UpdateSubTaskField( SVA_TM_INTERMEDIATE_FIELD_TO_UPDATE, + subtaskId, + SVA_TM_DEC_ADDR_OUT_FRAME_PARAMETERS, + FCMD_NEW_ADDRESS, + (t_uint32) algoParamsInOutAddr, + 0, + sizeof(t_sva_vdc_vc1_param_inout)); + if (tmError!= SVA_TM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + + tmError=sva_TM_UpdateSubTaskField( SVA_TM_INTERMEDIATE_FIELD_TO_UPDATE, + subtaskId, + SVA_TM_DEC_ADDR_IN_FRAME_PARAMETERS, + FCMD_NEW_ADDRESS, + (t_uint32) algoParamsInOutAddr, + 0, + sizeof(t_sva_vdc_vc1_param_inout)); + if (tmError!= SVA_TM_OK) {return SVA_INTERNAL_VIDEO_DECODER_ERROR;} + + return SVA_OK; +} + --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/vc1/sva_dc_vc1p.h @@ -0,0 +1,37 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ + +#ifndef __INC_SVA_DC_VC1P_H +#define __INC_SVA_DC_VC1P_H + +#include "hcl_defs.h" +#include "sva_decode.h" +#include "../sva_dc_algo.h" +#include "sva.h" + +PUBLIC t_sva_error sva_DC_VC1_GetNextFrameParamsInOut( t_sva_service_instance_num, t_sva_dc_algo_params_inout *); +PUBLIC t_sva_error sva_DC_VC1_GetNextFrameParamsIn( t_sva_service_instance_num, t_sva_dc_algo_params_in *); +PUBLIC t_sva_error sva_DC_VC1_GetNextFrameAddr(t_sva_service_instance_num , t_physical_address *, t_uint32 *, t_sva_buffer_id * ); +PUBLIC t_sva_error sva_DC_VC1_AreNextFrameInfosAvailable(t_sva_service_instance_num , t_bool *); +PUBLIC t_sva_error sva_DC_VC1_GetLastErrorType (t_sva_service_instance_num, t_uint16 * ); +PUBLIC t_sva_error sva_DC_VC1_GetStartCodeValue ( t_uint32 * ); +PUBLIC t_sva_error sva_DC_VC1_SetupParamInOut(t_sva_service_instance_num,t_sva_tm_subtask_id); +//PUBLIC t_sva_error sva_DC_VC1_SubTaskFieldsFullUpdate (t_sva_service_instance_num , t_sva_buffer_id *); +//PUBLIC t_sva_error sva_DC_VC1_TryToInitBitstreamFields(t_uint8 ,t_sva_buffer_id *); +#endif --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/display/sva_display.c @@ -0,0 +1,5661 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ + +/*------------------------------------------------------------------------ + * Includes + *----------------------------------------------------------------------*/ +#include "hcl_defs.h" +#include "sva.h" +#include "sva_display.h" +#include "sva_displayp.h" +#include "sva_buffermgt.h" +#include "sva_eventmgt.h" +#include "sva_timemgtp.h" +#include "sva_taskmgtp.h" + +#define DPB_PUSH_FIFO_DEFAULT_SIZE 51 + + +/*------------------------------------------------------------------------ + * Global Variables + *----------------------------------------------------------------------*/ +#ifdef __DEBUG +ALIGN(32) PRIVATE t_sva_dp_debug_events eventDisplayDebugTable[NUM_MAX_DISPLAY]; +ALIGN(32) PRIVATE t_sva_dp_debug_commands commandDisplayDebugTable[NUM_MAX_DISPLAY]; +ALIGN(32) PRIVATE t_sva_dp_debug_transitions transitionDisplayDebugTable[NUM_MAX_DISPLAY]; +ALIGN(32) PRIVATE t_sva_dp_debug_update updateDisplayDebugTable[NUM_MAX_DISPLAY]; +#endif + +extern t_sva_ti_system_time systemTimeDesc[SVA_NB_MAX_SERVICE]; + +PRIVATE t_sva_dp_descriptor displayDesc[NUM_MAX_DISPLAY]; + +PRIVATE const t_sva_tm_field_ctrl_desc defaultDisplayFieldDescArray[DISPLAY_FIELD_NUMBER]={ + { SVA_TM_DCMD_ALLOCATE, {{sizeof(t_sva_dpl_frame_buffer_in), DISPLAY_DEFAULT_INFOS_MEMORY_ID}}}, + { SVA_TM_DCMD_ALLOCATE, {{sizeof(t_sva_dpl_frame_buffer_out), DISPLAY_DEFAULT_INFOS_MEMORY_ID}}}, + { SVA_TM_DCMD_ALLOCATE, {{sizeof(t_sva_dpl_internal_buf), DISPLAY_DEFAULT_INFOS_MEMORY_ID}}}, + { SVA_TM_DCMD_ALLOCATE, {{sizeof(t_sva_dpl_param_in), DISPLAY_DEFAULT_INFOS_MEMORY_ID}}}, + { SVA_TM_DCMD_ALLOCATE, {{sizeof(t_sva_dpl_param_out), DISPLAY_DEFAULT_INFOS_MEMORY_ID}}}, + { SVA_TM_DCMD_ALLOCATE, {{sizeof(t_sva_dpl_param_inout), DISPLAY_DEFAULT_INFOS_MEMORY_ID}}}, + { SVA_TM_DCMD_ALLOCATE, {{sizeof(t_sva_dpl_param_inout), DISPLAY_DEFAULT_INFOS_MEMORY_ID}}} +}; + + + +/*table that translate grab state into service state*/ +PRIVATE const t_sva_service_state displayState2ServiceState[SVA_DP_LAST_DUMMY_STATE]= { + SVA_SERVICE_NOT_INITIALIZED, /*SVA_DP_NOT_INITIALIZED*/ + SVA_SERVICE_WAIT_FOR_CONFIGURATION, /*SVA_DP_WAIT_FOR_CONFIGURATION*/ + SVA_SERVICE_WAIT_FOR_INTERNAL_NEEDS, /*SVA_DP_WAIT_FOR_INTERNAL_NEEDS*/ + SVA_SERVICE_WAIT_FOR_ACTIVATE, /*SVA_DP_WAIT_FOR_ACTIVATE*/ + SVA_SERVICE_WAIT_FOR_START, /*SVA_DP_WAIT_FOR_START*/ + SVA_SERVICE_FLUSHING, /*SVA_DP_FLUSHING_IN*/ + SVA_SERVICE_FLUSHING, /*SVA_DP_FLUSHING_OUT*/ + SVA_SERVICE_WAIT_FOR_DATA, /*SVA_DP_WAIT_FOR_DATA*/ + SVA_SERVICE_RUNNING, /*SVA_DP_RUNNING*/ + SVA_SERVICE_ABORT_REQUESTED, /*SVA_DP_ABORT_REQUESTED*/ + SVA_SERVICE_STOP_REQUESTED, /*SVA_DP_STOP_REQUESTED*/ + SVA_SERVICE_ERROR /*SVA_DP_ERROR*/ +}; + + +PRIVATE const t_sva_dp_state stateMachine[SVA_DP_LAST_DUMMY_STATE][SVA_DP_LAST_DUMMY_TRANSITION]= { + /* Current State = SVA_DP_NOT_INITIALIZED */ + { + SVA_DP_WAIT_FOR_CONFIGURATION, /*SVA_DP_CREATE*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_CONFIGURE*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_INTERNAL_NEEDS*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_ACTIVATE*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_INACTIVATE*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_CONTROL_START*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_CONTROL_STOP*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_CONTROL_ABORT*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_ALL_DEPENDENCIES_RESOLVED*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_PUSH*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_EVENT_EOK*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_EVENT_FAKE*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_EVENT_ACTIVE*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_EVENT_INACTIVE*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_RESET*/ + SVA_DP_NOT_INITIALIZED, /*SVA_DP_CONTROL_DELETE*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_EVENT_ERROR*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_FLUSH_IN*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_FLUSH_OUT*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_CANCEL*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_UPDATE_PARAM*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_GET_PARAM_SIZE*/ + SVA_DP_TRANSITION_REJECTED /*SVA_DP_EVENT_ABORT*/ + }, + /* Current State = SVA_SERVICE_WAIT_FOR_CONFIGURATION */ + { + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_CREATE*/ + SVA_DP_WAIT_FOR_INTERNAL_NEEDS, /*SVA_DP_CONFIGURE*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_INTERNAL_NEEDS*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_ACTIVATE*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_INACTIVATE*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_CONTROL_START*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_CONTROL_STOP*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_CONTROL_ABORT*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_ALL_DEPENDENCIES_RESOLVED*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_PUSH*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_EVENT_EOK*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_EVENT_FAKE*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_EVENT_ACTIVE*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_EVENT_INACTIVE*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_RESET*/ + SVA_DP_NOT_INITIALIZED, /*SVA_DP_CONTROL_DELETE*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_EVENT_ERROR*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_FLUSH_IN*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_FLUSH_OUT*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_CANCEL*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_UPDATE_PARAM*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_GET_PARAM_SIZE*/ + SVA_DP_TRANSITION_REJECTED /*SVA_DP_EVENT_ABORT*/ + }, + /* Current State = SVA_SERVICE_WAIT_FOR_INTERNAL_NEEDS */ + { + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_CREATE*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_CONFIGURE*/ + SVA_DP_WAIT_FOR_ACTIVATE, /*SVA_DP_INTERNAL_NEEDS*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_ACTIVATE*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_INACTIVATE*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_CONTROL_START*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_CONTROL_STOP*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_CONTROL_ABORT*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_ALL_DEPENDENCIES_RESOLVED*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_PUSH*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_EVENT_EOK*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_EVENT_FAKE*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_EVENT_ACTIVE*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_EVENT_INACTIVE*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_RESET*/ + SVA_DP_NOT_INITIALIZED, /*SVA_DP_CONTROL_DELETE*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_EVENT_ERROR*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_FLUSH_IN*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_FLUSH_OUT*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_CANCEL*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_UPDATE_PARAM*/ + SVA_DP_WAIT_FOR_INTERNAL_NEEDS, /*SVA_DP_GET_PARAM_SIZE*/ + SVA_DP_TRANSITION_REJECTED /*SVA_DP_EVENT_ABORT*/ + }, + /* Current State = SVA_SERVICE_WAIT_FOR_ACTIVATE */ + { + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_CREATE*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_CONFIGURE*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_INTERNAL_NEEDS*/ + SVA_DP_WAIT_FOR_ACTIVATE, /*SVA_DP_ACTIVATE*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_INACTIVATE*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_CONTROL_START*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_CONTROL_STOP*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_CONTROL_ABORT*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_ALL_DEPENDENCIES_RESOLVED*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_PUSH*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_EVENT_EOK*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_EVENT_FAKE*/ + SVA_DP_WAIT_FOR_START, /*SVA_DP_EVENT_ACTIVE*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_EVENT_INACTIVE*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_RESET*/ + SVA_DP_NOT_INITIALIZED, /*SVA_DP_CONTROL_DELETE*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_EVENT_ERROR*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_FLUSH_IN*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_FLUSH_OUT*/ + SVA_DP_WAIT_FOR_ACTIVATE, /*SVA_DP_CANCEL*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_UPDATE_PARAM*/ + SVA_DP_WAIT_FOR_ACTIVATE , /*SVA_DP_GET_PARAM_SIZE*/ + SVA_DP_TRANSITION_REJECTED /*SVA_DP_EVENT_ABORT*/ + }, + /* Current State = SVA_SERVICE_WAIT_FOR_START */ + { + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_CREATE*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_CONFIGURE*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_INTERNAL_NEEDS*/ + SVA_DP_WAIT_FOR_START, /*SVA_DP_ACTIVATE*/ + SVA_DP_WAIT_FOR_START, /*SVA_DP_INACTIVATE*/ + SVA_DP_WAIT_FOR_DATA, /*SVA_DP_CONTROL_START*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_CONTROL_STOP*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_CONTROL_ABORT*/ + SVA_DP_WAIT_FOR_START, /*SVA_DP_ALL_DEPENDENCIES_RESOLVED*/ + SVA_DP_WAIT_FOR_START, /*SVA_DP_PUSH*/ + SVA_DP_ERROR, /*SVA_DP_EVENT_EOK*/ + SVA_DP_ERROR, /*SVA_DP_EVENT_FAKE*/ + SVA_DP_WAIT_FOR_START, /*SVA_DP_EVENT_ACTIVE*/ + SVA_DP_WAIT_FOR_START, /*SVA_DP_EVENT_INACTIVE*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_RESET*/ + SVA_DP_NOT_INITIALIZED, /*SVA_DP_CONTROL_DELETE*/ + SVA_DP_ERROR, /*SVA_DP_EVENT_ERROR*/ + SVA_DP_FLUSHING_IN, /*SVA_DP_FLUSH_IN*/ + SVA_DP_FLUSHING_OUT, /*SVA_DP_FLUSH_OUT*/ + SVA_DP_WAIT_FOR_START, /*SVA_DP_CANCEL*/ + SVA_DP_WAIT_FOR_START, /*SVA_DP_UPDATE_PARAM*/ + SVA_DP_WAIT_FOR_START , /*SVA_DP_GET_PARAM_SIZE*/ + SVA_DP_TRANSITION_REJECTED /*SVA_DP_EVENT_ABORT*/ + }, + /* Current State = SVA_DP_FLUSHING_IN */ + { + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_CREATE*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_CONFIGURE*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_INTERNAL_NEEDS*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_ACTIVATE*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_INACTIVATE*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_CONTROL_START*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_CONTROL_STOP*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_CONTROL_ABORT*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_ALL_DEPENDENCIES_RESOLVED*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_PUSH*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_EVENT_EOK*/ + SVA_DP_WAIT_FOR_START, /*SVA_DP_EVENT_FAKE*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_EVENT_ACTIVE*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_EVENT_INACTIVE*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_RESET*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_CONTROL_DELETE*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_EVENT_ERROR*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_FLUSH_IN*/ + SVA_DP_WAIT_FOR_START, /*SVA_DP_FLUSH_OUT*/ + SVA_DP_FLUSHING_IN, /*SVA_DP_CANCEL*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_UPDATE_PARAM*/ + SVA_DP_FLUSHING_IN, /*SVA_DP_GET_PARAM_SIZE*/ + SVA_DP_TRANSITION_REJECTED /*SVA_DP_EVENT_ABORT*/ + }, + /* Current State = SVA_DP_FLUSHING_OUT */ + { + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_CREATE*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_CONFIGURE*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_INTERNAL_NEEDS*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_ACTIVATE*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_INACTIVATE*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_CONTROL_START*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_CONTROL_STOP*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_CONTROL_ABORT*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_ALL_DEPENDENCIES_RESOLVED*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_PUSH*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_EVENT_EOK*/ + SVA_DP_WAIT_FOR_START, /*SVA_DP_EVENT_FAKE*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_EVENT_ACTIVE*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_EVENT_INACTIVE*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_RESET*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_CONTROL_DELETE*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_EVENT_ERROR*/ + SVA_DP_WAIT_FOR_START, /*SVA_DP_FLUSH_IN*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_FLUSH_OUT*/ + SVA_DP_FLUSHING_OUT, /*SVA_DP_CANCEL*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_UPDATE_PARAM*/ + SVA_DP_FLUSHING_OUT, /*SVA_DP_GET_PARAM_SIZE*/ + SVA_DP_TRANSITION_REJECTED /*SVA_DP_EVENT_ABORT*/ + }, + + + /* Current State = SVA_SERVICE_WAIT_FOR_DATA */ + { + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_CREATE*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_CONFIGURE*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_INTERNAL_NEEDS*/ + SVA_DP_WAIT_FOR_DATA, /*SVA_DP_ACTIVATE*/ + SVA_DP_WAIT_FOR_DATA, /*SVA_DP_INACTIVATE*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_CONTROL_START*/ + SVA_DP_STOP_REQUESTED, /*SVA_DP_CONTROL_STOP*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_CONTROL_ABORT*/ + SVA_DP_RUNNING, /*SVA_DP_ALL_DEPENDENCIES_RESOLVED*/ + SVA_DP_WAIT_FOR_DATA, /*SVA_DP_PUSH*/ + SVA_DP_ERROR, /*SVA_DP_EVENT_EOK*/ + SVA_DP_ERROR, /*SVA_DP_EVENT_FAKE*/ + SVA_DP_WAIT_FOR_DATA, /*SVA_DP_EVENT_ACTIVE*/ + SVA_DP_WAIT_FOR_DATA, /*SVA_DP_EVENT_INACTIVE*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_RESET*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_CONTROL_DELETE*/ + SVA_DP_ERROR, /*SVA_DP_EVENT_ERROR*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_FLUSH_IN*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_FLUSH_OUT*/ + SVA_DP_WAIT_FOR_DATA, /*SVA_DP_CANCEL*/ + SVA_DP_WAIT_FOR_DATA, /*SVA_DP_UPDATE_PARAM*/ + SVA_DP_WAIT_FOR_DATA, /*SVA_DP_GET_PARAM_SIZE*/ + SVA_DP_TRANSITION_REJECTED /*SVA_DP_EVENT_ABORT*/ + }, + /* Current State = SVA_SERVICE_RUNNING */ + { + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_CREATE*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_CONFIGURE*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_INTERNAL_NEEDS*/ + SVA_DP_RUNNING, /*SVA_DP_ACTIVATE*/ + SVA_DP_RUNNING, /*SVA_DP_INACTIVATE*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_CONTROL_START*/ + SVA_DP_STOP_REQUESTED, /*SVA_DP_CONTROL_STOP*/ + SVA_DP_ABORT_REQUESTED, /*SVA_DP_CONTROL_ABORT*/ + SVA_DP_RUNNING, /*SVA_DP_ALL_DEPENDENCIES_RESOLVED*/ + SVA_DP_RUNNING, /*SVA_DP_PUSH*/ + SVA_DP_WAIT_FOR_DATA, /*SVA_DP_EVENT_EOK*/ + SVA_DP_ERROR, /*SVA_DP_EVENT_FAKE*/ + SVA_DP_RUNNING, /*SVA_DP_EVENT_ACTIVE*/ + SVA_DP_RUNNING, /*SVA_DP_EVENT_INACTIVE*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_RESET*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_CONTROL_DELETE*/ + SVA_DP_ERROR, /*SVA_DP_EVENT_ERROR*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_FLUSH_IN*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_FLUSH_OUT*/ + SVA_DP_RUNNING, /*SVA_DP_CANCEL*/ + SVA_DP_RUNNING, /*SVA_DP_UPDATE_PARAM*/ + SVA_DP_RUNNING, /*SVA_DP_GET_PARAM_SIZE*/ + SVA_DP_TRANSITION_REJECTED /*SVA_DP_EVENT_ABORT*/ + + }, + /* Current State = SVA_SERVICE_ABORT_REQUESTED */ + { + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_CREATE*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_CONFIGURE*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_INTERNAL_NEEDS*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_ACTIVATE*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_INACTIVATE*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_CONTROL_START*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_CONTROL_STOP*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_CONTROL_ABORT*/ + SVA_DP_ABORT_REQUESTED, /*SVA_DP_ALL_DEPENDENCIES_RESOLVED*/ + SVA_DP_ABORT_REQUESTED, /*SVA_DP_PUSH*/ + SVA_DP_ERROR, /*SVA_DP_EVENT_EOK*/ + SVA_DP_ERROR, /*SVA_DP_EVENT_FAKE*/ + SVA_DP_ERROR, /*SVA_DP_EVENT_ACTIVE*/ + SVA_DP_ERROR, /*SVA_DP_EVENT_INACTIVE*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_RESET*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_CONTROL_DELETE*/ + SVA_DP_ERROR, /*SVA_DP_EVENT_ERROR*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_FLUSH_IN*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_FLUSH_OUT*/ + SVA_DP_ABORT_REQUESTED, /*SVA_DP_CANCEL*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_UPDATE_PARAM*/ + SVA_DP_ABORT_REQUESTED, /*SVA_DP_GET_PARAM_SIZE*/ + SVA_DP_ERROR /*SVA_DP_EVENT_ABORT*/ + }, + /* Current State = SVA_SERVICE_STOP_REQUESTED */ + { + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_CREATE*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_CONFIGURE*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_INTERNAL_NEEDS*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_ACTIVATE*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_INACTIVATE*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_CONTROL_START*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_CONTROL_STOP*/ + SVA_DP_ABORT_REQUESTED, /*SVA_DP_CONTROL_ABORT*/ + SVA_DP_STOP_REQUESTED, /*SVA_DP_ALL_DEPENDENCIES_RESOLVED*/ + SVA_DP_STOP_REQUESTED, /*SVA_DP_PUSH*/ + SVA_DP_WAIT_FOR_START, /*SVA_DP_EVENT_EOK*/ + SVA_DP_ERROR, /*SVA_DP_EVENT_FAKE*/ + SVA_DP_ERROR, /*SVA_DP_EVENT_ACTIVE*/ + SVA_DP_ERROR, /*SVA_DP_EVENT_INACTIVE*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_RESET*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_CONTROL_DELETE*/ + SVA_DP_ERROR, /*SVA_DP_EVENT_ERROR*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_FLUSH_IN*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_FLUSH_OUT*/ + SVA_DP_STOP_REQUESTED, /*SVA_DP_CANCEL*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_UPDATE_PARAM*/ + SVA_DP_STOP_REQUESTED, /*SVA_DP_GET_PARAM_SIZE*/ + SVA_DP_TRANSITION_REJECTED /*SVA_DP_EVENT_ABORT*/ /*@ change to rejected*/ + }, + /* Current State = SVA_SERVICE_ERROR */ + { + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_CREATE*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_CONFIGURE*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_INTERNAL_NEEDS*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_ACTIVATE*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_INACTIVATE*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_CONTROL_START*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_CONTROL_STOP*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_CONTROL_ABORT*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_ALL_DEPENDENCIES_RESOLVED*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_PUSH*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_EVENT_EOK*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_EVENT_FAKE*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_EVENT_ACTIVE*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_EVENT_INACTIVE*/ + SVA_DP_WAIT_FOR_START, /*SVA_DP_RESET*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_CONTROL_DELETE*/ + SVA_DP_ERROR, /*SVA_DP_EVENT_ERROR*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_FLUSH_IN*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_FLUSH_OUT*/ + SVA_DP_ERROR, /*SVA_DP_CANCEL*/ + SVA_DP_TRANSITION_REJECTED, /*SVA_DP_UPDATE_PARAM*/ + SVA_DP_ERROR, /*SVA_DP_GET_PARAM_SIZE*/ + SVA_DP_TRANSITION_REJECTED /*SVA_DP_EVENT_ABORT*/ + } +}; + + +/*activate state machine description*/ +PRIVATE const t_sva_dp_activate_state activateStateMachine[SVA_DP_LAST_ACTIVATE_DUMMY_STATE][SVA_DP_LAST_DUMMY_TRANSITION]= { + /* Current State = SVA_DP_INACTIVE */ + { + SVA_DP_INACTIVE, /*SVA_DP_CREATE*/ + SVA_DP_INACTIVE, /*SVA_DP_CONFIGURE*/ + SVA_DP_INACTIVE, /*SVA_DP_INTERNAL_NEEDS*/ + SVA_DP_IN_ACTIVATION, /*SVA_DP_ACTIVATE*/ + SVA_DP_ACTIVATE_TRANSITION_REJECTED, /*SVA_DP_INACTIVATE*/ + SVA_DP_ACTIVATE_TRANSITION_REJECTED, /*SVA_DP_CONTROL_START*/ + SVA_DP_ACTIVATE_TRANSITION_REJECTED, /*SVA_DP_CONTROL_STOP*/ + SVA_DP_ACTIVATE_TRANSITION_REJECTED, /*SVA_DP_CONTROL_ABORT*/ + SVA_DP_INACTIVE, /*SVA_DP_ALL_DEPENDENCIES_RESOLVED*/ + SVA_DP_INACTIVE, /*SVA_DP_PUSH*/ + SVA_DP_INACTIVE, /*SVA_DP_EVENT_EOK*/ + SVA_DP_INACTIVE, /*SVA_DP_EVENT_FAKE*/ + SVA_DP_INACTIVE, /*SVA_DP_EVENT_ACTIVE*/ + SVA_DP_INACTIVE, /*SVA_DP_EVENT_INACTIVE*/ + SVA_DP_INACTIVE, /*SVA_DP_RESET*/ + SVA_DP_INACTIVE, /*SVA_DP_CONTROL_DELETE*/ + SVA_DP_INACTIVE, /*SVA_DP_EVENT_ERROR*/ + SVA_DP_INACTIVE, /*SVA_DP_FLUSH_IN*/ + SVA_DP_INACTIVE, /*SVA_DP_FLUSH_OUT*/ + SVA_DP_ACTIVATE_TRANSITION_REJECTED, /*SVA_DP_CANCEL*/ + SVA_DP_INACTIVE, /*SVA_DP_UPDATE_PARAM*/ + SVA_DP_INACTIVE, /*SVA_DP_GET_PARAM_SIZE*/ + SVA_DP_INACTIVE /*SVA_DP_EVENT_ABORT*/ + }, + /* Current State = SVA_DP_IN_ACTIVATION */ + { + SVA_DP_ACTIVATE_TRANSITION_REJECTED, /*SVA_DP_CREATE*/ + SVA_DP_ACTIVATE_TRANSITION_REJECTED, /*SVA_DP_CONFIGURE*/ + SVA_DP_ACTIVATE_TRANSITION_REJECTED, /*SVA_DP_INTERNAL_NEEDS*/ + SVA_DP_ACTIVATE_TRANSITION_REJECTED, /*SVA_DP_ACTIVATE*/ + SVA_DP_ACTIVATE_TRANSITION_REJECTED, /*SVA_DP_INACTIVATE*/ + SVA_DP_ACTIVATE_TRANSITION_REJECTED, /*SVA_DP_CONTROL_START*/ + SVA_DP_ACTIVATE_TRANSITION_REJECTED, /*SVA_DP_CONTROL_STOP*/ + SVA_DP_ACTIVATE_TRANSITION_REJECTED, /*SVA_DP_CONTROL_ABORT*/ + SVA_DP_IN_ACTIVATION, /*SVA_DP_ALL_DEPENDENCIES_RESOLVED*/ + SVA_DP_IN_ACTIVATION, /*SVA_DP_PUSH*/ + SVA_DP_IN_ACTIVATION, /*SVA_DP_EVENT_EOK*/ + SVA_DP_IN_ACTIVATION, /*SVA_DP_EVENT_FAKE*/ + SVA_DP_ACTIVE, /*SVA_DP_EVENT_ACTIVE*/ + SVA_DP_IN_ACTIVATION, /*SVA_DP_EVENT_INACTIVE*/ + SVA_DP_IN_ACTIVATION, /*SVA_DP_RESET*/ + SVA_DP_ACTIVATE_TRANSITION_REJECTED, /*SVA_DP_CONTROL_DELETE*/ + SVA_DP_IN_ACTIVATION, /*SVA_DP_EVENT_ERROR*/ + SVA_DP_IN_ACTIVATION, /*SVA_DP_FLUSH_IN*/ + SVA_DP_IN_ACTIVATION, /*SVA_DP_FLUSH_OUT*/ + SVA_DP_INACTIVE, /*SVA_DP_CANCEL*/ + SVA_DP_IN_ACTIVATION, /*SVA_DP_UPDATE_PARAM*/ + SVA_DP_IN_ACTIVATION, /*SVA_DP_GET_PARAM_SIZE*/ + SVA_DP_IN_ACTIVATION /*SVA_DP_EVENT_ABORT*/ + }, + /* Current State = SVA_DP_ACTIVE */ + { + SVA_DP_ACTIVATE_TRANSITION_REJECTED, /*SVA_DP_CREATE*/ + SVA_DP_ACTIVATE_TRANSITION_REJECTED, /*SVA_DP_CONFIGURE*/ + SVA_DP_ACTIVATE_TRANSITION_REJECTED, /*SVA_DP_INTERNAL_NEEDS*/ + SVA_DP_ACTIVATE_TRANSITION_REJECTED, /*SVA_DP_ACTIVATE*/ + SVA_DP_IN_INACTIVATION, /*SVA_DP_INACTIVATE*/ + SVA_DP_ACTIVE, /*SVA_DP_CONTROL_START*/ + SVA_DP_ACTIVE, /*SVA_DP_CONTROL_STOP*/ + SVA_DP_ACTIVE, /*SVA_DP_CONTROL_ABORT*/ + SVA_DP_ACTIVE, /*SVA_DP_ALL_DEPENDENCIES_RESOLVED*/ + SVA_DP_ACTIVE, /*SVA_DP_PUSH*/ + SVA_DP_ACTIVE, /*SVA_DP_EVENT_EOK*/ + SVA_DP_ACTIVE, /*SVA_DP_EVENT_FAKE*/ + SVA_DP_ACTIVE, /*SVA_DP_EVENT_ACTIVE*/ + SVA_DP_ACTIVE, /*SVA_DP_EVENT_INACTIVE*/ + SVA_DP_ACTIVE, /*SVA_DP_RESET*/ + SVA_DP_INACTIVE, /*SVA_DP_CONTROL_DELETE*/ + SVA_DP_ACTIVE, /*SVA_DP_EVENT_ERROR*/ + SVA_DP_ACTIVE, /*SVA_DP_FLUSH_IN*/ + SVA_DP_ACTIVE, /*SVA_DP_FLUSH_OUT*/ + SVA_DP_ACTIVATE_TRANSITION_REJECTED, /*SVA_DP_CANCEL*/ + SVA_DP_ACTIVE, /*SVA_DP_UPDATE_PARAM*/ + SVA_DP_ACTIVE, /*SVA_DP_GET_PARAM_SIZE*/ + SVA_DP_ACTIVE /*SVA_DP_EVENT_ABORT*/ + }, + /* Current State = SVA_DP_IN_INACTIVATION */ + { + SVA_DP_ACTIVATE_TRANSITION_REJECTED, /*SVA_DP_CREATE*/ + SVA_DP_ACTIVATE_TRANSITION_REJECTED, /*SVA_DP_CONFIGURE*/ + SVA_DP_ACTIVATE_TRANSITION_REJECTED, /*SVA_DP_INTERNAL_NEEDS*/ + SVA_DP_ACTIVATE_TRANSITION_REJECTED, /*SVA_DP_ACTIVATE*/ + SVA_DP_ACTIVATE_TRANSITION_REJECTED, /*SVA_DP_INACTIVATE*/ + SVA_DP_ACTIVATE_TRANSITION_REJECTED, /*SVA_DP_CONTROL_START*/ + SVA_DP_ACTIVATE_TRANSITION_REJECTED, /*SVA_DP_CONTROL_STOP*/ + SVA_DP_ACTIVATE_TRANSITION_REJECTED, /*SVA_DP_CONTROL_ABORT*/ + SVA_DP_IN_INACTIVATION, /*SVA_DP_ALL_DEPENDENCIES_RESOLVED*/ + SVA_DP_IN_INACTIVATION, /*SVA_DP_PUSH*/ + SVA_DP_IN_INACTIVATION, /*SVA_DP_EVENT_EOK*/ + SVA_DP_IN_INACTIVATION, /*SVA_DP_EVENT_FAKE*/ + SVA_DP_IN_INACTIVATION, /*SVA_DP_EVENT_ACTIVE*/ + SVA_DP_INACTIVE, /*SVA_DP_EVENT_INACTIVE*/ + SVA_DP_INACTIVE, /*SVA_DP_RESET*/ + SVA_DP_ACTIVATE_TRANSITION_REJECTED, /*SVA_DP_CONTROL_DELETE*/ + SVA_DP_IN_INACTIVATION, /*SVA_DP_EVENT_ERROR*/ + SVA_DP_IN_INACTIVATION, /*SVA_DP_FLUSH_IN*/ + SVA_DP_IN_INACTIVATION, /*SVA_DP_FLUSH_OUT*/ + SVA_DP_ACTIVE, /*SVA_DP_CANCEL*/ + SVA_DP_IN_INACTIVATION, /*SVA_DP_UPDATE_PARAM*/ + SVA_DP_IN_INACTIVATION, /*SVA_DP_GET_PARAM_SIZE*/ + SVA_DP_IN_INACTIVATION /*SVA_DP_EVENT_ABORT*/ + } +}; + + +/* + * Define the tables of conversion between SVA HCL API enum and the SVA programming model ones + */ +PRIVATE const t_sva_hw_bpp bpp_hclapi2hwapi[] = { + SVA_BPP_RGB444, SVA_BPP_RGB555, SVA_BPP_RGB565, + SVA_BPP_RGB888, SVA_BPP_RGB888_UNPACKED +}; + +PRIVATE const t_sva_hw_chroma_sampling_format csf_hclapi2hwapi[] = {SVA_CSF_DEFAULT, SVA_CSF_MPEG2_4, SVA_CSF_MPEG1}; + +#define NB_HCL_MIRRORING_TYPE 3 /* none/horizontal/vertical */ +PRIVATE const t_sva_dp_hw_rotation_mirroring rot_mir_hclapi2hwapi[][NB_HCL_MIRRORING_TYPE] = { + { /* SVA_ROTATION_NONE */ + { SVA_HW_ROTATION_NONE, SVA_HW_MIRRORING_NONE }, /* SVA_NO_MIRRORING */ + { SVA_HW_ROTATION_NONE, SVA_HW_MIRRORING_VERTICAL }, /* SVA_HORIZONTAL_MIRRORING */ + { SVA_HW_ROTATION_NONE, SVA_HW_MIRRORING_HORIZONTAL } /* SVA_VERTICAL_MIRRORING */ + }, + { /* SVA_ROTATION_90 */ + { SVA_HW_ROTATION_90, SVA_HW_MIRRORING_HORIZONTAL }, /* SVA_NO_MIRRORING */ + { SVA_HW_ROTATION_90, SVA_HW_MIRRORING_BOTH }, /* SVA_HORIZONTAL_MIRRORING */ + { SVA_HW_ROTATION_90, SVA_HW_MIRRORING_VERTICAL } /* SVA_VERTICAL_MIRRORING */ + }, + { /* SVA_ROTATION_180 */ + { SVA_HW_ROTATION_NONE, SVA_HW_MIRRORING_BOTH }, /* SVA_NO_MIRRORING */ + { SVA_HW_ROTATION_NONE, SVA_HW_MIRRORING_HORIZONTAL }, /* SVA_HORIZONTAL_MIRRORING */ + { SVA_HW_ROTATION_NONE, SVA_HW_MIRRORING_VERTICAL } /* SVA_VERTICAL_MIRRORING */ + }, + { /* SVA_ROTATION_270 */ + { SVA_HW_ROTATION_90, SVA_HW_MIRRORING_NONE }, /* SVA_NO_MIRRORING */ + { SVA_HW_ROTATION_90, SVA_HW_MIRRORING_VERTICAL }, /* SVA_HORIZONTAL_MIRRORING */ + { SVA_HW_ROTATION_90, SVA_HW_MIRRORING_BOTH } /* SVA_VERTICAL_MIRRORING */ + } +}; + +/* + * Define the conversion table from the different filter mode and the display subtask type + * WARNING: This table SHALL be updated if the t_sva_deblocking_filter_mode and t_sva_deringing_filter_mode enums + * are updated into sva.h + */ +PRIVATE const t_sva_tm_subtask_type filter_mode_2_subtask_type[NUMBER_OF_DEBLOCKING_FILTER_MODE][NUMBER_OF_DERINGING_FILTER_MODE]= { + /* SVA_NONE_DEBLOCKING_FILTER */ + { + SVA_TM_DISPLAY_NO_FILTERING, /* SVA_NONE_DERINGING_FILTER */ + SVA_TM_DISPLAY_MPEG4_DERINGING /* SVA_MPEG4_DERINGING_FILTER */ + }, + /* SVA_MPEG4_DEBLOCKING_FILTER */ + { + SVA_TM_DISPLAY_MPEG4_DEBLOCKING, /* SVA_NONE_DERINGING_FILTER */ + SVA_TM_DISPLAY_MPEG4_DEBLOCKING_DERINGING /* SVA_MPEG4_DERINGING_FILTER */ + }, + /* SVA_H263_DEBLOCKING_FILTER */ + { + SVA_TM_DISPLAY_H263_DEBLOCKING, /* SVA_NONE_DERINGING_FILTER */ + SVA_TM_DISPLAY_H263_DEBLOCKING_MPEG4_DERINGING /* SVA_MPEG4_DERINGING_FILTER */ + } +}; + + +/*------------------------------------------------------------------------ + * Private Macros + *----------------------------------------------------------------------*/ +/* + * Define the upper range value of the brightness and contrast configuration parameters + */ +#define CNT_BRT_MAX_RANGE_VALUE 100 + +/* + * Define the macro used to convert contrast configuration parameter ( if bpp !=0) + * to the hw parameter programmation value + */ +#define COMPUTE_CONTRAST(requestedValue) (t_sva_param_subfield)(((t_uint32)requestedValue*SVA_CNT_150)/CNT_BRT_MAX_RANGE_VALUE) + +/* + * Define the macro used to convert contrast configuration parameter (if bpp=0) + * to the hw parameter programmation value + */ +#define COMPUTE_CONTRAST_ZERO_BPP(requestedValue) (t_sva_param_subfield)(((t_uint32)requestedValue*SVA_CNT_ZERO_BPP_150)/CNT_BRT_MAX_RANGE_VALUE) + +/* + * Define the macro used to convert brightness configuration parameter (if bpp!=0) + * to the hw parameter programmation value + */ +#define COMPUTE_BRIGHTNESS(requestedValue) (t_sva_param_subfield)(((t_uint32)requestedValue*SVA_BRT_150)/CNT_BRT_MAX_RANGE_VALUE) + +/* + * Define the macro used to convert brightness configuration parameter (if bpp=0) + * to the hw parameter programmation value + */ +#define COMPUTE_BRIGHTNESS_ZERO_BPP(requestedValue) (t_sva_param_subfield)(((t_uint32)requestedValue*SVA_BRT_ZERO_BPP_150)/CNT_BRT_MAX_RANGE_VALUE) + +/* + * Define the macro used to convert alpha key configuration parameter + * to the hw parameter programmation value + */ +#define COMPUTE_ALPHA_KEY(bpp, value) (t_sva_param_subfield)( \ + (bpp == SVA_COLOR_12BITS)?(((t_uint32)value & MASK_QUARTET0)<>4))<<4); if ((arg-ret)>8) {ret=ret+16;} } +#else + +void SVA_DP_REALIGN_16(t_uint16*pret, t_uint16 arg) { + *pret = (t_uint16)(((t_uint32)(arg>>4))<<4); + if((arg- *pret)>8) { *pret += 16;} + +} +#endif + +#define SVA_DP_ALIGN_WITH_MAX(ret,arg,offset,max) { ret = arg; ret = (t_uint16)(((t_uint32)(arg>>4))<<4); if (((ret+offset+16)<=max)&&(arg&MASK_QUARTET)) {ret=ret+16;}} + +#define REALIGN_FLOOR(value, alignment) { value &= ~(alignment-1); } +#define REALIGN_CEIL(value, alignment) { if ((value & (alignment-1)) != 0) {value &= ~(alignment-1); value += alignment;} } + + + +/*------------------------------------------------------------------------ + * PRIVATE Functions Prototypes + *----------------------------------------------------------------------*/ +PRIVATE void sva_DP_ResetInstanceDescriptor(t_sva_service_instance_num); +PRIVATE void sva_DP_InitFifos(t_sva_service_instance_num); +PRIVATE t_sva_dp_state sva_DP_UpdateInstanceStatesMachine(t_sva_service_instance_num, t_sva_dp_transition); +PRIVATE t_bool sva_DP_isTransitionValid(t_sva_service_instance_num, t_sva_dp_transition); +PRIVATE t_bool sva_DP_isConfigurationValid(const t_sva_postprocessor_configuration *); +PRIVATE t_sva_dp_error sva_DP_CheckServiceId(t_sva_service_id); +PRIVATE t_sva_dp_error sva_DP_BuildParamInStructure(const t_sva_postprocessor_configuration *, t_sva_dpl_param_in *); +PRIVATE t_sva_dp_error sva_DP_ResetStatus(t_sva_postprocessor_status *); +PRIVATE t_sva_error sva_DP_DoFlushOut(t_sva_service_id); +PRIVATE t_sva_error sva_DP_DoFlushIn(t_sva_service_id); +PRIVATE t_sva_dp_error sva_DP_CreateSubTasksDescriptors(t_sva_service_id, const t_sva_postprocessor_configuration *, t_sva_tm_subtask_list_id *); +PRIVATE t_bool sva_DP_isChangeConfIsImmediate(t_bool, t_sva_dp_conf_handle*); +PRIVATE void sva_DP_ResetParamConfHandle(t_sva_dp_conf_handle *); +PRIVATE void sva_DP_ConfigurationChangeOnPush(t_sva_service_id,t_sva_buffer_type,t_sva_push_mode,t_sva_buffer_id); +PRIVATE void sva_DP_ConfigurationChangeOnSolveDep(t_sva_service_instance_num,t_sva_dp_subtask_dependencies,t_sva_buffer_id); + +PRIVATE t_sva_error sva_DP_CreateAndConfigurePIPSubTasks(t_sva_service_id, t_sva_tm_subtask_id*); +PRIVATE t_sva_error sva_DP_UpdatePIPSubtasksAndAddToSubtaskList(t_sva_tm_subtask_id, t_sva_service_instance_num, t_sva_tm_subtask_list_id, t_sva_tm_timestamp* ); +PRIVATE void sva_DP_ComputePipPieces(t_sva_service_instance_num ); +PRIVATE t_bool sva_DP_isPrimarySubtask(t_sva_service_instance_num, t_sva_tm_subtask_id); +PRIVATE void sva_DP_BuildPipParamIn(t_uint16, t_sva_service_instance_num, t_sva_dpl_param_in *); + +PRIVATE void sva_DP_DisablePip(t_sva_service_instance_num); + +/****************************************************************************/ +/* NAME: t_sva_error sva_DP_Init ( void ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine initialize the Display Management module */ +/* */ +/* PARAMETERS: */ +/* IN : none */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_dp_error */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_sva_error sva_DP_Init(void) +{ + t_sva_service_instance_num ind; + + for (ind = 0; ind < NUM_MAX_DISPLAY; ind++) { + sva_DP_ResetInstanceDescriptor(ind); + sva_DP_InitFifos(ind); + sva_DP_ResetStatus(&displayDesc[ind].status); + sva_DP_ResetParamConfHandle(&displayDesc[ind].confHandle); + +#ifdef __DEBUG + /*init debug counters*/ + eventDisplayDebugTable[ind].nbOfEventReceived=0; + commandDisplayDebugTable[ind].nbOfCommandReceived=0; + transitionDisplayDebugTable[ind].nbOfTransitionReceived=0; + updateDisplayDebugTable[ind].nbOfResolvedDep=0; +#endif + + } + + return SVA_OK; +} + +/****************************************************************************/ +/* NAME: t_sva_error sva_DP_Create ( t_sva_service_id * pServiceId ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine allows to create a new instance of a Disp. Service */ +/* */ +/* PARAMETERS: */ +/* IN : none */ +/* */ +/* INOUT : */ +/* - pServiceId: return service ID value */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_sva_error sva_DP_Create(t_sva_service_id *pServiceId) +{ + + t_sva_service_instance_num ind = 0; + + HCL_ASSERT(pServiceId!=NULL); + + while (displayDesc[ind].state != SVA_DP_NOT_INITIALIZED) {ind++;} + + if (ind >= NUM_MAX_DISPLAY ) + { + return SVA_INTERNAL_POSTPROCESSOR_ERROR; + } + /* Note: task_id is put in service_id in SVA_Create function */ + /* Here we only put the instance number in the ServiceId */ + WRITE_INSTANCE_NUM_IN_SERVICE_ID(ind, *pServiceId); + + +#ifdef __DEBUG + /*init service counter*/ + eventDisplayDebugTable[ind].nbOfEventReceived=0; + commandDisplayDebugTable[ind].nbOfCommandReceived=0; + transitionDisplayDebugTable[ind].nbOfTransitionReceived=0; + updateDisplayDebugTable[ind].nbOfResolvedDep=0; +#endif + + + /* Memorize the instance service Id */ + displayDesc[ind].serviceId = *pServiceId; + + /* Update the main state machine and the activateState machine */ + sva_DP_UpdateInstanceStatesMachine(ind, SVA_DP_CREATE); + + + return SVA_OK; +} + +/****************************************************************************/ +/* NAME: t_sva_error sva_DP_Reset ( t_sva_service_id serviceId ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine allows to reset an instance of a Display Service */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - serviceId: identifier of the given service */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_sva_error sva_DP_Reset(t_sva_service_id serviceId) +{ + + t_sva_service_instance_num instanceNum = READ_INSTANCE_NUM_IN_SERVICE_ID(serviceId); + + if (sva_DP_UpdateInstanceStatesMachine(instanceNum, SVA_DP_RESET) == SVA_DP_TRANSITION_REJECTED) + { + return SVA_INTERNAL_POSTPROCESSOR_ERROR; + } + + return SVA_OK; +} + + + +/****************************************************************************/ +/* NAME: t_sva_error sva_DP_Control ( */ +/* t_sva_service_id serviceId, */ +/* t_sva_service_cmd_id cmdId, */ +/* t_sva_timestamp timeStamp */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine allows to control an instance of a Display Service */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - serviceId: identifier of the given service */ +/* - cmdId: command to apply to the DISPLAY */ +/* - timeStamp: value of timeStamp */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_sva_error sva_DP_Control( + t_sva_service_id serviceId, + t_sva_service_cmd_id cmdId, + t_uint32 param + ) +{ + t_sva_service_instance_num instanceNum = READ_INSTANCE_NUM_IN_SERVICE_ID(serviceId); + t_sva_dp_descriptor *pDesc=&displayDesc[instanceNum]; + t_sva_error status = SVA_UNEXPECTED_API_CALL; + t_sva_dp_error error; + t_sva_tm_error tmError; + + /*check for service id validity*/ + error=sva_DP_CheckServiceId(serviceId); + if (error!=SVA_DP_OK) + { + return SVA_INTERNAL_POSTPROCESSOR_ERROR; + } + +#ifdef __DEBUG + { + t_uint32 systemTime; + + SVA_GetServiceSystemTime(serviceId,&systemTime); + commandDisplayDebugTable[instanceNum].commandDebugDesc[commandDisplayDebugTable[instanceNum].nbOfCommandReceived%LOG_DEPTH].command=cmdId; + commandDisplayDebugTable[instanceNum].commandDebugDesc[commandDisplayDebugTable[instanceNum].nbOfCommandReceived%LOG_DEPTH].systemTime=systemTime; + commandDisplayDebugTable[instanceNum].commandDebugDesc[commandDisplayDebugTable[instanceNum].nbOfCommandReceived%LOG_DEPTH].parameter=param; + commandDisplayDebugTable[instanceNum].nbOfCommandReceived++; + } +#endif + + + /*handle command*/ + switch(cmdId) + { + case SVA_SERVICE_START: + if (sva_DP_isTransitionValid(instanceNum,SVA_DP_CONTROL_START)==TRUE) + { + /* transition are force before sending task command to avoid race condition*/ + sva_DP_UpdateInstanceStatesMachine(instanceNum, SVA_DP_CONTROL_START); + /* as we accepted some push before (or after a restart) some dependencies are perhaps + already scheduled + */ + if (GET_FIFO_NB_ELEMS(pDesc->subtasksDependencyFifo)nbSubtasks) + { + sva_DP_UpdateInstanceStatesMachine(instanceNum, SVA_DP_ALL_DEPENDENCIES_RESOLVED); + } + /*now send start command*/ + tmError=sva_TM_SendTaskCommand(pDesc->subtasksListId,SVA_TM_TCMD_START,param); + HCL_DEBUG_ASSERT(tmError==SVA_TM_OK); + + status = SVA_OK; + } + break; + case SVA_SERVICE_STOP: + if (sva_DP_isTransitionValid(instanceNum,SVA_DP_CONTROL_STOP)==TRUE) + { + /* transition are force before sending task command to avoid race condition*/ + sva_DP_UpdateInstanceStatesMachine(instanceNum, SVA_DP_CONTROL_STOP); + /*stop subtask list*/ + tmError=sva_TM_SendTaskCommand(pDesc->subtasksListId,SVA_TM_TCMD_STOP,param); + HCL_DEBUG_ASSERT(tmError==SVA_TM_OK); + + status = SVA_OK; + + } + break; + case SVA_SERVICE_ABORT: + if (sva_DP_isTransitionValid(instanceNum,SVA_DP_CONTROL_ABORT)==TRUE) + { + /* transition are force before sending task command to avoid race condition*/ + sva_DP_UpdateInstanceStatesMachine(instanceNum, SVA_DP_CONTROL_ABORT); + /*abort subtask list*/ + tmError=sva_TM_SendTaskCommand(pDesc->subtasksListId,SVA_TM_TCMD_ABORT,param); + HCL_DEBUG_ASSERT(tmError==SVA_TM_OK); + + status = SVA_OK; + } + break; + + case SVA_SERVICE_RESET: + if (sva_DP_isTransitionValid(instanceNum,SVA_DP_RESET)==TRUE) + { + /*do instance clean-up so service can restart: uncrement the error counter of status structure*/ + pDesc->status.eventStats.errorCounter++; + sva_DP_UpdateInstanceStatesMachine(instanceNum, SVA_DP_RESET); + + status = SVA_OK; + + } + break; + case SVA_SERVICE_FLUSH_IN: + if (sva_DP_isTransitionValid(instanceNum,SVA_DP_FLUSH_IN)==TRUE) + { + /*flush input buffer and params buffer if necessary*/ + status = sva_DP_DoFlushIn(serviceId); + if (status == SVA_OK) + { + sva_DP_UpdateInstanceStatesMachine(instanceNum, SVA_DP_FLUSH_IN); + /*generate a fake event since flush command is asynchronous*/ + sva_TM_SendTaskCommand(pDesc->subtasksListId,SVA_TM_TCMD_FAKE_EVENT,param); + } + } + break; + case SVA_SERVICE_FLUSH_OUT: + if (sva_DP_isTransitionValid(instanceNum,SVA_DP_FLUSH_OUT)==TRUE) + { + /*flush input buffer if necessary*/ + status = sva_DP_DoFlushOut(serviceId); + if (status == SVA_OK) + { + sva_DP_UpdateInstanceStatesMachine(instanceNum, SVA_DP_FLUSH_OUT); + /*generate a fake event since flush command is asynchronous*/ + sva_TM_SendTaskCommand(pDesc->subtasksListId,SVA_TM_TCMD_FAKE_EVENT,param); + } + } + break; + /*unknown command*/ + default: + status = SVA_UNKNOWN_CMD_ID; + break; + } + + return status; + +} + + +PRIVATE t_sva_error sva_DP_CheckPIPStateMachine(t_uint32 param, t_sva_dp_pip_state pipActivation, t_sva_dp_pip_state *newpipActivation, t_bool * donothing) +{ + + t_sva_error svaError=SVA_OK; + + if(param!=0) + { + switch(pipActivation) + { + case SVA_DP_NO_PIP: + case SVA_DP_PIP_CONFIGURATION: + *newpipActivation = SVA_DP_PIP_CREATION; + *donothing = FALSE; + break; + case SVA_DP_PIP_DELETION: + *newpipActivation = SVA_DP_PIP_DELETION; + svaError= SVA_CONFIGURATION_IN_PROGRESS; + *donothing = TRUE; + break; + default: + *newpipActivation = pipActivation; + *donothing = TRUE; + break; + } + + } + else + { + switch(pipActivation) + { + case SVA_DP_NO_PIP: + svaError= SVA_INCOHERENT_CONFIGURATION; + *newpipActivation = SVA_DP_NO_PIP; + *donothing = TRUE; + break; + case SVA_DP_PIP_RUNNING: + *newpipActivation = SVA_DP_PIP_TO_BE_DELETED; + *donothing = FALSE; + break; + case SVA_DP_PIP_CONFIGURATION: + *newpipActivation = SVA_DP_NO_PIP; + *donothing = FALSE; + break; + default: + *newpipActivation = pipActivation; + *donothing = TRUE; + break; + + } + + } + + return svaError; + +} + + + +/****************************************************************************/ +/* NAME: t_sva_error sva_DP_UpdateParams ( */ +/* t_sva_service_id serviceId, */ +/* t_sva_update_cmd_type updateCmdType, */ +/* t_sva_preprocessor_param_id paramId, */ +/* t_uint32 param */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine allows to update params for an instance of a Display */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - serviceId: identifier of the given service */ +/* - updateCmdType: command to apply to the DISPLAY */ +/* - paramd: value of timeStamp */ +/* - param: parameter for the cmdType */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/****************************************************************************/ +PUBLIC t_sva_error SVA_UpdatePostProcessorParams( + t_sva_service_id serviceId, + t_sva_update_cmd_type updateCmdType, + t_sva_postprocessor_param_id paramId, + t_uint32 * pParam + ) +{ + + t_sva_service_instance_num instanceNum = READ_INSTANCE_NUM_IN_SERVICE_ID(serviceId); + t_sva_dp_descriptor *pDesc=&displayDesc[instanceNum]; + t_sva_postprocessor_configuration *pNextConf=&pDesc->confHandle.nextConf; + t_sva_postprocessor_configuration *pConf=&pDesc->confHandle.currentConf; + t_sva_dp_error status; + t_sva_error svaError=SVA_OK; + t_bool donothing = FALSE; + t_sva_dp_pip_state newPipAct; + t_uint32 param = *pParam; + t_sva_window_desc * pPip = (t_sva_window_desc *)pParam; + t_sva_image_desc *pPip2 = (t_sva_image_desc *)pParam; + t_sva_offset_desc *pOffset = (t_sva_offset_desc *) pParam; + t_sva_ace_offset * pAce = (t_sva_ace_offset*)pParam; + t_sva_image_desc *pVideoFrameImageDesc = (t_sva_image_desc *)pParam; + t_sva_image_desc *pSourceFrameImageDesc = (t_sva_image_desc *)pParam; + HCL_ASSERT(pParam!=NULL); + + /*check for service id validity*/ + status=sva_DP_CheckServiceId(serviceId); + if (status!=SVA_DP_OK) {return SVA_INTERNAL_POSTPROCESSOR_ERROR;} + + /*check that transition is allowed*/ + if (sva_DP_isTransitionValid(instanceNum,SVA_DP_UPDATE_PARAM)==FALSE) {return SVA_UNEXPECTED_API_CALL;} + + /*check that a configuration is not currently on going*/ + //if (pDesc->confHandle.confState!=SVA_DP_NO_CONF_CHANGE_NEED) {return SVA_CONFIGURATION_IN_PROGRESS;} + + /*take command into account for next configuration*/ + switch(paramId) + { + case SVA_POSTPROCESSOR_PPP_TILE: + { + t_uint32 counter = 0; + t_sva_ppp_tile_info* tiles = pDesc->tile_info = (t_sva_ppp_tile_info*)pParam; + while(tiles){ //all tiles + if (tiles->image.height && tiles->image.width){ + pDesc->tile_info_new[counter].image = tiles->image; + pDesc->tile_info_new[counter].imageOffset = tiles->imageOffset; + counter++; + } + tiles = tiles->next_tile; + } + + pDesc->tile_info_new[counter].image.width = 0; + + if (counter){ + if (counter == 1) + return SVA_INCOHERENT_CONFIGURATION; + + pDesc->pipPieceCounter_new = counter; + if (pDesc->pipPieceCounter_new > DISPLAY_NB_MAX_OF_PIP_PIECE) { + return SVA_INCOHERENT_CONFIGURATION; + } + + pDesc->is_ppp_tiling = TRUE; + if (pDesc->pipActivated == SVA_DP_PIP_RUNNING){ + pDesc->change_ppp_tiling = TRUE; + //pDesc->pipActivated = SVA_DP_PIP_CONFIGURATION; + }else{ + t_uint32 idx; + for (idx=0; idx to copy terminating tile config + pDesc->tile_info_cur[idx].image = pDesc->tile_info_new[idx].image; + pDesc->tile_info_cur[idx].imageOffset = pDesc->tile_info_new[idx].imageOffset; + } + pDesc->pipPieceCounter = counter; + pDesc->change_ppp_tiling = FALSE; + } + }else{ + //pDesc->is_ppp_tiling = FALSE; + } + + svaError = sva_DP_CheckPIPStateMachine(counter, pDesc->pipActivated, &newPipAct, &donothing); + pDesc->pipActivated = newPipAct; + } + break; + case SVA_POSTPROCESSOR_PIP: + svaError = sva_DP_CheckPIPStateMachine(pPip->image.width, pDesc->pipActivated, &newPipAct, &donothing); + pDesc->pipActivated = newPipAct; + break; + case SVA_POSTPROCESSOR_CONTRAST: + pNextConf->contrast=(t_uint8)param ; + break; + case SVA_POSTPROCESSOR_REDBLUESWAP: + pNextConf->redBlueSwap=(t_bool)param; + break; + case SVA_POSTPROCESSOR_BRIGHTNESS: + pNextConf->brightness=(t_uint8)param; + break; + case SVA_POSTPROCESSOR_DITHERING: + pNextConf->isDithering=(t_bool)param; + break; + case SVA_POSTPROCESSOR_MIRRORING: + pNextConf->mirrorMode=(t_sva_mirroring_mode)param; + break; + case SVA_POSTPROCESSOR_ROTATION: + pNextConf->rotationMode=(t_sva_rotation_mode)param; + break; + case SVA_POSTPROCESSOR_FRAME_ALPHAKEY: + pNextConf->alphaKey=(t_uint8) param; + break; + case SVA_POSTPROCESSOR_CROPPING: + pNextConf->sourceFrameDesc.window.image.height = pPip->image.height; + pNextConf->sourceFrameDesc.window.image.width = pPip->image.width; + pNextConf->sourceFrameDesc.window.imageOffset.offsetX = pPip->imageOffset.offsetX; + pNextConf->sourceFrameDesc.window.imageOffset.offsetY = pPip->imageOffset.offsetY; + break; + case SVA_POSTPROCESSOR_RESIZE: + pNextConf->resizedImageDesc.height = pPip2->height; + pNextConf->resizedImageDesc.width = pPip2->width; + break; + case SVA_POSTPROCESSOR_CLIPPING: + pNextConf->clippedWindowDesc.image.height = pPip->image.height; + pNextConf->clippedWindowDesc.image.width = pPip->image.width; + pNextConf->clippedWindowDesc.imageOffset.offsetX = pPip->imageOffset.offsetX; + pNextConf->clippedWindowDesc.imageOffset.offsetY = pPip->imageOffset.offsetY; + break; + case SVA_POSTPROCESSOR_SCREEN_WINDOW_OFFSET: + pNextConf->videoFrameBufferDesc.window.imageOffset.offsetX=pOffset->offsetX; + pNextConf->videoFrameBufferDesc.window.imageOffset.offsetY=pOffset->offsetY; + break; + case SVA_POSTPROCESSOR_SCREEN_BUFFER_ADDR: + pNextConf->screenFrameBufferBaseAddr=(t_physical_address)param; + break; + case SVA_POSTPROCESSOR_ALT_SCREEN_BUFFER_ADDR: + pNextConf->screenAlternateFrameBufferBaseAddr=(t_physical_address )param; + break; + case SVA_POSTPROCESSOR_MATRIX_COEFF: + /* TBD */ + break; + case SVA_POSTPROCESSOR_ANTI_TEARING_EFFECT: + /* TBD */ + break; + case SVA_POSTPROCESSOR_ACE_STRENGTH: + pNextConf->aceStrength=(t_sva_ace_strength)param; + break; + case SVA_POSTPROCESSOR_ACE_RANGE: + pNextConf->aceRange=(t_sva_color_range)param; + break; + case SVA_POSTPROCESSOR_ACE_OFFSET: + pDesc->confHandle.isAceOffsetNeedUpdate=TRUE; + pDesc->confHandle.newAceOffset.ace_offset_0 = pAce->ace_offset_0; + pDesc->confHandle.newAceOffset.ace_offset_1 = pAce->ace_offset_1; + pDesc->confHandle.newAceOffset.ace_offset_2 = pAce->ace_offset_2; + pDesc->confHandle.newAceOffset.ace_offset_3 = pAce->ace_offset_3; + break; + case SVA_POSTPROCESSOR_OUTPUT_RANGE: + pNextConf->outputRange= (t_sva_color_range)param; + break; + + case SVA_POSTPROCESSOR_VIDEOFRAME_SIZE: + pNextConf->videoFrameBufferDesc.frame.height = pVideoFrameImageDesc->height; + pNextConf->videoFrameBufferDesc.frame.width = pVideoFrameImageDesc->width; + break; + case SVA_POSTPROCESSOR_SOURCEFRAME_SIZE: + pNextConf->sourceFrameDesc.frame.height = pSourceFrameImageDesc->height; + pNextConf->sourceFrameDesc.frame.width = pSourceFrameImageDesc->width; + break; + default: + break; + } + + + pDesc->confHandle.paramId[pDesc->confHandle.nbParams] = paramId; + pDesc->confHandle.nbParams ++; + + if(donothing==FALSE) + { + /*take into account updateCmdType*/ + switch(updateCmdType) + { + case SVA_UPDATE_MULTIPLE: + /*nothing to do*/ + break; + case SVA_UPDATE_LAST: + if(sva_DP_isConfigurationValid(pNextConf)==FALSE){return SVA_INCOHERENT_CONFIGURATION;} + + if (sva_DP_isChangeConfIsImmediate(pConf->isDirectScreenAccess, &pDesc->confHandle)==TRUE) // function not yet implemented + { + if (pDesc->is_ppp_tiling){ + if (!pDesc->change_ppp_tiling){ + if (SVA_POSTPROCESSOR_PPP_TILE == paramId){ + if((pDesc->pipActivated == SVA_DP_PIP_CREATION ) || + (pDesc->pipActivated == SVA_DP_PIP_CONFIGURATION) ){ + if(pDesc->pipPieceCounter){ //all tiles + sva_DP_ComputePipPieces(instanceNum); + + sva_DP_CreateAndConfigurePIPSubTasks(serviceId, &pDesc->pipSubtasksIdArrayNoSynchro[0]); // same configuration than current Conf + pDesc->pipActivated = SVA_DP_PIP_CONFIGURATION; + } + } + } + } + }else{ + if((pDesc->pipActivated == SVA_DP_PIP_CREATION) || + (pDesc->pipActivated == SVA_DP_PIP_CONFIGURATION)){ + SVA_DP_REALIGN_16(pDesc->pipWindowDesc.imageOffset.offsetX,pPip->imageOffset.offsetX); + SVA_DP_REALIGN_16(pDesc->pipWindowDesc.imageOffset.offsetY,pPip->imageOffset.offsetY); + SVA_DP_ALIGN_WITH_MAX(pDesc->pipWindowDesc.image.width,pPip->image.width,pDesc->pipWindowDesc.imageOffset.offsetX,pDesc->confHandle.currentConf.sourceFrameDesc.window.image.width); + SVA_DP_ALIGN_WITH_MAX(pDesc->pipWindowDesc.image.height,pPip->image.height,pDesc->pipWindowDesc.imageOffset.offsetY,pDesc->confHandle.currentConf.sourceFrameDesc.window.image.height); + //pDesc->pipWindowDesc.image.width = pPip->image.width; + //pDesc->pipWindowDesc.image.height = pPip->image.height; + //pDesc->pipWindowDesc.imageOffset.offsetX = pPip->imageOffset.offsetX; + //pDesc->pipWindowDesc.imageOffset.offsetY = pPip->imageOffset.offsetY; + sva_DP_ComputePipPieces(instanceNum); + pPip->image.width = pDesc->newPipWindow.image.width; + pPip->image.height = pDesc->newPipWindow.image.height; + pPip->imageOffset.offsetX = pDesc->newPipWindow.imageOffset.offsetX; + pPip->imageOffset.offsetY = pDesc->newPipWindow.imageOffset.offsetY; + + sva_DP_CreateAndConfigurePIPSubTasks(serviceId, &pDesc->pipSubtasksIdArrayNoSynchro[0]); // same configuration than current Conf + pDesc->pipActivated = SVA_DP_PIP_CONFIGURATION; + } + } + /* resize and cropping on going: not mandatory */ + if((pDesc->pipActivated == SVA_DP_PIP_RUNNING)&&((paramId == SVA_POSTPROCESSOR_RESIZE)||(paramId == SVA_POSTPROCESSOR_CROPPING))){ + sva_DP_ComputePipPieces(instanceNum); + } + + /* disable PIP */ + if(pDesc->pipActivated == SVA_DP_PIP_TO_BE_DELETED){ + sva_DP_DisablePip(instanceNum); + } + + + *pConf=*pNextConf; + pDesc->confHandle.currentConfCounter++; + pDesc->confHandle.confState=SVA_DP_IMMEDIATE_CONF_CHANGE_NEED; + + svaError = SVA_IMMEDIATE_UPDATE; + + } + else + { + + t_uint8 i; + /* choose buffer on which modofication will be applied */ + for(i=0; iconfHandle.nbParams; i++) { + + /* FIX ME */ + if((pDesc->confHandle.paramId[i] == SVA_POSTPROCESSOR_CROPPING)||(pDesc->confHandle.paramId[i]==SVA_POSTPROCESSOR_SOURCEFRAME_SIZE)){ + pDesc->confHandle.bufferType[0]=SVA_IMAGE_BUFFER_TYPE; + pDesc->confHandle.pushMode[0]=SVA_PUSH_IN; + pDesc->confHandle.needs.buffer_in_needed = (t_bitfield)TRUE; + break; + } + } + + for(i=0; iconfHandle.nbParams; i++) { + + /* FIX ME */ + if((pDesc->confHandle.paramId[i] == SVA_POSTPROCESSOR_RESIZE)||(pDesc->confHandle.paramId[i]==SVA_POSTPROCESSOR_CLIPPING)){ + pDesc->confHandle.bufferType[0]=SVA_IMAGE_BUFFER_TYPE; + pDesc->confHandle.pushMode[0]=SVA_PUSH_OUT; + pDesc->confHandle.needs.buffer_out_needed = (t_bitfield)TRUE; + break; + } + } + + + /* compute confState */ + if ((pDesc->confHandle.needs.buffer_in_needed == (t_bitfield)TRUE) && (pDesc->confHandle.needs.buffer_out_needed == (t_bitfield)TRUE)) + { + pDesc->confHandle.confState = SVA_DP_WAIT_FOR_BUFFER_INOUT; + pDesc->confHandle.needs.buffer_in_needed = (t_bitfield)FALSE; + pDesc->confHandle.needs.buffer_out_needed = (t_bitfield)FALSE; + + } + else if (pDesc->confHandle.needs.buffer_in_needed == (t_bitfield)TRUE) + { + pDesc->confHandle.confState = SVA_DP_WAIT_FOR_BUFFER_IN_ONLY; + pDesc->confHandle.needs.buffer_in_needed = (t_bitfield)FALSE; + } + else if (pDesc->confHandle.needs.buffer_out_needed == (t_bitfield)TRUE) + { + pDesc->confHandle.confState = SVA_DP_WAIT_FOR_BUFFER_OUT_ONLY; + pDesc->confHandle.needs.buffer_out_needed = (t_bitfield)FALSE; + } + + + /* reset paramId table and nbParams */ + sva_DP_ResetParamConfHandle(&pDesc->confHandle); + + svaError= SVA_DELAYED_UPDATE; + + } + + + + break; + + case SVA_UPDATE_REVERT: + /*cancel previously param update*/ + *pNextConf=*pConf; + pDesc->confHandle.isAceOffsetNeedUpdate=FALSE; + break; + default: + break; + } + + /*update state machine => do nothing*/ + sva_DP_UpdateInstanceStatesMachine(instanceNum, SVA_DP_UPDATE_PARAM); + } + return svaError; +} + + + +/****************************************************************************/ +/* NAME: t_sva_error sva_DP_Push ( */ +/* t_sva_service_id serviceId, */ +/* t_sva_buffer_id bufferId, */ +/* t_sva_push_mode pushMode, */ +/* t_sva_buffer_type bufferType, */ +/* t_sva_timestamp timeStamp */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine allows to push data in a Display service */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - serviceId: identifier of the service */ +/* - bufferId: identifier of the buffer */ +/* - pushMode: PUSH_IN/PUSH_OUT */ +/* - bufferType: */ +/* - timeStamp: */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_sva_error sva_DP_Push( + t_sva_service_id serviceId, + t_sva_buffer_id bufferId, + t_sva_push_mode pushMode, + t_sva_buffer_type bufferType, + t_sva_timestamp timeStamp + ) +{ + + t_sva_service_instance_num instanceNum = READ_INSTANCE_NUM_IN_SERVICE_ID(serviceId); + t_sva_dp_descriptor *pDesc=&displayDesc[instanceNum]; + t_sva_dp_error status; + t_sva_error svaError; + t_sva_bm_error bmError; + t_sva_ff_error ffError; + t_sva_tm_timestamp tmTimeStamp; + t_size bufferSize; + t_size minSize=0; + t_uint32 pixelSize = 0; + t_uint32 width = 0; + t_uint32 height = 0; + + + + + /*check for service id validity*/ + status=sva_DP_CheckServiceId(serviceId); + if (status!=SVA_DP_OK) {return SVA_INTERNAL_POSTPROCESSOR_ERROR;} + + /*check that transition is allowed*/ + if (sva_DP_isTransitionValid(instanceNum,SVA_DP_PUSH)==FALSE) {return SVA_UNEXPECTED_API_CALL;} + + if (pDesc->change_ppp_tiling){ + if(pDesc->pipActivated == SVA_DP_PIP_RUNNING){ + if(pDesc->pipPieceCounter_new){ //all tiles + t_sva_dp_pip_subtask_id pipSubtaskId; + t_uint32 idx; + + while (POP_FIFO_ELEM(pDesc->pipSubtasksFifos.pushFifo,t_sva_dp_pip_subtask_id,pipSubtaskId )!=SVA_FIFO_EMPTY) + { + } + + if(pDesc->is_ppp_tiling) { + t_uint32 i; + for(i=0;i<(pDesc->pipPieceCounter-1)*pDesc->nbSubtasks;i++){ + t_sva_tm_error tmError; + tmError = sva_TM_DeleteSubTask(pDesc->pipSubtasksIdArrayNoSynchro[i]); + if (tmError!=SVA_TM_OK) { + return SVA_INTERNAL_POSTPROCESSOR_ERROR; + }else{ + pDesc->pipSubtasksIdArrayNoSynchro[i] = 0; + } + } + } + + pDesc->pipPieceCounter = pDesc->pipPieceCounter_new; + + for (idx=0; idxpipPieceCounter+1; idx++){ //+1 -> to copy terminating tile config + pDesc->tile_info_cur[idx].image = pDesc->tile_info_new[idx].image; + pDesc->tile_info_cur[idx].imageOffset = pDesc->tile_info_new[idx].imageOffset; + } + + sva_DP_ComputePipPieces(instanceNum); + + sva_DP_CreateAndConfigurePIPSubTasks(serviceId, &pDesc->pipSubtasksIdArrayNoSynchro[0]); + + pDesc->confHandle.currentConf = pDesc->confHandle.nextConf; + pDesc->confHandle.currentConfCounter++; + pDesc->confHandle.confState = SVA_DP_IMMEDIATE_CONF_CHANGE_NEED; + + sva_DP_UpdateInstanceStatesMachine(instanceNum, SVA_DP_UPDATE_PARAM); //FIXME: is this correct? + pDesc->change_ppp_tiling = FALSE; + pDesc->pipPieceCounter_new = 0; + } + } + } + + + /*check if a configuration change can occur on this buffer*/ + sva_DP_ConfigurationChangeOnPush(serviceId,bufferType,pushMode,bufferId); + + /*handle provide buffer*/ + + switch(bufferType){ + case SVA_IMAGE_BUFFER_TYPE: + if (pushMode == SVA_PUSH_IN) { + + /*Here minSize is calculated from nextConf handle as nextConf configuration should be taken into account + by this buffer Push + */ + minSize = pDesc->confHandle.nextConf.sourceFrameDesc.frame.height*pDesc->confHandle.nextConf.sourceFrameDesc.frame.width*3/2; + if(pDesc->confHandle.currentConf.raster_in_format){ + minSize = minSize + 256; //128-byte alignment for each Chroma component + } + + /*read buffer size*/ + bmError=sva_BM_GetBufferSize(bufferId,&bufferSize); + if (bmError!=SVA_BM_OK) {return SVA_INTERNAL_POSTPROCESSOR_ERROR;} + + /*check buffer has enought space*/ + if (bufferSize>=minSize) + { + + if (GET_FIFO_NB_ELEMS(pDesc->inputImageFifos.pushFifo) >= DPB_PUSH_FIFO_DEFAULT_SIZE) {svaError=SVA_INTERNAL_FIFOS_FULL;} + + ffError=PUSH_FIFO_ELEM(pDesc->inputImageFifos.pushFifo, t_sva_buffer_id, bufferId); + + if (timeStamp.type == SVA_NO_TIMESTAMP) + { + tmTimeStamp.timestampType = SVA_TM_IMMEDIATE; + tmTimeStamp.timestampValue = 0; + } + else /* PRESENTATION_TIMESTAMP */ + { + tmTimeStamp.timestampType = SVA_TM_ABSOLUTE; + tmTimeStamp.timestampValue = timeStamp.value; + } + + ffError=PUSH_FIFO_ELEM(pDesc->inputTimestampsFifos.pushFifo, t_sva_tm_timestamp, tmTimeStamp); + if (ffError!=SVA_FIFO_OK) {svaError=SVA_INTERNAL_FIFOS_FULL;} + else {svaError=SVA_OK;} + } + else {svaError = SVA_INTERNAL_POSTPROCESSOR_ERROR; } + if (GET_FIFO_NB_ELEMS(pDesc->inputImageFifos.pushFifo) >= DPB_PUSH_FIFO_DEFAULT_SIZE) {svaError=SVA_INTERNAL_FIFOS_FULL;} + } + else if (pushMode == SVA_PUSH_OUT) { + + switch(pDesc->confHandle.currentConf.transformId){ + case SVA_POSTPROCESSOR_RGB: + case SVA_POSTPROCESSOR_YUV420PL_TO_RGB: + case SVA_POSTPROCESSOR_YUV422PL_TO_RGB: + //case SVA_POSTPROCESSOR_YUV420MB_TO_RGB: + { + switch(pDesc->confHandle.currentConf.bitsPerPixel){ + case SVA_COLOR_12BITS: + case SVA_COLOR_15BITS: + case SVA_COLOR_16BITS: + pixelSize = 4; //pixelSize is double of actual value; divided below + break; + case SVA_COLOR_24BITS: + pixelSize = 6; // patch for vi 12349 This pixelsize refers to double the no.of bytes per pixel + break; + case SVA_COLOR_32BITS: + pixelSize = 8; //pixelSize is double of actual value; divided below + break; + default: + {return SVA_INTERNAL_POSTPROCESSOR_ERROR; } + + } + } + break; + case SVA_POSTPROCESSOR_YUV420MB_TO_YUV420MB: + pixelSize = 3; //pixelSize is double of actual value; divided below + break; + case SVA_POSTPROCESSOR_YUV: + case SVA_POSTPROCESSOR_YUV420PL_TO_YUV422PL: + //case SVA_POSTPROCESSOR_YUV420MB_TO_YUV422PL: + pixelSize = 4; //pixelSize is double of actual value; divided below + break; + } + + width = pDesc->confHandle.nextConf.videoFrameBufferDesc.frame.width; + height = pDesc->confHandle.nextConf.videoFrameBufferDesc.frame.height; + + minSize = (height *width*pixelSize)>>1; + + if(pDesc->confHandle.currentConf.transformId == SVA_POSTPROCESSOR_YUV420MB_TO_YUV420_SEP_COMP_MB){ + minSize = height*width+((width/2+8)&0xff0)*((height/2+8)&0xff0)*2; + } else if(pDesc->confHandle.currentConf.transformId == SVA_POSTPROCESSOR_YUV420MB_TO_YUV422_SEP_COMP_MB){ + minSize = height*width+((width/2+8)&0xff0)*height*2; + } + + /*read buffer size*/ + bmError=sva_BM_GetBufferSize(bufferId,&bufferSize); + if (bmError!=SVA_BM_OK) {return SVA_INTERNAL_POSTPROCESSOR_ERROR;} + + /*check buffer has enought space*/ + if (bufferSize>=minSize) + { + + if(pDesc->confHandle.currentConf.isDirectScreenAccess == FALSE) { + + if (GET_FIFO_NB_ELEMS(pDesc->outputImageFifos.pushFifo) >= PUSH_FIFO_DEFAULT_SIZE+3) {svaError=SVA_INTERNAL_FIFOS_FULL;} + + ffError=PUSH_FIFO_ELEM(pDesc->outputImageFifos.pushFifo, t_sva_buffer_id, bufferId); + if (ffError!=SVA_FIFO_OK) {svaError=SVA_INTERNAL_FIFOS_FULL;} + else {svaError=SVA_OK;} + } + else + svaError=SVA_INTERNAL_POSTPROCESSOR_ERROR; + + } /*bufferSize>= minSize*/ + else {svaError = SVA_INTERNAL_POSTPROCESSOR_ERROR; } + + } + else + svaError=SVA_INTERNAL_POSTPROCESSOR_ERROR; + break; + + case SVA_PARAMS_BUFFER_TYPE: + /* input params */ + ffError=PUSH_FIFO_ELEM(pDesc->inputParamsFifos.pushFifo, t_sva_buffer_id, bufferId); + if (ffError!=SVA_FIFO_OK) {svaError=SVA_INTERNAL_POSTPROCESSOR_ERROR;} + else {svaError=SVA_OK;} + break; + default: + svaError=SVA_INVALID_BUFFER_TYPE; + break; + } + + + /*update state machine*/ + sva_DP_UpdateInstanceStatesMachine(instanceNum,SVA_DP_PUSH); + + /*update buffer status if we have succeeded to push it and try to solve dependencies*/ + if (svaError == SVA_OK) + { + t_uint32 systemTime; + + svaError=SVA_GetServiceSystemTime(serviceId,&systemTime); + if (svaError!=SVA_OK) {return SVA_INTERNAL_POSTPROCESSOR_ERROR;} + bmError=sva_BM_UpdateBufferStatus(bufferId, SVA_BUFFER_IN_USE, systemTime); + if (bmError!=SVA_BM_OK) {return SVA_INTERNAL_POSTPROCESSOR_ERROR;} + status=sva_DP_ResolveDependencies(instanceNum); + } + + return svaError; + +} + + +/****************************************************************************/ +/* NAME: t_sva_error sva_DP_GetPostProcessorStatus ( */ +/* t_sva_service_id serviceId, */ +/* t_sva_postprocessor_status * pStatus */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine allows to get status of the Display service */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - serviceId: identifier of the service */ +/* - pStatus: status for the display service */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_dp_error */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_sva_error SVA_GetPostProcessorStatus(t_sva_service_id serviceId, t_sva_postprocessor_status * pStatus ) +{ + + t_sva_service_instance_num instanceNum = READ_INSTANCE_NUM_IN_SERVICE_ID(serviceId); + t_sva_dp_descriptor *pDesc=&displayDesc[instanceNum]; + t_sva_dp_error dpError; + + HCL_ASSERT(pStatus != 0); + /*check for service id validity*/ + dpError=sva_DP_CheckServiceId(serviceId); + if (dpError!=SVA_DP_OK) {return SVA_INTERNAL_POSTPROCESSOR_ERROR;} + + /*copy status*/ + *pStatus=pDesc->status; + pStatus->nbInputImagesPostProcessed = pDesc->nbInputImagesPostProcessed; + pStatus->nbOutputImagesDisplayed = pDesc->nbOutputImagesDisplayed; + + if (!pDesc->confHandle.currentConf.isDirectScreenAccess){ + pStatus->bufferizationStats.outLevel=GET_FIFO_NB_ELEMS(pDesc->outputImageFifos.pushFifo); + } + pStatus->bufferizationStats.inLevel=GET_FIFO_NB_ELEMS(pDesc->inputImageFifos.pushFifo); + + return SVA_OK; +} + + + +/****************************************************************************/ +/* NAME: t_sva_dp_error sva_DP_DispatchVirtualHwEvent ( */ +/* t_sva_virtual_hw_event_id eventId, */ +/* t_sva_service_id serviceId, */ +/* t_sva_tm_subtask_id subtaskId, */ +/* t_uint32 eventTimestamp, */ +/* t_uint32 eventDate, */ +/* t_uint8 maxOfEvent, */ +/* t_sva_event_desc * pEventDesc, */ +/* t_uint32 * pNbEvent */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine allows to dispatch event of the Display service */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - eventId: event identifier */ +/* - serviceId: identifier of the service */ +/* - subtaskId: identifier of the subtask for which is the event */ +/* - eventTimestamp: time at which the event occur (system time unit) */ +/* - eventDate: time at which the event occur (ticks time unit) */ +/* - maxOfEvent: nb of event max contained in EventDesc */ +/* - pEventDesc: structure of Events */ +/* - pNbEvent: nb of event into EventDesc */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_dp_error */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ + +PUBLIC t_sva_error sva_DP_DispatchVirtualHwEvent( + t_sva_tm_virtual_hw_event_id eventId, + t_sva_service_id serviceId, + t_sva_tm_subtask_id subtaskId, + t_uint32 eventTimestamp, + t_uint32 eventDate, + t_uint8 maxOfEvent, + t_sva_event_desc * pEventDesc, + t_uint32 * pNbEvent + ) +{ + t_sva_service_instance_num instanceNum = READ_INSTANCE_NUM_IN_SERVICE_ID(serviceId); + t_sva_dp_descriptor *pDesc=&displayDesc[instanceNum]; + const t_sva_postprocessor_configuration *pConf =&pDesc->confHandle.currentConf; + t_sva_dpl_param_out paramOut; + t_sva_tm_error tmError; + t_sva_ff_error ffError; + t_sva_dp_error dpError; + t_uint32 nbEventsRaised = 0; + t_uint8 subtaskIndex=0; + t_bool isFound = FALSE; + t_sva_dp_pip_subtask_id pipSubtaskId; + t_bool isUpdateStateNeed=FALSE; + + + HCL_ASSERT(pEventDesc != NULL); + HCL_ASSERT(pNbEvent != NULL); + + *pNbEvent=0; + + /*check for service id validity*/ + dpError=sva_DP_CheckServiceId(serviceId); + if (dpError!=SVA_DP_OK) {return SVA_INTERNAL_POSTPROCESSOR_ERROR;} + +#ifdef __DEBUG + eventDisplayDebugTable[instanceNum].eventDebugDesc[eventDisplayDebugTable[instanceNum].nbOfEventReceived%LOG_DEPTH].event=eventId; + eventDisplayDebugTable[instanceNum].eventDebugDesc[eventDisplayDebugTable[instanceNum].nbOfEventReceived%LOG_DEPTH].systemTime=eventTimestamp; + eventDisplayDebugTable[instanceNum].eventDebugDesc[eventDisplayDebugTable[instanceNum].nbOfEventReceived%LOG_DEPTH].subtaskId=subtaskId; + eventDisplayDebugTable[instanceNum].nbOfEventReceived++; +#endif + + + /* + * Switch eventId + */ + + switch(eventId) + { + + // missing : SVA_EVENT_POSTPROCESSOR_LINE_SYNCHRO to be configured thru displaySyncLine + + case SVA_TM_ACTIVE_HW_EVENT: + /*add activate event*/ + CHECK_TABLE_OVERFLOW(nbEventsRaised, maxOfEvent, SVA_INTERNAL_POSTPROCESSOR_ERROR); + + pEventDesc[nbEventsRaised].eventId = SVA_EVENT_SERVICE_ACTIVATED; + pEventDesc[nbEventsRaised].serviceId = serviceId; + pEventDesc[nbEventsRaised].bufferId = INVALID_BUFFER_ID; + pEventDesc[nbEventsRaised].eventTimestamp = (t_sva_timestamp_value) eventTimestamp; + pEventDesc[nbEventsRaised].eventDate = (t_sva_timestamp_value) eventDate; + pEventDesc[nbEventsRaised].extraInfo=0; + nbEventsRaised++; + /*update state machine*/ + sva_DP_UpdateInstanceStatesMachine(instanceNum,SVA_DP_EVENT_ACTIVE); + break; + case SVA_TM_INACTIVE_HW_EVENT: + /*add inactivate event*/ + CHECK_TABLE_OVERFLOW(nbEventsRaised, maxOfEvent, SVA_INTERNAL_POSTPROCESSOR_ERROR); + pEventDesc[nbEventsRaised].eventId = SVA_EVENT_SERVICE_INACTIVATED; + pEventDesc[nbEventsRaised].serviceId = serviceId; + pEventDesc[nbEventsRaised].bufferId = INVALID_BUFFER_ID; + pEventDesc[nbEventsRaised].eventTimestamp = (t_sva_timestamp_value) eventTimestamp; + pEventDesc[nbEventsRaised].eventDate = (t_sva_timestamp_value) eventDate; + pEventDesc[nbEventsRaised].extraInfo=0; + nbEventsRaised++; + /*update state machine*/ + sva_DP_UpdateInstanceStatesMachine(instanceNum,SVA_DP_EVENT_INACTIVE); + break; + case SVA_TM_ERR_HW_EVENT: + /*read param out*/ + tmError=sva_TM_GetSubTaskField(subtaskId, SVA_TM_DIS_ADDR_OUT_PARAMETERS,(t_logical_address) ¶mOut, + 0, sizeof(t_sva_dpl_param_out), FALSE); + HCL_DEBUG_ASSERT(tmError==SVA_TM_OK); + CHECK_TABLE_OVERFLOW(nbEventsRaised, maxOfEvent, SVA_INTERNAL_POSTPROCESSOR_ERROR); + + pEventDesc[nbEventsRaised].eventId = SVA_EVENT_SERVICE_ERROR; + pEventDesc[nbEventsRaised].serviceId = serviceId; + pEventDesc[nbEventsRaised].bufferId = INVALID_BUFFER_ID; + pEventDesc[nbEventsRaised].eventTimestamp = (t_sva_timestamp_value) eventTimestamp; + pEventDesc[nbEventsRaised].eventDate = (t_sva_timestamp_value) eventDate; + // if (pDesc->state==SVA_DP_ABORT_REQUESTED) + // { + // pEventDesc[nbEventsRaised].extraInfo=0; + //} + // else + // { + if (paramOut.error_type!=0) {pEventDesc[nbEventsRaised].extraInfo=(t_uint32)SVA_POSTPROCESSOR_TASK_PARAMETER_ERROR;} + else {pEventDesc[nbEventsRaised].extraInfo=(t_uint32)SVA_POSTPROCESSOR_NO_ERROR;} +// } + + nbEventsRaised++; + /*update state machine*/ + sva_DP_UpdateInstanceStatesMachine(instanceNum,SVA_DP_EVENT_ERROR); + break; + case SVA_TM_ABORT_HW_EVENT: + /*read param out*/ + tmError=sva_TM_GetSubTaskField(subtaskId, SVA_TM_DIS_ADDR_OUT_PARAMETERS,(t_logical_address) ¶mOut, + 0, sizeof(t_sva_dpl_param_out), FALSE); + HCL_DEBUG_ASSERT(tmError==SVA_TM_OK); + CHECK_TABLE_OVERFLOW(nbEventsRaised, maxOfEvent, SVA_INTERNAL_POSTPROCESSOR_ERROR); + + pEventDesc[nbEventsRaised].eventId = SVA_EVENT_SERVICE_ERROR; + pEventDesc[nbEventsRaised].serviceId = serviceId; + pEventDesc[nbEventsRaised].bufferId = INVALID_BUFFER_ID; + pEventDesc[nbEventsRaised].eventTimestamp = (t_sva_timestamp_value) eventTimestamp; + pEventDesc[nbEventsRaised].eventDate = (t_sva_timestamp_value) eventDate; + pEventDesc[nbEventsRaised].extraInfo=0; + + nbEventsRaised++; + /*update state machine*/ + sva_DP_UpdateInstanceStatesMachine(instanceNum,SVA_DP_EVENT_ERROR); + break; + + case SVA_TM_FAKE_HW_EVENT: + + CHECK_TABLE_OVERFLOW(nbEventsRaised, maxOfEvent, SVA_INTERNAL_POSTPROCESSOR_ERROR); + + if (pDesc->state == SVA_DP_FLUSHING_IN) { + pEventDesc[nbEventsRaised].eventId = SVA_EVENT_SERVICE_FLUSHED_IN; + } + if (pDesc->state == SVA_DP_FLUSHING_OUT) { + pEventDesc[nbEventsRaised].eventId = SVA_EVENT_SERVICE_FLUSHED_OUT; + } + + pEventDesc[nbEventsRaised].serviceId = serviceId; + pEventDesc[nbEventsRaised].bufferId = INVALID_BUFFER_ID; + pEventDesc[nbEventsRaised].eventTimestamp = (t_sva_timestamp_value) eventTimestamp; + pEventDesc[nbEventsRaised].eventDate = (t_sva_timestamp_value) eventDate; + pEventDesc[nbEventsRaised].extraInfo=0; + nbEventsRaised++; + /*update state machine*/ + sva_DP_UpdateInstanceStatesMachine(instanceNum,SVA_DP_EVENT_FAKE); + break; + + case SVA_TM_EOT_HW_EVENT: + /* can be either : + * - SVA_EVENT_POSTPROCESSOR_ALT_SYNCHRO + * - SVA_EVENT_POSTPROCESSOR_SYNCHRO + * - SVA_EVENT_BUFFER_VOIDED + * - SVA_EVENT_BUFFER_FILLED + */ + + if(pDesc->pipActivated == SVA_DP_PIP_RUNNING) + { + + if(READ_FIFO_ELEM(pDesc->pipSubtasksFifos.inUseFifo, t_sva_dp_pip_subtask_id, pipSubtaskId)!=SVA_FIFO_EMPTY) + { + if(pipSubtaskId.secSubtaskId[pDesc->pipPieceCounter-2]==subtaskId) + { + POP_FIFO_ELEM(pDesc->pipSubtasksFifos.inUseFifo, t_sva_dp_pip_subtask_id, pipSubtaskId); + subtaskId = pipSubtaskId.primarySubtaskId; + + pipSubtaskId.primarySubtaskId = 0xAAAAAAAA; + ffError = PUSH_FIFO_ELEM(pDesc->pipSubtasksFifos.pushFifo, t_sva_dp_pip_subtask_id, pipSubtaskId); + + } + + } + else + { + //? + } + + } + else if(pDesc->pipActivated == SVA_DP_PIP_DELETION) + { + if(READ_FIFO_ELEM(pDesc->pipSubtasksFifos.inUseFifo, t_sva_dp_pip_subtask_id, pipSubtaskId)!=SVA_FIFO_EMPTY) + { + + if(pipSubtaskId.secSubtaskId[pDesc->pipPieceCounter-2]==subtaskId) + { + POP_FIFO_ELEM(pDesc->pipSubtasksFifos.inUseFifo, t_sva_dp_pip_subtask_id, pipSubtaskId); + subtaskId = pipSubtaskId.primarySubtaskId; + + } + + } + else + { + + while (POP_FIFO_ELEM(pDesc->pipSubtasksFifos.pushFifo,t_sva_dp_pip_subtask_id,pipSubtaskId )!=SVA_FIFO_EMPTY) + { + + } + pDesc->pipActivated = SVA_DP_NO_PIP; + + //FIXME: is it correct to delete PIP subtasks here? + if(pDesc->is_ppp_tiling) { + t_uint32 i; + for(i=0;i<(pDesc->pipPieceCounter-1)*pDesc->nbSubtasks;i++){ + tmError=sva_TM_DeleteSubTask(pDesc->pipSubtasksIdArrayNoSynchro[i]); + if (tmError!=SVA_TM_OK) {return SVA_INTERNAL_POSTPROCESSOR_ERROR;} + } + } + pDesc->is_ppp_tiling = FALSE; + } + } + + + + /* + * Look for index in SubtaskListArray corresponding to subtaskId + * Only used for EOT event + */ + if ((eventId != SVA_TM_EOK_HW_EVENT) && (subtaskId != INVALID_SUBTASK_ID)) + { + /* Search the instance number of the given subtaskId */ + do + { + if (displayDesc[instanceNum].state != SVA_DP_NOT_INITIALIZED) + { + for (subtaskIndex=0; subtaskIndex < displayDesc[instanceNum].nbSubtasks && isFound==FALSE; subtaskIndex++) + { + if (displayDesc[instanceNum].subtasksIdArray[subtaskIndex] == subtaskId) + { + isFound = TRUE; + } + } + + } + } + while (!isFound && ++instanceNum < NUM_MAX_POSTPROCESSOR); + } + + if (instanceNum >= NUM_MAX_POSTPROCESSOR) {return SVA_INTERNAL_POSTPROCESSOR_ERROR;} + + + if (pConf->isDirectScreenAccess) { + CHECK_TABLE_OVERFLOW(nbEventsRaised, maxOfEvent, SVA_INTERNAL_POSTPROCESSOR_ERROR); + pEventDesc[nbEventsRaised].serviceId = serviceId; + pEventDesc[nbEventsRaised].bufferId = INVALID_BUFFER_ID; + pEventDesc[nbEventsRaised].eventTimestamp = (t_sva_timestamp_value) eventTimestamp; + pEventDesc[nbEventsRaised].eventDate = (t_sva_timestamp_value) eventDate; + + if (pConf->isDoubleBufferMode && ((subtaskIndex-1)%2) == 1) + { + pEventDesc[nbEventsRaised].eventId = SVA_EVENT_POSTPROCESSOR_ALT_SYNCHRO; + } + else {pEventDesc[nbEventsRaised].eventId = SVA_EVENT_POSTPROCESSOR_SYNCHRO;} + nbEventsRaised++; + } + + { + t_sva_dp_subtask_dependencies subtaskDep; + t_sva_dpl_param_inout paramInOut; + + tmError=sva_TM_GetSubTaskField(subtaskId, SVA_TM_DIS_ADDR_OUT_FRAME_PARAMETERS,(t_logical_address) ¶mInOut, + 0, sizeof(t_sva_dpl_param_inout), FALSE); + HCL_DEBUG_ASSERT(tmError==SVA_TM_OK); + + pDesc->status.isAceEnable=(pDesc->confHandle.currentConf.aceMode!=SVA_POSTPROCESSOR_ACE_DISABLE)?TRUE:FALSE; + pDesc->status.aceOffset.ace_offset_0=paramInOut.ace_offset0; + pDesc->status.aceOffset.ace_offset_1=paramInOut.ace_offset1; + pDesc->status.aceOffset.ace_offset_2=paramInOut.ace_offset2; + pDesc->status.aceOffset.ace_offset_3=paramInOut.ace_offset3; + + /* + * A subtask has ended so we have to resolve its dependency for its next execution + */ + subtaskDep.subtaskId = subtaskId; + + subtaskDep.dependencies = pDesc->defaultConfiguredDependency; + ffError = PUSH_FIFO_ELEM(pDesc->subtasksDependencyFifo, t_sva_dp_subtask_dependencies, subtaskDep); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + + /* + * Generate all the events linked with the EOT + */ + if (subtaskDep.dependencies.inputImageDep == (t_bitfield)NOT_RESOLVED_DEPENDENCY) + { + pDesc->nbInputImagesPostProcessed++; + pDesc->status.eventStats.voidedCounter++; + + CHECK_TABLE_OVERFLOW(nbEventsRaised, maxOfEvent, SVA_INTERNAL_POSTPROCESSOR_ERROR); + pEventDesc[nbEventsRaised].eventId = SVA_EVENT_BUFFER_VOIDED; + pEventDesc[nbEventsRaised].serviceId = serviceId; + pEventDesc[nbEventsRaised].eventTimestamp = (t_sva_timestamp_value) eventTimestamp; + pEventDesc[nbEventsRaised].eventDate = (t_sva_timestamp_value) eventDate; + + + /* Get bufferId: */ + ffError = POP_FIFO_ELEM(pDesc->inputImageFifos.inUseFifo,t_sva_buffer_id,pEventDesc[nbEventsRaised].bufferId); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + + + sva_BM_UpdateBufferStatus(pEventDesc[nbEventsRaised].bufferId,SVA_BUFFER_VOIDED,eventTimestamp); + + nbEventsRaised++; + + if (subtaskDep.dependencies.inputParamsDep == (t_bitfield)NOT_RESOLVED_DEPENDENCY) + { + pDesc->status.eventStats.voidedCounter++; + + CHECK_TABLE_OVERFLOW(nbEventsRaised, maxOfEvent, SVA_INTERNAL_POSTPROCESSOR_ERROR); + pEventDesc[nbEventsRaised].eventId = SVA_EVENT_BUFFER_VOIDED; + pEventDesc[nbEventsRaised].serviceId = serviceId; + pEventDesc[nbEventsRaised].eventTimestamp = (t_sva_timestamp_value) eventTimestamp; + pEventDesc[nbEventsRaised].eventDate = (t_sva_timestamp_value) eventDate; + + /* Get bufferId: */ + ffError = POP_FIFO_ELEM(pDesc->inputParamsFifos.inUseFifo,t_sva_buffer_id,pEventDesc[nbEventsRaised].bufferId); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + + sva_BM_UpdateBufferStatus(pEventDesc[nbEventsRaised].bufferId,SVA_BUFFER_VOIDED,eventTimestamp); + + + nbEventsRaised++; + } + } + + if (subtaskDep.dependencies.outputImageDep == (t_bitfield)NOT_RESOLVED_DEPENDENCY) + { + + pDesc->nbOutputImagesDisplayed++; + pDesc->status.eventStats.filledCounter++; + CHECK_TABLE_OVERFLOW(nbEventsRaised, maxOfEvent, SVA_INTERNAL_POSTPROCESSOR_ERROR); + pEventDesc[nbEventsRaised].eventId = SVA_EVENT_BUFFER_FILLED; + pEventDesc[nbEventsRaised].serviceId = serviceId; + pEventDesc[nbEventsRaised].eventTimestamp = (t_sva_timestamp_value) eventTimestamp; + pEventDesc[nbEventsRaised].eventDate = (t_sva_timestamp_value) eventDate; + + /* Get bufferId */ + ffError=POP_FIFO_ELEM(pDesc->outputImageFifos.inUseFifo, t_sva_buffer_id,pEventDesc[nbEventsRaised].bufferId); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + + sva_BM_UpdateBufferStatus(pEventDesc[nbEventsRaised].bufferId,SVA_BUFFER_FILLED,eventTimestamp); + + nbEventsRaised++; + } + } + break; + case SVA_TM_EOK_HW_EVENT : + + if (pDesc->state==SVA_DP_STOP_REQUESTED) + { + /*generate a stop event*/ + CHECK_TABLE_OVERFLOW(nbEventsRaised, maxOfEvent, SVA_INTERNAL_POSTPROCESSOR_ERROR); + pEventDesc[nbEventsRaised].eventId = SVA_EVENT_SERVICE_STOPPED; + pEventDesc[nbEventsRaised].serviceId = serviceId; + pEventDesc[nbEventsRaised].bufferId = INVALID_BUFFER_ID; + pEventDesc[nbEventsRaised].eventTimestamp = (t_sva_timestamp_value) eventTimestamp; + pEventDesc[nbEventsRaised].eventDate = (t_sva_timestamp_value) eventDate; + pEventDesc[nbEventsRaised].extraInfo=0; + nbEventsRaised++; + isUpdateStateNeed=TRUE; + } + + if (pDesc->change_ppp_tiling && (pDesc->pipActivated == SVA_DP_PIP_RUNNING) ){ + //remove subtasks from the FIFO. and delete those subtasks. + t_sva_error status = sva_DP_DoFlushIn(serviceId); + if (status != SVA_OK) + { + } + + while (POP_FIFO_ELEM(pDesc->pipSubtasksFifos.pushFifo,t_sva_dp_pip_subtask_id,pipSubtaskId )!=SVA_FIFO_EMPTY) + { + } + + if(pDesc->is_ppp_tiling) { + t_uint32 i; + for(i=0;i<(pDesc->pipPieceCounter-1)*pDesc->nbSubtasks;i++){ + tmError = sva_TM_DeleteSubTask(pDesc->pipSubtasksIdArrayNoSynchro[i]); + if (tmError!=SVA_TM_OK) { + return SVA_INTERNAL_POSTPROCESSOR_ERROR; + }else{ + pDesc->pipSubtasksIdArrayNoSynchro[i] = 0; + } + } + } + pDesc->is_ppp_tiling = FALSE; + } + + if (GET_FIFO_NB_ELEMS(pDesc->subtasksDependencyFifo)==pDesc->nbSubtasks) + { + t_sva_dp_subtask_dependencies subtaskDep; + subtaskDep.subtaskId = subtaskId; + + ffError = READ_FIFO_ELEM(pDesc->subtasksDependencyFifo, t_sva_dp_subtask_dependencies, subtaskDep); + + if (subtaskDep.dependencies.outputImageDep == (t_bitfield)NOT_RESOLVED_DEPENDENCY) + { + + CHECK_TABLE_OVERFLOW(nbEventsRaised, maxOfEvent, SVA_INTERNAL_POSTPROCESSOR_ERROR); + pEventDesc[nbEventsRaised].eventId = SVA_EVENT_OVERFLOW; + pEventDesc[nbEventsRaised].serviceId = serviceId; + pEventDesc[nbEventsRaised].bufferId = INVALID_BUFFER_ID; + pEventDesc[nbEventsRaised].eventTimestamp = (t_sva_timestamp_value) eventTimestamp; + pEventDesc[nbEventsRaised].eventDate = (t_sva_timestamp_value) eventDate; + pEventDesc[nbEventsRaised].extraInfo=0; + nbEventsRaised++; + + /*update status*/ + pDesc->status.eventStats.overflowCounter++; + isUpdateStateNeed=TRUE; + } + + if (subtaskDep.dependencies.inputImageDep == (t_bitfield)NOT_RESOLVED_DEPENDENCY) + { + CHECK_TABLE_OVERFLOW(nbEventsRaised, maxOfEvent, SVA_INTERNAL_POSTPROCESSOR_ERROR); + pEventDesc[nbEventsRaised].eventId = SVA_EVENT_UNDERFLOW; + pEventDesc[nbEventsRaised].serviceId = serviceId; + pEventDesc[nbEventsRaised].bufferId = INVALID_BUFFER_ID; + pEventDesc[nbEventsRaised].eventTimestamp = (t_sva_timestamp_value) eventTimestamp; + pEventDesc[nbEventsRaised].eventDate = (t_sva_timestamp_value) eventDate; + pEventDesc[nbEventsRaised].extraInfo=0; + nbEventsRaised++; + + /*update status*/ + pDesc->status.eventStats.underflowCounter++; + isUpdateStateNeed=TRUE; + } + } + if(isUpdateStateNeed==TRUE) + sva_DP_UpdateInstanceStatesMachine(instanceNum,SVA_DP_EVENT_EOK); + break; + default: + break; + } + + + /*try to solve some dependencies*/ + sva_DP_ResolveDependencies(instanceNum); + + /*return number of generated events*/ + *pNbEvent=nbEventsRaised; + + + return SVA_OK; +} + +/****************************************************************************/ +/* NAME: t_sva_error sva_DP_ProvideInternalNeeds ( */ +/* t_sva_service_id serviceId */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine allows to end the configuration of the service */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - serviceId: identifier of the service */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_sva_error sva_DP_ProvideInternalNeeds( t_sva_service_id serviceId) +{ + t_sva_dp_error status; + t_sva_service_instance_num instanceNum = READ_INSTANCE_NUM_IN_SERVICE_ID(serviceId); + t_sva_dp_descriptor *pDesc=&displayDesc[instanceNum]; + t_sva_postprocessor_configuration *pConf=&pDesc->confHandle.currentConf; + t_sva_ff_error ffError; + t_sva_tm_error tmError; + t_sva_dpl_param_in paramInBuffer; + t_sva_dpl_param_inout paramInOutBuffer; + t_sva_dpl_frame_buffer_out bufferOut; + t_sva_error svaError; + t_uint32 i; + t_physical_address tempBlockPhyAddress = NULL; + t_sva_dpl_internal_buf internalBuffer; + + /*check for service id validity*/ + status=sva_DP_CheckServiceId(serviceId); + if (status!=SVA_DP_OK) {return SVA_INTERNAL_POSTPROCESSOR_ERROR;} + + /*check that transition is allowed*/ + if (sva_DP_isTransitionValid(instanceNum,SVA_DP_INTERNAL_NEEDS)==FALSE) {return SVA_INTERNAL_POSTPROCESSOR_ERROR;} + + /*provide some memory to event management*/ + svaError=sva_EM_ProvideInternalNeeds(serviceId); + if (svaError!=SVA_OK) {return SVA_INTERNAL_POSTPROCESSOR_ERROR;} + + + /* create fifo: it depends on pDependencies because it is stored here the number and the type of fifo to be created */ + /* ------------------------- */ + /* inputImage */ + { + t_sva_dp_fifo_dep *pFifos = &pDesc->inputImageFifos; + t_sva_dp_fifo_dep *pTimestampFifos = &pDesc->inputTimestampsFifos; + + CREATE_FIFO(t_sva_buffer_id, DPB_PUSH_FIFO_DEFAULT_SIZE, pFifos->pushFifo, ffError); + if (ffError != SVA_FIFO_OK) {return SVA_INTERNAL_POSTPROCESSOR_ERROR;} + + CREATE_FIFO(t_sva_buffer_id, pDesc->nbSubtasks, pFifos->inUseFifo, ffError); + if (ffError != SVA_FIFO_OK) {return SVA_INTERNAL_POSTPROCESSOR_ERROR;} + + CREATE_FIFO(t_sva_tm_timestamp, DPB_PUSH_FIFO_DEFAULT_SIZE, pTimestampFifos->pushFifo, ffError); + if (ffError != SVA_FIFO_OK) {return SVA_INTERNAL_POSTPROCESSOR_ERROR;} + + + } + /* params buffer (optional) */ + if ( + pDesc->confHandle.currentConf.deringingFilterMode != SVA_NONE_DERINGING_FILTER + || pDesc->confHandle.currentConf.deblockingFilterMode != SVA_NONE_DEBLOCKING_FILTER + || pDesc->confHandle.currentConf.aceMode == SVA_POSTPROCESSOR_ACE_EXTERNAL + ) + { + t_sva_dp_fifo_dep *pFifos = &pDesc->inputParamsFifos; + CREATE_FIFO(t_sva_buffer_id, DPB_PUSH_FIFO_DEFAULT_SIZE, pFifos->pushFifo, ffError); + if (ffError != SVA_FIFO_OK) {return SVA_INTERNAL_POSTPROCESSOR_ERROR;} + + CREATE_FIFO(t_sva_buffer_id, pDesc->nbSubtasks, pFifos->inUseFifo, ffError); + if (ffError != SVA_FIFO_OK) {return SVA_INTERNAL_POSTPROCESSOR_ERROR;} + } + + /* output image (optional) */ + if (!pDesc->confHandle.currentConf.isDirectScreenAccess) + { + t_sva_dp_fifo_dep *pFifos = &pDesc->outputImageFifos; + CREATE_FIFO(t_sva_buffer_id,PUSH_FIFO_DEFAULT_SIZE+3+pDesc->nbSubtasks, pFifos->pushFifo, ffError); + if (ffError != SVA_FIFO_OK) {return SVA_INTERNAL_POSTPROCESSOR_ERROR;} + + CREATE_FIFO(t_sva_buffer_id, pDesc->nbSubtasks, pFifos->inUseFifo, ffError); + if (ffError != SVA_FIFO_OK) {return SVA_INTERNAL_POSTPROCESSOR_ERROR;} + } + + /* subtasks */ + CREATE_FIFO(t_sva_dp_subtask_dependencies, pDesc->nbSubtasks, pDesc->subtasksDependencyFifo, ffError); + if (ffError != SVA_FIFO_OK) {return SVA_INTERNAL_POSTPROCESSOR_ERROR;} + + + /* PIP: Create Fifo for PIP Subtasks even if PIP is not used */ + { + t_sva_dp_fifo_dep *pFifos = &pDesc->pipSubtasksFifos; + CREATE_FIFO(t_sva_dp_pip_subtask_id, pDesc->nbPipSubtasks,pFifos->pushFifo, ffError); + if (ffError != SVA_FIFO_OK) {return SVA_INTERNAL_POSTPROCESSOR_ERROR;} + + CREATE_FIFO(t_sva_dp_pip_subtask_id, pDesc->nbPipSubtasks,pFifos->inUseFifo, ffError); + if (ffError != SVA_FIFO_OK) {return SVA_INTERNAL_POSTPROCESSOR_ERROR;} + + } + + + /* Create subtasks */ + /* ---------------- */ + + status = sva_DP_CreateSubTasksDescriptors(serviceId, pConf, &pDesc->subtasksListId); + if (status != SVA_DP_OK) {return SVA_INTERNAL_POSTPROCESSOR_ERROR;} + + /* enable events for sub task list */ + /* we enable EOT, ERR and EOK ... events */ + /* ------------------------------------- */ + + tmError=sva_TM_DisableAllVirtualHwEvents(pDesc->subtasksListId); + if (tmError != SVA_TM_OK) {return SVA_INTERNAL_POSTPROCESSOR_ERROR;} + tmError=sva_TM_EnableVirtualHwEvents(pDesc->subtasksListId,SVA_TM_EOT_HW_EVENT); + if (tmError != SVA_TM_OK) {return SVA_INTERNAL_POSTPROCESSOR_ERROR;} + tmError=sva_TM_EnableVirtualHwEvents(pDesc->subtasksListId,SVA_TM_ERR_HW_EVENT); + if (tmError != SVA_TM_OK) {return SVA_INTERNAL_POSTPROCESSOR_ERROR;} + tmError=sva_TM_EnableVirtualHwEvents(pDesc->subtasksListId,SVA_TM_EOK_HW_EVENT); + if (tmError != SVA_TM_OK) {return SVA_INTERNAL_POSTPROCESSOR_ERROR;} + tmError=sva_TM_EnableVirtualHwEvents(pDesc->subtasksListId,SVA_TM_INACTIVE_HW_EVENT); + if (tmError != SVA_TM_OK) {return SVA_INTERNAL_POSTPROCESSOR_ERROR;} + tmError=sva_TM_EnableVirtualHwEvents(pDesc->subtasksListId,SVA_TM_ACTIVE_HW_EVENT); + if (tmError != SVA_TM_OK) {return SVA_INTERNAL_POSTPROCESSOR_ERROR;} + tmError=sva_TM_EnableVirtualHwEvents(pDesc->subtasksListId,SVA_TM_FAKE_HW_EVENT); + if (tmError != SVA_TM_OK) {return SVA_INTERNAL_POSTPROCESSOR_ERROR;} + tmError=sva_TM_EnableVirtualHwEvents(pDesc->subtasksListId,SVA_TM_ABORT_HW_EVENT); + if (tmError != SVA_TM_OK) {return SVA_INTERNAL_POSTPROCESSOR_ERROR;} + + + /* + * Initialize the param_in structure + */ + + status = sva_DP_BuildParamInStructure(pConf, ¶mInBuffer); + if (status != SVA_DP_OK) {return SVA_INTERNAL_POSTPROCESSOR_ERROR;} + + for (i=0; inbSubtasks; i++) { + tmError = sva_TM_InitSubTaskField(pDesc->subtasksIdArray[i], + SVA_TM_DIS_ADDR_IN_PARAMETERS, + (t_logical_address) ¶mInBuffer, + sizeof(t_sva_dpl_param_in)); + + if (tmError != SVA_TM_OK) {return SVA_INTERNAL_POSTPROCESSOR_ERROR;} + } + + + /* + * Initialize dspl_frame_out, only in case of DSA + */ + + + if (pDesc->confHandle.currentConf.isDirectScreenAccess) + { + /* + * There are 2 cases : + * (1) we are in single buffer mode, so all subtasks have the same output buffers + * + * (2) we are in double buffer mode, so we alternate between the both buffers one task per two + * we reference it alternatively + */ + + if (!pConf->isDoubleBufferMode) + { + bufferOut.addr_dest_buffer = pConf->screenFrameBufferBaseAddr; + + for (i=0; inbSubtasks; i++) + { + tmError = sva_TM_InitSubTaskField(pDesc->subtasksIdArray[i],SVA_TM_DIS_ADDR_OUT_FRAME_BUFFER,(t_logical_address) &bufferOut, sizeof(t_sva_dpl_frame_buffer_out)>>2); + if (tmError != SVA_TM_OK) {return SVA_INTERNAL_POSTPROCESSOR_ERROR;} + + } + + } + else + { + for (i=0; inbSubtasks; i++) + { + bufferOut.addr_dest_buffer = ((i%2)==0)?pConf->screenFrameBufferBaseAddr:pConf->screenAlternateFrameBufferBaseAddr; + tmError = sva_TM_InitSubTaskField(pDesc->subtasksIdArray[i],SVA_TM_DIS_ADDR_OUT_FRAME_BUFFER,(t_logical_address) &bufferOut, sizeof(t_sva_dpl_frame_buffer_out)); + if (tmError != SVA_TM_OK) {return SVA_INTERNAL_POSTPROCESSOR_ERROR;} + + } + } + + } + + /* + * Initialize Inout params + */ + + paramInOutBuffer.ace_offset0 = 0; + paramInOutBuffer.ace_offset1 = 0; + paramInOutBuffer.ace_offset2 = 0; + paramInOutBuffer.ace_offset3 = 0; + + /* paramInOut buffer configuration: ACE */ + + for (i=0; inbSubtasks; i++) { + tmError = sva_TM_InitSubTaskField(pDesc->subtasksIdArray[i], + SVA_TM_DIS_ADDR_IN_FRAME_PARAMETERS, + (t_logical_address) ¶mInOutBuffer, + sizeof(t_sva_dpl_param_inout)); + + if (tmError != SVA_TM_OK) {return SVA_INTERNAL_POSTPROCESSOR_ERROR;} + } + + + /* + * Alloc temporary block in case transformId = SVA_POSTPROCESSOR_YUV420PL_TO_RGB or SVA_POSTPROCESSOR_YUV420MB_TO_YUV420MB + * also in case of SVA_POSTPROCESSOR_YUV420PL_TO_YUV422PL and SVA_POSTPROCESSOR_YUV422PL_TO_RGB + * and SVA_POSTPROCESSOR_YUV420MB_TO_YUV420_SEP_COMP_MB, SVA_POSTPROCESSOR_YUV420MB_TO_YUV422_SEP_COMP_MB + + */ + + if((pConf->transformId == SVA_POSTPROCESSOR_YUV420PL_TO_RGB) + ||(pConf->transformId == SVA_POSTPROCESSOR_YUV420MB_TO_YUV420MB) + ||(pConf->transformId ==SVA_POSTPROCESSOR_YUV420PL_TO_YUV422PL) + ||(pConf->transformId ==SVA_POSTPROCESSOR_YUV422PL_TO_RGB) + ||(pConf->transformId ==SVA_POSTPROCESSOR_YUV420MB_TO_YUV420_SEP_COMP_MB) + ||(pConf->transformId ==SVA_POSTPROCESSOR_YUV420MB_TO_YUV422_SEP_COMP_MB)) + { + t_uint32 memSize; + t_sva_mm_error mmError; + t_sva_block_id tempBlockId; + + + /* alloc block */ + if ((pConf->transformId == SVA_POSTPROCESSOR_YUV420PL_TO_RGB) + ||(pConf->transformId ==SVA_POSTPROCESSOR_YUV420PL_TO_YUV422PL) + ||(pConf->transformId ==SVA_POSTPROCESSOR_YUV422PL_TO_RGB)) + { + memSize = (pConf->sourceFrameDesc.frame.width * pConf->sourceFrameDesc.frame.height * 3)>>1; + } + else //if (pConf->transformId == SVA_POSTPROCESSOR_YUV420MB_TO_YUV420MB) or SVA_POSTPROCESSOR_YUV420MB_TO_YUV422_SEP_COMP_MB or SVA_POSTPROCESSOR_YUV420MB_TO_YUV420_SEP_COMP_MB + { + memSize = (pConf->videoFrameBufferDesc.frame.width*pConf->videoFrameBufferDesc.frame.height) << 1; + } + + mmError = sva_MM_AllocBlock(SDRAM_ID, memSize, SVA_MM_ALIGN_256BYTES, &tempBlockId); + if (mmError != SVA_MM_OK) {return SVA_INTERNAL_POSTPROCESSOR_ERROR;} + + pDesc->tempBlockId = tempBlockId; + + sva_MM_GetBlockPhysicalAddress(pDesc->tempBlockId, &tempBlockPhyAddress); + + + { + + t_logical_address logAddr; + t_uint8 * ptr, * ptrEnd; + + sva_MM_GetBlockLogicalAddress(pDesc->tempBlockId, &logAddr); + ptr = (t_uint8*)logAddr; + ptrEnd = ptr + memSize; + + /* reset block */ + while(ptr < ptrEnd) + { + *ptr++ = 0; + } + } + + + + } + /* prog dspl_int_buff in all cases because must be initialised even when unused*/ + internalBuffer.addr_temp_buffer = tempBlockPhyAddress; + for(i=0; inbSubtasks; i++) + { + + tmError=sva_TM_InitSubTaskField(pDesc->subtasksIdArray[i],SVA_TM_DIS_ADDR_INTERNAL_BUFFER,(t_uint32)&internalBuffer,sizeof(t_sva_dpl_internal_buf)); + HCL_DEBUG_ASSERT(tmError==SVA_TM_OK); + + } + + + + /* + * Default dependancies + */ + + + pDesc->defaultConfiguredDependency.inputImageDep = (t_bitfield)NOT_RESOLVED_DEPENDENCY; + + + /* input params needs */ + if ( + pDesc->confHandle.currentConf.deringingFilterMode != SVA_NONE_DERINGING_FILTER + || pDesc->confHandle.currentConf.deblockingFilterMode != SVA_NONE_DEBLOCKING_FILTER + || pDesc->confHandle.currentConf.aceMode == SVA_POSTPROCESSOR_ACE_EXTERNAL + ) + { + + pDesc->defaultConfiguredDependency.inputParamsDep = (t_bitfield)NOT_RESOLVED_DEPENDENCY; + } + else { + pDesc->defaultConfiguredDependency.inputParamsDep = (t_bitfield)INTERNAL_DEPENDENCY; + } + + + + /* output image buffer needs */ + if (!pDesc->confHandle.currentConf.isDirectScreenAccess) + { + + pDesc->defaultConfiguredDependency.outputImageDep = (t_bitfield)NOT_RESOLVED_DEPENDENCY; + } + else { + pDesc->defaultConfiguredDependency.outputImageDep = (t_bitfield)INTERNAL_DEPENDENCY; + } + + + + + /* Push subtask in subtasksDependencyFifo since they are ready to be solved*/ + for(i=0;inbSubtasks;i++) + { + t_sva_dp_subtask_dependencies subtaskDep; + + subtaskDep.subtaskId=pDesc->subtasksIdArray[i]; + subtaskDep.dependencies=pDesc->defaultConfiguredDependency; + ffError=PUSH_FIFO_ELEM(pDesc->subtasksDependencyFifo, t_sva_dp_subtask_dependencies, subtaskDep); + if (ffError!=SVA_FIFO_OK) {return SVA_INTERNAL_POSTPROCESSOR_ERROR;} + } + + + + /* Update the state machine */ + sva_DP_UpdateInstanceStatesMachine(instanceNum,SVA_DP_INTERNAL_NEEDS); + + return SVA_OK; +} + + +/****************************************************************************/ +/* NAME: t_sva_error sva_DP_GetInternalNeeds ( */ +/* t_sva_service_id serviceId */ +/* t_size* pSize */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine returns the size of the memory needed for Display */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - serviceId: identifier of the service */ +/* - pSize: size needed */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_dp_error */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_sva_error sva_DP_GetInternalNeeds(t_sva_service_id serviceId, t_size * pSize) +{ + + t_sva_dp_error status; + t_uint8 standardPushFifoNum = 0; + t_uint8 standardInUseFifoNum = 0; + t_uint8 extendedPushFifoNum=0; + t_uint8 timestampedBufferIdFifoNum = 0; + t_size fifoSize; + t_uint8 defaultSubtasksNb; + + t_sva_service_instance_num instanceNum = READ_INSTANCE_NUM_IN_SERVICE_ID(serviceId); + t_sva_dp_descriptor *pDesc=&displayDesc[instanceNum]; + t_sva_error svaError; + + + /*check for service id validity*/ + status=sva_DP_CheckServiceId(serviceId); + if (status!=SVA_DP_OK) {return SVA_INTERNAL_POSTPROCESSOR_ERROR;} + + /*check pointer validity*/ + HCL_ASSERT(pSize!=0); + + /*compute memory size need*/ + *pSize = 0; + + + defaultSubtasksNb = (t_uint8)(SUBTASK_DEFAULT_NUMBER % 2); + /* memory size needed is dependant on configuration */ + if (pDesc->confHandle.currentConf.isDoubleBufferMode == TRUE) { + if (defaultSubtasksNb!=0) {pDesc->nbSubtasks = (t_uint8)(SUBTASK_DEFAULT_NUMBER*2);} + else { pDesc->nbSubtasks = (t_uint8)(SUBTASK_DEFAULT_NUMBER);} + } + else {pDesc->nbSubtasks = SUBTASK_DEFAULT_NUMBER;} + + + /* PIP: Even if PIP is not used */ + //pDesc->nbPipSubtasks = 3 * pDesc->nbSubtasks; + pDesc->nbPipSubtasks = (DISPLAY_NB_MAX_OF_PIP_PIECE-1) * pDesc->nbSubtasks; + + /* Input image needs */ + timestampedBufferIdFifoNum++; /* PushFifo */ + standardPushFifoNum++; /* PushFifo */ + standardInUseFifoNum++; /* inUseFifo */ + + /* Input params needs */ + if ( + pDesc->confHandle.currentConf.deringingFilterMode != SVA_NONE_DERINGING_FILTER + || pDesc->confHandle.currentConf.deblockingFilterMode != SVA_NONE_DEBLOCKING_FILTER + || pDesc->confHandle.currentConf.aceMode == SVA_POSTPROCESSOR_ACE_EXTERNAL + ) + { + standardPushFifoNum++; /* pushFifo */ + standardInUseFifoNum++; /* inUseFifo */ + } + + /* Output image buffer needs */ + if (!pDesc->confHandle.currentConf.isDirectScreenAccess) + { + extendedPushFifoNum++; /* pushFifo */ + standardInUseFifoNum++; /* inUseFifo */ + } + + + /*memory need by event management*/ + svaError=sva_EM_GetInternalNeeds(&fifoSize); + if (svaError!=SVA_OK) {return SVA_INTERNAL_POSTPROCESSOR_ERROR;} + + *pSize = fifoSize; + + + /* PIP: Even if PIP is not used */ + GET_FIFO_MEMORY_NEEDS(t_sva_dp_pip_subtask_id, pDesc->nbPipSubtasks, fifoSize); + *pSize += 2*fifoSize; /* 2 because Push + inUse */ + + + /* total fifo creation */ + GET_FIFO_MEMORY_NEEDS(t_sva_dp_subtask_dependencies, pDesc->nbSubtasks, fifoSize); + *pSize += fifoSize; + + if (timestampedBufferIdFifoNum != 0) + { + /* timestamped push fifo size computation */ + GET_FIFO_MEMORY_NEEDS(t_sva_timestamped_buffer_id, DPB_PUSH_FIFO_DEFAULT_SIZE, fifoSize); + *pSize += timestampedBufferIdFifoNum * fifoSize; + } + + if (standardPushFifoNum != 0) + { + /* standard push fifo size computation */ + GET_FIFO_MEMORY_NEEDS(t_sva_buffer_id, DPB_PUSH_FIFO_DEFAULT_SIZE, fifoSize); + *pSize += standardPushFifoNum * fifoSize; + } + + if (extendedPushFifoNum != 0) + { + /* standard push fifo size computation */ + GET_FIFO_MEMORY_NEEDS(t_sva_buffer_id, PUSH_FIFO_DEFAULT_SIZE+3+pDesc->nbSubtasks, fifoSize); + *pSize += extendedPushFifoNum * fifoSize; + } + + if (standardInUseFifoNum != 0) + { + /* in use fifo size computation */ + GET_FIFO_MEMORY_NEEDS(t_sva_buffer_id, pDesc->nbSubtasks, fifoSize); + *pSize += standardInUseFifoNum * fifoSize; + } + + + + return svaError; +} + + + + + +/****************************************************************************/ +/* NAME: t_sva_error sva_DP_Activate ( */ +/* t_sva_service_id serviceId */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine activates the DISPLAY service */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - serviceId: identifier of the service */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_sva_error sva_DP_Activate(t_sva_service_id serviceId, t_sva_service_mode serviceMode, t_sva_fw_id *pFwId) +{ + + + t_sva_service_instance_num instanceNum = READ_INSTANCE_NUM_IN_SERVICE_ID(serviceId); + t_sva_dp_descriptor *pDesc=&displayDesc[instanceNum]; + t_sva_error status; + t_sva_dp_error dpError; + + /*check for service id validity*/ + dpError=sva_DP_CheckServiceId(serviceId); + if (dpError!=SVA_DP_OK) {return SVA_INTERNAL_POSTPROCESSOR_ERROR;} + + /*check that transition is allowed*/ + if (sva_DP_isTransitionValid(instanceNum,SVA_DP_ACTIVATE)==FALSE) {return SVA_INTERNAL_POSTPROCESSOR_ERROR;} + + /* Update the state machine */ + /* Update state machine before command is send to task management to avoid race condition */ + sva_DP_UpdateInstanceStatesMachine(instanceNum,SVA_DP_ACTIVATE); + + /*activate subTaskList*/ + status=sva_TM_ActivateSubTaskList(pDesc->subtasksListId,serviceMode,pFwId); + if (status != SVA_OK && status != SVA_FW_SWITCH_OCCURED && status != SVA_FW_SWITCH_DELAYED) + { + sva_DP_UpdateInstanceStatesMachine(instanceNum,SVA_DP_CANCEL); + + return status; + } + return status; +} + + + +/****************************************************************************/ +/* NAME: t_sva_error sva_DP_Inactivate ( */ +/* t_sva_service_id serviceId */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine deactivates the DISPLAY service */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - serviceId: identifier of the service */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_sva_error sva_DP_Inactivate(t_sva_service_id serviceId) +{ + + t_sva_dp_error status; + t_sva_service_instance_num instanceNum = READ_INSTANCE_NUM_IN_SERVICE_ID(serviceId); + t_sva_dp_descriptor *pDesc=&displayDesc[instanceNum]; + t_sva_tm_error tmError; + + /*check for service id validity*/ + status=sva_DP_CheckServiceId(serviceId); + if (status!=SVA_DP_OK) {return SVA_INTERNAL_POSTPROCESSOR_ERROR;} + + /*check that transition is allowed*/ + if (sva_DP_isTransitionValid(instanceNum,SVA_DP_INACTIVATE)==FALSE) {return SVA_INTERNAL_POSTPROCESSOR_ERROR;} + + /* Update the state machine */ + /* Update state machine before command is send to task management to avoid race condition */ + sva_DP_UpdateInstanceStatesMachine(instanceNum,SVA_DP_INACTIVATE); + + /*inactivate subTaskList*/ + tmError=sva_TM_InActivateSubTaskList(pDesc->subtasksListId); + if (tmError != SVA_TM_OK) + { + sva_DP_UpdateInstanceStatesMachine(instanceNum,SVA_DP_CANCEL); + + return SVA_INTERNAL_POSTPROCESSOR_ERROR; + } + + return SVA_OK; +} + + + + +/****************************************************************************/ +/* NAME: t_sva_error sva_DP_Delete ( */ +/* t_sva_service_id serviceId */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine deletes the DISPLAY service */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - serviceId: identifier of the service */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_sva_error sva_DP_Delete(t_sva_service_id serviceId) +{ + + t_sva_service_instance_num instanceNum = READ_INSTANCE_NUM_IN_SERVICE_ID(serviceId); + t_sva_dp_descriptor *pDesc=&displayDesc[instanceNum]; + t_sva_postprocessor_configuration *pConf=&pDesc->confHandle.currentConf; + t_uint32 i; + t_sva_tm_error tmError; + t_sva_dp_error status; + t_sva_error svaError; + + /*check for service id validity*/ + status=sva_DP_CheckServiceId(serviceId); + if (status!=SVA_DP_OK) {return SVA_INTERNAL_POSTPROCESSOR_ERROR;} + + /*check that transition is allowed*/ + if (sva_DP_isTransitionValid(instanceNum,SVA_DP_CONTROL_DELETE)==FALSE) {return SVA_INTERNAL_POSTPROCESSOR_ERROR;} + + /*check that flush has been done*/ + if (IS_FIFO_EMPTY(pDesc->inputImageFifos.pushFifo)==FALSE) {return SVA_INTERNAL_POSTPROCESSOR_ERROR;} + if (IS_FIFO_EMPTY(pDesc->inputImageFifos.inUseFifo)==FALSE) {return SVA_INTERNAL_POSTPROCESSOR_ERROR;} + + if (IS_FIFO_EMPTY(pDesc->inputTimestampsFifos.pushFifo)==FALSE) {return SVA_INTERNAL_POSTPROCESSOR_ERROR;} + + + if ( + pDesc->confHandle.currentConf.deringingFilterMode != SVA_NONE_DERINGING_FILTER + || pDesc->confHandle.currentConf.deblockingFilterMode != SVA_NONE_DEBLOCKING_FILTER + || pDesc->confHandle.currentConf.aceMode == SVA_POSTPROCESSOR_ACE_EXTERNAL + ) + { + if (IS_FIFO_EMPTY(pDesc->inputParamsFifos.pushFifo)==FALSE) {return SVA_INTERNAL_POSTPROCESSOR_ERROR;} + if (IS_FIFO_EMPTY(pDesc->inputParamsFifos.inUseFifo)==FALSE) {return SVA_INTERNAL_POSTPROCESSOR_ERROR;} + } + + if (!pDesc->confHandle.currentConf.isDirectScreenAccess){ + if (IS_FIFO_EMPTY(pDesc->outputImageFifos.pushFifo)==FALSE) {return SVA_INTERNAL_POSTPROCESSOR_ERROR;} + if (IS_FIFO_EMPTY(pDesc->outputImageFifos.inUseFifo)==FALSE) {return SVA_INTERNAL_POSTPROCESSOR_ERROR;} + } + + + + + /*start to delete. Things to do depend of current state*/ + if (pDesc->state==SVA_DP_WAIT_FOR_ACTIVATE || pDesc->state==SVA_DP_WAIT_FOR_START) + { + /*delete fifos*/ + DELETE_FIFO(pDesc->inputImageFifos.pushFifo); + DELETE_FIFO(pDesc->inputImageFifos.inUseFifo); + DELETE_FIFO(pDesc->inputTimestampsFifos.inUseFifo); + /* PIP*/ + DELETE_FIFO(pDesc->pipSubtasksFifos.pushFifo); + DELETE_FIFO(pDesc->pipSubtasksFifos.inUseFifo); + + DELETE_FIFO(pDesc->subtasksDependencyFifo); + + if ( + pDesc->confHandle.currentConf.deringingFilterMode != SVA_NONE_DERINGING_FILTER + || pDesc->confHandle.currentConf.deblockingFilterMode != SVA_NONE_DEBLOCKING_FILTER + || pDesc->confHandle.currentConf.aceMode == SVA_POSTPROCESSOR_ACE_EXTERNAL + ) + { + DELETE_FIFO(pDesc->inputParamsFifos.pushFifo); + DELETE_FIFO(pDesc->inputParamsFifos.inUseFifo); + } + if (!pDesc->confHandle.currentConf.isDirectScreenAccess){ + DELETE_FIFO(pDesc->outputImageFifos.pushFifo); + DELETE_FIFO(pDesc->outputImageFifos.inUseFifo); + } + + + /*delete subtasklist*/ + tmError=sva_TM_DeleteSubTaskList(pDesc->subtasksListId); + if (tmError!=SVA_TM_OK) {return SVA_INTERNAL_POSTPROCESSOR_ERROR;} + /*delete subtasks*/ + for(i=0;inbSubtasks;i++) + { + tmError=sva_TM_DeleteSubTask(pDesc->subtasksIdArray[i]); + if (tmError!=SVA_TM_OK) {return SVA_INTERNAL_POSTPROCESSOR_ERROR;} + } + + /* Delete secondary subtasks in case of PIP */ + if((pDesc->pipActivated != SVA_DP_PIP_CREATION)&&(pDesc->pipActivated != SVA_DP_NO_PIP)) { + if(pDesc->is_ppp_tiling) { //FIXME:patch + for(i=0;i<(pDesc->pipPieceCounter-1)*pDesc->nbSubtasks;i++){ + tmError=sva_TM_DeleteSubTask(pDesc->pipSubtasksIdArrayNoSynchro[i]); + if (tmError!=SVA_TM_OK) {return SVA_INTERNAL_POSTPROCESSOR_ERROR;} + } + }else{ + for(i=0;inbPipSubtasks;i++){ + tmError=sva_TM_DeleteSubTask(pDesc->pipSubtasksIdArrayNoSynchro[i]); + if (tmError!=SVA_TM_OK) {return SVA_INTERNAL_POSTPROCESSOR_ERROR;} + } + } + } + } + + if((pDesc->state!=SVA_DP_WAIT_FOR_CONFIGURATION) && (pDesc->state!=SVA_DP_WAIT_FOR_INTERNAL_NEEDS)) + { + /* deleteBlock */ + if((pConf->transformId == SVA_POSTPROCESSOR_YUV420PL_TO_RGB) + ||(pConf->transformId == SVA_POSTPROCESSOR_YUV420MB_TO_YUV420MB) + ||(pConf->transformId ==SVA_POSTPROCESSOR_YUV420PL_TO_YUV422PL) + ||(pConf->transformId ==SVA_POSTPROCESSOR_YUV422PL_TO_RGB) + ||(pConf->transformId ==SVA_POSTPROCESSOR_YUV420MB_TO_YUV420_SEP_COMP_MB) + ||(pConf->transformId ==SVA_POSTPROCESSOR_YUV420MB_TO_YUV422_SEP_COMP_MB)) + { + t_sva_mm_error mmError; + mmError=sva_MM_FreeBlock(pDesc->tempBlockId); + HCL_DEBUG_ASSERT(mmError==SVA_MM_OK); + } + } + + /*delete descriptor use by memory management*/ + svaError =sva_EM_Delete(serviceId); + if (svaError!=SVA_OK) {return svaError;} + + /* reset instance */ + sva_DP_ResetInstanceDescriptor(instanceNum); + + /* Reset status */ + sva_DP_ResetStatus(&displayDesc[instanceNum].status); + + /* Update the state machine */ + sva_DP_UpdateInstanceStatesMachine(instanceNum,SVA_DP_CONTROL_DELETE); + + /* Sarvesh: Changes for VI16505 */ + { + t_uint32 index; + + index = READ_FIFO_ID_IN_SERVICE_ID(serviceId); + systemTimeDesc[index].is_service_time_running = TRUE; + } + + return SVA_OK; +} + + + +/****************************************************************************/ +/* NAME: t_sva_error SVA_ConfigurePostProcessor ( */ +/* t_sva_service_id serviceId, */ +/* t_sva_postprocessor_configuration preProConfig */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine configures a DISPLAY service */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - serviceId: identifier of the service */ +/* - preProConfig: configuration of the service */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_dp_error */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_sva_error SVA_ConfigurePostProcessor( + t_sva_service_id serviceId, + const t_sva_postprocessor_configuration* pConf + ) +{ + t_sva_dp_error status; + t_sva_service_instance_num instanceNum = READ_INSTANCE_NUM_IN_SERVICE_ID(serviceId); + t_sva_dp_descriptor *pDesc=&displayDesc[instanceNum]; + + + /*check for service id validity*/ + status=sva_DP_CheckServiceId(serviceId); + if (status!=SVA_DP_OK) {return SVA_INTERNAL_POSTPROCESSOR_ERROR;} + + /*check that transition is allowed*/ + if (sva_DP_isTransitionValid(instanceNum, SVA_DP_CONFIGURE)==FALSE) {return SVA_INTERNAL_POSTPROCESSOR_ERROR;} + + /*check pointer validity*/ + HCL_ASSERT(pConf!=0); + + #ifdef __STN_8815 + #if __STN_8815 >= 20 + #else + if (pConf->raster_in_format == TRUE) + { + return SVA_INCOHERENT_CONFIGURATION; + } + #endif + #endif + + /*check configuration validity*/ + if (sva_DP_isConfigurationValid(pConf)==FALSE) { + return SVA_INCOHERENT_CONFIGURATION; + } + + /* check config discrepencies: */ + if(((pConf->transformId ==SVA_POSTPROCESSOR_YUV420MB_TO_YUV422PL) + ||(pConf->transformId ==SVA_POSTPROCESSOR_YUV420MB_TO_YUV420MB) + ||(pConf->transformId ==SVA_POSTPROCESSOR_YUV420MB_TO_YUV420_SEP_COMP_MB) + ||(pConf->transformId ==SVA_POSTPROCESSOR_YUV420MB_TO_YUV422_SEP_COMP_MB)) + &&(pConf->isDirectScreenAccess==TRUE)) + { + return SVA_INTERNAL_POSTPROCESSOR_ERROR; + } + if((pConf->isDoubleBufferMode ==TRUE)&&(pConf->isDirectScreenAccess==FALSE)) + { + return SVA_INTERNAL_POSTPROCESSOR_ERROR; + } + + /*copy it internally*/ + pDesc->confHandle.currentConf=*pConf; + pDesc->confHandle.nextConf=*pConf; + pDesc->confHandle.currentConfCounter=0; + pDesc->confHandle.confState = SVA_DP_NO_CONF_CHANGE_NEED; + + /* Reset subtask conf counter */ + { + t_uint16 i; + for(i=0; isubtasksConfCounter[i] = 0;} + } + /* Reset config */ + sva_DP_ResetParamConfHandle(&pDesc->confHandle); + + /* Update the states machine */ + sva_DP_UpdateInstanceStatesMachine(instanceNum,SVA_DP_CONFIGURE); + + return SVA_OK; +} + + +/****************************************************************************/ +/* NAME: t_sva_error sva_DP_GetParamsBufferSize ( */ +/* t_sva_service_id serviceId, */ +/* t_sva_push_mode mode, */ +/* t_size *pSize */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine return need buffer size in bytes for params buffers. */ +/* If mode is SVA_PUSH_OUT then return size for cropping vector buffer */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - serviceId: identifier of the service */ +/* - mode: allow to differentiate in and out buffers */ +/* */ +/* OUT : */ +/* - pSize: needed size in bytes for buffers in output */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/* - SVA_OK : Command taken into account */ +/* - SVA_UNKNOWN_SERVICE_ID : service id is not correct */ +/* - SVA_UNEXPECTED_API_CALL : Command cannot be excecuted in */ +/* current context. */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_sva_error sva_DP_GetParamsBufferSize( + t_sva_service_id serviceId, + t_sva_push_mode mode, + t_size *pSize +) +{ + t_sva_service_instance_num instanceNum = READ_INSTANCE_NUM_IN_SERVICE_ID(serviceId); + t_sva_dp_error dpstatus; + t_sva_dp_descriptor *pDesc=&displayDesc[instanceNum]; + t_sva_postprocessor_configuration *pConf=&pDesc->confHandle.currentConf; + t_sva_error svaError = SVA_OK; + + HCL_ASSERT(pSize!=NULL); + + /*check for service id validity*/ + dpstatus=sva_DP_CheckServiceId(serviceId); + if (dpstatus!=SVA_DP_OK) {return SVA_INTERNAL_POSTPROCESSOR_ERROR;} + + /*check that transition is allowed*/ + if (sva_DP_isTransitionValid(instanceNum,SVA_DP_GET_PARAM_SIZE)==FALSE) {return SVA_UNEXPECTED_API_CALL;} + + /*get size to return in bytes*/ + + if(pConf->aceMode != SVA_POSTPROCESSOR_ACE_EXTERNAL) + { + + if((pConf->deringingFilterMode != SVA_NONE_DERINGING_FILTER)||(pConf->deblockingFilterMode != SVA_NONE_DEBLOCKING_FILTER)) + { + //size of the deblocking when display is linked to a decoder with deblocking or deriniging filter? + svaError = SVA_NOT_SUPPORTED_YET; + } + else + { + /*nothing in that case*/ + *pSize = 0; + + } + + } + else + { + if (mode==SVA_PUSH_OUT) + { + /*nothing in output*/ + *pSize=0; + } + else + { + /*ace parameters*/ + *pSize=sizeof(t_sva_ace_offset); + } + } + + + /* Update the state machine */ + sva_DP_UpdateInstanceStatesMachine(instanceNum,SVA_DP_GET_PARAM_SIZE); + + return svaError; +} +/****************************************************************************/ +/* NAME: void sva_DP_ResetInstanceDescriptor( */ +/* t_sva_service_instance_num instanceNum */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine initializes the instance descriptor */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - instanceNum: identifier of the Service instance */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: void */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PRIVATE void sva_DP_ResetInstanceDescriptor(t_sva_service_instance_num instanceNum) +{ + t_sva_dp_descriptor *pDesc = &displayDesc[instanceNum]; + const t_sva_dp_dependencies_desc defaultDepDesc = DEFAULT_INTERNAL_DEPENDENCY; + + pDesc->state = SVA_DP_NOT_INITIALIZED; + pDesc->activateState = SVA_DP_INACTIVE; + pDesc->serviceId = 0; + pDesc->defaultConfiguredDependency = defaultDepDesc; + pDesc->nbInputImagesPostProcessed=0; + pDesc->nbOutputImagesDisplayed=0; + pDesc->nbSubtasks = 0; + pDesc->subtasksListId = 0; + pDesc->pipActivated = SVA_DP_NO_PIP; + pDesc->is_ppp_tiling = FALSE; + pDesc->pipPieceCounter = 0; + pDesc->confHandle.isAceOffsetNeedUpdate=FALSE; + pDesc->isUpdateConf = FALSE; + + + } + + PRIVATE void sva_DP_InitFifos(t_sva_service_instance_num instanceNum) + { + + t_sva_dp_descriptor *pDesc = &displayDesc[instanceNum]; + //const t_sva_dp_dependencies_desc defaultDepDesc = DEFAULT_INTERNAL_DEPENDENCY; + + INIT_FIFO(pDesc->inputImageFifos.pushFifo); + INIT_FIFO(pDesc->inputImageFifos.inUseFifo); + INIT_FIFO(pDesc->inputTimestampsFifos.pushFifo); + INIT_FIFO(pDesc->outputImageFifos.pushFifo); + INIT_FIFO(pDesc->outputImageFifos.inUseFifo); + INIT_FIFO(pDesc->inputParamsFifos.pushFifo); + INIT_FIFO(pDesc->inputParamsFifos.inUseFifo); + INIT_FIFO(pDesc->subtasksDependencyFifo); + + + /* PIP: Allocated even if PIP is not used */ + INIT_FIFO(pDesc->pipSubtasksFifos.pushFifo); + INIT_FIFO(pDesc->pipSubtasksFifos.inUseFifo); + + +} + +/****************************************************************************/ +/* NAME: t_sva_dp_state sva_DP_UpdateInstanceStatesMachine( */ +/* t_sva_service_instance_num instanceNum,*/ +/* t_sva_dp_transition requestedTransition*/ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine allows to update the state machine of a given instance*/ +/* following the given requestedTransition */ +/* */ +/* N.B: This routine returns the new state after the requested transition */ +/* A special return state (SVA_DP_TRANSITION_REJECTED) is used to check */ +/* the validity of a transition request */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - instanceNum: identifier of the Service instance */ +/* - requestedTransition: identifier of the requested transition */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: t_hv_dp_state */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PRIVATE t_sva_dp_state sva_DP_UpdateInstanceStatesMachine +( + t_sva_service_instance_num instanceNum, + t_sva_dp_transition requestedTransition + ) +{ + t_sva_dp_state nextState; + t_sva_dp_activate_state nextActivateState; + t_sva_dp_descriptor *pDesc = &displayDesc[instanceNum]; + + +#ifdef __DEBUG + { + t_uint32 systemTime; + + SVA_GetServiceSystemTime(pDesc->serviceId,&systemTime); + transitionDisplayDebugTable[instanceNum].transitionDebugDesc[transitionDisplayDebugTable[instanceNum].nbOfTransitionReceived%LOG_DEPTH].state=pDesc->state; + transitionDisplayDebugTable[instanceNum].transitionDebugDesc[transitionDisplayDebugTable[instanceNum].nbOfTransitionReceived%LOG_DEPTH].transition=requestedTransition; + transitionDisplayDebugTable[instanceNum].transitionDebugDesc[transitionDisplayDebugTable[instanceNum].nbOfTransitionReceived%LOG_DEPTH].systemTime=systemTime; + transitionDisplayDebugTable[instanceNum].transitionDebugDesc[transitionDisplayDebugTable[instanceNum].nbOfTransitionReceived%LOG_DEPTH].activateState=pDesc->activateState; + transitionDisplayDebugTable[instanceNum].nbOfTransitionReceived++; + + } +#endif + + /* Compute the next states */ + nextState=stateMachine[pDesc->state][requestedTransition]; + nextActivateState=activateStateMachine[pDesc->activateState][requestedTransition]; + + /* Check if the transition is valid */ + if (nextState != SVA_DP_TRANSITION_REJECTED && nextActivateState!=SVA_DP_ACTIVATE_TRANSITION_REJECTED) + { + /* Update the current states of the instance */ + pDesc->state = nextState; + pDesc->activateState = nextActivateState; + pDesc->status.state=displayState2ServiceState[pDesc->state]; + + } + + return nextState; +} + + +/****************************************************************************/ +/* NAME: t_bool sva_DP_isTransitionValid( */ +/* t_sva_service_instance_num instanceNum,*/ +/* t_sva_dp_transition requestedTransition*/ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine checks if the requestedTransition is valid */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - instanceNum: identifier of the Service instance */ +/* - requestedTransition: identifier of the requested transition */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: t_bool */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PRIVATE t_bool sva_DP_isTransitionValid +( + t_sva_service_instance_num instanceNum, + t_sva_dp_transition requestedTransition + ) +{ + t_sva_dp_state nextState; + t_sva_dp_activate_state nextActivateState; + t_sva_dp_descriptor *pDesc = &displayDesc[instanceNum]; + + /* Compute the next states */ + nextState=stateMachine[pDesc->state][requestedTransition]; + nextActivateState=activateStateMachine[pDesc->activateState][requestedTransition]; + + /*return false in case of invalid transition for at least one state machine*/ + if (nextState != SVA_DP_TRANSITION_REJECTED && nextActivateState!=SVA_DP_ACTIVATE_TRANSITION_REJECTED) {return TRUE;} + else {return FALSE;} +} + +/****************************************************************************/ +/* NAME: t_bool sva_DP_isConfigurationValid( */ +/* const t_sva_preprocessor_configuration *pConf */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will check that given configuration given to grab is */ +/* valid. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - pConf: a pointer to the configuration to check */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: t_bool */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PRIVATE t_bool sva_DP_isConfigurationValid +( + const t_sva_postprocessor_configuration *pConfiguration +) +{ + + HCL_ASSERT(pConfiguration!=NULL); + + if((pConfiguration->transformId==SVA_POSTPROCESSOR_YUV422PL_TO_RGB)&&(pConfiguration->raster_in_format==TRUE)) + return FALSE; + + /* check if given config param has a good enum value */ + CHECK_RANGE0(pConfiguration->syncMode, SVA_POSPROCESSOR_NO_EXT_SYNC, SVA_POSTPROCESSOR_EXT_DISPLAY_SYNC); + CHECK_RANGE0(pConfiguration->outputRange, SVA_FULL_RANGE, SVA_BT601_RANGE); + CHECK_RANGE0(pConfiguration->aceMode, SVA_POSTPROCESSOR_ACE_DISABLE, SVA_POSTPROCESSOR_ACE_EXTERNAL); + CHECK_RANGE0(pConfiguration->mirrorMode, SVA_NO_MIRRORING, SVA_VERTICAL_MIRRORING); + CHECK_RANGE0(pConfiguration->rotationMode, SVA_NO_ROTATION, SVA_ROTATION_270); + CHECK_RANGE0(pConfiguration->deblockingFilterMode, SVA_NONE_DEBLOCKING_FILTER, SVA_H263_DEBLOCKING_FILTER); + CHECK_RANGE0(pConfiguration->deringingFilterMode, SVA_NONE_DERINGING_FILTER, SVA_MPEG4_DERINGING_FILTER); + CHECK_RANGE0(pConfiguration->chromaSamplingFormat, SVA_DEFAULT_SAMPLING_FORMAT, SVA_MPEG1_SAMPLING_FORMAT); + + CHECK_ALIGNMENT(pConfiguration->screenFrameBufferBaseAddr, 4); + if (pConfiguration->isDoubleBufferMode) + { + CHECK_ALIGNMENT(pConfiguration->screenAlternateFrameBufferBaseAddr,4); + } + + /* Check destination frame width and height */ + CHECK_RANGE(pConfiguration->videoFrameBufferDesc.frame.height, 4, 4080); + CHECK_RANGE(pConfiguration->videoFrameBufferDesc.frame.width, 4, 4080); + + if((pConfiguration->transformId == SVA_POSTPROCESSOR_YUV420MB_TO_YUV420MB) + ||(pConfiguration->transformId ==SVA_POSTPROCESSOR_YUV420MB_TO_YUV420_SEP_COMP_MB) + ||(pConfiguration->transformId ==SVA_POSTPROCESSOR_YUV420MB_TO_YUV422_SEP_COMP_MB)) + { + /* case FPE = 2 (or 3)*/ + CHECK_ALIGNMENT(pConfiguration->videoFrameBufferDesc.frame.height, 16); + CHECK_ALIGNMENT(pConfiguration->videoFrameBufferDesc.frame.width, 16); + + } + else /* FPE = 0 or 1*/ + { + + #if (__STN_8815 >= 20) + if (pConfiguration->bitsPerPixel == SVA_COLOR_32BITS) + { + //do nothing + } + else if (pConfiguration->bitsPerPixel == SVA_COLOR_24BITS) + #else + if ((pConfiguration->bitsPerPixel == SVA_COLOR_24BITS) || (pConfiguration->bitsPerPixel == SVA_COLOR_32BITS)) + #endif + { + CHECK_ALIGNMENT(pConfiguration->videoFrameBufferDesc.frame.height, 4); + CHECK_ALIGNMENT(pConfiguration->videoFrameBufferDesc.frame.width, 4); + } + else + { + CHECK_ALIGNMENT(pConfiguration->videoFrameBufferDesc.frame.height, 2); + CHECK_ALIGNMENT(pConfiguration->videoFrameBufferDesc.frame.width, 2); + } + } + + CHECK_RANGE0(pConfiguration->videoFrameBufferDesc.window.imageOffset.offsetX, 0, pConfiguration->videoFrameBufferDesc.frame.width - pConfiguration->clippedWindowDesc.image.width); + CHECK_RANGE0(pConfiguration->videoFrameBufferDesc.window.imageOffset.offsetY, 0, pConfiguration->videoFrameBufferDesc.frame.height - pConfiguration->clippedWindowDesc.image.height); + +#if (__STN_8815 >= 20) + if (pConfiguration->bitsPerPixel == SVA_COLOR_32BITS) + { + //do nothing + } + else if (pConfiguration->bitsPerPixel == SVA_COLOR_24BITS) +#else + if ((pConfiguration->bitsPerPixel == SVA_COLOR_24BITS) || (pConfiguration->bitsPerPixel == SVA_COLOR_32BITS)) +#endif + { + + CHECK_ALIGNMENT(pConfiguration->videoFrameBufferDesc.window.imageOffset.offsetX, 4); + CHECK_ALIGNMENT(pConfiguration->videoFrameBufferDesc.window.imageOffset.offsetY, 4); + } + else + { + + CHECK_ALIGNMENT(pConfiguration->videoFrameBufferDesc.window.imageOffset.offsetX, 2); + CHECK_ALIGNMENT(pConfiguration->videoFrameBufferDesc.window.imageOffset.offsetY, 2); + } + + /*Source Frame Checks*/ + if ((pConfiguration->transformId == SVA_POSTPROCESSOR_YUV420PL_TO_RGB ) + ||(pConfiguration->transformId == SVA_POSTPROCESSOR_YUV420PL_TO_YUV422PL) + ||(pConfiguration->transformId == SVA_POSTPROCESSOR_YUV422PL_TO_RGB)) + { + /* case FPE=1*/ + if(pConfiguration->raster_in_format==FALSE) + { + CHECK_RANGE(pConfiguration->sourceFrameDesc.frame.height, 16, 288); + CHECK_RANGE(pConfiguration->sourceFrameDesc.frame.width, 16, 352); + } + else + { /* case FPE=0*/ + CHECK_RANGE(pConfiguration->sourceFrameDesc.frame.height, 16, 4080); + CHECK_RANGE(pConfiguration->sourceFrameDesc.frame.width, 16, 4080); + } + } + else + { + CHECK_RANGE(pConfiguration->sourceFrameDesc.frame.height, 16, 4080); + CHECK_RANGE(pConfiguration->sourceFrameDesc.frame.width, 16, 4080); + } + + CHECK_RANGE(pConfiguration->sourceFrameDesc.window.image.height, 16, pConfiguration->sourceFrameDesc.frame.height); + CHECK_RANGE(pConfiguration->sourceFrameDesc.window.image.width, 16, pConfiguration->sourceFrameDesc.frame.width); + CHECK_RANGE0(pConfiguration->sourceFrameDesc.window.imageOffset.offsetX, 0, pConfiguration->sourceFrameDesc.frame.width - pConfiguration->sourceFrameDesc.window.image.width); + CHECK_RANGE0(pConfiguration->sourceFrameDesc.window.imageOffset.offsetY, 0, pConfiguration->sourceFrameDesc.frame.height - pConfiguration->sourceFrameDesc.window.image.height); + + + if((pConfiguration->rotationMode == SVA_NO_ROTATION)||(pConfiguration->rotationMode == SVA_ROTATION_180)) + { + + CHECK_RANGE(pConfiguration->resizedImageDesc.height, pConfiguration->sourceFrameDesc.window.image.height/4, pConfiguration->sourceFrameDesc.window.image.height*4); + CHECK_RANGE(pConfiguration->resizedImageDesc.width, pConfiguration->sourceFrameDesc.window.image.width/4, pConfiguration->sourceFrameDesc.window.image.width*4); + } + else + { + CHECK_RANGE(pConfiguration->resizedImageDesc.height, pConfiguration->sourceFrameDesc.window.image.width/4, pConfiguration->sourceFrameDesc.window.image.width*4); + CHECK_RANGE(pConfiguration->resizedImageDesc.width, pConfiguration->sourceFrameDesc.window.image.height/4, pConfiguration->sourceFrameDesc.window.image.height*4); + + } + + CHECK_ALIGNMENT(pConfiguration->sourceFrameDesc.frame.height, 16); + CHECK_ALIGNMENT(pConfiguration->sourceFrameDesc.frame.width, 16); + CHECK_ALIGNMENT(pConfiguration->sourceFrameDesc.window.image.height, 16); + CHECK_ALIGNMENT(pConfiguration->sourceFrameDesc.window.image.width, 16); + CHECK_ALIGNMENT(pConfiguration->sourceFrameDesc.window.imageOffset.offsetX, 16); + CHECK_ALIGNMENT(pConfiguration->sourceFrameDesc.window.imageOffset.offsetY, 16); + CHECK_ALIGNMENT(pConfiguration->resizedImageDesc.height, 1); + CHECK_ALIGNMENT(pConfiguration->resizedImageDesc.width, 1); + + +#if (__STN_8815 >= 20) + if (pConfiguration->bitsPerPixel == SVA_COLOR_32BITS) + { + //do nothing + } + else if (pConfiguration->bitsPerPixel == SVA_COLOR_24BITS) +#else + if (pConfiguration->bitsPerPixel == SVA_COLOR_32BITS) + { + //do nothing + } + else if (pConfiguration->bitsPerPixel == SVA_COLOR_24BITS) +#endif + { + CHECK_ALIGNMENT(pConfiguration->clippedWindowDesc.image.height, 4); + CHECK_ALIGNMENT(pConfiguration->clippedWindowDesc.image.width, 4); +#if (__STN_8815 >= 20) + CHECK_ALIGNMENT(pConfiguration->clippedWindowDesc.imageOffset.offsetX, 1); + CHECK_ALIGNMENT(pConfiguration->clippedWindowDesc.imageOffset.offsetY, 1); +#else + CHECK_ALIGNMENT(pConfiguration->clippedWindowDesc.imageOffset.offsetX, 4); + CHECK_ALIGNMENT(pConfiguration->clippedWindowDesc.imageOffset.offsetY, 4); +#endif + } + else + { + CHECK_ALIGNMENT(pConfiguration->clippedWindowDesc.image.height, 2); + CHECK_ALIGNMENT(pConfiguration->clippedWindowDesc.image.width, 2); +#if (__STN_8815 >= 20) + CHECK_ALIGNMENT(pConfiguration->clippedWindowDesc.imageOffset.offsetX, 1); + CHECK_ALIGNMENT(pConfiguration->clippedWindowDesc.imageOffset.offsetY, 1); +#else + CHECK_ALIGNMENT(pConfiguration->clippedWindowDesc.imageOffset.offsetX, 2); + CHECK_ALIGNMENT(pConfiguration->clippedWindowDesc.imageOffset.offsetY, 2); +#endif + } + + +/* clipping constraints STN_15 or STN_8810 */ + +#if ( defined(__STN_8815) || (__STN_8810 == 20)) +{ + + + t_uint32 check0, check1; + + if((pConfiguration->rotationMode == SVA_NO_ROTATION)||(pConfiguration->rotationMode == SVA_ROTATION_180)) + { + + /*RWW-CWW-CHO<16*RWW/SWW*/ + check0 = pConfiguration->resizedImageDesc.width - pConfiguration->clippedWindowDesc.image.width - pConfiguration->clippedWindowDesc.imageOffset.offsetX; + + check1 = ((16 * pConfiguration->resizedImageDesc.width) % pConfiguration->sourceFrameDesc.window.image.width) + ?(((16 * pConfiguration->resizedImageDesc.width) / pConfiguration->sourceFrameDesc.window.image.width)+1) + :((16 * pConfiguration->resizedImageDesc.width) / pConfiguration->sourceFrameDesc.window.image.width); + + if(check0 >= check1 ) return FALSE; + + /*RWH-CWH-CVO<16*RWH/SWH*/ + check0 = pConfiguration->resizedImageDesc.height - pConfiguration->clippedWindowDesc.image.height - pConfiguration->clippedWindowDesc.imageOffset.offsetY; + check1 = ((16 * pConfiguration->resizedImageDesc.height) % pConfiguration->sourceFrameDesc.window.image.height) + ?(((16 * pConfiguration->resizedImageDesc.height) / pConfiguration->sourceFrameDesc.window.image.height)+1) + :((16 * pConfiguration->resizedImageDesc.height) / pConfiguration->sourceFrameDesc.window.image.height); + + if(check0 >= check1 ) return FALSE; + } + else + { + /*RWW-CWW-CHO<16*RWW/SWH*/ + check0 = pConfiguration->resizedImageDesc.width - pConfiguration->clippedWindowDesc.image.width - pConfiguration->clippedWindowDesc.imageOffset.offsetX; + + check1 = ((16 * pConfiguration->resizedImageDesc.width) % pConfiguration->sourceFrameDesc.window.image.height) + ?(((16 * pConfiguration->resizedImageDesc.width) / pConfiguration->sourceFrameDesc.window.image.height)+1) + :((16 * pConfiguration->resizedImageDesc.width) / pConfiguration->sourceFrameDesc.window.image.height); + + if(check0 >= check1 ) return FALSE; + + /*RWH-CWH-CVO<16*RWH/SWW*/ + check0 = pConfiguration->resizedImageDesc.height - pConfiguration->clippedWindowDesc.image.height - pConfiguration->clippedWindowDesc.imageOffset.offsetY; + check1 = ((16 * pConfiguration->resizedImageDesc.height) % pConfiguration->sourceFrameDesc.window.image.width) + ? (((16 * pConfiguration->resizedImageDesc.height) / pConfiguration->sourceFrameDesc.window.image.width)+1) + : ((16 * pConfiguration->resizedImageDesc.height) / pConfiguration->sourceFrameDesc.window.image.width) ; + + if(check0 >= check1 ) return FALSE; + } + + #if (__STN_8815 >= 20) + + /*0<=CHOclippedWindowDesc.imageOffset.offsetX) < 0) || (pConfiguration->clippedWindowDesc.imageOffset.offsetX >= pConfiguration->resizedImageDesc.width)) return FALSE; + /*CHO+CWW<=RWW*/ + if((pConfiguration->clippedWindowDesc.imageOffset.offsetX + pConfiguration->clippedWindowDesc.image.width)> pConfiguration->resizedImageDesc.width) return FALSE; + + /*0<=CVOclippedWindowDesc.imageOffset.offsetY) < 0) || (pConfiguration->clippedWindowDesc.imageOffset.offsetY >= pConfiguration->resizedImageDesc.height)) return FALSE; + /*CVO+CWH<=RWH*/ + if((pConfiguration->clippedWindowDesc.imageOffset.offsetY + pConfiguration->clippedWindowDesc.image.height)> pConfiguration->resizedImageDesc.height) return FALSE; + + if((pConfiguration->rotationMode == SVA_NO_ROTATION)||(pConfiguration->rotationMode == SVA_ROTATION_180)) + /* rot off */ + { + + check0 = ((16*pConfiguration->resizedImageDesc.width)%pConfiguration->sourceFrameDesc.window.image.width) + ? (((16*pConfiguration->resizedImageDesc.width)/pConfiguration->sourceFrameDesc.window.image.width)+1) + : ((16*pConfiguration->resizedImageDesc.width)/pConfiguration->sourceFrameDesc.window.image.width); + /*CHO<16*RWW/SWW*/ + if(pConfiguration->clippedWindowDesc.imageOffset.offsetX >= check0) return FALSE; + + check1 = ((16*pConfiguration->resizedImageDesc.height)%pConfiguration->sourceFrameDesc.window.image.height) + ? (((16*pConfiguration->resizedImageDesc.height)/pConfiguration->sourceFrameDesc.window.image.height)+1) + : ((16*pConfiguration->resizedImageDesc.height)/pConfiguration->sourceFrameDesc.window.image.height); + /*CVO<16*RWH/SWH*/ + if(pConfiguration->clippedWindowDesc.imageOffset.offsetY >= check1) return FALSE;} + else + { + + check0 = ((16*pConfiguration->resizedImageDesc.width)%pConfiguration->sourceFrameDesc.window.image.height) + ? (((16*pConfiguration->resizedImageDesc.width)/pConfiguration->sourceFrameDesc.window.image.height)+1) + :((16*pConfiguration->resizedImageDesc.width)/pConfiguration->sourceFrameDesc.window.image.height); + /*CHO<16*RWW/SWH*/ + if(pConfiguration->clippedWindowDesc.imageOffset.offsetX >= check0) return FALSE; + + check1 = ((16*pConfiguration->resizedImageDesc.height)%pConfiguration->sourceFrameDesc.window.image.width) + ? (((16*pConfiguration->resizedImageDesc.height)/pConfiguration->sourceFrameDesc.window.image.width)+1) + :((16*pConfiguration->resizedImageDesc.height)/pConfiguration->sourceFrameDesc.window.image.width); + /*CVO<16*RWH/SWW*/ + if(pConfiguration->clippedWindowDesc.imageOffset.offsetY >= check1) return FALSE; + } + + #else /*(__STN_8815 >= 20)*/ + + if((pConfiguration->rotationMode == SVA_NO_ROTATION)||(pConfiguration->rotationMode == SVA_ROTATION_180)) + /* rot off */ + { + /*if (RWWa>=SWW) then CHO<=14*RWW/SWW-1 else CHO<=16*RWW/SWW-4}*/ + if(pConfiguration->resizedImageDesc.width >= pConfiguration->sourceFrameDesc.window.image.width) + { + check0 = ((14 * pConfiguration->resizedImageDesc.width) % pConfiguration->sourceFrameDesc.window.image.width) + ? ((((14 * pConfiguration->resizedImageDesc.width) / pConfiguration->sourceFrameDesc.window.image.width)+1) - 1) + : (((14 * pConfiguration->resizedImageDesc.width) / pConfiguration->sourceFrameDesc.window.image.width)-1) ; + if(pConfiguration->clippedWindowDesc.imageOffset.offsetX > check0) return FALSE; + } + else + { + check0 = ((16 * pConfiguration->resizedImageDesc.width) % pConfiguration->sourceFrameDesc.window.image.width) + ? ((((16 * pConfiguration->resizedImageDesc.width) / pConfiguration->sourceFrameDesc.window.image.width)+1) - 4) + : (((16 * pConfiguration->resizedImageDesc.width) / pConfiguration->sourceFrameDesc.window.image.width)-4); + if(pConfiguration->clippedWindowDesc.imageOffset.offsetX > check0) return FALSE; + } + + /*if (RWH>=SWH) then CVO<=14*RWH/SWH-1 else CVO<=16*RWH/SWH-3*/ + if(pConfiguration->resizedImageDesc.height >= pConfiguration->sourceFrameDesc.window.image.height) + { + check0 = ((14 * pConfiguration->resizedImageDesc.height) % pConfiguration->sourceFrameDesc.window.image.height) + ? ((((14 * pConfiguration->resizedImageDesc.height) / pConfiguration->sourceFrameDesc.window.image.height)+1) - 1) + : (((14 * pConfiguration->resizedImageDesc.height) / pConfiguration->sourceFrameDesc.window.image.height)-1); + if(pConfiguration->clippedWindowDesc.imageOffset.offsetY > check0) return FALSE; + } + else + { + check0 = ((16 * pConfiguration->resizedImageDesc.height) % pConfiguration->sourceFrameDesc.window.image.height) + ? ((((16 * pConfiguration->resizedImageDesc.height) / pConfiguration->sourceFrameDesc.window.image.height)+1) - 3) + : (((16 * pConfiguration->resizedImageDesc.height) / pConfiguration->sourceFrameDesc.window.image.height)-3); + if(pConfiguration->clippedWindowDesc.imageOffset.offsetY > check0) return FALSE; + } + + } + else + { + + /*if (RWW>=SWH) then CHO<=14*RWW/SWH-1 else CHO<=16*RWW/SWH-4*/ + if(pConfiguration->resizedImageDesc.width >= pConfiguration->sourceFrameDesc.window.image.height) + { + check0 = ((14 * pConfiguration->resizedImageDesc.width) % pConfiguration->sourceFrameDesc.window.image.height) + ? ((((14 * pConfiguration->resizedImageDesc.width) / pConfiguration->sourceFrameDesc.window.image.height)+1) - 1) + : (((14 * pConfiguration->resizedImageDesc.width) / pConfiguration->sourceFrameDesc.window.image.height) - 1) ; + if(pConfiguration->clippedWindowDesc.imageOffset.offsetX > check0) return FALSE; + } + else + { + check0 = ((16 * pConfiguration->resizedImageDesc.width) % pConfiguration->sourceFrameDesc.window.image.height) + ? ((((16 * pConfiguration->resizedImageDesc.width) / pConfiguration->sourceFrameDesc.window.image.height)+1) - 4) + : (((16 * pConfiguration->resizedImageDesc.width) / pConfiguration->sourceFrameDesc.window.image.height) - 4) ; + ; + if(pConfiguration->clippedWindowDesc.imageOffset.offsetX > check0) return FALSE; + } + + + /*if (RWH>=SWW) then CVO<=14*RWH/SWW-1 else CVO<=16*RWH/SWW-3} */ + if(pConfiguration->resizedImageDesc.height >= pConfiguration->sourceFrameDesc.window.image.width) + { + check0 = ((14 * pConfiguration->resizedImageDesc.height) % pConfiguration->sourceFrameDesc.window.image.width) + ? ((((14 * pConfiguration->resizedImageDesc.height) / pConfiguration->sourceFrameDesc.window.image.width)+1) - 1) + : (((14 * pConfiguration->resizedImageDesc.height) / pConfiguration->sourceFrameDesc.window.image.width) - 1);; + if(pConfiguration->clippedWindowDesc.imageOffset.offsetY > check0) return FALSE; + } + else + { + check0 = ((16 * pConfiguration->resizedImageDesc.height) % pConfiguration->sourceFrameDesc.window.image.width) + ? ((((16 * pConfiguration->resizedImageDesc.height) / pConfiguration->sourceFrameDesc.window.image.width)+1) - 3) + : (((16 * pConfiguration->resizedImageDesc.height) / pConfiguration->sourceFrameDesc.window.image.width) - 3); + if(pConfiguration->clippedWindowDesc.imageOffset.offsetY > check0) return FALSE; + } + } + #endif /* __STN_15==20 */ + +} +#endif + + /* Check contrast and brigthness */ + CHECK_RANGE0(pConfiguration->contrast, 0, CNT_BRT_MAX_RANGE_VALUE); + CHECK_RANGE0(pConfiguration->brightness, 0, CNT_BRT_MAX_RANGE_VALUE); + + /* check color matrix coeff values */ + CHECK_RANGE(pConfiguration->colorMatrix.matrix_coef1, -1024, 1023); + CHECK_RANGE(pConfiguration->colorMatrix.matrix_coef2, -1024, 1023); + CHECK_RANGE(pConfiguration->colorMatrix.matrix_coef3, -1024, 1023); + CHECK_RANGE(pConfiguration->colorMatrix.matrix_coef4, -1024, 1023); + + /* check display synchronisation line number if activated, 16 <= displaySyncLine <= SWH */ + if(pConfiguration->displaySyncLine != 0x3FF) + { + CHECK_ALIGNMENT(pConfiguration->displaySyncLine, 16); + CHECK_RANGE(pConfiguration->displaySyncLine, 16, pConfiguration->sourceFrameDesc.window.image.height); + } + + /* Check ace strength and ace range */ + if (pConfiguration->aceMode != SVA_POSTPROCESSOR_ACE_DISABLE) + { + CHECK_RANGE(pConfiguration->aceStrength, SVA_ACE_STRENGTH_1, SVA_ACE_STRENGTH_8); + CHECK_RANGE0(pConfiguration->aceRange, SVA_FULL_RANGE, SVA_BT601_RANGE); + } + + + return TRUE; +} + + +/****************************************************************************/ +/* NAME: t_sva_dp_error sva_DP_CheckServiceId(t_sva_service_id serviceId) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will check that task_id and instance number of servideId*/ +/* are both valid */ +/* */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - serviceId: service id to check */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: t_sva_gb_error */ +/* - SVA_DP_INVALID_INSTANCE_NB : Invalid instance number */ +/* - SVA_DP_INVALID_TASK_ID_NB : Invalid task id */ +/* - SVA_DP_OK : Command was executed or is on going */ +/* */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ + +PRIVATE t_sva_dp_error sva_DP_CheckServiceId(t_sva_service_id serviceId) +{ + t_sva_service_instance_num instanceNum = READ_INSTANCE_NUM_IN_SERVICE_ID(serviceId); + t_sva_sv_task_id taskId = READ_TASK_ID_IN_SERVICE_ID(serviceId); + + if (taskId!=SVA_SV_DISPLAY_TID) {return SVA_DP_INVALID_TASK_ID_NB;} + if (instanceNum>=NUM_MAX_DISPLAY) {return SVA_DP_INVALID_INSTANCE_NB;} + + return SVA_DP_OK; +} + + +/****************************************************************************/ +/* NAME: t_sva_dp_error sva_DP_CreateSubTasksDescriptors( */ +/* t_sva_service_id serviceId */ +/* t_uint8 nbSubtasks */ +/* const t_sva_postprocessor_configuration *pConf, */ +/* t_sva_tm_subtask_id *pSubtaskIdArray, */ +/* t_sva_tm_subtask_list_id *pListId */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine creates all required display subtasks descriptors */ +/* It don't take into account any dependency, and reference only one */ +/* param_in structure */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - nbSubtasks: number of tasks to be created */ +/* - pConf: configuration to support */ +/* */ +/* OUT: */ +/* - pSubtaskIdArray: array of all created subtasks */ +/* - pListId: identifier of the new created subtask list */ +/* */ +/* RETURN: t_sva_dp_error */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PRIVATE t_sva_dp_error sva_DP_CreateSubTasksDescriptors +( + t_sva_service_id serviceId, + const t_sva_postprocessor_configuration *pConf, + t_sva_tm_subtask_list_id *pListId + ) +{ + t_sva_tm_task_ctrl_desc displayTaskDesc; + t_sva_tm_field_ctrl_desc displayFieldDescArray[DISPLAY_FIELD_NUMBER]; + t_sva_tm_synchro synchro=SVA_TM_NO_SYNCHRO; + t_sva_tm_subtask_type subtaskType; + t_sva_tm_bot_eot requestedHwEvent; + t_sva_tm_error tmError; + t_uint8 i; + t_sva_tm_postprocessing_type postProc; + + t_sva_service_instance_num instanceNum = READ_INSTANCE_NUM_IN_SERVICE_ID(serviceId); + t_sva_dp_descriptor *pDesc=&displayDesc[instanceNum]; + + HCL_ASSERT(pConf!=NULL); + HCL_ASSERT(pListId!=NULL); + + /* Prepare the task control descriptor */ + displayTaskDesc.memId = DISPLAY_DEFAULT_MEMORY_ID; + displayTaskDesc.fieldnb = DISPLAY_FIELD_NUMBER; + displayTaskDesc.pfieldctrldesc = displayFieldDescArray; + + /* Copy default display field descriptor array */ + for (i=0; i < DISPLAY_FIELD_NUMBER; i++) + { + displayFieldDescArray[i] = defaultDisplayFieldDescArray[i]; + } + + /* Extract parameters from configuration */ + //synchro = (t_sva_tm_synchro)((pConf->isDirectScreenAccess)?SVA_TM_DISPLAY_VSYNC:SVA_TM_NO_SYNCHRO); + //synchro = SVA_TM_DISPLAY_VSYNC; + + + if(pConf->syncMode == SVA_POSPROCESSOR_NO_EXT_SYNC) + { + synchro = SVA_TM_NO_SYNCHRO; + } + else if(pConf->syncMode == SVA_POSTPROCESSOR_EXT_DISPLAY_SYNC) + { + synchro = SVA_TM_DISPLAY_VSYNC; + } + + + + subtaskType = filter_mode_2_subtask_type[pConf->deblockingFilterMode][pConf->deringingFilterMode]; + + if (pConf->raster_in_format == TRUE) + { + switch (subtaskType) + { + case SVA_TM_DISPLAY_NO_FILTERING : subtaskType = SVA_TM_DISPLAY_NO_FILTERING_RASTER_IN ; break; + case SVA_TM_DISPLAY_MPEG4_DEBLOCKING : subtaskType = SVA_TM_DISPLAY_MPEG4_DEBLOCKING_RASTER_IN ; break; + case SVA_TM_DISPLAY_MPEG4_DEBLOCKING_DERINGING : subtaskType = SVA_TM_DISPLAY_MPEG4_DEBLOCKING_DERINGING_RASTER_IN ; break; + case SVA_TM_DISPLAY_H263_DEBLOCKING : subtaskType = SVA_TM_DISPLAY_H263_DEBLOCKING_RASTER_IN ; break; + case SVA_TM_DISPLAY_H263_DEBLOCKING_MPEG4_DERINGING: subtaskType = SVA_TM_DISPLAY_H263_DEBLOCKING_MPEG4_DERINGING_RASTER_IN; break; + case SVA_TM_DISPLAY_MPEG4_DERINGING : subtaskType = SVA_TM_DISPLAY_MPEG4_DERINGING_RASTER_IN ; break; + } + } + + requestedHwEvent = SVA_TM_EOT_EN; + + + if ((pConf->transformId == SVA_POSTPROCESSOR_YUV420MB_TO_RGB) + ||(pConf->transformId == SVA_POSTPROCESSOR_YUV420MB_TO_YUV422PL)) + { + postProc = SVA_TM_NO_POST_PROCESSING; + } + else if ((pConf->transformId == SVA_POSTPROCESSOR_YUV420PL_TO_RGB ) + ||(pConf->transformId == SVA_POSTPROCESSOR_YUV420PL_TO_YUV422PL) + ||(pConf->transformId == SVA_POSTPROCESSOR_YUV422PL_TO_RGB)) + { + if(pConf->raster_in_format==FALSE) + postProc = SVA_TM_YUV420PL_TO_RGB; + else + postProc = SVA_TM_NO_POST_PROCESSING; + + } + else if(pConf->transformId == SVA_POSTPROCESSOR_YUV420MB_TO_YUV420MB) + { + postProc = SVA_TM_YUV420MB_TO_YUV420MB; + } + else //SVA_POSTPROCESSOR_YUV420MB_TO_YUV420_SEP_COMP_MB or SVA_POSTPROCESSOR_YUV420MB_TO_YUV422_SEP_COMP_MB + { + postProc = SVA_TM_YUV420MB_TO_YUV_SEP_COMP_MB; + } + + pDesc->postProc = postProc; + + /* Always: in case of PIP, they are considered as PRIMARY */ + for (i=0; i < pDesc->nbSubtasks; i++) + { + + + tmError=sva_TM_CreateSubTask( + SVA_TM_DISPLAY, + &displayTaskDesc, + subtaskType, + postProc, + synchro, + requestedHwEvent, + SVA_TM_BBM_DEFAULT, + &pDesc->subtasksIdArray[i] + ); + + + if (tmError != SVA_TM_OK) {return SVA_DP_TM_LINKED_ERROR;} + + } + + + + + /* Connect subtasks */ + for(i=0;inbSubtasks;i++) + { + tmError=sva_TM_ConnectSubtasksFields(pDesc->subtasksIdArray[(i+pDesc->nbSubtasks-1)%pDesc->nbSubtasks], + SVA_TM_DIS_ADDR_OUT_FRAME_PARAMETERS, + pDesc->subtasksIdArray[i], + SVA_TM_DIS_ADDR_IN_FRAME_PARAMETERS); + if (tmError != SVA_TM_OK) {return SVA_DP_TM_LINKED_ERROR;} + } + + + + + if ((pConf->transformId == SVA_POSTPROCESSOR_YUV420MB_TO_RGB) + ||(pConf->transformId == SVA_POSTPROCESSOR_YUV420MB_TO_YUV422PL)) + { + if(pConf->aceMode != SVA_POSTPROCESSOR_ACE_DISABLE) + { + tmError=sva_TM_CreateSubTaskList(SVA_TM_DISPLAY, serviceId,SVA_FW_FEAT_POST_PROCESSOR | SVA_FW_FEAT_ACE,&pDesc->subtasksListId); + if (tmError != SVA_TM_OK) {return SVA_DP_TM_LINKED_ERROR;} + } + else + { + tmError=sva_TM_CreateSubTaskList(SVA_TM_DISPLAY, serviceId,SVA_FW_FEAT_POST_PROCESSOR,&pDesc->subtasksListId); + if (tmError != SVA_TM_OK) {return SVA_DP_TM_LINKED_ERROR;} + } + + } + else + { + if(pConf->aceMode != SVA_POSTPROCESSOR_ACE_DISABLE) + { + tmError=sva_TM_CreateSubTaskList(SVA_TM_DISPLAY, serviceId,SVA_FW_FEAT_POST_PROCESSOR_RASTER_TO_MB | SVA_FW_FEAT_ACE ,&pDesc->subtasksListId); + if (tmError != SVA_TM_OK) {return SVA_DP_TM_LINKED_ERROR;} + } + else + { + tmError=sva_TM_CreateSubTaskList(SVA_TM_DISPLAY, serviceId,SVA_FW_FEAT_POST_PROCESSOR_RASTER_TO_MB ,&pDesc->subtasksListId); + if (tmError != SVA_TM_OK) {return SVA_DP_TM_LINKED_ERROR;} + } + } + + return SVA_DP_OK; +} + + + +/****************************************************************************/ +/* NAME: t_sva_dp_error sva_DP_BuildParamInStructure( */ +/* const t_sva_postprocessor_configuration *pConf,*/ +/* t_sva_dpl_param_in *pParamIn */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine builds the paramIn structure from the given configuration */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - pConf: provided postprocessor configuration */ +/* */ +/* OUT: */ +/* - pParamIn: paramIn structure to build */ +/* */ +/* RETURN: t_sva_dp_error */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PRIVATE t_sva_dp_error sva_DP_BuildParamInStructure +( + const t_sva_postprocessor_configuration *pConf, + t_sva_dpl_param_in *pParamIn + ) +{ + + HCL_ASSERT(pConf!=NULL); + HCL_ASSERT(pParamIn!=NULL); + + pParamIn->source_frame_width = pConf->sourceFrameDesc.frame.width; + pParamIn->source_frame_height = pConf->sourceFrameDesc.frame.height; + pParamIn->source_window_width = pConf->sourceFrameDesc.window.image.width; + pParamIn->source_window_height = pConf->sourceFrameDesc.window.image.height; + pParamIn->source_window_horizontal_offset = pConf->sourceFrameDesc.window.imageOffset.offsetX; + pParamIn->source_window_vertical_offset = pConf->sourceFrameDesc.window.imageOffset.offsetY; + pParamIn->resized_window_width = pConf->resizedImageDesc.width; + pParamIn->resized_window_height = pConf->resizedImageDesc.height; + pParamIn->clipped_window_width = pConf->clippedWindowDesc.image.width; + pParamIn->clipped_window_height = pConf->clippedWindowDesc.image.height; + pParamIn->clipped_window_horizontal_offset = pConf->clippedWindowDesc.imageOffset.offsetX; + pParamIn->clipped_window_vertical_offset = pConf->clippedWindowDesc.imageOffset.offsetY; + + + + pParamIn->destination_frame_width = pConf->videoFrameBufferDesc.frame.width; + pParamIn->destination_frame_height = pConf->videoFrameBufferDesc.frame.height; + + + pParamIn->destination_window_horizontal_offset = pConf->videoFrameBufferDesc.window.imageOffset.offsetX; + pParamIn->destination_window_vertical_offset = pConf->videoFrameBufferDesc.window.imageOffset.offsetY; + + /* FIX ME : add reference to Nomadik Full Cut B */ + if((pConf->transformId==SVA_POSTPROCESSOR_YUV420MB_TO_RGB)||(pConf->transformId==SVA_POSTPROCESSOR_YUV420PL_TO_RGB)) + { + pParamIn->bits_per_pixel = (t_sva_param_subfield)bpp_hclapi2hwapi[pConf->bitsPerPixel]; + } + else if(pConf->transformId == SVA_POSTPROCESSOR_YUV422PL_TO_RGB) + { + pParamIn->bits_per_pixel = (t_sva_param_subfield) ((t_ushort_value)0x100 | (t_ushort_value) bpp_hclapi2hwapi[pConf->bitsPerPixel]); + } + else if(pConf->transformId == SVA_POSTPROCESSOR_YUV420MB_TO_YUV420_SEP_COMP_MB) + { + pParamIn->bits_per_pixel = (t_sva_param_subfield) (0x0000); + } + else if (pConf->transformId == SVA_POSTPROCESSOR_YUV420MB_TO_YUV422_SEP_COMP_MB) + { + pParamIn->bits_per_pixel = (t_sva_param_subfield) (0x0100); + } + else //SVA_POSTPROCESSOR_YUV420MB_TO_YUV422PL or SVA_POSTPROCESSOR_YUV420MB_TO_YUV420MB or SVA_POSTPROCESSOR_YUV420PL_TO_YUV422PL + { + pParamIn->bits_per_pixel = 0; + } + + pParamIn->dithering = (t_sva_param_subfield)((pConf->isDithering)?1:0); + pParamIn->mirroring = (t_sva_param_subfield)rot_mir_hclapi2hwapi[pConf->rotationMode][pConf->mirrorMode].mirroring; + pParamIn->rotation = (t_sva_param_subfield)rot_mir_hclapi2hwapi[pConf->rotationMode][pConf->mirrorMode].rotation; + pParamIn->chroma_sampling_format = (t_sva_param_subfield)csf_hclapi2hwapi[pConf->chromaSamplingFormat]; + pParamIn->alpha_key = COMPUTE_ALPHA_KEY(pConf->bitsPerPixel, pConf->alphaKey); + pParamIn->red_blue_swap = (t_sva_param_subfield)((pConf->redBlueSwap)?1:0); + + /* Check if we can disable the resize engine */ + if ((pConf->sourceFrameDesc.window.image.width == pConf->resizedImageDesc.width) + && (pConf->sourceFrameDesc.window.image.height == pConf->resizedImageDesc.height)) + { + pParamIn->chroma_duplication = 1; + } + else {pParamIn->chroma_duplication = 0;} + + + + /* to be added: */ + if ((pParamIn->bits_per_pixel & 0xFF) != 0) + { + pParamIn->contrast = COMPUTE_CONTRAST(pConf->contrast); + pParamIn->brightness = COMPUTE_BRIGHTNESS(pConf->brightness); + + pParamIn->matrix_coef1 = pConf->colorMatrix.matrix_coef1; + pParamIn->matrix_coef2 = pConf->colorMatrix.matrix_coef2; + pParamIn->matrix_coef3 = pConf->colorMatrix.matrix_coef3; + pParamIn->matrix_coef4 = pConf->colorMatrix.matrix_coef4; + } + else + { + + pParamIn->contrast = COMPUTE_CONTRAST_ZERO_BPP(pConf->contrast); + pParamIn->brightness = COMPUTE_BRIGHTNESS_ZERO_BPP(pConf->brightness); + //pParamIn->contrast = 128; + //pParamIn->brightness = 16384; + //pParamIn->matrix_coef1 = 128; + pParamIn->matrix_coef1 = pConf->colorMatrix.matrix_coef1; + pParamIn->matrix_coef2 = 0; + pParamIn->matrix_coef3 = 0; + //pParamIn->matrix_coef4 = 128; + pParamIn->matrix_coef4 = pConf->colorMatrix.matrix_coef4; + } + + pParamIn->display_sync_line = (t_sva_param_subfield)(pConf->displaySyncLine); + pParamIn->ace_enable = (t_sva_param_subfield)((pConf->aceMode!=0)?1:0); + pParamIn->ace_strength = (t_sva_param_subfield)(pConf->aceStrength); + pParamIn->ace_range = (t_sva_param_subfield)((pConf->aceRange)?1:0); + + + pParamIn->output_range= (t_sva_param_subfield)((pConf->outputRange)?1:0); + + + return SVA_DP_OK; +} + + +/****************************************************************************/ +/* NAME: t_sva_dp_error sva_DP_ResetStatus( */ +/* t_sva_postprocessor_status *pStatus */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will reset status descriptor. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - pStatus: status descriptor to reset */ +/* */ +/* OUT: none */ +/* */ +/* RETURN: t_sva_dp_error */ +/* - SVA_DP_OK */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PRIVATE t_sva_dp_error sva_DP_ResetStatus +( + t_sva_postprocessor_status *pStatus +) +{ + HCL_ASSERT(pStatus != 0); + pStatus->state=SVA_SERVICE_NOT_INITIALIZED; + pStatus->errorId=SVA_POSTPROCESSOR_NO_ERROR; + pStatus->nbInputImagesPostProcessed=0; + pStatus->nbOutputImagesDisplayed=0; + pStatus->eventStats.voidedCounter=0; + pStatus->eventStats.filledCounter=0; + pStatus->eventStats.partlyCounter=0; + pStatus->eventStats.readOnlyCounter=0; + pStatus->eventStats.underflowCounter=0; + pStatus->eventStats.overflowCounter=0; + pStatus->eventStats.errorCounter=0; + pStatus->bufferizationStats.inLevel=0; + pStatus->bufferizationStats.outLevel=0; + + return SVA_DP_OK; +} + + +/****************************************************************************/ +/* NAME: t_sva_error sva_DP_DoFlushIn( */ +/* t_sva_service_id serviceId */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will flush output fifo. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - serviceId: service identifier */ +/* */ +/* OUT: none */ +/* */ +/* RETURN: t_sva_error */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PRIVATE t_sva_error sva_DP_DoFlushIn +( + t_sva_service_id serviceId +) +{ + t_sva_service_instance_num instanceNum = READ_INSTANCE_NUM_IN_SERVICE_ID(serviceId); + t_sva_dp_descriptor *pDesc=&displayDesc[instanceNum]; + t_uint32 systemTime; + t_sva_error svaError; + t_sva_tm_error tmError; + t_sva_dp_subtask_dependencies subtaskDep; + t_sva_ff_error ffError; + t_sva_buffer_id bufferId=INVALID_BUFFER_ID; + volatile t_sva_tm_timestamp timeStamp; + t_sva_bm_error bmError; + //t_sva_dp_pip_subtask_id pipSubtaskId; + + t_uint16 i; + + + /*remove scheduled tasks and push them back in subtasksDependencyFifo with default dep*/ + /*so they can be rescheduled */ + do + { + tmError=sva_TM_RemoveElemFromSubTaskList(pDesc->subtasksListId,&subtaskDep.subtaskId); + if (tmError==SVA_TM_OK) + { + + + if(sva_DP_isPrimarySubtask(instanceNum, subtaskDep.subtaskId)) { + subtaskDep.dependencies = pDesc->defaultConfiguredDependency; + ffError=PUSH_FIFO_ELEM(pDesc->subtasksDependencyFifo,t_sva_dp_subtask_dependencies,subtaskDep); + if (ffError!=SVA_FIFO_OK) {return SVA_INTERNAL_POSTPROCESSOR_ERROR;} + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + } + else { + /* repush in PIP fifo */ + + } + } + } while (tmError==SVA_TM_OK); + + + + for(i=0; inbSubtasks; i++) + { + ffError=READ_FIFO_ELEM(pDesc->subtasksDependencyFifo,t_sva_dp_subtask_dependencies,subtaskDep); + if (ffError!=SVA_FIFO_OK) {return SVA_INTERNAL_POSTPROCESSOR_ERROR;} + + if(sva_DP_isPrimarySubtask(instanceNum, subtaskDep.subtaskId)) + { + ffError=POP_FIFO_ELEM(pDesc->subtasksDependencyFifo,t_sva_dp_subtask_dependencies,subtaskDep); + if (ffError!=SVA_FIFO_OK) {return SVA_INTERNAL_POSTPROCESSOR_ERROR;} + subtaskDep.dependencies = pDesc->defaultConfiguredDependency; + ffError=PUSH_FIFO_ELEM(pDesc->subtasksDependencyFifo,t_sva_dp_subtask_dependencies,subtaskDep); + if (ffError!=SVA_FIFO_OK) {return SVA_INTERNAL_POSTPROCESSOR_ERROR;} + } + } + + + /*get time*/ + svaError=SVA_GetServiceSystemTime(serviceId,&systemTime); + if (svaError != SVA_OK) {return SVA_INTERNAL_POSTPROCESSOR_ERROR;} + + /*flush Input fifo*/ + + while(POP_FIFO_ELEM(pDesc->inputImageFifos.inUseFifo,t_sva_buffer_id,bufferId) != SVA_FIFO_EMPTY) + { + bmError=sva_BM_UpdateBufferStatus(bufferId,SVA_BUFFER_NOT_USED,systemTime); + if (bmError!=SVA_BM_OK) {return SVA_INTERNAL_POSTPROCESSOR_ERROR;} + } + while(POP_FIFO_ELEM(pDesc->inputImageFifos.pushFifo,t_sva_buffer_id,bufferId) != SVA_FIFO_EMPTY) + { + bmError=sva_BM_UpdateBufferStatus(bufferId,SVA_BUFFER_NOT_USED,systemTime); + if (bmError!=SVA_BM_OK) {return SVA_INTERNAL_POSTPROCESSOR_ERROR;} + } + + while(POP_FIFO_ELEM(pDesc->inputTimestampsFifos.pushFifo,t_sva_tm_timestamp, timeStamp) != SVA_FIFO_EMPTY) + { + } + + + + if ( + pDesc->confHandle.currentConf.deringingFilterMode != SVA_NONE_DERINGING_FILTER + || pDesc->confHandle.currentConf.deblockingFilterMode != SVA_NONE_DEBLOCKING_FILTER + || pDesc->confHandle.currentConf.aceMode == SVA_POSTPROCESSOR_ACE_EXTERNAL + ) + { + + while(POP_FIFO_ELEM(pDesc->inputParamsFifos.inUseFifo,t_sva_buffer_id,bufferId) != SVA_FIFO_EMPTY) + { + bmError=sva_BM_UpdateBufferStatus(bufferId,SVA_BUFFER_NOT_USED,systemTime); + if (bmError!=SVA_BM_OK) {return SVA_INTERNAL_POSTPROCESSOR_ERROR;} + } + while(POP_FIFO_ELEM(pDesc->inputParamsFifos.pushFifo,t_sva_buffer_id,bufferId) != SVA_FIFO_EMPTY) + { + bmError=sva_BM_UpdateBufferStatus(bufferId,SVA_BUFFER_NOT_USED,systemTime); + if (bmError!=SVA_BM_OK) {return SVA_INTERNAL_POSTPROCESSOR_ERROR;} + } + + + while(POP_FIFO_ELEM(pDesc->inputTimestampsFifos.pushFifo,t_sva_tm_timestamp, timeStamp) != SVA_FIFO_EMPTY) + { + } + + + } + + if (!pDesc->confHandle.currentConf.isDirectScreenAccess){ + do + { + ffError=POP_REVERSE_FIFO_ELEM(pDesc->outputImageFifos.inUseFifo,t_sva_buffer_id,bufferId); + if (ffError==SVA_FIFO_OK) + { + ffError=PUSH_REVERSE_FIFO_ELEM(pDesc->outputImageFifos.pushFifo,t_sva_buffer_id,bufferId); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + } + } while (ffError==SVA_FIFO_OK); + + } + + + return SVA_OK; +} +/****************************************************************************/ +/* NAME: t_sva_error sva_DP_DoFlushOut( */ +/* t_sva_service_id serviceId */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will flush output fifo. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - serviceId: service identifier */ +/* */ +/* OUT: none */ +/* */ +/* RETURN: t_sva_error */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PRIVATE t_sva_error sva_DP_DoFlushOut +( + t_sva_service_id serviceId +) +{ + t_sva_service_instance_num instanceNum = READ_INSTANCE_NUM_IN_SERVICE_ID(serviceId); + t_sva_dp_descriptor *pDesc=&displayDesc[instanceNum]; + t_uint32 systemTime; + t_sva_error svaError; + t_sva_tm_error tmError; + t_sva_dp_subtask_dependencies subtaskDep; + t_sva_ff_error ffError; + t_sva_buffer_id bufferId = 0; + t_sva_bm_error bmError; + t_uint16 i; + //t_sva_dp_pip_subtask_id pipSubtaskId; + + /*remove schedule tasks and push them back in subtasksDependencyFifo with default dep*/ + /*so they can be rescheduled */ + do + { + tmError=sva_TM_RemoveElemFromSubTaskList(pDesc->subtasksListId,&subtaskDep.subtaskId); + if (tmError==SVA_TM_OK) + { + + if(sva_DP_isPrimarySubtask(instanceNum, subtaskDep.subtaskId)) { + subtaskDep.dependencies = pDesc->defaultConfiguredDependency; + ffError=PUSH_FIFO_ELEM(pDesc->subtasksDependencyFifo,t_sva_dp_subtask_dependencies,subtaskDep); + if (ffError!=SVA_FIFO_OK) {return SVA_INTERNAL_POSTPROCESSOR_ERROR;} + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + } + else { + /* FIX ME */ + } + } + } while (tmError==SVA_TM_OK); + + + + for(i=0; inbSubtasks; i++) + { + ffError=READ_FIFO_ELEM(pDesc->subtasksDependencyFifo,t_sva_dp_subtask_dependencies,subtaskDep); + if (ffError!=SVA_FIFO_OK) {return SVA_INTERNAL_POSTPROCESSOR_ERROR;} + + if(sva_DP_isPrimarySubtask(instanceNum, subtaskDep.subtaskId)) + { + ffError=POP_FIFO_ELEM(pDesc->subtasksDependencyFifo,t_sva_dp_subtask_dependencies,subtaskDep); + if (ffError!=SVA_FIFO_OK) {return SVA_INTERNAL_POSTPROCESSOR_ERROR;} + subtaskDep.dependencies = pDesc->defaultConfiguredDependency; + ffError=PUSH_FIFO_ELEM(pDesc->subtasksDependencyFifo,t_sva_dp_subtask_dependencies,subtaskDep); + if (ffError!=SVA_FIFO_OK) {return SVA_INTERNAL_POSTPROCESSOR_ERROR;} + } + } + + /*get time*/ + svaError=SVA_GetServiceSystemTime(serviceId,&systemTime); + if (svaError != SVA_OK) {return SVA_INTERNAL_POSTPROCESSOR_ERROR;} + + /*flush fifo*/ + while(POP_FIFO_ELEM(pDesc->outputImageFifos.inUseFifo,t_sva_buffer_id,bufferId) != SVA_FIFO_EMPTY) + { + bmError=sva_BM_UpdateBufferStatus(bufferId,SVA_BUFFER_NOT_USED,systemTime); + if (bmError!=SVA_BM_OK) {return SVA_INTERNAL_POSTPROCESSOR_ERROR;} + } + while(POP_FIFO_ELEM(pDesc->outputImageFifos.pushFifo,t_sva_buffer_id,bufferId) != SVA_FIFO_EMPTY) + { + bmError=sva_BM_UpdateBufferStatus(bufferId,SVA_BUFFER_NOT_USED,systemTime); + if (bmError!=SVA_BM_OK) {return SVA_INTERNAL_POSTPROCESSOR_ERROR;} + } + + + return SVA_OK; +} + + +/****************************************************************************/ +/* NAME: t_sva_dp_error sva_DP_ResolveDependencies( */ +/* t_sva_service_instance_num instanceNum */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine tries to resolve any external pending dependencies */ +/* by checking data availability into push fifos */ +/* PARAMETERS: */ +/* IN : */ +/* - instanceNum: identifier of the Service instance */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: t_sva_dp_error */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_sva_dp_error sva_DP_ResolveDependencies(t_sva_service_instance_num instanceNum) +{ + t_sva_dp_descriptor *pDesc = &displayDesc[instanceNum]; + t_sva_dp_subtask_dependencies subTaskDep; + t_sva_tm_timestamp timeStamp; + t_sva_buffer_id bufferId=INVALID_BUFFER_ID; + t_sva_ff_error ffError=SVA_FIFO_OK; + t_sva_tm_error tmError=SVA_TM_OK; + t_sva_dp_error dpError = SVA_DP_OK; + t_bool dependencyNotSolved=FALSE; + t_sva_postprocessor_configuration *pConf=&pDesc->confHandle.currentConf; + + /*check that transition is valid*/ + if (sva_DP_isTransitionValid(instanceNum,SVA_DP_ALL_DEPENDENCIES_RESOLVED)==FALSE) {return SVA_DP_INVALID_TRANSITION;} + + + while (!IS_FIFO_EMPTY(pDesc->subtasksDependencyFifo) && dependencyNotSolved==FALSE) + { + + #ifdef __DEBUG + updateDisplayDebugTable[instanceNum].nbOfResolvedDep++; + #endif + + ffError = READ_FIFO_ELEM(pDesc->subtasksDependencyFifo, t_sva_dp_subtask_dependencies, subTaskDep); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + + if (subTaskDep.dependencies.inputImageDep == (t_bitfield)NOT_RESOLVED_DEPENDENCY) + { + t_sva_dpl_frame_buffer_in bufferIn; + + + /* + * We have some input image dependency to resolve + * so we check if we need also resolve params buffer dependency + * if it is the case we want to resolve the both together + */ + if (subTaskDep.dependencies.inputParamsDep == (t_bitfield)NOT_RESOLVED_DEPENDENCY && + IS_FIFO_EMPTY(pDesc->inputParamsFifos.pushFifo)) {break;} /* abort the input dependencies resolution */ + + /* + * so we check into the input Image buffer push fifo if we have a bufferId + */ + + #ifdef __DEBUG + ffError= READ_FIFO_ELEM(pDesc->inputImageFifos.pushFifo, t_sva_buffer_id, bufferId); + updateDisplayDebugTable[instanceNum].updateDebugDesc[updateDisplayDebugTable[instanceNum].nbOfResolvedDep%LOG_DEPTH].bufferId = bufferId; + updateDisplayDebugTable[instanceNum].updateDebugDesc[updateDisplayDebugTable[instanceNum].nbOfResolvedDep%LOG_DEPTH].isPopEmpty = TRUE; + #endif + + if (POP_FIFO_ELEM(pDesc->inputImageFifos.pushFifo, t_sva_buffer_id, bufferId) != SVA_FIFO_EMPTY) + { + + t_bool deblockingUpdate=FALSE; + + #ifdef __DEBUG + updateDisplayDebugTable[instanceNum].updateDebugDesc[updateDisplayDebugTable[instanceNum].nbOfResolvedDep%LOG_DEPTH].bufferId = bufferId; + updateDisplayDebugTable[instanceNum].updateDebugDesc[updateDisplayDebugTable[instanceNum].nbOfResolvedDep%LOG_DEPTH].isPopEmpty = FALSE; + #endif + + /*handle configuration change*/ + + if (pDesc->confHandle.confState!=SVA_DP_IMMEDIATE_CONF_CHANGE_NEED) + { + sva_DP_ConfigurationChangeOnSolveDep(instanceNum,subTaskDep,bufferId); + } + + + /* So we put it into the in use fifo */ + ffError = PUSH_FIFO_ELEM(pDesc->inputImageFifos.inUseFifo, t_sva_buffer_id, bufferId); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + + /* we update the given subtask with the given buffer */ + sva_BM_GetBufferPhysicalAddress(bufferId, &bufferIn.addr_source_buffer); + + pDesc->pipAddrSourceBuffer = bufferIn.addr_source_buffer; + + /* We update the dependency of the given subtask */ + ffError=UPDATE_FIFO_ELEM_FIELD(pDesc->subtasksDependencyFifo, + t_sva_dp_subtask_dependencies, .dependencies.inputImageDep, + RESOLVED_DEPENDENCY); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + + subTaskDep.dependencies.inputImageDep = (t_bitfield)RESOLVED_DEPENDENCY; + + if (subTaskDep.dependencies.inputParamsDep == (t_bitfield)NOT_RESOLVED_DEPENDENCY) + { + ffError = POP_FIFO_ELEM(pDesc->inputParamsFifos.pushFifo, t_sva_buffer_id, bufferId); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + + ffError = PUSH_FIFO_ELEM(pDesc->inputParamsFifos.inUseFifo, t_sva_buffer_id, bufferId); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + + if((pConf->deringingFilterMode != SVA_NONE_DERINGING_FILTER)||(pConf->deblockingFilterMode != SVA_NONE_DEBLOCKING_FILTER)) + { + sva_BM_GetBufferPhysicalAddress(bufferId, &bufferIn.addr_deblocking_param_buffer ); + pDesc->pipDeblockingParamBuffer = bufferIn.addr_deblocking_param_buffer; + + deblockingUpdate=TRUE; + } + else if(pConf->aceMode == SVA_POSTPROCESSOR_ACE_EXTERNAL) + { + t_logical_address addr; + + //Get ACE offset from buffer + sva_BM_GetBufferLogicalAddress(bufferId, &addr ); + //init subtaslfield + tmError = sva_TM_UpdateSubTaskField(SVA_TM_INTERMEDIATE_FIELD_TO_UPDATE, subTaskDep.subtaskId, SVA_TM_DIS_ADDR_IN_FRAME_PARAMETERS, FCMD_COPY,(t_uint32) addr, 2, 8); + if (tmError!= SVA_TM_OK) {return SVA_DP_TM_LINKED_ERROR;} + } + else + { + dpError = SVA_DP_TM_LINKED_ERROR; + HCL_DEBUG_ASSERT(dpError == SVA_DP_OK); + } + + /* We update the dependency of the given subtask */ + ffError=UPDATE_FIFO_ELEM_FIELD(pDesc->subtasksDependencyFifo, + t_sva_dp_subtask_dependencies, .dependencies.inputParamsDep, + RESOLVED_DEPENDENCY); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + subTaskDep.dependencies.inputParamsDep = (t_bitfield)RESOLVED_DEPENDENCY; + + + } + + + if (deblockingUpdate==TRUE) + { + tmError = sva_TM_UpdateSubTaskField(SVA_TM_INTERMEDIATE_FIELD_TO_UPDATE, subTaskDep.subtaskId, SVA_TM_DIS_ADDR_IN_FRAME_BUFFER, FCMD_COPY,(t_uint32) &bufferIn, 0, 8); + if (tmError!= SVA_TM_OK) {return SVA_DP_TM_LINKED_ERROR;} + } + else + { + tmError = sva_TM_UpdateSubTaskField(SVA_TM_INTERMEDIATE_FIELD_TO_UPDATE, subTaskDep.subtaskId, SVA_TM_DIS_ADDR_IN_FRAME_BUFFER, FCMD_COPY,(t_uint32) &bufferIn, 0, 4); + if (tmError!= SVA_TM_OK) {return SVA_DP_TM_LINKED_ERROR;} + } + + } + + } + + if (subTaskDep.dependencies.outputImageDep == (t_bitfield)NOT_RESOLVED_DEPENDENCY) + { + t_sva_dpl_frame_buffer_out bufferOut; + + /* + * We have some output image dependency to resolve + * so we check into the output Image buffer push fifo if we have a bufferId + */ + if (POP_FIFO_ELEM(pDesc->outputImageFifos.pushFifo, t_sva_buffer_id, bufferId) != SVA_FIFO_EMPTY) + { + + + + /*handle configuration change*/ + if (pDesc->confHandle.confState!=SVA_DP_IMMEDIATE_CONF_CHANGE_NEED) + { + sva_DP_ConfigurationChangeOnSolveDep(instanceNum,subTaskDep,bufferId); + } + + /* So we put it into the in use fifo */ + ffError = PUSH_FIFO_ELEM(pDesc->outputImageFifos.inUseFifo, t_sva_buffer_id, bufferId); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + + /* we update the given subtask with the given buffer */ + sva_BM_GetBufferPhysicalAddress(bufferId, &bufferOut.addr_dest_buffer ); + + //pDesc->pipDestBuffer = bufferOut.addr_dest_buffer; + + /* We update the dependency of the given subtask */ + ffError=UPDATE_FIFO_ELEM_FIELD(pDesc->subtasksDependencyFifo, + t_sva_dp_subtask_dependencies, .dependencies.outputImageDep, + RESOLVED_DEPENDENCY); + subTaskDep.dependencies.outputImageDep = (t_bitfield)RESOLVED_DEPENDENCY; + tmError = sva_TM_UpdateSubTaskField(SVA_TM_INTERMEDIATE_FIELD_TO_UPDATE, subTaskDep.subtaskId, SVA_TM_DIS_ADDR_OUT_FRAME_BUFFER, FCMD_COPY,(t_uint32) &bufferOut, 0, 4); + if (tmError!= SVA_TM_OK) {return SVA_DP_TM_LINKED_ERROR;} + } + } + + + #ifdef __DEBUG + updateDisplayDebugTable[instanceNum].updateDebugDesc[updateDisplayDebugTable[instanceNum].nbOfResolvedDep%LOG_DEPTH].isResolvedAll = FALSE; + #endif + + { + /* Implementation for change request CR0054 */ + t_bool Checkdependency = TRUE; + + if (sva_IsServiceTimeRunning(pDesc->serviceId) == FALSE) + { + ffError = READ_FIFO_ELEM(pDesc->inputTimestampsFifos.pushFifo, t_sva_tm_timestamp, timeStamp); + if (timeStamp.timestampType == SVA_TM_ABSOLUTE) + { + t_uint32 service_time; + SVA_GetServiceSystemTime(pDesc->serviceId, &service_time); + if (timeStamp.timestampValue>service_time) + { + /* do n't try to resolve or check for resolved dependencies since service system time is less than PRESENTATION TIME STAMP*/ + Checkdependency = FALSE; + } + } + } + + /* Check if all dependencies are be resolved */ + if ( + subTaskDep.dependencies.inputImageDep != (t_bitfield)NOT_RESOLVED_DEPENDENCY && + subTaskDep.dependencies.inputParamsDep != (t_bitfield)NOT_RESOLVED_DEPENDENCY && + subTaskDep.dependencies.outputImageDep != (t_bitfield)NOT_RESOLVED_DEPENDENCY && + Checkdependency != FALSE + ) + { + + + #ifdef __DEBUG + updateDisplayDebugTable[instanceNum].updateDebugDesc[updateDisplayDebugTable[instanceNum].nbOfResolvedDep%LOG_DEPTH].isResolvedAll = TRUE; + #endif + /*handle configuration change*/ + if (pDesc->confHandle.confState==SVA_DP_IMMEDIATE_CONF_CHANGE_NEED) + { + sva_DP_ConfigurationChangeOnSolveDep(instanceNum,subTaskDep,bufferId); + } + + /* Remove the subtask from the dependency fifo */ + ffError = POP_FIFO_ELEM(pDesc->subtasksDependencyFifo, t_sva_dp_subtask_dependencies, subTaskDep); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + ffError = POP_FIFO_ELEM(pDesc->inputTimestampsFifos.pushFifo, t_sva_tm_timestamp, timeStamp); + sva_DP_UpdateInstanceStatesMachine(instanceNum,SVA_DP_ALL_DEPENDENCIES_RESOLVED); + + + if ((pDesc->pipActivated == SVA_DP_PIP_CONFIGURATION)|| (pDesc->pipActivated == SVA_DP_PIP_RUNNING)) + { + + sva_DP_UpdatePIPSubtasksAndAddToSubtaskList(subTaskDep.subtaskId, instanceNum, pDesc->subtasksListId, &timeStamp); + pDesc->pipActivated = SVA_DP_PIP_RUNNING; + } + else { + tmError=sva_TM_AddElemToSubTaskList(pDesc->subtasksListId,subTaskDep.subtaskId, &timeStamp, 1); + HCL_DEBUG_ASSERT(tmError==SVA_TM_OK); + } + + + } + else {dependencyNotSolved=TRUE;} + } + + } + + + + + + return SVA_DP_OK; +} + + + +/****************************************************************************/ +/* NAME: t_bool sva_DP_isChangeConfIsImmediate( */ +/* t_sva_dp_conf_handle * pConfHandle */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PRIVATE t_bool sva_DP_isChangeConfIsImmediate(t_bool dsa_enable, t_sva_dp_conf_handle * pConfHandle) { + + + HCL_ASSERT(pConfHandle != 0); + + /* + for(i=0; inbParams; i++) { + if ((pConfHandle->paramId[i]== SVA_POSTPROCESSOR_SOURCEFRAME_SIZE)|| + ((pConfHandle->paramId[i]== SVA_POSTPROCESSOR_CLIPPING)&&(dsa_enable==FALSE))|| + (pConfHandle->paramId[i]== SVA_POSTPROCESSOR_CROPPING)|| + ((pConfHandle->paramId[i]== SVA_POSTPROCESSOR_RESIZE)&&(dsa_enable==FALSE)) + ) { + return FALSE; + } + } + */ + + return TRUE; + +} + + +/****************************************************************************/ +/* NAME: t_sva_dp_error sva_DP_ResetParamConfHandle( */ +/* t_sva_dp_conf_handle * pConfHandle */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PRIVATE void sva_DP_ResetParamConfHandle(t_sva_dp_conf_handle * pConfHandle) { + t_uint8 i; + HCL_ASSERT(pConfHandle !=0 ); + for(i=0; inbParams; i++) { + pConfHandle->paramId[i] = SVA_POSTPROCESSOR_MATRIX_COEFF; + } + + pConfHandle->nbParams = 0; + +} + + + +/****************************************************************************/ +/* NAME: t_sva_dp_error sva_DP_ConfigurationChangeOnPush( */ +/* t_sva_service_id serviceId, */ +/* t_sva_buffer_type bufferType, */ +/* t_sva_push_mode pushMode, */ +/* t_sva_buffer_id bufferId */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will check is the push buffer is of the type and mode need*/ +/* for a configuration change. */ +/* In that case it will keep bufferId so the configuration become fully */ +/* active when buffer depencency will be solve. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - serviceId: service descriptor on which push occur */ +/* - bufferType : type of buffer push */ +/* - pushMode : mode of buffer push */ +/* - bufferId : buffer identifier */ +/* */ +/* OUT: none */ +/* */ +/* RETURN: void */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PRIVATE void sva_DP_ConfigurationChangeOnPush( + t_sva_service_id serviceId, + t_sva_buffer_type bufferType, + t_sva_push_mode pushMode, + t_sva_buffer_id bufferId +) +{ + t_sva_service_instance_num instanceNum = READ_INSTANCE_NUM_IN_SERVICE_ID(serviceId); + t_sva_dp_descriptor *pDesc=&displayDesc[instanceNum]; + + /* change config for input buffer */ + if ( ((pDesc->confHandle.confState==SVA_DP_WAIT_FOR_BUFFER_IN_ONLY)||(pDesc->confHandle.confState==SVA_DP_WAIT_FOR_BUFFER_INOUT)) && + bufferType == SVA_IMAGE_BUFFER_TYPE && + pushMode == SVA_PUSH_IN + ) + { + + pDesc->confHandle.currentConf=pDesc->confHandle.nextConf; + pDesc->confHandle.bufferId[0]=bufferId; + pDesc->confHandle.needs.buffer_in_id_needed = (t_bitfield)TRUE; + } + + /* change config for output buffer */ + if ( ((pDesc->confHandle.confState==SVA_DP_WAIT_FOR_BUFFER_OUT_ONLY)||(pDesc->confHandle.confState==SVA_DP_WAIT_FOR_BUFFER_INOUT)) && + bufferType == SVA_IMAGE_BUFFER_TYPE && + pushMode == SVA_PUSH_OUT + ) + { + + pDesc->confHandle.currentConf=pDesc->confHandle.nextConf; + pDesc->confHandle.bufferId[1]=bufferId; + pDesc->confHandle.needs.buffer_out_id_needed = (t_bitfield)TRUE; + } + + + /* compute confState */ + if ((pDesc->confHandle.needs.buffer_in_id_needed == (t_bitfield)TRUE) && (pDesc->confHandle.needs.buffer_out_id_needed == (t_bitfield)TRUE)) + { + pDesc->confHandle.confState = SVA_DP_WAIT_FOR_BUFFER_ID_INOUT; + pDesc->confHandle.needs.buffer_in_id_needed = (t_bitfield)FALSE; + pDesc->confHandle.needs.buffer_out_id_needed = (t_bitfield)FALSE; + + } + else if (pDesc->confHandle.needs.buffer_in_id_needed == (t_bitfield)TRUE) + { + pDesc->confHandle.confState = SVA_DP_WAIT_FOR_BUFFER_ID_IN_ONLY; + pDesc->confHandle.needs.buffer_in_id_needed = (t_bitfield)FALSE; + } + else if (pDesc->confHandle.needs.buffer_out_id_needed == (t_bitfield)TRUE) + { + pDesc->confHandle.confState = SVA_DP_WAIT_FOR_BUFFER_ID_OUT_ONLY; + pDesc->confHandle.needs.buffer_out_id_needed = (t_bitfield)FALSE; + } + +} + +/****************************************************************************/ +/* NAME: t_sva_gb_error sva_DP_ConfigurationChangeOnSolveDep( */ +/* t_sva_service_instance_num instanceNum, */ +/* t_sva_dp_subtask_dependencies subTaskDep, */ +/* t_sva_buffer_id bufferId */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine is call from sva_DP_ResolveDependencies() API. It will be */ +/* In charge to do two different things. */ +/* 1) In case we have a synchronized configuration change, we wait to */ +/* solve dependencies for correct buffer id to change configuration */ +/* to use. */ +/* 2) Update paramin of subtasks at the right instant */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - serviceId: service descriptor on which push occur */ +/* - bufferType : type of buffer push */ +/* - pushMode : mode of buffer push */ +/* - bufferId : buffer identifier */ +/* */ +/* OUT: none */ +/* */ +/* RETURN: void */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PRIVATE void sva_DP_ConfigurationChangeOnSolveDep( + t_sva_service_instance_num instanceNum, + t_sva_dp_subtask_dependencies subTaskDep, + t_sva_buffer_id bufferId +) +{ + t_sva_dp_descriptor *pDesc=&displayDesc[instanceNum]; + t_sva_postprocessor_configuration *pConf=&pDesc->confHandle.currentConf; + + + /*first check in case we are in sync mode if bufferid is the on we are waiting for*/ + /* 1 */ + if (pDesc->confHandle.confState==SVA_DP_WAIT_FOR_BUFFER_ID_IN_ONLY && + pDesc->confHandle.bufferId[0]==bufferId) + { + pDesc->confHandle.currentConfCounter++; + pDesc->confHandle.confState=SVA_DP_SYNC_CONF_CHANGE_NEED; + } + + /* 2 */ + if (pDesc->confHandle.confState==SVA_DP_WAIT_FOR_BUFFER_ID_OUT_ONLY && + pDesc->confHandle.bufferId[1]==bufferId) + { + pDesc->confHandle.currentConfCounter++; + pDesc->confHandle.confState=SVA_DP_SYNC_CONF_CHANGE_NEED; + } + + /* 3 */ + if (pDesc->confHandle.confState==SVA_DP_WAIT_FOR_BUFFER_ID_INOUT && + pDesc->confHandle.bufferId[0]==bufferId) + { + pDesc->confHandle.currentConfCounter++; + pDesc->confHandle.confState=SVA_DP_SYNC_CONF_CHANGE_ABOUT_TO_BE_NEEDED; + } + + /* 4 */ + if (pDesc->confHandle.confState==SVA_DP_SYNC_CONF_CHANGE_ABOUT_TO_BE_NEEDED && + pDesc->confHandle.bufferId[1]==bufferId) + { + pDesc->confHandle.currentConfCounter++; + pDesc->confHandle.confState=SVA_DP_SYNC_CONF_CHANGE_NEED; + } + + + #ifdef __DEBUG + updateDisplayDebugTable[instanceNum].updateDebugDesc[updateDisplayDebugTable[instanceNum].nbOfResolvedDep%LOG_DEPTH].updateInfos.subtaskId=subTaskDep.subtaskId; + updateDisplayDebugTable[instanceNum].updateDebugDesc[updateDisplayDebugTable[instanceNum].nbOfResolvedDep%LOG_DEPTH].updateInfos.isParamInUpdate=FALSE; + #endif + + /* then try to update subtask paramin*/ + if (pDesc->confHandle.confState==SVA_DP_SYNC_CONF_CHANGE_NEED || + pDesc->confHandle.confState==SVA_DP_IMMEDIATE_CONF_CHANGE_NEED) + { + t_uint32 index; + t_bool exitForLoop=FALSE; + + /*search for conf counter of subtaskid*/ + for(index=0;indexnbSubtasks && exitForLoop==FALSE;index++) + { + if (pDesc->subtasksIdArray[index]==subTaskDep.subtaskId) {exitForLoop=TRUE;} + } + index--; + + /*check if we need to change conf*/ + if (pDesc->subtasksConfCounter[index]!=pDesc->confHandle.currentConfCounter) + { + //t_sva_dpl_param_in paramInBuffer; + t_sva_tm_error tmError; + + + #ifdef __DEBUG + updateDisplayDebugTable[instanceNum].updateDebugDesc[updateDisplayDebugTable[instanceNum].nbOfResolvedDep%LOG_DEPTH].updateInfos.index=index; + updateDisplayDebugTable[instanceNum].updateDebugDesc[updateDisplayDebugTable[instanceNum].nbOfResolvedDep%LOG_DEPTH].updateInfos.isParamInUpdate=TRUE; + #endif + + /*we need to update subtask with new paramin*/ + sva_DP_BuildParamInStructure(pConf,&pDesc->newParamInBuffer); + tmError=sva_TM_InitSubTaskField(subTaskDep.subtaskId,SVA_TM_DIS_ADDR_IN_PARAMETERS, + (t_logical_address)&pDesc->newParamInBuffer,sizeof(t_sva_dpl_param_in)); + HCL_DEBUG_ASSERT(tmError==SVA_TM_OK); + + /* need also to do it for PIP subtasks if PIP activated */ + pDesc->isUpdateConf = TRUE; + + + + /* and inout if ace */ + if (pDesc->confHandle.isAceOffsetNeedUpdate==TRUE) + { + t_sva_dpl_param_inout paramInOutBuffer; + + /*we need to update subtask with new paraminout*/ + + paramInOutBuffer.ace_offset0 = pDesc->confHandle.newAceOffset.ace_offset_0; + paramInOutBuffer.ace_offset1 = pDesc->confHandle.newAceOffset.ace_offset_1; + paramInOutBuffer.ace_offset2 = pDesc->confHandle.newAceOffset.ace_offset_2; + paramInOutBuffer.ace_offset3 = pDesc->confHandle.newAceOffset.ace_offset_3; + + tmError=sva_TM_InitSubTaskField(subTaskDep.subtaskId,SVA_TM_DIS_ADDR_IN_FRAME_PARAMETERS, + (t_logical_address)¶mInOutBuffer,sizeof(t_sva_dpl_param_inout)); + HCL_DEBUG_ASSERT(tmError==SVA_TM_OK); + + /*only the first subtask need to be updated*/ + pDesc->confHandle.isAceOffsetNeedUpdate=FALSE; + } + + /*update conf counter*/ + pDesc->subtasksConfCounter[index]=pDesc->confHandle.currentConfCounter; + + + if(pDesc->state == SVA_DP_WAIT_FOR_START) + { + t_uint16 k; + /* update all SUBTASK_DEFAULT_NUMBER subtaks with new parameters since no subtask is actually used */ + for(k=0;knbSubtasks;k++) + { + if (k!= index) + { + tmError=sva_TM_InitSubTaskField(pDesc->subtasksIdArray[k],SVA_TM_DIS_ADDR_IN_PARAMETERS, + (t_logical_address)&pDesc->newParamInBuffer,sizeof(t_sva_dpl_param_in)); + HCL_DEBUG_ASSERT(tmError==SVA_TM_OK); + + } + } + + + /* increase counter for all */ + for(k=0;knbSubtasks; k++) + pDesc->subtasksConfCounter[k] = pDesc->subtasksConfCounter[index]; + + /* change state */ + pDesc->confHandle.confState=SVA_DP_NO_CONF_CHANGE_NEED; + + } + + + + + + } + else + { + /*all subtask have been updated*/ + pDesc->confHandle.confState=SVA_DP_NO_CONF_CHANGE_NEED; + } + } +} + +/****************************************************************************/ +/* NAME: t_sva_gb_error sva_DP_CreateAndConfigurePIPSubTasks( */ +/* t_sva_service_id , */ +/* t_sva_tm_subtask_id * */ +/* ) */ +/****************************************************************************/ +PRIVATE t_sva_error sva_DP_CreateAndConfigurePIPSubTasks(t_sva_service_id serviceId, t_sva_tm_subtask_id* pPIPSubTaskIdArray) { + + t_sva_tm_task_ctrl_desc displayTaskDesc; + t_sva_tm_field_ctrl_desc displayFieldDescArray[DISPLAY_FIELD_NUMBER]; + t_sva_tm_subtask_type subtaskType; + t_sva_tm_error tmError; + t_uint8 i,j; + t_sva_ff_error ffError; + t_sva_error svaError=SVA_OK; + + t_sva_service_instance_num instanceNum = READ_INSTANCE_NUM_IN_SERVICE_ID(serviceId); + t_sva_dp_descriptor *pDesc=&displayDesc[instanceNum]; + t_sva_postprocessor_configuration *pConf=&pDesc->confHandle.currentConf; + + + /* Prepare the task control descriptor */ + displayTaskDesc.memId = DISPLAY_DEFAULT_MEMORY_ID; + displayTaskDesc.fieldnb = DISPLAY_FIELD_NUMBER; + displayTaskDesc.pfieldctrldesc = displayFieldDescArray; + + /* Copy default display field descriptor array */ + for (i=0; i < DISPLAY_FIELD_NUMBER; i++) + { + displayFieldDescArray[i] = defaultDisplayFieldDescArray[i]; + } + + /* Extract parameters from configuration */ + subtaskType = filter_mode_2_subtask_type[pConf->deblockingFilterMode][pConf->deringingFilterMode]; + + + + + /* Create SECONDARY SUBTASKS */ + if (pDesc->is_ppp_tiling){ + for (i=0; i < (pDesc->pipPieceCounter-1)*pDesc->nbSubtasks; i++){ + tmError=sva_TM_CreateSubTask( + SVA_TM_DISPLAY, + &displayTaskDesc, + subtaskType, + pDesc->postProc, + SVA_TM_NO_SYNCHRO, + SVA_TM_EOT_EN, + SVA_TM_BBM_DEFAULT, + &pDesc->pipSubtasksIdArrayNoSynchro[i] + ); + if (tmError != SVA_TM_OK) {return SVA_INTERNAL_POSTPROCESSOR_ERROR;} + } + }else{ + for (i=0; i < pDesc->nbPipSubtasks; i++) + { + + + tmError=sva_TM_CreateSubTask( + SVA_TM_DISPLAY, + &displayTaskDesc, + subtaskType, + pDesc->postProc, + SVA_TM_NO_SYNCHRO, + SVA_TM_EOT_EN, + SVA_TM_BBM_DEFAULT, + &pDesc->pipSubtasksIdArrayNoSynchro[i] + ); + + + if (tmError != SVA_TM_OK) {return SVA_INTERNAL_POSTPROCESSOR_ERROR;} + } + } + + + /* + * Initialize the param_in structure + */ + { + t_sva_dpl_param_in paramInBuffer; + + sva_DP_BuildParamInStructure(pConf, ¶mInBuffer); + + if (pDesc->is_ppp_tiling){ + for (i=0; i<(pDesc->pipPieceCounter-1)*pDesc->nbSubtasks; i++) + { + tmError = sva_TM_InitSubTaskField(pDesc->pipSubtasksIdArrayNoSynchro[i], + SVA_TM_DIS_ADDR_IN_PARAMETERS, + (t_logical_address) ¶mInBuffer, + sizeof(t_sva_dpl_param_in)); + + if (tmError != SVA_TM_OK) {return SVA_INTERNAL_POSTPROCESSOR_ERROR;} + } + }else{ + for (i=0; inbPipSubtasks; i++) + { + tmError = sva_TM_InitSubTaskField(pDesc->pipSubtasksIdArrayNoSynchro[i], + SVA_TM_DIS_ADDR_IN_PARAMETERS, + (t_logical_address) ¶mInBuffer, + sizeof(t_sva_dpl_param_in)); + + if (tmError != SVA_TM_OK) {return SVA_INTERNAL_POSTPROCESSOR_ERROR;} + } + } + + } + /* + * Initialize paramInOUt for ACE + */ + { + t_sva_dpl_param_inout paramInOutBuffer; + paramInOutBuffer.ace_offset0 = 0; + paramInOutBuffer.ace_offset1 = 0; + paramInOutBuffer.ace_offset2 = 0; + paramInOutBuffer.ace_offset3 = 0; + + if (pDesc->is_ppp_tiling){ + for (i=0; i<(pDesc->pipPieceCounter-1)*pDesc->nbSubtasks; i++) + { + + tmError = sva_TM_InitSubTaskField(pDesc->pipSubtasksIdArrayNoSynchro[i], + SVA_TM_DIS_ADDR_IN_FRAME_PARAMETERS, + (t_logical_address) ¶mInOutBuffer, + sizeof(t_sva_dpl_param_inout)); + + if (tmError != SVA_TM_OK) {return SVA_INTERNAL_POSTPROCESSOR_ERROR;} + } + }else{ + for (i=0; inbPipSubtasks; i++) + { + + tmError = sva_TM_InitSubTaskField(pDesc->pipSubtasksIdArrayNoSynchro[i], + SVA_TM_DIS_ADDR_IN_FRAME_PARAMETERS, + (t_logical_address) ¶mInOutBuffer, + sizeof(t_sva_dpl_param_inout)); + + if (tmError != SVA_TM_OK) {return SVA_INTERNAL_POSTPROCESSOR_ERROR;} + } + } + } + + /* + * Initialize dspl_frame_out, only in case of DSA + */ + { + t_sva_dpl_frame_buffer_out bufferOut; + if (pDesc->confHandle.currentConf.isDirectScreenAccess) + { + + bufferOut.addr_dest_buffer = pConf->screenFrameBufferBaseAddr; + if (pDesc->is_ppp_tiling){ + for (i=0; i<(pDesc->pipPieceCounter-1)*pDesc->nbSubtasks; i++) + { + tmError = sva_TM_InitSubTaskField(pDesc->pipSubtasksIdArrayNoSynchro[i],SVA_TM_DIS_ADDR_OUT_FRAME_BUFFER,(t_logical_address) &bufferOut, sizeof(t_sva_dpl_frame_buffer_out)>>2); + if (tmError != SVA_TM_OK) {return SVA_INTERNAL_POSTPROCESSOR_ERROR;} + } + }else{ + for (i=0; inbPipSubtasks; i++) + { + tmError = sva_TM_InitSubTaskField(pDesc->pipSubtasksIdArrayNoSynchro[i],SVA_TM_DIS_ADDR_OUT_FRAME_BUFFER,(t_logical_address) &bufferOut, sizeof(t_sva_dpl_frame_buffer_out)>>2); + if (tmError != SVA_TM_OK) {return SVA_INTERNAL_POSTPROCESSOR_ERROR;} + } + } + + + } + } + + /* + * Initialize internal buffer + */ + if((pConf->transformId == SVA_POSTPROCESSOR_YUV420PL_TO_RGB) + ||(pConf->transformId == SVA_POSTPROCESSOR_YUV420MB_TO_YUV420MB) + ||(pConf->transformId == SVA_POSTPROCESSOR_YUV420PL_TO_YUV422PL) + ||(pConf->transformId == SVA_POSTPROCESSOR_YUV422PL_TO_RGB) + ||(pConf->transformId == SVA_POSTPROCESSOR_YUV420MB_TO_YUV420_SEP_COMP_MB) + ||(pConf->transformId == SVA_POSTPROCESSOR_YUV420MB_TO_YUV422_SEP_COMP_MB) + ) + { + t_physical_address tempBlockPhyAddress; + t_sva_dpl_internal_buf internalBuffer; + + sva_MM_GetBlockPhysicalAddress(pDesc->tempBlockId, &tempBlockPhyAddress); + + internalBuffer.addr_temp_buffer = tempBlockPhyAddress; + if (pDesc->is_ppp_tiling){ + for(i=0; i<(pDesc->pipPieceCounter-1)*pDesc->nbSubtasks; i++) + { + tmError=sva_TM_InitSubTaskField(pDesc->pipSubtasksIdArrayNoSynchro[i],SVA_TM_DIS_ADDR_INTERNAL_BUFFER,(t_uint32)&internalBuffer,sizeof(t_sva_dpl_internal_buf)); + if (tmError != SVA_TM_OK) {return SVA_INTERNAL_POSTPROCESSOR_ERROR;} + } + }else{ + for(i=0; inbPipSubtasks; i++) + { + + tmError=sva_TM_InitSubTaskField(pDesc->pipSubtasksIdArrayNoSynchro[i],SVA_TM_DIS_ADDR_INTERNAL_BUFFER,(t_uint32)&internalBuffer,sizeof(t_sva_dpl_internal_buf)); + if (tmError != SVA_TM_OK) {return SVA_INTERNAL_POSTPROCESSOR_ERROR;} + } + } + } + + + /* push piptask_id in fifo */ + if (pDesc->is_ppp_tiling){ + for (i=0; inbSubtasks; i++) //FIXME: will this be correct? + //for (i=0; i<(pDesc->nbSubtasks*pDesc->pipPieceCounter)/(pDesc->pipPieceCounter-1); i++) //Patch + { + t_sva_dp_pip_subtask_id pipSubtaskId; + pipSubtaskId.primarySubtaskId = 0xAAAAAAAA; + + for(j=0; jpipPieceCounter-1; j++) { + pipSubtaskId.secSubtaskId[j] = pDesc->pipSubtasksIdArrayNoSynchro[(pDesc->pipPieceCounter-1)*i+j]; + } + ffError=PUSH_FIFO_ELEM(pDesc->pipSubtasksFifos.pushFifo, t_sva_dp_pip_subtask_id, pipSubtaskId ); + if (ffError!=SVA_FIFO_OK) {svaError=SVA_INTERNAL_FIFOS_FULL;} + } + }else{ + for (i=0; inbPipSubtasks/(pDesc->pipPieceCounter-1); i++) + { + t_sva_dp_pip_subtask_id pipSubtaskId; + pipSubtaskId.primarySubtaskId = 0xAAAAAAAA; + + for(j=0; jpipPieceCounter-1; j++) { + pipSubtaskId.secSubtaskId[j] = pDesc->pipSubtasksIdArrayNoSynchro[(pDesc->pipPieceCounter-1)*i+j]; + } + ffError=PUSH_FIFO_ELEM(pDesc->pipSubtasksFifos.pushFifo, t_sva_dp_pip_subtask_id, pipSubtaskId ); + if (ffError!=SVA_FIFO_OK) {svaError=SVA_INTERNAL_FIFOS_FULL;} + } + } + return svaError; + + +} + + +/****************************************************************************/ +/* NAME: void sva_DP_ComputePieces( */ +/* t_sva_service_instance_num instanceNum */ +/* ) */ +/****************************************************************************/ +void sva_DP_ComputePipPieces(t_sva_service_instance_num instanceNum) { + t_sva_dp_descriptor *pDesc=&displayDesc[instanceNum]; + t_sva_window_desc *pPipWindowDesc = &pDesc->pipWindowDesc; + t_sva_postprocessor_configuration *pConf = &pDesc->confHandle.nextConf; + + + t_uint32 sourceWidth; + t_uint32 sourceHeight; + t_uint16 count=0; + t_uint16 videoOffsetX=pDesc->confHandle.currentConf.videoFrameBufferDesc.window.imageOffset.offsetX; + t_uint16 videoOffsetY=pDesc->confHandle.currentConf.videoFrameBufferDesc.window.imageOffset.offsetY; + t_uint16 pipOffsetX=0; + t_uint16 pipOffsetY=0; + t_uint32 temp; + + t_sva_ppp_tile_info* tiles = pDesc->tile_info_cur; //pDesc->tile_info; + t_sva_dp_hw_rotation_mirroring hwTransfo; + + hwTransfo.mirroring = rot_mir_hclapi2hwapi[pConf->rotationMode][pConf->mirrorMode].mirroring; + hwTransfo.rotation = rot_mir_hclapi2hwapi[pConf->rotationMode][pConf->mirrorMode].rotation; + + + + /* modify source sense if rotation 90/270 */ + if (hwTransfo.rotation == SVA_HW_ROTATION_NONE) + { + sourceWidth = pConf->sourceFrameDesc.window.image.width; + sourceHeight = pConf->sourceFrameDesc.window.image.height; + } + else + { + sourceWidth = pConf->sourceFrameDesc.window.image.height; + sourceHeight = pConf->sourceFrameDesc.window.image.width; + + } + + /* compute scale(=resize factor) if resize */ + pDesc->scaleX = (pConf->resizedImageDesc.width* SVA_DP_FACTOR)/sourceWidth; + pDesc->scaleY = (pConf->resizedImageDesc.height*SVA_DP_FACTOR)/sourceHeight; + pDesc->iScaleX = (sourceWidth*SVA_DP_FACTOR)/pConf->resizedImageDesc.width; + pDesc->iScaleY = (sourceHeight*SVA_DP_FACTOR)/pConf->resizedImageDesc.height; + + + if (pDesc->is_ppp_tiling){ + while(tiles && (countpipPieceCounter) ){ //all tiles + if( tiles->image.height && tiles->image.width ){ + /* Aligned cut-off pieces and destination pieces (computed from aligned pieces) */ + pDesc->newDestinationPipRectangular[count].image.width = tiles->image.width; + pDesc->newDestinationPipRectangular[count].image.height = tiles->image.height; + pDesc->newDestinationPipRectangular[count].imageOffset.offsetX = tiles->imageOffset.offsetX; + pDesc->newDestinationPipRectangular[count].imageOffset.offsetY = tiles->imageOffset.offsetY; + + pDesc->alignSourcePipRectangular[count].image.width = (pDesc->newDestinationPipRectangular[count].image.width * SVA_DP_FACTOR)/pDesc->scaleX; + pDesc->alignSourcePipRectangular[count].image.height = (pDesc->newDestinationPipRectangular[count].image.height* SVA_DP_FACTOR)/pDesc->scaleY; + pDesc->alignSourcePipRectangular[count].imageOffset.offsetX = (pDesc->newDestinationPipRectangular[count].imageOffset.offsetX* SVA_DP_FACTOR)/pDesc->scaleX; + pDesc->alignSourcePipRectangular[count].imageOffset.offsetY = (pDesc->newDestinationPipRectangular[count].imageOffset.offsetY* SVA_DP_FACTOR)/pDesc->scaleY; + + SVA_DP_REALIGN_16(pDesc->alignSourcePipRectangular[count].image.width, pDesc->alignSourcePipRectangular[count].image.width); + SVA_DP_REALIGN_16(pDesc->alignSourcePipRectangular[count].image.height, pDesc->alignSourcePipRectangular[count].image.height); + SVA_DP_REALIGN_16(pDesc->alignSourcePipRectangular[count].imageOffset.offsetX, pDesc->alignSourcePipRectangular[count].imageOffset.offsetX); + SVA_DP_REALIGN_16(pDesc->alignSourcePipRectangular[count].imageOffset.offsetY, pDesc->alignSourcePipRectangular[count].imageOffset.offsetY); + + pDesc->Index[count] = count+1; + count++; + } + //tiles = tiles->next_tile; + tiles++; + } + }else{ + pDesc->pipPieceCounter = 0; + + /* recompute pip according transfo (mirror, rotate, ...) */ + pipOffsetX = pPipWindowDesc->imageOffset.offsetX; + pipOffsetY = pPipWindowDesc->imageOffset.offsetY; + + + switch (hwTransfo.mirroring) { + case SVA_HW_MIRRORING_BOTH: + if(hwTransfo.rotation == SVA_HW_ROTATION_NONE) + { + pipOffsetX= pConf->resizedImageDesc.width-pPipWindowDesc->image.width-pipOffsetX +2*videoOffsetX; + pipOffsetY= pConf->resizedImageDesc.height-pPipWindowDesc->image.height-pipOffsetY+2*videoOffsetY; + } + else + { + pipOffsetX = pipOffsetX; + pipOffsetY = pConf->resizedImageDesc.height-pPipWindowDesc->image.height-pipOffsetY+2*videoOffsetY; + } + break; + case SVA_HW_MIRRORING_VERTICAL: + if(hwTransfo.rotation == SVA_HW_ROTATION_NONE) + { + pipOffsetX = pipOffsetX; + pipOffsetY = pConf->resizedImageDesc.height-pPipWindowDesc->image.height-pipOffsetY+2*videoOffsetY; + } + else + { + pipOffsetX = pConf->resizedImageDesc.width-pPipWindowDesc->image.width-pipOffsetX +2*videoOffsetX; + pipOffsetY = pipOffsetY; + } + break; + case SVA_HW_MIRRORING_HORIZONTAL: + if(hwTransfo.rotation == SVA_HW_ROTATION_NONE) + { + pipOffsetX = pConf->resizedImageDesc.width-pPipWindowDesc->image.width-pipOffsetX +2*videoOffsetX; + pipOffsetY = pipOffsetY; + } + else + { + pipOffsetX = pipOffsetX; + pipOffsetY = pipOffsetY; //pConf->resizedImageDesc.height-pPipWindowDesc->image.height-pipOffsetY+2*videoOffsetY; + + } + break; + } + + + /* Exact cut-off pieces in SRC window*/ + + /*0*/ + pDesc->sourcePipRectangular[0].image.width = (t_uint16)sourceWidth; + pDesc->sourcePipRectangular[0].image.height = (t_uint16)(((pipOffsetY-videoOffsetY)*pDesc->iScaleY)/SVA_DP_FACTOR); + pDesc->sourcePipRectangular[0].imageOffset.offsetX = 0; + pDesc->sourcePipRectangular[0].imageOffset.offsetY = 0; + + if(pDesc->sourcePipRectangular[0].image.height!=0) + { + + pDesc->pipPieceCounter++; + pDesc->Index[count] = 1; + count++; + } + + /*1*/ + pDesc->sourcePipRectangular[1].image.width = (t_uint16)(((pipOffsetX-videoOffsetX)*pDesc->iScaleX)/SVA_DP_FACTOR); + pDesc->sourcePipRectangular[1].image.height = (t_uint16)((pPipWindowDesc->image.height*pDesc->iScaleY)/SVA_DP_FACTOR) ; + pDesc->sourcePipRectangular[1].imageOffset.offsetX = 0; + pDesc->sourcePipRectangular[1].imageOffset.offsetY = pDesc->sourcePipRectangular[0].image.height; + + if((pDesc->sourcePipRectangular[1].image.width !=0)&&(pDesc->sourcePipRectangular[1].image.height!=0)) + { + pDesc->pipPieceCounter++; + pDesc->Index[count] = 2; + count++; + } + + + /*2*/ + temp = ((pDesc->sourcePipRectangular[1].image.width*pDesc->scaleX)/SVA_DP_FACTOR); + pDesc->sourcePipRectangular[2].image.width = (t_uint16)(sourceWidth - (((temp + pPipWindowDesc->image.width)*pDesc->iScaleX)/SVA_DP_FACTOR)); + pDesc->sourcePipRectangular[2].image.height = pDesc->sourcePipRectangular[1].image.height; + pDesc->sourcePipRectangular[2].imageOffset.offsetX = (t_uint16)(sourceWidth - pDesc->sourcePipRectangular[2].image.width); + pDesc->sourcePipRectangular[2].imageOffset.offsetY = pDesc->sourcePipRectangular[0].image.height; + + if((pDesc->sourcePipRectangular[2].image.width !=0)&&(pDesc->sourcePipRectangular[2].image.height!=0)) + { + pDesc->pipPieceCounter++; + pDesc->Index[count] = 3; + count++; + } + + /*3*/ + pDesc->sourcePipRectangular[3].image.width = (t_uint16)sourceWidth; + pDesc->sourcePipRectangular[3].image.height = (t_uint16)(sourceHeight - (pDesc->sourcePipRectangular[0].image.height + pDesc->sourcePipRectangular[1].image.height)); + pDesc->sourcePipRectangular[3].imageOffset.offsetX = 0; + pDesc->sourcePipRectangular[3].imageOffset.offsetY = (pDesc->sourcePipRectangular[0].image.height + pDesc->sourcePipRectangular[1].image.height); + + if(pDesc->sourcePipRectangular[3].image.height != 0) + { + pDesc->pipPieceCounter++; + pDesc->Index[count] = 4; + count++; + } + + /* Aligned cut-off pieces and destination pieces (computed from aligned pieces) */ + /*0*/ + SVA_DP_REALIGN_16(pDesc->alignSourcePipRectangular[0].image.width, pDesc->sourcePipRectangular[0].image.width); + SVA_DP_REALIGN_16(pDesc->alignSourcePipRectangular[0].image.height, pDesc->sourcePipRectangular[0].image.height); + pDesc->alignSourcePipRectangular[0].imageOffset.offsetX=0; + pDesc->alignSourcePipRectangular[0].imageOffset.offsetY=0; + + pDesc->newDestinationPipRectangular[0].image.width = pConf->resizedImageDesc.width; + pDesc->newDestinationPipRectangular[0].image.height = (t_uint16)((pDesc->alignSourcePipRectangular[0].image.height*pDesc->scaleY)/SVA_DP_FACTOR); + pDesc->newDestinationPipRectangular[0].imageOffset.offsetX = 0; + pDesc->newDestinationPipRectangular[0].imageOffset.offsetY = 0; + + /*1*/ + SVA_DP_REALIGN_16(pDesc->alignSourcePipRectangular[1].image.width, pDesc->sourcePipRectangular[1].image.width); + SVA_DP_REALIGN_16(pDesc->alignSourcePipRectangular[1].image.height, pDesc->sourcePipRectangular[1].image.height); + pDesc->alignSourcePipRectangular[1].imageOffset.offsetX=0; + SVA_DP_REALIGN_16(pDesc->alignSourcePipRectangular[1].imageOffset.offsetY, pDesc->sourcePipRectangular[1].imageOffset.offsetY); + + pDesc->newDestinationPipRectangular[1].image.width = (t_uint16)((pDesc->alignSourcePipRectangular[1].image.width*pDesc->scaleX)/SVA_DP_FACTOR); + pDesc->newDestinationPipRectangular[1].image.height = (t_uint16)((pDesc->alignSourcePipRectangular[1].image.height*pDesc->scaleY)/SVA_DP_FACTOR); + pDesc->newDestinationPipRectangular[1].imageOffset.offsetX = 0; + pDesc->newDestinationPipRectangular[1].imageOffset.offsetY = pDesc->newDestinationPipRectangular[0].image.height; + + /*2*/ + SVA_DP_REALIGN_16(pDesc->alignSourcePipRectangular[2].image.width, pDesc->sourcePipRectangular[2].image.width); + SVA_DP_REALIGN_16(pDesc->alignSourcePipRectangular[2].image.height, pDesc->sourcePipRectangular[2].image.height); + pDesc->alignSourcePipRectangular[2].imageOffset.offsetX = (t_uint16)(sourceWidth - pDesc->alignSourcePipRectangular[2].image.width); + SVA_DP_REALIGN_16(pDesc->alignSourcePipRectangular[2].imageOffset.offsetY, pDesc->sourcePipRectangular[2].imageOffset.offsetY); + + pDesc->newDestinationPipRectangular[2].image.width = (t_uint16)((pDesc->alignSourcePipRectangular[2].image.width*pDesc->scaleX)/SVA_DP_FACTOR); + pDesc->newDestinationPipRectangular[2].image.height = (t_uint16)((pDesc->alignSourcePipRectangular[2].image.height*pDesc->scaleY)/SVA_DP_FACTOR); + pDesc->newDestinationPipRectangular[2].imageOffset.offsetX = pConf->resizedImageDesc.width - pDesc->newDestinationPipRectangular[2].image.width; + pDesc->newDestinationPipRectangular[2].imageOffset.offsetY = pDesc->newDestinationPipRectangular[0].image.height; + + /*3*/ + SVA_DP_REALIGN_16(pDesc->alignSourcePipRectangular[3].image.width, pDesc->sourcePipRectangular[3].image.width); + pDesc->alignSourcePipRectangular[3].image.height= (t_uint16)(sourceHeight - (pDesc->alignSourcePipRectangular[0].image.height + pDesc->alignSourcePipRectangular[1].image.height)); + SVA_DP_REALIGN_16(pDesc->alignSourcePipRectangular[3].imageOffset.offsetX, pDesc->sourcePipRectangular[3].imageOffset.offsetX); + pDesc->alignSourcePipRectangular[3].imageOffset.offsetY=(pDesc->alignSourcePipRectangular[0].image.height + pDesc->alignSourcePipRectangular[1].image.height); + + pDesc->newDestinationPipRectangular[3].image.width = pConf->resizedImageDesc.width; + pDesc->newDestinationPipRectangular[3].image.height = (t_uint16)((pDesc->alignSourcePipRectangular[3].image.height*pDesc->scaleY)/SVA_DP_FACTOR); + pDesc->newDestinationPipRectangular[3].imageOffset.offsetX =0; + pDesc->newDestinationPipRectangular[3].imageOffset.offsetY =pDesc->newDestinationPipRectangular[0].image.height+pDesc->newDestinationPipRectangular[1].image.height; + + + + + /* modify offset of destination according transformation (mirror, rotate) */ + switch (hwTransfo.mirroring) { + case SVA_HW_MIRRORING_BOTH: + if(hwTransfo.rotation == SVA_HW_ROTATION_NONE) { + /* OK */ + pDesc->newDestinationPipRectangular[0].imageOffset.offsetY = pConf->resizedImageDesc.height-pDesc->newDestinationPipRectangular[0].image.height ; + pDesc->newDestinationPipRectangular[1].imageOffset.offsetX = pConf->resizedImageDesc.width-pDesc->newDestinationPipRectangular[1].image.width; + pDesc->newDestinationPipRectangular[1].imageOffset.offsetY = pDesc->newDestinationPipRectangular[3].image.height; + pDesc->newDestinationPipRectangular[2].imageOffset.offsetX = 0; + pDesc->newDestinationPipRectangular[2].imageOffset.offsetY = pDesc->newDestinationPipRectangular[1].imageOffset.offsetY; + pDesc->newDestinationPipRectangular[3].imageOffset.offsetY = 0; + + } + if(hwTransfo.rotation == SVA_HW_ROTATION_90) { + /* ok */ + pDesc->newDestinationPipRectangular[0].imageOffset.offsetX = 0; + pDesc->newDestinationPipRectangular[0].imageOffset.offsetY = pConf->resizedImageDesc.height-pDesc->newDestinationPipRectangular[0].image.height ; + pDesc->newDestinationPipRectangular[3].imageOffset.offsetX = 0; + pDesc->newDestinationPipRectangular[3].imageOffset.offsetY = 0; + pDesc->newDestinationPipRectangular[1].imageOffset.offsetY=pDesc->newDestinationPipRectangular[3].image.height; + pDesc->newDestinationPipRectangular[2].imageOffset.offsetY=pDesc->newDestinationPipRectangular[3].image.height; + } + + + /*ok*/ + pDesc->newPipWindow.image.width=pDesc->newDestinationPipRectangular[3].image.width -pDesc->newDestinationPipRectangular[1].image.width-pDesc->newDestinationPipRectangular[2].image.width; + pDesc->newPipWindow.image.height=pDesc->newDestinationPipRectangular[2].image.height; + pDesc->newPipWindow.imageOffset.offsetX=pConf->videoFrameBufferDesc.window.imageOffset.offsetX+pDesc->newDestinationPipRectangular[2].image.width; + pDesc->newPipWindow.imageOffset.offsetY=pConf->videoFrameBufferDesc.window.imageOffset.offsetY+pDesc->newDestinationPipRectangular[3].image.height; + + + + break; + case SVA_HW_MIRRORING_VERTICAL: + if(hwTransfo.rotation == SVA_HW_ROTATION_NONE) { + /* OK */ + pDesc->newDestinationPipRectangular[0].imageOffset.offsetX = 0; + pDesc->newDestinationPipRectangular[0].imageOffset.offsetY = pConf->resizedImageDesc.height-pDesc->newDestinationPipRectangular[0].image.height; + pDesc->newDestinationPipRectangular[1].imageOffset.offsetY = pDesc->newDestinationPipRectangular[3].image.height; + pDesc->newDestinationPipRectangular[2].imageOffset.offsetY = pDesc->newDestinationPipRectangular[1].imageOffset.offsetY; + pDesc->newDestinationPipRectangular[3].imageOffset.offsetX = 0; + pDesc->newDestinationPipRectangular[3].imageOffset.offsetY = 0; + + } + if(hwTransfo.rotation == SVA_HW_ROTATION_90) { + /* ok */ + pDesc->newDestinationPipRectangular[1].imageOffset.offsetX = pConf->resizedImageDesc.width-pDesc->newDestinationPipRectangular[1].image.width; + pDesc->newDestinationPipRectangular[2].imageOffset.offsetX = 0; + + } + + + /*ok*/ + pDesc->newPipWindow.image.width=pDesc->newDestinationPipRectangular[3].image.width -pDesc->newDestinationPipRectangular[1].image.width-pDesc->newDestinationPipRectangular[2].image.width; + pDesc->newPipWindow.image.height=pDesc->newDestinationPipRectangular[1].image.height; + pDesc->newPipWindow.imageOffset.offsetX=pConf->videoFrameBufferDesc.window.imageOffset.offsetX+pDesc->newDestinationPipRectangular[1].image.width; + pDesc->newPipWindow.imageOffset.offsetY=pConf->videoFrameBufferDesc.window.imageOffset.offsetY+pDesc->newDestinationPipRectangular[3].image.height; + + + + break; + case SVA_HW_MIRRORING_HORIZONTAL: + if(hwTransfo.rotation == SVA_HW_ROTATION_NONE) { + /* OK */ + pDesc->newDestinationPipRectangular[1].imageOffset.offsetX = pConf->resizedImageDesc.width-pDesc->newDestinationPipRectangular[1].image.width; + pDesc->newDestinationPipRectangular[2].imageOffset.offsetX = 0; + + } + // ROT90 OK + + /*ok*/ + pDesc->newPipWindow.image.width=pDesc->newDestinationPipRectangular[0].image.width -pDesc->newDestinationPipRectangular[1].image.width-pDesc->newDestinationPipRectangular[2].image.width; + pDesc->newPipWindow.image.height=pDesc->newDestinationPipRectangular[2].image.height; + pDesc->newPipWindow.imageOffset.offsetX=pConf->videoFrameBufferDesc.window.imageOffset.offsetX+pDesc->newDestinationPipRectangular[2].image.width; + pDesc->newPipWindow.imageOffset.offsetY=pConf->videoFrameBufferDesc.window.imageOffset.offsetY+pDesc->newDestinationPipRectangular[0].image.height; + + + break; + + + case SVA_HW_MIRRORING_NONE: + pDesc->newPipWindow.image.width=pDesc->newDestinationPipRectangular[0].image.width -pDesc->newDestinationPipRectangular[1].image.width-pDesc->newDestinationPipRectangular[2].image.width; + pDesc->newPipWindow.image.height=pDesc->newDestinationPipRectangular[1].image.height; + pDesc->newPipWindow.imageOffset.offsetX=pConf->videoFrameBufferDesc.window.imageOffset.offsetX+pDesc->newDestinationPipRectangular[1].image.width; + pDesc->newPipWindow.imageOffset.offsetY=pConf->videoFrameBufferDesc.window.imageOffset.offsetY+pDesc->newDestinationPipRectangular[0].image.height; + + break; + + } + + + + } + + + + +} + + +/****************************************************************************/ +/* NAME: void sva_DP_BuildPipParamIn */ +/* (t_uint16 index, t_sva_service_instance_num instanceNum, t_sva_dpl_param_in *pParamIn) */ +/* ) */ +/****************************************************************************/ +void sva_DP_BuildPipParamIn(t_uint16 index, t_sva_service_instance_num instanceNum, t_sva_dpl_param_in *pParamIn) { + t_sva_dp_descriptor *pDesc=&displayDesc[instanceNum]; + t_sva_postprocessor_configuration *pConf = &pDesc->confHandle.nextConf; + t_sva_dp_hw_rotation_mirroring hwTransfo; + + t_sva_postprocessor_configuration tempConf; + t_bool ret=TRUE; + + tempConf.bitsPerPixel = pConf->bitsPerPixel; + tempConf.isDoubleBufferMode = pConf->isDoubleBufferMode; + tempConf.screenFrameBufferBaseAddr = pConf->screenFrameBufferBaseAddr; + tempConf.screenAlternateFrameBufferBaseAddr = pConf->screenAlternateFrameBufferBaseAddr; + tempConf.brightness = pConf->brightness; + tempConf.contrast = pConf->contrast; + tempConf.transformId = pConf->transformId; + tempConf.colorMatrix.matrix_coef1 = pConf->colorMatrix.matrix_coef1; + tempConf.colorMatrix.matrix_coef2 = pConf->colorMatrix.matrix_coef2; + tempConf.colorMatrix.matrix_coef3 = pConf->colorMatrix.matrix_coef3; + tempConf.colorMatrix.matrix_coef4 = pConf->colorMatrix.matrix_coef4; + tempConf.displaySyncLine = pConf->displaySyncLine; + tempConf.aceMode = pConf->aceMode; + tempConf.syncMode = pConf->syncMode; + tempConf.outputRange = pConf->outputRange; + tempConf.mirrorMode = pConf->mirrorMode; + tempConf.rotationMode = pConf->rotationMode; + tempConf.deblockingFilterMode = pConf->deblockingFilterMode; + tempConf.deringingFilterMode = pConf->deringingFilterMode; + tempConf.chromaSamplingFormat = pConf->chromaSamplingFormat; + + hwTransfo.mirroring = rot_mir_hclapi2hwapi[pConf->rotationMode][pConf->mirrorMode].mirroring; + hwTransfo.rotation = rot_mir_hclapi2hwapi[pConf->rotationMode][pConf->mirrorMode].rotation; + + /* source frame */ + pParamIn->source_frame_width = pConf->sourceFrameDesc.frame.width; + pParamIn->source_frame_height = pConf->sourceFrameDesc.frame.height; + + + /* take right cropped source: compute source window size and offset */ + switch(hwTransfo.rotation) { + case SVA_HW_ROTATION_90: + + tempConf.rotationMode = SVA_ROTATION_90; + pParamIn->source_window_width = pDesc->alignSourcePipRectangular[index-1].image.height; + pParamIn->source_window_height = pDesc->alignSourcePipRectangular[index-1].image.width; + + if(hwTransfo.mirroring != SVA_HW_MIRRORING_NONE){ + + /* ?, OK for MIRR_BOTH */ + pParamIn->source_window_horizontal_offset = pDesc->alignSourcePipRectangular[index-1].imageOffset.offsetY; + SVA_DP_REALIGN_16(pParamIn->source_window_vertical_offset, (pConf->sourceFrameDesc.window.image.height - pDesc->alignSourcePipRectangular[index-1].imageOffset.offsetX - pDesc->alignSourcePipRectangular[index-1].image.width)); + } + else { + /* OK*/ + SVA_DP_REALIGN_16(pParamIn->source_window_horizontal_offset, (pConf->sourceFrameDesc.window.image.width - pDesc->alignSourcePipRectangular[index-1].imageOffset.offsetY - pDesc->alignSourcePipRectangular[index-1].image.height)); + pParamIn->source_window_vertical_offset = pDesc->alignSourcePipRectangular[index-1].imageOffset.offsetX; + + } + break; + case SVA_HW_ROTATION_NONE: + + tempConf.rotationMode = SVA_NO_ROTATION; + /* OK */ + pParamIn->source_window_width= pDesc->alignSourcePipRectangular[index-1].image.width; + pParamIn->source_window_height= pDesc->alignSourcePipRectangular[index-1].image.height; + + pParamIn->source_window_horizontal_offset = pDesc->alignSourcePipRectangular[index-1].imageOffset.offsetX; + pParamIn->source_window_vertical_offset = pDesc->alignSourcePipRectangular[index-1].imageOffset.offsetY; + + break; + } + + /* resized and clipped */ + pParamIn->resized_window_width= pDesc->newDestinationPipRectangular[index-1].image.width; + pParamIn->resized_window_height= pDesc->newDestinationPipRectangular[index-1].image.height; + pParamIn->clipped_window_width = pParamIn->resized_window_width; + pParamIn->clipped_window_height = pParamIn->resized_window_height; + pParamIn->clipped_window_horizontal_offset = 0; + pParamIn->clipped_window_vertical_offset = 0; + + /* destination */ + pParamIn->destination_frame_width = pConf->videoFrameBufferDesc.frame.width; + pParamIn->destination_frame_height = pConf->videoFrameBufferDesc.frame.height; + pParamIn->destination_window_horizontal_offset= ( pConf->videoFrameBufferDesc.window.imageOffset.offsetX+pDesc->newDestinationPipRectangular[index-1].imageOffset.offsetX); + pParamIn->destination_window_vertical_offset= (pConf->videoFrameBufferDesc.window.imageOffset.offsetY+pDesc->newDestinationPipRectangular[index-1].imageOffset.offsetY); + + /* check conf */ + tempConf.sourceFrameDesc.frame.width = pParamIn->source_frame_width; + tempConf.sourceFrameDesc.frame.height = pParamIn->source_frame_height; + tempConf.sourceFrameDesc.window.image.width = pParamIn->source_window_width; + tempConf.sourceFrameDesc.window.image.height = pParamIn->source_window_height; + tempConf.sourceFrameDesc.window.imageOffset.offsetX = pParamIn->source_window_horizontal_offset; + tempConf.sourceFrameDesc.window.imageOffset.offsetY = pParamIn->source_window_vertical_offset; + tempConf.resizedImageDesc.width = pParamIn->resized_window_width; + tempConf.resizedImageDesc.height = pParamIn->clipped_window_height; + tempConf.clippedWindowDesc.image.width = pParamIn->clipped_window_width; + tempConf.clippedWindowDesc.image.height = pParamIn->clipped_window_height; + tempConf.clippedWindowDesc.imageOffset.offsetX = pParamIn->clipped_window_horizontal_offset; + tempConf.clippedWindowDesc.imageOffset.offsetY = pParamIn->clipped_window_vertical_offset; + tempConf.videoFrameBufferDesc.frame.width = pParamIn->destination_frame_width; + tempConf.videoFrameBufferDesc.frame.height = pParamIn->destination_frame_height; + tempConf.videoFrameBufferDesc.window.imageOffset.offsetX = pParamIn->destination_window_horizontal_offset; + tempConf.videoFrameBufferDesc.window.imageOffset.offsetY = pParamIn->destination_window_vertical_offset; + + ret = sva_DP_isConfigurationValid(&tempConf); + HCL_ASSERT(ret!=FALSE); + + + +} + + +/****************************************************************************/ +/* NAME: void sva_DP_UpdatePIPSubtasksAndAddToSubtaskList( */ +/* t_sva_service_instance_num , */ +/* t_sva_tm_subtask_id , */ +/* t_sva_tm_timestamp * */ +/* ) */ +/* -------------------------------------------------------------------------*/ +/* To be called in resolveDependancies */ +/****************************************************************************/ +t_sva_error sva_DP_UpdatePIPSubtasksAndAddToSubtaskList(t_sva_tm_subtask_id primSubtaskId, t_sva_service_instance_num instanceNum, t_sva_tm_subtask_list_id subtasksListId, t_sva_tm_timestamp* pTimeStamp){ + t_sva_dp_descriptor *pDesc=&displayDesc[instanceNum]; + t_uint8 i; + t_sva_dp_pip_subtask_id pipSubtaskId; + t_sva_ff_error ffError; + t_sva_tm_error tmError; + + t_sva_dpl_frame_buffer_in bufferIn; + t_sva_dpl_frame_buffer_out bufferOut; + t_logical_address destAddr; + t_sva_dpl_param_in paramIn; + t_sva_dpl_param_in pipParamIn; + t_sva_tm_subtask_list_info * pListInfo; + +/* Pop pipPieceCounter-1 pip subtasks */ + + + ffError = POP_FIFO_ELEM(pDesc->pipSubtasksFifos.pushFifo, t_sva_dp_pip_subtask_id, pipSubtaskId); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + + pipSubtaskId.primarySubtaskId = primSubtaskId; + ffError = PUSH_FIFO_ELEM(pDesc->pipSubtasksFifos.inUseFifo, t_sva_dp_pip_subtask_id, pipSubtaskId); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + + + /* and update source_addr fields*/ + + bufferIn.addr_source_buffer = pDesc->pipAddrSourceBuffer; + bufferIn.addr_deblocking_param_buffer = pDesc->pipDeblockingParamBuffer; + + for(i=0; i pipPieceCounter-1; i++) { + tmError = sva_TM_UpdateSubTaskField(SVA_TM_INTERMEDIATE_FIELD_TO_UPDATE, pipSubtaskId.secSubtaskId[i], SVA_TM_DIS_ADDR_IN_FRAME_BUFFER, FCMD_COPY,(t_uint32) &bufferIn, 0, 8); + + } + + /* also update dest_addr fields (it is worth only in case of double buffering mode) */ + + tmError = sva_TM_GetSubTaskField(primSubtaskId,SVA_TM_DIS_ADDR_OUT_FRAME_BUFFER, (t_logical_address)&destAddr , 0, 4,FALSE); + bufferOut.addr_dest_buffer = destAddr; + for(i=0; i pipPieceCounter-1; i++) { + tmError = sva_TM_UpdateSubTaskField(SVA_TM_INTERMEDIATE_FIELD_TO_UPDATE, pipSubtaskId.secSubtaskId[i], SVA_TM_DIS_ADDR_OUT_FRAME_BUFFER, FCMD_COPY,(t_uint32) &bufferOut, 0, 4); + + } + +/* Update Param In for primSubtaskId */ + sva_DP_BuildPipParamIn(pDesc->Index[0], instanceNum, ¶mIn); + tmError = sva_TM_UpdateSubTaskField(SVA_TM_INTERMEDIATE_FIELD_TO_UPDATE, pipSubtaskId.primarySubtaskId, SVA_TM_DIS_ADDR_IN_PARAMETERS, FCMD_COPY,(t_uint32) ¶mIn, 0, 32); + + +/* Update Param In for secSubtaskId */ + + for(i=0; i pipPieceCounter-1; i++) { + sva_DP_BuildPipParamIn(pDesc->Index[i+1], instanceNum, &pipParamIn); + tmError = sva_TM_UpdateSubTaskField(SVA_TM_INTERMEDIATE_FIELD_TO_UPDATE, pipSubtaskId.secSubtaskId[i], SVA_TM_DIS_ADDR_IN_PARAMETERS, FCMD_COPY,(t_uint32) &pipParamIn, 0, 32); + + + tmError = sva_TM_GetSubTaskField(pipSubtaskId.secSubtaskId[i],SVA_TM_DIS_ADDR_IN_PARAMETERS, (t_logical_address)&pipParamIn, 0, sizeof(t_sva_dpl_param_in), FALSE ); + + if (pDesc->isUpdateConf == TRUE) + { + + //pipParamIn.bits_per_pixel = paramIn.bis_per_pixel; + //pipParamIn.dithering = paramIn.dithering; + pipParamIn.chroma_sampling_format = pDesc->newParamInBuffer.chroma_sampling_format; + pipParamIn.alpha_key = pDesc->newParamInBuffer.alpha_key; + pipParamIn.red_blue_swap = pDesc->newParamInBuffer.red_blue_swap; + pipParamIn.chroma_duplication = pDesc->newParamInBuffer.chroma_duplication; + pipParamIn.contrast = pDesc->newParamInBuffer.contrast; + pipParamIn.brightness = pDesc->newParamInBuffer.brightness; + } + + + tmError = sva_TM_InitSubTaskField(pipSubtaskId.secSubtaskId[i],SVA_TM_DIS_ADDR_IN_PARAMETERS, (t_logical_address)&pipParamIn, sizeof(t_sva_dpl_param_in)); + + } + + + /* if conf changed */ + if (pDesc->isUpdateConf == TRUE) + { + pDesc->isUpdateConf = FALSE; + } + + + +/* AddElem to SubtaskList */ + pListInfo = (t_sva_tm_subtask_list_info *)pDesc->subtasksListId; + //tmError=sva_TM_DisableVirtualHwEvents(pDesc->subtasksListId, SVA_TM_EOT_HW_EVENT); + //if (tmError != SVA_TM_OK) {return SVA_INTERNAL_POSTPROCESSOR_ERROR;} + + pListInfo->eventMask &= ~(t_uint32)SVA_TM_EOT_HW_EVENT; + + tmError=sva_TM_AddElemToSubTaskList(pDesc->subtasksListId,pipSubtaskId.primarySubtaskId, pTimeStamp, pDesc->pipPieceCounter); + HCL_DEBUG_ASSERT(tmError==SVA_TM_OK); + + + + + for(i=0; i pipPieceCounter-2; i++) { + tmError=sva_TM_AddElemToSubTaskList(pDesc->subtasksListId,pipSubtaskId.secSubtaskId[i], pTimeStamp, pDesc->pipPieceCounter-1-i); + HCL_DEBUG_ASSERT(tmError==SVA_TM_OK); + + + + } + + + //tmError=sva_TM_EnableVirtualHwEvents(pDesc->subtasksListId, SVA_TM_EOT_HW_EVENT); + //if (tmError != SVA_TM_OK) {return SVA_INTERNAL_POSTPROCESSOR_ERROR;} + + pListInfo->eventMask |= (t_uint32)SVA_TM_EOT_HW_EVENT; + + tmError=sva_TM_AddElemToSubTaskList(pDesc->subtasksListId,pipSubtaskId.secSubtaskId[pDesc->pipPieceCounter-2], pTimeStamp, 1); + HCL_DEBUG_ASSERT(tmError==SVA_TM_OK); + + return SVA_OK; + +} + +/****************************************************************************/ +/* NAME: t_bool sva_DP_isPrimarySubtask( */ +/* t_sva_service_instance_num , */ +/* t_sva_tm_subtask_id */ +/* ) */ +/****************************************************************************/ + +t_bool sva_DP_isPrimarySubtask(t_sva_service_instance_num instanceNum, t_sva_tm_subtask_id subtaskId) { + t_sva_dp_descriptor *pDesc=&displayDesc[instanceNum]; + t_uint8 i; + + + for(i=0; inbSubtasks; i++) { + if(subtaskId == pDesc->subtasksIdArray[i]) { + return TRUE; + } + } + + return FALSE; +} + +/****************************************************************************/ +/* NAME: t_bool sva_DP_DisablePip( */ +/* t_sva_service_instance_num */ +/* ) */ +/****************************************************************************/ +void sva_DP_DisablePip(t_sva_service_instance_num instanceNum) { + t_sva_dp_descriptor *pDesc=&displayDesc[instanceNum]; + pDesc->pipActivated = SVA_DP_PIP_DELETION; +} + + + + +void sva_DP_GetTemporaryBufferAddress(t_sva_service_instance_num instanceNum, t_system_address * pAddr) +{ + t_sva_dp_descriptor *pDesc=&displayDesc[instanceNum]; + sva_MM_GetBlockSystemAddress(pDesc->tempBlockId, pAddr); + +} --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/display/sva_display.h @@ -0,0 +1,99 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ + +#ifndef __INC_SVA_DISPLAY_H +#define __INC_SVA_DISPLAY_H + + +#include "hcl_defs.h" +#include "sva.h" +#include "svap.h" +#include "sva_taskmgt.h" +#include "sva_service.h" + + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* + * Define the symbols used to identify the various errors of the Display Module + */ + +//typedef t_uint32 t_sva_dp_error; + + +typedef enum { + SVA_DP_INVALID_TRANSITION = SVA_DP_LAST_ERROR, + SVA_DP_NO_MORE_AVAILABLE_INSTANCE, + SVA_DP_INVALID_INSTANCE_NB, + SVA_DP_INVALID_TASK_ID_NB, + SVA_DP_NOT_SUPPORTED, + SVA_DP_INVALID_CONTROL_PARAM, + SVA_DP_INVALID_PUSH, + SVA_DP_INVALID_BUFFER_TYPE, + SVA_DP_INVALID_BUFFER_SIZE, + SVA_DP_INVALID_CONFIGURATION, + SVA_DP_UNKNOWN_CMD_ID, + SVA_DP_UNEXPECTED_HW_EVENT, + SVA_DP_SYNCHRO_INFO_NOT_AVAILABLE, + SVA_DP_TI_LINKED_ERROR, + SVA_DP_BM_LINKED_ERROR, + SVA_DP_MM_LINKED_ERROR, + SVA_DP_FF_LINKED_ERROR, + SVA_DP_TM_LINKED_ERROR, + SVA_DP_NULL_POINTER_PARAMETER, + SVA_DP_FIFO_NOT_EMPTY, + SVA_DP_OK = HCL_OK +} t_sva_dp_error; + + +/******************************************************************************* +* PUBLIC Functions +*******************************************************************************/ + +PUBLIC t_sva_error sva_DP_Init( void ); +PUBLIC t_sva_error sva_DP_Reset( t_sva_service_id ); +PUBLIC t_sva_error sva_DP_Create( t_sva_service_id *); +PUBLIC t_sva_error sva_DP_Control(t_sva_service_id, t_sva_service_cmd_id, t_uint32 ); +PUBLIC t_sva_error sva_DP_Push(t_sva_service_id, t_sva_buffer_id, t_sva_push_mode, t_sva_buffer_type, t_sva_timestamp ); + +PUBLIC t_sva_error sva_DP_DispatchVirtualHwEvent(t_sva_tm_virtual_hw_event_id, t_sva_service_id, t_sva_tm_subtask_id, t_uint32, t_uint32, t_uint8, t_sva_event_desc *, t_uint32 *); +PUBLIC t_sva_error sva_DP_ProvideInternalNeeds( t_sva_service_id); +PUBLIC t_sva_error sva_DP_GetInternalNeeds(t_sva_service_id, t_size *); +PUBLIC t_sva_error sva_DP_Activate(t_sva_service_id, t_sva_service_mode, t_sva_fw_id *); +PUBLIC t_sva_error sva_DP_Inactivate(t_sva_service_id); +PUBLIC t_sva_error sva_DP_Delete(t_sva_service_id ); +PUBLIC t_sva_error sva_DP_GetParamsBufferSize(t_sva_service_id ,t_sva_push_mode,t_size *); +PUBLIC t_sva_dp_error sva_DP_ResolveDependencies(t_sva_service_instance_num); + + +//t_sva_postprocessor_configuration is in sva.h +// function is sva.h +//PUBLIC t_sva_error SVA_ConfigurePostProcessor( t_sva_service_id, t_sva_postprocessor_configuration); + +//t_sva_postprocessor_param_id is in sva.h +//PUBLIC t_sva_error SVA_UpdatePostProcessorParams(t_sva_service_id, t_sva_update_cmd_type, t_sva_postprocessor_param_id, t_uint32); + + +#ifdef __cplusplus +} /* allow C++ to use these headers */ +#endif /* __cplusplus */ + +#endif --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/display/sva_displayp.h @@ -0,0 +1,424 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ + +#ifndef __INC_SVA_DISPLAYP_H +#define __INC_SVA_DISPLAYP_H + + +#include "hcl_defs.h" +#include "sva.h" +#include "sva_display.h" +#include "sva_taskmgt.h" +#include "sva_fifo.h" +#include "sva_service.h" + + +#ifdef __DEBUG + /* + * Define number of event to log + */ + #define LOG_DEPTH 128 +#endif + + +/* + * Define the maximum number of parameters in t_sva_postprocessor_configuration + */ +#define MAX_CONF_PARAM_NUMBER 22 + + + +/* + * Define the number of possible modifcations (here 2=modification concerning input buffer + mod for output buffer + */ +#define DEFAULT_CHANGE_NUMBER 2 + + +/* + * Define the number of field inside a Display Subtask descriptor (spec v0.93) + */ +#define DISPLAY_FIELD_NUMBER 7 + +/* + * Define the default memory used to store subtasks descriptors + */ +#define DISPLAY_DEFAULT_MEMORY_ID SDRAM_ID + +/* + * Define the default memory used to store param_out (infos) data + */ +#define DISPLAY_DEFAULT_INFOS_MEMORY_ID SDRAM_ID + + +/* + * Define SVA_DP_NB_MAX_OF_PIECE + */ + +//#define DISPLAY_NB_MAX_OF_PIP_PIECE 4 +#define DISPLAY_NB_MAX_OF_PIP_PIECE 16 + + +/* + * Define Factor for PIP scaling + */ + #define SVA_DP_FACTOR 50000 + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/******************************************************************************/ +/* Types definitions */ +/******************************************************************************/ +/* + * Define the various state of a Grab instance service + */ +typedef enum { + SVA_DP_NOT_INITIALIZED, + SVA_DP_WAIT_FOR_CONFIGURATION, + SVA_DP_WAIT_FOR_INTERNAL_NEEDS, + SVA_DP_WAIT_FOR_ACTIVATE, + SVA_DP_WAIT_FOR_START, + SVA_DP_FLUSHING_IN, + SVA_DP_FLUSHING_OUT, + SVA_DP_WAIT_FOR_DATA, + SVA_DP_RUNNING, + SVA_DP_ABORT_REQUESTED, + SVA_DP_STOP_REQUESTED, + SVA_DP_ERROR, + SVA_DP_LAST_DUMMY_STATE, + SVA_DP_TRANSITION_REJECTED +} t_sva_dp_state; + +/* + * Define the various activate state of a Grab instance service + */ +typedef enum { + SVA_DP_INACTIVE, + SVA_DP_IN_ACTIVATION, + SVA_DP_ACTIVE, + SVA_DP_IN_INACTIVATION, + SVA_DP_LAST_ACTIVATE_DUMMY_STATE, + SVA_DP_ACTIVATE_TRANSITION_REJECTED +} t_sva_dp_activate_state; + +/* + * Define the various transitions of the grab service + */ +typedef enum { + SVA_DP_CREATE, + SVA_DP_CONFIGURE, + SVA_DP_INTERNAL_NEEDS, + SVA_DP_ACTIVATE, + SVA_DP_INACTIVATE, + SVA_DP_CONTROL_START, + SVA_DP_CONTROL_STOP, + SVA_DP_CONTROL_ABORT, + SVA_DP_ALL_DEPENDENCIES_RESOLVED, + SVA_DP_PUSH, + SVA_DP_EVENT_EOK, + SVA_DP_EVENT_FAKE, + SVA_DP_EVENT_ACTIVE, + SVA_DP_EVENT_INACTIVE, + SVA_DP_RESET, + SVA_DP_CONTROL_DELETE, + SVA_DP_EVENT_ERROR, + SVA_DP_FLUSH_IN, + SVA_DP_FLUSH_OUT, + SVA_DP_CANCEL, + SVA_DP_UPDATE_PARAM, + SVA_DP_GET_PARAM_SIZE, + SVA_DP_EVENT_ABORT, + SVA_DP_LAST_DUMMY_TRANSITION +} t_sva_dp_transition; + + + +/* + * Define the symbol used to qualify the state of the dependency + * for a given type of buffer + */ +typedef enum { + INTERNAL_DEPENDENCY, + NOT_RESOLVED_DEPENDENCY, + RESOLVED_DEPENDENCY +} t_sva_dp_dependencies_state; + +/* + * Define the structure used to manage the subtasks dependency + */ +typedef struct { + t_bitfield inputImageDep:2; + t_bitfield outputImageDep:2; + t_bitfield inputParamsDep:2; +} t_sva_dp_dependencies_desc; + +#define DEFAULT_INTERNAL_DEPENDENCY {INTERNAL_DEPENDENCY, INTERNAL_DEPENDENCY, INTERNAL_DEPENDENCY} + +/* + * Define the structure used to manage the dependencies of each subtasks + */ +typedef struct { +t_sva_tm_subtask_id subtaskId; +t_sva_dp_dependencies_desc dependencies; +} t_sva_dp_subtask_dependencies; + +/* + * Define the fifos used to manage the dependency + * The buffers, provided though the Push routine, are buffered inside the pushFifo + * When programming them (using them) into a subtask, then they are considered as used, + * as so pushed inside th inUseFifo + */ +typedef struct { + t_sva_fifo pushFifo; + t_sva_fifo inUseFifo; +} t_sva_dp_fifo_dep; + + +typedef enum { + SVA_DP_NO_CONF_CHANGE_NEED, + SVA_DP_IMMEDIATE_CONF_CHANGE_NEED, + SVA_DP_WAIT_FOR_BUFFER_INOUT, + SVA_DP_WAIT_FOR_BUFFER_IN_ONLY, + SVA_DP_WAIT_FOR_BUFFER_OUT_ONLY, + SVA_DP_WAIT_FOR_BUFFER_ID_INOUT, + SVA_DP_WAIT_FOR_BUFFER_ID_OUT_ONLY, + SVA_DP_WAIT_FOR_BUFFER_ID_IN_ONLY, + SVA_DP_SYNC_CONF_CHANGE_ABOUT_TO_BE_NEEDED, + SVA_DP_SYNC_CONF_CHANGE_NEED +} t_sva_dp_conf_state; + + + + +/* + * Define the structure used to manage states when changing parameters on the fly + */ +typedef struct { + t_bitfield buffer_out_needed:1; + t_bitfield buffer_in_needed:1; + t_bitfield buffer_out_id_needed:1; + t_bitfield buffer_in_id_needed:1; +} t_sva_dp_buffer_needs; + +#define DEFAULT_BUFFER_NEEDS {FALSE, FALSE, FALSE, FALSE} + + +/* + * Define a PIP subtask ID structure + */ +typedef struct { +t_sva_tm_subtask_id primarySubtaskId; +t_sva_tm_subtask_id secSubtaskId[DISPLAY_NB_MAX_OF_PIP_PIECE-1]; +} t_sva_dp_pip_subtask_id; + + + +/* + * Define structure that handle all stuff need to manipulate configuration change + */ +typedef struct { + t_sva_postprocessor_configuration currentConf; + t_sva_postprocessor_configuration nextConf; + t_sva_ace_offset newAceOffset; + t_bool isAceOffsetNeedUpdate; + t_uint32 currentConfCounter; + t_sva_postprocessor_param_id paramId[MAX_CONF_PARAM_NUMBER]; + t_uint32 nbParams; + t_sva_buffer_type bufferType[DEFAULT_CHANGE_NUMBER]; + t_sva_push_mode pushMode[DEFAULT_CHANGE_NUMBER]; + t_sva_buffer_id bufferId[DEFAULT_CHANGE_NUMBER]; + t_sva_dp_buffer_needs needs; + t_sva_dp_conf_state confState; +} t_sva_dp_conf_handle; + + + +typedef enum { + SVA_DP_NO_PIP, + SVA_DP_PIP_CREATION, + SVA_DP_PIP_CONFIGURATION, + SVA_DP_PIP_RESOLVED, + SVA_DP_PIP_RUNNING, + SVA_DP_PIP_TO_BE_DELETED, + SVA_DP_PIP_DELETION +}t_sva_dp_pip_state; + +/* + * Define the descriptor of a Display service instance + */ +typedef struct { + t_sva_dp_state state; + t_sva_dp_activate_state activateState; + t_sva_service_id serviceId; + t_sva_dp_conf_handle confHandle; + t_sva_dp_dependencies_desc defaultConfiguredDependency; + t_uint32 nbInputImagesPostProcessed; + t_uint32 nbOutputImagesDisplayed; + t_sva_dp_fifo_dep inputImageFifos; + t_sva_dp_fifo_dep inputTimestampsFifos; + t_sva_dp_fifo_dep outputImageFifos; + t_sva_dp_fifo_dep inputParamsFifos; + t_sva_fifo subtasksDependencyFifo; + t_uint8 nbSharedBuffers; + t_uint8 nbSubtasks; + t_sva_tm_subtask_id subtasksIdArray[SUBTASK_DEFAULT_NUMBER*2]; // x2 in order to support double buffer + t_sva_tm_subtask_list_id subtasksListId; + t_sva_postprocessor_status status; + t_uint32 subtasksConfCounter[SUBTASK_DEFAULT_NUMBER*2]; + + /* PIP variables */ + volatile t_sva_dp_pip_state pipActivated; + t_uint8 nbPipSubtasks; + t_sva_window_desc pipWindowDesc; + t_sva_dp_fifo_dep pipSubtasksFifos; + //t_sva_tm_subtask_id pipSubtasksIdArrayNoSynchro[3*SUBTASK_DEFAULT_NUMBER*2]; + t_sva_tm_subtask_id pipSubtasksIdArrayNoSynchro[DISPLAY_NB_MAX_OF_PIP_PIECE*SUBTASK_DEFAULT_NUMBER]; + + t_sva_ppp_tile_info *tile_info; + t_sva_ppp_tile_info tile_info_cur[DISPLAY_NB_MAX_OF_PIP_PIECE]; + t_sva_ppp_tile_info tile_info_new[DISPLAY_NB_MAX_OF_PIP_PIECE]; + t_bool is_ppp_tiling; + t_bool change_ppp_tiling; +//volatile t_sva_window_desc destinationPipRectangular[DISPLAY_NB_MAX_OF_PIP_PIECE]; + + volatile t_sva_window_desc sourcePipRectangular[DISPLAY_NB_MAX_OF_PIP_PIECE]; + volatile t_sva_window_desc alignSourcePipRectangular[DISPLAY_NB_MAX_OF_PIP_PIECE]; + volatile t_sva_window_desc newDestinationPipRectangular[DISPLAY_NB_MAX_OF_PIP_PIECE]; + volatile t_uint8 pipPieceCounter; + volatile t_uint8 pipPieceCounter_new; + t_physical_address pipAddrSourceBuffer; + t_physical_address pipDeblockingParamBuffer; + t_physical_address pipDestBuffer; + volatile t_uint32 scaleX; + volatile t_uint32 scaleY; + volatile t_uint32 iScaleX; + volatile t_uint32 iScaleY; + volatile t_uint16 Index[DISPLAY_NB_MAX_OF_PIP_PIECE]; + + + volatile t_sva_block_id tempBlockId; + volatile t_sva_tm_postprocessing_type postProc; + t_sva_window_desc newPipWindow; + volatile t_bool isUpdateConf; + t_sva_dpl_param_in newParamInBuffer; + +} t_sva_dp_descriptor; + + + + +/* + * Define the internal structure allowing to mirroring and rotation hw parameters + * Used to implement the conversion table between HCL API and the HW programmation values + */ +typedef struct { + t_sva_hw_rotation rotation; + t_sva_hw_mirroring mirroring; +} t_sva_dp_hw_rotation_mirroring; + + + + + + +#ifdef __DEBUG + /******************************************************************************/ + /* Trace Types definitions */ + /******************************************************************************/ + typedef struct { + t_sva_tm_virtual_hw_event_id event; + t_uint32 systemTime; + t_sva_tm_subtask_id subtaskId; + t_uint32 padding; + } t_sva_dp_debug_event_desc; + typedef struct { + t_uint32 padding[3]; + t_uint32 nbOfEventReceived; + t_sva_dp_debug_event_desc eventDebugDesc[LOG_DEPTH]; + } t_sva_dp_debug_events; + + typedef struct { + t_sva_service_cmd_id command; + t_uint32 systemTime; + t_uint32 parameter; + t_uint32 padding; + } t_sva_dp_debug_command_desc; + typedef struct { + t_uint32 padding[3]; + t_uint32 nbOfCommandReceived; + t_sva_dp_debug_command_desc commandDebugDesc[LOG_DEPTH]; + } t_sva_dp_debug_commands; + + typedef struct { + t_sva_dp_state state;/*state before transition occur*/ + t_sva_dp_transition transition; + t_uint32 systemTime; + t_sva_dp_activate_state activateState;/*state before transition occur*/ + } t_sva_dp_debug_transition_desc; + typedef struct { + t_uint32 padding[3]; + t_uint32 nbOfTransitionReceived; + t_sva_dp_debug_transition_desc transitionDebugDesc[LOG_DEPTH]; + } t_sva_dp_debug_transitions; + + + typedef struct { + t_sva_tm_subtask_id subtaskId; + t_bool isParamInUpdate; + t_uint8 index; + }t_sva_dp_debug_update_infos; + typedef struct { + t_sva_buffer_id bufferId; + t_bool isPopEmpty; + t_bool isResolvedAll; + t_sva_dp_debug_update_infos updateInfos; + }t_sva_dp_debug_update_desc; + typedef struct { + t_uint32 padding[3]; + t_uint32 nbOfResolvedDep; + t_sva_dp_debug_update_desc updateDebugDesc[LOG_DEPTH]; + }t_sva_dp_debug_update; + + +#endif + + + + + + + + + + + + + + + + + + +#ifdef __cplusplus +} /* allow C++ to use these headers */ +#endif /* __cplusplus */ + +#endif /* __INC_SVA_DISPLAYP_H */ +/* End of file - sva_displayp.h */ --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/encode/brc/sva_brc.c @@ -0,0 +1,3648 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ + + +/*------------------------------------------------------------------------ + * Includes + *----------------------------------------------------------------------*/ +#include "hcl_defs.h" +#include "sva_host_interface.h" +#include "sva_buffermgt.h" +#include "sva_fifo.h" +#include "sva_encode.h" +#include "../sva_ec_algo.h" +#include "sva_brc.h" +#include "sva_brcp.h" + +/*------------------------------------------------------------------------ + * Global Variables + *----------------------------------------------------------------------*/ +PRIVATE t_sva_brc_descriptor brcDesc[NUM_MAX_BRC]; + +/*------------------------------------------------------------------------ + * Private functions + *----------------------------------------------------------------------*/ +PRIVATE t_sva_brc_error sva_BRC_ResetDescriptor(t_sva_brc_descriptor *); +PRIVATE t_sva_brc_error sva_EC_BRC_InitQpConstant(t_sva_service_instance_num ,const t_sva_video_encoder_configuration *); +PRIVATE t_sva_brc_error sva_EC_BRC_InitVbr(t_sva_service_instance_num ,const t_sva_video_encoder_configuration *); +PRIVATE t_sva_brc_error sva_EC_BRC_InitCbr(t_sva_service_instance_num ,const t_sva_video_encoder_configuration *); +PRIVATE t_sva_brc_error sva_EC_BRC_InitFrameBase(t_sva_service_instance_num ,const t_sva_video_encoder_configuration *); +PRIVATE t_bool sva_BRC_IsQpConstantConfigurationValid(const t_sva_video_encoder_configuration *); +PRIVATE t_bool sva_BRC_IsVbrConfigurationValid(const t_sva_video_encoder_configuration *); +PRIVATE t_bool sva_BRC_IsCbrConfigurationValid(const t_sva_video_encoder_configuration *); +PRIVATE t_bool sva_BRC_IsFrameBaseConfigurationValid(const t_sva_video_encoder_configuration *); +PRIVATE t_sva_brc_error sva_EC_BRC_InitPictureQpConstant(t_sva_service_instance_num, t_sva_timestamp_value, t_sva_brc_out *, t_bool *); +PRIVATE t_sva_brc_error sva_EC_BRC_InitPictureVbr(t_sva_service_instance_num, t_sva_timestamp_value, t_sva_brc_out *, t_bool *); +PRIVATE t_sva_brc_error sva_EC_BRC_InitPictureCbr(t_sva_service_instance_num, t_sva_timestamp_value, t_sva_brc_out *, t_bool *); +PRIVATE t_sva_brc_error sva_EC_BRC_InitPictureFrameBase(t_sva_service_instance_num, t_sva_brc_user_request, t_sva_brc_out *); +PRIVATE t_sva_brc_error sva_EC_BRC_InitSeqQpConstant(t_sva_service_instance_num ,t_sva_brc_out *); +PRIVATE t_sva_brc_error sva_EC_BRC_InitSeqVbr(t_sva_service_instance_num ,t_sva_brc_out *); +PRIVATE t_sva_brc_error sva_EC_BRC_InitSeqCbr(t_sva_service_instance_num ,t_sva_brc_out *); +PRIVATE t_sva_brc_error sva_EC_BRC_InitQpBrcStatsPrev(t_sva_service_instance_num ,t_uint32 *); +PRIVATE t_sva_brc_error sva_EC_BRC_InitVbrBrcStatsPrev(t_sva_service_instance_num ,t_uint32 *); +PRIVATE t_sva_brc_error sva_EC_BRC_InitCbrBrcStatsPrev(t_sva_service_instance_num ,t_uint32 *); +PRIVATE t_sva_brc_error sva_EC_BRC_InitFrameBaseBrcStatsPrev(t_sva_service_instance_num ,t_uint32 *); +PRIVATE t_sva_brc_error sva_EC_BRC_UpdateQpParams(t_sva_service_instance_num ,t_sva_update_cmd_type ,t_sva_video_encoder_param_id ,t_uint32); +PRIVATE t_sva_brc_error sva_EC_BRC_UpdateVbrParams(t_sva_service_instance_num ,t_sva_update_cmd_type ,t_sva_video_encoder_param_id ,t_uint32); +PRIVATE t_sva_brc_error sva_EC_BRC_UpdateCbrParams(t_sva_service_instance_num ,t_sva_update_cmd_type ,t_sva_video_encoder_param_id ,t_uint32); +PRIVATE t_sva_brc_error sva_EC_BRC_UpdateFrameBaseParams(t_sva_service_instance_num ,t_sva_update_cmd_type ,t_sva_video_encoder_param_id ,t_uint32); +PRIVATE t_sva_brc_error sva_EC_BRC_ComputeIntraPeriod(t_sva_service_instance_num, t_uint32, t_uint32 *); +PRIVATE t_uint32 sva_EC_BRC_MaxVopSize(t_uint32); +PRIVATE t_bool sva_EC_BRC_IsPreviousPictureWasStrategicSkipCbr(t_sva_service_instance_num); +PRIVATE t_bool sva_EC_BRC_IsPreviousPictureWasStrategicSkipQpConstantHrd(t_sva_service_instance_num); + +/****************************************************************************/ +/* NAME: t_sva_brc_error sva_EC_BRC_Init( */ +/* t_sva_service_instance_num instanceNum, */ +/* const t_sva_video_encoder_configuration *pConf */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine init a brc descriptor. It save configuration and */ +/* check it. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - instanceNum: number of the descriptor to use. */ +/* - pConf: configuration to use and check. */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_brc_error */ +/* t.b.d */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + * TODO : add others brc algo +*/ +PUBLIC t_sva_brc_error sva_EC_BRC_Init( + t_sva_service_instance_num instanceNum, + const t_sva_video_encoder_configuration *pConf +) +{ + t_sva_brc_descriptor *pDesc=&brcDesc[instanceNum]; + t_sva_brc_error status; + + HCL_DEBUG_ASSERT(pConf!=NULL); + /*reset current descriptor*/ + status=sva_BRC_ResetDescriptor(pDesc); + if (status!=SVA_BRC_OK) {return status;} + + /*init descriptor according to brc mode*/ + switch(pConf->brcMode) + { + case SVA_QP_CONSTANT: + status = sva_EC_BRC_InitQpConstant(instanceNum,pConf); + break; + case SVA_VBR: + status = sva_EC_BRC_InitVbr(instanceNum,pConf); + break; + case SVA_CBR: + status = sva_EC_BRC_InitCbr(instanceNum,pConf); + break; + case SVA_FRAME_BASE: + status = sva_EC_BRC_InitFrameBase(instanceNum,pConf); + break; + default: + status=SVA_BRC_NOT_SUPPORTED; + break; + } + + return status; +} + +/****************************************************************************/ +/* NAME: t_sva_brc_error sva_EC_BRC_GetInternalNeeds( */ +/* t_sva_service_instance_num instanceNum, */ +/* t_size *pSize */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will return cachable memory need by brc. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - instanceNum: number of the descriptor to use. */ +/* */ +/* OUT : */ +/* - pSize: needed size in bytes */ +/* */ +/* RETURN: */ +/* t_sva_brc_error */ +/* t.b.d */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + * DONE +*/ +PUBLIC t_sva_brc_error sva_EC_BRC_GetInternalNeeds( + t_sva_service_instance_num instanceNum, + t_size *pSize +) +{ + HCL_DEBUG_ASSERT(pSize!=NULL); + + (void) instanceNum; + /*need no memory*/ + *pSize=0; + + return SVA_BRC_OK; +} + +/****************************************************************************/ +/* NAME: t_sva_brc_error sva_EC_BRC_ProvideMemoryNeeds( */ +/* t_sva_service_instance_num instanceNum */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will allow brc to use cachable memory request during */ +/* sva_EC_BRC_GetInternalNeeds() call. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - instanceNum: number of the descriptor to use. */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_brc_error */ +/* t.b.d */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + * DONE +*/ +PUBLIC t_sva_brc_error sva_EC_BRC_ProvideMemoryNeeds( + t_sva_service_instance_num instanceNum +) +{ + /*nothing to do*/ + (void) instanceNum; + + return SVA_BRC_OK; +} + +/****************************************************************************/ +/* NAME: t_sva_brc_error sva_EC_BRC_EncodeAlgoDelete( */ +/* t_sva_service_instance_num instanceNum */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will allow brc to delete all memory need (fifos) */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - instanceNum: number of the descriptor to use. */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_brc_error */ +/* t.b.d */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + * DONE +*/ +PUBLIC t_sva_brc_error sva_EC_BRC_EncodeAlgoDelete( + t_sva_service_instance_num instanceNum +) +{ + /*nothing to do*/ + (void) instanceNum; + + return SVA_BRC_OK; +} + +/****************************************************************************/ +/* NAME: t_sva_brc_error sva_EC_BRC_InitPicture( */ +/* t_sva_service_instance_num instanceNum, */ +/* t_sva_brc_user_request brcUserRequest, */ +/* t_sva_timestamp_value pts, */ +/* t_sva_brc_out *pBrcOut, */ +/* t_bool *pIsPreviousSkip */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will be called before each picture. It will return */ +/* some value to be use to program picture. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - instanceNum: number of the descriptor to use. */ +/* - brcUserRequest: give param from user in case of framebase brc, else */ +/* not use. */ +/* - pts: timeStamp value of picture to program. */ +/* */ +/* OUT : */ +/* - pBrcOut: data need by algo to program params in of a subtask */ +/* - pIsPreviousSkip: return true when previous picture was skip. */ +/* */ +/* RETURN: */ +/* t_sva_brc_error */ +/* t.b.d */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + * DONE +*/ +PUBLIC t_sva_brc_error sva_EC_BRC_InitPicture( + t_sva_service_instance_num instanceNum, + t_sva_brc_user_request brcUserRequest, + t_sva_timestamp_value pts, + t_sva_brc_out *pBrcOut, + t_bool *pIsPreviousSkip +) +{ + t_sva_brc_descriptor *pDesc=&brcDesc[instanceNum]; + t_sva_video_encoder_configuration *pConf=&pDesc->conf; + t_sva_brc_error status; + + HCL_DEBUG_ASSERT(pBrcOut!=NULL); + HCL_DEBUG_ASSERT(pIsPreviousSkip!=NULL); + /*default skip value*/ + *pIsPreviousSkip = FALSE; + /*call correct function according to brc mode*/ + switch(pConf->brcMode) + { + case SVA_QP_CONSTANT: + status = sva_EC_BRC_InitPictureQpConstant(instanceNum,pts,pBrcOut,pIsPreviousSkip); + break; + case SVA_VBR: + status = sva_EC_BRC_InitPictureVbr(instanceNum,pts,pBrcOut,pIsPreviousSkip); + break; + case SVA_CBR: + status = sva_EC_BRC_InitPictureCbr(instanceNum,pts,pBrcOut,pIsPreviousSkip); + break; + case SVA_FRAME_BASE: + status = sva_EC_BRC_InitPictureFrameBase(instanceNum,brcUserRequest,pBrcOut); + break; + default: + status=SVA_BRC_NOT_SUPPORTED; + break; + } + + return status; +} + +/****************************************************************************/ +/* NAME: t_sva_brc_error sva_EC_BRC_FinishPicture( */ +/* t_sva_service_instance_num instanceNum, */ +/* t_sva_brc_in *pBrcIn */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will be called after encoding of a picture to return */ +/* infos need by brc algorithm. It's call just after EOT. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - instanceNum: number of the descriptor to use. */ +/* - pBrcIn: data coming from algo after picture is finish */ +/* */ +/* OUT : */ +/* - pIsCurrentStrategicSkip: return info about the fact current is strategic*/ +/* skip or not. */ +/* */ +/* RETURN: */ +/* t_sva_brc_error */ +/* t.b.d */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + * DONE +*/ +PUBLIC t_sva_brc_error sva_EC_BRC_FinishPicture( + t_sva_service_instance_num instanceNum, + t_sva_brc_in *pBrcIn +) +{ + t_sva_brc_descriptor *pDesc=&brcDesc[instanceNum]; + //t_sva_video_encoder_configuration *pConf=&pDesc->conf; + t_sva_brc_error status = SVA_BRC_OK; + + HCL_DEBUG_ASSERT(pBrcIn!=NULL); + + /*store data in eot fifo*/ + pDesc->eotFifo.eotData[pDesc->eotFifo.ptrWrite].bitstreamSizeInBits = pBrcIn->bitstreamSize + pBrcIn->stuffingBits; + pDesc->eotFifo.eotData[pDesc->eotFifo.ptrWrite].bufferFullness = 0; + pDesc->eotFifo.eotData[pDesc->eotFifo.ptrWrite].skipPrev = pBrcIn->brcSkipPrev; + pDesc->eotFifo.eotData[pDesc->eotFifo.ptrWrite].skipCurrent = pBrcIn->skipCurrent; + pDesc->eotFifo.ptrWrite = 1 - pDesc->eotFifo.ptrWrite; + + return status; +} + +/****************************************************************************/ +/* NAME: t_sva_brc_error sva_EC_BRC_InitBrcStatsPrev( */ +/* t_sva_service_instance_num instanceNum, */ +/* t_uint32 *pBrcStatsPrev */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will be called after encoding of a picture to return */ +/* infos need by brc algorithm. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - instanceNum: number of the descriptor to use. */ +/* */ +/* OUT : */ +/* - pBrcStatsPrev: brc stats to init. */ +/* */ +/* RETURN: */ +/* t_sva_brc_error */ +/* t.b.d */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + + */ +PUBLIC t_sva_brc_error sva_EC_BRC_InitBrcStatsPrev( + t_sva_service_instance_num instanceNum, + t_uint32 *pBrcStatsPrev +) +{ + t_sva_brc_descriptor *pDesc=&brcDesc[instanceNum]; + t_sva_video_encoder_configuration *pConf=&pDesc->conf; + t_sva_brc_error status; + + HCL_DEBUG_ASSERT(pBrcStatsPrev!=NULL); + /*call correct function according to brc mode*/ + switch(pConf->brcMode) + { + case SVA_QP_CONSTANT: + status = sva_EC_BRC_InitQpBrcStatsPrev(instanceNum,pBrcStatsPrev); + break; + case SVA_VBR: + status = sva_EC_BRC_InitVbrBrcStatsPrev(instanceNum,pBrcStatsPrev); + break; + case SVA_CBR: + status = sva_EC_BRC_InitCbrBrcStatsPrev(instanceNum,pBrcStatsPrev); + break; + case SVA_FRAME_BASE: + status = sva_EC_BRC_InitFrameBaseBrcStatsPrev(instanceNum,pBrcStatsPrev); + break; + default: + status = SVA_BRC_NOT_SUPPORTED; + break; + } + + return status; +} + +/****************************************************************************/ +/* NAME: t_sva_ec_algo_error sva_EC_BRC_UpdateBrcParams( */ +/* t_sva_service_instance_num instanceNum, */ +/* t_sva_update_cmd_type updateCmdType, */ +/* t_sva_video_encoder_param_id paramId, */ +/* t_uint32 param */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will update brc dynamic parameters */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - instanceNum: number of the descriptor to use. */ +/* - updateCmdType: command to apply to the Brc */ +/* - paramId: Parameter to update */ +/* - param: parameter for the cmdType */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_ec_algo_error */ +/* t.b.d */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + +*/ +PUBLIC t_sva_brc_error sva_EC_BRC_UpdateBrcParams( + t_sva_service_instance_num instanceNum, + t_sva_update_cmd_type updateCmdType, + t_sva_video_encoder_param_id paramId, + t_uint32 param +) +{ + t_sva_brc_descriptor *pDesc=&brcDesc[instanceNum]; + t_sva_video_encoder_configuration *pConf=&pDesc->conf; + t_sva_brc_error status; + + /*call correct function according to brc mode*/ + switch(pConf->brcMode) + { + case SVA_QP_CONSTANT: + status = sva_EC_BRC_UpdateQpParams(instanceNum,updateCmdType,paramId,param); + break; + case SVA_VBR: + status = sva_EC_BRC_UpdateVbrParams(instanceNum,updateCmdType,paramId,param); + break; + case SVA_CBR: + status = sva_EC_BRC_UpdateCbrParams(instanceNum,updateCmdType,paramId,param); + break; + case SVA_FRAME_BASE: + status = sva_EC_BRC_UpdateFrameBaseParams(instanceNum,updateCmdType,paramId,param); + break; + default: + status=SVA_BRC_NOT_SUPPORTED; + break; + } + + return status; +} + + +/****************************************************************************/ +/* NAME: t_sva_brc_error sva_BRC_ResetDescriptor( */ +/* t_sva_brc_descriptor *pDesc */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine init a brc descriptor. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - pDesc: descriptor to init */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_brc_error */ +/* t.b.d */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + * DONE +*/ +PRIVATE t_sva_brc_error sva_BRC_ResetDescriptor( + t_sva_brc_descriptor *pDesc +) +{ + HCL_DEBUG_ASSERT(pDesc!=NULL); + + pDesc->isNextConfRequiredIntraResquest = FALSE; + pDesc->isFlagIntraRequest = FALSE; + + return SVA_BRC_OK; +} + +/****************************************************************************/ +/* NAME: t_sva_brc_error sva_EC_BRC_InitQpConstant( */ +/* t_sva_service_instance_num instanceNum, */ +/* const t_sva_video_encoder_configuration *pConf */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine init a brc descriptor. It save configuration and */ +/* check it. This is only for Qp constant brc. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - pDesc: descriptor to init */ +/* - pConf: configuration to use */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_brc_error */ +/* t.b.d */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + * DONE +*/ +PRIVATE t_sva_brc_error sva_EC_BRC_InitQpConstant( + t_sva_service_instance_num instanceNum, + const t_sva_video_encoder_configuration *pConf +) +{ + t_sva_brc_descriptor *pDesc=&brcDesc[instanceNum]; + + HCL_DEBUG_ASSERT(pConf!=NULL); + /*check configuration*/ + if (sva_BRC_IsQpConstantConfigurationValid(pConf)==FALSE) + { + return SVA_BRC_NOT_SUPPORTED; + } + + /*init some stuff*/ + pDesc->qpConstantState.pictureCounter = 0; + + /*save configuration*/ + pDesc->conf=*pConf; +#if defined(SVA_BRC_H264) /* H264 BRC */ + + pDesc->h264Conf=*((t_sva_video_encoder_algo_h264_configuration_params *)pConf->pAlgoConfig); +#else /* MPEG4 BRC */ + + pDesc->mp4Conf=*((t_sva_video_encoder_algo_mpeg4_configuration_params *)pConf->pAlgoConfig); +#endif /* End defined(SVA_BRC_H264) */ + pDesc->brcQpParam=*((t_sva_brc_qpConstant_configuration_params *)pConf->pBrcConfig); + pDesc->nextBrcQpParam=*((t_sva_brc_qpConstant_configuration_params *)pConf->pBrcConfig); + + return SVA_BRC_OK; +} + +/****************************************************************************/ +/* NAME: t_sva_brc_error sva_EC_BRC_InitVbr( */ +/* t_sva_service_instance_num instanceNum, */ +/* const t_sva_video_encoder_configuration *pConf */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine init a brc descriptor. It save configuration and */ +/* check it. This is only for Vbr brc. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - pDesc: descriptor to init */ +/* - pConf: configuration to use */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_brc_error */ +/* t.b.d */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + * DONE +*/ +PRIVATE t_sva_brc_error sva_EC_BRC_InitVbr( + t_sva_service_instance_num instanceNum, + const t_sva_video_encoder_configuration *pConf +) +{ + t_sva_brc_descriptor *pDesc=&brcDesc[instanceNum]; + + HCL_DEBUG_ASSERT(pConf!=NULL); + /*check configuration*/ + if (sva_BRC_IsVbrConfigurationValid(pConf)==FALSE) + { + return SVA_BRC_NOT_SUPPORTED; + } + + /*init some stuff*/ + pDesc->vbrState.pictureCounter = 0; + + /*save configuration*/ + pDesc->conf=*pConf; +#if defined(SVA_BRC_H264) /* H264 BRC */ + + pDesc->h264Conf=*((t_sva_video_encoder_algo_h264_configuration_params *)pConf->pAlgoConfig); +#else /* MPEG4 BRC */ + + pDesc->mp4Conf=*((t_sva_video_encoder_algo_mpeg4_configuration_params *)pConf->pAlgoConfig); +#endif /* End defined(SVA_BRC_H264) */ + pDesc->brcVbrParam=*((t_sva_brc_vbr_configuration_params *)pConf->pBrcConfig); + pDesc->nextBrcVbrParam=*((t_sva_brc_vbr_configuration_params *)pConf->pBrcConfig); + + return SVA_BRC_OK; +} + +/****************************************************************************/ +/* NAME: t_sva_brc_error sva_EC_BRC_InitCbr( */ +/* t_sva_service_instance_num instanceNum, */ +/* const t_sva_video_encoder_configuration *pConf */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine init a brc descriptor. It save configuration and */ +/* check it. This is only for Cbr brc. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - pDesc: descriptor to init */ +/* - pConf: configuration to use */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_brc_error */ +/* t.b.d */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + * DONE +*/ +PRIVATE t_sva_brc_error sva_EC_BRC_InitCbr( + t_sva_service_instance_num instanceNum, + const t_sva_video_encoder_configuration *pConf +) +{ + t_sva_brc_descriptor *pDesc=&brcDesc[instanceNum]; + + HCL_DEBUG_ASSERT(pConf!=NULL); + /*check configuration*/ + if (sva_BRC_IsCbrConfigurationValid(pConf)==FALSE) + { + return SVA_BRC_NOT_SUPPORTED; + } + + /*init some stuff*/ + pDesc->cbrState.pictureCounter = 0; + + /*save configuration*/ + pDesc->conf=*pConf; +#if defined(SVA_BRC_H264) /* H264 BRC */ + + pDesc->h264Conf=*((t_sva_video_encoder_algo_h264_configuration_params *)pConf->pAlgoConfig); +#else /* MPEG4 BRC */ + + pDesc->mp4Conf=*((t_sva_video_encoder_algo_mpeg4_configuration_params *)pConf->pAlgoConfig); +#endif /* End defined(SVA_BRC_H264) */ + pDesc->brcCbrParam=*((t_sva_brc_cbr_configuration_params *)pConf->pBrcConfig); + pDesc->nextBrcCbrParam=*((t_sva_brc_cbr_configuration_params *)pConf->pBrcConfig); + + return SVA_BRC_OK; +} + +/****************************************************************************/ +/* NAME: t_sva_brc_error sva_EC_BRC_InitFrameBase( */ +/* t_sva_service_instance_num instanceNum, */ +/* const t_sva_video_encoder_configuration *pConf */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine init a brc descriptor. It save configuration and */ +/* check it. This is only for frmae base brc. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - pDesc: descriptor to init */ +/* - pConf: configuration to use */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_brc_error */ +/* t.b.d */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + * DONE +*/ +PRIVATE t_sva_brc_error sva_EC_BRC_InitFrameBase( + t_sva_service_instance_num instanceNum, + const t_sva_video_encoder_configuration *pConf +) +{ + t_sva_brc_descriptor *pDesc=&brcDesc[instanceNum]; + + HCL_DEBUG_ASSERT(pConf!=NULL); + /*check configuration*/ + if (sva_BRC_IsFrameBaseConfigurationValid(pConf)==FALSE) + { + return SVA_BRC_NOT_SUPPORTED; + } + + /*save configuration*/ + pDesc->conf=*pConf; + + return SVA_BRC_OK; +} + +/****************************************************************************/ +/* NAME: t_bool sva_BRC_IsQpConstantConfigurationValid( */ +/* const t_sva_video_encoder_configuration *pConf */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will check configuration is valid for a Qp constant */ +/* brc algorithm. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - pConf: configuration to check. */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_bool */ +/* t.b.d */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + * DONE +*/ +PRIVATE t_bool sva_BRC_IsQpConstantConfigurationValid( + const t_sva_video_encoder_configuration *pConf +) +{ + t_sva_brc_qpConstant_configuration_params *pConfQp; + + HCL_DEBUG_ASSERT(pConf!=NULL); + pConfQp=(t_sva_brc_qpConstant_configuration_params *) pConf->pBrcConfig; + + /*check Qp constant param*/ + CHECK_RANGE(pConfQp->IPictureQp, SVA_BRC_QP_I_MIN, SVA_BRC_QP_I_MAX); + CHECK_RANGE(pConfQp->PPictureQp, SVA_BRC_QP_P_MIN, SVA_BRC_QP_P_MAX); + + return TRUE; +} + +/****************************************************************************/ +/* NAME: t_bool sva_BRC_IsVbrConfigurationValid( */ +/* const t_sva_video_encoder_configuration *pConf */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will check configuration is valid for a Vbr */ +/* brc algorithm. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - pConf: configuration to check. */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_bool */ +/* t.b.d */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + +*/ +PRIVATE t_bool sva_BRC_IsVbrConfigurationValid( + const t_sva_video_encoder_configuration *pConf +) +{ + t_sva_brc_vbr_configuration_params *pConfVbr; + + HCL_DEBUG_ASSERT(pConf!=NULL); + pConfVbr=(t_sva_brc_vbr_configuration_params *) pConf->pBrcConfig; + + (void) pConfVbr; + + + return TRUE; +} + +/****************************************************************************/ +/* NAME: t_bool sva_BRC_IsCbrConfigurationValid( */ +/* const t_sva_video_encoder_configuration *pConf */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will check configuration is valid for a Cbr */ +/* brc algorithm. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - pConf: configuration to check. */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_bool */ +/* t.b.d */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + +*/ +PRIVATE t_bool sva_BRC_IsCbrConfigurationValid( + const t_sva_video_encoder_configuration *pConf +) +{ + t_sva_brc_cbr_configuration_params *pConfCbr; + + HCL_DEBUG_ASSERT(pConf!=NULL); + pConfCbr=(t_sva_brc_cbr_configuration_params *) pConf->pBrcConfig; + + (void) pConfCbr; + + + return TRUE; +} + +/****************************************************************************/ +/* NAME: t_bool sva_BRC_IsFrameBaseConfigurationValid( */ +/* const t_sva_video_encoder_configuration *pConf */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will check configuration is valid for a frame base */ +/* brc algorithm. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - pConf: configuration to check. */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_bool */ +/* t.b.d */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + * DONE +*/ +PRIVATE t_bool sva_BRC_IsFrameBaseConfigurationValid( + const t_sva_video_encoder_configuration *pConf +) +{ + /* as there is no field in a frame base configuration it is always valid*/ + + return TRUE; +} + +/****************************************************************************/ +/* NAME: t_sva_brc_error sva_EC_BRC_InitPictureQpConstant( */ +/* t_sva_service_instance_num instanceNum, */ +/* t_sva_timestamp_value pts, */ +/* t_sva_brc_out *pBrcOut, */ +/* t_bool *pIsPreviousSkip */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will be called before each picture. It will return */ +/* some value to be use to program picture. This is Qp constant */ +/* variant. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - instanceNum: number of the descriptor to use. */ +/* - pts: Time stamp of picture. */ +/* */ +/* OUT : */ +/* - pBrcOut: data need by algo to program params in of a subtask */ +/* - pIsPreviousSkip: Return info about the fact previous picture is skip. */ +/* */ +/* RETURN: */ +/* t_sva_brc_error */ +/* t.b.d */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + * DONE +*/ +PRIVATE t_sva_brc_error sva_EC_BRC_InitPictureQpConstant( + t_sva_service_instance_num instanceNum, + t_sva_timestamp_value pts, + t_sva_brc_out *pBrcOut, + t_bool *pIsPreviousSkip +) +{ + t_sva_brc_descriptor *pDesc = &brcDesc[instanceNum]; + t_sva_brc_qpConstant_configuration_params *pBrcParam=&pDesc->brcQpParam; + t_sva_brc_qpConstant_state *pState = &pDesc->qpConstantState; + t_sva_brc_error brcError = SVA_BRC_OK; + t_sint32 bufferLevel; + + HCL_DEBUG_ASSERT(pBrcOut!=NULL); + HCL_DEBUG_ASSERT(pIsPreviousSkip!=NULL); + + *pIsPreviousSkip = FALSE; + /* + * We try to program a new picture n. We first excecute NoBRC_host_PostPict() that + * use EOT information from picture n-2 and then NoBRC_HOST_InitPict(). + * Note the following things : + * - this API can be call twice if we have an It skip and picture is already + * programmed. In that case we don't have to re-run code. We will simply + * use save pBrcOut during previous call. Only code part that can modify + * picture type will be run again. + * - for first call we call the equivalent of NoBRC_InitSeq(). + * - for second call (so for picture 1) we don't have a valid eot. But such + * a virtual eot will be build in NoBRC_InitSeq() and put in eotFifo. + */ + if (pState->pictureCounter == 0) + { + brcError = sva_EC_BRC_InitSeqQpConstant(instanceNum,pBrcOut); + pState->prevPts = pts; + } + else + { + t_uint32 ptsDiff = pts - pState->prevPts; + t_sva_brc_eot_data *pEotDataNMinus2 = &pDesc->eotFifo.eotData[1-(pState->pictureCounter%2)]; + + pState->prevPts = pts; + /*first detect if we replay a picture*/ + if (ptsDiff == 0) + { + *pIsPreviousSkip = TRUE; + + /*need to get back programming*/ + *pBrcOut = pState->saveBrcOut; + + /* handle special case of all first pictures skipped */ + /* note that we use pState->pictureCounter - 1 since pState->pictureCounter*/ + /* has already been incremented */ + if (pDesc->conf.bufferingModel == SVA_BRC_QP_CONSTANT_VBV_ANNEX_G) + { + if (pState->pictureCounter - 1 == pState->skipCount[1] + 1) + { + pBrcOut->tsSeconds = 0; + pBrcOut->tsModulo = 0; + pBrcOut->firstISkippedFlag = 1; + } + } + + /*fix skip count*/ + pState->skipCount[0] = pState->skipCount[1] + 1; + pBrcOut->skipCount = pState->skipCount[0]; + + /*need to know if previous was an Intra to fix picture type*/ + /*deltaTicks is reset. Modif in ref v2.4*/ + if (pState->pictureCodingType[1] == SVA_BRC_I_PICTURE) + { + pBrcOut->pictureCodingType = SVA_BRC_I_PICTURE; + pBrcOut->quant = pBrcParam->IPictureQp; + } + pState->pictureCodingType[0] = pBrcOut->pictureCodingType; + + + if (pDesc->conf.bufferingModel == SVA_BRC_QP_CONSTANT_VBV_ANNEX_G) + { + if (pState->pictureCodingType[1] == SVA_BRC_I_PICTURE) + { + pBrcOut->brcTargetMinPred = pState->brcTargetMinPred[1]; + } + pState->brcTargetMinPred[0] = pState->brcTargetMinPred[1]; + } + } + else + { + t_uint32 seconds; + t_uint32 modulo; + t_uint32 currTicks; + t_uint32 prevTicks; + + /*handle pts correction variable*/ + if (pEotDataNMinus2->skipPrev == 1 || + pState->prevStrategicSkip == 1) + { + pState->skipPrevCount++; + if (pState->pictureCounter - 1 == pState->skipPrevCount) + { + /* first pictures have been it skipped */ + pState->ptsCor += (pts - pState->prevPts); + pts = pState->prevPts; + } + } + pState->prevPts = pts; + + /*run NoBRC_host_PostPict() + NoBRC_HOST_InitPict() code*/ + /* + * NoBRC_host_PostPict() : this concern picture n-2 + * Reprogramming stuff in case of skip is done differently in HCL. + */ + /* Normal buffer handling */ + if (pEotDataNMinus2->skipPrev == 1 || + pState->prevStrategicSkip == 1) + { + pState->buffer = BRCMAX((t_sint32) pState->buffer - (t_sint32) pState->bufferDepletion,0); + } + else + { + pState->buffer = BRCMAX((t_sint32) pState->buffer + (t_sint32) pEotDataNMinus2->bitstreamSizeInBits - (t_sint32) pState->bufferDepletion,0); + } + + /*retriewe interrupt skip info for picture n-1 if it's already available*/ + if (pDesc->eotFifo.ptrWrite != (pState->pictureCounter % 2) && + pDesc->eotFifo.eotData[1-pDesc->eotFifo.ptrWrite].skipPrev == 1) + { + *pIsPreviousSkip = TRUE; + } + + /*retriewe strategic skip info for picture n-1*/ + if (pDesc->conf.bufferingModel == SVA_BUFFERING_HRD && + pState->buffer > pState->picTarget) + { + *pIsPreviousSkip = TRUE; + pState->prevStrategicSkip = 1; + } + else {pState->prevStrategicSkip = 0;} + + /*maintain skipCount variable*/ + pState->skipCount[1] = pState->skipCount[0]; + if (*pIsPreviousSkip == TRUE) {pState->skipCount[0] = pState->skipCount[0] + 1;} + else {pState->skipCount[0] = 0;} + + /* NoBRC_HOST_InitPict() code */ + /* + * First compute seconds and modulo. Modulo must be in pState->vopTimeIncrementResolution units + */ + + pState->bufferDepletion = (pState->deltaTimeStamp * pState->bitRateDelayed * pState->fixedVopTimeIncrement + pState->bufferMod) / pState->vopTimeIncrementResolution; + pState->bufferMod = (t_uint16)(pState->deltaTimeStamp * pState->bitRateDelayed * pState->fixedVopTimeIncrement + pState->bufferMod) % pState->vopTimeIncrementResolution; + pState->bitRateDelayed = pBrcParam->bitRate; + +#if defined(SVA_BRC_H264) /* H264 BRC */ + /* TBD */ //\/ Sarvesh: Check this +#else /* MPEG4 BRC */ + if (pDesc->mp4Conf.flagShortHeader == TRUE) + { + pts = (pts + 1500) / 3003; + seconds = (pts * 1001) / 30000; + modulo = (pts * 1001) % 30000; + } + else + { + seconds = pts / 90000; + modulo = pts % 90000; + modulo = (modulo * pState->vopTimeIncrementResolution) / 90000; + } +#endif /* End defined(SVA_BRC_H264) */ + currTicks = ((seconds * pState->vopTimeIncrementResolution) + modulo); + prevTicks = ((pState->oldModuloTimeBase * pState->vopTimeIncrementResolution) + pState->prevVopTimeIncrement); + pState->deltaTicks += (currTicks-prevTicks); + + pState->deltaTimeStamp = ((modulo - pState->prevVopTimeIncrement) + (seconds - pState->oldModuloTimeBase) * pState->vopTimeIncrementResolution + (pState->fixedVopTimeIncrement >> 1)) / pState->fixedVopTimeIncrement; + pState->prevVopTimeIncrement = (t_sint16)modulo; + pState->oldModuloTimeBase = (t_uint16)seconds; + + if(pBrcOut->brcType != 0) + { + pState->picTarget = ((pBrcParam->bitRate << 10) + (pState->frameRate >> 1)) / pState->frameRate; + } + + if (pDesc->conf.bufferingModel == SVA_BUFFERING_HRD) + { + pState->targetBuffLevel = (3277 * pState->picTarget) >> 15; + } + + /*fill pBrcOut*/ + if (pDesc->conf.bufferingModel == SVA_BUFFERING_NONE) {pBrcOut->brcType = SVA_BRC_QP_BUFFERING_NONE;} + else if (pDesc->conf.bufferingModel == SVA_BUFFERING_HRD) {pBrcOut->brcType = SVA_BRC_QP_CONSTANT_HRD;} + else {pBrcOut->brcType = SVA_BRC_QP_CONSTANT_VBV_ANNEX_G;} + pBrcOut->brcFrameTarget = 0; /*not use in qp constant*/ + pBrcOut->brcTargetMinPred = pState->bufferDepletion - pState->buffer; + if (pDesc->conf.bufferingModel == SVA_BUFFERING_HRD) + { + pState->maxBufferLevel = ((pBrcParam->bitRate << 10) + (pState->frameRate >> 1)) / pState->frameRate; + } + + + if (pDesc->conf.bufferingModel == SVA_BUFFERING_HRD) + { + pBrcOut->brcTargetMaxPred = BRCMAX(0, 4 * (t_sint32)pState->maxBufferLevel + (t_sint32)pState->sMax - (t_sint32)pState->buffer); + } + else + { + pBrcOut->brcTargetMaxPred = BRCMAX(0, (t_sint32)pBrcParam->vbvOccupancy - (t_sint32)pState->buffer); + } + + + pBrcOut->skipCount = pState->skipCount[0]; + pBrcOut->bitRate = pBrcParam->bitRate; + pBrcOut->frameRate = pState->frameRate; + pBrcOut->deltaTarget = pState->targetBuffLevel - pState->buffer; + pBrcOut->minQp = 2; + pBrcOut->maxQp = 31; + pBrcOut->vopTimeIncrementResolution = pState->vopTimeIncrementResolution; + pBrcOut->fixedVopTimeIncrement = pState->fixedVopTimeIncrement; + pBrcOut->smax = pState->sMax; + pBrcOut->minBaseQuality = 0; /*not use in cbr*/ + pBrcOut->minFrameRate = 0; /*not use in cbr*/ + pBrcOut->maxBuffLevel = pState->maxBufferLevel; + pBrcOut->tsSeconds = pState->oldModuloTimeBase; + pBrcOut->tsModulo = pState->prevVopTimeIncrement; + pBrcOut->firstISkippedFlag = 0; + pBrcOut->initTsModuloOld = pState->initTsModuloOld; + /* info need to fill vol header + * note that these info need only to be provide for an I + * and when isSystemHeaderAddBeforeIntra is active. We send + * them anyway for each picture. + */ + pBrcOut->vbvBufferSizeIn16384BitsUnit = (pBrcParam->vbvBufferSize >> 14); + bufferLevel = (t_sint32)pState->buffer - (t_sint32)pState->bufferDepletion; + pBrcOut->bufferSizeForVbv = bufferLevel; + + /* + * pictureCodingType is set in intra in the following case : + * - An intra must be inserted since deltaTicks reach intraPeriod + * - Previous skip picture was an intra. Note that in this + * case deltaTicks IS reset. (Modif in ref. v2.4) + */ + if (pState->pictureCodingType[0] == SVA_BRC_I_PICTURE) {pState->deltaTicks = 0;} + if (pState->deltaTicks >= pState->intraPeriod || pDesc->isFlagIntraRequest == TRUE) + { + pBrcOut->pictureCodingType = SVA_BRC_I_PICTURE; + pDesc->isFlagIntraRequest = FALSE; + pBrcOut->quant = pBrcParam->IPictureQp; + } + else + { + pBrcOut->pictureCodingType = SVA_BRC_P_PICTURE; + pBrcOut->quant = pBrcParam->PPictureQp; + } + + /*need to fix intra decision*/ + if (*pIsPreviousSkip == TRUE && pState->pictureCodingType[0] == SVA_BRC_I_PICTURE) + { + pBrcOut->pictureCodingType = SVA_BRC_I_PICTURE; + pBrcOut->quant = pBrcParam->IPictureQp; + } + + /*need to fix min pred*/ + if (pDesc->conf.bufferingModel == SVA_BRC_QP_CONSTANT_VBV_ANNEX_G) + { + if (*pIsPreviousSkip == TRUE && pState->pictureCodingType[0] == SVA_BRC_I_PICTURE) + { + pBrcOut->brcTargetMinPred = pState->brcTargetMinPred[0]; + } + } + + /* handle special case of all first pictures skipped */ + if (pDesc->conf.bufferingModel == SVA_BRC_QP_CONSTANT_VBV_ANNEX_G) + { + if (*pIsPreviousSkip == TRUE && pState->pictureCounter == pState->skipCount[0]) + { + pBrcOut->tsSeconds = 0; + pBrcOut->tsModulo = 0; + pBrcOut->firstISkippedFlag = 1; + } + } + + /*save picture type historic*/ + pState->pictureCodingType[1] = pState->pictureCodingType[0]; + pState->pictureCodingType[0] = pBrcOut->pictureCodingType; + + /*save min_pred history*/ + pState->brcTargetMinPred[1] = pState->brcTargetMinPred[0]; + pState->brcTargetMinPred[0] = pBrcOut->brcTargetMinPred; + + + /*save brcOut*/ + pState->saveBrcOut = *pBrcOut; + + /*update picture counter*/ + pState->pictureCounter++; + } + } + + return brcError; +} + +/****************************************************************************/ +/* NAME: t_sva_brc_error sva_EC_BRC_InitPictureVbr( */ +/* t_sva_service_instance_num instanceNum, */ +/* t_sva_timestamp_value pts, */ +/* t_sva_brc_out *pBrcOut, */ +/* t_bool *pIsPreviousSkip */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will be called before each picture. It will return */ +/* some value to be use to program picture. This is Vbr */ +/* variant. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - instanceNum: number of the descriptor to use. */ +/* - pts: Time stamp of picture. */ +/* */ +/* OUT : */ +/* - pBrcOut: data need by algo to program params in of a subtask */ +/* - pIsPreviousSkip: Return info about the fact previous picture is skip. */ +/* */ +/* RETURN: */ +/* t_sva_brc_error */ +/* t.b.d */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + * DONE +*/ +PRIVATE t_sva_brc_error sva_EC_BRC_InitPictureVbr( + t_sva_service_instance_num instanceNum, + t_sva_timestamp_value pts, + t_sva_brc_out *pBrcOut, + t_bool *pIsPreviousSkip +) +{ + t_sva_brc_descriptor *pDesc = &brcDesc[instanceNum]; + t_sva_brc_vbr_configuration_params *pBrcParam = &pDesc->brcVbrParam; + t_sva_brc_vbr_state *pState = &pDesc->vbrState; + t_sva_brc_error brcError = SVA_BRC_OK; + t_sint32 bufferLevel; + + HCL_DEBUG_ASSERT(pBrcOut!=NULL); + HCL_DEBUG_ASSERT(pIsPreviousSkip!=NULL); + + /* pts correction */ + pts = pts - pState->ptsCor; + + *pIsPreviousSkip = FALSE; + /* + * We try to program a new picture n. We first excecute VBR_host_PostPict() that + * use EOT information from picture n-2 and then VBR_HOST_InitPict(). + * Note the following things : + * - this API can be call twice if we have an It skip and picture is already + * programmed. In that case we don't have to re-run code. We will simply + * use save pBrcOut during previous call. Only code part that can modify + * picture type will be run again. + * - for first call we call the equivalent of MMS_InitSeq(). + * - for second call (so for picture 1) we don't have a valid eot. But such + * a virtual eot will be build in MMS_InitSeq() and put in eotFifo. + */ + if (pState->pictureCounter == 0) + { + brcError = sva_EC_BRC_InitSeqVbr(instanceNum,pBrcOut); + pState->prevPts = pts; + } + else + { + t_uint32 ptsDiff = pts - pState->prevPts; + t_sva_brc_eot_data *pEotDataNMinus2 = &pDesc->eotFifo.eotData[1-(pState->pictureCounter%2)]; + + /*first detect if we replay a picture*/ + if (ptsDiff == 0) + { + *pIsPreviousSkip = TRUE; + + /*need to get back programming*/ + *pBrcOut = pState->saveBrcOut; + + /* handle special case of all first pictures skipped */ + /* note that we use pState->pictureCounter - 1 since pState->pictureCounter*/ + /* has already been incremented */ + if (pState->pictureCounter - 1 == pState->skipCount[1] + 1) + { + pBrcOut->tsSeconds = 0; + pBrcOut->tsModulo = 0; + pBrcOut->firstISkippedFlag = 1; + } + + /*fix skip count*/ + pState->skipCount[0] = pState->skipCount[1] + 1; + pBrcOut->skipCount = pState->skipCount[0]; + + /*need to know if previous was an Intra to fix picture type*/ + /*deltaTicks is reset. Modif in ref v2.4*/ + if (pState->pictureCodingType[1] == SVA_BRC_I_PICTURE) + { + pBrcOut->pictureCodingType = SVA_BRC_I_PICTURE; + } + pState->pictureCodingType[0] = pBrcOut->pictureCodingType; + + /*fix min pred*/ + if (pState->pictureCodingType[1] == SVA_BRC_I_PICTURE) + { + pBrcOut->brcTargetMinPred = pState->brcTargetMinPred[1]; + } + pState->brcTargetMinPred[0] = pState->brcTargetMinPred[1]; + } + else + { + t_uint32 seconds; + t_uint32 modulo; + t_uint32 currTicks; + t_uint32 prevTicks; + + + /*retriewe skip info for picture n-1 if it's already available*/ + if (pDesc->eotFifo.ptrWrite != (pState->pictureCounter % 2) && + pDesc->eotFifo.eotData[1-pDesc->eotFifo.ptrWrite].skipPrev == 1) + { + *pIsPreviousSkip = TRUE; + } + + /*update spatial quality in case of dynamic change*/ + switch(pBrcParam->spatialQuality) + { + case SVA_SPATIAL_QUALITY_NONE: + pState->minBaseQuality = 31; + break; + case SVA_SPATIAL_QUALITY_LOW: + pState->minBaseQuality = 18; + break; + case SVA_SPATIAL_QUALITY_MEDIUM: + pState->minBaseQuality = 13; + break; + case SVA_SPATIAL_QUALITY_HIGH: + pState->minBaseQuality = 8; + break; + default: + brcError = SVA_BRC_NOT_SUPPORTED; + pState->minBaseQuality = 31; + break; + } + + /*maintain skipCount variable*/ + pState->skipCount[1] = pState->skipCount[0]; + if (*pIsPreviousSkip == TRUE) {pState->skipCount[0] = pState->skipCount[0] + 1;} + else {pState->skipCount[0] = 0;} + + /*handle pts correction variable*/ + if (pEotDataNMinus2->skipPrev == 1) + { + pState->skipPrevCount++; + if (pState->pictureCounter - 1 == pState->skipPrevCount) + { + /* first pictures have been it skipped */ + pState->ptsCor += (pts - pState->prevPts); + pts = pState->prevPts; + } + } + pState->prevPts = pts; + + /*run VBR_host_PostPict() + VBR_HOST_InitPict() code*/ + /* + * VBR_host_PostPict() : this use info from picture n-2 + * Reprogramming stuff in case of skip is done differently in HCL. + */ + if (pEotDataNMinus2->skipPrev == 1) /*indicate than n-2 has been It skip*/ + { + pState->buffer = BRCMAX((t_sint32) pState->buffer - (t_sint32) pState->bufferDepletion,0); + } + else + { + pState->buffer = BRCMAX((t_sint32) pState->buffer + (t_sint32) pEotDataNMinus2->bitstreamSizeInBits - (t_sint32) pState->bufferDepletion,0); + } + + /* VBR_HOST_InitPict() code */ + /* + * First compute seconds and modulo. Modulo must be in pState->vopTimeIncrementResolution units + */ + pState->bufferDepletion = (pState->deltaTimeStamp * pState->bitRateDelayed * pState->fixedVopTimeIncrement + pState->bufferMod) / pState->vopTimeIncrementResolution; + pState->bufferMod = (t_uint16)(pState->deltaTimeStamp * pState->bitRateDelayed * pState->fixedVopTimeIncrement + pState->bufferMod) % pState->vopTimeIncrementResolution; + pState->bitRateDelayed = pBrcParam->bitRate; + + +#if defined(SVA_BRC_H264) /* H264 BRC */ + /* TBD */ //\/ Sarvesh: Check this +#else /* MPEG4 BRC */ + if (pDesc->mp4Conf.flagShortHeader == TRUE) + + { + pts = (pts + 1500) / 3003; + seconds = (pts * 1001) / 30000; + modulo = (pts * 1001) % 30000; + } + else + { + seconds = pts / 90000; + modulo = pts % 90000; + modulo = (modulo * pState->vopTimeIncrementResolution) / 90000; + } +#endif /* End defined(SVA_BRC_H264) */ + currTicks = ((seconds * pState->vopTimeIncrementResolution) + modulo); + prevTicks = ((pState->oldModuloTimeBase * pState->vopTimeIncrementResolution) + pState->prevVopTimeIncrement); + pState->deltaTicks += (currTicks-prevTicks); + + + pState->deltaTimeStamp = ((modulo - pState->prevVopTimeIncrement) + (seconds - pState->oldModuloTimeBase) * pState->vopTimeIncrementResolution + (pState->fixedVopTimeIncrement >> 1)) / pState->fixedVopTimeIncrement; + pState->prevVopTimeIncrement = (t_sint16)modulo; + pState->oldModuloTimeBase = (t_uint16)seconds; + + /*fill pBrcOut*/ + pBrcOut->quant = 0; /*not use in vbr*/ + pBrcOut->brcType = SVA_BRC_VBR; + pBrcOut->brcFrameTarget = 0; /*not use in vbr*/ + pBrcOut->brcTargetMinPred = pState->bufferDepletion - pState->buffer; + + pBrcOut->brcTargetMaxPred = BRCMAX(0, (t_sint32) pBrcParam->vbvOccupancy - (t_sint32) pState->buffer); + pBrcOut->skipCount = pState->skipCount[0]; + pBrcOut->bitRate = pBrcParam->bitRate; + pBrcOut->frameRate = pState->frameRate; + pBrcOut->deltaTarget = pState->targetBuffLevel - pState->buffer; + pBrcOut->minQp = 2; + pBrcOut->maxQp = 31; + pBrcOut->vopTimeIncrementResolution = pState->vopTimeIncrementResolution; + pBrcOut->fixedVopTimeIncrement = pState->fixedVopTimeIncrement; + pBrcOut->smax = pState->sMax; + pBrcOut->minBaseQuality = pState->minBaseQuality; + pBrcOut->minFrameRate = pState->minFrameRate; + pBrcOut->maxBuffLevel = 0;/*not use in vbr*/ + pBrcOut->tsSeconds = seconds; + pBrcOut->tsModulo = modulo; + pBrcOut->firstISkippedFlag = 0; + pBrcOut->initTsModuloOld = pState->initTsModuloOld; + /* info need to fill vol header + * note that these info need only to be provide for an I + * and when isSystemHeaderAddBeforeIntra is active. We send + * them anyway for each picture. + */ + pBrcOut->vbvBufferSizeIn16384BitsUnit = (pBrcParam->vbvBufferSize >> 14); + bufferLevel = (t_sint32)pState->buffer - (t_sint32)pState->bufferDepletion; + pBrcOut->bufferSizeForVbv = bufferLevel; + + /* + * pictureCodingType is set in intra in the following case : + * - An intra must be inserted since deltaTicks reach intraPeriod + * - Previous skip picture was an intra. Note that in this + * case deltaTicks IS reset. (Modif in ref. v2.4) + */ + if (pState->pictureCodingType[0] == SVA_BRC_I_PICTURE) {pState->deltaTicks = 0;} + if (pState->deltaTicks >= pState->intraPeriod || pDesc->isFlagIntraRequest == TRUE) + { + pBrcOut->pictureCodingType = SVA_BRC_I_PICTURE; + pDesc->isFlagIntraRequest = FALSE; + } + else + { + pBrcOut->pictureCodingType = SVA_BRC_P_PICTURE; + } + + /*need to fix intra decision*/ + if (*pIsPreviousSkip == TRUE && pState->pictureCodingType[0] == SVA_BRC_I_PICTURE) + { + pBrcOut->pictureCodingType = SVA_BRC_I_PICTURE; + } + + /*need to fix min pred*/ + if (*pIsPreviousSkip == TRUE && pState->pictureCodingType[0] == SVA_BRC_I_PICTURE) + { + pBrcOut->brcTargetMinPred = pState->brcTargetMinPred[0]; + } + + /* handle special case of all first pictures skipped */ + if (*pIsPreviousSkip == TRUE && pState->pictureCounter == pState->skipCount[0]) + { + pBrcOut->tsSeconds = 0; + pBrcOut->tsModulo = 0; + pBrcOut->firstISkippedFlag = 1; + } + + /*save picture type historic*/ + pState->pictureCodingType[1] = pState->pictureCodingType[0]; + pState->pictureCodingType[0] = pBrcOut->pictureCodingType; + + /*save min_pred history*/ + pState->brcTargetMinPred[1] = pState->brcTargetMinPred[0]; + pState->brcTargetMinPred[0] = pBrcOut->brcTargetMinPred; + + /*save brcOut*/ + pState->saveBrcOut = *pBrcOut; + + /*update picture counter*/ + pState->pictureCounter++; + } + } + + return brcError; +} + +/****************************************************************************/ +/* NAME: t_sva_brc_error sva_EC_BRC_InitPictureCbr( */ +/* t_sva_service_instance_num instanceNum, */ +/* t_sva_timestamp_value pts, */ +/* t_sva_brc_out *pBrcOut, */ +/* t_bool *pIsPreviousSkip */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will be called before each picture. It will return */ +/* some value to be use to program picture. This is Cbr */ +/* variant. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - instanceNum: number of the descriptor to use. */ +/* - pts: Time stamp of picture. */ +/* */ +/* OUT : */ +/* - pBrcOut: data need by algo to program params in of a subtask */ +/* - pIsPreviousSkip: Return info about the fact previous picture is skip. */ +/* */ +/* RETURN: */ +/* t_sva_brc_error */ +/* t.b.d */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + +*/ +PRIVATE t_sva_brc_error sva_EC_BRC_InitPictureCbr( + t_sva_service_instance_num instanceNum, + t_sva_timestamp_value pts, + t_sva_brc_out *pBrcOut, + t_bool *pIsPreviousSkip +) +{ + t_sva_brc_descriptor *pDesc = &brcDesc[instanceNum]; + t_sva_brc_cbr_configuration_params *pBrcParam = &pDesc->brcCbrParam; + t_sva_brc_cbr_state *pState = &pDesc->cbrState; + t_sva_brc_error brcError = SVA_BRC_OK; + t_sint32 bufferLevel; + + HCL_DEBUG_ASSERT(pBrcOut!=NULL); + HCL_DEBUG_ASSERT(pIsPreviousSkip!=NULL); + + *pIsPreviousSkip = FALSE; + /* + * We try to program a new picture n. We first excecute VBR_host_PostPict() that + * use EOT information from picture n-2 and then VBR_HOST_InitPict(). + * Note the following things : + * - this API can be call twice if we have an It skip and picture is already + * programmed. In that case we don't have to re-run code. We will simply + * use save pBrcOut during previous call. Only code part that can modify + * picture type will be run again. + * - for first call we call the equivalent of MaSaCBR_InitSeq(). + * - for second call (so for picture 1) we don't have a valid eot. But such + * a virtual eot will be build in MaSaCBR_InitSeq() and put in eotFifo. + */ + if (pState->pictureCounter == 0) + { + brcError = sva_EC_BRC_InitSeqCbr(instanceNum,pBrcOut); + pState->prevPts = pts; + } + else + { + t_uint32 ptsDiff = pts - pState->prevPts; + t_sva_brc_eot_data *pEotDataNMinus2 = &pDesc->eotFifo.eotData[1-(pState->pictureCounter%2)]; + + pState->prevPts = pts; + /*first detect if we replay a picture*/ + if (ptsDiff == 0) + { + *pIsPreviousSkip = TRUE; + + /*need to get back programming*/ + *pBrcOut = pState->saveBrcOut; + + /*fix skip count*/ + pState->skipCount[0] = pState->skipCount[1] + 1; + pBrcOut->skipCount = pState->skipCount[0]; + + /*need to know if previous was an Intra to fix picture type*/ + /*deltaTicks is reset. Modif in ref v2.4*/ + if (pState->pictureCodingType[1] == SVA_BRC_I_PICTURE) + { + pBrcOut->pictureCodingType = SVA_BRC_I_PICTURE; + } + pState->pictureCodingType[0] = pBrcOut->pictureCodingType; + } + else + { + t_uint32 seconds; + t_uint32 modulo; + t_uint32 currTicks; + t_uint32 prevTicks; + + /*run VBR_host_PostPict() + VBR_HOST_InitPict() code*/ + /* + * VBR_host_PostPict() : this concern picture n-2 + * Reprogramming stuff in case of skip is done differently in HCL. + */ + /* Normal buffer handling */ + if (pEotDataNMinus2->skipPrev == 1 || + pState->prevStrategicSkip == 1) + { + pState->buffer = BRCMAX((t_sint32) pState->buffer - (t_sint32) pState->bufferDepletion,0); + } + else + { + pState->buffer = BRCMAX((t_sint32) pState->buffer + (t_sint32) pEotDataNMinus2->bitstreamSizeInBits - (t_sint32) pState->bufferDepletion,0); + + } +#if defined(SVA_BRC_H264) /* H264 BRC */ + /* TBD */ //\/ Sarvesh: Check this +#else /* MPEG4 BRC */ + /* time stamp modification for partly optimal timeStamp. Only for SP */ + if (pDesc->mp4Conf.flagShortHeader == FALSE) + { + if (pState->fakeFlag == 1) + { + if (pEotDataNMinus2->skipPrev == 0 && pState->prevStrategicSkip == 0 && + pState->pictureCounter > 2) + { + pState->fakeFlag = 0; + } + else if (pState->pictureCounter > 2) + { + pState->ptsDiff += ptsDiff; + } + } + } + + /* partly optimal timeStamp. Only for SP */ + if (pDesc->mp4Conf.flagShortHeader == FALSE) + { + if (pState->prevPictureCodingType == SVA_BRC_P_PICTURE && pState->prevStrategicSkip == 0 && + pState->govFlag == 0) + { + pState->govFlag = 1; + pState->buffer = BRCMAX((t_sint32)pState->bufferFakeTs + (t_sint32) pEotDataNMinus2->bitstreamSizeInBits - (t_sint32) pState->bufferDepletion,0); + } + if (pState->prevPictureCodingType == SVA_BRC_I_PICTURE && pState->govFlag == 0 && + pEotDataNMinus2->skipPrev == 0 && pState->prevStrategicSkip == 0) /* added compare to ref VI : 5649*/ + { + pState->bufferFakeTs = pState->buffer; + } + } +#endif /* End defined(SVA_BRC_H264) */ + + /*retriewe interrupt skip info for picture n-1 if it's already available*/ + if (pDesc->eotFifo.ptrWrite != (pState->pictureCounter % 2) && + pDesc->eotFifo.eotData[1-pDesc->eotFifo.ptrWrite].skipPrev == 1) + { + *pIsPreviousSkip = TRUE; + } + + /*retriewe strategic skip info for picture n-1*/ + if (pState->buffer > pState->picTarget) + { + *pIsPreviousSkip = TRUE; + pState->prevStrategicSkip = 1; + } + else {pState->prevStrategicSkip = 0;} + + /*maintain skipCount variable*/ + pState->skipCount[1] = pState->skipCount[0]; + if (*pIsPreviousSkip == TRUE) {pState->skipCount[0] = pState->skipCount[0] + 1;} + else {pState->skipCount[0] = 0;} + + /* VBR_HOST_InitPict() code */ + /* + * First compute seconds and modulo. Modulo must be in pState->vopTimeIncrementResolution units + */ + + pState->bufferDepletion = (pState->deltaTimeStamp * pState->bitRateDelayed * pState->fixedVopTimeIncrement + pState->bufferMod) / pState->vopTimeIncrementResolution; + pState->bufferMod = (t_uint16)(pState->deltaTimeStamp * pState->bitRateDelayed * pState->fixedVopTimeIncrement + pState->bufferMod) % pState->vopTimeIncrementResolution; + pState->bitRateDelayed = pBrcParam->bitRate; + + pts -= pState->ptsDiff; +#if defined(SVA_BRC_H264) /* H264 BRC */ + /* TBD */ //\/ Sarvesh: Check this +#else /* MPEG4 BRC */ + if (pDesc->mp4Conf.flagShortHeader == TRUE) + { + pts = (pts + 1500) / 3003; + seconds = (pts * 1001) / 30000; + modulo = (pts * 1001) % 30000; + } + else + { + seconds = pts / 90000; + modulo = pts % 90000; + modulo = (modulo * pState->vopTimeIncrementResolution) / 90000; + } +#endif /* End defined(SVA_BRC_H264) */ + currTicks = ((seconds * pState->vopTimeIncrementResolution) + modulo); + prevTicks = ((pState->oldModuloTimeBase * pState->vopTimeIncrementResolution) + pState->prevVopTimeIncrement); + pState->deltaTicks += (currTicks-prevTicks); + + + pState->deltaTimeStamp = ((modulo - pState->prevVopTimeIncrement) + (seconds - pState->oldModuloTimeBase) * pState->vopTimeIncrementResolution + (pState->fixedVopTimeIncrement >> 1)) / pState->fixedVopTimeIncrement; +#if defined(SVA_BRC_H264) /* H264 BRC */ + /* TBD */ //\/ Sarvesh : Check this +#else /* MPEG4 BRC */ + if (pDesc->mp4Conf.flagShortHeader == FALSE) + { + if (pState->govFlag == 1 || pState->prevStrategicSkip == 0) + { + pState->prevVopTimeIncrement = (t_sint16)modulo; + pState->oldModuloTimeBase = (t_uint16)seconds; + } + } + else + { + pState->prevVopTimeIncrement = (t_sint16)modulo; + pState->oldModuloTimeBase = (t_uint16)seconds; + } +#endif /* End defined(SVA_BRC_H264) */ + + + pState->picTarget = ((pBrcParam->bitRate << 10) + (pState->frameRate >> 1)) / pState->frameRate; + pState->targetBuffLevel = (3277 * pState->picTarget) >> 15; + + /*fill pBrcOut*/ + pBrcOut->quant = 0; /*not use in cbr*/ + pBrcOut->brcType = SVA_BRC_CBR; + pBrcOut->brcFrameTarget = 0; /*not use in cbr*/ + pBrcOut->brcTargetMinPred = pState->bufferDepletion - pState->buffer; +#if defined(SVA_BRC_H264) /* H264 BRC */ + /* Sarvesh: TBD */ //\/ Sarvesh: Check this +#else /* MPEG4 BRC */ + if (pDesc->mp4Conf.flagShortHeader == TRUE) + { + pState->maxBufferLevel = ((pBrcParam->bitRate << 10) + (pState->frameRate >> 1)) / pState->frameRate; + } + + + if (pDesc->mp4Conf.flagShortHeader == TRUE) + { + pBrcOut->brcTargetMaxPred = BRCMAX(0, 4 * (t_sint32)pState->maxBufferLevel + (t_sint32)pState->sMax - (t_sint32)pState->buffer + (t_sint32)pState->bufferDepletion); + } + else + { + pBrcOut->brcTargetMaxPred = BRCMAX(0, (t_sint32)pBrcParam->vbvOccupancy - (t_sint32)pState->buffer + (t_sint32)pState->bufferDepletion); + } +#endif /* End defined(SVA_BRC_H264) */ + + pBrcOut->skipCount = pState->skipCount[0]; + pBrcOut->bitRate = pBrcParam->bitRate; + pBrcOut->frameRate = pState->frameRate; + pBrcOut->deltaTarget = pState->targetBuffLevel - pState->buffer + pState->bufferDepletion; + pBrcOut->minQp = 2; + pBrcOut->maxQp = 31; + pBrcOut->vopTimeIncrementResolution = pState->vopTimeIncrementResolution; + pBrcOut->fixedVopTimeIncrement = pState->fixedVopTimeIncrement; + pBrcOut->smax = pState->sMax; + pBrcOut->minBaseQuality = 0; /*not use in cbr*/ + pBrcOut->minFrameRate = 0; /*not use in cbr*/ + pBrcOut->maxBuffLevel = pState->maxBufferLevel; + pBrcOut->tsSeconds = pState->oldModuloTimeBase; + pBrcOut->tsModulo = pState->prevVopTimeIncrement; + pBrcOut->firstISkippedFlag = 0;/*not use in cbr*/ + pBrcOut->initTsModuloOld = 0;/*not use in cbr*/ + /* info need to fill vol header + * note that these info need only to be provide for an I + * and when isSystemHeaderAddBeforeIntra is active. We send + * them anyway for each picture. + */ + pBrcOut->vbvBufferSizeIn16384BitsUnit = (pBrcParam->vbvBufferSize >> 14); + bufferLevel = (t_sint32)pState->buffer - (t_sint32)pState->bufferDepletion; + pBrcOut->bufferSizeForVbv = bufferLevel; + + /* save previous picture coding type*/ + pState->prevPictureCodingType = pState->pictureCodingType[0]; + + /* + * pictureCodingType is set in intra in the following case : + * - An intra must be inserted since deltaTicks reach intraPeriod + * - Previous skip picture was an intra. Note that in this + * case deltaTicks IS reset. (Modif in ref. v2.4) + */ + if (pState->pictureCodingType[0] == SVA_BRC_I_PICTURE) {pState->deltaTicks = 0;} + if (pState->deltaTicks >= pState->intraPeriod || pDesc->isFlagIntraRequest == TRUE) + { + pBrcOut->pictureCodingType = SVA_BRC_I_PICTURE; + pDesc->isFlagIntraRequest = FALSE; + } + else + { + pBrcOut->pictureCodingType = SVA_BRC_P_PICTURE; + } + + /*need to fix intra decision*/ + if (*pIsPreviousSkip == TRUE && pState->pictureCodingType[0] == SVA_BRC_I_PICTURE) + { + pBrcOut->pictureCodingType = SVA_BRC_I_PICTURE; + } + + /*save picture type historic*/ + pState->pictureCodingType[1] = pState->pictureCodingType[0]; + pState->pictureCodingType[0] = pBrcOut->pictureCodingType; + + /*save brcOut*/ + pState->saveBrcOut = *pBrcOut; + + /*update picture counter*/ + pState->pictureCounter++; + } + } + + return brcError; +} + +/****************************************************************************/ +/* NAME: t_sva_brc_error sva_EC_BRC_InitPictureFrameBase( */ +/* t_sva_service_instance_num instanceNum, */ +/* t_sva_brc_user_request brcUserRequest, */ +/* t_sva_brc_out *pBrcOut */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will be called before each picture. It will return */ +/* some value to be use to program picture. This is frame base */ +/* variant. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - instanceNum: number of the descriptor to use. */ +/* - brcUserRequest: type and size of picture request by user. */ +/* */ +/* OUT : */ +/* - pBrcOut: data need by algo to program params in of a subtask */ +/* */ +/* RETURN: */ +/* t_sva_brc_error */ +/* t.b.d */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + * DONE +*/ +PRIVATE t_sva_brc_error sva_EC_BRC_InitPictureFrameBase( + t_sva_service_instance_num instanceNum, + t_sva_brc_user_request brcUserRequest, + t_sva_brc_out *pBrcOut +) +{ + /*define directly in param in*/ + pBrcOut->pictureCodingType = brcUserRequest.pictureCodingType; + pBrcOut->quant = 0; /* not use */ + pBrcOut->brcType = SVA_BRC_FRAME_BASE; + pBrcOut->brcFrameTarget = brcUserRequest.frameTargetSize * 8; + pBrcOut->brcTargetMinPred = 0; /* not use */ + pBrcOut->brcTargetMaxPred = 0; /* not use */ + pBrcOut->skipCount = 0; /* not use */ + pBrcOut->bitRate = 0; /* not use */ + pBrcOut->frameRate = 0; /* not use */ + pBrcOut->deltaTarget = 0; /* not use */ + pBrcOut->minQp = 2; + pBrcOut->maxQp = 31; + pBrcOut->vopTimeIncrementResolution = 0; /* not use */ + pBrcOut->fixedVopTimeIncrement = 0; /* not use */ + pBrcOut->smax = 0; /* not use */ + pBrcOut->minBaseQuality = 0; /* not use */ + pBrcOut->minFrameRate = 0; /* not use */ + pBrcOut->maxBuffLevel = 0; /* not use */ + pBrcOut->tsSeconds = 0; /* not use */ + pBrcOut->tsModulo = 0; /* not use */ + pBrcOut->vbvBufferSizeIn16384BitsUnit = 0; /* not use */ + pBrcOut->bufferSizeForVbv = 0; /* not use */ + + return SVA_BRC_OK; +} + +/****************************************************************************/ +/* NAME: t_sva_brc_error sva_EC_BRC_InitSeqQpConstant( */ +/* t_sva_service_instance_num instanceNum, */ +/* t_sva_brc_out *pBrcOut */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will be called to program first subtask of Qp constant*/ +/* algo. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - instanceNum: number of the descriptor to use. */ +/* */ +/* OUT : */ +/* - pBrcOut: data need by algo to program params in of a subtask */ +/* */ +/* RETURN: */ +/* t_sva_brc_error */ +/* t.b.d */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + * DONE +*/ +PRIVATE t_sva_brc_error sva_EC_BRC_InitSeqQpConstant( + t_sva_service_instance_num instanceNum, + t_sva_brc_out *pBrcOut +) +{ + t_sva_brc_descriptor *pDesc = &brcDesc[instanceNum]; + t_sva_brc_qpConstant_configuration_params *pBrcParam = &pDesc->brcQpParam; + t_sva_brc_qpConstant_state *pState = &pDesc->qpConstantState; + t_sva_brc_error brcError = SVA_BRC_OK; + t_uint32 MBnum = (pDesc->conf.sourceFrameDesc.window.image.height * + pDesc->conf.sourceFrameDesc.window.image.width) / 256; + t_uint16 deltaTStamp; + + pState->bitRateDelayed = pBrcParam->bitRate; + + /*init hcl specific variable*/ + pState->skipCount[0] = 0; + pState->skipCount[1] = 0; + pState->pictureCodingType[0] = SVA_BRC_I_PICTURE; + pState->pictureCodingType[1] = SVA_BRC_I_PICTURE; + pState->brcTargetMinPred[0] = 0; + pState->brcTargetMinPred[1] = 0; + pState->ptsCor = 0; + pState->skipPrevCount = 0; + + /* NoBRC_InitSeq() code */ +#if defined(SVA_BRC_H264) /* H264 BRC */ + /* VBR host variable */ +//\/ pState->frameRate = ((t_uint32)((t_uint32)pDesc->h264Conf.vopTimeIncrementResolution << 10) + (pDesc->h264Conf.vopTimeIncrement >> 1)) / pDesc->h264Conf.vopTimeIncrement; +#else /* MPEG4 BRC */ + /* VBR host variable */ + pState->frameRate = ((t_uint16)((t_uint32)pDesc->mp4Conf.vopTimeIncrementResolution << 10) + (pDesc->mp4Conf.vopTimeIncrement >> 1)) / pDesc->mp4Conf.vopTimeIncrement; +#endif /* End defined(SVA_BRC_H264) */ + + pState->nextFrameRate = pState->frameRate; +#if defined(SVA_BRC_H264) /* H264 BRC */ + /* Sarvesh :TBD */ //\/ Sarvesh: Check this +#else /* MPEG4 BRC */ + if (pDesc->mp4Conf.flagShortHeader == TRUE) + { + + pState->vopTimeIncrementResolution = 30000; + pState->fixedVopTimeIncrement = 1001; + } + else + { + pState->vopTimeIncrementResolution = pDesc->mp4Conf.vopTimeIncrementResolution; + pState->fixedVopTimeIncrement = pDesc->mp4Conf.vopTimeIncrement; + } +#endif /* End defined(SVA_BRC_H264) */ + pState->bufferMod = 0; + pState->prevVopTimeIncrement = 0; + pState->oldModuloTimeBase = 0; + if (pDesc->conf.bufferingModel == SVA_BUFFERING_NONE) + { + pState->sMax = sva_EC_BRC_MaxVopSize(MBnum); + } + else if (pDesc->conf.bufferingModel == SVA_BUFFERING_HRD) + { + pState->sMax = sva_EC_BRC_MaxVopSize(MBnum); + pState->maxBufferLevel = ((pBrcParam->bitRate << 10) + (pState->frameRate >> 1)) / pState->frameRate; + pState->picTarget = ((pBrcParam->bitRate << 10) + (pState->frameRate >> 1)) / pState->frameRate; + pState->targetBuffLevel = (3277 * pState->picTarget) >> 15; + } + else + { + pState->sMax = pBrcParam->swissBuffer; + pState->maxBufferLevel = BRCMIN(pBrcParam->swissBuffer,pBrcParam->vbvOccupancy); + pState->picTarget = ((pBrcParam->bitRate << 10) + (pState->frameRate >> 1)) / pState->frameRate; + pState->targetBuffLevel = (pState->maxBufferLevel + 1) >> 1; + } + + pState->buffer = 0; +#if defined(SVA_BRC_H264) /* H264 BRC */ +//\/ pState->initTsModuloOld = -((pState->fixedVopTimeIncrement % pState->vopTimeIncrementResolution) * +//\/ (((t_sint32)pState->vopTimeIncrementResolution / pDesc->h264Conf.vopTimeIncrementResolution + ((pState->fixedVopTimeIncrement / pDesc->h264Conf.vopTimeIncrement) >> 1)) / +//\/ (pState->fixedVopTimeIncrement / pDesc->h264Conf.vopTimeIncrement))); +//\/ deltaTStamp = ((pState->fixedVopTimeIncrement % pState->vopTimeIncrementResolution) * +//\/ (((t_uint32)pState->vopTimeIncrementResolution / pDesc->h264Conf.vopTimeIncrementResolution + ((pState->fixedVopTimeIncrement / pDesc->h264Conf.vopTimeIncrement) >> 1)) / +//\/ (pState->fixedVopTimeIncrement / pDesc->h264Conf.vopTimeIncrement))); +#else /* MPEG4 BRC */ + pState->initTsModuloOld = (t_sint16)-((pState->fixedVopTimeIncrement % pState->vopTimeIncrementResolution) * + (((t_sint32)pState->vopTimeIncrementResolution / pDesc->mp4Conf.vopTimeIncrementResolution + ((pState->fixedVopTimeIncrement / pDesc->mp4Conf.vopTimeIncrement) >> 1)) / + (pState->fixedVopTimeIncrement / pDesc->mp4Conf.vopTimeIncrement))); + deltaTStamp = (t_uint16)((pState->fixedVopTimeIncrement % pState->vopTimeIncrementResolution) * + (((t_uint32)pState->vopTimeIncrementResolution / pDesc->mp4Conf.vopTimeIncrementResolution + ((pState->fixedVopTimeIncrement / pDesc->mp4Conf.vopTimeIncrement) >> 1)) / + (pState->fixedVopTimeIncrement / pDesc->mp4Conf.vopTimeIncrement))); +#endif /* End defined(SVA_BRC_H264) */ + deltaTStamp = deltaTStamp / pState->fixedVopTimeIncrement; + pState->bufferDepletion = (deltaTStamp * pBrcParam->bitRate * pState->fixedVopTimeIncrement) / pState->vopTimeIncrementResolution; + pState->deltaTicks = 0; + pState->prevStrategicSkip = 0; + + /*hamac brc value*/ + pBrcOut->pictureCodingType = SVA_BRC_I_PICTURE; + pBrcOut->quant = pBrcParam->IPictureQp; + if (pDesc->conf.bufferingModel == SVA_BUFFERING_NONE) + { + pBrcOut->brcType = SVA_BRC_QP_BUFFERING_NONE; + } + else if (pDesc->conf.bufferingModel == SVA_BUFFERING_HRD) + { + pBrcOut->brcType = SVA_BRC_QP_CONSTANT_HRD; + } + else + { + pBrcOut->brcType = SVA_BRC_QP_CONSTANT_VBV_ANNEX_G; + } + pBrcOut->brcFrameTarget = 0; + pBrcOut->brcTargetMinPred = pState->bufferDepletion; + + if (pDesc->conf.bufferingModel == SVA_BUFFERING_HRD) + { + pBrcOut->brcTargetMaxPred = 4 * pState->maxBufferLevel + pState->sMax + pState->picTarget; + } + else + { + pBrcOut->brcTargetMaxPred = pBrcParam->vbvOccupancy + pState->picTarget; + } + + pBrcOut->skipCount = 0; + pBrcOut->bitRate = pBrcParam->bitRate; + pBrcOut->frameRate = pState->frameRate; + pBrcOut->deltaTarget = pState->targetBuffLevel - pState->buffer; + pBrcOut->minQp = 2; + pBrcOut->maxQp = 31; + pBrcOut->vopTimeIncrementResolution = pState->vopTimeIncrementResolution; + pBrcOut->fixedVopTimeIncrement = pState->fixedVopTimeIncrement; + pBrcOut->smax = pState->sMax; + pBrcOut->minBaseQuality = 0;/*not use in cbr*/ + pBrcOut->minFrameRate = 0;/*not use in cbr*/ + pBrcOut->maxBuffLevel = pState->maxBufferLevel; + pBrcOut->tsSeconds = 0; + pBrcOut->tsModulo = 0; + pBrcOut->firstISkippedFlag = 0; + pBrcOut->initTsModuloOld = pState->initTsModuloOld; + + /* save brcOut */ + pState->saveBrcOut = *pBrcOut; + + /*init dataFifo*/ + pDesc->eotFifo.eotData[0].bitstreamSizeInBits = pState->bufferDepletion; + pDesc->eotFifo.eotData[0].bufferFullness = 0; + pDesc->eotFifo.eotData[0].skipPrev = 0; + pDesc->eotFifo.eotData[0].skipCurrent = 0; + pDesc->eotFifo.ptrWrite = 1; + + pState->pictureCounter++; + + + pState->deltaTimeStamp = ((t_sint16)(-pState->initTsModuloOld))/(t_sint16)pState->fixedVopTimeIncrement; + +#if defined(SVA_BRC_H264) /* H264 BRC */ + /* not exactely the same frameRate */ +//\/ pState->frameRate = (t_uint32)(((pDesc->h264Conf.vopTimeIncrementResolution) + (pDesc->h264Conf.vopTimeIncrement >> 1)) / pDesc->h264Conf.vopTimeIncrement)<<10; +#else /* MPEG4 BRC */ + /* not exactely the same frameRate */ + pState->frameRate = (t_uint16)(((pDesc->mp4Conf.vopTimeIncrementResolution) + (pDesc->mp4Conf.vopTimeIncrement >> 1)) / pDesc->mp4Conf.vopTimeIncrement)<<10; +#endif /* End defined(SVA_BRC_H264) */ + + return brcError; +} + +/****************************************************************************/ +/* NAME: t_sva_brc_error sva_EC_BRC_InitSeqVbr( */ +/* t_sva_service_instance_num instanceNum, */ +/* t_sva_brc_out *pBrcOut */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will be called to program first subtask of VBR algo. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - instanceNum: number of the descriptor to use. */ +/* */ +/* OUT : */ +/* - pBrcOut: data need by algo to program params in of a subtask */ +/* */ +/* RETURN: */ +/* t_sva_brc_error */ +/* t.b.d */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + * DONE +*/ +PRIVATE t_sva_brc_error sva_EC_BRC_InitSeqVbr( + t_sva_service_instance_num instanceNum, + t_sva_brc_out *pBrcOut +) +{ + t_sva_brc_descriptor *pDesc = &brcDesc[instanceNum]; + t_sva_brc_vbr_configuration_params *pBrcParam = &pDesc->brcVbrParam; + t_sva_brc_vbr_state *pState = &pDesc->vbrState; + t_sva_brc_error brcError = SVA_BRC_OK; + + /*init hcl specific variable*/ + pState->skipCount[0] = 0; + pState->skipCount[1] = 0; + pState->pictureCodingType[0] = SVA_BRC_I_PICTURE; + pState->pictureCodingType[1] = SVA_BRC_I_PICTURE; + pState->brcTargetMinPred[0] = 0; + pState->brcTargetMinPred[1] = 0; + pState->ptsCor = 0; + pState->skipPrevCount = 0; + + /* MMS_InitSeq() code */ +#if defined(SVA_BRC_H264) /* H264 BRC */ + /* VBR host variable */ +//\/ pState->frameRate = ((t_uint32)((t_uint32)pDesc->h264Conf.vopTimeIncrementResolution << 10) + (pDesc->h264Conf.vopTimeIncrement >> 1)) / pDesc->h264Conf.vopTimeIncrement; +#else /* MPEG4 BRC */ + /* VBR host variable */ + pState->frameRate = ((t_uint16)((t_uint32)pDesc->mp4Conf.vopTimeIncrementResolution << 10) + (pDesc->mp4Conf.vopTimeIncrement >> 1)) / pDesc->mp4Conf.vopTimeIncrement; +#endif /* End defined(SVA_BRC_H264) */ + + pState->nextFrameRate = pState->frameRate; + pState->minFrameRate = (t_uint16)pBrcParam->minFrameRate << 10; +#if defined(SVA_BRC_H264) /* H264 BRC */ + /* Sarvesh: TBD */ //\/ Sarvesh: Check this +#else /* MPEG4 BRC */ + if (pDesc->mp4Conf.flagShortHeader == TRUE) + { + + pState->vopTimeIncrementResolution = 30000; + pState->fixedVopTimeIncrement = 1001; + } + else + { + pState->vopTimeIncrementResolution = pDesc->mp4Conf.vopTimeIncrementResolution; + pState->fixedVopTimeIncrement = pDesc->mp4Conf.vopTimeIncrement; + } +#endif /* End defined(SVA_BRC_H264) */ + pState->bufferMod = 0; + pState->prevVopTimeIncrement = 0; + pState->oldModuloTimeBase = 0; + pState->maxBufferLevel = BRCMIN(pBrcParam->swissBuffer,pBrcParam->vbvOccupancy); + pState->sMax = pBrcParam->swissBuffer; + pState->targetBuffLevel = ((pState->maxBufferLevel + 1) >> 1); + pState->picTarget = ((pBrcParam->bitRate << 10) + (pState->frameRate >> 1)) / pState->frameRate; + switch(pBrcParam->spatialQuality) + { + case SVA_SPATIAL_QUALITY_NONE: + pState->minBaseQuality = 31; + break; + case SVA_SPATIAL_QUALITY_LOW: + pState->minBaseQuality = 18; + break; + case SVA_SPATIAL_QUALITY_MEDIUM: + pState->minBaseQuality = 13; + break; + case SVA_SPATIAL_QUALITY_HIGH: + pState->minBaseQuality = 8; + break; + default: + brcError = SVA_BRC_NOT_SUPPORTED; + pState->minBaseQuality = 31; + break; + } + + pBrcOut->brcTargetMaxPred = BRCMAX( 0, (t_sint32)pState->maxBufferLevel ); + + pState->buffer = 0; +#if defined(SVA_BRC_H264) /* H264 BRC */ +//\/ pState->initTsModuloOld = -((pState->fixedVopTimeIncrement % pState->vopTimeIncrementResolution) * +//\/ (((t_sint32)pState->vopTimeIncrementResolution / pDesc->h264Conf.vopTimeIncrementResolution + ((pState->fixedVopTimeIncrement / pDesc->h264Conf.vopTimeIncrement) >> 1)) / +//\/ (pState->fixedVopTimeIncrement / pDesc->h264Conf.vopTimeIncrement))); +#else /* MPEG4 BRC */ + pState->initTsModuloOld = (t_sint16)-((pState->fixedVopTimeIncrement % pState->vopTimeIncrementResolution) * + (((t_sint32)pState->vopTimeIncrementResolution / pDesc->mp4Conf.vopTimeIncrementResolution + ((pState->fixedVopTimeIncrement / pDesc->mp4Conf.vopTimeIncrement) >> 1)) / + (pState->fixedVopTimeIncrement / pDesc->mp4Conf.vopTimeIncrement))); +#endif /* End defined(SVA_BRC_H264) */ + pState->deltaTicks = ((t_sint16)(-pState->initTsModuloOld))/(t_sint16)pState->fixedVopTimeIncrement; + pState->bufferDepletion = (pState->deltaTicks * pBrcParam->bitRate * pState->fixedVopTimeIncrement) / pState->vopTimeIncrementResolution; + + pState->bitRateDelayed = pBrcParam->bitRate; + + /* hamac brc value */ + pBrcOut->pictureCodingType = SVA_BRC_I_PICTURE; + pBrcOut->quant = 0; /*not use in vbr*/ + pBrcOut->brcType = SVA_BRC_VBR; + pBrcOut->brcFrameTarget = 0; /*not use in vbr*/ + pBrcOut->brcTargetMinPred = 0; + pBrcOut->skipCount = 0; + pBrcOut->bitRate = pBrcParam->bitRate; + pBrcOut->frameRate = pState->frameRate; + pBrcOut->deltaTarget = pState->targetBuffLevel - pState->buffer; + pBrcOut->minQp = 2; + pBrcOut->maxQp = 31; + pBrcOut->vopTimeIncrementResolution = pState->vopTimeIncrementResolution; + pBrcOut->fixedVopTimeIncrement = pState->fixedVopTimeIncrement; + pBrcOut->smax = pState->sMax; + pBrcOut->minBaseQuality = pState->minBaseQuality; + pBrcOut->minFrameRate = pState->minFrameRate; + pBrcOut->maxBuffLevel = 0;/*not use in vbr*/ + pBrcOut->tsSeconds = 0; + pBrcOut->tsModulo = 0; + pBrcOut->firstISkippedFlag = 0; + pBrcOut->initTsModuloOld = pState->initTsModuloOld; + + /* save brcOut */ + pState->saveBrcOut = *pBrcOut; + + /* init dataFifo */ + pDesc->eotFifo.eotData[0].bitstreamSizeInBits = pState->bufferDepletion; + pDesc->eotFifo.eotData[0].bufferFullness = 0; + pDesc->eotFifo.eotData[0].skipPrev = 0; + pDesc->eotFifo.eotData[0].skipCurrent = 0; + pDesc->eotFifo.ptrWrite = 1; + + pState->pictureCounter++; + + //VBR_host.delta_T_stamp = ((t_sint16)(-hamac_inout.hamac_stats_prev.ts_modulo_old))/(t_sint16)VBR_host.fixed_vop_time_increment; + pState->deltaTimeStamp = ((t_sint16)(-pState->initTsModuloOld))/(t_sint16)pState->fixedVopTimeIncrement; + +#if defined(SVA_BRC_H264) /* H264 BRC */ + /* not exactely the same frameRate */ +//\/ pState->frameRate = (t_uint32)(((pDesc->h264Conf.vopTimeIncrementResolution) + (pDesc->h264Conf.vopTimeIncrement >> 1)) / pDesc->h264Conf.vopTimeIncrement)<<10; +#else /* MPEG4 BRC */ + /* not exactely the same frameRate */ + pState->frameRate = (t_uint16)(((pDesc->mp4Conf.vopTimeIncrementResolution) + (pDesc->mp4Conf.vopTimeIncrement >> 1)) / pDesc->mp4Conf.vopTimeIncrement)<<10; +#endif /* End defined(SVA_BRC_H264) */ + + return brcError; +} + +/****************************************************************************/ +/* NAME: t_sva_brc_error sva_EC_BRC_InitSeqCbr( */ +/* t_sva_service_instance_num instanceNum, */ +/* t_sva_brc_out *pBrcOut */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will be called to program first subtask of CBR algo. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - instanceNum: number of the descriptor to use. */ +/* */ +/* OUT : */ +/* - pBrcOut: data need by algo to program params in of a subtask */ +/* */ +/* RETURN: */ +/* t_sva_brc_error */ +/* t.b.d */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + * DONE +*/ +PRIVATE t_sva_brc_error sva_EC_BRC_InitSeqCbr( + t_sva_service_instance_num instanceNum, + t_sva_brc_out *pBrcOut +) +{ + + t_sva_brc_descriptor *pDesc = &brcDesc[instanceNum]; + t_sva_brc_cbr_configuration_params *pBrcParam = &pDesc->brcCbrParam; + t_sva_brc_cbr_state *pState = &pDesc->cbrState; + t_sva_brc_error brcError = SVA_BRC_OK; + t_uint32 MBnum = (pDesc->conf.sourceFrameDesc.window.image.height * + pDesc->conf.sourceFrameDesc.window.image.width) / 256; + t_uint16 deltaTStamp; + + pState->bitRateDelayed = pBrcParam->bitRate; + + /*init hcl specific variable*/ + pState->skipCount[0] = 0; + pState->skipCount[1] = 0; + pState->pictureCodingType[0] = SVA_BRC_I_PICTURE; + pState->pictureCodingType[1] = SVA_BRC_I_PICTURE; + pState->brcTargetMinPred[0] = 0; + pState->brcTargetMinPred[1] = 0; + pState->prevPictureCodingType = SVA_BRC_I_PICTURE; + pState->fakeFlag = 1; + pState->ptsDiff = 0; + + /* MaSaCBR_InitSeq() code*/ +#if defined(SVA_BRC_H264) /* H264 BRC */ + /*VBR host variable*/ +//\/ pState->frameRate = ((t_uint32)((t_uint32)pDesc->h264Conf.vopTimeIncrementResolution << 10) + (pDesc->h264Conf.vopTimeIncrement >> 1)) / pDesc->h264Conf.vopTimeIncrement; +#else /* MPEG4 BRC */ + /*VBR host variable*/ + pState->frameRate = ((t_uint16)((t_uint32)pDesc->mp4Conf.vopTimeIncrementResolution << 10) + (pDesc->mp4Conf.vopTimeIncrement >> 1)) / pDesc->mp4Conf.vopTimeIncrement; +#endif /* End defined(SVA_BRC_H264) */ + pState->nextFrameRate = pState->frameRate; +#if defined(SVA_BRC_H264) /* H264 BRC */ + /* Sarvesh: TBD */ //\/ Sarvesh: Check this +#else /* MPEG4 BRC */ + if (pDesc->mp4Conf.flagShortHeader == TRUE) + { + + pState->vopTimeIncrementResolution = 30000; + pState->fixedVopTimeIncrement = 1001; + } + else + { + pState->vopTimeIncrementResolution = pDesc->mp4Conf.vopTimeIncrementResolution; + pState->fixedVopTimeIncrement = pDesc->mp4Conf.vopTimeIncrement; + } +#endif /* End defined(SVA_BRC_H264) */ + pState->bufferMod = 0; + pState->prevVopTimeIncrement = 0; + pState->oldModuloTimeBase = 0; +#if defined(SVA_BRC_H264) /* H264 BRC */ + /* Sarvesh: TBD */ //\/ Sarvesh: Check this +#else /* MPEG4 BRC */ + if (pDesc->mp4Conf.flagShortHeader == TRUE) + { + pState->maxBufferLevel = ((pBrcParam->bitRate << 10) + (pState->frameRate >> 1)) / pState->frameRate; + pState->sMax = sva_EC_BRC_MaxVopSize(MBnum); + pState->picTarget = ((pBrcParam->bitRate << 10) + (pState->frameRate >> 1)) / pState->frameRate; + pState->targetBuffLevel = (3277 * pState->picTarget) >> 15; + } + else + { + pState->maxBufferLevel = BRCMIN(pBrcParam->swissBuffer,pBrcParam->vbvOccupancy); + pState->sMax = pBrcParam->swissBuffer; + pState->picTarget = ((pBrcParam->bitRate << 10) + (pState->frameRate >> 1)) / pState->frameRate; + pState->targetBuffLevel = (3277 * pState->picTarget) >> 15; + } +#endif /* End defined(SVA_BRC_H264) */ + pState->buffer = 0; + +#if defined(SVA_BRC_H264) /* H264 BRC */ +//\/ pState->initTsModuloOld = -((pState->fixedVopTimeIncrement % pState->vopTimeIncrementResolution) * +//\/ (((t_sint32)pState->vopTimeIncrementResolution / pDesc->h264Conf.vopTimeIncrementResolution + ((pState->fixedVopTimeIncrement / pDesc->h264Conf.vopTimeIncrement) >> 1)) / +//\/ (pState->fixedVopTimeIncrement / pDesc->h264Conf.vopTimeIncrement))); + +//\/ deltaTStamp = ((pState->fixedVopTimeIncrement % pState->vopTimeIncrementResolution) * +//\/ (((t_uint32)pState->vopTimeIncrementResolution / pDesc->h264Conf.vopTimeIncrementResolution + ((pState->fixedVopTimeIncrement / pDesc->h264Conf.vopTimeIncrement) >> 1)) / +//\/ (pState->fixedVopTimeIncrement / pDesc->h264Conf.vopTimeIncrement))); +#else /* MPEG4 BRC */ + pState->initTsModuloOld = (t_sint16)-((pState->fixedVopTimeIncrement % pState->vopTimeIncrementResolution) * + (((t_sint32)pState->vopTimeIncrementResolution / pDesc->mp4Conf.vopTimeIncrementResolution + ((pState->fixedVopTimeIncrement / pDesc->mp4Conf.vopTimeIncrement) >> 1)) / + (pState->fixedVopTimeIncrement / pDesc->mp4Conf.vopTimeIncrement))); + + deltaTStamp = (t_uint16)((pState->fixedVopTimeIncrement % pState->vopTimeIncrementResolution) * + (((t_uint32)pState->vopTimeIncrementResolution / pDesc->mp4Conf.vopTimeIncrementResolution + ((pState->fixedVopTimeIncrement / pDesc->mp4Conf.vopTimeIncrement) >> 1)) / + (pState->fixedVopTimeIncrement / pDesc->mp4Conf.vopTimeIncrement))); +#endif /* End defined(SVA_BRC_H264) */ + deltaTStamp = deltaTStamp / pState->fixedVopTimeIncrement; + + + pState->bufferDepletion = (deltaTStamp * pBrcParam->bitRate * pState->fixedVopTimeIncrement) / pState->vopTimeIncrementResolution; + pState->deltaTicks = 0; + pState->prevStrategicSkip = 0; + pState->govFlag = 0; + + /*hamac brc value*/ + pBrcOut->pictureCodingType = SVA_BRC_I_PICTURE; + pBrcOut->quant = 0; /*not use in cbr*/ + pBrcOut->brcType = SVA_BRC_CBR; + pBrcOut->brcFrameTarget = 0; /*not use in cbr*/ + pBrcOut->brcTargetMinPred = pState->bufferDepletion; +#if defined(SVA_BRC_H264) /* H264 BRC */ + /* Sarvesh: TBD */ //\/ Sarvesh: Check this +#else /* MPEG4 BRC */ + if (pDesc->mp4Conf.flagShortHeader == TRUE) + { + pBrcOut->brcTargetMaxPred = 4 * pState->maxBufferLevel + pState->sMax + pState->picTarget; + } + else + { + pBrcOut->brcTargetMaxPred = pBrcParam->vbvOccupancy + pState->picTarget; + } +#endif /* End defined(SVA_BRC_H264) */ + pBrcOut->skipCount = 0; + pBrcOut->bitRate = pBrcParam->bitRate; + pBrcOut->frameRate = pState->frameRate; + pBrcOut->deltaTarget = pState->targetBuffLevel - pState->buffer + pState->bufferDepletion; + pBrcOut->minQp = 2; + pBrcOut->maxQp = 31; + pBrcOut->vopTimeIncrementResolution = pState->vopTimeIncrementResolution; + pBrcOut->fixedVopTimeIncrement = pState->fixedVopTimeIncrement; + pBrcOut->smax = pState->sMax; + pBrcOut->minBaseQuality = 0;/*not use in cbr*/ + pBrcOut->minFrameRate = 0;/*not use in cbr*/ + pBrcOut->maxBuffLevel = pState->maxBufferLevel; + pBrcOut->tsSeconds = 0; + pBrcOut->tsModulo = 0; + pBrcOut->firstISkippedFlag = 0;/*not use in cbr*/ + pBrcOut->initTsModuloOld = pState->initTsModuloOld; + + /* save brcOut */ + pState->saveBrcOut = *pBrcOut; + + /*init dataFifo*/ + pDesc->eotFifo.eotData[0].bitstreamSizeInBits = 0; + pDesc->eotFifo.eotData[0].bufferFullness = 0; + pDesc->eotFifo.eotData[0].skipPrev = 0; + pDesc->eotFifo.eotData[0].skipCurrent = 0; + pDesc->eotFifo.ptrWrite = 1; + + pState->pictureCounter++; + pState->deltaTimeStamp = ((t_sint16)(-pState->initTsModuloOld))/(t_sint16)pState->fixedVopTimeIncrement; + +#if defined(SVA_BRC_H264) /* H264 BRC */ + /* not exactely the same frameRate */ +//\/ pState->frameRate = (t_uint32)(((pDesc->h264Conf.vopTimeIncrementResolution) + (pDesc->h264Conf.vopTimeIncrement >> 1)) / pDesc->h264Conf.vopTimeIncrement)<<10; +#else /* MPEG4 BRC */ + /* not exactely the same frameRate */ + pState->frameRate = (t_uint16)(((pDesc->mp4Conf.vopTimeIncrementResolution) + (pDesc->mp4Conf.vopTimeIncrement >> 1)) / pDesc->mp4Conf.vopTimeIncrement)<<10; +#endif /* End defined(SVA_BRC_H264) */ + + return brcError; +} + +/****************************************************************************/ +/* NAME: t_sva_brc_error sva_EC_BRC_InitQpBrcStatsPrev( */ +/* t_sva_service_instance_num instanceNum, */ +/* t_uint32 *pBrcStatsPrev */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will be called after encoding of a picture to return */ +/* infos need by brc algorithm. This is for Qp constant mode. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - instanceNum: number of the descriptor to use. */ +/* */ +/* OUT : */ +/* - pBrcStatsPrev: brc stats to init. */ +/* */ +/* RETURN: */ +/* t_sva_brc_error */ +/* t.b.d */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + +*/ +PRIVATE t_sva_brc_error sva_EC_BRC_InitQpBrcStatsPrev( + t_sva_service_instance_num instanceNum, + t_uint32 *pBrcStatsPrev +) +{ + t_sva_brc_descriptor *pDesc = &brcDesc[instanceNum]; + t_sva_brc_qpConstant_state *pState = &pDesc->qpConstantState; +#if defined(SVA_BRC_H264) /* H264 BRC */ + t_sva_vec_h264_param_inout *pInOut=(t_sva_vec_h264_param_inout *) pBrcStatsPrev; +#else /* MPEG4 BRC */ + t_sva_vec_mpeg4_param_inout *pInOut=(t_sva_vec_mpeg4_param_inout *) pBrcStatsPrev; +#endif /* End defined(SVA_BRC_H264) */ + t_sva_brc_qpConstant_configuration_params *pBrcParam = &pDesc->brcQpParam; + t_uint16 vopTimeIncrementResolution; + t_uint16 fixedVopTimeIncrement; + t_uint16 deltaTStamp; + t_uint32 bufferDepletion; + t_uint32 i; + + HCL_DEBUG_ASSERT(pBrcStatsPrev!=NULL); + HCL_DEBUG_ASSERT(pInOut!=NULL); + /*set all stuff to zero*/ + pInOut->bitstream_size = 0; + pInOut->stuffing_bits = 0; + pInOut->pictCount = 0; + pInOut->I_Qp = 0; + pInOut->P_Qp = 0; + pInOut->last_I_Size = 0; + pInOut->comp_SUM = 0; + pInOut->comp_count = 0; + pInOut->BUFFER_mod = 0; + pInOut->ts_modulo_old = 0; + pInOut->ts_seconds_old = 0; + pInOut->gov_flag = 0; + pInOut->avgSAD = 0; + pInOut->seqSAD = 0; + pInOut->min_pict_quality = 0; + pInOut->diff_min_quality = 0; + pInOut->TotSkip = 0; + pInOut->Skip_Current = 0; + pInOut->Cprev = 0; + pInOut->BPPprev = 0; + pInOut->PictQpSum = 0; + pInOut->S_overhead = 0; + pInOut->hec_count = 0; + for(i=0;i<6;i++) {pInOut->ts_vector[i] = 0;} + pInOut->buffer_fullness = 0; + +#if defined(SVA_BRC_H264) /* H264 BRC part ie if SVA_BRC_H264 */ + /* Sarvesh: TBD */ //\/ Sarvesh: Check this +#else /* MPEG4 BRC, else SVA_BRC_H264 */ + pInOut->buffer_fullness_fake_TS = 0; + pInOut->BUFFER_depletion = 0; + pInOut->buffer_saved = 0; +#endif /* End defined(SVA_BRC_H264) */ + +#if defined(SVA_BRC_H264) /* H264 BRC */ + /* Sarvesh: TBD */ //\/ Sarvesh: Check this +#else /* MPEG4 BRC */ + /* define some variable use later*/ + if (pDesc->mp4Conf.flagShortHeader == TRUE) + { + pState->vopTimeIncrementResolution = 30000; + pState->fixedVopTimeIncrement = 1001; + } + else + { + pState->vopTimeIncrementResolution = pDesc->mp4Conf.vopTimeIncrementResolution; + pState->fixedVopTimeIncrement = pDesc->mp4Conf.vopTimeIncrement; + } +#endif /* End defined(SVA_BRC_H264) */ +#if defined(SVA_BRC_H264) /* H264 BRC */ +//\/ deltaTStamp = ((pState->fixedVopTimeIncrement % pState->vopTimeIncrementResolution) * +//\/ (((t_uint32)pState->vopTimeIncrementResolution / pDesc->h264Conf.vopTimeIncrementResolution + ((pState->fixedVopTimeIncrement / pDesc->h264Conf.vopTimeIncrement) >> 1)) / +//\/ (pState->fixedVopTimeIncrement / pDesc->h264Conf.vopTimeIncrement))); +//\/ deltaTStamp = deltaTStamp / pState->fixedVopTimeIncrement; +//\/ bufferDepletion = (deltaTStamp * pBrcParam->bitRate * pState->fixedVopTimeIncrement) / pState->vopTimeIncrementResolution; +#else /* MPEG4 BRC */ + deltaTStamp = (t_uint16)((pState->fixedVopTimeIncrement % pState->vopTimeIncrementResolution) * + (((t_uint32)pState->vopTimeIncrementResolution / pDesc->mp4Conf.vopTimeIncrementResolution + ((pState->fixedVopTimeIncrement / pDesc->mp4Conf.vopTimeIncrement) >> 1)) / + (pState->fixedVopTimeIncrement / pDesc->mp4Conf.vopTimeIncrement))); + deltaTStamp = deltaTStamp / pState->fixedVopTimeIncrement; + bufferDepletion = (deltaTStamp * pBrcParam->bitRate * pState->fixedVopTimeIncrement) / pState->vopTimeIncrementResolution; +#endif /* End defined(SVA_BRC_H264) */ + +#if defined(SVA_BRC_H264) /* H264 BRC */ + /* Sarvesh: TBD */ //\/ Sarvesh: Check this +#else /* MPEG4 BRC */ + /*set to non zero for following part*/ + if (pDesc->mp4Conf.flagShortHeader == TRUE) + { + vopTimeIncrementResolution = 30000; + fixedVopTimeIncrement = 1001; + } + else + { + vopTimeIncrementResolution = pDesc->mp4Conf.vopTimeIncrementResolution; + fixedVopTimeIncrement = pDesc->mp4Conf.vopTimeIncrement; + } +#endif /* End defined(SVA_BRC_H264) */ + pInOut->I_Qp = 16; + pInOut->P_Qp = 16; + pInOut->BPPprev = 64; +#if defined(SVA_BRC_H264) /* H264 BRC */ +//\/ pInOut->ts_modulo_old = -((fixedVopTimeIncrement % vopTimeIncrementResolution) * +//\/ (((t_sint32)vopTimeIncrementResolution / pDesc->h264Conf.vopTimeIncrementResolution + ((fixedVopTimeIncrement / pDesc->h264Conf.vopTimeIncrement) >> 1)) / +//\/ (fixedVopTimeIncrement / pDesc->h264Conf.vopTimeIncrement))); +#else /* MPEG4 BRC */ + pInOut->ts_modulo_old = (t_short_value)-((fixedVopTimeIncrement % vopTimeIncrementResolution) * + (((t_sint32)vopTimeIncrementResolution / pDesc->mp4Conf.vopTimeIncrementResolution + ((fixedVopTimeIncrement / pDesc->mp4Conf.vopTimeIncrement) >> 1)) / + (fixedVopTimeIncrement / pDesc->mp4Conf.vopTimeIncrement))); +#endif /* End defined(SVA_BRC_H264) */ + sva_EC_BRC_ComputeIntraPeriod(instanceNum,pBrcParam->pictureIntraRefresh,&pState->intraPeriod); + pInOut->buffer_fullness = bufferDepletion; + pInOut->bitstream_size = bufferDepletion; + +#if defined(SVA_BRC_H264) /* H264 BRC part ie if SVA_BRC_H264 */ + /* Sarvesh: TBD */ //\/ Sarvesh: Check this +#else /* MPEG4 BRC, else SVA_BRC_H264 */ + pInOut->BUFFER_depletion = bufferDepletion; +#endif /* End defined(SVA_BRC_H264) */ + + return SVA_BRC_OK; +} + +/****************************************************************************/ +/* NAME: t_sva_brc_error sva_EC_BRC_InitVbrBrcStatsPrev( */ +/* t_sva_service_instance_num instanceNum, */ +/* t_uint32 *pBrcStatsPrev */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will be called after encoding of a picture to return */ +/* infos need by brc algorithm. This is for vbr mode. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - instanceNum: number of the descriptor to use. */ +/* */ +/* OUT : */ +/* - pBrcStatsPrev: brc stats to init. */ +/* */ +/* RETURN: */ +/* t_sva_brc_error */ +/* t.b.d */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + +*/ +PRIVATE t_sva_brc_error sva_EC_BRC_InitVbrBrcStatsPrev( + t_sva_service_instance_num instanceNum, + t_uint32 *pBrcStatsPrev +) +{ + t_sva_brc_descriptor *pDesc = &brcDesc[instanceNum]; + t_sva_brc_vbr_state *pState = &pDesc->vbrState; +#if defined(SVA_BRC_H264) /* H264 BRC */ + t_sva_vec_h264_param_inout *pInOut=(t_sva_vec_h264_param_inout *) pBrcStatsPrev; +#else /* MPEG4 BRC */ + t_sva_vec_mpeg4_param_inout *pInOut=(t_sva_vec_mpeg4_param_inout *) pBrcStatsPrev; +#endif /* End defined(SVA_BRC_H264) */ + t_sva_brc_vbr_configuration_params *pBrcParam = &pDesc->brcVbrParam; + t_uint16 vopTimeIncrementResolution; + t_uint16 fixedVopTimeIncrement; + t_uint16 deltaTStamp; + t_uint32 i; + + HCL_DEBUG_ASSERT(pBrcStatsPrev!=NULL); + HCL_DEBUG_ASSERT(pInOut!=NULL); + /*set all stuff to zero*/ + pInOut->bitstream_size = 0; + pInOut->stuffing_bits = 0; + pInOut->pictCount = 0; + pInOut->I_Qp = 0; + pInOut->P_Qp = 0; + pInOut->last_I_Size = 0; + pInOut->comp_SUM = 0; + pInOut->comp_count = 0; + pInOut->BUFFER_mod = 0; + pInOut->ts_modulo_old = 0; + pInOut->ts_seconds_old = 0; + pInOut->gov_flag = 0; + pInOut->avgSAD = 0; + pInOut->seqSAD = 0; + pInOut->min_pict_quality = 0; + pInOut->diff_min_quality = 0; + pInOut->TotSkip = 0; + pInOut->Skip_Current = 0; + pInOut->Cprev = 0; + pInOut->BPPprev = 0; + pInOut->PictQpSum = 0; + pInOut->S_overhead = 0; + pInOut->hec_count = 0; + for(i=0;i<6;i++) {pInOut->ts_vector[i] = 0;} + pInOut->buffer_fullness = 0; + +#if defined(SVA_BRC_H264) /* H264 BRC part ie if SVA_BRC_H264 */ + /* Sarvesh: TBD */ //\/ Sarvesh: Check this +#else /* MPEG4 BRC, else SVA_BRC_H264 */ + pInOut->buffer_fullness_fake_TS = 0; + pInOut->BUFFER_depletion = 0; + pInOut->buffer_saved = 0; +#endif /* End defined(SVA_BRC_H264) */ + +#if defined(SVA_BRC_H264) /* H264 BRC */ + /* Sarvesh: TBD */ //\/ Sarvesh: Check this +#else /* MPEG4 BRC */ + /*set to non zero for following part*/ + if (pDesc->mp4Conf.flagShortHeader == TRUE) + { + vopTimeIncrementResolution = 30000; + fixedVopTimeIncrement = 1001; + } + else + { + vopTimeIncrementResolution = pDesc->mp4Conf.vopTimeIncrementResolution; + fixedVopTimeIncrement = pDesc->mp4Conf.vopTimeIncrement; + } +#endif /* End defined(SVA_BRC_H264) */ + pInOut->I_Qp = 8; + pInOut->P_Qp = 16; + pInOut->min_pict_quality = 0; +#if defined(SVA_BRC_H264) /* H264 BRC */ +//\/ pInOut->ts_modulo_old = -((fixedVopTimeIncrement % vopTimeIncrementResolution) * +//\/ (((t_sint32)vopTimeIncrementResolution / pDesc->h264Conf.vopTimeIncrementResolution + ((fixedVopTimeIncrement / pDesc->h264Conf.vopTimeIncrement) >> 1)) / +//\/ (fixedVopTimeIncrement / pDesc->h264Conf.vopTimeIncrement))); +#else /* MPEG4 BRC */ + pInOut->ts_modulo_old = (t_short_value)-((fixedVopTimeIncrement % vopTimeIncrementResolution) * + (((t_sint32)vopTimeIncrementResolution / pDesc->mp4Conf.vopTimeIncrementResolution + ((fixedVopTimeIncrement / pDesc->mp4Conf.vopTimeIncrement) >> 1)) / + (fixedVopTimeIncrement / pDesc->mp4Conf.vopTimeIncrement))); +#endif /* End defined(SVA_BRC_H264) */ + sva_EC_BRC_ComputeIntraPeriod(instanceNum,pBrcParam->pictureIntraRefresh,&pState->intraPeriod); + deltaTStamp = ((t_sint16)(-pInOut->ts_modulo_old))/(t_sint16)fixedVopTimeIncrement; + +#if defined(SVA_BRC_H264) /* H264 BRC part ie if SVA_BRC_H264 */ + /* Sarvesh: TBD */ //\/ Sarvesh: Check this +#else /* MPEG4 BRC, else SVA_BRC_H264 */ + pInOut->BUFFER_depletion= (deltaTStamp * pBrcParam->bitRate * fixedVopTimeIncrement) / vopTimeIncrementResolution; +#endif /* End defined(SVA_BRC_H264) */ + + return SVA_BRC_OK; +} + +/****************************************************************************/ +/* NAME: t_sva_brc_error sva_EC_BRC_InitCbrBrcStatsPrev( */ +/* t_sva_service_instance_num instanceNum, */ +/* t_uint32 *pBrcStatsPrev */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will be called after encoding of a picture to return */ +/* infos need by brc algorithm. This is for cbr mode. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - instanceNum: number of the descriptor to use. */ +/* */ +/* OUT : */ +/* - pBrcStatsPrev: brc stats to init. */ +/* */ +/* RETURN: */ +/* t_sva_brc_error */ +/* t.b.d */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + +*/ +PRIVATE t_sva_brc_error sva_EC_BRC_InitCbrBrcStatsPrev( + t_sva_service_instance_num instanceNum, + t_uint32 *pBrcStatsPrev +) +{ + t_sva_brc_descriptor *pDesc = &brcDesc[instanceNum]; + t_sva_brc_cbr_state *pState = &pDesc->cbrState; +#if defined(SVA_BRC_H264) /* H264 BRC */ + t_sva_vec_h264_param_inout *pInOut=(t_sva_vec_h264_param_inout *) pBrcStatsPrev; +#else /* MPEG4 BRC */ + t_sva_vec_mpeg4_param_inout *pInOut=(t_sva_vec_mpeg4_param_inout *) pBrcStatsPrev; +#endif /* End defined(SVA_BRC_H264) */ + t_sva_brc_cbr_configuration_params *pBrcParam = &pDesc->brcCbrParam; + t_uint16 vopTimeIncrementResolution; + t_uint16 fixedVopTimeIncrement; + t_uint16 deltaTStamp; + t_uint32 bufferDepletion; + t_uint32 i; + + HCL_DEBUG_ASSERT(pBrcStatsPrev!=NULL); + HCL_DEBUG_ASSERT(pInOut!=NULL); + /*set all stuff to zero*/ + pInOut->bitstream_size = 0; + pInOut->stuffing_bits = 0; + pInOut->pictCount = 0; + pInOut->I_Qp = 0; + pInOut->P_Qp = 0; + pInOut->last_I_Size = 0; + pInOut->comp_SUM = 0; + pInOut->comp_count = 0; + pInOut->BUFFER_mod = 0; + pInOut->ts_modulo_old = 0; + pInOut->ts_seconds_old = 0; + pInOut->gov_flag = 0; + pInOut->avgSAD = 0; + pInOut->seqSAD = 0; + pInOut->min_pict_quality = 0; + pInOut->diff_min_quality = 0; + pInOut->TotSkip = 0; + pInOut->Skip_Current = 0; + pInOut->Cprev = 0; + pInOut->BPPprev = 0; + pInOut->PictQpSum = 0; + pInOut->S_overhead = 0; + pInOut->hec_count = 0; + for(i=0;i<6;i++) {pInOut->ts_vector[i] = 0;} + pInOut->buffer_fullness = 0; + +#if defined(SVA_BRC_H264) /* H264 BRC part ie if SVA_BRC_H264 */ + /* Sarvesh: TBD */ //\/ Sarvesh: Check this +#else /* MPEG4 BRC, else SVA_BRC_H264 */ + pInOut->buffer_fullness_fake_TS = 0; + pInOut->BUFFER_depletion = 0; + pInOut->buffer_saved = 0; +#endif /* End defined(SVA_BRC_H264) */ + +#if defined(SVA_BRC_H264) /* H264 BRC */ + /* Sarvesh: TBD */ //\/ Sarvesh: Check this +#else /* MPEG4 BRC */ + /* define some variable use later*/ + if (pDesc->mp4Conf.flagShortHeader == TRUE) + { + pState->vopTimeIncrementResolution = 30000; + pState->fixedVopTimeIncrement = 1001; + } + else + { + pState->vopTimeIncrementResolution = pDesc->mp4Conf.vopTimeIncrementResolution; + pState->fixedVopTimeIncrement = pDesc->mp4Conf.vopTimeIncrement; + } +#endif /* End defined(SVA_BRC_H264) */ +#if defined(SVA_BRC_H264) /* H264 BRC */ +//\/ deltaTStamp = ((pState->fixedVopTimeIncrement % pState->vopTimeIncrementResolution) * +//\/ (((t_uint32)pState->vopTimeIncrementResolution / pDesc->h264Conf.vopTimeIncrementResolution + ((pState->fixedVopTimeIncrement / pDesc->h264Conf.vopTimeIncrement) >> 1)) / +//\/ (pState->fixedVopTimeIncrement / pDesc->h264Conf.vopTimeIncrement))); +#else /* MPEG4 BRC */ + deltaTStamp = (t_uint16)((pState->fixedVopTimeIncrement % pState->vopTimeIncrementResolution) * + (((t_uint32)pState->vopTimeIncrementResolution / pDesc->mp4Conf.vopTimeIncrementResolution + ((pState->fixedVopTimeIncrement / pDesc->mp4Conf.vopTimeIncrement) >> 1)) / + (pState->fixedVopTimeIncrement / pDesc->mp4Conf.vopTimeIncrement))); +#endif /* End defined(SVA_BRC_H264) */ + deltaTStamp = deltaTStamp / pState->fixedVopTimeIncrement; + bufferDepletion = (deltaTStamp * pBrcParam->bitRate * pState->fixedVopTimeIncrement) / pState->vopTimeIncrementResolution; + +#if defined(SVA_BRC_H264) /* H264 BRC */ + /* Sarvesh: TBD */ //\/ Sarvesh: Check this +#else /* MPEG4 BRC */ + /*set to non zero for following part*/ + if (pDesc->mp4Conf.flagShortHeader == TRUE) + { + vopTimeIncrementResolution = 30000; + fixedVopTimeIncrement = 1001; + } + else + { + vopTimeIncrementResolution = pDesc->mp4Conf.vopTimeIncrementResolution; + fixedVopTimeIncrement = pDesc->mp4Conf.vopTimeIncrement; + } +#endif /* End defined(SVA_BRC_H264) */ + pInOut->I_Qp = 16; + pInOut->P_Qp = 16; + pInOut->BPPprev = 64; +#if defined(SVA_BRC_H264) /* H264 BRC */ +//\/ pInOut->ts_modulo_old = -((fixedVopTimeIncrement % vopTimeIncrementResolution) * +//\/ (((t_sint32)vopTimeIncrementResolution / pDesc->h264Conf.vopTimeIncrementResolution + ((fixedVopTimeIncrement / pDesc->h264Conf.vopTimeIncrement) >> 1)) / +//\/ (fixedVopTimeIncrement / pDesc->h264Conf.vopTimeIncrement))); +#else /* MPEG4 BRC */ + pInOut->ts_modulo_old = (t_short_value)-((fixedVopTimeIncrement % vopTimeIncrementResolution) * + (((t_sint32)vopTimeIncrementResolution / pDesc->mp4Conf.vopTimeIncrementResolution + ((fixedVopTimeIncrement / pDesc->mp4Conf.vopTimeIncrement) >> 1)) / + (fixedVopTimeIncrement / pDesc->mp4Conf.vopTimeIncrement))); +#endif /* End defined(SVA_BRC_H264) */ + sva_EC_BRC_ComputeIntraPeriod(instanceNum,pBrcParam->pictureIntraRefresh,&pState->intraPeriod); + pInOut->buffer_fullness = bufferDepletion; + pInOut->bitstream_size = bufferDepletion; + +#if defined(SVA_BRC_H264) /* H264 BRC part ie if SVA_BRC_H264 */ + /* Sarvesh: TBD */ //\/ Sarvesh: Check this +#else /* MPEG4 BRC, else SVA_BRC_H264 */ + pInOut->BUFFER_depletion = bufferDepletion; +#endif /* End defined(SVA_BRC_H264) */ + + return SVA_BRC_OK; +} + +/****************************************************************************/ +/* NAME: t_sva_brc_error sva_EC_BRC_InitFrameBaseBrcStatsPrev( */ +/* t_sva_service_instance_num instanceNum, */ +/* t_uint32 *pBrcStatsPrev */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will be called after encoding of a picture to return */ +/* infos need by brc algorithm. This is for frame base mode. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - instanceNum: number of the descriptor to use. */ +/* */ +/* OUT : */ +/* - pBrcStatsPrev: brc stats to init. */ +/* */ +/* RETURN: */ +/* t_sva_brc_error */ +/* t.b.d */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + * DONE +*/ +PRIVATE t_sva_brc_error sva_EC_BRC_InitFrameBaseBrcStatsPrev( + t_sva_service_instance_num instanceNum, + t_uint32 *pBrcStatsPrev +) +{ +#if defined(SVA_BRC_H264) /* H264 BRC */ + t_sva_vec_h264_param_inout *pInOut=(t_sva_vec_h264_param_inout *) pBrcStatsPrev; +#else /* MPEG4 BRC */ + t_sva_vec_mpeg4_param_inout *pInOut=(t_sva_vec_mpeg4_param_inout *) pBrcStatsPrev; +#endif /* End defined(SVA_BRC_H264) */ + t_uint32 i; + + HCL_DEBUG_ASSERT(pBrcStatsPrev!=NULL); + HCL_DEBUG_ASSERT(pInOut!=NULL); + + /*init all inout to init value*/ + pInOut->bitstream_size = 0; + pInOut->stuffing_bits = 0; + pInOut->pictCount = 0; + pInOut->I_Qp = 16; + pInOut->P_Qp = 16; + pInOut->last_I_Size = 0; + pInOut->comp_SUM = 0; + pInOut->comp_count = 0; + pInOut->BUFFER_mod = 0; + pInOut->ts_modulo_old = 0; + pInOut->ts_seconds_old = 0; + pInOut->gov_flag = 0; + pInOut->avgSAD = 0; + pInOut->seqSAD = 0; + pInOut->min_pict_quality = 0; + pInOut->diff_min_quality = 0; + pInOut->TotSkip = 0; + pInOut->Skip_Current = 0; + pInOut->Cprev = 0; + pInOut->BPPprev = 64; + pInOut->PictQpSum = 0; + pInOut->S_overhead = 0; + pInOut->hec_count = 0; + for(i=0;i<6;i++) {pInOut->ts_vector[i] = 0;} + pInOut->buffer_fullness = 0; + +#if defined(SVA_BRC_H264) /* H264 BRC part ie if SVA_BRC_H264 */ + /* Sarvesh: TBD */ //\/ Sarvesh: Check this +#else /* MPEG4 BRC, else SVA_BRC_H264 */ + pInOut->buffer_fullness_fake_TS = 0; +#endif /* End defined(SVA_BRC_H264) */ + + + return SVA_BRC_OK; +} + +/****************************************************************************/ +/* NAME: t_sva_ec_algo_error sva_EC_BRC_UpdateQpParams( */ +/* t_sva_service_instance_num instanceNum, */ +/* t_sva_update_cmd_type updateCmdType, */ +/* t_sva_video_encoder_param_id paramId, */ +/* t_uint32 param */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will update Qp brc dynamic parameters */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - instanceNum: number of the descriptor to use. */ +/* - updateCmdType: command to apply to the Brc */ +/* - paramId: Parameter to update */ +/* - param: parameter for the cmdType */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_ec_algo_error */ +/* t.b.d */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + +*/ +PRIVATE t_sva_brc_error sva_EC_BRC_UpdateQpParams( + t_sva_service_instance_num instanceNum, + t_sva_update_cmd_type updateCmdType, + t_sva_video_encoder_param_id paramId, + t_uint32 param +) +{ + t_sva_brc_descriptor *pDesc=&brcDesc[instanceNum]; + t_sva_intra_request *pIntraRequest; + t_sva_brc_error status = SVA_BRC_OK; + + /*update next configuration*/ + switch(paramId) + { + case SVA_ENCODER_PICTURE_INTRA_REFRESH: + pDesc->nextBrcQpParam.pictureIntraRefresh = param; + break; + case SVA_ENCODER_REQUEST_INTRA: + /*macroblock intra refresh is handle in algo code*/ + pIntraRequest = (t_sva_intra_request *) param; + if (pIntraRequest->isIntraFullPicture == TRUE) + { + pDesc->isNextConfRequiredIntraResquest = TRUE; + } + break; + case SVA_ENCODER_BITRATE: + if (pDesc->conf.bufferingModel != SVA_BUFFERING_NONE) + { + pDesc->nextBrcQpParam.bitRate = param; + } + else {status = SVA_BRC_UNKNOWN_CMD_ID;} + break; + default: + status = SVA_BRC_UNKNOWN_CMD_ID; + break; + } + + /*configuration change*/ + switch(updateCmdType) + { + case SVA_UPDATE_MULTIPLE: + /*nothing to do*/ + break; + case SVA_UPDATE_LAST: + pDesc->isFlagIntraRequest = pDesc->isNextConfRequiredIntraResquest; + pDesc->brcQpParam = pDesc->nextBrcQpParam; + break; + case SVA_UPDATE_REVERT: + pDesc->nextBrcQpParam = pDesc->brcQpParam; + pDesc->isNextConfRequiredIntraResquest = FALSE; + break; + default: + break; + } + + return status; +} + +/****************************************************************************/ +/* NAME: t_sva_ec_algo_error sva_EC_BRC_UpdateVbrParams( */ +/* t_sva_service_instance_num instanceNum, */ +/* t_sva_update_cmd_type updateCmdType, */ +/* t_sva_video_encoder_param_id paramId, */ +/* t_uint32 param */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will update vbr brc dynamic parameters */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - instanceNum: number of the descriptor to use. */ +/* - updateCmdType: command to apply to the Brc */ +/* - paramId: Parameter to update */ +/* - param: parameter for the cmdType */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_ec_algo_error */ +/* t.b.d */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + +*/ +PRIVATE t_sva_brc_error sva_EC_BRC_UpdateVbrParams( + t_sva_service_instance_num instanceNum, + t_sva_update_cmd_type updateCmdType, + t_sva_video_encoder_param_id paramId, + t_uint32 param +) +{ + t_sva_brc_descriptor *pDesc=&brcDesc[instanceNum]; + t_sva_brc_vbr_state *pState = &pDesc->vbrState; + t_sva_brc_vbr_configuration_params *pBrcParam = &pDesc->brcVbrParam; + t_sva_intra_request *pIntraRequest; + t_sva_brc_error status = SVA_BRC_OK; + + /*update next configuration*/ + switch(paramId) + { + case SVA_ENCODER_REQUEST_INTRA: + /*macroblock intra refresh is handle in algo code*/ + pIntraRequest = (t_sva_intra_request *) param; + if (pIntraRequest->isIntraFullPicture == TRUE) + { + pDesc->isNextConfRequiredIntraResquest = TRUE; + } + break; + case SVA_ENCODER_BITRATE: + pDesc->nextBrcVbrParam.bitRate = param; + break; + case SVA_ENCODER_FRAME_RATE: + pState->nextFrameRate = (t_uint16) (param << 10); + break; + case SVA_ENCODER_SPATIAL_QUALITY: + pDesc->nextBrcVbrParam.spatialQuality = (t_sva_brc_spatial_quality) param; + break; + case SVA_ENCODER_MIN_FRAME_RATE: + pDesc->nextBrcVbrParam.minFrameRate = param; + break; + case SVA_ENCODER_PICTURE_INTRA_REFRESH: + pDesc->nextBrcVbrParam.pictureIntraRefresh = param; + break; + default: + status = SVA_BRC_UNKNOWN_CMD_ID; + break; + } + + /*configuration change*/ + switch(updateCmdType) + { + case SVA_UPDATE_MULTIPLE: + /*nothing to do*/ + break; + case SVA_UPDATE_LAST: + pState->frameRate = pState->nextFrameRate; + pDesc->isFlagIntraRequest = pDesc->isNextConfRequiredIntraResquest; + pDesc->brcVbrParam = pDesc->nextBrcVbrParam; + pState->minFrameRate = (t_uint16)pDesc->brcVbrParam.minFrameRate << 10; + sva_EC_BRC_ComputeIntraPeriod(instanceNum,pBrcParam->pictureIntraRefresh, &pState->intraPeriod); + break; + case SVA_UPDATE_REVERT: + pState->nextFrameRate = pState->frameRate; + pDesc->isNextConfRequiredIntraResquest = FALSE; + pDesc->nextBrcVbrParam = pDesc->brcVbrParam; + break; + default: + break; + } + + return status; +} + +/****************************************************************************/ +/* NAME: t_sva_ec_algo_error sva_EC_BRC_UpdateCbrParams( */ +/* t_sva_service_instance_num instanceNum, */ +/* t_sva_update_cmd_type updateCmdType, */ +/* t_sva_video_encoder_param_id paramId, */ +/* t_uint32 param */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will update cbr brc dynamic parameters */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - instanceNum: number of the descriptor to use. */ +/* - updateCmdType: command to apply to the Brc */ +/* - paramId: Parameter to update */ +/* - param: parameter for the cmdType */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_ec_algo_error */ +/* t.b.d */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + +*/ +PRIVATE t_sva_brc_error sva_EC_BRC_UpdateCbrParams( + t_sva_service_instance_num instanceNum, + t_sva_update_cmd_type updateCmdType, + t_sva_video_encoder_param_id paramId, + t_uint32 param +) +{ + t_sva_brc_descriptor *pDesc=&brcDesc[instanceNum]; + t_sva_brc_cbr_state *pState = &pDesc->cbrState; + t_sva_brc_cbr_configuration_params *pBrcParam = &pDesc->brcCbrParam; + t_sva_intra_request *pIntraRequest; + t_sva_brc_error status = SVA_BRC_OK; + + /*update next configuration*/ + switch(paramId) + { + case SVA_ENCODER_REQUEST_INTRA: + /*macroblock intra refresh is handle in algo code*/ + pIntraRequest = (t_sva_intra_request *) param; + if (pIntraRequest->isIntraFullPicture == TRUE) + { + pDesc->isNextConfRequiredIntraResquest = TRUE; + } + break; + case SVA_ENCODER_BITRATE: + pDesc->nextBrcCbrParam.bitRate = param; + break; + case SVA_ENCODER_FRAME_RATE: + pState->nextFrameRate = (t_uint16) (param << 10); + break; + case SVA_ENCODER_PICTURE_INTRA_REFRESH: + pDesc->nextBrcCbrParam.pictureIntraRefresh = param; + break; + default: + status = SVA_BRC_UNKNOWN_CMD_ID; + break; + } + + /*configuration change*/ + switch(updateCmdType) + { + case SVA_UPDATE_MULTIPLE: + /*nothing to do*/ + break; + case SVA_UPDATE_LAST: + pState->frameRate = pState->nextFrameRate; + pDesc->isFlagIntraRequest = pDesc->isNextConfRequiredIntraResquest; + pDesc->brcCbrParam = pDesc->nextBrcCbrParam; + sva_EC_BRC_ComputeIntraPeriod(instanceNum,pBrcParam->pictureIntraRefresh, &pState->intraPeriod); + break; + case SVA_UPDATE_REVERT: + pState->nextFrameRate = pState->frameRate; + pDesc->isNextConfRequiredIntraResquest = FALSE; + pDesc->nextBrcCbrParam = pDesc->brcCbrParam; + break; + default: + break; + } + + return status; +} + +/****************************************************************************/ +/* NAME: t_sva_ec_algo_error sva_EC_BRC_UpdateFrameBaseParams( */ +/* t_sva_service_instance_num instanceNum, */ +/* t_sva_update_cmd_type updateCmdType, */ +/* t_sva_video_encoder_param_id paramId, */ +/* t_uint32 param */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will update frame base brc dynamic parameters */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - instanceNum: number of the descriptor to use. */ +/* - updateCmdType: command to apply to the Brc */ +/* - paramId: Parameter to update */ +/* - param: parameter for the cmdType */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_ec_algo_error */ +/* t.b.d */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + * DONE +*/ +PRIVATE t_sva_brc_error sva_EC_BRC_UpdateFrameBaseParams( + t_sva_service_instance_num instanceNum, + t_sva_update_cmd_type updateCmdType, + t_sva_video_encoder_param_id paramId, + t_uint32 param +) +{ + return SVA_BRC_UNKNOWN_CMD_ID; +} + +/****************************************************************************/ +/* NAME: t_sva_fw_features sva_EC_BRC_GetFeatures( */ +/* t_sva_service_instance_num instanceNum */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will return features need by brc algorithm. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - instanceNum: number of the descriptor to use. */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_fw_features */ +/* return features need by BRC algorithm. */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_sva_fw_features sva_EC_BRC_GetFeatures( + t_sva_service_instance_num instanceNum +) +{ + t_sva_brc_descriptor *pDesc=&brcDesc[instanceNum]; + t_sva_fw_features res = SVA_FW_FEAT_NONE; + + switch(pDesc->conf.brcMode) + { + case SVA_QP_CONSTANT: +//\/ res = SVA_FW_FEAT_ENCODER_CONSTANT_QP; + break; + case SVA_FRAME_BASE: + res = SVA_FW_FEAT_ENCODER_FRAME_BY_FRAME; + break; + case SVA_CBR: + res = SVA_FW_FEAT_ENCODER_CBR; + break; + case SVA_VBR: + res = SVA_FW_FEAT_ENCODER_VBR; + break; + default: + break; + } + + return res; +} + +/****************************************************************************/ +/* NAME: t_uint32 sva_EC_BRC_GetVbvOccupancy( */ +/* t_sva_service_instance_num instanceNum, */ +/* t_sint32 bufferLevel, */ +/* t_size prevPictureSizeInBits */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will return features need by brc algorithm. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - instanceNum: number of the descriptor to use. */ +/* - bufferLevel: bufferLevel that need to be corrected by prevPictureSize */ +/* - prevPictureSizeInBits: prev picture size in bits */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_uint32 */ +/* return vbvOccupancy to put in vol header */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_uint32 sva_EC_BRC_GetVbvOccupancy( + t_sva_service_instance_num instanceNum, + t_sint32 bufferLevel, + t_size prevPictureSizeInBits +) +{ + t_sva_brc_descriptor *pDesc=&brcDesc[instanceNum]; + t_uint32 vbvOccupancy; + t_uint32 initialVbvOccupancy; + + /* get initial vbvOccupancy provide by users*/ + switch(pDesc->conf.brcMode) + { + case SVA_CBR: + { + t_sva_brc_cbr_configuration_params *pBrcParam = &pDesc->brcCbrParam; + + initialVbvOccupancy = pBrcParam->vbvOccupancy; + } + break; + case SVA_VBR: + { + t_sva_brc_vbr_configuration_params *pBrcParam = &pDesc->brcVbrParam; + + initialVbvOccupancy = pBrcParam->vbvOccupancy; + } + break; + case SVA_QP_CONSTANT: + /* This part will only be call when buffering model != SVA_BUFFERING_NONE */ + { + t_sva_brc_qpConstant_configuration_params *pBrcParam = &pDesc->brcQpParam; + + initialVbvOccupancy = pBrcParam->vbvOccupancy; + } + break; + default: + initialVbvOccupancy = 0; + break; + } + + /* compute vbvOccupancy to put in vol header*/ + bufferLevel += prevPictureSizeInBits; + if (bufferLevel < 0) {bufferLevel = 0;} + vbvOccupancy = (initialVbvOccupancy - bufferLevel) >> 6; + + return vbvOccupancy; +} + +/****************************************************************************/ +/* NAME: t_bool sva_EC_BRC_IsPreviousPictureWasStrategicSkip( */ +/* t_sva_service_instance_num instanceNum */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will return true if picture n-1 was strategic skipped */ +/* else it will return false. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - instanceNum: number of the descriptor to use. */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_bool */ +/* TRUE : picture n-1 was strategic skipped. */ +/* FALSE : picture n-1 was not strategic skipped. */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_bool sva_EC_BRC_IsPreviousPictureWasStrategicSkip( + t_sva_service_instance_num instanceNum +) +{ + t_sva_brc_descriptor *pDesc=&brcDesc[instanceNum]; + t_bool res; + + switch(pDesc->conf.brcMode) + { + case SVA_CBR: + res = sva_EC_BRC_IsPreviousPictureWasStrategicSkipCbr(instanceNum); + break; + case SVA_QP_CONSTANT: + if (pDesc->conf.bufferingModel == SVA_BUFFERING_HRD) + { + res = sva_EC_BRC_IsPreviousPictureWasStrategicSkipQpConstantHrd(instanceNum); + } + else {res = FALSE;} + break; + default: + res = FALSE; + break; + } + + return res; +} + +/****************************************************************************/ +/* NAME: t_sva_ec_algo_error sva_EC_BRC_ComputeIntraPeriod( */ +/* t_sva_service_instance_num instanceNum, */ +/* t_uint32 pictureIntraRefresh */ +/* t_uint32 *pIntraPeriod */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will compute intra period in the correct unit */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - instanceNum: number of the descriptor to use. */ +/* - pictureIntraRefresh: number of P between two I */ +/* */ +/* OUT : */ +/* - pIntraPeriod: Intra period in correct units */ +/* */ +/* RETURN: */ +/* t_sva_ec_algo_error */ +/* t.b.d */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PRIVATE t_sva_brc_error sva_EC_BRC_ComputeIntraPeriod( + t_sva_service_instance_num instanceNum, + t_uint32 pictureIntraRefresh, + t_uint32 *pIntraPeriod +) +{ + t_sva_brc_descriptor *pDesc = &brcDesc[instanceNum]; + t_uint32 ticksBetweenTwoPic; + t_uint16 vopTimeIncrementResolution; + t_uint16 fixedVopTimeIncrement; + + /*set vopTimeIncrementResolution and fixedVopTimeIncrement according to algo*/ + +#if defined(SVA_BRC_H264) /* H264 BRC */ + /* Sarvesh: TBD */ //\/ Sarvesh: Check this +#else /* MPEG4 BRC */ + if (pDesc->mp4Conf.flagShortHeader == TRUE) + { + vopTimeIncrementResolution = 30000; + fixedVopTimeIncrement = 1001; + } + else + { + vopTimeIncrementResolution = pDesc->mp4Conf.vopTimeIncrementResolution; + fixedVopTimeIncrement = pDesc->mp4Conf.vopTimeIncrement; + } +#endif /* End defined(SVA_BRC_H264) */ + +#if defined(SVA_BRC_H264) /* H264 BRC */ + /*compute intra period*/ +//\/ ticksBetweenTwoPic = ((fixedVopTimeIncrement % vopTimeIncrementResolution) * +//\/ (((t_uint32)vopTimeIncrementResolution / pDesc->h264Conf.vopTimeIncrementResolution + ((fixedVopTimeIncrement / pDesc->h264Conf.vopTimeIncrement) >> 1)) / +//\/ (fixedVopTimeIncrement / pDesc->h264Conf.vopTimeIncrement))); +#else /* MPEG4 BRC */ + /*compute intra period*/ + ticksBetweenTwoPic = ((fixedVopTimeIncrement % vopTimeIncrementResolution) * + (((t_uint32)vopTimeIncrementResolution / pDesc->mp4Conf.vopTimeIncrementResolution + ((fixedVopTimeIncrement / pDesc->mp4Conf.vopTimeIncrement) >> 1)) / + (fixedVopTimeIncrement / pDesc->mp4Conf.vopTimeIncrement))); +#endif /* End defined(SVA_BRC_H264) */ + if (pictureIntraRefresh == 0xffffffff) + { + *pIntraPeriod = 0x7fffffff; + } + else + { + *pIntraPeriod = pictureIntraRefresh * ticksBetweenTwoPic; + } + + return SVA_BRC_OK; +} + +/****************************************************************************/ +/* NAME: t_uint32 sva_EC_BRC_MaxVopSize( */ +/* t_uint32 mbNum */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will compute max allowed vop size in bytes */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - mbNum: number of macroblock for picture */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_uint32 */ +/* maximal size of vop in bits ? */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PRIVATE t_uint32 sva_EC_BRC_MaxVopSize( + t_uint32 mbNum +) +{ + t_uint32 res; + + if (mbNum <= 99) {res = 64 * ONE_KB;} + else if (mbNum <= 396) {res = 256 * ONE_KB;} + else if (mbNum <= 1584) {res = 512 * ONE_KB;} + else {res = 1024 * ONE_KB;} + + return res; +} + +/****************************************************************************/ +/* NAME: t_bool sva_EC_BRC_IsPreviousPictureWasStrategicSkipCbr( */ +/* t_sva_service_instance_num instanceNum */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will return true if picture n-1 was strategic skipped */ +/* else it will return false. */ +/* This routine is for CBR only. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - instanceNum: number of the descriptor to use. */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_bool */ +/* TRUE : picture n-1 was strategic skipped. */ +/* FALSE : picture n-1 was not strategic skipped. */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PRIVATE t_bool sva_EC_BRC_IsPreviousPictureWasStrategicSkipCbr( + t_sva_service_instance_num instanceNum +) +{ + t_sva_brc_descriptor *pDesc = &brcDesc[instanceNum]; + t_sva_brc_cbr_state *pState = &pDesc->cbrState; + t_uint32 buffer=0; + buffer = buffer;/*For removing compiler warning*/ + + if (pState->pictureCounter == 0) {return FALSE;} + else + { + t_sva_brc_eot_data *pEotDataNMinus2 = &pDesc->eotFifo.eotData[1-(pState->pictureCounter%2)]; + + /* compute buffer level*/ + if (pEotDataNMinus2->skipPrev == 1 || + pState->prevStrategicSkip == 1) + { + buffer = BRCMAX((t_sint32) pState->buffer - (t_sint32) pState->bufferDepletion,0); + } + else + { + buffer = BRCMAX((t_sint32) pState->buffer + (t_sint32) pEotDataNMinus2->bitstreamSizeInBits - (t_sint32) pState->bufferDepletion,0); + } +#if defined(SVA_BRC_H264) /* H264 BRC */ + /* Sarvesh: TBD */ //\/ Sarvesh: Check this +#else /* MPEG4 BRC */ + /* handle partly optimal time stamp case */ + if (pDesc->mp4Conf.flagShortHeader == FALSE) + { + if (pState->prevPictureCodingType == SVA_BRC_P_PICTURE && pState->prevStrategicSkip == 0 && + pState->govFlag == 0) + { + buffer = BRCMAX((t_sint32)pState->bufferFakeTs + (t_sint32) pEotDataNMinus2->bitstreamSizeInBits - (t_sint32) pState->bufferDepletion,0); + } + } +#endif /* End defined(SVA_BRC_H264) */ + +#define SVA_ENABLE_BRC_HCL_WORKAROUND_VI10315 +#if defined(SVA_ENABLE_BRC_HCL_WORKAROUND_VI10315) /* Sarvesh: Temporary HCL workaround for parsing error, VI10315 */ + /* Always return FALSE i.e. No frame is skipped, even if skipped return FALSE */ + return FALSE; +#else /* else of #if SVA_ENABLE_BRC_HCL_WORKAROUND_VI10315 */ + /* check if previous picture has been strategic skipped */ + if (buffer > (t_sint32) pState->picTarget) {return TRUE;} + else {return FALSE;} +#endif /* endif of #if SVA_ENABLE_BRC_HCL_WORKAROUND_VI10315 */ + } +} + +/****************************************************************************/ +/* NAME: t_bool sva_EC_BRC_IsPreviousPictureWasStrategicSkipQpConstantHrd( */ +/* t_sva_service_instance_num instanceNum */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will return true if picture n-1 was strategic skipped */ +/* else it will return false. */ +/* This routine is for Qp constant when buffering model is HRD only. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - instanceNum: number of the descriptor to use. */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_bool */ +/* TRUE : picture n-1 was strategic skipped. */ +/* FALSE : picture n-1 was not strategic skipped. */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PRIVATE t_bool sva_EC_BRC_IsPreviousPictureWasStrategicSkipQpConstantHrd( + t_sva_service_instance_num instanceNum +) +{ + t_sva_brc_descriptor *pDesc = &brcDesc[instanceNum]; + t_sva_brc_qpConstant_state *pState = &pDesc->qpConstantState; + t_uint32 buffer; + + if (pState->pictureCounter == 0) {return FALSE;} + else + { + t_sva_brc_eot_data *pEotDataNMinus2 = &pDesc->eotFifo.eotData[1-(pState->pictureCounter%2)]; + + /* compute buffer level*/ + if (pEotDataNMinus2->skipPrev == 1 || + pState->prevStrategicSkip == 1) + { + buffer = BRCMAX((t_sint32) pState->buffer - (t_sint32) pState->bufferDepletion,0); + } + else + { + buffer = BRCMAX((t_sint32) pState->buffer + (t_sint32) pEotDataNMinus2->bitstreamSizeInBits - (t_sint32) pState->bufferDepletion,0); + } + + /* check if previous picture has been strategic skipped*/ + if (buffer > pState->picTarget) {return TRUE;} + else {return FALSE;} + } +} + + /* End of file - sva_brc.c */ --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/encode/brc/sva_brc.h @@ -0,0 +1,112 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ + +#ifndef __INC_SVA_BRC_H +#define __INC_SVA_BRC_H + +#include "hcl_defs.h" +#include "sva.h" +#include "../sva_encode.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/******************************************************************************/ +/* Constants definitions */ +/******************************************************************************/ + +/******************************************************************************/ +/* Types definitions */ +/******************************************************************************/ +/* + * Define the symbols used to identify the various errors of the Brc Module + */ +typedef enum { + SVA_BRC_UNKNOWN_CMD_ID, + SVA_BRC_INVALID_INSTANCE_NB, + SVA_BRC_NOT_SUPPORTED, + SVA_BRC_OK = HCL_OK +} t_sva_brc_error; + +/* + * Define output of brc. These data will be use to fill param_in structures + */ +typedef struct { + /*define directly in param in*/ + t_uint16 pictureCodingType; + t_uint16 quant; + t_uint16 brcType; + t_uint32 brcFrameTarget; + t_uint32 brcTargetMinPred; + t_uint32 brcTargetMaxPred; + t_uint32 skipCount; + t_uint32 bitRate; + t_uint16 frameRate; + t_sint32 deltaTarget; + t_uint16 minQp; + t_uint16 maxQp; + t_uint16 vopTimeIncrementResolution; + t_uint16 fixedVopTimeIncrement; + t_uint32 smax; + t_uint16 minBaseQuality; + t_uint16 minFrameRate; + t_uint32 maxBuffLevel; + t_uint32 tsSeconds; + t_uint32 tsModulo; + t_uint16 firstISkippedFlag; + t_sint16 initTsModuloOld; + /*data need by algo part for header writing*/ + t_uint32 vbvBufferSizeIn16384BitsUnit; + t_sint32 bufferSizeForVbv; +} t_sva_brc_out; + +/* + * Define input of brc. These data will be use to finish a picture brc update + */ +typedef struct { + /*bitstream size info*/ + t_uint32 bitstreamSize; + t_uint32 stuffingBits; + /*skipping info*/ + t_uint16 brcSkipPrev; + t_uint32 skipCurrent; +} t_sva_brc_in; + +/******************************************************************************* +* PUBLIC Functions +*******************************************************************************/ +PUBLIC t_sva_brc_error sva_EC_BRC_Init(t_sva_service_instance_num , const t_sva_video_encoder_configuration *); +PUBLIC t_sva_brc_error sva_EC_BRC_GetInternalNeeds(t_sva_service_instance_num, t_size *); +PUBLIC t_sva_brc_error sva_EC_BRC_ProvideMemoryNeeds(t_sva_service_instance_num); +PUBLIC t_sva_brc_error sva_EC_BRC_EncodeAlgoDelete(t_sva_service_instance_num); +PUBLIC t_sva_brc_error sva_EC_BRC_InitPicture(t_sva_service_instance_num,t_sva_brc_user_request,t_sva_timestamp_value,t_sva_brc_out *,t_bool *); +PUBLIC t_sva_brc_error sva_EC_BRC_FinishPicture(t_sva_service_instance_num,t_sva_brc_in *); +PUBLIC t_sva_brc_error sva_EC_BRC_InitBrcStatsPrev(t_sva_service_instance_num,t_uint32 *); +PUBLIC t_sva_brc_error sva_EC_BRC_UpdateBrcParams(t_sva_service_instance_num, t_sva_update_cmd_type, t_sva_video_encoder_param_id, t_uint32); +PUBLIC t_sva_fw_features sva_EC_BRC_GetFeatures(t_sva_service_instance_num); +PUBLIC t_uint32 sva_EC_BRC_GetVbvOccupancy(t_sva_service_instance_num ,t_sint32 , t_size); +PUBLIC t_bool sva_EC_BRC_IsPreviousPictureWasStrategicSkip(t_sva_service_instance_num); + +#ifdef __cplusplus +} /* allow C++ to use these headers */ +#endif /* __cplusplus */ + +#endif /* __INC_SVA_BRC_H */ +/* End of file - sva_brc.h */ --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/encode/brc/sva_brcp.h @@ -0,0 +1,262 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ + +#ifndef __INC_SVA_BRCP_H +#define __INC_SVA_BRCP_H + +#include "hcl_defs.h" +#include "sva.h" +#include "sva_encode.h" +#include "../sva_ec_algo.h" +#include "sva_brc.h" + +/******************************************************************************/ +/* Constants definitions */ +/******************************************************************************/ +/* + * Define BRCMIN / BRCMAX macro + */ +#define BRCMIN(a,b) (((a)<(b))?a:b) +#define BRCMAX(a,b) (((a)>(b))?a:b) + +/* + * Define the maximum number of brc structure to maintain + */ +#define NUM_MAX_BRC 4 + +/* + * Define params range to check when in qp constant mode + */ +#define SVA_BRC_QP_I_MIN 2 +#define SVA_BRC_QP_I_MAX 31 +#define SVA_BRC_QP_P_MIN 2 +#define SVA_BRC_QP_P_MAX 31 + +/* + * Define value for picture type + */ +#define SVA_BRC_I_PICTURE 0 +#define SVA_BRC_P_PICTURE 1 + +/* + * Define value brc type + */ +#define SVA_BRC_QP_BUFFERING_NONE 0 +#define SVA_BRC_FRAME_BASE 1 +#define SVA_BRC_CBR 2 +#define SVA_BRC_VBR 3 +#define SVA_BRC_QP_CONSTANT_VBV_ANNEX_G 4 +#define SVA_BRC_QP_CONSTANT_HRD 6 + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ +/******************************************************************************/ +/* Types definitions */ +/******************************************************************************/ +/* + * Define data save on an EOT + */ +typedef struct { + t_uint32 bitstreamSizeInBits; + t_sint32 bufferFullness; + t_uint32 skipPrev; + t_uint32 skipCurrent; +} t_sva_brc_eot_data; + +/* + * Define eot fifo to have a similar behaviour as in ref model + */ +typedef struct { + t_uint32 ptrWrite; + t_sva_brc_eot_data eotData[2]; +} t_sva_brc_eot_fifo; + +/* + * Define the structure to handle vbr algorithm + */ +typedef struct { + /* hcl vbr variable */ + t_uint32 pictureCounter; + t_sva_timestamp_value prevPts; + t_uint32 skipCount[2]; /*need to handle already program subtask without know prev was skipped*/ + t_uint32 pictureCodingType[2]; /*need to handle already program subtask without know prev was skipped*/ + t_uint32 brcTargetMinPred[2]; /*need to handle already program subtask without know prev was skipped*/ + t_uint32 ptsCor; /*need to handle pts correction when first pictures skipped*/ + t_uint32 skipPrevCount; /*need to handle pts correction when first pictures skipped*/ + + t_sva_brc_out saveBrcOut; + + /* reference model variable */ + t_uint16 frameRate; /*compute at init. avoid duplicate calculation*/ + t_uint16 vopTimeIncrementResolution; /*compute at init. avoid duplicate calculation*/ + t_uint16 fixedVopTimeIncrement; /*compute at init. avoid duplicate calculation*/ + t_uint32 sMax; /*could be remove : always pBrcParam->swissBuffer*/ + t_uint16 minBaseQuality; /*compute at init. avoid duplicate calculation. Dyn param in HCL ?*/ + t_uint16 minFrameRate; /*compute at init. avoid duplicate calculation*/ + t_uint32 picTarget; /*compute at init. avoid duplicate calculation. Dyn param in HCL ?*/ + t_uint32 targetBuffLevel; /*compute at init. avoid duplicate calculation*/ + t_uint32 buffer; /* need to keep state*/ + t_uint32 prevBuffer; /*could be remove : could be local in postPic*/ + t_uint16 bufferMod; /* need to keep state*/ + t_uint32 bufferDepletion; /* need to keep state*/ + t_sint16 prevVopTimeIncrement; /* need to keep state*/ + t_uint16 oldModuloTimeBase; /* need to keep state*/ + t_uint32 maxBufferLevel; /* could be remove*/ + t_uint32 deltaTicks; /* need to keep state*/ + t_uint32 intraPeriod; /*compute at init. avoid duplicate calculation*/ + t_sint16 initTsModuloOld; /*init ts value. Negative value.*/ + + /* variable need to handle dynamic command*/ + t_uint16 nextFrameRate; + + /* GT: Dynamic Bitrate 05/05/2006 */ + t_uint32 bitRateDelayed; + + t_uint32 deltaTimeStamp; + +} t_sva_brc_vbr_state; + +typedef struct { + /* hcl cbr variable */ + t_uint32 pictureCounter; + t_sva_timestamp_value prevPts; + t_uint32 skipCount[2]; /*need to handle already program subtask without know prev was skipped*/ + t_uint32 pictureCodingType[2]; /*need to handle already program subtask without know prev was skipped*/ + + t_uint32 brcTargetMinPred[2]; /*need to handle already program subtask without know prev was skipped*/ + t_uint32 govFlag; + t_uint32 prevPictureCodingType; + /* stuff to handle partly optimal time stamp (main part)*/ + t_uint32 fakeFlag; + t_uint32 ptsDiff; + + t_sva_brc_out saveBrcOut; + /* reference model variable */ + t_uint16 frameRate; /*compute at init. avoid duplicate calculation*/ + t_uint16 vopTimeIncrementResolution; /*compute at init. avoid duplicate calculation*/ + t_uint16 fixedVopTimeIncrement; /*compute at init. avoid duplicate calculation*/ + t_uint32 sMax; /*could be remove : always pBrcParam->swissBuffer*/ + t_uint32 picTarget; /*compute at init. avoid duplicate calculation. Dyn param in HCL ?*/ + t_uint32 targetBuffLevel; /*compute at init. avoid duplicate calculation*/ + t_uint32 buffer; /* need to keep state*/ + t_uint32 bufferFakeTs; /* need when parly optimal time stamp management active */ + t_uint32 prevBuffer; /*could be remove : could be local in postPic*/ + t_uint16 bufferMod; /* need to keep state*/ + t_uint32 bufferDepletion; /* need to keep state*/ + t_sint16 prevVopTimeIncrement; /* need to keep state*/ + t_uint16 oldModuloTimeBase; /* need to keep state*/ + t_uint32 maxBufferLevel; /* could be remove*/ + t_uint32 deltaTicks; /* need to keep state*/ + t_uint32 intraPeriod; /*compute at init. avoid duplicate calculation*/ + t_uint16 prevStrategicSkip; /* indicate if picture n-1 has been strategic skip*/ + t_sint16 initTsModuloOld; /**/ + + /* variable need to handle dynamic command*/ + t_uint16 nextFrameRate; + + /* GT: Dynamic Bitrate 05/05/2006 */ + t_uint32 bitRateDelayed; + + t_uint32 deltaTimeStamp; + +} t_sva_brc_cbr_state; + +typedef struct { + /* hcl cbr variable */ + t_uint32 pictureCounter; + t_sva_timestamp_value prevPts; + t_uint32 skipCount[2]; /*need to handle already program subtask without know prev was skipped*/ + t_uint32 pictureCodingType[2]; /*need to handle already program subtask without know prev was skipped*/ + + t_uint32 brcTargetMinPred[2]; /*need to handle already program subtask without know prev was skipped*/ + t_uint32 ptsCor; /*need to handle pts correction when first pictures skipped*/ + t_uint32 skipPrevCount; /*need to handle pts correction when first pictures skipped*/ + + t_sva_brc_out saveBrcOut; + /* reference model variable */ + t_uint16 frameRate; /*compute at init. avoid duplicate calculation*/ + t_uint16 vopTimeIncrementResolution; /*compute at init. avoid duplicate calculation*/ + t_uint16 fixedVopTimeIncrement; /*compute at init. avoid duplicate calculation*/ + t_uint32 sMax; /*could be remove : always pBrcParam->swissBuffer*/ + t_uint32 picTarget; /*compute at init. avoid duplicate calculation. Dyn param in HCL ?*/ + t_uint32 targetBuffLevel; /*compute at init. avoid duplicate calculation*/ + t_uint32 buffer; /* need to keep state*/ + t_uint32 prevBuffer; /*could be remove : could be local in postPic*/ + t_uint16 bufferMod; /* need to keep state*/ + t_uint32 bufferDepletion; /* need to keep state*/ + t_sint16 prevVopTimeIncrement; /* need to keep state*/ + t_uint16 oldModuloTimeBase; /* need to keep state*/ + t_uint32 maxBufferLevel; /* could be remove*/ + t_uint32 deltaTicks; /* need to keep state*/ + t_uint32 intraPeriod; /*compute at init. avoid duplicate calculation*/ + t_uint16 prevStrategicSkip; /* indicate if picture n-1 has been strategic skip*/ + t_sint16 initTsModuloOld; /*init ts value. Negative value.*/ + + /* variable need to handle dynamic command*/ + t_uint16 nextFrameRate; + + /* GT: Dynamic Bitrate 05/05/2006 */ + t_uint32 bitRateDelayed; + + t_uint32 deltaTimeStamp; + +} t_sva_brc_qpConstant_state; + +/* + * Define the descriptor of a brc instance + */ +typedef struct { + t_sva_video_encoder_configuration conf; +#if defined(SVA_BRC_H264) /* H264 BRC */ + /*need to store H264 conf !!!!*/ + + t_sva_video_encoder_algo_h264_configuration_params h264Conf; +#else /* MPEG4 BRC */ + /*need to store mpeg4 conf !!!!*/ + + t_sva_video_encoder_algo_mpeg4_configuration_params mp4Conf; +#endif /* End defined(SVA_BRC_H264) */ + /*common stuff*/ + t_sva_brc_eot_fifo eotFifo; + /*qp constant stuff*/ + t_sva_brc_qpConstant_configuration_params brcQpParam; + t_sva_brc_qpConstant_configuration_params nextBrcQpParam; + t_sva_brc_qpConstant_state qpConstantState; + /*vbr stuff*/ + t_sva_brc_vbr_configuration_params brcVbrParam; + t_sva_brc_vbr_configuration_params nextBrcVbrParam; + t_sva_brc_vbr_state vbrState; + /*cbr stuff*/ + t_sva_brc_cbr_configuration_params brcCbrParam; + t_sva_brc_cbr_configuration_params nextBrcCbrParam; + t_sva_brc_cbr_state cbrState; + /*frame base stuff*/ + /*nothing*/ + /*stuff to handle force picture intra refresh*/ + t_bool isNextConfRequiredIntraResquest; + t_bool isFlagIntraRequest; +} t_sva_brc_descriptor; + +#ifdef __cplusplus +} /* allow C++ to use these headers */ +#endif /* __cplusplus */ + +#endif /* __INC_SVA_BRCP_H */ +/* End of file - sva_brcp.h */ --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/encode/h264/sva_ec_h264.c @@ -0,0 +1,4739 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ + +/*------------------------------------------------------------------------ + * Includes + *----------------------------------------------------------------------*/ +#include "hcl_defs.h" +#include "sva_host_interface.h" +#include "sva_buffermgt.h" +#include "sva_fifo.h" +#include "sva_encode.h" + +#include "sva_ec_algo.h" +#include "sva_ec_h264.h" + +#include "sva_ec_h264p.h" + +/*------------------------------------------------------------------------ + * Global Variables + *----------------------------------------------------------------------*/ +PRIVATE t_sva_ec_h264_descriptor h264EncodeDesc[NUM_MAX_H264_ENCODE]; +//\/PRIVATE t_NALU nal_unit;//\/ +//\/PRIVATE t_uint8 nal_unit_buff[MAX_NALU_BUFF_SIZE];//\/ + +t_sint16 log2_max_frame_num_minus4; +t_sint16 log2_max_pic_order_cnt_lsb_minus4; +//\/t_uint32 NALAUsize = 0; /* NZ: size of whole access unit */ +//\/t_uint32 VCLAUsize = 0; /* NZ: size of all VCL NALU in the AU*/ +//\/t_uint16 firstAU = 1; /* NZ: flag to signal the first AU */ +#if 1 //\/ code added by sarvesh + /* These globals are added to access idr_flag and IntraForced config * + * parameter in sva_EC_H264_EncodeOneFrame from sva_EC_H264_AlgoInit * + * as pH264Conf is inaccessible in sva_EC_H264_EncodeOneFrame */ +//\/ t_sint32 g_idr_flag; /* Global saved Encode intra slices as IDR */ +//\/ t_sint32 g_IntraForced; /* Global force an Intra at this frame */ +//\/ t_sint32 g_SeinitialQP; +#endif //\/end of #if 1 //\/ code added by sarvesh + +/*********************************** Start: Code added for migration to MAINVER1.2 ***********************************/ +//\/t_uint8 rbsp[NONVCL_BUFFER_SIZE]; /* NZ: statically alloc'ed buffer for non-VCL NAL unit */ +t_uint8 rbsp[NONVCL_BUFFER_SIZE]; /* NZ: statically alloc'ed buffer for non-VCL NAL unit EXCEPT Filled Data NAL Units */ +const t_uint32 LevelLimits[16][6] = { + { 10, 1485, 99, 64, 175, 2}, /* 1.0 [0] */ + {101, 1485, 99, 128, 350, 2}, /* 1.0b [1] */ + { 11, 3000, 396, 192, 500, 2}, /* 1.1 [2] */ + { 12, 6000, 396, 384, 1000, 2}, /* 1.2 [3] */ + { 13, 11880, 396, 768, 2000, 2}, /* 1.3 [4] */ + { 20, 11880, 396, 2000, 2000, 2}, /* 2.0 [5] */ + { 21, 19800, 792, 4000, 4000, 2}, /* 2.1 [6] */ + { 22, 20250, 1620, 4000, 4000, 2}, /* 2.2 [7] */ + { 30, 40500, 1620, 10000, 10000, 2}, /* 3.0 [8] */ + { 31, 108000, 3600, 14000, 14000, 4}, /* 3.1 [9] */ + { 32, 216000, 5120, 20000, 20000, 4}, /* 3.2 [10] */ + { 40, 245760, 8192, 20000, 25000, 4}, /* 4.0 [11] */ + { 41, 245760, 8192, 50000, 62500, 2}, /* 4.1 [12] */ + { 42, 522240, 8704, 50000, 62500, 2}, /* 4.2 [13] */ + { 50, 589824, 22080, 135000, 135000, 2}, /* 5.0 [14] */ + { 51, 983040, 36864, 240000, 240000, 2} /* 5.1 [15] */ +}; +t_uint32 g_bit_rate_val; +#define SVA_EC_H264_TEMP_NO_FRAMES_VAL 10 +/************************************ End: Code added for migration to MAINVER1.2 ************************************/ + +/*------------------------------------------------------------------------ + * Private functions + *----------------------------------------------------------------------*/ +PRIVATE t_sva_ec_algo_error sva_EC_H264_ResetDescriptor(t_sva_ec_h264_descriptor *); +PRIVATE t_bool sva_EC_H264_IsConfigurationValid(const t_sva_video_encoder_configuration *); +PRIVATE t_sva_ec_algo_error sva_EC_H264_ANNEXB_GetNextFrameParamIn + ( + t_sva_service_instance_num, + t_sva_ec_algo_params_in * + ); +PRIVATE t_sva_ec_algo_error sva_EC_H264_ANNEXB_GetNextHeader + ( + t_sva_service_instance_num, + t_sva_ec_algo_header *, + t_size * + ); +PRIVATE t_size sva_EC_H264_ANNEXB_GetMaxHeaderSize(t_sva_service_instance_num); +PRIVATE t_sva_ec_algo_error sva_EC_H264_ANNEXB_UpdateVideoEncoderParams + ( + t_sva_service_instance_num, + t_sva_update_cmd_type, + t_sva_video_encoder_param_id, + t_uint32 + ); +PRIVATE t_sva_ec_algo_error sva_EC_H264_GetH4DSize(t_sva_service_instance_num , t_size* ); + +/*********************************** Start: Code added for migration to MAINVER1.2 ***********************************/ +t_sint32 WriteAnnexbNALU (t_p_NALU p_nalu, t_sva_data_unit_buffer *pOutBuf); +t_sint32 CopyAnnexbNALU (t_p_NALU p_nalu, t_sva_data_unit_buffer *pOutBuf); +t_uint32 WriteSPS(t_sva_service_instance_num instanceNum, t_sva_data_unit_buffer *pOutBuf); +t_uint32 WritePPS(t_sva_service_instance_num instanceNum, t_sva_data_unit_buffer *pOutBuf); +t_uint32 WriteNALU (t_sva_service_instance_num instanceNum, t_NALUflavour flavour, t_p_NALU p_nalu, t_sva_data_unit_buffer *pOutBuf); +//\/void GenerateSeq_parameter_set_NALU (t_sva_service_instance_num instanceNum, t_NALU * nalu); +void GenerateSeq_parameter_set_NALU (t_sva_service_instance_num instanceNum, t_p_NALU nalu); +//\/void GeneratePic_parameter_set_NALU (t_sva_service_instance_num instanceNum, t_NALU * nalu); +void GeneratePic_parameter_set_NALU (t_sva_service_instance_num instanceNum, t_p_NALU nalu); +t_sint32 GenerateSeq_parameter_set_rbsp (t_p_seq_parameter_set_rbsp p_sps, t_uint8 *rbsp); +t_sint32 GeneratePic_parameter_set_rbsp (t_sva_service_instance_num instanceNum, t_p_pic_parameter_set_rbsp p_pps, t_uint8 *rbsp); +PRIVATE t_sint32 GenerateVUISequenceParameters(t_p_seq_parameter_set_rbsp p_sps, Bitstream *bitstream); + +t_sint8 u_1(t_sint32 value, Bitstream *bitstream); +PRIVATE t_sint8 host_writeSyntaxElement_fixed(CodElement *codel, Bitstream *bitstream); +t_sint8 u_v(t_sint32 n, t_sint32 value, Bitstream *bitstream); +t_sint8 ue_v(t_sint32 value, Bitstream *bitstream); +PRIVATE t_sint8 host_writeSyntaxElement_UVLC(t_uint16 value, Bitstream *bitstream, t_sint32 sign); +t_sint8 se_v(t_sint32 value, Bitstream *bitstream); +void host_ue_linfo(t_uint16 ue, CodElement *sym); +void host_se_linfo(t_sint16 se, CodElement *sym); +PRIVATE void host_writeUVLC2buffer(CodElement *codel, Bitstream *currStream); +void SODBtoRBSP(Bitstream *currStream); +t_sint32 RBSPtoEBSP(t_uint8 *streamBuffer, t_sint32 begin_bytepos, t_sint32 end_bytepos, t_sint32 min_num_bytes); +PRIVATE t_sva_ec_algo_error FillParameterSetStructures (t_sva_service_instance_num instanceNum); +t_uint32 getMaxCPB(t_uint16 level_idc, t_uint16 constraint_set3_flag); +t_uint16 getIndexFromLevel (t_uint16 level_idc, t_uint16 constraint_set3_flag); +void AutomaticLevelDetection( t_sva_service_instance_num instanceNum); +PRIVATE t_uint32 CeilLog2( t_uint32 uiVal); +PRIVATE void PatchInp (t_sva_service_instance_num instanceNum); +void InitPicture(t_sva_service_instance_num instanceNum); +void PostPicture(t_sva_service_instance_num instanceNum); +PRIVATE t_sva_ec_algo_error init_img( t_sva_service_instance_num instanceNum); +t_uint32 ComputeMaxBitSizePerAU (t_sva_service_instance_num instanceNum); +void hamac_copy_param_in(t_sva_service_instance_num instanceNum, t_sva_ec_algo_params_in *pParamIn); +void SetNextImageType(t_sva_service_instance_num instanceNum); +void encode_one_frame (t_sva_service_instance_num instanceNum, t_sva_ec_algo_params_in *pParamIn); +PRIVATE void code_a_picture(t_sva_service_instance_num instanceNum, t_sva_ec_algo_params_in *pParamIn); +PRIVATE t_sva_ec_algo_error sva_EC_H264_EncodeOneFrame(t_sva_service_instance_num instanceNum, + t_sva_ec_algo_params_in *pParamIn); +/************************************ End: Code added for migration to MAINVER1.2 ************************************/ + +/****************************************************************************/ +/* NAME: t_sva_ec_algo_error sva_EC_H264_AlgoInit( */ +/* t_sva_service_instance_num instanceNum, */ +/* const t_sva_video_encoder_configuration *pConf */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine init an h264 descriptor. It save configuration and */ +/* check it. It dispatch this init to brc too. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - instanceNum: number of the descriptor to use. */ +/* - pConf: configuration to use and check. */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_ec_algo_error */ +/* t.b.d */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ + +PUBLIC t_sva_ec_algo_error sva_EC_H264_AlgoInit +( + t_sva_service_instance_num instanceNum, + const t_sva_video_encoder_configuration *pConf +) +{ + t_sva_ec_h264_descriptor *pDesc = &h264EncodeDesc[instanceNum]; +//\/ t_sva_video_encoder_algo_h264_configuration_params *pH264Conf; + t_sva_ec_algo_error algoError; +#if defined(INC_BRC_MODULE) /* if INC_BRC_MODULE */ + t_sva_brc_error brcError; +#endif /* End defined(INC_BRC_MODULE) */ +//\/ t_p_ImageParameters p_img = &pDesc->images;//\/ + +//\/ t_sva_vec_h264_param_in *pH264ParamIn = (t_sva_vec_h264_param_in *) pParamIn; +//\/ ImageParameters *p_img = &pDesc->images;//\/ +//\/ pic_parameter_set_rbsp_t *active_pps = &pDesc->active_pps;//\/ + t_p_seq_parameter_set_rbsp p_active_sps = &pDesc->active_sps; + + + HCL_DEBUG_ASSERT(pConf != NULL); + HCL_DEBUG_ASSERT(pConf->pAlgoConfig != NULL); + +//\/ pH264Conf = (t_sva_video_encoder_algo_h264_configuration_params *) pConf->pAlgoConfig; + + /* Save configuration */ + pDesc->conf = *pConf; + pDesc->h264Conf = *((t_sva_video_encoder_algo_h264_configuration_params *) pConf->pAlgoConfig); + pDesc->h264NextConf = *((t_sva_video_encoder_algo_h264_configuration_params *) pConf->pAlgoConfig); + pDesc->isFlagIntraRequest = FALSE; + pDesc->isNextConfRequiredIntraResquest = FALSE; + + /* Init h264 instance stuff */ + algoError = sva_EC_H264_ResetDescriptor(pDesc); + if (algoError != SVA_EC_ALGO_OK) + { + return(algoError); + } + +/*********************************** Start: Code added for migration to MAINVER1.2 ***********************************/ + PatchInp(instanceNum); /*\/ Sarvesh: HCL part, sva_EC_H264_IsConfigurationValid */ + + algoError = init_img(instanceNum); + if (algoError != SVA_EC_ALGO_OK) + { + return(algoError); + } + /* detect new level */ + AutomaticLevelDetection(instanceNum); /* HCL: Part of HCL */ + + /* extracts info from global variables */ + algoError = FillParameterSetStructures(instanceNum); + if (algoError != SVA_EC_ALGO_OK) + { + return(algoError); + } + +#ifdef _SUPPORT_SEI_MESSAGES_ + /* init SEI structure (if needed) and alloc required memory */ + if( pDesc->h264Conf.HrdSendMessages == 2) /* HCL: Part of HCL, Check the range of this var from 0 to 2 in HCL */ + InitSEIMessages(); /* HCL: Part of HCL */ +#endif /* _SUPPORT_SEI_MESSAGES_ */ +/************************************ End: Code added for migration to MAINVER1.2 ************************************/ + +#if 1 //\/ code added by sarvesh + /* Save the idr_flag and IntraForced information received from user */ +//\/ g_idr_flag = pH264Conf->idr_enable; +//\/ g_IntraForced = pH264Conf->IntraForced; +//\/ g_SeinitialQP = pH264Conf->SeinitialQP; + +/* SARVESH: Remove this part after taking FW3.8.1 */ + /*Rate control */ +//\/ if(!pDesc->h264Conf.brc_type) { /* without using rate control */ +//\/ if(!pDesc->conf.brcMode) { /* without using rate control */ +//\/ if (p_img->picture_coding_type == I_SLICE) +//\/ p_img->quant = pDesc->h264Conf.QPISlice; /* set quant. parameter for I-frame */ +//\/ else +//\/ p_img->quant = pDesc->h264Conf.QPPSlice; +//\/ } +#endif //\/end of #if 1 //\/ code added by sarvesh + +/*********************************** Start: Code added for migration to MAINVER1.2 ***********************************/ + /************************************************************************************** + * This part of code should be called when the SPS parameters have been initilized * + * This is done in FillParameterSetStructures function call so this function should * + * be called before putting below piece of code to modify bit_rate value * + **************************************************************************************/ + if (pDesc->h264Conf.HrdSendMessages>1) /* HCL: Part of HCL */ + g_bit_rate_val = (p_active_sps->vui_seq_parameters.nal_hrd_parameters.bit_rate_value_minus1[0] + 1 ) * (1 << (p_active_sps->vui_seq_parameters.nal_hrd_parameters.bit_rate_scale + 6)); + else + g_bit_rate_val = pDesc->h264Conf.bit_rate; +/************************************ End: Code added for migration to MAINVER1.2 ************************************/ + + /*check configuration*/ + if (sva_EC_H264_IsConfigurationValid(pConf) == FALSE) + { + return(SVA_EC_H264_PARAM_ERROR); + } + + /* Compute airThreshold */ + pDesc->frameRate = pDesc->h264Conf.FrameRate; + pDesc->nextFrameRate = pDesc->frameRate; +//\/ pDesc->airThreshold = (27 - (((pDesc->frameRate) * 39322) >> 16)); +//\/ pDesc->frameRate = (pH264Conf->vopTimeIncrementResolution + (pH264Conf->vopTimeIncrement >> 1)) / pH264Conf->vopTimeIncrement; +//\/ pDesc->nextFrameRate = pDesc->frameRate; +//\/ pDesc->airThreshold = (27 - (((pDesc->frameRate) * 39322) >> 16)); + +#if defined(INC_BRC_MODULE) /* if INC_BRC_MODULE */ + /*call brc init*/ + brcError = sva_EC_BRC_Init(instanceNum, pConf); + if (brcError != SVA_BRC_OK) + { + return(SVA_EC_H264_BRC_ERROR); + } +#endif /* End defined(INC_BRC_MODULE) */ + + return(SVA_EC_ALGO_OK); +} + +/****************************************************************************/ +/* NAME: t_sva_ec_algo_error sva_EC_H264_GetInternalNeeds( */ +/* t_sva_service_instance_num instanceNum, */ +/* t_size *pSize */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will return cacheble memory need by an h264 instance. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - instanceNum: number of the descriptor to use. */ +/* */ +/* OUT : */ +/* - pSize: need cachable memory size in bytes */ +/* */ +/* RETURN: */ +/* t_sva_ec_algo_error */ +/* t.b.d */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ + +/* + * DONE +*/ +PUBLIC t_sva_ec_algo_error sva_EC_H264_GetInternalNeeds(t_sva_service_instance_num instanceNum, t_size *pSize) +{ +#if defined(INC_BRC_MODULE) /* if INC_BRC_MODULE */ + t_sva_brc_error brcError; + t_size needSize; +//\/ t_sva_ec_algo_error ec_algo_error = SVA_EC_ALGO_OK; +#endif /* End defined(INC_BRC_MODULE) */ +//\/ t_size h4dSize=0; +//\/ t_uint32 i=0; + + HCL_DEBUG_ASSERT(pSize != NULL); + + /*We just need some space to handle infos*/ +#ifdef SVA_USE_GENERIC_ENCODER_INFOS + *pSize = sizeof(t_sva_video_encoder_infos); +#else /* SVA_USE_GENERIC_ENCODER_INFOS */ + *pSize = sizeof(t_sva_video_encoder_h264_infos); +#endif /* SVA_USE_GENERIC_ENCODER_INFOS */ + +//\/ ec_algo_error = sva_EC_H264_GetH4DSize (instanceNum, &h4dSize); +//\/ if(SVA_EC_ALGO_OK != ec_algo_error) { return SVA_INTERNAL_VIDEO_ENCODER_ERROR;} +//\/ +//\/ for(i=0; ipInfos = (t_sva_video_encoder_infos *) logicalAddress; +#else /* SVA_USE_GENERIC_ENCODER_INFOS */ + pDesc->pInfos = (t_sva_video_encoder_h264_infos *) logicalAddress; +#endif /* SVA_USE_GENERIC_ENCODER_INFOS */ + + +//\/ ec_algo_error = sva_EC_H264_GetH4DSize (instanceNum, &h4dSize); +//\/ if(SVA_EC_ALGO_OK != ec_algo_error) { return SVA_INTERNAL_VIDEO_ENCODER_ERROR;} +//\/ +//\/ for(i=0; iblockH4DAddr[i].physical); +//\/ if (inError != SVA_IN_OK) +//\/ { +//\/ return(SVA_EC_H264_INTERNAL_ERROR); +//\/ } +//\/ +//\/ internalBuffer.addr_h264e_H4D_buffer = pDesc->blockH4DAddr[i].physical; +//\/ +//\/ tmError=sva_TM_InitSubTaskField(pSubtaskIdArray[i],SVA_TM_ENC_ADDR_INTERNAL_BUFFER,(t_logical_address) &internalBuffer.addr_h264e_H4D_buffer,h4dSize); +//\/ HCL_DEBUG_ASSERT(tmError==SVA_TM_OK); +//\/ } + + ec_algo_error=sva_EC_H264_GetH4DSize (instanceNum, &h4dSize); + if(ec_algo_error!=SVA_EC_ALGO_OK) { return (t_sva_ec_algo_error) SVA_INTERNAL_VIDEO_ENCODER_ERROR;} + + for(i=0; iblockH4DId[i]); + if (mmError!= SVA_MM_OK) {return (t_sva_ec_algo_error) SVA_INTERNAL_VIDEO_ENCODER_ERROR;} + mmError=sva_MM_GetBlockSystemAddress(pDesc->blockH4DId[i],&pDesc->blockH4DAddr[i]); + if (mmError!= SVA_MM_OK) {return (t_sva_ec_algo_error) SVA_INTERNAL_VIDEO_ENCODER_ERROR;} + + //\/sva_DC_H264_ResetBlock(pDesc->blockH4DAddr[i], h4dSize); + } + + + for(i=0; iblockInfoId[i], pDesc->blockInfoSize); +//\/ if (svaError!= SVA_OK) {return SVA_INTERNAL_VIDEO_ENCODER_ERROR;} + + internalBuffer.addr_h264e_H4D_buffer = pDesc->blockH4DAddr[i].physical; + +//\/ tmError=sva_TM_InitSubTaskField(pSubtaskIdArray[i],SVA_TM_DEC_ADDR_INTERNAL_BUFFER,(t_uint32)internalBuffer.addr_h264e_H4D_buffer,h4dSize); +//\/ if (tmError!= SVA_TM_OK) {return SVA_INTERNAL_VIDEO_ENCODER_ERROR;} + + /* Update this field in subtask */ + tmError=sva_TM_UpdateSubTaskField(SVA_TM_INTERMEDIATE_FIELD_TO_UPDATE,/*don't take sem since task is not scheduled*/ + pSubtaskIdArray[i], SVA_TM_ENC_ADDR_INTERNAL_BUFFER, + FCMD_COPY,(t_uint32) &internalBuffer.addr_h264e_H4D_buffer,HCL_BITFIELD_OFFSET(t_sva_vec_internal_buffer,addr_h264e_H4D_buffer), + sizeof(internalBuffer.addr_h264e_H4D_buffer)); +//\/ /*sizeof(internalBuffer.addr_search_window_buffer)+sizeof(internalBuffer.addr_search_window_end)*/h4dSize); + if (tmError!=SVA_TM_OK) {return (t_sva_ec_algo_error) SVA_INTERNAL_VIDEO_ENCODER_ERROR;} + } + +#if defined(INC_BRC_MODULE) /* if INC_BRC_MODULE */ + /*dispatch to brc*/ + brcError = sva_EC_BRC_ProvideMemoryNeeds(instanceNum); + if (brcError != SVA_BRC_OK) + { + return(SVA_EC_H264_BRC_ERROR); + } +#endif /* End defined(INC_BRC_MODULE) */ + + return(SVA_EC_ALGO_OK); +} + +/****************************************************************************/ +/* NAME: t_sva_ec_algo_error sva_EC_H264_EncodeAlgoDelete( */ +/* t_sva_service_instance_num instanceNum */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will delete all allocated stuff (mainly fifo) */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - instanceNum: number of the descriptor to use. */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_ec_algo_error */ +/* t.b.d */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ + +/* + * DONE +*/ +PUBLIC t_sva_ec_algo_error sva_EC_H264_EncodeAlgoDelete(t_sva_service_instance_num instanceNum) +{ +#if defined(INC_BRC_MODULE) /* if INC_BRC_MODULE */ + t_sva_brc_error brcError; +#endif /* End defined(INC_BRC_MODULE) */ + t_sva_mm_error mmError = SVA_MM_OK; + t_sva_ec_h264_descriptor *pDesc = &h264EncodeDesc[instanceNum]; + t_uint16 i; + + +#ifdef _SUPPORT_SEI_MESSAGES_ + /* shutdown SEI stuff and free alloc'ed memory */ + if( pDesc->h264Conf.HrdSendMessages == 2) { + CloseSEIMessages(); /* HCL: Have to taken care in HCL */ + } +#endif /* _SUPPORT_SEI_MESSAGES_ */ + +/* Free blocks from internal needs */ + for(i=0; iblockH4DId[i]); + if (mmError!= SVA_MM_OK) {return (t_sva_ec_algo_error) SVA_INTERNAL_VIDEO_ENCODER_ERROR;} + + } + + + /* Nothing to do for H264 Encode */ +#if defined(INC_BRC_MODULE) /* if INC_BRC_MODULE */ + /*dispatch to brc*/ + brcError = sva_EC_BRC_EncodeAlgoDelete(instanceNum); + if (brcError != SVA_BRC_OK) + { + return(SVA_EC_H264_BRC_ERROR); + } +#endif /* End defined(INC_BRC_MODULE) */ + + return(SVA_EC_ALGO_OK); +} + +/****************************************************************************/ +/* NAME: t_sva_ec_algo_error sva_EC_H264_UpdateVideoEncoderParams( */ +/* t_sva_service_instance_num instanceNum, */ +/* t_sva_update_cmd_type updateCmdType, */ +/* t_sva_video_encoder_param_id paramId, */ +/* t_uint32 param */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will update dynamic parameters */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - instanceNum: number of the descriptor to use. */ +/* - updateCmdType: command to apply to the h264 Encode */ +/* - paramId: Parameter to update */ +/* - param: parameter for the cmdType */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_ec_algo_error */ +/* t.b.d */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ + +/* + +*/ +//\/ Sarvesh: Used only for the dynamic parameter update, not updated right now... +PUBLIC t_sva_ec_algo_error sva_EC_H264_UpdateVideoEncoderParams +( + t_sva_service_instance_num instanceNum, + t_sva_update_cmd_type updateCmdType, + t_sva_video_encoder_param_id paramId, + t_uint32 param +) +{ + t_sva_ec_h264_descriptor *pDesc = &h264EncodeDesc[instanceNum]; + t_sva_ec_algo_error algoError = SVA_EC_ALGO_OK; + t_sva_brc_error brcError = SVA_BRC_OK; + + /*handle algo parameters*/ + algoError = sva_EC_H264_ANNEXB_UpdateVideoEncoderParams(instanceNum, updateCmdType, paramId, param); + + /*take into account updateCmdType for algo part*/ + switch (updateCmdType) + { + case SVA_UPDATE_MULTIPLE: + /*nothing to do*/ + break; + + case SVA_UPDATE_LAST: + /*check new configuration is valid*/ + pDesc->conf.pAlgoConfig = (tp_sva_codec_algo_configuration_params) & pDesc->h264NextConf; + if (sva_EC_H264_IsConfigurationValid(&pDesc->conf) == FALSE) + { + return(SVA_EC_H264_INTERNAL_ERROR); + } + + /*compute airThreshold*/ + pDesc->frameRate = pDesc->nextFrameRate; + pDesc->airThreshold = (27 - (((pDesc->frameRate) * 39322) >> 16)); + + /*copy next as current*/ + pDesc->isFlagIntraRequest = pDesc->isNextConfRequiredIntraResquest; + pDesc->h264Conf = pDesc->h264NextConf; + pDesc->isNextConfRequiredIntraResquest = FALSE; + break; + + case SVA_UPDATE_REVERT: + /*cancel previously param update*/ + pDesc->isNextConfRequiredIntraResquest = FALSE; + pDesc->h264NextConf = pDesc->h264Conf; + pDesc->nextFrameRate = pDesc->frameRate; + break; + + default: + break; + } + +#if defined(INC_BRC_MODULE) /* if INC_BRC_MODULE */ + /*dispatch command to brc even if not a brc command*/ + /*this is need to dispatch LAST/REVERT info*/ + brcError = sva_EC_BRC_UpdateBrcParams(instanceNum, updateCmdType, paramId, param); +#endif /* End defined(INC_BRC_MODULE) */ + + /*return an error if both algo and brc return an error*/ + if (algoError != SVA_EC_ALGO_OK && brcError != SVA_BRC_OK) + { + return(SVA_EC_H264_CMD_NOT_SUPPORTED); + } + else + { + return(SVA_EC_ALGO_OK); + } +} + +/****************************************************************************/ +/* NAME: t_sva_ec_algo_error sva_EC_H264_PushImageInfo( */ +/* t_sva_service_instance_num instanceNum, */ +/* const t_sva_ec_algo_image_info *pImageInfo */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will save time stamp value to use for next picture */ +/* encoding. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - instanceNum: number of the descriptor to use. */ +/* - pImageInfo: picture information (pts and cropping vector) */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_ec_algo_error */ +/* t.b.d */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ + +/* + * DONE +*/ +PUBLIC t_sva_ec_algo_error sva_EC_H264_PushImageInfo +( + t_sva_service_instance_num instanceNum, + const t_sva_ec_algo_image_info *pImageInfo +) +{ + t_sva_ec_h264_descriptor *pDesc = &h264EncodeDesc[instanceNum]; + t_sva_ec_save *pCur = &pDesc->current; + + HCL_DEBUG_ASSERT(pImageInfo != NULL); + + /* Save pts value */ + pCur->pts = pImageInfo->pts.value; + pDesc->croppingVector = pImageInfo->croppingVector; + pDesc->brcUserRequest = pImageInfo->brcUserRequest; + + return(SVA_EC_ALGO_OK); +} + +/****************************************************************************/ +/* NAME: t_sva_ec_algo_error sva_EC_H264_GetNextFrameParamIn( */ +/* t_sva_service_instance_num instanceNum, */ +/* t_sva_ec_algo_params_in *pParamIn */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will fill Param in structure (t_sva_vec_h264_param_in) */ +/* for next picture. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - instanceNum: Number of the descriptor to use. */ +/* */ +/* OUT : */ +/* - pParamIn: Parameters to output */ +/* */ +/* RETURN: */ +/* t_sva_ec_algo_error */ +/* t.b.d */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ + +/* + * DONE +*/ +PUBLIC t_sva_ec_algo_error sva_EC_H264_GetNextFrameParamIn +( + t_sva_service_instance_num instanceNum, + t_sva_ec_algo_params_in *pParamIn +) +{ +//\/ t_sva_ec_h264_descriptor *pDesc = &h264EncodeDesc[instanceNum]; + t_sva_ec_algo_error algoError; + + HCL_DEBUG_ASSERT(pParamIn != NULL); + algoError = sva_EC_H264_ANNEXB_GetNextFrameParamIn(instanceNum, pParamIn); + + return(algoError); +} + +/****************************************************************************/ +/* NAME: t_sva_ec_algo_error sva_EC_H264_GetNextHeader( */ +/* t_sva_service_instance_num instanceNum, */ +/* t_sva_ec_algo_header *pHeader, */ +/* t_size *pSizeInBits */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will fill paramin picture for next picture. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - instanceNum: number of the descriptor to use. */ +/* */ +/* OUT : */ +/* - pHeader: header to write */ +/* - pSizeInBits: size in bits of the header */ +/* */ +/* RETURN: */ +/* t_sva_ec_algo_error */ +/* t.b.d */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ + +/* + * DONE +*/ +//\/ Sarvesh: Header buffer is not required ofr current version of H264 Encode so not updated or updated dummy +PUBLIC t_sva_ec_algo_error sva_EC_H264_GetNextHeader +( + t_sva_service_instance_num instanceNum, + t_sva_ec_algo_header *pHeader, + t_size *pSizeInBits +) +{ +//\/ t_sva_ec_h264_descriptor *pDesc = &h264EncodeDesc[instanceNum]; + t_sva_ec_algo_error algoError; + + HCL_DEBUG_ASSERT(pHeader != NULL); + HCL_DEBUG_ASSERT(pSizeInBits != NULL); + + algoError = sva_EC_H264_ANNEXB_GetNextHeader(instanceNum, pHeader, pSizeInBits); + + return(algoError); +} + +/****************************************************************************/ +/* NAME: t_sva_ec_algo_error sva_EC_H264_InitParamInOut( */ +/* t_sva_service_instance_num instanceNum, */ +/* t_sva_ec_algo_params_inout *pParamInout */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will init inout parameters for the first picture */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - instanceNum: number of the descriptor to use. */ +/* */ +/* OUT : */ +/* - pParamInout: inout parameters to init */ +/* */ +/* RETURN: */ +/* t_sva_ec_algo_error */ +/* t.b.d */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ + +/* + * TO DO : call brc level API +*/ +PUBLIC t_sva_ec_algo_error sva_EC_H264_InitParamInOut +( + t_sva_service_instance_num instanceNum, + t_sva_ec_algo_params_inout *pParamInout +) +{ + t_sva_ec_h264_descriptor *pDesc = &h264EncodeDesc[instanceNum]; + t_sva_vec_h264_param_inout *pH264ParamInOut = (t_sva_vec_h264_param_inout *) pParamInout; +#if defined(INC_BRC_MODULE) /* if INC_BRC_MODULE */ + t_sva_brc_error brcError; +#endif /* End defined(INC_BRC_MODULE) */ + t_p_ImageParameters p_img = &pDesc->images;//\/ + + HCL_DEBUG_ASSERT(pParamInout != NULL); + HCL_DEBUG_ASSERT(pH264ParamInOut != NULL); + +//\/ pH264ParamInOut->quant = p_img->quant;//\/ Sarvesh: TBD +#if 0 //\/ changed code + pH264ParamInOut->quant = 34;//\/p_img->quant;//\/ Sarvesh: TBD + pH264ParamInOut->I_Qp = 34;//\/p_img->quant;//\/ Sarvesh: TBD + pH264ParamInOut->P_Qp = 34;//\/p_img->quant;//\/ Sarvesh: TBD +#else //\/else of #if 0 //\/ changed code + /* Initialize inout part, pb because quant should be in param_in interface */ +//\/ pH264ParamInOut->quant = p_img->quant; /* SARVESH: Remove this part after taking FW3.8.1 */ +//\/ p_img->quant = hi_h264_param_inout_out->quant; +//\/ pH264ParamInOut->I_Qp = g_SeinitialQP;//\/p_img->quant;//\/ Sarvesh: TBD +//\/ pH264ParamInOut->P_Qp = g_SeinitialQP;//\/p_img->quant;//\/ Sarvesh: TBD +#endif //\/end of #if 0 //\/ changed code + +/*********************************** Start: Code added for migration to MAINVER1.2 ***********************************/ + /* This piece of code is added to make first picture number as * + * zero so that init_me IN parameter value is calculated right */ + /* The value of init_me should be 1 for first frame and Zero for subsequent frames */ + p_img->number = 0; + +//\/ pH264ParamInOut->timestamp_old = -1;//\/34;//\/p_img->quant;//\/ Sarvesh: TBD + pH264ParamInOut->timestamp_old = (t_sint32) -1; /* HCL: Part of HCL */ +/************************************ End: Code added for migration to MAINVER1.2 ************************************/ +//\/ pH264ParamInOut->previous_MB_MV_num = 1;//\/34;//\/p_img->quant;//\/ Sarvesh: TBD + +#if defined(INC_BRC_MODULE) /* if INC_BRC_MODULE */ + /*init param related to brc*/ + brcError = sva_EC_BRC_InitBrcStatsPrev(instanceNum, (t_uint32 *) pParamInout); + if (brcError != SVA_BRC_OK) + { + return(SVA_EC_H264_BRC_ERROR); + } +#endif /* End defined(INC_BRC_MODULE) */ + + /*init param related to algo*/ +//\/ pH264ParamInOut->hec_count = pDesc->h264Conf.hecFreq; + + return(SVA_EC_ALGO_OK); +} + +/****************************************************************************/ +/* NAME: t_sva_ec_algo_error sva_EC_H264_SetFrameParamOut( */ +/* t_sva_service_instance_num instanceNum, */ +/* const t_sva_ec_algo_params_out *pParamOut, */ +/* t_sva_ec_algo_params_inout *pParamInout */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will provide info to algo module after a subtask has */ +/* been excecuted. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - instanceNum: number of the descriptor to use. */ +/* - pParamIn: param in parameters. */ +/* - pParamOut: param out parameters. */ +/* - pParamInout: out param inout. */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_ec_algo_error */ +/* t.b.d */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ + +/* + * DONE +*/ +//\/ Sarvesh: This API is called after EOT has come, will be updated later +PUBLIC t_sva_ec_algo_error sva_EC_H264_SetFrameParamOut +( + t_sva_service_instance_num instanceNum, + const t_sva_ec_algo_params_out *pParamOut, + const t_sva_ec_algo_params_inout *pParamInout +) +{ + t_sva_ec_h264_descriptor *pDesc = &h264EncodeDesc[instanceNum]; + t_p_ImageParameters p_img = &pDesc->images;//\/ + t_sva_vec_h264_param_out *pH264ParamOut = (t_sva_vec_h264_param_out *) pParamOut; + t_sva_vec_h264_param_inout *pH264ParamInOut = (t_sva_vec_h264_param_inout *) pParamInout; +#if defined(INC_BRC_MODULE) /* if INC_BRC_MODULE */ + t_sva_brc_in brcIn; + t_sva_brc_error brcError; +#endif /* End defined(INC_BRC_MODULE) */ + t_uint32 videoPacketNbToCopy; + t_uint32 videoPacketOffset = 0; + t_uint32 i; + + HCL_DEBUG_ASSERT(pParamOut != NULL); + HCL_DEBUG_ASSERT(pParamInout != NULL); + HCL_DEBUG_ASSERT(pH264ParamOut != NULL); + HCL_DEBUG_ASSERT(pH264ParamInOut != NULL); + +#ifdef _REMOVE_FOR_TIME_BEING_ //\/ Firmware not updating brc_skip_prv + /* Save skip and stream size info */ + /* Skip info */ + pDesc->isCurrentItSkip = (t_bool) ((pH264ParamOut->brc_skip_prev != 0) ? TRUE : FALSE); + if (pH264ParamInOut->Skip_Current == 1 && pDesc->isCurrentItSkip == FALSE) + { + pDesc->isCurrentStrategicSkip = TRUE; + } + else + { + pDesc->isCurrentStrategicSkip = FALSE; + } +#else /* _REMOVE_FOR_TIME_BEING_ */ + pDesc->isCurrentItSkip = FALSE; + pDesc->isCurrentStrategicSkip = FALSE; +#endif /* _REMOVE_FOR_TIME_BEING_ */ + +/*********************************** Start: Code added for migration to MAINVER1.2 ***********************************/ +//\/ p_img->quant = pH264ParamInOut->quant; /* SARVESH: Remove this part after taking FW3.8.1 */ + /* pass the skip info to a host structure (just for readibility) */ + p_img->Skip_Next = pH264ParamInOut->Skip_Next; + p_img->Skip_Current = pH264ParamInOut->Skip_Current; +/************************************ End: Code added for migration to MAINVER1.2 ************************************/ + /* Save bitstream size */ +//\/ pDesc->bitstreamSizeBits = pH264ParamInOut->bitstream_size + pH264ParamInOut->stuffing_bits; + pDesc->bitstreamSizeBits = pH264ParamInOut->bitstream_size; + + /* Size info */ +//\/ pDesc->pInfos->encodedFrameSize = (pH264ParamInOut->bitstream_size + pH264ParamInOut->stuffing_bits + 7) / 8; + pDesc->pInfos->encodedFrameSize = (pH264ParamInOut->bitstream_size + 7) / 8; +#ifdef SVA_USE_GENERIC_ENCODER_INFOS + pDesc->pInfos->vpSliceNum = pH264ParamOut->slice_num; +#else /* SVA_USE_GENERIC_ENCODER_INFOS */ + pDesc->pInfos->stuffingBits = pH264ParamInOut->stuffing_bits;//\/ + pDesc->pInfos->sliceNum = pH264ParamOut->slice_num; +#endif /* SVA_USE_GENERIC_ENCODER_INFOS */ + if (pH264ParamOut->slice_num > SVA_EC_H264_SLICE_POS_COUNT) + { + videoPacketNbToCopy = SVA_EC_H264_SLICE_POS_COUNT; + videoPacketOffset = pH264ParamOut->slice_num % SVA_EC_H264_SLICE_POS_COUNT; + } + else + { + videoPacketNbToCopy = pH264ParamOut->slice_num; + } + + for (i = 0; i < videoPacketNbToCopy; i++) + { +#ifdef SVA_USE_GENERIC_ENCODER_INFOS + pDesc->pInfos->vpSlicePos[i] = pH264ParamOut->slice_pos[(i + videoPacketOffset) % SVA_EC_H264_SLICE_POS_COUNT]; +#else /* SVA_USE_GENERIC_ENCODER_INFOS */ + pDesc->pInfos->slicePos[i] = pH264ParamOut->slice_pos[(i + videoPacketOffset) % SVA_EC_H264_SLICE_POS_COUNT]; +#endif /* SVA_USE_GENERIC_ENCODER_INFOS */ + } + +#if defined(INC_BRC_MODULE) /* if INC_BRC_MODULE */ + /* Provide data to BRC */ + brcIn.bitstreamSize = pH264ParamInOut->bitstream_size; + brcIn.stuffingBits = pH264ParamInOut->stuffing_bits; +//\/ brcIn.brcSkipPrev = pH264ParamOut->brc_skip_prev; + brcIn.brcSkipPrev = pH264ParamInOut->Skip_Next; + brcIn.skipCurrent = pH264ParamInOut->Skip_Current; + brcError = sva_EC_BRC_FinishPicture(instanceNum, &brcIn); + if (brcError != SVA_BRC_OK) + { + return(SVA_EC_H264_BRC_ERROR); + } +#endif /* End defined(INC_BRC_MODULE) */ + +/*********************************** Start: Code added for migration to MAINVER1.2 ***********************************/ + /* management of encoding timestamp and coded picture counter */ +//\/ PostPicture(instanceNum); +//\/ p_img->number++; +/************************************ End: Code added for migration to MAINVER1.2 ************************************/ + return(SVA_EC_ALGO_OK); +} + +/****************************************************************************/ +/* NAME: t_sva_ec_algo_error sva_EC_H264_GetSkipInfo( */ +/* t_sva_service_instance_num instanceNum, */ +/* t_bool *pIsCurrentStrategicSkip, */ +/* t_bool *pIsCurrentItSkip */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will return skip information need by encode part to */ +/* handle buffers correctly. It must call after */ +/* sva_EC_H264_SetFrameParamOut() call. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - instanceNum: number of the descriptor to use. */ +/* */ +/* OUT : */ +/* - pIsCurrentStrategicSkip: return information about the fact that current*/ +/* picture is strategic skip. */ +/* - pIsCurrentItSkip: return information about the fact that current picture*/ +/* is IT skip. */ +/* */ +/* RETURN: */ +/* t_sva_ec_algo_error */ +/* t.b.d */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ + +/* + +*/ +PUBLIC t_sva_ec_algo_error sva_EC_H264_GetSkipInfo +( + t_sva_service_instance_num instanceNum, + t_bool *pIsCurrentStrategicSkip, + t_bool *pIsCurrentItSkip +) +{ + t_sva_ec_h264_descriptor *pDesc = &h264EncodeDesc[instanceNum]; + + HCL_DEBUG_ASSERT(pIsCurrentStrategicSkip != NULL); + HCL_DEBUG_ASSERT(pIsCurrentItSkip != NULL); + + /*return skip info for encode part so it can handle buffers correctly*/ + *pIsCurrentStrategicSkip = pDesc->isCurrentStrategicSkip; + *pIsCurrentItSkip = pDesc->isCurrentItSkip; + + return(SVA_EC_ALGO_OK); +} + +/****************************************************************************/ +/* NAME: t_sva_ec_algo_error sva_EC_H264_GetBitstreamSize( */ +/* t_sva_service_instance_num instanceNum, */ +/* t_size *pBitstreamSizeInBits */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will return size of encoded stream in bits. This */ +/* include stuffings bits. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - instanceNum: number of the descriptor to use. */ +/* */ +/* OUT : */ +/* - pBitstreamSizeInBits: return size of encoded bitstream in bits. This */ +/* include stuffing bits. */ +/* */ +/* RETURN: */ +/* t_sva_ec_algo_error */ +/* t.b.d */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ + +/* + * DONE +*/ +PUBLIC t_sva_ec_algo_error sva_EC_H264_GetBitstreamSize +( + t_sva_service_instance_num instanceNum, + t_size *pBitstreamSizeInBits +) +{ + t_sva_ec_h264_descriptor *pDesc = &h264EncodeDesc[instanceNum]; + + HCL_DEBUG_ASSERT(pBitstreamSizeInBits != NULL); + + *pBitstreamSizeInBits = pDesc->bitstreamSizeBits; + + return(SVA_EC_ALGO_OK); +} + +/****************************************************************************/ +/* NAME: t_sva_ec_algo_error sva_EC_H264_PachBitstream( */ +/* t_sva_service_instance_num instanceNum, */ +/* const t_sva_ec_algo_params_in *pParamIn, */ +/* t_logical_address bitstreamAddr */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will return size of encoded stream in bits. This */ +/* include stuffings bits. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - instanceNum: number of the descriptor to use. */ +/* - bitstreamAddr : start address of bitstream. */ +/* */ +/* OUT : */ +/* none */ +/* */ +/* RETURN: */ +/* t_sva_ec_algo_error */ +/* t.b.d */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ + + +PUBLIC t_sva_ec_algo_error sva_EC_H264_PatchBitstream +( + t_sva_service_instance_num instanceNum, + const t_sva_ec_algo_params_in *pParamIn, + t_logical_address bitstreamAddr +) +{ + t_sva_vec_h264_param_in *pH264ParamIn = (t_sva_vec_h264_param_in *) pParamIn; +//\/ t_sva_ec_h264_descriptor *pDesc = &h264EncodeDesc[instanceNum]; +//\/ t_uint8 *bitBuffer = (t_uint8 *) bitstreamAddr; +//\/ t_sint32 bufferLevel; +//\/ t_uint32 vbvOccupancy; +//\/ t_uint8 buffer[5]; +//\/ t_uint8 i; + + HCL_DEBUG_ASSERT(pParamIn != NULL); + HCL_DEBUG_ASSERT(pH264ParamIn != NULL); + +//\/ if (pDesc->h264Conf.isSystemHeaderAddBeforeIntra == TRUE && pDesc->conf.bufferingModel != SVA_BUFFERING_NONE) +//\/ { +//\/ /* check if we have something to do*/ +//\/ if (pH264ParamIn->picture_coding_type == SVA_H264_VOP_CODING_TYPE_I) +//\/ { +//\/ if (pDesc->isFirstPicture == TRUE) +//\/ { +//\/ /*check in case of first picture skip*/ +//\/ if (pDesc->isCurrentItSkip == FALSE && pDesc->isCurrentStrategicSkip == FALSE) +//\/ { +//\/ pDesc->isFirstPicture = FALSE; +//\/ } +//\/ } +//\/ else +//\/ { +//\/ if (pDesc->isCurrentItSkip == FALSE && pDesc->isCurrentStrategicSkip == FALSE) +//\/ { +//\/ /* So we have to fix vol header of current picture*/ +//\/ /* copy the 5 bytes of bitstream that need to be modify +//\/ * in local buffer to improve speed. +//\/ */ +//\/ for (i = 0; i < 5; i++) +//\/ { +//\/ buffer[i] = bitBuffer[26 + i]; +//\/ } +//\/ +//\/ /* get bufferSizeForVbv store in bitstream */ +//\/ bufferLevel = ((buffer[0] & 0x3f) << 26); +//\/ bufferLevel += (buffer[1] << 18); +//\/ bufferLevel += (buffer[2] << 10); +//\/ bufferLevel += (buffer[3] << 2); +//\/ bufferLevel += ((buffer[4] & 0xc0) >> 6); +//\/ +//\/ /* ask brc for vbv_occupancy value */ +//\/ vbvOccupancy = sva_EC_BRC_GetVbvOccupancy(instanceNum, bufferLevel, pDesc->previousBitstreamSize); +//\/ +//\/ /* patch bitstream*/ +//\/ buffer[0] = (buffer[0] & 0xc0); +//\/ buffer[1] = 0; +//\/ buffer[2] = 0; +//\/ buffer[3] = 0; +//\/ buffer[4] = (buffer[4] & 0x3f); +//\/ bitBuffer[26] = buffer[0] + 0x20 + ((pDesc->brcOut.vbvBufferSizeIn16384BitsUnit + 1 & 7) << 2) + ((vbvOccupancy & 0x3000000) >> 24); +//\/ bitBuffer[27] = ((vbvOccupancy & 0xff0000) >> 16); +//\/ bitBuffer[28] = ((vbvOccupancy & 0x8000) >> 16) + 0x40 + ((vbvOccupancy & 0x7e00) >> 9); +//\/ bitBuffer[29] = ((vbvOccupancy & 0x1fe) >> 1); +//\/ bitBuffer[30] = buffer[4] + 0x40 + ((vbvOccupancy & 1) << 7); +//\/ } +//\/ } +//\/ } +//\/ +//\/ /* update previous picture size*/ +//\/ if (pDesc->isCurrentItSkip == FALSE && pDesc->isCurrentStrategicSkip == FALSE) +//\/ { +//\/ pDesc->previousBitstreamSize = pDesc->bitstreamSizeBits; +//\/ } +//\/ else +//\/ { +//\/ pDesc->previousBitstreamSize = 0; +//\/ } +//\/ } + + return(SVA_EC_ALGO_OK); +} + +/****************************************************************************/ +/* NAME: t_sva_ec_algo_error sva_EC_H264_FillInfosBuffer( */ +/* t_sva_service_instance_num instanceNum, */ +/* t_sva_buffer_id bufferId */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will fill given buffer with infos of good type. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - instanceNum: number of the descriptor to use. */ +/* - bufferId: buffer where to write infos. */ +/* */ +/* OUT : */ +/* - pBitstreamSizeInBits: return size of encoded bitstream in bits. This */ +/* include stuffing bits. */ +/* */ +/* RETURN: */ +/* t_sva_ec_algo_error */ +/* t.b.d */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ + +/* + * DONE +*/ +PUBLIC t_sva_ec_algo_error sva_EC_H264_FillInfosBuffer(t_sva_service_instance_num instanceNum, t_sva_buffer_id bufferId) +{ + t_sva_ec_h264_descriptor *pDesc = &h264EncodeDesc[instanceNum]; + t_logical_address infoAddr; +#ifdef SVA_USE_GENERIC_ENCODER_INFOS + t_sva_video_encoder_infos *pInfos; +#else /* SVA_USE_GENERIC_ENCODER_INFOS */ + t_sva_video_encoder_h264_infos *pInfos; +#endif /* SVA_USE_GENERIC_ENCODER_INFOS */ + t_uint32 videoPacketNbToCopy; + t_uint32 i; + t_sva_bm_error bmError; + + /*get a pointer on the data to write*/ + bmError = sva_BM_GetBufferLogicalAddress(bufferId, &infoAddr); + if (bmError != SVA_BM_OK) + { + return(SVA_EC_H264_INTERNAL_ERROR); + } + +#ifdef SVA_USE_GENERIC_ENCODER_INFOS + pInfos = (t_sva_video_encoder_infos *) infoAddr; +#else /* SVA_USE_GENERIC_ENCODER_INFOS */ + pInfos = (t_sva_video_encoder_h264_infos *) infoAddr; +#endif /* SVA_USE_GENERIC_ENCODER_INFOS */ + + /*copy data*/ + pInfos->encodedFrameSize = pDesc->pInfos->encodedFrameSize; +#ifdef SVA_USE_GENERIC_ENCODER_INFOS + pInfos->vpSliceNum = pDesc->pInfos->vpSliceNum; + if (pInfos->vpSliceNum > SVA_EC_H264_SLICE_POS_COUNT) +#else /* SVA_USE_GENERIC_ENCODER_INFOS */ + pInfos->stuffingBits = pDesc->pInfos->stuffingBits;//\/ + pInfos->sliceNum = pDesc->pInfos->sliceNum; + if (pInfos->sliceNum > SVA_EC_H264_SLICE_POS_COUNT) +#endif /* SVA_USE_GENERIC_ENCODER_INFOS */ + { + videoPacketNbToCopy = SVA_EC_H264_SLICE_POS_COUNT; + } + else + { +#ifdef SVA_USE_GENERIC_ENCODER_INFOS + videoPacketNbToCopy = pInfos->vpSliceNum; +#else /* SVA_USE_GENERIC_ENCODER_INFOS */ + videoPacketNbToCopy = pInfos->sliceNum; +#endif /* SVA_USE_GENERIC_ENCODER_INFOS */ + } + + for (i = 0; i < videoPacketNbToCopy; i++) + { +#ifdef SVA_USE_GENERIC_ENCODER_INFOS + pInfos->vpSlicePos[i] = pDesc->pInfos->vpSlicePos[i]; +#else /* SVA_USE_GENERIC_ENCODER_INFOS */ + pInfos->slicePos[i] = pDesc->pInfos->slicePos[i]; +#endif /* SVA_USE_GENERIC_ENCODER_INFOS */ + } + + return(SVA_EC_ALGO_OK); +} + +/****************************************************************************/ +/* NAME: t_bool sva_EC_H264_IsPreviousPictureWasStategicSkip( */ +/* t_sva_service_instance_num instanceNum */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will return skip information need by encode part to */ +/* handle buffers correctly. It must call after */ +/* sva_EC_H264_SetFrameParamOut() call. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - instanceNum: number of the descriptor to use. */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_bool */ +/* TRUE : previous picture was strategic skip */ +/* FALSE : previous picture was not strategic skip */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ + + +PUBLIC t_bool sva_EC_H264_IsPreviousPictureWasStategicSkip(t_sva_service_instance_num instanceNum) +{ +#if defined(INC_BRC_MODULE) /* if INC_BRC_MODULE */ + return(sva_EC_BRC_IsPreviousPictureWasStrategicSkip(instanceNum)); +#else /* else of INC_BRC_MODULE */ + return(FALSE);//\/ +#endif /* End defined(INC_BRC_MODULE) */ +} + +/****************************************************************************/ +/* NAME: t_size sva_EC_H264_GetParamsInSize( */ +/* t_sva_service_instance_num instanceNum */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will return numbers of bytes need to handle h264 */ +/* paramin structure. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - instanceNum: number of the descriptor to use. */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_size */ +/* t.b.d */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ + +/* + * DONE +*/ +PUBLIC t_size sva_EC_H264_GetParamsInSize(t_sva_service_instance_num instanceNum) +{ + (void) instanceNum; + + return(sizeof(t_sva_vec_h264_param_in)); +} + +/****************************************************************************/ +/* NAME: t_size sva_EC_H264_GetParamsOutSize( */ +/* t_sva_service_instance_num instanceNum */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will return numbers of bytes need to handle h264 */ +/* paramout structure. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - instanceNum: number of the descriptor to use. */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_size */ +/* t.b.d */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ + +/* + * DONE +*/ +PUBLIC t_size sva_EC_H264_GetParamsOutSize(t_sva_service_instance_num instanceNum) +{ + (void) instanceNum; + + return(sizeof(t_sva_vec_h264_param_out)); +} + +/****************************************************************************/ +/* NAME: t_size sva_EC_H264_GetParamsInOutSize( */ +/* t_sva_service_instance_num instanceNum */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will return numbers of bytes need to handle h264 */ +/* paraminout structure. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - instanceNum: number of the descriptor to use. */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_size */ +/* t.b.d */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ + +/* + * DONE +*/ +PUBLIC t_size sva_EC_H264_GetParamsInOutSize(t_sva_service_instance_num instanceNum) +{ + (void) instanceNum; + + return(sizeof(t_sva_vec_h264_param_inout)); +} + +/****************************************************************************/ +/* NAME: t_size sva_EC_H264_GetMaxHeaderSize( */ +/* t_sva_service_instance_num instanceNum */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will return max number of bytes a header can be. Thus */ +/* encode part will allocate enought space for such header. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - instanceNum: number of the descriptor to use. */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_size */ +/* t.b.d */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ + +/* + * DONE +*/ +PUBLIC t_size sva_EC_H264_GetMaxHeaderSize(t_sva_service_instance_num instanceNum) +{ +//\/ t_sva_ec_h264_descriptor *pDesc = &h264EncodeDesc[instanceNum]; + + return(sva_EC_H264_ANNEXB_GetMaxHeaderSize(instanceNum)); +} + +/****************************************************************************/ +/* NAME: t_sva_ec_algo_error sva_EC_H264_ResetDescriptor( */ +/* t_sva_ec_h264_descriptor *pDesc */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine reset an h264 descriptor. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - pDesc: h264 descritor to reset. */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_ec_algo_error */ +/* t.b.d */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ + +/* + * DONE +*/ +PRIVATE t_sva_ec_algo_error sva_EC_H264_ResetDescriptor(t_sva_ec_h264_descriptor *pDesc) +{ + t_uint32 i; + + HCL_ASSERT(pDesc != NULL); + + /*init current field*/ + pDesc->current.pts = 0; + pDesc->current.pictureNb = ~0; + pDesc->current.roundValue = 0; +//\/ pDesc->current.pictureCodingType = SVA_H264_SLICE_CODING_TYPE_I;//\/I_SLICE; + pDesc->current.pictureCodingType = I_SLICE; +//\/ pDesc->current.gobFrameId = 0; +//\/ pDesc->current.temporalSh.tr = 0; +//\/ pDesc->current.temporalSh.cumulTimeSlot = 0; +//\/ pDesc->current.temporalSh.slotDelay = 0; +//\/ pDesc->current.temporalSp.remainForOffset = 0; +//\/ pDesc->current.temporalSp.moduloTimeBase = 0; +//\/ pDesc->current.temporalSp.vopTimeIncrement = 0; +//\/ pDesc->current.temporalSp.vopTimeIncrementBitSize = 0; +//\/ if (pDesc->h264Conf.flagShortHeader == FALSE) +//\/ { +//\/ while ((1 << pDesc->current.temporalSp.vopTimeIncrementBitSize) < pDesc->h264Conf.vopTimeIncrementResolution) +//\/ { +//\/ pDesc->current.temporalSp.vopTimeIncrementBitSize++; +//\/ } +//\/ } + + /* init skip fifo with current*/ + for (i = 0; i < 2; i++) + { + pDesc->skipFifo[i] = pDesc->current; + } + + /* init vbv_occupancy fix stuff */ + pDesc->isFirstPicture = TRUE; + + return(SVA_EC_ALGO_OK); +} + +/****************************************************************************/ +/* NAME: t_sva_ec_algo_error sva_EC_H264_IsConfigurationValid( */ +/* const t_sva_video_encoder_configuration *pConf */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine check if configuration is valid. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - pConf: configuration to check validity. */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_ec_algo_error */ +/* t.b.d */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ + +/* + * TO DO : deblocking support : do it when done at encode level + * - additional checks must be done for some param +*/ +PRIVATE t_bool sva_EC_H264_IsConfigurationValid(const t_sva_video_encoder_configuration *pConf) +{ + t_sva_video_encoder_algo_h264_configuration_params *pH264Conf; +//\/ t_uint16 width; +//\/ t_uint16 height; + + HCL_ASSERT(pConf != NULL); + pH264Conf = (t_sva_video_encoder_algo_h264_configuration_params *) pConf->pAlgoConfig; +//\/ width = pConf->sourceFrameDesc.window.image.width; +//\/ height = pConf->sourceFrameDesc.window.image.height; + + /*check first general config limit by algo*/ + /*t_sva_windowed_frame_desc sourceFrameDesc*/ + CHECK_ALIGNMENT(pConf->sourceFrameDesc.frame.height, SVA_EC_H264_SOURCE_FRAME_HEIGHT_ALIGN); + CHECK_RANGE + ( + pConf->sourceFrameDesc.frame.height, + SVA_EC_H264_SOURCE_FRAME_HEIGHT_MIN, + SVA_EC_H264_SOURCE_FRAME_HEIGHT_MAX + ); + CHECK_ALIGNMENT(pConf->sourceFrameDesc.frame.width, SVA_EC_H264_SOURCE_FRAME_WIDTH_ALIGN); + CHECK_RANGE + ( + pConf->sourceFrameDesc.frame.width, + SVA_EC_H264_SOURCE_FRAME_WIDTH_MIN, + SVA_EC_H264_SOURCE_FRAME_WIDTH_MAX + ); + CHECK_ALIGNMENT(pConf->sourceFrameDesc.window.image.height, SVA_EC_H264_SOURCE_WINDOW_HEIGHT_ALIGN); + CHECK_RANGE + ( + pConf->sourceFrameDesc.window.image.height, + SVA_EC_H264_SOURCE_WINDOW_HEIGHT_MIN, + pConf->sourceFrameDesc.frame.height + ); + CHECK_ALIGNMENT(pConf->sourceFrameDesc.window.image.width, SVA_EC_H264_SOURCE_WINDOW_WIDTH_ALIGN); + CHECK_RANGE + ( + pConf->sourceFrameDesc.window.image.width, + SVA_EC_H264_SOURCE_WINDOW_WIDTH_MIN, + pConf->sourceFrameDesc.frame.width + ); + CHECK_ALIGNMENT(pConf->sourceFrameDesc.window.imageOffset.offsetX, SVA_EC_H264_SOURCE_WINDOW_OFFSET_X_ALIGN); + CHECK_RANGE0 + ( + pConf->sourceFrameDesc.window.imageOffset.offsetX, + SVA_EC_H264_SOURCE_WINDOW_OFFSET_X_MIN, + pConf->sourceFrameDesc.frame.width - pConf->sourceFrameDesc.window.image.width + ); + CHECK_ALIGNMENT(pConf->sourceFrameDesc.window.imageOffset.offsetY, SVA_EC_H264_SOURCE_WINDOW_OFFSET_Y_ALIGN); + CHECK_RANGE0 + ( + pConf->sourceFrameDesc.window.imageOffset.offsetY, + SVA_EC_H264_SOURCE_WINDOW_OFFSET_Y_MIN, + pConf->sourceFrameDesc.frame.height - pConf->sourceFrameDesc.window.image.height + ); + +//\/ /*additional size check for short header*/ +//\/ if +//\/ ( +//\/ pH264Conf->flagShortHeader == TRUE +//\/ && (width != SVA_EC_H264_SQCIF_WIDTH || height != SVA_EC_H264_SQCIF_HEIGHT) +//\/ && (width != SVA_EC_H264_QCIF_WIDTH || height != SVA_EC_H264_QCIF_HEIGHT) +//\/ && (width != SVA_EC_H264_CIF_WIDTH || height != SVA_EC_H264_CIF_HEIGHT) +//\/ && (width != SVA_EC_H264_CIF4_WIDTH || height != SVA_EC_H264_CIF4_HEIGHT) +//\/ && (width != SVA_EC_H264_CIF16_WIDTH || height != SVA_EC_H264_CIF16_HEIGHT) +//\/ && (width != SVA_EC_H264_VGA_WIDTH || height != SVA_EC_H264_VGA_HEIGHT) +//\/ && (width != SVA_EC_H264_MB1_WIDTH || height != SVA_EC_H264_MB1_HEIGHT) +//\/ ) +//\/ { +//\/ return(FALSE); +//\/ } +//\/ +//\/ /*check vopTimeIncrement*/ +//\/ if (pH264Conf->vopTimeIncrement == 0) +//\/ { +//\/ return(FALSE); +//\/ } +//\/ +//\/ /*additional size check when data is partinionned*/ +//\/ if (pH264Conf->flagShortHeader == FALSE && pH264Conf->isDataPartitionedEnable == TRUE) +//\/ { +//\/ CHECK_RANGE +//\/ ( +//\/ pConf->sourceFrameDesc.window.image.height, +//\/ SVA_EC_H264_SOURCE_WINDOW_HEIGHT_MIN, +//\/ SVA_EC_H264_SOURCE_WINDOW_HEIGHT_PARTITIONED_MAX +//\/ ); +//\/ CHECK_RANGE +//\/ ( +//\/ pConf->sourceFrameDesc.window.image.width, +//\/ SVA_EC_H264_SOURCE_WINDOW_WIDTH_MIN, +//\/ SVA_EC_H264_SOURCE_WINDOW_WIDTH_PARTITIONED_MAX +//\/ ); +//\/ } +//\/ +//\/ /*check specific to short header*/ +//\/ if (pH264Conf->flagShortHeader == TRUE) +//\/ { +//\/ /*check gob header frequency*/ +//\/ CHECK_RANGE0(pH264Conf->gobHeaderFrequency, 0, pConf->sourceFrameDesc.window.image.height / 16); +//\/ +//\/ /*isDataPartitionedEnable and isReversibleVlcEnable must be false*/ +//\/ if (pH264Conf->isDataPartitionedEnable == TRUE || pH264Conf->isReversibleVlcEnable == TRUE) +//\/ { +//\/ return(FALSE); +//\/ } +//\/ } +//\/ +//\/ /*check specific to simple profile*/ +//\/ if (pH264Conf->flagShortHeader == FALSE) +//\/ { +//\/ /*check hec frequency*/ +//\/ CHECK_RANGE0 +//\/ ( +//\/ pH264Conf->hecFreq, +//\/ 0, +//\/ (pConf->sourceFrameDesc.window.image.height * pConf->sourceFrameDesc.window.image.width) / 256 +//\/ ); +//\/ +//\/ /*check isReversibleVlcEnable enable when isDataPartitionedEnable is enable*/ +//\/ if (pH264Conf->isReversibleVlcEnable == TRUE && pH264Conf->isDataPartitionedEnable == FALSE) +//\/ { +//\/ return(FALSE); +//\/ } +//\/ +//\/ /*check hec generation when isDataPartitionedEnable is enable*/ +//\/ if (pH264Conf->hecFreq != 0 && pH264Conf->isDataPartitionedEnable == FALSE) +//\/ { +//\/ return(FALSE); +//\/ } +//\/ +//\/ if (pH264Conf->isDataPartitionedEnable == TRUE) +//\/ { +//\/ /* vpSizeMax VSM must not be greater than the "Max. videopacket length" defined in Table N1 of [1]: +//\/ - for Simple Profile Level 0, VSM<=2048, +//\/ - for Simple Profile Level 1, VSM<=2048, +//\/ - for Simple Profile Level 2, VSM<=4096, +//\/ - for Simple Profile Level 3, VSM<=8192.*/ +//\/ /* vpSizeType possible values are 0,1,2 or 3*/ +//\/ CHECK_RANGE0(pH264Conf->vpSizeType, 0, 3); +//\/ +//\/ /* Video packet bit size (VBS used only when vp_size_type=0/2/3) +//\/ The following relation must hold:0<=VBS<= vpSizeMax */ +//\/ if (pH264Conf->vpSizeType != 1) +//\/ { +//\/ CHECK_RANGE0(pH264Conf->vpBitSize, 0, pH264Conf->vpSizeMax); +//\/ } +//\/ +//\/ /*Video packet macroblock size (VMS used only when vp_size_type=1/2/3). +//\/ The following relation must hold:0<=VMS<=window_width*window_height/256*/ +//\/ if (pH264Conf->vpSizeType != 0) +//\/ { +//\/ CHECK_RANGE0(pH264Conf->vpMbSize, 0, width * height / 256); +//\/ } +//\/ } +//\/ } +//\/ +//\/ /*check isSystemHeaderAddBeforeIntra*/ +//\/ if (pH264Conf->isSystemHeaderAddBeforeIntra == TRUE && pH264Conf->flagShortHeader == TRUE) +//\/ { +//\/ /*insertion of vol header is only valid in simple profile*/ +//\/ return(FALSE); +//\/ } +//\/ + /*check deblocking support*/ + /*for h264 / only no deblocking or out of the loop SVA_DEBLOCKING_DERINGING_FILTER allowed*/ + if + ( + !((SVA_NONE_FILTER == pConf->inTheLoopFilter || SVA_DEBLOCKING_FILTER == pConf->inTheLoopFilter) + && SVA_NONE_FILTER == pConf->outTheLoopFilter) + ) + { + return(FALSE); + } + + if + ( (SVA_DEBLOCKING_FILTER == pConf->inTheLoopFilter) && + (SVA_H264_NONE_FILTER == pH264Conf->disable_deblocking_filter_idc) + ) + { + return(FALSE); + } + + if + ( (SVA_NONE_FILTER == pConf->inTheLoopFilter) && + (SVA_H264_NONE_FILTER != pH264Conf->disable_deblocking_filter_idc) + ) + { + return(FALSE); + } +#if defined(INC_BRC_MODULE) /* if INC_BRC_MODULE */ + /* Check brcMode/bufferingModel/flagShortHeader compatibility */ + switch (pConf->brcMode) + { + case SVA_QP_CONSTANT: + if (pConf->bufferingModel == SVA_BUFFERING_HRD || pConf->bufferingModel == SVA_BUFFERING_ANNEXG) + { + return(FALSE); + } + break; + + case SVA_FRAME_BASE: + if (pConf->bufferingModel != SVA_BUFFERING_NONE) + { + return(FALSE); + } + break; + + case SVA_CBR: + if (pConf->bufferingModel != SVA_BUFFERING_HRD) + { + return(FALSE); + } + else if (pConf->bufferingModel != SVA_BUFFERING_VBV) + { + return(FALSE); + } + break; + + case SVA_VBR: + if (pConf->bufferingModel != SVA_BUFFERING_ANNEXG) + { + return(FALSE); + } + else if (pConf->bufferingModel != SVA_BUFFERING_VBV) + { + return(FALSE); + } + break; + + default: + return(FALSE); + + // break; line commented fcor warning removal. + } +#endif /* End defined(INC_BRC_MODULE) */ + + return(TRUE); +} + +/****************************************************************************/ +/* NAME: t_sva_ec_algo_error sva_EC_H264_ANNEXB_GetNextFrameParamIn( */ +/* t_sva_service_instance_num instanceNum, */ +/* t_sva_ec_algo_params_in *pParamIn */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will fill Param in structure (t_sva_vec_h264_param_in) */ +/* for next picture. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - instanceNum: number of the descriptor to use. */ +/* */ +/* OUT : */ +/* - pParamIn: parameters to output */ +/* */ +/* RETURN: */ +/* t_sva_ec_algo_error */ +/* t.b.d */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ + +PRIVATE t_sva_ec_algo_error sva_EC_H264_ANNEXB_GetNextFrameParamIn +( + t_sva_service_instance_num instanceNum, + t_sva_ec_algo_params_in *pParamIn +) +{ + t_sva_ec_h264_descriptor *pDesc = &h264EncodeDesc[instanceNum]; + t_sva_vec_h264_param_in *pH264ParamIn = (t_sva_vec_h264_param_in *) pParamIn; + t_sva_ec_save *pCur = &pDesc->current; + t_bool isPreviousSkip=FALSE; + t_bool isPictureReplay; +#if defined(INC_BRC_MODULE) /* if INC_BRC_MODULE */ + t_sva_brc_error brcError; +#endif /* End defined(INC_BRC_MODULE) */ + t_sva_ec_save *pPrev; + t_uint32 i; + +//\/ pic_parameter_set_rbsp_t *active_pps = &pDesc->active_pps;//\/ +//\/ ImageParameters *p_img = &pDesc->images;//\/ + + HCL_ASSERT(pParamIn != NULL); + HCL_ASSERT(pH264ParamIn != NULL); + +#if defined(INC_BRC_MODULE) /* if INC_BRC_MODULE */ + /*get info from brc concerning param in*/ + brcError = sva_EC_BRC_InitPicture(instanceNum, pDesc->brcUserRequest, pCur->pts, &pDesc->brcOut, &isPreviousSkip); + if (brcError != SVA_BRC_OK) + { + return(SVA_EC_H264_BRC_ERROR); + } +#endif /* End defined(INC_BRC_MODULE) */ + + /* + * Now is the fun part !!!!!!! + * At this point we know if previous picture has been skip or not. Moreover by compare pDesc->pts with the + * last one push we can detect the case where a picture is programmed twice due to skip interrupt. + * We then define pPrev the point on previous not skip picture info. + */ + if (pCur->pts == pDesc->skipFifo[0].pts && pCur->pictureNb != ~0) + { + isPictureReplay = TRUE; + } + else + { + isPictureReplay = FALSE; + } + + if (isPreviousSkip == TRUE) + { + if (isPictureReplay == TRUE) + { + pPrev = &pDesc->skipFifo[2]; + } + else + { + pPrev = &pDesc->skipFifo[1]; + } + } + else + { + pPrev = &pDesc->skipFifo[0]; + } + + /*compute pictureNb*/ + pCur->pictureNb = pPrev->pictureNb + 1; + + /*compute temporal reference*/ + if (pCur->pictureNb == 0) + { +//\/ pCur->temporalSh.tr = 0; +//\/ pCur->temporalSh.cumulTimeSlot = 0; +//\/ pCur->temporalSh.slotDelay = 0; + } + else + { +//\/ t_uint32 ptsDifference; + + /*compute pts difference*/ +//\/ ptsDifference = pCur->pts - pPrev->pts; + + /*update tr. Use ptsDifference*/ +//\/ pCur->temporalSh.tr = +//\/ ( +//\/ (ptsDifference + pPrev->temporalSh.cumulTimeSlot + H264_ANNEXB_ROUND_VALUE) / +//\/ H264_ANNEXB_CLOCK_SLOT + +//\/ pPrev->temporalSh.tr +//\/ ) & 0xff; +//\/ pCur->temporalSh.cumulTimeSlot = (ptsDifference + pPrev->temporalSh.cumulTimeSlot + H264_ANNEXB_ROUND_VALUE) % H264_ANNEXB_CLOCK_SLOT; +//\/ pCur->temporalSh.cumulTimeSlot -= H264_ANNEXB_ROUND_VALUE; + + /*rounding of tr*/ + /*pCur->temporalSh.slotDelay = pPrev->temporalSh.slotDelay; + if (pCur->temporalSh.cumulTimeSlot !=0 && pCur->temporalSh.slotDelay == 0) + { + pCur->temporalSh.tr++; + pCur->temporalSh.slotDelay = 1; + } + else if (pCur->temporalSh.cumulTimeSlot == 0 && pCur->temporalSh.slotDelay !=0) + { + pCur->temporalSh.tr--; + pCur->temporalSh.slotDelay = 0; + }*/ + } + + /*fill brc parameters*/ +//\/ pH264ParamIn->picture_coding_type = p_img->picture_coding_type; +//\/ pCur->pictureCodingType = p_img->picture_coding_type; +//\/ pH264ParamIn->picture_coding_type = pDesc->brcOut.pictureCodingType; +//\/ pCur->pictureCodingType = pDesc->brcOut.pictureCodingType; +//\/ pH264ParamIn->quant = pDesc->brcOut.quant; +//\/ pH264ParamIn->brc_type = pDesc->brcOut.brcType; +//\/ pH264ParamIn->brc_frame_target = pDesc->brcOut.brcFrameTarget; +//\/ pH264ParamIn->brc_target_min_pred = pDesc->brcOut.brcTargetMinPred; +//\/ pH264ParamIn->brc_target_max_pred = pDesc->brcOut.brcTargetMaxPred; +//\/ pH264ParamIn->skip_count = pDesc->brcOut.skipCount; +//\/ pH264ParamIn->bit_rate = pDesc->brcOut.bitRate; +//\/ pH264ParamIn->framerate = pDesc->brcOut.frameRate; +//\/ pH264ParamIn->ts_modulo = pDesc->brcOut.tsModulo; +//\/ pH264ParamIn->ts_seconds = pDesc->brcOut.tsSeconds; +//\/ pH264ParamIn->delta_target = pDesc->brcOut.deltaTarget; +//\/ pH264ParamIn->minQp = pDesc->brcOut.minQp; +//\/ pH264ParamIn->maxQp = pDesc->brcOut.maxQp; +//\/ pH264ParamIn->vop_time_increment_resolution = pDesc->brcOut.vopTimeIncrementResolution; +//\/ pH264ParamIn->fixed_vop_time_increment = pDesc->brcOut.fixedVopTimeIncrement; +//\/ pH264ParamIn->Smax = pDesc->brcOut.smax; +//\/ pH264ParamIn->min_base_quality = pDesc->brcOut.minBaseQuality; +//\/ pH264ParamIn->min_framerate = pDesc->brcOut.minFrameRate; +//\/ pH264ParamIn->max_buff_level = pDesc->brcOut.maxBuffLevel; +//\/ pH264ParamIn->first_I_skipped_flag = pDesc->brcOut.firstISkippedFlag; +//\/ pH264ParamIn->init_ts_modulo_old = pDesc->brcOut.initTsModuloOld; + + /*fill h264 short header parameters*/ +//\/ pH264ParamIn->flag_short_header = (t_uint16) ((pDesc->h264Conf.flagShortHeader == TRUE) ? 1 : 0); + pH264ParamIn->frame_width = pDesc->conf.sourceFrameDesc.frame.width; + pH264ParamIn->frame_height = pDesc->conf.sourceFrameDesc.frame.height; + pH264ParamIn->window_width = pDesc->conf.sourceFrameDesc.window.image.width; + pH264ParamIn->window_height = pDesc->conf.sourceFrameDesc.window.image.height; + if (pDesc->conf.isCroppingVectorEnabled == TRUE) + { + pH264ParamIn->window_horizontal_offset = pDesc->croppingVector.offsetX; + pH264ParamIn->window_vertical_offset = pDesc->croppingVector.offsetY; + } + else + { + pH264ParamIn->window_horizontal_offset = pDesc->conf.sourceFrameDesc.window.imageOffset.offsetX; + pH264ParamIn->window_vertical_offset = pDesc->conf.sourceFrameDesc.window.imageOffset.offsetY; + } + +//\/ pH264ParamIn->gob_header_freq = pDesc->h264Conf.gobHeaderFrequency; +//\/ if (pPrev->pictureCodingType != pCur->pictureCodingType && pDesc->h264Conf.gobHeaderFrequency != 0) +//\/ { +//\/ pCur->gobFrameId = (pPrev->gobFrameId + 1) & 0x3; +//\/ } +//\/ +//\/ pH264ParamIn->gob_frame_id = pCur->gobFrameId; +//\/ pH264ParamIn->data_partitioned = (t_uint16) ((pDesc->h264Conf.isDataPartitionedEnable == TRUE) ? 1 : 0); +//\/ pH264ParamIn->reversible_vlc = (t_uint16) ((pDesc->h264Conf.isReversibleVlcEnable == TRUE) ? 1 : 0); +//\/ pH264ParamIn->hec_freq = pDesc->h264Conf.hecFreq; +//\/ pH264ParamIn->modulo_time_base = 0; +//\/ pH264ParamIn->vop_time_increment = 0; +//\/ pH264ParamIn->vp_size_type = pDesc->h264Conf.vpSizeType; +//\/ pH264ParamIn->vp_size_max = pDesc->h264Conf.vpSizeMax; +//\/ pH264ParamIn->vp_bit_size = pDesc->h264Conf.vpBitSize; +//\/ pH264ParamIn->vp_mb_size = pDesc->h264Conf.vpMbSize; + +//\/ SARVESH: Uncomment below statement and check the skipFifo management, Time stamp management + pH264ParamIn->init_me = (t_uint16) ((pCur->pictureNb == 0) ? 1 : 0); + +//\/ +//\/ if +//\/ ( +//\/ pDesc->conf.sourceFrameDesc.window.image.width <= SVA_EC_H264_QCIF_WIDTH +//\/ && pDesc->conf.sourceFrameDesc.window.image.height <= SVA_EC_H264_QCIF_HEIGHT +//\/ && (pDesc->h264Conf.vopTimeIncrementResolution / pDesc->h264Conf.vopTimeIncrement) <= 15 +//\/ ) +//\/ { /* Slimpeg optimized for low resolution/frame rate (improved quality) */ +//\/ pH264ParamIn->me_type = 1; +//\/ } +//\/ else +//\/ { +//\/ if +//\/ ( +//\/ pDesc->conf.sourceFrameDesc.window.image.width >= SVA_EC_H264_VGA_WIDTH +//\/ || pDesc->conf.sourceFrameDesc.window.image.height >= SVA_EC_H264_VGA_HEIGHT +//\/ ) +//\/ { /* Slimpeg optimized for high resolution/frame rate (improved performance) */ +//\/ pH264ParamIn->me_type = 2; +//\/ } +//\/ else +//\/ { /* normal slimpeg */ +//\/ pH264ParamIn->me_type = 0; +//\/ } +//\/ } +//\/ +//\/ pH264ParamIn->vop_fcode_forward = 1; /* not use in SH */ +//\/ if (pDesc->h264Conf.rtypeMode == SVA_RTYPE_MODE_CONSTANT_ZERO) +//\/ { +//\/ pH264ParamIn->rounding_type = 0; +//\/ } +//\/ else if (pDesc->h264Conf.rtypeMode == SVA_RTYPE_MODE_CONSTANT_ONE) +//\/ { +//\/ pH264ParamIn->rounding_type = 1; +//\/ } +//\/ else +//\/ { +//\/ pH264ParamIn->rounding_type = pPrev->roundValue; +//\/ if (pDesc->brcOut.pictureCodingType != 0) +//\/ { +//\/ pH264ParamIn->rounding_type = 1 - pH264ParamIn->rounding_type; +//\/ } +//\/ } +//\/ +//\/ pCur->roundValue = pH264ParamIn->rounding_type; +//\/ pH264ParamIn->intra_refresh_type = (t_uint16) pDesc->h264Conf.irMode; +//\/ pH264ParamIn->air_mb_num = pDesc->h264Conf.airMbNum; +//\/ pH264ParamIn->cir_period_max = pDesc->h264Conf.cirPeriodMax; +//\/ pH264ParamIn->air_thr = pDesc->airThreshold; + for (i = 0; i < 8; i++) + { + if (pDesc->isFlagIntraRequest == TRUE) + { + pH264ParamIn->slice_loss_first_mb[i] = pDesc->intraRequest.sliceIntraFirstMb[i]; + pH264ParamIn->slice_loss_mb_num[i] = pDesc->intraRequest.sliceIntraMbNumber[i]; + } + else + { + pH264ParamIn->slice_loss_first_mb[i] = 0; + pH264ParamIn->slice_loss_mb_num[i] = 0; + } + } + + pDesc->isFlagIntraRequest = FALSE; + + /*shift fifo*/ + if (isPreviousSkip == TRUE) + { + if (isPictureReplay == TRUE) + { + pDesc->skipFifo[1] = pDesc->skipFifo[2]; + } + } + else + { + pDesc->skipFifo[2] = pDesc->skipFifo[1]; + pDesc->skipFifo[1] = pDesc->skipFifo[0]; + } + + pDesc->skipFifo[0] = *pCur; + +/*********************************** H264 ref code part start **************/ +sva_EC_H264_EncodeOneFrame(instanceNum,pParamIn); +//\/ pCur->pictureCodingType = p_img->picture_coding_type;//\/ Sarvesh: TBD + pCur->pictureCodingType = pH264ParamIn->picture_coding_type;//\/ Sarvesh: TBD +/*********************************** H264 ref code part end **************/ + + return(SVA_EC_ALGO_OK); +} + +/****************************************************************************/ +/* NAME: t_sva_ec_algo_error sva_EC_H264_ANNEXB_GetNextHeader( */ +/* t_sva_service_instance_num instanceNum, */ +/* t_sva_ec_algo_header *pHeader, */ +/* t_size *pSizeInBits */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will fill header picture for next picture for SH */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - instanceNum: number of the descriptor to use. */ +/* */ +/* OUT : */ +/* - pHeader: header to write */ +/* - pSizeInBits: size in bits of the header */ +/* */ +/* RETURN: */ +/* t_sva_ec_algo_error */ +/* t.b.d */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ + +/* + * DONE +*/ +PRIVATE t_sva_ec_algo_error sva_EC_H264_ANNEXB_GetNextHeader +( + t_sva_service_instance_num instanceNum, + t_sva_ec_algo_header *pHeader, + t_size *pSizeInBits +) +{ + t_sva_ec_h264_descriptor *pDesc = &h264EncodeDesc[instanceNum]; +//\/ t_sva_ec_save *pCur = &pDesc->current; + t_uint8 *pHeaderData = (t_uint8 *) pHeader; + t_uint16 width = pDesc->conf.sourceFrameDesc.window.image.width; + t_uint16 height = pDesc->conf.sourceFrameDesc.window.image.height; +//\/ t_uint8 temporalReferenceMsb; +//\/ t_uint8 temporalReferenceLsb; +//\/ t_uint8 sourceFormat; + + HCL_ASSERT(pHeader != NULL); + HCL_ASSERT(pSizeInBits != NULL); + HCL_ASSERT(pHeaderData != NULL); + + /*compute intermediate parameters*/ +//\/ temporalReferenceMsb = (t_uint8) ((pCur->temporalSh.tr & 0xc0) >> 6); +//\/ temporalReferenceLsb = (t_uint8) ((pCur->temporalSh.tr & 0x3f) << 2); + + + if (width == SVA_EC_H264_SQCIF_WIDTH && height == SVA_EC_H264_SQCIF_HEIGHT) + { +//\/ sourceFormat = SVA_EC_H264_ANNEXB_SOURCE_FORMAT_SQCIF; + } + else if (width == SVA_EC_H264_QCIF_WIDTH && height == SVA_EC_H264_QCIF_HEIGHT) + { +//\/ sourceFormat = SVA_EC_H264_ANNEXB_SOURCE_FORMAT_QCIF; + } + else if (width == SVA_EC_H264_CIF_WIDTH && height == SVA_EC_H264_CIF_HEIGHT) + { +//\/ sourceFormat = SVA_EC_H264_ANNEXB_SOURCE_FORMAT_CIF; + } + else if (width == SVA_EC_H264_CIF4_WIDTH && height == SVA_EC_H264_CIF4_HEIGHT) + { +//\/ sourceFormat = SVA_EC_H264_ANNEXB_SOURCE_FORMAT_CIF4; + } + else if (width == SVA_EC_H264_CIF16_WIDTH && height == SVA_EC_H264_CIF16_HEIGHT) + { +//\/ sourceFormat = SVA_EC_H264_ANNEXB_SOURCE_FORMAT_CIF16; + } + else if (width == SVA_EC_H264_VGA_WIDTH && height == SVA_EC_H264_VGA_HEIGHT) + { +//\/ sourceFormat = SVA_EC_H264_ANNEXB_SOURCE_FORMAT_VGA; + } + else if (width == SVA_EC_H264_MB1_WIDTH && height == SVA_EC_H264_MB1_HEIGHT) + { +//\/ sourceFormat = SVA_EC_H264_ANNEXB_SOURCE_FORMAT_MB1; + } + else + { + return(SVA_EC_H264_PARAM_ERROR); + } + + /*fill header*/ + pHeaderData[0] = 0x00; +//\/ pHeaderData[1] = 0x00; +//\/ pHeaderData[2] = (t_uint8) (0x80 + temporalReferenceMsb); +//\/ pHeaderData[3] = (t_uint8) (0x02 + temporalReferenceLsb); +//\/ pHeaderData[4] = (t_uint8) ((sourceFormat << 2) + (pCur->pictureCodingType << 1)); +//\/ pHeaderData[5] = 0; + + /*set header size in bits*/ +//\/ *pSizeInBits = 43; + *pSizeInBits = 8; + + return(SVA_EC_ALGO_OK); +} + +/****************************************************************************/ +/* NAME: t_size sva_EC_H264_ANNEXB_GetMaxHeaderSize( */ +/* t_sva_service_instance_num instanceNum */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will return max number of bytes a header can be. Thus */ +/* encode part will allocate enought space for such header. This is for*/ +/* a short header stream. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - instanceNum: number of the descriptor to use. */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_size */ +/* t.b.d */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ + +/* + * DONE +*/ +PRIVATE t_size sva_EC_H264_ANNEXB_GetMaxHeaderSize(t_sva_service_instance_num instanceNum) +{ + (void) instanceNum; + + return(SVA_EC_H264_ANNEXB_MAX_HEADER_SIZE); +} + +/****************************************************************************/ +/* NAME: t_sva_ec_algo_error sva_EC_H264_ANNEXB_UpdateVideoEncoderParams( */ +/* t_sva_service_instance_num instanceNum, */ +/* t_sva_update_cmd_type updateCmdType, */ +/* t_sva_video_encoder_param_id paramId, */ +/* t_uint32 param */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will update dynamic parameters for short header. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - instanceNum: number of the descriptor to use. */ +/* - updateCmdType: command to apply to the h264 Encode */ +/* - paramId: Parameter to update */ +/* - param: parameter for the updateCmdType */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_ec_algo_error */ +/* t.b.d */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ + +/* + * TO DO : all + */ +PRIVATE t_sva_ec_algo_error sva_EC_H264_ANNEXB_UpdateVideoEncoderParams //\/ Sarvesh: Revove this/Check this +( + t_sva_service_instance_num instanceNum, + t_sva_update_cmd_type updateCmdType, + t_sva_video_encoder_param_id paramId, + t_uint32 param +) +{ + t_sva_ec_h264_descriptor *pDesc = &h264EncodeDesc[instanceNum]; + t_sva_intra_request *pIntraRequest; + t_sva_ec_algo_error status = SVA_EC_ALGO_OK; + + /*take command into account for next configuration*/ + switch (paramId) + { + case SVA_ENCODER_FRAME_RATE: + pDesc->nextFrameRate = (t_uint16) param; + break; + + case SVA_ENCODER_HEADER_FREQUENCY: +//\/ pDesc->h264NextConf.gobHeaderFrequency = (t_uint16) param; + status = SVA_EC_H264_CMD_NOT_SUPPORTED; + break; + + case SVA_ENCODER_AIR_MB_NUM: + pDesc->h264NextConf.air_mb_num = (t_uint16) param; + break; + + case SVA_ENCODER_CIR_PERIOD: +//\/ pDesc->h264NextConf.cirPeriodMax = (t_uint16) param; + status = SVA_EC_H264_CMD_NOT_SUPPORTED; + break; + + case SVA_ENCODER_REQUEST_INTRA: + /*full intra picture refresh is handle in brc code*/ + pIntraRequest = (t_sva_intra_request *) param; + if (pIntraRequest->isIntraFullPicture == FALSE) + { + pDesc->isNextConfRequiredIntraResquest = TRUE; + pDesc->intraRequest = *pIntraRequest; + } + else + { + status = SVA_EC_H264_CMD_NOT_SUPPORTED; + } + break; + + default: + status = SVA_EC_H264_CMD_NOT_SUPPORTED; + break; + } + + return(status); +} + +/****************************************************************************/ +/* NAME: t_sva_fw_features sva_EC_H264_GetFeatures( */ +/* t_sva_service_instance_num instanceNum */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will return features need by h264 algorithm. It will */ +/* also get brc features needed. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - instanceNum: number of the descriptor to use. */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_fw_features */ +/* features need by algo + brc */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ + +/****************************************************************************/ +PUBLIC t_sva_fw_features sva_EC_H264_GetFeatures(t_sva_service_instance_num instanceNum) +{ +//\/ t_sva_ec_h264_descriptor *pDesc = &h264EncodeDesc[instanceNum]; + t_sva_fw_features res = SVA_FW_FEAT_H264_ENCODER; + +#if defined(INC_BRC_MODULE) /* if INC_BRC_MODULE */ + /* First get brc features need*/ + res = sva_EC_BRC_GetFeatures(instanceNum); +#endif /* End defined(INC_BRC_MODULE) */ + +//\/ /* then add h264 encoder features needs */ +//\/ if (pDesc->h264Conf.flagShortHeader == TRUE) +//\/ { +//\/ res += SVA_FW_FEAT_H264_SH_ENCODER; +//\/ } +//\/ else +//\/ { +//\/ res += SVA_FW_FEAT_H264_SP_ENCODER; +//\/ } + + /* if size is greater than qcif add SVA_FW_FEAT_H264_DECODER_CIF_VGA */ +//\/ if +//\/ ( +//\/ pDesc->conf.sourceFrameDesc.window.image.height > SVA_EC_H264_QCIF_HEIGHT +//\/ || pDesc->conf.sourceFrameDesc.window.image.width > SVA_EC_H264_QCIF_WIDTH +//\/ ) +//\/ { +//\/ res += SVA_FW_FEAT_H264_DECODER_CIF_VGA; +//\/ } + + /* if AIR or/and CIR features then ask them */ +//\/ if (pDesc->h264Conf.irMode != SVA_AIR_DISABLED_CIR_DISABLED) +//\/ { +//\/ res += SVA_FW_FEAT_ENCODER_AIR_CIR; +//\/ } + + return(res); +} + +/*! + ************************************************************************ + * \brief + * FillParameterSetStructures: extracts info from global variables and + * generates a picture and sequence parameter set structure + * + * \param sps + * Sequence parameter set to be filled + * \param pps + * Picture parameter set to be filled + * \par + * Function reads all kinds of values from several global variables, + * including pDesc->h264Conf. and image-> and fills in the sps and pps. Many + * values are current hard-coded to defaults, especially most of the + * VUI stuff. Currently, the sps and pps structures are fixed length + * This mode is not supported. Hence, the function does not need to + * allocate memory for the FMOmap, the pointer slice_group_id is + * always NULL. + * + * \par + * Limitations + * Currently, the encoder does not support multiple parameter sets, + * primarily because the config file does not support it. Hence the + * If one day multiple parameter sets are implemented, it would + * make sense to break this function into two, one for the picture and + * one for the sequence. + * The following pps and sps elements seem not to be used in the encoder + * or decoder and, hence, a guessed default value is conveyed: + * + * pps->num_ref_idx_l1_active_minus1 = p_img->num_ref_pic_active_bwd_minus1; + * pps->chroma_qp_index_offset = 0; + * sps->required_frame_num_update_behaviour_flag = FALSE; + * sps->direct_temporal_constrained_flag = FALSE; + * + * \par + * Regarding the QP + * The previous software versions coded the absolute QP only in the + * slice header. This is kept, and the offset in the PPS is coded + * even if we could save bits by intelligently using this field. + * + ************************************************************************ + */ + +/*\/ Sarvesh: test application/Utils */ +//\/void FillParameterSetStructures (t_p_seq_parameter_set_rbsp p_sps, +//\/ t_p_pic_parameter_set_rbsp p_pps) +PRIVATE t_sva_ec_algo_error FillParameterSetStructures(t_sva_service_instance_num instanceNum) +{ + t_sva_ec_h264_descriptor *pDesc = &h264EncodeDesc[instanceNum]; + t_p_pic_parameter_set_rbsp p_pps = &pDesc->active_pps;//\/ + t_p_seq_parameter_set_rbsp p_sps = &pDesc->active_sps;//\/ + t_p_ImageParameters p_img = &pDesc->images;//\/ + t_uint32 i; + + /* NZ */ + t_sint16 bit_rate_scale=0; + t_uint32 bit_rate_value=0; + t_sint16 cpb_size_scale=0; + t_uint32 cpb_size_value=0; + t_uint32 cpb_size; + + t_uint32 MaxCPB; + /* NZ */ + + /* ************************************************************************* */ + /* Sequence Parameter Set */ + /* ************************************************************************* */ + HCL_ASSERT (p_sps != NULL); + HCL_ASSERT (p_pps != NULL); + /* Profile and Level should be calculated using the info from the config */ + /* file. Calculation is hidden in IndetifyProfile() and IdentifyLevel() */ + p_sps->profile_idc = pDesc->h264Conf.ProfileIDC; + p_sps->level_idc = p_img->level_idc; + + /* needs to be set according to profile */ + p_sps->constrained_set0_flag = 0; + p_sps->constrained_set1_flag = 0; + p_sps->constrained_set2_flag = 0; + p_sps->constrained_set3_flag = p_img->constraint_set3_flag; + + p_sps->seq_parameter_set_id = p_img->seq_parameter_set_idc; + + /* Fidelity Range Extensions stuff */ + p_sps->bit_depth_luma_minus8 = 0; + p_sps->bit_depth_chroma_minus8 = 0; + + /*! POC stuff: */ + p_sps->log2_max_frame_num_minus4 = log2_max_frame_num_minus4; + p_sps->log2_max_pic_order_cnt_lsb_minus4 = log2_max_pic_order_cnt_lsb_minus4; + p_sps->pic_order_cnt_type = pDesc->h264Conf.pic_order_cnt_type; + p_sps->num_ref_frames_in_pic_order_cnt_cycle = 1; + p_sps->offset_for_non_ref_pic = 0; + + for (i=0; inum_ref_frames_in_pic_order_cnt_cycle; i++) + { + p_sps->offset_for_ref_frame[i] = 2; + } + /* End of POC stuff */ + + + /*required_frame_num_update_behaviour_flag hardcoded to zero */ + p_sps->gaps_in_frame_num_value_allowed_flag = FALSE; /* double check */ + + /* Picture size, finally a simple one :-) */ +//\/ p_sps->pic_width_in_mbs_minus1 = ((pDesc->h264Conf.frame_width)/16) -1; +//\/ p_sps->pic_height_in_map_units_minus1 = (((pDesc->h264Conf.frame_height)/16)) - 1; + p_sps->pic_width_in_mbs_minus1 = ((pDesc->conf.sourceFrameDesc.frame.width)/16) -1; + p_sps->pic_height_in_map_units_minus1 = (((pDesc->conf.sourceFrameDesc.frame.height)/16)) - 1; + + if (pDesc->h264Conf.HrdSendMessages) + p_sps->vui_parameters_present_flag = 1; + else + p_sps->vui_parameters_present_flag = 0; + + /* NZ */ + if (p_sps->vui_parameters_present_flag) { + MaxCPB = getMaxCPB(p_img->level_idc, p_img->constraint_set3_flag); + p_sps->vui_seq_parameters.aspect_ratio_info_present_flag = pDesc->h264Conf.aspect_ratio_info_present_flag; + if (pDesc->h264Conf.aspect_ratio_info_present_flag) { + p_sps->vui_seq_parameters.aspect_ratio_idc = pDesc->h264Conf.aspect_ratio_idc; + if (pDesc->h264Conf.aspect_ratio_idc == EXTENDED_SAR) { + p_sps->vui_seq_parameters.sar_width = (t_uint16)pDesc->h264Conf.sar_width; + p_sps->vui_seq_parameters.sar_height = (t_uint16)pDesc->h264Conf.sar_height; + } + } + + p_sps->vui_seq_parameters.overscan_info_present_flag = 0; + p_sps->vui_seq_parameters.video_signal_type_present_flag = pDesc->h264Conf.video_signal_type_present_flag; + if (pDesc->h264Conf.video_signal_type_present_flag) { + p_sps->vui_seq_parameters.video_format = pDesc->h264Conf.video_format; + p_sps->vui_seq_parameters.video_full_range_flag = pDesc->h264Conf.video_full_range_flag; + p_sps->vui_seq_parameters.colour_description_present_flag = pDesc->h264Conf.colour_description_present_flag; + if (pDesc->h264Conf.colour_description_present_flag) { + p_sps->vui_seq_parameters.colour_primaries = pDesc->h264Conf.colour_primaries; + p_sps->vui_seq_parameters.transfer_characteristics = pDesc->h264Conf.transfer_characteristics; + p_sps->vui_seq_parameters.matrix_coefficients = pDesc->h264Conf.matrix_coefficients; + } + } + + p_sps->vui_seq_parameters.chroma_location_info_present_flag = 0; + + p_sps->vui_seq_parameters.timing_info_present_flag =1; + p_sps->vui_seq_parameters.num_units_in_tick = 1000; + p_sps->vui_seq_parameters.time_scale = (pDesc->h264Conf.FrameRate*1000 )/1024; + p_sps->vui_seq_parameters.fixed_frame_rate_flag =0; + + /* get bit_rate_scale and bit_rate_value from bitrate input from config file (BRC) */ + bit_rate_value = pDesc->h264Conf.bit_rate; + bit_rate_scale =0; + while (!(bit_rate_value & (t_uint32)0x01)) { + bit_rate_value = bit_rate_value >> 1; + bit_rate_scale++; + } + bit_rate_value--; + bit_rate_scale -=6; + + /* patch to avoid negs for bit_rate_scale */ + if (bit_rate_scale<0) { + bit_rate_scale = 0; + bit_rate_value = (t_sint32) (pDesc->h264Conf.bit_rate / 64) -1; + } + + /* NZ: patch for u_v() syntax element limit: it cannot write a more than 32 bit lenght bitpatter; + Limiting the value to be u_v()-coded to 65534 the problem is avoided. + This will limit the precision of the bitrate value coded in the stream */ + if (bit_rate_value > 65534) { + while (bit_rate_value > 65534) { + bit_rate_value /= 2; + bit_rate_scale++; + } + bit_rate_value--; /* NZ: This "--" is to code a value minor than the wished one (ie to approximate it by defeats). + If you want to approximate it by excess you can safely comment this line */ + } + + if (pDesc->h264Conf.HrdSendMessages < 2) + p_sps->vui_seq_parameters.nal_hrd_parameters_present_flag = 0; + else { + p_sps->vui_seq_parameters.nal_hrd_parameters_present_flag = 1; + + /* HRD parameters for all nal units */ + /* get cpb_size_scale and cpb_size_value from level/profile */ + if (pDesc->h264Conf.CpbBufferSize > MaxCPB*1200) { +//\/ printf("\n *** WARNING !!! ***"); +//\/ printf("\nCPB size inserted for HRD NAL units overcomes the limit for this level:"); +//\/ printf("(%ld > %ld)", pDesc->h264Conf.CpbBufferSize, MaxCPB*1200 ); +//\/ printf("\nto avoid compliancy problem the value will be clipped to max defined for this level: %ld", MaxCPB*1200); + cpb_size_value = MaxCPB*1200; + } + else + cpb_size_value = pDesc->h264Conf.CpbBufferSize; + + cpb_size = cpb_size_value; + cpb_size_scale = 0; + while (!(cpb_size_value & (t_uint32)0x01)) { + cpb_size_value = cpb_size_value >> 1; + cpb_size_scale++; + } + cpb_size_value--; + cpb_size_scale -=4; + /* patch to avoid negs for cpb_size_scale */ + if (cpb_size_scale<0) { + cpb_size_scale = 0; + cpb_size_value = (cpb_size / 16) -1; + } + /* NZ: patch for u_v() syntax element limit: it cannot write a more than 32 bit lenght bitpatter; + Limiting the value to be u_v()-coded to 65534 the problem is avoided. + This will limit the precision of the bitrate value coded in the stream */ + if (cpb_size_value > 65534) { + while (cpb_size_value > 65534) { + cpb_size_value /= 2; + cpb_size_scale++; + } + cpb_size_value--; /* NZ: This "--" is to code a value minor than the wished one (ie to approximate it by defeats). + If you want to approximate it by excess you can safely comment this line */ + } + + /* now set up the value in sps struct */ + p_sps->vui_seq_parameters.nal_hrd_parameters.cpb_cnt_minus1 = 0; + p_sps->vui_seq_parameters.nal_hrd_parameters.bit_rate_scale = bit_rate_scale; + p_sps->vui_seq_parameters.nal_hrd_parameters.cpb_size_scale = cpb_size_scale; + for (i=0; i vui_seq_parameters.nal_hrd_parameters.cpb_cnt_minus1+1; i++) { + p_sps->vui_seq_parameters.nal_hrd_parameters.bit_rate_value_minus1[i] = bit_rate_value; + p_sps->vui_seq_parameters.nal_hrd_parameters.cpb_size_value_minus1[i] = cpb_size_value; + p_sps->vui_seq_parameters.nal_hrd_parameters.cbr_flag[i] = 1; + } + p_sps->vui_seq_parameters.nal_hrd_parameters.initial_cpb_removal_delay_length_minus1 = SEI_INITIAL_CPB_REMOVAL_DELAY_BITS-1; + p_sps->vui_seq_parameters.nal_hrd_parameters.cpb_removal_delay_length_minus1 = SEI_CPB_REMOVAL_DELAY_BITS-1; + p_sps->vui_seq_parameters.nal_hrd_parameters.dpb_output_delay_length_minus1 = SEI_DPB_REMOVAL_DELAY_BITS-1; + p_sps->vui_seq_parameters.nal_hrd_parameters.time_offset_length = 0; + /* END of HRD parameters for all nal units */ + } + + if (pDesc->h264Conf.HrdSendMessages < 2) + p_sps->vui_seq_parameters.vcl_hrd_parameters_present_flag = 0; + else { + p_sps->vui_seq_parameters.vcl_hrd_parameters_present_flag = 1; + + /* HRD parameters for vcl nal units ONLY*/ + if (pDesc->h264Conf.CpbBufferSize > MaxCPB*1000) { +//\/ printf("\n *** WARNING !!! ***"); +//\/ printf("\nCPB size inserted for VCL NAL units overcomes the limit for this level:"); +//\/ printf("(%ld > %ld)", pDesc->h264Conf.CpbBufferSize, MaxCPB*1000); +//\/ printf("\nto avoid compliancy problem the value will be clipped to max defined for this level: %ld\n\n", MaxCPB*1000); + cpb_size_value = MaxCPB*1000; + } + else + cpb_size_value = pDesc->h264Conf.CpbBufferSize; + + cpb_size = cpb_size_value; + cpb_size_scale =0; + while (!(cpb_size_value & (t_uint32)0x01)) { + cpb_size_value = cpb_size_value >> 1; + cpb_size_scale++; + } + cpb_size_value--; + cpb_size_scale -=4; + /* patch to avoid negs for cpb_size_scale */ + if (cpb_size_scale<0) { + cpb_size_scale = 0; + cpb_size_value = (cpb_size / 16) -1; + } + /* NZ: patch for u_v() syntax element limit: it cannot write a more than 32 bit lenght bitpatter; + Limiting the value to be u_v()-coded to 65534 the problem is avoided. + This will limit the precision of the bitrate value coded in the stream */ + if (cpb_size_value > 65534) { + while (cpb_size_value > 65534) { + cpb_size_value /= 2; + cpb_size_scale++; + } + cpb_size_value--; /* NZ: This "--" is to code a value minor than the wished one (ie to approximate it by defeats). + If you want to approximate it by excess you can safely comment this line */ + } + + p_sps->vui_seq_parameters.vcl_hrd_parameters.cpb_cnt_minus1 = 0; + p_sps->vui_seq_parameters.vcl_hrd_parameters.bit_rate_scale = bit_rate_scale; + p_sps->vui_seq_parameters.vcl_hrd_parameters.cpb_size_scale = cpb_size_scale; + for (i=0; i vui_seq_parameters.vcl_hrd_parameters.cpb_cnt_minus1+1; i++) { + p_sps->vui_seq_parameters.vcl_hrd_parameters.bit_rate_value_minus1[i] = bit_rate_value; + p_sps->vui_seq_parameters.vcl_hrd_parameters.cpb_size_value_minus1[i] = cpb_size_value; + p_sps->vui_seq_parameters.vcl_hrd_parameters.cbr_flag[i] = 1; + } + + p_sps->vui_seq_parameters.vcl_hrd_parameters.initial_cpb_removal_delay_length_minus1 = SEI_INITIAL_CPB_REMOVAL_DELAY_BITS-1; + p_sps->vui_seq_parameters.vcl_hrd_parameters.cpb_removal_delay_length_minus1 = SEI_CPB_REMOVAL_DELAY_BITS-1; + p_sps->vui_seq_parameters.vcl_hrd_parameters.dpb_output_delay_length_minus1 = SEI_DPB_REMOVAL_DELAY_BITS-1; + p_sps->vui_seq_parameters.vcl_hrd_parameters.time_offset_length = 0; + /* end of HRD parameters for vcl nal units ONLY*/ + } + + if ((p_sps->vui_seq_parameters.nal_hrd_parameters_present_flag == 1) && (p_sps->vui_seq_parameters.vcl_hrd_parameters_present_flag == 1)) + p_sps->vui_seq_parameters.low_delay_hrd_flag = 1; + + p_sps->vui_seq_parameters.pic_struct_present_flag = PIC_STRUCT_PRESENT_FLAG; + p_sps->vui_seq_parameters.bitstream_restriction_flag = BITSTREAM_RESTRICTION_FLAG; +#if BITSTREAM_RESTRICTION_FLAG == 1 + p_sps->vui_seq_parameters.motion_vectors_over_pic_boundaries_flag = 1; + p_sps->vui_seq_parameters.max_bytes_per_pic_denom = 0; + p_sps->vui_seq_parameters.max_bits_per_mb_denom = 0; + p_sps->vui_seq_parameters.log2_max_mv_length_vertical = 16; + p_sps->vui_seq_parameters.log2_max_mv_length_horizontal = 16; + p_sps->vui_seq_parameters.num_reorder_frames = 0; + p_sps->vui_seq_parameters.max_dec_frame_buffering = 1; +#endif + + } + /* NZ */ + + /* ************************************************************************* */ + /* Picture Parameter Set */ + /* ************************************************************************* */ + + p_pps->seq_parameter_set_id = p_sps->seq_parameter_set_id; + p_pps->entropy_coding_mode_flag = 0; + for(i=0; i<8; i++) + p_sps->seq_scaling_list_present_flag[i] = 0; + + p_pps->pic_scaling_matrix_present_flag = 0; + for(i=0; i<8; i++) + p_pps->pic_scaling_list_present_flag[i] = 0; + + + /* JVT-Fxxx (by Stephan Wenger, make this flag unconditional */ + p_pps->pic_init_qs_minus26 = 0; + p_pps->chroma_qp_index_offset = pDesc->h264Conf.chroma_qp_index_offset; /* double check: is this chroma fidelity thing already implemented??? */ + p_pps->deblocking_filter_control_present_flag = DEBLOCKING_FILTER_CONTROL_PRESENT_FLAG; + p_pps->constrained_intra_pred_flag = pDesc->h264Conf.use_constrained_intra_flag; + p_pps->redundant_pic_cnt_present_flag = 0; + + p_sps->frame_cropping_flag = FALSE; + p_sps->frame_cropping_rect_left_offset = 0; + p_sps->frame_cropping_rect_right_offset = 0; + p_sps->frame_cropping_rect_top_offset = 0; + p_sps->frame_cropping_rect_bottom_offset = 0; + + return(SVA_EC_ALGO_OK); +} + +/*! + ************************************************************************************* + * \brief + * Returns max CPB size defined for given level + * \return + * Max CPB size defined for given level + * + ************************************************************************************* + */ + +t_uint32 getMaxCPB(t_uint16 level_idc, t_uint16 constraint_set3_flag) +{ + t_uint16 index = getIndexFromLevel(level_idc, constraint_set3_flag); + return LevelLimits[index][4]; +} + +/*! + *********************************************************************** + * \brief + * Initializes the Image structure with appropriate parameters. + * \par Input: + * Input Parameters struct inp_par *inp + * \par Output: + * Image Parameters struct img_par *p_img + *********************************************************************** + */ + +PRIVATE t_sva_ec_algo_error init_img(t_sva_service_instance_num instanceNum) +{ + t_sva_ec_h264_descriptor *pDesc = &h264EncodeDesc[instanceNum]; + t_p_ImageParameters p_img = &pDesc->images;//\/ + +//\/ p_img->PicWidthInMbs = (pDesc->h264Conf.frame_width)/MB_BLOCK_SIZE; +//\/ p_img->PicHeightInMbs = (pDesc->h264Conf.frame_height)/MB_BLOCK_SIZE; + p_img->PicWidthInMbs = (pDesc->conf.sourceFrameDesc.frame.width)/MB_BLOCK_SIZE; + p_img->PicHeightInMbs = (pDesc->conf.sourceFrameDesc.frame.height)/MB_BLOCK_SIZE; + p_img->PicSizeInMbs = p_img->PicWidthInMbs * p_img->PicHeightInMbs; + p_img->Skip_Current = 0; + p_img->Skip_Next = 0; + + /* first slice is always INTRA.... */ + p_img->picture_coding_type = I_SLICE; + + /* reset counter for actually coded picture */ + p_img->CodedPictureCounter = 0; + + p_img->pic_counter = 0; + p_img->totskipped = 0; + + p_img->imagetype_next = I_SLICE; /* the type of the frame we are going to give to "BRC_InitPict" */ + + /* init value for timestamps */ + p_img->timestamp = 0; + p_img->timestamp_old = -1; + p_img->delta_ts = 0; + + /* reset counter for seq_parameter_set_idc (used in multiple SPS case (dynamic bitrate/framerate)) */ + p_img->seq_parameter_set_idc = 0; + + p_img->NonVCLNALUSize = 0; + + p_img->SeinitialQP = 35; /* NZ: Hardcoded to a fix value for the time being. Removed from input struct on 07/June/2007 */ + + return(SVA_EC_ALGO_OK); +} + +/****************************************************************************/ +/* NAME: t_sva_ec_algo_error sva_EC_H264_GenerateBitStreamDataUnits( */ +/* t_sva_service_instance_num instanceNum, */ +/* t_sva_data_unit_type data_unit_type, */ +/* t_sva_data_unit_buffer *pOutBuf */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will generate the data requested data streams */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - instanceNum: number of the descriptor to use. */ +/* - data_unit_type: Type of data unit need to be generated */ +/* */ +/* OUT : */ +/* - pOutBuf : Pointer to output buffer containing requested data stream */ +/* */ +/* RETURN: */ +/* t_sva_ec_algo_error */ +/* t.b.d */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ + +/*\/ Sarvesh: Test application */ +//\/t_sint32 start_sequence(t_sva_service_instance_num instanceNum, +//\/ const t_sva_video_encoder_configuration *pConf, t_sva_sps_pps_output_buff pOutBuf) + +PUBLIC t_sva_ec_algo_error sva_EC_H264_GenerateBitStreamDataUnits(t_sva_service_instance_num instanceNum, + t_sva_data_unit_type data_unit_type, t_sva_data_unit_buffer *pOutBuf) +{ +//\/ t_sint32 len=0; +//\/ t_NALU *nalu; + t_sva_ec_h264_descriptor *pDesc = &h264EncodeDesc[instanceNum]; + t_p_ImageParameters p_img = &pDesc->images;//\/ + + HCL_ASSERT(pOutBuf != NULL); + HCL_ASSERT(pOutBuf->pOBuf != NULL); + pOutBuf->byteCount = 0; //\/ Initialize the numebr of bytes written + +//\/ WriteNALU = WriteAnnexbNALU; + + /*! As a sequence header, here we write the both sequence and picture */ + /*! parameter sets. As soon as IDR is implemented, this should go to the */ + /*! IDR part, as both parsets have to be transmitted as part of an IDR. */ + /*! An alterbative may be to consider this function the IDR start function. */ + + /* Generate the NON VLC NAL units as requested by the user */ + switch (data_unit_type) + { + case SVA_DATA_SPS_NAL_UNIT: + /* write first SPS */ +#if 0 /* if of Don't take NON VCL NALU size */ + WriteSPS(instanceNum, pOutBuf); /* HCL: Part of HCL */ +#else /* else of Don't take NON VCL NALU size */ + p_img->NonVCLNALUSize += WriteSPS(instanceNum, pOutBuf); /* HCL: Part of HCL */ +#endif /* endif of Don't take NON VCL NALU size */ + /* Generate SPS NAL Unit */ +//\/ nalu = NULL; +//\/ nalu = GenerateSeq_parameter_set_NALU (instanceNum); +//\/ len += WriteNALU (nalu, pOutBuf); +//\/ FreeNALU (nalu); + break; + + case SVA_DATA_PPS_NAL_UNIT: + /* write first PPS */ +#if 0 /* if of Don't take NON VCL NALU size */ + WritePPS(instanceNum, pOutBuf); /* HCL: Part of HCL */ +#else /* else of Don't take NON VCL NALU size */ + p_img->NonVCLNALUSize += WritePPS(instanceNum, pOutBuf); /* HCL: Part of HCL */ +#endif /* endif of Don't take NON VCL NALU size */ + /* Generate SPS NAL Unit */ +//\/ nalu = NULL; +//\/ nalu = GeneratePic_parameter_set_NALU (instanceNum); +//\/ len += WriteNALU (nalu, pOutBuf); +//\/ FreeNALU (nalu); + break; + + case SVA_DATA_SPS_AND_PPS_NAL_UNIT: +#if 0 /* if of Don't take NON VCL NALU size */ + /* write first SPS */ + WriteSPS(instanceNum, pOutBuf); /* HCL: Part of HCL */ + /* write first PPS */ + WritePPS(instanceNum, pOutBuf); /* HCL: Part of HCL */ +#else /* else of Don't take NON VCL NALU size */ + /* write first SPS */ + p_img->NonVCLNALUSize += WriteSPS(instanceNum, pOutBuf); /* HCL: Part of HCL */ + /* write first PPS */ + p_img->NonVCLNALUSize += WritePPS(instanceNum, pOutBuf); /* HCL: Part of HCL */ +#endif /* endif of Don't take NON VCL NALU size */ + /* Generate both SPS and PPS NAL Unit */ +//\/ nalu = NULL; +//\/ nalu = GenerateSeq_parameter_set_NALU (instanceNum); +//\/ len += WriteNALU (nalu, pOutBuf); +//\/ FreeNALU (nalu); +//\/ nalu = NULL; +//\/ nalu = GeneratePic_parameter_set_NALU (instanceNum); +//\/ len += WriteNALU (nalu, pOutBuf); +//\/ FreeNALU (nalu); + break; + + default: + break; + } + +//\/ stats->bit_ctr_parametersets_n = len; + return SVA_EC_ALGO_OK;//\/0; +} + +/*! + ******************************************************************************************** + * \brief + * Writes a NALU to the Annex B Byte Stream + * + * \return + * number of bits written + * + ******************************************************************************************** +*/ + +t_sint32 WriteAnnexbNALU (t_p_NALU p_nalu, t_sva_data_unit_buffer *pOutBuf) +{ + t_sint32 BitsWritten = 0; + t_uint32 i = 0; + + HCL_ASSERT (p_nalu != NULL); + HCL_ASSERT (p_nalu->forbidden_bit == 0); + HCL_ASSERT (p_nalu->startcodeprefix_len == 3 || p_nalu->startcodeprefix_len == 4); + + if (p_nalu->startcodeprefix_len > 3) + { + pOutBuf->pOBuf[pOutBuf->byteCount++] = 0; + BitsWritten =+ 8; + } + pOutBuf->pOBuf[pOutBuf->byteCount++] = 0; + pOutBuf->pOBuf[pOutBuf->byteCount++] = 0; + pOutBuf->pOBuf[pOutBuf->byteCount++] = 1; + BitsWritten += 24; + + for (i = 0; i < p_nalu->len; i++) + { + pOutBuf->pOBuf[pOutBuf->byteCount++] = p_nalu->buf[i]; + } + BitsWritten += p_nalu->len * 8; + + return BitsWritten; +} + +/*! + ******************************************************************************************** + * \brief + * Copy a NALU to the Annex B Byte Stream + * DO NOT INSERT header of AnnexB, only copy bitstream data (header inserted in hamac part ) + * \return + * number of bits written + * + ******************************************************************************************** +*/ + +t_sint32 CopyAnnexbNALU (t_p_NALU p_nalu, t_sva_data_unit_buffer *pOutBuf) +{ + t_sint32 BitsWritten = 0; + t_uint32 i = 0; + + HCL_ASSERT (p_nalu != NULL); + + for (i = 0; i < p_nalu->len; i++) + { + pOutBuf->pOBuf[pOutBuf->byteCount++] = p_nalu->buf[i]; + } + BitsWritten += p_nalu->len * 8; + + return BitsWritten; +} + +/*! +************************************************************************************* +* \brief +* t_sint32 GenerateSeq_parameter_set_NALU (); +* +* \note +* Uses the global variables through FillParameterSetStructures() +* +* \return +* A NALU containing the Sequence ParameterSet +* +************************************************************************************* +*/ + +void GenerateSeq_parameter_set_NALU (t_sva_service_instance_num instanceNum, t_p_NALU nalu) +{ + t_sva_ec_h264_descriptor *pDesc = &h264EncodeDesc[instanceNum]; + t_p_seq_parameter_set_rbsp p_active_sps = &pDesc->active_sps;//\/ + t_sint32 RBSPlen = 0; + t_uint16 len; + + HCL_ASSERT (nalu != NULL); + + nalu->forbidden_bit = 0; + nalu->nal_reference_idc = NALU_PRIORITY_HIGHEST; + nalu->nal_unit_type = NALU_TYPE_SPS; + nalu->startcodeprefix_len = 4; + nalu->buf[0] = (t_uint8) + (nalu->forbidden_bit << 7 | + nalu->nal_reference_idc << 5 | + nalu->nal_unit_type); + + RBSPlen = GenerateSeq_parameter_set_rbsp (p_active_sps, &(nalu->buf[1]) ); + + len = (t_uint16) (1 + RBSPtoEBSP (& (nalu->buf[1]), 0, RBSPlen, 0)); + + nalu->len = len; +} + +/*! +************************************************************************************* +* \brief +* void GeneratePic_parameter_set_NALU (); +* +* \note +* Uses the global variables through FillParameterSetStructures() +* +* \return +* A NALU containing the Picture Parameter Set +* +************************************************************************************* +*/ + +void GeneratePic_parameter_set_NALU (t_sva_service_instance_num instanceNum, t_p_NALU nalu) +{ + t_sva_ec_h264_descriptor *pDesc = &h264EncodeDesc[instanceNum]; + t_p_pic_parameter_set_rbsp p_active_pps = &pDesc->active_pps;//\/ + t_sint32 RBSPlen = 0; + t_uint16 len; + + HCL_ASSERT (nalu != NULL); + + nalu->forbidden_bit = 0; + nalu->nal_reference_idc = NALU_PRIORITY_HIGHEST; + nalu->nal_unit_type = NALU_TYPE_PPS; + nalu->startcodeprefix_len = 4; + nalu->buf[0] = (t_uint8) + (nalu->forbidden_bit << 7 | + nalu->nal_reference_idc << 5 | + nalu->nal_unit_type); + + RBSPlen = GeneratePic_parameter_set_rbsp (instanceNum, p_active_pps, &(nalu->buf[1])); + + len = (t_uint16)(1 + RBSPtoEBSP (& (nalu->buf[1]), 0, RBSPlen, 0)); + + nalu->len = len; +} + +/*! + ************************************************************************************* + * \brief + * t_sint32 GenerateSeq_parameter_set_rbsp (t_p_seq_parameter_set_rbsp p_sps, t_uint8 *rbsp); + * + * \param sps + * sequence parameter structure + * \param rbsp + * buffer to be filled with the rbsp, size should be at least MAXIMUMPARSETRBSPSIZE + * + * \return + * size of the RBSP in bytes + * + * \note + * Sequence Parameter VUI function is called, but the function implements + * an exit (-1) + ************************************************************************************* + */ +/*\/ Sarvesh: seq_parameter_set_rbsp() from H264 stadard page 55 */ +t_sint32 GenerateSeq_parameter_set_rbsp (t_p_seq_parameter_set_rbsp p_sps, t_uint8 *rbsp) +{ + Bitstream bitstream, *p_bitstream = &bitstream; + + t_sint32 len = 0, LenInBytes; + t_uint32 i; + + HCL_ASSERT (rbsp != NULL); + + p_bitstream->streamBuffer = (t_uint8 *)rbsp; + p_bitstream->bits_to_go = 8; + + p_bitstream->byte_pos = 0;//\/ + p_bitstream->byte_buf = 0;//\/ + + len+=u_v(8, p_sps->profile_idc, p_bitstream); + len+=u_1(p_sps->constrained_set0_flag, p_bitstream); + len+=u_1(p_sps->constrained_set1_flag, p_bitstream); + len+=u_1(p_sps->constrained_set2_flag, p_bitstream); + len+=u_1(p_sps->constrained_set3_flag, p_bitstream); + len+=u_v(4, 0, p_bitstream); + len+=u_v(8, p_sps->level_idc, p_bitstream); + len+=ue_v(p_sps->seq_parameter_set_id, p_bitstream); + + /* Fidelity Range Extensions stuff */ + if((p_sps->profile_idc==FREXT_HP) || + (p_sps->profile_idc==FREXT_Hi10P) || + (p_sps->profile_idc==FREXT_Hi422) || + (p_sps->profile_idc==FREXT_Hi444)) + { + len+=ue_v(1, p_bitstream); + len+=ue_v(p_sps->bit_depth_luma_minus8, p_bitstream); + len+=ue_v(p_sps->bit_depth_chroma_minus8, p_bitstream); + len+=u_1(0, p_bitstream); + /*other chroma info to be added in the future */ + len+=u_1(0, p_bitstream); + } + + len+=ue_v(p_sps->log2_max_frame_num_minus4, p_bitstream); + len+=ue_v(p_sps->pic_order_cnt_type, p_bitstream); + + if (p_sps->pic_order_cnt_type == 0) + len+=ue_v(p_sps->log2_max_pic_order_cnt_lsb_minus4, p_bitstream); + else if (p_sps->pic_order_cnt_type == 1) { + len+=u_1(DELTA_PIC_ORDER_ALWAYS_ZERO_FLAG, p_bitstream); + len+=se_v(p_sps->offset_for_non_ref_pic, p_bitstream); + len+=se_v(0, p_bitstream); + len+=ue_v(p_sps->num_ref_frames_in_pic_order_cnt_cycle, p_bitstream); + for (i=0; inum_ref_frames_in_pic_order_cnt_cycle; i++) + len+=se_v(p_sps->offset_for_ref_frame[i], p_bitstream); + } + len+=ue_v(1, p_bitstream); /* FP: num_ref_frames forced to '1' */ + len+=u_1(p_sps->gaps_in_frame_num_value_allowed_flag, p_bitstream); + len+=ue_v(p_sps->pic_width_in_mbs_minus1, p_bitstream); + len+=ue_v(p_sps->pic_height_in_map_units_minus1, p_bitstream); + len+=u_1(1, p_bitstream); + len+=u_1(1, p_bitstream); + len+=u_1(p_sps->frame_cropping_flag, p_bitstream); + if (p_sps->frame_cropping_flag) { + len+=ue_v(p_sps->frame_cropping_rect_left_offset, p_bitstream); + len+=ue_v(p_sps->frame_cropping_rect_right_offset, p_bitstream); + len+=ue_v(p_sps->frame_cropping_rect_top_offset, p_bitstream); + len+=ue_v(p_sps->frame_cropping_rect_bottom_offset, p_bitstream); + } + + len+=u_1(p_sps->vui_parameters_present_flag, p_bitstream); + if (p_sps->vui_parameters_present_flag) + len+=GenerateVUISequenceParameters(p_sps, p_bitstream); + + SODBtoRBSP(p_bitstream); /* copies the last couple of bits into the byte buffer */ + LenInBytes=p_bitstream->byte_pos; + + return LenInBytes; +} + +/*! + ************************************************************************************* + * \brief + * t_sint32 GeneratePic_parameter_set_rbsp (t_p_pic_parameter_set_rbsp p_pps, char *rbsp); + * + * \param pps + * picture parameter structure + * \param rbsp + * buffer to be filled with the rbsp, size should be at least MAXIMUMPARSETRBSPSIZE + * + * \return + * size of the RBSP in bytes, negative in case of an error + * + * \note + * Picture Parameter VUI function is called, but the function implements + * an exit (-1) + ************************************************************************************* + */ + +t_sint32 GeneratePic_parameter_set_rbsp (t_sva_service_instance_num instanceNum, t_p_pic_parameter_set_rbsp p_pps, t_uint8 *rbsp) +{ + t_sva_ec_h264_descriptor *pDesc = &h264EncodeDesc[instanceNum]; + Bitstream bitstream, *p_bitstream = &bitstream; + t_sint32 len = 0, LenInBytes; + t_sint32 profile_idc; + + HCL_ASSERT (rbsp != NULL); + + /* In order to use the entropy coding functions from golomb.c we need */ + /* to allocate a partition structure. It will be freed later in this */ + /* function */ + p_bitstream->streamBuffer = (t_uint8 *)rbsp; + p_bitstream->bits_to_go = 8; + + p_bitstream->byte_pos = 0;//\/ + p_bitstream->byte_buf = 0;//\/ + + len+=ue_v (PIC_PARAMETER_SET_ID, p_bitstream); + len+=ue_v (p_pps->seq_parameter_set_id, p_bitstream); + len+=u_1 (p_pps->entropy_coding_mode_flag, p_bitstream); + len+=u_1 (PIC_ORDER_PRESENT_FLAG, p_bitstream); + len+=ue_v (0, p_bitstream); + len+=ue_v (NUM_REF_IDX_L0_ACTIVE_MINUS1, p_bitstream); + + /* FP: Warning, in the following: check which list to use (0 or 1) */ + len+=ue_v (NUM_REF_IDX_L0_ACTIVE_MINUS1, p_bitstream); + + len+=u_1 (0, p_bitstream); + len+=u_v (2, 0, p_bitstream); + len+=se_v (PIC_INIT_QP_MINUS26, p_bitstream); + len+=se_v (p_pps->pic_init_qs_minus26, p_bitstream); + + profile_idc = pDesc->h264Conf.ProfileIDC; + if((profile_idc==FREXT_HP) || + (profile_idc==FREXT_Hi10P) || + (profile_idc==FREXT_Hi422) || + (profile_idc==FREXT_Hi444)) + len+=se_v (0, p_bitstream); /* FP: forced to zero */ + else + len+=se_v (p_pps->chroma_qp_index_offset, p_bitstream); + + len+=u_1(p_pps->deblocking_filter_control_present_flag, p_bitstream); + len+=u_1(p_pps->constrained_intra_pred_flag, p_bitstream); + len+=u_1(p_pps->redundant_pic_cnt_present_flag, p_bitstream); + + SODBtoRBSP(p_bitstream); /* copies the last couple of bits into the byte buffer */ + LenInBytes=p_bitstream->byte_pos; + + return LenInBytes; +} + +/*\/ Sarvesh: rbsp_trailing_bits( ) function in standard */ +void SODBtoRBSP(Bitstream *currStream) +{ + currStream->byte_buf <<= 1; + currStream->byte_buf |= 1; + currStream->bits_to_go--; + currStream->byte_buf <<= currStream->bits_to_go; + currStream->streamBuffer[currStream->byte_pos++] = (t_uint8) currStream->byte_buf; + currStream->bits_to_go = 8; + currStream->byte_buf = 0; +} + +/*! + ************************************************************************************* + * \brief + * Function body for VUI Parameter generation (to be done) + * \author Nicola Zandona' + * \return + * exits with error message + ************************************************************************************* + */ +/*\/ Sarvesh: vui_parameters( ) function from standard */ +PRIVATE t_sint32 GenerateVUISequenceParameters(t_p_seq_parameter_set_rbsp p_sps, Bitstream *bitstream) +{ + t_sint32 len=0; + t_uint32 i; + + len+=u_1(p_sps->vui_seq_parameters.aspect_ratio_info_present_flag, bitstream); + if (p_sps->vui_seq_parameters.aspect_ratio_info_present_flag) { + len+=u_v(8, p_sps->vui_seq_parameters.aspect_ratio_idc, bitstream); + if (p_sps->vui_seq_parameters.aspect_ratio_idc == 255) { + len+=u_v(16, p_sps->vui_seq_parameters.sar_width, bitstream); + len+=u_v(16, p_sps->vui_seq_parameters.sar_height, bitstream); + } + } + + len+=u_1(p_sps->vui_seq_parameters.overscan_info_present_flag, bitstream); + if (p_sps->vui_seq_parameters.overscan_info_present_flag) + len+=u_1(p_sps->vui_seq_parameters.overscan_appropriate_flag, bitstream); + + len+=u_1(p_sps->vui_seq_parameters.video_signal_type_present_flag, bitstream); + if (p_sps->vui_seq_parameters.video_signal_type_present_flag) { + len+=u_v(3, p_sps->vui_seq_parameters.video_format, bitstream); + len+=u_1(p_sps->vui_seq_parameters.video_full_range_flag, bitstream); + len+=u_1(p_sps->vui_seq_parameters.colour_description_present_flag, bitstream); + if (p_sps->vui_seq_parameters.colour_description_present_flag) { + len+=u_v(8, p_sps->vui_seq_parameters.colour_primaries, bitstream); + len+=u_v(8, p_sps->vui_seq_parameters.transfer_characteristics, bitstream); + len+=u_v(8, p_sps->vui_seq_parameters.matrix_coefficients, bitstream); + } + } + + len+=u_1(p_sps->vui_seq_parameters.chroma_location_info_present_flag, bitstream); + if (p_sps->vui_seq_parameters.chroma_location_info_present_flag) { + len+=ue_v(p_sps->vui_seq_parameters.chroma_sample_loc_type_top_field, bitstream); + len+=ue_v(p_sps->vui_seq_parameters.chroma_sample_loc_type_bottom_field, bitstream); + } + + len+=u_1(p_sps->vui_seq_parameters.timing_info_present_flag, bitstream); + if (p_sps->vui_seq_parameters.timing_info_present_flag) { + len+=u_v(32, p_sps->vui_seq_parameters.num_units_in_tick, bitstream); + len+=u_v(32, p_sps->vui_seq_parameters.time_scale, bitstream); + len+=u_1(p_sps->vui_seq_parameters.fixed_frame_rate_flag, bitstream); + } + + len+=u_1(p_sps->vui_seq_parameters.nal_hrd_parameters_present_flag, bitstream); + if (p_sps->vui_seq_parameters.nal_hrd_parameters_present_flag) { + len+=ue_v(p_sps->vui_seq_parameters.nal_hrd_parameters.cpb_cnt_minus1, bitstream); + len+=u_v(4, p_sps->vui_seq_parameters.nal_hrd_parameters.bit_rate_scale, bitstream); + len+=u_v(4, p_sps->vui_seq_parameters.nal_hrd_parameters.cpb_size_scale, bitstream); + for (i=0; i < p_sps->vui_seq_parameters.nal_hrd_parameters.cpb_cnt_minus1 +1; i++) { + len+=ue_v(p_sps->vui_seq_parameters.nal_hrd_parameters.bit_rate_value_minus1[i], bitstream); + len+=ue_v(p_sps->vui_seq_parameters.nal_hrd_parameters.cpb_size_value_minus1[i], bitstream); + len+=u_1(p_sps->vui_seq_parameters.nal_hrd_parameters.cbr_flag[i], bitstream); + } + len+=u_v(5, p_sps->vui_seq_parameters.nal_hrd_parameters.initial_cpb_removal_delay_length_minus1, bitstream); + len+=u_v(5, p_sps->vui_seq_parameters.nal_hrd_parameters.cpb_removal_delay_length_minus1, bitstream); + len+=u_v(5, p_sps->vui_seq_parameters.nal_hrd_parameters.dpb_output_delay_length_minus1, bitstream); + len+=u_v(5, p_sps->vui_seq_parameters.nal_hrd_parameters.time_offset_length, bitstream); + } + + len+=u_1(p_sps->vui_seq_parameters.vcl_hrd_parameters_present_flag, bitstream); + if (p_sps->vui_seq_parameters.vcl_hrd_parameters_present_flag) { + len+=ue_v(p_sps->vui_seq_parameters.vcl_hrd_parameters.cpb_cnt_minus1, bitstream); + len+=u_v(4, p_sps->vui_seq_parameters.vcl_hrd_parameters.bit_rate_scale, bitstream); + len+=u_v(4, p_sps->vui_seq_parameters.vcl_hrd_parameters.cpb_size_scale, bitstream); + for (i=0; i < p_sps->vui_seq_parameters.vcl_hrd_parameters.cpb_cnt_minus1 +1; i++) { + len+=ue_v(p_sps->vui_seq_parameters.vcl_hrd_parameters.bit_rate_value_minus1[i], bitstream); + len+=ue_v(p_sps->vui_seq_parameters.vcl_hrd_parameters.cpb_size_value_minus1[i], bitstream); + len+=u_1(p_sps->vui_seq_parameters.vcl_hrd_parameters.cbr_flag[i], bitstream); + } + len+=u_v(5, p_sps->vui_seq_parameters.vcl_hrd_parameters.initial_cpb_removal_delay_length_minus1, bitstream); + len+=u_v(5, p_sps->vui_seq_parameters.vcl_hrd_parameters.cpb_removal_delay_length_minus1, bitstream); + len+=u_v(5, p_sps->vui_seq_parameters.vcl_hrd_parameters.dpb_output_delay_length_minus1, bitstream); + len+=u_v(5, p_sps->vui_seq_parameters.vcl_hrd_parameters.time_offset_length, bitstream); + } + + if (p_sps->vui_seq_parameters.nal_hrd_parameters_present_flag || p_sps->vui_seq_parameters.vcl_hrd_parameters_present_flag) + len+=u_1(p_sps->vui_seq_parameters.low_delay_hrd_flag, bitstream); + + len+=u_1(p_sps->vui_seq_parameters.pic_struct_present_flag, bitstream); + + len+=u_1(p_sps->vui_seq_parameters.bitstream_restriction_flag, bitstream); + if (p_sps->vui_seq_parameters.bitstream_restriction_flag) { + len+=u_1(p_sps->vui_seq_parameters.motion_vectors_over_pic_boundaries_flag, bitstream); + len+=ue_v(p_sps->vui_seq_parameters.max_bytes_per_pic_denom, bitstream); + len+=ue_v(p_sps->vui_seq_parameters.max_bits_per_mb_denom, bitstream); + len+=ue_v(p_sps->vui_seq_parameters.log2_max_mv_length_horizontal, bitstream); + len+=ue_v(p_sps->vui_seq_parameters.log2_max_mv_length_vertical, bitstream); + len+=ue_v(p_sps->vui_seq_parameters.num_reorder_frames, bitstream); + len+=ue_v(p_sps->vui_seq_parameters.max_dec_frame_buffering, bitstream); + } + return len; +} + +/*! + ************************************************************************************* + * \brief + * u_1, writes a flag (u(1) syntax element, returns the length in bits, + * always 1 + * + * \param tracestring + * the string for the trace file + * \param value + * the value to be coded + * \param part + * the Data Partition the value should be coded into + * + * \return + * Number of bits used by the coded syntax element (always 1) + * + * \ note + * This function writes always the bit buffer for the progressive scan flag, and + * should not be used (or should be modified appropriately) for the interlace crap + * When used in the context of the Parameter Sets, this is obviously not a + * problem. + * + ************************************************************************************* + */ +t_sint8 u_1(t_sint32 value, Bitstream *bitstream) +{ + CodElement codelem, *codel = &codelem; + + HCL_ASSERT(value >= 0); + codel->data = value; + codel->nbit = 1; + HCL_ASSERT (bitstream->streamBuffer != NULL); + return host_writeSyntaxElement_fixed(codel, bitstream); +} + +/*! + ************************************************************************************* + * \brief + * u_v, writes a n bit fixed length syntax element, returns the length in bits, + * + * \param n + * length in bits + * \param tracestring + * the string for the trace file + * \param value + * the value to be coded + * \param part + * the Data Partition the value should be coded into + * + * \return + * Number of bits used by the coded syntax element + * + * \ note + * This function writes always the bit buffer for the progressive scan flag, and + * should not be used (or should be modified appropriately) for the interlace crap + * When used in the context of the Parameter Sets, this is obviously not a + * problem. + * + ************************************************************************************* + */ +t_sint8 u_v(t_sint32 n, t_sint32 value, Bitstream *bitstream) +{ + CodElement codelem, *codel = &codelem; + + HCL_ASSERT(value >= 0); + codel->data = value; + codel->nbit = (t_sint8)n; + HCL_ASSERT (bitstream->streamBuffer != NULL); + return host_writeSyntaxElement_fixed(codel, bitstream); +} + +/*! + ************************************************************************************* + * \brief + * ue_v, writes an ue(v) syntax element, returns the length in bits + * + * \param tracestring + * the string for the trace file + * \param value + * the value to be coded + * \param part + * the Data Partition the value should be coded into + * + * \return + * Number of bits used by the coded syntax element + * + * \ note + * This function writes always the bit buffer for the progressive scan flag, and + * should not be used (or should be modified appropriately) for the interlace crap + * When used in the context of the Parameter Sets, this is obviously not a + * problem. + * + ************************************************************************************* + */ +t_sint8 ue_v(t_sint32 value, Bitstream *bitstream) +{ + t_sint8 len; + HCL_ASSERT (bitstream->streamBuffer != NULL); + HCL_ASSERT(value >= 0); + len = host_writeSyntaxElement_UVLC((t_uint16)value, bitstream, 0); + return(len); +} + +/*! + ************************************************************************************* + * \brief + * se_v, writes an se(v) syntax element, returns the length in bits + * + * \param tracestring + * the string for the trace file + * \param value + * the value to be coded + * \param part + * the Data Partition the value should be coded into + * + * \return + * Number of bits used by the coded syntax element + * + * \ note + * This function writes always the bit buffer for the progressive scan flag, and + * should not be used (or should be modified appropriately) for the interlace crap + * When used in the context of the Parameter Sets, this is obviously not a + * problem. + * + ************************************************************************************* + */ +t_sint8 se_v(t_sint32 value, Bitstream *bitstream) +{ + t_sint8 len; + HCL_ASSERT (bitstream->streamBuffer != NULL); + len = host_writeSyntaxElement_UVLC((t_uint16)value, bitstream, 1); + return(len); +} + +/*! + ************************************************************************ + * \brief + * generates UVLC code and passes the codeword to the buffer + ************************************************************************ + */ +PRIVATE t_sint8 host_writeSyntaxElement_UVLC(t_uint16 value, Bitstream *bitstream, t_sint32 sign) +{ +#if TRACE + SyntaxElement syntaxel, *se = &syntaxel; +#endif + CodElement codelem, *codel = &codelem; + + if (sign == 0) host_ue_linfo(value, codel); + else host_se_linfo(value, codel); + + host_writeUVLC2buffer(codel, bitstream); + +#if TRACE + se->value1 = value; + se->nbit = codel->nbit; +//\/ snprintf(se->tracestring, TRACESTRING_SIZE, ""); + se->data = codel->data; + trace2out(se); +#endif + + return(codel->nbit); +} + +/*! + ************************************************************************ + * \brief + * passes the fixed codeword to the buffer + ************************************************************************ + */ +PRIVATE t_sint8 host_writeSyntaxElement_fixed(CodElement *codel, Bitstream *bitstream) +{ +#if TRACE + SyntaxElement symbol, *se = &symbol; +#endif + host_writeUVLC2buffer(codel, bitstream); + +#if TRACE + se->value1 = codel->data; + se->nbit = codel->nbit; + se->data = codel->data; + trace2out(se); +#endif + + return(codel->nbit); +} + +/*! + ************************************************************************ + * \brief + * writes UVLC code to the appropriate buffer + ************************************************************************ + */ +PRIVATE void host_writeUVLC2buffer(CodElement *codel, Bitstream *currStream) +{ + t_sint32 i; + t_uint32 mask = 1 << (codel->nbit - 1); + + /* Add the new bits to the bitstream. */ + /* Write out a byte if it is full */ + for (i = 0; i < codel->nbit; i++) { + currStream->byte_buf <<= 1; + if (codel->data & mask) + currStream->byte_buf |= 1; + currStream->bits_to_go--; + mask >>= 1; + if (currStream->bits_to_go == 0) { + currStream->bits_to_go = 8; + currStream->streamBuffer[currStream->byte_pos++] = (t_uint8) currStream->byte_buf; + currStream->byte_buf = 0; + } + } +} + +/*! + ************************************************************************ + * \brief + * mapping for ue(v) syntax elements + * \param ue + * value to be mapped + * \param dummy + * dummy parameter + * \param info + * returns mapped value + * \param len + * returns mapped value length + ************************************************************************ + */ +void host_ue_linfo(t_uint16 ue, CodElement *sym) +{ + t_sint8 suffix_len; + t_sint16 nn; + t_sint16 tmp_info; /* info part of UVLC code */ + + nn = (ue + 1) >> 1; + for (suffix_len = 0; (nn != 0) && (suffix_len < 16); suffix_len++) { + nn >>= 1; + } + + tmp_info = ue + 1 - (1 << suffix_len); + sym->nbit = 2 * suffix_len + 1; + sym->data = (1 << suffix_len) | (tmp_info & ((1 << suffix_len) - 1)); +} + +/*! + ************************************************************************ + * \brief + * mapping for se(v) syntax elements + * \param se + * value to be mapped + * \param dummy + * dummy parameter + * \param len + * returns mapped value length + * \param info + * returns mapped value + ************************************************************************ + */ +void host_se_linfo(t_sint16 se, CodElement *sym) +{ + t_sint8 suffix_len, n, sign; + t_sint16 nn; + t_sint16 tmp_info; /* info part of UVLC code */ + sign = 0; + + if (se <= 0) sign = 1; + n = absm(se) << 1; + + nn = n/2; + for (suffix_len = 0; (nn != 0) && (suffix_len < 16); suffix_len++) { + nn /= 2; + } + tmp_info = n - (1 << suffix_len) + sign; + /* Makes code word and passes it back + A code word has the following format: 0 0 0 ... 1 Xn ...X2 X1 X0. + Info : Xn..X2 X1 X0 + Length : Total number of bits in the codeword */ + sym->nbit = suffix_len * 2 + 1; + sym->data = (1 << suffix_len) | (tmp_info & ((1 << suffix_len) - 1)); +} + +/*! +************************************************************************ +* \brief +* This function converts a RBSP payload to an EBSP payload +* +* \param streamBuffer +* pointer to data bits +* \param begin_bytepos +* The byte position after start-code, after which stuffing to +* prevent start-code emulation begins. +* \param end_bytepos +* Size of streamBuffer in bytes. +* \param min_num_bytes +* Minimum number of bytes in payload. Should be 0 for VLC entropy +* coding mode. Determines number of stuffed words for CABAC mode. +* \return +* Size of streamBuffer after stuffing. +* \note +* NAL_Payload_buffer is used as temporary buffer to store data. +* +* +************************************************************************ +*/ +t_sint32 RBSPtoEBSP(t_uint8 *streamBuffer, t_sint32 begin_bytepos, t_sint32 end_bytepos, t_sint32 min_num_bytes) +{ + t_sint32 i, j, count; + + PRIVATE t_uint8 NAL_Payload_buffer[NONVCL_BUFFER_SIZE]; + + for(i = begin_bytepos; i < end_bytepos; i++) + NAL_Payload_buffer[i] = streamBuffer[i]; + + count = 0; + j = begin_bytepos; + for(i = begin_bytepos; i < end_bytepos; i++) + { + if(count == ZEROBYTES_SHORTSTARTCODE && !(NAL_Payload_buffer[i] & 0xFC)) + { + streamBuffer[j] = 0x03; + j++; + count = 0; + } + + streamBuffer[j] = NAL_Payload_buffer[i]; + if(NAL_Payload_buffer[i] == 0x00) + count++; + else + count = 0; + j++; + } + while (j < begin_bytepos+min_num_bytes) { + streamBuffer[j] = 0x00; /* cabac stuffing word */ + streamBuffer[j+1] = 0x00; + streamBuffer[j+2] = 0x03; + j += 3; +//\/ stats->bit_use_stuffingBits[p_img->picture_coding_type]+=16; + } + return j; +} + +/****************************************************************************/ +/* NAME: t_sva_ec_algo_error sva_EC_H264_EncodeOneFrame( */ +/* t_sva_service_instance_num instanceNum */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will Encode one frame */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - instanceNum: number of the descriptor to use. */ +/* */ +/* OUT : None */ +/* */ +/* RETURN: */ +/* t_sva_ec_algo_error */ +/* t.b.d */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +//\/ For loop containing SetNextImageType and encode_one_frame function calls +//\/ for (p_img->number=0; p_img->number < pH264Conf->no_frames; p_img->number++) +PRIVATE t_sva_ec_algo_error sva_EC_H264_EncodeOneFrame(t_sva_service_instance_num instanceNum, + t_sva_ec_algo_params_in *pParamIn) +{ + t_sva_ec_h264_descriptor *pDesc = &h264EncodeDesc[instanceNum]; + t_p_ImageParameters p_img = &pDesc->images;//\/ + + HCL_ASSERT(pParamIn != NULL); + + /* sets the image type and manage the timestamp stuff */ + InitPicture(instanceNum); + + /* ENCODING ONE FRAME */ + encode_one_frame(instanceNum, pParamIn); + + //\/ Sarvesh: Decide weather to call this function will be called here or in sva_EC_H264_SetFrameParamOut API + /* management of encoding timestamp and coded picture counter */ + PostPicture(instanceNum); + + p_img->number++; + + return SVA_EC_ALGO_OK;//\/ +} + +/*! + ************************************************************************ + * \brief + * Encodes one frame + ************************************************************************ + */ +void encode_one_frame (t_sva_service_instance_num instanceNum, t_sva_ec_algo_params_in *pParamIn) +{ + t_sva_ec_h264_descriptor *pDesc = &h264EncodeDesc[instanceNum]; + t_p_ImageParameters p_img = &pDesc->images;//\/ +//\/ PRIVATE t_sint32 prev_frame_no = 0; +//\/ t_p_StorablePicture p_tmp; + + /* Init parameters_in structure between host/hamac */ +//\/ stats->bit_slice = 0; + + /*Rate control */ +//\/ if(!pDesc->h264Conf.brc_type) { /* without using rate control */ + if(!pDesc->conf.brcMode) { /* without using rate control */ + if (p_img->picture_coding_type == I_SLICE) + p_img->SeinitialQP = (t_uint8)pDesc->h264Conf.QPISlice; /* set quant. parameter for I-frame */ + else + p_img->SeinitialQP = (t_uint8)pDesc->h264Conf.QPPSlice; + } +/* + else { + NZ: already initialized in init_img(). Hardcode by now + } +*/ + +//\/ stats->em_prev_bits_frm = 0; +//\/ stats->em_prev_bits = &stats->em_prev_bits_frm; + + /* code a picture */ + code_a_picture(instanceNum, pParamIn); + + /* if needed, find the PSNR */ +#ifdef REPORT_EVERYTHING + find_distortion(); + find_snr (); +#endif +#if 0 //\/ Useless code + stats->bit_ctr_emulationprevention += stats->em_prev_bits_frm; + + /* if not skipped, write the picture */ + if (!hi->addr_out_frame_parameters.Skip_Current) +//\/ write_out_picture(p_enc_picture, p_dec); + + /* EL: if current picture is skipped, keep the previous picture as reference (LVR_MMS_VBR)*/ + if (!hi->addr_out_frame_parameters.Skip_Current) { + /* FP: swaps the current and reference frame */ + p_tmp = p_enc_picture; + p_enc_picture = p_ref_picture; + p_ref_picture = p_tmp; + } + + /* NZ: Copy inout out to inout in */ + hinfo_in.addr_in_frame_parameters = hinfo_in.addr_out_frame_parameters; + + /* NZ: swap the skip parameter (just an overwrite, since Skip_Current is no more used on host side -for this picture-) */ + hi->addr_in_frame_parameters.Skip_Current = hi->addr_out_frame_parameters.Skip_Next; + + /* patch for # of MV for 2 consecutive MBs (level >= 3.1 ): init for frame #0 */ + if(p_img->number == 0) + mb_param.prev_mb_mv_num = 1; + + /* NICOLA */ + /* + if(p_img->number == 0) + hi->addr_in_frame_parameters.previous_MB_MV_num = 1; + */ + + + /* POC200301: Verify that POC coding type 2 is not used if more than one consecutive */ + /* non-reference frame is requested or if decoding order is different from output order */ + if (pDesc->h264Conf.pic_order_cnt_type == 2) { + if (frame_no < prev_frame_no) +//\/ error("POC type 2 cannot be applied for the coding pattern where the encoding /decoding order of pictures are different from the output order.\n", -1); + prev_frame_no = frame_no; + } + +#ifdef REPORT_EVERYTHING + ReportNALNonVLCBits(); +#endif + + if (IMG_NUMBER == 0) { +#ifdef REPORT_EVERYTHING + ReportFirstframe(); +#endif + } + else { + switch (p_img->picture_coding_type) { + case I_SLICE: + stats->bit_ctr_P += stats->bit_ctr - stats->bit_ctr_n; +#ifdef REPORT_EVERYTHING + ReportIntra(); +#endif + break; + default: /* P */ + stats->bit_ctr_P += stats->bit_ctr - stats->bit_ctr_n; +#ifdef REPORT_EVERYTHING + ReportP(); +#endif + } + } + stats->bit_ctr_n = stats->bit_ctr; +#endif //\/end of #if 0 //\/ Useless code +} + +/*! + ************************************************************************ + * \brief + * Encodes a picture + * + * This is the main picture coding loop.. It is called by all this + * frame and field coding stuff after the p_img-> elements have been + * set up. Not sure whether it is useful for MB-adaptive frame/field + * coding + ************************************************************************ + */ +void code_a_picture(t_sva_service_instance_num instanceNum, t_sva_ec_algo_params_in *pParamIn) +{ + t_sva_ec_h264_descriptor *pDesc = &h264EncodeDesc[instanceNum]; + t_p_ImageParameters p_img = &pDesc->images;//\/ + t_sva_vec_h264_param_in *pH264ParamIn = (t_sva_vec_h264_param_in *) pParamIn;//\/ + +#ifdef _REMOVE_FOR_TIME_BEING_ + t_uint32 i, slice_index = 0; + t_uint32 nalu_len = 0; +#endif /* _REMOVE_FOR_TIME_BEING_ */ +#ifdef _SUPPORT_SEI_MESSAGES_ + t_uint32 SEIsize = 0; +#endif /* _SUPPORT_SEI_MESSAGES_ */ +#ifdef _DUMP_VERIF_ + PRIVATE t_uint32 cur_img; +#endif + +#ifdef _REMOVE_FOR_TIME_BEING_ + t_NALU nalu; + t_p_NALU p_nalu = &nalu; +#endif /* _REMOVE_FOR_TIME_BEING_ */ + + HCL_ASSERT(pParamIn != NULL); + + p_img->idr_flag = ((!p_img->CodedPictureCounter)) || (p_img->idr_flag && (p_img->picture_coding_type == I_SLICE)); +//\/ pH264ParamIn->init_me = (p_img->number == 0); + pH264ParamIn->idr_flag = p_img->idr_flag; + +#ifdef _SUPPORT_SEI_MESSAGES_ + /* Init SEIio structure */ + InitSEIio(SEIio); +#endif /* _SUPPORT_SEI_MESSAGES_ */ + +#ifdef COLLECT_STATS + hinfo_in.stats = stats; +#endif + +#ifdef _SUPPORT_SEI_MESSAGES_ + /* NZ: SEI message size estimation */ + if (pDesc->h264Conf.HrdSendMessages == 2) { + t_uint16 PTSEIsize = 0, BPSEIsize = 0; + + /* Buffering Period + Picture Timing */ + if (SEIio->forceBP) { + /* Estimate BP SEI size */ + BPSEIsize = EstimateBP(); + BPSEIsize += 8; /* NZ: +1 for last_payload_type_byte; only 1 byte because payload_type for those SEI is always less than 0xff */ + BPSEIsize += ((BPSEIsize>>(3+8)) +1)<<3; /* NZ: an addictional 0xff byte for each byte more than 255; +1 one for last_payload_size_byte byte */ + } + + /* Picture Timing */ + /* Estimate PT SEI size */ + PTSEIsize = EstimatePT(); + PTSEIsize += 8; /* NZ: +1 for last_payload_type_byte; only 1 byte because payload_type for those SEI is always less than 0xff */ + PTSEIsize += ((PTSEIsize>>(3+8)) +1)<<3; /* NZ: an addictional 0xff byte for each byte more than 255; +1 one for last_payload_size_byte byte */ + + /* NZ + Details: + + 1 for final 0x80 byte in SEI payload + + 1 for first NAL byte : forbidden_zero_bit + nal_ref_idc + nal_unit_type + + 4 for NAL startcode + */ + if (!pDesc->h264Conf.annexb) + SEIsize = (PTSEIsize + BPSEIsize + ((1 + 1 + 4)<<3)); + else + SEIsize = (PTSEIsize + BPSEIsize + ((1 + 1)<<3)); + p_img->NonVCLNALUSize += SEIsize; + } +#endif /* _SUPPORT_SEI_MESSAGES_ */ + + /* Prepares all the input-only parameters for the Hamac */ +//\/ hinfo_in.addr_in_frame_buffer.addr_source_buffer.imgY = imgY_org; +//\/ hinfo_in.addr_in_frame_buffer.addr_source_buffer.imgUV[0] = imgUV_org[0]; +//\/ hinfo_in.addr_in_frame_buffer.addr_source_buffer.imgUV[1] = imgUV_org[1]; +//\/ hinfo_in.addr_in_bitstream_buffer.addr_bitstream_start = out_streamBuffer; /* put here the coded bitstream */ + hamac_copy_param_in(instanceNum, pParamIn); +//\/ hamac_copy_storable(&hinfo_in.addr_out_frame_buffer.addr_dest_buffer, p_enc_picture ); +//\/ hamac_copy_storable(&hinfo_in.addr_in_frame_buffer.addr_fwd_ref_buffer, p_ref_picture ); + +//\/ pH264ParamIn->window_width = pH264ParamIn->frame_width;//\/ +//\/ pH264ParamIn->window_height = pH264ParamIn->frame_height;//\/ + +#ifdef _DUMP_VERIF_ + /* Manage crop , by default, no crop*/ + pH264ParamIn->window_width = pH264ParamIn->frame_width; + pH264ParamIn->window_height = pH264ParamIn->frame_height; + pH264ParamIn->window_horizontal_offset = 0; + pH264ParamIn->window_vertical_offset = 0; + dump_struct_to_file_header( pH264ParamIn, vec_h264_param_in, fp_h264_param_in, cur_img ); + dump_struct_to_file_header( hi_h264_param_inout_in, vec_h264_param_inout, fp_h264_param_in, cur_img ); + + /* reset output structure */ +//\/ memset (hi_vec_h264_param_out, 0, sizeof(vec_h264_param_out)); +#endif + +//\/ hamac_main(); + + + +//\/ Below line is removed from here as it will be done in "sva_EC_H264_SetFrameParamOut" API +//\/ p_img->quant = hi_h264_param_inout_out->quant; + + /* CM for verif */ + /* Dump Param out */ + +#ifdef _DUMP_VERIF_ + dump_struct_to_file_header( hi_h264_param_inout_out, vec_h264_param_inout, fp_h264_param_out, cur_img); + dump_struct_to_file_header( hi_vec_h264_param_out, vec_h264_param_out, fp_h264_param_out, cur_img ); + { + static FILE * fp_bitstream; + if (!fp_bitstream) +//\/ fp_bitstream = fopen("bitstream.264", "wb"); +//\/ fwrite(out_streamBuffer, hi_h264_param_inout_out->bitstream_size/8, 1, fp_bitstream); + + } +#if 1 + { + static int init; + static FILE* fp_bsoff; + static FILE* fp_mvectors; + static FILE* fp_forward; + static FILE* fp_irefresh; + static FILE* fp_crcoff; + t_uint32 width = pH264ParamIn->frame_width; + t_uint32 height = pH264ParamIn->frame_height; + t_uint32 mbsize = (width/16)*(height/16); + int i; + int off; + + if (!init) + { +//\/ fp_bsoff = fopen("bsoffsets.txt", "wt"); +//\/ fp_mvectors = fopen("mvectors.bin", "wb"); +//\/ fp_forward = fopen("forward.bin", "wb"); +//\/ fp_irefresh = fopen("irefresh.bin", "wb"); +//\/ fp_crcoff = fopen("crcoffsets.txt", "wt"); + init = 1; + } + + for(i = 0; i < MAX_CHANNELS; i++) + { + if (ftab[i].fp) +//\/ off = ftell(ftab[i].fp); + else + off = 0; +//\/ fprintf(fp_crcoff, "%-8ld ", off); +//\/ fprintf(fp_crcoff, "%-8ld ", ftab[i].nb); + } +//\/ fprintf(fp_crcoff, "\n"); +//\/ fprintf(fp_bsoff, "%lu\n", hi_h264_param_inout_out->bitstream_size/8); + /*fwrite(hinfo_in.addr_out_frame_buffer.addr_motion_vector_buffer, 4*4*2*2*mbsize, 1, fp_mvectors);*/ +//\/ fwrite(loc_mv_p, 4*2*mbsize, 1, fp_mvectors); + if (0) { + /* For compatibility with FW 0.9 verif code */ + t_uint16 CC_modulation = 0; +//\/ fwrite(&CC_modulation, 2, 1, fp_mvectors); + } + /*fwrite(hinfo_in.addr_in_frame_buffer.addr_fwd_ref_buffer.imgY, 256*mbsize, 1, fp_forward); + fwrite(hinfo_in.addr_in_frame_buffer.addr_fwd_ref_buffer.imgUV[0], 64*mbsize, 1, fp_forward); + fwrite(hinfo_in.addr_in_frame_buffer.addr_fwd_ref_buffer.imgUV[1], 64*mbsize, 1, fp_forward);*/ +//\/ fwrite(hinfo_in.addr_out_frame_buffer.addr_dest_buffer.imgY, 256*mbsize, 1, fp_forward); +//\/ fwrite(hinfo_in.addr_out_frame_buffer.addr_dest_buffer.imgUV[0], 128*mbsize, 1, fp_forward); + } +//\/ printf("img %lu, bsize %lu\n", cur_img, hi_h264_param_inout_out->bitstream_size/8); +#endif + cur_img++; +#endif + +//\/ Below lines is removed from here as it will be done in "sva_EC_H264_SetFrameParamOut" API + /* pass the skip info to a host structure (just for readibility) */ +//\/ p_img->Skip_Next = hi->addr_out_frame_parameters.Skip_Next; +//\/ p_img->Skip_Current = hi->addr_out_frame_parameters.Skip_Current; + +#ifdef _SUPPORT_SEI_MESSAGES_ + /* local copy to speed-up (used in the write loop below) */ + slice_index = hinfo_in.addr_out_parameters.slice_num; + + /* ============================ SEI Messages Start ================================= */ + if(pDesc->h264Conf.HrdSendMessages == 2) { + /* computation of AU bits relevant to VCL NALU only and overall NALU */ + SEIio->NALAUsize = (p_img->NonVCLNALUSize + hi->addr_out_frame_parameters.bitstream_size); + SEIio->VCLAUsize = hi->addr_out_frame_parameters.bitstream_size; + + /* NZ: now copy the removal timestamp from hamac to SEI struct */ + SEIio->currAUts = hi->addr_out_frame_parameters.removal_time; + + /* set the flag InitBuffer for first input image */ + SEIio->InitBuffer = (p_img->number==0); + + /* compute and write SEI messages in the stream */ + if (!p_img->Skip_Current) + WriteSEI (SEIio); + else + p_img->NonVCLNALUSize -= SEIsize; + } + /* ============================ SEI Messages End ================================= */ + + /* FP: Loop over slices and write them all, create one NALU per slice */ + for(i=0; istartcodeprefix_len = 2+ZEROBYTES_SHORTSTARTCODE; + if (slice_index == 1) + nalu_len = hinfo_in.addr_out_frame_parameters.bitstream_size>>3; + else { + if (i == (slice_index-1)) + nalu_len = (hinfo_in.addr_out_frame_parameters.bitstream_size>>3) - hinfo_in.addr_out_parameters.slice_pos[i]; + else + nalu_len = hinfo_in.addr_out_parameters.slice_pos[i+1] - hinfo_in.addr_out_parameters.slice_pos[i]; + } + p_nalu->len = nalu_len ; + p_nalu->max_size = pDesc->h264Conf.frame_width*pDesc->h264Conf.frame_height*4; + p_nalu->buf = ((t_uint8*)out_streamBuffer) + hinfo_in.addr_out_parameters.slice_pos[i]; + if (p_img->idr_flag) { + p_nalu->nal_unit_type = NALU_TYPE_IDR; + p_nalu->nal_reference_idc = NALU_PRIORITY_HIGHEST; + } + else { + p_nalu->nal_unit_type = NALU_TYPE_SLICE; + p_nalu->nal_reference_idc = NALU_PRIORITY_HIGH; + } + p_nalu->forbidden_bit = 0; + + if (!hi->addr_out_frame_parameters.Skip_Current) + stats->bit_ctr += WriteNALU (VCL_NALU, p_nalu); + } + + WriteFillerDataNALU(hi->addr_out_frame_parameters.stuffing_bits); + + /* this is to update the final arrival time in SEI struct */ + if (!p_img->Skip_Current) + UpdateFinalArrivalTime(SEIio); +#endif /* _SUPPORT_SEI_MESSAGES_ */ +} + +#define COPY_INPUT_FIELD(field) pH264ParamIn->field = pDesc->h264Conf.field +#define COPY_IMG_FIELD(field) pH264ParamIn->field = p_img->field + +/*\/ Sarvesh: Test application */ +//\/void hamac_copy_param_in(vec_subtask_param *hinfo, InputParameters *input, ImageParameters *p_img) +void hamac_copy_param_in(t_sva_service_instance_num instanceNum, t_sva_ec_algo_params_in *pParamIn) +{ +//\/ t_uint16 i ; + t_sva_ec_h264_descriptor *pDesc = &h264EncodeDesc[instanceNum]; + t_sva_vec_h264_param_in *pH264ParamIn = (t_sva_vec_h264_param_in *) pParamIn; + t_p_ImageParameters p_img = &pDesc->images;//\/ +//\/ pic_parameter_set_rbsp_t *active_pps = &pDesc->active_pps;//\/ + + /* copy the subset of the input parameters used by the DSP */ + + COPY_INPUT_FIELD(algo_config); + COPY_IMG_FIELD(level_idc); + pH264ParamIn->use_constrained_intra_flag = (t_ushort_value)pDesc->h264Conf.use_constrained_intra_flag; + COPY_INPUT_FIELD(slice_size_type); + COPY_INPUT_FIELD(slice_bit_size); + COPY_INPUT_FIELD(slice_mb_size); +//\/ COPY_INPUT_FIELD(brc_type); + pH264ParamIn->brc_type = pDesc->conf.brcMode; + COPY_INPUT_FIELD(me_type); + COPY_INPUT_FIELD(intra_disable); + +//\/ hinfo->addr_in_parameters.bit_rate = bit_rate; + pH264ParamIn->bit_rate = g_bit_rate_val; + + COPY_IMG_FIELD(SeinitialQP); + /* SARVESH: Already done in sva_EC_H264_ANNEXB_GetNextFrameParamIn so removed from here */ +//\/ COPY_INPUT_FIELD(frame_width); +//\/ COPY_INPUT_FIELD(frame_height); +//\/ pH264ParamIn->frame_width = pDesc->conf.sourceFrameDesc.frame.width; +//\/ pH264ParamIn->frame_height = pDesc->conf.sourceFrameDesc.frame.height; + pH264ParamIn->pic_order_cnt_type = (t_ushort_value)pDesc->h264Conf.pic_order_cnt_type; + COPY_INPUT_FIELD(intra_refresh_type); + COPY_INPUT_FIELD(air_mb_num); + +//\/ for (i=0; i<8; i++) { +//\/ COPY_INPUT_FIELD(slice_loss_first_mb[i]); +//\/ COPY_INPUT_FIELD(slice_loss_mb_num[i]); +//\/ } + pH264ParamIn->annexb = (t_ushort_value)pDesc->h264Conf.annexb; + + COPY_INPUT_FIELD(CpbBufferSize); + + /* EL: input framerate is multiplied by 1024 to add precision in BRC computations (10 bits) */ +//\/ hinfo->addr_in_parameters.framerate = pDesc->h264Conf.FrameRate; + pH264ParamIn->framerate = pDesc->h264Conf.FrameRate; +//\/ COPY_INPUT_FIELD(framerate); + + /* copy the PPS required to encode the slice headers */ + /* hinfo->addr_in_parameters.deblocking_filter_control_present_flag = active_pps->deblocking_filter_control_present_flag; */ + pH264ParamIn->log2_max_frame_num_minus4 = log2_max_frame_num_minus4; + pH264ParamIn->log2_max_pic_order_cnt_lsb_minus4 = log2_max_pic_order_cnt_lsb_minus4; + + /* copy the subset of the image parameters used by the DSP */ + COPY_IMG_FIELD(CodedPictureCounter); + COPY_IMG_FIELD(picture_coding_type); + COPY_IMG_FIELD(frame_poc); + COPY_IMG_FIELD(frame_num); + COPY_IMG_FIELD(idr_flag); + + COPY_IMG_FIELD(timestamp); + + COPY_IMG_FIELD(NonVCLNALUSize); + + /* the following parameter is to disable deblocking filter */ + + pH264ParamIn->disable_deblocking_filter_idc = (t_ushort_value)pDesc->h264Conf.disable_deblocking_filter_idc; +//\/ pH264ParamIn->slice_alpha_c0_offset_div2 = pDesc->h264Conf.slice_alpha_c0_offset_div2; +//\/ pH264ParamIn->slice_beta_offset_div2 = pDesc->h264Conf.slice_beta_offset_div2; + pH264ParamIn->slice_alpha_c0_offset_div2 = (t_short_value)pDesc->h264Conf.slice_alpha_c0_offset_div2; + pH264ParamIn->slice_beta_offset_div2 = (t_short_value)pDesc->h264Conf.slice_beta_offset_div2; + + pH264ParamIn->MaxSumNumBitsInNALU = ComputeMaxBitSizePerAU(instanceNum); + +#ifdef SVA_EC_H264_ENABLE_SEI_MSGS + pH264ParamIn->lastBPAUts = SEIio->lastBPAUts; +#endif /* end of SVA_EC_H264_ENABLE_SEI_MSGS */ + + /* The following fields should never appear in a Nomadik configuration */ + + /* These fields are used only with JVT M.E. */ +//\/#if !defined(USE_ME_ST_ONLY) +//\/ COPY_INPUT_FIELD(full_search); +//\/ COPY_INPUT_FIELD(search_range); +//\/ COPY_INPUT_FIELD(InterSearch16x16); +//\/ COPY_INPUT_FIELD(InterSearch16x8); +//\/ COPY_INPUT_FIELD(InterSearch8x16); +//\/ COPY_INPUT_FIELD(InterSearch8x8); +//\/ COPY_INPUT_FIELD(InterSearch8x4); +//\/ COPY_INPUT_FIELD(InterSearch4x8); +//\/ COPY_INPUT_FIELD(InterSearch4x4); +//\/#endif + +//\/#if !defined(DISABLE_HADAMARD) +//\/ COPY_INPUT_FIELD(hadamard); +//\/#endif + + /* Initialize inout part, pb because quant should be in param_in interface */ +//\/hinfo->addr_in_frame_parameters.quant = p_img->quant; //\/ Sarvesh: Will be done in 'sva_EC_H264_InitParamInOut' +} + +/****************************************************************************/ +/* NAME: t_sva_error sva_EC_H264_GetInfoBlockSize( */ +/* t_sva_service_instance_num instanceNum */ +/* t_size* */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PRIVATE t_sva_ec_algo_error sva_EC_H264_GetH4DSize(t_sva_service_instance_num instanceNum, t_size* pSize ) +{ + t_sva_ec_algo_error ec_algo_error = SVA_EC_ALGO_OK; + t_sva_ec_h264_descriptor *pDesc = &h264EncodeDesc[instanceNum]; +//\/ pic_parameter_set_rbsp_t *pps = &pDesc->active_pps;//\/ + t_p_seq_parameter_set_rbsp p_sps = &pDesc->active_sps;//\/ +//\/ t_sva_h264_desc * pH264Desc = &h264Desc[instanceNum]; + + /* formule magique Cyril */ +//\/ *pSize = ((pDesc->picWidthInMbsMinus1+1)<<4) * 8 + 288; +//\/ *pSize = ((sps->pic_width_in_mbs_minus1+1)<<4) * 8 + 288; + *pSize = ((p_sps->pic_width_in_mbs_minus1+1)<<4) * 8 + 320; + + return ec_algo_error; +} + +/*! + *********************************************************************** + * \brief + * Checks the input parameters for consistency. + *********************************************************************** + */ + /*\/ Sarvesh: HCL part but under debug flag */ +PRIVATE void PatchInp (t_sva_service_instance_num instanceNum) +{ +//\/ t_sint32 bitdepth_qp_scale = 0; + t_sva_ec_h264_descriptor *pDesc = &h264EncodeDesc[instanceNum]; + + + +//\/ pDesc->h264Conf.width_cr = pDesc->h264Conf.frame_width /2; +//\/ pDesc->h264Conf.height_cr = pDesc->h264Conf.frame_height /2; + + +//\/ TestEncoderParams(bitdepth_qp_scale); /* HCL: Part of HCL */ + + /* NZ: Patch for HCL */ +//\/ pDesc->h264Conf.FrameRate = (t_uint16)(pDesc->h264Conf.FrameRate_parser * 1024); + +//\/ if (pDesc->h264Conf.FrameRate == 0) +//\/ pDesc->h264Conf.FrameRate = INIT_FRAME_RATE*1024; + + { + t_sint32 storedBplus1 = 1; /* FP: No B-FRAMES */ + + /* FP: this config option has changed from JM92 to JM10 */ + if (pDesc->h264Conf.Log2MaxFNumMinus4 == -1) { +//\/ log2_max_frame_num_minus4 = Clip3(0,12, (t_sint16) (CeilLog2(pDesc->h264Conf.no_frames * storedBplus1) - 4)); + log2_max_frame_num_minus4 = Clip3(0,12, (t_sint16) (CeilLog2(SVA_EC_H264_TEMP_NO_FRAMES_VAL * storedBplus1) - 4)); + } + else { + log2_max_frame_num_minus4 = (t_sint16)pDesc->h264Conf.Log2MaxFNumMinus4; + } + } + + log2_max_pic_order_cnt_lsb_minus4 = max( (t_sint16)(CeilLog2(2*SVA_EC_H264_TEMP_NO_FRAMES_VAL)) - 4, 0); + + + +#if INPUT_FORMAT == 1 + /* FP: when MB-Tile format is used, only CDME works (has been implemented so far) */ + if(pDesc->h264Conf.me_type != ME_ST && pDesc->h264Conf.me_type != ME8815_ST) { +//\/ error("MB-Tile format is supported with CDME only", 500); + } +#endif /* INPUT_FORMAT */ + + + /* FP: automatic cropping has been removed, size must be multiple of 16 pels */ +//\/ if(pDesc->h264Conf.frame_width % 16 || pDesc->h264Conf.frame_height % 16) { + if(pDesc->conf.sourceFrameDesc.frame.width % 16 || pDesc->conf.sourceFrameDesc.frame.height % 16) { +//\/ error("Automatic cropping not supported, image size must be multiple of 16 pels", 500); + } + +//\/#ifdef DISABLE_HADAMARD + /* FP: with DISABLE_HADAMARD the Hadamard cannot be used to SATD */ +//\/ if(pDesc->h264Conf.hadamard) { +//\/ error("DISABLE_HADAMARD is defined, cannot use Hadamard option", 500); +//\/ } +//\/#endif + + /* FP: with USE_ME_ST_ONLY then only ME_ST is allowed */ +//\/#ifdef USE_ME_ST_ONLY +//\/ if ((pDesc->h264Conf.me_type != ME_ST)&&(pDesc->h264Conf.me_type != ME8815_ST)) { +//\/ error("Only ME_ST and ME8815_ST allowed", 500); +//\/ } +//\/#endif + + +//\/ if(pDesc->h264Conf.brc_type == FRAME_BASED_BRC) { + if(pDesc->conf.brcMode == SVA_FRAME_BASE) { +//\/ error("Rate-Controller algorithm not yet implemented", 500); + } + + + /* FP: VUI/SEI are allowed only with BRC enabled */ +//\/ if(pDesc->h264Conf.brc_type == 0 && pDesc->h264Conf.HrdSendMessages) { + if(pDesc->conf.brcMode == 0 && pDesc->h264Conf.HrdSendMessages) { +//\/ error("VUI/SEI require that the BRC is also enabled", 500); + } + + + /* FP: the slice-loss parameters are allowed only within the dynamic options file */ +//\/ if(pDesc->h264Conf.slice_loss_first_mb[0] || pDesc->h264Conf.slice_loss_mb_num[0]) { +//\/ error("SliceLossFirstMb and SliceLossMbNum are allowed only within dynamic options file", 500); +//\/ } + + /* NZ: When in Constant QP mode (RateControlEnable =0), Automatic Level Detection is NOT allowed*/ + if((pDesc->conf.brcMode== 0) && (pDesc->h264Conf.level_idc==-1)) { +//\/ error("When in Constant QP mode (RateControlEnable=0), Automatic Level Detection (LevelIDC=-1) is NOT allowed", 500); + } + + + /* FP: combines INTRA disable modes in a single variable *//* HCL: Part of HCL */ + pDesc->h264Conf.intra_disable = 0; + if(pDesc->h264Conf.IntraDisableInterOnly) pDesc->h264Conf.intra_disable |= INTRA_DISABLE_INTER_ONLY; + if(pDesc->h264Conf.Intra4x4ParDisable) pDesc->h264Conf.intra_disable |= INTRA4X4_PAR_DISABLE; + if(pDesc->h264Conf.Intra4x4DiagDisable) pDesc->h264Conf.intra_disable |= INTRA4X4_DIAG_DISABLE; + if(pDesc->h264Conf.Intra4x4DirDisable) pDesc->h264Conf.intra_disable |= INTRA4X4_DIR_DISABLE; + if(pDesc->h264Conf.Intra16x16ParDisable) pDesc->h264Conf.intra_disable |= INTRA16X16_PAR_DISABLE; + if(pDesc->h264Conf.Intra16x16PlaneDisable) pDesc->h264Conf.intra_disable |= INTRA16X16_PLANE_DISABLE; + if(pDesc->h264Conf.ChromaIntraDisable) pDesc->h264Conf.intra_disable |= CHROMA_INTRA_DISABLE; +} + +/*! + ************************************************************************ + * \brief + * calculate Ceil(Log2(uiVal)) + ************************************************************************ + */ +PRIVATE t_uint32 CeilLog2( t_uint32 uiVal) +{ + t_uint32 uiTmp = uiVal-1; + t_uint32 uiRet = 0; + + while( uiTmp != 0 ) + { + uiTmp >>= 1; + uiRet++; + } + return uiRet; +} + +/*! + ************************************************************************ + * \brief + * Update host structure after a picture has been coded + ************************************************************************ + */ +void PostPicture (t_sva_service_instance_num instanceNum) +{ + t_sva_ec_h264_descriptor *pDesc = &h264EncodeDesc[instanceNum]; + t_p_ImageParameters p_img = &pDesc->images;//\/ + + /* now, only if current picture has been skipped, decrement effective coded picture counter */ + if (p_img->Skip_Current) + p_img->totskipped++; + else + p_img->CodedPictureCounter++; + + /* if the first IDR has been skipped (only in VBR case), keep track of SPS and PPS that have already been written in start sequence */ + if (!(!p_img->CodedPictureCounter && p_img->Skip_Current)) { + /* reset the bit counter for non VCL NALU for next AU */ + p_img->NonVCLNALUSize = 0; + } + + /* manage timestamp */ + p_img->timestamp_old = p_img->timestamp; + + /* if no timestamp file, just increment it */ +//\/ if(fp_timestamp == NULL) + p_img->timestamp++; //\/ +} + +/*********************************** Start: Code added for migration to MAINVER1.2 ***********************************/ +/*! + ************************************************************************ + * \brief + * This function writes an SPS into the stream + ************************************************************************ + */ +t_uint32 WriteSPS(t_sva_service_instance_num instanceNum, t_sva_data_unit_buffer *pOutBuf) +{ + t_uint32 len = 0; + t_NALU nalu; + t_p_NALU p_nalu = &nalu; + + /* NZ: rbsp buffer statically alloc'ed in host_nalucommon.h */ + p_nalu->buf = &rbsp[0]; + + GenerateSeq_parameter_set_NALU (instanceNum, p_nalu); + + len += WriteNALU (instanceNum, NON_VCL_NALU, p_nalu, pOutBuf); + +//\/#ifdef REPORT_EVERYTHING +//\/ stats->bit_ctr_parametersets += len; +//\/ stats->SPSbits += len; +//\/#endif + return len; +} + +/*! + ************************************************************************ + * \brief + * This function writes an PPS into the stream + ************************************************************************ + */ +t_uint32 WritePPS(t_sva_service_instance_num instanceNum, t_sva_data_unit_buffer *pOutBuf) +{ + t_uint32 len = 0; + t_NALU nalu; + t_p_NALU p_nalu = &nalu; + + /* NZ: rbsp buffer statically alloc'ed in host_nalucommon.h */ + p_nalu->buf = &rbsp[0]; + + GeneratePic_parameter_set_NALU (instanceNum, p_nalu); + + len += WriteNALU (instanceNum, NON_VCL_NALU, p_nalu, pOutBuf); + +//\/#ifdef REPORT_EVERYTHING +//\/ stats->bit_ctr_parametersets += len; +//\/ stats->PPSbits += len; +//\/#endif + return len; +} + +/*! +************************************************************************************* +* \brief +* t_uint16 getIndexFromLevel (void) +* +* \note +* This function returns the row index of LevelLimits table for current level +* +************************************************************************************* +*/ +t_uint16 getIndexFromLevel (t_uint16 level_idc, t_uint16 constraint_set3_flag) +{ + t_uint16 i; + for (i=0; i < 16; i++) { + if (level_idc == LevelLimits[i][0]) { + if (level_idc != 11) + break; + else { /* NZ: here surely i>0 !!*/ + if (constraint_set3_flag == 0) + break; + else { + i--; + break; + } + } + } + } + return i; +} + +/*! +************************************************************************************* +* \brief +* t_sint32 AutomaticLevelDetection(); +* +* \note +* Use the size/bitrate to detect minimum level for coding +* +************************************************************************************* +*/ + +void AutomaticLevelDetection( t_sva_service_instance_num instanceNum) +{ + t_sva_ec_h264_descriptor *pDesc = &h264EncodeDesc[instanceNum]; + t_p_ImageParameters p_img = &pDesc->images;//\/ + + + + +//\/ t_sva_video_encoder_algo_h264_configuration_params *pH264Conf; +//\/ t_sva_ec_h264_descriptor *pDesc = &h264EncodeDesc[instanceNum]; +//\/ pic_parameter_set_rbsp_t *pps = &pDesc->active_pps;//\/ +//\/ seq_parameter_set_rbsp_t *sps = &pDesc->active_sps;//\/ +//\/ ImageParameters *p_img = &pDesc->images;//\/ + t_uint16 i=0; + t_uint32 fr = pDesc->h264Conf.FrameRate; + +//\/ HCL_ASSERT(pConf != NULL); +//\/ pH264Conf = (t_sva_video_encoder_algo_h264_configuration_params *) pConf->pAlgoConfig; + + if (pDesc->h264Conf.level_idc == -1) { + while (i<16) { + if (LevelLimits[i][2] >= p_img->PicSizeInMbs ) + break; + else + i++; + } + while (i<16) + { + if ((t_sint32)LevelLimits[i][3]*1000 >= pDesc->h264Conf.bit_rate) + break; + else + i++; + } + while (i<16) + { + if (1024*LevelLimits[i][1] >= fr*p_img->PicSizeInMbs ) + break; + else + i++; + } + + /* level 1.0b should be indicated as 11 as set the flag constraint_set3_flag (otherwise always cleared) */ + if (LevelLimits[i][0] == 101) { + p_img->constraint_set3_flag = 1; + p_img->level_idc = 11; + } + else { + p_img->constraint_set3_flag = 0; + p_img->level_idc = (t_uint16)LevelLimits[i][0]; + } + } + else { /* no automatic level detection */ + p_img->constraint_set3_flag = 0; + p_img->level_idc = (t_uint16)pDesc->h264Conf.level_idc; + } +} + +/*! + ************************************************************************************* + * \brief + * t_uint32 ComputeMaxBitSizePerAU (void) + * + * \note + * This function compute the max size of a whole AU + * (passed to the BRC in order to limit the size of pictures) + * + ************************************************************************************* + */ +t_uint32 ComputeMaxBitSizePerAU (t_sva_service_instance_num instanceNum) +{ + t_uint32 MaxBitSizePerAU; + t_uint16 i; + t_sva_ec_h264_descriptor *pDesc = &h264EncodeDesc[instanceNum]; + t_p_ImageParameters p_img = &pDesc->images;//\/ + + i = getIndexFromLevel(p_img->level_idc, p_img->constraint_set3_flag); + + if (p_img->number == 0) { + MaxBitSizePerAU = (384 * p_img->PicSizeInMbs) / LevelLimits[i][5]; + } + else { + /* NZ: this 1000 is to take into account fractional frame rates */ + MaxBitSizePerAU = 1000*(384 * LevelLimits[i][1] / ((pDesc->h264Conf.FrameRate>>10)*1000) ) / LevelLimits[i][5]; + } + return MaxBitSizePerAU<<3; /* NZ: in bits */ +} + +/*! + ************************************************************************ + * \brief + * Set properly host structure before coding a picture + ************************************************************************ + */ + +void InitPicture (t_sva_service_instance_num instanceNum) +{ + t_sva_ec_h264_descriptor *pDesc = &h264EncodeDesc[instanceNum]; + t_p_ImageParameters p_img = &pDesc->images;//\/ + +//\/ pic_parameter_set_rbsp_t *active_pps = &pDesc->active_pps; + t_p_seq_parameter_set_rbsp p_active_sps = &pDesc->active_sps; + + + PRIVATE t_uint16 needSPSPPS = 0; + PRIVATE t_uint16 forceSPSPPS = 0; +//\/ t_uint16 ts_time_increment = TIME_STAMPS_REF_CLOCK/(t_uint32)pDesc->h264Conf.FrameRate; /*time increment: delta ticks between two frames*/ +//\/ t_uint16 i; + + +#if !defined(__CC_ARM) +//\/frame_no = IMG_NUMBER; +//\/ ReadOneFrame (frame_no, pDesc->h264Conf.infile_header, +//\/ pDesc->h264Conf.frame_width, pDesc->h264Conf.frame_height, pDesc->h264Conf.width_cr, pDesc->h264Conf.height_cr); +#endif + + +#ifdef REPORT_EVERYTHING + if (p_img->CodedPictureCounter) { + stats->SPSbits = 0; + stats->PPSbits = 0; + } + stats->SEIbits = 0; +#endif + + /* slice-loss reset it will be set by dynamic options only */ +//\/ for (i=0; i<8; i++) { /* HCL: Need to be discuss whether part of HCL or Appli */ +//\/ pDesc->h264Conf.slice_loss_first_mb[i] = 0; +//\/ pDesc->h264Conf.slice_loss_mb_num[i] = 0; +//\/ } + + /* reset IntraForced flag from input struct */ +//\/ pDesc->h264Conf.IntraForced = 0; //\/ This is not required for HCL + + /* set p_img IDR flag accordingly to input config, and set it if an IDR has been skipped */ + if (p_img->Skip_Current && (p_img->idr_flag == 1)) + p_img->idr_flag = 1; + else + p_img->idr_flag = (t_sint8)pDesc->h264Conf.idr_enable; + + + /* activate all dynamic options for this frame */ + /* HCL: The implementation of this part need to be taken care in HCL also while doing Dynamic parameter update */ +//\/ if(pDesc->h264Conf.DynoptFileName[0] != '\0') { +//\/ forceSPSPPS = dyn_check(p_img->number); +//\/ } + forceSPSPPS = NO_ACTION;//\/ Sarvesh + + /* management of grab timestamp (simulated by mean of an external file) */ +//\/ if(fp_timestamp != NULL) { +//\/ t_sint32 items = fscanf(fp_timestamp, "%ld", &(p_img->timestamp)); +//\/ if( items != 1 ) +//\/ error("EOF reading time-stamps file", 666); +//\/ /* normalize to ref clock */ +//\/ p_img->timestamp = (p_img->timestamp + (ts_time_increment>>1)) / ts_time_increment; +//\/ } + + if (forceSPSPPS == NO_ACTION) { + if (p_img->Skip_Current && (p_img->picture_coding_type==I_SLICE)) { + /* force to insert a intra picture */ + /* p_img->picture_coding_type = I_SLICE; */ + p_img->delta_ts = 0; + } + else + p_img->picture_coding_type = (t_uint8)p_img->imagetype_next; + } + else if (forceSPSPPS == SEND_SPS_AND_PPS) { +#ifndef NO_ADDITIONAL_SPS_PPS + p_img->picture_coding_type = I_SLICE; + p_img->idr_flag = 1; +#endif /* end of #ifndef NO_ADDITIONAL_SPS_PPS */ +//\/ p_img->picture_coding_type = I_SLICE; +//\/ p_img->idr_flag = 1; + } + + /* If equal to 1 current must be coded as Intra (if IDR or not is defined by config file) */ + if (pDesc->h264Conf.IntraForced) { + p_img->picture_coding_type = I_SLICE; + p_img->idr_flag = (t_sint8)pDesc->h264Conf.idr_enable; + p_img->delta_ts = 0; + } + + SetNextImageType(instanceNum); /* set in p_img->imagetype_next the type for next picture */ + + + /* compute poc and frame_num */ + p_img->frame_poc = (p_img->picture_coding_type == I_SLICE && p_img->idr_flag ? 0 : p_img->pic_counter-p_img->totskipped) * 2; + p_img->frame_num = (p_img->picture_coding_type == I_SLICE && p_img->idr_flag ? 0 : (p_img->pic_counter-p_img->totskipped)) % (1 << (log2_max_frame_num_minus4 + 4)); + + /* an IDR reset those counter */ + if (p_img->picture_coding_type == I_SLICE && p_img->idr_flag) { + p_img->pic_counter = 0; + p_img->totskipped = 0; + } + /*always incremented */ + p_img->pic_counter++; + +#ifdef NO_ADDITIONAL_SPS_PPS +if (forceSPSPPS == SEND_SPS_AND_PPS) { + /* update the bit_rate glob variable (used by BRC) */ + if (pDesc->h264Conf.HrdSendMessages) + bit_rate = (p_active_sps->vui_seq_parameters.nal_hrd_parameters.bit_rate_value_minus1[0] + 1 ) * (1 << (p_active_sps->vui_seq_parameters.nal_hrd_parameters.bit_rate_scale + 6)); + else + bit_rate = pDesc->h264Conf.bit_rate; +} +#else /* else of #ifdef NO_ADDITIONAL_SPS_PPS */ + /* managment of starting of a new coded sequence (SPS+PPS+IDR) ) */ + if (needSPSPPS || (!needSPSPPS && (forceSPSPPS == SEND_SPS_AND_PPS))) { + if (!p_img->Skip_Next) { + /* force and IDR */ + p_img->picture_coding_type = I_SLICE; + p_img->idr_flag = 1; + + /* increment SPS idc */ + p_img->seq_parameter_set_idc = (p_img->seq_parameter_set_idc+1) % 32; + + /* detect new level */ + AutomaticLevelDetection(instanceNum); + + /* fill SPS and PPS data structure accordingly to new bitrate/framerate/level */ + FillParameterSetStructures (instanceNum); + + /* update the bit_rate glob variable (used by BRC) */ + if (pDesc->h264Conf.HrdSendMessages) + g_bit_rate_val = (p_active_sps->vui_seq_parameters.nal_hrd_parameters.bit_rate_value_minus1[0] + 1 ) * (1 << (p_active_sps->vui_seq_parameters.nal_hrd_parameters.bit_rate_scale + 6)); + else + g_bit_rate_val = pDesc->h264Conf.bit_rate; + + /* write the new SPS */ + //\/ Sarvesh: This will be done alternatevely in HCL code +//\/ p_img->NonVCLNALUSize += WriteSPS(); + + /* write the new PPS */ + //\/ Sarvesh: This will be done alternatevely in HCL code +//\/ p_img->NonVCLNALUSize += WritePPS(); + + /* SPS + PPS no more needed */ + needSPSPPS = 0; + } + else { + /* still need SPS + PPS since also this has been skipped */ + needSPSPPS = 1; + } + } +#endif /* end of #ifdef NO_ADDITIONAL_SPS_PPS */ +} + +/*! + ************************************************************************ + * \brief + * Set the image type for I and P + ************************************************************************ + */ +void SetNextImageType(t_sva_service_instance_num instanceNum) +{ + t_sva_ec_h264_descriptor *pDesc = &h264EncodeDesc[instanceNum]; + t_p_ImageParameters p_img = &pDesc->images;//\/ + t_sint32 numb_intra_period; + + /* if the number of I_SLICE intra period is set to zero we assert the number of P_SLICE to be max as possible */ + if (pDesc->h264Conf.intra_period == 0) + numb_intra_period = MAX_VALUE; + else + numb_intra_period = pDesc->h264Conf.intra_period; + + /* number of frames between two different I_SLICE, reset to zero after coding a single I_SLICE */ + p_img->delta_ts = p_img->delta_ts + (p_img->timestamp - p_img->timestamp_old); + + if (p_img->delta_ts >= numb_intra_period) { + p_img->imagetype_next = I_SLICE; + p_img->delta_ts = 0; + } + else + p_img->imagetype_next = P_SLICE; + +} +/************************************ End: Code added for migration to MAINVER1.2 ************************************/ + +/*********************************** Start: Code added for migration to MAINVER1.2b ***********************************/ +t_uint32 WriteNALU (t_sva_service_instance_num instanceNum, t_NALUflavour flavour, t_p_NALU p_nalu, t_sva_data_unit_buffer *pOutBuf) +{ + t_sva_ec_h264_descriptor *pDesc = &h264EncodeDesc[instanceNum]; + t_sint32 BitsWritten = 0; + t_uint8 bitMask=0xFF; + t_uint32 i = 0; + + HCL_ASSERT (p_nalu != NULL); +//\/ HCL_ASSERT (p_out != NULL); + + if (pDesc->h264Conf.annexb) +//\/ if (pDesc->h264Conf.annexb) + { +//\/ fwrite ((void*)&(p_nalu->len),sizeof(t_uint32),1,p_out); + pOutBuf->pOBuf[pOutBuf->byteCount++] = (t_uint8) (p_nalu->len>>0) & bitMask; + pOutBuf->pOBuf[pOutBuf->byteCount++] = (t_uint8) (p_nalu->len>>8) & bitMask; + pOutBuf->pOBuf[pOutBuf->byteCount++] = (t_uint8)(p_nalu->len>>16) & bitMask; + pOutBuf->pOBuf[pOutBuf->byteCount++] = (t_uint8)(p_nalu->len>>24) & bitMask; + BitsWritten =+ 32; + } + else { + if (flavour == NON_VCL_NALU) { + if (p_nalu->startcodeprefix_len > 3) { +//\/ putc (0, p_out); +//\/ BitsWritten =+ 8; + pOutBuf->pOBuf[pOutBuf->byteCount++] = 0; + BitsWritten =+ 8; + } +//\/ putc (0, p_out); +//\/ putc (0, p_out); +//\/ putc (1, p_out); +//\/ BitsWritten += 24; + pOutBuf->pOBuf[pOutBuf->byteCount++] = 0; + pOutBuf->pOBuf[pOutBuf->byteCount++] = 0; + pOutBuf->pOBuf[pOutBuf->byteCount++] = 1; + BitsWritten += 24; + } + /* + else { + NZ: for VCL_NALU NALU, when pDesc->h264Conf.annexb = 0 (AnnexB) startcode is already inserted by FW + } + */ + } + +//\/ if (p_nalu->len != fwrite (p_nalu->buf, 1, p_nalu->len , p_out)) { +//\/ printf ("Fatal: cannot write %d bytes to bitstream file, exit (-1)\n", p_nalu->len); +//\/ exit (-1); +//\/ } +//\/ BitsWritten += p_nalu->len * 8; + + for (i = 0; i < p_nalu->len; i++) + { + pOutBuf->pOBuf[pOutBuf->byteCount++] = p_nalu->buf[i]; + } + BitsWritten += p_nalu->len * 8; + +//\/ fflush (p_out); + return BitsWritten; +} +/************************************ End: Code added for migration to MAINVER1.2b ************************************/ + +/* End of file - sva_ec_h264.c */ + --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/encode/h264/sva_ec_h264.h @@ -0,0 +1,79 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ +#ifndef _SVA_EC_H264_H_ +#define _SVA_EC_H264_H_ + +#include "hcl_defs.h" +#include "sva_encode.h" +//\/#include "../sva_ec_algo.h" +#include "sva_ec_algo.h" +#include "sva.h" + +/******************************************************************************/ +/* PUBLIC Functions */ +/******************************************************************************/ +PUBLIC t_sva_ec_algo_error sva_EC_H264_AlgoInit(t_sva_service_instance_num, const t_sva_video_encoder_configuration *); +PUBLIC t_sva_ec_algo_error sva_EC_H264_GetInternalNeeds(t_sva_service_instance_num, t_size *); +//\/PUBLIC t_sva_ec_algo_error sva_EC_H264_ProvideMemoryNeeds(t_sva_service_instance_num); +PUBLIC t_sva_ec_algo_error sva_EC_H264_ProvideMemoryNeeds(t_sva_service_instance_num instanceNum, const t_sva_tm_subtask_id *pSubtaskIdArray); +PUBLIC t_sva_ec_algo_error sva_EC_H264_EncodeAlgoDelete(t_sva_service_instance_num); +PUBLIC t_sva_ec_algo_error sva_EC_H264_UpdateVideoEncoderParams + ( + t_sva_service_instance_num, + t_sva_update_cmd_type, + t_sva_video_encoder_param_id, + t_uint32 + ); +PUBLIC t_sva_ec_algo_error sva_EC_H264_PushImageInfo(t_sva_service_instance_num, const t_sva_ec_algo_image_info *); +PUBLIC t_sva_ec_algo_error sva_EC_H264_GetNextFrameParamIn(t_sva_service_instance_num, t_sva_ec_algo_params_in *); +PUBLIC t_sva_ec_algo_error sva_EC_H264_GetNextHeader(t_sva_service_instance_num, t_sva_ec_algo_header *, t_size *); +PUBLIC t_sva_ec_algo_error sva_EC_H264_InitParamInOut(t_sva_service_instance_num, t_sva_ec_algo_params_inout *); +PUBLIC t_sva_ec_algo_error sva_EC_H264_SetFrameParamOut + ( + t_sva_service_instance_num, + const t_sva_ec_algo_params_out *, + const t_sva_ec_algo_params_inout * + ); +PUBLIC t_sva_ec_algo_error sva_EC_H264_GetSkipInfo(t_sva_service_instance_num, t_bool *, t_bool *); +PUBLIC t_sva_ec_algo_error sva_EC_H264_GetBitstreamSize(t_sva_service_instance_num, t_size *); +PUBLIC t_sva_ec_algo_error sva_EC_H264_FillInfosBuffer(t_sva_service_instance_num, t_sva_buffer_id); +PUBLIC t_bool sva_EC_H264_IsPreviousPictureWasStategicSkip(t_sva_service_instance_num); +PUBLIC t_size sva_EC_H264_GetParamsInSize(t_sva_service_instance_num); +PUBLIC t_size sva_EC_H264_GetParamsOutSize(t_sva_service_instance_num); +PUBLIC t_size sva_EC_H264_GetParamsInOutSize(t_sva_service_instance_num); +PUBLIC t_size sva_EC_H264_GetMaxHeaderSize(t_sva_service_instance_num); +PUBLIC t_sva_fw_features sva_EC_H264_GetFeatures(t_sva_service_instance_num); +PUBLIC t_sva_ec_algo_error sva_EC_H264_GenerateBitStreamDataUnits(t_sva_service_instance_num instanceNum, + t_sva_data_unit_type data_unit_type, t_sva_data_unit_buffer *pOutBuf); +PUBLIC t_sva_ec_algo_error sva_EC_H264_PatchBitstream + ( + t_sva_service_instance_num, + const t_sva_ec_algo_params_in *, + t_logical_address + ); + +#ifdef __cplusplus +} /* allow C++ to use these headers */ +#endif /* __cplusplus */ + + +#endif /* _SVA_EC_H264_H_ */ + +/* End of file - sva_ec_h264.h */ + --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/encode/h264/sva_ec_h264p.h @@ -0,0 +1,646 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ +#ifndef _SVA_EC_H264P_H_ +#define _SVA_EC_H264P_H_ + +#include "hcl_defs.h" +#include "sva.h" +#include "sva_encode.h" +#include "sva_ec_algo.h" +#include "sva_brc.h" + +/******************************************************************************/ +/* Constants definitions */ +/******************************************************************************/ +/*------------------------------------------------------------------* + * Define the maximum number of h264 encode structure to maintain * + *------------------------------------------------------------------*/ +#define NUM_MAX_H264_ENCODE 4 + +/*--------------------------------------------------------------* + * Define the clockSlot value for short header in 90Khz value * + *--------------------------------------------------------------*/ +//\/#define H264_ANNEXB_CLOCK_SLOT (1001 * 90000 / 30000) + +/*--------------------------------------------------------------* + * Define the rounding value for temporal reference computation * + *--------------------------------------------------------------*/ +//\/#define H264_ANNEXB_ROUND_VALUE 1500 + +/*----------------------------------* + * Define value for picture type * + *----------------------------------*/ +//\/#define SVA_H264_I_PICTURE 0 +//\/#define SVA_H264_P_PICTURE 1 + +/*------------------------------------------------------------------* + * Define various configuration limits for h264 encode SH or SP * + *------------------------------------------------------------------*/ +/* Define source frame limits */ +#define SVA_EC_H264_SOURCE_FRAME_HEIGHT_ALIGN 16 +#define SVA_EC_H264_SOURCE_FRAME_HEIGHT_MIN 16 +#define SVA_EC_H264_SOURCE_FRAME_HEIGHT_MAX 480 +#define SVA_EC_H264_SOURCE_FRAME_WIDTH_ALIGN 16 +#define SVA_EC_H264_SOURCE_FRAME_WIDTH_MIN 16 +#define SVA_EC_H264_SOURCE_FRAME_WIDTH_MAX 640 + +/* Define cropping window limits */ +#define SVA_EC_H264_SOURCE_WINDOW_HEIGHT_ALIGN 16 +#define SVA_EC_H264_SOURCE_WINDOW_HEIGHT_MIN 16 +#define SVA_EC_H264_SOURCE_WINDOW_WIDTH_ALIGN 16 +#define SVA_EC_H264_SOURCE_WINDOW_WIDTH_MIN 16 +#define SVA_EC_H264_SOURCE_WINDOW_OFFSET_X_ALIGN 1 +#define SVA_EC_H264_SOURCE_WINDOW_OFFSET_X_MIN 0 +#define SVA_EC_H264_SOURCE_WINDOW_OFFSET_Y_ALIGN 1 +#define SVA_EC_H264_SOURCE_WINDOW_OFFSET_Y_MIN 0 + +/* Define limits for partinioned */ +#define SVA_EC_H264_SOURCE_WINDOW_HEIGHT_PARTITIONED_MAX 288 +#define SVA_EC_H264_SOURCE_WINDOW_WIDTH_PARTITIONED_MAX 352 + +/*------------------------------------------------------* + * Define supported size for H264 short header mode. * + * Last two are custom mode * + *------------------------------------------------------*/ +#define SVA_EC_H264_SQCIF_WIDTH 128 +#define SVA_EC_H264_SQCIF_HEIGHT 96 +#define SVA_EC_H264_QCIF_WIDTH 176 +#define SVA_EC_H264_QCIF_HEIGHT 144 +#define SVA_EC_H264_CIF_WIDTH 352 +#define SVA_EC_H264_CIF_HEIGHT 288 +#define SVA_EC_H264_CIF4_WIDTH 704 +#define SVA_EC_H264_CIF4_HEIGHT 576 +#define SVA_EC_H264_CIF16_WIDTH 1408 +#define SVA_EC_H264_CIF16_HEIGHT 1152 +#define SVA_EC_H264_VGA_WIDTH 640 +#define SVA_EC_H264_VGA_HEIGHT 480 +#define SVA_EC_H264_MB1_WIDTH 16 +#define SVA_EC_H264_MB1_HEIGHT 16 + +/*--------------------------------------------------* + * Define supported size for H264 short header mode * + * last two are custom mode * + *--------------------------------------------------*/ +#define SVA_EC_H264_ANNEXB_SOURCE_FORMAT_SQCIF 1 +#define SVA_EC_H264_ANNEXB_SOURCE_FORMAT_QCIF 2 +#define SVA_EC_H264_ANNEXB_SOURCE_FORMAT_CIF 3 +#define SVA_EC_H264_ANNEXB_SOURCE_FORMAT_CIF4 4 +#define SVA_EC_H264_ANNEXB_SOURCE_FORMAT_CIF16 5 +#define SVA_EC_H264_ANNEXB_SOURCE_FORMAT_VGA 6 +#define SVA_EC_H264_ANNEXB_SOURCE_FORMAT_MB1 7 + +/*--------------------------------------* + * Define vop constant to write in SP * + *--------------------------------------*/ +//\/ Sarvesh: Remove these defines as these are related to MPEG4 standard +//\/#define SVA_H264_VOS_START_CODE 0x000001b0 +//\/#define SVA_H264_VISUAL_OBJECT_START_CODE 0x000001b5 +//\/#define SVA_H264_VIDEO_OBJECT_TYPE 1 +//\/#define SVA_H264_VIDEO_OBJECT_START_CODE 0x00000100 +//\/#define SVA_H264_VOL_START_CODE 0x00000120 +//\/#define SVA_H264_SIMPLE_OBJECT_TYPE 1 +//\/#define SVA_H264_SQUARE_ASPECT_RATIO 1 +//\/#define SVA_H264_VBV_PRESENT 1 +//\/#define SVA_H264_NO_VBV_PRESENT 0 +//\/#define SVA_H264_CHROMA_4_2_0 1 +//\/#define SVA_H264_VIDEO_RECTANGULAR_SHAPE 0 + +//\/#define SVA_H264_VOP_START_CODE 0x000001b6 +//\/#define SVA_H264_SLICE_CODING_TYPE_I 0 +//\/#define SVA_H264_SLICE_CODING_TYPE_P 1 +//\/#define SVA_H264_SLICE_CODING_TYPE_I 2 +//\/#define SVA_H264_SLICE_CODING_TYPE_P 0 + +//\/#define SVA_H264_BASE_LINE_PROFILE_IDC 66 + +//\/#define SVA_H264_MARKER_BIT 1 +//\/#define SVA_H264_VOP_CODED 1 +//\/#define SVA_RTYPE_MODE_CONSTANT_ZERO 0 +//\/#define SVA_RTYPE_MODE_CONSTANT_ONE 1 +//\/#define SVA_H264_INTRA_DC_VLC_THR 0 + +/*----------------------------------* + * Define max header size in byte * + *----------------------------------*/ + +#define SVA_EC_H264_ANNEXB_MAX_HEADER_SIZE 6 + + +//\/#define SVA_EC_H264_SP_MAX_HEADER_SIZE 56 + +//\/ Sarvesh: Check this value as this is 32 for MPEG4 +//\/#define SVA_EC_H264_SLICE_POS_COUNT 1320 +//\/#define SVA_EC_H264_SLICE_POS_COUNT 1620 + +//\/#define MAXRBSPSIZE 64000 +//\/#define MAX_NALU_BUFF_SIZE 64000 +//\/#define NALU_TYPE_SLICE 1 +//\/#define NALU_TYPE_DPA 2 +//\/#define NALU_TYPE_DPB 3 +//\/#define NALU_TYPE_DPC 4 +//\/#define NALU_TYPE_IDR 5 +//\/#define NALU_TYPE_SEI 6 +//\/#define NALU_TYPE_SPS 7 +//\/#define NALU_TYPE_PPS 8 +//\/#define NALU_TYPE_AUD 9 +//\/#define NALU_TYPE_EOSEQ 10 +//\/#define NALU_TYPE_EOSTREAM 11 +//\/#define NALU_TYPE_FILL 12 +//\/ +//\/#define NALU_PRIORITY_HIGHEST 3 +//\/#define NALU_PRIORITY_HIGH 2 +//\/#define NALU_PRIRITY_LOW 1 +//\/#define NALU_PRIORITY_DISPOSABLE 0 + +//\/#define PIC_PARAMETER_SET_ID 0 +//\/#define DEBLOCKING_FILTER_CONTROL_PRESENT_FLAG 1 +//\/#define PIC_INIT_QP_MINUS26 0 +//\/#define DELTA_PIC_ORDER_ALWAYS_ZERO_FLAG 0 +//\/#define PIC_ORDER_PRESENT_FLAG 0 +//\/#define NUM_REF_IDX_L0_ACTIVE_MINUS1 0 + +//\/#define MAX_REF_BITS 32 /* FP: this has to be checked !!! Temporary value. */ +//\/#define MAX_WIDTH 720 /* RR: SDTV max */ +//\/#define MAX_HEIGHT 480 /* RR: SDTV max */ +//\/#define MAX_FRAME_SIZE_MBS ((MAX_WIDTH/MB_BLOCK_SIZE)*(MAX_HEIGHT/MB_BLOCK_SIZE)) +//\/#define MAX_STREAMBUF_SIZE (MAX_WIDTH*MAX_HEIGHT*8) /* FP: max bitstream size per slice, 4 == safety margin */ + +//\/#define ZEROBYTES_SHORTSTARTCODE 2 /* indicates the number of zero bytes in the short start-code prefix */ + +/* The reference grabbing frequency [Hz] */ +//\/#define TIME_STAMPS_REF_CLOCK 90000 + + +/*********************************** Start: Code added for migration to MAINVER1.2 ***********************************/ +#define NALU_PRIORITY_HIGHEST 3 +#define NALU_PRIORITY_HIGH 2 +#define NALU_PRIRITY_LOW 1 +#define NALU_PRIORITY_DISPOSABLE 0 + +#define NALU_TYPE_SLICE 1 +#define NALU_TYPE_DPA 2 +#define NALU_TYPE_DPB 3 +#define NALU_TYPE_DPC 4 +#define NALU_TYPE_IDR 5 +#define NALU_TYPE_SEI 6 +#define NALU_TYPE_SPS 7 +#define NALU_TYPE_PPS 8 +#define NALU_TYPE_AUD 9 +#define NALU_TYPE_EOSEQ 10 +#define NALU_TYPE_EOSTREAM 11 +#define NALU_TYPE_FILL 12 + +/* FREXT Profile IDC definitions */ +#define FREXT_HP 100 /* YUV 4:2:0/8 "High" */ +#define FREXT_Hi10P 110 /* YUV 4:2:0/10 "High 10" */ +#define FREXT_Hi422 122 /* YUV 4:2:2/10 "High 4:2:2" */ +#define FREXT_Hi444 144 /* YUV 4:4:4/12 "High 4:4:4" */ + +#define MB_BLOCK_SIZE 16 + +/* NZ: deblocking filter control */ +#define DEBLOCKING_FILTER_CONTROL_PRESENT_FLAG 1 + +/* some VUI defines */ +#define ASPECT_RATIO_INFO_PRESENT_FLAG 1 +#define EXTENDED_SAR 255 + +/* NZ: When SEI are enabled defines which type of bitstream HRD compliancy (type 1 or 2) */ +#define NAL_HRD_PARAMETERS_PRESENT_FLAG 1 +#define VCL_HRD_PARAMETERS_PRESENT_FLAG 1 +#define PIC_STRUCT_PRESENT_FLAG 0 +#define BITSTREAM_RESTRICTION_FLAG 1 + +/* NZ: Accuracy control in VUI/SEI time base */ +/* Number of Bits used to encode CPB_Removal_Delay in Picture Timing SEI Messages */ +#define SEI_INITIAL_CPB_REMOVAL_DELAY_BITS 28 +#define SEI_CPB_REMOVAL_DELAY_BITS 16 +#define SEI_DPB_REMOVAL_DELAY_BITS 16 + +#define absm(A) ((A)<(0) ? (-(A)):(A)) /* abs macro, faster than procedure */ +#define MAX_VALUE 999999L /* used for start value for some variables */ + +/* H264 Encode defines */ +//\/#define PROFILE_IDC 66 +#define INIT_FRAME_RATE 30 + +/* FP: Bit Rate Control Algorithms (brc_type) */ +#define CONST_QP_NO_BUFF 0 +#define FRAME_BASED_BRC 1 +#define LOW_DELAY_CBR 2 +#define LVR_MMS_VBR 3 + +/* FP: mask-bits to disable specific INTRA modes */ +#define INTRA_DISABLE_INTER_ONLY 1 +#define INTRA4X4_PAR_DISABLE 2 +#define INTRA4X4_DIAG_DISABLE 4 +#define INTRA4X4_DIR_DISABLE 8 +#define INTRA16X16_PAR_DISABLE 16 +#define INTRA16X16_PLANE_DISABLE 32 +#define CHROMA_INTRA_DISABLE 64 + +#define Clip3(min,max,val) (((val)<(min))?(min):(((val)>(max))?(max):(val))) +#define max(a, b) (((a) > (b)) ? (a) : (b)) +#define min(a, b) (((a) < (b)) ? (a) : (b)) + +/* FP: the different Motion Estimation Algorithms */ +#define ME8815_ST 0 +#define ME_ST 1 + +/* FP: these are the default settings used in the SLICE header */ +#define PIC_PARAMETER_SET_ID 0 +#define PIC_INIT_QP_MINUS26 0 +#define DELTA_PIC_ORDER_ALWAYS_ZERO_FLAG 0 +#define PIC_ORDER_PRESENT_FLAG 0 +#define NUM_REF_IDX_L0_ACTIVE_MINUS1 0 + +/* Start code and Emulation Prevention need this to be defined in identical manner at encoder and decoder */ +#define ZEROBYTES_SHORTSTARTCODE 2 /* indicates the number of zero bytes in the short start-code prefix */ + +/* The reference grabbing frequency [Hz] */ +#define TIME_STAMPS_REF_CLOCK 90000 + +/* NZ: Multiple SPS/PPS control */ +#define NO_ACTION 0 +#define SEND_SPS 1 +#define SEND_PPS 2 +#define SEND_SPS_AND_PPS 3 +#define IMG_NUMBER (p_img->number) + +//\/#define NONVCL_BUFFER_SIZE 2048 +#define NONVCL_BUFFER_SIZE 128 +/************************************ End: Code added for migration to MAINVER1.2 ************************************/ + +/*********************************** Start: Code added for migration to MAINVER1.2b ***********************************/ +/* NZ: maximun cpb leaky bucket model in HRD */ +#define MAXIMUMVALUEOFcpb_cnt 32 + +/* NZ: This define is used to avoid the insertion of a new SPS+PPS+IDR when a change of Bit rate or Frame Rate occurs. + In this case only the new value of target bit rate is updated, but the compliancy of the stream cannot be assessed. */ +/* #define NO_ADDITIONAL_SPS_PPS */ +/************************************ End: Code added for migration to MAINVER1.2b ************************************/ + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + + +/******************************************************************************/ +/* Types definitions */ +/******************************************************************************/ + +/*--------------------------------------------------* + * Define the structure to handle bitstream write * + *--------------------------------------------------*/ +//\/ Sarvesh: This structure should be removed, it is used for the header buffer +typedef struct +{ + /* Scratch buffer handling */ + t_uint64 buffer; + t_uint32 nbBitsValid; + + /* Destination buffer */ + t_uint8 *currBuffer; + t_uint8 *endBuffer; + + /* Save total write bits */ + t_uint32 totalBitsWritten; +} t_sva_ec_h264_write_stream; + +/*--------------------------------------------------* + * Define the structure to handle temporal value * + *--------------------------------------------------*/ +//\/typedef struct +//\/{ +//\/ t_uint32 tr; +//\/ t_sint32 cumulTimeSlot; +//\/ t_uint32 slotDelay; +//\/} t_sva_ec_h264_sh_temporal; + +/*------------------------------------------------------* + * Define the structure to handle temporal value for SP * + *------------------------------------------------------*/ +//\/typedef struct +//\/{ +//\/ /* Remain of previous division when convert diff from 90000 Hz to vopTimeIncrementResolution Hz */ +//\/ t_uint32 remainForOffset; +//\/ +//\/ /* Temporal data value */ +//\/ t_uint32 moduloTimeBase; +//\/ t_uint32 vopTimeIncrement; +//\/ +//\/ /* Save vopTimeIncrementBitSize */ +//\/ t_uint32 vopTimeIncrementBitSize; +//\/} t_sva_ec_h264_sp_temporal; + +/*----------------------------------------------------------* + * Define the type that keep all data need for skip fifo * + *----------------------------------------------------------*/ +typedef struct +{ + t_sva_timestamp_value pts; + t_uint32 pictureNb; + t_uint16 roundValue; //\/ Used for Motion compensation, may not be updated for first release + + /* Short header specific */ + t_uint16 pictureCodingType; +//\/ t_sva_ec_h264_sh_temporal temporalSh; +//\/ t_uint16 gobFrameId; + + /* Simple profile specific */ +//\/ t_sva_ec_h264_sp_temporal temporalSp; +} t_sva_ec_save; + + +//\/ ref: parsetcommon.h structures +//\/#define MAXIMUMPARSETRBSPSIZE 1500 +//\/#define MAXIMUMPARSETNALUSIZE 1500 +//\/#define SIZEslice_group_id (sizeof (byte) * 60000) /* should be sufficient for HUGE pictures, need one t_sint32 per MB in a picture */ + +//\/#define MAXSPS 32 +//\/#define MAXPPS 256 + +//\/#define MAXIMUMVALUEOFcpb_cnt 32 +typedef struct { + t_uint32 cpb_cnt_minus1; /* ue(v) */ + t_uint32 bit_rate_scale; /* u(4) */ + t_uint32 cpb_size_scale; /* u(4) */ + t_uint32 bit_rate_value_minus1 [MAXIMUMVALUEOFcpb_cnt]; /* ue(v) */ + t_uint32 cpb_size_value_minus1[MAXIMUMVALUEOFcpb_cnt]; /* ue(v) */ + t_uint32 cbr_flag[MAXIMUMVALUEOFcpb_cnt]; /* u(1) */ + t_uint32 initial_cpb_removal_delay_length_minus1; /* u(5) */ + t_uint32 cpb_removal_delay_length_minus1; /* u(5) */ + t_uint32 dpb_output_delay_length_minus1; /* u(5) */ + t_uint32 time_offset_length; /* u(5) */ +} t_hrd_parameters; + +typedef struct { + t_sint32 aspect_ratio_info_present_flag; /* u(1) */ + t_uint32 aspect_ratio_idc; /* u(8) */ + t_uint16 sar_width; /* u(16) */ + t_uint16 sar_height; /* u(16) */ + t_sint32 overscan_info_present_flag; /* u(1) */ + t_sint32 overscan_appropriate_flag; /* u(1) */ + t_sint32 video_signal_type_present_flag; /* u(1) */ + t_uint32 video_format; /* u(3) */ + t_sint32 video_full_range_flag; /* u(1) */ + t_sint32 colour_description_present_flag; /* u(1) */ + t_uint32 colour_primaries; /* u(8) */ + t_uint32 transfer_characteristics; /* u(8) */ + t_uint32 matrix_coefficients; /* u(8) */ + t_sint32 chroma_location_info_present_flag; /* u(1) */ + t_uint32 chroma_sample_loc_type_top_field; /* ue(v) */ + t_uint32 chroma_sample_loc_type_bottom_field; /* ue(v) */ + t_sint32 timing_info_present_flag; /* u(1) */ + t_uint32 num_units_in_tick; /* u(32) */ + t_uint32 time_scale; /* u(32) */ + t_sint32 fixed_frame_rate_flag; /* u(1) */ + t_sint32 nal_hrd_parameters_present_flag; /* u(1) */ + t_hrd_parameters nal_hrd_parameters; /* t_hrd_paramters */ + t_sint32 vcl_hrd_parameters_present_flag; /* u(1) */ + t_hrd_parameters vcl_hrd_parameters; /* t_hrd_paramters */ + /* if ((nal_hrd_parameters_present_flag || (vcl_hrd_parameters_present_flag)) */ + t_sint32 low_delay_hrd_flag; /* u(1) */ + t_sint32 pic_struct_present_flag; /* u(1) */ + t_sint32 bitstream_restriction_flag; /* u(1) */ + t_sint32 motion_vectors_over_pic_boundaries_flag; /* u(1) */ + t_uint32 max_bytes_per_pic_denom; /* ue(v) */ + t_uint32 max_bits_per_mb_denom; /* ue(v) */ + t_uint32 log2_max_mv_length_vertical; /* ue(v) */ + t_uint32 log2_max_mv_length_horizontal; /* ue(v) */ + t_uint32 num_reorder_frames; /* ue(v) */ + t_uint32 max_dec_frame_buffering; /* ue(v) */ +} t_vui_seq_parameters; + +/*\/ Sarvesh: test application/Utils */ +typedef struct { + t_uint32 seq_parameter_set_id; /* ue(v) */ + t_sint32 entropy_coding_mode_flag; /* u(1) */ + t_sint32 pic_scaling_matrix_present_flag; /* u(1) */ + t_sint32 pic_scaling_list_present_flag[8]; /* u(1) */ + t_sint32 pic_init_qs_minus26; /* se(v) */ + t_sint32 chroma_qp_index_offset; /* se(v) */ + t_sint32 deblocking_filter_control_present_flag; /* u(1) */ + t_sint32 constrained_intra_pred_flag; /* u(1) */ + t_sint32 redundant_pic_cnt_present_flag; /* u(1) */ + t_sint32 vui_pic_parameters_flag; /* u(1) */ +} t_pic_parameter_set_rbsp, *t_p_pic_parameter_set_rbsp; + +#define MAXnum_ref_frames_in_pic_order_cnt_cycle 256 +typedef struct { + t_uint32 profile_idc; /* u(8) */ + t_sint32 constrained_set0_flag; /* u(1) */ + t_sint32 constrained_set1_flag; /* u(1) */ + t_sint32 constrained_set2_flag; /* u(1) */ + t_sint32 constrained_set3_flag; /* u(1) */ + t_uint32 level_idc; /* u(8) */ + t_uint32 seq_parameter_set_id; /* ue(v) */ + t_sint32 seq_scaling_list_present_flag[8]; /* u(1) */ + t_uint32 bit_depth_luma_minus8; /* ue(v) */ + t_uint32 bit_depth_chroma_minus8; /* ue(v) */ + t_sint16 log2_max_frame_num_minus4; /* ue(v) */ + t_uint32 pic_order_cnt_type; + /* if( pic_order_cnt_type == 0 ) */ + t_sint16 log2_max_pic_order_cnt_lsb_minus4; /* ue(v) */ + /* else if( pic_order_cnt_type == 1 ) */ + t_sint32 offset_for_non_ref_pic; /* se(v) */ + t_uint32 num_ref_frames_in_pic_order_cnt_cycle; /* ue(v) */ + /* for( i = 0; i < num_ref_frames_in_pic_order_cnt_cycle; i++ ) */ + t_sint32 offset_for_ref_frame[MAXnum_ref_frames_in_pic_order_cnt_cycle]; /* se(v) */ + t_sint32 gaps_in_frame_num_value_allowed_flag; /* u(1) */ + t_uint32 pic_width_in_mbs_minus1; /* ue(v) */ + t_uint32 pic_height_in_map_units_minus1; /* ue(v) */ + t_sint32 frame_cropping_flag; /* u(1) */ + t_uint32 frame_cropping_rect_left_offset; /* ue(v) */ + t_uint32 frame_cropping_rect_right_offset; /* ue(v) */ + t_uint32 frame_cropping_rect_top_offset; /* ue(v) */ + t_uint32 frame_cropping_rect_bottom_offset; /* ue(v) */ + t_sint32 vui_parameters_present_flag; /* u(1) */ + t_vui_seq_parameters vui_seq_parameters; /* t_vui_seq_parameters */ +} t_seq_parameter_set_rbsp, *t_p_seq_parameter_set_rbsp; + +typedef struct +{ + t_uint32 number; /* current image number to be encoded */ + + t_uint32 pic_counter; + t_uint16 totskipped; + + t_uint16 imagetype_next; /* the type of the frame we are going to give to "BRC_InitPict" */ + + t_uint32 CodedPictureCounter; /* Coded picture counter */ + t_uint8 picture_coding_type; +//\/ t_sint8 quant; /* quant for the current frame */ + t_uint8 SeinitialQP; + /* t_sint32 tr;*/ + + t_sint32 frame_poc; + t_uint32 frame_num; /* frame_num for this frame */ + + t_uint8 PicWidthInMbs; + t_uint8 PicHeightInMbs; + t_uint16 PicSizeInMbs; + + + t_uint16 Skip_Next; + t_uint16 Skip_Current; + + + t_sint32 timestamp; /* timestamps number of current frame given in input */ + t_sint32 timestamp_old; /* number of previous timestamp, use to count the skipped frames */ + t_sint32 delta_ts; + + t_sint8 idr_flag; + t_uint16 level_idc; + t_uint16 constraint_set3_flag; + + t_uint16 seq_parameter_set_idc; + + t_uint32 NonVCLNALUSize; + + t_uint32 NALfinal_arrival_time; + +} t_ImageParameters, *t_p_ImageParameters; + +/* Bitstream */ +typedef struct +{ + t_sint32 byte_pos; /* current position in bitstream; */ + t_sint8 bits_to_go; /* current bitcounter */ + t_uint32 byte_buf; /* current buffer for last written byte */ + t_uint8 *streamBuffer; /* actual buffer for written bytes */ +} Bitstream; + +#if TRACE +/* Syntaxelement */ +typedef struct syntaxelement +{ + t_sint16 value1; /* numerical value of syntax element */ + t_sint8 nbit; /* length of code */ + t_uint32 data; /* UVLC bitpattern */ + #define TRACESTRING_SIZE 100 /* size of trace string */ + char tracestring[TRACESTRING_SIZE]; /* trace string */ +} SyntaxElement; +#endif /* end #if TRACE */ + +/*--------------------------------------------------* + * Define the descriptor of a h264 encode instance * + *--------------------------------------------------*/ +//\/ Sarvesh: Check this +typedef struct +{ + t_sva_video_encoder_configuration conf; + t_sva_video_encoder_algo_h264_configuration_params h264Conf; + t_bool isFlagIntraRequest; + + /* Dynamic conf change stuff */ + t_sva_video_encoder_algo_h264_configuration_params h264NextConf; + t_uint16 frameRate; + t_uint16 nextFrameRate; + t_sva_intra_request intraRequest; + t_bool isNextConfRequiredIntraResquest; +#ifdef SVA_USE_GENERIC_ENCODER_INFOS + t_sva_video_encoder_infos *pInfos; +#else /* SVA_USE_GENERIC_ENCODER_INFOS */ + t_sva_video_encoder_h264_infos *pInfos; +#endif /* SVA_USE_GENERIC_ENCODER_INFOS */ + t_sva_brc_user_request brcUserRequest; + t_sva_offset_desc croppingVector; + t_uint32 airThreshold; + + /* Simple profile sprecific stuff */ + /* Needed stuff to handle parly optimal TS */ + t_bool isSnapshotNeeded; + t_uint32 saveVopTimeIncrement; + t_uint32 saveRemainForOffset; + + /* BRC data */ + t_sva_brc_out brcOut; + + /* Skip infos from last encoded picture */ + t_bool isCurrentItSkip; + t_bool isCurrentStrategicSkip; + + /* Bitstream size in bits with stuffing bits */ + t_size bitstreamSizeBits; + + /* Specific stuff need for vbv_occupancy fixing in vol header */ + t_uint16 pictureCodingType[2]; + t_uint16 ptrRd; + t_uint16 ptrWr; + t_bool isFirstPicture; + t_size previousBitstreamSize; + + /* Current state */ + t_sva_ec_save current; + + /* FIFO that keep save data need in case of skip */ + t_sva_ec_save skipFifo[3]; + + + t_pic_parameter_set_rbsp active_pps;//\/ + t_seq_parameter_set_rbsp active_sps;//\/ + t_ImageParameters images; + t_sva_block_id blockH4DId[SUBTASK_DEFAULT_NUMBER]; + t_system_address blockH4DAddr[SUBTASK_DEFAULT_NUMBER]; + +} t_sva_ec_h264_descriptor; + +/*********************************** Start: Code added for migration to MAINVER1.2 ***********************************/ +/* Codelement */ +typedef struct codelement +{ + t_uint32 data; /* UVLC bitpattern */ + t_sint8 nbit; /* length of code */ +} CodElement; + +typedef struct +{ + t_sint32 startcodeprefix_len; /*! 4 for parameter sets and first slice in picture, 3 for everything else (suggested) */ + t_uint32 len; /*! Length of the NAL unit (Excluding the start code, which does not belong to the NALU) */ + t_uint32 max_size; /*! Nal Unit Buffer size */ + t_sint32 nal_unit_type; /*! NALU_TYPE_xxxx */ + t_sint32 nal_reference_idc; /*! NALU_PRIORITY_xxxx */ + t_sint32 forbidden_bit; /*! should be always FALSE */ + t_uint8 *buf; /*! contains the first byte followed by the EBSP */ +} t_NALU, *t_p_NALU; + +typedef enum +{ + I_SLICE = 0, + P_SLICE +} SliceType; + +/************************************ End: Code added for migration to MAINVER1.2 ************************************/ + +/*********************************** Start: Code added for migration to MAINVER1.2b ***********************************/ +typedef enum { + NON_VCL_NALU, + VCL_NALU +} t_NALUflavour; + +/************************************ End: Code added for migration to MAINVER1.2b ************************************/ +#ifdef __cplusplus +} /* allow C++ to use these headers */ +#endif /* __cplusplus */ +#endif /* _SVA_EC_H264P_H_ */ + +/* End of file - sva_ec_h264p.h */ + --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/encode/mpeg4/sva_ec_mpeg4.c @@ -0,0 +1,2556 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ + + +/*------------------------------------------------------------------------ + * Includes + *----------------------------------------------------------------------*/ + +#include "hcl_defs.h" +#include "sva_host_interface.h" +#include "sva_buffermgt.h" +#include "sva_fifo.h" +#include "sva_encode.h" + +#include "../sva_ec_algo.h" +#include "sva_ec_mpeg4.h" + +#include "sva_ec_mpeg4p.h" + +/*------------------------------------------------------------------------ + * Global Variables + *----------------------------------------------------------------------*/ +PRIVATE t_sva_ec_mp4_descriptor mp4EncodeDesc[NUM_MAX_MP4_ENCODE]; + +/*------------------------------------------------------------------------ + * Private functions + *----------------------------------------------------------------------*/ +PRIVATE t_sva_ec_algo_error sva_EC_MP4_ResetDescriptor(t_sva_ec_mp4_descriptor *); +PRIVATE t_bool sva_EC_MP4_IsConfigurationValid(const t_sva_video_encoder_configuration *); +PRIVATE t_sva_ec_algo_error sva_EC_MP4_SH_GetNextFrameParamIn(t_sva_service_instance_num ,t_sva_ec_algo_params_in *); +PRIVATE t_sva_ec_algo_error sva_EC_MP4_SP_GetNextFrameParamIn(t_sva_service_instance_num ,t_sva_ec_algo_params_in *); +PRIVATE t_sva_ec_algo_error sva_EC_MP4_SH_GetNextHeader(t_sva_service_instance_num ,t_sva_ec_algo_header *,t_size *); +PRIVATE t_sva_ec_algo_error sva_EC_MP4_SP_GetNextHeader(t_sva_service_instance_num ,t_sva_ec_algo_header *,t_size *); +PRIVATE t_size sva_EC_MP4_SH_GetMaxHeaderSize(t_sva_service_instance_num); +PRIVATE t_size sva_EC_MP4_SP_GetMaxHeaderSize(t_sva_service_instance_num); +PRIVATE t_sva_ec_algo_error sva_EC_MP4_initWriteStream(t_uint8 *,t_uint32,t_sva_ec_mp4_write_stream *); +PRIVATE void sva_EC_MP4_writeBits(t_sva_ec_mp4_write_stream *,t_uint32, t_uint32); +PRIVATE void sva_EC_MP4_align(t_sva_ec_mp4_write_stream *); +PRIVATE t_sva_ec_algo_error sva_EC_MP4_flushWriteStream(t_sva_ec_mp4_write_stream *); +PRIVATE t_sva_ec_algo_error sva_EC_MP4_SH_UpdateVideoEncoderParams(t_sva_service_instance_num ,t_sva_update_cmd_type ,t_sva_video_encoder_param_id ,t_uint32 ); +PRIVATE t_sva_ec_algo_error sva_EC_MP4_SP_UpdateVideoEncoderParams(t_sva_service_instance_num ,t_sva_update_cmd_type ,t_sva_video_encoder_param_id ,t_uint32 ); + +/****************************************************************************/ +/* NAME: t_sva_ec_algo_error sva_EC_MP4_AlgoInit( */ +/* t_sva_service_instance_num instanceNum, */ +/* const t_sva_video_encoder_configuration *pConf */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine init an mpeg4 descriptor. It save configuration and */ +/* check it. It dispatch this init to brc too. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - instanceNum: number of the descriptor to use. */ +/* - pConf: configuration to use and check. */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_ec_algo_error */ +/* t.b.d */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + * DONE +*/ +PUBLIC t_sva_ec_algo_error sva_EC_MP4_AlgoInit( + t_sva_service_instance_num instanceNum, + const t_sva_video_encoder_configuration *pConf +) +{ + t_sva_ec_mp4_descriptor *pDesc=&mp4EncodeDesc[instanceNum]; + t_sva_video_encoder_algo_mpeg4_configuration_params *pMp4Conf; + t_sva_ec_algo_error algoError; + t_sva_brc_error brcError; + + HCL_DEBUG_ASSERT(pConf!=NULL); + HCL_DEBUG_ASSERT(pConf->pAlgoConfig!=NULL); + + pMp4Conf=(t_sva_video_encoder_algo_mpeg4_configuration_params *)pConf->pAlgoConfig; + /*save configuration*/ + pDesc->conf=*pConf; + pDesc->mp4Conf=*((t_sva_video_encoder_algo_mpeg4_configuration_params *)pConf->pAlgoConfig); + pDesc->mp4NextConf=*((t_sva_video_encoder_algo_mpeg4_configuration_params *)pConf->pAlgoConfig); + pDesc->isFlagIntraRequest = FALSE; + pDesc->isNextConfRequiredIntraResquest = FALSE; + + /*init mp4 instance stuff*/ + algoError=sva_EC_MP4_ResetDescriptor(pDesc); + if (algoError!=SVA_EC_ALGO_OK) {return algoError;} + + /*check configuration*/ + if (sva_EC_MP4_IsConfigurationValid(pConf)==FALSE) + { + return SVA_EC_MP4_PARAM_ERROR; + } + + /*compute airThreshold*/ + pDesc->frameRate = (pMp4Conf->vopTimeIncrementResolution + (pMp4Conf->vopTimeIncrement >> 1)) / pMp4Conf->vopTimeIncrement; + pDesc->nextFrameRate = pDesc->frameRate; + pDesc->airThreshold = (27-(((pDesc->frameRate)*39322)>>16)); + + /*call brc init*/ + brcError=sva_EC_BRC_Init(instanceNum,pConf); + if (brcError!=SVA_BRC_OK) {return SVA_EC_MP4_BRC_ERROR;} + + return SVA_EC_ALGO_OK; +} + +/****************************************************************************/ +/* NAME: t_sva_ec_algo_error sva_EC_MP4_GetInternalNeeds( */ +/* t_sva_service_instance_num instanceNum, */ +/* t_size *pSize */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will return cachable memory need by an mpeg4 instance */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - instanceNum: number of the descriptor to use. */ +/* */ +/* OUT : */ +/* - pSize: need cachable memory size in bytes */ +/* */ +/* RETURN: */ +/* t_sva_ec_algo_error */ +/* t.b.d */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + * DONE +*/ +PUBLIC t_sva_ec_algo_error sva_EC_MP4_GetInternalNeeds( + t_sva_service_instance_num instanceNum, + t_size *pSize +) +{ + t_sva_brc_error brcError; + t_size needSize; + + HCL_DEBUG_ASSERT(pSize!=NULL); + + /*We just need some space to handle infos*/ +#ifdef SVA_USE_GENERIC_ENCODER_INFOS + *pSize=sizeof(t_sva_video_encoder_infos); +#else /* SVA_USE_GENERIC_ENCODER_INFOS */ + *pSize=sizeof(t_sva_video_encoder_mpeg4_infos); +#endif /* SVA_USE_GENERIC_ENCODER_INFOS */ + + /*Ask brc for space it need*/ + brcError=sva_EC_BRC_GetInternalNeeds(instanceNum,&needSize); + if (brcError!=SVA_BRC_OK) {return SVA_EC_MP4_BRC_ERROR;} + *pSize+=needSize; + + return SVA_EC_ALGO_OK; +} + +/****************************************************************************/ +/* NAME: t_sva_ec_algo_error sva_EC_MP4_ProvideMemoryNeeds( */ +/* t_sva_service_instance_num instanceNum */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will use memory allocated by user. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - instanceNum: number of the descriptor to use. */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_ec_algo_error */ +/* t.b.d */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + * DONE +*/ +PUBLIC t_sva_ec_algo_error sva_EC_MP4_ProvideMemoryNeeds( + t_sva_service_instance_num instanceNum, const t_sva_tm_subtask_id *pSubtaskIdArray +) +{ + t_sva_ec_mp4_descriptor *pDesc=&mp4EncodeDesc[instanceNum]; + t_sva_brc_error brcError; + t_sva_in_error inError; + t_logical_address logicalAddress; + + /*get memory*/ +#ifdef SVA_USE_GENERIC_ENCODER_INFOS + inError=sva_IN_AllocMemory(sizeof(t_sva_video_encoder_infos),&logicalAddress); +#else /* SVA_USE_GENERIC_ENCODER_INFOS */ + inError=sva_IN_AllocMemory(sizeof(t_sva_video_encoder_mpeg4_infos),&logicalAddress); +#endif /* SVA_USE_GENERIC_ENCODER_INFOS */ + if (inError!=SVA_IN_OK) {return SVA_EC_MP4_INTERNAL_ERROR;} + + /*use it*/ +#ifdef SVA_USE_GENERIC_ENCODER_INFOS + pDesc->pInfos=(t_sva_video_encoder_infos *) logicalAddress; +#else /* SVA_USE_GENERIC_ENCODER_INFOS */ + pDesc->pInfos=(t_sva_video_encoder_mpeg4_infos *) logicalAddress; +#endif /* SVA_USE_GENERIC_ENCODER_INFOS */ + + /*dispatch to brc*/ + brcError=sva_EC_BRC_ProvideMemoryNeeds(instanceNum); + if (brcError!=SVA_BRC_OK) {return SVA_EC_MP4_BRC_ERROR;} + + return SVA_EC_ALGO_OK; +} + +/****************************************************************************/ +/* NAME: t_sva_ec_algo_error sva_EC_MP4_EncodeAlgoDelete( */ +/* t_sva_service_instance_num instanceNum */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will delete all allocated stuff (mainly fifo) */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - instanceNum: number of the descriptor to use. */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_ec_algo_error */ +/* t.b.d */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + * DONE +*/ +PUBLIC t_sva_ec_algo_error sva_EC_MP4_EncodeAlgoDelete( + t_sva_service_instance_num instanceNum +) +{ + t_sva_brc_error brcError; + + /*nothing to do for mpeg4*/ + + /*dispatch to brc*/ + brcError=sva_EC_BRC_EncodeAlgoDelete(instanceNum); + if (brcError!=SVA_BRC_OK) {return SVA_EC_MP4_BRC_ERROR;} + + return SVA_EC_ALGO_OK; +} + +/****************************************************************************/ +/* NAME: t_sva_ec_algo_error sva_EC_MP4_UpdateVideoEncoderParams( */ +/* t_sva_service_instance_num instanceNum, */ +/* t_sva_update_cmd_type updateCmdType, */ +/* t_sva_video_encoder_param_id paramId, */ +/* t_uint32 param */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will update dynamic parameters */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - instanceNum: number of the descriptor to use. */ +/* - updateCmdType: command to apply to the mp4 Encode */ +/* - paramId: Parameter to update */ +/* - param: parameter for the cmdType */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_ec_algo_error */ +/* t.b.d */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + * if changing both at a time brc and algo param and brc + * config is false then algo param will be change anyway ... +*/ +PUBLIC t_sva_ec_algo_error sva_EC_MP4_UpdateVideoEncoderParams( + t_sva_service_instance_num instanceNum, + t_sva_update_cmd_type updateCmdType, + t_sva_video_encoder_param_id paramId, + t_uint32 param +) +{ + t_sva_ec_mp4_descriptor *pDesc=&mp4EncodeDesc[instanceNum]; + t_sva_ec_algo_error algoError = SVA_EC_ALGO_OK; + t_sva_brc_error brcError = SVA_BRC_OK; + + /*handle algo parameters*/ + if (pDesc->mp4Conf.flagShortHeader==TRUE) + { + algoError=sva_EC_MP4_SH_UpdateVideoEncoderParams(instanceNum,updateCmdType,paramId,param); + } + else + { + algoError=sva_EC_MP4_SP_UpdateVideoEncoderParams(instanceNum,updateCmdType,paramId,param); + } + /*take into account updateCmdType for algo part*/ + switch(updateCmdType) + { + case SVA_UPDATE_MULTIPLE: + /*nothing to do*/ + break; + case SVA_UPDATE_LAST: + /*check new configuration is valid*/ + pDesc->conf.pAlgoConfig = (tp_sva_codec_algo_configuration_params) &pDesc->mp4NextConf; + if (sva_EC_MP4_IsConfigurationValid(&pDesc->conf)==FALSE) {return SVA_EC_MP4_INTERNAL_ERROR;} + /*compute airThreshold*/ + pDesc->frameRate = pDesc->nextFrameRate; + pDesc->airThreshold = (27-(((pDesc->frameRate)*39322)>>16)); + /*copy next as current*/ + pDesc->isFlagIntraRequest = pDesc->isNextConfRequiredIntraResquest; + pDesc->mp4Conf = pDesc->mp4NextConf; + pDesc->isNextConfRequiredIntraResquest = FALSE; + break; + case SVA_UPDATE_REVERT: + /*cancel previously param update*/ + pDesc->isNextConfRequiredIntraResquest = FALSE; + pDesc->mp4NextConf = pDesc->mp4Conf; + pDesc->nextFrameRate = pDesc->frameRate; + break; + default: + break; + } + + /*dispatch command to brc even if not a brc command*/ + /*this is need to dispatch LAST/REVERT info*/ + brcError = sva_EC_BRC_UpdateBrcParams(instanceNum,updateCmdType,paramId,param); + + /*return an error if both algo and brc return an error*/ + if (algoError != SVA_EC_ALGO_OK && brcError != SVA_BRC_OK) {return SVA_EC_MP4_CMD_NOT_SUPPORTED;} + else {return SVA_EC_ALGO_OK;} +} + +/****************************************************************************/ +/* NAME: t_sva_ec_algo_error sva_EC_MP4_PushImageInfo( */ +/* t_sva_service_instance_num instanceNum, */ +/* const t_sva_ec_algo_image_info *pImageInfo */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will save timestamp value to use for next picture */ +/* encoding. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - instanceNum: number of the descriptor to use. */ +/* - pImageInfo: picture information (pts and cropping vector) */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_ec_algo_error */ +/* t.b.d */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + * DONE +*/ +PUBLIC t_sva_ec_algo_error sva_EC_MP4_PushImageInfo( + t_sva_service_instance_num instanceNum, + const t_sva_ec_algo_image_info *pImageInfo +) +{ + t_sva_ec_mp4_descriptor *pDesc=&mp4EncodeDesc[instanceNum]; + t_sva_ec_save *pCur = &pDesc->current; + + HCL_DEBUG_ASSERT(pImageInfo!=NULL); + /*save pts value*/ + pCur->pts = pImageInfo->pts.value; + pDesc->croppingVector=pImageInfo->croppingVector; + pDesc->brcUserRequest=pImageInfo->brcUserRequest; + + return SVA_EC_ALGO_OK; +} + +/****************************************************************************/ +/* NAME: t_sva_ec_algo_error sva_EC_MP4_GetNextFrameParamIn( */ +/* t_sva_service_instance_num instanceNum, */ +/* t_sva_ec_algo_params_in *pParamIn */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will fill paramin picture for next picture. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - instanceNum: number of the descriptor to use. */ +/* */ +/* OUT : */ +/* - pParamIn: parameters to output */ +/* */ +/* RETURN: */ +/* t_sva_ec_algo_error */ +/* t.b.d */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + * DONE +*/ +PUBLIC t_sva_ec_algo_error sva_EC_MP4_GetNextFrameParamIn( + t_sva_service_instance_num instanceNum, + t_sva_ec_algo_params_in *pParamIn +) +{ + t_sva_ec_mp4_descriptor *pDesc=&mp4EncodeDesc[instanceNum]; + t_sva_ec_algo_error algoError; + + HCL_DEBUG_ASSERT(pParamIn!=NULL); + if (pDesc->mp4Conf.flagShortHeader==TRUE) + { + algoError=sva_EC_MP4_SH_GetNextFrameParamIn(instanceNum,pParamIn); + } + else + { + algoError=sva_EC_MP4_SP_GetNextFrameParamIn(instanceNum,pParamIn); + } + + return algoError; +} + +/****************************************************************************/ +/* NAME: t_sva_ec_algo_error sva_EC_MP4_GetNextHeader( */ +/* t_sva_service_instance_num instanceNum, */ +/* t_sva_ec_algo_header *pHeader, */ +/* t_size *pSizeInBits */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will fill paramin picture for next picture. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - instanceNum: number of the descriptor to use. */ +/* */ +/* OUT : */ +/* - pHeader: header to write */ +/* - pSizeInBits: size in bits of the header */ +/* */ +/* RETURN: */ +/* t_sva_ec_algo_error */ +/* t.b.d */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + * DONE +*/ +PUBLIC t_sva_ec_algo_error sva_EC_MP4_GetNextHeader( + t_sva_service_instance_num instanceNum, + t_sva_ec_algo_header *pHeader, + t_size *pSizeInBits +) +{ + t_sva_ec_mp4_descriptor *pDesc=&mp4EncodeDesc[instanceNum]; + t_sva_ec_algo_error algoError; + + HCL_DEBUG_ASSERT(pHeader!=NULL); + HCL_DEBUG_ASSERT(pSizeInBits!=NULL); + if (pDesc->mp4Conf.flagShortHeader==TRUE) + { + algoError=sva_EC_MP4_SH_GetNextHeader(instanceNum,pHeader,pSizeInBits); + } + else + { + algoError=sva_EC_MP4_SP_GetNextHeader(instanceNum,pHeader,pSizeInBits); + } + + return algoError; +} + +/****************************************************************************/ +/* NAME: t_sva_ec_algo_error sva_EC_MP4_InitParamInOut( */ +/* t_sva_service_instance_num instanceNum, */ +/* t_sva_ec_algo_params_inout *pParamInout */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will init inout parameters for the first picture */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - instanceNum: number of the descriptor to use. */ +/* */ +/* OUT : */ +/* - pParamInout: inout parameters to init */ +/* */ +/* RETURN: */ +/* t_sva_ec_algo_error */ +/* t.b.d */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + * TO DO : call brc level API +*/ +PUBLIC t_sva_ec_algo_error sva_EC_MP4_InitParamInOut( + t_sva_service_instance_num instanceNum, + t_sva_ec_algo_params_inout *pParamInout +) +{ + t_sva_ec_mp4_descriptor *pDesc=&mp4EncodeDesc[instanceNum]; + t_sva_vec_mpeg4_param_inout *pMeg4ParamInOut=(t_sva_vec_mpeg4_param_inout *) pParamInout; + t_sva_brc_error brcError; + + HCL_DEBUG_ASSERT(pParamInout!=NULL); + HCL_DEBUG_ASSERT(pMeg4ParamInOut!=NULL); + /*init param related to brc*/ + brcError=sva_EC_BRC_InitBrcStatsPrev(instanceNum,(t_uint32 *) pParamInout); + if (brcError!=SVA_BRC_OK) {return SVA_EC_MP4_BRC_ERROR;} + + /*init param related to algo*/ + pMeg4ParamInOut->hec_count=pDesc->mp4Conf.hecFreq; + + //CR 155 PictQpSumIntra =0 + pMeg4ParamInOut->PictQpSumIntra =0; + + return SVA_EC_ALGO_OK; +} + +/****************************************************************************/ +/* NAME: t_sva_ec_algo_error sva_EC_MP4_SetFrameParamOut( */ +/* t_sva_service_instance_num instanceNum, */ +/* const t_sva_ec_algo_params_out *pParamOut, */ +/* t_sva_ec_algo_params_inout *pParamInout */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will provide info to algo module after a subtask has */ +/* been excecuted. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - instanceNum: number of the descriptor to use. */ +/* - pParamIn: param in parameters. */ +/* - pParamOut: param out parameters. */ +/* - pParamInout: out param inout. */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_ec_algo_error */ +/* t.b.d */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + * DONE +*/ +PUBLIC t_sva_ec_algo_error sva_EC_MP4_SetFrameParamOut( + t_sva_service_instance_num instanceNum, + const t_sva_ec_algo_params_out *pParamOut, + const t_sva_ec_algo_params_inout *pParamInout +) +{ + t_sva_ec_mp4_descriptor *pDesc=&mp4EncodeDesc[instanceNum]; + t_sva_vec_mpeg4_param_out *pMpeg4ParamOut=(t_sva_vec_mpeg4_param_out *) pParamOut; + t_sva_vec_mpeg4_param_inout *pMeg4ParamInOut=(t_sva_vec_mpeg4_param_inout *) pParamInout; + t_sva_brc_in brcIn; + t_sva_brc_error brcError; + t_uint32 videoPacketNbToCopy; + t_uint32 videoPacketOffset=0; + t_uint32 i; + + HCL_DEBUG_ASSERT(pParamOut!=NULL); + HCL_DEBUG_ASSERT(pParamInout!=NULL); + HCL_DEBUG_ASSERT(pMpeg4ParamOut!=NULL); + HCL_DEBUG_ASSERT(pMeg4ParamInOut!=NULL); + /*save skip and stream size info*/ + /*skip info*/ + pDesc->isCurrentItSkip=(t_bool)((pMpeg4ParamOut->brc_skip_prev!=0)?TRUE:FALSE); + +#define SVA_ENABLE_MP4_HCL_WORKAROUND_VI10315 +#if defined(SVA_ENABLE_MP4_HCL_WORKAROUND_VI10315) /* Sarvesh: Temporary HCL workaround for parsing error, VI10315 */ + if (SVA_CBR == pDesc->conf.brcMode) + { + /* Always assume no frame is strategically skipped */ + pDesc->isCurrentStrategicSkip = FALSE; + } + else + { + if (pMeg4ParamInOut->Skip_Current == 1 && pDesc->isCurrentItSkip == FALSE) + { + pDesc->isCurrentStrategicSkip = TRUE; + } + else {pDesc->isCurrentStrategicSkip = FALSE;} + } +#else /* else of #if SVA_ENABLE_MP4_HCL_WORKAROUND_VI10315 */ + if (pMeg4ParamInOut->Skip_Current == 1 && pDesc->isCurrentItSkip == FALSE) + { + pDesc->isCurrentStrategicSkip = TRUE; + } + else {pDesc->isCurrentStrategicSkip = FALSE;} +#endif /* endif of #if SVA_ENABLE_MP4_HCL_WORKAROUND_VI10315 */ + /*save bitstream size*/ + pDesc->bitstreamSizeBits=pMeg4ParamInOut->bitstream_size+pMeg4ParamInOut->stuffing_bits; + /*size info*/ + pDesc->pInfos->encodedFrameSize=(pMeg4ParamInOut->bitstream_size+pMeg4ParamInOut->stuffing_bits+7)/8; + pDesc->pInfos->vpSliceNum=pMpeg4ParamOut->vp_num; + if (pMpeg4ParamOut->vp_num>SVA_EC_MPEG4_VP_POS_COUNT) {videoPacketNbToCopy=SVA_EC_MPEG4_VP_POS_COUNT;videoPacketOffset=pMpeg4ParamOut->vp_num%SVA_EC_MPEG4_VP_POS_COUNT;} + else {videoPacketNbToCopy=pMpeg4ParamOut->vp_num;} + for(i=0;ipInfos->vpSlicePos[i]=pMpeg4ParamOut->vp_pos[(i+videoPacketOffset)%SVA_EC_MPEG4_VP_POS_COUNT]; + } + + /*provide data to brc*/ + brcIn.bitstreamSize=pMeg4ParamInOut->bitstream_size; + brcIn.stuffingBits=pMeg4ParamInOut->stuffing_bits; + brcIn.brcSkipPrev=pMpeg4ParamOut->brc_skip_prev; + brcIn.skipCurrent=pMeg4ParamInOut->Skip_Current; + brcError=sva_EC_BRC_FinishPicture(instanceNum,&brcIn); + if (brcError!=SVA_BRC_OK) {return SVA_EC_MP4_BRC_ERROR;} + + return SVA_EC_ALGO_OK; +} + + +/****************************************************************************/ +/* NAME: t_sva_ec_algo_error sva_EC_MP4_GetSkipInfo( */ +/* t_sva_service_instance_num instanceNum, */ +/* t_bool *pIsCurrentStrategicSkip, */ +/* t_bool *pIsCurrentItSkip */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will return skip information need by encode part to */ +/* handle buffers correctly. It must call after */ +/* sva_EC_MP4_SetFrameParamOut() call. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - instanceNum: number of the descriptor to use. */ +/* */ +/* OUT : */ +/* - pIsCurrentStrategicSkip: return information about the fact that current*/ +/* picture is strategic skip. */ +/* - pIsCurrentItSkip: return information about the fact that current picture*/ +/* is IT skip. */ +/* */ +/* RETURN: */ +/* t_sva_ec_algo_error */ +/* t.b.d */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + * implement correctly this +*/ +PUBLIC t_sva_ec_algo_error sva_EC_MP4_GetSkipInfo( + t_sva_service_instance_num instanceNum, + t_bool *pIsCurrentStrategicSkip, + t_bool *pIsCurrentItSkip +) +{ + t_sva_ec_mp4_descriptor *pDesc=&mp4EncodeDesc[instanceNum]; + + HCL_DEBUG_ASSERT(pIsCurrentStrategicSkip!=NULL); + HCL_DEBUG_ASSERT(pIsCurrentItSkip!=NULL); + + /*return skip info for encode part so it can handle buffers correctly*/ + *pIsCurrentStrategicSkip=pDesc->isCurrentStrategicSkip; + *pIsCurrentItSkip=pDesc->isCurrentItSkip; + + return SVA_EC_ALGO_OK; +} + +/****************************************************************************/ +/* NAME: t_sva_ec_algo_error sva_EC_MP4_GetBitstreamSize( */ +/* t_sva_service_instance_num instanceNum, */ +/* t_size *pBitstreamSizeInBits */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will return size of encoded stream in bits. This */ +/* include stuffings bits. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - instanceNum: number of the descriptor to use. */ +/* */ +/* OUT : */ +/* - pBitstreamSizeInBits: return size of encoded bitstream in bits. This */ +/* include stuffing bits. */ +/* */ +/* RETURN: */ +/* t_sva_ec_algo_error */ +/* t.b.d */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + * DONE +*/ +PUBLIC t_sva_ec_algo_error sva_EC_MP4_GetBitstreamSize( + t_sva_service_instance_num instanceNum, + t_size *pBitstreamSizeInBits +) +{ + t_sva_ec_mp4_descriptor *pDesc=&mp4EncodeDesc[instanceNum]; + + HCL_DEBUG_ASSERT(pBitstreamSizeInBits!=NULL); + + *pBitstreamSizeInBits=pDesc->bitstreamSizeBits; + + return SVA_EC_ALGO_OK; +} + +/****************************************************************************/ +/* NAME: t_sva_ec_algo_error sva_EC_MP4_PachBitstream( */ +/* t_sva_service_instance_num instanceNum, */ +/* const t_sva_ec_algo_params_in *pParamIn, */ +/* t_logical_address bitstreamAddr */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will return size of encoded stream in bits. This */ +/* include stuffings bits. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - instanceNum: number of the descriptor to use. */ +/* - bitstreamAddr : start address of bitstream. */ +/* */ +/* OUT : */ +/* none */ +/* */ +/* RETURN: */ +/* t_sva_ec_algo_error */ +/* t.b.d */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + * using bitstream to store bufferLevel is slow due to the fact that + * bitstream is in a non cachable area. + * So it would be better to use internal variable in t_sva_ec_mp4_descriptor + * Structure to hold these data. +*/ +PUBLIC t_sva_ec_algo_error sva_EC_MP4_PatchBitstream( + t_sva_service_instance_num instanceNum, + const t_sva_ec_algo_params_in *pParamIn, + t_logical_address bitstreamAddr +) +{ + t_sva_vec_mpeg4_param_in *pMpeg4ParamIn=(t_sva_vec_mpeg4_param_in *) pParamIn; + t_sva_ec_mp4_descriptor *pDesc=&mp4EncodeDesc[instanceNum]; + t_uint8 *bitBuffer = (t_uint8 *) bitstreamAddr; + t_sint32 bufferLevel; + t_uint32 vbvOccupancy; + t_uint8 buffer[5]; + t_uint8 i; + + HCL_DEBUG_ASSERT(pParamIn!=NULL); + HCL_DEBUG_ASSERT(pMpeg4ParamIn!=NULL); + + if (pDesc->mp4Conf.isSystemHeaderAddBeforeIntra == TRUE && + pDesc->conf.bufferingModel != SVA_BUFFERING_NONE) + { + /* check if we have something to do*/ + if (pMpeg4ParamIn->picture_coding_type == SVA_MPEG4_VOP_CODING_TYPE_I) + { + if (pDesc->isFirstPicture == TRUE) + { + /*check in case of first picture skip*/ + if (pDesc->isCurrentItSkip == FALSE && pDesc->isCurrentStrategicSkip == FALSE) + { + pDesc->isFirstPicture = FALSE; + } + } + else + { + if (pDesc->isCurrentItSkip == FALSE && pDesc->isCurrentStrategicSkip == FALSE) + { + /* So we have to fix vol header of current picture*/ + /* copy the 5 bytes of bitstream that need to be modify + * in local buffer to improve speed. + */ + for (i=0;i<5;i++) {buffer[i] = bitBuffer[26 + i];} + /* get bufferSizeForVbv store in bitstream */ + bufferLevel = ((buffer[0] & 0x3f) << 26); + bufferLevel += (buffer[1] << 18); + bufferLevel += (buffer[2] << 10); + bufferLevel += (buffer[3] << 2); + bufferLevel += ((buffer[4] & 0xc0) >> 6); + /* ask brc for vbv_occupancy value */ + vbvOccupancy = sva_EC_BRC_GetVbvOccupancy(instanceNum , bufferLevel, pDesc->previousBitstreamSize); + /* patch bitstream*/ + buffer[0] = (buffer[0] & 0xc0); + buffer[1] = 0; + buffer[2] = 0; + buffer[3] = 0; + buffer[4] = (buffer[4] & 0x3f); + bitBuffer[26] = (t_uint8) (buffer[0] + 0x20 + ((pDesc->brcOut.vbvBufferSizeIn16384BitsUnit+1 & 7) << 2) + + ((vbvOccupancy & 0x3000000) >> 24)); + bitBuffer[27] = (t_uint8)((vbvOccupancy & 0xff0000) >> 16); + bitBuffer[28] = (t_uint8)(((vbvOccupancy & 0x8000) >> 16) + 0x40 + ((vbvOccupancy & 0x7e00) >> 9)); + bitBuffer[29] = (t_uint8)((vbvOccupancy & 0x1fe ) >> 1); + bitBuffer[30] = (t_uint8) (buffer[4] + 0x40 + (t_uint8)((vbvOccupancy & 1) << 7)); + } + } + } + /* update previous picture size*/ + if (pDesc->isCurrentItSkip == FALSE && pDesc->isCurrentStrategicSkip == FALSE) + { + pDesc->previousBitstreamSize = pDesc->bitstreamSizeBits; + } + else {pDesc->previousBitstreamSize = 0;} + } + + return SVA_EC_ALGO_OK; +} + +/****************************************************************************/ +/* NAME: t_sva_ec_algo_error sva_EC_MP4_FillInfosBuffer( */ +/* t_sva_service_instance_num instanceNum, */ +/* t_sva_buffer_id bufferId */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will fill given buffer with infos of good type. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - instanceNum: number of the descriptor to use. */ +/* - bufferId: buffer where to write infos. */ +/* */ +/* OUT : */ +/* - pBitstreamSizeInBits: return size of encoded bitstream in bits. This */ +/* include stuffing bits. */ +/* */ +/* RETURN: */ +/* t_sva_ec_algo_error */ +/* t.b.d */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + * DONE +*/ +PUBLIC t_sva_ec_algo_error sva_EC_MP4_FillInfosBuffer( + t_sva_service_instance_num instanceNum, + t_sva_buffer_id bufferId +) +{ + t_sva_ec_mp4_descriptor *pDesc=&mp4EncodeDesc[instanceNum]; + t_logical_address infoAddr; +#ifdef SVA_USE_GENERIC_ENCODER_INFOS + t_sva_video_encoder_infos *pInfos; +#else /* SVA_USE_GENERIC_ENCODER_INFOS */ + t_sva_video_encoder_mpeg4_infos *pInfos; +#endif /* SVA_USE_GENERIC_ENCODER_INFOS */ + t_uint32 videoPacketNbToCopy; + t_uint32 i; + t_sva_bm_error bmError; + + /*get a pointer on the data to write*/ + bmError=sva_BM_GetBufferLogicalAddress(bufferId,&infoAddr); + if (bmError!=SVA_BM_OK) {return SVA_EC_MP4_INTERNAL_ERROR;} +#ifdef SVA_USE_GENERIC_ENCODER_INFOS + pInfos=(t_sva_video_encoder_infos *) infoAddr; +#else /* SVA_USE_GENERIC_ENCODER_INFOS */ + pInfos=(t_sva_video_encoder_mpeg4_infos *) infoAddr; +#endif /* SVA_USE_GENERIC_ENCODER_INFOS */ + + /*copy data*/ + pInfos->encodedFrameSize=pDesc->pInfos->encodedFrameSize; + pInfos->vpSliceNum=pDesc->pInfos->vpSliceNum; + if (pInfos->vpSliceNum>SVA_EC_MPEG4_VP_POS_COUNT) {videoPacketNbToCopy=SVA_EC_MPEG4_VP_POS_COUNT;} + else {videoPacketNbToCopy=pInfos->vpSliceNum;} + for(i=0;ivpSlicePos[i]=pDesc->pInfos->vpSlicePos[i]; + } + + return SVA_EC_ALGO_OK; +} + +/****************************************************************************/ +/* NAME: t_bool sva_EC_MP4_IsPreviousPictureWasStategicSkip( */ +/* t_sva_service_instance_num instanceNum */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will return skip information need by encode part to */ +/* handle buffers correctly. It must call after */ +/* sva_EC_MP4_SetFrameParamOut() call. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - instanceNum: number of the descriptor to use. */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_bool */ +/* TRUE : previous picture was strategic skip */ +/* FALSE : previous picture was not strategic skip */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + * implement this +*/ +PUBLIC t_bool sva_EC_MP4_IsPreviousPictureWasStategicSkip( + t_sva_service_instance_num instanceNum +) +{ + return sva_EC_BRC_IsPreviousPictureWasStrategicSkip(instanceNum); +} + +/****************************************************************************/ +/* NAME: t_size sva_EC_MP4_GetParamsInSize( */ +/* t_sva_service_instance_num instanceNum */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will return numbers of bytes need to handle mpeg4 */ +/* paramin structure. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - instanceNum: number of the descriptor to use. */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_size */ +/* t.b.d */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + * DONE +*/ +PUBLIC t_size sva_EC_MP4_GetParamsInSize( + t_sva_service_instance_num instanceNum +) +{ + (void) instanceNum; + + return sizeof(t_sva_vec_mpeg4_param_in); +} + +/****************************************************************************/ +/* NAME: t_size sva_EC_MP4_GetParamsOutSize( */ +/* t_sva_service_instance_num instanceNum */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will return numbers of bytes need to handle mpeg4 */ +/* paramout structure. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - instanceNum: number of the descriptor to use. */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_size */ +/* t.b.d */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + * DONE +*/ +PUBLIC t_size sva_EC_MP4_GetParamsOutSize( + t_sva_service_instance_num instanceNum +) +{ + (void) instanceNum; + + return sizeof(t_sva_vec_mpeg4_param_out); +} + +/****************************************************************************/ +/* NAME: t_size sva_EC_MP4_GetParamsInOutSize( */ +/* t_sva_service_instance_num instanceNum */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will return numbers of bytes need to handle mpeg4 */ +/* paraminout structure. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - instanceNum: number of the descriptor to use. */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_size */ +/* t.b.d */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + * DONE +*/ +PUBLIC t_size sva_EC_MP4_GetParamsInOutSize( + t_sva_service_instance_num instanceNum +) +{ + (void) instanceNum; + + return sizeof(t_sva_vec_mpeg4_param_inout); +} + +/****************************************************************************/ +/* NAME: t_size sva_EC_MP4_GetMaxHeaderSize( */ +/* t_sva_service_instance_num instanceNum */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will return max number of bytes a header can be. Thus */ +/* encode part will allocate enought space for such header. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - instanceNum: number of the descriptor to use. */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_size */ +/* t.b.d */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + * DONE +*/ +PUBLIC t_size sva_EC_MP4_GetMaxHeaderSize( + t_sva_service_instance_num instanceNum +) +{ + t_sva_ec_mp4_descriptor *pDesc=&mp4EncodeDesc[instanceNum]; + + if (pDesc->mp4Conf.flagShortHeader==TRUE) + { + return sva_EC_MP4_SH_GetMaxHeaderSize(instanceNum); + } + else + { + return sva_EC_MP4_SP_GetMaxHeaderSize(instanceNum); + } +} + +/****************************************************************************/ +/* NAME: t_sva_ec_algo_error sva_EC_MP4_ResetDescriptor( */ +/* t_sva_ec_mp4_descriptor *pDesc */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine reset an mpeg4 descriptor. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - pDesc: mp4 descritor to reset. */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_ec_algo_error */ +/* t.b.d */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + * DONE +*/ +PRIVATE t_sva_ec_algo_error sva_EC_MP4_ResetDescriptor( + t_sva_ec_mp4_descriptor *pDesc +) +{ + t_uint32 i; + + HCL_ASSERT(pDesc!=NULL); + + /*init current field*/ + pDesc->current.pts = 0; + pDesc->current.pictureNb = ~0; + pDesc->current.roundValue = 0; // check with reference model to see what is first value. + pDesc->current.pictureCodingType = SVA_MP4_P_PICTURE; + pDesc->current.gobFrameId = 0; + pDesc->current.temporalSh.tr = 0; + pDesc->current.temporalSh.cumulTimeSlot = 0; + pDesc->current.temporalSh.slotDelay = 0; + pDesc->current.temporalSp.remainForOffset = 0; + pDesc->current.temporalSp.moduloTimeBase = 0; + pDesc->current.temporalSp.vopTimeIncrement = 0; + pDesc->current.temporalSp.vopTimeIncrementBitSize = 0; + if (pDesc->mp4Conf.flagShortHeader==FALSE) + { + while((1<current.temporalSp.vopTimeIncrementBitSize) < pDesc->mp4Conf.vopTimeIncrementResolution) + { + pDesc->current.temporalSp.vopTimeIncrementBitSize++; + } + } + + /* init skip fifo with current*/ + for(i=0;i<2;i++) {pDesc->skipFifo[i]=pDesc->current;} + + /* init vbv_occupancy fix stuff */ + pDesc->isFirstPicture = TRUE; + + return SVA_EC_ALGO_OK; +} + +/****************************************************************************/ +/* NAME: t_sva_ec_algo_error sva_EC_MP4_IsConfigurationValid( */ +/* const t_sva_video_encoder_configuration *pConf */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine check if configuration is valid. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - pConf: configuration to check validity. */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_ec_algo_error */ +/* t.b.d */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + * TO DO : deblocking support : do it when done at encode level + * - additional checks must be done for some param +*/ +PRIVATE t_bool sva_EC_MP4_IsConfigurationValid( + const t_sva_video_encoder_configuration *pConf +) +{ + t_sva_video_encoder_algo_mpeg4_configuration_params *pMp4Conf; + t_uint16 width; + t_uint16 height; + + HCL_ASSERT(pConf!=NULL); + pMp4Conf=(t_sva_video_encoder_algo_mpeg4_configuration_params *)pConf->pAlgoConfig; + width=pConf->sourceFrameDesc.window.image.width; + height=pConf->sourceFrameDesc.window.image.height; + /*check first general config limit by algo*/ + /*t_sva_windowed_frame_desc sourceFrameDesc*/ + CHECK_ALIGNMENT(pConf->sourceFrameDesc.frame.height,SVA_EC_MP4_SOURCE_FRAME_HEIGHT_ALIGN); + CHECK_RANGE(pConf->sourceFrameDesc.frame.height, SVA_EC_MP4_SOURCE_FRAME_HEIGHT_MIN, SVA_EC_MP4_SOURCE_FRAME_HEIGHT_MAX); + CHECK_ALIGNMENT(pConf->sourceFrameDesc.frame.width,SVA_EC_MP4_SOURCE_FRAME_WIDTH_ALIGN); + CHECK_RANGE(pConf->sourceFrameDesc.frame.width, SVA_EC_MP4_SOURCE_FRAME_WIDTH_MIN, SVA_EC_MP4_SOURCE_FRAME_WIDTH_MAX); + CHECK_ALIGNMENT(pConf->sourceFrameDesc.window.image.height,SVA_EC_MP4_SOURCE_WINDOW_HEIGHT_ALIGN); + CHECK_RANGE(pConf->sourceFrameDesc.window.image.height, SVA_EC_MP4_SOURCE_WINDOW_HEIGHT_MIN, pConf->sourceFrameDesc.frame.height); + CHECK_ALIGNMENT(pConf->sourceFrameDesc.window.image.width,SVA_EC_MP4_SOURCE_WINDOW_WIDTH_ALIGN); + CHECK_RANGE(pConf->sourceFrameDesc.window.image.width, SVA_EC_MP4_SOURCE_WINDOW_WIDTH_MIN, pConf->sourceFrameDesc.frame.width); + CHECK_ALIGNMENT(pConf->sourceFrameDesc.window.imageOffset.offsetX,SVA_EC_MP4_SOURCE_WINDOW_OFFSET_X_ALIGN); + CHECK_RANGE0(pConf->sourceFrameDesc.window.imageOffset.offsetX, SVA_EC_MP4_SOURCE_WINDOW_OFFSET_X_MIN, pConf->sourceFrameDesc.frame.width-pConf->sourceFrameDesc.window.image.width); + CHECK_ALIGNMENT(pConf->sourceFrameDesc.window.imageOffset.offsetY,SVA_EC_MP4_SOURCE_WINDOW_OFFSET_Y_ALIGN); + CHECK_RANGE0(pConf->sourceFrameDesc.window.imageOffset.offsetY, SVA_EC_MP4_SOURCE_WINDOW_OFFSET_Y_MIN, pConf->sourceFrameDesc.frame.height-pConf->sourceFrameDesc.window.image.height); + /*additional size check for short header*/ + if (pMp4Conf->flagShortHeader==TRUE && + (width!=SVA_EC_MP4_SQCIF_WIDTH || height!=SVA_EC_MP4_SQCIF_HEIGHT) && + (width!=SVA_EC_MP4_QCIF_WIDTH || height!=SVA_EC_MP4_QCIF_HEIGHT) && + (width!=SVA_EC_MP4_CIF_WIDTH || height!=SVA_EC_MP4_CIF_HEIGHT) && + (width!=SVA_EC_MP4_CIF4_WIDTH || height!=SVA_EC_MP4_CIF4_HEIGHT) && + (width!=SVA_EC_MP4_CIF16_WIDTH || height!=SVA_EC_MP4_CIF16_HEIGHT)) + { + return FALSE; + } + + /*check vopTimeIncrement*/ + if (pMp4Conf->vopTimeIncrement==0){return FALSE;} + + /*additional size check when data is partinionned*/ + if (pMp4Conf->flagShortHeader==FALSE && pMp4Conf->isDataPartitionedEnable==TRUE) + { + CHECK_RANGE(pConf->sourceFrameDesc.window.image.height, SVA_EC_MP4_SOURCE_WINDOW_HEIGHT_MIN, SVA_EC_MP4_SOURCE_WINDOW_HEIGHT_PARTITIONED_MAX); + CHECK_RANGE(pConf->sourceFrameDesc.window.image.width, SVA_EC_MP4_SOURCE_WINDOW_WIDTH_MIN, SVA_EC_MP4_SOURCE_WINDOW_WIDTH_PARTITIONED_MAX); + } + + /*check specific to short header*/ + if (pMp4Conf->flagShortHeader==TRUE) + { + /*check gob header frequency*/ + CHECK_RANGE0(pMp4Conf->gobHeaderFrequency, 0, pConf->sourceFrameDesc.window.image.height/16); + + CHECK_RANGE0(pMp4Conf->vpBitSize, 0, 65535);//Max value as mailed by MC, CR 155 + /*isDataPartitionedEnable and isReversibleVlcEnable must be false*/ + if (pMp4Conf->isDataPartitionedEnable==TRUE || pMp4Conf->isReversibleVlcEnable==TRUE) {return FALSE;} + } + + /*check specific to simple profile*/ + if (pMp4Conf->flagShortHeader==FALSE) + { + /*check hec frequency*/ + CHECK_RANGE0(pMp4Conf->hecFreq, 0, (pConf->sourceFrameDesc.window.image.height*pConf->sourceFrameDesc.window.image.width)/256); + /*check isReversibleVlcEnable enable when isDataPartitionedEnable is enable*/ + if (pMp4Conf->isReversibleVlcEnable==TRUE && pMp4Conf->isDataPartitionedEnable==FALSE) {return FALSE;} + /*check hec generation when isDataPartitionedEnable is enable*/ + if (pMp4Conf->hecFreq!=0 && pMp4Conf->isDataPartitionedEnable==FALSE) {return FALSE;} + + + if(pMp4Conf->isDataPartitionedEnable==TRUE) + { + /* vpSizeMax VSM must not be greater than the "Max. videopacket length" defined in Table N1 of [1]: + - for Simple Profile Level 0, VSM<=2048, + - for Simple Profile Level 1, VSM<=2048, + - for Simple Profile Level 2, VSM<=4096, + - for Simple Profile Level 3, VSM<=8192.*/ + + /* vpSizeType possible values are 0,1,2 or 3*/ + CHECK_RANGE0(pMp4Conf->vpSizeType, 0, 3); + + /* Video packet bit size (VBS used only when vp_size_type=0/2/3) + The following relation must hold:0<=VBS<= vpSizeMax */ + if(pMp4Conf->vpSizeType != 1) {CHECK_RANGE0(pMp4Conf->vpBitSize, 0, pMp4Conf->vpSizeMax);} + + /*Video packet macroblock size (VMS used only when vp_size_type=1/2/3). + The following relation must hold:0<=VMS<=window_width*window_height/256*/ + if(pMp4Conf->vpSizeType != 0) {CHECK_RANGE0(pMp4Conf->vpMbSize, 0, width*height/256);} + + } + } + /*check isSystemHeaderAddBeforeIntra*/ + if (pMp4Conf->isSystemHeaderAddBeforeIntra == TRUE && pMp4Conf->flagShortHeader == TRUE) + { + /*insertion of vol header is only valid in simple profile*/ + return FALSE; + } + + /*check deblocking support*/ + /*for mpeg4 / only no deblocking or out of the loop SVA_DEBLOCKING_DERINGING_FILTER allowed*/ + if ((pConf->inTheLoopFilter!=SVA_NONE_FILTER || pConf->outTheLoopFilter!=SVA_DEBLOCKING_DERINGING_FILTER) && + (pConf->inTheLoopFilter!=SVA_NONE_FILTER || pConf->outTheLoopFilter!=SVA_NONE_FILTER)) + { + return FALSE; + } + + /* check brcMode/bufferingModel/flagShortHeader compatibility*/ + switch(pConf->brcMode) + { + case SVA_QP_CONSTANT: + if (pMp4Conf->flagShortHeader == TRUE) + { + if (pConf->bufferingModel == SVA_BUFFERING_VBV) {return FALSE;} + } + else + { + if (pConf->bufferingModel == SVA_BUFFERING_HRD || + pConf->bufferingModel == SVA_BUFFERING_ANNEXG) + { + return FALSE; + } + } + break; + case SVA_FRAME_BASE: + if (pConf->bufferingModel != SVA_BUFFERING_NONE) {return FALSE;} + break; + case SVA_CBR: + if (pMp4Conf->flagShortHeader == TRUE && pConf->bufferingModel != SVA_BUFFERING_HRD) {return FALSE;} + else if (pMp4Conf->flagShortHeader == FALSE && pConf->bufferingModel != SVA_BUFFERING_VBV) {return FALSE;} + break; + case SVA_VBR: + if (pMp4Conf->flagShortHeader == TRUE && pConf->bufferingModel != SVA_BUFFERING_ANNEXG) {return FALSE;} + else if (pMp4Conf->flagShortHeader == FALSE && pConf->bufferingModel != SVA_BUFFERING_VBV) {return FALSE;} + break; + default: + return FALSE; +// break; line commented fcor warning removal. + } + + return TRUE; +} + +/****************************************************************************/ +/* NAME: t_sva_ec_algo_error sva_EC_MP4_SH_GetNextFrameParamIn( */ +/* t_sva_service_instance_num instanceNum, */ +/* t_sva_ec_algo_params_in *pParamIn */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will fill paramin picture for next picture for SH. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - instanceNum: number of the descriptor to use. */ +/* */ +/* OUT : */ +/* - pParamIn: parameters to output */ +/* */ +/* RETURN: */ +/* t_sva_ec_algo_error */ +/* t.b.d */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + * do correct modulo_time_base and vop_time_increment use when + * ts_seconds and ts_modulo stuff ok. +*/ +PRIVATE t_sva_ec_algo_error sva_EC_MP4_SH_GetNextFrameParamIn( + t_sva_service_instance_num instanceNum, + t_sva_ec_algo_params_in *pParamIn +) +{ + t_sva_ec_mp4_descriptor *pDesc=&mp4EncodeDesc[instanceNum]; + t_sva_vec_mpeg4_param_in *pMpeg4ParamIn=(t_sva_vec_mpeg4_param_in *) pParamIn; + t_sva_ec_save *pCur = &pDesc->current; + t_bool isPreviousSkip; + t_bool isPictureReplay; + t_sva_brc_error brcError; + t_sva_ec_save *pPrev; + t_uint32 i; + + HCL_ASSERT(pParamIn!=NULL); + HCL_ASSERT(pMpeg4ParamIn!=NULL); + + /*get info from brc concerning param in*/ + brcError=sva_EC_BRC_InitPicture(instanceNum,pDesc->brcUserRequest,pCur->pts,&pDesc->brcOut,&isPreviousSkip); + if (brcError!=SVA_BRC_OK) {return SVA_EC_MP4_BRC_ERROR;} + /* + * Now is the fun part !!!!!!! + * At this point we know if previous picture has been skip or not. Moreover by compare pDesc->pts with the + * last one push we can detect the case where a picture is programmed twice due to skip interrupt. + * We then define pPrev tha point on previous not skip picture info. + */ + if (pCur->pts == pDesc->skipFifo[0].pts && pCur->pictureNb != ~0) {isPictureReplay = TRUE;} + else {isPictureReplay = FALSE;} + if (isPreviousSkip == TRUE) + { + if (isPictureReplay == TRUE) {pPrev = &pDesc->skipFifo[2];} + else {pPrev = &pDesc->skipFifo[1];} + } + else {pPrev = &pDesc->skipFifo[0];} + + /*compute pictureNb*/ + pCur->pictureNb = pPrev->pictureNb + 1; + + /*compute temporal reference*/ + if (pCur->pictureNb == 0) + { + pCur->temporalSh.tr = 0; + pCur->temporalSh.cumulTimeSlot = 0; + pCur->temporalSh.slotDelay = 0; + } + else + { + t_uint32 ptsDifference; + + /*compute pts difference*/ + ptsDifference = pCur->pts - pPrev->pts; + + /*update tr. Use ptsDifference*/ + pCur->temporalSh.tr = ((ptsDifference + pPrev->temporalSh.cumulTimeSlot + MP4_SH_ROUND_VALUE) / MP4_SH_CLOCK_SLOT + pPrev->temporalSh.tr)&0xff; + pCur->temporalSh.cumulTimeSlot = (ptsDifference + pPrev->temporalSh.cumulTimeSlot + MP4_SH_ROUND_VALUE) % MP4_SH_CLOCK_SLOT; + pCur->temporalSh.cumulTimeSlot -= MP4_SH_ROUND_VALUE; + + /*rounding of tr*/ + /*pCur->temporalSh.slotDelay = pPrev->temporalSh.slotDelay; + if (pCur->temporalSh.cumulTimeSlot !=0 && pCur->temporalSh.slotDelay == 0) + { + pCur->temporalSh.tr++; + pCur->temporalSh.slotDelay = 1; + } + else if (pCur->temporalSh.cumulTimeSlot == 0 && pCur->temporalSh.slotDelay !=0) + { + pCur->temporalSh.tr--; + pCur->temporalSh.slotDelay = 0; + }*/ + } + + /*fill brc parameters*/ + pMpeg4ParamIn->picture_coding_type=pDesc->brcOut.pictureCodingType; + pCur->pictureCodingType = pDesc->brcOut.pictureCodingType; + pMpeg4ParamIn->quant=pDesc->brcOut.quant; + pMpeg4ParamIn->brc_type=pDesc->brcOut.brcType; + pMpeg4ParamIn->brc_frame_target=pDesc->brcOut.brcFrameTarget; + pMpeg4ParamIn->brc_target_min_pred=pDesc->brcOut.brcTargetMinPred; + pMpeg4ParamIn->brc_target_max_pred=pDesc->brcOut.brcTargetMaxPred; + pMpeg4ParamIn->skip_count=pDesc->brcOut.skipCount; + pMpeg4ParamIn->bit_rate=pDesc->brcOut.bitRate; + pMpeg4ParamIn->framerate=pDesc->brcOut.frameRate; + pMpeg4ParamIn->ts_modulo = (t_short_value)pDesc->brcOut.tsModulo; + pMpeg4ParamIn->ts_seconds = (t_ushort_value)pDesc->brcOut.tsSeconds; + pMpeg4ParamIn->delta_target=pDesc->brcOut.deltaTarget; + pMpeg4ParamIn->minQp=pDesc->brcOut.minQp; + pMpeg4ParamIn->maxQp=pDesc->brcOut.maxQp; + pMpeg4ParamIn->vop_time_increment_resolution=pDesc->brcOut.vopTimeIncrementResolution; + pMpeg4ParamIn->fixed_vop_time_increment=pDesc->brcOut.fixedVopTimeIncrement; + pMpeg4ParamIn->Smax=pDesc->brcOut.smax; + pMpeg4ParamIn->min_base_quality=pDesc->brcOut.minBaseQuality; + pMpeg4ParamIn->min_framerate=pDesc->brcOut.minFrameRate; + pMpeg4ParamIn->max_buff_level=pDesc->brcOut.maxBuffLevel; + pMpeg4ParamIn->first_I_skipped_flag=pDesc->brcOut.firstISkippedFlag; + pMpeg4ParamIn->init_ts_modulo_old=pDesc->brcOut.initTsModuloOld; + + /*fill mpeg4 short header parameters*/ + pMpeg4ParamIn->flag_short_header=(t_uint16)((pDesc->mp4Conf.flagShortHeader==TRUE)?1:0); + pMpeg4ParamIn->frame_width=pDesc->conf.sourceFrameDesc.frame.width; + pMpeg4ParamIn->frame_height=pDesc->conf.sourceFrameDesc.frame.height; + pMpeg4ParamIn->window_width=pDesc->conf.sourceFrameDesc.window.image.width; + pMpeg4ParamIn->window_height=pDesc->conf.sourceFrameDesc.window.image.height; + if (pDesc->conf.isCroppingVectorEnabled==TRUE) + { + pMpeg4ParamIn->window_horizontal_offset=pDesc->croppingVector.offsetX; + pMpeg4ParamIn->window_vertical_offset=pDesc->croppingVector.offsetY; + } + else + { + pMpeg4ParamIn->window_horizontal_offset=pDesc->conf.sourceFrameDesc.window.imageOffset.offsetX; + pMpeg4ParamIn->window_vertical_offset=pDesc->conf.sourceFrameDesc.window.imageOffset.offsetY; + } + pMpeg4ParamIn->gob_header_freq=pDesc->mp4Conf.gobHeaderFrequency; + if (pPrev->pictureCodingType != pCur->pictureCodingType && pDesc->mp4Conf.gobHeaderFrequency != 0) + { + pCur->gobFrameId = (pPrev->gobFrameId+1)&0x3; + } + pMpeg4ParamIn->gob_frame_id=pCur->gobFrameId; + pMpeg4ParamIn->data_partitioned=(t_uint16)((pDesc->mp4Conf.isDataPartitionedEnable==TRUE)?1:0); + pMpeg4ParamIn->reversible_vlc=(t_uint16)((pDesc->mp4Conf.isReversibleVlcEnable==TRUE)?1:0); + pMpeg4ParamIn->hec_freq=pDesc->mp4Conf.hecFreq; + pMpeg4ParamIn->modulo_time_base=0; + pMpeg4ParamIn->vop_time_increment=0; + pMpeg4ParamIn->vp_size_type=pDesc->mp4Conf.vpSizeType; + pMpeg4ParamIn->vp_size_max=pDesc->mp4Conf.vpSizeMax; + pMpeg4ParamIn->vp_bit_size=pDesc->mp4Conf.vpBitSize; + pMpeg4ParamIn->vp_mb_size=pDesc->mp4Conf.vpMbSize; + pMpeg4ParamIn->init_me=(t_uint16)((pCur->pictureNb == 0)?1:0); + + if(pMpeg4ParamIn->flag_short_header == TRUE) + { + if(pMpeg4ParamIn->vp_bit_size != 0)//segmented mode + { + pMpeg4ParamIn->minQp = 4; //CR 155 must be forced + pMpeg4ParamIn->vp_size_type = 0; //CR 155 must be forced + + } + } + + if( pDesc->conf.sourceFrameDesc.window.image.width <= SVA_EC_MP4_QCIF_WIDTH && + pDesc->conf.sourceFrameDesc.window.image.height <= SVA_EC_MP4_QCIF_HEIGHT && + (pDesc->mp4Conf.vopTimeIncrementResolution / pDesc->mp4Conf.vopTimeIncrement) <= 15) + {/* Slimpeg optimized for low resolution/frame rate (improved quality) */ + pMpeg4ParamIn->me_type=1; + } + else + { + if( pDesc->conf.sourceFrameDesc.window.image.width >= SVA_EC_MP4_VGA_WIDTH || + pDesc->conf.sourceFrameDesc.window.image.height >= SVA_EC_MP4_VGA_HEIGHT ) + {/* Slimpeg optimized for high resolution/frame rate (improved performance) */ + pMpeg4ParamIn->me_type=2; + } + else + {/* normal slimpeg */ + pMpeg4ParamIn->me_type=0; + } + } + + + pMpeg4ParamIn->vop_fcode_forward=1;/* not use in SH */ + if (pDesc->mp4Conf.rtypeMode==SVA_RTYPE_MODE_CONSTANT_ZERO) {pMpeg4ParamIn->rounding_type=0;} + else if (pDesc->mp4Conf.rtypeMode==SVA_RTYPE_MODE_CONSTANT_ONE) {pMpeg4ParamIn->rounding_type=1;} + else + { + pMpeg4ParamIn->rounding_type = pPrev->roundValue; + if (pDesc->brcOut.pictureCodingType!=0) {pMpeg4ParamIn->rounding_type = 1 - pMpeg4ParamIn->rounding_type;} + } + pCur->roundValue = pMpeg4ParamIn->rounding_type; + pMpeg4ParamIn->intra_refresh_type=(t_uint16) pDesc->mp4Conf.irMode; + pMpeg4ParamIn->air_mb_num=pDesc->mp4Conf.airMbNum; + pMpeg4ParamIn->cir_period_max=pDesc->mp4Conf.cirPeriodMax; + pMpeg4ParamIn->air_thr = (t_ushort_value)pDesc->airThreshold; + for(i=0;i<8;i++) + { + if (pDesc->isFlagIntraRequest == TRUE) + { + pMpeg4ParamIn->slice_loss_first_mb[i]=pDesc->intraRequest.sliceIntraFirstMb[i]; + pMpeg4ParamIn->slice_loss_mb_num[i]=pDesc->intraRequest.sliceIntraMbNumber[i]; + } + else + { + pMpeg4ParamIn->slice_loss_first_mb[i]=0; + pMpeg4ParamIn->slice_loss_mb_num[i]=0; + } + } + pDesc->isFlagIntraRequest = FALSE; + + /*shift fifo*/ + if (isPreviousSkip == TRUE) + { + if (isPictureReplay == TRUE) {pDesc->skipFifo[1] = pDesc->skipFifo[2];} + } + else + { + pDesc->skipFifo[2] = pDesc->skipFifo[1]; + pDesc->skipFifo[1] = pDesc->skipFifo[0]; + } + pDesc->skipFifo[0] = *pCur; + + + return SVA_EC_ALGO_OK; +} + +/****************************************************************************/ +/* NAME: t_sva_ec_algo_error sva_EC_MP4_SP_GetNextFrameParamIn( */ +/* t_sva_service_instance_num instanceNum, */ +/* t_sva_ec_algo_params_in *pParamIn */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will fill paramin picture for next picture for SP. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - instanceNum: number of the descriptor to use. */ +/* */ +/* OUT : */ +/* - pParamIn: parameters to output */ +/* */ +/* RETURN: */ +/* t_sva_ec_algo_error */ +/* t.b.d */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + * TODO : add ts_seconds and ts_modulo stuff +*/ +PRIVATE t_sva_ec_algo_error sva_EC_MP4_SP_GetNextFrameParamIn( + t_sva_service_instance_num instanceNum, + t_sva_ec_algo_params_in *pParamIn +) +{ + t_sva_ec_mp4_descriptor *pDesc=&mp4EncodeDesc[instanceNum]; + t_sva_vec_mpeg4_param_in *pMpeg4ParamIn=(t_sva_vec_mpeg4_param_in *) pParamIn; + t_sva_ec_save *pCur = &pDesc->current; + t_sva_brc_error brcError; + t_bool isPreviousSkip; + t_bool isPictureReplay; + t_sva_ec_save *pPrev; + t_uint32 i; + + HCL_ASSERT(pParamIn!=NULL); + HCL_ASSERT(pMpeg4ParamIn!=NULL); + /*get info from brc concerning param in*/ + brcError=sva_EC_BRC_InitPicture(instanceNum,pDesc->brcUserRequest,pCur->pts,&pDesc->brcOut,&isPreviousSkip); + if (brcError!=SVA_BRC_OK) {return SVA_EC_MP4_BRC_ERROR;} + /* + * Now is the fun part !!!!!!! + * At this point we know if previous picture has been skip or not. Moreover by compare pDesc->pts with the + * last one push we can detect the case where a picture is programmed twice due to skip interrupt. + * We then define pPrev tha point on previous not skip picture info. + */ + if (pCur->pts == pDesc->skipFifo[0].pts) {isPictureReplay = TRUE;} + else {isPictureReplay = FALSE;} + if (isPreviousSkip == TRUE) + { + if (isPictureReplay == TRUE) {pPrev = &pDesc->skipFifo[2];} + else {pPrev = &pDesc->skipFifo[1];} + } + else {pPrev = &pDesc->skipFifo[0];} + + /*compute pictureNb*/ + pCur->pictureNb = pPrev->pictureNb + 1; + + /*compute temporal reference*/ + if (pCur->pictureNb == 0) + { + pCur->temporalSp.remainForOffset=0; + pCur->temporalSp.moduloTimeBase=0; + pCur->temporalSp.vopTimeIncrement=0; + pDesc->isSnapshotNeeded = TRUE; + } + else + { + t_uint32 ptsDifference; + t_uint32 incDifference; + + /*compute pts difference*/ + ptsDifference = pCur->pts - pPrev->pts; + + /*update temporal reference value. Use ptsDifference*/ + /*convert ptsDifference in 90Khz to incDifference in vopTimeIncrementResolutionHz value*/ + incDifference=(ptsDifference * pDesc->mp4Conf.vopTimeIncrementResolution + pPrev->temporalSp.remainForOffset)/90000; + pCur->temporalSp.remainForOffset = (ptsDifference * pDesc->mp4Conf.vopTimeIncrementResolution + pPrev->temporalSp.remainForOffset)%90000; + /* parly optimal time stamp stuff */ + if (pDesc->conf.brcMode == SVA_CBR) + { + if (pDesc->isSnapshotNeeded == TRUE) + { + pDesc->isSnapshotNeeded =FALSE; + pDesc->saveVopTimeIncrement = incDifference; + pDesc->saveRemainForOffset = pCur->temporalSp.remainForOffset; + } + else if (pPrev->pictureNb == 0 && isPreviousSkip == TRUE) + { + incDifference = pDesc->saveVopTimeIncrement; + pCur->temporalSp.remainForOffset = pDesc->saveRemainForOffset; + } + } + /*compute moduloTimeBase and vopTimeIncrement value*/ + pCur->temporalSp.vopTimeIncrement = pPrev->temporalSp.vopTimeIncrement + incDifference; + + /*correct vopTimeIncrement in case of frame skipping */ + if(isPreviousSkip == TRUE){ + if (isPictureReplay == TRUE){ + if(pDesc->skipFifo[2].temporalSp.vopTimeIncrement > pDesc->skipFifo[0].temporalSp.vopTimeIncrement){ + while(pCur->temporalSp.vopTimeIncrement >= pDesc->mp4Conf.vopTimeIncrementResolution) + pCur->temporalSp.vopTimeIncrement -= pDesc->mp4Conf.vopTimeIncrementResolution; + } + + } + else { + if(pDesc->skipFifo[1].temporalSp.vopTimeIncrement > pDesc->skipFifo[0].temporalSp.vopTimeIncrement){ + while(pCur->temporalSp.vopTimeIncrement >= pDesc->mp4Conf.vopTimeIncrementResolution) + pCur->temporalSp.vopTimeIncrement -= pDesc->mp4Conf.vopTimeIncrementResolution; + } + } + } + + pCur->temporalSp.moduloTimeBase = 0; + while(pCur->temporalSp.vopTimeIncrement >= pDesc->mp4Conf.vopTimeIncrementResolution) + { + pCur->temporalSp.vopTimeIncrement -= pDesc->mp4Conf.vopTimeIncrementResolution; + pCur->temporalSp.moduloTimeBase++; + } + } + /*fill brc parameters*/ + pMpeg4ParamIn->picture_coding_type=pDesc->brcOut.pictureCodingType; + pCur->pictureCodingType = pDesc->brcOut.pictureCodingType; + pMpeg4ParamIn->quant=pDesc->brcOut.quant; + pMpeg4ParamIn->brc_type=pDesc->brcOut.brcType; + pMpeg4ParamIn->brc_frame_target=pDesc->brcOut.brcFrameTarget; + pMpeg4ParamIn->brc_target_min_pred=pDesc->brcOut.brcTargetMinPred; + pMpeg4ParamIn->brc_target_max_pred=pDesc->brcOut.brcTargetMaxPred; + // pMpeg4ParamIn->skip_count=pDesc->brcOut.skipCount; + pMpeg4ParamIn->skip_count=0; //changed for brc + pMpeg4ParamIn->bit_rate=pDesc->brcOut.bitRate; + pMpeg4ParamIn->ts_modulo = (t_short_value)pDesc->brcOut.tsModulo; + pMpeg4ParamIn->ts_seconds = (t_ushort_value)pDesc->brcOut.tsSeconds; + pMpeg4ParamIn->framerate=pDesc->brcOut.frameRate; + pMpeg4ParamIn->delta_target=pDesc->brcOut.deltaTarget; + pMpeg4ParamIn->minQp=pDesc->brcOut.minQp; + pMpeg4ParamIn->maxQp=pDesc->brcOut.maxQp; + pMpeg4ParamIn->vop_time_increment_resolution=pDesc->brcOut.vopTimeIncrementResolution; + pMpeg4ParamIn->fixed_vop_time_increment=pDesc->brcOut.fixedVopTimeIncrement; + pMpeg4ParamIn->Smax=pDesc->brcOut.smax; + pMpeg4ParamIn->min_base_quality=pDesc->brcOut.minBaseQuality; + pMpeg4ParamIn->min_framerate=pDesc->brcOut.minFrameRate; + pMpeg4ParamIn->max_buff_level=pDesc->brcOut.maxBuffLevel; + pMpeg4ParamIn->first_I_skipped_flag=pDesc->brcOut.firstISkippedFlag; + pMpeg4ParamIn->init_ts_modulo_old=pDesc->brcOut.initTsModuloOld; + + /*fill vop time increment resolution*/ + pMpeg4ParamIn->vop_time_increment_resolution=pDesc->mp4Conf.vopTimeIncrementResolution; + + /*fill mpeg4 simple profile parameters*/ + pMpeg4ParamIn->flag_short_header=(t_uint16)((pDesc->mp4Conf.flagShortHeader==TRUE)?1:0); + pMpeg4ParamIn->frame_width=pDesc->conf.sourceFrameDesc.frame.width; + pMpeg4ParamIn->frame_height=pDesc->conf.sourceFrameDesc.frame.height; + pMpeg4ParamIn->window_width=pDesc->conf.sourceFrameDesc.window.image.width; + pMpeg4ParamIn->window_height=pDesc->conf.sourceFrameDesc.window.image.height; + if (pDesc->conf.isCroppingVectorEnabled==TRUE) + { + pMpeg4ParamIn->window_horizontal_offset=pDesc->croppingVector.offsetX; + pMpeg4ParamIn->window_vertical_offset=pDesc->croppingVector.offsetY; + } + else + { + pMpeg4ParamIn->window_horizontal_offset=pDesc->conf.sourceFrameDesc.window.imageOffset.offsetX; + pMpeg4ParamIn->window_vertical_offset=pDesc->conf.sourceFrameDesc.window.imageOffset.offsetY; + } + pMpeg4ParamIn->gob_header_freq=pDesc->mp4Conf.gobHeaderFrequency; + pMpeg4ParamIn->gob_frame_id=0; + pMpeg4ParamIn->data_partitioned=(t_uint16)((pDesc->mp4Conf.isDataPartitionedEnable==TRUE)?1:0); + pMpeg4ParamIn->reversible_vlc=(t_uint16)((pDesc->mp4Conf.isReversibleVlcEnable==TRUE)?1:0); + pMpeg4ParamIn->hec_freq=pDesc->mp4Conf.hecFreq; + //pMpeg4ParamIn->modulo_time_base=(1<<(pCur->temporalSp.moduloTimeBase+1))-2; + pMpeg4ParamIn->modulo_time_base = (t_ushort_value)pCur->temporalSp.moduloTimeBase; + pMpeg4ParamIn->vop_time_increment=(t_ushort_value)pCur->temporalSp.vopTimeIncrement; + pMpeg4ParamIn->vp_size_type=pDesc->mp4Conf.vpSizeType; + pMpeg4ParamIn->vp_size_max=pDesc->mp4Conf.vpSizeMax; + pMpeg4ParamIn->vp_bit_size=pDesc->mp4Conf.vpBitSize; + pMpeg4ParamIn->vp_mb_size=pDesc->mp4Conf.vpMbSize; + pMpeg4ParamIn->init_me=(t_uint16)((pCur->pictureNb == 0)?1:0); + + if( pDesc->conf.sourceFrameDesc.window.image.width <= SVA_EC_MP4_QCIF_WIDTH && + pDesc->conf.sourceFrameDesc.window.image.height <= SVA_EC_MP4_QCIF_HEIGHT && + (pDesc->mp4Conf.vopTimeIncrementResolution / pDesc->mp4Conf.vopTimeIncrement) <= 15) + {/* Slimpeg optimized for low resolution/frame rate (improved quality) */ + pMpeg4ParamIn->me_type=1; + } + else + { + if( pDesc->conf.sourceFrameDesc.window.image.width >= SVA_EC_MP4_VGA_WIDTH || + pDesc->conf.sourceFrameDesc.window.image.height >= SVA_EC_MP4_VGA_HEIGHT ) + {/* Slimpeg optimized for high resolution/frame rate (improved performance) */ + pMpeg4ParamIn->me_type=2; + } + else + {/* normal slimpeg */ + pMpeg4ParamIn->me_type=0; + } + } + + + /* stretch motion vector according to skip count */ + // pMpeg4ParamIn->vop_fcode_forward=(t_ushort_value)( 1 + pDesc->brcOut.skipCount); + pMpeg4ParamIn->vop_fcode_forward = 1; //changed for brc + if (pMpeg4ParamIn->vop_fcode_forward > 7) {pMpeg4ParamIn->vop_fcode_forward = 7;} + if (pDesc->mp4Conf.rtypeMode==SVA_RTYPE_MODE_CONSTANT_ZERO) {pMpeg4ParamIn->rounding_type=0;} + else if (pDesc->mp4Conf.rtypeMode==SVA_RTYPE_MODE_CONSTANT_ONE) {pMpeg4ParamIn->rounding_type=1;} + else + { + pMpeg4ParamIn->rounding_type = pPrev->roundValue; + if (pDesc->brcOut.pictureCodingType!=0) {pMpeg4ParamIn->rounding_type = 1 - pMpeg4ParamIn->rounding_type;} + } + pCur->roundValue = pMpeg4ParamIn->rounding_type; + pMpeg4ParamIn->intra_refresh_type=(t_uint16) pDesc->mp4Conf.irMode; + pMpeg4ParamIn->air_mb_num=pDesc->mp4Conf.airMbNum; + pMpeg4ParamIn->cir_period_max=pDesc->mp4Conf.cirPeriodMax; + pMpeg4ParamIn->air_thr = (t_ushort_value)pDesc->airThreshold; + for(i=0;i<8;i++) + { + if (pDesc->isFlagIntraRequest == TRUE) + { + pMpeg4ParamIn->slice_loss_first_mb[i]=pDesc->intraRequest.sliceIntraFirstMb[i]; + pMpeg4ParamIn->slice_loss_mb_num[i]=pDesc->intraRequest.sliceIntraMbNumber[i]; + } + else + { + pMpeg4ParamIn->slice_loss_first_mb[i]=0; + pMpeg4ParamIn->slice_loss_mb_num[i]=0; + } + } + pDesc->isFlagIntraRequest = FALSE; + + /*shift fifo*/ + if (isPreviousSkip == TRUE) + { + if (isPictureReplay == TRUE) {pDesc->skipFifo[1] = pDesc->skipFifo[2];} + } + else + { + pDesc->skipFifo[2] = pDesc->skipFifo[1]; + pDesc->skipFifo[1] = pDesc->skipFifo[0]; + } + pDesc->skipFifo[0] = *pCur; + + return SVA_EC_ALGO_OK; +} + + +/****************************************************************************/ +/* NAME: t_sva_ec_algo_error sva_EC_MP4_SH_GetNextHeader( */ +/* t_sva_service_instance_num instanceNum, */ +/* t_sva_ec_algo_header *pHeader, */ +/* t_size *pSizeInBits */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will fill header picture for next picture for SH */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - instanceNum: number of the descriptor to use. */ +/* */ +/* OUT : */ +/* - pHeader: header to write */ +/* - pSizeInBits: size in bits of the header */ +/* */ +/* RETURN: */ +/* t_sva_ec_algo_error */ +/* t.b.d */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + * DONE +*/ +PRIVATE t_sva_ec_algo_error sva_EC_MP4_SH_GetNextHeader( + t_sva_service_instance_num instanceNum, + t_sva_ec_algo_header *pHeader, + t_size *pSizeInBits +) +{ + t_sva_ec_mp4_descriptor *pDesc=&mp4EncodeDesc[instanceNum]; + t_sva_ec_save *pCur = &pDesc->current; + t_uint8 *pHeaderData=(t_uint8 *) pHeader; + t_uint16 width=pDesc->conf.sourceFrameDesc.window.image.width; + t_uint16 height=pDesc->conf.sourceFrameDesc.window.image.height; + t_uint8 temporalReferenceMsb; + t_uint8 temporalReferenceLsb; + t_uint8 sourceFormat; + + HCL_ASSERT(pHeader!=NULL); + HCL_ASSERT(pSizeInBits!=NULL); + HCL_ASSERT(pHeaderData!=NULL); + + /*compute intermediate parameters*/ + temporalReferenceMsb=(t_uint8)((pCur->temporalSh.tr&0xc0)>>6); + temporalReferenceLsb=(t_uint8)((pCur->temporalSh.tr&0x3f)<<2); + /* compute it only once*/ + if (width==SVA_EC_MP4_SQCIF_WIDTH && height==SVA_EC_MP4_SQCIF_HEIGHT) {sourceFormat=SVA_EC_MP4_SH_SOURCE_FORMAT_SQCIF;} + else if (width==SVA_EC_MP4_QCIF_WIDTH && height==SVA_EC_MP4_QCIF_HEIGHT) {sourceFormat=SVA_EC_MP4_SH_SOURCE_FORMAT_QCIF;} + else if (width==SVA_EC_MP4_CIF_WIDTH && height==SVA_EC_MP4_CIF_HEIGHT) {sourceFormat=SVA_EC_MP4_SH_SOURCE_FORMAT_CIF;} + else if (width==SVA_EC_MP4_CIF4_WIDTH && height==SVA_EC_MP4_CIF4_HEIGHT) {sourceFormat=SVA_EC_MP4_SH_SOURCE_FORMAT_CIF4;} + else if (width==SVA_EC_MP4_CIF16_WIDTH && height==SVA_EC_MP4_CIF16_HEIGHT) {sourceFormat=SVA_EC_MP4_SH_SOURCE_FORMAT_CIF16;} + else if (width==SVA_EC_MP4_VGA_WIDTH && height==SVA_EC_MP4_VGA_HEIGHT) {sourceFormat=SVA_EC_MP4_SH_SOURCE_FORMAT_VGA;} + else if (width==SVA_EC_MP4_MB1_WIDTH && height==SVA_EC_MP4_MB1_HEIGHT) {sourceFormat=SVA_EC_MP4_SH_SOURCE_FORMAT_MB1;} + else {return SVA_EC_MP4_PARAM_ERROR;} + + /*fill header*/ + pHeaderData[0]=0x00; + pHeaderData[1]=0x00; + pHeaderData[2]=(t_uint8)(0x80+temporalReferenceMsb); + pHeaderData[3]=(t_uint8)(0x02+temporalReferenceLsb); + pHeaderData[4]=(t_uint8)((sourceFormat<<2)+(pCur->pictureCodingType<<1)); + pHeaderData[5]=0; + + /*set header size in bits*/ + *pSizeInBits=43; + + return SVA_EC_ALGO_OK; +} + +/****************************************************************************/ +/* NAME: t_sva_ec_algo_error sva_EC_MP4_SP_GetNextHeader( */ +/* t_sva_service_instance_num instanceNum, */ +/* t_sva_ec_algo_header *pHeader, */ +/* t_size *pSizeInBits */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will fill header picture for next picture for SP */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - instanceNum: number of the descriptor to use. */ +/* */ +/* OUT : */ +/* - pHeader: header to write */ +/* - pSizeInBits: size in bits of the header */ +/* */ +/* RETURN: */ +/* t_sva_ec_algo_error */ +/* t.b.d */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + * TODO + * - add vol generation when requested +*/ +PRIVATE t_sva_ec_algo_error sva_EC_MP4_SP_GetNextHeader( + t_sva_service_instance_num instanceNum, + t_sva_ec_algo_header *pHeader, + t_size *pSizeInBits +) +{ + t_sva_ec_mp4_descriptor *pDesc=&mp4EncodeDesc[instanceNum]; + t_sva_ec_save *pCur = &pDesc->current; + t_sva_ec_mp4_write_stream writeStream; + t_sva_ec_algo_error algoError; + + HCL_ASSERT(pHeader!=NULL); + HCL_ASSERT(pSizeInBits!=NULL); + (void) instanceNum; + + /*init stream structure*/ + algoError=sva_EC_MP4_initWriteStream((t_uint8 *) pHeader,SVA_EC_MP4_SP_MAX_HEADER_SIZE,&writeStream); + if (algoError!=SVA_EC_ALGO_OK) {return algoError;} + + /*write VOS+VO+VOL is needed*/ + if (pCur->pictureNb != 0 && pCur->pictureCodingType == SVA_MP4_I_PICTURE && + pDesc->mp4Conf.isSystemHeaderAddBeforeIntra == TRUE) + { + /* VOS part*/ + sva_EC_MP4_writeBits(&writeStream,SVA_MPEG4_VOS_START_CODE,32); + sva_EC_MP4_writeBits(&writeStream,pDesc->mp4Conf.profileAndLevel,8); + /* VO part*/ + sva_EC_MP4_writeBits(&writeStream,SVA_MPEG4_VISUAL_OBJECT_START_CODE,32); + /* set is_visual_object_identifier to zero*/ + sva_EC_MP4_writeBits(&writeStream,0,1); + sva_EC_MP4_writeBits(&writeStream,SVA_MPEG4_VIDEO_OBJECT_TYPE,4); + /* set video_signal_type to zero*/ + sva_EC_MP4_writeBits(&writeStream,0,1); + /* alignement */ + sva_EC_MP4_writeBits(&writeStream,1,2); + sva_EC_MP4_writeBits(&writeStream,SVA_MPEG4_VIDEO_OBJECT_START_CODE,32); + /* VOL part */ + sva_EC_MP4_writeBits(&writeStream,SVA_MPEG4_VOL_START_CODE,32); + /* random_accessible_vol set to zero*/ + sva_EC_MP4_writeBits(&writeStream,0,1); + sva_EC_MP4_writeBits(&writeStream,SVA_MPEG4_SIMPLE_OBJECT_TYPE,8); + /* is_object_layer_identifier set to zero */ + sva_EC_MP4_writeBits(&writeStream,0,1); + sva_EC_MP4_writeBits(&writeStream,SVA_MPEG4_SQUARE_ASPECT_RATIO,4); + /* + * We don't give vbv information when there is no buffering model + */ + if (pDesc->conf.bufferingModel == SVA_BUFFERING_NONE) + { + /* no vbv information set*/ + sva_EC_MP4_writeBits(&writeStream,SVA_MPEG4_NO_VBV_PRESENT,1); + } + else + { + /* vbv information set*/ + sva_EC_MP4_writeBits(&writeStream,SVA_MPEG4_VBV_PRESENT,1); + sva_EC_MP4_writeBits(&writeStream,SVA_MPEG4_CHROMA_4_2_0,2); + /* always low delay */ + sva_EC_MP4_writeBits(&writeStream,1,1); + /* vbv data present */ + sva_EC_MP4_writeBits(&writeStream,1,1); + /* first part of bitrate set to zero since out of level range*/ + sva_EC_MP4_writeBits(&writeStream,0,15); + sva_EC_MP4_writeBits(&writeStream,SVA_MPEG4_MARKER_BIT,1); + sva_EC_MP4_writeBits(&writeStream,(pDesc->brcOut.bitRate + 399) / 400,15); + sva_EC_MP4_writeBits(&writeStream,SVA_MPEG4_MARKER_BIT,1); + sva_EC_MP4_writeBits(&writeStream,(pDesc->brcOut.vbvBufferSizeIn16384BitsUnit >> 3),15); + /* + * At this point we don't have all the info to fill correctly vbvOccupancy + * as we need size of picture n-1. So we store hostBuffer - bufferDepletion(n/n-1) + * instead of (marker+latter_half_vbv_buffer_size+...+marker_bit). + * This value will then be patch when receiving eot for picture n using previous + * picture size and original vbv_occupancy. + */ + sva_EC_MP4_writeBits(&writeStream,pDesc->brcOut.bufferSizeForVbv,32); + + + + /*sva_EC_MP4_writeBits(&writeStream,SVA_MPEG4_MARKER_BIT,1); + sva_EC_MP4_writeBits(&writeStream,(pDesc->brcOut.vbvBufferSizeIn16384BitsUnit & 0x7),3);*/ + /* first part of vbv occupancy set to zero since out of level range*/ + /*sva_EC_MP4_writeBits(&writeStream,0,11); + sva_EC_MP4_writeBits(&writeStream,SVA_MPEG4_MARKER_BIT,1); + sva_EC_MP4_writeBits(&writeStream,pDesc->brcOut.vbvOccupancyIn64BitsUnit,15); + sva_EC_MP4_writeBits(&writeStream,SVA_MPEG4_MARKER_BIT,1);*/ + } + sva_EC_MP4_writeBits(&writeStream,SVA_MPEG4_VIDEO_RECTANGULAR_SHAPE,2); + sva_EC_MP4_writeBits(&writeStream,SVA_MPEG4_MARKER_BIT,1); + sva_EC_MP4_writeBits(&writeStream,pDesc->mp4Conf.vopTimeIncrementResolution,16); + sva_EC_MP4_writeBits(&writeStream,SVA_MPEG4_MARKER_BIT,1); + /* fixed_vop_rate set to zero*/ + sva_EC_MP4_writeBits(&writeStream,0,1); + sva_EC_MP4_writeBits(&writeStream,SVA_MPEG4_MARKER_BIT,1); + sva_EC_MP4_writeBits(&writeStream,pDesc->conf.sourceFrameDesc.window.image.width,13); + sva_EC_MP4_writeBits(&writeStream,SVA_MPEG4_MARKER_BIT,1); + sva_EC_MP4_writeBits(&writeStream,pDesc->conf.sourceFrameDesc.window.image.height,13); + sva_EC_MP4_writeBits(&writeStream,SVA_MPEG4_MARKER_BIT,1); + /* not interlace */ + sva_EC_MP4_writeBits(&writeStream,0,1); + /* no obmc */ + sva_EC_MP4_writeBits(&writeStream,1,1); + /* no sprite*/ + sva_EC_MP4_writeBits(&writeStream,0,1); + /* 8 bits */ + sva_EC_MP4_writeBits(&writeStream,0,1); + /* no quant value per coeff */ + sva_EC_MP4_writeBits(&writeStream,0,1); + /* complexity estimation off */ + sva_EC_MP4_writeBits(&writeStream,1,1); + if (pDesc->mp4Conf.isDataPartitionedEnable == FALSE) + { + sva_EC_MP4_writeBits(&writeStream,1,1); + sva_EC_MP4_writeBits(&writeStream,0,1); + } + else + { + sva_EC_MP4_writeBits(&writeStream,0,1); + sva_EC_MP4_writeBits(&writeStream,1,1); + if (pDesc->mp4Conf.isReversibleVlcEnable == TRUE) + { + sva_EC_MP4_writeBits(&writeStream,1,1); + } + else + { + sva_EC_MP4_writeBits(&writeStream,0,1); + } + } + /* no scalability */ + sva_EC_MP4_writeBits(&writeStream,0,1); + /* align */ + sva_EC_MP4_align(&writeStream); + } + + /*write VOP header until quant value*/ + sva_EC_MP4_writeBits(&writeStream,SVA_MPEG4_VOP_START_CODE,32); + if (pCur->pictureCodingType==SVA_MP4_I_PICTURE) + { + sva_EC_MP4_writeBits(&writeStream,SVA_MPEG4_VOP_CODING_TYPE_I,2); + } + else + { + sva_EC_MP4_writeBits(&writeStream,SVA_MPEG4_VOP_CODING_TYPE_P,2); + } + /*timestamp stuff*/ + while(pCur->temporalSp.moduloTimeBase!=0) + { + pCur->temporalSp.moduloTimeBase--; + sva_EC_MP4_writeBits(&writeStream,1,1); + } + sva_EC_MP4_writeBits(&writeStream,0,1); + sva_EC_MP4_writeBits(&writeStream,SVA_MPEG4_MARKER_BIT,1); + sva_EC_MP4_writeBits(&writeStream,pCur->temporalSp.vopTimeIncrement,pCur->temporalSp.vopTimeIncrementBitSize); + sva_EC_MP4_writeBits(&writeStream,SVA_MPEG4_MARKER_BIT,1); + sva_EC_MP4_writeBits(&writeStream,SVA_MPEG4_VOP_CODED,1); + /*vop rounding stuff*/ + if (pDesc->brcOut.pictureCodingType==SVA_MP4_P_PICTURE) + { + if (pDesc->mp4Conf.rtypeMode==SVA_RTYPE_MODE_CONSTANT_ZERO) + { + sva_EC_MP4_writeBits(&writeStream,0,1); + } + else if (pDesc->mp4Conf.rtypeMode==SVA_RTYPE_MODE_CONSTANT_ONE) + { + sva_EC_MP4_writeBits(&writeStream,1,1); + } + else + { + sva_EC_MP4_writeBits(&writeStream,1-pCur->roundValue,1); + } + } + sva_EC_MP4_writeBits(&writeStream,SVA_MPEG4_INTRA_DC_VLC_THR,3); + + /*flush*/ + algoError=sva_EC_MP4_flushWriteStream(&writeStream); + if (algoError!=SVA_EC_ALGO_OK) {return algoError;} + + /*get number of bits written*/ + *pSizeInBits=writeStream.totalBitsWritten; + + return SVA_EC_ALGO_OK; +} + +/****************************************************************************/ +/* NAME: t_size sva_EC_MP4_SH_GetMaxHeaderSize( */ +/* t_sva_service_instance_num instanceNum */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will return max number of bytes a header can be. Thus */ +/* encode part will allocate enought space for such header. This is for*/ +/* a short header stream. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - instanceNum: number of the descriptor to use. */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_size */ +/* t.b.d */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + * DONE +*/ +PRIVATE t_size sva_EC_MP4_SH_GetMaxHeaderSize( + t_sva_service_instance_num instanceNum +) +{ + (void) instanceNum; + + return SVA_EC_MP4_SH_MAX_HEADER_SIZE; +} + +/****************************************************************************/ +/* NAME: t_size sva_EC_MP4_SP_GetMaxHeaderSize( */ +/* t_sva_service_instance_num instanceNum */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will return max number of bytes a header can be. Thus */ +/* encode part will allocate enought space for such header. This is for*/ +/* a simple profile stream. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - instanceNum: number of the descriptor to use. */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_size */ +/* t.b.d */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + * DONE +*/ +PRIVATE t_size sva_EC_MP4_SP_GetMaxHeaderSize( + t_sva_service_instance_num instanceNum +) +{ + (void) instanceNum; + + return SVA_EC_MP4_SP_MAX_HEADER_SIZE; +} + +/****************************************************************************/ +/* NAME: t_sva_ec_algo_error sva_EC_MP4_initWriteStream( */ +/* t_uint8 *pStartBuffer, */ +/* t_uint32 bufferSizeInBytes, */ +/* t_sva_ec_mp4_write_stream *pStream */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will init given pStream structure. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - pStartBuffer: start address of destination buffer. */ +/* - bufferSizeInBytes: size in bytes of destination buffer. */ +/* */ +/* OUT : */ +/* - pStream: structure to init. */ +/* */ +/* RETURN: */ +/* t_sva_ec_algo_error */ +/* t.b.d */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + * DONE +*/ +PRIVATE t_sva_ec_algo_error sva_EC_MP4_initWriteStream( + t_uint8 *pStartBuffer, + t_uint32 bufferSizeInBytes, + t_sva_ec_mp4_write_stream *pStream +) +{ + pStream->buffer=0; + pStream->nbBitsValid=0; + pStream->currBuffer=pStartBuffer; + pStream->endBuffer=pStartBuffer+bufferSizeInBytes; + pStream->totalBitsWritten=0; + + return SVA_EC_ALGO_OK; +} + +/****************************************************************************/ +/* NAME: void sva_EC_MP4_writeBits( */ +/* t_sva_ec_mp4_write_stream *pStream, */ +/* t_uint32 data, */ +/* t_uint32 nbBits */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will write nbBits with data value in output buffer. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - pStream: pointer that contain current state (INOUT). */ +/* - data: data value to write. */ +/* - nbBits: size in bits of the data to write */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_ec_algo_error */ +/* t.b.d */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + * DONE +*/ +PRIVATE void sva_EC_MP4_writeBits( + t_sva_ec_mp4_write_stream *pStream, + t_uint32 data, + t_uint32 nbBits +) +{ + t_uint64 tmp; + + /*write in scratch buffer first*/ + if (nbBits!=32) {tmp=((data)&((1<nbBitsValid-nbBits)); + pStream->buffer+=tmp; + pStream->nbBitsValid+=nbBits; + pStream->totalBitsWritten+=nbBits; + + /*try to write data into destination buffer*/ + while(pStream->nbBitsValid>=8) + { + HCL_ASSERT(pStream->currBuffer!=pStream->endBuffer); + + tmp=((pStream->buffer>>56)&0xff); + *pStream->currBuffer++=(t_uint8) tmp; + pStream->buffer=(pStream->buffer<<8); + pStream->nbBitsValid-=8; + } +} + +/****************************************************************************/ +/* NAME: void sva_EC_MP4_align( */ +/* t_sva_ec_mp4_write_stream *pStream */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will write one bits so that position is aligned on a */ +/* byte boundary. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - pStream: pointer that contain current state (INOUT). */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_ec_algo_error */ +/* t.b.d */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + * DONE +*/ +PRIVATE void sva_EC_MP4_align( + t_sva_ec_mp4_write_stream *pStream +) +{ + /* + * reference add first a zero bit stuf and then one bits + */ + + if (pStream->totalBitsWritten % 8 != 0) + { + sva_EC_MP4_writeBits(pStream,0,1); + } + + while(pStream->totalBitsWritten % 8 != 0) + { + sva_EC_MP4_writeBits(pStream,1,1); + } +} + +/****************************************************************************/ +/* NAME: t_sva_ec_algo_error sva_EC_MP4_flushWriteStream( */ +/* t_sva_ec_mp4_write_stream *pStream */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will insure that last bits are well written in */ +/* destination buffer. */ +/* PARAMETERS: */ +/* IN : */ +/* - pStream: pointer that contain current state (INOUT). */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_ec_algo_error */ +/* t.b.d */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + * DONE +*/ +PRIVATE t_sva_ec_algo_error sva_EC_MP4_flushWriteStream( + t_sva_ec_mp4_write_stream *pStream +) +{ + if (pStream->nbBitsValid!=0) + { + t_uint32 nbStuffBits=8-pStream->nbBitsValid; + + sva_EC_MP4_writeBits(pStream,0,nbStuffBits); + /*correct pStream->totalBitsWritten so it doesn't take into account padding bits*/ + pStream->totalBitsWritten-=nbStuffBits; + } + + return SVA_EC_ALGO_OK; +} + +/****************************************************************************/ +/* NAME: t_sva_ec_algo_error sva_EC_MP4_SH_UpdateVideoEncoderParams( */ +/* t_sva_service_instance_num instanceNum, */ +/* t_sva_update_cmd_type updateCmdType, */ +/* t_sva_video_encoder_param_id paramId, */ +/* t_uint32 param */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will update dynamic parameters for short header. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - instanceNum: number of the descriptor to use. */ +/* - updateCmdType: command to apply to the mp4 Encode */ +/* - paramId: Parameter to update */ +/* - param: parameter for the cmdType */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_ec_algo_error */ +/* t.b.d */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + * TO DO : all +*/ +PRIVATE t_sva_ec_algo_error sva_EC_MP4_SH_UpdateVideoEncoderParams( + t_sva_service_instance_num instanceNum, + t_sva_update_cmd_type updateCmdType, + t_sva_video_encoder_param_id paramId, + t_uint32 param +) +{ + t_sva_ec_mp4_descriptor *pDesc=&mp4EncodeDesc[instanceNum]; + t_sva_intra_request *pIntraRequest; + t_sva_ec_algo_error status = SVA_EC_ALGO_OK; + + /*take command into account for next configuration*/ + switch(paramId) + { + case SVA_ENCODER_FRAME_RATE: + pDesc->nextFrameRate = (t_uint16) param; + break; + case SVA_ENCODER_HEADER_FREQUENCY: + pDesc->mp4NextConf.gobHeaderFrequency = (t_uint16) param; + break; + case SVA_ENCODER_AIR_MB_NUM: + pDesc->mp4NextConf.airMbNum = (t_uint16) param; + break; + case SVA_ENCODER_CIR_PERIOD: + pDesc->mp4NextConf.cirPeriodMax = (t_uint16) param; + break; + case SVA_ENCODER_REQUEST_INTRA: + /*full intra picture refresh is handle in brc code*/ + pIntraRequest = (t_sva_intra_request *) param; + if (pIntraRequest->isIntraFullPicture == FALSE) + { + pDesc->isNextConfRequiredIntraResquest = TRUE; + pDesc->intraRequest = *pIntraRequest; + } + else {status = SVA_EC_MP4_CMD_NOT_SUPPORTED;} + break; + default: + status = SVA_EC_MP4_CMD_NOT_SUPPORTED; + break; + } + + return status; +} + +/****************************************************************************/ +/* NAME: t_sva_ec_algo_error sva_EC_MP4_SP_UpdateVideoEncoderParams( */ +/* t_sva_service_instance_num instanceNum, */ +/* t_sva_update_cmd_type updateCmdType, */ +/* t_sva_video_encoder_param_id paramId, */ +/* t_uint32 param */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will update dynamic parameters for simple profile. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - instanceNum: number of the descriptor to use. */ +/* - updateCmdType: command to apply to the mp4 Encode */ +/* - paramId: Parameter to update */ +/* - param: parameter for the cmdType */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_ec_algo_error */ +/* t.b.d */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + * TO DO : all +*/ +PRIVATE t_sva_ec_algo_error sva_EC_MP4_SP_UpdateVideoEncoderParams( + t_sva_service_instance_num instanceNum, + t_sva_update_cmd_type updateCmdType, + t_sva_video_encoder_param_id paramId, + t_uint32 param +) +{ + t_sva_ec_mp4_descriptor *pDesc=&mp4EncodeDesc[instanceNum]; + t_sva_intra_request *pIntraRequest; + t_sva_ec_algo_error status = SVA_EC_ALGO_OK; + t_sva_ec_mp4_packetsize_info *parameter; + + /*take command into account for next configuration*/ + switch(paramId) + { + case SVA_ENCODER_FRAME_RATE: + pDesc->nextFrameRate = (t_uint16) param; + break; + case SVA_ENCODER_HEADER_FREQUENCY: + pDesc->mp4NextConf.hecFreq = (t_uint16) param; + break; + case SVA_ENCODER_PACKET_SIZE: + pDesc->mp4NextConf.vpBitSize = (t_uint16) param; + break; + case SVA_ENCODER_PACKET_SIZE_INFO: + parameter=(t_sva_ec_mp4_packetsize_info *)param; + pDesc->mp4NextConf.vpBitSize = parameter->vpBitSize; + pDesc->mp4NextConf.vpMbSize = parameter->vpMbSize; + pDesc->mp4NextConf.vpSizeMax = parameter->vpSizeMax; + pDesc->mp4NextConf.vpSizeType = parameter->vpSizeType; + break; + case SVA_ENCODER_AIR_MB_NUM: + pDesc->mp4NextConf.airMbNum = (t_uint16) param; + break; + case SVA_ENCODER_CIR_PERIOD: + pDesc->mp4NextConf.cirPeriodMax = (t_uint16) param; + break; + case SVA_ENCODER_REQUEST_INTRA: + /*full intra picture refresh is handle in brc code*/ + pIntraRequest = (t_sva_intra_request *) param; + if (pIntraRequest->isIntraFullPicture == FALSE) + { + pDesc->isNextConfRequiredIntraResquest = TRUE; + pDesc->intraRequest = *pIntraRequest; + } + else {status = SVA_EC_MP4_CMD_NOT_SUPPORTED;} + break; + default: + status = SVA_EC_MP4_CMD_NOT_SUPPORTED; + break; + } + + return status; +} + +/****************************************************************************/ +/* NAME: t_sva_fw_features sva_EC_MP4_GetFeatures( */ +/* t_sva_service_instance_num instanceNum */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will return features need by mpeg4 algorithm. It will */ +/* also get brc features needed. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - instanceNum: number of the descriptor to use. */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_fw_features */ +/* features need by algo + brc */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_sva_fw_features sva_EC_MP4_GetFeatures( + t_sva_service_instance_num instanceNum +) +{ + t_sva_ec_mp4_descriptor *pDesc=&mp4EncodeDesc[instanceNum]; + t_sva_fw_features res; + + /* First get brc features need*/ + res = sva_EC_BRC_GetFeatures(instanceNum); + /* then add mpeg4 encoder features needs */ + if (pDesc->mp4Conf.flagShortHeader == TRUE) + { + res += SVA_FW_FEAT_MPEG4_SH_ENCODER; + } + else + { + res += SVA_FW_FEAT_MPEG4_SP_ENCODER; + } + /* if size is greater than qcif add SVA_FW_FEAT_MPEG4_DECODER_CIF_VGA */ + if (pDesc->conf.sourceFrameDesc.window.image.height > SVA_EC_MP4_QCIF_HEIGHT || + pDesc->conf.sourceFrameDesc.window.image.width > SVA_EC_MP4_QCIF_WIDTH) + { + res += SVA_FW_FEAT_MPEG4_DECODER_CIF_VGA; + } + /* if AIR or/and CIR features then ask them */ + if (pDesc->mp4Conf.irMode != SVA_AIR_DISABLED_CIR_DISABLED) + { + res += SVA_FW_FEAT_ENCODER_AIR_CIR; + } + + return res; +} + +/****************************************************************************/ +/* NAME: t_sva_ec_algo_error sva_EC_MP4_GenerateBitStreamDataUnits( */ +/* t_sva_service_instance_num instanceNum, */ +/* t_sva_data_unit_type data_unit_type */ +/* t_sva_data_unit_buffer *pOutBuf */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will generate the data requested data streams */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - instanceNum: number of the descriptor to use. */ +/* - data_unit_type: Type of data unit need to be generated */ +/* */ +/* OUT : */ +/* - data_out_buffer : Output buffer containing Data stream */ +/* */ +/* RETURN: */ +/* t_sva_ec_algo_error */ +/* t.b.d */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ + +PUBLIC t_sva_ec_algo_error sva_EC_MP4_GenerateBitStreamDataUnits(t_sva_service_instance_num instanceNum, + t_sva_data_unit_type data_unit_type, t_sva_data_unit_buffer *pOutBuf) +{ + HCL_ASSERT(pOutBuf->pOBuf != NULL); + /* TBD */ + /* This API is just to give compatibility with H264 encode APIs, will not be used for MPEG4 */ + return SVA_EC_ALGO_OK; +} + +/* End of file - sva_ec_mpeg4.c */ + --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/encode/mpeg4/sva_ec_mpeg4.h @@ -0,0 +1,69 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ + +#ifndef __INC_SVA_EC_MP4_H +#define __INC_SVA_EC_MP4_H + +#include "hcl_defs.h" +#include "sva_encode.h" +#include "../sva_ec_algo.h" +#include "sva.h" + +/******************************************************************************/ +/* Constants definitions */ +/******************************************************************************/ + + +/******************************************************************************/ +/* Types definitions */ +/******************************************************************************/ + + +/******************************************************************************/ +/* PUBLIC Functions */ +/******************************************************************************/ +PUBLIC t_sva_ec_algo_error sva_EC_MP4_AlgoInit(t_sva_service_instance_num,const t_sva_video_encoder_configuration *); +PUBLIC t_sva_ec_algo_error sva_EC_MP4_GetInternalNeeds(t_sva_service_instance_num, t_size *); +PUBLIC t_sva_ec_algo_error sva_EC_MP4_ProvideMemoryNeeds(t_sva_service_instance_num, const t_sva_tm_subtask_id *pSubtaskIdArray); +PUBLIC t_sva_ec_algo_error sva_EC_MP4_EncodeAlgoDelete(t_sva_service_instance_num); +PUBLIC t_sva_ec_algo_error sva_EC_MP4_UpdateVideoEncoderParams(t_sva_service_instance_num ,t_sva_update_cmd_type ,t_sva_video_encoder_param_id ,t_uint32); +PUBLIC t_sva_ec_algo_error sva_EC_MP4_PushImageInfo(t_sva_service_instance_num, const t_sva_ec_algo_image_info *); +PUBLIC t_sva_ec_algo_error sva_EC_MP4_GetNextFrameParamIn(t_sva_service_instance_num, t_sva_ec_algo_params_in *); +PUBLIC t_sva_ec_algo_error sva_EC_MP4_GetNextHeader(t_sva_service_instance_num, t_sva_ec_algo_header *, t_size *); +PUBLIC t_sva_ec_algo_error sva_EC_MP4_InitParamInOut(t_sva_service_instance_num, t_sva_ec_algo_params_inout *); +PUBLIC t_sva_ec_algo_error sva_EC_MP4_SetFrameParamOut(t_sva_service_instance_num, const t_sva_ec_algo_params_out *, const t_sva_ec_algo_params_inout *); +PUBLIC t_sva_ec_algo_error sva_EC_MP4_GetSkipInfo(t_sva_service_instance_num,t_bool *,t_bool *); +PUBLIC t_sva_ec_algo_error sva_EC_MP4_GetBitstreamSize(t_sva_service_instance_num, t_size *); +PUBLIC t_sva_ec_algo_error sva_EC_MP4_FillInfosBuffer(t_sva_service_instance_num, t_sva_buffer_id); +PUBLIC t_bool sva_EC_MP4_IsPreviousPictureWasStategicSkip(t_sva_service_instance_num); +PUBLIC t_size sva_EC_MP4_GetParamsInSize(t_sva_service_instance_num); +PUBLIC t_size sva_EC_MP4_GetParamsOutSize(t_sva_service_instance_num); +PUBLIC t_size sva_EC_MP4_GetParamsInOutSize(t_sva_service_instance_num); +PUBLIC t_size sva_EC_MP4_GetMaxHeaderSize(t_sva_service_instance_num); +PUBLIC t_sva_fw_features sva_EC_MP4_GetFeatures(t_sva_service_instance_num); +PUBLIC t_sva_ec_algo_error sva_EC_MP4_PatchBitstream(t_sva_service_instance_num ,const t_sva_ec_algo_params_in * ,t_logical_address); +PUBLIC t_sva_ec_algo_error sva_EC_MP4_GenerateBitStreamDataUnits(t_sva_service_instance_num instanceNum, + t_sva_data_unit_type data_unit_type, t_sva_data_unit_buffer *pOutBuf); + +#ifdef __cplusplus +} /* allow C++ to use these headers */ +#endif /* __cplusplus */ + +#endif /* __INC_SVA_EC_MP4_H */ +/* End of file - sva_ec_mpeg4.h */ --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/encode/mpeg4/sva_ec_mpeg4p.h @@ -0,0 +1,246 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ + +#ifndef __INC_SVA_EC_MP4P_H +#define __INC_SVA_EC_MP4P_H + +#include "hcl_defs.h" +#include "sva.h" +#include "sva_encode.h" +#include "../sva_ec_algo.h" +#include "../brc/sva_brc.h" + +/******************************************************************************/ +/* Constants definitions */ +/******************************************************************************/ +/* + * Define the maximum number of mp4 encode structure to maintain + */ +#define NUM_MAX_MP4_ENCODE 4 +/* + * Define the clockSlot value for short header in 90Khz value + */ +#define MP4_SH_CLOCK_SLOT (1001*90000/30000) + +/* + * Define the rounding value for temporal reference computation + */ +#define MP4_SH_ROUND_VALUE 1500 + +/* + * Define value for picture type + */ +#define SVA_MP4_I_PICTURE 0 +#define SVA_MP4_P_PICTURE 1 + +/* + * Define various configuration limits for mpeg4 encode SH or SP +*/ + /*define source frame limits*/ +#define SVA_EC_MP4_SOURCE_FRAME_HEIGHT_ALIGN 16 +#define SVA_EC_MP4_SOURCE_FRAME_HEIGHT_MIN 16 +#define SVA_EC_MP4_SOURCE_FRAME_HEIGHT_MAX 576//Euro-SDTV +#define SVA_EC_MP4_SOURCE_FRAME_WIDTH_ALIGN 16 +#define SVA_EC_MP4_SOURCE_FRAME_WIDTH_MIN 16 +#define SVA_EC_MP4_SOURCE_FRAME_WIDTH_MAX 720//Euro-SDTV + /*define cropping window limits*/ +#define SVA_EC_MP4_SOURCE_WINDOW_HEIGHT_ALIGN 16 +#define SVA_EC_MP4_SOURCE_WINDOW_HEIGHT_MIN 16 +#define SVA_EC_MP4_SOURCE_WINDOW_WIDTH_ALIGN 16 +#define SVA_EC_MP4_SOURCE_WINDOW_WIDTH_MIN 16 +#define SVA_EC_MP4_SOURCE_WINDOW_OFFSET_X_ALIGN 1 +#define SVA_EC_MP4_SOURCE_WINDOW_OFFSET_X_MIN 0 +#define SVA_EC_MP4_SOURCE_WINDOW_OFFSET_Y_ALIGN 1 +#define SVA_EC_MP4_SOURCE_WINDOW_OFFSET_Y_MIN 0 + /*define limits for partinioned*/ +#define SVA_EC_MP4_SOURCE_WINDOW_HEIGHT_PARTITIONED_MAX 288 +#define SVA_EC_MP4_SOURCE_WINDOW_WIDTH_PARTITIONED_MAX 352 + +/* + * Define supported size for MPEG4 short header mode. last two are custom mode +*/ +#define SVA_EC_MP4_SQCIF_WIDTH 128 +#define SVA_EC_MP4_SQCIF_HEIGHT 96 +#define SVA_EC_MP4_QCIF_WIDTH 176 +#define SVA_EC_MP4_QCIF_HEIGHT 144 +#define SVA_EC_MP4_CIF_WIDTH 352 +#define SVA_EC_MP4_CIF_HEIGHT 288 +#define SVA_EC_MP4_CIF4_WIDTH 704 +#define SVA_EC_MP4_CIF4_HEIGHT 576 +#define SVA_EC_MP4_CIF16_WIDTH 1408 +#define SVA_EC_MP4_CIF16_HEIGHT 1152 +#define SVA_EC_MP4_VGA_WIDTH 640 +#define SVA_EC_MP4_SDTV_HEIGHT 576 +#define SVA_EC_MP4_SDTV_WIDTH 720 +#define SVA_EC_MP4_VGA_HEIGHT 480 +#define SVA_EC_MP4_MB1_WIDTH 16 +#define SVA_EC_MP4_MB1_HEIGHT 16 + +/* + * Define supported size for MPEG4 short header mode. last two are custom mode +*/ +#define SVA_EC_MP4_SH_SOURCE_FORMAT_SQCIF 1 +#define SVA_EC_MP4_SH_SOURCE_FORMAT_QCIF 2 +#define SVA_EC_MP4_SH_SOURCE_FORMAT_CIF 3 +#define SVA_EC_MP4_SH_SOURCE_FORMAT_CIF4 4 +#define SVA_EC_MP4_SH_SOURCE_FORMAT_CIF16 5 +#define SVA_EC_MP4_SH_SOURCE_FORMAT_VGA 6 +#define SVA_EC_MP4_SH_SOURCE_FORMAT_MB1 7 + +/* + * Define vop constant to write in SP +*/ +#define SVA_MPEG4_VOS_START_CODE 0x000001b0 +#define SVA_MPEG4_VISUAL_OBJECT_START_CODE 0x000001b5 +#define SVA_MPEG4_VIDEO_OBJECT_TYPE 1 +#define SVA_MPEG4_VIDEO_OBJECT_START_CODE 0x00000100 +#define SVA_MPEG4_VOL_START_CODE 0x00000120 +#define SVA_MPEG4_SIMPLE_OBJECT_TYPE 1 +#define SVA_MPEG4_SQUARE_ASPECT_RATIO 1 +#define SVA_MPEG4_VBV_PRESENT 1 +#define SVA_MPEG4_NO_VBV_PRESENT 0 +#define SVA_MPEG4_CHROMA_4_2_0 1 +#define SVA_MPEG4_VIDEO_RECTANGULAR_SHAPE 0 + +#define SVA_MPEG4_VOP_START_CODE 0x000001b6 +#define SVA_MPEG4_VOP_CODING_TYPE_I 0 +#define SVA_MPEG4_VOP_CODING_TYPE_P 1 +#define SVA_MPEG4_MARKER_BIT 1 +#define SVA_MPEG4_VOP_CODED 1 +#define SVA_RTYPE_MODE_CONSTANT_ZERO 0 +#define SVA_RTYPE_MODE_CONSTANT_ONE 1 +#define SVA_MPEG4_INTRA_DC_VLC_THR 0 + +/* + * Define max header size in byte +*/ +#define SVA_EC_MP4_SH_MAX_HEADER_SIZE 6 + +#define SVA_EC_MP4_SP_MAX_HEADER_SIZE 56 + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ +/******************************************************************************/ +/* Types definitions */ +/******************************************************************************/ +/* + * Define the structure to handle bitstream write + */ +typedef struct { + /*scratch buffer handling*/ + t_uint64 buffer; + t_uint32 nbBitsValid; + /*destination buffer*/ + t_uint8 *currBuffer; + t_uint8 *endBuffer; + /*save total write bits*/ + t_uint32 totalBitsWritten; +} t_sva_ec_mp4_write_stream; + +/* + * Define the structure to handle temporal value + */ +typedef struct { + t_uint32 tr; + t_sint32 cumulTimeSlot; + t_uint32 slotDelay; +} t_sva_ec_mp4_sh_temporal; + +/* + * Define the structure to handle temporal value for SP + */ +typedef struct { + /*remain of previous division when convert diff from 90000 Hz to vopTimeIncrementResolution Hz*/ + t_uint32 remainForOffset; + /*temporal data value*/ + t_uint32 moduloTimeBase; + t_uint32 vopTimeIncrement; + /*save vopTimeIncrementBitSize*/ + t_uint32 vopTimeIncrementBitSize; +} t_sva_ec_mp4_sp_temporal; + +/* + * Define the type that keep all data need for skip fifo + */ + typedef struct { + t_sva_timestamp_value pts; + t_uint32 pictureNb; + t_uint16 roundValue; + /* short header specific */ + t_uint16 pictureCodingType; + t_sva_ec_mp4_sh_temporal temporalSh; + t_uint16 gobFrameId; + /* simple profile specific */ + t_sva_ec_mp4_sp_temporal temporalSp; +} t_sva_ec_save; + + +/* + * Define the descriptor of a mp4 encode instance + */ +typedef struct { + t_sva_video_encoder_configuration conf; + t_sva_video_encoder_algo_mpeg4_configuration_params mp4Conf; + t_bool isFlagIntraRequest; + /*dynamic conf change stuff*/ + t_sva_video_encoder_algo_mpeg4_configuration_params mp4NextConf; + t_uint16 frameRate; + t_uint16 nextFrameRate; + t_sva_intra_request intraRequest; + t_bool isNextConfRequiredIntraResquest; +#ifdef SVA_USE_GENERIC_ENCODER_INFOS + t_sva_video_encoder_infos *pInfos; +#else /* SVA_USE_GENERIC_ENCODER_INFOS */ + t_sva_video_encoder_mpeg4_infos *pInfos; +#endif /* SVA_USE_GENERIC_ENCODER_INFOS */ + t_sva_brc_user_request brcUserRequest; + t_sva_offset_desc croppingVector; + t_uint32 airThreshold; + /*simple profile sprecific stuff*/ + /*needed stuff to handle parly optimal TS*/ + t_bool isSnapshotNeeded; + t_uint32 saveVopTimeIncrement; + t_uint32 saveRemainForOffset; + /*brc data*/ + t_sva_brc_out brcOut; + /*skip infos from last encoded picture*/ + t_bool isCurrentItSkip; + t_bool isCurrentStrategicSkip; + /*bitstream size in bits with stuffing bits*/ + t_size bitstreamSizeBits; + /*specific stuff need for vbv_occupancy fixing in vol header*/ + t_uint16 pictureCodingType[2]; + t_uint16 ptrRd; + t_uint16 ptrWr; + t_bool isFirstPicture; + t_size previousBitstreamSize; + /*current state*/ + t_sva_ec_save current; + /*fifo that keep save data need in case of skip*/ + t_sva_ec_save skipFifo[3]; +} t_sva_ec_mp4_descriptor; + +#ifdef __cplusplus +} /* allow C++ to use these headers */ +#endif /* __cplusplus */ + +#endif /* __INC_SVA_EC_MP4P_H */ +/* End of file - sva_ec_mpeg4p.h */ + --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/encode/sva_ec_algo.h @@ -0,0 +1,187 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ + +#ifndef __INC_SVA_EC_ALGO_H +#define __INC_SVA_EC_ALGO_H + +#include "hcl_defs.h" +#include "sva.h" +#include "sva_service.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/******************************************************************************/ +/* Constants definitions */ +/******************************************************************************/ + +/******************************************************************************/ +/* Types definitions */ +/******************************************************************************/ +/* + * Define image information give to algo + */ +typedef struct { + t_sva_timestamp pts; + t_sva_offset_desc croppingVector; + t_sva_brc_user_request brcUserRequest; +} t_sva_ec_algo_image_info; + +/* + * Define list of algorithm supported by video encode + */ +typedef enum { + SVA_EC_ALGO_MPEG4 = 0, + SVA_EC_ALGO_H264 = 1, + SVA_EC_ALGO_NB +}t_sva_ec_algo; + +/* + * Define algorithm errors + */ +typedef enum { + SVA_EC_MP4_XXXX = SVA_EC_MP4_LAST_ERROR, + SVA_EC_MP4_FIFO_LINKED_ERROR, + SVA_EC_MP4_FIFO_FULL_ERROR, + SVA_EC_MP4_BRC_ERROR, + SVA_EC_MP4_PARAM_ERROR, + SVA_EC_MP4_CMD_NOT_SUPPORTED, + SVA_EC_MP4_INTERNAL_ERROR, + SVA_EC_MP4_YYYY, + SVA_EC_H263_XXXX = SVA_EC_H263_LAST_ERROR, + SVA_EC_H263_YYYY, + SVA_EC_H264_XXXX = SVA_EC_H264_LAST_ERROR, + SVA_EC_H264_FIFO_LINKED_ERROR, + SVA_EC_H264_FIFO_FULL_ERROR, + SVA_EC_H264_BRC_ERROR, + SVA_EC_H264_PARAM_ERROR, + SVA_EC_H264_CMD_NOT_SUPPORTED, + SVA_EC_H264_INTERNAL_ERROR, + SVA_EC_H264_YYYY, + SVA_EC_H264_OP_FILE_ERROR, + SVA_EC_ALGO_OK = HCL_OK +} t_sva_ec_algo_error; + +/* + * Define various type for exchanging info + */ +typedef void t_sva_ec_algo_params_in; +typedef void t_sva_ec_algo_params_inout; +typedef void t_sva_ec_algo_params_out; +typedef void t_sva_ec_algo_header; + +typedef struct{ + /* + * Init algo part for an instance. Also check and save configuration. + */ + t_sva_ec_algo_error (*pAlgoInit)(t_sva_service_instance_num,const t_sva_video_encoder_configuration *); + /* + * Get cachable memory size need by algo part. + */ + t_sva_ec_algo_error (*pGetInternalNeeds)(t_sva_service_instance_num, t_size *); + /* + * Cachable have been provide by user and can be use by algo + */ +//\/ t_sva_ec_algo_error (*pProvideMemoryNeeds)(t_sva_service_instance_num); + t_sva_ec_algo_error (*pProvideMemoryNeeds) (t_sva_service_instance_num, const t_sva_tm_subtask_id *); + /* + * Give a chance to algo box to free memory use + */ + t_sva_ec_algo_error (*pEncodeAlgoDelete)(t_sva_service_instance_num); + /* + * Update video encoder parameter on the fly + */ + t_sva_ec_algo_error (*pUpdateVideoEncoderParams)(t_sva_service_instance_num ,t_sva_update_cmd_type ,t_sva_video_encoder_param_id ,t_uint32); + + /* + * Push some information to algo box about image. This API MUST be called just before + * getting paramin/header fields. + */ + t_sva_ec_algo_error (*pPushImageInfo) (t_sva_service_instance_num, const t_sva_ec_algo_image_info *); + /* + * Shall be call to fill paramin structure. Must be call before calling pGetNextHeader API + */ + t_sva_ec_algo_error (*pGetNextFrameParamIn) (t_sva_service_instance_num, t_sva_ec_algo_params_in *); + /* + * Shall be call to fill header structure + */ + t_sva_ec_algo_error (*pGetNextHeader) (t_sva_service_instance_num, t_sva_ec_algo_header *, t_size *); + /* + * Shall be call at init to fill initial value of inout structure + */ + t_sva_ec_algo_error (*pInitParamInOut) (t_sva_service_instance_num, t_sva_ec_algo_params_inout *); + /* + * This function allows to transmit the output params data to algo box. This include out and + * output of inout. + */ + t_sva_ec_algo_error (*pSetFrameParamOut) (t_sva_service_instance_num, const t_sva_ec_algo_params_out *, const t_sva_ec_algo_params_inout *); + /* + * This function allows to retriewe skip info after a subtask finish. It must be call after + * pSetFrameParamOut() + */ + t_sva_ec_algo_error (*pGetSkipInfo) (t_sva_service_instance_num,t_bool *,t_bool *); + /* + * This function allows to retriewe bitstream size info after a subtask finish. It must be call after + * pSetFrameParamOut() + */ + t_sva_ec_algo_error (*pGetBitstreamSize)(t_sva_service_instance_num, t_size *); + /* + * This function will give to the user a possiblity to patch generated bitstream. + * Today following use case are : + * - patch vbv_occupancy of vol header since it need size of previous picture. + */ + t_sva_ec_algo_error (*pPachBitstream)(t_sva_service_instance_num, const t_sva_ec_algo_params_in *, t_logical_address); + /* + * This function will fill info buffer after a subtask finish. It must be call after + * pSetFrameParamOut() + */ + t_sva_ec_algo_error (*pFillInfosBuffer)(t_sva_service_instance_num, t_sva_buffer_id); + /* + * This function must be call before trying to solve subtask dependencies. It allow + * subtask to be programmed to know if the previous picture was strategic skipped. This + * allow to choose buffer that need to be use for current subtask. + */ + t_bool (*pIsPreviousPictureWasStategicSkip)(t_sva_service_instance_num); + /* + * functions to know size of param in/inout/out. all are static, so call them once + * return size is in bytes + */ + t_size (*pGetParamsInSize) (t_sva_service_instance_num); + t_size (*pGetParamsOutSize) (t_sva_service_instance_num); + t_size (*pGetParamsInOutSize) (t_sva_service_instance_num); + t_size (*pGetMaxHeaderSize) (t_sva_service_instance_num); + /* + * functions to know features need by algo. Note that algo part must call equivalent + * brc API to add brc features need. + */ + t_sva_fw_features (*pGetFeatures) (t_sva_service_instance_num); + /* + * Generate SPS and PPS Non VCL NAL Units //\/ Changes by Sarvesh for H264 Encode + */ + t_sva_ec_algo_error (*pGenerateBitStreamDataUnits)(t_sva_service_instance_num , t_sva_data_unit_type, t_sva_data_unit_buffer *); + +} t_sva_algo_encode_fct_array; + +#ifdef __cplusplus +} /* allow C++ to use these headers */ +#endif /* __cplusplus */ + +#endif /* __INC_SVA_EC_ALGO_H */ +/* End of file - sva_ec_algo.h */ --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/encode/sva_encode.c @@ -0,0 +1,4594 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ +/*------------------------------------------------------------------------ + * Includes + *----------------------------------------------------------------------*/ +#include "hcl_defs.h" +#include "sva_encode.h" +#include "sva_encodep.h" +#include "sva_eventmgt.h" +#include "sva_ec_algo.h" +#include "mpeg4/sva_ec_mpeg4.h" +#include "h264/sva_ec_h264.h" + +/*------------------------------------------------------------------------ + * TODO : + * - + * - mainly in dispatch + * - flush implementation today must only be call before a delete + * => due to algo/brc coherency (need more api ...) + * - STREAM mode + * - check if sva_EC_GetParamsBufferSize() API has to return zero + * when param is not use. + *----------------------------------------------------------------------*/ + +/*------------------------------------------------------------------------ + * Private macro + *----------------------------------------------------------------------*/ +//#define NB_SUPPORTED_ENCODER_TRANSFORMS 5 +#define IS_DEPENDENCY_SOLVED(a) ((a==RESOLVED_INTERNAL_DEPENDENCY || a==RESOLVED_DEPENDENCY)?TRUE:FALSE) +#define SOLVE_DEPENDENCY(a) (t_sva_ec_dependencies_state)((a==NOT_RESOLVED_DEPENDENCY)?RESOLVED_DEPENDENCY:RESOLVED_INTERNAL_DEPENDENCY) + +/*------------------------------------------------------------------------ + * Global Variables + *----------------------------------------------------------------------*/ + #ifdef __DEBUG +ALIGN(32) PRIVATE t_sva_ec_debug_events eventEncodeDebugTable[NUM_MAX_ENCODE]; +ALIGN(32) PRIVATE t_sva_ec_debug_commands commandEncodeDebugTable[NUM_MAX_ENCODE]; +ALIGN(32) PRIVATE t_sva_ec_debug_transitions transitionEncodeDebugTable[NUM_MAX_ENCODE]; +#endif +/*instance descriptors*/ +PRIVATE t_sva_ec_descriptor encodeDesc[NUM_MAX_ENCODE]; + +/*table that translate transform id into an encode subtask type*/ +PRIVATE const t_sva_tm_subtask_type algo_2_subtask_type[SVA_EC_ALGO_NB]={ + SVA_TM_ENCODE_MPEG4_SW, SVA_TM_ENCODE_H264}; + +/*table that describe memory allocation for encode*/ +/* param_in / param_out and param_inout structure size are + * filled later on when requested needed size to algo part. +*/ +PRIVATE const t_sva_tm_field_ctrl_desc defaultEncodeFieldDescArray[ENCODE_FIELD_NUMBER]={ + { SVA_TM_DCMD_ALLOCATE, {{sizeof(t_sva_vec_frame_buffer_in), ENCODE_DEFAULT_INFOS_MEMORY_ID}}}, + { SVA_TM_DCMD_ALLOCATE, {{sizeof(t_sva_vec_frame_buffer_out), ENCODE_DEFAULT_INFOS_MEMORY_ID}}}, + { SVA_TM_DCMD_ALLOCATE, {{sizeof(t_sva_vec_internal_buffer), ENCODE_DEFAULT_INFOS_MEMORY_ID}}}, + { SVA_TM_DCMD_ALLOCATE, {{sizeof(t_sva_header_buf), ENCODE_DEFAULT_INFOS_MEMORY_ID}}}, + { SVA_TM_DCMD_ALLOCATE, {{sizeof(t_sva_bitstream_buffer_pos), ENCODE_DEFAULT_INFOS_MEMORY_ID}}}, + { SVA_TM_DCMD_ALLOCATE, {{sizeof(t_sva_bitstream_buffer_pos), ENCODE_DEFAULT_INFOS_MEMORY_ID}}}, + { SVA_TM_DCMD_ALLOCATE, {{0, ENCODE_DEFAULT_INFOS_MEMORY_ID}}}, + { SVA_TM_DCMD_ALLOCATE, {{0, ENCODE_DEFAULT_INFOS_MEMORY_ID}}}, + { SVA_TM_DCMD_ALLOCATE, {{0, ENCODE_DEFAULT_INFOS_MEMORY_ID}}}, + { SVA_TM_DCMD_NULL, {{0, ENCODE_DEFAULT_INFOS_MEMORY_ID}}} +}; + +/*algorithmics plugins*/ +PRIVATE t_sva_algo_encode_fct_array encodeAlgoDesc[SVA_EC_ALGO_NB]={ +//MPEG4 +{ + sva_EC_MP4_AlgoInit, + sva_EC_MP4_GetInternalNeeds, + sva_EC_MP4_ProvideMemoryNeeds, + sva_EC_MP4_EncodeAlgoDelete, + sva_EC_MP4_UpdateVideoEncoderParams, + sva_EC_MP4_PushImageInfo, + sva_EC_MP4_GetNextFrameParamIn, + sva_EC_MP4_GetNextHeader, + sva_EC_MP4_InitParamInOut, + sva_EC_MP4_SetFrameParamOut, + sva_EC_MP4_GetSkipInfo, + sva_EC_MP4_GetBitstreamSize, + sva_EC_MP4_PatchBitstream, + sva_EC_MP4_FillInfosBuffer, + sva_EC_MP4_IsPreviousPictureWasStategicSkip, + sva_EC_MP4_GetParamsInSize, + sva_EC_MP4_GetParamsOutSize, + sva_EC_MP4_GetParamsInOutSize, + sva_EC_MP4_GetMaxHeaderSize, + sva_EC_MP4_GetFeatures, + sva_EC_MP4_GenerateBitStreamDataUnits //\/ Changes by Sarvesh for H264 Encode +}, +//H264 +{ + sva_EC_H264_AlgoInit, + sva_EC_H264_GetInternalNeeds, + sva_EC_H264_ProvideMemoryNeeds, + sva_EC_H264_EncodeAlgoDelete, + sva_EC_H264_UpdateVideoEncoderParams, + sva_EC_H264_PushImageInfo, + sva_EC_H264_GetNextFrameParamIn, + sva_EC_H264_GetNextHeader, + sva_EC_H264_InitParamInOut, + sva_EC_H264_SetFrameParamOut, + sva_EC_H264_GetSkipInfo, + sva_EC_H264_GetBitstreamSize, + sva_EC_H264_PatchBitstream, + sva_EC_H264_FillInfosBuffer, + sva_EC_H264_IsPreviousPictureWasStategicSkip, + sva_EC_H264_GetParamsInSize, + sva_EC_H264_GetParamsOutSize, + sva_EC_H264_GetParamsInOutSize, + sva_EC_H264_GetMaxHeaderSize, + sva_EC_H264_GetFeatures, + sva_EC_H264_GenerateBitStreamDataUnits //\/ Changes by Sarvesh for H264 Encode +} +}; + +/*table that translate encode state into service state*/ +PRIVATE const t_sva_service_state encodeState2ServiceState[SVA_EC_LAST_DUMMY_STATE]= { + SVA_SERVICE_NOT_INITIALIZED, /*SVA_EC_NOT_INITIALIZED*/ + SVA_SERVICE_WAIT_FOR_CONFIGURATION, /*SVA_EC_WAIT_FOR_CONFIGURATION*/ + SVA_SERVICE_WAIT_FOR_INTERNAL_NEEDS, /*SVA_EC_WAIT_FOR_INTERNAL_NEEDS*/ + SVA_SERVICE_WAIT_FOR_ACTIVATE, /*SVA_EC_WAIT_FOR_ACTIVATE*/ + SVA_SERVICE_WAIT_FOR_START, /*SVA_EC_WAIT_FOR_START*/ + SVA_SERVICE_FLUSHING, /*SVA_EC_FLUSHING_IN*/ + SVA_SERVICE_FLUSHING, /*SVA_EC_FLUSHING_OUT*/ + SVA_SERVICE_WAIT_FOR_DATA, /*SVA_EC_WAIT_FOR_DATA*/ + SVA_SERVICE_RUNNING, /*SVA_EC_RUNNING*/ + SVA_SERVICE_ABORT_REQUESTED, /*SVA_EC_ABORT_REQUESTED*/ + SVA_SERVICE_STOP_REQUESTED, /*SVA_EC_STOP_REQUESTED*/ + SVA_SERVICE_ERROR /*SVA_EC_ERROR*/ +}; + +/*main state machine description*/ +PRIVATE const t_sva_ec_state stateMachine[SVA_EC_LAST_DUMMY_STATE][SVA_EC_LAST_DUMMY_TRANSITION]= { + /* Current State = SVA_EC_NOT_INITIALIZED */ + { + SVA_EC_WAIT_FOR_CONFIGURATION, /*SVA_EC_CREATE*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_CONFIGURE*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_INTERNAL_NEEDS*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_ACTIVATE*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_INACTIVATE*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_CONTROL_START*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_CONTROL_STOP*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_CONTROL_ABORT*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_ALL_DEPENDENCIES_RESOLVED*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_PUSH*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_EVENT_EOK*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_EVENT_FAKE*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_EVENT_ACTIVE*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_EVENT_INACTIVE*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_RESET*/ + SVA_EC_NOT_INITIALIZED, /*SVA_EC_CONTROL_DELETE*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_EVENT_ERROR*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_FLUSH_IN*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_FLUSH_OUT*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_CANCEL*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_UPDATE_PARAM*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_GET_PARAM_SIZE*/ + SVA_EC_TRANSITION_REJECTED /* SVA_EC_GEN_DATA_UNIT */ + }, + /* Current State = SVA_EC_WAIT_FOR_CONFIGURATION */ + { + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_CREATE*/ + SVA_EC_WAIT_FOR_INTERNAL_NEEDS, /*SVA_EC_CONFIGURE*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_INTERNAL_NEEDS*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_ACTIVATE*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_INACTIVATE*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_CONTROL_START*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_CONTROL_STOP*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_CONTROL_ABORT*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_ALL_DEPENDENCIES_RESOLVED*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_PUSH*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_EVENT_EOK*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_EVENT_FAKE*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_EVENT_ACTIVE*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_EVENT_INACTIVE*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_RESET*/ + SVA_EC_NOT_INITIALIZED, /*SVA_EC_CONTROL_DELETE*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_EVENT_ERROR*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_FLUSH_IN*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_FLUSH_OUT*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_CANCEL*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_UPDATE_PARAM*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_GET_PARAM_SIZE*/ + SVA_EC_TRANSITION_REJECTED /* SVA_EC_GEN_DATA_UNIT */ + }, + /* Current State = SVA_EC_WAIT_FOR_INTERNAL_NEEDS */ + { + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_CREATE*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_CONFIGURE*/ + SVA_EC_WAIT_FOR_ACTIVATE, /*SVA_EC_INTERNAL_NEEDS*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_ACTIVATE*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_INACTIVATE*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_CONTROL_START*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_CONTROL_STOP*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_CONTROL_ABORT*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_ALL_DEPENDENCIES_RESOLVED*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_PUSH*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_EVENT_EOK*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_EVENT_FAKE*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_EVENT_ACTIVE*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_EVENT_INACTIVE*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_RESET*/ + SVA_EC_NOT_INITIALIZED, /*SVA_EC_CONTROL_DELETE*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_EVENT_ERROR*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_FLUSH_IN*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_FLUSH_OUT*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_CANCEL*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_UPDATE_PARAM*/ + SVA_EC_WAIT_FOR_INTERNAL_NEEDS, /*SVA_EC_GET_PARAM_SIZE*/ + SVA_EC_WAIT_FOR_INTERNAL_NEEDS /* SVA_EC_GEN_DATA_UNIT */ + }, + /* Current State = SVA_EC_WAIT_FOR_ACTIVATE */ + { + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_CREATE*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_CONFIGURE*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_INTERNAL_NEEDS*/ + SVA_EC_WAIT_FOR_ACTIVATE, /*SVA_EC_ACTIVATE*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_INACTIVATE*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_CONTROL_START*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_CONTROL_STOP*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_CONTROL_ABORT*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_ALL_DEPENDENCIES_RESOLVED*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_PUSH*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_EVENT_EOK*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_EVENT_FAKE*/ + SVA_EC_WAIT_FOR_START, /*SVA_EC_EVENT_ACTIVE*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_EVENT_INACTIVE*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_RESET*/ + SVA_EC_NOT_INITIALIZED, /*SVA_EC_CONTROL_DELETE*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_EVENT_ERROR*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_FLUSH_IN*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_FLUSH_OUT*/ + SVA_EC_WAIT_FOR_ACTIVATE, /*SVA_EC_CANCEL*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_UPDATE_PARAM*/ + SVA_EC_WAIT_FOR_ACTIVATE, /*SVA_EC_GET_PARAM_SIZE*/ + SVA_EC_WAIT_FOR_ACTIVATE /* SVA_EC_GEN_DATA_UNIT */ + }, + /* Current State = SVA_EC_WAIT_FOR_START */ + { + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_CREATE*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_CONFIGURE*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_INTERNAL_NEEDS*/ + SVA_EC_WAIT_FOR_START, /*SVA_EC_ACTIVATE*/ + SVA_EC_WAIT_FOR_START, /*SVA_EC_INACTIVATE*/ + SVA_EC_WAIT_FOR_DATA, /*SVA_EC_CONTROL_START*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_CONTROL_STOP*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_CONTROL_ABORT*/ + SVA_EC_WAIT_FOR_START, /*SVA_EC_ALL_DEPENDENCIES_RESOLVED*/ + SVA_EC_WAIT_FOR_START, /*SVA_EC_PUSH*/ + SVA_EC_ERROR, /*SVA_EC_EVENT_EOK*/ + SVA_EC_ERROR, /*SVA_EC_EVENT_FAKE*/ + SVA_EC_WAIT_FOR_START, /*SVA_EC_EVENT_ACTIVE*/ + SVA_EC_WAIT_FOR_START, /*SVA_EC_EVENT_INACTIVE*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_RESET*/ + SVA_EC_NOT_INITIALIZED, /*SVA_EC_CONTROL_DELETE*/ + SVA_EC_ERROR, /*SVA_EC_EVENT_ERROR*/ + SVA_EC_FLUSHING_IN, /*SVA_EC_FLUSH_IN*/ + SVA_EC_FLUSHING_OUT, /*SVA_EC_FLUSH_OUT*/ + SVA_EC_WAIT_FOR_START, /*SVA_EC_CANCEL*/ + SVA_EC_WAIT_FOR_START, /*SVA_EC_UPDATE_PARAM*/ + SVA_EC_WAIT_FOR_START, /*SVA_EC_GET_PARAM_SIZE*/ + SVA_EC_WAIT_FOR_START /* SVA_EC_GEN_DATA_UNIT */ + }, + /* Current State = SVA_EC_FLUSHING_IN */ + { + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_CREATE*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_CONFIGURE*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_INTERNAL_NEEDS*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_ACTIVATE*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_INACTIVATE*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_CONTROL_START*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_CONTROL_STOP*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_CONTROL_ABORT*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_ALL_DEPENDENCIES_RESOLVED*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_PUSH*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_EVENT_EOK*/ + SVA_EC_WAIT_FOR_START, /*SVA_EC_EVENT_FAKE*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_EVENT_ACTIVE*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_EVENT_INACTIVE*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_RESET*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_CONTROL_DELETE*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_EVENT_ERROR*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_FLUSH_IN*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_FLUSH_OUT*/ + SVA_EC_FLUSHING_IN, /*SVA_EC_CANCEL*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_UPDATE_PARAM*/ + SVA_EC_FLUSHING_IN, /*SVA_EC_GET_PARAM_SIZE*/ + SVA_EC_FLUSHING_IN /* SVA_EC_GEN_DATA_UNIT */ + }, + /* Current State = SVA_EC_FLUSHING_OUT */ + { + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_CREATE*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_CONFIGURE*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_INTERNAL_NEEDS*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_ACTIVATE*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_INACTIVATE*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_CONTROL_START*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_CONTROL_STOP*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_CONTROL_ABORT*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_ALL_DEPENDENCIES_RESOLVED*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_PUSH*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_EVENT_EOK*/ + SVA_EC_WAIT_FOR_START, /*SVA_EC_EVENT_FAKE*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_EVENT_ACTIVE*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_EVENT_INACTIVE*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_RESET*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_CONTROL_DELETE*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_EVENT_ERROR*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_FLUSH_IN*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_FLUSH_OUT*/ + SVA_EC_FLUSHING_OUT, /*SVA_EC_CANCEL*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_UPDATE_PARAM*/ + SVA_EC_FLUSHING_OUT, /*SVA_EC_GET_PARAM_SIZE*/ + SVA_EC_FLUSHING_OUT /* SVA_EC_GEN_DATA_UNIT */ + }, + /* Current State = SVA_EC_WAIT_FOR_DATA */ + { + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_CREATE*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_CONFIGURE*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_INTERNAL_NEEDS*/ + SVA_EC_WAIT_FOR_DATA, /*SVA_EC_ACTIVATE*/ + SVA_EC_WAIT_FOR_DATA, /*SVA_EC_INACTIVATE*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_CONTROL_START*/ + SVA_EC_STOP_REQUESTED, /*SVA_EC_CONTROL_STOP*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_CONTROL_ABORT*/ + SVA_EC_RUNNING, /*SVA_EC_ALL_DEPENDENCIES_RESOLVED*/ + SVA_EC_WAIT_FOR_DATA, /*SVA_EC_PUSH*/ + SVA_EC_ERROR, /*SVA_EC_EVENT_EOK*/ + SVA_EC_ERROR, /*SVA_EC_EVENT_FAKE*/ + SVA_EC_WAIT_FOR_DATA, /*SVA_EC_EVENT_ACTIVE*/ + SVA_EC_WAIT_FOR_DATA, /*SVA_EC_EVENT_INACTIVE*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_RESET*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_CONTROL_DELETE*/ + SVA_EC_ERROR, /*SVA_EC_EVENT_ERROR*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_FLUSH_IN*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_FLUSH_OUT*/ + SVA_EC_WAIT_FOR_DATA, /*SVA_EC_CANCEL*/ + SVA_EC_WAIT_FOR_DATA, /*SVA_EC_UPDATE_PARAM*/ + SVA_EC_WAIT_FOR_DATA, /*SVA_EC_GET_PARAM_SIZE*/ + SVA_EC_WAIT_FOR_DATA /* SVA_EC_GEN_DATA_UNIT */ + }, + /* Current State = SVA_EC_RUNNING */ + { + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_CREATE*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_CONFIGURE*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_INTERNAL_NEEDS*/ + SVA_EC_RUNNING, /*SVA_EC_ACTIVATE*/ + SVA_EC_RUNNING, /*SVA_EC_INACTIVATE*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_CONTROL_START*/ + SVA_EC_STOP_REQUESTED, /*SVA_EC_CONTROL_STOP*/ + SVA_EC_ABORT_REQUESTED, /*SVA_EC_CONTROL_ABORT*/ + SVA_EC_RUNNING, /*SVA_EC_ALL_DEPENDENCIES_RESOLVED*/ + SVA_EC_RUNNING, /*SVA_EC_PUSH*/ + SVA_EC_WAIT_FOR_DATA, /*SVA_EC_EVENT_EOK*/ + SVA_EC_ERROR, /*SVA_EC_EVENT_FAKE*/ + SVA_EC_RUNNING, /*SVA_EC_EVENT_ACTIVE*/ + SVA_EC_RUNNING, /*SVA_EC_EVENT_INACTIVE*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_RESET*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_CONTROL_DELETE*/ + SVA_EC_ERROR, /*SVA_EC_EVENT_ERROR*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_FLUSH_IN*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_FLUSH_OUT*/ + SVA_EC_RUNNING, /*SVA_EC_CANCEL*/ + SVA_EC_RUNNING, /*SVA_EC_UPDATE_PARAM*/ + SVA_EC_RUNNING, /*SVA_EC_GET_PARAM_SIZE*/ + SVA_EC_RUNNING /* SVA_EC_GEN_DATA_UNIT */ + }, + /* Current State = SVA_EC_ABORT_REQUESTED */ + { + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_CREATE*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_CONFIGURE*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_INTERNAL_NEEDS*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_ACTIVATE*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_INACTIVATE*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_CONTROL_START*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_CONTROL_STOP*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_CONTROL_ABORT*/ + SVA_EC_ABORT_REQUESTED, /*SVA_EC_ALL_DEPENDENCIES_RESOLVED*/ + SVA_EC_ABORT_REQUESTED, /*SVA_EC_PUSH*/ + SVA_EC_ERROR, /*SVA_EC_EVENT_EOK*/ + SVA_EC_ERROR, /*SVA_EC_EVENT_FAKE*/ + SVA_EC_ERROR, /*SVA_EC_EVENT_ACTIVE*/ + SVA_EC_ERROR, /*SVA_EC_EVENT_INACTIVE*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_RESET*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_CONTROL_DELETE*/ + SVA_EC_ERROR, /*SVA_EC_EVENT_ERROR*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_FLUSH_IN*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_FLUSH_OUT*/ + SVA_EC_ABORT_REQUESTED, /*SVA_EC_CANCEL*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_UPDATE_PARAM*/ + SVA_EC_ABORT_REQUESTED, /*SVA_EC_GET_PARAM_SIZE*/ + SVA_EC_ABORT_REQUESTED /* SVA_EC_GEN_DATA_UNIT */ + }, + /* Current State = SVA_EC_STOP_REQUESTED */ + { + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_CREATE*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_CONFIGURE*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_INTERNAL_NEEDS*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_ACTIVATE*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_INACTIVATE*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_CONTROL_START*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_CONTROL_STOP*/ + SVA_EC_ABORT_REQUESTED, /*SVA_EC_CONTROL_ABORT*/ + SVA_EC_STOP_REQUESTED, /*SVA_EC_ALL_DEPENDENCIES_RESOLVED*/ + SVA_EC_STOP_REQUESTED, /*SVA_EC_PUSH*/ + SVA_EC_WAIT_FOR_START, /*SVA_EC_EVENT_EOK*/ + SVA_EC_ERROR, /*SVA_EC_EVENT_FAKE*/ + SVA_EC_ERROR, /*SVA_EC_EVENT_ACTIVE*/ + SVA_EC_ERROR, /*SVA_EC_EVENT_INACTIVE*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_RESET*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_CONTROL_DELETE*/ + SVA_EC_ERROR, /*SVA_EC_EVENT_ERROR*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_FLUSH_IN*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_FLUSH_OUT*/ + SVA_EC_STOP_REQUESTED, /*SVA_EC_CANCEL*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_UPDATE_PARAM*/ + SVA_EC_STOP_REQUESTED, /*SVA_EC_GET_PARAM_SIZE*/ + SVA_EC_STOP_REQUESTED /* SVA_EC_GEN_DATA_UNIT */ + }, + /* Current State = SVA_EC_ERROR */ + { + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_CREATE*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_CONFIGURE*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_INTERNAL_NEEDS*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_ACTIVATE*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_INACTIVATE*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_CONTROL_START*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_CONTROL_STOP*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_CONTROL_ABORT*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_ALL_DEPENDENCIES_RESOLVED*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_PUSH*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_EVENT_EOK*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_EVENT_FAKE*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_EVENT_ACTIVE*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_EVENT_INACTIVE*/ + SVA_EC_WAIT_FOR_START, /*SVA_EC_RESET*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_CONTROL_DELETE*/ + SVA_EC_ERROR, /*SVA_EC_EVENT_ERROR*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_FLUSH_IN*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_FLUSH_OUT*/ + SVA_EC_ERROR, /*SVA_EC_CANCEL*/ + SVA_EC_TRANSITION_REJECTED, /*SVA_EC_UPDATE_PARAM*/ + SVA_EC_ERROR, /*SVA_EC_GET_PARAM_SIZE*/ + SVA_EC_ERROR /* SVA_EC_GEN_DATA_UNIT */ + } +}; + +/*activate state machine description*/ +PRIVATE const t_sva_ec_activate_state activateStateMachine[SVA_EC_LAST_ACTIVATE_DUMMY_STATE][SVA_EC_LAST_DUMMY_TRANSITION]= { + /* Current State = SVA_EC_INACTIVE */ + { + SVA_EC_INACTIVE, /*SVA_EC_CREATE*/ + SVA_EC_INACTIVE, /*SVA_EC_CONFIGURE*/ + SVA_EC_INACTIVE, /*SVA_EC_INTERNAL_NEEDS*/ + SVA_EC_IN_ACTIVATION, /*SVA_EC_ACTIVATE*/ + SVA_EC_ACTIVATE_TRANSITION_REJECTED, /*SVA_EC_INACTIVATE*/ + SVA_EC_ACTIVATE_TRANSITION_REJECTED, /*SVA_EC_CONTROL_START*/ + SVA_EC_ACTIVATE_TRANSITION_REJECTED, /*SVA_EC_CONTROL_STOP*/ + SVA_EC_ACTIVATE_TRANSITION_REJECTED, /*SVA_EC_CONTROL_ABORT*/ + SVA_EC_INACTIVE, /*SVA_EC_ALL_DEPENDENCIES_RESOLVED*/ + SVA_EC_INACTIVE, /*SVA_EC_PUSH*/ + SVA_EC_INACTIVE, /*SVA_EC_EVENT_EOK*/ + SVA_EC_INACTIVE, /*SVA_EC_EVENT_FAKE*/ + SVA_EC_INACTIVE, /*SVA_EC_EVENT_ACTIVE*/ + SVA_EC_INACTIVE, /*SVA_EC_EVENT_INACTIVE*/ + SVA_EC_INACTIVE, /*SVA_EC_RESET*/ + SVA_EC_INACTIVE, /*SVA_EC_CONTROL_DELETE*/ + SVA_EC_INACTIVE, /*SVA_EC_EVENT_ERROR*/ + SVA_EC_INACTIVE, /*SVA_EC_FLUSH_IN*/ + SVA_EC_INACTIVE, /*SVA_EC_FLUSH_OUT*/ + SVA_EC_ACTIVATE_TRANSITION_REJECTED, /*SVA_EC_CANCEL*/ + SVA_EC_INACTIVE, /*SVA_EC_UPDATE_PARAM*/ + SVA_EC_INACTIVE, /*SVA_EC_GET_PARAM_SIZE*/ + SVA_EC_INACTIVE /* SVA_EC_GEN_DATA_UNIT */ + }, + /* Current State = SVA_EC_IN_ACTIVATION */ + { + SVA_EC_ACTIVATE_TRANSITION_REJECTED, /*SVA_EC_CREATE*/ + SVA_EC_ACTIVATE_TRANSITION_REJECTED, /*SVA_EC_CONFIGURE*/ + SVA_EC_ACTIVATE_TRANSITION_REJECTED, /*SVA_EC_INTERNAL_NEEDS*/ + SVA_EC_ACTIVATE_TRANSITION_REJECTED, /*SVA_EC_ACTIVATE*/ + SVA_EC_ACTIVATE_TRANSITION_REJECTED, /*SVA_EC_INACTIVATE*/ + SVA_EC_ACTIVATE_TRANSITION_REJECTED, /*SVA_EC_CONTROL_START*/ + SVA_EC_ACTIVATE_TRANSITION_REJECTED, /*SVA_EC_CONTROL_STOP*/ + SVA_EC_ACTIVATE_TRANSITION_REJECTED, /*SVA_EC_CONTROL_ABORT*/ + SVA_EC_IN_ACTIVATION, /*SVA_EC_ALL_DEPENDENCIES_RESOLVED*/ + SVA_EC_IN_ACTIVATION, /*SVA_EC_PUSH*/ + SVA_EC_IN_ACTIVATION, /*SVA_EC_EVENT_EOK*/ + SVA_EC_IN_ACTIVATION, /*SVA_EC_EVENT_FAKE*/ + SVA_EC_ACTIVE, /*SVA_EC_EVENT_ACTIVE*/ + SVA_EC_IN_ACTIVATION, /*SVA_EC_EVENT_INACTIVE*/ + SVA_EC_IN_ACTIVATION, /*SVA_EC_RESET*/ + SVA_EC_ACTIVATE_TRANSITION_REJECTED, /*SVA_EC_CONTROL_DELETE*/ + SVA_EC_IN_ACTIVATION, /*SVA_EC_EVENT_ERROR*/ + SVA_EC_IN_ACTIVATION, /*SVA_EC_FLUSH_IN*/ + SVA_EC_IN_ACTIVATION, /*SVA_EC_FLUSH_OUT*/ + SVA_EC_INACTIVE, /*SVA_EC_CANCEL*/ + SVA_EC_IN_ACTIVATION, /*SVA_EC_UPDATE_PARAM*/ + SVA_EC_IN_ACTIVATION, /*SVA_EC_GET_PARAM_SIZE*/ + SVA_EC_IN_ACTIVATION /* SVA_EC_GEN_DATA_UNIT */ + }, + /* Current State = SVA_EC_ACTIVE */ + { + SVA_EC_ACTIVATE_TRANSITION_REJECTED, /*SVA_EC_CREATE*/ + SVA_EC_ACTIVATE_TRANSITION_REJECTED, /*SVA_EC_CONFIGURE*/ + SVA_EC_ACTIVATE_TRANSITION_REJECTED, /*SVA_EC_INTERNAL_NEEDS*/ + SVA_EC_ACTIVATE_TRANSITION_REJECTED, /*SVA_EC_ACTIVATE*/ + SVA_EC_IN_INACTIVATION, /*SVA_EC_INACTIVATE*/ + SVA_EC_ACTIVE, /*SVA_EC_CONTROL_START*/ + SVA_EC_ACTIVE, /*SVA_EC_CONTROL_STOP*/ + SVA_EC_ACTIVE, /*SVA_EC_CONTROL_ABORT*/ + SVA_EC_ACTIVE, /*SVA_EC_ALL_DEPENDENCIES_RESOLVED*/ + SVA_EC_ACTIVE, /*SVA_EC_PUSH*/ + SVA_EC_ACTIVE, /*SVA_EC_EVENT_EOK*/ + SVA_EC_ACTIVE, /*SVA_EC_EVENT_FAKE*/ + SVA_EC_ACTIVE, /*SVA_EC_EVENT_ACTIVE*/ + SVA_EC_ACTIVE, /*SVA_EC_EVENT_INACTIVE*/ + SVA_EC_ACTIVE, /*SVA_EC_RESET*/ + SVA_EC_INACTIVE, /*SVA_EC_CONTROL_DELETE*/ + SVA_EC_ACTIVE, /*SVA_EC_EVENT_ERROR*/ + SVA_EC_ACTIVE, /*SVA_EC_FLUSH_IN*/ + SVA_EC_ACTIVE, /*SVA_EC_FLUSH_OUT*/ + SVA_EC_ACTIVATE_TRANSITION_REJECTED, /*SVA_EC_CANCEL*/ + SVA_EC_ACTIVE, /*SVA_EC_UPDATE_PARAM*/ + SVA_EC_ACTIVE, /*SVA_EC_GET_PARAM_SIZE*/ + SVA_EC_ACTIVE /* SVA_EC_GEN_DATA_UNIT */ + }, + /* Current State = SVA_EC_IN_INACTIVATION */ + { + SVA_EC_ACTIVATE_TRANSITION_REJECTED, /*SVA_EC_CREATE*/ + SVA_EC_ACTIVATE_TRANSITION_REJECTED, /*SVA_EC_CONFIGURE*/ + SVA_EC_ACTIVATE_TRANSITION_REJECTED, /*SVA_EC_INTERNAL_NEEDS*/ + SVA_EC_ACTIVATE_TRANSITION_REJECTED, /*SVA_EC_ACTIVATE*/ + SVA_EC_ACTIVATE_TRANSITION_REJECTED, /*SVA_EC_INACTIVATE*/ + SVA_EC_ACTIVATE_TRANSITION_REJECTED, /*SVA_EC_CONTROL_START*/ + SVA_EC_ACTIVATE_TRANSITION_REJECTED, /*SVA_EC_CONTROL_STOP*/ + SVA_EC_ACTIVATE_TRANSITION_REJECTED, /*SVA_EC_CONTROL_ABORT*/ + SVA_EC_IN_INACTIVATION, /*SVA_EC_ALL_DEPENDENCIES_RESOLVED*/ + SVA_EC_IN_INACTIVATION, /*SVA_EC_PUSH*/ + SVA_EC_IN_INACTIVATION, /*SVA_EC_EVENT_EOK*/ + SVA_EC_IN_INACTIVATION, /*SVA_EC_EVENT_FAKE*/ + SVA_EC_IN_INACTIVATION, /*SVA_EC_EVENT_ACTIVE*/ + SVA_EC_INACTIVE, /*SVA_EC_EVENT_INACTIVE*/ + SVA_EC_INACTIVE, /*SVA_EC_RESET*/ + SVA_EC_ACTIVATE_TRANSITION_REJECTED, /*SVA_EC_CONTROL_DELETE*/ + SVA_EC_IN_INACTIVATION, /*SVA_EC_EVENT_ERROR*/ + SVA_EC_IN_INACTIVATION, /*SVA_EC_FLUSH_IN*/ + SVA_EC_IN_INACTIVATION, /*SVA_EC_FLUSH_OUT*/ + SVA_EC_ACTIVE, /*SVA_EC_CANCEL*/ + SVA_EC_IN_INACTIVATION, /*SVA_EC_UPDATE_PARAM*/ + SVA_EC_IN_INACTIVATION, /*SVA_EC_GET_PARAM_SIZE*/ + SVA_EC_IN_INACTIVATION /* SVA_EC_GEN_DATA_UNIT */ + } +}; + +/*------------------------------------------------------------------------ + * Private functions prototype + *----------------------------------------------------------------------*/ +PRIVATE t_sva_ec_error sva_EC_ResolveDependencies(t_sva_service_instance_num ); +PRIVATE t_sva_ec_state sva_EC_UpdateInstanceStateMachine(t_sva_service_instance_num ,t_sva_ec_transition ); +PRIVATE t_bool sva_EC_isTransitionValid(t_sva_service_instance_num ,t_sva_ec_transition ); +PRIVATE t_sva_error sva_EC_CheckServiceId(t_sva_service_id ); +PRIVATE t_sva_error sva_EC_DoReset(t_sva_service_id ); +PRIVATE t_sva_error sva_EC_DoFlushIn(t_sva_service_id ); +PRIVATE t_sva_error sva_EC_DoFlushOut(t_sva_service_id ); +PRIVATE t_sva_ec_error sva_EC_ResetStatus(t_sva_video_encoder_status *); +PRIVATE void sva_EC_ResetDescriptor(t_sva_ec_descriptor *); +PRIVATE t_sva_error sva_EC_AllocateMemoryAndLink(t_sva_service_instance_num); +PRIVATE t_bool sva_EC_IsConfigurationValid(const t_sva_video_encoder_configuration *); + +/****************************************************************************/ +/* NAME: t_sva_error sva_EC_Init ( void ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine initialize the Encode Management module. */ +/* 1) Set state of instance to SVA_SERVICE_NOT_INITIALIZED */ +/* 2) init fifos */ +/* 3) Init descriptor for all instances */ +/* */ +/* PARAMETERS: */ +/* IN : none */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/* - always SVA_OK */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + * DONE +*/ +PUBLIC t_sva_error sva_EC_Init( + t_sva_block_id blockId, + t_size blockSize +) +{ + t_uint32 i; + + /*init all encode instances*/ + for(i=0;itransformId) + { + case SVA_ENCODER_MPEG4_SP_L4A: + pDesc->algoId=SVA_EC_ALGO_MPEG4; + break; + case SVA_ENCODER_H264: + pDesc->algoId=SVA_EC_ALGO_H264; + break; + case SVA_ENCODER_H263_P0_L10: + case SVA_ENCODER_H263_P0_L30: + case SVA_ENCODER_H263_P3_L10: + case SVA_ENCODER_H263_P3_L30: + default: + return SVA_INCOHERENT_CONFIGURATION; + /*break;*/ + } + + #ifdef __STN_8815 + #if __STN_8815 >= 20 + if (pConf->raster_in_format == TRUE) + { + if (pDesc->algoId == SVA_EC_ALGO_MPEG4) + { + /* must be MPEG4, this only supported */ + if (pConf->no_search_window == TRUE) + { + /* must enable search window for this feature */ + } + else + { + return SVA_INCOHERENT_CONFIGURATION; + } + } + else + { + return SVA_INCOHERENT_CONFIGURATION; + } + } + #else + if (pConf->raster_in_format == TRUE) + { + return SVA_INCOHERENT_CONFIGURATION; + } + #endif + #endif + + /*check some part of configuration*/ + if (sva_EC_IsConfigurationValid(pConf)==FALSE) + { + return SVA_INCOHERENT_CONFIGURATION; + } + + /*dispatch to algo part*/ + algoError=encodeAlgoDesc[pDesc->algoId].pAlgoInit(instanceNum,pConf); + if (algoError!=SVA_EC_ALGO_OK) {return SVA_INCOHERENT_CONFIGURATION;} + + /*save configuration*/ + pDesc->conf=*pConf; + + /* Update the state machine */ + sva_EC_UpdateInstanceStateMachine(instanceNum,SVA_EC_CONFIGURE); + + return SVA_OK; +} +/*********************** //\/Sarvesh: SPS and PPS generation start ***********************/ +/************************ //\/Sarvesh: SPS and PPS generation End ************************/ + +/****************************************************************************/ +/* NAME: t_sva_error sva_EC_GetInternalNeeds( */ +/* t_sva_service_id serviceId, */ +/* t_size* pNeedsSize */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine returns the size of the memory needed for Encode */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - serviceId: identifier of the service */ +/* - pNeedsSize: size needed */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/* - SVA_OK : Command taken into account */ +/* - SVA_UNKNOWN_SERVICE_ID : service id is not correct */ +/* */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + * DONE +*/ +PUBLIC t_sva_error sva_EC_GetInternalNeeds( + t_sva_service_id serviceId, + t_size *pNeedsSize +) +{ + t_sva_service_instance_num instanceNum = READ_INSTANCE_NUM_IN_SERVICE_ID(serviceId); + t_sva_ec_descriptor *pDesc=&encodeDesc[instanceNum]; + t_sva_ec_algo_error algoError; + t_sva_error status; + t_uint32 fifoSize; + + /*check pointer validity*/ + EC_CHECK_NULL_POINTER(pNeedsSize); + + /*check for service id validity*/ + status=sva_EC_CheckServiceId(serviceId); + if (status!=SVA_OK) {return status;} + + /*compute memory size need*/ + *pNeedsSize = 0; + /*memory need by event management*/ + status=sva_EM_GetInternalNeeds(pNeedsSize); + if (status!=SVA_OK) {return status;} + /*add memory need by algo+brc part*/ + algoError=encodeAlgoDesc[pDesc->algoId].pGetInternalNeeds(instanceNum,&fifoSize); + if (algoError!=SVA_EC_ALGO_OK) {return SVA_INTERNAL_VIDEO_ENCODER_ERROR;} + *pNeedsSize+=fifoSize; + /*add memory need by encode fifo*/ + /*due to source image fifos*/ + GET_FIFO_MEMORY_NEEDS(t_sva_buffer_id, PUSH_FIFO_DEFAULT_SIZE+2, fifoSize); + *pNeedsSize+=fifoSize; + GET_FIFO_MEMORY_NEEDS(t_sva_buffer_id, SUBTASK_ENCODE_NUMBER, fifoSize); + *pNeedsSize+=fifoSize; + /*due to timestamp fifos*/ + GET_FIFO_MEMORY_NEEDS(t_sva_timestamp, PUSH_FIFO_DEFAULT_SIZE+2, fifoSize); + *pNeedsSize+=fifoSize; + GET_FIFO_MEMORY_NEEDS(t_sva_timestamp, SUBTASK_ENCODE_NUMBER, fifoSize); + *pNeedsSize+=fifoSize; + /*due to bitstream buffer use*/ + GET_FIFO_MEMORY_NEEDS(t_sva_buffer_id, PUSH_FIFO_DEFAULT_SIZE+2, fifoSize);/*add 2 due to revert*/ + *pNeedsSize+=fifoSize; + GET_FIFO_MEMORY_NEEDS(t_sva_buffer_id, SUBTASK_ENCODE_NUMBER, fifoSize); + *pNeedsSize+=fifoSize; + /*due to destination buffers*/ + if (pDesc->conf.isDestinationBufferRequested==TRUE) + { + GET_FIFO_MEMORY_NEEDS(t_sva_buffer_id, PUSH_FIFO_DEFAULT_SIZE+2, fifoSize);/*add 2 due to revert*/ + } + else + { + GET_FIFO_MEMORY_NEEDS(t_sva_buffer_id, SUBTASK_ENCODE_NUMBER, fifoSize); + } + *pNeedsSize+=fifoSize; + GET_FIFO_MEMORY_NEEDS(t_sva_buffer_id, SUBTASK_ENCODE_NUMBER, fifoSize); + *pNeedsSize+=fifoSize; + /*due to forward reference buffers*/ + if (pDesc->conf.isDestinationBufferRequested==TRUE) + { + GET_FIFO_MEMORY_NEEDS(t_sva_buffer_id, PUSH_FIFO_DEFAULT_SIZE+2, fifoSize);/*add 2 due to revert*/ + } + else + { + GET_FIFO_MEMORY_NEEDS(t_sva_buffer_id, SUBTASK_ENCODE_NUMBER, fifoSize); + } + *pNeedsSize+=fifoSize; + GET_FIFO_MEMORY_NEEDS(t_sva_buffer_id, SUBTASK_ENCODE_NUMBER, fifoSize); + *pNeedsSize+=fifoSize; + /*due to read Intra refresh buffers*/ + GET_FIFO_MEMORY_NEEDS(t_sva_buffer_id, SUBTASK_ENCODE_NUMBER, fifoSize); + *pNeedsSize+=fifoSize; + GET_FIFO_MEMORY_NEEDS(t_sva_buffer_id, SUBTASK_ENCODE_NUMBER, fifoSize); + *pNeedsSize+=fifoSize; + /*due to write Intra refresh buffers*/ + GET_FIFO_MEMORY_NEEDS(t_sva_buffer_id, SUBTASK_ENCODE_NUMBER, fifoSize); + *pNeedsSize+=fifoSize; + GET_FIFO_MEMORY_NEEDS(t_sva_buffer_id, SUBTASK_ENCODE_NUMBER, fifoSize); + *pNeedsSize+=fifoSize; + /*due to infos buffer*/ + if (pDesc->conf.areInfosRequested==TRUE) + { + GET_FIFO_MEMORY_NEEDS(t_sva_buffer_id, PUSH_FIFO_DEFAULT_SIZE+2, fifoSize); + *pNeedsSize+=fifoSize; + GET_FIFO_MEMORY_NEEDS(t_sva_buffer_id, SUBTASK_ENCODE_NUMBER, fifoSize); + *pNeedsSize+=fifoSize; + } + /*due to deblocking buffer*/ + if (pDesc->conf.outTheLoopFilter!=SVA_NONE_FILTER) + { + GET_FIFO_MEMORY_NEEDS(t_sva_buffer_id, PUSH_FIFO_DEFAULT_SIZE+2, fifoSize); + *pNeedsSize+=fifoSize; + GET_FIFO_MEMORY_NEEDS(t_sva_buffer_id, SUBTASK_ENCODE_NUMBER, fifoSize); + *pNeedsSize+=fifoSize; + } + /*due to cropping vector*/ + if (pDesc->conf.isCroppingVectorEnabled==TRUE) + { + GET_FIFO_MEMORY_NEEDS(t_sva_buffer_id, PUSH_FIFO_DEFAULT_SIZE+2, fifoSize); + *pNeedsSize+=fifoSize; + GET_FIFO_MEMORY_NEEDS(t_sva_buffer_id, SUBTASK_ENCODE_NUMBER, fifoSize); + *pNeedsSize+=fifoSize; + } + if (pDesc->conf.brcMode==SVA_FRAME_BASE) + { + GET_FIFO_MEMORY_NEEDS(t_sva_buffer_id, PUSH_FIFO_DEFAULT_SIZE+2, fifoSize); + *pNeedsSize+=fifoSize; + GET_FIFO_MEMORY_NEEDS(t_sva_buffer_id, SUBTASK_ENCODE_NUMBER, fifoSize); + *pNeedsSize+=fifoSize; + } + + /*due to subtask dependencies fifo*/ + GET_FIFO_MEMORY_NEEDS(t_sva_ec_subtask_dependencies, SUBTASK_ENCODE_NUMBER, fifoSize); + *pNeedsSize+=fifoSize; + GET_FIFO_MEMORY_NEEDS(t_sva_ec_subtask_dependencies, SUBTASK_ENCODE_NUMBER, fifoSize); + *pNeedsSize+=fifoSize; + /*add memory need by caching of params*/ + *pNeedsSize+=encodeAlgoDesc[pDesc->algoId].pGetParamsInSize(instanceNum); + *pNeedsSize+=encodeAlgoDesc[pDesc->algoId].pGetParamsOutSize(instanceNum); + *pNeedsSize+=encodeAlgoDesc[pDesc->algoId].pGetParamsInOutSize(instanceNum); + + return SVA_OK; +} + +/****************************************************************************/ +/* NAME: t_sva_error sva_EC_ProvideInternalNeeds ( */ +/* t_sva_service_id serviceId */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine allows to end the configuration of the service since */ +/* memory need has been provide by user. */ +/* - create fifos */ +/* - create subtasks */ +/* - create subtasklist */ +/* - enable events */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - serviceId: identifier of the service */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/* - SVA_OK : Command taken into account */ +/* - SVA_UNKNOWN_SERVICE_ID : service id is not correct */ +/* - SVA_UNEXPECTED_API_CALL : Command cannot be excecuted in */ +/* current context. */ +/* - SVA_INTERNAL_VIDEO_ENCODER_ERROR : internal error */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + * DONE +*/ +PUBLIC t_sva_error sva_EC_ProvideInternalNeeds(t_sva_service_id serviceId) +{ + t_sva_error status; + t_sva_service_instance_num instanceNum = READ_INSTANCE_NUM_IN_SERVICE_ID(serviceId); + t_sva_ec_descriptor *pDesc=&encodeDesc[instanceNum]; + t_sva_video_encoder_configuration *pConf = &pDesc->conf; + t_sva_tm_postprocessing_type ppType; + t_sva_ff_error ffError; + t_sva_tm_error tmError; + t_sva_in_error inLocalError; + t_sva_ec_algo_error algoError; + t_sva_tm_task_ctrl_desc encodeTaskDesc; + t_sva_tm_field_ctrl_desc copyEncodeFieldDescArray[ENCODE_FIELD_NUMBER]; + t_sva_fw_features needFeatures; + t_sva_tm_subtask_type sva_tm_subtask_type; + t_uint32 i; + + /* Sarvesh: Temporary HCL workaround for FW VI9607 */ + /* We have to zero initialize the memory pointed by PARAM IN(pDesc->paramInAddr), PARAM INOUT(pDesc->paramInOutAddr) for HCL to work */ + /* Memory pointed by PARAM OUT (pDesc->paramOutAddr) is not updated in the subtask memory, so need not to be zero initialized */ +#define SVA_ZERO_INITIALIZE_PARAMS_VI9607_ENABLE_HCL_WORKAROUND +#ifdef SVA_ZERO_INITIALIZE_PARAMS_VI9607_ENABLE_HCL_WORKAROUND + t_uint32 param_count = 0; + t_uint8 *pParamAdd = NULL; +#endif /* End of #ifdef SVA_ZERO_INITIALIZE_PARAMS_VI9607_ENABLE_HCL_WORKAROUND */ + + /*check for service id validity*/ + status=sva_EC_CheckServiceId(serviceId); + if (status!=SVA_OK) {return status;} + + /*check that transition is allowed*/ + if (sva_EC_isTransitionValid(instanceNum,SVA_EC_INTERNAL_NEEDS)==FALSE) {return SVA_UNEXPECTED_API_CALL;} + + /*copy TvoFieldDescArray*/ + for(i=0;ialgoId].pProvideMemoryNeeds(instanceNum, pDesc->subtasksIdArray); +//\/ if (algoError!=SVA_EC_ALGO_OK) {return SVA_INTERNAL_VIDEO_ENCODER_ERROR;} + + /*create fifo*/ + CREATE_FIFO(t_sva_ec_subtask_dependencies, SUBTASK_ENCODE_NUMBER, pDesc->subtasksDependencyFifo, ffError); + if (ffError != SVA_FIFO_OK) {return SVA_INTERNAL_VIDEO_ENCODER_ERROR;} + CREATE_FIFO(t_sva_ec_subtask_dependencies, SUBTASK_ENCODE_NUMBER, pDesc->inUseSubtaskDependency, ffError); + if (ffError != SVA_FIFO_OK) {return SVA_INTERNAL_VIDEO_ENCODER_ERROR;} + CREATE_FIFO(t_sva_buffer_id, PUSH_FIFO_DEFAULT_SIZE+2, pDesc->sourceBufferFifos.pushFifo, ffError); + if (ffError != SVA_FIFO_OK) {return SVA_INTERNAL_VIDEO_ENCODER_ERROR;} + CREATE_FIFO(t_sva_buffer_id, SUBTASK_ENCODE_NUMBER, pDesc->sourceBufferFifos.inUseFifo, ffError); + if (ffError != SVA_FIFO_OK) {return SVA_INTERNAL_VIDEO_ENCODER_ERROR;} + CREATE_FIFO(t_sva_timestamp, PUSH_FIFO_DEFAULT_SIZE+2, pDesc->timeStampFifos.pushFifo, ffError); + if (ffError != SVA_FIFO_OK) {return SVA_INTERNAL_VIDEO_ENCODER_ERROR;} + CREATE_FIFO(t_sva_timestamp, SUBTASK_ENCODE_NUMBER, pDesc->timeStampFifos.inUseFifo, ffError); + if (ffError != SVA_FIFO_OK) {return SVA_INTERNAL_VIDEO_ENCODER_ERROR;} + CREATE_FIFO(t_sva_buffer_id, PUSH_FIFO_DEFAULT_SIZE+2, pDesc->bitstreamBufferFifos.pushFifo, ffError);/*add 2 due to revert*/ + if (ffError != SVA_FIFO_OK) {return SVA_INTERNAL_VIDEO_ENCODER_ERROR;} + CREATE_FIFO(t_sva_buffer_id, SUBTASK_ENCODE_NUMBER, pDesc->bitstreamBufferFifos.inUseFifo, ffError); + if (ffError != SVA_FIFO_OK) {return SVA_INTERNAL_VIDEO_ENCODER_ERROR;} + if (pDesc->conf.isDestinationBufferRequested==TRUE) + { + CREATE_FIFO(t_sva_buffer_id, PUSH_FIFO_DEFAULT_SIZE+2, pDesc->destBufferFifos.pushFifo, ffError);/*add 2 due to revert*/ + } + else + { + CREATE_FIFO(t_sva_buffer_id, SUBTASK_ENCODE_NUMBER, pDesc->destBufferFifos.pushFifo, ffError); + } + if (ffError != SVA_FIFO_OK) {return SVA_INTERNAL_VIDEO_ENCODER_ERROR;} + CREATE_FIFO(t_sva_buffer_id, SUBTASK_ENCODE_NUMBER, pDesc->destBufferFifos.inUseFifo, ffError); + if (ffError != SVA_FIFO_OK) {return SVA_INTERNAL_VIDEO_ENCODER_ERROR;} + if (pDesc->conf.isDestinationBufferRequested==TRUE) + { + CREATE_FIFO(t_sva_buffer_id, PUSH_FIFO_DEFAULT_SIZE+2, pDesc->fwRefBufferFifos.pushFifo, ffError);/*add 2 due to revert*/ + } + else + { + CREATE_FIFO(t_sva_buffer_id, SUBTASK_ENCODE_NUMBER, pDesc->fwRefBufferFifos.pushFifo, ffError); + } + if (ffError != SVA_FIFO_OK) {return SVA_INTERNAL_VIDEO_ENCODER_ERROR;} + CREATE_FIFO(t_sva_buffer_id, SUBTASK_ENCODE_NUMBER, pDesc->fwRefBufferFifos.inUseFifo, ffError); + if (ffError != SVA_FIFO_OK) {return SVA_INTERNAL_VIDEO_ENCODER_ERROR;} + CREATE_FIFO(t_sva_buffer_id, SUBTASK_ENCODE_NUMBER, pDesc->readIntraRefreshBufferFifos.pushFifo, ffError); + if (ffError != SVA_FIFO_OK) {return SVA_INTERNAL_VIDEO_ENCODER_ERROR;} + CREATE_FIFO(t_sva_buffer_id, SUBTASK_ENCODE_NUMBER, pDesc->readIntraRefreshBufferFifos.inUseFifo, ffError); + if (ffError != SVA_FIFO_OK) {return SVA_INTERNAL_VIDEO_ENCODER_ERROR;} + CREATE_FIFO(t_sva_buffer_id, SUBTASK_ENCODE_NUMBER, pDesc->writeIntraRefreshBufferFifos.pushFifo, ffError); + if (ffError != SVA_FIFO_OK) {return SVA_INTERNAL_VIDEO_ENCODER_ERROR;} + CREATE_FIFO(t_sva_buffer_id, SUBTASK_ENCODE_NUMBER, pDesc->writeIntraRefreshBufferFifos.inUseFifo, ffError); + if (ffError != SVA_FIFO_OK) {return SVA_INTERNAL_VIDEO_ENCODER_ERROR;} + if (pDesc->conf.areInfosRequested) + { + CREATE_FIFO(t_sva_buffer_id, PUSH_FIFO_DEFAULT_SIZE+2, pDesc->infoBufferFifos.pushFifo, ffError); + if (ffError != SVA_FIFO_OK) {return SVA_INTERNAL_VIDEO_ENCODER_ERROR;} + CREATE_FIFO(t_sva_buffer_id, SUBTASK_ENCODE_NUMBER, pDesc->infoBufferFifos.inUseFifo, ffError); + if (ffError != SVA_FIFO_OK) {return SVA_INTERNAL_VIDEO_ENCODER_ERROR;} + } + if (pDesc->conf.outTheLoopFilter!=SVA_NONE_FILTER) + { + CREATE_FIFO(t_sva_buffer_id, PUSH_FIFO_DEFAULT_SIZE+2, pDesc->deblockingBufferFifos.pushFifo, ffError); + if (ffError != SVA_FIFO_OK) {return SVA_INTERNAL_VIDEO_ENCODER_ERROR;} + CREATE_FIFO(t_sva_buffer_id, SUBTASK_ENCODE_NUMBER, pDesc->deblockingBufferFifos.inUseFifo, ffError); + if (ffError != SVA_FIFO_OK) {return SVA_INTERNAL_VIDEO_ENCODER_ERROR;} + } + if (pDesc->conf.isCroppingVectorEnabled==TRUE) + { + CREATE_FIFO(t_sva_buffer_id, PUSH_FIFO_DEFAULT_SIZE+2, pDesc->croppingBufferFifos.pushFifo, ffError); + if (ffError != SVA_FIFO_OK) {return SVA_INTERNAL_VIDEO_ENCODER_ERROR;} + CREATE_FIFO(t_sva_buffer_id, SUBTASK_ENCODE_NUMBER, pDesc->croppingBufferFifos.inUseFifo, ffError); + if (ffError != SVA_FIFO_OK) {return SVA_INTERNAL_VIDEO_ENCODER_ERROR;} + } + if (pDesc->conf.brcMode==SVA_FRAME_BASE) + { + CREATE_FIFO(t_sva_buffer_id, PUSH_FIFO_DEFAULT_SIZE+2, pDesc->brcBufferFifos.pushFifo, ffError); + if (ffError != SVA_FIFO_OK) {return SVA_INTERNAL_VIDEO_ENCODER_ERROR;} + CREATE_FIFO(t_sva_buffer_id, SUBTASK_ENCODE_NUMBER, pDesc->brcBufferFifos.inUseFifo, ffError); + if (ffError != SVA_FIFO_OK) {return SVA_INTERNAL_VIDEO_ENCODER_ERROR;} + } + + /*get mem for params caching*/ + inLocalError=sva_IN_AllocMemory(encodeAlgoDesc[pDesc->algoId].pGetParamsInSize(instanceNum),&pDesc->paramInAddr); + if (inLocalError != SVA_IN_OK) {return SVA_INTERNAL_VIDEO_ENCODER_ERROR;} + +#ifdef SVA_ZERO_INITIALIZE_PARAMS_VI9607_ENABLE_HCL_WORKAROUND + if (SVA_EC_ALGO_H264 == pDesc->algoId) + { + pParamAdd = (t_uint8*)pDesc->paramInAddr; + for(param_count=0;param_count<(encodeAlgoDesc[pDesc->algoId].pGetParamsInSize(instanceNum));param_count++) + { + *pParamAdd++ = 0; + } + } /* end if SVA_EC_ALGO_H264 */ +#endif /* End of #ifdef SVA_ZERO_INITIALIZE_PARAMS_VI9607_ENABLE_HCL_WORKAROUND */ + inLocalError=sva_IN_AllocMemory(encodeAlgoDesc[pDesc->algoId].pGetParamsOutSize(instanceNum),&pDesc->paramOutAddr); + if (inLocalError != SVA_IN_OK) {return SVA_INTERNAL_VIDEO_ENCODER_ERROR;} + inLocalError=sva_IN_AllocMemory(encodeAlgoDesc[pDesc->algoId].pGetParamsInOutSize(instanceNum),&pDesc->paramInOutAddr); + if (inLocalError != SVA_IN_OK) {return SVA_INTERNAL_VIDEO_ENCODER_ERROR;} +#ifdef SVA_ZERO_INITIALIZE_PARAMS_VI9607_ENABLE_HCL_WORKAROUND + if (SVA_EC_ALGO_H264 == pDesc->algoId) + { + pParamAdd = (t_uint8*)pDesc->paramInOutAddr; + for(param_count=0;param_count<(encodeAlgoDesc[pDesc->algoId].pGetParamsInOutSize(instanceNum));param_count++) + { + *pParamAdd++ = 0; + } + pParamAdd = NULL; + } /* end if SVA_EC_ALGO_H264 */ +#endif /* End of #ifdef SVA_ZERO_INITIALIZE_PARAMS_VI9607_ENABLE_HCL_WORKAROUND */ + + /*define memory subtask descriptor*/ + encodeTaskDesc.memId=ENCODE_DEFAULT_MEMORY_ID; + encodeTaskDesc.fieldnb=ENCODE_FIELD_NUMBER; + encodeTaskDesc.pfieldctrldesc=(t_sva_tm_field_ctrl_desc *)copyEncodeFieldDescArray; + encodeTaskDesc.pfieldctrldesc[ENCODE_FIELD_PARAMIN].commandDesc.allocDesc.sizetoallocate=(t_uint16) encodeAlgoDesc[pDesc->algoId].pGetParamsInSize(instanceNum); + encodeTaskDesc.pfieldctrldesc[ENCODE_FIELD_PARAMOUT].commandDesc.allocDesc.sizetoallocate=(t_uint16) encodeAlgoDesc[pDesc->algoId].pGetParamsOutSize(instanceNum); + encodeTaskDesc.pfieldctrldesc[ENCODE_FIELD_IN_PARAMINOUT].commandDesc.allocDesc.sizetoallocate=(t_uint16) encodeAlgoDesc[pDesc->algoId].pGetParamsInOutSize(instanceNum); + if (SVA_EC_ALGO_MPEG4 == pDesc->algoId) + { + /*define which deblocking set-up to use*/ + if (pConf->inTheLoopFilter==SVA_DEBLOCKING_FILTER && pConf->outTheLoopFilter==SVA_DERINGING_FILTER) + { + ppType=SVA_TM_H263_DEBLOCKING_IN_LOOP_AND_DERINGING_OUT; + } + else if (pConf->inTheLoopFilter==SVA_DEBLOCKING_FILTER && pConf->outTheLoopFilter==SVA_NONE_FILTER) + { + ppType=SVA_TM_H263_DEBLOCKING_IN_LOOP; + } + else if (pConf->inTheLoopFilter==SVA_NONE_FILTER && pConf->outTheLoopFilter==SVA_DEBLOCKING_DERINGING_FILTER) + { + ppType=SVA_TM_DEBLOCKING_DERINGING_OUT_LOOP; + } + else + { + ppType=SVA_TM_NO_POST_PROCESSING; + } + } /* end if SVA_EC_ALGO_MPEG4 */ + else if (SVA_EC_ALGO_H264 == pDesc->algoId) + { + ppType=SVA_TM_NO_POST_PROCESSING; + } /* end if SVA_EC_ALGO_H264 */ + else + { + return SVA_INTERNAL_VIDEO_ENCODER_ERROR; + } + + sva_tm_subtask_type = algo_2_subtask_type[pDesc->algoId]; + + if (sva_tm_subtask_type == SVA_TM_ENCODE_MPEG4_SW) + { + if (pConf->no_search_window == TRUE) + { + if (pConf->raster_in_format == TRUE) + { + sva_tm_subtask_type = SVA_TM_ENCODE_MPEG4_NO_SW_RASTER_IN; + } + else + { + sva_tm_subtask_type = SVA_TM_ENCODE_MPEG4_NO_SW; + } + } + } + + /*create subtask*/ + for(i=0;isubtasksIdArray[i]); + if (tmError != SVA_TM_OK) {return SVA_INTERNAL_VIDEO_ENCODER_ERROR;} + } + /*links inout between them*/ + for(i=0;isubtasksIdArray[i], + SVA_TM_ENC_ADDR_IN_FRAME_PARAMETERS, + pDesc->subtasksIdArray[(i+SUBTASK_ENCODE_NUMBER-1)%SUBTASK_ENCODE_NUMBER], + SVA_TM_ENC_ADDR_OUT_FRAME_PARAMETERS); + if (tmError != SVA_TM_OK) {return SVA_INTERNAL_VIDEO_ENCODER_ERROR;} + } + + algoError=encodeAlgoDesc[pDesc->algoId].pProvideMemoryNeeds(instanceNum, pDesc->subtasksIdArray);//\/ + if (algoError!=SVA_EC_ALGO_OK) {return SVA_INTERNAL_VIDEO_ENCODER_ERROR;}//\/ + + /*get needed features*/ + needFeatures = encodeAlgoDesc[pDesc->algoId].pGetFeatures(instanceNum); + + /*create subtasklist*/ + tmError=sva_TM_CreateSubTaskList(SVA_TM_ENCODE,serviceId,needFeatures,&pDesc->subtasksListId); + if (tmError != SVA_TM_OK) {return SVA_INTERNAL_VIDEO_ENCODER_ERROR;} + + /* enable events for sub task list*/ + /* we enable EOT, EOW, BRC, ERR and EOK event*/ + /* we also enable activate, inactivate and fake event*/ + tmError=sva_TM_DisableAllVirtualHwEvents(pDesc->subtasksListId); + if (tmError != SVA_TM_OK) {return SVA_INTERNAL_VIDEO_ENCODER_ERROR;} + tmError=sva_TM_EnableVirtualHwEvents(pDesc->subtasksListId,SVA_TM_EOT_HW_EVENT); + if (tmError != SVA_TM_OK) {return SVA_INTERNAL_VIDEO_ENCODER_ERROR;} + tmError=sva_TM_EnableVirtualHwEvents(pDesc->subtasksListId,SVA_TM_EOW_HW_EVENT); + if (tmError != SVA_TM_OK) {return SVA_INTERNAL_VIDEO_ENCODER_ERROR;} + tmError=sva_TM_EnableVirtualHwEvents(pDesc->subtasksListId,SVA_TM_BRC_HW_EVENT); + if (tmError != SVA_TM_OK) {return SVA_INTERNAL_VIDEO_ENCODER_ERROR;} + tmError=sva_TM_EnableVirtualHwEvents(pDesc->subtasksListId,SVA_TM_ERR_HW_EVENT); + if (tmError != SVA_TM_OK) {return SVA_INTERNAL_VIDEO_ENCODER_ERROR;} + tmError=sva_TM_EnableVirtualHwEvents(pDesc->subtasksListId,SVA_TM_EOK_HW_EVENT); + if (tmError != SVA_TM_OK) {return SVA_INTERNAL_VIDEO_ENCODER_ERROR;} + tmError=sva_TM_EnableVirtualHwEvents(pDesc->subtasksListId,SVA_TM_INACTIVE_HW_EVENT); + if (tmError != SVA_TM_OK) {return SVA_INTERNAL_VIDEO_ENCODER_ERROR;} + tmError=sva_TM_EnableVirtualHwEvents(pDesc->subtasksListId,SVA_TM_ACTIVE_HW_EVENT); + if (tmError != SVA_TM_OK) {return SVA_INTERNAL_VIDEO_ENCODER_ERROR;} + tmError=sva_TM_EnableVirtualHwEvents(pDesc->subtasksListId,SVA_TM_FAKE_HW_EVENT); + if (tmError != SVA_TM_OK) {return SVA_INTERNAL_VIDEO_ENCODER_ERROR;} + + /* Set default dependencies*/ + pDesc->defaultDep.brcAlgoDep=NOT_RESOLVED_DEPENDENCY; + pDesc->defaultDep.sourceBufferDep=NOT_RESOLVED_DEPENDENCY; + pDesc->defaultDep.bitstreamBufferDep=NOT_RESOLVED_DEPENDENCY; + if (pDesc->conf.isDestinationBufferRequested==TRUE) + { + pDesc->defaultDep.destBufferDep=NOT_RESOLVED_DEPENDENCY; + pDesc->defaultDep.fwRefBufferDep=NOT_RESOLVED_DEPENDENCY; + } + else + { + pDesc->defaultDep.destBufferDep=NOT_RESOLVED_INTERNAL_DEPENDENCY; + pDesc->defaultDep.fwRefBufferDep=NOT_RESOLVED_INTERNAL_DEPENDENCY; + } + pDesc->defaultDep.readIntraRefreshBufferDep=NOT_RESOLVED_INTERNAL_DEPENDENCY; + pDesc->defaultDep.writeIntraRefreshBufferDep=NOT_RESOLVED_INTERNAL_DEPENDENCY; + if (pDesc->conf.areInfosRequested==FALSE) + { + pDesc->defaultDep.infoBufferDep=RESOLVED_INTERNAL_DEPENDENCY; + } + else + { + pDesc->defaultDep.infoBufferDep=NOT_RESOLVED_DEPENDENCY; + } + if (pDesc->conf.outTheLoopFilter!=SVA_NONE_FILTER) + { + pDesc->defaultDep.deblockingBufferDep=NOT_RESOLVED_DEPENDENCY; + } + else {pDesc->defaultDep.deblockingBufferDep=RESOLVED_INTERNAL_DEPENDENCY;} + if (pDesc->conf.isCroppingVectorEnabled==TRUE) + { + pDesc->defaultDep.croppingBufferDep=NOT_RESOLVED_DEPENDENCY; + } + else {pDesc->defaultDep.croppingBufferDep=RESOLVED_INTERNAL_DEPENDENCY;} + if (pDesc->conf.brcMode==SVA_FRAME_BASE) + { + pDesc->defaultDep.brcBufferDep=NOT_RESOLVED_DEPENDENCY; + } + else {pDesc->defaultDep.brcBufferDep=RESOLVED_INTERNAL_DEPENDENCY;} + + /* Allocate internal video memory need if needed*/ + status=sva_EC_AllocateMemoryAndLink(instanceNum); + if (status!=SVA_OK) {return SVA_INTERNAL_VIDEO_ENCODER_ERROR;} + + /* Push subtask in subtasksDependencyFifo since they are ready to be solved*/ + for(i=0;isubtasksIdArray[i]; + /*default dependencies*/ + subtaskDep.dependencies=pDesc->defaultDep; + /*set buffer list to use*/ + subtaskDep.bufferListId=pDesc->bufferListIdArray[i]; + /*set header buffer to use*/ + subtaskDep.headerBufferBlockId=pDesc->headerBufferBlockIdArray[i]; + /*set default value for cropiing vector*/ + subtaskDep.croppingVector=pConf->sourceFrameDesc.window.imageOffset; + /*in case of first subtask then forward ref buffer is marked as solve dep done*/ + if (i==0) {subtaskDep.dependencies.fwRefBufferDep=RESOLVED_INTERNAL_DEPENDENCY;} + + /*push subtask in the list of subtask to resolve dep*/ + ffError=PUSH_FIFO_ELEM(pDesc->subtasksDependencyFifo, t_sva_ec_subtask_dependencies, subtaskDep); + if (ffError!=SVA_FIFO_OK) {return SVA_INTERNAL_VIDEO_ENCODER_ERROR;} + } + + /*init first paraminout*/ + algoError=encodeAlgoDesc[pDesc->algoId].pInitParamInOut(instanceNum,(t_sva_ec_algo_params_inout *) pDesc->paramInOutAddr); + if (algoError!=SVA_EC_ALGO_OK) {return SVA_INTERNAL_VIDEO_ENCODER_ERROR;} + tmError=sva_TM_InitSubTaskField(pDesc->subtasksIdArray[0], SVA_TM_ENC_ADDR_IN_FRAME_PARAMETERS, + pDesc->paramInOutAddr, encodeAlgoDesc[pDesc->algoId].pGetParamsInOutSize(instanceNum)); + if (tmError!=SVA_TM_OK) {return SVA_INTERNAL_VIDEO_ENCODER_ERROR;} + + /* Update the state machine */ + sva_EC_UpdateInstanceStateMachine(instanceNum,SVA_EC_INTERNAL_NEEDS); + + return SVA_OK; +} + +/****************************************************************************/ +/* NAME: t_sva_error sva_EC_Activate( */ +/* t_sva_service_id serviceId, */ +/* t_sva_service_mode serviceMode, */ +/* t_sva_fw_id *pFwId */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine activates the encode service */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - serviceId: identifier of the service */ +/* - serviceMode : set service to real_time or not */ +/* */ +/* OUT : */ +/* - pFwId : identifier of firmware id for which user shall provide location*/ +/* */ +/* RETURN: */ +/* t_sva_error */ +/* - SVA_OK : Command taken into account */ +/* - SVA_UNKNOWN_SERVICE_ID : service id is not correct */ +/* - SVA_UNEXPECTED_API_CALL : Command cannot be excecuted in */ +/* current context. */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + * DONE +*/ +PUBLIC t_sva_error sva_EC_Activate( + t_sva_service_id serviceId, + t_sva_service_mode serviceMode, + t_sva_fw_id *pFwId +) +{ + t_sva_error status; + t_sva_service_instance_num instanceNum = READ_INSTANCE_NUM_IN_SERVICE_ID(serviceId); + t_sva_ec_descriptor *pDesc=&encodeDesc[instanceNum]; + + EC_CHECK_NULL_POINTER(pFwId); + + /*check for service id validity*/ + status=sva_EC_CheckServiceId(serviceId); + if (status!=SVA_OK) {return status;} + + /*check that transition is allowed*/ + if (sva_EC_isTransitionValid(instanceNum,SVA_EC_ACTIVATE)==FALSE) {return SVA_UNEXPECTED_API_CALL;} + + /* Update the state machine */ + /* Update state machine before command is send to task management to avoid race condition */ + sva_EC_UpdateInstanceStateMachine(instanceNum,SVA_EC_ACTIVATE); + + /*activate subTaskList*/ + /*handle informative error code*/ + status=sva_TM_ActivateSubTaskList(pDesc->subtasksListId,serviceMode,pFwId); + if (status != SVA_OK && status != SVA_FW_SWITCH_OCCURED && status != SVA_FW_SWITCH_DELAYED) + { + sva_EC_UpdateInstanceStateMachine(instanceNum,SVA_EC_CANCEL); + + return status; + } + + return status; +} + +/****************************************************************************/ +/* NAME: t_sva_error sva_EC_Inactivate( */ +/* t_sva_service_id serviceId */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine deactivates the encode service */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - serviceId: identifier of the service */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/* - SVA_OK : Command taken into account */ +/* - SVA_UNKNOWN_SERVICE_ID : service id is not correct */ +/* - SVA_UNEXPECTED_API_CALL : Command cannot be excecuted in */ +/* current context. */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + * DONE +*/ +PUBLIC t_sva_error sva_EC_Inactivate(t_sva_service_id serviceId) +{ + t_sva_error status; + t_sva_service_instance_num instanceNum = READ_INSTANCE_NUM_IN_SERVICE_ID(serviceId); + t_sva_ec_descriptor *pDesc=&encodeDesc[instanceNum]; + t_sva_tm_error tmError; + + /*check for service id validity*/ + status=sva_EC_CheckServiceId(serviceId); + if (status!=SVA_OK) {return status;} + + /*check that transition is allowed*/ + if (sva_EC_isTransitionValid(instanceNum,SVA_EC_INACTIVATE)==FALSE) {return SVA_UNEXPECTED_API_CALL;} + + /* Update the state machine */ + /* Update state machine before command is send to task management to avoid race condition */ + sva_EC_UpdateInstanceStateMachine(instanceNum,SVA_EC_INACTIVATE); + + /*inactivate subTaskList*/ + /*handle informative error code*/ + tmError=sva_TM_InActivateSubTaskList(pDesc->subtasksListId); + if (tmError != SVA_TM_OK) + { + sva_EC_UpdateInstanceStateMachine(instanceNum,SVA_EC_CANCEL); + + return SVA_INTERNAL_VIDEO_ENCODER_ERROR; + } + + return SVA_OK; +} + +/****************************************************************************/ +/* NAME: t_sva_error sva_EC_Control ( */ +/* t_sva_service_id serviceId, */ +/* t_sva_service_cmd_id cmdId, */ +/* t_uint32 param */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine allows to control an instance of an encode Service */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - serviceId: identifier of the given service */ +/* - cmdId: command to apply to the encode */ +/* - param: parameter use by command */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/* - SVA_OK : Command taken into account */ +/* - SVA_UNKNOWN_SERVICE_ID : service id is not correct */ +/* - SVA_UNEXPECTED_API_CALL : Command cannot be excecuted in */ +/* current context. */ +/* - SVA_UNKNOWN_CMD_ID : Command to execute is unknown */ +/* - SVA_INTERNAL_VIDEO_ENCODER_ERROR : internal error */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + DONE +*/ +PUBLIC t_sva_error sva_EC_Control( + t_sva_service_id serviceId, + t_sva_service_cmd_id cmdId, + t_uint32 param +) +{ + t_sva_service_instance_num instanceNum = READ_INSTANCE_NUM_IN_SERVICE_ID(serviceId); + t_sva_ec_descriptor *pDesc=&encodeDesc[instanceNum]; + t_sva_error status = SVA_UNEXPECTED_API_CALL; + t_sva_error error; + t_sva_tm_error tmError; + + /*check for service id validity*/ + error=sva_EC_CheckServiceId(serviceId); + if (error!=SVA_OK) {return error;} + +#ifdef __DEBUG + { + t_uint32 systemTime; + + SVA_GetServiceSystemTime(serviceId,&systemTime); + commandEncodeDebugTable[instanceNum].commandDebugDesc[commandEncodeDebugTable[instanceNum].nbOfCommandReceived%LOG_DEPTH].command=cmdId; + commandEncodeDebugTable[instanceNum].commandDebugDesc[commandEncodeDebugTable[instanceNum].nbOfCommandReceived%LOG_DEPTH].systemTime=systemTime; + commandEncodeDebugTable[instanceNum].commandDebugDesc[commandEncodeDebugTable[instanceNum].nbOfCommandReceived%LOG_DEPTH].parameter=param; + commandEncodeDebugTable[instanceNum].nbOfCommandReceived++; + } +#endif + + /*handle command*/ + switch(cmdId) + { + case SVA_SERVICE_START: + if (sva_EC_isTransitionValid(instanceNum,SVA_EC_CONTROL_START)==TRUE) + { + /* transition are force before sending task command to avoid race condition*/ + sva_EC_UpdateInstanceStateMachine(instanceNum,SVA_EC_CONTROL_START); + /* as we accepted some push before (or after a restart) some dependencies are perhaps + already scheduled + */ + if (GET_FIFO_NB_ELEMS(pDesc->subtasksDependencyFifo)!=SUBTASK_ENCODE_NUMBER) + { + sva_EC_UpdateInstanceStateMachine(instanceNum,SVA_EC_ALL_DEPENDENCIES_RESOLVED); + } + /*now send start command*/ + tmError=sva_TM_SendTaskCommand(pDesc->subtasksListId,SVA_TM_TCMD_START,param); + HCL_DEBUG_ASSERT(tmError==SVA_TM_OK); + + status = SVA_OK; + } + break; + case SVA_SERVICE_STOP: + if (sva_EC_isTransitionValid(instanceNum,SVA_EC_CONTROL_STOP)==TRUE) + { + /* transition are force before sending task command to avoid race condition*/ + sva_EC_UpdateInstanceStateMachine(instanceNum,SVA_EC_CONTROL_STOP); + /*stop subtask list*/ + tmError=sva_TM_SendTaskCommand(pDesc->subtasksListId,SVA_TM_TCMD_STOP,param); + HCL_DEBUG_ASSERT(tmError==SVA_TM_OK); + + status = SVA_OK; + } + break; + case SVA_SERVICE_ABORT: + if (sva_EC_isTransitionValid(instanceNum,SVA_EC_CONTROL_ABORT)==TRUE) + { + /* transition are force before sending task command to avoid race condition*/ + sva_EC_UpdateInstanceStateMachine(instanceNum,SVA_EC_CONTROL_ABORT); + /*abort subtask list*/ + tmError=sva_TM_SendTaskCommand(pDesc->subtasksListId,SVA_TM_TCMD_ABORT,param); + HCL_DEBUG_ASSERT(tmError==SVA_TM_OK); + + status = SVA_OK; + } + break; + case SVA_SERVICE_RESET: + if (sva_EC_isTransitionValid(instanceNum,SVA_EC_RESET)==TRUE) + { + /*do instance clean-up so service can restart*/ + status = sva_EC_DoReset(serviceId); + if (status == SVA_OK) + { + sva_EC_UpdateInstanceStateMachine(instanceNum,SVA_EC_RESET); + } + } + break; + case SVA_SERVICE_FLUSH_IN: + if (sva_EC_isTransitionValid(instanceNum,SVA_EC_FLUSH_IN)==TRUE) + { + /*flush output buffer if necessary*/ + status = sva_EC_DoFlushIn(serviceId); + if (status == SVA_OK) + { + sva_EC_UpdateInstanceStateMachine(instanceNum,SVA_EC_FLUSH_IN); + /*generate a fake event since flush command is asynchronous*/ + sva_TM_SendTaskCommand(pDesc->subtasksListId,SVA_TM_TCMD_FAKE_EVENT,param); + } + } + break; + case SVA_SERVICE_FLUSH_OUT: + if (sva_EC_isTransitionValid(instanceNum,SVA_EC_FLUSH_OUT)==TRUE) + { + /*flush output buffer if necessary*/ + status = sva_EC_DoFlushOut(serviceId); + if (status == SVA_OK) + { + sva_EC_UpdateInstanceStateMachine(instanceNum,SVA_EC_FLUSH_OUT); + /*generate a fake event since flush command is asynchronous*/ + sva_TM_SendTaskCommand(pDesc->subtasksListId,SVA_TM_TCMD_FAKE_EVENT,param); + } + } + break; + /*unknown command*/ + default: + status = SVA_UNKNOWN_CMD_ID; + break; + } + + return status; +} + +/****************************************************************************/ +/* NAME: t_sva_error SVA_UpdateVideoEncoderParams( */ +/* t_sva_service_id serviceId, */ +/* t_sva_update_cmd_type updateCmdType, */ +/* t_sva_video_encoder_param_id paramId, */ +/* t_uint32 param */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine allows to update params for an instance of encode */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - serviceId: identifier of the given service */ +/* - updateCmdType: command to apply to the Encode */ +/* - paramId: Parameter to update */ +/* - param: parameter for the cmdType */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/* - SVA_OK : Command taken into account */ +/* - SVA_UNKNOWN_SERVICE_ID : service id is not correct */ +/* - SVA_UNEXPECTED_API_CALL : Command cannot be excecuted in */ +/* current context. */ +/* - SVA_INTERNAL_VIDEO_ENCODER_ERROR : internal error */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + DONE +*/ +PUBLIC t_sva_error SVA_UpdateVideoEncoderParams( + t_sva_service_id serviceId, + t_sva_update_cmd_type updateCmdType, + t_sva_video_encoder_param_id paramId, + t_uint32 param + ) +{ + t_sva_service_instance_num instanceNum = READ_INSTANCE_NUM_IN_SERVICE_ID(serviceId); + t_sva_ec_descriptor *pDesc=&encodeDesc[instanceNum]; + t_sva_ec_algo_error algoError; + t_sva_error status = SVA_OK; + + /*check for service id validity*/ + status=sva_EC_CheckServiceId(serviceId); + if (status!=SVA_OK) {return status;} + + /*check that transition is allowed*/ + if (sva_EC_isTransitionValid(instanceNum,SVA_EC_UPDATE_PARAM)==FALSE) {return SVA_UNEXPECTED_API_CALL;} + + /*call algo API*/ + algoError=encodeAlgoDesc[pDesc->algoId].pUpdateVideoEncoderParams(instanceNum,updateCmdType,paramId,param); + if (algoError!=SVA_EC_ALGO_OK) {return SVA_INTERNAL_VIDEO_ENCODER_ERROR;} + + /*return SVA_IMMEDIATE_UPDATE when SVA_UPDATE_LAST*/ + if (updateCmdType == SVA_UPDATE_LAST) {status = SVA_IMMEDIATE_UPDATE;} + + /*update state machine => do nothing*/ + sva_EC_UpdateInstanceStateMachine(instanceNum,SVA_EC_UPDATE_PARAM); + + return status; +} + +/****************************************************************************/ +/* NAME: t_sva_error SVA_GenerateBitStreamDataUnits ( */ +/* t_sva_service_id serviceId, */ +/* t_sva_data_unit_type data_unit_type */ +/* t_sva_data_unit_buffer *pOutBuf */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will generate the SPS and PPS Non VCL NAL units for */ +/* given encoder configuration */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - serviceId: identifier of the service */ +/* - data_unit_type: Type of Data units need to be generated */ +/* */ +/* OUT : */ +/* - pOutBuf: Output Buffer containing newly created SPS and PPS NAL units */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/* - SVA_OK : Command taken into account */ +/* - SVA_UNKNOWN_SERVICE_ID : service id is not correct */ +/* - SVA_UNEXPECTED_API_CALL : Command cannot be excecuted in */ +/* current context. */ +/* - SVA_INTERNAL_VIDEO_ENCODER_ERROR : internal error */ +/* - SVA_INCOHERENT_CONFIGURATION : detected an incoherent conf */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + * DONE +*/ +//\/ Changes by Sarvesh for H264 Encode +PUBLIC t_sva_error SVA_GenerateBitStreamDataUnits( + t_sva_service_id serviceId, + t_sva_data_unit_type data_unit_type, + t_sva_data_unit_buffer *pOutBuf +) +{ + t_sva_error status = SVA_OK; + t_sva_service_instance_num instanceNum = READ_INSTANCE_NUM_IN_SERVICE_ID(serviceId); + t_sva_ec_descriptor *pDesc=&encodeDesc[instanceNum]; + t_sva_ec_algo_error algoError; + + /* Check for service id validity */ + status=sva_EC_CheckServiceId(serviceId); + if (status!=SVA_OK) {return status;} + + /*check that transition is allowed*/ + if (sva_EC_isTransitionValid(instanceNum,SVA_EC_GEN_DATA_UNIT)==FALSE) {return SVA_UNEXPECTED_API_CALL;} + + /* Dispatch to algo part */ + algoError=encodeAlgoDesc[pDesc->algoId].pGenerateBitStreamDataUnits(instanceNum, data_unit_type, pOutBuf); + if (algoError!=SVA_EC_ALGO_OK) {return SVA_VIDEO_ENCODER_DATA_ERROR;} + + + /* Update the state machine */ +//\/ sva_EC_UpdateInstanceStateMachine(instanceNum,SVA_EC_GEN_DATA_UNIT); + + return SVA_OK; +} + +/****************************************************************************/ +/* NAME: t_sva_error sva_EC_Push( */ +/* t_sva_service_id serviceId, */ +/* t_sva_buffer_id bufferId, */ +/* t_sva_push_mode pushMode, */ +/* t_sva_buffer_type bufferType, */ +/* t_sva_timestamp timeStamp */ +/* ) */ +/*--------------------------------------------------------------------------*/ + /* DESCRIPTION: */ + /* This routine allows to push data in an Encode service */ +/* - it will check buffer has enought size according to conf/algo */ +/* - it will push it in the corresponding pushFifo fifo */ +/* - update status of buffer */ +/* - try to solve some dependencies */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - serviceId: identifier of the service */ +/* - bufferId: identifier of the buffer */ +/* - pushMode: PUSH_IN/PUSH_OUT */ +/* - bufferType: */ +/* - timeStamp: */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/* - SVA_OK : Command taken into account */ +/* - SVA_UNKNOWN_SERVICE_ID : service id is not correct */ +/* - SVA_UNEXPECTED_API_CALL : Command cannot be excecuted in */ +/* current context. */ +/* - SVA_INTERNAL_VIDEO_ENCODER_ERROR : internal error */ +/* - SVA_INVALID_BUFFER_TYPE : buffer type is not handle by grab */ +/* - SVA_INTERNAL_FIFOS_FULL : internal fifos are full */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + DONE +*/ +PUBLIC t_sva_error sva_EC_Push( + t_sva_service_id serviceId, + t_sva_buffer_id bufferId, + t_sva_push_mode pushMode, + t_sva_buffer_type bufferType, + t_sva_timestamp timeStamp +) +{ + t_sva_service_instance_num instanceNum = READ_INSTANCE_NUM_IN_SERVICE_ID(serviceId); + t_sva_ec_descriptor *pDesc=&encodeDesc[instanceNum]; + const t_sva_video_encoder_configuration *pConf = &pDesc->conf; + t_sva_error status; + t_sva_bm_error bmError; + t_sva_ff_error ffError; + t_sva_ec_error ecError; + t_size bufferSize; + t_size minSize=0; + + /*check for service id validity*/ + status=sva_EC_CheckServiceId(serviceId); + if (status!=SVA_OK) {return status;} + + /*check that transition is allowed*/ + if (sva_EC_isTransitionValid(instanceNum,SVA_EC_PUSH)==FALSE) {return SVA_UNEXPECTED_API_CALL;} + + /*handle provide buffer*/ + switch(bufferType) + { + case SVA_IMAGE_BUFFER_TYPE: + if (pushMode==SVA_PUSH_IN) + { + minSize = ((((t_uint32)pConf->sourceFrameDesc.frame.height * (t_uint32)pConf->sourceFrameDesc.frame.width)*3)/2); + + /*read buffer size*/ + bmError=sva_BM_GetBufferSize(bufferId,&bufferSize); + if (bmError!=SVA_BM_OK) {return SVA_INTERNAL_VIDEO_ENCODER_ERROR;} + /*check buffer has enought space*/ + if (bufferSize>=minSize) + { + /*check space into fifo*/ + if (GET_FIFO_NB_ELEMS(pDesc->sourceBufferFifos.pushFifo) >= PUSH_FIFO_DEFAULT_SIZE) {status=SVA_INTERNAL_FIFOS_FULL;} + ffError=PUSH_FIFO_ELEM(pDesc->sourceBufferFifos.pushFifo, t_sva_buffer_id, bufferId); + if (ffError!=SVA_FIFO_OK) {status=SVA_INTERNAL_FIFOS_FULL;} + ffError=PUSH_FIFO_ELEM(pDesc->timeStampFifos.pushFifo, t_sva_timestamp, timeStamp); + if (ffError!=SVA_FIFO_OK) {status=SVA_INTERNAL_FIFOS_FULL;} + else + { + pDesc->status.bufferizationStats.inLevel++; + status=SVA_OK; + } + } + else { status=SVA_INTERNAL_VIDEO_ENCODER_ERROR; } + } + else + { + /*destination buffers in external mode*/ + if (pDesc->conf.isDestinationBufferRequested==TRUE) + { + minSize = ((((t_uint32)pConf->sourceFrameDesc.window.image.height * (t_uint32)pConf->sourceFrameDesc.window.image.width)*3)/2); + + /*read buffer size*/ + bmError=sva_BM_GetBufferSize(bufferId,&bufferSize); + if (bmError!=SVA_BM_OK) {return SVA_INTERNAL_VIDEO_ENCODER_ERROR;} + /*check buffer has enought space*/ + if (bufferSize>=minSize) + { + /*check space into fifo*/ + if (GET_FIFO_NB_ELEMS(pDesc->destBufferFifos.pushFifo) >= PUSH_FIFO_DEFAULT_SIZE) {status=SVA_INTERNAL_FIFOS_FULL;} + ffError=PUSH_FIFO_ELEM(pDesc->destBufferFifos.pushFifo, t_sva_buffer_id, bufferId); + if (ffError!=SVA_FIFO_OK) {status=SVA_INTERNAL_FIFOS_FULL;} + if (GET_FIFO_NB_ELEMS(pDesc->fwRefBufferFifos.pushFifo) >= PUSH_FIFO_DEFAULT_SIZE) {status=SVA_INTERNAL_FIFOS_FULL;} + ffError=PUSH_FIFO_ELEM(pDesc->fwRefBufferFifos.pushFifo, t_sva_buffer_id, bufferId); + if (ffError!=SVA_FIFO_OK) {status=SVA_INTERNAL_FIFOS_FULL;} + else {status=SVA_OK;} + } + else { status=SVA_INTERNAL_VIDEO_ENCODER_ERROR; } + } + else {status=SVA_INVALID_BUFFER_TYPE;} + } + break; + case SVA_BITSTREAM_BUFFER_TYPE: + if (GET_FIFO_NB_ELEMS(pDesc->bitstreamBufferFifos.pushFifo) >= PUSH_FIFO_DEFAULT_SIZE) {status=SVA_INTERNAL_FIFOS_FULL;} + ffError=PUSH_FIFO_ELEM(pDesc->bitstreamBufferFifos.pushFifo, t_sva_buffer_id, bufferId); + if (ffError!=SVA_FIFO_OK) {status=SVA_INTERNAL_FIFOS_FULL;} + else + { + pDesc->status.bufferizationStats.outLevel++; + status=SVA_OK; + } + break; + case SVA_INFOS_BUFFER_TYPE: + if (pushMode==SVA_PUSH_OUT) + { + if (pDesc->defaultDep.infoBufferDep==NOT_RESOLVED_DEPENDENCY) + { +#ifdef SVA_USE_GENERIC_ENCODER_INFOS + minSize = sizeof(t_sva_video_encoder_infos); +#else /* SVA_USE_GENERIC_ENCODER_INFOS */ + if (SVA_EC_ALGO_MPEG4 == pDesc->algoId) + { + minSize = sizeof(t_sva_video_encoder_mpeg4_infos); + } + else if (SVA_EC_ALGO_H264 == pDesc->algoId) + { + minSize = sizeof(t_sva_video_encoder_h264_infos); + } +#endif /* SVA_USE_GENERIC_ENCODER_INFOS */ + + /*read buffer size*/ + bmError=sva_BM_GetBufferSize(bufferId,&bufferSize); + if (bmError!=SVA_BM_OK) {return SVA_INTERNAL_VIDEO_ENCODER_ERROR;} + /*check buffer has enought space*/ + if (bufferSize>=minSize) + { + /*check space into fifo*/ + if (GET_FIFO_NB_ELEMS(pDesc->infoBufferFifos.pushFifo) >= PUSH_FIFO_DEFAULT_SIZE) {status=SVA_INTERNAL_FIFOS_FULL;} + ffError=PUSH_FIFO_ELEM(pDesc->infoBufferFifos.pushFifo, t_sva_buffer_id, bufferId); + if (ffError!=SVA_FIFO_OK) {status=SVA_INTERNAL_FIFOS_FULL;} + else {status=SVA_OK;} + } + else { status=SVA_INTERNAL_VIDEO_ENCODER_ERROR; } + } + else {status=SVA_INVALID_BUFFER_TYPE;} + } + else + { + if (pDesc->defaultDep.brcBufferDep==NOT_RESOLVED_DEPENDENCY) + { + minSize = sizeof(t_sva_brc_user_request); + + /*read buffer size*/ + bmError=sva_BM_GetBufferSize(bufferId,&bufferSize); + if (bmError!=SVA_BM_OK) {return SVA_INTERNAL_VIDEO_ENCODER_ERROR;} + /*check buffer has enought space*/ + if (bufferSize>=minSize) + { + /*check space into fifo*/ + if (GET_FIFO_NB_ELEMS(pDesc->brcBufferFifos.pushFifo) >= PUSH_FIFO_DEFAULT_SIZE) {status=SVA_INTERNAL_FIFOS_FULL;} + ffError=PUSH_FIFO_ELEM(pDesc->brcBufferFifos.pushFifo, t_sva_buffer_id, bufferId); + if (ffError!=SVA_FIFO_OK) {status=SVA_INTERNAL_FIFOS_FULL;} + else {status=SVA_OK;} + } + else { status=SVA_INTERNAL_VIDEO_ENCODER_ERROR; } + } + else {status=SVA_INVALID_BUFFER_TYPE;} + } + break; + case SVA_PARAMS_BUFFER_TYPE: + if (pushMode==SVA_PUSH_OUT) + { + if (pDesc->defaultDep.deblockingBufferDep==NOT_RESOLVED_DEPENDENCY) + { +//\/ minSize = ((pConf->sourceFrameDesc.window.image.height/16+2)*(pConf->sourceFrameDesc.window.image.width/16+2)*4+15)&0xfff0; + /* Deblocking parameters */ + if (SVA_EC_ALGO_MPEG4 == pDesc->algoId) + { + minSize=((pConf->sourceFrameDesc.window.image.height/16+2)*(pConf->sourceFrameDesc.window.image.width/16+2)*4+15)&0xfff0; + } + else if (SVA_EC_ALGO_H264 == pDesc->algoId) + { + //\/ minSize = (pH264Desc->picWidthInMbsMinus1+1) * (pH264Desc->picHeightInMapUnitsMinus1+1)* sizeof(t_sva_h264_h4d_param); + minSize=(((pConf->sourceFrameDesc.window.image.height/16)*(pConf->sourceFrameDesc.window.image.width/16)*(sizeof(t_sva_h264_h4d_param)))+15)&0xfff0; + } + + /* Read buffer size */ + bmError=sva_BM_GetBufferSize(bufferId,&bufferSize); + if (bmError!=SVA_BM_OK) {return SVA_INTERNAL_VIDEO_ENCODER_ERROR;} + /*check buffer has enought space*/ + if (bufferSize>=minSize) + { + /*check space into fifo*/ + if (GET_FIFO_NB_ELEMS(pDesc->deblockingBufferFifos.pushFifo) >= PUSH_FIFO_DEFAULT_SIZE) {status=SVA_INTERNAL_FIFOS_FULL;} + ffError=PUSH_FIFO_ELEM(pDesc->deblockingBufferFifos.pushFifo, t_sva_buffer_id, bufferId); + if (ffError!=SVA_FIFO_OK) {status=SVA_INTERNAL_FIFOS_FULL;} + else {status=SVA_OK;} + } + else { status=SVA_INTERNAL_VIDEO_ENCODER_ERROR; } + } + else {status=SVA_INVALID_BUFFER_TYPE;} + } + else + { + if (pDesc->defaultDep.croppingBufferDep==NOT_RESOLVED_DEPENDENCY) + { + minSize = sizeof(t_sva_offset_desc); + + /*read buffer size*/ + bmError=sva_BM_GetBufferSize(bufferId,&bufferSize); + if (bmError!=SVA_BM_OK) {return SVA_INTERNAL_VIDEO_ENCODER_ERROR;} + /*check buffer has enought space*/ + if (bufferSize>=minSize) + { + /*check space into fifo*/ + if (GET_FIFO_NB_ELEMS(pDesc->croppingBufferFifos.pushFifo) >= PUSH_FIFO_DEFAULT_SIZE) {status=SVA_INTERNAL_FIFOS_FULL;} + ffError=PUSH_FIFO_ELEM(pDesc->croppingBufferFifos.pushFifo, t_sva_buffer_id, bufferId); + if (ffError!=SVA_FIFO_OK) {status=SVA_INTERNAL_FIFOS_FULL;} + else {status=SVA_OK;} + } + else { status=SVA_INTERNAL_VIDEO_ENCODER_ERROR; } + } + } + break; + default: + status=SVA_INVALID_BUFFER_TYPE; + break; + } + + /*update state machine*/ + sva_EC_UpdateInstanceStateMachine(instanceNum,SVA_EC_PUSH); + + /*update buffer status if we have succeeded to push it and try to solve dependencies*/ + if (status == SVA_OK) + { + t_uint32 systemTime; + t_sva_error svaError; + + svaError=SVA_GetServiceSystemTime(serviceId,&systemTime); + if (svaError!=SVA_OK) {return SVA_INTERNAL_VIDEO_ENCODER_ERROR;} + bmError=sva_BM_UpdateBufferStatus(bufferId, SVA_BUFFER_IN_USE, systemTime); + if (bmError!=SVA_BM_OK) {return SVA_INTERNAL_VIDEO_ENCODER_ERROR;} + ecError=sva_EC_ResolveDependencies(instanceNum); + if (ecError!=SVA_EC_OK) {return SVA_INTERNAL_VIDEO_ENCODER_ERROR;} + } + + return status; +} + +/****************************************************************************/ +/* NAME: t_sva_error SVA_GetVideoEncoderStatus ( */ +/* t_sva_service_id serviceId, */ +/* t_sva_video_encoder_status * pStatus */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine allows to get status of the encode service */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - serviceId: identifier of the service */ +/* - pStatus: status for the encode service */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/* - SVA_OK : Command taken into account */ +/* - SVA_UNKNOWN_SERVICE_ID : service id is not correct */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + DONE +*/ +PUBLIC t_sva_error SVA_GetVideoEncoderStatus( + t_sva_service_id serviceId, + t_sva_video_encoder_status *pStatus +) +{ + t_sva_service_instance_num instanceNum = READ_INSTANCE_NUM_IN_SERVICE_ID(serviceId); + t_sva_ec_descriptor *pDesc=&encodeDesc[instanceNum]; + t_sva_error status; + + EC_CHECK_NULL_POINTER(pStatus); + + /*check for service id validity*/ + status=sva_EC_CheckServiceId(serviceId); + if (status!=SVA_OK) {return status;} + + /*copy status*/ + *pStatus=pDesc->status; + + return SVA_OK; +} + +/****************************************************************************/ +/* NAME: t_sva_ec_error sva_EC_DispatchVirtualHwEvent( */ +/* t_sva_virtual_hw_event_id eventId, */ +/* t_sva_service_id serviceId, */ +/* t_sva_tm_subtask_id subtaskId, */ +/* t_uint32 eventTimestamp, */ +/* t_uint32 eventDate, */ +/* t_uint8 maxOfEvent, */ +/* t_sva_event_desc *pEventDesc, */ +/* t_uint32 *pNbEvent */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine allows to dispatch event of the encode service */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - eventId: event identifier */ +/* - serviceId: identifier of the service */ +/* - subtaskId: identifier of the subtask for which is the event */ +/* - eventTimestamp: time at which the event occur (system time unit) */ +/* - eventDate: time at which the event occur (ticks time unit) */ +/* - maxOfEvent: nb of event max contained in EventDesc */ +/* - pEventDesc: structure of Events */ +/* - pNbEvent: nb of event into EventDesc */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_ec_error */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + +*/ +PUBLIC t_sva_ec_error sva_EC_DispatchVirtualHwEvent( + t_sva_tm_virtual_hw_event_id eventId, + t_sva_service_id serviceId, + t_sva_tm_subtask_id subtaskId, + t_uint32 eventTimestamp, + t_uint32 eventDate, + t_uint8 maxOfEvent, + t_sva_event_desc *pEventDesc, + t_uint32 *pNbEvent +) +{ + t_sva_service_instance_num instanceNum = READ_INSTANCE_NUM_IN_SERVICE_ID(serviceId); + t_sva_ec_descriptor *pDesc=&encodeDesc[instanceNum]; + t_size bitstreamSizeInBits; + t_sva_error status; + t_sva_tm_error tmError; + t_sva_ff_error ffError; + t_sva_blm_error blmError; + t_sva_ec_algo_error algoError; + t_uint32 nbEventsRaised = 0; + t_sva_ec_subtask_dependencies subTaskDep; + t_sva_buffer_id bufferId=INVALID_BUFFER_ID; + t_sva_tm_subtask_id dummySubtaskId; + t_bool isCurrentStrategicSkip,isCurrentItSkip; + /*t_sva_timestamp emptyTimeStamp={SVA_NO_TIMESTAMP,0};*/ + t_sva_timestamp dummyTimeStamp={SVA_NO_TIMESTAMP,0}; + t_bool isUpdateStateNeed=FALSE; + t_logical_address bitstreamAddr; + t_sva_bm_error bmError; + t_uint32 i; + + EC_CHECK_NULL_POINTER(pEventDesc); + EC_CHECK_NULL_POINTER(pNbEvent); + + (void) maxOfEvent; + (void) dummyTimeStamp; + *pNbEvent=0; + /*check for service id validity*/ + status=sva_EC_CheckServiceId(serviceId); + if (status!=SVA_OK) {return SVA_EC_INVALID_INSTANCE_NB;} + +#ifdef __DEBUG + { + t_uint32 systemTimeDbg; + + SVA_GetServiceSystemTime(serviceId,&systemTimeDbg); + eventEncodeDebugTable[instanceNum].eventDebugDesc[eventEncodeDebugTable[instanceNum].nbOfEventReceived%LOG_DEPTH].event=eventId; + eventEncodeDebugTable[instanceNum].eventDebugDesc[eventEncodeDebugTable[instanceNum].nbOfEventReceived%LOG_DEPTH].systemTime=eventTimestamp; + eventEncodeDebugTable[instanceNum].eventDebugDesc[eventEncodeDebugTable[instanceNum].nbOfEventReceived%LOG_DEPTH].subtaskId=subtaskId; + eventEncodeDebugTable[instanceNum].eventDebugDesc[eventEncodeDebugTable[instanceNum].nbOfEventReceived%LOG_DEPTH].serviceId=serviceId; + eventEncodeDebugTable[instanceNum].eventDebugDesc[eventEncodeDebugTable[instanceNum].nbOfEventReceived%LOG_DEPTH].startHandlingTime=systemTimeDbg; + //eventEncodeDebugTable[instanceNum].nbOfEventReceived++; + } +#endif + + switch(eventId) + { + case SVA_TM_EOT_HW_EVENT: + /* An encode subtask has just finish. We now have to do the following : + * 1) Provide out param and out of inout to algo box + * 2) Get from algo box skip information + * 3) For all buffers + * - various stuff according to skip info/internal or external + * - possibly generate events + * - possibly repush into fifo for internal buffers + * - .... + * 4) Repush subtask in depencencies + */ + /*read param out*/ + tmError=sva_TM_GetSubTaskField(subtaskId,SVA_TM_ENC_ADDR_OUT_PARAMETERS,pDesc->paramOutAddr, + 0,encodeAlgoDesc[pDesc->algoId].pGetParamsOutSize(instanceNum),FALSE); + HCL_DEBUG_ASSERT(tmError==SVA_TM_OK); + /*read param out inout*/ + tmError=sva_TM_GetSubTaskField(subtaskId,SVA_TM_ENC_ADDR_OUT_FRAME_PARAMETERS,pDesc->paramInOutAddr, + 0,encodeAlgoDesc[pDesc->algoId].pGetParamsInOutSize(instanceNum),FALSE); + HCL_DEBUG_ASSERT(tmError==SVA_TM_OK); + /*provide both info to algo box*/ + algoError=encodeAlgoDesc[pDesc->algoId].pSetFrameParamOut(instanceNum,(t_sva_ec_algo_params_out *) pDesc->paramOutAddr, + (t_sva_ec_algo_params_inout *) pDesc->paramInOutAddr); + HCL_DEBUG_ASSERT(algoError==SVA_EC_ALGO_OK); + /*retriewe skip information*/ + algoError=encodeAlgoDesc[pDesc->algoId].pGetSkipInfo(instanceNum,&isCurrentStrategicSkip,&isCurrentItSkip); + HCL_DEBUG_ASSERT(algoError==SVA_EC_ALGO_OK); + /*retriewe bitstream size infos*/ + algoError=encodeAlgoDesc[pDesc->algoId].pGetBitstreamSize(instanceNum,&bitstreamSizeInBits); + HCL_DEBUG_ASSERT(algoError==SVA_EC_ALGO_OK); + /*Sometimes we can have to patch bitstream*/ + tmError=sva_TM_GetSubTaskField(subtaskId,SVA_TM_ENC_ADDR_IN_PARAMETERS,pDesc->paramInAddr, + 0,encodeAlgoDesc[pDesc->algoId].pGetParamsInSize(instanceNum),FALSE); + HCL_DEBUG_ASSERT(tmError==SVA_TM_OK); + ffError=READ_FIFO_ELEM(pDesc->bitstreamBufferFifos.inUseFifo,t_sva_buffer_id,bufferId); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + bmError=sva_BM_GetBufferLogicalAddress(bufferId,&bitstreamAddr); + HCL_DEBUG_ASSERT(bmError==SVA_BM_OK); + algoError=encodeAlgoDesc[pDesc->algoId].pPachBitstream(instanceNum,(t_sva_ec_algo_params_in *)pDesc->paramInAddr,bitstreamAddr); + HCL_DEBUG_ASSERT(algoError==SVA_EC_ALGO_OK); + + /*update status*/ + if (isCurrentStrategicSkip==TRUE || isCurrentItSkip==TRUE) + { + pDesc->status.nbImagesSkipped++; + } + else + { + pDesc->status.nbImagesEncoded++; + pDesc->status.nbBytesEncoded+=(bitstreamSizeInBits+7)/8; + } + + /*pop subtask dep from in use*/ + if (isCurrentItSkip==FALSE) + { + ffError=POP_FIFO_ELEM(pDesc->inUseSubtaskDependency,t_sva_ec_subtask_dependencies,subTaskDep); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + } + + /*handle all buffers*/ + /*source buffers / No dependencies with skip /external only*/ + pDesc->status.eventStats.voidedCounter++; + pDesc->status.bufferizationStats.inLevel--; + ffError=POP_FIFO_ELEM(pDesc->sourceBufferFifos.inUseFifo,t_sva_buffer_id,bufferId); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + ffError=POP_FIFO_ELEM(pDesc->timeStampFifos.inUseFifo,t_sva_timestamp,dummyTimeStamp); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + CHECK_TABLE_OVERFLOW(nbEventsRaised, maxOfEvent, SVA_EC_NOT_SUPPORTED); + pEventDesc[nbEventsRaised].eventId = SVA_EVENT_BUFFER_VOIDED; + pEventDesc[nbEventsRaised].serviceId = serviceId; + pEventDesc[nbEventsRaised].bufferId = bufferId; + pEventDesc[nbEventsRaised].eventTimestamp = (t_sva_timestamp_value) eventTimestamp; + pEventDesc[nbEventsRaised].eventDate = (t_sva_timestamp_value) eventDate; + pEventDesc[nbEventsRaised].extraInfo=0; + nbEventsRaised++; + sva_BM_UpdateBufferStatus(bufferId,SVA_BUFFER_VOIDED,eventTimestamp); + /*cropping buffers / No dependencies with skip /external only*/ + if (pDesc->defaultDep.croppingBufferDep==NOT_RESOLVED_DEPENDENCY) + { + pDesc->status.eventStats.voidedCounter++; + ffError=POP_FIFO_ELEM(pDesc->croppingBufferFifos.inUseFifo,t_sva_buffer_id,bufferId); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + CHECK_TABLE_OVERFLOW(nbEventsRaised, maxOfEvent, SVA_EC_NOT_SUPPORTED); + pEventDesc[nbEventsRaised].eventId = SVA_EVENT_BUFFER_VOIDED; + pEventDesc[nbEventsRaised].serviceId = serviceId; + pEventDesc[nbEventsRaised].bufferId = bufferId; + pEventDesc[nbEventsRaised].eventTimestamp = (t_sva_timestamp_value) eventTimestamp; + pEventDesc[nbEventsRaised].eventDate = (t_sva_timestamp_value) eventDate; + pEventDesc[nbEventsRaised].extraInfo=0; + nbEventsRaised++; + sva_BM_UpdateBufferStatus(bufferId,SVA_BUFFER_VOIDED,eventTimestamp); + } + /*bitstream buffers / dependency with skip /external only*/ + + /* whatever bitstream is skip or not, we have to remove it from buffer list */ + /* Ifit is IT skip then we don't remove it since it will be done on BRC interrupt */ + if (isCurrentItSkip == FALSE) + { + ffError=READ_FIFO_ELEM(pDesc->bitstreamBufferFifos.inUseFifo,t_sva_buffer_id,bufferId); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + blmError=sva_BLM_RemoveBufferFromList(subTaskDep.bufferListId,&bufferId); + HCL_DEBUG_ASSERT(blmError==SVA_BLM_OK); + } + if (isCurrentStrategicSkip==FALSE && isCurrentItSkip==FALSE) + { + pDesc->status.eventStats.filledCounter++; + pDesc->status.bufferizationStats.outLevel--; + ffError=POP_FIFO_ELEM(pDesc->bitstreamBufferFifos.inUseFifo,t_sva_buffer_id,bufferId); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + CHECK_TABLE_OVERFLOW(nbEventsRaised, maxOfEvent, SVA_EC_NOT_SUPPORTED); + pEventDesc[nbEventsRaised].eventId = SVA_EVENT_BUFFER_FILLED; + pEventDesc[nbEventsRaised].serviceId = serviceId; + pEventDesc[nbEventsRaised].bufferId = bufferId; + pEventDesc[nbEventsRaised].eventTimestamp = (t_sva_timestamp_value) eventTimestamp; + pEventDesc[nbEventsRaised].eventDate = (t_sva_timestamp_value) eventDate; + pEventDesc[nbEventsRaised].extraInfo=bitstreamSizeInBits; + nbEventsRaised++; + sva_BM_UpdateBufferStatus(bufferId,SVA_BUFFER_FILLED,eventTimestamp); + } + /*destination buffers / dependency with skip /external or internal*/ + if (isCurrentStrategicSkip==FALSE && isCurrentItSkip==FALSE) + { + ffError=POP_FIFO_ELEM(pDesc->destBufferFifos.inUseFifo,t_sva_buffer_id,bufferId); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + + if (subTaskDep.dependencies.destBufferDep==RESOLVED_DEPENDENCY) + { + /*external buffers only so send an event*/ + pDesc->status.eventStats.readOnlyCounter++; + CHECK_TABLE_OVERFLOW(nbEventsRaised, maxOfEvent, SVA_EC_NOT_SUPPORTED); + pEventDesc[nbEventsRaised].eventId = SVA_EVENT_BUFFER_FILLED_READ_ONLY; + pEventDesc[nbEventsRaised].serviceId = serviceId; + pEventDesc[nbEventsRaised].bufferId=bufferId; + pEventDesc[nbEventsRaised].eventTimestamp = (t_sva_timestamp_value) eventTimestamp; + pEventDesc[nbEventsRaised].eventDate = (t_sva_timestamp_value) eventDate; + pEventDesc[nbEventsRaised].extraInfo=0; + nbEventsRaised++; + } + else + { + ffError=PUSH_FIFO_ELEM(pDesc->destBufferFifos.pushFifo,t_sva_buffer_id,bufferId); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + } + } + /*forward reference buffers / dependency with skip /external or internal*/ + if (isCurrentStrategicSkip==FALSE && isCurrentItSkip==FALSE) + { + /*for first eot we don't pop fifo since no push where done*/ + + if (pDesc->handleForwardInitCnt==1) + { + pDesc->handleForwardInitCnt++; + } + else + { + ffError=POP_FIFO_ELEM(pDesc->fwRefBufferFifos.inUseFifo,t_sva_buffer_id,bufferId); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + if (subTaskDep.dependencies.fwRefBufferDep==RESOLVED_DEPENDENCY) + { + /*external buffers only so send an event*/ + pDesc->status.eventStats.filledCounter++; + CHECK_TABLE_OVERFLOW(nbEventsRaised, maxOfEvent, SVA_EC_NOT_SUPPORTED); + pEventDesc[nbEventsRaised].eventId = SVA_EVENT_BUFFER_FILLED; + pEventDesc[nbEventsRaised].serviceId = serviceId; + pEventDesc[nbEventsRaised].bufferId = bufferId; + pEventDesc[nbEventsRaised].eventTimestamp = (t_sva_timestamp_value) eventTimestamp; + pEventDesc[nbEventsRaised].eventDate = (t_sva_timestamp_value) eventDate; + pEventDesc[nbEventsRaised].extraInfo = 0; + nbEventsRaised++; + sva_BM_UpdateBufferStatus(bufferId,SVA_BUFFER_FILLED,eventTimestamp); + } + else + { + ffError=PUSH_FIFO_ELEM(pDesc->fwRefBufferFifos.pushFifo,t_sva_buffer_id,bufferId); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + } + } + } + /*read intra refresh buffers / dependency with IT skip /internal only*/ + if (isCurrentItSkip==FALSE) + { + ffError=POP_FIFO_ELEM(pDesc->readIntraRefreshBufferFifos.inUseFifo,t_sva_buffer_id,bufferId); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + ffError=PUSH_FIFO_ELEM(pDesc->readIntraRefreshBufferFifos.pushFifo,t_sva_buffer_id,bufferId); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + } + /*write intra refresh buffers / dependency with IT skip /internal only*/ + if (isCurrentItSkip==FALSE) + { + ffError=POP_FIFO_ELEM(pDesc->writeIntraRefreshBufferFifos.inUseFifo,t_sva_buffer_id,bufferId); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + ffError=PUSH_FIFO_ELEM(pDesc->writeIntraRefreshBufferFifos.pushFifo,t_sva_buffer_id,bufferId); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + } + /*infos buffers / dependency with skip /external only*/ + if (isCurrentStrategicSkip==FALSE && isCurrentItSkip==FALSE && pDesc->defaultDep.infoBufferDep==NOT_RESOLVED_DEPENDENCY) + { + pDesc->status.eventStats.filledCounter++; + ffError=POP_FIFO_ELEM(pDesc->infoBufferFifos.inUseFifo,t_sva_buffer_id,bufferId); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + algoError=encodeAlgoDesc[pDesc->algoId].pFillInfosBuffer(instanceNum,bufferId); + HCL_DEBUG_ASSERT(algoError==SVA_EC_ALGO_OK); + CHECK_TABLE_OVERFLOW(nbEventsRaised, maxOfEvent, SVA_EC_NOT_SUPPORTED); + pEventDesc[nbEventsRaised].eventId = SVA_EVENT_BUFFER_FILLED; + pEventDesc[nbEventsRaised].serviceId = serviceId; + pEventDesc[nbEventsRaised].bufferId = bufferId; + pEventDesc[nbEventsRaised].eventTimestamp = (t_sva_timestamp_value) eventTimestamp; + pEventDesc[nbEventsRaised].eventDate = (t_sva_timestamp_value) eventDate; + pEventDesc[nbEventsRaised].extraInfo=0; + nbEventsRaised++; + sva_BM_UpdateBufferStatus(bufferId,SVA_BUFFER_FILLED,eventTimestamp); + } + /*deblocking buffers / dependency with skip /external only*/ + /*when internal all this stuff is n.a*/ + if (isCurrentStrategicSkip==FALSE && isCurrentItSkip==FALSE && pDesc->conf.outTheLoopFilter!=SVA_NONE_FILTER) + { + pDesc->status.eventStats.filledCounter++; + ffError=POP_FIFO_ELEM(pDesc->deblockingBufferFifos.inUseFifo,t_sva_buffer_id,bufferId); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + CHECK_TABLE_OVERFLOW(nbEventsRaised, maxOfEvent, SVA_EC_NOT_SUPPORTED); + pEventDesc[nbEventsRaised].eventId = SVA_EVENT_BUFFER_FILLED; + pEventDesc[nbEventsRaised].serviceId = serviceId; + pEventDesc[nbEventsRaised].bufferId = bufferId; + pEventDesc[nbEventsRaised].eventTimestamp = (t_sva_timestamp_value) eventTimestamp; + pEventDesc[nbEventsRaised].eventDate = (t_sva_timestamp_value) eventDate; + pEventDesc[nbEventsRaised].extraInfo= 0; + nbEventsRaised++; + sva_BM_UpdateBufferStatus(bufferId,SVA_BUFFER_FILLED,eventTimestamp); + } + /*brc Buffers / no skip dependencies since there is no skip in this brc mode*/ + if (pDesc->defaultDep.brcBufferDep==NOT_RESOLVED_DEPENDENCY) + { + pDesc->status.eventStats.voidedCounter++; + ffError=POP_FIFO_ELEM(pDesc->brcBufferFifos.inUseFifo,t_sva_buffer_id,bufferId); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + CHECK_TABLE_OVERFLOW(nbEventsRaised, maxOfEvent, SVA_EC_NOT_SUPPORTED); + pEventDesc[nbEventsRaised].eventId = SVA_EVENT_BUFFER_VOIDED; + pEventDesc[nbEventsRaised].serviceId = serviceId; + pEventDesc[nbEventsRaised].bufferId = bufferId; + pEventDesc[nbEventsRaised].eventTimestamp = (t_sva_timestamp_value) eventTimestamp; + pEventDesc[nbEventsRaised].eventDate = (t_sva_timestamp_value) eventDate; + pEventDesc[nbEventsRaised].extraInfo=0; + nbEventsRaised++; + sva_BM_UpdateBufferStatus(bufferId,SVA_BUFFER_VOIDED,eventTimestamp); + } + + /*repush subtask with default dependencies so it can be programmed and then re-excecuted*/ + /*in case of It skip do not repush it to avoid starting solving new dependencies*/ + if (isCurrentItSkip==FALSE) + { + subTaskDep.dependencies = pDesc->defaultDep; + ffError=PUSH_FIFO_ELEM(pDesc->subtasksDependencyFifo,t_sva_ec_subtask_dependencies,subTaskDep); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + } + break; + case SVA_TM_EOK_HW_EVENT: + /* We can reveive an EOK for the four following reason : + * 1) no more subtask scheduled => OVERFLOW event or/and UNDERFLOW event + * 2) a stop has been requested => SVA_EVENT_SERVICE_STOPPED + * 3) an abort has been requested => SVA_EVENT_SERVICE_ERROR + * 4) a BRC interrupt has occured => no event to user + * Note than reason 1 can arrive at the same time as 2 or 3 or 4 + + */ + isUpdateStateNeed=FALSE; + if (pDesc->state==SVA_EC_STOP_REQUESTED) + { + /*generate a stop event*/ + CHECK_TABLE_OVERFLOW(nbEventsRaised, maxOfEvent, SVA_EC_NOT_SUPPORTED); + pEventDesc[nbEventsRaised].eventId = SVA_EVENT_SERVICE_STOPPED; + pEventDesc[nbEventsRaised].serviceId = serviceId; + pEventDesc[nbEventsRaised].bufferId = INVALID_BUFFER_ID; + pEventDesc[nbEventsRaised].eventTimestamp = (t_sva_timestamp_value) eventTimestamp; + pEventDesc[nbEventsRaised].eventDate = (t_sva_timestamp_value) eventDate; + pEventDesc[nbEventsRaised].extraInfo=0; + nbEventsRaised++; + /*update state*/ + isUpdateStateNeed=TRUE; + } + + if (GET_FIFO_NB_ELEMS(pDesc->subtasksDependencyFifo)==SUBTASK_ENCODE_NUMBER) + { + ffError=READ_FIFO_ELEM(pDesc->subtasksDependencyFifo,t_sva_ec_subtask_dependencies,subTaskDep); + + /*test underflow*/ + if (ffError==SVA_FIFO_OK && + (subTaskDep.dependencies.sourceBufferDep==NOT_RESOLVED_DEPENDENCY || + subTaskDep.dependencies.croppingBufferDep==NOT_RESOLVED_DEPENDENCY || + subTaskDep.dependencies.brcBufferDep==NOT_RESOLVED_DEPENDENCY)) + { + /*we have an underflow*/ + pDesc->status.eventStats.underflowCounter++; + CHECK_TABLE_OVERFLOW(nbEventsRaised, maxOfEvent, SVA_EC_NOT_SUPPORTED); + pEventDesc[nbEventsRaised].eventId = SVA_EVENT_UNDERFLOW; + pEventDesc[nbEventsRaised].serviceId = serviceId; + pEventDesc[nbEventsRaised].bufferId = INVALID_BUFFER_ID; + pEventDesc[nbEventsRaised].eventTimestamp = (t_sva_timestamp_value) eventTimestamp; + pEventDesc[nbEventsRaised].eventDate = (t_sva_timestamp_value) eventDate; + pEventDesc[nbEventsRaised].extraInfo=0; + nbEventsRaised++; + } + + /*test overflow*/ + if (ffError==SVA_FIFO_OK && + (subTaskDep.dependencies.bitstreamBufferDep==NOT_RESOLVED_DEPENDENCY || + subTaskDep.dependencies.infoBufferDep==NOT_RESOLVED_DEPENDENCY || + subTaskDep.dependencies.destBufferDep==NOT_RESOLVED_DEPENDENCY || + subTaskDep.dependencies.deblockingBufferDep==NOT_RESOLVED_DEPENDENCY)) + { + /*we have an overflow*/ + pDesc->status.eventStats.overflowCounter++; + CHECK_TABLE_OVERFLOW(nbEventsRaised, maxOfEvent, SVA_EC_NOT_SUPPORTED); + pEventDesc[nbEventsRaised].eventId = SVA_EVENT_OVERFLOW; + pEventDesc[nbEventsRaised].serviceId = serviceId; + pEventDesc[nbEventsRaised].bufferId = INVALID_BUFFER_ID; + pEventDesc[nbEventsRaised].eventTimestamp = (t_sva_timestamp_value) eventTimestamp; + pEventDesc[nbEventsRaised].eventDate = (t_sva_timestamp_value) eventDate; + pEventDesc[nbEventsRaised].extraInfo=0; + nbEventsRaised++; + } + + /*update state*/ + isUpdateStateNeed=TRUE; + } + if (isUpdateStateNeed==TRUE) + { + /*update state*/ + sva_EC_UpdateInstanceStateMachine(instanceNum,SVA_EC_EVENT_EOK); + } + break; + case SVA_TM_BRC_HW_EVENT: + /* We receive this interrupt since current encoded picture must be skip due to vbv + * Constraint. Instance is stop to avoid excuting next subtask. + * So to recover from such event, idea is to repush every buffer back from inUse + * pushFifo. We also need to repush subtask dependencies so they are solve again. + * We then restart encode task. + * We do the following : + * 1) remove subtask from TM + * 2) reverse pop inUse buffer from fifo and reverse push in the push fifo + * 3) reverse pop subtask from inUse, reset depndencies and reverse push to dep fifo + * 4) empty buffer list + * 5) restart encode + * + * NOTE : brc buffers doesn't appear below because they are use in frame base brc mode and in + * this mode no skip occur. + */ + do + { + tmError=sva_TM_RemoveElemFromSubTaskList(pDesc->subtasksListId,&dummySubtaskId); + } while (tmError==SVA_TM_OK); + /* 2) reverse pop inUse buffer from fifo and reverse push in the push fifo*/ + /*source buffers also have to be repushed back since we will solve again ALL dependencies*/ + do + { + ffError=POP_REVERSE_FIFO_ELEM(pDesc->sourceBufferFifos.inUseFifo,t_sva_buffer_id,bufferId); + if (ffError==SVA_FIFO_OK) + { + ffError=PUSH_REVERSE_FIFO_ELEM(pDesc->sourceBufferFifos.pushFifo,t_sva_buffer_id,bufferId); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + } + } while (ffError==SVA_FIFO_OK); + /*cropping buffers also have to be repushed back since we will solve again ALL dependencies*/ + do + { + ffError=POP_REVERSE_FIFO_ELEM(pDesc->croppingBufferFifos.inUseFifo,t_sva_buffer_id,bufferId); + if (ffError==SVA_FIFO_OK) + { + ffError=PUSH_REVERSE_FIFO_ELEM(pDesc->croppingBufferFifos.pushFifo,t_sva_buffer_id,bufferId); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + } + } while (ffError==SVA_FIFO_OK); + /*timestamps*/ + do + { + t_sva_timestamp timeStamp={SVA_NO_TIMESTAMP,0}; + + ffError=POP_REVERSE_FIFO_ELEM(pDesc->timeStampFifos.inUseFifo,t_sva_timestamp,timeStamp); + if (ffError==SVA_FIFO_OK) + { + ffError=PUSH_REVERSE_FIFO_ELEM(pDesc->timeStampFifos.pushFifo,t_sva_timestamp,timeStamp); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + } + } while (ffError==SVA_FIFO_OK); + /*bitstream buffers*/ + + do + { + ffError=POP_REVERSE_FIFO_ELEM(pDesc->bitstreamBufferFifos.inUseFifo,t_sva_buffer_id,bufferId); + if (ffError==SVA_FIFO_OK) + { + ffError=PUSH_REVERSE_FIFO_ELEM(pDesc->bitstreamBufferFifos.pushFifo,t_sva_buffer_id,bufferId); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + } + } while (ffError==SVA_FIFO_OK); + /*destination buffers*/ + do + { + ffError=POP_REVERSE_FIFO_ELEM(pDesc->destBufferFifos.inUseFifo,t_sva_buffer_id,bufferId); + if (ffError==SVA_FIFO_OK) + { + ffError=PUSH_REVERSE_FIFO_ELEM(pDesc->destBufferFifos.pushFifo,t_sva_buffer_id,bufferId); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + } + } while (ffError==SVA_FIFO_OK); + /*forward reference buffers*/ + do + { + ffError=POP_REVERSE_FIFO_ELEM(pDesc->fwRefBufferFifos.inUseFifo,t_sva_buffer_id,bufferId); + if (ffError==SVA_FIFO_OK) + { + ffError=PUSH_REVERSE_FIFO_ELEM(pDesc->fwRefBufferFifos.pushFifo,t_sva_buffer_id,bufferId); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + } + } while (ffError==SVA_FIFO_OK); + /*read intra refresh buffers*/ + do + { + ffError=POP_REVERSE_FIFO_ELEM(pDesc->readIntraRefreshBufferFifos.inUseFifo,t_sva_buffer_id,bufferId); + if (ffError==SVA_FIFO_OK) + { + ffError=PUSH_REVERSE_FIFO_ELEM(pDesc->readIntraRefreshBufferFifos.pushFifo,t_sva_buffer_id,bufferId); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + } + } while (ffError==SVA_FIFO_OK); + /*write intra refresh buffers*/ + do + { + ffError=POP_REVERSE_FIFO_ELEM(pDesc->writeIntraRefreshBufferFifos.inUseFifo,t_sva_buffer_id,bufferId); + if (ffError==SVA_FIFO_OK) + { + ffError=PUSH_REVERSE_FIFO_ELEM(pDesc->writeIntraRefreshBufferFifos.pushFifo,t_sva_buffer_id,bufferId); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + } + } while (ffError==SVA_FIFO_OK); + /*info buffers*/ + do + { + ffError=POP_REVERSE_FIFO_ELEM(pDesc->infoBufferFifos.inUseFifo,t_sva_buffer_id,bufferId); + if (ffError==SVA_FIFO_OK) + { + ffError=PUSH_REVERSE_FIFO_ELEM(pDesc->infoBufferFifos.pushFifo,t_sva_buffer_id,bufferId); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + } + } while (ffError==SVA_FIFO_OK); + /*deblocking buffers*/ + do + { + ffError=POP_REVERSE_FIFO_ELEM(pDesc->deblockingBufferFifos.inUseFifo,t_sva_buffer_id,bufferId); + if (ffError==SVA_FIFO_OK) + { + ffError=PUSH_REVERSE_FIFO_ELEM(pDesc->deblockingBufferFifos.pushFifo,t_sva_buffer_id,bufferId); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + } + } while (ffError==SVA_FIFO_OK); + /*3) reverse pop subtask from inUse, reset dependencies and push to dep fifo*/ + /*NOTE : push is not reverse to preserve inout connection*/ + /*one subtask not in use can be partially program*/ + /*reset its state*/ + ffError=POP_FIFO_ELEM(pDesc->subtasksDependencyFifo,t_sva_ec_subtask_dependencies,subTaskDep); + subTaskDep.dependencies=pDesc->defaultDep; + if (ffError==SVA_FIFO_OK) + { + ffError=PUSH_FIFO_ELEM(pDesc->subtasksDependencyFifo,t_sva_ec_subtask_dependencies,subTaskDep); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + } + do + { + /*fully set subtask*/ + ffError=POP_REVERSE_FIFO_ELEM(pDesc->inUseSubtaskDependency,t_sva_ec_subtask_dependencies,subTaskDep); + subTaskDep.dependencies=pDesc->defaultDep; + if (ffError==SVA_FIFO_OK) + { + ffError=PUSH_FIFO_ELEM(pDesc->subtasksDependencyFifo,t_sva_ec_subtask_dependencies,subTaskDep); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + } + } while (ffError==SVA_FIFO_OK); + /* When skipped picture is the first one we encode (until we succeed to encode a first picture). In that + * case then we have to set forward reference as been resolved. + */ + if (pDesc->handleForwardInitCnt == 1) + { + ffError=UPDATE_FIFO_ELEM_FIELD(pDesc->subtasksDependencyFifo, + t_sva_ec_subtask_dependencies, .dependencies.fwRefBufferDep, + SOLVE_DEPENDENCY(subTaskDep.dependencies.fwRefBufferDep)); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + } + + /*4) empty buffer list*/ + for(i=0;ibufferListIdArray[i],&bufferId); + } + /*5) restart encode*/ + //tmError=sva_TM_SendTaskCommand(pDesc->subtasksListId,SVA_TM_TCMD_START,(t_uint32) &emptyTimeStamp); + //HCL_DEBUG_ASSERT(tmError==SVA_TM_OK); + + break; + case SVA_TM_FAKE_HW_EVENT: + /*in case of flush out we need to generate filled event for inUse buffers*/ + if (pDesc->conf.isDestinationBufferRequested==TRUE) + { + while(POP_FIFO_ELEM(pDesc->fwRefBufferFifos.inUseFifo,t_sva_buffer_id,bufferId) != SVA_FIFO_EMPTY) + { + /*generate event*/ + CHECK_TABLE_OVERFLOW(nbEventsRaised, maxOfEvent, SVA_EC_NOT_SUPPORTED); + pEventDesc[nbEventsRaised].eventId = SVA_EVENT_BUFFER_FILLED; + pEventDesc[nbEventsRaised].serviceId = serviceId; + pEventDesc[nbEventsRaised].bufferId = bufferId; + pEventDesc[nbEventsRaised].eventTimestamp = (t_sva_timestamp_value) eventTimestamp; + pEventDesc[nbEventsRaised].eventDate = (t_sva_timestamp_value) eventDate; + pEventDesc[nbEventsRaised].extraInfo=0; + nbEventsRaised++; + /*update state*/ + bmError=sva_BM_UpdateBufferStatus(bufferId,SVA_BUFFER_NOT_USED,eventTimestamp); + HCL_DEBUG_ASSERT(bmError==SVA_BM_OK); + } + } + /*add flush event*/ + if (pDesc->state==SVA_EC_FLUSHING_IN) + { + CHECK_TABLE_OVERFLOW(nbEventsRaised, maxOfEvent, SVA_EC_NOT_SUPPORTED); + pEventDesc[nbEventsRaised].eventId = SVA_EVENT_SERVICE_FLUSHED_IN; + } + else + { + CHECK_TABLE_OVERFLOW(nbEventsRaised, maxOfEvent, SVA_EC_NOT_SUPPORTED); + pEventDesc[nbEventsRaised].eventId = SVA_EVENT_SERVICE_FLUSHED_OUT; + } + pEventDesc[nbEventsRaised].serviceId = serviceId; + pEventDesc[nbEventsRaised].bufferId = INVALID_BUFFER_ID; + pEventDesc[nbEventsRaised].eventTimestamp = (t_sva_timestamp_value) eventTimestamp; + pEventDesc[nbEventsRaised].eventDate = (t_sva_timestamp_value) eventDate; + pEventDesc[nbEventsRaised].extraInfo=0; + nbEventsRaised++; + /*update state machine*/ + sva_EC_UpdateInstanceStateMachine(instanceNum,SVA_EC_EVENT_FAKE); + break; + case SVA_TM_ACTIVE_HW_EVENT: + /*add activate event*/ + CHECK_TABLE_OVERFLOW(nbEventsRaised, maxOfEvent, SVA_EC_NOT_SUPPORTED); + pEventDesc[nbEventsRaised].eventId = SVA_EVENT_SERVICE_ACTIVATED; + pEventDesc[nbEventsRaised].serviceId = serviceId; + pEventDesc[nbEventsRaised].bufferId = INVALID_BUFFER_ID; + pEventDesc[nbEventsRaised].eventTimestamp = (t_sva_timestamp_value) eventTimestamp; + pEventDesc[nbEventsRaised].eventDate = (t_sva_timestamp_value) eventDate; + pEventDesc[nbEventsRaised].extraInfo=0; + nbEventsRaised++; + /*update state machine*/ + sva_EC_UpdateInstanceStateMachine(instanceNum,SVA_EC_EVENT_ACTIVE); + break; + case SVA_TM_INACTIVE_HW_EVENT: + /*add inactivate event*/ + CHECK_TABLE_OVERFLOW(nbEventsRaised, maxOfEvent, SVA_EC_NOT_SUPPORTED); + pEventDesc[nbEventsRaised].eventId = SVA_EVENT_SERVICE_INACTIVATED; + pEventDesc[nbEventsRaised].serviceId = serviceId; + pEventDesc[nbEventsRaised].bufferId = INVALID_BUFFER_ID; + pEventDesc[nbEventsRaised].eventTimestamp = (t_sva_timestamp_value) eventTimestamp; + pEventDesc[nbEventsRaised].eventDate = (t_sva_timestamp_value) eventDate; + pEventDesc[nbEventsRaised].extraInfo=0; + nbEventsRaised++; + /*update state machine*/ + sva_EC_UpdateInstanceStateMachine(instanceNum,SVA_EC_EVENT_INACTIVE); + break; + case SVA_TM_EOW_HW_EVENT: + /* send physical stop to avoid others encode stay stuck */ + tmError = sva_TM_SendTaskCommand(pDesc->subtasksListId,SVA_TM_TCMD_STOP_PHYSICAL,0); + HCL_DEBUG_ASSERT(tmError == SVA_TM_OK); + case SVA_TM_ERR_HW_EVENT: + /*add error event*/ + pDesc->status.eventStats.errorCounter++; + CHECK_TABLE_OVERFLOW(nbEventsRaised, maxOfEvent, SVA_EC_NOT_SUPPORTED); + + pEventDesc[nbEventsRaised].eventId = SVA_EVENT_SERVICE_ERROR; + pEventDesc[nbEventsRaised].serviceId = serviceId; + pEventDesc[nbEventsRaised].bufferId = INVALID_BUFFER_ID; + pEventDesc[nbEventsRaised].eventTimestamp = (t_sva_timestamp_value) eventTimestamp; + pEventDesc[nbEventsRaised].eventDate = (t_sva_timestamp_value) eventDate; + if (pDesc->state==SVA_EC_ABORT_REQUESTED) + { + pEventDesc[nbEventsRaised].extraInfo=0; + } + else + { + pEventDesc[nbEventsRaised].extraInfo=(t_uint32)SVA_VIDEO_ENCODER_ERROR_DUMMY; + } + + nbEventsRaised++; + + /*update state machine*/ + sva_EC_UpdateInstanceStateMachine(instanceNum,SVA_EC_EVENT_ERROR); + break; + default: + break; + } + + /*try to solve some dependencies*/ + sva_EC_ResolveDependencies(instanceNum); + + /*return number of generated events*/ + *pNbEvent=nbEventsRaised; + +#ifdef __DEBUG + { + t_uint32 systemTimeDbg; + + SVA_GetServiceSystemTime(serviceId,&systemTimeDbg); + eventEncodeDebugTable[instanceNum].eventDebugDesc[eventEncodeDebugTable[instanceNum].nbOfEventReceived%LOG_DEPTH].stopHandlingTime=systemTimeDbg; + eventEncodeDebugTable[instanceNum].nbOfEventReceived++; + } +#endif + + return SVA_EC_OK; +} + +/****************************************************************************/ +/* NAME: t_sva_error sva_EC_Delete ( */ +/* t_sva_service_id serviceId */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine deletes the encode service */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - serviceId: identifier of the service */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/* - SVA_OK : Command taken into account */ +/* - SVA_UNKNOWN_SERVICE_ID : service id is not correct */ +/* - SVA_UNEXPECTED_API_CALL : Command cannot be excecuted in */ +/* current context. */ +/* - SVA_INTERNAL_VIDEO_ENCODER_ERROR : internal error */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + DONE +*/ +PUBLIC t_sva_error sva_EC_Delete(t_sva_service_id serviceId) +{ + t_sva_service_instance_num instanceNum = READ_INSTANCE_NUM_IN_SERVICE_ID(serviceId); + t_sva_ec_descriptor *pDesc=&encodeDesc[instanceNum]; + t_sva_video_encoder_configuration *pConf = &pDesc->conf; + t_sva_ec_algo_error algoError; + t_sva_buffer_id bufferId=INVALID_BUFFER_ID; + t_sva_tm_error tmError; + t_sva_mm_error mmError; + t_sva_error status; + t_uint32 i; + + (void) bufferId; + /*check for service id validity*/ + status=sva_EC_CheckServiceId(serviceId); + if (status!=SVA_OK) {return status;} + + /*check that transition is allowed*/ + if (sva_EC_isTransitionValid(instanceNum,SVA_EC_CONTROL_DELETE)==FALSE) {return SVA_UNEXPECTED_API_CALL;} + + /*let algo delete it's stuff*/ + algoError=encodeAlgoDesc[pDesc->algoId].pEncodeAlgoDelete(instanceNum); + if (algoError!=SVA_EC_ALGO_OK) {return SVA_INTERNAL_VIDEO_ENCODER_ERROR;} + + /*flush internal fifos*/ + /*destination and forward if internal*/ + if (pDesc->defaultDep.destBufferDep==NOT_RESOLVED_INTERNAL_DEPENDENCY) + { + while(POP_FIFO_ELEM(pDesc->destBufferFifos.pushFifo,t_sva_buffer_id,bufferId) != SVA_FIFO_EMPTY) {;} + while(POP_FIFO_ELEM(pDesc->destBufferFifos.inUseFifo,t_sva_buffer_id,bufferId) != SVA_FIFO_EMPTY) {;} + while(POP_FIFO_ELEM(pDesc->fwRefBufferFifos.pushFifo,t_sva_buffer_id,bufferId) != SVA_FIFO_EMPTY) {;} + while(POP_FIFO_ELEM(pDesc->fwRefBufferFifos.inUseFifo,t_sva_buffer_id,bufferId) != SVA_FIFO_EMPTY) {;} + } + /*read / write intra refresh buffers*/ + while(POP_FIFO_ELEM(pDesc->readIntraRefreshBufferFifos.pushFifo,t_sva_buffer_id,bufferId) != SVA_FIFO_EMPTY) {;} + while(POP_FIFO_ELEM(pDesc->readIntraRefreshBufferFifos.inUseFifo,t_sva_buffer_id,bufferId) != SVA_FIFO_EMPTY) {;} + while(POP_FIFO_ELEM(pDesc->writeIntraRefreshBufferFifos.pushFifo,t_sva_buffer_id,bufferId) != SVA_FIFO_EMPTY) {;} + while(POP_FIFO_ELEM(pDesc->writeIntraRefreshBufferFifos.inUseFifo,t_sva_buffer_id,bufferId) != SVA_FIFO_EMPTY) {;} + + /*check that flush has been done*/ + if (IS_FIFO_EMPTY(pDesc->sourceBufferFifos.pushFifo)==FALSE) {return SVA_INTERNAL_VIDEO_ENCODER_ERROR;} + if (IS_FIFO_EMPTY(pDesc->sourceBufferFifos.inUseFifo)==FALSE) {return SVA_INTERNAL_VIDEO_ENCODER_ERROR;} + if (IS_FIFO_EMPTY(pDesc->timeStampFifos.pushFifo)==FALSE) {return SVA_INTERNAL_VIDEO_ENCODER_ERROR;} + if (IS_FIFO_EMPTY(pDesc->timeStampFifos.inUseFifo)==FALSE) {return SVA_INTERNAL_VIDEO_ENCODER_ERROR;} + if (IS_FIFO_EMPTY(pDesc->bitstreamBufferFifos.pushFifo)==FALSE) {return SVA_INTERNAL_VIDEO_ENCODER_ERROR;} + if (IS_FIFO_EMPTY(pDesc->bitstreamBufferFifos.inUseFifo)==FALSE) {return SVA_INTERNAL_VIDEO_ENCODER_ERROR;} + if (IS_FIFO_EMPTY(pDesc->destBufferFifos.pushFifo)==FALSE) {return SVA_INTERNAL_VIDEO_ENCODER_ERROR;} + if (IS_FIFO_EMPTY(pDesc->destBufferFifos.inUseFifo)==FALSE) {return SVA_INTERNAL_VIDEO_ENCODER_ERROR;} + if (IS_FIFO_EMPTY(pDesc->fwRefBufferFifos.pushFifo)==FALSE) {return SVA_INTERNAL_VIDEO_ENCODER_ERROR;} + if (IS_FIFO_EMPTY(pDesc->fwRefBufferFifos.inUseFifo)==FALSE) {return SVA_INTERNAL_VIDEO_ENCODER_ERROR;} + if (IS_FIFO_EMPTY(pDesc->readIntraRefreshBufferFifos.pushFifo)==FALSE) {return SVA_INTERNAL_VIDEO_ENCODER_ERROR;} + if (IS_FIFO_EMPTY(pDesc->readIntraRefreshBufferFifos.inUseFifo)==FALSE) {return SVA_INTERNAL_VIDEO_ENCODER_ERROR;} + if (IS_FIFO_EMPTY(pDesc->writeIntraRefreshBufferFifos.pushFifo)==FALSE) {return SVA_INTERNAL_VIDEO_ENCODER_ERROR;} + if (IS_FIFO_EMPTY(pDesc->writeIntraRefreshBufferFifos.inUseFifo)==FALSE) {return SVA_INTERNAL_VIDEO_ENCODER_ERROR;} + if (IS_FIFO_EMPTY(pDesc->infoBufferFifos.pushFifo)==FALSE) {return SVA_INTERNAL_VIDEO_ENCODER_ERROR;} + if (IS_FIFO_EMPTY(pDesc->infoBufferFifos.inUseFifo)==FALSE) {return SVA_INTERNAL_VIDEO_ENCODER_ERROR;} + if (IS_FIFO_EMPTY(pDesc->deblockingBufferFifos.inUseFifo)==FALSE) {return SVA_INTERNAL_VIDEO_ENCODER_ERROR;} + if (IS_FIFO_EMPTY(pDesc->deblockingBufferFifos.inUseFifo)==FALSE) {return SVA_INTERNAL_VIDEO_ENCODER_ERROR;} + if (IS_FIFO_EMPTY(pDesc->croppingBufferFifos.inUseFifo)==FALSE) {return SVA_INTERNAL_VIDEO_ENCODER_ERROR;} + if (IS_FIFO_EMPTY(pDesc->croppingBufferFifos.inUseFifo)==FALSE) {return SVA_INTERNAL_VIDEO_ENCODER_ERROR;} + if (IS_FIFO_EMPTY(pDesc->brcBufferFifos.inUseFifo)==FALSE) {return SVA_INTERNAL_VIDEO_ENCODER_ERROR;} + if (IS_FIFO_EMPTY(pDesc->brcBufferFifos.inUseFifo)==FALSE) {return SVA_INTERNAL_VIDEO_ENCODER_ERROR;} + + /*start to delete. Things to do depend of current state*/ + if (pDesc->state==SVA_EC_WAIT_FOR_ACTIVATE || pDesc->state==SVA_EC_WAIT_FOR_START) + { + /*delete fifos*/ + DELETE_FIFO(pDesc->sourceBufferFifos.pushFifo); + DELETE_FIFO(pDesc->sourceBufferFifos.inUseFifo); + DELETE_FIFO(pDesc->timeStampFifos.pushFifo); + DELETE_FIFO(pDesc->timeStampFifos.inUseFifo); + DELETE_FIFO(pDesc->bitstreamBufferFifos.pushFifo); + DELETE_FIFO(pDesc->bitstreamBufferFifos.inUseFifo); + DELETE_FIFO(pDesc->destBufferFifos.pushFifo); + DELETE_FIFO(pDesc->destBufferFifos.inUseFifo); + DELETE_FIFO(pDesc->fwRefBufferFifos.pushFifo); + DELETE_FIFO(pDesc->fwRefBufferFifos.inUseFifo); + DELETE_FIFO(pDesc->readIntraRefreshBufferFifos.pushFifo); + DELETE_FIFO(pDesc->readIntraRefreshBufferFifos.inUseFifo); + DELETE_FIFO(pDesc->writeIntraRefreshBufferFifos.pushFifo); + DELETE_FIFO(pDesc->writeIntraRefreshBufferFifos.inUseFifo); + DELETE_FIFO(pDesc->infoBufferFifos.pushFifo); + DELETE_FIFO(pDesc->infoBufferFifos.inUseFifo); + DELETE_FIFO(pDesc->deblockingBufferFifos.inUseFifo); + DELETE_FIFO(pDesc->deblockingBufferFifos.inUseFifo); + DELETE_FIFO(pDesc->croppingBufferFifos.inUseFifo); + DELETE_FIFO(pDesc->croppingBufferFifos.inUseFifo); + DELETE_FIFO(pDesc->brcBufferFifos.inUseFifo); + DELETE_FIFO(pDesc->brcBufferFifos.inUseFifo); + DELETE_FIFO(pDesc->subtasksDependencyFifo); + DELETE_FIFO(pDesc->inUseSubtaskDependency); + + /*delete subtasklist*/ + tmError=sva_TM_DeleteSubTaskList(pDesc->subtasksListId); + if (tmError!=SVA_TM_OK) {return SVA_INTERNAL_VIDEO_ENCODER_ERROR;} + /*delete subtasks*/ + for(i=0;ibufferListIdArray[i]); + if (blmError!=SVA_BLM_OK) {return SVA_INTERNAL_VIDEO_ENCODER_ERROR;} + /*delete subtask*/ + tmError=sva_TM_DeleteSubTask(pDesc->subtasksIdArray[i]); + if (tmError!=SVA_TM_OK) {return SVA_INTERNAL_VIDEO_ENCODER_ERROR;} + } + + /*delete internal video memory use*/ + for(i=0;idefaultDep.destBufferDep==NOT_RESOLVED_INTERNAL_DEPENDENCY) + { + status=SVA_FreeBuffer(pDesc->destRefBufferIdArray[i]); + if (status!=SVA_OK) {return SVA_INTERNAL_VIDEO_ENCODER_ERROR;} + } + /*delete buffers use for intra refresh buffers*/ + status=SVA_FreeBuffer(pDesc->intraRefreshBufferIdArray[i]); + if (status!=SVA_OK) {return SVA_INTERNAL_VIDEO_ENCODER_ERROR;} + } + + /*delete header buffers*/ + for(i=0;iheaderBufferBlockIdArray[i]); + if (mmError!=SVA_MM_OK) {return SVA_INTERNAL_VIDEO_ENCODER_ERROR;} + } + + /*delete motion buffer*/ + mmError=sva_MM_FreeBlock(pDesc->motionBufferBlockId); + if (mmError!=SVA_MM_OK) {return SVA_INTERNAL_VIDEO_ENCODER_ERROR;} + + /*delete deblocking buffer if needed*/ + if (pConf->inTheLoopFilter!=SVA_NONE_FILTER && pConf->outTheLoopFilter==SVA_NONE_FILTER) + { + mmError=sva_MM_FreeBlock(pDesc->deblockingBufferBlockId); + if (mmError!=SVA_MM_OK) {return SVA_INTERNAL_VIDEO_ENCODER_ERROR;} + } + } + + /*delete descriptor use by memory management*/ + status=sva_EM_Delete(serviceId); + if (status!=SVA_OK) {return status;} + + /*reset descriptors*/ + sva_EC_ResetDescriptor(pDesc); + + /* Update the state machine */ + sva_EC_UpdateInstanceStateMachine(instanceNum,SVA_EC_CONTROL_DELETE); + + return SVA_OK; +} + +/****************************************************************************/ +/* NAME: t_sva_error sva_EC_GetParamsBufferSize ( */ +/* t_sva_service_id serviceId, */ +/* t_sva_push_mode mode, */ +/* t_size *pSize */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine return need buffer size in bytes for params buffers. */ +/* If mode is SVA_PUSH_IN then return size for cropping vector buffer */ +/* else return size for deblocking buffers. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - serviceId: identifier of the service */ +/* - mode: allow to differentiate in and out buffers */ +/* */ +/* OUT : */ +/* - pSize: needed size in bytes for buffers in in or out */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/* - SVA_OK : Command taken into account */ +/* - SVA_UNKNOWN_SERVICE_ID : service id is not correct */ +/* - SVA_UNEXPECTED_API_CALL : Command cannot be excecuted in */ +/* current context. */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + TODO : + - do we have to return zero when param is not use ? +*/ +PUBLIC t_sva_error sva_EC_GetParamsBufferSize( + t_sva_service_id serviceId, + t_sva_push_mode mode, + t_size *pSize +) +{ + t_sva_service_instance_num instanceNum = READ_INSTANCE_NUM_IN_SERVICE_ID(serviceId); + t_sva_ec_descriptor *pDesc=&encodeDesc[instanceNum]; + t_sva_video_encoder_configuration *pConf = &pDesc->conf; + t_sva_error status; + HCL_ASSERT(pSize!=NULL); + + /*check for service id validity*/ + status=sva_EC_CheckServiceId(serviceId); + if (status!=SVA_OK) {return status;} + + /*check that transition is allowed*/ + if (sva_EC_isTransitionValid(instanceNum,SVA_EC_GET_PARAM_SIZE)==FALSE) {return SVA_UNEXPECTED_API_CALL;} + + /*get size to return in bytes*/ + if (mode==SVA_PUSH_IN) + { + /*cropping parameters*/ + *pSize=sizeof(t_sva_offset_desc); + } + else + { + /*deblocking parameters*/ + if (SVA_EC_ALGO_MPEG4 == pDesc->algoId) + { + *pSize=((pConf->sourceFrameDesc.window.image.height/16+2)*(pConf->sourceFrameDesc.window.image.width/16+2)*4+15)&0xfff0; + } + else if (SVA_EC_ALGO_H264 == pDesc->algoId) + { + //\/ *pSize = (pH264Desc->picWidthInMbsMinus1+1) * (pH264Desc->picHeightInMapUnitsMinus1+1)* sizeof(t_sva_h264_h4d_param); + *pSize=(((pConf->sourceFrameDesc.window.image.height/16)*(pConf->sourceFrameDesc.window.image.width/16)*(sizeof(t_sva_h264_h4d_param)))+15)&0xfff0; + } +//\/ *pSize=((pConf->sourceFrameDesc.window.image.height/16+2)*(pConf->sourceFrameDesc.window.image.width/16+2)*4+15)&0xfff0; +//\/ *pSize = (pH264Desc->picWidthInMbsMinus1+1) * (pH264Desc->picHeightInMapUnitsMinus1+1)* sizeof(t_sva_h264_h4d_param); +//\/ *pSize=((pConf->sourceFrameDesc.window.image.height/16)*(pConf->sourceFrameDesc.window.image.width/16)*(sizeof(t_sva_h264_h4d_param))); +//\/ *pSize=(((pConf->sourceFrameDesc.window.image.height/16)*(pConf->sourceFrameDesc.window.image.width/16)*(sizeof(t_sva_h264_h4d_param)))+15)&0xfff0; + } + + /* Update the state machine */ + sva_EC_UpdateInstanceStateMachine(instanceNum,SVA_EC_GET_PARAM_SIZE); + + return SVA_OK; +} + + +/****************************************************************************/ +/* NAME: t_sva_error sva_EC_ResolveDependencies( */ +/* t_sva_service_instance_num instanceNum */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* */ +/* This routine is called in hv_GB_Push and after specific event like EOT */ +/* */ +/* PARAMETERS: */ +/* IN : none */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: t_sva_gb_error */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + TODO : use a macro to compute field offsets +*/ +PRIVATE t_sva_ec_error sva_EC_ResolveDependencies +( + t_sva_service_instance_num instanceNum +) +{ + t_sva_ec_descriptor *pDesc=&encodeDesc[instanceNum]; + t_bool dependencyNotSolved=FALSE; + t_sva_buffer_id bufferId=INVALID_BUFFER_ID; + t_sva_ec_subtask_dependencies subTaskDep; + t_sva_ff_error ffError; + t_sva_tm_error tmError; + + /*check that transition is valid*/ + if (sva_EC_isTransitionValid(instanceNum,SVA_EC_ALL_DEPENDENCIES_RESOLVED)==FALSE) {return SVA_EC_INVALID_TRANSITION;} + + /*enter loop where we try to solve dep for a maximum of subtasks*/ + while(IS_FIFO_EMPTY(pDesc->subtasksDependencyFifo)==FALSE && dependencyNotSolved==FALSE) + { + /*read subtask for which we will try to solve dependencies*/ + ffError=READ_FIFO_ELEM(pDesc->subtasksDependencyFifo,t_sva_ec_subtask_dependencies,subTaskDep); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + + /*try to solve dep*/ + if (IS_DEPENDENCY_SOLVED(subTaskDep.dependencies.brcAlgoDep)==FALSE) + { + /* + * this virtual dependency is always solve. It's use to insure that call to + * pIsPreviousPictureWasStategicSkip() has been done. + */ + /*update subtask dependency as in use*/ + ffError=UPDATE_FIFO_ELEM_FIELD(pDesc->subtasksDependencyFifo, + t_sva_ec_subtask_dependencies, .dependencies.brcAlgoDep, + SOLVE_DEPENDENCY(subTaskDep.dependencies.brcAlgoDep)); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + /*line below is not really usefull*/ + subTaskDep.dependencies.brcAlgoDep = SOLVE_DEPENDENCY(subTaskDep.dependencies.brcAlgoDep); + /*get info about the fact that previous picture was strategic skip*/ + subTaskDep.isPrevSubTaskStrategicSkipped = encodeAlgoDesc[pDesc->algoId].pIsPreviousPictureWasStategicSkip(instanceNum); + /*update subtask info about skipping*/ + ffError=UPDATE_FIFO_ELEM_FIELD(pDesc->subtasksDependencyFifo, + t_sva_ec_subtask_dependencies, .isPrevSubTaskStrategicSkipped, + subTaskDep.isPrevSubTaskStrategicSkipped); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + } + if (IS_DEPENDENCY_SOLVED(subTaskDep.dependencies.sourceBufferDep)==FALSE) + { + if (POP_FIFO_ELEM(pDesc->sourceBufferFifos.pushFifo,t_sva_buffer_id,bufferId) != SVA_FIFO_EMPTY) + { + t_sva_vec_frame_buffer_in frameBufferIn; + t_physical_address bufferAddr; + t_sva_bm_error bmError; + + /*we can resolve source Buffer dependency, so we do it*/ + /*push the source Buffer in the in use fifo*/ + ffError=PUSH_FIFO_ELEM(pDesc->sourceBufferFifos.inUseFifo,t_sva_buffer_id,bufferId); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + /*pop and push for time stamp info*/ + ffError=POP_FIFO_ELEM(pDesc->timeStampFifos.pushFifo,t_sva_timestamp,subTaskDep.timeStamp); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + ffError=PUSH_FIFO_ELEM(pDesc->timeStampFifos.inUseFifo,t_sva_timestamp,subTaskDep.timeStamp); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + /*update time stamp subtask field*/ + ffError=UPDATE_FIFO_ELEM_FIELD(pDesc->subtasksDependencyFifo, + t_sva_ec_subtask_dependencies, .timeStamp, + subTaskDep.timeStamp); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + /*update subtask dependency as in use*/ + ffError=UPDATE_FIFO_ELEM_FIELD(pDesc->subtasksDependencyFifo, + t_sva_ec_subtask_dependencies, .dependencies.sourceBufferDep, + SOLVE_DEPENDENCY(subTaskDep.dependencies.sourceBufferDep)); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + subTaskDep.dependencies.sourceBufferDep = SOLVE_DEPENDENCY(subTaskDep.dependencies.sourceBufferDep); + /*update field in the task list*/ + bmError=sva_BM_GetBufferPhysicalAddress(bufferId,&bufferAddr); + HCL_DEBUG_ASSERT(bmError==SVA_BM_OK); + frameBufferIn.addr_source_buffer=bufferAddr; + /*update this field in subtask*/ + tmError=sva_TM_UpdateSubTaskField(SVA_TM_INTERMEDIATE_FIELD_TO_UPDATE,/*don't take sem since task is not scheduled*/ + subTaskDep.subtaskId, SVA_TM_ENC_ADDR_IN_FRAME_BUFFER, + FCMD_COPY,(t_uint32) &frameBufferIn.addr_source_buffer,HCL_BITFIELD_OFFSET(t_sva_vec_frame_buffer_in,addr_source_buffer), + sizeof(frameBufferIn.addr_source_buffer)); + HCL_DEBUG_ASSERT(tmError==SVA_TM_OK); + } + } + if (IS_DEPENDENCY_SOLVED(subTaskDep.dependencies.croppingBufferDep)==FALSE) + { + if (POP_FIFO_ELEM(pDesc->croppingBufferFifos.pushFifo,t_sva_buffer_id,bufferId) != SVA_FIFO_EMPTY) + { + t_logical_address bufferAddr; + t_sva_bm_error bmError; + + /*we can resolve source Buffer dependency, so we do it*/ + /*push the source Buffer in the in use fifo*/ + ffError=PUSH_FIFO_ELEM(pDesc->croppingBufferFifos.inUseFifo,t_sva_buffer_id,bufferId); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + /*cast buffer onto a cropping vector*/ + bmError=sva_BM_GetBufferLogicalAddress(bufferId,&bufferAddr); + HCL_DEBUG_ASSERT(bmError==SVA_BM_OK); + subTaskDep.croppingVector=*((t_sva_offset_desc *) bufferAddr); + /*update cropping vector in subtaskdep*/ + ffError=UPDATE_FIFO_ELEM_FIELD(pDesc->subtasksDependencyFifo, + t_sva_ec_subtask_dependencies, .croppingVector, + subTaskDep.croppingVector); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + /*update subtask dependency as in use*/ + ffError=UPDATE_FIFO_ELEM_FIELD(pDesc->subtasksDependencyFifo, + t_sva_ec_subtask_dependencies, .dependencies.croppingBufferDep, + SOLVE_DEPENDENCY(subTaskDep.dependencies.croppingBufferDep)); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + subTaskDep.dependencies.croppingBufferDep = SOLVE_DEPENDENCY(subTaskDep.dependencies.croppingBufferDep); + } + } + if (IS_DEPENDENCY_SOLVED(subTaskDep.dependencies.bitstreamBufferDep)==FALSE) + { + if (subTaskDep.isPrevSubTaskStrategicSkipped==TRUE || + POP_FIFO_ELEM(pDesc->bitstreamBufferFifos.pushFifo,t_sva_buffer_id,bufferId) != SVA_FIFO_EMPTY) + { + t_sva_blm_error blmError; + t_sva_bitstream_buffer_pos bitstreamBufferPos; + t_sva_bm_error bmError; + + /*if we handle a strategic skip then read in the in use fifo*/ + if (subTaskDep.isPrevSubTaskStrategicSkipped==TRUE) + { + ffError=READ_FIFO_ELEM(pDesc->bitstreamBufferFifos.inUseFifo,t_sva_buffer_id,bufferId); + } + else /*buffer id comes from push fifo so set it has being in use*/ + { + ffError=PUSH_FIFO_ELEM(pDesc->bitstreamBufferFifos.inUseFifo,t_sva_buffer_id,bufferId); + } + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + /*update subtask dependency as in use*/ + ffError=UPDATE_FIFO_ELEM_FIELD(pDesc->subtasksDependencyFifo, + t_sva_ec_subtask_dependencies, .dependencies.bitstreamBufferDep, + SOLVE_DEPENDENCY(subTaskDep.dependencies.bitstreamBufferDep)); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + subTaskDep.dependencies.bitstreamBufferDep= SOLVE_DEPENDENCY(subTaskDep.dependencies.bitstreamBufferDep); + /*update field in the task list*/ + blmError=sva_BLM_AddBufferInList(subTaskDep.bufferListId,bufferId); + HCL_DEBUG_ASSERT(blmError==SVA_BLM_OK); + /*update field in subtask*/ + blmError=sva_BLM_GetBufferListPhysicalAddress(subTaskDep.bufferListId,&bitstreamBufferPos.addr_bitstream_buf_struct); + HCL_DEBUG_ASSERT(blmError==SVA_BLM_OK); + bmError=sva_BM_GetBufferPhysicalAddress(bufferId,&bitstreamBufferPos.addr_bitstream_start); + HCL_DEBUG_ASSERT(bmError==SVA_BM_OK); + bitstreamBufferPos.bitstream_offset=0; + tmError=sva_TM_InitSubTaskField(subTaskDep.subtaskId, SVA_TM_ENC_ADDR_IN_BITSTREAM_BUFFER, + (t_logical_address) &bitstreamBufferPos, sizeof(bitstreamBufferPos)); + HCL_DEBUG_ASSERT(tmError==SVA_TM_OK); + } + } + if (IS_DEPENDENCY_SOLVED(subTaskDep.dependencies.destBufferDep)==FALSE) + { + if (subTaskDep.isPrevSubTaskStrategicSkipped==TRUE || + POP_FIFO_ELEM(pDesc->destBufferFifos.pushFifo,t_sva_buffer_id,bufferId) != SVA_FIFO_EMPTY) + { + t_sva_vec_frame_buffer_out frameBufferOut; + t_physical_address bufferAddr; + t_sva_bm_error bmError; + + /*if we handle a strategic skip then read in the in use fifo*/ + if (subTaskDep.isPrevSubTaskStrategicSkipped==TRUE) + { + ffError=READ_FIFO_ELEM(pDesc->destBufferFifos.inUseFifo,t_sva_buffer_id,bufferId); + } + else /*buffer id comes from push fifo so set it has being in use*/ + { + ffError=PUSH_FIFO_ELEM(pDesc->destBufferFifos.inUseFifo,t_sva_buffer_id,bufferId); + } + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + /*update subtask dependency as in use*/ + ffError=UPDATE_FIFO_ELEM_FIELD(pDesc->subtasksDependencyFifo, + t_sva_ec_subtask_dependencies, .dependencies.destBufferDep, + SOLVE_DEPENDENCY(subTaskDep.dependencies.destBufferDep)); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + subTaskDep.dependencies.destBufferDep=SOLVE_DEPENDENCY(subTaskDep.dependencies.destBufferDep); + /*update field in the task list*/ + bmError=sva_BM_GetBufferPhysicalAddress(bufferId,&bufferAddr); + HCL_DEBUG_ASSERT(bmError==SVA_BM_OK); + frameBufferOut.addr_dest_buffer=bufferAddr; + /*update this field in subtask*/ + tmError=sva_TM_UpdateSubTaskField(SVA_TM_INTERMEDIATE_FIELD_TO_UPDATE,/*don't take sem since task is not scheduled*/ + subTaskDep.subtaskId, SVA_TM_ENC_ADDR_OUT_FRAME_BUFFER, + FCMD_COPY,(t_uint32) &frameBufferOut.addr_dest_buffer,HCL_BITFIELD_OFFSET(t_sva_vec_frame_buffer_out,addr_dest_buffer), + sizeof(frameBufferOut.addr_dest_buffer)); + HCL_DEBUG_ASSERT(tmError==SVA_TM_OK); + /*handle forward reference buffer for first picture*/ + if (pDesc->handleForwardInitCnt==0) + { + t_sva_vec_frame_buffer_in frameBufferIn; + + /*increment counter to avoid to return here*/ + pDesc->handleForwardInitCnt++; + /*set forward reference buffer address to the same value as destination buffer*/ + /*This will work since motion estimation is deon before encoding*/ + frameBufferIn.addr_fwd_ref_buffer=frameBufferOut.addr_dest_buffer; + tmError=sva_TM_UpdateSubTaskField(SVA_TM_INTERMEDIATE_FIELD_TO_UPDATE,/*don't take sem since task is not scheduled*/ + subTaskDep.subtaskId, SVA_TM_ENC_ADDR_IN_FRAME_BUFFER, + FCMD_COPY,(t_uint32) &frameBufferIn.addr_fwd_ref_buffer,HCL_BITFIELD_OFFSET(t_sva_vec_frame_buffer_in,addr_fwd_ref_buffer), + sizeof(frameBufferIn.addr_fwd_ref_buffer)); + HCL_DEBUG_ASSERT(tmError==SVA_TM_OK); + } + } + } + if (IS_DEPENDENCY_SOLVED(subTaskDep.dependencies.fwRefBufferDep)==FALSE) + { + if (subTaskDep.isPrevSubTaskStrategicSkipped==TRUE || + POP_FIFO_ELEM(pDesc->fwRefBufferFifos.pushFifo,t_sva_buffer_id,bufferId) != SVA_FIFO_EMPTY) + { + t_sva_vec_frame_buffer_in frameBufferIn; + t_physical_address bufferAddr; + t_sva_bm_error bmError; + + /*if we handle a strategic skip then read in the in use fifo*/ + if (subTaskDep.isPrevSubTaskStrategicSkipped==TRUE) + { + ffError=READ_FIFO_ELEM(pDesc->fwRefBufferFifos.inUseFifo,t_sva_buffer_id,bufferId); + } + else /*buffer id comes from push fifo so set it has being in use*/ + { + ffError=PUSH_FIFO_ELEM(pDesc->fwRefBufferFifos.inUseFifo,t_sva_buffer_id,bufferId); + } + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + /*update subtask dependency as in use*/ + ffError=UPDATE_FIFO_ELEM_FIELD(pDesc->subtasksDependencyFifo, + t_sva_ec_subtask_dependencies, .dependencies.fwRefBufferDep, + SOLVE_DEPENDENCY(subTaskDep.dependencies.fwRefBufferDep)); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + subTaskDep.dependencies.fwRefBufferDep=SOLVE_DEPENDENCY(subTaskDep.dependencies.fwRefBufferDep); + /*update field in the task list*/ + bmError=sva_BM_GetBufferPhysicalAddress(bufferId,&bufferAddr); + HCL_DEBUG_ASSERT(bmError==SVA_BM_OK); + frameBufferIn.addr_fwd_ref_buffer=bufferAddr; + /*update this field in subtask*/ + tmError=sva_TM_UpdateSubTaskField(SVA_TM_INTERMEDIATE_FIELD_TO_UPDATE,/*don't take sem since task is not scheduled*/ + subTaskDep.subtaskId, SVA_TM_ENC_ADDR_IN_FRAME_BUFFER, + FCMD_COPY,(t_uint32) &frameBufferIn.addr_fwd_ref_buffer,HCL_BITFIELD_OFFSET(t_sva_vec_frame_buffer_in,addr_fwd_ref_buffer), + sizeof(frameBufferIn.addr_fwd_ref_buffer)); + HCL_DEBUG_ASSERT(tmError==SVA_TM_OK); + } + } + if (IS_DEPENDENCY_SOLVED(subTaskDep.dependencies.readIntraRefreshBufferDep)==FALSE) + { + if (POP_FIFO_ELEM(pDesc->readIntraRefreshBufferFifos.pushFifo,t_sva_buffer_id,bufferId) != SVA_FIFO_EMPTY) + { + t_sva_vec_frame_buffer_in frameBufferIn; + t_physical_address bufferAddr; + t_sva_bm_error bmError; + + ffError=PUSH_FIFO_ELEM(pDesc->readIntraRefreshBufferFifos.inUseFifo,t_sva_buffer_id,bufferId); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + /*update subtask dependency as in use*/ + ffError=UPDATE_FIFO_ELEM_FIELD(pDesc->subtasksDependencyFifo, + t_sva_ec_subtask_dependencies, .dependencies.readIntraRefreshBufferDep, + SOLVE_DEPENDENCY(subTaskDep.dependencies.readIntraRefreshBufferDep)); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + subTaskDep.dependencies.readIntraRefreshBufferDep=SOLVE_DEPENDENCY(subTaskDep.dependencies.readIntraRefreshBufferDep); + /*update field in the task list*/ + bmError=sva_BM_GetBufferPhysicalAddress(bufferId,&bufferAddr); + HCL_DEBUG_ASSERT(bmError==SVA_BM_OK); + frameBufferIn.addr_intra_refresh_buffer=bufferAddr; + /*update this field in subtask*/ + tmError=sva_TM_UpdateSubTaskField(SVA_TM_INTERMEDIATE_FIELD_TO_UPDATE,/*don't take sem since task is not scheduled*/ + subTaskDep.subtaskId, SVA_TM_ENC_ADDR_IN_FRAME_BUFFER, + FCMD_COPY,(t_uint32) &frameBufferIn.addr_intra_refresh_buffer,HCL_BITFIELD_OFFSET(t_sva_vec_frame_buffer_in,addr_intra_refresh_buffer), + sizeof(frameBufferIn.addr_intra_refresh_buffer)); + HCL_DEBUG_ASSERT(tmError==SVA_TM_OK); + } + } + if (IS_DEPENDENCY_SOLVED(subTaskDep.dependencies.writeIntraRefreshBufferDep)==FALSE) + { + if (POP_FIFO_ELEM(pDesc->writeIntraRefreshBufferFifos.pushFifo,t_sva_buffer_id,bufferId) != SVA_FIFO_EMPTY) + { + t_sva_vec_frame_buffer_out frameBufferOut; + t_physical_address bufferAddr; + t_sva_bm_error bmError; + + ffError=PUSH_FIFO_ELEM(pDesc->writeIntraRefreshBufferFifos.inUseFifo,t_sva_buffer_id,bufferId); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + /*update subtask dependency as in use*/ + ffError=UPDATE_FIFO_ELEM_FIELD(pDesc->subtasksDependencyFifo, + t_sva_ec_subtask_dependencies, .dependencies.writeIntraRefreshBufferDep, + SOLVE_DEPENDENCY(subTaskDep.dependencies.writeIntraRefreshBufferDep)); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + subTaskDep.dependencies.writeIntraRefreshBufferDep=SOLVE_DEPENDENCY(subTaskDep.dependencies.writeIntraRefreshBufferDep); + /*update field in the task list*/ + bmError=sva_BM_GetBufferPhysicalAddress(bufferId,&bufferAddr); + HCL_DEBUG_ASSERT(bmError==SVA_BM_OK); + frameBufferOut.addr_intra_refresh_buffer=bufferAddr; + /*update this field in subtask*/ + tmError=sva_TM_UpdateSubTaskField(SVA_TM_INTERMEDIATE_FIELD_TO_UPDATE,/*don't take sem since task is not scheduled*/ + subTaskDep.subtaskId, SVA_TM_ENC_ADDR_OUT_FRAME_BUFFER, + FCMD_COPY,(t_uint32) &frameBufferOut.addr_intra_refresh_buffer,HCL_BITFIELD_OFFSET(t_sva_vec_frame_buffer_out,addr_intra_refresh_buffer), + sizeof(frameBufferOut.addr_intra_refresh_buffer)); + HCL_DEBUG_ASSERT(tmError==SVA_TM_OK); + } + } + if (IS_DEPENDENCY_SOLVED(subTaskDep.dependencies.infoBufferDep)==FALSE) + { + if (subTaskDep.isPrevSubTaskStrategicSkipped==TRUE || + POP_FIFO_ELEM(pDesc->infoBufferFifos.pushFifo,t_sva_buffer_id,bufferId) != SVA_FIFO_EMPTY) + { + /*if we handle a strategic skip then read in the in use fifo*/ + if (subTaskDep.isPrevSubTaskStrategicSkipped==TRUE) + { + ffError=READ_FIFO_ELEM(pDesc->infoBufferFifos.inUseFifo,t_sva_buffer_id,bufferId); + } + else /*buffer id comes from push fifo so set it has being in use*/ + { + ffError=PUSH_FIFO_ELEM(pDesc->infoBufferFifos.inUseFifo,t_sva_buffer_id,bufferId); + } + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + /*update subtask dependency as in use*/ + ffError=UPDATE_FIFO_ELEM_FIELD(pDesc->subtasksDependencyFifo, + t_sva_ec_subtask_dependencies, .dependencies.infoBufferDep, + SOLVE_DEPENDENCY(subTaskDep.dependencies.infoBufferDep)); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + subTaskDep.dependencies.infoBufferDep= SOLVE_DEPENDENCY(subTaskDep.dependencies.infoBufferDep); + } + } + if (IS_DEPENDENCY_SOLVED(subTaskDep.dependencies.deblockingBufferDep)==FALSE) + { + if (subTaskDep.isPrevSubTaskStrategicSkipped==TRUE || + POP_FIFO_ELEM(pDesc->deblockingBufferFifos.pushFifo,t_sva_buffer_id,bufferId) != SVA_FIFO_EMPTY) + { + t_sva_vec_frame_buffer_out frameBufferOut; + t_physical_address bufferAddr; + t_sva_bm_error bmError; + + /*if we handle a strategic skip then read in the in use fifo*/ + if (subTaskDep.isPrevSubTaskStrategicSkipped==TRUE) + { + ffError=READ_FIFO_ELEM(pDesc->deblockingBufferFifos.inUseFifo,t_sva_buffer_id,bufferId); + } + else /*buffer id comes from push fifo so set it has being in use*/ + { + ffError=PUSH_FIFO_ELEM(pDesc->deblockingBufferFifos.inUseFifo,t_sva_buffer_id,bufferId); + } + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + /*update subtask dependency as in use*/ + ffError=UPDATE_FIFO_ELEM_FIELD(pDesc->subtasksDependencyFifo, + t_sva_ec_subtask_dependencies, .dependencies.deblockingBufferDep, + SOLVE_DEPENDENCY(subTaskDep.dependencies.deblockingBufferDep)); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + subTaskDep.dependencies.deblockingBufferDep=SOLVE_DEPENDENCY(subTaskDep.dependencies.deblockingBufferDep); + /*update field in the task list*/ + bmError=sva_BM_GetBufferPhysicalAddress(bufferId,&bufferAddr); + HCL_DEBUG_ASSERT(bmError==SVA_BM_OK); + frameBufferOut.addr_deblocking_param_buffer=bufferAddr; + /*update this field in subtask*/ + tmError=sva_TM_UpdateSubTaskField(SVA_TM_INTERMEDIATE_FIELD_TO_UPDATE,/*don't take sem since task is not scheduled*/ + subTaskDep.subtaskId, SVA_TM_ENC_ADDR_OUT_FRAME_BUFFER, + FCMD_COPY,(t_uint32) &frameBufferOut.addr_deblocking_param_buffer,HCL_BITFIELD_OFFSET(t_sva_vec_frame_buffer_out,addr_deblocking_param_buffer), + sizeof(frameBufferOut.addr_deblocking_param_buffer)); + HCL_DEBUG_ASSERT(tmError==SVA_TM_OK); + } + } + if (IS_DEPENDENCY_SOLVED(subTaskDep.dependencies.brcBufferDep)==FALSE) + { + if (POP_FIFO_ELEM(pDesc->brcBufferFifos.pushFifo,t_sva_buffer_id,bufferId) != SVA_FIFO_EMPTY) + { + t_logical_address bufferAddr; + t_sva_bm_error bmError; + + /*we can resolve source Buffer dependency, so we do it*/ + /*push the source Buffer in the in use fifo*/ + ffError=PUSH_FIFO_ELEM(pDesc->brcBufferFifos.inUseFifo,t_sva_buffer_id,bufferId); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + /*cast buffer onto a cropping vector*/ + bmError=sva_BM_GetBufferLogicalAddress(bufferId,&bufferAddr); + HCL_DEBUG_ASSERT(bmError==SVA_BM_OK); + subTaskDep.brcUserRequest=*((t_sva_brc_user_request *) bufferAddr); + /*update cropping vector in subtaskdep*/ + ffError=UPDATE_FIFO_ELEM_FIELD(pDesc->subtasksDependencyFifo, + t_sva_ec_subtask_dependencies, .brcUserRequest, + subTaskDep.brcUserRequest); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + /*update subtask dependency as in use*/ + ffError=UPDATE_FIFO_ELEM_FIELD(pDesc->subtasksDependencyFifo, + t_sva_ec_subtask_dependencies, .dependencies.brcBufferDep, + SOLVE_DEPENDENCY(subTaskDep.dependencies.brcBufferDep)); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + subTaskDep.dependencies.brcBufferDep = SOLVE_DEPENDENCY(subTaskDep.dependencies.brcBufferDep); + } + } + /*check that all dependency has been resolved to continue*/ + if (IS_DEPENDENCY_SOLVED(subTaskDep.dependencies.sourceBufferDep)==TRUE && + IS_DEPENDENCY_SOLVED(subTaskDep.dependencies.bitstreamBufferDep)==TRUE && + IS_DEPENDENCY_SOLVED(subTaskDep.dependencies.destBufferDep)==TRUE && + IS_DEPENDENCY_SOLVED(subTaskDep.dependencies.fwRefBufferDep)==TRUE && + IS_DEPENDENCY_SOLVED(subTaskDep.dependencies.readIntraRefreshBufferDep)==TRUE && + IS_DEPENDENCY_SOLVED(subTaskDep.dependencies.writeIntraRefreshBufferDep)==TRUE && + IS_DEPENDENCY_SOLVED(subTaskDep.dependencies.infoBufferDep)==TRUE && + IS_DEPENDENCY_SOLVED(subTaskDep.dependencies.deblockingBufferDep)==TRUE && + IS_DEPENDENCY_SOLVED(subTaskDep.dependencies.croppingBufferDep)==TRUE && + IS_DEPENDENCY_SOLVED(subTaskDep.dependencies.brcBufferDep)==TRUE) + { + t_sva_tm_timestamp immediateTimeStamp={SVA_TM_IMMEDIATE,0}; + t_logical_address headerLogicalAddress; + t_sva_header_buf headerBuf; + t_size headerSizeBits; + t_sva_mm_error mmError; + t_sva_ec_algo_error algoError; + t_sva_ec_algo_image_info imageInfo; + + /*give infos for algo box*/ + imageInfo.pts=subTaskDep.timeStamp; + if (pDesc->defaultDep.croppingBufferDep==NOT_RESOLVED_DEPENDENCY) {imageInfo.croppingVector=subTaskDep.croppingVector;} + if (pDesc->defaultDep.brcBufferDep==NOT_RESOLVED_DEPENDENCY) {imageInfo.brcUserRequest=subTaskDep.brcUserRequest;} + algoError=encodeAlgoDesc[pDesc->algoId].pPushImageInfo(instanceNum,(t_sva_ec_algo_image_info *) &imageInfo); + HCL_DEBUG_ASSERT(algoError==SVA_EC_ALGO_OK); + + /*set up paramin*/ + algoError=encodeAlgoDesc[pDesc->algoId].pGetNextFrameParamIn(instanceNum,(t_sva_ec_algo_params_in *) pDesc->paramInAddr); + HCL_DEBUG_ASSERT(algoError==SVA_EC_ALGO_OK); + tmError=sva_TM_InitSubTaskField(subTaskDep.subtaskId, SVA_TM_ENC_ADDR_IN_PARAMETERS, + pDesc->paramInAddr, encodeAlgoDesc[pDesc->algoId].pGetParamsInSize(instanceNum)); + HCL_DEBUG_ASSERT(tmError==SVA_TM_OK); + + /*set up header*/ + mmError=sva_MM_GetBlockLogicalAddress(subTaskDep.headerBufferBlockId,&headerLogicalAddress); + HCL_DEBUG_ASSERT(mmError==SVA_MM_OK); + algoError=encodeAlgoDesc[pDesc->algoId].pGetNextHeader(instanceNum,(t_sva_ec_algo_header *)headerLogicalAddress,&headerSizeBits); + HCL_DEBUG_ASSERT(algoError==SVA_EC_ALGO_OK); + mmError=sva_MM_GetBlockPhysicalAddress(subTaskDep.headerBufferBlockId,&headerBuf.addr_header_buffer); + HCL_DEBUG_ASSERT(mmError==SVA_MM_OK); + headerBuf.header_size=headerSizeBits; + tmError=sva_TM_InitSubTaskField(subTaskDep.subtaskId, SVA_TM_ENC_ADDR_IN_HEADER_BUFFER, + (t_logical_address) &headerBuf, sizeof(t_sva_header_buf)); + HCL_DEBUG_ASSERT(tmError==SVA_TM_OK); + + /*pop subtask from list of subtask for which dep has to be solved*/ + ffError=POP_FIFO_ELEM(pDesc->subtasksDependencyFifo,t_sva_ec_subtask_dependencies,subTaskDep); + /*push subtask in list of subtask being in use*/ + ffError=PUSH_FIFO_ELEM(pDesc->inUseSubtaskDependency,t_sva_ec_subtask_dependencies,subTaskDep); + /*update state machine*/ + sva_EC_UpdateInstanceStateMachine(instanceNum,SVA_EC_ALL_DEPENDENCIES_RESOLVED); + /*add subtask to list of schedulable subtasks*/ + tmError=sva_TM_AddElemToSubTaskList(pDesc->subtasksListId,subTaskDep.subtaskId,&immediateTimeStamp, 1); + HCL_DEBUG_ASSERT(tmError==SVA_TM_OK); + } + else {dependencyNotSolved=TRUE;} + } + + return SVA_EC_OK; +} + +/****************************************************************************/ +/* NAME: t_sva_ec_state sva_EC_UpdateInstanceStateMachine( */ +/* t_sva_service_instance_num instanceNum, */ +/* t_sva_ec_transition requestedTransition */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine allows to update both state machine */ +/* following the given requestedTransition */ +/* */ +/* N.B: This routine returns the new state after the requested transition */ +/* A special return state (SVA_GB_TRANSITION_REJECTED) is used to check */ +/* the validity of a transition request */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - instanceNum : instance number for which state must be updated */ +/* - requestedTransition: identifier of the requested transition */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: t_sva_ec_state */ +/* - one of the t_sva_ec_state */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + DONE +*/ +PRIVATE t_sva_ec_state sva_EC_UpdateInstanceStateMachine +( + t_sva_service_instance_num instanceNum, + t_sva_ec_transition requestedTransition +) +{ + t_sva_ec_descriptor *pDesc=&encodeDesc[instanceNum]; + t_sva_ec_state nextState; + t_sva_ec_activate_state nextActivateState; + +#ifdef __DEBUG + { + t_uint32 systemTime; + + SVA_GetServiceSystemTime(pDesc->serviceId,&systemTime); + transitionEncodeDebugTable[instanceNum].transitionDebugDesc[transitionEncodeDebugTable[instanceNum].nbOfTransitionReceived%LOG_DEPTH].state=pDesc->state; + transitionEncodeDebugTable[instanceNum].transitionDebugDesc[transitionEncodeDebugTable[instanceNum].nbOfTransitionReceived%LOG_DEPTH].transition=requestedTransition; + transitionEncodeDebugTable[instanceNum].transitionDebugDesc[transitionEncodeDebugTable[instanceNum].nbOfTransitionReceived%LOG_DEPTH].systemTime=systemTime; + transitionEncodeDebugTable[instanceNum].transitionDebugDesc[transitionEncodeDebugTable[instanceNum].nbOfTransitionReceived%LOG_DEPTH].activateState=pDesc->activateState; + transitionEncodeDebugTable[instanceNum].nbOfTransitionReceived++; + + } +#endif + + /* Compute the next state */ + nextState=stateMachine[pDesc->state][requestedTransition]; + nextActivateState=activateStateMachine[pDesc->activateState][requestedTransition]; + + /* Check if the transition is valid */ + if (nextState != SVA_EC_TRANSITION_REJECTED && nextActivateState!=SVA_EC_ACTIVATE_TRANSITION_REJECTED) + { + /* Update both current state of the instance */ + pDesc->state = nextState; + pDesc->activateState = nextActivateState; + /* Update status*/ + pDesc->status.state=encodeState2ServiceState[pDesc->state]; + } + + return nextState; +} + +/****************************************************************************/ +/* NAME: t_bool sva_EC_isTransitionValid( */ +/* t_sva_service_instance_num instanceNum, */ +/* t_sva_ec_transition requestedTransition */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine checks if the requestedTransition is valid for both */ +/* state machine */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - instanceNum : instance number for which transition check must be done*/ +/* - requestedTransition: identifier of the requested transition */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: t_bool */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + DONE +*/ +PRIVATE t_bool sva_EC_isTransitionValid +( + t_sva_service_instance_num instanceNum, + t_sva_ec_transition requestedTransition +) +{ + t_sva_ec_descriptor *pDesc=&encodeDesc[instanceNum]; + t_sva_ec_state nextState; + t_sva_ec_activate_state nextActivateState; + + /* Compute the next state for both state machine*/ + nextState=stateMachine[pDesc->state][requestedTransition]; + nextActivateState=activateStateMachine[pDesc->activateState][requestedTransition]; + + /*return false in case of invalid transition for at least one state machine*/ + if (nextState != SVA_EC_TRANSITION_REJECTED && nextActivateState!=SVA_EC_ACTIVATE_TRANSITION_REJECTED) {return TRUE;} + else {return FALSE;} +} + +/****************************************************************************/ +/* NAME: t_sva_error sva_EC_CheckServiceId(t_sva_service_id serviceId) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will check that task_id and instance number of servideId*/ +/* are both valid */ +/* */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - serviceId: service id to check */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: t_sva_error */ +/* - SVA_UNKNOWN_SERVICE_ID : Invalid service id. Either due to an */ +/* invalid task id or invalid instance number. */ +/* - SVA_OK : Service id is valid */ +/* */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + DONE +*/ +PRIVATE t_sva_error sva_EC_CheckServiceId(t_sva_service_id serviceId) +{ + t_sva_service_instance_num instanceNum = READ_INSTANCE_NUM_IN_SERVICE_ID(serviceId); + t_sva_sv_task_id taskId = READ_TASK_ID_IN_SERVICE_ID(serviceId); + + if (taskId!=SVA_SV_ENCODE_TID) {return SVA_UNKNOWN_SERVICE_ID;} + if (instanceNum>=NUM_MAX_ENCODE) {return SVA_UNKNOWN_SERVICE_ID;} + + return SVA_OK; +} + +/****************************************************************************/ +/* NAME: t_sva_error sva_EC_DoReset( */ +/* t_sva_service_id serviceId */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will reset a service so it can restart after an error. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - serviceId: service identifier */ +/* */ +/* OUT: none */ +/* */ +/* RETURN: t_sva_error */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + DONE +*/ +PRIVATE t_sva_error sva_EC_DoReset +( + t_sva_service_id serviceId +) +{ + (void) serviceId; + + return SVA_OK; +} + +/****************************************************************************/ +/* NAME: t_sva_error sva_EC_DoFlushIn( */ +/* t_sva_service_id serviceId */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will flush input fifo. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - serviceId: service identifier */ +/* */ +/* OUT: none */ +/* */ +/* RETURN: t_sva_error */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + TODO : + - See how to handle a restart after this call +*/ +PRIVATE t_sva_error sva_EC_DoFlushInX +( + t_sva_service_id serviceId +) +{ + t_sva_service_instance_num instanceNum = READ_INSTANCE_NUM_IN_SERVICE_ID(serviceId); + t_sva_ec_descriptor *pDesc=&encodeDesc[instanceNum]; + //t_sva_ec_subtask_dependencies subtaskDep; + t_sva_timestamp dummyTimeStamp={SVA_NO_TIMESTAMP,0}; + t_sva_buffer_id bufferId = INVALID_BUFFER_ID; + t_uint32 systemTime; + t_sva_error svaError; + //t_sva_tm_error tmError; + t_sva_ff_error ffError; + t_sva_bm_error bmError; + + + (void) dummyTimeStamp; + + /*get time*/ + svaError=SVA_GetServiceSystemTime(serviceId,&systemTime); + if (svaError != SVA_OK) {return SVA_INTERNAL_VIDEO_ENCODER_ERROR;} + + /*flush fifo*/ + /*flush source fifo*/ + while(POP_FIFO_ELEM(pDesc->sourceBufferFifos.inUseFifo,t_sva_buffer_id,bufferId) != SVA_FIFO_EMPTY) + { + bmError=sva_BM_UpdateBufferStatus(bufferId,SVA_BUFFER_NOT_USED,systemTime); + if (bmError!=SVA_BM_OK) {return SVA_INTERNAL_VIDEO_ENCODER_ERROR;} + } + while(POP_FIFO_ELEM(pDesc->sourceBufferFifos.pushFifo,t_sva_buffer_id,bufferId) != SVA_FIFO_EMPTY) + { + bmError=sva_BM_UpdateBufferStatus(bufferId,SVA_BUFFER_NOT_USED,systemTime); + if (bmError!=SVA_BM_OK) {return SVA_INTERNAL_VIDEO_ENCODER_ERROR;} + } + /*time stamp fifo*/ + while(POP_FIFO_ELEM(pDesc->timeStampFifos.inUseFifo,t_sva_timestamp,dummyTimeStamp) != SVA_FIFO_EMPTY) {;} + while(POP_FIFO_ELEM(pDesc->timeStampFifos.pushFifo,t_sva_timestamp,dummyTimeStamp) != SVA_FIFO_EMPTY) {;} + /*flush cropping buffers*/ + if (pDesc->defaultDep.croppingBufferDep==NOT_RESOLVED_DEPENDENCY) + { + while(POP_FIFO_ELEM(pDesc->croppingBufferFifos.inUseFifo,t_sva_buffer_id,bufferId) != SVA_FIFO_EMPTY) + { + bmError=sva_BM_UpdateBufferStatus(bufferId,SVA_BUFFER_NOT_USED,systemTime); + if (bmError!=SVA_BM_OK) {return SVA_INTERNAL_VIDEO_ENCODER_ERROR;} + } + while(POP_FIFO_ELEM(pDesc->croppingBufferFifos.pushFifo,t_sva_buffer_id,bufferId) != SVA_FIFO_EMPTY) + { + bmError=sva_BM_UpdateBufferStatus(bufferId,SVA_BUFFER_NOT_USED,systemTime); + if (bmError!=SVA_BM_OK) {return SVA_INTERNAL_VIDEO_ENCODER_ERROR;} + } + } + /*flush brc buffers*/ + if (pDesc->defaultDep.brcBufferDep==NOT_RESOLVED_DEPENDENCY) + { + while(POP_FIFO_ELEM(pDesc->brcBufferFifos.inUseFifo,t_sva_buffer_id,bufferId) != SVA_FIFO_EMPTY) + { + bmError=sva_BM_UpdateBufferStatus(bufferId,SVA_BUFFER_NOT_USED,systemTime); + if (bmError!=SVA_BM_OK) {return SVA_INTERNAL_VIDEO_ENCODER_ERROR;} + } + while(POP_FIFO_ELEM(pDesc->brcBufferFifos.pushFifo,t_sva_buffer_id,bufferId) != SVA_FIFO_EMPTY) + { + bmError=sva_BM_UpdateBufferStatus(bufferId,SVA_BUFFER_NOT_USED,systemTime); + if (bmError!=SVA_BM_OK) {return SVA_INTERNAL_VIDEO_ENCODER_ERROR;} + } + } + + /*handle internal buffers*/ + /*intra refresh buffers are push back from inUse to pushFifo*/ + do + { + ffError=POP_REVERSE_FIFO_ELEM(pDesc->readIntraRefreshBufferFifos.inUseFifo,t_sva_buffer_id,bufferId); + if (ffError==SVA_FIFO_OK) + { + ffError=PUSH_REVERSE_FIFO_ELEM(pDesc->readIntraRefreshBufferFifos.pushFifo,t_sva_buffer_id,bufferId); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + } + } while (ffError==SVA_FIFO_OK); + do + { + ffError=POP_REVERSE_FIFO_ELEM(pDesc->writeIntraRefreshBufferFifos.inUseFifo,t_sva_buffer_id,bufferId); + if (ffError==SVA_FIFO_OK) + { + ffError=PUSH_REVERSE_FIFO_ELEM(pDesc->writeIntraRefreshBufferFifos.pushFifo,t_sva_buffer_id,bufferId); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + } + } while (ffError==SVA_FIFO_OK); + /*destination buffers and fw ref buffers if internal are push back from inUse to pushFifo*/ + if (pDesc->conf.isDestinationBufferRequested == FALSE) + { + do + { + ffError=POP_REVERSE_FIFO_ELEM(pDesc->destBufferFifos.inUseFifo,t_sva_buffer_id,bufferId); + if (ffError==SVA_FIFO_OK) + { + ffError=PUSH_REVERSE_FIFO_ELEM(pDesc->destBufferFifos.pushFifo,t_sva_buffer_id,bufferId); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + } + } while (ffError==SVA_FIFO_OK); + do + { + ffError=POP_REVERSE_FIFO_ELEM(pDesc->fwRefBufferFifos.inUseFifo,t_sva_buffer_id,bufferId); + if (ffError==SVA_FIFO_OK) + { + ffError=PUSH_REVERSE_FIFO_ELEM(pDesc->fwRefBufferFifos.pushFifo,t_sva_buffer_id,bufferId); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + } + } while (ffError==SVA_FIFO_OK); + } + + /*move output buffers from the in use fifo to the push fifo in reverse order*/ + /*bitstreamBufferFifos*/ + do + { + ffError=POP_REVERSE_FIFO_ELEM(pDesc->writeIntraRefreshBufferFifos.inUseFifo,t_sva_buffer_id,bufferId); + if (ffError==SVA_FIFO_OK) + { + ffError=PUSH_REVERSE_FIFO_ELEM(pDesc->writeIntraRefreshBufferFifos.pushFifo,t_sva_buffer_id,bufferId); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + } + } while (ffError==SVA_FIFO_OK); + /*destBufferFifos and fwRefBufferFifos if internal*/ + /*NOTE : could be merge with above but not done */ + if (pDesc->conf.isDestinationBufferRequested == TRUE) + { + do + { + ffError=POP_REVERSE_FIFO_ELEM(pDesc->destBufferFifos.inUseFifo,t_sva_buffer_id,bufferId); + if (ffError==SVA_FIFO_OK) + { + ffError=PUSH_REVERSE_FIFO_ELEM(pDesc->destBufferFifos.pushFifo,t_sva_buffer_id,bufferId); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + } + } while (ffError==SVA_FIFO_OK); + do + { + ffError=POP_REVERSE_FIFO_ELEM(pDesc->fwRefBufferFifos.inUseFifo,t_sva_buffer_id,bufferId); + if (ffError==SVA_FIFO_OK) + { + ffError=PUSH_REVERSE_FIFO_ELEM(pDesc->fwRefBufferFifos.pushFifo,t_sva_buffer_id,bufferId); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + } + } while (ffError==SVA_FIFO_OK); + } + /*info buffers*/ + if (pDesc->conf.areInfosRequested==TRUE) + { + do + { + ffError=POP_REVERSE_FIFO_ELEM(pDesc->infoBufferFifos.inUseFifo,t_sva_buffer_id,bufferId); + if (ffError==SVA_FIFO_OK) + { + ffError=PUSH_REVERSE_FIFO_ELEM(pDesc->infoBufferFifos.pushFifo,t_sva_buffer_id,bufferId); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + } + } while (ffError==SVA_FIFO_OK); + } + /*deblocking*/ + if (pDesc->conf.outTheLoopFilter!=SVA_NONE_FILTER) + { + do + { + ffError=POP_REVERSE_FIFO_ELEM(pDesc->deblockingBufferFifos.inUseFifo,t_sva_buffer_id,bufferId); + if (ffError==SVA_FIFO_OK) + { + ffError=PUSH_REVERSE_FIFO_ELEM(pDesc->deblockingBufferFifos.pushFifo,t_sva_buffer_id,bufferId); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + } + } while (ffError==SVA_FIFO_OK); + } + + return SVA_OK; +} + +/****************************************************************************/ +/* NAME: t_sva_error sva_EC_DoFlushOut( */ +/* t_sva_service_id serviceId */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will flush output fifo. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - serviceId: service identifier */ +/* */ +/* OUT: none */ +/* */ +/* RETURN: t_sva_error */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + TODO : + - See how to handle a restart after this call +*/ +PRIVATE t_sva_error sva_EC_DoFlushOutX +( + t_sva_service_id serviceId +) +{ + t_sva_service_instance_num instanceNum = READ_INSTANCE_NUM_IN_SERVICE_ID(serviceId); + t_sva_ec_descriptor *pDesc=&encodeDesc[instanceNum]; + t_sva_ec_subtask_dependencies subtaskDep; + t_sva_buffer_id bufferId; + t_uint32 systemTime; + t_sva_error svaError; + t_sva_tm_error tmError; + t_sva_ff_error ffError; + t_sva_bm_error bmError; + t_sva_blm_error blmError; + t_uint32 i; + + + /*remove schedule tasks and push them back in subtasksDependencyFifo with default dep*/ + /*so they can be rescheduled */ + do + { + tmError=sva_TM_RemoveElemFromSubTaskList(pDesc->subtasksListId,&subtaskDep.subtaskId); + if (tmError==SVA_TM_OK) + { + /*pop it from in use fifo*/ + ffError=POP_FIFO_ELEM(pDesc->inUseSubtaskDependency,t_sva_ec_subtask_dependencies,subtaskDep); + if (ffError!=SVA_FIFO_OK) {return SVA_INTERNAL_VIDEO_ENCODER_ERROR;} + /*reset dependencies*/ + subtaskDep.dependencies = pDesc->defaultDep; + /*push it in the list of dependencies to check*/ + ffError=PUSH_FIFO_ELEM(pDesc->subtasksDependencyFifo,t_sva_ec_subtask_dependencies,subtaskDep); + if (ffError!=SVA_FIFO_OK) {return SVA_INTERNAL_VIDEO_ENCODER_ERROR;} + } + } while (tmError==SVA_TM_OK); +#if 1 + /* Reset the subtasks dependencies */ + for(i=0;isubtasksDependencyFifo,t_sva_ec_subtask_dependencies,subtaskDep); + /* Reset them to default one */ + subtaskDep.dependencies=pDesc->defaultDep; + if (ffError==SVA_FIFO_OK) + { + /* Push them back */ + ffError=PUSH_FIFO_ELEM(pDesc->subtasksDependencyFifo,t_sva_ec_subtask_dependencies,subtaskDep); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + } + } + do + { + /* REVERSE POP the subtasks dependencies if some element are present in * + * inUseSubtaskDependency i.e. all the dependencies were resolved for * + * this subtask */ + ffError=POP_REVERSE_FIFO_ELEM(pDesc->inUseSubtaskDependency,t_sva_ec_subtask_dependencies,subtaskDep); + subtaskDep.dependencies=pDesc->defaultDep; + if (ffError==SVA_FIFO_OK) + { + /* Push them back */ + ffError=PUSH_FIFO_ELEM(pDesc->subtasksDependencyFifo,t_sva_ec_subtask_dependencies,subtaskDep); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + } + } while (ffError==SVA_FIFO_OK); +#else + /* SARVESH: This piece of code is just for reference, It lead to some * + * quality issues because it reset all the elements of the structure */ + do + { + ffError=POP_FIFO_ELEM(pDesc->subtasksDependencyFifo,t_sva_ec_subtask_dependencies,subtaskDep); + } while (ffError==SVA_FIFO_OK); + do + { + ffError=POP_FIFO_ELEM(pDesc->inUseSubtaskDependency,t_sva_ec_subtask_dependencies,subtaskDep); + } while (ffError==SVA_FIFO_OK); + + /* Push subtask in subtasksDependencyFifo since they are ready to be solved*/ + for(i=0;iconf; + + /*subtaskid*/ + subtaskDep.subtaskId=pDesc->subtasksIdArray[i]; + /*default dependencies*/ + subtaskDep.dependencies=pDesc->defaultDep; + /*set buffer list to use*/ + subtaskDep.bufferListId=pDesc->bufferListIdArray[i]; + /*set header buffer to use*/ + subtaskDep.headerBufferBlockId=pDesc->headerBufferBlockIdArray[i]; + /*set default value for cropiing vector*/ + subtaskDep.croppingVector=pConf->sourceFrameDesc.window.imageOffset; + /*in case of first subtask then forward ref buffer is marked as solve dep done*/ + if (i==0) {subtaskDep.dependencies.fwRefBufferDep=RESOLVED_INTERNAL_DEPENDENCY;} + + /*push subtask in the list of subtask to resolve dep*/ + ffError=PUSH_FIFO_ELEM(pDesc->subtasksDependencyFifo, t_sva_ec_subtask_dependencies, subtaskDep); + if (ffError!=SVA_FIFO_OK) {return SVA_INTERNAL_VIDEO_ENCODER_ERROR;} + } +#endif + + /*get time*/ + svaError=SVA_GetServiceSystemTime(serviceId,&systemTime); + if (svaError != SVA_OK) {return SVA_INTERNAL_VIDEO_ENCODER_ERROR;} + + /*flush fifo*/ + /*bitstream buffers*/ + while(POP_FIFO_ELEM(pDesc->bitstreamBufferFifos.inUseFifo,t_sva_buffer_id,bufferId) != SVA_FIFO_EMPTY) + { + bmError=sva_BM_UpdateBufferStatus(bufferId,SVA_BUFFER_NOT_USED,systemTime); + if (bmError!=SVA_BM_OK) {return SVA_INTERNAL_VIDEO_ENCODER_ERROR;} + } + while(POP_FIFO_ELEM(pDesc->bitstreamBufferFifos.pushFifo,t_sva_buffer_id,bufferId) != SVA_FIFO_EMPTY) + { + bmError=sva_BM_UpdateBufferStatus(bufferId,SVA_BUFFER_NOT_USED,systemTime); + if (bmError!=SVA_BM_OK) {return SVA_INTERNAL_VIDEO_ENCODER_ERROR;} + } + /*also remove them from buffer list management*/ + for(i=0;ibufferListIdArray[i],&bufferId); + if (blmError!=SVA_BLM_OK && blmError!=SVA_BLM_LIST_EMPTY) {return SVA_INTERNAL_VIDEO_ENCODER_ERROR;} + } while(blmError!=SVA_BLM_LIST_EMPTY); + } + + /*info Buffers is needed*/ + if (pDesc->conf.areInfosRequested==TRUE) + { + while(POP_FIFO_ELEM(pDesc->infoBufferFifos.inUseFifo,t_sva_buffer_id,bufferId) != SVA_FIFO_EMPTY) + { + bmError=sva_BM_UpdateBufferStatus(bufferId,SVA_BUFFER_NOT_USED,systemTime); + if (bmError!=SVA_BM_OK) {return SVA_INTERNAL_VIDEO_ENCODER_ERROR;} + } + while(POP_FIFO_ELEM(pDesc->infoBufferFifos.pushFifo,t_sva_buffer_id,bufferId) != SVA_FIFO_EMPTY) + { + bmError=sva_BM_UpdateBufferStatus(bufferId,SVA_BUFFER_NOT_USED,systemTime); + if (bmError!=SVA_BM_OK) {return SVA_INTERNAL_VIDEO_ENCODER_ERROR;} + } + } + /*destination and forward reference buffers if external*/ + if (pDesc->conf.isDestinationBufferRequested==TRUE) + { + while(POP_FIFO_ELEM(pDesc->destBufferFifos.inUseFifo,t_sva_buffer_id,bufferId) != SVA_FIFO_EMPTY) + { + bmError=sva_BM_UpdateBufferStatus(bufferId,SVA_BUFFER_NOT_USED,systemTime); + if (bmError!=SVA_BM_OK) {return SVA_INTERNAL_VIDEO_ENCODER_ERROR;} + } + while(POP_FIFO_ELEM(pDesc->destBufferFifos.pushFifo,t_sva_buffer_id,bufferId) != SVA_FIFO_EMPTY) + { + bmError=sva_BM_UpdateBufferStatus(bufferId,SVA_BUFFER_NOT_USED,systemTime); + if (bmError!=SVA_BM_OK) {return SVA_INTERNAL_VIDEO_ENCODER_ERROR;} + } + /*for forward do not flush in use buffers. It will done on IT with generation of a filled event*/ + while(POP_FIFO_ELEM(pDesc->fwRefBufferFifos.pushFifo,t_sva_buffer_id,bufferId) != SVA_FIFO_EMPTY) + { + bmError=sva_BM_UpdateBufferStatus(bufferId,SVA_BUFFER_NOT_USED,systemTime); + if (bmError!=SVA_BM_OK) {return SVA_INTERNAL_VIDEO_ENCODER_ERROR;} + } + } + /*deblocking if external*/ + if (pDesc->conf.outTheLoopFilter!=SVA_NONE_FILTER) + { + while(POP_FIFO_ELEM(pDesc->deblockingBufferFifos.inUseFifo,t_sva_buffer_id,bufferId) != SVA_FIFO_EMPTY) + { + bmError=sva_BM_UpdateBufferStatus(bufferId,SVA_BUFFER_NOT_USED,systemTime); + if (bmError!=SVA_BM_OK) {return SVA_INTERNAL_VIDEO_ENCODER_ERROR;} + } + while(POP_FIFO_ELEM(pDesc->deblockingBufferFifos.pushFifo,t_sva_buffer_id,bufferId) != SVA_FIFO_EMPTY) + { + bmError=sva_BM_UpdateBufferStatus(bufferId,SVA_BUFFER_NOT_USED,systemTime); + if (bmError!=SVA_BM_OK) {return SVA_INTERNAL_VIDEO_ENCODER_ERROR;} + } + } + + /*handle internal buffers*/ + /*intra refresh buffers are push back from inUse to pushFifo*/ + do + { + ffError=POP_REVERSE_FIFO_ELEM(pDesc->readIntraRefreshBufferFifos.inUseFifo,t_sva_buffer_id,bufferId); + if (ffError==SVA_FIFO_OK) + { + ffError=PUSH_REVERSE_FIFO_ELEM(pDesc->readIntraRefreshBufferFifos.pushFifo,t_sva_buffer_id,bufferId); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + } + } while (ffError==SVA_FIFO_OK); + do + { + ffError=POP_REVERSE_FIFO_ELEM(pDesc->writeIntraRefreshBufferFifos.inUseFifo,t_sva_buffer_id,bufferId); + if (ffError==SVA_FIFO_OK) + { + ffError=PUSH_REVERSE_FIFO_ELEM(pDesc->writeIntraRefreshBufferFifos.pushFifo,t_sva_buffer_id,bufferId); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + } + } while (ffError==SVA_FIFO_OK); + /*destination buffers and fw ref buffers if internal are push back from inUse to pushFifo*/ + if (pDesc->conf.isDestinationBufferRequested == FALSE) + { + do + { + ffError=POP_REVERSE_FIFO_ELEM(pDesc->destBufferFifos.inUseFifo,t_sva_buffer_id,bufferId); + if (ffError==SVA_FIFO_OK) + { + ffError=PUSH_REVERSE_FIFO_ELEM(pDesc->destBufferFifos.pushFifo,t_sva_buffer_id,bufferId); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + } + } while (ffError==SVA_FIFO_OK); + do + { + ffError=POP_REVERSE_FIFO_ELEM(pDesc->fwRefBufferFifos.inUseFifo,t_sva_buffer_id,bufferId); + if (ffError==SVA_FIFO_OK) + { + ffError=PUSH_REVERSE_FIFO_ELEM(pDesc->fwRefBufferFifos.pushFifo,t_sva_buffer_id,bufferId); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + } + } while (ffError==SVA_FIFO_OK); + } + + /*move input buffers from the in use fifo to the push fifo in reverse order*/ + /*source buffer*/ + do + { + ffError=POP_REVERSE_FIFO_ELEM(pDesc->sourceBufferFifos.inUseFifo,t_sva_buffer_id,bufferId); + if (ffError==SVA_FIFO_OK) + { + ffError=PUSH_REVERSE_FIFO_ELEM(pDesc->sourceBufferFifos.pushFifo,t_sva_buffer_id,bufferId); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + } + } while (ffError==SVA_FIFO_OK); + /*time stamp*/ + do + { + ffError=POP_REVERSE_FIFO_ELEM(pDesc->timeStampFifos.inUseFifo,t_sva_buffer_id,bufferId); + if (ffError==SVA_FIFO_OK) + { + ffError=PUSH_REVERSE_FIFO_ELEM(pDesc->timeStampFifos.pushFifo,t_sva_buffer_id,bufferId); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + } + } while (ffError==SVA_FIFO_OK); + /* cropping buffers if enabled */ + if (pDesc->defaultDep.croppingBufferDep==NOT_RESOLVED_DEPENDENCY) + { + do + { + ffError=POP_REVERSE_FIFO_ELEM(pDesc->croppingBufferFifos.inUseFifo,t_sva_buffer_id,bufferId); + if (ffError==SVA_FIFO_OK) + { + ffError=PUSH_REVERSE_FIFO_ELEM(pDesc->croppingBufferFifos.pushFifo,t_sva_buffer_id,bufferId); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + } + } while (ffError==SVA_FIFO_OK); + } + /* brc buffers*/ + if (pDesc->defaultDep.brcBufferDep==NOT_RESOLVED_DEPENDENCY) + { + do + { + ffError=POP_REVERSE_FIFO_ELEM(pDesc->brcBufferFifos.inUseFifo,t_sva_buffer_id,bufferId); + if (ffError==SVA_FIFO_OK) + { + ffError=PUSH_REVERSE_FIFO_ELEM(pDesc->brcBufferFifos.pushFifo,t_sva_buffer_id,bufferId); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + } + } while (ffError==SVA_FIFO_OK); + } + + return SVA_OK; +} + +PRIVATE t_sva_error sva_EC_DoFlush +( + t_sva_service_id serviceId +) +{ + t_sva_error sva_error; + + sva_error = sva_EC_DoFlushInX(serviceId); + HCL_DEBUG_ASSERT(sva_error == SVA_OK); + sva_error = sva_EC_DoFlushOutX(serviceId); + HCL_DEBUG_ASSERT(sva_error == SVA_OK); + + return sva_error; +} + +PRIVATE t_sva_error sva_EC_DoFlushIn +( + t_sva_service_id serviceId +) +{ + return sva_EC_DoFlush(serviceId); +} + +PRIVATE t_sva_error sva_EC_DoFlushOut +( + t_sva_service_id serviceId +) +{ + return sva_EC_DoFlush(serviceId); +} + + + +/****************************************************************************/ +/* NAME: t_sva_ec_error sva_EC_ResetStatus( */ +/* t_sva_video_encoder_status *pStatus */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will reset status descriptor. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - pStatus: status descriptor to reset */ +/* */ +/* OUT: none */ +/* */ +/* RETURN: t_sva_ec_error */ +/* - SVA_EC_OK */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + DONE +*/ +PRIVATE t_sva_ec_error sva_EC_ResetStatus +( + t_sva_video_encoder_status *pStatus +) +{ + EC_CHECK_NULL_POINTER(pStatus); + + pStatus->state=SVA_SERVICE_NOT_INITIALIZED; + pStatus->errorId=SVA_VIDEO_ENCODER_ERROR_DUMMY; + pStatus->nbBytesEncoded=0; + pStatus->nbImagesEncoded=0; + pStatus->nbImagesSkipped=0; + pStatus->eventStats.voidedCounter=0; + pStatus->eventStats.filledCounter=0; + pStatus->eventStats.partlyCounter=0; + pStatus->eventStats.readOnlyCounter=0; + pStatus->eventStats.underflowCounter=0; + pStatus->eventStats.overflowCounter=0; + pStatus->eventStats.errorCounter=0; + pStatus->bufferizationStats.inLevel=0; + pStatus->bufferizationStats.outLevel=0; + + return SVA_EC_OK; +} + +/****************************************************************************/ +/* NAME: void sva_EC_ResetDescriptor( */ +/* t_sva_ec_descriptor *pDesc */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine is in charge reset encode descriptor for one instance */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - pDesc: descriptor to reset */ +/* */ +/* OUT: none */ +/* */ +/* RETURN: void */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + DONE +*/ +PRIVATE void sva_EC_ResetDescriptor(t_sva_ec_descriptor *pDesc) +{ + EC_CHECK_NULL_POINTER(pDesc); + + sva_EC_ResetStatus(&pDesc->status); + pDesc->handleForwardInitCnt=0; +} + +/****************************************************************************/ +/* NAME: t_sva_error sva_EC_AllocateMemoryAndLink( */ +/* t_sva_service_instance_num instanceNum */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine allocate all needed internal memory and link them to */ +/* subtask. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - instanceNum : identifier of the Service instance */ +/* */ +/* OUT: */ +/* */ +/* RETURN: t_sva_error */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + * DONE +*/ +PRIVATE t_sva_error sva_EC_AllocateMemoryAndLink +( + t_sva_service_instance_num instanceNum +) +{ + t_sva_ec_descriptor *pDesc=&encodeDesc[instanceNum]; + const t_sva_video_encoder_configuration *pConf = &pDesc->conf; + t_sva_error status; + t_sva_mm_error mmError; + t_sva_tm_error tmError; + t_sva_ff_error ffError; + t_sva_blm_error blmError; + t_size memSize=0; /* memSize initialized with Zero to remove unnecessary warning */ + t_system_address systemAddress; + t_uint32 i; + t_uint32 width=(t_uint32) pConf->sourceFrameDesc.window.image.width; + t_uint32 height=(t_uint32) pConf->sourceFrameDesc.window.image.height; + + /*check if need to allocate memory for destination buffer*/ + if (pDesc->defaultDep.destBufferDep==NOT_RESOLVED_INTERNAL_DEPENDENCY) + { + /*compute size to allocate*/ + memSize=(height*width*3)/2; + + /*allocate mem*/ + for(i=0;idestRefBufferIdArray[i]); + if (status!=SVA_OK) {return SVA_INTERNAL_VIDEO_ENCODER_ERROR;} +#if 0 + { + t_uint32 j; + t_uint8 *dst=(t_uint8 *) systemAddress.logical; + + for(j=0;jdestBufferFifos.pushFifo,t_sva_buffer_id,pDesc->destRefBufferIdArray[i]); + if (ffError!=SVA_FIFO_OK) {return SVA_INTERNAL_VIDEO_ENCODER_ERROR;} + ffError=PUSH_FIFO_ELEM(pDesc->fwRefBufferFifos.pushFifo,t_sva_buffer_id,pDesc->destRefBufferIdArray[i]); + if (ffError!=SVA_FIFO_OK) {return SVA_INTERNAL_VIDEO_ENCODER_ERROR;} + } + } + /******************************************** + * Values from Page 372 HAMAC spec * + * sva_specification_8815_v0.4_draft7.pdf: * + * for H263/MPEG4: * + * ((SWW/16+2)*(SWH/16+2)*4+15)&0xFFF0 * + * for H264 encoder: * + * ((SWW/16+2)*(SWH/16+2)*8+15)&0xFFF0 * + *******************************************/ + /*allocate and link motion vector buffer*/ + if (SVA_EC_ALGO_MPEG4 == pDesc->algoId) + { + memSize=((height/16+2)*(width/16+2)*4+15)&0xfff0; //\/ Origional value for MPEG4 + } + else if (SVA_EC_ALGO_H264 == pDesc->algoId) + { +/* Line of code taken from H264 encode reference code alloc_mv_field func and hostmbuffer.c file *///\/ +//\/ if((mv = (t_uint32*)calloc(2*(size_y / BLOCK_SIZE)*(size_x / BLOCK_SIZE), sizeof(t_sint16))) == NULL) +//\/ memSize=(2*(height / SVA_EC_BLOCK_SIZE)*(width / SVA_EC_BLOCK_SIZE))*(sizeof(t_sint16));//\/ Values taken from Ref code +//\/ memSize=((height/16)*(width/16)*8+15)&0xfff0;//\/ Values taken from page 372 of sva_specification_8815_v0.4_draft6.pdf + memSize=((height/16+2)*(width/16+2)*8+15)&0xfff0;//\/ Values taken from page 372 of sva_specification_8815_v0.4_draft7.pdf + } + +//\/ memSize=((height/16+2)*(width/16+2)*4+15); //\/ Origional value for MPEG4 +/* Line of code taken from H264 encode reference code alloc_mv_field func and hostmbuffer.c file *///\/ +//\/ if((mv = (t_uint32*)calloc(2*(size_y / BLOCK_SIZE)*(size_x / BLOCK_SIZE), sizeof(t_sint16))) == NULL) +//\/ memSize=(2*(height / SVA_EC_BLOCK_SIZE)*(width / SVA_EC_BLOCK_SIZE))*(sizeof(t_sint16));//\/ + + mmError=sva_MM_AllocBlock(SDRAM_ID,memSize,SVA_MM_ALIGN_16BYTES,&pDesc->motionBufferBlockId); + if (mmError!=SVA_MM_OK) {return SVA_INTERNAL_VIDEO_ENCODER_ERROR;} +#if 0 + { + t_uint32 j; + t_logical_address blockAddr; + t_uint8 *dst; + + sva_MM_GetBlockLogicalAddress(pDesc->motionBufferBlockId,&blockAddr); + dst=(t_uint8 *) blockAddr; + for(j=0;jmotionBufferBlockId,&frameBufferOut.addr_motion_vector_buffer); + if (mmError!=SVA_MM_OK) {return SVA_INTERNAL_VIDEO_ENCODER_ERROR;} + /*update this field in subtask*/ + tmError=sva_TM_UpdateSubTaskField(SVA_TM_INTERMEDIATE_FIELD_TO_UPDATE,/*don't take sem since task is not scheduled*/ + pDesc->subtasksIdArray[i], SVA_TM_ENC_ADDR_OUT_FRAME_BUFFER, + FCMD_COPY,(t_uint32) &frameBufferOut.addr_motion_vector_buffer,HCL_BITFIELD_OFFSET(t_sva_vec_frame_buffer_out,addr_motion_vector_buffer), + sizeof(frameBufferOut.addr_motion_vector_buffer)); + if (tmError!=SVA_TM_OK) {return SVA_INTERNAL_VIDEO_ENCODER_ERROR;} + } + + /*allocate intra refresh buffers*/ + memSize=((height/16)*(width/16)*2+15)&0xfff0; + + for(i=0;iintraRefreshBufferIdArray[i]); + if (status!=SVA_OK) {return SVA_INTERNAL_VIDEO_ENCODER_ERROR;} + } + /*push in fifos*/ + for(i=0;ireadIntraRefreshBufferFifos.pushFifo,t_sva_buffer_id,pDesc->intraRefreshBufferIdArray[i]); + if (ffError!=SVA_FIFO_OK) {return SVA_INTERNAL_VIDEO_ENCODER_ERROR;} + ffError=PUSH_FIFO_ELEM(pDesc->writeIntraRefreshBufferFifos.pushFifo,t_sva_buffer_id,pDesc->intraRefreshBufferIdArray[1-i]); + if (ffError!=SVA_FIFO_OK) {return SVA_INTERNAL_VIDEO_ENCODER_ERROR;} + } + + /*allocate buffer list*/ + for(i=0;ibufferListIdArray[i]); + if (blmError!=SVA_BLM_OK) {return SVA_INTERNAL_VIDEO_ENCODER_ERROR;} + } + + /*allocate header buffers*/ + memSize=encodeAlgoDesc[pDesc->algoId].pGetMaxHeaderSize(instanceNum); + for(i=0;iheaderBufferBlockIdArray[i]); + if (mmError!=SVA_MM_OK) {return SVA_INTERNAL_VIDEO_ENCODER_ERROR;} + } + + /* allocate internal memory for deblocking*/ + /* We allocate such memory when deblocking is in the loop only*/ + if (pConf->inTheLoopFilter!=SVA_NONE_FILTER && pConf->outTheLoopFilter==SVA_NONE_FILTER) + { +//\/ memSize=((height/16+2)*(width/16+2)*4+15)&0xfff0; + if (SVA_EC_ALGO_MPEG4 == pDesc->algoId) + { + memSize=((height/16+2)*(width/16+2)*4+15)&0xfff0; + } + else if (SVA_EC_ALGO_H264 == pDesc->algoId) + { + //\/ minSize = (pH264Desc->picWidthInMbsMinus1+1) * (pH264Desc->picHeightInMapUnitsMinus1+1)* sizeof(t_sva_h264_h4d_param); + memSize=(((height/16)*(width/16)*(sizeof(t_sva_h264_h4d_param)))+15)&0xfff0; + } + + /* SARVESH: To achieve better performance with H264 encode the * + * 'Encode Deblocking Parameter Buffer' has been moved to eSRAM * + * instead of SDRAM as recommended by FW team. */ + + /*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!* + * !! SARVESH: Beware of allocating this buffer from eSRAM for * + * STn8810 as you may not have enough eSRAM area left after * + * allocation 48KB for search window buffer. Below algoId check * + * can be added and this buffer can always be allocated in SDRAM * + * if STn8810 platform is to be supported !! * + *!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/ + /* Alloc memory */ + mmError=sva_MM_AllocBlock(ESRAM_ID,memSize,SVA_MM_ALIGN_16BYTES,&pDesc->deblockingBufferBlockId); + //\/mmError=sva_MM_AllocBlock(SDRAM_ID,memSize,SVA_MM_ALIGN_16BYTES,&pDesc->deblockingBufferBlockId); + if (mmError!=SVA_MM_OK) {return SVA_INTERNAL_VIDEO_ENCODER_ERROR;} + /*set subtask to point on it*/ + for(i=0;ideblockingBufferBlockId,&frameBufferOut.addr_deblocking_param_buffer); + if (mmError!=SVA_MM_OK) {return SVA_INTERNAL_VIDEO_ENCODER_ERROR;} + /*update this field in subtask*/ + tmError=sva_TM_UpdateSubTaskField(SVA_TM_INTERMEDIATE_FIELD_TO_UPDATE,/*don't take sem since task is not scheduled*/ + pDesc->subtasksIdArray[i], SVA_TM_ENC_ADDR_OUT_FRAME_BUFFER, + FCMD_COPY,(t_uint32) &frameBufferOut.addr_deblocking_param_buffer,HCL_BITFIELD_OFFSET(t_sva_vec_frame_buffer_out,addr_deblocking_param_buffer), + sizeof(frameBufferOut.addr_deblocking_param_buffer)); + if (tmError!=SVA_TM_OK) {return SVA_INTERNAL_VIDEO_ENCODER_ERROR;} + } + } + + /* init window buffer address */ + for(i=0;iesRamBlockId,&internalBuffer.addr_search_window_buffer); + internalBuffer.addr_search_window_end=internalBuffer.addr_search_window_buffer+pDesc->esRamSize; + if (mmError!=SVA_MM_OK) {return SVA_INTERNAL_VIDEO_ENCODER_ERROR;} + + /*update this field in subtask*/ + tmError=sva_TM_UpdateSubTaskField(SVA_TM_INTERMEDIATE_FIELD_TO_UPDATE,/*don't take sem since task is not scheduled*/ + pDesc->subtasksIdArray[i], SVA_TM_ENC_ADDR_INTERNAL_BUFFER, + FCMD_COPY,(t_uint32) &internalBuffer.addr_search_window_buffer,HCL_BITFIELD_OFFSET(t_sva_vec_internal_buffer,addr_search_window_buffer), + sizeof(internalBuffer.addr_search_window_buffer)+sizeof(internalBuffer.addr_search_window_end)); + if (tmError!=SVA_TM_OK) {return SVA_INTERNAL_VIDEO_ENCODER_ERROR;} + } + + return SVA_OK; +} + +/****************************************************************************/ +/* NAME: t_bool sva_EC_IsConfigurationValid( */ +/* const t_sva_video_encoder_configuration *pConf */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will check that given configuration given to encode is */ +/* valid. This concern only part that is independant of algo/brc part. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - pConf: a pointer to the configuration to check */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: t_bool */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + DONE +*/ +PRIVATE t_bool sva_EC_IsConfigurationValid +( + const t_sva_video_encoder_configuration *pConf +) +{ + EC_CHECK_NULL_POINTER(pConf); + + /*only image mode is supported*/ + if (pConf->mode!=SVA_CODEC_IMAGE_MODE) {return FALSE;} + + + + /* Check param enum possible value range*/ + CHECK_RANGE0( pConf->inTheLoopFilter, SVA_NONE_FILTER, SVA_DEBLOCKING_DERINGING_FILTER); + CHECK_RANGE0( pConf->outTheLoopFilter, SVA_NONE_FILTER, SVA_DEBLOCKING_DERINGING_FILTER); + CHECK_RANGE0( pConf->brcMode, SVA_QP_CONSTANT, SVA_VBR); + CHECK_RANGE0( pConf->bufferingModel,SVA_BUFFERING_NONE, SVA_BUFFERING_ANNEXG); + + return TRUE; +} --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/encode/sva_encode.h @@ -0,0 +1,90 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ + +#ifndef __INC_SVA_ENCODE_H +#define __INC_SVA_ENCODE_H + +#include "sva.h" +#include "svap.h" +#include "sva_taskmgt.h" + +/******************************************************************************/ +/* Constants definitions */ +/******************************************************************************/ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* + * Define the symbols used to identify the various errors of the encode Module + */ +typedef enum { + SVA_EC_INVALID_TRANSITION = SVA_EC_LAST_ERROR, + SVA_EC_NO_MORE_AVAILABLE_INSTANCE, + SVA_EC_INVALID_INSTANCE_NB, + SVA_EC_INVALID_TASK_ID_NB, + SVA_EC_NOT_SUPPORTED, + SVA_EC_INVALID_CONTROL_PARAM, + SVA_EC_INVALID_PUSH, + SVA_EC_INVALID_BUFFER_TYPE, + SVA_EC_INVALID_BUFFER_SIZE, + SVA_EC_INVALID_CONFIGURATION, + SVA_EC_UNKNOWN_CMD_ID, + SVA_EC_UNEXPECTED_HW_EVENT, + SVA_EC_SYNCHRO_INFO_NOT_AVAILABLE, + SVA_EC_TI_LINKED_ERROR, + SVA_EC_BM_LINKED_ERROR, + SVA_EC_MM_LINKED_ERROR, + SVA_EC_FF_LINKED_ERROR, + SVA_EC_TM_LINKED_ERROR, + SVA_EC_NULL_POINTER_PARAMETER, + SVA_EC_FIFO_NOT_EMPTY, + SVA_EC_OK = HCL_OK +} t_sva_ec_error; + + +/******************************************************************************* +* PUBLIC Functions +*******************************************************************************/ + +PUBLIC t_sva_error sva_EC_Init( t_sva_block_id, t_size); +PUBLIC t_sva_error sva_EC_Reset( t_sva_service_id ); +PUBLIC t_sva_error sva_EC_Create( t_sva_service_id *); +PUBLIC t_sva_error sva_EC_Control(t_sva_service_id, t_sva_service_cmd_id, t_uint32 ); +PUBLIC t_sva_error sva_EC_Push(t_sva_service_id, t_sva_buffer_id, t_sva_push_mode, t_sva_buffer_type, t_sva_timestamp ); +PUBLIC t_sva_ec_error sva_EC_DispatchVirtualHwEvent(t_sva_tm_virtual_hw_event_id, t_sva_service_id, t_sva_tm_subtask_id, t_uint32, t_uint32, t_uint8, t_sva_event_desc *, t_uint32 *); +PUBLIC t_sva_error sva_EC_ProvideInternalNeeds( t_sva_service_id); +PUBLIC t_sva_error sva_EC_GetInternalNeeds(t_sva_service_id, t_size *); +PUBLIC t_sva_error sva_EC_Activate(t_sva_service_id, t_sva_service_mode, t_sva_fw_id *); +PUBLIC t_sva_error sva_EC_Inactivate(t_sva_service_id); +PUBLIC t_sva_error sva_EC_Delete(t_sva_service_id ); +PUBLIC t_sva_error sva_EC_GetParamsBufferSize(t_sva_service_id, t_sva_push_mode, t_size *); +//t_sva_video_encoder_configuration is in sva.h +// function is sva.h +//PUBLIC t_sva_error SVA_ConfigureVideoEncoder( t_sva_service_id, t_sva_video_encoder_configuration); +//PUBLIC t_sva_error SVA_GetVideoEncoderStatus(t_sva_service_id, t_sva_video_encoder_status *); +//PUBLIC t_sva_error SVA_UpdateVideoEncoderParams(t_sva_service_id, t_sva_update_cmd_type, t_sva_video_encoder_param_id, t_uint32 ); + +#ifdef __cplusplus +} /* allow C++ to use these headers */ +#endif /* __cplusplus */ + +#endif /* __INC_SVA_ENCODE_H */ +/* End of file - sva_encode.h */ --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/encode/sva_encodep.h @@ -0,0 +1,340 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ + +#ifndef __INC_SVA_ENCODEP_H +#define __INC_SVA_ENCODEP_H + +#include "hcl_defs.h" +#include "sva_encode.h" +#include "sva_taskmgt.h" +#include "sva_buffermgt.h" +#include "sva_fifo.h" +#include "sva_service.h" +#include "sva_ec_algo.h" +#include "sva_bufferlistmgt.h" + +/******************************************************************************/ +/* Constants definitions */ +/******************************************************************************/ + +#ifdef __DEBUG +/* + * Define number of event to log +*/ +#define LOG_DEPTH 16 +#endif + +/* + * Define the number of field inside a Grab Subtask descriptor (spec v0.96) + */ +#define ENCODE_FIELD_NUMBER 10 + +/* + * Define paramin field offset (spec v0.96) + */ +#define ENCODE_FIELD_PARAMIN 6 + +/* + * Define paramout field offset (spec v0.96) + */ +#define ENCODE_FIELD_PARAMOUT 7 + +/* + * Define in paraminout field offset (spec v0.96) + */ +#define ENCODE_FIELD_IN_PARAMINOUT 8 + +/* + * Define the default memory used to store subtasks descriptors + */ +#define ENCODE_DEFAULT_MEMORY_ID SDRAM_ID + +/* + * Define the default memory used to store param_out (infos) data + */ +#define ENCODE_DEFAULT_INFOS_MEMORY_ID SDRAM_ID + +/* + * Define macro to handle null pointer +*/ +#define EC_CHECK_NULL_POINTER(pointer) HCL_ASSERT(pointer!=NULL) + +/* + * Define macro to describe the size of block for encode +*/ + +#define SVA_EC_BLOCK_SIZE 4 + +/* + * Define various configuration limits for encode + * See in each algo box for limits +*/ + + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/******************************************************************************/ +/* Types definitions */ +/******************************************************************************/ +/* + * Define the various state of a Encode instance service + */ +typedef enum { + SVA_EC_NOT_INITIALIZED, + SVA_EC_WAIT_FOR_CONFIGURATION, + SVA_EC_WAIT_FOR_INTERNAL_NEEDS, + SVA_EC_WAIT_FOR_ACTIVATE, + SVA_EC_WAIT_FOR_START, + SVA_EC_FLUSHING_IN, + SVA_EC_FLUSHING_OUT, + SVA_EC_WAIT_FOR_DATA, + SVA_EC_RUNNING, + SVA_EC_ABORT_REQUESTED, + SVA_EC_STOP_REQUESTED, + SVA_EC_ERROR, + SVA_EC_LAST_DUMMY_STATE, + SVA_EC_TRANSITION_REJECTED +} t_sva_ec_state; + +/* + * Define the various activate state of an Encode instance service + */ +typedef enum { + SVA_EC_INACTIVE, + SVA_EC_IN_ACTIVATION, + SVA_EC_ACTIVE, + SVA_EC_IN_INACTIVATION, + SVA_EC_LAST_ACTIVATE_DUMMY_STATE, + SVA_EC_ACTIVATE_TRANSITION_REJECTED +} t_sva_ec_activate_state; + +/* + * Define the various transitions of the encode service + */ +typedef enum { + SVA_EC_CREATE, + SVA_EC_CONFIGURE, + SVA_EC_INTERNAL_NEEDS, + SVA_EC_ACTIVATE, + SVA_EC_INACTIVATE, + SVA_EC_CONTROL_START, + SVA_EC_CONTROL_STOP, + SVA_EC_CONTROL_ABORT, + SVA_EC_ALL_DEPENDENCIES_RESOLVED, + SVA_EC_PUSH, + SVA_EC_EVENT_EOK, + SVA_EC_EVENT_FAKE, + SVA_EC_EVENT_ACTIVE, + SVA_EC_EVENT_INACTIVE, + SVA_EC_RESET, + SVA_EC_CONTROL_DELETE, + SVA_EC_EVENT_ERROR, + SVA_EC_FLUSH_IN, + SVA_EC_FLUSH_OUT, + SVA_EC_CANCEL, + SVA_EC_UPDATE_PARAM, + SVA_EC_GET_PARAM_SIZE, + SVA_EC_GEN_DATA_UNIT, + SVA_EC_LAST_DUMMY_TRANSITION +} t_sva_ec_transition; + +/* + * Define the symbol used to qualify the state of the dependency + * for a given type of buffer + */ +typedef enum { + NOT_RESOLVED_INTERNAL_DEPENDENCY, + RESOLVED_INTERNAL_DEPENDENCY, + NOT_RESOLVED_DEPENDENCY, + RESOLVED_DEPENDENCY +} t_sva_ec_dependencies_state; + +/* + * Define the structure used to manage the subtasks dependency + */ +typedef struct { + t_sva_ec_dependencies_state brcAlgoDep; + t_sva_ec_dependencies_state sourceBufferDep; + t_sva_ec_dependencies_state bitstreamBufferDep; + t_sva_ec_dependencies_state destBufferDep; + t_sva_ec_dependencies_state fwRefBufferDep; + t_sva_ec_dependencies_state readIntraRefreshBufferDep; + t_sva_ec_dependencies_state writeIntraRefreshBufferDep; + t_sva_ec_dependencies_state infoBufferDep; + t_sva_ec_dependencies_state deblockingBufferDep; + t_sva_ec_dependencies_state croppingBufferDep; + t_sva_ec_dependencies_state brcBufferDep; +} t_sva_ec_dependencies_desc; + +/* + * Define the structure used to manage the dependencies of each subtasks + */ +typedef struct { + t_sva_tm_subtask_id subtaskId; + t_sva_ec_dependencies_desc dependencies; + t_bool isPrevSubTaskStrategicSkipped; + t_sva_buffer_list_id bufferListId; + t_sva_block_id headerBufferBlockId; + t_sva_timestamp timeStamp; + t_sva_offset_desc croppingVector; + t_sva_brc_user_request brcUserRequest; +} t_sva_ec_subtask_dependencies; + +/* + * Define the fifos used to manage the dependency + * The buffers, provided though the Push routine, are buffered inside the pushFifo + * When programming them (using them) into a subtask, then they are considered as used, + * as so pushed inside th inUseFifo + */ +typedef struct { + t_sva_fifo pushFifo; + t_sva_fifo inUseFifo; +} t_sva_ec_fifo_dep; + +/* + * Define the descriptor of a Grab service instance + */ +typedef struct { + t_sva_service_id serviceId; + t_sva_ec_state state; + t_sva_ec_activate_state activateState; + t_sva_video_encoder_configuration conf; + t_sva_ec_algo algoId; + t_sva_ec_dependencies_desc defaultDep; + t_sva_ec_fifo_dep sourceBufferFifos; + t_sva_ec_fifo_dep timeStampFifos; + t_sva_ec_fifo_dep bitstreamBufferFifos; + t_sva_ec_fifo_dep destBufferFifos; + t_sva_ec_fifo_dep fwRefBufferFifos; + t_sva_ec_fifo_dep readIntraRefreshBufferFifos; + t_sva_ec_fifo_dep writeIntraRefreshBufferFifos; + t_sva_ec_fifo_dep infoBufferFifos; + t_sva_ec_fifo_dep deblockingBufferFifos; + t_sva_ec_fifo_dep croppingBufferFifos; + t_sva_ec_fifo_dep brcBufferFifos; + t_sva_fifo subtasksDependencyFifo; + t_sva_fifo inUseSubtaskDependency; + t_sva_tm_subtask_id subtasksIdArray[SUBTASK_ENCODE_NUMBER]; + t_sva_buffer_list_id bufferListIdArray[SUBTASK_ENCODE_NUMBER]; + t_sva_tm_subtask_list_id subtasksListId; + t_uint32 handleForwardInitCnt; + /*internal memory allocated*/ + t_sva_block_id motionBufferBlockId; + t_sva_buffer_id destRefBufferIdArray[SUBTASK_ENCODE_NUMBER]; + t_sva_buffer_id intraRefreshBufferIdArray[SUBTASK_ENCODE_NUMBER]; + t_sva_block_id headerBufferBlockIdArray[SUBTASK_ENCODE_NUMBER]; + t_sva_block_id deblockingBufferBlockId; + /* internal pointers to allow handling of params. Memory is allocated in + * memory provide by user. + */ + t_logical_address paramInAddr; + t_logical_address paramOutAddr; + t_logical_address paramInOutAddr; + /*encoder status*/ + t_sva_video_encoder_status status; + /*esram block id and size*/ + t_sva_block_id esRamBlockId; + t_size esRamSize; +} t_sva_ec_descriptor; + + +#ifdef __DEBUG + /******************************************************************************/ + /* Trace Types definitions */ + /******************************************************************************/ + typedef struct { + t_sva_tm_virtual_hw_event_id event; + t_uint32 systemTime; + t_sva_tm_subtask_id subtaskId; + t_sva_service_id serviceId; + t_uint32 startHandlingTime; + t_uint32 stopHandlingTime; + } t_sva_ec_debug_event_desc; + typedef struct { + t_uint32 padding[3]; + t_uint32 nbOfEventReceived; + t_sva_ec_debug_event_desc eventDebugDesc[LOG_DEPTH]; + } t_sva_ec_debug_events; + + typedef struct { + t_sva_service_cmd_id command; + t_uint32 systemTime; + t_uint32 parameter; + t_uint32 padding; + } t_sva_ec_debug_command_desc; + typedef struct { + t_uint32 padding[3]; + t_uint32 nbOfCommandReceived; + t_sva_ec_debug_command_desc commandDebugDesc[LOG_DEPTH]; + } t_sva_ec_debug_commands; + + typedef struct { + t_sva_ec_state state;/*state before transition occur*/ + t_sva_ec_transition transition; + t_uint32 systemTime; + t_sva_ec_activate_state activateState;/*state before transition occur*/ + } t_sva_ec_debug_transition_desc; + typedef struct { + t_uint32 padding[3]; + t_uint32 nbOfTransitionReceived; + t_sva_ec_debug_transition_desc transitionDebugDesc[LOG_DEPTH]; + } t_sva_ec_debug_transitions; +#endif + +/* from tps_h4d_param structure from ref code: */ +typedef struct +{ + unsigned _0 : 2; unsigned A_l : 6; + unsigned _1 : 2; unsigned B_l : 6; + unsigned _2 : 2; unsigned A_c : 6; + unsigned _3 : 2; unsigned B_c : 6; + +} t_sva_h264_ab_index; + + + +typedef struct +{ + unsigned _0 : 2; unsigned h0 : 3; unsigned v0 : 3; + unsigned _1 : 2; unsigned h1 : 3; unsigned v1 : 3; + unsigned _2 : 2; unsigned h2 : 3; unsigned v2 : 3; + unsigned _3 : 2; unsigned h3 : 3; unsigned v3 : 3; + +} t_sva_h264_strength; + + + +typedef struct +{ + t_sva_h264_ab_index index[3]; + t_uint32 loc; + t_sva_h264_strength bs[4]; + +} t_sva_h264_h4d_param; + + +#ifdef __cplusplus +} /* allow C++ to use these headers */ +#endif /* __cplusplus */ + +#endif /* __INC_SVA_ENCODEP_H */ +/* End of file - sva_encodep.h */ + --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/events_management/sva_eventmgt.c @@ -0,0 +1,896 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ + +/*------------------------------------------------------------------------ + * Includes + *----------------------------------------------------------------------*/ +#include "hcl_defs.h" +#include "sva.h" +#include "sva_eventmgt.h" +#include "sva_eventmgtp.h" +#include "sva_fifo.h" +#include "sva_timemgt.h" +#include "sva_service.h" +#include "sva_hwp.h" +#include "sva_display.h" +#include "sva_decode.h" +#include "sva_grab.h" +#include "sva_still_encode.h" +#include "sva_still_decode.h" +#include "sva_encode.h" +#include "sva_openservicemgt.h" +#include "sva_stab.h" +#include "sva_tvo.h" + +/*------------------------------------------------------------------------ + * Global Variables + *----------------------------------------------------------------------*/ +PRIVATE t_sva_regs_mapping *pSVARegs; +PRIVATE t_sva_fifo serviceEventsFifo[SVA_NB_MAX_SERVICE];/* take the define from timemgt.h */ + +PRIVATE t_sva_fifo_id_state allocatedEventFifoId[SVA_NB_MAX_SERVICE]; + +PRIVATE t_sva_event_desc eventDesc[SIMULTANEOUS_USER_EVENTS_MAX_NUM]; + + +PRIVATE tp_sva_sv_DispatchHwEvent eventsDispatchTab[SVA_SW_PROCESSING + 1] = { + (tp_sva_sv_DispatchHwEvent) NULL, /* SVA_SERVICE_NONE */ + (tp_sva_sv_DispatchHwEvent) sva_GB_DispatchVirtualHwEvent, /* SVA_PREPROCESSOR */ + (tp_sva_sv_DispatchHwEvent) sva_DC_DispatchVirtualHwEvent, /* SVA_VIDEO_DECODER */ + (tp_sva_sv_DispatchHwEvent) sva_EC_DispatchVirtualHwEvent, /* SVA_VIDEO_ENCODER */ + (tp_sva_sv_DispatchHwEvent) sva_DP_DispatchVirtualHwEvent, /* SVA_POSTPROCESSOR */ + (tp_sva_sv_DispatchHwEvent) sva_SEC_DispatchVirtualHwEvent, /* SVA_STILL_IMAGE_ENCODER */ + (tp_sva_sv_DispatchHwEvent) sva_SDC_DispatchVirtualHwEvent, /* SVA_STILL_IMAGE_DECODER */ + (tp_sva_sv_DispatchHwEvent) sva_TV_DispatchVirtualHwEvent, /* SVA_TV_OUTPUT */ + (tp_sva_sv_DispatchHwEvent) sva_ST_DispatchVirtualHwEvent, /* SVA_SW_PROCESSING */ +}; + +/*------------------------------------------------------------------------ + * Private Macros + *----------------------------------------------------------------------*/ + +/*------------------------------------------------------------------------ + * PRIVATE Functions Prototypes + *----------------------------------------------------------------------*/ +PRIVATE t_sva_em_error sva_EM_ResetFifoIdPool(void); +PRIVATE t_sva_em_error sva_EM_ProvideFifoId (t_uint8* fifoId); +PRIVATE t_sva_em_error sva_EM_FreeFifoId (t_uint8 fifoId); + +/****************************************************************************/ +/* NAME: t_sva_em_error sva_EM_ResetFifoIdPool (void) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - none */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/* - SVA_OK : */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PRIVATE t_sva_em_error sva_EM_ResetFifoIdPool(void) { + + t_uint8 i; + for(i=0; iglobalIsr = pSVARegs->cfg.cfg_isr; + pPrivateStatus->irq1Isr = pSVARegs->cfg.cfg_iis; + /* read task interrupt registers*/ + for (taskIndex = ENCODE_TID;taskIndex <= TVO_TID; taskIndex = (t_sva_hw_task_id)(taskIndex + 1)) + { + if ((pPrivateStatus->globalIsr & (1UL << taskIndex)) != 0) + { + pTasksRegs = (t_sva_task_regs *)&pSVARegs->genTask.taskRegs[taskIndex]; + pPrivateStatus->taskContext[taskIndex].isr = SVA_HW_REG_R(taskIndex,isr); + pPrivateStatus->taskContext[taskIndex].iad = SVA_HW_REG_R(taskIndex,iad); + pPrivateStatus->taskContext[taskIndex].its = SVA_HW_REG_R(taskIndex,its); + + pPrivateStatus->taskContext[taskIndex].iad_err = SVA_HW_REG_R(taskIndex,iad_err); + pPrivateStatus->taskContext[taskIndex].its_err = SVA_HW_REG_R(taskIndex,its_err); + + /* Acknowledge the given interrupt sources */ + SVA_HW_REG_W(taskIndex, isr, pPrivateStatus->taskContext[taskIndex].isr); + } + + else + { + pPrivateStatus->taskContext[taskIndex].isr = 0; + pPrivateStatus->taskContext[taskIndex].iad = 0; + pPrivateStatus->taskContext[taskIndex].its = 0; + + pPrivateStatus->taskContext[taskIndex].iad_err = 0; + pPrivateStatus->taskContext[taskIndex].its_err = 0; + + } + } + /* read irp register only if we have a grab eof interrupt */ + if ((pPrivateStatus->taskContext[GRAB_TID].isr & MASK_BIT5) != 0) + { + pPrivateStatus->grpIrpRw = SVA_HW_READ_IRP(pSVARegs->cfg.cfg_irp_rw); + + pPrivateStatus->grpIrpRw &= 0xffff; + + if (pPrivateStatus->grpIrpRw != 0) {SVA_HW_WRITE_IRP(pSVARegs->cfg.cfg_irp_rw,0);} + pPrivateStatus->grpIrpError = SVA_HW_READ_IRP(pSVARegs->cfg.cfg_irp_error); + + pPrivateStatus->grpIrpError &= 0xffff; + + if (pPrivateStatus->grpIrpError != 0) {SVA_HW_WRITE_IRP(pSVARegs->cfg.cfg_irp_error,0);} + } + else + { + pPrivateStatus->grpIrpRw = 0; + pPrivateStatus->grpIrpError = 0; + } +} + +extern t_uint32 Last_IAD_EOT_ERR[5]; +extern t_uint32 Last_IAD_ERR[5]; + +void sva_ReadResetIadValue() +{ + t_sva_hw_task_id taskIndex; + volatile t_sva_task_regs *pTasksRegs; + + for (taskIndex = ENCODE_TID;taskIndex <= TVO_TID; taskIndex = (t_sva_hw_task_id)(taskIndex + 1)) + { + pTasksRegs = (t_sva_task_regs *)&pSVARegs->genTask.taskRegs[taskIndex]; + SVA_HW_REG_W(taskIndex,iad,0); /* Reset XXX_IAD */ + SVA_HW_REG_W(taskIndex,iad_err,0); /* Reset XXX_IAD_ERR */ + Last_IAD_EOT_ERR[taskIndex] = SVA_HW_REG_R(taskIndex,iad); + Last_IAD_ERR[taskIndex] = SVA_HW_REG_R(taskIndex,iad_err); + } + +} + +/****************************************************************************/ +/* NAME: t_bool SVA_IsIRQSrcActive( */ +/* t_sva_irq_src irqSrc, */ +/* t_sva_irq_status *pIrqStatus */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine SHALL be called for any IRQs related to HAMAC Video IP. */ +/* This procedure returns the current HW context (that is to say, takes a*/ +/* snapshot of the HW). */ +/* This procedure SHALL be called before calling SVA_ProcessIRQSrc() */ +/* routine in case where the SVA_GetIRQSrcStatus() is not used. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - irqSrc: IRQ Source identifier */ +/* */ +/* OUT : */ +/* - pIrqStatus: internal storage variable to save the HW context */ +/* */ +/* RETURN: t_bool */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_bool SVA_IsIRQSrcActive( + t_sva_irq_src irqSrc, + t_sva_irq_status *pIrqStatus + ) +{ + t_sva_hw_task_id taskIndex; + t_sva_irq_private_status *pPrivateStatus = (t_sva_irq_private_status *)pIrqStatus; + volatile t_sva_task_regs *pTasksRegs; + + (void) irqSrc;/*discard irqSrc*/ + + HCL_ASSERT(pIrqStatus!=NULL); + HCL_DEBUG_ASSERT(pPrivateStatus!=NULL); + + pPrivateStatus->globalIsr = pSVARegs->cfg.cfg_isr; + pPrivateStatus->irq1Isr = pSVARegs->cfg.cfg_iis; + for (taskIndex = ENCODE_TID; taskIndex <= TVO_TID; taskIndex = (t_sva_hw_task_id)(taskIndex + 1)) + { + if ((pPrivateStatus->globalIsr & (1UL << taskIndex)) != 0) + { + pTasksRegs = (t_sva_task_regs *)&pSVARegs->genTask.taskRegs[taskIndex]; + pPrivateStatus->taskContext[taskIndex].isr = SVA_HW_REG_R(taskIndex,isr); + pPrivateStatus->taskContext[taskIndex].iad = SVA_HW_REG_R(taskIndex,iad); + pPrivateStatus->taskContext[taskIndex].its = SVA_HW_REG_R(taskIndex,its); + + /* Acknowledge the given interrupt sources */ + SVA_HW_REG_W(taskIndex, isr, pPrivateStatus->taskContext[taskIndex].isr); + } + } + + return (t_bool)((pSVARegs->cfg.cfg_isr != 0)?TRUE:FALSE); +} + + +PUBLIC t_sva_tm_error sva_TM_TestToEmulateHWInterrupt(t_sva_tm_task_id taskId, t_uint32 *hwIad, t_uint32 *hwIsr, t_uint32 *hwIts); + +/****************************************************************************/ +/* NAME: t_sva_error SVA_ProcessIRQSrc( t_sva_irq_status *pIrqStatus ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine SHALL be called for any IRQs related to HAMAC Video IP. */ +/* It processes all IRQs sources saved into pIrqStatus. */ +/* Task management will transform these hardware interruption into virtual*/ +/* interruption (this mask to services the multitasking). */ +/* Services will then transform these virtual events into user events. */ +/* User will then retriewe user events using SVA_GetServicePendingEvents */ +/* API. */ +/* */ +/* PARAMETERS: */ +/* INOUT : */ +/* - pIrqStatus: internal storage variable to save the HW context */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/* - SVA_NO_MORE_PENDING_EVENT */ +/* */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_sva_error SVA_ProcessIRQSrc( + t_sva_irq_status *pIrqStatus +) +{ + t_sva_irq_private_status *pPrivateStatus = (t_sva_irq_private_status *)pIrqStatus; + t_sva_irq_private_status iPrivateStatus1 = *pPrivateStatus;//(t_sva_irq_private_status *)pIrqStatus; + t_sva_irq_private_status iPrivateStatus2 = *pPrivateStatus;//(t_sva_irq_private_status *)pIrqStatus; + + t_sva_hw_task_id taskIndex=ENCODE_TID; + t_sva_error svaError=SVA_OK; + + /* Fix me: What to do with these? */ + iPrivateStatus2.grpIrpError = 0; + iPrivateStatus2.grpIrpRw = 0; + iPrivateStatus2.irq1Isr = 0; + iPrivateStatus2.globalIsr = 0; + for (taskIndex = ENCODE_TID; taskIndex <= TVO_TID; taskIndex = (t_sva_hw_task_id)(taskIndex + 1)) + { + + if ((pPrivateStatus->globalIsr & (1UL << taskIndex)) != 0) + { + if(((iPrivateStatus1.taskContext[taskIndex].isr & ISR_ERR_MASK)!=0) && ((iPrivateStatus1.taskContext[taskIndex].isr & ISR_EOK_MASK)==0)) + { + HCL_ASSERT(0); + } + } + if(((iPrivateStatus1.taskContext[taskIndex].isr & ISR_ERR_MASK)!=0) && ((iPrivateStatus1.taskContext[taskIndex].isr & ISR_EOK_MASK)!=0)) + { + if((iPrivateStatus1.taskContext[taskIndex].isr & ISR_EOT_MASK) == 0) + { + + iPrivateStatus1.taskContext[taskIndex].iad = iPrivateStatus1.taskContext[taskIndex].iad_err ; + iPrivateStatus1.taskContext[taskIndex].its = iPrivateStatus1.taskContext[taskIndex].its_err ; + } /* end if */ + else + { + iPrivateStatus2.taskContext[taskIndex].iad = iPrivateStatus1.taskContext[taskIndex].iad_err ; + iPrivateStatus2.taskContext[taskIndex].its = iPrivateStatus1.taskContext[taskIndex].its_err ; + iPrivateStatus2.taskContext[taskIndex].isr = ISR_ERR_MASK; + + iPrivateStatus1.taskContext[taskIndex].isr &= ~ISR_ERR_MASK; + + if((iPrivateStatus1.taskContext[taskIndex].isr & ISR_EOK_MASK)!=0) + { + //iPrivateStatus1.taskContext[taskIndex].isr &= ~ISR_EOK_MASK; + iPrivateStatus2.taskContext[taskIndex].isr |= ISR_EOK_MASK; + iPrivateStatus2.globalIsr |= (1<irq1Isr & IIS_BE_MASK) + { + pSVARegs->cfg.cfg_iis = IIS_BE_MASK; + } + + if (pPrivateStatus->irq1Isr & IIS_EOI_MASK) + { + sva_TM_DispatchEOIEvent(); + pSVARegs->cfg.cfg_iis = IIS_EOI_MASK; + } + + +/* The following implementation is fully to be checked */ + + for (taskIndex = ENCODE_TID; taskIndex <= TVO_TID; taskIndex = (t_sva_hw_task_id)(taskIndex + 1)) + { + if ((pPrivateStatus->globalIsr & (1UL << taskIndex)) != 0) + { + // sva_TM_TestToEmulateHWInterrupt((t_sva_tm_task_id) taskIndex, &pPrivateStatus->taskContext[taskIndex].iad, &pPrivateStatus->taskContext[taskIndex].isr, &pPrivateStatus->taskContext[taskIndex].its); ///vk changes + sva_TM_DispatchHWEvent((t_sva_tm_task_id) taskIndex, + pPrivateStatus->taskContext[taskIndex].iad, + pPrivateStatus->taskContext[taskIndex].isr, + pPrivateStatus->taskContext[taskIndex].its, + (taskIndex == GRAB_TID ? pPrivateStatus->grpIrpRw : 0), + (taskIndex == GRAB_TID ? pPrivateStatus->grpIrpError : 0), + SIMULTANEOUS_VIRTUAL_EVENTS_MAX_NUM, + vitualHwEventDesc, + &nbVirtualHwEvents); + + for(i=0;itaskContext[taskIndex].isr &= ~((t_uint32)virtualEventId); + } + } + } + else if ( (serviceType != SVA_SERVICE_NONE) && (serviceType <= SVA_SW_PROCESSING) ) + { + /* It's not an open service, dispatch it internally.*/ + for(virtualEventId = SVA_TM_BOT_HW_EVENT; virtualEventId <= SVA_TM_LAST_HW_EVENT;virtualEventId=(t_sva_tm_virtual_hw_event_id)((t_uint32)virtualEventId<<1)) + { + if ((vitualHwEventDesc[i].virtualEventIdMask & virtualEventId) != 0) + { + t_uint8 j; + + svaError = (t_sva_error)(eventsDispatchTab[(t_uint32)(serviceType)](virtualEventId, + vitualHwEventDesc[i].serviceId, + vitualHwEventDesc[i].subtaskId, + vitualHwEventDesc[i].eventTimestamp, + vitualHwEventDesc[i].eventDate, + SIMULTANEOUS_USER_EVENTS_MAX_NUM, + eventDesc, + &nbUserEvents)); + if(svaError != SVA_OK) { return SVA_INTERNAL_EVENT_MGT_ERROR ;} + + + for(j=0; jtaskContext[taskIndex].isr &= ~((t_uint32)virtualEventId); + } + } + } + } + pPrivateStatus->globalIsr &= ~(1UL << taskIndex); + } + } + + + + return SVA_NO_MORE_PENDING_EVENT; +} + + +/****************************************************************************/ +/* NAME: t_bool SVA_AreServicePendingEvents(t_sva_service_id serviceId) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine checks if it exists any event related to a service. */ +/* */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - serviceId: Identifier of the service */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_bool */ +/* - TRUE : pending events for serviceId */ +/* - FALSE : no events for serviceId */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_bool SVA_AreServicePendingEvents(t_sva_service_id serviceId) +{ + t_bool retValue; + t_uint8 fifoId = READ_FIFO_ID_IN_SERVICE_ID(serviceId); + // t_sva_error status; + + /* TO BE ADDED: check serviceId */ + HCL_ASSERT(serviceId != NULL); + /*check for service id validity*/ + + //if (status!=SVA_OK) {return status; } + + retValue = (t_bool)!IS_FIFO_EMPTY(serviceEventsFifo[fifoId]); + + return retValue; +} + + + +/****************************************************************************/ +/* NAME: t_sva_error SVA_GetServicePendingEvents( */ +/* t_sva_service_id serviceId, */ +/* t_sva_event_desc *pEventDesc */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine provides (one by one) all the pending events related to */ +/* a given service. */ +/* */ +/* 1) The returned value (SVA_REMAINING_PENDING_EVENTS) means that there are*/ +/* some pending events related to the given service. */ +/* 2) The returned value (SVA_NO_MORE_PENDING_EVENT) means that all events */ +/* have been notified */ +/* 3) The returned value (SVA_NO_PENDING_EVENT_ERROR) means there is none */ +/* pending event */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - serviceId: Identifier of the service */ +/* */ +/* OUT : */ +/* - pEventDesc: descriptor of the pending event */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/* - See description for a list of possible error code */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_sva_error SVA_GetServicePendingEvents( + t_sva_service_id serviceId, + t_sva_event_desc *pEventDesc +) +{ + + t_sva_ff_error ffError=SVA_FIFO_OK; + t_uint8 fifoId; + //t_sva_error status; + + (void) ffError; + + HCL_ASSERT(pEventDesc!=NULL); + + + /* TO BE ADDED: check serviceId */ + HCL_ASSERT(serviceId != NULL); + /*check for service id validity*/ + /*status=sva_DC_CheckServiceId(serviceId); + if (status!=SVA_OK) {return status; } + */ + + fifoId = READ_FIFO_ID_IN_SERVICE_ID(serviceId); + + if (IS_FIFO_EMPTY(serviceEventsFifo[fifoId])) {return SVA_NO_PENDING_EVENT_ERROR;} + + ffError = POP_FIFO_ELEM(serviceEventsFifo[fifoId], t_sva_event_desc, *pEventDesc); + + return (t_sva_error)((IS_FIFO_EMPTY(serviceEventsFifo[fifoId]))?SVA_NO_MORE_PENDING_EVENT:SVA_REMAINING_PENDING_EVENTS); +} + + + + +/****************************************************************************/ +/* NAME: t_sva_error SVA_AcknowledgeEvent( */ +/* const t_sva_event_desc *pEventDesc */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine acknowledges an occured event related to a given buffer.*/ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - pEventDesc: Descriptor of the event to acknowledge */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/* - SVA_UNKNOWN_EVENT_DESC */ +/* - SVA_OK */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_sva_error SVA_AcknowledgeEvent( + const t_sva_event_desc *pEventDesc + ) +{ + HCL_ASSERT(pEventDesc!=NULL); + + /* What has to be done here ???? */ + + return SVA_OK; +} --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/events_management/sva_eventmgt.h @@ -0,0 +1,97 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ + +#ifndef __INC_SVA_EM_H +#define __INC_SVA_EM_H + +#include "hcl_defs.h" +#include "sva.h" +#include "svap.h" +#include "sva_hwp.h" + + +/******************************************************************************/ +/* Constants definitions */ +/******************************************************************************/ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/******************************************************************************/ +/* Types definitions */ +/******************************************************************************/ +/* + * Define the errors for the module + */ + +typedef enum { + SVA_EM_ERROR = SVA_EM_LAST_ERROR, + SVA_EM_NO_MORE_FIFO_ID, + SVA_EM_FIFO_ID_ALREADY_FREE, + SVA_EM_OK = SVA_OK +}t_sva_em_error; + +/* + * Define the various events those can be dispatched by event management module + */ +typedef enum { + BOT_HW_EVENT = ISR_BOT_MASK, + EOT_HW_EVENT = ISR_EOT_MASK, + ACK_HW_EVENT = ISR_ACK_MASK, + EOW_HW_EVENT = ISR_EOW_MASK, + BOF_HW_EVENT = ISR_BOF_MASK, + UBU_HW_EVENT = ISR_UBU_MASK, + GS_HW_EVENT = ISR_GS_MASK, + BOW_HW_EVENT = ISR_BOW_MASK, + EOF_HW_EVENT = ISR_CER_MASK, + ERR_HW_EVENT = ISR_ERR_MASK, + EOK_HW_EVENT = ISR_EOK_MASK, + EOI_HW_EVENT = IIS_EOI_MASK << SHIFT_BYTE1, + BERR_HW_EVENT= IIS_BE_MASK << SHIFT_BYTE1 +} t_sva_hw_event_id; + + + + +/******************************************************************************* +* PUBLIC Functions +*******************************************************************************/ +PUBLIC t_sva_error sva_EM_Init(t_logical_address, t_logical_address); +PUBLIC t_sva_error sva_EM_Create(t_sva_service_id*); +PUBLIC t_sva_error sva_EM_GetInternalNeeds(t_size *); +PUBLIC t_sva_error sva_EM_ProvideInternalNeeds(t_sva_service_id ); +PUBLIC t_sva_error sva_EM_Delete(t_sva_service_id); + +PRIVATE t_sva_error sva_ProcessIRQSrc_X(t_sva_irq_status *); +/* Described into sva.h +PUBLIC void SVA_GetIRQSrcStatus(t_sva_irq_src, t_sva_irq_status *); +PUBLIC t_bool SVA_IsIRQSrcActive(t_sva_irq_src, t_sva_irq_status *); +PUBLIC t_sva_error SVA_ProcessIRQSrc(t_sva_irq_status *); +PUBLIC t_bool SVA_AreServicePendingEvents(t_sva_service_id); +PUBLIC t_sva_error SVA_GetServicePendingEvents(t_sva_service_id, t_sva_event_desc *); +PUBLIC t_sva_error SVA_AcknowledgeEvent(const t_sva_event_desc *); +*/ + +#ifdef __cplusplus +} /* allow C++ to use these headers */ +#endif /* __cplusplus */ + +#endif /* __INC_SVA_EM_H */ +/* End of file - sva_eventmgt.h */ --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/events_management/sva_eventmgtp.h @@ -0,0 +1,84 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ + +#ifndef __INC_SVA_EMP_H +#define __INC_SVA_EMP_H + +#include "hcl_defs.h" +#include "sva_hwp.h" + +/******************************************************************************/ +/* Constants definitions */ +/******************************************************************************/ +/* + * Define the maximum number of events those could be occured simultaneously + * on a HAMAC Video Line + */ +#define SIMULTANEOUS_VIRTUAL_EVENTS_MAX_NUM 16 + +/* + * Define the maximum number of events those could be occured simultaneously + * for a given task + */ +#define SIMULTANEOUS_USER_EVENTS_MAX_NUM 64 + + +/******************************************************************************/ +/* Types definitions */ +/******************************************************************************/ +/* + * Define the state of the allocated fifoId + */ + +typedef enum { + SVA_FIFO_ID_FREE, + SVA_FIFO_ID_USED, + SVA_FIFO_ID_UNKNOWN +} t_sva_fifo_id_state; + + +/* + * Define the hw context saved for a given HV Task when an interrupt occurs + */ +typedef struct { + t_uint32 isr; + t_uint32 iad; + t_uint32 its; + t_uint32 iad_err; + t_uint32 its_err; +} t_sva_task_hw_context; + +/* + * Define the internal status used to save the HV hw interrupt context + */ +typedef struct { + t_uint32 globalIsr; + t_uint32 irq1Isr; + t_uint32 grpIrpRw; + t_uint32 grpIrpError; + t_sva_task_hw_context taskContext[SVA_NUM_TASKS]; +} t_sva_irq_private_status; + +/******************************************************************************* +* PUBLIC Functions +*******************************************************************************/ + +#endif /* __INC_SVA_EMP_H */ +/* End of file - sva_eventmgtp.h */ + --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/events_management/sva_irqmgt.c @@ -0,0 +1,225 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ + +/*------------------------------------------------------------------------ + * Includes + *----------------------------------------------------------------------*/ +#include "hcl_defs.h" +#include "sva.h" +#include "sva_irqmgt.h" + +/*------------------------------------------------------------------------ + * Global Variables + *----------------------------------------------------------------------*/ +PRIVATE t_sva_regs_mapping *pSVARegs; + +/*------------------------------------------------------------------------ + * Private Macros + *---------------------------------------G-------------------------------*/ + +/*------------------------------------------------------------------------ + * PRIVATE Functions Prototypes + *----------------------------------------------------------------------*/ + +/****************************************************************************/ +/* NAME: void SVA_SetBaseAddress ( */ +/* t_logical_address svaRegLogicalBaseAddr */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine initializes the HV HCL IRQs Management */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - svaRegLogicalBaseAddr: HV Registers Space logical base address */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC void SVA_SetBaseAddress(t_logical_address svaRegLogicalBaseAddr) +{ + pSVARegs = (t_sva_regs_mapping *)svaRegLogicalBaseAddr; +} + +/****************************************************************************/ +/* NAME: t_sva_irq_src SVA_GetIRQSrc( t_sva_irq_num irqNum ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine SHALL be called for any IRQs related to HAMAC Video IP. */ +/* This procedure returns only the first IRQ source number available. */ +/* */ +/* N.B: In our case, this procedure returns only SVA_IRQ since we provide */ +/* a high level of abstraction through complex event description. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - irqNum: Identifier of the IRQ asserted (between the 2 of the HV) */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_irq_src: HV IRQ Source identifier (in our case always SVA_IRQ)*/ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_sva_irq_src SVA_GetIRQSrc( +t_sva_irq_num irqNum +) +{ + (void) irqNum;/*discard irqNum*/ + + return SVA_IRQ; +} + + + + +/****************************************************************************/ +/* NAME: void SVA_ClearIRQSrc( t_sva_irq_src irqSrc ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine allows to acknowledge the irqSrc interrupt source. */ +/* In our case, do nothing */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - irqSrc: IRQ Source identifier (in our case, only SVA_IRQ) */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: void */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC void SVA_ClearIRQSrc( +t_sva_irq_src irqSrc +) +{ + (void) irqSrc;/*discard irqSrc*/ +} + + +/****************************************************************************/ +/* NAME: void SVA_EnableIRQSrc( t_sva_irq_src irqSrc ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine allows to enable the given irqSrc interrupt source */ +/* (HW level mask). */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - irqSrc: IRQ Source identifier (in our case, only SVA_IRQ) */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: void */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC void SVA_EnableIRQSrc( +t_sva_irq_src irqSrc +) +{ + (void) irqSrc;/*discard irqSrc*/ + + pSVARegs->cfg.cfg_imr = (MASK_IRQ1 | MASK_TVO_IRQ | MASK_DPL_IRQ | MASK_GRB_IRQ | MASK_VDC_IRQ | MASK_VEC_IRQ); +} + +/****************************************************************************/ +/* NAME: void SVA_DisableIRQSrc( t_sva_irq_src irqSrc ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine allows to disable the given irqSrc interrupt source */ +/* (HW level mask). */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - irqSrc: IRQ Source identifier (in our case, only SVA_IRQ) */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: void */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC void SVA_DisableIRQSrc( +t_sva_irq_src irqSrc +) +{ + (void) irqSrc;/*discard irqSrc*/ + + pSVARegs->cfg.cfg_imr &= ~(MASK_IRQ1 | MASK_TVO_IRQ | MASK_DPL_IRQ | MASK_GRB_IRQ | MASK_VDC_IRQ | MASK_VEC_IRQ); +} + +/****************************************************************************/ +/* NAME: t_bool SVA_IsPendingIRQSrc( t_sva_irq_src irqSrc ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine allows to check if the given irqSrc source is active. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - irqSrc: IRQ Source identifier (in our case, only SVA_IRQ) */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: t_bool */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_bool SVA_IsPendingIRQSrc( +t_sva_irq_src irqSrc +) +{ + (void) irqSrc;/*discard irqSrc*/ + + return (t_bool)((pSVARegs->cfg.cfg_isr == 0)?FALSE:TRUE); +} + +/****************************************************************************/ +/* NAME: t_sva_irq_num SVA_GetDeviceId( t_sva_irq_src irqSrc ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine allows to get the device id that had raised the irqSrc. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - irqSrc: IRQ Source identifier (in our case, only SVA_IRQ) */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: t_sva_irq_num: always SVA_IRQ_0 */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_sva_irq_num SVA_GetDeviceId( +t_sva_irq_src irqSrc +) +{ + (void) irqSrc;/*discard irqSrc*/ + + return SVA_IRQ_0; +} + + +/* End of irqMgt.c */ --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/events_management/sva_irqmgt.h @@ -0,0 +1,42 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ + +#ifndef __INC_SVA_IM_H +#define __INC_SVA_IM_H + +#include "hcl_defs.h" +#include "sva.h" +#include "sva_hwp.h" + + + +/* +t_sva_error SVA_SetBaseAddress(t_logical_address); +t_sva_error SVA_GetIRQSrc(t_sva_irq_num); +t_sva_error SVA_ClearIRQSrc(t_sva_irq_src); +t_sva_error SVA_EnableIRQSrc(t_sva_irq_src); +t_sva_error SVA_DisableIRQSrc(t_sva_irq_src); +t_sva_error SVA_IsPendingIRQSrc(t_irq_src); +t_sva_error SVA_GetDeviceId(t_sva_irq_src); +*/ + + +#endif /* __INC_SVA_IM_H */ +/* End of file - sva_irqmgt.h */ + --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/firmware_management/sva_fwmgt.c @@ -0,0 +1,1907 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ + +/*------------------------------------------------------------------------ + * Includes + *----------------------------------------------------------------------*/ +#include "hcl_defs.h" +#include "sva_fwmgt.h" +#include "sva_fwmgtp.h" +#include "hloader.h" +#include "sva_timemgt.h" +#include "sva_hwp.h" +#include "sva_taskmgt.h" +#include "sva_hwtaskmgt.h" +//#include "../decode/sva_decodep.h" +//#include "../decode/h264/sva_dc_h264.h" + +#include "sva_decodep.h" +#include "sva_dc_h264.h" + +/*------------------------------------------------------------------------ + * Global Variables + *----------------------------------------------------------------------*/ +PRIVATE t_sva_fm_internal_desc IntFwDesc; //stores base address and ccp synchro code +PRIVATE t_sva_fw_desc FwDesc[MAX_FW_REGISTERED]; //stores t_sva_fw_desc provided by TM +PRIVATE t_sva_fm_id_mgt FwIdMgt[MAX_FW_REGISTERED]; //manages FW id availability and registered FW address +PRIVATE t_sva_fm_current_fw_mgt currentFwMgt; //manages information related to downloaded FW +PRIVATE t_sva_fm_irp_internal_desc IrpFwDesc; /* manage irp firmware information */ +t_sva_fw_set_feature FwSetFeature[MAX_FW_REGISTERED*MAX_NB_SET_FEATURE]; //manages information related to the set of feature of fwId +t_uint32 Hard_Reset=0; +extern t_sva_config_regs_mapping1 *saveRegValue; +/*------------------------------------------------------------------------ + * Private Macros + *----------------------------------------------------------------------*/ + + +/*------------------------------------------------------------------------ + * Private Constants + *----------------------------------------------------------------------*/ +const t_system_address dummySystemAddress = {0, 0}; +const t_ahb_zone dummyAhbZone = {{0, 0}, {0, 0}, 0}; + +/*------------------------------------------------------------------------ + * PRIVATE Functions Prototypes + *----------------------------------------------------------------------*/ +PRIVATE t_bool sva_FM_areNewFeaturesIncludedInCurrentFeatures(t_sva_fw_features, t_sva_fw_features); +PRIVATE t_bool sva_FM_areFeaturesUsedInCurrentFW(t_uint32 *pFwFeaturesUsed); +PRIVATE t_sva_fm_error sva_FW_boot(t_bool); +#if __STN_8815 == 10 +PRIVATE void sva_FW_softReset(void); +#endif +PRIVATE void sva_Host_SoftReset(t_sva_fm_internal_desc *IntFwDesc); + +/*------------------------------------------------------------------------ + * SVA level API + *----------------------------------------------------------------------*/ + +/****************************************************************************/ +/* NAME: t_sva_error SVA_RegisterFirmware ( */ +/* t_logical_address fwInfoLogicalAddress, */ +/* t_sva_fw_id *pFwId */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will register a new firmware. FM_Mgt user doesn't know*/ +/* about the content of FW descriptor: he only provides an address */ +/* corresponding to .inf file information */ +/* An id will be returned to user to identify FW during future API call*/ +/* Fw provided is also checked regarding targeted programming model */ +/* and HW platform */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - fwInfoLogicalAddress: address of .inf file content */ +/* (Describe firmware features) */ +/* */ +/* OUT : */ +/* - pFwId : return firmware id to user. */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/* - SVA_OK : firmware has been registered and return pFwId value */ +/* could be use for API call. */ +/* - SVA_NO_MORE_FIRMWARE_ID : firmware management is unable to register*/ +/* firmware since no space is availale to store information in */ +/* firmware management internal database. */ +/* */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_sva_error SVA_RegisterFirmware( + t_logical_address fwInfoLogicalAddress, + t_sva_fw_id *pFwId +) +{ + t_uint32 i=0,j=0,k=0; + t_uint32 numberSetFeature; + t_sva_fw_desc *pFwDesc; + + pFwDesc = (t_sva_fw_desc *) fwInfoLogicalAddress; + + HCL_ASSERT(pFwId!=NULL); + + //Check provided FW + //At a first implementation, only one kind of structure type for t_sva_fw_desc is supported + + // Coherancy between parameter from .inf file and current compilation + if ( !(pFwDesc->programmingModel & SVA_FW_PROGRAMMING_MODEL) || + !(pFwDesc->hwVersion & SVA_FW_HARDWARE_VERSION ) ) + return SVA_INCOHERENT_FW_PROVIDED; + + //Check if a FWId instance is available + while ((FwIdMgt[i].idAvailability != SVA_FM_ID_AVAILABLE) && (i != MAX_FW_REGISTERED)) {i++;} + + if (i >= MAX_FW_REGISTERED) {return SVA_NO_MORE_FIRMWARE_ID;} + + //Save FwSetFeature + if(pFwDesc->structureVersion==0) + { + j=0; + while(j<(MAX_FW_REGISTERED*MAX_NB_SET_FEATURE) && FwSetFeature[j].fwFeatures!=0) {j++;} + if (j >= (MAX_FW_REGISTERED*MAX_NB_SET_FEATURE)) + { + return SVA_INCOHERENT_FW_PROVIDED; + } + else + { + FwSetFeature[j].fwFeatures=pFwDesc->fwFeatures[0]; + FwSetFeature[j].fwId=i; + } + + } + else if(pFwDesc->structureVersion==1) + { + numberSetFeature=pFwDesc->reservedOrSetFeature; + j=0; + for(k=0;k= (MAX_FW_REGISTERED*MAX_NB_SET_FEATURE)) + { + return SVA_INCOHERENT_FW_PROVIDED; + } + else + { + FwSetFeature[j].fwFeatures=pFwDesc->fwFeatures[k]; + FwSetFeature[j].fwId=i; + } + } + } + + //Save FwDesc + FwDesc[i]=*pFwDesc; + FwIdMgt[i].idAvailability=SVA_FM_ID_NOT_AVAILABLE; + + //Generate FWId + *pFwId=i; + + return SVA_OK; +} + +/****************************************************************************/ +/* NAME: t_sva_error SVA_IrpInit( */ +/* t_logical_address fwAddress, */ +/* t_size fwSize */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will register an irp firmware. Note that it must be */ +/* call by user after SVA_AddPrivateMemoryChunk() call and before */ +/* activating any service. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - fwAddress: address of irp firmware. */ +/* - fwSize: size of irp firmware in bytes. */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/* - SVA_OK : firmware has been registered and return pFwId value */ +/* could be use for API call. */ +/* - SVA_NOT_SUPPORTED_YET : hardware doesn't support irp. */ +/* - SVA_OUT_OF_MEMORY : not enough memory to store firmware. */ +/* */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_sva_error SVA_IrpInit( + t_logical_address fwAddress, + t_size fwSize +) +{ + t_sva_mm_error mmError; + t_sva_error svaError; + t_uint8 *pSrc = (t_uint8 *) fwAddress; + t_uint8 *pDst; + t_uint32 i; + + + svaError = SVA_OK; + + /* Check if hardware support irp*/ + if (SVA_FW_IRP_SUPPORTED == FALSE) + { + return SVA_NOT_SUPPORTED_YET; + } + else + { + if(IrpFwDesc.eWarpFwAddress != fwAddress) + { + /* Allocate memory in irpFwBlockId and copy firmware. */ + mmError = sva_MM_AllocBlock(SDRAM_ID, fwSize, SVA_MM_ALIGN_16BYTES, &IrpFwDesc.irpFwBlockId); + if (mmError != SVA_MM_OK) {return SVA_OUT_OF_MEMORY;} + + mmError=sva_MM_GetBlockPhysicalAddress(IrpFwDesc.irpFwBlockId,(t_logical_address *) &pDst); + HCL_DEBUG_ASSERT(mmError==SVA_MM_OK); + IntFwDesc.pSVARegs->cfg.cfg_irp_fw_addr = (t_uint32)pDst; + IntFwDesc.pSVARegs->cfg.cfg_irp_fw_size = fwSize; + + + mmError = sva_MM_GetBlockLogicalAddress(IrpFwDesc.irpFwBlockId,(t_logical_address *) &pDst); + HCL_DEBUG_ASSERT(mmError==SVA_MM_OK); + + for(i=0;i= MAX_FW_REGISTERED) {return SVA_INCOHERENT_FW_PROVIDED;} + + //Check if FwId was previously registered + if (FwIdMgt[fwId].idAvailability == SVA_FM_ID_AVAILABLE) {return SVA_UNREGISTERED_FIRMWARE_ID;} + + //Unregister FwId + FwIdMgt[fwId].idAvailability = SVA_FM_ID_AVAILABLE; + FwIdMgt[fwId].fwAddress = 0; + FwIdMgt[fwId].setNbFeature = 0; + + FwDesc[fwId].structureVersion = 0; + FwDesc[fwId].reservedOrSetFeature = 0; + FwDesc[fwId].programmingModel = 0; + FwDesc[fwId].fwVersion.minor = 0; + FwDesc[fwId].fwVersion.major = 0; + FwDesc[fwId].fwVersion.version = 0; + FwDesc[fwId].hwVersion = 0; + for(i=0;i= MAX_FW_REGISTERED) {return SVA_INCOHERENT_FW_PROVIDED;} + + //Check if FwId was previously registered + if (FwIdMgt[fwId].idAvailability == SVA_FM_ID_AVAILABLE) {return SVA_UNREGISTERED_FIRMWARE_ID;} + + FwIdMgt[fwId].fwAddress = firmwareAddress; + + return SVA_OK; +} + + +/*------------------------------------------------------------------------ + * Internal level API + *----------------------------------------------------------------------*/ +/****************************************************************************/ +/* NAME: t_sva_fm_error sva_FM_Init ( */ +/* t_system_address svaRegSystemBaseAddr, */ +/* t_system_address svaMemSystemBaseAddr, */ +/* t_uint32 ccpSyncroCode, */ +/* t_bool lowLevelClockGating */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine initializes the SVA HCL Firmware management */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - svaRegSystemBaseAddr: SVA Registers Space base address */ +/* - svaMemSystemBaseAddr: SVA Memory Space base address */ +/* - ccpSyncroCode: synchronization code used in the CCP interface */ +/* default value is 0x03020100 */ +/* - lowLevelClockGating: TRUE: low level, FALSE: high level */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_fm_error */ +/* - SVA_FM_OK : init done */ +/* */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_sva_fm_error sva_FM_Init( + t_system_address svaRegSystemBaseAddr, + t_system_address svaMemSystemBaseAddr, + t_uint32 ccpSyncroCode, + t_bool lowLevelClockGating +) +{ + t_sva_mm_error mmError = SVA_MM_OK; + t_loader_error loaderError; + t_uint32 i=0,j=0; + //t_uint8 instanceNum; //For removing compiler warning + + + + /* init irp firmware management structure */ + IrpFwDesc.isIrpFwPresent = FALSE; + IrpFwDesc.isIrpFwBoot = FALSE; + + //Init FwIdMgt and FwDesc structures + for (i=0;i 10 + { + sva_Host_SoftReset(&IntFwDesc); + } + #endif + #endif + //sva_Host_SoftReset(&IntFwDesc); + + loaderError = HLOADER_Init(&IntFwDesc.LoaderConfig); + HCL_ASSERT(loaderError==LOADER_OK); + + IntFwDesc.sdramSystemAddress.physical = NULL; + IntFwDesc.sdramSystemAddress.logical = NULL; + IntFwDesc.sdramSize = 0; + IntFwDesc.sdramBlockId = INVALID_SDRAM_BLOCK_ID; + + return SVA_FM_OK; + +} /* End of sva_FM_Init() function. */ + + +PRIVATE t_uint32 savedFwID; +void sva_FM_Save() +{ + savedFwID = currentFwMgt.downloadedFwId; +} + +t_sva_tm_error sva_TM_RecheckHwInterrupts (void); + +//void sva_TM_Restore(); //For removing warning + +void sva_FM_Restore() +{ + sva_FM_Download(savedFwID); +// SVA_DisableIRQSrc (SVA_IRQ); + + sva_TM_RecheckHwInterrupts(); +/* + SVA_DisableIRQSrc (SVA_IRQ); + + sva_TM_Restore(); +*/ +// SVA_EnableIRQSrc (SVA_IRQ); +} + +/****************************************************************************/ +/* NAME: t_sva_fm_error sva_FM_Download(t_sva_fw_id fwId) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will download a new firmware into SVA. After load all */ +/* features will be mark as unregistered. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - fwId: firmware to load and boot. */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_fm_error */ +/* - SVA_FM_OK : firmware has been load and boot. */ +/* - SVA_FM_UNKNOWN_FIRMWARE_ID : fwId incoherent. */ +/* - SVA_FM_UNREGISTERED_FIRMWARE_ID : requiredFwId has not been */ +/* registered. */ +/* - SVA_FM_FW_NO_ADDRESS : address where to find mmf is not known.*/ +/* */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ + +PUBLIC t_sva_fm_error sva_FM_Download(t_sva_fw_id fwId) +{ + t_uint32 i=0; + //t_uint8 instanceNum; //For removing compiler warning + t_uint8 setNbFeatureFind=0; + t_loader_error loaderError; + t_sva_fm_error fmError; + + //Check FwId + if (fwId >= MAX_FW_REGISTERED) {return SVA_FM_UNKNOWN_FIRMWARE_ID;} + + //Check if FwId was previously registered + if (FwIdMgt[fwId].idAvailability == SVA_FM_ID_AVAILABLE) {return SVA_FM_UNREGISTERED_FIRMWARE_ID;} + + //Check if FwId address was provided + if (FwIdMgt[fwId].fwAddress == 0) {return SVA_FM_FW_NO_ADDRESS;} + + +#ifdef __STN_8815 + if (IrpFwDesc.isIrpFwPresent == TRUE && IntFwDesc.irp_booted == TRUE) + { + IntFwDesc.pSVARegs->cfg.cfg_irp_save_addr = IntFwDesc.vpipCtxSaveSystemAddress.physical; + + IntFwDesc.warmbootCfgRegs.cfg_irp_error = IntFwDesc.pSVARegs->cfg.cfg_irp_error; + IntFwDesc.warmbootCfgRegs.cfg_irp_fw_addr = IntFwDesc.pSVARegs->cfg.cfg_irp_fw_addr; + IntFwDesc.warmbootCfgRegs.cfg_irp_fw_size = IntFwDesc.pSVARegs->cfg.cfg_irp_fw_size; + IntFwDesc.warmbootCfgRegs.cfg_irp_ptr = IntFwDesc.pSVARegs->cfg.cfg_irp_ptr; + IntFwDesc.warmbootCfgRegs.cfg_irp_rw = IntFwDesc.pSVARegs->cfg.cfg_irp_rw; + IntFwDesc.warmbootCfgRegs.cfg_irp_save_addr = IntFwDesc.pSVARegs->cfg.cfg_irp_save_addr; + + sva_TM_HW_SendTaskCommand(SVA_TM_GRAB, SVA_TM_TCMD_SAVE_VPIP_STATE, 0 /*ignored */); + IntFwDesc.vpipCtxSaved = TRUE; + } +#endif + //Init information related to current FW + currentFwMgt.downloadedFwId=SVA_FW_INVALID_ID; + currentFwMgt.instanceNb=0; //used only by open service + for (i=0;ihostRegs)[MMIO_ICACHE_EMUL_UDATA0]=0x01; + + ((volatile t_uint16 *)IntFwDesc.pSVAMem->hostRegs)[MMIO_ICACHE_EMUL_UADDRL]=0x01; + + //HLOADER_CacheConfig(&IntFwDesc.LoaderConfig,0x00); + } + /*Hard Soft Reset is not working with 8815A0*/ + + #ifdef __STN_8815 + #if __STN_8815 > 10 + sva_Host_SoftReset(&IntFwDesc); + #elif __STN_8815 == 10 + { + sva_FW_softReset(); + } + #endif + #endif + + //Increase clock speed to increase FW code download + IntFwDesc.pSVARegs->cfg.cfg_clk=1; + + //Configure HV registers that are intended to be setted before MMDSP init procedure + IntFwDesc.pSVARegs->cfg.cfg_ice=0; /* workaround for pif fifo full bug (valid for 8800/8810 AA and AB) */ + IntFwDesc.pSVARegs->cfg.cfg_csc = IntFwDesc.ccpSyncroCode; + IntFwDesc.pSVARegs->cfg.cfg_cgc = IntFwDesc.lowLevelClockGating; + + // Address in ARM memory space where MMF file content can be read + IntFwDesc.LoaderConfig.FirmwareBaseAddr = (t_uint32 *) FwIdMgt[fwId].fwAddress; + // Size in bytes of the MMF file : Not used + IntFwDesc.LoaderConfig.FirmwareSize = 0; + + + loaderError=HLOADER_FirmwareLoad(&IntFwDesc.LoaderConfig); + if (loaderError!=LOADER_OK) {return SVA_FM_FW_LOAD_ERROR;} + + + + /*reduce clock speed*/ + IntFwDesc.pSVARegs->cfg.cfg_clk=0; + +#ifdef __STN_8815 + + + //Inactivate (disable and flush) Instruction cache + //enable + HLOADER_CacheConfig(&IntFwDesc.LoaderConfig,0x07); + + //flush + { + + ((volatile t_uint16 *)IntFwDesc.pSVAMem->hostRegs)[MMIO_ICACHE_EMUL_UDATA0]=0x01; + + ((volatile t_uint16 *)IntFwDesc.pSVAMem->hostRegs)[MMIO_ICACHE_EMUL_UADDRL]=0x01; + + + + } + + + + + +/* + if (FwDesc[fwId].fwFeatures[0]&SVA_FW_FEAT_IRP == SVA_FW_FEAT_IRP) + { + IrpFwDesc.isIrpFwPresent = TRUE; + } + else + { + IrpFwDesc.isIrpFwPresent = FALSE; + }*/ +#endif + + //find correct feature set to put it in currentFwMgt + if(FwIdMgt[fwId].setNbFeature==0){return SVA_FM_UNKNOWN_FIRMWARE_ID;} + i=0; + while(i=MAX_FW_REGISTERED*MAX_NB_SET_FEATURE) + return SVA_FM_FW_INTERNAL_ERROR; + + /*boot mmdsp*/ + fmError=sva_FW_boot(FwSetFeature[i].fwFeatures&SVA_FW_FEAT_IRP?TRUE:FALSE); + if(fmError!=SVA_FM_OK){return SVA_FM_FW_INTERNAL_ERROR;} + + currentFwMgt.downloadedFwId=fwId; + + currentFwMgt.downloadedSetFeature=FwSetFeature[i].fwFeatures; + + if(IntFwDesc.pSVARegs->cfg.cfg_tim == 0x00) + IntFwDesc.pSVARegs->cfg.cfg_tim = IntFwDesc.pSVARegs->cfg.cfg_tim + 8; + + { + extern void sva_ReadResetIadValue(); + sva_ReadResetIadValue(); + } + +#ifdef __STN_8815 + if (IrpFwDesc.isIrpFwPresent == TRUE && IntFwDesc.irp_booted == TRUE) + { + IntFwDesc.pSVARegs->cfg.cfg_irp_save_addr = IntFwDesc.vpipCtxSaveSystemAddress.physical; + sva_TM_HW_SendTaskCommand(SVA_TM_GRAB, SVA_TM_TCMD_LOAD_VPIP_STATE, 0 /*ignored */); + + IntFwDesc.pSVARegs->cfg.cfg_irp_error = IntFwDesc.warmbootCfgRegs.cfg_irp_error; + IntFwDesc.pSVARegs->cfg.cfg_irp_fw_addr = IntFwDesc.warmbootCfgRegs.cfg_irp_fw_addr; + IntFwDesc.pSVARegs->cfg.cfg_irp_fw_size = IntFwDesc.warmbootCfgRegs.cfg_irp_fw_size; + IntFwDesc.pSVARegs->cfg.cfg_irp_ptr = IntFwDesc.warmbootCfgRegs.cfg_irp_ptr; + IntFwDesc.pSVARegs->cfg.cfg_irp_rw = IntFwDesc.warmbootCfgRegs.cfg_irp_rw; + IntFwDesc.pSVARegs->cfg.cfg_irp_save_addr = IntFwDesc.warmbootCfgRegs.cfg_irp_save_addr; + + IntFwDesc.vpipCtxSaved = FALSE; + } +#endif + +#if 1 +{ + /* HCL workaround for FW VI15547 for resetting cfg_irp_grabhq_status register after every FW boot */ + /* This should be removed ifyou are using FW V3.13.2.1 and above */ + IntFwDesc.pSVARegs->cfg.cfg_irp_grabhq_status = (t_uint16) 0x0; +} +#endif + return (SVA_FM_OK); +} /* End of sva_FM_Download() function. */ + +/****************************************************************************/ +/* NAME :t_sva_error SVA_WasDeepSleeepEntered() */ +/*--------------------------------------------------------------------------*/ +/* Description : */ +/* IN : */ +/* */ +/* OUT: */ +/****************************************************************************/ +t_bool SVA_WasDeepSleepEntered() +{ + if (saveRegValue->sva_context_magic_number == SVA_CONTEXT_MAGIC_NUMBER) + { + return (IntFwDesc.pSVARegs->cfg.cfg_tim == 0)?TRUE:FALSE; + } + else return FALSE; +} + +/****************************************************************************/ +/* NAME: t_sva_fm_error sva_FM_ResetFirmwareShareArea ( */ +/* t_sva_fw_id fwId) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine is intended for task management to signal that FW */ +/* (corresponding to FwId) availability is no more insured in share area*/ +/* At a first implementation, task management is supposed to call it */ +/* as soon as FW has been loaded thanks to sva_FM_Download() */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - fwId: Describe firmware features. */ +/* */ +/* OUT : */ +/* - none */ +/* */ +/* RETURN: */ +/* t_sva_fm_error */ +/* - SVA_FM_OK : firmwareAddress for fwId has been resetted. */ +/* - SVA_FM_UNKNOWN_FIRMWARE_ID : fwId is not a registered value. */ +/* - SVA_FM_UNREGISTERED_FIRMWARE_ID : fwId is not a registered value.*/ +/* */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_sva_fm_error sva_FM_ResetFirmwareShareArea(t_sva_fw_id fwId) +{ + //Check FwId + if (fwId >= MAX_FW_REGISTERED) return SVA_FM_UNKNOWN_FIRMWARE_ID; + + //Check if FwId was previously registered + if (FwIdMgt[fwId].idAvailability == SVA_FM_ID_AVAILABLE) return SVA_FM_UNREGISTERED_FIRMWARE_ID; + + FwIdMgt[fwId].fwAddress = 0; + + return SVA_FM_OK; +} + +/****************************************************************************/ +/* NAME: t_sva_fm_error sva_FM_GetVersion (t_version *pFwVersion) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine is intended to provide information about downloaded FW*/ +/* version. if no FW downloaded, returns SVA_FM_NO_FIRMWARE_LOADED */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* */ +/* */ +/* OUT : */ +/* - *pFwVersion: Describe downloaded firmware version */ +/* */ +/* RETURN: */ +/* t_sva_fm_error */ +/* - SVA_FM_OK : pFwVersion was updated with current FW information*/ +/* - SVA_FM_NO_FIRMWARE_LOADED : No Fw loaded at this time */ +/* */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_sva_fm_error sva_FM_GetFwVersion(t_version *pFwVersion) +{ + HCL_ASSERT(pFwVersion!=NULL); + + //Check if a Fw was previously downloaded + if (currentFwMgt.downloadedFwId == SVA_FW_INVALID_ID) return SVA_FM_NO_FIRMWARE_LOADED; + + // firmware version number + pFwVersion->version =(t_bitfield)((IntFwDesc.pSVARegs->idn.idn_frv>>SHIFT_QUARTET2)&MASK_QUARTET); + pFwVersion->major =(t_bitfield)((IntFwDesc.pSVARegs->idn.idn_frv>>SHIFT_QUARTET1)&MASK_QUARTET); + pFwVersion->minor =(t_bitfield)((IntFwDesc.pSVARegs->idn.idn_frv>>SHIFT_QUARTET0)&MASK_QUARTET); + + return SVA_FM_OK; +} + +/****************************************************************************/ +/* NAME: t_sva_fm_error sva_FM_GetPatchLevel( t_uint32 *pFwPatchLevel ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine returns the current patch level of the SVA Firmware. */ +/* */ +/* PARAMETERS: */ +/* IN : none */ +/* */ +/* OUT : */ +/* - pFwPatchLevel: returned patch level value */ +/* */ +/* RETURN: */ +/* t_sva_fm_error */ +/* - SVA_FM_OK : pFwPatchLevel was updated with current FW info */ +/* - SVA_FM_NO_FIRMWARE_LOADED : No Fw loaded at this time */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_sva_fm_error sva_FM_GetPatchLevel( t_uint32 *pFwPatchLevel ) +{ + HCL_ASSERT(pFwPatchLevel!=NULL); + + //Check if a Fw was previously downloaded + if (currentFwMgt.downloadedFwId == SVA_FW_INVALID_ID) return SVA_FM_NO_FIRMWARE_LOADED; + + //firmware patch number + *pFwPatchLevel=(t_bitfield)((IntFwDesc.pSVARegs->idn.idn_frv>>SHIFT_QUARTET3)&MASK_QUARTET); + + return SVA_FM_OK; +} + + +/****************************************************************************/ +/* NAME: t_sva_fm_error sva_FM_InformPrivateMemoryChunk( */ +/* t_sva_memory_id memoryId, */ +/* t_system_address systemAddress, */ +/* t_size size); */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine is called form main function SVA_AddPrivateMemoryChunk() */ +/* in order to inform firmware module a chunk has been provided to SVA HCL */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - memoryId : memory ID of the chunk. */ +/* - systemAddress : System address of the chunk. */ +/* - size : Size of the chunk given to HCL. */ +/* */ +/* OUT : */ +/* - none. */ +/* */ +/* RETURN: */ +/* t_sva_fm_error */ +/* - SVA_FM_OK */ +/* - SVA_FM_FW_INTERNAL_ERROR : Can't allocate sdramBuffer */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_sva_fm_error sva_FM_InformPrivateMemoryChunk( + t_sva_memory_id memoryId, t_system_address systemAddress, t_size size) +{ + t_sva_mm_error mmStatus; + t_sva_block_id prog2BlockId; + t_sva_block_id data2BlockId; + t_sva_block_id data2BlockId_24; + + if (SVA_FW_MMDSP_RUN_FROM_DDR == TRUE) + { + /* MMDSP source code will have to run from DDR, save its caracteristics */ + if ( (memoryId == SDRAM_ID) && (size != 0)) + { + IntFwDesc.chunkSystemAddress = systemAddress; + IntFwDesc.chunkSize = size; + + /* Get a free block for FW to be loaded by loader (if needed) */ + + mmStatus = sva_MM_AllocBlock(memoryId, SVA_FW_MMDSP_SDRAM_SIZE, SVA_MM_ALIGN_1024BYTES, + &IntFwDesc.sdramBlockId); + if (mmStatus != SVA_MM_OK) return(SVA_FM_FW_INTERNAL_ERROR); + + mmStatus = sva_MM_GetBlockSystemAddress(IntFwDesc.sdramBlockId, &IntFwDesc.sdramSystemAddress); + if (mmStatus != SVA_MM_OK) return(SVA_FM_FW_INTERNAL_ERROR); + + /* prg1 and data1 in DDR */ + IntFwDesc.LoaderConfig.ProgramZone1.Base.logical = IntFwDesc.sdramSystemAddress.logical; + IntFwDesc.LoaderConfig.ProgramZone1.Base.physical = IntFwDesc.sdramSystemAddress.physical; + IntFwDesc.LoaderConfig.ProgramZone1.Top.logical = IntFwDesc.sdramSystemAddress.logical + SVA_FW_MMDSP_SDRAM_SIZE/2 - 1; + IntFwDesc.LoaderConfig.ProgramZone1.Top.physical = IntFwDesc.sdramSystemAddress.physical + SVA_FW_MMDSP_SDRAM_SIZE/2 - 1; + IntFwDesc.LoaderConfig.ProgramZone1.Size = SVA_FW_MMDSP_SDRAM_SIZE/2; + + IntFwDesc.LoaderConfig.Data16Zone1.Base.logical = IntFwDesc.sdramSystemAddress.logical + SVA_FW_MMDSP_SDRAM_SIZE/2; + IntFwDesc.LoaderConfig.Data16Zone1.Base.physical = IntFwDesc.sdramSystemAddress.physical + SVA_FW_MMDSP_SDRAM_SIZE/2; + IntFwDesc.LoaderConfig.Data16Zone1.Top.logical = IntFwDesc.sdramSystemAddress.logical + SVA_FW_MMDSP_SDRAM_SIZE - 1; + IntFwDesc.LoaderConfig.Data16Zone1.Top.physical = IntFwDesc.sdramSystemAddress.physical + SVA_FW_MMDSP_SDRAM_SIZE - 1; + IntFwDesc.LoaderConfig.Data16Zone1.Size = SVA_FW_MMDSP_SDRAM_SIZE/2; + + + /* prog2 and data2 in eSRAM */ + + + + mmStatus = sva_MM_AllocBlock(ESRAM_ID,SVA_FW_ESRAM_DATA24_SIZE, SVA_MM_ALIGN_256BYTES, &data2BlockId_24); + if (mmStatus != SVA_MM_OK) return(SVA_FM_FW_INTERNAL_ERROR); + + mmStatus = sva_MM_GetBlockSystemAddress(data2BlockId_24, &IntFwDesc.LoaderConfig.Data24Zone2.Base); + if (mmStatus != SVA_MM_OK) return(SVA_FM_FW_INTERNAL_ERROR); + + + IntFwDesc.LoaderConfig.Data24Zone2.Top.physical = IntFwDesc.LoaderConfig.Data24Zone2.Base.physical + SVA_FW_ESRAM_DATA24_SIZE -1; + IntFwDesc.LoaderConfig.Data24Zone2.Top.logical = IntFwDesc.LoaderConfig.Data24Zone2.Base.logical+ SVA_FW_ESRAM_DATA24_SIZE -1; + IntFwDesc.LoaderConfig.Data24Zone2.Size = SVA_FW_ESRAM_DATA24_SIZE; + + mmStatus = sva_MM_AllocBlock(ESRAM_ID,SVA_FW_ESRAM_DATA16_SIZE, SVA_MM_ALIGN_256BYTES, &data2BlockId); + if (mmStatus != SVA_MM_OK) return(SVA_FM_FW_INTERNAL_ERROR); + + mmStatus = sva_MM_GetBlockSystemAddress(data2BlockId, &IntFwDesc.LoaderConfig.Data16Zone2.Base); + if (mmStatus != SVA_MM_OK) return(SVA_FM_FW_INTERNAL_ERROR); + IntFwDesc.LoaderConfig.Data16Zone2.Top.physical = IntFwDesc.LoaderConfig.Data16Zone2.Base.physical + SVA_FW_ESRAM_DATA16_SIZE -1; + IntFwDesc.LoaderConfig.Data16Zone2.Top.logical = IntFwDesc.LoaderConfig.Data16Zone2.Base.logical+ SVA_FW_ESRAM_DATA16_SIZE -1; + IntFwDesc.LoaderConfig.Data16Zone2.Size = SVA_FW_ESRAM_DATA16_SIZE; + + + + mmStatus = sva_MM_AllocBlock(ESRAM_ID,SVA_FW_ESRAM_PROG2_SIZE, SVA_MM_ALIGN_256BYTES, &prog2BlockId); + if (mmStatus != SVA_MM_OK) return(SVA_FM_FW_INTERNAL_ERROR); + + mmStatus = sva_MM_GetBlockSystemAddress(prog2BlockId, &IntFwDesc.LoaderConfig.ProgramZone2.Base); + if (mmStatus != SVA_MM_OK) return(SVA_FM_FW_INTERNAL_ERROR); + IntFwDesc.LoaderConfig.ProgramZone2.Top.physical = IntFwDesc.LoaderConfig.ProgramZone2.Base.physical + SVA_FW_ESRAM_PROG2_SIZE -1; + IntFwDesc.LoaderConfig.ProgramZone2.Top.logical = IntFwDesc.LoaderConfig.ProgramZone2.Base.logical + SVA_FW_ESRAM_PROG2_SIZE -1; + IntFwDesc.LoaderConfig.ProgramZone2.Size = SVA_FW_ESRAM_PROG2_SIZE; + + + + } + } + return(SVA_FM_OK); + +} /* End of sva_FM_InformPrivateMemoryChunk() function. */ + + +/****************************************************************************/ +/* NAME: t_sva_error sva_FM_ConfigurePrivateMemoryChunk() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine set up the Data16_1 and Data24 sections within the */ +/* MMDSP+ memory. It removes the SDRAM default mapping previously set */ +/* by sva_FM_InformPrivateMemoryChunk, then it creates a data24 section*/ +/* and an extended data16_1 section. This function must be called with */ +/* the right parameters in order to use the VC1 decoder, H264 encode */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - additionnalZone : Type of zone to be allocated */ +/* INOUT: */ +/* - modifiedZoneSize: Pointer to size of the extended data16_1 */ +/* section <-> size of the */ +/* VC1 decoder image buffer section = */ +/* (nb of buffer * buffer_size) */ +/* */ +/* OUT : - zoneAddress : start address of the dedicated zone */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_sva_fm_error sva_FM_ConfigurePrivateMemoryChunk( t_sva_dedicated_area_purpose additionalZone, + t_size *modifiedZoneSize, + t_system_address * zoneAddress) { + + t_sva_mm_error mmStatus; + t_uint32 data16_zone1_size = *modifiedZoneSize + SVA_FW_MMDSP_SDRAM_SIZE - (SVA_FW_SDRAM_PROG_ZONE1_SIZE + SVA_FW_SDRAM_DATA24_ZONE1_SIZE); + + if ((additionalZone != SVA_VC1_IMAGE_BUFFER_AREA)&&(additionalZone != SVA_H264_INTERNAL_AREA)&&(additionalZone != SVA_H264_ENC_FW_PROG_ZONE1_AREA)&& (additionalZone != SVA_SW_PREPROC_BUFFER_AREA)) return SVA_FM_FW_INTERNAL_ERROR; + HCL_DEBUG_ASSERT(zoneAddress != NULL); + + if (SVA_FW_MMDSP_RUN_FROM_DDR == TRUE) + { + /* remove the block already allocated */ + mmStatus = sva_MM_FreeBlock(IntFwDesc.sdramBlockId); + if (mmStatus != SVA_MM_OK) return SVA_FM_FW_INTERNAL_ERROR; + + /* allocate onr big block : SVA_FW_MMDSP_SDRAM_SIZE + additional zone */ + mmStatus = sva_MM_AllocBlock(SDRAM_ID, ((*modifiedZoneSize)+SVA_FW_MMDSP_SDRAM_SIZE), SVA_MM_ALIGN_1024BYTES, &IntFwDesc.sdramBlockId); + if (mmStatus != SVA_MM_OK) return SVA_FM_FW_INTERNAL_ERROR; + + mmStatus = sva_MM_GetBlockSystemAddress(IntFwDesc.sdramBlockId, &IntFwDesc.sdramSystemAddress); + if (mmStatus != SVA_MM_OK) return SVA_FM_FW_INTERNAL_ERROR; + + /* prg1 and data1 (16 & 24) in DDR : SVA_FW_SDRAM_PROG_ZONE1_SIZE */ + IntFwDesc.LoaderConfig.ProgramZone1.Base.logical = IntFwDesc.sdramSystemAddress.logical; + IntFwDesc.LoaderConfig.ProgramZone1.Base.physical = IntFwDesc.sdramSystemAddress.physical; + IntFwDesc.LoaderConfig.ProgramZone1.Top.logical = IntFwDesc.sdramSystemAddress.logical + SVA_FW_SDRAM_PROG_ZONE1_SIZE - 1; + IntFwDesc.LoaderConfig.ProgramZone1.Top.physical = IntFwDesc.sdramSystemAddress.physical + SVA_FW_SDRAM_PROG_ZONE1_SIZE - 1; + IntFwDesc.LoaderConfig.ProgramZone1.Size = SVA_FW_SDRAM_PROG_ZONE1_SIZE; + + // DATA24_1 Memory SVA_FW_SDRAM_DATA24_ZONE1_SIZE + IntFwDesc.LoaderConfig.Data24Zone1.Base.logical = IntFwDesc.sdramSystemAddress.logical + SVA_FW_SDRAM_PROG_ZONE1_SIZE; + IntFwDesc.LoaderConfig.Data24Zone1.Base.physical = IntFwDesc.sdramSystemAddress.physical + SVA_FW_SDRAM_PROG_ZONE1_SIZE; + IntFwDesc.LoaderConfig.Data24Zone1.Top.logical = IntFwDesc.sdramSystemAddress.logical + SVA_FW_SDRAM_PROG_ZONE1_SIZE + SVA_FW_SDRAM_DATA24_ZONE1_SIZE - 1; + IntFwDesc.LoaderConfig.Data24Zone1.Top.physical = IntFwDesc.sdramSystemAddress.physical + SVA_FW_SDRAM_PROG_ZONE1_SIZE + SVA_FW_SDRAM_DATA24_ZONE1_SIZE - 1; + IntFwDesc.LoaderConfig.Data24Zone1.Size = SVA_FW_SDRAM_DATA24_ZONE1_SIZE; + + // DATA16_1 Memory (*modifiedZoneSize + SVA_FW_MMDSP_SDRAM_SIZE - (SVA_FW_SDRAM_PROG_ZONE1_SIZE + SVA_FW_SDRAM_DATA24_ZONE1_SIZE)) + IntFwDesc.LoaderConfig.Data16Zone1.Base.logical = IntFwDesc.sdramSystemAddress.logical + SVA_FW_SDRAM_PROG_ZONE1_SIZE + SVA_FW_SDRAM_DATA24_ZONE1_SIZE; + IntFwDesc.LoaderConfig.Data16Zone1.Base.physical = IntFwDesc.sdramSystemAddress.physical + SVA_FW_SDRAM_PROG_ZONE1_SIZE + SVA_FW_SDRAM_DATA24_ZONE1_SIZE; + IntFwDesc.LoaderConfig.Data16Zone1.Top.logical = IntFwDesc.sdramSystemAddress.logical + SVA_FW_SDRAM_PROG_ZONE1_SIZE + SVA_FW_SDRAM_DATA24_ZONE1_SIZE + data16_zone1_size - 1; + IntFwDesc.LoaderConfig.Data16Zone1.Top.physical = IntFwDesc.sdramSystemAddress.physical + SVA_FW_SDRAM_PROG_ZONE1_SIZE + SVA_FW_SDRAM_DATA24_ZONE1_SIZE + data16_zone1_size - 1; + IntFwDesc.LoaderConfig.Data16Zone1.Size = data16_zone1_size; + + *zoneAddress = IntFwDesc.LoaderConfig.Data16Zone1.Base; + *modifiedZoneSize = data16_zone1_size; + } + return(SVA_FM_OK); +} + +/****************************************************************************/ +/* STANDARD SERVICE SPECIFIC FUNCTIONS */ +/****************************************************************************/ + +/****************************************************************************/ +/* NAME: t_bool sva_FM_IsFirmwareChangeNeededByFeatures( */ +/* t_sva_fw_features newFeatures) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine check if currently download fw can support additionnals*/ +/* features provide by user. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - newFeatures: list of features for which API will check if it's */ +/* supported by current loaded firmware. */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_bool */ +/* - TRUE : current firmware can support additionnal features */ +/* requested. */ +/* - FALSE : current firmware can't support additionnal features */ +/* requested. */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_bool sva_FM_IsFirmwareChangeNeededByFeatures(t_sva_fw_features newFeatures) +{ + t_bool isFWChange=TRUE; + + //Check if a FW has already been loaded + if (currentFwMgt.downloadedFwId != SVA_FW_INVALID_ID) + { + if(sva_FM_areNewFeaturesIncludedInCurrentFeatures(newFeatures,currentFwMgt.downloadedSetFeature)) + {isFWChange=FALSE;} + } + + return isFWChange; +} + + +/****************************************************************************/ +/* NAME: t_sva_fm_error sva_FM_GetFirmwareIdByFeatures( */ +/* t_sva_fw_features newFeatures, */ +/* t_sva_fw_id *pFwId) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* First, routine check that new Features are known by registered FW */ +/* Then, routine will try to find a firmwareId in it's database that */ +/* can support currently used features plus new features required by */ +/* user. */ +/* Choosed algorithm is basic: first FW (in the registering order ) */ +/* satisfying requested Features is choosen( even if there is another */ +/* FW covering more features) */ +/* It will also check that an address is associated to FW */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - newFeatures: list of additional features requested by user */ +/* */ +/* OUT : */ +/* - pFwId: returned firmware id that support actual features plus */ +/* the one requested by user (newFeatures) */ +/* If such a firmware doesn't exist then value returned will */ +/* be SVA_FW_INVALID_ID. */ +/* */ +/* RETURN: */ +/* t_sva_fm_error */ +/* - SVA_FM_OK : always return Ok. */ +/* - SVA_FM_FEATURES_UNKNOWN_BY_REGISTERED_FW : newFeatures requested*/ +/* are unknown by FW registered in database */ +/* - SVA_FM_FW_NO_ADDRESS : FW identified as *pFwId but its */ +/* address was not previously provided */ +/* user should call SVA_SetFirmwareShareArea() */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_sva_fm_error sva_FM_GetFirmwareIdByFeatures( + t_sva_fw_features newFeatures, + t_sva_fw_id *pFwId +) +{ + t_uint32 i=0,j=0,fwFeaturesCurrentlyUsed; + t_bool fwFound= FALSE; + t_sva_fw_features setFeatureFind=0; + t_sva_fw_features wantedFeatures; + + //Check pointer parameters + HCL_ASSERT(pFwId!=NULL); + + //Check that requested new Features are known by at least 1 FW in the database + i=0; + do + { + if ((IrpFwDesc.isIrpFwPresent == FALSE && (newFeatures & FwSetFeature[i].fwFeatures) == newFeatures) || + (IrpFwDesc.isIrpFwPresent == TRUE && (newFeatures & (FwSetFeature[i].fwFeatures | SVA_FW_FEAT_IRP)) == newFeatures)) + { + fwFound= TRUE; + } + i++; + } + while ((fwFound == FALSE) && (i != MAX_FW_REGISTERED*MAX_NB_SET_FEATURE)); + + if (fwFound == FALSE) //new Fetures unknown in FW database + {return SVA_FM_FEATURES_UNKNOWN_BY_REGISTERED_FW;} + + + //Test if a FW has been previously downloaded + if(currentFwMgt.downloadedFwId != SVA_FW_INVALID_ID) + { + //Test if at least 1 Feature is Registered on this FW + if (sva_FM_areFeaturesUsedInCurrentFW(&fwFeaturesCurrentlyUsed) == TRUE) + { + //desired features are then the new one + those corresponding to downloaded FW + wantedFeatures = newFeatures | fwFeaturesCurrentlyUsed; + } + else + //no features are registered on this FW + { + wantedFeatures = newFeatures; + } + } + + else + //A FW has NOT already been downloaded + { + wantedFeatures = newFeatures; + } + + //Parse Registered FW database to find suitable FW + i=0; + fwFound= FALSE; + do + { + if ((IrpFwDesc.isIrpFwPresent == FALSE && (wantedFeatures & FwSetFeature[i].fwFeatures) == wantedFeatures) || + (IrpFwDesc.isIrpFwPresent == TRUE && (wantedFeatures & (FwSetFeature[i].fwFeatures | SVA_FW_FEAT_IRP)) == wantedFeatures)) + { + fwFound= TRUE; + } + i++; + } + while ((fwFound == FALSE) && (i != MAX_FW_REGISTERED)); + + //no suitable FW in registered FW database + if (fwFound == FALSE) {*pFwId=SVA_FW_INVALID_ID;} + else + //provide suitable FW + { + *pFwId = FwSetFeature[i-1].fwId; + //Test if Fw address was already provided + if (FwIdMgt[*pFwId].fwAddress == 0) {return SVA_FM_FW_NO_ADDRESS;} + + //Find set feature number to put it in FwIdMgt + j=0; + while(j> i) & 1) == 1) //one feature instance to be added + { + if ( currentFwMgt.featuresMgt[i] >= SVA_FW_FEAT_INSTANCE_MAX_NUMBER) + {return SVA_FM_FEATURES_OVERFLOW;} //maximum instance number for a specific feature reached + else + { + (currentFwMgt.featuresMgt[i])++; //add a new instance related to feature i + } + } + } + + return SVA_FM_OK; +} + +/****************************************************************************/ +/* NAME: t_sva_fm_error sva_FM_UnRegisterFeaturesUse( */ +/* t_sva_fw_features featuresToUnregister) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will unregister featuresToUnregister as unuses by */ +/* current loaded firmware. */ +/* Features must be unregistered the same number of times they have */ +/* been registered. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - featuresToUnregister: list of features to unregister by */ +/* current loaded firmware. */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_fm_error */ +/* - SVA_FM_OK : features has been unregistered */ +/* - SVA_FM_NO_FIRMWARE_LOADED : no firmware has been loaded. So */ +/* featuresToUnregister has not been unregistered. */ +/* - SVA_FM_FEATURES_UNDERFLOW : one of the features in featuresToRegister*/ +/* has been unregistered too many times. */ +/* */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_sva_fm_error sva_FM_UnRegisterFeaturesUse( + t_sva_fw_features featuresToUnregister +) +{ + t_uint32 i=0; + + //Check that a FW is already loaded + if(currentFwMgt.downloadedFwId == SVA_FW_INVALID_ID) {return SVA_FM_NO_FIRMWARE_LOADED;} + + //UnRegister suitable features in currentFwMgt + for (i=0;i> i) & 1) == 1) //one feature instance to be removed + { + if ( currentFwMgt.featuresMgt[i] == 0) + {return SVA_FM_FEATURES_UNDERFLOW;} //minimum instance number for a specific feature reached + else + { + (currentFwMgt.featuresMgt[i])--; //remove an instance related to feature i + } + } + } + + return SVA_FM_OK; +} + +/****************************************************************************/ +/* OPEN SERVICE SPECIFIC FUNCTIONS */ +/****************************************************************************/ + + +/****************************************************************************/ +/* NAME: t_sva_fm_error sva_FM_TestFirmwareChangeNeedByFirmwareId( */ +/* t_sva_fw_id fmId, t_bool *pIsFWChangeNeeded) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine check if currently downloaded fw is the firmware */ +/* requested by user with fwId. */ +/* Targets Open Service */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - fmId: Id of firmware for which API has to check if it's the one */ +/* loaded or not. */ +/* */ +/* OUT : *pIsFWChangeNeeded */ +/* - TRUE : current firmware is the firmware requested by user */ +/* - FALSE : current firmware isn't the firmware requested by user */ +/* */ +/* RETURN: */ +/* t_sva_fm_error */ +/* SVA_FM_UNKNOWN_FIRMWARE_ID if incorrect FwId */ +/* SVA_FM_UNREGISTERED_FIRMWARE_ID if FW not registered */ +/* SVA_FM_OK if OK */ +/* */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_sva_fm_error sva_FM_TestFirmwareChangeNeedByFirmwareId(t_sva_fw_id fwId, t_bool *pIsFWChangeNeeded) +{ + t_uint32 downloadedFwId; + + //Check pointer parameters + HCL_ASSERT(pIsFWChangeNeeded!=NULL); + + //Check FwId + if (fwId >= MAX_FW_REGISTERED) return SVA_FM_UNKNOWN_FIRMWARE_ID; + + //Check if FwId was previously registered + if (FwIdMgt[fwId].idAvailability == SVA_FM_ID_AVAILABLE) return SVA_FM_UNREGISTERED_FIRMWARE_ID; + + downloadedFwId=currentFwMgt.downloadedFwId; + *pIsFWChangeNeeded=TRUE; + + //Check if a FW has already been loaded + if (downloadedFwId!=SVA_FW_INVALID_ID) + { + if(fwId == downloadedFwId) + {*pIsFWChangeNeeded=FALSE;} + } + + return SVA_FM_OK; +} + +/****************************************************************************/ +/* NAME: t_sva_fm_error sva_FM_GetFirmwareIdByFirmwareId( */ +/* t_sva_fw_id requiredFwId, */ +/* t_sva_fw_id *pFwId) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will check in it's database if requiredFwId can support*/ +/* current features registered. */ +/* In case requiredFwId can't support current features registered */ +/* then SVA_FW_INVALID_ID is return in pFwId. */ +/* Targets Open Service */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - requiredFwId: Id for which API will check if it's support current */ +/* registered features. */ +/* */ +/* OUT : */ +/* - pFwId: return requiredFwId if requiredFwId is registered and can */ +/* support current registered features. */ +/* If requiredFwId can't support current registered features */ +/* it takes SVA_FW_INVALID_ID value. */ +/* */ +/* RETURN: */ +/* t_sva_fm_error */ +/* - SVA_FM_OK:API has return pFwId (that can be SVA_FW_INVALID_ID)*/ +/* - SVA_FM_UNREGISTERED_FIRMWARE_ID : requiredFwId has not been */ +/* registered. */ +/* - SVA_FM_UNKNOWN_FIRMWARE_ID : FWId is incoherent */ +/* - SVA_FM_FW_NO_ADDRESS : requiredFwId support current features */ +/* but its address was not previously provided. */ +/* user should call SVA_SetFirmwareShareArea() */ +/* */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_sva_fm_error sva_FM_GetFirmwareIdByFirmwareId( + t_sva_fw_id requiredFwId, + t_sva_fw_id *pFwId +) +{ + t_uint32 i=0,nbSetFeature=0; + + //Check pointer parameters + HCL_ASSERT(pFwId!=NULL); + + //Check requiredFwId + if (requiredFwId >= MAX_FW_REGISTERED) return SVA_FM_UNKNOWN_FIRMWARE_ID; + + //Check if requiredFwId was previously registered + if (FwIdMgt[requiredFwId].idAvailability == SVA_FM_ID_AVAILABLE) return SVA_FM_UNREGISTERED_FIRMWARE_ID; + + //Check number set feature of requiredFwId + for(i=0;i1){return SVA_FM_UNKNOWN_FIRMWARE_ID;} + + //Check if current FW Features are includes in requiredFwId Features + if (sva_FM_areNewFeaturesIncludedInCurrentFeatures(currentFwMgt.downloadedSetFeature, FwDesc[requiredFwId].fwFeatures[0])) + { + //One can change FW enabling new Features by keeping also old features + *pFwId=requiredFwId; + + //Test if Fw address was already provided + if (FwIdMgt[*pFwId].fwAddress == 0) {return SVA_FM_FW_NO_ADDRESS;} + } + else + { + //requiredFwId does not support actual fetures + *pFwId=SVA_FW_INVALID_ID; + } + + return SVA_FM_OK; +} + + +/****************************************************************************/ +/* NAME: t_sva_fm_error sva_FM_IncrementeFirmwareIdInstance( */ +/* t_sva_fw_id fwId) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will record that a new instance of fwId is requested. */ +/* If fwId is not the currently loaded one then an error will be returned.*/ +/* For open service */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - fwId: firmware to record. */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_fm_error */ +/* - SVA_FM_OK : a new firmware instance has been added */ +/* - SVA_FM_UNREGISTERED_FIRMWARE_ID : Fw not yet registered */ +/* by SVA_RegisterFirmware() */ +/* - SVA_FM_ANOTHER_FIRMWARE_ALREADY_LOADED : another firmware with*/ +/* a different firmware id has already be loaded. fwId instance*/ +/* will not be recorded. */ +/* - SVA_FM_FW_ID_OVERFLOW : fwId has been recorded too many times.*/ +/* - SVA_FM_UNKNOWN_FIRMWARE_ID : fwId incoherent. */ +/* */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_sva_fm_error sva_FM_IncrementeFirmwareIdInstance(t_sva_fw_id fwId) +{ + //Check FwId + if (fwId >= MAX_FW_REGISTERED) {return SVA_FM_UNKNOWN_FIRMWARE_ID;} + + //Check if FwId was previously registered + if (FwIdMgt[fwId].idAvailability == SVA_FM_ID_AVAILABLE) {return SVA_FM_UNREGISTERED_FIRMWARE_ID;} + + //Check if FwId is the current FW + if (currentFwMgt.downloadedFwId != fwId) {return SVA_FM_ANOTHER_FIRMWARE_ALREADY_LOADED;} + + //Check that instance number does not overflow + if (currentFwMgt.instanceNb == SVA_FW_FEAT_INSTANCE_MAX_NUMBER) {return SVA_FM_FW_ID_OVERFLOW;} + + currentFwMgt.instanceNb++; + + return SVA_FM_OK; +} + +/****************************************************************************/ +/* NAME: t_sva_fm_error sva_FM_DecrementeFirmwareIdInstance( */ +/* t_sva_fw_id fwId) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will decremente fwId instance for a specifc FW. */ +/* Aimed at open service */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - fwId: firmware on which an instance should be removed. */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_fm_error */ +/* - SVA_FM_OK : firmware has been registered */ +/* - SVA_FM_ANOTHER_FIRMWARE_ALREADY_LOADED : another firmware with*/ +/* is downloaded. fwId instance will not be removed */ +/* - SVA_FM_UNREGISTERED_FIRMWARE_ID : requiredFwId has not been */ +/* registered. */ +/* - SVA_FM_FW_ID_UNDERFLOW : fw instance has been removed too many times*/ +/* - SVA_FM_UNKNOWN_FIRMWARE_ID : fwId incoherent */ +/* */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_sva_fm_error sva_FM_DecrementeFirmwareIdInstance(t_sva_fw_id fwId) +{ + //Check FwId + if (fwId >= MAX_FW_REGISTERED) {return SVA_FM_UNKNOWN_FIRMWARE_ID;} + + //Check if FwId was previously registered + if (FwIdMgt[fwId].idAvailability == SVA_FM_ID_AVAILABLE) {return SVA_FM_UNREGISTERED_FIRMWARE_ID;} + + //Check if FwId is the current FW + if (currentFwMgt.downloadedFwId != fwId) {return SVA_FM_ANOTHER_FIRMWARE_ALREADY_LOADED;} + + //Check that instance number does not overflow + if (currentFwMgt.instanceNb == 0) {return SVA_FM_FW_ID_UNDERFLOW;} + + currentFwMgt.instanceNb--; + + return SVA_FM_OK; +} + + +/**************************************************************************** + ** + ** Private functions + ** + *****************************************************************************/ + + +/****************************************************************************/ +/* NAME: t_bool sva_FM_areNewFeaturesIncludedInCurrentFeatures( */ +/* t_sva_fw_features, t_sva_fw_features) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine check if requested new Features are already provided by*/ +/* current FW features */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - newFeatures: requested FW features. */ +/* - currentFeatures: Features proposed by downloaded FW */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_bool */ +/* */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PRIVATE t_bool sva_FM_areNewFeaturesIncludedInCurrentFeatures(t_sva_fw_features newFeatures, t_sva_fw_features currentFeatures) +{ + + if (IrpFwDesc.isIrpFwBoot == TRUE) {currentFeatures |= SVA_FW_FEAT_IRP;} + if ((newFeatures & currentFeatures) == newFeatures) {return TRUE;} + else {return FALSE;} + +} + +/****************************************************************************/ +/* NAME: t_bool sva_FM_areFeaturesUsedInCurrentFW( */ +/* t_uint32 *pFwFeaturesUsed) */ +/* */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine check if, at least one feature is used at this time. */ +/* This is done by scanning .featuresMgt[x] that corresponds to the number */ +/* of service using a specific feature. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - pFwFeaturesUsed: pointer to mask of all currently used features. */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_bool */ +/* */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PRIVATE t_bool sva_FM_areFeaturesUsedInCurrentFW(t_uint32 *pFwFeaturesUsed) +{ + t_uint8 i=0; + + *pFwFeaturesUsed = 0; + + do + { + if (currentFwMgt.featuresMgt[i] != 0) + *pFwFeaturesUsed |= (1<cfg.cfg_rst=1; + + for(i=0;i<0xff;i++) {(void)0;} + + /* + * Restore saved System Time context + */ + sva_TI_RestoreSystemTimeContext(); +} +#endif + +/****************************************************************************/ +/* NAME: void sva_FW_Host_softReset(void) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* this routine will perform host soft reset of MMDSP */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - IntFwDesc : To get HamacBaseAddress */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* none */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PRIVATE void sva_Host_SoftReset(t_sva_fm_internal_desc *IntFwDesc) +{ + #if 0 + t_uint32 temp_Emul_Bkcmd; + t_uint32 temp_Emul_Clockmd; + + *((volatile t_uint32 *) (IntFwDesc->LoaderConfig.HamacBaseAddr.logical + 0x5BC80)) = 0x0; + *((volatile t_uint32 *) (IntFwDesc->LoaderConfig.HamacBaseAddr.logical + 0x5BCC0)) = 0x0; + *((volatile t_uint32 *) (IntFwDesc->LoaderConfig.HamacBaseAddr.logical + 0x5BD00)) = 0x0; + *((volatile t_uint32 *) (IntFwDesc->LoaderConfig.HamacBaseAddr.logical + 0x5BD40)) = 0x0; + *((volatile t_uint32 *) (IntFwDesc->LoaderConfig.HamacBaseAddr.logical + 0x5BD80)) = 0x0; + + /*CFG_IMR Reset*/ + *((volatile t_uint32 *) (IntFwDesc->LoaderConfig.HamacBaseAddr.logical + 0x5BC28)) = 0x0; + /* Clear CFG_IIS register by writing it to 0x03 */ + *((volatile t_uint32 *) (IntFwDesc->LoaderConfig.HamacBaseAddr.logical + 0x5BC20)) = 0x3; + + /* For each task type xxx in (VEC, VDC, GRB, DPL, TVD) : */ + /* - Lock semaphore = wait until xxx_SEM = 0 */ + /* - Reset xxx_IMR register to 0x0 */ + /* - Clear xxx_ISR register by writing it to 0xFF */ + /* - Unlock semaphore = write xxx_SEM to 0x1 */ + + /* Task type = VEC */ + while (*((volatile t_uint32 *) (IntFwDesc->LoaderConfig.HamacBaseAddr.logical + 0x5BC84)) = 0x0){} + *((volatile t_uint32 *) (IntFwDesc->LoaderConfig.HamacBaseAddr.logical + 0x5BCA8)) = 0x0; + *((volatile t_uint32 *) (IntFwDesc->LoaderConfig.HamacBaseAddr.logical + 0x5BCA4)) = 0xFF; + *((volatile t_uint32 *) (IntFwDesc->LoaderConfig.HamacBaseAddr.logical + 0x5BC84)) = 0x1; + + /* Task type = VDC */ + while (*((volatile t_uint32 *) (IntFwDesc->LoaderConfig.HamacBaseAddr.logical + 0x5BCC4)) = 0x0){} + *((volatile t_uint32 *) (IntFwDesc->LoaderConfig.HamacBaseAddr.logical + 0x5BCE8)) = 0x0; + *((volatile t_uint32 *) (IntFwDesc->LoaderConfig.HamacBaseAddr.logical + 0x5BCE4)) = 0xFF; + *((volatile t_uint32 *) (IntFwDesc->LoaderConfig.HamacBaseAddr.logical + 0x5BCC4)) = 0x1; + + + /* Task type = GRB */ + while (*((volatile t_uint32 *) (IntFwDesc->LoaderConfig.HamacBaseAddr.logical + 0x5BD04)) = 0x0){} + *((volatile t_uint32 *) (IntFwDesc->LoaderConfig.HamacBaseAddr.logical + 0x5BD28)) = 0x0; + *((volatile t_uint32 *) (IntFwDesc->LoaderConfig.HamacBaseAddr.logical + 0x5BD24)) = 0xFF; + *((volatile t_uint32 *) (IntFwDesc->LoaderConfig.HamacBaseAddr.logical + 0x5BD04)) = 0x1; + + /* Task type = DPL */ + while (*((volatile t_uint32 *) (IntFwDesc->LoaderConfig.HamacBaseAddr.logical + 0x5BD44)) = 0x0){} + *((volatile t_uint32 *) (IntFwDesc->LoaderConfig.HamacBaseAddr.logical + 0x5BD68)) = 0x0; + *((volatile t_uint32 *) (IntFwDesc->LoaderConfig.HamacBaseAddr.logical + 0x5BD64)) = 0xFF; + *((volatile t_uint32 *) (IntFwDesc->LoaderConfig.HamacBaseAddr.logical + 0x5BD64)) = 0x1; + + /* Task type = TVD */ + while (*((volatile t_uint32 *) (IntFwDesc->LoaderConfig.HamacBaseAddr.logical + 0x5BD84)) = 0x0){} + *((volatile t_uint32 *) (IntFwDesc->LoaderConfig.HamacBaseAddr.logical + 0x5BDA8)) = 0x0; + *((volatile t_uint32 *) (IntFwDesc->LoaderConfig.HamacBaseAddr.logical + 0x5BDA4)) = 0xFF; + *((volatile t_uint32 *) (IntFwDesc->LoaderConfig.HamacBaseAddr.logical + 0x5BD84)) = 0x1; + + *((volatile t_uint16 *) (IntFwDesc->LoaderConfig.HamacBaseAddr.logical + 0x60020)) = 1; + + temp_Emul_Bkcmd=*((volatile t_uint16 *) (IntFwDesc->LoaderConfig.HamacBaseAddr.logical + 0x60056)); + temp_Emul_Clockmd=*((volatile t_uint16 *) (IntFwDesc->LoaderConfig.HamacBaseAddr.logical + 0x60074)); + *((volatile t_uint16 *) (IntFwDesc->LoaderConfig.HamacBaseAddr.logical + 0x60074))=0x01; + *((volatile t_uint16 *) (IntFwDesc->LoaderConfig.HamacBaseAddr.logical + 0x60056))=0x0; + + *((volatile t_uint16 *) (IntFwDesc->LoaderConfig.HamacBaseAddr.logical + 0x5Ec14)) = 0x10f8; + *((volatile t_uint16 *) (IntFwDesc->LoaderConfig.HamacBaseAddr.logical + 0x60056)) = 0x8; + *((volatile t_uint16 *) (IntFwDesc->LoaderConfig.HamacBaseAddr.logical + 0x60074)) = 0x0; + #endif + *((volatile t_uint16 *) (IntFwDesc->LoaderConfig.HamacBaseAddr.logical + 0x60020)) = 1; + +} + +/****************************************************************************/ +/* NAME: t_sva_fm_error sva_FW_boot(void) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* this routine will boot mmdsp and wait until boot is finished: */ +/* ie subtask can be programmed */ +/* */ +/* PARAMETERS: */ +/* IN : none */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_fm_error */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PRIVATE t_sva_fm_error sva_FW_boot(t_bool irp_boot) +{ + + //Follow MMDSP initialization procedure described in Hamac video specification + + t_uint32 saveimr = IntFwDesc.pSVARegs->cfg.cfg_imr; + SVA_DisableIRQSrc(SVA_IRQ); + +#ifdef __STN_8810 + //soft reset of mmdsp+ core + IntFwDesc.pSVAMem->hostRegs[HOST_SOFT_RESET]=1; + + //access to compatible_reg + IntFwDesc.pSVAMem->mmioSpace[MMIO_COMPATIBLE_MODE]=0x00F8; + + //enable access to internal memory + IntFwDesc.pSVAMem->hostRegs[HOST_BK_CMD]=8; + + //start mmdsp core clocks*/ + IntFwDesc.pSVAMem->hostRegs[HOST_STOP_CLOCK]=0; +#else /* __STN_8810 */ + +#if 0 + IntFwDesc.pSVARegs->cfg.cfg_irp_act = 1; + if (IrpFwDesc.isIrpFwPresent == TRUE && irp_boot == TRUE) + { + + + if (IntFwDesc.vpipCtxSaved == TRUE) + { + IntFwDesc.pSVARegs->cfg.cfg_irp_save_addr = IntFwDesc.vpipCtxSaveSystemAddress.physical; + IntFwDesc.pSVARegs->cfg.cfg_irp_act = 2;/*boot ewarp with restore */ + } + + } + else + { + IrpFwDesc.isIrpFwBoot = FALSE; + IntFwDesc.pSVARegs->cfg.cfg_irp_act = 0;/*don't boot ewarp*/ + } + + //Work around for dualeWarp boot + IntFwDesc.pSVARegs->cfg.cfg_irp_act = 1; +#else + /* Work around for dualEwarp boot */ + /* This workaround should be removed if we are using FW V3.13.2 or above */ + IntFwDesc.pSVARegs->cfg.cfg_irp_act = 1; +#endif + HLOADER_Boot(&IntFwDesc.LoaderConfig); + HLOADER_CacheConfig(&IntFwDesc.LoaderConfig,0x07); + + + IntFwDesc.pSVARegs->cfg.cfg_cgc = 1; + +#endif /* __STN_8810 */ + + //wait for eoi interrupt: polling + while((IntFwDesc.pSVARegs->cfg.cfg_iis & IIS_EOI_MASK) == 0) + { + volatile t_uint32 i; + for (i=0; i < 100; i++) {(void)0;} + } + + // Acknowledge the EOI interrupt + IntFwDesc.pSVARegs->cfg.cfg_iis = IIS_EOI_MASK; + IntFwDesc.pSVARegs->cfg.cfg_imr = saveimr; + + // Warning: IRQ unmask at task level no more done in FW mgt! + + + + return(SVA_FM_OK); +} + +/* END of sva_fwmgt.c */ + --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/firmware_management/sva_fwmgt.h @@ -0,0 +1,180 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ + +#ifndef __INC_SVA_FM_H +#define __INC_SVA_FM_H + +#include "hcl_defs.h" +#include "sva_hwp.h" +#include "sva.h" +#include "svap.h" +#include "sva_memorymgt.h" + +/******************************************************************************/ +/* Constants definitions */ +/******************************************************************************/ +/* + * define invalid FW id that correspond to default FWId +*/ +#define SVA_FW_INVALID_ID MASK_ALL32 + +/* + * define maximum number of set feature for one fw +*/ +#define MAX_NB_SET_FEATURE 3 + +/* + * define all possible FW features +*/ +#define SVA_FW_FEAT_NONE 0 + +/* Postprocessing part */ +#define SVA_FW_FEAT_POST_PROCESSOR MASK_BIT0 +#define SVA_FW_FEAT_POST_PROCESSOR_RASTER_TO_MB MASK_BIT12 + +/* Preprocessing part */ +#define SVA_FW_FEAT_PRE_PROCESSOR MASK_BIT1 +#define SVA_FW_FEAT_IRP MASK_BIT26 + +/* Preprocessing AND Postprocessing part */ +#define SVA_FW_FEAT_ACE MASK_BIT13 + +/* Video decoder part : */ +#define SVA_FW_FEAT_MPEG4_DECODER MASK_BIT2 +#define SVA_FW_FEAT_MPEG4_SP_DECODER SVA_FW_FEAT_MPEG4_DECODER +#define SVA_FW_FEAT_MPEG4_SH_DECODER MASK_BIT14 +#define SVA_FW_FEAT_MPEG4_DECODER_CIF_VGA MASK_BIT24 +#define SVA_FW_FEAT_MPEG4_DECODER_CIF MASK_BIT27 +#define SVA_FW_FEAT_MPEG4_DECODER_ERC MASK_BIT28 + +#define SVA_FW_FEAT_MPEG4_DECODER_CIF MASK_BIT27 +#define SVA_FW_FEAT_MPEG4_DECODER_ERC MASK_BIT28 + +#define SVA_FW_FEAT_H264_DECODER MASK_BIT15 +#define SVA_FW_FEAT_WMV9_DECODER MASK_BIT16 +#define SVA_FW_FEAT_MPEG2_DECODER MASK_BIT30 + +/* Video encoder part : */ +#define SVA_FW_FEAT_MPEG4_ENCODER MASK_BIT3 +#define SVA_FW_FEAT_MPEG4_SP_ENCODER SVA_FW_FEAT_MPEG4_ENCODER +#define SVA_FW_FEAT_MPEG4_SH_ENCODER MASK_BIT18 + +#define SVA_FW_FEAT_H264_ENCODER MASK_BIT19 + +#define SVA_FW_FEAT_ENCODER_CONSTANT_QP MASK_BIT20 +#define SVA_FW_FEAT_ENCODER_CBR MASK_BIT21 +#define SVA_FW_FEAT_ENCODER_VBR MASK_BIT22 +#define SVA_FW_FEAT_ENCODER_FRAME_BY_FRAME MASK_BIT23 +#define SVA_FW_FEAT_ENCODER_AIR_CIR MASK_BIT25 + +/* Still decoder part : */ +#define SVA_FW_FEAT_JPEG_DECODER MASK_BIT7 + +/* Still encoder part : */ +#define SVA_FW_FEAT_JPEG_ENCODER MASK_BIT8 + +/* Software processing part : */ +#define SVA_FW_FEAT_STAB MASK_BIT11 + +/* TV Output part */ +#define SVA_FW_FEAT_TVO MASK_BIT9 + + + +/* GRABHQ */ +#define SVA_FW_FEAT_PREPROC_ALGO MASK_BIT29 + + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + +/******************************************************************************/ +/* Types definitions */ +/******************************************************************************/ +/* + * Definition of symbol used by Firmware Management routines to return error + */ +typedef enum { + SVA_FM_UNKNOWN_FIRMWARE_ID = SVA_FM_LAST_ERROR, + SVA_FM_UNREGISTERED_FIRMWARE_ID, + SVA_FM_NO_FIRMWARE_LOADED, + SVA_FM_ANOTHER_FIRMWARE_ALREADY_LOADED, + SVA_FM_FEATURES_OVERFLOW, + SVA_FM_FEATURES_UNDERFLOW, + SVA_FM_FEATURES_UNKNOWN_BY_REGISTERED_FW, + SVA_FM_FW_ID_OVERFLOW, + SVA_FM_FW_ID_UNDERFLOW, + SVA_FM_FW_NO_ADDRESS, + SVA_FM_FW_LOAD_ERROR, + SVA_FM_FW_INTERNAL_ERROR, + SVA_FM_OK = SVA_OK + //SVA_FM_FW_CHANGE_NEEDED, + //SVA_FM_FW_READY_TO_DOWNLOAD, + //SVA_FM_FW_CONFLICT +} t_sva_fm_error; + + +/* + * t_sva_fw_features type allow to define features supported by a firmware +*/ +typedef t_uint32 t_sva_fw_features; + +/* + * t_sva_fw_desc type allow to define firmware descriptor +*/ +typedef struct { + t_uint8 structureVersion; + t_uint8 reservedOrSetFeature; + t_uint16 programmingModel; + t_version fwVersion; + t_uint32 hwVersion; + t_sva_fw_features fwFeatures[MAX_NB_SET_FEATURE]; +}t_sva_fw_desc; + +/******************************************************************************* +* PUBLIC Functions +*******************************************************************************/ +PUBLIC t_sva_fm_error sva_FM_Init(t_system_address, t_system_address, t_uint32, t_bool ); +PUBLIC t_bool sva_FM_IsFirmwareChangeNeededByFeatures(t_sva_fw_features); +PUBLIC t_sva_fm_error sva_FM_TestFirmwareChangeNeedByFirmwareId(t_sva_fw_id, t_bool *); +PUBLIC t_sva_fm_error sva_FM_GetFirmwareIdByFeatures(t_sva_fw_features, t_sva_fw_id *); +PUBLIC t_sva_fm_error sva_FM_GetFirmwareIdByFirmwareId(t_sva_fw_id, t_sva_fw_id *); +PUBLIC t_sva_fm_error sva_FM_RegisterFeaturesUse(t_sva_fw_features); +PUBLIC t_sva_fm_error sva_FM_UnRegisterFeaturesUse(t_sva_fw_features); +PUBLIC t_sva_fm_error sva_FM_IncrementeFirmwareIdInstance(t_sva_fw_id); +PUBLIC t_sva_fm_error sva_FM_DecrementeFirmwareIdInstance(t_sva_fw_id); +PUBLIC t_sva_fm_error sva_FM_Download(t_sva_fw_id); +PUBLIC t_sva_fm_error sva_FM_ResetFirmwareShareArea(t_sva_fw_id); +PUBLIC t_sva_fm_error sva_FM_GetFwVersion(t_version *); +PUBLIC t_sva_fm_error sva_FM_GetPatchLevel(t_uint32 *); +PUBLIC t_sva_fm_error sva_FM_InformPrivateMemoryChunk(t_sva_memory_id, t_system_address, t_size); +PUBLIC t_sva_fm_error sva_FM_ConfigurePrivateMemoryChunk(t_sva_dedicated_area_purpose ,t_size *, t_system_address *); +/*PUBLIC t_sva_error SVA_RegisterFirmware(const t_sva_fw_desc *, t_sva_fw_id *); see sva.h */ +/*PUBLIC t_sva_error SVA_UnregisterFirmware(t_sva_fw_id); see sva.h */ +/*PUBLIC t_sva_error SVA_SetFirmwareShareArea(t_sva_fw_id, t_logical_address); see sva.h */ + + +#ifdef __cplusplus +} /* allow C++ to use these headers */ +#endif /* __cplusplus */ + +#endif /* __INC_SVA_FM_H */ +/* End of file - sva_fwmgt.h */ --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/firmware_management/sva_fwmgtp.h @@ -0,0 +1,304 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ +#ifndef __INC_SVA_FM_P_H +#define __INC_SVA_FM_P_H + +#include "hcl_defs.h" +#include "sva.h" +#include "hloader.h" +#include "sva_hwp.h" +#include "sva_memorymgt.h" +#include "sva_service.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/******************************************************************************/ +/* Constants definitions */ +/******************************************************************************/ + +/* + * define maximum number of FW that can be registered +*/ +#define MAX_FW_REGISTERED 12 + +/* + * define constant related to firmware supported features +*/ +//maximum FW feature number +//Should be <33 as stored in a t_uint32 with 1 bit per feature +#define SVA_FW_FEAT_MAX_NUMBER 32 +//maximum instance number of a specific feature +#define SVA_FW_FEAT_INSTANCE_MAX_NUMBER 4 + +/* + * For Open Service + * define maximum instance number of a specific FW that can be registered +*/ +#define MAX_INSTANCE_OF_SPECIFIC_FW 8 + +/* + * define maximum number of FW that can be registered +*/ +#define SVA_FW_BOOT_TABLE_SIZE (4 * ONE_KB) + +/* + * define expected FW programming model version +*/ +#define FW_PROGRAMMING_MODEL_NONE 0 +#define FW_V0_96_PROGRAMMING_MODEL MASK_BIT0 +#define FW_V0_97_PROGRAMMING_MODEL MASK_BIT1 +#define FW_V1_00_PROGRAMMING_MODEL MASK_BIT2 +#define FW_V1_10_PROGRAMMING_MODEL MASK_BIT3 +#define FW_V1_11_PROGRAMMING_MODEL MASK_BIT4 +#define FW_V1_12_PROGRAMMING_MODEL MASK_BIT5 + +/* + * define constant need to pass hardware supported +*/ +#define SVA_FW_HARD_NONE 0 +#define SVA_FW_HARD_LITEA MASK_BIT0 +#define SVA_FW_HARD_LITEB MASK_BIT1 +#define SVA_FW_HARD_FULL_AA MASK_BIT2 +#define SVA_FW_HARD_FULL_AB MASK_BIT3 +#define SVA_FW_HARD_FULL_BA MASK_BIT4 +#define SVA_FW_HARD_8815_AA MASK_BIT5 +#define SVA_FW_HARD_8815_BA MASK_BIT6 + +/* + * define constant for FW identification +*/ +#define SVA_FW_ID_NONE 0 +#define SVA_FW_ID_2_5_2_3 0x00020523 +#define SVA_FW_ID_2_5_3 0x00020503 +#define SVA_FW_ID_2_5_4_4 0x00020544 +#define SVA_FW_ID_2_5_5 0x00020505 +#define SVA_FW_ID_2_5_7 0x00020507 +#define SVA_FW_ID_2_5_9 0x00020509 +#define SVA_FW_ID_2_6_2_1 0x00020621 +#define SVA_FW_ID_2_8_0 0x00020800 +#define SVA_FW_ID_3_0_2 0x00030002 +#define SVA_FW_ID_3_1_1 0x00030101 +#define SVA_FW_ID_3_1_3_3 0x00030133 +#define SVA_FW_ID_3_2_0 0x00030200 +#define SVA_FW_ID_3_3_0 0x00030300 +#define SVA_FW_ID_3_3_3 0x00030303 + +/* + * define MMDSP memories size (to initialize it) +*/ +#define SVA_MMDSP_DATA_MEM_SIZE 8192 //in words +#define SVA_MMDSP_CODE_MEM_SIZE 16384 //in words +#define SVA_MMDSP_DICT_MEM_SIZE 4096 //in words + +/* + * define if irp present +*/ +#if defined(__STN_8815) + #define SVA_FW_IRP_SUPPORTED TRUE +#else + #define SVA_FW_IRP_SUPPORTED FALSE +#endif + +/******************************************************************************/ +/* chip dependant constants definition */ +/******************************************************************************/ +#ifdef __STN_8810 + +# if __STN_8810==20 /* STN8810 cut B0 */ + +/* ******* Firmware version management. ******* */ +# define SVA_FW_PROGRAMMING_MODEL (FW_V1_12_PROGRAMMING_MODEL) +# define SVA_FW_HARDWARE_VERSION (SVA_FW_HARD_FULL_BA) + +# else /* STN8810 cut A0/A1 */ + +/* ******* Firmware version management. ******* */ +# define SVA_FW_PROGRAMMING_MODEL (FW_V1_12_PROGRAMMING_MODEL) +# define SVA_FW_HARDWARE_VERSION (SVA_FW_HARD_FULL_AA|SVA_FW_HARD_FULL_AB) +# endif /* __STN_8810==20 */ + +/* ******* Specific flags management ******* */ +/* Flag to indicate the MMDSP firware has to run from DDR */ +/* i.e. the code has to be copied into DDR section during */ +/* FW download (handled by hloader). */ +#define SVA_FW_MMDSP_RUN_FROM_DDR FALSE +#define SVA_FW_MMDSP_SDRAM_SIZE 0 +#define SVA_FW_ESRAM_PROG2_SIZE 0 +#define SVA_FW_ESRAM_DATA24_SIZE 0 +#define SVA_FW_ESRAM_DATA16_SIZE 0 + +/* ******* SVA / MMDSP Memory mapping ******* */ + +#define LOG_PROGRAM_ZONE1_BASE (t_logical_address)(((t_sva_mem_mapping *)IntFwDesc.svaMemSystemBaseAddr.logical)->codeMem) +#define PHY_PROGRAM_ZONE1_BASE (t_physical_address)(((t_sva_mem_mapping *)IntFwDesc.svaMemSystemBaseAddr.physical)->codeMem) +#define LOG_PROGRAM_ZONE1_TOP 0 +#define PHY_PROGRAM_ZONE1_TOP 0 +#define SIZE_PROGRAM_ZONE1 (t_uint32)sizeof (((t_sva_mem_mapping *)IntFwDesc.svaMemSystemBaseAddr.physical)->codeMem); +/* PS : Size was (t_uint32)sizeof (((t_sva_mem_mapping *)IntFwDesc.svaMemSystemBaseAddr.physical)->codeMem); */ + +#elif defined __STN_8815 /* __STN_8815 */ + +/* ******* Firmware version management. ******* */ +# define SVA_FW_PROGRAMMING_MODEL (FW_V1_12_PROGRAMMING_MODEL) +#if __STN_8815 >= 20 +# define SVA_FW_HARDWARE_VERSION (SVA_FW_HARD_8815_BA) +#else +# define SVA_FW_HARDWARE_VERSION (SVA_FW_HARD_8815_AA) +#endif + +/* ******* Specific flags management ******* */ +/* Flag to indicate the MMDSP firware has to run from DDR */ +/* i.e. the code has to be copied into DDR section during */ +/* FW download (handled by hloader). */ +#define SVA_FW_MMDSP_RUN_FROM_DDR TRUE + +#define SVA_FW_MMDSP_SDRAM_SIZE (600*1024) + +/* Sarvesh: !!Beware!! Below value taken from FW version V3.9.0, These * + * values need to be changed if there is some change in the size of * + * different sections in FW in further FW releases */ +//\/#define SVA_FW_SDRAM_PROG_ZONE1_SIZE (550*1024) +#define SVA_FW_SDRAM_PROG_ZONE1_SIZE (300*1024) +#define SVA_FW_SDRAM_H264_ENC_DATA16_ZONE1_SIZE_MAX (150*1024) +//\/#define SVA_FW_SDRAM_DATA16_ZONE1_SIZE_MAX (512*1024) +#define SVA_FW_SDRAM_DATA16_ZONE1_SIZE_MAX (300*1024) +#define SVA_FW_SDRAM_DATA24_ZONE1_SIZE (150*1024) +#define SVA_FW_SDRAM_VC1_DEC_DEDICATED_BUFF_SIZE_MIN (100*1024) +#define SVA_FW_SDRAM_H264_DEC_DEDICATED_BUFF_SIZE_MIN (50*1024) +#define SVA_FW_SDRAM_PREPROC_DATA16_ZONE1_SIZE_MAX (11*1024*1024) + +#define SVA_FW_ESRAM_PROG2_SIZE (120*1024) +#define SVA_FW_ESRAM_DATA24_SIZE (36*1024) +#define SVA_FW_ESRAM_DATA16_SIZE (24*1024) + +/* ******* SVA / MMDSP Memory mapping ******* */ +#define LOG_PROGRAM_ZONE1_BASE 0 +#define PHY_PROGRAM_ZONE1_BASE 0 +#define LOG_PROGRAM_ZONE1_TOP 0 +#define PHY_PROGRAM_ZONE1_TOP 0 +#define SIZE_PROGRAM_ZONE1 0 + +#else +# error Chip not supported +#endif /* __STN_8810 */ + +/******************************************************************************/ +/* Types definitions */ +/******************************************************************************/ + +/* + * t_sva_fm_id_availability type allow to define registering availability for each FW id +*/ +typedef enum { + SVA_FM_ID_AVAILABLE, //FwId not yet registered + SVA_FM_ID_NOT_AVAILABLE //FwId registered +} t_sva_fm_id_availability; + +/* + * t_sva_fm_id_mgt type merge information related to a specific FwId +*/ +typedef struct { + t_sva_fm_id_availability idAvailability; + t_logical_address fwAddress; + t_uint8 setNbFeature; +} t_sva_fm_id_mgt; + +/* + * structure to handle irp firmware management +*/ +typedef struct { + t_bool isIrpFwPresent; + t_bool isIrpFwBoot; + t_sva_block_id irpFwBlockId; + t_size eWarpFwSize; + t_logical_address eWarpFwAddress; +} t_sva_fm_irp_internal_desc; + +typedef struct { + t_uint32 cfg_irp_fw_addr; /* start address eWarp firmware */ + t_uint32 cfg_irp_fw_size; /* size in bytes of eWarp firmware */ + t_uint32 cfg_irp_save_addr; /* State save address register */ + t_uint32 cfg_irp_ptr; /* ptr of circular buffer for rw packet */ + t_uint32 cfg_irp_rw; /* status of the current rw operation */ + t_uint32 cfg_irp_error; /* error code */ +} t_sva_fm_warmboot_cfg_regs; + +/* + * t_sva_fm_internal_desc type merge information related to internal needs of FW mgt + * i.e. all parameters setted during sva_FM_Init() +*/ +typedef struct { + t_system_address svaRegSystemBaseAddr; + t_system_address svaMemSystemBaseAddr; + t_system_address svaERamSystemBaseAddr; + t_sva_regs_mapping *pSVARegs; + t_sva_mem_mapping *pSVAMem; + t_uint32 ccpSyncroCode; + t_bool lowLevelClockGating; + t_loader_config LoaderConfig; + t_system_address chunkSystemAddress; + t_size chunkSize; + t_sva_block_id sdramBlockId; + t_system_address sdramSystemAddress; + t_sva_block_id vpipCtxSaveBlockId; + t_system_address vpipCtxSaveSystemAddress; + t_bool vpipCtxSaved; + t_bool irp_booted; + t_size sdramSize; + t_sva_fm_warmboot_cfg_regs warmbootCfgRegs; +} t_sva_fm_internal_desc; + + + +/* + * t_sva_fm_current_fw_mgt type merge information related to downloaded FW +*/ +typedef struct { + t_uint32 downloadedFwId; //identifies current active FW + //It is set at the end of sva_FM_Download() + t_uint8 instanceNb; //instance recorded for a specific firmware: used by Open service + //It is reset by sva_FM_Download() + // incremented by sva_FM_IncrementeFirmwareIdInstance() + // decremented by sva_FM_DecrementeFirmwareIdInstance() + t_uint8 featuresMgt[SVA_FW_FEAT_MAX_NUMBER];//counter array related to each FW feature: used if not open service + //It is reset by sva_FM_Download() + // incremented by sva_FM_RegisterFeaturesUse() + // decremented by sva_FM_UnRegisterFeaturesUse() + t_uint32 downloadedSetFeature; //identifies current active set feature + + + +} t_sva_fm_current_fw_mgt; + +/* + * t_sva_fw_feature type allow to define different set of feature for the same firmware Id +*/ +typedef struct { + t_sva_fw_features fwFeatures; + t_uint32 fwId; +}t_sva_fw_set_feature; + +#ifdef __cplusplus +} /* allow C++ to use these headers */ +#endif /* __cplusplus */ + +#endif /* __INC_SVA_FM_P_H */ +/* End of file - sva_fwmgtp.h */ --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/grab/sva_grab.c @@ -0,0 +1,3810 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ +/*------------------------------------------------------------------------ + * Includes + *----------------------------------------------------------------------*/ +#include "hcl_defs.h" +#include "sva_grab.h" +#include "sva_grabp.h" +#include "sva_eventmgt.h" + +/*------------------------------------------------------------------------ + * Private macro + *----------------------------------------------------------------------*/ +#define NB_SUPPORTED_PREPROCESSOR_TRANSFORMS 10 + + /*------------------------------------------------------------------------ + * Global Variables + *----------------------------------------------------------------------*/ + #ifdef __DEBUG +ALIGN(32) PRIVATE t_sva_gb_debug_events eventGrabDebugTable[NUM_MAX_GRAB]; +ALIGN(32) PRIVATE t_sva_gb_debug_commands commandGrabDebugTable[NUM_MAX_GRAB]; +ALIGN(32) PRIVATE t_sva_gb_debug_transitions transitionGrabDebugTable[NUM_MAX_GRAB]; +#endif +/*instance descriptors*/ +PRIVATE t_sva_gb_descriptor grabDesc[NUM_MAX_GRAB]; +PRIVATE t_bool isPacketOnGoing = FALSE; + +/*counter of current number of start service*/ +/* + * Will be increment on a successfull start command and decrement either on a + * reset command or an EOK when in SVA_SERVICE_STOP_REQUESTED. +*/ +PRIVATE t_uint32 grabStartedServiceCnt = 0; + +/*table that translate transform id into a grab subtask type*/ +PRIVATE const t_sva_tm_subtask_type transformation_2_subtask_type[NB_SUPPORTED_PREPROCESSOR_TRANSFORMS]={ + SVA_TM_GRAB_RAW_DATA, /*SVA_PREPROCESSOR_RAW, */ + SVA_TM_GRAB_NO_CACHE, /*SVA_PREPROCESSOR_YUV420_MB, */ + SVA_TM_GRAB_WITH_SEP_COMP, /*SVA_PREPROCESSOR_YUV420_SEP_COMP_MB, */ + SVA_TM_GRAB_WITH_SEP_COMP, /*SVA_PREPROCESSOR_YUV422_SEP_COMP_MB, */ + SVA_TM_GRAB_CAMERA_RASTER_OUT, /*SVA_PREPROCESSOR_YUV420_RASTER_OUT, */ + SVA_TM_GRAB_SENSOR_NO_CACHE, /*SVA_PREPROCESSOR_SENSOR_YUV420_MB, */ + SVA_TM_GRAB_SENSOR_WITH_SEP_COMP, /*SVA_PREPROCESSOR_SENSOR_YUV420_SEP_COMP_MB,*/ + SVA_TM_GRAB_SENSOR_WITH_SEP_COMP, /*SVA_PREPROCESSOR_SENSOR_YUV422_SEP_COMP_MB,*/ + SVA_TM_GRAB_SENSOR_RASTER_OUT, /*SVA_PREPROCESSOR_SENSOR_YUV420_RASTER_OUT */ + SVA_TM_GRAB_SENSOR_HQ /*SVA_PREPROCESSOR_SENSOR_HIGHQUALITY_YUV420_MB*/ + }; + +/* table that translate t_sva_preprocessor_input_mode into sva interface_configuration type*/ +PRIVATE const t_uint16 input_mode_2_interface_configuration[SVA_PREPROCESSOR_CCP1_INTERFACE_FALLING_EDGE_STROBE_ENABLE + 1]={ + 0x00, /* SVA_PREPROCESSOR_CCP0_INTERFACE_RISING_EDGE or SVA_PREPROCESSOR_CCP_INTERFACE_RISING_EDGE */ + 0x01, /* SVA_PREPROCESSOR_CCIR656_INTERFACE_RISING_EDGE */ + 0x02, /* SVA_PREPROCESSOR_CCP0_INTERFACE_FALLING_EDGE or SVA_PREPROCESSOR_CCP_INTERFACE_FALLING_EDGE */ + 0x03, /* SVA_PREPROCESSOR_CCIR656_INTERFACE_FALLING_EDGE */ + 0x10, /* SVA_PREPROCESSOR_CCP0_INTERFACE_RISING_EDGE_STROBE_ENABLE or SVA_PREPROCESSOR_CCP_INTERFACE_RISING_EDGE_STROBE_ENABLE */ + 0x12, /* SVA_PREPROCESSOR_CCP0_INTERFACE_FALLING_EDGE_STROBE_ENABLE or SVA_PREPROCESSOR_CCP_INTERFACE_FALLING_EDGE_STROBE_ENABLE */ + 0x20, /* SVA_PREPROCESSOR_CCP1_INTERFACE_RISING_EDGE */ + 0x22, /* SVA_PREPROCESSOR_CCP1_INTERFACE_FALLING_EDGE */ + 0x30, /* SVA_PREPROCESSOR_CCP1_INTERFACE_RISING_EDGE_STROBE_ENABLE */ + 0x32 /* SVA_PREPROCESSOR_CCP1_INTERFACE_FALLING_EDGE_STROBE_ENABLE */ +}; + +/*table that describe memory allocation for grab*/ +PRIVATE const t_sva_tm_field_ctrl_desc defaultGrabFieldDescArray[GRAB_FIELD_NUMBER]={ + { SVA_TM_DCMD_ALLOCATE, {{sizeof(t_sva_grb_frame_buffer_in), GRAB_DEFAULT_INFOS_MEMORY_ID}}}, + { SVA_TM_DCMD_ALLOCATE, {{sizeof(t_sva_grb_frame_buffer_out), GRAB_DEFAULT_INFOS_MEMORY_ID}}}, + { SVA_TM_DCMD_ALLOCATE, {{sizeof(t_sva_grb_internal_buffer), GRAB_DEFAULT_INFOS_MEMORY_ID}}}, + { SVA_TM_DCMD_ALLOCATE, {{sizeof(t_sva_grb_param_in), GRAB_DEFAULT_INFOS_MEMORY_ID}}}, + { SVA_TM_DCMD_ALLOCATE, {{sizeof(t_sva_grb_param_out), GRAB_DEFAULT_INFOS_MEMORY_ID}}}, + { SVA_TM_DCMD_ALLOCATE, {{sizeof(t_sva_grb_param_inout), GRAB_DEFAULT_INFOS_MEMORY_ID}}}, + { SVA_TM_DCMD_NULL, {{sizeof(t_sva_grb_param_inout), GRAB_DEFAULT_INFOS_MEMORY_ID}}} +}; + +/*table that translate grab state into service state*/ +PRIVATE const t_sva_service_state grabState2ServiceState[SVA_GB_LAST_DUMMY_STATE]= { + SVA_SERVICE_NOT_INITIALIZED, /*SVA_GB_NOT_INITIALIZED*/ + SVA_SERVICE_WAIT_FOR_CONFIGURATION, /*SVA_GB_WAIT_FOR_CONFIGURATION*/ + SVA_SERVICE_WAIT_FOR_INTERNAL_NEEDS, /*SVA_GB_WAIT_FOR_INTERNAL_NEEDS*/ + SVA_SERVICE_WAIT_FOR_ACTIVATE, /*SVA_GB_WAIT_FOR_ACTIVATE*/ + SVA_SERVICE_WAIT_FOR_START, /*SVA_GB_WAIT_FOR_START*/ + SVA_SERVICE_FLUSHING, /*SVA_GB_FLUSHING_IN*/ + SVA_SERVICE_FLUSHING, /*SVA_GB_FLUSHING_OUT*/ + SVA_SERVICE_WAIT_FOR_DATA, /*SVA_GB_WAIT_FOR_DATA*/ + SVA_SERVICE_RUNNING, /*SVA_GB_RUNNING*/ + SVA_SERVICE_ABORT_REQUESTED, /*SVA_GB_ABORT_REQUESTED*/ + SVA_SERVICE_STOP_REQUESTED, /*SVA_GB_STOP_REQUESTED*/ + SVA_SERVICE_ERROR /*SVA_GB_ERROR*/ +}; + +/*main state machine description*/ +PRIVATE const t_sva_gb_state stateMachine[SVA_GB_LAST_DUMMY_STATE][SVA_GB_LAST_DUMMY_TRANSITION]= { + /* Current State = SVA_GB_NOT_INITIALIZED */ + { + SVA_GB_WAIT_FOR_CONFIGURATION, /*SVA_GB_CREATE*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_CONFIGURE*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_INTERNAL_NEEDS*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_ACTIVATE*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_INACTIVATE*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_CONTROL_START*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_CONTROL_STOP*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_CONTROL_ABORT*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_ALL_DEPENDENCIES_RESOLVED*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_PUSH*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_EVENT_EOK*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_EVENT_FAKE*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_EVENT_ACTIVE*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_EVENT_INACTIVE*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_RESET*/ + SVA_GB_NOT_INITIALIZED, /*SVA_GB_CONTROL_DELETE*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_EVENT_ERROR*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_FLUSH_IN*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_FLUSH_OUT*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_CANCEL*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_UPDATE_PARAM*/ + SVA_GB_TRANSITION_REJECTED /*SVA_GB_EVENT_ABORT*/ + }, + /* Current State = SVA_GB_WAIT_FOR_CONFIGURATION */ + { + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_CREATE*/ + SVA_GB_WAIT_FOR_INTERNAL_NEEDS, /*SVA_GB_CONFIGURE*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_INTERNAL_NEEDS*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_ACTIVATE*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_INACTIVATE*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_CONTROL_START*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_CONTROL_STOP*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_CONTROL_ABORT*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_ALL_DEPENDENCIES_RESOLVED*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_PUSH*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_EVENT_EOK*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_EVENT_FAKE*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_EVENT_ACTIVE*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_EVENT_INACTIVE*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_RESET*/ + SVA_GB_NOT_INITIALIZED, /*SVA_GB_CONTROL_DELETE*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_EVENT_ERROR*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_FLUSH_IN*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_FLUSH_OUT*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_CANCEL*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_UPDATE_PARAM*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_EVENT_ABORT*/ + }, + /* Current State = SVA_GB_WAIT_FOR_INTERNAL_NEEDS */ + { + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_CREATE*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_CONFIGURE*/ + SVA_GB_WAIT_FOR_ACTIVATE, /*SVA_GB_INTERNAL_NEEDS*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_ACTIVATE*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_INACTIVATE*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_CONTROL_START*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_CONTROL_STOP*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_CONTROL_ABORT*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_ALL_DEPENDENCIES_RESOLVED*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_PUSH*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_EVENT_EOK*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_EVENT_FAKE*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_EVENT_ACTIVE*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_EVENT_INACTIVE*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_RESET*/ + SVA_GB_NOT_INITIALIZED, /*SVA_GB_CONTROL_DELETE*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_EVENT_ERROR*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_FLUSH_IN*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_FLUSH_OUT*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_CANCEL*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_UPDATE_PARAM*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_EVENT_ABORT*/ + }, + /* Current State = SVA_GB_WAIT_FOR_ACTIVATE */ + { + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_CREATE*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_CONFIGURE*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_INTERNAL_NEEDS*/ + SVA_GB_WAIT_FOR_ACTIVATE, /*SVA_GB_ACTIVATE*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_INACTIVATE*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_CONTROL_START*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_CONTROL_STOP*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_CONTROL_ABORT*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_ALL_DEPENDENCIES_RESOLVED*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_PUSH*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_EVENT_EOK*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_EVENT_FAKE*/ + SVA_GB_WAIT_FOR_START, /*SVA_GB_EVENT_ACTIVE*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_EVENT_INACTIVE*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_RESET*/ + SVA_GB_NOT_INITIALIZED, /*SVA_GB_CONTROL_DELETE*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_EVENT_ERROR*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_FLUSH_IN*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_FLUSH_OUT*/ + SVA_GB_WAIT_FOR_ACTIVATE, /*SVA_GB_CANCEL*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_UPDATE_PARAM*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_EVENT_ABORT*/ + }, + /* Current State = SVA_GB_WAIT_FOR_START */ + { + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_CREATE*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_CONFIGURE*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_INTERNAL_NEEDS*/ + SVA_GB_WAIT_FOR_START, /*SVA_GB_ACTIVATE*/ + SVA_GB_WAIT_FOR_START, /*SVA_GB_INACTIVATE*/ + SVA_GB_WAIT_FOR_DATA, /*SVA_GB_CONTROL_START*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_CONTROL_STOP*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_CONTROL_ABORT*/ + SVA_GB_WAIT_FOR_START, /*SVA_GB_ALL_DEPENDENCIES_RESOLVED*/ + SVA_GB_WAIT_FOR_START, /*SVA_GB_PUSH*/ + SVA_GB_ERROR, /*SVA_GB_EVENT_EOK*/ + SVA_GB_ERROR, /*SVA_GB_EVENT_FAKE*/ + SVA_GB_WAIT_FOR_START, /*SVA_GB_EVENT_ACTIVE*/ + SVA_GB_WAIT_FOR_START, /*SVA_GB_EVENT_INACTIVE*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_RESET*/ + SVA_GB_NOT_INITIALIZED, /*SVA_GB_CONTROL_DELETE*/ + SVA_GB_ERROR, /*SVA_GB_EVENT_ERROR*/ + SVA_GB_FLUSHING_IN, /*SVA_GB_FLUSH_IN*/ + SVA_GB_FLUSHING_OUT, /*SVA_GB_FLUSH_OUT*/ + SVA_GB_WAIT_FOR_START, /*SVA_GB_CANCEL*/ + SVA_GB_WAIT_FOR_START , /*SVA_GB_UPDATE_PARAM*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_EVENT_ABORT*/ + }, + /* Current State = SVA_GB_FLUSHING_IN */ + { + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_CREATE*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_CONFIGURE*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_INTERNAL_NEEDS*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_ACTIVATE*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_INACTIVATE*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_CONTROL_START*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_CONTROL_STOP*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_CONTROL_ABORT*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_ALL_DEPENDENCIES_RESOLVED*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_PUSH*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_EVENT_EOK*/ + SVA_GB_WAIT_FOR_START, /*SVA_GB_EVENT_FAKE*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_EVENT_ACTIVE*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_EVENT_INACTIVE*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_RESET*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_CONTROL_DELETE*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_EVENT_ERROR*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_FLUSH_IN*/ + SVA_GB_WAIT_FOR_START, /*SVA_GB_FLUSH_OUT*/ + SVA_GB_FLUSHING_IN, /*SVA_GB_CANCEL*/ + SVA_GB_TRANSITION_REJECTED /*SVA_GB_UPDATE_PARAM*/ + }, + /* Current State = SVA_GB_FLUSHING_OUT */ + { + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_CREATE*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_CONFIGURE*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_INTERNAL_NEEDS*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_ACTIVATE*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_INACTIVATE*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_CONTROL_START*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_CONTROL_STOP*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_CONTROL_ABORT*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_ALL_DEPENDENCIES_RESOLVED*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_PUSH*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_EVENT_EOK*/ + SVA_GB_WAIT_FOR_START, /*SVA_GB_EVENT_FAKE*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_EVENT_ACTIVE*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_EVENT_INACTIVE*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_RESET*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_CONTROL_DELETE*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_EVENT_ERROR*/ + SVA_GB_WAIT_FOR_START, /*SVA_GB_FLUSH_IN*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_FLUSH_OUT*/ + SVA_GB_FLUSHING_OUT, /*SVA_GB_CANCEL*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_UPDATE_PARAM*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_EVENT_ABORT*/ + }, + /* Current State = SVA_GB_WAIT_FOR_DATA */ + { + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_CREATE*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_CONFIGURE*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_INTERNAL_NEEDS*/ + SVA_GB_WAIT_FOR_DATA, /*SVA_GB_ACTIVATE*/ + SVA_GB_WAIT_FOR_DATA, /*SVA_GB_INACTIVATE*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_CONTROL_START*/ + SVA_GB_STOP_REQUESTED, /*SVA_GB_CONTROL_STOP*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_CONTROL_ABORT*/ + SVA_GB_RUNNING, /*SVA_GB_ALL_DEPENDENCIES_RESOLVED*/ + SVA_GB_WAIT_FOR_DATA, /*SVA_GB_PUSH*/ + SVA_GB_ERROR, /*SVA_GB_EVENT_EOK*/ + SVA_GB_ERROR, /*SVA_GB_EVENT_FAKE*/ + SVA_GB_WAIT_FOR_DATA, /*SVA_GB_EVENT_ACTIVE*/ + SVA_GB_WAIT_FOR_DATA, /*SVA_GB_EVENT_INACTIVE*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_RESET*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_CONTROL_DELETE*/ + SVA_GB_ERROR, /*SVA_GB_EVENT_ERROR*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_FLUSH_IN*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_FLUSH_OUT*/ + SVA_GB_WAIT_FOR_DATA, /*SVA_GB_CANCEL*/ + SVA_GB_WAIT_FOR_DATA, /*SVA_GB_UPDATE_PARAM*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_EVENT_ABORT*/ + }, + /* Current State = SVA_GB_RUNNING */ + { + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_CREATE*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_CONFIGURE*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_INTERNAL_NEEDS*/ + SVA_GB_RUNNING, /*SVA_GB_ACTIVATE*/ + SVA_GB_RUNNING, /*SVA_GB_INACTIVATE*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_CONTROL_START*/ + SVA_GB_STOP_REQUESTED, /*SVA_GB_CONTROL_STOP*/ + SVA_GB_ABORT_REQUESTED, /*SVA_GB_CONTROL_ABORT*/ + SVA_GB_RUNNING, /*SVA_GB_ALL_DEPENDENCIES_RESOLVED*/ + SVA_GB_RUNNING, /*SVA_GB_PUSH*/ + SVA_GB_WAIT_FOR_DATA, /*SVA_GB_EVENT_EOK*/ + SVA_GB_ERROR, /*SVA_GB_EVENT_FAKE*/ + SVA_GB_RUNNING, /*SVA_GB_EVENT_ACTIVE*/ + SVA_GB_RUNNING, /*SVA_GB_EVENT_INACTIVE*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_RESET*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_CONTROL_DELETE*/ + SVA_GB_ERROR, /*SVA_GB_EVENT_ERROR*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_FLUSH_IN*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_FLUSH_OUT*/ + SVA_GB_RUNNING, /*SVA_GB_CANCEL*/ + SVA_GB_RUNNING, /*SVA_GB_UPDATE_PARAM*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_EVENT_ABORT*/ + }, + /* Current State = SVA_GB_ABORT_REQUESTED */ + { + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_CREATE*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_CONFIGURE*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_INTERNAL_NEEDS*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_ACTIVATE*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_INACTIVATE*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_CONTROL_START*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_CONTROL_STOP*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_CONTROL_ABORT*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_ALL_DEPENDENCIES_RESOLVED*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_PUSH*/ + SVA_GB_ERROR, /*SVA_GB_EVENT_EOK*/ + SVA_GB_ERROR, /*SVA_GB_EVENT_FAKE*/ + SVA_GB_ERROR, /*SVA_GB_EVENT_ACTIVE*/ + SVA_GB_ERROR, /*SVA_GB_EVENT_INACTIVE*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_RESET*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_CONTROL_DELETE*/ + SVA_GB_ERROR, /*SVA_GB_EVENT_ERROR*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_FLUSH_IN*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_FLUSH_OUT*/ + SVA_GB_ABORT_REQUESTED, /*SVA_GB_CANCEL*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_UPDATE_PARAM*/ + SVA_GB_ERROR /*SVA_GB_EVENT_ABORT*/ //check + }, + /* Current State = SVA_GB_STOP_REQUESTED */ + { + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_CREATE*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_CONFIGURE*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_INTERNAL_NEEDS*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_ACTIVATE*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_INACTIVATE*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_CONTROL_START*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_CONTROL_STOP*/ + SVA_GB_ABORT_REQUESTED, /*SVA_GB_CONTROL_ABORT*/ + SVA_GB_STOP_REQUESTED, /*SVA_GB_ALL_DEPENDENCIES_RESOLVED*/ + SVA_GB_STOP_REQUESTED, /*SVA_GB_PUSH*/ + SVA_GB_WAIT_FOR_START, /*SVA_GB_EVENT_EOK*/ + SVA_GB_ERROR, /*SVA_GB_EVENT_FAKE*/ + SVA_GB_ERROR, /*SVA_GB_EVENT_ACTIVE*/ + SVA_GB_ERROR, /*SVA_GB_EVENT_INACTIVE*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_RESET*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_CONTROL_DELETE*/ + SVA_GB_ERROR, /*SVA_GB_EVENT_ERROR*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_FLUSH_IN*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_FLUSH_OUT*/ + SVA_GB_STOP_REQUESTED, /*SVA_GB_CANCEL*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_UPDATE_PARAM*/ + SVA_GB_ERROR, /*SVA_GB_EVENT_ABORT*/ + }, + /* Current State = SVA_GB_ERROR */ + { + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_CREATE*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_CONFIGURE*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_INTERNAL_NEEDS*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_ACTIVATE*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_INACTIVATE*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_CONTROL_START*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_CONTROL_STOP*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_CONTROL_ABORT*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_ALL_DEPENDENCIES_RESOLVED*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_PUSH*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_EVENT_EOK*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_EVENT_FAKE*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_EVENT_ACTIVE*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_EVENT_INACTIVE*/ + SVA_GB_WAIT_FOR_START, /*SVA_GB_RESET*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_CONTROL_DELETE*/ + SVA_GB_ERROR, /*SVA_GB_EVENT_ERROR*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_FLUSH*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_FLUSH_IN*/ + SVA_GB_ERROR, /*SVA_GB_CANCEL*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_UPDATE_PARAM*/ + SVA_GB_TRANSITION_REJECTED, /*SVA_GB_EVENT_ABORT*/ + } +}; + +/*activate state machine description*/ +PRIVATE const t_sva_gb_activate_state activateStateMachine[SVA_GB_LAST_ACTIVATE_DUMMY_STATE][SVA_GB_LAST_DUMMY_TRANSITION]= { + /* Current State = SVA_GB_INACTIVE */ + { + SVA_GB_INACTIVE, /*SVA_GB_CREATE*/ + SVA_GB_INACTIVE, /*SVA_GB_CONFIGURE*/ + SVA_GB_INACTIVE, /*SVA_GB_INTERNAL_NEEDS*/ + SVA_GB_IN_ACTIVATION, /*SVA_GB_ACTIVATE*/ + SVA_GB_ACTIVATE_TRANSITION_REJECTED, /*SVA_GB_INACTIVATE*/ + SVA_GB_INACTIVE, /*SVA_GB_CONTROL_START*/ + SVA_GB_INACTIVE, /*SVA_GB_CONTROL_STOP*/ + SVA_GB_ACTIVATE_TRANSITION_REJECTED, /*SVA_GB_CONTROL_ABORT*/ + SVA_GB_INACTIVE, /*SVA_GB_ALL_DEPENDENCIES_RESOLVED*/ + SVA_GB_INACTIVE, /*SVA_GB_PUSH*/ + SVA_GB_INACTIVE, /*SVA_GB_EVENT_EOK*/ + SVA_GB_INACTIVE, /*SVA_GB_EVENT_FAKE*/ + SVA_GB_INACTIVE, /*SVA_GB_EVENT_ACTIVE*/ + SVA_GB_INACTIVE, /*SVA_GB_EVENT_INACTIVE*/ + SVA_GB_INACTIVE, /*SVA_GB_RESET*/ + SVA_GB_INACTIVE, /*SVA_GB_CONTROL_DELETE*/ + SVA_GB_INACTIVE, /*SVA_GB_EVENT_ERROR*/ + SVA_GB_INACTIVE, /*SVA_GB_FLUSH_IN*/ + SVA_GB_INACTIVE, /*SVA_GB_FLUSH_OUT*/ + SVA_GB_ACTIVATE_TRANSITION_REJECTED, /*SVA_GB_CANCEL*/ + SVA_GB_INACTIVE, /*SVA_GB_UPDATE_PARAM*/ + SVA_GB_INACTIVE /*SVA_GB_EVENT_ABORT*/ + }, + /* Current State = SVA_GB_IN_ACTIVATION */ + { + SVA_GB_ACTIVATE_TRANSITION_REJECTED, /*SVA_GB_CREATE*/ + SVA_GB_ACTIVATE_TRANSITION_REJECTED, /*SVA_GB_CONFIGURE*/ + SVA_GB_ACTIVATE_TRANSITION_REJECTED, /*SVA_GB_INTERNAL_NEEDS*/ + SVA_GB_ACTIVATE_TRANSITION_REJECTED, /*SVA_GB_ACTIVATE*/ + SVA_GB_ACTIVATE_TRANSITION_REJECTED, /*SVA_GB_INACTIVATE*/ + SVA_GB_IN_ACTIVATION, /*SVA_GB_CONTROL_START*/ + SVA_GB_IN_ACTIVATION, /*SVA_GB_CONTROL_STOP*/ + SVA_GB_ACTIVATE_TRANSITION_REJECTED, /*SVA_GB_CONTROL_ABORT*/ + SVA_GB_IN_ACTIVATION, /*SVA_GB_ALL_DEPENDENCIES_RESOLVED*/ + SVA_GB_IN_ACTIVATION, /*SVA_GB_PUSH*/ + SVA_GB_IN_ACTIVATION, /*SVA_GB_EVENT_EOK*/ + SVA_GB_IN_ACTIVATION, /*SVA_GB_EVENT_FAKE*/ + SVA_GB_ACTIVE, /*SVA_GB_EVENT_ACTIVE*/ + SVA_GB_IN_ACTIVATION, /*SVA_GB_EVENT_INACTIVE*/ + SVA_GB_IN_ACTIVATION, /*SVA_GB_RESET*/ + SVA_GB_ACTIVATE_TRANSITION_REJECTED, /*SVA_GB_CONTROL_DELETE*/ + SVA_GB_IN_ACTIVATION, /*SVA_GB_EVENT_ERROR*/ + SVA_GB_IN_ACTIVATION, /*SVA_GB_FLUSH_IN*/ + SVA_GB_IN_ACTIVATION, /*SVA_GB_FLUSH_OUT*/ + SVA_GB_INACTIVE, /*SVA_GB_CANCEL*/ + SVA_GB_IN_ACTIVATION, /*SVA_GB_UPDATE_PARAM*/ + SVA_GB_IN_ACTIVATION /*SVA_GB_EVENT_ABORT*/ + }, + /* Current State = SVA_GB_ACTIVE */ + { + SVA_GB_ACTIVATE_TRANSITION_REJECTED, /*SVA_GB_CREATE*/ + SVA_GB_ACTIVATE_TRANSITION_REJECTED, /*SVA_GB_CONFIGURE*/ + SVA_GB_ACTIVATE_TRANSITION_REJECTED, /*SVA_GB_INTERNAL_NEEDS*/ + SVA_GB_ACTIVATE_TRANSITION_REJECTED, /*SVA_GB_ACTIVATE*/ + SVA_GB_IN_INACTIVATION, /*SVA_GB_INACTIVATE*/ + SVA_GB_ACTIVE, /*SVA_GB_CONTROL_START*/ + SVA_GB_ACTIVE, /*SVA_GB_CONTROL_STOP*/ + SVA_GB_ACTIVE, /*SVA_GB_CONTROL_ABORT*/ + SVA_GB_ACTIVE, /*SVA_GB_ALL_DEPENDENCIES_RESOLVED*/ + SVA_GB_ACTIVE, /*SVA_GB_PUSH*/ + SVA_GB_ACTIVE, /*SVA_GB_EVENT_EOK*/ + SVA_GB_ACTIVE, /*SVA_GB_EVENT_FAKE*/ + SVA_GB_ACTIVE, /*SVA_GB_EVENT_ACTIVE*/ + SVA_GB_ACTIVE, /*SVA_GB_EVENT_INACTIVE*/ + SVA_GB_ACTIVE, /*SVA_GB_RESET*/ + SVA_GB_INACTIVE, /*SVA_GB_CONTROL_DELETE*/ + SVA_GB_ACTIVE, /*SVA_GB_EVENT_ERROR*/ + SVA_GB_ACTIVE, /*SVA_GB_FLUSH_IN*/ + SVA_GB_ACTIVE, /*SVA_GB_FLUSH_OUT*/ + SVA_GB_ACTIVATE_TRANSITION_REJECTED, /*SVA_GB_CANCEL*/ + SVA_GB_ACTIVE, /*SVA_GB_UPDATE_PARAM*/ + SVA_GB_ACTIVE /*SVA_GB_EVENT_ABORT*/ + }, + /* Current State = SVA_GB_IN_INACTIVATION */ + { + SVA_GB_ACTIVATE_TRANSITION_REJECTED, /*SVA_GB_CREATE*/ + SVA_GB_ACTIVATE_TRANSITION_REJECTED, /*SVA_GB_CONFIGURE*/ + SVA_GB_ACTIVATE_TRANSITION_REJECTED, /*SVA_GB_INTERNAL_NEEDS*/ + SVA_GB_ACTIVATE_TRANSITION_REJECTED, /*SVA_GB_ACTIVATE*/ + SVA_GB_ACTIVATE_TRANSITION_REJECTED, /*SVA_GB_INACTIVATE*/ + SVA_GB_IN_INACTIVATION, /*SVA_GB_CONTROL_START*/ + SVA_GB_IN_INACTIVATION, /*SVA_GB_CONTROL_STOP*/ + SVA_GB_ACTIVATE_TRANSITION_REJECTED, /*SVA_GB_CONTROL_ABORT*/ + SVA_GB_IN_INACTIVATION, /*SVA_GB_ALL_DEPENDENCIES_RESOLVED*/ + SVA_GB_IN_INACTIVATION, /*SVA_GB_PUSH*/ + SVA_GB_IN_INACTIVATION, /*SVA_GB_EVENT_EOK*/ + SVA_GB_IN_INACTIVATION, /*SVA_GB_EVENT_FAKE*/ + SVA_GB_IN_INACTIVATION, /*SVA_GB_EVENT_ACTIVE*/ + SVA_GB_INACTIVE, /*SVA_GB_EVENT_INACTIVE*/ + SVA_GB_INACTIVE, /*SVA_GB_RESET*/ + SVA_GB_ACTIVATE_TRANSITION_REJECTED, /*SVA_GB_CONTROL_DELETE*/ + SVA_GB_IN_INACTIVATION, /*SVA_GB_EVENT_ERROR*/ + SVA_GB_IN_INACTIVATION, /*SVA_GB_FLUSH_IN*/ + SVA_GB_IN_INACTIVATION, /*SVA_GB_FLUSH_OUT*/ + SVA_GB_ACTIVE, /*SVA_GB_CANCEL*/ + SVA_GB_IN_INACTIVATION, /*SVA_GB_UPDATE_PARAM*/ + SVA_GB_IN_INACTIVATION /*SVA_GB_EVENT_ABORT*/ + } +}; + +/*------------------------------------------------------------------------ + * Private functions prototype + *----------------------------------------------------------------------*/ +PRIVATE t_sva_gb_error sva_GB_ResolveDependencies(t_sva_service_instance_num ); +PRIVATE t_bool sva_GB_IsConfigurationValid(const t_sva_preprocessor_configuration *); +PRIVATE t_bool sva_GB_IsIrpConfigurationValid(const t_sva_preprocessor_configuration *); +PRIVATE t_sva_gb_state sva_GB_UpdateInstanceStateMachine(t_sva_service_instance_num ,t_sva_gb_transition ); +PRIVATE t_bool sva_GB_isTransitionValid(t_sva_service_instance_num ,t_sva_gb_transition ); +PRIVATE t_sva_error sva_GB_CheckServiceId(t_sva_service_id ); +PRIVATE t_sva_error sva_GB_BuildParamInStructure(const t_sva_preprocessor_configuration *,t_sva_grb_param_in *); +PRIVATE t_sva_error sva_GB_BuildParamInOutStructure(const t_sva_ace_offset *,t_sva_grb_param_inout *); +PRIVATE t_sva_error sva_GB_DoReset(t_sva_service_id ); +PRIVATE t_sva_error sva_GB_DoFlushIn(t_sva_service_id ); +PRIVATE t_sva_error sva_GB_DoFlushOut(t_sva_service_id ); +PRIVATE t_sva_gb_error sva_GB_ResetStatus(t_sva_preprocessor_status *); +PRIVATE void sva_GB_ConfigurationChangeOnPush(t_sva_service_id ,t_sva_buffer_type ,t_sva_push_mode ,t_sva_buffer_id ); +PRIVATE void sva_GB_ConfigurationChangeOnSolveDep(t_sva_service_instance_num ,t_sva_gb_subtask_dependencies ,t_sva_buffer_id ); +PRIVATE t_bool sva_GB_isChangeConfIsImmediate(const t_sva_preprocessor_configuration *,const t_sva_preprocessor_configuration *); +PRIVATE void sva_GB_ResetDescriptor(t_sva_gb_descriptor *); + +/****************************************************************************/ +/* NAME: t_sva_gb_error sva_GB_Init ( void ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine initialize the Grab Management module. */ +/* 1) Set state of instance to SVA_SERVICE_NOT_INITIALIZED */ +/* 2) init fifos */ +/* */ +/* PARAMETERS: */ +/* IN : none */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/* - always SVA_OK */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + TO DO : + - add debug data init +*/ +PUBLIC t_sva_error sva_GB_Init(void) +{ + t_uint32 i; + + /*init all grab instances*/ + for(i=0;i= 20 + #else + if (pConf->transformId == SVA_PREPROCESSOR_YUV420_RASTER_OUT || pConf->transformId == SVA_PREPROCESSOR_SENSOR_YUV420_RASTER_OUT) + { + return SVA_INCOHERENT_CONFIGURATION; + } + #endif + #endif + + /*check configuration validity*/ + if (sva_GB_IsConfigurationValid(pConf)==FALSE) + { + return SVA_INCOHERENT_CONFIGURATION; + } + + /*set isIrpMode variable*/ + if (pConf->transformId == SVA_PREPROCESSOR_SENSOR_YUV420_MB || + pConf->transformId == SVA_PREPROCESSOR_SENSOR_YUV420_SEP_COMP_MB || + pConf->transformId == SVA_PREPROCESSOR_SENSOR_YUV422_SEP_COMP_MB || + pConf->transformId == SVA_PREPROCESSOR_SENSOR_YUV420_RASTER_OUT || + pConf->transformId == SVA_PREPROCESSOR_SENSOR_HIGHQUALITY_YUV420_MB) + { + pDesc->isIrpMode = TRUE; + } + else {pDesc->isIrpMode = FALSE;} + + /*copy it internally*/ + pDesc->confHandle.currentConf=*pConf; + pDesc->confHandle.nextConf=*pConf; + + /* Update the state machine */ + sva_GB_UpdateInstanceStateMachine(instanceNum,SVA_GB_CONFIGURE); + + return SVA_OK; +} + +/****************************************************************************/ +/* NAME: t_sva_error sva_GB_GetInternalNeeds( */ +/* t_sva_service_id serviceId, */ +/* t_size* pNeedsSize */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine returns the size of the memory needed for Grab */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - serviceId: identifier of the service */ +/* - pNeedsSize: size needed */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/* - SVA_OK : Command taken into account */ +/* - SVA_UNKNOWN_SERVICE_ID : service id is not correct */ +/* */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + DONE +*/ +PUBLIC t_sva_error sva_GB_GetInternalNeeds( + t_sva_service_id serviceId, + t_size *pNeedsSize +) +{ + t_sva_service_instance_num instanceNum = READ_INSTANCE_NUM_IN_SERVICE_ID(serviceId); + t_sva_gb_descriptor *pDesc=&grabDesc[instanceNum]; + t_sva_preprocessor_configuration *pConf=&pDesc->confHandle.currentConf; + t_sva_error status; + t_uint32 fifoSize; + + /*check for service id validity*/ + status=sva_GB_CheckServiceId(serviceId); + if (status!=SVA_OK) {return status;} + + /*check pointer validity*/ + GB_CHECK_NULL_POINTER(pNeedsSize); + + /*compute memory size need*/ + *pNeedsSize = 0; + /*memory need by event management*/ + status=sva_EM_GetInternalNeeds(pNeedsSize); + if (status!=SVA_OK) {return status;} + /*memory need due to image buffer*/ + if (pConf->isInputInterlaced == TRUE && pConf->isOutputFrame == TRUE) + { + /* + * In case of interlaced input and output in frame (field0+field1) then + * we allocate 2 times more space since user buffer will be push two times + */ + GET_FIFO_MEMORY_NEEDS(t_sva_buffer_id, 2*PUSH_FIFO_DEFAULT_SIZE, fifoSize); + } + else + { + GET_FIFO_MEMORY_NEEDS(t_sva_buffer_id, PUSH_FIFO_DEFAULT_SIZE, fifoSize); + } + *pNeedsSize+=fifoSize; + GET_FIFO_MEMORY_NEEDS(t_sva_buffer_id, SUBTASK_GRAB_NUMBER, fifoSize); + *pNeedsSize+=fifoSize; + /*memory need due to subtask dependency fifo*/ + GET_FIFO_MEMORY_NEEDS(t_sva_gb_subtask_dependencies, SUBTASK_GRAB_NUMBER, fifoSize); + *pNeedsSize+=fifoSize; + + if(pConf->transformId == SVA_PREPROCESSOR_SENSOR_HIGHQUALITY_YUV420_MB) + { + /*For Grid buffer*/ + GET_FIFO_MEMORY_NEEDS(t_sva_buffer_id, PUSH_FIFO_DEFAULT_SIZE, fifoSize); + *pNeedsSize+=fifoSize; + GET_FIFO_MEMORY_NEEDS(t_sva_buffer_id, PUSH_FIFO_DEFAULT_SIZE, fifoSize); + *pNeedsSize+=fifoSize; + + /*For Snapshot buffer*/ + GET_FIFO_MEMORY_NEEDS(t_sva_buffer_id, PUSH_FIFO_DEFAULT_SIZE, fifoSize); + *pNeedsSize+=fifoSize; + GET_FIFO_MEMORY_NEEDS(t_sva_buffer_id, PUSH_FIFO_DEFAULT_SIZE, fifoSize); + *pNeedsSize+=fifoSize; + + } + + return SVA_OK; +} + +/****************************************************************************/ +/* NAME: t_sva_error sva_GB_ProvideInternalNeeds ( */ +/* t_sva_service_id serviceId */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine allows to end the configuration of the service since */ +/* memory need has been provide by user. */ +/* - create fifos */ +/* - create subtasks */ +/* - create subtasklist */ +/* - enable events */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - serviceId: identifier of the service */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/* - SVA_OK : Command taken into account */ +/* - SVA_UNKNOWN_SERVICE_ID : service id is not correct */ +/* - SVA_UNEXPECTED_API_CALL : Command cannot be excecuted in */ +/* current context. */ +/* - SVA_INTERNAL_PREPROCESSOR_ERROR : internal error */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + DONE +*/ +PUBLIC t_sva_error sva_GB_ProvideInternalNeeds(t_sva_service_id serviceId) +{ + t_sva_error status; + t_sva_service_instance_num instanceNum = READ_INSTANCE_NUM_IN_SERVICE_ID(serviceId); + t_sva_gb_descriptor *pDesc=&grabDesc[instanceNum]; + t_sva_preprocessor_configuration *pConf=&pDesc->confHandle.currentConf; + t_sva_ff_error ffError; + t_sva_tm_error tmError; + t_sva_grb_param_in paramInBuffer; + t_sva_grb_param_inout paramInOutBuffer; + t_sva_grb_internal_buffer paramInternalBuffer; + t_sva_ace_offset initAceOffset={0,0,0,0}; + t_sva_tm_task_ctrl_desc grabTaskDesc; + t_sva_fw_features neededFeatures = SVA_FW_FEAT_PRE_PROCESSOR; + t_uint32 i; + t_sva_mm_error mmError; + + /*check for service id validity*/ + status=sva_GB_CheckServiceId(serviceId); + if (status!=SVA_OK) {return status;} + + /*check that transition is allowed*/ + if (sva_GB_isTransitionValid(instanceNum,SVA_GB_INTERNAL_NEEDS)==FALSE) {return SVA_UNEXPECTED_API_CALL;} + + /*provide some memory to event management*/ + status=sva_EM_ProvideInternalNeeds(serviceId); + if (status!=SVA_OK) {return status;} + + /*create fifo*/ + if (pConf->isInputInterlaced == TRUE && pConf->isOutputFrame == TRUE) + { + /* + * In case of interlaced input and output in frame (field0+field1) then + * we allocate 2 times more space since user buffer will be push two times + */ + CREATE_FIFO(t_sva_buffer_id, 2*PUSH_FIFO_DEFAULT_SIZE, pDesc->outputImageFifos.pushFifo, ffError); + } + else + { + CREATE_FIFO(t_sva_buffer_id, PUSH_FIFO_DEFAULT_SIZE, pDesc->outputImageFifos.pushFifo, ffError); + } + if (ffError != SVA_FIFO_OK) {return SVA_INTERNAL_PREPROCESSOR_ERROR;} + CREATE_FIFO(t_sva_buffer_id, SUBTASK_GRAB_NUMBER, pDesc->outputImageFifos.inUseFifo, ffError); + if (ffError != SVA_FIFO_OK) {return SVA_INTERNAL_PREPROCESSOR_ERROR;} + CREATE_FIFO(t_sva_gb_subtask_dependencies, SUBTASK_GRAB_NUMBER, pDesc->subtasksDependencyFifo, ffError); + if (ffError != SVA_FIFO_OK) {return SVA_INTERNAL_PREPROCESSOR_ERROR;} + + if(pConf->transformId == SVA_PREPROCESSOR_SENSOR_HIGHQUALITY_YUV420_MB) + { + CREATE_FIFO(t_sva_buffer_id, PUSH_FIFO_DEFAULT_SIZE, pDesc->paramFifos.pushFifo,ffError); + if (ffError != SVA_FIFO_OK) {return SVA_INTERNAL_PREPROCESSOR_ERROR;} + CREATE_FIFO(t_sva_buffer_id, PUSH_FIFO_DEFAULT_SIZE, pDesc->paramFifos.inUseFifo,ffError); + if (ffError != SVA_FIFO_OK) {return SVA_INTERNAL_PREPROCESSOR_ERROR;} + + CREATE_FIFO(t_sva_buffer_id, PUSH_FIFO_DEFAULT_SIZE, pDesc->snapshotImageFifos.pushFifo,ffError); + if (ffError != SVA_FIFO_OK) {return SVA_INTERNAL_PREPROCESSOR_ERROR;} + CREATE_FIFO(t_sva_buffer_id, PUSH_FIFO_DEFAULT_SIZE, pDesc->snapshotImageFifos.inUseFifo,ffError); + if (ffError != SVA_FIFO_OK) {return SVA_INTERNAL_PREPROCESSOR_ERROR;} + + + } + + /*create subtasks*/ + grabTaskDesc.memId=GRAB_DEFAULT_MEMORY_ID; + grabTaskDesc.fieldnb=GRAB_FIELD_NUMBER; + grabTaskDesc.pfieldctrldesc=(t_sva_tm_field_ctrl_desc *)defaultGrabFieldDescArray; + for(i=0;itransformId],SVA_TM_NO_POST_PROCESSING, + SVA_TM_NO_SYNCHRO,SVA_TM_EOT_EN,SVA_TM_BBM_DEFAULT,&pDesc->subtasksIdArray[i]); + if (tmError != SVA_TM_OK) {return SVA_INTERNAL_PREPROCESSOR_ERROR;} + } + /*links inout between them*/ + for(i=0;isubtasksIdArray[i], + SVA_TM_GRB_ADDR_IN_FRAME_PARAMETERS, + pDesc->subtasksIdArray[(i+SUBTASK_GRAB_NUMBER-1)%SUBTASK_GRAB_NUMBER], + SVA_TM_GRB_ADDR_OUT_FRAME_PARAMETERS); + if (tmError != SVA_TM_OK) {return SVA_INTERNAL_PREPROCESSOR_ERROR;} + } + + /*create subtasklist*/ + if (pConf->isAceEnable == TRUE) {neededFeatures |= SVA_FW_FEAT_ACE;} + if (pConf->transformId == SVA_PREPROCESSOR_SENSOR_YUV420_MB || + pConf->transformId == SVA_PREPROCESSOR_SENSOR_YUV420_SEP_COMP_MB || + pConf->transformId == SVA_PREPROCESSOR_SENSOR_YUV422_SEP_COMP_MB || + pConf->transformId == SVA_PREPROCESSOR_SENSOR_YUV420_RASTER_OUT || + pConf->transformId == SVA_PREPROCESSOR_SENSOR_HIGHQUALITY_YUV420_MB) + { + neededFeatures |= SVA_FW_FEAT_IRP; + } + + if(pConf->transformId == SVA_PREPROCESSOR_SENSOR_HIGHQUALITY_YUV420_MB) + neededFeatures |= SVA_FW_FEAT_PREPROC_ALGO; + + + tmError=sva_TM_CreateSubTaskList(SVA_TM_GRAB,serviceId,neededFeatures,&pDesc->subtasksListId); + if (tmError != SVA_TM_OK) {return SVA_INTERNAL_PREPROCESSOR_ERROR;} + + /* enable events for sub task list*/ + /* we enable EOT, GS, ERR and EOK event*/ + /* we also enable activate, inactivate and fake event*/ + /* we also enable packet events even if we are not in irp mode */ + tmError=sva_TM_DisableAllVirtualHwEvents(pDesc->subtasksListId); + if (tmError != SVA_TM_OK) {return SVA_INTERNAL_PREPROCESSOR_ERROR;} + tmError=sva_TM_EnableVirtualHwEvents(pDesc->subtasksListId,SVA_TM_EOT_HW_EVENT); + if (tmError != SVA_TM_OK) {return SVA_INTERNAL_PREPROCESSOR_ERROR;} + if (pConf->transformId == SVA_PREPROCESSOR_SENSOR_HIGHQUALITY_YUV420_MB) + { + tmError=sva_TM_EnableVirtualHwEvents(pDesc->subtasksListId,SVA_TM_BOF_HW_EVENT); + if (tmError != SVA_TM_OK) {return SVA_INTERNAL_PREPROCESSOR_ERROR;} + + } + + tmError=sva_TM_EnableVirtualHwEvents(pDesc->subtasksListId,SVA_TM_GS_HW_EVENT); + if (tmError != SVA_TM_OK) {return SVA_INTERNAL_PREPROCESSOR_ERROR;} + tmError=sva_TM_EnableVirtualHwEvents(pDesc->subtasksListId,SVA_TM_ERR_HW_EVENT); + if (tmError != SVA_TM_OK) {return SVA_INTERNAL_PREPROCESSOR_ERROR;} + tmError=sva_TM_EnableVirtualHwEvents(pDesc->subtasksListId,SVA_TM_EOK_HW_EVENT); + if (tmError != SVA_TM_OK) {return SVA_INTERNAL_PREPROCESSOR_ERROR;} + tmError=sva_TM_EnableVirtualHwEvents(pDesc->subtasksListId,SVA_TM_INACTIVE_HW_EVENT); + if (tmError != SVA_TM_OK) {return SVA_INTERNAL_PREPROCESSOR_ERROR;} + tmError=sva_TM_EnableVirtualHwEvents(pDesc->subtasksListId,SVA_TM_ACTIVE_HW_EVENT); + if (tmError != SVA_TM_OK) {return SVA_INTERNAL_PREPROCESSOR_ERROR;} + tmError=sva_TM_EnableVirtualHwEvents(pDesc->subtasksListId,SVA_TM_FAKE_HW_EVENT); + if (tmError != SVA_TM_OK) {return SVA_INTERNAL_PREPROCESSOR_ERROR;} + tmError=sva_TM_EnableVirtualHwEvents(pDesc->subtasksListId,SVA_TM_ABORT_HW_EVENT); + if (tmError != SVA_TM_OK) {return SVA_INTERNAL_PREPROCESSOR_ERROR;} + if (pDesc->isIrpMode) + { + /* Only enable Irp related virtual event if Irp feature is used. */ + tmError=sva_TM_EnableVirtualHwEvents(pDesc->subtasksListId,SVA_TM_PACKET_READ_HW_EVENT); + if (tmError != SVA_TM_OK) {return SVA_INTERNAL_PREPROCESSOR_ERROR;} + tmError=sva_TM_EnableVirtualHwEvents(pDesc->subtasksListId,SVA_TM_PACKET_WRITE_HW_EVENT); + if (tmError != SVA_TM_OK) {return SVA_INTERNAL_PREPROCESSOR_ERROR;} + tmError=sva_TM_EnableVirtualHwEvents(pDesc->subtasksListId,SVA_TM_PACKET_ERROR_HW_EVENT); + if (tmError != SVA_TM_OK) {return SVA_INTERNAL_PREPROCESSOR_ERROR;} + } + + /*initialize paramin of subtasks*/ + status=sva_GB_BuildParamInStructure(pConf,¶mInBuffer); + if (status!=SVA_OK) {return status;} + for(i=0;iisInputInterlaced==TRUE) + { + if (i%2 == 0) {paramInBuffer.field_sync=SVA_GB_FIELD_ZERO;} + else {paramInBuffer.field_sync=SVA_GB_FIELD_ONE;} + } + tmError=sva_TM_InitSubTaskField(pDesc->subtasksIdArray[i],SVA_TM_GRB_ADDR_IN_PARAMETERS, + (t_logical_address)¶mInBuffer,sizeof(t_sva_grb_param_in)); + if (tmError != SVA_TM_OK) {return SVA_INTERNAL_PREPROCESSOR_ERROR;} + } + /*initialize in paraminout of subtasks*/ + /*normally only first subtask should be init that way*/ + status=sva_GB_BuildParamInOutStructure(&initAceOffset,¶mInOutBuffer); + if (status!=SVA_OK) {return status;} + for(i=0;isubtasksIdArray[i],SVA_TM_GRB_ADDR_IN_FRAME_PARAMETERS, + (t_logical_address)¶mInOutBuffer,sizeof(t_sva_grb_param_inout)); + if (tmError != SVA_TM_OK) {return SVA_INTERNAL_PREPROCESSOR_ERROR;} + } + // For CR133 + if(pConf->transformId == SVA_PREPROCESSOR_SENSOR_HIGHQUALITY_YUV420_MB) + { + //Allocate 10 MB + mmError=sva_MM_AllocDedicatedBlock((pConf->sourceFrameDesc.window.image.width)*(pConf->sourceFrameDesc.window.image.height)*2 + (pConf->sourceFrameDesc.window.image.width * 30),SVA_MM_ALIGN_4096BYTES,&grabDesc[instanceNum].idpBlockId); +//\/ mmError=sva_MM_AllocDedicatedBlock(2560*1920*2,SVA_MM_ALIGN_256BYTES,&grabDesc->idpBlockId); + if (mmError!= SVA_MM_OK) {return SVA_INTERNAL_PREPROCESSOR_ERROR;} + mmError=sva_MM_GetDedicatedBlockSystemAddress(grabDesc[instanceNum].idpBlockId,&grabDesc[instanceNum].idpBlockAddr); + if (mmError!= SVA_MM_OK) {return SVA_INTERNAL_PREPROCESSOR_ERROR;} + + //Used to free the buffer only for HQ mode + grabDesc[instanceNum].grabHQEnable = TRUE; + + + //Build internal buffer + paramInternalBuffer.addr_raw_bayer_write_buffer = grabDesc[instanceNum].idpBlockAddr.physical; + + for(i=0;isubtasksIdArray[i],SVA_TM_GRB_ADDR_INTERNAL_BUFFER, + (t_logical_address)¶mInternalBuffer,sizeof(paramInternalBuffer)); + if (tmError != SVA_TM_OK) {return SVA_INTERNAL_PREPROCESSOR_ERROR;} + + } + } + + /* Set default dependencies*/ + pDesc->defaultDep.outputImageDep=NOT_RESOLVED_DEPENDENCY; + + if(pConf->transformId == SVA_PREPROCESSOR_SENSOR_HIGHQUALITY_YUV420_MB) + { + /************************************************************************ + * !! Sarvesh: This dependendecy should depend on requirement of * + * snapshot buffer by FW. For FW V3.13.0, V3.13.1, V3.13.2, and * + * V3.13.2.1 it is mandatory to Push snapshot alongwith output buffer * + * for GrabHQ so this dependeny is NOT_RESOLVED_DEPENDENCY for GrabHQ, * + * it could be configurable if FW add to support dynamically * + * enable/disable snapshot buffer which is not the case till * + * FW V3.13.2.1 !! * + ************************************************************************/ + pDesc->defaultDep.snapshotImageDep = NOT_RESOLVED_DEPENDENCY; + if (pConf->grabhqConfig.isGridironEnabled == TRUE) + { + pDesc->defaultDep.paramDep[SVA_GRAB_GRID0_BUFF_DEP_TO_BE_RESOLVED] = NOT_RESOLVED_DEPENDENCY; + pDesc->defaultDep.paramDep[SVA_GRAB_GRID1_BUFF_DEP_TO_BE_RESOLVED] = NOT_RESOLVED_DEPENDENCY; + pDesc->defaultDep.paramDep[SVA_GRAB_GRID2_BUFF_DEP_TO_BE_RESOLVED] = NOT_RESOLVED_DEPENDENCY; + pDesc->defaultDep.paramDep[SVA_GRAB_GRID3_BUFF_DEP_TO_BE_RESOLVED] = NOT_RESOLVED_DEPENDENCY; + } + else + { + pDesc->defaultDep.paramDep[SVA_GRAB_GRID0_BUFF_DEP_TO_BE_RESOLVED] = INTERNAL_DEPENDENCY; + pDesc->defaultDep.paramDep[SVA_GRAB_GRID1_BUFF_DEP_TO_BE_RESOLVED] = INTERNAL_DEPENDENCY; + pDesc->defaultDep.paramDep[SVA_GRAB_GRID2_BUFF_DEP_TO_BE_RESOLVED] = INTERNAL_DEPENDENCY; + pDesc->defaultDep.paramDep[SVA_GRAB_GRID3_BUFF_DEP_TO_BE_RESOLVED] = INTERNAL_DEPENDENCY; + } + } + else + { + pDesc->defaultDep.paramDep[SVA_GRAB_GRID0_BUFF_DEP_TO_BE_RESOLVED] = INTERNAL_DEPENDENCY; + pDesc->defaultDep.paramDep[SVA_GRAB_GRID1_BUFF_DEP_TO_BE_RESOLVED] = INTERNAL_DEPENDENCY; + pDesc->defaultDep.paramDep[SVA_GRAB_GRID2_BUFF_DEP_TO_BE_RESOLVED] = INTERNAL_DEPENDENCY; + pDesc->defaultDep.paramDep[SVA_GRAB_GRID3_BUFF_DEP_TO_BE_RESOLVED] = INTERNAL_DEPENDENCY; + pDesc->defaultDep.snapshotImageDep = INTERNAL_DEPENDENCY; + } + + /* Push subtask in subtasksDependencyFifo since they are ready to be solved*/ + for(i=0;isubtasksIdArray[i]; + subtaskDep.dependencies=pDesc->defaultDep; + ffError=PUSH_FIFO_ELEM(pDesc->subtasksDependencyFifo, t_sva_gb_subtask_dependencies, subtaskDep); + if (ffError!=SVA_FIFO_OK) {return SVA_INTERNAL_PREPROCESSOR_ERROR;} + } + + /* Update the state machine */ + sva_GB_UpdateInstanceStateMachine(instanceNum,SVA_GB_INTERNAL_NEEDS); + + return SVA_OK; +} + +/****************************************************************************/ +/* NAME: t_sva_error sva_GB_Activate( */ +/* t_sva_service_id serviceId, */ +/* t_sva_service_mode serviceMode, */ +/* t_sva_fw_id *pFwId */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine activates the GRAB service */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - serviceId: identifier of the service */ +/* - serviceMode : set service to real_time or not */ +/* */ +/* OUT : */ +/* - pFwId : identifier of firmware id for which user shall provide location*/ +/* */ +/* RETURN: */ +/* t_sva_error */ +/* - SVA_OK : Command taken into account */ +/* - SVA_UNKNOWN_SERVICE_ID : service id is not correct */ +/* - SVA_UNEXPECTED_API_CALL : Command cannot be excecuted in */ +/* current context. */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + TO DO : + - error code ???? of sva_TM_ActivateSubTaskList +*/ +PUBLIC t_sva_error sva_GB_Activate( + t_sva_service_id serviceId, + t_sva_service_mode serviceMode, + t_sva_fw_id *pFwId +) +{ + t_sva_error status; + t_sva_service_instance_num instanceNum = READ_INSTANCE_NUM_IN_SERVICE_ID(serviceId); + t_sva_gb_descriptor *pDesc=&grabDesc[instanceNum]; + + /*check for service id validity*/ + status=sva_GB_CheckServiceId(serviceId); + if (status!=SVA_OK) {return status;} + + /*check that transition is allowed*/ + if (sva_GB_isTransitionValid(instanceNum,SVA_GB_ACTIVATE)==FALSE) {return SVA_UNEXPECTED_API_CALL;} + + /* Update the state machine */ + /* Update state machine before command is send to task management to avoid race condition */ + sva_GB_UpdateInstanceStateMachine(instanceNum,SVA_GB_ACTIVATE); + + /*activate subTaskList*/ + /*handle informative error code*/ + status=sva_TM_ActivateSubTaskList(pDesc->subtasksListId,serviceMode,pFwId); + if (status != SVA_OK && status != SVA_FW_SWITCH_OCCURED && status != SVA_FW_SWITCH_DELAYED) + { + sva_GB_UpdateInstanceStateMachine(instanceNum,SVA_GB_CANCEL); + + return status; + } + + return status; +} + +/****************************************************************************/ +/* NAME: t_sva_error sva_GB_Inactivate( */ +/* t_sva_service_id serviceId */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine deactivates the GRAB service */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - serviceId: identifier of the service */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/* - SVA_OK : Command taken into account */ +/* - SVA_UNKNOWN_SERVICE_ID : service id is not correct */ +/* - SVA_UNEXPECTED_API_CALL : Command cannot be excecuted in */ +/* current context. */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + TO DO : + - error code ???? of sva_TM_InActivateSubTaskList +*/ +PUBLIC t_sva_error sva_GB_Inactivate(t_sva_service_id serviceId) +{ + t_sva_error status; + t_sva_service_instance_num instanceNum = READ_INSTANCE_NUM_IN_SERVICE_ID(serviceId); + t_sva_gb_descriptor *pDesc=&grabDesc[instanceNum]; + t_sva_tm_error tmError; + + /*check for service id validity*/ + status=sva_GB_CheckServiceId(serviceId); + if (status!=SVA_OK) {return status;} + + /*check that transition is allowed*/ + if (sva_GB_isTransitionValid(instanceNum,SVA_GB_INACTIVATE)==FALSE) {return SVA_UNEXPECTED_API_CALL;} + + /* Update the state machine */ + /* Update state machine before command is send to task management to avoid race condition */ + sva_GB_UpdateInstanceStateMachine(instanceNum,SVA_GB_INACTIVATE); + + /*inactivate subTaskList*/ + /*handle informative error code*/ + tmError=sva_TM_InActivateSubTaskList(pDesc->subtasksListId); + if (tmError != SVA_TM_OK) + { + sva_GB_UpdateInstanceStateMachine(instanceNum,SVA_GB_CANCEL); + + return SVA_INTERNAL_PREPROCESSOR_ERROR; + } + + return SVA_OK; +} + +/****************************************************************************/ +/* NAME: t_sva_error sva_GB_Control ( */ +/* t_sva_service_id serviceId, */ +/* t_sva_service_cmd_id cmdId, */ +/* t_uint32 param */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine allows to control an instance of a Grab Service */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - serviceId: identifier of the given service */ +/* - cmdId: command to apply to the GRAB */ +/* - param: parameter use by command */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/* - SVA_OK : Command taken into account */ +/* - SVA_UNKNOWN_SERVICE_ID : service id is not correct */ +/* - SVA_UNEXPECTED_API_CALL : Command cannot be excecuted in */ +/* current context. */ +/* - SVA_UNKNOWN_CMD_ID : Command to execute is unknown */ +/* - SVA_INTERNAL_PREPROCESSOR_ERROR : internal error */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + DONE +*/ + PUBLIC t_sva_error sva_GB_Control( + t_sva_service_id serviceId, + t_sva_service_cmd_id cmdId, + t_uint32 param +) +{ + t_sva_service_instance_num instanceNum = READ_INSTANCE_NUM_IN_SERVICE_ID(serviceId); + t_sva_gb_descriptor *pDesc=&grabDesc[instanceNum]; + t_sva_error status = SVA_UNEXPECTED_API_CALL; + t_sva_error error; + t_sva_tm_error tmError; + + /*check for service id validity*/ + error=sva_GB_CheckServiceId(serviceId); + if (error!=SVA_OK) {return error;} + +#ifdef __DEBUG + { + t_uint32 systemTime; + + SVA_GetServiceSystemTime(serviceId,&systemTime); + commandGrabDebugTable[instanceNum].commandDebugDesc[commandGrabDebugTable[instanceNum].nbOfCommandReceived%LOG_DEPTH].command=cmdId; + commandGrabDebugTable[instanceNum].commandDebugDesc[commandGrabDebugTable[instanceNum].nbOfCommandReceived%LOG_DEPTH].systemTime=systemTime; + commandGrabDebugTable[instanceNum].commandDebugDesc[commandGrabDebugTable[instanceNum].nbOfCommandReceived%LOG_DEPTH].parameter=param; + commandGrabDebugTable[instanceNum].nbOfCommandReceived++; + } +#endif + + /*handle command*/ + switch(cmdId) + { + case SVA_SERVICE_START: + if (sva_GB_isTransitionValid(instanceNum,SVA_GB_CONTROL_START)==TRUE) + { + /* We check that no other grab is already started*/ + if (grabStartedServiceCnt != NUM_MAX_STARTED_GRAB) + { + grabStartedServiceCnt++; + + /* transition are force before sending task command to avoid race condition*/ + sva_GB_UpdateInstanceStateMachine(instanceNum,SVA_GB_CONTROL_START); + /* as we accepted some push before (or after a restart) some dependencies are perhaps + already scheduled + */ + if (GET_FIFO_NB_ELEMS(pDesc->subtasksDependencyFifo)!=SUBTASK_GRAB_NUMBER) + { + sva_GB_UpdateInstanceStateMachine(instanceNum,SVA_GB_ALL_DEPENDENCIES_RESOLVED); + } + /*now send start command*/ + tmError=sva_TM_SendTaskCommand(pDesc->subtasksListId,SVA_TM_TCMD_START,param); + HCL_DEBUG_ASSERT(tmError==SVA_TM_OK); + + status = SVA_OK; + } + } + break; + case SVA_SERVICE_STOP: + if (sva_GB_isTransitionValid(instanceNum,SVA_GB_CONTROL_STOP)==TRUE) + { + /* transition are force before sending task command to avoid race condition*/ + sva_GB_UpdateInstanceStateMachine(instanceNum,SVA_GB_CONTROL_STOP); + /*stop subtask list*/ + tmError=sva_TM_SendTaskCommand(pDesc->subtasksListId,SVA_TM_TCMD_STOP,param); + HCL_DEBUG_ASSERT(tmError==SVA_TM_OK); + + status = SVA_OK; + } + break; + case SVA_SERVICE_ABORT: + if (sva_GB_isTransitionValid(instanceNum,SVA_GB_CONTROL_ABORT)==TRUE) + { + /* transition are force before sending task command to avoid race condition*/ + sva_GB_UpdateInstanceStateMachine(instanceNum,SVA_GB_CONTROL_ABORT); + /*abort subtask list*/ + tmError=sva_TM_SendTaskCommand(pDesc->subtasksListId,SVA_TM_TCMD_ABORT,param); + HCL_DEBUG_ASSERT(tmError==SVA_TM_OK); + + status = SVA_OK; + } + break; + case SVA_SERVICE_RESET: + if (sva_GB_isTransitionValid(instanceNum,SVA_GB_RESET)==TRUE) + { + /* Decrement grabStartedServiceCnt since we return to SVA_SERVICE_WAIT_FOR_START state */ + HCL_DEBUG_ASSERT(grabStartedServiceCnt != 0); + grabStartedServiceCnt--; + + /*do instance clean-up so service can restart*/ + status = sva_GB_DoReset(serviceId); + if (status == SVA_OK) + { + sva_GB_UpdateInstanceStateMachine(instanceNum,SVA_GB_RESET); + } + } + break; + case SVA_SERVICE_FLUSH_IN: + if (sva_GB_isTransitionValid(instanceNum,SVA_GB_FLUSH_IN)==TRUE) + { + if(pDesc->grabHQEnable == TRUE) + { + /*flush Input buffer if necessary*/ + status = sva_GB_DoFlushIn(serviceId); + if (status == SVA_OK) + { + sva_GB_UpdateInstanceStateMachine(instanceNum,SVA_GB_FLUSH_IN); + /*generate a fake event since flush command is asynchronous*/ + sva_TM_SendTaskCommand(pDesc->subtasksListId,SVA_TM_TCMD_FAKE_EVENT,param); + } + } + else + { + /*no flush of input for grab since there is no input !!!!*/ + status = SVA_UNKNOWN_CMD_ID; + } + } + break; + case SVA_SERVICE_FLUSH_OUT: + if (sva_GB_isTransitionValid(instanceNum,SVA_GB_FLUSH_OUT)==TRUE) + { + /*flush output buffer if necessary*/ + status = sva_GB_DoFlushOut(serviceId); + if (status == SVA_OK) + { + sva_GB_UpdateInstanceStateMachine(instanceNum,SVA_GB_FLUSH_OUT); + /*generate a fake event since flush command is asynchronous*/ + sva_TM_SendTaskCommand(pDesc->subtasksListId,SVA_TM_TCMD_FAKE_EVENT,param); + } + } + break; + /*unknown command*/ + default: + status = SVA_UNKNOWN_CMD_ID; + break; + } + + return status; +} + +/****************************************************************************/ +/* NAME: t_sva_error SVA_UpdatePreProcessorParams( */ +/* t_sva_service_id serviceId, */ +/* t_sva_update_cmd_type updateCmdType, */ +/* t_sva_preprocessor_param_id paramId, */ +/* t_uint32 param */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine allows to update params for an instance of a Grab */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - serviceId: identifier of the given service */ +/* - updateCmdType: command to apply to the GRAB */ +/* - paramd: value of timeStamp */ +/* - param: parameter for the cmdType */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/* - SVA_OK : Command taken into account */ +/* - SVA_UNKNOWN_SERVICE_ID : service id is not correct */ +/* - SVA_UNEXPECTED_API_CALL : Command cannot be excecuted in */ +/* current context. */ +/* - SVA_INTERNAL_PREPROCESSOR_ERROR : internal error */ +/* - SVA_INCOHERENT_CONFIGURATION:bad config param or command */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + TO DO : + - Management of ace offset ? + - need to add an error of type configuration on-going +*/ +PUBLIC t_sva_error SVA_UpdatePreProcessorParams( + t_sva_service_id serviceId, + t_sva_update_cmd_type updateCmdType, + t_sva_preprocessor_param_id paramId, + t_uint32 param + ) +{ + t_sva_service_instance_num instanceNum = READ_INSTANCE_NUM_IN_SERVICE_ID(serviceId); + t_sva_gb_descriptor *pDesc=&grabDesc[instanceNum]; + t_sva_preprocessor_configuration *pNextConf=&pDesc->confHandle.nextConf; + t_sva_preprocessor_configuration *pConf=&pDesc->confHandle.currentConf; + t_sva_tm_error tmError; + t_sva_error status; + + + /*check for service id validity*/ + status=sva_GB_CheckServiceId(serviceId); + if (status!=SVA_OK) {return status;} + + /*check that transition is allowed*/ + if (sva_GB_isTransitionValid(instanceNum,SVA_GB_UPDATE_PARAM)==FALSE) {return SVA_UNEXPECTED_API_CALL;} + + /*special case of irp mode*/ + if (pDesc->isIrpMode == TRUE) + { + /* handle SVA_PREPROCESSOR_PACKET_WRITE and SVA_PREPROCESSOR_PACKET_READ paramId*/ + if (paramId == SVA_PREPROCESSOR_PACKET_WRITE || + paramId == SVA_PREPROCESSOR_PACKET_READ) + { + t_sva_mm_error mmError; + t_sva_packet *pPacket = (t_sva_packet *) param; + t_sva_gb_packet *pIrpPacket; + t_physical_address irpPacketPhysicalAddress; + + /* check that no r/w packet is currently ongoing */ + if (isPacketOnGoing == TRUE) {return SVA_CONFIGURATION_IN_PROGRESS;} + + /* fill packet structure */ + mmError = sva_MM_GetBlockLogicalAddress(pDesc->irpPacketId, (t_logical_address *) &pIrpPacket); + if (mmError != SVA_MM_OK) {return SVA_INTERNAL_PREPROCESSOR_ERROR;} + mmError = sva_MM_GetBlockPhysicalAddress(pDesc->irpPacketId, &irpPacketPhysicalAddress); + if (mmError != SVA_MM_OK) {return SVA_INTERNAL_PREPROCESSOR_ERROR;} + pIrpPacket->payloadSize = SVA_GB_PACKET_PAYLOAD_SIZE; + pIrpPacket->address = pPacket->address; + pIrpPacket->value = pPacket->value; + + /*flag a packet transmission on going*/ + /*NOTE : done before sva_TM_SendTaskCommand. Not necessary done before as*/ + /* code is not reentrant. But grab testes supposed a 'minimum' reentrancy for */ + /* this point .... */ + isPacketOnGoing = TRUE; + + /* start a r/w packet */ + if (paramId == SVA_PREPROCESSOR_PACKET_READ) + { + tmError=sva_TM_SendTaskCommand(pDesc->subtasksListId,SVA_TM_TCMD_READ_PACKET,irpPacketPhysicalAddress); + } + else + { + tmError=sva_TM_SendTaskCommand(pDesc->subtasksListId,SVA_TM_TCMD_WRITE_PACKET,irpPacketPhysicalAddress); + } + if (tmError != SVA_TM_OK) + { + isPacketOnGoing = FALSE; + return SVA_INTERNAL_PREPROCESSOR_ERROR; + } + + /*update state machine => do nothing*/ + sva_GB_UpdateInstanceStateMachine(instanceNum,SVA_GB_UPDATE_PARAM); + + return status; + } + else if (paramId == SVA_PREPROCESSOR_HQ_STATUS_READ)//HQ Grab status + { + tmError=sva_TM_SendTaskCommand(pDesc->subtasksListId,SVA_TM_TCMD_GRABHQ_STATUS,param); + if(tmError != SVA_TM_OK) + { + return SVA_INTERNAL_PREPROCESSOR_ERROR; + } + else + { + return SVA_OK; + } + } + else if (paramId == SVA_PREPROCESSOR_HQ_STATUS_TST) + { + tmError=sva_TM_SendTaskCommand(pDesc->subtasksListId,SVA_TM_TCMD_GRABHQ_TST,param); + if(tmError != SVA_TM_OK) + { + return SVA_INTERNAL_PREPROCESSOR_ERROR; + } + else + { + return SVA_OK; + } + } + else if (paramId == SVA_PREPROCESSOR_HQ_READ_NB_FAILURE_BML_PROCESS) /* Read status of BML retries made for a BML process */ + { + tmError=sva_TM_SendTaskCommand(pDesc->subtasksListId,SVA_TM_TCMD_GRABHQ_READ_NB_FAILURE_BML_PROCESS,param); + if(tmError != SVA_TM_OK) + { + return SVA_INTERNAL_PREPROCESSOR_ERROR; + } + else + { + return SVA_OK; + } + } + else //Do nothing + { + } + } + else + { + /* Not in IRP mode, don't support PACKET_WRITE or PACKET_READ */ + if (paramId == SVA_PREPROCESSOR_PACKET_WRITE || + paramId == SVA_PREPROCESSOR_PACKET_READ) + {return SVA_INCOHERENT_CONFIGURATION;} + } + + /*check that a configuration is not currently on going*/ + //if (pDesc->confHandle.confState!=SVA_GB_NO_CONF_CHANGE_NEED) {return SVA_CONFIGURATION_IN_PROGRESS;} + + /*take command into account for next configuration*/ + switch(paramId) + { + case SVA_PREPROCESSOR_CROPPING: + pNextConf->sourceFrameDesc.window=*((t_sva_window_desc *) param); + break; + case SVA_PREPROCESSOR_RESIZE: + pNextConf->resizedWindowDesc=*((t_sva_image_desc *) param); + break; + case SVA_PREPROCESSOR_GRAB_LINE_NUMBER_SYNC: + pNextConf->grabSyncLine=param; + break; + /* + * dynamic activate / deactivate of ace is no more supported. This is due + * to the fact that some firmware may or may not support ACE. + */ + /*case SVA_PREPROCESSOR_ACE_ENABLE: + pNextConf->isAceEnable=(t_bool) param; + break;*/ + case SVA_PREPROCESSOR_ACE_STRENGTH: + pNextConf->aceStrength=(t_sva_ace_strength) param; + break; + case SVA_PREPROCESSOR_ACE_RANGE: + pNextConf->aceRange=(t_sva_color_range) param; + break; + case SVA_PREPROCESSOR_OUTPUT_RANGE: + pNextConf->outputRange=(t_sva_color_range) param; + break; + case SVA_PREPROCESSOR_ACE_OFFSET: + pDesc->confHandle.isAceOffsetNeedUpdate=TRUE; + pDesc->confHandle.newAceOffset=*((t_sva_ace_offset *) param); + break; + case SVA_PREPROCESSOR_HQ_PREPROC: + { + t_sva_preprocessor_grabhq_configuration *grabhq_new_config = (t_sva_preprocessor_grabhq_configuration *) param; + pNextConf->grabhqConfig.castCool = grabhq_new_config->castCool; + pNextConf->grabhqConfig.castDay = grabhq_new_config->castDay; + pNextConf->grabhqConfig.castHorizon = grabhq_new_config->castHorizon; + pNextConf->grabhqConfig.castInc = grabhq_new_config->castInc; + pNextConf->grabhqConfig.gridHSize = grabhq_new_config->gridHSize; + pNextConf->grabhqConfig.isChannelOffsetEnabled = grabhq_new_config->isChannelOffsetEnabled; + pNextConf->grabhqConfig.isGridironEnabled = grabhq_new_config->isGridironEnabled; + pNextConf->grabhqConfig.isScorpioEnabled = grabhq_new_config->isScorpioEnabled; + pNextConf->grabhqConfig.scorpioStrength = grabhq_new_config->scorpioStrength; + + pNextConf->grabhqConfig.bmlClockDivisor = grabhq_new_config->bmlClockDivisor; + pNextConf->grabhqConfig.nbMaxBmlRetiesOnFailure = grabhq_new_config->nbMaxBmlRetiesOnFailure; + } + default: + break; + } + + /*take into account updateCmdType*/ + switch(updateCmdType) + { + case SVA_UPDATE_MULTIPLE: + /*nothing to do*/ + break; + case SVA_UPDATE_LAST: + /*check new configuration is valid*/ + if (sva_GB_IsConfigurationValid(&pDesc->confHandle.nextConf)==FALSE) {return SVA_INCOHERENT_CONFIGURATION;} + /*change conf state according to type of change*/ + if (sva_GB_isChangeConfIsImmediate(&pDesc->confHandle.currentConf,&pDesc->confHandle.nextConf)==TRUE) + { + *pConf=*pNextConf; + pDesc->confHandle.currentConfCounter++; + pDesc->confHandle.confState=SVA_GB_IMMEDIATE_CONF_CHANGE_NEED; + status=SVA_IMMEDIATE_UPDATE; + } + else + { + /*in grab case this is not necessary since we reveive only one buffer type + but we do it this way anyway so it serve as an example. + */ + pDesc->confHandle.bufferType=SVA_IMAGE_BUFFER_TYPE; + pDesc->confHandle.pushMode=SVA_PUSH_OUT; + pDesc->confHandle.confState=SVA_GB_WAIT_FOR_BUFFER; + status=SVA_DELAYED_UPDATE; + } + break; + case SVA_UPDATE_REVERT: + /*cancel previously param update*/ + *pNextConf=*pConf; + pDesc->confHandle.isAceOffsetNeedUpdate=FALSE; + break; + default: + break; + } + + /*update state machine => do nothing*/ + sva_GB_UpdateInstanceStateMachine(instanceNum,SVA_GB_UPDATE_PARAM); + + return status; +} + +/****************************************************************************/ +/* NAME: t_sva_error sva_GB_Push ( */ +/* t_sva_service_id serviceId, */ +/* t_sva_buffer_id bufferId, */ +/* t_sva_push_mode pushMode, */ +/* t_sva_buffer_type bufferType, */ +/* t_sva_timestamp timeStamp */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine allows to push data in a Grab service */ +/* - it will check buffer has enought size according to conf */ +/* - it will push it in the corresponding pushFifo fifo */ +/* - update status of buffer */ +/* - try to solve some dependencies */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - serviceId: identifier of the service */ +/* - bufferId: identifier of the buffer */ +/* - pushMode: PUSH_IN/PUSH_OUT */ +/* - bufferType: */ +/* - timeStamp: */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/* - SVA_OK : Command taken into account */ +/* - SVA_UNKNOWN_SERVICE_ID : service id is not correct */ +/* - SVA_UNEXPECTED_API_CALL : Command cannot be excecuted in */ +/* current context. */ +/* - SVA_INTERNAL_PREPROCESSOR_ERROR : internal error */ +/* - SVA_INVALID_BUFFER_TYPE : buffer type is not handle by grab */ +/* - SVA_INTERNAL_FIFOS_FULL : internal fifos are full */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + DONE +*/ +PUBLIC t_sva_error sva_GB_Push( + t_sva_service_id serviceId, + t_sva_buffer_id bufferId, + t_sva_push_mode pushMode, + t_sva_buffer_type bufferType, + t_sva_timestamp timeStamp +) +{ + t_sva_service_instance_num instanceNum = READ_INSTANCE_NUM_IN_SERVICE_ID(serviceId); + t_sva_gb_descriptor *pDesc=&grabDesc[instanceNum]; + t_sva_preprocessor_configuration *pConf=&pDesc->confHandle.currentConf; + t_sva_error status; + t_sva_bm_error bmError; + t_sva_ff_error ffError; + t_sva_gb_error gbError; + t_size bufferSize; + t_size minSize=0; + + (void) timeStamp; + /*check for service id validity*/ + status=sva_GB_CheckServiceId(serviceId); + if (status!=SVA_OK) {return status;} + + /*check that transition is allowed*/ + if (sva_GB_isTransitionValid(instanceNum,SVA_GB_PUSH)==FALSE) {return SVA_UNEXPECTED_API_CALL;} + + /*check if a configuration change can occur on this buffer*/ + sva_GB_ConfigurationChangeOnPush(serviceId,bufferType,pushMode,bufferId); + + /*handle provide buffer*/ + switch(bufferType) + { + case SVA_IMAGE_BUFFER_TYPE: + if (pushMode != SVA_PUSH_OUT) return SVA_UNEXPECTED_API_CALL; + /*compute minimum size of buffer according to current configuration*/ + if (pConf->transformId==SVA_PREPROCESSOR_YUV420_MB || + pConf->transformId==SVA_PREPROCESSOR_SENSOR_YUV420_MB || pConf->transformId==SVA_PREPROCESSOR_SENSOR_HIGHQUALITY_YUV420_MB) + { + /*This check is for GRABHQ. since there are two image buffers*/ + /*This is forcing the user to push output images in sequence*/ + if(pDesc->imageBuffDepToBeResolved == SVA_GRAB_OUT_BUFF_DEP_TO_BE_RESOLVED) + { + if (pConf->isInputInterlaced == TRUE && pConf->isOutputFrame == TRUE) + { + /*in that case user has to provide and output buffer big enought to handle both field*/ + minSize=(((t_uint32)pConf->resizedWindowDesc.height*(t_uint32)pConf->resizedWindowDesc.width)*3); + } + else /* SVA_GRAB_SNAP_BUFF_DEP_TO_BE_RESOLVED */ + { + minSize=(((t_uint32)pConf->resizedWindowDesc.height*(t_uint32)pConf->resizedWindowDesc.width)*3)/2; + } + } + else /* SVA_GRAB_SNAP_BUFF_DEP_TO_BE_RESOLVED */ + { + minSize=(((t_uint32)pConf->snapshotImageDesc.height*(t_uint32)pConf->snapshotImageDesc.width)*3)/2; + } + } + else if (pConf->transformId==SVA_PREPROCESSOR_YUV420_SEP_COMP_MB || + pConf->transformId==SVA_PREPROCESSOR_SENSOR_YUV420_SEP_COMP_MB) + { + + minSize=(t_uint32)(pConf->resizedWindowDesc.height*pConf->resizedWindowDesc.width+ + ((pConf->resizedWindowDesc.width/2+8)&0xff0)*((pConf->resizedWindowDesc.height/2+8)&0xff0)*2); + } + else if (pConf->transformId==SVA_PREPROCESSOR_YUV422_SEP_COMP_MB || + pConf->transformId==SVA_PREPROCESSOR_SENSOR_YUV422_SEP_COMP_MB) + { + minSize=(t_uint32)(pConf->resizedWindowDesc.height*pConf->resizedWindowDesc.width+ + ((pConf->resizedWindowDesc.width/2+8)&0xff0)*pConf->resizedWindowDesc.height*2); + } + else {;} + /*read buffer size*/ + bmError=sva_BM_GetBufferSize(bufferId,&bufferSize); + if (bmError!=SVA_BM_OK) {return SVA_INTERNAL_PREPROCESSOR_ERROR;} + /*check buffer has enought space*/ + if (bufferSize>=minSize) + { + if(pDesc->imageBuffDepToBeResolved == SVA_GRAB_OUT_BUFF_DEP_TO_BE_RESOLVED) + { + ffError=PUSH_FIFO_ELEM(pDesc->outputImageFifos.pushFifo, t_sva_buffer_id, bufferId); + /* In case of interlace mode with frame output we push buffer twice */ + if (pConf->isInputInterlaced == TRUE && pConf->isOutputFrame == TRUE) + { + ffError=PUSH_FIFO_ELEM(pDesc->outputImageFifos.pushFifo, t_sva_buffer_id, bufferId); + } + if (ffError!=SVA_FIFO_OK) {status=SVA_INTERNAL_FIFOS_FULL;} + else {status=SVA_OK;} + if(pConf->transformId == SVA_PREPROCESSOR_SENSOR_HIGHQUALITY_YUV420_MB) + { + pDesc->imageBuffDepToBeResolved = SVA_GRAB_SNAP_BUFF_DEP_TO_BE_RESOLVED; + } + } + else /* SVA_GRAB_SNAP_BUFF_DEP_TO_BE_RESOLVED */ + { + if(pConf->transformId == SVA_PREPROCESSOR_SENSOR_HIGHQUALITY_YUV420_MB) + { + pDesc->imageBuffDepToBeResolved = SVA_GRAB_OUT_BUFF_DEP_TO_BE_RESOLVED; + } + else + { + return SVA_UNEXPECTED_API_CALL; + } + ffError=PUSH_FIFO_ELEM(pDesc->snapshotImageFifos.pushFifo, t_sva_buffer_id, bufferId); + if (ffError!=SVA_FIFO_OK) {status=SVA_INTERNAL_FIFOS_FULL;} + else {status=SVA_OK;} + + } + } + else {status=SVA_INTERNAL_PREPROCESSOR_ERROR;} + break; + case SVA_PARAMS_BUFFER_TYPE: + if (pushMode != SVA_PUSH_IN) return SVA_UNEXPECTED_API_CALL; + if (pConf->grabhqConfig.isGridironEnabled==FALSE) + { + return SVA_UNEXPECTED_API_CALL; + } + /*compute minimum size of buffer according to current configuration*/ + if (pConf->transformId==SVA_PREPROCESSOR_SENSOR_HIGHQUALITY_YUV420_MB) + { + minSize = SVA_GRID_BUFFER_MIN_SIZE; //For 3MP, size calculation method not provided for other sizes + } + /*read buffer size*/ + bmError=sva_BM_GetBufferSize(bufferId,&bufferSize); + if (bmError!=SVA_BM_OK) {return SVA_INTERNAL_PREPROCESSOR_ERROR;} + /*check buffer has enought space*/ + if (bufferSize>=minSize) + { + ffError=PUSH_FIFO_ELEM(pDesc->paramFifos.pushFifo, t_sva_buffer_id, bufferId); + if (ffError!=SVA_FIFO_OK) {status=SVA_INTERNAL_FIFOS_FULL;} + else {status=SVA_OK;} + } + else {status=SVA_INTERNAL_PREPROCESSOR_ERROR;} + break; + default: + status=SVA_INVALID_BUFFER_TYPE; + break; + } + + /*update state machine*/ + sva_GB_UpdateInstanceStateMachine(instanceNum,SVA_GB_PUSH); + + /*update buffer status if we have succeeded to push it and try to solve dependencies*/ + if (status == SVA_OK) + { + t_uint32 systemTime; + t_sva_error svaError; + + svaError=SVA_GetServiceSystemTime(serviceId,&systemTime); + if (svaError!=SVA_OK) {return SVA_INTERNAL_PREPROCESSOR_ERROR;} + bmError=sva_BM_UpdateBufferStatus(bufferId, SVA_BUFFER_IN_USE, systemTime); + if (bmError!=SVA_BM_OK) {return SVA_INTERNAL_PREPROCESSOR_ERROR;} + gbError=sva_GB_ResolveDependencies(instanceNum); + if (gbError!=SVA_GB_OK) {return SVA_INTERNAL_PREPROCESSOR_ERROR;} + } + + return status; +} + +/****************************************************************************/ +/* NAME: t_sva_error SVA_GetPreProcessorStatus ( */ +/* t_sva_service_id serviceId, */ +/* t_sva_preprocessor_status * pStatus */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine allows to get status of the Grab service */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - serviceId: identifier of the service */ +/* - pStatus: status for the grab service */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/* - SVA_OK : Command taken into account */ +/* - SVA_UNKNOWN_SERVICE_ID : service id is not correct */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + DONE +*/ +PUBLIC t_sva_error SVA_GetPreProcessorStatus( + t_sva_service_id serviceId, + t_sva_preprocessor_status *pStatus +) +{ + t_sva_service_instance_num instanceNum = READ_INSTANCE_NUM_IN_SERVICE_ID(serviceId); + t_sva_gb_descriptor *pDesc=&grabDesc[instanceNum]; + t_sva_preprocessor_configuration *pConf=&pDesc->confHandle.currentConf; + t_sva_error status; + + GB_CHECK_NULL_POINTER(pStatus); + + /*check for service id validity*/ + status=sva_GB_CheckServiceId(serviceId); + if (status!=SVA_OK) {return status;} + + /*copy status*/ + *pStatus=pDesc->status; + /*set correct value for fifo fullness*/ + pStatus->bufferizationStats.outLevel=GET_FIFO_NB_ELEMS(pDesc->outputImageFifos.pushFifo); + if (pConf->isInputInterlaced == TRUE) + { + pStatus->bufferizationStats.outLevel = pStatus->bufferizationStats.outLevel / 2; + } + + return SVA_OK; +} + +/****************************************************************************/ +/* NAME: t_sva_gb_error sva_GB_DispatchVirtualHwEvent( */ +/* t_sva_virtual_hw_event_id eventId, */ +/* t_sva_service_id serviceId, */ +/* t_sva_tm_subtask_id subtaskId, */ +/* t_uint32 eventTimestamp, */ +/* t_uint32 eventDate, */ +/* t_uint8 maxOfEvent, */ +/* t_sva_event_desc *pEventDesc, */ +/* t_uint32 *pNbEvent */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine allows to dispatch event of the Grab service */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - eventId: event identifier */ +/* - serviceId: identifier of the service */ +/* - subtaskId: identifier of the subtask for which is the event */ +/* - eventTimestamp: time at which the event occur (system time unit) */ +/* - eventDate: time at which the event occur (ticks time unit) */ +/* - maxOfEvent: nb of event max contained in EventDesc */ +/* - pEventDesc: structure of Events */ +/* - pNbEvent: nb of event into EventDesc */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_gb_error */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + +*/ + +/*@BORT-$TOP*/ +/*REMOVE IT FROM ERR*/ +/*add sva_GB_UpdateInstanceStateMachine(instanceNum,SVA_GB_EVENT_ABORT); + + CHECK_TABLE_OVERFLOW(nbEventsRaised, maxOfEvent, SVA_GB_NOT_SUPPORTED); + pEventDesc[nbEventsRaised].eventId = SVA_EVENT_SERVICE_ERROR; + pEventDesc[nbEventsRaised].serviceId = serviceId; + pEventDesc[nbEventsRaised].bufferId = INVALID_BUFFER_ID; + pEventDesc[nbEventsRaised].eventTimestamp = (t_sva_timestamp_value) eventTimestamp; + pEventDesc[nbEventsRaised].eventDate = (t_sva_timestamp_value) eventDate; +*/ +/*@BORT-$TOP*/ +PUBLIC t_sva_gb_error sva_GB_DispatchVirtualHwEvent( + t_sva_tm_virtual_hw_event_id eventId, + t_sva_service_id serviceId, + t_sva_tm_subtask_id subtaskId, + t_uint32 eventTimestamp, + t_uint32 eventDate, + t_uint8 maxOfEvent, + t_sva_event_desc *pEventDesc, + t_uint32 *pNbEvent +) +{ + t_sva_service_instance_num instanceNum = READ_INSTANCE_NUM_IN_SERVICE_ID(serviceId); + t_sva_gb_descriptor *pDesc=&grabDesc[instanceNum]; + t_sva_preprocessor_configuration *pConf=&pDesc->confHandle.currentConf; + t_sva_grb_param_out paramOut; + ts_t1xhv_grb_param_inout paramInOut; + t_sva_gb_subtask_dependencies subtaskDep; + t_sva_tm_error tmError; + t_sva_ff_error ffError; + t_sva_error status; + t_bool isUpdateStateNeed=FALSE; + t_uint32 nbEventsRaised = 0; + + GB_CHECK_NULL_POINTER(pEventDesc); + GB_CHECK_NULL_POINTER(pNbEvent); + + (void) maxOfEvent; + *pNbEvent=0; + + /*check for service id validity*/ + status=sva_GB_CheckServiceId(serviceId); + if (status!=SVA_OK) {return SVA_GB_INVALID_INSTANCE_NB;} + + /*check pointers*/ + GB_CHECK_NULL_POINTER(pEventDesc); + GB_CHECK_NULL_POINTER(pNbEvent); + +#ifdef __DEBUG + eventGrabDebugTable[instanceNum].eventDebugDesc[eventGrabDebugTable[instanceNum].nbOfEventReceived%LOG_DEPTH].event=eventId; + eventGrabDebugTable[instanceNum].eventDebugDesc[eventGrabDebugTable[instanceNum].nbOfEventReceived%LOG_DEPTH].systemTime=eventTimestamp; + eventGrabDebugTable[instanceNum].eventDebugDesc[eventGrabDebugTable[instanceNum].nbOfEventReceived%LOG_DEPTH].subtaskId=subtaskId; + eventGrabDebugTable[instanceNum].eventDebugDesc[eventGrabDebugTable[instanceNum].nbOfEventReceived%LOG_DEPTH].serviceId=serviceId; + eventGrabDebugTable[instanceNum].nbOfEventReceived++; +#endif + + switch(eventId) + { + case SVA_TM_EOT_HW_EVENT: + //printf("\n SVA_TM_EOT_HW_EVENT"); + /* A grab subtask has just finish. We now have to do the following : + * 1) Change buffer state to filled. + * 2) Filled event for user. + * 3) Update status descriptor + * 4) repush subtask. + */ + /*read param out*/ + tmError=sva_TM_GetSubTaskField(subtaskId, SVA_TM_GRB_ADDR_OUT_PARAMETERS,(t_logical_address) ¶mOut, + 0, sizeof(t_sva_grb_param_out), FALSE); + HCL_DEBUG_ASSERT(tmError==SVA_TM_OK); + /*read out param out*/ + tmError=sva_TM_GetSubTaskField(subtaskId, SVA_TM_GRB_ADDR_OUT_FRAME_PARAMETERS,(t_logical_address) ¶mInOut, + 0, sizeof(ts_t1xhv_grb_param_inout), FALSE); + HCL_DEBUG_ASSERT(tmError==SVA_TM_OK); + + /* First Generate Voided events for Grid buffers for GrabHQ service only and GridIron enabled */ + if ((pConf->transformId == SVA_PREPROCESSOR_SENSOR_HIGHQUALITY_YUV420_MB) && (pConf->grabhqConfig.isGridironEnabled == TRUE)) + { + /* Gives a single Void event for all the buffer */ + while(IS_FIFO_EMPTY(pDesc->paramFifos.inUseFifo) == FALSE) + { + /* fill user event */ + CHECK_TABLE_OVERFLOW(nbEventsRaised, maxOfEvent, SVA_GB_NOT_SUPPORTED); + pEventDesc[nbEventsRaised].eventId = SVA_EVENT_BUFFER_VOIDED; + pEventDesc[nbEventsRaised].serviceId = serviceId; + pEventDesc[nbEventsRaised].eventTimestamp = (t_sva_timestamp_value) eventTimestamp; + pEventDesc[nbEventsRaised].eventDate = (t_sva_timestamp_value) eventDate; + pEventDesc[nbEventsRaised].extraInfo = sva_TI_ConvertTicksToSystemTime(serviceId,(t_sva_ticks) paramOut.time_stamp); + pEventDesc[nbEventsRaised].extraInfo2 = 1; //Not used + + ffError = POP_FIFO_ELEM(pDesc->paramFifos.inUseFifo,t_sva_buffer_id,pEventDesc[nbEventsRaised].bufferId); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + + /* update buffer status */ + sva_BM_UpdateBufferStatus(pEventDesc[nbEventsRaised].bufferId,SVA_BUFFER_VOIDED,eventTimestamp); + nbEventsRaised++; + pDesc->status.eventStats.voidedCounter++; + } + } + + /* + * fill event is NOT sent when we are in interlace and that output + * is a frame and field 0 has been grabbed since 2 subtasks are + * use to retriewe an entire frame (field0 + field1). + * In any case buffer has to be pop from the push fifo. + */ + ffError=POP_FIFO_ELEM(pDesc->outputImageFifos.inUseFifo,t_sva_buffer_id,pEventDesc[nbEventsRaised].bufferId); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + if (pConf->isInputInterlaced == FALSE || pConf->isOutputFrame == FALSE || paramOut.field_number == 1) + { + /*fill user event*/ + CHECK_TABLE_OVERFLOW(nbEventsRaised, maxOfEvent, SVA_GB_NOT_SUPPORTED); + pEventDesc[nbEventsRaised].eventId = SVA_EVENT_BUFFER_FILLED; + pEventDesc[nbEventsRaised].serviceId = serviceId; + pEventDesc[nbEventsRaised].eventTimestamp = (t_sva_timestamp_value) eventTimestamp; + pEventDesc[nbEventsRaised].eventDate = (t_sva_timestamp_value) eventDate; + pEventDesc[nbEventsRaised].extraInfo = sva_TI_ConvertTicksToSystemTime(serviceId,(t_sva_ticks) paramOut.time_stamp); + pEventDesc[nbEventsRaised].extraInfo2 = paramOut.field_number; + + /*update buffer status*/ + sva_BM_UpdateBufferStatus(pEventDesc[nbEventsRaised].bufferId,SVA_BUFFER_FILLED,eventTimestamp); + nbEventsRaised++; + + pDesc->status.eventStats.filledCounter++; + } + + /*update status descriptor*/ + + pDesc->status.isAceEnable=pDesc->confHandle.currentConf.isAceEnable; + pDesc->status.aceOffset.ace_offset_0=paramInOut.ace_offset0; + pDesc->status.aceOffset.ace_offset_1=paramInOut.ace_offset1; + pDesc->status.aceOffset.ace_offset_2=paramInOut.ace_offset2; + pDesc->status.aceOffset.ace_offset_3=paramInOut.ace_offset3; + pDesc->status.nbGrabbedImage++; + + /*repush subtask with default dependencies so it can be programmed and then re-excecuted*/ + subtaskDep.subtaskId = subtaskId; + subtaskDep.dependencies = pDesc->defaultDep; + ffError=PUSH_FIFO_ELEM(pDesc->subtasksDependencyFifo,t_sva_gb_subtask_dependencies,subtaskDep); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + break; + case SVA_TM_BOF_HW_EVENT: + + if (pConf->transformId == SVA_PREPROCESSOR_SENSOR_HIGHQUALITY_YUV420_MB) + { + ffError=POP_FIFO_ELEM(pDesc->snapshotImageFifos.inUseFifo,t_sva_buffer_id,pEventDesc[nbEventsRaised].bufferId); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + /*fill user event*/ + CHECK_TABLE_OVERFLOW(nbEventsRaised, maxOfEvent, SVA_GB_NOT_SUPPORTED); + pEventDesc[nbEventsRaised].eventId = SVA_EVENT_BUFFER_FILLED; + pEventDesc[nbEventsRaised].serviceId = serviceId; + pEventDesc[nbEventsRaised].eventTimestamp = (t_sva_timestamp_value) eventTimestamp; + pEventDesc[nbEventsRaised].eventDate = (t_sva_timestamp_value) eventDate; + pEventDesc[nbEventsRaised].extraInfo = 1; //Not used + pEventDesc[nbEventsRaised].extraInfo2 = 1; //Not used + + /*update buffer status*/ + sva_BM_UpdateBufferStatus(pEventDesc[nbEventsRaised].bufferId,SVA_BUFFER_FILLED,eventTimestamp); + nbEventsRaised++; + + pDesc->status.eventStats.filledCounter++; + + } + break; + case SVA_TM_EOK_HW_EVENT: + //printf("\n SVA_TM_EOK_HW_EVENT"); + /* We can reveive an EOK for the three following reason : + * 1) no more subtask scheduled => OVERFLOW event + * 2) a stop has been requested + * 3) an abort has been requested + * Note than reason 1 can arrive at the same time as 2 or 3 + + */ + isUpdateStateNeed=FALSE; + if (pDesc->state==SVA_GB_STOP_REQUESTED) + { + /* Decrement grabStartedServiceCnt since we return to SVA_SERVICE_WAIT_FOR_START state */ + HCL_DEBUG_ASSERT(grabStartedServiceCnt != 0); + grabStartedServiceCnt--; + + /*generate a stop event*/ + CHECK_TABLE_OVERFLOW(nbEventsRaised, maxOfEvent, SVA_GB_NOT_SUPPORTED); + pEventDesc[nbEventsRaised].eventId = SVA_EVENT_SERVICE_STOPPED; + pEventDesc[nbEventsRaised].serviceId = serviceId; + pEventDesc[nbEventsRaised].bufferId = INVALID_BUFFER_ID; + pEventDesc[nbEventsRaised].eventTimestamp = (t_sva_timestamp_value) eventTimestamp; + pEventDesc[nbEventsRaised].eventDate = (t_sva_timestamp_value) eventDate; + pEventDesc[nbEventsRaised].extraInfo=0; + nbEventsRaised++; + /*update state*/ + isUpdateStateNeed=TRUE; + } + if (pDesc->state==SVA_GB_ABORT_REQUESTED) + { + CHECK_TABLE_OVERFLOW(nbEventsRaised, maxOfEvent, SVA_GB_NOT_SUPPORTED); + pEventDesc[nbEventsRaised].eventId = SVA_EVENT_SERVICE_ERROR; + pEventDesc[nbEventsRaised].serviceId = serviceId; + pEventDesc[nbEventsRaised].bufferId = INVALID_BUFFER_ID; + pEventDesc[nbEventsRaised].eventTimestamp = (t_sva_timestamp_value) eventTimestamp; + pEventDesc[nbEventsRaised].eventDate = (t_sva_timestamp_value) eventDate; + pEventDesc[nbEventsRaised].extraInfo = 0; + pEventDesc[nbEventsRaised].extraInfo2 = 0; + nbEventsRaised++; + pDesc->status.eventStats.errorCounter++; + + /*update state machine*/ + sva_GB_UpdateInstanceStateMachine(instanceNum,SVA_GB_EVENT_ERROR); + } + + if (GET_FIFO_NB_ELEMS(pDesc->subtasksDependencyFifo)==SUBTASK_GRAB_NUMBER) + { + /*generate an overflow*/ + CHECK_TABLE_OVERFLOW(nbEventsRaised, maxOfEvent, SVA_GB_NOT_SUPPORTED); + pEventDesc[nbEventsRaised].eventId = SVA_EVENT_OVERFLOW; + pEventDesc[nbEventsRaised].serviceId = serviceId; + pEventDesc[nbEventsRaised].bufferId = INVALID_BUFFER_ID; + pEventDesc[nbEventsRaised].eventTimestamp = (t_sva_timestamp_value) eventTimestamp; + pEventDesc[nbEventsRaised].eventDate = (t_sva_timestamp_value) eventDate; + pEventDesc[nbEventsRaised].extraInfo=0; + nbEventsRaised++; + /*update status*/ + pDesc->status.eventStats.overflowCounter++; + /*update state*/ + isUpdateStateNeed=TRUE; + } + if (isUpdateStateNeed==TRUE) + { + /*update state*/ + sva_GB_UpdateInstanceStateMachine(instanceNum,SVA_GB_EVENT_EOK); + } + break; + case SVA_TM_FAKE_HW_EVENT: + //printf("\n SVA_TM_FAKE_HW_EVENT"); + /*add flush event*/ + if(pDesc->state == SVA_GB_FLUSHING_IN) + { + CHECK_TABLE_OVERFLOW(nbEventsRaised, maxOfEvent, SVA_GB_NOT_SUPPORTED); + pEventDesc[nbEventsRaised].eventId = SVA_EVENT_SERVICE_FLUSHED_IN; + pEventDesc[nbEventsRaised].serviceId = serviceId; + pEventDesc[nbEventsRaised].bufferId = INVALID_BUFFER_ID; + pEventDesc[nbEventsRaised].eventTimestamp = (t_sva_timestamp_value) eventTimestamp; + pEventDesc[nbEventsRaised].eventDate = (t_sva_timestamp_value) eventDate; + pEventDesc[nbEventsRaised].extraInfo=0; + nbEventsRaised++; + } + else if(pDesc->state == SVA_GB_FLUSHING_OUT) + { + CHECK_TABLE_OVERFLOW(nbEventsRaised, maxOfEvent, SVA_GB_NOT_SUPPORTED); + pEventDesc[nbEventsRaised].eventId = SVA_EVENT_SERVICE_FLUSHED_OUT; + pEventDesc[nbEventsRaised].serviceId = serviceId; + pEventDesc[nbEventsRaised].bufferId = INVALID_BUFFER_ID; + pEventDesc[nbEventsRaised].eventTimestamp = (t_sva_timestamp_value) eventTimestamp; + pEventDesc[nbEventsRaised].eventDate = (t_sva_timestamp_value) eventDate; + pEventDesc[nbEventsRaised].extraInfo=0; + nbEventsRaised++; + } + + /*update state machine*/ + sva_GB_UpdateInstanceStateMachine(instanceNum,SVA_GB_EVENT_FAKE); + break; + case SVA_TM_ACTIVE_HW_EVENT: + //printf("\n SVA_TM_ACTIVE_HW_EVENT"); + /*add activate event*/ + CHECK_TABLE_OVERFLOW(nbEventsRaised, maxOfEvent, SVA_GB_NOT_SUPPORTED); + pEventDesc[nbEventsRaised].eventId = SVA_EVENT_SERVICE_ACTIVATED; + pEventDesc[nbEventsRaised].serviceId = serviceId; + pEventDesc[nbEventsRaised].bufferId = INVALID_BUFFER_ID; + pEventDesc[nbEventsRaised].eventTimestamp = (t_sva_timestamp_value) eventTimestamp; + pEventDesc[nbEventsRaised].eventDate = (t_sva_timestamp_value) eventDate; + pEventDesc[nbEventsRaised].extraInfo=0; + nbEventsRaised++; + /*update state machine*/ + sva_GB_UpdateInstanceStateMachine(instanceNum,SVA_GB_EVENT_ACTIVE); + break; + case SVA_TM_INACTIVE_HW_EVENT: + //printf("\n SVA_TM_INACTIVE_HW_EVENT"); + /*add inactivate event*/ + CHECK_TABLE_OVERFLOW(nbEventsRaised, maxOfEvent, SVA_GB_NOT_SUPPORTED); + pEventDesc[nbEventsRaised].eventId = SVA_EVENT_SERVICE_INACTIVATED; + pEventDesc[nbEventsRaised].serviceId = serviceId; + pEventDesc[nbEventsRaised].bufferId = INVALID_BUFFER_ID; + pEventDesc[nbEventsRaised].eventTimestamp = (t_sva_timestamp_value) eventTimestamp; + pEventDesc[nbEventsRaised].eventDate = (t_sva_timestamp_value) eventDate; + pEventDesc[nbEventsRaised].extraInfo=0; + nbEventsRaised++; + /*update state machine*/ + sva_GB_UpdateInstanceStateMachine(instanceNum,SVA_GB_EVENT_INACTIVE); + break; + case SVA_TM_ERR_HW_EVENT: + //printf("\n SVA_TM_ERR_HW_EVENT"); + /*read param out*/ + tmError=sva_TM_GetSubTaskField(subtaskId, SVA_TM_GRB_ADDR_OUT_PARAMETERS,(t_logical_address) ¶mOut, + 0, sizeof(t_sva_grb_param_out), FALSE); + HCL_DEBUG_ASSERT(tmError==SVA_TM_OK); + + /* Decrement grabStartedServiceCnt since we return to SVA_SERVICE_WAIT_FOR_START state in case of error also */ + //HCL_DEBUG_ASSERT(grabStartedServiceCnt != 0); + //grabStartedServiceCnt--; // this is already being done in RESET under control service so no need to perform decrement here */ + + /*add error event*/ + CHECK_TABLE_OVERFLOW(nbEventsRaised, maxOfEvent, SVA_GB_NOT_SUPPORTED); + pEventDesc[nbEventsRaised].eventId = SVA_EVENT_SERVICE_ERROR; + pEventDesc[nbEventsRaised].serviceId = serviceId; + pEventDesc[nbEventsRaised].bufferId = INVALID_BUFFER_ID; + pEventDesc[nbEventsRaised].eventTimestamp = (t_sva_timestamp_value) eventTimestamp; + pEventDesc[nbEventsRaised].eventDate = (t_sva_timestamp_value) eventDate; + /*@BORT-$TOP*/ +// if (pDesc->state==SVA_GB_ABORT_REQUESTED) + // { + // pEventDesc[nbEventsRaised].extraInfo = 0; + // pEventDesc[nbEventsRaised].extraInfo2 = 0; +// } + // else + // { + pEventDesc[nbEventsRaised].extraInfo=(t_uint32)SVA_PREPROCESSOR_TASK_PARAMETER_ERROR; + pEventDesc[nbEventsRaised].extraInfo2 = paramOut.error_type; +// } + + nbEventsRaised++; + + /*increase number of error*/ + pDesc->status.eventStats.errorCounter++; + + /*update state machine*/ + sva_GB_UpdateInstanceStateMachine(instanceNum,SVA_GB_EVENT_ERROR); + break; + + case SVA_TM_ABORT_HW_EVENT: + CHECK_TABLE_OVERFLOW(nbEventsRaised, maxOfEvent, SVA_GB_NOT_SUPPORTED); + pEventDesc[nbEventsRaised].eventId = SVA_EVENT_SERVICE_ERROR; + pEventDesc[nbEventsRaised].serviceId = serviceId; + pEventDesc[nbEventsRaised].bufferId = INVALID_BUFFER_ID; + pEventDesc[nbEventsRaised].eventTimestamp = (t_sva_timestamp_value) eventTimestamp; + pEventDesc[nbEventsRaised].eventDate = (t_sva_timestamp_value) eventDate; + pEventDesc[nbEventsRaised].extraInfo = 0; + pEventDesc[nbEventsRaised].extraInfo2 = 0; + nbEventsRaised++; + pDesc->status.eventStats.errorCounter++; + + /*update state machine*/ + sva_GB_UpdateInstanceStateMachine(instanceNum,SVA_GB_EVENT_ERROR); + + break; + case SVA_TM_GS_HW_EVENT: + //printf("\n SVA_TM_GS_HW_EVENT"); + /*add error event*/ + CHECK_TABLE_OVERFLOW(nbEventsRaised, maxOfEvent, SVA_GB_NOT_SUPPORTED); + pEventDesc[nbEventsRaised].eventId = SVA_EVENT_PREPROCESSOR_LINE_SYNCHRO; + pEventDesc[nbEventsRaised].serviceId = serviceId; + pEventDesc[nbEventsRaised].bufferId = INVALID_BUFFER_ID; + pEventDesc[nbEventsRaised].eventTimestamp = (t_sva_timestamp_value) eventTimestamp; + pEventDesc[nbEventsRaised].eventDate = (t_sva_timestamp_value) eventDate; + pEventDesc[nbEventsRaised].extraInfo=0; + nbEventsRaised++; + break; + case SVA_TM_PACKET_ERROR_HW_EVENT: + CHECK_TABLE_OVERFLOW(nbEventsRaised, maxOfEvent, SVA_GB_NOT_SUPPORTED); + pEventDesc[nbEventsRaised].eventId = SVA_EVENT_PACKET_ERROR; + pEventDesc[nbEventsRaised].serviceId = serviceId; + pEventDesc[nbEventsRaised].bufferId = INVALID_BUFFER_ID; + pEventDesc[nbEventsRaised].eventTimestamp = (t_sva_timestamp_value) eventTimestamp; + pEventDesc[nbEventsRaised].eventDate = (t_sva_timestamp_value) eventDate; + pEventDesc[nbEventsRaised].extraInfo=0; + nbEventsRaised++; + break; + case SVA_TM_PACKET_WRITE_HW_EVENT: + CHECK_TABLE_OVERFLOW(nbEventsRaised, maxOfEvent, SVA_GB_NOT_SUPPORTED); + pEventDesc[nbEventsRaised].eventId = SVA_EVENT_PACKET_WRITE; + pEventDesc[nbEventsRaised].serviceId = serviceId; + pEventDesc[nbEventsRaised].bufferId = INVALID_BUFFER_ID; + pEventDesc[nbEventsRaised].eventTimestamp = (t_sva_timestamp_value) eventTimestamp; + pEventDesc[nbEventsRaised].eventDate = (t_sva_timestamp_value) eventDate; + pEventDesc[nbEventsRaised].extraInfo=0; + isPacketOnGoing = FALSE; + nbEventsRaised++; + break; + case SVA_TM_PACKET_READ_HW_EVENT: + { + t_sva_mm_error mmError; + t_sva_gb_packet *pIrpPacket; + + CHECK_TABLE_OVERFLOW(nbEventsRaised, maxOfEvent, SVA_GB_NOT_SUPPORTED); + mmError = sva_MM_GetBlockLogicalAddress(pDesc->irpPacketId, (t_logical_address *) &pIrpPacket); + HCL_DEBUG_ASSERT(mmError==SVA_MM_OK); + pEventDesc[nbEventsRaised].eventId = SVA_EVENT_PACKET_READ; + pEventDesc[nbEventsRaised].serviceId = serviceId; + pEventDesc[nbEventsRaised].bufferId = INVALID_BUFFER_ID; + pEventDesc[nbEventsRaised].eventTimestamp = (t_sva_timestamp_value) eventTimestamp; + pEventDesc[nbEventsRaised].eventDate = (t_sva_timestamp_value) eventDate; + pEventDesc[nbEventsRaised].extraInfo = pIrpPacket->value; + isPacketOnGoing = FALSE; + nbEventsRaised++; + } + break; + default: + break; + } + + /*try to solve some dependencies*/ + sva_GB_ResolveDependencies(instanceNum); + + /*return number of generated events*/ + *pNbEvent=nbEventsRaised; + + return SVA_GB_OK; +} + +/****************************************************************************/ +/* NAME: t_sva_error sva_GB_Delete ( */ +/* t_sva_service_id serviceId */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine deletes the GRAB service */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - serviceId: identifier of the service */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/* - SVA_OK : Command taken into account */ +/* - SVA_UNKNOWN_SERVICE_ID : service id is not correct */ +/* - SVA_UNEXPECTED_API_CALL : Command cannot be excecuted in */ +/* current context. */ +/* - SVA_INTERNAL_PREPROCESSOR_ERROR : internal error */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + DONE +*/ +PUBLIC t_sva_error sva_GB_Delete(t_sva_service_id serviceId) +{ + t_sva_service_instance_num instanceNum = READ_INSTANCE_NUM_IN_SERVICE_ID(serviceId); + t_sva_gb_descriptor *pDesc=&grabDesc[instanceNum]; + t_uint32 i; + t_sva_tm_error tmError; + t_sva_mm_error mmError; + t_sva_error status; + + /*check for service id validity*/ + status=sva_GB_CheckServiceId(serviceId); + if (status!=SVA_OK) {return status;} + + /*check that transition is allowed*/ + if (sva_GB_isTransitionValid(instanceNum,SVA_GB_CONTROL_DELETE)==FALSE) {return SVA_UNEXPECTED_API_CALL;} + + /*check that flush has been done*/ + if (IS_FIFO_EMPTY(pDesc->outputImageFifos.pushFifo)==FALSE) {return SVA_INTERNAL_PREPROCESSOR_ERROR;} + if (IS_FIFO_EMPTY(pDesc->outputImageFifos.inUseFifo)==FALSE) {return SVA_INTERNAL_PREPROCESSOR_ERROR;} + + if (IS_FIFO_EMPTY(pDesc->paramFifos.pushFifo)==FALSE) {return SVA_INTERNAL_PREPROCESSOR_ERROR;} + if (IS_FIFO_EMPTY(pDesc->paramFifos.pushFifo)==FALSE) {return SVA_INTERNAL_PREPROCESSOR_ERROR;} + + if (IS_FIFO_EMPTY(pDesc->snapshotImageFifos.pushFifo)==FALSE) {return SVA_INTERNAL_PREPROCESSOR_ERROR;} + if (IS_FIFO_EMPTY(pDesc->snapshotImageFifos.pushFifo)==FALSE) {return SVA_INTERNAL_PREPROCESSOR_ERROR;} + + + /*start to delete. Things to do depend of current state*/ + if (pDesc->state==SVA_GB_WAIT_FOR_ACTIVATE || pDesc->state==SVA_GB_WAIT_FOR_START) + { + /*delete fifos*/ + DELETE_FIFO(pDesc->outputImageFifos.pushFifo); + DELETE_FIFO(pDesc->outputImageFifos.inUseFifo); + + DELETE_FIFO(pDesc->paramFifos.pushFifo); + DELETE_FIFO(pDesc->paramFifos.inUseFifo); + + DELETE_FIFO(pDesc->snapshotImageFifos.pushFifo); + DELETE_FIFO(pDesc->snapshotImageFifos.inUseFifo); + + DELETE_FIFO(pDesc->subtasksDependencyFifo); + /*delete subtasklist*/ + tmError=sva_TM_DeleteSubTaskList(pDesc->subtasksListId); + if (tmError!=SVA_TM_OK) {return SVA_INTERNAL_PREPROCESSOR_ERROR;} + /*delete subtasks*/ + for(i=0;isubtasksIdArray[i]); + if (tmError!=SVA_TM_OK) {return SVA_INTERNAL_PREPROCESSOR_ERROR;} + } + } + + /*Free dedicated memory allocated for RAW IDP buffer*/ + if(pDesc->grabHQEnable == TRUE) + { + mmError=sva_MM_FreeDedicatedBlock(pDesc->idpBlockId); + if (mmError!= SVA_MM_OK) {return SVA_INTERNAL_PREPROCESSOR_ERROR;} + } + /*delete memory allocated for irp packet*/ + mmError = sva_MM_FreeBlock(pDesc->irpPacketId); + if (mmError!=SVA_MM_OK) {return SVA_INTERNAL_PREPROCESSOR_ERROR;} + + /*delete descriptor use by memory management*/ + status=sva_EM_Delete(serviceId); + if (status!=SVA_OK) {return status;} + + /*reset descriptors*/ + sva_GB_ResetDescriptor(pDesc); + + /* Update the state machine */ + sva_GB_UpdateInstanceStateMachine(instanceNum,SVA_GB_CONTROL_DELETE); + + return SVA_OK; +} + +/****************************************************************************/ +/* NAME: t_sva_gb_error sva_GB_ResolveDependencies( */ +/* t_sva_service_instance_num instanceNum */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* */ +/* This routine is called in hv_GB_Push and after specific event like EOT */ +/* */ +/* PARAMETERS: */ +/* IN : none */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: t_sva_gb_error */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + TO DO : + - update params + - error code +*/ +PRIVATE t_sva_gb_error sva_GB_ResolveDependencies +( + t_sva_service_instance_num instanceNum +) +{ + t_sva_gb_descriptor *pDesc=&grabDesc[instanceNum]; + t_bool dependencyNotSolved=FALSE; + t_sva_buffer_id bufferId=INVALID_BUFFER_ID; + t_sva_gb_subtask_dependencies subTaskDep; + t_sva_grb_frame_buffer_out bufferOut; + t_sva_grb_frame_buffer_in parambufferIn; + t_sva_ff_error ffError; + t_sva_tm_error tmError; + + /*check that transition is valid*/ + if (sva_GB_isTransitionValid(instanceNum,SVA_GB_ALL_DEPENDENCIES_RESOLVED)==FALSE) {return SVA_GB_INVALID_TRANSITION;} + + /*enter loop where we try to solve dep for a maximum of subtasks*/ + while(IS_FIFO_EMPTY(pDesc->subtasksDependencyFifo)==FALSE && dependencyNotSolved==FALSE) + { + /*read subtask for which we will try to solve dependencies*/ + ffError=READ_FIFO_ELEM(pDesc->subtasksDependencyFifo,t_sva_gb_subtask_dependencies,subTaskDep); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + if (subTaskDep.dependencies.outputImageDep == NOT_RESOLVED_DEPENDENCY) + { + if (POP_FIFO_ELEM(pDesc->outputImageFifos.pushFifo,t_sva_buffer_id,bufferId) != SVA_FIFO_EMPTY) + { + t_physical_address bufferAddr; + t_size bufferSize; + t_sva_bm_error bmError; + + /*handle configuration change*/ + if (pDesc->confHandle.confState == SVA_GB_WAIT_FOR_BUFFER_ID || + pDesc->confHandle.confState == SVA_GB_SYNC_CONF_CHANGE_NEED) + { + sva_GB_ConfigurationChangeOnSolveDep(instanceNum,subTaskDep,bufferId); + } + + /*we can resolve output image dependency, so we do it*/ + /*push the image buffer in the in use fifo*/ + ffError=PUSH_FIFO_ELEM(pDesc->outputImageFifos.inUseFifo,t_sva_buffer_id,bufferId); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + /*update subtask dependency as in use*/ + ffError=UPDATE_FIFO_ELEM_FIELD(pDesc->subtasksDependencyFifo, + t_sva_gb_subtask_dependencies, .dependencies.outputImageDep, + RESOLVED_DEPENDENCY); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + subTaskDep.dependencies.outputImageDep = RESOLVED_DEPENDENCY; + /*update field in the task list*/ + bmError=sva_BM_GetBufferPhysicalAddress(bufferId,&bufferAddr); + HCL_DEBUG_ASSERT(bmError==SVA_BM_OK); + bmError=sva_BM_GetBufferSize(bufferId,&bufferSize); + HCL_DEBUG_ASSERT(bmError==SVA_BM_OK); + bufferOut.addr_dest_lc_buffer=bufferAddr; + bufferOut.addr_dest_raw_data_buffer=bufferAddr; + bufferOut.addr_dest_raw_data_end=bufferAddr+bufferSize; + /*don't take semaphore since task is not schedulable and copy all structure is possible*/ + tmError=sva_TM_InitSubTaskField(subTaskDep.subtaskId, SVA_TM_GRB_ADDR_OUT_FRAME_BUFFER, + (t_logical_address) &bufferOut, sizeof(t_sva_grb_frame_buffer_out)); + HCL_DEBUG_ASSERT(tmError==SVA_TM_OK); + } + } + if (subTaskDep.dependencies.snapshotImageDep == NOT_RESOLVED_DEPENDENCY) + { + if (POP_FIFO_ELEM(pDesc->snapshotImageFifos.pushFifo,t_sva_buffer_id,bufferId) != SVA_FIFO_EMPTY) + { + t_physical_address bufferAddr; + t_size bufferSize; + t_sva_bm_error bmError; + + /*handle configuration change*/ + if (pDesc->confHandle.confState == SVA_GB_WAIT_FOR_BUFFER_ID || + pDesc->confHandle.confState == SVA_GB_SYNC_CONF_CHANGE_NEED) + { + sva_GB_ConfigurationChangeOnSolveDep(instanceNum,subTaskDep,bufferId); + } + + /*we can resolve output image dependency, so we do it*/ + /*push the image buffer in the in use fifo*/ + ffError=PUSH_FIFO_ELEM(pDesc->snapshotImageFifos.inUseFifo,t_sva_buffer_id,bufferId); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + /*update subtask dependency as in use*/ + ffError=UPDATE_FIFO_ELEM_FIELD(pDesc->subtasksDependencyFifo, + t_sva_gb_subtask_dependencies, .dependencies.snapshotImageDep, + RESOLVED_DEPENDENCY); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + subTaskDep.dependencies.snapshotImageDep = RESOLVED_DEPENDENCY; + /*update field in the task list*/ + bmError=sva_BM_GetBufferPhysicalAddress(bufferId,&bufferAddr); + HCL_DEBUG_ASSERT(bmError==SVA_BM_OK); + bmError=sva_BM_GetBufferSize(bufferId,&bufferSize); + HCL_DEBUG_ASSERT(bmError==SVA_BM_OK); + bufferOut.addr_snap_buffer=bufferAddr; + /*don't take semaphore since task is not schedulable and copy all structure is possible*/ + //tmError=sva_TM_InitSubTaskField(subTaskDep.subtaskId, SVA_TM_GRB_ADDR_OUT_FRAME_BUFFER, + // (t_logical_address) &bufferOut.addr_snap_buffer, sizeof(bufferOut.addr_snap_buffer)); + tmError=sva_TM_UpdateSubTaskField(SVA_TM_INTERMEDIATE_FIELD_TO_UPDATE, subTaskDep.subtaskId,SVA_TM_GRB_ADDR_OUT_FRAME_BUFFER, FCMD_COPY, (t_uint32)&bufferOut.addr_snap_buffer,12, sizeof(bufferOut.addr_snap_buffer)); + HCL_DEBUG_ASSERT(tmError==SVA_TM_OK); + } + } + if (subTaskDep.dependencies.paramDep[pDesc->gridBuffDepToBeResolved] == NOT_RESOLVED_DEPENDENCY) + { + if (POP_FIFO_ELEM(pDesc->paramFifos.pushFifo,t_sva_buffer_id,bufferId) != SVA_FIFO_EMPTY) + { + t_physical_address bufferAddr; + t_size bufferSize; + t_sva_bm_error bmError; + + /*handle configuration change*/ + if (pDesc->confHandle.confState == SVA_GB_WAIT_FOR_BUFFER_ID || + pDesc->confHandle.confState == SVA_GB_SYNC_CONF_CHANGE_NEED) + { + sva_GB_ConfigurationChangeOnSolveDep(instanceNum,subTaskDep,bufferId); + } + /*we can resolve input param dependency, so we do it*/ + /*push the input param buffer in the in use fifo*/ + ffError=PUSH_FIFO_ELEM(pDesc->paramFifos.inUseFifo,t_sva_buffer_id,bufferId); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + /*update subtask dependency as in use*/ + ffError=UPDATE_FIFO_ELEM_FIELD(pDesc->subtasksDependencyFifo, + t_sva_gb_subtask_dependencies, .dependencies.paramDep[pDesc->gridBuffDepToBeResolved], + RESOLVED_DEPENDENCY); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + subTaskDep.dependencies.paramDep[pDesc->gridBuffDepToBeResolved] = RESOLVED_DEPENDENCY; + + /*update field in the task list*/ + bmError=sva_BM_GetBufferPhysicalAddress(bufferId,&bufferAddr); + HCL_DEBUG_ASSERT(bmError==SVA_BM_OK); + bmError=sva_BM_GetBufferSize(bufferId,&bufferSize); + HCL_DEBUG_ASSERT(bmError==SVA_BM_OK); + + switch (pDesc->gridBuffDepToBeResolved) + { + case SVA_GRAB_GRID0_BUFF_DEP_TO_BE_RESOLVED: + pDesc->gridDayPhyAddr = bufferAddr; + pDesc->gridBuffDepToBeResolved = SVA_GRAB_GRID1_BUFF_DEP_TO_BE_RESOLVED; + break; + case SVA_GRAB_GRID1_BUFF_DEP_TO_BE_RESOLVED: + pDesc->gridCoolPhyAdd = bufferAddr; + pDesc->gridBuffDepToBeResolved = SVA_GRAB_GRID2_BUFF_DEP_TO_BE_RESOLVED; + break; + case SVA_GRAB_GRID2_BUFF_DEP_TO_BE_RESOLVED: + pDesc->gridIncPhyAddr = bufferAddr; + pDesc->gridBuffDepToBeResolved = SVA_GRAB_GRID3_BUFF_DEP_TO_BE_RESOLVED; + break; + case SVA_GRAB_GRID3_BUFF_DEP_TO_BE_RESOLVED: + pDesc->gridHorPhyAddr = bufferAddr; + pDesc->gridBuffDepToBeResolved = SVA_GRAB_GRID0_BUFF_DEP_TO_BE_RESOLVED; + + parambufferIn.addr_grid_buffer_day = pDesc->gridDayPhyAddr; + parambufferIn.addr_grid_buffer_cool = pDesc->gridCoolPhyAdd; + parambufferIn.addr_grid_buffer_inc = pDesc->gridIncPhyAddr; + parambufferIn.addr_grid_buffer_hor = pDesc->gridHorPhyAddr; + + /*don't take semaphore since task is not schedulable and copy all structure is possible*/ + tmError=sva_TM_InitSubTaskField(subTaskDep.subtaskId, SVA_TM_GRB_ADDR_IN_FRAME_BUFFER, + (t_logical_address) ¶mbufferIn, sizeof(t_sva_grb_frame_buffer_in)); + HCL_DEBUG_ASSERT(tmError==SVA_TM_OK); + break; + default: + HCL_ASSERT(1); + break; + } + } + } + + /*check that all dependency has been resolved to continue*/ + /*Check only for the last grid buffer */ + if ((subTaskDep.dependencies.outputImageDep != NOT_RESOLVED_DEPENDENCY) && + (subTaskDep.dependencies.paramDep[SVA_GRAB_GRID0_BUFF_DEP_TO_BE_RESOLVED] != NOT_RESOLVED_DEPENDENCY) && + (subTaskDep.dependencies.paramDep[SVA_GRAB_GRID1_BUFF_DEP_TO_BE_RESOLVED] != NOT_RESOLVED_DEPENDENCY) && + (subTaskDep.dependencies.paramDep[SVA_GRAB_GRID2_BUFF_DEP_TO_BE_RESOLVED] != NOT_RESOLVED_DEPENDENCY) && + (subTaskDep.dependencies.paramDep[SVA_GRAB_GRID3_BUFF_DEP_TO_BE_RESOLVED] != NOT_RESOLVED_DEPENDENCY) && + (subTaskDep.dependencies.snapshotImageDep != NOT_RESOLVED_DEPENDENCY) + ) + { + t_sva_tm_timestamp immediateTimeStamp={SVA_TM_IMMEDIATE,0}; + + /*handle configuration change*/ + if (pDesc->confHandle.confState==SVA_GB_IMMEDIATE_CONF_CHANGE_NEED) + { + sva_GB_ConfigurationChangeOnSolveDep(instanceNum,subTaskDep,bufferId); + } + /*pop subtask from list of subtask for which dep has to be solved*/ + ffError=POP_FIFO_ELEM(pDesc->subtasksDependencyFifo,t_sva_gb_subtask_dependencies,subTaskDep); + /*update state machine*/ + sva_GB_UpdateInstanceStateMachine(instanceNum,SVA_GB_ALL_DEPENDENCIES_RESOLVED); + /*add subtask to list of schedulable subtasks*/ + tmError=sva_TM_AddElemToSubTaskList(pDesc->subtasksListId,subTaskDep.subtaskId,&immediateTimeStamp, 1); + HCL_DEBUG_ASSERT(tmError==SVA_TM_OK); + } + else + { + dependencyNotSolved=TRUE; + } + } + + return SVA_GB_OK; +} + +/****************************************************************************/ +/* NAME: t_bool sva_GB_IsConfigurationValid( */ +/* const t_sva_preprocessor_configuration *pConf */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will check that given configuration given to grab is */ +/* valid. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - pConf: a pointer to the configuration to check */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: t_bool */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + TO DO : + - check if some others value can be check +*/ +PRIVATE t_bool sva_GB_IsConfigurationValid +( + const t_sva_preprocessor_configuration *pConf +) +{ + HCL_DEBUG_ASSERT(pConf != NULL); + + /* when in irp mode do specific check */ + if (pConf->transformId == SVA_PREPROCESSOR_SENSOR_YUV420_MB || + pConf->transformId == SVA_PREPROCESSOR_SENSOR_YUV420_SEP_COMP_MB || + pConf->transformId == SVA_PREPROCESSOR_SENSOR_YUV422_SEP_COMP_MB || + pConf->transformId == SVA_PREPROCESSOR_SENSOR_YUV420_RASTER_OUT || + pConf->transformId == SVA_PREPROCESSOR_SENSOR_HIGHQUALITY_YUV420_MB) + { + return sva_GB_IsIrpConfigurationValid(pConf); + } + + /*t_sva_preprocessor_capability_id transformId*/ + if (pConf->transformId == SVA_PREPROCESSOR_RAW && SVA_PREPROCESSOR_RAW_SUPPORTED == FALSE) {return FALSE;} + if (pConf->transformId == SVA_PREPROCESSOR_YUV420_MB && SVA_PREPROCESSOR_YUV420_MB_SUPPORTED == FALSE) {return FALSE;} + if (pConf->transformId == SVA_PREPROCESSOR_YUV420_SEP_COMP_MB && SVA_PREPROCESSOR_YUV420_SEP_COMP_MB_SUPPORTED == FALSE) {return FALSE;} + if (pConf->transformId == SVA_PREPROCESSOR_YUV422_SEP_COMP_MB && SVA_PREPROCESSOR_YUV422_SEP_COMP_MB_SUPPORTED == FALSE) {return FALSE;} + + /*check interfaceSyncMode possible values: external or embedded synchronisation*/ + CHECK_RANGE0(pConf->interfaceSyncMode, SVA_PREPROCESSOR_SYNC_EMBEDDED_CODES, SVA_PREPROCESSOR_SYNC_EXTERNAL_MODE2); + + /*t_bool isInputInterlaced*/ + if (pConf->isInputInterlaced == TRUE) + { + + /*test hardware support for interlace*/ + if (SVA_PREPROCESSOR_INTERLACE_SUPPORTED == FALSE) + { + return FALSE; + } + else + { + /*transform must be the classical 420Mb*/ + if (pConf->transformId != SVA_PREPROCESSOR_YUV420_MB) {return FALSE;} + /*interface must be ccir with embedded synchro*/ + if (pConf->interfaceCConfiguration != SVA_PREPROCESSOR_CCIR656_INTERFACE_RISING_EDGE && + pConf->interfaceCConfiguration != SVA_PREPROCESSOR_CCIR656_INTERFACE_FALLING_EDGE && + pConf->interfaceSyncMode != SVA_PREPROCESSOR_SYNC_EMBEDDED_CODES) + { + return FALSE; + } + /*ace must be disable*/ + if (pConf->isAceEnable==TRUE) {return FALSE;} + /*resize must be disable*/ + if (pConf->resizedWindowDesc.width != pConf->sourceFrameDesc.window.image.width || + pConf->resizedWindowDesc.height != pConf->sourceFrameDesc.window.image.height) + { + return FALSE; + } + } + } + + /*t_sva_windowed_frame_desc sourceFrameDesc*/ + if (pConf->transformId!=SVA_PREPROCESSOR_RAW) + { + CHECK_ALIGNMENT(pConf->sourceFrameDesc.frame.height,SVA_GB_SOURCE_FRAME_HEIGHT_ALIGN); + CHECK_RANGE(pConf->sourceFrameDesc.frame.height, SVA_GB_SOURCE_FRAME_HEIGHT_MIN, SVA_GB_SOURCE_FRAME_HEIGHT_MAX); + CHECK_ALIGNMENT(pConf->sourceFrameDesc.frame.width,SVA_GB_SOURCE_FRAME_WIDTH_ALIGN); + CHECK_RANGE(pConf->sourceFrameDesc.frame.width, SVA_GB_SOURCE_FRAME_WIDTH_MIN, SVA_GB_SOURCE_FRAME_WIDTH_MAX); + CHECK_ALIGNMENT(pConf->sourceFrameDesc.window.image.height,SVA_GB_SOURCE_WINDOW_HEIGHT_ALIGN); + CHECK_RANGE(pConf->sourceFrameDesc.window.image.height, SVA_GB_SOURCE_WINDOW_HEIGHT_MIN, pConf->sourceFrameDesc.frame.height); + CHECK_ALIGNMENT(pConf->sourceFrameDesc.window.image.width,SVA_GB_SOURCE_WINDOW_WIDTH_ALIGN); + CHECK_RANGE(pConf->sourceFrameDesc.window.image.width, SVA_GB_SOURCE_WINDOW_WIDTH_MIN, pConf->sourceFrameDesc.frame.width); + CHECK_ALIGNMENT(pConf->sourceFrameDesc.window.imageOffset.offsetX,SVA_GB_SOURCE_WINDOW_OFFSET_X_ALIGN); + CHECK_RANGE0(pConf->sourceFrameDesc.window.imageOffset.offsetX, SVA_GB_SOURCE_WINDOW_OFFSET_X_MIN, pConf->sourceFrameDesc.frame.width-pConf->sourceFrameDesc.window.image.width); + CHECK_ALIGNMENT(pConf->sourceFrameDesc.window.imageOffset.offsetY,SVA_GB_SOURCE_WINDOW_OFFSET_Y_ALIGN); + CHECK_RANGE0(pConf->sourceFrameDesc.window.imageOffset.offsetY, SVA_GB_SOURCE_WINDOW_OFFSET_Y_MIN, pConf->sourceFrameDesc.frame.height-pConf->sourceFrameDesc.window.image.height); + } + + /*t_sva_image_desc resizedWindowDesc*/ + if (pConf->transformId!=SVA_PREPROCESSOR_RAW) + { + CHECK_ALIGNMENT(pConf->resizedWindowDesc.width,SVA_GB_RESIZED_WINDOW_WIDTH_ALIGN); + if (pConf->resizedWindowDesc.width!=pConf->sourceFrameDesc.window.image.width) + { + CHECK_RANGE(pConf->resizedWindowDesc.width, SVA_GB_RESIZED_WINDOW_WIDTH_MIN, SVA_GB_RESIZED_WINDOW_WIDTH_MAX); + CHECK_RANGE(pConf->resizedWindowDesc.width, pConf->sourceFrameDesc.window.image.width/SVA_GB_MAX_DOWNSCALING_FACTOR, pConf->sourceFrameDesc.window.image.width*SVA_GB_MAX_UPSCALING_FACTOR); + } + CHECK_ALIGNMENT(pConf->resizedWindowDesc.height,SVA_GB_RESIZED_WINDOW_HEIGHT_ALIGN); + if (pConf->resizedWindowDesc.height!=pConf->sourceFrameDesc.window.image.height) + { + CHECK_RANGE(pConf->resizedWindowDesc.height, SVA_GB_RESIZED_WINDOW_HEIGHT_MIN, SVA_GB_RESIZED_WINDOW_HEIGHT_MAX); + CHECK_RANGE(pConf->resizedWindowDesc.height, pConf->sourceFrameDesc.window.image.height/SVA_GB_MAX_DOWNSCALING_FACTOR, pConf->sourceFrameDesc.window.image.height*SVA_GB_MAX_UPSCALING_FACTOR); + } + } + + /*t_sva_preprocessor_input_mode interfaceCConfiguration*/ + if (pConf->interfaceCConfiguration == SVA_PREPROCESSOR_CCP0_INTERFACE_RISING_EDGE_STROBE_ENABLE || + pConf->interfaceCConfiguration == SVA_PREPROCESSOR_CCP0_INTERFACE_FALLING_EDGE_STROBE_ENABLE || + pConf->interfaceCConfiguration == SVA_PREPROCESSOR_CCP1_INTERFACE_RISING_EDGE_STROBE_ENABLE || + pConf->interfaceCConfiguration == SVA_PREPROCESSOR_CCP1_INTERFACE_FALLING_EDGE_STROBE_ENABLE) + { + if (SVA_PREPROCESSOR_CCP_STROBE_ENABLE_SUPPORTED == FALSE) {return FALSE;} + } + if (pConf->interfaceCConfiguration == SVA_PREPROCESSOR_CCP1_INTERFACE_RISING_EDGE || + pConf->interfaceCConfiguration == SVA_PREPROCESSOR_CCP1_INTERFACE_FALLING_EDGE || + pConf->interfaceCConfiguration == SVA_PREPROCESSOR_CCP1_INTERFACE_RISING_EDGE_STROBE_ENABLE || + pConf->interfaceCConfiguration == SVA_PREPROCESSOR_CCP1_INTERFACE_FALLING_EDGE_STROBE_ENABLE) + { + if (SVA_PREPROCESSOR_CCP1_SUPPORTED == FALSE) {return FALSE;} + } + + /*Check Grab synchronisation line number limits */ + CHECK_RANGE0(pConf->grabSyncLine, 0, SVA_GB_SYNC_LINE_MAX); + + /* Check ace strength and ace range */ + if (pConf->isAceEnable==TRUE) + { + CHECK_RANGE(pConf->aceStrength, SVA_ACE_STRENGTH_1, SVA_ACE_STRENGTH_8); + CHECK_RANGE0(pConf->aceRange, SVA_FULL_RANGE, SVA_BT601_RANGE); + } + /* Check bits per pixel, valid in CCIR656 raw data mode with external synchronisation*/ + if((pConf->transformId==SVA_PREPROCESSOR_RAW)&& + (pConf->interfaceSyncMode != SVA_PREPROCESSOR_SYNC_EMBEDDED_CODES)) + { + CHECK_RANGE0(pConf->rawBpp, SVA_PREPROCESSOR_RAW_8BPP, SVA_PREPROCESSOR_RAW_10BPP); + } + + /* Check OutputRange possible values */ + CHECK_RANGE0(pConf->outputRange, SVA_FULL_RANGE, SVA_BT601_RANGE); + + return TRUE; +} + +/****************************************************************************/ +/* NAME: t_bool sva_GB_IsIrpConfigurationValid( */ +/* const t_sva_preprocessor_configuration *pConf */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will check that given configuration given to grab is */ +/* valid. This concern only irp mode. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - pConf: a pointer to the configuration to check */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: t_bool */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PRIVATE t_bool sva_GB_IsIrpConfigurationValid +( + const t_sva_preprocessor_configuration *pConf +) +{ + HCL_DEBUG_ASSERT(pConf != NULL); + + /* first check irp supported */ + if (SVA_PREPROCESSOR_IRP_SUPPORTED == FALSE) + { + return FALSE; + } + else + { + /* t_sva_preprocessor_capability_id transformId */ + /* no check done */ + + /*t_sva_windowed_frame_desc sourceFrameDesc*/ + CHECK_ALIGNMENT(pConf->sourceFrameDesc.frame.height,SVA_GB_SOURCE_FRAME_HEIGHT_ALIGN); + CHECK_RANGE(pConf->sourceFrameDesc.frame.height, SVA_GB_SOURCE_FRAME_HEIGHT_MIN, SVA_GB_SOURCE_FRAME_HEIGHT_MAX); + CHECK_ALIGNMENT(pConf->sourceFrameDesc.frame.width,SVA_GB_SOURCE_FRAME_WIDTH_ALIGN); + CHECK_RANGE(pConf->sourceFrameDesc.frame.width, SVA_GB_SOURCE_FRAME_WIDTH_MIN, SVA_GB_SOURCE_FRAME_WIDTH_MAX); + if (pConf->sourceFrameDesc.window.image.height != pConf->sourceFrameDesc.frame.height) {return FALSE;} + if (pConf->sourceFrameDesc.window.image.width != pConf->sourceFrameDesc.frame.width) {return FALSE;} + if (pConf->sourceFrameDesc.window.imageOffset.offsetX != 0) {return FALSE;} + if (pConf->sourceFrameDesc.window.imageOffset.offsetY != 0) {return FALSE;} + + /*t_sva_image_desc resizedWindowDesc*/ + /*This check was added for FW 3.12.0*/ + if(pConf->transformId != SVA_PREPROCESSOR_SENSOR_HIGHQUALITY_YUV420_MB) + { + if (pConf->resizedWindowDesc.height != pConf->sourceFrameDesc.frame.height) {return FALSE;} + if (pConf->resizedWindowDesc.width != pConf->sourceFrameDesc.frame.width) {return FALSE;} + } + if(pConf->transformId == SVA_PREPROCESSOR_SENSOR_HIGHQUALITY_YUV420_MB) + { + CHECK_RANGE(pConf->grabhqConfig.bmlClockDivisor, SVA_GB_HQ_BML_CLK_DIVISER_MIN, SVA_GB_HQ_BML_CLK_DIVISER_MAX); + CHECK_RANGE(pConf->grabhqConfig.nbMaxBmlRetiesOnFailure, SVA_GB_HQ_BML_RECOVER_NB_RETRY_MIN, SVA_GB_HQ_BML_RECOVER_NB_RETRY_MAX); + } + + /*t_sva_preprocessor_input_mode interfaceCConfiguration*/ + if (pConf->interfaceCConfiguration == SVA_PREPROCESSOR_CCP0_INTERFACE_RISING_EDGE_STROBE_ENABLE || + pConf->interfaceCConfiguration == SVA_PREPROCESSOR_CCP0_INTERFACE_FALLING_EDGE_STROBE_ENABLE || + pConf->interfaceCConfiguration == SVA_PREPROCESSOR_CCP1_INTERFACE_RISING_EDGE_STROBE_ENABLE || + pConf->interfaceCConfiguration == SVA_PREPROCESSOR_CCP1_INTERFACE_FALLING_EDGE_STROBE_ENABLE) + { + if (SVA_PREPROCESSOR_CCP_STROBE_ENABLE_SUPPORTED == FALSE) {return FALSE;} + } + if (pConf->interfaceCConfiguration == SVA_PREPROCESSOR_CCP1_INTERFACE_RISING_EDGE || + pConf->interfaceCConfiguration == SVA_PREPROCESSOR_CCP1_INTERFACE_FALLING_EDGE || + pConf->interfaceCConfiguration == SVA_PREPROCESSOR_CCP1_INTERFACE_RISING_EDGE_STROBE_ENABLE || + pConf->interfaceCConfiguration == SVA_PREPROCESSOR_CCP1_INTERFACE_FALLING_EDGE_STROBE_ENABLE) + { + if (SVA_PREPROCESSOR_CCP1_SUPPORTED == FALSE) {return FALSE;} + } + + /*t_bool isInputInterlaced*/ + if (pConf->isInputInterlaced == TRUE) {return FALSE;} + + /*t_bool isAceEnable*/ + if (pConf->isAceEnable == TRUE) {return FALSE;} + + /*interface must be ccir with embedded synchro*/ + if (pConf->interfaceCConfiguration != SVA_PREPROCESSOR_CCIR656_INTERFACE_RISING_EDGE && + pConf->interfaceCConfiguration != SVA_PREPROCESSOR_CCIR656_INTERFACE_FALLING_EDGE && + pConf->interfaceSyncMode != SVA_PREPROCESSOR_SYNC_EMBEDDED_CODES) + { + return FALSE; + } + /*t_sva_preprocessor_ccir_input_sync_mode interfaceSyncMode*/ + /*t_sva_preprocessor_ccir_raw_bpp rawBpp*/ + /*t_uint32 grabSyncLine*/ + /*t_sva_color_range outputRange*/ + /*t_sva_ace_strength aceStrength*/ + /*t_sva_color_range aceRange*/ + /*no check done*/ + } + return TRUE; +} + +/****************************************************************************/ +/* NAME: t_sva_gb_state sva_GB_UpdateInstanceStateMachine( */ +/* t_sva_service_instance_num instanceNum, */ +/* t_sva_gb_transition requestedTransition */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine allows to update both state machine */ +/* following the given requestedTransition */ +/* */ +/* N.B: This routine returns the new state after the requested transition */ +/* A special return state (SVA_GB_TRANSITION_REJECTED) is used to check */ +/* the validity of a transition request */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - instanceNum : instance number for which state must be updated */ +/* - requestedTransition: identifier of the requested transition */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: t_sva_gb_state */ +/* - one of the t_sva_gb_state */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + DONE +*/ +PRIVATE t_sva_gb_state sva_GB_UpdateInstanceStateMachine +( + t_sva_service_instance_num instanceNum, + t_sva_gb_transition requestedTransition +) +{ + t_sva_gb_descriptor *pDesc=&grabDesc[instanceNum]; + t_sva_gb_state nextState; + t_sva_gb_activate_state nextActivateState; + +#ifdef __DEBUG + { + t_uint32 systemTime; + + SVA_GetServiceSystemTime(pDesc->serviceId,&systemTime); + transitionGrabDebugTable[instanceNum].transitionDebugDesc[transitionGrabDebugTable[instanceNum].nbOfTransitionReceived%LOG_DEPTH].state=pDesc->state; + transitionGrabDebugTable[instanceNum].transitionDebugDesc[transitionGrabDebugTable[instanceNum].nbOfTransitionReceived%LOG_DEPTH].transition=requestedTransition; + transitionGrabDebugTable[instanceNum].transitionDebugDesc[transitionGrabDebugTable[instanceNum].nbOfTransitionReceived%LOG_DEPTH].systemTime=systemTime; + transitionGrabDebugTable[instanceNum].transitionDebugDesc[transitionGrabDebugTable[instanceNum].nbOfTransitionReceived%LOG_DEPTH].activateState=pDesc->activateState; + transitionGrabDebugTable[instanceNum].nbOfTransitionReceived++; + + } +#endif + + /* Compute the next state */ + nextState=stateMachine[pDesc->state][requestedTransition]; + nextActivateState=activateStateMachine[pDesc->activateState][requestedTransition]; + + /* Check if the transition is valid */ + if (nextState != SVA_GB_TRANSITION_REJECTED && nextActivateState!=SVA_GB_ACTIVATE_TRANSITION_REJECTED) + { + /* Update both current state of the instance */ + pDesc->state = nextState; + pDesc->activateState = nextActivateState; + /* Update status*/ + pDesc->status.state=grabState2ServiceState[pDesc->state]; + } + + return nextState; +} + +/****************************************************************************/ +/* NAME: t_bool sva_GB_isTransitionValid( */ +/* t_sva_service_instance_num instanceNum, */ +/* t_sva_gb_transition requestedTransition */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine checks if the requestedTransition is valid for both */ +/* state machine */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - instanceNum : instance number for which transition check must be done*/ +/* - requestedTransition: identifier of the requested transition */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: t_bool */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + DONE +*/ +PRIVATE t_bool sva_GB_isTransitionValid +( + t_sva_service_instance_num instanceNum, + t_sva_gb_transition requestedTransition +) +{ + t_sva_gb_descriptor *pDesc=&grabDesc[instanceNum]; + t_sva_gb_state nextState; + t_sva_gb_activate_state nextActivateState; + + /* Compute the next state for both state machine*/ + nextState=stateMachine[pDesc->state][requestedTransition]; + nextActivateState=activateStateMachine[pDesc->activateState][requestedTransition]; + + /*return false in case of invalid transition for at least one state machine*/ + if (nextState != SVA_GB_TRANSITION_REJECTED && nextActivateState!=SVA_GB_ACTIVATE_TRANSITION_REJECTED) {return TRUE;} + else {return FALSE;} +} + +/****************************************************************************/ +/* NAME: t_sva_error sva_GB_CheckServiceId(t_sva_service_id serviceId) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will check that task_id and instance number of servideId*/ +/* are both valid */ +/* */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - serviceId: service id to check */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: t_sva_gb_error */ +/* - SVA_UNKNOWN_SERVICE_ID : Invalid service id. Either due to an */ +/* invalid task id or invalid instance number. */ +/* - SVA_OK : Service id is valid */ +/* */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + DONE +*/ +PRIVATE t_sva_error sva_GB_CheckServiceId(t_sva_service_id serviceId) +{ + t_sva_service_instance_num instanceNum = READ_INSTANCE_NUM_IN_SERVICE_ID(serviceId); + t_sva_sv_task_id taskId = READ_TASK_ID_IN_SERVICE_ID(serviceId); + + if (taskId!=SVA_SV_GRAB_TID) {return SVA_UNKNOWN_SERVICE_ID;} + if (instanceNum>=NUM_MAX_GRAB) {return SVA_UNKNOWN_SERVICE_ID;} + + return SVA_OK; +} + +/****************************************************************************/ +/* NAME: t_sva_error sva_GB_BuildParamInStructure( */ +/* const t_sva_preprocessor_configuration *pConf, */ +/* t_sva_grb_param_in *pParamIn */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine builds the paramIn structure from the given configuration */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - pConf: provided preprocessor configuration */ +/* */ +/* OUT: */ +/* - pParamIn: paramIn structure to build */ +/* */ +/* RETURN: t_sva_error */ +/* */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + TO DO : + - fix remaining hard-coded value +*/ +PRIVATE t_sva_error sva_GB_BuildParamInStructure +( + const t_sva_preprocessor_configuration *pConf, + t_sva_grb_param_in *pParamIn +) +{ + HCL_DEBUG_ASSERT(pConf != NULL); + HCL_DEBUG_ASSERT(pParamIn != NULL); + + /*describe source frame size*/ + pParamIn->source_frame_width=(t_short_value)pConf->sourceFrameDesc.frame.width; + pParamIn->source_frame_height=(t_short_value)pConf->sourceFrameDesc.frame.height; + /*describe source window size and cropping offset*/ + pParamIn->source_window_width=(t_short_value)pConf->sourceFrameDesc.window.image.width; + pParamIn->source_window_height=(t_short_value)pConf->sourceFrameDesc.window.image.height; + pParamIn->source_window_horizontal_offset=(t_short_value)pConf->sourceFrameDesc.window.imageOffset.offsetX; + pParamIn->source_window_vertical_offset=(t_short_value)pConf->sourceFrameDesc.window.imageOffset.offsetY; + /*describe target window size*/ + pParamIn->resized_window_width=(t_short_value)pConf->resizedWindowDesc.width; + pParamIn->resized_window_height=(t_short_value)pConf->resizedWindowDesc.height; + pParamIn->snap_window_width=(t_ushort_value)pConf->snapshotImageDesc.width; + pParamIn->snap_window_height=(t_ushort_value)pConf->snapshotImageDesc.height; + /*set interface_configuration*/ + pParamIn->interface_configuration = input_mode_2_interface_configuration[pConf->interfaceCConfiguration]; + switch(pConf->interfaceSyncMode) + { + case SVA_PREPROCESSOR_SYNC_EMBEDDED_CODES: + /*nothing to do*/ + break; + case SVA_PREPROCESSOR_SYNC_EXTERNAL_MODE1: + pParamIn->interface_configuration|=0x4; + break; + case SVA_PREPROCESSOR_SYNC_EXTERNAL_MODE2: + pParamIn->interface_configuration|=0xc; + break; + default: + return SVA_INCOHERENT_CONFIGURATION; + /*break;*/ + } + /*set grab_sync_line*/ + pParamIn->grab_sync_line=(t_ushort_value)pConf->grabSyncLine; + /*set chroma_sampling_format*/ + if (pConf->transformId==SVA_PREPROCESSOR_YUV422_SEP_COMP_MB || + pConf->transformId==SVA_PREPROCESSOR_SENSOR_YUV422_SEP_COMP_MB) + { + pParamIn->chroma_sampling_format=SVA_GB_CHROMA_YUV422; + } + else if (pConf->resizedWindowDesc.width==pConf->sourceFrameDesc.window.image.width && + pConf->resizedWindowDesc.height==pConf->sourceFrameDesc.window.image.height) + { + pParamIn->chroma_sampling_format=SVA_GB_CHROMA_YUV420_DECIMATION; + } + else {pParamIn->chroma_sampling_format=SVA_GB_CHROMA_YUV420_DOWNSAMPLING;} + /*ace stuff*/ + if (pConf->isAceEnable==TRUE) + { + pParamIn->ace_enable=1; + pParamIn->ace_strength=(t_uint16) pConf->aceStrength; + pParamIn->ace_range=(t_uint16) pConf->aceRange; + } + else + { + pParamIn->ace_enable=0; + pParamIn->ace_strength=(t_uint16) pConf->aceStrength; + pParamIn->ace_range=(t_uint16) pConf->aceRange; + } + /*output range*/ + pParamIn->output_range=(t_uint16) pConf->outputRange; + + /*interlace*/ + /* + * if input is interlace but output is not done in a frame (so it's + * done on a field) interlace mode is not set for firmware. + */ + if (pConf->isInputInterlaced == TRUE) + { + if (pConf->isOutputFrame == TRUE) {pParamIn->interlace_enable = 1;} + else {pParamIn->interlace_enable = 0;} + } + else {pParamIn->interlace_enable = 0;} + + /*field_sync*/ + /* selection is done on subtask by subtask basis and so is done above*/ + pParamIn->field_sync=SVA_GB_ANY_FIELD; + + /*raw_data_bpp*/ + if (pConf->rawBpp == SVA_PREPROCESSOR_RAW_10BPP) + { + pParamIn->raw_data_bpp=SVA_GB_RAW_10_BITS; + } + else + { + pParamIn->raw_data_bpp=SVA_GB_RAW_8_BITS; + } + + if(pConf->transformId == SVA_PREPROCESSOR_SENSOR_HIGHQUALITY_YUV420_MB) + { + pParamIn->choffset_enable = pConf->grabhqConfig.isChannelOffsetEnabled; + pParamIn->gridiron_enable = pConf->grabhqConfig.isGridironEnabled; + pParamIn->reserved0 = 0; + pParamIn->scorpio_enable = pConf->grabhqConfig.isScorpioEnabled; + pParamIn->scorpio_strenght = pConf->grabhqConfig.scorpioStrength; + pParamIn->cast_day = pConf->grabhqConfig.castDay; + pParamIn->cast_cool = pConf->grabhqConfig.castCool; + pParamIn->cast_inc = pConf->grabhqConfig.castInc; + pParamIn->cast_hor = pConf->grabhqConfig.castHorizon; + pParamIn->gridhsize = pConf->grabhqConfig.gridHSize; + pParamIn->bml_clock_divisor = pConf->grabhqConfig.bmlClockDivisor; + pParamIn->bml_recover_nb_retry = pConf->grabhqConfig.nbMaxBmlRetiesOnFailure; + } + + return SVA_OK; +} + +/****************************************************************************/ +/* NAME: t_sva_error sva_GB_BuildParamInOutStructure( */ +/* const t_sva_ace_offset *pAceOffset, */ +/* t_sva_grb_param_inout *pParamInOut */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine builds the paramInOut structure from the given ace offset.*/ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - pAceOffset: provided ace offsets */ +/* */ +/* OUT: */ +/* - pParamInOut: paramInout structure to build */ +/* */ +/* RETURN: t_sva_error */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + DONE +*/ +PRIVATE t_sva_error sva_GB_BuildParamInOutStructure +( + const t_sva_ace_offset *pAceOffset, + t_sva_grb_param_inout *pParamInOut +) +{ + HCL_DEBUG_ASSERT(pAceOffset != NULL); + HCL_DEBUG_ASSERT(pParamInOut != NULL); + + /*set ace offset*/ + pParamInOut->ace_offset0=pAceOffset->ace_offset_0; + pParamInOut->ace_offset1=pAceOffset->ace_offset_1; + pParamInOut->ace_offset2=pAceOffset->ace_offset_2; + pParamInOut->ace_offset3=pAceOffset->ace_offset_3; + + return SVA_OK; +} + +/****************************************************************************/ +/* NAME: t_sva_error sva_GB_DoReset( */ +/* t_sva_service_id serviceId */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will reset a service so it can restart after an error. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - serviceId: service identifier */ +/* */ +/* OUT: none */ +/* */ +/* RETURN: t_sva_error */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + DONE +*/ +PRIVATE t_sva_error sva_GB_DoReset +( + t_sva_service_id serviceId +) +{ + //t_sva_service_instance_num instanceNum = READ_INSTANCE_NUM_IN_SERVICE_ID(serviceId); + //t_sva_gb_descriptor *pDesc=&grabDesc[instanceNum]; + (void) serviceId; + + return SVA_OK; +} + +/****************************************************************************/ +/* NAME: t_sva_error sva_GB_DoFlushIn( */ +/* t_sva_service_id serviceId */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will flush input fifo. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - serviceId: service identifier */ +/* */ +/* OUT: none */ +/* */ +/* RETURN: t_sva_error */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + DONE +*/ +PRIVATE t_sva_error sva_GB_DoFlushIn +( + t_sva_service_id serviceId +) +{ + t_sva_service_instance_num instanceNum = READ_INSTANCE_NUM_IN_SERVICE_ID(serviceId); + t_sva_gb_descriptor *pDesc=&grabDesc[instanceNum]; + t_sva_gb_subtask_dependencies subtaskDep; + t_sva_buffer_id bufferId = 0; + t_uint32 systemTime; + t_sva_error svaError; + t_sva_tm_error tmError; + t_sva_ff_error ffError; + t_sva_bm_error bmError; + + /*remove schedule tasks and push them back in subtasksDependencyFifo with default dep*/ + /*so they can be rescheduled */ + do + { + tmError=sva_TM_RemoveElemFromSubTaskList(pDesc->subtasksListId,&subtaskDep.subtaskId); + if (tmError==SVA_TM_OK) + { + subtaskDep.dependencies = pDesc->defaultDep; + ffError=PUSH_FIFO_ELEM(pDesc->subtasksDependencyFifo,t_sva_gb_subtask_dependencies,subtaskDep); + if (ffError!=SVA_FIFO_OK) {return SVA_INTERNAL_PREPROCESSOR_ERROR;} + } + } while (tmError==SVA_TM_OK); + + /*get time*/ + svaError=SVA_GetServiceSystemTime(serviceId,&systemTime); + if (svaError != SVA_OK) {return SVA_INTERNAL_PREPROCESSOR_ERROR;} + + /*flush fifo*/ + while(POP_FIFO_ELEM(pDesc->paramFifos.inUseFifo,t_sva_buffer_id,bufferId) != SVA_FIFO_EMPTY) + { + bmError=sva_BM_UpdateBufferStatus(bufferId,SVA_BUFFER_NOT_USED,systemTime); + if (bmError!=SVA_BM_OK) {return SVA_INTERNAL_PREPROCESSOR_ERROR;} + } + while(POP_FIFO_ELEM(pDesc->paramFifos.pushFifo,t_sva_buffer_id,bufferId) != SVA_FIFO_EMPTY) + { + bmError=sva_BM_UpdateBufferStatus(bufferId,SVA_BUFFER_NOT_USED,systemTime); + if (bmError!=SVA_BM_OK) {return SVA_INTERNAL_PREPROCESSOR_ERROR;} + } + + do + { + ffError=POP_REVERSE_FIFO_ELEM(pDesc->outputImageFifos.inUseFifo,t_sva_buffer_id,bufferId); + if (ffError==SVA_FIFO_OK) + { + ffError=PUSH_REVERSE_FIFO_ELEM(pDesc->outputImageFifos.pushFifo,t_sva_buffer_id,bufferId); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + } + } while (ffError==SVA_FIFO_OK); + + do + { + ffError=POP_REVERSE_FIFO_ELEM(pDesc->snapshotImageFifos.inUseFifo,t_sva_buffer_id,bufferId); + if (ffError==SVA_FIFO_OK) + { + ffError=PUSH_REVERSE_FIFO_ELEM(pDesc->snapshotImageFifos.pushFifo,t_sva_buffer_id,bufferId); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + } + } while (ffError==SVA_FIFO_OK); + + + return SVA_OK; +} +/****************************************************************************/ +/* NAME: t_sva_error sva_GB_DoFlushOut( */ +/* t_sva_service_id serviceId */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will flush output fifo. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - serviceId: service identifier */ +/* */ +/* OUT: none */ +/* */ +/* RETURN: t_sva_error */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + DONE +*/ +PRIVATE t_sva_error sva_GB_DoFlushOut +( + t_sva_service_id serviceId +) +{ + t_sva_service_instance_num instanceNum = READ_INSTANCE_NUM_IN_SERVICE_ID(serviceId); + t_sva_gb_descriptor *pDesc=&grabDesc[instanceNum]; + t_sva_gb_subtask_dependencies subtaskDep; + t_sva_buffer_id bufferId = 0; + t_uint32 systemTime; + t_sva_error svaError; + t_sva_tm_error tmError; + t_sva_ff_error ffError; + t_sva_bm_error bmError; + t_uint32 i; + t_uint32 task_removed=0; + + /*remove schedule tasks and push them back in subtasksDependencyFifo with default dep*/ + /*so they can be rescheduled */ + do + { + tmError=sva_TM_RemoveElemFromSubTaskList(pDesc->subtasksListId,&subtaskDep.subtaskId); + if (tmError==SVA_TM_OK) + { + subtaskDep.dependencies = pDesc->defaultDep; + ffError=PUSH_FIFO_ELEM(pDesc->subtasksDependencyFifo,t_sva_gb_subtask_dependencies,subtaskDep); + if (ffError!=SVA_FIFO_OK) {return SVA_INTERNAL_PREPROCESSOR_ERROR;} + task_removed++; + } + } while (tmError==SVA_TM_OK); + + /* Push subtask in subtasksDependencyFifo since they are ready to be solved*/ + for(i=0;i<((SUBTASK_GRAB_NUMBER-task_removed)+1);i++) + { + t_sva_gb_subtask_dependencies subtaskDep; + + ffError=POP_FIFO_ELEM(pDesc->subtasksDependencyFifo, t_sva_gb_subtask_dependencies, subtaskDep); + subtaskDep.dependencies=pDesc->defaultDep; + ffError=PUSH_FIFO_ELEM(pDesc->subtasksDependencyFifo, t_sva_gb_subtask_dependencies, subtaskDep); + if (ffError!=SVA_FIFO_OK) {return SVA_INTERNAL_PREPROCESSOR_ERROR;} + } + /*get time*/ + svaError=SVA_GetServiceSystemTime(serviceId,&systemTime); + if (svaError != SVA_OK) {return SVA_INTERNAL_PREPROCESSOR_ERROR;} + + /*flush fifo*/ + while(POP_FIFO_ELEM(pDesc->outputImageFifos.inUseFifo,t_sva_buffer_id,bufferId) != SVA_FIFO_EMPTY) + { + bmError=sva_BM_UpdateBufferStatus(bufferId,SVA_BUFFER_NOT_USED,systemTime); + if (bmError!=SVA_BM_OK) {return SVA_INTERNAL_PREPROCESSOR_ERROR;} + } + while(POP_FIFO_ELEM(pDesc->outputImageFifos.pushFifo,t_sva_buffer_id,bufferId) != SVA_FIFO_EMPTY) + { + bmError=sva_BM_UpdateBufferStatus(bufferId,SVA_BUFFER_NOT_USED,systemTime); + if (bmError!=SVA_BM_OK) {return SVA_INTERNAL_PREPROCESSOR_ERROR;} + } + + /*flush fifo*/ + while(POP_FIFO_ELEM(pDesc->snapshotImageFifos.inUseFifo,t_sva_buffer_id,bufferId) != SVA_FIFO_EMPTY) + { + bmError=sva_BM_UpdateBufferStatus(bufferId,SVA_BUFFER_NOT_USED,systemTime); + if (bmError!=SVA_BM_OK) {return SVA_INTERNAL_PREPROCESSOR_ERROR;} + } + while(POP_FIFO_ELEM(pDesc->snapshotImageFifos.pushFifo,t_sva_buffer_id,bufferId) != SVA_FIFO_EMPTY) + { + bmError=sva_BM_UpdateBufferStatus(bufferId,SVA_BUFFER_NOT_USED,systemTime); + if (bmError!=SVA_BM_OK) {return SVA_INTERNAL_PREPROCESSOR_ERROR;} + } + + return SVA_OK; +} +/****************************************************************************/ +/* NAME: t_sva_gb_error sva_GB_ResetStatus( */ +/* t_sva_preprocessor_status *pStatus */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will reset status descriptor. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - pStatus: status descriptor to reset */ +/* */ +/* OUT: none */ +/* */ +/* RETURN: t_sva_gb_error */ +/* - SVA_GB_OK */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + DONE +*/ +PRIVATE t_sva_gb_error sva_GB_ResetStatus +( + t_sva_preprocessor_status *pStatus +) +{ + GB_CHECK_NULL_POINTER(pStatus); + + pStatus->state=SVA_SERVICE_NOT_INITIALIZED; + pStatus->errorId=SVA_PREPROCESSOR_NO_ERROR; + pStatus->nbGrabbedImage=0; + pStatus->isAceEnable=FALSE; + pStatus->aceOffset.ace_offset_0=0; + pStatus->aceOffset.ace_offset_1=0; + pStatus->aceOffset.ace_offset_2=0; + pStatus->aceOffset.ace_offset_3=0; + pStatus->eventStats.voidedCounter=0; + pStatus->eventStats.filledCounter=0; + pStatus->eventStats.partlyCounter=0; + pStatus->eventStats.readOnlyCounter=0; + pStatus->eventStats.underflowCounter=0; + pStatus->eventStats.overflowCounter=0; + pStatus->eventStats.errorCounter=0; + pStatus->bufferizationStats.inLevel=0; + pStatus->bufferizationStats.outLevel=0; + + return SVA_GB_OK; +} + +/****************************************************************************/ +/* NAME: t_sva_gb_error sva_GB_ConfigurationChangeOnPush( */ +/* t_sva_service_id serviceId, */ +/* t_sva_buffer_type bufferType, */ +/* t_sva_push_mode pushMode, */ +/* t_sva_buffer_id bufferId */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will check is the push buffer is of the type and mode need*/ +/* for a configuration change. */ +/* In that case it will keep bufferId so the configuration become fully */ +/* active when buffer depencency will be solve. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - serviceId: service descriptor on which push occur */ +/* - bufferType : type of buffer push */ +/* - pushMode : mode of buffer push */ +/* - bufferId : buffer identifier */ +/* */ +/* OUT: none */ +/* */ +/* RETURN: void */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + DONE +*/ +PRIVATE void sva_GB_ConfigurationChangeOnPush( + t_sva_service_id serviceId, + t_sva_buffer_type bufferType, + t_sva_push_mode pushMode, + t_sva_buffer_id bufferId +) +{ + t_sva_service_instance_num instanceNum = READ_INSTANCE_NUM_IN_SERVICE_ID(serviceId); + t_sva_gb_descriptor *pDesc=&grabDesc[instanceNum]; + + if (pDesc->confHandle.confState==SVA_GB_WAIT_FOR_BUFFER && + pDesc->confHandle.bufferType==bufferType && + pDesc->confHandle.pushMode==pushMode) + { + /*change current configuration for buffer push check only*/ + /*store on which buffer id it will become fully active*/ + pDesc->confHandle.currentConf=pDesc->confHandle.nextConf; + pDesc->confHandle.bufferId=bufferId; + pDesc->confHandle.confState=SVA_GB_WAIT_FOR_BUFFER_ID; + } +} + +/****************************************************************************/ +/* NAME: t_sva_gb_error sva_GB_ConfigurationChangeOnSolveDep( */ +/* t_sva_service_instance_num instanceNum, */ +/* t_sva_gb_subtask_dependencies subTaskDep, */ +/* t_sva_buffer_id bufferId */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine is call from sva_GB_ResolveDependencies() API. It will be */ +/* In charge to do two different things. */ +/* 1) In case we have a synchronized configuration change, we wait to */ +/* solve dependencies for correct buffer id to change configuration */ +/* to use. */ +/* 2) Update paramin of subtasks at the right instant */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - serviceId: service descriptor on which push occur */ +/* - bufferType : type of buffer push */ +/* - pushMode : mode of buffer push */ +/* - bufferId : buffer identifier */ +/* */ +/* OUT: none */ +/* */ +/* RETURN: void */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + DONE +*/ +PRIVATE void sva_GB_ConfigurationChangeOnSolveDep( + t_sva_service_instance_num instanceNum, + t_sva_gb_subtask_dependencies subTaskDep, + t_sva_buffer_id bufferId +) +{ + t_sva_gb_descriptor *pDesc=&grabDesc[instanceNum]; + t_sva_preprocessor_configuration *pConf=&pDesc->confHandle.currentConf; + + /*first check in case we are in sync mode if bufferid is the on we are waiting for*/ + if (pDesc->confHandle.confState==SVA_GB_WAIT_FOR_BUFFER_ID && + pDesc->confHandle.bufferId==bufferId) + { + /*change state and conf counter*/ + pDesc->confHandle.currentConfCounter++; + pDesc->confHandle.confState=SVA_GB_SYNC_CONF_CHANGE_NEED; + } + + /*try to update subtask paramin*/ + if (pDesc->confHandle.confState==SVA_GB_SYNC_CONF_CHANGE_NEED || + pDesc->confHandle.confState==SVA_GB_IMMEDIATE_CONF_CHANGE_NEED) + { + t_uint32 index; + t_bool exitForLoop=FALSE; + + /*search for conf counter of subtaskid*/ + for(index=0;indexsubtasksIdArray[index]==subTaskDep.subtaskId) {exitForLoop=TRUE;} + } + index--; + + /*check if we need to change conf*/ + if (pDesc->subtasksConfCounter[index]!=pDesc->confHandle.currentConfCounter) + { + t_sva_grb_param_in paramInBuffer; + t_sva_tm_error tmError; + + /*we need to update subtask with new paramin*/ + sva_GB_BuildParamInStructure(pConf,¶mInBuffer); + /* + * in case we are in interlace mode, even index subtask grab field 0 + * and odd index subtask grab field 1 + */ + if (pConf->isInputInterlaced==TRUE) + { + if (index%2 == 0) {paramInBuffer.field_sync=SVA_GB_FIELD_ZERO;} + else {paramInBuffer.field_sync=SVA_GB_FIELD_ONE;} + } + tmError=sva_TM_InitSubTaskField(subTaskDep.subtaskId,SVA_TM_GRB_ADDR_IN_PARAMETERS, + (t_logical_address)¶mInBuffer,sizeof(t_sva_grb_param_in)); + HCL_DEBUG_ASSERT(tmError==SVA_TM_OK); + + /*update paraminout if ace offset need to be reset to a given value*/ + if (pDesc->confHandle.isAceOffsetNeedUpdate==TRUE) + { + t_sva_grb_param_inout paramInOutBuffer; + + /*we need to update subtask with new paraminout*/ + sva_GB_BuildParamInOutStructure(&pDesc->confHandle.newAceOffset,¶mInOutBuffer); + tmError=sva_TM_InitSubTaskField(subTaskDep.subtaskId,SVA_TM_GRB_ADDR_IN_FRAME_PARAMETERS, + (t_logical_address)¶mInOutBuffer,sizeof(t_sva_grb_param_inout)); + HCL_DEBUG_ASSERT(tmError==SVA_TM_OK); + + /*only the first subtask need to be updated*/ + pDesc->confHandle.isAceOffsetNeedUpdate=FALSE; + } + + /*update conf counter*/ + pDesc->subtasksConfCounter[index]=pDesc->confHandle.currentConfCounter; + } + else + { + /*all subtask have been updated*/ + pDesc->confHandle.confState=SVA_GB_NO_CONF_CHANGE_NEED; + } + } +} + +/****************************************************************************/ +/* NAME: t_bool sva_GB_isChangeConfIsImmediate( */ +/* const t_sva_preprocessor_configuration *pCurrent, */ +/* const t_sva_preprocessor_configuration *pNext */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine is in charge to check if there is an output size change */ +/* between current configuration and the next one. If such a difference */ +/* exists then configuration change has to be synchronized and function */ +/* return FALSE. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - pCurrent: current configuration */ +/* - pNext : next configuration */ +/* */ +/* OUT: none */ +/* */ +/* RETURN: t_bool */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + DONE +*/ +PRIVATE t_bool sva_GB_isChangeConfIsImmediate( + const t_sva_preprocessor_configuration *pCurrent, + const t_sva_preprocessor_configuration *pNext +) +{ + GB_CHECK_NULL_POINTER(pCurrent); + GB_CHECK_NULL_POINTER(pNext); + + /**************************************************************************/ + /* The size of the buffers already pushed will be assumed to be greater */ + /* than or equal to the size of resize required. So the update can happen*/ + /* on the next immediate buffer in FIFO */ + /**************************************************************************/ + + + /*if (pCurrent->resizedWindowDesc.height!=pNext->resizedWindowDesc.height || + pCurrent->resizedWindowDesc.width!=pNext->resizedWindowDesc.width) + { + return FALSE; + }*/ + + return TRUE; +} + +/****************************************************************************/ +/* NAME: void sva_GB_ResetDescriptor( */ +/* t_sva_gb_descriptor *pDesc */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine is in charge to check if there is an output size change */ +/* between current configuration and the next one. If such a difference */ +/* exists then configuration change has to be synchronized and function */ +/* return FALSE. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - pDesc: descriptor to reset */ +/* */ +/* OUT: none */ +/* */ +/* RETURN: void */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + DONE +*/ +PRIVATE void sva_GB_ResetDescriptor(t_sva_gb_descriptor *pDesc) +{ + t_uint32 i; + + GB_CHECK_NULL_POINTER(pDesc); + + pDesc->confHandle.isAceOffsetNeedUpdate=FALSE; + pDesc->confHandle.currentConfCounter=0; + pDesc->confHandle.confState=SVA_GB_NO_CONF_CHANGE_NEED; + for(i=0;isubtasksConfCounter[i]=0;} + sva_GB_ResetStatus(&pDesc->status); + pDesc->isIrpMode = FALSE; + pDesc->grabHQEnable = FALSE; + pDesc->gridBuffDepToBeResolved = SVA_GRAB_GRID0_BUFF_DEP_TO_BE_RESOLVED; + pDesc->imageBuffDepToBeResolved = SVA_GRAB_OUT_BUFF_DEP_TO_BE_RESOLVED; +} + +/****************************************************************************/ +/* NAME: t_logical_address SVA_GetGrabHQIdpAddress( */ +/* t_sva_service_id serviceId */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine provies the logical address of raw idp buffer */ +/* The buffer is available only for GRABHQ task adn is used only for testing purpose */ +/* PARAMETERS: */ +/* IN : */ +/* - pDesc: descriptor to reset */ +/* */ +/* OUT: none */ +/* */ +/* RETURN: void */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ + +PUBLIC t_logical_address SVA_GetGrabHQIdpAddress(t_sva_service_id serviceId) +{ + t_sva_service_instance_num instanceNum = READ_INSTANCE_NUM_IN_SERVICE_ID(serviceId); + t_sva_gb_descriptor *pDesc=&grabDesc[instanceNum]; + return(pDesc->idpBlockAddr.logical); + +} + + --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/grab/sva_grab.h @@ -0,0 +1,88 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ +#ifndef __INC_SVA_GRAB_H +#define __INC_SVA_GRAB_H + +#include "sva.h" +#include "svap.h" +#include "sva_taskmgt.h" + +/******************************************************************************/ +/* Constants definitions */ +/******************************************************************************/ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* + * Define the symbols used to identify the various errors of the Grab Module + */ +typedef enum { + SVA_GB_INVALID_TRANSITION = SVA_GB_LAST_ERROR, + SVA_GB_NO_MORE_AVAILABLE_INSTANCE, + SVA_GB_INVALID_INSTANCE_NB, + SVA_GB_INVALID_TASK_ID_NB, + SVA_GB_NOT_SUPPORTED, + SVA_GB_INVALID_CONTROL_PARAM, + SVA_GB_INVALID_PUSH, + SVA_GB_INVALID_BUFFER_TYPE, + SVA_GB_INVALID_BUFFER_SIZE, + SVA_GB_INVALID_CONFIGURATION, + SVA_GB_UNKNOWN_CMD_ID, + SVA_GB_UNEXPECTED_HW_EVENT, + SVA_GB_SYNCHRO_INFO_NOT_AVAILABLE, + SVA_GB_TI_LINKED_ERROR, + SVA_GB_BM_LINKED_ERROR, + SVA_GB_MM_LINKED_ERROR, + SVA_GB_FF_LINKED_ERROR, + SVA_GB_TM_LINKED_ERROR, + SVA_GB_NULL_POINTER_PARAMETER, + SVA_GB_FIFO_NOT_EMPTY, + SVA_GB_OK = HCL_OK +} t_sva_gb_error; + + +/******************************************************************************* +* PUBLIC Functions +*******************************************************************************/ + +PUBLIC t_sva_error sva_GB_Init( void ); +PUBLIC t_sva_error sva_GB_Reset( t_sva_service_id ); +PUBLIC t_sva_error sva_GB_Create( t_sva_service_id *); +PUBLIC t_sva_error sva_GB_Control(t_sva_service_id, t_sva_service_cmd_id, t_uint32 ); +PUBLIC t_sva_error sva_GB_Push(t_sva_service_id, t_sva_buffer_id, t_sva_push_mode, t_sva_buffer_type, t_sva_timestamp ); +PUBLIC t_sva_gb_error sva_GB_DispatchVirtualHwEvent(t_sva_tm_virtual_hw_event_id, t_sva_service_id, t_sva_tm_subtask_id, t_uint32, t_uint32, t_uint8, t_sva_event_desc *, t_uint32 *); +PUBLIC t_sva_error sva_GB_ProvideInternalNeeds( t_sva_service_id); +PUBLIC t_sva_error sva_GB_GetInternalNeeds(t_sva_service_id, t_size *); +PUBLIC t_sva_error sva_GB_Activate(t_sva_service_id, t_sva_service_mode, t_sva_fw_id *); +PUBLIC t_sva_error sva_GB_Inactivate(t_sva_service_id); +PUBLIC t_sva_error sva_GB_Delete(t_sva_service_id ); +//t_sva_preprocessor_configuration is in sva.h +// function is sva.h +//PUBLIC t_sva_error SVA_ConfigurePreProcessor( t_sva_service_id, t_sva_preprocessor_configuration); +//PUBLIC t_sva_error SVA_GetPreProcessorStatus(t_sva_service_id, t_sva_preprocessor_status *); +//PUBLIC t_sva_error SVA_UpdatePreProcessorParams(t_sva_service_id, t_sva_update_cmd_type, t_sva_preprocessor_param_id, t_uint32 ); + +#ifdef __cplusplus +} /* allow C++ to use these headers */ +#endif /* __cplusplus */ + +#endif /* __INC_SVA_GRAB_H */ +/* End of file - sva_grab.h */ --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/grab/sva_grabp.h @@ -0,0 +1,411 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ + +#ifndef __INC_SVA_GRABP_H +#define __INC_SVA_GRABP_H + +#include "hcl_defs.h" +#include "sva_grab.h" +#include "sva_taskmgt.h" +#include "sva_buffermgt.h" +#include "sva_fifo.h" +#include "sva_service.h" + +/******************************************************************************/ +/* Constants definitions */ +/******************************************************************************/ +#ifdef __DEBUG + /* + * Define number of event to log + */ + #define LOG_DEPTH 16 +#endif + +/* + * Define the number of field inside a Grab Subtask descriptor (spec v0.96) + */ +#define GRAB_FIELD_NUMBER 7 + +/* + * Define the default memory used to store subtasks descriptors + */ +#define GRAB_DEFAULT_MEMORY_ID SDRAM_ID + +/* + * Define the default memory used to store param_out (infos) data + */ +#define GRAB_DEFAULT_INFOS_MEMORY_ID SDRAM_ID + +/* + * Define macro to handle null pointer +*/ +#define GB_CHECK_NULL_POINTER(pointer) HCL_ASSERT(pointer!=NULL) + +/* + * Define macro to handle chroma selection +*/ +#define SVA_GB_CHROMA_YUV422 0 +#define SVA_GB_CHROMA_YUV420_DOWNSAMPLING 1 +#define SVA_GB_CHROMA_YUV420_DECIMATION 3 + +/* + * Define macro to handle field selection +*/ +#define SVA_GB_ANY_FIELD 0 +#define SVA_GB_FIELD_ZERO 1 +#define SVA_GB_FIELD_ONE 3 + +/* + * Define macro to handle raw mode bit number +*/ +#define SVA_GB_RAW_8_BITS 0 +#define SVA_GB_RAW_10_BITS 1 + +/* + * Define various configuration limits for grab +*/ + /*define support of transforms*/ +#ifdef __PLATFORM_MEVKLITE + #define SVA_PREPROCESSOR_RAW_SUPPORTED FALSE +#else + #define SVA_PREPROCESSOR_RAW_SUPPORTED TRUE +#endif +#define SVA_PREPROCESSOR_YUV420_MB_SUPPORTED TRUE +#define SVA_PREPROCESSOR_YUV420_SEP_COMP_MB_SUPPORTED TRUE +#define SVA_PREPROCESSOR_YUV422_SEP_COMP_MB_SUPPORTED TRUE +#if defined(__STN_8815) + #define SVA_PREPROCESSOR_IRP_SUPPORTED TRUE +#else + #define SVA_PREPROCESSOR_IRP_SUPPORTED FALSE +#endif + /* define data/strobe enable support */ +#if __STN_8810==20 + #define SVA_PREPROCESSOR_CCP_STROBE_ENABLE_SUPPORTED TRUE +#elif defined(__STN_8815) + #define SVA_PREPROCESSOR_CCP_STROBE_ENABLE_SUPPORTED TRUE +#else + #define SVA_PREPROCESSOR_CCP_STROBE_ENABLE_SUPPORTED FALSE +#endif + /* define ccp1 support */ +#if defined(__STN_8815) + #define SVA_PREPROCESSOR_CCP1_SUPPORTED TRUE +#else + #define SVA_PREPROCESSOR_CCP1_SUPPORTED FALSE +#endif + /*define support of interlace*/ +#if __STN_8810==20 + #define SVA_PREPROCESSOR_INTERLACE_SUPPORTED TRUE +#elif defined(__STN_8815) + #define SVA_PREPROCESSOR_INTERLACE_SUPPORTED TRUE +#else + #define SVA_PREPROCESSOR_INTERLACE_SUPPORTED FALSE +#endif + /*define source frame limits*/ +#define SVA_GB_SOURCE_FRAME_HEIGHT_ALIGN 2 +#define SVA_GB_SOURCE_FRAME_HEIGHT_MIN 16 + +#if __STN_8815>=20 +#define SVA_GB_SOURCE_FRAME_HEIGHT_MAX 1984 /*Not documneted in SVA SPec Draft 0.4 & V0.4*/ +#define SVA_GB_SOURCE_FRAME_WIDTH_MAX 2624 /*Not documneted in SVA SPec Draft 0.4 & V0.4*/ +#else +#define SVA_GB_SOURCE_FRAME_HEIGHT_MAX 2032 +#define SVA_GB_SOURCE_FRAME_WIDTH_MAX 2032 +#endif + +/* Define BML clock diviser limits */ +#define SVA_GB_HQ_BML_CLK_DIVISER_MIN 2 +#define SVA_GB_HQ_BML_CLK_DIVISER_MAX 4 + +/* Define BML recover retry limits */ +#define SVA_GB_HQ_BML_RECOVER_NB_RETRY_MIN 1 +#define SVA_GB_HQ_BML_RECOVER_NB_RETRY_MAX 15 + +#define SVA_GB_SOURCE_FRAME_WIDTH_ALIGN 2 +#define SVA_GB_SOURCE_FRAME_WIDTH_MIN 16 + + /*define cropping window limits*/ +#define SVA_GB_SOURCE_WINDOW_HEIGHT_ALIGN 1 +#define SVA_GB_SOURCE_WINDOW_HEIGHT_MIN 16 +#define SVA_GB_SOURCE_WINDOW_WIDTH_ALIGN 4 +#define SVA_GB_SOURCE_WINDOW_WIDTH_MIN 16 +#define SVA_GB_SOURCE_WINDOW_OFFSET_X_ALIGN 4 +#define SVA_GB_SOURCE_WINDOW_OFFSET_X_MIN 0 +#define SVA_GB_SOURCE_WINDOW_OFFSET_Y_ALIGN 1 +#define SVA_GB_SOURCE_WINDOW_OFFSET_Y_MIN 0 + /*define resized(target) window limits*/ + /*for min and max width and height, limits are use when resize */ + /*engine is active.*/ +#define SVA_GB_RESIZED_WINDOW_WIDTH_ALIGN 16 +#define SVA_GB_RESIZED_WINDOW_WIDTH_MIN 16 +#define SVA_GB_RESIZED_WINDOW_WIDTH_MAX 384 +#define SVA_GB_RESIZED_WINDOW_HEIGHT_ALIGN 16 +#define SVA_GB_RESIZED_WINDOW_HEIGHT_MIN 16 +#define SVA_GB_RESIZED_WINDOW_HEIGHT_MAX 304 +#ifdef __PLATFORM_MEVKLITE + #define SVA_GB_MAX_DOWNSCALING_FACTOR 1 + #define SVA_GB_MAX_UPSCALING_FACTOR 1 +#else + #define SVA_GB_MAX_DOWNSCALING_FACTOR 5 + #define SVA_GB_MAX_UPSCALING_FACTOR 1 +#endif + +/* + * Define packet payload size +*/ +#define SVA_GB_PACKET_PAYLOAD_SIZE 1 + +/* Define Grab synchronisation line number limits */ +#define SVA_GB_SYNC_LINE_MAX 1023 + +/*Define minimum size for grid buffers*/ +#define SVA_GRID_BUFFER_MIN_SIZE 66*50*2*4 + + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/******************************************************************************/ +/* Types definitions */ +/******************************************************************************/ +/* + * Define the various state of a Grab instance service + */ +typedef enum { + SVA_GB_NOT_INITIALIZED, + SVA_GB_WAIT_FOR_CONFIGURATION, + SVA_GB_WAIT_FOR_INTERNAL_NEEDS, + SVA_GB_WAIT_FOR_ACTIVATE, + SVA_GB_WAIT_FOR_START, + SVA_GB_FLUSHING_IN, + SVA_GB_FLUSHING_OUT, + SVA_GB_WAIT_FOR_DATA, + SVA_GB_RUNNING, + SVA_GB_ABORT_REQUESTED, + SVA_GB_STOP_REQUESTED, + SVA_GB_ERROR, + SVA_GB_LAST_DUMMY_STATE, + SVA_GB_TRANSITION_REJECTED +} t_sva_gb_state; + +/* + * Define the various activate state of a Grab instance service + */ +typedef enum { + SVA_GB_INACTIVE, + SVA_GB_IN_ACTIVATION, + SVA_GB_ACTIVE, + SVA_GB_IN_INACTIVATION, + SVA_GB_LAST_ACTIVATE_DUMMY_STATE, + SVA_GB_ACTIVATE_TRANSITION_REJECTED +} t_sva_gb_activate_state; + +/* + * Define the various transitions of the grab service + */ +typedef enum { + SVA_GB_CREATE, + SVA_GB_CONFIGURE, + SVA_GB_INTERNAL_NEEDS, + SVA_GB_ACTIVATE, + SVA_GB_INACTIVATE, + SVA_GB_CONTROL_START, + SVA_GB_CONTROL_STOP, + SVA_GB_CONTROL_ABORT, + SVA_GB_ALL_DEPENDENCIES_RESOLVED, + SVA_GB_PUSH, + SVA_GB_EVENT_EOK, + SVA_GB_EVENT_FAKE, + SVA_GB_EVENT_ACTIVE, + SVA_GB_EVENT_INACTIVE, + SVA_GB_RESET, + SVA_GB_CONTROL_DELETE, + SVA_GB_EVENT_ERROR, + SVA_GB_FLUSH_IN, + SVA_GB_FLUSH_OUT, + SVA_GB_CANCEL, + SVA_GB_UPDATE_PARAM, + SVA_GB_EVENT_ABORT, + SVA_GB_LAST_DUMMY_TRANSITION +} t_sva_gb_transition; + +/* + * Define the symbol used to qualify the state of the dependency + * for a given type of buffer + */ +typedef enum { + INTERNAL_DEPENDENCY, + NOT_RESOLVED_DEPENDENCY, + RESOLVED_DEPENDENCY +} t_sva_gb_dependencies_state; + +typedef enum { +SVA_GRAB_OUT_BUFF_DEP_TO_BE_RESOLVED = 0, +SVA_GRAB_SNAP_BUFF_DEP_TO_BE_RESOLVED = 1 +} t_sva_gb_image_buff_dep_to_be_resolved; + +typedef enum { +SVA_GRAB_GRID0_BUFF_DEP_TO_BE_RESOLVED = 0, +SVA_GRAB_GRID1_BUFF_DEP_TO_BE_RESOLVED = 1, +SVA_GRAB_GRID2_BUFF_DEP_TO_BE_RESOLVED = 2, +SVA_GRAB_GRID3_BUFF_DEP_TO_BE_RESOLVED = 3 +} t_sva_gb_grid_buff_dep_to_be_resolved; + +/* + * Define the structure used to manage the subtasks dependency + */ +typedef struct { + t_sva_gb_dependencies_state outputImageDep; + t_sva_gb_dependencies_state paramDep[SVA_GRAB_GRID3_BUFF_DEP_TO_BE_RESOLVED+1]; + t_sva_gb_dependencies_state snapshotImageDep; +} t_sva_gb_dependencies_desc; + +/* + * Define the structure used to manage the dependencies of each subtasks + */ +typedef struct { + t_sva_tm_subtask_id subtaskId; + t_sva_gb_dependencies_desc dependencies; +} t_sva_gb_subtask_dependencies; + +/* + * Define the fifos used to manage the dependency + * The buffers, provided though the Push routine, are buffered inside the pushFifo + * When programming them (using them) into a subtask, then they are considered as used, + * as so pushed inside th inUseFifo + */ +typedef struct { + t_sva_fifo pushFifo; + t_sva_fifo inUseFifo; +} t_sva_gb_fifo_dep; + +/* + * Define state machine use to synchronize configuration update + */ +typedef enum { + SVA_GB_NO_CONF_CHANGE_NEED, + SVA_GB_IMMEDIATE_CONF_CHANGE_NEED, + SVA_GB_WAIT_FOR_BUFFER, + SVA_GB_WAIT_FOR_BUFFER_ID, + SVA_GB_SYNC_CONF_CHANGE_NEED +} t_sva_gb_conf_state; + +/* + * Define structure that handle all stuff need to manipulate configuration change + */ +typedef struct { + t_sva_preprocessor_configuration currentConf; + t_sva_preprocessor_configuration nextConf; + t_sva_ace_offset newAceOffset; + t_bool isAceOffsetNeedUpdate; + t_uint32 currentConfCounter; + t_sva_buffer_type bufferType; + t_sva_push_mode pushMode; + t_sva_buffer_id bufferId; + t_sva_gb_conf_state confState; +} t_sva_gb_conf_handle; + +/* + * Define the one element packet structure. Structure size + * must be a multiple of 16 bytes. + */ +typedef struct { + t_uint32 payloadSize; /*must be set to 1*/ + t_uint16 address; + t_uint16 value; + t_uint32 padding1[2]; +} t_sva_gb_packet; + +/* + * Define the descriptor of a Grab service instance + */ +typedef struct { + t_sva_gb_state state; + t_sva_service_id serviceId; + t_sva_gb_activate_state activateState; + t_sva_gb_conf_handle confHandle; + t_sva_gb_dependencies_desc defaultDep; + t_sva_gb_fifo_dep outputImageFifos; + t_sva_gb_fifo_dep paramFifos; + t_sva_gb_fifo_dep snapshotImageFifos; + t_sva_fifo subtasksDependencyFifo; + t_sva_tm_subtask_id subtasksIdArray[SUBTASK_GRAB_NUMBER]; + t_uint32 subtasksConfCounter[SUBTASK_GRAB_NUMBER]; + t_sva_tm_subtask_list_id subtasksListId; + t_sva_preprocessor_status status; + t_bool isIrpMode; + t_sva_block_id irpPacketId; + t_bool grabHQEnable; + t_sva_block_id idpBlockId; + t_system_address idpBlockAddr; + t_sva_gb_grid_buff_dep_to_be_resolved gridBuffDepToBeResolved; + t_sva_gb_image_buff_dep_to_be_resolved imageBuffDepToBeResolved; + t_physical_address gridDayPhyAddr; + t_physical_address gridCoolPhyAdd; + t_physical_address gridIncPhyAddr; + t_physical_address gridHorPhyAddr; +} t_sva_gb_descriptor; + +#ifdef __DEBUG + /******************************************************************************/ + /* Trace Types definitions */ + /******************************************************************************/ + typedef struct { + t_sva_tm_virtual_hw_event_id event; + t_uint32 systemTime; + t_sva_tm_subtask_id subtaskId; + t_sva_service_id serviceId; + } t_sva_gb_debug_event_desc; + typedef struct { + t_uint32 padding[3]; + t_uint32 nbOfEventReceived; + t_sva_gb_debug_event_desc eventDebugDesc[LOG_DEPTH]; + } t_sva_gb_debug_events; + + typedef struct { + t_sva_service_cmd_id command; + t_uint32 systemTime; + t_uint32 parameter; + t_uint32 padding; + } t_sva_gb_debug_command_desc; + typedef struct { + t_uint32 padding[3]; + t_uint32 nbOfCommandReceived; + t_sva_gb_debug_command_desc commandDebugDesc[LOG_DEPTH]; + } t_sva_gb_debug_commands; + + typedef struct { + t_sva_gb_state state;/*state before transition occur*/ + t_sva_gb_transition transition; + t_uint32 systemTime; + t_sva_gb_activate_state activateState;/*state before transition occur*/ + } t_sva_gb_debug_transition_desc; + typedef struct { + t_uint32 padding[3]; + t_uint32 nbOfTransitionReceived; + t_sva_gb_debug_transition_desc transitionDebugDesc[LOG_DEPTH]; + } t_sva_gb_debug_transitions; +#endif + +#ifdef __cplusplus +} /* allow C++ to use these headers */ +#endif /* __cplusplus */ + +#endif /* __INC_SVA_GRABP_H */ +/* End of file - sva_grabP.h */ --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_bufferlistmgt.h @@ -0,0 +1,87 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ +#ifndef __INC_SVA_BUFFERLISTMGT_H +#define __INC_SVA_BUFFERLISTMGT_H + +#include "hcl_defs.h" +#include "sva.h" +#include "sva_buffermgt.h" + +/******************************************************************************/ +/* Constants definitions */ +/******************************************************************************/ + +/* + * Define the special invalid value for t_sva_buffer_list_id variables + */ +#define INVALID_BUFFER_LIST_ID (MASK_ALL32) + +/******************************************************************************/ +/* Types definitions */ +/******************************************************************************/ +/* + * Define the type used to identify/reference a list of buffer + */ +typedef t_uint32 t_sva_buffer_list_id; + + +/* + * Definition of symbol used by Buffer List Management routines to return error + */ +typedef enum { + /* TBD */ + SVA_BLM_ERROR = SVA_BLM_LAST_ERROR, + SVA_BLM_UNKNOWN_IDENTIFIER, + SVA_BLM_LIST_NOT_EMPTY, + SVA_BLM_LIST_EMPTY, + SVA_BLM_NO_MORE_BUFFER_LIST_ID, + SVA_BLM_OK = HCL_OK +} t_sva_blm_error; + +typedef enum +{ + BEGIN_OF_FIRST_BUFFER, + END_OF_LAST_BUFFER +} t_sva_blm_boundary; + +/******************************************************************************* +* PUBLIC Functions +*******************************************************************************/ + +// init +PUBLIC t_sva_blm_error sva_BLM_Init(void); +//create an id for a list +PUBLIC t_sva_blm_error sva_BLM_CreateBufferList(t_sva_buffer_list_id *); +//add a new element at the end of the list: a new bitstream buffer is available for service ; it is defined by its start address and also its end address +PUBLIC t_sva_blm_error sva_BLM_AddBufferInList(t_sva_buffer_list_id, t_sva_buffer_id); +//remove first element at list start: a bitstream buffer has been fully decoded and can be removed from the list +PUBLIC t_sva_blm_error sva_BLM_RemoveBufferFromList(t_sva_buffer_list_id, t_sva_buffer_id *); +//delete buffer list +PUBLIC t_sva_blm_error sva_BLM_DeleteBufferList (const t_sva_buffer_list_id ); +//get physical address of first element of the list +PUBLIC t_sva_blm_error sva_BLM_GetBufferListPhysicalAddress (t_sva_buffer_list_id, t_physical_address *); +//modify start/stop address of buffer list's element +PUBLIC t_sva_blm_error sva_BLM_UpdateBufferMemoryBoundaryInBufferList (t_sva_buffer_list_id, t_sva_blm_boundary , t_sint32); +//Get the index of the buffer list's handle from a given buffer +PUBLIC t_sva_blm_error sva_BLM_GetBufferListIndex (t_sva_buffer_list_id, t_sva_buffer_id, t_uint32 *); + + +#endif /* __INC_SVA_BUFFERLISTMGT_H */ +// End of file - sva_bufferlistmgt.h + --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_buffermgt.h @@ -0,0 +1,111 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ + +#ifndef __INC_SVA_BM_H +#define __INC_SVA_BM_H + +#include "hcl_defs.h" +#include "sva.h" +#include "svap.h" +#include "sva_memorymgt.h" +#include "sva_timemgt.h" +#include "sva_host_interface.h" +#include "sva_bufferlistmgtp.h" + + +/******************************************************************************/ +/* Constants definitions */ +/******************************************************************************/ + +/* + * Define the special invalid value for t_sva_buffer_id variables + */ +#define INVALID_BUFFER_ID MASK_ALL32 + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/******************************************************************************/ +/* Types definitions */ +/******************************************************************************/ +/* + * Definition of symbol used by Buffer Management routines to return error + */ +typedef enum { + SVA_BM_ERROR = SVA_BM_LAST_ERROR, + SVA_BM_UNKNOWN_BUFFER_ID, + SVA_BM_OK = SVA_OK +} t_sva_bm_error; + +/* + * Definition of structure inside buffer header that manages the buffer link list. + * These data are mainly initialized/used by buffer list mgt block. + */ + +/* IMPORTANT : folowing struture must match an 8-words boundary */ +typedef struct +{ + t_sva_bitstream_buf_link bufferLink; // structure containing bitstream buffer link informations + /* WARNING : Keep this field at first position, otherwise buffer-list management won't work anymore !! */ + + t_sva_buffer_id nextBufferId; // next buffer Id in the list + t_sva_buffer_id prevBufferId; // previous buffer Id in the list + + t_uint32 bufferListId; + t_uint32 index; // align structure size to 16 bytes boundaries +} t_sva_bm_list_elem; // sizeof(t_sva_bm_list_elem) = 8 words + +typedef t_sva_bm_list_elem t_sva_bm_list_info[NB_MAX_MANAGED_BUFFER_LIST]; + + + +/******************************************************************************* +* PUBLIC Functions +*******************************************************************************/ +PUBLIC t_sva_bm_error sva_BM_Init(void); +/* Buffers Management (Memory point of view) */ +/* Implemented here but prototyped into sva.h */ +/* PUBLIC t_sva_error SVA_DefineBuffer(t_sva_buffer_type, t_size, t_system_address, t_sva_buffer_id *); */ +/* PUBLIC t_sva_error SVA_RemoveBuffer(t_sva_buffer_id ); */ +/* PUBLIC t_sva_error SVA_AllocBuffer(t_sva_buffer_type, t_size, t_system_address *, t_sva_buffer_id *); */ +/* PUBLIC t_sva_error SVA_FreeBuffer(t_sva_buffer_id ); */ +PUBLIC t_sva_bm_error sva_BM_GetStatus(t_uint32 *); + +/* Buffers Management Information routines */ +/* PUBLIC t_sva_error SVA_GetBufferStatus(t_sva_buffer_id, t_sva_buffer_status *); */ /* Implemented here but prototyped into sva.h */ +PUBLIC t_sva_bm_error sva_BM_UpdateBufferStatus(t_sva_buffer_id, t_sva_buffer_state, t_sva_ticks); +PUBLIC t_sva_bm_error sva_BM_GetBufferLogicalAddress(t_sva_buffer_id, t_logical_address*); +PUBLIC t_sva_bm_error sva_BM_GetBufferPhysicalAddress(t_sva_buffer_id, t_physical_address*); +PUBLIC t_sva_bm_error sva_BM_GetBufferSystemAddress(t_sva_buffer_id, t_system_address *); +PUBLIC t_sva_bm_error sva_BM_GetBufferType(t_sva_buffer_id, t_sva_buffer_type*); +PUBLIC t_sva_bm_error sva_BM_GetBufferSize(t_sva_buffer_id, t_size*); + +/* PUBLIC t_sva_error SVA_SetBufferData(t_sva_buffer_id, t_uint32); */ +/* PUBLIC t_sva_error SVA_GetBufferData(t_sva_buffer_id, t_uint32*); */ +PUBLIC t_sva_bm_error sva_BM_GetBufferLinkInformation( t_sva_buffer_id, t_sva_bm_list_elem **, t_physical_address *); +PUBLIC t_sva_bm_error sva_BM_SetBufferLinkInformation( t_sva_buffer_id, t_sva_bm_list_elem *, t_uint32); + + +#ifdef __cplusplus +} /* allow C++ to use these headers */ +#endif /* __cplusplus */ + +#endif /* __INC_SVA_BM_H */ +/* End of file - sva_bufferMgt.h */ --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_capabilities.h @@ -0,0 +1,46 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ + +#ifndef __INC_SVA_CAPABILITIES_H +#define __INC_SVA_CAPABILITIES_H + +#include "hcl_defs.h" +#include "sva.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/******************************************************************************/ +/* Types definitions */ +/******************************************************************************/ + + +/******************************************************************************* +* PUBLIC Functions +*******************************************************************************/ + + + +#ifdef __cplusplus +} /* allow C++ to use these headers */ +#endif /* __cplusplus */ + +#endif /* __INC_HV_CAPABILITIES_H */ +/* End of file - sva_capabilities.h */ --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_dc_mpeg2.h @@ -0,0 +1,181 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ + +#ifndef __INC_SVA_DC_Mpeg2_H +#define __INC_SVA_DC_Mpeg2_H + +#include "hcl_defs.h" +#include "sva_decode.h" +#include "../sva_dc_algo.h" +#include "sva.h" +#include "sva_decodep.h" + +/******************************************************************************/ +/* Constants definitions */ +/******************************************************************************/ + +#define START_CODE_VALUE_SEQUENCE_HEADER 0x000001B3 +#define START_CODE_VALUE_SEQUENCE_EXTENSION 0x000001B5 +#define START_CODE_VALUE_PICTURE_HEADER 0x00000100 +#define START_CODE_VALUE_GOP 0x000001B8 + + +#define OFFSET_VIDEOSTARTMARKER_GOBLAYER 7 //6 bytes 50bits +#define MPEG2_DECODE_MAX_FIFO_SIZE DECODE_MAX_FIFO_SIZE + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/******************************************************************************/ +/* Types definitions */ +/******************************************************************************/ + +/***********************************/ +/*** Structure definition ***/ +/***********************************/ +typedef struct { + t_sva_buffer_id bitstreamBuffer; + t_sva_buffer_id fwdReferenceImage; + t_sva_buffer_id bwdReferenceImage; + t_sva_Mpeg2_picture_type pictureType; + t_uint16 pictureStructure; +} t_sva_Mpeg2_reference_handler; +/* + * Define the structure used to manage the subtasks dependency + */ +typedef struct { + t_sva_dc_dependencies_state referenceDep;//reference dependency + t_sva_dc_dependencies_state outputDeblockingDep; + t_sva_dc_dependencies_state outputInfosDep; +} t_sva_dc_Mpeg2_dependencies_desc; + +typedef struct { + t_sva_image_desc imageDesc; + t_sva_codec_mode codecMode; + t_sva_video_decoder_algo_Mpeg2_configuration_params staticParams; + t_sva_fifo fifoDynamicParams; //type: t_sva_decoder_algo_mpeg2_header_infos + t_sva_fifo fifoBitstream; //type: t_sva_bitstream_desc + t_sva_fifo referenceHandlerFifo; + t_sva_fifo referenceHandlerOutFifo; + t_sva_fifo refImageFifo; // Current reference Image FIFO + t_sva_fifo prevRefImageFifo; // Previous reference Image FIFO + t_sva_fifo fakeBitstreamFifo; + t_sva_dc_Mpeg2_dependencies_desc defaultDep; // default mpeg2 dependencies + t_sva_dc_fifo_dep Mpeg2Dep; + t_sva_vdc_Mpeg2_param_out lastFrameMpeg2ParamOut; + t_sva_vdc_Mpeg2_param_out statisticalMpeg2ParamOut; + t_system_address paramInOutAddress; + t_sva_block_id paramInOutBlockId; + t_sva_buffer_id lastRefBuffer; // Last reference Buffer ID + t_sva_buffer_id lastPrevRefBuffer; // Last Previous reference Buffer ID + t_system_address addr_mv_history_buffer; + t_sva_buffer_id addr_mv_history_buffer_id; +} t_sva_Mpeg2_desc; + +typedef enum { + SVA_DC_MPEG2_XXXX = SVA_LAST_ERROR, + SVA_DC_MPEG2_FIFO_LINKED_ERROR, + SVA_DC_MPEG2_FIFO_FULL_ERROR, + SVA_DC_MPEG2_YYYY, + SVA_DC_MPEG2_UNEXPECTED_API_CALL, + SVA_DC__MPEG2_ALGO_OK = HCL_OK +} t_sva_dc_mpeg2_algo_error; + +typedef struct { + t_uint32 Mpeg2SeqHeaderStartCode; + t_uint32 Mpeg2SeqExtensionStartCode; + t_uint32 Mpeg2GropuofpictureStartCode; + t_uint32 Mpeg2PicHeaderStartCode; +} t_Mpeg2_start_code; + +typedef struct { + t_sva_service_id serviceId; + t_sva_buffer_id bitstreamBuffer; + t_uint32 byteOffset; + t_uint32 bitOffset; + t_sva_video_decoder_algo_Mpeg2_header_infos headerInfos; +} t_sva_Mpeg2_SetHeaderInfosParam; + + +/******************************************************************************/ +/* PUBLIC Functions */ +/******************************************************************************/ +PUBLIC t_sva_error sva_DC_Mpeg2_Init(t_sva_service_instance_num, t_sva_codec_mode, t_sva_image_desc, const t_sva_dc_algo_configuration_params *); +PUBLIC t_sva_error sva_DC_Mpeg2_GetMemoryNeeds(t_sva_service_instance_num, t_size *); + +PUBLIC t_sva_error sva_DC_Mpeg2_ProvideMemoryNeeds( t_sva_service_instance_num ); +PUBLIC t_sva_error sva_DC_Mpeg2_Close(t_sva_service_instance_num); +PUBLIC t_sva_error sva_DC_Mpeg2_GetNextFrameParamsIn(t_sva_service_instance_num, t_sva_dc_algo_params_in *); +PUBLIC t_sva_error sva_DC_Mpeg2_GetNextFrameParamsInOut(t_sva_service_instance_num, t_sva_dc_algo_params_inout *); +PUBLIC t_sva_error sva_DC_Mpeg2_SetOutputParams(t_sva_service_instance_num, const t_sva_dc_algo_params_out *); +PUBLIC t_sva_error sva_DC_Mpeg2_GetNextFrameAddr(t_sva_service_instance_num, t_physical_address *, t_uint32 *, t_sva_buffer_id *); +PUBLIC t_sva_error sva_DC_Mpeg2_GetStatus(t_sva_service_instance_num, t_sva_dc_algo_status *, t_sva_dc_algo_status *); +PUBLIC t_sva_error sva_DC_Mpeg2_AreNextFrameInfosAvailable(t_sva_service_instance_num, t_bool *); +PUBLIC t_size sva_DC_Mpeg2_GetNextFrameParamsInSize(t_sva_service_instance_num); +PUBLIC t_size sva_DC_Mpeg2_GetNextFrameParamsInOutSize(t_sva_service_instance_num); +PUBLIC t_size sva_DC_Mpeg2_GetOutputParamsSize(t_sva_service_instance_num); + +PUBLIC t_sva_error sva_DC_Mpeg2_PushBitstreamBuffer(t_sva_service_instance_num, t_sva_buffer_id); +PUBLIC t_sva_error sva_DC_Mpeg2_GetStartCodeValue(t_uint32 *); +PUBLIC t_sva_error sva_DC_Mpeg2_GetLastErrorType (t_sva_service_instance_num, t_uint16 *); +PUBLIC t_sva_error sva_DC_Mpeg2_FlushFifos(t_sva_service_instance_num); +PUBLIC t_sva_error sva_DC_Mpeg2_DeleteFake(t_sva_service_instance_num); +PUBLIC t_sva_error sva_DC_Mpeg2_SubTaskFieldsFullUpdate ( t_sva_service_instance_num, t_sva_buffer_id *); +PUBLIC t_sva_error sva_DC_Mpeg2_GetParamsBufferSize(t_sva_service_instance_num, t_sva_push_mode, t_sva_filter_mode, t_uint32, t_uint32, t_size *); +PUBLIC t_sva_error sva_DC_Mpeg2_Push(t_sva_service_instance_num, t_sva_buffer_type, t_sva_buffer_id ); +PUBLIC t_sva_error sva_DC_Mpeg2_DispatchEOT( + t_sva_service_instance_num, + t_sva_tm_subtask_id, + t_sva_event_desc*, + t_sva_service_id, + t_uint32, + t_uint32, + t_uint32 *, + t_uint32, + t_sva_buffer_list_id); +PUBLIC t_sva_error sva_DC_Mpeg2_HandleFakeEvent( t_sva_tm_virtual_hw_event_id , + t_sva_service_id , + t_sva_tm_subtask_id , + t_uint32 , + t_uint32 , + t_uint8 , + t_uint32 *, + t_sva_event_desc *); +PUBLIC t_sva_error sva_DC_Mpeg2_TryToInitBitstreamFields(t_sva_service_instance_num, t_sva_buffer_id *); +PUBLIC t_sva_error sva_DC_Mpeg2_FlushBitstreams(t_sva_service_instance_num); +PUBLIC t_sva_error sva_DC_Mpeg2_InitHeaderInfos(t_sva_service_instance_num); +PUBLIC t_sva_error sva_DC_Mpeg2_GSetHeaderInfos(t_sva_service_instance_num, t_sva_service_id, t_sva_buffer_id, t_uint32, t_uint32, const t_sva_header_infos *); +PUBLIC t_sva_error sva_DC_Mpeg2_AssertEndOfBitstream(t_sva_service_instance_num, t_sva_service_id); +PUBLIC t_sva_error sva_DC_Mpeg2_ResolveDependencies(t_sva_service_instance_num); +PUBLIC t_sva_error sva_DC_Mpeg2_GetFWFeatures (t_sva_service_instance_num, t_sva_fw_features*); +PUBLIC t_sva_error sva_DC_Mpeg2_GetSubTaskType(t_sva_service_instance_num, t_sva_tm_subtask_type*); +PUBLIC t_sva_error sva_DC_Mpeg2_GetPPPType(t_sva_service_instance_num, t_sva_tm_postprocessing_type*); +PUBLIC t_sva_error sva_DC_Mpeg2_GetNbBufferListByFrame(t_uint32*); +PUBLIC t_sva_error sva_DC_Mpeg2_CreateAndConfigSubtasksList(t_sva_service_instance_num, t_sva_service_id ); +PUBLIC t_bool sva_DC_Mpeg2_AreAllDependanciesResolved(t_sva_dc_dependencies_desc *, t_sva_dc_Mpeg2_dependencies_desc *); +PUBLIC t_bool sva_DC_Mpeg2_CheckInputDep(t_sva_service_instance_num); +PUBLIC t_bool sva_DC_Mpeg2_CheckOutputDep(t_sva_service_instance_num); + +#ifdef __cplusplus +} /* allow C++ to use these headers */ +#endif /* __cplusplus */ + +#endif /* __INC_sva_DC_Mpeg2_H */ +/* End of file - sva_dc_mpeg2.h */ --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_decode.h @@ -0,0 +1,97 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ + +#ifndef __INC_SVA_DECODE_H +#define __INC_SVA_DECODE_H + +#include "sva.h" +#include "svap.h" +#include "sva_taskmgt.h" + +/******************************************************************************/ +/* Constants definitions */ +/******************************************************************************/ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +// max number of setHeaderInfos consecutive calls +#define DECODE_MAX_FIFO_SIZE 16 + +/* + * Define the symbols used to identify the various errors of the Decode Module + */ +typedef enum { + SVA_DC_INVALID_TRANSITION = SVA_DC_LAST_ERROR, + SVA_DC_NO_MORE_AVAILABLE_INSTANCE, + SVA_DC_INVALID_INSTANCE_NB, + SVA_DC_INVALID_TASK_ID_NB, + SVA_DC_NOT_SUPPORTED, + SVA_DC_INVALID_CONTROL_PARAM, + SVA_DC_INVALID_PUSH, + SVA_DC_INVALID_BUFFER_TYPE, + SVA_DC_INVALID_BUFFER_SIZE, + SVA_DC_INVALID_CONFIGURATION, + SVA_DC_UNKNOWN_CMD_ID, + SVA_DC_UNEXPECTED_HW_EVENT, + SVA_DC_TI_LINKED_ERROR, + SVA_DC_BLM_LINKED_ERROR, + SVA_DC_BM_LINKED_ERROR, + SVA_DC_MM_LINKED_ERROR, + SVA_DC_FF_LINKED_ERROR, + SVA_DC_TM_LINKED_ERROR, + SVA_DC_NULL_POINTER_PARAMETER, + SVA_DC_FIFO_NOT_EMPTY, + SVA_DC_OK = HCL_OK +} t_sva_dc_error; + + + +/******************************************************************************* +* PUBLIC Functions +*******************************************************************************/ + +PUBLIC t_sva_error sva_DC_Init( void ); +PUBLIC t_sva_error sva_DC_Reset( t_sva_service_id ); +PUBLIC t_sva_error sva_DC_Create( t_sva_service_id *); +PUBLIC t_sva_error sva_DC_Control(t_sva_service_id, t_sva_service_cmd_id, t_uint32 ); +PUBLIC t_sva_error sva_DC_Push(t_sva_service_id, t_sva_buffer_id, t_sva_push_mode, t_sva_buffer_type ); +PUBLIC t_sva_error sva_DC_DispatchVirtualHwEvent(t_sva_tm_virtual_hw_event_id, t_sva_service_id, t_sva_tm_subtask_id, t_uint32, t_uint32, t_uint8, t_sva_event_desc *, t_uint32 *); +PUBLIC t_sva_error sva_DC_ProvideInternalNeeds( t_sva_service_id); +PUBLIC t_sva_error sva_DC_GetInternalNeeds(t_sva_service_id, t_size *); +PUBLIC t_sva_error sva_DC_Activate(t_sva_service_id, t_sva_service_mode, t_sva_fw_id *); +PUBLIC t_sva_error sva_DC_Inactivate(t_sva_service_id); +PUBLIC t_sva_error sva_DC_Delete(t_sva_service_id ); +PUBLIC t_sva_error sva_DC_SetHeaderInfos( t_sva_service_id, t_sva_buffer_id, t_uint32, t_uint32, const t_sva_header_infos *); +PUBLIC t_sva_error sva_DC_AssertEndOfBitstream(t_sva_service_id); +PUBLIC t_sva_error sva_DC_GetParamsBufferSize(t_sva_service_id ,t_sva_push_mode ,t_size *); +PUBLIC t_sva_error sva_DC_CheckServiceId(t_sva_service_id ); +//t_sva_decoder_configuration is in sva.h +// function is sva.h +//PUBLIC t_sva_error sva_DC_ConfigureVideoDecoder( t_sva_service_id, t_sva_decoder_configuration); +//PUBLIC t_sva_error sva_DC_GetVideoDecoderStatus(t_sva_service_id, t_sva_decoder_status *); +//PUBLIC t_sva_error sva_DC_UpdateVideoDecoderParams(t_sva_service_id, t_sva_update_cmd_type, t_sva_decoder_param_id, t_uint32 ); + +#ifdef __cplusplus +} /* allow C++ to use these headers */ +#endif /* __cplusplus */ + +#endif /* __INC_SVA_DECODE_H */ +/* End of file - sva_decode.h */ --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_display.h @@ -0,0 +1,99 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ + +#ifndef __INC_SVA_DISPLAY_H +#define __INC_SVA_DISPLAY_H + + +#include "hcl_defs.h" +#include "sva.h" +#include "svap.h" +#include "sva_taskmgt.h" +#include "sva_service.h" + + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* + * Define the symbols used to identify the various errors of the Display Module + */ + +//typedef t_uint32 t_sva_dp_error; + + +typedef enum { + SVA_DP_INVALID_TRANSITION = SVA_DP_LAST_ERROR, + SVA_DP_NO_MORE_AVAILABLE_INSTANCE, + SVA_DP_INVALID_INSTANCE_NB, + SVA_DP_INVALID_TASK_ID_NB, + SVA_DP_NOT_SUPPORTED, + SVA_DP_INVALID_CONTROL_PARAM, + SVA_DP_INVALID_PUSH, + SVA_DP_INVALID_BUFFER_TYPE, + SVA_DP_INVALID_BUFFER_SIZE, + SVA_DP_INVALID_CONFIGURATION, + SVA_DP_UNKNOWN_CMD_ID, + SVA_DP_UNEXPECTED_HW_EVENT, + SVA_DP_SYNCHRO_INFO_NOT_AVAILABLE, + SVA_DP_TI_LINKED_ERROR, + SVA_DP_BM_LINKED_ERROR, + SVA_DP_MM_LINKED_ERROR, + SVA_DP_FF_LINKED_ERROR, + SVA_DP_TM_LINKED_ERROR, + SVA_DP_NULL_POINTER_PARAMETER, + SVA_DP_FIFO_NOT_EMPTY, + SVA_DP_OK = HCL_OK +} t_sva_dp_error; + + +/******************************************************************************* +* PUBLIC Functions +*******************************************************************************/ + +PUBLIC t_sva_error sva_DP_Init( void ); +PUBLIC t_sva_error sva_DP_Reset( t_sva_service_id ); +PUBLIC t_sva_error sva_DP_Create( t_sva_service_id *); +PUBLIC t_sva_error sva_DP_Control(t_sva_service_id, t_sva_service_cmd_id, t_uint32 ); +PUBLIC t_sva_error sva_DP_Push(t_sva_service_id, t_sva_buffer_id, t_sva_push_mode, t_sva_buffer_type, t_sva_timestamp ); + +PUBLIC t_sva_error sva_DP_DispatchVirtualHwEvent(t_sva_tm_virtual_hw_event_id, t_sva_service_id, t_sva_tm_subtask_id, t_uint32, t_uint32, t_uint8, t_sva_event_desc *, t_uint32 *); +PUBLIC t_sva_error sva_DP_ProvideInternalNeeds( t_sva_service_id); +PUBLIC t_sva_error sva_DP_GetInternalNeeds(t_sva_service_id, t_size *); +PUBLIC t_sva_error sva_DP_Activate(t_sva_service_id, t_sva_service_mode, t_sva_fw_id *); +PUBLIC t_sva_error sva_DP_Inactivate(t_sva_service_id); +PUBLIC t_sva_error sva_DP_Delete(t_sva_service_id ); +PUBLIC t_sva_error sva_DP_GetParamsBufferSize(t_sva_service_id ,t_sva_push_mode,t_size *); +PUBLIC t_sva_dp_error sva_DP_ResolveDependencies(t_sva_service_instance_num); + + +//t_sva_postprocessor_configuration is in sva.h +// function is sva.h +//PUBLIC t_sva_error SVA_ConfigurePostProcessor( t_sva_service_id, t_sva_postprocessor_configuration); + +//t_sva_postprocessor_param_id is in sva.h +//PUBLIC t_sva_error SVA_UpdatePostProcessorParams(t_sva_service_id, t_sva_update_cmd_type, t_sva_postprocessor_param_id, t_uint32); + + +#ifdef __cplusplus +} /* allow C++ to use these headers */ +#endif /* __cplusplus */ + +#endif --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_encode.h @@ -0,0 +1,90 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ + +#ifndef __INC_SVA_ENCODE_H +#define __INC_SVA_ENCODE_H + +#include "sva.h" +#include "svap.h" +#include "sva_taskmgt.h" + +/******************************************************************************/ +/* Constants definitions */ +/******************************************************************************/ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* + * Define the symbols used to identify the various errors of the encode Module + */ +typedef enum { + SVA_EC_INVALID_TRANSITION = SVA_EC_LAST_ERROR, + SVA_EC_NO_MORE_AVAILABLE_INSTANCE, + SVA_EC_INVALID_INSTANCE_NB, + SVA_EC_INVALID_TASK_ID_NB, + SVA_EC_NOT_SUPPORTED, + SVA_EC_INVALID_CONTROL_PARAM, + SVA_EC_INVALID_PUSH, + SVA_EC_INVALID_BUFFER_TYPE, + SVA_EC_INVALID_BUFFER_SIZE, + SVA_EC_INVALID_CONFIGURATION, + SVA_EC_UNKNOWN_CMD_ID, + SVA_EC_UNEXPECTED_HW_EVENT, + SVA_EC_SYNCHRO_INFO_NOT_AVAILABLE, + SVA_EC_TI_LINKED_ERROR, + SVA_EC_BM_LINKED_ERROR, + SVA_EC_MM_LINKED_ERROR, + SVA_EC_FF_LINKED_ERROR, + SVA_EC_TM_LINKED_ERROR, + SVA_EC_NULL_POINTER_PARAMETER, + SVA_EC_FIFO_NOT_EMPTY, + SVA_EC_OK = HCL_OK +} t_sva_ec_error; + + +/******************************************************************************* +* PUBLIC Functions +*******************************************************************************/ + +PUBLIC t_sva_error sva_EC_Init( t_sva_block_id, t_size); +PUBLIC t_sva_error sva_EC_Reset( t_sva_service_id ); +PUBLIC t_sva_error sva_EC_Create( t_sva_service_id *); +PUBLIC t_sva_error sva_EC_Control(t_sva_service_id, t_sva_service_cmd_id, t_uint32 ); +PUBLIC t_sva_error sva_EC_Push(t_sva_service_id, t_sva_buffer_id, t_sva_push_mode, t_sva_buffer_type, t_sva_timestamp ); +PUBLIC t_sva_ec_error sva_EC_DispatchVirtualHwEvent(t_sva_tm_virtual_hw_event_id, t_sva_service_id, t_sva_tm_subtask_id, t_uint32, t_uint32, t_uint8, t_sva_event_desc *, t_uint32 *); +PUBLIC t_sva_error sva_EC_ProvideInternalNeeds( t_sva_service_id); +PUBLIC t_sva_error sva_EC_GetInternalNeeds(t_sva_service_id, t_size *); +PUBLIC t_sva_error sva_EC_Activate(t_sva_service_id, t_sva_service_mode, t_sva_fw_id *); +PUBLIC t_sva_error sva_EC_Inactivate(t_sva_service_id); +PUBLIC t_sva_error sva_EC_Delete(t_sva_service_id ); +PUBLIC t_sva_error sva_EC_GetParamsBufferSize(t_sva_service_id, t_sva_push_mode, t_size *); +//t_sva_video_encoder_configuration is in sva.h +// function is sva.h +//PUBLIC t_sva_error SVA_ConfigureVideoEncoder( t_sva_service_id, t_sva_video_encoder_configuration); +//PUBLIC t_sva_error SVA_GetVideoEncoderStatus(t_sva_service_id, t_sva_video_encoder_status *); +//PUBLIC t_sva_error SVA_UpdateVideoEncoderParams(t_sva_service_id, t_sva_update_cmd_type, t_sva_video_encoder_param_id, t_uint32 ); + +#ifdef __cplusplus +} /* allow C++ to use these headers */ +#endif /* __cplusplus */ + +#endif /* __INC_SVA_ENCODE_H */ +/* End of file - sva_encode.h */ --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_eventmgt.h @@ -0,0 +1,97 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ + +#ifndef __INC_SVA_EM_H +#define __INC_SVA_EM_H + +#include "hcl_defs.h" +#include "sva.h" +#include "svap.h" +#include "sva_hwp.h" + + +/******************************************************************************/ +/* Constants definitions */ +/******************************************************************************/ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/******************************************************************************/ +/* Types definitions */ +/******************************************************************************/ +/* + * Define the errors for the module + */ + +typedef enum { + SVA_EM_ERROR = SVA_EM_LAST_ERROR, + SVA_EM_NO_MORE_FIFO_ID, + SVA_EM_FIFO_ID_ALREADY_FREE, + SVA_EM_OK = SVA_OK +}t_sva_em_error; + +/* + * Define the various events those can be dispatched by event management module + */ +typedef enum { + BOT_HW_EVENT = ISR_BOT_MASK, + EOT_HW_EVENT = ISR_EOT_MASK, + ACK_HW_EVENT = ISR_ACK_MASK, + EOW_HW_EVENT = ISR_EOW_MASK, + BOF_HW_EVENT = ISR_BOF_MASK, + UBU_HW_EVENT = ISR_UBU_MASK, + GS_HW_EVENT = ISR_GS_MASK, + BOW_HW_EVENT = ISR_BOW_MASK, + EOF_HW_EVENT = ISR_CER_MASK, + ERR_HW_EVENT = ISR_ERR_MASK, + EOK_HW_EVENT = ISR_EOK_MASK, + EOI_HW_EVENT = IIS_EOI_MASK << SHIFT_BYTE1, + BERR_HW_EVENT= IIS_BE_MASK << SHIFT_BYTE1 +} t_sva_hw_event_id; + + + + +/******************************************************************************* +* PUBLIC Functions +*******************************************************************************/ +PUBLIC t_sva_error sva_EM_Init(t_logical_address, t_logical_address); +PUBLIC t_sva_error sva_EM_Create(t_sva_service_id*); +PUBLIC t_sva_error sva_EM_GetInternalNeeds(t_size *); +PUBLIC t_sva_error sva_EM_ProvideInternalNeeds(t_sva_service_id ); +PUBLIC t_sva_error sva_EM_Delete(t_sva_service_id); + +PRIVATE t_sva_error sva_ProcessIRQSrc_X(t_sva_irq_status *); +/* Described into sva.h +PUBLIC void SVA_GetIRQSrcStatus(t_sva_irq_src, t_sva_irq_status *); +PUBLIC t_bool SVA_IsIRQSrcActive(t_sva_irq_src, t_sva_irq_status *); +PUBLIC t_sva_error SVA_ProcessIRQSrc(t_sva_irq_status *); +PUBLIC t_bool SVA_AreServicePendingEvents(t_sva_service_id); +PUBLIC t_sva_error SVA_GetServicePendingEvents(t_sva_service_id, t_sva_event_desc *); +PUBLIC t_sva_error SVA_AcknowledgeEvent(const t_sva_event_desc *); +*/ + +#ifdef __cplusplus +} /* allow C++ to use these headers */ +#endif /* __cplusplus */ + +#endif /* __INC_SVA_EM_H */ +/* End of file - sva_eventmgt.h */ --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_fifo.h @@ -0,0 +1,335 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ + +#ifndef __INC_SVA_FIFO_H +#define __INC_SVA_FIFO_H + +#include "hcl_defs.h" +#include "sva_internalneeds.h" +#include "svap.h" + +/******************************************************************************/ +/* Constants definitions */ +/******************************************************************************/ +/* + * Definition of the macro providing the memory needs + * to build a fifo of elements with the type + * Takes 3 params: + * - typeName: C type of the fifo element (width of the fifo) + * - nbElem: size (depth/height) of the fifo + * - (output) computed memory needs size + */ +#define GET_FIFO_MEMORY_NEEDS(typeName, nbElem, memoryNeedsSize) \ + do { \ + t_uint16 mask = MASK_BIT10; \ + while(((t_uint16)(nbElem) & mask) == 0) {mask >>=1;} \ + if ((nbElem) > mask) {mask <<= 1;} \ + memoryNeedsSize = (t_uint16)(mask * sizeof(typeName)); \ + /* align on word boundary */ \ + if ((memoryNeedsSize % 4)!=0) \ + {memoryNeedsSize += (4-(memoryNeedsSize % 4));} \ + } while(0) + +/* + * Definition of the macro allowing to define a fifo descriptor to its default value + * Takes 1 param: + * - fifoDesc: Fifo descriptor to init + */ +#define INIT_FIFO(fifoDesc) \ + do { \ + fifoDesc.readIndex = 0; \ + fifoDesc.writeIndex = 0; \ + fifoDesc.elemCount = 0; \ + fifoDesc.indexMask = 0; \ + fifoDesc.baseAddr = (t_logical_address)0; \ + } while(0) + +/* + * Definition of the macro allowing to create a new fifo (dynamically allocated) + * Takes 4 params: + * - typeName: C type of the fifo element (width of the fifo) + * - nbElem: size (depth/height) of the fifo + * - fifoDesc: Fifo descriptor to update + * - (output) error: raised error or SVA_FIFO_OK + */ +#define CREATE_FIFO(typeName, nbElem, fifoDesc, error) \ + do { \ + t_uint16 mask = MASK_BIT10; \ + fifoDesc.readIndex = 0; \ + fifoDesc.writeIndex = 0; \ + fifoDesc.elemCount = 0; \ + fifoDesc.indexMask = 0; \ + fifoDesc.baseAddr = (t_logical_address)0; \ + error=SVA_FIFO_ERROR; \ + if ((nbElem) !=0) \ + { \ + t_sva_in_error inError; \ + while(((t_uint16)(nbElem) & mask) == 0) {mask >>=1;} \ + if ((nbElem) > mask) {mask <<= 1;} \ + inError = sva_IN_AllocMemory(((t_uint32)mask * sizeof(typeName)), \ + &fifoDesc.baseAddr); \ + error = (t_sva_ff_error)((inError == SVA_IN_ERROR)?SVA_FIFO_ERROR:SVA_FIFO_OK); \ + fifoDesc.indexMask = (t_uint16)(mask - 1); \ + } \ + } while(0) + +/* + * Definition of the macro allowing to check if the given Fifo is EMPTY + */ +#define IS_FIFO_EMPTY(fifoDesc) \ + ((fifoDesc.elemCount == 0)?TRUE:FALSE) + +/* + * Definition of the macro allowing to check if the given Fifo is FULL + */ +#define IS_FIFO_FULL(fifoDesc) \ + ((fifoDesc.elemCount == (fifoDesc.indexMask + 1))?TRUE:FALSE) + + +/* + * Definition of the macro allowing to get the number of Fifo elems + */ +#define GET_FIFO_NB_ELEMS(fifoDesc) \ + (fifoDesc.elemCount) + +/* + * Definition of the macro allowing to add (push/write) a new elem into the given fifo + * Takes 3 params: + * - fifoDesc: Fifo descriptor + * - typeName: C type of the fifo element (use to cast pointer) + * - newFirstElem: new element to add to the fifo + * + * In order to provide a return value, we use multi-statement expressions + * (the last one is evaluated as return value) + */ +#define PUSH_FIFO_ELEM(fifoDesc, typeName, newFirstElem) \ + (t_sva_ff_error) ( \ + (fifoDesc.elemCount == (fifoDesc.indexMask + 1)) \ + ?SVA_FIFO_FULL \ + : \ + ( \ + ((typeName *)fifoDesc.baseAddr)[fifoDesc.writeIndex] = newFirstElem, \ + fifoDesc.writeIndex = (t_uint16)((fifoDesc.writeIndex + 1) & fifoDesc.indexMask), \ + fifoDesc.elemCount++, \ + SVA_FIFO_OK \ + ) \ + ) + +/* + * Definition of the macro allowing to read the first element of the given fifo + * N.B: This macro does not modify the Fifo, i.e the element remains into the fifo + * Takes 3 params: + * - fifoDesc: Fifo descriptor + * - typeName: C type of the fifo element (use to cast pointer) + * - elem: element to update with the read value + * + * In order to provide a return value, we use multi-statement expressions + * (the last one is evaluated as return value) + */ +#define READ_FIFO_ELEM(fifoDesc, typeName, elem) \ + (t_sva_ff_error) ( \ + elem = ((typeName *)fifoDesc.baseAddr)[fifoDesc.readIndex], \ + (fifoDesc.elemCount ==0)?SVA_FIFO_EMPTY:SVA_FIFO_OK \ + ) + +/* + * Definition of the macro allowing to update the first element of the given fifo + * This macro SHALL be used only for structured element + * Takes 4 params: + * - fifoDesc: Fifo descriptor + * - typeName: C type of the fifo element (use to cast pointer) + * - fieldName: name of the field to update ('.fieldName' format mandatory) + * - newFieldValue: new value to store into the given field + * + * In order to provide a return value, we use multi-statement expressions + * (the last one is evaluated as return value) + */ +#define UPDATE_FIFO_ELEM_FIELD(fifoDesc, typeName, fieldName, newFieldValue) \ + (t_sva_ff_error) ( \ + (fifoDesc.elemCount == 0) \ + ?SVA_FIFO_EMPTY \ + : \ + ( \ + ((typeName *)fifoDesc.baseAddr)[fifoDesc.readIndex]fieldName = newFieldValue, \ + SVA_FIFO_OK \ + ) \ + ) + +/* + * Definition of the macro allowing to pop (read/extract) the first element of the given fifo + * N.B: This macro modifies the Fifo, i.e the element is removed from the Fifo + * Takes 3 params: + * - fifoDesc: Fifo descriptor + * - typeName: C type of the fifo element (use to cast pointer) + * - elem: element to update with the read value + * + * In order to provide a return value, we use multi-statement expressions + * (the last one is evaluated as return value) + */ +#define POP_FIFO_ELEM(fifoDesc, typeName, elem) \ + (t_sva_ff_error) ( \ + (fifoDesc.elemCount == 0) \ + ?SVA_FIFO_EMPTY \ + : \ + ( \ + elem = ((typeName *)fifoDesc.baseAddr)[fifoDesc.readIndex], \ + fifoDesc.readIndex = (t_uint16)((fifoDesc.readIndex + 1) & fifoDesc.indexMask), \ + fifoDesc.elemCount--, \ + SVA_FIFO_OK \ + ) \ + ) + +/* + * Definition of the macro allowing to flush a fifo + * Takes 1 param: + * - fifoDesc: Fifo descriptor to flush + */ +#define FLUSH_FIFO(fifoDesc) \ + do { \ + fifoDesc.readIndex = 0; \ + fifoDesc.writeIndex = 0; \ + fifoDesc.elemCount = 0; \ + } while(0) + +/* + * Definition of the macro allowing to delete (desallocate) a previously created fifo + * Takes 1 param: + * - fifoDesc: Fifo descriptor + */ +#define DELETE_FIFO(fifoDesc) \ + ( \ + fifoDesc.readIndex = 0, \ + fifoDesc.writeIndex = 0, \ + fifoDesc.elemCount = 0, \ + fifoDesc.baseAddr = 0, \ + fifoDesc.indexMask = 0 \ + ) + + +/* + * Definition of the macro allowing to add (push/write) a new elem into the given fifo seen as a Lifo + * N.B: This macro manages the FIFO like a LIFO, i.e the new elem is added in order to be the first one to be poped + * Takes 3 params: + * - fifoDesc: Fifo descriptor + * - typeName: C type of the fifo element (use to cast pointer) + * - newFirstElem: new element to add to the fifo + * + * In order to provide a return value, we use multi-statement expressions + * (the last one is evaluated as return value) + */ +#define PUSH_REVERSE_FIFO_ELEM(fifoDesc, typeName, newFirstElem) \ + (t_sva_ff_error) ( \ + (fifoDesc.elemCount == (fifoDesc.indexMask + 1)) \ + ?SVA_FIFO_FULL \ + : \ + ( \ + fifoDesc.readIndex = (t_uint16)((fifoDesc.readIndex - 1) & fifoDesc.indexMask), \ + ((typeName *)fifoDesc.baseAddr)[fifoDesc.readIndex] = newFirstElem, \ + fifoDesc.elemCount++, \ + SVA_FIFO_OK \ + ) \ + ) + +/* + * Definition of the macro allowing to read the last element of the given fifo seen as a lifo + * N.B: This macro does not modify the Fifo, i.e the element remains into the fifo + * Takes 3 params: + * - fifoDesc: Fifo descriptor + * - typeName: C type of the fifo element (use to cast pointer) + * - elem: element to update with the read value + * + * In order to provide a return value, we use multi-statement expressions + * (the last one is evaluated as return value) + */ +#define READ_REVERSE_FIFO_ELEM(fifoDesc, typeName, elem) \ + (t_sva_ff_error) ( \ + (fifoDesc.elemCount == 0) \ + ?SVA_FIFO_EMPTY \ + : \ + ( \ + elem = ((typeName *)fifoDesc.baseAddr)[(t_uint16)((fifoDesc.writeIndex - 1) & fifoDesc.indexMask)], \ + SVA_FIFO_OK \ + ) \ + ) + +/* + * Definition of the macro allowing to pop (read/extract) the last element of the given fifo seen as a lifo + * N.B: This macro modifies the Fifo, i.e the element is removed from the Fifo + * Takes 3 params: + * - fifoDesc: Fifo descriptor + * - typeName: C type of the fifo element (use to cast pointer) + * - elem: element to update with the read value + * + * In order to provide a return value, we use multi-statement expressions + * (the last one is evaluated as return value) + */ +#define POP_REVERSE_FIFO_ELEM(fifoDesc, typeName, elem) \ + (t_sva_ff_error) ( \ + (fifoDesc.elemCount == 0) \ + ?SVA_FIFO_EMPTY \ + : \ + ( \ + fifoDesc.writeIndex = (t_uint16)((fifoDesc.writeIndex - 1) & fifoDesc.indexMask), \ + elem = ((typeName *)fifoDesc.baseAddr)[fifoDesc.writeIndex], \ + fifoDesc.elemCount--, \ + SVA_FIFO_OK \ + ) \ + ) + +/******************************************************************************/ +/* Macros definitions */ +/******************************************************************************/ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/******************************************************************************/ +/* Types definitions */ +/******************************************************************************/ +/* + * Definition of symbol used to return error related to Fifo management + */ +typedef enum { + SVA_FIFO_ERROR = SVA_FF_LAST_ERROR, + SVA_FIFO_FULL, + SVA_FIFO_EMPTY, + SVA_FIFO_OK = HCL_OK +} t_sva_ff_error; +/* + * Definition of the structure used to manage a Fifo + */ +typedef struct { +t_uint16 elemCount; +t_uint16 indexMask; +t_uint16 readIndex; +t_uint16 writeIndex; +t_logical_address baseAddr; +} t_sva_fifo; + +/******************************************************************************* +* PUBLIC Functions +*******************************************************************************/ + +#ifdef __cplusplus +} /* allow C++ to use these headers */ +#endif /* __cplusplus */ + +#endif /* __INC_SVA_FIFO_H */ +/* End of file - sva_fifo.h */ --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_fwmgt.h @@ -0,0 +1,180 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ + +#ifndef __INC_SVA_FM_H +#define __INC_SVA_FM_H + +#include "hcl_defs.h" +#include "sva_hwp.h" +#include "sva.h" +#include "svap.h" +#include "sva_memorymgt.h" + +/******************************************************************************/ +/* Constants definitions */ +/******************************************************************************/ +/* + * define invalid FW id that correspond to default FWId +*/ +#define SVA_FW_INVALID_ID MASK_ALL32 + +/* + * define maximum number of set feature for one fw +*/ +#define MAX_NB_SET_FEATURE 3 + +/* + * define all possible FW features +*/ +#define SVA_FW_FEAT_NONE 0 + +/* Postprocessing part */ +#define SVA_FW_FEAT_POST_PROCESSOR MASK_BIT0 +#define SVA_FW_FEAT_POST_PROCESSOR_RASTER_TO_MB MASK_BIT12 + +/* Preprocessing part */ +#define SVA_FW_FEAT_PRE_PROCESSOR MASK_BIT1 +#define SVA_FW_FEAT_IRP MASK_BIT26 + +/* Preprocessing AND Postprocessing part */ +#define SVA_FW_FEAT_ACE MASK_BIT13 + +/* Video decoder part : */ +#define SVA_FW_FEAT_MPEG4_DECODER MASK_BIT2 +#define SVA_FW_FEAT_MPEG4_SP_DECODER SVA_FW_FEAT_MPEG4_DECODER +#define SVA_FW_FEAT_MPEG4_SH_DECODER MASK_BIT14 +#define SVA_FW_FEAT_MPEG4_DECODER_CIF_VGA MASK_BIT24 +#define SVA_FW_FEAT_MPEG4_DECODER_CIF MASK_BIT27 +#define SVA_FW_FEAT_MPEG4_DECODER_ERC MASK_BIT28 + +#define SVA_FW_FEAT_MPEG4_DECODER_CIF MASK_BIT27 +#define SVA_FW_FEAT_MPEG4_DECODER_ERC MASK_BIT28 + +#define SVA_FW_FEAT_H264_DECODER MASK_BIT15 +#define SVA_FW_FEAT_WMV9_DECODER MASK_BIT16 +#define SVA_FW_FEAT_MPEG2_DECODER MASK_BIT30 + +/* Video encoder part : */ +#define SVA_FW_FEAT_MPEG4_ENCODER MASK_BIT3 +#define SVA_FW_FEAT_MPEG4_SP_ENCODER SVA_FW_FEAT_MPEG4_ENCODER +#define SVA_FW_FEAT_MPEG4_SH_ENCODER MASK_BIT18 + +#define SVA_FW_FEAT_H264_ENCODER MASK_BIT19 + +#define SVA_FW_FEAT_ENCODER_CONSTANT_QP MASK_BIT20 +#define SVA_FW_FEAT_ENCODER_CBR MASK_BIT21 +#define SVA_FW_FEAT_ENCODER_VBR MASK_BIT22 +#define SVA_FW_FEAT_ENCODER_FRAME_BY_FRAME MASK_BIT23 +#define SVA_FW_FEAT_ENCODER_AIR_CIR MASK_BIT25 + +/* Still decoder part : */ +#define SVA_FW_FEAT_JPEG_DECODER MASK_BIT7 + +/* Still encoder part : */ +#define SVA_FW_FEAT_JPEG_ENCODER MASK_BIT8 + +/* Software processing part : */ +#define SVA_FW_FEAT_STAB MASK_BIT11 + +/* TV Output part */ +#define SVA_FW_FEAT_TVO MASK_BIT9 + + + +/* GRABHQ */ +#define SVA_FW_FEAT_PREPROC_ALGO MASK_BIT29 + + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + +/******************************************************************************/ +/* Types definitions */ +/******************************************************************************/ +/* + * Definition of symbol used by Firmware Management routines to return error + */ +typedef enum { + SVA_FM_UNKNOWN_FIRMWARE_ID = SVA_FM_LAST_ERROR, + SVA_FM_UNREGISTERED_FIRMWARE_ID, + SVA_FM_NO_FIRMWARE_LOADED, + SVA_FM_ANOTHER_FIRMWARE_ALREADY_LOADED, + SVA_FM_FEATURES_OVERFLOW, + SVA_FM_FEATURES_UNDERFLOW, + SVA_FM_FEATURES_UNKNOWN_BY_REGISTERED_FW, + SVA_FM_FW_ID_OVERFLOW, + SVA_FM_FW_ID_UNDERFLOW, + SVA_FM_FW_NO_ADDRESS, + SVA_FM_FW_LOAD_ERROR, + SVA_FM_FW_INTERNAL_ERROR, + SVA_FM_OK = SVA_OK + //SVA_FM_FW_CHANGE_NEEDED, + //SVA_FM_FW_READY_TO_DOWNLOAD, + //SVA_FM_FW_CONFLICT +} t_sva_fm_error; + + +/* + * t_sva_fw_features type allow to define features supported by a firmware +*/ +typedef t_uint32 t_sva_fw_features; + +/* + * t_sva_fw_desc type allow to define firmware descriptor +*/ +typedef struct { + t_uint8 structureVersion; + t_uint8 reservedOrSetFeature; + t_uint16 programmingModel; + t_version fwVersion; + t_uint32 hwVersion; + t_sva_fw_features fwFeatures[MAX_NB_SET_FEATURE]; +}t_sva_fw_desc; + +/******************************************************************************* +* PUBLIC Functions +*******************************************************************************/ +PUBLIC t_sva_fm_error sva_FM_Init(t_system_address, t_system_address, t_uint32, t_bool ); +PUBLIC t_bool sva_FM_IsFirmwareChangeNeededByFeatures(t_sva_fw_features); +PUBLIC t_sva_fm_error sva_FM_TestFirmwareChangeNeedByFirmwareId(t_sva_fw_id, t_bool *); +PUBLIC t_sva_fm_error sva_FM_GetFirmwareIdByFeatures(t_sva_fw_features, t_sva_fw_id *); +PUBLIC t_sva_fm_error sva_FM_GetFirmwareIdByFirmwareId(t_sva_fw_id, t_sva_fw_id *); +PUBLIC t_sva_fm_error sva_FM_RegisterFeaturesUse(t_sva_fw_features); +PUBLIC t_sva_fm_error sva_FM_UnRegisterFeaturesUse(t_sva_fw_features); +PUBLIC t_sva_fm_error sva_FM_IncrementeFirmwareIdInstance(t_sva_fw_id); +PUBLIC t_sva_fm_error sva_FM_DecrementeFirmwareIdInstance(t_sva_fw_id); +PUBLIC t_sva_fm_error sva_FM_Download(t_sva_fw_id); +PUBLIC t_sva_fm_error sva_FM_ResetFirmwareShareArea(t_sva_fw_id); +PUBLIC t_sva_fm_error sva_FM_GetFwVersion(t_version *); +PUBLIC t_sva_fm_error sva_FM_GetPatchLevel(t_uint32 *); +PUBLIC t_sva_fm_error sva_FM_InformPrivateMemoryChunk(t_sva_memory_id, t_system_address, t_size); +PUBLIC t_sva_fm_error sva_FM_ConfigurePrivateMemoryChunk(t_sva_dedicated_area_purpose ,t_size *, t_system_address *); +/*PUBLIC t_sva_error SVA_RegisterFirmware(const t_sva_fw_desc *, t_sva_fw_id *); see sva.h */ +/*PUBLIC t_sva_error SVA_UnregisterFirmware(t_sva_fw_id); see sva.h */ +/*PUBLIC t_sva_error SVA_SetFirmwareShareArea(t_sva_fw_id, t_logical_address); see sva.h */ + + +#ifdef __cplusplus +} /* allow C++ to use these headers */ +#endif /* __cplusplus */ + +#endif /* __INC_SVA_FM_H */ +/* End of file - sva_fwmgt.h */ --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_grab.h @@ -0,0 +1,89 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ + +#ifndef __INC_SVA_GRAB_H +#define __INC_SVA_GRAB_H + +#include "sva.h" +#include "svap.h" +#include "sva_taskmgt.h" + +/******************************************************************************/ +/* Constants definitions */ +/******************************************************************************/ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* + * Define the symbols used to identify the various errors of the Grab Module + */ +typedef enum { + SVA_GB_INVALID_TRANSITION = SVA_GB_LAST_ERROR, + SVA_GB_NO_MORE_AVAILABLE_INSTANCE, + SVA_GB_INVALID_INSTANCE_NB, + SVA_GB_INVALID_TASK_ID_NB, + SVA_GB_NOT_SUPPORTED, + SVA_GB_INVALID_CONTROL_PARAM, + SVA_GB_INVALID_PUSH, + SVA_GB_INVALID_BUFFER_TYPE, + SVA_GB_INVALID_BUFFER_SIZE, + SVA_GB_INVALID_CONFIGURATION, + SVA_GB_UNKNOWN_CMD_ID, + SVA_GB_UNEXPECTED_HW_EVENT, + SVA_GB_SYNCHRO_INFO_NOT_AVAILABLE, + SVA_GB_TI_LINKED_ERROR, + SVA_GB_BM_LINKED_ERROR, + SVA_GB_MM_LINKED_ERROR, + SVA_GB_FF_LINKED_ERROR, + SVA_GB_TM_LINKED_ERROR, + SVA_GB_NULL_POINTER_PARAMETER, + SVA_GB_FIFO_NOT_EMPTY, + SVA_GB_OK = HCL_OK +} t_sva_gb_error; + + +/******************************************************************************* +* PUBLIC Functions +*******************************************************************************/ + +PUBLIC t_sva_error sva_GB_Init( void ); +PUBLIC t_sva_error sva_GB_Reset( t_sva_service_id ); +PUBLIC t_sva_error sva_GB_Create( t_sva_service_id *); +PUBLIC t_sva_error sva_GB_Control(t_sva_service_id, t_sva_service_cmd_id, t_uint32 ); +PUBLIC t_sva_error sva_GB_Push(t_sva_service_id, t_sva_buffer_id, t_sva_push_mode, t_sva_buffer_type, t_sva_timestamp ); +PUBLIC t_sva_gb_error sva_GB_DispatchVirtualHwEvent(t_sva_tm_virtual_hw_event_id, t_sva_service_id, t_sva_tm_subtask_id, t_uint32, t_uint32, t_uint8, t_sva_event_desc *, t_uint32 *); +PUBLIC t_sva_error sva_GB_ProvideInternalNeeds( t_sva_service_id); +PUBLIC t_sva_error sva_GB_GetInternalNeeds(t_sva_service_id, t_size *); +PUBLIC t_sva_error sva_GB_Activate(t_sva_service_id, t_sva_service_mode, t_sva_fw_id *); +PUBLIC t_sva_error sva_GB_Inactivate(t_sva_service_id); +PUBLIC t_sva_error sva_GB_Delete(t_sva_service_id ); +//t_sva_preprocessor_configuration is in sva.h +// function is sva.h +//PUBLIC t_sva_error SVA_ConfigurePreProcessor( t_sva_service_id, t_sva_preprocessor_configuration); +//PUBLIC t_sva_error SVA_GetPreProcessorStatus(t_sva_service_id, t_sva_preprocessor_status *); +//PUBLIC t_sva_error SVA_UpdatePreProcessorParams(t_sva_service_id, t_sva_update_cmd_type, t_sva_preprocessor_param_id, t_uint32 ); + +#ifdef __cplusplus +} /* allow C++ to use these headers */ +#endif /* __cplusplus */ + +#endif /* __INC_SVA_GRAB_H */ +/* End of file - sva_grab.h */ --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_host_interface.h @@ -0,0 +1,290 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ + +#ifndef _SVA_HOST_INTERFACE_H_ +#define _SVA_HOST_INTERFACE_H_ + + +/*------------------------------------------------------------------------ + * Include + *----------------------------------------------------------------------*/ +#include "t1xhv_host_interface.h" + +/* + * Define the bits_per_pixels valid values + */ +typedef enum { + SVA_BPP_RGB444 = 0xC, + SVA_BPP_RGB555 = 0xF, + SVA_BPP_RGB565 = 0x10, + SVA_BPP_RGB888 = 0x18, + SVA_BPP_RGB888_UNPACKED = 0x20 +} t_sva_hw_bpp; + +/* + * Define the mirroring valid values + */ +typedef enum { + SVA_HW_MIRRORING_NONE = 0, + SVA_HW_MIRRORING_HORIZONTAL = 1, + SVA_HW_MIRRORING_VERTICAL = 2, + SVA_HW_MIRRORING_BOTH = 3 +} t_sva_hw_mirroring; + +/* + * Define the rotation valid values + */ +typedef enum { + SVA_HW_ROTATION_NONE = 0, + SVA_HW_ROTATION_90 = 1 +} t_sva_hw_rotation; + +/* + * Define the chroma_sampling_format valid values + */ +typedef enum { + SVA_CSF_DEFAULT = 0, + SVA_CSF_MPEG2_4 = 1, + SVA_CSF_MPEG1 = 2 +} t_sva_hw_chroma_sampling_format; + +/* + * Define the contrast valid values (continuous) (if bpp!=0) + */ +typedef enum { + SVA_CNT_50 = 0, + SVA_CNT_100 = 149, + SVA_CNT_150 = 297 +} t_sva_hw_contrast; + +/* + * Define the brightness valid values (continuous) (if bpp!=0) + */ +typedef enum { + SVA_BRT_50 = 0, + SVA_BRT_100 = 16689, + SVA_BRT_150 = 33377 +} t_sva_hw_brightness; + +/* + * Define the contrast valid values (continuous) (if bpp=0) + */ +typedef enum { + SVA_CNT_ZERO_BPP_50 = 0, + SVA_CNT_ZERO_BPP_100 = 128, + SVA_CNT_ZERO_BPP_150 = 254 +} t_sva_hw_contrast_ZERO_BPP; + +/* + * Define the brightness valid values (continuous) (if bpp=0) + */ +typedef enum { + SVA_BRT_ZERO_BPP_50 = 0, + SVA_BRT_ZERO_BPP_100 = 16689, + SVA_BRT_ZERO_BPP_150 = 32767 +} t_sva_hw_brightness_ZERO_BPP; + + +/* + * Define the common type t_sva_param_subfield used for any param subfield + */ +typedef t_uint16 t_sva_param_subfield; + +/*------------------------------------------------------------------------ + * Types : redefine types defined in ts_t1xhv_host_interface.h + *----------------------------------------------------------------------*/ + +typedef ts_t1xhv_subtask_link t_sva_subtask_link; + +typedef ts_t1xhv_subtask_descriptor t_sva_subtask_descriptor; + +typedef ts_t1xhv_bitstream_buf t_sva_bitstream_buffer; + +typedef ts_t1xhv_bitstream_buf_pos t_sva_bitstream_buffer_pos; + +typedef ts_t1xhv_bitstream_buf_link t_sva_bitstream_buf_link; + +typedef ts_t1xhv_header_buf t_sva_header_buf; + +/*****************************************************************************/ +/** + * \brief Parameter structure decode + * + * Parameter structure for decode + **/ +/*****************************************************************************/ + +typedef ts_t1xhv_vdc_subtask_param t_sva_vdc_subtask_param; + +typedef ts_t1xhv_vdc_frame_buf_in t_sva_vdc_frame_buffer_in; + +typedef ts_t1xhv_vdc_internal_buf t_sva_vdc_internal_buf; + +typedef ts_t1xhv_vdc_frame_buf_out t_sva_vdc_frame_buffer_out; + +typedef ts_t1xhv_vdc_h264_param_in t_sva_vdc_h264_param_in; + +typedef ts_t1xhv_vdc_h264_param_inout t_sva_vdc_h264_param_inout; + +typedef ts_t1xhv_vdc_h264_param_out t_sva_vdc_h264_param_out; + +typedef ts_t1xhv_vdc_h264_slice t_sva_vdc_h264_slice; + +typedef ts_t1xhv_vdc_mpeg4_param_in t_sva_vdc_mpeg4_param_in; + +typedef ts_t1xhv_vdc_mpeg4_param_out t_sva_vdc_mpeg4_param_out; + +typedef ts_t1xhv_vdc_mpeg4_param_inout t_sva_vdc_mpeg4_param_inout; + +typedef ts_t1xhv_vdc_mpeg2_param_in t_sva_vdc_Mpeg2_param_in; + +typedef ts_t1xhv_vdc_mpeg2_param_out t_sva_vdc_Mpeg2_param_out; +typedef ts_t1xhv_vdc_mpeg4_param_inout t_sva_vdc_Mpeg2_param_inout; +typedef ts_t1xhv_vdc_vc1_param_in t_sva_vdc_vc1_param_in; + +typedef ts_t1xhv_vdc_vc1_param_out t_sva_vdc_vc1_param_out; + +typedef ts_t1xhv_vdc_vc1_param_inout t_sva_vdc_vc1_param_inout; + +typedef ts_t1xhv_vdc_h263_param_in t_sva_vdc_h263_param_in; + +typedef ts_t1xhv_vdc_h263_param_inout t_sva_vdc_h263_param_inout; + +typedef ts_t1xhv_vdc_h263_param_out t_sva_vdc_h263_param_out; + +typedef ts_t1xhv_vdc_jpeg_param_in t_sva_vdc_jpeg_param_in; + +typedef ts_t1xhv_vdc_jpeg_param_out t_sva_vdc_jpeg_param_out; + +typedef ts_t1xhv_vdc_jpeg_param_inout t_sva_vdc_jpeg_param_inout; + +/*****************************************************************************/ +/** + * \brief Parameter structure encode + * + * Parameter structure for encode + **/ +/*****************************************************************************/ + +typedef ts_t1xhv_vec_subtask_param t_sva_vec_subtask_param; + +typedef ts_t1xhv_vec_frame_buf_in t_sva_vec_frame_buffer_in; + +typedef ts_t1xhv_vec_frame_buf_out t_sva_vec_frame_buffer_out; + +typedef ts_t1xhv_vec_internal_buf t_sva_vec_internal_buffer; + +typedef ts_t1xhv_vec_h264_param_in t_sva_vec_h264_param_in; + +typedef ts_t1xhv_vec_h264_param_out t_sva_vec_h264_param_out; + +typedef ts_t1xhv_vec_h264_param_inout t_sva_vec_h264_param_inout; + +typedef ts_t1xhv_vec_mpeg4_param_inout t_sva_vec_mpeg4_param_inout; + +typedef ts_t1xhv_vec_mpeg4_param_in t_sva_vec_mpeg4_param_in; + +typedef ts_t1xhv_vec_mpeg4_param_out t_sva_vec_mpeg4_param_out; + +typedef ts_t1xhv_vec_h263_param_in t_sva_vec_h263_param_in; + +typedef ts_t1xhv_vec_h263_param_inout t_sva_vec_h263_param_inout; + +typedef ts_t1xhv_vec_h263_param_out t_sva_vec_h263_param_out; + +typedef ts_t1xhv_vec_jpeg_param_in t_sva_vec_jpeg_param_in; + +typedef ts_t1xhv_vec_jpeg_param_out t_sva_vec_jpeg_param_out; + +typedef ts_t1xhv_vec_jpeg_param_inout t_sva_vec_jpeg_param_inout; + + +/*****************************************************************************/ +/** + * \brief Parameter structure for image stabilization + * + * Parameter structure for image stabilization + **/ +/*****************************************************************************/ +typedef ts_t1xhv_vec_stab_param_in t_sva_vec_stab_param_in; + +typedef ts_t1xhv_vec_stab_param_out t_sva_vec_stab_param_out; + +/*****************************************************************************/ +/** + * \BRIEF Parameter structure for display + * + * Parameter structure for display + **/ +/*****************************************************************************/ +typedef ts_t1xhv_dpl_subtask_param t_sva_dpl_subtask_param; + +typedef ts_t1xhv_dpl_frame_buf_in t_sva_dpl_frame_buffer_in; + +typedef ts_t1xhv_dpl_frame_buf_out t_sva_dpl_frame_buffer_out; + +typedef ts_t1xhv_dpl_param_in t_sva_dpl_param_in; + +typedef ts_t1xhv_dpl_param_out t_sva_dpl_param_out; + +typedef ts_t1xhv_dpl_param_inout t_sva_dpl_param_inout; + +typedef ts_t1xhv_dpl_internal_buf t_sva_dpl_internal_buf; + + +/*****************************************************************************/ +/** + * \BRIEF Parameter structure for grab + * + * Parameter structure for grab + **/ +/*****************************************************************************/ +typedef ts_t1xhv_grb_subtask_param t_sva_grb_subtask_param; + +typedef ts_t1xhv_grb_frame_buf_in t_sva_grb_frame_buffer_in; + +typedef ts_t1xhv_grb_frame_buf_out t_sva_grb_frame_buffer_out; + +typedef ts_t1xhv_grb_internal_buf t_sva_grb_internal_buffer; + +typedef ts_t1xhv_grb_param_in t_sva_grb_param_in; + +typedef ts_t1xhv_grb_param_out t_sva_grb_param_out; + +typedef ts_t1xhv_grb_param_inout t_sva_grb_param_inout; + +/*****************************************************************************/ +/** + * \BRIEF Parameter structure for tvout + * + * Parameter structure for tvout + **/ +/*****************************************************************************/ +typedef ts_t1xhv_tvd_subtask_param t_sva_tvo_subtask_param; + +typedef ts_t1xhv_tvd_frame_buf_in t_sva_tvo_frame_buf_in; + +typedef ts_t1xhv_tvd_param_init t_sva_tvo_param_init; + +typedef ts_t1xhv_tvd_param_in t_sva_tvo_param_in; + + +#endif /* _SVA_HOST_INTERFACE_H_ */ + + --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_internalneeds.h @@ -0,0 +1,60 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ + +#ifndef __INC_SVA_IN_H +#define __INC_SVA_IN_H + +#include "hcl_defs.h" +#include "sva.h" +#include "svap.h" + +typedef struct { + t_logical_address baseAddr; + t_logical_address currentPointer; + t_logical_address endAddr; +} t_sva_internal_needs_desc; + + +typedef enum { + SVA_IN_ERROR = SVA_IN_LAST_ERROR, + SVA_IN_OK = HCL_OK +} t_sva_in_error; + + +/* ------------------------------------ */ +/* Internal Needs Module initialization */ +/* ------------------------------------ */ +PUBLIC t_sva_error sva_IN_Init(void); + +/* ------------------------------------------------ */ +/* Provide piece of memory to Internal Needs Module */ +/* ------------------------------------------------ */ +PUBLIC t_sva_in_error sva_IN_ProvideInternalNeeds(t_logical_address, t_size); +// ###: to be added service_id as parameter + + +/* ----------------------------------------------------------- */ +/* Allocate inside the Internal Needs memory a piece of memory */ +/* ----------------------------------------------------------- */ +PUBLIC t_sva_in_error sva_IN_AllocMemory(t_size, t_logical_address *); + + + +#endif /* __INC_SVA_IN_H */ + --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_irqmgt.h @@ -0,0 +1,42 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ + +#ifndef __INC_SVA_IM_H +#define __INC_SVA_IM_H + +#include "hcl_defs.h" +#include "sva.h" +#include "sva_hwp.h" + + + +/* +t_sva_error SVA_SetBaseAddress(t_logical_address); +t_sva_error SVA_GetIRQSrc(t_sva_irq_num); +t_sva_error SVA_ClearIRQSrc(t_sva_irq_src); +t_sva_error SVA_EnableIRQSrc(t_sva_irq_src); +t_sva_error SVA_DisableIRQSrc(t_sva_irq_src); +t_sva_error SVA_IsPendingIRQSrc(t_irq_src); +t_sva_error SVA_GetDeviceId(t_sva_irq_src); +*/ + + +#endif /* __INC_SVA_IM_H */ +/* End of file - sva_irqmgt.h */ + --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_memorymgt.h @@ -0,0 +1,163 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ + +#ifndef __INC_SVA_MM_H +#define __INC_SVA_MM_H + +#include "hcl_defs.h" +#include "sva.h" +#include "svap.h" + +/******************************************************************************/ +/* Constants definitions */ +/******************************************************************************/ +/* + * Define the number of different kind of memroy managed by this module + */ +#define MEMORY_TYPE_NUMBER 3 + +/* + * Define a constant use to tag an invalid block id into SDRAM memory + */ +#define INVALID_SDRAM_BLOCK_ID 0 + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/******************************************************************************/ +/* Types definitions */ +/******************************************************************************/ +/* + * Define symbols used to identify/reference different kind of memory managed into the system + */ +typedef enum { + UNKNOWN_MEMORY_ID = -1, + XRAM_ID = 0, + ESRAM_ID, + SDRAM_ID // SHALL be the last one (only SDRAM chunk can be dynamically added) +} t_sva_memory_id; + +/* + * Define the type used to identify/reference an allocated piece of memory (block) into the HCL + */ +typedef t_uint32 t_sva_block_id; + +/* + * Definition of symbol used by Memory Management routines to return error + */ +typedef enum { + SVA_MM_UNKNOWN_ADDR = SVA_MM_LAST_ERROR, + SVA_MM_WRONG_DEDICATED, + SVA_MM_UNKNOWN_BLOCKID, + SVA_MM_OUT_OF_MEMORY, + SVA_MM_SIZE_INCOMPATIBLE, + SVA_MM_MAX_SMALLBLOCK_REACHED, + SVA_MM_MAX_MEMORY_CHUNK_REACHED, + SVA_MM_OK = HCL_OK +} t_sva_mm_error; + +/* + * Definition of the different block alignment supported + * This is a 'at least' request, that is to say the module could provide a buffer + * with a most constraint alignement (i.e a 4WORDS for a requested WORD alignement) + */ +typedef enum { + SVA_MM_ALIGN_BYTE = 0x00000000, + SVA_MM_ALIGN_HALFWORD = 0x00000001, + SVA_MM_ALIGN_WORD = 0x00000003, + SVA_MM_ALIGN_16BYTES = 0x0000000F, + SVA_MM_ALIGN_4WORDS = 0x0000000F, + SVA_MM_ALIGN_AHB_BURST = 0x0000000F, + SVA_MM_ALIGN_32BYTES = 0x0000001F, + SVA_MM_ALIGN_8WORDS = 0x0000001F, + SVA_MM_ALIGN_64BYTES = 0x0000003F, + SVA_MM_ALIGN_16WORDS = 0x0000003F, + SVA_MM_ALIGN_128BYTES = 0x0000007F, + SVA_MM_ALIGN_32WORDS = 0x0000007F, + SVA_MM_ALIGN_256BYTES = 0x000000FF, + SVA_MM_ALIGN_64WORDS = 0x000000FF, + SVA_MM_ALIGN_512BYTES = 0x000001FF, + SVA_MM_ALIGN_128WORDS = 0x000001FF, + SVA_MM_ALIGN_1024BYTES = 0x000003FF, + SVA_MM_ALIGN_256WORDS = 0x000003FF, + SVA_MM_ALIGN_2048BYTES = 0x000007FF, + SVA_MM_ALIGN_512WORDS = 0x000007FF, + SVA_MM_ALIGN_4096BYTES = 0x00000FFF, + SVA_MM_ALIGN_1024WORDS = 0x00000FFF +} t_sva_mm_alignment; + + +/* + * Definition of the memory management public status of a given memory + */ +typedef struct { + t_uint32 numUsedBlocks; + t_uint32 numFreeBlocks; + t_size freeBlockMinSize; + t_size freeBlockMaxSize; + t_size overallFreeBlocksSize; + t_size overallUsedBlocksSize; +} t_sva_mm_status; + + +typedef struct t_sva_dedicated_memory_block { + t_size size; + t_system_address address; + struct t_sva_dedicated_memory_block * previousBlock; + struct t_sva_dedicated_memory_block * nextBlock; +} t_sva_dedicated_memory_block; + +typedef struct { + t_uint32 nbOfFreeBlocks; + t_uint32 nbOfUseBlocks; + t_sva_dedicated_memory_block * firstFreeBlock; + t_sva_dedicated_memory_block * firstUsedBlock; +} t_sva_dedicated_memory; + + +/****************************************************************************** +* PUBLIC Functions +*******************************************************************************/ +/* Memory Management Module Initialisation */ +PUBLIC t_sva_mm_error sva_MM_Init(void); + +/* Memory Management routines */ +PUBLIC t_sva_mm_error sva_MM_AddFreeBlock(t_sva_memory_id, t_system_address, t_size); +PUBLIC t_sva_mm_error sva_MM_AllocBlock(t_sva_memory_id, t_size, t_sva_mm_alignment, t_sva_block_id *); +PUBLIC t_sva_mm_error sva_MM_FreeBlock(t_sva_block_id); + +/* Status and 'Translation' routines */ +PUBLIC t_sva_mm_error sva_MM_GetBlockSystemAddress(t_sva_block_id, t_system_address *); +PUBLIC t_sva_mm_error sva_MM_GetBlockLogicalAddress(t_sva_block_id, t_logical_address *); +PUBLIC t_sva_mm_error sva_MM_GetBlockPhysicalAddress(t_sva_block_id, t_physical_address *); +PUBLIC t_sva_mm_error sva_MM_GetBlockMemoryId(t_sva_block_id, t_sva_memory_id *); +PUBLIC t_sva_mm_error sva_MM_GetStatus(t_sva_memory_id, t_sva_mm_status *); +PUBLIC t_sva_mm_error sva_MM_PhysicalToLogicalAddress(t_physical_address, t_logical_address *); +PUBLIC t_sva_mm_error sva_MM_InitDedicatedMemory(t_sva_dedicated_area_purpose , t_system_address , t_size); +PUBLIC t_sva_mm_error sva_MM_AllocDedicatedBlock(t_size , t_sva_mm_alignment , t_sva_block_id * ); +PUBLIC t_sva_mm_error sva_MM_FreeDedicatedBlock(t_sva_block_id); +PUBLIC t_sva_mm_error sva_MM_GetDedicatedBlockSystemAddress(t_sva_block_id, t_system_address *); + +#ifdef __cplusplus +} /* allow C++ to use these headers */ +#endif /* __cplusplus */ + +#endif /* __INC_HV_MM_H */ +/* End of file - sva_memorymgt.h */ --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_openservice.h @@ -0,0 +1,62 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ + +#ifndef __INC_OPENSERVICE_H +#define __INC_OPENSERVICE_H + +#include "hcl_defs.h" +#include "sva_taskmgt.h" + +/* + * This enum type will be use by SVA_OM_BUILD_FIELD_ID macro to select task to use between + * decode, encode, grab, display and tvo + */ +typedef enum { + SVA_OM_DEC =0x10, + SVA_OM_ENC =0x20, + SVA_OM_GRB =0x30, + SVA_OM_DIS =0x40, + SVA_OM_TVO =0x50 +} t_sva_open_service_task; + +/* + * This macro allow to build a t_sva_tm_field_id that will be of the correct format for + * task management API (sva_TM_GetSubTaskField, sva_TM_ConnectSubtasksFields, sva_TM_InitSubTaskField, + * sva_TM_UpdateSubTaskField) + */ +#define SVA_OM_BUILD_FIELD_ID(task,fieldNb) ((t_sva_tm_field_id)(((task&MASK_BYTE0)<. */ +/*---------------------------------------------------------------------------*/ + +#ifndef __INC_SVA_OM_H +#define __INC_SVA_OM_H + +#include "hcl_defs.h" +#include "sva.h" + +/******************************************************************************/ +/* Constants definitions */ +/******************************************************************************/ + + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/******************************************************************************/ +/* Types definitions */ +/******************************************************************************/ +/* + * Definition of symbol used by open service Management routines to return error + */ +typedef enum { + SVA_OM_UNREGISTERED , // = SVA_OM_LAST_ERROR, + SVA_OM_NOT_AN_OPEN_SERVICE, + SVA_OM_OK = SVA_OK +} t_sva_om_error; + +/******************************************************************************* +* PUBLIC Functions +*******************************************************************************/ +PUBLIC t_sva_om_error sva_OM_Init(void); +PUBLIC t_bool sva_OM_isOpenService(t_sva_service_id); +PUBLIC t_sva_om_error sva_OM_GetFirmwareId(t_sva_service_id, t_sva_fw_id *); +PUBLIC t_sva_error sva_OM_Create(t_sva_service_type, t_sva_service_id *); +PUBLIC t_sva_error sva_OM_Delete(t_sva_service_id); +PUBLIC t_sva_error sva_OM_Control(t_sva_service_id, t_sva_service_cmd_id, t_uint32); +PUBLIC t_sva_error sva_OM_Activate(t_sva_service_id, t_sva_service_mode, t_sva_fw_id *); +PUBLIC t_sva_error sva_OM_Inactivate(t_sva_service_id); +PUBLIC t_sva_error sva_OM_GetInternalNeeds(t_sva_service_id, t_size *); +PUBLIC t_sva_error sva_OM_ProvideInternalNeeds(t_sva_service_id); +PUBLIC t_sva_error sva_OM_DispatchVirtualHwEvent(t_sva_tm_virtual_hw_event_id ,t_sva_service_id ,t_sva_tm_subtask_id ,t_uint32 ,t_uint32 ,t_uint8 ,t_sva_event_desc *,t_uint32 *); + +/*PUBLIC t_sva_error SVA_RegisterOpenService(const tp_sva_open_service_methods , t_sva_fw_id, t_sva_service_type *); see sva.h */ +/*PUBLIC t_sva_error SVA_UnregisterOpenService(t_sva_service_type); see sva.h */ + + +#ifdef __cplusplus +} /* allow C++ to use these headers */ +#endif /* __cplusplus */ + +#endif /* __INC_HV_FM_H */ +/* End of file - hv_fwMgt.h */ --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_service.h @@ -0,0 +1,337 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ + +#ifndef __INC_SVA_SERVICE_H +#define __INC_SVA_SERVICE_H + +#include "hcl_defs.h" +#include "sva.h" +#include "sva_taskmgt.h" +#include "platform_os.h" + + +/******************************************************************************/ +/* Constants definitions */ +/******************************************************************************/ + + +/*----------------------------------------------------------------------* + * Defines : general subtask * + *----------------------------------------------------------------------*/ + +/* number max of subtask for one instance */ +#define SUBTASK_NMAX 256 + +/* define number of sub task a service must create by default */ +#define SUBTASK_DEFAULT_NUMBER 2 + +/*----------------------------------------------------------------------* + * Defines : grab instances and subtasks * + *----------------------------------------------------------------------*/ + +/* Define the number of subtask use by grab. It's fix to 4. Reason is to have an even number to ease interlace support */ +#define SUBTASK_GRAB_NUMBER 4 + +/* define maximum number of grab supported */ +#define NUM_MAX_GRAB 4 + +/* define maximum number of started grab supported */ +#define NUM_MAX_STARTED_GRAB 1 + +/*----------------------------------------------------------------------* + * Defines : video encode instances and subtasks * + *----------------------------------------------------------------------*/ + +/* Define the number of subtask use by encode. It's different from default service value and is equal to brc pipedepth */ +#define SUBTASK_ENCODE_NUMBER 2 + +/* define maximum number of encode supported */ +#define NUM_MAX_ENCODE 4 + +/* define maximum number of active encode supported */ +#define NUM_MAX_ACTIVE_ENCODE 1 + +/*----------------------------------------------------------------------* + * Defines : video decode instances and subtasks * + *----------------------------------------------------------------------*/ + +/* SUBTASK_DECODE_NUMBER => SUBTASK_DEFAULT_NUMBER */ + +/* define maximum number of decode supported */ +#define NUM_MAX_DECODE 4 + +/* define maximum number of active decode supported */ +#define NUM_MAX_ACTIVE_DECODE 1 + +/*----------------------------------------------------------------------* + * Defines : still encode instances and subtasks * + *----------------------------------------------------------------------*/ + +/* Define subtask number */ +#define STILL_ENCODE_SUBTASK_DEFAULT_NUMBER 1 + +/* Define the maximum number of still encode instance those can be run in parallel */ +#define NUM_MAX_STILL_ENCODE 4 + +/*----------------------------------------------------------------------* + * Defines : still decode instances and subtasks * + *----------------------------------------------------------------------*/ + +/* STILL_DECODE_SUBTASK_DEFAULT_NUMBER => SUBTASK_DEFAULT_NUMBER */ + +/* Define the maximum number of still-image decode instance those can be run in parallel */ +#define NUM_MAX_STILL_DECODE 8 + +/*----------------------------------------------------------------------* + * Defines : stab instances and subtasks * + *----------------------------------------------------------------------*/ + +/* define maximum number of stab supported */ +#define NUM_MAX_STAB 4 + +/*----------------------------------------------------------------------* + * Defines : display instances and subtasks * + *----------------------------------------------------------------------*/ + +/* Define the maximum number of display instance those can be run in parallel */ +#define NUM_MAX_POSTPROCESSOR 4 + +/* Define the maximum number of display instance those can be run in parallel */ +#define NUM_MAX_DISPLAY 4 + +/*----------------------------------------------------------------------* + * Defines : tvo instances and subtasks * + *----------------------------------------------------------------------*/ + +/* Define the number of subtask use by TVO. */ + +#define SUBTASK_TVO_NUMBER 1 + +/* define maximum number of tvo supported */ +#define NUM_MAX_TV 1 + + + +/*define default fifo depth for buffer*/ +#define PUSH_FIFO_DEFAULT_SIZE 16 +#define STREAMING_FIFO_DEFAULT_SIZE 256 + +/******************************************************************************/ +/* Types definitions */ +/******************************************************************************/ + +/* +Structure of Service_ID: + + 31 23 15 7 0 + / FIFOEVT_INDEX / TASK_ID / OPENSERVICE / INSTANCE / + +Instance and TASK_ID are handled by Service module +*/ + +#define WRITE_INSTANCE_NUM_IN_SERVICE_ID(instanceNb,serviceId) \ +(serviceId = ((serviceId & ~MASK_BYTE0) | ((t_sva_service_id)instanceNb & MASK_BYTE0))) + +#define READ_INSTANCE_NUM_IN_SERVICE_ID(serviceId) \ +((t_sva_service_instance_num) (serviceId & MASK_BYTE)) + +#define WRITE_OPEN_SERVICE_NUM_IN_SERVICE_ID(serviceType,serviceId) \ +(serviceId = ((serviceId & ~MASK_BYTE1) | (((t_sva_service_id)serviceType & MASK_BYTE0)<>SHIFT_BYTE1)) + +#define WRITE_TASK_ID_IN_SERVICE_ID(taskId,serviceId) \ +(serviceId = ((serviceId & ~MASK_BYTE2) | (((t_sva_service_id)taskId & MASK_BYTE0)<>SHIFT_BYTE2)) + + +#define WRITE_FIFO_ID_IN_SERVICE_ID(fifoId,serviceId) \ +(serviceId = ((serviceId & ~MASK_BYTE3) | (((t_sva_service_id)fifoId & MASK_BYTE0)<>SHIFT_BYTE3)) + + +#define CHECK_NULL_POINTER(pointer) \ +do {if (pointer==NULL) {return SVA_NULL_POINTER_PARAMETER;}} while(0) + +/* + * Define a macro that compute the given mask linked to a structure field corresponding to a field (16 or 32 bits access) + * i.e mask used to update it (for exemple: PARAM_ONE_FIELD16_MASK(source_frame_height,t_sva_dpl_param_in) gives 0x02 + */ +#define PARAM_ONE_FIELD16_MASK(structureType,fieldName) \ + (1 << (HCL_BITHCL_BITFIELD_OFFSET(structureType, fieldName)/sizeof(t_uint16))) + +#define PARAM_ONE_FIELD32_MASK(structureType,fieldName) \ + (1 << (HCL_BITHCL_BITFIELD_OFFSET(structureType, fieldName)/sizeof(t_uint32))) + +#define PARAM_ALL_FIELDS16_MASK(structureType) \ + ((1 << (sizeof(structureType)/sizeof(t_uint16)))-1) + +#define PARAM_ALL_FIELDS32_MASK(structureType) \ + ((1 << (sizeof(structureType)/sizeof(t_uint32)))-1) + +/* + * Define the macro used to test if the first parameter is in the correct range + */ +#define TEST_RANGE(param, valMin, valMax) \ + (((param) >= (valMin)) && ((param) <= (valMax))) + +#define TEST_RANGE0(param, valMin, valMax) \ + ((param) <= (valMax)) + +/* + * Define the macro used to test if the first parameter has the correct alignment constraint + */ +#define TEST_ALIGNMENT(param, value) \ + (((param)%(value)) == 0) + +/* + * Define the macro used to check if the first parameter is in the correct range + * if it is not the case then return FALSE + */ +#define CHECK_RANGE(param, valMin, valMax) \ + do { \ + if (!TEST_RANGE(param, valMin, valMax)) {return FALSE;} \ + } while(0) + +#define CHECK_RANGE0(param, valMin, valMax) \ + do { \ + if (!TEST_RANGE0(param, valMin, valMax)) {return FALSE;} \ + } while(0) + +/* + * Define the macro used to check if the first parameter has the correct alignment constraint + * if it is not the case then return FALSE + */ +#define CHECK_ALIGNMENT(param, value) \ + do { \ + if (!TEST_ALIGNMENT(param, value)) {return FALSE;} \ + } while(0) + + +/* + * Define a macro used to test a critical condition in order to prevent an array overflow + */ +#define CHECK_TABLE_OVERFLOW(nextIndex, maxIndex, errorCode) \ + {if (nextIndex>=maxIndex) { \ + HCL_DEBUG_ASSERT(1==0); \ + return(errorCode);}} + +/* + * Definition of the type used to link together a buffer and its related timestamp + */ +typedef struct { + t_sva_buffer_id bufferId; + t_sva_timestamp timestamp; +} t_sva_timestamped_buffer_id; + +typedef enum { +SVA_SV_ERROR =-1, +SVA_SV_OK = HCL_OK, +SVA_SV_VP_DISPATCH_REQUESTED = 15 +}t_sva_sv_error; + +typedef enum { +SVA_SV_MPEG4_ALGO =0, +SVA_SV_H264_ALGO =1, +SVA_SV_VC1_ALGO =2, +SVA_SV_MPEG2_ALGO =3, +SVA_SV_H263_ALGO =4 +}t_sva_sv_algo; + + +typedef enum { +SVA_SV_JPEG_ALGO =0, +SVA_SV_XXX_ALGO = 1 +}t_sva_sv_still_algo; + + + +typedef t_sva_sv_error (*tp_sva_sv_DispatchHwEvent) ( t_sva_tm_virtual_hw_event_id, t_sva_service_id, t_sva_tm_subtask_id, t_uint32, t_uint32, t_uint8,t_sva_event_desc *,t_uint32* ); + + +/* + * Define the symbols used to identify the various services + * supported inside the HCL + */ +typedef enum { + SVA_SV_GRAB_TID = 1, + SVA_SV_DECODE_TID = 2, + SVA_SV_ENCODE_TID = 3, + SVA_SV_DISPLAY_TID = 4, + SVA_SV_STILL_ENCODE_TID = 5, + SVA_SV_STILL_DECODE_TID = 6, + SVA_SV_TVO_TID = 7, + SVA_SV_STAB_TID = 8, + SVA_SV_OPEN_SERVICE=128 +} t_sva_sv_task_id; + +/* + * Define type to handle instance number + */ +typedef t_uint8 t_sva_service_instance_num; + +/******************************************************************************* +* PUBLIC Functions +*******************************************************************************/ + + +/* +t_sva__error SVA__Init( t_logical_address ); + +t_sva__error SVA__Reset( t_sva_service_id ); + +t_sva__error SVA__Create( t_sva_service_id *); + +#### Name to be discussed : +#t_sva_error SVA_Configure( t_sva_service_id, t_sva__configuration); + +### Added: +#t_sva__error SVA__ProvideInternalNeeds( t_sva_service_id); + +t_sva__error SVA__Control(t_sva_service_id, t_sva_cmd_id, t_sva_timestamp ); + +#### Name to be discussed : +#t_sva__error SVA__UpdateParams(t_sva_service_id, t_sva_update_cmd_type, t_sva__param_id, t_uint32); + +t_sva__error SVA__Push(t_sva_service_id, t_sva_buffer_id, t_sva_push_mode, t_sva_buffer_type, t_sva_timestamp ); + +t_sva__error SVA__Status(t_sva_service_id, t_sva__status * ); + +t_sva__error SVA__DispatchVirtualHwEvent(t_sva_virtual_hw_event_id, t_sva_service_id, t_sva_subtask_id, t_sva_ticks, t_uint8, t_sva_event_desc *, t_uint32 *); + +#### Added: +#t_sva__error SVA__GetInternalNeeds(t_sva_service_id, t_size *) + +t_sva__error SVA__Activate(t_sva_service_id); + +t_sva__error SVA__Deactivate(t_sva_service_id); + +t_sva__error SVA__Delete(t_sva_service_id ); +*/ + + + + +#endif /* __INC_SVA_SERVICE_H */ +/* End of file - SVA.h */ --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_stab.h @@ -0,0 +1,89 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ + +#ifndef __INC_SVA_STAB_H +#define __INC_SVA_STAB_H + +#include "sva.h" +#include "svap.h" +#include "sva_taskmgt.h" + +/******************************************************************************/ +/* Constants definitions */ +/******************************************************************************/ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* + * Define the symbols used to identify the various errors of the STab Module + */ +typedef enum { + SVA_ST_INVALID_TRANSITION = SVA_EC_STAB_LAST_ERROR, + SVA_ST_NO_MORE_AVAILABLE_INSTANCE, + SVA_ST_INVALID_INSTANCE_NB, + SVA_ST_INVALID_TASK_ID_NB, + SVA_ST_NOT_SUPPORTED, + SVA_ST_INVALID_CONTROL_PARAM, + SVA_ST_INVALID_PUSH, + SVA_ST_INVALID_BUFFER_TYPE, + SVA_ST_INVALID_BUFFER_SIZE, + SVA_ST_INVALID_CONFIGURATION, + SVA_ST_UNKNOWN_CMD_ID, + SVA_ST_UNEXPECTED_HW_EVENT, + SVA_ST_TI_LINKED_ERROR, + SVA_ST_BM_LINKED_ERROR, + SVA_ST_MM_LINKED_ERROR, + SVA_ST_FF_LINKED_ERROR, + SVA_ST_TM_LINKED_ERROR, + SVA_ST_NULL_POINTER_PARAMETER, + SVA_ST_FIFO_NOT_EMPTY, + SVA_ST_OK = HCL_OK +} t_sva_st_error; + + +/******************************************************************************* +* PUBLIC Functions +*******************************************************************************/ + +PUBLIC t_sva_error sva_ST_Init(t_sva_block_id ,t_size); +PUBLIC t_sva_error sva_ST_Reset( t_sva_service_id ); +PUBLIC t_sva_error sva_ST_Create( t_sva_service_id *); +PUBLIC t_sva_error sva_ST_Control(t_sva_service_id, t_sva_service_cmd_id, t_uint32 ); +PUBLIC t_sva_error sva_ST_Push(t_sva_service_id, t_sva_buffer_id, t_sva_push_mode, t_sva_buffer_type, t_sva_timestamp ); +PUBLIC t_sva_st_error sva_ST_DispatchVirtualHwEvent(t_sva_tm_virtual_hw_event_id, t_sva_service_id, t_sva_tm_subtask_id, t_uint32, t_uint32, t_uint8, t_sva_event_desc *, t_uint32 *); +PUBLIC t_sva_error sva_ST_ProvideInternalNeeds( t_sva_service_id); +PUBLIC t_sva_error sva_ST_GetInternalNeeds(t_sva_service_id, t_size *); +PUBLIC t_sva_error sva_ST_Activate(t_sva_service_id, t_sva_service_mode, t_sva_fw_id *); +PUBLIC t_sva_error sva_ST_Inactivate(t_sva_service_id); +PUBLIC t_sva_error sva_ST_Delete(t_sva_service_id ); +PUBLIC t_sva_error sva_ST_GetParamsBufferSize(t_sva_service_id ,t_sva_push_mode ,t_size *); +//t_sva_sw_processing_configuration is in sva.h +// function is sva.h +//PUBLIC t_sva_error SVA_ConfigureSwProcessing( t_sva_service_id, t_sva_sw_processing_configuration); +//PUBLIC t_sva_error SVA_GetSwProcessingStatus(t_sva_service_id, t_sva_sw_processing_status *); +//PUBLIC t_sva_error SVA_UpdateSwProcessingParams(t_sva_service_id, t_sva_update_cmd_type, t_sva_sw_processing_param_id, t_uint32 ); + +#ifdef __cplusplus +} /* allow C++ to use these headers */ +#endif /* __cplusplus */ + +#endif /* __INC_SVA_STAB_H */ +/* End of file - sva_stab.h */ --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_still_decode.h @@ -0,0 +1,111 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ + +#ifndef __INC_SVA_STILLDECODE_H +#define __INC_SVA_STILLDECODE_H + + +#include "hcl_defs.h" +#include "sva.h" +#include "svap.h" +#include "sva_service.h" +#include "sva_taskmgt.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* + * Currently, only JPEG is supported + */ +#define SVA_SDC_NUMBER_OF_ALGO_SUPPORTED 1 + +/* + * Define the symbols used to identify the number of still-image decoder service + */ + +typedef struct { + t_sva_bitstream_buffer_pos bitstreamPosition; + t_sva_buffer_id relatedBufferId; +} t_sva_bitstream_desc; + +typedef t_sva_service_instance_num t_sva_still_decoder_instance_num; + + +/* + * Define the symbols used to identify the various errors of the still-image module + */ + +typedef enum { + SVA_SDC_INVALID_TRANSITION, //= SVA_SDC_LAST_ERROR, + SVA_SDC_NO_MORE_AVAILABLE_INSTANCE, + SVA_SDC_INVALID_INSTANCE_NB, + SVA_SDC_INVALID_TASK_ID_NB, + SVA_SDC_NOT_SUPPORTED, + SVA_SDC_INVALID_CONTROL_PARAM, + SVA_SDC_INVALID_PUSH, + SVA_SDC_INVALID_BUFFER_TYPE, + SVA_SDC_INVALID_BUFFER_SIZE, + SVA_SDC_INVALID_CONFIGURATION, + SVA_SDC_UNKNOWN_CMD_ID, + SVA_SDC_UNEXPECTED_HW_EVENT, + SVA_SDC_UNEXPECTED_API_CALL, + SVA_SDC_SYNCHRO_INFO_NOT_AVAILABLE, + SVA_SDC_TI_LINKED_ERROR, + SVA_SDC_BM_LINKED_ERROR, + SVA_SDC_MM_LINKED_ERROR, + SVA_SDC_FF_LINKED_ERROR, + SVA_SDC_TM_LINKED_ERROR, + SVA_SDC_NULL_POINTER_PARAMETER, + SVA_SDC_FIFO_NOT_EMPTY, + SVA_SDC_OK = HCL_OK +} t_sva_sdc_error; + +typedef enum { + SVA_SDC_DECODE_COMPLETE, + SVA_SDC_DECODE_INCOMPLETE, + SVA_SDC_DECODE_NOPROGRESS +} t_sva_sdc_decode_status; + + +/******************************************************************************* +* PUBLIC Functions +*******************************************************************************/ + +PUBLIC t_sva_error sva_SDC_Init(void ); +PUBLIC t_sva_error sva_SDC_Reset(t_sva_service_id ); +PUBLIC t_sva_error sva_SDC_Create(t_sva_service_id * ); +PUBLIC t_sva_error sva_SDC_Control(t_sva_service_id, t_sva_service_cmd_id, t_uint32 ); +PUBLIC t_sva_error sva_SDC_Push(t_sva_service_id, t_sva_buffer_id, t_sva_push_mode, t_sva_buffer_type); +PUBLIC t_sva_error sva_SDC_DispatchVirtualHwEvent(t_sva_tm_virtual_hw_event_id, t_sva_service_id, t_sva_tm_subtask_id, t_uint32, t_uint32, t_uint8, t_sva_event_desc *, t_uint32 * ); +PUBLIC t_sva_error sva_SDC_ProvideInternalNeeds(t_sva_service_id, t_system_address, t_size); +PUBLIC t_sva_error sva_SDC_GetInternalNeeds(t_sva_service_id, t_size * , t_size *); +PUBLIC t_sva_error sva_SDC_Activate(t_sva_service_id, t_sva_service_mode, t_sva_fw_id * ); +PUBLIC t_sva_error sva_SDC_Inactivate(t_sva_service_id ); +PUBLIC t_sva_error sva_SDC_Delete(t_sva_service_id ); +PUBLIC t_sva_error sva_SDC_SetHeaderInfos(t_sva_service_id, t_sva_buffer_id,t_uint32,t_uint32,const t_sva_header_infos *); +PUBLIC t_sva_error sva_SDC_AssertEndOfBitstream(t_sva_service_id); +PUBLIC t_sva_error sva_SDC_GetParamsBufferSize(t_sva_service_id,t_sva_push_mode,t_size *); + +#ifdef __cplusplus +} /* allow C++ to use these headers */ +#endif /* __cplusplus */ + +#endif/* __INC_SVA_STILLDECODE_H */ +/* End of file - sva_still_decode.h */ --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_still_encode.h @@ -0,0 +1,96 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ + +#ifndef __INC_SVA_STILLENCODE_H +#define __INC_SVA_STILLENCODE_H + + +#include "hcl_defs.h" +#include "sva.h" +#include "svap.h" +#include "sva_service.h" +#include "sva_taskmgt.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + +/* + * Define the symbols used to identify the number of encoder service + */ +#define SVA_SEC_NUMBER_OF_ALGO_SUPPORTED 5 + +/* + * Define the symbols used to identify the number of encoder service + */ +typedef t_sva_service_instance_num t_sva_still_encoder_instance_num; + + +/* + * Define the symbols used to identify the various errors of the Still Encode Module + */ + +typedef enum { + SVA_SEC_INVALID_TRANSITION = SVA_SEC_LAST_ERROR, + SVA_SEC_NO_MORE_AVAILABLE_INSTANCE, + SVA_SEC_INVALID_INSTANCE_NB, + SVA_SEC_INVALID_TASK_ID_NB, + SVA_SEC_NOT_SUPPORTED, + SVA_SEC_INVALID_CONTROL_PARAM, + SVA_SEC_INVALID_PUSH, + SVA_SEC_INVALID_BUFFER_TYPE, + SVA_SEC_INVALID_BUFFER_SIZE, + SVA_SEC_INVALID_CONFIGURATION, + SVA_SEC_UNKNOWN_CMD_ID, + SVA_SEC_UNEXPECTED_HW_EVENT, + SVA_SEC_SYNCHRO_INFO_NOT_AVAILABLE, + SVA_SEC_TI_LINKED_ERROR, + SVA_SEC_BM_LINKED_ERROR, + SVA_SEC_MM_LINKED_ERROR, + SVA_SEC_FF_LINKED_ERROR, + SVA_SEC_TM_LINKED_ERROR, + SVA_SEC_NULL_POINTER_PARAMETER, + SVA_SEC_FIFO_NOT_EMPTY, + SVA_SEC_OK = HCL_OK +} t_sva_sec_error; + + +/******************************************************************************* +* PUBLIC Functions +*******************************************************************************/ + +PUBLIC t_sva_error sva_SEC_Init( void ); +PUBLIC t_sva_error sva_SEC_Reset( t_sva_service_id ); +PUBLIC t_sva_error sva_SEC_Create( t_sva_service_id *); +PUBLIC t_sva_error sva_SEC_Control(t_sva_service_id, t_sva_service_cmd_id, t_uint32 ); +PUBLIC t_sva_error sva_SEC_Push(t_sva_service_id, t_sva_buffer_id, t_sva_push_mode, t_sva_buffer_type, t_sva_timestamp ); +PUBLIC t_sva_error sva_SEC_DispatchVirtualHwEvent(t_sva_tm_virtual_hw_event_id, t_sva_service_id, t_sva_tm_subtask_id, t_uint32, t_uint32, t_uint8, t_sva_event_desc *, t_uint32 *); +PUBLIC t_sva_error sva_SEC_ProvideInternalNeeds( t_sva_service_id); +PUBLIC t_sva_error sva_SEC_GetInternalNeeds(t_sva_service_id, t_size *); +PUBLIC t_sva_error sva_SEC_Activate(t_sva_service_id, t_sva_service_mode, t_sva_fw_id *); +PUBLIC t_sva_error sva_SEC_Inactivate(t_sva_service_id); +PUBLIC t_sva_error sva_SEC_Delete(t_sva_service_id ); + + +#ifdef __cplusplus +} /* allow C++ to use these headers */ +#endif /* __cplusplus */ + +#endif --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_taskmgt.h @@ -0,0 +1,403 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ + +#ifndef __INC_SVA_TASKMGT_H +#define __INC_SVA_TASKMGT_H + +#include "hcl_defs.h" +#include "sva_memorymgt.h" +#include "sva_fwmgt.h" +#include "sva_host_interface.h" +#include "svap.h" +#include "sva.h" +#include "sva_hwp.h" +#include "sva_timemgt.h" + +/******************************************************************************/ +/* Constants definitions */ +/******************************************************************************/ + +/*------------------------------------------------------------------------ + * Defines + *----------------------------------------------------------------------*/ + +#define INTERNAL_MEM_EXT_BIT 0 +#define EXTERNAL_MEM_EXT_BIT 1 + + + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/******************************************************************************/ +/* Types definitions */ +/******************************************************************************/ + + + +typedef t_uint32 t_sva_tm_subtask_id; //0 is reserved +typedef t_uint32 t_sva_tm_subtasklist_id; //0 is reserved + +/* + * Define the special invalid value for t_sva_tm_subtask_id variables + */ +#define INVALID_SUBTASK_ID MASK_ALL32 +#define INVALID_SUBTASK_LIST_ID MASK_ALL32 + + +typedef struct { + t_uint16 sizetoallocate; //in BYTES + t_sva_memory_id memId; //field Memory Id +} t_sva_tm_alloc_desc; + +typedef struct { + t_uint8 fieldtoreference; //used only if reference command: start at 0 + t_uint32 subtaskidtoreference; //used only if reference command +} t_sva_tm_ref_desc; + +typedef union { + t_sva_tm_alloc_desc allocDesc; + t_sva_tm_ref_desc refDesc; +} t_sva_tm_command_desc; + +typedef enum { + SVA_TM_DCMD_ALLOCATE, + SVA_TM_DCMD_REFERENCE, + SVA_TM_DCMD_NULL, + SVA_TM_DCMD_DUMMY = ~(MASK_BIT31) +}t_sva_tm_mem_command; + +typedef struct { + t_sva_tm_mem_command command; + t_sva_tm_command_desc commandDesc; +}t_sva_tm_field_ctrl_desc; + +typedef struct { + t_sva_memory_id memId; // subtask Memory Id + t_uint8 fieldnb; // field number for a given subtask (depends on task type) + t_sva_tm_field_ctrl_desc *pfieldctrldesc;// points on an array of t_sva_field_ctrl_desc +}t_sva_tm_task_ctrl_desc; + + +typedef enum { + SVA_TM_ENCODE_MPEG4_SW =0x00, + SVA_TM_ENCODE_MPEG4_NO_SW =0x01, + SVA_TM_ENCODE_H263_SW =0x02, + SVA_TM_ENCODE_H263_NO_SW =0x03, + SVA_TM_IMAGE_STAB_SW =0x04, + SVA_TM_IMAGE_STAB_NO_SW =0x05, + SVA_TM_ENCODE_JPEG =0x06, + SVA_TM_ENCODE_H264 =0x07, + SVA_TM_ENCODE_MPEG4_NO_SW_RASTER_IN =0x08, + SVA_TM_IMAGE_STAB_NO_SW_RASTER_IN =0x09, + SVA_TM_ENCODE_JPEG_RASTER_IN =0x0A, + SVA_TM_ENCODE_JPEG_THUMBNAIL =0x0B, + SVA_TM_DECODE_MPEG4 =0x20, + SVA_TM_DECODE_H263 =0x21, + SVA_TM_DECODE_JPEG =0x22, + SVA_TM_DECODE_H264 =0x23, + SVA_TM_DECODE_VC1 =0x24, // dummy value TO BE UPDATED once fw specification frozen + SVA_TM_DECODE_MPEG4_RASTER_OUT =0x25, + SVA_TM_DECODE_H263_RASTER_OUT =0x26, + SVA_TM_DECODE_JPEG_NO_SLICE =0x27, + SVA_TM_DECODE_MPEG2 =0x28, + SVA_TM_GRAB_WITH_CACHE =0x40, + SVA_TM_GRAB_NO_CACHE =0x41, + SVA_TM_GRAB_WITH_SEP_COMP =0x42, //For JPEG encode + SVA_TM_GRAB_RAW_DATA =0x43, + SVA_TM_GRAB_SENSOR_NO_CACHE =0x44, + SVA_TM_GRAB_SENSOR_WITH_SEP_COMP =0x45, + SVA_TM_GRAB_CAMERA_RASTER_OUT =0x46, + SVA_TM_GRAB_SENSOR_RASTER_OUT =0x47, + SVA_TM_GRAB_SENSOR_HQ =0x4A, + SVA_TM_DISPLAY_NO_FILTERING =0x60, + SVA_TM_DISPLAY_MPEG4_DEBLOCKING =0x61, + SVA_TM_DISPLAY_MPEG4_DEBLOCKING_DERINGING =0x62, + SVA_TM_DISPLAY_H263_DEBLOCKING =0x63, + SVA_TM_DISPLAY_H263_DEBLOCKING_MPEG4_DERINGING =0x64, + SVA_TM_DISPLAY_MPEG4_DERINGING =0x65, + SVA_TM_DISPLAY_NO_FILTERING_RASTER_IN =0x66, + SVA_TM_DISPLAY_MPEG4_DEBLOCKING_RASTER_IN =0x67, + SVA_TM_DISPLAY_MPEG4_DEBLOCKING_DERINGING_RASTER_IN =0x68, + SVA_TM_DISPLAY_H263_DEBLOCKING_RASTER_IN =0x69, + SVA_TM_DISPLAY_H263_DEBLOCKING_MPEG4_DERINGING_RASTER_IN =0x6A, + SVA_TM_DISPLAY_MPEG4_DERINGING_RASTER_IN =0x6B, + SVA_TM_TVO_STANDARD =0x70 +}t_sva_tm_subtask_type; + +typedef enum { + SVA_TM_NO_POST_PROCESSING =0, + SVA_TM_DEBLOCKING_DERINGING_OUT_LOOP =1, // parameters are put in the deblocking param buffer and + // will be used by display task + SVA_TM_YUV420PL_TO_RGB =1, + SVA_TM_H263_DEBLOCKING_IN_LOOP =2, // parameters taken into account in the encode subtask + SVA_TM_YUV420MB_TO_YUV420MB =2, + SVA_TM_H263_DEBLOCKING_IN_LOOP_AND_DERINGING_OUT =3, // mix of the 2 first + SVA_TM_YUV420MB_TO_YUV_SEP_COMP_MB = 3 //YUV420MB-tiled to YUV420/422 MB-tiled Separate Component +}t_sva_tm_postprocessing_type; + +typedef enum { + SVA_TM_IMMEDIATE, + SVA_TM_RELATIVE, + SVA_TM_ABSOLUTE +}t_sva_tm_timestamp_type; + +typedef t_uint32 t_sva_tm_timestamp_value; + +typedef struct { + t_sva_tm_timestamp_type timestampType; + t_sva_tm_timestamp_value timestampValue; +}t_sva_tm_timestamp; + +typedef enum { + SVA_TM_NO_IT, + SVA_TM_BOT_EN, + SVA_TM_EOT_EN, + SVA_TM_BOT_EOT_EN +} t_sva_tm_bot_eot; + +typedef enum { + SVA_TM_NO_SYNCHRO, + SVA_TM_DISPLAY_VSYNC +}t_sva_tm_synchro; + +typedef enum { + SVA_TM_BBM_DEFAULT = 0, // Default mode for all services except decode/encode + SVA_TM_CIRCULAR_MODE = 0, // + SVA_TM_LINK_LIST_MODE +} t_sva_tm_bbm; + +typedef t_uint32 t_sva_tm_subtask_list_id; + +typedef enum { + // first digit references task / last digit references field position in the subtask structure + SVA_TM_SUBTASK_LINK =0x0000, + SVA_TM_DEC_ADDR_IN_FRAME_BUFFER =0x1000, + SVA_TM_DEC_ADDR_OUT_FRAME_BUFFER =0x1001, + SVA_TM_DEC_ADDR_INTERNAL_BUFFER =0x1002, + SVA_TM_DEC_ADDR_IN_BITSTREAM_BUFFER =0x1003, + SVA_TM_DEC_ADDR_OUT_BITSTREAM_BUFFER=0x1004, + SVA_TM_DEC_ADDR_IN_PARAMETERS =0x1005, + SVA_TM_DEC_ADDR_OUT_PARAMETERS =0x1006, + SVA_TM_DEC_ADDR_IN_FRAME_PARAMETERS =0x1007, + SVA_TM_DEC_ADDR_OUT_FRAME_PARAMETERS=0x1008, + SVA_TM_ENC_ADDR_IN_FRAME_BUFFER =0x2000, + SVA_TM_ENC_ADDR_OUT_FRAME_BUFFER =0x2001, + SVA_TM_ENC_ADDR_INTERNAL_BUFFER =0x2002, + SVA_TM_ENC_ADDR_IN_HEADER_BUFFER =0x2003, + SVA_TM_ENC_ADDR_IN_BITSTREAM_BUFFER =0x2004, + SVA_TM_ENC_ADDR_OUT_BITSTREAM_BUFFER=0x2005, + SVA_TM_ENC_ADDR_IN_PARAMETERS =0x2006, + SVA_TM_ENC_ADDR_OUT_PARAMETERS =0x2007, + SVA_TM_ENC_ADDR_IN_FRAME_PARAMETERS =0x2008, + SVA_TM_ENC_ADDR_OUT_FRAME_PARAMETERS=0x2009, + SVA_TM_GRB_ADDR_IN_FRAME_BUFFER =0x3000, + SVA_TM_GRB_ADDR_OUT_FRAME_BUFFER =0x3001, + SVA_TM_GRB_ADDR_INTERNAL_BUFFER =0x3002, + SVA_TM_GRB_ADDR_IN_PARAMETERS =0x3003, + SVA_TM_GRB_ADDR_OUT_PARAMETERS =0x3004, + SVA_TM_GRB_ADDR_IN_FRAME_PARAMETERS =0x3005, + SVA_TM_GRB_ADDR_OUT_FRAME_PARAMETERS=0x3006, + SVA_TM_DIS_ADDR_IN_FRAME_BUFFER =0x4000, + SVA_TM_DIS_ADDR_OUT_FRAME_BUFFER =0x4001, + SVA_TM_DIS_ADDR_INTERNAL_BUFFER =0x4002, + SVA_TM_DIS_ADDR_IN_PARAMETERS =0x4003, + SVA_TM_DIS_ADDR_OUT_PARAMETERS =0x4004, + SVA_TM_DIS_ADDR_IN_FRAME_PARAMETERS =0x4005, + SVA_TM_DIS_ADDR_OUT_FRAME_PARAMETERS=0x4006, + + + SVA_TM_TVO_ADDR_IN_FRAME_BUFFER =0x5000, + SVA_TM_TVO_ADDR_INIT_PARAMETERS =0x5001, + SVA_TM_TVO_ADDR_IN_PARAMETERS =0x5002 +}t_sva_tm_field_id; + +typedef enum { + FCMD_COPY, + FCMD_NEW_ADDRESS +}t_sva_field_command; + +typedef enum { +/* Enum, Associated data structures, Notes */ + SVA_TM_TCMD_STOP, /* N.A., None */ + SVA_TM_TCMD_START, /* t_sva_tm_timestamp, start conditions of the subtask */ + SVA_TM_TCMD_ABORT, /* N.A., None */ + SVA_TM_TCMD_FAKE_EVENT, /* N.A., None */ + SVA_TM_TCMD_STOP_SLICE, /* N.A., None */ + SVA_TM_TCMD_UPDATE_BUFFER, /* N.A., None */ + SVA_TM_TCMD_STOP_PHYSICAL, /* N.A., None */ + SVA_TM_TCMD_READ_PACKET, /* t_physical_address, physical address of packet to read */ + SVA_TM_TCMD_WRITE_PACKET, /* t_physical_address, physical address of packet to write */ + SVA_TM_TCMD_SAVE_VPIP_STATE,/* t_physical_address, physical address to save VPIP */ + SVA_TM_TCMD_LOAD_VPIP_STATE,/* t_physical_address, physical address to load VPIP */ + SVA_TM_TCMD_GRABHQ_STATUS, /* Grab HQ read status */ + SVA_TM_TCMD_GRABHQ_TST, + SVA_TM_TCMD_GRABHQ_READ_NB_FAILURE_BML_PROCESS +}t_sva_tm_task_cmd_id; + +typedef enum { + SVA_TM_ENCODE, + SVA_TM_DECODE, + SVA_TM_GRAB, + SVA_TM_DISPLAY, + SVA_TM_TVO, + SVA_TM_NO_TASK +}t_sva_tm_task_id; + +typedef enum { + SVA_TM_ONLY_ONE_FIELD_TO_UPDATE, // only one field to update to have a coherent subtask + // semaphore locked when UpdatexSubtaskField starts and unlocked when function ends + SVA_TM_FIRST_FIELD_TO_UPDATE, // semaphore locked when UpdatexSubtaskField starts (no unlock) + SVA_TM_INTERMEDIATE_FIELD_TO_UPDATE,// no semaphore lock or unlock + SVA_TM_LAST_FIELD_TO_UPDATE // semaphore not locked but unlocked when function ends +}t_sva_tm_update_desc; + +/* Virtual hardware event management. */ +typedef struct { + t_sva_service_id serviceId; + t_sva_tm_subtask_id subtaskId; + t_uint32 virtualEventIdMask; + t_sva_timestamp_value eventTimestamp; + t_sva_timestamp_value eventDate; + t_uint32 extraInfos; +} t_sva_tm_virtual_hw_event_desc; + +/*@BORT-$TOP*/ +//ADD SVA_TM_ABORT_HW_EVENT + +typedef enum { + SVA_TM_NO_HW_EVENT = MASK_NULL32, + SVA_TM_BOT_HW_EVENT = ISR_BOT_MASK, + SVA_TM_EOT_HW_EVENT = ISR_EOT_MASK, + SVA_TM_ACK_HW_EVENT = ISR_ACK_MASK, + SVA_TM_EOW_HW_EVENT = ISR_EOW_MASK, + SVA_TM_BOF_HW_EVENT = ISR_BOF_MASK, + SVA_TM_EOF1_HW_EVENT = ISR_EOF1_MASK, + SVA_TM_UBU_HW_EVENT = ISR_UBU_MASK, + SVA_TM_GS_HW_EVENT = ISR_GS_MASK, + SVA_TM_DS_HW_EVENT = ISR_DS_MASK, + SVA_TM_BOW_HW_EVENT = ISR_BOW_MASK, + SVA_TM_EOF2_HW_EVENT = ISR_EOF2_MASK, + SVA_TM_BRC_HW_EVENT = ISR_BRC_MASK, + SVA_TM_EOF_HW_EVENT = ISR_CER_MASK, + SVA_TM_ERR_HW_EVENT = ISR_ERR_MASK, + SVA_TM_EOK_HW_EVENT = ISR_EOK_MASK, + SVA_TM_EOI_HW_EVENT = IIS_EOI_MASK << SHIFT_BYTE1, + SVA_TM_BERR_HW_EVENT = IIS_BE_MASK << SHIFT_BYTE1, + SVA_TM_INACTIVE_HW_EVENT = MASK_BIT10, + SVA_TM_ACTIVE_HW_EVENT = MASK_BIT11, + SVA_TM_FAKE_HW_EVENT = MASK_BIT12, + SVA_TM_PACKET_ERROR_HW_EVENT = MASK_BIT13, + SVA_TM_PACKET_READ_HW_EVENT = MASK_BIT14, + SVA_TM_PACKET_WRITE_HW_EVENT = MASK_BIT15, + SVA_TM_ABORT_HW_EVENT =MASK_BIT16, /*@BORT-$TOP*///New event added + + + /* Please insert bellow and update the following upper boundary */ + SVA_TM_LAST_HW_EVENT =SVA_TM_ABORT_HW_EVENT , + SVA_TM_PADDING_SO_EVENT_MGT_WORK = MASK_BIT30 +} t_sva_tm_virtual_hw_event_id; + +/* Error management. */ +typedef enum { + SVA_TM_MM_XRAM_ERROR = SVA_TM_LAST_ERROR, + SVA_TM_MM_ESRAM_ERROR, + SVA_TM_MM_SDRAM_ERROR, + SVA_TM_BAD_TIMESTAMP_VALUE, + SVA_TM_BAD_TIMESTAMP_TYPE, + SVA_TM_COLLAPSE_WITH_NEXT_SUBTASK_ERROR, + SVA_TM_UPDATE_CURRENT_SUBTASK_FIELD_ERROR, + SVA_TM_SUBTASKLIST_CONNECTED_ERROR, + SVA_TM_BAD_FUNCTION_PARAMETER, + SVA_TM_NO_MORE_SUBTASKLIST_DESC, + SVA_TM_NO_MORE_SUBTASK_DESC, + SVA_TM_NO_MORE_EVENT_DESC, + SVA_TM_TIME_OUT_ERROR, + SVA_TM_OK = SVA_OK, + SVA_WARNING_TM_UPDATE_CURRENT_SUBTASK_LINK = SVA_TM_FIRST_INFO, + SVA_WARNING_TM_DELETE_CURRENT_SUBTASK, + + + + + + + +}t_sva_tm_error; + +/******************************************************************************* +* PUBLIC Functions +*******************************************************************************/ + +/*Init*/ +PUBLIC t_sva_tm_error sva_TM_Init( t_logical_address, t_logical_address ); +PUBLIC t_sva_tm_error sva_TM_Reset( void ); + +/*SubTask Management*/ +PUBLIC t_sva_tm_error sva_TM_CreateSubTask( t_sva_tm_task_id, const t_sva_tm_task_ctrl_desc *, + t_sva_tm_subtask_type, t_sva_tm_postprocessing_type, + t_sva_tm_synchro,t_sva_tm_bot_eot, t_sva_tm_bbm, t_sva_tm_subtask_id*); + +PUBLIC t_sva_tm_error sva_TM_DeleteSubTask( t_sva_tm_subtask_id ); + +/*SubTask List Management */ +PUBLIC t_sva_tm_error sva_TM_CreateSubTaskList( t_sva_tm_task_id, t_sva_service_id, t_sva_fw_features, t_sva_tm_subtask_list_id *); +PUBLIC t_sva_tm_error sva_TM_CreateSubTaskListOpenService( t_sva_tm_task_id, t_sva_service_id, t_sva_fw_id, t_sva_tm_subtask_list_id *); + + +PUBLIC t_sva_tm_error sva_TM_DeleteSubTaskList( t_sva_tm_subtask_list_id ); +PUBLIC t_sva_tm_error sva_TM_AddElemToSubTaskList( t_sva_tm_subtask_list_id, t_sva_tm_subtask_id, t_sva_tm_timestamp *, t_uint32); +PUBLIC t_sva_tm_error sva_TM_RemoveElemFromSubTaskList( t_sva_tm_subtask_list_id, t_sva_tm_subtask_id *); + +PUBLIC t_sva_error sva_TM_ActivateSubTaskList(t_sva_tm_subtask_list_id subtaskListId,t_sva_service_mode serviceMode, + t_sva_fw_id *pFwId); +PUBLIC t_sva_tm_error sva_TM_InActivateSubTaskList( t_sva_tm_subtask_list_id ); + +PUBLIC t_sva_tm_error sva_TM_SendTaskCommand( t_sva_tm_subtask_list_id, t_sva_tm_task_cmd_id, t_uint32); + +PUBLIC t_uint32 sva_TM_GetNbSubTask(t_sva_tm_subtask_list_id); + +// Last parameter: For Open service, last parameter should be true as will not discriminate if should take semaphore or not +PUBLIC t_sva_tm_error sva_TM_GetSubTaskField(t_sva_tm_subtask_id, t_sva_tm_field_id, + t_logical_address, t_uint32, t_size, t_bool); +PUBLIC t_sva_tm_error sva_TM_ConnectSubtasksFields(t_sva_tm_subtask_id, t_sva_tm_field_id, t_sva_tm_subtask_id, t_sva_tm_field_id); +PUBLIC t_sva_tm_error sva_TM_InitSubTaskField(t_sva_tm_subtask_id, t_sva_tm_field_id, t_logical_address, t_size ); +PUBLIC t_sva_tm_error sva_TM_UpdateSubTaskField(t_sva_tm_update_desc, t_sva_tm_subtask_id, + t_sva_tm_field_id, t_sva_field_command,t_uint32, t_uint32, t_size); + + +// Hardware event stuff +PUBLIC t_sva_tm_error sva_TM_DispatchHWEvent( t_sva_tm_task_id, t_uint32, t_uint32, t_uint32, t_uint32, t_uint32, + t_uint8, t_sva_tm_virtual_hw_event_desc *, t_uint32 *); +PUBLIC t_sva_tm_error sva_TM_DispatchEOIEvent( void ); + +// Virtual Hardware event stuff +PUBLIC t_sva_tm_error sva_TM_EnableVirtualHwEvents(t_sva_tm_subtasklist_id, t_sva_tm_virtual_hw_event_id); +PUBLIC t_sva_tm_error sva_TM_DisableVirtualHwEvents(t_sva_tm_subtasklist_id, t_sva_tm_virtual_hw_event_id); +PUBLIC t_sva_tm_error sva_TM_EnableAllVirtualHwEvents(t_sva_tm_subtasklist_id); +PUBLIC t_sva_tm_error sva_TM_DisableAllVirtualHwEvents(t_sva_tm_subtasklist_id); + +#ifdef __cplusplus +} /* allow C++ to use these headers */ +#endif /* __cplusplus */ + +#endif /* __INC_SVA_TASKMGT_H */ +/* End of file - sva_taskmgt.h */ + --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_timemgt.h @@ -0,0 +1,80 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ + +#ifndef __INC_SVA_TI_H +#define __INC_SVA_TI_H + +#include "hcl_defs.h" +#include "sva.h" + +/******************************************************************************/ +/* Constants definitions */ +/******************************************************************************/ + +/* + * Definition of the Nb Max of Services: to be put in a common.h file + */ + +#define SVA_NB_MAX_SERVICE 64 + + +/* + * Definition of the System Time frequency + */ +#define SYSTEM_TIME_FREQUENCY 90000 + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/******************************************************************************/ +/* Types definitions */ +/******************************************************************************/ +/* + * Define the type use to manage HV internal timer ticks + */ +typedef t_uint32 t_sva_ticks; + + +/******************************************************************************* +* PUBLIC Functions +*******************************************************************************/ +PUBLIC t_sva_error sva_TI_Init(t_logical_address, t_logical_address, t_uint32); + +/* Time/synchronization Management */ +/* Implemented here but prototyped into sva.h */ +/*PUBLIC t_sva_error SVA_SetServiceSystemTime(t_sva_service_id, t_uint32); see sva.h */ +/*PUBLIC t_sva_error SVA_GetServiceSystemTime(t_sva_service_id, t_uint32 *); see sva.h */ + + + +PUBLIC t_sva_error sva_TI_GetCurrentTicksValue(t_sva_ticks * ); +PUBLIC t_sva_ticks sva_TI_ConvertHzToTicks( t_uint32 ); +PUBLIC t_sva_ticks sva_TI_ConvertSystemTimeToTicks(t_sva_service_id, t_uint32 ); +PUBLIC t_uint32 sva_TI_ConvertTicksToSystemTime( t_sva_service_id, t_sva_ticks ); +PUBLIC t_sva_error sva_TI_SaveSystemTimeContext(void); +PUBLIC t_sva_error sva_TI_RestoreSystemTimeContext(void); +t_bool sva_IsServiceTimeRunning(t_sva_service_id); + +#ifdef __cplusplus +} /* allow C++ to use these headers */ +#endif /* __cplusplus */ + +#endif /* __INC_SVA_TI_H */ +/* End of file - sva_timemgt.h */ --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_tvo.h @@ -0,0 +1,89 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ + +#ifndef __INC_SVA_TVO_H +#define __INC_SVA_TVO_H + +#include "sva.h" +#include "svap.h" +#include "sva_taskmgt.h" + +/******************************************************************************/ +/* Constants definitions */ +/******************************************************************************/ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* + * Define the symbols used to identify the various errors of the TVO Module + */ +typedef enum { + SVA_TV_INVALID_TRANSITION = SVA_TV_LAST_ERROR, + SVA_TV_NO_MORE_AVAILABLE_INSTANCE, + SVA_TV_INVALID_INSTANCE_NB, + SVA_TV_INVALID_TASK_ID_NB, + SVA_TV_NOT_SUPPORTED, + SVA_TV_INVALID_CONTROL_PARAM, + SVA_TV_INVALID_PUSH, + SVA_TV_INVALID_BUFFER_TYPE, + SVA_TV_INVALID_BUFFER_SIZE, + SVA_TV_INVALID_CONFIGURATION, + SVA_TV_UNKNOWN_CMD_ID, + SVA_TV_UNEXPECTED_HW_EVENT, + SVA_TV_TI_LINKED_ERROR, + SVA_TV_BM_LINKED_ERROR, + SVA_TV_MM_LINKED_ERROR, + SVA_TV_FF_LINKED_ERROR, + SVA_TV_TM_LINKED_ERROR, + SVA_TV_NULL_POINTER_PARAMETER, + SVA_TV_FIFO_NOT_EMPTY, + SVA_TV_OK = HCL_OK +} t_sva_tv_error; + + +/******************************************************************************* +* PUBLIC Functions +*******************************************************************************/ + +PUBLIC t_sva_error sva_TV_Init(void); +PUBLIC t_sva_error sva_TV_Reset( t_sva_service_id ); +PUBLIC t_sva_error sva_TV_Create( t_sva_service_id *); +PUBLIC t_sva_error sva_TV_Control(t_sva_service_id, t_sva_service_cmd_id, t_uint32 ); +PUBLIC t_sva_error sva_TV_Push(t_sva_service_id, t_sva_buffer_id, t_sva_push_mode, t_sva_buffer_type, t_sva_timestamp ); +PUBLIC t_sva_tv_error sva_TV_DispatchVirtualHwEvent(t_sva_tm_virtual_hw_event_id, t_sva_service_id, t_sva_tm_subtask_id, t_uint32, t_uint32, t_uint8, t_sva_event_desc *, t_uint32 *); +PUBLIC t_sva_error sva_TV_ProvideInternalNeeds( t_sva_service_id); +PUBLIC t_sva_error sva_TV_GetInternalNeeds(t_sva_service_id, t_size *); +PUBLIC t_sva_error sva_TV_Activate(t_sva_service_id, t_sva_service_mode, t_sva_fw_id *); +PUBLIC t_sva_error sva_TV_Inactivate(t_sva_service_id); +PUBLIC t_sva_error sva_TV_Delete(t_sva_service_id ); +PUBLIC t_sva_error sva_TV_GetParamsBufferSize(t_sva_service_id ,t_sva_push_mode ,t_size *); +//t_sva_tvo_configuration is in sva.h +// function is sva.h +//PUBLIC t_sva_error SVA_ConfigureTVOutput( t_sva_service_id, t_sva_tvo_configuration); +//PUBLIC t_sva_error SVA_GetTVOutputStatus(t_sva_service_id, t_sva_tvo_status *); +//PUBLIC t_sva_error SVA_UpdateTVOutputParams(t_sva_service_id, t_sva_update_cmd_type, t_sva_tvo_param_id, t_uint32 ); + +#ifdef __cplusplus +} /* allow C++ to use these headers */ +#endif /* __cplusplus */ + +#endif /* __INC_SVA_TVO_H */ +/* End of file - sva_tvo.h */ --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/svap.h @@ -0,0 +1,193 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ + +#ifndef __INC_SVAP_H +#define __INC_SVAP_H + +#include "hcl_defs.h" + +/******************************************************************************/ +/* Constants definitions */ +/******************************************************************************/ +/* + * Define various conditonnal compilation flags in order to include or not any SW workarounds + */ +/*#define WORK_AROUND_AHB*/ + +/* + * Define the maximum number of error defined per module + */ +#define SVA_MODULE_ERROR_RANGE 0x20 + +/* + * Define an Id related to each module of the SVA HCL + * The Id = 1 is reserved for SVA HCL itself + */ +typedef enum { + SVA_EM_ID = 2, /* Events Mgt */ + SVA_MM_ID, /* Memory Mgt */ + SVA_BM_ID, /* Buffers Mgt */ + SVA_BLM_ID, /* Buffers ListMgt */ + SVA_TM_ID, /* Tasks Mgt */ + SVA_FM_ID, /* Firmware Mgt */ + SVA_TI_ID, /* Time Mgt */ + SVA_VP_ID, /* Video Pipeline */ + SVA_FF_ID, /* FIFO macros */ + SVA_IN_ID, /* Internal Needs Mgt */ + SVA_SV_ID, /* Common Service */ + SVA_DP_ID, /* Display Service */ + SVA_DC_ID, /* Decode Service */ + SVA_EC_ID, /* Encode Service */ + SVA_GB_ID, /* Grab Service */ + SVA_DC_ERC_ID, /* Decode Error Concealment */ + SVA_DC_MP4_ID, /* Decode MPEG4 Algo */ + SVA_DC_H263_ID, /* Decode H263 Algo */ + SVA_DC_H264_ID, /* Decode H263 Algo */ + SVA_EC_BRC_ID, /* Encode Bit Rate Control */ + SVA_EC_MP4_ID, /* Encode MPEG4 Algo */ + SVA_EC_H263_ID, /* Encode H263 Algo */ + SVA_EC_H264_ID, /* Encode H264 Algo */ + SVA_EC_STAB_ID, /* Encode Stabilization */ + SVA_SEC_JPEG_ID, /* Still Encode JPEG ALgo */ + SVA_SEC_ID, /* still Encode service */ + SVA_TV_ID /* TVO Service */ +} sva_module_id; + +/* ************************** CONFIGURATION PART ************************** */ + + +//typedef t_uint32 t_sva_fw_id; + + +typedef struct { + t_uint32 cfg_psa; /* Subtask parameter Start Address register */ + t_uint32 cfg_pea; /* Subtask parameter Stop Address register */ + t_uint32 cfg_ice; /* Idle Cycle Enable register */ + t_uint32 cfg_csc; /* CCP synchronization codes register */ + t_uint32 cfg_cgc; /* clock gating control register */ + t_uint32 cfg_irp_fw_addr; /* start address eWarp firmware */ + t_uint32 cfg_irp_fw_size; /* size in bytes of eWarp firmware */ + t_uint32 cfg_irp_rw; /* status of the current rw operation */ + t_uint32 cfg_irp_error; /* error code */ + t_uint32 cfg_irp_bs; /* start of circular buffer for rw packet */ + t_uint32 cfg_irp_be; /* end of circular buffer for rw packet */ + t_uint32 cfg_irp_ptr; /* ptr of circular buffer for rw packet */ + t_uint32 cfg_clk; /* Clock generation register */ + t_uint32 ckg_cken; /* added*/ + t_uint32 cfg_tim; /* Timer Initialization value register */ + t_uint32 cfg_iis; /* IRQ1 Interrupt Status register */ + t_uint32 cfg_isr; /* Global Interrupt status register */ + t_uint32 cfg_imr; /* Global Interrupt mask register */ +// t_uint32 wasDeepSleepEntered; + t_uint32 temp_idn_frv; + t_uint32 fwId; + t_uint32 sva_context_magic_number; +} t_sva_config_regs_mapping1; + +#define SVA_CONTEXT_MAGIC_NUMBER 0x53415645UL + +#define SVA_EM_LAST_ERROR (-(SVA_EM_ID * SVA_MODULE_ERROR_RANGE)) +#define SVA_EM_FIRST_INFO (+((SVA_DP_ID - 1) * SVA_MODULE_ERROR_RANGE)) + +#define SVA_MM_LAST_ERROR (-(SVA_MM_ID * SVA_MODULE_ERROR_RANGE)) +#define SVA_MM_FIRST_INFO (+((SVA_MM_ID - 1) * SVA_MODULE_ERROR_RANGE)) + +#define SVA_BM_LAST_ERROR (-(SVA_BM_ID * SVA_MODULE_ERROR_RANGE)) +#define SVA_BM_FIRST_INFO (+((SVA_BM_ID - 1) * SVA_MODULE_ERROR_RANGE)) + +#define SVA_BLM_LAST_ERROR (-(SVA_BLM_ID * SVA_MODULE_ERROR_RANGE)) +#define SVA_BLM_FIRST_INFO (+((SVA_BLM_ID - 1) * SVA_MODULE_ERROR_RANGE)) + +#define SVA_TM_LAST_ERROR (-(SVA_TM_ID * SVA_MODULE_ERROR_RANGE)) +#define SVA_TM_FIRST_INFO (+((SVA_TM_ID - 1) * SVA_MODULE_ERROR_RANGE)) + +#define SVA_FM_LAST_ERROR (-(SVA_FM_ID * SVA_MODULE_ERROR_RANGE)) +#define SVA_FM_FIRST_INFO (+((SVA_FM_ID - 1) * SVA_MODULE_ERROR_RANGE)) + +#define SVA_TI_LAST_ERROR (-(SVA_TI_ID * SVA_MODULE_ERROR_RANGE)) +#define SVA_TI_FIRST_INFO (+((SVA_TI_ID - 1) * SVA_MODULE_ERROR_RANGE)) + +#define SVA_FF_LAST_ERROR (-(SVA_FF_ID * SVA_MODULE_ERROR_RANGE)) +#define SVA_FF_FIRST_INFO (+((SVA_FF_ID - 1) * SVA_MODULE_ERROR_RANGE)) + +#define SVA_IN_LAST_ERROR (-(SVA_IN_ID * SVA_MODULE_ERROR_RANGE)) +#define SVA_IN_FIRST_INFO (+((SVA_IN_ID - 1) * SVA_MODULE_ERROR_RANGE)) + +#define SVA_SV_LAST_ERROR (-(SVA_SV_ID * SVA_MODULE_ERROR_RANGE)) +#define SVA_SV_FIRST_INFO (+((SVA_SV_ID - 1) * SVA_MODULE_ERROR_RANGE)) + +#define SVA_DP_LAST_ERROR (-(SVA_DP_ID * SVA_MODULE_ERROR_RANGE)) +#define SVA_DP_FIRST_INFO (+((SVA_DP_ID - 1) * SVA_MODULE_ERROR_RANGE)) + +#define SVA_DC_LAST_ERROR (-(SVA_DC_ID * SVA_MODULE_ERROR_RANGE)) +#define SVA_DC_FIRST_INFO (+((SVA_DC_ID - 1) * SVA_MODULE_ERROR_RANGE)) + +#define SVA_EC_LAST_ERROR (-(SVA_EC_ID * SVA_MODULE_ERROR_RANGE)) +#define SVA_EC_FIRST_INFO (+((SVA_EC_ID - 1) * SVA_MODULE_ERROR_RANGE)) + +#define SVA_GB_LAST_ERROR (-(SVA_GB_ID * SVA_MODULE_ERROR_RANGE)) +#define SVA_GB_FIRST_INFO (+((SVA_GB_ID - 1) * SVA_MODULE_ERROR_RANGE)) + +#define SVA_DC_ERC_LAST_ERROR (-(SVA_DC_ERC_ID * SVA_MODULE_ERROR_RANGE)) +#define SVA_DC_ERC_FIRST_INFO (+((SVA_DC_ERC_ID - 1) * SVA_MODULE_ERROR_RANGE)) + +#define SVA_DC_MP4_LAST_ERROR (-(SVA_DC_MP4_ID * SVA_MODULE_ERROR_RANGE)) +#define SVA_DC_MP4_FIRST_INFO (+((SVA_DC_MP4_ID - 1) * SVA_MODULE_ERROR_RANGE)) + +#define SVA_DC_H263_LAST_ERROR (-(SVA_DC_H263_ID * SVA_MODULE_ERROR_RANGE)) +#define SVA_DC_H263_FIRST_INFO (+((SVA_DC_H263_ID - 1) * SVA_MODULE_ERROR_RANGE)) + +#define SVA_DC_H264_LAST_ERROR (-(SVA_DC_H264_ID * SVA_MODULE_ERROR_RANGE)) +#define SVA_DC_H264_FIRST_INFO (+((SVA_DC_H264_ID - 1) * SVA_MODULE_ERROR_RANGE)) + + +#define SVA_EC_BRC_LAST_ERROR (-(SVA_EC_BRC_ID * SVA_MODULE_ERROR_RANGE)) +#define SVA_EC_BRC_FIRST_INFO (+((SVA_EC_BRC_ID - 1) * SVA_MODULE_ERROR_RANGE)) + +#define SVA_EC_MP4_LAST_ERROR (-(SVA_EC_MP4_ID * SVA_MODULE_ERROR_RANGE)) +#define SVA_EC_MP4_FIRST_INFO (+((SVA_EC_MP4_ID - 1) * SVA_MODULE_ERROR_RANGE)) + +#define SVA_EC_H263_LAST_ERROR (-(SVA_EC_H263_ID * SVA_MODULE_ERROR_RANGE)) +#define SVA_EC_H263_FIRST_INFO (+((SVA_EC_H263_ID - 1) * SVA_MODULE_ERROR_RANGE)) + +#define SVA_EC_H264_LAST_ERROR (-(SVA_EC_H264_ID * SVA_MODULE_ERROR_RANGE)) +#define SVA_EC_H264_FIRST_INFO (+((SVA_EC_H264_ID - 1) * SVA_MODULE_ERROR_RANGE)) + +#define SVA_EC_STAB_LAST_ERROR (-(SVA_EC_STAB_ID * SVA_MODULE_ERROR_RANGE)) +#define SVA_EC_STAB_FIRST_INFO (+((SVA_EC_STAB_ID - 1) * SVA_MODULE_ERROR_RANGE)) + +#define SVA_SEC_JPEG_LAST_ERROR (-(SVA_SEC_JPEG_ID * SVA_MODULE_ERROR_RANGE)) +#define SVA_SEC_JPEG_FIRST_INFO (+((SVA_SEC_JPEG_ID - 1) * SVA_MODULE_ERROR_RANGE)) + +#define SVA_SEC_LAST_ERROR (-(SVA_SEC_ID * SVA_MODULE_ERROR_RANGE)) +#define SVA_SEC_FIRST_INFO (+((SVA_SEC_ID - 1) * SVA_MODULE_ERROR_RANGE)) + +#define SVA_TV_LAST_ERROR (-(SVA_TV_ID * SVA_MODULE_ERROR_RANGE)) +#define SVA_TV_FIRST_ERROR (+((SVA_TV_ID - 1) * SVA_MODULE_ERROR_RANGE)) + +/******************************************************************************/ +/* Types definitions */ +/******************************************************************************/ + +#ifdef __cplusplus +} /* allow C++ to use these headers */ +#endif /* __cplusplus */ + +#endif /* __INC_SVAP_H */ +/* End of file - hvP.h */ --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/t1xhv_host_interface.h @@ -0,0 +1,1725 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ + +#ifndef _T1XHV_HOST_INTERFACE_H_ +#define _T1XHV_HOST_INTERFACE_H_ + +/* + * Includes + */ +#include "t1xhv_retarget.h" + +/* + * Types + */ + +/*****************************************************************************/ +/** + * \brief Parameter common structure + * \author Philippe Rochette + * + * Parameter common structure + */ +/*****************************************************************************/ + +/** + * \brief This structure define one link to a subtask description. + */ +typedef struct t1xhv_subtask_link { + + t_ahb_address addr; /**<\brief Add. of associated subtask */ + t_ulong_value type; /**<\brief Define type for subtask */ + t_time_stamp execution_time_stamp; /**<\brief Define time to start subtask */ + t_ulong_value dependency; /**<\brief Coded depend. between tasks */ + +} ts_t1xhv_subtask_link, *tps_t1xhv_subtask_link; + + +/** + * \brief This structure define Parameters in Memory for Subtask parameters. + */ +typedef struct t1xhv_subtask_descriptor { + + ts_t1xhv_subtask_link s_next_subtask; /**<\brief Link to next subtask + * -- ts_t1xhv_subtask_link */ + ts_t1xhv_subtask_link s_current_subtask; /**<\brief Link to current subtask + * -- ts_t1xhv_subtask_link */ + ts_t1xhv_subtask_link s_interrupt_subtask; /**<\brief Link to interrupt subtask + * -- ts_t1xhv_subtask_link */ + t_ulong_value task_count; /**<\brief Task counter (0 if no + * more task) + */ + +} ts_t1xhv_subtask_descriptor, *tps_t1xhv_subtask_descriptor; + + +/** \brief This structure define Parameters needed to For begin/end of buffer. */ +typedef struct t1xhv_bitstream_buf_pos { + + t_ahb_address addr_bitstream_buf_struct; /**<\brief Choose buffer structure */ + t_ahb_address addr_bitstream_start; /**<\brief Bitstream Start add. inside buffer */ + t_ulong_value bitstream_offset; /**<\brief Bitstream offset in bits */ + t_ulong_value reserved_1; /**<\brief Reserved 32 */ + +} ts_t1xhv_bitstream_buf_pos, *tps_t1xhv_bitstream_buf_pos; + + +/** \brief This structure define a bitstream buffer. */ +typedef struct t1xhv_bitstream_buf { + + t_ahb_address addr_buffer_start; /**<\brief Buffer start */ + t_ahb_address addr_buffer_end; /**<\brief Buffer end */ + t_ahb_address addr_window_start; /**<\brief Window start (inside buffer) */ + t_ahb_address addr_window_end; /**<\brief Windows end (inside buffer) */ + +} ts_t1xhv_bitstream_buf, *tps_t1xhv_bitstream_buf; + + +/** \brief This structure define a link buffer. */ +typedef struct t1xhv_bitstream_buf_link { + + t_ahb_address addr_next_buf_link; /**<\brief Address next structure */ + t_ahb_address addr_prev_buf_link; /**<\brief Address prev structure */ + t_ahb_address addr_buffer_start; /**<\brief Bitstream buffer start */ + t_ahb_address addr_buffer_end; /**<\brief Bitstream buffer end */ + +} ts_t1xhv_bitstream_buf_link, *tps_t1xhv_bitstream_buf_link; + + +/** \brief This structure define an header buffer. */ +typedef struct t1xhv_header_buf { + + t_ahb_address addr_header_buffer; /**<\brief Start add. of the header buffer */ + t_ulong_value header_size; /**<\brief Header size */ + t_ahb_address reserved_1; /**<\brief Reserved 32 */ + t_ahb_address reserved_2; /**<\brief Reserved 32 */ + +} ts_t1xhv_header_buf, *tps_t1xhv_header_buf; + + + + +/*****************************************************************************/ +/** + * \brief Parameter structure decode + * \author Philippe Rochette + * + * Parameter structure for decode H264, MPEG4, JPEG and H263. + * Hamac Video Spec v0.1 sections 6.5 and 13.2 + */ +/*****************************************************************************/ + +/** \brief This structure define description of a subtask decode. */ +typedef struct t1xhv_vdc_subtask_param { + + ts_t1xhv_subtask_link s_link; /**<\brief Link to next subtask (chained list) + * -- ts_t1xhv_subtask_link + */ + t_ahb_address addr_in_frame_buffer; /**<\brief Add. of struct for input frame buffer + * -- ts_t1xhv_vdc_frame_buffer_in + */ + t_ahb_address addr_out_frame_buffer; /**<\brief Add. of struct for output frame buffer + * -- ts_t1xhv_vdc_frame_buffer_out + */ + t_ahb_address addr_internal_buffer; /**<\brief Add. of struct for internal buffer + * -- ts_t1xhv_vdc_internal_buf + */ + t_ahb_address addr_in_bitstream_buffer; /**<\brief Add. of struct for in bitstream buffer + * -- ts_t1xhv_bitstream_buffer + */ + t_ahb_address addr_out_bitstream_buffer; /**<\brief Add. of struct for out bitstream buffer + * -- ts_t1xhv_bitstream_buffer_position + */ + t_ahb_address addr_in_parameters; /**<\brief Add. of struct for input parameters + * of decode (depend on standard) + */ + t_ahb_address addr_out_parameters; /**<\brief Add. of struct for output parameters + * of decode (depend on standard) + */ + t_ahb_address addr_in_frame_parameters; /**<\brief Add. of struct for input frame parameters + * of decode (depend on standard) + */ + t_ahb_address addr_out_frame_parameters; /**<\brief Add. of struct for output frame parameters + * of decode (depend on standard) + */ + t_ahb_address reserved_1; /**<\brief Reserved 32 */ + t_ahb_address reserved_2; /**<\brief Reserved 32 */ + t_ahb_address reserved_3; /**<\brief Reserved 32 */ + +} ts_t1xhv_vdc_subtask_param, *tps_t1xhv_vdc_subtask_param; + + + +/** \brief This structure define a reference frame buffer. */ +typedef struct t1xhv_vdc_frame_buf_in { + + t_ahb_address addr_fwd_ref_buffer; /**<\brief Address of Forward reference buffer. */ + t_ahb_address addr_bwd_ref_buffer; /**<\brief Address of backward reference buffer */ + t_ulong_value reserved_2; /**<\brief Reserved 32 */ + t_ulong_value reserved_3; /**<\brief Reserved 32 */ + +} ts_t1xhv_vdc_frame_buf_in, *tps_t1xhv_vdc_frame_buf_in; + + +/** \brief This structure define a reference frame buffer. */ +typedef struct t1xhv_vdc_internal_buf { + + t_ahb_address addr_h264d_H4D_buffer; /**<\brief Address of temporary buffer used by H4D for H264. */ + t_ahb_address addr_h264d_block_info; /**<\brief Address of block_info */ + t_ahb_address addr_h264d_mb_slice_map; /**<\brief Address of mb_slice_map */ + t_ahb_address addr_mv_history_buffer; /**<\brief VC1 motion vector history buffer (for B framesdecoding) */ + +} ts_t1xhv_vdc_internal_buf, *tps_t1xhv_vdc_internal_buf; + + +/** \brief This structure define an output frame buffer. */ +typedef struct t1xhv_vdc_frame_buf_out { + + t_ahb_address addr_dest_buffer; /**<\brief Address of output frame buffer. */ + t_ahb_address addr_deblocking_param_buffer; /**<\brief Address of parameters for PPP. */ + t_ahb_address addr_motion_vector_buffer; /**<\brief Start add of motion vector buffer */ + t_ahb_address addr_jpeg_coef_buffer; /**<\brief Start address of JPEG Coef buffer */ + t_ahb_address addr_jpeg_line_buffer; /**<\brief Start address of JPEG line buffer */ + t_ulong_value reserved_1; /**<\brief Reserved 32 */ + t_ulong_value reserved_2; /**<\brief Reserved 32 */ + t_ulong_value reserved_3; /**<\brief Reserved 32 */ + +} ts_t1xhv_vdc_frame_buf_out, *tps_t1xhv_vdc_frame_buf_out; + + +/** \brief Structure for parameters FROM Host for a H264 decode task */ +typedef struct t1xhv_vdc_h264_param_in { + + t_ahb_address addr_first_slice; /**<\brief address of first slice info structure */ + t_ushort_value parsing_error; /**<\brief slice header parsing error */ + t_ushort_value DBLK_flag; /**<\brief DBLK_flag == 0 : No deblocking (no more bit true ) * + * DBLK_flag == 1 : Deblocking at the end of decode * + * DBLK_flag == 3 : Deblocking parallelized with decode * + * ( possible when no FMO ) */ + t_ushort_value ERC_used; /**<\brief ERC_used == 0 : no Errors in bitstream can occur * + * ERC_used == 1 : Errors in bitstream can occur */ + t_ushort_value intra_conc; /**<\brief flag for concealment updated in SVA */ + t_ulong_value reserved_2; /**<\brief Reserved 32 */ + +} ts_t1xhv_vdc_h264_param_in, *tps_t1xhv_vdc_h264_param_in; + +/** \brief Structure for parameters FROM and TO Host for a H264 decode task */ +typedef struct t1xhv_vdc_h264_param_inout { + + t_ulong_value reserved_1; /**<\brief Reserved 32 */ + t_ulong_value reserved_2; /**<\brief Reserved 32 */ + t_ulong_value reserved_3; /**<\brief Reserved 32 */ + t_ulong_value reserved_4; /**<\brief Reserved 32 */ + +} ts_t1xhv_vdc_h264_param_inout, *tps_t1xhv_vdc_h264_param_inout; + +/** \brief Structure for parameters TO Host for a H264 decode task */ +typedef struct t1xhv_vdc_h264_param_out { + + t_ushort_value picture_loss; /**<\brief number of decoded macroblocks */ + t_ushort_value mb_count; /**<\brief number of decoded macroblocks */ + t_ulong_value reserved_2; /**<\brief reserved 32 */ + t_ulong_value reserved_3; /**<\brief Reserved 32 */ + t_ulong_value reserved_4; /**<\brief Reserved 32 */ + t_ushort_value slice_loss_first_mb[8]; + t_ushort_value slice_loss_mb_num[8]; + +} ts_t1xhv_vdc_h264_param_out, *tps_t1xhv_vdc_h264_param_out; + +/** \brief Structure for parameters TO Host for H264 to decode 1 slice */ +typedef struct t1xhv_vdc_h264_slice { + t_ushort_value discarded_slice; /**<\brief flag set by host for discarded slice */ + t_ushort_value pic_width_in_mbs; /**<\brief pic width in macroblocks */ + t_ushort_value pic_height_in_map_units; /**<\brief pic height in macroblocks */ + t_ushort_value chroma_qp_index_offset; /**<\brief chroma qp index offset */ + t_ushort_value constr_intra_pred_flag; /**<\brief constr intra pred flag */ + t_ushort_value first_mb_in_slice; /**<\brief first macroblock of the slice */ + t_ushort_value slice_qp; /**<\brief Initial Qp value for the slice */ + t_ushort_value slice_type; /**<\brief slice coding type */ + t_ushort_value slice_num; /**<\brief number of the slice in the current frame */ + t_ushort_value num_ref_idx_l0_active_minus1; /**<\brief maximum reference index for reference frame */ + t_ushort_value s_info_disable_filter; /**<\brief 1 = disable filter for the slie */ + t_ushort_value s_info_alpha_c0_offset_div2; /**<\brief offset used for alpha and tc0 tables (deblocking)*/ + t_ushort_value s_info_beta_offset_div2; /**<\brief offset used for beta table (deblocking) */ + t_ushort_value reserved_1; /**<\brief Reserved 16 */ + t_ahb_address addr_list0[17]; /**<\brief reference picture 0 */ + t_ahb_address addr_bitstream_buf_struct; /**<\brief bitstream buffer structure address */ + t_ahb_address addr_bitstream_start; /**<\brief bitstream position 16 byte aligned */ + t_ulong_value bitstream_offset; /**<\brief bitstream position offset */ + t_ulong_value bitstream_size_in_bytes; /**<\brief bitstream size in bytes for current slice */ + t_ahb_address addr_next_h264_slice; /**<\brief address for next slice (NULL is no more slice) */ + t_long_value reserved_2; /**<\brief Reserved 32 */ + t_long_value reserved_3; /**<\brief Reserved 32 */ + t_long_value reserved_4; /**<\brief Reserved 32 */ +} ts_t1xhv_vdc_h264_slice, *tps_t1xhv_vdc_h264_slice; + + +/** \brief Structure for parameters FROM Host for a MPEG4 decode task */ +typedef struct t1xhv_vdc_mpeg4_param_in { + t_ushort_value picture_coding_type; /**<\brief Current pict I,P or B */ + t_ushort_value quant; /**<\brief Quantization parameter */ + t_ushort_value quant_type ; /**<\brief ASP-Selects method 1 (1) or 2 (0) inverse quantisation */ + t_ushort_value intra_quant_mat[64] ; /**<\brief ASP-inverse intra quantisation matrix */ + t_ushort_value nonintra_quant_mat[64] ; /**<\brief ASP-inverse non intra quantisation matrix */ + t_ushort_value low_delay ; /**<\brief ASP-if 0 => B frames */ + t_ushort_value interlaced ; /**<\brief ASP-if 1 => interlaced mode */ + t_ushort_value rounding_type; /**<\brief Rounding type */ + t_ushort_value intra_dc_vlc_thr; /**<\brief Threshold to consider DC as AC coeff */ + t_ushort_value vop_fcode_forward; /**<\brief Fcode to decode MV */ + t_ushort_value vop_fcode_backward ; /**<\brief ASP-Fcode to decode MV */ + t_ushort_value frame_width; /**<\brief Nb of pixel per line */ + t_ushort_value frame_height; /**<\brief Nb of line */ + t_ushort_value flag_short_header; /**<\brief Short Header mode if =1 */ + t_ushort_value modulo_time_base ; /**<\brief ASP-needed for TRB and TRD computation */ + t_ushort_value vop_time_increment ; /**<\brief ASP-needed for TRB and TRD computation */ + t_ushort_value vop_time_increment_resolution; /**<\brief VOP time increment */ + t_ushort_value resync_marker_disable; /**<\brief Resync Marker Disable */ + t_ushort_value data_partitioned; /**<\brief Data Partitioned */ + t_ushort_value reversible_vlc; /**<\brief Reversible VLC */ + t_ushort_value error_concealment_config; /**<\brief Error Concealment MPEG4 */ + t_ushort_value reserved_1; /**<\brief Reserved 16 */ + t_ulong_value reserved_2; /**<\brief Reserved 32 */ + +} ts_t1xhv_vdc_mpeg4_param_in, *tps_t1xhv_vdc_mpeg4_param_in; + +/** \brief Structure for parameters FROM and TO Host for a MPEG4 decode task */ +typedef struct t1xhv_vdc_mpeg4_param_inout { + + t_ulong_value reserved_1; /**<\brief Reserved 32 */ + t_ulong_value reserved_2; /**<\brief Reserved 32 */ + t_ulong_value reserved_3; /**<\brief Reserved 32 */ + t_ulong_value reserved_4; /**<\brief Reserved 32 */ + +} ts_t1xhv_vdc_mpeg4_param_inout, *tps_t1xhv_vdc_mpeg4_param_inout; + + +/** \brief Structure for parameters TO Host for a MPEG4 decode task */ +typedef struct t1xhv_vdc_mpeg4_param_out { + + t_ushort_value error_type; /**<\brief Return bitstream error type */ + t_ushort_value picture_loss; /**<\brief Picturee loss flags */ + t_ushort_value slice_loss_first_mb[8]; /**<\brief Slice lost first macroblock */ + t_ushort_value slice_loss_mb_num[8]; /**<\brief Slice loss MB number */ + t_ushort_value concealed_mb_num; /**<\brief NB of Concealed MacroBlock */ + t_ushort_value concealed_vp_num; /**<\brief NB of Concealed video packets */ + t_ushort_value decoded_vp_num; /**<\brief NB of video packets decoded */ + + t_ushort_value reserved_1; /**<\brief Reserved 32 */ + t_ulong_value reserved_2; /**<\brief Reserved 32 */ + +} ts_t1xhv_vdc_mpeg4_param_out, *tps_t1xhv_vdc_mpeg4_param_out; + +/** \brief Structure for parameters FROM and TO Host for a MPEG2 decode task */ +typedef struct t1xhv_vdc_mpeg2_param_in { + t_ushort_value vertical_size; + t_ushort_value mb_width; + t_ushort_value mb_height; + t_ushort_value intra_quantizer_matrix[64]; + t_ushort_value non_intra_quantizer_matrix[64]; + t_ushort_value picture_coding_type; + t_ushort_value full_pel_forward_vector; + t_ushort_value forward_f_code; + t_ushort_value full_pel_backward_vector; + t_ushort_value backward_f_code; + t_ushort_value f_code[2][2]; + t_ushort_value intra_dc_precision; + t_ushort_value picture_structure; + t_ushort_value top_field_first; + t_ushort_value frame_pred_frame_dct; + t_ushort_value concealment_motion_vectors; + t_ushort_value q_scale_type; + t_ushort_value intra_vlc_format; + t_ushort_value alternate_scan; + t_ushort_value scalable_mode; + t_ushort_value MPEG2_Flag; + t_ulong_value reserved1; + +} ts_t1xhv_vdc_mpeg2_param_in, *tps_t1xhv_vdc_mpeg2_param_in; + +typedef struct t1xhv_vdc_mpeg2_param_out { + t_ushort_value error_type; /**<\brief Return bitstream error type */ + t_ushort_value reserved_1; + t_ulong_value reserved_2; + t_ulong_value reserved_3; + t_ulong_value reserved_4; + +} ts_t1xhv_vdc_mpeg2_param_out, *tps_t1xhv_vdc_mpeg2_param_out; + +/** \brief Structure for parameters FROM Host for a H263 decode task */ +typedef struct t1xhv_vdc_h263_param_in { + + t_ushort_value picture_coding_type; /**<\brief True if inter picture, false if intra */ + t_ushort_value quant; /**<\brief Quantification parameter for current + * frame + */ + t_ushort_value rounding_type; /**<\brief Rounding control parameters*/ + t_ushort_value enable_annexes; /**<\brief - Enable mv over picture boundary + * - Enable 4 mv + * - Enable AC/DC prediction + * - Enable deblocking filter + * - Enable slice structure + * - Enable modified quantization + */ + t_ushort_value frame_width; /**<\brief Nb of pixel per line */ + t_ushort_value frame_height; /**<\brief Nb of line */ + t_ushort_value error_concealment_config; /**<\brief Error Concealment MPEG4 */ + t_ushort_value reserved_1; /**<\brief Start code detection */ + +} ts_t1xhv_vdc_h263_param_in, *tps_t1xhv_vdc_h263_param_in; + +/** \brief Structure for parameters FROM and TO Host for a H263 decode task */ +typedef struct t1xhv_vdc_h263_param_inout { + + t_ulong_value reserved_1; /**<\brief Reserved 32 */ + t_ulong_value reserved_2; /**<\brief Reserved 32 */ + t_ulong_value reserved_3; /**<\brief Reserved 32 */ + t_ulong_value reserved_4; /**<\brief Reserved 32 */ + +} ts_t1xhv_vdc_h263_param_inout, *tps_t1xhv_vdc_h263_param_inout; + +/** \brief Structure for parameters TO Host for a H263 decode task */ +typedef struct t1xhv_vdc_h263_param_out { + + t_ushort_value error_type; /**<\brief Return bitstream error type */ + t_ushort_value picture_loss; /**<\brief Picturee loss flags */ + t_ushort_value slice_loss_first_mb[8]; /**<\brief Slice lost first macroblock */ + t_ushort_value slice_loss_mb_num[8]; /**<\brief Slice loss MB number */ + t_ushort_value concealed_mb_num; /**<\brief NB of Concealed MacroBlock */ + t_ushort_value concealed_vp_num; /**<\brief NB of Concealed video packets */ + t_ushort_value decoded_vp_num; /**<\brief NB of video packets decoded */ + + t_ushort_value reserved_1; /**<\brief Reserved 32 */ + t_ulong_value reserved_2; /**<\brief Reserved 32 */ + +} ts_t1xhv_vdc_h263_param_out, *tps_t1xhv_vdc_h263_param_out; + +/** \brief Structure for parameters FROM Host for a JPEG decode task */ +typedef struct t1xhv_vdc_jpeg_param_in { + + t_ushort_value frame_width; /**<\brief Nb of pixel per line*/ + t_ushort_value frame_height; /**<\brief Nb of line*/ + t_ushort_value nb_components; /**<\brief Nb of components in the scan */ + + t_ushort_value h_sampling_factor_y; /**< \brief horizontal sampling factor of Y */ + t_ushort_value v_sampling_factor_y; /**< \brief vertical sampling factor of Y */ + + t_ushort_value h_sampling_factor_cb; /**< \brief horizontal sampling factor of Cb */ + t_ushort_value v_sampling_factor_cb; /**< \brief vertical sampling factor of Cb */ + + t_ushort_value h_sampling_factor_cr; /**< \brief horizontal sampling factor of Cr */ + t_ushort_value v_sampling_factor_cr; /**< \brief vertical sampling factor of Cr */ + + t_ushort_value downsampling_factor; /**< \brief 1,1/2,1/4,1/8 */ + + t_ushort_value restart_interval; /**< \brief restart interval segment length (Ri) */ + + t_ushort_value progressive_mode; /**< \brief SOF2 */ + + t_ushort_value nb_scan_components; /**< \brief number of image component in frame (Nf) */ + + t_ushort_value component_selector_y; /**< \brief ==1 if y present in current scan */ + t_ushort_value component_selector_cb; /**< \brief ==1 if cb present in current scan */ + t_ushort_value component_selector_cr; /**< \brief ==1 if cr present in current scan */ + + t_ushort_value start_spectral_selection; /**< \brief start of spectral selection + * in progressive mode (Ss) + */ + t_ushort_value end_spectral_selection; /**< \brief end of spectral selection + * in progressive mode (Se) + */ + t_ushort_value successive_approx_position; /**< \brief Al value (low) */ + t_ushort_value ace_enable; /**< \brief ask for 420 data processing:unused */ + t_ushort_value ace_strength; /**< \brief ask for 420 data processing:unused */ + t_ushort_value reserved_1; /**<\brief Reserved 16 */ + t_ulong_value reserved_2; /**<\brief Reserved 32 */ + + t_ushort_value quant_y[64]; /**< \brief y quantization table */ + t_ushort_value quant_cb[64]; /**< \brief cb quantization table */ + t_ushort_value quant_cr[64]; /**< \brief cr quantization table */ + + t_ushort_value huffman_y_code_dc[12]; /**<\brief DC Huffman code table for luma */ + t_ushort_value huffman_y_size_dc[12]; /**<\brief DC Huffman size table for luma */ + t_ushort_value huffman_y_code_ac[256]; /**<\brief AC Huffman size table for luma */ + t_ushort_value huffman_y_size_ac[256]; /**<\brief AC Huffman code table for luma */ + + t_ushort_value huffman_cb_code_dc[12]; /**<\brief DC Huffman size table for chroma */ + t_ushort_value huffman_cb_size_dc[12]; /**<\brief DC Huffman code table for chroma */ + t_ushort_value huffman_cb_code_ac[256]; /**<\brief AC Huffman size table for chroma */ + t_ushort_value huffman_cb_size_ac[256]; /**<\brief AC Huffman code table for chroma */ + + t_ushort_value huffman_cr_code_dc[12]; /**<\brief DC Huffman size table for chroma */ + t_ushort_value huffman_cr_size_dc[12]; /**<\brief DC Huffman code table for chroma */ + t_ushort_value huffman_cr_code_ac[256]; /**<\brief AC Huffman size table for chroma */ + t_ushort_value huffman_cr_size_ac[256]; /**<\brief AC Huffman code table for chroma */ + t_ushort_value window_width; /**<\brief Crop window width */ + t_ushort_value window_height; /**<\brief Crop window height */ + t_ushort_value window_horizontal_offset; /**<\brief offset of window width when there's a crop*/ + t_ushort_value window_vertical_offset; /**<\brief offset of window height when there's a crop*/ + t_ulong_value reserved_3; /**<\brief Reserved 32 */ + t_ulong_value reserved_4; /**<\brief Reserved 32 */ + +} ts_t1xhv_vdc_jpeg_param_in, *tps_t1xhv_vdc_jpeg_param_in; + + +/** \brief Structure for output parameters of JPEG encode task */ +typedef struct t1xhv_vdc_jpeg_param_out { + + t_ushort_value error_type; /**<\brief Error status */ + t_ushort_value reserved_1; /**<\brief Reserved 16 */ + t_short_value ace_offset0; /**<\brief Automatic Contrast Enhancement offet 0 */ + t_short_value ace_offset1; /**<\brief Automatic Contrast Enhancement offet 1 */ + t_short_value ace_offset2; /**<\brief Automatic Contrast Enhancement offet 2 */ + t_short_value ace_offset3; /**<\brief Automatic Contrast Enhancement offet 3 */ + t_ulong_value reserved_2; /**<\brief Reserved 32 */ + +} ts_t1xhv_vdc_jpeg_param_out, *tps_t1xhv_vdc_jpeg_param_out; + +typedef struct t1xhv_vdc_jpeg_param_inout { + + t_ulong_value mcu_index; /**<\brief MCU index */ + t_ulong_value end_of_band_run; /**< \brief end of band value in progressive mode */ + t_ushort_value dc_predictor_y; /**<\brief Luma DC ppredictor */ + t_ushort_value dc_predictor_cb; /**<\brief Cb chroma DC predictor */ + t_ushort_value dc_predictor_cr; /**<\brief Cr Chroma DC predictot */ + t_ushort_value reserved_1; /**<\brief Reserved 32 */ + t_ulong_value ace_count0; /**<\brief Automatic Contrast Enhancement offet 0 */ + t_ulong_value ace_count1; /**<\brief Automatic Contrast Enhancement offet 1 */ + t_ulong_value ace_count2; /**<\brief Automatic Contrast Enhancement offet 2 */ + t_ulong_value ace_count3; /**<\brief Automatic Contrast Enhancement offet 3 */ + t_ulong_value crop_mcu_index; /**<\brief MCU index in crop */ + t_ulong_value crop_mcu_index_in_row; /**<\brief MCU index in crop in row */ + t_ulong_value reserved_2; /**<\brief Reserved 32 */ + t_ulong_value reserved_3; /**<\brief Reserved 32 */ + +} ts_t1xhv_vdc_jpeg_param_inout, *tps_t1xhv_vdc_jpeg_param_inout; + + +/** @{ \name enable_annexes parameter bitfield definition + * \author Jean-Marc Volle + * \note Spec V0.95 p348 + */ + +/** \brief Enable Annex D.1: + * As an input,EAD allows to enable the annex D.1 + * (motion vectors over picture boundaries)for an H263 decode + * subtask.It is not used if picture_coding_type=0.In the profiles + * that are currently supported,it must be equal to EAJ,otherwise + * error_type is set to 0xc4. As an output,EAD returns the annex D.1 + * enable ag for the next frame found in the bitstream,if enable_scd=1 + * (if enable_scd=0,this eld is unde ned).It is equal to the EAJ + * output. 0 =annex disabled 1 =annex enabled + */ +#define ENABLE_ANNEXES_EAD 0x0001 + +/** \brief Enable Annex F.2: + * As an input,EAF allows to enable the annex F.2 (four motion + * vectors per macroblock)for an H263 decode subtask.It is not + * used if picture_coding_type=0.In the pro les that are currently + * supported,it must be equal to EAJ,otherwise error_type is set to + * 0xc5. As an output,EAF returns the annex F.2 enable ag for the + * next frame found in the bitstream,if enable_scd=1 (if enable_scd=0, + * this field is undefined).It is equal to the EAJ output. + */ +#define ENABLE_ANNEXES_EAF 0x0002 + +/** \brief Enable Annex I: + * As an input,EAI allows to enable the annex I (advanced intra coding) + * for an H263 decode subtask. As an output,EAI returns the annex I + * enable flag for the next frame found in the bitstream,if enable_scd=1 + * (if enable_scd=0,this field is undefined).It is obtained from the + * OPPTYPE eld of the H263 bitstream. + */ +#define ENABLE_ANNEXES_EAI 0x0004 + +/** \brief Enable Annex J: + * As an input,EAJ allows to enable the annex J (deblocking lter)for + * an H263 decode subtask. As an output,EAJ returns the annex J enable + * flag for the next frame found in the bitstream,if enable_scd=1 + * (if enable_scd=0,this eld is undefined).It is obtained from the + * OPPTYPE eld of the H263 bitstream. + */ +#define ENABLE_ANNEXES_EAJ 0x0008 + +/** \brief Enable Annex K: + * As an input,EAK allows to enable the annex K (slice structured + * coding,with- out submodes)for an H263 decode subtask. As an output, + * EAK returns the annex K enable flag for the next frame found in the + * bitstream,if enable_scd=1 (if enable_scd=0,this eld is undefined). + * It is obtained from the OPPTYPE eld of the H263 bitstream. + */ +#define ENABLE_ANNEXES_EAK 0x0010 + +/** \brief Enable Annex T: + * As an input,EAT allows to enable the annex T (modi ed quantization) + * for an H263 decode subtask. As an output,EAT returns the annex T enable + * flag for the next frame found in the bitstream,if enable_scd=1 + * (if enable_scd=0,this eld is undefined).It is obtained from + * the OPPTYPE filed of the H263 bitstream. */ +#define ENABLE_ANNEXES_EAT 0x0020 +/** @}end of enable_annexes parameter bitfield definition*/ + + + +/*****************************************************************************/ +/** + * \brief Parameter structure encode + * \author Philippe Rochette + * + * Parameter structure for encode. Hamac Video Spec v0.1 sections 7.6 + **/ +/*****************************************************************************/ + +/** \brief This structure define description of a subtask encode. */ +typedef struct t1xhv_vec_subtask_param { + + ts_t1xhv_subtask_link s_link; /**<\brief Link to next subtask (chained list) + * -- ts_t1xhv_subtask_link + */ + t_ahb_address addr_in_frame_buffer; /**<\brief Add. of struct for input frame buffer + * -- ts_t1xhv_vec_frame_buffer_in + */ + t_ahb_address addr_out_frame_buffer; /**<\brief Add. of struct for output frame buffer + * -- ts_t1xhv_vec_frame_buffer_out + */ + t_ahb_address addr_internal_buffer; /**<\brief Add. of struct for internal buffer + * -- ts_t1xhv_vec_internal_buf + */ + t_ahb_address addr_in_header_buffer; /**<\brief Add. of struct for header buffer + * -- ts_t1xhv_bitstream_buf_header + */ + t_ahb_address addr_in_bitstream_buffer; /**<\brief Add. of struct for in bitstr. buffer + * -- ts_t1xhv_init_bitstream_buffer + */ + t_ahb_address addr_out_bitstream_buffer; /**<\brief Add. of struct for output bitstream buffer + * -- ts_t1xhv_bitstream_buffer + */ + t_ahb_address addr_in_parameters; /**<\brief Add. of struct for input parameters + * of encode (depend on standard) + */ + t_ahb_address addr_out_parameters; /**<\brief Add. of struct for output parameters + * of encode (depend on standard) + */ + t_ahb_address addr_in_frame_parameters; /**<\brief Add. of struct for inout parameters + * of encode (depend on standard) + */ + t_ahb_address addr_out_frame_parameters; /**<\brief Add. of struct for inout parameters + * of encode (depend on standard) + */ + t_ahb_address reserved_1; /**<\brief Reserved 32 */ + t_ahb_address reserved_2; /**<\brief Reserved 32 */ + +} ts_t1xhv_vec_subtask_param, *tps_t1xhv_vec_subtask_param; + + +/** \brief This structure define a reference frame buffer. */ +typedef struct t1xhv_vec_frame_buf_in { + + t_ahb_address addr_source_buffer; /**<\brief Buffer to encode. */ + t_ahb_address addr_fwd_ref_buffer; /**<\brief Address of prev reconstructed buffer */ + t_ahb_address addr_grab_ref_buffer; /**<\brief Address of buffer from grab */ + t_ahb_address addr_intra_refresh_buffer; /**<\brief Add. of intra refresh buffer */ + +} ts_t1xhv_vec_frame_buf_in, *tps_t1xhv_vec_frame_buf_in; + + +/** \brief This structure define an output frame buffer. */ +typedef struct t1xhv_vec_frame_buf_out { + + t_ahb_address addr_dest_buffer; /**<\brief Add. of output frame buffer */ + t_ahb_address addr_deblocking_param_buffer; /**<\brief Add. of parameters for PPP */ + t_ahb_address addr_motion_vector_buffer; /**<\brief Add. of motion vector */ + t_ahb_address addr_intra_refresh_buffer; /**<\brief Add. of intra refresh buffer */ + +} ts_t1xhv_vec_frame_buf_out, *tps_t1xhv_vec_frame_buf_out; + + +/** \brief This structure define an internal frame buffer. */ +typedef struct t1xhv_vec_internal_buf { + + t_ahb_address addr_search_window_buffer; /**<\brief Start add. of buffer for Search Window */ + t_ahb_address addr_search_window_end; /**<\brief End add. of buffer for Search Window */ + t_ahb_address addr_jpeg_run_level_buffer; /**<\brief Start add. of JPEG run level buffer */ + t_ahb_address addr_h264e_H4D_buffer; /**<\brief Address of temporary buffer used by H4D for H264. */ + +} ts_t1xhv_vec_internal_buf, *tps_t1xhv_vec_internal_buf; + +/** \brief This structure define parameters of a subtask encode for MPEG4. */ +typedef struct t1xhv_vec_mpeg4_param_in { + + t_ushort_value picture_coding_type; /**<\brief Type I or P of actual frame */ + t_ushort_value flag_short_header; /**<\brief Short header mode if =1 */ + t_ushort_value frame_width; /**<\brief Width in pixels from current frame */ + t_ushort_value frame_height; /**<\brief Height in pixels from current frame */ + t_ushort_value window_width; /**<\brief Width in pixels from current Window */ + t_ushort_value window_height; /**<\brief Height in pixels from current Window */ + t_ushort_value window_horizontal_offset; /**<\brief Horizontal offset from current Window */ + t_ushort_value window_vertical_offset; /**<\brief Vertical offset from current Window */ + t_ushort_value gob_header_freq; /**<\brief.Enables the use of GOB headers */ + t_ushort_value gob_frame_id; /**<\brief Species the gob_frame_id field of GOB headers */ + t_ushort_value data_partitioned; /**<\brief enables data partitioning, for an MPEG4encode + * subtask. It is used only when flag_short_header=0. + * It must be equal to 0 if the frame size is greater than + * CIF,otherwise error_type is set to 0xc6. + */ + t_ushort_value reversible_vlc; /**<\brief Enables the use of reversible codes,for an + * MPEG4encode subtask. It is used only when + * flag_short_header=0 and data_partitioned=1. + */ + t_ushort_value hec_freq; /**<\brief Enables the use of Header Extension Codes and + * associated information,for an MPEG4encode subtask. It + * is used only when flag_short_header=0 and + * data_partitioned=1. When hec_freq=0, no HEC information + * is inserted.Otherwise,HEC information is inserted in + * video packet headers once every hec_freq video packets. + */ + t_ushort_value modulo_time_base; /**<\brief the modulo_time_base field to be written in HEC */ + t_ushort_value vop_time_increment; /**<\brief the vop_time_increment field to be written in HEC */ + t_ushort_value vp_size_type; /**<\brief Control of the video packet size,for an + * MPEG4encode subtask. It is used only when + * flag_short_header=0 and data_partitioned=1. + * It enables the use of vp_bit_size and vp_mb_size + * parameters.A video packet s closed as soon as it + * reaches the corresponding limit or the vp_size_max + * limit.Note that the last macroblock of the video packet + * will be replaced by a "not coded" macroblock if the + * vp__size_max limit is reached. + */ + t_ushort_value vp_size_max; /**<\brief Maximum video packet size,in bits,for an + * MPEG4encode subtask. It is used only when + * flag_short_header=0 and data_partitioned=1. + * If the vp_size_max limit is reached,the last macroblock + * is replaced by a "not coded" macroblock and the video + * packet is closed,in order to respect the limit. + */ + t_ushort_value vp_bit_size; /**<\brief Minimum video packet size in bits,for an MPEG4 + * encode subtask. + * It is used only when flag_short_header=0 and + * data_partitioned=1 and vp_size_type=0/2/3. + * A video packet is closed as soon as it reaches the + * corresponding limit or the vp_size_max limit. + * Note that the last macroblock of the video packet will + * be replaced by a "not coded" macroblock + * if the vp_size_max limit is reached. + */ + t_ushort_value vp_mb_size; /**<\brief Minimum video packet size n macroblocks, + * for an MPEG4encode subtask.It s used only when + * flag_short_header=0 and data_partitioned=1 and + * vp_size_type=1/2/3.A video packet s closed as soon as + * it reaches the corresponding limit or the vp_size_max + * limit. Note that the last macroblock of the video + * packet will be replaced by a "not coded" macroblock + * if the vp__size_max limit is reached. + */ + t_ushort_value init_me; /**<\brief Allows to initialize the motion estimation + * data at the beginning of an MPEG4/H263 encode + * subtask (e.g.after a scene change detection) + */ + t_ushort_value me_type; /**<\brief defines the motion estimation algorithm */ + t_ushort_value vop_fcode_forward; /**<\brief Fcode used (to determine Search window size */ + t_ushort_value rounding_type; /**<\brief defines the value of the rounding control + * parameter used for pixel value interpolation + * in motion compensation for P-frames. It is not + * used if picture_coding_type=0. + */ + t_ushort_value intra_refresh_type; /**<\brief enables the Adaptive Intra Refresh (AIR) + * and/or Cyclic Intra Refresh (CIR) algorithms, + * for an MPEG4/H263 encode subtask. + */ + t_ushort_value air_mb_num; /**<\brief the number of macroblocks per frame to be + * refreshed in the AIR algorithm + */ + t_ushort_value cir_period_max; /**<\brief the maximum macroblock refresh period in + * the CIR algorithm + */ + t_ushort_value quant; /**<\brief Initial value of the quantization parameter + * for an MPEG4 or an H263 encode subtask. It must be + * different from 0, otherwise error_type is set to 0xc0. + */ + t_ushort_value brc_type; /**<\brief the bit rate control (BRC) algorithm */ + t_ulong_value brc_frame_target; /**<\brief Target size in bits for current frame. + * It is not used if brc_method=0/3. + */ + t_ulong_value brc_target_min_pred; /**<\brief the predicted minimum number of bits to + * avoid buffer underflow + */ + t_ulong_value brc_target_max_pred; /**<\brief the predicted maximum number of bits to + * avoid buffer overflow + */ + t_ulong_value skip_count; /**<\brief the number of frames that have been + * skipped consecutively + */ + + t_ulong_value bit_rate; /**<\brief Bitstream bit rate CBR/VBR */ + t_ushort_value framerate; /**<\brief Bitstream frame rate CBR/VBR */ + t_short_value ts_modulo; /**<\brief vop time increment, signed */ + t_ushort_value ts_seconds; /**<\brief modulo time base */ + t_ushort_value air_thr; /**<\brief threshold for AIR */ + + t_ulong_value delta_target; /**<\brief Distance to target rate, signed */ + t_ushort_value minQp; /**<\brief Picture minimum allowed quantization parameter */ + t_ushort_value maxQp; /**<\brief Picture maximum allowed quantization parameter */ + t_ushort_value vop_time_increment_resolution; /**<\brief VOP time increment resolution CBR/VBR/HEC*/ + t_ushort_value fixed_vop_time_increment; /**<\brief Fixed VOP time increment */ + t_ulong_value Smax; /**<\brief Texture max size */ + t_ushort_value min_base_quality; /**<\brief used in VBR only */ + t_ushort_value min_framerate; /**<\brief used in VBR only */ + t_ulong_value max_buff_level; /**<\brief used in CBR only */ + + t_ushort_value first_I_skipped_flag; /**<\brief from mainver24d */ + t_short_value init_ts_modulo_old; /**<\brief from mainver24d */ + + t_ushort_value slice_loss_first_mb[8]; /**<\brief the positions of the first macroblock of + * slices that have been concealed */ + t_ushort_value slice_loss_mb_num[8]; /**<\brief number of macroblocks of slices that have + * been concealed */ + +} ts_t1xhv_vec_mpeg4_param_in, *tps_t1xhv_vec_mpeg4_param_in; + + +/** \brief This structure define parameters at the same time input + * and output of a subtask encode for MPEG4. */ +typedef struct t1xhv_vec_mpeg4_param_inout { + + t_ulong_value bitstream_size; /**<\brief Size in bits of the bitstream that has been + * written by an encode subtask, including the header but + * not the stuffing bits. + */ + t_ulong_value stuffing_bits; /**<\brief Number of stuffing bits added in the bitstream + * during the encode subtask. + * It is not used if brc_method=0/1/3. + */ + t_ulong_value pictCount; /**<\brief Picture count */ + t_ushort_value I_Qp; /**<\brief Initial quantization parameter for intra picture */ + t_ushort_value P_Qp; /**<\brief Initial quantization parameter for inter picture */ + t_ulong_value last_I_Size; /**<\brief Last intra picture size */ + t_ulong_value comp_SUM; /**<\brief comp sum */ + t_ulong_value comp_count; /**<\brief comp count */ + t_ushort_value BUFFER_mod; /**<\brief Buffer mod */ + t_ushort_value hec_count; /**<\brief number of VP since last HEC */ + t_ulong_value ts_seconds_old; /**<\brief Old modulo time base */ + t_short_value ts_modulo_old; /**<\brief Previous vop time increment, signed */ + t_ushort_value gov_flag; /**<\brief for CBR */ + t_ulong_value avgSAD; /**<\brief Average SAD in VBR */ + t_ulong_value seqSAD; /**<\brief Sequential SAD in VBR */ + t_ushort_value min_pict_quality; /**<\brief Minimum picture quality in VBR */ + t_ushort_value diff_min_quality; /**<\brief Difference minimum quality in VBR, signed */ + t_ulong_value TotSkip; /**<\brief Total skip in VBR */ + + t_ulong_value Skip_Current; /**<\brief Used in VBR and CBR */ + + t_ushort_value Cprev; /**<\brief Previous header size in CBR */ + t_ushort_value BPPprev; /**<\brief Previous bit per pixel parameter in CBR */ + t_ulong_value PictQpSum; /**<\brief Picture quantization parameter sum in CBR */ + t_ulong_value S_overhead; /**<\brief Texture size overhead in CBR */ + + t_long_value ts_vector[6]; /**<\brief for TS moving average */ + + t_long_value buffer_fullness; /**<\brief for CBR */ + t_long_value buffer_fullness_fake_TS;/**<\brief for CBR */ + + t_ulong_value BUFFER_depletion; /**<\brief added from mainver2.4d */ + t_ushort_value buffer_saved; /**<\brief added from mainver2.4d */ + t_ushort_value intra_Qp_flag; /**<\brief added for MAINVER2.5c */ + + t_ulong_value BUFFER_depletion_fake_TS; /**<\brief added for MAINVER2.5a */ + t_ushort_value old_P_Qp_vbr; /**<\brief added for MAINVER2.5c */ + t_ushort_value reserved_1; + t_ulong_value pictCount_prev; /**<\brief added for MAINVER2.5c */ + t_ulong_value PictQpSumIntra; /**<\brief added for segmented mode */ + +} ts_t1xhv_vec_mpeg4_param_inout, *tps_t1xhv_vec_mpeg4_param_inout; + + +/** \brief This structure define parameters output of a subtask encode for MPEG4. */ +typedef struct t1xhv_vec_mpeg4_param_out { + + t_ushort_value error_type; /**<\brief Error type if an error occurs during the encode + * subtask. + */ + t_ushort_value vp_num; /**<\brief Number of video packets that have been written + * by an MPEG4 encode subtask.It is used only when + * flag_short_header=0. Note that there is no video packet + * header for the first video packet. + */ + t_ushort_value vp_pos[32]; /**<\brief positions of the first video packets (up to 32) + * that have been written by an MPEG4encode subtask. It is + * used only when flag_short_header=0. The positions are + * given in bytes,relatively to the beginning of the + * bitstream that has been written,including the header. + */ + t_ushort_value brc_skip_prev; /**<\brief Flag indicative when the encoded frame needs + * to be skipped */ + t_ushort_value reserved_1; /**<\brief reserved 16 */ + t_ulong_value reserved_2; /**<\brief reserved 32 */ + t_ulong_value reserved_3; /**<\brief reserved 32 */ + + } ts_t1xhv_vec_mpeg4_param_out, *tps_t1xhv_vec_mpeg4_param_out; + + +/** \brief This structure define parameters of a subtask encode for H264. */ +typedef struct t1xhv_vec_h264_param_in { + + t_long_value level_idc; /**<\brief level idc (required by CDME) */ + + /* the following are image parameters and can change from frame to frame */ + t_ushort_value picture_coding_type; /**<\brief Type I or P of actual frame */ + t_ushort_value frame_width; /**<\brief Width in pixels from current frame */ + t_ushort_value frame_height; /**<\brief Height in pixels from current frame */ + t_ushort_value window_width; /**<\brief Width in pixels from current Window */ + t_ushort_value window_height; /**<\brief Height in pixels from current Window */ + t_ushort_value window_horizontal_offset; /**<\brief Horizontal offset from current Window */ + t_ushort_value window_vertical_offset; /**<\brief Vertical offset from current Window */ + t_ushort_value algo_config; /**<\brief 0b11 for performances (> 15 fps) , + unsetting bit 0 for complex intra in P slices , + unsetting bit 1 for complex inter in P slices */ + t_ulong_value CodedPictureCounter; /**<\brief Coded picture image counter */ + t_ulong_value frame_poc; /**<\brief Current picture POC */ + t_ulong_value frame_num; /**<\brief Frame number */ + t_ushort_value init_me; /**<\brief Allows to initialize the motion estimation + * data at the beginning of an MPEG4/H263/H264 encode + * subtask (e.g.after a scene change detection) */ + + /* the following are from the configuration file */ + t_ushort_value me_type; /**<\brief M.E. algorithm selection */ + t_ushort_value rounding_type; /**<\brief MECC:Used for motion comp */ + t_ushort_value annexb; /**<\brief AnnexB selection : 0:on, others:off */ + t_ushort_value use_constrained_intra_flag; /**<\brief 0: Inter MB pixels are allowed for intra prediction 1: Not allowed */ + t_ushort_value slice_size_type; /* control of the slice size */ + t_ushort_value slice_bit_size; /* Argument to the specified slice algorithm */ + t_ushort_value slice_mb_size; /* Argument to the specified slice algorithm */ + + t_ushort_value intra_disable; /**<\brief each bit disable a specific INTRA mode */ + t_ushort_value intra_refresh_type; /**<\brief enables the Adaptive Intra Refresh (AIR) + * and/or Cyclic Intra Refresh (CIR) algorithms, + * for an MPEG4/H263/H264 encode subtask. + */ + t_ushort_value air_mb_num; /**<\brief the number of macroblocks per frame to be + * refreshed in the AIR algorithm + */ + t_ushort_value reserved_2; + t_ushort_value slice_loss_first_mb[8]; /**<\brief the positions of the first macroblock of + * slices that have been concealed */ + t_ushort_value slice_loss_mb_num[8]; /**<\brief number of macroblocks of slices that have + * been concealed */ + t_ulong_value MaxSumNumBitsInNALU ; /** <\brief max size for a AU */ + + /* the following are used to encode the Slice Header */ + t_ushort_value idr_flag; /**<\brief Picture Intra type IDR */ + t_ushort_value pic_order_cnt_type; /**<\brief POC mode: 0,1,2 */ + t_ushort_value log2_max_frame_num_minus4;/**<\brief log2 max frame num minus4 */ + t_ushort_value log2_max_pic_order_cnt_lsb_minus4;/**<\brief log2 max pic order cnt lsb minus4 */ + + /* the following parameter is to disable deblocking filter (not implemented yet)*/ + t_ushort_value disable_deblocking_filter_idc; /**<\brief disable loop filter */ + t_short_value slice_alpha_c0_offset_div2; /**<\brief custom loop filter parameter */ + t_short_value slice_beta_offset_div2; /**<\brief custom loop filter parameter */ + + + + /* the following are specific for use with the rate-controller */ + t_ushort_value brc_type; /**<\brief the bit rate control (BRC) algorithm */ + t_ulong_value lastBPAUts; /**<\brief removal timestamp of last AU with BP SEI message associated with */ + t_ulong_value NALfinal_arrival_time; /**<\brief arrival time of previous frame. Used by CBR for + dynamic bitrate change support. + */ + + /* NZ: the following are specific for SEI message computattion in hamac side */ + t_ulong_value CpbBufferSize; /**<\brief size of CPB buffer. Used by VBR. */ + t_ulong_value bit_rate; /**<\brief Target bitrate */ + t_short_value SeinitialQP; /**<\brief Initial quantization parameter for first intra picture */ + t_ushort_value framerate; /**<\brief Target framerate */ + t_ulong_value timestamp; /**<\brief Timesatamp value of current frame */ + + t_ulong_value NonVCLNALUSize; /**<\brief size of non-VCL NALU (i.e. SPS, PPS, filler NALU,...) */ + + t_ulong_value reserved_3[2]; /**<\brief Padding for 4*32 multiple struct size */ + +} ts_t1xhv_vec_h264_param_in, *tps_t1xhv_vec_h264_param_in; + + +/** \brief This structure define parameters at the same time input + * and output of a subtask encode for H264. */ +typedef struct t1xhv_vec_h264_param_inout { + /* RR Normally quant param is in param_in structure , to be checked */ + t_short_value quant; /**<\brief Current quantization parameter */ + t_ushort_value I_Qp; /**<\brief Quantization parameter of last encoded intra picture */ + + t_ulong_value bitstream_size; /**<\brief Size in bits of the bitstream that has been + * written by an encode subtask, including the header but + * not the stuffing bits. + */ + t_ulong_value stuffing_bits; /**<\brief Number of stuffing bits added in the bitstream + * during the encode subtask. + * It is not used if brc_method=0/1/3. + */ + + t_ulong_value last_I_Size; /**<\brief Last intra picture size */ + t_ulong_value comp_SUM; /**<\brief comp sum : used in VBR and CBR */ + t_ulong_value comp_count; /**<\brief comp count : used in VBR and CBR */ + + t_ushort_value Skip_Current; /**<\brief current picture skip flag : used in VBR and CBR */ + t_ushort_value Skip_Next; /**<\brief next picture skip flag : used in CBR */ + + t_ushort_value Cprev; /**<\brief Previous header size in CBR */ + t_ushort_value reserved_1; /**<\brief Just to align on 32 bits boundary */ + t_ulong_value PictQpSum; /**<\brief Picture quantization parameter sum in CBR */ + t_ulong_value S_overhead; /**<\brief Texture size overhead in CBR */ + t_ulong_value prev_pict_Qp; /**<\brief Picture Qp value of previous frame */ + + t_long_value bits_enc_buffer; /**<\brief Fullness of encoder buffer (bits). Used in CBR and VBR */ + t_long_value bits_dec_buffer; /**<\brief Fullness of decoder buffer (bits<<8 => 8 bits precision). + * Used in CBR and VBR to compute removal times + */ + + /* VBR */ + t_ulong_value last_size; /**<\brief Size of previous picture */ + t_ushort_value last_was_I; /**<\brief Previous INTRA picture flag */ + t_ushort_value reserved_2; /**<\brief to align on 32 bits */ + + /* TIMESTAMPS */ + t_long_value timestamp_old; /**<\brief Timesatamp value of previous frame */ + t_ulong_value removal_time; /**<\brief Removal time of current frame (nb. of ticks 1/framerate) (generated by BRC) */ + + /* dynamic options */ + t_ushort_value old_framerate; /**<\brief framerate value of previous picture (used for dynamic framerate change) */ + t_ushort_value reserved_3; /**<\brief to align on 32 bits */ + t_ulong_value old_bit_rate; /**<\brief bitrate value of previous picture (used for dynamic bitrate change) */ + + t_ushort_value previous_MB_MV_num; /**<\brief DF: check for Level 3.1 constraints (number of MV across MBs) */ + t_ushort_value CC_modulation; /**< Parameter for the modulation of the thresholds in case of low/middle-low motion */ /* Used in CDME8815 */ + /* AIR data */ + t_ushort_value refreshed_mbs; /**<\brief Number of refreshed mbs in current frame>*/ + + t_ushort_value reserved_4[7]; /**<\brief Padding for 4*32 multiple struct size */ + +} ts_t1xhv_vec_h264_param_inout, *tps_t1xhv_vec_h264_param_inout; + + +/** \brief This structure define parameters output of a subtask encode for H264. */ +typedef struct t1xhv_vec_h264_param_out { + t_ushort_value error_type; /**<\brief Error type if an error occurs during the encode subtask. */ + t_ushort_value slice_num; /**<\brief Number of slices that have been written by an H264 encode subtask. */ + t_ulong_value slice_pos[1620]; /**<\brief positions of the first slices (up to 1320 enough for SDTV) that have been written by an H264 encode subtask. */ + + t_ulong_value reserved_1[3]; /**<\brief Padding for 4*32 multiple struct size */ +} ts_t1xhv_vec_h264_param_out, *tps_t1xhv_vec_h264_param_out; + +/** \brief This structure define parameters of a subtask encode for H263. */ +typedef struct t1xhv_vec_h263_param_in { + + t_ushort_value picture_coding_type; /**<\brief Type I or P of actual frame */ + t_ushort_value frame_width; /**<\brief Width in pixels from current frame */ + t_ushort_value frame_height; /**<\brief Height in pixels from current frame */ + t_ushort_value window_width; /**<\brief Width in pixels from current Window */ + t_ushort_value window_height; /**<\brief Height in pixels from current Window */ + t_ushort_value window_horizontal_offset; /**<\brief Horizontal offset from current Window */ + t_ushort_value window_vertical_offset; /**<\brief Vertical offset from current Window */ + t_ushort_value enable_annexes; /**<\brief - Enable mv over picture boundary + * - Enable AC/DC prediction + * - Enable deblocking filter + * - Enable slice structure + * - Enable modified quantization + */ + t_ushort_value gob_header_freq; /**<\brief Frequency of GOB headers */ + t_ushort_value gob_frame_id; /**<\brief GOB frame id (to be written into GOB hdrs) */ + t_ushort_value slice_size_type; /**<\brief Parameter for annex k */ + t_ushort_value slice_bit_size; /**<\brief */ + t_ushort_value slice_mb_size; /**<\brief */ + t_ushort_value init_me; /**<\brief Allows to initialize the motion estimation + * data at the beginning of an MPEG4/H263 encode + * subtask (e.g.after a scene change detection) + */ + t_ushort_value me_type; /**<\brief Selects motion est algo */ + t_ushort_value reserved_1; + t_ushort_value rounding_type; /**<\brief Used for motion comp */ + t_ushort_value intra_refresh_type; /**<\brief Intra refresh: AIR/CIR */ + t_ushort_value air_mb_num; /**<\brief Nbr of AIR MBs */ + t_ushort_value cir_period_max; /**<\brief CIR period */ + t_ushort_value quant; /**<\brief Initial value of the quantization parameter + * for an MPEG4 or an H263 encode subtask. It must be + * different from 0, otherwise error_type is set to 0xc0. + */ + t_ushort_value brc_type; /**<\brief Method for bit rate control */ + t_ulong_value brc_frame_target; /**<\brief Target size in bits for current frame. + * It is used if brc_type=1. + */ + t_ulong_value brc_target_min_pred; /**<\brief internal variable */ + t_ulong_value brc_target_max_pred; /**<\brief internal variable */ + t_ulong_value skip_count; /**<\brief nb of consecutive skipped images */ + t_ulong_value bitrate; /**<\brief target bitrate */ + t_ushort_value framerate; /**<\brief framerate */ + t_ushort_value ts_modulo; /**<\brief current TS */ + t_ushort_value ts_seconds; /**<\brief current TS */ + t_ushort_value air_thr; /**<\brief threshold for AIR */ + t_ulong_value delta_target; /**<\brief internal */ + t_ushort_value minQp; /**<\brief min Qp */ + t_ushort_value maxQp; /**<\brief max Qp */ + t_ushort_value vop_time_increment_resolution; /**<\brief internal */ + t_ushort_value fixed_vop_time_increment; /**<\brief internal */ + t_ulong_value Smax; /**<\brief internal */ + t_ushort_value min_base_quality; /**<\brief internal */ + t_ushort_value min_framerate; /**<\brief internal */ + t_ulong_value max_buff_level; /**<\brief internal */ + t_ushort_value slice_loss_first_mb[8]; /**<\brief the positions of the first macroblock of + * slices that have been concealed */ + t_ushort_value slice_loss_mb_num[8]; /**<\brief number of macroblocks of slices that have + * been concealed */ +} ts_t1xhv_vec_h263_param_in, *tps_t1xhv_vec_h263_param_in; + +/** \brief This structure define parameters at the same time input + * and output of a subtask encode for H263. */ +typedef struct t1xhv_vec_h263_param_inout { + t_ulong_value bitstream_size; /**<\brief size of encoded stream */ + t_ulong_value stuffing_bits; /**<\brief stuffing bits */ + t_ulong_value pictCount; /**<\brief internal */ + t_ushort_value I_Qp; /**<\brief internal */ + t_ushort_value P_Qp; /**<\brief internal */ + t_ulong_value last_I_size; /**<\brief internal */ + t_ulong_value comp_SUM; /**<\brief internal */ + t_ulong_value comp_count; /**<\brief internal */ + t_ushort_value BUFFER_mod; /**<\brief internal */ + t_ushort_value ts_modulo_old; /**<\brief internal */ + t_ulong_value ts_seconds_old; /**<\brief internal */ + t_ulong_value avgSAD; /**<\brief internal */ + t_ulong_value seqSAD; /**<\brief internal */ + t_ushort_value min_pict_quality; /**<\brief internal */ + t_ushort_value diff_min_quality; /**<\brief internal */ + t_ulong_value TotSkip; /**<\brief internal */ + t_ulong_value SkipCurrent; /**<\brief internal */ + t_ushort_value Cprev; /**<\brief internal */ + t_ushort_value BPPprev; /**<\brief internal */ + t_ulong_value PictQpSum; /**<\brief internal */ + t_ulong_value S_overhead; /**<\brief Texture size overhead in CBR */ + t_long_value ts_vector[6]; /**<\brief for TS moving average */ + t_long_value buffer_fullness; /**<\brief for CBR */ +} ts_t1xhv_vec_h263_param_inout, *tps_t1xhv_vec_h263_param_inout; + + +/** \brief This structure define parameters output of H263 encode subtask */ +typedef struct t1xhv_vec_h263_param_out { + + t_ushort_value error_type; /**<\brief Error status */ + t_ushort_value slice_num; /**<\brief */ + t_ushort_value slice_pos[32]; /**<\brief positions of the 1st slices (up to 32) */ + t_ushort_value brc_skip_prev; /**<\brief skip decided by BRC */ + t_ushort_value reserved_1; /**<\brief reserved 16 */ + t_ulong_value reserved_2; /**<\brief reserved 32 */ + t_ulong_value reserved_3; /**<\brief reserved 32 */ +} ts_t1xhv_vec_h263_param_out, *tps_t1xhv_vec_h263_param_out; + +/** \brief Structure for parameters FROM Host for a JPEG encode task */ +typedef struct t1xhv_vec_jpeg_param_in { + + t_ushort_value frame_width; /**<\brief Nb of pixel per line */ + t_ushort_value frame_height; /**<\brief Nb of line */ + t_ushort_value window_width; /**<\brief Nb of pixels per line to be encoded */ + t_ushort_value window_height; /**<\brief Nb of lines to be encoded */ + t_ushort_value window_horizontal_offset; /**<\brief Nb of pixels for horizontal offset */ + t_ushort_value window_vertical_offset; /**<\brief Nb of pixels for vertical offset */ + t_ushort_value sampling_mode; /**<\brief Added in v0.96 */ + t_ushort_value restart_interval; /**<\brief Nb of MCUs between 2 restart markers */ + t_ushort_value quant_luma[64]; /**<\brief Quantization table for luma */ + t_ushort_value quant_chroma[64]; /**<\brief Quantization table for chroma */ + t_ushort_value huffman_luma_code_dc[12]; /**<\brief DC Huffman code table */ + t_ushort_value huffman_luma_size_dc[12]; /**<\brief DC Huffman size table */ + t_ushort_value huffman_luma_code_ac[256]; /**<\brief AC Huffman code table */ + t_ushort_value huffman_luma_size_ac[256]; /**<\brief AC Huffman size table */ + t_ushort_value huffman_chroma_code_dc[12]; /**<\brief DC Huffman code table */ + t_ushort_value huffman_chroma_size_dc[12]; /**<\brief DC Huffman size table */ + t_ushort_value huffman_chroma_code_ac[256];/**<\brief AC Huffman code table */ + t_ushort_value huffman_chroma_size_ac[256];/**<\brief AC Huffman size table */ + t_ushort_value last_slice; /**<\brief Added in v0.96 */ + t_ushort_value enable_optimized_quant; /**<\brief Added in v0.96 */ + t_ushort_value target_bpp; /**<\brief Added in v0.96 */ + t_ushort_value enable_optimized_huffman; /**<\brief Added in v0.96 */ + t_ushort_value rotation; /**<\brief 0=no rotate,1=rotate 90,2=rotate -90 */ + t_ushort_value reserved_1; /**<\brief reserved 32 */ + t_ulong_value reserved_2; /**<\brief reserved 32 */ + +} ts_t1xhv_vec_jpeg_param_in, *tps_t1xhv_vec_jpeg_param_in; + +/** \brief Structure for output parameters of JPEG encode task */ +typedef struct t1xhv_vec_jpeg_param_out { + + t_ushort_value error_type; /**<\brief Error status */ + t_ushort_value reserved; /**<\brief To align next field on 32b boundary */ + t_ulong_value bitstream_size; /**<\brief Size of encoded bitstream in bits */ + t_ulong_value reserved_1; /**<\brief To align struct size on 128b */ + t_ulong_value reserved_2; /**<\brief To align struct size on 128b */ + +} ts_t1xhv_vec_jpeg_param_out, *tps_t1xhv_vec_jpeg_param_out; + +/** \brief Structure for output parameters of JPEG encode task */ +typedef struct t1xhv_vec_jpeg_param_inout { + + t_ushort_value restart_mcu_count; /**<\brief Added in v0.96 */ + t_ushort_value dc_predictor_y; /**<\brief Added in v0.96 */ + t_ushort_value dc_predictor_cb; /**<\brief Added in v0.96 */ + t_ushort_value dc_predictor_cr; /**<\brief Added in v0.96 */ + t_ushort_value restart_marker_id; + t_ushort_value reserved_1; /**<\brief To align struct on 128b */ + t_ulong_value reserved_2; /**<\brief To align struct on 128b */ + +} ts_t1xhv_vec_jpeg_param_inout, *tps_t1xhv_vec_jpeg_param_inout; + + +/*****************************************************************************/ +/** + * \brief Parameter structure for image stabilization + * \author Serge Backert + * + * Parameter structure for image stabilization + */ +/*****************************************************************************/ + +/** \brief Structure for parameters FROM Host for an image stab. encode task */ +typedef struct t1xhv_vec_stab_param_in { + + t_ushort_value frame_width; /**<\brief Nb of pixel per line */ + t_ushort_value frame_height; /**<\brief Nb of line */ + t_ushort_value zone_of_interest_bitmap[84]; /**<\brief Zone to consider for + stab vect computation */ + t_ulong_value reserved_1; /**<\brief To align struct on 32b */ + +} ts_t1xhv_vec_stab_param_in, *tps_t1xhv_vec_stab_param_in; + +/** \brief Structure for parameters TO Host from an image stab. encode task */ +typedef struct t1xhv_vec_stab_param_out { + + t_ushort_value error_type; /**<\brief Error status */ + t_ushort_value reserved_1; /**<\brief reserved 16 */ + t_short_value stab_vector_x; /**<\brief Stabilization vector x coordinate */ + t_short_value stab_vector_y; /**<\brief Stabilization vector y coordinate */ + t_ulong_value reserved_2; /**<\brief To align struct on 16 bytes */ + t_ulong_value reserved_3; /**<\brief To align struct on 16 bytes */ + +} ts_t1xhv_vec_stab_param_out, *tps_t1xhv_vec_stab_param_out; + + + + + +/*****************************************************************************/ +/** + * \brief Parameter structure for display + * \author Jean-Marc Volle + * + * Parameter structure for display. Hamac Video Spec v0.1 + */ +/*****************************************************************************/ +typedef struct t1xhv_dpl_subtask_param { + + ts_t1xhv_subtask_link s_link; /**<\brief Link to next subtask + * (chained list) same for all tasks + * -- ts_t1xhv_subtask_link */ + t_ahb_address addr_in_frame_buffer; /**<\brief Address of structure for + * input frame buffer + * -- ts_t1xhv_dpl_frame_buffer_in */ + t_ahb_address addr_out_frame_buffer; /**<\brief Address of structure for + * output frame buffer + * -- ts_t1xhv_dpl_frame_buffer_out */ + t_ahb_address addr_internal_buffer; /**<\brief Address of structure for + * internal buffer + * -- ts_t1xhv_dpl_interna_buf */ + t_ahb_address addr_in_parameters; /**<\brief Address of structure for + * input parameters + * -- ts_t1xhv_dpl_parameters_in */ + t_ahb_address addr_out_parameters; /**<\brief Address of structure for + * output parameters + * -- ts_t1xhv_dpl_parameters_out */ + t_ahb_address addr_in_frame_parameters; /**<\brief Add. of struct for inout parameters + * of display */ + t_ahb_address addr_out_frame_parameters; /**<\brief Add. of struct for inout parameters + * of display */ + + t_ulong_value reserved_1; /**<\brief reserved 32 */ + +} ts_t1xhv_dpl_subtask_param, *tps_t1xhv_dpl_subtask_param; + + +/** + * \brief t1xhv_dpl_frame_buf_in, pointed by the second field of the parameter + * structure + */ +typedef struct t1xhv_dpl_frame_buf_in { + + t_ahb_address addr_source_buffer; /**<\brief Source buffer start address */ + t_ahb_address addr_deblocking_param_buffer; /**<\brief Deblocing parameters + * buffer start address */ + t_ulong_value reserved_1; /**<\brief reserved 32 */ + t_ulong_value reserved_2; /**<\brief reserved 32 */ + +} ts_t1xhv_dpl_frame_buf_in, *tps_t1xhv_dpl_frame_buf_in; + +/** + * \brief t1xhv_dpl_frame_buf_out, pointed by the third field of the parameter + * structure, same as the one for decoder, necessary to duplicate ? + */ +typedef struct t1xhv_dpl_frame_buf_out { + + t_ahb_address addr_dest_buffer; /**<\brief Destination buffer start address */ + t_ulong_value reserved_1; /**<\brief reserved 32 */ + t_ulong_value reserved_2; /**<\brief reserved 32 */ + t_ulong_value reserved_3; /**<\brief reserved 32 */ + +} ts_t1xhv_dpl_frame_buf_out, *tps_t1xhv_dpl_frame_buf_out; + +/** + * \brief t1xhv_dpl_internal_buf, pointed by the fourth field of the parameter + * structure, same as the one for decoder, necessary to duplicate ? + */ +typedef struct t1xhv_dpl_internal_buf { + + t_ahb_address addr_temp_buffer; /**<\brief temporary buffer start address */ + t_ulong_value reserved_1; /**<\brief reserved 32 */ + t_ulong_value reserved_2; /**<\brief reserved 32 */ + t_ulong_value reserved_3; /**<\brief reserved 32 */ + +} ts_t1xhv_dpl_internal_buf, *tps_t1xhv_dpl_internal_buf; + +/** + * \brief t1xhv_dpl_parameters_in, pointed by the fifth field of the parameter + * structure. Read from Host + */ +typedef struct t1xhv_dpl_param_in { + + t_ushort_value source_frame_width; /**<\brief YCbCr 4:2:0 input pict width in pixels */ + t_ushort_value source_frame_height; /**<\brief YCbCr 4:2:0 input pict height in pixels */ + t_ushort_value source_window_width; /**<\brief Source window width */ + t_ushort_value source_window_height; /**<\brief Source window height */ + t_ushort_value source_window_horizontal_offset; /**<\brief Source window horizontal offset */ + t_ushort_value source_window_vertical_offset; /**<\brief Source window vetical offset */ + t_ushort_value resized_window_width; /**<\brief Resized window width */ + t_ushort_value resized_window_height; /**<\brief Resized window height */ + t_ushort_value clipped_window_width; /**<\brief Clipped window width */ + t_ushort_value clipped_window_height; /**<\brief Clipped window height */ + t_ushort_value clipped_window_horizontal_offset; /**<\brief Clipped window horizontal offset */ + t_ushort_value clipped_window_vertical_offset; /**<\brief Clipped window vetical offset */ + t_ushort_value destination_frame_width; /**<\brief RGB output picture width in pixel */ + t_ushort_value destination_frame_height; /**<\brief RGB output picture height in pixel */ + t_ushort_value destination_window_horizontal_offset; /**<\brief Destination window horizontal offset */ + t_ushort_value destination_window_vertical_offset; /**<\brief Destination window vetical offset */ + t_ushort_value bits_per_pixel; /**<\brief Number of bits per pixel following RGB + * conversion. Decoded inside FW + * 0 => YCbCr 422 + * 12 => RGB 444 + * 15 => RGB 555 + * 16 => RGB 565 + * 24 => RGB 888 + * 32 => RGB 888 (with 8 bit alpha component) + * others: 16 assumed + */ + t_ushort_value dithering; /**<\brief Dithering (used only if BPP =3) + * 0 =>disable + * 1 =>enable */ + t_ushort_value mirroring; /**<\brief Mirroring + * 0 =>no mirroring + * 1 =>horizontal mirroring (left-right) + * 2 =>vertical mirroring (upside-down) + * 3 =>horizontal &vertical mirroring =180 + * rotation */ + t_ushort_value rotation; /**<\brief Rotation + * 0 =>no rotation + * 1 =>90 o rotation (counter clockwise if + * MIR [0 ] ==0,else clockwise). + */ + t_ushort_value chroma_sampling_format; /**<\brief */ + t_ushort_value alpha_key; /**<\brief Alpha key for RGB 12 or 24bpp */ + t_ushort_value red_blue_swap; /**<\brief Swap R/B in output (for disp. device)*/ + t_ushort_value reserved_1; /**<\brief padding field */ + t_ushort_value chroma_duplication; /**<\brief 0=>chroma upsampling (MUPOC-Full only) + * 1=>chroma duplication + */ + t_ushort_value contrast; /**<\brief Contrast */ + t_ushort_value brightness; /**<\brief Brightness */ + + t_short_value matrix_coef1; /**<\brief Matrix coefficient 1 */ + t_short_value matrix_coef2; /**<\brief Matrix coefficient 2 */ + t_short_value matrix_coef3; /**<\brief Matrix coefficient 3 */ + t_short_value matrix_coef4; /**<\brief Matrix coefficient 4 */ + + t_ushort_value display_sync_line; + t_ushort_value ace_enable; /**<\brief ace enable */ + t_ushort_value ace_strength; /**<\brief ace correction strength from 1 to 8 */ + t_ushort_value ace_range; /**<\brief ace range: 0=full, 1=reduced(BT601) */ + t_ushort_value output_range; + t_ulong_value reserved_2; /**<\brief reserved 32 */ + t_ulong_value reserved_3; /**<\brief reserved 32 */ + + +} ts_t1xhv_dpl_param_in, *tps_t1xhv_dpl_param_in; + +/** + * \brief t1xhv_dpl_parameters_out, pointed by the sixth field of the parameter + * structure. + */ +typedef struct t1xhv_dpl_param_out { + + t_ushort_value error_type; /**<\brief Error type */ + t_ushort_value reserved_1; /**<\brief reserved 16 */ + t_ulong_value reserved_2; /**<\brief reserved 32 */ + t_ulong_value reserved_3; /**<\brief reserved 32 */ + t_ulong_value reserved_4; /**<\brief reserved 32 */ + +} ts_t1xhv_dpl_param_out, *tps_t1xhv_dpl_param_out; + +typedef struct t1xhv_dpl_param_inout { + t_ulong_value reserved_1; /**<\brief reserved 32 */ + t_short_value ace_offset0; /**<\brief ace output offset 0 */ + t_short_value ace_offset1; /**<\brief ace output offset 1 */ + t_short_value ace_offset2; /**<\brief ace output offset 2 */ + t_short_value ace_offset3; /**<\brief ace output offset 3 */ + t_ulong_value reserved_2; /**<\brief reserved 32 */ + +} ts_t1xhv_dpl_param_inout, *tps_t1xhv_dpl_param_inout; + + +/*****************************************************************************/ +/** + * \brief Parameter structure for grab + * \author Serge Backert, Loic Habrial + * + * Parameter structure for grab. Hamac Video Spec v0.1 + */ +/*****************************************************************************/ +typedef struct t1xhv_grb_subtask_param { + + ts_t1xhv_subtask_link s_link; /**<\brief Link to next subtask (chained + * list) same for all tasks + * -- ts_t1xhv_subtask_link */ + t_ahb_address addr_in_frame_buffer; /**<\brief Add. of structure for input + * frame buffer + * -- ts_t1xhv_grb_frame_buffer_in */ + t_ahb_address addr_out_frame_buffer; /**<\brief Add. of structure for output + * frame buffer + * -- ts_t1xhv_grb_frame_buffer_out */ + t_ahb_address addr_internal_buffer; /**<\brief Add. of structure for internal + * buffer + * -- ts_t1xhv_grb_internal_buffer */ + t_ahb_address addr_in_parameters; /**<\brief Add. of structure for input + * parameters + * -- ts_t1xhv_grb_parameters_in */ + t_ahb_address addr_out_parameters; /**<\brief Add. of structure for output + * parameters + * -- ts_t1xhv_grb_parameters_out */ + t_ahb_address addr_in_frame_parameters; /**<\brief Add. of struct for inout parameters + * of encode (depend on standard) */ + t_ahb_address addr_out_frame_parameters; /**<\brief Add. of struct for inout parameters + * of encode (depend on standard) */ + + t_ahb_address reserved_1; /**<\brief reserved 32 */ + +} ts_t1xhv_grb_subtask_param, *tps_t1xhv_grb_subtask_param; + +/** + * \brief t1xhv_grb_frame_buf_in, pointed by the second field of the parameter + * structure + */ +typedef struct t1xhv_grb_frame_buf_in { + t_ahb_address addr_grid_buffer_day; /**<\brief Start address of grid buffer */ + t_ahb_address addr_grid_buffer_cool; /**<\brief reserved 32 */ + t_ahb_address addr_grid_buffer_inc; /**<\brief reserved 32 */ + t_ahb_address addr_grid_buffer_hor; /**<\brief reserved 32 */ + +} ts_t1xhv_grb_frame_buf_in, *tps_t1xhv_grb_frame_buf_in; + +/** + * \brief t1xhv_grb_frame_buf_out, pointed by the third field of the parameter + * structure. + */ +typedef struct t1xhv_grb_frame_buf_out { + + t_ahb_address addr_dest_lc_buffer; /**<\brief Start address of destination buffer + * for a grab macroblock */ + t_ahb_address addr_dest_raw_data_buffer; /**<\brief Start address of destination buffer + * for a grab raw data */ + t_ahb_address addr_dest_raw_data_end; /**<\brief End address of destination buffer + * for a grab raw data */ + t_ahb_address addr_snap_buffer; + +} ts_t1xhv_grb_frame_buf_out, *tps_t1xhv_grb_frame_buf_out; + +/** + * \brief t1xhv_grb_internal_buf, pointed by the fourth field of the parameter + * structure. + */ +typedef struct t1xhv_grb_internal_buf { + + t_ahb_address addr_raw_bayer_write_buffer; /**<\brief Start address of raw bayer buffer for BMS/BML */ + t_ulong_value reserved0; /**<\brief reserved 32 */ + t_ulong_value reserved1; /**<\brief reserved 32 */ + t_ulong_value reserved2; /**<\brief reserved 32 */ + +} ts_t1xhv_grb_internal_buf, *tps_t1xhv_grb_internal_buf; + +/** + * \brief t1xhv_grb_parameters_in, pointed by the fifth field of the parameter + * structure. Read from Host. + */ +typedef struct t1xhv_grb_param_in { + + t_ushort_value source_frame_width; /**<\brief Width of the source frame */ + t_ushort_value source_frame_height; /**<\brief Height of the source frame */ + + t_ushort_value source_window_width; /**<\brief Width of the source window */ + t_ushort_value source_window_height; /**<\brief Height of the source window */ + + t_ushort_value source_window_horizontal_offset; /**<\brief Horizontal offset of the source window */ + t_ushort_value source_window_vertical_offset; /**<\brief Vertical offset of the source window */ + + t_ushort_value resized_window_width; /**<\brief Width of the resized window */ + t_ushort_value resized_window_height; /**<\brief Height of the resized window */ + + + t_ushort_value snap_window_width; /**<\brief Width of the resized window */ + t_ushort_value snap_window_height; /**<\brief Height of the resized window */ + + t_ushort_value interface_configuration; /**<\brief Camera interface usage */ + t_ushort_value grab_sync_line; /**<\brief Grab_sync trigger line index */ + + t_ushort_value chroma_sampling_format; /**<\brief Processing of chroma components */ + t_ushort_value ace_enable; /**<\brief ace enable */ + + t_ushort_value ace_strength; /**<\brief ace correction strength from 1 to 8 */ + t_ushort_value ace_range; /**<\brief ace range: 0=full, 1=reduced(BT601) */ + + + t_ushort_value output_range; /**<\brief ace output range of the grab subtask */ + t_ushort_value interlace_enable; /**<\brief ccir interlace mode enable */ + + t_ushort_value field_sync; /**<\brief ccir field synchronization selection */ + t_ushort_value raw_data_bpp; /**<\brief ccir 10-bit mode enable */ + + t_ushort_value choffset_enable; + t_ushort_value gridiron_enable; + + t_ushort_value reserved0; + t_ushort_value scorpio_enable; + + + t_ushort_value scorpio_strenght; + t_ushort_value perf_measure; + t_ulong_value cast_day; + t_ulong_value cast_cool; + t_ulong_value cast_inc; + + t_ulong_value cast_hor; + t_long_value gridhsize; + + t_ushort_value bml_clock_divisor; + t_ushort_value bml_recover_nb_retry; + t_ulong_value reserved_3; + + +} ts_t1xhv_grb_param_in, *tps_t1xhv_grb_param_in; + + + +/** \brief Structure for parameters FROM and TO Host for a grab task */ +typedef struct t1xhv_grb_param_inout { + + t_ulong_value reserved_1; /**<\brief reserved 32 */ + t_short_value ace_offset0; /**<\brief ace output offset 0 */ + t_short_value ace_offset1; /**<\brief ace output offset 1 */ + t_short_value ace_offset2; /**<\brief ace output offset 2 */ + t_short_value ace_offset3; /**<\brief ace output offset 3 */ + t_ulong_value reserved_2; /**<\brief reserved 32 */ + +} ts_t1xhv_grb_param_inout, *tps_t1xhv_grb_param_inout; + + +/** + * \brief t1xhv_grb_parameters_out, pointed by the sixth field of the parameter + * structure. + */ +typedef struct t1xhv_grb_param_out { + + t_ushort_value error_type; /**<\brief Error status */ + t_ushort_value field_number; /**<\brief the number of the ccir field grabbed */ + t_time_stamp time_stamp; /**<\brief Execution time stamp */ + t_ulong_value reserved_1; /**<\brief reserved 32 */ + t_ulong_value reserved_2; /**<\brief reserved 32 */ + +} ts_t1xhv_grb_param_out, *tps_t1xhv_grb_param_out; + + +/*****************************************************************************/ +/** @{ \name Parameters structures for tvout + * \author Jean-Marc Volle + * \note Spec V0.1 + */ +/*****************************************************************************/ + +/** \brief This structure define description of a subtask tvout */ + +typedef struct t1xhv_tvd_subtask_param { + + ts_t1xhv_subtask_link s_link; /**<\brief Link to next subtask + * (chained list) same for all tasks + * -- ts_t1xhv_subtask_link */ + t_ahb_address addr_in_frame_buffer; /**<\brief Address of structure for + * input frame buffer + * -- ts_t1xhv_tvd_frame_buf_in */ + t_ahb_address addr_init_parameters; /**<\brief Address of structure for + * init parameters + * -- ts_t1xhv_tvd_param_init */ + t_ahb_address addr_in_parameters; /**<\brief Address of structure for + * in parameters + * -- ts_t1xhv_tvd_param_in */ + t_ahb_address reserved; /**<\brief Reserved 32 */ + +} ts_t1xhv_tvd_subtask_param, *tps_t1xhv_tvd_subtask_param; + + +/** + * \brief t1xhv_tvd_frame_buf_in, pointed by the second field of the parameter + * structure + */ +typedef struct t1xhv_tvd_frame_buf_in { + + t_ahb_address addr_source_buffer; /**<\brief Source buffer start address */ + t_ahb_address reserved_1; /**<\brief Reserved 32 */ + t_ahb_address reserved_2; /**<\brief Reserved 32 */ + t_ahb_address reserved_3; /**<\brief Reserved 32 */ + +} ts_t1xhv_tvd_frame_buf_in, *tps_t1xhv_tvd_frame_buf_in; +/** + * \brief t1xhv_tvd_param_init, pointed by the third field of the parameter + * structure, + */ + +typedef struct t1xhv_tvd_param_init { + t_ushort_value clock_signal_selection; /**<\brief Clock edge selection signal */ + t_ushort_value clock_edge_selection; /**<\brief Clock edge selection */ + t_ushort_value interlace_enable; /**<\brief Interlacing enable flag */ + t_ushort_value number_of_lines; /**<\brief Number of lines */ + t_ushort_value field1_blanking_start_line; /**<\brief Field1 blanking start line */ + t_ushort_value field1_blanking_end_line; /**<\brief Field1 blanking end line */ + t_ushort_value field2_blanking_start_line; /**<\brief Field2 blanking start line */ + t_ushort_value field2_blanking_end_line; /**<\brief Field2 blanking end line */ + t_ushort_value field1_identification_start_line; /**<\brief Field1 identification start line */ + t_ushort_value field2_identification_start_line; /**<\brief Field2 identification start line */ + t_ushort_value line_blanking_witdh; /**<\brief Line blanking width */ + t_ushort_value active_line_width; /**<\brief Active line width */ + t_ulong_value reserved_1; /**<\brief Reserved 32 */ + t_ulong_value reserved_2; /**<\brief Reserved 32 */ + +} ts_t1xhv_tvd_param_init, *tps_t1xhv_tvd_param_init; + +/** + * \brief t1xhv_tvd_parameters_in, pointed by the fourth field of the parameter + * structure. Read from Host + */ +typedef struct t1xhv_tvd_param_in { + t_ushort_value source_frame_width; /**<\brief Source frame width */ + t_ushort_value source_frame_height; /**<\brief Source frame height */ + t_ushort_value source_window_width; /**<\brief Source window width */ + t_ushort_value field1_source_window_height; /**<\brief Field1 source window height */ + t_ushort_value field2_source_window_height; /**<\brief Field2 source window height */ + t_ushort_value source_window_horizontal_offset; /**<\brief Source window horizontal offset */ + t_ushort_value field1_source_window_vertical_offset; /**<\brief Field1 source window vertical offset */ + t_ushort_value field2_source_window_vertical_offset; /**<\brief Field2 source window vertical offset */ + t_ushort_value destination_window_horizontal_offset; /**<\brief Destination window horizontal offset */ + t_ushort_value field1_destination_window_vertical_offset; /**<\brief Field1 destination window vertical offset */ + t_ushort_value field2_destination_window_vertical_offset; /**<\brief Field2 destination window vertical offset */ + t_ushort_value background_y; /**<\brief Background luminance value */ + t_ushort_value background_cb; /**<\brief Background Cb chrominance value */ + t_ushort_value background_cr; /**<\brief Background Cr chrominance value */ + t_ulong_value reserved_1; /**<\brief Reserved 32 */ + +} ts_t1xhv_tvd_param_in, *tps_t1xhv_tvd_param_in; + +/** @}end of tvout subtask structures definition */ + + +typedef struct vdc_vc1_param_in +{ + t_ulong_value frame_size; /**< \brief size of the frame in bytes */ + t_ushort_value max_picture_width; /**< \brief maximum width of the picture (Annex J HORIZ_SIZE) */ + t_ushort_value max_picture_height; /**< \brief maximum height of the picture (Annex J VERT_SIZE) */ + t_ushort_value profile; /**< \brief profile: 0 == SIMPLE, 1 == MAIN */ + t_ushort_value quantizer; /**< \brief quantizer specifier (Annex J QUANTIZER) */ + t_ushort_value dquant; /**< \brief macro-bloc quantization (Annex J DQUANT) */ + t_ushort_value max_b_frames; /**< \brief maximum number of consecutive b-frames (Annex J MAXBFRAMES) */ + t_ushort_value multires_coding_enabled; /**< \brief multi resolution coding used (Annex J MULTIRES) */ + t_ushort_value extended_mv_enabled; /**< \brief extended motion vectors used (Annex J EXTENDED_MV) */ + t_ushort_value overlap_transform_enabled; /**< \brief overlaping transform used (Annex J OVERLAP) */ + t_ushort_value syncmarker_enabled; /**< \brief synchronisation markers used (Annex J SYNCMARKER) */ + t_ushort_value rangered_enabled; /**< \brief range reduction used (Annex J RANGERED) */ + t_ushort_value frame_interpolation_enabled; /**< \brief frame interpolation in picture header (Annex J FINTERPFLAG) */ + t_ushort_value variable_size_transform_enabled; /**< \brief variable size inverse transform used (Annex J VSTRANSFORM) */ + t_ushort_value loop_filter_enabled; /**< \brief in-the-loop filtering used (Annex J LOOPFILTER) */ + t_ushort_value fast_uvmc_enabled; /**< \brief fast chroma motion compensention (Annex J FASTUVMC) */ + t_ushort_value is_smpte_conformant; /**< \brief flag stating that the stream is conformant to SMPTE (reset of MV history not done) default:TRUE */ + t_ushort_value overboost; /**< \brief flag activating maximum performance decoding. 0=normal decode, + 1=deblocking+overlap disabled with MB output instead of raster */ + t_ushort_value simplified_filter; /**< \brief enable this flag if you want to use Intra filter for inter pictures as + well. This improves performance for low bitrates. Output is raster in this case */ + t_ulong_value padding3; + t_ulong_value padding4; + +} ts_t1xhv_vdc_vc1_param_in, *tps_t1xhv_vdc_vc1_param_in; + + +/** \brief Hamac video vc1 decode output parameters + * \note These parameters are picture layer parameters needed for post-processing*/ +typedef struct vdc_vc1_param_out +{ + t_ushort_value error_type; /**<\brief Error status */ + t_ushort_value frame_interpolation_hint_enabled; /**< \brief picture layer frame interpolation hint set (INTERPFRM) */ + t_ushort_value range_reduction_frame_enabled; /**< \brief picture layer frame rangered flag (RANGEREDFRM) */ + t_ushort_value b_fraction_numerator; /**< \brief picture layer b fraction numerator (BFRACTION) */ + t_ushort_value b_fraction_denominator; /**< \brief picture layer b fraction denominatror (BFRACTION) */ + t_ushort_value buffer_fullness; /**< \brief picture layer buffer fullness (BF) */ + t_ushort_value picture_res; /**< \brief picture resolution: 1x1 == 0 2x1 == 1,1x2 == 2, 2x2 = 3 */ + t_ushort_value max_picture_width; /**< \brief true width of the decoded picture (including res) */ + t_ushort_value max_picture_height; /**< \brief true height of the decoded picture */ + t_ushort_value picture_width; /**< \brief true width of the decoded picture (including res) */ + t_ushort_value picture_height; /**< \brief true height of the decoded picture */ + t_ushort_value picture_type; /**< \brief picture type: I==0, P==1,B==2,BI==3,SKIPPED==4 */ + t_ulong_value padding1; /**< \brief Reserved 32 */ + t_ulong_value padding2; /**< \brief Reserved 32 */ + +} ts_t1xhv_vdc_vc1_param_out, *tps_t1xhv_vdc_vc1_param_out; + +/** \brief Hamac video vc1 decode in / out parameters */ +typedef struct vdc_vc1_param_inout +{ + t_ushort_value intensity_compensate_enabled; /**< \brief true if last P frame decoded has intensity compensation set */ + t_ushort_value last_ref_rangered_enabled; /**< \brief true if last reference decoded has range reduction set */ + t_ushort_value previous_last_ref_rangered_enabled; /**< \brief true if previous last reference decoded has range reduction set */ + t_ushort_value last_ref_interpolation_hint_enabled; /**< \brief used to update output parameters of skipped images */ + t_ushort_value last_ref_buffer_fullness;/**< \brief used to pass buffer fullness of last decoded picture to skipped pictures */ + t_ushort_value luma_scale; /**< \brief LUMSCALE value of last P frame decoded */ + t_ushort_value luma_shift; /**< \brief LUMSHIFT value of last P frame decoded */ + t_ushort_value rnd_ctrl; /**< \brief RND control value (VC-1 8.3.7) */ + t_ushort_value reference_resolution; /**< \brief reference picture resolution same type than output param*/ + t_ushort_value padding1; + t_ulong_value padding2; + t_ulong_value padding3; + t_ulong_value padding4; + +} ts_t1xhv_vdc_vc1_param_inout, *tps_t1xhv_vdc_vc1_param_inout; + + + + +#endif /* _T1XHV_HOST_INTERFACE_H_ */ + + --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/t1xhv_retarget.h @@ -0,0 +1,41 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ + +#ifndef _T1XSVA_RETARGET_H_ +#define _T1XSVA_RETARGET_H_ + + +/*------------------------------------------------------------------------ + * Include + *----------------------------------------------------------------------*/ +#include "hcl_defs.h" + +/*------------------------------------------------------------------------ + * Types + *----------------------------------------------------------------------*/ + typedef t_uint32 t_ulong_value; /* 32 bit unsigned integer (Little endian for 16 bit word) */ + typedef t_sint32 t_long_value; /* 32 bit signed integer (Little endian for 16 bit word) */ + typedef t_uint16 t_ushort_value; /* 16 bit unsigned integer */ + typedef t_sint16 t_short_value; /* 16 bit signed integer */ + typedef t_physical_address t_ahb_address; /* 32 bit unsigned integer to define AHB address */ + typedef t_uint32 t_time_stamp; /* 32 bit unsigned integer to define a time stamp */ + +#endif /* _T1XSVA_RETARGET_H_ */ + + --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/memory_management/sva_bufferlistmgt.c @@ -0,0 +1,541 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ + +/*------------------------------------------------------------------------ + * Includes + *----------------------------------------------------------------------*/ +#include "sva.h" +#include "sva_buffermgt.h" +#include "sva_bufferlistmgt.h" +#include "sva_bufferlistmgtp.h" +#include "sva_buffermgtp.h" +#include "sva_memorymgt.h" + +/*------------------------------------------------------------------------ + * Global Variables + *----------------------------------------------------------------------*/ +PRIVATE t_sva_bm_buffer_list_desc bufferListInfo[NB_MAX_MANAGED_BUFFER_LIST]; + +/****************************************************************************/ +/* NAME: t_sva_blm_error sva_BLM_Init ( void ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine initialize the BufferList Management module (internal */ +/* Private structure) */ +/* */ +/* PARAMETERS: */ +/* IN : - none */ +/* */ +/* OUT: - none */ +/* */ +/* RETURN: */ +/* t_sva_blm_error */ +/* - SVA_BLM_OK : init done correctly */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_sva_blm_error sva_BLM_Init(void) +{ + t_uint32 cpt; + + for (cpt=0; cptisFree) + return(SVA_BLM_UNKNOWN_IDENTIFIER); + + if (pBufferListInfo->nbBufferId == NB_MAX_BUFFER_ID_IN_LIST) + return(SVA_BLM_ERROR); + + // look for an empty slot (ID = INVALID_BUFFER_LIST_ID) to fit the listID in the buffer structure + if (sva_BLM_GetBufferListIndex(INVALID_BUFFER_LIST_ID, bufferId, &bufferListIndex1) != SVA_BLM_OK) + return SVA_BLM_ERROR; + + if (sva_BM_GetBufferLinkInformation( bufferId, &pBufferToBeAddedListInfo, + &bufferLinkPhysicalAddress) != SVA_BM_OK) return(SVA_BLM_UNKNOWN_IDENTIFIER); + + pBufferToBeAddedListInfo[bufferListIndex1].bufferListId = bufferListId; + + if (pBufferListInfo->lastBufferId != INVALID_BUFFER_ID) + { + if (sva_BM_GetBufferLinkInformation( pBufferListInfo->lastBufferId, + &pBufferLastListInfo, &bufferLastLinkPhysicalAddress) != SVA_BM_OK) + return(SVA_BLM_ERROR); + + if (sva_BLM_GetBufferListIndex(bufferListId, pBufferListInfo->lastBufferId, &bufferListIndex2) != SVA_BLM_OK) + return SVA_BLM_ERROR; + + /* There's already an element in the list. */ + pBufferToBeAddedListInfo[bufferListIndex1].nextBufferId = INVALID_BUFFER_ID; + pBufferToBeAddedListInfo[bufferListIndex1].prevBufferId = pBufferListInfo->lastBufferId; + pBufferToBeAddedListInfo[bufferListIndex1].bufferLink.addr_next_buf_link = 0; + pBufferToBeAddedListInfo[bufferListIndex1].bufferLink.addr_prev_buf_link = + bufferLastLinkPhysicalAddress + (bufferListIndex2)*(sizeof(t_sva_bm_list_elem)); + + pBufferLastListInfo[bufferListIndex2].nextBufferId = bufferId; + pBufferLastListInfo[bufferListIndex2].bufferLink.addr_next_buf_link = + bufferLinkPhysicalAddress + (bufferListIndex1)*(sizeof(t_sva_bm_list_elem)); + + pBufferListInfo->nbBufferId += 1; + pBufferListInfo->lastBufferId = bufferId; + } + else + { + /* First element in the list. */ + pBufferListInfo->nbBufferId = 1; + pBufferListInfo->firstLinkPhysicalAddress = bufferLinkPhysicalAddress + (bufferListIndex1)*(sizeof(t_sva_bm_list_elem)); + pBufferListInfo->firstBufferId = bufferId; + pBufferListInfo->lastBufferId = bufferId; + + pBufferToBeAddedListInfo[bufferListIndex1].nextBufferId = INVALID_BUFFER_ID; + pBufferToBeAddedListInfo[bufferListIndex1].prevBufferId = INVALID_BUFFER_ID; + pBufferToBeAddedListInfo[bufferListIndex1].bufferLink.addr_next_buf_link = 0; /**<\brief Address next structure */ + pBufferToBeAddedListInfo[bufferListIndex1].bufferLink.addr_prev_buf_link = 0; /**<\brief Address prev structure */ + } + + return SVA_BLM_OK; + +} /* End of sva_BLM_AddBufferInList() function. */ + +/****************************************************************************/ +/* NAME: t_sva_blm_error sva_BLM_RemoveBufferFromList( */ +/* t_sva_buffer_list_id bufferListId, */ +/* t_sva_buffer_id *bufferId) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: This function removes the first buffer from buffer list */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - bufferListId: identifier to the buffer-list */ +/* - pBufferId : pointer to identifier to the buffer that is removed */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_blm_error */ +/* - SVA_BLM_OK : */ +/* - SVA_BLM_UNKNOWN_IDENTIFIER : */ +/* - SVA_BLM_LIST_EMPTY : */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_sva_blm_error sva_BLM_RemoveBufferFromList(t_sva_buffer_list_id bufferListId, + t_sva_buffer_id *pBufferId) +{ + t_sva_bm_buffer_list_desc *pBufferListInfo; + t_sva_buffer_id bufferSecondId; + t_sva_buffer_id bufferToBeRemovedId; + + t_sva_bm_list_elem *pBufferToBeRemovedListInfo; + t_physical_address bufferLinkPhysicalAddress; + + t_sva_bm_list_elem *pBufferSecondListInfo; + t_physical_address bufferSecondLinkPhysicalAddress; + + t_uint32 bufferListIndex; + + HCL_DEBUG_ASSERT(pBufferId!=NULL); + + pBufferListInfo = (t_sva_bm_buffer_list_desc *)(bufferListId); + + /* Initial checks. */ + /* To be done : Check that bufferListId address is inside the bufferListInfo[] memory window */ + if (pBufferListInfo->isFree) + return(SVA_BLM_UNKNOWN_IDENTIFIER); + + if ( (pBufferListInfo->nbBufferId == 0) || (pBufferListInfo->lastBufferId == INVALID_BUFFER_ID) ) + /* No buffer Id to be removed. */ + return(SVA_BLM_LIST_EMPTY); + + *pBufferId = pBufferListInfo->firstBufferId; + + if (pBufferListInfo->firstBufferId == pBufferListInfo->lastBufferId) + { + /* Last buffer to be removed from the list. */ + pBufferListInfo->nbBufferId = 0; + pBufferListInfo->firstLinkPhysicalAddress = 0; + pBufferListInfo->firstBufferId = INVALID_BUFFER_ID; + pBufferListInfo->lastBufferId = INVALID_BUFFER_ID; + + /* Not last buffer to be removed from the list. */ + bufferToBeRemovedId = *pBufferId; + if (sva_BM_GetBufferLinkInformation( bufferToBeRemovedId, &pBufferToBeRemovedListInfo, + &bufferLinkPhysicalAddress) != SVA_BM_OK) return(SVA_BLM_ERROR); + + if (sva_BLM_GetBufferListIndex(bufferListId, bufferToBeRemovedId, &bufferListIndex) != SVA_BLM_OK) return SVA_BLM_ERROR; + + pBufferToBeRemovedListInfo[bufferListIndex].nextBufferId = INVALID_BUFFER_ID; + pBufferToBeRemovedListInfo[bufferListIndex].prevBufferId = INVALID_BUFFER_ID; + pBufferToBeRemovedListInfo[bufferListIndex].bufferLink.addr_next_buf_link = 0; + pBufferToBeRemovedListInfo[bufferListIndex].bufferLink.addr_prev_buf_link = 0; + pBufferToBeRemovedListInfo[bufferListIndex].bufferListId = INVALID_BUFFER_LIST_ID; + } + else + { + /* Not last buffer to be removed from the list. */ + bufferToBeRemovedId = pBufferListInfo->firstBufferId; + if (sva_BM_GetBufferLinkInformation( bufferToBeRemovedId, &pBufferToBeRemovedListInfo, + &bufferLinkPhysicalAddress) != SVA_BM_OK) return SVA_BLM_ERROR; + + if (sva_BLM_GetBufferListIndex(bufferListId, bufferToBeRemovedId, &bufferListIndex) != SVA_BLM_OK) return SVA_BLM_ERROR; + + bufferSecondId = pBufferToBeRemovedListInfo[bufferListIndex].nextBufferId; + + pBufferToBeRemovedListInfo[bufferListIndex].nextBufferId = INVALID_BUFFER_ID; + pBufferToBeRemovedListInfo[bufferListIndex].prevBufferId = INVALID_BUFFER_ID; + pBufferToBeRemovedListInfo[bufferListIndex].bufferLink.addr_next_buf_link = 0; + pBufferToBeRemovedListInfo[bufferListIndex].bufferLink.addr_prev_buf_link = 0; + pBufferToBeRemovedListInfo[bufferListIndex].bufferListId = INVALID_BUFFER_LIST_ID; + + if (sva_BM_GetBufferLinkInformation( bufferSecondId, + &pBufferSecondListInfo, &bufferSecondLinkPhysicalAddress) != SVA_BM_OK) return SVA_BLM_ERROR; + + if (sva_BLM_GetBufferListIndex(bufferListId, bufferSecondId, &bufferListIndex) != SVA_BLM_OK) return SVA_BLM_ERROR; + + pBufferListInfo->nbBufferId -= 1; + pBufferListInfo->firstLinkPhysicalAddress = + bufferSecondLinkPhysicalAddress + (bufferListIndex)*(sizeof(t_sva_bm_list_elem)); + pBufferListInfo->firstBufferId = bufferSecondId; + + pBufferSecondListInfo[bufferListIndex].prevBufferId = INVALID_BUFFER_ID; + pBufferSecondListInfo[bufferListIndex].bufferLink.addr_prev_buf_link = 0; + } + + return SVA_BLM_OK; +} /* End of sva_BLM_RemoveBufferFromList() function. */ + +/****************************************************************************/ +/* NAME: t_sva_blm_error sva_BLM_DeleteBufferList( */ +/* const t_sva_buffer_list_id bufferListId ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: This routine enables to delete a buffer list. This function */ +/* does not check the buffer list content. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - bufferListId: identifier to the buffer-list */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_blm_error */ +/* - SVA_BLM_OK : */ +/* - SVA_BLM_LIST_NOT_EMPTY : */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_sva_blm_error sva_BLM_DeleteBufferList( const t_sva_buffer_list_id bufferListId) +{ + t_sva_bm_buffer_list_desc *pBufferListInfo; + + pBufferListInfo = (t_sva_bm_buffer_list_desc *)(bufferListId); + + /* Initial checks. */ + /* To be done : Check that bufferListId address is inside the bufferListInfo[] memory window */ + if (pBufferListInfo->isFree) + return(SVA_BLM_UNKNOWN_IDENTIFIER); + + if (pBufferListInfo->nbBufferId != 0) + return(SVA_BLM_LIST_NOT_EMPTY); + + pBufferListInfo->isFree = TRUE; + pBufferListInfo->nbBufferId = 0; + pBufferListInfo->firstLinkPhysicalAddress = 0; + pBufferListInfo->firstBufferId = INVALID_BUFFER_ID; + pBufferListInfo->lastBufferId = INVALID_BUFFER_ID; + + return SVA_BLM_OK; +} /* End of sva_BLM_DeleteBufferList() function. */ + +/****************************************************************************/ +/* NAME: t_sva_blm_error sva_BLM_GetBufferListPhysicalAddress( */ +/* const t_sva_buffer_list_id bufferListId, */ +/* t_physical_address *LinkPhysicalAddress) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: This routine returns the first list's element physical */ +/* address */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - bufferListId: identifier to the buffer-list */ +/* */ +/* OUT : */ +/* - pLinkPhysicalAddress : Pointer on physical address. */ +/* */ +/* RETURN: */ +/* t_sva_blm_error */ +/* - SVA_BLM_OK : Physical address available */ +/* - SVA_BLM_UNKNOWN_IDENTIFIER : Buffer list ID is unknown */ +/* - SVA_BLM_LIST_EMPTY : Physical can't be returned:list is empty */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_sva_blm_error sva_BLM_GetBufferListPhysicalAddress (t_sva_buffer_list_id bufferListId, + t_physical_address *pLinkPhysicalAddress) +{ + t_sva_bm_buffer_list_desc *pBufferListInfo; + t_sva_blm_error blmError = SVA_BLM_OK; + + HCL_DEBUG_ASSERT(pLinkPhysicalAddress!=NULL); + + pBufferListInfo = (t_sva_bm_buffer_list_desc *)(bufferListId); + + /* Initial checks. */ + /* To be done : Check that bufferListId address is inside the bufferListInfo[] memory window */ + if (pBufferListInfo->isFree) + return SVA_BLM_UNKNOWN_IDENTIFIER; + + if (pBufferListInfo->nbBufferId == 0) + return SVA_BLM_LIST_EMPTY; + + *pLinkPhysicalAddress = (pBufferListInfo->firstLinkPhysicalAddress); + + return blmError; +} /* End of sva_BLM_GetBufferListPhysicalAddress() function. */ + +/****************************************************************************/ +/* NAME: t_sva_blm_error sva_BLM_UpdateBufferMemoryBoundaryInBufferList( */ +/* t_sva_buffer_list_id bufferListId, */ +/* t_sva_blm_boundary boundary, */ +/* t_sint32 offset) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: This routine enables to modify start/stop address of the */ +/* first/last buffer that is inside the buffer list. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - bufferListId: identifier to the buffer-list */ +/* - boundary: specify the boundary to update */ +/* - offset: specify the signed offset to apply to the memory address */ +/* i.e.boundary */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_blm_error */ +/* - SVA_BLM_OK : Boundary correctly modified. */ +/* - SVA_BLM_UNKNOWN_IDENTIFIER : Buffer list ID is unknown */ +/* - SVA_BLM_ERROR : Internal error (e.g. can't access to one of */ +/* the buffer of the list) */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_sva_blm_error sva_BLM_UpdateBufferMemoryBoundaryInBufferList ( + t_sva_buffer_list_id bufferListId, + t_sva_blm_boundary boundary, + t_sint32 offset) +{ + + t_sva_bm_buffer_list_desc *pBufferListInfo; + t_physical_address physicalAddress; + t_sva_bm_list_elem *pBufferInfo; + + t_uint32 bufferListIndex; + + pBufferListInfo = (t_sva_bm_buffer_list_desc *)(bufferListId); + + /* Initial checks. */ + /* To be done : Check that bufferListId address is inside the bufferListInfo[] memory window */ + if (pBufferListInfo->isFree) + return(SVA_BLM_UNKNOWN_IDENTIFIER); + + switch (boundary) + { + case BEGIN_OF_FIRST_BUFFER : + if (sva_BM_GetBufferLinkInformation( pBufferListInfo->firstBufferId, &pBufferInfo, &physicalAddress) != SVA_BM_OK) + return(SVA_BLM_ERROR); + + if (sva_BLM_GetBufferListIndex(bufferListId, pBufferListInfo->firstBufferId, &bufferListIndex) != SVA_BLM_OK) + return SVA_BLM_ERROR; + + pBufferInfo[bufferListIndex].bufferLink.addr_buffer_start = + (t_physical_address)((t_sint32)(pBufferInfo[bufferListIndex].bufferLink.addr_buffer_start)+offset); + break; + + case END_OF_LAST_BUFFER : + if (sva_BM_GetBufferLinkInformation( pBufferListInfo->lastBufferId, &pBufferInfo, &physicalAddress) != SVA_BM_OK) + return(SVA_BLM_ERROR); + + if (sva_BLM_GetBufferListIndex(bufferListId, pBufferListInfo->lastBufferId, &bufferListIndex) != SVA_BLM_OK) + return SVA_BLM_ERROR; + + pBufferInfo[bufferListIndex].bufferLink.addr_buffer_end = + (t_physical_address)((t_sint32)(pBufferInfo[bufferListIndex].bufferLink.addr_buffer_end)+offset); + break; + + default : + return(SVA_BLM_ERROR); + } /* switch (boundary) */ + + return(SVA_BLM_OK); + +} /* End of sva_BLM_UpdateBufferMemoryBoundaryInBufferList() function. */ + + + +/****************************************************************************/ +/* NAME: t_sva_blm_error sva_BLM_GetBufferListIndex ( */ +/* t_sva_buffer_list_id bufferListId, */ +/* t_sva_buffer_id bufferId, t_uint32 * bufferListIndex) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: returns the index of the bufferListId in the buffer */ +/* structure */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - bufferListId: identifier to the buffer-list */ +/* - bufferId : handle of the buffer */ +/* */ +/* OUT : */ +/* - bufferListIndex: index of the buffer list in the buffer structure */ +/* */ +/* RETURN: */ +/* t_sva_blm_error */ +/* - SVA_BLM_OK : bufferListIndex is valid */ +/* - SVA_BLM_ERROR : Internal error */ +/* - SVA_BLM_UNKNOWN_IDENTIFIER : bufferId not present in the */ +/* buffer list (bufferListId) */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_sva_blm_error sva_BLM_GetBufferListIndex (t_sva_buffer_list_id bufferListId, + t_sva_buffer_id bufferId, t_uint32 * bufferListIndex) { + + t_physical_address bufferLinkPhysicalAddress; + t_sva_bm_list_elem *pCurrentBufferListInfo; + t_uint32 index; + + HCL_DEBUG_ASSERT(bufferListIndex != NULL); + + if (sva_BM_GetBufferLinkInformation( bufferId, &pCurrentBufferListInfo, &bufferLinkPhysicalAddress) != SVA_BM_OK) + return(SVA_BLM_ERROR); + + // Look for the right buf_link, matching the current buffer list ID + for (index=0; index abort + if (index == NB_MAX_MANAGED_BUFFER_LIST) return SVA_BLM_UNKNOWN_IDENTIFIER; + + *bufferListIndex = index; + + return SVA_BLM_OK; +} + + +// End of file - sva_bufferlistmgt.c --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/memory_management/sva_bufferlistmgt.h @@ -0,0 +1,87 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ +#ifndef __INC_SVA_BUFFERLISTMGT_H +#define __INC_SVA_BUFFERLISTMGT_H + +#include "hcl_defs.h" +#include "sva.h" +#include "sva_buffermgt.h" + +/******************************************************************************/ +/* Constants definitions */ +/******************************************************************************/ + +/* + * Define the special invalid value for t_sva_buffer_list_id variables + */ +#define INVALID_BUFFER_LIST_ID (MASK_ALL32) + +/******************************************************************************/ +/* Types definitions */ +/******************************************************************************/ +/* + * Define the type used to identify/reference a list of buffer + */ +typedef t_uint32 t_sva_buffer_list_id; + + +/* + * Definition of symbol used by Buffer List Management routines to return error + */ +typedef enum { + /* TBD */ + SVA_BLM_ERROR = SVA_BLM_LAST_ERROR, + SVA_BLM_UNKNOWN_IDENTIFIER, + SVA_BLM_LIST_NOT_EMPTY, + SVA_BLM_LIST_EMPTY, + SVA_BLM_NO_MORE_BUFFER_LIST_ID, + SVA_BLM_OK = HCL_OK +} t_sva_blm_error; + +typedef enum +{ + BEGIN_OF_FIRST_BUFFER, + END_OF_LAST_BUFFER +} t_sva_blm_boundary; + +/******************************************************************************* +* PUBLIC Functions +*******************************************************************************/ + +// init +PUBLIC t_sva_blm_error sva_BLM_Init(void); +//create an id for a list +PUBLIC t_sva_blm_error sva_BLM_CreateBufferList(t_sva_buffer_list_id *); +//add a new element at the end of the list: a new bitstream buffer is available for service ; it is defined by its start address and also its end address +PUBLIC t_sva_blm_error sva_BLM_AddBufferInList(t_sva_buffer_list_id, t_sva_buffer_id); +//remove first element at list start: a bitstream buffer has been fully decoded and can be removed from the list +PUBLIC t_sva_blm_error sva_BLM_RemoveBufferFromList(t_sva_buffer_list_id, t_sva_buffer_id *); +//delete buffer list +PUBLIC t_sva_blm_error sva_BLM_DeleteBufferList (const t_sva_buffer_list_id ); +//get physical address of first element of the list +PUBLIC t_sva_blm_error sva_BLM_GetBufferListPhysicalAddress (t_sva_buffer_list_id, t_physical_address *); +//modify start/stop address of buffer list's element +PUBLIC t_sva_blm_error sva_BLM_UpdateBufferMemoryBoundaryInBufferList (t_sva_buffer_list_id, t_sva_blm_boundary , t_sint32); +//Get the index of the buffer list's handle from a given buffer +PUBLIC t_sva_blm_error sva_BLM_GetBufferListIndex (t_sva_buffer_list_id, t_sva_buffer_id, t_uint32 *); + + +#endif /* __INC_SVA_BUFFERLISTMGT_H */ +// End of file - sva_bufferlistmgt.h + --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/memory_management/sva_bufferlistmgtp.h @@ -0,0 +1,73 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ + +#ifndef __INC_SVA_BLM_P_H +#define __INC_SVA_BLM_P_H + +#include "hcl_defs.h" +#include "sva.h" +#include "sva_service.h" + +/******************************************************************************/ +/* Buffer List Constants definitions */ +/******************************************************************************/ +/* + * Define the maximum number of buffer list id + * managed at the same time into the buffer management library + */ +#define NB_MAX_MANAGED_BUFFER_LIST ((NUM_MAX_GRAB*SUBTASK_GRAB_NUMBER)+(NUM_MAX_ENCODE*SUBTASK_ENCODE_NUMBER)+(NUM_MAX_DECODE*SUBTASK_DEFAULT_NUMBER)+(NUM_MAX_STILL_ENCODE*STILL_ENCODE_SUBTASK_DEFAULT_NUMBER)+(NUM_MAX_STILL_DECODE*SUBTASK_DEFAULT_NUMBER)) +/* + * Define the maximum number of buffer list id + * managed at the same time into the buffer management library + */ +#define NB_MAX_BUFFER_ID_IN_LIST 64 + + +/* + * Define the possible state of an element of buffer list Id array. +*/ +#define SVA_BLM_FREE ((t_physical_address)NULL) +#define SVA_BLM_ALLOCATED ((t_physical_address)(-1)) + + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/******************************************************************************/ +/* Types definitions */ +/******************************************************************************/ + +/* + * Define a type used to characterize a buffer list element + */ +typedef struct { + t_bool isFree; + t_uint32 nbBufferId; + t_sva_buffer_id firstBufferId; + t_sva_buffer_id lastBufferId; + t_physical_address firstLinkPhysicalAddress; +} t_sva_bm_buffer_list_desc; + +#ifdef __cplusplus +} /* allow C++ to use these headers */ +#endif /* __cplusplus */ + +#endif /* __INC_SVA_BLM_P_H */ +/* End of file - sva_bufferlistmgtp.h */ --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/memory_management/sva_buffermgt.c @@ -0,0 +1,1212 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ + +/*------------------------------------------------------------------------ + * Includes + *----------------------------------------------------------------------*/ +#include "hcl_defs.h" +#include "sva_buffermgt.h" +#include "sva_buffermgtp.h" +#include "sva_bufferlistmgt.h" + +/*------------------------------------------------------------------------ + * Global Variables + *----------------------------------------------------------------------*/ +ALIGN(32) PRIVATE t_uint32 nbAllocatedBuffers = 0; + +//PUBLIC t_sva_dedicated_memory dedicatedMemoryMap; +/*------------------------------------------------------------------------ + * Private Macros + *----------------------------------------------------------------------*/ +/* + * +*/ +#define BM_CHECK_BUFFER_ID(x) {if ( ((t_sva_bm_buffer_desc *)(x))->magicNumber != SVA_BM_MAGIC_NUMBER) \ + return(SVA_BM_UNKNOWN_BUFFER_ID);} + +#define CHECK_BUFFER_ID(x) {if ( ((t_sva_bm_buffer_desc *)(x))->magicNumber != SVA_BM_MAGIC_NUMBER) \ + return(SVA_UNKNOWN_BUFFER_ID);} + +/*------------------------------------------------------------------------ + * PRIVATE Functions Prototypes + *----------------------------------------------------------------------*/ + +/*------------------------------------------------------------------------ + * PUBLIC Functions Prototypes + *----------------------------------------------------------------------*/ + +/****************************************************************************/ +/* NAME: t_sva_bm_error sva_BM_Init (void) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine initialize the Buffer Management module */ +/* */ +/* PARAMETERS: */ +/* IN : none */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_bm_error: SVA_BM_OK */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: no */ +/****************************************************************************/ +PUBLIC t_sva_bm_error sva_BM_Init(void) +{ + nbAllocatedBuffers = 0; + + sva_BLM_Init(); + + return(SVA_BM_OK); +} /* End of sva_BM_Init() function. */ + + +/****************************************************************************/ +/* NAME: t_sva_bm_error sva_BM_InitDedicatedMemory () */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine initialize the additional zone within the SVA chunk */ +/* */ +/* PARAMETERS: */ +/* IN : additionalZone : purpose of the additional zone */ +/* zoneAddress : start address of the dedicated zone */ +/* zoneSize : size */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_bm_error: SVA_BM_OK */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: no */ +/****************************************************************************/ +/* +PUBLIC t_sva_bm_error sva_BM_InitDedicatedMemory( t_sva_dedicated_area_purpose additionalZone, + t_system_address zoneAddress, + t_size zoneSize) { + + t_sva_dedicated_memory_block * dedicatedMemoryInitBlock; + t_sva_block_id dedicatedMemoryInitBlockId; + t_system_address dedicatedMemoryInitBlockAddress; + t_sva_mm_error mmStatus; + + if (additionalZone != SVA_VC1_IMAGE_BUFFER_AREA) return SVA_BM_ERROR; + + // set up mapping of the dedicated memory + dedicatedMemoryMap.nbOfFreeBlocks = 1; + dedicatedMemoryMap.nbOfUseBlocks = 0; + mmStatus = sva_MM_AllocBlock(SDRAM_ID, sizeof(t_sva_dedicated_memory_block), SVA_MM_ALIGN_16BYTES, &dedicatedMemoryInitBlockId); + if (mmStatus != SVA_MM_OK) return(SVA_BM_ERROR); + mmStatus = sva_MM_GetBlockSystemAddress(dedicatedMemoryInitBlockId, &dedicatedMemoryInitBlockAddress); + if (mmStatus != SVA_MM_OK) return(SVA_BM_ERROR); + dedicatedMemoryInitBlock = (t_sva_dedicated_memory_block *)dedicatedMemoryInitBlockAddress.logical; + + dedicatedMemoryInitBlock->address.logical = zoneAddress.logical + (128*ONE_KB); + dedicatedMemoryInitBlock->address.physical = zoneAddress.physical + (128*ONE_KB); + dedicatedMemoryInitBlock->size = zoneSize - (128*ONE_KB); // keep 128KB for fw internal needs + dedicatedMemoryInitBlock->nextBlock = NULL; + dedicatedMemoryInitBlock->previousBlock = NULL; + + dedicatedMemoryMap.firstFreeBlock = dedicatedMemoryInitBlock; + dedicatedMemoryMap.firstUsedBlock = NULL; + + // prog2 and data2 in eSRAM -> not affected + return SVA_BM_OK; +} +*/ + +/* Buffers Management (Memory point of view) */ + +/****************************************************************************/ +/* NAME: t_sva_error SVA_DefineBuffer ( */ +/* t_sva_buffer_type bufferType, */ +/* t_size bufferSize, */ +/* t_system_address bufferSystemAddr, */ +/* t_sva_buffer_id *pBufferId) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine defines a new share buffer between the upper layer */ +/* and the HCL. */ +/* The chunk of memory SHALL have been allocated previously */ +/* by upper layer. */ +/* The goal of this routine is only to share, */ +/* between the user and the HCL, the characteristics of a piece of */ +/* memory used as a buffer of a given type. */ +/* */ +/* PARAMETERS: */ +/* IN : - bufferType: identify which kind of buffer we want to allocate */ +/* - bufferSize: buffer size */ +/* - bufferSystemAddr: allocated buffer system address */ +/* */ +/* OUT: - pBufferId: returned identifier of the allocated buffer */ +/* */ +/* RETURN: */ +/* t_sva_error: SVA_OK */ +/* SVA_NO_MORE_BUFFER_ID */ +/* SVA_MISALIGNED_BUFFER */ +/* SVA_OUT_OF_MEMORY */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_sva_error SVA_DefineBuffer(t_sva_buffer_type bufferType, + t_size bufferSize, + t_system_address bufferSystemAddress, + t_sva_buffer_id *pBufferId) +{ + t_sva_mm_alignment alignment; + t_sva_bm_buffer_desc *pBufferDesc; + t_sva_block_id headerBlockId; + t_system_address headerBlockSystemAddress; + t_sva_mm_error mmErrorCode; + t_uint32 i; + + HCL_DEBUG_ASSERT(pBufferId!=NULL); + + switch(bufferType) + { + case SVA_INFOS_BUFFER_TYPE: + case SVA_PARAMS_BUFFER_TYPE: + alignment = SVA_MM_ALIGN_WORD; + break; + case SVA_IMAGE_BUFFER_TYPE: + alignment = SVA_MM_ALIGN_256BYTES; + break; + default: + alignment = SVA_MM_ALIGN_AHB_BURST; + } + + if ((bufferSystemAddress.physical & alignment) != 0) {return SVA_MISALIGNED_BUFFER;} + if (bufferType == SVA_BITSTREAM_BUFFER_TYPE && (bufferSize & alignment) != 0) {return SVA_MISALIGNED_BUFFER;} + + /* Allocate in SDRAM one header for this buffer. */ + mmErrorCode = sva_MM_AllocBlock(SDRAM_ID, sizeof(t_sva_bm_buffer_desc), SVA_MM_ALIGN_16BYTES,&headerBlockId); + if (mmErrorCode != SVA_MM_OK) {return SVA_OUT_OF_MEMORY;} + sva_MM_GetBlockSystemAddress(headerBlockId, &headerBlockSystemAddress); + + pBufferDesc = (t_sva_bm_buffer_desc *)(headerBlockSystemAddress.logical); + + /* Now, initialize all header's fields. */ + pBufferDesc->status.type = bufferType; + pBufferDesc->status.state = SVA_BUFFER_NOT_USED; + pBufferDesc->status.timestamp.type = SVA_NO_TIMESTAMP; + pBufferDesc->status.timestamp.value = 0; + pBufferDesc->extraData = 0; + + pBufferDesc->bufferblockId = INVALID_SDRAM_BLOCK_ID; + pBufferDesc->bufferSystemAddress = bufferSystemAddress; + pBufferDesc->bufferSize = bufferSize; + pBufferDesc->headerBufferBlockId = headerBlockId; + pBufferDesc->headerBufferSystemAddress = headerBlockSystemAddress; + + for (i=0; ibufferListInfo[i].nextBufferId = INVALID_BUFFER_ID; + pBufferDesc->bufferListInfo[i].prevBufferId = INVALID_BUFFER_ID; + pBufferDesc->bufferListInfo[i].bufferLink.addr_next_buf_link = 0; + pBufferDesc->bufferListInfo[i].bufferLink.addr_prev_buf_link = 0; + pBufferDesc->bufferListInfo[i].bufferLink.addr_buffer_start = bufferSystemAddress.physical; + /* Warning, addr_buffer_end is multiple of 16 bytes (cf. HAMAC Video Specifications : */ + /* BBE is the address of the 32-bit word following the last word that belongs to the */ + /* bitstream buffer. It must be a multiple of 16, otherwise error_type is set to 0x8a */ + pBufferDesc->bufferListInfo[i].bufferLink.addr_buffer_end = bufferSystemAddress.physical + bufferSize; + + pBufferDesc->bufferListInfo[i].bufferListId = INVALID_BUFFER_LIST_ID; + pBufferDesc->bufferListInfo[i].index = i; + } + + pBufferDesc->magicNumber = SVA_BM_MAGIC_NUMBER; + + *pBufferId = (t_sva_buffer_id)(pBufferDesc); + + return(SVA_OK); + +} /* End of SVA_DefineBuffer() function. */ + +/****************************************************************************/ +/* NAME: t_sva_error SVA_RemoveBuffer ( */ +/* t_sva_buffer_id bufferId) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine is used to declare that a previously defined buffer */ +/* will not be used anymore. */ +/* */ +/* PARAMETERS: */ +/* IN : - bufferId: identifier of the buffer to remove */ +/* */ +/* OUT: none */ +/* */ +/* RETURN: */ +/* t_sva_error: SVA_OK */ +/* SVA_UNKNOWN_BUFFER_ID */ +/* SVA_INTERNAL_MEMORY_MGT_ERROR */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_sva_error SVA_RemoveBuffer(t_sva_buffer_id bufferId) +{ + t_sva_bm_buffer_desc *pBufferDesc; + t_sva_mm_error mmErrorCode; + + CHECK_BUFFER_ID(bufferId); /* Will return SVA_UNKNOWN_BUFFER_ID if required. */ + + pBufferDesc = (t_sva_bm_buffer_desc *)(bufferId); + + if (pBufferDesc->status.state == SVA_BUFFER_IN_USE) {return SVA_BUFFER_IS_IN_USE;} + + pBufferDesc->magicNumber = 0; + + mmErrorCode = sva_MM_FreeBlock(pBufferDesc->headerBufferBlockId); + if (mmErrorCode != SVA_MM_OK) {return SVA_INTERNAL_MEMORY_MGT_ERROR;} + + return(SVA_OK); +} /* End of SVA_RemoveBuffer() function. */ + +/****************************************************************************/ +/* NAME: t_sva_error SVA_AllocBuffer ( */ +/* t_sva_buffer_type bufferType, */ +/* t_size bufferSize, */ +/* t_system_address *pBufferSystemAddr, */ +/* t_sva_buffer_id *pBufferId) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine allocates a buffer into the internal managed memory. */ +/* This routine is provided in case of the user provides to the HCL at */ +/* initialization stage (or after that, thanks to a */ +/* SVA_AddPrivateMemoryChunk() call) a big piece of memory ( some MB) */ +/* and buffers are managed by the HCL */ +/* */ +/* PARAMETERS: */ +/* IN : - bufferType: identify which kind of buffer we want to allocate */ +/* - bufferSize: buffer size */ +/* */ +/* OUT: - pBufferSystemAddr: allocated buffer system address */ +/* - pBufferId: returned identifier of the allocated buffer */ +/* */ +/* RETURN: */ +/* t_sva_error: SVA_OK */ +/* SVA_NO_MORE_BUFFER_ID */ +/* SVA_MISALIGNED_BUFFER */ +/* SVA_OUT_OF_MEMORY */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_sva_error SVA_AllocBuffer(t_sva_buffer_type bufferType, + t_size bufferSize, + t_system_address *pBufferSystemAddr, + t_sva_buffer_id *pBufferId) +{ + t_sva_mm_error mmErrorCode; + t_sva_bm_buffer_desc *pBufferDesc; + t_sva_block_id headerBlockId; + t_sva_block_id bufferBlockId; + t_system_address headerBlockSystemAddress; + t_system_address bufferBlockSystemAddress; + t_sva_mm_alignment alignment = SVA_MM_ALIGN_4096BYTES; // MMU page alignment + t_uint32 i; + + + HCL_DEBUG_ASSERT(pBufferSystemAddr!=NULL); + HCL_DEBUG_ASSERT(pBufferId!=NULL); + + switch (bufferType) + { + case SVA_INFOS_BUFFER_TYPE: + case SVA_PARAMS_BUFFER_TYPE: + alignment = SVA_MM_ALIGN_WORD; + break; + case SVA_IMAGE_BUFFER_TYPE: + alignment = SVA_MM_ALIGN_256BYTES; + break; + default: + alignment = SVA_MM_ALIGN_AHB_BURST; + } + + /* Check bufferSize correctness */ + if (bufferType == SVA_BITSTREAM_BUFFER_TYPE && (bufferSize & alignment) != 0) {return SVA_MISALIGNED_BUFFER;} + + /* Allocate in SDRAM one header for this buffer. */ + mmErrorCode = sva_MM_AllocBlock(SDRAM_ID, sizeof(t_sva_bm_buffer_desc), SVA_MM_ALIGN_16BYTES,&headerBlockId); + if (mmErrorCode != SVA_MM_OK) {return SVA_OUT_OF_MEMORY;} + mmErrorCode = sva_MM_GetBlockSystemAddress(headerBlockId, &headerBlockSystemAddress); + if (mmErrorCode != SVA_MM_OK) {return SVA_INTERNAL_MEMORY_MGT_ERROR;} + + pBufferDesc = (t_sva_bm_buffer_desc *)(headerBlockSystemAddress.logical); + + /* Allocate the requested memory chunk (i.e. buffer data) */ + mmErrorCode = sva_MM_AllocBlock(SDRAM_ID, bufferSize, SVA_MM_ALIGN_4096BYTES, &bufferBlockId); + if (mmErrorCode != SVA_MM_OK) {sva_MM_FreeBlock(headerBlockId);return(SVA_OUT_OF_MEMORY);} + mmErrorCode = sva_MM_GetBlockSystemAddress(bufferBlockId, &bufferBlockSystemAddress); + if (mmErrorCode != SVA_MM_OK) {return SVA_INTERNAL_MEMORY_MGT_ERROR;} + + pBufferDesc->status.type = bufferType; + pBufferDesc->status.state = SVA_BUFFER_NOT_USED; + pBufferDesc->status.timestamp.type = SVA_NO_TIMESTAMP; + pBufferDesc->status.timestamp.value = 0; + pBufferDesc->extraData = 0; + + pBufferDesc->bufferblockId = bufferBlockId; + pBufferDesc->bufferSystemAddress = bufferBlockSystemAddress; + pBufferDesc->bufferSize = bufferSize; + pBufferDesc->headerBufferBlockId = headerBlockId; + pBufferDesc->headerBufferSystemAddress = headerBlockSystemAddress; + + for (i=0; ibufferListInfo[i].nextBufferId = INVALID_BUFFER_ID; + pBufferDesc->bufferListInfo[i].prevBufferId = INVALID_BUFFER_ID; + pBufferDesc->bufferListInfo[i].bufferLink.addr_next_buf_link = 0; + pBufferDesc->bufferListInfo[i].bufferLink.addr_prev_buf_link = 0; + pBufferDesc->bufferListInfo[i].bufferLink.addr_buffer_start = bufferBlockSystemAddress.physical; + /* Warning, addr_buffer_end is multiple of 16 bytes (cf. HAMAC Video Specifications : */ + /* BBE is the address of the 32-bit word following the last word that belongs to the */ + /* bitstream buffer. It must be a multiple of 16, otherwise error_type is set to 0x8a */ + pBufferDesc->bufferListInfo[i].bufferLink.addr_buffer_end = bufferBlockSystemAddress.physical + bufferSize; + + pBufferDesc->bufferListInfo[i].bufferListId = INVALID_BUFFER_LIST_ID; + pBufferDesc->bufferListInfo[i].index = i; + } + + pBufferDesc->magicNumber = SVA_BM_MAGIC_NUMBER; + + *pBufferSystemAddr = bufferBlockSystemAddress; + *pBufferId = (t_sva_buffer_id)(pBufferDesc); + + nbAllocatedBuffers++; + return(SVA_OK); +} /* End of SVA_AllocBuffer() function. */ + +/****************************************************************************/ +/* NAME: t_sva_error SVA_FreeBuffer ( */ +/* t_sva_buffer_id bufferId) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine frees a previously allocated buffer. */ +/* */ +/* PARAMETERS: */ +/* IN : - bufferId: identifier of the buffer to remove */ +/* */ +/* OUT: none */ +/* */ +/* RETURN: */ +/* t_sva_error: SVA_OK */ +/* SVA_BM_UNKNOWN_BUFFER_ID */ +/* SVA_BUFFER_IS_IN_USE */ +/* SVA_INTERNAL_MEMORY_MGT_ERROR */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_sva_error SVA_FreeBuffer(t_sva_buffer_id bufferId) +{ + t_sva_bm_buffer_desc *pBufferDesc; + t_sva_mm_error mmErrorCode; + + CHECK_BUFFER_ID(bufferId); /* Will return SVA_UNKNOWN_BUFFER_ID if required. */ + + pBufferDesc = (t_sva_bm_buffer_desc *)(bufferId); + + if (pBufferDesc->status.state == SVA_BUFFER_IN_USE) {return SVA_BUFFER_IS_IN_USE;} + + pBufferDesc->magicNumber = 0; + + mmErrorCode = sva_MM_FreeBlock(pBufferDesc->bufferblockId); + if (mmErrorCode != SVA_MM_OK) {return SVA_INTERNAL_MEMORY_MGT_ERROR;} + + mmErrorCode = sva_MM_FreeBlock(pBufferDesc->headerBufferBlockId); + if (mmErrorCode != SVA_MM_OK) {return SVA_INTERNAL_MEMORY_MGT_ERROR;} + + nbAllocatedBuffers--; + return(SVA_OK); +} /* End of SVA_FreeBuffer() function. */ + + +/****************************************************************************/ +/* NAME: t_sva_error SVA_AllocDedicatedBuffer () */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine allocates a buffer into the internal managed memory. */ +/* it behaves like SVA_AllocBuffer, but the allocation is actually */ +/* made with the MMDSP Data16_1 memory section, created after a call */ +/* to SVA_ConfigurePrivateMemoryChunk(). */ +/* This routine must be used to allocate SVA_IMAGE_BUFFER_TYPE buffers */ +/* for the VC1 decoder. */ +/* */ +/* PARAMETERS: */ +/* IN : - bufferType: identify which kind of buffer we want to allocate */ +/* - bufferSize: buffer size */ +/* - bufferUsage: must be SVA_VC1_DEDICATED_BUFFER */ +/* */ +/* OUT: - pBufferSystemAddr: allocated buffer system address */ +/* - pBufferId: returned identifier of the allocated buffer */ +/* */ +/* RETURN: */ +/* t_sva_error: SVA_OK */ +/* SVA_NO_MORE_BUFFER_ID */ +/* SVA_MISALIGNED_BUFFER */ +/* SVA_OUT_OF_MEMORY */ +/* SVA_UNEXPECTED_API_CALL */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_sva_error SVA_AllocDedicatedBuffer( t_sva_buffer_usage bufferUsage, + t_sva_buffer_type bufferType, + t_size size, + t_system_address *pSystemAddress, + t_sva_buffer_id *pBufferId) { + + t_sva_mm_error mmErrorCode; + t_sva_bm_buffer_desc *pBufferDesc; + t_sva_block_id headerBlockId; + t_system_address headerBlockSystemAddress; + t_uint32 i; + + t_sva_mm_alignment alignment; + + + /* + t_sva_dedicated_memory_block *freeBlock, *usedBlock; + t_sva_dedicated_memory_block *removedBlock; + t_sva_dedicated_memory_block * dedicatedMemoryNewBlock; + t_system_address dedicatedMemoryNewBlockAddress; + */ + t_sva_block_id dedicatedMemoryNewBlockId; + t_sva_dedicated_memory_block * dedicatedMemoryNewBlock; + t_system_address dedicatedMemoryNewBlockAddress, align_dedicatedMemoryNewBlockAddress; + + if (bufferType == SVA_IMAGE_BUFFER_TYPE) + alignment = SVA_MM_ALIGN_4096BYTES; + else if (bufferType == SVA_PARAMS_BUFFER_TYPE) //Currently for GB_HQ only + alignment = SVA_MM_ALIGN_4096BYTES; + else + alignment = SVA_MM_ALIGN_WORD; + + HCL_DEBUG_ASSERT(pSystemAddress!=NULL); + HCL_DEBUG_ASSERT(pBufferId!=NULL); + + // as far as only VC1 decode is concerned, SVA_AllocDedicatedBuffer() supports only SVA_IMAGE_BUFFER_TYPE + // For GB HQ only SVA_PARAMS_BUFFER_TYPE is supported + //if (bufferUsage!=SVA_VC1_DEDICATED_BUFFER || bufferUsage!= SVA_GB_HQ_DEDICATED_BUFFER) return SVA_UNEXPECTED_API_CALL; + if (bufferUsage==SVA_VC1_DEDICATED_BUFFER) + if (bufferType!=SVA_IMAGE_BUFFER_TYPE) + return SVA_UNEXPECTED_API_CALL; + else if (bufferUsage==SVA_GB_HQ_DEDICATED_BUFFER ) + if(bufferType!=SVA_PARAMS_BUFFER_TYPE) + return SVA_UNEXPECTED_API_CALL; + else + return SVA_UNEXPECTED_API_CALL; + + /* Allocate in SDRAM a new header for this buffer. */ + mmErrorCode = sva_MM_AllocBlock(SDRAM_ID, sizeof(t_sva_bm_buffer_desc), SVA_MM_ALIGN_16BYTES,&headerBlockId); + if (mmErrorCode != SVA_MM_OK) {return SVA_OUT_OF_MEMORY;} + mmErrorCode = sva_MM_GetBlockSystemAddress(headerBlockId, &headerBlockSystemAddress); + if (mmErrorCode != SVA_MM_OK) {return SVA_INTERNAL_MEMORY_MGT_ERROR;} + + pBufferDesc = (t_sva_bm_buffer_desc *)(headerBlockSystemAddress.logical); + + /* Allocate the requested memory chunk (i.e. buffer data) */ + /* + freeBlock = dedicatedMemoryMap.firstFreeBlock; + usedBlock = dedicatedMemoryMap.firstUsedBlock; + // look for the first big enough block to fit the new buffer + while((freeBlock->size < size) && (freeBlock->nextBlock != NULL)) freeBlock = freeBlock->nextBlock; + if ((freeBlock->size < size) && (freeBlock->nextBlock == NULL)) return SVA_OUT_OF_MEMORY; + + // allocate a "dedicated" header + mmErrorCode = sva_MM_AllocBlock(SDRAM_ID, sizeof(t_sva_dedicated_memory_block), SVA_MM_ALIGN_16BYTES, &dedicatedMemoryNewBlockId); + if (mmErrorCode != SVA_MM_OK) return(SVA_INTERNAL_MEMORY_MGT_ERROR); + mmErrorCode = sva_MM_GetBlockSystemAddress(dedicatedMemoryNewBlockId, &dedicatedMemoryNewBlockAddress); + if (mmErrorCode != SVA_MM_OK) return(SVA_INTERNAL_MEMORY_MGT_ERROR); + dedicatedMemoryNewBlock = (t_sva_dedicated_memory_block *)dedicatedMemoryNewBlockAddress.logical; + + // append the new block at the end of the chain + dedicatedMemoryNewBlock->address.logical = freeBlock->address.logical; + dedicatedMemoryNewBlock->address.physical = freeBlock->address.physical; + dedicatedMemoryNewBlock->size = size; + if (usedBlock==NULL) { // if there is no block allocated + dedicatedMemoryNewBlock->previousBlock = NULL; + dedicatedMemoryMap.firstUsedBlock = dedicatedMemoryNewBlock; + } else { // else, the new block is appened at the end of the chain list + while (usedBlock->nextBlock != NULL) usedBlock = usedBlock->nextBlock; + dedicatedMemoryNewBlock->previousBlock = usedBlock; + usedBlock->nextBlock = dedicatedMemoryNewBlock; + } + dedicatedMemoryNewBlock->nextBlock = NULL; + dedicatedMemoryMap.nbOfUseBlocks++; + + // update free block chain list + if (freeBlock->size == size) { // if the new block's size matched a free block's size, the free block is picked off the list + removedBlock = freeBlock; + freeBlock = freeBlock->previousBlock; + if (freeBlock == NULL) { // if there is just one free block left .... + dedicatedMemoryMap.firstFreeBlock = removedBlock->nextBlock; // it goes to list's first spot + if (removedBlock->nextBlock != NULL) removedBlock->nextBlock->previousBlock = NULL; + } else { + freeBlock->nextBlock = removedBlock->nextBlock; + removedBlock = removedBlock->nextBlock; + removedBlock->previousBlock = freeBlock; + } + dedicatedMemoryMap.nbOfFreeBlocks--; + } else { // if the free block is bigger than needed, its size and start address get updated + freeBlock->address.logical = freeBlock->address.logical + size; + freeBlock->address.physical = freeBlock->address.physical + size; + freeBlock->size = freeBlock->size - size; + } + */ + mmErrorCode = sva_MM_AllocDedicatedBlock(size, alignment, &dedicatedMemoryNewBlockId); + if (mmErrorCode != SVA_MM_OK) return(SVA_INTERNAL_MEMORY_MGT_ERROR); + mmErrorCode = sva_MM_GetBlockSystemAddress(dedicatedMemoryNewBlockId, &dedicatedMemoryNewBlockAddress); + if (mmErrorCode != SVA_MM_OK) return(SVA_INTERNAL_MEMORY_MGT_ERROR); + dedicatedMemoryNewBlock = (t_sva_dedicated_memory_block *)dedicatedMemoryNewBlockAddress.logical; + + align_dedicatedMemoryNewBlockAddress = dedicatedMemoryNewBlock->address; + + { + t_uint32 offset; + if ((align_dedicatedMemoryNewBlockAddress.physical & alignment) != 0) + { + offset = (t_uint16)(((t_uint32)alignment - (t_uint32)(align_dedicatedMemoryNewBlockAddress.physical & alignment)) + 1); + } + else {offset = 0;} + + align_dedicatedMemoryNewBlockAddress.logical += offset; + align_dedicatedMemoryNewBlockAddress.physical += offset; + } + + pBufferDesc->status.type = bufferType; + pBufferDesc->status.state = SVA_BUFFER_NOT_USED; + pBufferDesc->status.timestamp.type = SVA_NO_TIMESTAMP; + pBufferDesc->status.timestamp.value = 0; + pBufferDesc->extraData = 0; + + pBufferDesc->bufferblockId = dedicatedMemoryNewBlockId; + pBufferDesc->bufferSystemAddress = align_dedicatedMemoryNewBlockAddress; + pBufferDesc->bufferSize = size; + pBufferDesc->headerBufferBlockId = headerBlockId; + pBufferDesc->headerBufferSystemAddress = headerBlockSystemAddress; + + for (i=0; ibufferListInfo[i].nextBufferId = INVALID_BUFFER_ID; + pBufferDesc->bufferListInfo[i].prevBufferId = INVALID_BUFFER_ID; + pBufferDesc->bufferListInfo[i].bufferLink.addr_next_buf_link = 0; + pBufferDesc->bufferListInfo[i].bufferLink.addr_prev_buf_link = 0; + pBufferDesc->bufferListInfo[i].bufferLink.addr_buffer_start = align_dedicatedMemoryNewBlockAddress.physical; + /* Warning, addr_buffer_end is multiple of 16 bytes (cf. HAMAC Video Specifications : */ + /* BBE is the address of the 32-bit word following the last word that belongs to the */ + /* bitstream buffer. It must be a multiple of 16, otherwise error_type is set to 0x8a */ + pBufferDesc->bufferListInfo[i].bufferLink.addr_buffer_end = align_dedicatedMemoryNewBlockAddress.physical + size; + + pBufferDesc->bufferListInfo[i].bufferListId = INVALID_BUFFER_LIST_ID; + pBufferDesc->bufferListInfo[i].index = i; + } + + pBufferDesc->magicNumber = SVA_BM_MAGIC_NUMBER; + + *pSystemAddress = align_dedicatedMemoryNewBlockAddress; + *pBufferId = (t_sva_buffer_id)(pBufferDesc); + + nbAllocatedBuffers++; + return(SVA_OK); +} + + +/****************************************************************************/ +/* NAME: t_sva_error SVA_FreeDedicatedBuffer () */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine frees a previously allocated dedicated buffer. */ +/* */ +/* PARAMETERS: */ +/* IN : - bufferId: identifier of the buffer to remove */ +/* - bufferUsage : must be SVA_VC1_DEDICATED_BUFFER */ +/* OUT: none */ +/* */ +/* RETURN: */ +/* t_sva_error: SVA_OK */ +/* SVA_BM_UNKNOWN_BUFFER_ID */ +/* SVA_BUFFER_IS_IN_USE */ +/* SVA_INTERNAL_MEMORY_MGT_ERROR */ +/* SVA_UNEXPECTED_API_CALL */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_sva_error SVA_FreeDedicatedBuffer( t_sva_buffer_usage bufferUsage, t_sva_buffer_id bufferId) { + + t_sva_bm_buffer_desc *pBufferDesc; + + t_sva_mm_error mmErrorCode; + /* + t_system_address dedicatedMemoryBlockAddress; + t_system_address blockStartAddress, blockEndAddress; + t_sva_dedicated_memory_block *prevDedicatedMemoryBlock, *dedicatedMemoryBlock, *nextDedicatedMemoryBlock; + t_sva_dedicated_memory_block *freeBlock; + t_sva_dedicated_memory_block *mergedBlock; + t_bool merged; + */ + CHECK_BUFFER_ID(bufferId); /* Will return SVA_UNKNOWN_BUFFER_ID if required. */ + // As far as today, dedicated buffers are only used by VC1 decoder and GB GQ + if (bufferUsage!=SVA_VC1_DEDICATED_BUFFER&&bufferUsage!=SVA_GB_HQ_DEDICATED_BUFFER) return SVA_UNEXPECTED_API_CALL; + + pBufferDesc = (t_sva_bm_buffer_desc *)(bufferId); + + if (pBufferDesc->status.state == SVA_BUFFER_IN_USE) {return SVA_BUFFER_IS_IN_USE;} + + mmErrorCode =sva_MM_FreeDedicatedBlock(pBufferDesc->bufferblockId); + if (mmErrorCode != SVA_MM_OK) return(SVA_INTERNAL_MEMORY_MGT_ERROR); + + mmErrorCode = sva_MM_FreeBlock(pBufferDesc->headerBufferBlockId); + if (mmErrorCode != SVA_MM_OK) {return SVA_INTERNAL_MEMORY_MGT_ERROR;} + + nbAllocatedBuffers--; + + /* + mmErrorCode = sva_MM_GetBlockSystemAddress(pBufferDesc->bufferblockId, &dedicatedMemoryBlockAddress); + if (mmErrorCode != SVA_MM_OK) return(SVA_INTERNAL_MEMORY_MGT_ERROR); + dedicatedMemoryBlock = (t_sva_dedicated_memory_block *)dedicatedMemoryBlockAddress.logical; + + if (dedicatedMemoryMap.nbOfUseBlocks == 1) + dedicatedMemoryMap.firstUsedBlock = NULL; + else { + prevDedicatedMemoryBlock = dedicatedMemoryBlock->previousBlock; + nextDedicatedMemoryBlock = dedicatedMemoryBlock->nextBlock; + if (prevDedicatedMemoryBlock!=NULL) + prevDedicatedMemoryBlock->nextBlock = nextDedicatedMemoryBlock; + else + dedicatedMemoryMap.firstUsedBlock = nextDedicatedMemoryBlock; + if (nextDedicatedMemoryBlock!=NULL) nextDedicatedMemoryBlock->previousBlock = prevDedicatedMemoryBlock; + } + + dedicatedMemoryMap.nbOfUseBlocks--; + + // handle and defragment the free blocks chain + blockStartAddress = dedicatedMemoryBlock->address; + blockEndAddress.logical = blockStartAddress.logical + dedicatedMemoryBlock->size; + blockEndAddress.physical = blockStartAddress.physical + dedicatedMemoryBlock->size; + + // check is the released memory can be merged with an existing free block + merged = FALSE; + freeBlock = dedicatedMemoryMap.firstFreeBlock; + while (freeBlock != NULL) { + // if one or two block limit(s) match(es) a free block limit, expand the existing free block + if(freeBlock->address.logical == blockEndAddress.logical) { + if (merged == FALSE) { + freeBlock->address = blockStartAddress; + freeBlock->size = freeBlock->size + dedicatedMemoryBlock->size; + merged = TRUE; + } else { + mergedBlock = dedicatedMemoryMap.firstFreeBlock; + while ((mergedBlock->address.logical + mergedBlock->size) != blockEndAddress.logical) { + mergedBlock = mergedBlock->nextBlock; + if (mergedBlock == NULL) return SVA_INTERNAL_MEMORY_MGT_ERROR; // block to be merged not found + } + mergedBlock->size = mergedBlock->size + freeBlock->size; // resize the complete block + mergedBlock->nextBlock = freeBlock->nextBlock; // and remove "freeBlock" from the free block chain + if (freeBlock->nextBlock != NULL) freeBlock->nextBlock->previousBlock = mergedBlock; + dedicatedMemoryMap.nbOfFreeBlocks--; + } + } else { + if((freeBlock->address.logical + freeBlock->size) == blockStartAddress.logical) { + if (merged == FALSE) { + freeBlock->size = freeBlock->size + dedicatedMemoryBlock->size; + merged = TRUE; + } else { + mergedBlock = dedicatedMemoryMap.firstFreeBlock; + while (mergedBlock->address.logical != blockStartAddress.logical) { + mergedBlock = mergedBlock->nextBlock; + if (mergedBlock == NULL) return SVA_INTERNAL_MEMORY_MGT_ERROR; // block to be merged not found + } + mergedBlock->address = freeBlock->address; // update beginning address of the merged area + mergedBlock->size = mergedBlock->size + freeBlock->size; // resize the complete block + mergedBlock->previousBlock = freeBlock->previousBlock; + if (freeBlock->previousBlock != NULL) + freeBlock->previousBlock->nextBlock = mergedBlock; + else // if previous is NULL, it means mergedBlock takes the first spot in the free list + dedicatedMemoryMap.firstFreeBlock = mergedBlock; + dedicatedMemoryMap.nbOfFreeBlocks--; + } + } + } + freeBlock = freeBlock->nextBlock; + } + + if (merged == FALSE) { // no block merged performed ? + // move the block from the used list back to the free list (1st position in the list) + dedicatedMemoryBlock->nextBlock = dedicatedMemoryMap.firstFreeBlock; + dedicatedMemoryMap.firstFreeBlock->previousBlock = dedicatedMemoryBlock; + dedicatedMemoryMap.firstFreeBlock = dedicatedMemoryBlock; + dedicatedMemoryBlock->previousBlock = NULL; + dedicatedMemoryMap.nbOfFreeBlocks++; + } + */ + + return SVA_OK; +} + +/****************************************************************************/ +/* NAME: t_sva_bm_error sva_BM_GetStatus ( */ +/* t_uint32 *pNbAllocatedBuffers) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine provides the number of buffers currently allocated. */ +/* */ +/* PARAMETERS: */ +/* IN : none */ +/* */ +/* OUT: - pNbAllocatedBuffers: nb allocated buffers */ +/* */ +/* RETURN: */ +/* t_sva_error: SVA_OK */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_sva_bm_error sva_BM_GetStatus(t_uint32 *pNbAllocatedBuffers) +{ + HCL_ASSERT(pNbAllocatedBuffers!=NULL); + + *pNbAllocatedBuffers = nbAllocatedBuffers; + + return(SVA_BM_OK); +} /* End of sva_BM_GetStatus() function. */ + +/****************************************************************************/ +/* NAME: t_sva_error SVA_GetBufferStatus ( */ +/* t_sva_buffer_id bufferId, */ +/* t_sva_buffer_status *pStatus) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine provides the current status of a given buffer. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - bufferId: identifier of the buffer */ +/* */ +/* OUT : */ +/* - pStatus: current status of the buffer */ +/* */ +/* RETURN: */ +/* t_sva_error : SVA_OK */ +/* SVA_BM_UNKNOWN_BUFFER_ID */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_sva_error SVA_GetBufferStatus(t_sva_buffer_id bufferId, + t_sva_buffer_status *pStatus) +{ + t_sva_bm_buffer_desc *pBufferDesc; + + HCL_ASSERT(pStatus!=NULL); + + CHECK_BUFFER_ID(bufferId); /* Will return SVA_UNKNOWN_BUFFER_ID if required. */ + + pBufferDesc = (t_sva_bm_buffer_desc *)(bufferId); + + *pStatus = pBufferDesc->status; + + return(SVA_OK); +} /* End of SVA_GetBufferStatus() function. */ + + +/****************************************************************************/ +/* NAME: t_sva_bm_error sva_BM_UpdateBufferStatus ( */ +/* t_sva_buffer_id bufferId, */ +/* t_sva_buffer_state state, */ +/* t_sva_ticks ticksValue) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine allows to update the current state of a given buffer */ +/* and the associated timestamp (system time) */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - bufferId: identifier of the buffer */ +/* - state: new state of the given buffer */ +/* - ticksValue: timestamp (internal time) of the state update */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_bm_error: SVA_BM_OK */ +/* SVA_BM_UNKNOWN_BUFFER_ID */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_sva_bm_error sva_BM_UpdateBufferStatus ( + t_sva_buffer_id bufferId, + t_sva_buffer_state state, + t_sva_ticks ticksValue) +{ + t_sva_bm_buffer_desc *pBufferDesc; + + (void)(ticksValue); + + BM_CHECK_BUFFER_ID(bufferId); /* Will return SVA_BM_UNKNOWN_BUFFER_ID if required. */ + + pBufferDesc = (t_sva_bm_buffer_desc *)(bufferId); + + pBufferDesc->status.state = state; + + return(SVA_BM_OK); +} /* End of sva_BM_UpdateBufferStatus() function. */ + +/****************************************************************************/ +/* NAME: t_sva_bm_error sva_BM_GetBufferLogicalAddress ( */ +/* t_sva_buffer_id bufferId, */ +/* t_logical_address *pLogicalAddress) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine returns the logical address of a given buffer */ +/* */ +/* PARAMETERS: */ +/* IN : - bufferId: buffer identifier */ +/* */ +/* OUT: - pLogicalAddress: logical address of the buffer. */ +/* */ +/* RETURN: */ +/* t_sva_bm_error: SVA_BM_OK */ +/* SVA_BM_UNKNOWN_BUFFER_ID */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_sva_bm_error sva_BM_GetBufferLogicalAddress( + t_sva_buffer_id bufferId, + t_logical_address *pLogicalAddress) +{ + t_sva_bm_buffer_desc *pBufferDesc; + + HCL_ASSERT (pLogicalAddress!=NULL); + + BM_CHECK_BUFFER_ID(bufferId); /* Will return SVA_BM_UNKNOWN_BUFFER_ID if required. */ + + pBufferDesc = (t_sva_bm_buffer_desc *)(bufferId); + + *pLogicalAddress = pBufferDesc->bufferSystemAddress.logical; + + return(SVA_BM_OK); +} /* End of sva_BM_GetBufferLogicalAddress() function. */ + +/****************************************************************************/ +/* NAME: t_sva_bm_error sva_BM_GetBufferPhysicalAddress ( */ +/* t_sva_buffer_id bufferId */ +/* t_physical_address *pPhysicalAddress) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine returns the physical address of a given buffer */ +/* */ +/* PARAMETERS: */ +/* IN : - bufferId: buffer identifier */ +/* */ +/* OUT: - pPhysicalAddress: physical address of the buffer */ +/* */ +/* RETURN: */ +/* t_sva_bm_error: SVA_BM_OK */ +/* SVA_BM_UNKNOWN_BUFFER_ID */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_sva_bm_error sva_BM_GetBufferPhysicalAddress( + t_sva_buffer_id bufferId, + t_physical_address *pPhysicalAddress) +{ + t_sva_bm_buffer_desc *pBufferDesc; + + HCL_ASSERT (pPhysicalAddress!=NULL); + + BM_CHECK_BUFFER_ID(bufferId); /* Will return SVA_BM_UNKNOWN_BUFFER_ID if required. */ + + pBufferDesc = (t_sva_bm_buffer_desc *)(bufferId); + + *pPhysicalAddress = pBufferDesc->bufferSystemAddress.physical; + + return(SVA_BM_OK); +} /* End of sva_BM_GetBufferLogicalAddress() function. */ + +/****************************************************************************/ +/* NAME: t_sva_bm_error sva_BM_GetBufferSystemAddress ( */ +/* t_sva_buffer_id bufferId, */ +/* t_system_address *pSystemAddress) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine returns the system address of a given buffer */ +/* */ +/* PARAMETERS: */ +/* IN : - bufferId: buffer identifier */ +/* */ +/* OUT: - pSystemAddress: system address of the given buffer */ +/* */ +/* RETURN: */ +/* t_sva_bm_error: SVA_BM_OK */ +/* SVA_BM_UNKNOWN_BUFFER_ID */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_sva_bm_error sva_BM_GetBufferSystemAddress( + t_sva_buffer_id bufferId, + t_system_address *pSystemAddress) +{ + t_sva_bm_buffer_desc *pBufferDesc; + + HCL_ASSERT (pSystemAddress!=NULL); + + BM_CHECK_BUFFER_ID(bufferId); /* Will return SVA_BM_UNKNOWN_BUFFER_ID if required. */ + + pBufferDesc = (t_sva_bm_buffer_desc *)(bufferId); + + *pSystemAddress = pBufferDesc->bufferSystemAddress; + + return(SVA_BM_OK); +} /* End of sva_BM_GetBufferSystemAddress() function. */ + +/****************************************************************************/ +/* NAME: t_sva_bm_error sva_BM_GetBufferType ( */ +/* t_sva_buffer_id bufferId */ +/* t_sva_buffer_type *pBufferType) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine returns the type of a given buffer */ +/* */ +/* PARAMETERS: */ +/* IN : - bufferId: buffer identifier */ +/* */ +/* OUT: - pBufferType: Type of the given buffer */ +/* */ +/* RETURN: */ +/* t_sva_bm_error: SVA_BM_OK */ +/* SVA_BM_UNKNOWN_BUFFER_ID */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_sva_bm_error sva_BM_GetBufferType( + t_sva_buffer_id bufferId, + t_sva_buffer_type *pBufferType) +{ + t_sva_bm_buffer_desc *pBufferDesc; + + HCL_ASSERT(pBufferType!=NULL); + + BM_CHECK_BUFFER_ID(bufferId); /* Will return SVA_BM_UNKNOWN_BUFFER_ID if required. */ + + pBufferDesc = (t_sva_bm_buffer_desc *)(bufferId); + + *pBufferType = pBufferDesc->status.type; + + return(SVA_BM_OK); +} /* End of sva_BM_GetBufferType() function. */ + + +/****************************************************************************/ +/* NAME: t_sva_bm_error sva_BM_GetBufferSize ( */ +/* t_sva_buffer_id bufferId */ +/* t_size *pBufferSize) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine returns the size of a given buffer */ +/* */ +/* PARAMETERS: */ +/* IN : - bufferId: buffer identifier */ +/* */ +/* OUT: - pBufferSize: Size of a given buffer */ +/* */ +/* RETURN: */ +/* t_sva_bm_error: SVA_BM_OK */ +/* SVA_BM_UNKNOWN_BUFFER_ID */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ + +PUBLIC t_sva_bm_error sva_BM_GetBufferSize( + t_sva_buffer_id bufferId, + t_size *pBufferSize) +{ + t_sva_bm_buffer_desc *pBufferDesc; + + HCL_ASSERT(pBufferSize!=NULL); + + BM_CHECK_BUFFER_ID(bufferId); /* Will return SVA_BM_UNKNOWN_BUFFER_ID if required. */ + + pBufferDesc = (t_sva_bm_buffer_desc *)(bufferId); + + *pBufferSize = pBufferDesc->bufferSize; + + return(SVA_BM_OK); +} /* End of sva_BM_GetBufferSize() function. */ + +/****************************************************************************/ +/* NAME: t_sva_error SVA_SetBufferData ( */ +/* t_sva_buffer_id bufferId, */ +/* t_uint32 BufferData) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine allowes to store specific application data in buffer */ +/* header */ +/* */ +/* PARAMETERS: */ +/* IN : - bufferId: identifier of the buffer */ +/* - BufferData: application data to store in buffer */ +/* */ +/* OUT: none */ +/* */ +/* RETURN: */ +/* t_sva_error : SVA_OK */ +/* SVA_BM_UNKNOWN_BUFFER_ID */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_sva_error SVA_SetBufferData(t_sva_buffer_id bufferId, + t_uint32 BufferData) +{ + t_sva_bm_buffer_desc *pBufferDesc; + + CHECK_BUFFER_ID(bufferId); /* Will return SVA_BM_UNKNOWN_BUFFER_ID if required. */ + + pBufferDesc = (t_sva_bm_buffer_desc *)(bufferId); + + pBufferDesc->extraData = BufferData; + + return(SVA_OK); +} /* End of SVA_SetBufferData() function. */ + + + +/****************************************************************************/ +/* NAME: t_sva_error SVA_GetBufferData ( */ +/* t_sva_buffer_id bufferId, */ +/* t_uint32 *pBufferData) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine allowes to restore specific application data in buffer */ +/* header */ +/* */ +/* PARAMETERS: */ +/* IN : - bufferId: identifier of the buffer */ +/* */ +/* OUT: - pBufferData: application data to store in buffer */ +/* */ +/* RETURN: */ +/* t_sva_error : SVA_OK */ +/* SVA_BM_UNKNOWN_BUFFER_ID */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_sva_error SVA_GetBufferData(t_sva_buffer_id bufferId, + t_uint32 *pBufferData) +{ + t_sva_bm_buffer_desc *pBufferDesc; + + HCL_ASSERT(pBufferData!=NULL); + + CHECK_BUFFER_ID(bufferId); /* Will return SVA_BM_UNKNOWN_BUFFER_ID if required. */ + + pBufferDesc = (t_sva_bm_buffer_desc *)(bufferId); + + *pBufferData = pBufferDesc->extraData; + return(SVA_OK); +} /* End of SVA_GetBufferData() function. */ + +/****************************************************************************/ +/* NAME: t_sva_bm_error sva_BM_GetBufferLinkInformation ( */ +/* t_sva_buffer_id bufferId, */ +/* t_sva_bitstream_buf_link bitstreamBufferLink, */ +/* t_physical_address *pLinkPhysicalAddress) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine allowes to get bitstream buffer informations */ +/* header */ +/* */ +/* PARAMETERS: */ +/* IN : - bufferId: identifier of the buffer */ +/* */ +/* OUT: - pBitstreamBufferLink: link informations pointer */ +/* - pLinkPhysicalAddress: physical address pointer. This address takes*/ +/* into accoun tthe EXT bit to set if the buffer is localized in */ +/* external memory. */ +/* */ +/* RETURN: */ +/* t_sva_error : SVA_BM_OK */ +/* SVA_BM_ERROR */ +/* SVA_BM_UNKNOWN_BUFFER_ID */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_sva_bm_error sva_BM_GetBufferLinkInformation( t_sva_buffer_id bufferId, + t_sva_bm_list_elem **pBitstreamBufferLink, + t_physical_address *pLinkPhysicalAddress) +{ + t_sva_bm_buffer_desc *pBufferDesc; + t_sva_memory_id memoryId; + t_sva_mm_error mmErrorCode; + + HCL_ASSERT((pBitstreamBufferLink!=NULL)&&(pLinkPhysicalAddress!=NULL)); + + BM_CHECK_BUFFER_ID(bufferId); /* Will return SVA_BM_UNKNOWN_BUFFER_ID if required. */ + + pBufferDesc = (t_sva_bm_buffer_desc *)(bufferId); + + *pBitstreamBufferLink = (t_sva_bm_list_elem *)(bufferId); + + /* Management of EXT bit, even for V0.96 that needs it (There's a bug in */ + /* HAMAC video specification documentation. */ + + /* Get memory Id of header data field. */ + mmErrorCode = sva_MM_GetBlockMemoryId(pBufferDesc->headerBufferBlockId, &memoryId); + if (mmErrorCode != SVA_MM_OK) {return(SVA_BM_ERROR);} + + if (memoryId == SDRAM_ID) + *pLinkPhysicalAddress = pBufferDesc->headerBufferSystemAddress.physical + BLM_EXTERNAL_MEM_EXT_BIT; + else + *pLinkPhysicalAddress = pBufferDesc->headerBufferSystemAddress.physical; + + return(SVA_BM_OK); +} /* End of sva_BM_GetBufferLinkInformation() function. */ + +/****************************************************************************/ +/* NAME: t_sva_bm_error sva_BM_SetBufferLinkInformation ( */ +/* t_sva_buffer_id bufferId, */ +/* t_sva_bitstream_buf_link bitstreamBufferLink) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine allowes to set bitstream buffer informations */ +/* header */ +/* */ +/* PARAMETERS: */ +/* IN : - bufferId: identifier of the buffer */ +/* - pBitstreamBufferLink: link informations ponter */ +/* */ +/* OUT: - none */ +/* */ +/* RETURN: */ +/* t_sva_error : SVA_OK */ +/* SVA_BM_UNKNOWN_BUFFER_ID */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_sva_bm_error sva_BM_SetBufferLinkInformation( t_sva_buffer_id bufferId, + t_sva_bm_list_elem * pBitstreamBufferLink, t_uint32 index) +{ + t_sva_bm_buffer_desc *pBufferDesc; + + HCL_ASSERT (pBitstreamBufferLink!=NULL); + + BM_CHECK_BUFFER_ID(bufferId); /* Will return SVA_BM_UNKNOWN_BUFFER_ID if required. */ + + pBufferDesc = (t_sva_bm_buffer_desc *)(bufferId); + + pBufferDesc->bufferListInfo[index]= *pBitstreamBufferLink; + + return(SVA_BM_OK); +} /* End of sva_BM_SetBuferLinkInformation() function. */ + +/* End of file - sva_buffermgt.c */ --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/memory_management/sva_buffermgt.h @@ -0,0 +1,111 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ + +#ifndef __INC_SVA_BM_H +#define __INC_SVA_BM_H + +#include "hcl_defs.h" +#include "sva.h" +#include "svap.h" +#include "sva_memorymgt.h" +#include "sva_timemgt.h" +#include "sva_host_interface.h" +#include "sva_bufferlistmgtp.h" + + +/******************************************************************************/ +/* Constants definitions */ +/******************************************************************************/ + +/* + * Define the special invalid value for t_sva_buffer_id variables + */ +#define INVALID_BUFFER_ID MASK_ALL32 + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/******************************************************************************/ +/* Types definitions */ +/******************************************************************************/ +/* + * Definition of symbol used by Buffer Management routines to return error + */ +typedef enum { + SVA_BM_ERROR = SVA_BM_LAST_ERROR, + SVA_BM_UNKNOWN_BUFFER_ID, + SVA_BM_OK = SVA_OK +} t_sva_bm_error; + +/* + * Definition of structure inside buffer header that manages the buffer link list. + * These data are mainly initialized/used by buffer list mgt block. + */ + +/* IMPORTANT : folowing struture must match an 8-words boundary */ +typedef struct +{ + t_sva_bitstream_buf_link bufferLink; // structure containing bitstream buffer link informations + /* WARNING : Keep this field at first position, otherwise buffer-list management won't work anymore !! */ + + t_sva_buffer_id nextBufferId; // next buffer Id in the list + t_sva_buffer_id prevBufferId; // previous buffer Id in the list + + t_uint32 bufferListId; + t_uint32 index; // align structure size to 16 bytes boundaries +} t_sva_bm_list_elem; // sizeof(t_sva_bm_list_elem) = 8 words + +typedef t_sva_bm_list_elem t_sva_bm_list_info[NB_MAX_MANAGED_BUFFER_LIST]; + + + +/******************************************************************************* +* PUBLIC Functions +*******************************************************************************/ +PUBLIC t_sva_bm_error sva_BM_Init(void); +/* Buffers Management (Memory point of view) */ +/* Implemented here but prototyped into sva.h */ +/* PUBLIC t_sva_error SVA_DefineBuffer(t_sva_buffer_type, t_size, t_system_address, t_sva_buffer_id *); */ +/* PUBLIC t_sva_error SVA_RemoveBuffer(t_sva_buffer_id ); */ +/* PUBLIC t_sva_error SVA_AllocBuffer(t_sva_buffer_type, t_size, t_system_address *, t_sva_buffer_id *); */ +/* PUBLIC t_sva_error SVA_FreeBuffer(t_sva_buffer_id ); */ +PUBLIC t_sva_bm_error sva_BM_GetStatus(t_uint32 *); + +/* Buffers Management Information routines */ +/* PUBLIC t_sva_error SVA_GetBufferStatus(t_sva_buffer_id, t_sva_buffer_status *); */ /* Implemented here but prototyped into sva.h */ +PUBLIC t_sva_bm_error sva_BM_UpdateBufferStatus(t_sva_buffer_id, t_sva_buffer_state, t_sva_ticks); +PUBLIC t_sva_bm_error sva_BM_GetBufferLogicalAddress(t_sva_buffer_id, t_logical_address*); +PUBLIC t_sva_bm_error sva_BM_GetBufferPhysicalAddress(t_sva_buffer_id, t_physical_address*); +PUBLIC t_sva_bm_error sva_BM_GetBufferSystemAddress(t_sva_buffer_id, t_system_address *); +PUBLIC t_sva_bm_error sva_BM_GetBufferType(t_sva_buffer_id, t_sva_buffer_type*); +PUBLIC t_sva_bm_error sva_BM_GetBufferSize(t_sva_buffer_id, t_size*); + +/* PUBLIC t_sva_error SVA_SetBufferData(t_sva_buffer_id, t_uint32); */ +/* PUBLIC t_sva_error SVA_GetBufferData(t_sva_buffer_id, t_uint32*); */ +PUBLIC t_sva_bm_error sva_BM_GetBufferLinkInformation( t_sva_buffer_id, t_sva_bm_list_elem **, t_physical_address *); +PUBLIC t_sva_bm_error sva_BM_SetBufferLinkInformation( t_sva_buffer_id, t_sva_bm_list_elem *, t_uint32); + + +#ifdef __cplusplus +} /* allow C++ to use these headers */ +#endif /* __cplusplus */ + +#endif /* __INC_SVA_BM_H */ +/* End of file - sva_bufferMgt.h */ --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/memory_management/sva_buffermgtp.h @@ -0,0 +1,83 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ + +#ifndef __INC_SVA_BM_P_H +#define __INC_SVA_BM_P_H + +#include "hcl_defs.h" +//#include "sva.h" +#include "sva_buffermgt.h" + +/******************************************************************************/ +/* Buffer Constants definitions */ +/******************************************************************************/ +/* + * Defines a "magic" number to check buffer ID integrity. + * NB : correspond to ASCII code "BM_1" +*/ +#define SVA_BM_MAGIC_NUMBER 0x424D5F31 + + +/* + * Defines the bit specifying the internal/external access. +*/ +#define BLM_INTERNAL_MEM_EXT_BIT 0 +#define BLM_EXTERNAL_MEM_EXT_BIT 1 + + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/******************************************************************************/ +/* Types definitions */ +/******************************************************************************/ +/* + * Define a type used to characterize to identify internally a bufferid + * type size SHALL be compliant with NB_MAX_MANAGED_BUFFER + */ +// To be removed ... +//typedef t_uint8 t_sva_bm_buffer_id; + +/* + * Define a type used to characterize a kind of memory (see t_sva_memory_id) + */ +typedef struct { + t_sva_bm_list_info bufferListInfo; /* Warning : Keep it in first position */ + + t_sva_buffer_status status; + t_uint32 extraData; + + t_sva_block_id bufferblockId; + t_system_address bufferSystemAddress; + t_size bufferSize; + + t_sva_block_id headerBufferBlockId; + t_system_address headerBufferSystemAddress; + + t_uint32 magicNumber; + +} t_sva_bm_buffer_desc; + +#ifdef __cplusplus +} /* allow C++ to use these headers */ +#endif /* __cplusplus */ + +#endif /* __INC_SVA_BM_P_H */ +/* End of file - sva_buffermgtp.h */ --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/memory_management/sva_memorymgt.c @@ -0,0 +1,1578 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ + +/*------------------------------------------------------------------------ + * Includes + *----------------------------------------------------------------------*/ +#include "hcl_defs.h" +#include "sva_memorymgt.h" +#include "sva_memorymgtp.h" +#include "sva_fwmgt.h" +#include "sva_fwmgtp.h" + + + +PRIVATE t_sva_dedicated_memory dedicatedMemoryMap; +PRIVATE t_sva_dedicated_memory_block initMemoryBlock; +PRIVATE t_sva_dedicated_memory_block initMemoryBlock_tmp; + +/*------------------------------------------------------------------------ + * Global Variables + *----------------------------------------------------------------------*/ +PRIVATE t_sva_mm_memory_desc memDesc[SDRAM_ID + NB_MAX_MANAGED_MEMORY_CHUNK]; +PRIVATE t_uint8 nbSDRAMChunks = 0; +PRIVATE t_sva_mm_small_block_id smallBlockIdArray[NB_MAX_MANAGED_SMALL_BLOCK]; + +/*------------------------------------------------------------------------ + * PRivate Macros + *----------------------------------------------------------------------*/ +#define SMALL_BLOCK_ID_2_INDEX(pBlockId) \ + (t_uint8)(((t_uint32)pBlockId - (t_uint32)smallBlockIdArray)/sizeof(t_sva_mm_small_block_id)) + +/*------------------------------------------------------------------------ + * PRIVATE Functions Prototypes + *----------------------------------------------------------------------*/ +PRIVATE t_sva_mm_error FindNotUsedSmallBlockId(t_uint8 *); +PRIVATE t_sva_mm_error AllocLargeBlock (t_uint32, t_sva_mm_alignment, t_sva_block_id *); +PRIVATE t_sva_mm_error AllocSmallBlock (t_sva_memory_id, t_size, t_sva_mm_alignment, t_sva_block_id *); +PRIVATE t_sva_mm_error FreeSmallBlock(t_sva_mm_small_block_id *); +PRIVATE t_sva_mm_error FreeLargeBlock(t_sva_mm_large_block_id *); +PRIVATE t_sva_mm_error sva_MM_ResetDedicatedMemory(void); +/****************************************************************************/ +/* NAME: t_sva_mm_error sva_MM_Init ( void ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine initialize the Memory Management module (internal */ +/* Private structure) */ +/* */ +/* PARAMETERS: */ +/* IN : none */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_mm_error */ +/* - SVA_MM_OK : init done correctly */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_sva_mm_error sva_MM_Init(void) +{ + t_uint32 ind; + nbSDRAMChunks = 0; + for (ind=0; ind < NB_MAX_MANAGED_SMALL_BLOCK; ind++) + { + smallBlockIdArray[ind].magic = SMALLBLOCK_MAGIC_NUMBER; + smallBlockIdArray[ind].size = 0; + smallBlockIdArray[ind].next = MASK_ALL8; + smallBlockIdArray[ind].previous = MASK_ALL8; + } + + return SVA_MM_OK; +} + +/****************************************************************************/ +/* NAME: t_sva_mm_error sva_MM_AddFreeBlock ( */ +/* t_sva_memory_id memoryId, */ +/* t_system_address bufferSystemAddr, */ +/* t_size bufferSize */ +/* ); */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine allows to add a new reserved block to the free list */ +/* This routine will be called at intialization step, in order to */ +/* provide the memory chunks for each kind of memory(XRAM,ESRAM,SDRAM)*/ +/* After this step, this routine has meaning only for SDRAM memory */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - memoryId: identifier of the memory (today only SDRAM_ID) */ +/* - bufferSystemAddr: system address of the new block */ +/* - bufferSize: size of the above buffer */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_mm_error */ +/* - SVA_MM_MAX_MEMORY_CHUNK_REACHED : return value when you add */ +/* more than NB_MAX_MANAGED_MEMORY_CHUNK of sdram block */ +/* - SVA_MM_SIZE_INCOMPATIBLE : return value when you add block for*/ +/* XRAM or ESRAM with a size >MASK_ALL16 */ +/* - SVA_MM_OUT_OF_MEMORY : return when not free small block */ +/* descriptor exist. This should not occured. */ +/* - SVA_MM_OK : add block done correctly */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_sva_mm_error sva_MM_AddFreeBlock( + t_sva_memory_id memoryId, + t_system_address bufferSystemAddr, + t_size bufferSize + ) +{ + if (bufferSize == 0) + return(SVA_MM_OK); + + /* Check if it is a new block of SDRAM memory (init, and new AddPrivateMemoryChunk()) */ + if (memoryId == SDRAM_ID) + { + if (nbSDRAMChunks >= NB_MAX_MANAGED_MEMORY_CHUNK) {return SVA_MM_MAX_MEMORY_CHUNK_REACHED;} + + memDesc[SDRAM_ID + nbSDRAMChunks].systemAddress = bufferSystemAddr; + memDesc[SDRAM_ID + nbSDRAMChunks].physicalEndAddr = bufferSystemAddr.physical + bufferSize - 1; + memDesc[SDRAM_ID + nbSDRAMChunks].logicalEndAddr = bufferSystemAddr.logical + bufferSize - 1; + memDesc[SDRAM_ID + nbSDRAMChunks].logicalToPhysicalOffset = bufferSystemAddr.logical - bufferSystemAddr.physical; + memDesc[SDRAM_ID + nbSDRAMChunks].allocatedMemorySize = 0; + + /* Check if we are at intialization stage */ + if (nbSDRAMChunks == 0) + { + t_sva_mm_large_block_id *pLargeBlockId; + pLargeBlockId = (t_sva_mm_large_block_id *)bufferSystemAddr.logical; + + memDesc[SDRAM_ID + nbSDRAMChunks].freeBlocksNum = 1; + memDesc[SDRAM_ID + nbSDRAMChunks].usedBlocksNum = 0; + + pLargeBlockId->physicalAddr = bufferSystemAddr.physical + sizeof(t_sva_mm_large_block_id); + pLargeBlockId->size = bufferSize - sizeof(t_sva_mm_large_block_id); + pLargeBlockId->next = (t_sva_mm_large_block_id *)0; + pLargeBlockId->previous = (t_sva_mm_large_block_id *)0; + + memDesc[SDRAM_ID + nbSDRAMChunks].firstFreeBlock = (void *)pLargeBlockId; + } + else + { + memDesc[SDRAM_ID + nbSDRAMChunks].freeBlocksNum = 0; + memDesc[SDRAM_ID + nbSDRAMChunks].usedBlocksNum = 0; + memDesc[SDRAM_ID + nbSDRAMChunks].firstFreeBlock = (void *)0; + /* + * Search the first block of the free list of the SDRAM memory manager + * whom the physical address is greater than the new block one + * else the last one + */ + { + t_sva_mm_large_block_id *pBlockId; + t_sva_mm_large_block_id *pLargeBlockId; + pLargeBlockId = (t_sva_mm_large_block_id *)bufferSystemAddr.logical; + + pBlockId = (t_sva_mm_large_block_id *)memDesc[SDRAM_ID].firstFreeBlock; + while(pBlockId->physicalAddr < bufferSystemAddr.physical && pBlockId->next != 0) {pBlockId = pBlockId->next;} + + pLargeBlockId->physicalAddr = bufferSystemAddr.physical + sizeof(t_sva_mm_large_block_id); + pLargeBlockId->size = bufferSize - sizeof(t_sva_mm_large_block_id); + if (pBlockId->physicalAddr < bufferSystemAddr.physical) + { + pLargeBlockId->next = (t_sva_mm_large_block_id *)0; + pLargeBlockId->previous = pBlockId; + pBlockId->next = pLargeBlockId; + } + else + { + pLargeBlockId->next = pBlockId; + pLargeBlockId->previous = pBlockId->previous; + if (pBlockId->previous != 0) {pBlockId->previous->next = pLargeBlockId;} + else {memDesc[SDRAM_ID].firstFreeBlock = (void *)pLargeBlockId;} + pBlockId->previous = pLargeBlockId; + } + } + memDesc[SDRAM_ID].freeBlocksNum++; + } + nbSDRAMChunks++; + } + else /* Initialisation of the XRAM and ESRAM memory (today use only at initialization stage) */ + { + if (bufferSize > 512*1024) {return SVA_MM_SIZE_INCOMPATIBLE;} + + memDesc[memoryId].systemAddress = bufferSystemAddr; + memDesc[memoryId].physicalEndAddr = bufferSystemAddr.physical + bufferSize - 1; + memDesc[memoryId].logicalEndAddr = bufferSystemAddr.logical + bufferSize - 1; + memDesc[memoryId].logicalToPhysicalOffset = bufferSystemAddr.logical - bufferSystemAddr.physical; + memDesc[memoryId].freeBlocksNum = 1; + memDesc[memoryId].usedBlocksNum = 0; + memDesc[memoryId].allocatedMemorySize = 0; + + /* Reset all remaining smallBlockId used for this kind of memory */ + { + t_uint8 i; + for (i=0; i < NB_MAX_MANAGED_SMALL_BLOCK; i++) + { + if (smallBlockIdArray[i].magic == (SMALLBLOCK_MAGIC_NUMBER | memoryId)) + { + smallBlockIdArray[i].size = 0; + } + } + } + + /* Search a free block id into the smallBlockIdArray */ + { + t_uint8 i; + if (FindNotUsedSmallBlockId(&i) != SVA_MM_OK) {return SVA_MM_OUT_OF_MEMORY;} + + smallBlockIdArray[i].magic = SMALLBLOCK_MAGIC_NUMBER | memoryId; + smallBlockIdArray[i].offset = 0; + smallBlockIdArray[i].size = bufferSize; + smallBlockIdArray[i].previous = MASK_ALL8; + smallBlockIdArray[i].next = MASK_ALL8; + + memDesc[memoryId].firstFreeBlock = (void *)&smallBlockIdArray[i]; + } + } + + return SVA_MM_OK; +} + +/****************************************************************************/ +/* NAME: t_sva_mm_error sva_MM_AllocBlock ( */ +/* t_sva_memory_id memoryId, */ +/* t_size size, */ +/* t_sva_mm_alignment alignment, */ +/* t_sva_block_id *pBlockId */ +/* ); */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine allocates a new block of a given memory with the */ +/* given alignment */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - memoryId: identifier of the memory to allocate */ +/* - size: size to allocate */ +/* - alignment: requested alignment */ +/* */ +/* OUT : none */ +/* - pBlockId: returned just allocated buffer identifier */ +/* */ +/* RETURN: */ +/* t_sva_mm_error */ +/* See AllocLargeBlock() and AllocSmallBlock() for error code */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_sva_mm_error sva_MM_AllocBlock +( + t_sva_memory_id memoryId, + t_size size, + t_sva_mm_alignment alignment, + t_sva_block_id *pBlockId + ) +{ + t_sva_mm_error status; + + /* Check size */ + if(size == 0) + { + *pBlockId = INVALID_SDRAM_BLOCK_ID; + return SVA_MM_SIZE_INCOMPATIBLE; + } + /* Check if we want to allocate some memory into system RAM */ + if (memoryId == SDRAM_ID) {status = AllocLargeBlock(size, alignment, pBlockId);} + else /* Small memories (XRAM, ESRAM) */ + { + status = AllocSmallBlock(memoryId, size, alignment, pBlockId); + } + + return status; +} + + + +/****************************************************************************/ +/* NAME: t_sva_mm_error sva_MM_AllocDedicatedBlock ( */ +/* t_sva_memory_id memoryId, */ +/* t_size size, */ +/* t_sva_mm_alignment alignment, */ +/* t_sva_block_id *pBlockId */ +/* ); */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine allocates a new block of a given memory with the */ +/* given alignment */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - memoryId: identifier of the memory to allocate */ +/* - size: size to allocate */ +/* - alignment: requested alignment */ +/* */ +/* OUT : none */ +/* - pBlockId: returned just allocated buffer identifier */ +/* */ +/* RETURN: */ +/* t_sva_mm_error */ +/* See AllocLargeBlock() and AllocSmallBlock() for error code */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_sva_mm_error sva_MM_AllocDedicatedBlock(t_size size, t_sva_mm_alignment alignment, t_sva_block_id * pBlockId) +{ + t_sva_dedicated_memory_block *freeBlock, *usedBlock; + t_sva_dedicated_memory_block *removedBlock; + t_sva_dedicated_memory_block * dedicatedMemoryNewBlock; + t_sva_block_id dedicatedMemoryNewBlockId; + t_system_address dedicatedMemoryNewBlockAddress; + t_sva_mm_error mmErrorCode = SVA_MM_OK; + t_uint16 offset; + t_size realAllocatedSize; + + + + freeBlock = dedicatedMemoryMap.firstFreeBlock; + usedBlock = dedicatedMemoryMap.firstUsedBlock; + // look for the first big enough block to fit the new buffer + /* + while((freeBlock->size < size) && (freeBlock->nextBlock != NULL)) freeBlock = freeBlock->nextBlock; + if ((freeBlock->size < size) && (freeBlock->nextBlock == NULL)) return SVA_OUT_OF_MEMORY; + */ + /* + * Search a free block with the right alignment + * and the right size + */ + + do + { + if ((freeBlock->address.physical & alignment) != 0) + { + offset = (t_uint16)(((t_uint32)alignment - (t_uint32)(freeBlock->address.physical & alignment)) + 1); + } + else {offset = 0;} + + realAllocatedSize = size + offset; + if (freeBlock->size < realAllocatedSize) + { + freeBlock = freeBlock->nextBlock; + if (freeBlock == NULL) break; + } + else {break;} + } while(freeBlock->nextBlock != NULL); + + + if (freeBlock == NULL) {return SVA_MM_OUT_OF_MEMORY;} + if ((freeBlock->size < realAllocatedSize) && (freeBlock->nextBlock == NULL)) {return SVA_MM_OUT_OF_MEMORY;} + + // allocate a "dedicated" header + mmErrorCode = sva_MM_AllocBlock(SDRAM_ID, sizeof(t_sva_dedicated_memory_block), SVA_MM_ALIGN_16BYTES, pBlockId); + if (mmErrorCode != SVA_MM_OK) return(mmErrorCode); + dedicatedMemoryNewBlockId = *pBlockId; + mmErrorCode = sva_MM_GetBlockSystemAddress(dedicatedMemoryNewBlockId, &dedicatedMemoryNewBlockAddress); + if (mmErrorCode != SVA_MM_OK) return(mmErrorCode); + dedicatedMemoryNewBlock = (t_sva_dedicated_memory_block *)dedicatedMemoryNewBlockAddress.logical; + + // append the new block at the end of the chain +//\/ dedicatedMemoryNewBlock->address.logical = freeBlock->address.logical; +//\/ dedicatedMemoryNewBlock->address.physical = freeBlock->address.physical; + dedicatedMemoryNewBlock->address.logical = freeBlock->address.logical+offset; + dedicatedMemoryNewBlock->address.physical = freeBlock->address.physical+offset; + dedicatedMemoryNewBlock->size = realAllocatedSize; + if (usedBlock==NULL) { // if there is no block allocated + dedicatedMemoryNewBlock->previousBlock = NULL; + dedicatedMemoryMap.firstUsedBlock = dedicatedMemoryNewBlock; + } else { // else, the new block is appened at the end of the chain list + while (usedBlock->nextBlock != NULL) usedBlock = usedBlock->nextBlock; + dedicatedMemoryNewBlock->previousBlock = usedBlock; + usedBlock->nextBlock = dedicatedMemoryNewBlock; + } + dedicatedMemoryNewBlock->nextBlock = NULL; + dedicatedMemoryMap.nbOfUseBlocks++; + + // update free block chain list + if (freeBlock->size == realAllocatedSize) { // if the new block's size matched a free block's size, the free block is picked off the list + removedBlock = freeBlock; + freeBlock = freeBlock->previousBlock; + if (freeBlock == NULL) { // if there is just one free block left .... + dedicatedMemoryMap.firstFreeBlock = removedBlock->nextBlock; // it goes to list's first spot + if (removedBlock->nextBlock != NULL) removedBlock->nextBlock->previousBlock = NULL; + } else { + freeBlock->nextBlock = removedBlock->nextBlock; + removedBlock = removedBlock->nextBlock; + removedBlock->previousBlock = freeBlock; + } + dedicatedMemoryMap.nbOfFreeBlocks--; + } else { // if the free block is bigger than needed, its size and start address get updated + freeBlock->address.logical = freeBlock->address.logical + realAllocatedSize; + freeBlock->address.physical = freeBlock->address.physical + realAllocatedSize; + freeBlock->size = freeBlock->size - realAllocatedSize; + } + + + return mmErrorCode; + +} + + +/****************************************************************************/ +/* NAME: t_sva_mm_error sva_MM_FreeBlock ( */ +/* t_sva_block_id blockId */ +/* ); */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine frees a previously allocated buffer. */ +/* So this one is added to the free list of the given memory */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - blockId: identifier of the block to free */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_mm_error */ +/* see FreeSmallBlock() and FreeLargeBlock() API for error code */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_sva_mm_error sva_MM_FreeBlock(t_sva_block_id blockId) +{ + t_sva_mm_error status; + t_sva_mm_small_block_id *pSBlock = (t_sva_mm_small_block_id *) blockId; + + HCL_DEBUG_ASSERT(pSBlock!=NULL); + + /* Check if it is small block identifier or not */ + if ((pSBlock->magic & ~SMALLBLOCK_MAGIC_NUM_MEMORY_ID_MASK) == SMALLBLOCK_MAGIC_NUMBER) + { + status = FreeSmallBlock((t_sva_mm_small_block_id *) blockId); + } + else {status = FreeLargeBlock((t_sva_mm_large_block_id *) blockId);} + + return status; +} + + + + +/****************************************************************************/ +/* NAME: t_sva_mm_error sva_MM_FreeDedicatedBlock ( */ +/* t_sva_block_id blockId */ +/* ); */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine frees a previously allocated buffer. */ +/* So this one is added to the free list of the given memory */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - blockId: identifier of the block to free */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_mm_error */ +/* see FreeSmallBlock() and FreeLargeBlock() API for error code */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_sva_mm_error sva_MM_FreeDedicatedBlock(t_sva_block_id blockId) +{ + + t_sva_mm_error mmErrorCode; + t_system_address dedicatedMemoryBlockAddress; + t_system_address blockStartAddress, blockEndAddress; + t_sva_dedicated_memory_block *prevDedicatedMemoryBlock, *dedicatedMemoryBlock, *nextDedicatedMemoryBlock; + t_sva_dedicated_memory_block *freeBlock; + t_sva_dedicated_memory_block *mergedBlock; + t_bool merged; + + mmErrorCode = sva_MM_GetBlockSystemAddress(blockId, &dedicatedMemoryBlockAddress); + if (mmErrorCode != SVA_MM_OK) return(mmErrorCode); + + + + dedicatedMemoryBlock = (t_sva_dedicated_memory_block *)dedicatedMemoryBlockAddress.logical; + + if (dedicatedMemoryMap.nbOfUseBlocks == 1) + dedicatedMemoryMap.firstUsedBlock = NULL; + else { + prevDedicatedMemoryBlock = dedicatedMemoryBlock->previousBlock; + nextDedicatedMemoryBlock = dedicatedMemoryBlock->nextBlock; + if (prevDedicatedMemoryBlock!=NULL) + prevDedicatedMemoryBlock->nextBlock = nextDedicatedMemoryBlock; + else + dedicatedMemoryMap.firstUsedBlock = nextDedicatedMemoryBlock; + if (nextDedicatedMemoryBlock!=NULL) nextDedicatedMemoryBlock->previousBlock = prevDedicatedMemoryBlock; + } + + dedicatedMemoryMap.nbOfUseBlocks--; + + // handle and defragment the free blocks chain + blockStartAddress = dedicatedMemoryBlock->address; + blockEndAddress.logical = blockStartAddress.logical + dedicatedMemoryBlock->size; + blockEndAddress.physical = blockStartAddress.physical + dedicatedMemoryBlock->size; + + // check is the released memory can be merged with an existing free block + merged = FALSE; + freeBlock = dedicatedMemoryMap.firstFreeBlock; + while (freeBlock != NULL) { + // if one or two block limit(s) match(es) a free block limit, expand the existing free block + if(freeBlock->address.logical == blockEndAddress.logical) { + if (merged == FALSE) { + freeBlock->address = blockStartAddress; + freeBlock->size = freeBlock->size + dedicatedMemoryBlock->size; + merged = TRUE; + } else { + mergedBlock = dedicatedMemoryMap.firstFreeBlock; + while ((mergedBlock->address.logical + mergedBlock->size) != blockEndAddress.logical) { + mergedBlock = mergedBlock->nextBlock; + if (mergedBlock == NULL) return SVA_MM_OUT_OF_MEMORY; // block to be merged not found + } + mergedBlock->size = mergedBlock->size + freeBlock->size; // resize the complete block + mergedBlock->nextBlock = freeBlock->nextBlock; // and remove "freeBlock" from the free block chain + if (freeBlock->nextBlock != NULL) freeBlock->nextBlock->previousBlock = mergedBlock; + dedicatedMemoryMap.nbOfFreeBlocks--; + } + } else { + if((freeBlock->address.logical + freeBlock->size) == blockStartAddress.logical) { + if (merged == FALSE) { + freeBlock->size = freeBlock->size + dedicatedMemoryBlock->size; + merged = TRUE; + } else { + mergedBlock = dedicatedMemoryMap.firstFreeBlock; + while (mergedBlock->address.logical != blockStartAddress.logical) { + mergedBlock = mergedBlock->nextBlock; + if (mergedBlock == NULL) return SVA_MM_OUT_OF_MEMORY; // block to be merged not found + } + mergedBlock->address = freeBlock->address; // update beginning address of the merged area + mergedBlock->size = mergedBlock->size + freeBlock->size; // resize the complete block + mergedBlock->previousBlock = freeBlock->previousBlock; + if (freeBlock->previousBlock != NULL) + freeBlock->previousBlock->nextBlock = mergedBlock; + else // if previous is NULL, it means mergedBlock takes the first spot in the free list + dedicatedMemoryMap.firstFreeBlock = mergedBlock; + dedicatedMemoryMap.nbOfFreeBlocks--; + } + } + } + + freeBlock = freeBlock->nextBlock; + + } + + if (merged == FALSE) { // no block merged performed ? + // move the block from the used list back to the free list (1st position in the list) + dedicatedMemoryBlock->nextBlock = dedicatedMemoryMap.firstFreeBlock; + dedicatedMemoryMap.firstFreeBlock->previousBlock = dedicatedMemoryBlock; + dedicatedMemoryMap.firstFreeBlock = dedicatedMemoryBlock; + dedicatedMemoryBlock->previousBlock = NULL; + dedicatedMemoryMap.nbOfFreeBlocks++; + } + else + { + mmErrorCode = sva_MM_FreeBlock(blockId); + if (mmErrorCode != SVA_MM_OK) return(mmErrorCode); + } + + if(dedicatedMemoryMap.nbOfUseBlocks == 0) + sva_MM_ResetDedicatedMemory(); + + return SVA_MM_OK; +} + +/****************************************************************************/ +/* NAME: t_sva_mm_error sva_MM_GetBlockSystemAddress ( */ +/* t_sva_block_id blockId, */ +/* t_system_address *pSystemAddr */ +/* ); */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine allows to get the system address of the first byte */ +/* of a given block */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - blockId: identifier of the block */ +/* */ +/* OUT : */ +/* - pSystemAddr: system address of the given block */ +/* */ +/* RETURN: */ +/* t_sva_mm_error */ +/* - SVA_MM_UNKNOWN_BLOCKID : return value when we can't find */ +/* blockId provide by user. */ +/* - SVA_MM_OK : ok */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_sva_mm_error sva_MM_GetBlockSystemAddress +( + t_sva_block_id blockId, + t_system_address *pSystemAddr + ) +{ + t_sva_mm_small_block_id *pSBlock = (t_sva_mm_small_block_id *) blockId; + + HCL_DEBUG_ASSERT(pSystemAddr!=NULL); + HCL_DEBUG_ASSERT(pSBlock!=NULL); + + /* Check if it is small block identifier or not */ + if ((pSBlock->magic & ~SMALLBLOCK_MAGIC_NUM_MEMORY_ID_MASK) == SMALLBLOCK_MAGIC_NUMBER) + { + t_sva_memory_id memoryId = (t_sva_memory_id)(pSBlock->magic & SMALLBLOCK_MAGIC_NUM_MEMORY_ID_MASK); + if (pSBlock->size == 0) {return SVA_MM_UNKNOWN_BLOCKID;} + pSystemAddr->physical = memDesc[memoryId].systemAddress.physical + pSBlock->offset; + pSystemAddr->logical = memDesc[memoryId].systemAddress.logical + pSBlock->offset; + } + else + { + t_sva_mm_large_block_id *pLBlock = (t_sva_mm_large_block_id *) blockId; + if ((t_uint32)pLBlock->next != MASK_ALL32) {return SVA_MM_UNKNOWN_BLOCKID;} + pSystemAddr->physical = pLBlock->physicalAddr + (t_physical_address)pLBlock->previous; + pSystemAddr->logical = (t_logical_address)pLBlock + sizeof(t_sva_mm_large_block_id) + (t_physical_address)pLBlock->previous; + } + + return SVA_MM_OK; +} + + +PUBLIC t_sva_mm_error sva_MM_GetDedicatedBlockSystemAddress( + t_sva_block_id blockId, + t_system_address *pSystemAddr +) +{ + t_system_address systemAddr; + t_sva_dedicated_memory_block * pDedicatedBlock; + + sva_MM_GetBlockSystemAddress(blockId,&systemAddr); + pDedicatedBlock = (t_sva_dedicated_memory_block *)systemAddr.logical; + pSystemAddr->logical = pDedicatedBlock->address.logical; + pSystemAddr->physical = pDedicatedBlock->address.physical; + return SVA_MM_OK; +} + + +/****************************************************************************/ +/* NAME: t_sva_mm_error sva_MM_GetBlockLogicalAddress ( */ +/* t_sva_block_id blockId */ +/* t_logical_address *pBlockLogicalAddress */ +/* ); */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine returns the logical address of the first byte */ +/* of a given memory block. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - blockId: identifier of the memory block */ +/* */ +/* OUT : */ +/* - pBlockLogicalAddress : logical address of blockId. */ +/* */ +/* RETURN: */ +/* t_sva_mm_error */ +/* - SVA_MM_UNKNOWN_BLOCKID : blockId is unknown. */ +/* - SVA_MM_OK : pBlockLogicalAddress contain blockId logical */ +/* address. */ +/* */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_sva_mm_error sva_MM_GetBlockLogicalAddress( + t_sva_block_id blockId, + t_logical_address *pBlockLogicalAddress +) +{ + t_logical_address logicalAddr; + t_sva_mm_small_block_id *pSBlock; + + HCL_DEBUG_ASSERT(pBlockLogicalAddress != NULL); + HCL_DEBUG_ASSERT(blockId != 0); + pSBlock = (t_sva_mm_small_block_id *) blockId; + + /* Check if it is small block identifier or not */ + if ((pSBlock->magic & ~SMALLBLOCK_MAGIC_NUM_MEMORY_ID_MASK) == SMALLBLOCK_MAGIC_NUMBER) + { + t_sva_memory_id memoryId = (t_sva_memory_id)(pSBlock->magic & SMALLBLOCK_MAGIC_NUM_MEMORY_ID_MASK); + if (pSBlock->size == 0) {return SVA_MM_UNKNOWN_BLOCKID;} + + logicalAddr = memDesc[memoryId].systemAddress.logical + pSBlock->offset; + } + else + { + t_sva_mm_large_block_id *pLBlock = (t_sva_mm_large_block_id *) blockId; + if ((t_uint32)pLBlock->next != MASK_ALL32) {return SVA_MM_UNKNOWN_BLOCKID;} + + logicalAddr = (t_logical_address)pLBlock + sizeof(t_sva_mm_large_block_id) + (t_physical_address)pLBlock->previous; + } + + *pBlockLogicalAddress=logicalAddr; + + return SVA_MM_OK; +} + + +/****************************************************************************/ +/* NAME: t_sva_mm_error sva_MM_GetBlockPhysicalAddress ( */ +/* t_sva_block_id blockId, */ +/* t_physical_address *pBlockPhysicalAddress */ +/* ); */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine returns the physical address of the first byte */ +/* of a given memory block. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - blockId: identifier of the memory block */ +/* */ +/* OUT : */ +/* - pBlockPhysicalAddress : physical address of blockId. */ +/* */ +/* RETURN: */ +/* t_sva_mm_error */ +/* - SVA_MM_UNKNOWN_BLOCKID : blockId is unknown. */ +/* - SVA_MM_OK : pBlockLogicalAddress contain blockId physical */ +/* address. */ +/* */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_sva_mm_error sva_MM_GetBlockPhysicalAddress( + t_sva_block_id blockId, + t_physical_address *pBlockPhysicalAddress +) +{ + t_physical_address physicalAddr; + t_sva_mm_small_block_id *pSBlock; + + HCL_DEBUG_ASSERT(pBlockPhysicalAddress!=NULL); + HCL_DEBUG_ASSERT(blockId != 0); + pSBlock = (t_sva_mm_small_block_id *) blockId; + + /* Check if it is small block identifier or not */ + if ((pSBlock->magic & ~SMALLBLOCK_MAGIC_NUM_MEMORY_ID_MASK) == SMALLBLOCK_MAGIC_NUMBER) + { + t_sva_memory_id memoryId = (t_sva_memory_id)(pSBlock->magic & SMALLBLOCK_MAGIC_NUM_MEMORY_ID_MASK); + if (pSBlock->size == 0) {return SVA_MM_UNKNOWN_BLOCKID;} + + physicalAddr = memDesc[memoryId].systemAddress.physical + pSBlock->offset; + } + else + { + t_sva_mm_large_block_id *pLBlock = (t_sva_mm_large_block_id *) blockId; + if ((t_uint32)pLBlock->next != MASK_ALL32) {return SVA_MM_UNKNOWN_BLOCKID;} + physicalAddr = pLBlock->physicalAddr + (t_physical_address)pLBlock->previous; + } + + *pBlockPhysicalAddress=physicalAddr; + + return SVA_MM_OK; +} + + +/****************************************************************************/ +/* NAME: t_sva_mm_error sva_MM_GetBlockMemoryId ( */ +/* t_sva_block_id blockId, */ +/* t_sva_memory_id *pBlockMemoryId */ +/* ); */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine returns the memory Id of the given memory block */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - blockId: identifier of the memory block */ +/* */ +/* OUT : */ +/* - pBlockMemoryId : memory Id of blockId. */ +/* */ +/* RETURN: */ +/* t_sva_mm_error */ +/* - SVA_MM_UNKNOWN_BLOCKID : blockId is unknown. */ +/* - SVA_MM_OK : pBlockLogicalAddress contain blockId physical */ +/* address. */ +/* */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_sva_mm_error sva_MM_GetBlockMemoryId( + t_sva_block_id blockId, + t_sva_memory_id *pBlockMemoryId +) +{ + t_sva_memory_id memoryId; + t_sva_mm_small_block_id *pSBlock; + + HCL_DEBUG_ASSERT(pBlockMemoryId!=NULL); + HCL_DEBUG_ASSERT(blockId != 0); + pSBlock = (t_sva_mm_small_block_id *) blockId; + + /* Check if it is small block identifier or not */ + if ((pSBlock->magic & ~SMALLBLOCK_MAGIC_NUM_MEMORY_ID_MASK) == SMALLBLOCK_MAGIC_NUMBER) + { + if (pSBlock->size == 0) {return SVA_MM_UNKNOWN_BLOCKID; } + + memoryId = (t_sva_memory_id)(pSBlock->magic & SMALLBLOCK_MAGIC_NUM_MEMORY_ID_MASK); + } + else {memoryId = SDRAM_ID;} + + *pBlockMemoryId=memoryId; + + return SVA_MM_OK; +} + +/****************************************************************************/ +/* NAME: t_sva_mm_error sva_MM_PhysicalToLogicalAddress ( */ +/* t_physical_address physicalAddress, */ +/* t_logical_address *pLogicalAddress */ +/* ); */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine converts a physical address to the logical one */ +/* If the routine is unable to provide the mapping, an assertion */ +/* will occured. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - physicalAddress: physical address to convert */ +/* */ +/* OUT : */ +/* - pLogicalAddress: Corresponding logical address */ +/* */ +/* RETURN: */ +/* t_sva_mm_error */ +/* - SVA_MM_OK */ +/* */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_sva_mm_error sva_MM_PhysicalToLogicalAddress +( + t_physical_address physicalAddress, + t_logical_address *pLogicalAddress +) +{ + t_logical_address logicalAddr; + t_uint8 ind; + + HCL_DEBUG_ASSERT(pLogicalAddress!=NULL); + for(ind = XRAM_ID; ind < SDRAM_ID+nbSDRAMChunks; ind++) + { + if ((physicalAddress >= memDesc[ind].systemAddress.physical) && (physicalAddress <= memDesc[ind].physicalEndAddr)) {break;} + } + + HCL_ASSERT(ind < (SDRAM_ID+nbSDRAMChunks)); + + logicalAddr = physicalAddress + memDesc[ind].logicalToPhysicalOffset; + + *pLogicalAddress=logicalAddr; + + return SVA_MM_OK; +} + + +/****************************************************************************/ +/* NAME: t_sva_mm_error sva_MM_GetStatus ( */ +/* t_sva_memory_id memoryId, */ +/* t_sva_mm_status *pStatus */ +/* ); */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine provides the current state of the memory management */ +/* of a given memory type */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - memoryId: memory type identifier */ +/* */ +/* OUT : */ +/* - pStatus: current status */ +/* */ +/* RETURN: */ +/* t_sva_mm_error */ +/* - SVA_MM_OK : always successfull */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_sva_mm_error sva_MM_GetStatus +( + t_sva_memory_id memoryId, + t_sva_mm_status *pStatus + ) +{ + HCL_DEBUG_ASSERT(pStatus!=NULL); + + pStatus->numUsedBlocks = memDesc[memoryId].usedBlocksNum; + pStatus->numFreeBlocks = memDesc[memoryId].freeBlocksNum; + pStatus->overallUsedBlocksSize = memDesc[memoryId].allocatedMemorySize; + + pStatus->freeBlockMinSize = MASK_ALL32; + pStatus->freeBlockMaxSize = 0; + pStatus->overallFreeBlocksSize = 0; + + if (memoryId == SDRAM_ID) + { + t_sva_mm_large_block_id *pBlock = (t_sva_mm_large_block_id *)memDesc[SDRAM_ID].firstFreeBlock; + while ( pBlock!= 0 ) + { + if (pStatus->freeBlockMinSize > pBlock->size) {pStatus->freeBlockMinSize = pBlock->size;} + + if (pStatus->freeBlockMaxSize < pBlock->size) {pStatus->freeBlockMaxSize = pBlock->size;} + + /* + * Accumulate all free blocks (take into account the memory management descriptor) + */ + pStatus->overallFreeBlocksSize += (pBlock->size - sizeof(t_sva_mm_large_block_id)); + + pBlock = pBlock->next; + } + /* + * Take into account the memory management descriptor size) + */ + pStatus->freeBlockMinSize -= sizeof(t_sva_mm_large_block_id); + pStatus->freeBlockMaxSize -= sizeof(t_sva_mm_large_block_id); + } + else /* memoryId = XRAM_ID or ESRAM_ID */ + { + t_sva_mm_small_block_id *pBlock = (t_sva_mm_small_block_id *)memDesc[memoryId].firstFreeBlock; + + while(pBlock != 0) + { + if (pStatus->freeBlockMinSize > pBlock->size) {pStatus->freeBlockMinSize = pBlock->size;} + + if (pStatus->freeBlockMaxSize < pBlock->size) {pStatus->freeBlockMaxSize = pBlock->size;} + + pStatus->overallFreeBlocksSize += pBlock->size; + + if (pBlock->next != MASK_ALL8) {pBlock = &smallBlockIdArray[pBlock->next];} + else {pBlock = 0;} + } + } + + return SVA_MM_OK; +} + +/****************************************************************************/ +/* NAME: t_sva_mm_error FindNotUsedSmallBlockId ( */ +/* t_uint8 *pIndex */ +/* ); */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine finds a not used entry into the smallBlockIdArray */ +/* */ +/* PARAMETERS: */ +/* IN : none */ +/* */ +/* OUT : */ +/* - pIndex: found not used entry index */ +/* */ +/* RETURN: */ +/* t_sva_mm_error */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PRIVATE t_sva_mm_error FindNotUsedSmallBlockId(t_uint8 *pIndex) +{ + t_uint8 i = 0; + + HCL_DEBUG_ASSERT(pIndex!=NULL); + + while (i < NB_MAX_MANAGED_SMALL_BLOCK && smallBlockIdArray[i].size != 0) {i++;} + + if (i==NB_MAX_MANAGED_SMALL_BLOCK) {return SVA_MM_MAX_SMALLBLOCK_REACHED;} + + *pIndex = i; + return SVA_MM_OK; +} + +/****************************************************************************/ +/* NAME: t_svz_mm_error AllocLargeBlock ( */ +/* t_size size, */ +/* t_sva_mm_alignment alignment, */ +/* t_sva_block_id *pBlockId */ +/* ); */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine allocates a new block of a given memory with the */ +/* given alignment */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - size: size to allocate */ +/* - alignment: requested alignment */ +/* */ +/* OUT : none */ +/* - pBlockId: returned just allocated buffer identifier */ +/* */ +/* RETURN: */ +/* t_sva_mm_error */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PRIVATE t_sva_mm_error AllocLargeBlock +( + t_uint32 size, + t_sva_mm_alignment alignment, + t_sva_block_id *pBlockId + ) +{ + t_sva_mm_large_block_id *pBlock = (t_sva_mm_large_block_id *)memDesc[SDRAM_ID].firstFreeBlock; + t_uint32 realAllocatedSize; + t_uint16 offset = 0; + + HCL_DEBUG_ASSERT(pBlockId!=NULL); + + if (pBlock == 0) {return SVA_MM_OUT_OF_MEMORY;} + + /* + * Search a free block with the right alignment + * and the right size + */ + do + { + if ((pBlock->physicalAddr & alignment) != 0) + { + offset = (t_uint16)(((t_uint32)alignment - (t_uint32)(pBlock->physicalAddr & alignment)) + 1); + } + else {offset = 0;} + + realAllocatedSize = size + offset; + if (pBlock->size < realAllocatedSize) {pBlock = pBlock->next;} + else {break;} + } while(pBlock != 0); + + /* Check if we have found a block with the correct size */ + if (pBlock == 0) {return SVA_MM_OUT_OF_MEMORY;} + + memDesc[SDRAM_ID].usedBlocksNum++; + + /* + * Check if the alignment offset is greater than the threshold + * in order to create a new free block or not + */ + if (offset >= (LARGE_BLOCK_DISCARD_THRESHOLD + sizeof(t_sva_mm_large_block_id))) + { + t_sva_mm_large_block_id *pNewFreeBlock; + pNewFreeBlock = (t_sva_mm_large_block_id*)((t_uint32)pBlock + offset); + pNewFreeBlock->physicalAddr = pBlock->physicalAddr + offset; + pNewFreeBlock->size = pBlock->size - offset; + pNewFreeBlock->previous = pBlock; + pNewFreeBlock->next = pBlock->next; + if (pBlock->next != 0) {pBlock->next->previous = pNewFreeBlock;} + + /* pBlock point on the new free block */ + pBlock->size = ((t_uint32)offset - sizeof(t_sva_mm_large_block_id)); + pBlock->next = pNewFreeBlock; + + memDesc[SDRAM_ID].freeBlocksNum++; + realAllocatedSize = size; + offset = 0; + pBlock = pNewFreeBlock; + } + + /* Remove the new allocated buffer from the free list */ + { + t_sva_mm_large_block_id *pNewFreeBlock; + if ((pBlock->size - realAllocatedSize) < (LARGE_BLOCK_DISCARD_THRESHOLD + sizeof(t_sva_mm_large_block_id))) + { + realAllocatedSize = pBlock->size; + if (pBlock->previous != 0) {pBlock->previous->next = pBlock->next;} + else {memDesc[SDRAM_ID].firstFreeBlock = (void *)pBlock->next;} + + if (pBlock->next != 0) {pBlock->next->previous = pBlock->previous;} + memDesc[SDRAM_ID].freeBlocksNum--; + } + else + { + /* Align the realAllocatedSize on word boundary */ + realAllocatedSize += (realAllocatedSize % 4)?(4-(realAllocatedSize % 4)):0; + pNewFreeBlock = (t_sva_mm_large_block_id*)((t_uint32)pBlock + sizeof(t_sva_mm_large_block_id) + realAllocatedSize); + + pNewFreeBlock->physicalAddr = pBlock->physicalAddr + realAllocatedSize + sizeof(t_sva_mm_large_block_id); + pNewFreeBlock->size = pBlock->size - (realAllocatedSize + sizeof(t_sva_mm_large_block_id)); + pNewFreeBlock->previous = pBlock->previous; + pNewFreeBlock->next = pBlock->next; + if (pBlock->previous != 0) {pBlock->previous->next = pNewFreeBlock;} + else {memDesc[SDRAM_ID].firstFreeBlock = (void *)pNewFreeBlock;} + + if (pBlock->next != 0) {pBlock->next->previous = pNewFreeBlock;} + } + } + + /* Build the blockId descriptor */ + pBlock->physicalAddr = pBlock->physicalAddr; + pBlock->size = realAllocatedSize; + /* In case of allocated block then the previous field if used to save the alignment offset */ + pBlock->previous = (t_sva_mm_large_block_id *)((t_uint32)offset); + pBlock->next = (t_sva_mm_large_block_id *)MASK_ALL32; + + + memDesc[SDRAM_ID].allocatedMemorySize += realAllocatedSize; + + /* Update out parameter */ + *pBlockId = (t_sva_block_id)pBlock; + + return SVA_MM_OK; +} + + + +/****************************************************************************/ +/* NAME: t_hv_mm_error AllocSmallBlock ( */ +/* t_sva_memory_id memoryId, */ +/* t_size size, */ +/* t_sva_mm_alignment alignment, */ +/* t_sva_block_id *pBlockId */ +/* ); */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine allocates a new block of a given memory with the */ +/* given alignment */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - memoryId: identifier of the memory to allocate */ +/* - size: size to allocate */ +/* - alignment: requested alignment */ +/* */ +/* OUT : none */ +/* - pBlockId: returned just allocated buffer identifier */ +/* */ +/* RETURN: */ +/* t_sva_mm_error */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PRIVATE t_sva_mm_error AllocSmallBlock +( + t_sva_memory_id memoryId, + t_size size, + t_sva_mm_alignment alignment, + t_sva_block_id *pBlockId + ) +{ + t_sva_mm_small_block_id *pBlock = (t_sva_mm_small_block_id *)memDesc[memoryId].firstFreeBlock; + t_uint32 realAllocatedSize; + t_uint32 alignmentOffset = 0; + + HCL_DEBUG_ASSERT(pBlockId!=NULL); + + if (pBlock == 0) {return SVA_MM_OUT_OF_MEMORY;} + + + + /* + * Search a free block with the good alignment + * and the good size + */ + do + { + if ((pBlock->offset & alignment) != 0) + { + alignmentOffset = (t_uint32)((alignment+1) - (pBlock->offset & alignment)); + } + else {alignmentOffset = 0;} + + realAllocatedSize = (t_uint32)(size + alignmentOffset); + if (pBlock->size < realAllocatedSize) + { + if (pBlock->next !=MASK_ALL8) {pBlock = &smallBlockIdArray[pBlock->next];} + else {pBlock = 0;} + } + else {break;} + } while(pBlock !=0); + + /* Check if we have found a block with the correct size */ + if (pBlock == 0) {return SVA_MM_OUT_OF_MEMORY;} + + memDesc[memoryId].usedBlocksNum++; + + /* check if the found block has 'directly' the correct size and alignment */ + if (pBlock->size == size) + { + /* Remove the block from the free list */ + if (pBlock->previous != MASK_ALL8) {smallBlockIdArray[pBlock->previous].next = pBlock->next;} + else {memDesc[memoryId].firstFreeBlock = (void *)&smallBlockIdArray[pBlock->next];} + + if (pBlock->next != MASK_ALL8) {smallBlockIdArray[pBlock->next].previous = pBlock->previous;} + + memDesc[memoryId].freeBlocksNum--; + } + else // allocated block is either equal to realAllocatedSize so we shall create a new block with the remaining bytes + // or has a greater size than the requested one + { + t_sva_mm_error status; + t_uint8 i = 0; // fake initialization to avoid pclint fake warnings + t_bool isNewBlockAllocated =FALSE; + + if (pBlock->size != realAllocatedSize) + { + status = FindNotUsedSmallBlockId(&i); + if (status != SVA_MM_OK) {return status;} + + smallBlockIdArray[i].magic = SMALLBLOCK_MAGIC_NUMBER | memoryId; + smallBlockIdArray[i].offset = (t_uint32)(pBlock->offset + realAllocatedSize); + smallBlockIdArray[i].size = (t_uint32)(pBlock->size-realAllocatedSize); + smallBlockIdArray[i].previous = pBlock->previous; + smallBlockIdArray[i].next = pBlock->next; + isNewBlockAllocated = TRUE; + } + + /* + * Check if the found block has not the good alignment + * then cut the free block into two free blocks + * (one before (size = alignment offset) and one after (size = remaining bytes)) + */ + if ((pBlock->offset & alignment) != 0) + { + t_uint8 ind; + /* Create the first free block */ + status = FindNotUsedSmallBlockId(&ind); + memDesc[memoryId].freeBlocksNum++; + if (status != SVA_MM_OK) {return status;} + + smallBlockIdArray[ind].magic = SMALLBLOCK_MAGIC_NUMBER | memoryId; + smallBlockIdArray[ind].offset = pBlock->offset; + smallBlockIdArray[ind].size = alignmentOffset; + + /* Check if remaining byte is not ZERO */ + if (isNewBlockAllocated) + { + /* The above created new free block will have this one as previous */ + smallBlockIdArray[i].previous = ind; + + smallBlockIdArray[ind].previous = pBlock->previous; + smallBlockIdArray[ind].next = i; + } + else + { + smallBlockIdArray[ind].previous = pBlock->previous; + smallBlockIdArray[ind].next = pBlock->next; + } + + i = ind; + } + else + { + smallBlockIdArray[smallBlockIdArray[i].next].previous = i; //VI15152 + + } + + if (smallBlockIdArray[i].previous == MASK_ALL8) {memDesc[memoryId].firstFreeBlock = &smallBlockIdArray[i];} + else {smallBlockIdArray[smallBlockIdArray[i].previous].next = i;} + } + + /* Build the blockId descriptor */ + pBlock->offset = (t_uint32)(pBlock->offset + alignmentOffset); + pBlock->size = size; + pBlock->previous = MASK_ALL8; + pBlock->next = MASK_ALL8; + + memDesc[memoryId].allocatedMemorySize += size; + + /* Update out parameter */ + *pBlockId = (t_sva_block_id)pBlock; + + return SVA_MM_OK; +} + + + + + +/****************************************************************************/ +/* NAME: t_sva_mm_error FreeSmallBlock ( */ +/* t_sva_mm_small_block_id *pBlockToFree */ +/* ); */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine frees a previously allocated small buffer. */ +/* So this one is added to the free list of the given memory */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - pBlockToFree: identifier of the block to free */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_mm_error */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PRIVATE t_sva_mm_error FreeSmallBlock(t_sva_mm_small_block_id *pBlockToFree) +{ + t_sva_memory_id memoryId; + t_sva_mm_small_block_id *pBlock; + t_uint8 blockToFreeIndex; + t_uint8 blockIndex; + + if (pBlockToFree == 0 || + (pBlockToFree->magic & ~SMALLBLOCK_MAGIC_NUM_MEMORY_ID_MASK) != SMALLBLOCK_MAGIC_NUMBER) + { + return SVA_MM_UNKNOWN_BLOCKID; + } + + memoryId = (t_sva_memory_id)(pBlockToFree->magic & SMALLBLOCK_MAGIC_NUM_MEMORY_ID_MASK); + blockToFreeIndex = SMALL_BLOCK_ID_2_INDEX(pBlockToFree); + + memDesc[memoryId].usedBlocksNum--; + memDesc[memoryId].freeBlocksNum++; + memDesc[memoryId].allocatedMemorySize -= pBlockToFree->size; + + /* + * Search where inserting this new free block + * i.e the first block whom the offset is greater than pBlock->offset + * will be its next one + */ + pBlock = (t_sva_mm_small_block_id *)memDesc[memoryId].firstFreeBlock; + while (pBlock->offset < pBlockToFree->offset) + { + if (pBlock->next != MASK_ALL8) {pBlock = &smallBlockIdArray[pBlock->next];} + else {break;} + } + + blockIndex = SMALL_BLOCK_ID_2_INDEX(pBlock); + + if (pBlock->offset > pBlockToFree->offset) + { + /* + * The block shall be inserted between pBlock et pBlock->previous + */ + pBlockToFree->next = blockIndex; + pBlockToFree->previous = pBlock->previous; + if (pBlock->previous == MASK_ALL8) + { + /* Add to the first place */ + memDesc[memoryId].firstFreeBlock = pBlockToFree; + pBlock->previous = blockToFreeIndex; + } + else + { + smallBlockIdArray[pBlock->previous].next = blockToFreeIndex; + pBlock->previous = blockToFreeIndex; + } + } + else + { + /* Add to the last place */ + pBlockToFree->previous = blockIndex; + pBlockToFree->next = MASK_ALL8; + pBlock->next = blockToFreeIndex; + } + + /* Check if we can merge the block with its predecessor */ + if (pBlockToFree->previous != MASK_ALL8) + { + pBlock = &smallBlockIdArray[pBlockToFree->previous]; + if (pBlockToFree->offset == (pBlock->offset + pBlock->size)) + { + pBlock->size = (t_uint32)(pBlock->size + pBlockToFree->size); + pBlock->next = pBlockToFree->next; + if (pBlock->next != MASK_ALL8) {smallBlockIdArray[pBlock->next].previous = pBlockToFree->previous;} + /* Flag the related smallBlockIdArray entry as unused */ + pBlockToFree->size = 0; + pBlockToFree->next = MASK_ALL8; + pBlockToFree->previous = MASK_ALL8; + pBlockToFree = pBlock; + memDesc[memoryId].freeBlocksNum--; + } + } + + /* Check if we can merge the block with its successor */ + if (pBlockToFree->next != MASK_ALL8) + { + pBlock = &smallBlockIdArray[pBlockToFree->next]; + if ((pBlockToFree->offset + pBlockToFree->size) == pBlock->offset) + { + pBlockToFree->size = (t_uint32)(pBlockToFree->size + pBlock->size); + pBlockToFree->next = pBlock->next; + if (pBlockToFree->next != MASK_ALL8) + { + smallBlockIdArray[pBlockToFree->next].previous = pBlock->previous; + } + /* the related smallBlockIdArray entry as unused */ + pBlock->size = 0; + pBlock->next = MASK_ALL8; + pBlock->previous = MASK_ALL8; + memDesc[memoryId].freeBlocksNum--; + } + } + + return SVA_MM_OK; + +} + +/****************************************************************************/ +/* NAME: t_sva_mm_error FreeLargeBlock ( */ +/* t_sva_mm_large_block_id *pBlockToFree */ +/* ); */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine frees a previously allocated large buffer. */ +/* So this one is added to the free list of the SDRAM memory */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - pBlockToFree: identifier of the block to free */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_mm_error */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PRIVATE t_sva_mm_error FreeLargeBlock(t_sva_mm_large_block_id *pBlockToFree) +{ + t_sva_mm_large_block_id *pBlock; + + if (pBlockToFree == 0 || (t_uint32)pBlockToFree->next != MASK_ALL32) {return SVA_MM_UNKNOWN_BLOCKID;} + + memDesc[SDRAM_ID].usedBlocksNum--; + memDesc[SDRAM_ID].freeBlocksNum++; + memDesc[SDRAM_ID].allocatedMemorySize -= pBlockToFree->size; + + /* + * Search where inserting this new free block + * i.e the first block whom the offset is greater than pBlock->offset + * will be its next one + */ + pBlock = (t_sva_mm_large_block_id *)memDesc[SDRAM_ID].firstFreeBlock; + while (pBlockToFree->physicalAddr > pBlock->physicalAddr && pBlock->next != 0) + { + pBlock = pBlock->next; + } + + if (pBlock->physicalAddr > pBlockToFree->physicalAddr) + { + pBlockToFree->next = pBlock; + if (pBlock->previous == 0) + { + pBlockToFree->previous = 0; + memDesc[SDRAM_ID].firstFreeBlock = (void *) pBlockToFree; + } + else + { + pBlockToFree->previous = pBlock->previous; + pBlock->previous->next = pBlockToFree; + } + pBlock->previous = pBlockToFree; + } + else + /* Add to the end of the free list */ + { + pBlockToFree->previous = pBlock; + pBlockToFree->next = 0; + pBlock->next = pBlockToFree; + } + + /* Check if we can merge the block with its predecessor */ + if (pBlockToFree->previous != NULL) + { + t_sva_mm_large_block_id *pPrevBlock = pBlockToFree->previous; + if (pBlockToFree->physicalAddr == (pPrevBlock->physicalAddr + pPrevBlock->size + sizeof(t_sva_mm_large_block_id))) + { + /* merge the block to free with the previous one */ + pPrevBlock->size += (pBlockToFree->size + sizeof(t_sva_mm_large_block_id)); + pPrevBlock->next = pBlockToFree->next; + if (pPrevBlock->next != 0) {pPrevBlock->next->previous = pPrevBlock;} + pBlockToFree = pPrevBlock; + memDesc[SDRAM_ID].freeBlocksNum--; + } + } + + /* Check if we can merge the block with its successor */ + if (pBlockToFree->next != NULL) + { + t_sva_mm_large_block_id *pNextBlock = pBlockToFree->next; + if (pNextBlock->physicalAddr == (pBlockToFree->physicalAddr + pBlockToFree->size + sizeof(t_sva_mm_large_block_id))) + { + /* merge the block to free with the next one */ + pBlockToFree->size += (pNextBlock->size + sizeof(t_sva_mm_large_block_id)); + pBlockToFree->next = pNextBlock->next; + if (pBlockToFree->next != 0) {pBlockToFree->next->previous = pBlockToFree;} + + memDesc[SDRAM_ID].freeBlocksNum--; + } + } + + return SVA_MM_OK; +} + + + +/****************************************************************************/ +/* NAME: t_sva_mm_error sva_MM_InitDedicatedMemory ( */ +/* ); */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - pBlockToFree: identifier of the block to free */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_mm_error */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_sva_mm_error sva_MM_InitDedicatedMemory( t_sva_dedicated_area_purpose additionalZone, + t_system_address zoneAddress, + t_size zoneSize) { + + t_sva_dedicated_memory_block * dedicatedMemoryInitBlock; + t_sva_block_id dedicatedMemoryInitBlockId; + t_system_address dedicatedMemoryInitBlockAddress; + t_sva_mm_error mmStatus; + + if ((additionalZone != SVA_VC1_IMAGE_BUFFER_AREA)&&(additionalZone != SVA_H264_INTERNAL_AREA)&&(additionalZone != SVA_H264_ENC_FW_PROG_ZONE1_AREA)&& (additionalZone != SVA_SW_PREPROC_BUFFER_AREA)) return SVA_MM_WRONG_DEDICATED; + + // set up mapping of the dedicated memory + dedicatedMemoryMap.nbOfFreeBlocks = 1; + dedicatedMemoryMap.nbOfUseBlocks = 0; + mmStatus = sva_MM_AllocBlock(SDRAM_ID, sizeof(t_sva_dedicated_memory_block), SVA_MM_ALIGN_16BYTES, &dedicatedMemoryInitBlockId); + if (mmStatus != SVA_MM_OK) return(mmStatus); + mmStatus = sva_MM_GetBlockSystemAddress(dedicatedMemoryInitBlockId, &dedicatedMemoryInitBlockAddress); + if (mmStatus != SVA_MM_OK) return(mmStatus); + dedicatedMemoryInitBlock = (t_sva_dedicated_memory_block *)dedicatedMemoryInitBlockAddress.logical; + + dedicatedMemoryInitBlock->address.logical = zoneAddress.logical + SVA_FW_SDRAM_DATA16_ZONE1_SIZE_MAX; + dedicatedMemoryInitBlock->address.physical = zoneAddress.physical + SVA_FW_SDRAM_DATA16_ZONE1_SIZE_MAX; + dedicatedMemoryInitBlock->size = zoneSize - SVA_FW_SDRAM_DATA16_ZONE1_SIZE_MAX; // keep 512KB for fw internal needs + dedicatedMemoryInitBlock->nextBlock = NULL; + dedicatedMemoryInitBlock->previousBlock = NULL; + + dedicatedMemoryMap.firstFreeBlock = dedicatedMemoryInitBlock; + dedicatedMemoryMap.firstUsedBlock = NULL; + + + initMemoryBlock.address = dedicatedMemoryInitBlock->address; + initMemoryBlock.size = dedicatedMemoryInitBlock->size; + initMemoryBlock.nextBlock = NULL; + initMemoryBlock.previousBlock = NULL; + + // prog2 and data2 in eSRAM -> not affected + return SVA_MM_OK; +} + + +PRIVATE t_sva_mm_error sva_MM_ResetDedicatedMemory(void) +{ + dedicatedMemoryMap.nbOfFreeBlocks = 1; + dedicatedMemoryMap.nbOfUseBlocks = 0; + initMemoryBlock_tmp = initMemoryBlock; + dedicatedMemoryMap.firstFreeBlock = &initMemoryBlock_tmp; + dedicatedMemoryMap.firstUsedBlock = NULL; + + return SVA_MM_OK; +} + +/* End of file: sva_memoryMgt.c */ + + --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/memory_management/sva_memorymgt.h @@ -0,0 +1,163 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ + +#ifndef __INC_SVA_MM_H +#define __INC_SVA_MM_H + +#include "hcl_defs.h" +#include "sva.h" +#include "svap.h" + +/******************************************************************************/ +/* Constants definitions */ +/******************************************************************************/ +/* + * Define the number of different kind of memroy managed by this module + */ +#define MEMORY_TYPE_NUMBER 3 + +/* + * Define a constant use to tag an invalid block id into SDRAM memory + */ +#define INVALID_SDRAM_BLOCK_ID 0 + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/******************************************************************************/ +/* Types definitions */ +/******************************************************************************/ +/* + * Define symbols used to identify/reference different kind of memory managed into the system + */ +typedef enum { + UNKNOWN_MEMORY_ID = -1, + XRAM_ID = 0, + ESRAM_ID, + SDRAM_ID // SHALL be the last one (only SDRAM chunk can be dynamically added) +} t_sva_memory_id; + +/* + * Define the type used to identify/reference an allocated piece of memory (block) into the HCL + */ +typedef t_uint32 t_sva_block_id; + +/* + * Definition of symbol used by Memory Management routines to return error + */ +typedef enum { + SVA_MM_UNKNOWN_ADDR = SVA_MM_LAST_ERROR, + SVA_MM_WRONG_DEDICATED, + SVA_MM_UNKNOWN_BLOCKID, + SVA_MM_OUT_OF_MEMORY, + SVA_MM_SIZE_INCOMPATIBLE, + SVA_MM_MAX_SMALLBLOCK_REACHED, + SVA_MM_MAX_MEMORY_CHUNK_REACHED, + SVA_MM_OK = HCL_OK +} t_sva_mm_error; + +/* + * Definition of the different block alignment supported + * This is a 'at least' request, that is to say the module could provide a buffer + * with a most constraint alignement (i.e a 4WORDS for a requested WORD alignement) + */ +typedef enum { + SVA_MM_ALIGN_BYTE = 0x00000000, + SVA_MM_ALIGN_HALFWORD = 0x00000001, + SVA_MM_ALIGN_WORD = 0x00000003, + SVA_MM_ALIGN_16BYTES = 0x0000000F, + SVA_MM_ALIGN_4WORDS = 0x0000000F, + SVA_MM_ALIGN_AHB_BURST = 0x0000000F, + SVA_MM_ALIGN_32BYTES = 0x0000001F, + SVA_MM_ALIGN_8WORDS = 0x0000001F, + SVA_MM_ALIGN_64BYTES = 0x0000003F, + SVA_MM_ALIGN_16WORDS = 0x0000003F, + SVA_MM_ALIGN_128BYTES = 0x0000007F, + SVA_MM_ALIGN_32WORDS = 0x0000007F, + SVA_MM_ALIGN_256BYTES = 0x000000FF, + SVA_MM_ALIGN_64WORDS = 0x000000FF, + SVA_MM_ALIGN_512BYTES = 0x000001FF, + SVA_MM_ALIGN_128WORDS = 0x000001FF, + SVA_MM_ALIGN_1024BYTES = 0x000003FF, + SVA_MM_ALIGN_256WORDS = 0x000003FF, + SVA_MM_ALIGN_2048BYTES = 0x000007FF, + SVA_MM_ALIGN_512WORDS = 0x000007FF, + SVA_MM_ALIGN_4096BYTES = 0x00000FFF, + SVA_MM_ALIGN_1024WORDS = 0x00000FFF +} t_sva_mm_alignment; + + +/* + * Definition of the memory management public status of a given memory + */ +typedef struct { + t_uint32 numUsedBlocks; + t_uint32 numFreeBlocks; + t_size freeBlockMinSize; + t_size freeBlockMaxSize; + t_size overallFreeBlocksSize; + t_size overallUsedBlocksSize; +} t_sva_mm_status; + + +typedef struct t_sva_dedicated_memory_block { + t_size size; + t_system_address address; + struct t_sva_dedicated_memory_block * previousBlock; + struct t_sva_dedicated_memory_block * nextBlock; +} t_sva_dedicated_memory_block; + +typedef struct { + t_uint32 nbOfFreeBlocks; + t_uint32 nbOfUseBlocks; + t_sva_dedicated_memory_block * firstFreeBlock; + t_sva_dedicated_memory_block * firstUsedBlock; +} t_sva_dedicated_memory; + + +/****************************************************************************** +* PUBLIC Functions +*******************************************************************************/ +/* Memory Management Module Initialisation */ +PUBLIC t_sva_mm_error sva_MM_Init(void); + +/* Memory Management routines */ +PUBLIC t_sva_mm_error sva_MM_AddFreeBlock(t_sva_memory_id, t_system_address, t_size); +PUBLIC t_sva_mm_error sva_MM_AllocBlock(t_sva_memory_id, t_size, t_sva_mm_alignment, t_sva_block_id *); +PUBLIC t_sva_mm_error sva_MM_FreeBlock(t_sva_block_id); + +/* Status and 'Translation' routines */ +PUBLIC t_sva_mm_error sva_MM_GetBlockSystemAddress(t_sva_block_id, t_system_address *); +PUBLIC t_sva_mm_error sva_MM_GetBlockLogicalAddress(t_sva_block_id, t_logical_address *); +PUBLIC t_sva_mm_error sva_MM_GetBlockPhysicalAddress(t_sva_block_id, t_physical_address *); +PUBLIC t_sva_mm_error sva_MM_GetBlockMemoryId(t_sva_block_id, t_sva_memory_id *); +PUBLIC t_sva_mm_error sva_MM_GetStatus(t_sva_memory_id, t_sva_mm_status *); +PUBLIC t_sva_mm_error sva_MM_PhysicalToLogicalAddress(t_physical_address, t_logical_address *); +PUBLIC t_sva_mm_error sva_MM_InitDedicatedMemory(t_sva_dedicated_area_purpose , t_system_address , t_size); +PUBLIC t_sva_mm_error sva_MM_AllocDedicatedBlock(t_size , t_sva_mm_alignment , t_sva_block_id * ); +PUBLIC t_sva_mm_error sva_MM_FreeDedicatedBlock(t_sva_block_id); +PUBLIC t_sva_mm_error sva_MM_GetDedicatedBlockSystemAddress(t_sva_block_id, t_system_address *); + +#ifdef __cplusplus +} /* allow C++ to use these headers */ +#endif /* __cplusplus */ + +#endif /* __INC_HV_MM_H */ +/* End of file - sva_memorymgt.h */ --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/memory_management/sva_memorymgtp.h @@ -0,0 +1,105 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ + +#ifndef __INC_SVA_MM_P_H +#define __INC_SVA_MM_P_H + +#include "hcl_defs.h" + +/******************************************************************************/ +/* Constants definitions */ +/******************************************************************************/ +/* + * Define the maximum number of memory chunk (SDRAM only) + * managed at the same time into the memory management library + */ +#define NB_MAX_MANAGED_MEMORY_CHUNK 4 + +/* + * Define the maximum number of small block id (today XRAM and ESRAM) + * managed at the same time into the memory management library + */ +#define NB_MAX_MANAGED_SMALL_BLOCK 16 + +/* + * Define the Small Block Magic Number value + * (impossible physical address in order to discriminate small blocks from large ones) + * The 4LSb are used to identify the memory type (here XRAM or ESRAM) + */ +#define SMALLBLOCK_MAGIC_NUMBER 0xFFFFFFF0UL +#define SMALLBLOCK_MAGIC_NUM_MEMORY_ID_MASK 0xF + +/* + * Define the threshold used to decide if we create a new block + * when cutting one into several pieces. + * If the size is lesser than the threshold, then we merge the 'small' block with the allocated one + */ +#define LARGE_BLOCK_DISCARD_THRESHOLD 512 + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/******************************************************************************/ +/* Types definitions */ +/******************************************************************************/ +/* + * Define the types used to characterize a memory chunk internally + */ +/* Small one (< 512KB) */ +typedef struct st_small_block_id { + t_uint32 magic; + t_uint32 offset; + t_uint32 size; + t_uint8 previous; + t_uint8 next; +} t_sva_mm_small_block_id; + +/* Large one (others, > 1MB) */ +typedef struct st_large_block_id { + t_physical_address physicalAddr; + t_uint32 size; + struct st_large_block_id *previous; + struct st_large_block_id *next; +} t_sva_mm_large_block_id; + +/* + * Define a type used to characterize a kind of memory (see t_sva_memory_id) + */ +typedef struct { + t_system_address systemAddress; + t_physical_address physicalEndAddr; + t_logical_address logicalEndAddr; + t_uint32 logicalToPhysicalOffset; + t_uint16 freeBlocksNum; + t_uint16 usedBlocksNum; + void * firstFreeBlock; + t_size allocatedMemorySize; +} t_sva_mm_memory_desc; + +/******************************************************************************* +* PRIVATE Functions prototype +*******************************************************************************/ + +#ifdef __cplusplus +} /* allow C++ to use these headers */ +#endif /* __cplusplus */ + +#endif /* __INC_SVA_MM_P_H */ +/* End of file - sva_memorymgtp.h */ --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/openservice_management/sva_openservice.h @@ -0,0 +1,62 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ + +#ifndef __INC_OPENSERVICE_H +#define __INC_OPENSERVICE_H + +#include "hcl_defs.h" +#include "sva_taskmgt.h" + +/* + * This enum type will be use by SVA_OM_BUILD_FIELD_ID macro to select task to use between + * decode, encode, grab, display and tvo + */ +typedef enum { + SVA_OM_DEC =0x10, + SVA_OM_ENC =0x20, + SVA_OM_GRB =0x30, + SVA_OM_DIS =0x40, + SVA_OM_TVO =0x50 +} t_sva_open_service_task; + +/* + * This macro allow to build a t_sva_tm_field_id that will be of the correct format for + * task management API (sva_TM_GetSubTaskField, sva_TM_ConnectSubtasksFields, sva_TM_InitSubTaskField, + * sva_TM_UpdateSubTaskField) + */ +#define SVA_OM_BUILD_FIELD_ID(task,fieldNb) ((t_sva_tm_field_id)(((task&MASK_BYTE0)<. */ +/*---------------------------------------------------------------------------*/ + +#include "hcl_defs.h" +#include "sva.h" +#include "sva_openservice.h" +#include "sva_openservicemgt.h" +#include "sva_openservicemgtp.h" + +/*------------------------------------------------------------------------ + * Global Variables + *----------------------------------------------------------------------*/ +PRIVATE t_sva_om_descriptor omDesc[NUM_MAX_OPEN_SERVICE_DESCRIPTOR]; + +/*------------------------------------------------------------------------ + * SVA level API + *----------------------------------------------------------------------*/ +/****************************************************************************/ +/* NAME: t_sva_error SVA_RegisterOpenService ( */ +/* const tp_sva_open_service_methods pMethods, */ +/* t_sva_fw_id fwId, */ +/* t_sva_service_type *pServiceType */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will register a new open service. It will store its */ +/* methods, firmware needed. It will return to user a t_sva_service_type*/ +/* to use during creation of an instance of the open service. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - pMethods: list of open service methods */ +/* - fwId: firmware required for open service */ +/* */ +/* OUT : */ +/* - pServiceType : user will use this type when creating an instance */ +/* of an open service. */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/* - SVA_OK : methods and firmware has been registered */ +/* - SVA_NO_MORE_OPEN_SERVICE : Unable to provide a new */ +/* t_sva_service_type */ +/* */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_sva_error SVA_RegisterOpenService( + const tp_sva_open_service_methods pMethods, + t_sva_fw_id fwId, + t_sva_service_type *pServiceType +) +{ + t_uint32 i; + + HCL_ASSERT(pMethods!=NULL); + HCL_ASSERT(pServiceType!=NULL); + + /*try to find a free descriptor*/ + for(i=0;i SVA_OPEN_SERVICE_7) + { + return SVA_INCOHERENT_SERVICE_TYPE; + } + + /*check that service type is in use*/ + index=(t_uint32) (serviceType-SVA_OPEN_SERVICE_0); + if (omDesc[index].fwId==MASK_ALL32) + { + return SVA_INCOHERENT_SERVICE_TYPE; + } + + /*unregister it*/ + omDesc[index].fwId=MASK_ALL32; + + return SVA_OK; +} + +/*------------------------------------------------------------------------ + * Internal level API + *----------------------------------------------------------------------*/ +/****************************************************************************/ +/* NAME: t_sva_error sva_OM_Init() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will init open service management. */ +/* */ +/* PARAMETERS: */ +/* IN : none */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_om_error */ +/* - SVA_OM_OK */ +/* */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_sva_om_error sva_OM_Init(void) +{ + t_uint32 i; + + /*reset all descriptors*/ + for(i=0;i SVA_OPEN_SERVICE_7) + { + return FALSE; + } + else {return TRUE;} +} + +/****************************************************************************/ +/* NAME: t_sva_om_error sva_OM_GetFirmwareId( */ +/* t_sva_service_id serviceId, */ +/* t_sva_fw_id *pFwId */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will return firmware Id need by an open service. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - serviceId : service for which we want to retriewe a firmware id. */ +/* */ +/* OUT : */ +/* - pFwId : return firmware id. */ +/* */ +/* RETURN: */ +/* t_sva_om_error */ +/* - SVA_OM_OK : API successfull */ +/* - SVA_OM_NOT_AN_OPEN_SERVICE : serviceId is not an open service */ +/* - SVA_OM_UNREGISTERED : open service is not registered */ +/* */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_sva_om_error sva_OM_GetFirmwareId( + t_sva_service_id serviceId, + t_sva_fw_id *pFwId +) +{ + t_uint32 index; + + HCL_ASSERT(pFwId!=NULL); + + /*check that we have an open service*/ + if (sva_OM_isOpenService(serviceId)==FALSE) {return SVA_OM_NOT_AN_OPEN_SERVICE;} + + /*check if it's register or not*/ + index=(t_uint32) (READ_OPEN_SERVICE_NUM_IN_SERVICE_ID(serviceId)-SVA_OPEN_SERVICE_0); + if (omDesc[index].fwId==MASK_ALL32) {return SVA_OM_UNREGISTERED;} + + /*return firmware id*/ + *pFwId=omDesc[index].fwId; + + return SVA_OM_OK; +} + +/****************************************************************************/ +/* NAME: t_sva_error sva_OM_Create( */ +/* t_sva_service_type serviceType, */ +/* t_sva_service_id *pServiceId */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will dispatch call to create method of open service. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - serviceType : User give value return during SVA_RegisterOpenService*/ +/* call. */ +/* */ +/* OUT : */ +/* - pServiceId : return a serviceId. */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/* - open service dependant */ +/* */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_sva_error sva_OM_Create( + t_sva_service_type serviceType, + t_sva_service_id *pServiceId +) +{ + t_uint32 index; + + HCL_ASSERT(pServiceId!=NULL); + + /*check that we have an open service*/ + if (serviceType < SVA_OPEN_SERVICE_0 || serviceType > SVA_OPEN_SERVICE_7) + { + return SVA_FATAL_ERROR; + } + + /*check if it's register or not*/ + index=(t_uint32) (serviceType-SVA_OPEN_SERVICE_0); + if (omDesc[index].fwId==MASK_ALL32) {return SVA_FATAL_ERROR;} + + /*We use open service field to retriewe methods to use*/ + WRITE_OPEN_SERVICE_NUM_IN_SERVICE_ID(serviceType,*pServiceId); + + /*dispatch it*/ + return omDesc[index].methods.pCreateService(pServiceId); +} + +/****************************************************************************/ +/* NAME: t_sva_error sva_OM_Delete( */ +/* t_sva_service_id serviceId */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will dispatch call to delete method of open service. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - serviceId : open service Id need to find correct dispatch API */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/* - open service dependant */ +/* */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_sva_error sva_OM_Delete( + t_sva_service_id serviceId +) +{ + t_uint32 index; + + /*check that we have an open service*/ + if (sva_OM_isOpenService(serviceId)==FALSE) {return SVA_FATAL_ERROR;} + + /*check if it's register or not*/ + index=(t_uint32) (READ_OPEN_SERVICE_NUM_IN_SERVICE_ID(serviceId)-SVA_OPEN_SERVICE_0); + if (omDesc[index].fwId==MASK_ALL32) {return SVA_FATAL_ERROR;} + + /*dispatch it*/ + return omDesc[index].methods.pDeleteService(serviceId); +} + +/****************************************************************************/ +/* NAME: t_sva_error sva_OM_Control( */ +/* t_sva_service_id serviceId, */ +/* t_sva_service_cmd_id cmdId, */ +/* t_uint32 param */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will dispatch call to control method of open service. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - serviceId : open service Id need to find correct dispatch API */ +/* - cmdId : command request by user */ +/* - param : param associated to cmdId */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/* - open service dependant */ +/* */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_sva_error sva_OM_Control( + t_sva_service_id serviceId, + t_sva_service_cmd_id cmdId, + t_uint32 param +) +{ + t_uint32 index; + + /*check that we have an open service*/ + if (sva_OM_isOpenService(serviceId)==FALSE) {return SVA_FATAL_ERROR;} + + /*check if it's register or not*/ + index=(t_uint32) (READ_OPEN_SERVICE_NUM_IN_SERVICE_ID(serviceId)-SVA_OPEN_SERVICE_0); + if (omDesc[index].fwId==MASK_ALL32) {return SVA_FATAL_ERROR;} + + /*dispatch it*/ + return omDesc[index].methods.pControlService(serviceId,cmdId,param); +} + +/****************************************************************************/ +/* NAME: t_sva_error sva_OM_Activate( */ +/* t_sva_service_id serviceId, */ +/* t_sva_service_mode serviceMode, */ +/* t_sva_fw_id *pFwId */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will dispatch call to activate method of open service.*/ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - serviceId : open service Id need to find correct dispatch API */ +/* - serviceMode : activation mode of service (real or not real time) */ +/* */ +/* OUT : */ +/* - pFwId : firmware id information if needed. */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/* - open service dependant */ +/* */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_sva_error sva_OM_Activate( + t_sva_service_id serviceId, + t_sva_service_mode serviceMode, + t_sva_fw_id *pFwId +) +{ + t_uint32 index; + + /*check that we have an open service*/ + if (sva_OM_isOpenService(serviceId)==FALSE) {return SVA_FATAL_ERROR;} + + /*check if it's register or not*/ + index=(t_uint32) (READ_OPEN_SERVICE_NUM_IN_SERVICE_ID(serviceId)-SVA_OPEN_SERVICE_0); + if (omDesc[index].fwId==MASK_ALL32) {return SVA_FATAL_ERROR;} + + /*dispatch it*/ + return omDesc[index].methods.pActivateService(serviceId,serviceMode,pFwId); +} + +/****************************************************************************/ +/* NAME: t_sva_error sva_OM_Inactivate( */ +/* t_sva_service_id serviceId */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will dispatch call to inactivate method of open */ +/* service. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - serviceId : open service Id need to find correct dispatch API */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/* - open service dependant */ +/* */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_sva_error sva_OM_Inactivate(t_sva_service_id serviceId) +{ + t_uint32 index; + + /*check that we have an open service*/ + if (sva_OM_isOpenService(serviceId)==FALSE) {return SVA_FATAL_ERROR;} + + /*check if it's register or not*/ + index=(t_uint32) (READ_OPEN_SERVICE_NUM_IN_SERVICE_ID(serviceId)-SVA_OPEN_SERVICE_0); + if (omDesc[index].fwId==MASK_ALL32) {return SVA_FATAL_ERROR;} + + /*dispatch it*/ + return omDesc[index].methods.pInactivateService(serviceId); +} + +/****************************************************************************/ +/* NAME: t_sva_error sva_OM_GetInternalNeeds( */ +/* t_sva_service_id serviceId, */ +/* t_size *pSize */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will dispatch call to getInternalNeeds method of open */ +/* service. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - serviceId : open service Id need to find correct dispatch API */ +/* */ +/* OUT : */ +/* - pSize : return memory size need by service. */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/* - open service dependant */ +/* */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_sva_error sva_OM_GetInternalNeeds( + t_sva_service_id serviceId, + t_size *pSize) +{ + t_uint32 index; + + /*check that we have an open service*/ + if (sva_OM_isOpenService(serviceId)==FALSE) {return SVA_FATAL_ERROR;} + + /*check if it's register or not*/ + index=(t_uint32) (READ_OPEN_SERVICE_NUM_IN_SERVICE_ID(serviceId)-SVA_OPEN_SERVICE_0); + if (omDesc[index].fwId==MASK_ALL32) {return SVA_FATAL_ERROR;} + + /*dispatch it*/ + return omDesc[index].methods.pGetServiceInternalNeeds(serviceId,pSize); +} + +/****************************************************************************/ +/* NAME: t_sva_error sva_OM_ProvideInternalNeeds( */ +/* t_sva_service_id serviceId */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will dispatch call to provideInternalNeeds method of */ +/* open service. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - serviceId : open service Id need to find correct dispatch API */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/* - open service dependant */ +/* */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_sva_error sva_OM_ProvideInternalNeeds( + t_sva_service_id serviceId +) +{ + t_uint32 index; + + /*check that we have an open service*/ + if (sva_OM_isOpenService(serviceId)==FALSE) {return SVA_FATAL_ERROR;} + + /*check if it's register or not*/ + index=(t_uint32) (READ_OPEN_SERVICE_NUM_IN_SERVICE_ID(serviceId)-SVA_OPEN_SERVICE_0); + if (omDesc[index].fwId==MASK_ALL32) {return SVA_FATAL_ERROR;} + + /*dispatch it*/ + return omDesc[index].methods.pProvideServiceInternalNeeds(serviceId); +} + +/****************************************************************************/ +/* NAME: t_sva_error sva_OM_DispatchVirtualHwEvent( */ +/* t_sva_tm_virtual_hw_event_id eventId, */ +/* t_sva_service_id serviceId, */ +/* t_sva_tm_subtask_id subtaskId, */ +/* t_uint32 eventTimestamp, */ +/* t_uint32 eventDate, */ +/* t_uint8 maxOfEvent, */ +/* t_sva_event_desc *pEventDesc, */ +/* t_uint32 *pNbEvent */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will dispatch call to dispatchVirtualHwEvent method of*/ +/* open service. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - virtualEvent : virtual event to process. */ +/* - serviceId : open service Id need to find correct dispatch API. */ +/* - eventTimestamp: time at which the event occur (system time unit) */ +/* - eventDate: time at which the event occur (ticks time unit) */ +/* - nbMaxEvents : size of pEventDesc table. Give the max number of */ +/* event the dispatch API can filled. */ +/* */ +/* OUT : */ +/* - pEventDesc : table where user will put event */ +/* - pNbEventsRaised : number of user events generated by user. */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/* - open service dependant */ +/* */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_sva_error sva_OM_DispatchVirtualHwEvent( + t_sva_tm_virtual_hw_event_id eventId, + t_sva_service_id serviceId, + t_sva_tm_subtask_id subtaskId, + t_uint32 eventTimestamp, + t_uint32 eventDate, + t_uint8 nbMaxEvents, + t_sva_event_desc *pEventDesc, + t_uint32 *pNbEvent +) +{ + t_uint32 index; + + *pNbEvent=0; + + /*check that we have an open service*/ + if (sva_OM_isOpenService(serviceId)==FALSE) {return SVA_FATAL_ERROR;} + + /*check if it's register or not*/ + index=(t_uint32) (READ_OPEN_SERVICE_NUM_IN_SERVICE_ID(serviceId)-SVA_OPEN_SERVICE_0); + if (omDesc[index].fwId==MASK_ALL32) {return SVA_FATAL_ERROR;} + + /*dispatch it*/ + return omDesc[index].methods.pDispatchHwEvent(eventId,serviceId,subtaskId,eventTimestamp,eventDate,nbMaxEvents,pEventDesc,pNbEvent); +} + +// End of file - sva_openservicemgt.c --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/openservice_management/sva_openservicemgt.h @@ -0,0 +1,71 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ + +#ifndef __INC_SVA_OM_H +#define __INC_SVA_OM_H + +#include "hcl_defs.h" +#include "sva.h" + +/******************************************************************************/ +/* Constants definitions */ +/******************************************************************************/ + + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/******************************************************************************/ +/* Types definitions */ +/******************************************************************************/ +/* + * Definition of symbol used by open service Management routines to return error + */ +typedef enum { + SVA_OM_UNREGISTERED , // = SVA_OM_LAST_ERROR, + SVA_OM_NOT_AN_OPEN_SERVICE, + SVA_OM_OK = SVA_OK +} t_sva_om_error; + +/******************************************************************************* +* PUBLIC Functions +*******************************************************************************/ +PUBLIC t_sva_om_error sva_OM_Init(void); +PUBLIC t_bool sva_OM_isOpenService(t_sva_service_id); +PUBLIC t_sva_om_error sva_OM_GetFirmwareId(t_sva_service_id, t_sva_fw_id *); +PUBLIC t_sva_error sva_OM_Create(t_sva_service_type, t_sva_service_id *); +PUBLIC t_sva_error sva_OM_Delete(t_sva_service_id); +PUBLIC t_sva_error sva_OM_Control(t_sva_service_id, t_sva_service_cmd_id, t_uint32); +PUBLIC t_sva_error sva_OM_Activate(t_sva_service_id, t_sva_service_mode, t_sva_fw_id *); +PUBLIC t_sva_error sva_OM_Inactivate(t_sva_service_id); +PUBLIC t_sva_error sva_OM_GetInternalNeeds(t_sva_service_id, t_size *); +PUBLIC t_sva_error sva_OM_ProvideInternalNeeds(t_sva_service_id); +PUBLIC t_sva_error sva_OM_DispatchVirtualHwEvent(t_sva_tm_virtual_hw_event_id ,t_sva_service_id ,t_sva_tm_subtask_id ,t_uint32 ,t_uint32 ,t_uint8 ,t_sva_event_desc *,t_uint32 *); + +/*PUBLIC t_sva_error SVA_RegisterOpenService(const tp_sva_open_service_methods , t_sva_fw_id, t_sva_service_type *); see sva.h */ +/*PUBLIC t_sva_error SVA_UnregisterOpenService(t_sva_service_type); see sva.h */ + + +#ifdef __cplusplus +} /* allow C++ to use these headers */ +#endif /* __cplusplus */ + +#endif /* __INC_HV_FM_H */ +/* End of file - hv_fwMgt.h */ --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/openservice_management/sva_openservicemgtp.h @@ -0,0 +1,56 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ + +#ifndef __INC_SVA_OMP_H +#define __INC_SVA_OMP_H + +#include "hcl_defs.h" +#include "sva_service.h" + +/******************************************************************************/ +/* Constants definitions */ +/******************************************************************************/ +/* + * Define maximal number of open service that can be registered at a time + */ +#define NUM_MAX_OPEN_SERVICE_DESCRIPTOR 8 + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/******************************************************************************/ +/* Types definitions */ +/******************************************************************************/ + + +/* + * Define the descriptor of an open service descriptor + */ +typedef struct { + t_sva_open_service_methods methods; + t_sva_fw_id fwId; +} t_sva_om_descriptor; + +#ifdef __cplusplus +} /* allow C++ to use these headers */ +#endif /* __cplusplus */ + +#endif /* __INC_SVA_ENCODEP_H */ +/* End of file - sva_encodep.h */ --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/stab/sva_stab.c @@ -0,0 +1,2855 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ +/*------------------------------------------------------------------------ + * Includes + *----------------------------------------------------------------------*/ +#include "hcl_defs.h" +#include "sva_stab.h" +#include "sva_stabp.h" +#include "sva_eventmgt.h" + +/*------------------------------------------------------------------------ + * Global Variables + *----------------------------------------------------------------------*/ + #ifdef __DEBUG +ALIGN(32) PRIVATE t_sva_st_debug_events eventStabDebugTable[NUM_MAX_STAB]; +ALIGN(32) PRIVATE t_sva_st_debug_commands commandStabDebugTable[NUM_MAX_STAB]; +ALIGN(32) PRIVATE t_sva_st_debug_transitions transitionStabDebugTable[NUM_MAX_STAB]; +#endif +/*instance descriptors*/ +PRIVATE t_sva_st_descriptor stabDesc[NUM_MAX_STAB]; + +/*table that describe memory allocation for stab*/ +PRIVATE const t_sva_tm_field_ctrl_desc defaultStabFieldDescArray[STAB_FIELD_NUMBER]={ + { SVA_TM_DCMD_ALLOCATE, {{sizeof(t_sva_vec_frame_buffer_in), STAB_DEFAULT_INFOS_MEMORY_ID}}}, + { SVA_TM_DCMD_ALLOCATE, {{sizeof(t_sva_vec_frame_buffer_out), STAB_DEFAULT_INFOS_MEMORY_ID}}}, + { SVA_TM_DCMD_ALLOCATE, {{sizeof(t_sva_vec_internal_buffer), STAB_DEFAULT_INFOS_MEMORY_ID}}}, + { SVA_TM_DCMD_ALLOCATE, {{sizeof(t_sva_header_buf), STAB_DEFAULT_INFOS_MEMORY_ID}}}, + { SVA_TM_DCMD_ALLOCATE, {{sizeof(t_sva_bitstream_buffer_pos), STAB_DEFAULT_INFOS_MEMORY_ID}}}, + { SVA_TM_DCMD_ALLOCATE, {{sizeof(t_sva_bitstream_buffer_pos), STAB_DEFAULT_INFOS_MEMORY_ID}}}, + { SVA_TM_DCMD_ALLOCATE, {{sizeof(t_sva_vec_stab_param_in), STAB_DEFAULT_INFOS_MEMORY_ID}}}, + { SVA_TM_DCMD_ALLOCATE, {{sizeof(t_sva_vec_stab_param_out), STAB_DEFAULT_INFOS_MEMORY_ID}}} +}; + +/*table that translate stab state into service state*/ +PRIVATE const t_sva_service_state stabState2ServiceState[SVA_ST_LAST_DUMMY_STATE]= { + SVA_SERVICE_NOT_INITIALIZED, /*SVA_ST_NOT_INITIALIZED*/ + SVA_SERVICE_WAIT_FOR_CONFIGURATION, /*SVA_ST_WAIT_FOR_CONFIGURATION*/ + SVA_SERVICE_WAIT_FOR_INTERNAL_NEEDS, /*SVA_ST_WAIT_FOR_INTERNAL_NEEDS*/ + SVA_SERVICE_WAIT_FOR_ACTIVATE, /*SVA_ST_WAIT_FOR_ACTIVATE*/ + SVA_SERVICE_WAIT_FOR_START, /*SVA_ST_WAIT_FOR_START*/ + SVA_SERVICE_FLUSHING, /*SVA_ST_FLUSHING_IN*/ + SVA_SERVICE_FLUSHING, /*SVA_ST_FLUSHING_OUT*/ + SVA_SERVICE_WAIT_FOR_DATA, /*SVA_ST_WAIT_FOR_DATA*/ + SVA_SERVICE_RUNNING, /*SVA_ST_RUNNING*/ + SVA_SERVICE_ABORT_REQUESTED, /*SVA_ST_ABORT_REQUESTED*/ + SVA_SERVICE_STOP_REQUESTED, /*SVA_ST_STOP_REQUESTED*/ + SVA_SERVICE_ERROR /*SVA_ST_ERROR*/ +}; + +/*main state machine description*/ +PRIVATE const t_sva_st_state stateMachine[SVA_ST_LAST_DUMMY_STATE][SVA_ST_LAST_DUMMY_TRANSITION]= { + /* Current State = SVA_ST_NOT_INITIALIZED */ + { + SVA_ST_WAIT_FOR_CONFIGURATION, /*SVA_ST_CREATE*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_CONFIGURE*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_INTERNAL_NEEDS*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_ACTIVATE*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_INACTIVATE*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_CONTROL_START*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_CONTROL_STOP*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_CONTROL_ABORT*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_ALL_DEPENDENCIES_RESOLVED*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_PUSH*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_EVENT_EOK*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_EVENT_FAKE*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_EVENT_ACTIVE*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_EVENT_INACTIVE*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_RESET*/ + SVA_ST_NOT_INITIALIZED, /*SVA_ST_CONTROL_DELETE*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_EVENT_ERROR*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_FLUSH_IN*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_FLUSH_OUT*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_CANCEL*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_UPDATE_PARAM*/ + SVA_ST_TRANSITION_REJECTED /*SVA_ST_GET_PARAM_SIZE*/ + }, + /* Current State = SVA_ST_WAIT_FOR_CONFIGURATION */ + { + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_CREATE*/ + SVA_ST_WAIT_FOR_INTERNAL_NEEDS, /*SVA_ST_CONFIGURE*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_INTERNAL_NEEDS*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_ACTIVATE*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_INACTIVATE*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_CONTROL_START*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_CONTROL_STOP*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_CONTROL_ABORT*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_ALL_DEPENDENCIES_RESOLVED*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_PUSH*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_EVENT_EOK*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_EVENT_FAKE*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_EVENT_ACTIVE*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_EVENT_INACTIVE*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_RESET*/ + SVA_ST_NOT_INITIALIZED, /*SVA_ST_CONTROL_DELETE*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_EVENT_ERROR*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_FLUSH_IN*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_FLUSH_OUT*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_CANCEL*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_UPDATE_PARAM*/ + SVA_ST_TRANSITION_REJECTED /*SVA_ST_GET_PARAM_SIZE*/ + }, + /* Current State = SVA_ST_WAIT_FOR_INTERNAL_NEEDS */ + { + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_CREATE*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_CONFIGURE*/ + SVA_ST_WAIT_FOR_ACTIVATE, /*SVA_ST_INTERNAL_NEEDS*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_ACTIVATE*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_INACTIVATE*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_CONTROL_START*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_CONTROL_STOP*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_CONTROL_ABORT*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_ALL_DEPENDENCIES_RESOLVED*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_PUSH*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_EVENT_EOK*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_EVENT_FAKE*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_EVENT_ACTIVE*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_EVENT_INACTIVE*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_RESET*/ + SVA_ST_NOT_INITIALIZED, /*SVA_ST_CONTROL_DELETE*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_EVENT_ERROR*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_FLUSH_IN*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_FLUSH_OUT*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_CANCEL*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_UPDATE_PARAM*/ + SVA_ST_WAIT_FOR_INTERNAL_NEEDS /*SVA_ST_GET_PARAM_SIZE*/ + }, + /* Current State = SVA_ST_WAIT_FOR_ACTIVATE */ + { + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_CREATE*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_CONFIGURE*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_INTERNAL_NEEDS*/ + SVA_ST_WAIT_FOR_ACTIVATE, /*SVA_ST_ACTIVATE*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_INACTIVATE*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_CONTROL_START*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_CONTROL_STOP*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_CONTROL_ABORT*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_ALL_DEPENDENCIES_RESOLVED*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_PUSH*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_EVENT_EOK*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_EVENT_FAKE*/ + SVA_ST_WAIT_FOR_START, /*SVA_ST_EVENT_ACTIVE*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_EVENT_INACTIVE*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_RESET*/ + SVA_ST_NOT_INITIALIZED, /*SVA_ST_CONTROL_DELETE*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_EVENT_ERROR*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_FLUSH_IN*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_FLUSH_OUT*/ + SVA_ST_WAIT_FOR_ACTIVATE, /*SVA_ST_CANCEL*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_UPDATE_PARAM*/ + SVA_ST_WAIT_FOR_ACTIVATE /*SVA_ST_GET_PARAM_SIZE*/ + }, + /* Current State = SVA_ST_WAIT_FOR_START */ + { + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_CREATE*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_CONFIGURE*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_INTERNAL_NEEDS*/ + SVA_ST_WAIT_FOR_START, /*SVA_ST_ACTIVATE*/ + SVA_ST_WAIT_FOR_START, /*SVA_ST_INACTIVATE*/ + SVA_ST_WAIT_FOR_DATA, /*SVA_ST_CONTROL_START*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_CONTROL_STOP*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_CONTROL_ABORT*/ + SVA_ST_WAIT_FOR_START, /*SVA_ST_ALL_DEPENDENCIES_RESOLVED*/ + SVA_ST_WAIT_FOR_START, /*SVA_ST_PUSH*/ + SVA_ST_ERROR, /*SVA_ST_EVENT_EOK*/ + SVA_ST_ERROR, /*SVA_ST_EVENT_FAKE*/ + SVA_ST_WAIT_FOR_START, /*SVA_ST_EVENT_ACTIVE*/ + SVA_ST_WAIT_FOR_START, /*SVA_ST_EVENT_INACTIVE*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_RESET*/ + SVA_ST_NOT_INITIALIZED, /*SVA_ST_CONTROL_DELETE*/ + SVA_ST_ERROR, /*SVA_ST_EVENT_ERROR*/ + SVA_ST_FLUSHING_IN, /*SVA_ST_FLUSH_IN*/ + SVA_ST_FLUSHING_OUT, /*SVA_ST_FLUSH_OUT*/ + SVA_ST_WAIT_FOR_START, /*SVA_ST_CANCEL*/ + SVA_ST_WAIT_FOR_START, /*SVA_ST_UPDATE_PARAM*/ + SVA_ST_WAIT_FOR_START /*SVA_ST_GET_PARAM_SIZE*/ + }, + /* Current State = SVA_ST_FLUSHING_IN */ + { + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_CREATE*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_CONFIGURE*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_INTERNAL_NEEDS*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_ACTIVATE*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_INACTIVATE*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_CONTROL_START*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_CONTROL_STOP*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_CONTROL_ABORT*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_ALL_DEPENDENCIES_RESOLVED*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_PUSH*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_EVENT_EOK*/ + SVA_ST_WAIT_FOR_START, /*SVA_ST_EVENT_FAKE*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_EVENT_ACTIVE*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_EVENT_INACTIVE*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_RESET*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_CONTROL_DELETE*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_EVENT_ERROR*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_FLUSH_IN*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_FLUSH_OUT*/ + SVA_ST_FLUSHING_IN, /*SVA_ST_CANCEL*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_UPDATE_PARAM*/ + SVA_ST_FLUSHING_IN /*SVA_ST_GET_PARAM_SIZE*/ + }, + /* Current State = SVA_ST_FLUSHING_OUT */ + { + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_CREATE*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_CONFIGURE*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_INTERNAL_NEEDS*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_ACTIVATE*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_INACTIVATE*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_CONTROL_START*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_CONTROL_STOP*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_CONTROL_ABORT*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_ALL_DEPENDENCIES_RESOLVED*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_PUSH*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_EVENT_EOK*/ + SVA_ST_WAIT_FOR_START, /*SVA_ST_EVENT_FAKE*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_EVENT_ACTIVE*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_EVENT_INACTIVE*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_RESET*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_CONTROL_DELETE*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_EVENT_ERROR*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_FLUSH_IN*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_FLUSH_OUT*/ + SVA_ST_FLUSHING_OUT, /*SVA_ST_CANCEL*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_UPDATE_PARAM*/ + SVA_ST_FLUSHING_OUT /*SVA_ST_GET_PARAM_SIZE*/ + }, + /* Current State = SVA_ST_WAIT_FOR_DATA */ + { + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_CREATE*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_CONFIGURE*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_INTERNAL_NEEDS*/ + SVA_ST_WAIT_FOR_DATA, /*SVA_ST_ACTIVATE*/ + SVA_ST_WAIT_FOR_DATA, /*SVA_ST_INACTIVATE*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_CONTROL_START*/ + SVA_ST_STOP_REQUESTED, /*SVA_ST_CONTROL_STOP*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_CONTROL_ABORT*/ + SVA_ST_RUNNING, /*SVA_ST_ALL_DEPENDENCIES_RESOLVED*/ + SVA_ST_WAIT_FOR_DATA, /*SVA_ST_PUSH*/ + SVA_ST_ERROR, /*SVA_ST_EVENT_EOK*/ + SVA_ST_ERROR, /*SVA_ST_EVENT_FAKE*/ + SVA_ST_WAIT_FOR_DATA, /*SVA_ST_EVENT_ACTIVE*/ + SVA_ST_WAIT_FOR_DATA, /*SVA_ST_EVENT_INACTIVE*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_RESET*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_CONTROL_DELETE*/ + SVA_ST_ERROR, /*SVA_ST_EVENT_ERROR*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_FLUSH_IN*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_FLUSH_OUT*/ + SVA_ST_WAIT_FOR_DATA, /*SVA_ST_CANCEL*/ + SVA_ST_WAIT_FOR_DATA, /*SVA_ST_UPDATE_PARAM*/ + SVA_ST_WAIT_FOR_DATA /*SVA_ST_GET_PARAM_SIZE*/ + }, + /* Current State = SVA_ST_RUNNING */ + { + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_CREATE*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_CONFIGURE*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_INTERNAL_NEEDS*/ + SVA_ST_RUNNING, /*SVA_ST_ACTIVATE*/ + SVA_ST_RUNNING, /*SVA_ST_INACTIVATE*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_CONTROL_START*/ + SVA_ST_STOP_REQUESTED, /*SVA_ST_CONTROL_STOP*/ + SVA_ST_ABORT_REQUESTED, /*SVA_ST_CONTROL_ABORT*/ + SVA_ST_RUNNING, /*SVA_ST_ALL_DEPENDENCIES_RESOLVED*/ + SVA_ST_RUNNING, /*SVA_ST_PUSH*/ + SVA_ST_WAIT_FOR_DATA, /*SVA_ST_EVENT_EOK*/ + SVA_ST_ERROR, /*SVA_ST_EVENT_FAKE*/ + SVA_ST_RUNNING, /*SVA_ST_EVENT_ACTIVE*/ + SVA_ST_RUNNING, /*SVA_ST_EVENT_INACTIVE*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_RESET*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_CONTROL_DELETE*/ + SVA_ST_ERROR, /*SVA_ST_EVENT_ERROR*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_FLUSH_IN*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_FLUSH_OUT*/ + SVA_ST_RUNNING, /*SVA_ST_CANCEL*/ + SVA_ST_RUNNING, /*SVA_ST_UPDATE_PARAM*/ + SVA_ST_RUNNING /*SVA_ST_GET_PARAM_SIZE*/ + }, + /* Current State = SVA_ST_ABORT_REQUESTED */ + { + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_CREATE*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_CONFIGURE*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_INTERNAL_NEEDS*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_ACTIVATE*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_INACTIVATE*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_CONTROL_START*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_CONTROL_STOP*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_CONTROL_ABORT*/ + SVA_ST_ABORT_REQUESTED, /*SVA_ST_ALL_DEPENDENCIES_RESOLVED*/ + SVA_ST_ABORT_REQUESTED, /*SVA_ST_PUSH*/ + SVA_ST_ERROR, /*SVA_ST_EVENT_EOK*/ + SVA_ST_ERROR, /*SVA_ST_EVENT_FAKE*/ + SVA_ST_ERROR, /*SVA_ST_EVENT_ACTIVE*/ + SVA_ST_ERROR, /*SVA_ST_EVENT_INACTIVE*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_RESET*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_CONTROL_DELETE*/ + SVA_ST_ERROR, /*SVA_ST_EVENT_ERROR*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_FLUSH_IN*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_FLUSH_OUT*/ + SVA_ST_ABORT_REQUESTED, /*SVA_ST_CANCEL*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_UPDATE_PARAM*/ + SVA_ST_ABORT_REQUESTED /*SVA_ST_GET_PARAM_SIZE*/ + }, + /* Current State = SVA_ST_STOP_REQUESTED */ + { + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_CREATE*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_CONFIGURE*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_INTERNAL_NEEDS*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_ACTIVATE*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_INACTIVATE*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_CONTROL_START*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_CONTROL_STOP*/ + SVA_ST_ABORT_REQUESTED, /*SVA_ST_CONTROL_ABORT*/ + SVA_ST_STOP_REQUESTED, /*SVA_ST_ALL_DEPENDENCIES_RESOLVED*/ + SVA_ST_STOP_REQUESTED, /*SVA_ST_PUSH*/ + SVA_ST_WAIT_FOR_START, /*SVA_ST_EVENT_EOK*/ + SVA_ST_ERROR, /*SVA_ST_EVENT_FAKE*/ + SVA_ST_ERROR, /*SVA_ST_EVENT_ACTIVE*/ + SVA_ST_ERROR, /*SVA_ST_EVENT_INACTIVE*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_RESET*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_CONTROL_DELETE*/ + SVA_ST_ERROR, /*SVA_ST_EVENT_ERROR*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_FLUSH_IN*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_FLUSH_OUT*/ + SVA_ST_STOP_REQUESTED, /*SVA_ST_CANCEL*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_UPDATE_PARAM*/ + SVA_ST_STOP_REQUESTED /*SVA_ST_GET_PARAM_SIZE*/ + }, + /* Current State = SVA_ST_ERROR */ + { + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_CREATE*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_CONFIGURE*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_INTERNAL_NEEDS*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_ACTIVATE*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_INACTIVATE*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_CONTROL_START*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_CONTROL_STOP*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_CONTROL_ABORT*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_ALL_DEPENDENCIES_RESOLVED*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_PUSH*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_EVENT_EOK*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_EVENT_FAKE*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_EVENT_ACTIVE*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_EVENT_INACTIVE*/ + SVA_ST_WAIT_FOR_START, /*SVA_ST_RESET*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_CONTROL_DELETE*/ + SVA_ST_ERROR, /*SVA_ST_EVENT_ERROR*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_FLUSH_IN*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_FLUSH_OUT*/ + SVA_ST_ERROR, /*SVA_ST_CANCEL*/ + SVA_ST_TRANSITION_REJECTED, /*SVA_ST_UPDATE_PARAM*/ + SVA_ST_ERROR /*SVA_ST_GET_PARAM_SIZE*/ + } +}; + +/*activate state machine description*/ +PRIVATE const t_sva_st_activate_state activateStateMachine[SVA_ST_LAST_ACTIVATE_DUMMY_STATE][SVA_ST_LAST_DUMMY_TRANSITION]= { + /* Current State = SVA_ST_INACTIVE */ + { + SVA_ST_INACTIVE, /*SVA_ST_CREATE*/ + SVA_ST_INACTIVE, /*SVA_ST_CONFIGURE*/ + SVA_ST_INACTIVE, /*SVA_ST_INTERNAL_NEEDS*/ + SVA_ST_IN_ACTIVATION, /*SVA_ST_ACTIVATE*/ + SVA_ST_ACTIVATE_TRANSITION_REJECTED, /*SVA_ST_INACTIVATE*/ + SVA_ST_ACTIVATE_TRANSITION_REJECTED, /*SVA_ST_CONTROL_START*/ + SVA_ST_ACTIVATE_TRANSITION_REJECTED, /*SVA_ST_CONTROL_STOP*/ + SVA_ST_ACTIVATE_TRANSITION_REJECTED, /*SVA_ST_CONTROL_ABORT*/ + SVA_ST_INACTIVE, /*SVA_ST_ALL_DEPENDENCIES_RESOLVED*/ + SVA_ST_INACTIVE, /*SVA_ST_PUSH*/ + SVA_ST_INACTIVE, /*SVA_ST_EVENT_EOK*/ + SVA_ST_INACTIVE, /*SVA_ST_EVENT_FAKE*/ + SVA_ST_INACTIVE, /*SVA_ST_EVENT_ACTIVE*/ + SVA_ST_INACTIVE, /*SVA_ST_EVENT_INACTIVE*/ + SVA_ST_INACTIVE, /*SVA_ST_RESET*/ + SVA_ST_INACTIVE, /*SVA_ST_CONTROL_DELETE*/ + SVA_ST_INACTIVE, /*SVA_ST_EVENT_ERROR*/ + SVA_ST_INACTIVE, /*SVA_ST_FLUSH_IN*/ + SVA_ST_INACTIVE, /*SVA_ST_FLUSH_OUT*/ + SVA_ST_ACTIVATE_TRANSITION_REJECTED, /*SVA_ST_CANCEL*/ + SVA_ST_INACTIVE, /*SVA_ST_UPDATE_PARAM*/ + SVA_ST_INACTIVE /*SVA_ST_GET_PARAM_SIZE*/ + }, + /* Current State = SVA_ST_IN_ACTIVATION */ + { + SVA_ST_ACTIVATE_TRANSITION_REJECTED, /*SVA_ST_CREATE*/ + SVA_ST_ACTIVATE_TRANSITION_REJECTED, /*SVA_ST_CONFIGURE*/ + SVA_ST_ACTIVATE_TRANSITION_REJECTED, /*SVA_ST_INTERNAL_NEEDS*/ + SVA_ST_ACTIVATE_TRANSITION_REJECTED, /*SVA_ST_ACTIVATE*/ + SVA_ST_ACTIVATE_TRANSITION_REJECTED, /*SVA_ST_INACTIVATE*/ + SVA_ST_ACTIVATE_TRANSITION_REJECTED, /*SVA_ST_CONTROL_START*/ + SVA_ST_ACTIVATE_TRANSITION_REJECTED, /*SVA_ST_CONTROL_STOP*/ + SVA_ST_ACTIVATE_TRANSITION_REJECTED, /*SVA_ST_CONTROL_ABORT*/ + SVA_ST_IN_ACTIVATION, /*SVA_ST_ALL_DEPENDENCIES_RESOLVED*/ + SVA_ST_IN_ACTIVATION, /*SVA_ST_PUSH*/ + SVA_ST_IN_ACTIVATION, /*SVA_ST_EVENT_EOK*/ + SVA_ST_IN_ACTIVATION, /*SVA_ST_EVENT_FAKE*/ + SVA_ST_ACTIVE, /*SVA_ST_EVENT_ACTIVE*/ + SVA_ST_IN_ACTIVATION, /*SVA_ST_EVENT_INACTIVE*/ + SVA_ST_IN_ACTIVATION, /*SVA_ST_RESET*/ + SVA_ST_ACTIVATE_TRANSITION_REJECTED, /*SVA_ST_CONTROL_DELETE*/ + SVA_ST_IN_ACTIVATION, /*SVA_ST_EVENT_ERROR*/ + SVA_ST_IN_ACTIVATION, /*SVA_ST_FLUSH_IN*/ + SVA_ST_IN_ACTIVATION, /*SVA_ST_FLUSH_OUT*/ + SVA_ST_INACTIVE, /*SVA_ST_CANCEL*/ + SVA_ST_IN_ACTIVATION, /*SVA_ST_UPDATE_PARAM*/ + SVA_ST_IN_ACTIVATION /*SVA_ST_GET_PARAM_SIZE*/ + }, + /* Current State = SVA_ST_ACTIVE */ + { + SVA_ST_ACTIVATE_TRANSITION_REJECTED, /*SVA_ST_CREATE*/ + SVA_ST_ACTIVATE_TRANSITION_REJECTED, /*SVA_ST_CONFIGURE*/ + SVA_ST_ACTIVATE_TRANSITION_REJECTED, /*SVA_ST_INTERNAL_NEEDS*/ + SVA_ST_ACTIVATE_TRANSITION_REJECTED, /*SVA_ST_ACTIVATE*/ + SVA_ST_IN_INACTIVATION, /*SVA_ST_INACTIVATE*/ + SVA_ST_ACTIVE, /*SVA_ST_CONTROL_START*/ + SVA_ST_ACTIVE, /*SVA_ST_CONTROL_STOP*/ + SVA_ST_ACTIVE, /*SVA_ST_CONTROL_ABORT*/ + SVA_ST_ACTIVE, /*SVA_ST_ALL_DEPENDENCIES_RESOLVED*/ + SVA_ST_ACTIVE, /*SVA_ST_PUSH*/ + SVA_ST_ACTIVE, /*SVA_ST_EVENT_EOK*/ + SVA_ST_ACTIVE, /*SVA_ST_EVENT_FAKE*/ + SVA_ST_ACTIVE, /*SVA_ST_EVENT_ACTIVE*/ + SVA_ST_ACTIVE, /*SVA_ST_EVENT_INACTIVE*/ + SVA_ST_ACTIVE, /*SVA_ST_RESET*/ + SVA_ST_INACTIVE, /*SVA_ST_CONTROL_DELETE*/ + SVA_ST_ACTIVE, /*SVA_ST_EVENT_ERROR*/ + SVA_ST_ACTIVE, /*SVA_ST_FLUSH_IN*/ + SVA_ST_ACTIVE, /*SVA_ST_FLUSH_OUT*/ + SVA_ST_ACTIVATE_TRANSITION_REJECTED, /*SVA_ST_CANCEL*/ + SVA_ST_ACTIVE, /*SVA_ST_UPDATE_PARAM*/ + SVA_ST_ACTIVE /*SVA_ST_GET_PARAM_SIZE*/ + }, + /* Current State = SVA_ST_IN_INACTIVATION */ + { + SVA_ST_ACTIVATE_TRANSITION_REJECTED, /*SVA_ST_CREATE*/ + SVA_ST_ACTIVATE_TRANSITION_REJECTED, /*SVA_ST_CONFIGURE*/ + SVA_ST_ACTIVATE_TRANSITION_REJECTED, /*SVA_ST_INTERNAL_NEEDS*/ + SVA_ST_ACTIVATE_TRANSITION_REJECTED, /*SVA_ST_ACTIVATE*/ + SVA_ST_ACTIVATE_TRANSITION_REJECTED, /*SVA_ST_INACTIVATE*/ + SVA_ST_ACTIVATE_TRANSITION_REJECTED, /*SVA_ST_CONTROL_START*/ + SVA_ST_ACTIVATE_TRANSITION_REJECTED, /*SVA_ST_CONTROL_STOP*/ + SVA_ST_ACTIVATE_TRANSITION_REJECTED, /*SVA_ST_CONTROL_ABORT*/ + SVA_ST_IN_INACTIVATION, /*SVA_ST_ALL_DEPENDENCIES_RESOLVED*/ + SVA_ST_IN_INACTIVATION, /*SVA_ST_PUSH*/ + SVA_ST_IN_INACTIVATION, /*SVA_ST_EVENT_EOK*/ + SVA_ST_IN_INACTIVATION, /*SVA_ST_EVENT_FAKE*/ + SVA_ST_IN_INACTIVATION, /*SVA_ST_EVENT_ACTIVE*/ + SVA_ST_INACTIVE, /*SVA_ST_EVENT_INACTIVE*/ + SVA_ST_INACTIVE, /*SVA_ST_RESET*/ + SVA_ST_ACTIVATE_TRANSITION_REJECTED, /*SVA_ST_CONTROL_DELETE*/ + SVA_ST_IN_INACTIVATION, /*SVA_ST_EVENT_ERROR*/ + SVA_ST_IN_INACTIVATION, /*SVA_ST_FLUSH_IN*/ + SVA_ST_IN_INACTIVATION, /*SVA_ST_FLUSH_OUT*/ + SVA_ST_ACTIVE, /*SVA_ST_CANCEL*/ + SVA_ST_IN_INACTIVATION, /*SVA_ST_UPDATE_PARAM*/ + SVA_ST_IN_INACTIVATION /*SVA_ST_GET_PARAM_SIZE*/ + } +}; + +/*------------------------------------------------------------------------ + * Private functions prototype + *----------------------------------------------------------------------*/ +PRIVATE t_sva_st_error sva_ST_ResolveDependencies(t_sva_service_instance_num ); +PRIVATE t_sva_st_state sva_ST_UpdateInstanceStateMachine(t_sva_service_instance_num ,t_sva_st_transition ); +PRIVATE t_bool sva_ST_isTransitionValid(t_sva_service_instance_num ,t_sva_st_transition ); +PRIVATE t_sva_error sva_ST_CheckServiceId(t_sva_service_id ); +PRIVATE t_sva_error sva_ST_DoReset(t_sva_service_id ); +PRIVATE t_sva_error sva_ST_DoFlushIn(t_sva_service_id ); +PRIVATE t_sva_error sva_ST_DoFlushOut(t_sva_service_id ); +PRIVATE t_sva_st_error sva_ST_ResetStatus(t_sva_sw_processing_status *); +PRIVATE void sva_ST_ResetDescriptor(t_sva_st_descriptor *); +PRIVATE t_bool sva_ST_IsConfigurationValid(const t_sva_sw_processing_configuration *); +PRIVATE t_sva_error sva_ST_AllocateMemoryAndLink(t_sva_service_instance_num); +PRIVATE t_sva_error sva_ST_BuildParamInStructure(const t_sva_sw_processing_configuration * ,t_sva_vec_stab_param_in *); + +/****************************************************************************/ +/* NAME: t_sva_error sva_ST_Init ( void ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine initialize the Stab Management module. */ +/* 1) Set state of instance to SVA_SERVICE_NOT_INITIALIZED */ +/* 2) init fifos */ +/* 3) Init descriptor for all instances */ +/* */ +/* PARAMETERS: */ +/* IN : none */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/* - always SVA_OK */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + * DONE +*/ +PUBLIC t_sva_error sva_ST_Init( + t_sva_block_id blockId, + t_size blockSize +) +{ + t_uint32 i; + + /*init all encode instances*/ + for(i=0;iconf=*pConf; + + /* Update the state machine */ + sva_ST_UpdateInstanceStateMachine(instanceNum,SVA_ST_CONFIGURE); + + return SVA_OK; +} + +/****************************************************************************/ +/* NAME: t_sva_error sva_ST_GetInternalNeeds( */ +/* t_sva_service_id serviceId, */ +/* t_size* pNeedsSize */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine returns the size of the memory needed for Stab */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - serviceId: identifier of the service */ +/* - pNeedsSize: size needed */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/* - SVA_OK : Command taken into account */ +/* - SVA_UNKNOWN_SERVICE_ID : service id is not correct */ +/* */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + DONE +*/ +PUBLIC t_sva_error sva_ST_GetInternalNeeds( + t_sva_service_id serviceId, + t_size *pNeedsSize +) +{ + t_sva_error status; + t_uint32 fifoSize; + + /*check for service id validity*/ + status=sva_ST_CheckServiceId(serviceId); + if (status!=SVA_OK) {return status;} + + /*check pointer validity*/ + ST_CHECK_NULL_POINTER(pNeedsSize); + + /*compute memory size need*/ + *pNeedsSize = 0; + /*memory need by event management*/ + status=sva_EM_GetInternalNeeds(pNeedsSize); + if (status!=SVA_OK) {return status;} + /*note that we allocate PUSH_FIFO_DEFAULT_SIZE + SUBTASK_DEFAULT_NUMBER slot for push fifo*/ + /*We do that to allow push reverse during flush in/out*/ + /*memory need due to input image buffer*/ + GET_FIFO_MEMORY_NEEDS(t_sva_buffer_id, PUSH_FIFO_DEFAULT_SIZE + SUBTASK_DEFAULT_NUMBER, fifoSize); + *pNeedsSize+=fifoSize; + GET_FIFO_MEMORY_NEEDS(t_sva_buffer_id, SUBTASK_DEFAULT_NUMBER, fifoSize); + *pNeedsSize+=fifoSize; + /*memory need due to output param buffer*/ + GET_FIFO_MEMORY_NEEDS(t_sva_buffer_id, PUSH_FIFO_DEFAULT_SIZE + SUBTASK_DEFAULT_NUMBER, fifoSize); + *pNeedsSize+=fifoSize; + GET_FIFO_MEMORY_NEEDS(t_sva_buffer_id, SUBTASK_DEFAULT_NUMBER, fifoSize); + *pNeedsSize+=fifoSize; + /*memory need due to refImageFifos*/ + GET_FIFO_MEMORY_NEEDS(t_sva_buffer_id, PUSH_FIFO_DEFAULT_SIZE + SUBTASK_DEFAULT_NUMBER, fifoSize); + *pNeedsSize+=fifoSize; + GET_FIFO_MEMORY_NEEDS(t_sva_buffer_id, SUBTASK_DEFAULT_NUMBER, fifoSize); + *pNeedsSize+=fifoSize; + /*memory need due to subtask dependency fifo*/ + GET_FIFO_MEMORY_NEEDS(t_sva_st_subtask_dependencies, SUBTASK_DEFAULT_NUMBER, fifoSize); + *pNeedsSize+=fifoSize; + + return SVA_OK; +} + +/****************************************************************************/ +/* NAME: t_sva_error sva_ST_ProvideInternalNeeds ( */ +/* t_sva_service_id serviceId */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine allows to end the configuration of the service since */ +/* memory need has been provide by user. */ +/* - create fifos */ +/* - create subtasks */ +/* - create subtasklist */ +/* - enable events */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - serviceId: identifier of the service */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/* - SVA_OK : Command taken into account */ +/* - SVA_UNKNOWN_SERVICE_ID : service id is not correct */ +/* - SVA_UNEXPECTED_API_CALL : Command cannot be excecuted in */ +/* current context. */ +/* - SVA_INTERNAL_SWPROCESSOR_ERROR : internal error */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + DONE +*/ +PUBLIC t_sva_error sva_ST_ProvideInternalNeeds(t_sva_service_id serviceId) +{ + t_sva_error status; + t_sva_service_instance_num instanceNum = READ_INSTANCE_NUM_IN_SERVICE_ID(serviceId); + t_sva_st_descriptor *pDesc=&stabDesc[instanceNum]; + t_sva_sw_processing_configuration *pConf=&pDesc->conf; + t_sva_ff_error ffError; + t_sva_tm_error tmError; + t_sva_vec_stab_param_in paramInBuffer; + t_sva_tm_task_ctrl_desc stabTaskDesc; + t_uint32 i; + + /*check for service id validity*/ + status=sva_ST_CheckServiceId(serviceId); + if (status!=SVA_OK) {return status;} + + /*check that transition is allowed*/ + if (sva_ST_isTransitionValid(instanceNum,SVA_ST_INTERNAL_NEEDS)==FALSE) {return SVA_UNEXPECTED_API_CALL;} + + /*provide some memory to event management*/ + status=sva_EM_ProvideInternalNeeds(serviceId); + if (status!=SVA_OK) {return status;} + + /*create fifo*/ + CREATE_FIFO(t_sva_buffer_id, PUSH_FIFO_DEFAULT_SIZE + SUBTASK_DEFAULT_NUMBER, pDesc->inputImageFifos.pushFifo, ffError); + if (ffError != SVA_FIFO_OK) {return SVA_INTERNAL_SWPROCESSOR_ERROR;} + CREATE_FIFO(t_sva_buffer_id, SUBTASK_DEFAULT_NUMBER, pDesc->inputImageFifos.inUseFifo, ffError); + if (ffError != SVA_FIFO_OK) {return SVA_INTERNAL_SWPROCESSOR_ERROR;} + CREATE_FIFO(t_sva_buffer_id, PUSH_FIFO_DEFAULT_SIZE + SUBTASK_DEFAULT_NUMBER, pDesc->refImageFifos.pushFifo, ffError); + if (ffError != SVA_FIFO_OK) {return SVA_INTERNAL_SWPROCESSOR_ERROR;} + CREATE_FIFO(t_sva_buffer_id, SUBTASK_DEFAULT_NUMBER, pDesc->refImageFifos.inUseFifo, ffError); + if (ffError != SVA_FIFO_OK) {return SVA_INTERNAL_SWPROCESSOR_ERROR;} + CREATE_FIFO(t_sva_buffer_id, PUSH_FIFO_DEFAULT_SIZE + SUBTASK_DEFAULT_NUMBER, pDesc->stabParamFifos.pushFifo, ffError); + if (ffError != SVA_FIFO_OK) {return SVA_INTERNAL_SWPROCESSOR_ERROR;} + CREATE_FIFO(t_sva_buffer_id, SUBTASK_DEFAULT_NUMBER, pDesc->stabParamFifos.inUseFifo, ffError); + if (ffError != SVA_FIFO_OK) {return SVA_INTERNAL_SWPROCESSOR_ERROR;} + CREATE_FIFO(t_sva_st_subtask_dependencies, SUBTASK_DEFAULT_NUMBER, pDesc->subtasksDependencyFifo, ffError); + if (ffError != SVA_FIFO_OK) {return SVA_INTERNAL_SWPROCESSOR_ERROR;} + + /*create subtasks*/ + stabTaskDesc.memId=STAB_DEFAULT_MEMORY_ID; + stabTaskDesc.fieldnb=STAB_FIELD_NUMBER; + stabTaskDesc.pfieldctrldesc=(t_sva_tm_field_ctrl_desc *)defaultStabFieldDescArray; + for(i=0;isubtasksIdArray[i]); + if (tmError != SVA_TM_OK) {return SVA_INTERNAL_SWPROCESSOR_ERROR;} + } + + /*create subtasklist*/ + + tmError=sva_TM_CreateSubTaskList(SVA_TM_ENCODE,serviceId,SVA_FW_FEAT_MPEG4_ENCODER,&pDesc->subtasksListId); + + if (tmError != SVA_TM_OK) {return SVA_INTERNAL_SWPROCESSOR_ERROR;} + + /* enable events for sub task list*/ + /* we enable EOT, ERR and EOK event*/ + /* we also enable activate, inactivate and fake event*/ + tmError=sva_TM_DisableAllVirtualHwEvents(pDesc->subtasksListId); + if (tmError != SVA_TM_OK) {return SVA_INTERNAL_SWPROCESSOR_ERROR;} + tmError=sva_TM_EnableVirtualHwEvents(pDesc->subtasksListId,SVA_TM_EOT_HW_EVENT); + if (tmError != SVA_TM_OK) {return SVA_INTERNAL_SWPROCESSOR_ERROR;} + tmError=sva_TM_EnableVirtualHwEvents(pDesc->subtasksListId,SVA_TM_ERR_HW_EVENT); + if (tmError != SVA_TM_OK) {return SVA_INTERNAL_SWPROCESSOR_ERROR;} + tmError=sva_TM_EnableVirtualHwEvents(pDesc->subtasksListId,SVA_TM_EOK_HW_EVENT); + if (tmError != SVA_TM_OK) {return SVA_INTERNAL_SWPROCESSOR_ERROR;} + tmError=sva_TM_EnableVirtualHwEvents(pDesc->subtasksListId,SVA_TM_INACTIVE_HW_EVENT); + if (tmError != SVA_TM_OK) {return SVA_INTERNAL_SWPROCESSOR_ERROR;} + tmError=sva_TM_EnableVirtualHwEvents(pDesc->subtasksListId,SVA_TM_ACTIVE_HW_EVENT); + if (tmError != SVA_TM_OK) {return SVA_INTERNAL_SWPROCESSOR_ERROR;} + tmError=sva_TM_EnableVirtualHwEvents(pDesc->subtasksListId,SVA_TM_FAKE_HW_EVENT); + if (tmError != SVA_TM_OK) {return SVA_INTERNAL_SWPROCESSOR_ERROR;} + + /*initialize paramin of subtasks*/ + status=sva_ST_BuildParamInStructure(pConf,¶mInBuffer); + if (status!=SVA_OK) {return status;} + for(i=0;isubtasksIdArray[i],SVA_TM_ENC_ADDR_IN_PARAMETERS, + (t_logical_address)¶mInBuffer,sizeof(t_sva_grb_param_in)); + if (tmError != SVA_TM_OK) {return SVA_INTERNAL_SWPROCESSOR_ERROR;} + } + + /* init window buffer address */ + for(i=0;iesRamBlockId,&internalBuffer.addr_search_window_buffer); + internalBuffer.addr_search_window_end=internalBuffer.addr_search_window_buffer+pDesc->esRamSize; + if (mmError!=SVA_MM_OK) {return SVA_INTERNAL_SWPROCESSOR_ERROR;} + + /*update this field in subtask*/ + tmError=sva_TM_UpdateSubTaskField(SVA_TM_INTERMEDIATE_FIELD_TO_UPDATE,/*don't take sem since task is not scheduled*/ + pDesc->subtasksIdArray[i], SVA_TM_ENC_ADDR_INTERNAL_BUFFER, + FCMD_COPY,(t_uint32) &internalBuffer.addr_search_window_buffer,HCL_BITFIELD_OFFSET(t_sva_vec_internal_buffer,addr_search_window_buffer), + sizeof(internalBuffer.addr_search_window_buffer)+sizeof(internalBuffer.addr_search_window_end)); + if (tmError!=SVA_TM_OK) {return SVA_INTERNAL_SWPROCESSOR_ERROR;} + } + + /* Set default dependencies*/ + pDesc->defaultDep.inputImageDep=NOT_RESOLVED_DEPENDENCY; + pDesc->defaultDep.stabParamDep=NOT_RESOLVED_DEPENDENCY; + pDesc->defaultDep.refImageDep=NOT_RESOLVED_DEPENDENCY; + + /* Allocate internal video memory need if needed*/ + status=sva_ST_AllocateMemoryAndLink(instanceNum); + if (status!=SVA_OK) {return SVA_INTERNAL_VIDEO_ENCODER_ERROR;} + + /* Push subtask in subtasksDependencyFifo since they are ready to be solved*/ + for(i=0;isubtasksIdArray[i]; + subtaskDep.dependencies=pDesc->defaultDep; + /*for first subtask reference image is said to be solved*/ + if (i==0) {subtaskDep.dependencies.refImageDep=RESOLVED_DEPENDENCY;} + ffError=PUSH_FIFO_ELEM(pDesc->subtasksDependencyFifo, t_sva_st_subtask_dependencies, subtaskDep); + if (ffError!=SVA_FIFO_OK) {return SVA_INTERNAL_SWPROCESSOR_ERROR;} + } + + /* Update the state machine */ + sva_ST_UpdateInstanceStateMachine(instanceNum,SVA_ST_INTERNAL_NEEDS); + + return SVA_OK; +} + +/****************************************************************************/ +/* NAME: t_sva_error sva_ST_Activate( */ +/* t_sva_service_id serviceId, */ +/* t_sva_service_mode serviceMode, */ +/* t_sva_fw_id *pFwId */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine activates the stab service */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - serviceId: identifier of the service */ +/* - serviceMode : set service to real_time or not */ +/* */ +/* OUT : */ +/* - pFwId : identifier of firmware id for which user shall provide location*/ +/* */ +/* RETURN: */ +/* t_sva_error */ +/* - SVA_OK : Command taken into account */ +/* - SVA_UNKNOWN_SERVICE_ID : service id is not correct */ +/* - SVA_UNEXPECTED_API_CALL : Command cannot be excecuted in */ +/* current context. */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + * DONE +*/ +PUBLIC t_sva_error sva_ST_Activate( + t_sva_service_id serviceId, + t_sva_service_mode serviceMode, + t_sva_fw_id *pFwId +) +{ + t_sva_error status; + t_sva_service_instance_num instanceNum = READ_INSTANCE_NUM_IN_SERVICE_ID(serviceId); + t_sva_st_descriptor *pDesc=&stabDesc[instanceNum]; + + ST_CHECK_NULL_POINTER(pFwId); + + /*check for service id validity*/ + status=sva_ST_CheckServiceId(serviceId); + if (status!=SVA_OK) {return status;} + + /*check that transition is allowed*/ + if (sva_ST_isTransitionValid(instanceNum,SVA_ST_ACTIVATE)==FALSE) {return SVA_UNEXPECTED_API_CALL;} + + /* Update the state machine */ + /* Update state machine before command is send to task management to avoid race condition */ + sva_ST_UpdateInstanceStateMachine(instanceNum,SVA_ST_ACTIVATE); + + /*activate subTaskList*/ + /*handle informative error code*/ + status=sva_TM_ActivateSubTaskList(pDesc->subtasksListId,serviceMode,pFwId); + if (status != SVA_OK && status != SVA_FW_SWITCH_OCCURED && status != SVA_FW_SWITCH_DELAYED) + { + sva_ST_UpdateInstanceStateMachine(instanceNum,SVA_ST_CANCEL); + + return status; + } + + return status; +} + +/****************************************************************************/ +/* NAME: t_sva_error sva_ST_Inactivate( */ +/* t_sva_service_id serviceId */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine deactivates the stab service */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - serviceId: identifier of the service */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/* - SVA_OK : Command taken into account */ +/* - SVA_UNKNOWN_SERVICE_ID : service id is not correct */ +/* - SVA_UNEXPECTED_API_CALL : Command cannot be excecuted in */ +/* current context. */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + * DONE +*/ +PUBLIC t_sva_error sva_ST_Inactivate(t_sva_service_id serviceId) +{ + t_sva_error status; + t_sva_service_instance_num instanceNum = READ_INSTANCE_NUM_IN_SERVICE_ID(serviceId); + t_sva_st_descriptor *pDesc=&stabDesc[instanceNum]; + t_sva_tm_error tmError; + + /*check for service id validity*/ + status=sva_ST_CheckServiceId(serviceId); + if (status!=SVA_OK) {return status;} + + /*check that transition is allowed*/ + if (sva_ST_isTransitionValid(instanceNum,SVA_ST_INACTIVATE)==FALSE) {return SVA_UNEXPECTED_API_CALL;} + + /* Update the state machine */ + /* Update state machine before command is send to task management to avoid race condition */ + sva_ST_UpdateInstanceStateMachine(instanceNum,SVA_ST_INACTIVATE); + + /*inactivate subTaskList*/ + /*handle informative error code*/ + tmError=sva_TM_InActivateSubTaskList(pDesc->subtasksListId); + if (tmError != SVA_TM_OK) + { + sva_ST_UpdateInstanceStateMachine(instanceNum,SVA_ST_CANCEL); + + return SVA_INTERNAL_SWPROCESSOR_ERROR; + } + + return SVA_OK; +} + +/****************************************************************************/ +/* NAME: t_sva_error sva_ST_Control ( */ +/* t_sva_service_id serviceId, */ +/* t_sva_service_cmd_id cmdId, */ +/* t_uint32 param */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine allows to control an instance of a stab Service */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - serviceId: identifier of the given service */ +/* - cmdId: command to apply to the encode */ +/* - param: parameter use by command */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/* - SVA_OK : Command taken into account */ +/* - SVA_UNKNOWN_SERVICE_ID : service id is not correct */ +/* - SVA_UNEXPECTED_API_CALL : Command cannot be excecuted in */ +/* current context. */ +/* - SVA_UNKNOWN_CMD_ID : Command to execute is unknown */ +/* - SVA_INTERNAL_SWPROCESSOR_ERROR : internal error */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + DONE +*/ +PUBLIC t_sva_error sva_ST_Control( + t_sva_service_id serviceId, + t_sva_service_cmd_id cmdId, + t_uint32 param +) +{ + t_sva_service_instance_num instanceNum = READ_INSTANCE_NUM_IN_SERVICE_ID(serviceId); + t_sva_st_descriptor *pDesc=&stabDesc[instanceNum]; + t_sva_error status = SVA_UNEXPECTED_API_CALL; + t_sva_error error; + t_sva_tm_error tmError; + + /*check for service id validity*/ + error=sva_ST_CheckServiceId(serviceId); + if (error!=SVA_OK) {return error;} + +#ifdef __DEBUG + { + t_uint32 systemTime; + + SVA_GetServiceSystemTime(serviceId,&systemTime); + commandStabDebugTable[instanceNum].commandDebugDesc[commandStabDebugTable[instanceNum].nbOfCommandReceived%LOG_DEPTH].command=cmdId; + commandStabDebugTable[instanceNum].commandDebugDesc[commandStabDebugTable[instanceNum].nbOfCommandReceived%LOG_DEPTH].systemTime=systemTime; + commandStabDebugTable[instanceNum].commandDebugDesc[commandStabDebugTable[instanceNum].nbOfCommandReceived%LOG_DEPTH].parameter=param; + commandStabDebugTable[instanceNum].nbOfCommandReceived++; + } +#endif + + /*handle command*/ + switch(cmdId) + { + case SVA_SERVICE_START: + if (sva_ST_isTransitionValid(instanceNum,SVA_ST_CONTROL_START)==TRUE) + { + /* transition are force before sending task command to avoid race condition*/ + sva_ST_UpdateInstanceStateMachine(instanceNum,SVA_ST_CONTROL_START); + /* as we accepted some push before (or after a restart) some dependencies are perhaps + already scheduled + */ + if (GET_FIFO_NB_ELEMS(pDesc->subtasksDependencyFifo)!=SUBTASK_DEFAULT_NUMBER) + { + sva_ST_UpdateInstanceStateMachine(instanceNum,SVA_ST_ALL_DEPENDENCIES_RESOLVED); + } + /*now send start command*/ + tmError=sva_TM_SendTaskCommand(pDesc->subtasksListId,SVA_TM_TCMD_START,param); + HCL_DEBUG_ASSERT(tmError==SVA_TM_OK); + + status = SVA_OK; + } + break; + case SVA_SERVICE_STOP: + if (sva_ST_isTransitionValid(instanceNum,SVA_ST_CONTROL_STOP)==TRUE) + { + /* transition are force before sending task command to avoid race condition*/ + sva_ST_UpdateInstanceStateMachine(instanceNum,SVA_ST_CONTROL_STOP); + /*stop subtask list*/ + tmError=sva_TM_SendTaskCommand(pDesc->subtasksListId,SVA_TM_TCMD_STOP,param); + HCL_DEBUG_ASSERT(tmError==SVA_TM_OK); + + status = SVA_OK; + } + break; + case SVA_SERVICE_ABORT: + if (sva_ST_isTransitionValid(instanceNum,SVA_ST_CONTROL_ABORT)==TRUE) + { + /* transition are force before sending task command to avoid race condition*/ + sva_ST_UpdateInstanceStateMachine(instanceNum,SVA_ST_CONTROL_ABORT); + /*abort subtask list*/ + tmError=sva_TM_SendTaskCommand(pDesc->subtasksListId,SVA_TM_TCMD_ABORT,param); + HCL_DEBUG_ASSERT(tmError==SVA_TM_OK); + + status = SVA_OK; + } + break; + case SVA_SERVICE_RESET: + if (sva_ST_isTransitionValid(instanceNum,SVA_ST_RESET)==TRUE) + { + /*do instance clean-up so service can restart*/ + status = sva_ST_DoReset(serviceId); + if (status == SVA_OK) + { + sva_ST_UpdateInstanceStateMachine(instanceNum,SVA_ST_RESET); + } + } + break; + case SVA_SERVICE_FLUSH_IN: + if (sva_ST_isTransitionValid(instanceNum,SVA_ST_FLUSH_IN)==TRUE) + { + /*flush output buffer if necessary*/ + status = sva_ST_DoFlushIn(serviceId); + if (status == SVA_OK) + { + sva_ST_UpdateInstanceStateMachine(instanceNum,SVA_ST_FLUSH_IN); + /*generate a fake event since flush command is asynchronous*/ + sva_TM_SendTaskCommand(pDesc->subtasksListId,SVA_TM_TCMD_FAKE_EVENT,param); + } + } + break; + case SVA_SERVICE_FLUSH_OUT: + if (sva_ST_isTransitionValid(instanceNum,SVA_ST_FLUSH_OUT)==TRUE) + { + /*flush output buffer if necessary*/ + status = sva_ST_DoFlushOut(serviceId); + if (status == SVA_OK) + { + sva_ST_UpdateInstanceStateMachine(instanceNum,SVA_ST_FLUSH_OUT); + /*generate a fake event since flush command is asynchronous*/ + sva_TM_SendTaskCommand(pDesc->subtasksListId,SVA_TM_TCMD_FAKE_EVENT,param); + } + } + break; + /*unknown command*/ + default: + status = SVA_UNKNOWN_CMD_ID; + break; + } + + return status; +} + +/****************************************************************************/ +/* NAME: t_sva_error SVA_UpdateSwProcessingParams( */ +/* t_sva_service_id serviceId, */ +/* t_sva_update_cmd_type updateCmdType, */ +/* t_sva_sw_processing_param_id paramId, */ +/* t_uint32 param */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine allows to update params for an instance of a stab */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - serviceId: identifier of the given service */ +/* - updateCmdType: command to apply to the Stab */ +/* - paramd: value of timeStamp */ +/* - param: parameter for the cmdType */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/* - SVA_OK : Command taken into account */ +/* - SVA_UNKNOWN_SERVICE_ID : service id is not correct */ +/* - SVA_UNEXPECTED_API_CALL : Command cannot be excecuted in */ +/* current context. */ +/* - SVA_INTERNAL_SWPROCESSOR_ERROR : internal error */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + TO DO : + - add command +*/ +PUBLIC t_sva_error SVA_UpdateSwProcessingParams( + t_sva_service_id serviceId, + t_sva_update_cmd_type updateCmdType, + t_sva_sw_processing_param_id paramId, + t_uint32 param + ) +{ + t_sva_service_instance_num instanceNum = READ_INSTANCE_NUM_IN_SERVICE_ID(serviceId); + t_sva_error status; + + /*check for service id validity*/ + status=sva_ST_CheckServiceId(serviceId); + if (status!=SVA_OK) {return status;} + + /*check that transition is allowed*/ + if (sva_ST_isTransitionValid(instanceNum,SVA_ST_UPDATE_PARAM)==FALSE) {return SVA_UNEXPECTED_API_CALL;} + + status=SVA_NOT_SUPPORTED_YET; + + /*update state machine => do nothing*/ + sva_ST_UpdateInstanceStateMachine(instanceNum,SVA_ST_UPDATE_PARAM); + + return status; +} + +/****************************************************************************/ +/* NAME: t_sva_error sva_ST_Push( */ +/* t_sva_service_id serviceId, */ +/* t_sva_buffer_id bufferId, */ +/* t_sva_push_mode pushMode, */ +/* t_sva_buffer_type bufferType, */ +/* t_sva_timestamp timeStamp */ +/* ) */ +/*--------------------------------------------------------------------------*/ + /* DESCRIPTION: */ + /* This routine allows to push data in a Stab service */ +/* - it will check buffer has enought size according to conf/algo */ +/* - it will push it in the corresponding pushFifo fifo */ +/* - update status of buffer */ +/* - try to solve some dependencies */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - serviceId: identifier of the service */ +/* - bufferId: identifier of the buffer */ +/* - pushMode: PUSH_IN/PUSH_OUT */ +/* - bufferType: */ +/* - timeStamp: */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/* - SVA_OK : Command taken into account */ +/* - SVA_UNKNOWN_SERVICE_ID : service id is not correct */ +/* - SVA_UNEXPECTED_API_CALL : Command cannot be excecuted in */ +/* current context. */ +/* - SVA_INTERNAL_SWPROCESSOR_ERROR : internal error */ +/* - SVA_INVALID_BUFFER_TYPE : buffer type is not handle by grab */ +/* - SVA_INTERNAL_FIFOS_FULL : internal fifos are full */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + DONE +*/ +PUBLIC t_sva_error sva_ST_Push( + t_sva_service_id serviceId, + t_sva_buffer_id bufferId, + t_sva_push_mode pushMode, + t_sva_buffer_type bufferType, + t_sva_timestamp timeStamp +) +{ + t_sva_service_instance_num instanceNum = READ_INSTANCE_NUM_IN_SERVICE_ID(serviceId); + t_sva_st_descriptor *pDesc=&stabDesc[instanceNum]; + const t_sva_sw_processing_configuration *pConf = &pDesc->conf; + t_sva_error status; + t_sva_bm_error bmError; + t_sva_ff_error ffError; + t_sva_st_error stError; + t_size bufferSize; + t_size minSize=0; + + /*check for service id validity*/ + status=sva_ST_CheckServiceId(serviceId); + if (status!=SVA_OK) {return status;} + + /*check that transition is allowed*/ + if (sva_ST_isTransitionValid(instanceNum,SVA_ST_PUSH)==FALSE) {return SVA_UNEXPECTED_API_CALL;} + + /*handle provide buffer*/ + switch(bufferType) + { + case SVA_IMAGE_BUFFER_TYPE: + if (pushMode != SVA_PUSH_IN) return SVA_UNEXPECTED_API_CALL; // image buffer must be pushed in only + minSize = ((((t_uint32)pConf->originalPicture.height * (t_uint32)pConf->originalPicture.width)*3)/2); + + /*read buffer size*/ + bmError=sva_BM_GetBufferSize(bufferId,&bufferSize); + if (bmError!=SVA_BM_OK) {return SVA_INTERNAL_SWPROCESSOR_ERROR;} + /*check buffer has enought space*/ + if (bufferSize>=minSize) + { + /*check space into fifo*/ + if (GET_FIFO_NB_ELEMS(pDesc->inputImageFifos.pushFifo) >= PUSH_FIFO_DEFAULT_SIZE) {status=SVA_INTERNAL_FIFOS_FULL;} + ffError=PUSH_FIFO_ELEM(pDesc->inputImageFifos.pushFifo, t_sva_buffer_id, bufferId); + if (ffError!=SVA_FIFO_OK) {status=SVA_INTERNAL_FIFOS_FULL;} + if (GET_FIFO_NB_ELEMS(pDesc->refImageFifos.pushFifo) >= PUSH_FIFO_DEFAULT_SIZE) {status=SVA_INTERNAL_FIFOS_FULL;} + ffError=PUSH_FIFO_ELEM(pDesc->refImageFifos.pushFifo, t_sva_buffer_id, bufferId); + if (ffError!=SVA_FIFO_OK) {status=SVA_INTERNAL_FIFOS_FULL;} + else + { + pDesc->status.bufferizationStats.inLevel++; + status=SVA_OK; + } + } + else { status=SVA_INTERNAL_SWPROCESSOR_ERROR; } + break; + case SVA_PARAMS_BUFFER_TYPE: + if (pushMode != SVA_PUSH_OUT) return SVA_UNEXPECTED_API_CALL; // param buffer must be pushed out only + minSize = sizeof(t_sva_offset_desc); + + /*read buffer size*/ + bmError=sva_BM_GetBufferSize(bufferId,&bufferSize); + if (bmError!=SVA_BM_OK) {return SVA_INTERNAL_SWPROCESSOR_ERROR;} + /*check buffer has enought space*/ + if (bufferSize>=minSize) + { + /*check space into fifo*/ + if (GET_FIFO_NB_ELEMS(pDesc->stabParamFifos.pushFifo) >= PUSH_FIFO_DEFAULT_SIZE) {status=SVA_INTERNAL_FIFOS_FULL;} + ffError=PUSH_FIFO_ELEM(pDesc->stabParamFifos.pushFifo, t_sva_buffer_id, bufferId); + if (ffError!=SVA_FIFO_OK) {status=SVA_INTERNAL_FIFOS_FULL;} + else + { + pDesc->status.bufferizationStats.outLevel++; + status=SVA_OK; + } + } + else { status=SVA_INTERNAL_SWPROCESSOR_ERROR; } + break; + default: + status=SVA_INVALID_BUFFER_TYPE; + break; + } + + /*update state machine*/ + sva_ST_UpdateInstanceStateMachine(instanceNum,SVA_ST_PUSH); + + /*update buffer status if we have succeeded to push it and try to solve dependencies*/ + if (status == SVA_OK) + { + t_uint32 systemTime; + t_sva_error svaError; + + svaError=SVA_GetServiceSystemTime(serviceId,&systemTime); + if (svaError!=SVA_OK) {return SVA_INTERNAL_SWPROCESSOR_ERROR;} + bmError=sva_BM_UpdateBufferStatus(bufferId, SVA_BUFFER_IN_USE, systemTime); + if (bmError!=SVA_BM_OK) {return SVA_INTERNAL_SWPROCESSOR_ERROR;} + stError=sva_ST_ResolveDependencies(instanceNum); + if (stError!=SVA_ST_OK) {return SVA_INTERNAL_SWPROCESSOR_ERROR;} + } + + return status; +} + +/****************************************************************************/ +/* NAME: t_sva_error SVA_GetSwProcessingStatus ( */ +/* t_sva_service_id serviceId, */ +/* t_sva_sw_processing_status * pStatus */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine allows to get status of the stab service */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - serviceId: identifier of the service */ +/* - pStatus: status for the stab service */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/* - SVA_OK : Command taken into account */ +/* - SVA_UNKNOWN_SERVICE_ID : service id is not correct */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + DONE +*/ +PUBLIC t_sva_error SVA_GetSwProcessingStatus( + t_sva_service_id serviceId, + t_sva_sw_processing_status *pStatus +) +{ + t_sva_service_instance_num instanceNum = READ_INSTANCE_NUM_IN_SERVICE_ID(serviceId); + t_sva_st_descriptor *pDesc=&stabDesc[instanceNum]; + t_sva_error status; + + ST_CHECK_NULL_POINTER(pStatus); + + /*check for service id validity*/ + status=sva_ST_CheckServiceId(serviceId); + if (status!=SVA_OK) {return status;} + + /*copy status*/ + *pStatus=pDesc->status; + + return SVA_OK; +} + +/****************************************************************************/ +/* NAME: t_sva_ec_error sva_ST_DispatchVirtualHwEvent( */ +/* t_sva_virtual_hw_event_id eventId, */ +/* t_sva_service_id serviceId, */ +/* t_sva_tm_subtask_id subtaskId, */ +/* t_uint32 eventTimestamp, */ +/* t_uint32 eventDate, */ +/* t_uint8 maxOfEvent, */ +/* t_sva_event_desc *pEventDesc, */ +/* t_uint32 *pNbEvent */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine allows to dispatch event of the stab service */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - eventId: event identifier */ +/* - serviceId: identifier of the service */ +/* - subtaskId: identifier of the subtask for which is the event */ +/* - eventTimestamp: time at which the event occur (system time unit) */ +/* - eventDate: time at which the event occur (ticks time unit) */ +/* - maxOfEvent: nb of event max contained in EventDesc */ +/* - pEventDesc: structure of Events */ +/* - pNbEvent: nb of event into EventDesc */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_st_error */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ + +PUBLIC t_sva_st_error sva_ST_DispatchVirtualHwEvent( + t_sva_tm_virtual_hw_event_id eventId, + t_sva_service_id serviceId, + t_sva_tm_subtask_id subtaskId, + t_uint32 eventTimestamp, + t_uint32 eventDate, + t_uint8 maxOfEvent, + t_sva_event_desc *pEventDesc, + t_uint32 *pNbEvent +) +{ + t_sva_service_instance_num instanceNum = READ_INSTANCE_NUM_IN_SERVICE_ID(serviceId); + t_sva_st_descriptor *pDesc=&stabDesc[instanceNum]; + t_sva_vec_stab_param_out paramOut; + t_sva_offset_desc *pCropOffset; + t_sva_error status; + t_sva_tm_error tmError; + t_sva_ff_error ffError; + t_sva_bm_error bmError; + t_uint32 nbEventsRaised = 0; + t_sva_st_subtask_dependencies subTaskDep; + t_sva_buffer_id bufferId=INVALID_BUFFER_ID; + t_bool isUpdateStateNeed=FALSE; + + ST_CHECK_NULL_POINTER(pEventDesc); + ST_CHECK_NULL_POINTER(pNbEvent); + + (void) maxOfEvent; + *pNbEvent=0; + /*check for service id validity*/ + status=sva_ST_CheckServiceId(serviceId); + if (status!=SVA_OK) {return SVA_ST_INVALID_INSTANCE_NB;} + +#ifdef __DEBUG + { + eventStabDebugTable[instanceNum].eventDebugDesc[eventStabDebugTable[instanceNum].nbOfEventReceived%LOG_DEPTH].event=eventId; + eventStabDebugTable[instanceNum].eventDebugDesc[eventStabDebugTable[instanceNum].nbOfEventReceived%LOG_DEPTH].systemTime=eventTimestamp; + eventStabDebugTable[instanceNum].eventDebugDesc[eventStabDebugTable[instanceNum].nbOfEventReceived%LOG_DEPTH].subtaskId=subtaskId; + eventStabDebugTable[instanceNum].eventDebugDesc[eventStabDebugTable[instanceNum].nbOfEventReceived%LOG_DEPTH].serviceId=serviceId; + eventStabDebugTable[instanceNum].nbOfEventReceived++; + } +#endif + + switch(eventId) + { + case SVA_TM_EOT_HW_EVENT: + /* A stab subtask has just finish. We now have to do the following : + * 1) Read param out to retriewe motion vector + * 2) Generate stab vector and generate a filled event for the buffer + * 3) Repush subtask in depencencies + */ + pDesc->status.nbImagesStabilized++; + /*read param out*/ + tmError=sva_TM_GetSubTaskField(subtaskId,SVA_TM_ENC_ADDR_OUT_PARAMETERS,(t_logical_address) ¶mOut, + 0,sizeof(t_sva_vec_stab_param_out),FALSE); + HCL_DEBUG_ASSERT(tmError==SVA_TM_OK); + + /*update current cropping vector*/ + + pDesc->croppingVector.offsetX+=(t_sint16) paramOut.stab_vector_x; + pDesc->croppingVector.offsetY+=(t_sint16) paramOut.stab_vector_y; + + if((t_uint32)abs(pDesc->croppingVector.offsetY) > pDesc->conf.verticalThreshold) + { + /* Vertical Panning */ + if(pDesc->croppingVector.offsetY>0) + { + pDesc->croppingVector.offsetY = (t_sint16)pDesc->conf.verticalThreshold; + } + else /*pDesc->croppingVector.offsetY <0*/ + { + pDesc->croppingVector.offsetY = (t_sint16)(-((t_sint32)pDesc->conf.verticalThreshold)); + } + } + + if((t_uint32)abs(pDesc->croppingVector.offsetX) > pDesc->conf.horizontalThreshold) + { + /* Horizontal Panning */ + if(pDesc->croppingVector.offsetX>0) + { + pDesc->croppingVector.offsetX = (t_sint16)pDesc->conf.horizontalThreshold; + } + else /*pDesc->croppingVector.offsetX <0*/ + { + pDesc->croppingVector.offsetX = (t_sint16)(-((t_sint32)pDesc->conf.horizontalThreshold)); + } + } + + /*Generate stab vector and generate a filled event for the buffer*/ + /*Pop stab buffer*/ + ffError=POP_FIFO_ELEM(pDesc->stabParamFifos.inUseFifo,t_sva_buffer_id,bufferId); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + /*get logical address*/ + bmError=sva_BM_GetBufferLogicalAddress(bufferId,(t_logical_address *) &pCropOffset); + HCL_DEBUG_ASSERT(bmError==SVA_BM_OK); + + /*output vector using cropping*/ + /*horizontal*/ + pCropOffset->offsetX=pDesc->conf.startCroppingOffset.offsetX+pDesc->croppingVector.offsetX; + /*vertical*/ + pCropOffset->offsetY=pDesc->conf.startCroppingOffset.offsetY+pDesc->croppingVector.offsetY; + + /*fill user event*/ + pDesc->status.eventStats.filledCounter++; + CHECK_TABLE_OVERFLOW(nbEventsRaised, maxOfEvent, SVA_ST_NOT_SUPPORTED); + pEventDesc[nbEventsRaised].eventId = SVA_EVENT_BUFFER_FILLED; + pEventDesc[nbEventsRaised].serviceId = serviceId; + pEventDesc[nbEventsRaised].bufferId = bufferId; + pEventDesc[nbEventsRaised].eventTimestamp = (t_sva_timestamp_value) eventTimestamp; + pEventDesc[nbEventsRaised].eventDate = (t_sva_timestamp_value) eventDate; + pEventDesc[nbEventsRaised].extraInfo=0; + /*update buffer status*/ + sva_BM_UpdateBufferStatus(pEventDesc[nbEventsRaised].bufferId,SVA_BUFFER_FILLED,eventTimestamp); + nbEventsRaised++; + /*update buffer level*/ + pDesc->status.bufferizationStats.outLevel--; + + /*handle reference image*/ + if (pDesc->handleReferenceInitCnt==1) + { + pDesc->handleReferenceInitCnt++; + } + else + { + ffError=POP_FIFO_ELEM(pDesc->refImageFifos.inUseFifo,t_sva_buffer_id,bufferId); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + pDesc->status.eventStats.voidedCounter++; + CHECK_TABLE_OVERFLOW(nbEventsRaised, maxOfEvent, SVA_ST_NOT_SUPPORTED); + pEventDesc[nbEventsRaised].eventId = SVA_EVENT_BUFFER_VOIDED; + pEventDesc[nbEventsRaised].serviceId = serviceId; + pEventDesc[nbEventsRaised].bufferId = bufferId; + pEventDesc[nbEventsRaised].eventTimestamp = (t_sva_timestamp_value) eventTimestamp; + pEventDesc[nbEventsRaised].eventDate = (t_sva_timestamp_value) eventDate; + pEventDesc[nbEventsRaised].extraInfo=0; + /*update buffer status*/ + sva_BM_UpdateBufferStatus(pEventDesc[nbEventsRaised].bufferId,SVA_BUFFER_VOIDED,eventTimestamp); + nbEventsRaised++; + /*update buffer level*/ + pDesc->status.bufferizationStats.inLevel--; + } + + /*pop image from inUse fifo*/ + ffError=POP_FIFO_ELEM(pDesc->inputImageFifos.inUseFifo,t_sva_buffer_id,bufferId); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + + /*repush subtask*/ + subTaskDep.subtaskId = subtaskId; + subTaskDep.dependencies = pDesc->defaultDep; + ffError=PUSH_FIFO_ELEM(pDesc->subtasksDependencyFifo,t_sva_st_subtask_dependencies,subTaskDep); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + break; + case SVA_TM_EOK_HW_EVENT: + /* We can reveive an EOK for the three following reason : + * 1) no more subtask scheduled => UNDERFLOW or/and OVERFLOW event + * 2) a stop has been requested + * 3) an abort has been requested + * Note than reason 1 can arrive at the same time as 2 or 3 + + */ + isUpdateStateNeed=FALSE; + if (pDesc->state==SVA_ST_STOP_REQUESTED) + { + /*generate a stop event*/ + CHECK_TABLE_OVERFLOW(nbEventsRaised, maxOfEvent, SVA_ST_NOT_SUPPORTED); + pEventDesc[nbEventsRaised].eventId = SVA_EVENT_SERVICE_STOPPED; + pEventDesc[nbEventsRaised].serviceId = serviceId; + pEventDesc[nbEventsRaised].bufferId = INVALID_BUFFER_ID; + pEventDesc[nbEventsRaised].eventTimestamp = (t_sva_timestamp_value) eventTimestamp; + pEventDesc[nbEventsRaised].eventDate = (t_sva_timestamp_value) eventDate; + pEventDesc[nbEventsRaised].extraInfo=0; + nbEventsRaised++; + /*update state*/ + isUpdateStateNeed=TRUE; + } + + if (GET_FIFO_NB_ELEMS(pDesc->subtasksDependencyFifo)==SUBTASK_DEFAULT_NUMBER) + { + ffError=READ_FIFO_ELEM(pDesc->subtasksDependencyFifo,t_sva_st_subtask_dependencies,subTaskDep); + + /*test underflow*/ + if (ffError==SVA_FIFO_OK && + (subTaskDep.dependencies.inputImageDep==NOT_RESOLVED_DEPENDENCY)) + { + /*we have an underflow*/ + pDesc->status.eventStats.underflowCounter++; + CHECK_TABLE_OVERFLOW(nbEventsRaised, maxOfEvent, SVA_ST_NOT_SUPPORTED); + pEventDesc[nbEventsRaised].eventId = SVA_EVENT_UNDERFLOW; + pEventDesc[nbEventsRaised].serviceId = serviceId; + pEventDesc[nbEventsRaised].bufferId = INVALID_BUFFER_ID; + pEventDesc[nbEventsRaised].eventTimestamp = (t_sva_timestamp_value) eventTimestamp; + pEventDesc[nbEventsRaised].eventDate = (t_sva_timestamp_value) eventDate; + pEventDesc[nbEventsRaised].extraInfo=0; + nbEventsRaised++; + } + + /*test overflow*/ + if (ffError==SVA_FIFO_OK && + (subTaskDep.dependencies.stabParamDep==NOT_RESOLVED_DEPENDENCY)) + { + /*we have an overflow*/ + pDesc->status.eventStats.overflowCounter++; + CHECK_TABLE_OVERFLOW(nbEventsRaised, maxOfEvent, SVA_ST_NOT_SUPPORTED); + pEventDesc[nbEventsRaised].eventId = SVA_EVENT_OVERFLOW; + pEventDesc[nbEventsRaised].serviceId = serviceId; + pEventDesc[nbEventsRaised].bufferId = INVALID_BUFFER_ID; + pEventDesc[nbEventsRaised].eventTimestamp = (t_sva_timestamp_value) eventTimestamp; + pEventDesc[nbEventsRaised].eventDate = (t_sva_timestamp_value) eventDate; + pEventDesc[nbEventsRaised].extraInfo=0; + nbEventsRaised++; + } + + /*update state*/ + isUpdateStateNeed=TRUE; + } + if (isUpdateStateNeed==TRUE) + { + /*update state*/ + sva_ST_UpdateInstanceStateMachine(instanceNum,SVA_ST_EVENT_EOK); + } + break; + case SVA_TM_FAKE_HW_EVENT: + /*in case of flush in we need to generate void event for ref Buffers*/ + if (pDesc->state==SVA_ST_FLUSHING_IN) + { + t_sva_bm_error bmError; + + while(POP_FIFO_ELEM(pDesc->refImageFifos.inUseFifo,t_sva_buffer_id,bufferId) != SVA_FIFO_EMPTY) + { + /*maintain stats*/ + pDesc->status.eventStats.voidedCounter++; + /*generate event*/ + CHECK_TABLE_OVERFLOW(nbEventsRaised, maxOfEvent, SVA_ST_NOT_SUPPORTED); + pEventDesc[nbEventsRaised].eventId = SVA_EVENT_BUFFER_VOIDED; + pEventDesc[nbEventsRaised].serviceId = serviceId; + pEventDesc[nbEventsRaised].bufferId = bufferId; + pEventDesc[nbEventsRaised].eventTimestamp = (t_sva_timestamp_value) eventTimestamp; + pEventDesc[nbEventsRaised].eventDate = (t_sva_timestamp_value) eventDate; + pEventDesc[nbEventsRaised].extraInfo=0; + nbEventsRaised++; + /*update state*/ + bmError=sva_BM_UpdateBufferStatus(bufferId,SVA_BUFFER_NOT_USED,eventTimestamp); + HCL_DEBUG_ASSERT(bmError==SVA_BM_OK); + /*maintain inlevel*/ + pDesc->status.bufferizationStats.inLevel--; + } + } + /*add flush event*/ + if (pDesc->state==SVA_ST_FLUSHING_IN) + { + CHECK_TABLE_OVERFLOW(nbEventsRaised, maxOfEvent, SVA_ST_NOT_SUPPORTED); + pEventDesc[nbEventsRaised].eventId = SVA_EVENT_SERVICE_FLUSHED_IN; + } + else + { + CHECK_TABLE_OVERFLOW(nbEventsRaised, maxOfEvent, SVA_ST_NOT_SUPPORTED); + pEventDesc[nbEventsRaised].eventId = SVA_EVENT_SERVICE_FLUSHED_OUT; + } + pEventDesc[nbEventsRaised].serviceId = serviceId; + pEventDesc[nbEventsRaised].bufferId = INVALID_BUFFER_ID; + pEventDesc[nbEventsRaised].eventTimestamp = (t_sva_timestamp_value) eventTimestamp; + pEventDesc[nbEventsRaised].eventDate = (t_sva_timestamp_value) eventDate; + pEventDesc[nbEventsRaised].extraInfo=0; + nbEventsRaised++; + + /*update state machine*/ + sva_ST_UpdateInstanceStateMachine(instanceNum,SVA_ST_EVENT_FAKE); + break; + case SVA_TM_ACTIVE_HW_EVENT: + /*add activate event*/ + CHECK_TABLE_OVERFLOW(nbEventsRaised, maxOfEvent, SVA_ST_NOT_SUPPORTED); + pEventDesc[nbEventsRaised].eventId = SVA_EVENT_SERVICE_ACTIVATED; + pEventDesc[nbEventsRaised].serviceId = serviceId; + pEventDesc[nbEventsRaised].bufferId = INVALID_BUFFER_ID; + pEventDesc[nbEventsRaised].eventTimestamp = (t_sva_timestamp_value) eventTimestamp; + pEventDesc[nbEventsRaised].eventDate = (t_sva_timestamp_value) eventDate; + pEventDesc[nbEventsRaised].extraInfo=0; + nbEventsRaised++; + + /*update state machine*/ + sva_ST_UpdateInstanceStateMachine(instanceNum,SVA_ST_EVENT_ACTIVE); + break; + case SVA_TM_INACTIVE_HW_EVENT: + /*add inactivate event*/ + CHECK_TABLE_OVERFLOW(nbEventsRaised, maxOfEvent, SVA_ST_NOT_SUPPORTED); + pEventDesc[nbEventsRaised].eventId = SVA_EVENT_SERVICE_INACTIVATED; + pEventDesc[nbEventsRaised].serviceId = serviceId; + pEventDesc[nbEventsRaised].bufferId = INVALID_BUFFER_ID; + pEventDesc[nbEventsRaised].eventTimestamp = (t_sva_timestamp_value) eventTimestamp; + pEventDesc[nbEventsRaised].eventDate = (t_sva_timestamp_value) eventDate; + pEventDesc[nbEventsRaised].extraInfo=0; + nbEventsRaised++; + + /*update state machine*/ + sva_ST_UpdateInstanceStateMachine(instanceNum,SVA_ST_EVENT_INACTIVE); + break; + case SVA_TM_ERR_HW_EVENT: + pDesc->status.eventStats.errorCounter++; + CHECK_TABLE_OVERFLOW(nbEventsRaised, maxOfEvent, SVA_ST_NOT_SUPPORTED); + + pEventDesc[nbEventsRaised].eventId = SVA_EVENT_SERVICE_ERROR; + pEventDesc[nbEventsRaised].serviceId = serviceId; + pEventDesc[nbEventsRaised].bufferId = INVALID_BUFFER_ID; + pEventDesc[nbEventsRaised].eventTimestamp = (t_sva_timestamp_value) eventTimestamp; + pEventDesc[nbEventsRaised].eventDate = (t_sva_timestamp_value) eventDate; + if (pDesc->state==SVA_ST_ABORT_REQUESTED) + { + pEventDesc[nbEventsRaised].extraInfo=0; + } + else + { + pEventDesc[nbEventsRaised].extraInfo=(t_uint32)SVA_SW_PROCESSING_ERROR_DUMMY; + } + nbEventsRaised++; + + /*update state machine*/ + sva_ST_UpdateInstanceStateMachine(instanceNum,SVA_ST_EVENT_ERROR); + break; + default: + break; + } + + /*try to solve some dependencies*/ + sva_ST_ResolveDependencies(instanceNum); + + /*return number of generated events*/ + *pNbEvent=nbEventsRaised; + + return SVA_ST_OK; +} + +/****************************************************************************/ +/* NAME: t_sva_error sva_ST_Delete ( */ +/* t_sva_service_id serviceId */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine deletes the stab service */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - serviceId: identifier of the service */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/* - SVA_OK : Command taken into account */ +/* - SVA_UNKNOWN_SERVICE_ID : service id is not correct */ +/* - SVA_UNEXPECTED_API_CALL : Command cannot be excecuted in */ +/* current context. */ +/* - SVA_INTERNAL_SWPROCESSOR_ERROR : internal error */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + DONE +*/ +PUBLIC t_sva_error sva_ST_Delete(t_sva_service_id serviceId) +{ + t_sva_service_instance_num instanceNum = READ_INSTANCE_NUM_IN_SERVICE_ID(serviceId); + t_sva_st_descriptor *pDesc=&stabDesc[instanceNum]; + t_uint32 i; + t_sva_tm_error tmError; + t_sva_mm_error mmError; + t_sva_error status; + + /*check for service id validity*/ + status=sva_ST_CheckServiceId(serviceId); + if (status!=SVA_OK) {return status;} + + /*check that transition is allowed*/ + if (sva_ST_isTransitionValid(instanceNum,SVA_ST_CONTROL_DELETE)==FALSE) {return SVA_UNEXPECTED_API_CALL;} + + /*check that flush has been done*/ + if (IS_FIFO_EMPTY(pDesc->inputImageFifos.pushFifo)==FALSE) {return SVA_INTERNAL_SWPROCESSOR_ERROR;} + if (IS_FIFO_EMPTY(pDesc->inputImageFifos.inUseFifo)==FALSE) {return SVA_INTERNAL_SWPROCESSOR_ERROR;} + if (IS_FIFO_EMPTY(pDesc->refImageFifos.pushFifo)==FALSE) {return SVA_INTERNAL_SWPROCESSOR_ERROR;} + if (IS_FIFO_EMPTY(pDesc->refImageFifos.inUseFifo)==FALSE) {return SVA_INTERNAL_SWPROCESSOR_ERROR;} + if (IS_FIFO_EMPTY(pDesc->stabParamFifos.pushFifo)==FALSE) {return SVA_INTERNAL_SWPROCESSOR_ERROR;} + if (IS_FIFO_EMPTY(pDesc->stabParamFifos.inUseFifo)==FALSE) {return SVA_INTERNAL_SWPROCESSOR_ERROR;} + + /*start to delete. Things to do depend of current state*/ + if (pDesc->state==SVA_ST_WAIT_FOR_ACTIVATE || pDesc->state==SVA_ST_WAIT_FOR_START) + { + /*delete fifos*/ + DELETE_FIFO(pDesc->inputImageFifos.pushFifo); + DELETE_FIFO(pDesc->inputImageFifos.inUseFifo); + DELETE_FIFO(pDesc->refImageFifos.pushFifo); + DELETE_FIFO(pDesc->refImageFifos.inUseFifo); + DELETE_FIFO(pDesc->stabParamFifos.pushFifo); + DELETE_FIFO(pDesc->stabParamFifos.inUseFifo); + DELETE_FIFO(pDesc->subtasksDependencyFifo); + + /*delete subtasklist*/ + tmError=sva_TM_DeleteSubTaskList(pDesc->subtasksListId); + if (tmError!=SVA_TM_OK) {return SVA_INTERNAL_SWPROCESSOR_ERROR;} + + /*delete subtasks*/ + for(i=0;isubtasksIdArray[i]); + if (tmError!=SVA_TM_OK) {return SVA_INTERNAL_SWPROCESSOR_ERROR;} + } + + /*delete motion buffer*/ + mmError=sva_MM_FreeBlock(pDesc->motionBufferBlockId); + if (mmError!=SVA_MM_OK) {return SVA_INTERNAL_VIDEO_ENCODER_ERROR;} + + } + + /*delete descriptor use by memory management*/ + status=sva_EM_Delete(serviceId); + if (status!=SVA_OK) {return status;} + + /*reset descriptors*/ + sva_ST_ResetDescriptor(pDesc); + + /* Update the state machine */ + sva_ST_UpdateInstanceStateMachine(instanceNum,SVA_ST_CONTROL_DELETE); + + return SVA_OK; +} + +/****************************************************************************/ +/* NAME: t_sva_error sva_ST_GetParamsBufferSize ( */ +/* t_sva_service_id serviceId, */ +/* t_sva_push_mode mode, */ +/* t_size *pSize */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine return need buffer size in bytes for params buffers. */ +/* If mode is SVA_PUSH_OUT then return size for cropping vector buffer */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - serviceId: identifier of the service */ +/* - mode: allow to differentiate in and out buffers */ +/* */ +/* OUT : */ +/* - pSize: needed size in bytes for buffers in output */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/* - SVA_OK : Command taken into account */ +/* - SVA_UNKNOWN_SERVICE_ID : service id is not correct */ +/* - SVA_UNEXPECTED_API_CALL : Command cannot be excecuted in */ +/* current context. */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + DONE +*/ +PUBLIC t_sva_error sva_ST_GetParamsBufferSize( + t_sva_service_id serviceId, + t_sva_push_mode mode, + t_size *pSize +) +{ + t_sva_service_instance_num instanceNum = READ_INSTANCE_NUM_IN_SERVICE_ID(serviceId); + t_sva_error status; + HCL_ASSERT(pSize!=NULL); + + /*check for service id validity*/ + status=sva_ST_CheckServiceId(serviceId); + if (status!=SVA_OK) {return status;} + + /*check that transition is allowed*/ + if (sva_ST_isTransitionValid(instanceNum,SVA_ST_GET_PARAM_SIZE)==FALSE) {return SVA_UNEXPECTED_API_CALL;} + + /*get size to return in bytes*/ + if (mode==SVA_PUSH_IN) + { + /*nothing in input*/ + *pSize=0; + } + else + { + /*cropping parameters*/ + *pSize=sizeof(t_sva_offset_desc); + } + + /* Update the state machine */ + sva_ST_UpdateInstanceStateMachine(instanceNum,SVA_ST_GET_PARAM_SIZE); + + return SVA_OK; +} + +/****************************************************************************/ +/* NAME: t_sva_st_error sva_ST_ResolveDependencies( */ +/* t_sva_service_instance_num instanceNum */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* */ +/* This routine is called in sva_ST_Push and after specific event like EOT */ +/* */ +/* PARAMETERS: */ +/* IN : none */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: t_sva_st_error */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + TO DO : + - update params + - error code +*/ +PRIVATE t_sva_st_error sva_ST_ResolveDependencies +( + t_sva_service_instance_num instanceNum +) +{ + t_sva_st_descriptor *pDesc=&stabDesc[instanceNum]; + t_bool dependencyNotSolved=FALSE; + t_sva_buffer_id bufferId=INVALID_BUFFER_ID; + t_sva_st_subtask_dependencies subTaskDep; + t_sva_ff_error ffError; + t_sva_tm_error tmError; + + /*check that transition is valid*/ + if (sva_ST_isTransitionValid(instanceNum,SVA_ST_ALL_DEPENDENCIES_RESOLVED)==FALSE) {return SVA_ST_INVALID_TRANSITION;} + + /*enter loop where we try to solve dep for a maximum of subtasks*/ + while(IS_FIFO_EMPTY(pDesc->subtasksDependencyFifo)==FALSE && dependencyNotSolved==FALSE) + { + /*read subtask for which we will try to solve dependencies*/ + ffError=READ_FIFO_ELEM(pDesc->subtasksDependencyFifo,t_sva_st_subtask_dependencies,subTaskDep); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + if (subTaskDep.dependencies.inputImageDep == NOT_RESOLVED_DEPENDENCY) + { + if (POP_FIFO_ELEM(pDesc->inputImageFifos.pushFifo,t_sva_buffer_id,bufferId) != SVA_FIFO_EMPTY) + { + t_physical_address bufferAddr; + t_sva_vec_frame_buffer_in frameBufferIn; + t_sva_bm_error bmError; + + /*we can resolve input image dependency, so we do it*/ + /*push the image buffer in the in use fifo*/ + ffError=PUSH_FIFO_ELEM(pDesc->inputImageFifos.inUseFifo,t_sva_buffer_id,bufferId); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + /*update subtask dependency as in use*/ + ffError=UPDATE_FIFO_ELEM_FIELD(pDesc->subtasksDependencyFifo, + t_sva_st_subtask_dependencies, .dependencies.inputImageDep, + RESOLVED_DEPENDENCY); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + subTaskDep.dependencies.inputImageDep = RESOLVED_DEPENDENCY; + /*update field in the task list*/ + bmError=sva_BM_GetBufferPhysicalAddress(bufferId,&bufferAddr); + HCL_DEBUG_ASSERT(bmError==SVA_BM_OK); + frameBufferIn.addr_source_buffer=bufferAddr; + + /*update this field in subtask*/ + tmError=sva_TM_UpdateSubTaskField(SVA_TM_INTERMEDIATE_FIELD_TO_UPDATE,/*don't take sem since task is not scheduled*/ + subTaskDep.subtaskId, SVA_TM_ENC_ADDR_IN_FRAME_BUFFER, + FCMD_COPY,(t_uint32) &frameBufferIn.addr_source_buffer,HCL_BITFIELD_OFFSET(t_sva_vec_frame_buffer_in,addr_source_buffer), + sizeof(frameBufferIn.addr_source_buffer)); + HCL_DEBUG_ASSERT(tmError==SVA_TM_OK); + if (pDesc->handleReferenceInitCnt==0) + { + pDesc->handleReferenceInitCnt++; + /*first subtask is executed with addr_source_buffer=addr_grab_ref_buffer*/ + frameBufferIn.addr_grab_ref_buffer=bufferAddr; + /*update this field in subtask*/ + tmError=sva_TM_UpdateSubTaskField(SVA_TM_INTERMEDIATE_FIELD_TO_UPDATE,/*don't take sem since task is not scheduled*/ + subTaskDep.subtaskId, SVA_TM_ENC_ADDR_IN_FRAME_BUFFER, + FCMD_COPY,(t_uint32) &frameBufferIn.addr_grab_ref_buffer,HCL_BITFIELD_OFFSET(t_sva_vec_frame_buffer_in,addr_grab_ref_buffer), + sizeof(frameBufferIn.addr_grab_ref_buffer)); + HCL_DEBUG_ASSERT(tmError==SVA_TM_OK); + } + } + } + if (subTaskDep.dependencies.refImageDep == NOT_RESOLVED_DEPENDENCY) + { + if (POP_FIFO_ELEM(pDesc->refImageFifos.pushFifo,t_sva_buffer_id,bufferId) != SVA_FIFO_EMPTY) + { + t_physical_address bufferAddr; + t_sva_vec_frame_buffer_in frameBufferIn; + t_sva_bm_error bmError; + + /*we can resolve reference image dependency, so we do it*/ + /*push the image buffer in the in use fifo*/ + ffError=PUSH_FIFO_ELEM(pDesc->refImageFifos.inUseFifo,t_sva_buffer_id,bufferId); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + /*update subtask dependency as in use*/ + ffError=UPDATE_FIFO_ELEM_FIELD(pDesc->subtasksDependencyFifo, + t_sva_st_subtask_dependencies, .dependencies.refImageDep, + RESOLVED_DEPENDENCY); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + subTaskDep.dependencies.refImageDep = RESOLVED_DEPENDENCY; + /*update field in the task list*/ + bmError=sva_BM_GetBufferPhysicalAddress(bufferId,&bufferAddr); + HCL_DEBUG_ASSERT(bmError==SVA_BM_OK); + frameBufferIn.addr_grab_ref_buffer=bufferAddr; + + /*update this field in subtask*/ + tmError=sva_TM_UpdateSubTaskField(SVA_TM_INTERMEDIATE_FIELD_TO_UPDATE,/*don't take sem since task is not scheduled*/ + subTaskDep.subtaskId, SVA_TM_ENC_ADDR_IN_FRAME_BUFFER, + FCMD_COPY,(t_uint32) &frameBufferIn.addr_grab_ref_buffer,HCL_BITFIELD_OFFSET(t_sva_vec_frame_buffer_in,addr_grab_ref_buffer), + sizeof(frameBufferIn.addr_grab_ref_buffer)); + HCL_DEBUG_ASSERT(tmError==SVA_TM_OK); + } + } + if (subTaskDep.dependencies.stabParamDep == NOT_RESOLVED_DEPENDENCY) + { + if (POP_FIFO_ELEM(pDesc->stabParamFifos.pushFifo,t_sva_buffer_id,bufferId) != SVA_FIFO_EMPTY) + { + ffError=PUSH_FIFO_ELEM(pDesc->stabParamFifos.inUseFifo,t_sva_buffer_id,bufferId); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + /*update subtask dependency as in use*/ + ffError=UPDATE_FIFO_ELEM_FIELD(pDesc->subtasksDependencyFifo, + t_sva_st_subtask_dependencies, .dependencies.stabParamDep, + RESOLVED_DEPENDENCY); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + subTaskDep.dependencies.stabParamDep= RESOLVED_DEPENDENCY; + } + } + /*check that all dependency has been resolved to continue*/ + if (subTaskDep.dependencies.inputImageDep != NOT_RESOLVED_DEPENDENCY && + subTaskDep.dependencies.stabParamDep != NOT_RESOLVED_DEPENDENCY) + { + t_sva_tm_timestamp immediateTimeStamp={SVA_TM_IMMEDIATE,0}; + + /*pop subtask from list of subtask for which dep has to be solved*/ + ffError=POP_FIFO_ELEM(pDesc->subtasksDependencyFifo,t_sva_st_subtask_dependencies,subTaskDep); + /*update state machine*/ + sva_ST_UpdateInstanceStateMachine(instanceNum,SVA_ST_ALL_DEPENDENCIES_RESOLVED); + /*add subtask to list of schedulable subtasks*/ + tmError=sva_TM_AddElemToSubTaskList(pDesc->subtasksListId,subTaskDep.subtaskId,&immediateTimeStamp, 1); + HCL_DEBUG_ASSERT(tmError==SVA_TM_OK); + } + else {dependencyNotSolved=TRUE;} + } + + return SVA_ST_OK; +} + +/****************************************************************************/ +/* NAME: t_sva_st_state sva_ST_UpdateInstanceStateMachine( */ +/* t_sva_service_instance_num instanceNum, */ +/* t_sva_st_transition requestedTransition */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine allows to update both state machine */ +/* following the given requestedTransition */ +/* */ +/* N.B: This routine returns the new state after the requested transition */ +/* A special return state (SVA_ST_TRANSITION_REJECTED) is used to check */ +/* the validity of a transition request */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - instanceNum : instance number for which state must be updated */ +/* - requestedTransition: identifier of the requested transition */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: t_sva_st_state */ +/* - one of the t_sva_st_state */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + DONE +*/ +PRIVATE t_sva_st_state sva_ST_UpdateInstanceStateMachine +( + t_sva_service_instance_num instanceNum, + t_sva_st_transition requestedTransition +) +{ + t_sva_st_descriptor *pDesc=&stabDesc[instanceNum]; + t_sva_st_state nextState; + t_sva_st_activate_state nextActivateState; + +#ifdef __DEBUG + { + t_uint32 systemTime; + + SVA_GetServiceSystemTime(pDesc->serviceId,&systemTime); + transitionStabDebugTable[instanceNum].transitionDebugDesc[transitionStabDebugTable[instanceNum].nbOfTransitionReceived%LOG_DEPTH].state=pDesc->state; + transitionStabDebugTable[instanceNum].transitionDebugDesc[transitionStabDebugTable[instanceNum].nbOfTransitionReceived%LOG_DEPTH].transition=requestedTransition; + transitionStabDebugTable[instanceNum].transitionDebugDesc[transitionStabDebugTable[instanceNum].nbOfTransitionReceived%LOG_DEPTH].systemTime=systemTime; + transitionStabDebugTable[instanceNum].transitionDebugDesc[transitionStabDebugTable[instanceNum].nbOfTransitionReceived%LOG_DEPTH].activateState=pDesc->activateState; + transitionStabDebugTable[instanceNum].nbOfTransitionReceived++; + + } +#endif + + /* Compute the next state */ + nextState=stateMachine[pDesc->state][requestedTransition]; + nextActivateState=activateStateMachine[pDesc->activateState][requestedTransition]; + + /* Check if the transition is valid */ + if (nextState != SVA_ST_TRANSITION_REJECTED && nextActivateState!=SVA_ST_ACTIVATE_TRANSITION_REJECTED) + { + /* Update both current state of the instance */ + pDesc->state = nextState; + pDesc->activateState = nextActivateState; + /* Update status*/ + pDesc->status.state=stabState2ServiceState[pDesc->state]; + } + + return nextState; +} + +/****************************************************************************/ +/* NAME: t_bool sva_ST_isTransitionValid( */ +/* t_sva_service_instance_num instanceNum, */ +/* t_sva_st_transition requestedTransition */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine checks if the requestedTransition is valid for both */ +/* state machine */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - instanceNum : instance number for which transition check must be done*/ +/* - requestedTransition: identifier of the requested transition */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: t_bool */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + DONE +*/ +PRIVATE t_bool sva_ST_isTransitionValid +( + t_sva_service_instance_num instanceNum, + t_sva_st_transition requestedTransition +) +{ + t_sva_st_descriptor *pDesc=&stabDesc[instanceNum]; + t_sva_st_state nextState; + t_sva_st_activate_state nextActivateState; + + /* Compute the next state for both state machine*/ + nextState=stateMachine[pDesc->state][requestedTransition]; + nextActivateState=activateStateMachine[pDesc->activateState][requestedTransition]; + + /*return false in case of invalid transition for at least one state machine*/ + if (nextState != SVA_ST_TRANSITION_REJECTED && nextActivateState!=SVA_ST_ACTIVATE_TRANSITION_REJECTED) {return TRUE;} + else {return FALSE;} +} + +/****************************************************************************/ +/* NAME: t_sva_error sva_ST_CheckServiceId(t_sva_service_id serviceId) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will check that task_id and instance number of servideId*/ +/* are both valid */ +/* */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - serviceId: service id to check */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: t_sva_error */ +/* - SVA_UNKNOWN_SERVICE_ID : Invalid service id. Either due to an */ +/* invalid task id or invalid instance number. */ +/* - SVA_OK : Service id is valid */ +/* */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + DONE +*/ +PRIVATE t_sva_error sva_ST_CheckServiceId(t_sva_service_id serviceId) +{ + t_sva_service_instance_num instanceNum = READ_INSTANCE_NUM_IN_SERVICE_ID(serviceId); + t_sva_sv_task_id taskId = READ_TASK_ID_IN_SERVICE_ID(serviceId); + + if (taskId!=SVA_SV_STAB_TID) {return SVA_UNKNOWN_SERVICE_ID;} + if (instanceNum>=NUM_MAX_STAB) {return SVA_UNKNOWN_SERVICE_ID;} + + return SVA_OK; +} + +/****************************************************************************/ +/* NAME: t_sva_error sva_ST_DoReset( */ +/* t_sva_service_id serviceId */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will reset a service so it can restart after an error. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - serviceId: service identifier */ +/* */ +/* OUT: none */ +/* */ +/* RETURN: t_sva_error */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + DONE +*/ +PRIVATE t_sva_error sva_ST_DoReset +( + t_sva_service_id serviceId +) +{ + (void) serviceId; + + return SVA_OK; +} + +/****************************************************************************/ +/* NAME: t_sva_error sva_ST_DoFlushIn( */ +/* t_sva_service_id serviceId */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will flush input fifo. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - serviceId: service identifier */ +/* */ +/* OUT: none */ +/* */ +/* RETURN: t_sva_error */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + TODO : + - See how to handle a restart after this call +*/ +PRIVATE t_sva_error sva_ST_DoFlushIn +( + t_sva_service_id serviceId +) +{ + t_sva_service_instance_num instanceNum = READ_INSTANCE_NUM_IN_SERVICE_ID(serviceId); + t_sva_st_descriptor *pDesc=&stabDesc[instanceNum]; + t_sva_st_subtask_dependencies subtaskDep; + t_sva_timestamp dummyTimeStamp={SVA_NO_TIMESTAMP,0}; + t_sva_buffer_id bufferId = INVALID_BUFFER_ID; + t_uint32 systemTime; + t_sva_error svaError; + t_sva_tm_error tmError; + t_sva_ff_error ffError; + t_sva_bm_error bmError; + + + (void) dummyTimeStamp; + /*remove schedule tasks and push them back in subtasksDependencyFifo with default dep*/ + /*so they can be rescheduled */ + do + { + tmError=sva_TM_RemoveElemFromSubTaskList(pDesc->subtasksListId,&subtaskDep.subtaskId); + if (tmError==SVA_TM_OK) + { + subtaskDep.dependencies = pDesc->defaultDep; + ffError=PUSH_FIFO_ELEM(pDesc->subtasksDependencyFifo,t_sva_st_subtask_dependencies,subtaskDep); + if (ffError!=SVA_FIFO_OK) {return SVA_INTERNAL_SWPROCESSOR_ERROR;} + } + } while (tmError==SVA_TM_OK); + + /*get time*/ + svaError=SVA_GetServiceSystemTime(serviceId,&systemTime); + if (svaError != SVA_OK) {return SVA_INTERNAL_SWPROCESSOR_ERROR;} + + /*flush fifo*/ + /*flush source fifo*/ + while(POP_FIFO_ELEM(pDesc->inputImageFifos.inUseFifo,t_sva_buffer_id,bufferId) != SVA_FIFO_EMPTY) + { + bmError=sva_BM_UpdateBufferStatus(bufferId,SVA_BUFFER_NOT_USED,systemTime); + if (bmError!=SVA_BM_OK) {return SVA_INTERNAL_SWPROCESSOR_ERROR;} + } + while(POP_FIFO_ELEM(pDesc->inputImageFifos.pushFifo,t_sva_buffer_id,bufferId) != SVA_FIFO_EMPTY) + { + bmError=sva_BM_UpdateBufferStatus(bufferId,SVA_BUFFER_NOT_USED,systemTime); + if (bmError!=SVA_BM_OK) {return SVA_INTERNAL_SWPROCESSOR_ERROR;} + } + /*flush reference fifo*/ + /*we keep last reference buffer id in pDesc->refImageFifos.inUseFifo*/ + /*it will be release under interruption with a voided event associated*/ + while(GET_FIFO_NB_ELEMS(pDesc->refImageFifos.inUseFifo)>1) + { + POP_FIFO_ELEM(pDesc->refImageFifos.inUseFifo,t_sva_buffer_id,bufferId); + ffError=PUSH_REVERSE_FIFO_ELEM(pDesc->refImageFifos.pushFifo,t_sva_buffer_id,bufferId); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + } + while(POP_FIFO_ELEM(pDesc->refImageFifos.pushFifo,t_sva_buffer_id,bufferId) != SVA_FIFO_EMPTY) + { + bmError=sva_BM_UpdateBufferStatus(bufferId,SVA_BUFFER_NOT_USED,systemTime); + if (bmError!=SVA_BM_OK) {return SVA_INTERNAL_SWPROCESSOR_ERROR;} + pDesc->status.bufferizationStats.inLevel--; + } + + /*we also have to reset handleReferenceInitCnt variable since we have to more reference*/ + pDesc->handleReferenceInitCnt=0; + /*now we change dependency of first subtaskDep in fifo to not resolve reference image*/ + ffError=UPDATE_FIFO_ELEM_FIELD(pDesc->subtasksDependencyFifo, + t_sva_st_subtask_dependencies, .dependencies.refImageDep, + RESOLVED_DEPENDENCY); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + + /*move output buffers from the in use fifo to the push fifo in reverse order*/ + do + { + ffError=POP_REVERSE_FIFO_ELEM(pDesc->stabParamFifos.inUseFifo,t_sva_buffer_id,bufferId); + if (ffError==SVA_FIFO_OK) + { + ffError=PUSH_REVERSE_FIFO_ELEM(pDesc->stabParamFifos.pushFifo,t_sva_buffer_id,bufferId); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + } + } while (ffError==SVA_FIFO_OK); + + return SVA_OK; +} + +/****************************************************************************/ +/* NAME: t_sva_error sva_ST_DoFlushOut( */ +/* t_sva_service_id serviceId */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will flush output fifo. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - serviceId: service identifier */ +/* */ +/* OUT: none */ +/* */ +/* RETURN: t_sva_error */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + TODO : + - See how to handle a restart after this call +*/ +PRIVATE t_sva_error sva_ST_DoFlushOut +( + t_sva_service_id serviceId +) +{ + t_sva_service_instance_num instanceNum = READ_INSTANCE_NUM_IN_SERVICE_ID(serviceId); + t_sva_st_descriptor *pDesc=&stabDesc[instanceNum]; + t_sva_st_subtask_dependencies subtaskDep; + t_sva_timestamp dummyTimeStamp={SVA_NO_TIMESTAMP,0}; + t_sva_buffer_id bufferId = INVALID_BUFFER_ID; + t_uint32 systemTime; + t_sva_error svaError; + t_sva_tm_error tmError; + t_sva_ff_error ffError; + t_sva_bm_error bmError; + + + (void) dummyTimeStamp; + /*remove schedule tasks and push them back in subtasksDependencyFifo with default dep*/ + /*so they can be rescheduled */ + do + { + tmError=sva_TM_RemoveElemFromSubTaskList(pDesc->subtasksListId,&subtaskDep.subtaskId); + if (tmError==SVA_TM_OK) + { + subtaskDep.dependencies = pDesc->defaultDep; + ffError=PUSH_FIFO_ELEM(pDesc->subtasksDependencyFifo,t_sva_st_subtask_dependencies,subtaskDep); + if (ffError!=SVA_FIFO_OK) {return SVA_INTERNAL_SWPROCESSOR_ERROR;} + } + } while (tmError==SVA_TM_OK); + + /*get time*/ + svaError=SVA_GetServiceSystemTime(serviceId,&systemTime); + if (svaError != SVA_OK) {return SVA_INTERNAL_SWPROCESSOR_ERROR;} + + /*flush fifo*/ + /*flush param fifo*/ + while(POP_FIFO_ELEM(pDesc->stabParamFifos.inUseFifo,t_sva_buffer_id,bufferId) != SVA_FIFO_EMPTY) + { + bmError=sva_BM_UpdateBufferStatus(bufferId,SVA_BUFFER_NOT_USED,systemTime); + if (bmError!=SVA_BM_OK) {return SVA_INTERNAL_SWPROCESSOR_ERROR;} + pDesc->status.bufferizationStats.outLevel--; + } + while(POP_FIFO_ELEM(pDesc->stabParamFifos.pushFifo,t_sva_buffer_id,bufferId) != SVA_FIFO_EMPTY) + { + bmError=sva_BM_UpdateBufferStatus(bufferId,SVA_BUFFER_NOT_USED,systemTime); + if (bmError!=SVA_BM_OK) {return SVA_INTERNAL_SWPROCESSOR_ERROR;} + pDesc->status.bufferizationStats.outLevel--; + } + + /*move input buffers and reference fifo from the in use fifo to the push fifo in reverse order*/ + do + { + ffError=POP_REVERSE_FIFO_ELEM(pDesc->inputImageFifos.inUseFifo,t_sva_buffer_id,bufferId); + if (ffError==SVA_FIFO_OK) + { + ffError=PUSH_REVERSE_FIFO_ELEM(pDesc->inputImageFifos.pushFifo,t_sva_buffer_id,bufferId); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + } + } while (ffError==SVA_FIFO_OK); + do + { + ffError=POP_REVERSE_FIFO_ELEM(pDesc->refImageFifos.inUseFifo,t_sva_buffer_id,bufferId); + if (ffError==SVA_FIFO_OK) + { + ffError=PUSH_REVERSE_FIFO_ELEM(pDesc->refImageFifos.pushFifo,t_sva_buffer_id,bufferId); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + } + } while (ffError==SVA_FIFO_OK); + + return SVA_OK; +} + +/****************************************************************************/ +/* NAME: t_sva_ec_error sva_ST_ResetStatus( */ +/* t_sva_sw_processing_status *pStatus */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will reset status descriptor. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - pStatus: status descriptor to reset */ +/* */ +/* OUT: none */ +/* */ +/* RETURN: t_sva_st_error */ +/* - SVA_ST_OK */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + DONE +*/ +PRIVATE t_sva_st_error sva_ST_ResetStatus +( + t_sva_sw_processing_status *pStatus +) +{ + ST_CHECK_NULL_POINTER(pStatus); + + pStatus->state=SVA_SERVICE_NOT_INITIALIZED; + pStatus->errorId=SVA_SW_PROCESSING_ERROR_DUMMY; + pStatus->nbImagesStabilized=0; + pStatus->eventStats.voidedCounter=0; + pStatus->eventStats.filledCounter=0; + pStatus->eventStats.partlyCounter=0; + pStatus->eventStats.readOnlyCounter=0; + pStatus->eventStats.underflowCounter=0; + pStatus->eventStats.overflowCounter=0; + pStatus->eventStats.errorCounter=0; + pStatus->bufferizationStats.inLevel=0; + pStatus->bufferizationStats.outLevel=0; + + return SVA_ST_OK; +} + +/****************************************************************************/ +/* NAME: void sva_ST_ResetDescriptor( */ +/* t_sva_st_descriptor *pDesc */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine is in charge reset encode descriptor for one instance */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - pDesc: descriptor to reset */ +/* */ +/* OUT: none */ +/* */ +/* RETURN: void */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + DONE +*/ +PRIVATE void sva_ST_ResetDescriptor(t_sva_st_descriptor *pDesc) +{ + ST_CHECK_NULL_POINTER(pDesc); + + sva_ST_ResetStatus(&pDesc->status); + pDesc->handleReferenceInitCnt=0; + pDesc->croppingVector.offsetX=pDesc->croppingVector.offsetY=0; +} + + +/****************************************************************************/ +/* NAME: t_sva_error sva_ST_AllocateMemoryAndLink( */ +/* t_sva_service_instance_num instanceNum */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine allocate all needed internal memory and link them to */ +/* subtask. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - instanceNum : identifier of the Service instance */ +/* */ +/* OUT: */ +/* */ +/* RETURN: t_sva_error */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + * DONE +*/ +PRIVATE t_sva_error sva_ST_AllocateMemoryAndLink +( + t_sva_service_instance_num instanceNum +) +{ + t_sva_st_descriptor *pDesc=&stabDesc[instanceNum]; + const t_sva_sw_processing_configuration *pConf = &pDesc->conf; + t_sva_mm_error mmError; + t_sva_tm_error tmError; + t_size memSize; + t_uint32 i; + t_uint32 width=(t_uint32) pConf->originalPicture.width; + t_uint32 height=(t_uint32) pConf->originalPicture.height; + + //allocate and link motion vector buffer + memSize=((height/16+2)*(width/16+2)*4+15); + + mmError=sva_MM_AllocBlock(SDRAM_ID,memSize,SVA_MM_ALIGN_16BYTES,&pDesc->motionBufferBlockId); + if (mmError!=SVA_MM_OK) {return SVA_INTERNAL_VIDEO_ENCODER_ERROR;} + + for(i=0;imotionBufferBlockId,&frameBufferOut.addr_motion_vector_buffer); + if (mmError!=SVA_MM_OK) {return SVA_INTERNAL_VIDEO_ENCODER_ERROR;} + //update this field in subtask + tmError=sva_TM_UpdateSubTaskField(SVA_TM_INTERMEDIATE_FIELD_TO_UPDATE,//don't take sem since task is not scheduled + pDesc->subtasksIdArray[i], SVA_TM_ENC_ADDR_OUT_FRAME_BUFFER, + FCMD_COPY,(t_uint32) &frameBufferOut.addr_motion_vector_buffer,HCL_BITFIELD_OFFSET(t_sva_vec_frame_buffer_out,addr_motion_vector_buffer), + sizeof(frameBufferOut.addr_motion_vector_buffer)); + if (tmError!=SVA_TM_OK) {return SVA_INTERNAL_VIDEO_ENCODER_ERROR;} + } + + return SVA_OK; +} + + +/****************************************************************************/ +/* NAME: t_bool sva_ST_IsConfigurationValid( */ +/* const t_sva_sw_processing_configuration *pConf */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will check that given configuration given to stab is */ +/* valid. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - pConf: a pointer to the configuration to check */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: t_bool */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + DONE +*/ +PRIVATE t_bool sva_ST_IsConfigurationValid +( + const t_sva_sw_processing_configuration *pConf +) +{ + ST_CHECK_NULL_POINTER(pConf); + + /*t_sva_image_desc originalPicture*/ + CHECK_ALIGNMENT(pConf->originalPicture.height,SVA_ST_SOURCE_FRAME_HEIGHT_ALIGN); + CHECK_RANGE(pConf->originalPicture.height, SVA_ST_SOURCE_FRAME_HEIGHT_MIN, SVA_ST_SOURCE_FRAME_HEIGHT_MAX); + CHECK_ALIGNMENT(pConf->originalPicture.width,SVA_ST_SOURCE_FRAME_WIDTH_ALIGN); + CHECK_RANGE(pConf->originalPicture.width, SVA_ST_SOURCE_FRAME_WIDTH_MIN, SVA_ST_SOURCE_FRAME_WIDTH_MAX); + + /* if treshold are lower than startCroppingOffset then there is a risk to output + * negative cropping vector offset !!!! So check that user provide threshold that + * are valid relative to startCroppingOffset */ + /*t_sva_offset_desc startCroppingOffset / t_uint32 horizontalThreshold*/ + if (pConf->horizontalThreshold > pConf->startCroppingOffset.offsetX) {return FALSE;} + /*t_sva_offset_desc startCroppingOffset / t_uint32 verticalThreshold*/ + if (pConf->verticalThreshold > pConf->startCroppingOffset.offsetY) {return FALSE;} + + return TRUE; +} + +/****************************************************************************/ +/* NAME: t_sva_error sva_ST_BuildParamInStructure( */ +/* const t_sva_sw_processing_configuration *pConf, */ +/* t_sva_vec_stab_param_in *pParamIn */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine builds the paramIn structure from the given configuration */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - pConf: provided stab configuration */ +/* */ +/* OUT: */ +/* - pParamIn: paramIn structure to build */ +/* */ +/* RETURN: t_sva_error */ +/* */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + DONE +*/ +PRIVATE t_sva_error sva_ST_BuildParamInStructure +( + const t_sva_sw_processing_configuration *pConf, + t_sva_vec_stab_param_in *pParamIn +) +{ + t_uint32 i,j; + t_uint32 index=0; + + HCL_DEBUG_ASSERT(pConf != NULL); + HCL_DEBUG_ASSERT(pParamIn != NULL); + + /*set frame widht and height*/ + pParamIn->frame_width=pConf->originalPicture.width; + pParamIn->frame_height=pConf->originalPicture.height; + + /*set ZOI*/ + if (pConf->isUsingCustomZoneOfInterestBitmap==TRUE) + { + /*user set a custom ZOI, so just copy it in paramin*/ + for(i=0;i<84;i++) + { + pParamIn->zone_of_interest_bitmap[i]=pConf->customZoneOfInterestBitmap[i]; + } + } + else + { + /*set ZOI area to zero*/ + for(i=0;i<84;i++) + { + pParamIn->zone_of_interest_bitmap[i]=0; + } + + /*we check if we find a known config. Else we set a default ZOI area*/ + if (pConf->originalPicture.width==SVA_ST_WIDTH_VGA_PLUS && + pConf->originalPicture.height==SVA_ST_HEIGHT_VGA_PLUS) + { + /*VGA+*/ + /*We set four box near corner*/ + for(j=0;j=SVA_ST_VGA_HOR_LIMIT2) + { + pParamIn->zone_of_interest_bitmap[index/16]|=(1<<(15-(index%16))); + } + index++; + } + } + for(j=SVA_ST_VGA_VERT_LIMIT1;j=SVA_ST_VGA_HOR_LIMIT2) + { + pParamIn->zone_of_interest_bitmap[index/16]|=(1<<(15-(index%16))); + } + index++; + } + } + } + else if (pConf->originalPicture.width==SVA_ST_WIDTH_CIF_PLUS && + pConf->originalPicture.height==SVA_ST_HEIGHT_CIF_PLUS) + { + /*CIF+*/ + /*We set two rectangle*/ + for(j=0;j=SVA_ST_CIF_HOR_LIMIT2) + { + pParamIn->zone_of_interest_bitmap[index/16]|=(1<<(15-(index%16))); + } + index++; + } + } + } + else if (pConf->originalPicture.width==SVA_ST_WIDTH_QVGA_PLUS && + pConf->originalPicture.height==SVA_ST_HEIGHT_QVGA_PLUS) + { + /*QVGA+*/ + /*We set two rectangle*/ + for(j=0;j=SVA_ST_QVGA_HOR_LIMIT2) + { + pParamIn->zone_of_interest_bitmap[index/16]|=(1<<(15-(index%16))); + } + index++; + } + } + } + else if (pConf->originalPicture.width==SVA_ST_WIDTH_QCIF_PLUS && + pConf->originalPicture.height==SVA_ST_HEIGHT_QCIF_PLUS) + { + /*QCIF+*/ + /*We set two rectangle*/ + for(j=0;j=SVA_ST_QCIF_HOR_LIMIT2) + { + pParamIn->zone_of_interest_bitmap[index/16]|=(1<<(15-(index%16))); + } + index++; + } + } + } + else if (pConf->originalPicture.width==SVA_ST_WIDTH_SQCIF_PLUS && + pConf->originalPicture.height==SVA_ST_HEIGHT_SQCIF_PLUS) + { + /*SQCIF+*/ + /*We set two rectangle*/ + for(j=0;j=SVA_ST_SQCIF_HOR_LIMIT2) + { + pParamIn->zone_of_interest_bitmap[index/16]|=(1<<(15-(index%16))); + } + index++; + } + } + } + else + { + /*default configuration*/ + t_uint32 threshold1=pConf->originalPicture.width/48; + t_uint32 threshold2=threshold1*2; + + for(j=0;j<(t_uint32)(pConf->originalPicture.height/16);j++) + { + for(i=0;i<(t_uint32)(pConf->originalPicture.width/16);i++) + { + if (i=threshold2) + { + pParamIn->zone_of_interest_bitmap[index/16]|=(1<<(15-(index%16))); + } + index++; + } + } + } + } + + return SVA_OK; +} --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/stab/sva_stab.h @@ -0,0 +1,89 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ + +#ifndef __INC_SVA_STAB_H +#define __INC_SVA_STAB_H + +#include "sva.h" +#include "svap.h" +#include "sva_taskmgt.h" + +/******************************************************************************/ +/* Constants definitions */ +/******************************************************************************/ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* + * Define the symbols used to identify the various errors of the STab Module + */ +typedef enum { + SVA_ST_INVALID_TRANSITION = SVA_EC_STAB_LAST_ERROR, + SVA_ST_NO_MORE_AVAILABLE_INSTANCE, + SVA_ST_INVALID_INSTANCE_NB, + SVA_ST_INVALID_TASK_ID_NB, + SVA_ST_NOT_SUPPORTED, + SVA_ST_INVALID_CONTROL_PARAM, + SVA_ST_INVALID_PUSH, + SVA_ST_INVALID_BUFFER_TYPE, + SVA_ST_INVALID_BUFFER_SIZE, + SVA_ST_INVALID_CONFIGURATION, + SVA_ST_UNKNOWN_CMD_ID, + SVA_ST_UNEXPECTED_HW_EVENT, + SVA_ST_TI_LINKED_ERROR, + SVA_ST_BM_LINKED_ERROR, + SVA_ST_MM_LINKED_ERROR, + SVA_ST_FF_LINKED_ERROR, + SVA_ST_TM_LINKED_ERROR, + SVA_ST_NULL_POINTER_PARAMETER, + SVA_ST_FIFO_NOT_EMPTY, + SVA_ST_OK = HCL_OK +} t_sva_st_error; + + +/******************************************************************************* +* PUBLIC Functions +*******************************************************************************/ + +PUBLIC t_sva_error sva_ST_Init(t_sva_block_id ,t_size); +PUBLIC t_sva_error sva_ST_Reset( t_sva_service_id ); +PUBLIC t_sva_error sva_ST_Create( t_sva_service_id *); +PUBLIC t_sva_error sva_ST_Control(t_sva_service_id, t_sva_service_cmd_id, t_uint32 ); +PUBLIC t_sva_error sva_ST_Push(t_sva_service_id, t_sva_buffer_id, t_sva_push_mode, t_sva_buffer_type, t_sva_timestamp ); +PUBLIC t_sva_st_error sva_ST_DispatchVirtualHwEvent(t_sva_tm_virtual_hw_event_id, t_sva_service_id, t_sva_tm_subtask_id, t_uint32, t_uint32, t_uint8, t_sva_event_desc *, t_uint32 *); +PUBLIC t_sva_error sva_ST_ProvideInternalNeeds( t_sva_service_id); +PUBLIC t_sva_error sva_ST_GetInternalNeeds(t_sva_service_id, t_size *); +PUBLIC t_sva_error sva_ST_Activate(t_sva_service_id, t_sva_service_mode, t_sva_fw_id *); +PUBLIC t_sva_error sva_ST_Inactivate(t_sva_service_id); +PUBLIC t_sva_error sva_ST_Delete(t_sva_service_id ); +PUBLIC t_sva_error sva_ST_GetParamsBufferSize(t_sva_service_id ,t_sva_push_mode ,t_size *); +//t_sva_sw_processing_configuration is in sva.h +// function is sva.h +//PUBLIC t_sva_error SVA_ConfigureSwProcessing( t_sva_service_id, t_sva_sw_processing_configuration); +//PUBLIC t_sva_error SVA_GetSwProcessingStatus(t_sva_service_id, t_sva_sw_processing_status *); +//PUBLIC t_sva_error SVA_UpdateSwProcessingParams(t_sva_service_id, t_sva_update_cmd_type, t_sva_sw_processing_param_id, t_uint32 ); + +#ifdef __cplusplus +} /* allow C++ to use these headers */ +#endif /* __cplusplus */ + +#endif /* __INC_SVA_STAB_H */ +/* End of file - sva_stab.h */ --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/stab/sva_stabp.h @@ -0,0 +1,284 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ + +#ifndef __INC_SVA_STABP_H +#define __INC_SVA_STABP_H + +#include "hcl_defs.h" +#include "sva_stab.h" +#include "sva_taskmgt.h" +#include "sva_buffermgt.h" +#include "sva_fifo.h" +#include "sva_service.h" + +/******************************************************************************/ +/* Constants definitions */ +/******************************************************************************/ +#ifdef __DEBUG + /* + * Define number of event to log + */ + #define LOG_DEPTH 16 +#endif + +/* + * Define the number of field inside an encode Subtask descriptor (spec v0.96) + */ +#define STAB_FIELD_NUMBER 8 + +/* + * Define the default memory used to store subtasks descriptors + */ +#define STAB_DEFAULT_MEMORY_ID SDRAM_ID + +/* + * Define the default memory used to store param_out (infos) data + */ +#define STAB_DEFAULT_INFOS_MEMORY_ID SDRAM_ID + +/* + * Define macro to handle null pointer +*/ +#define ST_CHECK_NULL_POINTER(pointer) HCL_ASSERT(pointer!=NULL) + +/* + * Define various size of plus format +*/ +#define SVA_ST_WIDTH_VGA_PLUS 672 +#define SVA_ST_HEIGHT_VGA_PLUS 496 +#define SVA_ST_WIDTH_CIF_PLUS 384 +#define SVA_ST_HEIGHT_CIF_PLUS 304 +#define SVA_ST_WIDTH_QVGA_PLUS 352 +#define SVA_ST_HEIGHT_QVGA_PLUS 256 +#define SVA_ST_WIDTH_QCIF_PLUS 208 +#define SVA_ST_HEIGHT_QCIF_PLUS 160 +#define SVA_ST_WIDTH_SQCIF_PLUS 144 +#define SVA_ST_HEIGHT_SQCIF_PLUS 112 + +/* + * Define treshold +*/ +#define SVA_ST_VGA_VERT_LIMIT1 10 +#define SVA_ST_VGA_VERT_LIMIT2 21 +#define SVA_ST_VGA_HOR_LIMIT1 14 +#define SVA_ST_VGA_HOR_LIMIT2 28 +#define SVA_ST_CIF_HOR_LIMIT1 8 +#define SVA_ST_CIF_HOR_LIMIT2 16 +#define SVA_ST_QVGA_HOR_LIMIT1 7 +#define SVA_ST_QVGA_HOR_LIMIT2 15 +#define SVA_ST_QCIF_HOR_LIMIT1 4 +#define SVA_ST_QCIF_HOR_LIMIT2 9 +#define SVA_ST_SQCIF_HOR_LIMIT1 3 +#define SVA_ST_SQCIF_HOR_LIMIT2 6 + +/* + * Define various configuration limits for grab +*/ +#define SVA_ST_SOURCE_FRAME_HEIGHT_ALIGN 16 +#define SVA_ST_SOURCE_FRAME_WIDTH_ALIGN 16 +#define SVA_ST_SOURCE_FRAME_HEIGHT_MIN 32 +#define SVA_ST_SOURCE_FRAME_HEIGHT_MAX 512 +#define SVA_ST_SOURCE_FRAME_WIDTH_MIN 32 +#define SVA_ST_SOURCE_FRAME_WIDTH_MAX 672 + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/******************************************************************************/ +/* Types definitions */ +/******************************************************************************/ +/* + * Define the various state of a Stab instance service + */ +typedef enum { + SVA_ST_NOT_INITIALIZED, + SVA_ST_WAIT_FOR_CONFIGURATION, + SVA_ST_WAIT_FOR_INTERNAL_NEEDS, + SVA_ST_WAIT_FOR_ACTIVATE, + SVA_ST_WAIT_FOR_START, + SVA_ST_FLUSHING_IN, + SVA_ST_FLUSHING_OUT, + SVA_ST_WAIT_FOR_DATA, + SVA_ST_RUNNING, + SVA_ST_ABORT_REQUESTED, + SVA_ST_STOP_REQUESTED, + SVA_ST_ERROR, + SVA_ST_LAST_DUMMY_STATE, + SVA_ST_TRANSITION_REJECTED +} t_sva_st_state; + +/* + * Define the various activate state of a Stab instance service + */ +typedef enum { + SVA_ST_INACTIVE, + SVA_ST_IN_ACTIVATION, + SVA_ST_ACTIVE, + SVA_ST_IN_INACTIVATION, + SVA_ST_LAST_ACTIVATE_DUMMY_STATE, + SVA_ST_ACTIVATE_TRANSITION_REJECTED +} t_sva_st_activate_state; + +/* + * Define the various transitions of the stab service + */ +typedef enum { + SVA_ST_CREATE, + SVA_ST_CONFIGURE, + SVA_ST_INTERNAL_NEEDS, + SVA_ST_ACTIVATE, + SVA_ST_INACTIVATE, + SVA_ST_CONTROL_START, + SVA_ST_CONTROL_STOP, + SVA_ST_CONTROL_ABORT, + SVA_ST_ALL_DEPENDENCIES_RESOLVED, + SVA_ST_PUSH, + SVA_ST_EVENT_EOK, + SVA_ST_EVENT_FAKE, + SVA_ST_EVENT_ACTIVE, + SVA_ST_EVENT_INACTIVE, + SVA_ST_RESET, + SVA_ST_CONTROL_DELETE, + SVA_ST_EVENT_ERROR, + SVA_ST_FLUSH_IN, + SVA_ST_FLUSH_OUT, + SVA_ST_CANCEL, + SVA_ST_UPDATE_PARAM, + SVA_ST_GET_PARAM_SIZE, + SVA_ST_LAST_DUMMY_TRANSITION +} t_sva_st_transition; + +/* + * Define the symbol used to qualify the state of the dependency + * for a given type of buffer + */ +typedef enum { + INTERNAL_DEPENDENCY, + NOT_RESOLVED_DEPENDENCY, + RESOLVED_DEPENDENCY +} t_sva_st_dependencies_state; + +/* + * Define the structure used to manage the subtasks dependency + */ +typedef struct { + t_sva_st_dependencies_state inputImageDep; + t_sva_st_dependencies_state stabParamDep; + t_sva_st_dependencies_state refImageDep; +} t_sva_st_dependencies_desc; + +/* + * Define the structure used to manage the dependencies of each subtasks + */ +typedef struct { + t_sva_tm_subtask_id subtaskId; + t_sva_st_dependencies_desc dependencies; +} t_sva_st_subtask_dependencies; + +/* + * Define the fifos used to manage the dependency + * The buffers, provided though the Push routine, are buffered inside the pushFifo + * When programming them (using them) into a subtask, then they are considered as used, + * as so pushed inside th inUseFifo + */ +typedef struct { + t_sva_fifo pushFifo; + t_sva_fifo inUseFifo; +} t_sva_st_fifo_dep; + +/* + * Define structure that contain horizontal and vertical signed offset + */ +typedef struct { +t_sint16 offsetX; +t_sint16 offsetY; +} t_sva_st_offset_signed_desc; + +/* + * Define the descriptor of a Stab service instance + */ +typedef struct { + t_sva_st_state state; + t_sva_service_id serviceId; + t_sva_st_activate_state activateState; + t_sva_st_dependencies_desc defaultDep; + t_sva_st_fifo_dep inputImageFifos; + t_sva_st_fifo_dep refImageFifos; + t_sva_st_fifo_dep stabParamFifos; + t_sva_fifo subtasksDependencyFifo; + t_sva_tm_subtask_id subtasksIdArray[SUBTASK_DEFAULT_NUMBER]; + t_sva_tm_subtask_list_id subtasksListId; + t_sva_sw_processing_configuration conf; + t_sva_sw_processing_status status; + t_sva_block_id motionBufferBlockId; + t_uint32 handleReferenceInitCnt; + t_sva_st_offset_signed_desc croppingVector; + /*esram block id and size*/ + t_sva_block_id esRamBlockId; + t_size esRamSize; +} t_sva_st_descriptor; + +#ifdef __DEBUG + /******************************************************************************/ + /* Trace Types definitions */ + /******************************************************************************/ + typedef struct { + t_sva_tm_virtual_hw_event_id event; + t_uint32 systemTime; + t_sva_tm_subtask_id subtaskId; + t_sva_service_id serviceId; + } t_sva_st_debug_event_desc; + typedef struct { + t_uint32 padding[3]; + t_uint32 nbOfEventReceived; + t_sva_st_debug_event_desc eventDebugDesc[LOG_DEPTH]; + } t_sva_st_debug_events; + + typedef struct { + t_sva_service_cmd_id command; + t_uint32 systemTime; + t_uint32 parameter; + t_uint32 padding; + } t_sva_st_debug_command_desc; + typedef struct { + t_uint32 padding[3]; + t_uint32 nbOfCommandReceived; + t_sva_st_debug_command_desc commandDebugDesc[LOG_DEPTH]; + } t_sva_st_debug_commands; + + typedef struct { + t_sva_st_state state;/*state before transition occur*/ + t_sva_st_transition transition; + t_uint32 systemTime; + t_sva_st_activate_state activateState;/*state before transition occur*/ + } t_sva_st_debug_transition_desc; + typedef struct { + t_uint32 padding[3]; + t_uint32 nbOfTransitionReceived; + t_sva_st_debug_transition_desc transitionDebugDesc[LOG_DEPTH]; + } t_sva_st_debug_transitions; +#endif + +#ifdef __cplusplus +} /* allow C++ to use these headers */ +#endif /* __cplusplus */ + +#endif /* __INC_SVA_STABP_H */ +/* End of file - sva_stabp.h */ --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_decode/jpeg/sva_sdc_jpeg.c @@ -0,0 +1,1047 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ +#include "hcl_defs.h" +#include "sva_host_interface.h" +#include "sva_buffermgt.h" +#include "sva_fifo.h" +#include "sva_still_decode.h" + +#include "../sva_sdc_algo.h" +#include "sva_sdc_jpeg.h" + +#include "sva_sdc_jpegp.h" + + +/*------------------------------------------------------------------------ + * Global Variables + *----------------------------------------------------------------------*/ +PRIVATE t_sva_sdc_jpeg_descriptor jpegStillDecodeDesc[NUM_MAX_JPEG_DECODE]; + +/*------------------------------------------------------------------------ + * Private functions + *----------------------------------------------------------------------*/ +PRIVATE t_bool sva_SDC_JPEG_CheckConfiguration(const t_sva_still_algo_jpeg_decoder_configuration_params *); + + +/****************************************************************************/ +/* NAME: sva_SDC_JPEG_InitAndConfigure() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: This routine enables to store all statical parameters */ +/* PARAMETERS: */ +/* IN : t_sva_still_decoder_instance_num instanceNum */ +/* OUT : */ +/* */ +/* RETURN: */ +/* t_sva_sdc_algo_error */ +/****************************************************************************/ +PUBLIC t_sva_sdc_algo_error sva_SDC_JPEG_InitAndConfigure( + t_sva_still_decoder_instance_num instanceNum, + t_sva_still_decoder_configuration const *pConf +) +/* TODO: need to check if jpeg decode configuration parameters are valid */ +{ + HCL_ASSERT(pConf!=NULL); + + INIT_FIFO(jpegStillDecodeDesc[instanceNum].fifoPushedInParam); + INIT_FIFO(jpegStillDecodeDesc[instanceNum].fifoInUseInParam); + INIT_FIFO(jpegStillDecodeDesc[instanceNum].fifoFreeInParam); + + INIT_FIFO(jpegStillDecodeDesc[instanceNum].fifoLineBufferBlock); + + INIT_FIFO(jpegStillDecodeDesc[instanceNum].fifoBitstream); + + /* a copy of the still-decode parameter and jpeg params are done here */ + jpegStillDecodeDesc[instanceNum].configuration = *pConf; + jpegStillDecodeDesc[instanceNum].jpegConfiguration = *((t_sva_still_algo_jpeg_decoder_configuration_params *)pConf->pAlgoConfig); + if (sva_SDC_JPEG_CheckConfiguration(&jpegStillDecodeDesc[instanceNum].jpegConfiguration)==FALSE) + { + return SVA_SDC_JPEG_PARAM_ERROR; + } + if((pConf->decodedFrameDesc.height> MAX_HEIGHT)||(pConf->decodedFrameDesc.width > MAX_WIDTH)) + { + return SVA_SDC_JPEG_PARAM_ERROR; + } + return SVA_SDC_ALGO_OK; +} + + + +/*****************************************************************************/ +/* NAME: sva_SDC_JPEG_GetMemoryNeeds() */ +/*---------------------------------------------------------------------------*/ +/* DESCRIPTION: determine cachable memory needs for software process */ +/* PARAMETERS: */ +/* IN : t_sva_still_decoder_instance_num instanceNum */ +/* OUT :t_size *pMemNeeds */ +/* */ +/* RETURN: */ +/* t_sva_sdc_algo_error */ +/*****************************************************************************/ + +PUBLIC t_sva_sdc_algo_error sva_SDC_JPEG_GetMemoryNeeds( + t_sva_still_decoder_instance_num instanceNum, + t_size *pMemNeeds, + t_size *pSizeNCNB +) +/* DONE */ +{ + t_size fifoSize; + + HCL_ASSERT(pMemNeeds != 0); + HCL_ASSERT(pSizeNCNB != 0); + *pMemNeeds = 0; + *pSizeNCNB = 0; + + { + t_sva_sampling_factor *pSampFactor; + t_uint16 maxhSampFactor,maxvSampFactor; + t_uint32 mcusInRow; + t_uint32 mcusInCol; + + /* Compute co-efficient buffer size */ + pSampFactor = &jpegStillDecodeDesc[instanceNum].jpegConfiguration.samplingFactor; + + maxhSampFactor = pSampFactor->hSamplingFactorY; + maxhSampFactor = (maxhSampFactor > pSampFactor->hSamplingFactorCb) ? maxhSampFactor: pSampFactor->hSamplingFactorCb; + maxhSampFactor = (maxhSampFactor > pSampFactor->hSamplingFactorCr) ? maxhSampFactor: pSampFactor->hSamplingFactorCr; + + maxvSampFactor = pSampFactor->vSamplingFactorY; + maxvSampFactor = (maxvSampFactor > pSampFactor->vSamplingFactorCb) ? maxvSampFactor: pSampFactor->vSamplingFactorCb; + maxvSampFactor = (maxvSampFactor > pSampFactor->vSamplingFactorCr) ? maxvSampFactor: pSampFactor->vSamplingFactorCr; + + mcusInRow = jpegStillDecodeDesc[instanceNum].configuration.crop_window.image.width / (8*maxhSampFactor); + mcusInCol = jpegStillDecodeDesc[instanceNum].configuration.crop_window.image.height / (8*maxvSampFactor); + + if ( ( jpegStillDecodeDesc[instanceNum].configuration.crop_window.image.width % (8* maxhSampFactor) ) != 0) mcusInRow++; + if ( ( jpegStillDecodeDesc[instanceNum].configuration.crop_window.image.height % (8* maxvSampFactor) ) != 0) mcusInCol++; + + jpegStillDecodeDesc[instanceNum].mcusInFrame = (t_uint32) mcusInRow * (t_uint32) mcusInCol; + + if(jpegStillDecodeDesc[instanceNum].configuration.transformId == SVA_DECODER_PROGRESSIVE_JPEG) + { + t_uint32 mcuByteSize; + t_uint32 bufferSize; + + + mcuByteSize = 64 * sizeof(t_uint16) *( + pSampFactor->hSamplingFactorY * pSampFactor->vSamplingFactorY + + pSampFactor->hSamplingFactorCb * pSampFactor->vSamplingFactorCb + + pSampFactor->hSamplingFactorCr * pSampFactor->vSamplingFactorCr ); + + bufferSize = jpegStillDecodeDesc[instanceNum].mcusInFrame * mcuByteSize; + + *pSizeNCNB+=bufferSize; + *pSizeNCNB+=256; + } + + } + + /* IN-Parameter free Fifo, ready-to-use Fifo and In-Use */ + GET_FIFO_MEMORY_NEEDS(t_sva_sdc_block, PUSH_FIFO_DEFAULT_SIZE, fifoSize); + *pMemNeeds += fifoSize; + GET_FIFO_MEMORY_NEEDS(t_sva_sdc_block, PUSH_FIFO_DEFAULT_SIZE, fifoSize); + *pMemNeeds += fifoSize; + GET_FIFO_MEMORY_NEEDS(t_sva_sdc_block, PUSH_FIFO_DEFAULT_SIZE, fifoSize); + *pMemNeeds += fifoSize; + + /* Line Buffer Fifo */ + GET_FIFO_MEMORY_NEEDS(t_sva_block_id, 1, fifoSize); + *pMemNeeds += fifoSize; + + /* Co-efficient Buffer Fifo for progressive mode*/ + GET_FIFO_MEMORY_NEEDS(t_sva_block_id, 1, fifoSize); + *pMemNeeds += fifoSize; + + /* Bitstream Buffer info Fifo for start of new scan*/ + GET_FIFO_MEMORY_NEEDS(t_sva_bitstream_desc, PUSH_FIFO_DEFAULT_SIZE, fifoSize); + *pMemNeeds += fifoSize; + + return SVA_SDC_ALGO_OK; +} + + +/****************************************************************************/ +/* NAME: sva_SDC_JPEG_ProvideMemoryNeeds() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: This routine enables to provide cachable memory needs */ +/* for encode fifos */ +/* PARAMETERS: */ +/* IN : t_sva_still_decoder_instance_num instanceNum */ +/* OUT : */ +/* */ +/* RETURN: */ +/* t_sva_sdc_algo_error */ +/****************************************************************************/ +PUBLIC t_sva_sdc_algo_error sva_SDC_JPEG_ProvideMemoryNeeds( + t_sva_still_decoder_instance_num instanceNum, + const t_sva_tm_subtask_id *pSubtaskIdArray, + t_system_address systemAddressNCNB, + t_size sizeNCNB +) +/* TODO: compute and allocate co-efficient buffer for progressive mode */ +{ + + t_sva_ff_error ffError; + t_sva_mm_error mmError; + t_sva_tm_error tmError; + t_uint32 lineBufferSize; + t_uint32 i; + t_system_address bufferAddr; + t_sva_vdc_frame_buffer_out outBuffer; + t_sva_block_id lineBufferBlockId; + t_sva_sdc_block inParamBlockDesc; + t_uint32 mcusInRow; + t_uint32 mcusInCol; + t_uint16 maxhSampFactor,maxvSampFactor; + t_sva_sampling_factor *pSampFactor; + + HCL_ASSERT(pSubtaskIdArray!=0); + + /* IN-Parameter free Fifo, ready-to-use Fifo and In-Use */ + CREATE_FIFO(t_sva_sdc_block, PUSH_FIFO_DEFAULT_SIZE, jpegStillDecodeDesc[instanceNum].fifoFreeInParam, ffError); + if (ffError != SVA_FIFO_OK) {return SVA_SDC_JPEG_FIFO_LINKED_ERROR;} + CREATE_FIFO(t_sva_sdc_block, PUSH_FIFO_DEFAULT_SIZE, jpegStillDecodeDesc[instanceNum].fifoPushedInParam, ffError); + if (ffError != SVA_FIFO_OK) {return SVA_SDC_JPEG_FIFO_LINKED_ERROR;} + CREATE_FIFO(t_sva_sdc_block, PUSH_FIFO_DEFAULT_SIZE, jpegStillDecodeDesc[instanceNum].fifoInUseInParam, ffError); + if (ffError != SVA_FIFO_OK) {return SVA_SDC_JPEG_FIFO_LINKED_ERROR;} + + /* Line Buffer Fifo */ + CREATE_FIFO(t_sva_block_id, 1, jpegStillDecodeDesc[instanceNum].fifoLineBufferBlock, ffError); + if (ffError != SVA_FIFO_OK) {return SVA_SDC_JPEG_FIFO_LINKED_ERROR;} + + /* Bitstream Buffer info Fifo for start of new scan*/ + CREATE_FIFO(t_sva_bitstream_desc, PUSH_FIFO_DEFAULT_SIZE, jpegStillDecodeDesc[instanceNum].fifoBitstream, ffError); + if (ffError != SVA_FIFO_OK) {return SVA_SDC_JPEG_FIFO_LINKED_ERROR;} + + /* Alloc block line Buffer */ + /* -------------------------- */ + outBuffer.addr_jpeg_line_buffer = 0; + outBuffer.addr_dest_buffer = 0; + outBuffer.addr_jpeg_coef_buffer = 0; + + /* Compute line buffer size */ + if((jpegStillDecodeDesc[instanceNum].jpegConfiguration.downsamplingFactor==SVA_DOWNSAMPLING_FACTOR_8)&&(jpegStillDecodeDesc[instanceNum].jpegConfiguration.samplingFactor.vSamplingFactorCb==1)&&(jpegStillDecodeDesc[instanceNum].jpegConfiguration.samplingFactor.vSamplingFactorY==1)&&(jpegStillDecodeDesc[instanceNum].jpegConfiguration.samplingFactor.vSamplingFactorCr==1)) + { + lineBufferSize = (t_uint32) ((((jpegStillDecodeDesc[instanceNum].configuration.decodedFrameDesc.width+15)>>4)<<4)>>1)*(8>>(t_uint8)(jpegStillDecodeDesc[instanceNum].jpegConfiguration.downsamplingFactor)); + + mmError=sva_MM_AllocBlock(SDRAM_ID,lineBufferSize,SVA_MM_ALIGN_16BYTES, &lineBufferBlockId); + if (mmError != SVA_MM_OK) {return(SVA_SDC_JPEG_PARAM_ERROR);} + + sva_MM_GetBlockSystemAddress(lineBufferBlockId, &bufferAddr); + outBuffer.addr_jpeg_line_buffer = bufferAddr.physical; + ffError=PUSH_FIFO_ELEM(jpegStillDecodeDesc[instanceNum].fifoLineBufferBlock,t_sva_block_id,lineBufferBlockId); + if (ffError!= SVA_FIFO_OK) {return SVA_SDC_JPEG_FIFO_FULL_ERROR;} + } + + /* Alloc block co-efficient Buffer */ + /* -------------------------- */ + + + /* Compute co-efficient buffer size */ + pSampFactor = &jpegStillDecodeDesc[instanceNum].jpegConfiguration.samplingFactor; + + maxhSampFactor = pSampFactor->hSamplingFactorY; + maxhSampFactor = (maxhSampFactor > pSampFactor->hSamplingFactorCb) ? maxhSampFactor: pSampFactor->hSamplingFactorCb; + maxhSampFactor = (maxhSampFactor > pSampFactor->hSamplingFactorCr) ? maxhSampFactor: pSampFactor->hSamplingFactorCr; + + maxvSampFactor = pSampFactor->vSamplingFactorY; + maxvSampFactor = (maxvSampFactor > pSampFactor->vSamplingFactorCb) ? maxvSampFactor: pSampFactor->vSamplingFactorCb; + maxvSampFactor = (maxvSampFactor > pSampFactor->vSamplingFactorCr) ? maxvSampFactor: pSampFactor->vSamplingFactorCr; + + mcusInRow = jpegStillDecodeDesc[instanceNum].configuration.crop_window.image.width / (8*maxhSampFactor); + mcusInCol = jpegStillDecodeDesc[instanceNum].configuration.crop_window.image.height / (8*maxvSampFactor); + + if ( ( jpegStillDecodeDesc[instanceNum].configuration.crop_window.image.width % (8* maxhSampFactor) ) != 0) mcusInRow++; + if ( ( jpegStillDecodeDesc[instanceNum].configuration.crop_window.image.height % (8* maxvSampFactor) ) != 0) mcusInCol++; + + jpegStillDecodeDesc[instanceNum].mcusInFrame = (t_uint32) mcusInRow * (t_uint32) mcusInCol; + + if(jpegStillDecodeDesc[instanceNum].configuration.transformId == SVA_DECODER_PROGRESSIVE_JPEG) + { + t_uint32 mcuByteSize; + t_uint32 bufferSize; + t_uint32 bufferSizeby4; + t_uint32 *coeffbuffAddr; + + mcuByteSize = 64 * sizeof(t_uint16) *( + pSampFactor->hSamplingFactorY * pSampFactor->vSamplingFactorY + + pSampFactor->hSamplingFactorCb * pSampFactor->vSamplingFactorCb + + pSampFactor->hSamplingFactorCr * pSampFactor->vSamplingFactorCr ); + + bufferSize = jpegStillDecodeDesc[instanceNum].mcusInFrame * mcuByteSize; + + if (bufferSize>sizeNCNB) + { + return SVA_SDC_JPEG_PARAM_ERROR; + } + + { + t_physical_address non_aligned_address = systemAddressNCNB.physical; + t_size aligned_size; + systemAddressNCNB.physical&=~SVA_MM_ALIGN_16BYTES; + systemAddressNCNB.physical+=16; + + aligned_size = systemAddressNCNB.physical - non_aligned_address; + + systemAddressNCNB.logical += aligned_size; + } + + bufferAddr = systemAddressNCNB; + + outBuffer.addr_jpeg_coef_buffer = bufferAddr.physical; + + /* reset co-efficient buffer to zero - temporarily */ + + bufferSizeby4 = bufferSize >> 2; + coeffbuffAddr = (t_uint32 *)bufferAddr.logical; + + /* co-efficient buffer is reset here */ + for(i = 0;i < bufferSizeby4; i++) + coeffbuffAddr[i] = 0; + } + + for(i = 0; i < SUBTASK_DEFAULT_NUMBER; i++) + { + tmError = sva_TM_InitSubTaskField(pSubtaskIdArray[i], SVA_TM_DEC_ADDR_OUT_FRAME_BUFFER, (t_uint32)&outBuffer, sizeof(t_sva_vdc_frame_buffer_out)); + HCL_DEBUG_ASSERT(tmError == SVA_TM_OK); + } + + /* Alloc block IN-PARAMETER Buffer */ + /* ------------------------------- */ + for(i = 0;i < PUSH_FIFO_DEFAULT_SIZE; i++) + { + t_sva_vdc_jpeg_param_in* pInParams; + t_sva_sampling_factor* pSamplingFactor; + + mmError = sva_MM_AllocBlock(SDRAM_ID,sizeof(t_sva_vdc_jpeg_param_in),SVA_MM_ALIGN_16BYTES, &inParamBlockDesc.blockId); + if (mmError != SVA_MM_OK) {return(SVA_SDC_JPEG_PARAM_ERROR);} + + sva_MM_GetBlockSystemAddress(inParamBlockDesc.blockId, &bufferAddr); + inParamBlockDesc.addr = bufferAddr; + + + pInParams = (t_sva_vdc_jpeg_param_in*)bufferAddr.logical; + + /* set transformation Id - whether sequential or, progressive */ + if(jpegStillDecodeDesc[instanceNum].configuration.transformId == SVA_DECODER_SEQUENTIAL_JPEG) + pInParams->progressive_mode = 0; + else if(jpegStillDecodeDesc[instanceNum].configuration.transformId == SVA_DECODER_PROGRESSIVE_JPEG) + pInParams->progressive_mode = 1; + + /* set image height and width */ + pInParams->frame_width = jpegStillDecodeDesc[instanceNum].configuration.decodedFrameDesc.width; + pInParams->frame_height = jpegStillDecodeDesc[instanceNum].configuration.decodedFrameDesc.height; + + pInParams->window_width = jpegStillDecodeDesc[instanceNum].configuration.crop_window.image.width; + pInParams->window_height = jpegStillDecodeDesc[instanceNum].configuration.crop_window.image.height; + pInParams->window_horizontal_offset = jpegStillDecodeDesc[instanceNum].configuration.crop_window.imageOffset.offsetX; + pInParams->window_vertical_offset = jpegStillDecodeDesc[instanceNum].configuration.crop_window.imageOffset.offsetY; + + /* set sampling factor */ + pSamplingFactor = (t_sva_sampling_factor*) &(pInParams->h_sampling_factor_y); + *pSamplingFactor = jpegStillDecodeDesc[instanceNum].jpegConfiguration.samplingFactor; + + /* set downsampling factor */ + pInParams->downsampling_factor = 1<<(t_uint32)jpegStillDecodeDesc[instanceNum].jpegConfiguration.downsamplingFactor; + + /* set number of frame components */ + if(jpegStillDecodeDesc[instanceNum].jpegConfiguration.colorMode == SVA_MONOCHROME) + { + pInParams->nb_components = 1; + pInParams->h_sampling_factor_cb = 0; + pInParams->v_sampling_factor_cb = 0; + pInParams->h_sampling_factor_cr = 0; + pInParams->v_sampling_factor_cr = 0; + } + else + pInParams->nb_components = 3; + + /* set ACE strength */ + pInParams->ace_enable = 1; + pInParams->ace_strength = (t_ushort_value)(jpegStillDecodeDesc[instanceNum].configuration.aceStrength); + + ffError = PUSH_FIFO_ELEM(jpegStillDecodeDesc[instanceNum].fifoFreeInParam,t_sva_sdc_block,inParamBlockDesc); + if (ffError != SVA_FIFO_OK) {return SVA_SDC_JPEG_FIFO_FULL_ERROR;} + } + + + for(i = 0;i < SUBTASK_DEFAULT_NUMBER; i++) + { + t_sva_vdc_jpeg_param_inout inoutBuffer; + + inoutBuffer.mcu_index = 0; + inoutBuffer.end_of_band_run = 0; + inoutBuffer.dc_predictor_y = 0; + inoutBuffer.dc_predictor_cb = 0; + inoutBuffer.dc_predictor_cr = 0; + inoutBuffer.ace_count0 = 0; + inoutBuffer.ace_count1 = 0; + inoutBuffer.ace_count2 = 0; + inoutBuffer.ace_count3 = 0; + inoutBuffer.crop_mcu_index = 0; + inoutBuffer.crop_mcu_index_in_row = 0; + + tmError = sva_TM_InitSubTaskField(pSubtaskIdArray[i], SVA_TM_DEC_ADDR_IN_FRAME_PARAMETERS, (t_uint32)&inoutBuffer, sizeof(t_sva_vdc_jpeg_param_inout)); + HCL_DEBUG_ASSERT(tmError == SVA_TM_OK); + } + + return SVA_SDC_ALGO_OK; +} + + +/****************************************************************************/ +/* NAME: sva_SDC_JPEG_SetHeaderInfos() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: This routine enables user to give Header Infos to the module*/ +/* PARAMETERS: */ +/* IN : t_sva_service_instance_num instanceNum */ +/* t_sva_buffer_id bufferId */ +/* t_uint32 byteOffset */ +/* t_uint32 bitOffset */ +/* const t_sva_header_infos *headerInfos */ +/* OUT :none */ +/* */ +/* RETURN: */ +/* t_sva_sdc_algo_error */ +/*--------------------------------------------------------------------------*/ +/* USE: NA */ +/* USED BY: NA */ +/****************************************************************************/ +PUBLIC t_sva_sdc_algo_error sva_SDC_JPEG_SetHeaderInfos( + t_sva_service_instance_num instanceNum, + t_sva_buffer_id bufferId, + t_uint32 byteOffset, + t_uint32 bitOffset, + const t_sva_header_infos *pHeaderInfos +) +{ + t_sva_ff_error ffError; + t_sva_still_decoder_algo_sequential_jpeg_header_infos *pSeqHeaderInfos=NULL; + t_sva_still_decoder_algo_progressive_jpeg_header_infos *pProgHeaderInfos=NULL; + t_sva_bitstream_desc bitstreamDesc; + t_sva_sdc_block inParamBlockDesc; + t_sva_vdc_jpeg_param_in* pInParams; + t_sva_buffer_status bufferStatus; + t_physical_address bufferStartAddr; + t_sva_bm_error bmError; + t_sva_error svaError; + t_sva_huffman_table *pHuffTable=NULL; + t_sva_quantization_table *pQuantTable=NULL; + t_uint16 i; + t_bool checkCb = TRUE; + t_bool checkAc = TRUE; + + HCL_ASSERT(pHeaderInfos!=NULL); + + //check that buffer is already pushed: ie is in "sva_BUFFER_IN_USE" state + svaError = SVA_GetBufferStatus(bufferId, &bufferStatus); + if (svaError != SVA_OK) {return SVA_SDC_ALGO_UNEXPECTED_API_CALL; } + +// HCL_DEBUG_ASSERT(bufferStatus.state == SVA_BUFFER_IN_USE); + if (bufferStatus.state != SVA_BUFFER_IN_USE) { return SVA_SDC_ALGO_UNEXPECTED_API_CALL; } + + /* Check input header info param */ + if (jpegStillDecodeDesc[instanceNum].configuration.transformId == SVA_DECODER_PROGRESSIVE_JPEG) + { + pProgHeaderInfos = (t_sva_still_decoder_algo_progressive_jpeg_header_infos *)pHeaderInfos; + //value: 0 = the Y/Cr/Cb component is not present in the current scan; 1 = present + if(pProgHeaderInfos->componentSelectorY>1 || pProgHeaderInfos->componentSelectorCb>1 || pProgHeaderInfos->componentSelectorCr>1) + { + return SVA_SDC_JPEG_PARAM_ERROR; + } + + // Spectral selection value range:0 to 63. + if(pProgHeaderInfos->startSpectralSelection>63 || pProgHeaderInfos->endSpectralSelection>63 || + pProgHeaderInfos->endSpectralSelectionstartSpectralSelection) + { + return SVA_SDC_JPEG_PARAM_ERROR; + } + pHuffTable = &pProgHeaderInfos->huffmanTable; + pQuantTable = &pProgHeaderInfos->quantizationTable; + if(pProgHeaderInfos->componentSelectorCb==0) + { checkCb = FALSE ; } + /* In progressive mode, the first Huffman table given has only Dc components + if both startSpectralSelction and endSpectralSelection are set to 0 + so do not check Ac components in this case */ + if((pProgHeaderInfos->startSpectralSelection == 0)&&(pProgHeaderInfos->endSpectralSelection == 0)) + { checkAc = FALSE ; } + + } + else if (jpegStillDecodeDesc[instanceNum].configuration.transformId == SVA_DECODER_SEQUENTIAL_JPEG) + { + + pSeqHeaderInfos = (t_sva_still_decoder_algo_sequential_jpeg_header_infos *)pHeaderInfos; + pHuffTable = &pSeqHeaderInfos->huffmanTable; + pQuantTable = &pSeqHeaderInfos->quantizationTable; + if(jpegStillDecodeDesc[instanceNum].jpegConfiguration.colorMode == SVA_MONOCHROME) + { checkCb = FALSE ; } + } + /* Check quant table and huffman table*/ + for (i=0; i<12; i++) + { + if(pHuffTable->huffmanYSizeDc[i] > 16) {return SVA_SDC_JPEG_PARAM_ERROR;} + if((checkCb == TRUE)&&(pHuffTable->huffmanCbSizeDc[i] > 16)) {return SVA_SDC_JPEG_PARAM_ERROR;} + } + if(checkAc == TRUE) + { + for (i=0; i<256; i++) + { + if(pHuffTable->huffmanYSizeAc[i]> 16) {return SVA_SDC_JPEG_PARAM_ERROR;} + if((checkCb == TRUE)&&(pHuffTable->huffmanCbSizeAc[i]> 16)) {return SVA_SDC_JPEG_PARAM_ERROR;} + } + } + + for (i=0; i<64; i++) + { + if(pQuantTable->quant_y[i]> 255) {return SVA_SDC_JPEG_PARAM_ERROR;} + if((checkCb == TRUE)&&((pQuantTable->quant_cb[i]> 255)||(pQuantTable->quant_cb[i]==0))) {return SVA_SDC_JPEG_PARAM_ERROR;} + } + + + /* Get a free IN-PARAMETERS structure */ + ffError = POP_FIFO_ELEM(jpegStillDecodeDesc[instanceNum].fifoFreeInParam,t_sva_sdc_block,inParamBlockDesc); + if (ffError != SVA_FIFO_OK) {return SVA_SDC_JPEG_FIFO_LINKED_ERROR;} + + pInParams = (t_sva_vdc_jpeg_param_in*)inParamBlockDesc.addr.logical; + /* Store dynamic parameters here */ + if (jpegStillDecodeDesc[instanceNum].configuration.transformId == SVA_DECODER_SEQUENTIAL_JPEG) + { + + pSeqHeaderInfos = (t_sva_still_decoder_algo_sequential_jpeg_header_infos *)pHeaderInfos; + pHuffTable = (t_sva_huffman_table *)&pInParams->huffman_y_code_dc[0]; + *pHuffTable = pSeqHeaderInfos->huffmanTable; + pQuantTable = (t_sva_quantization_table *)&pInParams->quant_y[0]; + *pQuantTable = pSeqHeaderInfos->quantizationTable; + /* set restart interval */ + pInParams->restart_interval = pSeqHeaderInfos->restartInterval; + + if(jpegStillDecodeDesc[instanceNum].jpegConfiguration.colorMode == SVA_MONOCHROME) + { + pInParams->nb_scan_components = 1; + pInParams->component_selector_y = 1; + pInParams->component_selector_cb = 0; + pInParams->component_selector_cr = 0; + } + else + { + pInParams->nb_scan_components = 3; + pInParams->component_selector_y = 1; + pInParams->component_selector_cb = 1; + pInParams->component_selector_cr = 1; + } + } + else if (jpegStillDecodeDesc[instanceNum].configuration.transformId == SVA_DECODER_PROGRESSIVE_JPEG) + { + pHuffTable = (t_sva_huffman_table *)&pInParams->huffman_y_code_dc[0]; + *pHuffTable = pProgHeaderInfos->huffmanTable; + pQuantTable = (t_sva_quantization_table *)&pInParams->quant_y[0]; + *pQuantTable = pProgHeaderInfos->quantizationTable; + + pInParams->restart_interval = pProgHeaderInfos->restartInterval; + pInParams->nb_scan_components = pProgHeaderInfos->nbScanComponents; + pInParams->component_selector_y = pProgHeaderInfos->componentSelectorY; + pInParams->component_selector_cb = pProgHeaderInfos->componentSelectorCb; + pInParams->component_selector_cr = pProgHeaderInfos->componentSelectorCr; + pInParams->start_spectral_selection = pProgHeaderInfos->startSpectralSelection; + pInParams->end_spectral_selection = pProgHeaderInfos->endSpectralSelection; + pInParams->successive_approx_position = pProgHeaderInfos->successiveApproxPosition; + } + + /* Store completed params in pushed fifo */ + ffError = PUSH_FIFO_ELEM(jpegStillDecodeDesc[instanceNum].fifoPushedInParam, t_sva_sdc_block, inParamBlockDesc); + if (ffError != SVA_FIFO_OK) {return SVA_SDC_JPEG_FIFO_FULL_ERROR;} + + bmError = sva_BM_GetBufferPhysicalAddress(bufferId, &bufferStartAddr); + if (bmError != SVA_BM_OK) {return SVA_SDC_ALGO_UNEXPECTED_API_CALL; } + + + /*Store bitstream position in fifoBitstream*/ + //This field will be setted in sva_DC_TryToInitBitstreamFields as decode module manages bitstrem buffer list + bitstreamDesc.bitstreamPosition.addr_bitstream_buf_struct = 0;//address of bitstream buffer list will be updated by ResolveDependancies() (should be multiple of 16) + bitstreamDesc.bitstreamPosition.addr_bitstream_start = ((byteOffset >> 4) <<4) + bufferStartAddr; //in bytes (Should be aligned on 16 bytes + absolute address) + bitstreamDesc.bitstreamPosition.bitstream_offset = (byteOffset - ((byteOffset >> 4) <<4)) * 8 + bitOffset; //Is the offset in bits between aligned address and provided no aligned address in byte + user offset + bitstreamDesc.relatedBufferId = bufferId; + ffError = PUSH_FIFO_ELEM(jpegStillDecodeDesc[instanceNum].fifoBitstream, t_sva_bitstream_desc, bitstreamDesc); + if (ffError != SVA_FIFO_OK) {return SVA_SDC_JPEG_FIFO_FULL_ERROR;} + + return SVA_SDC_ALGO_OK; +} + + +/****************************************************************************/ +/* NAME: sva_SDC_JPEG_AreNextFrameInfosAvailable() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: This routine enables user to Header Infos for new scan is */ +/* available */ +/* PARAMETERS: */ +/* IN : t_sva_service_instance_num instanceNum */ +/* OUT: t_bool pCond */ +/* */ +/* RETURN: */ +/* t_sva_sdc_algo_error */ +/*--------------------------------------------------------------------------*/ +/* USE: NA */ +/* USED BY: NA */ +/****************************************************************************/ +PUBLIC t_sva_sdc_algo_error sva_SDC_JPEG_AreNextFrameInfosAvailable( + t_sva_service_instance_num instanceNum, + t_bool* pCond +) +{ + HCL_ASSERT(pCond!=NULL); + + if(IS_FIFO_EMPTY(jpegStillDecodeDesc[instanceNum].fifoPushedInParam) == FALSE) + *pCond = TRUE; + else + *pCond = FALSE; + + return SVA_SDC_ALGO_OK; +} + + +/****************************************************************************/ +/* NAME: sva_SDC_JPEG_GetNextFrameParamsIn() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: This routine enables user to get Header Infos to the module*/ +/* PARAMETERS: */ +/* IN : t_sva_service_instance_num instanceNum */ +/* OUT: t_physical_address* frameParmIn */ +/* t_sva_bitstream_desc* bitsDesc */ +/* */ +/* RETURN: */ +/* t_sva_sdc_algo_error */ +/*--------------------------------------------------------------------------*/ +/* USE: NA */ +/* USED BY: NA */ +/****************************************************************************/ +PUBLIC t_sva_sdc_algo_error sva_SDC_JPEG_GetNextFrameParamsIn( + t_sva_service_instance_num instanceNum, + t_physical_address* frameParamIn, + t_sva_bitstream_desc* bitsDesc +) +{ + t_sva_sdc_block inParamBlockDesc; + t_sva_ff_error ffError; + + HCL_ASSERT((frameParamIn!=NULL)&&(bitsDesc!=NULL)); + + if(IS_FIFO_EMPTY(jpegStillDecodeDesc[instanceNum].fifoPushedInParam) == TRUE){return SVA_SDC_ALGO_UNEXPECTED_API_CALL;} + ffError = POP_FIFO_ELEM(jpegStillDecodeDesc[instanceNum].fifoPushedInParam, t_sva_sdc_block, inParamBlockDesc); + if (ffError != SVA_FIFO_OK) {return SVA_SDC_JPEG_FIFO_LINKED_ERROR;} + *frameParamIn = inParamBlockDesc.addr.physical; + + ffError = PUSH_FIFO_ELEM(jpegStillDecodeDesc[instanceNum].fifoInUseInParam, t_sva_sdc_block, inParamBlockDesc); + if (ffError != SVA_FIFO_OK) {return SVA_SDC_JPEG_FIFO_FULL_ERROR;} + + ffError = POP_FIFO_ELEM(jpegStillDecodeDesc[instanceNum].fifoBitstream, t_sva_bitstream_desc, *bitsDesc); + if (ffError != SVA_FIFO_OK) {return SVA_SDC_JPEG_FIFO_LINKED_ERROR;} + + return SVA_SDC_ALGO_OK; +} + + +/****************************************************************************/ +/* NAME: sva_SDC_JPEG_GetParamBufferSize() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: This routine enables user to get the param buffer size */ +/* PARAMETERS: */ +/* IN : t_sva_service_instance_num instanceNum */ +/* OUT: t_size* size of param buffer */ +/* */ +/* RETURN: */ +/* t_sva_sdc_algo_error */ +/*--------------------------------------------------------------------------*/ +/* USE: NA */ +/* USED BY: NA */ +/****************************************************************************/ +PUBLIC t_sva_sdc_algo_error sva_SDC_JPEG_GetParamBufferSize( + t_sva_service_instance_num instanceNum, + t_size* pSize +) +{ + HCL_ASSERT(pSize!=NULL); + + *pSize = sizeof(t_sva_ace_offset); + + return SVA_SDC_ALGO_OK; +} + + +/****************************************************************************/ +/* NAME: sva_SDC_JPEG_FlushFifos() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: This routine enables user to flush internal fifos */ +/* PARAMETERS: */ +/* IN : t_sva_service_instance_num instanceNum */ +/* */ +/* RETURN: */ +/* t_sva_sdc_algo_error */ +/*--------------------------------------------------------------------------*/ +/* USE: NA */ +/* USED BY: NA */ +/****************************************************************************/ +PUBLIC t_sva_sdc_algo_error sva_SDC_JPEG_FlushFifos( + t_sva_service_instance_num instanceNum +) +{ + t_sva_ff_error ffError; + t_sva_sdc_block inParamBlockDesc; + while(IS_FIFO_EMPTY(jpegStillDecodeDesc[instanceNum].fifoPushedInParam) == FALSE) + { + ffError=POP_FIFO_ELEM(jpegStillDecodeDesc[instanceNum].fifoPushedInParam,t_sva_sdc_block,inParamBlockDesc); + if (ffError != SVA_FIFO_OK) {return SVA_SDC_JPEG_FIFO_LINKED_ERROR;} + ffError = PUSH_FIFO_ELEM(jpegStillDecodeDesc[instanceNum].fifoFreeInParam, t_sva_sdc_block, inParamBlockDesc); + if (ffError != SVA_FIFO_OK) {return SVA_SDC_JPEG_FIFO_FULL_ERROR;} + + } + + while(IS_FIFO_EMPTY(jpegStillDecodeDesc[instanceNum].fifoInUseInParam) == FALSE) + { + ffError = POP_FIFO_ELEM(jpegStillDecodeDesc[instanceNum].fifoInUseInParam, t_sva_sdc_block, inParamBlockDesc); + if (ffError != SVA_FIFO_OK) {return SVA_SDC_JPEG_FIFO_LINKED_ERROR;} + ffError = PUSH_FIFO_ELEM(jpegStillDecodeDesc[instanceNum].fifoFreeInParam, t_sva_sdc_block, inParamBlockDesc); + if (ffError != SVA_FIFO_OK) {return SVA_SDC_JPEG_FIFO_FULL_ERROR;} + + } + + jpegStillDecodeDesc[instanceNum].lastMcuIndex = 0; + + return SVA_SDC_ALGO_OK; +} + + +/****************************************************************************/ +/* NAME: sva_SDC_JPEG_Close() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: This routine enables user to delete all allocated memory */ +/* PARAMETERS: */ +/* IN : t_sva_service_instance_num instanceNum */ +/* */ +/* RETURN: */ +/* t_sva_sdc_algo_error */ +/*--------------------------------------------------------------------------*/ +/* USE: NA */ +/* USED BY: NA */ +/****************************************************************************/ +PUBLIC t_sva_sdc_algo_error sva_SDC_JPEG_Close( + t_sva_service_instance_num instanceNum +) +{ + t_sva_ff_error ffError; + t_sva_mm_error mmError; + t_sva_sdc_block inParamBlockDesc; + t_sva_block_id block; + + /* delete in-parameters Fifos */ + while(IS_FIFO_EMPTY(jpegStillDecodeDesc[instanceNum].fifoPushedInParam) == FALSE) + { + ffError = POP_FIFO_ELEM(jpegStillDecodeDesc[instanceNum].fifoPushedInParam, t_sva_sdc_block, inParamBlockDesc); + if (ffError != SVA_FIFO_OK) {return SVA_SDC_JPEG_FIFO_LINKED_ERROR;} + mmError = sva_MM_FreeBlock(inParamBlockDesc.blockId); + if (mmError != SVA_MM_OK) {return(SVA_SDC_JPEG_FIFO_LINKED_ERROR);} + } + + while(IS_FIFO_EMPTY(jpegStillDecodeDesc[instanceNum].fifoInUseInParam) == FALSE) + { + ffError = POP_FIFO_ELEM(jpegStillDecodeDesc[instanceNum].fifoInUseInParam, t_sva_sdc_block, inParamBlockDesc); + if (ffError != SVA_FIFO_OK) {return SVA_SDC_JPEG_FIFO_LINKED_ERROR;} + mmError = sva_MM_FreeBlock(inParamBlockDesc.blockId); + if (mmError != SVA_MM_OK) {return(SVA_SDC_JPEG_FIFO_LINKED_ERROR);} + } + + while(IS_FIFO_EMPTY(jpegStillDecodeDesc[instanceNum].fifoFreeInParam) == FALSE) + { + ffError = POP_FIFO_ELEM(jpegStillDecodeDesc[instanceNum].fifoFreeInParam, t_sva_sdc_block, inParamBlockDesc); + if (ffError!= SVA_FIFO_OK) {return SVA_SDC_JPEG_FIFO_LINKED_ERROR;} + mmError = sva_MM_FreeBlock(inParamBlockDesc.blockId); + if (mmError != SVA_MM_OK) {return(SVA_SDC_JPEG_FIFO_LINKED_ERROR);} + } + /* delete line buffer block */ + while(IS_FIFO_EMPTY(jpegStillDecodeDesc[instanceNum].fifoLineBufferBlock) == FALSE) + { + ffError = POP_FIFO_ELEM(jpegStillDecodeDesc[instanceNum].fifoLineBufferBlock, t_sva_block_id, block); + if (ffError != SVA_FIFO_OK) {return SVA_SDC_JPEG_FIFO_LINKED_ERROR;} + mmError = sva_MM_FreeBlock(block); + if (mmError != SVA_MM_OK) {return(SVA_SDC_JPEG_FIFO_LINKED_ERROR);} + } + + DELETE_FIFO(jpegStillDecodeDesc[instanceNum].fifoPushedInParam); + DELETE_FIFO(jpegStillDecodeDesc[instanceNum].fifoInUseInParam); + DELETE_FIFO(jpegStillDecodeDesc[instanceNum].fifoFreeInParam); + + DELETE_FIFO(jpegStillDecodeDesc[instanceNum].fifoLineBufferBlock); + + DELETE_FIFO(jpegStillDecodeDesc[instanceNum].fifoBitstream); + + jpegStillDecodeDesc[instanceNum].lastMcuIndex = 0; + + /* TODO: must be made zero during reset */ + jpegStillDecodeDesc[instanceNum].mcusInFrame = 0; + + return SVA_SDC_ALGO_OK; +} + + +/****************************************************************************/ +/* NAME: sva_SDC_JPEG_CleanupTaskEnd() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: This routine enables user to cleanup and reset structure */ +/* at the end of a scan decoding */ +/* PARAMETERS: */ +/* IN : t_sva_service_instance_num instanceNum */ +/* t_sva_tm_subtask_id subtaskId: */ +/* */ +/* RETURN: */ +/* t_sva_sdc_algo_error */ +/*--------------------------------------------------------------------------*/ +/* USE: NA */ +/* USED BY: NA */ +/****************************************************************************/ + +PUBLIC t_sva_sdc_algo_error sva_SDC_JPEG_CleanupTaskEnd( + t_sva_service_instance_num instanceNum, t_sva_tm_subtask_id subtaskId +) +{ + t_sva_ff_error ffError; + t_sva_tm_error tmError; + t_sva_sdc_block inParamBlockDesc; + t_sva_vdc_jpeg_param_inout inoutBuffer; + + ffError = POP_FIFO_ELEM(jpegStillDecodeDesc[instanceNum].fifoInUseInParam, t_sva_sdc_block, inParamBlockDesc); + if (ffError != SVA_FIFO_OK) {return SVA_SDC_JPEG_FIFO_LINKED_ERROR;} + ffError = PUSH_FIFO_ELEM(jpegStillDecodeDesc[instanceNum].fifoFreeInParam,t_sva_sdc_block,inParamBlockDesc); + if (ffError != SVA_FIFO_OK) {return SVA_SDC_JPEG_FIFO_FULL_ERROR;} + + inoutBuffer.mcu_index = 0; + inoutBuffer.end_of_band_run = 0; + inoutBuffer.dc_predictor_y = 0; + inoutBuffer.dc_predictor_cb = 0; + inoutBuffer.dc_predictor_cr = 0; + inoutBuffer.ace_count0 = 0; + inoutBuffer.ace_count1 = 0; + inoutBuffer.ace_count2 = 0; + inoutBuffer.ace_count3 = 0; + inoutBuffer.crop_mcu_index = 0; + inoutBuffer.crop_mcu_index_in_row = 0; + + jpegStillDecodeDesc[instanceNum].lastMcuIndex = 0; + + tmError = sva_TM_InitSubTaskField(subtaskId, SVA_TM_DEC_ADDR_IN_FRAME_PARAMETERS, (t_uint32)&inoutBuffer, sizeof(t_sva_vdc_jpeg_param_inout)); + HCL_DEBUG_ASSERT(tmError == SVA_TM_OK); + + return SVA_SDC_ALGO_OK; +} + + +/****************************************************************************/ +/* NAME: sva_SDC_JPEG_GetDecodeStatus() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: This routine enables user to know what is the status of */ +/* at the end of a sub-task */ +/* PARAMETERS: */ +/* IN : instanceNum */ +/* subtaskId: subtask id for which the decode status is being enquired */ +/* OUT : pDecodeStatus: whether decode had no progress, some progress, */ +/* or, has been completed */ +/* */ +/* RETURN: */ +/* t_sva_sdc_algo_error */ +/*--------------------------------------------------------------------------*/ +/* USE: NA */ +/* USED BY: NA */ +/****************************************************************************/ +PUBLIC t_sva_sdc_algo_error sva_SDC_JPEG_GetDecodeStatus ( + t_sva_service_instance_num instanceNum, + t_sva_tm_subtask_id subtaskId, + t_sva_sdc_decode_status* pDecodeStatus, + t_uint32* pExtraInfo +) +{ + t_sva_tm_error tmError; + t_sva_vdc_jpeg_param_inout paramInOut; + t_uint32 downsampledBlock; + + HCL_ASSERT(pDecodeStatus != 0); + HCL_ASSERT(pExtraInfo != 0); + + *pDecodeStatus = SVA_SDC_DECODE_NOPROGRESS; + *pExtraInfo = 0; + + tmError = sva_TM_GetSubTaskField(subtaskId,SVA_TM_DEC_ADDR_OUT_FRAME_PARAMETERS, (t_logical_address)¶mInOut, 0, sizeof(t_sva_vdc_jpeg_param_inout), FALSE); + if(tmError != SVA_TM_OK) {return SVA_SDC_ALGO_TM_LINKED_ERROR;} + + if (jpegStillDecodeDesc[instanceNum].configuration.transformId == SVA_DECODER_PROGRESSIVE_JPEG) + { + /* TODO: does not handle all the conditions, what if no decode is done at all?? */ + /* a possible solution is that the firmware doesnot reset inout parameter at end of task for progressive mode */ + if(paramInOut.mcu_index == 0 && paramInOut.end_of_band_run == 0) + *pDecodeStatus = SVA_SDC_DECODE_COMPLETE; + } + else if (jpegStillDecodeDesc[instanceNum].configuration.transformId == SVA_DECODER_SEQUENTIAL_JPEG) + { + if (jpegStillDecodeDesc[instanceNum].mcusInFrame == paramInOut.mcu_index) + *pDecodeStatus = SVA_SDC_DECODE_COMPLETE; + else if(jpegStillDecodeDesc[instanceNum].lastMcuIndex < paramInOut.mcu_index) + { + *pDecodeStatus = SVA_SDC_DECODE_INCOMPLETE; + /* an 8x8 block contains 64 bytes */ + downsampledBlock = ((64 >> (t_uint32)jpegStillDecodeDesc[instanceNum].jpegConfiguration.downsamplingFactor) >> (t_uint32)jpegStillDecodeDesc[instanceNum].jpegConfiguration.downsamplingFactor); + /* decoder always returns in YUV420 macroblock format */ + *pExtraInfo = paramInOut.mcu_index * 6 * downsampledBlock; /* YUV420 format consists of 4 Y blocks and 1 Cr and Cb blocks each */ + jpegStillDecodeDesc[instanceNum].lastMcuIndex = paramInOut.mcu_index; + } + } + /* else not required */ + + return SVA_SDC_ALGO_OK; +} + + +/****************************************************************************/ +/* NAME: sva_SDC_JPEG_SetParamBuffer() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: This routine enables user to set ACE parameter in user buffer*/ +/* PARAMETERS: */ +/* IN : instanceNum */ +/* OUT : addr: address of the ACE buffer */ +/* */ +/* RETURN: */ +/* t_sva_sdc_algo_error */ +/*--------------------------------------------------------------------------*/ +/* USE: NA */ +/* USED BY: NA */ +/****************************************************************************/ + + +PUBLIC t_sva_sdc_algo_error sva_SDC_JPEG_SetParamBuffer ( + t_sva_service_instance_num instanceNum, + t_sva_tm_subtask_id subtaskId, + t_logical_address addr +) +{ + t_sva_tm_error tmError; + t_sva_vdc_jpeg_param_out paramOut; + t_sva_ace_offset *pAceOffset; + tmError = sva_TM_GetSubTaskField(subtaskId, SVA_TM_DEC_ADDR_OUT_PARAMETERS,(t_uint32)¶mOut, 0, sizeof(t_sva_vdc_jpeg_param_out), TRUE); + if(tmError != SVA_TM_OK) {return SVA_SDC_ALGO_TM_LINKED_ERROR;} + pAceOffset = (t_sva_ace_offset *) addr; + + pAceOffset->ace_offset_0 = paramOut.ace_offset0; + pAceOffset->ace_offset_1 = paramOut.ace_offset1; + pAceOffset->ace_offset_2 = paramOut.ace_offset2; + pAceOffset->ace_offset_3 = paramOut.ace_offset3; + + return SVA_SDC_ALGO_OK; +} + +/****************************************************************************/ +/* NAME: sva_SDC_JPEG_SetStartCodeValueForFakeBuffer() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: This routines copy a specific pattern at a given position */ +/* that has to ba used in a fake bitstream buffer */ +/* PARAMETERS: */ +/* IN : systemAddress */ +/* OUT : */ +/* */ +/* RETURN: */ +/* SVA_SDC_ALGO_OK */ +/*--------------------------------------------------------------------------*/ +/* USE: NA */ +/* USED BY: NA */ +/****************************************************************************/ +PUBLIC t_sva_sdc_algo_error sva_SDC_JPEG_SetStartCodeValueForFakeBuffer ( + t_system_address systemAddress) +{ + t_uint8 * temp; + + /* marker added at the beginning of the fake bitstream so that error is generated */ + temp = (t_uint8*) systemAddress.logical; + temp[0] = 0xFF; + temp[1] = 0xFF; + temp[2] = 0xFF; + temp[3] = 0xFF; + temp[4] = 0xFF; + temp[5] = 0xFF; + + return SVA_SDC_ALGO_OK; +} + +/****************************************************************************/ +/* NAME: sva_SDC_JPEG_CheckConfiguration() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: This routine enables user to know whether jpeg related */ +/* configuration is valid */ +/* PARAMETERS: */ +/* IN : pJpegConfig */ +/* OUT : */ +/* */ +/* RETURN: */ +/* t_bool */ +/*--------------------------------------------------------------------------*/ +/* USE: NA */ +/* USED BY: NA */ +/****************************************************************************/ + + + +PRIVATE t_bool sva_SDC_JPEG_CheckConfiguration( + const t_sva_still_algo_jpeg_decoder_configuration_params * pJpegConfig +) +{ + HCL_ASSERT(pJpegConfig!=NULL); + + if ( (pJpegConfig->colorMode != SVA_MONOCHROME) && (pJpegConfig->colorMode != SVA_COLOR) ) + return FALSE; + + /* sampling factor must be 1, 2 or 4 */ + CHECK_RANGE(pJpegConfig->samplingFactor.hSamplingFactorY, 1, 4); + CHECK_RANGE(pJpegConfig->samplingFactor.vSamplingFactorY, 1, 4); + if( pJpegConfig->samplingFactor.hSamplingFactorY ==3 || + pJpegConfig->samplingFactor.vSamplingFactorY ==3) + { + return FALSE; + } + + /* if monochrome, component_selector_cb/cr will be set to 0, + so cb/cr_sampling_factor not used */ + if(pJpegConfig->colorMode !=SVA_MONOCHROME) + { + /* sampling factor must be 1, 2 or 4 */ + CHECK_RANGE(pJpegConfig->samplingFactor.hSamplingFactorCb, 1, 4); + CHECK_RANGE(pJpegConfig->samplingFactor.hSamplingFactorCr, 1, 4); + CHECK_RANGE(pJpegConfig->samplingFactor.vSamplingFactorCb, 1, 4); + CHECK_RANGE(pJpegConfig->samplingFactor.vSamplingFactorCr, 1, 4); + + if(pJpegConfig->samplingFactor.hSamplingFactorCb ==3 || + pJpegConfig->samplingFactor.hSamplingFactorCr ==3 || + pJpegConfig->samplingFactor.vSamplingFactorCb ==3 || + pJpegConfig->samplingFactor.vSamplingFactorCr ==3 + ) + { + return FALSE; + } + } + + + CHECK_RANGE0(pJpegConfig->downsamplingFactor,SVA_DOWNSAMPLING_FACTOR_1,SVA_DOWNSAMPLING_FACTOR_8); + + return TRUE; +} + + --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_decode/jpeg/sva_sdc_jpeg.h @@ -0,0 +1,70 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ +#ifndef __INC_SVA_SDC_JPEG_H +#define __INC_SVA_SDC_JPEG_H +#define MAX_WIDTH 4080 +#define MAX_HEIGHT 4080 + +#include "hcl_defs.h" +#include "sva_still_decode.h" +#include "../sva_sdc_algo.h" +#include "sva.h" + +/******************************************************************************/ +/* Constants definitions */ +/******************************************************************************/ + + +/******************************************************************************/ +/* Types definitions */ +/******************************************************************************/ + +typedef struct { + t_sva_block_id blockId; + t_system_address addr; +} t_sva_sdc_block; + +/******************************************************************************/ +/* PUBLIC Functions */ +/******************************************************************************/ +PUBLIC t_sva_sdc_algo_error sva_SDC_JPEG_InitAndConfigure(t_sva_still_decoder_instance_num,const t_sva_still_decoder_configuration *); +PUBLIC t_sva_sdc_algo_error sva_SDC_JPEG_GetMemoryNeeds(t_sva_still_decoder_instance_num,t_size *,t_size *); +PUBLIC t_sva_sdc_algo_error sva_SDC_JPEG_ProvideMemoryNeeds(t_sva_still_decoder_instance_num, const t_sva_tm_subtask_id *, t_system_address, t_size); +//PUBLIC t_sva_sdc_algo_error sva_SDC_JPEG_GetFrameBufferOut(t_sva_still_decoder_instance_num, t_sva_vdc_frame_buffer_out * frameBufferOut); +//PUBLIC t_sva_sdc_algo_error sva_SDC_JPEG_GetOutParamsAdderessAndSize(t_sva_still_decoder_instance_num instanceNb, t_logical_address addr, t_size * pSize); +//PUBLIC t_sva_sdc_algo_error sva_SDC_JPEG_GetParamBufferSize(t_sva_still_decoder_instance_num instanceNb, t_size * pSize); +//PUBLIC t_sva_sdc_algo_error sva_SDC_JPEG_FillParamBuffer(t_sva_still_decoder_instance_num instanceNb, t_logical_address addr); +PUBLIC t_sva_sdc_algo_error sva_SDC_JPEG_SetHeaderInfos(t_sva_service_instance_num, t_sva_buffer_id, t_uint32, t_uint32, const t_sva_header_infos *); +PUBLIC t_sva_sdc_algo_error sva_SDC_JPEG_AreNextFrameInfosAvailable (t_sva_service_instance_num, t_bool*); +PUBLIC t_sva_sdc_algo_error sva_SDC_JPEG_GetNextFrameParamsIn (t_sva_still_decoder_instance_num, t_physical_address*, t_sva_bitstream_desc*); +//PUBLIC t_sva_dc_algo_error sva_DC_JPEG_GetLastErrorType(t_sva_service_instance_num instanceNb, t_uint16 * pErrorType); +PUBLIC t_sva_sdc_algo_error sva_SDC_JPEG_GetParamBufferSize (t_sva_still_decoder_instance_num, t_size*); +PUBLIC t_sva_sdc_algo_error sva_SDC_JPEG_FlushFifos (t_sva_service_instance_num); +PUBLIC t_sva_sdc_algo_error sva_SDC_JPEG_Close (t_sva_service_instance_num); +PUBLIC t_sva_sdc_algo_error sva_SDC_JPEG_CleanupTaskEnd (t_sva_service_instance_num, t_sva_tm_subtask_id); +PUBLIC t_sva_sdc_algo_error sva_SDC_JPEG_GetDecodeStatus (t_sva_service_instance_num, t_sva_tm_subtask_id, t_sva_sdc_decode_status*, t_uint32*); +PUBLIC t_sva_sdc_algo_error sva_SDC_JPEG_SetParamBuffer (t_sva_service_instance_num, t_sva_tm_subtask_id, t_logical_address); +PUBLIC t_sva_sdc_algo_error sva_SDC_JPEG_SetStartCodeValueForFakeBuffer (t_system_address); + +#ifdef __cplusplus +} /* allow C++ to use these headers */ +#endif /* __cplusplus */ + +#endif /* __INC_SVA_SEC_JPEG_H */ +/* End of file - sva_sec_jpeg.h */ --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_decode/jpeg/sva_sdc_jpegp.h @@ -0,0 +1,74 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ + +#ifndef __INC_SVA_SDC_JPEGP_H +#define __INC_SVA_SDC_JPEGP_H + +#include "hcl_defs.h" +#include "sva_still_decode.h" +#include "../sva_sdc_algo.h" +#include "sva.h" + +/******************************************************************************/ +/* Constants definitions */ +/******************************************************************************/ +/* + * Define the maximum number of jpeg decode structure to maintain + */ +#define NUM_MAX_JPEG_DECODE 8 + + + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ +/******************************************************************************/ +/* Types definitions */ +/******************************************************************************/ + +typedef enum { + SVA_SDC_JPEG_PROGRESSIVE_ALGO, + SVA_SDC_JPEG_SEQUENTIAL_ALGO +} t_sva_sdc_jpeg_algo; + + +/* + * Define the descriptor of a jpeg still decode instance + */ +typedef struct { + t_sva_still_decoder_configuration configuration; + t_sva_still_algo_jpeg_decoder_configuration_params jpegConfiguration; + t_sva_fifo fifoFreeInParam; + t_sva_fifo fifoPushedInParam; + t_sva_fifo fifoInUseInParam; + t_sva_fifo fifoBitstream; + + t_sva_fifo fifoLineBufferBlock; + + t_uint32 lastMcuIndex; + t_uint32 mcusInFrame; +} t_sva_sdc_jpeg_descriptor; + + +#ifdef __cplusplus +} /* allow C++ to use these headers */ +#endif /* __cplusplus */ + +#endif /* __INC_SVA_SDC_JPEGP_H */ +/* End of file - sva_sdc_jpegp.h */ --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_decode/sva_sdc_algo.h @@ -0,0 +1,96 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ + +#ifndef __INC_SVA_SDC_ALGO_H +#define __INC_SVA_SDC_ALGO_H + +#include "hcl_defs.h" +#include "sva.h" +#include "sva_still_decode.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/******************************************************************************/ +/* Constants definitions */ +/******************************************************************************/ +/* + * define Size and source format for various image type + * needed by jpeg ... +*/ + + +/******************************************************************************/ +/* Types definitions */ +/******************************************************************************/ + +typedef enum { + SVA_SDC_JPEG_PARAM_ERROR = 1, + SVA_SDC_JPEG_FIFO_LINKED_ERROR, + SVA_SDC_ALGO_TM_LINKED_ERROR, + SVA_SDC_JPEG_FIFO_FULL_ERROR, + SVA_SDC_ALGO_UNEXPECTED_API_CALL, + SVA_SDC_ALGO_OK = HCL_OK + +} t_sva_sdc_algo_error; + +typedef struct{ + +/* + * + * Allows to init and configure a given encoder + */ +t_sva_sdc_algo_error (*pInitAndConfigure) (t_sva_still_decoder_instance_num, const t_sva_still_decoder_configuration * ); + +/* + * Allows to set the static parameter of a given encoder + */ +t_sva_sdc_algo_error (*pGetMemoryNeeds) (t_sva_still_decoder_instance_num,t_size *, t_size *); + +t_sva_sdc_algo_error (*pProvideMemoryNeeds)(t_sva_still_decoder_instance_num, const t_sva_tm_subtask_id *, t_system_address, t_size); + +t_sva_sdc_algo_error (*pGetNextFrameParamsIn) (t_sva_still_decoder_instance_num, t_physical_address*, t_sva_bitstream_desc*); + +t_sva_sdc_algo_error (*pAreNextFrameInfosAvailable) (t_sva_service_instance_num, t_bool*); + +t_sva_sdc_algo_error (*pSetHeaderInfos) (t_sva_service_instance_num, t_sva_buffer_id, t_uint32, t_uint32, const t_sva_header_infos *); + +t_sva_sdc_algo_error (*pGetParamBufferSize) (t_sva_service_instance_num, t_size*); + +t_sva_sdc_algo_error (*pFlushFifos) (t_sva_service_instance_num); + +t_sva_sdc_algo_error (*pDecodeAlgoClose) (t_sva_service_instance_num); + +t_sva_sdc_algo_error (*pCleanupTaskEnd) (t_sva_service_instance_num, t_sva_tm_subtask_id); + +t_sva_sdc_algo_error (*pGetDecodeStatus)(t_sva_service_instance_num, t_sva_tm_subtask_id, t_sva_sdc_decode_status*, t_uint32*); + +t_sva_sdc_algo_error (*pSetParamBuffer) (t_sva_service_instance_num, t_sva_tm_subtask_id, t_logical_address); + +t_sva_sdc_algo_error (*pSetStartCodeValueForFakeBuffer) (t_system_address); + +} t_sva_algo_still_decode_fct_array; + +#ifdef __cplusplus +} /* allow C++ to use these headers */ +#endif /* __cplusplus */ + +#endif /* __INC_SVA_SEC_ALGO_H */ +/* End of file - sva_sec_algo.h */ --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_decode/sva_still_decode.c @@ -0,0 +1,3174 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ +/*------------------------------------------------------------------------ + * Includes + *----------------------------------------------------------------------*/ +#include "sva.h" +#include "sva_still_decode.h" + +#include "sva_still_decodep.h" + +#include "sva_taskmgt.h" +#include "sva_eventmgt.h" +#include "sva_buffermgt.h" +#include "sva_service.h" + +#include "sva_sdc_algo.h" +#include "jpeg/sva_sdc_jpeg.h" + + /*------------------------------------------------------------------------ + * Global Variables + *----------------------------------------------------------------------*/ + #ifdef __DEBUG +ALIGN(32) PRIVATE t_sva_sdc_debug_events eventStillDecodeDebugTable[NUM_MAX_STILL_DECODE]; +ALIGN(32) PRIVATE t_sva_sdc_debug_commands commandStillDecodeDebugTable[NUM_MAX_STILL_DECODE]; +ALIGN(32) PRIVATE t_sva_sdc_debug_transitions transitionStillDecodeDebugTable[NUM_MAX_STILL_DECODE]; +#endif + + /*instance descriptors*/ +PRIVATE t_sva_sdc_descriptor stillDecodeDesc[NUM_MAX_STILL_DECODE]; + + /*table that describe memory allocation for fields of a still-image decode sub-task*/ +PRIVATE const t_sva_tm_field_ctrl_desc defaultStillDecodeFieldDescArray[SVA_SDC_NUMBER_OF_ALGO_SUPPORTED][STILL_DECODE_FIELD_NUMBER]={ + { + { SVA_TM_DCMD_NULL, {{sizeof(t_sva_vdc_frame_buffer_in), STILL_DECODE_DEFAULT_MEMORY_ID}}}, /*this field is not required by a still-decode sub-task*/ + { SVA_TM_DCMD_ALLOCATE, {{sizeof(t_sva_vdc_frame_buffer_out), STILL_DECODE_DEFAULT_MEMORY_ID}}}, + { SVA_TM_DCMD_NULL, {{sizeof(t_sva_vdc_internal_buf), STILL_DECODE_DEFAULT_MEMORY_ID}}}, + { SVA_TM_DCMD_ALLOCATE, {{sizeof(t_sva_bitstream_buffer_pos), STILL_DECODE_DEFAULT_MEMORY_ID}}},/*bitstream buffer list allocated by BLM module*/ + { SVA_TM_DCMD_NULL, {{sizeof(t_sva_bitstream_buffer_pos), STILL_DECODE_DEFAULT_MEMORY_ID}}}, /*this field is not required since, will be connected to the previous field*/ + { SVA_TM_DCMD_NULL, {{sizeof(t_sva_vdc_jpeg_param_in), STILL_DECODE_DEFAULT_MEMORY_ID}}}, /*this field is not required since, will be provided during resolution of dependanccies*/ + { SVA_TM_DCMD_ALLOCATE, {{sizeof(t_sva_vdc_jpeg_param_out), STILL_DECODE_DEFAULT_MEMORY_ID}}}, + { SVA_TM_DCMD_ALLOCATE, {{sizeof(t_sva_vdc_jpeg_param_inout), STILL_DECODE_DEFAULT_MEMORY_ID}}}, + { SVA_TM_DCMD_NULL, {{sizeof(t_sva_vdc_jpeg_param_inout), STILL_DECODE_DEFAULT_MEMORY_ID}}} /*this field is not required since, will be connected to the previous field*/ + } /*JPEG*/ +}; + + +PRIVATE t_sva_algo_still_decode_fct_array stillDecodeAlgoDesc[SVA_SDC_NUMBER_OF_ALGO_SUPPORTED]={ +/*JPEG*/ + { + sva_SDC_JPEG_InitAndConfigure, + sva_SDC_JPEG_GetMemoryNeeds, + sva_SDC_JPEG_ProvideMemoryNeeds, + sva_SDC_JPEG_GetNextFrameParamsIn, + sva_SDC_JPEG_AreNextFrameInfosAvailable, + sva_SDC_JPEG_SetHeaderInfos, + sva_SDC_JPEG_GetParamBufferSize, + sva_SDC_JPEG_FlushFifos, + sva_SDC_JPEG_Close, + sva_SDC_JPEG_CleanupTaskEnd, + sva_SDC_JPEG_GetDecodeStatus, + sva_SDC_JPEG_SetParamBuffer, + sva_SDC_JPEG_SetStartCodeValueForFakeBuffer + } +}; + +/*table that translate decode state into service state*/ +PRIVATE const t_sva_service_state decodeState2ServiceState[SVA_SDC_LAST_DUMMY_STATE]= { + SVA_SERVICE_NOT_INITIALIZED, /*SVA_SDC_NOT_INITIALIZED*/ + SVA_SERVICE_WAIT_FOR_CONFIGURATION, /*SVA_SDC_WAIT_FOR_CONFIGURATION*/ + SVA_SERVICE_WAIT_FOR_INTERNAL_NEEDS, /*SVA_SDC_WAIT_FOR_INTERNAL_NEEDS*/ + SVA_SERVICE_WAIT_FOR_ACTIVATE, /*SVA_SDC_WAIT_FOR_ACTIVATE*/ + SVA_SERVICE_WAIT_FOR_START, /*SVA_SDC_WAIT_FOR_START*/ + SVA_SERVICE_FLUSHING, /*SVA_SDC_FLUSHING_IN*/ + SVA_SERVICE_FLUSHING, /*SVA_SDC_FLUSHING_OUT*/ + SVA_SERVICE_WAIT_FOR_DATA, /*SVA_SDC_WAIT_FOR_DATA*/ + SVA_SERVICE_RUNNING, /*SVA_SDC_RUNNING*/ + SVA_SERVICE_RUNNING, /*SVA_SDC_STOP_SLICE_REQUESTED*/ + SVA_SERVICE_ABORT_REQUESTED, /*SVA_SDC_ABORT_REQUESTED*/ + SVA_SERVICE_STOP_REQUESTED, /*SVA_SDC_STOP_REQUESTED*/ + SVA_SERVICE_ERROR /*SVA_SDC_ERROR*/ +}; + + +PRIVATE const t_sva_sdc_state stateMachine[SVA_SDC_LAST_DUMMY_STATE][SVA_SDC_LAST_DUMMY_TRANSITION]= { + /* Current State = SVA_SDC_NOT_INITIALIZED */ + { + SVA_SDC_WAIT_FOR_CONFIGURATION, /*SVA_SDC_CREATE*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_CONFIGURE*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_INTERNAL_NEEDS*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_ACTIVATE*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_INACTIVATE*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_CONTROL_START*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_CONTROL_STOP*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_STOP_SLICE*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_CONTROL_ABORT*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_ALL_DEPENDENCIES_RESOLVED*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_PUSH*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_EVENT_EOK*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_EVENT_FAKE*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_EVENT_ACTIVE*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_EVENT_INACTIVE*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_RESET*/ + SVA_SDC_NOT_INITIALIZED, /*SVA_SDC_CONTROL_DELETE*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_EVENT_ERROR*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_FLUSH_IN*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_FLUSH_OUT*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_CANCEL*/ + }, + /* Current State = SVA_SDC_WAIT_FOR_CONFIGURATION */ + { + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_CREATE*/ + SVA_SDC_WAIT_FOR_INTERNAL_NEEDS, /*SVA_SDC_CONFIGURE*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_INTERNAL_NEEDS*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_ACTIVATE*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_INACTIVATE*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_CONTROL_START*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_CONTROL_STOP*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_STOP_SLICE*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_CONTROL_ABORT*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_ALL_DEPENDENCIES_RESOLVED*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_PUSH*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_EVENT_EOK*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_EVENT_FAKE*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_EVENT_ACTIVE*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_EVENT_INACTIVE*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_RESET*/ + SVA_SDC_NOT_INITIALIZED, /*SVA_SDC_CONTROL_DELETE*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_EVENT_ERROR*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_FLUSH_IN*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_FLUSH_OUT*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_CANCEL*/ + }, + /* Current State = SVA_SDC_WAIT_FOR_INTERNAL_NEEDS */ + { + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_CREATE*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_CONFIGURE*/ + SVA_SDC_WAIT_FOR_ACTIVATE, /*SVA_SDC_INTERNAL_NEEDS*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_ACTIVATE*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_INACTIVATE*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_CONTROL_START*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_CONTROL_STOP*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_STOP_SLICE*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_CONTROL_ABORT*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_ALL_DEPENDENCIES_RESOLVED*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_PUSH*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_EVENT_EOK*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_EVENT_FAKE*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_EVENT_ACTIVE*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_EVENT_INACTIVE*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_RESET*/ + SVA_SDC_NOT_INITIALIZED, /*SVA_SDC_CONTROL_DELETE*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_EVENT_ERROR*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_FLUSH_IN*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_FLUSH_OUT*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_CANCEL*/ + }, + /* Current State = SVA_SDC_WAIT_FOR_ACTIVATE */ + { + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_CREATE*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_CONFIGURE*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_INTERNAL_NEEDS*/ + SVA_SDC_WAIT_FOR_ACTIVATE, /*SVA_SDC_ACTIVATE*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_INACTIVATE*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_CONTROL_START*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_CONTROL_STOP*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_STOP_SLICE*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_CONTROL_ABORT*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_ALL_DEPENDENCIES_RESOLVED*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_PUSH*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_EVENT_EOK*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_EVENT_FAKE*/ + SVA_SDC_WAIT_FOR_START, /*SVA_SDC_EVENT_ACTIVE*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_EVENT_INACTIVE*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_RESET*/ + SVA_SDC_NOT_INITIALIZED, /*SVA_SDC_CONTROL_DELETE*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_EVENT_ERROR*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_FLUSH_IN*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_FLUSH_OUT*/ + SVA_SDC_WAIT_FOR_ACTIVATE, /*SVA_SDC_CANCEL*/ + }, + /* Current State = SVA_SDC_WAIT_FOR_START */ + { + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_CREATE*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_CONFIGURE*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_INTERNAL_NEEDS*/ + SVA_SDC_WAIT_FOR_START, /*SVA_SDC_ACTIVATE*/ + SVA_SDC_WAIT_FOR_START, /*SVA_SDC_INACTIVATE*/ + SVA_SDC_WAIT_FOR_DATA, /*SVA_SDC_CONTROL_START*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_CONTROL_STOP*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_STOP_SLICE*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_CONTROL_ABORT*/ + SVA_SDC_WAIT_FOR_START, /*SVA_SDC_ALL_DEPENDENCIES_RESOLVED*/ + SVA_SDC_WAIT_FOR_START, /*SVA_SDC_PUSH*/ + SVA_SDC_ERROR, /*SVA_SDC_EVENT_EOK*/ + SVA_SDC_ERROR, /*SVA_SDC_EVENT_FAKE*/ + SVA_SDC_WAIT_FOR_START, /*SVA_SDC_EVENT_ACTIVE*/ + SVA_SDC_WAIT_FOR_START, /*SVA_SDC_EVENT_INACTIVE*/ + SVA_SDC_WAIT_FOR_START, /*SVA_SDC_RESET*/ + SVA_SDC_NOT_INITIALIZED, /*SVA_SDC_CONTROL_DELETE*/ + SVA_SDC_ERROR, /*SVA_SDC_EVENT_ERROR*/ + SVA_SDC_FLUSHING_IN, /*SVA_SDC_FLUSH_IN*/ + SVA_SDC_FLUSHING_OUT, /*SVA_SDC_FLUSH_OUT*/ + SVA_SDC_WAIT_FOR_START, /*SVA_SDC_CANCEL*/ + }, + /* Current State = SVA_SDC_FLUSHING_IN */ + { + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_CREATE*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_CONFIGURE*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_INTERNAL_NEEDS*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_ACTIVATE*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_INACTIVATE*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_CONTROL_START*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_CONTROL_STOP*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_STOP_SLICE*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_CONTROL_ABORT*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_ALL_DEPENDENCIES_RESOLVED*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_PUSH*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_EVENT_EOK*/ + SVA_SDC_WAIT_FOR_START, /*SVA_SDC_EVENT_FAKE*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_EVENT_ACTIVE*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_EVENT_INACTIVE*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_RESET*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_CONTROL_DELETE*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_EVENT_ERROR*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_FLUSH_IN*/ + SVA_SDC_WAIT_FOR_START, /*SVA_SDC_FLUSH_OUT*/ + SVA_SDC_FLUSHING_IN, /*SVA_SDC_CANCEL*/ + }, + /* Current State = SVA_SDC_FLUSHING_OUT */ + { + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_CREATE*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_CONFIGURE*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_INTERNAL_NEEDS*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_ACTIVATE*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_INACTIVATE*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_CONTROL_START*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_CONTROL_STOP*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_STOP_SLICE*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_CONTROL_ABORT*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_ALL_DEPENDENCIES_RESOLVED*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_PUSH*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_EVENT_EOK*/ + SVA_SDC_WAIT_FOR_START, /*SVA_SDC_EVENT_FAKE*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_EVENT_ACTIVE*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_EVENT_INACTIVE*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_RESET*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_CONTROL_DELETE*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_EVENT_ERROR*/ + SVA_SDC_WAIT_FOR_START, /*SVA_SDC_FLUSH_IN*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_FLUSH_OUT*/ + SVA_SDC_FLUSHING_OUT, /*SVA_SDC_CANCEL*/ + }, + /* Current State = SVA_SDC_WAIT_FOR_DATA */ + { + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_CREATE*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_CONFIGURE*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_INTERNAL_NEEDS*/ + SVA_SDC_WAIT_FOR_DATA, /*SVA_SDC_ACTIVATE*/ + SVA_SDC_WAIT_FOR_DATA, /*SVA_SDC_INACTIVATE*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_CONTROL_START*/ + SVA_SDC_STOP_REQUESTED, /*SVA_SDC_CONTROL_STOP*/ + SVA_SDC_ERROR, /*SVA_SDC_STOP_SLICE*/ + SVA_SDC_ABORT_REQUESTED, /*SVA_SDC_CONTROL_ABORT*/ + SVA_SDC_RUNNING, /*SVA_SDC_ALL_DEPENDENCIES_RESOLVED*/ + SVA_SDC_WAIT_FOR_DATA, /*SVA_SDC_PUSH*/ + SVA_SDC_ERROR, /*SVA_SDC_EVENT_EOK*/ + SVA_SDC_ERROR, /*SVA_SDC_EVENT_FAKE*/ + SVA_SDC_WAIT_FOR_DATA, /*SVA_SDC_EVENT_ACTIVE*/ + SVA_SDC_WAIT_FOR_DATA, /*SVA_SDC_EVENT_INACTIVE*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_RESET*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_CONTROL_DELETE*/ + SVA_SDC_ERROR, /*SVA_SDC_EVENT_ERROR*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_FLUSH_IN*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_FLUSH_OUT*/ + SVA_SDC_WAIT_FOR_DATA, /*SVA_SDC_CANCEL*/ + }, + /* Current State = SVA_SDC_RUNNING */ + { + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_CREATE*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_CONFIGURE*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_INTERNAL_NEEDS*/ + SVA_SDC_RUNNING, /*SVA_SDC_ACTIVATE*/ + SVA_SDC_RUNNING, /*SVA_SDC_INACTIVATE*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_CONTROL_START*/ + SVA_SDC_STOP_REQUESTED, /*SVA_SDC_CONTROL_STOP*/ + SVA_SDC_STOP_SLICE_REQUESTED, /*SVA_SDC_STOP_SLICE*/ + SVA_SDC_ABORT_REQUESTED, /*SVA_SDC_CONTROL_ABORT*/ + SVA_SDC_RUNNING, /*SVA_SDC_ALL_DEPENDENCIES_RESOLVED*/ + SVA_SDC_RUNNING, /*SVA_SDC_PUSH*/ + SVA_SDC_WAIT_FOR_DATA, /*SVA_SDC_EVENT_EOK*/ + SVA_SDC_ERROR, /*SVA_SDC_EVENT_FAKE*/ + SVA_SDC_RUNNING, /*SVA_SDC_EVENT_ACTIVE*/ + SVA_SDC_RUNNING, /*SVA_SDC_EVENT_INACTIVE*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_RESET*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_CONTROL_DELETE*/ + SVA_SDC_ERROR, /*SVA_SDC_EVENT_ERROR*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_FLUSH_IN*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_FLUSH_OUT*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_CANCEL*/ + }, + /* Current State = SVA_SDC_STOP_SLICE_REQUESTED */ + { /*REM Dependancy resolution is switched off when in state SVA_SDC_STOP_SLICE_REQUESTED*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_CREATE*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_CONFIGURE*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_INTERNAL_NEEDS*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_ACTIVATE*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_INACTIVATE*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_CONTROL_START*/ + SVA_SDC_STOP_REQUESTED, /*SVA_SDC_CONTROL_STOP*/ + SVA_SDC_ERROR, /*SVA_SDC_STOP_SLICE*/ + SVA_SDC_ABORT_REQUESTED, /*SVA_SDC_CONTROL_ABORT*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_ALL_DEPENDENCIES_RESOLVED*/ + SVA_SDC_STOP_SLICE_REQUESTED, /*SVA_SDC_PUSH*/ + SVA_SDC_WAIT_FOR_DATA, /*SVA_SDC_EVENT_EOK*/ + SVA_SDC_ERROR, /*SVA_SDC_EVENT_FAKE*/ + SVA_SDC_STOP_SLICE_REQUESTED, /*SVA_SDC_EVENT_ACTIVE*/ + SVA_SDC_STOP_SLICE_REQUESTED, /*SVA_SDC_EVENT_INACTIVE*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_RESET*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_CONTROL_DELETE*/ + SVA_SDC_ERROR, /*SVA_SDC_EVENT_ERROR*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_FLUSH_IN*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_FLUSH_OUT*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_CANCEL*/ + }, + /* Current State = SVA_SDC_ABORT_REQUESTED */ + { + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_CREATE*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_CONFIGURE*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_INTERNAL_NEEDS*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_ACTIVATE*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_INACTIVATE*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_CONTROL_START*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_CONTROL_STOP*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_STOP_SLICE*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_CONTROL_ABORT*/ + SVA_SDC_ABORT_REQUESTED, /*SVA_SDC_ALL_DEPENDENCIES_RESOLVED*/ + SVA_SDC_ABORT_REQUESTED, /*SVA_SDC_PUSH*/ + SVA_SDC_ERROR, /*SVA_SDC_EVENT_EOK*/ + SVA_SDC_ERROR, /*SVA_SDC_EVENT_FAKE*/ + SVA_SDC_ERROR, /*SVA_SDC_EVENT_ACTIVE*/ + SVA_SDC_ERROR, /*SVA_SDC_EVENT_INACTIVE*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_RESET*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_CONTROL_DELETE*/ + SVA_SDC_ERROR, /*SVA_SDC_EVENT_ERROR*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_FLUSH_IN*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_FLUSH_OUT*/ + SVA_SDC_ABORT_REQUESTED, /*SVA_SDC_CANCEL*/ + }, + /* Current State = SVA_SDC_STOP_REQUESTED */ + { + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_CREATE*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_CONFIGURE*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_INTERNAL_NEEDS*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_ACTIVATE*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_INACTIVATE*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_CONTROL_START*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_CONTROL_STOP*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_STOP_SLICE*/ + SVA_SDC_ABORT_REQUESTED, /*SVA_SDC_CONTROL_ABORT*/ + SVA_SDC_STOP_REQUESTED, /*SVA_SDC_ALL_DEPENDENCIES_RESOLVED*/ + SVA_SDC_STOP_REQUESTED, /*SVA_SDC_PUSH*/ + SVA_SDC_WAIT_FOR_START, /*SVA_SDC_EVENT_EOK*/ + SVA_SDC_ERROR, /*SVA_SDC_EVENT_FAKE*/ + SVA_SDC_ERROR, /*SVA_SDC_EVENT_ACTIVE*/ + SVA_SDC_ERROR, /*SVA_SDC_EVENT_INACTIVE*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_RESET*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_CONTROL_DELETE*/ + SVA_SDC_ERROR, /*SVA_SDC_EVENT_ERROR*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_FLUSH_IN*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_FLUSH_OUT*/ + SVA_SDC_STOP_REQUESTED, /*SVA_SDC_CANCEL*/ + }, + /* Current State = SVA_SDC_ERROR */ + { + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_CREATE*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_CONFIGURE*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_INTERNAL_NEEDS*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_ACTIVATE*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_INACTIVATE*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_CONTROL_START*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_CONTROL_STOP*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_STOP_SLICE*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_CONTROL_ABORT*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_ALL_DEPENDENCIES_RESOLVED*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_PUSH*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_EVENT_EOK*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_EVENT_FAKE*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_EVENT_ACTIVE*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_EVENT_INACTIVE*/ + SVA_SDC_WAIT_FOR_START, /*SVA_SDC_RESET*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_CONTROL_DELETE*/ + SVA_SDC_ERROR, /*SVA_SDC_EVENT_ERROR*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_FLUSH_IN*/ + SVA_SDC_TRANSITION_REJECTED, /*SVA_SDC_FLUSH_OUT*/ + SVA_SDC_ERROR, /*SVA_SDC_CANCEL*/ + } +}; + + +/*activate state machine description*/ +PRIVATE const t_sva_sdc_activate_state activateStateMachine[SVA_SDC_LAST_ACTIVATE_DUMMY_STATE][SVA_SDC_LAST_DUMMY_TRANSITION]= { + /* Current State = SVA_SDC_INACTIVE */ + { + SVA_SDC_INACTIVE, /*SVA_SDC_CREATE*/ + SVA_SDC_INACTIVE, /*SVA_SDC_CONFIGURE*/ + SVA_SDC_INACTIVE, /*SVA_SDC_INTERNAL_NEEDS*/ + SVA_SDC_IN_ACTIVATION, /*SVA_SDC_ACTIVATE*/ + SVA_SDC_ACTIVATE_TRANSITION_REJECTED, /*SVA_SDC_INACTIVATE*/ + SVA_SDC_ACTIVATE_TRANSITION_REJECTED, /*SVA_SDC_CONTROL_START*/ + SVA_SDC_ACTIVATE_TRANSITION_REJECTED, /*SVA_SDC_CONTROL_STOP*/ + SVA_SDC_ACTIVATE_TRANSITION_REJECTED, /*SVA_SDC_STOP_SLICE*/ + SVA_SDC_ACTIVATE_TRANSITION_REJECTED, /*SVA_SDC_CONTROL_ABORT*/ + SVA_SDC_INACTIVE, /*SVA_SDC_ALL_DEPENDENCIES_RESOLVED*/ + SVA_SDC_INACTIVE, /*SVA_SDC_PUSH*/ + SVA_SDC_INACTIVE, /*SVA_SDC_EVENT_EOK*/ + SVA_SDC_INACTIVE, /*SVA_SDC_EVENT_FAKE*/ + SVA_SDC_INACTIVE, /*SVA_SDC_EVENT_ACTIVE*/ + SVA_SDC_INACTIVE, /*SVA_SDC_EVENT_INACTIVE*/ + SVA_SDC_INACTIVE, /*SVA_SDC_RESET*/ + SVA_SDC_INACTIVE, /*SVA_SDC_CONTROL_DELETE*/ + SVA_SDC_INACTIVE, /*SVA_SDC_EVENT_ERROR*/ + SVA_SDC_INACTIVE, /*SVA_SDC_FLUSH_IN*/ + SVA_SDC_INACTIVE, /*SVA_SDC_FLUSH_OUT*/ + SVA_SDC_ACTIVATE_TRANSITION_REJECTED, /*SVA_SDC_CANCEL*/ + }, + /* Current State = SVA_SDC_IN_ACTIVATION */ + { + SVA_SDC_ACTIVATE_TRANSITION_REJECTED, /*SVA_SDC_CREATE*/ + SVA_SDC_ACTIVATE_TRANSITION_REJECTED, /*SVA_SDC_CONFIGURE*/ + SVA_SDC_ACTIVATE_TRANSITION_REJECTED, /*SVA_SDC_INTERNAL_NEEDS*/ + SVA_SDC_ACTIVATE_TRANSITION_REJECTED, /*SVA_SDC_ACTIVATE*/ + SVA_SDC_ACTIVATE_TRANSITION_REJECTED, /*SVA_SDC_INACTIVATE*/ + SVA_SDC_ACTIVATE_TRANSITION_REJECTED, /*SVA_SDC_CONTROL_START*/ + SVA_SDC_ACTIVATE_TRANSITION_REJECTED, /*SVA_SDC_CONTROL_STOP*/ + SVA_SDC_ACTIVATE_TRANSITION_REJECTED, /*SVA_SDC_STOP_SLICE*/ + SVA_SDC_ACTIVATE_TRANSITION_REJECTED, /*SVA_SDC_CONTROL_ABORT*/ + SVA_SDC_IN_ACTIVATION, /*SVA_SDC_ALL_DEPENDENCIES_RESOLVED*/ + SVA_SDC_IN_ACTIVATION, /*SVA_SDC_PUSH*/ + SVA_SDC_IN_ACTIVATION, /*SVA_SDC_EVENT_EOK*/ + SVA_SDC_IN_ACTIVATION, /*SVA_SDC_EVENT_FAKE*/ + SVA_SDC_ACTIVE, /*SVA_SDC_EVENT_ACTIVE*/ + SVA_SDC_IN_ACTIVATION, /*SVA_SDC_EVENT_INACTIVE*/ + SVA_SDC_IN_ACTIVATION, /*SVA_SDC_RESET*/ + SVA_SDC_ACTIVATE_TRANSITION_REJECTED, /*SVA_SDC_CONTROL_DELETE*/ + SVA_SDC_IN_ACTIVATION, /*SVA_SDC_EVENT_ERROR*/ + SVA_SDC_IN_ACTIVATION, /*SVA_SDC_FLUSH_IN*/ + SVA_SDC_IN_ACTIVATION, /*SVA_SDC_FLUSH_OUT*/ + SVA_SDC_INACTIVE, /*SVA_SDC_CANCEL*/ + }, + /* Current State = SVA_SDC_ACTIVE */ + { + SVA_SDC_ACTIVATE_TRANSITION_REJECTED, /*SVA_SDC_CREATE*/ + SVA_SDC_ACTIVATE_TRANSITION_REJECTED, /*SVA_SDC_CONFIGURE*/ + SVA_SDC_ACTIVATE_TRANSITION_REJECTED, /*SVA_SDC_INTERNAL_NEEDS*/ + SVA_SDC_ACTIVATE_TRANSITION_REJECTED, /*SVA_SDC_ACTIVATE*/ + SVA_SDC_IN_INACTIVATION, /*SVA_SDC_INACTIVATE*/ + SVA_SDC_ACTIVE, /*SVA_SDC_CONTROL_START*/ + SVA_SDC_ACTIVE, /*SVA_SDC_CONTROL_STOP*/ + SVA_SDC_ACTIVE, /*SVA_SDC_STOP_SLICE*/ + SVA_SDC_ACTIVE, /*SVA_SDC_CONTROL_ABORT*/ + SVA_SDC_ACTIVE, /*SVA_SDC_ALL_DEPENDENCIES_RESOLVED*/ + SVA_SDC_ACTIVE, /*SVA_SDC_PUSH*/ + SVA_SDC_ACTIVE, /*SVA_SDC_EVENT_EOK*/ + SVA_SDC_ACTIVE, /*SVA_SDC_EVENT_FAKE*/ + SVA_SDC_ACTIVE, /*SVA_SDC_EVENT_ACTIVE*/ + SVA_SDC_ACTIVE, /*SVA_SDC_EVENT_INACTIVE*/ + SVA_SDC_ACTIVE, /*SVA_SDC_RESET*/ + SVA_SDC_INACTIVE, /*SVA_SDC_CONTROL_DELETE*/ + SVA_SDC_ACTIVE, /*SVA_SDC_EVENT_ERROR*/ + SVA_SDC_ACTIVE, /*SVA_SDC_FLUSH_IN*/ + SVA_SDC_ACTIVE, /*SVA_SDC_FLUSH_OUT*/ + SVA_SDC_ACTIVATE_TRANSITION_REJECTED, /*SVA_SDC_CANCEL*/ + }, + /* Current State = SVA_SDC_IN_INACTIVATION */ + { + SVA_SDC_ACTIVATE_TRANSITION_REJECTED, /*SVA_SDC_CREATE*/ + SVA_SDC_ACTIVATE_TRANSITION_REJECTED, /*SVA_SDC_CONFIGURE*/ + SVA_SDC_ACTIVATE_TRANSITION_REJECTED, /*SVA_SDC_INTERNAL_NEEDS*/ + SVA_SDC_ACTIVATE_TRANSITION_REJECTED, /*SVA_SDC_ACTIVATE*/ + SVA_SDC_ACTIVATE_TRANSITION_REJECTED, /*SVA_SDC_INACTIVATE*/ + SVA_SDC_ACTIVATE_TRANSITION_REJECTED, /*SVA_SDC_CONTROL_START*/ + SVA_SDC_ACTIVATE_TRANSITION_REJECTED, /*SVA_SDC_CONTROL_STOP*/ + SVA_SDC_ACTIVATE_TRANSITION_REJECTED, /*SVA_SDC_STOP_SLICE*/ + SVA_SDC_ACTIVATE_TRANSITION_REJECTED, /*SVA_SDC_CONTROL_ABORT*/ + SVA_SDC_IN_INACTIVATION, /*SVA_SDC_ALL_DEPENDENCIES_RESOLVED*/ + SVA_SDC_IN_INACTIVATION, /*SVA_SDC_PUSH*/ + SVA_SDC_IN_INACTIVATION, /*SVA_SDC_EVENT_EOK*/ + SVA_SDC_IN_INACTIVATION, /*SVA_SDC_EVENT_FAKE*/ + SVA_SDC_IN_INACTIVATION, /*SVA_SDC_EVENT_ACTIVE*/ + SVA_SDC_INACTIVE, /*SVA_SDC_EVENT_INACTIVE*/ + SVA_SDC_INACTIVE, /*SVA_SDC_RESET*/ + SVA_SDC_ACTIVATE_TRANSITION_REJECTED, /*SVA_SDC_CONTROL_DELETE*/ + SVA_SDC_IN_INACTIVATION, /*SVA_SDC_EVENT_ERROR*/ + SVA_SDC_IN_INACTIVATION, /*SVA_SDC_FLUSH_IN*/ + SVA_SDC_IN_INACTIVATION, /*SVA_SDC_FLUSH_OUT*/ + SVA_SDC_ACTIVE, /*SVA_SDC_CANCEL*/ + } +}; + + +/*------------------------------------------------------------------------ + * Private functions prototype + *----------------------------------------------------------------------*/ + +PRIVATE t_sva_sdc_error sva_SDC_ResolveDependencies(t_sva_service_instance_num ); +PRIVATE t_bool sva_SDC_AreAllDependanciesResolved(t_sva_sdc_subtask_dependencies ); +PRIVATE t_bool sva_SDC_IsConfigurationValid(const t_sva_still_decoder_configuration *pConf); +PRIVATE t_bool sva_SDC_isTransitionValid(t_sva_service_instance_num, t_sva_sdc_transition); +PRIVATE t_sva_error sva_SDC_CheckServiceId(t_sva_service_id); +PRIVATE t_sva_sdc_state sva_SDC_UpdateInstanceStatesMachine(t_sva_service_instance_num, t_sva_sdc_transition ); +PRIVATE t_sva_sdc_error sva_SDC_CreateSubTasksDescriptors(t_sva_service_id, t_uint8, t_sva_tm_subtask_id*,t_sva_tm_subtask_list_id*); +PRIVATE t_sva_error sva_SDC_DoFlushIn(t_sva_service_id serviceId); +PRIVATE t_sva_error sva_SDC_DoFlushOut(t_sva_service_id serviceId); +PRIVATE void sva_SDC_ResetInstance(t_sva_service_id serviceId); +PRIVATE void sva_SDC_ResetStatus(t_sva_still_decoder_status *pStatus); +PRIVATE t_sva_error sva_SDC_DoReset(t_sva_service_id serviceId); + +/****************************************************************************/ +/* NAME: t_sva_SDC_error sva_SDC_Init ( void ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine initialize the Still-Image Decode Management module. */ +/* 1) Set state of instance to SVA_SERVICE_NOT_INITIALIZED */ +/* 2) init fifos */ +/* */ +/* PARAMETERS: */ +/* IN : none */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/* - always SVA_OK */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ + +PUBLIC t_sva_error sva_SDC_Init(void) +{ + t_uint32 i; + + /*init all still-decode instances*/ + for(i = 0;i < NUM_MAX_STILL_DECODE; i++) + { + /*init instance states*/ + stillDecodeDesc[i].state = SVA_SDC_NOT_INITIALIZED; + stillDecodeDesc[i].serviceId = 0; + stillDecodeDesc[i].activateState = SVA_SDC_INACTIVE; + /*init fifo use*/ + INIT_FIFO(stillDecodeDesc[i].inputBitstreamFifo); + INIT_FIFO(stillDecodeDesc[i].outputImageFifos.push); + INIT_FIFO(stillDecodeDesc[i].outputImageFifos.inUse); + INIT_FIFO(stillDecodeDesc[i].aceParamFifos.push); + INIT_FIFO(stillDecodeDesc[i].aceParamFifos.inUse); + INIT_FIFO(stillDecodeDesc[i].subtasksDependencyFifo); + INIT_FIFO(stillDecodeDesc[i].fakeBitstreamFifo); + + INIT_FIFO(stillDecodeDesc[i].windowBufferFifos.push); + INIT_FIFO(stillDecodeDesc[i].windowBufferFifos.inUse); + + stillDecodeDesc[i].assertEndofStream = FALSE; + stillDecodeDesc[i].stopSliceRequested = FALSE; + stillDecodeDesc[i].fakeBufferAdded = FALSE; + + + /*init others value linked to decoder status*/ + sva_SDC_ResetStatus(&(stillDecodeDesc[i].status)); + + #ifdef __DEBUG + /*init debug counters*/ + eventStillDecodeDebugTable[i].nbOfEventReceived=0; + commandStillDecodeDebugTable[i].nbOfCommandReceived=0; + transitionStillDecodeDebugTable[i].nbOfTransitionReceived=0; + #endif + } + + return SVA_OK; +} + +/****************************************************************************/ +/* NAME: t_sva_error sva_SDC_Create(t_sva_service_id * pServiceId) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine allows to create a new instance of a Decode Service */ +/* - it will search for a free descriptor */ +/* - it will modify instance number in serviceId */ +/* */ +/* PARAMETERS: */ +/* IN : none */ +/* */ +/* INOUT : */ +/* - pServiceId: return service ID value */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/* - SVA_OK : service creation ok */ +/* - SVA_INTERNAL_STILL_DECODER_ERROR : unable to find an available*/ +/* decriptor so service creation failed. */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ + +/* DONE */ + +PUBLIC t_sva_error sva_SDC_Create(t_sva_service_id *pServiceId) +{ + t_bool exitForLoop = FALSE; + t_sva_service_instance_num instanceNum; + + + SDC_CHECK_NULL_POINTER(pServiceId); + + /*check for free decode instance*/ + for(instanceNum = 0; instanceNum < NUM_MAX_STILL_DECODE && exitForLoop == FALSE; instanceNum++) + { + if (stillDecodeDesc[instanceNum].state == SVA_SDC_NOT_INITIALIZED) {exitForLoop = TRUE;} + } + if (exitForLoop == FALSE) {return SVA_INTERNAL_STILL_DECODER_ERROR;} + instanceNum--; + + /*fill pServiceId*/ + WRITE_INSTANCE_NUM_IN_SERVICE_ID(instanceNum, *pServiceId); + + /* save service id*/ + stillDecodeDesc[instanceNum].serviceId = *pServiceId; + + #ifdef __DEBUG + /*init debug counters*/ + eventStillDecodeDebugTable[instanceNum].nbOfEventReceived=0; + commandStillDecodeDebugTable[instanceNum].nbOfCommandReceived=0; + transitionStillDecodeDebugTable[instanceNum].nbOfTransitionReceived=0; + #endif + + /* Update the state machine */ + sva_SDC_UpdateInstanceStatesMachine(instanceNum,SVA_SDC_CREATE); + + return SVA_OK; +} + + + +/****************************************************************************/ +/* NAME: t_sva_error SVA_ConfigureStillImageDecoder ( */ +/* t_sva_service_id serviceId, */ +/* t_sva_still_decoder_configuration *pConf */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine configures a STILL DECODE service */ +/* - It will check configuration validity */ +/* - Save it in descriptor */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - serviceId: identifier of the service */ +/* - pConf: configuration of the service */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/* - SVA_OK : Command taken into account */ +/* - SVA_UNKNOWN_SERVICE_ID : service id is not correct */ +/* - SVA_UNEXPECTED_API_CALL : Command cannot be excecuted in */ +/* current context. */ +/* - SVA_INTERNAL_STILL_DECODER_ERROR : internal error */ +/* - SVA_INCOHERENT_CONFIGURATION : detected an incoherent conf */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ + +PUBLIC t_sva_error SVA_ConfigureStillImageDecoder ( + t_sva_service_id serviceId, + const t_sva_still_decoder_configuration *pConf_main +) +{ + + t_sva_error status; + t_sva_service_instance_num instanceNum = READ_INSTANCE_NUM_IN_SERVICE_ID(serviceId); + t_sva_sdc_descriptor *pDesc = &stillDecodeDesc[instanceNum]; + t_sva_sdc_algo_error algoError; + + t_sva_still_decoder_configuration Conf = *pConf_main; + t_sva_still_decoder_configuration *pConf = &Conf; + + /*check for service id validity*/ + status=sva_SDC_CheckServiceId(serviceId); + if (status != SVA_OK) {return status;} + + /*check that transition is allowed*/ + if (sva_SDC_isTransitionValid(instanceNum,SVA_SDC_CONFIGURE)==FALSE) {return SVA_UNEXPECTED_API_CALL;} + + /*check pointer validity*/ + SDC_CHECK_NULL_POINTER(pConf); + + /*check configuration validity*/ + if (sva_SDC_IsConfigurationValid(pConf) == FALSE) + { + return SVA_INCOHERENT_CONFIGURATION; + } + /* stores algo specific needs - currently only JPEG is involved */ + if(pConf->transformId == SVA_DECODER_SEQUENTIAL_JPEG || pConf->transformId == SVA_DECODER_PROGRESSIVE_JPEG) + { + pDesc->algo=SVA_SV_JPEG_ALGO; + pDesc->downsamplingFactor = ((t_sva_still_algo_jpeg_decoder_configuration_params*)(pConf->pAlgoConfig))->downsamplingFactor; + } + + if (pConf->transformId == SVA_DECODER_PROGRESSIVE_JPEG) + { + if (pConf->is_cropping_enabled == TRUE) + { + return SVA_NOT_SUPPORTED_YET; + } + } + /* store frame image size */ + pDesc->outImageSize = pConf->decodedFrameDesc; + if (pConf->is_cropping_enabled == FALSE) + { + t_sva_window_desc crop_window; + crop_window.image = pConf->decodedFrameDesc; + crop_window.imageOffset.offsetX = 0; + crop_window.imageOffset.offsetY = 0; + pDesc->crop_window = crop_window; + pConf->crop_window = crop_window; + } + else + { + if (pConf->crop_window.image.width + pConf->crop_window.imageOffset.offsetX > pConf->decodedFrameDesc.width) + { + return SVA_INCOHERENT_CONFIGURATION; + } + + if (pConf->crop_window.image.height + pConf->crop_window.imageOffset.offsetY > pConf->decodedFrameDesc.height) + { + return SVA_INCOHERENT_CONFIGURATION; + } + + pDesc->crop_window = pConf->crop_window; + } + pDesc->codecMode = pConf->mode; + pDesc->no_slice_mode = pConf->no_slice_mode; + + /*call pInitAndConfigure() API to get memory need of algo decoder*/ + algoError = stillDecodeAlgoDesc[pDesc->algo].pInitAndConfigure(instanceNum,pConf); + if (algoError != SVA_SDC_ALGO_OK) { return SVA_INCOHERENT_CONFIGURATION;} + + /* Update the state machine */ + sva_SDC_UpdateInstanceStatesMachine(instanceNum,SVA_SDC_CONFIGURE); + + return SVA_OK; +} + + +/****************************************************************************/ +/* NAME: t_sva_error sva_SDC_Activate( */ +/* t_sva_service_id serviceId, */ +/* t_sva_service_mode serviceMode, */ +/* t_sva_fw_id *pFwId */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine activates the still decode service */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - serviceId: identifier of the service */ +/* - serviceMode : set service to real_time or not */ +/* */ +/* OUT : */ +/* - pFwId : identifier of firmware id for which user shall provide location*/ +/* */ +/* RETURN: */ +/* t_sva_error */ +/* - SVA_OK : Command taken into account */ +/* - SVA_UNKNOWN_SERVICE_ID : service id is not correct */ +/* - SVA_UNEXPECTED_API_CALL : Command cannot be excecuted in */ +/* current context. */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* DONE */ +PUBLIC t_sva_error sva_SDC_Activate ( + t_sva_service_id serviceId, + t_sva_service_mode serviceMode, + t_sva_fw_id *pFwId +) +{ + t_sva_error status; + t_sva_service_instance_num instanceNum = READ_INSTANCE_NUM_IN_SERVICE_ID(serviceId); + t_sva_sdc_descriptor *pDesc = &stillDecodeDesc[instanceNum]; + + + /*check for service id validity*/ + status = sva_SDC_CheckServiceId(serviceId); + if (status != SVA_OK) {return status;} + + /*check that transition is allowed*/ + if (sva_SDC_isTransitionValid(instanceNum,SVA_SDC_ACTIVATE) == FALSE) {return SVA_UNEXPECTED_API_CALL;} + + /* Update the state machine */ + /* Update state machine before command is send to task management to avoid race condition */ + sva_SDC_UpdateInstanceStatesMachine(instanceNum,SVA_SDC_ACTIVATE); + + /*activate subTaskList*/ + + status = sva_TM_ActivateSubTaskList(pDesc->subtasksListId,serviceMode,pFwId); + if (status != SVA_OK && status != SVA_FW_SWITCH_OCCURED && status != SVA_FW_SWITCH_DELAYED) + { + sva_SDC_UpdateInstanceStatesMachine(instanceNum,SVA_SDC_CANCEL); + + return status; + } + return status; +} + +/****************************************************************************/ +/* NAME: t_sva_error sva_SDC_Inactivate( */ +/* t_sva_service_id serviceId */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine deactivates the still decode service */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - serviceId: identifier of the service */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/* - SVA_OK : Command taken into account */ +/* - SVA_UNKNOWN_SERVICE_ID : service id is not correct */ +/* - SVA_UNEXPECTED_API_CALL : Command cannot be excecuted in */ +/* current context. */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* DONE */ +PUBLIC t_sva_error sva_SDC_Inactivate ( + t_sva_service_id serviceId +) +{ + t_sva_error status; + t_sva_tm_error tmError; + t_sva_service_instance_num instanceNum = READ_INSTANCE_NUM_IN_SERVICE_ID(serviceId); + t_sva_sdc_descriptor *pDesc = &stillDecodeDesc[instanceNum]; + + + /*check for service id validity*/ + status = sva_SDC_CheckServiceId(serviceId); + if (status != SVA_OK) {return status;} + + /*check that transition is allowed*/ + if (sva_SDC_isTransitionValid(instanceNum,SVA_SDC_INACTIVATE) == FALSE) {return SVA_UNEXPECTED_API_CALL;} + + /* Update the state machine */ + /* Update state machine before command is send to task management to avoid race condition */ + sva_SDC_UpdateInstanceStatesMachine(instanceNum,SVA_SDC_INACTIVATE); + + /*inactivate subTaskList*/ + /*handle informative error code*/ + tmError = sva_TM_InActivateSubTaskList(pDesc->subtasksListId); + if (tmError != SVA_TM_OK) + { + sva_SDC_UpdateInstanceStatesMachine(instanceNum,SVA_SDC_CANCEL); + return SVA_INTERNAL_STILL_DECODER_ERROR; + } + return SVA_OK; +} + + + +/****************************************************************************/ +/* NAME: t_sva_error sva_SDC_GetInternalNeeds ( */ +/* t_sva_service_id serviceId */ +/* t_size* pSize */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine returns the size of the memory needed for decode */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - serviceId: identifier of the service */ +/* - pSize: size needed */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/* - SVA_OK */ +/* - SVA_INTERNAL STILL_DECODER_ERROR */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_sva_error sva_SDC_GetInternalNeeds ( + t_sva_service_id serviceId, + t_size * pSize, + t_size * pSizeNCNB +) +/* DONE */ +{ + t_sva_error status; + t_size fifoSize = 0; + t_sva_service_instance_num instanceNum = READ_INSTANCE_NUM_IN_SERVICE_ID(serviceId); + t_sva_sdc_descriptor *pDesc=&stillDecodeDesc[instanceNum]; + t_sva_sdc_algo_error algoError; + + /*check pointer validity*/ + HCL_ASSERT(pSize!=0); + HCL_ASSERT(pSizeNCNB!=0); + + *pSize = 0; + *pSizeNCNB = 0; + + /*check for service id validity*/ + status = sva_SDC_CheckServiceId(serviceId); + if (status != SVA_OK) {return status;} + + /*default dependencies*/ + /* ------------------ */ + pDesc->defaultDep.outputBufferDep = NOT_RESOLVED_DEPENDENCY; + pDesc->defaultDep.bitstreamBufferDep = NOT_RESOLVED_DEPENDENCY; + pDesc->defaultDep.headerInfoDep = NOT_RESOLVED_DEPENDENCY; + pDesc->defaultDep.paramBufferDep = NOT_RESOLVED_DEPENDENCY; + + /*compute memory size needs*/ + /* ------------------------ */ + + /*memory needed by event management*/ + status = sva_EM_GetInternalNeeds(&fifoSize); + if (status != SVA_OK) {return status;} + + *pSize = fifoSize; + + /*call pGetMemoryNeeds() API to get memory need of algo encoder*/ + algoError = stillDecodeAlgoDesc[pDesc->algo].pGetMemoryNeeds(instanceNum, + &fifoSize,pSizeNCNB); + if (algoError != SVA_SDC_ALGO_OK) {return SVA_INTERNAL_STILL_DECODER_ERROR;} + + *pSize += fifoSize; + + /* add memory needed by internal fifos */ + + /* subtasksDependencyFifo */ + GET_FIFO_MEMORY_NEEDS(t_sva_sdc_subtask_dependencies, SUBTASK_DEFAULT_NUMBER, fifoSize); + *pSize += fifoSize; + + /* bitstream */ + GET_FIFO_MEMORY_NEEDS(t_sva_buffer_id, PUSH_FIFO_DEFAULT_SIZE, fifoSize); + *pSize += fifoSize; + + /* ACE param buffer FIFOs - one pushed and other in-use */ + GET_FIFO_MEMORY_NEEDS(t_sva_buffer_id, PUSH_FIFO_DEFAULT_SIZE + SUBTASK_DEFAULT_NUMBER, fifoSize); + *pSize += fifoSize; + GET_FIFO_MEMORY_NEEDS(t_sva_buffer_id, SUBTASK_DEFAULT_NUMBER, fifoSize); + *pSize += fifoSize; + + /* output image buffer FIFOs - one pushed and other in-use */ + GET_FIFO_MEMORY_NEEDS(t_sva_buffer_id, PUSH_FIFO_DEFAULT_SIZE + SUBTASK_DEFAULT_NUMBER, fifoSize); + *pSize += fifoSize; + GET_FIFO_MEMORY_NEEDS(t_sva_buffer_id, SUBTASK_DEFAULT_NUMBER, fifoSize); + *pSize += fifoSize; + + /* fake bitstream buffer FIFO */ + GET_FIFO_MEMORY_NEEDS(t_sva_buffer_id, 1, fifoSize); + *pSize += fifoSize; + + /* bitstream window buffer FIFOs - one pushed and other in-use */ + /* these buffers are used to support circular mode */ + GET_FIFO_MEMORY_NEEDS(t_sva_sdc_block, SUBTASK_DEFAULT_NUMBER, fifoSize); + *pSize += fifoSize; + GET_FIFO_MEMORY_NEEDS(t_sva_sdc_block, SUBTASK_DEFAULT_NUMBER, fifoSize); + *pSize += fifoSize; + + return SVA_OK; +} + + + +/****************************************************************************/ +/* NAME: t_sva_error sva_SDC_ProvideInternalNeeds ( */ +/* t_sva_service_id serviceId */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine allows to end the configuration of the service. It */ +/* satisfies internal memory requirements. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - serviceId: identifier of the service */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/* - SVA_OK */ +/* - SVA_UNEXPECTED_API_CALL */ +/* - SVA_INTERNAL STILL_DECODER_ERROR */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_sva_error sva_SDC_ProvideInternalNeeds ( + t_sva_service_id serviceId, + t_system_address systemAddressNCNB, + t_size sizeNCNB +) +/* DONE */ +{ + + t_sva_error status; + t_sva_ff_error ffError; + t_sva_tm_error tmError; + t_sva_mm_error mmError; + t_sva_sdc_error svaError; + t_sva_sdc_algo_error algoError; + t_sva_sdc_subtask_dependencies subtaskDep; + t_sva_service_instance_num instanceNum = READ_INSTANCE_NUM_IN_SERVICE_ID(serviceId); + t_sva_sdc_descriptor *pDesc = &stillDecodeDesc[instanceNum]; + t_sva_buffer_id fakeBitstream; + t_system_address sysAddr; + t_uint32 i; + + + /*check for service id validity*/ + status = sva_SDC_CheckServiceId(serviceId); + if (status != SVA_OK) {return status;} + + /*check that transition is allowed*/ + if (sva_SDC_isTransitionValid(instanceNum,SVA_SDC_INTERNAL_NEEDS) == FALSE) {return SVA_UNEXPECTED_API_CALL;} + + /*provide some memory to event management*/ + /* ------------------------------------- */ + status = sva_EM_ProvideInternalNeeds(serviceId); + if (status != SVA_OK) {return SVA_INTERNAL_STILL_DECODER_ERROR;} + + + /* create internal fifos */ + /* --------------------- */ + + /* subtasksDependencyFifo */ + CREATE_FIFO(t_sva_sdc_subtask_dependencies, SUBTASK_DEFAULT_NUMBER, pDesc->subtasksDependencyFifo, ffError); + if (ffError != SVA_FIFO_OK) {return SVA_INTERNAL_STILL_DECODER_ERROR;} + + /* bitstream */ + CREATE_FIFO(t_sva_buffer_id, PUSH_FIFO_DEFAULT_SIZE, pDesc->inputBitstreamFifo, ffError); + if (ffError != SVA_FIFO_OK) {return SVA_INTERNAL_STILL_DECODER_ERROR;} + + /* ACE param buffer FIFOs - one pushed and other in-use */ + CREATE_FIFO(t_sva_buffer_id, PUSH_FIFO_DEFAULT_SIZE + SUBTASK_DEFAULT_NUMBER, pDesc->aceParamFifos.push, ffError); + if (ffError != SVA_FIFO_OK) {return SVA_INTERNAL_STILL_DECODER_ERROR;} + CREATE_FIFO(t_sva_buffer_id, SUBTASK_DEFAULT_NUMBER, pDesc->aceParamFifos.inUse, ffError); + if (ffError != SVA_FIFO_OK) {return SVA_INTERNAL_STILL_DECODER_ERROR;} + + /* output image buffer FIFOs - one pushed and other in-use */ + CREATE_FIFO(t_sva_buffer_id, PUSH_FIFO_DEFAULT_SIZE + SUBTASK_DEFAULT_NUMBER, pDesc->outputImageFifos.push, ffError); + if (ffError != SVA_FIFO_OK) {return SVA_INTERNAL_STILL_DECODER_ERROR;} + CREATE_FIFO(t_sva_buffer_id, SUBTASK_DEFAULT_NUMBER, pDesc->outputImageFifos.inUse, ffError); + if (ffError != SVA_FIFO_OK) {return SVA_INTERNAL_STILL_DECODER_ERROR;} + + /* fake bitstream buffer FIFO */ + CREATE_FIFO(t_sva_buffer_id, 1, pDesc->fakeBitstreamFifo, ffError); + if (ffError != SVA_FIFO_OK) {return SVA_INTERNAL_STILL_DECODER_ERROR;} + + /* bitstream window buffer FIFOs */ + CREATE_FIFO(t_sva_sdc_block, SUBTASK_DEFAULT_NUMBER, pDesc->windowBufferFifos.push, ffError); + if (ffError != SVA_FIFO_OK) {return SVA_INTERNAL_STILL_DECODER_ERROR;} + CREATE_FIFO(t_sva_sdc_block, SUBTASK_DEFAULT_NUMBER, pDesc->windowBufferFifos.inUse, ffError); + if (ffError != SVA_FIFO_OK) {return SVA_INTERNAL_STILL_DECODER_ERROR;} + + + + /* Allocate memory for fake bitstream buffer */ + /* ----------------------------------------- */ + + /* TODO: Fake bitstream size to be determined */ + status = SVA_AllocBuffer(SVA_BITSTREAM_BUFFER_TYPE, 512, &sysAddr, &fakeBitstream); + if (status != SVA_OK) {return status;} + + ffError = PUSH_FIFO_ELEM(pDesc->fakeBitstreamFifo, t_sva_buffer_id, fakeBitstream); + if (ffError!=SVA_FIFO_OK) {return SVA_INTERNAL_STILL_DECODER_ERROR;} + + algoError = stillDecodeAlgoDesc[pDesc->algo].pSetStartCodeValueForFakeBuffer(sysAddr); + if (algoError!=SVA_SDC_ALGO_OK) {return SVA_INTERNAL_STILL_DECODER_ERROR;} + + /* Allocate memory blocks for bitstream window buffer */ + /* -------------------------------------------------- */ + for(i=0; iwindowBufferFifos.push, t_sva_sdc_block, blockDesc); + if (ffError!=SVA_FIFO_OK) {return SVA_INTERNAL_STILL_DECODER_ERROR;} + } + + + /* Create subtasks */ + /* ---------------- */ + svaError = sva_SDC_CreateSubTasksDescriptors(serviceId, SUBTASK_DEFAULT_NUMBER, pDesc->subtasksIdArray, &pDesc->subtasksListId); + if (svaError != SVA_SDC_OK) {return SVA_INTERNAL_STILL_DECODER_ERROR;} + + /* Enable interrupts */ + /* ----------------- */ + tmError=sva_TM_DisableAllVirtualHwEvents(pDesc->subtasksListId); + if (tmError != SVA_TM_OK) {return SVA_INTERNAL_STILL_DECODER_ERROR;} + tmError=sva_TM_EnableVirtualHwEvents(pDesc->subtasksListId,SVA_TM_EOT_HW_EVENT); + if (tmError != SVA_TM_OK) {return SVA_INTERNAL_STILL_DECODER_ERROR;} + + tmError=sva_TM_EnableVirtualHwEvents(pDesc->subtasksListId,SVA_TM_EOW_HW_EVENT); + if (tmError != SVA_TM_OK) {return SVA_INTERNAL_STILL_DECODER_ERROR;} + + tmError=sva_TM_EnableVirtualHwEvents(pDesc->subtasksListId,SVA_TM_ERR_HW_EVENT); + if (tmError != SVA_TM_OK) {return SVA_INTERNAL_STILL_DECODER_ERROR;} + tmError=sva_TM_EnableVirtualHwEvents(pDesc->subtasksListId,SVA_TM_EOK_HW_EVENT); + if (tmError != SVA_TM_OK) {return SVA_INTERNAL_STILL_DECODER_ERROR;} + tmError=sva_TM_EnableVirtualHwEvents(pDesc->subtasksListId,SVA_TM_INACTIVE_HW_EVENT); + if (tmError != SVA_TM_OK) {return SVA_INTERNAL_STILL_DECODER_ERROR;} + tmError=sva_TM_EnableVirtualHwEvents(pDesc->subtasksListId,SVA_TM_ACTIVE_HW_EVENT); + if (tmError != SVA_TM_OK) {return SVA_INTERNAL_STILL_DECODER_ERROR;} + tmError=sva_TM_EnableVirtualHwEvents(pDesc->subtasksListId,SVA_TM_FAKE_HW_EVENT); + if (tmError != SVA_TM_OK) {return SVA_INTERNAL_STILL_DECODER_ERROR;} + + + /* call pProvideMemoryNeeds() API : will allocate blocks for IN-PARAMS as well as allocate blocks */ + /* for line buffer and co-efficient buffer (if required)*/ + /* ---------------------------- */ + algoError=stillDecodeAlgoDesc[pDesc->algo].pProvideMemoryNeeds(instanceNum, pDesc->subtasksIdArray, systemAddressNCNB, sizeNCNB); + if (algoError!=SVA_SDC_ALGO_OK) {return SVA_INTERNAL_STILL_DECODER_ERROR;} + + /* push dependencies */ + /* ----------------- */ + for(i=0;isubtasksIdArray[i]; + subtaskDep.dependencies=pDesc->defaultDep; + + ffError=PUSH_FIFO_ELEM(pDesc->subtasksDependencyFifo, t_sva_sdc_subtask_dependencies, subtaskDep); + if (ffError!=SVA_FIFO_OK) {return SVA_INTERNAL_STILL_DECODER_ERROR;} + } + + /* Update the state machine */ + /* ------------------------ */ + sva_SDC_UpdateInstanceStatesMachine(instanceNum,SVA_SDC_INTERNAL_NEEDS); + + return SVA_OK; +} + + + +/****************************************************************************/ +/* NAME: t_sva_sdc_error sva_SDC_CreateSubTasksDescriptors( */ +/* t_sva_service_id serviceId, */ +/* t_uint8 nbSubtasks, */ +/* t_sva_tm_subtask_id *pSubtaskIdArray, */ +/* t_sva_tm_subtask_list_id *pListId */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine creates all required still-decode subtasks descriptors */ +/* */ +/* PARAMETERS: */ +/* IN: */ +/* - serviceId: maps the instance number */ +/* - nbSubtasks: number of tasks to be created */ +/* */ +/* OUT: */ +/* - pSubtaskIdArray: array of all created subtasks */ +/* - pListId: identifier of the new created subtask list */ +/* */ +/* RETURN: t_sva_sdc_error */ +/* - SVA_SDC_TM_LINKED_ERROR */ +/* - SVA_SDC_NOT_SUPPORTED */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ + +PRIVATE t_sva_sdc_error sva_SDC_CreateSubTasksDescriptors ( + t_sva_service_id serviceId, + t_uint8 nbSubtasks, + t_sva_tm_subtask_id *pSubtaskIdArray, + t_sva_tm_subtask_list_id *pListId +) +/* DONE */ +{ + t_sva_tm_task_ctrl_desc stillDecodeTaskDesc; + t_sva_tm_field_ctrl_desc stillDecodeFieldDescArray[STILL_DECODE_FIELD_NUMBER]; + t_sva_tm_error tmError; + t_sva_tm_subtask_type subtaskType; + t_uint8 i; + t_sva_service_instance_num instanceNum = READ_INSTANCE_NUM_IN_SERVICE_ID(serviceId); + t_sva_sdc_descriptor *pDesc = &stillDecodeDesc[instanceNum]; + + HCL_ASSERT(pSubtaskIdArray != NULL); + HCL_ASSERT(pListId != NULL); + +// if(pDesc->algo == SVA_SV_JPEG_ALGO) + if (pDesc->no_slice_mode == TRUE) + { + subtaskType = SVA_TM_DECODE_JPEG_NO_SLICE; + } + else + { + subtaskType = SVA_TM_DECODE_JPEG; + } + + /* Prepare the task control descriptor */ + stillDecodeTaskDesc.memId = STILL_DECODE_DEFAULT_MEMORY_ID; + stillDecodeTaskDesc.fieldnb = STILL_DECODE_FIELD_NUMBER; + stillDecodeTaskDesc.pfieldctrldesc = stillDecodeFieldDescArray; + + /* Copy default display field descriptor array */ + for (i=0; i < STILL_DECODE_FIELD_NUMBER; i++) + { + stillDecodeFieldDescArray[i] = defaultStillDecodeFieldDescArray[pDesc->algo][i]; + } + + /* Create subtasks */ + /* warning: circular Buffer mode has been used for still decode */ + for (i=0; i < nbSubtasks; i++) + { + tmError=sva_TM_CreateSubTask( + SVA_TM_DECODE, + &stillDecodeTaskDesc, + subtaskType, + SVA_TM_NO_POST_PROCESSING, + SVA_TM_NO_SYNCHRO, + SVA_TM_EOT_EN, + SVA_TM_CIRCULAR_MODE, + &pSubtaskIdArray[i] + ); + + if (tmError != SVA_TM_OK) {return SVA_SDC_TM_LINKED_ERROR;} + + } + + /* Connect the input and output in-out parameters and bitstream parameters of the same sub-task structure */ + for(i = 0; i < nbSubtasks; i++) + { + tmError=sva_TM_ConnectSubtasksFields(pDesc->subtasksIdArray[i], + SVA_TM_DEC_ADDR_IN_FRAME_PARAMETERS, + pDesc->subtasksIdArray[i], + SVA_TM_DEC_ADDR_OUT_FRAME_PARAMETERS); + if (tmError != SVA_TM_OK) {return SVA_SDC_TM_LINKED_ERROR;} + + + tmError=sva_TM_ConnectSubtasksFields(pDesc->subtasksIdArray[i], + SVA_TM_DEC_ADDR_IN_BITSTREAM_BUFFER, + pDesc->subtasksIdArray[i], + SVA_TM_DEC_ADDR_OUT_BITSTREAM_BUFFER); + if (tmError != SVA_TM_OK) {return SVA_SDC_TM_LINKED_ERROR;} + } + + if(pDesc->algo == SVA_SV_JPEG_ALGO) + { + tmError=sva_TM_CreateSubTaskList(SVA_TM_DECODE, serviceId,SVA_FW_FEAT_JPEG_DECODER,&pDesc->subtasksListId); + if (tmError != SVA_TM_OK) {return SVA_SDC_TM_LINKED_ERROR;} + } + else + return SVA_SDC_NOT_SUPPORTED; + + return SVA_SDC_OK; +} + + +/****************************************************************************/ +/* NAME: sva_SDC_SetHeaderInfos() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: This routine enables to give Header infos (dynamic params) */ +/* related to a given bitstream buffer and also */ +/* the address of the first byte of coded data taken into account by SVA */ +/* (relative to buffer start) */ +/* JPEG: first byte of first mcu of a scan */ +/* */ +/* PARAMETERS: */ +/* IN : t_sva_service_id serviceId : */ +/* t_sva_buffer_id bitstreamBufferId: */ +/* t_uint32 byteOffset (in bytes ) */ +/* t_uint32 bitOffset (in bits) */ +/* const t_sva_header_infos *pHeaderInfos */ +/* OUT :none */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/* - SVA_OK : header provided successfully */ +/* - SVA_NOT_BITSTREAM_BUFFER : buffer id provided does not correpond*/ +/* to a bitstream buffer */ +/* - SVA_FIFO_FULL: header is rejected has internal fifo is full */ +/* - SVA_INTERNAL_STILL_DECODER_ERROR */ +/*--------------------------------------------------------------------------*/ +/* USE: NA */ +/* USED BY: NA */ +/****************************************************************************/ +PUBLIC t_sva_error sva_SDC_SetHeaderInfos ( + t_sva_service_id serviceId, + t_sva_buffer_id bitstreamBuffer, + t_uint32 byteOffset, + t_uint32 bitOffset, + const t_sva_header_infos *pHeaderInfos +) +{ + t_sva_service_instance_num instanceNum = READ_INSTANCE_NUM_IN_SERVICE_ID(serviceId); + t_sva_sdc_descriptor *pDesc = &stillDecodeDesc[instanceNum]; + t_sva_error status; + t_sva_sdc_algo_error algoError; + t_sva_sdc_error dcError; + t_sva_bm_error bmError; + t_sva_buffer_type bufferType; + + /*check for service id validity*/ + status=sva_SDC_CheckServiceId(serviceId); + if (status != SVA_OK) {return status;} + + /*check pointers*/ + SDC_CHECK_NULL_POINTER(pHeaderInfos); + + bmError = sva_BM_GetBufferType(bitstreamBuffer, &bufferType); + if(bmError != SVA_BM_OK) {return SVA_INTERNAL_STILL_DECODER_ERROR;} + if(bufferType != SVA_BITSTREAM_BUFFER_TYPE){return SVA_INVALID_BUFFER_TYPE;} + + /*check that transition is allowed*/ + if (sva_SDC_isTransitionValid(instanceNum,SVA_SDC_PUSH) == FALSE) {return SVA_UNEXPECTED_API_CALL;} + + algoError = stillDecodeAlgoDesc[pDesc->algo].pSetHeaderInfos(instanceNum, bitstreamBuffer, byteOffset, bitOffset, pHeaderInfos); + if(algoError != SVA_SDC_ALGO_OK) {return SVA_INTERNAL_STILL_DECODER_ERROR;} + + sva_SDC_UpdateInstanceStatesMachine(instanceNum,SVA_SDC_PUSH); + + dcError = sva_SDC_ResolveDependencies(instanceNum); + if (dcError != SVA_SDC_OK) {return SVA_INTERNAL_STILL_DECODER_ERROR;} + return SVA_OK; +} + + +/****************************************************************************/ +/* NAME: t_sva_error sva_SDC_Control ( */ +/* t_sva_service_id serviceId, */ +/* t_sva_service_cmd_id cmdId, */ +/* t_uint32 param */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine allows to control an instance of a Decode Service */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - serviceId: identifier of the given service */ +/* - cmdId: command to apply to the decode */ +/* - param: parameter use by command */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/* - SVA_OK : Command taken into account */ +/* - SVA_UNKNOWN_SERVICE_ID : service id is not correct */ +/* - SVA_UNEXPECTED_API_CALL : Command cannot be excecuted in */ +/* current context. */ +/* - SVA_UNKNOWN_CMD_ID : Command to execute is unknown */ +/* - SVA_INTERNAL_STILL_DECODER_ERROR : internal error */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ + +PUBLIC t_sva_error sva_SDC_Control ( + t_sva_service_id serviceId, + t_sva_service_cmd_id cmdId, + t_uint32 param +) +{ + t_sva_service_instance_num instanceNum = READ_INSTANCE_NUM_IN_SERVICE_ID(serviceId); + t_sva_sdc_descriptor *pDesc = &stillDecodeDesc[instanceNum]; + t_sva_error status = SVA_UNEXPECTED_API_CALL; + t_sva_error error; + t_sva_tm_error tmError; + + /*check for service id validity*/ + error = sva_SDC_CheckServiceId(serviceId); + if (error != SVA_OK) {return error;} + +#ifdef __DEBUG + { + t_uint32 systemTime; + + SVA_GetServiceSystemTime(serviceId,&systemTime); + commandStillDecodeDebugTable[instanceNum].commandDebugDesc[commandStillDecodeDebugTable[instanceNum].nbOfCommandReceived%LOG_DEPTH].command=cmdId; + commandStillDecodeDebugTable[instanceNum].commandDebugDesc[commandStillDecodeDebugTable[instanceNum].nbOfCommandReceived%LOG_DEPTH].systemTime=systemTime; + commandStillDecodeDebugTable[instanceNum].commandDebugDesc[commandStillDecodeDebugTable[instanceNum].nbOfCommandReceived%LOG_DEPTH].parameter=param; + commandStillDecodeDebugTable[instanceNum].nbOfCommandReceived++; + } +#endif + + /*handle command*/ + switch(cmdId) + { + case SVA_SERVICE_START: + if (sva_SDC_isTransitionValid(instanceNum, SVA_SDC_CONTROL_START) == TRUE) + { + /* transition are force before sending task command to avoid race condition*/ + sva_SDC_UpdateInstanceStatesMachine(instanceNum, SVA_SDC_CONTROL_START); + /* as we accepted some push before (or after a restart) some dependencies are perhaps + already scheduled + */ + if (GET_FIFO_NB_ELEMS(pDesc->subtasksDependencyFifo) != SUBTASK_DEFAULT_NUMBER) + { + sva_SDC_UpdateInstanceStatesMachine(instanceNum, SVA_SDC_ALL_DEPENDENCIES_RESOLVED); + } + /*now send start command*/ + tmError = sva_TM_SendTaskCommand(pDesc->subtasksListId, SVA_TM_TCMD_START, param); + HCL_DEBUG_ASSERT(tmError == SVA_TM_OK); + + status = SVA_OK; + } + break; + case SVA_SERVICE_STOP: + if (sva_SDC_isTransitionValid(instanceNum, SVA_SDC_CONTROL_STOP) == TRUE) + { + /* transition are force before sending task command to avoid race condition*/ + sva_SDC_UpdateInstanceStatesMachine(instanceNum, SVA_SDC_CONTROL_STOP); + /*stop subtask list*/ + tmError = sva_TM_SendTaskCommand(pDesc->subtasksListId, SVA_TM_TCMD_STOP,param); + HCL_DEBUG_ASSERT(tmError == SVA_TM_OK); + + status = SVA_OK; + } + break; + case SVA_SERVICE_ABORT: + if (sva_SDC_isTransitionValid(instanceNum, SVA_SDC_CONTROL_ABORT)==TRUE) + { + if (sva_TM_GetNbSubTask(pDesc->subtasksListId) != 0) + { + /* transition are force before sending task command to avoid race condition*/ + sva_SDC_UpdateInstanceStatesMachine(instanceNum, SVA_SDC_CONTROL_ABORT); + /*abort subtask list*/ + tmError = sva_TM_SendTaskCommand(pDesc->subtasksListId, SVA_TM_TCMD_ABORT, param); + HCL_DEBUG_ASSERT(tmError == SVA_TM_OK); + + status = SVA_OK; + } + } + break; + case SVA_SERVICE_RESET: + if (sva_SDC_isTransitionValid(instanceNum, SVA_SDC_RESET) == TRUE) + { + /*do instance clean-up so service can restart*/ + status = sva_SDC_DoReset(serviceId); + if (status == SVA_OK) + { + sva_SDC_UpdateInstanceStatesMachine(instanceNum, SVA_SDC_RESET); + } + } + break; + case SVA_SERVICE_FLUSH_IN: + if (sva_SDC_isTransitionValid(instanceNum, SVA_SDC_FLUSH_IN) == TRUE) + { + /*flush input buffer if necessary*/ + status = sva_SDC_DoFlushIn(serviceId); + if (status == SVA_OK) + { + sva_SDC_UpdateInstanceStatesMachine(instanceNum, SVA_SDC_FLUSH_IN); + /*generate a fake event since flush command is asynchronous*/ + sva_TM_SendTaskCommand(pDesc->subtasksListId, SVA_TM_TCMD_FAKE_EVENT, param); + } + } + break; + case SVA_SERVICE_FLUSH_OUT: + if (sva_SDC_isTransitionValid(instanceNum, SVA_SDC_FLUSH_OUT) == TRUE) + { + /*flush output buffer if necessary*/ + status = sva_SDC_DoFlushOut(serviceId); + if (status == SVA_OK) + { + sva_SDC_UpdateInstanceStatesMachine(instanceNum, SVA_SDC_FLUSH_OUT); + /*generate a fake event since flush command is asynchronous*/ + sva_TM_SendTaskCommand(pDesc->subtasksListId, SVA_TM_TCMD_FAKE_EVENT, param); + } + } + break; + /*unknown command*/ + default: + status = SVA_UNKNOWN_CMD_ID; + break; + } + return status; +} + + +/****************************************************************************/ +/* NAME: t_sva_error sva_SDC_Push ( */ +/* t_sva_service_id serviceId, */ +/* t_sva_buffer_id bufferId, */ +/* t_sva_push_mode pushMode, */ +/* t_sva_buffer_type bufferType */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine allows to push data in a Still Decode service */ +/* - it will check buffer has enought size according to conf */ +/* - it will push it in the corresponding pushFifo fifo */ +/* - update status of buffer */ +/* - try to resolve some dependencies */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - serviceId: identifier of the service */ +/* - bufferId: identifier of the buffer */ +/* - pushMode: PUSH_IN/PUSH_OUT */ +/* - bufferType: */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/* - SVA_OK : Command taken into account */ +/* - SVA_UNKNOWN_SERVICE_ID : service id is not correct */ +/* - SVA_UNEXPECTED_API_CALL : Command cannot be excecuted in */ +/* current context. */ +/* - SVA_INTERNAL_STILL_DECODER_ERROR : internal error */ +/* - SVA_INVALID_BUFFER_TYPE : buffer type is not handle by grab */ +/* - SVA_INTERNAL_FIFOS_FULL : internal fifos are full */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ + +PUBLIC t_sva_error sva_SDC_Push ( + t_sva_service_id serviceId, + t_sva_buffer_id bufferId, + t_sva_push_mode pushMode, + t_sva_buffer_type bufferType +) +{ + t_sva_service_instance_num instanceNum = READ_INSTANCE_NUM_IN_SERVICE_ID(serviceId); + t_sva_sdc_descriptor *pDesc=&stillDecodeDesc[instanceNum]; + t_sva_error status; + t_sva_buffer_status bufferStatus; + t_sva_bm_error bmError; + t_sva_ff_error ffError; + t_sva_sdc_error sdcError; + t_sva_sdc_algo_error algoError; + t_size bufferSize; + t_size minSize=0; + + /*check for service id validity*/ + status=sva_SDC_CheckServiceId(serviceId); + if (status!=SVA_OK) {return status;} + + /*check that transition is allowed*/ + if (sva_SDC_isTransitionValid(instanceNum,SVA_SDC_PUSH)==FALSE) {return SVA_UNEXPECTED_API_CALL;} + + //check that buffer is NOT already pushed: ie is in "sva_BUFFER_IN_USE" state + status=SVA_GetBufferStatus(bufferId,&bufferStatus); + if (status != SVA_OK) {return SVA_INVALID_BUFFER_TYPE; } + + switch(bufferType) + { + case SVA_PARAMS_BUFFER_TYPE: + if(pushMode != SVA_PUSH_OUT) {return SVA_UNEXPECTED_API_CALL;} + + if (bufferStatus.state != SVA_BUFFER_NOT_USED && bufferStatus.state != SVA_BUFFER_VOIDED && bufferStatus.state != SVA_BUFFER_FILLED) { return SVA_BUFFER_IS_IN_USE; } + /*compute minimum size of buffer according to current configuration*/ + algoError=stillDecodeAlgoDesc[pDesc->algo].pGetParamBufferSize(instanceNum, &minSize); + HCL_DEBUG_ASSERT(algoError == SVA_SDC_ALGO_OK); + + /*read buffer size*/ + bmError=sva_BM_GetBufferSize(bufferId,&bufferSize); + if (bmError!=SVA_BM_OK) {return SVA_INTERNAL_STILL_DECODER_ERROR;} + /*check buffer has enought space*/ + if (bufferSize>=minSize) + { + if (GET_FIFO_NB_ELEMS(pDesc->aceParamFifos.push) >= PUSH_FIFO_DEFAULT_SIZE) {status=SVA_INTERNAL_FIFOS_FULL;} + ffError=PUSH_FIFO_ELEM(pDesc->aceParamFifos.push, t_sva_buffer_id, bufferId); + if (ffError!=SVA_FIFO_OK) {status=SVA_INTERNAL_FIFOS_FULL;} + else {status=SVA_OK;} + } + else {status=SVA_INTERNAL_STILL_DECODER_ERROR;} + break; + + case SVA_BITSTREAM_BUFFER_TYPE: + { + t_sva_sdc_subtask_dependencies subtaskDep; + + if(pushMode != SVA_PUSH_IN) {return SVA_UNEXPECTED_API_CALL;} + + if(pDesc->assertEndofStream == TRUE) + return SVA_UNEXPECTED_API_CALL; + + if (bufferStatus.state != SVA_BUFFER_NOT_USED && bufferStatus.state != SVA_BUFFER_VOIDED) { return SVA_BUFFER_IS_IN_USE; } + /*Store buffer in bitstream buffer fifo*/ + ffError = PUSH_FIFO_ELEM(pDesc->inputBitstreamFifo,t_sva_buffer_id,bufferId); + if (ffError != SVA_FIFO_OK) {return SVA_INTERNAL_FIFOS_FULL;} + + pDesc->status.bufferizationStats.inLevel++; + + if(IS_FIFO_EMPTY(pDesc->subtasksDependencyFifo) == FALSE)// when all the dependencies are in queue + { + /*read subtask for which we will try to solve dependencies*/ + ffError = READ_FIFO_ELEM(pDesc->subtasksDependencyFifo, t_sva_sdc_subtask_dependencies, subtaskDep); + HCL_DEBUG_ASSERT(ffError == SVA_FIFO_OK); + + /* check header info dependancies */ + if(subtaskDep.dependencies.headerInfoDep == RESOLVED_DEPENDENCY && subtaskDep.dependencies.bitstreamBufferDep==NOT_RESOLVED_DEPENDENCY) //try to resolve header dep. + { + ffError = UPDATE_FIFO_ELEM_FIELD(pDesc->subtasksDependencyFifo,t_sva_sdc_subtask_dependencies,.dependencies.bitstreamBufferDep,RESOLVED_DEPENDENCY); + if (ffError != SVA_FIFO_OK) {return SVA_INTERNAL_STILL_DECODER_ERROR;} + } + } + if((pDesc->sdcEowOccured)&&((pDesc->codecMode == SVA_CODEC_STREAM_MODE)||(pDesc->codecMode == SVA_CODEC_SEGMENTED_MODE))) + { + t_sva_sdc_block blockDesc; + t_sva_bitstream_buffer_pos bitPos; + t_physical_address phyAddr; + t_size Size; + t_sva_bitstream_buffer * pBuffer; + t_sva_tm_error tmError; + t_uint32 dummyParam = 0; + t_sva_tm_subtask_id subtaskId = pDesc->sdcSubtaskIdEOW ; + + ffError=READ_FIFO_ELEM(stillDecodeDesc[instanceNum].windowBufferFifos.inUse, t_sva_sdc_block, blockDesc); + HCL_DEBUG_ASSERT (ffError == SVA_FIFO_OK); + + bmError = sva_BM_GetBufferPhysicalAddress(bufferId, &phyAddr); + HCL_DEBUG_ASSERT (bmError == SVA_BM_OK); + bmError = sva_BM_GetBufferSize(bufferId, &Size); + HCL_DEBUG_ASSERT (bmError == SVA_BM_OK); + + pBuffer = (t_sva_bitstream_buffer *)blockDesc.addr.logical; + + pBuffer->addr_buffer_start = phyAddr; + pBuffer->addr_buffer_end = phyAddr + Size; + pBuffer->addr_window_start = phyAddr; + pBuffer->addr_window_end = phyAddr + Size; + + bitPos.addr_bitstream_buf_struct = blockDesc.addr.physical | 0x00000001; + bitPos.addr_bitstream_start = phyAddr; + bitPos.bitstream_offset = 0; + + tmError = sva_TM_InitSubTaskField(subtaskId, SVA_TM_DEC_ADDR_IN_BITSTREAM_BUFFER, + (t_logical_address) &bitPos, sizeof(t_sva_bitstream_buffer_pos)); + + tmError=sva_TM_SendTaskCommand(pDesc->subtasksListId, SVA_TM_TCMD_UPDATE_BUFFER, dummyParam); + HCL_DEBUG_ASSERT(tmError == SVA_TM_OK); + pDesc->sdcEowOccured = FALSE; + } + } + break; + + case SVA_IMAGE_BUFFER_TYPE: + { + t_uint32 mbWidth; + t_uint32 mbHeight; + + if(pushMode != SVA_PUSH_OUT) {return SVA_UNEXPECTED_API_CALL;} + + if (bufferStatus.state != SVA_BUFFER_NOT_USED && bufferStatus.state != SVA_BUFFER_FILLED) { return SVA_BUFFER_IS_IN_USE; } + + bmError = sva_BM_GetBufferSize(bufferId,&bufferSize); + if (bmError != SVA_BM_OK) {return SVA_INTERNAL_STILL_DECODER_ERROR;} + + /* calculate output image size */ + mbWidth = (((((pDesc->crop_window.image.width + 7)>>3)*(8>>(t_uint8)(pDesc->downsamplingFactor))) + 15)>>4); + mbHeight = (((((pDesc->crop_window.image.height + 7)>>3)*(8>>(t_uint8)(pDesc->downsamplingFactor))) + 15)>>4); + minSize = (((mbWidth)<<4)*((mbHeight)<<4)*3)>>1; + + /*check buffer has enought space*/ + if (bufferSize>=minSize) + { + //Push in both Fifos outputImageFifos.push and inputFwdImageFifos.push + if (GET_FIFO_NB_ELEMS(pDesc->outputImageFifos.push) >= PUSH_FIFO_DEFAULT_SIZE) {status=SVA_INTERNAL_FIFOS_FULL;} + ffError=PUSH_FIFO_ELEM(pDesc->outputImageFifos.push, t_sva_buffer_id, bufferId); + if (ffError != SVA_FIFO_OK) {status = SVA_INTERNAL_FIFOS_FULL;} + else {status = SVA_OK;} + pDesc->status.bufferizationStats.outLevel++; + } + else {status=SVA_INTERNAL_STILL_DECODER_ERROR;} + } + break; + + default: + status = SVA_INVALID_BUFFER_TYPE; + break; + } + + /*update state machine*/ + sva_SDC_UpdateInstanceStatesMachine(instanceNum, SVA_SDC_PUSH); + + /*update buffer status if we have succeeded to push it and try to solve dependencies*/ + if (status == SVA_OK) + { + t_uint32 systemTime; + t_sva_error svaError; + + svaError = SVA_GetServiceSystemTime(serviceId, &systemTime); + if (svaError != SVA_OK) {return SVA_INTERNAL_STILL_DECODER_ERROR;} + bmError = sva_BM_UpdateBufferStatus(bufferId, SVA_BUFFER_IN_USE, systemTime); + if (bmError != SVA_BM_OK) {return SVA_INTERNAL_STILL_DECODER_ERROR;} + sdcError = sva_SDC_ResolveDependencies(instanceNum); + if (sdcError != SVA_SDC_OK) {return SVA_INTERNAL_STILL_DECODER_ERROR;} + } + return status; +} + + +/****************************************************************************/ +/* NAME: t_sva_error sva_SDC_DispatchVirtualHwEvent ( */ +/* t_sva_virtual_hw_event_id eventId, */ +/* t_sva_service_id serviceId, */ +/* t_sva_tm_subtask_id subtaskId, */ +/* t_sva_ticks ticks, */ +/* t_uint8 maxOfEvent, */ +/* t_sva_event_desc * pEventDesc, */ +/* t_uint32 * pNbEvent */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine allows to dispatch event of the encode service */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - eventId: event identifier */ +/* - serviceId: identifier of the service */ +/* - subtaskId: identifier of the subtask for which is the event */ +/* - ticks: */ +/* - maxOfEvent: nb of event max contained in EventDesc */ +/* - pEventDesc: structure of Events */ +/* - pNbEvent: nb of event into EventDesc */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ + +PUBLIC t_sva_error sva_SDC_DispatchVirtualHwEvent ( + t_sva_tm_virtual_hw_event_id eventId, + t_sva_service_id serviceId, + t_sva_tm_subtask_id subtaskId, + t_uint32 eventTimestamp, + t_uint32 eventDate, + t_uint8 maxOfEvent, + t_sva_event_desc * pEventDesc, + t_uint32 * pNbEvent + ) +{ + t_sva_service_instance_num instanceNum = READ_INSTANCE_NUM_IN_SERVICE_ID(serviceId); + t_sva_sdc_descriptor *pDesc = &stillDecodeDesc[instanceNum]; + t_sva_ff_error ffError; + t_uint32 nbEventsRaised = 0; + t_uint32 dummyParam = 0; + t_sva_tm_error tmError; + t_sva_error status; + t_sva_vdc_jpeg_param_out paramOut; + t_sva_buffer_id bufferId; + t_size Size; + t_uint32 nbInputBitstreamFifoElem; + + + HCL_ASSERT(pEventDesc != 0); + HCL_ASSERT(pNbEvent != 0); + + *pNbEvent = 0; + + /*check for service id validity*/ + status = sva_SDC_CheckServiceId(serviceId); + if (status != SVA_OK) {return SVA_INTERNAL_STILL_DECODER_ERROR;} + +#ifdef __DEBUG + { + t_uint32 systemTimeDbg; + + SVA_GetServiceSystemTime(serviceId,&systemTimeDbg); + eventStillDecodeDebugTable[instanceNum].eventDebugDesc[eventStillDecodeDebugTable[instanceNum].nbOfEventReceived%LOG_DEPTH].event=eventId; + eventStillDecodeDebugTable[instanceNum].eventDebugDesc[eventStillDecodeDebugTable[instanceNum].nbOfEventReceived%LOG_DEPTH].systemTime=eventTimestamp; + eventStillDecodeDebugTable[instanceNum].eventDebugDesc[eventStillDecodeDebugTable[instanceNum].nbOfEventReceived%LOG_DEPTH].subtaskId=subtaskId; + eventStillDecodeDebugTable[instanceNum].eventDebugDesc[eventStillDecodeDebugTable[instanceNum].nbOfEventReceived%LOG_DEPTH].serviceId=serviceId; + eventStillDecodeDebugTable[instanceNum].eventDebugDesc[eventStillDecodeDebugTable[instanceNum].nbOfEventReceived%LOG_DEPTH].startHandlingTime=systemTimeDbg; + //eventStillDecodeDebugTable[instanceNum].nbOfEventReceived++; + } +#endif + + /* + * Switch eventId + */ + + switch(eventId) + { + + case SVA_TM_EOW_HW_EVENT: + nbInputBitstreamFifoElem = GET_FIFO_NB_ELEMS(pDesc->inputBitstreamFifo); + /* Can only be possible in case of input bitstream buffer underflow */ + if(nbInputBitstreamFifoElem > 1 || pDesc->codecMode == SVA_CODEC_IMAGE_MODE || pDesc->assertEndofStream == TRUE || ((nbInputBitstreamFifoElem == 1) && (pDesc->codecMode != SVA_CODEC_IMAGE_MODE))) + { + t_sva_buffer_id bufferId; + t_sva_bitstream_buffer * pBuffer; + t_sva_sdc_block blockDesc; + t_sva_bm_error bmError; + t_physical_address phyAddr; + + ffError = POP_FIFO_ELEM(pDesc->inputBitstreamFifo, t_sva_buffer_id, pEventDesc[nbEventsRaised].bufferId); + HCL_DEBUG_ASSERT(ffError == SVA_FIFO_OK); + + CHECK_TABLE_OVERFLOW(nbEventsRaised, maxOfEvent, SVA_INTERNAL_EVENT_MGT_ERROR); + pEventDesc[nbEventsRaised].eventId = SVA_EVENT_BUFFER_VOIDED; + pEventDesc[nbEventsRaised].serviceId = serviceId; + pEventDesc[nbEventsRaised].eventTimestamp = (t_sva_timestamp_value) eventTimestamp; + pEventDesc[nbEventsRaised].eventDate = (t_sva_timestamp_value) eventDate; + pEventDesc[nbEventsRaised].extraInfo = 0; + sva_BM_UpdateBufferStatus(pEventDesc[nbEventsRaised].bufferId, SVA_BUFFER_VOIDED, eventTimestamp); + nbEventsRaised++; + /* event statistics */ + pDesc->status.eventStats.voidedCounter++; + if ((nbInputBitstreamFifoElem == 1) && (pDesc->codecMode != SVA_CODEC_IMAGE_MODE) && ((pDesc->assertEndofStream != TRUE))) + { + pDesc->sdcEowOccured = TRUE; + pDesc->sdcSubtaskIdEOW = subtaskId; + } + else + { + ffError=READ_FIFO_ELEM(stillDecodeDesc[instanceNum].windowBufferFifos.inUse, t_sva_sdc_block, blockDesc); + HCL_DEBUG_ASSERT (ffError == SVA_FIFO_OK); + + if(pDesc->codecMode == SVA_CODEC_IMAGE_MODE || (pDesc->assertEndofStream == TRUE && IS_FIFO_EMPTY(pDesc->inputBitstreamFifo)==TRUE)) + { /* must return error */ + pDesc->fakeBufferAdded = TRUE; + ffError = READ_FIFO_ELEM(pDesc->fakeBitstreamFifo, t_sva_buffer_id, bufferId); + HCL_DEBUG_ASSERT (ffError == SVA_FIFO_OK); + } + else + { + ffError = READ_FIFO_ELEM(pDesc->inputBitstreamFifo, t_sva_buffer_id, bufferId); + HCL_DEBUG_ASSERT (ffError == SVA_FIFO_OK); + } + + bmError = sva_BM_GetBufferPhysicalAddress(bufferId, &phyAddr); + HCL_DEBUG_ASSERT (bmError == SVA_BM_OK); + bmError = sva_BM_GetBufferSize(bufferId, &Size); + HCL_DEBUG_ASSERT (bmError == SVA_BM_OK); + + pBuffer = (t_sva_bitstream_buffer *)blockDesc.addr.logical; + + pBuffer->addr_buffer_start = phyAddr; + pBuffer->addr_buffer_end = phyAddr + Size; + pBuffer->addr_window_start = phyAddr; + pBuffer->addr_window_end = phyAddr + Size; + + tmError=sva_TM_SendTaskCommand(pDesc->subtasksListId, SVA_TM_TCMD_UPDATE_BUFFER, dummyParam); + HCL_DEBUG_ASSERT(tmError == SVA_TM_OK); + } + } + else + { + if (sva_SDC_isTransitionValid(instanceNum, SVA_SDC_STOP_SLICE) == TRUE) + { + tmError=sva_TM_SendTaskCommand(pDesc->subtasksListId, SVA_TM_TCMD_STOP_SLICE, dummyParam); + HCL_DEBUG_ASSERT(tmError == SVA_TM_OK); + + sva_SDC_UpdateInstanceStatesMachine(instanceNum, SVA_SDC_STOP_SLICE); + pDesc->stopSliceRequested = TRUE; + } + } + break; + + case SVA_TM_EOT_HW_EVENT: + /* can be either : + * - SVA_EVENT_BUFFER_VOIDED + * - SVA_EVENT_BUFFER_FILLED + * - SVA_EVENT_BUFFER_PARTLY_FILLED */ + { + t_sva_sdc_subtask_dependencies subtaskDep; + t_logical_address paramAddr; + t_sva_bitstream_buffer_pos bufferOutPos; + t_sva_sdc_algo_error algoError; + t_sva_bm_error bmError; + t_sva_sdc_block blockDesc = {INVALID_BUFFER_ID, 0x00000000}; + t_sva_sdc_decode_status decodeStatus; + t_uint32 extraInfo = 0; + + sva_TM_GetSubTaskField(subtaskId,SVA_TM_DEC_ADDR_IN_BITSTREAM_BUFFER,(t_logical_address)&bufferOutPos,0, sizeof(t_sva_bitstream_buffer_pos), TRUE); + if (pDesc->stopSliceRequested == FALSE) + { + decodeStatus = SVA_SDC_DECODE_COMPLETE; + } + else + { + algoError = stillDecodeAlgoDesc[pDesc->algo].pGetDecodeStatus(instanceNum, subtaskId,&decodeStatus,&extraInfo); + HCL_DEBUG_ASSERT(algoError==SVA_SDC_ALGO_OK); + pDesc->stopSliceRequested = FALSE; + } + + if(decodeStatus == SVA_SDC_DECODE_COMPLETE) + { + /* clean-up in algo module after task completion */ + algoError = stillDecodeAlgoDesc[pDesc->algo].pCleanupTaskEnd(instanceNum, subtaskId); + HCL_DEBUG_ASSERT(algoError == SVA_SDC_ALGO_OK); + + /* Handle subtask dependency */ + subtaskDep.subtaskId = subtaskId; + subtaskDep.dependencies = pDesc->defaultDep; + ffError = PUSH_FIFO_ELEM(pDesc->subtasksDependencyFifo, t_sva_sdc_subtask_dependencies, subtaskDep); + HCL_DEBUG_ASSERT(ffError == SVA_FIFO_OK); + + /* Handle input bitstream buffer */ + if(pDesc->fakeBufferAdded == FALSE) + { + t_physical_address phyAddr; + + ffError = READ_FIFO_ELEM(pDesc->inputBitstreamFifo,t_sva_buffer_id,bufferId); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + + /* Get start address and size of the concerned buffer. */ + bmError = sva_BM_GetBufferPhysicalAddress(bufferId, &phyAddr); + HCL_DEBUG_ASSERT (bmError == SVA_BM_OK); + bmError = sva_BM_GetBufferSize(bufferId, &Size); + HCL_DEBUG_ASSERT (bmError == SVA_BM_OK); + + /* checking this condition is important since, this buffer might be the start buffer of the next scan */ + if(bufferOutPos.addr_bitstream_start >= phyAddr && bufferOutPos.addr_bitstream_start < (phyAddr + Size)) + { + ffError = POP_FIFO_ELEM(pDesc->inputBitstreamFifo,t_sva_buffer_id,pEventDesc[nbEventsRaised].bufferId); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + CHECK_TABLE_OVERFLOW(nbEventsRaised, maxOfEvent, SVA_INTERNAL_EVENT_MGT_ERROR); + pEventDesc[nbEventsRaised].eventId = SVA_EVENT_BUFFER_VOIDED; + pEventDesc[nbEventsRaised].serviceId = serviceId; + pEventDesc[nbEventsRaised].eventTimestamp = (t_sva_timestamp_value) eventTimestamp; + pEventDesc[nbEventsRaised].eventDate = (t_sva_timestamp_value) eventDate; + pEventDesc[nbEventsRaised].extraInfo = 0; + sva_BM_UpdateBufferStatus(pEventDesc[nbEventsRaised].bufferId,SVA_BUFFER_VOIDED,eventTimestamp); + nbEventsRaised++; + pDesc->status.eventStats.voidedCounter++; + pDesc->status.bufferizationStats.inLevel--; + } + } + pDesc->fakeBufferAdded = FALSE; + ffError = POP_FIFO_ELEM(stillDecodeDesc[instanceNum].windowBufferFifos.inUse,t_sva_sdc_block,blockDesc); + HCL_DEBUG_ASSERT (ffError == SVA_FIFO_OK); + ffError = PUSH_FIFO_ELEM(stillDecodeDesc[instanceNum].windowBufferFifos.push,t_sva_sdc_block,blockDesc); + HCL_DEBUG_ASSERT (ffError == SVA_FIFO_OK); + + /* Handle output image buffers */ + ffError=POP_FIFO_ELEM(pDesc->outputImageFifos.inUse, t_sva_buffer_id,pEventDesc[nbEventsRaised].bufferId); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + CHECK_TABLE_OVERFLOW(nbEventsRaised, maxOfEvent, SVA_INTERNAL_EVENT_MGT_ERROR); + pEventDesc[nbEventsRaised].eventId = SVA_EVENT_BUFFER_FILLED; + pEventDesc[nbEventsRaised].serviceId = serviceId; + pEventDesc[nbEventsRaised].eventTimestamp = (t_sva_timestamp_value) eventTimestamp; + pEventDesc[nbEventsRaised].eventDate = (t_sva_timestamp_value) eventDate; + pEventDesc[nbEventsRaised].extraInfo = 0; + sva_BM_UpdateBufferStatus(pEventDesc[nbEventsRaised].bufferId,SVA_BUFFER_FILLED,eventTimestamp); + nbEventsRaised++; + pDesc->status.nbImagesDecoded++; + pDesc->status.eventStats.filledCounter++; + pDesc->status.bufferizationStats.outLevel--; + + /* Handle output ACE param buffer */ + ffError=POP_FIFO_ELEM(pDesc->aceParamFifos.inUse, t_sva_buffer_id,pEventDesc[nbEventsRaised].bufferId); + HCL_DEBUG_ASSERT(ffError == SVA_FIFO_OK); + bmError = sva_BM_GetBufferLogicalAddress(pEventDesc[nbEventsRaised].bufferId, ¶mAddr); + HCL_DEBUG_ASSERT(bmError == SVA_BM_OK); + algoError = stillDecodeAlgoDesc[pDesc->algo].pSetParamBuffer(instanceNum, subtaskId, paramAddr); + HCL_DEBUG_ASSERT(algoError == SVA_SDC_ALGO_OK); + + CHECK_TABLE_OVERFLOW(nbEventsRaised, maxOfEvent, SVA_INTERNAL_EVENT_MGT_ERROR); + pEventDesc[nbEventsRaised].eventId = SVA_EVENT_BUFFER_FILLED; + pEventDesc[nbEventsRaised].serviceId = serviceId; + pEventDesc[nbEventsRaised].eventTimestamp = (t_sva_timestamp_value) eventTimestamp; + pEventDesc[nbEventsRaised].eventDate = (t_sva_timestamp_value) eventDate; + pEventDesc[nbEventsRaised].extraInfo = 0; + sva_BM_UpdateBufferStatus(pEventDesc[nbEventsRaised].bufferId,SVA_BUFFER_FILLED,eventTimestamp); + nbEventsRaised++; + pDesc->status.eventStats.filledCounter++; + } + else if (decodeStatus == SVA_SDC_DECODE_INCOMPLETE || decodeStatus == SVA_SDC_DECODE_NOPROGRESS) + { + t_uint32 byteOffset; + t_uint32 bitOffset; + + /* Handle subtask dependancies */ + subtaskDep.subtaskId = subtaskId; + subtaskDep.dependencies = pDesc->defaultDep; + subtaskDep.dependencies.outputBufferDep = RESOLVED_DEPENDENCY; + subtaskDep.dependencies.headerInfoDep = RESOLVED_DEPENDENCY; + subtaskDep.dependencies.paramBufferDep = RESOLVED_DEPENDENCY; + if(GET_FIFO_NB_ELEMS(pDesc->inputBitstreamFifo) > 1) /* An EOW alway does not mean all buffer has been exhausted because of concurrency */ + subtaskDep.dependencies.bitstreamBufferDep = RESOLVED_DEPENDENCY; + if(pDesc->assertEndofStream == TRUE) /* a case for codec mode where, the fake buffer was added on-the-fly */ + subtaskDep.dependencies.bitstreamBufferDep = RESOLVED_DEPENDENCY; + ffError = PUSH_REVERSE_FIFO_ELEM(pDesc->subtasksDependencyFifo, t_sva_sdc_subtask_dependencies, subtaskDep); + HCL_DEBUG_ASSERT(ffError == SVA_FIFO_OK); + + + if (decodeStatus == SVA_SDC_DECODE_INCOMPLETE) + { + /* Handle input bitstream buffer */ + byteOffset = bufferOutPos.addr_bitstream_start; + bitOffset = bufferOutPos.bitstream_offset; + + bufferOutPos.addr_bitstream_start = ((byteOffset >> 4) <<4); + bufferOutPos.bitstream_offset = (byteOffset - ((byteOffset >> 4) <<4)) * 8 + bitOffset; + + // printf("..bitstream start position is %d\n", bufferOutPos.addr_bitstream_start); + // printf("..bitstream offset is %d\n", bufferOutPos.bitstream_offset); + + ffError = READ_FIFO_ELEM(stillDecodeDesc[instanceNum].windowBufferFifos.inUse,t_sva_sdc_block,blockDesc); + HCL_DEBUG_ASSERT (ffError == SVA_FIFO_OK); + bufferOutPos.addr_bitstream_buf_struct = blockDesc.addr.physical | 0x00000001; + + tmError=sva_TM_InitSubTaskField(subtaskId, SVA_TM_DEC_ADDR_IN_BITSTREAM_BUFFER, + (t_logical_address) &bufferOutPos, sizeof(t_sva_bitstream_buffer_pos)); + if (tmError!= SVA_TM_OK) {return SVA_INTERNAL_STILL_DECODER_ERROR;} + + /* Handle output image buffer */ + CHECK_TABLE_OVERFLOW(nbEventsRaised, maxOfEvent, SVA_INTERNAL_EVENT_MGT_ERROR); + pEventDesc[nbEventsRaised].eventId = SVA_EVENT_BUFFER_PARTLY_FILLED; + pEventDesc[nbEventsRaised].serviceId = serviceId; + pEventDesc[nbEventsRaised].eventTimestamp = (t_sva_timestamp_value) eventTimestamp; + pEventDesc[nbEventsRaised].eventDate = (t_sva_timestamp_value) eventDate; + pEventDesc[nbEventsRaised].extraInfo = extraInfo; + + ffError=READ_FIFO_ELEM(pDesc->outputImageFifos.inUse, t_sva_buffer_id,pEventDesc[nbEventsRaised].bufferId); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + nbEventsRaised++; + pDesc->status.eventStats.partlyCounter++; + } + } + } + break; + + case SVA_TM_EOK_HW_EVENT : + if (pDesc->state == SVA_SDC_STOP_REQUESTED) + { + /*generate a stop event*/ + CHECK_TABLE_OVERFLOW(nbEventsRaised, maxOfEvent, SVA_INTERNAL_EVENT_MGT_ERROR); + pEventDesc[nbEventsRaised].eventId = SVA_EVENT_SERVICE_STOPPED; + pEventDesc[nbEventsRaised].serviceId = serviceId; + pEventDesc[nbEventsRaised].bufferId = INVALID_BUFFER_ID; + pEventDesc[nbEventsRaised].eventTimestamp = (t_sva_timestamp_value) eventTimestamp; + pEventDesc[nbEventsRaised].eventDate = (t_sva_timestamp_value) eventDate; + pEventDesc[nbEventsRaised].extraInfo = 0; + nbEventsRaised++; + } + + sva_SDC_UpdateInstanceStatesMachine(instanceNum, SVA_SDC_EVENT_EOK); + + break; + + case SVA_TM_ACTIVE_HW_EVENT: + CHECK_TABLE_OVERFLOW(nbEventsRaised, maxOfEvent, SVA_INTERNAL_EVENT_MGT_ERROR); + pEventDesc[nbEventsRaised].eventId = SVA_EVENT_SERVICE_ACTIVATED; + pEventDesc[nbEventsRaised].serviceId = serviceId; + pEventDesc[nbEventsRaised].bufferId = INVALID_BUFFER_ID; + pEventDesc[nbEventsRaised].eventTimestamp = (t_sva_timestamp_value) eventTimestamp; + pEventDesc[nbEventsRaised].eventDate = (t_sva_timestamp_value) eventDate; + pEventDesc[nbEventsRaised].extraInfo = 0; + nbEventsRaised++; + sva_SDC_UpdateInstanceStatesMachine(instanceNum, SVA_SDC_EVENT_ACTIVE); + break; + + case SVA_TM_INACTIVE_HW_EVENT: + CHECK_TABLE_OVERFLOW(nbEventsRaised, maxOfEvent, SVA_INTERNAL_EVENT_MGT_ERROR); + pEventDesc[nbEventsRaised].eventId = SVA_EVENT_SERVICE_INACTIVATED; + pEventDesc[nbEventsRaised].serviceId = serviceId; + pEventDesc[nbEventsRaised].bufferId = INVALID_BUFFER_ID; + pEventDesc[nbEventsRaised].eventTimestamp = (t_sva_timestamp_value) eventTimestamp; + pEventDesc[nbEventsRaised].eventDate = (t_sva_timestamp_value) eventDate; + pEventDesc[nbEventsRaised].extraInfo = 0; + nbEventsRaised++; + sva_SDC_UpdateInstanceStatesMachine(instanceNum,SVA_SDC_EVENT_INACTIVE); + break; + + case SVA_TM_FAKE_HW_EVENT: + if (pDesc->state == SVA_SDC_FLUSHING_IN) { + pEventDesc[nbEventsRaised].eventId = SVA_EVENT_SERVICE_FLUSHED_IN; + } + if (pDesc->state == SVA_SDC_FLUSHING_OUT) { + pEventDesc[nbEventsRaised].eventId = SVA_EVENT_SERVICE_FLUSHED_OUT; + } + + CHECK_TABLE_OVERFLOW(nbEventsRaised, maxOfEvent, SVA_INTERNAL_EVENT_MGT_ERROR); + pEventDesc[nbEventsRaised].serviceId = serviceId; + pEventDesc[nbEventsRaised].bufferId = INVALID_BUFFER_ID; + pEventDesc[nbEventsRaised].eventTimestamp = (t_sva_timestamp_value) eventTimestamp; + pEventDesc[nbEventsRaised].eventDate = (t_sva_timestamp_value) eventDate; + pEventDesc[nbEventsRaised].extraInfo = 0; + nbEventsRaised++; + sva_SDC_UpdateInstanceStatesMachine(instanceNum, SVA_SDC_EVENT_FAKE); + break; + + case SVA_TM_ERR_HW_EVENT: + sva_TM_GetSubTaskField(subtaskId,SVA_TM_DEC_ADDR_OUT_PARAMETERS,(t_logical_address)¶mOut,0, sizeof(t_sva_vdc_jpeg_param_out), TRUE); + CHECK_TABLE_OVERFLOW(nbEventsRaised, maxOfEvent, SVA_INTERNAL_EVENT_MGT_ERROR); + + pEventDesc[nbEventsRaised].eventId = SVA_EVENT_SERVICE_ERROR; + pEventDesc[nbEventsRaised].serviceId = serviceId; + pEventDesc[nbEventsRaised].bufferId = INVALID_BUFFER_ID; + pEventDesc[nbEventsRaised].eventTimestamp = (t_sva_timestamp_value) eventTimestamp; + pEventDesc[nbEventsRaised].eventDate = (t_sva_timestamp_value) eventDate; + if (pDesc->state == SVA_SDC_ABORT_REQUESTED) + { + pEventDesc[nbEventsRaised].extraInfo = 0; + } + else + { + pEventDesc[nbEventsRaised].extraInfo = (t_uint32) (paramOut.error_type); + } + + pDesc->status.errorId = SVA_STILL_DECODER_TASK_PARAMETER_ERROR; + nbEventsRaised++; + pDesc->status.eventStats.errorCounter++; + sva_SDC_UpdateInstanceStatesMachine(instanceNum, SVA_SDC_EVENT_ERROR); + break; + + default: + break; + } + /*try to solve some dependencies*/ + sva_SDC_ResolveDependencies(instanceNum); + + /*return number of generated events*/ + *pNbEvent = nbEventsRaised; + +#ifdef __DEBUG + { + t_uint32 systemTimeDbg; + + SVA_GetServiceSystemTime(serviceId,&systemTimeDbg); + eventStillDecodeDebugTable[instanceNum].eventDebugDesc[eventStillDecodeDebugTable[instanceNum].nbOfEventReceived%LOG_DEPTH].stopHandlingTime=systemTimeDbg; + eventStillDecodeDebugTable[instanceNum].nbOfEventReceived++; + } +#endif + + return SVA_OK; +} + + +/****************************************************************************/ +/* NAME: t_sva_sdc_error sva_SDC_ResolveDependencies( */ +/* t_sva_service_instance_num instanceNum */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* */ +/* This routine is called in sva_SDC_Push, SVA_SetHeaderInfos() */ +/* and after specific event like EOT */ +/* */ +/* PARAMETERS: */ +/* IN : instanceNum: instance number of the service */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: t_sva_SDC_error */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ + +PRIVATE t_sva_sdc_error sva_SDC_ResolveDependencies ( + t_sva_service_instance_num instanceNum +) +{ + t_sva_sdc_descriptor *pDesc = &stillDecodeDesc[instanceNum]; + t_sva_sdc_algo_error algoError; + t_bool condition=FALSE; + t_sva_buffer_id bufferId; + t_sva_sdc_subtask_dependencies subtaskDep; + t_sva_bitstream_desc bitstreamDesc; + t_sva_ff_error ffError; + t_sva_tm_error tmError; + t_sva_bm_error bmError; + t_physical_address phyAddr; + t_sva_bitstream_buffer_pos bitPos; + t_size Size; + + /* check that transition is valid */ + if (sva_SDC_isTransitionValid(instanceNum,SVA_SDC_ALL_DEPENDENCIES_RESOLVED) == FALSE) {return SVA_SDC_INVALID_TRANSITION;} + + /* check if any of the dependancies for the first sub-task in the queue could be resolved */ + if(IS_FIFO_EMPTY(pDesc->subtasksDependencyFifo) == FALSE) + { + /*read subtask for which we will try to solve dependencies*/ + ffError=READ_FIFO_ELEM(pDesc->subtasksDependencyFifo, t_sva_sdc_subtask_dependencies, subtaskDep); + HCL_DEBUG_ASSERT(ffError == SVA_FIFO_OK); + + /* check header info dependancies */ + if(subtaskDep.dependencies.headerInfoDep == NOT_RESOLVED_DEPENDENCY) //try to resolve header dep. + { + algoError = stillDecodeAlgoDesc[pDesc->algo].pAreNextFrameInfosAvailable(instanceNum, &condition); + HCL_DEBUG_ASSERT(algoError == SVA_SDC_ALGO_OK); + /* if header dependancy gets resolved at this stage bitstream dependancy also get resolved*/ + if(condition == TRUE) + { + t_sva_sdc_block blockDesc = {INVALID_BUFFER_ID, 0x00000000}; + t_sva_bitstream_buffer * pBuffer; + + algoError = stillDecodeAlgoDesc[pDesc->algo].pGetNextFrameParamsIn(instanceNum, &phyAddr, &bitstreamDesc); + HCL_DEBUG_ASSERT(algoError == SVA_SDC_ALGO_OK); + + /* Update subtask Field by address for param-in buffer */ + tmError=sva_TM_UpdateSubTaskField(SVA_TM_INTERMEDIATE_FIELD_TO_UPDATE, subtaskDep.subtaskId, + SVA_TM_DEC_ADDR_IN_PARAMETERS, FCMD_NEW_ADDRESS, phyAddr|0x00000001, 0, 0); + if (tmError != SVA_TM_OK) {return SVA_SDC_TM_LINKED_ERROR;} + ffError=UPDATE_FIFO_ELEM_FIELD(pDesc->subtasksDependencyFifo, t_sva_sdc_subtask_dependencies, .dependencies.headerInfoDep, RESOLVED_DEPENDENCY); + if (ffError != SVA_FIFO_OK) {return SVA_SDC_FF_LINKED_ERROR;} + + bmError = sva_BM_GetBufferPhysicalAddress(bitstreamDesc.relatedBufferId, &phyAddr); + HCL_DEBUG_ASSERT (bmError == SVA_BM_OK); + bmError = sva_BM_GetBufferSize(bitstreamDesc.relatedBufferId, &Size); + HCL_DEBUG_ASSERT (bmError == SVA_BM_OK); + + ffError=POP_FIFO_ELEM(stillDecodeDesc[instanceNum].windowBufferFifos.push,t_sva_sdc_block,blockDesc); + if (ffError != SVA_FIFO_OK) {return SVA_SDC_FF_LINKED_ERROR;} + ffError=PUSH_FIFO_ELEM(stillDecodeDesc[instanceNum].windowBufferFifos.inUse,t_sva_sdc_block,blockDesc); + if (ffError != SVA_FIFO_OK) {return SVA_SDC_FF_LINKED_ERROR;} + + pBuffer = (t_sva_bitstream_buffer *)blockDesc.addr.logical; + + pBuffer->addr_buffer_start = phyAddr; + pBuffer->addr_buffer_end = phyAddr + Size; + pBuffer->addr_window_start = phyAddr; + pBuffer->addr_window_end = phyAddr + Size; + + bitPos.addr_bitstream_buf_struct = blockDesc.addr.physical | 0x00000001; + bitPos.addr_bitstream_start = bitstreamDesc.bitstreamPosition.addr_bitstream_start; + bitPos.bitstream_offset = bitstreamDesc.bitstreamPosition.bitstream_offset; + + tmError = sva_TM_InitSubTaskField(subtaskDep.subtaskId, SVA_TM_DEC_ADDR_IN_BITSTREAM_BUFFER, + (t_logical_address) &bitPos, sizeof(t_sva_bitstream_buffer_pos)); + ffError = UPDATE_FIFO_ELEM_FIELD(pDesc->subtasksDependencyFifo, t_sva_sdc_subtask_dependencies, .dependencies.bitstreamBufferDep, RESOLVED_DEPENDENCY); + if (ffError != SVA_FIFO_OK) {return SVA_SDC_FF_LINKED_ERROR;} + } + } + + if(subtaskDep.dependencies.outputBufferDep == NOT_RESOLVED_DEPENDENCY) //try to resolve image dep. + { + if(IS_FIFO_EMPTY(pDesc->outputImageFifos.push) == FALSE) //1 image buffer available => resolve + { + //Transfer elem from outputimage fifo push to inUse + ffError = POP_FIFO_ELEM(stillDecodeDesc[instanceNum].outputImageFifos.push, t_sva_buffer_id, bufferId); + if (ffError!= SVA_FIFO_OK) {return SVA_SDC_FF_LINKED_ERROR;} + ffError = PUSH_FIFO_ELEM(stillDecodeDesc[instanceNum].outputImageFifos.inUse, t_sva_buffer_id, bufferId); + if (ffError!= SVA_FIFO_OK) {return SVA_SDC_FF_LINKED_ERROR;} + + /* update dependancy infos regarding image buffer */ + ffError = UPDATE_FIFO_ELEM_FIELD(pDesc->subtasksDependencyFifo, t_sva_sdc_subtask_dependencies, .dependencies.outputBufferDep, RESOLVED_DEPENDENCY); + if (ffError != SVA_FIFO_OK) {return SVA_SDC_FF_LINKED_ERROR;} + //update subtask to take into account new buffer: update addroutframebuf/dest buffer part field + bmError = sva_BM_GetBufferPhysicalAddress(bufferId, &phyAddr); + HCL_DEBUG_ASSERT(bmError == SVA_BM_OK); + + //upadate frame buffer output subtask Field + tmError = sva_TM_UpdateSubTaskField(SVA_TM_INTERMEDIATE_FIELD_TO_UPDATE, subtaskDep.subtaskId, + SVA_TM_DEC_ADDR_OUT_FRAME_BUFFER, FCMD_COPY, (t_uint32)&phyAddr, 0, 4); + if (tmError != SVA_TM_OK) {return SVA_SDC_TM_LINKED_ERROR;} + } + } + + if(subtaskDep.dependencies.paramBufferDep == NOT_RESOLVED_DEPENDENCY) //try to resolve infos dep. + { + if(IS_FIFO_EMPTY(pDesc->aceParamFifos.push) == FALSE) //1 infos buffer available => resolve + { + //Remove Info buffer from fifo and stores it as bufferId + !! transfer to InUse fifo !! + ffError = POP_FIFO_ELEM(stillDecodeDesc[instanceNum].aceParamFifos.push, t_sva_buffer_id, bufferId); + if (ffError != SVA_FIFO_OK) {return SVA_SDC_FF_LINKED_ERROR;} + ffError = PUSH_FIFO_ELEM(stillDecodeDesc[instanceNum].aceParamFifos.inUse, t_sva_buffer_id, bufferId); + if (ffError != SVA_FIFO_OK) {return SVA_SDC_FF_LINKED_ERROR;} + + //update dependancy infos regarding infos buffer + ffError = UPDATE_FIFO_ELEM_FIELD(pDesc->subtasksDependencyFifo, t_sva_sdc_subtask_dependencies, .dependencies.paramBufferDep, RESOLVED_DEPENDENCY); + if (ffError != SVA_FIFO_OK) {return SVA_SDC_FF_LINKED_ERROR;} + } + } + + //Are all subtask dep resolved? + ffError = READ_FIFO_ELEM(stillDecodeDesc[instanceNum].subtasksDependencyFifo, t_sva_sdc_subtask_dependencies, subtaskDep);//update infosDep + if(sva_SDC_AreAllDependanciesResolved(subtaskDep) == TRUE) + { + t_sva_tm_timestamp immediateTimeStamp = {SVA_TM_IMMEDIATE, 0}; + + /*pop subtask from list of subtask for which dep has to be solved*/ + ffError = POP_FIFO_ELEM(pDesc->subtasksDependencyFifo, t_sva_sdc_subtask_dependencies,subtaskDep); + if (ffError != SVA_FIFO_OK) {return SVA_SDC_FF_LINKED_ERROR;} + /*add subtask to list of schedulable subtasks*/ + tmError = sva_TM_AddElemToSubTaskList(pDesc->subtasksListId, subtaskDep.subtaskId, &immediateTimeStamp, 1); + HCL_DEBUG_ASSERT(tmError == SVA_TM_OK); + /*update state machine*/ + sva_SDC_UpdateInstanceStatesMachine(instanceNum, SVA_SDC_ALL_DEPENDENCIES_RESOLVED); + + } + } + return SVA_SDC_OK; +} + + +/****************************************************************************/ +/* NAME: sva_SDC_AreAllDependanciesResolved() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: This routine enables to check all dependancies related */ +/* to a subtask */ +/* PARAMETERS: */ +/* IN : t_sva_SDC_subtask_dependencies subtaskDep : Subtask to check */ +/* OUT :none */ +/* */ +/* RETURN: */ +/* t_bool */ +/*--------------------------------------------------------------------------*/ +/* USE: NA */ +/* USED BY: NA */ +/****************************************************************************/ +PRIVATE t_bool sva_SDC_AreAllDependanciesResolved(t_sva_sdc_subtask_dependencies subtaskDep) +{ + if((subtaskDep.dependencies.bitstreamBufferDep != NOT_RESOLVED_DEPENDENCY)&& + (subtaskDep.dependencies.outputBufferDep != NOT_RESOLVED_DEPENDENCY)&& + (subtaskDep.dependencies.paramBufferDep != NOT_RESOLVED_DEPENDENCY)&& + (subtaskDep.dependencies.headerInfoDep != NOT_RESOLVED_DEPENDENCY)) + { + return TRUE; + } + else {return FALSE;} +} + +/****************************************************************************/ +/* NAME: t_bool sva_SDC_IsConfigurationValid( */ +/* const t_sva_still_decoder_configuration *pConf */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will check that given configuration given to grab is */ +/* valid. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - pConf: a pointer to the configuration to check */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: t_bool */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + TO DO : + - check if some others value can be check +*/ +PRIVATE t_bool sva_SDC_IsConfigurationValid ( + const t_sva_still_decoder_configuration *pConf +) +{ + HCL_DEBUG_ASSERT(pConf != NULL); + + if(pConf->transformId != SVA_DECODER_SEQUENTIAL_JPEG && pConf->transformId != SVA_DECODER_PROGRESSIVE_JPEG) + return FALSE; + /* stream mode not yet supported */ + if(pConf->mode != SVA_CODEC_IMAGE_MODE && pConf->mode != SVA_CODEC_SEGMENTED_MODE) + return FALSE; + + if(pConf->aceStrength < SVA_ACE_STRENGTH_1 || pConf->aceStrength > SVA_ACE_STRENGTH_8) + return FALSE; + + return TRUE; +} + +/****************************************************************************/ +/* NAME: t_bool sva_SDC_isTransitionValid( */ +/* t_sva_service_instance_num instanceNum, */ +/* t_sva_SDC_transition requestedTransition */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine checks if the requestedTransition is valid for both */ +/* state machine */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - instanceNum : instance number for which transition check must be done*/ +/* - requestedTransition: identifier of the requested transition */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: t_bool */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + DONE +*/ +PRIVATE t_bool sva_SDC_isTransitionValid ( + t_sva_service_instance_num instanceNum, + t_sva_sdc_transition requestedTransition +) +{ + t_sva_sdc_descriptor *pDesc = &stillDecodeDesc[instanceNum]; + t_sva_sdc_state nextState; + t_sva_sdc_activate_state nextActivateState; + + /* Compute the next state for both state machine*/ + nextState=stateMachine[pDesc->state][requestedTransition]; + nextActivateState = activateStateMachine[pDesc->activateState][requestedTransition]; + + /*return false in case of invalid transition for at least one state machine*/ + if (nextState != SVA_SDC_TRANSITION_REJECTED && nextActivateState != SVA_SDC_ACTIVATE_TRANSITION_REJECTED) {return TRUE;} + else {return FALSE;} +} + +/****************************************************************************/ +/* NAME: t_sva_error sva_SDC_CheckServiceId(t_sva_service_id serviceId) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will check that task_id and instance number of servideId*/ +/* are both valid */ +/* */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - serviceId: service id to check */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: t_sva_SDC_error */ +/* - SVA_UNKNOWN_SERVICE_ID : Invalid service id. Either due to an */ +/* invalid task id or invalid instance number. */ +/* - SVA_OK : Service id is valid */ +/* */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + DONE +*/ +PRIVATE t_sva_error sva_SDC_CheckServiceId ( + t_sva_service_id serviceId +) +{ + t_sva_service_instance_num instanceNum = READ_INSTANCE_NUM_IN_SERVICE_ID(serviceId); + t_sva_sv_task_id taskId = READ_TASK_ID_IN_SERVICE_ID(serviceId); + + if (taskId != SVA_SV_STILL_DECODE_TID) {return SVA_UNKNOWN_SERVICE_ID;} + if (instanceNum >= NUM_MAX_STILL_DECODE) {return SVA_UNKNOWN_SERVICE_ID;} + + return SVA_OK; +} + +/****************************************************************************/ +/* NAME: t_sva_SDC_state sva_SDC_UpdateInstanceStatesMachine( */ +/* t_sva_service_instance_num instanceNum, */ +/* t_sva_SDC_transition requestedTransition */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine allows to update both state machine */ +/* following the given requestedTransition */ +/* */ +/* N.B: This routine returns the new state after the requested transition */ +/* A special return state (SVA_SDC_TRANSITION_REJECTED) is used to check */ +/* the validity of a transition request */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - instanceNum : instance number for which state must be updated */ +/* - requestedTransition: identifier of the requested transition */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: t_sva_SDC_state */ +/* - one of the t_sva_SDC_state */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + DONE +*/ +PRIVATE t_sva_sdc_state sva_SDC_UpdateInstanceStatesMachine ( + t_sva_service_instance_num instanceNum, + t_sva_sdc_transition requestedTransition +) +{ + t_sva_sdc_descriptor *pDesc = &stillDecodeDesc[instanceNum]; + t_sva_sdc_state nextState; + t_sva_sdc_activate_state nextActivateState; + + +#ifdef __DEBUG + { + t_uint32 systemTime; + + SVA_GetServiceSystemTime(pDesc->serviceId,&systemTime); + transitionStillDecodeDebugTable[instanceNum].transitionDebugDesc[transitionStillDecodeDebugTable[instanceNum].nbOfTransitionReceived%LOG_DEPTH].state=pDesc->state; + transitionStillDecodeDebugTable[instanceNum].transitionDebugDesc[transitionStillDecodeDebugTable[instanceNum].nbOfTransitionReceived%LOG_DEPTH].transition=requestedTransition; + transitionStillDecodeDebugTable[instanceNum].transitionDebugDesc[transitionStillDecodeDebugTable[instanceNum].nbOfTransitionReceived%LOG_DEPTH].systemTime=systemTime; + transitionStillDecodeDebugTable[instanceNum].transitionDebugDesc[transitionStillDecodeDebugTable[instanceNum].nbOfTransitionReceived%LOG_DEPTH].activateState=pDesc->activateState; + transitionStillDecodeDebugTable[instanceNum].nbOfTransitionReceived++; + + } +#endif + + /* Compute the next state */ + nextState=stateMachine[pDesc->state][requestedTransition]; + nextActivateState=activateStateMachine[pDesc->activateState][requestedTransition]; + + /* Check if the transition is valid */ + if (nextState != SVA_SDC_TRANSITION_REJECTED && nextActivateState != SVA_SDC_ACTIVATE_TRANSITION_REJECTED) + { + /* Update both current state of the instance */ + pDesc->state = nextState; + pDesc->activateState = nextActivateState; + /* Update status*/ + pDesc->status.state = decodeState2ServiceState[pDesc->state]; + } + + return nextState; +} + + +/****************************************************************************/ +/* NAME: t_sva_error sva_SDC_DoFlushIn( */ +/* t_sva_service_id serviceId */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will flush input fifo. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - serviceId: service identifier */ +/* */ +/* OUT: none */ +/* */ +/* RETURN: t_sva_error */ +/* - SVA_OK */ +/* - SVA_INTERNAL_STILL_DECODER_ERROR */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + DONE +*/ +PRIVATE t_sva_error sva_SDC_DoFlushIn ( + t_sva_service_id serviceId +) +{ + t_sva_service_instance_num instanceNum = READ_INSTANCE_NUM_IN_SERVICE_ID(serviceId); + t_sva_sdc_descriptor *pDesc=&stillDecodeDesc[instanceNum]; + t_sva_sdc_subtask_dependencies subtaskDep; + t_sva_buffer_id bufferId = INVALID_BUFFER_ID; + t_uint32 systemTime; + t_sva_error svaError; + t_sva_tm_error tmError; + t_sva_ff_error ffError; + t_sva_bm_error bmError; + t_sva_sdc_algo_error algoError; + t_sva_sdc_block blockDesc; + + /*remove schedule tasks and push them back in subtasksDependencyFifo with default dep*/ + /*so they can be rescheduled */ + do + { + tmError=sva_TM_RemoveElemFromSubTaskList(pDesc->subtasksListId,&subtaskDep.subtaskId); + if (tmError==SVA_TM_OK) + { + algoError = stillDecodeAlgoDesc[pDesc->algo].pCleanupTaskEnd(instanceNum, subtaskDep.subtaskId); + HCL_DEBUG_ASSERT(algoError == SVA_SDC_ALGO_OK); + subtaskDep.dependencies = pDesc->defaultDep; + ffError=PUSH_FIFO_ELEM(pDesc->subtasksDependencyFifo,t_sva_sdc_subtask_dependencies,subtaskDep); + if (ffError!=SVA_FIFO_OK) {return SVA_INTERNAL_STILL_DECODER_ERROR;} + } + } while (tmError==SVA_TM_OK); + + /*get time*/ + svaError=SVA_GetServiceSystemTime(serviceId,&systemTime); + if (svaError != SVA_OK) {return SVA_INTERNAL_STILL_DECODER_ERROR;} + + /* fifos inputBitstreamFifo */ + while(POP_FIFO_ELEM(pDesc->inputBitstreamFifo,t_sva_buffer_id,bufferId) != SVA_FIFO_EMPTY) + { + bmError=sva_BM_UpdateBufferStatus(bufferId,SVA_BUFFER_NOT_USED,systemTime); + if (bmError!=SVA_BM_OK) {return SVA_INTERNAL_STILL_DECODER_ERROR;} + pDesc->status.bufferizationStats.inLevel--; + } + + while(POP_FIFO_ELEM(pDesc->windowBufferFifos.inUse,t_sva_sdc_block,blockDesc) != SVA_FIFO_EMPTY) + { + ffError=PUSH_FIFO_ELEM(pDesc->windowBufferFifos.push,t_sva_sdc_block,blockDesc); + if (ffError!= SVA_FIFO_OK) {return SVA_INTERNAL_STILL_DECODER_ERROR;} + } + + /*move all output buffers from the in use fifo to the push fifo in reverse order*/ + /* For JPEG decode, that means : */ + /* - aceParamFifos */ + /* - outputImageFifos */ + do + { + ffError=POP_REVERSE_FIFO_ELEM(pDesc->aceParamFifos.inUse,t_sva_buffer_id,bufferId); + if (ffError==SVA_FIFO_OK) + { + ffError=PUSH_REVERSE_FIFO_ELEM(pDesc->aceParamFifos.push,t_sva_buffer_id,bufferId); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + } + } while (ffError==SVA_FIFO_OK); + + do + { + ffError=POP_REVERSE_FIFO_ELEM(pDesc->outputImageFifos.inUse,t_sva_buffer_id,bufferId); + if (ffError==SVA_FIFO_OK) + { + ffError=PUSH_REVERSE_FIFO_ELEM(pDesc->outputImageFifos.push,t_sva_buffer_id,bufferId); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + } + } while (ffError==SVA_FIFO_OK); + + /*flush algo specific fifo*/ + algoError=stillDecodeAlgoDesc[pDesc->algo].pFlushFifos(instanceNum); + HCL_DEBUG_ASSERT(algoError == SVA_SDC_ALGO_OK); + + return SVA_OK; +} + + +/****************************************************************************/ +/* NAME: t_sva_error sva_SDC_DoFlushOut( */ +/* t_sva_service_id serviceId */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will flush output fifos: */ +/* PARAMETERS: */ +/* IN : */ +/* - serviceId: service identifier */ +/* */ +/* OUT: none */ +/* */ +/* RETURN: t_sva_error */ +/* - SVA_OK */ +/* - SVA_INTERNAL_STILL_DECODER_ERROR */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + DONE +*/ +PRIVATE t_sva_error sva_SDC_DoFlushOut ( + t_sva_service_id serviceId +) +{ + t_sva_service_instance_num instanceNum = READ_INSTANCE_NUM_IN_SERVICE_ID(serviceId); + t_sva_sdc_descriptor *pDesc=&stillDecodeDesc[instanceNum]; + t_sva_sdc_subtask_dependencies subtaskDep; + t_sva_buffer_id bufferId; + t_uint32 systemTime; + t_sva_error svaError; + t_sva_tm_error tmError; + t_sva_ff_error ffError; + t_sva_bm_error bmError; + t_sva_sdc_algo_error algoError; + + /*remove schedule tasks and push them back in subtasksDependencyFifo with default dep*/ + /*so they can be rescheduled */ + do + { + tmError=sva_TM_RemoveElemFromSubTaskList(pDesc->subtasksListId,&subtaskDep.subtaskId); + if (tmError==SVA_TM_OK) + { + algoError = stillDecodeAlgoDesc[pDesc->algo].pCleanupTaskEnd(instanceNum, subtaskDep.subtaskId); + HCL_DEBUG_ASSERT(algoError == SVA_SDC_ALGO_OK); + subtaskDep.dependencies = pDesc->defaultDep; + ffError=PUSH_FIFO_ELEM(pDesc->subtasksDependencyFifo,t_sva_sdc_subtask_dependencies,subtaskDep); + if (ffError!=SVA_FIFO_OK) {return SVA_INTERNAL_STILL_DECODER_ERROR;} + } + } while (tmError==SVA_TM_OK); + + /*get time*/ + svaError=SVA_GetServiceSystemTime(serviceId,&systemTime); + if (svaError != SVA_OK) {return SVA_INTERNAL_STILL_DECODER_ERROR;} + + /*flush fifos*/ + //fifo outputImageFifo + while(POP_FIFO_ELEM(pDesc->outputImageFifos.push,t_sva_buffer_id,bufferId) != SVA_FIFO_EMPTY) + { + bmError=sva_BM_UpdateBufferStatus(bufferId,SVA_BUFFER_NOT_USED,systemTime); + if (bmError!=SVA_BM_OK) {return SVA_INTERNAL_STILL_DECODER_ERROR;} + pDesc->status.bufferizationStats.outLevel--; + } + while(POP_FIFO_ELEM(pDesc->outputImageFifos.inUse,t_sva_buffer_id,bufferId) != SVA_FIFO_EMPTY) + { + bmError=sva_BM_UpdateBufferStatus(bufferId,SVA_BUFFER_NOT_USED,systemTime); + if (bmError!=SVA_BM_OK) {return SVA_INTERNAL_STILL_DECODER_ERROR;} + pDesc->status.bufferizationStats.outLevel--; + } + + + //fifos outputParamsFifos + while(POP_FIFO_ELEM(pDesc->aceParamFifos.push,t_sva_buffer_id,bufferId) != SVA_FIFO_EMPTY) + { + bmError=sva_BM_UpdateBufferStatus(bufferId,SVA_BUFFER_NOT_USED,systemTime); + if (bmError!=SVA_BM_OK) {return SVA_INTERNAL_STILL_DECODER_ERROR;} + } + while(POP_FIFO_ELEM(pDesc->aceParamFifos.inUse,t_sva_buffer_id,bufferId) != SVA_FIFO_EMPTY) + { + bmError=sva_BM_UpdateBufferStatus(bufferId,SVA_BUFFER_NOT_USED,systemTime); + if (bmError!=SVA_BM_OK) {return SVA_INTERNAL_STILL_DECODER_ERROR;} + } + + + return SVA_OK; +} + + +/****************************************************************************/ +/* NAME: t_sva_error sva_SDC_Delete ( */ +/* t_sva_service_id serviceId */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine deletes a Decode service */ +/* a SVA_SERVICE_FLUSH_IN and a SVA_SERVICE_FLUSH_OUT command should */ +/* be done previously */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - serviceId: identifier of the service */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/* - SVA_OK : Command taken into account */ +/* - SVA_UNKNOWN_SERVICE_ID : service id is not correct */ +/* - SVA_UNEXPECTED_API_CALL : Command cannot be excecuted in */ +/* current context. */ +/* - SVA_INTERNAL_STILL_DECODER_ERROR : internal error */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + DONE +*/ +PUBLIC t_sva_error sva_SDC_Delete ( + t_sva_service_id serviceId +) +{ + t_sva_service_instance_num instanceNum = READ_INSTANCE_NUM_IN_SERVICE_ID(serviceId); + t_sva_sdc_descriptor *pDesc=&stillDecodeDesc[instanceNum]; + t_uint32 i; + t_sva_tm_error tmError; + t_sva_error svaError; + t_sva_sdc_algo_error algoError; + t_sva_error status; + t_sva_mm_error mmError; + t_sva_buffer_id removedBufferId; + t_sva_sdc_block blockDesc; + + /*check for service id validity*/ + status=sva_SDC_CheckServiceId(serviceId); + if (status!=SVA_OK) {return status;} + + /*check that transition is allowed*/ + if (sva_SDC_isTransitionValid(instanceNum,SVA_SDC_CONTROL_DELETE)==FALSE) {return SVA_UNEXPECTED_API_CALL;} + + /*check that flush has been done in all fifos*/ + /* image fifos */ + if (IS_FIFO_EMPTY(pDesc->outputImageFifos.push)==FALSE) {return SVA_INTERNAL_STILL_DECODER_ERROR;} + if (IS_FIFO_EMPTY(pDesc->outputImageFifos.inUse)==FALSE) {return SVA_INTERNAL_STILL_DECODER_ERROR;} + /* bitstream fifo */ + if (IS_FIFO_EMPTY(pDesc->inputBitstreamFifo)==FALSE) {return SVA_INTERNAL_STILL_DECODER_ERROR;} + /* ACE param fifo */ + if (IS_FIFO_EMPTY(pDesc->aceParamFifos.push)==FALSE) {return SVA_INTERNAL_STILL_DECODER_ERROR;} + if (IS_FIFO_EMPTY(pDesc->aceParamFifos.inUse)==FALSE) {return SVA_INTERNAL_STILL_DECODER_ERROR;} + + /*start to delete. Things to do depend of current state*/ + if (pDesc->state==SVA_SDC_WAIT_FOR_ACTIVATE || pDesc->state==SVA_SDC_WAIT_FOR_START) + { + /*check that subtask dependancy fifo is full: no subtask scheduled*/ + //Test fifo full is only relevant when size is even + if (GET_FIFO_NB_ELEMS(pDesc->subtasksDependencyFifo)fakeBitstreamFifo,t_sva_buffer_id,removedBufferId) != SVA_FIFO_EMPTY) + { + svaError=SVA_FreeBuffer(removedBufferId); + if (svaError!=SVA_OK) {return SVA_INTERNAL_STILL_DECODER_ERROR;} + } + + while(POP_FIFO_ELEM(pDesc->windowBufferFifos.push,t_sva_sdc_block,blockDesc) != SVA_FIFO_EMPTY) + { + mmError=sva_MM_FreeBlock(blockDesc.blockId); + if (mmError!=SVA_MM_OK) {return SVA_INTERNAL_STILL_DECODER_ERROR;} + } + while(POP_FIFO_ELEM(pDesc->windowBufferFifos.inUse,t_sva_sdc_block,blockDesc) != SVA_FIFO_EMPTY) + { + mmError=sva_MM_FreeBlock(blockDesc.blockId); + if (mmError!=SVA_MM_OK) {return SVA_INTERNAL_STILL_DECODER_ERROR;} + } + + /*delete output image fifos*/ + DELETE_FIFO(pDesc->outputImageFifos.push); + DELETE_FIFO(pDesc->outputImageFifos.inUse); + /*delete bitstream fifo*/ + DELETE_FIFO(pDesc->inputBitstreamFifo); + /*delete ACE params fifos*/ + DELETE_FIFO(pDesc->aceParamFifos.push); + DELETE_FIFO(pDesc->aceParamFifos.inUse); + + /*delete subtask dependancy fifos*/ + DELETE_FIFO(pDesc->subtasksDependencyFifo); + + /*delete fake bitstream buffer fifos*/ + DELETE_FIFO(pDesc->fakeBitstreamFifo); + + /*delete bitstream window buffer fifos*/ + DELETE_FIFO(pDesc->windowBufferFifos.push); + DELETE_FIFO(pDesc->windowBufferFifos.inUse); + + /*algo specific fifos*/ + algoError=stillDecodeAlgoDesc[pDesc->algo].pDecodeAlgoClose(instanceNum); + HCL_DEBUG_ASSERT(algoError == SVA_SDC_ALGO_OK); + + /*delete subtasklist*/ + tmError=sva_TM_DeleteSubTaskList(pDesc->subtasksListId); + if (tmError!=SVA_TM_OK) {return SVA_INTERNAL_STILL_DECODER_ERROR;} + + /*delete subtasks*/ + for(i=0;isubtasksIdArray[i]); + if (tmError!=SVA_TM_OK) {return SVA_INTERNAL_STILL_DECODER_ERROR;} + } + + /*delete descriptor use by memory management*/ + status=sva_EM_Delete(serviceId); + if (status!=SVA_OK) {return status;} + } + + /*reset instance descriptor*/ + sva_SDC_ResetInstance(serviceId); + + /* Update the state machine */ + sva_SDC_UpdateInstanceStatesMachine(instanceNum,SVA_SDC_CONTROL_DELETE); + + return SVA_OK; +} + + +/****************************************************************************/ +/* NAME: t_sva_error sva_SDC_ResetInstance ( void ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine initialize one service instance of Decode */ +/* 1) Set state of instance to SVA_SERVICE_NOT_INITIALIZED */ +/* 2) init fifos */ +/* */ +/* PARAMETERS: */ +/* IN : none */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/* - always SVA_OK */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PRIVATE void sva_SDC_ResetInstance( + t_sva_service_id serviceId +) +{ + t_sva_service_instance_num i = READ_INSTANCE_NUM_IN_SERVICE_ID(serviceId); + + /*init instance states*/ + stillDecodeDesc[i].state=SVA_SDC_NOT_INITIALIZED; + stillDecodeDesc[i].serviceId=0; + stillDecodeDesc[i].activateState=SVA_SDC_INACTIVE; + /*init fifo use*/ + INIT_FIFO(stillDecodeDesc[i].inputBitstreamFifo); + INIT_FIFO(stillDecodeDesc[i].outputImageFifos.push); + INIT_FIFO(stillDecodeDesc[i].outputImageFifos.inUse); + INIT_FIFO(stillDecodeDesc[i].aceParamFifos.push); + INIT_FIFO(stillDecodeDesc[i].aceParamFifos.inUse); + INIT_FIFO(stillDecodeDesc[i].subtasksDependencyFifo); + INIT_FIFO(stillDecodeDesc[i].fakeBitstreamFifo); + INIT_FIFO(stillDecodeDesc[i].windowBufferFifos.push); + INIT_FIFO(stillDecodeDesc[i].windowBufferFifos.inUse); + + stillDecodeDesc[i].assertEndofStream = FALSE; + stillDecodeDesc[i].stopSliceRequested = FALSE; + stillDecodeDesc[i].fakeBufferAdded = FALSE; + + stillDecodeDesc[i].sdcEowOccured=FALSE; + + /*init others value linked to decoder status*/ + sva_SDC_ResetStatus(&(stillDecodeDesc[i].status)); + + //internal events +} + + +/****************************************************************************/ +/* NAME: t_sva_error sva_SDC_DoReset ( void ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine resets one service instance of Decode */ +/* 2) cleans FIFO */ +/* */ +/* PARAMETERS: */ +/* IN : serviceId */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/* - SVA_OK */ +/* - SVA_INTERNAL_STILL_DECODER_ERROR */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ + +PRIVATE t_sva_error sva_SDC_DoReset( + t_sva_service_id serviceId +) +{ + t_sva_error status = SVA_OK; + t_sva_service_instance_num i = READ_INSTANCE_NUM_IN_SERVICE_ID(serviceId); + + stillDecodeDesc[i].assertEndofStream = FALSE; + stillDecodeDesc[i].stopSliceRequested = FALSE; + stillDecodeDesc[i].fakeBufferAdded = FALSE; + + /* flush all input output FIFOs */ + /* warning: not required, user app. must use specific commands for it */ +// status = sva_SDC_DoFlushIn(serviceId); +// status = sva_SDC_DoFlushOut(serviceId); + + + /*init others value linked to decoder status*/ + sva_SDC_ResetStatus(&(stillDecodeDesc[i].status)); + + return status; +} + + + + +/****************************************************************************/ +/* NAME: t_sva_error sva_SDC_AssertEndOfBitstream( */ +/* t_sva_service_id serviceId */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine allows to signal the end of a bitstream push. This */ +/* function may be used with video or still decoders. The last bitstream */ +/* is pushed using this API. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - serviceId: service identifier */ +/* */ +/* OUT : */ +/* - none */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/* - SVA_UNKNOWN_SERVICE_ID : service id is unknown */ +/* - SVA_INTERNAL_STILL_DECODER_ERROR */ +/* - SVA_UNEXPECTED_API_CALL : API is not supposed to be call in */ +/* service current state. */ +/* accept buffer for the moment. */ +/* - SVA_OK */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ + +PUBLIC t_sva_error sva_SDC_AssertEndOfBitstream( + t_sva_service_id serviceId +) +{ + t_sva_service_instance_num instanceNum = READ_INSTANCE_NUM_IN_SERVICE_ID(serviceId); + t_sva_sdc_descriptor *pDesc=&stillDecodeDesc[instanceNum]; + t_sva_sdc_subtask_dependencies subtaskDep; + t_sva_ff_error ffError; + t_sva_sdc_error sdcError; + + if(pDesc->codecMode == SVA_CODEC_IMAGE_MODE) + return SVA_UNEXPECTED_API_CALL; + + if(pDesc->assertEndofStream == TRUE) + return SVA_UNEXPECTED_API_CALL; + + if(IS_FIFO_EMPTY(pDesc->subtasksDependencyFifo)==FALSE) + { + /*read subtask for which we will try to solve dependencies*/ + ffError=READ_FIFO_ELEM(pDesc->subtasksDependencyFifo,t_sva_sdc_subtask_dependencies,subtaskDep); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + + /* check header info dependancies */ + if(subtaskDep.dependencies.headerInfoDep==RESOLVED_DEPENDENCY && subtaskDep.dependencies.bitstreamBufferDep==NOT_RESOLVED_DEPENDENCY) + { + ffError=UPDATE_FIFO_ELEM_FIELD(pDesc->subtasksDependencyFifo,t_sva_sdc_subtask_dependencies,.dependencies.bitstreamBufferDep,RESOLVED_DEPENDENCY); + if (ffError != SVA_FIFO_OK) {return SVA_INTERNAL_STILL_DECODER_ERROR;} + sdcError = sva_SDC_ResolveDependencies(instanceNum); + if (sdcError != SVA_SDC_OK) {return SVA_INTERNAL_STILL_DECODER_ERROR;} + } + } + + pDesc->assertEndofStream = TRUE; + + return SVA_OK; + } + + + /**************************************************************************/ +/* NAME: t_sva_error SVA_GetStillImageDecoderStatus ( */ +/* t_sva_service_id serviceId, */ +/* t_sva_still_decoder_status * pStatus */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine allows to get status of the Still Decode service */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - serviceId: identifier of the service */ +/* - pStatus: status for the decode service */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/* - SVA_OK : Command taken into account */ +/* - SVA_UNKNOWN_SERVICE_ID : service id is not correct */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + DONE +*/ +PUBLIC t_sva_error SVA_GetStillImageDecoderStatus( + t_sva_service_id serviceId, + t_sva_still_decoder_status * pStatus +) +{ + t_sva_service_instance_num instanceNum = READ_INSTANCE_NUM_IN_SERVICE_ID(serviceId); + t_sva_sdc_descriptor *pDesc=&stillDecodeDesc[instanceNum]; + t_sva_error status; + + /*check for service id validity*/ + status=sva_SDC_CheckServiceId(serviceId); + if (status!=SVA_OK) {return status;} + + /*check pointers*/ + SDC_CHECK_NULL_POINTER(pStatus); + + /*copy status*/ + *pStatus=pDesc->status; + + return SVA_OK; +} + + +/****************************************************************************/ +/* NAME: void sva_SDC_ResetStatus( */ +/* t_sva_still_decoder_status *pStatus */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will reset status descriptor. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - pStatus: status descriptor to reset */ +/* */ +/* OUT: none */ +/* */ +/* RETURN: t_sva_SDC_error */ +/* - SVA_SDC_OK */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + DONE +*/ +PRIVATE void sva_SDC_ResetStatus ( + t_sva_still_decoder_status *pStatus +) +{ + /*check pointers*/ + SDC_CHECK_NULL_POINTER(pStatus); + + pStatus->state = SVA_SERVICE_NOT_INITIALIZED; + pStatus->nbBytesDecoded = 0; + pStatus->nbImagesDecoded = 0; + pStatus->errorId = SVA_STILL_DECODER_NO_ERROR; + //user events + pStatus->eventStats.voidedCounter = 0; + pStatus->eventStats.filledCounter = 0; + pStatus->eventStats.partlyCounter = 0; + pStatus->eventStats.readOnlyCounter = 0; + pStatus->eventStats.underflowCounter = 0; + pStatus->eventStats.overflowCounter = 0; + pStatus->eventStats.errorCounter = 0; + pStatus->bufferizationStats.inLevel = 0; + pStatus->bufferizationStats.outLevel = 0; + +} + + +/****************************************************************************/ +/* NAME: t_sva_error SVA_GetParamsBufferSize( */ +/* t_sva_service_id serviceId, */ +/* t_sva_push_mode mode, */ +/* t_size *pSize */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine returns the size of the params buffer of the conf- */ +/* igured service. */ +/* */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - serviceId: service identifier */ +/* - mode: SVA_PUSH_IN / SVA_PUSH_OUT */ +/* */ +/* OUT : */ +/* - pSize: size of the params buffer */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/* SVA_UNKNOWN_SERVICE_ID */ +/* SVA_OK */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ + +PUBLIC t_sva_error sva_SDC_GetParamsBufferSize(t_sva_service_id serviceId,t_sva_push_mode pushMode,t_size * pSize) +{ + t_sva_service_instance_num instanceNum = READ_INSTANCE_NUM_IN_SERVICE_ID(serviceId); + t_sva_sdc_descriptor *pDesc=&stillDecodeDesc[instanceNum]; + t_sva_sdc_algo_error algoError; + t_sva_error status; + + /*check for service id validity*/ + status=sva_SDC_CheckServiceId(serviceId); + if (status!=SVA_OK) {return status;} + + /*check pointers*/ + SDC_CHECK_NULL_POINTER(pSize); + + algoError = stillDecodeAlgoDesc[pDesc->algo].pGetParamBufferSize(instanceNum, pSize); + HCL_DEBUG_ASSERT(algoError == SVA_SDC_ALGO_OK); + + + return SVA_OK; +} + + --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_decode/sva_still_decode.h @@ -0,0 +1,111 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ + +#ifndef __INC_SVA_STILLDECODE_H +#define __INC_SVA_STILLDECODE_H + + +#include "hcl_defs.h" +#include "sva.h" +#include "svap.h" +#include "sva_service.h" +#include "sva_taskmgt.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* + * Currently, only JPEG is supported + */ +#define SVA_SDC_NUMBER_OF_ALGO_SUPPORTED 1 + +/* + * Define the symbols used to identify the number of still-image decoder service + */ + +typedef struct { + t_sva_bitstream_buffer_pos bitstreamPosition; + t_sva_buffer_id relatedBufferId; +} t_sva_bitstream_desc; + +typedef t_sva_service_instance_num t_sva_still_decoder_instance_num; + + +/* + * Define the symbols used to identify the various errors of the still-image module + */ + +typedef enum { + SVA_SDC_INVALID_TRANSITION, //= SVA_SDC_LAST_ERROR, + SVA_SDC_NO_MORE_AVAILABLE_INSTANCE, + SVA_SDC_INVALID_INSTANCE_NB, + SVA_SDC_INVALID_TASK_ID_NB, + SVA_SDC_NOT_SUPPORTED, + SVA_SDC_INVALID_CONTROL_PARAM, + SVA_SDC_INVALID_PUSH, + SVA_SDC_INVALID_BUFFER_TYPE, + SVA_SDC_INVALID_BUFFER_SIZE, + SVA_SDC_INVALID_CONFIGURATION, + SVA_SDC_UNKNOWN_CMD_ID, + SVA_SDC_UNEXPECTED_HW_EVENT, + SVA_SDC_UNEXPECTED_API_CALL, + SVA_SDC_SYNCHRO_INFO_NOT_AVAILABLE, + SVA_SDC_TI_LINKED_ERROR, + SVA_SDC_BM_LINKED_ERROR, + SVA_SDC_MM_LINKED_ERROR, + SVA_SDC_FF_LINKED_ERROR, + SVA_SDC_TM_LINKED_ERROR, + SVA_SDC_NULL_POINTER_PARAMETER, + SVA_SDC_FIFO_NOT_EMPTY, + SVA_SDC_OK = HCL_OK +} t_sva_sdc_error; + +typedef enum { + SVA_SDC_DECODE_COMPLETE, + SVA_SDC_DECODE_INCOMPLETE, + SVA_SDC_DECODE_NOPROGRESS +} t_sva_sdc_decode_status; + + +/******************************************************************************* +* PUBLIC Functions +*******************************************************************************/ + +PUBLIC t_sva_error sva_SDC_Init(void ); +PUBLIC t_sva_error sva_SDC_Reset(t_sva_service_id ); +PUBLIC t_sva_error sva_SDC_Create(t_sva_service_id * ); +PUBLIC t_sva_error sva_SDC_Control(t_sva_service_id, t_sva_service_cmd_id, t_uint32 ); +PUBLIC t_sva_error sva_SDC_Push(t_sva_service_id, t_sva_buffer_id, t_sva_push_mode, t_sva_buffer_type); +PUBLIC t_sva_error sva_SDC_DispatchVirtualHwEvent(t_sva_tm_virtual_hw_event_id, t_sva_service_id, t_sva_tm_subtask_id, t_uint32, t_uint32, t_uint8, t_sva_event_desc *, t_uint32 * ); +PUBLIC t_sva_error sva_SDC_ProvideInternalNeeds(t_sva_service_id, t_system_address, t_size); +PUBLIC t_sva_error sva_SDC_GetInternalNeeds(t_sva_service_id, t_size * , t_size *); +PUBLIC t_sva_error sva_SDC_Activate(t_sva_service_id, t_sva_service_mode, t_sva_fw_id * ); +PUBLIC t_sva_error sva_SDC_Inactivate(t_sva_service_id ); +PUBLIC t_sva_error sva_SDC_Delete(t_sva_service_id ); +PUBLIC t_sva_error sva_SDC_SetHeaderInfos(t_sva_service_id, t_sva_buffer_id,t_uint32,t_uint32,const t_sva_header_infos *); +PUBLIC t_sva_error sva_SDC_AssertEndOfBitstream(t_sva_service_id); +PUBLIC t_sva_error sva_SDC_GetParamsBufferSize(t_sva_service_id,t_sva_push_mode,t_size *); + +#ifdef __cplusplus +} /* allow C++ to use these headers */ +#endif /* __cplusplus */ + +#endif/* __INC_SVA_STILLDECODE_H */ +/* End of file - sva_still_decode.h */ --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_decode/sva_still_decodep.h @@ -0,0 +1,267 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ + +#ifndef __INC_SVA_STILLDECODEP_H +#define __INC_SVA_STILLDECODEP_H + + +#include "hcl_defs.h" +#include "sva.h" +#include "sva_still_decode.h" +#include "sva_taskmgt.h" +#include "sva_fifo.h" +#include "sva_service.h" +#include "sva_bufferlistmgt.h" + + + +/******************************************************************************/ +/* Constants definitions */ +/******************************************************************************/ + +#ifdef __DEBUG + /* + * Define number of event to log + */ + #define LOG_DEPTH 16 +#endif + + +/* + * Define the number of field inside a still-image decode Subtask descriptor (spec v1.1) + */ +#define STILL_DECODE_FIELD_NUMBER 9 + + +/* + * Define the default memory used to store subtasks descriptors + */ +#define STILL_DECODE_DEFAULT_MEMORY_ID SDRAM_ID + +/* + * Define macro to handle null pointer +*/ +#define SDC_CHECK_NULL_POINTER(pointer) HCL_ASSERT(pointer!=NULL) + + #ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/******************************************************************************/ +/* Types definitions */ +/******************************************************************************/ + + +/* + * Define the various state of a still-image decode instance service + */ +typedef enum { + SVA_SDC_NOT_INITIALIZED, + SVA_SDC_WAIT_FOR_CONFIGURATION, + SVA_SDC_WAIT_FOR_INTERNAL_NEEDS, + SVA_SDC_WAIT_FOR_ACTIVATE, + SVA_SDC_WAIT_FOR_START, + SVA_SDC_FLUSHING_IN, + SVA_SDC_FLUSHING_OUT, + SVA_SDC_WAIT_FOR_DATA, + SVA_SDC_RUNNING, + SVA_SDC_STOP_SLICE_REQUESTED, + SVA_SDC_ABORT_REQUESTED, + SVA_SDC_STOP_REQUESTED, + SVA_SDC_ERROR, + SVA_SDC_TRANSITION_REJECTED, + SVA_SDC_LAST_DUMMY_STATE + +} t_sva_sdc_state; + +/* + * Define the various activate state of a still-image decode instance service + */ +typedef enum { + SVA_SDC_INACTIVE, + SVA_SDC_IN_ACTIVATION, + SVA_SDC_ACTIVE, + SVA_SDC_IN_INACTIVATION, + SVA_SDC_LAST_ACTIVATE_DUMMY_STATE, + SVA_SDC_ACTIVATE_TRANSITION_REJECTED +} t_sva_sdc_activate_state; + +/* + * Define the various transitions of the still-image decode service + */ +typedef enum { + SVA_SDC_CREATE, + SVA_SDC_CONFIGURE, + SVA_SDC_INTERNAL_NEEDS, + SVA_SDC_ACTIVATE, + SVA_SDC_INACTIVATE, + SVA_SDC_CONTROL_START, + SVA_SDC_CONTROL_STOP, + SVA_SDC_STOP_SLICE, + SVA_SDC_CONTROL_ABORT, + SVA_SDC_ALL_DEPENDENCIES_RESOLVED, + SVA_SDC_PUSH, + SVA_SDC_EVENT_EOK, + SVA_SDC_EVENT_FAKE, + SVA_SDC_EVENT_ACTIVE, + SVA_SDC_EVENT_INACTIVE, + SVA_SDC_RESET, + SVA_SDC_CONTROL_DELETE, + SVA_SDC_EVENT_ERROR, + SVA_SDC_FLUSH_IN, + SVA_SDC_FLUSH_OUT, + SVA_SDC_CANCEL, + SVA_SDC_LAST_DUMMY_TRANSITION +} t_sva_sdc_transition; + + + +/* + * Define the symbol used to qualify the state of the dependency + * for a given type of buffer + */ +typedef enum { + INTERNAL_DEPENDENCY, + NOT_RESOLVED_DEPENDENCY, + RESOLVED_DEPENDENCY +} t_sva_sdc_dependencies_state; + +/* + * Define the structure used to manage the subtasks dependency + */ +typedef struct { + t_sva_sdc_dependencies_state bitstreamBufferDep; + t_sva_sdc_dependencies_state outputBufferDep; + t_sva_sdc_dependencies_state headerInfoDep; + t_sva_sdc_dependencies_state paramBufferDep; +} t_sva_sdc_dependencies_desc; + +#define DEFAULT_INTERNAL_DEPENDENCY {INTERNAL_DEPENDENCY, INTERNAL_DEPENDENCY} + + +/* + * Define the structure used to manage the dependencies of each subtasks + */ +typedef struct { + t_sva_tm_subtask_id subtaskId; + t_sva_sdc_dependencies_desc dependencies; +} t_sva_sdc_subtask_dependencies; + +/* + * Define the fifos used to manage the dependency + * The buffers, provided though the Push routine, are buffered inside the pushFifo + * When programming them (using them) into a subtask, then they are considered as used, + * as so pushed inside th inUseFifo + */ +typedef struct { + t_sva_fifo push; + t_sva_fifo inUse; +} t_sva_sdc_fifo_dep; + + +typedef struct { + t_sva_buffer_id bufferId; + t_physical_address bufferAddress; +}t_sva_sdc_buffer_desc; + +/* + * Define the descriptor of a still-image decode service instance + */ +typedef struct { + t_sva_image_desc outImageSize; + t_sva_window_desc crop_window; + t_sva_downsampling_factor downsamplingFactor; + t_sva_sdc_state state; + t_sva_sdc_activate_state activateState; + t_sva_service_id serviceId; + + t_sva_codec_mode codecMode; + t_sva_sv_still_algo algo; + t_sva_tm_subtask_id subtasksIdArray[SUBTASK_DEFAULT_NUMBER]; + t_sva_tm_subtask_list_id subtasksListId; + t_sva_still_decoder_status status; + t_bool no_slice_mode; +// t_sva_still_decoder_internal_event_stats internalEventStatus; + + //dependancy info + t_sva_fifo subtasksDependencyFifo; + t_sva_fifo inputBitstreamFifo; + t_sva_fifo fakeBitstreamFifo; // this is needed because of a hardware constraint + t_sva_sdc_fifo_dep aceParamFifos; + t_sva_sdc_fifo_dep outputImageFifos; + t_sva_sdc_dependencies_desc defaultDep; + + t_sva_sdc_fifo_dep windowBufferFifos; + t_bool assertEndofStream; + t_bool fakeBufferAdded; + t_bool stopSliceRequested; + volatile t_bool sdcEowOccured; + volatile t_sva_tm_subtask_id sdcSubtaskIdEOW; +} t_sva_sdc_descriptor; + + +#ifdef __DEBUG + /******************************************************************************/ + /* Trace Types definitions */ + /******************************************************************************/ + typedef struct { + t_sva_tm_virtual_hw_event_id event; + t_uint32 systemTime; + t_sva_tm_subtask_id subtaskId; + t_sva_service_id serviceId; + t_uint32 startHandlingTime; + t_uint32 stopHandlingTime; + } t_sva_sdc_debug_event_desc; + typedef struct { + t_uint32 padding[3]; + t_uint32 nbOfEventReceived; + t_sva_sdc_debug_event_desc eventDebugDesc[LOG_DEPTH]; + } t_sva_sdc_debug_events; + + typedef struct { + t_sva_service_cmd_id command; + t_uint32 systemTime; + t_uint32 parameter; + t_uint32 padding; + } t_sva_sdc_debug_command_desc; + typedef struct { + t_uint32 padding[3]; + t_uint32 nbOfCommandReceived; + t_sva_sdc_debug_command_desc commandDebugDesc[LOG_DEPTH]; + } t_sva_sdc_debug_commands; + + typedef struct { + t_sva_sdc_state state;/*state before transition occur*/ + t_sva_sdc_transition transition; + t_uint32 systemTime; + t_sva_sdc_activate_state activateState;/*state before transition occur*/ + } t_sva_sdc_debug_transition_desc; + typedef struct { + t_uint32 padding[3]; + t_uint32 nbOfTransitionReceived; + t_sva_sdc_debug_transition_desc transitionDebugDesc[LOG_DEPTH]; + } t_sva_sdc_debug_transitions; +#endif + +#ifdef __cplusplus +} /* allow C++ to use these headers */ +#endif /* __cplusplus */ + +#endif /* __INC_SVA_STILLDECODEP_H */ +/* End of file - sva_still_decodep.h */ --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_encode/jpeg/sva_sec_jpeg.c @@ -0,0 +1,682 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ + +#include "hcl_defs.h" +#include "sva_host_interface.h" +#include "sva_buffermgt.h" +#include "sva_fifo.h" +#include "sva_still_encode.h" + +#include "../sva_sec_algo.h" +#include "sva_sec_jpeg.h" + +#include "sva_sec_jpegp.h" + +/*------------------------------------------------------------------------ + * Global Variables + *----------------------------------------------------------------------*/ +PRIVATE t_sva_sec_jpeg_descriptor jpegStillEncodeDesc[NUM_MAX_JPEG_ENCODE]; + +/*------------------------------------------------------------------------ + * Private functions + *----------------------------------------------------------------------*/ +PRIVATE t_bool sva_SEC_JPEG_CheckConfiguration(t_sva_still_encoder_configuration const *); +PRIVATE t_sva_sec_algo_error sva_SEC_JPEG_ComputeRunLevelBufferSize(t_sva_still_encoder_instance_num, t_uint16, t_uint32*); + + + +/****************************************************************************/ +/* NAME: sva_SEC_JPEG_InitAndConfigure() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: This routine enables to store all statical parameters */ +/* and determine also cachable memory needs for software process*/ +/* PARAMETERS: */ +/* IN : t_sva_still_encoder_instance_num instanceNum */ + +/* OUT : */ +/* */ +/* RETURN: */ +/* t_sva_sec_algo_error */ +/****************************************************************************/ +PUBLIC t_sva_sec_algo_error sva_SEC_JPEG_InitAndConfigure( +t_sva_still_encoder_instance_num instanceNum, +t_sva_still_encoder_configuration const *pConf){ + + HCL_ASSERT(pConf!=NULL); + + + jpegStillEncodeDesc[instanceNum].configuration=*pConf; + jpegStillEncodeDesc[instanceNum].bitstreamSize = 0; + jpegStillEncodeDesc[instanceNum].jpegConfiguration=*((t_sva_still_algo_jpeg_configuration_params *)pConf->pAlgoConfig); + if (sva_SEC_JPEG_CheckConfiguration(pConf)==FALSE) + { + return SVA_SEC_JPEG_PARAM_ERROR; + } + + + if (jpegStillEncodeDesc[instanceNum].jpegConfiguration.rotation != SVA_JPEG_ENCODE_ROTATION_NONE && pConf->transformId != SVA_ENCODER_JPEG_420_MB) + { + return SVA_SEC_JPEG_PARAM_ERROR; + } + + + return SVA_SEC_ALGO_OK; + +} + + +/****************************************************************************/ +/* NAME: sva_SEC_JPEG_MemoryNeeds() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: This routine enables to store all statical parameters */ +/* and determine also cachable memory needs for software process*/ +/* PARAMETERS: */ +/* IN : t_sva_still_encoder_instance_num instanceNum */ +/* t_sva_still_encoder_configuration */ +/* t_sva_image_desc imageDesc */ +/* t_sva_codec_algo_configuration_params *confParams */ +/* OUT :t_size *pMemNeeds */ +/* */ +/* RETURN: */ +/* t_sva_sec_algo_error */ +/****************************************************************************/ + +PUBLIC t_sva_sec_algo_error sva_SEC_JPEG_GetMemoryNeeds( +t_sva_still_encoder_instance_num instanceNum, +t_size *pMemNeeds) +{ + + HCL_ASSERT(pMemNeeds != 0); + *pMemNeeds = 0; + + return SVA_SEC_ALGO_OK; +} + +/****************************************************************************/ +/* NAME: sva_SEC_JPEG_ProvideMemoryNeeds() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: This routine enables to provide cachable memory needs */ +/* for encode fifos */ +/* PARAMETERS: */ +/* IN : t_sva_still_encoder_instance_num instanceNum */ +/* OUT : */ +/* */ +/* RETURN: */ +/* t_sva_sec_algo_error */ +/****************************************************************************/ + +PUBLIC t_sva_sec_algo_error sva_SEC_JPEG_ProvideMemoryNeeds(t_sva_still_encoder_instance_num instanceNum, const t_sva_tm_subtask_id *pSubtaskIdArray) +{ + + t_sva_mm_error mmError; + t_sva_tm_error tmError; + t_uint32 runLevelBufferSize; + t_sva_sec_algo_error algoError; + t_uint32 i; + t_physical_address bufferAddr; + t_sva_vec_internal_buffer internalBuffer; + + HCL_ASSERT(pSubtaskIdArray!=0); + + /* Alloc block RunLevelBuffer */ + algoError = sva_SEC_JPEG_ComputeRunLevelBufferSize(instanceNum, jpegStillEncodeDesc[instanceNum].configuration.transformId, &runLevelBufferSize); + if (algoError != SVA_SEC_ALGO_OK) {return SVA_SEC_JPEG_PARAM_ERROR;} + mmError=sva_MM_AllocBlock(SDRAM_ID,runLevelBufferSize,SVA_MM_ALIGN_WORD, &jpegStillEncodeDesc[instanceNum].runLevelBufferBlockId); + if ((mmError != SVA_MM_OK)&&(mmError!=SVA_MM_SIZE_INCOMPATIBLE)) {return(SVA_SEC_JPEG_PARAM_ERROR);} + + if(runLevelBufferSize != 0) + { + + mmError = sva_MM_GetBlockPhysicalAddress(jpegStillEncodeDesc[instanceNum].runLevelBufferBlockId, &bufferAddr); + if (mmError != SVA_MM_OK) {return(SVA_SEC_JPEG_PARAM_ERROR);} + + internalBuffer.addr_jpeg_run_level_buffer = bufferAddr; + for(i=0; iframe_width=pDesc->configuration.sourceFrameDesc.frame.width; + jpegParamIn->frame_height=pDesc->configuration.sourceFrameDesc.frame.height; + jpegParamIn->window_width=pDesc->configuration.sourceFrameDesc.window.image.width; + jpegParamIn->window_height=pDesc->configuration.sourceFrameDesc.window.image.height; + jpegParamIn->window_horizontal_offset=pDesc->configuration.sourceFrameDesc.window.imageOffset.offsetX; + jpegParamIn->window_vertical_offset=pDesc->configuration.sourceFrameDesc.window.imageOffset.offsetY; + + jpegParamIn->restart_interval=pDesc->jpegConfiguration.restartInterval; + + for (i=0; i<64; i++) { + jpegParamIn->quant_luma[i] = pDesc->jpegConfiguration.quantizationTable.quant_y[i]; + jpegParamIn->quant_chroma[i] = pDesc->jpegConfiguration.quantizationTable.quant_cb[i]; + } + for (i=0; i<12; i++) { + jpegParamIn->huffman_luma_code_dc[i]=pDesc->jpegConfiguration.huffmanTable.huffmanYCodeDc[i]; + jpegParamIn->huffman_luma_size_dc[i]=pDesc->jpegConfiguration.huffmanTable.huffmanYSizeDc[i]; + jpegParamIn->huffman_chroma_code_dc[i]=pDesc->jpegConfiguration.huffmanTable.huffmanCbCodeDc[i]; + jpegParamIn->huffman_chroma_size_dc[i]=pDesc->jpegConfiguration.huffmanTable.huffmanCbSizeDc[i]; + } + for (i=0; i<256; i++) { + jpegParamIn->huffman_luma_code_ac[i]=pDesc->jpegConfiguration.huffmanTable.huffmanYCodeAc[i]; + jpegParamIn->huffman_luma_size_ac[i]=pDesc->jpegConfiguration.huffmanTable.huffmanYSizeAc[i]; + jpegParamIn->huffman_chroma_code_ac[i]=pDesc->jpegConfiguration.huffmanTable.huffmanCbCodeAc[i]; + jpegParamIn->huffman_chroma_size_ac[i]=pDesc->jpegConfiguration.huffmanTable.huffmanCbSizeAc[i]; + } + if (pDesc->configuration.isSliceMode == TRUE) + jpegParamIn->last_slice = 0; + else + jpegParamIn->last_slice = 1; + + + jpegParamIn->sampling_mode = (t_uint16)pDesc->configuration.transformId; + + jpegParamIn->enable_optimized_quant = (t_uint16)pDesc->jpegConfiguration.isOptimizeQuantTableEnable; + jpegParamIn->target_bpp = (t_uint16)pDesc->jpegConfiguration.targetBpp; + jpegParamIn->enable_optimized_huffman=(t_uint16)pDesc->jpegConfiguration.isOptimizeHuffmanTableEnable; + jpegParamIn->rotation=(t_uint16)pDesc->jpegConfiguration.rotation; + + + return SVA_SEC_ALGO_OK; +} + +/****************************************************************************/ +/* NAME: sva_SEC_JPEG_GetFrameParamInOut() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: This routine provides t_sva_vec_jpeg_param_inout data */ +/* that will be used by encode module to update inout_param fields*/ +/* PARAMETERS: */ +/* IN : t_sva_still_encoder_instance_num instanceNum) */ +/* OUT :t_sva_sec_algo_params_inout *algoParamsInOut */ +/* t_bool *pIsUpdateSubTaskNeed */ +/* */ +/* RETURN: */ +/* t_sva_sec_algo_error */ +/****************************************************************************/ + +PUBLIC t_sva_sec_algo_error sva_SEC_JPEG_GetFrameParamInOut( +t_sva_still_encoder_instance_num instanceNum, +t_sva_sec_algo_params_inout *algoParamsInOut +) +{ + + t_sva_sec_jpeg_descriptor *pDesc=&jpegStillEncodeDesc[instanceNum]; + t_sva_vec_jpeg_param_inout *jpegParamInOut; + HCL_ASSERT(algoParamsInOut != 0); + + + jpegParamInOut =(t_sva_vec_jpeg_param_inout *) algoParamsInOut; + + + + // Start Values + jpegParamInOut->restart_mcu_count = pDesc->jpegConfiguration.restartInterval; //0; + jpegParamInOut->dc_predictor_y = 0; + jpegParamInOut->dc_predictor_cb =0; + jpegParamInOut->dc_predictor_cr=0; + jpegParamInOut->restart_marker_id=0; + jpegParamInOut->reserved_1=0; + jpegParamInOut->reserved_2=0; + + + + return SVA_SEC_ALGO_OK; +} + +/****************************************************************************/ +/* NAME: sva_SEC_JPEG_SetFrameParamOut() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: This routine provides t_sva_vec_jpeg_param_out data */ +/* that will be used by encode module to update out_param fields*/ +/* PARAMETERS: */ +/* IN : t_sva_still_encoder_instance_num instanceNum) */ +/* OUT :t_sva_sec_algo_params_inout *algoParamsOut */ +/* t_bool *pIsUpdateSubTaskNeed */ +/* */ +/* RETURN: */ +/* t_sva_sec_algo_error */ +/****************************************************************************/ + +PUBLIC t_sva_sec_algo_error sva_SEC_JPEG_SetFrameParamOut( +t_sva_still_encoder_instance_num instanceNum, +const t_sva_sec_algo_params_out *algoParamsOut +) +{ + t_sva_sec_jpeg_descriptor *pDesc=&jpegStillEncodeDesc[instanceNum]; + t_sva_vec_jpeg_param_out *jpegParamOut; + + + HCL_ASSERT(algoParamsOut!=0); + + jpegParamOut=(t_sva_vec_jpeg_param_out *) algoParamsOut; + pDesc->bitstreamSize =jpegParamOut->bitstream_size; + + return SVA_SEC_ALGO_OK; +} + + +/****************************************************************************/ +/* NAME: sva_SEC_JPEG_GetBitstreamSize() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: This routine enables user to know the size encoded bitstream */ +/* */ +/* PARAMETERS: */ +/* IN : t_sva_still_encoder_instance_num instanceNum */ +/* OUT : */ +/* */ +/* RETURN: */ +/* size in byte */ +/****************************************************************************/ +PUBLIC t_uint32 sva_SEC_JPEG_GetBitstreamSize(t_sva_still_encoder_instance_num instanceNum) { + t_sva_sec_jpeg_descriptor *pDesc=&jpegStillEncodeDesc[instanceNum]; + return (pDesc->bitstreamSize ); +} + +/****************************************************************************/ +/* NAME: sva_SEC_JPEG_ResetBitstreamSize() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: This routine enables user to know the size encoded bitstream */ +/* */ +/* PARAMETERS: */ +/* IN : t_sva_still_encoder_instance_num instanceNum */ +/* OUT : */ +/* */ +/* RETURN: */ +/* size in byte */ +/****************************************************************************/ +PUBLIC t_uint32 sva_SEC_JPEG_ResetBitstreamSize(t_sva_still_encoder_instance_num instanceNum) { + t_sva_sec_jpeg_descriptor *pDesc=&jpegStillEncodeDesc[instanceNum]; + pDesc->bitstreamSize =0; + return 1; +} + + +/****************************************************************************/ +/* NAME: sva_SEC_JPEG_GetParamsInSize() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: This routine enables user to know the size of Paramin */ +/* structure: depends on algo used (and FW release) */ +/* PARAMETERS: */ +/* IN : t_sva_still_encoder_instance_num instanceNum */ +/* OUT : */ +/* */ +/* RETURN: */ +/* size in byte */ +/****************************************************************************/ + +PUBLIC t_size sva_SEC_JPEG_GetParamsInSize(t_sva_still_encoder_instance_num instanceNum) +{ + (void) instanceNum;/*discard instanceNum*/ + return(sizeof(t_sva_vec_jpeg_param_in)); +} + +/****************************************************************************/ +/* NAME: sva_SEC_JPEG_GetParamsInOutSize() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: This routine enables user to know the size of Paraminout */ +/* structure: depends on algo used (and FW release) */ +/* PARAMETERS: */ +/* IN : t_sva_still_encoder_instance_num instanceNum */ +/* OUT : */ +/* */ +/* RETURN: */ +/* size in byte */ +/****************************************************************************/ + +PUBLIC t_size sva_SEC_JPEG_GetParamsInOutSize(t_sva_still_encoder_instance_num instanceNum) +{ + (void) instanceNum;/*discard instanceNum*/ + return(sizeof(t_sva_vec_jpeg_param_inout)); +} + +/****************************************************************************/ +/* NAME: sva_SEC_JPEG_GetParamsOutSize() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: This routine enables user to know the size of Paramout */ +/* structure: depends on algo used (and FW release) */ +/* PARAMETERS: */ +/* IN : t_sva_still_encoder_instance_num instanceNum */ +/* OUT : */ +/* */ +/* RETURN: */ +/* size in byte */ +/****************************************************************************/ + +PUBLIC t_size sva_SEC_JPEG_GetParamsOutSize(t_sva_still_encoder_instance_num instanceNum) +{ + (void) instanceNum;/*discard instanceNum*/ + return(sizeof(t_sva_vec_jpeg_param_out)); +} + + +/****************************************************************************/ +/* NAME: sva_SEC_JPEG_GetLastSliceOffsetAndSize() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* */ +/* PARAMETERS: */ +/* IN : t_sva_still_encoder_instance_num instanceNum */ +/* OUT : */ +/* */ +/* RETURN: */ +/* */ +/****************************************************************************/ + +PUBLIC t_size sva_SEC_JPEG_GetLastSliceOffsetAndSize(t_sva_still_encoder_instance_num instanceNum, t_uint32* pOffset) +{ + t_sva_vec_jpeg_param_in unused; + + (void) instanceNum;/*discard instanceNum*/ + + *pOffset = (&(unused.last_slice) - &(unused.frame_width) ); + return (sizeof(unused.last_slice)); +} + + +/****************************************************************************/ +/* NAME: sva_SEC_JPEG_FlushFifos() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: This routine enables to flush fifos */ +/* PARAMETERS: */ +/* IN : t_sva_still_encoder_instance_num instanceNum */ +/* OUT : */ +/* */ +/* RETURN: */ +/* t_sva_sec_algo_error */ +/****************************************************************************/ + +PUBLIC t_sva_sec_algo_error sva_SEC_JPEG_FlushFifos(t_sva_still_encoder_instance_num instanceNum) +{ +return SVA_SEC_ALGO_OK; +} + +/****************************************************************************/ +/* NAME: sva_SEC_JPEG_Control() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: This routine enables to control algo box. command could be */ +/* dispatch to brc box. */ +/* PARAMETERS: */ +/* IN : - t_sva_still_encoder_instance_num instanceNum */ +/* - t_sva_sec_algo_control jpegCmd */ +/* - t_uint32 param */ +/* OUT : */ +/* */ +/* RETURN: */ +/* t_sva_sec_algo_error */ +/****************************************************************************/ + +PUBLIC t_sva_sec_algo_error sva_SEC_JPEG_Control( +t_sva_still_encoder_instance_num instanceNum, +t_sva_sec_algo_control jpegCmd, +t_uint32 param +) +{ + return SVA_SEC_JPEG_CMD_NOT_SUPPORTED; +} + +/****************************************************************************/ +/* NAME: t_bool sva_SEC_JPEG_CheckConfiguration( */ +/* const t_sva_still_algo_jpeg_configuration_params *pConf) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will check that configuration given to jpeg is valid */ +/* and coherent. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - pConf: a pointer to the configuration to check */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: t_bool */ +/****************************************************************************/ + +PRIVATE t_bool sva_SEC_JPEG_CheckConfiguration +( + t_sva_still_encoder_configuration const *pConf +) +{ + t_uint16 i; + t_sva_still_algo_jpeg_configuration_params *pJpConf; + + pJpConf=(t_sva_still_algo_jpeg_configuration_params *)pConf->pAlgoConfig; + + /*check first general config limit by algo*/ + /*t_sva_windowed_frame_desc sourceFrameDesc*/ + CHECK_ALIGNMENT(pConf->sourceFrameDesc.frame.height,16); + CHECK_RANGE(pConf->sourceFrameDesc.frame.height, 16, 4080); + CHECK_ALIGNMENT(pConf->sourceFrameDesc.frame.width,16); + CHECK_RANGE(pConf->sourceFrameDesc.frame.width, 16, 4080); + + if(pConf->transformId == SVA_ENCODER_JPEG_MONOCHROME|| pConf->transformId == SVA_ENCODER_JPEG_444_SEP_COMP_MB) + { + CHECK_ALIGNMENT(pConf->sourceFrameDesc.window.image.width,8); + } + else /* 4.2.0 or 4.2.2 formats */ + { + CHECK_RANGE(pConf->sourceFrameDesc.window.image.width, 16, pConf->sourceFrameDesc.frame.width); + CHECK_ALIGNMENT(pConf->sourceFrameDesc.window.image.width,16); + } + + if(pConf->transformId == SVA_ENCODER_JPEG_420_SEP_COMP_MB|| pConf->transformId == SVA_ENCODER_JPEG_420_MB) + { + CHECK_RANGE(pConf->sourceFrameDesc.window.image.height, 16, pConf->sourceFrameDesc.frame.height); + CHECK_ALIGNMENT(pConf->sourceFrameDesc.window.image.height,16); + } + else /* Y only, 4.4.4 or 4.2.2 formats */ + { + + CHECK_ALIGNMENT(pConf->sourceFrameDesc.window.image.height,8); + } + CHECK_RANGE(pConf->sourceFrameDesc.window.image.height, 8, pConf->sourceFrameDesc.frame.height); + CHECK_RANGE(pConf->sourceFrameDesc.window.image.width, 8, pConf->sourceFrameDesc.frame.width); + CHECK_ALIGNMENT(pConf->sourceFrameDesc.window.imageOffset.offsetX,8); + CHECK_RANGE0(pConf->sourceFrameDesc.window.imageOffset.offsetX, 0, pConf->sourceFrameDesc.frame.width-pConf->sourceFrameDesc.window.image.width); + CHECK_ALIGNMENT(pConf->sourceFrameDesc.window.imageOffset.offsetY,8); + CHECK_RANGE0(pConf->sourceFrameDesc.window.imageOffset.offsetY, 0, pConf->sourceFrameDesc.frame.height-pConf->sourceFrameDesc.window.image.height); + + /*Check Huffman size table. It is not used if enable_optimized_huffman=1.*/ + /* WARNING: encoder use only one chroma table (here cb)*/ + if(pJpConf->isOptimizeHuffmanTableEnable!=TRUE) + { + for (i=0; i<12; i++) + { + CHECK_RANGE0(pJpConf->huffmanTable.huffmanYSizeDc[i], 0, 16); + CHECK_RANGE0(pJpConf->huffmanTable.huffmanCbSizeDc[i], 0, 16); + } + for (i=0; i<256; i++) + { + CHECK_RANGE0(pJpConf->huffmanTable.huffmanYSizeAc[i], 0, 16); + CHECK_RANGE0(pJpConf->huffmanTable.huffmanCbSizeAc[i], 0, 16); + } + } + /* check quantization table value */ + if(pJpConf->isOptimizeQuantTableEnable != TRUE) + { + for (i=0; i<64; i++) + { + CHECK_RANGE(pJpConf->quantizationTable.quant_y[i], 1, 255); + CHECK_RANGE(pJpConf->quantizationTable.quant_cb[i], 1, 255); + } + } + + return TRUE; +} + + + +/****************************************************************************/ +/* NAME: t_sva_sec_algo_error sva_SEC_ComputeRunLevelBufferSize( */ +/* t_uint16 samplingMode, t_uint32* pSize) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* */ +/* PARAMETERS: */ +/* IN : */ + +/* */ +/* OUT : none */ +/* */ +/* RETURN: t_bool */ +/****************************************************************************/ +PRIVATE t_sva_sec_algo_error sva_SEC_JPEG_ComputeRunLevelBufferSize(t_sva_still_encoder_instance_num instanceNum, t_uint16 samplingMode, t_uint32* pSize) { + t_sva_sec_jpeg_descriptor *pDesc=&jpegStillEncodeDesc[instanceNum]; + t_uint16 height = pDesc->configuration.sourceFrameDesc.frame.height; + t_uint16 width = pDesc->configuration.sourceFrameDesc.frame.width; + + HCL_ASSERT(pSize != 0); + + if((pDesc->configuration.thumbnailMode == SVA_THUMBNAIL_DC_420MB)&&(samplingMode == 4)) + { + height = pDesc->configuration.sourceFrameDesc.window.image.height; + width = pDesc->configuration.sourceFrameDesc.window.image.width; + *pSize = (((width/8)+15)&0xFFF0)*(((height/8)+15)&0xFFF0)*3/2; + } + else if(pDesc->configuration.thumbnailMode == SVA_NON_THUMBNAIL) + { + //if((height > 288)||(width>352)) + //{ + + height = 32; + //} + + + switch (samplingMode) { + case 0: // MONOCHROME + *pSize = width * height * 4 ; + break; + case 1: // 420 MB SEP + *pSize = width * height * 3 * 2; + break; + case 2: // 422 MB SEP + *pSize = width * height * 4 * 2; + break; + case 3: // 444 MB SEP + *pSize = width * height * 4 * 3; + break; + case 4: // 420 MB + *pSize = 0; + break; + default: + *pSize = 0; + return SVA_SEC_JPEG_PARAM_ERROR; + + } + } + + return SVA_SEC_ALGO_OK; +} + + +/****************************************************************************/ +/* NAME: t_sva_sec_algo_error sva_SEC_JPEG_ChoseFirmwareFeature( */ +/* t_sva_sv_algo algo, t_uint32* fwFeat) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* */ +/* PARAMETERS: */ +/* IN : */ + +/* */ +/* OUT : none */ +/* */ +/* RETURN: t_bool */ +/****************************************************************************/ +PUBLIC t_sva_sec_algo_error sva_SEC_JPEG_ChoseFirmwareFeature(t_sva_sv_still_algo algo, t_uint32* fwFeat) { + + HCL_ASSERT(fwFeat != 0); + + switch(algo) { + case SVA_SV_JPEG_ALGO: + *fwFeat = SVA_FW_FEAT_JPEG_ENCODER; + break; + default: + return SVA_SEC_JPEG_PARAM_ERROR; + } + return SVA_SEC_ALGO_OK; +} + + +/* End of file - sva_sec_jpeg.c */ + --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_encode/jpeg/sva_sec_jpeg.h @@ -0,0 +1,63 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ + +#ifndef __INC_SVA_SEC_JPEG_H +#define __INC_SVA_SEC_JPEG_H + +#include "hcl_defs.h" +#include "sva_still_encode.h" +#include "../sva_sec_algo.h" +#include "sva.h" + +/******************************************************************************/ +/* Constants definitions */ +/******************************************************************************/ + + +/******************************************************************************/ +/* Types definitions */ +/******************************************************************************/ + + +/******************************************************************************/ +/* PUBLIC Functions */ +/******************************************************************************/ +PUBLIC t_sva_sec_algo_error sva_SEC_JPEG_InitAndConfigure(t_sva_still_encoder_instance_num,const t_sva_still_encoder_configuration *); +PUBLIC t_sva_sec_algo_error sva_SEC_JPEG_GetMemoryNeeds(t_sva_still_encoder_instance_num,t_size *); +PUBLIC t_sva_sec_algo_error sva_SEC_JPEG_ProvideMemoryNeeds(t_sva_still_encoder_instance_num, const t_sva_tm_subtask_id * ); +PUBLIC t_sva_sec_algo_error sva_SEC_JPEG_GetFrameParamIn(t_sva_still_encoder_instance_num, t_sva_sec_algo_params_in *); +PUBLIC t_sva_sec_algo_error sva_SEC_JPEG_GetFrameParamInOut(t_sva_still_encoder_instance_num,t_sva_sec_algo_params_inout *); +PUBLIC t_sva_sec_algo_error sva_SEC_JPEG_SetFrameParamOut(t_sva_still_encoder_instance_num,const t_sva_sec_algo_params_out *); +PUBLIC t_size sva_SEC_JPEG_GetParamsInSize(t_sva_still_encoder_instance_num); +PUBLIC t_size sva_SEC_JPEG_GetParamsInOutSize(t_sva_still_encoder_instance_num); +PUBLIC t_size sva_SEC_JPEG_GetParamsOutSize(t_sva_still_encoder_instance_num); +PUBLIC t_sva_sec_algo_error sva_SEC_JPEG_FlushFifos(t_sva_still_encoder_instance_num); +PUBLIC t_sva_sec_algo_error sva_SEC_JPEG_Control(t_sva_still_encoder_instance_num, t_sva_sec_algo_control, t_uint32); +PUBLIC t_sva_sec_algo_error sva_SEC_JPEG_Delete(t_sva_still_encoder_instance_num); +PUBLIC t_sva_sec_algo_error sva_SEC_JPEG_ChoseFirmwareFeature(t_sva_sv_still_algo, t_uint32*); +PUBLIC t_uint32 sva_SEC_JPEG_GetBitstreamSize(t_sva_still_encoder_instance_num); +PUBLIC t_size sva_SEC_JPEG_GetLastSliceOffsetAndSize(t_sva_still_encoder_instance_num, t_uint32*); +PUBLIC t_uint32 sva_SEC_JPEG_ResetBitstreamSize(t_sva_still_encoder_instance_num ) ; + +#ifdef __cplusplus +} /* allow C++ to use these headers */ +#endif /* __cplusplus */ + +#endif /* __INC_SVA_SEC_JPEG_H */ +/* End of file - sva_sec_jpeg.h */ --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_encode/jpeg/sva_sec_jpegp.h @@ -0,0 +1,62 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ + +#ifndef __INC_SVA_SEC_JPEGP_H +#define __INC_SVA_SEC_JPEGP_H + +#include "hcl_defs.h" +#include "sva_still_encode.h" +#include "../sva_sec_algo.h" +#include "sva.h" + +/******************************************************************************/ +/* Constants definitions */ +/******************************************************************************/ +/* + * Define the maximum number of jpeg encode structure to maintain + */ +#define NUM_MAX_JPEG_ENCODE 4 + + + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ +/******************************************************************************/ +/* Types definitions */ +/******************************************************************************/ + + +/* + * Define the descriptor of a mp4 encode instance + */ +typedef struct { + t_sva_still_encoder_configuration configuration; + t_sva_still_algo_jpeg_configuration_params jpegConfiguration; + t_uint32 imageNb; + t_uint32 bitstreamSize; + t_sva_block_id runLevelBufferBlockId; +} t_sva_sec_jpeg_descriptor; + +#ifdef __cplusplus +} /* allow C++ to use these headers */ +#endif /* __cplusplus */ + +#endif /* __INC_SVA_SEC_JPEGP_H */ +/* End of file - sva_sec_jpegp.h */ --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_encode/sva_sec_algo.h @@ -0,0 +1,152 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ + +#ifndef __INC_SVA_SEC_ALGO_H +#define __INC_SVA_SEC_ALGO_H + +#include "hcl_defs.h" +#include "sva.h" +#include "sva_still_encode.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/******************************************************************************/ +/* Constants definitions */ +/******************************************************************************/ +/* + * define Size and source format for various image type + * needed by jpeg ... +*/ + + +/******************************************************************************/ +/* Types definitions */ +/******************************************************************************/ +typedef struct { + t_sva_timestamp pts; +} t_sva_sec_algo_image_info; + +typedef enum { + SVA_SEC_JPEG_PARAM_ERROR = SVA_SEC_JPEG_LAST_ERROR, + SVA_SEC_JPEG_CMD_NOT_SUPPORTED, + SVA_SEC_ALGO_OK = HCL_OK +} t_sva_sec_algo_error; + +typedef enum { + SVA_SEC_ALGO_REQUEST_INTRA_CODING +} t_sva_sec_algo_control; + + +typedef void t_sva_sec_algo_configuration_params; +typedef void t_sva_sec_algo_params_in; +typedef void t_sva_sec_algo_params_inout; +typedef void t_sva_sec_algo_params_out; +typedef void t_sva_sec_algo_status; + + +typedef struct{ + +/* + * + * Allows to init and configure a given encoder + */ +t_sva_sec_algo_error (*pInitAndConfigure) (t_sva_still_encoder_instance_num, const t_sva_still_encoder_configuration * ); + +/* + * Allows to set the static parameter of a given encoder + */ +t_sva_sec_algo_error (*pGetMemoryNeeds) (t_sva_still_encoder_instance_num,t_size *); + +/* + * + * Allows to get the internal decode module memory needs of a given encoder + */ +t_sva_sec_algo_error (*pProvideMemoryNeeds) (t_sva_still_encoder_instance_num, const t_sva_tm_subtask_id *); + + +/* + * Shall be call to fill paramin structure + */ +t_sva_sec_algo_error (*pGetFrameParamIn) (t_sva_still_encoder_instance_num, t_sva_sec_algo_params_in *); + +/* + * Shall be call to fill paraminout structure + * t_sva_sec_algo_params_inout structure in subtask or not. + */ +t_sva_sec_algo_error (*pGetFrameParamInOut) (t_sva_still_encoder_instance_num,t_sva_sec_algo_params_inout *); + + +/* + * Shall be call to fill paramout structure + * t_sva_sec_algo_params_out structure in subtask or not. + */ +t_sva_sec_algo_error (*pSetFrameParamOut) (t_sva_still_encoder_instance_num,const t_sva_sec_algo_params_out *); + + +/* + * functions to know size of param in/inout/out. all are static, so call them once +*/ +t_size (*pGetParamsInSize) (t_sva_still_encoder_instance_num); +t_size (*pGetParamsInOutSize) (t_sva_still_encoder_instance_num); +t_size (*pGetParamsOutSize) (t_sva_still_encoder_instance_num); + + +/* + * This function enables to flush algo specific fifos + * It is used when end of stream is detected. + */ +t_sva_sec_algo_error (*pFlushFifos) (t_sva_still_encoder_instance_num); + +/* + * This function allow to control algo box. Some control will be perform directly in + * algo box, some others will be perform by brc box. + */ +t_sva_sec_algo_error (*pControl) (t_sva_still_encoder_instance_num, t_sva_sec_algo_control, t_uint32); + +/* + * Shall be called at close step + * Allows to unallocate any fifos of a given encoder + */ +t_sva_sec_algo_error (*pDelete) (t_sva_still_encoder_instance_num); + +/* + * Shall be called at close step + * Allows to unallocate any fifos of a given encoder + */ +t_sva_sec_algo_error (*pChoseFirmwareFeature) (t_sva_sv_still_algo, t_uint32*); + +t_uint32 (*pGetBitstreamSize)(t_sva_still_encoder_instance_num); + + +t_size (*pGetLastSliceOffsetAndSize)(t_sva_still_encoder_instance_num, t_uint32*); + +t_uint32 (*pResetBitstreamSize)(t_sva_still_encoder_instance_num); + + + +} t_sva_algo_still_encode_fct_array; + +#ifdef __cplusplus +} /* allow C++ to use these headers */ +#endif /* __cplusplus */ + +#endif /* __INC_SVA_SEC_ALGO_H */ +/* End of file - sva_sec_algo.h */ --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_encode/sva_still_encode.c @@ -0,0 +1,3752 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ + +/*------------------------------------------------------------------------ + * Includes + *----------------------------------------------------------------------*/ +#include "hcl_defs.h" +#include "sva.h" +#include "sva_still_encode.h" +#include "sva_still_encodep.h" +#include "sva_buffermgt.h" +#include "sva_eventmgt.h" +#include "jpeg/sva_sec_jpeg.h" +#include "sva_taskmgtp.h" + +/*------------------------------------------------------------------------ + * Global Variables + *----------------------------------------------------------------------*/ + +PRIVATE t_sva_sec_descriptor stillEncodeDesc[NUM_MAX_STILL_ENCODE]; + +PRIVATE const t_sva_tm_field_ctrl_desc defaultStillEncodeFieldDescArray[SVA_SEC_NUMBER_OF_ALGO_SUPPORTED][STILL_ENCODE_FIELD_NUMBER]={ + { + { SVA_TM_DCMD_ALLOCATE, {{sizeof(t_sva_vec_frame_buffer_in), STILL_ENCODE_DEFAULT_INFOS_MEMORY_ID}}}, + { SVA_TM_DCMD_ALLOCATE, {{sizeof(t_sva_vec_frame_buffer_out), STILL_ENCODE_DEFAULT_INFOS_MEMORY_ID}}}, + { SVA_TM_DCMD_ALLOCATE, {{sizeof(t_sva_vec_internal_buffer), STILL_ENCODE_DEFAULT_INFOS_MEMORY_ID}}}, + { SVA_TM_DCMD_ALLOCATE, {{sizeof(t_sva_header_buf), STILL_ENCODE_DEFAULT_INFOS_MEMORY_ID}}}, + { SVA_TM_DCMD_ALLOCATE, {{sizeof(t_sva_bitstream_buffer_pos), STILL_ENCODE_DEFAULT_INFOS_MEMORY_ID}}}, + { SVA_TM_DCMD_ALLOCATE, {{sizeof(t_sva_bitstream_buffer_pos), STILL_ENCODE_DEFAULT_INFOS_MEMORY_ID}}}, + { SVA_TM_DCMD_ALLOCATE, {{sizeof(t_sva_vec_jpeg_param_in), STILL_ENCODE_DEFAULT_INFOS_MEMORY_ID}}}, + { SVA_TM_DCMD_ALLOCATE, {{sizeof(t_sva_vec_jpeg_param_out), STILL_ENCODE_DEFAULT_INFOS_MEMORY_ID}}}, + { SVA_TM_DCMD_ALLOCATE, {{sizeof(t_sva_vec_jpeg_param_inout), STILL_ENCODE_DEFAULT_INFOS_MEMORY_ID}}}, + { SVA_TM_DCMD_ALLOCATE, {{sizeof(t_sva_vec_jpeg_param_inout), STILL_ENCODE_DEFAULT_INFOS_MEMORY_ID}}} + } + +}; + + +PRIVATE t_sva_algo_still_encode_fct_array stillEncodeAlgoDesc[SVA_SEC_NUMBER_OF_ALGO_SUPPORTED]={ +//JPEG +{ + sva_SEC_JPEG_InitAndConfigure, + sva_SEC_JPEG_GetMemoryNeeds, + sva_SEC_JPEG_ProvideMemoryNeeds, + sva_SEC_JPEG_GetFrameParamIn, + sva_SEC_JPEG_GetFrameParamInOut, + sva_SEC_JPEG_SetFrameParamOut, + sva_SEC_JPEG_GetParamsInSize, + sva_SEC_JPEG_GetParamsInOutSize, + sva_SEC_JPEG_GetParamsOutSize, + sva_SEC_JPEG_FlushFifos, + sva_SEC_JPEG_Control, + sva_SEC_JPEG_Delete, + sva_SEC_JPEG_ChoseFirmwareFeature, + sva_SEC_JPEG_GetBitstreamSize, + sva_SEC_JPEG_GetLastSliceOffsetAndSize, + sva_SEC_JPEG_ResetBitstreamSize +} +}; + + +/*table that translate still_encode state into service state*/ +PRIVATE const t_sva_service_state stillEncodeState2ServiceState[SVA_SEC_LAST_DUMMY_STATE]= { + SVA_SERVICE_NOT_INITIALIZED, /*SVA_SEC_NOT_INITIALIZED*/ + SVA_SERVICE_WAIT_FOR_CONFIGURATION, /*SVA_SEC_WAIT_FOR_CONFIGURATION*/ + SVA_SERVICE_WAIT_FOR_INTERNAL_NEEDS, /*SVA_SEC_WAIT_FOR_INTERNAL_NEEDS*/ + SVA_SERVICE_WAIT_FOR_ACTIVATE, /*SVA_SEC_WAIT_FOR_ACTIVATE*/ + SVA_SERVICE_WAIT_FOR_START, /*SVA_SEC_WAIT_FOR_START*/ + SVA_SERVICE_FLUSHING, /*SVA_SEC_FLUSHING_IN*/ + SVA_SERVICE_FLUSHING, /*SVA_SEC_FLUSHING_OUT*/ + SVA_SERVICE_WAIT_FOR_DATA, /*SVA_SEC_WAIT_FOR_DATA*/ + SVA_SERVICE_RUNNING, /*SVA_SEC_RUNNING*/ + SVA_SERVICE_ABORT_REQUESTED, /*SVA_SEC_ABORT_REQUESTED*/ + SVA_SERVICE_STOP_REQUESTED, /*SVA_SEC_STOP_REQUESTED*/ + SVA_SERVICE_ERROR, /*SVA_SEC_ERROR*/ + SVA_SERVICE_WAIT_FOR_DATA /*SVA_SEC_WAIT_FOR_DATA_EOW*/ +}; + + +PRIVATE const t_sva_sec_state stateMachine[SVA_SEC_LAST_DUMMY_STATE][SVA_SEC_LAST_DUMMY_TRANSITION]= { + /* Current State = SVA_SEC_NOT_INITIALIZED */ + { + SVA_SEC_WAIT_FOR_CONFIGURATION, /*SVA_SEC_CREATE*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_CONFIGURE*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_INTERNAL_NEEDS*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_ACTIVATE*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_INACTIVATE*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_CONTROL_START*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_CONTROL_STOP*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_CONTROL_ABORT*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_ALL_DEPENDENCIES_RESOLVED*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_PUSH*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_EVENT_EOK*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_EVENT_FAKE*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_EVENT_ACTIVE*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_EVENT_INACTIVE*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_RESET*/ + SVA_SEC_NOT_INITIALIZED, /*SVA_SEC_CONTROL_DELETE*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_EVENT_ERROR*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_FLUSH_IN*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_FLUSH_OUT*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_CANCEL*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_UPDATE_PARAM*/ + SVA_SEC_TRANSITION_REJECTED /*SVA_SEC_EVENT_EOW*/ + + }, + /* Current State = SVA_SERVICE_WAIT_FOR_CONFIGURATION */ + { + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_CREATE*/ + SVA_SEC_WAIT_FOR_INTERNAL_NEEDS, /*SVA_SEC_CONFIGURE*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_INTERNAL_NEEDS*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_ACTIVATE*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_INACTIVATE*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_CONTROL_START*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_CONTROL_STOP*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_CONTROL_ABORT*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_ALL_DEPENDENCIES_RESOLVED*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_PUSH*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_EVENT_EOK*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_EVENT_FAKE*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_EVENT_ACTIVE*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_EVENT_INACTIVE*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_RESET*/ + SVA_SEC_NOT_INITIALIZED, /*SVA_SEC_CONTROL_DELETE*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_EVENT_ERROR*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_FLUSH_IN*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_FLUSH_OUT*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_CANCEL*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_UPDATE_PARAM*/ + SVA_SEC_TRANSITION_REJECTED /*SVA_SEC_EVENT_EOW*/ + + }, + /* Current State = SVA_SERVICE_WAIT_FOR_INTERNAL_NEEDS */ + { + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_CREATE*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_CONFIGURE*/ + SVA_SEC_WAIT_FOR_ACTIVATE, /*SVA_SEC_INTERNAL_NEEDS*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_ACTIVATE*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_INACTIVATE*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_CONTROL_START*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_CONTROL_STOP*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_CONTROL_ABORT*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_ALL_DEPENDENCIES_RESOLVED*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_PUSH*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_EVENT_EOK*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_EVENT_FAKE*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_EVENT_ACTIVE*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_EVENT_INACTIVE*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_RESET*/ + SVA_SEC_NOT_INITIALIZED, /*SVA_SEC_CONTROL_DELETE*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_EVENT_ERROR*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_FLUSH_IN*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_FLUSH_OUT*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_CANCEL*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_UPDATE_PARAM*/ + SVA_SEC_TRANSITION_REJECTED /*SVA_SEC_EVENT_EOW*/ + + }, + /* Current State = SVA_SERVICE_WAIT_FOR_ACTIVATE */ + { + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_CREATE*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_CONFIGURE*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_INTERNAL_NEEDS*/ + SVA_SEC_WAIT_FOR_ACTIVATE, /*SVA_SEC_ACTIVATE*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_INACTIVATE*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_CONTROL_START*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_CONTROL_STOP*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_CONTROL_ABORT*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_ALL_DEPENDENCIES_RESOLVED*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_PUSH*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_EVENT_EOK*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_EVENT_FAKE*/ + SVA_SEC_WAIT_FOR_START, /*SVA_SEC_EVENT_ACTIVE*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_EVENT_INACTIVE*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_RESET*/ + SVA_SEC_NOT_INITIALIZED, /*SVA_SEC_CONTROL_DELETE*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_EVENT_ERROR*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_FLUSH_IN*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_FLUSH_OUT*/ + SVA_SEC_WAIT_FOR_ACTIVATE, /*SVA_SEC_CANCEL*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_UPDATE_PARAM*/ + SVA_SEC_TRANSITION_REJECTED /*SVA_SEC_EVENT_EOW*/ + + }, + /* Current State = SVA_SERVICE_WAIT_FOR_START */ + { + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_CREATE*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_CONFIGURE*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_INTERNAL_NEEDS*/ + SVA_SEC_WAIT_FOR_START, /*SVA_SEC_ACTIVATE*/ + SVA_SEC_WAIT_FOR_START, /*SVA_SEC_INACTIVATE*/ + SVA_SEC_WAIT_FOR_DATA, /*SVA_SEC_CONTROL_START*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_CONTROL_STOP*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_CONTROL_ABORT*/ + SVA_SEC_WAIT_FOR_START, /*SVA_SEC_ALL_DEPENDENCIES_RESOLVED*/ + SVA_SEC_WAIT_FOR_START, /*SVA_SEC_PUSH*/ + SVA_SEC_ERROR, /*SVA_SEC_EVENT_EOK*/ + SVA_SEC_ERROR, /*SVA_SEC_EVENT_FAKE*/ + SVA_SEC_WAIT_FOR_START, /*SVA_SEC_EVENT_ACTIVE*/ + SVA_SEC_WAIT_FOR_START, /*SVA_SEC_EVENT_INACTIVE*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_RESET*/ + SVA_SEC_NOT_INITIALIZED, /*SVA_SEC_CONTROL_DELETE*/ + SVA_SEC_ERROR, /*SVA_SEC_EVENT_ERROR*/ + SVA_SEC_FLUSHING_IN, /*SVA_SEC_FLUSH_IN*/ + SVA_SEC_FLUSHING_OUT, /*SVA_SEC_FLUSH_OUT*/ + SVA_SEC_WAIT_FOR_START, /*SVA_SEC_CANCEL*/ + SVA_SEC_WAIT_FOR_START, /*SVA_SEC_UPDATE_PARAM*/ + SVA_SEC_TRANSITION_REJECTED /*SVA_SEC_EVENT_EOW*/ + + }, + /* Current State = SVA_SEC_FLUSHING_IN */ + { + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_CREATE*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_CONFIGURE*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_INTERNAL_NEEDS*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_ACTIVATE*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_INACTIVATE*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_CONTROL_START*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_CONTROL_STOP*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_CONTROL_ABORT*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_ALL_DEPENDENCIES_RESOLVED*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_PUSH*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_EVENT_EOK*/ + SVA_SEC_WAIT_FOR_START, /*SVA_SEC_EVENT_FAKE*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_EVENT_ACTIVE*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_EVENT_INACTIVE*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_RESET*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_CONTROL_DELETE*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_EVENT_ERROR*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_FLUSH_IN*/ + SVA_SEC_WAIT_FOR_START, /*SVA_SEC_FLUSH_OUT*/ + SVA_SEC_FLUSHING_IN, /*SVA_SEC_CANCEL*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_UPDATE_PARAM*/ + SVA_SEC_TRANSITION_REJECTED /*SVA_SEC_EVENT_EOW*/ + + }, + /* Current State = SVA_SEC_FLUSHING_OUT */ + { + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_CREATE*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_CONFIGURE*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_INTERNAL_NEEDS*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_ACTIVATE*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_INACTIVATE*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_CONTROL_START*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_CONTROL_STOP*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_CONTROL_ABORT*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_ALL_DEPENDENCIES_RESOLVED*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_PUSH*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_EVENT_EOK*/ + SVA_SEC_WAIT_FOR_START, /*SVA_SEC_EVENT_FAKE*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_EVENT_ACTIVE*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_EVENT_INACTIVE*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_RESET*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_CONTROL_DELETE*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_EVENT_ERROR*/ + SVA_SEC_WAIT_FOR_START, /*SVA_SEC_FLUSH_IN*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_FLUSH_OUT*/ + SVA_SEC_FLUSHING_OUT, /*SVA_SEC_CANCEL*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_UPDATE_PARAM*/ + SVA_SEC_TRANSITION_REJECTED /*SVA_SEC_EVENT_EOW*/ + + }, + + + /* Current State = SVA_SERVICE_WAIT_FOR_DATA */ + { + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_CREATE*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_CONFIGURE*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_INTERNAL_NEEDS*/ + SVA_SEC_WAIT_FOR_DATA, /*SVA_SEC_ACTIVATE*/ + SVA_SEC_WAIT_FOR_DATA, /*SVA_SEC_INACTIVATE*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_CONTROL_START*/ + SVA_SEC_STOP_REQUESTED, /*SVA_SEC_CONTROL_STOP*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_CONTROL_ABORT*/ + SVA_SEC_RUNNING, /*SVA_SEC_ALL_DEPENDENCIES_RESOLVED*/ + SVA_SEC_WAIT_FOR_DATA, /*SVA_SEC_PUSH*/ + SVA_SEC_ERROR, /*SVA_SEC_EVENT_EOK*/ + SVA_SEC_ERROR, /*SVA_SEC_EVENT_FAKE*/ + SVA_SEC_WAIT_FOR_DATA, /*SVA_SEC_EVENT_ACTIVE*/ + SVA_SEC_WAIT_FOR_DATA, /*SVA_SEC_EVENT_INACTIVE*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_RESET*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_CONTROL_DELETE*/ + SVA_SEC_ERROR, /*SVA_SEC_EVENT_ERROR*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_FLUSH_IN*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_FLUSH_OUT*/ + SVA_SEC_WAIT_FOR_DATA, /*SVA_SEC_CANCEL*/ + SVA_SEC_WAIT_FOR_DATA, /*SVA_SEC_UPDATE_PARAM*/ + SVA_SEC_TRANSITION_REJECTED /*SVA_SEC_EVENT_EOW*/ + + }, + /* Current State = SVA_SERVICE_RUNNING */ + { + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_CREATE*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_CONFIGURE*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_INTERNAL_NEEDS*/ + SVA_SEC_RUNNING, /*SVA_SEC_ACTIVATE*/ + SVA_SEC_RUNNING, /*SVA_SEC_INACTIVATE*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_CONTROL_START*/ + SVA_SEC_STOP_REQUESTED, /*SVA_SEC_CONTROL_STOP*/ + SVA_SEC_ABORT_REQUESTED, /*SVA_SEC_CONTROL_ABORT*/ + SVA_SEC_RUNNING, /*SVA_SEC_ALL_DEPENDENCIES_RESOLVED*/ + SVA_SEC_RUNNING, /*SVA_SEC_PUSH*/ + SVA_SEC_WAIT_FOR_DATA, /*SVA_SEC_EVENT_EOK*/ + SVA_SEC_ERROR, /*SVA_SEC_EVENT_FAKE*/ + SVA_SEC_RUNNING, /*SVA_SEC_EVENT_ACTIVE*/ + SVA_SEC_RUNNING, /*SVA_SEC_EVENT_INACTIVE*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_RESET*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_CONTROL_DELETE*/ + SVA_SEC_ERROR, /*SVA_SEC_EVENT_ERROR*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_FLUSH_IN*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_FLUSH_OUT*/ + SVA_SEC_RUNNING, /*SVA_SEC_CANCEL*/ + SVA_SEC_RUNNING, /*SVA_SEC_UPDATE_PARAM*/ + SVA_SEC_WAIT_FOR_DATA_EOW /*SVA_SEC_EVENT_EOW*/ + + }, + /* Current State = SVA_SERVICE_ABORT_REQUESTED */ + { + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_CREATE*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_CONFIGURE*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_INTERNAL_NEEDS*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_ACTIVATE*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_INACTIVATE*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_CONTROL_START*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_CONTROL_STOP*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_CONTROL_ABORT*/ + SVA_SEC_ABORT_REQUESTED, /*SVA_SEC_ALL_DEPENDENCIES_RESOLVED*/ + SVA_SEC_ABORT_REQUESTED, /*SVA_SEC_PUSH*/ + SVA_SEC_ERROR, /*SVA_SEC_EVENT_EOK*/ + SVA_SEC_ERROR, /*SVA_SEC_EVENT_FAKE*/ + SVA_SEC_ERROR, /*SVA_SEC_EVENT_ACTIVE*/ + SVA_SEC_ERROR, /*SVA_SEC_EVENT_INACTIVE*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_RESET*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_CONTROL_DELETE*/ + SVA_SEC_ERROR, /*SVA_SEC_EVENT_ERROR*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_FLUSH_IN*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_FLUSH_OUT*/ + SVA_SEC_ABORT_REQUESTED, /*SVA_SEC_CANCEL*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_UPDATE_PARAM*/ + SVA_SEC_ABORT_REQUESTED /*SVA_SEC_EVENT_EOW*/ + + }, + /* Current State = SVA_SERVICE_STOP_REQUESTED */ + { + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_CREATE*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_CONFIGURE*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_INTERNAL_NEEDS*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_ACTIVATE*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_INACTIVATE*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_CONTROL_START*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_CONTROL_STOP*/ + SVA_SEC_ABORT_REQUESTED, /*SVA_SEC_CONTROL_ABORT*/ + SVA_SEC_STOP_REQUESTED, /*SVA_SEC_ALL_DEPENDENCIES_RESOLVED*/ + SVA_SEC_STOP_REQUESTED, /*SVA_SEC_PUSH*/ + SVA_SEC_WAIT_FOR_START, /*SVA_SEC_EVENT_EOK*/ + SVA_SEC_ERROR, /*SVA_SEC_EVENT_FAKE*/ + SVA_SEC_ERROR, /*SVA_SEC_EVENT_ACTIVE*/ + SVA_SEC_ERROR, /*SVA_SEC_EVENT_INACTIVE*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_RESET*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_CONTROL_DELETE*/ + SVA_SEC_ERROR, /*SVA_SEC_EVENT_ERROR*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_FLUSH_IN*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_FLUSH_OUT*/ + SVA_SEC_STOP_REQUESTED, /*SVA_SEC_CANCEL*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_UPDATE_PARAM*/ + SVA_SEC_STOP_REQUESTED /*SVA_SEC_EVENT_EOW*/ + + }, + /* Current State = SVA_SERVICE_ERROR */ + { + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_CREATE*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_CONFIGURE*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_INTERNAL_NEEDS*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_ACTIVATE*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_INACTIVATE*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_CONTROL_START*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_CONTROL_STOP*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_CONTROL_ABORT*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_ALL_DEPENDENCIES_RESOLVED*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_PUSH*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_EVENT_EOK*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_EVENT_FAKE*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_EVENT_ACTIVE*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_EVENT_INACTIVE*/ + SVA_SEC_WAIT_FOR_START, /*SVA_SEC_RESET*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_CONTROL_DELETE*/ + SVA_SEC_ERROR, /*SVA_SEC_EVENT_ERROR*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_FLUSH_IN*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_FLUSH_OUT*/ + SVA_SEC_ERROR, /*SVA_GB_CANCEL*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_GB_UPDATE_PARAM*/ + SVA_SEC_TRANSITION_REJECTED /*SVA_SEC_EVENT_EOW*/ + + }, + /* Current State = SVA_SEC_WAIT_FOR_DATA_EOW */ + { + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_CREATE*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_CONFIGURE*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_INTERNAL_NEEDS*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_ACTIVATE*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_INACTIVATE*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_CONTROL_START*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_CONTROL_STOP*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_CONTROL_ABORT*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_ALL_DEPENDENCIES_RESOLVED*/ + SVA_SEC_RUNNING, /*SVA_SEC_PUSH*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_EVENT_EOK*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_EVENT_FAKE*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_EVENT_ACTIVE*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_EVENT_INACTIVE*/ + SVA_SEC_WAIT_FOR_START, /*SVA_SEC_RESET*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_CONTROL_DELETE*/ + SVA_SEC_ERROR, /*SVA_SEC_EVENT_ERROR*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_FLUSH_IN*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_FLUSH_OUT*/ + SVA_SEC_ERROR, /*SVA_SEC_CANCEL*/ + SVA_SEC_TRANSITION_REJECTED, /*SVA_SEC_UPDATE_PARAM*/ + SVA_SEC_ERROR /*SVA_SEC_EVENT_EOW*/ + }, + + +}; + + +/*activate state machine description*/ +PRIVATE const t_sva_sec_activate_state activateStateMachine[SVA_SEC_LAST_ACTIVATE_DUMMY_STATE][SVA_SEC_LAST_DUMMY_TRANSITION]= { + /* Current State = SVA_SEC_INACTIVE */ + { + SVA_SEC_INACTIVE, /*SVA_SEC_CREATE*/ + SVA_SEC_INACTIVE, /*SVA_SEC_CONFIGURE*/ + SVA_SEC_INACTIVE, /*SVA_SEC_INTERNAL_NEEDS*/ + SVA_SEC_IN_ACTIVATION, /*SVA_SEC_ACTIVATE*/ + SVA_SEC_ACTIVATE_TRANSITION_REJECTED, /*SVA_SEC_INACTIVATE*/ + SVA_SEC_ACTIVATE_TRANSITION_REJECTED, /*SVA_SEC_CONTROL_START*/ + SVA_SEC_ACTIVATE_TRANSITION_REJECTED, /*SVA_SEC_CONTROL_STOP*/ + SVA_SEC_ACTIVATE_TRANSITION_REJECTED, /*SVA_SEC_CONTROL_ABORT*/ + SVA_SEC_INACTIVE, /*SVA_SEC_ALL_DEPENDENCIES_RESOLVED*/ + SVA_SEC_INACTIVE, /*SVA_SEC_PUSH*/ + SVA_SEC_INACTIVE, /*SVA_SEC_EVENT_EOK*/ + SVA_SEC_INACTIVE, /*SVA_SEC_EVENT_FAKE*/ + SVA_SEC_INACTIVE, /*SVA_SEC_EVENT_ACTIVE*/ + SVA_SEC_INACTIVE, /*SVA_SEC_EVENT_INACTIVE*/ + SVA_SEC_INACTIVE, /*SVA_SEC_RESET*/ + SVA_SEC_INACTIVE, /*SVA_SEC_CONTROL_DELETE*/ + SVA_SEC_INACTIVE, /*SVA_SEC_EVENT_ERROR*/ + SVA_SEC_INACTIVE, /*SVA_SEC_FLUSH_IN*/ + SVA_SEC_INACTIVE, /*SVA_SEC_FLUSH_OUT*/ + SVA_SEC_ACTIVATE_TRANSITION_REJECTED, /*SVA_SEC_CANCEL*/ + SVA_SEC_INACTIVE, /*SVA_SEC_UPDATE_PARAM*/ + SVA_SEC_ACTIVATE_TRANSITION_REJECTED /*SVA_SEC_EVENT_EOW*/ + + }, + /* Current State = SVA_SEC_IN_ACTIVATION */ + { + SVA_SEC_ACTIVATE_TRANSITION_REJECTED, /*SVA_SEC_CREATE*/ + SVA_SEC_ACTIVATE_TRANSITION_REJECTED, /*SVA_SEC_CONFIGURE*/ + SVA_SEC_ACTIVATE_TRANSITION_REJECTED, /*SVA_SEC_INTERNAL_NEEDS*/ + SVA_SEC_ACTIVATE_TRANSITION_REJECTED, /*SVA_SEC_ACTIVATE*/ + SVA_SEC_ACTIVATE_TRANSITION_REJECTED, /*SVA_SEC_INACTIVATE*/ + SVA_SEC_ACTIVATE_TRANSITION_REJECTED, /*SVA_SEC_CONTROL_START*/ + SVA_SEC_ACTIVATE_TRANSITION_REJECTED, /*SVA_SEC_CONTROL_STOP*/ + SVA_SEC_ACTIVATE_TRANSITION_REJECTED, /*SVA_SEC_CONTROL_ABORT*/ + SVA_SEC_IN_ACTIVATION, /*SVA_SEC_ALL_DEPENDENCIES_RESOLVED*/ + SVA_SEC_IN_ACTIVATION, /*SVA_SEC_PUSH*/ + SVA_SEC_IN_ACTIVATION, /*SVA_SEC_EVENT_EOK*/ + SVA_SEC_IN_ACTIVATION, /*SVA_SEC_EVENT_FAKE*/ + SVA_SEC_ACTIVE, /*SVA_SEC_EVENT_ACTIVE*/ + SVA_SEC_IN_ACTIVATION, /*SVA_SEC_EVENT_INACTIVE*/ + SVA_SEC_IN_ACTIVATION, /*SVA_SEC_RESET*/ + SVA_SEC_ACTIVATE_TRANSITION_REJECTED, /*SVA_SEC_CONTROL_DELETE*/ + SVA_SEC_IN_ACTIVATION, /*SVA_SEC_EVENT_ERROR*/ + SVA_SEC_IN_ACTIVATION, /*SVA_SEC_FLUSH_IN*/ + SVA_SEC_IN_ACTIVATION, /*SVA_SEC_FLUSH_OUT*/ + SVA_SEC_INACTIVE, /*SVA_SEC_CANCEL*/ + SVA_SEC_IN_ACTIVATION, /*SVA_SEC_UPDATE_PARAM*/ + SVA_SEC_ACTIVATE_TRANSITION_REJECTED /*SVA_SEC_EVENT_EOW*/ + + }, + /* Current State = SVA_SEC_ACTIVE */ + { + SVA_SEC_ACTIVATE_TRANSITION_REJECTED, /*SVA_SEC_CREATE*/ + SVA_SEC_ACTIVATE_TRANSITION_REJECTED, /*SVA_SEC_CONFIGURE*/ + SVA_SEC_ACTIVATE_TRANSITION_REJECTED, /*SVA_SEC_INTERNAL_NEEDS*/ + SVA_SEC_ACTIVATE_TRANSITION_REJECTED, /*SVA_SEC_ACTIVATE*/ + SVA_SEC_IN_INACTIVATION, /*SVA_SEC_INACTIVATE*/ + SVA_SEC_ACTIVE, /*SVA_SEC_CONTROL_START*/ + SVA_SEC_ACTIVE, /*SVA_SEC_CONTROL_STOP*/ + SVA_SEC_ACTIVE, /*SVA_SEC_CONTROL_ABORT*/ + SVA_SEC_ACTIVE, /*SVA_SEC_ALL_DEPENDENCIES_RESOLVED*/ + SVA_SEC_ACTIVE, /*SVA_SEC_PUSH*/ + SVA_SEC_ACTIVE, /*SVA_SEC_EVENT_EOK*/ + SVA_SEC_ACTIVE, /*SVA_SEC_EVENT_FAKE*/ + SVA_SEC_ACTIVE, /*SVA_SEC_EVENT_ACTIVE*/ + SVA_SEC_ACTIVE, /*SVA_SEC_EVENT_INACTIVE*/ + SVA_SEC_ACTIVE, /*SVA_SEC_RESET*/ + SVA_SEC_INACTIVE, /*SVA_SEC_CONTROL_DELETE*/ + SVA_SEC_ACTIVE, /*SVA_SEC_EVENT_ERROR*/ + SVA_SEC_ACTIVE, /*SVA_SEC_FLUSH_IN*/ + SVA_SEC_ACTIVE, /*SVA_SEC_FLUSH_OUT*/ + SVA_SEC_ACTIVATE_TRANSITION_REJECTED, /*SVA_SEC_CANCEL*/ + SVA_SEC_ACTIVE, /*SVA_SEC_UPDATE_PARAM*/ + SVA_SEC_ACTIVE /*SVA_SEC_EVENT_EOW*/ + + }, + /* Current State = SVA_SEC_IN_INACTIVATION */ + { + SVA_SEC_ACTIVATE_TRANSITION_REJECTED, /*SVA_SEC_CREATE*/ + SVA_SEC_ACTIVATE_TRANSITION_REJECTED, /*SVA_SEC_CONFIGURE*/ + SVA_SEC_ACTIVATE_TRANSITION_REJECTED, /*SVA_SEC_INTERNAL_NEEDS*/ + SVA_SEC_ACTIVATE_TRANSITION_REJECTED, /*SVA_SEC_ACTIVATE*/ + SVA_SEC_ACTIVATE_TRANSITION_REJECTED, /*SVA_SEC_INACTIVATE*/ + SVA_SEC_ACTIVATE_TRANSITION_REJECTED, /*SVA_SEC_CONTROL_START*/ + SVA_SEC_ACTIVATE_TRANSITION_REJECTED, /*SVA_SEC_CONTROL_STOP*/ + SVA_SEC_ACTIVATE_TRANSITION_REJECTED, /*SVA_SEC_CONTROL_ABORT*/ + SVA_SEC_IN_INACTIVATION, /*SVA_SEC_ALL_DEPENDENCIES_RESOLVED*/ + SVA_SEC_IN_INACTIVATION, /*SVA_SEC_PUSH*/ + SVA_SEC_IN_INACTIVATION, /*SVA_SEC_EVENT_EOK*/ + SVA_SEC_IN_INACTIVATION, /*SVA_SEC_EVENT_FAKE*/ + SVA_SEC_IN_INACTIVATION, /*SVA_SEC_EVENT_ACTIVE*/ + SVA_SEC_INACTIVE, /*SVA_SEC_EVENT_INACTIVE*/ + SVA_SEC_INACTIVE, /*SVA_SEC_RESET*/ + SVA_SEC_ACTIVATE_TRANSITION_REJECTED, /*SVA_SEC_CONTROL_DELETE*/ + SVA_SEC_IN_INACTIVATION, /*SVA_SEC_EVENT_ERROR*/ + SVA_SEC_IN_INACTIVATION, /*SVA_SEC_FLUSH_IN*/ + SVA_SEC_IN_INACTIVATION, /*SVA_SEC_FLUSH_OUT*/ + SVA_SEC_ACTIVE, /*SVA_SEC_CANCEL*/ + SVA_SEC_IN_INACTIVATION, /*SVA_SEC_UPDATE_PARAM*/ + SVA_SEC_IN_INACTIVATION /*SVA_SEC_EVENT_EOW*/ + + } +}; + + + +/*------------------------------------------------------------------------ + * Private macro + *----------------------------------------------------------------------*/ +#define NB_SUPPORTED_STILL_ENCODE_TRANSFORMS 5 +/* + * Define the conversion table from the different filter mode and the encode subtask type + */ +/* + +PRIVATE const t_sva_tm_subtask_type transformation_2_subtask_type[NB_SUPPORTED_STILL_ENCODE_TRANSFORMS]={ + SVA_TM_ENCODE_JPEG, + SVA_TM_ENCODE_JPEG, + SVA_TM_ENCODE_JPEG, + SVA_TM_ENCODE_JPEG, + SVA_TM_ENCODE_JPEG + }; +*/ + +/*------------------------------------------------------------------------ + * Private Macros + *----------------------------------------------------------------------*/ + + + +/*------------------------------------------------------------------------ + * PRIVATE Functions Prototypes + *----------------------------------------------------------------------*/ +PRIVATE void sva_SEC_ResetInstanceDescriptor(t_sva_service_instance_num); +PRIVATE t_sva_sec_state sva_SEC_UpdateInstanceStatesMachine(t_sva_service_instance_num, t_sva_sec_transition); +PRIVATE t_bool sva_SEC_isTransitionValid(t_sva_service_instance_num, t_sva_sec_transition); +PRIVATE t_bool sva_SEC_isConfigurationValid(const t_sva_still_encoder_configuration *); +PRIVATE t_sva_sec_error sva_SEC_CheckServiceId(t_sva_service_id); +PRIVATE t_sva_sec_error sva_SEC_ResetStatus(t_sva_still_encoder_status *); +PRIVATE t_sva_error sva_SEC_DoFlushOut(t_sva_service_id); +PRIVATE t_sva_error sva_SEC_DoFlushIn(t_sva_service_id); +PRIVATE t_sva_sec_error sva_SEC_ResolveDependencies(t_sva_service_instance_num); +PRIVATE t_sva_sec_error sva_SEC_CreateSubTasksDescriptors(t_sva_service_id, t_uint8, t_sva_tm_subtask_id *, t_sva_tm_subtask_list_id *); +PRIVATE t_sva_sec_error sva_SEC_AllocateParams(t_sva_service_instance_num ); +PRIVATE t_sva_sec_error sva_SEC_FreeParams(t_sva_service_instance_num); +PRIVATE t_sva_sec_error sva_SEC_ConfigureSubTasksParams(t_sva_service_id, t_uint8, const t_sva_still_encoder_configuration *,const t_sva_tm_subtask_id *); +//PRIVATE t_sva_sec_error sva_SEC_GetBufferIdFromPhysicalAddress(t_sva_service_instance_num, t_physical_address, t_sva_buffer_id*); +PRIVATE t_sva_error sva_SEC_HandleFakeEvent( t_sva_tm_virtual_hw_event_id ,t_sva_service_id ,t_sva_tm_subtask_id ,t_uint32 ,t_uint32 ,t_uint8 ,t_uint32 *,t_sva_event_desc *) ; + +/****************************************************************************/ +/* NAME: t_sva_sec_error sva_SEC_Init ( void ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine initialize the encode Management module */ +/* */ +/* PARAMETERS: */ +/* IN : none */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_sec_error */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_sva_error sva_SEC_Init(void) +{ + + t_sva_service_instance_num ind; + + for (ind = 0; ind < NUM_MAX_STILL_ENCODE; ind++) { + sva_SEC_ResetInstanceDescriptor(ind); + sva_SEC_ResetStatus(&stillEncodeDesc[ind].status); + + } + + return SVA_OK; + +} + +/****************************************************************************/ +/* NAME: t_sva_sec_error sva_SEC_Create ( t_sva_service_id * pServiceId ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine allows to create a new instance of a Disp. Service */ +/* */ +/* PARAMETERS: */ +/* IN : none */ +/* */ +/* INOUT : */ +/* - pServiceId: return service ID value */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_sec_error */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_sva_error sva_SEC_Create(t_sva_service_id *pServiceId) +{ + + + t_sva_service_instance_num ind = 0; + //t_sva_blm_error blmError; + t_sva_error status=SVA_OK; + + HCL_ASSERT(pServiceId!=NULL); + + while (stillEncodeDesc[ind].state != SVA_SEC_NOT_INITIALIZED) {ind++;} + + if (ind >= NUM_MAX_STILL_ENCODE ) + { + return SVA_INTERNAL_STILL_ENCODER_ERROR; + } + + WRITE_INSTANCE_NUM_IN_SERVICE_ID(ind, *pServiceId); + + + // Memorize the instance service Id + stillEncodeDesc[ind].serviceId = *pServiceId; + + sva_SEC_ResetInstanceDescriptor(ind); + + // Update the main state machine and the activateState machine + sva_SEC_UpdateInstanceStatesMachine(ind, SVA_SEC_CREATE); + + + return status; + +} + +/****************************************************************************/ +/* NAME: t_sva_sec_error sva_SEC_Reset ( t_sva_service_id serviceId ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine allows to reset an instance of a encode Service */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - serviceId: identifier of the given service */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_sec_error */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_sva_error sva_SEC_Reset(t_sva_service_id serviceId) +{ + + t_sva_service_instance_num instanceNum = READ_INSTANCE_NUM_IN_SERVICE_ID(serviceId); + + if (sva_SEC_UpdateInstanceStatesMachine(instanceNum, SVA_SEC_RESET) == SVA_SEC_TRANSITION_REJECTED) + { + return SVA_INTERNAL_STILL_ENCODER_ERROR; + } + + return SVA_OK; + +} + + + +/****************************************************************************/ +/* NAME: t_sva_sec_error sva_SEC_Control ( */ +/* t_sva_service_id serviceId, */ +/* t_sva_service_cmd_id cmdId, */ +/* t_sva_timestamp timeStamp */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine allows to control an instance of a encode Service */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - serviceId: identifier of the given service */ +/* - cmdId: command to apply to the STILL_ENCODE */ +/* - timeStamp: value of timeStamp */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_sec_error */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_sva_error sva_SEC_Control( + t_sva_service_id serviceId, + t_sva_service_cmd_id cmdId, + t_uint32 param + ) +{ + t_sva_service_instance_num instanceNum = READ_INSTANCE_NUM_IN_SERVICE_ID(serviceId); + t_sva_sec_descriptor *pDesc=&stillEncodeDesc[instanceNum]; + t_sva_error status = SVA_UNEXPECTED_API_CALL; + t_sva_sec_error error; + t_sva_tm_error tmError; + + /*check for service id validity*/ + error=sva_SEC_CheckServiceId(serviceId); + if (error!=SVA_SEC_OK) {return SVA_INTERNAL_STILL_ENCODER_ERROR;} + + + /*handle command*/ + switch(cmdId) + { + case SVA_SERVICE_START: + if (sva_SEC_isTransitionValid(instanceNum,SVA_SEC_CONTROL_START)==TRUE) + { + sva_SEC_UpdateInstanceStatesMachine(instanceNum, SVA_SEC_CONTROL_START); + if (IS_FIFO_FULL(pDesc->subtasksDependencyFifo)==FALSE) + { + sva_SEC_UpdateInstanceStatesMachine(instanceNum, SVA_SEC_ALL_DEPENDENCIES_RESOLVED); + } + tmError=sva_TM_SendTaskCommand(pDesc->subtasksListId,SVA_TM_TCMD_START,param); + HCL_DEBUG_ASSERT(tmError==SVA_TM_OK); + status = SVA_OK; + } + break; + case SVA_SERVICE_STOP: + if (sva_SEC_isTransitionValid(instanceNum,SVA_SEC_CONTROL_STOP)==TRUE) + { + if (pDesc->state == SVA_SEC_WAIT_FOR_DATA) + { + sva_SEC_UpdateInstanceStatesMachine(instanceNum, SVA_SEC_CONTROL_STOP); + tmError=sva_TM_SendTaskCommand(pDesc->subtasksListId,SVA_TM_TCMD_STOP,param); + HCL_DEBUG_ASSERT(tmError==SVA_TM_OK); + status = SVA_OK; + } + else /* SVA_SEC_RUNNING */ + { + t_sva_tm_subtask_list_info *pListInfo = (t_sva_tm_subtask_list_info *)pDesc->subtasksListId; + if (pListInfo->nbSubtask == 0) + { + sva_SEC_UpdateInstanceStatesMachine(instanceNum, SVA_SEC_CONTROL_STOP); + tmError=sva_TM_SendTaskCommand(pDesc->subtasksListId,SVA_TM_TCMD_STOP,param); + HCL_DEBUG_ASSERT(tmError==SVA_TM_OK); + status = SVA_OK; + } + } + + } + if (pDesc->state == SVA_SEC_WAIT_FOR_DATA_EOW || pDesc->state == SVA_SEC_RUNNING) + { + t_sva_blm_error blmError; + + if (pDesc->state == SVA_SEC_WAIT_FOR_DATA_EOW) + { + pDesc->stopOnEowFlag = TRUE; + sva_SEC_UpdateInstanceStatesMachine(instanceNum, SVA_SEC_PUSH); /* state => SVA_SEC_RUNNING */ + } + else /* SVA_SEC_RUNNING */ + { + pDesc->stopOnRunningFlag = TRUE; + } + + if((pDesc->confHandle.currentConf.mode == SVA_CODEC_STREAM_MODE)||(pDesc->confHandle.currentConf.mode == SVA_CODEC_SEGMENTED_MODE)) + { + t_sva_timestamp emptyTimeStamp; + t_uint32 addr_bitstream_buf_struct; + t_sva_tm_error tmError; + + blmError=sva_BLM_GetBufferListPhysicalAddress(pDesc->bitstreamBufferListId[0], &addr_bitstream_buf_struct); + HCL_DEBUG_ASSERT(blmError==SVA_BLM_OK); + { + t_sva_buffer_id bufferListLastBufferId; + t_sva_bm_list_elem * pBitstreamBufferLink; + bufferListLastBufferId = (((t_sva_bm_buffer_list_desc*)pDesc->bitstreamBufferListId[0])->lastBufferId); + + pBitstreamBufferLink = (t_sva_bm_list_elem *)(bufferListLastBufferId); + HCL_ASSERT(pBitstreamBufferLink->bufferLink.addr_next_buf_link == 0); + + pDesc->bitstreamBufferLastBufferId = bufferListLastBufferId; + pDesc->bitstreamBufferPrevLink = pBitstreamBufferLink->bufferLink.addr_prev_buf_link; + pDesc->bitstreamBufferNextLink = pBitstreamBufferLink->bufferLink.addr_next_buf_link; + pBitstreamBufferLink->bufferLink.addr_next_buf_link = addr_bitstream_buf_struct|0x00000001; + pBitstreamBufferLink->bufferLink.addr_prev_buf_link = addr_bitstream_buf_struct|0x00000001; + } + + emptyTimeStamp.type=SVA_NO_TIMESTAMP; + emptyTimeStamp.value=0; + tmError = sva_TM_SendTaskCommand(pDesc->subtasksListId, SVA_TM_TCMD_UPDATE_BUFFER, (t_uint32)&emptyTimeStamp); + HCL_ASSERT(tmError==SVA_TM_OK); + pDesc->eowOccured = FALSE; + } + status = SVA_OK; + } + break; + case SVA_SERVICE_ABORT: + if (sva_SEC_isTransitionValid(instanceNum,SVA_SEC_CONTROL_ABORT)==TRUE) + { + sva_SEC_UpdateInstanceStatesMachine(instanceNum, SVA_SEC_CONTROL_ABORT); + tmError=sva_TM_SendTaskCommand(pDesc->subtasksListId,SVA_TM_TCMD_ABORT,param); + HCL_DEBUG_ASSERT(tmError==SVA_TM_OK); + status = SVA_OK; + } + break; + + case SVA_SERVICE_RESET: + if (sva_SEC_isTransitionValid(instanceNum,SVA_SEC_RESET)==TRUE) + { + pDesc->status.eventStats.errorCounter++; + sva_SEC_UpdateInstanceStatesMachine(instanceNum, SVA_SEC_RESET); + status = SVA_OK; + } + break; + case SVA_SERVICE_FLUSH_IN: + if (sva_SEC_isTransitionValid(instanceNum,SVA_SEC_FLUSH_IN)==TRUE) + { + status = sva_SEC_DoFlushIn(serviceId); // FIX ME: not implemented + if (status == SVA_OK) + { + sva_SEC_UpdateInstanceStatesMachine(instanceNum, SVA_SEC_FLUSH_IN); + sva_TM_SendTaskCommand(pDesc->subtasksListId,SVA_TM_TCMD_FAKE_EVENT,param); + } + } + break; + case SVA_SERVICE_FLUSH_OUT: + if (sva_SEC_isTransitionValid(instanceNum,SVA_SEC_FLUSH_OUT)==TRUE) + { + status = sva_SEC_DoFlushOut(serviceId); // FIX ME: not implemented + if (status == SVA_OK) + { + sva_SEC_UpdateInstanceStatesMachine(instanceNum, SVA_SEC_FLUSH_OUT); + sva_TM_SendTaskCommand(pDesc->subtasksListId,SVA_TM_TCMD_FAKE_EVENT,param); + } + } + break; + default: + status = SVA_UNKNOWN_CMD_ID; + break; + } + + return status; + +} + + + + +/****************************************************************************/ +/* NAME: t_sva_sec_error sva_SEC_UpdateParams ( */ +/* t_sva_service_id serviceId, */ +/* t_sva_update_cmd_type updateCmdType, */ +/* t_sva_still_encoder_param_id paramId, */ +/* t_uint32 param */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine allows to update params for an instance of a encode */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - serviceId: identifier of the given service */ +/* - updateCmdType: command to apply to the STILL_ENCODE */ +/* - paramd: value of timeStamp */ +/* - param: parameter for the cmdType */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_sec_error */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_sva_error SVA_UpdateStillImageEncoderParams( + t_sva_service_id serviceId, + t_sva_update_cmd_type updateCmdType, + t_sva_still_encoder_param_id paramId, + t_uint32 param + ) +{ + t_sva_service_instance_num instanceNum = READ_INSTANCE_NUM_IN_SERVICE_ID(serviceId); + t_sva_sec_descriptor *pDesc=&stillEncodeDesc[instanceNum]; + t_sva_still_encoder_configuration *pNextConf=&pDesc->confHandle.nextConf; + t_sva_still_encoder_configuration *pConf=&pDesc->confHandle.currentConf; + t_sva_sec_error status; + + /*check for service id validity*/ + status=sva_SEC_CheckServiceId(serviceId); + if (status!=SVA_SEC_OK) {return SVA_INTERNAL_STILL_ENCODER_ERROR;} + + /*check that transition is allowed*/ + if (sva_SEC_isTransitionValid(instanceNum,SVA_SEC_UPDATE_PARAM)==FALSE) {return SVA_UNEXPECTED_API_CALL;} + + /*check that a configuration is not currently on going*/ + if (pDesc->confHandle.confState!=SVA_SEC_NO_CONF_CHANGE_NEED) {return SVA_INTERNAL_STILL_ENCODER_ERROR;} + + /*take command into account for next configuration*/ + switch(paramId) + { + case SVA_STILL_ENCODER_PARAM_DUMMY: + break; + default: + break; + } + + + /*take into account updateCmdType*/ + switch(updateCmdType) + { + case SVA_UPDATE_MULTIPLE: + /*nothing to do*/ + break; + case SVA_UPDATE_LAST: + /* FIX ME: For now, consider that all parameters are Immediate */ + *pConf=*pNextConf; + pDesc->confHandle.currentConfCounter++; + pDesc->confHandle.confState=SVA_SEC_IMMEDIATE_CONF_CHANGE_NEED; + break; + case SVA_UPDATE_REVERT: + /*cancel previously param update*/ + *pNextConf=*pConf; + break; + default: + break; + } + + /*update state machine => do nothing*/ + sva_SEC_UpdateInstanceStatesMachine(instanceNum, SVA_SEC_UPDATE_PARAM); + + return SVA_OK; +} + + + +/****************************************************************************/ +/* NAME: t_sva_sec_error sva_SEC_Push ( */ +/* t_sva_service_id serviceId, */ +/* t_sva_buffer_id bufferId, */ +/* t_sva_push_mode pushMode, */ +/* t_sva_buffer_type bufferType, */ +/* t_sva_timestamp timeStamp */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine allows to push data in a encode service */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - serviceId: identifier of the service */ +/* - bufferId: identifier of the buffer */ +/* - pushMode: PUSH_IN/PUSH_OUT */ +/* - bufferType: */ +/* - timeStamp: */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_sec_error */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_sva_error sva_SEC_Push( + t_sva_service_id serviceId, + t_sva_buffer_id bufferId, + t_sva_push_mode pushMode, + t_sva_buffer_type bufferType, + t_sva_timestamp timeStamp + ) +{ + + t_sva_service_instance_num instanceNum = READ_INSTANCE_NUM_IN_SERVICE_ID(serviceId); + t_sva_sec_descriptor *pDesc=&stillEncodeDesc[instanceNum]; + t_sva_sec_error status; + t_sva_bm_error bmError; + t_sva_ff_error ffError; + t_sva_blm_error blmError; + t_sva_error svaError; + t_size size; +// t_sva_tm_error tmError; + t_physical_address addr; + + + svaError = SVA_OK; //For removing compiler warning + + /*check for service id validity*/ + status=sva_SEC_CheckServiceId(serviceId); + if (status!=SVA_SEC_OK) {return SVA_INTERNAL_STILL_ENCODER_ERROR;} + + /*check that transition is allowed*/ + if (sva_SEC_isTransitionValid(instanceNum,SVA_SEC_PUSH)==FALSE) {return SVA_UNEXPECTED_API_CALL;} + + + /*handle provide buffer*/ + switch(bufferType){ + case SVA_IMAGE_BUFFER_TYPE: + if ((pushMode!=SVA_PUSH_IN)&&(pDesc->confHandle.currentConf.thumbnailMode!=SVA_THUMBNAIL_DC_420MB)) return SVA_UNEXPECTED_API_CALL; + if ((pushMode == SVA_PUSH_IN)&&(pDesc->defaultConfiguredDependency.inputBufferDep==NOT_RESOLVED_DEPENDENCY)) + { + + /* update currentPushInSize */ + sva_BM_GetBufferSize(bufferId, &size); + pDesc->currentPushInSize += size; + pDesc->sliceIndex++; + + if (pDesc->confHandle.currentConf.isSliceMode == TRUE) { + + //pDesc->newFrameAndWindowHeight = (size * pDesc->confHandle.currentConf.sourceFrameDesc.frame.height)/pDesc->expectedPushInSize; + + if(pDesc->currentPushInSize >= pDesc->expectedPushInSize) + { + if(pDesc->sliceNumber == 0xff) + + //pDesc->newFrameAndWindowHeight = (size * pDesc->confHandle.currentConf.sourceFrameDesc.frame.height)/pDesc->actualPushInSize; + pDesc->newFrameAndWindowHeight = pDesc->confHandle.currentConf.sourceFrameDesc.frame.height - pDesc->currentFrameAndWindowHeight; + pDesc->sliceNumber = pDesc->sliceIndex; + } + else + { + pDesc->newFrameAndWindowHeight = (t_uint16)((size * pDesc->confHandle.currentConf.sourceFrameDesc.frame.height)/pDesc->actualPushInSize); + pDesc->currentFrameAndWindowHeight += pDesc->newFrameAndWindowHeight; + } + + } + + + + /*push buffer in fifo*/ + ffError=PUSH_FIFO_ELEM(pDesc->inputBufferFifos.pushFifo, t_sva_buffer_id, bufferId); + if (ffError!=SVA_FIFO_OK) {svaError=SVA_INTERNAL_FIFOS_FULL;} + else {svaError=SVA_OK;} + } + + if((pushMode == SVA_PUSH_OUT)&&(pDesc->defaultConfiguredDependency.outputBufferDep==NOT_RESOLVED_DEPENDENCY)) + { + + /* add check size */ + pDesc->thumbnailExpectedSize = (((pDesc->confHandle.currentConf.sourceFrameDesc.window.image.width/8)+15)&0xFFF0)*((( pDesc->confHandle.currentConf.sourceFrameDesc.window.image.height/8)+15)&0xFFF0)*3/2 ; + sva_BM_GetBufferSize(bufferId, &size); + if (size < pDesc->thumbnailExpectedSize) + return SVA_IMAGE_BUFFER_TOO_SMALL; + + + /*push buffer in fifo*/ + ffError=PUSH_FIFO_ELEM(pDesc->outputBufferFifos.pushFifo, t_sva_buffer_id, bufferId); + if (ffError!=SVA_FIFO_OK) {svaError=SVA_INTERNAL_FIFOS_FULL;} + else {svaError=SVA_OK;} + } + + break; + + case SVA_BITSTREAM_BUFFER_TYPE: + + if (pushMode!=SVA_PUSH_OUT) return SVA_UNEXPECTED_API_CALL; // bitstream buffer must be pushed out + ffError=PUSH_FIFO_ELEM(pDesc->bitstreamBufferFifos.pushFifo, t_sva_buffer_id, bufferId); + if (ffError!=SVA_FIFO_OK) {svaError=SVA_INTERNAL_FIFOS_FULL;} + else {svaError=SVA_OK;} + + if ((pDesc->confHandle.currentConf.mode == SVA_CODEC_STREAM_MODE)||(pDesc->confHandle.currentConf.mode == SVA_CODEC_SEGMENTED_MODE)) { + blmError=sva_BLM_AddBufferInList(pDesc->bitstreamBufferListId[0], bufferId); + HCL_DEBUG_ASSERT(blmError==SVA_BLM_OK); + } + + sva_BM_GetBufferPhysicalAddress(bufferId, &pDesc->bitstreamBufferDesc[pDesc->bitstreamBufferNb].bufferAddress); + addr = pDesc->bitstreamBufferDesc[pDesc->bitstreamBufferNb].bufferAddress; + pDesc->bitstreamBufferDesc[pDesc->bitstreamBufferNb].bufferId=bufferId; + pDesc->bitstreamBufferNb = (pDesc->bitstreamBufferNb + 1)%PUSH_FIFO_DEFAULT_SIZE; + + if((pDesc->eowOccured)&&((pDesc->confHandle.currentConf.mode == SVA_CODEC_STREAM_MODE)||(pDesc->confHandle.currentConf.mode == SVA_CODEC_SEGMENTED_MODE))) + { + t_sva_timestamp emptyTimeStamp; + t_sva_tm_subtask_id subtaskId = pDesc->subtaskIdEOW ; + + t_sva_bitstream_buffer_pos bufferOutPosition; + t_uint32 addr_bitstream_buf_struct; + t_sva_tm_error tmError; + + + blmError=sva_BLM_GetBufferListPhysicalAddress(pDesc->bitstreamBufferListId[0], &addr_bitstream_buf_struct); + HCL_DEBUG_ASSERT(blmError==SVA_BLM_OK); + bufferOutPosition.addr_bitstream_buf_struct = addr_bitstream_buf_struct|0x00000001; + bufferOutPosition.addr_bitstream_start = addr; + bufferOutPosition.bitstream_offset=0; + + tmError=sva_TM_UpdateSubTaskField(SVA_TM_ONLY_ONE_FIELD_TO_UPDATE, subtaskId,SVA_TM_ENC_ADDR_IN_BITSTREAM_BUFFER,FCMD_COPY, (t_uint32)&bufferOutPosition,0, 12); + HCL_DEBUG_ASSERT(tmError==SVA_TM_OK); + + emptyTimeStamp.type=SVA_NO_TIMESTAMP; + emptyTimeStamp.value=0; + tmError = sva_TM_SendTaskCommand(pDesc->subtasksListId, SVA_TM_TCMD_UPDATE_BUFFER, (t_uint32)&emptyTimeStamp); + HCL_ASSERT(tmError==SVA_TM_OK); + pDesc->eowOccured = FALSE; + } + break; + + default: + svaError=SVA_INVALID_BUFFER_TYPE; + break; + } + + + /*update state machine*/ + sva_SEC_UpdateInstanceStatesMachine(instanceNum,SVA_SEC_PUSH); + + /*update buffer status if we have succeeded to push it and try to solve dependencies*/ + if (svaError == SVA_OK) + { + t_uint32 systemTime; + + svaError=SVA_GetServiceSystemTime(serviceId,&systemTime); + if (svaError!=SVA_OK) {return SVA_INTERNAL_STILL_ENCODER_ERROR;} + bmError=sva_BM_UpdateBufferStatus(bufferId, SVA_BUFFER_IN_USE, systemTime); + if (bmError!=SVA_BM_OK) {return SVA_INTERNAL_STILL_ENCODER_ERROR;} + status=sva_SEC_ResolveDependencies(instanceNum); + } + + return SVA_OK; +} + + +/****************************************************************************/ +/* NAME: t_sva_sec_error sva_SEC_GetStillImageEncoderStatus ( */ +/* t_sva_service_id serviceId, */ +/* t_sva_still_encoder_status * pStatus */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine allows to get status of the encode service */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - serviceId: identifier of the service */ +/* - pStatus: status for the encode service */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_sec_error */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_sva_error SVA_GetStillImageEncoderStatus(t_sva_service_id serviceId, t_sva_still_encoder_status * pStatus ) +{ + + t_sva_service_instance_num instanceNum = READ_INSTANCE_NUM_IN_SERVICE_ID(serviceId); + t_sva_sec_descriptor *pDesc=&stillEncodeDesc[instanceNum]; + t_sva_sec_error status; + + HCL_ASSERT(pStatus != 0); + /*check for service id validity*/ + status=sva_SEC_CheckServiceId(serviceId); + if (status!=SVA_SEC_OK) {return SVA_INTERNAL_STILL_ENCODER_ERROR;} + + /*copy status*/ + *pStatus=pDesc->status; + + return SVA_OK; + +} + + + +/****************************************************************************/ +/* NAME: t_sva_sec_error sva_SEC_DispatchVirtualHwEvent ( */ +/* t_sva_virtual_hw_event_id eventId, */ +/* t_sva_service_id serviceId, */ +/* t_sva_tm_subtask_id subtaskId, */ +/* t_sva_ticks ticks, */ +/* t_uint8 maxOfEvent, */ +/* t_sva_event_desc * pEventDesc, */ +/* t_uint32 * pNbEvent */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine allows to dispatch event of the encode service */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - eventId: event identifier */ +/* - serviceId: identifier of the service */ +/* - subtaskId: identifier of the subtask for which is the event */ +/* - ticks: */ +/* - maxOfEvent: nb of event max contained in EventDesc */ +/* - pEventDesc: structure of Events */ +/* - pNbEvent: nb of event into EventDesc */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_sec_error */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ + +PUBLIC t_sva_error sva_SEC_DispatchVirtualHwEvent( + t_sva_tm_virtual_hw_event_id eventId, + t_sva_service_id serviceId, + t_sva_tm_subtask_id subtaskId, + t_uint32 eventTimestamp, + t_uint32 eventDate, + t_uint8 maxOfEvent, + t_sva_event_desc * pEventDesc, + t_uint32 * pNbEvent + ) +{ + t_sva_service_instance_num instanceNum = READ_INSTANCE_NUM_IN_SERVICE_ID(serviceId); + t_sva_sec_descriptor *pDesc=&stillEncodeDesc[instanceNum]; + t_sva_ff_error ffError; + t_uint32 nbEventsRaised = 0; + t_sva_sec_error secError; + t_bool isUpdateStateNeed=FALSE; + + + HCL_ASSERT(pEventDesc != 0); + HCL_ASSERT(pNbEvent != 0); + + *pNbEvent=0; + + /*check for service id validity*/ + secError=sva_SEC_CheckServiceId(serviceId); + if (secError!=SVA_SEC_OK) {return SVA_INTERNAL_STILL_ENCODER_ERROR;} + + + /* + * Switch eventId + */ + + switch(eventId) + { + + case SVA_TM_ACTIVE_HW_EVENT: + CHECK_TABLE_OVERFLOW(nbEventsRaised, maxOfEvent, SVA_INTERNAL_EVENT_MGT_ERROR); + pEventDesc[nbEventsRaised].eventId = SVA_EVENT_SERVICE_ACTIVATED; + pEventDesc[nbEventsRaised].serviceId = serviceId; + pEventDesc[nbEventsRaised].bufferId = INVALID_BUFFER_ID; + pEventDesc[nbEventsRaised].eventTimestamp = (t_sva_timestamp_value) eventTimestamp; + pEventDesc[nbEventsRaised].eventDate = (t_sva_timestamp_value) eventDate; + pEventDesc[nbEventsRaised].extraInfo=0; + nbEventsRaised++; + sva_SEC_UpdateInstanceStatesMachine(instanceNum,SVA_SEC_EVENT_ACTIVE); + break; + case SVA_TM_INACTIVE_HW_EVENT: + CHECK_TABLE_OVERFLOW(nbEventsRaised, maxOfEvent, SVA_INTERNAL_EVENT_MGT_ERROR); + pEventDesc[nbEventsRaised].eventId = SVA_EVENT_SERVICE_INACTIVATED; + pEventDesc[nbEventsRaised].serviceId = serviceId; + pEventDesc[nbEventsRaised].bufferId = INVALID_BUFFER_ID; + pEventDesc[nbEventsRaised].eventTimestamp = (t_sva_timestamp_value) eventTimestamp; + pEventDesc[nbEventsRaised].eventDate = (t_sva_timestamp_value) eventDate; + pEventDesc[nbEventsRaised].extraInfo=0; + nbEventsRaised++; + sva_SEC_UpdateInstanceStatesMachine(instanceNum,SVA_SEC_EVENT_INACTIVE); + break; + case SVA_TM_ERR_HW_EVENT: + CHECK_TABLE_OVERFLOW(nbEventsRaised, maxOfEvent, SVA_INTERNAL_EVENT_MGT_ERROR); + /* in case of SVA_SEC_ABORT_REQUESTED also control will come here */ + pEventDesc[nbEventsRaised].eventId = SVA_EVENT_SERVICE_ERROR; + pEventDesc[nbEventsRaised].serviceId = serviceId; + pEventDesc[nbEventsRaised].bufferId = INVALID_BUFFER_ID; + pEventDesc[nbEventsRaised].eventTimestamp = (t_sva_timestamp_value) eventTimestamp; + pEventDesc[nbEventsRaised].eventDate = (t_sva_timestamp_value) eventDate; + pEventDesc[nbEventsRaised].extraInfo=0; + nbEventsRaised++; + break; + case SVA_TM_EOW_HW_EVENT: + if (pDesc->stopOnEowFlag == TRUE) + { + HCL_ASSERT(0); + } + else + { + if ((pDesc->confHandle.currentConf.mode == SVA_CODEC_STREAM_MODE)|| (pDesc->confHandle.currentConf.mode == SVA_CODEC_SEGMENTED_MODE)){ + t_uint32 nbElemsPush=0; + t_uint32 i; + t_sva_buffer_id bufferId; + t_sva_blm_error blmError=SVA_BLM_OK; + t_sva_sec_subtask_dependencies subtaskDep; + + /* also gives all previously buffer filled event */ + /* update bitstream fifo and buffer list */ + /* -------------------------------------------- */ + + /* if EOW event then it means there is no more usable buffer */ + /* then all buffers from push fifo have been added in bitstreamList */ + /* + the one in inUseFifo if any */ + + + nbElemsPush = GET_FIFO_NB_ELEMS(pDesc->bitstreamBufferFifos.pushFifo); + /* il faut lui laisser le dernier element de la link list sinon l update commande ne */ + /* fonctionne pas */ + + for(i=0; ibitstreamBufferListId[0], &bufferId); + HCL_DEBUG_ASSERT(blmError==SVA_BLM_OK); + + } + + /* gives buffer filled events */ + for(i=0; ibitstreamBufferFifos.pushFifo, t_sva_buffer_id,pEventDesc[nbEventsRaised].bufferId); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + sva_BM_GetBufferSize(pEventDesc[nbEventsRaised].bufferId,&pEventDesc[nbEventsRaised].extraInfo); + pEventDesc[nbEventsRaised].extraInfo = 8 * pEventDesc[nbEventsRaised].extraInfo; // in bits + + pDesc->bufferSizeOnEOW += pEventDesc[nbEventsRaised].extraInfo; + + pEventDesc[nbEventsRaised].extraInfo2 = 0; // not the last + sva_BM_UpdateBufferStatus(pEventDesc[nbEventsRaised].bufferId,SVA_BUFFER_FILLED,eventTimestamp); + nbEventsRaised++; + pDesc->status.eventStats.filledCounter++; + } + + CHECK_TABLE_OVERFLOW(nbEventsRaised, maxOfEvent, SVA_INTERNAL_EVENT_MGT_ERROR); + pEventDesc[nbEventsRaised].eventId = SVA_EVENT_BUFFER_FILLED_READ_ONLY; + pEventDesc[nbEventsRaised].serviceId = serviceId; + pEventDesc[nbEventsRaised].eventTimestamp = (t_sva_timestamp_value) eventTimestamp; + pEventDesc[nbEventsRaised].eventDate = (t_sva_timestamp_value) eventDate; + ffError=READ_FIFO_ELEM(pDesc->bitstreamBufferFifos.pushFifo, t_sva_buffer_id,pEventDesc[nbEventsRaised].bufferId); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + sva_BM_GetBufferSize(pEventDesc[nbEventsRaised].bufferId,&pEventDesc[nbEventsRaised].extraInfo); + pEventDesc[nbEventsRaised].extraInfo = 8 * pEventDesc[nbEventsRaised].extraInfo; + pEventDesc[nbEventsRaised].extraInfo2 = 0; // not the last + //sva_BM_UpdateBufferStatus(pEventDesc[nbEventsRaised].bufferId,SVA_BUFFER_FILLED,eventTimestamp); + nbEventsRaised++; + pDesc->status.eventStats.readOnlyCounter++; + + /* overflow event */ + /* -------------- */ + CHECK_TABLE_OVERFLOW(nbEventsRaised, maxOfEvent, SVA_INTERNAL_EVENT_MGT_ERROR); + pEventDesc[nbEventsRaised].eventId = SVA_EVENT_OVERFLOW; + pEventDesc[nbEventsRaised].serviceId = serviceId; + pEventDesc[nbEventsRaised].bufferId = INVALID_BUFFER_ID; + pEventDesc[nbEventsRaised].eventTimestamp = (t_sva_timestamp_value) eventTimestamp; + pEventDesc[nbEventsRaised].eventDate = (t_sva_timestamp_value) eventDate; + pEventDesc[nbEventsRaised].extraInfo=0; + nbEventsRaised++; + pDesc->status.eventStats.overflowCounter++; + + pDesc->eowOccured = TRUE; + ffError=READ_FIFO_ELEM(pDesc->inUseSubtasksDependencyFifo,t_sva_sec_subtask_dependencies,subtaskDep); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + pDesc->subtaskIdEOW = subtaskDep.subtaskId; + + + } + else { + /* Error in Case of Image mode */ + CHECK_TABLE_OVERFLOW(nbEventsRaised, maxOfEvent, SVA_INTERNAL_EVENT_MGT_ERROR); + pEventDesc[nbEventsRaised].eventId = SVA_EVENT_SERVICE_ERROR; + pEventDesc[nbEventsRaised].serviceId = serviceId; + pEventDesc[nbEventsRaised].bufferId = INVALID_BUFFER_ID; + pEventDesc[nbEventsRaised].eventTimestamp = (t_sva_timestamp_value) eventTimestamp; + pEventDesc[nbEventsRaised].eventDate = (t_sva_timestamp_value) eventDate; + pEventDesc[nbEventsRaised].extraInfo=0; + nbEventsRaised++; + } + sva_SEC_UpdateInstanceStatesMachine(instanceNum,SVA_SEC_EVENT_EOW); + if (pDesc->state == SVA_SEC_WAIT_FOR_DATA_EOW && pDesc->stopOnRunningFlag == TRUE) + { + sva_SEC_UpdateInstanceStatesMachine(instanceNum, SVA_SEC_PUSH); /* state => SVA_SEC_RUNNING */ + } + } + break; + case SVA_TM_FAKE_HW_EVENT: + CHECK_TABLE_OVERFLOW(nbEventsRaised, maxOfEvent, SVA_INTERNAL_EVENT_MGT_ERROR); + + sva_SEC_HandleFakeEvent( eventId, serviceId, subtaskId, eventTimestamp, eventDate, maxOfEvent, + &nbEventsRaised, + pEventDesc); + + if (pDesc->state == SVA_SEC_FLUSHING_IN) { + pEventDesc[nbEventsRaised].eventId = SVA_EVENT_SERVICE_FLUSHED_IN; + } + if (pDesc->state == SVA_SEC_FLUSHING_OUT) { + pEventDesc[nbEventsRaised].eventId = SVA_EVENT_SERVICE_FLUSHED_OUT; + } + + pEventDesc[nbEventsRaised].serviceId = serviceId; + pEventDesc[nbEventsRaised].bufferId = INVALID_BUFFER_ID; + pEventDesc[nbEventsRaised].eventTimestamp = (t_sva_timestamp_value) eventTimestamp; + pEventDesc[nbEventsRaised].eventDate = (t_sva_timestamp_value) eventDate; + pEventDesc[nbEventsRaised].extraInfo=0; + nbEventsRaised++; + sva_SEC_UpdateInstanceStatesMachine(instanceNum,SVA_SEC_EVENT_FAKE); + break; + + case SVA_TM_EOT_HW_EVENT: + /* can be either : + * - SVA_EVENT_BUFFER_VOIDED + * - SVA_EVENT_BUFFER_FILLED + */ + if (pDesc->stopOnEowFlag == TRUE || pDesc->stopOnRunningFlag == TRUE) + { + pDesc->stopOnEowFlag = FALSE; + pDesc->stopOnRunningFlag = FALSE; + sva_SEC_UpdateInstanceStatesMachine(instanceNum, SVA_SEC_CONTROL_STOP); /* state => SVA_SEC_STOP_REQUESTED */ + ((t_sva_tm_subtask_list_info *)pDesc->subtasksListId)->state = SVA_TM_IDLE; + + { + t_sva_bm_list_elem * pBitstreamBufferLink; + t_sva_buffer_id bufferListLastBufferId; + + HCL_ASSERT(pDesc->bitstreamBufferLastBufferId != 0); + bufferListLastBufferId = (((t_sva_bm_buffer_list_desc*)pDesc->bitstreamBufferListId[0])->lastBufferId); + /* If there is a crash in below ASSERT then user have pushed an extra buffer after giving * + * stop command to HCL and tis is unexpected from HCL point of view and may create problem */ + HCL_ASSERT(pDesc->bitstreamBufferLastBufferId == bufferListLastBufferId); + + pBitstreamBufferLink = (t_sva_bm_list_elem *)(pDesc->bitstreamBufferLastBufferId); + + pBitstreamBufferLink->bufferLink.addr_prev_buf_link = pDesc->bitstreamBufferPrevLink; + pBitstreamBufferLink->bufferLink.addr_next_buf_link = pDesc->bitstreamBufferNextLink; + } + { + t_sint32 remainingSize=(t_sint32)stillEncodeAlgoDesc[pDesc->algo].pGetBitstreamSize(instanceNum); + + pDesc->eotNumber++; + pDesc->status.nbImagesEncoded++; + pDesc->status.nbBytesEncoded += (remainingSize+7)/8; + /* first remove size of buffer already removed on EOW */ + remainingSize -= pDesc->bufferSizeOnEOW; + pDesc->bufferSizeOnEOW = 0; + } + } + else + { + t_uint32 nbElems=0; + t_sva_sec_subtask_dependencies subtaskDep; + t_logical_address paramAddr; + t_uint32 size; + t_uint32 newPreviousSize; + t_logical_address bitstream_logical_addr; + t_sva_buffer_id bufferId; + t_sva_sec_algo_error algoError; + t_sva_blm_error blmError=SVA_BLM_OK; + + t_sint32 bitstreamSize; + + t_uint32 i; + /* + * A subtask has ended so we have to resolve its dependency for its next execution + */ + + + newPreviousSize = 0; //For removing compiler warning + + ffError=POP_FIFO_ELEM(pDesc->inUseSubtasksDependencyFifo,t_sva_sec_subtask_dependencies,subtaskDep); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + + subtaskDep.subtaskId = subtaskId; + subtaskDep.dependencies = pDesc->defaultConfiguredDependency; + ffError = PUSH_FIFO_ELEM(pDesc->subtasksDependencyFifo, t_sva_sec_subtask_dependencies, subtaskDep); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + + + + /* + * Need to provide buffer out (only for bistream_size) to algo box and also to get bistream_out info + */ + + /* ParamOut */ + sva_MM_GetBlockLogicalAddress(pDesc->paramOutBlockId, ¶mAddr); + size = stillEncodeAlgoDesc[pDesc->algo].pGetParamsOutSize(instanceNum); + sva_TM_GetSubTaskField(subtaskId,SVA_TM_ENC_ADDR_OUT_PARAMETERS,paramAddr,0, size, TRUE); + algoError=stillEncodeAlgoDesc[pDesc->algo].pSetFrameParamOut(instanceNum,(const t_sva_sec_algo_params_out *) paramAddr); + if (algoError!=SVA_SEC_ALGO_OK) {return SVA_INTERNAL_STILL_ENCODER_ERROR;} + + /* remove buffer from list */ + if (pDesc->confHandle.currentConf.mode == SVA_CODEC_IMAGE_MODE) { /* Image Mode */ + + blmError=sva_BLM_RemoveBufferFromList(subtaskDep.bufferListId, &bufferId); + HCL_DEBUG_ASSERT(blmError==SVA_BLM_OK); + pDesc->nbBitstreamBuffers++; + bitstreamSize=(t_sint32)stillEncodeAlgoDesc[pDesc->algo].pGetBitstreamSize(instanceNum); + + pDesc->status.nbImagesEncoded++; + + + pDesc->status.nbBytesEncoded+=(bitstreamSize+7)/8; + + } + else if ((pDesc->confHandle.currentConf.mode == SVA_CODEC_STREAM_MODE)||((pDesc->confHandle.currentConf.mode == SVA_CODEC_SEGMENTED_MODE)&&(pDesc->confHandle.currentConf.isSliceMode == TRUE))) + { + t_sva_buffer_id bufferId=INVALID_BUFFER_ID; + t_uint32 bufferSize; + + t_uint32 dataSize=0; + t_bool ended=FALSE; + pDesc->eotNumber++; + + bitstreamSize=(t_sint32)stillEncodeAlgoDesc[pDesc->algo].pGetBitstreamSize(instanceNum); + pDesc->status.nbImagesEncoded++; + pDesc->status.nbBytesEncoded+=(bitstreamSize+7)/8; + + /* first remove size of buffer already removed on EOW */ + bitstreamSize -=pDesc->bufferSizeOnEOW; + pDesc->bufferSizeOnEOW = 0; + + + READ_FIFO_ELEM(pDesc->bitstreamBufferFifos.pushFifo, t_sva_buffer_id, pDesc->associatedBufferId[0]); + sva_BM_GetBufferSize(pDesc->associatedBufferId[0], &bufferSize); + bufferSize = 8*bufferSize; + dataSize += (bufferSize - pDesc->previousSize); + + + while(!ended) + { + if(dataSize < (t_uint32)bitstreamSize) + { + ffError=POP_FIFO_ELEM(pDesc->bitstreamBufferFifos.pushFifo, t_sva_buffer_id, bufferId); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + blmError=sva_BLM_RemoveBufferFromList(pDesc->bitstreamBufferListId[0], &bufferId); + HCL_DEBUG_ASSERT(blmError==SVA_BLM_OK); + + READ_FIFO_ELEM(pDesc->bitstreamBufferFifos.pushFifo, t_sva_buffer_id, pDesc->associatedBufferId[nbElems+1]); + sva_BM_GetBufferSize(pDesc->associatedBufferId[nbElems+1], &bufferSize); + bufferSize = 8*bufferSize; + dataSize += bufferSize; + nbElems++; + } + else + { + ended = TRUE; + } + + } + + newPreviousSize = bitstreamSize -dataSize+bufferSize; + + + /*reprogram bufferLinkaddr with new link addr*/ + /* attention, si elle est vide, probleme!!! */ + { + + t_sva_bitstream_buffer_pos bufferOutPosition; + t_uint32 addr_bitstream_buf_struct; + t_sva_tm_error tmError; + + blmError=sva_BLM_GetBufferListPhysicalAddress(pDesc->bitstreamBufferListId[0], &addr_bitstream_buf_struct); + HCL_DEBUG_ASSERT(blmError==SVA_BLM_OK); + bufferOutPosition.addr_bitstream_buf_struct = addr_bitstream_buf_struct|0x00000001; + tmError=sva_TM_UpdateSubTaskField(SVA_TM_ONLY_ONE_FIELD_TO_UPDATE, subtaskDep.subtaskId,SVA_TM_ENC_ADDR_OUT_BITSTREAM_BUFFER,FCMD_COPY, (t_uint32)&bufferOutPosition,0, 4); + HCL_DEBUG_ASSERT(tmError==SVA_TM_OK); + + + } + + } + else // SEGMENTED MODE and not slice mode + { + + t_sint32 remainingSize=(t_sint32)stillEncodeAlgoDesc[pDesc->algo].pGetBitstreamSize(instanceNum); + t_uint32 bufferSize; + + pDesc->eotNumber++; + pDesc->status.nbImagesEncoded++; + pDesc->status.nbBytesEncoded+=(remainingSize+7)/8; + /* first remove size of buffer already removed on EOW */ + remainingSize -=pDesc->bufferSizeOnEOW; + + + while(remainingSize>0) { + blmError=sva_BLM_RemoveBufferFromList(pDesc->bitstreamBufferListId[0], &bufferId); + HCL_DEBUG_ASSERT(blmError==SVA_BLM_OK); + sva_BM_GetBufferSize(bufferId, &bufferSize); + bufferSize = 8*bufferSize; + remainingSize -= bufferSize; + nbElems++; + + } + + + + } + + + /* + * Generate all the events linked with the EOT + */ + + { + t_uint32 size; + CHECK_TABLE_OVERFLOW(nbEventsRaised, maxOfEvent, SVA_INTERNAL_EVENT_MGT_ERROR); + pEventDesc[nbEventsRaised].eventId = SVA_EVENT_BUFFER_VOIDED; + pEventDesc[nbEventsRaised].serviceId = serviceId; + pEventDesc[nbEventsRaised].eventTimestamp = (t_sva_timestamp_value) eventTimestamp; + pEventDesc[nbEventsRaised].eventDate = (t_sva_timestamp_value) eventDate; + pEventDesc[nbEventsRaised].extraInfo2 =1; + /* Get bufferId: */ + ffError = POP_FIFO_ELEM(pDesc->inputBufferFifos.inUseFifo,t_sva_buffer_id,pEventDesc[nbEventsRaised].bufferId); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + sva_BM_GetBufferSize(pEventDesc[nbEventsRaised].bufferId, &size); + pEventDesc[nbEventsRaised].extraInfo = 8*size; + sva_BM_UpdateBufferStatus(pEventDesc[nbEventsRaised].bufferId,SVA_BUFFER_VOIDED,eventTimestamp); + nbEventsRaised++; + pDesc->status.eventStats.voidedCounter++; + } + + + + /* thumbnail: til slice mode is not possible with thumbnail, we keep it here */ + { + if(!IS_FIFO_EMPTY(pDesc->outputBufferFifos.inUseFifo)) + { + CHECK_TABLE_OVERFLOW(nbEventsRaised, maxOfEvent, SVA_INTERNAL_EVENT_MGT_ERROR); + pEventDesc[nbEventsRaised].eventId = SVA_EVENT_BUFFER_FILLED; + pEventDesc[nbEventsRaised].serviceId = serviceId; + pEventDesc[nbEventsRaised].eventTimestamp = (t_sva_timestamp_value) eventTimestamp; + pEventDesc[nbEventsRaised].eventDate = (t_sva_timestamp_value) eventDate; + pEventDesc[nbEventsRaised].extraInfo2 =1; + /* Get bufferId: */ + ffError = POP_FIFO_ELEM(pDesc->outputBufferFifos.inUseFifo,t_sva_buffer_id,pEventDesc[nbEventsRaised].bufferId); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + //sva_BM_GetBufferSize(pEventDesc[nbEventsRaised].bufferId, &size); + pEventDesc[nbEventsRaised].extraInfo = 8*pDesc->thumbnailExpectedSize; + sva_BM_UpdateBufferStatus(pEventDesc[nbEventsRaised].bufferId,SVA_BUFFER_FILLED,eventTimestamp); + nbEventsRaised++; + pDesc->status.eventStats.filledCounter++; + } + } + + if (pDesc->confHandle.currentConf.mode == SVA_CODEC_IMAGE_MODE) + { + CHECK_TABLE_OVERFLOW(nbEventsRaised, maxOfEvent, SVA_INTERNAL_EVENT_MGT_ERROR); + pEventDesc[nbEventsRaised].eventId = SVA_EVENT_BUFFER_FILLED; + pEventDesc[nbEventsRaised].serviceId = serviceId; + pEventDesc[nbEventsRaised].eventTimestamp = (t_sva_timestamp_value) eventTimestamp; + pEventDesc[nbEventsRaised].eventDate = (t_sva_timestamp_value) eventDate; + + pEventDesc[nbEventsRaised].extraInfo = stillEncodeAlgoDesc[pDesc->algo].pGetBitstreamSize(instanceNum); + pEventDesc[nbEventsRaised].extraInfo2 =1; + /* Get bufferId */ + ffError=POP_FIFO_ELEM(pDesc->bitstreamBufferFifos.inUseFifo, t_sva_buffer_id,pEventDesc[nbEventsRaised].bufferId); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + sva_BM_UpdateBufferStatus(pEventDesc[nbEventsRaised].bufferId,SVA_BUFFER_FILLED,eventTimestamp); + if(pDesc->confHandle.currentConf.isSliceMode == TRUE) + { + t_uint8 *src_addr; + sva_BM_GetBufferLogicalAddress(pEventDesc[nbEventsRaised].bufferId, &bitstream_logical_addr); + sva_TM_GetSubTaskField(subtaskId, SVA_TM_ENC_ADDR_OUT_BITSTREAM_BUFFER, + (t_uint32) &pDesc->prv_bitstream_offset, HCL_BITFIELD_OFFSET(t_sva_bitstream_buffer_pos, bitstream_offset), + sizeof(t_uint32),FALSE); + pDesc->prv_bitstream_offset %= 8; //for the extra bits which are not aligned + if((pDesc->nbBitstreamBuffers)==(pDesc->confHandle.currentConf.sourceFrameDesc.frame.height)/(pDesc->newFrameAndWindowHeight)) /* Last slice */ + { + pDesc->nbBitstreamBuffers=0; + } + else /* Don't pass last extra bits to user if not last slice, Will be updated in next bitstream buffer */ + { + pEventDesc[nbEventsRaised].extraInfo= pEventDesc[nbEventsRaised].extraInfo - pDesc->prv_bitstream_offset; + } + if (pDesc->prv_bitstream_offset != 0) + { + src_addr = (t_uint8*)(bitstream_logical_addr+(pEventDesc[nbEventsRaised].extraInfo/8)); + pDesc->prv_bitstream_last_byte= *src_addr; + } + else + { + pDesc->prv_bitstream_last_byte = 0; + } + } + nbEventsRaised++; + pDesc->status.eventStats.filledCounter++; + } + /**/ + else if((pDesc->confHandle.currentConf.mode == SVA_CODEC_STREAM_MODE)||((pDesc->confHandle.currentConf.mode == SVA_CODEC_SEGMENTED_MODE)&&(pDesc->confHandle.currentConf.isSliceMode == TRUE))) + { + t_uint32 size=0; + t_uint32 bitstreamSize=stillEncodeAlgoDesc[pDesc->algo].pGetBitstreamSize(instanceNum); + pDesc->status.nbImagesEncoded++; + pDesc->status.nbBytesEncoded+=(bitstreamSize+7)/8; + + /* il faut enlever ceux de la pushFifo et generer autant de BUFFER_FILLED */ + + for(i=0; iassociatedBufferId[i] ; + sva_BM_GetBufferSize(pEventDesc[nbEventsRaised].bufferId,&pEventDesc[nbEventsRaised].extraInfo); + pEventDesc[nbEventsRaised].extraInfo = 8 * pEventDesc[nbEventsRaised].extraInfo; + size += pEventDesc[nbEventsRaised].extraInfo; + pEventDesc[nbEventsRaised].extraInfo2 = 0; // not the last + sva_BM_UpdateBufferStatus(pEventDesc[nbEventsRaised].bufferId,SVA_BUFFER_FILLED,eventTimestamp); + nbEventsRaised++; + pDesc->status.eventStats.filledCounter++; + } + + CHECK_TABLE_OVERFLOW(nbEventsRaised, maxOfEvent, SVA_INTERNAL_EVENT_MGT_ERROR); + pEventDesc[nbEventsRaised].eventId = SVA_EVENT_BUFFER_PARTLY_FILLED; + pEventDesc[nbEventsRaised].serviceId = serviceId; + pEventDesc[nbEventsRaised].eventTimestamp = (t_sva_timestamp_value) eventTimestamp; + pEventDesc[nbEventsRaised].eventDate = (t_sva_timestamp_value) eventDate; + + pEventDesc[nbEventsRaised].bufferId = pDesc->associatedBufferId[nbElems]; + pEventDesc[nbEventsRaised].extraInfo = newPreviousSize /*bitstreamSize - pDesc->bufferSizeOnEOW - size + pDesc->previousSize*/ ; + pDesc->lastPartlyFilledSize = newPreviousSize; + pEventDesc[nbEventsRaised].extraInfo2 = 0; + if((pDesc->confHandle.currentConf.isSliceMode == FALSE)||(pDesc->sliceNumber==pDesc->eotNumber )) + { + t_uint32 offset; + t_size size; + t_uint16 value = 0x00; + pEventDesc[nbEventsRaised].extraInfo2 = 1; + pDesc->bufferOnLastSliceSize = 0; + /*also have to reset last_slice to 0 */ + size = stillEncodeAlgoDesc[pDesc->algo].pGetLastSliceOffsetAndSize(instanceNum,&offset); + sva_TM_UpdateSubTaskField(SVA_TM_ONLY_ONE_FIELD_TO_UPDATE, + subtaskDep.subtaskId, + SVA_TM_ENC_ADDR_IN_PARAMETERS, + FCMD_COPY, + (t_uint32)&value, + 2*offset, + size); + + pDesc->eotNumber =0; + + if(pDesc->confHandle.currentConf.mode == SVA_CODEC_SEGMENTED_MODE) + { + pEventDesc[nbEventsRaised].eventId = SVA_EVENT_BUFFER_FILLED; + sva_BM_UpdateBufferStatus(pEventDesc[nbEventsRaised].bufferId,SVA_BUFFER_FILLED,eventTimestamp); + + ffError=POP_FIFO_ELEM(pDesc->bitstreamBufferFifos.pushFifo, t_sva_buffer_id, bufferId); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + blmError=sva_BLM_RemoveBufferFromList(pDesc->bitstreamBufferListId[0], &bufferId); + HCL_DEBUG_ASSERT(blmError==SVA_BLM_OK); + + + ffError=UPDATE_FIFO_ELEM_FIELD(pDesc->subtasksDependencyFifo, + t_sva_sec_subtask_dependencies, .dependencies.bitstreamBufferDep, + NOT_RESOLVED_DEPENDENCY); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + + newPreviousSize = 0; + } + + + } + + pDesc->status.eventStats.partlyCounter++; + nbEventsRaised++; + pDesc->previousSize = newPreviousSize; + + } + else // SEGMENTED MODE but not slice mode + { + t_uint32 size=0; + t_uint32 bitstreamSize = stillEncodeAlgoDesc[pDesc->algo].pGetBitstreamSize(instanceNum); + bitstreamSize -= pDesc->bufferSizeOnEOW ; + pDesc->bufferSizeOnEOW = 0; + pDesc->status.nbImagesEncoded++; + pDesc->status.nbBytesEncoded+=(bitstreamSize+7)/8; + for(i=0; ibitstreamBufferFifos.pushFifo, t_sva_buffer_id,pEventDesc[nbEventsRaised].bufferId); + sva_BM_GetBufferSize(pEventDesc[nbEventsRaised].bufferId,&pEventDesc[nbEventsRaised].extraInfo); + pEventDesc[nbEventsRaised].extraInfo = 8*pEventDesc[nbEventsRaised].extraInfo; + size += pEventDesc[nbEventsRaised].extraInfo; + pEventDesc[nbEventsRaised].extraInfo2 = 0; // not the last + sva_BM_UpdateBufferStatus(pEventDesc[nbEventsRaised].bufferId,SVA_BUFFER_FILLED,eventTimestamp); + nbEventsRaised++; + pDesc->status.eventStats.filledCounter++; + } + + CHECK_TABLE_OVERFLOW(nbEventsRaised, maxOfEvent, SVA_INTERNAL_EVENT_MGT_ERROR); + pEventDesc[nbEventsRaised].eventId = SVA_EVENT_BUFFER_FILLED; + pEventDesc[nbEventsRaised].serviceId = serviceId; + pEventDesc[nbEventsRaised].eventTimestamp = (t_sva_timestamp_value) eventTimestamp; + pEventDesc[nbEventsRaised].eventDate = (t_sva_timestamp_value) eventDate; + POP_FIFO_ELEM(pDesc->bitstreamBufferFifos.pushFifo, t_sva_buffer_id,pEventDesc[nbEventsRaised].bufferId); + pEventDesc[nbEventsRaised].extraInfo = bitstreamSize-size; + pEventDesc[nbEventsRaised].extraInfo2 = 1; // the last or not + sva_BM_UpdateBufferStatus(pEventDesc[nbEventsRaised].bufferId,SVA_BUFFER_FILLED,eventTimestamp); + nbEventsRaised++; + pDesc->status.eventStats.filledCounter++; + + + } + + } + break; + case SVA_TM_EOK_HW_EVENT : + if (pDesc->state==SVA_SEC_STOP_REQUESTED) + { + /*generate a stop event*/ + CHECK_TABLE_OVERFLOW(nbEventsRaised, maxOfEvent, SVA_INTERNAL_EVENT_MGT_ERROR); + pEventDesc[nbEventsRaised].eventId = SVA_EVENT_SERVICE_STOPPED; + pEventDesc[nbEventsRaised].serviceId = serviceId; + pEventDesc[nbEventsRaised].bufferId = INVALID_BUFFER_ID; + pEventDesc[nbEventsRaised].eventTimestamp = (t_sva_timestamp_value) eventTimestamp; + pEventDesc[nbEventsRaised].eventDate = (t_sva_timestamp_value) eventDate; + pEventDesc[nbEventsRaised].extraInfo=0; + nbEventsRaised++; + isUpdateStateNeed=TRUE; + } + + if (GET_FIFO_NB_ELEMS(pDesc->subtasksDependencyFifo)==STILL_ENCODE_SUBTASK_DEFAULT_NUMBER) + { + t_sva_sec_subtask_dependencies subtaskDep; + subtaskDep.subtaskId = subtaskId; + + ffError = READ_FIFO_ELEM(pDesc->subtasksDependencyFifo, t_sva_sec_subtask_dependencies, subtaskDep); + + if (subtaskDep.dependencies.bitstreamBufferDep == RESOLVED_DEPENDENCY) + { + CHECK_TABLE_OVERFLOW(nbEventsRaised, maxOfEvent, SVA_INTERNAL_EVENT_MGT_ERROR); + pEventDesc[nbEventsRaised].eventId = SVA_EVENT_OVERFLOW; + pEventDesc[nbEventsRaised].serviceId = serviceId; + pEventDesc[nbEventsRaised].bufferId = INVALID_BUFFER_ID; + pEventDesc[nbEventsRaised].eventTimestamp = (t_sva_timestamp_value) eventTimestamp; + pEventDesc[nbEventsRaised].eventDate = (t_sva_timestamp_value) eventDate; + pEventDesc[nbEventsRaised].extraInfo=0; + nbEventsRaised++; + + pDesc->status.eventStats.overflowCounter++; + isUpdateStateNeed=TRUE; + } + + if (subtaskDep.dependencies.inputBufferDep == RESOLVED_DEPENDENCY) + { + CHECK_TABLE_OVERFLOW(nbEventsRaised, maxOfEvent, SVA_INTERNAL_EVENT_MGT_ERROR); + pEventDesc[nbEventsRaised].eventId = SVA_EVENT_UNDERFLOW; + pEventDesc[nbEventsRaised].serviceId = serviceId; + pEventDesc[nbEventsRaised].bufferId = INVALID_BUFFER_ID; + pEventDesc[nbEventsRaised].eventTimestamp = (t_sva_timestamp_value) eventTimestamp; + pEventDesc[nbEventsRaised].eventDate = (t_sva_timestamp_value) eventDate; + pEventDesc[nbEventsRaised].extraInfo=0; + nbEventsRaised++; + + pDesc->status.eventStats.underflowCounter++; + isUpdateStateNeed=TRUE; + } + } + if(isUpdateStateNeed==TRUE) + sva_SEC_UpdateInstanceStatesMachine(instanceNum,SVA_SEC_EVENT_EOK); + + break; + default: + break; + } + + + /*try to solve some dependencies*/ + sva_SEC_ResolveDependencies(instanceNum); + + /*return number of generated events*/ + *pNbEvent=nbEventsRaised; + + + return SVA_OK; +} + +/****************************************************************************/ +/* NAME: t_sva_sec_error sva_SEC_ProvideInternalNeeds ( */ +/* t_sva_service_id serviceId */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine allows to end the configuration of the service */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - serviceId: identifier of the service */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_sec_error */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_sva_error sva_SEC_ProvideInternalNeeds( t_sva_service_id serviceId) +{ + + t_sva_sec_error status; + + t_sva_service_instance_num instanceNum = READ_INSTANCE_NUM_IN_SERVICE_ID(serviceId); + t_sva_sec_descriptor *pDesc=&stillEncodeDesc[instanceNum]; + t_sva_still_encoder_configuration *pConf=&pDesc->confHandle.currentConf; + t_sva_ff_error ffError; + t_sva_tm_error tmError; + t_sva_blm_error blmError; + t_sva_error svaError; + t_uint32 i; + t_sva_sec_algo_error algoError; + + + + /*check for service id validity*/ + status=sva_SEC_CheckServiceId(serviceId); + if (status!=SVA_SEC_OK) {return SVA_INTERNAL_STILL_ENCODER_ERROR;} + + /*check that transition is allowed*/ + if (sva_SEC_isTransitionValid(instanceNum,SVA_SEC_INTERNAL_NEEDS)==FALSE) {return SVA_INTERNAL_STILL_ENCODER_ERROR;} + + /*provide some memory to event management*/ + /* ------------------------------------- */ + svaError=sva_EM_ProvideInternalNeeds(serviceId); + if (svaError!=SVA_OK) {return SVA_INTERNAL_STILL_ENCODER_ERROR;} + + + /* create internal fifos */ + /* --------------------- */ + /* inUseSubtasksDependencyFifo + subtasksDependencyFifo */ + CREATE_FIFO(t_sva_sec_subtask_dependencies, STILL_ENCODE_SUBTASK_DEFAULT_NUMBER, pDesc->inUseSubtasksDependencyFifo, ffError); + if (ffError != SVA_FIFO_OK) {return SVA_INTERNAL_STILL_ENCODER_ERROR;} + CREATE_FIFO(t_sva_sec_subtask_dependencies, STILL_ENCODE_SUBTASK_DEFAULT_NUMBER, pDesc->subtasksDependencyFifo, ffError); + if (ffError != SVA_FIFO_OK) {return SVA_INTERNAL_STILL_ENCODER_ERROR;} + + /* bistream */ + CREATE_FIFO(t_sva_buffer_id, PUSH_FIFO_DEFAULT_SIZE, pDesc->bitstreamBufferFifos.pushFifo, ffError); + if (ffError != SVA_FIFO_OK) {return SVA_INTERNAL_STILL_ENCODER_ERROR;} + CREATE_FIFO(t_sva_buffer_id, STILL_ENCODE_SUBTASK_DEFAULT_NUMBER, pDesc->bitstreamBufferFifos.inUseFifo, ffError); + if (ffError != SVA_FIFO_OK) {return SVA_INTERNAL_STILL_ENCODER_ERROR;} + + /* input */ + CREATE_FIFO(t_sva_buffer_id, PUSH_FIFO_DEFAULT_SIZE, pDesc->inputBufferFifos.pushFifo, ffError); + if (ffError != SVA_FIFO_OK) {return SVA_INTERNAL_STILL_ENCODER_ERROR;} + CREATE_FIFO(t_sva_buffer_id, STILL_ENCODE_SUBTASK_DEFAULT_NUMBER, pDesc->inputBufferFifos.inUseFifo, ffError); + if (ffError != SVA_FIFO_OK) {return SVA_INTERNAL_STILL_ENCODER_ERROR;} + + + /* output */ + CREATE_FIFO(t_sva_buffer_id, PUSH_FIFO_DEFAULT_SIZE, pDesc->outputBufferFifos.pushFifo, ffError); + if (ffError != SVA_FIFO_OK) {return SVA_INTERNAL_STILL_ENCODER_ERROR;} + CREATE_FIFO(t_sva_buffer_id, STILL_ENCODE_SUBTASK_DEFAULT_NUMBER, pDesc->outputBufferFifos.inUseFifo, ffError); + if (ffError != SVA_FIFO_OK) {return SVA_INTERNAL_STILL_ENCODER_ERROR;} + + + + + /* Create subtasks */ + /* ---------------- */ + + status = sva_SEC_CreateSubTasksDescriptors(serviceId, STILL_ENCODE_SUBTASK_DEFAULT_NUMBER, pDesc->subtasksIdArray, &pDesc->subtasksListId); + if (status != SVA_SEC_OK) {return SVA_INTERNAL_STILL_ENCODER_ERROR;} + + /* Enable interrupts */ + /* ----------------- */ + tmError=sva_TM_DisableAllVirtualHwEvents(pDesc->subtasksListId); + if (tmError != SVA_TM_OK) {return SVA_INTERNAL_STILL_ENCODER_ERROR;} + tmError=sva_TM_EnableVirtualHwEvents(pDesc->subtasksListId,SVA_TM_EOT_HW_EVENT); + if (tmError != SVA_TM_OK) {return SVA_INTERNAL_STILL_ENCODER_ERROR;} + + tmError=sva_TM_EnableVirtualHwEvents(pDesc->subtasksListId,SVA_TM_EOW_HW_EVENT); + if (tmError != SVA_TM_OK) {return SVA_INTERNAL_STILL_ENCODER_ERROR;} + + tmError=sva_TM_EnableVirtualHwEvents(pDesc->subtasksListId,SVA_TM_ERR_HW_EVENT); + if (tmError != SVA_TM_OK) {return SVA_INTERNAL_STILL_ENCODER_ERROR;} + tmError=sva_TM_EnableVirtualHwEvents(pDesc->subtasksListId,SVA_TM_EOK_HW_EVENT); + if (tmError != SVA_TM_OK) {return SVA_INTERNAL_STILL_ENCODER_ERROR;} + tmError=sva_TM_EnableVirtualHwEvents(pDesc->subtasksListId,SVA_TM_INACTIVE_HW_EVENT); + if (tmError != SVA_TM_OK) {return SVA_INTERNAL_STILL_ENCODER_ERROR;} + tmError=sva_TM_EnableVirtualHwEvents(pDesc->subtasksListId,SVA_TM_ACTIVE_HW_EVENT); + if (tmError != SVA_TM_OK) {return SVA_INTERNAL_STILL_ENCODER_ERROR;} + tmError=sva_TM_EnableVirtualHwEvents(pDesc->subtasksListId,SVA_TM_FAKE_HW_EVENT); + if (tmError != SVA_TM_OK) {return SVA_INTERNAL_STILL_ENCODER_ERROR;} + + + /* AllocateMemoryForParam (in out inout) */ + /* ------------------------------------- */ + status = sva_SEC_AllocateParams(instanceNum); + + /* Build ParamIn, ParamInOut, Header and ConfigureSubTask */ + /* ---------------------------------------------- */ + status = sva_SEC_ConfigureSubTasksParams(serviceId, STILL_ENCODE_SUBTASK_DEFAULT_NUMBER, pConf, pDesc->subtasksIdArray); + + /*call pProvideMemoryNeeds() API : will allocate JPEGRunLevelBuffer if necessary and Configure subtasks*/ + /* ---------------------------- */ + algoError=stillEncodeAlgoDesc[pDesc->algo].pProvideMemoryNeeds(instanceNum, pDesc->subtasksIdArray); + if (algoError!=SVA_SEC_ALGO_OK) {return SVA_INTERNAL_STILL_ENCODER_ERROR;} + + + /* If Image Mode : Create Link Lists */ + /* ---------------------------------- */ + if(pDesc->confHandle.currentConf.mode == SVA_CODEC_IMAGE_MODE) { + + for(i=0;ibitstreamBufferListId[i]); + if (blmError!=SVA_BLM_OK) {return SVA_INTERNAL_STILL_ENCODER_ERROR;} + } + } + + /* push dependencies */ + /* ----------------- */ + for(i=0;isubtasksIdArray[i]; + subtaskDep.dependencies=pDesc->defaultConfiguredDependency; + + if(pDesc->confHandle.currentConf.mode == SVA_CODEC_IMAGE_MODE) + subtaskDep.bufferListId = pDesc->bitstreamBufferListId[i]; + + if (i==0) + { + subtaskDep.dependencies.bitstreamBufferDep=NOT_RESOLVED_DEPENDENCY; + } + ffError=PUSH_FIFO_ELEM(pDesc->subtasksDependencyFifo, t_sva_sec_subtask_dependencies, subtaskDep); + if (ffError!=SVA_FIFO_OK) {return SVA_INTERNAL_STILL_ENCODER_ERROR;} + } + + /* Update the state machine */ + /* ------------------------ */ + sva_SEC_UpdateInstanceStatesMachine(instanceNum,SVA_SEC_INTERNAL_NEEDS); + + + return SVA_OK; +} + + +/****************************************************************************/ +/* NAME: t_sva_sec_error sva_SEC_GetInternalNeeds ( */ +/* t_sva_service_id serviceId */ +/* t_size* pSize */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine returns the size of the memory needed for encode */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - serviceId: identifier of the service */ +/* - pSize: size needed */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_sec_error */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_sva_error sva_SEC_GetInternalNeeds(t_sva_service_id serviceId, t_size * pSize) +{ + + t_sva_sec_error status; + + t_size fifoSize; + + t_sva_service_instance_num instanceNum = READ_INSTANCE_NUM_IN_SERVICE_ID(serviceId); + t_sva_sec_descriptor *pDesc=&stillEncodeDesc[instanceNum]; + t_sva_error svaError; + t_sva_sec_algo_error algoError; + + HCL_ASSERT(pSize != 0); + + *pSize = 0; + + /*check for service id validity*/ + status=sva_SEC_CheckServiceId(serviceId); + if (status!=SVA_SEC_OK) {return SVA_INTERNAL_STILL_ENCODER_ERROR;} + + /*check pointer validity*/ + HCL_ASSERT(pSize!=0); + + /*default dependencies*/ + /* ------------------ */ + pDesc->defaultConfiguredDependency.inputBufferDep=NOT_RESOLVED_DEPENDENCY; + pDesc->defaultConfiguredDependency.bitstreamBufferDep=INTERNAL_DEPENDENCY; + + + if(pDesc->confHandle.currentConf.thumbnailMode == SVA_NON_THUMBNAIL) + pDesc->defaultConfiguredDependency.outputBufferDep=INTERNAL_DEPENDENCY; + else + pDesc->defaultConfiguredDependency.outputBufferDep=NOT_RESOLVED_DEPENDENCY; + + + if ((pDesc->confHandle.currentConf.mode==SVA_CODEC_IMAGE_MODE)||((pDesc->confHandle.currentConf.mode==SVA_CODEC_SEGMENTED_MODE)&&(pDesc->confHandle.currentConf.isSliceMode==FALSE))) + pDesc->defaultConfiguredDependency.bitstreamBufferDep=NOT_RESOLVED_DEPENDENCY; + + /*compute memory size needs*/ + /* ------------------------ */ + + /*memory needed by event management*/ + svaError=sva_EM_GetInternalNeeds(&fifoSize); + if (svaError!=SVA_OK) {return SVA_INTERNAL_STILL_ENCODER_ERROR;} + + *pSize = fifoSize; + + /*call pGetMemoryNeeds() API to get memory need of algo encoder*/ + algoError=stillEncodeAlgoDesc[pDesc->algo].pGetMemoryNeeds(instanceNum, + &fifoSize); + if (algoError!=SVA_SEC_ALGO_OK) {return SVA_INTERNAL_STILL_ENCODER_ERROR;} + + *pSize += fifoSize; + + /* add memory needed by internal fifos */ + /* subtasksDependencyFifo and inUseSubtasksDependencyFifo */ + GET_FIFO_MEMORY_NEEDS(t_sva_sec_subtask_dependencies, STILL_ENCODE_SUBTASK_DEFAULT_NUMBER, fifoSize); + *pSize+=fifoSize; + GET_FIFO_MEMORY_NEEDS(t_sva_sec_subtask_dependencies, STILL_ENCODE_SUBTASK_DEFAULT_NUMBER, fifoSize); + *pSize+=fifoSize; + + /* bitstream */ + GET_FIFO_MEMORY_NEEDS(t_sva_buffer_id, PUSH_FIFO_DEFAULT_SIZE, fifoSize); + *pSize+=fifoSize; + GET_FIFO_MEMORY_NEEDS(t_sva_buffer_id, STILL_ENCODE_SUBTASK_DEFAULT_NUMBER, fifoSize); + *pSize+=fifoSize; + + /* input */ + GET_FIFO_MEMORY_NEEDS(t_sva_buffer_id, PUSH_FIFO_DEFAULT_SIZE, fifoSize); // pushFifo + *pSize+=fifoSize; + GET_FIFO_MEMORY_NEEDS(t_sva_buffer_id, STILL_ENCODE_SUBTASK_DEFAULT_NUMBER, fifoSize); // inUse + *pSize+=fifoSize; + + /* output */ + GET_FIFO_MEMORY_NEEDS(t_sva_buffer_id, PUSH_FIFO_DEFAULT_SIZE, fifoSize); // pushFifo + *pSize+=fifoSize; + GET_FIFO_MEMORY_NEEDS(t_sva_buffer_id, STILL_ENCODE_SUBTASK_DEFAULT_NUMBER, fifoSize); // inUse + *pSize+=fifoSize; + + + + return SVA_OK; +} + + + + + +/****************************************************************************/ +/* NAME: t_sva_sec_error sva_SEC_Activate ( */ +/* t_sva_service_id serviceId */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine activates the STILL_ENCODE service */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - serviceId: identifier of the service */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_sec_error */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_sva_error sva_SEC_Activate(t_sva_service_id serviceId, t_sva_service_mode serviceMode, t_sva_fw_id *pFwId) +{ + + t_sva_service_instance_num instanceNum = READ_INSTANCE_NUM_IN_SERVICE_ID(serviceId); + t_sva_sec_descriptor *pDesc=&stillEncodeDesc[instanceNum]; + t_sva_error status; + t_sva_sec_error secError; + + /*check for service id validity*/ + secError=sva_SEC_CheckServiceId(serviceId); + if (secError!=SVA_SEC_OK) {return SVA_INTERNAL_STILL_ENCODER_ERROR;} + + /*check that transition is allowed*/ + if (sva_SEC_isTransitionValid(instanceNum,SVA_SEC_ACTIVATE)==FALSE) {return SVA_INTERNAL_STILL_ENCODER_ERROR;} + + /* Update the state machine */ + /* Update state machine before command is send to task management to avoid race condition */ + sva_SEC_UpdateInstanceStatesMachine(instanceNum,SVA_SEC_ACTIVATE); + + /*activate subTaskList*/ + status=sva_TM_ActivateSubTaskList(pDesc->subtasksListId,serviceMode,pFwId); + if (status != SVA_OK && status != SVA_FW_SWITCH_OCCURED && status != SVA_FW_SWITCH_DELAYED) + { + sva_SEC_UpdateInstanceStatesMachine(instanceNum,SVA_SEC_CANCEL); + + return status; + } + return status; + + + +} + + + +/****************************************************************************/ +/* NAME: t_sva_sec_error sva_SEC_Inactivate ( */ +/* t_sva_service_id serviceId */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine deactivates the STILL_ENCODE service */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - serviceId: identifier of the service */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_sec_error */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_sva_error sva_SEC_Inactivate(t_sva_service_id serviceId) +{ + + t_sva_sec_error status; + t_sva_service_instance_num instanceNum = READ_INSTANCE_NUM_IN_SERVICE_ID(serviceId); + t_sva_sec_descriptor *pDesc=&stillEncodeDesc[instanceNum]; + t_sva_tm_error tmError; + + /*check for service id validity*/ + status=sva_SEC_CheckServiceId(serviceId); + if (status!=SVA_SEC_OK) {return SVA_INTERNAL_STILL_ENCODER_ERROR;} + + /*check that transition is allowed*/ + if (sva_SEC_isTransitionValid(instanceNum,SVA_SEC_INACTIVATE)==FALSE) {return SVA_INTERNAL_STILL_ENCODER_ERROR;} + + /* Update the state machine */ + /* Update state machine before command is send to task management to avoid race condition */ + sva_SEC_UpdateInstanceStatesMachine(instanceNum,SVA_SEC_INACTIVATE); + + /*inactivate subTaskList*/ + tmError=sva_TM_InActivateSubTaskList(pDesc->subtasksListId); + if (tmError != SVA_TM_OK) + { + sva_SEC_UpdateInstanceStatesMachine(instanceNum,SVA_SEC_CANCEL); + + return SVA_INTERNAL_STILL_ENCODER_ERROR; + } + + return SVA_OK; +} + + + + +/****************************************************************************/ +/* NAME: t_sva_sec_error sva_SEC_Delete ( */ +/* t_sva_service_id serviceId */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine deletes the STILL_ENCODE service */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - serviceId: identifier of the service */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_sec_error */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_sva_error sva_SEC_Delete(t_sva_service_id serviceId) +{ + + t_sva_service_instance_num instanceNum = READ_INSTANCE_NUM_IN_SERVICE_ID(serviceId); + t_sva_sec_descriptor *pDesc=&stillEncodeDesc[instanceNum]; + t_uint32 i; + t_sva_tm_error tmError; + t_sva_error status; + t_sva_sec_error secError; + t_sva_sec_algo_error algoError; + t_sva_blm_error blmError; + + /*check for service id validity*/ + secError=sva_SEC_CheckServiceId(serviceId); + if (secError!=SVA_SEC_OK) {return SVA_INTERNAL_STILL_ENCODER_ERROR;} + + /*check that transition is allowed*/ + if (sva_SEC_isTransitionValid(instanceNum,SVA_SEC_CONTROL_DELETE)==FALSE) {return SVA_UNEXPECTED_API_CALL;} + + + /*check that flush has been done*/ + if (IS_FIFO_EMPTY(pDesc->bitstreamBufferFifos.pushFifo)==FALSE) {return SVA_INTERNAL_STILL_ENCODER_ERROR;} + if (IS_FIFO_EMPTY(pDesc->bitstreamBufferFifos.inUseFifo)==FALSE) {return SVA_INTERNAL_STILL_ENCODER_ERROR;} + if (IS_FIFO_EMPTY(pDesc->inputBufferFifos.pushFifo)==FALSE) {return SVA_INTERNAL_STILL_ENCODER_ERROR;} + if (IS_FIFO_EMPTY(pDesc->inputBufferFifos.inUseFifo)==FALSE) {return SVA_INTERNAL_STILL_ENCODER_ERROR;} + + /*start to delete. Things to do depend of current state*/ + if (pDesc->state==SVA_SEC_WAIT_FOR_ACTIVATE || pDesc->state==SVA_SEC_WAIT_FOR_START) + { + /* delete created blocks */ + secError=sva_SEC_FreeParams(instanceNum); + if (secError!=SVA_SEC_OK) {return SVA_INTERNAL_STILL_ENCODER_ERROR;} + + /* Delete Algo Related stuff */ + algoError=stillEncodeAlgoDesc[pDesc->algo].pDelete(instanceNum); + if (algoError!=SVA_SEC_ALGO_OK) {return SVA_INTERNAL_STILL_ENCODER_ERROR;} + + /*delete fifos*/ + DELETE_FIFO(pDesc->inputBufferFifos.pushFifo); + DELETE_FIFO(pDesc->inputBufferFifos.inUseFifo); + DELETE_FIFO(pDesc->bitstreamBufferFifos.pushFifo); + DELETE_FIFO(pDesc->bitstreamBufferFifos.inUseFifo); + + if(pDesc->confHandle.currentConf.thumbnailMode != SVA_NON_THUMBNAIL) + { + DELETE_FIFO(pDesc->outputBufferFifos.pushFifo); + DELETE_FIFO(pDesc->outputBufferFifos.inUseFifo); + } + + DELETE_FIFO(pDesc->subtasksDependencyFifo); + DELETE_FIFO(pDesc->inUseSubtasksDependencyFifo); + + /*delete subtasklist*/ + tmError=sva_TM_DeleteSubTaskList(pDesc->subtasksListId); + if (tmError!=SVA_TM_OK) {return SVA_INTERNAL_STILL_ENCODER_ERROR;} + /*delete subtasks*/ + for(i=0;isubtasksIdArray[i]); + if (tmError!=SVA_TM_OK) {return SVA_INTERNAL_STILL_ENCODER_ERROR;} + } + + /* delete link lists */ + if (pDesc->confHandle.currentConf.mode == SVA_CODEC_IMAGE_MODE) + { + for(i=0;ibitstreamBufferListId[i]); + if (blmError!=SVA_BLM_OK) {return SVA_INTERNAL_STILL_ENCODER_ERROR;} + } + } + + + + } + + /*delete descriptor use by memory management*/ + status=sva_EM_Delete(serviceId); + if (status!=SVA_OK) {return status;} + + + /* delete link lists */ + if ((pDesc->confHandle.currentConf.mode == SVA_CODEC_STREAM_MODE)||(pDesc->confHandle.currentConf.mode == SVA_CODEC_SEGMENTED_MODE)) + { + blmError=sva_BLM_DeleteBufferList(pDesc->bitstreamBufferListId[0]); + if (blmError!=SVA_BLM_OK) {return SVA_INTERNAL_STILL_ENCODER_ERROR;} + } + + + /* Update the state machine */ + sva_SEC_UpdateInstanceStatesMachine(instanceNum,SVA_SEC_CONTROL_DELETE); + + + return SVA_OK; +} + + + +/****************************************************************************/ +/* NAME: t_sva_sec_error SVA_ConfigureStillImageEncoder ( */ +/* t_sva_service_id serviceId, */ +/* t_sva_still_encoder_configuration stillEncConfig */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine configures a STILL_ENCODE service */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - serviceId: identifier of the service */ +/* - stillEncConfig: configuration of the service */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_sec_error */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_sva_error SVA_ConfigureStillImageEncoder( + t_sva_service_id serviceId, + const t_sva_still_encoder_configuration* pConf + ) +{ + + t_sva_sec_error status; + t_sva_error svaError=SVA_OK; + t_sva_service_instance_num instanceNum = READ_INSTANCE_NUM_IN_SERVICE_ID(serviceId); + t_sva_sec_descriptor *pDesc=&stillEncodeDesc[instanceNum]; + t_sva_sec_algo_error algoError; + t_sva_blm_error blmError; + + /*check for service id validity*/ + status=sva_SEC_CheckServiceId(serviceId); + if (status!=SVA_SEC_OK) {return SVA_INTERNAL_STILL_ENCODER_ERROR;} + + #ifdef __STN_8815 + #if __STN_8815 >= 20 + #else + if (pConf->raster_in_format == TRUE) + { + return SVA_INCOHERENT_CONFIGURATION; + } + #endif + #endif + + /*check that transition is allowed*/ + if (sva_SEC_isTransitionValid(instanceNum, SVA_SEC_CONFIGURE)==FALSE) {return SVA_INTERNAL_STILL_ENCODER_ERROR;} + + /*check pointer validity*/ + HCL_ASSERT(pConf!=0); + + /*check configuration validity*/ + if (sva_SEC_isConfigurationValid(pConf)==FALSE) { + return SVA_INTERNAL_STILL_ENCODER_ERROR; + } + + /*copy it internally*/ + pDesc->confHandle.currentConf=*pConf; + pDesc->confHandle.nextConf=*pConf; + + + + + if ((pConf->mode == SVA_CODEC_STREAM_MODE)|| (pConf->mode == SVA_CODEC_SEGMENTED_MODE)){ + // Create Buffer List : in Stream Mode, only ONE LinkList is used so that itis created in Configure Fonc + // Note that in Image Mode, there are STILL_ENCODE_SUBTASK_DEFAULT_NUMBER LinkList allocated in ProvideInternalNeeds + blmError = sva_BLM_CreateBufferList(&pDesc->bitstreamBufferListId[0]); + if(blmError!=SVA_BLM_OK) {svaError=SVA_INTERNAL_STILL_ENCODER_ERROR;} + else {svaError=SVA_OK;} + } + + /*set algo*/ + switch(pConf->transformId) + { + case SVA_ENCODER_JPEG_MONOCHROME: + pDesc->expectedPushInSize = pConf->sourceFrameDesc.frame.height * pConf->sourceFrameDesc.frame.width; + pDesc->actualPushInSize = pDesc->expectedPushInSize; + + pDesc->algo=SVA_SV_JPEG_ALGO; + break; + case SVA_ENCODER_JPEG_420_SEP_COMP_MB: + pDesc->expectedPushInSize = pConf->sourceFrameDesc.frame.height*pConf->sourceFrameDesc.frame.width+ + ((pConf->sourceFrameDesc.frame.width/2+8)&0xff0)*((pConf->sourceFrameDesc.frame.height/2+8)&0xff0)*2; + pDesc->actualPushInSize = pConf->sourceFrameDesc.frame.height*pConf->sourceFrameDesc.frame.width+ + ((pConf->sourceFrameDesc.frame.width/2))*((pConf->sourceFrameDesc.frame.height/2))*2; + + pDesc->algo=SVA_SV_JPEG_ALGO; + break; + case SVA_ENCODER_JPEG_422_SEP_COMP_MB: + + pDesc->expectedPushInSize = pConf->sourceFrameDesc.frame.height*pConf->sourceFrameDesc.frame.width+ + ((pConf->sourceFrameDesc.frame.width/2+8)&0xff0)*pConf->sourceFrameDesc.frame.height*2; + + pDesc->actualPushInSize = pConf->sourceFrameDesc.frame.height*pConf->sourceFrameDesc.frame.width+ + ((pConf->sourceFrameDesc.frame.width/2))*pConf->sourceFrameDesc.frame.height*2; + + + pDesc->algo=SVA_SV_JPEG_ALGO; + break; + case SVA_ENCODER_JPEG_444_SEP_COMP_MB: + pDesc->expectedPushInSize = 3*pConf->sourceFrameDesc.frame.height * pConf->sourceFrameDesc.frame.width; + pDesc->actualPushInSize = pDesc->expectedPushInSize; + pDesc->algo=SVA_SV_JPEG_ALGO; + break; + + case SVA_ENCODER_JPEG_420_MB: + pDesc->expectedPushInSize = (pConf->sourceFrameDesc.frame.height * pConf->sourceFrameDesc.frame.width)*3/2; + pDesc->actualPushInSize = pDesc->expectedPushInSize; + pDesc->algo=SVA_SV_JPEG_ALGO; + break; + default: + return SVA_INTERNAL_STILL_ENCODER_ERROR; + /*break;*/ + } + + /*call pInitAndConfigure() API to get memory need of algo encoder*/ + algoError=stillEncodeAlgoDesc[pDesc->algo].pInitAndConfigure(instanceNum,pConf); + if (algoError != SVA_SEC_ALGO_OK) { return SVA_INTERNAL_STILL_ENCODER_ERROR;} + + /* Update the states machine */ + sva_SEC_UpdateInstanceStatesMachine(instanceNum,SVA_SEC_CONFIGURE); + + + return svaError; +} + + + +/****************************************************************************/ +/* NAME: void sva_SEC_ResetInstanceDescriptor( */ +/* t_sva_service_instance_num instanceNum */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine initializes the instance descriptor */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - instanceNum: identifier of the Service instance */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: void */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PRIVATE void sva_SEC_ResetInstanceDescriptor(t_sva_service_instance_num instanceNum) +{ + + + + const t_sva_sec_dependencies_desc defaultDepDesc = DEFAULT_INTERNAL_DEPENDENCY; + + + stillEncodeDesc[instanceNum].state = SVA_SEC_NOT_INITIALIZED; + stillEncodeDesc[instanceNum].activateState = SVA_SEC_INACTIVE; + //pDesc->serviceId = 0; + stillEncodeDesc[instanceNum].defaultConfiguredDependency = defaultDepDesc; + stillEncodeDesc[instanceNum].subtasksListId = 0; + stillEncodeDesc[instanceNum].bitstreamBufferNb = 0; + stillEncodeDesc[instanceNum].lastSlice = FALSE; + + // add eotNumber, sliceNumber + stillEncodeDesc[instanceNum].eotNumber=0; + stillEncodeDesc[instanceNum].sliceNumber=0xFF; + + stillEncodeDesc[instanceNum].expectedPushInSize = 0; + stillEncodeDesc[instanceNum].currentPushInSize = 0; + stillEncodeDesc[instanceNum].actualPushInSize = 0; + stillEncodeDesc[instanceNum].currentFrameAndWindowHeight = 0; + stillEncodeDesc[instanceNum].sliceIndex = 0; + stillEncodeDesc[instanceNum].nbBitstreamBuffers = 0; + stillEncodeDesc[instanceNum].previousSize = 0; + stillEncodeDesc[instanceNum].prv_bitstream_offset = 0; + stillEncodeDesc[instanceNum].prv_bitstream_last_byte = 0; + stillEncodeDesc[instanceNum].bufferSizeOnEOW=0; + stillEncodeDesc[instanceNum].bufferOnLastSliceSize=0; + + stillEncodeDesc[instanceNum].debug_count=0; + stillEncodeDesc[instanceNum].eowOccured=FALSE; + stillEncodeDesc[instanceNum].stopOnEowFlag=FALSE; + stillEncodeDesc[instanceNum].stopOnRunningFlag=FALSE; + stillEncodeDesc[instanceNum].bitstreamBufferLastBufferId = 0; + stillEncodeDesc[instanceNum].bitstreamBufferPrevLink = 0; + stillEncodeDesc[instanceNum].bitstreamBufferNextLink = 0; + + /*init fifos*/ + INIT_FIFO(stillEncodeDesc[instanceNum].inUseSubtasksDependencyFifo); + INIT_FIFO(stillEncodeDesc[instanceNum].subtasksDependencyFifo); + INIT_FIFO(stillEncodeDesc[instanceNum].bitstreamBufferFifos.pushFifo); + INIT_FIFO(stillEncodeDesc[instanceNum].bitstreamBufferFifos.inUseFifo); + INIT_FIFO(stillEncodeDesc[instanceNum].inputBufferFifos.pushFifo); + INIT_FIFO(stillEncodeDesc[instanceNum].inputBufferFifos.inUseFifo); + INIT_FIFO(stillEncodeDesc[instanceNum].outputBufferFifos.pushFifo); + INIT_FIFO(stillEncodeDesc[instanceNum].outputBufferFifos.inUseFifo); + + +} + +/****************************************************************************/ +/* NAME: t_sva_sec_state sva_SEC_UpdateInstanceStatesMachine( */ +/* t_sva_service_instance_num instanceNum,*/ +/* t_sva_sec_transition requestedTransition*/ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine allows to update the state machine of a given instance*/ +/* following the given requestedTransition */ +/* */ +/* N.B: This routine returns the new state after the requested transition */ +/* A special return state (SVA_SEC_TRANSITION_REJECTED) is used to check */ +/* the validity of a transition request */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - instanceNum: identifier of the Service instance */ +/* - requestedTransition: identifier of the requested transition */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: t_sva_sec_state */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PRIVATE t_sva_sec_state sva_SEC_UpdateInstanceStatesMachine +( + t_sva_service_instance_num instanceNum, + t_sva_sec_transition requestedTransition + ) +{ + + + t_sva_sec_state nextState; + t_sva_sec_activate_state nextActivateState; + t_sva_sec_descriptor *pDesc = &stillEncodeDesc[instanceNum]; + + + /* Compute the next states */ + nextState=stateMachine[pDesc->state][requestedTransition]; + nextActivateState=activateStateMachine[pDesc->activateState][requestedTransition]; + + /* Check if the transition is valid */ + if (nextState != SVA_SEC_TRANSITION_REJECTED && nextActivateState!=SVA_SEC_ACTIVATE_TRANSITION_REJECTED) + { + /* Update the current states of the instance */ + pDesc->state = nextState; + pDesc->activateState = nextActivateState; + pDesc->status.state=stillEncodeState2ServiceState[pDesc->state]; + + } + + return nextState; + + +} + + +/****************************************************************************/ +/* NAME: t_bool sva_SEC_isTransitionValid( */ +/* t_sva_service_instance_num instanceNum,*/ +/* t_sva_sec_transition requestedTransition*/ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine checks if the requestedTransition is valid */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - instanceNum: identifier of the Service instance */ +/* - requestedTransition: identifier of the requested transition */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: t_bool */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PRIVATE t_bool sva_SEC_isTransitionValid +( + t_sva_service_instance_num instanceNum, + t_sva_sec_transition requestedTransition + ) +{ + + t_sva_sec_state nextState; + t_sva_sec_activate_state nextActivateState; + t_sva_sec_descriptor *pDesc = &stillEncodeDesc[instanceNum]; + + /* Compute the next states */ + nextState=stateMachine[pDesc->state][requestedTransition]; + nextActivateState=activateStateMachine[pDesc->activateState][requestedTransition]; + + /*return false in case of invalid transition for at least one state machine*/ + if (nextState != SVA_SEC_TRANSITION_REJECTED && nextActivateState!=SVA_SEC_ACTIVATE_TRANSITION_REJECTED) {return TRUE;} + else {return FALSE;} + + +} + +/****************************************************************************/ +/* NAME: t_bool sva_SEC_isConfigurationValid( */ +/* const t_sva_still_encoder_configuration *pConf */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will check that given configuration given to grab is */ +/* valid. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - pConf: a pointer to the configuration to check */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: t_bool */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PRIVATE t_bool sva_SEC_isConfigurationValid +( + const t_sva_still_encoder_configuration *pConf +) +{ + if((pConf->raster_in_format==TRUE)&&(pConf->transformId !=SVA_ENCODER_JPEG_420_MB)) + return FALSE; + + if ((pConf->isSliceMode == TRUE)&&(pConf->thumbnailMode == SVA_THUMBNAIL_DC_420MB)) + return FALSE; + + + if((pConf->transformId !=SVA_ENCODER_JPEG_420_MB)&&(pConf->thumbnailMode == SVA_THUMBNAIL_DC_420MB)) + return FALSE; + + CHECK_RANGE0(pConf->mode, SVA_CODEC_IMAGE_MODE, SVA_CODEC_STREAM_MODE); + + return TRUE; +} + + +/****************************************************************************/ +/* NAME: t_sva_sec_error sva_SEC_CheckServiceId(t_sva_service_id serviceId) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will check that task_id and instance number of servideId*/ +/* are both valid */ +/* */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - serviceId: service id to check */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: t_sva_gb_error */ +/* - SVA_SEC_INVALID_INSTANCE_NB : Invalid instance number */ +/* - SVA_SEC_INVALID_TASK_ID_NB : Invalid task id */ +/* - SVA_SEC_OK : Command was executed or is on going */ +/* */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ + +PRIVATE t_sva_sec_error sva_SEC_CheckServiceId(t_sva_service_id serviceId) +{ + t_sva_service_instance_num instanceNum = READ_INSTANCE_NUM_IN_SERVICE_ID(serviceId); + t_sva_sv_task_id taskId = READ_TASK_ID_IN_SERVICE_ID(serviceId); + + if (taskId!=SVA_SV_STILL_ENCODE_TID) {return SVA_SEC_INVALID_TASK_ID_NB;} + if (instanceNum>=NUM_MAX_STILL_ENCODE) {return SVA_SEC_INVALID_INSTANCE_NB;} + + return SVA_SEC_OK; +} + + +/****************************************************************************/ +/* NAME: t_sva_sec_error sva_SEC_ConfigureSubTasksParams( */ +/* t_sva_service_id serviceId */ +/* t_uint8 nbSubtasks */ +/* const t_sva_still_encoder_configuration *pConf,*/ +/* const t_sva_tm_subtask_id *pSubtaskIdArray, */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - nbSubtasks: number of tasks to be created */ +/* - pConf: configuration to support */ +/* - pSubtaskIdArray: array of all created subtasks */ +/* OUT: */ +/* */ +/* RETURN: t_sva_sec_error */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PRIVATE t_sva_sec_error sva_SEC_ConfigureSubTasksParams +( + t_sva_service_id serviceId, + t_uint8 nbSubtasks, + const t_sva_still_encoder_configuration *pConf, + const t_sva_tm_subtask_id *pSubtaskIdArray + ) + { + + t_sva_tm_error tmError; + t_uint8 i; + t_logical_address paramAddr; + t_uint32 size; + t_sva_sec_algo_error algoError; + t_sva_header_buf headerBuffer; + t_sva_service_instance_num instanceNum = READ_INSTANCE_NUM_IN_SERVICE_ID(serviceId); + t_sva_sec_descriptor *pDesc=&stillEncodeDesc[instanceNum]; + + HCL_ASSERT(pSubtaskIdArray != 0); + HCL_ASSERT(pConf != 0); + + /* -- set paramin structure*/ + sva_MM_GetBlockLogicalAddress(pDesc->paramInBlockId, ¶mAddr); + algoError=stillEncodeAlgoDesc[pDesc->algo].pGetFrameParamIn(instanceNum,(t_sva_sec_algo_params_in *)paramAddr); + HCL_DEBUG_ASSERT(algoError==SVA_SEC_ALGO_OK); + size = stillEncodeAlgoDesc[pDesc->algo].pGetParamsInSize(instanceNum); + + for(i=0; iparamInOutBlockId, ¶mAddr); + algoError=stillEncodeAlgoDesc[pDesc->algo].pGetFrameParamInOut(instanceNum,(t_sva_sec_algo_params_inout *)paramAddr); + HCL_DEBUG_ASSERT(algoError==SVA_SEC_ALGO_OK); + size = stillEncodeAlgoDesc[pDesc->algo].pGetParamsInOutSize(instanceNum); + + for(i=0; ialgo][i]; + } + + if(pDesc->confHandle.currentConf.thumbnailMode == SVA_NON_THUMBNAIL) + { + if (pDesc->confHandle.currentConf.raster_in_format == TRUE) + { + subtaskType = SVA_TM_ENCODE_JPEG_RASTER_IN; + } + else + { + subtaskType = SVA_TM_ENCODE_JPEG; + } + } + else + subtaskType =SVA_TM_ENCODE_JPEG_THUMBNAIL; + + + /* Create subtasks */ + for (i=0; i < nbSubtasks; i++) + { + + tmError=sva_TM_CreateSubTask( + SVA_TM_ENCODE, + &stillEncodeTaskDesc, + subtaskType, + SVA_TM_NO_POST_PROCESSING, + SVA_TM_NO_SYNCHRO, + SVA_TM_EOT_EN, + SVA_TM_LINK_LIST_MODE, + &pSubtaskIdArray[i] + ); + + if (tmError != SVA_TM_OK) {return SVA_SEC_TM_LINKED_ERROR;} + + } + + + for(i=0;iconfHandle.currentConf.mode == SVA_CODEC_STREAM_MODE)||((pDesc->confHandle.currentConf.mode == SVA_CODEC_SEGMENTED_MODE)&&(pDesc->confHandle.currentConf.isSliceMode==TRUE))){ + + + tmError=sva_TM_ConnectSubtasksFields(pDesc->subtasksIdArray[(i+nbSubtasks-1)%nbSubtasks], + SVA_TM_ENC_ADDR_OUT_FRAME_PARAMETERS, + pDesc->subtasksIdArray[i], + SVA_TM_ENC_ADDR_IN_FRAME_PARAMETERS); + if (tmError != SVA_TM_OK) {return SVA_SEC_TM_LINKED_ERROR;} + + + + + + + tmError=sva_TM_ConnectSubtasksFields(pDesc->subtasksIdArray[(i+nbSubtasks-1)%nbSubtasks], + SVA_TM_ENC_ADDR_OUT_BITSTREAM_BUFFER, + pDesc->subtasksIdArray[i], + SVA_TM_ENC_ADDR_IN_BITSTREAM_BUFFER); + if (tmError != SVA_TM_OK) {return SVA_SEC_TM_LINKED_ERROR;} + + } + /* for Image+Slice mode */ + if ((pDesc->confHandle.currentConf.mode == SVA_CODEC_IMAGE_MODE)&&(pDesc->confHandle.currentConf.isSliceMode==TRUE)) + { + + tmError=sva_TM_ConnectSubtasksFields(pDesc->subtasksIdArray[(i+nbSubtasks-1)%nbSubtasks], + SVA_TM_ENC_ADDR_OUT_FRAME_PARAMETERS, + pDesc->subtasksIdArray[i], + SVA_TM_ENC_ADDR_IN_FRAME_PARAMETERS); + if (tmError != SVA_TM_OK) {return SVA_SEC_TM_LINKED_ERROR;} + } + } + + + algoError = stillEncodeAlgoDesc[pDesc->algo].pChoseFirmwareFeature(pDesc->algo, &fwFeature); + if (algoError != SVA_SEC_ALGO_OK) {return SVA_SEC_TM_LINKED_ERROR;} + tmError=sva_TM_CreateSubTaskList(SVA_TM_ENCODE, serviceId,fwFeature,&pDesc->subtasksListId); + if (tmError != SVA_TM_OK) {return SVA_SEC_TM_LINKED_ERROR;} + + return SVA_SEC_OK; +} + + + + + +/****************************************************************************/ +/* NAME: t_sva_sec_error sva_SEC_ResetStatus( */ +/* t_sva_still_encoder_status *pStatus */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will reset status descriptor. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - pStatus: status descriptor to reset */ +/* */ +/* OUT: none */ +/* */ +/* RETURN: t_sva_sec_error */ +/* - SVA_SEC_OK */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PRIVATE t_sva_sec_error sva_SEC_ResetStatus +( + t_sva_still_encoder_status *pStatus +) +{ + + HCL_ASSERT(pStatus != 0); + + pStatus->state=SVA_SERVICE_NOT_INITIALIZED; + pStatus->errorId=SVA_STILL_ENCODER_NO_ERROR; + pStatus->nbBytesEncoded=0; + pStatus->nbImagesEncoded=0; + pStatus->eventStats.voidedCounter=0; + pStatus->eventStats.filledCounter=0; + pStatus->eventStats.partlyCounter=0; + pStatus->eventStats.readOnlyCounter=0; + pStatus->eventStats.underflowCounter=0; + pStatus->eventStats.overflowCounter=0; + pStatus->eventStats.errorCounter=0; + pStatus->bufferizationStats.inLevel=0; + pStatus->bufferizationStats.outLevel=0; + + + return SVA_SEC_OK; +} + + +/****************************************************************************/ +/* NAME: t_sva_error sva_SEC_DoFlushIn( */ +/* t_sva_service_id serviceId */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will flush output fifo. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - serviceId: service identifier */ +/* */ +/* OUT: none */ +/* */ +/* RETURN: t_sva_error */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PRIVATE t_sva_error sva_SEC_DoFlushIn +( + t_sva_service_id serviceId +) +{ + + t_sva_service_instance_num instanceNum = READ_INSTANCE_NUM_IN_SERVICE_ID(serviceId); + t_sva_sec_descriptor *pDesc=&stillEncodeDesc[instanceNum]; + t_uint32 systemTime; + t_sva_error svaError; + t_sva_tm_error tmError; + t_sva_sec_subtask_dependencies subtaskDep; + t_sva_ff_error ffError; + t_sva_buffer_id bufferId=INVALID_BUFFER_ID; + t_sva_bm_error bmError; + t_uint32 i; + + /*remove schedule tasks and push them back in subtasksDependencyFifo with default dep*/ + /*so they can be rescheduled */ + do + { + tmError=sva_TM_RemoveElemFromSubTaskList(pDesc->subtasksListId,&subtaskDep.subtaskId); + if (tmError==SVA_TM_OK) + { + /*pop it from in use fifo*/ + ffError=POP_FIFO_ELEM(pDesc->inUseSubtasksDependencyFifo,t_sva_sec_subtask_dependencies,subtaskDep); + if (ffError!=SVA_FIFO_OK) {return SVA_INTERNAL_STILL_ENCODER_ERROR;} + /*reset */ + subtaskDep.dependencies = pDesc->defaultConfiguredDependency; + /*push*/ + ffError=PUSH_FIFO_ELEM(pDesc->subtasksDependencyFifo,t_sva_sec_subtask_dependencies,subtaskDep); + if (ffError!=SVA_FIFO_OK) {return SVA_INTERNAL_STILL_ENCODER_ERROR;} + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + } + } while (tmError==SVA_TM_OK); + + do + { + /* POP the subtasks dependencies if some element are present in * + * inUseSubtasksDependencyFifo i.e. all the dependencies were resolved for * + * this subtask */ + ffError=POP_FIFO_ELEM(pDesc->inUseSubtasksDependencyFifo,t_sva_sec_subtask_dependencies,subtaskDep); + subtaskDep.dependencies.inputBufferDep=pDesc->defaultConfiguredDependency.inputBufferDep; + if (ffError==SVA_FIFO_OK) + { + /* Push them back */ + ffError=PUSH_FIFO_ELEM(pDesc->subtasksDependencyFifo,t_sva_sec_subtask_dependencies,subtaskDep); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + } + } while (ffError==SVA_FIFO_OK); + /* Reset the subtasks dependencies */ + for(i=0;isubtasksDependencyFifo,t_sva_sec_subtask_dependencies,subtaskDep); + /* Reset them to default one */ + subtaskDep.dependencies.inputBufferDep=pDesc->defaultConfiguredDependency.inputBufferDep; + if (ffError==SVA_FIFO_OK) + { + /* Push them back */ + ffError=PUSH_FIFO_ELEM(pDesc->subtasksDependencyFifo,t_sva_sec_subtask_dependencies,subtaskDep); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + } + } + + /*get time*/ + svaError=SVA_GetServiceSystemTime(serviceId,&systemTime); + if (svaError != SVA_OK) {return SVA_INTERNAL_STILL_ENCODER_ERROR;} + + /*flush Input fifo*/ + + while(POP_FIFO_ELEM(pDesc->inputBufferFifos.inUseFifo,t_sva_buffer_id,bufferId) != SVA_FIFO_EMPTY) + { + bmError=sva_BM_UpdateBufferStatus(bufferId,SVA_BUFFER_NOT_USED,systemTime); + if (bmError!=SVA_BM_OK) {return SVA_INTERNAL_STILL_ENCODER_ERROR;} + } + while(POP_FIFO_ELEM(pDesc->inputBufferFifos.pushFifo,t_sva_buffer_id,bufferId) != SVA_FIFO_EMPTY) + { + bmError=sva_BM_UpdateBufferStatus(bufferId,SVA_BUFFER_NOT_USED,systemTime); + if (bmError!=SVA_BM_OK) {return SVA_INTERNAL_STILL_ENCODER_ERROR;} + } + + + + do + { + ffError=POP_REVERSE_FIFO_ELEM(pDesc->bitstreamBufferFifos.inUseFifo,t_sva_buffer_id,bufferId); + if (ffError==SVA_FIFO_OK) + { + ffError=PUSH_REVERSE_FIFO_ELEM(pDesc->bitstreamBufferFifos.pushFifo,t_sva_buffer_id,bufferId); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + } + } while (ffError==SVA_FIFO_OK); + + + return SVA_OK; +} +/****************************************************************************/ +/* NAME: t_sva_error sva_SEC_DoFlushOut( */ +/* t_sva_service_id serviceId */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will flush output fifo. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - serviceId: service identifier */ +/* */ +/* OUT: none */ +/* */ +/* RETURN: t_sva_error */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PRIVATE t_sva_error sva_SEC_DoFlushOut +( + t_sva_service_id serviceId +) +{ + t_sva_service_instance_num instanceNum = READ_INSTANCE_NUM_IN_SERVICE_ID(serviceId); + t_sva_sec_descriptor *pDesc=&stillEncodeDesc[instanceNum]; + t_uint32 systemTime; + t_sva_error svaError; + t_sva_tm_error tmError; + t_sva_sec_subtask_dependencies subtaskDep; + t_sva_ff_error ffError; + t_sva_buffer_id bufferId; + t_sva_bm_error bmError; + t_sva_blm_error blmError; + t_uint32 i; + + + /*remove schedule tasks and push them back in subtasksDependencyFifo with default dep*/ + /*so they can be rescheduled */ + do + { + tmError=sva_TM_RemoveElemFromSubTaskList(pDesc->subtasksListId,&subtaskDep.subtaskId); + if (tmError==SVA_TM_OK) + { + + /*pop it from in use fifo*/ + ffError=POP_FIFO_ELEM(pDesc->inUseSubtasksDependencyFifo,t_sva_sec_subtask_dependencies,subtaskDep); + if (ffError!=SVA_FIFO_OK) {return SVA_INTERNAL_STILL_ENCODER_ERROR;} + /*reset */ + subtaskDep.dependencies = pDesc->defaultConfiguredDependency; + /* push */ + ffError=PUSH_FIFO_ELEM(pDesc->subtasksDependencyFifo,t_sva_sec_subtask_dependencies,subtaskDep); + if (ffError!=SVA_FIFO_OK) {return SVA_INTERNAL_STILL_ENCODER_ERROR;} + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + } + } while (tmError==SVA_TM_OK); + + do + { + /* POP the subtasks dependencies if some element are present in * + * inUseSubtasksDependencyFifo i.e. all the dependencies were resolved for * + * this subtask */ + ffError=POP_FIFO_ELEM(pDesc->inUseSubtasksDependencyFifo,t_sva_sec_subtask_dependencies,subtaskDep); + subtaskDep.dependencies.bitstreamBufferDep=pDesc->defaultConfiguredDependency.bitstreamBufferDep; + subtaskDep.dependencies.outputBufferDep=pDesc->defaultConfiguredDependency.outputBufferDep; + if (ffError==SVA_FIFO_OK) + { + /* Push them back */ + ffError=PUSH_FIFO_ELEM(pDesc->subtasksDependencyFifo,t_sva_sec_subtask_dependencies,subtaskDep); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + } + } while (ffError==SVA_FIFO_OK); + /* Reset the subtasks dependencies */ + for(i=0;isubtasksDependencyFifo,t_sva_sec_subtask_dependencies,subtaskDep); + subtaskDep.dependencies.bitstreamBufferDep=pDesc->defaultConfiguredDependency.bitstreamBufferDep; + subtaskDep.dependencies.outputBufferDep=pDesc->defaultConfiguredDependency.outputBufferDep; + if (ffError==SVA_FIFO_OK) + { + /* Push them back */ + ffError=PUSH_FIFO_ELEM(pDesc->subtasksDependencyFifo,t_sva_sec_subtask_dependencies,subtaskDep); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + } + } + + /*get time*/ + svaError=SVA_GetServiceSystemTime(serviceId,&systemTime); + if (svaError != SVA_OK) {return SVA_INTERNAL_STILL_ENCODER_ERROR;} + + /*flush fifo*/ + while(POP_FIFO_ELEM(pDesc->bitstreamBufferFifos.inUseFifo,t_sva_buffer_id,bufferId) != SVA_FIFO_EMPTY) + { + bmError=sva_BM_UpdateBufferStatus(bufferId,SVA_BUFFER_NOT_USED,systemTime); + if (bmError!=SVA_BM_OK) {return SVA_INTERNAL_POSTPROCESSOR_ERROR;} + } + + + if(pDesc->confHandle.currentConf.thumbnailMode != SVA_NON_THUMBNAIL) + { + while(POP_FIFO_ELEM(pDesc->outputBufferFifos.pushFifo,t_sva_buffer_id,bufferId) != SVA_FIFO_EMPTY) + { + bmError=sva_BM_UpdateBufferStatus(bufferId,SVA_BUFFER_NOT_USED,systemTime); + if (bmError!=SVA_BM_OK) {return SVA_INTERNAL_POSTPROCESSOR_ERROR;} + } + /* patch for VI12471 We need to pop the in use outputput buffer as well other wise we may get an assertion failure */ + while(POP_FIFO_ELEM(pDesc->outputBufferFifos.inUseFifo,t_sva_buffer_id,bufferId) != SVA_FIFO_EMPTY) + { + bmError=sva_BM_UpdateBufferStatus(bufferId,SVA_BUFFER_NOT_USED,systemTime); + if (bmError!=SVA_BM_OK) {return SVA_INTERNAL_POSTPROCESSOR_ERROR;} + } + } + + + /* not to do yet for != CODEC_IMAGE_MODE */ + + if (pDesc->confHandle.currentConf.mode == SVA_CODEC_IMAGE_MODE) + { + + while(POP_FIFO_ELEM(pDesc->bitstreamBufferFifos.pushFifo,t_sva_buffer_id,bufferId) != SVA_FIFO_EMPTY) + { + bmError=sva_BM_UpdateBufferStatus(bufferId,SVA_BUFFER_NOT_USED,systemTime); + if (bmError!=SVA_BM_OK) {return SVA_INTERNAL_POSTPROCESSOR_ERROR;} + } + } + + /* remove buffer from bufferListId if necessary */ + + /* delete link lists */ + if ((pDesc->confHandle.currentConf.mode == SVA_CODEC_STREAM_MODE)||(pDesc->confHandle.currentConf.mode == SVA_CODEC_SEGMENTED_MODE)) + { + do { + blmError=sva_BLM_RemoveBufferFromList(pDesc->bitstreamBufferListId[0],&bufferId); + } while (blmError==SVA_BLM_OK); } + else // Image Mode + { + t_uint16 i; + for(i=0;ibitstreamBufferListId[i],&bufferId); + } while (blmError==SVA_BLM_OK); + } + } + + + + + return SVA_OK; +} + + +/****************************************************************************/ +/* NAME: t_sva_sec_error sva_SEC_ResolveDependencies( */ +/* t_sva_service_instance_num instanceNum */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine tries to resolve any external pending dependencies */ +/* by checking data availability into push fifos */ +/* PARAMETERS: */ +/* IN : */ +/* - instanceNum: identifier of the Service instance */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: t_sva_sec_error */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PRIVATE t_sva_sec_error sva_SEC_ResolveDependencies(t_sva_service_instance_num instanceNum) +{ + + t_sva_sec_descriptor *pDesc=&stillEncodeDesc[instanceNum]; + t_sva_sec_subtask_dependencies subTaskDep; + t_sva_buffer_id bufferId; + t_sva_ff_error ffError=SVA_FIFO_OK; + t_sva_tm_error tmError=SVA_TM_OK; + t_bool dependencyNotSolved=FALSE; + t_sva_blm_error blmError= SVA_BLM_OK; + + while(IS_FIFO_EMPTY(pDesc->subtasksDependencyFifo)==FALSE && dependencyNotSolved==FALSE) + { + ffError=READ_FIFO_ELEM(pDesc->subtasksDependencyFifo,t_sva_sec_subtask_dependencies,subTaskDep); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + + /* input buffer dependencies */ + /* ------------------------- */ + if (subTaskDep.dependencies.inputBufferDep==NOT_RESOLVED_DEPENDENCY) + { + if (POP_FIFO_ELEM(pDesc->inputBufferFifos.pushFifo,t_sva_buffer_id,bufferId) != SVA_FIFO_EMPTY) + { + t_sva_vec_frame_buffer_in bufferIn; + + /*we can solve source buffer dependencies so just do it*/ + ffError=PUSH_FIFO_ELEM(pDesc->inputBufferFifos.inUseFifo,t_sva_buffer_id,bufferId); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + /*note that source buffer dependencies is solved*/ + ffError=UPDATE_FIFO_ELEM_FIELD(pDesc->subtasksDependencyFifo, + t_sva_sec_subtask_dependencies, .dependencies.inputBufferDep, + RESOLVED_DEPENDENCY); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + subTaskDep.dependencies.inputBufferDep = RESOLVED_DEPENDENCY; + /*update field in the task list*/ + sva_BM_GetBufferPhysicalAddress(bufferId, &bufferIn.addr_source_buffer); + tmError=sva_TM_UpdateSubTaskField(SVA_TM_ONLY_ONE_FIELD_TO_UPDATE, + subTaskDep.subtaskId, + SVA_TM_ENC_ADDR_IN_FRAME_BUFFER, + FCMD_COPY, + (t_uint32) &bufferIn, + 0, + 4); + HCL_DEBUG_ASSERT(tmError==SVA_TM_OK); + + + /* if new image restart_mcu_count reinit */ + if(pDesc->sliceIndex==1) + { + + t_size size; + t_uint16 i; + t_uint32 paramAddr; + + /* -- set paraminout structure*/ + sva_MM_GetBlockLogicalAddress(pDesc->paramInOutBlockId, ¶mAddr); + stillEncodeAlgoDesc[pDesc->algo].pGetFrameParamInOut(instanceNum,(t_sva_sec_algo_params_inout *)paramAddr); + size = stillEncodeAlgoDesc[pDesc->algo].pGetParamsInOutSize(instanceNum); + + for(i=0; iconfHandle.currentConf.isSliceMode == TRUE) + { + tmError=sva_TM_UpdateSubTaskField(SVA_TM_ONLY_ONE_FIELD_TO_UPDATE,subTaskDep.subtaskId,SVA_TM_ENC_ADDR_IN_PARAMETERS,FCMD_COPY,(t_uint32)&(pDesc->newFrameAndWindowHeight),2,2); + tmError=sva_TM_UpdateSubTaskField(SVA_TM_ONLY_ONE_FIELD_TO_UPDATE,subTaskDep.subtaskId,SVA_TM_ENC_ADDR_IN_PARAMETERS,FCMD_COPY,(t_uint32)&(pDesc->newFrameAndWindowHeight),6,2); + } + + if(pDesc->currentPushInSize == pDesc->expectedPushInSize) + { + t_uint32 offset; + t_size size; + t_uint16 value = 0x01; + + pDesc->currentPushInSize = 0; + pDesc->sliceIndex = 0; + + size = stillEncodeAlgoDesc[pDesc->algo].pGetLastSliceOffsetAndSize(instanceNum,&offset); + tmError = sva_TM_UpdateSubTaskField(SVA_TM_ONLY_ONE_FIELD_TO_UPDATE, + subTaskDep.subtaskId, + SVA_TM_ENC_ADDR_IN_PARAMETERS, + FCMD_COPY, + (t_uint32)&value, + 2*offset, + size); + HCL_DEBUG_ASSERT(tmError==SVA_TM_OK); + + + } + + } + } + + /* output buffer dependancies */ + /* -------------------------- */ + if (subTaskDep.dependencies.outputBufferDep==NOT_RESOLVED_DEPENDENCY) + { + if (POP_FIFO_ELEM(pDesc->outputBufferFifos.pushFifo,t_sva_buffer_id,bufferId) != SVA_FIFO_EMPTY) + { + t_sva_vec_frame_buffer_out bufferOut; + + /*we can solve source buffer dependencies so just do it*/ + ffError=PUSH_FIFO_ELEM(pDesc->outputBufferFifos.inUseFifo,t_sva_buffer_id,bufferId); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + + /* upadte resolved*/ + ffError=UPDATE_FIFO_ELEM_FIELD(pDesc->subtasksDependencyFifo, + t_sva_sec_subtask_dependencies, .dependencies.outputBufferDep, + RESOLVED_DEPENDENCY); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + subTaskDep.dependencies.outputBufferDep = RESOLVED_DEPENDENCY; + + /*update field in the task list*/ + sva_BM_GetBufferPhysicalAddress(bufferId, &bufferOut.addr_dest_buffer); + tmError=sva_TM_UpdateSubTaskField(SVA_TM_ONLY_ONE_FIELD_TO_UPDATE, + subTaskDep.subtaskId, + SVA_TM_ENC_ADDR_OUT_FRAME_BUFFER, + FCMD_COPY, + (t_uint32) &bufferOut, + 0, + 4); + HCL_DEBUG_ASSERT(tmError==SVA_TM_OK); + + } + + } + + + /* bitstream buffer dependancies */ + /* ----------------------------- */ + if (subTaskDep.dependencies.bitstreamBufferDep==NOT_RESOLVED_DEPENDENCY) + { + if (POP_FIFO_ELEM(pDesc->bitstreamBufferFifos.pushFifo,t_sva_buffer_id,bufferId) != SVA_FIFO_EMPTY) + { + + t_sva_bitstream_buffer_pos bufferInPosition; + t_uint32 addr_bitstream_buf_struct; + + + /*we can solve info buffer dependencies so just do it*/ + + /*note that bitstream buffer dependencies is solved*/ + ffError=UPDATE_FIFO_ELEM_FIELD(pDesc->subtasksDependencyFifo, + t_sva_sec_subtask_dependencies, .dependencies.bitstreamBufferDep, + RESOLVED_DEPENDENCY); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + subTaskDep.dependencies.bitstreamBufferDep = RESOLVED_DEPENDENCY; + + /*update field in the task list*/ + sva_BM_GetBufferPhysicalAddress(bufferId, &bufferInPosition.addr_bitstream_start); + pDesc->bistreamStartAddress = bufferInPosition.addr_bitstream_start; + + if((pDesc->confHandle.currentConf.mode == SVA_CODEC_STREAM_MODE)||(pDesc->confHandle.currentConf.mode == SVA_CODEC_SEGMENTED_MODE)) + { + ffError=PUSH_FIFO_ELEM(pDesc->bitstreamBufferFifos.pushFifo,t_sva_buffer_id,bufferId); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + + blmError=sva_BLM_GetBufferListPhysicalAddress(pDesc->bitstreamBufferListId[0], &addr_bitstream_buf_struct); + HCL_DEBUG_ASSERT(blmError==SVA_BLM_OK); + } + else // Image Mode + { + + ffError=PUSH_FIFO_ELEM(pDesc->bitstreamBufferFifos.inUseFifo,t_sva_buffer_id,bufferId); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + + + blmError=sva_BLM_AddBufferInList(subTaskDep.bufferListId,bufferId); + HCL_DEBUG_ASSERT(blmError==SVA_BLM_OK); + + blmError=sva_BLM_GetBufferListPhysicalAddress(subTaskDep.bufferListId,&addr_bitstream_buf_struct); + HCL_DEBUG_ASSERT(blmError==SVA_BLM_OK); + } + + bufferInPosition.addr_bitstream_buf_struct = addr_bitstream_buf_struct|0x00000001; + bufferInPosition.bitstream_offset = 0; + if((pDesc->confHandle.currentConf.isSliceMode == TRUE) && (pDesc->prv_bitstream_offset != 0)) + { + t_uint8 *src_addr; + t_logical_address bitstream_logical_addr; + sva_BM_GetBufferLogicalAddress(bufferId, &bitstream_logical_addr); + src_addr = (t_uint8*)bitstream_logical_addr; + *src_addr = pDesc->prv_bitstream_last_byte; + bufferInPosition.bitstream_offset = pDesc->prv_bitstream_offset; + pDesc->prv_bitstream_offset = 0x0; + pDesc->prv_bitstream_last_byte = 0x0; + } + tmError=sva_TM_InitSubTaskField(subTaskDep.subtaskId,SVA_TM_ENC_ADDR_IN_BITSTREAM_BUFFER,(t_uint32)&bufferInPosition,sizeof(t_sva_bitstream_buffer_pos)); + HCL_DEBUG_ASSERT(tmError==SVA_TM_OK); + + + } + } + + /*if all dependencies solved then remove subtask from subtasksDependencyFifo and increment task counter*/ + if (subTaskDep.dependencies.inputBufferDep!=NOT_RESOLVED_DEPENDENCY && + subTaskDep.dependencies.bitstreamBufferDep!=NOT_RESOLVED_DEPENDENCY && + subTaskDep.dependencies.outputBufferDep!=NOT_RESOLVED_DEPENDENCY) + { + t_sva_tm_timestamp immediateTimeStamp={SVA_TM_IMMEDIATE,0}; + + ffError=POP_FIFO_ELEM(pDesc->subtasksDependencyFifo,t_sva_sec_subtask_dependencies,subTaskDep); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + + ffError=PUSH_FIFO_ELEM(pDesc->inUseSubtasksDependencyFifo,t_sva_sec_subtask_dependencies,subTaskDep); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + + sva_SEC_UpdateInstanceStatesMachine(instanceNum,SVA_SEC_ALL_DEPENDENCIES_RESOLVED); + + tmError=sva_TM_AddElemToSubTaskList(pDesc->subtasksListId,subTaskDep.subtaskId, &immediateTimeStamp, 1); + HCL_DEBUG_ASSERT(tmError==SVA_TM_OK); + } + else {dependencyNotSolved=TRUE;} + } + + return SVA_SEC_OK; +} + + + +/****************************************************************************/ +/* NAME: t_sva_sec_error sva_SEC_AllocateParams( */ +/* t_sva_service_instance_num instanceNum */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* */ +/* OUT: none */ +/* */ +/* RETURN: void */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PRIVATE t_sva_sec_error sva_SEC_AllocateParams(t_sva_service_instance_num instanceNum) { + + t_sva_sec_descriptor *pDesc=&stillEncodeDesc[instanceNum]; + t_sva_mm_error mmError; + t_size memSize; + + /*allocate internal memory for paramIn/paramOut/paramInOut mng*/ + memSize=stillEncodeAlgoDesc[pDesc->algo].pGetParamsInSize(instanceNum); + mmError=sva_MM_AllocBlock(SDRAM_ID,memSize,SVA_MM_ALIGN_WORD, &pDesc->paramInBlockId); + if (mmError != SVA_MM_OK) {return(SVA_SEC_MM_LINKED_ERROR);} + memSize=stillEncodeAlgoDesc[pDesc->algo].pGetParamsOutSize(instanceNum); + mmError=sva_MM_AllocBlock(SDRAM_ID,memSize,SVA_MM_ALIGN_WORD, &pDesc->paramOutBlockId); + if (mmError != SVA_MM_OK) {return(SVA_SEC_MM_LINKED_ERROR);} + memSize=stillEncodeAlgoDesc[pDesc->algo].pGetParamsInOutSize(instanceNum); + mmError=sva_MM_AllocBlock(SDRAM_ID,memSize,SVA_MM_ALIGN_WORD, &pDesc->paramInOutBlockId); + if (mmError != SVA_MM_OK) {return(SVA_SEC_MM_LINKED_ERROR);} + + return SVA_SEC_OK; +} + +/****************************************************************************/ +/* NAME: t_sva_sec_error sva_SEC_FreeParams( */ +/* t_sva_service_instance_num instanceNum */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* */ +/* OUT: none */ +/* */ +/* RETURN: void */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PRIVATE t_sva_sec_error sva_SEC_FreeParams(t_sva_service_instance_num instanceNum) { + t_sva_sec_descriptor *pDesc=&stillEncodeDesc[instanceNum]; + t_sva_mm_error mmError; + + + mmError=sva_MM_FreeBlock(pDesc->paramInBlockId); + if (mmError != SVA_MM_OK) {return(SVA_SEC_MM_LINKED_ERROR);} + + mmError=sva_MM_FreeBlock(pDesc->paramOutBlockId); + if (mmError != SVA_MM_OK) {return(SVA_SEC_MM_LINKED_ERROR);} + + mmError=sva_MM_FreeBlock(pDesc->paramInOutBlockId); + if (mmError != SVA_MM_OK) {return(SVA_SEC_MM_LINKED_ERROR);} + + return SVA_SEC_OK; + +} + +/****************************************************************************/ +/* NAME: t_sva_sec_error sva_SEC_HandleFakeEvent( */ +/* */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* */ +/* OUT: none */ +/* */ +/* RETURN: void */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PRIVATE t_sva_error sva_SEC_HandleFakeEvent( t_sva_tm_virtual_hw_event_id eventId, + t_sva_service_id serviceId, + t_sva_tm_subtask_id subtaskId, + t_uint32 eventTimestamp, + t_uint32 eventDate, + t_uint8 maxOfEvent, + t_uint32 *pNbEventsRaised, + t_sva_event_desc *pEventDesc) { + + + + t_sva_ff_error ffError = SVA_FIFO_OK; + t_sva_service_instance_num instanceNum = READ_INSTANCE_NUM_IN_SERVICE_ID(serviceId); + t_sva_sec_descriptor *pDesc=&stillEncodeDesc[instanceNum]; + t_uint32 nbEvents = *pNbEventsRaised; + t_sva_event_desc *pEvent; + t_sva_buffer_id bufferId; + t_uint32 systemTime; + t_sva_bm_error bmError; + + pEvent = &pEventDesc[nbEvents]; + systemTime = 0; //For removing compiler warning + + if((pDesc->state== SVA_SEC_FLUSHING_OUT)&&(pDesc->confHandle.currentConf.mode != SVA_CODEC_IMAGE_MODE)) + { + + + if(!IS_FIFO_EMPTY(pDesc->bitstreamBufferFifos.pushFifo)) + { + + CHECK_TABLE_OVERFLOW(*pNbEventsRaised, maxOfEvent, SVA_INTERNAL_EVENT_MGT_ERROR); + pEvent->eventId = SVA_EVENT_BUFFER_FILLED; + pEvent->serviceId = serviceId; + pEvent->eventTimestamp = (t_sva_timestamp_value) eventTimestamp; + pEvent->eventDate = (t_sva_timestamp_value) eventDate; + /* For SVA_CODEC_SEGMENTED_MODE last buffer need not to be indicated */ + if(pDesc->confHandle.currentConf.mode == SVA_CODEC_SEGMENTED_MODE ) + { + pEvent->extraInfo = 0; + pEvent->extraInfo2 = 0;; + } + /* For SVA_CODEC_STREAM_MODE last buffer need to be indicated */ + else + { + pEvent->extraInfo = pDesc->lastPartlyFilledSize; + pEvent->extraInfo2 = 1; + } + + /* Get bufferId */ + ffError=POP_FIFO_ELEM(pDesc->bitstreamBufferFifos.pushFifo, t_sva_buffer_id,pEvent->bufferId); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + sva_BM_UpdateBufferStatus(pEvent->bufferId,SVA_BUFFER_FILLED,eventTimestamp); + nbEvents++; + pEvent = &pEventDesc[nbEvents]; + + pDesc->status.eventStats.filledCounter++; + + + *pNbEventsRaised=nbEvents; + + } + + /* flush out others */ + while(POP_FIFO_ELEM(pDesc->bitstreamBufferFifos.pushFifo,t_sva_buffer_id,bufferId) != SVA_FIFO_EMPTY) + { + bmError=sva_BM_UpdateBufferStatus(bufferId,SVA_BUFFER_NOT_USED,systemTime); + if (bmError!=SVA_BM_OK) {return SVA_INTERNAL_POSTPROCESSOR_ERROR;} + } + + } + + return SVA_OK; + +} + +/****************************************************************************/ +/* NAME: t_sva_sec_error sva_SEC_GetBufferIdFromPhysicalAddress( */ +/* t_physical_address, t_sva_buffer_id*); */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* */ +/* OUT: none */ +/* */ +/* RETURN: void */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* +PRIVATE t_sva_sec_error sva_SEC_GetBufferIdFromPhysicalAddress(t_sva_service_instance_num instanceNum, t_physical_address address, t_sva_buffer_id * pId) { + t_uint16 i; + t_sva_sec_descriptor *pDesc=&stillEncodeDesc[instanceNum]; + HCL_ASSERT(pId != 0); + + for (i = 0; ibitstreamBufferDesc[i].bufferAddress == address) { + *pId = pDesc->bitstreamBufferDesc[i].bufferId; + return SVA_SEC_OK; + } + } + return SVA_SEC_OK; +} +*/ --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_encode/sva_still_encode.h @@ -0,0 +1,96 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ + +#ifndef __INC_SVA_STILLENCODE_H +#define __INC_SVA_STILLENCODE_H + + +#include "hcl_defs.h" +#include "sva.h" +#include "svap.h" +#include "sva_service.h" +#include "sva_taskmgt.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + +/* + * Define the symbols used to identify the number of encoder service + */ +#define SVA_SEC_NUMBER_OF_ALGO_SUPPORTED 5 + +/* + * Define the symbols used to identify the number of encoder service + */ +typedef t_sva_service_instance_num t_sva_still_encoder_instance_num; + + +/* + * Define the symbols used to identify the various errors of the Still Encode Module + */ + +typedef enum { + SVA_SEC_INVALID_TRANSITION = SVA_SEC_LAST_ERROR, + SVA_SEC_NO_MORE_AVAILABLE_INSTANCE, + SVA_SEC_INVALID_INSTANCE_NB, + SVA_SEC_INVALID_TASK_ID_NB, + SVA_SEC_NOT_SUPPORTED, + SVA_SEC_INVALID_CONTROL_PARAM, + SVA_SEC_INVALID_PUSH, + SVA_SEC_INVALID_BUFFER_TYPE, + SVA_SEC_INVALID_BUFFER_SIZE, + SVA_SEC_INVALID_CONFIGURATION, + SVA_SEC_UNKNOWN_CMD_ID, + SVA_SEC_UNEXPECTED_HW_EVENT, + SVA_SEC_SYNCHRO_INFO_NOT_AVAILABLE, + SVA_SEC_TI_LINKED_ERROR, + SVA_SEC_BM_LINKED_ERROR, + SVA_SEC_MM_LINKED_ERROR, + SVA_SEC_FF_LINKED_ERROR, + SVA_SEC_TM_LINKED_ERROR, + SVA_SEC_NULL_POINTER_PARAMETER, + SVA_SEC_FIFO_NOT_EMPTY, + SVA_SEC_OK = HCL_OK +} t_sva_sec_error; + + +/******************************************************************************* +* PUBLIC Functions +*******************************************************************************/ + +PUBLIC t_sva_error sva_SEC_Init( void ); +PUBLIC t_sva_error sva_SEC_Reset( t_sva_service_id ); +PUBLIC t_sva_error sva_SEC_Create( t_sva_service_id *); +PUBLIC t_sva_error sva_SEC_Control(t_sva_service_id, t_sva_service_cmd_id, t_uint32 ); +PUBLIC t_sva_error sva_SEC_Push(t_sva_service_id, t_sva_buffer_id, t_sva_push_mode, t_sva_buffer_type, t_sva_timestamp ); +PUBLIC t_sva_error sva_SEC_DispatchVirtualHwEvent(t_sva_tm_virtual_hw_event_id, t_sva_service_id, t_sva_tm_subtask_id, t_uint32, t_uint32, t_uint8, t_sva_event_desc *, t_uint32 *); +PUBLIC t_sva_error sva_SEC_ProvideInternalNeeds( t_sva_service_id); +PUBLIC t_sva_error sva_SEC_GetInternalNeeds(t_sva_service_id, t_size *); +PUBLIC t_sva_error sva_SEC_Activate(t_sva_service_id, t_sva_service_mode, t_sva_fw_id *); +PUBLIC t_sva_error sva_SEC_Inactivate(t_sva_service_id); +PUBLIC t_sva_error sva_SEC_Delete(t_sva_service_id ); + + +#ifdef __cplusplus +} /* allow C++ to use these headers */ +#endif /* __cplusplus */ + +#endif --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_encode/sva_still_encodep.h @@ -0,0 +1,248 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ + +#ifndef __INC_SVA_STILLENCODEP_H +#define __INC_SVA_STILLENCODEP_H + +#include "hcl_defs.h" +#include "sva.h" +#include "sva_still_encode.h" +#include "sva_taskmgt.h" +#include "sva_fifo.h" +#include "sva_service.h" +#include "sva_bufferlistmgt.h" + + +/* + * Define the number of field inside a Still Encode Subtask descriptor (spec v0.93) + */ +#define STILL_ENCODE_FIELD_NUMBER 10 + +/* + * Define the default memory used to store subtasks descriptors + */ +#define STILL_ENCODE_DEFAULT_MEMORY_ID SDRAM_ID + +/* + * Define the default memory used to store param_out (infos) data + */ +#define STILL_ENCODE_DEFAULT_INFOS_MEMORY_ID SDRAM_ID + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/******************************************************************************/ +/* Types definitions */ +/******************************************************************************/ + + +/* + * Define the various state of a Grab instance service + */ +typedef enum { + SVA_SEC_NOT_INITIALIZED, + SVA_SEC_WAIT_FOR_CONFIGURATION, + SVA_SEC_WAIT_FOR_INTERNAL_NEEDS, + SVA_SEC_WAIT_FOR_ACTIVATE, + SVA_SEC_WAIT_FOR_START, + SVA_SEC_FLUSHING_IN, + SVA_SEC_FLUSHING_OUT, + SVA_SEC_WAIT_FOR_DATA, + SVA_SEC_RUNNING, + SVA_SEC_ABORT_REQUESTED, + SVA_SEC_STOP_REQUESTED, + SVA_SEC_ERROR, + SVA_SEC_WAIT_FOR_DATA_EOW, + SVA_SEC_LAST_DUMMY_STATE, + SVA_SEC_TRANSITION_REJECTED +} t_sva_sec_state; + +/* + * Define the various activate state of a Grab instance service + */ +typedef enum { + SVA_SEC_INACTIVE, + SVA_SEC_IN_ACTIVATION, + SVA_SEC_ACTIVE, + SVA_SEC_IN_INACTIVATION, + SVA_SEC_LAST_ACTIVATE_DUMMY_STATE, + SVA_SEC_ACTIVATE_TRANSITION_REJECTED +} t_sva_sec_activate_state; + +/* + * Define the various transitions of the encode service + */ +typedef enum { + SVA_SEC_CREATE, + SVA_SEC_CONFIGURE, + SVA_SEC_INTERNAL_NEEDS, + SVA_SEC_ACTIVATE, + SVA_SEC_INACTIVATE, + SVA_SEC_CONTROL_START, + SVA_SEC_CONTROL_STOP, + SVA_SEC_CONTROL_ABORT, + SVA_SEC_ALL_DEPENDENCIES_RESOLVED, + SVA_SEC_PUSH, + SVA_SEC_EVENT_EOK, + SVA_SEC_EVENT_FAKE, + SVA_SEC_EVENT_ACTIVE, + SVA_SEC_EVENT_INACTIVE, + SVA_SEC_RESET, + SVA_SEC_CONTROL_DELETE, + SVA_SEC_EVENT_ERROR, + SVA_SEC_FLUSH_IN, + SVA_SEC_FLUSH_OUT, + SVA_SEC_CANCEL, + SVA_SEC_UPDATE_PARAM, + SVA_SEC_EVENT_EOW, + SVA_SEC_LAST_DUMMY_TRANSITION +} t_sva_sec_transition; + + + +/* + * Define the symbol used to qualify the state of the dependency + * for a given type of buffer + */ +typedef enum { + INTERNAL_DEPENDENCY, + NOT_RESOLVED_DEPENDENCY, + RESOLVED_DEPENDENCY +} t_sva_sec_dependencies_state; + +/* + * Define the structure used to manage the subtasks dependency + */ +typedef struct { + t_bitfield inputBufferDep:2; + t_bitfield outputBufferDep:2; + t_bitfield bitstreamBufferDep:2; +} t_sva_sec_dependencies_desc; + +#define DEFAULT_INTERNAL_DEPENDENCY {INTERNAL_DEPENDENCY, INTERNAL_DEPENDENCY, INTERNAL_DEPENDENCY} + + +/* + * Define the structure used to manage the dependencies of each subtasks + */ +typedef struct { +t_sva_tm_subtask_id subtaskId; +t_sva_sec_dependencies_desc dependencies; +t_sva_buffer_list_id bufferListId; +} t_sva_sec_subtask_dependencies; + +/* + * Define the fifos used to manage the dependency + * The buffers, provided though the Push routine, are buffered inside the pushFifo + * When programming them (using them) into a subtask, then they are considered as used, + * as so pushed inside th inUseFifo + */ +typedef struct { + t_sva_fifo pushFifo; + t_sva_fifo inUseFifo; +} t_sva_sec_fifo_dep; + + + + +typedef enum { + /* TBD */ + SVA_SEC_NO_CONF_CHANGE_NEED, + SVA_SEC_IMMEDIATE_CONF_CHANGE_NEED, + SVA_SEC_SYNC_CONF_CHANGE_NEED +} t_sva_sec_conf_state; + +/* + * Define structure that handle all stuff need to manipulate configuration change + */ +typedef struct { + t_sva_still_encoder_configuration currentConf; + t_sva_still_encoder_configuration nextConf; + t_uint32 currentConfCounter; + t_sva_sec_conf_state confState; +} t_sva_sec_conf_handle; + +typedef struct { + t_sva_buffer_id bufferId; + t_physical_address bufferAddress; +}t_sva_sec_buffer_desc; + +/* + * Define the descriptor of a stillEncode service instance + */ +typedef struct { + t_sva_sec_state state; + t_sva_sec_activate_state activateState; + t_sva_service_id serviceId; + t_sva_sec_conf_handle confHandle; + t_sva_sv_still_algo algo; + t_sva_sec_dependencies_desc defaultConfiguredDependency; + t_sva_fifo subtasksDependencyFifo; + t_sva_fifo inUseSubtasksDependencyFifo; + t_sva_tm_subtask_list_id subtasksListId; + t_sva_tm_subtask_id subtasksIdArray[STILL_ENCODE_SUBTASK_DEFAULT_NUMBER]; + t_sva_sec_fifo_dep inputBufferFifos; + t_sva_sec_fifo_dep outputBufferFifos; + t_sva_sec_fifo_dep bitstreamBufferFifos; + t_sva_block_id paramInBlockId; + t_sva_block_id paramOutBlockId; + t_sva_block_id paramInOutBlockId; + t_sva_sec_buffer_desc bitstreamBufferDesc[PUSH_FIFO_DEFAULT_SIZE]; + t_uint32 bitstreamBufferNb; + t_sva_still_encoder_status status; + t_sva_buffer_list_id bitstreamBufferListId[STILL_ENCODE_SUBTASK_DEFAULT_NUMBER]; + t_physical_address bistreamStartAddress; + t_bool lastSlice; + t_uint32 expectedPushInSize; + t_uint32 currentPushInSize; + t_uint32 actualPushInSize; + volatile t_uint32 nbBitstreamBuffers; + t_uint16 newFrameAndWindowHeight; + t_uint16 currentFrameAndWindowHeight; + volatile t_uint32 eotNumber; + t_uint32 sliceNumber; + volatile t_uint32 debug_count; + volatile t_bool eowOccured; + volatile t_sva_buffer_id associatedBufferId[PUSH_FIFO_DEFAULT_SIZE]; + volatile t_sva_tm_subtask_id subtaskIdEOW; + volatile t_uint32 previousSize; // size of data of previous image or slice in shared buffer (buffer_partly_filled) + volatile t_uint32 prv_bitstream_offset; // Bitstream offset of encoding + volatile t_uint8 prv_bitstream_last_byte; // Last byte of previous bitstream + volatile t_uint32 bufferSizeOnEOW; // size of buffer filled on last EOW for one image. + volatile t_uint32 bufferOnLastSliceSize; // sizo of bufferFilled on last slice + t_uint32 sliceIndex; + t_uint32 lastPartlyFilledSize; + t_uint32 thumbnailExpectedSize; + volatile t_bool stopOnEowFlag; + volatile t_bool stopOnRunningFlag; + t_sva_buffer_id bitstreamBufferLastBufferId; + t_ahb_address bitstreamBufferPrevLink; + t_ahb_address bitstreamBufferNextLink; +} t_sva_sec_descriptor; + + + + +#ifdef __cplusplus +} /* allow C++ to use these headers */ +#endif /* __cplusplus */ + +#endif /* __INC_SVA_STILLENCODEP_H */ +/* End of file - sva_stillencodep.h */ --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/sva.c @@ -0,0 +1,1827 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ +/*------------------------------------------------------------------------ + * Includes + *----------------------------------------------------------------------*/ + +#include "hcl_defs.h" +#include "sva.h" +#include "sva_hwp.h" +#include "sva_memorymgt.h" +#include "sva_buffermgt.h" +#include "sva_timemgt.h" +#include "sva_eventmgt.h" +#include "sva_taskmgt.h" +#include "sva_hwtaskmgt.h" +#include "sva_fwmgt.h" +#include "sva_fwmgtp.h" +#include "sva_timemgt.h" +#include "sva_service.h" +#include "sva_openservicemgt.h" +#include "sva_grab.h" +#include "sva_display.h" +#include "sva_encode.h" +#include "sva_decode.h" +#include "sva_still_encode.h" +#include "sva_stab.h" +#include "sva_internalneeds.h" +#include "sva_still_decode.h" +#include "sva_tvo.h" + +/*------------------------------------------------------------------------ + * Private Macro + *----------------------------------------------------------------------*/ + #define SVA_CCP_SYNC 0x03020100 + +/*------------------------------------------------------------------------ + * Global Variables + *----------------------------------------------------------------------*/ +PRIVATE t_sva_config_regs_mapping1 mapsaveRegValue; +PUBLIC t_sva_config_regs_mapping1 *saveRegValue =&mapsaveRegValue; +PRIVATE t_sva_regs_mapping *pSVARegs; /*need by SVA_GetVersion API*/ + +PUBLIC t_uint32 Last_IAD_EOT_ERR[5]; +PUBLIC t_uint32 Last_IAD_ERR[5]; +/*------------------------------------------------------------------------ + * Private functions prototype + *----------------------------------------------------------------------*/ +PUBLIC t_sva_error sva_GenericPush(t_sva_service_id ,t_sva_buffer_id ,t_sva_push_mode,t_sva_buffer_type ,t_sva_timestamp); + +/****************************************************************************/ +/* NAME: t_sva_error SVA_Init ( */ +/* t_system_address svaRegSystemBaseAddr, */ +/* t_system_address svaMemSystemBaseAddr, */ +/* t_system_address ERamSystemBaseAddr, */ +/* t_size ERamSize, */ +/* t_uint32 timerClkInHz */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine initializes the SVA HCL */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - svaRegSystemBaseAddr: SVA Registers Space base address */ +/* - svaMemSystemBaseAddr: SVA Memory Space base address */ +/* - ERamSystemBaseAddr: Embedded SRAM base address (used as HV cache) */ +/* - ERamSize: Size of the Embedded SRAM */ +/* - timerClkInHz: frequency of the timer clock */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/* - SVA_OK */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +t_sva_error SVA_Init( + t_system_address svaRegSystemBaseAddr, + t_system_address svaMemSystemBaseAddr, + t_system_address ERamSystemBaseAddr, + t_size ERamSize, + t_uint32 timerClkInHz +) +{ + t_sva_error status; + t_sva_mm_error mmError; + t_sva_bm_error bmError; + t_sva_fm_error fmError; + t_sva_tm_error tmError; + t_sva_om_error omError; + t_sva_error svaError; + t_sva_block_id blockId=INVALID_BUFFER_ID; + t_size blockSize=0; + t_uint8 loop_count1; + + for(loop_count1=0;loop_count1<5;loop_count1++) + { + Last_IAD_EOT_ERR[loop_count1] = SVA_LAST_IAD_EOT_ERR_RESET_VAL; + Last_IAD_ERR[loop_count1] = SVA_LAST_IAD_EOT_ERR_RESET_VAL; + } + + saveRegValue->sva_context_magic_number = 0; + + pSVARegs = (t_sva_regs_mapping *)svaRegSystemBaseAddr.logical; + /* Memory Management Module Initialization */ + mmError = sva_MM_Init(); + if (mmError != SVA_MM_OK) {return SVA_INTERNAL_MEMORY_MGT_ERROR;} + + /* ESRAM memory management intialization */ + mmError = sva_MM_AddFreeBlock(ESRAM_ID, ERamSystemBaseAddr, ERamSize); + if (mmError != SVA_MM_OK) {return SVA_INTERNAL_MEMORY_MGT_ERROR;} + + /* Buffer Management Module Initialization */ + bmError = sva_BM_Init(); + if (bmError != SVA_BM_OK) {return SVA_FATAL_ERROR;} + + + + /* Time Management Module Initialization */ + status = sva_TI_Init(svaRegSystemBaseAddr.logical, svaMemSystemBaseAddr.logical, timerClkInHz); + if (status != SVA_OK) {return status;} + + /* Events Management Module Initialization */ + status = sva_EM_Init(svaRegSystemBaseAddr.logical, svaMemSystemBaseAddr.logical); + if (status != SVA_OK) {return status;} + + /* Firmware Management Module Initialization */ + fmError = sva_FM_Init(svaRegSystemBaseAddr, svaMemSystemBaseAddr, SVA_CCP_SYNC,TRUE); + if (fmError != SVA_FM_OK) {return SVA_FATAL_ERROR;} + + /* Open service management init*/ + omError = sva_OM_Init(); + if (omError != SVA_OM_OK) {return SVA_FATAL_ERROR;} + + /* Task Management Module Initialization */ + tmError = sva_TM_Init(svaRegSystemBaseAddr.logical, svaMemSystemBaseAddr.logical); + if (tmError != SVA_TM_OK) {return SVA_FATAL_ERROR;} + + /* Service initialization */ + svaError = sva_DC_Init(); + if (svaError != SVA_OK) {return SVA_FATAL_ERROR;} + + svaError = sva_SDC_Init(); + if (svaError != SVA_OK) {return SVA_FATAL_ERROR;} + + svaError = sva_DP_Init(); + if (svaError != SVA_OK) {return SVA_FATAL_ERROR;} + + svaError = sva_GB_Init(); + if (svaError != SVA_OK) {return SVA_FATAL_ERROR;} + +// mmError= sva_MM_AllocBlock(ESRAM_ID,SVA_EC_SEARCHWINDOW_SIZE,SVA_MM_ALIGN_256BYTES,&blockId); +// if (mmError!=SVA_MM_OK) {return SVA_FATAL_ERROR;} + + svaError = sva_EC_Init(blockId,SVA_EC_SEARCHWINDOW_SIZE); + if (svaError != SVA_OK) {return SVA_FATAL_ERROR;} + + svaError = sva_SEC_Init(); + if (svaError != SVA_OK) {return SVA_FATAL_ERROR;} + + svaError = sva_ST_Init(blockId,blockSize); + if (svaError != SVA_OK) {return SVA_FATAL_ERROR;} + + svaError = sva_TV_Init(); + if (svaError != SVA_OK) {return SVA_FATAL_ERROR;} + + return SVA_OK; +} + +/****************************************************************************/ +/* NAME: t_sva_error SVA_AddPrivateMemoryChunk( */ +/* t_system_address hclManagedMemorySystemBaseAddr, */ +/* t_size hclManagedMemorySize */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine allows to provide to the HCL a new piece of memory */ +/* (contiguous, not cacheable, not bufferable) that the HCL will be */ +/* able to use for its internal needs and the user allocates/frees */ +/* through HV_AllocBuffer(), and HV_FreeBuffer() API routines. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - hclManagedMemorySystemBaseAddr: base Address of a Share Memory */ +/* Space if we want that the HV HCL manages itself */ +/* the shared buffers */ +/* - hclManagedMemorySize: size of the above Memory Space */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_sva_error SVA_AddPrivateMemoryChunk( + t_system_address hclManagedMemorySystemBaseAddr, + t_size hclManagedMemorySize + ) +{ + t_sva_mm_error mmStatus; + t_sva_fm_error fwStatus; + mmStatus = sva_MM_AddFreeBlock(SDRAM_ID, hclManagedMemorySystemBaseAddr, hclManagedMemorySize); + if (mmStatus != SVA_MM_OK) + return(SVA_INTERNAL_MEMORY_MGT_ERROR); + + fwStatus = sva_FM_InformPrivateMemoryChunk(SDRAM_ID, hclManagedMemorySystemBaseAddr, hclManagedMemorySize); + if (fwStatus != SVA_FM_OK) + return(SVA_INTERNAL_MEMORY_MGT_ERROR); + + return (SVA_OK); +} + +/****************************************************************************/ +/* NAME: t_sva_error SVA_ConfigurePrivateMemoryChunk() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine set up the Data16_1 and Data24 sections within the */ +/* MMDSP+ memory. It removes the SDRAM default mapping previously set */ +/* by sva_FM_InformPrivateMemoryChunk, then it creates a data24 section*/ +/* and an extended data16_1 section. This function must be called with */ +/* the right parameters in order to use the VC1 decoder, H264 encode */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - additionnalZone : Type of zone to be allocated */ +/* - zoneSize: size of the extended data16_1 section <-> size of the */ +/* VC1 decoder image buffer section = */ +/* (nb of buffer * buffer_size) */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_sva_error SVA_ConfigurePrivateMemoryChunk(t_sva_dedicated_area_purpose additionalZone,t_size zoneSize) { + + t_sva_fm_error fmError; + t_sva_mm_error mmError; + t_system_address zoneAddress; + t_size modifiedZoneSize=zoneSize; + t_uint32 minMemReq; + + if ((additionalZone != SVA_VC1_IMAGE_BUFFER_AREA)&&(additionalZone != SVA_H264_INTERNAL_AREA)&&(additionalZone != SVA_H264_ENC_FW_PROG_ZONE1_AREA)&& (additionalZone != SVA_SW_PREPROC_BUFFER_AREA)) return SVA_NOT_SUPPORTED_YET; + if (SVA_VC1_IMAGE_BUFFER_AREA == additionalZone) + { + minMemReq = (SVA_FW_SDRAM_PROG_ZONE1_SIZE + SVA_FW_SDRAM_DATA24_ZONE1_SIZE + SVA_FW_SDRAM_DATA16_ZONE1_SIZE_MAX + SVA_FW_SDRAM_VC1_DEC_DEDICATED_BUFF_SIZE_MIN) - SVA_FW_MMDSP_SDRAM_SIZE; + } + else if (SVA_H264_INTERNAL_AREA == additionalZone) + { + minMemReq = (SVA_FW_SDRAM_PROG_ZONE1_SIZE + SVA_FW_SDRAM_DATA24_ZONE1_SIZE + SVA_FW_SDRAM_DATA16_ZONE1_SIZE_MAX + SVA_FW_SDRAM_H264_DEC_DEDICATED_BUFF_SIZE_MIN) - SVA_FW_MMDSP_SDRAM_SIZE; + } + else if (SVA_H264_ENC_FW_PROG_ZONE1_AREA == additionalZone) + { + minMemReq = (SVA_FW_SDRAM_PROG_ZONE1_SIZE + SVA_FW_SDRAM_DATA24_ZONE1_SIZE + SVA_FW_SDRAM_H264_ENC_DATA16_ZONE1_SIZE_MAX) - SVA_FW_MMDSP_SDRAM_SIZE; + } + else if (SVA_SW_PREPROC_BUFFER_AREA == additionalZone) + { + minMemReq = (SVA_FW_SDRAM_PROG_ZONE1_SIZE + SVA_FW_SDRAM_DATA24_ZONE1_SIZE + SVA_FW_SDRAM_PREPROC_DATA16_ZONE1_SIZE_MAX) - SVA_FW_MMDSP_SDRAM_SIZE; + } + else + { + return SVA_NOT_SUPPORTED_YET; + } + if (zoneSize < minMemReq) + { + return SVA_INSUFFICIENT_MEMORY; + } + + fmError = sva_FM_ConfigurePrivateMemoryChunk(additionalZone, &modifiedZoneSize, &zoneAddress); + if (fmError != SVA_FM_OK) return SVA_INTERNAL_MEMORY_MGT_ERROR; + + mmError = sva_MM_InitDedicatedMemory(additionalZone, zoneAddress, modifiedZoneSize); + if (mmError != SVA_MM_OK) return SVA_INTERNAL_MEMORY_MGT_ERROR; + + return(SVA_OK); +} + + +/****************************************************************************/ +/* NAME: t_sva_error SVA_GetPrivateMemoryStatus( */ +/* t_sva_private_memory_status *pStatus */ +/* ); */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine provides the current status of the Private Memory */ +/* managed by the HCL. */ +/* */ +/* PARAMETERS: */ +/* IN : none */ +/* */ +/* OUT : */ +/* - pStatus: provided status */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_sva_error SVA_GetPrivateMemoryStatus( + t_sva_private_memory_status *pStatus + ) +{ + t_sva_mm_error mmError; + t_sva_bm_error bmError; + t_sva_mm_status mmStatus; + + HCL_ASSERT(pStatus!=NULL); + mmError = sva_MM_GetStatus(SDRAM_ID, &mmStatus); + + if (mmError == SVA_MM_OK) + { + pStatus->usedMemorySize = mmStatus.overallUsedBlocksSize; + pStatus->freeMemorySize = mmStatus.overallFreeBlocksSize; + pStatus->nbFreeBlock = mmStatus.numFreeBlocks; + pStatus->minBlockSize = mmStatus.freeBlockMinSize; + pStatus->maxBlockSize = mmStatus.freeBlockMaxSize; + pStatus->nbUsedBlock = mmStatus.numUsedBlocks; + } + + bmError = sva_BM_GetStatus(&pStatus->nbAllocatedBuffer); + + return (t_sva_error)(((bmError != SVA_BM_OK) || (mmError != SVA_MM_OK))?SVA_INTERNAL_MEMORY_MGT_ERROR:SVA_OK); +} + +/****************************************************************************/ +/* NAME: t_sva_error SVA_Reset ( */ +/* void */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine resets the SVA HCL */ +/* */ +/* PARAMETERS: */ +/* IN : none */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +t_sva_error SVA_Reset(void) +{ + return SVA_NOT_SUPPORTED_YET; +} + +/****************************************************************************/ +/* NAME: SVA_SaveDeviceContext() */ +/*--------------------------------------------------------------------------*/ +/* Description : */ +/* IN : */ +/* */ +/* OUT: */ +/****************************************************************************/ +t_sva_error SVA_SaveDeviceContext(void) +{ + if (pSVARegs==NULL) return SVA_UNEXPECTED_API_CALL; + saveRegValue->cfg_psa = pSVARegs->cfg.cfg_psa; //t_sva_config_regs_mapping.cfg_psa; + saveRegValue->cfg_pea=pSVARegs->cfg.cfg_pea; + saveRegValue->cfg_ice=pSVARegs->cfg.cfg_ice; + + saveRegValue->cfg_csc=pSVARegs->cfg.cfg_csc; + saveRegValue->cfg_cgc=pSVARegs->cfg.cfg_cgc; + + #if defined(__STN_8815) + saveRegValue->cfg_irp_fw_addr = pSVARegs->cfg.cfg_irp_fw_addr; + saveRegValue->cfg_irp_fw_size = pSVARegs->cfg.cfg_irp_fw_size; + + saveRegValue->cfg_irp_rw=pSVARegs->cfg.cfg_irp_rw; + saveRegValue->cfg_irp_error=pSVARegs->cfg.cfg_irp_error; + saveRegValue->cfg_irp_bs=pSVARegs->cfg.cfg_irp_bs; + saveRegValue->cfg_irp_be=pSVARegs->cfg.cfg_irp_be; + saveRegValue->cfg_irp_ptr=pSVARegs->cfg.cfg_irp_ptr; + #endif + + saveRegValue->cfg_clk=pSVARegs->cfg.cfg_clk; + #if defined(__STN_8815) + saveRegValue->ckg_cken=pSVARegs->cfg.ckg_cken; + #endif + + saveRegValue->cfg_tim=pSVARegs->cfg.cfg_tic; + + saveRegValue->cfg_iis=pSVARegs->cfg.cfg_iis; + saveRegValue->cfg_isr=pSVARegs->cfg.cfg_isr; + saveRegValue->cfg_imr=pSVARegs->cfg.cfg_imr; //This is to save the frm version + +// SVA_UnregisterFirmware(saveRegValue->fwId);// ADDed for testing + + { + void sva_FM_Save(); + sva_FM_Save(); + } + + + saveRegValue->temp_idn_frv=pSVARegs->idn.idn_frv; +// saveRegValue->wasDeepSleepEntered = pSVARegs->idn.idn_frv=(1<<2); + saveRegValue->sva_context_magic_number = SVA_CONTEXT_MAGIC_NUMBER; + return SVA_OK; +} + +/****************************************************************************/ +/* NAME :t_sva_error SVA_RestoreDeviceContext(t_sva_config_regs_mapping1 *) */ +/*--------------------------------------------------------------------------*/ +/* Description : */ +/* IN : */ +/* */ +/* OUT: */ +/****************************************************************************/ +t_sva_error SVA_RestoreDeviceContext(void) +{ + t_sva_tm_error tmErrCode = SVA_TM_OK; + + if (pSVARegs==NULL) return SVA_UNEXPECTED_API_CALL; + + if(SVA_WasDeepSleepEntered()==FALSE) + { + return SVA_UNEXPECTED_API_CALL; + } + + saveRegValue->sva_context_magic_number = 0; + + /*Second param passed as NULL, NOT used in sva_TM_HW_Init() */ + tmErrCode = sva_TM_HW_Init((t_logical_address)pSVARegs, (t_logical_address)NULL); + HCL_DEBUG_ASSERT(tmErrCode == SVA_TM_OK); + +// t_sva_fm_error fmErrCode; + //pSVARegs->cfg.cfg_psa = saveRegValue->cfg_psa; + + //pSVARegs->cfg.cfg_pea = saveRegValue->cfg_pea; + pSVARegs->cfg.cfg_ice = saveRegValue->cfg_ice; + + pSVARegs->cfg.cfg_csc = saveRegValue->cfg_csc; + //pSVARegs->cfg.cfg_cgc = saveRegValue->cfg_cgc; + + #if defined(__STN_8815) + //pSVARegs->cfg.cfg_irp_act = saveRegValue->cfg_irp_act; + pSVARegs->cfg.cfg_irp_fw_addr = saveRegValue->cfg_irp_fw_addr; + pSVARegs->cfg.cfg_irp_fw_size = saveRegValue->cfg_irp_fw_size ; + + pSVARegs->cfg.cfg_irp_rw = saveRegValue->cfg_irp_rw; + pSVARegs->cfg.cfg_irp_error= saveRegValue->cfg_irp_error ; + pSVARegs->cfg.cfg_irp_bs = saveRegValue->cfg_irp_bs; + pSVARegs->cfg.cfg_irp_be = saveRegValue->cfg_irp_be; + pSVARegs->cfg.cfg_irp_ptr= saveRegValue->cfg_irp_ptr; + #endif + + //pSVARegs->cfg.cfg_clk = saveRegValue->cfg_clk; + //pSVARegs->cfg.cfg_rst= saveRegValue->cfg_rst; + + #if defined(__STN_8815) + pSVARegs->cfg.ckg_cken= saveRegValue->ckg_cken ; + #endif + + pSVARegs->cfg.cfg_tim = saveRegValue->cfg_tim; + //pSVARegs->cfg.cfg_tic = saveRegValue->cfg_tic; + + //pSVARegs->cfg.cfg_iis = saveRegValue->cfg_iis; + //pSVARegs->cfg.cfg_isr = saveRegValue->cfg_isr; + + //SVA_DisableIRQSrc (SVA_IRQ); + pSVARegs->cfg.cfg_isr = 0x3f;//saveRegValue->cfg_isr; + + { + void sva_FM_Restore(); + sva_FM_Restore(); + } + + pSVARegs->cfg.cfg_imr = saveRegValue->cfg_imr; + + + //pSVARegs->idn.idn_frv = saveRegValue->temp_idn_frv; + + + return SVA_OK; + +} + +/****************************************************************************/ +/* NAME: t_sva_error SVA_GetVersion( t_sva_version * pVersion ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine returns the current HCL version. */ +/* */ +/* PARAMETERS: */ +/* IN : none */ +/* */ +/* OUT : */ +/* - pVersion: returned version structure */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ + + + +t_sva_error SVA_GetVersion(t_sva_version * pVersion) +{ + t_version undefinedVersion=UNDEFINED_VERSION; + t_sva_fm_error fmError; + + HCL_ASSERT(pVersion!=NULL); + + /* hcl api version number */ + pVersion->hclVersion.version=SVA_HCL_VERSION_ID; + pVersion->hclVersion.major=SVA_HCL_MAJOR_ID; + pVersion->hclVersion.minor=SVA_HCL_MINOR_ID; + + /* firmware version number */ + fmError=sva_FM_GetFwVersion(&pVersion->fwVersion); + if (fmError==SVA_FM_NO_FIRMWARE_LOADED) {pVersion->fwVersion=undefinedVersion;} + + /* hardware version number */ + pVersion->hwVersion.version =(t_bitfield)((pSVARegs->idn.idn_hrv>>SHIFT_QUARTET2)&MASK_QUARTET); + pVersion->hwVersion.major =(t_bitfield)((pSVARegs->idn.idn_hrv>>SHIFT_QUARTET1)&MASK_QUARTET); + pVersion->hwVersion.minor =(t_bitfield)((pSVARegs->idn.idn_hrv>>SHIFT_QUARTET0)&MASK_QUARTET); + + return SVA_OK; +} + +/****************************************************************************/ +/* NAME: t_sva_error SVA_CreateService( */ +/* t_sva_service_type serviceType, */ +/* t_sva_service_id * pServiceId */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine creates a new service. Its unique goal is to provide */ +/* an identifier */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - serviceType: type of the service (PREPROCESSOR/DECODER/...) */ +/* */ +/* OUT : */ +/* - pServiceId: returned Service identifier */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/* - SVA_INCOHERENT_SERVICE_TYPE : service type is unknown */ +/* - SVA_NOT_SUPPORTED_YET : service is not yet supported */ +/* - SVA_INTERNAL__ERROR : internal error inside service */ +/* - SVA_FATAL_ERROR : fatal error */ +/* - SVA_OK */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +t_sva_error SVA_CreateService( + t_sva_service_type serviceType, + t_sva_service_id *pServiceId +) +{ + t_sva_error status; + + HCL_ASSERT(pServiceId!=NULL); + + /*init service id to MASK_ALL32*/ + *pServiceId=MASK_ALL32; + + /*create fifo event*/ + status=sva_EM_Create(pServiceId); + if (status!=SVA_OK) {return status;} + + if (serviceType>=SVA_OPEN_SERVICE_0) + { + status=sva_OM_Create(serviceType,pServiceId); + } + else + { + /*We want to create a standard service*/ + WRITE_TASK_ID_IN_SERVICE_ID(serviceType,*pServiceId); + switch(serviceType) + { + case SVA_PREPROCESSOR: + status=sva_GB_Create(pServiceId); + break; + case SVA_VIDEO_DECODER: + status=sva_DC_Create(pServiceId); + break; + case SVA_VIDEO_ENCODER: + status=sva_EC_Create(pServiceId); + break; + case SVA_POSTPROCESSOR: + status=sva_DP_Create(pServiceId); + break; + case SVA_STILL_IMAGE_ENCODER: + status=sva_SEC_Create(pServiceId); + break; + case SVA_STILL_IMAGE_DECODER: + status=sva_SDC_Create(pServiceId); + break; + case SVA_TV_OUTPUT: + status=sva_TV_Create(pServiceId); + break; + case SVA_SW_PROCESSING: + status=sva_ST_Create(pServiceId); + break; + default: + status=SVA_INCOHERENT_SERVICE_TYPE; + break; + } + } + + /*in case service creation failed we have to delete created fifo*/ + if (status!=SVA_OK) + { + if (sva_EM_Delete(*pServiceId) != SVA_OK) + { + return(SVA_FATAL_ERROR); + } + } + + return status; +} + +/****************************************************************************/ +/* NAME: t_sva_error SVA_DeleteService( */ +/* t_sva_service_id serviceId */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine deletes a service (it frees any allocated resources) */ +/* SVA must be stopped when calling this function */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - serviceId: service identifier */ +/* */ +/* OUT : */ +/* - none */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/* - SVA_UNKNOWN_SERVICE_ID : service id is unknown */ +/* - SVA_NOT_SUPPORTED_YET : service is not yet supported */ +/* - SVA_INTERNAL__ERROR : internal error inside service */ +/* - SVA_UNEXPECTED_API_CALL : API is not supposed to be call in */ +/* service current state. */ +/* - SVA_OK */ +/* */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +t_sva_error SVA_DeleteService( + t_sva_service_id serviceId +) +{ + t_sva_error status; + t_sva_sv_task_id taskId=READ_TASK_ID_IN_SERVICE_ID(serviceId); + + if (sva_OM_isOpenService(serviceId)==TRUE) + { + status=sva_OM_Delete(serviceId); + } + else + { + switch(taskId) + { + case SVA_SV_GRAB_TID: + status=sva_GB_Delete(serviceId); + break; + case SVA_SV_DECODE_TID: + status=sva_DC_Delete(serviceId); + break; + case SVA_SV_ENCODE_TID: + status=sva_EC_Delete(serviceId); + break; + case SVA_SV_DISPLAY_TID: + status=sva_DP_Delete(serviceId); + break; + case SVA_SV_STILL_ENCODE_TID: + status=sva_SEC_Delete(serviceId); + break; + case SVA_SV_STILL_DECODE_TID: + status=sva_SDC_Delete(serviceId); + break; + case SVA_SV_TVO_TID: + status=sva_TV_Delete(serviceId); + break; + case SVA_SV_STAB_TID: + status=sva_ST_Delete(serviceId); + break; + default: + status=SVA_UNKNOWN_SERVICE_ID; + break; + } + } + + return status; +} + +PUBLIC t_sva_error sva_ResolveDependencies(t_sva_service_id serviceId) +{ + t_sva_error status = SVA_OK; + t_sva_sv_task_id taskId = READ_TASK_ID_IN_SERVICE_ID(serviceId); + t_sva_service_instance_num instanceNum = READ_INSTANCE_NUM_IN_SERVICE_ID(serviceId); + + + if (sva_OM_isOpenService(serviceId)==TRUE) + { + } + else + { + switch(taskId) + { + case SVA_SV_GRAB_TID: + break; + case SVA_SV_DECODE_TID: + break; + case SVA_SV_ENCODE_TID: + break; + case SVA_SV_DISPLAY_TID: + sva_DP_ResolveDependencies(instanceNum); + break; + case SVA_SV_STILL_ENCODE_TID: + break; + case SVA_SV_STILL_DECODE_TID: + break; + case SVA_SV_TVO_TID: + break; + case SVA_SV_STAB_TID: + break; + default: + status=SVA_UNKNOWN_SERVICE_ID; + break; + } + } + + return status; +} +/****************************************************************************/ +/* NAME: t_sva_error SVA_ControlService( */ +/* t_sva_service_id serviceId, */ +/* t_sva_service_cmd_id serviceCmdId, */ +/* t_uint32 param */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine allows sending commands to an activated service */ +/* These commands modify the internal state of the service */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - serviceId: service identifier */ +/* - serviceCmdId: identifier of the command to send */ +/* - param: parameter for the command */ +/* */ +/* OUT : */ +/* - none */ +/* */ +/* RETURN: */ +/* - SVA_UNKNOWN_SERVICE_ID : service id is unknown */ +/* - SVA_NOT_SUPPORTED_YET : service is not yet supported */ +/* - SVA_INTERNAL__ERROR : internal error inside service */ +/* - SVA_UNEXPECTED_API_CALL : API is not supposed to be call in */ +/* service current state. */ +/* - SVA_UNKNOWN_CMD_ID : command is unknown to the service */ +/* - SVA_OK */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +t_sva_error SVA_ControlService( + t_sva_service_id serviceId, + t_sva_service_cmd_id serviceCmdId, + t_uint32 param +) +{ + t_sva_error status = SVA_UNEXPECTED_API_CALL; + t_sva_sv_task_id taskId=READ_TASK_ID_IN_SERVICE_ID(serviceId); + + if (sva_OM_isOpenService(serviceId)==TRUE) + { + status=sva_OM_Control(serviceId,serviceCmdId,param); + } + else + { + if (serviceCmdId == SVA_SERVICE_ABORT) + { + if (taskId != SVA_SV_GRAB_TID) + { + return status; + } + } + switch(taskId) + { + case SVA_SV_GRAB_TID: + status=sva_GB_Control(serviceId,serviceCmdId,param); + break; + case SVA_SV_DECODE_TID: + status=sva_DC_Control(serviceId,serviceCmdId,param); + break; + case SVA_SV_ENCODE_TID: + status=sva_EC_Control(serviceId,serviceCmdId,param); + break; + case SVA_SV_DISPLAY_TID: + status=sva_DP_Control(serviceId,serviceCmdId,param); + break; + case SVA_SV_STILL_ENCODE_TID: + status=sva_SEC_Control(serviceId, serviceCmdId, param); + break; + case SVA_SV_STILL_DECODE_TID: + status=sva_SDC_Control(serviceId, serviceCmdId, param); + break; + case SVA_SV_TVO_TID: + status=sva_TV_Control(serviceId, serviceCmdId, param); + break; + case SVA_SV_STAB_TID: + status=sva_ST_Control(serviceId,serviceCmdId,param); + break; + default: + status=SVA_UNKNOWN_SERVICE_ID; + break; + } + } + + return status; +} + +/****************************************************************************/ +/* NAME: t_sva_error SVA_ActivateService( */ +/* t_sva_service_id serviceId, */ +/* t_sva_service_mode serviceMode, */ +/* t_sva_fw_id *pFwId */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine activates the service: then the service will respond */ +/* to commands. Note that this functions also loads the firmware (if */ +/* it is possible ) */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - serviceId: service identifier */ +/* - serviceMode: SVA_REALTIME_SERVICE / SVA_NON_REALTIME_SERVICE */ +/* */ +/* OUT : */ +/* - pFwId: needed firmware identifier */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/* - SVA_UNKNOWN_SERVICE_ID : service id is unknown */ +/* - SVA_NOT_SUPPORTED_YET : service is not yet supported */ +/* - SVA_INTERNAL__ERROR : internal error inside service */ +/* - SVA_INTERNAL_TASK_MGT_ERROR : internal error inside Task Mgt */ +/* - SVA_UNEXPECTED_API_CALL : API is not supposed to be call in */ +/* service current state. */ +/* - SVA_OK */ +/* - SVA_FW_CONFLICT : user must deactivate some services if he */ +/* want to activate this service. */ +/* - SVA_FW_DOWNLOAD_NEEDED : hcl need an address for *pFwId so it */ +/* can activate this service. */ +/* - SVA_FW_SWITCH_OCCURED : hcl will change firmware since it has */ +/* all information required and all activated services are none real */ +/* time */ +/* */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +t_sva_error SVA_ActivateService( + t_sva_service_id serviceId, + t_sva_service_mode serviceMode, + t_sva_fw_id *pFwId +) +{ + t_sva_error status; + t_sva_sv_task_id taskId=READ_TASK_ID_IN_SERVICE_ID(serviceId); + + if (sva_OM_isOpenService(serviceId)==TRUE) + { + status=sva_OM_Activate(serviceId,serviceMode,pFwId); + } + else + { + switch(taskId) + { + case SVA_SV_GRAB_TID: + status=sva_GB_Activate(serviceId,serviceMode,pFwId); + break; + case SVA_SV_DECODE_TID: + status=sva_DC_Activate(serviceId,serviceMode,pFwId); + break; + case SVA_SV_ENCODE_TID: + status=sva_EC_Activate(serviceId,serviceMode,pFwId); + break; + case SVA_SV_DISPLAY_TID: + status=sva_DP_Activate(serviceId,serviceMode,pFwId); + break; + case SVA_SV_STILL_ENCODE_TID: + status=sva_SEC_Activate(serviceId, serviceMode, pFwId); + break; + case SVA_SV_STILL_DECODE_TID: + status=sva_SDC_Activate(serviceId, serviceMode, pFwId); + break; + case SVA_SV_TVO_TID: + status=sva_TV_Activate(serviceId, serviceMode, pFwId); + break; + case SVA_SV_STAB_TID: + status=sva_ST_Activate(serviceId,serviceMode,pFwId); + break; + default: + status=SVA_UNKNOWN_SERVICE_ID; + break; + } + } + + return status; +} + +/****************************************************************************/ +/* NAME: t_sva_error SVA_InactivateService( */ +/* t_sva_service_id serviceId */ +/* ( */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine inactivates a stopped service: then the service will */ +/* not respond to any commands. */ +/* Note that after this function call. firmware need by this service can */ +/* be unload at any time so a call to an SVA_ActivateService can fail */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - serviceId: service identifier */ +/* */ +/* OUT : */ +/* - none */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/* - SVA_UNKNOWN_SERVICE_ID : service id is unknown */ +/* - SVA_NOT_SUPPORTED_YET : service is not yet supported */ +/* - SVA_INTERNAL__ERROR : internal error inside service */ +/* - SVA_UNEXPECTED_API_CALL : API is not supposed to be call in */ +/* service current state. */ +/* - SVA_OK */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +t_sva_error SVA_InactivateService(t_sva_service_id serviceId) +{ + t_sva_error status; + t_sva_sv_task_id taskId=READ_TASK_ID_IN_SERVICE_ID(serviceId); + + if (sva_OM_isOpenService(serviceId)==TRUE) + { + status=sva_OM_Inactivate(serviceId); + } + else + { + switch(taskId) + { + case SVA_SV_GRAB_TID: + status=sva_GB_Inactivate(serviceId); + break; + case SVA_SV_DECODE_TID: + status=sva_DC_Inactivate(serviceId); + break; + case SVA_SV_ENCODE_TID: + status=sva_EC_Inactivate(serviceId); + break; + case SVA_SV_DISPLAY_TID: + status=sva_DP_Inactivate(serviceId); + break; + case SVA_SV_STILL_ENCODE_TID: + status=sva_SEC_Inactivate(serviceId); + break; + case SVA_SV_STILL_DECODE_TID: + status=sva_SDC_Inactivate(serviceId); + break; + case SVA_SV_TVO_TID: + status=sva_TV_Inactivate(serviceId); + break; + case SVA_SV_STAB_TID: + status=sva_ST_Inactivate(serviceId); + break; + default: + status=SVA_UNKNOWN_SERVICE_ID; + break; + } + } + + return status; +} + +/****************************************************************************/ +/* NAME: t_sva_error SVA_GetServiceInternalNeedsNCNB( */ +/* t_sva_service_id serviceId, */ +/* t_size* pSize */ +/* t_size* pSizeNCNB */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine returns the size of memory needed for the configured */ +/* service. It must be called before starting the service. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - serviceId: service identifier */ +/* */ +/* OUT : */ +/* - pSize: size of needed memory */ +/* - pSizeNCNB: size of needed non-cachable non-bufferable memory */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/* - SVA_UNKNOWN_SERVICE_ID : service id is unknown */ +/* - SVA_NOT_SUPPORTED_YET : service is not yet supported */ +/* - SVA_INTERNAL__ERROR : internal error inside service */ +/* - SVA_UNEXPECTED_API_CALL : API is not supposed to be call in */ +/* service current state. */ +/* - SVA_OK */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +t_sva_error SVA_GetServiceInternalNeedsNCNB( + t_sva_service_id serviceId, + t_size * pSize, + t_size * pSizeNCNB +) +{ + t_sva_error status; + t_sva_sv_task_id taskId=READ_TASK_ID_IN_SERVICE_ID(serviceId); + + /* check pointer validity*/ + HCL_ASSERT(pSizeNCNB!=0); + *pSizeNCNB = 0; + + if (sva_OM_isOpenService(serviceId)==TRUE) + { + status=sva_OM_GetInternalNeeds(serviceId,pSize); + } + else + { + switch(taskId) + { + case SVA_SV_GRAB_TID: + status=sva_GB_GetInternalNeeds(serviceId,pSize); + break; + case SVA_SV_DECODE_TID: + status=sva_DC_GetInternalNeeds(serviceId,pSize); + break; + case SVA_SV_ENCODE_TID: + status=sva_EC_GetInternalNeeds(serviceId,pSize); + break; + case SVA_SV_DISPLAY_TID: + status=sva_DP_GetInternalNeeds(serviceId,pSize); + break; + case SVA_SV_STILL_ENCODE_TID: + status=sva_SEC_GetInternalNeeds(serviceId,pSize); + break; + case SVA_SV_STILL_DECODE_TID: + status=sva_SDC_GetInternalNeeds(serviceId,pSize,pSizeNCNB); + break; + case SVA_SV_TVO_TID: + status=sva_TV_GetInternalNeeds(serviceId,pSize); + break; + case SVA_SV_STAB_TID: + status=sva_ST_GetInternalNeeds(serviceId,pSize); + break; + default: + status=SVA_UNKNOWN_SERVICE_ID; + break; + } + } + + return status; +} + +/****************************************************************************/ +/* NAME: t_sva_error SVA_GetServiceInternalNeeds( */ +/* t_sva_service_id serviceId, */ +/* t_size* pSize */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine returns the size of memory needed for the configured */ +/* service. It must be called before starting the service. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - serviceId: service identifier */ +/* */ +/* OUT : */ +/* - pSize: size of needed memory */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/* - SVA_UNKNOWN_SERVICE_ID : service id is unknown */ +/* - SVA_NOT_SUPPORTED_YET : service is not yet supported */ +/* - SVA_INTERNAL__ERROR : internal error inside service */ +/* - SVA_UNEXPECTED_API_CALL : API is not supposed to be call in */ +/* service current state. or NCNB (non-cacheable non-bufferable memory */ +/* size requirement is non-zero. */ +/* - SVA_OK */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +t_sva_error SVA_GetServiceInternalNeeds( + t_sva_service_id serviceId, + t_size * pSize +) +{ + t_sva_error sva_error; + t_size sizeNCNB; + sva_error = SVA_GetServiceInternalNeedsNCNB(serviceId,pSize,&sizeNCNB); + + if (sizeNCNB != 0) + { + return SVA_UNEXPECTED_API_CALL; + } + + return sva_error; +} + +/****************************************************************************/ +/* NAME: t_sva_error SVA_ProvideServiceInternalNeedsNCNB( */ +/* t_sva_service_id serviceId, */ +/* t_logical_address baseAddress, */ +/* t_size size */ +/* t_system_address systemAddressNCNB, */ +/* t_size sizeNCNB */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine returns the actually needed memory at the specified */ +/* address. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - serviceId: service identifier */ +/* - baseAddress: address where memory is allocated */ +/* - size: size of memory to be allocated */ +/* - systemAddressNCNB:system address of Non-cachable non-bufferable memory*/ +/* - sizeNCNB: size of non-cachable non-bufferable memory */ +/* */ +/* OUT : */ +/* - none */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/* - SVA_UNKNOWN_SERVICE_ID : service id is unknown */ +/* - SVA_NOT_SUPPORTED_YET : service is not yet supported */ +/* - SVA_INTERNAL__ERROR : internal error inside service */ +/* - SVA_UNEXPECTED_API_CALL : API is not supposed to be call in */ +/* service current state. */ +/* - SVA_OK */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ + +t_sva_error SVA_ProvideServiceInternalNeedsNCNB( + t_sva_service_id serviceId, + t_logical_address baseAddress, + t_size size, + t_system_address systemAddressNCNB, + t_size sizeNCNB +) +{ + t_sva_error status; + t_sva_sv_task_id taskId=READ_TASK_ID_IN_SERVICE_ID(serviceId); + + /*give memory to internal needs module*/ + sva_IN_ProvideInternalNeeds(baseAddress, size); + + /*allow service to use this memory*/ + if (sva_OM_isOpenService(serviceId)==TRUE) + { + status=sva_OM_ProvideInternalNeeds(serviceId); + } + else + { + switch(taskId) + { + case SVA_SV_GRAB_TID: + status=sva_GB_ProvideInternalNeeds(serviceId); + break; + case SVA_SV_DECODE_TID: + status=sva_DC_ProvideInternalNeeds(serviceId); + break; + case SVA_SV_ENCODE_TID: + status=sva_EC_ProvideInternalNeeds(serviceId); + break; + case SVA_SV_DISPLAY_TID: + status=sva_DP_ProvideInternalNeeds(serviceId); + break; + case SVA_SV_STILL_ENCODE_TID: + status=sva_SEC_ProvideInternalNeeds(serviceId); + break; + case SVA_SV_STILL_DECODE_TID: + status=sva_SDC_ProvideInternalNeeds(serviceId,systemAddressNCNB,sizeNCNB); + break; + case SVA_SV_TVO_TID: + status=sva_TV_ProvideInternalNeeds(serviceId); + break; + case SVA_SV_STAB_TID: + status=sva_ST_ProvideInternalNeeds(serviceId); + break; + default: + status=SVA_UNKNOWN_SERVICE_ID; + break; + } + } + + return status; +} + + +/****************************************************************************/ +/* NAME: t_sva_error SVA_ProvideServiceInternalNeeds( */ +/* t_sva_service_id serviceId, */ +/* t_logical_address baseAddress, */ +/* t_size size */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine returns the actually needed memory at the specified */ +/* address. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - serviceId: service identifier */ +/* - baseAddress: address where memory is allocated */ +/* - size: size of memory to be allocated */ +/* */ +/* OUT : */ +/* - none */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/* - SVA_UNKNOWN_SERVICE_ID : service id is unknown */ +/* - SVA_NOT_SUPPORTED_YET : service is not yet supported */ +/* - SVA_INTERNAL__ERROR : internal error inside service */ +/* - SVA_UNEXPECTED_API_CALL : API is not supposed to be call in */ +/* service current state. */ +/* - SVA_SDC_JPEG_PARAM_ERROR : if called when NCNB memory */ +/* requirement is non-zero */ +/* - SVA_OK */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +t_sva_error SVA_ProvideServiceInternalNeeds( + t_sva_service_id serviceId, + t_logical_address baseAddress, + t_size size +) +{ + t_sva_error sva_error; + t_system_address systemAddressNCNB; + t_size sizeNCNB = 0; + + systemAddressNCNB.logical = 0xFFFFFFFFUL; + systemAddressNCNB.physical = 0xFFFFFFFFUL; + + sva_error = SVA_ProvideServiceInternalNeedsNCNB(serviceId, baseAddress, size, systemAddressNCNB, sizeNCNB); + + return sva_error; +} + +/****************************************************************************/ +/* NAME: t_sva_error SVA_PushBitstreamBuffer( */ +/* t_sva_service_id serviceId, */ +/* t_sva_buffer_id bufferId, */ +/* t_sva_push_mode mode */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine pushes a "defined" or "allocated" buffer into the HCL. */ +/* The buffer will be used either to write encoded data (output of */ +/* encoder) or to be decoded (input of decoder). */ +/* The service must be configured. */ +/* */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - serviceId: service identifier */ +/* - bufferId: buffer identifier */ +/* - mode: SVA_PUSH_IN / SVA_PUSH_OUT */ +/* */ +/* OUT : */ +/* - none */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/* - SVA_UNKNOWN_SERVICE_ID : service id is unknown */ +/* - SVA_NOT_SUPPORTED_YET : service is not yet supported */ +/* - SVA_INTERNAL__ERROR : internal error inside service */ +/* - SVA_UNEXPECTED_API_CALL : API is not supposed to be call in */ +/* service current state. */ +/* - SVA_UNKNOWN_BUFFER_ID : buffer id is unknown */ +/* - SVA_INVALID_BUFFER_TYPE : buffer type is not a bitstream one */ +/* - SVA_INTERNAL_FIFOS_FULL : service fifo are full and can't */ +/* accept buffer for the moment. */ +/* - SVA_OK */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +t_sva_error SVA_PushBitstreamBuffer( + t_sva_service_id serviceId, + t_sva_buffer_id bufferId, + t_sva_push_mode mode +) +{ + t_sva_error status; + t_sva_bm_error bmError; + t_sva_buffer_type bufferType; + t_sva_timestamp timeStamp={SVA_NO_TIMESTAMP,0}; + + /*check that buffer type is correct*/ + bmError=sva_BM_GetBufferType(bufferId,&bufferType); + if (bmError!=SVA_BM_OK) {return SVA_UNKNOWN_BUFFER_ID;} + if (bufferType!=SVA_BITSTREAM_BUFFER_TYPE) {return SVA_INVALID_BUFFER_TYPE;} + + + + /*allow service to use this memory*/ + status=sva_GenericPush(serviceId,bufferId,mode,bufferType,timeStamp); + + return status; +} + +/****************************************************************************/ +/* NAME: t_sva_error SVA_AssertEndOfBitstream( */ +/* t_sva_service_id serviceId */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine allows to signal the end of a bitstream push. This */ +/* function may be used with video or still decoders */ +/* */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - serviceId: service identifier */ +/* */ +/* OUT : */ +/* - none */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/* - SVA_UNKNOWN_SERVICE_ID : service id is unknown */ +/* - SVA_NOT_SUPPORTED_YET : service is not yet supported */ +/* - SVA_INTERNAL__ERROR : internal error inside service */ +/* - SVA_UNEXPECTED_API_CALL : API is not supposed to be call in */ +/* service current state. */ +/* - SVA_INTERNAL_FIFOS_FULL : service fifo are full and can't */ +/* accept buffer for the moment. */ +/* - SVA_OK */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +t_sva_error SVA_AssertEndOfBitstream(t_sva_service_id serviceId) +{ + t_sva_error status; + t_sva_sv_task_id taskId = READ_TASK_ID_IN_SERVICE_ID(serviceId); + + /* allow service to use this memory */ + if (sva_OM_isOpenService(serviceId)==TRUE) + { + status=SVA_NOT_SUPPORTED_YET; + } + else + { + switch(taskId) + { + case SVA_SV_GRAB_TID: + status=SVA_NOT_SUPPORTED_YET; + break; + case SVA_SV_DECODE_TID: + status=sva_DC_AssertEndOfBitstream(serviceId); + break; + case SVA_SV_ENCODE_TID: + status=SVA_NOT_SUPPORTED_YET; + break; + case SVA_SV_DISPLAY_TID: + status=SVA_NOT_SUPPORTED_YET; + break; + case SVA_SV_STILL_ENCODE_TID: + status=SVA_NOT_SUPPORTED_YET; + break; + case SVA_SV_STILL_DECODE_TID: + /* status=sva_SDC_ProvideInternalNeeds(serviceId); */ + status=sva_SDC_AssertEndOfBitstream(serviceId); + break; + case SVA_SV_TVO_TID: + status=SVA_NOT_SUPPORTED_YET; + break; + case SVA_SV_STAB_TID: + status=SVA_NOT_SUPPORTED_YET; + break; + default: + status=SVA_UNKNOWN_SERVICE_ID; + break; + } + } + return status; +} + +/****************************************************************************/ +/* NAME: t_sva_error SVA_PushImageBuffer( */ +/* t_sva_service_id serviceId, */ +/* t_sva_buffer_id bufferId, */ +/* t_sva_push_mode mode, */ +/* t_sva_timestamp timeStamp */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine pushes a "defined" or "allocated" buffer into the HCL. */ +/* The buffer will be used: */ +/* - to put grabbed/reconstructed/reference image data */ +/* - to put decoded image data */ +/* - to put YUV image data as post-P input or output */ +/* - to put RGB image as post-P output */ +/* The service must be configured. */ +/* */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - serviceId: service identifier */ +/* - bufferId: buffer identifier */ +/* - mode: SVA_PUSH_IN / SVA_PUSH_OUT */ +/* - timeStamp: timestamp related to the buffer */ +/* */ +/* OUT : */ +/* - none */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/* - SVA_UNKNOWN_SERVICE_ID : service id is unknown */ +/* - SVA_NOT_SUPPORTED_YET : service is not yet supported */ +/* - SVA_INTERNAL__ERROR : internal error inside service */ +/* - SVA_UNEXPECTED_API_CALL : API is not supposed to be call in */ +/* service current state. */ +/* - SVA_UNKNOWN_BUFFER_ID : buffer id is unknown */ +/* - SVA_INVALID_BUFFER_TYPE : buffer type is not a bitstream one */ +/* - SVA_INTERNAL_FIFOS_FULL : service fifo are full and can't */ +/* accept buffer for the moment. */ +/* - SVA_OK */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +t_sva_error SVA_PushImageBuffer( + t_sva_service_id serviceId, + t_sva_buffer_id bufferId, + t_sva_push_mode mode, + t_sva_timestamp timeStamp +) +{ + t_sva_error status; + t_sva_bm_error bmError; + t_sva_buffer_type bufferType; + + /*check that buffer type is correct*/ + bmError=sva_BM_GetBufferType(bufferId,&bufferType); + if (bmError!=SVA_BM_OK) {return SVA_UNKNOWN_BUFFER_ID;} + if (bufferType!=SVA_IMAGE_BUFFER_TYPE) {return SVA_INVALID_BUFFER_TYPE;} + + + + /*allow service to use this memory*/ + status=sva_GenericPush(serviceId,bufferId,mode,bufferType,timeStamp); + + return status; +} + +/****************************************************************************/ +/* NAME: t_sva_error SVA_PushInfosBuffer( */ +/* t_sva_service_id serviceId, */ +/* t_sva_buffer_id bufferId, */ +/* t_sva_push_mode mode */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine pushes a "defined" or "allocated" buffer into the HCL. */ +/* The service must be configured. */ +/* */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - serviceId: service identifier */ +/* - bufferId: buffer identifier */ +/* - mode: SVA_PUSH_IN / SVA_PUSH_OUT */ +/* */ +/* OUT : */ +/* - none */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/* - SVA_UNKNOWN_SERVICE_ID : service id is unknown */ +/* - SVA_NOT_SUPPORTED_YET : service is not yet supported */ +/* - SVA_INTERNAL__ERROR : internal error inside service */ +/* - SVA_UNEXPECTED_API_CALL : API is not supposed to be call in */ +/* service current state. */ +/* - SVA_UNKNOWN_BUFFER_ID : buffer id is unknown */ +/* - SVA_INVALID_BUFFER_TYPE : buffer type is not a bitstream one */ +/* - SVA_INTERNAL_FIFOS_FULL : service fifo are full and can't */ +/* accept buffer for the moment. */ +/* - SVA_OK */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +t_sva_error SVA_PushInfosBuffer( + t_sva_service_id serviceId, + t_sva_buffer_id bufferId, + t_sva_push_mode mode +) +{ + t_sva_error status; + t_sva_bm_error bmError; + t_sva_buffer_type bufferType; + t_sva_timestamp timeStamp={SVA_NO_TIMESTAMP,0}; + + /*check that buffer type is correct*/ + bmError=sva_BM_GetBufferType(bufferId,&bufferType); + if (bmError!=SVA_BM_OK) {return SVA_UNKNOWN_BUFFER_ID;} + if (bufferType!=SVA_INFOS_BUFFER_TYPE) {return SVA_INVALID_BUFFER_TYPE;} + + + + /*allow service to use this memory*/ + status=sva_GenericPush(serviceId,bufferId,mode,bufferType,timeStamp); + + return status; +} + +/****************************************************************************/ +/* NAME: t_sva_error SVA_PushParamsBuffer( */ +/* t_sva_service_id serviceId, */ +/* t_sva_buffer_id bufferId, */ +/* t_sva_push_mode mode */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine pushes a "defined" or "allocated" buffer into the HCL. */ +/* The service must be configured. */ +/* */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - serviceId : service identifier */ +/* - bufferId : buffer identifier */ +/* - mode: SVA_PUSH_IN / SVA_PUSH_OUT */ +/* */ +/* OUT : */ +/* - none */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/* - SVA_UNKNOWN_SERVICE_ID : service id is unknown */ +/* - SVA_NOT_SUPPORTED_YET : service is not yet supported */ +/* - SVA_INTERNAL__ERROR : internal error inside service */ +/* - SVA_UNEXPECTED_API_CALL : API is not supposed to be call in */ +/* service current state. */ +/* - SVA_UNKNOWN_BUFFER_ID : buffer id is unknown */ +/* - SVA_INVALID_BUFFER_TYPE : buffer type is not a bitstream one */ +/* - SVA_INTERNAL_FIFOS_FULL : service fifo are full and can't */ +/* accept buffer for the moment. */ +/* - SVA_OK */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +t_sva_error SVA_PushParamsBuffer( + t_sva_service_id serviceId, + t_sva_buffer_id bufferId, + t_sva_push_mode mode +) +{ + t_sva_error status; + t_sva_bm_error bmError; + t_sva_buffer_type bufferType; + t_sva_timestamp timeStamp={SVA_NO_TIMESTAMP,0}; + + /*check that buffer type is correct*/ + bmError=sva_BM_GetBufferType(bufferId,&bufferType); + if (bmError!=SVA_BM_OK) {return SVA_UNKNOWN_BUFFER_ID;} + if (bufferType!=SVA_PARAMS_BUFFER_TYPE) {return SVA_INVALID_BUFFER_TYPE;} + + + + /*allow service to use this memory*/ + status=sva_GenericPush(serviceId,bufferId,mode,bufferType,timeStamp); + + return status; +} + + +/****************************************************************************/ +/* NAME: t_sva_error SVA_GetParamsBufferSize( */ +/* t_sva_service_id serviceId, */ +/* t_sva_push_mode mode, */ +/* t_size *pSize */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine returns the size of the params buffer of the conf- */ +/* igured service. */ +/* */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - serviceId: service identifier */ +/* - mode: SVA_PUSH_IN / SVA_PUSH_OUT */ +/* */ +/* OUT : */ +/* - pSize: size of the params buffer */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/* SVA_UNKNOWN_SERVICE_ID */ +/* SVA_UNEXPECTED_API_CALL */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +t_sva_error SVA_GetParamsBufferSize( + t_sva_service_id serviceId, + t_sva_push_mode mode, + t_size *pSize +) +{ + t_sva_error status; + t_sva_sv_task_id taskId=READ_TASK_ID_IN_SERVICE_ID(serviceId); + + HCL_ASSERT(pSize!=NULL); + *pSize=0; + /*allow service to use this memory*/ + if (sva_OM_isOpenService(serviceId)==TRUE) + { + status=SVA_NOT_SUPPORTED_YET; + } + else + { + switch(taskId) + { + case SVA_SV_GRAB_TID: + status=SVA_NOT_SUPPORTED_YET; + break; + case SVA_SV_DECODE_TID: + status=sva_DC_GetParamsBufferSize(serviceId,mode,pSize); + break; + case SVA_SV_ENCODE_TID: + status=sva_EC_GetParamsBufferSize(serviceId,mode,pSize); + break; + case SVA_SV_DISPLAY_TID: + status=sva_DP_GetParamsBufferSize(serviceId,mode,pSize); + break; + case SVA_SV_STILL_ENCODE_TID: + status=SVA_NOT_SUPPORTED_YET; + break; + case SVA_SV_STILL_DECODE_TID: + status=sva_SDC_GetParamsBufferSize(serviceId,mode,pSize); + break; + case SVA_SV_TVO_TID: + status=SVA_NOT_SUPPORTED_YET; + break; + case SVA_SV_STAB_TID: + status=sva_ST_GetParamsBufferSize(serviceId,mode,pSize); + break; + default: + status=SVA_UNKNOWN_SERVICE_ID; + break; + } + } + + return status; +} + +/****************************************************************************/ +/* NAME: t_sva_error sva_GenericPush( */ +/* t_sva_service_id serviceId, */ +/* t_sva_buffer_id bufferId, */ +/* t_sva_push_mode mode, */ +/* t_sva_buffer_type bufferType, */ +/* t_sva_timestamp timeStamp */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine do the common part of various push variant at API level*/ +/* */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - serviceId: service identifier */ +/* - bufferId: buffer identifier */ +/* - mode: SVA_PUSH_IN / SVA_PUSH_OUT */ +/* - bufferType : type of buffer to push */ +/* - timeStamp: timestamp related to the buffer */ +/* */ +/* OUT : */ +/* - none */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/* - SVA_UNKNOWN_SERVICE_ID : service id is not correct */ +/* - SVA_NOT_SUPPORTED_YET : service is not yet supported */ +/* - SVA_UNEXPECTED_API_CALL : Command cannot be excecuted in */ +/* current context. */ +/* - SVA_INTERNAL__ERROR : internal error inside service */ +/* - SVA_INVALID_BUFFER_TYPE : buffer type is not handle by grab */ +/* - SVA_INTERNAL_FIFOS_FULL : internal fifos are full */ +/* - SVA_OK */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_sva_error sva_GenericPush( + t_sva_service_id serviceId, + t_sva_buffer_id bufferId, + t_sva_push_mode mode, + t_sva_buffer_type bufferType, + t_sva_timestamp timeStamp +) +{ + t_sva_sv_task_id taskId=READ_TASK_ID_IN_SERVICE_ID(serviceId); + t_sva_error status; + + if (sva_OM_isOpenService(serviceId)==TRUE) + { + status=SVA_NOT_SUPPORTED_YET; + } + else + { + switch(taskId) + { + case SVA_SV_GRAB_TID: + status=sva_GB_Push(serviceId,bufferId,mode,bufferType,timeStamp); + break; + case SVA_SV_DECODE_TID: + status=sva_DC_Push(serviceId,bufferId,mode,bufferType); + break; + case SVA_SV_ENCODE_TID: + status=sva_EC_Push(serviceId,bufferId,mode,bufferType,timeStamp); + break; + case SVA_SV_DISPLAY_TID: + status=sva_DP_Push(serviceId,bufferId,mode,bufferType,timeStamp); + break; + case SVA_SV_STILL_ENCODE_TID: + status=sva_SEC_Push(serviceId, bufferId, mode, bufferType, timeStamp); + break; + case SVA_SV_STILL_DECODE_TID: + status=sva_SDC_Push(serviceId, bufferId, mode, bufferType); + break; + case SVA_SV_TVO_TID: + status=sva_TV_Push(serviceId,bufferId,mode,bufferType,timeStamp); + break; + case SVA_SV_STAB_TID: + status=sva_ST_Push(serviceId,bufferId,mode,bufferType,timeStamp); + break; + default: + status=SVA_UNKNOWN_SERVICE_ID; + break; + } + } + + return status; +} + + +/****************************************************************************/ +/* NAME: SVA_SetHeaderInfos() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: This routine enables to give Header infos (dynamic params) */ +/* related to a given bitstream buffer and also */ +/* the address of the first byte of coded data taken into account by SVA */ +/* (relative to buffer start) */ +/* MPEG4 SH: first byte of first gob layer */ +/* MPEG4 SP: first byte of first motion texture */ +/* */ +/* PARAMETERS: */ +/* IN : t_sva_service_id serviceId : */ +/* t_sva_buffer_id bitstreamBufferId: */ +/* t_uint32 byteOffset (in bytes ) */ +/* t_uint32 bitOffset (in bits) */ +/* const t_sva_header_infos *pHeaderInfos */ +/* OUT :none */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/* - SVA_OK : header provided successfully */ +/* - SVA_NOT_BITSTREAM_BUFFER : buffer id provided does not correpond*/ +/* to a bitstream buffer */ +/* - SVA_FIFO_FULL: header is rejected has internal fifo is full */ +/*--------------------------------------------------------------------------*/ +/* USE: NA */ +/* USED BY: NA */ +/****************************************************************************/ +PUBLIC t_sva_error SVA_SetHeaderInfos +( + t_sva_service_id serviceId, + t_sva_buffer_id bitstreamBuffer, + t_uint32 byteOffset, + t_uint32 bitOffset, + const t_sva_header_infos *pHeaderInfos +) +{ + t_sva_sv_task_id taskId=READ_TASK_ID_IN_SERVICE_ID(serviceId); + t_sva_error status; + + if (sva_OM_isOpenService(serviceId)==TRUE) + { + status=SVA_NOT_SUPPORTED_YET; + } + else + { + switch(taskId) + { + case SVA_SV_DECODE_TID: + status=sva_DC_SetHeaderInfos(serviceId, bitstreamBuffer, byteOffset, bitOffset, pHeaderInfos); + break; + case SVA_SV_STILL_DECODE_TID: + status=sva_SDC_SetHeaderInfos(serviceId, bitstreamBuffer, byteOffset, bitOffset, pHeaderInfos); + break; + default: + status=SVA_UNKNOWN_SERVICE_ID; + break; + } + } + return status; +} + --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/sva.h @@ -0,0 +1,2148 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ + +#ifndef __INC_SVA_H +#define __INC_SVA_H + +#include "hcl_defs.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* + * Definition of the HCL SVA Version numbers + */ +#define SVA_HCL_VERSION_ID 8 +#define SVA_HCL_MAJOR_ID 0 +#define SVA_HCL_MINOR_ID 0 + +/* + * Definition of unknown version number + + */ +#define UNDEFINED_VERSION {MASK_ALL8,MASK_ALL8,MASK_ALL16} + +/* + * define symbol to disallow grab sync line generation + */ +#define SVA_NO_GRABSYNC_LINE 0x3ff + +/* + * define search window size in ESRAM (encode and stab) + */ + +#define SVA_EC_SEARCHWINDOW_SIZE (48*1024) + +/* Maximum number of video packets generated by Firmware per frame */ +/**<\brief positions of the first video packets (up to 32) +* that have been written by an MPEG4encode subtask. It is +* used only when flag_short_header=0. The positions are +* given in bytes,relatively to the beginning of the +* bitstream that has been written,including the header. +*/ +#define SVA_EC_MPEG4_VP_POS_COUNT 32 + +/* Maximum number of video slices generated by Firmware per frame */ +/* Positions of the 1st slices (up to 32) */ +#define SVA_EC_H263_SLICE_POS_COUNT 32 + +/* Maximum number of video slices generated by Firmware Per frame */ +/**<\brief positions of the first slices (up to 1320 enough for SDTV) that have been written by an H264 encode subtask. */ +//\/ Sarvesh: This size has been increased from 32 to 1320 for H264 Encode and to 1620 with FW 3.6.0 +#define SVA_EC_H264_SLICE_POS_COUNT 1620 + +#define SVA_LAST_IAD_EOT_ERR_RESET_VAL 0x45524F52UL + +typedef enum { + SVA_IRQ +} t_sva_irq_src; + +/* + * Define type used to memorize the current status of the IRQ sources + */ +typedef struct { + t_uint32 dummy_tab[30]; +}t_sva_irq_status; + +typedef enum { +SVA_LAST_ERROR = -64, +/* Internal HCL errors */ +SVA_INTERNAL_MEMORY_MGT_ERROR, +SVA_INTERNAL_VIDEO_DECODER_ERROR, +SVA_INTERNAL_VIDEO_ENCODER_ERROR, +SVA_INTERNAL_STILL_DECODER_ERROR, +SVA_INTERNAL_STILL_ENCODER_ERROR, +SVA_INTERNAL_POSTPROCESSOR_ERROR, +SVA_INTERNAL_PREPROCESSOR_ERROR, +SVA_INTERNAL_TV_OUTPUT_ERROR, +SVA_INTERNAL_SWPROCESSOR_ERROR, +SVA_INTERNAL_EVENT_MGT_ERROR, +SVA_INTERNAL_NEEDS_ERROR, +SVA_INTERNAL_TASK_MGT_ERROR, +/* Wrong HCL usage */ +SVA_IMAGE_BUFFER_TOO_SMALL, +SVA_INCOHERENT_CONFIGURATION, +SVA_UNEXPECTED_API_CALL, +SVA_MISALIGNED_BUFFER, +SVA_BUFFER_IS_IN_USE, +SVA_UNKNOWN_SERVICE_ID, +SVA_INCOHERENT_SERVICE_TYPE, +SVA_UNKNOWN_CMD_ID, +SVA_UNKNOWN_BUFFER_ID, +SVA_INVALID_BUFFER_TYPE, +SVA_OUT_OF_MEMORY, +SVA_NO_MORE_CHUNK, +SVA_NO_MORE_FW_ID, +SVA_UNKNOWN_FW_ID, +SVA_FW_CONFLICT, +SVA_FW_NOT_PROVIDED, +SVA_INCOHERENT_FW_PROVIDED, +SVA_NOT_SUPPORTED_YET, +SVA_UNREGISTERED_FIRMWARE_ID, +SVA_NO_MORE_FIRMWARE_ID, +SVA_FATAL_ERROR = -4, +SVA_INTERNAL_FIFOS_FULL, +SVA_FW_DOWNLOAD_NEEDED, +SVA_OK = HCL_OK, +SVA_REMAINING_PENDING_EVENTS = HCL_REMAINING_PENDING_EVENTS, +SVA_NO_MORE_PENDING_EVENT = HCL_NO_MORE_PENDING_EVENT, +SVA_NO_PENDING_EVENT_ERROR = HCL_NO_PENDING_EVENT_ERROR, +SVA_IMMEDIATE_UPDATE, +SVA_DELAYED_UPDATE, +SVA_FW_SWITCH_OCCURED, +SVA_FW_SWITCH_DELAYED, +SVA_CONFIGURATION_IN_PROGRESS, +SVA_VIDEO_DECODER_IMAGE_BUFFER_NEEDED, +SVA_VIDEO_ENCODER_DATA_ERROR, +SVA_INSUFFICIENT_MEMORY, +} t_sva_error; + + +typedef enum { +SVA_IRQ_0, +SVA_IRQ_1 +}t_sva_irq_num; + + +typedef enum { +SVA_SERVICE_NONE = 0, +SVA_PREPROCESSOR = 1, +SVA_VIDEO_DECODER = 2, +SVA_VIDEO_ENCODER = 3, +SVA_POSTPROCESSOR = 4, +SVA_STILL_IMAGE_ENCODER = 5, +SVA_STILL_IMAGE_DECODER = 6, +SVA_TV_OUTPUT = 7, +SVA_SW_PROCESSING = 8, +SVA_OPEN_SERVICE_0 = 128, +SVA_OPEN_SERVICE_1 = 129, +SVA_OPEN_SERVICE_2 = 130, +SVA_OPEN_SERVICE_3 = 131, +SVA_OPEN_SERVICE_4 = 132, +SVA_OPEN_SERVICE_5 = 133, +SVA_OPEN_SERVICE_6 = 134, +SVA_OPEN_SERVICE_7 = 135 +}t_sva_service_type; + + +typedef enum { +SVA_REALTIME_SERVICE, +SVA_NON_REALTIME_SERVICE +} t_sva_service_mode; + + +typedef enum { +SVA_SERVICE_NOT_INITIALIZED = MASK_BIT0, +SVA_SERVICE_WAIT_FOR_CONFIGURATION = MASK_BIT1, +SVA_SERVICE_WAIT_FOR_INTERNAL_NEEDS = MASK_BIT2, +SVA_SERVICE_WAIT_FOR_ACTIVATE = MASK_BIT3, +SVA_SERVICE_WAIT_FOR_START = MASK_BIT4, +SVA_SERVICE_FLUSHING = MASK_BIT5, +SVA_SERVICE_WAIT_FOR_DATA = MASK_BIT6, +SVA_SERVICE_RUNNING = MASK_BIT7, +SVA_SERVICE_ABORT_REQUESTED = MASK_BIT8, +SVA_SERVICE_STOP_REQUESTED = MASK_BIT9, +SVA_SERVICE_ERROR = MASK_BIT10 +} t_sva_service_state; + + +typedef enum { +SVA_UNKNOWN_BUFFER_TYPE = 0, +SVA_BITSTREAM_BUFFER_TYPE, +SVA_IMAGE_BUFFER_TYPE, +SVA_INFOS_BUFFER_TYPE, +SVA_PARAMS_BUFFER_TYPE, +SVA_INTERNAL_BUFFER_TYPE +} t_sva_buffer_type; + +typedef enum { +SVA_VC1_DEDICATED_BUFFER, +SVA_GB_HQ_DEDICATED_BUFFER +} t_sva_buffer_usage; + +typedef enum { +SVA_BUFFER_NOT_INIT, +SVA_BUFFER_NOT_USED, +SVA_BUFFER_IN_USE, +SVA_BUFFER_VOIDED, +SVA_BUFFER_FILLED +} t_sva_buffer_state; + + +typedef enum { +SVA_PUSH_IN, +SVA_PUSH_OUT +} t_sva_push_mode; + + +typedef enum { +SVA_INOUT_STREAM, +SVA_INOUT_BITSTREAM_BUFFER, +SVA_INOUT_IMAGE_BUFFER, +SVA_INOUT_INFOS_BUFFER, +SVA_INOUT_PARAMS_BUFFER +} t_sva_inout_type; + + +typedef enum { +SVA_INOUT_BINARY, // this format will be used for buffer whose internal organization is +// unknown or contain data of a unique type (Y/U/V) (JPEG case) +SVA_INOUT_YUV422, +SVA_INOUT_YUV420, +SVA_INOUT_RGB444, +SVA_INOUT_RGB555, +SVA_INOUT_RGB565, +SVA_INOUT_RGB888_PACKED, +SVA_INOUT_RGB888_UNPACKED, +SVA_INOUT_PARAMS_DEBLOCKING, //identify a buffer containing the deblocking filter parameters +SVA_INOUT_PARAMS_ACE, //identify a buffer containing the ACE offset from JPEG decode +// List various type of info buffer those could be provided by the various services +SVA_INOUT_INFO_VIDEO_ENCODER, // linked to the codec (MPEG4/H263/...) +SVA_INOUT_INFO_VIDEO_DECODER // linked to the codec (MPEG4/H263/...) +} t_sva_inout_format; + + +typedef enum { +SVA_PREPROCESSOR_RAW, +SVA_PREPROCESSOR_YUV420_MB, +SVA_PREPROCESSOR_YUV420_SEP_COMP_MB, +SVA_PREPROCESSOR_YUV422_SEP_COMP_MB, +SVA_PREPROCESSOR_YUV420_RASTER_OUT, +SVA_PREPROCESSOR_SENSOR_YUV420_MB, +SVA_PREPROCESSOR_SENSOR_YUV420_SEP_COMP_MB, +SVA_PREPROCESSOR_SENSOR_YUV422_SEP_COMP_MB, +SVA_PREPROCESSOR_SENSOR_YUV420_RASTER_OUT, +SVA_PREPROCESSOR_SENSOR_HIGHQUALITY_YUV420_MB +} t_sva_preprocessor_capability_id; + + +typedef enum { +SVA_POSTPROCESSOR_RGB=0, // YUV420 Macroblock tiled to RGB +SVA_POSTPROCESSOR_YUV=1, // YUV422 format (used as TVO input) + +SVA_POSTPROCESSOR_YUV420PL_TO_RGB=2, // YUV420 planar raster to RGB +SVA_POSTPROCESSOR_YUV420MB_TO_YUV420MB=3, // YUV420 MB tiled to YUV420 MB tiled +SVA_POSTPROCESSOR_YUV420PL_TO_YUV422PL=4, +SVA_POSTPROCESSOR_YUV422PL_TO_RGB=5, // NOT SUPPORTED!!!! +SVA_POSTPROCESSOR_YUV420MB_TO_RGB = SVA_POSTPROCESSOR_RGB, // YUV420 Macroblock tiled to RGB +SVA_POSTPROCESSOR_YUV420MB_TO_YUV422PL = SVA_POSTPROCESSOR_YUV, // YUV420 MB tiled to YUV422 planar raster (TVO input) +SVA_POSTPROCESSOR_YUV420MB_TO_YUV420_SEP_COMP_MB=6, +SVA_POSTPROCESSOR_YUV420MB_TO_YUV422_SEP_COMP_MB=7, +} t_sva_postprocessor_capability_id; + + +typedef enum { +SVA_DECODER_H263_P0_L10, +SVA_DECODER_H263_P0_L30, +SVA_DECODER_H263_P3_L10, +SVA_DECODER_H263_P3_L30, +SVA_DECODER_MPEG4_SP_L4A, +SVA_DECODER_H264, +SVA_DECODER_VC1_MP_LL, +SVA_DECODER_MPEG2_MP_ML +} t_sva_video_decoder_capability_id; + + +typedef enum { +SVA_ENCODER_H263_P0_L10, +SVA_ENCODER_H263_P0_L30, +SVA_ENCODER_H263_P3_L10, +SVA_ENCODER_H263_P3_L30, +SVA_ENCODER_MPEG4_SP_L4A, +SVA_ENCODER_H264 +} t_sva_video_encoder_capability_id; + + +typedef enum { + SVA_IMAGE_STABILIZATION +} t_sva_sw_processing_capability_id; + + +typedef enum { +SVA_ENCODER_JPEG_MONOCHROME, +SVA_ENCODER_JPEG_420_SEP_COMP_MB, +SVA_ENCODER_JPEG_422_SEP_COMP_MB, +SVA_ENCODER_JPEG_444_SEP_COMP_MB, +SVA_ENCODER_JPEG_420_MB +} t_sva_still_image_encoder_capability_id; + + +typedef enum { +SVA_DECODER_PROGRESSIVE_JPEG, +SVA_DECODER_SEQUENTIAL_JPEG +} t_sva_still_image_decoder_capability_id; + + +typedef enum { +SVA_NO_MIRRORING, +SVA_HORIZONTAL_MIRRORING, +SVA_VERTICAL_MIRRORING +} t_sva_mirroring_mode; + + +typedef enum { +SVA_NO_ROTATION, +SVA_ROTATION_90, +SVA_ROTATION_180, +SVA_ROTATION_270 +} t_sva_rotation_mode; + + +#define NUMBER_OF_DEBLOCKING_FILTER_MODE 4 +typedef enum { +SVA_NONE_DEBLOCKING_FILTER, +SVA_MPEG4_DEBLOCKING_FILTER, +SVA_H263_DEBLOCKING_FILTER, +SVA_H264_DEBLOCKING_FILTER, +SVA_MPEG2_DEBLOCKING_FILTER +} t_sva_deblocking_filter_mode; + + +#define NUMBER_OF_DERINGING_FILTER_MODE 3 +typedef enum { +SVA_NONE_DERINGING_FILTER, +SVA_MPEG4_DERINGING_FILTER, +SVA_H264_DERINGING_FILTER, +SVA_MPEG2_DERINGING_FILTER +} t_sva_deringing_filter_mode; + + +typedef enum { +SVA_CODEC_IMAGE_MODE, +SVA_CODEC_SEGMENTED_MODE, +SVA_CODEC_STREAM_MODE +//SVA_CODEC_CIRCULAR_MODE +} t_sva_codec_mode; + +typedef enum { +SVA_VC1_IMAGE_BUFFER_AREA, +SVA_H264_INTERNAL_AREA, +SVA_H264_ENC_FW_PROG_ZONE1_AREA, +SVA_SW_PREPROC_BUFFER_AREA +}t_sva_dedicated_area_purpose; + +/* + * Define the type used to provide parameters related to a given algorithm + * when configuring a Codec (decoder or encoder) + * (static parameters (bitstream related vs frame related)). + * For each kind of codec supported (MPEG4, H263,..), we provide + * a specific t_sva__algo__configuration_params type. + */ +typedef void * tp_sva_codec_algo_configuration_params; + +typedef enum { +SVA_PREPROCESSING_RESIZE = MASK_BIT0, +SVA_PREPROCESSING_CROP = MASK_BIT1 +} t_sva_preprocessing_transform_type; + + +typedef enum { +SVA_ENCODING_CROP = MASK_BIT0 +} t_sva_encoding_transform_type; + +typedef enum { +SVA_POSTPROCESSING_RESIZE = MASK_BIT0, +SVA_POSTPROCESSING_CROP = MASK_BIT1, +SVA_POSTPROCESSING_CLIP = MASK_BIT2, +SVA_POSTPROCESSING_MIRROR_H = MASK_BIT3, +SVA_POSTPROCESSING_MIRROR_V = MASK_BIT4, +SVA_POSTPROCESSING_ROTATE_90 = MASK_BIT5, +SVA_POSTPROCESSING_ROTATE_180 = MASK_BIT6, +SVA_POSTPROCESSING_ROTATE_270 = MASK_BIT7, +SVA_POSTPROCESSING_DITHERING = MASK_BIT8, +SVA_POSTPROCESSING_DEBLOCKING_FILTER = MASK_BIT9, +SVA_POSTPROCESSING_DERINGING_FILTER = MASK_BIT10 +} t_sva_postprocessing_transform_type; + + +typedef enum { +SVA_SERVICE_RESET = 1, +SVA_SERVICE_ABORT, +SVA_SERVICE_STOP, +SVA_SERVICE_START, +SVA_SERVICE_FLUSH_IN, +SVA_SERVICE_FLUSH_OUT +} t_sva_service_cmd_id; + + +typedef enum { +SVA_UPDATE_MULTIPLE, +SVA_UPDATE_LAST, +SVA_UPDATE_REVERT +} t_sva_update_cmd_type; + + +typedef enum { +/* no dynamic param identified today */ +SVA_VIDEO_DECODER_PARAM_DUMMY +} t_sva_video_decoder_param_id; + + +typedef enum { +SVA_ENCODER_REQUEST_INTRA, //parameter: a pointer to a structure t_sva_intra_request +SVA_ENCODER_BITRATE, // parameter : new bitrate in bit/s +SVA_ENCODER_FRAME_RATE, // parameter : value of new source frame rate => use only as info whensource frame rate change +SVA_ENCODER_SPATIAL_QUALITY, // parameter : t_sva_spatial_quality value +SVA_ENCODER_MIN_FRAME_RATE, // parameter : new mininum output frame rate +SVA_ENCODER_PICTURE_INTRA_REFRESH, // parameter : new interval between two I pictures +SVA_ENCODER_HEADER_FREQUENCY, // parameter : new gobHeaderFrequency in short header / newhecFreq in simple profile +SVA_ENCODER_AIR_MB_NUM, // parameter : new air macroblock number +SVA_ENCODER_CIR_PERIOD, // parameter : new refresh period for cir mode +SVA_ENCODER_PACKET_SIZE, // parameter : new packet size in bit +SVA_ENCODER_PACKET_SIZE_INFO // added for cr 190 +} t_sva_video_encoder_param_id; + +typedef enum { +SVA_PREPROCESSOR_CROPPING, /* parameter: a pointer to a t_sva_window_desc structure */ +SVA_PREPROCESSOR_RESIZE, /* parameter: a pointer to a t_sva_image_desc structure */ +SVA_PREPROCESSOR_GRAB_LINE_NUMBER_SYNC, /* parameter: line number */ +SVA_PREPROCESSOR_ACE_ENABLE, /* parameter : a boolean : TRUE => enable ace / FALSE => disable ace */ +SVA_PREPROCESSOR_ACE_STRENGTH, /* parameter : a t_sva_ace_strength value */ +SVA_PREPROCESSOR_ACE_RANGE, /* parameter : a t_sva_color_range value */ +SVA_PREPROCESSOR_OUTPUT_RANGE, /* parameter : a t_sva_color_range value */ +SVA_PREPROCESSOR_ACE_OFFSET, /* parameter: a pointer to a t_sva_ace_offset structure */ +SVA_PREPROCESSOR_PACKET_WRITE, /* parameter: a pointer to a t_sva_packet structure */ +SVA_PREPROCESSOR_PACKET_READ, /* parameter: a pointer to a t_sva_packet structure */ +SVA_PREPROCESSOR_HQ_STATUS_READ, /* Gives the status of HQ Grab substask, parameter: a pointer to a t_sva_gb_hq_status structure */ +SVA_PREPROCESSOR_HQ_STATUS_TST, /* Used to test geabHQ, set this to one when you need to stop at each stage */ +SVA_PREPROCESSOR_HQ_PREPROC, /* Dynamic update of grabhq preproc params */ +SVA_PREPROCESSOR_HQ_READ_NB_FAILURE_BML_PROCESS /* Read status of BML retries made for a BML process, Parameter: A pointer to a t_uint32 value */ +} t_sva_preprocessor_param_id; + +typedef enum { +SVA_POSTPROCESSOR_PPP_TILE, +SVA_POSTPROCESSOR_PIP, // parameter: a pointer to a t_sva_window_desc structure +// (if pointer NULL, then PIP disabled) +SVA_POSTPROCESSOR_CONTRAST, // a pointer to t_uint32 value which points to contrast range [0, 100] +SVA_POSTPROCESSOR_BRIGHTNESS, // a pointer to t_uint32 value which points to brightness in range [0, 100] +SVA_POSTPROCESSOR_DITHERING, // a pointer to t_uint32 value which points to Dithering 0: off - 1: on +SVA_POSTPROCESSOR_MIRRORING, // a pointer to t_uint32 value 0:off-1(SVA_HORIZONTAL_MIRRORING)-2(SVA_VERTICAL_MIRRORING) +SVA_POSTPROCESSOR_ROTATION, //a pointer to t_uint32 value 0:off-90(SVA_ROTATE_90)-180(SVA_ROTATE_180)-270(SVA_ROTATE_270) +SVA_POSTPROCESSOR_FRAME_ALPHAKEY, //a pointer to t_uint32 value,new alpha key value +SVA_POSTPROCESSOR_CROPPING, // parameter: a pointer to a t_sva_window_desc structure (input) +SVA_POSTPROCESSOR_RESIZE, // parameter: a pointer to a t_sva_image_desc structure +SVA_POSTPROCESSOR_CLIPPING, // parameter: a pointer to a t_sva_window_desc structure (output) +SVA_POSTPROCESSOR_SOURCEFRAME_SIZE,//NOT IMPLEMENTED YET // parameter: a pointer to t_sva_image_desc (input) +SVA_POSTPROCESSOR_VIDEOFRAME_SIZE,//NOT IMPLEMENTED YET // parameter: a pointer to t_sva_image_desc (output) +SVA_POSTPROCESSOR_SCREEN_WINDOW_OFFSET,// parameter: pointer to t_sva_offset_desc structure +SVA_POSTPROCESSOR_SCREEN_BUFFER_ADDR, // parameter: a t_physical_address value +SVA_POSTPROCESSOR_ALT_SCREEN_BUFFER_ADDR, // parameter: a t_physical_address value +SVA_POSTPROCESSOR_MATRIX_COEFF, // parameter: a pointer to t_sva_postprocessor_color_matrix +SVA_POSTPROCESSOR_ANTI_TEARING_EFFECT, // parameter: 0: off - 1: on +SVA_POSTPROCESSOR_ACE_ENABLE, // not used anymore +SVA_POSTPROCESSOR_ACE_STRENGTH, // parameter : a t_sva_ace_strength value +SVA_POSTPROCESSOR_ACE_RANGE, // parameter : a t_sva_color_range value +SVA_POSTPROCESSOR_ACE_OFFSET, // parameter: a pointer to a t_sva_ace_offset structure (see §4.38) +SVA_POSTPROCESSOR_OUTPUT_RANGE, // parameter : a t_sva_color_range value +SVA_POSTPROCESSOR_REDBLUESWAP +} t_sva_postprocessor_param_id; + + +typedef enum { +/* no dynamic param identified today */ +SVA_SW_PROCESSING_PARAM_DUMMY +} t_sva_sw_processing_param_id; + + +typedef enum { +/* no dynamic param identified today */ +SVA_STILL_ENCODER_PARAM_DUMMY +} t_sva_still_encoder_param_id; + + +typedef enum { +/* no dynamic param identified today */ +SVA_STILL_DECODER_PARAM_DUMMY +} t_sva_still_decoder_param_id; + + +typedef enum { +SVA_TVO_CROPPING, // parameter: a pointer to a t_sva_window_desc structure +SVA_TVO_WINDOW_OFFSET, // parameter: pointer to t_sva_offset_desc structure +SVA_TVO_BACKGROUND_COLOR // parameter: pointer to t_sva_yuv_color structure +} t_sva_tvo_param_id; + + +typedef enum { +SVA_NO_TIMESTAMP, +SVA_PRESENTATION_TIMESTAMP, +SVA_DECODING_TIMESTAMP, +SVA_GRABBING_TIMESTAMP +} t_sva_timestamp_type; + + +typedef enum { +SVA_COLOR_12BITS, +SVA_COLOR_15BITS, +SVA_COLOR_16BITS, +SVA_COLOR_24BITS, +SVA_COLOR_32BITS +} t_sva_color_depth; + +typedef enum { +SVA_FULL_RANGE, +SVA_BT601_RANGE +} t_sva_color_range; + +typedef enum { +SVA_DEFAULT_SAMPLING_FORMAT = 0, +SVA_MPEG2_4_SAMPLING_FORMAT = 1, +SVA_MPEG1_SAMPLING_FORMAT = 2 +} t_sva_sampling_format; + + +typedef enum { +SVA_MONOCHROME = 1, +SVA_COLOR = 3 +} t_sva_still_image_color_mode; + + +typedef enum { +SVA_DOWNSAMPLING_FACTOR_1, +SVA_DOWNSAMPLING_FACTOR_2, +SVA_DOWNSAMPLING_FACTOR_4, +SVA_DOWNSAMPLING_FACTOR_8 +} t_sva_downsampling_factor; + + +typedef enum { +SVA_ACE_STRENGTH_1 = 1, +SVA_ACE_STRENGTH_2, +SVA_ACE_STRENGTH_3, +SVA_ACE_STRENGTH_4, +SVA_ACE_STRENGTH_5, +SVA_ACE_STRENGTH_6, +SVA_ACE_STRENGTH_7, +SVA_ACE_STRENGTH_8 +} t_sva_ace_strength; + + +typedef enum { +SVA_POSTPROCESSOR_ACE_DISABLE, +SVA_POSTPROCESSOR_ACE_INTERNAL, +SVA_POSTPROCESSOR_ACE_EXTERNAL // when using with Still Image Decoder +} t_sva_postprocessor_ace_mode; + +typedef enum { +SVA_POSPROCESSOR_NO_EXT_SYNC, +SVA_POSTPROCESSOR_EXT_DISPLAY_SYNC // The external DISPLAY_SYNC signal is used. That means the display is synchronized by + // external hardware signal mainly provided by display engine. + // WARNING : To be used ONLY with valid hardware synchro, otherwise, display will be + // stucked !!! +} t_sva_postprocessor_external_sync_mode; + + +typedef enum { +SVA_PREPROCESSOR_RAW_8BPP, +SVA_PREPROCESSOR_RAW_10BPP +} t_sva_preprocessor_ccir_raw_bpp; + + +typedef enum { +SVA_PREPROCESSOR_SYNC_EMBEDDED_CODES, /* 0x0 */ +SVA_PREPROCESSOR_SYNC_EXTERNAL_MODE1, /* 0x1 */ +SVA_PREPROCESSOR_SYNC_EXTERNAL_MODE2 /* 0x2 */ +} t_sva_preprocessor_ccir_input_sync_mode; + +typedef enum { +SVA_PREPROCESSOR_CCP0_INTERFACE_RISING_EDGE, /* 0x0 */ +SVA_PREPROCESSOR_CCIR656_INTERFACE_RISING_EDGE, /* 0x1 */ +SVA_PREPROCESSOR_CCP0_INTERFACE_FALLING_EDGE, /* 0x2 */ +SVA_PREPROCESSOR_CCIR656_INTERFACE_FALLING_EDGE, /* 0x3 */ +SVA_PREPROCESSOR_CCP0_INTERFACE_RISING_EDGE_STROBE_ENABLE, /* 0x4 */ +SVA_PREPROCESSOR_CCP0_INTERFACE_FALLING_EDGE_STROBE_ENABLE, /* 0x5 */ +SVA_PREPROCESSOR_CCP1_INTERFACE_RISING_EDGE, /* 0x6 */ +SVA_PREPROCESSOR_CCP1_INTERFACE_FALLING_EDGE, /* 0x7 */ +SVA_PREPROCESSOR_CCP1_INTERFACE_RISING_EDGE_STROBE_ENABLE, /* 0x8 */ +SVA_PREPROCESSOR_CCP1_INTERFACE_FALLING_EDGE_STROBE_ENABLE, /* 0x9 */ +SVA_PREPROCESSOR_CCP_INTERFACE_RISING_EDGE = SVA_PREPROCESSOR_CCP0_INTERFACE_RISING_EDGE, /* 0x0 */ +SVA_PREPROCESSOR_CCP_INTERFACE_FALLING_EDGE = SVA_PREPROCESSOR_CCP0_INTERFACE_FALLING_EDGE, /* 0x2 */ +SVA_PREPROCESSOR_CCP_INTERFACE_RISING_EDGE_STROBE_ENABLE = SVA_PREPROCESSOR_CCP0_INTERFACE_RISING_EDGE_STROBE_ENABLE, /* 0x4 */ +SVA_PREPROCESSOR_CCP_INTERFACE_FALLING_EDGE_STROBE_ENABLE = SVA_PREPROCESSOR_CCP0_INTERFACE_FALLING_EDGE_STROBE_ENABLE /* 0x5 */ +} t_sva_preprocessor_input_mode; + + +typedef enum { +SVA_TVO_EXTERNAL_CLOCK_FALLING_EDGE, +SVA_TVO_EXTERNAL_CLOCK_RISING_EDGE, +SVA_TVO_INTERNAL_CLOCK_FALLING_EDGE, +SVA_TVO_INTERNAL_CLOCK_RISING_EDGE +} t_sva_tvo_clock_mode; + + +typedef enum { +SVA_BASIC_ERC, /* for h264 : file does not contain any error */ +SVA_FULL_ERC /* for h264, file contain error */ +} t_sva_erc_mode; + + +typedef enum { +SVA_QP_CONSTANT=0, +SVA_FRAME_BASE, /* user provide frame size for each picture to encode */ +SVA_CBR, +SVA_VBR +} t_sva_brc_mode; + + +typedef enum { +SVA_SPATIAL_QUALITY_NONE, +SVA_SPATIAL_QUALITY_LOW, +SVA_SPATIAL_QUALITY_MEDIUM, +SVA_SPATIAL_QUALITY_HIGH +} t_sva_brc_spatial_quality; + +typedef enum { +SVA_BUFFERING_NONE, +SVA_BUFFERING_VBV, +SVA_BUFFERING_HRD, +SVA_BUFFERING_ANNEXG +} t_sva_brc_buffering_model; + +typedef enum { +SVA_AIR_DISABLED_CIR_DISABLED=0, +SVA_AIR_ENABLED_CIR_DISABLED, +SVA_AIR_DISABLED_CIR_ENABLED, +SVA_AIR_ENABLED_CIR_ENABLED +} t_sva_brc_intra_refresh_mode; + + +typedef enum { +SVA_RTYPE_MODE_CONSTANT_ZERO, +SVA_RTYPE_MODE_CONSTANT_ONE, +SVA_RTYPE_MODE_TOGGLING +} t_sva_rtype_mode; + + +#define NUMBER_OF_FILTER_MODE 5 +typedef enum { +SVA_NONE_FILTER, +SVA_DEBLOCKING_FILTER, +SVA_DERINGING_FILTER , +SVA_DEBLOCKING_DERINGING_FILTER, +SVA_H264_DEBLOCKING_OPTIMIZED_FILTER = SVA_DEBLOCKING_DERINGING_FILTER + +} t_sva_filter_mode; + +typedef enum { +SVA_H264_FULL_FRAME_DEBLOCKING_FILTER, +SVA_H264_NONE_FILTER, +SVA_H264_SLICE_BOUNDRIES_DEBLOCKING_FILTER, +} t_sva_h264_filter_mode; + +typedef enum { +// TO BE COMPLETED +SVA_DECODER_TASK_PARAMETER_ERROR = -1, +SVA_DECODER_NO_ERROR = 0 +} t_sva_video_decoder_error_id; + + +typedef enum { +// TO BE COMPLETED +SVA_VIDEO_ENCODER_ERROR_DUMMY +} t_sva_video_encoder_error_id; + + +typedef enum { +SVA_PREPROCESSOR_TASK_PARAMETER_ERROR = -1, +SVA_PREPROCESSOR_NO_ERROR = 0 +// TO BE COMPLETED +} t_sva_preprocessor_error_id; + + +typedef enum { +SVA_POSTPROCESSOR_TASK_PARAMETER_ERROR = -1, +SVA_POSTPROCESSOR_NO_ERROR = 0 +// TO BE COMPLETED +} t_sva_postprocessor_error_id; + +typedef enum { +// TO BE COMPLETED +SVA_SW_PROCESSING_ERROR_DUMMY +} t_sva_sw_processing_error_id; + +typedef enum { +SVA_JPEG_ENCODER_ERROR, +SVA_STILL_ENCODER_NO_ERROR = 0 +} t_sva_still_image_encoder_error_id; + +typedef enum { +SVA_STILL_DECODER_TASK_PARAMETER_ERROR = -1, +SVA_STILL_DECODER_NO_ERROR = 0 +} t_sva_still_image_decoder_error_id; + +typedef enum { +// TO BE COMPLETED +SVA_TVO_ERROR +} t_sva_tvo_error_id; + + +typedef enum { +SVA_EVENT_BUFFER_VOIDED = 1,// the buffer has been read and is under user control +SVA_EVENT_BUFFER_FILLED, // the buffer has been written and is under user control +SVA_EVENT_BUFFER_PARTLY_FILLED, // the buffer has been partly written +// but remains under HCL control in order to continue to fill it +SVA_EVENT_BUFFER_FILLED_READ_ONLY, // the buffer has been written but remains under HCL control +SVA_EVENT_SERVICE_STOPPED, // the given service is stopped +SVA_EVENT_SERVICE_ACTIVATED, // the given service has been activated +SVA_EVENT_SERVICE_INACTIVATED, // the given service has been inactivated +SVA_EVENT_SERVICE_FLUSHED_IN, // the given service has been flushed (input bufferization) +SVA_EVENT_SERVICE_FLUSHED_OUT, // the given service has been flushed (output bufferization) +SVA_EVENT_SERVICE_ERROR, // the given service is in error state +SVA_EVENT_UNDERFLOW, // lack of data in input +SVA_EVENT_OVERFLOW, // lack of buffer in output +SVA_EVENT_PREPROCESSOR_LINE_SYNCHRO, // see t_sva_preprocessor_configuration type description +SVA_EVENT_POSTPROCESSOR_LINE_SYNCHRO, // see t_sva_postprocessor_configuration type description +SVA_EVENT_POSTPROCESSOR_SYNCHRO, // see t_sva_postprocessor_configuration type description +SVA_EVENT_POSTPROCESSOR_ALT_SYNCHRO, // see t_sva_postprocessor_configuration type description +SVA_EVENT_FW_NO_MORE_NEEDED, // the given firmware can be removed from the shared memory +SVA_EVENT_PACKET_READ, // an irp packet read is finish +SVA_EVENT_PACKET_WRITE, // an irp packet write is finish +SVA_EVENT_PACKET_ERROR // an irp packet error occur +} t_sva_event_id; + + + + +typedef t_uint32 t_sva_service_id; +typedef t_uint32 t_sva_fw_id; +typedef t_uint32 t_sva_buffer_id; +typedef t_uint32 t_sva_timestamp_value; +typedef void * tp_sva_codec_algo_static_params; +typedef void * tp_sva_brc_configuration_params; +typedef void * tp_sva_still_algo_configuration_params; +typedef void * tp_sva_open_service_methods; + +/* + * Define the constant value used to flag an invalid buffer identifier + */ +#define INVALID_BUFFER_ID MASK_ALL32 + +typedef struct { +t_sva_timestamp_type type; +t_sva_timestamp_value value; +} t_sva_timestamp; + +/* ------------------------ */ +/* Structure */ +/* -------------------------*/ + +typedef struct { +t_uint16 vpBitSize; +t_uint16 vpMbSize; +t_uint16 vpSizeMax; +t_uint16 vpSizeType; +}t_sva_ec_mp4_packetsize_info; + + +typedef struct { +t_version hclVersion; +t_version fwVersion; +t_version hwVersion; +} t_sva_version; + +typedef struct { +t_uint16 height; +t_uint16 width; +} t_sva_image_desc; + + +typedef struct { +t_uint16 offsetX; +t_uint16 offsetY; +} t_sva_offset_desc; + +typedef struct{ +t_sva_image_desc image; +t_sva_offset_desc imageOffset; +void* next_tile; // it is treated as (t_sva_ppp_tile_info*) +}t_sva_ppp_tile_info; + +typedef struct { +t_sva_image_desc image; +t_sva_offset_desc imageOffset; +} t_sva_window_desc; + + +typedef struct { +t_sva_image_desc frame; +t_sva_window_desc window; +} t_sva_windowed_frame_desc; + +/* BML clock diviser for FW Version >= 3.14.1.1 */ +typedef enum { +SVA_GRAB_HQ_BML_FREQ_CLK72_DIV2 = 2, +SVA_GRAB_HQ_BML_FREQ_CLK72_DIV3 = 3, +SVA_GRAB_HQ_BML_FREQ_CLK72_DIV4 = 4 +} t_sva_grab_hq_bml_clock_divisor; + +/* Configuration parameters related to GrabHQ only, Added after CR133 implementation */ +typedef struct { +t_bool isChannelOffsetEnabled; /* Channel Offset On/Off switch */ +t_bool isGridironEnabled; /* Gridiron On/Off switch */ +t_bool isScorpioEnabled; /* Scorpio On/Off switch */ +t_uint16 scorpioStrength; /* Scorpio strength */ +t_uint32 castDay; +t_uint32 castCool; +t_uint32 castInc; +t_uint32 castHorizon; +t_sint32 gridHSize; +t_sva_grab_hq_bml_clock_divisor bmlClockDivisor; /* BML Clock diviser */ +/* nbMaxBmlRetiesOnFailure is only valid if FW>=3.14.1.2 */ +t_uint32 nbMaxBmlRetiesOnFailure; /* Number of maximum BML reties to be made, if all the these reties have failed then FW will through and error */ +} t_sva_preprocessor_grabhq_configuration; + +typedef struct { +t_uint16 errorType; +t_uint16 pictureLoss; +t_uint16 sliceLossFirstMb[8]; +t_uint16 sliceLossMbNum[8]; +t_uint16 concealedMbNum; +t_uint16 concealedVpSliceNum; +t_uint16 decodedVpSliceNum; +t_uint16 reserved_1; +t_uint32 reserved_2; +} t_sva_video_decoder_infos; + +typedef struct +{ + t_uint16 error_type; + t_uint16 picture_loss; + t_uint16 slice_loss_first_mb[8]; + t_uint16 slice_loss_mb_num[8]; + t_uint16 concealed_mb_num; + t_uint16 concealed_vp_num; + t_uint16 decoded_vp_num; + + t_uint16 reserved_1; + t_uint32 reserved_2; +} t_sva_video_decoder_mpeg4_infos; + +typedef struct +{ + t_uint16 error_type; + t_uint16 reserved_1; + t_uint32 reserved_2; + t_uint32 reserved_3; + t_uint32 reserved_4; +} t_sva_video_decoder_Mpeg2_infos; +typedef struct +{ + t_uint16 error_type; + t_uint16 picture_loss; + t_uint16 slice_loss_first_mb[8]; + t_uint16 slice_loss_mb_num[8]; + t_uint16 concealed_mb_num; + t_uint16 concealed_vp_num; + t_uint16 decoded_vp_num; + t_uint16 reserved_1; + t_uint32 reserved_2; +} t_sva_video_decoder_h263_infos; + +typedef struct +{ + t_uint16 picture_loss; + t_uint16 mb_count; + t_uint32 reserved_2; + t_uint32 reserved_3; + t_uint32 reserved_4; + t_uint16 slice_loss_first_mb[8]; + t_uint16 slice_loss_mb_num[8]; +} t_sva_video_decoder_h264_infos; + +typedef struct +{ + t_uint16 error_type; + t_uint16 frame_interpolation_hint_enabled; + t_uint16 range_reduction_frame_enabled; + t_uint16 b_fraction_numerator; + t_uint16 b_fraction_denominator; + t_uint16 buffer_fullness; + t_uint16 picture_res; + t_uint16 max_picture_width; + t_uint16 max_picture_height; + t_uint16 picture_width; + t_uint16 picture_height; + t_uint16 picture_type; + t_uint32 padding1; + t_uint32 padding2; +} t_sva_video_decoder_vc1_infos; + + +typedef struct +{ + t_uint16 error_type; + t_uint16 reserved_1; + t_uint16 ace_offset0; + t_uint16 ace_offset1; + t_uint16 ace_offset2; + t_uint16 ace_offset3; + t_uint32 reserved_2; +} t_sva_still_decoder_jpeg_infos; + +/* Status of the GrabHQ subtask for FW Version >= 3.13.0 */ +typedef enum { +SVA_GRAB_HQ_SUBTASK_NOT_STARTED = 0, +SVA_GRAB_HQ_FIRST_STRIPE_FISRT_BML_DONE = 1, +SVA_GRAB_HQ_BMS_ENDED = 2, +SVA_GRAB_HQ_PREPROCESSING_STARTED = 2, +SVA_GRAB_HQ_PREPROCESSING_ENDED = 3, +SVA_GRAB_HQ_FIRST_BML_STARTED = 4, +SVA_GRAB_HQ_SUBTASK_ENDED = 5, +SVA_GRAB_HQ_SECOND_BML_STARTED = 6, +SVA_GRAB_HQ_SECOND_STRIPE_FIRST_BML_DONE = 6, +SVA_GRAB_HQ_FIRST_STRIPE_SECOND_BML_DONE = 7, +} t_sva_grab_hq_subtask_status; + +typedef struct { + t_bool isGrabHqTestModeEnabled; + t_sva_grab_hq_subtask_status grabHqSubtaskStatus; + t_uint16 cfgIrpGrabhqGridcastL; + t_uint16 cfgIrpGrabhqGridcastH; + t_uint16 cfgIrpGrabhqGridG1; + t_uint16 cfgIrpGrabhqGridG2; + t_uint16 cfgIrpGrabhqGridR; + t_uint16 cfgIrpGrabhqGridB; +} t_sva_gb_hq_status; + +#ifdef SVA_USE_GENERIC_ENCODER_INFOS +/******************************************************************************** + * SARVESH: Beware of using t_sva_video_encoder_infos instead of using codec * + * specific infos structure e.g. t_sva_video_encoder_mpeg4_infos or * + * t_sva_video_encoder_h264_infos. May lead to code break if you don't take care* + * of enough memory allocation. It is recommended to use service specific infos * + ********************************************************************************/ +typedef struct { +t_uint32 encodedFrameSize; /* size (in byte) of the encoded frame */ +/*(including header and stuffing bits) */ +t_uint32 vpSliceNum; +t_uint32 vpSlicePos[1620]; //\/ This size has been increased from 32 to 1320 for H264 Encode and to 1620 with FW 3.6.0 +} t_sva_video_encoder_infos; +#else /* SVA_USE_GENERIC_ENCODER_INFOS */ +typedef struct { +t_uint32 encodedFrameSize; /* size (in byte) of the encoded frame */ +/*(including header and stuffing bits) */ +t_uint32 vpSliceNum; +t_uint32 vpSlicePos[SVA_EC_MPEG4_VP_POS_COUNT]; +} t_sva_video_encoder_mpeg4_infos; + +typedef struct { +t_uint32 encodedFrameSize; /* size (in byte) of the encoded frame */ +/*(including header and stuffing bits) */ +t_uint32 sliceNum; +t_uint32 slicePos[SVA_EC_H263_SLICE_POS_COUNT]; +} t_sva_video_encoder_h263_infos; + +typedef struct { +t_uint32 encodedFrameSize; /* size (in byte) of the encoded frame */ +/*(including header and stuffing bits) */ +t_uint32 sliceNum; +t_uint32 slicePos[SVA_EC_H264_SLICE_POS_COUNT]; //\/ This size has been increased from 32 to 1320 for H264 Encode and to 1620 with FW 3.6.0 +t_uint32 stuffingBits; /* Number of stuffing bits(INOUT_OUT param from FW side) added in the bitstream during the encode subtask. It is not used if brc_method=0/1/3. */ +} t_sva_video_encoder_h264_infos; +#endif /* SVA_USE_GENERIC_ENCODER_INFOS */ + +typedef struct { +t_sva_inout_type type; +t_sva_inout_format format; +t_sva_image_desc maxSize; +} t_sva_inout_desc; + +typedef struct { +t_uint16 pictureCodingType; /* 0: intra / 1: inter */ +t_uint16 frameTargetSize; /* frame base target size (in byte) */ +} t_sva_brc_user_request; + +typedef struct { +t_uint32 minScaleFactor; // scaleFactor = (1/minScaleFactor) +t_uint32 maxScaleFactor; // scaleFactor = (maxScaleFactor) +t_uint32 scaleStep; // if ZERO (0) then continous resizing +} t_sva_resize_desc; + +typedef struct { +t_uint32 voidedCounter; // Buffer Voided event counter +t_uint32 filledCounter; // Buffer Filled event counter +t_uint32 partlyCounter; // Buffer Partly Filled event counter +t_uint32 readOnlyCounter; // Buffer Filled Read Only event counter +t_uint32 underflowCounter; // Underflow event counter +t_uint32 overflowCounter; // Overflow event counter +t_uint32 errorCounter; // Service Error event counter +} t_sva_service_event_stats; + + +typedef struct { +t_uint32 inLevel; // level of bufferization at input of a given service +t_uint32 outLevel; // level of bufferization at output of a given service +} t_sva_service_bufferization_stats; + + +typedef struct { +t_sva_preprocessor_capability_id capabilityId; +t_sva_inout_desc input; // camera interface +t_sva_inout_desc output[2]; // grabbed image and infos +t_sva_preprocessing_transform_type supportedTransformation; +t_sva_resize_desc resizeEngineFactors; +} t_sva_preprocessor_capabilities; + + +typedef struct { +t_sva_video_decoder_capability_id capabilityId; +t_sva_inout_desc input; // bitstream +t_sva_inout_desc output[3]; // decoded image and infos +// [and optional deblocking filter parameters] +} t_sva_video_decoder_capabilities; + + +typedef struct { +t_sva_video_encoder_capability_id capabilityId; +t_sva_inout_desc input; // image to encode +t_sva_inout_desc output[3]; // bitstream and infos [and optional deblocking filter parameters] +t_sva_encoding_transform_type supportedTransformation; +} t_sva_video_encoder_capabilities; + + +typedef struct { +t_sva_postprocessor_capability_id capabilityId; +t_sva_inout_desc input[2]; // image to postprocess [and optional deblocking filter parameters] +t_sva_inout_desc output; // postprocessed image +t_sva_postprocessing_transform_type supportedTransformation; +t_sva_resize_desc resizeEngineFactors; +} t_sva_postprocessor_capabilities; + + +typedef struct { +t_sva_sw_processing_capability_id capabilityId; +t_sva_inout_desc input[2]; // two grabbed images +t_sva_inout_desc output; // stabilization vector (infos) +} t_sva_sw_processing_capabilities; + +typedef struct { +t_sva_still_image_decoder_capability_id capabilityId; +t_sva_inout_desc input[3]; // three separate component image +t_sva_inout_desc output; // encoded image +} t_sva_still_decoder_capabilities; + +typedef struct { +t_sva_still_image_encoder_capability_id capabilityId; +t_sva_inout_desc input[3]; // three separate component image +t_sva_inout_desc output; // encoded image +t_sva_encoding_transform_type supportedTransformation; +} t_sva_still_encoder_capabilities; + +typedef const struct ts_sva_capabilities{ +t_uint8 nbSupportedPreprocessorTransforms; +t_sva_preprocessor_capabilities *preprocessorCapabilitiesArray; +t_uint8 nbSupportedDecoderTransforms; +t_sva_video_decoder_capabilities *decoderCapabilitiesArray; +t_uint8 nbSupportedSwProcessingTransforms; +t_sva_sw_processing_capabilities *swProcessingCapabilitiesArray; +t_uint8 nbSupportedEncoderTransforms; +t_sva_video_encoder_capabilities *encoderCapabilitiesArray; +t_uint8 nbSupportedPostprocessorTransforms; +t_sva_postprocessor_capabilities *postprocessorCapabilitiesArray; +t_uint8 nbSupportedStillDecoderTransforms; +t_sva_still_decoder_capabilities *stillDecoderCapabilitiesArray; +t_uint8 nbSupportedStillEncoderTransforms; +t_sva_still_encoder_capabilities *stillEncoderCapabilitiesArray; +} t_sva_capabilities, *tp_sva_capabilities; + +/********************************************/ +/* Common decoder structures */ +/********************************************/ +typedef struct { +t_sva_video_decoder_capability_id transformId; +t_bool areInfosRequested; // TRUE => User wants for each decoded image the related infos buffer +// The user SHALL provide all Infos buffers through SVA_PushInfosBuffer() +// FALSE => Infos buffers are not exported +t_sva_erc_mode ercMode; // The user SHALL provide all Infos buffers through SVA_PushInfosBuffer() +t_sva_codec_mode mode; // see §2.9: decoder => bitstream buffer as input +/*choose filter to use. Not all combinaison are possible*/ +t_sva_filter_mode inTheLoopFilter; +t_sva_filter_mode outTheLoopFilter; +t_sva_image_desc imageDesc; +t_bool raster_out_format; +tp_sva_codec_algo_configuration_params pAlgoConfig; +} t_sva_video_decoder_configuration; + + +typedef struct { +t_sva_service_state state; +t_sva_video_decoder_error_id errorId; +t_uint32 nbBytesDecoded; +t_uint32 nbImagesDecoded; +t_uint32 nbCompressedDataBufferized; // number of bytes inside input bitstream fifo +t_sva_service_event_stats eventStats; +t_sva_service_bufferization_stats bufferizationStats; +} t_sva_video_decoder_status; + +/********************************************/ +/* Codecs-dependant decoder structures */ +/********************************************/ +///////////// MPEG4 /////////////////// +typedef struct { +t_bool flagShortHeader; +t_uint16 vopTimeIncrementResolution; // range value: 1 to 65535 +t_bool isResyncMarkerDisable; +t_bool isDataPartitioned; +t_bool isReversibleVlc; +t_bool isInterlaced; +t_uint16 low_delay; +t_uint16 quant_type; +t_uint16 intra_quant_mat[64] ; +t_uint16 nonintra_quant_mat[64]; +t_uint8 profile; +} t_sva_video_decoder_algo_mpeg4_configuration_params; + +/*t_sva_video_decoder_algo_mpeg4_header_infos*/ +typedef struct { +t_uint16 pictureCodingType; // 0: Intra-coded, 1: Predictive-coded +t_uint16 quant; // value range: 1 to 31 +t_uint16 roundingType; // if used, value range: 0 to 1 +t_uint16 intraDcVlcThr; // if used, value range: 0 to 7 +t_uint16 vopFcodeForward; // if used, value range: 1 to 7 +t_uint16 vopFcodeBackward; +t_uint16 vop_time_increment; +t_uint16 modulo_time_base; + +} t_sva_video_decoder_algo_mpeg4_header_infos; + + +/********************************************/ +/* Codecs-dependant decoder structures */ +/********************************************/ +///////////// Start MPEG2 /////////////////// + +//Added for mpeg2 field picture support +typedef enum { + PICTURE_STRUCTURE_FRAME = 3, /** Frame picture structure*/ + PICTURE_STRUCTURE_BOTTOMFIELD = 2, /** Bottom Field */ + PICTURE_STRUCTURE_TOPFIELD = 1, /** Top Field */ + PICTURE_STRUCTURE_NONE = 0, /** Not applicable */ + } t_sva_Mpeg2_picture_structure; + +typedef struct { +t_bool load_intra_quantiser_matrix; +t_bool load_nonintra_quantiser_matrix; +t_bool progressive_sequence; +t_uint8 profile_level_indication; +t_uint8 chroma_format; +t_uint32 bit_rate; +} t_sva_video_decoder_algo_Mpeg2_configuration_params; + +/*t_sva_video_decoder_algo_mpeg4_header_infos*/ +typedef struct { +// not used t_ushort_value horizontal_size; + t_uint16 vertical_size; + t_uint16 mb_width; + t_uint16 mb_height; + // not used t_ushort_value progressive_sequence; + // not used t_ushort_value low_delay; + + t_uint16 intra_quantizer_matrix[64]; + t_uint16 non_intra_quantizer_matrix[64]; + + // not used t_ulong_value frame_rate; + // not used t_ulong_value bit_rate_value; + + // not used t_ulong_value vbv_buffer_size; + // not used t_ushort_value gop_flag; + // not used t_ushort_value closed_gop; + + // not used t_ushort_value broken_link; + // not used t_ushort_value temporal_reference; + t_uint16 picture_coding_type; + // not used t_ushort_value vbv_delay; + + t_uint16 full_pel_forward_vector; + t_uint16 forward_f_code; + t_uint16 full_pel_backward_vector; + t_uint16 backward_f_code; + + t_uint16 f_code[2][2]; + + t_uint16 intra_dc_precision; + t_uint16 picture_structure; + t_uint16 top_field_first; + t_uint16 frame_pred_frame_dct; + t_uint16 concealment_motion_vectors; + t_uint16 q_scale_type; + t_uint16 intra_vlc_format; + t_uint16 alternate_scan; + + // not used t_ushort_value repeat_first_field; + // not used t_ushort_value chroma_420_type; + // not used t_ushort_value progressive_frame; + t_uint16 scalable_mode; + t_uint16 MPEG2_Flag; + +} t_sva_video_decoder_algo_Mpeg2_header_infos; + +typedef enum { + PICTURE_SLICE_I = 1, /** I Picture / Field - can be used as a reference */ + PICTURE_SLICE_P = 2, /** P Picture / Field - can be used as a reference */ + PICTURE_SLICE_B = 3, /** B Picture / Field */ + PICTURE_SLICE_D = 4, /** D Picture / Field */ + PICTURE_SLICE_SKIPPED = 5 /** Picture Skipped / Field */ +} t_sva_Mpeg2_picture_type; + + +////////////// VC1 ///////////////////// +typedef enum { + PICTURE_TYPE_I = 0, /** I Picture / Field - can be used as a reference */ + PICTURE_TYPE_P = 1, /** P Picture / Field - can be used as a reference */ + PICTURE_TYPE_B = 2, /** B Picture / Field */ + PICTURE_TYPE_BI = 3, /** BI Picture / Field */ + PICTURE_SKIPPED = 4 /** Picture Skipped / Field */ +} t_sva_vc1_picture_type; + +typedef enum +{ + PICTURE_CODE_I = 0, /** I-Intra Picture */ + PICTURE_CODE_P = 1, /** P- Predictive Picture can be used as a reference */ + PICTURE_CODE_B = 2, /** B-Bidirectional Picture / Field */ +} t_sva_mp4_picture_type; + +typedef struct { // Sequence Layer parameters + t_uint8 profile; /** See standard */ + t_uint8 level; /** See standard */ + + t_uint8 quantizer; /** See standard */ + t_uint8 dquant; /** See standard */ + t_uint8 max_b_frames; /** See standard */ + t_uint8 qFramerateForPostproc; /** See standard */ + t_uint8 qBitrateForPostproc; /** See standard */ + + t_bool loopFilterEnabled; /** See standard */ + t_bool multiresCodingEnabled; /** See standard */ + t_bool fastUvmcEnabled; /** See standard */ + t_bool extendedMVEnabled; /** See standard */ + t_bool variableSizeTransformEnabled; /** See standard */ + t_bool overlapTransformEnabled; /** See standard */ + t_bool syncmarkerEnabled; /** See standard */ + t_bool rangeredEnabled; /** See standard */ + t_bool frameInterpolationEnabled; /** See standard */ + t_bool is_smpte_conformant; /** See standard */ + t_bool overboost; /** flag activating maximum performance decoding. 0=normal decode, 1=deblocking+overlap disabled with MB output instead of raster */ + t_bool simplified_filter; /** enable this flag if you want to use Intra filter for inter pictures as well. This improves performance for low bitrates. Output is raster in this case */ +} t_sva_video_decoder_algo_vc1_configuration_params; + +typedef struct { + t_uint32 frameSize; + t_sva_vc1_picture_type pictureCodingType; +} t_sva_video_decoder_algo_vc1_header_infos; + +////////////// H.264 /////////////////////// +typedef struct +{ + // size we have it in imageDesc. + t_uint16 levelIdc; + t_uint16 numRefFrames; + t_uint16 gapsInFrameNumValueFlag; + t_uint16 picOrderCntType; + t_uint16 log2MaxFrameNumMinus4; + t_uint16 log2MaxPicOrderCntLsbMinus4; + t_sint32 offsetForNonRefPic; /*t_sint32 ok */ + t_uint16 numRefFramesInPicOrderCntCycle; + t_sint32 offsetForRefFrame[256]; /*t_sint32 ok */ + t_sint32 offsetForTopToBottomField; +}t_sva_video_decoder_algo_h264_configuration_params; + +/* MMCO type operations */ +typedef enum +{ + SVA_DC_H264_DPB_END_MMCO=0, + SVA_DC_H264_DPB_UNMARK_SHORT_REF =1, + SVA_DC_H264_DPB_UNMARK_LONG_REF, + SVA_DC_H264_DPB_ASSIGN_LONG_TO_SHORT, + SVA_DC_H264_DPB_UNMARK_LONG_REF_GREATER, + SVA_DC_H264_DPB_UNMARK_LONG, + SVA_DC_H264_DPB_ASSIGN_LONG_TO_CURRENT +}t_sva_video_decoder_algo_h264_mmco_type; + +/* params to be given for each slice and taken from active pps, sps, slice header */ +typedef struct st_sva_video_decoder_algo_h264_slice_header_infos { + /* these are obtained by parsing */ + t_uint16 nut; + t_uint16 nri; + t_system_address sliceStartAddress; + t_uint32 sliceOffset;//bit position at sliceStartAdress + t_size sliceSize; + /* then taken from active pps, sps, slice header */ + t_uint16 sliceBetaOffsetDiv2; /*t_sint16 but ushort ProgModel*/ + t_uint16 firstMbInSlice; + t_uint16 sliceType; + t_uint16 numRefIdx10ActiveMinus1; + t_sint16 sliceQpDelta; /* t_sint16 ok */ + t_uint16 disableDeblockingFilterIdc; + t_uint16 sliceAlphaC0OffsetDiv2; /*t_sint16 but ushort in Progmodel */ + t_uint16 sliceNum; + t_uint16 sliceQp ; /*t_sint16 but ushort in Progmodel */ + /* to generate list0*/ + t_uint16 numRefIdxActiveOverrideFlag; + t_uint16 refPicListReorderingFlagl0; + t_uint16 frameNum; + t_uint16 reorderingOfPicNumsIdc[16]; + t_uint16 absDiffPicNumMinus1[16]; + t_uint16 longTermPicNum[16]; + struct st_sva_video_decoder_algo_h264_slice_header_infos *pNextHeader; +}t_sva_video_decoder_algo_h264_slice_header_infos; + +/*t_sva_video_decoder_algo_h264_header_infos*/ +typedef struct +{ + /* from PPS for vdc_h264_slice */ + t_uint16 chromaQpIndex; /*t_sint16 but ushort in Progmodel */ + t_uint16 constrIntraPredFlag; + t_uint16 numRefIdxl0ActiveMinus1; + /* from PPS and slice0 to compute sliceMap */ + t_uint16 slice0SliceGroupChangeCycle; + t_uint16 numSliceGroupsMinus1; + t_uint16 sliceGroupMapType; + t_uint16 runLenghtMinus1[8]; + t_uint16 topLeft[8]; + t_uint16 bottomRight[8]; + t_uint16 sliceGroupChangeDirFlag; + t_uint16 sliceGroupChangeRateMinus1; + t_uint16 sliceGroupId[1620]; + /* from active SPS: to be given to DPB */ + /* + t_uint16 numRefFrames; + t_uint16 gapsInFrameNumValueFlag; + t_uint16 picOrderCntType; + t_uint16 log2MaxFrameNumMinus4; + t_uint16 log2MaxPicOrderCntLsbMinus4; + t_sint32 offsetForNonRefPic; //t_sint32 + t_uint16 numRefFramesInPicOrderCntCycle; + t_sint32 offsetForRefFrame[256]; //t_sint32 + t_sint32 offsetForTopToBottomField; + */ + + /*from slice0: to be given to DPB */ + t_uint16 slice0Nut; + t_uint16 slice0Nri; + t_uint16 slice0FrameNum; + t_uint16 slice0PicOrderCntLsb; + t_sint32 slice0DeltaPicOrderCnt[2]; + t_sint32 slice0DeltaPicOrderCntBottom; + t_uint16 slice0LongTermReferenceFlag; + t_uint16 slice0NoOutputOfPriorPicsFlag; + t_uint16 slice0AdaptiveRefPicMarkingModeFlag; + t_sva_video_decoder_algo_h264_mmco_type slice0MemoryManagementControlOperation[16]; + t_uint16 slice0DifferenceOfPicNumsMinus1[16]; + t_uint16 slice0MarkingLongTermPicNum[16]; + t_uint16 slice0LongTermFrameIdx[16]; + t_uint16 slice0MaxLongTermFrameIdxPlus1[16]; + t_uint16 nbSlicesInFrame; + t_sva_video_decoder_algo_h264_slice_header_infos *pHeader; /* from each slice headers */ +}t_sva_video_decoder_algo_h264_header_infos; + +///////////// H.263 /////////////////////// +typedef struct { +/* today none configuration parameter is identified */ + t_uint32 dummy; +} t_sva_video_decoder_algo_h263_configuration_params; + +/*t_sva_video_decoder_algo_h263_header_infos*/ +typedef struct { +t_uint16 pictureCodingType; +t_uint16 quant; +t_uint16 roundingType; +t_uint16 enableAnnexes; +} t_sva_video_decoder_algo_h263_header_infos; + +////////////// End of decoder structures /////////////////// + + +typedef struct { +t_sva_video_encoder_capability_id transformId; +t_bool areInfosRequested; // TRUE => User wants for each encoded image the related infos buffer +// The user SHALL provide all Infos buffers through SVA_PushInfosBuffer() +// FALSE => Infos buffers are not exported +t_bool isCroppingVectorEnabled; // TRUE => User must provide for each image a cropping vector +// FALSE => No buffer of this type should be provide +t_bool isDestinationBufferRequested; // TRUE => User has to provide destination buffers for each image +// FALSE => No buffer of this type should be provide +t_sva_codec_mode mode; // see §2.9: encoder => bitstream buffer as output +t_sva_windowed_frame_desc sourceFrameDesc; +/*choose filter to use. Not all combinaison are possible*/ +t_sva_filter_mode inTheLoopFilter; +t_sva_filter_mode outTheLoopFilter; +/*choose brc to use. Not all combinaison allowed between brcMode/bufferingModel/algo */ +t_sva_brc_mode brcMode; +t_sva_brc_buffering_model bufferingModel; +tp_sva_brc_configuration_params pBrcConfig; +t_bool raster_in_format; +t_bool no_search_window; +tp_sva_codec_algo_configuration_params pAlgoConfig; +} t_sva_video_encoder_configuration; + + +typedef struct { +t_sva_service_state state; +t_sva_video_encoder_error_id errorId; +t_uint32 nbBytesEncoded; +t_uint32 nbImagesEncoded; +t_uint32 nbImagesSkipped; +t_sva_service_event_stats eventStats; +t_sva_service_bufferization_stats bufferizationStats; +} t_sva_video_encoder_status; + + +typedef struct { +t_bool flagShortHeader; +t_uint16 gobHeaderFrequency;/*when 0 then gob header insertion is disable*/ +t_bool isDataPartitionedEnable; +t_bool isReversibleVlcEnable; +t_uint16 hecFreq; // if used, value range: 0(HEC information disabled) to SourceWindowWidth*SourceWindowHeight/256 +t_uint16 vpSizeType; // if used, value range: 0 to 3 +t_uint16 vpSizeMax; // if used, value range: 0 to 2048(for Simple Profile Level=0/1) or 4096 (for SPL=2) or 8192 (for SPL=3) +t_uint16 vpBitSize; // if used, value range: 0 to vpSizeMax +t_uint16 vpMbSize; // if used, value range: 0 to window_width*window_height/256 +t_sva_brc_intra_refresh_mode irMode; +t_uint16 airMbNum; +t_uint16 cirPeriodMax; +t_sva_rtype_mode rtypeMode; +t_bool isSystemHeaderAddBeforeIntra; +t_uint8 profileAndLevel;// profile_and_level_indication field of VOS. Only use in SP and when +// isSystemHeaderAddBeforeIntra is true. This value will be copy in VOS header. +t_uint16 vopTimeIncrement; +t_uint16 vopTimeIncrementResolution; +} t_sva_video_encoder_algo_mpeg4_configuration_params; + + +#define FILE_NAME_SIZE 200 + +typedef struct { + t_sint32 ProfileIDC; /* profile idc */ + t_sint32 level_idc; /* level idc */ + +//\/ t_sint32 no_frames; /* number of frames to be encoded */ + t_sint32 QPISlice; /* QP of I pictures in case of no BRC (fix Qp encoding) */ + t_sint32 QPPSlice; /* QP of P pictures in case of no BRC (fix Qp encoding) */ + /* t_sint32 hadamard; */ /*!< 0: 'normal' SAD in 1/3 pixel search. 1: use 4x4 Haphazard transform and ' + Sum of absolute transform difference' in 1/3 pixel search */ + /* t_sint32 search_range; */ /*!< search range - integer pel search and 16x16 blocks. The search window is + generally around the predicted vector. Max vector is 2xmcrange. For 8x8 + and 4x4 block sizes the search range is 1/2 of that for 16x16 blocks. */ +//\/ t_sint32 Log2MaxFrameNum; + t_sint32 Log2MaxFNumMinus4; + + t_uint16 algo_config; /**<\brief 0b11 for performances (> 15 fps) , + unsetting bit 0 for complex intra in P slices , + unsetting bit 1 for complex inter in P slices */ +//\/ t_uint16 frame_width; /* image width (must be a multiple of 16 pels) */ +//\/ t_uint16 frame_height; /* image height (must be a multiple of 16 pels) */ +//\/ t_sint32 width_cr; /* HCL: We can remove this parameter from input parametrs */ +//\/ t_sint32 height_cr; /* HCL: We can remove this parameter from input parametrs */ + + + t_sint16 slice_size_type; /* Indicate what algorithm to use for setting slices */ + t_sint16 slice_mb_size; /* Argument when fixed # of MB in slice selected */ + t_sint16 slice_bit_size; /* Argument when fixed # of bytes in slice selected */ + t_sint32 use_constrained_intra_flag; /* 0: Inter MB pixels are allowed for intra prediction 1: Not allowed */ +//\/ t_sint32 infile_header; /* If input file has a header set this to the length of the header */ +//\/ char infile[FILE_NAME_SIZE]; /* YUV 4:2:0 input format */ +//\/ char outfile[FILE_NAME_SIZE]; /* H.264 compressed output bitstream */ +//\/ char ReconFile[FILE_NAME_SIZE]; /* Reconstructed Pictures */ +//\/ char TraceFile[FILE_NAME_SIZE]; /* Trace Outputs */ + t_sint32 intra_period; /* Random Access period though intra */ + + t_sint32 idr_enable; /* Encode intra slices as IDR */ +//\/ t_sint32 start_frame; /* Encode sequence starting from Frame start_frame */ + + t_sint32 annexb; /* Specifies the mode of the output file */ + +//\/ t_sint32 InterSearch16x16; +//\/ t_sint32 InterSearch16x8; +//\/ t_sint32 InterSearch8x16; +//\/ t_sint32 InterSearch8x8; +//\/ t_sint32 InterSearch8x4; +//\/ t_sint32 InterSearch4x8; +//\/ t_sint32 InterSearch4x4; + + t_sint32 IntraDisableInterOnly; + t_sint32 Intra4x4ParDisable; + t_sint32 Intra4x4DiagDisable; + t_sint32 Intra4x4DirDisable; + t_sint32 Intra16x16ParDisable; + t_sint32 Intra16x16PlaneDisable; + t_sint32 ChromaIntraDisable; + t_uint16 intra_disable; + + t_uint16 FrameRate; +//\/ double FrameRate_parser; + + t_sint32 chroma_qp_index_offset; +//\/#ifdef _FULL_SEARCH_RANGE_ +//\/ t_sint32 full_search; +//\/#endif + + t_sint32 pic_order_cnt_type; /* POC200301 */ + + /* Rate Control on JVT standard */ +//\/ t_sint16 brc_type; + t_sint32 bit_rate; + t_sint32 SeinitialQP; + t_uint16 me_type; /* M.E. Algorithm selection */ + + t_sint32 HrdSendMessages; + t_uint32 CpbBufferSize; + +//\/ char DynoptFileName[FILE_NAME_SIZE]; +//\/ char TimeStampsFileName[FILE_NAME_SIZE]; + + t_uint16 intra_refresh_type; /* 0=disabled 1=AIR */ + t_uint16 air_mb_num; +//\/ t_sint16 slice_loss_first_mb_parser; /* first MB lost (to be forced INTRA) JUST for parser use */ +//\/ t_sint16 slice_loss_mb_num_parser; /* number MBs lost (to be forced INTRA) JUST for parser use */ +//\/ t_sint16 slice_loss_first_mb[8]; /* first MB lost (to be forced INTRA) */ +//\/ t_sint16 slice_loss_mb_num[8]; /* number MBs lost (to be forced INTRA) */ + + /* pixel aspect ratio input parameters */ + t_sint32 aspect_ratio_info_present_flag;/* enable aspect ratio stuff in VUI */ + t_sint32 aspect_ratio_idc; /* aspect ratio idc */ + t_sint32 sar_width; /* used defined pixel width for aspect ratio */ + t_sint32 sar_height; /* used defined pixel height for aspect ratio */ + + /* deblocking filter stuff */ + t_sint32 disable_deblocking_filter_idc; + t_sint32 slice_alpha_c0_offset_div2; + t_sint32 slice_beta_offset_div2; + + t_sint32 video_signal_type_present_flag; + t_sint32 video_format; + t_sint32 video_full_range_flag; + t_sint32 colour_description_present_flag; + t_sint32 colour_primaries; + t_sint32 transfer_characteristics; + t_sint32 matrix_coefficients; + + t_sint32 IntraForced; /* force an Intra at this frame */ +} t_sva_video_encoder_algo_h264_configuration_params; + +typedef struct { +t_uint16 enableAnnexes; +t_uint16 gobHeaderFrequency;/*when 0 then gob header insertion is disable*/ +t_uint16 sliceSizeType; +t_uint16 sliceSizeMax; +t_uint16 sliceBitSize; +t_uint16 sliceMbSize; +t_sva_brc_intra_refresh_mode irMode; +t_uint16 airMbNum; +t_uint16 cirPeriodMax; +t_sva_rtype_mode rtypeMode; +} t_sva_video_encoder_algo_h263_configuration_params; + + +typedef struct { +t_uint32 pictureIntraRefresh;/*Give number of P picture between 2 I.*/ +t_uint8 IPictureQp;/*give the quantification value to use for I picture (2<=IPictureQp<=31)*/ +t_uint8 PPictureQp;/*give the quantification value to use for P picture (2<=PPictureQp<=31)*/ +/* Following field are only need when buffering model is different of SVA_BUFFERING_NONE*/ +t_uint32 bitRate;/*target bit rate in bits/s*/ +t_uint32 vbvBufferSize;/*vbv buffer size in bits*/ +t_uint32 vbvOccupancy;/*initial vbv occupancy in bits*/ +t_uint32 swissBuffer;/*swiss buffer in bits*/ +} t_sva_brc_qpConstant_configuration_params; + + +typedef struct { + t_uint32 dummy; +} t_sva_brc_frameBase_configuration_params; + + +typedef struct { +t_uint32 pictureIntraRefresh;/*Give number of P picture between 2 I.*/ +t_uint32 bitRate;/*target bit rate in bits/s*/ +t_uint32 vbvBufferSize;/*vbv buffer size in bits*/ +t_uint32 vbvOccupancy;/*initial vbv occupancy in bits*/ +t_uint32 swissBuffer;/*swiss buffer in bits*/ +} t_sva_brc_cbr_configuration_params; + + +typedef struct { +t_uint32 pictureIntraRefresh;/*Give number of P picture between 2 I.*/ +t_uint32 bitRate;/*target bit rate in bits/s*/ +t_sva_brc_spatial_quality spatialQuality; +t_uint32 minFrameRate;/*minimum output frame rate*/ +t_uint32 vbvBufferSize;/*vbv buffer size in bits*/ +t_uint32 vbvOccupancy;/*initial vbv occupancy in bits*/ +t_uint32 swissBuffer;/*swiss buffer in bits*/ +} t_sva_brc_vbr_configuration_params; + + +typedef struct { +t_bool isIntraFullPicture; // if true then request for an I picture, +// else only some Mb are request to be intra coded +t_uint16 sliceIntraFirstMb[8]; +t_uint16 sliceIntraMbNumber[8]; +} t_sva_intra_request; + + +typedef struct { +t_uint16 ace_offset_0; +t_uint16 ace_offset_1; +t_uint16 ace_offset_2; +t_uint16 ace_offset_3; +} t_sva_ace_offset; + +typedef struct { + t_uint16 address; + t_uint16 value; /* Not use for a read access */ +} t_sva_packet; + +typedef struct { +t_sva_preprocessor_capability_id transformId; +t_sva_windowed_frame_desc sourceFrameDesc; +t_sva_image_desc resizedWindowDesc; +t_sva_image_desc snapshotImageDesc; +t_sva_preprocessor_input_mode interfaceCConfiguration; /* CCP or CCIR656 */ +t_sva_preprocessor_ccir_input_sync_mode interfaceSyncMode; /* External or embedded synchronisation */ +t_bool isInputInterlaced; +t_bool isOutputFrame; +t_sva_preprocessor_ccir_raw_bpp rawBpp; /* If CCIR data bus is in 10 bits */ +/* This allow to grab raw data using full bus width */ +/* Only valid with transformId == SVA_PREPROCESSOR_RAW */ +/* and interfaceSyncMode != SVA_PREPROCESSOR_SYNC_EMBEDDED_CODES */ +t_uint32 grabSyncLine; /* define the grabbed line when raising the SVA_EVENT_PREPROCESSOR_SYNCHRO */ +/* to disable event generation please use SVA_NO_GRABSYNC_LINE (1023=0x3FF) value; value range: 0 to 1023 */ +t_sva_color_range outputRange; +t_bool isAceEnable; /* Enable or disable automatic contrast enhancement */ +t_sva_ace_strength aceStrength; +t_sva_color_range aceRange; +t_sva_preprocessor_grabhq_configuration grabhqConfig; +} t_sva_preprocessor_configuration; + +typedef struct { +t_sva_service_state state; +t_sva_preprocessor_error_id errorId; +t_uint32 nbGrabbedImage; +t_bool isAceEnable; +t_sva_ace_offset aceOffset; +t_sva_service_event_stats eventStats; +t_sva_service_bufferization_stats bufferizationStats; +} t_sva_preprocessor_status; + + +typedef struct { +t_sint16 matrix_coef1; +t_sint16 matrix_coef2; +t_sint16 matrix_coef3; +t_sint16 matrix_coef4; +} t_sva_postprocessor_color_matrix; + +typedef struct { +t_uint16 quant_y[64]; // value range for quant_y/cb/cr params: 1 to 255 +t_uint16 quant_cb[64]; +t_uint16 quant_cr[64]; +} t_sva_quantization_table; + + +typedef struct { +t_uint16 huffmanYCodeDc[12]; +t_uint16 huffmanYSizeDc[12]; // value range for huffman-Y/Cb/Cr-Size-Dc/Ac params: 1 to 16 (if 0 it will not be used) +t_uint16 huffmanYCodeAc[256]; +t_uint16 huffmanYSizeAc[256]; +t_uint16 huffmanCbCodeDc[12]; +t_uint16 huffmanCbSizeDc[12]; +t_uint16 huffmanCbCodeAc[256]; +t_uint16 huffmanCbSizeAc[256]; +t_uint16 huffmanCrCodeDc[12]; +t_uint16 huffmanCrSizeDc[12]; +t_uint16 huffmanCrCodeAc[256]; +t_uint16 huffmanCrSizeAc[256]; +} t_sva_huffman_table; + +typedef struct { +t_sva_postprocessor_capability_id transformId; +t_sva_postprocessor_external_sync_mode syncMode; +t_bool isDirectScreenAccess; // TRUE => screenFrameBufferBaseAddr SHALL be provided +// FALSE => the output buffer(s) will be provided one by one +// through SVA_PushImageBuffer() call +t_bool isDoubleBufferMode; // Only meaning if isDirectScreenAccess == TRUE +// TRUE => toggle between the 2 next frame buffers +// FALSE => use only the first one +// N.B: if isDirectScreenAccess == TRUE and isDoubleBufferMode == TRUE +// then the HCL will raised alternatively SVA_EVENT_POSTPROCESSOR_SYNCHRO and SVA_EVENT_POSTPROCESSOR_ALT_SYNCHRO events +// else (isDoubleBufferMode == FALSE) only SVA_EVENT_POSTPROCESSOR_SYNCHRO will be raised +t_physical_address screenFrameBufferBaseAddr; +t_physical_address screenAlternateFrameBufferBaseAddr; +t_sva_windowed_frame_desc sourceFrameDesc; +t_sva_image_desc resizedImageDesc; +t_sva_window_desc clippedWindowDesc; +t_sva_windowed_frame_desc videoFrameBufferDesc; +t_uint32 displaySyncLine; // SVA_EVENT_POSTPROCESSOR_LINE_SYNCHRO event will be raised +// when displaying the displaySyncLine line +// to disable event generation please use SVA_NO_GRABSYNC_LINE (1023=0x3FF) value +// if enable (!=1023) must be multiple of 16 and value range: 16 to source_window_height +t_sva_postprocessor_color_matrix colorMatrix; // matrix coef range: -1024 to 1023 +t_sva_color_range outputRange; +t_sva_postprocessor_ace_mode aceMode; +t_sva_ace_strength aceStrength; +t_sva_color_range aceRange; +t_sva_color_depth bitsPerPixel; +t_sva_mirroring_mode mirrorMode; +t_sva_rotation_mode rotationMode; +t_uint8 contrast; // values in [0..100] range. 50 is the standard value +t_uint8 brightness; // values in [0..100] range. 50 is the standard value +t_bool isDithering; +t_sva_deblocking_filter_mode deblockingFilterMode; +t_sva_deringing_filter_mode deringingFilterMode; +t_sva_sampling_format chromaSamplingFormat; +t_uint8 alphaKey; +t_bool redBlueSwap; +t_bool raster_in_format; +} t_sva_postprocessor_configuration; + + +typedef struct { +t_sva_service_state state; +t_sva_postprocessor_error_id errorId; +t_uint32 nbInputImagesPostProcessed; +t_uint32 nbOutputImagesDisplayed; +t_bool isAceEnable; +t_sva_ace_offset aceOffset; +t_sva_service_event_stats eventStats; +t_sva_service_bufferization_stats bufferizationStats; +} t_sva_postprocessor_status; + +typedef struct { +t_sva_sw_processing_capability_id transformId; +t_sva_image_desc originalPicture; +t_bool isUsingCustomZoneOfInterestBitmap; +t_sva_offset_desc startCroppingOffset; +t_uint32 horizontalThreshold; +t_uint32 verticalThreshold; +t_uint16 customZoneOfInterestBitmap[84]; +t_bool raster_in_format; +t_bool no_search_window; +} t_sva_sw_processing_configuration; + + +typedef struct { +t_sva_service_state state; +t_sva_sw_processing_error_id errorId; +t_uint32 nbImagesStabilized; +t_sva_service_event_stats eventStats; +t_sva_service_bufferization_stats bufferizationStats; +} t_sva_sw_processing_status; + + + +typedef enum { +SVA_NON_THUMBNAIL, +SVA_THUMBNAIL_DC_420MB /* Specific image buffer will have to be pushed out */ +} t_sva_thumbnail_mode; + + +typedef struct { +t_sva_still_image_encoder_capability_id transformId; +t_sva_codec_mode mode; // see §2.9: encoder => bitstream buffer as output +t_bool isSliceMode; +t_sva_thumbnail_mode thumbnailMode; +t_sva_windowed_frame_desc sourceFrameDesc; // if isSliceMode === TRUE, then no cropping possible +// sourceFrameDesc.window "==" sourceFrameDesc.frame +t_bool raster_in_format; +tp_sva_still_algo_configuration_params pAlgoConfig; +} t_sva_still_encoder_configuration; + +typedef enum +{ + SVA_JPEG_ENCODE_ROTATION_NONE, + SVA_JPEG_ENCODE_ROTATION_ANTICLOCKWISE, + SVA_JPEG_ENCODE_ROTATION_CLOCKWISE + }t_sva_jpeg_encode_on_fly_rotation; + +typedef struct { +t_uint16 restartInterval; +t_bool isOptimizeQuantTableEnable; +t_sva_jpeg_encode_on_fly_rotation rotation; +t_bool isOptimizeHuffmanTableEnable; +t_uint16 targetBpp; /* unit is 1/256 bpp */ +t_sva_quantization_table quantizationTable; /* WARNING: encoder use only one chroma table */ +/* (here quant_cb) */ +/* could be undefined if isOptimizeQuantTableEnable==TRUE */ +// value range for quant_y/cb/cr params: 1 to 255 +t_sva_huffman_table huffmanTable; /* could be undefined if isOptimizeHuffmanTableEnable==TRUE */ +// value range for huffman-Y/Cb/Cr-Size-Dc/Ac params: 1 to 16 (if 0 it will not be used) +} t_sva_still_algo_jpeg_configuration_params; + + +typedef struct { +t_sva_service_state state; +t_sva_still_image_encoder_error_id errorId; +t_uint32 nbBytesEncoded; +t_uint32 nbImagesEncoded; +t_sva_service_event_stats eventStats; +t_sva_service_bufferization_stats bufferizationStats; +} t_sva_still_encoder_status; + + +typedef struct { +t_uint16 hSamplingFactorY; +t_uint16 vSamplingFactorY; +t_uint16 hSamplingFactorCb; +t_uint16 vSamplingFactorCb; +t_uint16 hSamplingFactorCr; +t_uint16 vSamplingFactorCr;// param SamplingFactor-xx value: 1, 2 or 4 if used +//(used if componentSelector-xx = 1: if color_mode = monochrome only xSamplingFactorY used) +} t_sva_sampling_factor; + + +typedef struct { +t_uint16 restartInterval; +t_sva_huffman_table huffmanTable; +t_sva_quantization_table quantizationTable; +} t_sva_still_decoder_algo_sequential_jpeg_header_infos; + + +typedef struct { +t_uint16 nbScanComponents; +t_uint16 componentSelectorY; //value: 0 = the Y component is not present in the current scan; 1 = present +t_uint16 componentSelectorCb; //value: 0 = the Cb component is not present in the current scan; 1 = present +t_uint16 componentSelectorCr; //value: 0 = the Cr component is not present in the current scan; 1 = present +t_uint16 startSpectralSelection; // value range: 0 to 63 +t_uint16 endSpectralSelection; // value range: startSpectralSelection to 63 +t_uint16 successiveApproxPosition; +t_uint16 restartInterval; +t_sva_huffman_table huffmanTable; +t_sva_quantization_table quantizationTable; +} t_sva_still_decoder_algo_progressive_jpeg_header_infos; + + +typedef struct { +t_sva_still_image_decoder_capability_id transformId; +t_sva_codec_mode mode; // see §2.9: decoder => bitstream buffer as input +t_sva_image_desc decodedFrameDesc; +t_sva_window_desc crop_window; /*cropping is only supported from FW 3.6.0 onwards and HCL 3.4.0 onwards */ +t_sva_ace_strength aceStrength; +t_bool is_cropping_enabled; +t_bool no_slice_mode; +tp_sva_still_algo_configuration_params pAlgoConfig; +} t_sva_still_decoder_configuration; + + +typedef struct { +t_sva_still_image_color_mode colorMode; +t_sva_sampling_factor samplingFactor; // param SamplingFactor-xx value: 1, 2 or 4 if used +//(used if componentSelector-xx = 1: if colormode = monochrome only SamplingFactorY used) +t_sva_downsampling_factor downsamplingFactor; +} t_sva_still_algo_jpeg_decoder_configuration_params; + + +typedef struct { +t_sva_service_state state; +t_sva_still_image_decoder_error_id errorId; +t_uint32 nbBytesDecoded; +t_uint32 nbImagesDecoded; +t_sva_service_event_stats eventStats; +t_sva_service_bufferization_stats bufferizationStats; +} t_sva_still_decoder_status; + + +typedef struct { +t_bool isInterlacedEnabled; +t_uint16 numberOfLines ;// 6<=numberOfLines<=2047 +t_uint16 field1BlankingStartLine ; //FSB1: 1<=FBS1<=numberOfLines +//if isInterlacedEnabled=FALSE: FBS1!=FBE1 +//if isInterlacedEnabled=TRUE: (FBS1. */ +/*---------------------------------------------------------------------------*/ + + +/*------------------------------------------------------------------------ + * Includes + *----------------------------------------------------------------------*/ + +#include "hcl_defs.h" +#include "sva_hwp.h" +#include "sva_host_interface.h" +//#include "sva_memorymgt.h" +#include "sva_taskmgt.h" +#include "sva_taskmgtp.h" +#include "sva_hwtaskmgt.h" +#include "sva_hwtaskmgtp.h" + +/*------------------------------------------------------------------------ + * Private macro + *----------------------------------------------------------------------*/ +#if (SVA_TM_HW_SEM_PARANOID==1) + #define SVA_TM_HW_LOCK_SEM_DEBUG(a) sva_TM_HW_LockSemaphore(a) + #define SVA_TM_HW_UNLOCK_SEM_DEBUG(a) sva_TM_HW_UnlockSemaphore(a) +#else + #define SVA_TM_HW_LOCK_SEM_DEBUG(a) (void)(0) + #define SVA_TM_HW_UNLOCK_SEM_DEBUG(a) (void)(0) +#endif + +/*------------------------------------------------------------------------ + * Global Variables + *----------------------------------------------------------------------*/ +#ifdef __DEBUG + ALIGN(32) PRIVATE t_sva_tm_hw_debug TmHwDebugTable[SVA_TM_HW_TASK_NB]; +#endif + +#define SVA_IRP_SAVE_TIMEOUT 0xE0000 +#define SVA_CHECK_INTERVAL 0x0500 + +/* Physical access to register area */ +PRIVATE t_sva_regs_mapping *pSVAReg; +PRIVATE volatile t_sva_task_regs *PTaskRegs[SVA_TM_HW_TASK_NB]; +PUBLIC t_sva_tm_hw_task_state TaskState[SVA_TM_HW_TASK_NB]; +PRIVATE t_bool isPacketCmdRead; + + t_sva_tm_subtask_list_info p_CurrentSubtaskListId; +/*@BORT-$TOP*/ +/*Add Aborting state machine, so that till EOK corresponding to ABORT is received state is maintained*/ +/*This will help in preventing other commands to be excetued on the aborted task */ +/*Add SVA_TM_HW_WAIT_EOK_ABORT; */ +/*SVA_TM_HW_RUNNING-------------SVA_TM_HW_ABORT-------->>SVA_TM_HW_ABORTING---------------ABORT_EOK------->SVA_TM_HW_IDLE */ +/*@BORT-$TOP*/ +PRIVATE const t_sva_tm_hw_task_state stateMachine[SVA_TM_HW_LAST_DUMMY_STATE][SVA_TM_HW_LAST_DUMMY_TRANSITION]= { + /* Current State = SVA_TM_HW_IDLE */ + { + SVA_TM_HW_WAIT_START_ACK, /*SVA_TM_HW_SUBTASK_INSERT*/ + SVA_TM_HW_WAIT_START_ACK, /*SVA_TM_HW_FAKE*/ + SVA_TM_HW_IDLE, /*SVA_TM_HW_ACK*/ + SVA_TM_HW_IDLE, /*SVA_TM_HW_BRC_ERR_EOK_CNT_NOT_ZERO*/ + SVA_TM_HW_IDLE, /*SVA_TM_HW_BRC_ERR_EOK_CNT_ZERO*/ + SVA_TM_HW_IDLE, /*SVA_TM_HW_ABORT*/ + SVA_TM_HW_IDLE, /*SVA_TM_HW_ABORT_EOK*/ + SVA_TM_HW_WAIT_ACK_RETURN_IDLE /*SVA_TM_HW_RD_WR_PACKET*/ + }, + /* Current State = SVA_TM_HW_WAIT_START_ACK */ + { + SVA_TM_HW_WAIT_START_ACK, /*SVA_TM_HW_SUBTASK_INSERT*/ + SVA_TM_HW_WAIT_START_ACK, /*SVA_TM_HW_FAKE*/ + SVA_TM_HW_RUNNING, /*SVA_TM_HW_ACK*/ + SVA_TM_HW_WAIT_START_ACK, /*SVA_TM_HW_BRC_ERR_EOK_CNT_NOT_ZERO*/ + SVA_TM_HW_WAIT_START_ACK, /*SVA_TM_HW_BRC_ERR_EOK_CNT_ZERO*/ + SVA_TM_HW_WAIT_START_ACK, /*SVA_TM_HW_ABORT*/ + SVA_TM_HW_WAIT_START_ACK, /*SVA_TM_HW_ABORT_EOK*/ + SVA_TM_HW_WAIT_START_ACK_CMD_PACKET /*SVA_TM_HW_RD_WR_PACKET*/ + }, + /* Current State = SVA_TM_HW_RUNNING */ + { + SVA_TM_HW_RUNNING, /*SVA_TM_HW_SUBTASK_INSERT*/ + SVA_TM_HW_RUNNING, /*SVA_TM_HW_FAKE*/ + SVA_TM_HW_RUNNING, /*SVA_TM_HW_ACK*/ + SVA_TM_HW_WAIT_START_ACK, /*SVA_TM_HW_BRC_ERR_EOK_CNT_NOT_ZERO*/ + SVA_TM_HW_IDLE, /*SVA_TM_HW_BRC_ERR_EOK_CNT_ZERO*/ + SVA_TM_HW_ABORTING, /*SVA_TM_HW_ABORT*/ + SVA_TM_HW_IDLE, /*SVA_TM_HW_ABORT_EOK*/ //check:: This is wrong : state should be _RUNNING + SVA_TM_HW_WAIT_ACK_RETURN_RUNNING /*SVA_TM_HW_RD_WR_PACKET*/ + }, + /* Current State = SVA_TM_HW_WAIT_ACK_RETURN_IDLE */ + { + SVA_TM_HW_WAIT_ACK_RETURN_WAIT_START_ACK, /*SVA_TM_HW_SUBTASK_INSERT*/ + SVA_TM_HW_WAIT_ACK_RETURN_IDLE, /*SVA_TM_HW_FAKE*/ + SVA_TM_HW_IDLE, /*SVA_TM_HW_ACK*/ + SVA_TM_HW_WAIT_ACK_RETURN_IDLE, /*SVA_TM_HW_BRC_ERR_EOK_CNT_NOT_ZERO*/ + SVA_TM_HW_WAIT_ACK_RETURN_IDLE, /*SVA_TM_HW_BRC_ERR_EOK_CNT_ZERO*/ + SVA_TM_HW_WAIT_ACK_RETURN_IDLE, /*SVA_TM_HW_ABORT*/ + SVA_TM_HW_WAIT_ACK_RETURN_IDLE, /*SVA_TM_HW_ABORT_EOK*/ + SVA_TM_HW_WAIT_ACK_RETURN_IDLE /*SVA_TM_HW_RD_WR_PACKET*/ + }, + /* Current State = SVA_TM_HW_WAIT_ACK_RETURN_WAIT_START_ACK */ + { + SVA_TM_HW_WAIT_ACK_RETURN_WAIT_START_ACK, /*SVA_TM_HW_SUBTASK_INSERT*/ + SVA_TM_HW_WAIT_ACK_RETURN_WAIT_START_ACK, /*SVA_TM_HW_FAKE*/ + SVA_TM_HW_WAIT_START_ACK, /*SVA_TM_HW_ACK*/ + SVA_TM_HW_WAIT_ACK_RETURN_WAIT_START_ACK, /*SVA_TM_HW_BRC_ERR_EOK_CNT_NOT_ZERO*/ + SVA_TM_HW_WAIT_ACK_RETURN_WAIT_START_ACK, /*SVA_TM_HW_BRC_ERR_EOK_CNT_ZERO*/ + SVA_TM_HW_WAIT_ACK_RETURN_WAIT_START_ACK, /*SVA_TM_HW_ABORT*/ + SVA_TM_HW_WAIT_ACK_RETURN_WAIT_START_ACK, /*SVA_TM_HW_ABORT_EOK*/ + SVA_TM_HW_WAIT_ACK_RETURN_WAIT_START_ACK /*SVA_TM_HW_RD_WR_PACKET*/ + }, + /* Current State = SVA_TM_HW_WAIT_START_ACK_CMD_PACKET */ + { + SVA_TM_HW_WAIT_START_ACK_CMD_PACKET, /*SVA_TM_HW_SUBTASK_INSERT*/ + SVA_TM_HW_WAIT_START_ACK_CMD_PACKET, /*SVA_TM_HW_FAKE*/ + SVA_TM_HW_WAIT_ACK_RETURN_RUNNING, /*SVA_TM_HW_ACK*/ + SVA_TM_HW_WAIT_START_ACK_CMD_PACKET, /*SVA_TM_HW_BRC_ERR_EOK_CNT_NOT_ZERO*/ + SVA_TM_HW_WAIT_START_ACK_CMD_PACKET, /*SVA_TM_HW_BRC_ERR_EOK_CNT_ZERO*/ + SVA_TM_HW_WAIT_START_ACK_CMD_PACKET, /*SVA_TM_HW_ABORT*/ + SVA_TM_HW_WAIT_START_ACK_CMD_PACKET, /*SVA_TM_HW_ABORT_EOK*/ + SVA_TM_HW_WAIT_START_ACK_CMD_PACKET /*SVA_TM_HW_RD_WR_PACKET*/ + }, + /* Current State = SVA_TM_HW_WAIT_ACK_RETURN_RUNNING */ + { + SVA_TM_HW_WAIT_ACK_RETURN_RUNNING, /*SVA_TM_HW_SUBTASK_INSERT*/ + SVA_TM_HW_WAIT_ACK_RETURN_RUNNING, /*SVA_TM_HW_FAKE*/ + SVA_TM_HW_RUNNING, /*SVA_TM_HW_ACK*/ + SVA_TM_HW_WAIT_ACK_RETURN_WAIT_START_ACK, /*SVA_TM_HW_BRC_ERR_EOK_CNT_NOT_ZERO*/ + SVA_TM_HW_WAIT_ACK_RETURN_IDLE, /*SVA_TM_HW_BRC_ERR_EOK_CNT_ZERO*/ + SVA_TM_HW_WAIT_ACK_RETURN_RUNNING, /*SVA_TM_HW_ABORT*/ + SVA_TM_HW_WAIT_ACK_RETURN_RUNNING, /*SVA_TM_HW_ABORT_EOK*/ + SVA_TM_HW_WAIT_ACK_RETURN_RUNNING /*SVA_TM_HW_RD_WR_PACKET*/ + }, + /*Current State = SVA_TM_HW_ABORTING*/ + { + SVA_TM_HW_ABORTING, /*SVA_TM_HW_SUBTASK_INSERT*/ + SVA_TM_HW_ABORTING, /*SVA_TM_HW_FAKE*/ + SVA_TM_HW_ABORTING, /*SVA_TM_HW_ACK*/ + SVA_TM_HW_ABORTING, /*SVA_TM_HW_BRC_ERR_EOK_CNT_NOT_ZERO*/ + SVA_TM_HW_IDLE, /*SVA_TM_HW_BRC_ERR_EOK_CNT_ZERO*/ + SVA_TM_HW_ABORTING, /*SVA_TM_HW_ABORT*/ + SVA_TM_HW_IDLE, /*SVA_TM_HW_ABORT_EOK*/ + SVA_TM_HW_ABORTING /*SVA_TM_HW_RD_WR_PACKET*/ + }, + + +}; + +/*------------------------------------------------------------------------ + * Private Macros + *----------------------------------------------------------------------*/ + +/*------------------------------------------------------------------------ + * PRIVATE Functions Prototypes + *----------------------------------------------------------------------*/ +PRIVATE t_physical_address sva_TM_HW_GetSubTaskPhysicalAddress(t_sva_tm_subtask_id); +PRIVATE t_sva_tm_subtask_id sva_TM_HW_GetSubTaskIdFromPhysicalAddress(t_physical_address); +PRIVATE void sva_TM_HW_UpdateState(t_sva_tm_task_id,t_sva_tm_hw_task_transition); +PRIVATE void sva_TM_HW_RemoveSubtaskBelongsToSameService(t_sva_tm_task_id,t_sva_tm_subtasklist_id); +PRIVATE void sva_TM_HW_RemoveSubtaskBelongsToSameServiceAbort(t_sva_tm_task_id,t_sva_tm_subtasklist_id); +PRIVATE void sva_TM_HW_RemoveSubtask(t_sva_tm_subtask_id subtaskId); + +/****************************************************************************/ +/* NAME: sva_TM_HW_Init( */ +/* t_logical_address RegLogicalBaseAddr, */ +/* t_logical_address MemLogicalBaseAddr) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: This routine initializes hardware task management module */ +/* */ +/* PARAMETERS: */ +/* IN : - RegLogicalBaseAddr : SVA Registers base address */ +/* - MemLogicalBaseAddr : SVA Memory base address */ +/* */ +/* OUT: none */ +/* */ +/* RETURN: */ +/* t_sva_tm_error: SVA_TM_OK */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: no */ +/****************************************************************************/ +PUBLIC t_sva_tm_error sva_TM_HW_Init( t_logical_address RegLogicalBaseAddr, + t_logical_address MemLogicalBaseAddr) +{ + t_uint32 i; + + (void)MemLogicalBaseAddr; + /* Target the SVA's register area */ + pSVAReg=(t_sva_regs_mapping *)RegLogicalBaseAddr; + + /*init task regs pointer*/ + PTaskRegs[0]=(t_sva_task_regs *)&pSVAReg->task.vecTask; + PTaskRegs[1]=(t_sva_task_regs *)&pSVAReg->task.vdcTask; + PTaskRegs[2]=(t_sva_task_regs *)&pSVAReg->task.grbTask; + PTaskRegs[3]=(t_sva_task_regs *)&pSVAReg->task.dspTask; + PTaskRegs[4]=(t_sva_task_regs *)&pSVAReg->task.tvdTask; + + /* reset state of hardware semaphore */ + sva_TM_HW_UnlockSemaphore(SVA_TM_GRAB); + sva_TM_HW_UnlockSemaphore(SVA_TM_DISPLAY); + sva_TM_HW_UnlockSemaphore(SVA_TM_DECODE); + sva_TM_HW_UnlockSemaphore(SVA_TM_ENCODE); + sva_TM_HW_UnlockSemaphore(SVA_TM_TVO); + + /* reset register with undefined reset value */ + for(i=0;igenTask.nad=0; + PTaskRegs[i]->genTask.nty=0; + PTaskRegs[i]->genTask.nts=0; + PTaskRegs[i]->genTask.nrs=0; + + PTaskRegs[i]->genTask.cad=0; + PTaskRegs[i]->genTask.cty=0; + PTaskRegs[i]->genTask.cts=0; + PTaskRegs[i]->genTask.crs=0; + + PTaskRegs[i]->genTask.iad=0; + PTaskRegs[i]->genTask.ity=0; + PTaskRegs[i]->genTask.its=0; + PTaskRegs[i]->genTask.irs=0; + + + PTaskRegs[i]->genTask.cnt=0; + } + + /*init state machines*/ + for(i=0;i answer should be yes since we are not reeantrant +*/ + +PUBLIC t_sva_tm_subtask_info *sva_TM_HW_GetCurrentSubTaskId(t_sva_tm_task_id taskId, t_uint32 *p_executed_abort_address) +{ + /* this API is expected to be called in locked sempaphore state */ + volatile t_sva_task_regs *pTasksRegs=PTaskRegs[taskId]; + + t_sva_tm_subtask_info *pCurrentSubtaskInfo = NULL; + + /*get current programmed subtaskinfo and subtaskid*/ + *p_executed_abort_address = pTasksRegs->genTask.cad; + if (*p_executed_abort_address != 0) + { + pCurrentSubtaskInfo=(t_sva_tm_subtask_info *) sva_TM_HW_GetSubTaskIdFromPhysicalAddress((t_physical_address) (*p_executed_abort_address)); + } + else + { + if (pTasksRegs->genTask.cnt != 0) + { + *p_executed_abort_address = pTasksRegs->genTask.nad; + pCurrentSubtaskInfo=(t_sva_tm_subtask_info *) sva_TM_HW_GetSubTaskIdFromPhysicalAddress((t_physical_address) (*p_executed_abort_address));\ + *p_executed_abort_address = 0; + } + } + + return pCurrentSubtaskInfo; +} + +PUBLIC t_sva_tm_error sva_TM_HW_InsertImmediat( + t_sva_tm_subtask_id subtaskId +) +{ + t_sva_tm_subtask_info *pSubtaskInfo=(t_sva_tm_subtask_info *) subtaskId; + t_sva_tm_task_id taskId=pSubtaskInfo->taskId; + volatile t_sva_task_regs *pTasksRegs=PTaskRegs[taskId]; + volatile t_sva_subtask_link *pSubtaskLink=(t_sva_subtask_link *)&pTasksRegs->genTask.nad; + t_uint32 taskCounter; + + /*lock semaphore*/ + sva_TM_HW_LockSemaphore(taskId); + /*read task counter value*/ + taskCounter=pTasksRegs->genTask.cnt; + /*search link structure to update*/ + if (taskCounter!=0) + { + t_sva_tm_subtask_info *pLastSubtaskInfo; + + /*get last programmed subtaskinfo and subtaskid*/ + pLastSubtaskInfo=(t_sva_tm_subtask_info *) sva_TM_HW_GetSubTaskIdFromPhysicalAddress((t_physical_address) pTasksRegs->genTask.nad); + while(pLastSubtaskInfo->pNextInfo!=NULL) + { + pLastSubtaskInfo=pLastSubtaskInfo->pNextInfo; + } + + + + + /*link infos pointer*/ + pSubtaskInfo->pPreviousInfo=pLastSubtaskInfo; + pSubtaskInfo->pNextInfo=NULL; + pLastSubtaskInfo->pNextInfo=pSubtaskInfo; + /*get link structure to update*/ + pSubtaskLink=(t_sva_subtask_link *)((t_uint32)pLastSubtaskInfo+sizeof(t_sva_tm_subtask_info)); + } + else + { + /*first subtask of list so previous and next are invalid subtask*/ + pSubtaskInfo->pPreviousInfo=NULL; + pSubtaskInfo->pNextInfo=NULL; + } + /*update link structure*/ + pSubtaskLink->addr=sva_TM_HW_GetSubTaskPhysicalAddress(subtaskId); + pSubtaskLink->type=pSubtaskInfo->nty; + pSubtaskLink->execution_time_stamp=pSubtaskInfo->timestamp; + pSubtaskLink->dependency=0; + /*set task counter to new value*/ + if (taskId==SVA_TM_TVO) + { + if (TaskState[SVA_TM_TVO]==SVA_TM_HW_IDLE) + { + /*loop forever mode*/ + pTasksRegs->genTask.cnt=SVA_TM_HW_LOOP_FOREVER; + } + /*program last inserted subtask such that it link to itself*/ + pSubtaskLink=(t_sva_subtask_link *)((t_uint32)pSubtaskInfo+sizeof(t_sva_tm_subtask_info)); + pSubtaskLink->addr=sva_TM_HW_GetSubTaskPhysicalAddress(subtaskId); + pSubtaskLink->type=pSubtaskInfo->nty; + pSubtaskLink->execution_time_stamp=pSubtaskInfo->timestamp; + pSubtaskLink->dependency=0; + } + else + { + /*increment task counter*/ + pTasksRegs->genTask.cnt++; + } + /*update state machine*/ + sva_TM_HW_UpdateState(taskId,SVA_TM_HW_SUBTASK_INSERT); + /*unlock semaphore*/ + sva_TM_HW_UnlockSemaphore(taskId); + + return SVA_TM_OK; +} /* End of sva_TM_HW_InsertImmediat() function. */ + +/****************************************************************************/ +/* NAME: sva_TM_HW_InsertTimed( */ +/* t_sva_tm_subtask_id subtaskId, */ +/* t_sva_ticks ticks */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: This function will insert subtask at the right place */ +/* according to it's tick value and according to others subtask*/ +/* PARAMETERS: */ +/* IN : */ +/* - subtaskId : identifier of the subtask to insert */ +/* subtask is added at the end of the physical list */ +/* - ticks : excecution tick number of the subtask. Subtask is inserted*/ +/* in queue. */ +/* */ +/* OUT: none */ +/* */ +/* RETURN: */ +/* t_sva_error: SVA_TM_OK */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: no */ +/****************************************************************************/ +/* + TO DO : + - allow insertion in the right place + => need API to do that => use of stop + => need an algorithm to do that +*/ +PUBLIC t_sva_tm_error sva_TM_HW_InsertTimed( + t_sva_tm_subtask_id subtaskId, + t_sva_ticks ticks +) +{ + (void) ticks; + + return sva_TM_HW_InsertImmediat(subtaskId); +} /* End of sva_TM_HW_InsertTimed() function. */ + + +/****************************************************************************/ +/* NAME: sva_TM_HW_GenerateFake( */ +/* t_sva_tm_task_id taskId */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: This function will restart task is needed. This will insure */ +/* that al least one interrupt is generated. So logical list */ +/* will return a fake event on an it context. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - taskId : Identifier of the task for which we have to insure an */ +/* interrupt will be generated */ +/* */ +/* OUT: none */ +/* */ +/* RETURN: */ +/* t_sva_error: SVA_TM_OK */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: no */ +/****************************************************************************/ +PUBLIC t_sva_tm_error sva_TM_HW_GenerateFake( + t_sva_tm_task_id taskId +) +{ + SVA_TM_HW_LOCK_SEM_DEBUG(taskId); + + /*update state machine*/ + sva_TM_HW_UpdateState(taskId,SVA_TM_HW_FAKE); + + SVA_TM_HW_UNLOCK_SEM_DEBUG(taskId); + + return SVA_TM_OK; +} /* End of sva_TM_HW_GenerateFake() function. */ + + + + +PUBLIC t_sva_tm_subtask_list_info * sva_TM_GetOnePendingAbortRequest(t_sva_tm_task_id taskId); + +PUBLIC void sva_TM_HW_TestToEmulateHWInterrupt(t_sva_tm_task_id taskId, t_uint32 *hwIad, t_uint32 *hwIsr, t_uint32 *hwIts, t_sva_tm_subtask_id subtask_id_to_convert) +{ + if( *hwIsr == SVA_TM_HW_IT_ACK) + { + /* check here to use ACK as ERR and populate IAD */ + /* this is triggered as a pure ACK interrupt */ + /* calculate physical equivqlent IAD register value and update */ + + if (subtask_id_to_convert != INVALID_SUBTASK_ID) + { + //*hwIad = sva_TM_HW_GetSubTaskPhysicalAddress(subtask_id_to_convert); + } + } + + if ( + ((((*hwIsr)&SVA_TM_HW_IT_EOK)!=0) || (((*hwIsr)&SVA_TM_HW_IT_EOT)!=0)) + && (((*hwIad)&(~MASK_BIT0))!=0) + ) + { + /* a subtask finished test if IAD is to be used */ + + t_sva_tm_subtask_info *pInfo=(t_sva_tm_subtask_info *) sva_TM_HW_GetSubTaskIdFromPhysicalAddress(*hwIad); + + if (pInfo != (t_sva_tm_subtask_info *)INVALID_SUBTASK_ID) + { + t_sva_tm_subtask_list_info *p_sva_tm_subtask_list_info = (t_sva_tm_subtask_list_info *)pInfo->subtaskListId; + + if (p_sva_tm_subtask_list_info == (t_sva_tm_subtask_list_info *)INVALID_SUBTASK_LIST_ID) + { + p_sva_tm_subtask_list_info = sva_TM_GetOnePendingAbortRequest(taskId); + if (p_sva_tm_subtask_list_info == NULL) + { + p_sva_tm_subtask_list_info = (t_sva_tm_subtask_list_info *)INVALID_SUBTASK_LIST_ID; + } + else + { + if (p_sva_tm_subtask_list_info->firstSubtaskId != INVALID_SUBTASK_ID) + { + *hwIad = sva_TM_HW_GetSubTaskPhysicalAddress(p_sva_tm_subtask_list_info->firstSubtaskId); + } + } + } + + if (p_sva_tm_subtask_list_info != (t_sva_tm_subtask_list_info *)INVALID_SUBTASK_LIST_ID) + { + if(p_sva_tm_subtask_list_info->is_abort_requested == TRUE) + { + t_bool generate_err = TRUE; + if (p_sva_tm_subtask_list_info->nbSubtask == 0) + { + /* if we reach here it signifies that IAD was not be used IAD is not latest */ + /* get IAD to populate ERR simulation for aborting the service and generating error */ + /* left if next processing layers/code doesn't handle already handled iad */ + } + else + { + /* if we reach here then IAD must be used to trigger ERR event, we don't havre choise of ignoring IAD in this case but to treat it as valid and recent */ + } + + if (((*hwIsr)&SVA_TM_HW_IT_EOK)==0) /* it means we are here due to EOT */ + { + /* Look for the last subtask inserted in hardware list. */ + if ( (pInfo->nextSubtaskId == INVALID_SUBTASK_ID) || + ((pInfo->nextSubtaskId != INVALID_SUBTASK_ID) && + (((t_sva_tm_subtask_info *)(pInfo->nextSubtaskId))->subtaskState != SVA_TM_SCHECULED)) ) + { + } + else + { + generate_err = FALSE; + } + + } + + if (generate_err == TRUE) + { + if (p_sva_tm_subtask_list_info->executed_abort_iad != 0) + { + if (p_sva_tm_subtask_list_info->executed_abort_iad != *hwIad) + { + //exit(-1); + } + *hwIad = p_sva_tm_subtask_list_info->executed_abort_iad; + p_sva_tm_subtask_list_info->executed_abort_iad = 0; + } + + (*hwIsr)|=SVA_TM_HW_IT_ERR; /* triger it as hardware error interrupt */ +// (*hwIsr)&=~SVA_TM_HW_IT_EOT; /* mask eot */ + //(*hwIsr)|=SVA_TM_HW_IT_EOK; /* mask eok */ + p_sva_tm_subtask_list_info->is_abort_requested = FALSE; /* clear to indicate that abort condition has been taken into account */ + } + } + } + } + } + + #if 0 + if ( + ((((*hwIsr)&SVA_TM_HW_IT_EOK)!=0) || (((*hwIsr)&SVA_TM_HW_IT_ACK)!=0)) + && (((*hwIad)&(~MASK_BIT0))!=0) + ) + { + t_sva_tm_subtask_info *pInfo=(t_sva_tm_subtask_info *) sva_TM_HW_GetSubTaskIdFromPhysicalAddress(*hwIad); + + if (pInfo != (t_sva_tm_subtask_info *)INVALID_SUBTASK_ID) + { + t_sva_tm_subtask_list_info *p_sva_tm_subtask_list_info = (t_sva_tm_subtask_list_info *)pInfo->subtaskListId; + if (p_sva_tm_subtask_list_info != (t_sva_tm_subtask_list_info *)INVALID_SUBTASK_LIST_ID) + { + if ( + (p_sva_tm_subtask_list_info->nbSubtask == 0 && ((*hwIsr)&SVA_TM_HW_IT_ACK)) + || (p_sva_tm_subtask_list_info->nbSubtask != 0 && /*((*hwIsr)&SVA_TM_HW_IT_ACK) && */((*hwIsr)&SVA_TM_HW_IT_EOK)) + ) + if(p_sva_tm_subtask_list_info->is_abort_requested == TRUE) + { + (*hwIsr)|=SVA_TM_HW_IT_ERR; /* triger it as hardware error interrupt */ + p_sva_tm_subtask_list_info->is_abort_requested = FALSE; /* clear to indicate that abort condition has been taken into account */ + } + } + } + } + #endif +} + +/*@BORT-$TOP*/ + /*undesired task :if undesired task has been aborted but do capture_IAD to identify exact subtask which is terminated*/ + /* How to distinguish b/w desired from undesired ?*/ + /* + + sva_TM_HW_RetriveIAD(capture_IAD) + { + t_sva_tm_subtask_info *pInfo=(t_sva_tm_subtask_info *) sva_TM_HW_GetSubTaskIdFromPhysicalAddress(capture_iad); + + pPrevSubtaskLink=(t_sva_subtask_link *)((t_uint32)pInfo->pPreviousInfo+sizeof(t_sva_tm_subtask_info)); + pPrevSubtaskLink->address :(which is previous_ subtask_iad) + t_sva_tm_subtask_info *pInfo_prev=(t_sva_tm_subtask_info *) sva_TM_HW_GetSubTaskIdFromPhysicalAddress(capture_iad); + t_sva_tm_subtask_list_info *p_sva_tm_subtask_list_info = (t_sva_tm_subtask_list_info *)HwTasksInfos[taskId].(pInfo_prev->subtaskListId); + if (p_sva_tm_subtask_list_info-> state == _ABORTING_) + return iad; + + } + + */ + +PUBLIC t_uint32 sva_TM_HW_RetriveIAD(t_sva_tm_task_id taskId,t_uint32 iad) +{ + t_sva_tm_subtask_info *pInfo; + t_sva_subtask_link *pSubtaskLink; + t_sva_tm_subtask_list_info *p_sva_tm_subtask_list_info; + t_uint32 next_iad=0; + + + + pInfo = (t_sva_tm_subtask_info *) sva_TM_HW_GetSubTaskIdFromPhysicalAddress(iad); + p_sva_tm_subtask_list_info = (t_sva_tm_subtask_list_info *)pInfo->subtaskListId; + +// HCL_ASSERT((t_sva_tm_subtask_list_info *)pInfo->subtaskListId == (void *)INVALID_SUBTASK_LIST_ID); + + if (p_sva_tm_subtask_list_info->state != SVA_TM_ABORTING) + { + return iad; + } + else + { + while(1) + { + pSubtaskLink=(t_sva_subtask_link *)((t_uint32)pInfo->pNextInfo+sizeof(t_sva_tm_subtask_info)); + next_iad = pSubtaskLink->addr; + if(next_iad ==0) + { + break; + } + else + { + pInfo = (t_sva_tm_subtask_info *) sva_TM_HW_GetSubTaskIdFromPhysicalAddress(next_iad); + + p_sva_tm_subtask_list_info = (t_sva_tm_subtask_list_info *)pInfo->subtaskListId; + + if (p_sva_tm_subtask_list_info->state != SVA_TM_ABORTING) + { + return next_iad; + } + + } + + } + } + + + + return 0; + +} + + + +/****************************************************************************/ +/* NAME: sva_TM_HW_DispatchHWEvent( */ +/* t_sva_tm_task_id taskId, */ +/* t_uint32 iad, */ +/* t_uint32 isr, */ +/* t_uint32 its */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: This function will restart task is needed. This will insure */ +/* that al least one interrupt is generated. So logical list */ +/* will return a fake event on an it context. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - taskId : identifier of the task for which we receive some it */ +/* - iad : address of subtask at the origin of the interrupt */ +/* - isr : source(s) of the interrupt */ +/* - its : time stamp in ticks of the interrupt */ +/* */ +/* OUT: none */ +/* */ +/* RETURN: */ +/* none */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: no */ +/****************************************************************************/ +/* + TO DO : + - check if semaphore must be taken + => normaly no +*/ +/*what to add so that abort is served ain the updatestatemachine()*/ +PUBLIC void sva_TM_HW_DispatchHWEvent( + t_sva_tm_task_id taskId, + t_uint32 iad, + t_uint32 isr, + t_uint32 its +) +{ + volatile t_sva_task_regs *pTasksRegs=PTaskRegs[taskId]; + t_uint32 taskCounter; + + SVA_TM_HW_LOCK_SEM_DEBUG(taskId); + (void) its; + + /*read counter*/ + taskCounter=pTasksRegs->genTask.cnt; + +#ifdef __DEBUG + TmHwDebugTable[taskId].debugDesc[TmHwDebugTable[taskId].nbOfItReceived].iad=iad; + TmHwDebugTable[taskId].debugDesc[TmHwDebugTable[taskId].nbOfItReceived].isr=isr; + TmHwDebugTable[taskId].debugDesc[TmHwDebugTable[taskId].nbOfItReceived].its=its; + TmHwDebugTable[taskId].debugDesc[TmHwDebugTable[taskId].nbOfItReceived].taskCounter=taskCounter; + TmHwDebugTable[taskId].nbOfItReceived=(TmHwDebugTable[taskId].nbOfItReceived+1)%LOG_DEPTH; +#endif + + if ( (isr & SVA_TM_ABORT_HW_EVENT)!=0 ) + { + //t_uint32 capture_iad; + t_sva_tm_subtask_info *pInfo; + t_sva_tm_subtask_list_info *p_sva_tm_subtask_list_info; + //t_uint32 cnt=0; + + HCL_ASSERT(iad!=0); + + pInfo = (t_sva_tm_subtask_info *) sva_TM_HW_GetSubTaskIdFromPhysicalAddress(iad);//taken care below of not deleting no ABORTED task + if ((pInfo==NULL || pInfo==(t_sva_tm_subtask_info*)INVALID_SUBTASK_ID)){HCL_ASSERT(0);} + p_sva_tm_subtask_list_info = (t_sva_tm_subtask_list_info *)pInfo->subtaskListId; + if ((p_sva_tm_subtask_list_info==NULL || p_sva_tm_subtask_list_info==(t_sva_tm_subtask_list_info*)INVALID_SUBTASK_LIST_ID)){HCL_ASSERT(0);} + + { + //volatile t_sva_task_regs *pTasksRegs=PTaskRegs[taskId]; + volatile t_sva_subtask_link *pSubtaskLinkNAD; + pSubtaskLinkNAD=(t_sva_subtask_link *)&PTaskRegs[taskId]->genTask.nad; + pSubtaskLinkNAD->addr = iad; + pSubtaskLinkNAD->type = pInfo->nty; + pSubtaskLinkNAD->execution_time_stamp = pInfo->timestamp; + pSubtaskLinkNAD->dependency = 0; + } + + /* Remove all the aborted tasks*/ + // + while ( pInfo != (t_sva_tm_subtask_info *)INVALID_SUBTASK_ID && pInfo!=NULL) + { + HCL_ASSERT(pInfo!=NULL); + p_sva_tm_subtask_list_info = (t_sva_tm_subtask_list_info *)pInfo->subtaskListId; + if ( p_sva_tm_subtask_list_info->state==SVA_TM_ABORTING ) + { + /*remove subtasks that belong to same service from task and update task counter*/ + sva_TM_HW_RemoveSubtaskBelongsToSameServiceAbort(taskId,pInfo->subtaskListId); + } + + pInfo = pInfo->pNextInfo; + } + + taskCounter = 0; + + if (taskId != SVA_TM_GRAB) + { + volatile t_sva_task_regs *pTasksRegs=PTaskRegs[taskId]; + + if (pTasksRegs->genTask.nad != 0) + { + pInfo = (t_sva_tm_subtask_info *) sva_TM_HW_GetSubTaskIdFromPhysicalAddress((t_physical_address) pTasksRegs->genTask.nad); + + while(pInfo!=NULL) + { + taskCounter++; + pInfo = pInfo->pNextInfo; + + HCL_ASSERT(pInfo!=(t_sva_tm_subtask_info *)INVALID_SUBTASK_ID); + } + } + + pTasksRegs->genTask.cnt = taskCounter; + } + + /*@BORT-$TOP*/ + } + + /*test ack*/ + if (((isr&SVA_TM_HW_IT_ACK)!=0)/*&&((isr & SVA_TM_ABORT_HW_EVENT)==0)*/) + { + /*update state machine*/ + sva_TM_HW_UpdateState(taskId,SVA_TM_HW_ACK); + } + /*test eot*/ + if (((isr&SVA_TM_HW_IT_EOT)!=0)/*&&((isr & SVA_TM_ABORT_HW_EVENT)==0)*/) + { + /*@BORT-$TOP*/ + + t_sva_tm_subtask_info *pInfo=(t_sva_tm_subtask_info *) sva_TM_HW_GetSubTaskIdFromPhysicalAddress(iad); + + + + /*break link of finish subtask*/ + if (pInfo->pNextInfo!=NULL) {pInfo->pNextInfo->pPreviousInfo=NULL;} + } + /*test err || brc for encode task only*/ + if (((isr&SVA_TM_HW_IT_ERR)!=0 || ((isr&SVA_TM_HW_IT_BRC)!=0 && taskId==SVA_TM_ENCODE))/*&&((isr&SVA_TM_ABORT_HW_EVENT)==0)*/) + { + + + t_sva_tm_subtask_info *pInfo=(t_sva_tm_subtask_info *) sva_TM_HW_GetSubTaskIdFromPhysicalAddress(iad); + + + + /*remove subtasks that belong to same service from task and update task counter*/ + sva_TM_HW_RemoveSubtaskBelongsToSameService(taskId,pInfo->subtaskListId); + /*reread taskcounter*/ + taskCounter=pTasksRegs->genTask.cnt; + /*update state machine*/ + /*state machine will be update on the following EOK*/ + } + + /*test eok*/ + if (((isr&SVA_TM_HW_IT_EOK)!=0)/*&&((isr&SVA_TM_ABORT_HW_EVENT)==0)*/) /*ALL changes to be done: SVS*/ + { + + /*update state machine*/ + if (taskCounter==0) {sva_TM_HW_UpdateState(taskId,SVA_TM_HW_BRC_ERR_EOK_CNT_ZERO);} + else {sva_TM_HW_UpdateState(taskId,SVA_TM_HW_BRC_ERR_EOK_CNT_NOT_ZERO);} + + } + + + SVA_TM_HW_UNLOCK_SEM_DEBUG(taskId); + + +} /* End of sva_TM_HW_DispatchHWEvent() function.*/ + +/****************************************************************************/ +/* NAME: sva_TM_HW_GetSubTaskPhysicalAddress( */ +/* t_sva_tm_subtask_id subtaskId */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: This function will return physical address of link structure*/ +/* of given subtask. */ +/* Generate an assert if a memory error occur. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - subtaskId : identifier of the subtask for which we have to return */ +/* physical address of its link structure. */ +/* */ +/* OUT: none */ +/* */ +/* RETURN: */ +/* t_physical_address */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: no */ +/****************************************************************************/ +PRIVATE t_physical_address sva_TM_HW_GetSubTaskPhysicalAddress( + t_sva_tm_subtask_id subtaskId +) +{ + t_sva_tm_subtask_info *pSubTaskInfo=(t_sva_tm_subtask_info *) subtaskId; + t_sva_block_id blockId; + t_physical_address linkPhysicalAddress; + t_sva_mm_error mmError; + t_sva_memory_id memId; + + /*get block id*/ + blockId=pSubTaskInfo->memBlocks.subtaskBlockId; + /*get block physical address*/ + mmError=sva_MM_GetBlockPhysicalAddress(blockId,&linkPhysicalAddress); + HCL_ASSERT(mmError==SVA_MM_OK); + /*compute link physical address*/ + linkPhysicalAddress+=sizeof(t_sva_tm_subtask_info); + /*check if it's an external mem*/ + mmError=sva_MM_GetBlockMemoryId(blockId,&memId); + HCL_ASSERT(mmError==SVA_MM_OK); + if (memId!=XRAM_ID) {linkPhysicalAddress|=MASK_BIT0;} + + return linkPhysicalAddress; +} /* End of sva_TM_HW_GetSubTaskPhysicalAddress() function.*/ + +/****************************************************************************/ +/* NAME: sva_TM_HW_GetSubTaskIdFromPhysicalAddress( */ +/* t_physical_address physicalAddress */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: This function will return subtaskId from a physical address */ +/* physical address point on link of subtask. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - physicalAddress : address from which we have to retriewe subtaskId*/ +/* */ +/* OUT: none */ +/* */ +/* RETURN: */ +/* t_sva_tm_subtask_id */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: no */ +/****************************************************************************/ +PRIVATE t_sva_tm_subtask_id sva_TM_HW_GetSubTaskIdFromPhysicalAddress( + t_physical_address physicalAddress +) +{ + t_logical_address logicalAddress; + t_sva_tm_subtask_id subtaskId; + t_sva_mm_error mmError; + + /*retriewe logical address*/ + mmError=sva_MM_PhysicalToLogicalAddress(physicalAddress,&logicalAddress); + if (mmError!=SVA_MM_OK) {return INVALID_SUBTASK_ID;} + + /*compute subtaskid*/ + subtaskId=(t_sva_tm_subtask_id) (logicalAddress-sizeof(t_sva_tm_subtask_info)); + + /*remove external bit if exist*/ + subtaskId&=~MASK_BIT0; + + return subtaskId; +} /* End of sva_TM_HW_GetSubTaskIdFromPhysicalAddress() function.*/ + +/****************************************************************************/ +/* NAME: sva_TM_HW_UpdateState( */ +/* t_sva_tm_task_id taskId, */ +/* t_sva_tm_hw_task_transition taskTransition */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: This function will update state of a task according to */ +/* require transition. */ +/* It will also be responsible do call start command of task */ +/* if necessary. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - taskId : identifier of the task for which state has to be update. */ +/* - taskTransition : transition to perform to retriewe new state. */ +/* */ +/* OUT: none */ +/* */ +/* RETURN: */ +/* void */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: no */ +/****************************************************************************/ +PRIVATE void sva_TM_HW_UpdateState( + t_sva_tm_task_id taskId, + t_sva_tm_hw_task_transition taskTransition +) +{ + t_sva_tm_hw_task_state prevState=TaskState[taskId]; + volatile t_sva_task_regs *pTasksRegs=PTaskRegs[taskId]; + + /*change state*/ + TaskState[taskId]=stateMachine[prevState][taskTransition]; + /*send command to hv if needed*/ + if (TaskState[taskId]==SVA_TM_HW_WAIT_START_ACK && prevState!=SVA_TM_HW_WAIT_START_ACK) + { + /*send start command*/ + SVA_HW_REG_W(taskId,ctl,SVA_TM_HW_CMD_START); + } + + + + if ((TaskState[taskId] == SVA_TM_HW_WAIT_ACK_RETURN_IDLE && prevState == SVA_TM_HW_IDLE) || + (TaskState[taskId] == SVA_TM_HW_WAIT_ACK_RETURN_RUNNING && prevState != SVA_TM_HW_WAIT_ACK_RETURN_RUNNING)) + { + /*send rd/wr packet command*/ + if (isPacketCmdRead == TRUE) + { + SVA_HW_REG_W(taskId,ctl,SVA_TM_HW_CMD_READ); + } + else + { + SVA_HW_REG_W(taskId,ctl,SVA_TM_HW_CMD_WRITE); + } + } +} /* End of sva_TM_HW_UpdateState() function.*/ + +/****************************************************************************/ +/* NAME: sva_TM_HW_RemoveSubtaskBelongsToSameService( */ +/* t_sva_tm_task_id taskId, */ +/* t_sva_tm_subtasklist_id subtaskListId */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: This function will remove remove from task, all the subtask */ +/* that belongs to the same service as the subtask corresponding*/ +/* to iad. */ +/* Note that this function is called whereas task is stop. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - taskId : identifier of the task for which we have to remove some */ +/* subtasks. */ +/* - subtaskListId : identifier of subtastask list for which we have */ +/* to remove subtasks that belongs to it. */ +/* */ +/* OUT: none */ +/* */ +/* RETURN: */ +/* void */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: no */ +/****************************************************************************/ +PRIVATE void sva_TM_HW_RemoveSubtaskBelongsToSameService( + t_sva_tm_task_id taskId, + t_sva_tm_subtasklist_id subtaskListId +) +{ + volatile t_sva_task_regs *pTasksRegs=PTaskRegs[taskId]; + t_uint32 taskCounter; + t_uint32 i; + t_bool isRemoveFinish=FALSE; + t_bool isFindSubtaskToRemove=FALSE; + + t_bool flag = FALSE; + + + /*remove all subtask from physical list that belongs to logical one*/ + + while(isRemoveFinish==FALSE) + { + isFindSubtaskToRemove=FALSE; + /*read task counter value*/ + taskCounter=pTasksRegs->genTask.cnt; + /*try to remove one subtask*/ + if (taskCounter==0) {isRemoveFinish=TRUE;} + else + { + t_sva_tm_subtask_info *pCurrentSubtaskInfo; + + /*init pCurrentSubtaskInfo*/ + pCurrentSubtaskInfo=(t_sva_tm_subtask_info *) sva_TM_HW_GetSubTaskIdFromPhysicalAddress((t_physical_address) pTasksRegs->genTask.nad); + + if (flag == FALSE) /* for first time only */ + { + if (pCurrentSubtaskInfo->pPreviousInfo!=NULL) + { + t_sva_tm_subtask_info *pCurrentSubtaskInfo_iterator = pCurrentSubtaskInfo; + + while(1) + { + /* look for next and first non-matching subtasklist */ + if (pCurrentSubtaskInfo_iterator == NULL) break; + if (pCurrentSubtaskInfo_iterator->subtaskListId==subtaskListId) + { + volatile t_sva_subtask_link *pSubtaskLinkNAD; + pSubtaskLinkNAD=(t_sva_subtask_link *)&PTaskRegs[taskId]->genTask.nad; + + *pSubtaskLinkNAD = *((t_sva_subtask_link *)(((t_uint32)pCurrentSubtaskInfo_iterator)+sizeof(t_sva_tm_subtask_info))); + } + else break; + + pCurrentSubtaskInfo_iterator=pCurrentSubtaskInfo_iterator->pNextInfo; + } + } + flag = TRUE; + } + + /*search for a subtask that belongs to subtaskListId*/ + for(i=0;isubtaskListId==subtaskListId) + { + /*remove subtask from list*/ + sva_TM_HW_RemoveSubtask((t_sva_tm_subtask_id) pCurrentSubtaskInfo); + /*decrement task counter*/ + pTasksRegs->genTask.cnt--; + pCurrentSubtaskInfo=pCurrentSubtaskInfo->pNextInfo; + } + else + { + /*update pCurrentSubtaskInfo*/ + pCurrentSubtaskInfo=pCurrentSubtaskInfo->pNextInfo; + } + } + /*check if there are others subtask to try to remove*/ + if (i==taskCounter && isFindSubtaskToRemove==FALSE) {isRemoveFinish=TRUE;} + } + } +} /* End of sva_TM_HW_RemoveSubtaskBelongsToSameService() function.*/ + +/****************************************************************************/ +/* NAME: sva_TM_HW_RemoveSubtaskBelongsToSameServiceAbort( */ +/* t_sva_tm_task_id taskId, */ +/* t_sva_tm_subtasklist_id subtaskListId */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: This function will remove remove from task, all the subtask */ +/* that belongs to the same service as the subtask corresponding*/ +/* to iad. */ +/* Note that this function is called whereas task is stop. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - taskId : identifier of the task for which we have to remove some */ +/* subtasks. */ +/* - subtaskListId : identifier of subtastask list for which we have */ +/* to remove subtasks that belongs to it. */ +/* - iad */ +/* */ +/* OUT: none */ +/* */ +/* RETURN: */ +/* void */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: no */ +/****************************************************************************/ +PRIVATE void sva_TM_HW_RemoveSubtaskBelongsToSameServiceAbort( + t_sva_tm_task_id taskId, + t_sva_tm_subtasklist_id subtaskListId +) +{ + volatile t_sva_task_regs *pTasksRegs=PTaskRegs[taskId]; + t_bool isRemoveFinish=FALSE; + + t_bool flag = FALSE; + + //pTasksRegs->genTask.nad + /*remove all subtask from physical list that belongs to logical one*/ + + while(isRemoveFinish==FALSE) + { + /*try to remove one subtask*/ + t_sva_tm_subtask_info *pCurrentSubtaskInfo; + + if (pTasksRegs->genTask.nad == 0) + { + return; + } + /*init pCurrentSubtaskInfo*/ + //pCurrentSubtaskInfo=(t_sva_tm_subtask_info *) sva_TM_HW_GetSubTaskIdFromPhysicalAddress((t_physical_address)iad); + pCurrentSubtaskInfo=(t_sva_tm_subtask_info *) sva_TM_HW_GetSubTaskIdFromPhysicalAddress((t_physical_address) pTasksRegs->genTask.nad); + + if (flag == FALSE) /* for first time only */ + { + if (pCurrentSubtaskInfo->pPreviousInfo!=NULL) + { + t_sva_tm_subtask_info *pCurrentSubtaskInfo_iterator = pCurrentSubtaskInfo; + + while(1) + { + /* look for next and first non-matching subtasklist */ + if (pCurrentSubtaskInfo_iterator == NULL) break; + if (pCurrentSubtaskInfo_iterator->subtaskListId==subtaskListId) + { + volatile t_sva_subtask_link *pSubtaskLinkNAD; + pSubtaskLinkNAD=(t_sva_subtask_link *)&PTaskRegs[taskId]->genTask.nad; + + *pSubtaskLinkNAD = *((t_sva_subtask_link *)(((t_uint32)pCurrentSubtaskInfo_iterator)+sizeof(t_sva_tm_subtask_info))); + } + else break; + + pCurrentSubtaskInfo_iterator=pCurrentSubtaskInfo_iterator->pNextInfo; + } + } + flag = TRUE; + } + + /*search for a subtask that belongs to subtaskListId*/ + while(1) + { + /*check for current info*/ + if (pCurrentSubtaskInfo->subtaskListId==subtaskListId) + { + /*remove subtask from list*/ + sva_TM_HW_RemoveSubtask((t_sva_tm_subtask_id) pCurrentSubtaskInfo); + pCurrentSubtaskInfo=pCurrentSubtaskInfo->pNextInfo; + } + else + { + /*update pCurrentSubtaskInfo*/ + pCurrentSubtaskInfo=pCurrentSubtaskInfo->pNextInfo; + } + + if (pCurrentSubtaskInfo==NULL) + { + isRemoveFinish=TRUE; + break; + } + } + } +} /* End of sva_TM_HW_RemoveSubtaskBelongsToSameServiceAbort() function.*/ + +/****************************************************************************/ +/* NAME: sva_TM_HW_RemoveSubtask( */ +/* t_sva_tm_subtask_id subtaskId */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: This function will remove subtask from lists. */ +/* Note that task must be stop before calling this function. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - subtaskId : identifier of the subtask to remove from lists */ +/* */ +/* OUT: none */ +/* */ +/* RETURN: */ +/* void */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: no */ +/****************************************************************************/ +PRIVATE void sva_TM_HW_RemoveSubtask( + t_sva_tm_subtask_id subtaskId +) +{ + t_sva_tm_subtask_info *pSubtaskInfo=(t_sva_tm_subtask_info *) subtaskId; + t_sva_tm_task_id taskId=pSubtaskInfo->taskId; + t_sva_subtask_link *pSubtaskLink=(t_sva_subtask_link *) (subtaskId+sizeof(t_sva_tm_subtask_info)); + volatile t_sva_subtask_link *pPrevSubtaskLink; + + /*change link structure value*/ + if (pSubtaskInfo->pPreviousInfo==NULL) + { + pPrevSubtaskLink=(t_sva_subtask_link *)&PTaskRegs[taskId]->genTask.nad; + } + else + { + pPrevSubtaskLink=(t_sva_subtask_link *)((t_uint32)pSubtaskInfo->pPreviousInfo+sizeof(t_sva_tm_subtask_info)); + } + *pPrevSubtaskLink=*pSubtaskLink; + + /*change cached link structure*/ + if (pSubtaskInfo->pPreviousInfo!=NULL) + { + pSubtaskInfo->pPreviousInfo->pNextInfo=pSubtaskInfo->pNextInfo; + } + if (pSubtaskInfo->pNextInfo!=NULL) + { + pSubtaskInfo->pNextInfo->pPreviousInfo=pSubtaskInfo->pPreviousInfo; + } +} /* End of sva_TM_HW_RemoveSubtask() function.*/ + + +/****************************************************************************/ +/* NAME: sva_TM_HW_SendTaskCommand( */ +/* t_sva_tm_subtask_id subtaskId, */ +/* t_sva_tm_task_cmd_id command, */ +/* t_uint32 param */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: This function will send a physical command to the HAMAC. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - taskId : identifier of the task for which state has to be update. */ +/* - command : command to be performed. */ +/* - param : parameter whose meaning depends on command. */ +/* */ +/* OUT: none */ +/* */ +/* RETURN: */ +/* t_sva_tm_error */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: no */ +/****************************************************************************/ +PUBLIC t_sva_tm_error sva_TM_HW_SendTaskCommand( + t_sva_tm_task_id taskId, + t_sva_tm_task_cmd_id command, + t_uint32 param +) +{ + volatile t_sva_task_regs *pTasksRegs=PTaskRegs[taskId]; + + /*send appropriate command*/ + if(command == SVA_TM_TCMD_STOP_SLICE) + { + SVA_HW_REG_W(taskId,ctl,SVA_TM_HW_CMD_STOP_SLICE); + } + else if(command == SVA_TM_TCMD_UPDATE_BUFFER) + { + SVA_HW_REG_W(taskId,ctl,SVA_TM_HW_CMD_UPDATE_BITSTREAM_BUFFER); + } + else if (command == SVA_TM_TCMD_STOP_PHYSICAL) + { + SVA_HW_REG_W(taskId,ctl,SVA_TM_HW_CMD_STOP); + } + else if (command == SVA_TM_TCMD_READ_PACKET) + { + //Reset the error register. New eWarp FW boot sets junk value. + //SVA_HW_WRITE_IRP(pSVAReg->cfg.cfg_irp_error,0); + SVA_HW_WRITE_IRP(pSVAReg->cfg.cfg_irp_bs,param); + SVA_HW_WRITE_IRP(pSVAReg->cfg.cfg_irp_ptr,param); + SVA_HW_WRITE_IRP(pSVAReg->cfg.cfg_irp_be,param + 16); + isPacketCmdRead = TRUE; + sva_TM_HW_UpdateState(taskId,SVA_TM_HW_RD_WR_PACKET); + } + else if (command == SVA_TM_TCMD_WRITE_PACKET) + { + //SVA_HW_WRITE_IRP(pSVAReg->cfg.cfg_irp_error,0); + SVA_HW_WRITE_IRP(pSVAReg->cfg.cfg_irp_bs,param); + SVA_HW_WRITE_IRP(pSVAReg->cfg.cfg_irp_ptr,param); + SVA_HW_WRITE_IRP(pSVAReg->cfg.cfg_irp_be,param + 16); + isPacketCmdRead = FALSE; + sva_TM_HW_UpdateState(taskId,SVA_TM_HW_RD_WR_PACKET); + } + else if (command == SVA_TM_TCMD_SAVE_VPIP_STATE) + { + t_uint32 loop_counter = SVA_IRP_SAVE_TIMEOUT; + t_uint32 grb_isr_read_val = 0; + SVA_DisableIRQSrc(SVA_IRQ); + sva_TM_HW_EnableTaskInterrupt(SVA_TM_GRAB,SVA_TM_HW_IT_5); + sva_TM_HW_LockSemaphore(taskId); + SVA_HW_REG_W(taskId,ctl,SVA_TM_HW_CMD_VPIP_SAVE_STATUS); + sva_TM_HW_UnlockSemaphore(taskId); + do + { + if (!(loop_counter%SVA_CHECK_INTERVAL)) + { + grb_isr_read_val = SVA_HW_REG_R(taskId,isr); + } + loop_counter--; + } while ((loop_counter > 0) && !(grb_isr_read_val & SVA_TM_HW_IT_5)); + + if (loop_counter == 0) + { + return SVA_TM_TIME_OUT_ERROR; + } +// while(((SVA_HW_REG_R(taskId,isr))&0x20)!=0x20); +// SVA_HW_REG_W(taskId,isr,0x20); + grb_isr_read_val = SVA_HW_REG_R(taskId,isr); + /* Acknowledge all the interrupt raised for GrabTask */ + SVA_HW_REG_W(taskId, isr, grb_isr_read_val); + SVA_EnableIRQSrc(SVA_IRQ); + } + else if (command == SVA_TM_TCMD_LOAD_VPIP_STATE) + { + t_uint32 loop_counter = SVA_IRP_SAVE_TIMEOUT; + t_uint32 grb_isr_read_val = 0; + SVA_DisableIRQSrc(SVA_IRQ); + sva_TM_HW_EnableTaskInterrupt(SVA_TM_GRAB,SVA_TM_HW_IT_5); + sva_TM_HW_LockSemaphore(taskId); + SVA_HW_REG_W(taskId,ctl,SVA_TM_HW_CMD_VPIP_LOAD_STATUS); + sva_TM_HW_UnlockSemaphore(taskId); + do + { + if (!(loop_counter%SVA_CHECK_INTERVAL)) + { + grb_isr_read_val = SVA_HW_REG_R(taskId,isr); + } + loop_counter--; + } while ((loop_counter > 0) && !(grb_isr_read_val & SVA_TM_HW_IT_5)); + + if (loop_counter == 0) + { + return SVA_TM_TIME_OUT_ERROR; + } +// while(((SVA_HW_REG_R(taskId,isr))&0x20)!=0x20); +// SVA_HW_REG_W(taskId,isr,0x20); + grb_isr_read_val = SVA_HW_REG_R(taskId,isr); + /* Acknowledge all the interrupt raised for GrabTask */ + SVA_HW_REG_W(taskId, isr, grb_isr_read_val); + SVA_EnableIRQSrc(SVA_IRQ); + } + else if (command == SVA_TM_TCMD_ABORT) + { + SVA_HW_REG_W(taskId,ctl,SVA_TM_HW_CMD_ABORT); + sva_TM_HW_UpdateState(taskId,SVA_TM_HW_ABORT); /*@BORT_$TOP*/ //!@# + } + else if (command == SVA_TM_TCMD_START) + { + SVA_HW_REG_W(taskId,ctl,SVA_TM_HW_CMD_START); + } + else if (command == SVA_TM_TCMD_GRABHQ_STATUS) + { + t_sva_gb_hq_status *statusHQ = (t_sva_gb_hq_status *)param; + t_uint16 cfgIrpGrabhqStatusVal; + t_uint16 cfgIrpGrabhqStatusMask=(t_uint16)0x0007; + t_uint16 cfgIrpGrabhqMask=(t_uint16)0x000F; + //t_uint16 cfgIrpGrabhqTstMask=(t_uint16)0x0008; + + cfgIrpGrabhqStatusVal = SVA_HW_READ_IRP(pSVAReg->cfg.cfg_irp_grabhq_status) & cfgIrpGrabhqMask; + + statusHQ->grabHqSubtaskStatus = (t_sva_grab_hq_subtask_status) (cfgIrpGrabhqStatusVal & cfgIrpGrabhqStatusMask); + + /* Read other status registers if TST mode enabled else return zero */ +// if((cfgIrpGrabhqStatusVal & cfgIrpGrabhqTstMask) == cfgIrpGrabhqTstMask) /* TST Mode enabled */ +// { + statusHQ->cfgIrpGrabhqGridcastL = (t_uint16) SVA_HW_READ_IRP(pSVAReg->cfg.cfg_irp_grabhq_gridcast_l); + statusHQ->cfgIrpGrabhqGridcastH = (t_uint16) SVA_HW_READ_IRP(pSVAReg->cfg.cfg_irp_grabhq_gridcast_h); + statusHQ->cfgIrpGrabhqGridG1 = (t_uint16) SVA_HW_READ_IRP(pSVAReg->cfg.cfg_irp_grabhq_grid_g1); + statusHQ->cfgIrpGrabhqGridG2 = (t_uint16) SVA_HW_READ_IRP(pSVAReg->cfg.cfg_irp_grabhq_grid_g2); + statusHQ->cfgIrpGrabhqGridR = (t_uint16) SVA_HW_READ_IRP(pSVAReg->cfg.cfg_irp_grabhq_grid_r); + statusHQ->cfgIrpGrabhqGridB = (t_uint16) SVA_HW_READ_IRP(pSVAReg->cfg.cfg_irp_grabhq_grid_b); +// } +// else +// { +// statusHQ->cfgIrpGrabhqGridcastL = 0; +// statusHQ->cfgIrpGrabhqGridcastH = 0; +// statusHQ->cfgIrpGrabhqGridG1 = 0; +// statusHQ->cfgIrpGrabhqGridG2 = 0; +// statusHQ->cfgIrpGrabhqGridR = 0; +// statusHQ->cfgIrpGrabhqGridB = 0; +// } + } + else if (command == SVA_TM_TCMD_GRABHQ_TST) + { + t_sva_gb_hq_status *statusHQ = (t_sva_gb_hq_status *)param; + t_uint16 cfgIrpGrabhqStatusVal; + t_uint16 cfgIrpGrabhqTstBitMask=(t_uint16)0x08; + t_uint16 cfgIrpGrabhqMask=(t_uint16)0x000F; + + cfgIrpGrabhqStatusVal = SVA_HW_READ_IRP(pSVAReg->cfg.cfg_irp_grabhq_status) & cfgIrpGrabhqMask; + if(statusHQ->isGrabHqTestModeEnabled == TRUE) + { + SVA_HW_WRITE_IRP(pSVAReg->cfg.cfg_irp_grabhq_status,(t_uint16)(cfgIrpGrabhqStatusVal | cfgIrpGrabhqTstBitMask)); + } + else + { + SVA_HW_WRITE_IRP(pSVAReg->cfg.cfg_irp_grabhq_status,(t_uint16)(cfgIrpGrabhqStatusVal & ((t_uint16)~(cfgIrpGrabhqTstBitMask)))); + } + } + else if (command == SVA_TM_TCMD_GRABHQ_READ_NB_FAILURE_BML_PROCESS) + { + t_uint32 *bmlRetryStatus = (t_uint32 *)param; + t_uint16 cfgIrpGrabhqStatusVal; + t_uint16 cfgIrpGrabhqStatusMask=(t_uint16)0x00F0; + + /* Read whole 16bit value */ + cfgIrpGrabhqStatusVal = SVA_HW_READ_IRP(pSVAReg->cfg.cfg_irp_grabhq_status); + + *bmlRetryStatus = (t_uint32)((cfgIrpGrabhqStatusVal & cfgIrpGrabhqStatusMask)>>4); + } + else + { + return SVA_TM_BAD_FUNCTION_PARAMETER; + } + + return SVA_TM_OK; +} /* End of sva_TM_HW_SendTaskCommand() function.*/ + + +/****************************************************************************/ +/* NAME: SVA_ResetTaskDurationInfo() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: This routine resets the task duration counter for */ +/* video encoder,video decoder,grab and display */ +/* PARAMETERS: */ +/* IN : none */ +/* OUT :none */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/* - SVA_OK */ +/****************************************************************************/ +PUBLIC t_sva_error SVA_ResetTaskDurationInfo(void) +{ + volatile t_sva_task_regs *pTasksRegs; + + pTasksRegs=PTaskRegs[ENCODE_TID]; + sva_TM_HW_LockSemaphore(SVA_TM_ENCODE); + pTasksRegs->vecTask.dur = 0; + sva_TM_HW_UnlockSemaphore(SVA_TM_ENCODE); + + + pTasksRegs=PTaskRegs[DECODE_TID]; + sva_TM_HW_LockSemaphore(SVA_TM_DECODE); + pTasksRegs->vdcTask.dur = 0; + sva_TM_HW_UnlockSemaphore(SVA_TM_DECODE); + + pTasksRegs=PTaskRegs[GRAB_TID]; + sva_TM_HW_LockSemaphore(SVA_TM_GRAB); + pTasksRegs->grbTask.dur = 0; + sva_TM_HW_UnlockSemaphore(SVA_TM_GRAB); + + pTasksRegs=PTaskRegs[DISPLAY_TID]; + sva_TM_HW_LockSemaphore(SVA_TM_DISPLAY); + pTasksRegs->dspTask.dur = 0; + sva_TM_HW_UnlockSemaphore(SVA_TM_DISPLAY); + + return SVA_OK; + +} + + +/****************************************************************************/ +/* NAME: SVA_GetTaskDurationInfo() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: This routine gets the accumalted values from the task */ +/* duration register for video encoder,video decoder,grab and display */ +/* PARAMETERS: */ +/* IN :none */ +/* OUT :t_sva_duration *pDuration :Contains accumalted values */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/* - SVA_OK */ +/****************************************************************************/ +PUBLIC t_sva_error SVA_GetTaskDurationInfo(t_sva_duration *pDuration) +{ + volatile t_sva_task_regs *pTasksRegs; + + pTasksRegs=PTaskRegs[ENCODE_TID]; + sva_TM_HW_LockSemaphore(SVA_TM_ENCODE); + pDuration->vec_dur = pTasksRegs->vecTask.dur; + sva_TM_HW_UnlockSemaphore(SVA_TM_ENCODE); + + pTasksRegs=PTaskRegs[DECODE_TID]; + sva_TM_HW_LockSemaphore(SVA_TM_DECODE); + pDuration->vdc_dur = pTasksRegs->vdcTask.dur; + sva_TM_HW_UnlockSemaphore(SVA_TM_DECODE); + + pTasksRegs=PTaskRegs[GRAB_TID]; + sva_TM_HW_LockSemaphore(SVA_TM_GRAB); + pDuration->grb_dur = pTasksRegs->grbTask.dur; + sva_TM_HW_UnlockSemaphore(SVA_TM_GRAB); + + pTasksRegs=PTaskRegs[DISPLAY_TID]; + sva_TM_HW_LockSemaphore(SVA_TM_DISPLAY); + pDuration->dpl_dur = pTasksRegs->dspTask.dur; + sva_TM_HW_UnlockSemaphore(SVA_TM_DISPLAY); + + return SVA_OK; + +} + +/****************************************************************************/ +/* NAME: sva_BooteWarp() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: This routine sends boot command to eWarp */ +/* PARAMETERS: */ +/* IN :none */ +/* OUT :none */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/* - SVA_OK */ +/****************************************************************************/ +PUBLIC t_sva_error sva_BooteWarp(void) +{ + volatile t_sva_task_regs *pTasksRegs; + + pTasksRegs=PTaskRegs[GRAB_TID]; + sva_TM_HW_LockSemaphore(SVA_TM_GRAB); + SVA_HW_REG_W(GRAB_TID,ctl,SVA_TM_HW_CMD_BOOT); + sva_TM_HW_UnlockSemaphore(SVA_TM_GRAB); + + return SVA_OK; + +} + +/****************************************************************************/ +/* NAME: sva_BooteWarpStatus() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: This routine reads the status of eWarp boot */ +/* PARAMETERS: */ +/* IN :none */ +/* OUT :none */ +/* */ +/* RETURN: */ +/* t_bool */ +/* - TRUE when boot succesful */ +/* - FALSE on error */ +/****************************************************************************/ +PUBLIC t_bool sva_BooteWarpStatus(void) +{ + volatile t_sva_task_regs *pTasksRegs; + t_bool status; + + pTasksRegs=PTaskRegs[GRAB_TID]; + if( (SVA_HW_REG_R(GRAB_TID,isr)&0x20) == 0x20) + status = TRUE; + else + status = FALSE; + /*Reset the interrupt*/ + SVA_HW_WRITE_IRP(pSVAReg->cfg.cfg_irp_error,0); + SVA_HW_REG_W(GRAB_TID,isr,0x20); + + return status; + +} + + + +// End of file - sva_hwtaskmgt.c --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/tasks_management/sva_hwtaskmgt.h @@ -0,0 +1,93 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ + +#ifndef __INC_SVA_HW_TASKMGT_H +#define __INC_SVA_HW_TASKMGT_H + +#include "hcl_defs.h" +#include "sva_hwtaskmgt.h" + +//#include "sva_memorymgt.h" +//#include "sva_fwmgt.h" +//#include "sva_host_interface.h" +//#include "svap.h" +//#include "sva.h" +//#include "sva_hwp.h" +//#include "sva_timemgt.h" + +/******************************************************************************/ +/* Constants definitions */ +/******************************************************************************/ + +/*------------------------------------------------------------------------ + * Defines + *----------------------------------------------------------------------*/ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/******************************************************************************/ +/* Types definitions */ +/******************************************************************************/ +typedef enum { + SVA_TM_HW_IT_0 = MASK_BIT0, + SVA_TM_HW_IT_1 = MASK_BIT1, + SVA_TM_HW_IT_2 = MASK_BIT2, + SVA_TM_HW_IT_3 = MASK_BIT3, + SVA_TM_HW_IT_4 = MASK_BIT4, + SVA_TM_HW_IT_5 = MASK_BIT5, + SVA_TM_HW_IT_6 = MASK_BIT6, + SVA_TM_HW_IT_7 = MASK_BIT7 +} t_sva_tm_hw_event_id; + +/******************************************************************************* +* PUBLIC Functions +*******************************************************************************/ + +/* Harware Init */ +PUBLIC t_sva_tm_error sva_TM_HW_Init(t_logical_address, t_logical_address); +PUBLIC t_sva_tm_error sva_TM_HW_Reset(void); + +/* Hardware Task management */ +PUBLIC t_sva_tm_error sva_TM_HW_InsertImmediat(t_sva_tm_subtask_id); +PUBLIC t_sva_tm_error sva_TM_HW_InsertTimed(t_sva_tm_subtask_id, t_sva_ticks); +PUBLIC t_sva_tm_error sva_TM_HW_GenerateFake(t_sva_tm_task_id); + +PUBLIC t_uint32 sva_TM_HW_RetriveIAD(t_sva_tm_task_id,t_uint32 ); + +/* It dispatcher for hardware task management*/ +PUBLIC void sva_TM_HW_DispatchHWEvent(t_sva_tm_task_id, t_uint32, + t_uint32, t_uint32); + +/* Hardware ressources management */ +PUBLIC t_sva_tm_error sva_TM_HW_LockSemaphore(t_sva_tm_task_id); +PUBLIC t_sva_tm_error sva_TM_HW_UnlockSemaphore(t_sva_tm_task_id); +PUBLIC t_sva_tm_error sva_TM_HW_EnableTaskInterrupt(t_sva_tm_task_id, t_sva_tm_hw_event_id); +PUBLIC t_sva_tm_error sva_TM_HW_DisableTaskInterrupt(t_sva_tm_task_id, t_sva_tm_hw_event_id); +PUBLIC t_sva_tm_error sva_TM_HW_SendTaskCommand( t_sva_tm_task_id, t_sva_tm_task_cmd_id, t_uint32); +PUBLIC t_sva_error sva_BooteWarp(void); +PUBLIC t_bool sva_BooteWarpStatus(void); + +#ifdef __cplusplus +} /* allow C++ to use these headers */ +#endif /* __cplusplus */ + +#endif /* __INC_SVA_HW_TASKMGT_H */ +/* End of file - sva_hwtaskmgt.h */ --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/tasks_management/sva_hwtaskmgtp.h @@ -0,0 +1,134 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ + +#ifndef __INC_SVA_HW_TASKMGTP_H +#define __INC_SVA_HW_TASKMGTP_H + +#include "hcl_defs.h" +#include "sva_taskmgt.h" + +/******************************************************************************/ +/* Constants definitions */ +/******************************************************************************/ + + +/*------------------------------------------------------------------------ + * Defines + *----------------------------------------------------------------------*/ +#ifdef __DEBUG + /* + * Define number of event to log + */ + #define LOG_DEPTH 16 +#endif +/*define if semaphore must be taken even in part it must not*/ +#define SVA_TM_HW_SEM_PARANOID 1 + +/*define the number of task supported*/ +#define SVA_TM_HW_TASK_NB 5 + +/*define loop forever for subtask*/ +#define SVA_TM_HW_LOOP_FOREVER 0xff; + +/*define interrupt mask*/ + +#define SVA_TM_HW_IT_EOT MASK_BIT1 +#define SVA_TM_HW_IT_ACK MASK_BIT2 +#define SVA_TM_HW_IT_BRC MASK_BIT5 +#define SVA_TM_HW_IT_ERR MASK_BIT6 +#define SVA_TM_HW_IT_EOK MASK_BIT7 + + +/******************************************************************************/ +/* Types definitions */ +/******************************************************************************/ +/* + * Define the various command upported by tasks + */ +typedef enum { + SVA_TM_HW_CMD_STOP =0, + SVA_TM_HW_CMD_START =1, + SVA_TM_HW_CMD_ABORT =2, + SVA_TM_HW_CMD_UPDATE_BITSTREAM_WINDOW =3, + SVA_TM_HW_CMD_UPDATE_BITSTREAM_BUFFER =4, + SVA_TM_HW_CMD_CLEAR_DEPENCIES =5, + SVA_TM_HW_CMD_STOP_SLICE =6, + SVA_TM_HW_CMD_READ =8, + SVA_TM_HW_CMD_WRITE =9, + SVA_TM_HW_CMD_VPIP_SAVE_STATUS =0xA, + SVA_TM_HW_CMD_VPIP_LOAD_STATUS =0xB, + SVA_TM_HW_CMD_BOOT =0XC +} t_sva_tm_hw_task_cmd_id; + +/* + * Define the various state of a task + */ +typedef enum { + SVA_TM_HW_IDLE, + SVA_TM_HW_WAIT_START_ACK, + SVA_TM_HW_RUNNING, + SVA_TM_HW_WAIT_ACK_RETURN_IDLE, + SVA_TM_HW_WAIT_ACK_RETURN_WAIT_START_ACK, + SVA_TM_HW_WAIT_START_ACK_CMD_PACKET, + SVA_TM_HW_WAIT_ACK_RETURN_RUNNING, + SVA_TM_HW_ABORTING, + SVA_TM_HW_LAST_DUMMY_STATE, + SVA_TM_HW_TRANSITION_REJECTED +} t_sva_tm_hw_task_state; + +/* + * Define the various transition of a task state machine + */ +typedef enum { + SVA_TM_HW_SUBTASK_INSERT, + SVA_TM_HW_FAKE, + SVA_TM_HW_ACK, + SVA_TM_HW_BRC_ERR_EOK_CNT_NOT_ZERO, + SVA_TM_HW_BRC_ERR_EOK_CNT_ZERO, + SVA_TM_HW_ABORT, + SVA_TM_HW_ABORT_EOK, + SVA_TM_HW_RD_WR_PACKET, + SVA_TM_HW_LAST_DUMMY_TRANSITION +} t_sva_tm_hw_task_transition; + + +#ifdef __DEBUG + /******************************************************************************/ + /* Trace Types definitions */ + /******************************************************************************/ + typedef struct { + t_uint32 iad; + t_uint32 isr; + t_uint32 its; + t_uint32 taskCounter; + } t_sva_tm_hw_debug_desc; + typedef struct { + t_uint32 padding[3]; + t_uint32 nbOfItReceived; + t_sva_tm_hw_debug_desc debugDesc[LOG_DEPTH]; + } t_sva_tm_hw_debug; + +#endif + +#ifdef __cplusplus +} /* allow C++ to use these headers */ +#endif /* __cplusplus */ + +#endif /* __INC_SVA_HW_TASKMGTP_H */ +/* End of file - sva_hwtaskmgtp.h */ --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/tasks_management/sva_taskmgt.c @@ -0,0 +1,3573 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ + +/*------------------------------------------------------------------------ + * Includes + *----------------------------------------------------------------------*/ + +#include "hcl_defs.h" +#include "sva_hwp.h" +#include "sva_host_interface.h" +#include "sva_memorymgt.h" +#include "sva_taskmgt.h" +#include "sva_taskmgtp.h" +#include "sva_hwtaskmgt.h" +#include "sva_timemgt.h" +#include "sva_hwtaskmgtp.h" + +#ifdef __TRACE_TM +#include "debug.h" +#endif /* DEBUG == 1 */ + +extern t_uint32 Last_IAD_EOT_ERR[5]; +extern t_uint32 Last_IAD_ERR[5]; +extern t_sva_tm_hw_task_state TaskState[SVA_TM_HW_TASK_NB]; + +/*------------------------------------------------------------------------ + * Global Variables + *----------------------------------------------------------------------*/ +#ifdef __DEBUG /* ... debug informations ... */ +ALIGN(32) PRIVATE t_sva_tm_debug_hw_events evtTMHwDebugTable[SVA_TM_NB_HW_TASK]; +ALIGN(32) PRIVATE t_sva_tm_debug_virtual_events evtTMVirtualDebugTable[SVA_TM_NB_HW_TASK]; +ALIGN(32) PRIVATE t_sva_tm_debug_transitions transitionTMDebugTable[SVA_TM_NB_HW_TASK]; +ALIGN(32) PRIVATE t_sva_tm_debug_schedule scheduleTMDebugTable[SVA_TM_NB_HW_TASK]; +#endif + + + +PRIVATE t_sva_tm_global_info GlobalInfos; +PUBLIC t_sva_tm_global_tasks_info HwTasksInfos[SVA_TM_NB_HW_TASK]; +PRIVATE t_sva_tm_subtask_list_info ListInfo[SVA_TM_NB_HW_TASK][SVA_TM_TOTAL_SRV_PER_HW_TASK]; + +typedef struct{ + t_sva_tm_list_state state; + t_sva_tm_virtual_hw_event_id mask; +}t_sva_tm_stateTransition_elem; + +typedef struct{ + t_sva_tm_list_activation_state state; + t_sva_tm_virtual_hw_event_id mask; +}t_sva_tm_activateTransition_elem; + +/*@ABORT-$TOP*/ //CHANGE THE STATEMACHINE ACCORDING TO EVENT +PRIVATE const t_sva_tm_stateTransition_elem StateMachine[SVA_TM_LAST_LIST_DUMMY_STATE][SVA_TM_LAST_LIST_DUMMY_TRANSITION]= { + { + /* Current state : SVA_TM_IDLE */ + {SVA_TM_RUNNING , SVA_TM_NO_HW_EVENT}, /* SVA_TM_COMMAND_START */ + {SVA_TM_TRANSITION_REJECTED , SVA_TM_NO_HW_EVENT}, /* SVA_TM_COMMAND_STOP_LIST_EMPTY */ + {SVA_TM_TRANSITION_REJECTED , SVA_TM_NO_HW_EVENT}, /* SVA_TM_COMMAND_STOP_LIST_NOT_EMPTY */ + {SVA_TM_TRANSITION_REJECTED , SVA_TM_NO_HW_EVENT}, /* SVA_TM_COMMAND_ABORT */ + {SVA_TM_FAKING , SVA_TM_NO_HW_EVENT}, /* SVA_TM_COMMAND_FAKE */ + {SVA_TM_IDLE , SVA_TM_NO_HW_EVENT}, /* SVA_TM_COMMAND_ACTIVATE */ + {SVA_TM_IDLE , SVA_TM_NO_HW_EVENT}, /* SVA_TM_COMMAND_ACTIVATE_DELAYED */ + {SVA_TM_IDLE , SVA_TM_NO_HW_EVENT}, /* SVA_TM_COMMAND_INACTIVATE */ + {SVA_TM_IDLE , SVA_TM_NO_HW_EVENT}, /* SVA_TM_DUMMY_INTERRUPT */ + {SVA_TM_TRANSITION_REJECTED , SVA_TM_NO_HW_EVENT}, /* SVA_TM_ACK_INTERRUPT */ + {SVA_TM_TRANSITION_REJECTED , SVA_TM_NO_HW_EVENT}, /* SVA_TM_BOT_INTERRUPT */ + {SVA_TM_TRANSITION_REJECTED , SVA_TM_NO_HW_EVENT}, /* SVA_TM_EOT_INTERRUPT */ + {SVA_TM_TRANSITION_REJECTED , SVA_TM_NO_HW_EVENT}, /* SVA_TM_LAST_EOT_INTERRUPT */ + {SVA_TM_TRANSITION_REJECTED , SVA_TM_NO_HW_EVENT}, /* SVA_TM_ERR_INTERRUPT */ + {SVA_TM_TRANSITION_REJECTED , SVA_TM_NO_HW_EVENT}, /* SVA_TM_BRC_INTERRUPT */ + {SVA_TM_IDLE , SVA_TM_NO_HW_EVENT}, /* SVA_TM_EOI_INTERRUPT */ + {SVA_TM_IDLE , SVA_TM_NO_HW_EVENT}, /* SVA_TM_FAK_INTERRUPT */ + {SVA_TM_TRANSITION_REJECTED , SVA_TM_NO_HW_EVENT} /* SVA_TM_ABORT_INTERRUPT */ + }, + { + /* Current state : SVA_TM_RUNNING */ + {SVA_TM_TRANSITION_REJECTED , SVA_TM_NO_HW_EVENT}, /* SVA_TM_COMMAND_START */ + {SVA_TM_STOPPING_BY_FAKE , SVA_TM_NO_HW_EVENT}, /* SVA_TM_COMMAND_STOP_LIST_EMPTY */ + {SVA_TM_STOPPING , SVA_TM_NO_HW_EVENT}, /* SVA_TM_COMMAND_STOP_LIST_NOT_EMPTY */ + {SVA_TM_ABORTING , SVA_TM_NO_HW_EVENT}, /* SVA_TM_COMMAND_ABORT *///not sure + {SVA_TM_TRANSITION_REJECTED , SVA_TM_NO_HW_EVENT}, /* SVA_TM_COMMAND_FAKE */ + {SVA_TM_RUNNING , SVA_TM_NO_HW_EVENT}, /* SVA_TM_COMMAND_ACTIVATE */ + {SVA_TM_RUNNING , SVA_TM_NO_HW_EVENT}, /* SVA_TM_COMMAND_ACTIVATE_DELAYED */ + {SVA_TM_RUNNING , SVA_TM_NO_HW_EVENT}, /* SVA_TM_COMMAND_INACTIVATE */ + {SVA_TM_RUNNING , SVA_TM_NO_HW_EVENT}, /* SVA_TM_DUMMY_INTERRUPT */ + {SVA_TM_TRANSITION_REJECTED , SVA_TM_NO_HW_EVENT}, /* SVA_TM_ACK_INTERRUPT */ + {SVA_TM_RUNNING , SVA_TM_NO_HW_EVENT}, /* SVA_TM_BOT_INTERRUPT */ + {SVA_TM_RUNNING , SVA_TM_NO_HW_EVENT}, /* SVA_TM_EOT_INTERRUPT */ + {SVA_TM_RUNNING , SVA_TM_EOK_HW_EVENT}, /* SVA_TM_LAST_EOT_INTERRUPT */ + {SVA_TM_IDLE , SVA_TM_EOK_HW_EVENT}, /* SVA_TM_ERR_INTERRUPT */ + {SVA_TM_RUNNING , SVA_TM_NO_HW_EVENT}, /* SVA_TM_BRC_INTERRUPT */ + {SVA_TM_TRANSITION_REJECTED , SVA_TM_NO_HW_EVENT}, /* SVA_TM_EOI_INTERRUPT */ + {SVA_TM_TRANSITION_REJECTED , SVA_TM_NO_HW_EVENT}, /* SVA_TM_FAK_INTERRUPT */ + {SVA_TM_IDLE , SVA_TM_NO_HW_EVENT} /* SVA_TM_ABORT_INTERRUPT */ + }, + { + /* Current state : SVA_TM_FAKING */ + {SVA_TM_TRANSITION_REJECTED , SVA_TM_NO_HW_EVENT}, /* SVA_TM_COMMAND_START */ + {SVA_TM_TRANSITION_REJECTED , SVA_TM_NO_HW_EVENT}, /* SVA_TM_COMMAND_STOP_LIST_EMPTY */ + {SVA_TM_TRANSITION_REJECTED , SVA_TM_NO_HW_EVENT}, /* SVA_TM_COMMAND_STOP_LIST_NOT_EMPTY */ + {SVA_TM_TRANSITION_REJECTED , SVA_TM_NO_HW_EVENT}, /* SVA_TM_COMMAND_ABORT */ + {SVA_TM_TRANSITION_REJECTED , SVA_TM_NO_HW_EVENT}, /* SVA_TM_COMMAND_FAKE */ + {SVA_TM_TRANSITION_REJECTED , SVA_TM_NO_HW_EVENT}, /* SVA_TM_COMMAND_ACTIVATE */ + {SVA_TM_TRANSITION_REJECTED , SVA_TM_NO_HW_EVENT}, /* SVA_TM_COMMAND_ACTIVATE_DELAYED */ + {SVA_TM_TRANSITION_REJECTED , SVA_TM_NO_HW_EVENT}, /* SVA_TM_COMMAND_INACTIVATE */ + {SVA_TM_IDLE , SVA_TM_FAKE_HW_EVENT}, /* SVA_TM_DUMMY_INTERRUPT */ + {SVA_TM_IDLE , SVA_TM_NO_HW_EVENT}, /* SVA_TM_ACK_INTERRUPT */ + {SVA_TM_TRANSITION_REJECTED , SVA_TM_NO_HW_EVENT}, /* SVA_TM_BOT_INTERRUPT */ + {SVA_TM_TRANSITION_REJECTED , SVA_TM_NO_HW_EVENT}, /* SVA_TM_EOT_INTERRUPT */ + {SVA_TM_TRANSITION_REJECTED , SVA_TM_NO_HW_EVENT}, /* SVA_TM_LAST_EOT_INTERRUPT */ + {SVA_TM_TRANSITION_REJECTED , SVA_TM_NO_HW_EVENT}, /* SVA_TM_ERR_INTERRUPT */ + {SVA_TM_TRANSITION_REJECTED , SVA_TM_NO_HW_EVENT}, /* SVA_TM_BRC_INTERRUPT */ + {SVA_TM_TRANSITION_REJECTED , SVA_TM_NO_HW_EVENT}, /* SVA_TM_EOI_INTERRUPT */ + {SVA_TM_IDLE , SVA_TM_NO_HW_EVENT}, /* SVA_TM_FAK_INTERRUPT */ + {SVA_TM_TRANSITION_REJECTED , SVA_TM_NO_HW_EVENT} /* SVA_TM_ABORT_INTERRUPT */ + }, + { + /* Current state : SVA_TM_ABORTING //shubhrangam */ + {SVA_TM_TRANSITION_REJECTED , SVA_TM_NO_HW_EVENT}, /* SVA_TM_COMMAND_START */ + {SVA_TM_TRANSITION_REJECTED , SVA_TM_NO_HW_EVENT}, /* SVA_TM_COMMAND_STOP_LIST_EMPTY */ + {SVA_TM_TRANSITION_REJECTED , SVA_TM_NO_HW_EVENT}, /* SVA_TM_COMMAND_STOP_LIST_NOT_EMPTY */ + {SVA_TM_TRANSITION_REJECTED , SVA_TM_NO_HW_EVENT}, /* SVA_TM_COMMAND_ABORT */ + {SVA_TM_TRANSITION_REJECTED , SVA_TM_NO_HW_EVENT}, /* SVA_TM_COMMAND_FAKE */ + {SVA_TM_TRANSITION_REJECTED , SVA_TM_NO_HW_EVENT}, /* SVA_TM_COMMAND_ACTIVATE */ + {SVA_TM_TRANSITION_REJECTED , SVA_TM_NO_HW_EVENT}, /* SVA_TM_COMMAND_ACTIVATE_DELAYED */ + {SVA_TM_TRANSITION_REJECTED , SVA_TM_NO_HW_EVENT}, /* SVA_TM_COMMAND_INACTIVATE */ + {SVA_TM_ABORTING , SVA_TM_NO_HW_EVENT}, /* SVA_TM_DUMMY_INTERRUPT */ + {SVA_TM_TRANSITION_REJECTED , SVA_TM_NO_HW_EVENT}, /* SVA_TM_ACK_INTERRUPT */ + {SVA_TM_TRANSITION_REJECTED , SVA_TM_NO_HW_EVENT}, /* SVA_TM_BOT_INTERRUPT */ + {SVA_TM_ABORTING , SVA_TM_NO_HW_EVENT}, /* SVA_TM_EOT_INTERRUPT */ /* Not sure(added this because EOT doesnot come with ABORT ?? should change to rejected */ + {SVA_TM_IDLE , SVA_TM_ABORT_HW_EVENT}, /* SVA_TM_LAST_EOT_INTERRUPT */ /* Not sure (CONDITION :if last subtask then idle should not be effective */ + {SVA_TM_IDLE , SVA_TM_ABORT_HW_EVENT}, /* SVA_TM_ERR_INTERRUPT */ /* Not sure */ + {SVA_TM_TRANSITION_REJECTED , SVA_TM_NO_HW_EVENT}, /* SVA_TM_BRC_INTERRUPT */ + {SVA_TM_TRANSITION_REJECTED , SVA_TM_NO_HW_EVENT}, /* SVA_TM_EOI_INTERRUPT */ + {SVA_TM_TRANSITION_REJECTED , SVA_TM_EOK_HW_EVENT}, /* SVA_TM_FAK_INTERRUPT */ + {SVA_TM_IDLE , SVA_TM_NO_HW_EVENT} /* SVA_TM_ABORT_INTERRUPT */ + }, + { + /* Current state : SVA_TM_STOPPING */ + {SVA_TM_TRANSITION_REJECTED , SVA_TM_NO_HW_EVENT}, /* SVA_TM_COMMAND_START */ + {SVA_TM_TRANSITION_REJECTED , SVA_TM_NO_HW_EVENT}, /* SVA_TM_COMMAND_STOP_LIST_EMPTY */ + {SVA_TM_TRANSITION_REJECTED , SVA_TM_NO_HW_EVENT}, /* SVA_TM_COMMAND_STOP_LIST_NOT_EMPTY */ + {SVA_TM_ABORTING , SVA_TM_NO_HW_EVENT}, /* SVA_TM_COMMAND_ABORT *///check + {SVA_TM_TRANSITION_REJECTED , SVA_TM_NO_HW_EVENT}, /* SVA_TM_COMMAND_FAKE */ + {SVA_TM_TRANSITION_REJECTED , SVA_TM_NO_HW_EVENT}, /* SVA_TM_COMMAND_ACTIVATE */ + {SVA_TM_TRANSITION_REJECTED , SVA_TM_NO_HW_EVENT}, /* SVA_TM_COMMAND_ACTIVATE_DELAYED */ + {SVA_TM_TRANSITION_REJECTED , SVA_TM_NO_HW_EVENT}, /* SVA_TM_COMMAND_INACTIVATE */ + {SVA_TM_TRANSITION_REJECTED , SVA_TM_NO_HW_EVENT}, /* SVA_TM_DUMMY_INTERRUPT */ + {SVA_TM_TRANSITION_REJECTED , SVA_TM_NO_HW_EVENT}, /* SVA_TM_ACK_INTERRUPT */ + {SVA_TM_TRANSITION_REJECTED , SVA_TM_NO_HW_EVENT}, /* SVA_TM_BOT_INTERRUPT */ + {SVA_TM_STOPPING , SVA_TM_NO_HW_EVENT}, /* SVA_TM_EOT_INTERRUPT */ + {SVA_TM_IDLE , SVA_TM_EOK_HW_EVENT}, /* SVA_TM_LAST_EOT_INTERRUPT */ + {SVA_TM_IDLE , SVA_TM_NO_HW_EVENT}, /* SVA_TM_ERR_INTERRUPT */ + {SVA_TM_TRANSITION_REJECTED , SVA_TM_NO_HW_EVENT}, /* SVA_TM_BRC_INTERRUPT */ + {SVA_TM_TRANSITION_REJECTED , SVA_TM_NO_HW_EVENT}, /* SVA_TM_EOI_INTERRUPT */ + {SVA_TM_TRANSITION_REJECTED , SVA_TM_NO_HW_EVENT}, /* SVA_TM_FAK_INTERRUPT */ + {SVA_TM_IDLE , SVA_TM_NO_HW_EVENT} /* SVA_TM_ABORT_INTERRUPT */ + }, + { + /* Current state : SVA_TM_STOPPING_BY_FAKE */ + {SVA_TM_TRANSITION_REJECTED , SVA_TM_NO_HW_EVENT}, /* SVA_TM_COMMAND_START */ + {SVA_TM_TRANSITION_REJECTED , SVA_TM_NO_HW_EVENT}, /* SVA_TM_COMMAND_STOP_LIST_EMPTY */ + {SVA_TM_TRANSITION_REJECTED , SVA_TM_NO_HW_EVENT}, /* SVA_TM_COMMAND_STOP_LIST_NOT_EMPTY */ + {SVA_TM_TRANSITION_REJECTED , SVA_TM_NO_HW_EVENT}, /* SVA_TM_COMMAND_ABORT */ + {SVA_TM_TRANSITION_REJECTED , SVA_TM_NO_HW_EVENT}, /* SVA_TM_COMMAND_FAKE */ + {SVA_TM_TRANSITION_REJECTED , SVA_TM_NO_HW_EVENT}, /* SVA_TM_COMMAND_ACTIVATE */ + {SVA_TM_TRANSITION_REJECTED , SVA_TM_NO_HW_EVENT}, /* SVA_TM_COMMAND_ACTIVATE_DELAYED */ + {SVA_TM_TRANSITION_REJECTED , SVA_TM_NO_HW_EVENT}, /* SVA_TM_COMMAND_INACTIVATE */ + {SVA_TM_IDLE , SVA_TM_EOK_HW_EVENT}, /* SVA_TM_DUMMY_INTERRUPT */ + {SVA_TM_TRANSITION_REJECTED , SVA_TM_NO_HW_EVENT}, /* SVA_TM_ACK_INTERRUPT */ + {SVA_TM_IDLE , SVA_TM_NO_HW_EVENT}, /* SVA_TM_BOT_INTERRUPT */ + {SVA_TM_IDLE , SVA_TM_NO_HW_EVENT}, /* SVA_TM_EOT_INTERRUPT */ + {SVA_TM_TRANSITION_REJECTED , SVA_TM_NO_HW_EVENT}, /* SVA_TM_LAST_EOT_INTERRUPT */ + {SVA_TM_TRANSITION_REJECTED , SVA_TM_NO_HW_EVENT}, /* SVA_TM_ERR_INTERRUPT */ + {SVA_TM_TRANSITION_REJECTED , SVA_TM_NO_HW_EVENT}, /* SVA_TM_BRC_INTERRUPT */ + {SVA_TM_TRANSITION_REJECTED , SVA_TM_NO_HW_EVENT}, /* SVA_TM_EOI_INTERRUPT */ + {SVA_TM_IDLE , SVA_TM_EOK_HW_EVENT}, /* SVA_TM_FAK_INTERRUPT */ + {SVA_TM_TRANSITION_REJECTED, SVA_TM_NO_HW_EVENT} /* SVA_TM_ABORT_INTERRUPT */ + } +}; + +PRIVATE const t_sva_tm_activateTransition_elem activateStateMachine[SVA_TM_LAST_ACTIVATE_DUMMY_STATE][SVA_TM_LAST_LIST_DUMMY_TRANSITION]= { + { + /* Current state : SVA_TM_ACTIVATING */ + {SVA_TM_ACTIVATE_TRANSITION_REJECTED , SVA_TM_NO_HW_EVENT}, /* SVA_TM_COMMAND_START */ + {SVA_TM_ACTIVATE_TRANSITION_REJECTED , SVA_TM_NO_HW_EVENT}, /* SVA_TM_COMMAND_STOP_LIST_EMPTY */ + {SVA_TM_ACTIVATE_TRANSITION_REJECTED , SVA_TM_NO_HW_EVENT}, /* SVA_TM_COMMAND_STOP_LIST_NOT_EMPTY */ + {SVA_TM_ACTIVATE_TRANSITION_REJECTED , SVA_TM_NO_HW_EVENT}, /* SVA_TM_COMMAND_ABORT */ + {SVA_TM_ACTIVATE_TRANSITION_REJECTED , SVA_TM_NO_HW_EVENT}, /* SVA_TM_COMMAND_FAKE */ + {SVA_TM_ACTIVATE_TRANSITION_REJECTED , SVA_TM_NO_HW_EVENT}, /* SVA_TM_COMMAND_ACTIVATE */ + {SVA_TM_ACTIVATE_TRANSITION_REJECTED , SVA_TM_NO_HW_EVENT}, /* SVA_TM_COMMAND_ACTIVATE_DELAYED */ + {SVA_TM_ACTIVATE_TRANSITION_REJECTED , SVA_TM_NO_HW_EVENT}, /* SVA_TM_COMMAND_INACTIVATE */ + {SVA_TM_ACTIVATED , SVA_TM_ACTIVE_HW_EVENT}, /* SVA_TM_DUMMY_INTERRUPT */ + {SVA_TM_ACTIVATE_TRANSITION_REJECTED , SVA_TM_NO_HW_EVENT}, /* SVA_TM_ACK_INTERRUPT */ + {SVA_TM_ACTIVATE_TRANSITION_REJECTED , SVA_TM_NO_HW_EVENT}, /* SVA_TM_BOT_INTERRUPT */ + {SVA_TM_ACTIVATE_TRANSITION_REJECTED , SVA_TM_NO_HW_EVENT}, /* SVA_TM_EOT_INTERRUPT */ + {SVA_TM_ACTIVATE_TRANSITION_REJECTED , SVA_TM_NO_HW_EVENT}, /* SVA_TM_LAST_EOT_INTERRUPT */ + {SVA_TM_ACTIVATE_TRANSITION_REJECTED , SVA_TM_NO_HW_EVENT}, /* SVA_TM_ERR_INTERRUPT */ + {SVA_TM_ACTIVATE_TRANSITION_REJECTED , SVA_TM_NO_HW_EVENT}, /* SVA_TM_BRC_INTERRUPT */ + {SVA_TM_ACTIVATE_TRANSITION_REJECTED , SVA_TM_NO_HW_EVENT}, /* SVA_TM_EOI_INTERRUPT */ + {SVA_TM_ACTIVATED , SVA_TM_ACTIVE_HW_EVENT}, /* SVA_TM_FAK_INTERRUPT */ + {SVA_TM_ACTIVATE_TRANSITION_REJECTED , SVA_TM_NO_HW_EVENT} /* SVA_TM_ABORT_INTERRUPT */ + }, + { + /* Current state : SVA_TM_ACTIVATING_WITH_DELAY */ + {SVA_TM_ACTIVATE_TRANSITION_REJECTED , SVA_TM_NO_HW_EVENT}, /* SVA_TM_COMMAND_START */ + {SVA_TM_ACTIVATE_TRANSITION_REJECTED , SVA_TM_NO_HW_EVENT}, /* SVA_TM_COMMAND_STOP_LIST_EMPTY */ + {SVA_TM_ACTIVATE_TRANSITION_REJECTED , SVA_TM_NO_HW_EVENT}, /* SVA_TM_COMMAND_STOP_LIST_NOT_EMPTY */ + {SVA_TM_ACTIVATE_TRANSITION_REJECTED , SVA_TM_NO_HW_EVENT}, /* SVA_TM_COMMAND_ABORT */ + {SVA_TM_ACTIVATE_TRANSITION_REJECTED , SVA_TM_NO_HW_EVENT}, /* SVA_TM_COMMAND_FAKE */ + {SVA_TM_ACTIVATE_TRANSITION_REJECTED , SVA_TM_NO_HW_EVENT}, /* SVA_TM_COMMAND_ACTIVATE */ + {SVA_TM_ACTIVATE_TRANSITION_REJECTED , SVA_TM_NO_HW_EVENT}, /* SVA_TM_COMMAND_ACTIVATE_DELAYED */ + {SVA_TM_ACTIVATE_TRANSITION_REJECTED , SVA_TM_NO_HW_EVENT}, /* SVA_TM_COMMAND_INACTIVATE */ + {SVA_TM_ACTIVATE_TRANSITION_REJECTED , SVA_TM_NO_HW_EVENT}, /* SVA_TM_DUMMY_INTERRUPT */ + {SVA_TM_ACTIVATE_TRANSITION_REJECTED , SVA_TM_NO_HW_EVENT}, /* SVA_TM_ACK_INTERRUPT */ + {SVA_TM_ACTIVATE_TRANSITION_REJECTED , SVA_TM_NO_HW_EVENT}, /* SVA_TM_BOT_INTERRUPT */ + {SVA_TM_ACTIVATE_TRANSITION_REJECTED , SVA_TM_NO_HW_EVENT}, /* SVA_TM_EOT_INTERRUPT */ + {SVA_TM_ACTIVATE_TRANSITION_REJECTED , SVA_TM_NO_HW_EVENT}, /* SVA_TM_LAST_EOT_INTERRUPT */ + {SVA_TM_ACTIVATE_TRANSITION_REJECTED , SVA_TM_NO_HW_EVENT}, /* SVA_TM_ERR_INTERRUPT */ + {SVA_TM_ACTIVATE_TRANSITION_REJECTED , SVA_TM_NO_HW_EVENT}, /* SVA_TM_BRC_INTERRUPT */ + {SVA_TM_ACTIVATING , SVA_TM_NO_HW_EVENT}, /* SVA_TM_EOI_INTERRUPT */ + {SVA_TM_ACTIVATE_TRANSITION_REJECTED , SVA_TM_NO_HW_EVENT}, /* SVA_TM_FAK_INTERRUPT */ + {SVA_TM_ACTIVATE_TRANSITION_REJECTED , SVA_TM_NO_HW_EVENT} /* SVA_TM_ABORT_INTERRUPT */ + }, + { + /* Current state : SVA_TM_ACTIVATED */ + {SVA_TM_ACTIVATED , SVA_TM_NO_HW_EVENT}, /* SVA_TM_COMMAND_START */ + {SVA_TM_ACTIVATED , SVA_TM_NO_HW_EVENT}, /* SVA_TM_COMMAND_STOP_LIST_EMPTY */ + {SVA_TM_ACTIVATED , SVA_TM_NO_HW_EVENT}, /* SVA_TM_COMMAND_STOP_LIST_NOT_EMPTY */ + {SVA_TM_ACTIVATED , SVA_TM_NO_HW_EVENT}, /* SVA_TM_COMMAND_ABORT *///not sure + {SVA_TM_ACTIVATED , SVA_TM_NO_HW_EVENT}, /* SVA_TM_COMMAND_FAKE */ + {SVA_TM_ACTIVATE_TRANSITION_REJECTED , SVA_TM_NO_HW_EVENT}, /* SVA_TM_COMMAND_ACTIVATE */ + {SVA_TM_ACTIVATE_TRANSITION_REJECTED , SVA_TM_NO_HW_EVENT}, /* SVA_TM_COMMAND_ACTIVATE_DELAYED */ + {SVA_TM_DEACTIVATING , SVA_TM_NO_HW_EVENT}, /* SVA_TM_COMMAND_INACTIVATE */ + {SVA_TM_ACTIVATED , SVA_TM_NO_HW_EVENT}, /* SVA_TM_DUMMY_INTERRUPT */ + {SVA_TM_ACTIVATED , SVA_TM_NO_HW_EVENT}, /* SVA_TM_ACK_INTERRUPT */ + {SVA_TM_ACTIVATED , SVA_TM_NO_HW_EVENT}, /* SVA_TM_BOT_INTERRUPT */ + {SVA_TM_ACTIVATED , SVA_TM_NO_HW_EVENT}, /* SVA_TM_EOT_INTERRUPT */ + {SVA_TM_ACTIVATED , SVA_TM_NO_HW_EVENT}, /* SVA_TM_LAST_EOT_INTERRUPT */ + {SVA_TM_ACTIVATED , SVA_TM_NO_HW_EVENT}, /* SVA_TM_ERR_INTERRUPT */ + {SVA_TM_ACTIVATED , SVA_TM_NO_HW_EVENT}, /* SVA_TM_BRC_INTERRUPT */ + {SVA_TM_ACTIVATE_TRANSITION_REJECTED , SVA_TM_NO_HW_EVENT}, /* SVA_TM_EOI_INTERRUPT */ + {SVA_TM_ACTIVATED , SVA_TM_NO_HW_EVENT}, /* SVA_TM_FAK_INTERRUPT */ + {SVA_TM_ACTIVATED , SVA_TM_NO_HW_EVENT} /* SVA_TM_ABORT_INTERRUPT */ + }, + { + /* Current state : SVA_TM_DEACTIVATING */ + {SVA_TM_ACTIVATE_TRANSITION_REJECTED , SVA_TM_NO_HW_EVENT}, /* SVA_TM_COMMAND_START */ + {SVA_TM_ACTIVATE_TRANSITION_REJECTED , SVA_TM_NO_HW_EVENT}, /* SVA_TM_COMMAND_STOP_LIST_EMPTY */ + {SVA_TM_ACTIVATE_TRANSITION_REJECTED , SVA_TM_NO_HW_EVENT}, /* SVA_TM_COMMAND_STOP_LIST_NOT_EMPTY */ + {SVA_TM_ACTIVATE_TRANSITION_REJECTED , SVA_TM_NO_HW_EVENT}, /* SVA_TM_COMMAND_ABORT */ + {SVA_TM_ACTIVATE_TRANSITION_REJECTED , SVA_TM_NO_HW_EVENT}, /* SVA_TM_COMMAND_FAKE */ + {SVA_TM_ACTIVATE_TRANSITION_REJECTED , SVA_TM_NO_HW_EVENT}, /* SVA_TM_COMMAND_ACTIVATE */ + {SVA_TM_ACTIVATE_TRANSITION_REJECTED , SVA_TM_NO_HW_EVENT}, /* SVA_TM_COMMAND_ACTIVATE_DELAYED */ + {SVA_TM_ACTIVATE_TRANSITION_REJECTED , SVA_TM_NO_HW_EVENT}, /* SVA_TM_COMMAND_INACTIVATE */ + {SVA_TM_DEACTIVATED , SVA_TM_INACTIVE_HW_EVENT},/* SVA_TM_DUMMY_INTERRUPT */ + {SVA_TM_ACTIVATE_TRANSITION_REJECTED , SVA_TM_NO_HW_EVENT}, /* SVA_TM_ACK_INTERRUPT */ + {SVA_TM_ACTIVATE_TRANSITION_REJECTED , SVA_TM_NO_HW_EVENT}, /* SVA_TM_BOT_INTERRUPT */ + {SVA_TM_ACTIVATE_TRANSITION_REJECTED , SVA_TM_NO_HW_EVENT}, /* SVA_TM_EOT_INTERRUPT */ + {SVA_TM_ACTIVATE_TRANSITION_REJECTED , SVA_TM_NO_HW_EVENT}, /* SVA_TM_LAST_EOT_INTERRUPT */ + {SVA_TM_ACTIVATE_TRANSITION_REJECTED , SVA_TM_NO_HW_EVENT}, /* SVA_TM_ERR_INTERRUPT */ + {SVA_TM_ACTIVATE_TRANSITION_REJECTED , SVA_TM_NO_HW_EVENT}, /* SVA_TM_BRC_INTERRUPT */ + {SVA_TM_ACTIVATE_TRANSITION_REJECTED , SVA_TM_NO_HW_EVENT}, /* SVA_TM_EOI_INTERRUPT */ + {SVA_TM_DEACTIVATED , SVA_TM_INACTIVE_HW_EVENT},/* SVA_TM_FAK_INTERRUPT */ + {SVA_TM_ACTIVATE_TRANSITION_REJECTED , SVA_TM_NO_HW_EVENT} /* SVA_TM_ABORT_INTERRUPT */ + }, + { + /* Current state : SVA_TM_DEACTIVATED */ + {SVA_TM_DEACTIVATED , SVA_TM_NO_HW_EVENT}, /* SVA_TM_COMMAND_START */ + {SVA_TM_DEACTIVATED , SVA_TM_NO_HW_EVENT}, /* SVA_TM_COMMAND_STOP_LIST_EMPTY */ + {SVA_TM_DEACTIVATED , SVA_TM_NO_HW_EVENT}, /* SVA_TM_COMMAND_STOP_LIST_NOT_EMPTY */ + {SVA_TM_ACTIVATE_TRANSITION_REJECTED , SVA_TM_NO_HW_EVENT}, /* SVA_TM_COMMAND_ABORT */ + {SVA_TM_DEACTIVATED , SVA_TM_NO_HW_EVENT}, /* SVA_TM_COMMAND_FAKE */ + {SVA_TM_ACTIVATING , SVA_TM_NO_HW_EVENT}, /* SVA_TM_COMMAND_ACTIVATE */ + {SVA_TM_ACTIVATING_WITH_DELAY , SVA_TM_NO_HW_EVENT}, /* SVA_TM_COMMAND_ACTIVATE_DELAYED */ + {SVA_TM_ACTIVATE_TRANSITION_REJECTED , SVA_TM_NO_HW_EVENT}, /* SVA_TM_COMMAND_INACTIVATE */ + {SVA_TM_DEACTIVATED , SVA_TM_NO_HW_EVENT}, /* SVA_TM_DUMMY_INTERRUPT */ + {SVA_TM_DEACTIVATED , SVA_TM_NO_HW_EVENT}, /* SVA_TM_ACK_INTERRUPT */ + {SVA_TM_DEACTIVATED , SVA_TM_NO_HW_EVENT}, /* SVA_TM_BOT_INTERRUPT */ + {SVA_TM_DEACTIVATED , SVA_TM_NO_HW_EVENT}, /* SVA_TM_EOT_INTERRUPT */ + {SVA_TM_DEACTIVATED , SVA_TM_NO_HW_EVENT}, /* SVA_TM_LAST_EOT_INTERRUPT */ + {SVA_TM_DEACTIVATED , SVA_TM_NO_HW_EVENT}, /* SVA_TM_ERR_INTERRUPT */ + {SVA_TM_DEACTIVATED , SVA_TM_NO_HW_EVENT}, /* SVA_TM_BRC_INTERRUPT */ + {SVA_TM_ACTIVATE_TRANSITION_REJECTED , SVA_TM_NO_HW_EVENT}, /* SVA_TM_EOI_INTERRUPT */ + {SVA_TM_DEACTIVATED , SVA_TM_NO_HW_EVENT}, /* SVA_TM_FAK_INTERRUPT */ + {SVA_TM_ACTIVATE_TRANSITION_REJECTED , SVA_TM_NO_HW_EVENT} /* SVA_TM_ABORT_INTERRUPT */ + }}; + +/*------------------------------------------------------------------------ + * Private Macros + *----------------------------------------------------------------------*/ +#define NORMALIZE_ABSOLUTE_VALUE(timestampValue) (timestampValue &= ~MASK_BIT0) +#define NORMALIZE_RELATIVE_VALUE(timestampValue) (timestampValue |= MASK_BIT0) + +/*------------------------------------------------------------------------ + * Work around management + *----------------------------------------------------------------------*/ +/* + * Work around flag in the case an EOT is associated to an ERR one. This should + * never happen !!! Firmware bug. +*/ +#define __FW_WORK_AROUND_NO_EOT_WITH_ERR + + +/*------------------------------------------------------------------------ + * PRIVATE Functions Prototypes + *----------------------------------------------------------------------*/ +PRIVATE t_bool sva_TM_isTransitionValid (t_sva_tm_subtask_list_info *pListInfo,t_sva_tm_list_transition requestedTransition); +PRIVATE t_sva_tm_list_state sva_TM_UpdateInstanceStateMachine (t_sva_tm_subtask_list_info *pListInfo, + t_sva_tm_list_transition requestedTransition, t_uint32 *pNewEvents); +PRIVATE t_sva_tm_error sva_TM_markAsUnscheduledAllSubtasks (t_sva_tm_subtask_list_info *pListInfo); +PRIVATE t_sva_tm_error sva_TM_removeFirstSubtaskFromSubtaskList ( + t_sva_tm_subtask_list_id subtaskListId, t_sva_tm_subtask_id *subtaskId); + +PRIVATE t_sva_tm_error sva_TM_PrepareSchedule (void); +PRIVATE t_sva_tm_error sva_TM_ScheduleSubtaskInSubtaskList (t_sva_tm_subtask_list_info * pListInfo, t_uint32 *); +PRIVATE t_sva_tm_error sva_TM_DispatchEvent (t_bool isDispatchAllHwTasks, t_sva_tm_task_id taskId, + t_sva_tm_list_transition transition,t_uint32 *pRemainingEventToFill, + t_uint32 *pNbOfVirtualHwEvent, t_sva_tm_virtual_hw_event_desc * pVirtualEventDesc, + t_uint32 hwIts); +PRIVATE t_sva_tm_error sva_TM_CheckAndSetHwInterrupts (t_sva_tm_subtask_list_info *pListInfo, + t_uint32 newMask); +PUBLIC t_sva_tm_error sva_TM_RecheckHwInterrupts (void); +PRIVATE t_sva_tm_error sva_TM_CheckAndResetHwInterrupts (t_sva_tm_subtask_list_info *pListInfo, + t_uint32 newMask); + +/*------------------------------------------------------------------------ + * PUBLIC Functions Prototypes + *----------------------------------------------------------------------*/ + +/****************************************************************************/ +/* NAME: sva_TM_Init( */ +/* t_logical_address RegLogicalBaseAddr, */ +/* t_logical_address MemLogicalBaseAddr) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: This routine initializes task management module. */ +/* */ +/* PARAMETERS: */ +/* IN : - RegLogicalBaseAddr : SVA Registers base address */ +/* - MemLogicalBaseAddr : SVA Memory base address */ +/* */ +/* OUT: none */ +/* */ +/* RETURN: */ +/* t_sva_tm_error: SVA_TM_OK */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: no */ +/****************************************************************************/ +PUBLIC t_sva_tm_error sva_TM_Init(t_logical_address RegLogicalBaseAddr, + t_logical_address MemLogicalBaseAddr) +{ + t_sva_tm_subtask_list_info * pListInfo; + t_sva_tm_error tmErrCode = SVA_TM_OK; + t_uint32 listCnt = 0; + t_uint8 hwTskCpt; + t_uint8 bitCpt; + + /* transmit hardware initialization */ + tmErrCode = sva_TM_HW_Init (RegLogicalBaseAddr, MemLogicalBaseAddr); + + if (tmErrCode != SVA_TM_OK) + return(tmErrCode); + + /* logical subtask list initialization */ + pListInfo = (t_sva_tm_subtask_list_info *) &ListInfo[0][0]; + while (listCnt < (SVA_TM_NB_HW_TASK * SVA_TM_TOTAL_SRV_PER_HW_TASK)) + { + pListInfo->serviceId = 0; + pListInfo->taskId = (t_sva_tm_task_id)0; + pListInfo->fwFeatures = SVA_FW_FEAT_NONE; + pListInfo->fwId = MASK_ALL32; + pListInfo->serviceMode = SVA_REALTIME_SERVICE; + pListInfo->eventMask = MASK_NULL32; + pListInfo->nbSubtask = 0; + pListInfo->firstSubtaskId = INVALID_SUBTASK_ID; + pListInfo->lastSubtaskId = INVALID_SUBTASK_ID; + + pListInfo->nextSubtasklistId = INVALID_SUBTASK_LIST_ID; + pListInfo->previousSubtasklistId = INVALID_SUBTASK_LIST_ID; + + pListInfo->activationState = SVA_TM_DEACTIVATED; + pListInfo->state = SVA_TM_IDLE; + pListInfo->is_abort_requested = FALSE; + pListInfo->executed_abort_iad = 0; + + pListInfo++; + listCnt++; + } /* while ...*/ + + /* logical global initialization */ + for (hwTskCpt=0; hwTskCptfieldnb%4) != 0) + fieldNumberToBeAllocated = (t_uint8)(((pTaskCtrlDesc->fieldnb/4)+1)*4); + else + fieldNumberToBeAllocated = pTaskCtrlDesc->fieldnb; + + /*************************************************************************/ + /* Build part of nty and nts values */ + /*************************************************************************/ + /* This part is to be done when subtask is inserted in list or updated when a start is done. */ + ntySize =(t_uint16)(sizeof(t_sva_subtask_link)+((t_uint32)fieldNumberToBeAllocated*sizeof(t_physical_address))); + nty =(((t_uint32)ntySize<memId; + + /*************************************************************************/ + /* Subtask memory allocation and affectation : */ + /* 2/ Calculate the subtask parameter size by parsing the array */ + /* pCurrentFieldDescArray and associated commands */ + /*************************************************************************/ + switch(subtaskMemoryId) + { + case XRAM_ID : sizealloc_int = subtaskHeaderSize; break; + case ESRAM_ID: sizealloc_esram = subtaskHeaderSize; break; + case SDRAM_ID: sizealloc_sdram = subtaskHeaderSize; break; + default: tmErrorCode = SVA_TM_BAD_FUNCTION_PARAMETER;break; + } + + // Parse pfieldctrldesc structure array + fieldNumber = pTaskCtrlDesc->fieldnb; + pCurrentFieldDesc = pTaskCtrlDesc->pfieldctrldesc; + while ( (fieldNumber != 0) && (tmErrorCode == SVA_TM_OK) ) + { + switch(pCurrentFieldDesc->command) + { + case SVA_TM_DCMD_ALLOCATE : + fieldMemoryId = pCurrentFieldDesc->commandDesc.allocDesc.memId; + fieldsize = pCurrentFieldDesc->commandDesc.allocDesc.sizetoallocate; + + /* Check multiple of 16 alignment constraint. */ + if ( (fieldsize%4) != 0) + fieldsize = (t_uint8)(((fieldsize/4)+1)*4); + + switch(fieldMemoryId) + { + case XRAM_ID : sizealloc_int = sizealloc_int + fieldsize; break; + case ESRAM_ID : sizealloc_esram = sizealloc_esram + fieldsize; break; + case SDRAM_ID : sizealloc_sdram = sizealloc_sdram + fieldsize; break; + default : tmErrorCode = SVA_TM_BAD_FUNCTION_PARAMETER; break; + } + break; + case SVA_TM_DCMD_REFERENCE : + case SVA_TM_DCMD_NULL : + /* Nothing to do as it's not an allocation */ + break; + default: + tmErrorCode = SVA_TM_BAD_FUNCTION_PARAMETER; + break; + } + // Save field access depth + pCurrentFieldDesc++; + fieldNumber--; + } /* while (fieldNumber!=0) */ + + if (tmErrorCode != SVA_TM_OK) + return(tmErrorCode); + + /*************************************************************************/ + /* Subtask memory allocation and affectation : */ + /* 3/ Allocate memory blocks for each memory type */ + /*************************************************************************/ + if (sizealloc_int != 0) + { + mmErrorCode = sva_MM_AllocBlock(XRAM_ID, sizealloc_int, SVA_MM_ALIGN_16BYTES, &intBlockId); + if (mmErrorCode == SVA_MM_OK) + { + mmErrorCode = sva_MM_GetBlockPhysicalAddress(intBlockId, &intSubtaskPhyAddr); + if (subtaskMemoryId == XRAM_ID) + { + /* Update Physical memory pointer according to header + info sizes if required. */ + intSubtaskPhyAddr += (sizeof(t_sva_tm_subtask_info) + sizeof(t_sva_subtask_link) + + ((t_uint32)fieldNumberToBeAllocated * sizeof(t_physical_address)) + INTERNAL_MEM_EXT_BIT); + } + } + if (mmErrorCode != SVA_MM_OK) + { + sva_MM_FreeBlock(intBlockId); + return SVA_TM_MM_XRAM_ERROR; + } + } + if (sizealloc_esram != 0) + { + mmErrorCode = sva_MM_AllocBlock(ESRAM_ID, sizealloc_esram, SVA_MM_ALIGN_16BYTES, &esramBlockId); + + if (mmErrorCode == SVA_MM_OK) + { + mmErrorCode = sva_MM_GetBlockPhysicalAddress(esramBlockId, &esramSubtaskPhyAddr); + if (subtaskMemoryId == ESRAM_ID) + { + /* Update Physical memory pointer according to header + info sizes if required. */ + esramSubtaskPhyAddr += (sizeof(t_sva_tm_subtask_info) + sizeof(t_sva_subtask_link) + + ((t_uint32)fieldNumberToBeAllocated * sizeof(t_physical_address)) + EXTERNAL_MEM_EXT_BIT); + } + } + + if (mmErrorCode != SVA_MM_OK) + { + sva_MM_FreeBlock(esramBlockId); + if (sizealloc_int != 0) sva_MM_FreeBlock(intBlockId); + return SVA_TM_MM_ESRAM_ERROR; + } + } + if (sizealloc_sdram != 0) + { + mmErrorCode = sva_MM_AllocBlock(SDRAM_ID, sizealloc_sdram, SVA_MM_ALIGN_16BYTES, &sdramBlockId); + if (mmErrorCode == SVA_MM_OK) + { + mmErrorCode = sva_MM_GetBlockPhysicalAddress(sdramBlockId, &sdramSubtaskPhyAddr); + new_sdramSubtaskPhyAddr= sizeof(t_sva_tm_subtask_info) + sdramSubtaskPhyAddr + EXTERNAL_MEM_EXT_BIT; +/* changes done so that the value of Last_IAD_EOT_ERR[SVA_TM_GRAB] doesnot match with allocated subtasks id. + abort related changes*/ + if((taskId==SVA_TM_GRAB)&&(Last_IAD_EOT_ERR[taskId]==new_sdramSubtaskPhyAddr)) + { + new_sdramBlockId = sdramBlockId; + mmErrorCode = sva_MM_AllocBlock(SDRAM_ID, sizealloc_sdram, SVA_MM_ALIGN_16BYTES, &sdramBlockId); + if (mmErrorCode == SVA_MM_OK) + { + mmErrorCode = sva_MM_GetBlockPhysicalAddress(sdramBlockId, &sdramSubtaskPhyAddr); + } + sva_MM_FreeBlock(new_sdramBlockId); + + } + if ((subtaskMemoryId == SDRAM_ID)&&(mmErrorCode == SVA_MM_OK)) + { + /* Update Physical memory pointer according to header + info sizes if required. */ + sdramSubtaskPhyAddr += (sizeof(t_sva_tm_subtask_info) + sizeof(t_sva_subtask_link) + + ((t_uint32)fieldNumberToBeAllocated * sizeof(t_physical_address)) + EXTERNAL_MEM_EXT_BIT); + } + if (mmErrorCode != SVA_MM_OK) + { + sva_MM_FreeBlock(sdramBlockId); + } + } + if (mmErrorCode != SVA_MM_OK) + { + sva_MM_FreeBlock(sdramBlockId); + if (sizealloc_int != 0) sva_MM_FreeBlock(intBlockId); + if (sizealloc_esram != 0) sva_MM_FreeBlock(esramBlockId); + return SVA_TM_MM_SDRAM_ERROR; + } + } + /*************************************************************************/ + /* Subtask memory allocation and affectation : */ + /* 4/ Fill each field of subtask header data (info, type, link, ...)*/ + /* in suitable memory area */ + /*************************************************************************/ + switch (subtaskMemoryId) + { + case XRAM_ID : + blockId = intBlockId; + subtaskExtBit = INTERNAL_MEM_EXT_BIT; + subtaskBlockId = blockId; + mem1BlockId = esramBlockId; + mem2BlockId = sdramBlockId; + break; + case ESRAM_ID : + blockId = esramBlockId; + subtaskExtBit = EXTERNAL_MEM_EXT_BIT; + subtaskBlockId = blockId; + mem1BlockId = intBlockId; + mem2BlockId = sdramBlockId; + break; + case SDRAM_ID: + blockId = sdramBlockId; + subtaskExtBit = EXTERNAL_MEM_EXT_BIT; + subtaskBlockId = blockId; + mem1BlockId = intBlockId; + mem2BlockId = esramBlockId; + break; + default: + /* Should not happen as already tested above */ + tmErrorCode = SVA_TM_BAD_FUNCTION_PARAMETER; + break; + } /* switch (subtaskMemoryId) */ + + /* Get the logical address of the subtask header */ + mmErrorCode = sva_MM_GetBlockLogicalAddress(blockId, &subtaskLogAddr); + + if ( (mmErrorCode != SVA_MM_OK) || (tmErrorCode != SVA_TM_OK) ) + { + if (sizealloc_int != 0) sva_MM_FreeBlock(intBlockId); + if (sizealloc_esram != 0) sva_MM_FreeBlock(esramBlockId); + if (sizealloc_sdram != 0) sva_MM_FreeBlock(sdramBlockId); + return SVA_TM_BAD_FUNCTION_PARAMETER; + } + + /* Memorize its value. It will be reported to caller */ + *pSubtaskId = (t_sva_tm_subtask_id )subtaskLogAddr; + + /*Record block_id in subtask info fields*/ + psubtaskInfos = (t_sva_tm_subtask_info *) (subtaskLogAddr); + psubtaskLink = (t_sva_subtask_link *) (subtaskLogAddr + sizeof(t_sva_tm_subtask_info)); + + psubtaskInfos->subtaskListId = INVALID_SUBTASK_LIST_ID; + psubtaskInfos->nextSubtaskId = INVALID_SUBTASK_ID; + psubtaskInfos->previousSubtaskId = INVALID_SUBTASK_ID; + psubtaskInfos->subtaskState = SVA_TM_UNDEFINED_STATE; + + psubtaskInfos->atomicityNumber = 0; + psubtaskInfos->eventMask = MASK_NULL32; + + psubtaskInfos->taskId = taskId; + + psubtaskInfos->nty = nty; + psubtaskInfos->timestamp = 0; + psubtaskInfos->timestampType = SVA_TM_IMMEDIATE; + + psubtaskInfos->memBlocks.subtaskBlockId = subtaskBlockId; + psubtaskInfos->memBlocks.mem1BlockId = mem1BlockId; + psubtaskInfos->memBlocks.mem2BlockId = mem2BlockId; + + psubtaskLink->type = 0; + psubtaskLink->execution_time_stamp = 0; + psubtaskLink->addr = 0; + psubtaskLink->dependency = 0; // Today, no task dependency managed + + /*************************************************************************/ + /* Subtask memory allocation and affectation : */ + /* 4/ Fill each field of subtask field parameter (for each 3 memory */ + /* blocks if necessary) */ + /*************************************************************************/ + // NB : continue with same memory : SUBTASK MEMORY TYPE + //and currentSubtaskLogAddr at the first field ADDRESS + currentSubtaskLogAddr = subtaskLogAddr + sizeof(t_sva_tm_subtask_info) + sizeof(t_sva_subtask_link); + + //Parse pfieldctrldesc structure array + fieldNumber = pTaskCtrlDesc->fieldnb; + pCurrentFieldDesc = pTaskCtrlDesc->pfieldctrldesc; + + while ( (fieldNumber != 0) && (tmErrorCode == SVA_TM_OK) ) + { + switch(pCurrentFieldDesc->command) + { + case SVA_TM_DCMD_ALLOCATE: + /* Get memoryId of field to allocate */ + fieldMemoryId = pCurrentFieldDesc->commandDesc.allocDesc.memId; + fieldsize = pCurrentFieldDesc->commandDesc.allocDesc.sizetoallocate; + + /* Check multiple of 16 alignment constraint. */ + if ( (fieldsize%4) != 0) + fieldsize = (t_uint8)(((fieldsize/4)+1)*4); + + switch (fieldMemoryId) + { + case XRAM_ID : + *((t_logical_address *)currentSubtaskLogAddr) = (t_logical_address)intSubtaskPhyAddr; + intSubtaskPhyAddr += fieldsize; + break; + case ESRAM_ID : + *((t_logical_address *)currentSubtaskLogAddr) = (t_logical_address)esramSubtaskPhyAddr; + esramSubtaskPhyAddr += fieldsize; + break; + case SDRAM_ID : + *((t_logical_address *)currentSubtaskLogAddr) = (t_logical_address)sdramSubtaskPhyAddr; + sdramSubtaskPhyAddr += fieldsize; + break; + default : + tmErrorCode = SVA_TM_BAD_FUNCTION_PARAMETER; + break; + } /* switch (fieldMemoryId) */ + break; + case SVA_TM_DCMD_REFERENCE: + /* Update field address with the one given as parameter */ + *((t_logical_address *)currentSubtaskLogAddr) = + *((t_logical_address *)(pCurrentFieldDesc->commandDesc.refDesc.subtaskidtoreference + + sizeof(t_sva_tm_subtask_info) + sizeof(t_sva_subtask_link) + + (t_uint32)(pCurrentFieldDesc->commandDesc.refDesc.fieldtoreference) * + sizeof(t_logical_address))); + break; + case SVA_TM_DCMD_NULL: + *((t_logical_address *)currentSubtaskLogAddr) = (t_logical_address)subtaskExtBit; //equivalent to NULL + break; + default: + tmErrorCode = SVA_TM_BAD_FUNCTION_PARAMETER; + break; + } + pCurrentFieldDesc++; // Target next descriptor + fieldNumber--; // One less field to process + // update currentSubtaskLogAddr to next field address + currentSubtaskLogAddr = currentSubtaskLogAddr + sizeof(t_logical_address); + + } /* while(...) */ + + if (tmErrorCode != SVA_TM_OK) + { + if (sizealloc_int != 0) sva_MM_FreeBlock(intBlockId); + if (sizealloc_esram != 0) sva_MM_FreeBlock(esramBlockId); + if (sizealloc_sdram != 0) sva_MM_FreeBlock(sdramBlockId); + } + + return(tmErrorCode); +} /* End of sva_TM_CreateSubTask() function. */ + +/****************************************************************************/ +/* NAME: sva_TM_DeleteSubTask( */ +/* t_sva_tm_subtask_id subtaskId) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: This routine deletes a subtask in memory */ +/* */ +/* PARAMETERS: */ +/* IN : - subtaskId, subtask identifier */ +/* */ +/* OUT: none */ +/* */ +/* RETURN: */ +/* t_sva_tm_error: SVA_TM_OK */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: no */ +/****************************************************************************/ +PUBLIC t_sva_tm_error sva_TM_DeleteSubTask(t_sva_tm_subtask_id subtaskId) +{ + t_sva_tm_subtask_info *psubtaskInfos; + + /* Discard all parameters (temporary) */ + HCL_DEBUG_ASSERT(subtaskId != NULL); + + psubtaskInfos = (t_sva_tm_subtask_info *) subtaskId;//subtaskId is in fact the subtask logical address + + /* Free all allocated memory blocks */ + if (psubtaskInfos->memBlocks.subtaskBlockId != 0) + { + sva_MM_FreeBlock(psubtaskInfos->memBlocks.subtaskBlockId); + } + if (psubtaskInfos->memBlocks.mem1BlockId != 0) + { + sva_MM_FreeBlock(psubtaskInfos->memBlocks.mem1BlockId); + } + if (psubtaskInfos->memBlocks.mem2BlockId != 0) + { + sva_MM_FreeBlock(psubtaskInfos->memBlocks.mem2BlockId); + } + return(SVA_TM_OK); +} /* End of sva_TM_DeleteSubTask() function. */ + + +/*SubTask List Management */ +/****************************************************************************/ +/* NAME: sva_TM_CreateSubTaskList( */ +/* t_sva_service_id serviceId, */ +/* t_sva_fw_features fwFeature, */ +/* t_sva_tm_subtask_list_id *pSubtaskListId) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: This routine enables to create a subtask list in memory */ +/* */ +/* PARAMETERS: */ +/* IN : - serviceId, service identifer linked to the subtask list to be */ +/* created */ +/* - fwFeature, firmware feature needed to execute the subtasks */ +/* */ +/* OUT: - pSubtaskListId, subtask list Id */ +/* */ +/* RETURN: */ +/* t_sva_tm_error: SVA_TM_OK */ +/* SVA_TM_NO_MORE_SUBTASKLIST_DESC */ +/* SVA_TM_BAD_FUNCTION_PARAMETER */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: no */ +/****************************************************************************/ +PUBLIC t_sva_tm_error sva_TM_CreateSubTaskList(t_sva_tm_task_id taskId, + t_sva_service_id serviceId, + t_sva_fw_features fwFeature, + t_sva_tm_subtask_list_id *pSubtaskListId) +{ + t_sva_tm_error tmErrCode = SVA_TM_NO_MORE_SUBTASKLIST_DESC; + + t_sva_tm_subtask_list_info *pListInfo; + t_sva_tm_subtask_list_info *pLastlistInfo; + + HCL_DEBUG_ASSERT(pSubtaskListId!=NULL); + + if (taskId > SVA_TM_TVO) + return(SVA_TM_BAD_FUNCTION_PARAMETER); + + pListInfo = &ListInfo[taskId][0]; + pLastlistInfo = &ListInfo[taskId][SVA_TM_TOTAL_SRV_PER_HW_TASK - 1]; + + do + { + if (pListInfo->serviceId == 0) + { + /* Ok, a position was found. Terminate the initialization. */ + pListInfo->taskId = taskId; + pListInfo->serviceId = serviceId; + pListInfo->fwFeatures = fwFeature; + pListInfo->fwId = MASK_ALL32; + pListInfo->serviceMode = SVA_REALTIME_SERVICE; + pListInfo->eventMask = MASK_NULL32; + + pListInfo->nbSubtask = 0; + pListInfo->firstSubtaskId = INVALID_SUBTASK_ID; + pListInfo->lastSubtaskId = INVALID_SUBTASK_ID; + + pListInfo->activationState = SVA_TM_DEACTIVATED; + pListInfo->state = SVA_TM_IDLE; + pListInfo->is_abort_requested = FALSE; + pListInfo->executed_abort_iad = 0; + + /* Update subtask list ID for upper layer */ + *pSubtaskListId = (t_sva_tm_subtask_list_id)pListInfo; + + /* Enable ACK interrupt for lower layer. */ + if (HwTasksInfos[pListInfo->taskId].nbCreatedSubtaskLists == 0) + { + /* It's the first service that is created. Enable lower level */ + /* interrupts : ACK/EOK (required for the first fake interrupt) */ + sva_TM_CheckAndSetHwInterrupts (pListInfo, SVA_TM_ACK_HW_EVENT); + sva_TM_CheckAndSetHwInterrupts (pListInfo, SVA_TM_EOK_HW_EVENT); +#ifdef __DEBUG + /* In case of subtask duration tracking, allow also BOT IT. */ + if (TM_TRACK_SUBTASK_DURATION == TRUE) + sva_TM_CheckAndSetHwInterrupts (pListInfo, SVA_TM_BOT_HW_EVENT); +#endif + } + HwTasksInfos[taskId].nbCreatedSubtaskLists += 1; + + /* Link management. */ + if (HwTasksInfos[taskId].firstSubtaskListId == INVALID_SUBTASK_LIST_ID) + { + /* First element of the list. */ + HwTasksInfos[taskId].firstSubtaskListId = (t_sva_tm_subtask_list_id)pListInfo; + HwTasksInfos[taskId].lastSubtaskListId = (t_sva_tm_subtask_list_id)pListInfo; + + pListInfo->nextSubtasklistId = INVALID_SUBTASK_LIST_ID; + pListInfo->previousSubtasklistId = INVALID_SUBTASK_LIST_ID; + } + else + { + pListInfo->nextSubtasklistId = INVALID_SUBTASK_LIST_ID; + pListInfo->previousSubtasklistId = HwTasksInfos[taskId].lastSubtaskListId; + ((t_sva_tm_subtask_list_info *)(HwTasksInfos[taskId].lastSubtaskListId))->nextSubtasklistId + = (t_sva_tm_subtask_list_id)pListInfo; + HwTasksInfos[taskId].lastSubtaskListId = (t_sva_tm_subtask_list_id)pListInfo; + } + + tmErrCode = SVA_TM_OK; + } + else + pListInfo ++; + } while ( (tmErrCode != SVA_TM_OK) && (pListInfo <= pLastlistInfo) ); + + return(tmErrCode); +} /* End of sva_TM_CreateSubTaskList() function. */ + +/****************************************************************************/ +/* NAME: sva_TM_CreateSubTaskListOpenService( */ +/* t_sva_service_id serviceId, */ +/* t_sva_fw_id fwId, */ +/* t_sva_tm_subtask_list_id *pSubtaskListId) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: This routine enables to create a subtask list in memory if */ +/* the service is an open one. In this case, the firmware is */ +/* discriminated by its Id insted od feature desc. */ +/* */ +/* PARAMETERS: */ +/* IN : - serviceId, service identifer linked to the subtask list to be */ +/* created */ +/* - fwId, firmware identifier needed to execute the subtasks */ +/* */ +/* OUT: - pSubtaskListId, subtask list Id */ +/* */ +/* RETURN: */ +/* t_sva_tm_error: SVA_TM_OK */ +/* SVA_TM_BAD_FUNCTION_PARAMETER */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: no */ +/****************************************************************************/ +PUBLIC t_sva_tm_error sva_TM_CreateSubTaskListOpenService(t_sva_tm_task_id taskId, + t_sva_service_id serviceId, + t_sva_fw_id fwId, + t_sva_tm_subtask_list_id *pSubtaskListId) +{ + t_sva_tm_error tmErrCode = SVA_TM_NO_MORE_SUBTASKLIST_DESC; + + t_sva_tm_subtask_list_info *pListInfo; + t_sva_tm_subtask_list_info *pLastlistInfo; + + HCL_DEBUG_ASSERT(pSubtaskListId!=NULL); + + if (taskId > SVA_TM_TVO) + return(SVA_TM_BAD_FUNCTION_PARAMETER); + + pListInfo = &ListInfo[taskId][0]; + pLastlistInfo = &ListInfo[taskId][SVA_TM_TOTAL_SRV_PER_HW_TASK - 1]; + + do + { + if (pListInfo->serviceId == 0) + { + /* Ok, a position was found. Terminate the initialization. */ + pListInfo->taskId = taskId; + pListInfo->serviceId = serviceId; + pListInfo->fwFeatures = SVA_FW_FEAT_NONE; + pListInfo->fwId = fwId; + pListInfo->serviceMode = SVA_REALTIME_SERVICE; + pListInfo->eventMask = MASK_NULL32; + + pListInfo->nbSubtask = 0; + pListInfo->firstSubtaskId = INVALID_SUBTASK_ID; + pListInfo->lastSubtaskId = INVALID_SUBTASK_ID; + + pListInfo->activationState = SVA_TM_DEACTIVATED; + pListInfo->state = SVA_TM_IDLE; + pListInfo->is_abort_requested = FALSE; + pListInfo->executed_abort_iad = 0; + + /* Update subtask list ID for upper layer */ + *pSubtaskListId = (t_sva_tm_subtask_list_id)pListInfo; + + /* Enable ACK interrupt for lower layer. */ + if (HwTasksInfos[pListInfo->taskId].nbCreatedSubtaskLists == 0) + { + /* It's the first service that is created. Enable lower level */ + /* interrupts : ACK/EOK (required for the first fake interrupt) */ + sva_TM_CheckAndSetHwInterrupts (pListInfo, SVA_TM_ACK_HW_EVENT); + sva_TM_CheckAndSetHwInterrupts (pListInfo, SVA_TM_EOK_HW_EVENT); +#ifdef __DEBUG + /* In case of subtask duration tracking, allow also BOT IT. */ + if (TM_TRACK_SUBTASK_DURATION == TRUE) + sva_TM_CheckAndSetHwInterrupts (pListInfo, SVA_TM_BOT_HW_EVENT); +#endif + } + HwTasksInfos[taskId].nbCreatedSubtaskLists += 1; + + /* Link management. */ + if (HwTasksInfos[taskId].firstSubtaskListId == INVALID_SUBTASK_LIST_ID) + { + /* First element of the list. */ + HwTasksInfos[taskId].firstSubtaskListId = (t_sva_tm_subtask_list_id)pListInfo; + HwTasksInfos[taskId].lastSubtaskListId = (t_sva_tm_subtask_list_id)pListInfo; + + pListInfo->nextSubtasklistId = INVALID_SUBTASK_LIST_ID; + pListInfo->previousSubtasklistId = INVALID_SUBTASK_LIST_ID; + } + else + { + pListInfo->nextSubtasklistId = INVALID_SUBTASK_LIST_ID; + pListInfo->previousSubtasklistId = HwTasksInfos[taskId].lastSubtaskListId; + ((t_sva_tm_subtask_list_info *)(HwTasksInfos[taskId].lastSubtaskListId))->nextSubtasklistId + = (t_sva_tm_subtask_list_id)pListInfo; + HwTasksInfos[taskId].lastSubtaskListId = (t_sva_tm_subtask_list_id)pListInfo; + } + + tmErrCode = SVA_TM_OK; + } + else + pListInfo ++; + } while ( (tmErrCode != SVA_TM_OK) && (pListInfo <= pLastlistInfo) ); + + return(tmErrCode); +} /* End of sva_TM_CreateSubTaskListOpenService() function. */ + +/****************************************************************************/ +/* NAME: sva_TM_DeleteSubTaskList( */ +/* t_sva_tm_subtask_id subtaskListId) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: This routine deletes a subtask list in memory */ +/* */ +/* PARAMETERS: */ +/* IN : - subtaskListId, subtask list identifier */ +/* */ +/* OUT: none */ +/* */ +/* RETURN: */ +/* t_sva_tm_error: SVA_TM_OK */ +/* SVA_TM_BAD_FUNCTION_PARAMETER */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: no */ +/****************************************************************************/ +PUBLIC t_sva_tm_error sva_TM_DeleteSubTaskList( + t_sva_tm_subtask_list_id subtaskListId) +{ + t_sva_tm_subtask_list_info *pListInfo; + + pListInfo = (t_sva_tm_subtask_list_info *)subtaskListId; + + if (pListInfo->serviceId == 0) + return(SVA_TM_BAD_FUNCTION_PARAMETER); + + /* Disable possible pending hw interrupts. */ + sva_TM_CheckAndResetHwInterrupts(pListInfo, pListInfo->eventMask); + pListInfo->eventMask = MASK_NULL32; + + if (pListInfo->activationState != SVA_TM_DEACTIVATED) + { + /* The service was still activated. Decrement relevant counters. */ + if (pListInfo->serviceMode == SVA_REALTIME_SERVICE) + GlobalInfos.nbRealTimeActivatedService --; + else + GlobalInfos.nbNonRealTimeActivatedService --; + + if (pListInfo->fwFeatures != SVA_FW_FEAT_NONE) + /* Features are known by Task Management module. Update use counter */ + sva_FM_UnRegisterFeaturesUse (pListInfo->fwFeatures); + else + /* Otherwise, use the firmware Id instead. */ + sva_FM_DecrementeFirmwareIdInstance(pListInfo->fwId); + } /* if ... */ + + HwTasksInfos[pListInfo->taskId].nbCreatedSubtaskLists -= 1; + + /* Link management. */ + if (HwTasksInfos[pListInfo->taskId].nbCreatedSubtaskLists == 0) + { + /* Remove the last subtask list. */ + HwTasksInfos[pListInfo->taskId].firstSubtaskListId = INVALID_SUBTASK_LIST_ID; + HwTasksInfos[pListInfo->taskId].lastSubtaskListId = INVALID_SUBTASK_LIST_ID; + pListInfo->nextSubtasklistId = INVALID_SUBTASK_LIST_ID; + pListInfo->previousSubtasklistId = INVALID_SUBTASK_LIST_ID; + + /* It's the last service that is deleted. Disable lower level */ + /* interrupts : ACK/EOK. */ + sva_TM_CheckAndResetHwInterrupts (pListInfo, SVA_TM_ACK_HW_EVENT); + sva_TM_CheckAndResetHwInterrupts (pListInfo, SVA_TM_EOK_HW_EVENT); + } + else if (HwTasksInfos[pListInfo->taskId].firstSubtaskListId == subtaskListId) + { + /* First element of the list. */ + HwTasksInfos[pListInfo->taskId].firstSubtaskListId = pListInfo->nextSubtasklistId; + ((t_sva_tm_subtask_list_info *)(pListInfo->nextSubtasklistId))->previousSubtasklistId + = INVALID_SUBTASK_LIST_ID; + pListInfo->nextSubtasklistId = INVALID_SUBTASK_LIST_ID; + } + else if (HwTasksInfos[pListInfo->taskId].lastSubtaskListId == subtaskListId) + { + /* Last element of the list. */ + HwTasksInfos[pListInfo->taskId].lastSubtaskListId = pListInfo->previousSubtasklistId; + ((t_sva_tm_subtask_list_info *)(pListInfo->previousSubtasklistId))->nextSubtasklistId + = INVALID_SUBTASK_LIST_ID; + pListInfo->previousSubtasklistId = INVALID_SUBTASK_LIST_ID; + } + else + { + ((t_sva_tm_subtask_list_info *)(pListInfo->previousSubtasklistId))->nextSubtasklistId + = pListInfo->nextSubtasklistId; + ((t_sva_tm_subtask_list_info *)(pListInfo->nextSubtasklistId))->previousSubtasklistId + = pListInfo->previousSubtasklistId; + pListInfo->nextSubtasklistId = INVALID_SUBTASK_LIST_ID; + pListInfo->previousSubtasklistId = INVALID_SUBTASK_LIST_ID; + } + + pListInfo->serviceId = 0; + pListInfo->fwId = MASK_ALL32; + pListInfo->fwFeatures = SVA_FW_FEAT_NONE; + + /* Special case the removed subtaskListId is the last scanned by PrepareSchedule function. */ + /* In this case, just reset it. */ + if (HwTasksInfos[pListInfo->taskId].lastSubtaskListIdScanned == subtaskListId) + HwTasksInfos[pListInfo->taskId].lastSubtaskListIdScanned = HwTasksInfos[pListInfo->taskId].firstSubtaskListId; + + return(SVA_TM_OK); +} /* End of sva_TM_DeleteSubTaskList() function. */ + +/****************************************************************************/ +/* NAME: sva_TM_AddElemToSubTaskList( */ +/* t_sva_tm_subtask_list_id subtasklistId, */ +/* t_sva_tm_subtask_id newLastSubtaskId */ +/* t_sva_tm_timestamp *subtaskTimeStamp */ +/* t_uint32 atomicityNumber) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: This routine enables to add a subtask in a subtasklist */ +/* at the end of a previously created subtask list */ +/* */ +/* PARAMETERS: */ +/* IN : - subtaskListId, subtask list identifier */ +/* - newLastSubtaskId, subtask identifier to be added in the list */ +/* - subtaskTimeStamp, time stamp associated to the subtask */ +/* - atomicityNumber, indicate the number of subtask to be run together*/ +/* (single task : 1, ...) */ +/* */ +/* OUT: none */ +/* */ +/* RETURN: */ +/* t_sva_tm_error: SVA_TM_OK */ +/* SVA_TM_BAD_FUNCTION_PARAMETER */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: no */ +/****************************************************************************/ +PUBLIC t_sva_tm_error sva_TM_AddElemToSubTaskList( + t_sva_tm_subtask_list_id subtaskListId, + t_sva_tm_subtask_id newLastSubtaskId, + t_sva_tm_timestamp *pSubtaskTimeStamp, + t_uint32 atomicityNumber) +{ + //for nty and nts buiding + t_bool timestampEn = FALSE; + t_sva_ticks timestampInTicks; + + t_sva_tm_subtask_list_info *pListInfo = (t_sva_tm_subtask_list_info *)subtaskListId; + t_sva_tm_subtask_info *pSubtaskInfo = (t_sva_tm_subtask_info *)newLastSubtaskId; + t_sva_tm_subtask_info *pLastSubtaskInfo; + + HCL_DEBUG_ASSERT(pSubtaskTimeStamp!=NULL); + + if (atomicityNumber == 0) + return(SVA_TM_BAD_FUNCTION_PARAMETER); + + /*************************************************************************/ + /* time stamps informations. */ + /*************************************************************************/ + switch(pSubtaskTimeStamp->timestampType) + { + case SVA_TM_IMMEDIATE : + timestampInTicks = 0; + timestampEn = FALSE; + break; + case SVA_TM_RELATIVE : + timestampInTicks = sva_TI_ConvertSystemTimeToTicks(pListInfo->serviceId, pSubtaskTimeStamp->timestampValue); + NORMALIZE_RELATIVE_VALUE(timestampInTicks); + timestampEn = TRUE; + break; + case SVA_TM_ABSOLUTE : + timestampInTicks = sva_TI_ConvertSystemTimeToTicks(pListInfo->serviceId, pSubtaskTimeStamp->timestampValue); + NORMALIZE_ABSOLUTE_VALUE(timestampInTicks); + timestampEn = TRUE; + break; + default : + return(SVA_TM_BAD_FUNCTION_PARAMETER); + /* break; */ + } + pSubtaskInfo->nty |= ((t_uint32)timestampEn << SHIFT_TSE); + pSubtaskInfo->timestamp = timestampInTicks; + pSubtaskInfo->timestampType = pSubtaskTimeStamp->timestampType; + pSubtaskInfo->subtaskState = SVA_TM_READY_TO_SCHEDULE; + pSubtaskInfo->atomicityNumber = atomicityNumber; + pSubtaskInfo->eventMask = pListInfo->eventMask; + + /* Test if at least one element */ + if (pListInfo->lastSubtaskId == INVALID_SUBTASK_ID) + { + /* No, insert it as first AND last element. */ + pListInfo->firstSubtaskId = newLastSubtaskId; + + pSubtaskInfo->nextSubtaskId = INVALID_SUBTASK_ID; + pSubtaskInfo->previousSubtaskId = INVALID_SUBTASK_ID; + } + else + { + /* Yes, insert it as last element. */ + pLastSubtaskInfo = (t_sva_tm_subtask_info *)(pListInfo->lastSubtaskId); + pLastSubtaskInfo->nextSubtaskId = newLastSubtaskId; + + pSubtaskInfo->nextSubtaskId = INVALID_SUBTASK_ID; + pSubtaskInfo->previousSubtaskId = pListInfo->lastSubtaskId; + } + + pSubtaskInfo->subtaskListId = subtaskListId; + pListInfo->nbSubtask ++; + pListInfo->lastSubtaskId = newLastSubtaskId; + + /* A new subtask is inserted inot the subtask list. Try to schedule it. */ + sva_TM_PrepareSchedule(); + + return(SVA_TM_OK); + +} /* End of sva_TM_AddElemToSubTaskList() function. */ + + +/****************************************************************************/ +/* NAME: sva_TM_RemoveElemFromSubTaskList( */ +/* t_sva_tm_subtask_list_id subtasklistId, */ +/* t_sva_tm_subtask_id *pSubtaskId) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: This routine removes an element previously inserted in the */ +/* logical subtask list. */ +/* */ +/* PARAMETERS: */ +/* IN : - subtaskListId, subtask list identifier */ +/* */ +/* OUT: - pSubtaskId, pointer to subtask identifier removed from the list */ +/* */ +/* RETURN: */ +/* t_sva_tm_error: SVA_TM_OK */ +/* SVA_TM_NO_MORE_SUBTASK_DESC */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: no */ +/****************************************************************************/ +PUBLIC t_sva_tm_error sva_TM_RemoveElemFromSubTaskList( + t_sva_tm_subtask_list_id subtaskListId, + t_sva_tm_subtask_id *pSubtaskId) +{ + t_sva_tm_error tmError; + + tmError = sva_TM_removeFirstSubtaskFromSubtaskList ( + subtaskListId, pSubtaskId); + + return(tmError); + +} /* End of sva_TM_RemoveElemFromSubTaskList() function. */ + +/****************************************************************************/ +/* NAME: sva_TM_ActivateSubTaskList( */ +/* t_sva_tm_subtask_list_id subtaskListId, */ +/* t_sva_service_mode serviceMode, */ +/* t_sva_fw_id *pFwId) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: This routine activate the subtask list (i.e. it allowes all */ +/* subtask in it to be scheduled by hardware */ +/* */ +/* PARAMETERS: */ +/* IN : - subtaskListId, subtask list identifier */ +/* - serviceMode, specifies if the subtasklist's mode (real time or not*/ +/* (i.e may not support or yes auto firmware switch) */ +/* */ +/* OUT: none */ +/* */ +/* RETURN: */ +/* t_sva_tm_error: SVA_FW_CONFLICT */ +/* SVA_FW_DOWNLOAD_NEEDED */ +/* SVA_FW_NOT_PROVIDED */ +/* SVA_FW_SWITCH_OCCURED */ +/* SVA_INTERNAL_TASK_MGT_ERROR */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: no */ +/****************************************************************************/ +/* + * REMAINS TO BE DONE : Manage properly non-real-time mode. +*/ +PUBLIC t_sva_error sva_TM_ActivateSubTaskList( + t_sva_tm_subtask_list_id subtaskListId, + t_sva_service_mode serviceMode, + t_sva_fw_id *pFwId) +{ + t_sva_tm_subtask_list_info *pListInfo = (t_sva_tm_subtask_list_info *)subtaskListId; + t_sva_error errCode = SVA_FW_SWITCH_OCCURED; + t_sva_fm_error fmErrCode; + t_uint32 eventMask; + t_bool isFwChangeNeed=TRUE; + + + HCL_DEBUG_ASSERT(pFwId!=NULL); + + /* Test if transition is allowed */ + if (sva_TM_isTransitionValid(pListInfo, SVA_TM_COMMAND_ACTIVATE) == FALSE) + return(SVA_INTERNAL_TASK_MGT_ERROR); + + /* In case feature used is not available, test firmware availability with */ + /* the register firmware Id (Open service case). */ + if (pListInfo->fwFeatures == SVA_FW_FEAT_NONE) + { + sva_FM_TestFirmwareChangeNeedByFirmwareId(pListInfo->fwId,&isFwChangeNeed); + } + + if (pListInfo->fwFeatures != SVA_FW_FEAT_NONE && sva_FM_IsFirmwareChangeNeededByFeatures(pListInfo->fwFeatures) == TRUE) + { + /* A new Firmware download is need. Check if we allow it. */ + if (GlobalInfos.nbRealTimeActivatedService == 0) + /* Test is we allow the firmware switch mechanism. */ + { + fmErrCode = sva_FM_GetFirmwareIdByFeatures(pListInfo->fwFeatures, pFwId); + + /* Do we have a suitable FW ? */ + if ( (fmErrCode == SVA_FM_FEATURES_UNKNOWN_BY_REGISTERED_FW) || (*pFwId == SVA_FW_INVALID_ID) ) + /* There's no known firmware that supports the required feature plus the new one */ + return(SVA_FW_NOT_PROVIDED); + + /* Do we have its address in shared memory ? */ + if (fmErrCode == SVA_FM_FW_NO_ADDRESS) + return(SVA_FW_DOWNLOAD_NEEDED); + + if (GlobalInfos.nbScheduledSubtask == 0) + { + /* Change our state machine with a dummy event Mask as output. */ + sva_TM_UpdateInstanceStateMachine(pListInfo, SVA_TM_COMMAND_ACTIVATE, &eventMask); + + fmErrCode = sva_FM_Download (*pFwId); + HCL_DEBUG_ASSERT(fmErrCode==SVA_FM_OK); + + /*@BORT-$TOP*/ + /* + + Get the Garbage Value of Last_IAD_EOT_ERR + Last_IAD_EOT_ERR = pTasksRegs->genTask.nad; + + */ + + + GlobalInfos.fwState = SVA_TM_FW_LOADED; + GlobalInfos.fwIdActive = *pFwId; + + fmErrCode = sva_FM_RegisterFeaturesUse (pListInfo->fwFeatures); + HCL_DEBUG_ASSERT(fmErrCode==SVA_FM_OK); + + /* Enable all video irq sources */ + SVA_EnableIRQSrc (SVA_IRQ); + + sva_TM_CheckAndSetHwInterrupts(pListInfo, pListInfo->eventMask); + + /* WARNING : Resetting the firmware leads to resetting all interrupt mask register !*/ + /* We have to set all of it (i.e. all subtask types) before going ahead !!! */ + sva_TM_RecheckHwInterrupts(); + } + else + { + /* Change our state machine with a dummy event Mask as output. */ + sva_TM_UpdateInstanceStateMachine(pListInfo, SVA_TM_COMMAND_ACTIVATE_DELAYED, &eventMask); + + /* At least one subtask has been scheduled. Delay the firmware download... */ + GlobalInfos.fwState = SVA_TM_FW_CHANGING; + GlobalInfos.fwIdActive = *pFwId; + + errCode = SVA_FW_SWITCH_DELAYED; + + fmErrCode = sva_FM_RegisterFeaturesUse (pListInfo->fwFeatures); + HCL_DEBUG_ASSERT(fmErrCode==SVA_FM_OK); + + sva_TM_CheckAndSetHwInterrupts(pListInfo, pListInfo->eventMask); + } + } + else + return(SVA_FW_CONFLICT); + } + else if (pListInfo->fwFeatures == SVA_FW_FEAT_NONE && isFwChangeNeed == TRUE) + { + /* Test is we allow the firmware switch mechanism. */ + if (GlobalInfos.nbRealTimeActivatedService == 0) + { + + + /*test if we just need firmware address*/ + fmErrCode = sva_FM_GetFirmwareIdByFirmwareId(pListInfo->fwId, pFwId); + + /* Do we have a suitable FW ? */ + if (fmErrCode == SVA_FM_UNKNOWN_FIRMWARE_ID || fmErrCode == SVA_FM_UNREGISTERED_FIRMWARE_ID) + return (SVA_FW_NOT_PROVIDED); + + /* Do we have its address in shared memory ? */ + if (fmErrCode == SVA_FM_FW_NO_ADDRESS) + return (SVA_FW_DOWNLOAD_NEEDED); + + /*test firmware conflict case*/ + if (*pFwId == SVA_FW_INVALID_ID) + return (SVA_FW_CONFLICT); + + if (GlobalInfos.nbScheduledSubtask == 0) + { + /* Change our state machine with a dummy event Mask as output. */ + sva_TM_UpdateInstanceStateMachine(pListInfo, SVA_TM_COMMAND_ACTIVATE, &eventMask); + + fmErrCode = sva_FM_Download (*pFwId); + HCL_DEBUG_ASSERT(fmErrCode==SVA_FM_OK); + + + GlobalInfos.fwState = SVA_TM_FW_LOADED; + GlobalInfos.fwIdActive = *pFwId; + + fmErrCode = sva_FM_IncrementeFirmwareIdInstance (pListInfo->fwId); + HCL_DEBUG_ASSERT(fmErrCode==SVA_FM_OK); + + /*@BORT-$TOP*/ + /*Get the Garbage Value of Last_IAD_EOT_ERR + Last_IAD_EOT_ERR = pTasksRegs->genTask.nad; + */ + + + /* Enable all video irq sources */ + SVA_EnableIRQSrc (SVA_IRQ); + + sva_TM_CheckAndSetHwInterrupts(pListInfo, pListInfo->eventMask); + + /* WARNING : Resetting the firmware leads to resetting all interrupt mask register !*/ + /* We have to set all of it (i.e. all subtask types) before going ahead !!! */ + sva_TM_RecheckHwInterrupts(); + } + else + { + /* Change our state machine with a dummy event Mask as output. */ + sva_TM_UpdateInstanceStateMachine(pListInfo, SVA_TM_COMMAND_ACTIVATE_DELAYED, &eventMask); + + /* At least one subtask has been scheduled. Delay the firmware download... */ + GlobalInfos.fwState = SVA_TM_FW_CHANGING; + GlobalInfos.fwIdActive = *pFwId; + + errCode = SVA_FW_SWITCH_DELAYED; + + fmErrCode = sva_FM_IncrementeFirmwareIdInstance (pListInfo->fwId); + HCL_DEBUG_ASSERT(fmErrCode==SVA_FM_OK); + + sva_TM_CheckAndSetHwInterrupts(pListInfo, pListInfo->eventMask); + } + } + else {return SVA_FW_CONFLICT;} + } + else + { + /* The loaded firmware is suitable for our usage. */ + if (pListInfo->fwFeatures != SVA_FW_FEAT_NONE) + fmErrCode = sva_FM_RegisterFeaturesUse (pListInfo->fwFeatures); + else + fmErrCode = sva_FM_IncrementeFirmwareIdInstance (pListInfo->fwId); + HCL_DEBUG_ASSERT(fmErrCode==SVA_FM_OK); + + /* Change our state machine with a dummy event Mask as output. */ + sva_TM_UpdateInstanceStateMachine(pListInfo, SVA_TM_COMMAND_ACTIVATE, &eventMask); + + /* WARNING : Resetting the firmware leads to resetting all interrupt mask register !*/ + /* We have to set all of it (i.e. all subtask types) before going ahead !!! */ + sva_TM_CheckAndSetHwInterrupts(pListInfo, pListInfo->eventMask); + } + + if (serviceMode == SVA_REALTIME_SERVICE) + GlobalInfos.nbRealTimeActivatedService ++; + else + GlobalInfos.nbNonRealTimeActivatedService ++; + + pListInfo->serviceMode = serviceMode; + + /* Save the firwmare Id found. */ + pListInfo->fwId = *pFwId; + + /* Ask for a fake interrupt to change upper state. */ + sva_TM_HW_GenerateFake(pListInfo->taskId); + + return(errCode); +} /* End of sva_TM_ActivateSubTaskList() function. */ + +/****************************************************************************/ +/* NAME: sva_TM_InActivateSubTaskList( */ +/* t_sva_tm_subtask_list_id subtaskListId) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: This routine inactivate the subtask list (i.e. it forbides */ +/* all subtasks from this list to be scheduled by hardware) */ +/* */ +/* PARAMETERS: */ +/* IN : - subtaskListId, subtask list identifier */ +/* */ +/* OUT: none */ +/* */ +/* RETURN: */ +/* t_sva_tm_error: SVA_TM_OK */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: no */ +/****************************************************************************/ +PUBLIC t_sva_tm_error sva_TM_InActivateSubTaskList( + t_sva_tm_subtask_list_id subtaskListId) +{ + t_uint32 eventMask; + t_sva_tm_subtask_list_info *pListInfo = (t_sva_tm_subtask_list_info *)subtaskListId; + + /* Test state machine transition. */ + if (sva_TM_isTransitionValid (pListInfo, SVA_TM_COMMAND_INACTIVATE) == TRUE) + sva_TM_UpdateInstanceStateMachine(pListInfo, SVA_TM_COMMAND_INACTIVATE, &eventMask); + + if (pListInfo->serviceMode == SVA_REALTIME_SERVICE) + GlobalInfos.nbRealTimeActivatedService --; + else + GlobalInfos.nbNonRealTimeActivatedService --; + + if (pListInfo->fwFeatures != SVA_FW_FEAT_NONE) + sva_FM_UnRegisterFeaturesUse (pListInfo->fwFeatures); + else + sva_FM_DecrementeFirmwareIdInstance(pListInfo->fwId); + + /* Ask for a fake interrupt to change upper state. */ + sva_TM_HW_GenerateFake(pListInfo->taskId); + + return(SVA_TM_OK); +} /* End of sva_TM_InActivateSubTaskList() function. */ + +/****************************************************************************/ +/* NAME: sva_TM_SendTaskCommand( */ +/* t_sva_tm_subtask_list_id subtaskListId, */ +/* t_sva_tm_task_cmd_id command, */ +/* t_uint32 param) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: This routine enables to command a given task */ +/* Semaphore is locked during task control access */ +/* PARAMETERS: */ +/* IN : - subtaskListId, subtask list identifier */ +/* - command, command to be applied to subtask list */ +/* - param, parameter of the given command */ +/* -> Type of param : command : */ +/* */ +/* OUT: none */ +/* */ +/* RETURN: */ +/* t_sva_tm_error: SVA_TM_OK */ +/* SVA_TM_BAD_FUNCTION_PARAMETER */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: no */ +/****************************************************************************/ + +PUBLIC t_sva_tm_subtask_info * sva_TM_HW_GetCurrentSubTaskId(t_sva_tm_task_id taskId, t_uint32 *p_executed_abort_address); + +PUBLIC t_bool sva_TM_CheckAndExecuteAbortRequests(t_sva_tm_task_id taskId) +{ + t_bool is_abort_sent = FALSE; + t_sva_tm_subtask_list_info *p_firstSubtaskListId = (t_sva_tm_subtask_list_info *)HwTasksInfos[taskId].firstSubtaskListId; + t_sva_tm_subtask_list_info *p_lastSubtaskListId = (t_sva_tm_subtask_list_info *)HwTasksInfos[taskId].lastSubtaskListId; + + t_sva_tm_subtask_info *p_sva_tm_subtask_info; + + t_sva_tm_subtask_list_info *p_SubtaskListId; + + t_sva_tm_subtask_list_info *p_CurrentSubtaskListId; + + if (p_firstSubtaskListId!=(void*)INVALID_SUBTASK_LIST_ID && p_lastSubtaskListId!=(void*)INVALID_SUBTASK_LIST_ID) + { + t_uint32 executed_abort_address = 0; + sva_TM_HW_LockSemaphore(taskId); + p_SubtaskListId = p_firstSubtaskListId; + + p_sva_tm_subtask_info = sva_TM_HW_GetCurrentSubTaskId(taskId, &executed_abort_address); + + if (p_sva_tm_subtask_info == NULL || p_sva_tm_subtask_info == (void*)INVALID_SUBTASK_ID || p_sva_tm_subtask_info->subtaskListId == INVALID_SUBTASK_LIST_ID) + { + sva_TM_HW_UnlockSemaphore(taskId); + return is_abort_sent; /* all above requirements are mandatory to go forward */ + } + + p_CurrentSubtaskListId = (t_sva_tm_subtask_list_info *)(p_sva_tm_subtask_info->subtaskListId); + + while(1) + { + if (p_CurrentSubtaskListId == p_SubtaskListId) + if (p_CurrentSubtaskListId->is_abort_requested == TRUE) + { + is_abort_sent = TRUE; + p_CurrentSubtaskListId->executed_abort_iad = executed_abort_address; + sva_TM_HW_SendTaskCommand(taskId, SVA_TM_TCMD_ABORT, 0); + break; + } + + if (p_SubtaskListId == p_lastSubtaskListId) + { + break; + } + + p_SubtaskListId = (t_sva_tm_subtask_list_info*)p_SubtaskListId->nextSubtasklistId; + } + + sva_TM_HW_UnlockSemaphore(taskId); + } + else + { + HCL_ASSERT(0); /* something is wrong */ + } + + return is_abort_sent; +} + +PUBLIC t_uint32 sva_TM_GetNbSubTask(t_sva_tm_subtask_list_id subtaskListId) +{ + t_sva_tm_subtask_list_info *pListInfo = (t_sva_tm_subtask_list_info *)subtaskListId; + + return pListInfo->nbSubtask; +} + +PUBLIC t_sva_tm_error sva_TM_SendTaskCommand( + t_sva_tm_subtask_list_id subtaskListId, + t_sva_tm_task_cmd_id command, + t_uint32 param) +{ + t_uint32 NewEvents=0; + t_sva_tm_subtask_list_info *pListInfo = (t_sva_tm_subtask_list_info *)subtaskListId; + + /* Discard unused parameters */ + (void)param; + + switch (command) + { + case SVA_TM_TCMD_ABORT : //shubhrangam:added /*@BORT-$TOP*/ + + if (pListInfo->nbSubtask != 0) + { + /* The software subtask list is empty. Generate an EOK by fake. */ + if (sva_TM_isTransitionValid (pListInfo, SVA_TM_COMMAND_ABORT) == TRUE) + { + sva_TM_HW_SendTaskCommand(pListInfo->taskId, SVA_TM_TCMD_ABORT, param); + sva_TM_UpdateInstanceStateMachine(pListInfo, SVA_TM_COMMAND_ABORT, &NewEvents); + + } + + + } + else + { + + /* Ask for a fake interrupt to change upper state. */ + sva_TM_HW_GenerateFake(pListInfo->taskId); + } + + break; + + + case SVA_TM_TCMD_STOP : + + if (pListInfo->nbSubtask == 0) + { + /* The software subtask list is empty. Generate an EOK by fake. */ + if (sva_TM_isTransitionValid (pListInfo, SVA_TM_COMMAND_STOP_LIST_EMPTY) == TRUE) + sva_TM_UpdateInstanceStateMachine(pListInfo, SVA_TM_COMMAND_STOP_LIST_EMPTY, &NewEvents); + + /* Ask for a fake interrupt to change upper state. */ + sva_TM_HW_GenerateFake(pListInfo->taskId); + } + else + { + if (sva_TM_isTransitionValid (pListInfo, SVA_TM_COMMAND_STOP_LIST_NOT_EMPTY) == TRUE) + sva_TM_UpdateInstanceStateMachine(pListInfo, SVA_TM_COMMAND_STOP_LIST_NOT_EMPTY, &NewEvents); + } + + break; + + case SVA_TM_TCMD_START : + if (sva_TM_isTransitionValid(pListInfo, SVA_TM_COMMAND_START) == FALSE) + return(SVA_TM_BAD_FUNCTION_PARAMETER); + + sva_TM_UpdateInstanceStateMachine(pListInfo, SVA_TM_COMMAND_START, &NewEvents); + + /* Ask for a fake interrupt to change upper state. */ + //sva_TM_HW_GenerateFake(pListInfo->taskId); + //sva_TM_HW_SendTaskCommand(pListInfo->taskId, SVA_TM_TCMD_START, param); + + /* A subtask list is just being started. Try to schedule its already inserted subtasks. */ + sva_TM_PrepareSchedule(); + + break; + case SVA_TM_TCMD_FAKE_EVENT : + if (sva_TM_isTransitionValid(pListInfo, SVA_TM_COMMAND_FAKE) == FALSE) + return(SVA_TM_BAD_FUNCTION_PARAMETER); + sva_TM_UpdateInstanceStateMachine(pListInfo, SVA_TM_COMMAND_FAKE, &NewEvents); + + /* Ask for a fake interrupt to change upper state. */ + sva_TM_HW_GenerateFake(pListInfo->taskId); + + break; + /* Intermediate delivery including EOW support (JPEG decode support) */ + case SVA_TM_TCMD_READ_PACKET: + case SVA_TM_TCMD_WRITE_PACKET: + GlobalInfos.irpPacketSubtaskListId = subtaskListId; + sva_TM_HW_SendTaskCommand ( pListInfo->taskId, command, param); + break; + case SVA_TM_TCMD_STOP_SLICE : + case SVA_TM_TCMD_UPDATE_BUFFER : + case SVA_TM_TCMD_STOP_PHYSICAL : + sva_TM_HW_SendTaskCommand ( pListInfo->taskId, command, param); + break; + case SVA_TM_TCMD_GRABHQ_STATUS : + sva_TM_HW_SendTaskCommand ( pListInfo->taskId, command, param); + break; + case SVA_TM_TCMD_GRABHQ_TST : + sva_TM_HW_SendTaskCommand ( pListInfo->taskId, command, param); + break; + case SVA_TM_TCMD_GRABHQ_READ_NB_FAILURE_BML_PROCESS : + sva_TM_HW_SendTaskCommand ( pListInfo->taskId, command, param); + break; + default : + return(SVA_TM_BAD_FUNCTION_PARAMETER); + } /* switch */ + + return(SVA_TM_OK); +} /* End of sva_TM_SendTaskCommand() function. */ + + +// Last parameter: For Open service, last parameter should be true as will not discriminate if should take semaphore or not +/****************************************************************************/ +/* NAME: sva_TM_GetSubTaskField( */ +/* t_sva_tm_subtask_id subtaskId, */ +/* t_sva_tm_field_id fieldId, */ +/* t_logical_address destAddress, */ +/* t_uint32 offset, */ +/* t_size size, */ +/* t_bool TakeSemaphore) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: This routine enables to get a part of param#1 data */ +/* to a given subtask. */ +/* */ +/* PARAMETERS: */ +/* IN : - subtaskId, subtask identifier */ +/* - fieldId, first level field (i.e. subtask param's field) to be */ +/* copied */ +/* - destAddress, destination address to copy fields */ +/* - offset (in bytes), offset to apply from the base of param#1 data */ +/* structure */ +/* - size, number of byte to copy from subtask's fields */ +/* - TakeSemaphore, take or not the parameters semaphore */ +/* */ +/* OUT: none */ +/* */ +/* RETURN: */ +/* t_sva_tm_error: SVA_TM_OK */ +/* SVA_TM_BAD_FUNCTION_PARAMETER */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: no */ +/****************************************************************************/ +PUBLIC t_sva_tm_error sva_TM_GetSubTaskField( + t_sva_tm_subtask_id subtaskId, + t_sva_tm_field_id fieldId, + t_logical_address destAddress, + t_uint32 offset, + t_size size, + t_bool TakeSemaphore) +{ + t_logical_address subtaskLogAddr = 0; + t_logical_address fieldLogicalAddress = 0; + t_logical_address sourceLogicalAddress = 0; + t_physical_address sourcePhysicalAddress = 0; + + t_uint32 loopCounter = 0; + t_uint8 * pSourceAddress = 0; + t_uint8 * pDestAddress = 0; + + t_sva_tm_subtask_info *pSubtaskInfo = (t_sva_tm_subtask_info *)subtaskId; + + HCL_DEBUG_ASSERT(destAddress != NULL); + + subtaskLogAddr = (t_logical_address)subtaskId; + + if (TakeSemaphore) + sva_TM_HW_LockSemaphore(pSubtaskInfo->taskId); + + // .... + + /* Get the field's logical address that stores physical dest buffer address */ + fieldLogicalAddress = subtaskLogAddr + sizeof(t_sva_tm_subtask_info) + sizeof(t_sva_subtask_link) + + (t_uint32)((t_uint8)((t_uint32)fieldId & (t_uint32)0xFF)) * sizeof(t_logical_address); + + sourcePhysicalAddress = *((t_physical_address *)fieldLogicalAddress) & (~MASK_BIT0); //remove EXT bit from physical address + if (sva_MM_PhysicalToLogicalAddress(sourcePhysicalAddress, &sourceLogicalAddress) != SVA_MM_OK) + return(SVA_TM_BAD_FUNCTION_PARAMETER); + + sourceLogicalAddress += offset; + + pSourceAddress = (t_uint8 *)sourceLogicalAddress; + pDestAddress = (t_uint8 *)destAddress; + + for (loopCounter = 0; loopCounter < size; loopCounter ++) + *pDestAddress++ = *pSourceAddress++; + + // .... + if (TakeSemaphore) + sva_TM_HW_UnlockSemaphore(pSubtaskInfo->taskId); + + return(SVA_TM_OK); +} /* End of sva_TM_GetSubTaskField() function. */ + + +/****************************************************************************/ +/* NAME: sva_TM_ConnectSubtasksFields( */ +/* t_sva_tm_subtask_id srcSubtaskId, */ +/* t_sva_tm_field_id srcFieldId, */ +/* t_sva_subtask_id dstSubtaskId, */ +/* t_sva_tm_field_id dstFieldId) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: This routine enables to connect a given field (dstFieldId) */ +/* of a given subtask (dstSubtaskId) to a given field */ +/* (srcFieldId) of another subtask (srcSubtaskId) */ +/* */ +/* PARAMETERS: */ +/* IN : - srcSubtaskId: subtask Identifier */ +/* - srcFieldId: field Identifier */ +/* - dstSubtaskId: subtask Identifier */ +/* - dstFieldId: field Identifier */ +/* */ +/* OUT: none */ +/* */ +/* RETURN: */ +/* t_sva_tm_error: SVA_TM_OK */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: no */ +/****************************************************************************/ +PUBLIC t_sva_tm_error sva_TM_ConnectSubtasksFields( + t_sva_tm_subtask_id srcSubtaskId, + t_sva_tm_field_id srcFieldId, + t_sva_tm_subtask_id dstSubtaskId, + t_sva_tm_field_id dstFieldId) +{ + /* Discard all parameters (temporary) */ + t_logical_address srcSubtaskLogAddr = 0; + t_logical_address dstSubtaskLogAddr = 0; + + t_logical_address srcFieldLogicalAddress = 0; + t_logical_address dstFieldLogicalAddress = 0; + + srcSubtaskLogAddr = (t_logical_address)srcSubtaskId; + dstSubtaskLogAddr = (t_logical_address)dstSubtaskId; + + srcFieldLogicalAddress = srcSubtaskLogAddr + sizeof(t_sva_tm_subtask_info) + sizeof(t_sva_subtask_link) + + (t_uint32)((t_uint8)((t_uint32)srcFieldId & (t_uint32)0xFF)) * sizeof(t_logical_address); + + dstFieldLogicalAddress = dstSubtaskLogAddr + sizeof(t_sva_tm_subtask_info) + sizeof(t_sva_subtask_link) + + (t_uint32)((t_uint8)((t_uint32)dstFieldId & (t_uint32)0xFF)) * sizeof(t_logical_address); + + /* Now, connect... */ + *(t_logical_address *)dstFieldLogicalAddress = *(t_logical_address *)srcFieldLogicalAddress; + + return(SVA_TM_OK); +} /* End of sva_TM_ConnectSubtasksFields() function. */ + +/****************************************************************************/ +/* NAME: sva_TM_InitSubTaskField( */ +/* t_sva_tm_subtask_id subtaskId, */ +/* t_sva_tm_field_id fieldId, */ +/* t_logical_address sourceAddress, */ +/* t_size size) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: This routine enables to connect a given field of a given */ +/* subtask to a given field of another subtask */ +/* */ +/* PARAMETERS: */ +/* IN : - subtaskId, subtask Identifier */ +/* - fieldId, field Identifier to initialize */ +/* - sourceAddress, address of data to copy in subtask structure */ +/* - size, size in bytes of data transfert */ +/* */ +/* OUT: none */ +/* */ +/* RETURN: */ +/* t_sva_tm_error: SVA_TM_OK */ +/* SVA_TM_BAD_FUNCTION_PARAMETER */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: no */ +/****************************************************************************/ +PUBLIC t_sva_tm_error sva_TM_InitSubTaskField( + t_sva_tm_subtask_id subtaskId, + t_sva_tm_field_id fieldId, + t_logical_address sourceAddress, + t_size size) +{ + t_logical_address fieldLogicalAddress = 0; + t_logical_address destLogicalAddress = 0; + t_physical_address destPhysicalAddress = 0; + t_uint32 loopCounter = 0; + + t_uint8 * pDestBuffer = 0; + t_uint8 * pSrcBuffer = 0; + + HCL_DEBUG_ASSERT(sourceAddress != NULL); + + /* Get the field's logical address that stores physical dest buffer address */ + fieldLogicalAddress = (t_logical_address)subtaskId + sizeof(t_sva_tm_subtask_info) + sizeof(t_sva_subtask_link) + + (t_uint32)((t_uint8)((t_uint32)fieldId & (t_uint32)0xFF)) * sizeof(t_logical_address); + + destPhysicalAddress = *((t_physical_address *)fieldLogicalAddress) & (~MASK_BIT0); //remove EXT bit from physical address + if (sva_MM_PhysicalToLogicalAddress(destPhysicalAddress, &destLogicalAddress) != SVA_MM_OK) + return(SVA_TM_BAD_FUNCTION_PARAMETER); + + /* Calculate pointer to access data (source and destination) */ + pDestBuffer = (t_uint8 *)destLogicalAddress; + pSrcBuffer = (t_uint8 *)sourceAddress; + + /* Perform the copy */ + for (loopCounter = 0; loopCounter < size; loopCounter ++) + *pDestBuffer++ = *pSrcBuffer++; + + return(SVA_TM_OK); +} /* End of sva_TM_InitSubTaskField() function. */ + +/****************************************************************************/ +/* NAME: sva_TM_UpdateSubTaskField( */ +/* t_sva_tm_update_desc updateDesc, */ +/* t_sva_tm_subtask_id subtaskId, */ +/* t_sva_tm_field_id fieldId, */ +/* t_sva_field_command fieldCommand, */ +/* t_uint32 sourceAddress, */ +/* t_uint32 offset, */ +/* t_size size) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: This routine enables to fill or update a parameter memory */ +/* area of given field: */ +/* 2 methods allowed : > address.... */ +/* - provide the PHYSICAL address of the new buffer; use */ +/* "ADDRESS" command as "command" parameter. Offset and size */ +/* param ignored */ +/* > copy....... */ +/* - performs a copy from the source buffer to a memory area */ +/* linked to a given field (use "COPY" command) */ +/* LOGICAL address described in sourcebufferaddr */ +/* */ +/* PARAMETERS: */ +/* IN : - updateDesc: update descriptor (used for data semaphore management */ +/* to guarentee the subtask integrity */ +/* - subtaskId, subtask identifier */ +/* - fieldId, field identifer to update */ +/* - fieldCommand: command type to execute (COPY or ADDRESS) */ +/* - sourceAddress, address of data to copy in subtask structure */ +/* - offset, offset (in bytes) to apply from the base of param#1 data */ +/* structure */ +/* - size, size (in bytes) of data transfert */ +/* */ +/* OUT: none */ +/* */ +/* RETURN: */ +/* t_sva_tm_error: SVA_TM_OK */ +/* SVA_TM_BAD_FUNCTION_PARAMETER */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: no */ +/****************************************************************************/ +PUBLIC t_sva_tm_error sva_TM_UpdateSubTaskField( + t_sva_tm_update_desc updateDesc, + t_sva_tm_subtask_id subtaskId, + t_sva_tm_field_id fieldId, + t_sva_field_command fieldCommand, + t_uint32 sourceAddress, + t_uint32 offset, + t_size size) +{ + t_logical_address fieldLogicalAddress = 0; + t_logical_address destLogicalAddress = 0; + t_physical_address destPhysicalAddress = 0; + + t_uint32 loopCounter = 0; + t_uint8 * pSourceAddress = 0; + t_uint8 * pDestAddress = 0; + + t_sva_tm_error tmErrorCode = SVA_TM_OK; + t_sva_mm_error mmErrorCode = SVA_MM_OK; + + t_sva_tm_subtask_info *pSubtaskInfo = (t_sva_tm_subtask_info *)subtaskId; + + /* At first, take semaphore if required. */ + if ( (updateDesc == SVA_TM_ONLY_ONE_FIELD_TO_UPDATE) || + (updateDesc == SVA_TM_FIRST_FIELD_TO_UPDATE) ) + { + sva_TM_HW_LockSemaphore(pSubtaskInfo->taskId); + } + + /* Get the field's logical address that stores physical dest buffer address */ + fieldLogicalAddress = (t_logical_address)subtaskId + sizeof(t_sva_tm_subtask_info) + sizeof(t_sva_subtask_link) + + (t_uint32)((t_uint8)((t_uint32)fieldId & (t_uint32)0xFF)) * sizeof(t_logical_address); + + if (FCMD_COPY == fieldCommand) + { + destPhysicalAddress = *((t_physical_address *)fieldLogicalAddress) & (~MASK_BIT0); //remove EXT bit from physical address + mmErrorCode = sva_MM_PhysicalToLogicalAddress(destPhysicalAddress, &destLogicalAddress); + + destLogicalAddress += offset; + + pSourceAddress = (t_uint8 *)sourceAddress; + pDestAddress = (t_uint8 *)destLogicalAddress; + } + + if (mmErrorCode != SVA_MM_OK) + { + tmErrorCode = SVA_TM_BAD_FUNCTION_PARAMETER; + } + else + { + switch (fieldCommand) + { + case FCMD_COPY : + for (loopCounter = 0; loopCounter < size; loopCounter ++) + *pDestAddress++ = *pSourceAddress++; + break; + case FCMD_NEW_ADDRESS : + *((t_uint32 *)fieldLogicalAddress) = sourceAddress; + break; + default : + tmErrorCode = SVA_TM_BAD_FUNCTION_PARAMETER; + break; + } /* switch (fieldCommand) */ + } + + /* At last, release semaphore if required */ + if ( (updateDesc == SVA_TM_ONLY_ONE_FIELD_TO_UPDATE) || + (updateDesc == SVA_TM_LAST_FIELD_TO_UPDATE) ) + { + sva_TM_HW_UnlockSemaphore(pSubtaskInfo->taskId); + } + + return(tmErrorCode); +} /* End of sva_TM_UpdateSubTaskField() function */ + + + +// vk changes: abort +PUBLIC t_sva_tm_subtask_list_info * sva_TM_GetOnePendingAbortRequest(t_sva_tm_task_id taskId) +{ + t_sva_tm_subtask_list_info *p_sva_tm_subtask_list_info = (t_sva_tm_subtask_list_info *)HwTasksInfos[taskId].firstSubtaskListId; + + if (p_sva_tm_subtask_list_info == (void*)INVALID_SUBTASK_LIST_ID || p_sva_tm_subtask_list_info == NULL) + { + /* no abort request found */ + return NULL; + } + + /* iterate till finish */ + while(1) + { + if (p_sva_tm_subtask_list_info->is_abort_requested == TRUE) + { + return p_sva_tm_subtask_list_info; + } + + if (p_sva_tm_subtask_list_info == (t_sva_tm_subtask_list_info *)HwTasksInfos[taskId].lastSubtaskListId) + { + break; + } + + /* increment */ + p_sva_tm_subtask_list_info = (t_sva_tm_subtask_list_info *)p_sva_tm_subtask_list_info->nextSubtasklistId; + } + + /* no abort request found */ + return NULL; +} + +PUBLIC void sva_TM_HW_TestToEmulateHWInterrupt(t_sva_tm_task_id taskId, t_uint32 *hwIad, t_uint32 *hwIsr, t_uint32 *hwIts, t_sva_tm_subtask_id subtask_id_to_convert); +PUBLIC t_sva_tm_error sva_TM_TestToEmulateHWInterrupt(t_sva_tm_task_id taskId, t_uint32 *hwIad, t_uint32 *hwIsr, t_uint32 *hwIts) +{ + t_sva_tm_subtask_list_info *p_sva_tm_subtask_list_info; + p_sva_tm_subtask_list_info = sva_TM_GetOnePendingAbortRequest(taskId); + + if (p_sva_tm_subtask_list_info == NULL) + { + /* no pending abort request present, do normal processing as earlier */ + return SVA_TM_OK; + } + + /* just forward this to hardware */ + sva_TM_HW_TestToEmulateHWInterrupt(taskId, hwIad, hwIsr, hwIts, p_sva_tm_subtask_list_info->firstSubtaskId); + + /* re-request to have pending abort requested service subtasklist */ + p_sva_tm_subtask_list_info = sva_TM_GetOnePendingAbortRequest(taskId); + /* check here for still pending abort requests and generate abort if applicable */ + + if (p_sva_tm_subtask_list_info != NULL) + { + /* few service(s) is/are still waiting for its abort request completeion, give them next change by gernerating fake interrupts here */ + + if(sva_TM_CheckAndExecuteAbortRequests(taskId)) /**/ + { + /* if successfull hardware abort command has been sent to hardware */ + //sva_TM_HW_SendTaskCommand(pListInfo->taskId, SVA_TM_TCMD_ABORT, param); + } + else + { + /* the current executing subtask is not requested abort, they are different so..*/ + /* ask for a fake interrupt to give another change to get one of them aborted by error */ + //sva_TM_HW_GenerateFake(taskId); + //sva_TM_HW_SendTaskCommand(taskId, SVA_TM_TCMD_START, 0); + } + } + + return SVA_TM_OK; +} + +// Hardware event stuff +/****************************************************************************/ +/* NAME: sva_TM_DispatchHWEvent( */ +/* t_uint32 hwIad, */ +/* t_uint32 hwIsr, */ +/* t_uint32 hwIts, */ +/* t_uint32 hwReg1, */ +/* t_uint32 hwReg2, */ +/* t_uint8 maxOfEvent, */ +/* t_sva_virtual_hw_event_desc *pVirtualEventDesc, */ +/* t_uint32 *pNbOfVirtualHwEvent) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: This routine dispatches the hardware events that have just */ +/* occured. */ +/* */ +/* PARAMETERS: */ +/* IN : - hwIad, physical interrupt address register */ +/* - hwIsr, interrupt status register */ +/* - hwIts, interrupt time stamp register */ +/* - hwReg1,additional register value (according to TaskId) */ +/* - Only used for "SVA_TM_GRAB" (R/W packet IT status register) */ +/* - hwReg2,additional register value (according to TaskId) */ +/* - Only used for "SVA_TM_GRAB" (R/W packet IT error register) */ +/* - maxOfEvent, max available free space in the virtual hardware event*/ +/* data structure to fill. */ +/* - pVirtualEventDesc, pointer of first element of event data */ +/* structure to fill. */ +/* - pNbOfVirtualHwEvent, pointer to the number of element filled */ +/* */ +/* OUT: none */ +/* */ +/* RETURN: */ +/* t_sva_tm_error: SVA_TM_OK */ +/* SVA_TM_BAD_FUNCTION_PARAMETER */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: no */ +/****************************************************************************/ +PUBLIC t_sva_tm_error sva_TM_DispatchHWEvent( + t_sva_tm_task_id taskId, + t_uint32 hwIad, + t_uint32 hwIsr, + t_uint32 hwIts, + t_uint32 hwReg1, + t_uint32 hwReg2, + t_uint8 maxOfEvent, + t_sva_tm_virtual_hw_event_desc *pVirtualEventDesc, + t_uint32 *pNbOfVirtualHwEvent) +{ + t_sva_tm_virtual_hw_event_desc *pCurrentVirtualEventDesc; + t_logical_address hwTasklogicalAddress; + t_uint32 remainingEventToFill; + t_sva_tm_error tmErrorCode; + + t_sva_tm_virtual_hw_event_id virtualHwEvent = SVA_TM_NO_HW_EVENT; + t_bool isTVOTaskEnding = FALSE; + t_uint32 newVirtualHwEvent = 0; + /* Filter the unused iad fields. */ + t_uint32 hwIadRegister = hwIad & (~MASK_BIT0); + + /* Filter the unused isr fields. */ + /* - SVA_TM_ACK_HW_EVENT is not managed by this level. */ + /* - SVA_TM_EOK_HW_EVENT always virtually generated accoding to state */ + /* changes. */ + t_uint32 hwIsrRegister = hwIsr & ~(SVA_TM_ACK_HW_EVENT | SVA_TM_EOK_HW_EVENT); + +#ifdef __DEBUG + evtTMHwDebugTable[taskId].hwEventDebugDesc[evtTMHwDebugTable[taskId].nbOfElement%TM_LOG_DEPTH].Iad = hwIad; + evtTMHwDebugTable[taskId].hwEventDebugDesc[evtTMHwDebugTable[taskId].nbOfElement%TM_LOG_DEPTH].Isr = hwIsr; + evtTMHwDebugTable[taskId].hwEventDebugDesc[evtTMHwDebugTable[taskId].nbOfElement%TM_LOG_DEPTH].Its = hwIts; + sva_TI_GetCurrentTicksValue (&evtTMHwDebugTable[taskId].hwEventDebugDesc[evtTMHwDebugTable[taskId].nbOfElement%TM_LOG_DEPTH].timeInTicks); + evtTMHwDebugTable[taskId].lastElementPos = evtTMHwDebugTable[taskId].nbOfElement % TM_LOG_DEPTH; + if ((t_sva_tm_virtual_hw_event_id)(hwIsrRegister) & SVA_TM_BOT_HW_EVENT) + evtTMHwDebugTable[taskId].lastBOTtime = hwIts; + if ((TM_TRACK_SUBTASK_DURATION == TRUE) && ((t_sva_tm_virtual_hw_event_id)(hwIsrRegister) & SVA_TM_EOT_HW_EVENT)) + evtTMHwDebugTable[taskId].hwEventDebugDesc[evtTMHwDebugTable[taskId].nbOfElement%TM_LOG_DEPTH].subtaskDuration = + (t_uint32)(((hwIts - evtTMHwDebugTable[taskId].lastBOTtime) * 1000) / 90); + else + evtTMHwDebugTable[taskId].hwEventDebugDesc[evtTMHwDebugTable[taskId].nbOfElement%TM_LOG_DEPTH].subtaskDuration = 0; + evtTMHwDebugTable[taskId].nbOfElement++; +#endif /* __DEBUG */ + + HCL_DEBUG_ASSERT(pVirtualEventDesc!=NULL); + HCL_DEBUG_ASSERT(pNbOfVirtualHwEvent!=NULL); + + pCurrentVirtualEventDesc = pVirtualEventDesc; + *pNbOfVirtualHwEvent = 0; + remainingEventToFill = maxOfEvent; + if((hwIsr & SVA_TM_EOT_HW_EVENT)!=0) + { + Last_IAD_EOT_ERR[taskId] = hwIad; + } + + if (taskId == SVA_TM_TVO) + { + if(((hwIsr & SVA_TM_EOF1_HW_EVENT)!=0) || ((hwIsr & SVA_TM_EOF2_HW_EVENT)!=0)) + { + Last_IAD_EOT_ERR[taskId] = hwIad; + } + } + + if ((hwIsr & SVA_TM_EOK_HW_EVENT) != 0) + { + if ((hwIsr & SVA_TM_ERR_HW_EVENT) == 0) + { + if (TaskState[taskId] != SVA_TM_HW_ABORTING) + { + if(Last_IAD_EOT_ERR[taskId] != hwIad) + { + HCL_ASSERT(0); + } + } + } + } + + if((hwIsr & SVA_TM_ERR_HW_EVENT)!=0) + { + Last_IAD_ERR[taskId] = hwIad; + } + + if((hwIsr & SVA_TM_EOK_HW_EVENT)!= 0) + { + if ((hwIsr & SVA_TM_ERR_HW_EVENT)== 0) + { + if(Last_IAD_EOT_ERR[taskId] != hwIad) + { + if (TaskState[taskId] != SVA_TM_HW_ABORTING) + { + HCL_ASSERT(0); + } + hwIsr = hwIsr | SVA_TM_ABORT_HW_EVENT; + hwIsrRegister = hwIsrRegister | SVA_TM_ABORT_HW_EVENT; + Last_IAD_EOT_ERR[taskId] = hwIad; + } + } + } + /*@BORT_$TOP*/ + + if((hwIsr & SVA_TM_EOK_HW_EVENT)!=0) + { + Last_IAD_EOT_ERR[taskId] = hwIad; + } + + /* At first, propagate the interrupt to lower level of task management */ + sva_TM_HW_DispatchHWEvent(taskId, hwIad, hwIsr, hwIts); + + + + + + /* Here, check special case of TVO service ending. */ + if (taskId==SVA_TM_TVO && ListInfo[SVA_TM_TVO][0].state==SVA_TM_STOPPING && (hwIsr & SVA_TM_EOK_HW_EVENT)) + { + isTVOTaskEnding = TRUE; + } + + /* Here, check special case of Irp interrupt though EOF bit mask. */ + if (taskId==SVA_TM_GRAB && (hwIsrRegister & SVA_TM_EOF_HW_EVENT)) + { + t_sva_tm_subtask_list_info *pListInfo; + + /* Check a command had been sent for this interrupt. */ + HCL_DEBUG_ASSERT(GlobalInfos.irpPacketSubtaskListId != INVALID_SUBTASK_LIST_ID); + + pListInfo = (t_sva_tm_subtask_list_info *)GlobalInfos.irpPacketSubtaskListId; + newVirtualHwEvent = 0; + + /* Check GRB_IRP_ERROR report. (grpIrpError of t_sva_irq_private_status */ + if ( (hwReg2 != 0) && (pListInfo->eventMask & SVA_TM_PACKET_ERROR_HW_EVENT) ) + { + newVirtualHwEvent |= SVA_TM_PACKET_ERROR_HW_EVENT; + } + + /* Check GRB_IRP_RWIRP report (grpIrpRw of t_sva_irq_private_status */ + if (hwReg1 != 0) + { + if (hwReg1 == SVA_TM_IRP_WRITE_COMPLETED && (pListInfo->eventMask & SVA_TM_PACKET_WRITE_HW_EVENT)) + { + newVirtualHwEvent |= SVA_TM_PACKET_WRITE_HW_EVENT; + } + else if (hwReg1 == SVA_TM_IRP_READ_COMPLETED && (pListInfo->eventMask & SVA_TM_PACKET_READ_HW_EVENT)) + { + newVirtualHwEvent |= SVA_TM_PACKET_READ_HW_EVENT; + } + } + + if ( (newVirtualHwEvent != 0) && (remainingEventToFill >= 1) ) + { + pCurrentVirtualEventDesc->serviceId = pListInfo->serviceId; + pCurrentVirtualEventDesc->subtaskId = INVALID_SUBTASK_ID; + pCurrentVirtualEventDesc->virtualEventIdMask = (t_sva_tm_virtual_hw_event_id)((t_uint32)newVirtualHwEvent); + pCurrentVirtualEventDesc->eventTimestamp = sva_TI_ConvertTicksToSystemTime(pListInfo->serviceId, hwIts); + pCurrentVirtualEventDesc->eventDate = hwIts; + pCurrentVirtualEventDesc->extraInfos = hwReg2; +#ifdef __DEBUG + evtTMVirtualDebugTable[taskId].virtualEventDebugDesc[evtTMVirtualDebugTable[taskId].nbOfElement%TM_LOG_DEPTH].taskId = taskId; + evtTMVirtualDebugTable[taskId].virtualEventDebugDesc[evtTMVirtualDebugTable[taskId].nbOfElement%TM_LOG_DEPTH].serviceId = pCurrentVirtualEventDesc->serviceId; + evtTMVirtualDebugTable[taskId].virtualEventDebugDesc[evtTMVirtualDebugTable[taskId].nbOfElement%TM_LOG_DEPTH].subtaskId = pCurrentVirtualEventDesc->subtaskId; + evtTMVirtualDebugTable[taskId].virtualEventDebugDesc[evtTMVirtualDebugTable[taskId].nbOfElement%TM_LOG_DEPTH].virtualEvents = (t_sva_tm_virtual_hw_event_id)(pCurrentVirtualEventDesc->virtualEventIdMask); + sva_TI_GetCurrentTicksValue (&evtTMVirtualDebugTable[taskId].virtualEventDebugDesc[evtTMVirtualDebugTable[taskId].nbOfElement%TM_LOG_DEPTH].timeInTicks); + evtTMVirtualDebugTable[taskId].lastElementPos = evtTMVirtualDebugTable[taskId].nbOfElement % TM_LOG_DEPTH; + evtTMVirtualDebugTable[taskId].nbOfElement++; +#endif /* __DEBUG */ + + *pNbOfVirtualHwEvent = *pNbOfVirtualHwEvent + 1; + pCurrentVirtualEventDesc ++; + remainingEventToFill --; + } + + /* Reset current active SubtaskListId beause R/W received. */ + if (hwReg1 != 0) + GlobalInfos.irpPacketSubtaskListId = INVALID_SUBTASK_LIST_ID; + + /* Reset the bit source of the interrupt so that it's handled after.*/ + hwIsrRegister &= ~SVA_TM_EOF_HW_EVENT; + } + + /* Test if iad is valid (i.e. if we can retrive subtask address). */ + /* and relevant hw interrupt to manage. */ + if ((hwIadRegister != 0) && (hwIsrRegister != 0) || isTVOTaskEnding == TRUE) + { + t_sva_tm_subtask_list_info * pListInfo; + t_sva_tm_subtask_info * pSubtaskInfo = 0; + t_sva_tm_subtask_id removedSubtaskId; + + /* Retrieve the subtaslList and subtask concernend by this interrupt. */ + if (sva_MM_PhysicalToLogicalAddress( hwIadRegister, &hwTasklogicalAddress) != SVA_MM_OK) + return(SVA_TM_BAD_FUNCTION_PARAMETER); + + pSubtaskInfo = (t_sva_tm_subtask_info *)( (t_uint32)(hwTasklogicalAddress) - sizeof(t_sva_tm_subtask_info)); + pListInfo = (t_sva_tm_subtask_list_info *)(pSubtaskInfo->subtaskListId); + + /* Here, check the iad is correct in term of : */ + /* - it behaves to a subtaskList */ + /* - it's the first subtask of the subtaskList */ + + /* This assert can't be done like that !!! The atomicity number has to */ + /* used and checked. */ + if (taskId != SVA_TM_TVO) + { + if (hwIsrRegister & SVA_TM_ERR_HW_EVENT) + { + HCL_DEBUG_ASSERT(pSubtaskInfo->subtaskListId != INVALID_SUBTASK_LIST_ID); + } + else + { + HCL_DEBUG_ASSERT(pSubtaskInfo->subtaskListId != INVALID_SUBTASK_LIST_ID && pListInfo->firstSubtaskId == (t_sva_tm_subtask_id)pSubtaskInfo ); + } + } + + /* Get interrupts .. */ + virtualHwEvent = (t_sva_tm_virtual_hw_event_id)((t_uint32)hwIsrRegister); + newVirtualHwEvent = (t_uint32)virtualHwEvent; + + + /* Update internal state and new event to generate... */ + if (virtualHwEvent & SVA_TM_ERR_HW_EVENT) + { + /* An error is detected. Clear all scheduled subtasks but keep it in the subtask list !!! */ + /* PS : the HW task management will also unschedule all subtask for this service. */ + sva_TM_markAsUnscheduledAllSubtasks (pListInfo); + + if (sva_TM_isTransitionValid (pListInfo, SVA_TM_ERR_INTERRUPT) == TRUE) + { + sva_TM_UpdateInstanceStateMachine(pListInfo, SVA_TM_ERR_INTERRUPT, &newVirtualHwEvent); + } +#ifdef __FW_WORK_AROUND_NO_EOT_WITH_ERR + /* Sometimes, there's an EOT associated with this err. It should not be !!! */ + /* So erase it. */ + virtualHwEvent = (t_sva_tm_virtual_hw_event_id)(virtualHwEvent & (~SVA_TM_EOT_HW_EVENT)); + newVirtualHwEvent &= (t_uint32)(~SVA_TM_EOT_HW_EVENT); +#endif /* __FW_WORK_AROUND_NO_EOT_WITH_ERR */ + + /* Do not removed all subtask from the list has hwTaskManagement will do it by itself, */ + /* and upper layer (i.e. service) will remove manually all of it thanks to function */ + /* sva_TM_RemoveElemFromSubTaskList() call. */ + } + + if (virtualHwEvent & SVA_TM_BOT_HW_EVENT) + { + if (sva_TM_isTransitionValid (pListInfo, SVA_TM_BOT_INTERRUPT) == TRUE) + sva_TM_UpdateInstanceStateMachine(pListInfo, SVA_TM_BOT_INTERRUPT, &newVirtualHwEvent); + } + + if (virtualHwEvent & SVA_TM_EOT_HW_EVENT) + { + /* Look for the last subtask inserted in hardware list. */ + if ( (pSubtaskInfo->nextSubtaskId == INVALID_SUBTASK_ID) || + ((pSubtaskInfo->nextSubtaskId != INVALID_SUBTASK_ID) && + (((t_sva_tm_subtask_info *)(pSubtaskInfo->nextSubtaskId))->subtaskState != SVA_TM_SCHECULED)) ) + { + if (sva_TM_isTransitionValid (pListInfo, SVA_TM_LAST_EOT_INTERRUPT) == TRUE) + sva_TM_UpdateInstanceStateMachine(pListInfo, SVA_TM_LAST_EOT_INTERRUPT, &newVirtualHwEvent); + } + else + { + if (sva_TM_isTransitionValid (pListInfo, SVA_TM_EOT_INTERRUPT) == TRUE) + sva_TM_UpdateInstanceStateMachine(pListInfo, SVA_TM_EOT_INTERRUPT, &newVirtualHwEvent); + } + /* remove it from our list. */ + sva_TM_removeFirstSubtaskFromSubtaskList ( (t_sva_tm_subtask_list_id)(pListInfo), + &removedSubtaskId); + + /* As a subtask is removed from a subtask list, try to schedule a new one. */ + sva_TM_PrepareSchedule(); + } + + /* Here, check special case of TVO service ending. */ + if (isTVOTaskEnding) + if (sva_TM_isTransitionValid (pListInfo, SVA_TM_LAST_EOT_INTERRUPT) == TRUE) + sva_TM_UpdateInstanceStateMachine(pListInfo, SVA_TM_LAST_EOT_INTERRUPT, &newVirtualHwEvent); + + /* Filter virtual event to send to upper layer. */ + newVirtualHwEvent &= pSubtaskInfo->eventMask; + + + /* Now build virtual hardware events... */ + if (remainingEventToFill >= 1) + { + pCurrentVirtualEventDesc->serviceId = pListInfo->serviceId; + pCurrentVirtualEventDesc->subtaskId = (t_sva_tm_subtask_id)(pSubtaskInfo); + pCurrentVirtualEventDesc->virtualEventIdMask = (t_sva_tm_virtual_hw_event_id)((t_uint32)newVirtualHwEvent); + pCurrentVirtualEventDesc->eventTimestamp = sva_TI_ConvertTicksToSystemTime(pListInfo->serviceId, hwIts); + pCurrentVirtualEventDesc->eventDate = hwIts; + pCurrentVirtualEventDesc->extraInfos = 0; + +#ifdef __DEBUG + if (newVirtualHwEvent != 0) + { + evtTMVirtualDebugTable[taskId].virtualEventDebugDesc[evtTMVirtualDebugTable[taskId].nbOfElement%TM_LOG_DEPTH].taskId = taskId; + evtTMVirtualDebugTable[taskId].virtualEventDebugDesc[evtTMVirtualDebugTable[taskId].nbOfElement%TM_LOG_DEPTH].serviceId = pCurrentVirtualEventDesc->serviceId; + evtTMVirtualDebugTable[taskId].virtualEventDebugDesc[evtTMVirtualDebugTable[taskId].nbOfElement%TM_LOG_DEPTH].subtaskId = pCurrentVirtualEventDesc->subtaskId; + evtTMVirtualDebugTable[taskId].virtualEventDebugDesc[evtTMVirtualDebugTable[taskId].nbOfElement%TM_LOG_DEPTH].virtualEvents = (t_sva_tm_virtual_hw_event_id)((t_uint32)pCurrentVirtualEventDesc->virtualEventIdMask); + sva_TI_GetCurrentTicksValue (&evtTMVirtualDebugTable[taskId].virtualEventDebugDesc[evtTMVirtualDebugTable[taskId].nbOfElement%TM_LOG_DEPTH].timeInTicks); + evtTMVirtualDebugTable[taskId].lastElementPos = evtTMVirtualDebugTable[taskId].nbOfElement % TM_LOG_DEPTH; + evtTMVirtualDebugTable[taskId].nbOfElement++; + } +#endif /* __DEBUG */ + + *pNbOfVirtualHwEvent = *pNbOfVirtualHwEvent + 1; + pCurrentVirtualEventDesc ++; + remainingEventToFill --; + } + else + return(SVA_TM_BAD_FUNCTION_PARAMETER); + + + } /* hwIadRegister != 0 */ + + /* Now check if there's a pending firmware to be downloaded. */ + if ( (GlobalInfos.fwState == SVA_TM_FW_CHANGING) && (GlobalInfos.nbScheduledSubtask == 0) ) + { + t_sva_fm_error fmErrCode; +// t_uint32 eventMask; + + + fmErrCode = sva_FM_Download (GlobalInfos.fwIdActive); + HCL_DEBUG_ASSERT(fmErrCode==SVA_FM_OK); + + + /*@BORT-$TOP*/ + /* + + Get the Garbage Value of Last_IAD_EOT_ERR + + */ + + + + /* Change our state machine with a EOI event Mask as output for all hw Tasks. */ + tmErrorCode = sva_TM_DispatchEvent (TRUE, SVA_TM_NO_TASK, SVA_TM_EOI_INTERRUPT, &remainingEventToFill, + pNbOfVirtualHwEvent, pCurrentVirtualEventDesc, hwIts); + HCL_DEBUG_ASSERT(tmErrorCode == SVA_TM_OK); + + /* Enable all video irq sources */ + SVA_EnableIRQSrc (SVA_IRQ); + + /* WARNING : Resetting the firmware leads to resetting all interrupt mask register !*/ + /* We have to set all of it (i.e. all subtask types) before going ahead !!! */ + sva_TM_RecheckHwInterrupts(); + + /* Update global firmware state so that pending subtask can be scheduled again. */ + GlobalInfos.fwState = SVA_TM_FW_LOADED; + /* And now, try to schedule those possible pending subtask. */ + sva_TM_PrepareSchedule(); + + /* And in case there's no pending subtask, generate a fake interrupt on Display */ + /* taskId (never mind as it will be propagated to all task Id) */ + /* PS: if any subtask has just been scheduled, no problem as HW TM will filter it. */ + sva_TM_HW_GenerateFake(SVA_TM_DISPLAY); + } + else + { + /* Whatever the case, dispatch a "dummy" hardware event for all subtask lists */ + tmErrorCode = sva_TM_DispatchEvent (TRUE, SVA_TM_NO_TASK, SVA_TM_DUMMY_INTERRUPT, &remainingEventToFill, + pNbOfVirtualHwEvent, pCurrentVirtualEventDesc, hwIts); + HCL_DEBUG_ASSERT(tmErrorCode == SVA_TM_OK); + } +// pVirtualEventDesc = pCurrentVirtualEventDesc; + +/*@ORT-$TOP*/ + /* Test if iad is valid (i.e. if we can retrive subtask address). */ + /* and relevant hw interrupt to manage. */ + if ((hwIadRegister != 0) && (hwIsrRegister != 0) || isTVOTaskEnding == TRUE) + { + t_sva_tm_subtask_list_info * pListInfo; + t_sva_tm_subtask_info * pSubtaskInfo = 0; + //t_sva_tm_subtask_id removedSubtaskId; + + /* Retrieve the subtaslList and subtask concernend by this interrupt. */ + if (sva_MM_PhysicalToLogicalAddress( hwIadRegister, &hwTasklogicalAddress) != SVA_MM_OK) + return(SVA_TM_BAD_FUNCTION_PARAMETER); + + pSubtaskInfo = (t_sva_tm_subtask_info *)( (t_uint32)(hwTasklogicalAddress) - sizeof(t_sva_tm_subtask_info)); + pListInfo = (t_sva_tm_subtask_list_info *)(pSubtaskInfo->subtaskListId); + + /* Update internal state and new event to generate... */ + if (virtualHwEvent & SVA_TM_ABORT_HW_EVENT) + { + /* An error is detected. Clear all scheduled subtasks but keep it in the subtask list !!! */ + /* PS : the HW task management will also unschedule all subtask for this service. */ + if(pListInfo !=(void*) INVALID_SUBTASK_LIST_ID) + { + while(1) + { + if(pListInfo->previousSubtasklistId == INVALID_SUBTASK_LIST_ID) break; + pListInfo = (t_sva_tm_subtask_list_info*)pListInfo->previousSubtasklistId; + } + + while(1) + { + if(pListInfo->state == SVA_TM_ABORTING) + { + sva_TM_markAsUnscheduledAllSubtasks (pListInfo); + + if (sva_TM_isTransitionValid (pListInfo, SVA_TM_ABORT_INTERRUPT) == TRUE) //Think again if it FALSE + { + sva_TM_UpdateInstanceStateMachine(pListInfo, SVA_TM_ABORT_INTERRUPT, &newVirtualHwEvent); + } + else + { + HCL_ASSERT (0); + } + } + + if (pListInfo->nextSubtasklistId == INVALID_SUBTASK_LIST_ID) + { + break; + } + pListInfo = (t_sva_tm_subtask_list_info*)pListInfo->nextSubtasklistId; + } + } + } + } +/*@ORT-$TOP*/ + + return(SVA_TM_OK); +} /* End of sva_TM_DispatchHWEvent() function. */ + +/****************************************************************************/ +/* NAME: sva_TM_DispatchHWEvent(void) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: This routine dispatches the "end of firmware initialization */ +/* code execution" hardware event */ +/* */ +/* PARAMETERS: */ +/* IN : none */ +/* */ +/* OUT: none */ +/* */ +/* RETURN: */ +/* t_sva_tm_error: SVA_TM_OK */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: no */ +/****************************************************************************/ +PUBLIC t_sva_tm_error sva_TM_DispatchEOIEvent( void ) +{ + + return(SVA_TM_OK); +} /* End of sva_TM_DispatchEOIEvent() function. */ + +// Virtual Hardware event stuff +/****************************************************************************/ +/* NAME: sva_TM_EnableVirtualHwEvents( */ +/* t_sva_tm_subtasklist_id subtaskListId, */ +/* t_sva_virtual_hw_event_id virtualHwEvent) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: This routine enables a given virtual hardware event */ +/* */ +/* PARAMETERS: */ +/* IN : - subtaskListId, subtask list identifier */ +/* - virtualHwEvent, virtual hardware event to enable */ +/* */ +/* OUT: none */ +/* */ +/* RETURN: */ +/* t_sva_tm_error: SVA_TM_OK */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: no */ +/****************************************************************************/ +PUBLIC t_sva_tm_error sva_TM_EnableVirtualHwEvents( + t_sva_tm_subtasklist_id subtaskListId, + t_sva_tm_virtual_hw_event_id virtualHwEvent) +{ + t_sva_tm_subtask_list_info *pListInfo = (t_sva_tm_subtask_list_info *)subtaskListId; + + if ( ((pListInfo->activationState == SVA_TM_ACTIVATED)||(pListInfo->activationState == SVA_TM_ACTIVATING)) + && (virtualHwEvent <= SVA_TM_EOK_HW_EVENT) && !(pListInfo->eventMask & virtualHwEvent) ) + { + /* The service is either under activation, either already activated. If not already done */ + /* enable corresponding HW event (if any) to lower level. */ + sva_TM_CheckAndSetHwInterrupts (pListInfo, virtualHwEvent); + } + + /* Special case for Irp engine. Enabling R/W/Err virtual event should enable "EOF" interrupt */ + if ( ((pListInfo->activationState == SVA_TM_ACTIVATED)||(pListInfo->activationState == SVA_TM_ACTIVATING)) + && !(pListInfo->eventMask & virtualHwEvent) ) + { + if ((virtualHwEvent & (SVA_TM_PACKET_READ_HW_EVENT|SVA_TM_PACKET_WRITE_HW_EVENT|SVA_TM_PACKET_ERROR_HW_EVENT)) != 0) + { + if ((pListInfo->eventMask & (SVA_TM_PACKET_READ_HW_EVENT|SVA_TM_PACKET_WRITE_HW_EVENT|SVA_TM_PACKET_ERROR_HW_EVENT)) == 0) + /* First time one of those virtual events is activated. Enalble the Hardware interrupt EOF */ + sva_TM_CheckAndSetHwInterrupts (pListInfo, SVA_TM_EOF_HW_EVENT); + } + } + + /* Save locally the virtual hardware events. */ + pListInfo->eventMask |= (t_uint32)virtualHwEvent; + + return(SVA_TM_OK); +} /* End of sva_TM_EnableVirtualHwEvents() function. */ + +/****************************************************************************/ +/* NAME: sva_TM_DisableVirtualHwEvents( */ +/* t_sva_tm_subtasklist_id subtaskListId, */ +/* t_sva_virtual_hw_event_id virtualHwEvent) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: This routine disables a given virtual hardware event */ +/* */ +/* PARAMETERS: */ +/* IN : - subtaskListId, subtask list identifier */ +/* - virtualHwEvent, virtual hardware event to disable */ +/* */ +/* OUT: none */ +/* */ +/* RETURN: */ +/* t_sva_tm_error: SVA_TM_OK */ +/* SVA_TM_BAD_FUNCTION_PARAMETER */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: no */ +/****************************************************************************/ +PUBLIC t_sva_tm_error sva_TM_DisableVirtualHwEvents( + t_sva_tm_subtasklist_id subtaskListId, + t_sva_tm_virtual_hw_event_id virtualHwEvent) +{ + t_sva_tm_subtask_list_info * pListInfo = (t_sva_tm_subtask_list_info *)subtaskListId; + + if ( ((pListInfo->activationState == SVA_TM_ACTIVATED)||(pListInfo->activationState == SVA_TM_ACTIVATING)) + && (virtualHwEvent <= SVA_TM_EOK_HW_EVENT) && (pListInfo->eventMask & virtualHwEvent) ) + { + /* The service is either under activation, either already activated. If not already done */ + /* disable corresponding HW event (if any) to lower level. */ + sva_TM_CheckAndResetHwInterrupts (pListInfo, virtualHwEvent); + } + + /* Special case for Irp engine. Disabling R/W/Err virtual event should disable "EOF" interrupt */ + if ( ((pListInfo->activationState == SVA_TM_ACTIVATED)||(pListInfo->activationState == SVA_TM_ACTIVATING)) + && (pListInfo->eventMask & virtualHwEvent) ) + { + if ( (virtualHwEvent & (SVA_TM_PACKET_READ_HW_EVENT|SVA_TM_PACKET_WRITE_HW_EVENT|SVA_TM_PACKET_ERROR_HW_EVENT)) != 0) + { + if ( (pListInfo->eventMask & (SVA_TM_PACKET_READ_HW_EVENT|SVA_TM_PACKET_WRITE_HW_EVENT|SVA_TM_PACKET_ERROR_HW_EVENT)) == 0) + /* Last time one of those virtual events is deactivated. Disable the Hardware interrupt EOF */ + sva_TM_CheckAndResetHwInterrupts (pListInfo, SVA_TM_EOF_HW_EVENT); + } + } + + /* Save locally the virtual gardware events. */ + pListInfo->eventMask &= ~(t_uint32)virtualHwEvent; + + return(SVA_TM_OK); +} /* End of sva_TM_DisableVirtualHwEvents() function. */ + +/****************************************************************************/ +/* NAME: sva_TM_EnableAllVirtualHwEvents( */ +/* t_sva_tm_subtasklist_id subtaskListId) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: This routine enables all virtual hardware event */ +/* */ +/* PARAMETERS: */ +/* IN : - subtaskListId, subtask list identifier */ +/* */ +/* OUT: none */ +/* */ +/* RETURN: */ +/* t_sva_tm_error: SVA_TM_OK */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: no */ +/****************************************************************************/ +PUBLIC t_sva_tm_error sva_TM_EnableAllVirtualHwEvents( + t_sva_tm_subtasklist_id subtaskListId) +{ + t_uint32 eventMask = 1; + + while (eventMask <= (t_uint32)SVA_TM_LAST_HW_EVENT) + { + sva_TM_EnableVirtualHwEvents (subtaskListId, (t_sva_tm_virtual_hw_event_id) eventMask); + eventMask <<= 1; + } /* while ... */ + + return(SVA_TM_OK); +} /* End of sva_TM_EnableAllVirtualHwEvents() function. */ + +/****************************************************************************/ +/* NAME: sva_TM_DisableAllVirtualHwEvents( */ +/* t_sva_tm_subtasklist_id subtaskListId, */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: This routine disables all virtual hardware event */ +/* */ +/* PARAMETERS: */ +/* IN : - subtaskListId, subtask list identifier */ +/* */ +/* OUT: none */ +/* */ +/* RETURN: */ +/* t_sva_tm_error: SVA_TM_OK */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: no */ +/****************************************************************************/ +PUBLIC t_sva_tm_error sva_TM_DisableAllVirtualHwEvents( + t_sva_tm_subtasklist_id subtaskListId) +{ + t_uint32 eventMask = 1; + + while (eventMask <= (t_uint32)SVA_TM_LAST_HW_EVENT) + { + sva_TM_DisableVirtualHwEvents (subtaskListId, (t_sva_tm_virtual_hw_event_id) eventMask); + eventMask <<= 1; + } /* while ... */ + + return(SVA_TM_OK); +} /* End of sva_TM_DisableAllVirtualHwEvents() function. */ + + +/****************************************************************************/ +/* **************** Private functions **************** */ +/****************************************************************************/ + +/****************************************************************************/ +/* NAME: t_bool sva_TM_isTransitionValid( */ +/* t_sva_tm_subtask_list_info *pListInfo, */ +/* t_sva_tm_list_transition requestedTransition */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine checks if the requestedTransition is valid for both */ +/* state machine */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - pListInfo : subtask list informations pointer */ +/* - requestedTransition: identifier of the requested transition */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: t_bool */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PRIVATE t_bool sva_TM_isTransitionValid +( + t_sva_tm_subtask_list_info *pListInfo, + t_sva_tm_list_transition requestedTransition +) +{ + t_sva_tm_list_state nextState; + t_sva_tm_list_activation_state nextActivateState; + + HCL_DEBUG_ASSERT(pListInfo!=NULL && pListInfo != (void*)INVALID_SUBTASK_LIST_ID); + + /* Compute the next state for both state machine*/ + nextState = StateMachine[pListInfo->state][requestedTransition].state; + nextActivateState = activateStateMachine[pListInfo->activationState][requestedTransition].state; + + /*return false in case of invalid transition for at least one state machine*/ + if ( (nextState != SVA_TM_TRANSITION_REJECTED) && + (nextActivateState != SVA_TM_ACTIVATE_TRANSITION_REJECTED) ) + return(TRUE); + else + return(FALSE); + +} /* End of sva_TM_isTransitionValid() function. */ + +/****************************************************************************/ +/* NAME: t_sva_tm_list_state sva_TM_UpdateInstanceStateMachine( */ +/* t_sva_tm_subtask_list_info *pListInfo, */ +/* t_sva_tm_list_transition requestedTransition */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine allows to update both state machine */ +/* following the given requestedTransition and propose a virtual */ +/* hardware event to simulate. */ +/* */ +/* N.B: This routine returns the new state after the requested transition */ +/* A special return state (SVA_TM_TRANSITION_REJECTED) is used to check */ +/* the validity of a transition request */ +/* */ +/* ASSUMPTIONS : */ +/* Tne *pNewEvents data is updated but not set (i.e. it's not reset */ +/* at beginning of the function. */ +/* PARAMETERS: */ +/* IN : */ +/* - pListInfo : subtask list informations pointer */ +/* - requestedTransition: identifier of the requested transition */ +/* - pNewEvents : pointer ot new event to generate (i.e. virtual) */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: t_sva_tm_list_state */ +/* - one of the t_sva_gb_state */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PRIVATE t_sva_tm_list_state sva_TM_UpdateInstanceStateMachine +( + t_sva_tm_subtask_list_info *pListInfo, + t_sva_tm_list_transition requestedTransition, + t_uint32 *pNewEvents +) +{ + t_sva_tm_list_state nextState; + t_sva_tm_list_activation_state nextActivateState; + + HCL_DEBUG_ASSERT(pListInfo!=NULL); + HCL_DEBUG_ASSERT(pNewEvents!=NULL); + + /* Compute the next state for both state machine*/ + nextState = StateMachine[pListInfo->state][requestedTransition].state; + nextActivateState = activateStateMachine[pListInfo->activationState][requestedTransition].state; + + *pNewEvents |= StateMachine[pListInfo->state][requestedTransition].mask; + *pNewEvents |= activateStateMachine[pListInfo->activationState][requestedTransition].mask; + + if ( (nextState != SVA_TM_TRANSITION_REJECTED) && (nextActivateState != SVA_TM_ACTIVATE_TRANSITION_REJECTED) ) + { + /* Update both current state of the instance */ + pListInfo->state = nextState; + pListInfo->activationState = nextActivateState; +#ifdef __DEBUG + transitionTMDebugTable[pListInfo->taskId].transitionDebugDesc[transitionTMDebugTable[pListInfo->taskId].nbOfElement%TM_LOG_DEPTH].activationState = (t_sva_tm_list_activation_state)nextActivateState; + transitionTMDebugTable[pListInfo->taskId].transitionDebugDesc[transitionTMDebugTable[pListInfo->taskId].nbOfElement%TM_LOG_DEPTH].state = (t_sva_tm_list_state)nextState; + transitionTMDebugTable[pListInfo->taskId].transitionDebugDesc[transitionTMDebugTable[pListInfo->taskId].nbOfElement%TM_LOG_DEPTH].transition = requestedTransition; + transitionTMDebugTable[pListInfo->taskId].transitionDebugDesc[transitionTMDebugTable[pListInfo->taskId].nbOfElement%TM_LOG_DEPTH].virtualHwEvent = (t_sva_tm_virtual_hw_event_id)(*pNewEvents); + sva_TI_GetCurrentTicksValue (&transitionTMDebugTable[pListInfo->taskId].transitionDebugDesc[transitionTMDebugTable[pListInfo->taskId].nbOfElement%TM_LOG_DEPTH].timeInTicks); + transitionTMDebugTable[pListInfo->taskId].lastElementPos = transitionTMDebugTable[pListInfo->taskId].nbOfElement % TM_LOG_DEPTH; + transitionTMDebugTable[pListInfo->taskId].nbOfElement++; +#endif /* __DEBUG */ + } + return ((t_sva_tm_list_state)nextState); + +} /* End of sva_TM_UpdateInstanceStateMachine() function. */ + +/****************************************************************************/ +/* NAME: t_sva_tm_error sva_TM_markAsUnscheduledAllSubtasks( */ +/* t_sva_tm_subtask_list_info *pListInfo */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine modify all subtasks from SVA_TM_SCHECULED state to */ +/* SVA_TM_READY_TO_SCHEDULE state */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - pListInfo : subtask list informations pointer */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_tm_error: SVA_TM_OK */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PRIVATE t_sva_tm_error sva_TM_markAsUnscheduledAllSubtasks (t_sva_tm_subtask_list_info *pListInfo) +{ + t_sva_tm_subtask_id subtaskId; + t_sva_tm_subtask_info *pSubtaskInfo; + + HCL_DEBUG_ASSERT(pListInfo!=NULL); + + subtaskId = pListInfo->firstSubtaskId; + + while (subtaskId != INVALID_SUBTASK_ID) + { + pSubtaskInfo = (t_sva_tm_subtask_info *)subtaskId; + if (pSubtaskInfo->subtaskState == SVA_TM_SCHECULED) + { + pSubtaskInfo->subtaskState = SVA_TM_READY_TO_SCHEDULE; + if (HwTasksInfos[pListInfo->taskId].nbScheduledSubtask != 0) + { + DECREASE(HwTasksInfos[pSubtaskInfo->taskId].nbScheduledSubtask); + DECREASE(GlobalInfos.nbScheduledSubtask) + } + } + subtaskId = ((t_sva_tm_subtask_info *)(subtaskId))->nextSubtaskId; + } + + return(SVA_TM_OK); +} /* End of sva_TM_markAsUnscheduledAllSubtasks() function. */ + +/****************************************************************************/ +/* NAME: t_sva_tm_error sva_TM_removeFirstSubtaskFromSubtaskList( */ +/* t_sva_tm_subtask_list_id subtaskListId */ +/* t_sva_tm_subtask_id *subtaskId */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine removes the first subtask loaded subtask list. */ +/* */ +/* PARAMETERS: */ +/* IN : - subtaskListId: subtask list Id */ +/* */ +/* OUT: - pSubtaskId: pointer to subtask identifier removed from the list */ +/* */ +/* RETURN: */ +/* t_sva_tm_error: SVA_TM_OK */ +/* SVA_TM_NO_MORE_SUBTASK_DESC */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PRIVATE t_sva_tm_error sva_TM_removeFirstSubtaskFromSubtaskList ( + t_sva_tm_subtask_list_id subtaskListId, + t_sva_tm_subtask_id *pSubtaskId) +{ + t_sva_tm_subtask_list_info *pListInfo = (t_sva_tm_subtask_list_info *)subtaskListId; + t_sva_tm_subtask_info *pSubtaskInfo; + + HCL_DEBUG_ASSERT(pSubtaskId!=NULL); + + /* Default case, invalid subtask Id */ + *pSubtaskId = INVALID_SUBTASK_ID; + + if (pListInfo->nbSubtask != 0) + { + if (pListInfo->firstSubtaskId != INVALID_SUBTASK_ID) + { + pSubtaskInfo = (t_sva_tm_subtask_info *)(pListInfo->firstSubtaskId); + + if (pSubtaskInfo->nextSubtaskId != INVALID_SUBTASK_ID) + ((t_sva_tm_subtask_info *)(pSubtaskInfo->nextSubtaskId))->previousSubtaskId + = INVALID_SUBTASK_ID; + + pListInfo->firstSubtaskId = pSubtaskInfo->nextSubtaskId; + + pSubtaskInfo->subtaskListId = INVALID_SUBTASK_LIST_ID; + pSubtaskInfo->nextSubtaskId = INVALID_SUBTASK_ID; + pSubtaskInfo->previousSubtaskId = INVALID_SUBTASK_ID; + + if (pSubtaskInfo->subtaskState == SVA_TM_SCHECULED) + { + DECREASE(HwTasksInfos[pSubtaskInfo->taskId].nbScheduledSubtask); + DECREASE(GlobalInfos.nbScheduledSubtask) + } + pSubtaskInfo->subtaskState = SVA_TM_UNDEFINED_STATE; + + pListInfo->nbSubtask --; + if (pListInfo->nbSubtask == 0) + /* No more element in the subtask list. */ + pListInfo->lastSubtaskId = INVALID_SUBTASK_ID; + } + else + { + /* Error case. Reset the subtask counter. */ + pListInfo->nbSubtask = 0; + return(SVA_TM_NO_MORE_SUBTASK_DESC); + } + } + else + return(SVA_TM_NO_MORE_SUBTASK_DESC); + + *pSubtaskId = (t_sva_tm_subtask_id)pSubtaskInfo; + + return(SVA_TM_OK); +} /* End of sva_TM_removeFirstSubtaskFromSubtaskList() function. */ + +/****************************************************************************/ +/* NAME: t_sva_tm_error sva_TM_PrepareSchedule() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine performes the insertion of a logical subtask into the */ +/* hardware list according to subtaskList content. */ +/* It should be called when : */ +/* - inserting a new subtask in the subtask list */ +/* - starting a subtask list */ +/* - removing a scheduled subtask (i.e. EOT mgt) */ +/* - activating a subtask list (dummy event mgt) */ +/* */ +/* PS : Second step implementation : Basic Multi-instance support (only */ +/* immediat mode supported). For a specific HW subtask type, this */ +/* function scans each subtaslist and check if a schedule is required */ +/* and which logical subtask will scheduled. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - none */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_tm_error: SVA_TM_OK */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PRIVATE t_sva_tm_error sva_TM_PrepareSchedule (void) +{ + t_uint32 hwTaskLoopCpt = 0; + t_sva_tm_subtask_list_id currentSubtaskListId; + t_uint32 nbScheduledSubtask; + t_sva_tm_subtask_list_id initialSubtaskListId; + t_bool actionPerformedInLoop = FALSE; + + /* Test if a firmware is currently dowladed. If so, try to schedule a new subtask. */ + if (GlobalInfos.fwState == SVA_TM_FW_LOADED) + { + /* Scan all possible hw tasks... */ + for (hwTaskLoopCpt = 0; hwTaskLoopCpt < SVA_TM_NB_HW_TASK; hwTaskLoopCpt ++) + { + if ( (HwTasksInfos[hwTaskLoopCpt].nbCreatedSubtaskLists != 0) && + (HwTasksInfos[hwTaskLoopCpt].nbScheduledSubtask < SVA_TM_NB_MAX_SCHEDULED_SUBTASK) ) + { + /* Get the initial subtaskListId to be scanned (use currentSubtaskListId variable */ + /* in order to make code more clear. */ + + currentSubtaskListId = HwTasksInfos[hwTaskLoopCpt].lastSubtaskListIdScanned; + +#ifdef __DEBUG + scheduleTMDebugTable[hwTaskLoopCpt].scheduleTrace[scheduleTMDebugTable[hwTaskLoopCpt].nbOfElement%TM_LOG_DEPTH].initialSubtaskListId = currentSubtaskListId; +#endif + + if (currentSubtaskListId == INVALID_SUBTASK_LIST_ID || + ((t_sva_tm_subtask_list_info *)(currentSubtaskListId))->nextSubtasklistId == INVALID_SUBTASK_LIST_ID ) { + initialSubtaskListId = HwTasksInfos[hwTaskLoopCpt].firstSubtaskListId; } + else { + initialSubtaskListId = ((t_sva_tm_subtask_list_info *)(currentSubtaskListId))->nextSubtasklistId;} + + /* Use currentSubtaskListId as loop counter. */ + currentSubtaskListId = initialSubtaskListId; +#ifdef __DEBUG + scheduleTMDebugTable[hwTaskLoopCpt].scheduleTrace[scheduleTMDebugTable[hwTaskLoopCpt].nbOfElement%TM_LOG_DEPTH].modifiedInitialSubtaskListId = initialSubtaskListId; + scheduleTMDebugTable[hwTaskLoopCpt].scheduleTrace[scheduleTMDebugTable[hwTaskLoopCpt].nbOfElement%TM_LOG_DEPTH].scheduledSubtaskList = INVALID_SUBTASK_LIST_ID; + scheduleTMDebugTable[hwTaskLoopCpt].scheduleTrace[scheduleTMDebugTable[hwTaskLoopCpt].nbOfElement%TM_LOG_DEPTH].nbScheduledSubtask = 0xFFFFFFFF; + scheduleTMDebugTable[hwTaskLoopCpt].scheduleTrace[scheduleTMDebugTable[hwTaskLoopCpt].nbOfElement%TM_LOG_DEPTH].nbTotalScheduledSubtask = GlobalInfos.nbScheduledSubtask; + scheduleTMDebugTable[hwTaskLoopCpt].lastElementPos = scheduleTMDebugTable[hwTaskLoopCpt].nbOfElement % TM_LOG_DEPTH; + scheduleTMDebugTable[hwTaskLoopCpt].nbOfElement++; +#endif + do + { + actionPerformedInLoop = FALSE; + do + { + if (sva_TM_ScheduleSubtaskInSubtaskList((t_sva_tm_subtask_list_info *)(currentSubtaskListId), + &nbScheduledSubtask) == SVA_TM_OK){ + /* subtasks have been scheduled. Increment the total amount of it */ + HwTasksInfos[hwTaskLoopCpt].nbScheduledSubtask += nbScheduledSubtask; + /* And global counter too. */ + GlobalInfos.nbScheduledSubtask += nbScheduledSubtask; + actionPerformedInLoop = TRUE; +#ifdef __DEBUG + scheduleTMDebugTable[hwTaskLoopCpt].scheduleTrace[scheduleTMDebugTable[hwTaskLoopCpt].nbOfElement%TM_LOG_DEPTH].initialSubtaskListId = INVALID_SUBTASK_LIST_ID; + scheduleTMDebugTable[hwTaskLoopCpt].scheduleTrace[scheduleTMDebugTable[hwTaskLoopCpt].nbOfElement%TM_LOG_DEPTH].modifiedInitialSubtaskListId = INVALID_SUBTASK_LIST_ID; + scheduleTMDebugTable[hwTaskLoopCpt].scheduleTrace[scheduleTMDebugTable[hwTaskLoopCpt].nbOfElement%TM_LOG_DEPTH].scheduledSubtaskList = currentSubtaskListId; + scheduleTMDebugTable[hwTaskLoopCpt].scheduleTrace[scheduleTMDebugTable[hwTaskLoopCpt].nbOfElement%TM_LOG_DEPTH].nbScheduledSubtask = nbScheduledSubtask; + scheduleTMDebugTable[hwTaskLoopCpt].scheduleTrace[scheduleTMDebugTable[hwTaskLoopCpt].nbOfElement%TM_LOG_DEPTH].nbTotalScheduledSubtask = HwTasksInfos[hwTaskLoopCpt].nbScheduledSubtask; + scheduleTMDebugTable[hwTaskLoopCpt].lastElementPos = scheduleTMDebugTable[hwTaskLoopCpt].nbOfElement % TM_LOG_DEPTH; + scheduleTMDebugTable[hwTaskLoopCpt].nbOfElement++; +#endif + /* Save last subtaskList scanned so that during next Prepare, the next subtask*/ + HwTasksInfos[hwTaskLoopCpt].lastSubtaskListIdScanned = currentSubtaskListId; + } + + /* Get the next subtaskListId to be scanned... */ + currentSubtaskListId = ((t_sva_tm_subtask_list_info *)(currentSubtaskListId))->nextSubtasklistId; + if (currentSubtaskListId == INVALID_SUBTASK_LIST_ID) + /* The last subtaskListId of the list is reached. Take the first one instead. */ + currentSubtaskListId = HwTasksInfos[hwTaskLoopCpt].firstSubtaskListId; + + } while ( currentSubtaskListId != initialSubtaskListId && HwTasksInfos[hwTaskLoopCpt].nbScheduledSubtask < SVA_TM_NB_MAX_SCHEDULED_SUBTASK ); + + } while ( (actionPerformedInLoop) && + (HwTasksInfos[hwTaskLoopCpt].nbScheduledSubtask < SVA_TM_NB_MAX_SCHEDULED_SUBTASK) ); + + /* Save last subtaskList scanned so that during next Prepare, the next subtask*/ +// HwTasksInfos[hwTaskLoopCpt].lastSubtaskListIdScanned = currentSubtaskListId; + } + } /* for (hwTaskLoopCpt....) */ + } /* if (GlobalInfos.fwState == SVA_TM_FW_LOADED) */ + return(SVA_TM_OK); +} /* End of sva_TM_PrepareSchedule() function. */ + +/****************************************************************************/ +/* NAME: t_sva_tm_error sva_TM_ScheduleSubtaskInSubtaskList( */ +/* t_sva_tm_subtask_list_id subtaskListId */ +/* t_sva_tm_subtask_id *pSubtaskId */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine looks for the last unscheduled subtask in a specified */ +/* subtask list, and insert it into the hardware list. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - pListInfo : subtask list informations pointer */ +/* - nbScheduledSubtask : Number of scheduled subtasks */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_tm_error: SVA_TM_OK : one subtask has been scheduled. */ +/* SVA_TM_NO_MORE_SUBTASK_DESC */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PRIVATE t_sva_tm_error sva_TM_ScheduleSubtaskInSubtaskList ( + t_sva_tm_subtask_list_info * pListInfo, t_uint32 * pNbScheduledSubtask) +{ + t_sva_tm_subtask_id subtaskId; + t_sva_tm_subtask_id searchSubtaskId; + t_bool scheduleDone = FALSE; + t_sva_tm_error tmErrorCode = SVA_TM_NO_MORE_SUBTASK_DESC; + + HCL_DEBUG_ASSERT(pListInfo!=NULL); + HCL_DEBUG_ASSERT(pNbScheduledSubtask!=NULL); + + *pNbScheduledSubtask = 0; + + if ( (pListInfo->state == SVA_TM_RUNNING) && (pListInfo->activationState == SVA_TM_ACTIVATED) ) + { + subtaskId = pListInfo->firstSubtaskId; + while ( (subtaskId!=INVALID_SUBTASK_ID) && (!scheduleDone) ) + { + if (((t_sva_tm_subtask_info *)(subtaskId))->subtaskState == SVA_TM_READY_TO_SCHEDULE) + { + /* It's not alone. Check if all subtasks that are to be scheduled together */ + /* are inside the subtaskList. */ + + searchSubtaskId = subtaskId; + while ( searchSubtaskId != INVALID_SUBTASK_ID && + ((t_sva_tm_subtask_info *)(searchSubtaskId))->atomicityNumber != 1) + { + searchSubtaskId = ((t_sva_tm_subtask_info *)(searchSubtaskId))->nextSubtaskId; + } + + if (searchSubtaskId != INVALID_SUBTASK_ID && + ((t_sva_tm_subtask_info *)(searchSubtaskId))->atomicityNumber == 1) + { + /* Insert all atomic subTasks. */ + do + { + ((t_sva_tm_subtask_info *)(subtaskId))->subtaskState = SVA_TM_SCHECULED; + sva_TM_HW_InsertImmediat (subtaskId); + (*pNbScheduledSubtask) += 1; + if ( ((t_sva_tm_subtask_info *)(subtaskId))-> atomicityNumber == 1) + /* It's the last to be scheduled */ + scheduleDone = TRUE; + + subtaskId = ((t_sva_tm_subtask_info *)(subtaskId))->nextSubtaskId; + tmErrorCode = SVA_TM_OK; + } while ( scheduleDone != TRUE ); + } + /* Exit from the main loop. */ + scheduleDone = TRUE; + } + else + subtaskId = ((t_sva_tm_subtask_info *)(subtaskId))->nextSubtaskId; + } /* while ... */ + } + return(tmErrorCode); + +} /* End of sva_TM_ScheduleSubtaskInSubtaskList(). */ + +/****************************************************************************/ +/* NAME: t_sva_tm_error sva_TM_DispatchEvent( */ +/* t_bool isDispatchAllHwTasks, */ +/* t_sva_tm_task_id taskId, */ +/* t_sva_tm_list_transition transition, */ +/* t_uint32 *pRemainingEventToFill, */ +/* t_uint32 *pNbOfVirtualHwEvent, */ +/* t_sva_tm_virtual_hw_event_desc * pVirtualEventDesc, */ +/* t_uint32 hwIts) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine allow the dispatch of a specific transtion to either */ +/* all subtask lists of a hw task, either all subtask list of all hw */ +/* task */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - isDispatchAllHwTasks : determine if ALL hw task are impacted by */ +/* the requested transition. */ +/* - taskId : in case of isDispatchAllHwTasks is false, dispatch the */ +/* transition only to this hw task */ +/* - transition : transition to be dispatched. */ +/* - pRemainingEventToFill : pointer to available event to be filled */ +/* - pNbOfVirtualHwEvent : pointer to number of event filled */ +/* - pVirtualEventDesc : pointer to event data structure */ +/* - hwIts : Hardware interrupt time stamp top be reported with event */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_tm_error: SVA_TM_OK */ +/* SVA_TM_NO_MORE_EVENT_DESC */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + * line : pVirtualEventDesc->subtaskId = pListInfo->firstSubtaskId; to be confirmed !!!! +*/ +PRIVATE t_sva_tm_error sva_TM_DispatchEvent ( + t_bool isDispatchAllHwTasks, + t_sva_tm_task_id taskId, + t_sva_tm_list_transition transition, + t_uint32 *pRemainingEventToFill, + t_uint32 *pNbOfVirtualHwEvent, + t_sva_tm_virtual_hw_event_desc * pVirtualEventDesc, + t_uint32 hwIts + ) +{ + t_bool activationDone = FALSE; + t_uint8 hwTaskLoopCounterStart; + t_uint8 hwTaskLoopCounterEnd; + t_uint8 hwTaskLoopCounter; + + HCL_DEBUG_ASSERT(pRemainingEventToFill!=NULL); + HCL_DEBUG_ASSERT(pNbOfVirtualHwEvent!=NULL); + HCL_DEBUG_ASSERT(pVirtualEventDesc!=NULL); + + if (isDispatchAllHwTasks == TRUE) { + hwTaskLoopCounterStart = 0; + hwTaskLoopCounterEnd = SVA_TM_NB_HW_TASK-1;} + else { + hwTaskLoopCounterStart = (t_uint8)taskId; + hwTaskLoopCounterEnd = (t_uint8)taskId;} + + for (hwTaskLoopCounter = hwTaskLoopCounterStart; hwTaskLoopCounter <= hwTaskLoopCounterEnd; hwTaskLoopCounter ++) + { + t_sva_tm_virtual_hw_event_id newVirtualHwEvent; + t_sva_tm_subtask_list_info * pListInfo; + t_uint8 srvNb; + + pListInfo = &ListInfo[hwTaskLoopCounter][0]; + srvNb = (t_uint8)(HwTasksInfos[hwTaskLoopCounter].nbCreatedSubtaskLists); + + while ( (srvNb != 0) && (*pRemainingEventToFill != 0) ) + { + if (pListInfo->serviceId != 0) + { + srvNb --; + newVirtualHwEvent = SVA_TM_NO_HW_EVENT; + + if (sva_TM_isTransitionValid (pListInfo, transition) == TRUE) + { + sva_TM_UpdateInstanceStateMachine(pListInfo, transition, (t_uint32 *)&newVirtualHwEvent); + if (newVirtualHwEvent != SVA_TM_NO_HW_EVENT) + { + /* Test if there are still space to store event descriptions. */ + if (*pRemainingEventToFill == 0) + return(SVA_TM_NO_MORE_EVENT_DESC); + + /* Test if it's an activation. */ + if (newVirtualHwEvent & SVA_TM_ACTIVE_HW_EVENT) + activationDone = TRUE; + + /* New virtual hardware event to export. */ + pVirtualEventDesc->serviceId = pListInfo->serviceId; + pVirtualEventDesc->subtaskId = pListInfo->firstSubtaskId; /* TBC */ + pVirtualEventDesc->virtualEventIdMask = (t_sva_tm_virtual_hw_event_id)newVirtualHwEvent; + pVirtualEventDesc->eventTimestamp = sva_TI_ConvertTicksToSystemTime(pListInfo->serviceId, hwIts); + pVirtualEventDesc->eventDate = hwIts; + pVirtualEventDesc->extraInfos = 0; + #ifdef __DEBUG + evtTMVirtualDebugTable[pListInfo->taskId].virtualEventDebugDesc[evtTMVirtualDebugTable[pListInfo->taskId].nbOfElement%TM_LOG_DEPTH].taskId = pListInfo->taskId; + evtTMVirtualDebugTable[pListInfo->taskId].virtualEventDebugDesc[evtTMVirtualDebugTable[pListInfo->taskId].nbOfElement%TM_LOG_DEPTH].serviceId = pVirtualEventDesc->serviceId; + evtTMVirtualDebugTable[pListInfo->taskId].virtualEventDebugDesc[evtTMVirtualDebugTable[pListInfo->taskId].nbOfElement%TM_LOG_DEPTH].subtaskId = pVirtualEventDesc->subtaskId; + evtTMVirtualDebugTable[pListInfo->taskId].virtualEventDebugDesc[evtTMVirtualDebugTable[pListInfo->taskId].nbOfElement%TM_LOG_DEPTH].virtualEvents = (t_sva_tm_virtual_hw_event_id)(pVirtualEventDesc->virtualEventIdMask); + sva_TI_GetCurrentTicksValue (&evtTMVirtualDebugTable[pListInfo->taskId].virtualEventDebugDesc[evtTMVirtualDebugTable[pListInfo->taskId].nbOfElement%TM_LOG_DEPTH].timeInTicks); + evtTMVirtualDebugTable[pListInfo->taskId].lastElementPos = evtTMVirtualDebugTable[pListInfo->taskId].nbOfElement % TM_LOG_DEPTH; + evtTMVirtualDebugTable[pListInfo->taskId].nbOfElement++; + #endif /* __DEBUG */ + + *pRemainingEventToFill = *pRemainingEventToFill - 1; + *pNbOfVirtualHwEvent = *pNbOfVirtualHwEvent + 1; + pVirtualEventDesc ++; + } + } + } + pListInfo ++; + } /* while (srvNb != 0) */ + } /* for ... */ + + /* Check if a subtask list has just been activated and try to schedule its subtasks */ + if (activationDone) + sva_TM_PrepareSchedule(); + + return(SVA_TM_OK); +} /* End of sva_TM_DispatchEvent() function. */ + +/****************************************************************************/ +/* NAME: t_sva_tm_error sva_TM_CheckAndSetHwInterrupts( */ +/* t_sva_tm_subtask_list_info *pListInfo, */ +/* t_uint32 newMask) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine manages specific interrupt source counters in order */ +/* to activate or not corresponding hardware interrupt. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - pListInfo : subtask list informations pointer */ +/* - newMask : Mask of interrupts to be activated */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_tm_error: SVA_TM_OK */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PRIVATE t_sva_tm_error sva_TM_CheckAndSetHwInterrupts ( + t_sva_tm_subtask_list_info *pListInfo, + t_uint32 newMask) +{ + t_uint8 bitPosition; + + HCL_DEBUG_ASSERT(pListInfo!=NULL); + + for (bitPosition = 0; bitPosition < 8 ; bitPosition ++) + { + if ((1UL<taskId].hwEventMasks[bitPosition] = + (t_uint32)(HwTasksInfos[pListInfo->taskId].hwEventMasks[bitPosition] + 1); + } + } + /* Optimization : Enable all required interrupts. */ + sva_TM_HW_EnableTaskInterrupt(pListInfo->taskId, (t_sva_tm_hw_event_id)newMask); + + return(SVA_TM_OK); + +} /* End of sva_TM_CheckAndSetHwInterrupts() function. */ + +/****************************************************************************/ +/* NAME: t_sva_tm_error sva_TM_RecheckHwInterrupts(void) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine check if a hw interrupt has to be set according to */ +/* global hw interrupt bit counters. */ +/* */ +/* PARAMETERS: */ +/* IN : none */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_tm_error: SVA_TM_OK */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PUBLIC t_sva_tm_error sva_TM_RecheckHwInterrupts (void) +{ + t_uint8 hwTskCpt; + t_uint8 bitPosition; + + for (hwTskCpt=0; hwTskCpttaskId].hwEventMasks[bitPosition] == 0) + { + /* Do nothing hwEventMasks is already Zero */ + } + else + { + HwTasksInfos[pListInfo->taskId].hwEventMasks[bitPosition] = + (t_uint32)(HwTasksInfos[pListInfo->taskId].hwEventMasks[bitPosition] - 1); + } + + if (HwTasksInfos[pListInfo->taskId].hwEventMasks[bitPosition] == 0) + sva_TM_HW_DisableTaskInterrupt(pListInfo->taskId, (t_sva_tm_hw_event_id)((1UL<. */ +/*---------------------------------------------------------------------------*/ + +#ifndef __INC_SVA_TASKMGT_H +#define __INC_SVA_TASKMGT_H + +#include "hcl_defs.h" +#include "sva_memorymgt.h" +#include "sva_fwmgt.h" +#include "sva_host_interface.h" +#include "svap.h" +#include "sva.h" +#include "sva_hwp.h" +#include "sva_timemgt.h" + +/******************************************************************************/ +/* Constants definitions */ +/******************************************************************************/ + +/*------------------------------------------------------------------------ + * Defines + *----------------------------------------------------------------------*/ + +#define INTERNAL_MEM_EXT_BIT 0 +#define EXTERNAL_MEM_EXT_BIT 1 + + + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/******************************************************************************/ +/* Types definitions */ +/******************************************************************************/ + + + +typedef t_uint32 t_sva_tm_subtask_id; //0 is reserved +typedef t_uint32 t_sva_tm_subtasklist_id; //0 is reserved + +/* + * Define the special invalid value for t_sva_tm_subtask_id variables + */ +#define INVALID_SUBTASK_ID MASK_ALL32 +#define INVALID_SUBTASK_LIST_ID MASK_ALL32 + + +typedef struct { + t_uint16 sizetoallocate; //in BYTES + t_sva_memory_id memId; //field Memory Id +} t_sva_tm_alloc_desc; + +typedef struct { + t_uint8 fieldtoreference; //used only if reference command: start at 0 + t_uint32 subtaskidtoreference; //used only if reference command +} t_sva_tm_ref_desc; + +typedef union { + t_sva_tm_alloc_desc allocDesc; + t_sva_tm_ref_desc refDesc; +} t_sva_tm_command_desc; + +typedef enum { + SVA_TM_DCMD_ALLOCATE, + SVA_TM_DCMD_REFERENCE, + SVA_TM_DCMD_NULL, + SVA_TM_DCMD_DUMMY = ~(MASK_BIT31) +}t_sva_tm_mem_command; + +typedef struct { + t_sva_tm_mem_command command; + t_sva_tm_command_desc commandDesc; +}t_sva_tm_field_ctrl_desc; + +typedef struct { + t_sva_memory_id memId; // subtask Memory Id + t_uint8 fieldnb; // field number for a given subtask (depends on task type) + t_sva_tm_field_ctrl_desc *pfieldctrldesc;// points on an array of t_sva_field_ctrl_desc +}t_sva_tm_task_ctrl_desc; + + +typedef enum { + SVA_TM_ENCODE_MPEG4_SW =0x00, + SVA_TM_ENCODE_MPEG4_NO_SW =0x01, + SVA_TM_ENCODE_H263_SW =0x02, + SVA_TM_ENCODE_H263_NO_SW =0x03, + SVA_TM_IMAGE_STAB_SW =0x04, + SVA_TM_IMAGE_STAB_NO_SW =0x05, + SVA_TM_ENCODE_JPEG =0x06, + SVA_TM_ENCODE_H264 =0x07, + SVA_TM_ENCODE_MPEG4_NO_SW_RASTER_IN =0x08, + SVA_TM_IMAGE_STAB_NO_SW_RASTER_IN =0x09, + SVA_TM_ENCODE_JPEG_RASTER_IN =0x0A, + SVA_TM_ENCODE_JPEG_THUMBNAIL =0x0B, + SVA_TM_DECODE_MPEG4 =0x20, + SVA_TM_DECODE_H263 =0x21, + SVA_TM_DECODE_JPEG =0x22, + SVA_TM_DECODE_H264 =0x23, + SVA_TM_DECODE_VC1 =0x24, // dummy value TO BE UPDATED once fw specification frozen + SVA_TM_DECODE_MPEG4_RASTER_OUT =0x25, + SVA_TM_DECODE_H263_RASTER_OUT =0x26, + SVA_TM_DECODE_JPEG_NO_SLICE =0x27, + SVA_TM_DECODE_MPEG2 =0x28, + SVA_TM_GRAB_WITH_CACHE =0x40, + SVA_TM_GRAB_NO_CACHE =0x41, + SVA_TM_GRAB_WITH_SEP_COMP =0x42, //For JPEG encode + SVA_TM_GRAB_RAW_DATA =0x43, + SVA_TM_GRAB_SENSOR_NO_CACHE =0x44, + SVA_TM_GRAB_SENSOR_WITH_SEP_COMP =0x45, + SVA_TM_GRAB_CAMERA_RASTER_OUT =0x46, + SVA_TM_GRAB_SENSOR_RASTER_OUT =0x47, + SVA_TM_GRAB_SENSOR_HQ =0x4A, + SVA_TM_DISPLAY_NO_FILTERING =0x60, + SVA_TM_DISPLAY_MPEG4_DEBLOCKING =0x61, + SVA_TM_DISPLAY_MPEG4_DEBLOCKING_DERINGING =0x62, + SVA_TM_DISPLAY_H263_DEBLOCKING =0x63, + SVA_TM_DISPLAY_H263_DEBLOCKING_MPEG4_DERINGING =0x64, + SVA_TM_DISPLAY_MPEG4_DERINGING =0x65, + SVA_TM_DISPLAY_NO_FILTERING_RASTER_IN =0x66, + SVA_TM_DISPLAY_MPEG4_DEBLOCKING_RASTER_IN =0x67, + SVA_TM_DISPLAY_MPEG4_DEBLOCKING_DERINGING_RASTER_IN =0x68, + SVA_TM_DISPLAY_H263_DEBLOCKING_RASTER_IN =0x69, + SVA_TM_DISPLAY_H263_DEBLOCKING_MPEG4_DERINGING_RASTER_IN =0x6A, + SVA_TM_DISPLAY_MPEG4_DERINGING_RASTER_IN =0x6B, + SVA_TM_TVO_STANDARD =0x70 +}t_sva_tm_subtask_type; + +typedef enum { + SVA_TM_NO_POST_PROCESSING =0, + SVA_TM_DEBLOCKING_DERINGING_OUT_LOOP =1, // parameters are put in the deblocking param buffer and + // will be used by display task + SVA_TM_YUV420PL_TO_RGB =1, + SVA_TM_H263_DEBLOCKING_IN_LOOP =2, // parameters taken into account in the encode subtask + SVA_TM_YUV420MB_TO_YUV420MB =2, + SVA_TM_H263_DEBLOCKING_IN_LOOP_AND_DERINGING_OUT =3, // mix of the 2 first + SVA_TM_YUV420MB_TO_YUV_SEP_COMP_MB = 3 //YUV420MB-tiled to YUV420/422 MB-tiled Separate Component +}t_sva_tm_postprocessing_type; + +typedef enum { + SVA_TM_IMMEDIATE, + SVA_TM_RELATIVE, + SVA_TM_ABSOLUTE +}t_sva_tm_timestamp_type; + +typedef t_uint32 t_sva_tm_timestamp_value; + +typedef struct { + t_sva_tm_timestamp_type timestampType; + t_sva_tm_timestamp_value timestampValue; +}t_sva_tm_timestamp; + +typedef enum { + SVA_TM_NO_IT, + SVA_TM_BOT_EN, + SVA_TM_EOT_EN, + SVA_TM_BOT_EOT_EN +} t_sva_tm_bot_eot; + +typedef enum { + SVA_TM_NO_SYNCHRO, + SVA_TM_DISPLAY_VSYNC +}t_sva_tm_synchro; + +typedef enum { + SVA_TM_BBM_DEFAULT = 0, // Default mode for all services except decode/encode + SVA_TM_CIRCULAR_MODE = 0, // + SVA_TM_LINK_LIST_MODE +} t_sva_tm_bbm; + +typedef t_uint32 t_sva_tm_subtask_list_id; + +typedef enum { + // first digit references task / last digit references field position in the subtask structure + SVA_TM_SUBTASK_LINK =0x0000, + SVA_TM_DEC_ADDR_IN_FRAME_BUFFER =0x1000, + SVA_TM_DEC_ADDR_OUT_FRAME_BUFFER =0x1001, + SVA_TM_DEC_ADDR_INTERNAL_BUFFER =0x1002, + SVA_TM_DEC_ADDR_IN_BITSTREAM_BUFFER =0x1003, + SVA_TM_DEC_ADDR_OUT_BITSTREAM_BUFFER=0x1004, + SVA_TM_DEC_ADDR_IN_PARAMETERS =0x1005, + SVA_TM_DEC_ADDR_OUT_PARAMETERS =0x1006, + SVA_TM_DEC_ADDR_IN_FRAME_PARAMETERS =0x1007, + SVA_TM_DEC_ADDR_OUT_FRAME_PARAMETERS=0x1008, + SVA_TM_ENC_ADDR_IN_FRAME_BUFFER =0x2000, + SVA_TM_ENC_ADDR_OUT_FRAME_BUFFER =0x2001, + SVA_TM_ENC_ADDR_INTERNAL_BUFFER =0x2002, + SVA_TM_ENC_ADDR_IN_HEADER_BUFFER =0x2003, + SVA_TM_ENC_ADDR_IN_BITSTREAM_BUFFER =0x2004, + SVA_TM_ENC_ADDR_OUT_BITSTREAM_BUFFER=0x2005, + SVA_TM_ENC_ADDR_IN_PARAMETERS =0x2006, + SVA_TM_ENC_ADDR_OUT_PARAMETERS =0x2007, + SVA_TM_ENC_ADDR_IN_FRAME_PARAMETERS =0x2008, + SVA_TM_ENC_ADDR_OUT_FRAME_PARAMETERS=0x2009, + SVA_TM_GRB_ADDR_IN_FRAME_BUFFER =0x3000, + SVA_TM_GRB_ADDR_OUT_FRAME_BUFFER =0x3001, + SVA_TM_GRB_ADDR_INTERNAL_BUFFER =0x3002, + SVA_TM_GRB_ADDR_IN_PARAMETERS =0x3003, + SVA_TM_GRB_ADDR_OUT_PARAMETERS =0x3004, + SVA_TM_GRB_ADDR_IN_FRAME_PARAMETERS =0x3005, + SVA_TM_GRB_ADDR_OUT_FRAME_PARAMETERS=0x3006, + SVA_TM_DIS_ADDR_IN_FRAME_BUFFER =0x4000, + SVA_TM_DIS_ADDR_OUT_FRAME_BUFFER =0x4001, + SVA_TM_DIS_ADDR_INTERNAL_BUFFER =0x4002, + SVA_TM_DIS_ADDR_IN_PARAMETERS =0x4003, + SVA_TM_DIS_ADDR_OUT_PARAMETERS =0x4004, + SVA_TM_DIS_ADDR_IN_FRAME_PARAMETERS =0x4005, + SVA_TM_DIS_ADDR_OUT_FRAME_PARAMETERS=0x4006, + + + SVA_TM_TVO_ADDR_IN_FRAME_BUFFER =0x5000, + SVA_TM_TVO_ADDR_INIT_PARAMETERS =0x5001, + SVA_TM_TVO_ADDR_IN_PARAMETERS =0x5002 +}t_sva_tm_field_id; + +typedef enum { + FCMD_COPY, + FCMD_NEW_ADDRESS +}t_sva_field_command; + +typedef enum { +/* Enum, Associated data structures, Notes */ + SVA_TM_TCMD_STOP, /* N.A., None */ + SVA_TM_TCMD_START, /* t_sva_tm_timestamp, start conditions of the subtask */ + SVA_TM_TCMD_ABORT, /* N.A., None */ + SVA_TM_TCMD_FAKE_EVENT, /* N.A., None */ + SVA_TM_TCMD_STOP_SLICE, /* N.A., None */ + SVA_TM_TCMD_UPDATE_BUFFER, /* N.A., None */ + SVA_TM_TCMD_STOP_PHYSICAL, /* N.A., None */ + SVA_TM_TCMD_READ_PACKET, /* t_physical_address, physical address of packet to read */ + SVA_TM_TCMD_WRITE_PACKET, /* t_physical_address, physical address of packet to write */ + SVA_TM_TCMD_SAVE_VPIP_STATE,/* t_physical_address, physical address to save VPIP */ + SVA_TM_TCMD_LOAD_VPIP_STATE,/* t_physical_address, physical address to load VPIP */ + SVA_TM_TCMD_GRABHQ_STATUS, /* Grab HQ read status */ + SVA_TM_TCMD_GRABHQ_TST, + SVA_TM_TCMD_GRABHQ_READ_NB_FAILURE_BML_PROCESS +}t_sva_tm_task_cmd_id; + +typedef enum { + SVA_TM_ENCODE, + SVA_TM_DECODE, + SVA_TM_GRAB, + SVA_TM_DISPLAY, + SVA_TM_TVO, + SVA_TM_NO_TASK +}t_sva_tm_task_id; + +typedef enum { + SVA_TM_ONLY_ONE_FIELD_TO_UPDATE, // only one field to update to have a coherent subtask + // semaphore locked when UpdatexSubtaskField starts and unlocked when function ends + SVA_TM_FIRST_FIELD_TO_UPDATE, // semaphore locked when UpdatexSubtaskField starts (no unlock) + SVA_TM_INTERMEDIATE_FIELD_TO_UPDATE,// no semaphore lock or unlock + SVA_TM_LAST_FIELD_TO_UPDATE // semaphore not locked but unlocked when function ends +}t_sva_tm_update_desc; + +/* Virtual hardware event management. */ +typedef struct { + t_sva_service_id serviceId; + t_sva_tm_subtask_id subtaskId; + t_uint32 virtualEventIdMask; + t_sva_timestamp_value eventTimestamp; + t_sva_timestamp_value eventDate; + t_uint32 extraInfos; +} t_sva_tm_virtual_hw_event_desc; + +/*@BORT-$TOP*/ +//ADD SVA_TM_ABORT_HW_EVENT + +typedef enum { + SVA_TM_NO_HW_EVENT = MASK_NULL32, + SVA_TM_BOT_HW_EVENT = ISR_BOT_MASK, + SVA_TM_EOT_HW_EVENT = ISR_EOT_MASK, + SVA_TM_ACK_HW_EVENT = ISR_ACK_MASK, + SVA_TM_EOW_HW_EVENT = ISR_EOW_MASK, + SVA_TM_BOF_HW_EVENT = ISR_BOF_MASK, + SVA_TM_EOF1_HW_EVENT = ISR_EOF1_MASK, + SVA_TM_UBU_HW_EVENT = ISR_UBU_MASK, + SVA_TM_GS_HW_EVENT = ISR_GS_MASK, + SVA_TM_DS_HW_EVENT = ISR_DS_MASK, + SVA_TM_BOW_HW_EVENT = ISR_BOW_MASK, + SVA_TM_EOF2_HW_EVENT = ISR_EOF2_MASK, + SVA_TM_BRC_HW_EVENT = ISR_BRC_MASK, + SVA_TM_EOF_HW_EVENT = ISR_CER_MASK, + SVA_TM_ERR_HW_EVENT = ISR_ERR_MASK, + SVA_TM_EOK_HW_EVENT = ISR_EOK_MASK, + SVA_TM_EOI_HW_EVENT = IIS_EOI_MASK << SHIFT_BYTE1, + SVA_TM_BERR_HW_EVENT = IIS_BE_MASK << SHIFT_BYTE1, + SVA_TM_INACTIVE_HW_EVENT = MASK_BIT10, + SVA_TM_ACTIVE_HW_EVENT = MASK_BIT11, + SVA_TM_FAKE_HW_EVENT = MASK_BIT12, + SVA_TM_PACKET_ERROR_HW_EVENT = MASK_BIT13, + SVA_TM_PACKET_READ_HW_EVENT = MASK_BIT14, + SVA_TM_PACKET_WRITE_HW_EVENT = MASK_BIT15, + SVA_TM_ABORT_HW_EVENT =MASK_BIT16, /*@BORT-$TOP*///New event added + + + /* Please insert bellow and update the following upper boundary */ + SVA_TM_LAST_HW_EVENT =SVA_TM_ABORT_HW_EVENT , + SVA_TM_PADDING_SO_EVENT_MGT_WORK = MASK_BIT30 +} t_sva_tm_virtual_hw_event_id; + +/* Error management. */ +typedef enum { + SVA_TM_MM_XRAM_ERROR = SVA_TM_LAST_ERROR, + SVA_TM_MM_ESRAM_ERROR, + SVA_TM_MM_SDRAM_ERROR, + SVA_TM_BAD_TIMESTAMP_VALUE, + SVA_TM_BAD_TIMESTAMP_TYPE, + SVA_TM_COLLAPSE_WITH_NEXT_SUBTASK_ERROR, + SVA_TM_UPDATE_CURRENT_SUBTASK_FIELD_ERROR, + SVA_TM_SUBTASKLIST_CONNECTED_ERROR, + SVA_TM_BAD_FUNCTION_PARAMETER, + SVA_TM_NO_MORE_SUBTASKLIST_DESC, + SVA_TM_NO_MORE_SUBTASK_DESC, + SVA_TM_NO_MORE_EVENT_DESC, + SVA_TM_TIME_OUT_ERROR, + SVA_TM_OK = SVA_OK, + SVA_WARNING_TM_UPDATE_CURRENT_SUBTASK_LINK = SVA_TM_FIRST_INFO, + SVA_WARNING_TM_DELETE_CURRENT_SUBTASK, + + + + + + + +}t_sva_tm_error; + +/******************************************************************************* +* PUBLIC Functions +*******************************************************************************/ + +/*Init*/ +PUBLIC t_sva_tm_error sva_TM_Init( t_logical_address, t_logical_address ); +PUBLIC t_sva_tm_error sva_TM_Reset( void ); + +/*SubTask Management*/ +PUBLIC t_sva_tm_error sva_TM_CreateSubTask( t_sva_tm_task_id, const t_sva_tm_task_ctrl_desc *, + t_sva_tm_subtask_type, t_sva_tm_postprocessing_type, + t_sva_tm_synchro,t_sva_tm_bot_eot, t_sva_tm_bbm, t_sva_tm_subtask_id*); + +PUBLIC t_sva_tm_error sva_TM_DeleteSubTask( t_sva_tm_subtask_id ); + +/*SubTask List Management */ +PUBLIC t_sva_tm_error sva_TM_CreateSubTaskList( t_sva_tm_task_id, t_sva_service_id, t_sva_fw_features, t_sva_tm_subtask_list_id *); +PUBLIC t_sva_tm_error sva_TM_CreateSubTaskListOpenService( t_sva_tm_task_id, t_sva_service_id, t_sva_fw_id, t_sva_tm_subtask_list_id *); + + +PUBLIC t_sva_tm_error sva_TM_DeleteSubTaskList( t_sva_tm_subtask_list_id ); +PUBLIC t_sva_tm_error sva_TM_AddElemToSubTaskList( t_sva_tm_subtask_list_id, t_sva_tm_subtask_id, t_sva_tm_timestamp *, t_uint32); +PUBLIC t_sva_tm_error sva_TM_RemoveElemFromSubTaskList( t_sva_tm_subtask_list_id, t_sva_tm_subtask_id *); + +PUBLIC t_sva_error sva_TM_ActivateSubTaskList(t_sva_tm_subtask_list_id subtaskListId,t_sva_service_mode serviceMode, + t_sva_fw_id *pFwId); +PUBLIC t_sva_tm_error sva_TM_InActivateSubTaskList( t_sva_tm_subtask_list_id ); + +PUBLIC t_sva_tm_error sva_TM_SendTaskCommand( t_sva_tm_subtask_list_id, t_sva_tm_task_cmd_id, t_uint32); + +PUBLIC t_uint32 sva_TM_GetNbSubTask(t_sva_tm_subtask_list_id); + +// Last parameter: For Open service, last parameter should be true as will not discriminate if should take semaphore or not +PUBLIC t_sva_tm_error sva_TM_GetSubTaskField(t_sva_tm_subtask_id, t_sva_tm_field_id, + t_logical_address, t_uint32, t_size, t_bool); +PUBLIC t_sva_tm_error sva_TM_ConnectSubtasksFields(t_sva_tm_subtask_id, t_sva_tm_field_id, t_sva_tm_subtask_id, t_sva_tm_field_id); +PUBLIC t_sva_tm_error sva_TM_InitSubTaskField(t_sva_tm_subtask_id, t_sva_tm_field_id, t_logical_address, t_size ); +PUBLIC t_sva_tm_error sva_TM_UpdateSubTaskField(t_sva_tm_update_desc, t_sva_tm_subtask_id, + t_sva_tm_field_id, t_sva_field_command,t_uint32, t_uint32, t_size); + + +// Hardware event stuff +PUBLIC t_sva_tm_error sva_TM_DispatchHWEvent( t_sva_tm_task_id, t_uint32, t_uint32, t_uint32, t_uint32, t_uint32, + t_uint8, t_sva_tm_virtual_hw_event_desc *, t_uint32 *); +PUBLIC t_sva_tm_error sva_TM_DispatchEOIEvent( void ); + +// Virtual Hardware event stuff +PUBLIC t_sva_tm_error sva_TM_EnableVirtualHwEvents(t_sva_tm_subtasklist_id, t_sva_tm_virtual_hw_event_id); +PUBLIC t_sva_tm_error sva_TM_DisableVirtualHwEvents(t_sva_tm_subtasklist_id, t_sva_tm_virtual_hw_event_id); +PUBLIC t_sva_tm_error sva_TM_EnableAllVirtualHwEvents(t_sva_tm_subtasklist_id); +PUBLIC t_sva_tm_error sva_TM_DisableAllVirtualHwEvents(t_sva_tm_subtasklist_id); + +#ifdef __cplusplus +} /* allow C++ to use these headers */ +#endif /* __cplusplus */ + +#endif /* __INC_SVA_TASKMGT_H */ +/* End of file - sva_taskmgt.h */ + --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/tasks_management/sva_taskmgtp.h @@ -0,0 +1,359 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ + +#ifndef __INC_SVA_TASKMGTP_H +#define __INC_SVA_TASKMGTP_H + +#include "hcl_defs.h" +#include "sva_taskmgt.h" + +/******************************************************************************/ +/* Constants definitions */ +/******************************************************************************/ +#ifdef __DEBUG + /* + * Define number of event to log + */ + #define TM_LOG_DEPTH 32 + + /* Enable/Disable subtask duration tracking. */ +// #define TM_TRACK_SUBTASK_DURATION TRUE + #define TM_TRACK_SUBTASK_DURATION FALSE +#endif + +/* + * Defines the number of possible hardware services (ENC/DEC/PREP/POST/TVO) + * and the number of possible software services (PreP/Enc/Dec/Post/StillDec/StillEndENC/DEC/PREP/POST/TVO) +*/ +#define SVA_TM_NB_HW_TASK 5 + +/* + * Defines the number of software services that may be use dfor a single + * hardware task : + * ENC Encode.Still Encode/Stab 3 + * DEC Decode/Still Decode 2 + * PRE Preprocessor 1 + * POS Postprocessor 1 + * TVO TV Output 1 + * OPEN Open services 8 +*/ +#define SVA_TM_MAX_SERVICE_TYPE_PER_HW_TASK 8 + +/* + * Defines the max number of subtask list per service, i.e. max number of + * instance for a specific service +*/ +#define SVA_TM_MAX_INSTANCE_PER_SERVICE 5 + +#define SVA_TM_TOTAL_SRV_PER_HW_TASK (SVA_TM_MAX_INSTANCE_PER_SERVICE*SVA_TM_MAX_SERVICE_TYPE_PER_HW_TASK) + +/* + * Defines the max number of logical subtask scheduled in hardware +*/ +#define SVA_TM_NB_MAX_SCHEDULED_SUBTASK 5 + +/* + * Defines irp READ/WRITE mask +*/ +#define SVA_TM_IRP_READ_COMPLETED 1 +#define SVA_TM_IRP_WRITE_COMPLETED 2 + +/*------------------------------------------------------------------------ + * Defines + *----------------------------------------------------------------------*/ + +#define FIELDID2INDEX(fid) ((fid + 1) & MASK_BYTE0) + +#define DECREASE(a) {if((a)!=0) {(a)--;}}; + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +//shift for NTY register +#define SHIFT_NTY_SIZE 16 +#define SHIFT_EOTBOT 14 +#define SHIFT_BBM 13 +#define SHIFT_SYNCHRO 11 +#define SHIFT_TSE 10 +#define SHIFT_PPP 8 +#define SHIFT_TYPE 0 + +//mask for NTY register +#define MASK_NTY_SIZE (0xFFFFUL<. */ +/*---------------------------------------------------------------------------*/ + --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/tvo/sva_tvo.c @@ -0,0 +1,2478 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ +/*------------------------------------------------------------------------ + * Includes + *----------------------------------------------------------------------*/ +#include "hcl_defs.h" +#include "sva_tvo.h" +#include "sva_tvop.h" +#include "sva_eventmgt.h" +#include "sva_buffermgtp.h" +#include "sva_taskmgtp.h" + +/*------------------------------------------------------------------------ + * Global Variables + *----------------------------------------------------------------------*/ +#ifdef __DEBUG +ALIGN(32) PRIVATE t_sva_tv_debug_events eventTvoDebugTable[NUM_MAX_TV]; +ALIGN(32) PRIVATE t_sva_tv_debug_commands commandTvoDebugTable[NUM_MAX_TV]; +ALIGN(32) PRIVATE t_sva_tv_debug_transitions transitionTvoDebugTable[NUM_MAX_TV]; +#endif +/*instance descriptors*/ +PRIVATE t_sva_tv_descriptor tvoDesc[NUM_MAX_TV]; + +/*table that describe memory allocation for tvo*/ +/*t_sva_tvo_param_init and t_sva_tvo_param_in will be allocated only for one subtask*/ +/*others subtask will be link to this one*/ +PRIVATE const t_sva_tm_field_ctrl_desc defaultTvoFieldDescArray[TV_FIELD_NUMBER]={ + { SVA_TM_DCMD_ALLOCATE, {{sizeof(t_sva_tvo_frame_buf_in), TV_DEFAULT_INFOS_MEMORY_ID}}}, + { SVA_TM_DCMD_ALLOCATE, {{sizeof(t_sva_tvo_param_init), TV_DEFAULT_INFOS_MEMORY_ID}}}, + { SVA_TM_DCMD_ALLOCATE, {{sizeof(t_sva_tvo_param_in), TV_DEFAULT_INFOS_MEMORY_ID}}} +}; + +/*table that translate tvo state into service state*/ +PRIVATE const t_sva_service_state tvoState2ServiceState[SVA_TV_LAST_DUMMY_STATE]= { + SVA_SERVICE_NOT_INITIALIZED, /*SVA_ST_NOT_INITIALIZED*/ + SVA_SERVICE_WAIT_FOR_CONFIGURATION, /*SVA_ST_WAIT_FOR_CONFIGURATION*/ + SVA_SERVICE_WAIT_FOR_INTERNAL_NEEDS, /*SVA_ST_WAIT_FOR_INTERNAL_NEEDS*/ + SVA_SERVICE_WAIT_FOR_ACTIVATE, /*SVA_ST_WAIT_FOR_ACTIVATE*/ + SVA_SERVICE_WAIT_FOR_START, /*SVA_ST_WAIT_FOR_START*/ + SVA_SERVICE_FLUSHING, /*SVA_ST_FLUSHING_IN*/ + SVA_SERVICE_WAIT_FOR_DATA, /*SVA_ST_WAIT_FOR_DATA*/ + SVA_SERVICE_RUNNING, /*SVA_ST_RUNNING*/ + SVA_SERVICE_ABORT_REQUESTED, /*SVA_ST_ABORT_REQUESTED*/ + SVA_SERVICE_STOP_REQUESTED, /*SVA_ST_STOP_REQUESTED*/ + SVA_SERVICE_ERROR /*SVA_ST_ERROR*/ +}; + +/*main state machine description*/ +PRIVATE const t_sva_tv_state stateMachine[SVA_TV_LAST_DUMMY_STATE][SVA_TV_LAST_DUMMY_TRANSITION]= { + /* Current State = SVA_TV_NOT_INITIALIZED */ + { + SVA_TV_WAIT_FOR_CONFIGURATION, /*SVA_TV_CREATE*/ + SVA_TV_TRANSITION_REJECTED, /*SVA_TV_CONFIGURE*/ + SVA_TV_TRANSITION_REJECTED, /*SVA_TV_INTERNAL_NEEDS*/ + SVA_TV_TRANSITION_REJECTED, /*SVA_TV_ACTIVATE*/ + SVA_TV_TRANSITION_REJECTED, /*SVA_TV_INACTIVATE*/ + SVA_TV_TRANSITION_REJECTED, /*SVA_TV_CONTROL_START*/ + SVA_TV_TRANSITION_REJECTED, /*SVA_TV_CONTROL_STOP*/ + SVA_TV_TRANSITION_REJECTED, /*SVA_TV_CONTROL_ABORT*/ + SVA_TV_TRANSITION_REJECTED, /*SVA_TV_ALL_DEPENDENCIES_RESOLVED*/ + SVA_TV_TRANSITION_REJECTED, /*SVA_TV_PUSH*/ + SVA_TV_TRANSITION_REJECTED, /*SVA_TV_EVENT_EOK*/ + SVA_TV_TRANSITION_REJECTED, /*SVA_TV_EVENT_FAKE*/ + SVA_TV_TRANSITION_REJECTED, /*SVA_TV_EVENT_ACTIVE*/ + SVA_TV_TRANSITION_REJECTED, /*SVA_TV_EVENT_INACTIVE*/ + SVA_TV_TRANSITION_REJECTED, /*SVA_TV_RESET*/ + SVA_TV_NOT_INITIALIZED, /*SVA_TV_CONTROL_DELETE*/ + SVA_TV_TRANSITION_REJECTED, /*SVA_TV_EVENT_ERROR*/ + SVA_TV_TRANSITION_REJECTED, /*SVA_TV_FLUSH_IN*/ + SVA_TV_TRANSITION_REJECTED, /*SVA_TV_CANCEL*/ + SVA_TV_TRANSITION_REJECTED, /*SVA_TV_UPDATE_PARAM*/ + SVA_TV_TRANSITION_REJECTED /*SVA_TV_GET_PARAM_SIZE*/ + }, + /* Current State = SVA_TV_WAIT_FOR_CONFIGURATION */ + { + SVA_TV_TRANSITION_REJECTED, /*SVA_TV_CREATE*/ + SVA_TV_WAIT_FOR_INTERNAL_NEEDS, /*SVA_TV_CONFIGURE*/ + SVA_TV_TRANSITION_REJECTED, /*SVA_TV_INTERNAL_NEEDS*/ + SVA_TV_TRANSITION_REJECTED, /*SVA_TV_ACTIVATE*/ + SVA_TV_TRANSITION_REJECTED, /*SVA_TV_INACTIVATE*/ + SVA_TV_TRANSITION_REJECTED, /*SVA_TV_CONTROL_START*/ + SVA_TV_TRANSITION_REJECTED, /*SVA_TV_CONTROL_STOP*/ + SVA_TV_TRANSITION_REJECTED, /*SVA_TV_CONTROL_ABORT*/ + SVA_TV_TRANSITION_REJECTED, /*SVA_TV_ALL_DEPENDENCIES_RESOLVED*/ + SVA_TV_TRANSITION_REJECTED, /*SVA_TV_PUSH*/ + SVA_TV_TRANSITION_REJECTED, /*SVA_TV_EVENT_EOK*/ + SVA_TV_TRANSITION_REJECTED, /*SVA_TV_EVENT_FAKE*/ + SVA_TV_TRANSITION_REJECTED, /*SVA_TV_EVENT_ACTIVE*/ + SVA_TV_TRANSITION_REJECTED, /*SVA_TV_EVENT_INACTIVE*/ + SVA_TV_TRANSITION_REJECTED, /*SVA_TV_RESET*/ + SVA_TV_NOT_INITIALIZED, /*SVA_TV_CONTROL_DELETE*/ + SVA_TV_TRANSITION_REJECTED, /*SVA_TV_EVENT_ERROR*/ + SVA_TV_TRANSITION_REJECTED, /*SVA_TV_FLUSH_IN*/ + SVA_TV_TRANSITION_REJECTED, /*SVA_TV_CANCEL*/ + SVA_TV_TRANSITION_REJECTED, /*SVA_TV_UPDATE_PARAM*/ + SVA_TV_TRANSITION_REJECTED /*SVA_TV_GET_PARAM_SIZE*/ + }, + /* Current State = SVA_TV_WAIT_FOR_INTERNAL_NEEDS */ + { + SVA_TV_TRANSITION_REJECTED, /*SVA_TV_CREATE*/ + SVA_TV_TRANSITION_REJECTED, /*SVA_TV_CONFIGURE*/ + SVA_TV_WAIT_FOR_ACTIVATE, /*SVA_TV_INTERNAL_NEEDS*/ + SVA_TV_TRANSITION_REJECTED, /*SVA_TV_ACTIVATE*/ + SVA_TV_TRANSITION_REJECTED, /*SVA_TV_INACTIVATE*/ + SVA_TV_TRANSITION_REJECTED, /*SVA_TV_CONTROL_START*/ + SVA_TV_TRANSITION_REJECTED, /*SVA_TV_CONTROL_STOP*/ + SVA_TV_TRANSITION_REJECTED, /*SVA_TV_CONTROL_ABORT*/ + SVA_TV_TRANSITION_REJECTED, /*SVA_TV_ALL_DEPENDENCIES_RESOLVED*/ + SVA_TV_TRANSITION_REJECTED, /*SVA_TV_PUSH*/ + SVA_TV_TRANSITION_REJECTED, /*SVA_TV_EVENT_EOK*/ + SVA_TV_TRANSITION_REJECTED, /*SVA_TV_EVENT_FAKE*/ + SVA_TV_TRANSITION_REJECTED, /*SVA_TV_EVENT_ACTIVE*/ + SVA_TV_TRANSITION_REJECTED, /*SVA_TV_EVENT_INACTIVE*/ + SVA_TV_TRANSITION_REJECTED, /*SVA_TV_RESET*/ + SVA_TV_NOT_INITIALIZED, /*SVA_TV_CONTROL_DELETE*/ + SVA_TV_TRANSITION_REJECTED, /*SVA_TV_EVENT_ERROR*/ + SVA_TV_TRANSITION_REJECTED, /*SVA_TV_FLUSH_IN*/ + SVA_TV_TRANSITION_REJECTED, /*SVA_TV_CANCEL*/ + SVA_TV_TRANSITION_REJECTED, /*SVA_TV_UPDATE_PARAM*/ + SVA_TV_WAIT_FOR_INTERNAL_NEEDS /*SVA_TV_GET_PARAM_SIZE*/ + }, + /* Current State = SVA_TV_WAIT_FOR_ACTIVATE */ + { + SVA_TV_TRANSITION_REJECTED, /*SVA_TV_CREATE*/ + SVA_TV_TRANSITION_REJECTED, /*SVA_TV_CONFIGURE*/ + SVA_TV_TRANSITION_REJECTED, /*SVA_TV_INTERNAL_NEEDS*/ + SVA_TV_WAIT_FOR_ACTIVATE, /*SVA_TV_ACTIVATE*/ + SVA_TV_TRANSITION_REJECTED, /*SVA_TV_INACTIVATE*/ + SVA_TV_TRANSITION_REJECTED, /*SVA_TV_CONTROL_START*/ + SVA_TV_TRANSITION_REJECTED, /*SVA_TV_CONTROL_STOP*/ + SVA_TV_TRANSITION_REJECTED, /*SVA_TV_CONTROL_ABORT*/ + SVA_TV_TRANSITION_REJECTED, /*SVA_TV_ALL_DEPENDENCIES_RESOLVED*/ + SVA_TV_TRANSITION_REJECTED, /*SVA_TV_PUSH*/ + SVA_TV_TRANSITION_REJECTED, /*SVA_TV_EVENT_EOK*/ + SVA_TV_TRANSITION_REJECTED, /*SVA_TV_EVENT_FAKE*/ + SVA_TV_WAIT_FOR_START, /*SVA_TV_EVENT_ACTIVE*/ + SVA_TV_TRANSITION_REJECTED, /*SVA_TV_EVENT_INACTIVE*/ + SVA_TV_TRANSITION_REJECTED, /*SVA_TV_RESET*/ + SVA_TV_NOT_INITIALIZED, /*SVA_TV_CONTROL_DELETE*/ + SVA_TV_TRANSITION_REJECTED, /*SVA_TV_EVENT_ERROR*/ + SVA_TV_TRANSITION_REJECTED, /*SVA_TV_FLUSH_IN*/ + SVA_TV_WAIT_FOR_ACTIVATE, /*SVA_TV_CANCEL*/ + SVA_TV_TRANSITION_REJECTED, /*SVA_TV_UPDATE_PARAM*/ + SVA_TV_WAIT_FOR_ACTIVATE /*SVA_TV_GET_PARAM_SIZE*/ + }, + /* Current State = SVA_TV_WAIT_FOR_START */ + { + SVA_TV_TRANSITION_REJECTED, /*SVA_TV_CREATE*/ + SVA_TV_TRANSITION_REJECTED, /*SVA_TV_CONFIGURE*/ + SVA_TV_TRANSITION_REJECTED, /*SVA_TV_INTERNAL_NEEDS*/ + SVA_TV_WAIT_FOR_START, /*SVA_TV_ACTIVATE*/ + SVA_TV_WAIT_FOR_START, /*SVA_TV_INACTIVATE*/ + SVA_TV_WAIT_FOR_DATA, /*SVA_TV_CONTROL_START*/ + SVA_TV_TRANSITION_REJECTED, /*SVA_TV_CONTROL_STOP*/ + SVA_TV_TRANSITION_REJECTED, /*SVA_TV_CONTROL_ABORT*/ + SVA_TV_WAIT_FOR_START, /*SVA_TV_ALL_DEPENDENCIES_RESOLVED*/ + SVA_TV_WAIT_FOR_START, /*SVA_TV_PUSH*/ + SVA_TV_ERROR, /*SVA_TV_EVENT_EOK*/ + SVA_TV_ERROR, /*SVA_TV_EVENT_FAKE*/ + SVA_TV_WAIT_FOR_START, /*SVA_TV_EVENT_ACTIVE*/ + SVA_TV_WAIT_FOR_START, /*SVA_TV_EVENT_INACTIVE*/ + SVA_TV_TRANSITION_REJECTED, /*SVA_TV_RESET*/ + SVA_TV_NOT_INITIALIZED, /*SVA_TV_CONTROL_DELETE*/ + SVA_TV_ERROR, /*SVA_TV_EVENT_ERROR*/ + SVA_TV_FLUSHING_IN, /*SVA_TV_FLUSH_IN*/ + SVA_TV_WAIT_FOR_START, /*SVA_TV_CANCEL*/ + SVA_TV_WAIT_FOR_START, /*SVA_TV_UPDATE_PARAM*/ + SVA_TV_WAIT_FOR_START /*SVA_TV_GET_PARAM_SIZE*/ + }, + /* Current State = SVA_TV_FLUSHING_IN */ + { + SVA_TV_TRANSITION_REJECTED, /*SVA_TV_CREATE*/ + SVA_TV_TRANSITION_REJECTED, /*SVA_TV_CONFIGURE*/ + SVA_TV_TRANSITION_REJECTED, /*SVA_TV_INTERNAL_NEEDS*/ + SVA_TV_TRANSITION_REJECTED, /*SVA_TV_ACTIVATE*/ + SVA_TV_TRANSITION_REJECTED, /*SVA_TV_INACTIVATE*/ + SVA_TV_TRANSITION_REJECTED, /*SVA_TV_CONTROL_START*/ + SVA_TV_TRANSITION_REJECTED, /*SVA_TV_CONTROL_STOP*/ + SVA_TV_TRANSITION_REJECTED, /*SVA_TV_CONTROL_ABORT*/ + SVA_TV_TRANSITION_REJECTED, /*SVA_TV_ALL_DEPENDENCIES_RESOLVED*/ + SVA_TV_TRANSITION_REJECTED, /*SVA_TV_PUSH*/ + SVA_TV_TRANSITION_REJECTED, /*SVA_TV_EVENT_EOK*/ + SVA_TV_WAIT_FOR_START, /*SVA_TV_EVENT_FAKE*/ + SVA_TV_TRANSITION_REJECTED, /*SVA_TV_EVENT_ACTIVE*/ + SVA_TV_TRANSITION_REJECTED, /*SVA_TV_EVENT_INACTIVE*/ + SVA_TV_TRANSITION_REJECTED, /*SVA_TV_RESET*/ + SVA_TV_TRANSITION_REJECTED, /*SVA_TV_CONTROL_DELETE*/ + SVA_TV_TRANSITION_REJECTED, /*SVA_TV_EVENT_ERROR*/ + SVA_TV_TRANSITION_REJECTED, /*SVA_TV_FLUSH_IN*/ + SVA_TV_FLUSHING_IN, /*SVA_TV_CANCEL*/ + SVA_TV_TRANSITION_REJECTED, /*SVA_TV_UPDATE_PARAM*/ + SVA_TV_FLUSHING_IN /*SVA_TV_GET_PARAM_SIZE*/ + }, + /* Current State = SVA_TV_WAIT_FOR_DATA */ + { + SVA_TV_TRANSITION_REJECTED, /*SVA_TV_CREATE*/ + SVA_TV_TRANSITION_REJECTED, /*SVA_TV_CONFIGURE*/ + SVA_TV_TRANSITION_REJECTED, /*SVA_TV_INTERNAL_NEEDS*/ + SVA_TV_WAIT_FOR_DATA, /*SVA_TV_ACTIVATE*/ + SVA_TV_WAIT_FOR_DATA, /*SVA_TV_INACTIVATE*/ + SVA_TV_TRANSITION_REJECTED, /*SVA_TV_CONTROL_START*/ + SVA_TV_STOP_REQUESTED, /*SVA_TV_CONTROL_STOP*/ + SVA_TV_TRANSITION_REJECTED, /*SVA_TV_CONTROL_ABORT*/ + SVA_TV_RUNNING, /*SVA_TV_ALL_DEPENDENCIES_RESOLVED*/ + SVA_TV_WAIT_FOR_DATA, /*SVA_TV_PUSH*/ + SVA_TV_ERROR, /*SVA_TV_EVENT_EOK*/ + SVA_TV_ERROR, /*SVA_TV_EVENT_FAKE*/ + SVA_TV_WAIT_FOR_DATA, /*SVA_TV_EVENT_ACTIVE*/ + SVA_TV_WAIT_FOR_DATA, /*SVA_TV_EVENT_INACTIVE*/ + SVA_TV_TRANSITION_REJECTED, /*SVA_TV_RESET*/ + SVA_TV_TRANSITION_REJECTED, /*SVA_TV_CONTROL_DELETE*/ + SVA_TV_ERROR, /*SVA_TV_EVENT_ERROR*/ + SVA_TV_TRANSITION_REJECTED, /*SVA_TV_FLUSH_IN*/ + SVA_TV_WAIT_FOR_DATA, /*SVA_TV_CANCEL*/ + SVA_TV_WAIT_FOR_DATA, /*SVA_TV_UPDATE_PARAM*/ + SVA_TV_WAIT_FOR_DATA /*SVA_TV_GET_PARAM_SIZE*/ + }, + /* Current State = SVA_TV_RUNNING */ + { + SVA_TV_TRANSITION_REJECTED, /*SVA_TV_CREATE*/ + SVA_TV_TRANSITION_REJECTED, /*SVA_TV_CONFIGURE*/ + SVA_TV_TRANSITION_REJECTED, /*SVA_TV_INTERNAL_NEEDS*/ + SVA_TV_RUNNING, /*SVA_TV_ACTIVATE*/ + SVA_TV_RUNNING, /*SVA_TV_INACTIVATE*/ + SVA_TV_TRANSITION_REJECTED, /*SVA_TV_CONTROL_START*/ + SVA_TV_STOP_REQUESTED, /*SVA_TV_CONTROL_STOP*/ + SVA_TV_ABORT_REQUESTED, /*SVA_TV_CONTROL_ABORT*/ + SVA_TV_RUNNING, /*SVA_TV_ALL_DEPENDENCIES_RESOLVED*/ + SVA_TV_RUNNING, /*SVA_TV_PUSH*/ + SVA_TV_WAIT_FOR_DATA, /*SVA_TV_EVENT_EOK*/ + SVA_TV_ERROR, /*SVA_TV_EVENT_FAKE*/ + SVA_TV_RUNNING, /*SVA_TV_EVENT_ACTIVE*/ + SVA_TV_RUNNING, /*SVA_TV_EVENT_INACTIVE*/ + SVA_TV_TRANSITION_REJECTED, /*SVA_TV_RESET*/ + SVA_TV_TRANSITION_REJECTED, /*SVA_TV_CONTROL_DELETE*/ + SVA_TV_ERROR, /*SVA_TV_EVENT_ERROR*/ + SVA_TV_TRANSITION_REJECTED, /*SVA_TV_FLUSH_IN*/ + SVA_TV_RUNNING, /*SVA_TV_CANCEL*/ + SVA_TV_RUNNING, /*SVA_TV_UPDATE_PARAM*/ + SVA_TV_RUNNING /*SVA_TV_GET_PARAM_SIZE*/ + }, + /* Current State = SVA_TV_ABORT_REQUESTED */ + { + SVA_TV_TRANSITION_REJECTED, /*SVA_TV_CREATE*/ + SVA_TV_TRANSITION_REJECTED, /*SVA_TV_CONFIGURE*/ + SVA_TV_TRANSITION_REJECTED, /*SVA_TV_INTERNAL_NEEDS*/ + SVA_TV_TRANSITION_REJECTED, /*SVA_TV_ACTIVATE*/ + SVA_TV_TRANSITION_REJECTED, /*SVA_TV_INACTIVATE*/ + SVA_TV_TRANSITION_REJECTED, /*SVA_TV_CONTROL_START*/ + SVA_TV_TRANSITION_REJECTED, /*SVA_TV_CONTROL_STOP*/ + SVA_TV_TRANSITION_REJECTED, /*SVA_TV_CONTROL_ABORT*/ + SVA_TV_ABORT_REQUESTED, /*SVA_TV_ALL_DEPENDENCIES_RESOLVED*/ + SVA_TV_ABORT_REQUESTED, /*SVA_TV_PUSH*/ + SVA_TV_ERROR, /*SVA_TV_EVENT_EOK*/ + SVA_TV_ERROR, /*SVA_TV_EVENT_FAKE*/ + SVA_TV_ERROR, /*SVA_TV_EVENT_ACTIVE*/ + SVA_TV_ERROR, /*SVA_TV_EVENT_INACTIVE*/ + SVA_TV_TRANSITION_REJECTED, /*SVA_TV_RESET*/ + SVA_TV_TRANSITION_REJECTED, /*SVA_TV_CONTROL_DELETE*/ + SVA_TV_ERROR, /*SVA_TV_EVENT_ERROR*/ + SVA_TV_TRANSITION_REJECTED, /*SVA_TV_FLUSH_IN*/ + SVA_TV_ABORT_REQUESTED, /*SVA_TV_CANCEL*/ + SVA_TV_TRANSITION_REJECTED, /*SVA_TV_UPDATE_PARAM*/ + SVA_TV_ABORT_REQUESTED /*SVA_TV_GET_PARAM_SIZE*/ + }, + /* Current State = SVA_TV_STOP_REQUESTED */ + { + SVA_TV_TRANSITION_REJECTED, /*SVA_TV_CREATE*/ + SVA_TV_TRANSITION_REJECTED, /*SVA_TV_CONFIGURE*/ + SVA_TV_TRANSITION_REJECTED, /*SVA_TV_INTERNAL_NEEDS*/ + SVA_TV_TRANSITION_REJECTED, /*SVA_TV_ACTIVATE*/ + SVA_TV_TRANSITION_REJECTED, /*SVA_TV_INACTIVATE*/ + SVA_TV_TRANSITION_REJECTED, /*SVA_TV_CONTROL_START*/ + SVA_TV_TRANSITION_REJECTED, /*SVA_TV_CONTROL_STOP*/ + SVA_TV_ABORT_REQUESTED, /*SVA_TV_CONTROL_ABORT*/ + SVA_TV_STOP_REQUESTED, /*SVA_TV_ALL_DEPENDENCIES_RESOLVED*/ + SVA_TV_STOP_REQUESTED, /*SVA_TV_PUSH*/ + SVA_TV_WAIT_FOR_START, /*SVA_TV_EVENT_EOK*/ + SVA_TV_ERROR, /*SVA_TV_EVENT_FAKE*/ + SVA_TV_ERROR, /*SVA_TV_EVENT_ACTIVE*/ + SVA_TV_ERROR, /*SVA_TV_EVENT_INACTIVE*/ + SVA_TV_TRANSITION_REJECTED, /*SVA_TV_RESET*/ + SVA_TV_TRANSITION_REJECTED, /*SVA_TV_CONTROL_DELETE*/ + SVA_TV_ERROR, /*SVA_TV_EVENT_ERROR*/ + SVA_TV_TRANSITION_REJECTED, /*SVA_TV_FLUSH_IN*/ + SVA_TV_STOP_REQUESTED, /*SVA_TV_CANCEL*/ + SVA_TV_TRANSITION_REJECTED, /*SVA_TV_UPDATE_PARAM*/ + SVA_TV_STOP_REQUESTED /*SVA_TV_GET_PARAM_SIZE*/ + }, + /* Current State = SVA_TV_ERROR */ + { + SVA_TV_TRANSITION_REJECTED, /*SVA_TV_CREATE*/ + SVA_TV_TRANSITION_REJECTED, /*SVA_TV_CONFIGURE*/ + SVA_TV_TRANSITION_REJECTED, /*SVA_TV_INTERNAL_NEEDS*/ + SVA_TV_TRANSITION_REJECTED, /*SVA_TV_ACTIVATE*/ + SVA_TV_TRANSITION_REJECTED, /*SVA_TV_INACTIVATE*/ + SVA_TV_TRANSITION_REJECTED, /*SVA_TV_CONTROL_START*/ + SVA_TV_TRANSITION_REJECTED, /*SVA_TV_CONTROL_STOP*/ + SVA_TV_TRANSITION_REJECTED, /*SVA_TV_CONTROL_ABORT*/ + SVA_TV_TRANSITION_REJECTED, /*SVA_TV_ALL_DEPENDENCIES_RESOLVED*/ + SVA_TV_TRANSITION_REJECTED, /*SVA_TV_PUSH*/ + SVA_TV_TRANSITION_REJECTED, /*SVA_TV_EVENT_EOK*/ + SVA_TV_TRANSITION_REJECTED, /*SVA_TV_EVENT_FAKE*/ + SVA_TV_TRANSITION_REJECTED, /*SVA_TV_EVENT_ACTIVE*/ + SVA_TV_TRANSITION_REJECTED, /*SVA_TV_EVENT_INACTIVE*/ + SVA_TV_WAIT_FOR_START, /*SVA_TV_RESET*/ + SVA_TV_TRANSITION_REJECTED, /*SVA_TV_CONTROL_DELETE*/ + SVA_TV_ERROR, /*SVA_TV_EVENT_ERROR*/ + SVA_TV_TRANSITION_REJECTED, /*SVA_TV_FLUSH_IN*/ + SVA_TV_ERROR, /*SVA_TV_CANCEL*/ + SVA_TV_TRANSITION_REJECTED, /*SVA_TV_UPDATE_PARAM*/ + SVA_TV_ERROR /*SVA_TV_GET_PARAM_SIZE*/ + } +}; + +/*activate state machine description*/ +PRIVATE const t_sva_tv_activate_state activateStateMachine[SVA_TV_LAST_ACTIVATE_DUMMY_STATE][SVA_TV_LAST_DUMMY_TRANSITION]= { + /* Current State = SVA_TV_INACTIVE */ + { + SVA_TV_INACTIVE, /*SVA_TV_CREATE*/ + SVA_TV_INACTIVE, /*SVA_TV_CONFIGURE*/ + SVA_TV_INACTIVE, /*SVA_TV_INTERNAL_NEEDS*/ + SVA_TV_IN_ACTIVATION, /*SVA_TV_ACTIVATE*/ + SVA_TV_ACTIVATE_TRANSITION_REJECTED, /*SVA_TV_INACTIVATE*/ + SVA_TV_ACTIVATE_TRANSITION_REJECTED, /*SVA_TV_CONTROL_START*/ + SVA_TV_ACTIVATE_TRANSITION_REJECTED, /*SVA_TV_CONTROL_STOP*/ + SVA_TV_ACTIVATE_TRANSITION_REJECTED, /*SVA_TV_CONTROL_ABORT*/ + SVA_TV_INACTIVE, /*SVA_TV_ALL_DEPENDENCIES_RESOLVED*/ + SVA_TV_INACTIVE, /*SVA_TV_PUSH*/ + SVA_TV_INACTIVE, /*SVA_TV_EVENT_EOK*/ + SVA_TV_INACTIVE, /*SVA_TV_EVENT_FAKE*/ + SVA_TV_INACTIVE, /*SVA_TV_EVENT_ACTIVE*/ + SVA_TV_INACTIVE, /*SVA_TV_EVENT_INACTIVE*/ + SVA_TV_INACTIVE, /*SVA_TV_RESET*/ + SVA_TV_INACTIVE, /*SVA_TV_CONTROL_DELETE*/ + SVA_TV_INACTIVE, /*SVA_TV_EVENT_ERROR*/ + SVA_TV_INACTIVE, /*SVA_TV_FLUSH_IN*/ + SVA_TV_ACTIVATE_TRANSITION_REJECTED, /*SVA_TV_CANCEL*/ + SVA_TV_INACTIVE, /*SVA_TV_UPDATE_PARAM*/ + SVA_TV_INACTIVE /*SVA_TV_GET_PARAM_SIZE*/ + }, + /* Current State = SVA_TV_IN_ACTIVATION */ + { + SVA_TV_ACTIVATE_TRANSITION_REJECTED, /*SVA_TV_CREATE*/ + SVA_TV_ACTIVATE_TRANSITION_REJECTED, /*SVA_TV_CONFIGURE*/ + SVA_TV_ACTIVATE_TRANSITION_REJECTED, /*SVA_TV_INTERNAL_NEEDS*/ + SVA_TV_ACTIVATE_TRANSITION_REJECTED, /*SVA_TV_ACTIVATE*/ + SVA_TV_ACTIVATE_TRANSITION_REJECTED, /*SVA_TV_INACTIVATE*/ + SVA_TV_ACTIVATE_TRANSITION_REJECTED, /*SVA_TV_CONTROL_START*/ + SVA_TV_ACTIVATE_TRANSITION_REJECTED, /*SVA_TV_CONTROL_STOP*/ + SVA_TV_ACTIVATE_TRANSITION_REJECTED, /*SVA_TV_CONTROL_ABORT*/ + SVA_TV_IN_ACTIVATION, /*SVA_TV_ALL_DEPENDENCIES_RESOLVED*/ + SVA_TV_IN_ACTIVATION, /*SVA_TV_PUSH*/ + SVA_TV_IN_ACTIVATION, /*SVA_TV_EVENT_EOK*/ + SVA_TV_IN_ACTIVATION, /*SVA_TV_EVENT_FAKE*/ + SVA_TV_ACTIVE, /*SVA_TV_EVENT_ACTIVE*/ + SVA_TV_IN_ACTIVATION, /*SVA_TV_EVENT_INACTIVE*/ + SVA_TV_IN_ACTIVATION, /*SVA_TV_RESET*/ + SVA_TV_ACTIVATE_TRANSITION_REJECTED, /*SVA_TV_CONTROL_DELETE*/ + SVA_TV_IN_ACTIVATION, /*SVA_TV_EVENT_ERROR*/ + SVA_TV_IN_ACTIVATION, /*SVA_TV_FLUSH_IN*/ + SVA_TV_INACTIVE, /*SVA_TV_CANCEL*/ + SVA_TV_IN_ACTIVATION, /*SVA_TV_UPDATE_PARAM*/ + SVA_TV_IN_ACTIVATION /*SVA_TV_GET_PARAM_SIZE*/ + }, + /* Current State = SVA_TV_ACTIVE */ + { + SVA_TV_ACTIVATE_TRANSITION_REJECTED, /*SVA_TV_CREATE*/ + SVA_TV_ACTIVATE_TRANSITION_REJECTED, /*SVA_TV_CONFIGURE*/ + SVA_TV_ACTIVATE_TRANSITION_REJECTED, /*SVA_TV_INTERNAL_NEEDS*/ + SVA_TV_ACTIVATE_TRANSITION_REJECTED, /*SVA_TV_ACTIVATE*/ + SVA_TV_IN_INACTIVATION, /*SVA_TV_INACTIVATE*/ + SVA_TV_ACTIVE, /*SVA_TV_CONTROL_START*/ + SVA_TV_ACTIVE, /*SVA_TV_CONTROL_STOP*/ + SVA_TV_ACTIVE, /*SVA_TV_CONTROL_ABORT*/ + SVA_TV_ACTIVE, /*SVA_TV_ALL_DEPENDENCIES_RESOLVED*/ + SVA_TV_ACTIVE, /*SVA_TV_PUSH*/ + SVA_TV_ACTIVE, /*SVA_TV_EVENT_EOK*/ + SVA_TV_ACTIVE, /*SVA_TV_EVENT_FAKE*/ + SVA_TV_ACTIVE, /*SVA_TV_EVENT_ACTIVE*/ + SVA_TV_ACTIVE, /*SVA_TV_EVENT_INACTIVE*/ + SVA_TV_ACTIVE, /*SVA_TV_RESET*/ + SVA_TV_INACTIVE, /*SVA_TV_CONTROL_DELETE*/ + SVA_TV_ACTIVE, /*SVA_TV_EVENT_ERROR*/ + SVA_TV_ACTIVE, /*SVA_TV_FLUSH_IN*/ + SVA_TV_ACTIVATE_TRANSITION_REJECTED, /*SVA_TV_CANCEL*/ + SVA_TV_ACTIVE, /*SVA_TV_UPDATE_PARAM*/ + SVA_TV_ACTIVE /*SVA_TV_GET_PARAM_SIZE*/ + }, + /* Current State = SVA_TV_IN_INACTIVATION */ + { + SVA_TV_ACTIVATE_TRANSITION_REJECTED, /*SVA_TV_CREATE*/ + SVA_TV_ACTIVATE_TRANSITION_REJECTED, /*SVA_TV_CONFIGURE*/ + SVA_TV_ACTIVATE_TRANSITION_REJECTED, /*SVA_TV_INTERNAL_NEEDS*/ + SVA_TV_ACTIVATE_TRANSITION_REJECTED, /*SVA_TV_ACTIVATE*/ + SVA_TV_ACTIVATE_TRANSITION_REJECTED, /*SVA_TV_INACTIVATE*/ + SVA_TV_ACTIVATE_TRANSITION_REJECTED, /*SVA_TV_CONTROL_START*/ + SVA_TV_ACTIVATE_TRANSITION_REJECTED, /*SVA_TV_CONTROL_STOP*/ + SVA_TV_ACTIVATE_TRANSITION_REJECTED, /*SVA_TV_CONTROL_ABORT*/ + SVA_TV_IN_INACTIVATION, /*SVA_TV_ALL_DEPENDENCIES_RESOLVED*/ + SVA_TV_IN_INACTIVATION, /*SVA_TV_PUSH*/ + SVA_TV_IN_INACTIVATION, /*SVA_TV_EVENT_EOK*/ + SVA_TV_IN_INACTIVATION, /*SVA_TV_EVENT_FAKE*/ + SVA_TV_IN_INACTIVATION, /*SVA_TV_EVENT_ACTIVE*/ + SVA_TV_INACTIVE, /*SVA_TV_EVENT_INACTIVE*/ + SVA_TV_INACTIVE, /*SVA_TV_RESET*/ + SVA_TV_ACTIVATE_TRANSITION_REJECTED, /*SVA_TV_CONTROL_DELETE*/ + SVA_TV_IN_INACTIVATION, /*SVA_TV_EVENT_ERROR*/ + SVA_TV_IN_INACTIVATION, /*SVA_TV_FLUSH_IN*/ + SVA_TV_ACTIVE, /*SVA_TV_CANCEL*/ + SVA_TV_IN_INACTIVATION, /*SVA_TV_UPDATE_PARAM*/ + SVA_TV_IN_INACTIVATION /*SVA_TV_GET_PARAM_SIZE*/ + } +}; + +/*------------------------------------------------------------------------ + * Private functions prototype + *----------------------------------------------------------------------*/ +PRIVATE t_sva_tv_error sva_TV_ResolveDependencies(t_sva_service_instance_num ); +PRIVATE t_sva_tv_state sva_TV_UpdateInstanceStateMachine(t_sva_service_instance_num ,t_sva_tv_transition ); +PRIVATE t_bool sva_TV_isTransitionValid(t_sva_service_instance_num ,t_sva_tv_transition ); +PRIVATE t_sva_error sva_TV_CheckServiceId(t_sva_service_id ); +PRIVATE t_sva_error sva_TV_DoReset(t_sva_service_id ); +PRIVATE t_sva_error sva_TV_DoFlushIn(t_sva_service_id ); +PRIVATE t_sva_tv_error sva_TV_ResetStatus(t_sva_tvo_status *); +PRIVATE void sva_TV_ResetDescriptor(t_sva_tv_descriptor *); +PRIVATE t_bool sva_TV_IsConfigurationValid(const t_sva_tvo_configuration *); +PRIVATE t_sva_error sva_TV_BuildParamInStructure(const t_sva_tvo_configuration * ,t_sva_tvo_param_init *, t_sva_tvo_param_in *); + +/****************************************************************************/ +/* NAME: t_sva_error sva_TV_Init ( void ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine initialize the Tvo Management module. */ +/* 1) Set state of instance to SVA_SERVICE_NOT_INITIALIZED */ +/* 2) init fifos */ +/* 3) Init descriptor for all instances */ +/* */ +/* PARAMETERS: */ +/* IN : none */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/* - always SVA_OK */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + * DONE +*/ +PUBLIC t_sva_error sva_TV_Init() +{ + t_uint32 i; + + /*init all encode instances*/ + for(i=0;iconfHandle.currentConf=*pConf; + pDesc->confHandle.nextConf=*pConf; + + /* Update the state machine */ + sva_TV_UpdateInstanceStateMachine(instanceNum,SVA_TV_CONFIGURE); + + return SVA_OK; +} + +/****************************************************************************/ +/* NAME: t_sva_error sva_TV_GetInternalNeeds( */ +/* t_sva_service_id serviceId, */ +/* t_size* pNeedsSize */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine returns the size of the memory needed for TVO */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - serviceId: identifier of the service */ +/* - pNeedsSize: size needed */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/* - SVA_OK : Command taken into account */ +/* - SVA_UNKNOWN_SERVICE_ID : service id is not correct */ +/* */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + DONE +*/ +PUBLIC t_sva_error sva_TV_GetInternalNeeds( + t_sva_service_id serviceId, + t_size *pNeedsSize +) +{ + t_sva_error status; + t_uint32 fifoSize; + + /*check for service id validity*/ + status=sva_TV_CheckServiceId(serviceId); + if (status!=SVA_OK) {return status;} + + /*check pointer validity*/ + TV_CHECK_NULL_POINTER(pNeedsSize); + + /*compute memory size need*/ + *pNeedsSize = 0; + /*memory need by event management*/ + status=sva_EM_GetInternalNeeds(pNeedsSize); + if (status!=SVA_OK) {return status;} + /*memory need due to input image buffer*/ + GET_FIFO_MEMORY_NEEDS(t_sva_buffer_id, PUSH_FIFO_DEFAULT_SIZE , fifoSize); + *pNeedsSize+=fifoSize; + GET_FIFO_MEMORY_NEEDS(t_sva_buffer_id, PUSH_FIFO_DEFAULT_SIZE, fifoSize); + *pNeedsSize+=fifoSize; + /*memory need due to subtask dependency fifo*/ + GET_FIFO_MEMORY_NEEDS(t_sva_tv_subtask_dependencies, SUBTASK_TVO_NUMBER, fifoSize); + *pNeedsSize+=fifoSize; + GET_FIFO_MEMORY_NEEDS(t_sva_tv_subtask_dependencies, SUBTASK_TVO_NUMBER, fifoSize); + *pNeedsSize+=fifoSize; + + return SVA_OK; +} + +/****************************************************************************/ +/* NAME: t_sva_error sva_TV_ProvideInternalNeeds ( */ +/* t_sva_service_id serviceId */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine allows to end the configuration of the service since */ +/* memory need has been provide by user. */ +/* - create fifos */ +/* - create subtasks */ +/* - create subtasklist */ +/* - enable events */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - serviceId: identifier of the service */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/* - SVA_OK : Command taken into account */ +/* - SVA_UNKNOWN_SERVICE_ID : service id is not correct */ +/* - SVA_UNEXPECTED_API_CALL : Command cannot be excecuted in */ +/* current context. */ +/* - SVA_INTERNAL_TV_OUTPUT_ERROR : internal error */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + DONE +*/ +PUBLIC t_sva_error sva_TV_ProvideInternalNeeds( + t_sva_service_id serviceId +) +{ + t_sva_error status; + t_sva_service_instance_num instanceNum = READ_INSTANCE_NUM_IN_SERVICE_ID(serviceId); + t_sva_tv_descriptor *pDesc=&tvoDesc[instanceNum]; + t_sva_tvo_configuration *pConf=&pDesc->confHandle.currentConf; + t_sva_ff_error ffError; + t_sva_tm_error tmError; + t_sva_tvo_param_init paramInitBuffer; + t_sva_tvo_param_in paramInBuffer; + t_sva_tm_task_ctrl_desc tvoTaskDesc; + t_sva_tm_field_ctrl_desc copyTvoFieldDescArray[TV_FIELD_NUMBER]; + t_uint32 i; + + /*check for service id validity*/ + status=sva_TV_CheckServiceId(serviceId); + if (status!=SVA_OK) {return status;} + + /*check that transition is allowed*/ + if (sva_TV_isTransitionValid(instanceNum,SVA_TV_INTERNAL_NEEDS)==FALSE) {return SVA_UNEXPECTED_API_CALL;} + + /*copy TvoFieldDescArray*/ + for(i=0;iinputImageFifos.pushFifo, ffError); + if (ffError != SVA_FIFO_OK) {return SVA_INTERNAL_TV_OUTPUT_ERROR;} + CREATE_FIFO(t_sva_buffer_id, PUSH_FIFO_DEFAULT_SIZE, pDesc->inputImageFifos.inUseFifo, ffError); + if (ffError != SVA_FIFO_OK) {return SVA_INTERNAL_TV_OUTPUT_ERROR;} + CREATE_FIFO(t_sva_tv_subtask_dependencies, SUBTASK_TVO_NUMBER, pDesc->subtasksDependencyFifo, ffError); + if (ffError != SVA_FIFO_OK) {return SVA_INTERNAL_TV_OUTPUT_ERROR;} + CREATE_FIFO(t_sva_tv_subtask_dependencies, SUBTASK_TVO_NUMBER, pDesc->inUseSubtaskDependency, ffError); + if (ffError != SVA_FIFO_OK) {return SVA_INTERNAL_TV_OUTPUT_ERROR;} + + /*create subtasks*/ + tvoTaskDesc.memId=TV_DEFAULT_MEMORY_ID; + tvoTaskDesc.fieldnb=TV_FIELD_NUMBER; + tvoTaskDesc.pfieldctrldesc=(t_sva_tm_field_ctrl_desc *)copyTvoFieldDescArray; + for(i=0;isubtasksIdArray[0]; + tvoTaskDesc.pfieldctrldesc[2].command=SVA_TM_DCMD_REFERENCE; + tvoTaskDesc.pfieldctrldesc[2].commandDesc.refDesc.fieldtoreference=2; + tvoTaskDesc.pfieldctrldesc[2].commandDesc.refDesc.subtaskidtoreference=pDesc->subtasksIdArray[0]; + } + /*Stabilization use encode task*/ + tmError=sva_TM_CreateSubTask(SVA_TM_TVO, &tvoTaskDesc, + SVA_TM_TVO_STANDARD,SVA_TM_NO_POST_PROCESSING, + SVA_TM_NO_SYNCHRO,SVA_TM_NO_IT,SVA_TM_BBM_DEFAULT,&pDesc->subtasksIdArray[i]); + if (tmError != SVA_TM_OK) {return SVA_INTERNAL_TV_OUTPUT_ERROR;} + } + + /*create subtasklist*/ + tmError=sva_TM_CreateSubTaskList(SVA_TM_TVO,serviceId,SVA_FW_FEAT_TVO,&pDesc->subtasksListId); + if (tmError != SVA_TM_OK) {return SVA_INTERNAL_TV_OUTPUT_ERROR;} + + /* enable events for sub task list*/ + /* we enable EOF1, EOF2, ERR and EOK event*/ + /* we also enable activate, inactivate and fake event*/ + tmError=sva_TM_DisableAllVirtualHwEvents(pDesc->subtasksListId); + if (tmError != SVA_TM_OK) {return SVA_INTERNAL_TV_OUTPUT_ERROR;} + tmError=sva_TM_EnableVirtualHwEvents(pDesc->subtasksListId,SVA_TM_EOF1_HW_EVENT); + if (tmError != SVA_TM_OK) {return SVA_INTERNAL_TV_OUTPUT_ERROR;} + tmError=sva_TM_EnableVirtualHwEvents(pDesc->subtasksListId,SVA_TM_EOF2_HW_EVENT); + if (tmError != SVA_TM_OK) {return SVA_INTERNAL_TV_OUTPUT_ERROR;} + tmError=sva_TM_EnableVirtualHwEvents(pDesc->subtasksListId,SVA_TM_ERR_HW_EVENT); + if (tmError != SVA_TM_OK) {return SVA_INTERNAL_TV_OUTPUT_ERROR;} + tmError=sva_TM_EnableVirtualHwEvents(pDesc->subtasksListId,SVA_TM_EOK_HW_EVENT); + if (tmError != SVA_TM_OK) {return SVA_INTERNAL_TV_OUTPUT_ERROR;} + tmError=sva_TM_EnableVirtualHwEvents(pDesc->subtasksListId,SVA_TM_INACTIVE_HW_EVENT); + if (tmError != SVA_TM_OK) {return SVA_INTERNAL_TV_OUTPUT_ERROR;} + tmError=sva_TM_EnableVirtualHwEvents(pDesc->subtasksListId,SVA_TM_ACTIVE_HW_EVENT); + if (tmError != SVA_TM_OK) {return SVA_INTERNAL_TV_OUTPUT_ERROR;} + tmError=sva_TM_EnableVirtualHwEvents(pDesc->subtasksListId,SVA_TM_FAKE_HW_EVENT); + if (tmError != SVA_TM_OK) {return SVA_INTERNAL_TV_OUTPUT_ERROR;} + + /*initialize paramin of subtasks*/ + status=sva_TV_BuildParamInStructure(pConf,¶mInitBuffer,¶mInBuffer); + if (status!=SVA_OK) {return status;} + for(i=0;isubtasksIdArray[i],SVA_TM_TVO_ADDR_INIT_PARAMETERS, + (t_logical_address)¶mInitBuffer,sizeof(t_sva_tvo_param_init)); + if (tmError != SVA_TM_OK) {return SVA_INTERNAL_TV_OUTPUT_ERROR;} + tmError=sva_TM_InitSubTaskField(pDesc->subtasksIdArray[i],SVA_TM_TVO_ADDR_IN_PARAMETERS, + (t_logical_address)¶mInBuffer,sizeof(t_sva_tvo_param_in)); + if (tmError != SVA_TM_OK) {return SVA_INTERNAL_TV_OUTPUT_ERROR;} + } + + /* Set default dependencies*/ + pDesc->defaultDep.inputImageDep=NOT_RESOLVED_DEPENDENCY; + + /* Push subtask in subtasksDependencyFifo since they are ready to be solved*/ + for(i=0;isubtasksIdArray[i]; + subtaskDep.dependencies=pDesc->defaultDep; + ffError=PUSH_FIFO_ELEM(pDesc->subtasksDependencyFifo, t_sva_tv_subtask_dependencies, subtaskDep); + if (ffError!=SVA_FIFO_OK) {return SVA_INTERNAL_TV_OUTPUT_ERROR;} + } + + /* Update the state machine */ + sva_TV_UpdateInstanceStateMachine(instanceNum,SVA_TV_INTERNAL_NEEDS); + + return SVA_OK; +} + +/****************************************************************************/ +/* NAME: t_sva_error sva_TV_Activate( */ +/* t_sva_service_id serviceId, */ +/* t_sva_service_mode serviceMode, */ +/* t_sva_fw_id *pFwId */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine activates the tvo service */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - serviceId: identifier of the service */ +/* - serviceMode : set service to real_time or not */ +/* */ +/* OUT : */ +/* - pFwId : identifier of firmware id for which user shall provide location*/ +/* */ +/* RETURN: */ +/* t_sva_error */ +/* - SVA_OK : Command taken into account */ +/* - SVA_UNKNOWN_SERVICE_ID : service id is not correct */ +/* - SVA_UNEXPECTED_API_CALL : Command cannot be excecuted in */ +/* current context. */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + * DONE +*/ +PUBLIC t_sva_error sva_TV_Activate( + t_sva_service_id serviceId, + t_sva_service_mode serviceMode, + t_sva_fw_id *pFwId +) +{ + t_sva_error status; + t_sva_service_instance_num instanceNum = READ_INSTANCE_NUM_IN_SERVICE_ID(serviceId); + t_sva_tv_descriptor *pDesc=&tvoDesc[instanceNum]; + + TV_CHECK_NULL_POINTER(pFwId); + + /*check for service id validity*/ + status=sva_TV_CheckServiceId(serviceId); + if (status!=SVA_OK) {return status;} + + /*check that transition is allowed*/ + if (sva_TV_isTransitionValid(instanceNum,SVA_TV_ACTIVATE)==FALSE) {return SVA_UNEXPECTED_API_CALL;} + + /* Update the state machine */ + /* Update state machine before command is send to task management to avoid race condition */ + sva_TV_UpdateInstanceStateMachine(instanceNum,SVA_TV_ACTIVATE); + + /*activate subTaskList*/ + /*handle informative error code*/ + status=sva_TM_ActivateSubTaskList(pDesc->subtasksListId,serviceMode,pFwId); + if (status != SVA_OK && status != SVA_FW_SWITCH_OCCURED && status != SVA_FW_SWITCH_DELAYED) + { + sva_TV_UpdateInstanceStateMachine(instanceNum,SVA_TV_CANCEL); + + return status; + } + + return status; +} + +/****************************************************************************/ +/* NAME: t_sva_error sva_TV_Inactivate( */ +/* t_sva_service_id serviceId */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine deactivates the TVO service */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - serviceId: identifier of the service */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/* - SVA_OK : Command taken into account */ +/* - SVA_UNKNOWN_SERVICE_ID : service id is not correct */ +/* - SVA_UNEXPECTED_API_CALL : Command cannot be excecuted in */ +/* current context. */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + * DONE +*/ +PUBLIC t_sva_error sva_TV_Inactivate(t_sva_service_id serviceId) +{ + t_sva_error status; + t_sva_service_instance_num instanceNum = READ_INSTANCE_NUM_IN_SERVICE_ID(serviceId); + t_sva_tv_descriptor *pDesc=&tvoDesc[instanceNum]; + t_sva_tm_error tmError; + + /*check for service id validity*/ + status=sva_TV_CheckServiceId(serviceId); + if (status!=SVA_OK) {return status;} + + /*check that transition is allowed*/ + if (sva_TV_isTransitionValid(instanceNum,SVA_TV_INACTIVATE)==FALSE) {return SVA_UNEXPECTED_API_CALL;} + + /* Update the state machine */ + /* Update state machine before command is send to task management to avoid race condition */ + sva_TV_UpdateInstanceStateMachine(instanceNum,SVA_TV_INACTIVATE); + + /*inactivate subTaskList*/ + /*handle informative error code*/ + tmError=sva_TM_InActivateSubTaskList(pDesc->subtasksListId); + if (tmError != SVA_TM_OK) + { + sva_TV_UpdateInstanceStateMachine(instanceNum,SVA_TV_CANCEL); + + return SVA_INTERNAL_TV_OUTPUT_ERROR; + } + + return SVA_OK; +} + +/****************************************************************************/ +/* NAME: t_sva_error sva_TV_Control ( */ +/* t_sva_service_id serviceId, */ +/* t_sva_service_cmd_id cmdId, */ +/* t_uint32 param */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine allows to control an instance of a TVO Service */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - serviceId: identifier of the given service */ +/* - cmdId: command to apply to the encode */ +/* - param: parameter use by command */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/* - SVA_OK : Command taken into account */ +/* - SVA_UNKNOWN_SERVICE_ID : service id is not correct */ +/* - SVA_UNEXPECTED_API_CALL : Command cannot be excecuted in */ +/* current context. */ +/* - SVA_UNKNOWN_CMD_ID : Command to execute is unknown */ +/* - SVA_INTERNAL_TV_OUTPUT_ERROR : internal error */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + DONE +*/ +PUBLIC t_sva_error sva_TV_Control( + t_sva_service_id serviceId, + t_sva_service_cmd_id cmdId, + t_uint32 param +) +{ + t_sva_service_instance_num instanceNum = READ_INSTANCE_NUM_IN_SERVICE_ID(serviceId); + t_sva_tv_descriptor *pDesc=&tvoDesc[instanceNum]; + t_sva_error status = SVA_UNEXPECTED_API_CALL; + t_sva_error error; + t_sva_tm_error tmError; + + /*check for service id validity*/ + error=sva_TV_CheckServiceId(serviceId); + if (error!=SVA_OK) {return error;} + +#ifdef __DEBUG + { + t_uint32 systemTime; + + SVA_GetServiceSystemTime(serviceId,&systemTime); + commandTvoDebugTable[instanceNum].commandDebugDesc[commandTvoDebugTable[instanceNum].nbOfCommandReceived%LOG_DEPTH].command=cmdId; + commandTvoDebugTable[instanceNum].commandDebugDesc[commandTvoDebugTable[instanceNum].nbOfCommandReceived%LOG_DEPTH].systemTime=systemTime; + commandTvoDebugTable[instanceNum].commandDebugDesc[commandTvoDebugTable[instanceNum].nbOfCommandReceived%LOG_DEPTH].parameter=param; + commandTvoDebugTable[instanceNum].nbOfCommandReceived++; + } +#endif + + /*handle command*/ + switch(cmdId) + { + case SVA_SERVICE_START: + if (sva_TV_isTransitionValid(instanceNum,SVA_TV_CONTROL_START)==TRUE) + { + /* transition are force before sending task command to avoid race condition*/ + sva_TV_UpdateInstanceStateMachine(instanceNum,SVA_TV_CONTROL_START); + /* as we accepted some push before (or after a restart) some dependencies are perhaps + already scheduled + */ + if (GET_FIFO_NB_ELEMS(pDesc->subtasksDependencyFifo)!=SUBTASK_TVO_NUMBER) + { + sva_TV_UpdateInstanceStateMachine(instanceNum,SVA_TV_ALL_DEPENDENCIES_RESOLVED); + } + /*now send start command*/ + tmError=sva_TM_SendTaskCommand(pDesc->subtasksListId,SVA_TM_TCMD_START,param); + HCL_DEBUG_ASSERT(tmError==SVA_TM_OK); + + status = SVA_OK; + } + break; + case SVA_SERVICE_STOP: + if (sva_TV_isTransitionValid(instanceNum,SVA_TV_CONTROL_STOP)==TRUE) + { + t_sva_tm_subtask_list_info *pListInfo = (t_sva_tm_subtask_list_info *)pDesc->subtasksListId; + /* transition are force before sending task command to avoid race condition*/ + sva_TV_UpdateInstanceStateMachine(instanceNum,SVA_TV_CONTROL_STOP); + /* + * Send first a normal stop that will move subtaskList state in SVA_TM_STOPPING. + * then send a physical stop that will stop task and generate physical EOK. This + * physical EOK will be handle by taskmgt to generate a logical EOK. + */ + /*send a physical stop subtask list*/ + tmError=sva_TM_SendTaskCommand(pDesc->subtasksListId,SVA_TM_TCMD_STOP,param); + HCL_DEBUG_ASSERT(tmError==SVA_TM_OK); + if (pListInfo->nbSubtask != 0) /* Patch for VI17052, Physical STOP issued only when there is some subtask programmed at FW level */ + { + tmError=sva_TM_SendTaskCommand(pDesc->subtasksListId,SVA_TM_TCMD_STOP_PHYSICAL,param); + HCL_DEBUG_ASSERT(tmError==SVA_TM_OK); + } + status = SVA_OK; + } + break; + case SVA_SERVICE_ABORT: + if (sva_TV_isTransitionValid(instanceNum,SVA_TV_CONTROL_ABORT)==TRUE) + { + /* transition are force before sending task command to avoid race condition*/ + sva_TV_UpdateInstanceStateMachine(instanceNum,SVA_TV_CONTROL_ABORT); + /*do a stop until abort is implemented (abort_physical)*/ + /* + * Send first a normal stop that will move subtaskList state in SVA_TM_STOPPING. + * then send a physical stop that will stop task and generate physical EOK. This + * physical EOK will be handle by taskmgt to generate a logical EOK. + */ + /*send a physical stop subtask list*/ + tmError=sva_TM_SendTaskCommand(pDesc->subtasksListId,SVA_TM_TCMD_STOP,param); + HCL_DEBUG_ASSERT(tmError==SVA_TM_OK); + tmError=sva_TM_SendTaskCommand(pDesc->subtasksListId,SVA_TM_TCMD_STOP_PHYSICAL,param); + HCL_DEBUG_ASSERT(tmError==SVA_TM_OK); + + status = SVA_OK; + } + break; + case SVA_SERVICE_RESET: + if (sva_TV_isTransitionValid(instanceNum,SVA_TV_RESET)==TRUE) + { + /*do instance clean-up so service can restart*/ + status = sva_TV_DoReset(serviceId); + if (status == SVA_OK) + { + sva_TV_UpdateInstanceStateMachine(instanceNum,SVA_TV_RESET); + } + } + break; + case SVA_SERVICE_FLUSH_IN: + if (sva_TV_isTransitionValid(instanceNum,SVA_TV_FLUSH_IN)==TRUE) + { + /*flush output buffer if necessary*/ + status = sva_TV_DoFlushIn(serviceId); + if (status == SVA_OK) + { + sva_TV_UpdateInstanceStateMachine(instanceNum,SVA_TV_FLUSH_IN); + /*generate a fake event since flush command is asynchronous*/ + sva_TM_SendTaskCommand(pDesc->subtasksListId,SVA_TM_TCMD_FAKE_EVENT,param); + } + } + break; + case SVA_SERVICE_FLUSH_OUT: + /*no flush of output for tvo since there is no output !!!!*/ + status = SVA_UNKNOWN_CMD_ID; + break; + /*unknown command*/ + default: + status = SVA_UNKNOWN_CMD_ID; + break; + } + + return status; +} + +/****************************************************************************/ +/* NAME: t_sva_error SVA_UpdateTVOutputParams( */ +/* t_sva_service_id serviceId, */ +/* t_sva_update_cmd_type updateCmdType, */ +/* t_sva_tvo_param_id paramId, */ +/* t_uint32 param */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine allows to update params for an instance of a tvo */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - serviceId: identifier of the given service */ +/* - updateCmdType: command to apply to the tvo */ +/* - paramd: value of timeStamp */ +/* - param: parameter for the cmdType */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/* - SVA_OK : Command taken into account */ +/* - SVA_UNKNOWN_SERVICE_ID : service id is not correct */ +/* - SVA_UNEXPECTED_API_CALL : Command cannot be excecuted in */ +/* current context. */ +/* - SVA_INTERNAL_TV_OUTPUT_ERROR : internal error */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + TO DO : + - add command +*/ +PUBLIC t_sva_error SVA_UpdateTVOutputParams( + t_sva_service_id serviceId, + t_sva_update_cmd_type updateCmdType, + t_sva_tvo_param_id paramId, + t_uint32 param + ) +{ + t_sva_service_instance_num instanceNum = READ_INSTANCE_NUM_IN_SERVICE_ID(serviceId); + t_sva_tv_descriptor *pDesc=&tvoDesc[instanceNum]; + t_sva_tvo_configuration *pNextConf=&pDesc->confHandle.nextConf; + t_sva_tvo_configuration *pConf=&pDesc->confHandle.currentConf; + t_sva_tvo_param_init paramInit; + t_sva_tvo_param_in paramIn; + t_sva_tm_error tmError; + t_uint32 i; + t_sva_error status; + + /*check for service id validity*/ + status=sva_TV_CheckServiceId(serviceId); + if (status!=SVA_OK) {return status;} + + /*check that transition is allowed*/ + if (sva_TV_isTransitionValid(instanceNum,SVA_TV_UPDATE_PARAM)==FALSE) {return SVA_UNEXPECTED_API_CALL;} + + /*take command into account for next configuration*/ + switch(paramId) + { + case SVA_TVO_CROPPING: + pNextConf->sourceFrameDesc.window=*((t_sva_window_desc *) param); + break; + case SVA_TVO_WINDOW_OFFSET: + pNextConf->destinationWindowOffsetDesc=*((t_sva_offset_desc *) param); + break; + case SVA_TVO_BACKGROUND_COLOR: + pNextConf->backgroundColor=*((t_sva_yuv_color *) param); + break; + default: + break; + } + + /*take into account updateCmdType*/ + switch(updateCmdType) + { + case SVA_UPDATE_MULTIPLE: + /*nothing to do*/ + break; + case SVA_UPDATE_LAST: + /*check new configuration is valid*/ + if (sva_TV_IsConfigurationValid(pNextConf)==FALSE) {return SVA_INCOHERENT_CONFIGURATION;} + /*change param in on the fly*/ + /*first compute new paramin*/ + status=sva_TV_BuildParamInStructure(pNextConf,¶mInit,¶mIn); + if (status!=SVA_OK) {return SVA_INTERNAL_TV_OUTPUT_ERROR;} + /*then update paramin for all subtasks*/ + for(i=0;isubtasksIdArray[i], SVA_TM_TVO_ADDR_IN_PARAMETERS, + FCMD_COPY,(t_uint32) ¶mIn,0, + sizeof(t_sva_tvo_param_in)); + HCL_DEBUG_ASSERT(tmError==SVA_TM_OK); + } + /*copy next as current*/ + *pConf=*pNextConf; + status=SVA_IMMEDIATE_UPDATE; + break; + case SVA_UPDATE_REVERT: + /*cancel previously param update*/ + *pNextConf=*pConf; + break; + default: + break; + } + + /*update state machine => do nothing*/ + sva_TV_UpdateInstanceStateMachine(instanceNum,SVA_TV_UPDATE_PARAM); + + return status; +} + +/****************************************************************************/ +/* NAME: t_sva_error sva_TV_Push( */ +/* t_sva_service_id serviceId, */ +/* t_sva_buffer_id bufferId, */ +/* t_sva_push_mode pushMode, */ +/* t_sva_buffer_type bufferType, */ +/* t_sva_timestamp timeStamp */ +/* ) */ +/*--------------------------------------------------------------------------*/ + /* DESCRIPTION: */ + /* This routine allows to push data in a Tvo service */ +/* - it will check buffer has enought size according to conf/algo */ +/* - it will push it in the corresponding pushFifo fifo */ +/* - update status of buffer */ +/* - try to solve some dependencies */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - serviceId: identifier of the service */ +/* - bufferId: identifier of the buffer */ +/* - pushMode: PUSH_IN/PUSH_OUT */ +/* - bufferType: */ +/* - timeStamp: */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/* - SVA_OK : Command taken into account */ +/* - SVA_UNKNOWN_SERVICE_ID : service id is not correct */ +/* - SVA_UNEXPECTED_API_CALL : Command cannot be excecuted in */ +/* current context. */ +/* - SVA_INTERNAL_TV_OUTPUT_ERROR : internal error */ +/* - SVA_INVALID_BUFFER_TYPE : buffer type is not handle by tvo */ +/* - SVA_INTERNAL_FIFOS_FULL : internal fifos are full */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + DONE +*/ +PUBLIC t_sva_error sva_TV_Push( + t_sva_service_id serviceId, + t_sva_buffer_id bufferId, + t_sva_push_mode pushMode, + t_sva_buffer_type bufferType, + t_sva_timestamp timeStamp +) +{ + t_sva_service_instance_num instanceNum = READ_INSTANCE_NUM_IN_SERVICE_ID(serviceId); + t_sva_tv_descriptor *pDesc=&tvoDesc[instanceNum]; + const t_sva_tvo_configuration *pConf = &pDesc->confHandle.currentConf; + t_sva_error status; + t_sva_bm_error bmError; + t_sva_ff_error ffError; + t_sva_tv_error tvError; + t_size bufferSize; + t_size minSize=0; + t_sva_tv_subtask_dependencies subTaskDep; + t_sva_tm_error tmError; + t_sva_buffer_id tmpBufferId; + + tmpBufferId = (t_sva_buffer_id) 0; //For removing compiler warning + + /*check for service id validity*/ + status=sva_TV_CheckServiceId(serviceId); + if (status!=SVA_OK) {return status;} + + /*check that transition is allowed*/ + if (sva_TV_isTransitionValid(instanceNum,SVA_TV_PUSH)==FALSE) {return SVA_UNEXPECTED_API_CALL;} + + /*handle provide buffer*/ + switch(bufferType) + { + case SVA_IMAGE_BUFFER_TYPE: + if (pushMode != SVA_PUSH_IN) return SVA_UNEXPECTED_API_CALL; + minSize = (((t_uint32)pConf->sourceFrameDesc.frame.height * (t_uint32)pConf->sourceFrameDesc.frame.width)*2); + + /*read buffer size*/ + bmError=sva_BM_GetBufferSize(bufferId,&bufferSize); + if (bmError!=SVA_BM_OK) {return SVA_INTERNAL_TV_OUTPUT_ERROR;} + /*check buffer has enought space*/ + if (bufferSize>=minSize) + { + /*check space into fifo*/ + if (GET_FIFO_NB_ELEMS(pDesc->inputImageFifos.pushFifo) >= PUSH_FIFO_DEFAULT_SIZE) {status=SVA_INTERNAL_FIFOS_FULL;} + ffError=PUSH_FIFO_ELEM(pDesc->inputImageFifos.pushFifo, t_sva_buffer_id, bufferId); + if (ffError!=SVA_FIFO_OK) {status=SVA_INTERNAL_FIFOS_FULL;} + else + { + t_physical_address bufferAddr; + t_sva_tvo_frame_buf_in frameBufferIn; + t_sva_bm_error bmError; + + /*read subtask for which we will try to solve dependencies*/ + ffError=READ_FIFO_ELEM(pDesc->subtasksDependencyFifo,t_sva_tv_subtask_dependencies,subTaskDep); + if(ffError == SVA_FIFO_EMPTY){ + /*read subtask which is already scheduled in inUseSubtaskDependency*/ + ffError=READ_FIFO_ELEM(pDesc->inUseSubtaskDependency,t_sva_tv_subtask_dependencies,subTaskDep); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + + /*push the image buffer in the in use fifo*/ + ffError=POP_FIFO_ELEM(pDesc->inputImageFifos.pushFifo, t_sva_buffer_id,tmpBufferId); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + HCL_DEBUG_ASSERT(tmpBufferId==bufferId); + /*push the image buffer in the in use fifo*/ + ffError=PUSH_FIFO_ELEM(pDesc->inputImageFifos.inUseFifo,t_sva_buffer_id,bufferId); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + + /*update field in the task list*/ + bmError=sva_BM_GetBufferPhysicalAddress(bufferId,&bufferAddr); + HCL_DEBUG_ASSERT(bmError==SVA_BM_OK); + frameBufferIn.addr_source_buffer=bufferAddr; + + /*update this field in subtask*/ + tmError=sva_TM_UpdateSubTaskField(SVA_TM_ONLY_ONE_FIELD_TO_UPDATE, + subTaskDep.subtaskId, SVA_TM_TVO_ADDR_IN_FRAME_BUFFER, + FCMD_COPY,(t_uint32) &frameBufferIn.addr_source_buffer,HCL_BITFIELD_OFFSET(t_sva_tvo_frame_buf_in,addr_source_buffer), + sizeof(frameBufferIn.addr_source_buffer)); + HCL_DEBUG_ASSERT(tmError==SVA_TM_OK); + } + pDesc->status.bufferizationStats.inLevel++; + status=SVA_OK; + } + } + else { status=SVA_INTERNAL_TV_OUTPUT_ERROR; } + break; + default: + status=SVA_INVALID_BUFFER_TYPE; + break; + } + + /*update state machine*/ + sva_TV_UpdateInstanceStateMachine(instanceNum,SVA_TV_PUSH); + + /*update buffer status if we have succeeded to push it and try to solve dependencies*/ + if (status == SVA_OK) + { + t_uint32 systemTime; + t_sva_error svaError; + + svaError=SVA_GetServiceSystemTime(serviceId,&systemTime); + if (svaError!=SVA_OK) {return SVA_INTERNAL_TV_OUTPUT_ERROR;} + bmError=sva_BM_UpdateBufferStatus(bufferId, SVA_BUFFER_IN_USE, systemTime); + if (bmError!=SVA_BM_OK) {return SVA_INTERNAL_TV_OUTPUT_ERROR;} + tvError=sva_TV_ResolveDependencies(instanceNum); + if (tvError!=SVA_TV_OK) {return SVA_INTERNAL_TV_OUTPUT_ERROR;} + } + + return status; +} + +/****************************************************************************/ +/* NAME: t_sva_error SVA_GetTVOutputStatus ( */ +/* t_sva_service_id serviceId, */ +/* t_sva_tvo_status * pStatus */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine allows to get status of the tvo service */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - serviceId: identifier of the service */ +/* - pStatus: status for the tvo service */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/* - SVA_OK : Command taken into account */ +/* - SVA_UNKNOWN_SERVICE_ID : service id is not correct */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + DONE +*/ +PUBLIC t_sva_error SVA_GetTVOutputStatus( + t_sva_service_id serviceId, + t_sva_tvo_status *pStatus +) +{ + t_sva_service_instance_num instanceNum = READ_INSTANCE_NUM_IN_SERVICE_ID(serviceId); + t_sva_tv_descriptor *pDesc=&tvoDesc[instanceNum]; + t_sva_error status; + + TV_CHECK_NULL_POINTER(pStatus); + + /*check for service id validity*/ + status=sva_TV_CheckServiceId(serviceId); + if (status!=SVA_OK) {return status;} + + /*copy status*/ + *pStatus=pDesc->status; + + return SVA_OK; +} + +/****************************************************************************/ +/* NAME: t_sva_ec_error sva_TV_DispatchVirtualHwEvent( */ +/* t_sva_virtual_hw_event_id eventId, */ +/* t_sva_service_id serviceId, */ +/* t_sva_tm_subtask_id subtaskId, */ +/* t_uint32 eventTimestamp, */ +/* t_uint32 eventDate, */ +/* t_uint8 maxOfEvent, */ +/* t_sva_event_desc *pEventDesc, */ +/* t_uint32 *pNbEvent */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine allows to dispatch event of the tvo service */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - eventId: event identifier */ +/* - serviceId: identifier of the service */ +/* - subtaskId: identifier of the subtask for which is the event */ +/* - eventTimestamp: time at which the event occur (system time unit) */ +/* - eventDate: time at which the event occur (ticks time unit) */ +/* - maxOfEvent: nb of event max contained in EventDesc */ +/* - pEventDesc: structure of Events */ +/* - pNbEvent: nb of event into EventDesc */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_tv_error */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ + +PUBLIC t_sva_tv_error sva_TV_DispatchVirtualHwEvent( + t_sva_tm_virtual_hw_event_id eventId, + t_sva_service_id serviceId, + t_sva_tm_subtask_id subtaskId, + t_uint32 eventTimestamp, + t_uint32 eventDate, + t_uint8 maxOfEvent, + t_sva_event_desc *pEventDesc, + t_uint32 *pNbEvent +) +{ + t_sva_service_instance_num instanceNum = READ_INSTANCE_NUM_IN_SERVICE_ID(serviceId); + t_sva_tv_descriptor *pDesc=&tvoDesc[instanceNum]; + t_sva_error status; + t_sva_ff_error ffError; + //t_sva_tm_error tmError; + t_uint32 nbEventsRaised = 0; + //t_sva_tv_subtask_dependencies subTaskDep; + t_sva_buffer_id bufferId=INVALID_BUFFER_ID; + t_sva_tvo_frame_buf_in frameBufferIn; + t_sva_bm_buffer_desc *pBufferDesc; + + TV_CHECK_NULL_POINTER(pEventDesc); + TV_CHECK_NULL_POINTER(pNbEvent); + + (void) maxOfEvent; + *pNbEvent=0; + /*check for service id validity*/ + status=sva_TV_CheckServiceId(serviceId); + if (status!=SVA_OK) {return SVA_TV_INVALID_INSTANCE_NB;} + +#ifdef __DEBUG + { + eventTvoDebugTable[instanceNum].eventDebugDesc[eventTvoDebugTable[instanceNum].nbOfEventReceived%LOG_DEPTH].event=eventId; + eventTvoDebugTable[instanceNum].eventDebugDesc[eventTvoDebugTable[instanceNum].nbOfEventReceived%LOG_DEPTH].systemTime=eventTimestamp; + eventTvoDebugTable[instanceNum].eventDebugDesc[eventTvoDebugTable[instanceNum].nbOfEventReceived%LOG_DEPTH].subtaskId=subtaskId; + eventTvoDebugTable[instanceNum].eventDebugDesc[eventTvoDebugTable[instanceNum].nbOfEventReceived%LOG_DEPTH].serviceId=serviceId; + eventTvoDebugTable[instanceNum].nbOfEventReceived++; + } +#endif + + switch(eventId) + { + case SVA_TM_EOF2_HW_EVENT: + case SVA_TM_EOF1_HW_EVENT: + /* Check the addr_source_buffer (Y) */ + sva_TM_GetSubTaskField(subtaskId,SVA_TM_TVO_ADDR_IN_FRAME_BUFFER,(t_uint32) &frameBufferIn.addr_source_buffer,HCL_BITFIELD_OFFSET(t_sva_tvo_frame_buf_in,addr_source_buffer), sizeof(frameBufferIn.addr_source_buffer),FALSE); + + /* VOID remaining buffers */ + while(READ_FIFO_ELEM(pDesc->inputImageFifos.inUseFifo,t_sva_buffer_id,bufferId) != SVA_FIFO_EMPTY) + { + pBufferDesc = (t_sva_bm_buffer_desc *)(bufferId); + /*VOID in use buffer */ + if(pBufferDesc->bufferSystemAddress.logical != frameBufferIn.addr_source_buffer) + { + ffError=POP_FIFO_ELEM(pDesc->inputImageFifos.inUseFifo,t_sva_buffer_id,bufferId); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + pDesc->status.eventStats.voidedCounter++; + /* We use EOF2 to count number of picture displayed*/ + pDesc->status.nbImageDisplayed++; + CHECK_TABLE_OVERFLOW(nbEventsRaised, maxOfEvent, SVA_TV_NOT_SUPPORTED); + pEventDesc[nbEventsRaised].eventId = SVA_EVENT_BUFFER_VOIDED; + pEventDesc[nbEventsRaised].serviceId = serviceId; + pEventDesc[nbEventsRaised].bufferId = bufferId; + pEventDesc[nbEventsRaised].eventTimestamp = (t_sva_timestamp_value) eventTimestamp; + pEventDesc[nbEventsRaised].eventDate = (t_sva_timestamp_value) eventDate; + pEventDesc[nbEventsRaised].extraInfo=0; + sva_BM_UpdateBufferStatus(pEventDesc[nbEventsRaised].bufferId,SVA_BUFFER_VOIDED,eventTimestamp); + nbEventsRaised++; + /*update buffer level*/ + pDesc->status.bufferizationStats.inLevel--; + } + else + { + break; + } + + } + break; + case SVA_TM_EOK_HW_EVENT: + /* We can reveive an EOK for the following reason : + * 1) a stop has been requested + * 2) an abort has been requested + */ + if (pDesc->state==SVA_TV_STOP_REQUESTED) + { + /*generate a stop event*/ + CHECK_TABLE_OVERFLOW(nbEventsRaised, maxOfEvent, SVA_TV_NOT_SUPPORTED); + pEventDesc[nbEventsRaised].eventId = SVA_EVENT_SERVICE_STOPPED; + pEventDesc[nbEventsRaised].serviceId = serviceId; + pEventDesc[nbEventsRaised].bufferId = INVALID_BUFFER_ID; + pEventDesc[nbEventsRaised].eventTimestamp = (t_sva_timestamp_value) eventTimestamp; + pEventDesc[nbEventsRaised].eventDate = (t_sva_timestamp_value) eventDate; + pEventDesc[nbEventsRaised].extraInfo=0; + nbEventsRaised++; + /*update state*/ + sva_TV_UpdateInstanceStateMachine(instanceNum,SVA_TV_EVENT_EOK); + } + break; + case SVA_TM_FAKE_HW_EVENT: + /*add flush event*/ + CHECK_TABLE_OVERFLOW(nbEventsRaised, maxOfEvent, SVA_TV_NOT_SUPPORTED); + pEventDesc[nbEventsRaised].eventId = SVA_EVENT_SERVICE_FLUSHED_IN; + pEventDesc[nbEventsRaised].serviceId = serviceId; + pEventDesc[nbEventsRaised].bufferId = INVALID_BUFFER_ID; + pEventDesc[nbEventsRaised].eventTimestamp = (t_sva_timestamp_value) eventTimestamp; + pEventDesc[nbEventsRaised].eventDate = (t_sva_timestamp_value) eventDate; + pEventDesc[nbEventsRaised].extraInfo=0; + nbEventsRaised++; + + /*update state machine*/ + sva_TV_UpdateInstanceStateMachine(instanceNum,SVA_TV_EVENT_FAKE); + break; + case SVA_TM_ACTIVE_HW_EVENT: + /*add activate event*/ + CHECK_TABLE_OVERFLOW(nbEventsRaised, maxOfEvent, SVA_TV_NOT_SUPPORTED); + pEventDesc[nbEventsRaised].eventId = SVA_EVENT_SERVICE_ACTIVATED; + pEventDesc[nbEventsRaised].serviceId = serviceId; + pEventDesc[nbEventsRaised].bufferId = INVALID_BUFFER_ID; + pEventDesc[nbEventsRaised].eventTimestamp = (t_sva_timestamp_value) eventTimestamp; + pEventDesc[nbEventsRaised].eventDate = (t_sva_timestamp_value) eventDate; + pEventDesc[nbEventsRaised].extraInfo=0; + nbEventsRaised++; + + /*update state machine*/ + sva_TV_UpdateInstanceStateMachine(instanceNum,SVA_TV_EVENT_ACTIVE); + break; + case SVA_TM_INACTIVE_HW_EVENT: + /*add inactivate event*/ + CHECK_TABLE_OVERFLOW(nbEventsRaised, maxOfEvent, SVA_TV_NOT_SUPPORTED); + pEventDesc[nbEventsRaised].eventId = SVA_EVENT_SERVICE_INACTIVATED; + pEventDesc[nbEventsRaised].serviceId = serviceId; + pEventDesc[nbEventsRaised].bufferId = INVALID_BUFFER_ID; + pEventDesc[nbEventsRaised].eventTimestamp = (t_sva_timestamp_value) eventTimestamp; + pEventDesc[nbEventsRaised].eventDate = (t_sva_timestamp_value) eventDate; + pEventDesc[nbEventsRaised].extraInfo=0; + nbEventsRaised++; + + /*update state machine*/ + sva_TV_UpdateInstanceStateMachine(instanceNum,SVA_TV_EVENT_INACTIVE); + break; + case SVA_TM_ERR_HW_EVENT: + pDesc->status.eventStats.errorCounter++; + CHECK_TABLE_OVERFLOW(nbEventsRaised, maxOfEvent, SVA_TV_NOT_SUPPORTED); + pEventDesc[nbEventsRaised].eventId = SVA_EVENT_SERVICE_ERROR; + pEventDesc[nbEventsRaised].serviceId = serviceId; + pEventDesc[nbEventsRaised].bufferId = INVALID_BUFFER_ID; + pEventDesc[nbEventsRaised].eventTimestamp = (t_sva_timestamp_value) eventTimestamp; + pEventDesc[nbEventsRaised].eventDate = (t_sva_timestamp_value) eventDate; + if (pDesc->state==SVA_TV_ABORT_REQUESTED) + { + pEventDesc[nbEventsRaised].extraInfo=0; + } + else + { + pEventDesc[nbEventsRaised].extraInfo=(t_uint32)SVA_TVO_ERROR; + } + + nbEventsRaised++; + + /*update state machine*/ + sva_TV_UpdateInstanceStateMachine(instanceNum,SVA_TV_EVENT_ERROR); + break; + default: + break; + } + + /*try to solve some dependencies*/ + sva_TV_ResolveDependencies(instanceNum); + + /*return number of generated events*/ + *pNbEvent=nbEventsRaised; + + return SVA_TV_OK; +} + +/****************************************************************************/ +/* NAME: t_sva_error sva_TV_Delete ( */ +/* t_sva_service_id serviceId */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine deletes the tvo service */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - serviceId: identifier of the service */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: */ +/* t_sva_error */ +/* - SVA_OK : Command taken into account */ +/* - SVA_UNKNOWN_SERVICE_ID : service id is not correct */ +/* - SVA_UNEXPECTED_API_CALL : Command cannot be excecuted in */ +/* current context. */ +/* - SVA_INTERNAL_TV_OUTPUT_ERROR : internal error */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + DONE +*/ +PUBLIC t_sva_error sva_TV_Delete(t_sva_service_id serviceId) +{ + t_sva_service_instance_num instanceNum = READ_INSTANCE_NUM_IN_SERVICE_ID(serviceId); + t_sva_tv_descriptor *pDesc=&tvoDesc[instanceNum]; + t_uint32 i; + t_sva_tm_error tmError; + t_sva_error status; + + /*check for service id validity*/ + status=sva_TV_CheckServiceId(serviceId); + if (status!=SVA_OK) {return status;} + + /*check that transition is allowed*/ + if (sva_TV_isTransitionValid(instanceNum,SVA_TV_CONTROL_DELETE)==FALSE) {return SVA_UNEXPECTED_API_CALL;} + + /*check that flush has been done*/ + if (IS_FIFO_EMPTY(pDesc->inputImageFifos.pushFifo)==FALSE) {return SVA_INTERNAL_TV_OUTPUT_ERROR;} + if (IS_FIFO_EMPTY(pDesc->inputImageFifos.inUseFifo)==FALSE) {return SVA_INTERNAL_TV_OUTPUT_ERROR;} + + /*start to delete. Things to do depend of current state*/ + if (pDesc->state==SVA_TV_WAIT_FOR_ACTIVATE || pDesc->state==SVA_TV_WAIT_FOR_START) + { + /*delete fifos*/ + DELETE_FIFO(pDesc->inputImageFifos.pushFifo); + DELETE_FIFO(pDesc->inputImageFifos.inUseFifo); + DELETE_FIFO(pDesc->subtasksDependencyFifo); + DELETE_FIFO(pDesc->inUseSubtaskDependency); + /*delete subtasklist*/ + tmError=sva_TM_DeleteSubTaskList(pDesc->subtasksListId); + if (tmError!=SVA_TM_OK) {return SVA_INTERNAL_TV_OUTPUT_ERROR;} + /*delete subtasks*/ + for(i=0;isubtasksIdArray[i]); + if (tmError!=SVA_TM_OK) {return SVA_INTERNAL_TV_OUTPUT_ERROR;} + } + } + + /*delete descriptor use by memory management*/ + status=sva_EM_Delete(serviceId); + if (status!=SVA_OK) {return status;} + + /*reset descriptors*/ + sva_TV_ResetDescriptor(pDesc); + + /* Update the state machine */ + sva_TV_UpdateInstanceStateMachine(instanceNum,SVA_TV_CONTROL_DELETE); + + return SVA_OK; +} + +/****************************************************************************/ +/* NAME: t_sva_st_error sva_TV_ResolveDependencies( */ +/* t_sva_service_instance_num instanceNum */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* */ +/* This routine is called in sva_TV_Push and after specific event like EOT */ +/* */ +/* PARAMETERS: */ +/* IN : none */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: t_sva_tv_error */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + TO DO : + - update params + - error code +*/ +PRIVATE t_sva_tv_error sva_TV_ResolveDependencies +( + t_sva_service_instance_num instanceNum +) +{ + t_sva_tv_descriptor *pDesc=&tvoDesc[instanceNum]; + t_bool dependencyNotSolved=FALSE; + t_sva_buffer_id bufferId=INVALID_BUFFER_ID; + t_sva_tv_subtask_dependencies subTaskDep; + t_sva_tm_subtask_info *pSubtaskInfo; + t_sva_ff_error ffError; + t_sva_tm_error tmError; + + /*check that transition is valid*/ + if (sva_TV_isTransitionValid(instanceNum,SVA_TV_ALL_DEPENDENCIES_RESOLVED)==FALSE) {return SVA_TV_INVALID_TRANSITION;} + + /*enter loop where we try to solve dep for a maximum of subtasks*/ + while(IS_FIFO_EMPTY(pDesc->subtasksDependencyFifo)==FALSE && dependencyNotSolved==FALSE) + { + /*read subtask for which we will try to solve dependencies*/ + ffError=READ_FIFO_ELEM(pDesc->subtasksDependencyFifo,t_sva_tv_subtask_dependencies,subTaskDep); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + if (subTaskDep.dependencies.inputImageDep == NOT_RESOLVED_DEPENDENCY) + { + if (POP_FIFO_ELEM(pDesc->inputImageFifos.pushFifo,t_sva_buffer_id,bufferId) != SVA_FIFO_EMPTY) + { + t_physical_address bufferAddr; + t_sva_tvo_frame_buf_in frameBufferIn; + t_sva_bm_error bmError; + + /*we can resolve input image dependency, so we do it*/ + /*push the image buffer in the in use fifo*/ + ffError=PUSH_FIFO_ELEM(pDesc->inputImageFifos.inUseFifo,t_sva_buffer_id,bufferId); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + /*update subtask dependency as in use*/ + ffError=UPDATE_FIFO_ELEM_FIELD(pDesc->subtasksDependencyFifo, + t_sva_tv_subtask_dependencies, .dependencies.inputImageDep, + RESOLVED_DEPENDENCY); + HCL_DEBUG_ASSERT(ffError==SVA_FIFO_OK); + subTaskDep.dependencies.inputImageDep = RESOLVED_DEPENDENCY; + /*update field in the task list*/ + bmError=sva_BM_GetBufferPhysicalAddress(bufferId,&bufferAddr); + HCL_DEBUG_ASSERT(bmError==SVA_BM_OK); + frameBufferIn.addr_source_buffer=bufferAddr; + + /*update this field in subtask*/ + tmError=sva_TM_UpdateSubTaskField(SVA_TM_INTERMEDIATE_FIELD_TO_UPDATE,/*don't take sem since task is not scheduled*/ + subTaskDep.subtaskId, SVA_TM_TVO_ADDR_IN_FRAME_BUFFER, + FCMD_COPY,(t_uint32) &frameBufferIn.addr_source_buffer,HCL_BITFIELD_OFFSET(t_sva_tvo_frame_buf_in,addr_source_buffer), + sizeof(frameBufferIn.addr_source_buffer)); + HCL_DEBUG_ASSERT(tmError==SVA_TM_OK); + } + } + + pSubtaskInfo = (t_sva_tm_subtask_info*)subTaskDep.subtaskId; + + /*check that all dependency has been resolved to continue*/ + if ((subTaskDep.dependencies.inputImageDep != NOT_RESOLVED_DEPENDENCY) && (pSubtaskInfo->subtaskState != SVA_TM_SCHECULED)) + { + t_sva_tm_timestamp immediateTimeStamp={SVA_TM_IMMEDIATE,0}; + + /*pop subtask from list of subtask for which dep has to be solved*/ + ffError=POP_FIFO_ELEM(pDesc->subtasksDependencyFifo,t_sva_tv_subtask_dependencies,subTaskDep); + ffError=PUSH_FIFO_ELEM(pDesc->inUseSubtaskDependency,t_sva_tv_subtask_dependencies,subTaskDep); + /*update state machine*/ + sva_TV_UpdateInstanceStateMachine(instanceNum,SVA_TV_ALL_DEPENDENCIES_RESOLVED); + /*add subtask to list of schedulable subtasks*/ + tmError=sva_TM_AddElemToSubTaskList(pDesc->subtasksListId,subTaskDep.subtaskId,&immediateTimeStamp, 1); + HCL_DEBUG_ASSERT(tmError==SVA_TM_OK); + } + else {dependencyNotSolved=TRUE;} + } + + return SVA_TV_OK; +} + +/****************************************************************************/ +/* NAME: t_sva_st_state sva_TV_UpdateInstanceStateMachine( */ +/* t_sva_service_instance_num instanceNum, */ +/* t_sva_st_transition requestedTransition */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine allows to update both state machine */ +/* following the given requestedTransition */ +/* */ +/* N.B: This routine returns the new state after the requested transition */ +/* A special return state (SVA_TV_TRANSITION_REJECTED) is used to check */ +/* the validity of a transition request */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - instanceNum : instance number for which state must be updated */ +/* - requestedTransition: identifier of the requested transition */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: t_sva_tv_state */ +/* - one of the t_sva_tv_state */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + DONE +*/ +PRIVATE t_sva_tv_state sva_TV_UpdateInstanceStateMachine +( + t_sva_service_instance_num instanceNum, + t_sva_tv_transition requestedTransition +) +{ + t_sva_tv_descriptor *pDesc=&tvoDesc[instanceNum]; + t_sva_tv_state nextState; + t_sva_tv_activate_state nextActivateState; + +#ifdef __DEBUG + { + t_uint32 systemTime; + + SVA_GetServiceSystemTime(pDesc->serviceId,&systemTime); + transitionTvoDebugTable[instanceNum].transitionDebugDesc[transitionTvoDebugTable[instanceNum].nbOfTransitionReceived%LOG_DEPTH].state=pDesc->state; + transitionTvoDebugTable[instanceNum].transitionDebugDesc[transitionTvoDebugTable[instanceNum].nbOfTransitionReceived%LOG_DEPTH].transition=requestedTransition; + transitionTvoDebugTable[instanceNum].transitionDebugDesc[transitionTvoDebugTable[instanceNum].nbOfTransitionReceived%LOG_DEPTH].systemTime=systemTime; + transitionTvoDebugTable[instanceNum].transitionDebugDesc[transitionTvoDebugTable[instanceNum].nbOfTransitionReceived%LOG_DEPTH].activateState=pDesc->activateState; + transitionTvoDebugTable[instanceNum].nbOfTransitionReceived++; + + } +#endif + + /* Compute the next state */ + nextState=stateMachine[pDesc->state][requestedTransition]; + nextActivateState=activateStateMachine[pDesc->activateState][requestedTransition]; + + /* Check if the transition is valid */ + if (nextState != SVA_TV_TRANSITION_REJECTED && nextActivateState!=SVA_TV_ACTIVATE_TRANSITION_REJECTED) + { + /* Update both current state of the instance */ + pDesc->state = nextState; + pDesc->activateState = nextActivateState; + /* Update status*/ + pDesc->status.state=tvoState2ServiceState[pDesc->state]; + } + + return nextState; +} + +/****************************************************************************/ +/* NAME: t_bool sva_TV_isTransitionValid( */ +/* t_sva_service_instance_num instanceNum, */ +/* t_sva_st_transition requestedTransition */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine checks if the requestedTransition is valid for both */ +/* state machine */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - instanceNum : instance number for which transition check must be done*/ +/* - requestedTransition: identifier of the requested transition */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: t_bool */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + DONE +*/ +PRIVATE t_bool sva_TV_isTransitionValid +( + t_sva_service_instance_num instanceNum, + t_sva_tv_transition requestedTransition +) +{ + t_sva_tv_descriptor *pDesc=&tvoDesc[instanceNum]; + t_sva_tv_state nextState; + t_sva_tv_activate_state nextActivateState; + + /* Compute the next state for both state machine*/ + nextState=stateMachine[pDesc->state][requestedTransition]; + nextActivateState=activateStateMachine[pDesc->activateState][requestedTransition]; + + /*return false in case of invalid transition for at least one state machine*/ + if (nextState != SVA_TV_TRANSITION_REJECTED && nextActivateState!=SVA_TV_ACTIVATE_TRANSITION_REJECTED) {return TRUE;} + else {return FALSE;} +} + +/****************************************************************************/ +/* NAME: t_sva_error sva_TV_CheckServiceId(t_sva_service_id serviceId) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will check that task_id and instance number of servideId*/ +/* are both valid */ +/* */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - serviceId: service id to check */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: t_sva_error */ +/* - SVA_UNKNOWN_SERVICE_ID : Invalid service id. Either due to an */ +/* invalid task id or invalid instance number. */ +/* - SVA_OK : Service id is valid */ +/* */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + DONE +*/ +PRIVATE t_sva_error sva_TV_CheckServiceId( + t_sva_service_id serviceId +) +{ + t_sva_service_instance_num instanceNum = READ_INSTANCE_NUM_IN_SERVICE_ID(serviceId); + t_sva_sv_task_id taskId = READ_TASK_ID_IN_SERVICE_ID(serviceId); + + if (taskId!=SVA_SV_TVO_TID) {return SVA_UNKNOWN_SERVICE_ID;} + if (instanceNum>=NUM_MAX_TV) {return SVA_UNKNOWN_SERVICE_ID;} + + return SVA_OK; +} + +/****************************************************************************/ +/* NAME: t_sva_error sva_TV_DoReset( */ +/* t_sva_service_id serviceId */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will reset a service so it can restart after an error. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - serviceId: service identifier */ +/* */ +/* OUT: none */ +/* */ +/* RETURN: t_sva_error */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + DONE +*/ +PRIVATE t_sva_error sva_TV_DoReset +( + t_sva_service_id serviceId +) +{ + (void) serviceId; + + return SVA_OK; +} + +/****************************************************************************/ +/* NAME: t_sva_error sva_TV_DoFlushIn( */ +/* t_sva_service_id serviceId */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will flush input fifo. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - serviceId: service identifier */ +/* */ +/* OUT: none */ +/* */ +/* RETURN: t_sva_error */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +PRIVATE t_sva_error sva_TV_DoFlushIn +( + t_sva_service_id serviceId +) +{ + t_sva_service_instance_num instanceNum = READ_INSTANCE_NUM_IN_SERVICE_ID(serviceId); + t_sva_tv_descriptor *pDesc=&tvoDesc[instanceNum]; + t_sva_tv_subtask_dependencies subtaskDep; + t_sva_timestamp dummyTimeStamp={SVA_NO_TIMESTAMP,0}; + t_sva_buffer_id bufferId; + t_uint32 systemTime; + t_sva_error svaError; + t_sva_tm_error tmError; + t_sva_ff_error ffError; + t_sva_bm_error bmError; + + + (void) dummyTimeStamp; + /*remove schedule tasks and push them back in subtasksDependencyFifo with default dep*/ + /*so they can be rescheduled */ + do + { + tmError=sva_TM_RemoveElemFromSubTaskList(pDesc->subtasksListId,&subtaskDep.subtaskId); + if (tmError==SVA_TM_OK) + { + subtaskDep.dependencies = pDesc->defaultDep; + ffError=PUSH_FIFO_ELEM(pDesc->subtasksDependencyFifo,t_sva_tv_subtask_dependencies,subtaskDep); + if (ffError!=SVA_FIFO_OK) {return SVA_INTERNAL_TV_OUTPUT_ERROR;} + } + } while (tmError==SVA_TM_OK); + /*flush inUseSubtaskDependency fifo*/ + while(POP_FIFO_ELEM(pDesc->inUseSubtaskDependency,t_sva_tv_subtask_dependencies,subtaskDep) != SVA_FIFO_EMPTY) {;} + + /*get time*/ + svaError=SVA_GetServiceSystemTime(serviceId,&systemTime); + if (svaError != SVA_OK) {return SVA_INTERNAL_TV_OUTPUT_ERROR;} + + /*flush fifo*/ + /*flush source fifo*/ + while(POP_FIFO_ELEM(pDesc->inputImageFifos.inUseFifo,t_sva_buffer_id,bufferId) != SVA_FIFO_EMPTY) + { + bmError=sva_BM_UpdateBufferStatus(bufferId,SVA_BUFFER_NOT_USED,systemTime); + if (bmError!=SVA_BM_OK) {return SVA_INTERNAL_TV_OUTPUT_ERROR;} + } + while(POP_FIFO_ELEM(pDesc->inputImageFifos.pushFifo,t_sva_buffer_id,bufferId) != SVA_FIFO_EMPTY) + { + bmError=sva_BM_UpdateBufferStatus(bufferId,SVA_BUFFER_NOT_USED,systemTime); + if (bmError!=SVA_BM_OK) {return SVA_INTERNAL_TV_OUTPUT_ERROR;} + } + + return SVA_OK; +} + +/****************************************************************************/ +/* NAME: t_sva_ec_error sva_TV_ResetStatus( */ +/* t_sva_tvo_status *pStatus */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will reset status descriptor. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - pStatus: status descriptor to reset */ +/* */ +/* OUT: none */ +/* */ +/* RETURN: t_sva_tv_error */ +/* - SVA_TV_OK */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + DONE +*/ +PRIVATE t_sva_tv_error sva_TV_ResetStatus +( + t_sva_tvo_status *pStatus +) +{ + TV_CHECK_NULL_POINTER(pStatus); + + pStatus->state=SVA_SERVICE_NOT_INITIALIZED; + pStatus->errorId=SVA_TVO_ERROR; + pStatus->nbImageDisplayed=0; + pStatus->eventStats.voidedCounter=0; + pStatus->eventStats.filledCounter=0; + pStatus->eventStats.partlyCounter=0; + pStatus->eventStats.readOnlyCounter=0; + pStatus->eventStats.underflowCounter=0; + pStatus->eventStats.overflowCounter=0; + pStatus->eventStats.errorCounter=0; + pStatus->bufferizationStats.inLevel=0; + pStatus->bufferizationStats.outLevel=0; + + return SVA_TV_OK; +} + +/****************************************************************************/ +/* NAME: void sva_TV_ResetDescriptor( */ +/* t_sva_tv_descriptor *pDesc */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine is in charge reset encode descriptor for one instance */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - pDesc: descriptor to reset */ +/* */ +/* OUT: none */ +/* */ +/* RETURN: void */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + DONE +*/ +PRIVATE void sva_TV_ResetDescriptor( + t_sva_tv_descriptor *pDesc +) +{ + TV_CHECK_NULL_POINTER(pDesc); + + sva_TV_ResetStatus(&pDesc->status); +} + +/****************************************************************************/ +/* NAME: t_bool sva_TV_IsConfigurationValid( */ +/* const t_sva_tvo_configuration *pConf */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine will check that given configuration given to tvo is */ +/* valid. */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - pConf: a pointer to the configuration to check */ +/* */ +/* OUT : none */ +/* */ +/* RETURN: t_bool */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + DONE +*/ +PRIVATE t_bool sva_TV_IsConfigurationValid +( + const t_sva_tvo_configuration *pConf +) +{ + t_uint32 swh1; + t_uint32 swh2=0; + t_uint32 svo1; + t_uint32 svo2=0; + t_uint32 dvo1; + t_uint32 dvo2=0; + + TV_CHECK_NULL_POINTER(pConf); + + /* check clockMode enum value range */ + CHECK_RANGE0(pConf->clockMode, SVA_TVO_EXTERNAL_CLOCK_FALLING_EDGE, SVA_TVO_INTERNAL_CLOCK_RISING_EDGE); + + if (pConf->configOutput.isInterlacedEnabled==TRUE) + { + if (pConf->sourceFrameDesc.window.imageOffset.offsetY%2==0) + { + swh1=(pConf->sourceFrameDesc.window.image.height+1)/2; + swh2=(pConf->sourceFrameDesc.window.image.height)/2; + svo1=pConf->sourceFrameDesc.window.imageOffset.offsetY; + svo2=pConf->sourceFrameDesc.window.imageOffset.offsetY+1; + dvo1=pConf->destinationWindowOffsetDesc.offsetY/2; + dvo2=pConf->destinationWindowOffsetDesc.offsetY/2; + } + else + { + swh1=(pConf->sourceFrameDesc.window.image.height)/2; + swh2=(pConf->sourceFrameDesc.window.image.height+1)/2; + svo1=pConf->sourceFrameDesc.window.imageOffset.offsetY+1; + svo2=pConf->sourceFrameDesc.window.imageOffset.offsetY; + dvo1=(pConf->destinationWindowOffsetDesc.offsetY+1)/2; + dvo2=pConf->destinationWindowOffsetDesc.offsetY/2; + } + } + else + { + swh1=pConf->sourceFrameDesc.window.image.height; + svo1=pConf->sourceFrameDesc.window.imageOffset.offsetY; + dvo1=pConf->destinationWindowOffsetDesc.offsetY; + } + /*t_sva_tvo_config_output configOutput*/ + CHECK_RANGE(pConf->configOutput.numberOfLines,SVA_TV_NB_LINES_MIN,SVA_TV_NB_LINES_MAX); + CHECK_RANGE(pConf->configOutput.field1BlankingStartLine,SVA_TV_FIELD1_BLANKING_START_LINE_MIN,pConf->configOutput.numberOfLines); + CHECK_RANGE(pConf->configOutput.field1BlankingEndLine,SVA_TV_FIELD1_BLANKING_END_LINE_MIN,pConf->configOutput.numberOfLines); + if (pConf->configOutput.isInterlacedEnabled==TRUE) + { + CHECK_RANGE(pConf->configOutput.field2BlankingStartLine,SVA_TV_FIELD2_BLANKING_START_LINE_MIN,pConf->configOutput.numberOfLines); + CHECK_RANGE(pConf->configOutput.field2BlankingEndLine,SVA_TV_FIELD2_BLANKING_END_LINE_MIN,pConf->configOutput.numberOfLines); + } + CHECK_RANGE(pConf->configOutput.field1IdentificationStartLine,SVA_TV_FIELD1_IDENT_START_LINE_MIN,pConf->configOutput.numberOfLines); + if (pConf->configOutput.isInterlacedEnabled==TRUE) + { + CHECK_RANGE(pConf->configOutput.field2IdentificationStartLine,SVA_TV_FIELD2_IDENT_START_LINE_MIN,pConf->configOutput.numberOfLines); + } + CHECK_ALIGNMENT(pConf->configOutput.lineBlankingWidth,SVA_TV_LINE_BLANKING_WIDTH_ALIGN); + CHECK_RANGE(pConf->configOutput.lineBlankingWidth,SVA_TV_LINE_BLANKING_WIDTH_MIN,SVA_TV_LINE_BLANKING_WIDTH_MAX); + CHECK_ALIGNMENT(pConf->configOutput.activeLineWidth,SVA_TV_LINE_ACTIVE_WIDTH_ALIGN); + CHECK_RANGE(pConf->configOutput.activeLineWidth,SVA_TV_LINE_ACTIVE_WIDTH_MIN,SVA_TV_LINE_ACTIVE_WIDTH_MAX); + if ((pConf->configOutput.field1BlankingStartLine >= pConf->configOutput.field1IdentificationStartLine || + pConf->configOutput.field1IdentificationStartLine >= pConf->configOutput.field1BlankingEndLine) && + (pConf->configOutput.field1IdentificationStartLine >= pConf->configOutput.field1BlankingEndLine || + pConf->configOutput.field1BlankingEndLine >= pConf->configOutput.field1BlankingStartLine) && + (pConf->configOutput.field1BlankingEndLine >= pConf->configOutput.field1BlankingStartLine || + pConf->configOutput.field1BlankingStartLine >= pConf->configOutput.field1IdentificationStartLine)) + { + return FALSE; + } + if (pConf->configOutput.isInterlacedEnabled==TRUE) + { + if ((pConf->configOutput.field1BlankingStartLine >= pConf->configOutput.field1BlankingEndLine || + pConf->configOutput.field1BlankingEndLine >= pConf->configOutput.field2BlankingStartLine || + pConf->configOutput.field2BlankingStartLine >= pConf->configOutput.field2BlankingEndLine) && + (pConf->configOutput.field1BlankingEndLine >= pConf->configOutput.field2BlankingStartLine || + pConf->configOutput.field2BlankingStartLine >= pConf->configOutput.field2BlankingEndLine || + pConf->configOutput.field2BlankingEndLine >= pConf->configOutput.field1BlankingStartLine) && + (pConf->configOutput.field2BlankingStartLine >= pConf->configOutput.field2BlankingEndLine || + pConf->configOutput.field2BlankingEndLine >= pConf->configOutput.field1BlankingStartLine || + pConf->configOutput.field1BlankingStartLine >= pConf->configOutput.field1BlankingEndLine) && + (pConf->configOutput.field2BlankingEndLine >= pConf->configOutput.field1BlankingStartLine || + pConf->configOutput.field1BlankingStartLine >= pConf->configOutput.field1BlankingEndLine || + pConf->configOutput.field1BlankingEndLine >= pConf->configOutput.field2BlankingStartLine)) + { + return FALSE; + } + if ((pConf->configOutput.field2BlankingStartLine >= pConf->configOutput.field2IdentificationStartLine || + pConf->configOutput.field2IdentificationStartLine >= pConf->configOutput.field2BlankingEndLine) && + (pConf->configOutput.field2IdentificationStartLine >= pConf->configOutput.field2BlankingEndLine || + pConf->configOutput.field2BlankingEndLine >= pConf->configOutput.field2BlankingStartLine) && + (pConf->configOutput.field2BlankingEndLine >= pConf->configOutput.field2BlankingStartLine || + pConf->configOutput.field2BlankingStartLine >= pConf->configOutput.field2IdentificationStartLine)) + { + return FALSE; + } + } + else + { + if (pConf->configOutput.field1BlankingStartLine==pConf->configOutput.field1BlankingEndLine) {return FALSE;} + } + + /*t_sva_windowed_frame_desc sourceFrameDesc*/ + CHECK_ALIGNMENT(pConf->sourceFrameDesc.frame.width,SVA_TV_SOURCE_FRAME_WIDTH_ALIGN); + CHECK_RANGE(pConf->sourceFrameDesc.frame.width, SVA_TV_SOURCE_FRAME_WIDTH_MIN, SVA_TV_SOURCE_FRAME_WIDTH_MAX); + CHECK_ALIGNMENT(pConf->sourceFrameDesc.frame.height,SVA_TV_SOURCE_FRAME_HEIGHT_ALIGN); + CHECK_RANGE(pConf->sourceFrameDesc.frame.height, SVA_TV_SOURCE_FRAME_HEIGHT_MIN, SVA_TV_SOURCE_FRAME_HEIGHT_MAX); + CHECK_ALIGNMENT(pConf->sourceFrameDesc.window.image.width,SVA_TV_WINDOW_FRAME_WIDTH_ALIGN); + CHECK_RANGE(pConf->sourceFrameDesc.window.image.width, SVA_TV_WINDOW_FRAME_WIDTH_MIN, SVA_TV_WINDOW_FRAME_WIDTH_MAX); + CHECK_RANGE0(pConf->sourceFrameDesc.window.image.width, SVA_TV_WINDOW_FRAME_WIDTH_MIN, pConf->sourceFrameDesc.frame.width); + CHECK_RANGE0(pConf->sourceFrameDesc.window.image.width, SVA_TV_WINDOW_FRAME_WIDTH_MIN, pConf->configOutput.activeLineWidth); + if (pConf->configOutput.isInterlacedEnabled==TRUE) + { + CHECK_RANGE(swh1, SVA_TV_WINDOW_WINDOW_FIELD1_HEIGHT_MIN, SVA_TV_WINDOW_WINDOW_FIELD1_HEIGHT_MAX); + CHECK_RANGE(swh2, SVA_TV_WINDOW_WINDOW_FIELD2_HEIGHT_MIN, SVA_TV_WINDOW_WINDOW_FIELD2_HEIGHT_MAX); + if ((2*swh1-1) > pConf->sourceFrameDesc.frame.height || + swh1 > (t_uint32)((pConf->configOutput.field2BlankingStartLine-pConf->configOutput.field1BlankingEndLine)%pConf->configOutput.numberOfLines)) + { + return FALSE; + } + if ((2*swh2-1) > pConf->sourceFrameDesc.frame.height || + swh2 > (t_uint32)((pConf->configOutput.field1BlankingStartLine-pConf->configOutput.field2BlankingEndLine)%pConf->configOutput.numberOfLines)) + { + return FALSE; + } + } + else + { + CHECK_RANGE(swh1, SVA_TV_WINDOW_WINDOW_FIELD1_HEIGHT_MIN, SVA_TV_WINDOW_WINDOW_FIELD1_HEIGHT_MAX); + if (swh1 > pConf->sourceFrameDesc.frame.height || + swh1 > (t_uint32) ((pConf->configOutput.field1BlankingStartLine-pConf->configOutput.field1BlankingEndLine)%pConf->configOutput.numberOfLines)) + { + return FALSE; + } + } + CHECK_ALIGNMENT(pConf->sourceFrameDesc.window.imageOffset.offsetX,SVA_TV_SOURCE_WINDOW_HORIZONTAL_OFFSET_ALIGN); + CHECK_RANGE0(pConf->sourceFrameDesc.window.imageOffset.offsetX, SVA_TV_SOURCE_WINDOW_HORIZONTAL_OFFSET_MIN, pConf->sourceFrameDesc.frame.width); + if (pConf->sourceFrameDesc.window.imageOffset.offsetX > pConf->sourceFrameDesc.frame.width-pConf->sourceFrameDesc.window.image.width) + { + return FALSE; + } + CHECK_RANGE0(svo1, SVA_TV_SOURCE_WINDOW_VERTICAL_OFFSET_MIN, pConf->sourceFrameDesc.frame.height); + if (pConf->configOutput.isInterlacedEnabled==TRUE) + { + if (svo1+2*swh1-1 > pConf->sourceFrameDesc.frame.height) {return FALSE;} + CHECK_RANGE0(svo2, SVA_TV_SOURCE_WINDOW_VERTICAL_OFFSET_MIN, pConf->sourceFrameDesc.frame.height); + if (svo2+2*swh2-1 > pConf->sourceFrameDesc.frame.height) {return FALSE;} + } + else + { + if (svo1+swh1 > pConf->sourceFrameDesc.frame.height) {return FALSE;} + } + + /*t_sva_offset_desc destinationWindowOffsetDesc*/ + CHECK_ALIGNMENT(pConf->destinationWindowOffsetDesc.offsetX,SVA_TV_DEST_HORIZONTAL_OFFSET_ALIGN); + CHECK_RANGE0(pConf->destinationWindowOffsetDesc.offsetX, SVA_TV_DEST_HORIZONTAL_OFFSET_MIN, pConf->configOutput.activeLineWidth); + if (pConf->destinationWindowOffsetDesc.offsetX+pConf->sourceFrameDesc.window.image.width > pConf->configOutput.activeLineWidth) + { + return FALSE; + } + if (pConf->configOutput.isInterlacedEnabled==TRUE) + { + if (dvo1 >= (t_uint32)((pConf->configOutput.field2BlankingStartLine-pConf->configOutput.field1BlankingEndLine)%pConf->configOutput.numberOfLines) || + dvo1+swh1 > (t_uint32)((pConf->configOutput.field2BlankingStartLine-pConf->configOutput.field1BlankingEndLine)%pConf->configOutput.numberOfLines)) + { + return FALSE; + } + } + else + { + if (dvo1 >= (t_uint32)((pConf->configOutput.field1BlankingStartLine-pConf->configOutput.field1BlankingEndLine)%pConf->configOutput.numberOfLines) || + dvo1+swh1 > (t_uint32)((pConf->configOutput.field1BlankingStartLine-pConf->configOutput.field1BlankingEndLine)%pConf->configOutput.numberOfLines)) + { + return FALSE; + } + } + if (pConf->configOutput.isInterlacedEnabled==TRUE) + { + if (dvo2 >= (t_uint32)((pConf->configOutput.field1BlankingStartLine-pConf->configOutput.field2BlankingEndLine)%pConf->configOutput.numberOfLines) || + dvo2+swh2 > (t_uint32)((pConf->configOutput.field1BlankingStartLine-pConf->configOutput.field2BlankingEndLine)%pConf->configOutput.numberOfLines)) + { + return FALSE; + } + } + + /*t_sva_yuv_color backgroundColor*/ + CHECK_RANGE(pConf->backgroundColor.Y, SVA_TV_BACKGROUND_LUMA_MIN, SVA_TV_BACKGROUND_LUMA_MAX); + CHECK_RANGE(pConf->backgroundColor.U, SVA_TV_BACKGROUND_CHROMA_U_MIN, SVA_TV_BACKGROUND_CHROMA_U_MAX); + CHECK_RANGE(pConf->backgroundColor.V, SVA_TV_BACKGROUND_CHROMA_V_MIN, SVA_TV_BACKGROUND_CHROMA_V_MAX); + + return TRUE; +} + +/****************************************************************************/ +/* NAME: t_sva_error sva_TV_BuildParamInStructure( */ +/* const t_sva_tvo_configuration *pConf, */ +/* t_sva_tvo_param_init *pParamInit, */ +/* t_sva_tvo_param_in *pParamIn */ +/* ) */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION: */ +/* This routine builds the paramIn structure from the given configuration */ +/* */ +/* PARAMETERS: */ +/* IN : */ +/* - pConf: provided tvo configuration */ +/* */ +/* OUT: */ +/* - pParamInit : init param to build */ +/* - pParamIn: paramIn structure to build */ +/* */ +/* RETURN: t_sva_error */ +/* */ +/*--------------------------------------------------------------------------*/ +/* REENTRANCY: NA */ +/****************************************************************************/ +/* + DONE +*/ +PRIVATE t_sva_error sva_TV_BuildParamInStructure +( + const t_sva_tvo_configuration *pConf, + t_sva_tvo_param_init *pParamInit, + t_sva_tvo_param_in *pParamIn +) +{ + HCL_DEBUG_ASSERT(pConf != NULL); + HCL_DEBUG_ASSERT(pParamInit != NULL); + HCL_DEBUG_ASSERT(pParamIn != NULL); + + /*fill pParamInit*/ + switch(pConf->clockMode) + { + case SVA_TVO_EXTERNAL_CLOCK_FALLING_EDGE: + pParamInit->clock_signal_selection=0; + pParamInit->clock_edge_selection=0; + break; + case SVA_TVO_EXTERNAL_CLOCK_RISING_EDGE: + pParamInit->clock_signal_selection=0; + pParamInit->clock_edge_selection=1; + break; + case SVA_TVO_INTERNAL_CLOCK_FALLING_EDGE: + pParamInit->clock_signal_selection=1; + pParamInit->clock_edge_selection=0; + break; + case SVA_TVO_INTERNAL_CLOCK_RISING_EDGE: + pParamInit->clock_signal_selection=1; + pParamInit->clock_edge_selection=1; + break; + default: + return SVA_INTERNAL_TV_OUTPUT_ERROR; + /*break;*/ + } + pParamInit->interlace_enable=(t_uint16) pConf->configOutput.isInterlacedEnabled; + pParamInit->number_of_lines=pConf->configOutput.numberOfLines; + pParamInit->field1_blanking_start_line=pConf->configOutput.field1BlankingStartLine; + pParamInit->field1_blanking_end_line=pConf->configOutput.field1BlankingEndLine; + pParamInit->field2_blanking_start_line=pConf->configOutput.field2BlankingStartLine; + pParamInit->field2_blanking_end_line=pConf->configOutput.field2BlankingEndLine; + pParamInit->field1_identification_start_line=pConf->configOutput.field1IdentificationStartLine; + pParamInit->field2_identification_start_line=pConf->configOutput.field2IdentificationStartLine; + pParamInit->line_blanking_witdh=pConf->configOutput.lineBlankingWidth; + pParamInit->active_line_width=pConf->configOutput.activeLineWidth; + + /*fill pParamIn*/ + pParamIn->source_frame_width=pConf->sourceFrameDesc.frame.width; + pParamIn->source_frame_height=pConf->sourceFrameDesc.frame.height; + pParamIn->source_window_width=pConf->sourceFrameDesc.window.image.width; + pParamIn->source_window_horizontal_offset=pConf->sourceFrameDesc.window.imageOffset.offsetX; + pParamIn->destination_window_horizontal_offset=pConf->destinationWindowOffsetDesc.offsetX; + pParamIn->background_y=pConf->backgroundColor.Y; + pParamIn->background_cb=pConf->backgroundColor.U; + pParamIn->background_cr=pConf->backgroundColor.V; + if (pConf->configOutput.isInterlacedEnabled==TRUE) + { + if (pConf->sourceFrameDesc.window.imageOffset.offsetY%2==0) + { + pParamIn->field1_source_window_height=(pConf->sourceFrameDesc.window.image.height+1)/2; + pParamIn->field2_source_window_height=(pConf->sourceFrameDesc.window.image.height)/2; + pParamIn->field1_source_window_vertical_offset=pConf->sourceFrameDesc.window.imageOffset.offsetY; + pParamIn->field2_source_window_vertical_offset=pConf->sourceFrameDesc.window.imageOffset.offsetY+1; + pParamIn->field1_destination_window_vertical_offset=pConf->destinationWindowOffsetDesc.offsetY/2; + pParamIn->field2_destination_window_vertical_offset=pConf->destinationWindowOffsetDesc.offsetY/2; + } + else + { + pParamIn->field1_source_window_height=(pConf->sourceFrameDesc.window.image.height)/2; + pParamIn->field2_source_window_height=(pConf->sourceFrameDesc.window.image.height+1)/2; + pParamIn->field1_source_window_vertical_offset=pConf->sourceFrameDesc.window.imageOffset.offsetY+1; + pParamIn->field2_source_window_vertical_offset=pConf->sourceFrameDesc.window.imageOffset.offsetY; + pParamIn->field1_destination_window_vertical_offset=(pConf->destinationWindowOffsetDesc.offsetY+1)/2; + pParamIn->field2_destination_window_vertical_offset=pConf->destinationWindowOffsetDesc.offsetY/2; + } + } + else + { + pParamIn->field1_source_window_height=pConf->sourceFrameDesc.window.image.height; + pParamIn->field1_source_window_vertical_offset=pConf->sourceFrameDesc.window.imageOffset.offsetY; + pParamIn->field1_destination_window_vertical_offset=pConf->destinationWindowOffsetDesc.offsetY; + } + + return SVA_OK; +} --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/tvo/sva_tvo.h @@ -0,0 +1,89 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ + +#ifndef __INC_SVA_TVO_H +#define __INC_SVA_TVO_H + +#include "sva.h" +#include "svap.h" +#include "sva_taskmgt.h" + +/******************************************************************************/ +/* Constants definitions */ +/******************************************************************************/ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* + * Define the symbols used to identify the various errors of the TVO Module + */ +typedef enum { + SVA_TV_INVALID_TRANSITION = SVA_TV_LAST_ERROR, + SVA_TV_NO_MORE_AVAILABLE_INSTANCE, + SVA_TV_INVALID_INSTANCE_NB, + SVA_TV_INVALID_TASK_ID_NB, + SVA_TV_NOT_SUPPORTED, + SVA_TV_INVALID_CONTROL_PARAM, + SVA_TV_INVALID_PUSH, + SVA_TV_INVALID_BUFFER_TYPE, + SVA_TV_INVALID_BUFFER_SIZE, + SVA_TV_INVALID_CONFIGURATION, + SVA_TV_UNKNOWN_CMD_ID, + SVA_TV_UNEXPECTED_HW_EVENT, + SVA_TV_TI_LINKED_ERROR, + SVA_TV_BM_LINKED_ERROR, + SVA_TV_MM_LINKED_ERROR, + SVA_TV_FF_LINKED_ERROR, + SVA_TV_TM_LINKED_ERROR, + SVA_TV_NULL_POINTER_PARAMETER, + SVA_TV_FIFO_NOT_EMPTY, + SVA_TV_OK = HCL_OK +} t_sva_tv_error; + + +/******************************************************************************* +* PUBLIC Functions +*******************************************************************************/ + +PUBLIC t_sva_error sva_TV_Init(void); +PUBLIC t_sva_error sva_TV_Reset( t_sva_service_id ); +PUBLIC t_sva_error sva_TV_Create( t_sva_service_id *); +PUBLIC t_sva_error sva_TV_Control(t_sva_service_id, t_sva_service_cmd_id, t_uint32 ); +PUBLIC t_sva_error sva_TV_Push(t_sva_service_id, t_sva_buffer_id, t_sva_push_mode, t_sva_buffer_type, t_sva_timestamp ); +PUBLIC t_sva_tv_error sva_TV_DispatchVirtualHwEvent(t_sva_tm_virtual_hw_event_id, t_sva_service_id, t_sva_tm_subtask_id, t_uint32, t_uint32, t_uint8, t_sva_event_desc *, t_uint32 *); +PUBLIC t_sva_error sva_TV_ProvideInternalNeeds( t_sva_service_id); +PUBLIC t_sva_error sva_TV_GetInternalNeeds(t_sva_service_id, t_size *); +PUBLIC t_sva_error sva_TV_Activate(t_sva_service_id, t_sva_service_mode, t_sva_fw_id *); +PUBLIC t_sva_error sva_TV_Inactivate(t_sva_service_id); +PUBLIC t_sva_error sva_TV_Delete(t_sva_service_id ); +PUBLIC t_sva_error sva_TV_GetParamsBufferSize(t_sva_service_id ,t_sva_push_mode ,t_size *); +//t_sva_tvo_configuration is in sva.h +// function is sva.h +//PUBLIC t_sva_error SVA_ConfigureTVOutput( t_sva_service_id, t_sva_tvo_configuration); +//PUBLIC t_sva_error SVA_GetTVOutputStatus(t_sva_service_id, t_sva_tvo_status *); +//PUBLIC t_sva_error SVA_UpdateTVOutputParams(t_sva_service_id, t_sva_update_cmd_type, t_sva_tvo_param_id, t_uint32 ); + +#ifdef __cplusplus +} /* allow C++ to use these headers */ +#endif /* __cplusplus */ + +#endif /* __INC_SVA_TVO_H */ +/* End of file - sva_tvo.h */ --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/tvo/sva_tvop.h @@ -0,0 +1,278 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ + +#ifndef __INC_SVA_TVOP_H +#define __INC_SVA_TVOP_H + +#include "hcl_defs.h" +#include "sva_tvo.h" +#include "sva_taskmgt.h" +#include "sva_buffermgt.h" +#include "sva_fifo.h" +#include "sva_service.h" + +/******************************************************************************/ +/* Constants definitions */ +/******************************************************************************/ +#ifdef __DEBUG + /* + * Define number of event to log + */ + #define LOG_DEPTH 256 +#endif + +/* + * Define the number of field inside a TVO Subtask descriptor (spec v0.96) + */ +#define TV_FIELD_NUMBER 3 + +/* + * Define the default memory used to store subtasks descriptors + */ +#define TV_DEFAULT_MEMORY_ID SDRAM_ID + +/* + * Define the default memory used to store param_out (infos) data + */ +#define TV_DEFAULT_INFOS_MEMORY_ID SDRAM_ID + +/* + * Define macro to handle null pointer +*/ +#define TV_CHECK_NULL_POINTER(pointer) HCL_ASSERT(pointer!=NULL) + +/* + * Define various configuration limits for tvo +*/ +#define SVA_TV_NB_LINES_MIN 6 +#define SVA_TV_NB_LINES_MAX 2047 +#define SVA_TV_FIELD1_BLANKING_START_LINE_MIN 1 +#define SVA_TV_FIELD1_BLANKING_END_LINE_MIN 1 +#define SVA_TV_FIELD2_BLANKING_START_LINE_MIN 1 +#define SVA_TV_FIELD2_BLANKING_END_LINE_MIN 1 +#define SVA_TV_FIELD1_IDENT_START_LINE_MIN 1 +#define SVA_TV_FIELD2_IDENT_START_LINE_MIN 1 +#define SVA_TV_LINE_BLANKING_WIDTH_ALIGN 2 +#define SVA_TV_LINE_BLANKING_WIDTH_MIN 2 +#define SVA_TV_LINE_BLANKING_WIDTH_MAX 2046 +#define SVA_TV_LINE_ACTIVE_WIDTH_ALIGN 2 +#define SVA_TV_LINE_ACTIVE_WIDTH_MIN 2 +#define SVA_TV_LINE_ACTIVE_WIDTH_MAX 2046 + +#define SVA_TV_SOURCE_FRAME_HEIGHT_ALIGN 1 +#define SVA_TV_SOURCE_FRAME_WIDTH_ALIGN 8 +#define SVA_TV_SOURCE_FRAME_HEIGHT_MIN 1 +#define SVA_TV_SOURCE_FRAME_HEIGHT_MAX 2047 +#define SVA_TV_SOURCE_FRAME_WIDTH_MIN 8 +#define SVA_TV_SOURCE_FRAME_WIDTH_MAX 2040 +#define SVA_TV_WINDOW_FRAME_WIDTH_ALIGN 8 +#define SVA_TV_WINDOW_FRAME_WIDTH_MIN 8 +#define SVA_TV_WINDOW_FRAME_WIDTH_MAX 2040 +#define SVA_TV_WINDOW_WINDOW_FIELD1_HEIGHT_MIN 1 +#define SVA_TV_WINDOW_WINDOW_FIELD1_HEIGHT_MAX 2047 +#define SVA_TV_WINDOW_WINDOW_FIELD2_HEIGHT_MIN 1 +#define SVA_TV_WINDOW_WINDOW_FIELD2_HEIGHT_MAX 2047 +#define SVA_TV_SOURCE_WINDOW_HORIZONTAL_OFFSET_ALIGN 2 +#define SVA_TV_SOURCE_WINDOW_HORIZONTAL_OFFSET_MIN 0 +#define SVA_TV_SOURCE_WINDOW_VERTICAL_OFFSET_MIN 0 + +#define SVA_TV_DEST_HORIZONTAL_OFFSET_ALIGN 2 +#define SVA_TV_DEST_HORIZONTAL_OFFSET_MIN 0 + +#define SVA_TV_BACKGROUND_LUMA_MIN 16 +#define SVA_TV_BACKGROUND_LUMA_MAX 235 +#define SVA_TV_BACKGROUND_CHROMA_U_MIN 16 +#define SVA_TV_BACKGROUND_CHROMA_U_MAX 240 +#define SVA_TV_BACKGROUND_CHROMA_V_MIN 16 +#define SVA_TV_BACKGROUND_CHROMA_V_MAX 240 + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/******************************************************************************/ +/* Types definitions */ +/******************************************************************************/ +/* + * Define the various state of a TVO instance service + */ +typedef enum { + SVA_TV_NOT_INITIALIZED, + SVA_TV_WAIT_FOR_CONFIGURATION, + SVA_TV_WAIT_FOR_INTERNAL_NEEDS, + SVA_TV_WAIT_FOR_ACTIVATE, + SVA_TV_WAIT_FOR_START, + SVA_TV_FLUSHING_IN, + SVA_TV_WAIT_FOR_DATA, + SVA_TV_RUNNING, + SVA_TV_ABORT_REQUESTED, + SVA_TV_STOP_REQUESTED, + SVA_TV_ERROR, + SVA_TV_LAST_DUMMY_STATE, + SVA_TV_TRANSITION_REJECTED +} t_sva_tv_state; + +/* + * Define the various activate state of a TVO instance service + */ +typedef enum { + SVA_TV_INACTIVE, + SVA_TV_IN_ACTIVATION, + SVA_TV_ACTIVE, + SVA_TV_IN_INACTIVATION, + SVA_TV_LAST_ACTIVATE_DUMMY_STATE, + SVA_TV_ACTIVATE_TRANSITION_REJECTED +} t_sva_tv_activate_state; + +/* + * Define the various transitions of the stab service + */ +typedef enum { + SVA_TV_CREATE, + SVA_TV_CONFIGURE, + SVA_TV_INTERNAL_NEEDS, + SVA_TV_ACTIVATE, + SVA_TV_INACTIVATE, + SVA_TV_CONTROL_START, + SVA_TV_CONTROL_STOP, + SVA_TV_CONTROL_ABORT, + SVA_TV_ALL_DEPENDENCIES_RESOLVED, + SVA_TV_PUSH, + SVA_TV_EVENT_EOK, + SVA_TV_EVENT_FAKE, + SVA_TV_EVENT_ACTIVE, + SVA_TV_EVENT_INACTIVE, + SVA_TV_RESET, + SVA_TV_CONTROL_DELETE, + SVA_TV_EVENT_ERROR, + SVA_TV_FLUSH_IN, + SVA_TV_CANCEL, + SVA_TV_UPDATE_PARAM, + SVA_TV_GET_PARAM_SIZE, + SVA_TV_LAST_DUMMY_TRANSITION +} t_sva_tv_transition; + +/* + * Define the symbol used to qualify the state of the dependency + * for a given type of buffer + */ +typedef enum { + INTERNAL_DEPENDENCY, + NOT_RESOLVED_DEPENDENCY, + RESOLVED_DEPENDENCY +} t_sva_tv_dependencies_state; + +/* + * Define the structure used to manage the subtasks dependency + */ +typedef struct { + t_sva_tv_dependencies_state inputImageDep; +} t_sva_tv_dependencies_desc; + +/* + * Define the structure used to manage the dependencies of each subtasks + */ +typedef struct { + t_sva_tm_subtask_id subtaskId; + t_sva_tv_dependencies_desc dependencies; +} t_sva_tv_subtask_dependencies; + +/* + * Define the fifos used to manage the dependency + * The buffers, provided though the Push routine, are buffered inside the pushFifo + * When programming them (using them) into a subtask, then they are considered as used, + * as so pushed inside th inUseFifo + */ +typedef struct { + t_sva_fifo pushFifo; + t_sva_fifo inUseFifo; +} t_sva_tv_fifo_dep; + +/* + * Define structure that handle current and next configuration + */ +typedef struct { + t_sva_tvo_configuration currentConf; + t_sva_tvo_configuration nextConf; +} t_sva_tv_conf_handle; + +/* + * Define the descriptor of a TVO service instance + */ +typedef struct { + t_sva_tv_state state; + t_sva_service_id serviceId; + t_sva_tv_activate_state activateState; + t_sva_tv_conf_handle confHandle; + t_sva_tv_dependencies_desc defaultDep; + t_sva_tv_fifo_dep inputImageFifos; + t_sva_fifo subtasksDependencyFifo; + t_sva_fifo inUseSubtaskDependency; + t_sva_tm_subtask_id subtasksIdArray[SUBTASK_TVO_NUMBER]; + t_sva_tm_subtask_list_id subtasksListId; + t_sva_tvo_status status; +} t_sva_tv_descriptor; + +#ifdef __DEBUG + /******************************************************************************/ + /* Trace Types definitions */ + /******************************************************************************/ + typedef struct { + t_sva_tm_virtual_hw_event_id event; + t_uint32 systemTime; + t_sva_tm_subtask_id subtaskId; + t_sva_service_id serviceId; + } t_sva_tv_debug_event_desc; + typedef struct { + t_uint32 padding[3]; + t_uint32 nbOfEventReceived; + t_sva_tv_debug_event_desc eventDebugDesc[LOG_DEPTH]; + } t_sva_tv_debug_events; + + typedef struct { + t_sva_service_cmd_id command; + t_uint32 systemTime; + t_uint32 parameter; + t_uint32 padding; + } t_sva_tv_debug_command_desc; + typedef struct { + t_uint32 padding[3]; + t_uint32 nbOfCommandReceived; + t_sva_tv_debug_command_desc commandDebugDesc[LOG_DEPTH]; + } t_sva_tv_debug_commands; + + typedef struct { + t_sva_tv_state state;/*state before transition occur*/ + t_sva_tv_transition transition; + t_uint32 systemTime; + t_sva_tv_activate_state activateState;/*state before transition occur*/ + } t_sva_tv_debug_transition_desc; + typedef struct { + t_uint32 padding[3]; + t_uint32 nbOfTransitionReceived; + t_sva_tv_debug_transition_desc transitionDebugDesc[LOG_DEPTH]; + } t_sva_tv_debug_transitions; +#endif + +#ifdef __cplusplus +} /* allow C++ to use these headers */ +#endif /* __cplusplus */ + +#endif /* __INC_SVA_TVOP_H */ +/* End of file - sva_tvop.h */ --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/opengl/Makefile @@ -0,0 +1,18 @@ +KERNEL_PATH=./../../linux-2.6.20 +EXTRA_CFLAGS_NAME = $(shell echo $(CONFIG_NOMADIK_TARGET_EXTRA_CFLAGS)) +EXTRA_CFLAGS := $(EXTRA_CFLAGS_NAME) -D__arm -I$(src)/ -I$(src)/../hcl/include/ -I$(src)/../hcl/hloader/ + +#EXTRA_CFLAGS := -I$(src)/ -I$(src)/../hcl/include/ -I$(src)/../hcl/hloader/ + +driver_obj := ogl.o +hloader_obj := ../hcl/hloader/hloader.o + +obj-m += ogles.o + +ogles-objs := $(hloader_obj) $(driver_obj) + +all: + $(MAKE) -C $(KERNEL_PATH) M=`pwd` + +clean : + $(MAKE) -C ../../linux-2.6.20 M=`pwd` clean; rm -f $(hloader_obj) --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/opengl/ogl.c @@ -0,0 +1,565 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ + +#include /* Initiliasation support */ +#include /* Module support */ +#include /* Kernel support */ +#include /* Kernel version */ +#include /* File operations (fops) defines */ +#include /* Charactor device support */ +#include /* Memory/device locking macros */ +#include /* Defines standard error codes */ +#include /* Defines pointer (current) to current task */ +#include +#include /* User space access methods */ +#include +#include +#include +#include + +#include "ogl.h" +#include "ogl_ioctl.h" +#include "hloader.h" + +#define VERSION0 1 +#define VERSION1 0 +#define VERSION2 0 + +static unsigned int major = 0; +static struct cdev *ogl_cdev= NULL; +struct semaphore ogl_lock; + +static struct nomadik_ogl_descriptor* ogl_desc; +static t_loader_config ogl_loader_config; +void *dram_logical_addr,*esram_logical_addr; +dma_addr_t dram_physical_addr,esram_physical_addr; + +struct ogl_fwload_descriptor UserParams; + +#define ALIGN256(x) ((x+31)&~31) + +#define OGLES_DEFAULT_LOG_LEVEL 4 + +int ogles_debug = OGLES_DEFAULT_LOG_LEVEL; +module_param(ogles_debug, int, 0644); +MODULE_PARM_DESC(ogles_debug,"Debug level for messages"); +#define dbgprintk(num, format, args...) \ + do { \ + if(num >= ogles_debug ) \ + printk("OGLES:"format, ##args); \ + } while(0) + + +void ogl_suspend(); +void ogl_resume(); + + +/****************************************************************************** +* Prototype of operation entry points +******************************************************************************/ +//int ogl_open(struct inode *node, struct file *filp); +//int ogl_release(struct inode *node, struct file *filp); +//int ogl_mmap(struct file *fd, struct vm_area_struct *vm); + + +int ogl_mmap(struct file *fd, struct vm_area_struct *vma) +{ + int ret = NULL; + long length = vma->vm_end - vma->vm_start; + char memory_area = vma->vm_pgoff; + + vma->vm_pgoff = 0; // we don't really want any offset, so set to zero + dbgprintk(3, "OGL_DRV INFO - ogl_mmap :memory_area:%d\n",(int)memory_area); + switch (memory_area) + { + case TNL_MEMORY: + vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot); + ret = remap_pfn_range(vma,vma->vm_start, NOMADIK_OGL_BASE >> PAGE_SHIFT, length, vma->vm_page_prot); + dbgprintk(3, "OGL_DRV INFO - TNL_MEMORY : ret:%x,vma->vm_start:%x\n",ret,(unsigned int)vma->vm_start); + break; + case TNL_DEVICE_MEMORY: + dbgprintk(3, "OGL_DRV INFO - TNL_DEVICE_MEMORY :\n"); + vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot); + ret = remap_pfn_range(vma,vma->vm_start, ogl_desc->baseaddr_ogl_phys >> PAGE_SHIFT, length, vma->vm_page_prot); + dbgprintk(3, "OGL_DRV INFO - TNL_DEVICE_MEMORY : ret:%x,vma->vm_start:%x\n",ret,(unsigned int)vma->vm_start); + break; + default: + dbgprintk(3, "OGL_DRV INFO : Invalid memory type\n"); + break; + } + +return ret; + +} + +unsigned int boot_ogl_fw(t_loader_config *p_hloader_config) +{ + unsigned int *p_cgc = (unsigned int*)(ogl_desc->baseaddr_ogl + 0x40010); + unsigned int ret; + + ret = HLOADER_Boot(p_hloader_config); + if (ret == LOADER_OK) + { + dbgprintk(8, "Firmware loaded ok: core_id=%d\n", ogl_loader_config.Context.core_id); + } + else { + dbgprintk(3, "HLOADER_Boot FAILED! (%d)\n", ret); + return -1; + } + + ret = HLOADER_CacheConfig(p_hloader_config, 0x07); + if (ret == LOADER_OK) + dbgprintk(1, "Firmware loaded ok: core_id=%d\n", ogl_loader_config.Context.core_id); + else { + dbgprintk(3, "HLOADER_CacheConfig FAILED! (%d)\n", ret); + return -1; + } + + *p_cgc = (unsigned int)1; //cfg_cgc + return 0; +} + +unsigned int init_zone_addr(t_loader_config *p_hloader_config) +{ + t_uint32 base_progr_zon2; + t_uint32 base_dat16_zon2; + t_uint32 base_dat24_zon1, base_dat24_zon2; + t_uint32 base_mmio_zon; + t_uint32 ret; + +#ifdef OGLES_FW_DYNMEM + /* allocate memory for Program + Data16 static & dynamic + Data24 static & dynamic*/ + fw_logical_addr = (t_uint32) dma_alloc_coherent(NULL, FWM_SDRAM_ALLOCATED_SIZE , + &fw_physical_addr,GFP_KERNEL | GFP_DMA); + + dbgprintk(3, "ogl: init_zone_addr(),fw_logical_addr = %x,fw_physical_addr = %x\n",fw_logical_addr,fw_physical_addr); + + if (fw_logical_addr == NULL) { + dbgprintk(3, "memory allocation for firmware failed\n"); + ret = -ENOMEM; + return ret; + } +#endif + ogl_desc->tnlcommandfifo_baseaddr_ogl = (t_uint32)ioremap_nocache(ogl_desc->tnlcommandfifo_baseaddr_ogl_phys,NOMADIK_OGL_SIZE); + if(!ogl_desc->tnlcommandfifo_baseaddr_ogl){ + dbgprintk(3, "ioremap for FW data zone failed\n"); + ret = -ENOMEM; + return ret; + } + fw_physical_addr = ogl_desc->tnlcommandfifo_baseaddr_ogl_phys + COMMAND_BUFFER_ALLOCATED_SIZE + DRAW_BUFFER_ALLOCATED_SIZE; + fw_logical_addr = ogl_desc->tnlcommandfifo_baseaddr_ogl + COMMAND_BUFFER_ALLOCATED_SIZE + DRAW_BUFFER_ALLOCATED_SIZE; + dbgprintk(3, "ogl: init_zone_addr(),fw_logical_addr = %x,fw_physical_addr = %x\n",(unsigned int)fw_logical_addr,(unsigned int)fw_physical_addr); + + base_progr_zon2 = NULL;//eSRAM2_base; + base_dat16_zon2 = NULL;//eSRAM2_base + SIZE_PROGR_ZON2; + + base_dat24_zon1 = ogl_desc->tnlcommandfifo_baseaddr_ogl_phys + COMMAND_BUFFER_ALLOCATED_SIZE + DRAW_BUFFER_ALLOCATED_SIZE + FWM_SDRAM_ALLOCATED_SIZE; + base_dat24_zon2 = NULL;//eSRAM2_base + SIZE_PROGR_ZON2 + SIZE_DAT16_ZON2; + base_mmio_zon = DMA_APB_BASE_ADDR_1; + + + p_hloader_config->ProgramZone1.Base.physical = fw_physical_addr; + p_hloader_config->ProgramZone1.Base.logical = fw_logical_addr; + p_hloader_config->ProgramZone1.Top.physical = fw_physical_addr + SIZE_PROGR_ZON1 - 1; + p_hloader_config->ProgramZone1.Top.logical = fw_logical_addr + SIZE_PROGR_ZON1 - 1; + p_hloader_config->ProgramZone1.Size = SIZE_PROGR_ZON1; + + p_hloader_config->ProgramZone2.Base.physical = base_progr_zon2; + p_hloader_config->ProgramZone2.Base.logical = base_progr_zon2; + p_hloader_config->ProgramZone2.Top.physical = base_progr_zon2 + SIZE_PROGR_ZON2 - 1; + p_hloader_config->ProgramZone2.Top.logical = base_progr_zon2 + SIZE_PROGR_ZON2 - 1; + + p_hloader_config->Data16Zone1.Base.physical = ogl_desc->tnlcommandfifo_baseaddr_ogl_phys;//TNL_CMD_FIFO_BASEADDR; + p_hloader_config->Data16Zone1.Base.logical = ogl_desc->tnlcommandfifo_baseaddr_ogl;//TNL_CMD_FIFO_BASEADDR; + p_hloader_config->Data16Zone1.Top.physical = ogl_desc->tnlcommandfifo_baseaddr_ogl_phys + SIZE_DAT16_ZON1 - 1; + p_hloader_config->Data16Zone1.Top.logical = ogl_desc->tnlcommandfifo_baseaddr_ogl + SIZE_DAT16_ZON1 - 1; + + p_hloader_config->Data16Zone2.Base.physical = base_dat16_zon2; + p_hloader_config->Data16Zone2.Base.logical = base_dat16_zon2; + p_hloader_config->Data16Zone2.Top.physical = base_dat16_zon2 + SIZE_DAT16_ZON2 - 1; + p_hloader_config->Data16Zone2.Top.logical = base_dat16_zon2 + SIZE_DAT16_ZON2 - 1; + + + p_hloader_config->Data24Zone1.Base.physical = base_dat24_zon1; + p_hloader_config->Data24Zone1.Base.logical = ogl_desc->tnlcommandfifo_baseaddr_ogl + COMMAND_BUFFER_ALLOCATED_SIZE + DRAW_BUFFER_ALLOCATED_SIZE + FWM_SDRAM_ALLOCATED_SIZE;//base_dat24_zon1;// + p_hloader_config->Data24Zone1.Top.physical = base_dat24_zon1 + SIZE_DAT24_ZON1 - 1; + p_hloader_config->Data24Zone1.Top.logical = ogl_desc->tnlcommandfifo_baseaddr_ogl + + COMMAND_BUFFER_ALLOCATED_SIZE + DRAW_BUFFER_ALLOCATED_SIZE + FWM_SDRAM_ALLOCATED_SIZE + SIZE_DAT24_ZON1 - 1;//base_dat24_zon1 + SIZE_DAT24_ZON1 - 1;;// + + p_hloader_config->Data24Zone2.Base.physical = base_dat24_zon2; + p_hloader_config->Data24Zone2.Base.logical = base_dat24_zon2; + p_hloader_config->Data24Zone2.Top.physical = base_dat24_zon2 + SIZE_DAT24_ZON2 - 1; + p_hloader_config->Data24Zone2.Top.logical = base_dat24_zon2 + SIZE_DAT24_ZON2 - 1; + + p_hloader_config->MmioZone.Base.logical = (t_uint32)ioremap(HAMAC_EXT_MMIO_BASE,HAMAC_EXT_MMIO_END - HAMAC_EXT_MMIO_BASE); + if(!p_hloader_config->MmioZone.Base.logical){ + dbgprintk(3, "ioremap for MMIO zone failed\n"); + ret = -ENOMEM; + return ret; + } + p_hloader_config->MmioZone.Base.physical = (t_uint32)HAMAC_EXT_MMIO_BASE; + p_hloader_config->MmioZone.Top.logical = (ogl_loader_config.MmioZone.Base.logical + (HAMAC_EXT_MMIO_END - HAMAC_EXT_MMIO_BASE)); + p_hloader_config->MmioZone.Top.physical = HAMAC_EXT_MMIO_END; + + return 0; +} + +int ogl_boot() +{ + int ret = 0; + + dbgprintk(3, "ogl: firmware size = %x,UserParams.fw_ptr:%x\n",UserParams.fw_size,(unsigned int)UserParams.fw_ptr); + + if(!UserParams.fw_ptr){ + dbgprintk(3, "FW_LOAD error : failed to copy firmware fw->data==NULL\n"); + goto out_release_firmware; + } + if(!UserParams.fw_size){ + dbgprintk(3, "FW_LOAD error : fw size ==0\n"); + goto out_release_firmware; + } + dbgprintk(1, "ogl: firmware size = %x,UserParams.fw_ptr:%x,ogl_desc->baseaddr_ogl:%x,ogl_desc->baseaddr_ogl_phys:%x\n",UserParams.fw_size,(unsigned int)UserParams.fw_ptr,(unsigned int)ogl_desc->baseaddr_ogl,(unsigned int)ogl_desc->baseaddr_ogl_phys); + + /* Initialise the loader */ + ogl_loader_config.HamacBaseAddr.logical = ogl_desc->baseaddr_ogl; + ogl_loader_config.HamacBaseAddr.physical = ogl_desc->baseaddr_ogl_phys; + ogl_loader_config.FirmwareBaseAddr = (t_uint32 *)UserParams.fw_ptr; + ogl_loader_config.FirmwareSize = (t_uint32)UserParams.fw_size; + ogl_loader_config.LoadingInstr = 3; + + ret = HLOADER_Init(&ogl_loader_config); + if (ret == LOADER_OK) + dbgprintk(3, "HLOADER_Init SUCCESS! (%d)\n", ret); + else { + dbgprintk(3, "HLOADER_Init FAILED! (%d)\n", ret); + goto out_release_firmware; + } + + + ret = init_zone_addr(&ogl_loader_config); + if (ret != 0){ + dbgprintk(3, "Error in init_zone_addr \n"); + goto out_release_firmware; + }else + { + dbgprintk(3, "init_zone_addr SUCCESS\n"); + } + + ret = HLOADER_FirmwareLoad(&ogl_loader_config); + if (ret == LOADER_OK) + dbgprintk(3, "HLOADER_FirmwareLoad SUCCESS! (%d)\n", ret); + else { + dbgprintk(3, "HLOADER_FirmwareLoad FAILED! (%d)\n", ret); + goto out_release_firmware; + } + + ret = boot_ogl_fw(&ogl_loader_config); + if (ret != 0){ + dbgprintk(3, "Error in boot_sva_fw. \n"); + goto out_release_firmware; + }else + { + dbgprintk(3, "boot_sva_fw SUCCESS. \n"); + } + + return 0; + +out_release_firmware: + return -1; +} + + +int ogl_open(struct inode *node, struct file *filp){ + + int err = 0; /* No error */ + int major = imajor(node); /* The major number */ + int minor = iminor(node); /* The minor number */ + + vid_switch_sva_suspend(); + + dbgprintk(3, "==> ogl_open called, major = %d, Minor = %d\n",major,minor); + return err; +} + +int ogl_release(struct inode *node, struct file *filp){ + int err = 0; /* No error */ + int major = imajor(node); /* The major number */ + int minor = iminor(node); /* The minor number */ + dbgprintk(3, "==> ogl_release called, major = %d, Minor = %d\n",major,minor); + + vid_switch_sva_resume(); + + return (err); /* If we get here then we have succeeded */ +} +int ogl_ioctl(struct inode *node, struct file *filp, unsigned int cmd, unsigned long arg){ + + int err = 0; + + /*** Execute the command ***/ + switch (cmd) { + + case OGL_IOC_FW_BOOT: + { + + if ((err = copy_from_user(&UserParams, (OGL_Ioctl_fwload_desc *)arg, sizeof(OGL_Ioctl_fwload_desc)) )){ + /* Invalid user space address */ + goto fail; + } + //ogl_desc->tnlcommandfifo_baseaddr_ogl = UserParams.tnlcommandfifo_baseaddr_ogl; + ogl_desc->tnlcommandfifo_baseaddr_ogl_phys = UserParams.tnlcommandfifo_baseaddr_ogl_phys; + dbgprintk(3, "OGL_IOC_FW_BOOT:executing IOCTL command \n"); + if(ogl_desc->fw_boot_done == 0) + { + UserParams.ErrorCode = ogl_boot(); + if(ogl_desc->tnlcommandfifo_baseaddr_ogl) + iounmap((void*)ogl_desc->tnlcommandfifo_baseaddr_ogl); + + if(ogl_loader_config.MmioZone.Base.logical) + iounmap((void*)ogl_loader_config.MmioZone.Base.logical); + + ogl_desc->tnlcommandfifo_baseaddr_ogl=NULL; + ogl_loader_config.MmioZone.Base.logical=NULL; + + } + if(UserParams.ErrorCode == 0) + ogl_desc->fw_boot_done = 1; + else + ogl_desc->fw_boot_done = 0; + UserParams.baseaddr_ogl_phys = ogl_desc->baseaddr_ogl_phys; + if((err = copy_to_user((OGL_Ioctl_fwload_desc*)arg, &UserParams, sizeof(OGL_Ioctl_fwload_desc)))) { + /* Invalid user space address */ + goto fail; + } + + + } + break; + default: + dbgprintk(3, " Invalid IOCTL command \n"); + err = -ENOTTY; + goto fail; + + } + + fail: + return (err); + +} + +/* Various ogl File Operations*/ +static struct file_operations ogl_fops = { + open : ogl_open, + mmap : ogl_mmap, + ioctl : ogl_ioctl, + release : ogl_release, /* close */ +}; + +static int ogles_register_device(void) { + + int err = 0; /* No error */ + dev_t ogl_base_dev_no; + + /* + * Register the major number. If major = 0 then a major number is auto + * allocated. The allocated number is returned. + * The major number can be seen in user space in '/proc/devices' + */ + + if (major == 0) { + if (alloc_chrdev_region(&ogl_base_dev_no, 0, 4, "oglmodule")) { /* 4 is the number of max devices*/ + err = -EBUSY; + dbgprintk(3, "No major numbers for oglmodule by %s (pid %i)\n", current->comm, current->pid); + goto fail; + } + + major = MAJOR(ogl_base_dev_no); + } + else + { + ogl_base_dev_no = MKDEV(major, 0); + if (register_chrdev_region(ogl_base_dev_no, 4, "oglmodule")) { /* 4 is the number of max devices */ + err = -EBUSY; + dbgprintk(3, "No major numbers for oglmodule by %s (pid %i)\n", current->comm, current->pid); + goto fail; + } + } + + if (NULL == (ogl_cdev = cdev_alloc())) { + err = -EBUSY; + dbgprintk(3, "No major numbers for oglmodule by %s (pid %i)\n", current->comm, current->pid); + goto fail_reg; + } + + ogl_cdev->owner = THIS_MODULE; + ogl_cdev->ops = &ogl_fops; + + /* Appears in /var/log/syslog */ + dbgprintk(3, "Load module oglmodule [%d] by %s (pid %i)\n", major, current->comm, current->pid); + + /* Register the device nodes for this module */ + + /* Add the char device structure for this module */ + if (cdev_add(ogl_cdev, ogl_base_dev_no, 4)) { + err = -ENOMEM; + dbgprintk(3, "Failed adding oglmodule by %s (pid %i)\n", current->comm, current->pid); + goto fail_reg; + } + dbgprintk(3, "Welcome to ST Linux !!\n"); + return 0; + +fail_reg: + + /* Unregister the module */ + unregister_chrdev_region(MKDEV(major, 0), 4); + +fail : return (err); +} + +static void ogles_unregister_device(void) { + + /* Remove the char device structure (has been added) */ + cdev_del(ogl_cdev); + + /* Unregister the module */ + unregister_chrdev_region(MKDEV(major, 0), 4); + + dbgprintk(3, "Unload module dumpdata by %s (pid %i)\n", current->comm, current->pid); + dbgprintk(3, "Goodbye ST !! \n"); + +} + +static int ogles_drv_probe(struct platform_device *pdev) +{ + int ret = 0; + struct resource *res; + + dbgprintk (8, "Entering ogles_drv_probe\n"); + + ret = ogles_register_device(); + if (ret) { + printk("OGLES_DRV ERROR : registering misc device fails\n"); + goto out; + } + dbgprintk(5,"OGLES Device Registered\n"); + + ogl_desc = (struct nomadik_ogl_descriptor*) kmalloc(sizeof(struct nomadik_ogl_descriptor), GFP_KERNEL); + if(!ogl_desc) { + dbgprintk(3, "OGL_DRV ERROR : no memory available\n"); + ret = -ENOMEM; + goto out; + } + memset(ogl_desc, 0, sizeof(struct nomadik_ogl_descriptor)); + + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ogles-sva-data-mem"); + if(!res) { + dbgprintk(3, "OGLES_DRV ERROR : no resource found for OGLES data mem region\n"); + ret = -EINVAL; + goto out_kmalloc; + } + + ogl_desc->baseaddr_ogl_phys =res->start; + ogl_desc->baseaddr_ogl = (unsigned long)ioremap_nocache(res->start,(res->end - res->start + 1)); + dbgprintk(3, "ogl_open:ogl_desc->baseaddr_ogl_phys:%x,ogl_desc->baseaddr_ogl:%x\n",(unsigned int)ogl_desc->baseaddr_ogl_phys,(unsigned int)ogl_desc->baseaddr_ogl); + if(!ogl_desc->baseaddr_ogl) { + dbgprintk(3, "OGL_DRV ERROR : Failed to ioremap OGL interface\n"); + ret = -ENOMEM; + goto out_kmalloc; + } + + if(nomadik_clock_enable(NOMADIK_HCLK_SVA)<0){ + dbgprintk(3,"Failed to activate peripheral clock \n"); + ret = -EAGAIN; + goto out_ioremap; + } + + vid_switch_register_ogl_suspend_resume_fn(ogl_suspend,ogl_resume); + + return 0; + + out_ioremap: + iounmap((void*)ogl_desc->baseaddr_ogl); + out_kmalloc: + kfree(ogl_desc); + ogl_desc = NULL; + out: + dbgprintk(3, "OGLES DRV ERROR : ogles probe failed\n"); + + return ret; +} + +static int ogles_drv_remove(struct platform_device *pdev) +{ + dbgprintk (8, "Entering ogles_drv_remove\n"); + + if(ogl_desc->baseaddr_ogl) + iounmap((void*)ogl_desc->baseaddr_ogl); + if(ogl_desc) + kfree(ogl_desc); + +#ifdef OGLES_FW_DYNMEM + if(fw_physical_addr) + dma_free_coherent(NULL, FWM_SDRAM_ALLOCATED_SIZE, (void *)fw_logical_addr, + (dma_addr_t)fw_physical_addr); +#endif + + fw_physical_addr = NULL; + fw_logical_addr = NULL; + + vid_switch_unregister_ogl_suspend_resume_fn(); + ogles_unregister_device(); + return 0; +} + +static struct platform_driver ogles_driver = { + .probe = ogles_drv_probe, + .remove = ogles_drv_remove, + .driver = { + .name = "OGLES", + }, +}; + +static int __init nomadik_ogles_init(void) +{ + return platform_driver_register(&ogles_driver); +} + +static void __exit nomadik_ogles_exit(void) +{ + platform_driver_unregister(&ogles_driver); +} + + +void ogl_suspend() +{ + ogl_desc->fw_boot_done=0; +} + +void ogl_resume() +{ + ogl_desc->fw_boot_done=0; + /*Boot the firmware*/ +} + + + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Jayarami reddy "); +MODULE_DESCRIPTION(" This module is a OGLES module !!"); + +module_init(nomadik_ogles_init); +module_exit(nomadik_ogles_exit); --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/opengl/ogl.h @@ -0,0 +1,65 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ + +// enum identifying memory to map +enum { + TNL_MEMORY = 0, + TNL_DEVICE_MEMORY +}; + + + +char *ogl_buffer; + +unsigned long command_buffer_logical_addr; +dma_addr_t command_buffer_physical_addr; + +unsigned long fw_logical_addr; +dma_addr_t fw_physical_addr; + +#define COMMAND_BUFFER_ALLOCATED_SIZE (16*1024*1024) +#define FWM_SDRAM_ALLOCATED_SIZE (768*1024) +#define DRAW_BUFFER_ALLOCATED_SIZE (13*1024*1024) +#define FWM_DATA24_ALLOCATED_SIZE (256*1024) + +#define DMA_APB_BASE_ADDR_1 0x101C0000 + +#define SIZE_PROGR_ZON1 0x0C3500 //SDRAM +#define SIZE_PROGR_ZON2 0x01E000 //eSRAM +#define SIZE_DAT16_ZON1 0x1000000 //SDRAM (16MB is used) +#define SIZE_DAT16_ZON2 0x006000 //eSRAM +#define SIZE_DAT24_ZON1 0x100000 //SDRAM - unused // can be reduced to 100 or less ! +#define SIZE_DAT24_ZON2 0x009000 //eSRAM +#define SIZE_MMIO_ZON 0x200000 // - from Nomadik mem map starting at 0x101C 0000 + + +/* Open_GL driver descriptor */ +struct nomadik_ogl_descriptor +{ + unsigned long baseaddr_ogl; + unsigned long baseaddr_ogl_phys; + unsigned long tnlcommandfifo_baseaddr_ogl; + unsigned long tnlcommandfifo_baseaddr_ogl_phys; + unsigned int irq; + unsigned int fw_boot_done; +}; + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Jayarami reddy "); +MODULE_DESCRIPTION(" This module is a OGLES module !!"); --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/opengl/ogl_ioctl.h @@ -0,0 +1,56 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ + +#ifndef OGL_IOCTL_H +#define OGL_IOCTL_H + +#include /* Defines macros for ioctl numbers */ + +#define OGL_IOCTL_MAGIC_NUMBER 0X88 +#define TRIALBUFFER_LENGTH 100 +/* enums */ +typedef int OGLError_t; +enum +{ + OGL_SUCCESS = 0, + OGL_ERROR_BAD_PARAMS, + OGL_ERROR_NO_FREE_DEVICE, + OGL_ERROR_NO_EMPTY_BUF, + OGL_ERROR_INVALID_HANDLE +}; + +#define OGL_IOC_FW_BOOT _IOWR(OGL_IOCTL_MAGIC_NUMBER, 0, OGL_Ioctl_fwload_desc*) +struct ogl_fwload_descriptor +{ + /* Error code received by dumping application */ + OGLError_t ErrorCode; + char *fw_ptr; + int fw_size; + unsigned long baseaddr_ogl; + unsigned long baseaddr_ogl_phys; + unsigned long tnlcommandfifo_baseaddr_ogl; + unsigned long tnlcommandfifo_baseaddr_ogl_phys; +}; +typedef struct ogl_fwload_descriptor OGL_Ioctl_fwload_desc; + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Jayarami reddy "); +MODULE_DESCRIPTION(" This module is a OGLES module !!"); + +#endif //OGL_IOCTL_H --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/saa/Makefile @@ -0,0 +1,20 @@ +#KERNEL_PATH := ../../../../../linux-2.6.20 +EXTRA_CFLAGS_NAME = $(shell echo $(CONFIG_NOMADIK_TARGET_EXTRA_CFLAGS)) +EXTRA_CFLAGS := $(EXTRA_CFLAGS_NAME) -D__arm -I$(src)/ -I$(src)/../hcl/include/ -I$(src)/../hcl/saa/ -I$(src)/../hcl/hloader/ +# +#all: +# $(MAKE) -C $(KERNEL_PATH) M=`pwd` +# +# +obj-$(CONFIG_NOMADIK_SAA) += nmdkmod_SAA.o nmdkmod_fwload.o + +driver_obj := nomadik-saa.o +fwload_obj := nomadik-fwload.o + +hcl_obj := ../hcl/saa/hti.o ../hcl/saa/saa_base.o ../hcl/saa/saa_irq.o ../hcl/saa/saa.o ../hcl/hloader/hloader.o + +nmdkmod_SAA-objs := $(hcl_obj) $(driver_obj) +nmdkmod_fwload-objs := $(fwload_obj) + +#clean : +# $(MAKE) -C $(KERNEL_PATH) M=`pwd` clean; rm ../hcl/saa/*.o ../hcl/hloader/*.o --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/saa/README @@ -0,0 +1,72 @@ +SAA driver Build +************************************************************* + +SAA driver is built only as the external module. + +Path is : /vobs/ATS_8815_LINUX/Baseline/linux-2.6.20/drivers/media/nomadik_mm/saa +do make in this folder. it will generate the nmdkmod_SAA.ko, nmdkmod_fwload.ko + +SAA driver depends on DMA, SSP, AUDIOCODEC , FWLOAD(to load firmware file) driver. +Audiocodec driver depends on MSP and I2C. +These driver should be compiled with kernel either as module or static as the case may be. +These driver should be present at run time before inserting SAA driver. + +Audiocodec file is added as the sepearte entity in the +kernel. Path is : "/vobs/ATS_8815_LINUX/Baseline/linux-2.6.20/sound/" +for nhk15 file is "nomadik_stw5095.c" + +This module will export the functionality of nomadik stw5095 audiocodec +to be used by the other drivers in the kernel. Presently both SAA and ALSA +driver will use this module. To enable this module through make menuconfig, choose + +Device Drivers + -----> Sound + ------> Nomadik stw5095 audioc codec generic module + +This will make the module : $TOPDIR/sound/nmdkmod_acodec.ko + + +Firmware file +************************************************************** + +The firmware file required for SAA driver can be found at the path : +/vobs/ATS_8815_LINUX/Baseline/firmware/saa/saa.mmf ( for NHK15 ) + +This file must be put in the ramdisk at the path specified in the fwload application "exe_fwload" + that is "/modules/" etc. + +How to load SAA Driver +************************************************************** + +One can use the following commands to load SAA driver: + +1) mkdir -p /dev/misc +2) mknod /dev/misc/hamaca c 10 230 ( this will create the device node - SAA ) +3) mknod /dev/misc/fw_load c 10 231 ( this will create the device node - FWLOAD ) +4) insmod /modules/nmdkmod_fwload.ko +5) insmod /modules/nmdkmod_SAA.ko + + + + + + + + + + + + + + + + + + + + + + + + + --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/saa/nomadik-fwload.c @@ -0,0 +1,229 @@ +/*--------------------------------------------------------------------------------------------------*/ +/*© copyright STMicroelectronics, 2007. */ +/* */ +/*This program is free software; you can redistribute it and/or modify it under */ +/*the terms of the GNU General Public License as published by the Free */ +/*Software Foundation; either version 2.1 of the License, or (at your option) */ +/*any later version. */ +/* */ +/*This program is distributed in the hope that it will be useful, but WITHOUT */ +/*ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU General Public License for more details. */ +/* */ +/*You should have received a copy of the GNU General Public License */ +/*along with this program. If not, see . */ +/*--------------------------------------------------------------------------------------------------*/ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "nomadik-fwload.h" + +#define VERSION0 1 +#define VERSION1 0 +#define VERSION2 0 + +static struct fwload_descriptor* fw_desc; +static int rgstr_count = 0; + +static int fwload_open(struct inode* inode, struct file* file); +static int fwload_release(struct inode* inode, struct file* file); +static ssize_t fwload_write (struct file* file, const char __user* buffer, size_t size, loff_t * off); + +static struct file_operations fwload_fops = +{ + owner: THIS_MODULE, + open: fwload_open, + release: fwload_release, + write: fwload_write, +}; + +static struct miscdevice fwload_miscdev = +{ + 231, + "fw_load", + &fwload_fops +}; + +static int __init nomadik_fwload_init(void) +{ + int ret = 0; + ret = misc_register(&fwload_miscdev); + if (ret) { + printk("FWLOAD_DRV ERROR : registering FW_misc device fails\n"); + goto out; + } + rgstr_count++; + DBG(1,"FWLOAD Device Registered\n"); + + fw_desc = (struct fwload_descriptor*) kmalloc(sizeof(struct fwload_descriptor), GFP_KERNEL); + if(!fw_desc) { + printk("FWLOAD_DRV ERROR : no memory available\n"); + ret = -ENOMEM; + goto out_misc_register; + } + DBG(1, "fw_desc 0x%x\n",(unsigned int)fw_desc); + memset(fw_desc, 0, sizeof(struct fwload_descriptor)); + init_completion(&fw_desc->completion); + init_MUTEX(&fw_desc->sem); + + return 0; + + out_misc_register: + rgstr_count--; + misc_deregister(&fwload_miscdev); + out: + printk("FWLOAD_DRV ERROR : FW_LOAD probe failed\n"); + + return ret; +} + +static void __exit nomadik_fwload_exit(void) +{ + if(fw_desc) + kfree(fw_desc); + if(rgstr_count) { + rgstr_count--; + misc_deregister(&fwload_miscdev); + } +} + +static int fwload_open(struct inode* inode, struct file* file) +{ + struct kobject *kobj; + if (!(kobj = kobject_get(&(fwload_miscdev.this_device->kobj)))) + return -ENOENT; + + return 0; +} + +static int fwload_release(struct inode* inode, struct file* file) +{ + kobject_put(&(fwload_miscdev.this_device->kobj)); + return 0; +} + +static ssize_t fwload_write (struct file* file, const char __user* buffer, size_t size, loff_t * off) +{ + ssize_t remain; + if(!fw_desc){ + printk("fw_desc ==NULL\n"); + return 0; + } + fw_desc->fw_ptr = vmalloc(size); + if(!fw_desc->fw_ptr) { + printk("Error in vmalloc\n"); + return 0; /*Zero bytes written*/ + } + else + DBG(1, "Success: vmalloc\n"); + DBG(1, "address of buffer 0x%x, size =%d\n",(unsigned int)buffer, size); + down(&fw_desc->sem); + remain = copy_from_user(fw_desc->fw_ptr, buffer, size); + fw_desc->fw_size = size - remain; + if(remain) + printk("%d bytes remaining to be copied\n", remain); + DBG(1, "Inside FW_WRITE, count is %d\n", fw_desc->fw_size); + + up(&fw_desc->sem); + complete(&fw_desc->completion); + + return fw_desc->fw_size; +} + +int getfw_pointer(const struct firmware **fw_p) +{ + int retval; + struct firmware *firmware; + struct kobject *kobj; + + try_module_get(THIS_MODULE); + if (!fw_p) + return -EINVAL; + + *fw_p = firmware = kzalloc(sizeof(*firmware), GFP_KERNEL); + if (!firmware) { + printk(KERN_ERR "%s: kmalloc(struct firmware) failed\n", + __FUNCTION__); + retval = -ENOMEM; + goto out; + } + + /*Generate kevent, which should ultimately hit fwload_write*/ + if (!(kobj = kobject_get(&(fwload_miscdev.this_device->kobj)))) { + retval = -ENOENT; + goto out; + } + kobject_uevent(kobj, KOBJ_CHANGE); + + retval = wait_for_completion_timeout(&fw_desc->completion, 50*HZ);//6*HZ); + if(!retval) { + retval = -EINVAL; + goto out; + } + + down(&fw_desc->sem); + firmware->data = fw_desc->fw_ptr; + firmware->size = fw_desc->fw_size; + up(&fw_desc->sem); + kobject_put(&(fwload_miscdev.this_device->kobj)); + + return 0; +out: + if (firmware) { + if(firmware->data) + vfree(firmware->data); + kfree(firmware); + } + module_put(THIS_MODULE); + return retval; +} +EXPORT_SYMBOL(getfw_pointer); + +int relfw_pointer(const struct firmware *fw_p) +{ + if (fw_p) { + if(fw_p->data) + vfree(fw_p->data); + kfree(fw_p); + } + + module_put(THIS_MODULE); + return 0; +} +EXPORT_SYMBOL(relfw_pointer); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Vaibhav Agarwal "); +MODULE_DESCRIPTION("Nomadik FW_LOAD driver"); + +module_init(nomadik_fwload_init); +module_exit(nomadik_fwload_exit); --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/saa/nomadik-fwload.h @@ -0,0 +1,47 @@ +/*--------------------------------------------------------------------------------------------------*/ +/*© copyright STMicroelectronics, 2007. */ +/* */ +/*This program is free software; you can redistribute it and/or modify it under */ +/*the terms of the GNU General Public License as published by the Free */ +/*Software Foundation; either version 2.1 of the License, or (at your option) */ +/*any later version. */ +/* */ +/*This program is distributed in the hope that it will be useful, but WITHOUT */ +/*ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU General Public License for more details. */ +/* */ +/*You should have received a copy of the GNU General Public License */ +/*along with this program. If not, see . */ +/*--------------------------------------------------------------------------------------------------*/ + +#ifndef _NOMADIK_FWLOAD_H +#define _NOMADIK_FWLOAD_H + +/* Debugging stuff */ + +#ifndef CONFIG_DEBUG_USER +#define DBG_LEVEL 0 +#else +#define DBG_LEVEL 10 +#endif + +#if DBG_LEVEL > 0 +static int fw_debug = DBG_LEVEL; +#define DBG(n, args...) do { if (fw_debug>(n)) printk(args); } while (0) +#else +#define DBG(n, args...) do { } while (0) +#endif + +struct fwload_descriptor +{ + struct semaphore sem; + char *fw_ptr; + size_t fw_size; + struct completion completion; +}; + +int getfw_pointer(const struct firmware **fw_p); +int relfw_pointer(const struct firmware *fw_p); + +#endif --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/saa/nomadik-saa.c @@ -0,0 +1,4406 @@ +/*--------------------------------------------------------------------------------------------------*/ +/*© copyright STMicroelectronics, 2007. */ +/* */ +/*This program is free software; you can redistribute it and/or modify it under */ +/*the terms of the GNU General Public License as published by the Free */ +/*Software Foundation; either version 2.1 of the License, or (at your option) */ +/*any later version. */ +/* */ +/*This program is distributed in the hope that it will be useful, but WITHOUT */ +/*ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU General Public License for more details. */ +/* */ +/*You should have received a copy of the GNU General Public License */ +/*along with this program. If not, see . */ +/*--------------------------------------------------------------------------------------------------*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "saaioctl.h" +#include "nomadik-saa.h" +#include "nomadik-fwload.h" +#include "hloader.h" + +#define VERSION0 1 +#define VERSION1 5 +#define VERSION2 0 + +#define ALIGN256(x) ((x+31)&~31) + +/* bits and mask for the offset are defined considereing PAGE_SHIFT */ +#define SHIFT_BIT_BUFFER_NUMBER PAGE_SHIFT +#define MASK_BUFFER_NUMBER 0x0000000F +#define SHIFT_BIT_BLOCK_ID (SHIFT_BIT_BUFFER_NUMBER + 4) +#define MASK_BLOCK_ID 0x00000FFF +#define SHIFT_BIT_BUF_TYPE (SHIFT_BIT_BLOCK_ID + 12) +#define MASK_BUF_TYPE 0x0000000F + +static struct nomadik_saa_descriptor* saa_desc; +static t_loader_config saa_loader_config; +void *dram_logical_addr,*esram_logical_addr; +dma_addr_t dram_physical_addr,esram_physical_addr; +static const struct firmware *fw; +static char pipename[15]; +static char pipename_ssptx[15]; +static char pipename_ssprx[15]; +#ifdef CONFIG_NOMADIK_PM +static int saa_block_cnt; +#endif + +DECLARE_MUTEX(sem_saa_cmd); +#define SAA_EVENT_LOCK(flags) down(&sem_saa_cmd) +#define SAA_EVENT_UNLOCK(flags) up(&sem_saa_cmd) + +spinlock_t saa_hcl_lock = SPIN_LOCK_UNLOCKED; +#define SAA_HCL_LOCK(flags) spin_lock_irqsave(&saa_hcl_lock,flags) +#define SAA_HCL_UNLOCK(flags) spin_unlock_irqrestore(&saa_hcl_lock,flags) + +//warning removal +extern void l210_flush_range(unsigned long, unsigned long); + +static t_uint32 saa_convert_dsptoarm_address(t_uint32 dsp_address) +{ + t_uint32 arm_address = SAA_DspToArmAddress(dsp_address); + + if (dsp_address >= 0xF60000) + return arm_address - saa_loader_config.Data16Zone2.Base.logical + saa_loader_config.Data16Zone2.Base.physical; // external memory 16 bit (ESRAM) + else if (dsp_address >= 0x800000) + return arm_address - saa_loader_config.Data16Zone1.Base.logical + saa_loader_config.Data16Zone1.Base.physical; // external memory 16 bit (SDRAM) + else if (dsp_address >= 0x400000) + return arm_address - saa_loader_config.Data24Zone2.Base.logical + saa_loader_config.Data24Zone2.Base.physical; // external memory 24 bit (ESRAM) + else if (dsp_address >= 0x10000) + return arm_address - saa_loader_config.Data24Zone1.Base.logical + saa_loader_config.Data24Zone1.Base.physical; // external memory 24 bit (SDRAM) + else + return arm_address - saa_desc->baseaddr_saa + saa_desc->baseaddr_saa_phys; // SAA internal memory +} + +/** + * static void put_message (struct instance_descriptor* id, saa_message_info* msg,enum buffer_type buf_type) : + * + * @instance_descriptor* id: description of arg1 + * @saa_message_info* msg: description of arg2 + * @enum buffer_type buf_type : Buffer ( DMA/SHM ) that has produced the message + * + * Longer Description of function + **/ + +static void put_message (struct instance_descriptor* id, saa_message_info* msg, enum buffer_type buf_type) +{ + saa_message_info* existing; + void* existing_ptr = id->message_buffer; + int overwrite = 0; + /*unsigned long flags;*/ + + existing = (saa_message_info*)id->message_buffer; + + /* If existing message of the same type exists, just update the hardware ptr. */ + if(buf_type == SAA_BUFFER_TYPE_DMA) { + while (existing_ptr != id->current_pos) + { + if (msg->generic_msg.type == existing->generic_msg.type) + { + switch (existing->generic_msg.type) + { + case SAA_BUFFER_CONSUMED: + if (msg->buffer_consumed.block_id == existing->buffer_consumed.block_id) + overwrite=1; + break; + case SAA_BUFFER_PRODUCED: + if (msg->buffer_produced.block_id == existing->buffer_produced.block_id) + overwrite=1; + break; + case SAA_UNDERFLOW_OCCURRED: + if (msg->underflow_occured.block_id == existing->underflow_occured.block_id) + overwrite=1; + break; + case SAA_OVERFLOW_OCCURRED: + if (msg->overflow_occured.block_id == existing->overflow_occured.block_id) + overwrite=1; + break; + default: + break; + } + if (overwrite) + { + msg->generic_msg.message_id = existing->generic_msg.message_id; + memcpy(existing, msg, sizeof(saa_message_info)); + DEBUG(1, "Updated message type:%i\n", msg->generic_msg.type); + wake_up_interruptible(&id->message_wqueue); + return; + } + } + existing_ptr += sizeof(saa_message_info); + existing++; + } + } + + if ((MSG_BUFFER_SIZE - (id->current_pos - id->message_buffer)) < sizeof(saa_message_info)){ + printk ("SAA_DRV ERROR : put_message: No more space in message buffer\n"); + return; + } + msg->generic_msg.message_id = id->message_id++; + memcpy (id->current_pos, msg, sizeof(saa_message_info)); + id->current_pos += sizeof(saa_message_info); + DEBUG(1, "Added message %li : %i\n", msg->generic_msg.message_id, msg->generic_msg.type); + wake_up_interruptible(&id->message_wqueue); + return; +} + + +static void notify_underflow (struct buffer_info* buffer) +{ + saa_message_info msg; + unsigned long flags; + + msg.underflow_occured.type = SAA_UNDERFLOW_OCCURRED; + msg.underflow_occured.block_id = buffer->block_id; + spin_lock_irqsave(&(buffer->id->message_lock),flags); + put_message (buffer->id, &msg,buffer->buf_type); + spin_unlock_irqrestore(&(buffer->id->message_lock),flags); +} + + +static void notify_overflow (struct buffer_info* buffer) +{ + saa_message_info msg; + unsigned long flags; + + msg.overflow_occured.type = SAA_OVERFLOW_OCCURRED; + msg.overflow_occured.block_id = buffer->block_id; + spin_lock_irqsave(&(buffer->id->message_lock),flags); + put_message (buffer->id, &msg,buffer->buf_type); + spin_unlock_irqrestore(&(buffer->id->message_lock),flags); +} + + +void handle_circular_buffer(struct buffer_info* buffinfo_elem,t_uint16 frame_size) +{ + unsigned int advc_ptr, foll_ptr; + saa_message_info msg; + unsigned long flags; + + /* Advance the hw pointer. */ + buffinfo_elem->hw_ptr++; + buffinfo_elem->hw_ptr = (buffinfo_elem->hw_ptr % buffinfo_elem->frame_count); + DEBUG(1 ,"Handler circular buffer : Got blockid::%i, new hw_ptr:%u, app_ptr:%u\n", buffinfo_elem->block_id, buffinfo_elem->hw_ptr, buffinfo_elem->app_ptr); + + /* Add message to the instance. */ + if (buffinfo_elem->direction == SAA_DATA_DIRECTION_IN) + { + msg.buffer_produced.type = SAA_BUFFER_CONSUMED; + } + else + { + msg.buffer_produced.type = SAA_BUFFER_PRODUCED; + } + msg.buffer_produced.block_id = buffinfo_elem->block_id; + msg.buffer_produced.hw_ptr = buffinfo_elem->hw_ptr; + msg.buffer_produced.frame_size = frame_size; + + spin_lock_irqsave(&(buffinfo_elem->id->message_lock),flags); + put_message(buffinfo_elem->id, &msg,buffinfo_elem->buf_type); + spin_unlock_irqrestore(&(buffinfo_elem->id->message_lock),flags); + + + if(buffinfo_elem->buf_type == SAA_BUFFER_TYPE_DMA) { + /* set advancing pointer and following pointer. */ + if (buffinfo_elem->direction == SAA_DATA_DIRECTION_IN){ + advc_ptr = buffinfo_elem->app_ptr; + foll_ptr = buffinfo_elem->hw_ptr; + }else { + foll_ptr = buffinfo_elem->app_ptr; + advc_ptr = buffinfo_elem->hw_ptr; + } + + /* TODO: Accumulate the foll conditions into one. */ + /* Underflow first. */ + if (foll_ptr == advc_ptr && buffinfo_elem->direction == SAA_DATA_DIRECTION_IN ) { + DEBUG (6, "Underflow 3\n"); + notify_underflow (buffinfo_elem); + /* set the flag for xfer completed. */ + spin_lock(&buffinfo_elem->xfer_lock); + buffinfo_elem->xfer_done = 1; + spin_unlock(&buffinfo_elem->xfer_lock); + + /* notify waiting process. */ + wake_up_interruptible(&buffinfo_elem->xfer_queue); + return; + } + + /* Check Overflow. */ + if (advc_ptr == foll_ptr && buffinfo_elem->direction == SAA_DATA_DIRECTION_OUT ) { + DEBUG (6, "Overflow 3\n"); + notify_overflow (buffinfo_elem); + /* set the flag for xfer completed. */ + spin_lock(&buffinfo_elem->xfer_lock); + buffinfo_elem->xfer_done = 1; + spin_unlock(&buffinfo_elem->xfer_lock); + + /* notify waiting process. */ + wake_up_interruptible(&buffinfo_elem->xfer_queue); + return; + } + } else { + spin_lock(&buffinfo_elem->xfer_lock); + buffinfo_elem->xfer_done = 1; + spin_unlock(&buffinfo_elem->xfer_lock); + } +} + +/** + * dma_eot_handler - SAA DMA pipe callback for dma transfer completion. + * + * @void* param: pipe specific private data pointer. Its value is specified at + * callback registration and used to handle the struct buffer_info* data structure pointer. + * + * This function is the end of transfer callback routine for a DMA pipe. + * It is called by the DMA subsystem upon a DMA transfer completion on the buffer. + **/ + +irqreturn_t dma_eot_handler(int irq, void *param) +{ + struct buffer_info* buffinfo_elem = (struct buffer_info*)param; + unsigned long vm_start,vm_end; + + handle_circular_buffer(buffinfo_elem,0); + + spin_lock(&buffinfo_elem->xfer_lock); + if(buffinfo_elem->xfer_done == 1) { + spin_unlock(&buffinfo_elem->xfer_lock); + return IRQ_HANDLED; + } + spin_unlock(&buffinfo_elem->xfer_lock); + + /* Incase further buffers are available, start transfer. */ + if (SAA_DATA_DIRECTION_IN == buffinfo_elem->direction) + { + __set_dma_srcaddr(buffinfo_elem->dma_pipe_id, + (buffinfo_elem->buffer_base_address_phys + + (buffinfo_elem->hw_ptr * buffinfo_elem->frame_len))); + } + else + { + __set_dma_destaddr(buffinfo_elem->dma_pipe_id, + (buffinfo_elem->buffer_base_address_phys + + (buffinfo_elem->hw_ptr * buffinfo_elem->frame_len))); + } + set_dma_count(buffinfo_elem->dma_pipe_id, buffinfo_elem->frame_len); + + vm_start = buffinfo_elem->vma->vm_start + (buffinfo_elem->hw_ptr * buffinfo_elem->frame_len); + vm_end = vm_start + buffinfo_elem->frame_len + 1; +#if !defined(CONFIG_L2CACHE_ENABLE) + flush_cache_range(buffinfo_elem->vma,vm_start,vm_end); +#endif + DEBUG(1, "CALLBACK handler : enabling the dma transfer for the pipe = %d\n",buffinfo_elem->dma_pipe_id); + enable_dma(buffinfo_elem->dma_pipe_id); + DEBUG(1, "CALLBACK handler : after enabling dma\n"); + return IRQ_HANDLED; +} + +void saa_shm_released_handler(saa_event_map* event_ptr) +{ + struct list_head* element; + struct buffer_info* buffinfo_elem; + int i,flag=0; + t_uint32 buffer_address; + struct saa_block_info* block_info; + + buffer_address = ((t_uint32)event_ptr->params.iAlertShmBufferReleasedParams.buffer_add_msb << 16) | + event_ptr->params.iAlertShmBufferReleasedParams.buffer_add_lsb; + + DEBUG(1,"ESAA_FW_ALERT_SHM_BUFFER_RELEASED received from block id = %d\n",event_ptr->server_id); + DEBUG(1,"dsp buffer address = %x\n",(int)buffer_address); + + block_info = search_for_block_info(event_ptr->server_id); + if(!block_info) { + printk("block already deleted\n"); + return; + } + + buffinfo_elem = NULL; + spin_lock(&(block_info->instance->bufferinfo_lock)); + list_for_each(element,&(block_info->instance->bufferinfo_list)) { + buffinfo_elem = list_entry(element, struct buffer_info, list); + for(i=0;ishm_nb_buffers;i++) { + if(buffinfo_elem->shm_dsp_buffer_address[i] == buffer_address) { + flag = 1; + break; + } + } + if(flag == 1) + break; + } + spin_unlock(&(block_info->instance->bufferinfo_lock)); + + if(flag == 1) + handle_circular_buffer(buffinfo_elem,0); +} + +void saa_shm_ready_handler(saa_event_map* event_ptr) +{ + struct list_head* element; + struct buffer_info* buffinfo_elem; + int i,flag=0; + t_uint32 buffer_address; + t_uint16 frame_size; + struct saa_block_info* block_info; + + buffer_address = ((t_uint32)event_ptr->params.iAlertShmBufferReadyParams.buffer_add_msb << 16) | + event_ptr->params.iAlertShmBufferReadyParams.buffer_add_lsb; + frame_size = event_ptr->params.iAlertShmBufferReadyParams.frame_size; + + DEBUG(1,"ESAA_FW_ALERT_SHM_BUFFER_READY received from block id = %d\n",event_ptr->server_id); + DEBUG(1,"dsp buffer address = %x frame size = %hu\n",(int)buffer_address,frame_size); + + block_info = search_for_block_info(event_ptr->server_id); + if(!block_info) { + printk("block already deleted\n"); + return; + } + + buffinfo_elem = NULL; + spin_lock(&(block_info->instance->bufferinfo_lock)); + list_for_each(element,&(block_info->instance->bufferinfo_list)) { + buffinfo_elem = list_entry(element, struct buffer_info, list); + for(i=0;ishm_nb_buffers;i++) { + if(buffinfo_elem->shm_dsp_buffer_address[i] == buffer_address) { + flag = 1; + break; + } + } + if(flag == 1) + break; + } + spin_unlock(&(block_info->instance->bufferinfo_lock)); + + if(flag == 1) + handle_circular_buffer(buffinfo_elem,frame_size); +} + +void saa_eof_handler(saa_event_map* event_ptr) +{ + saa_message_info msg; + struct saa_block_info *block_info; + unsigned long flags; + + msg.eof_reached.type = SAA_EOF_REACHED; + msg.eof_reached.block_id = event_ptr->server_id; + msg.eof_reached.filesize = ((__u64)event_ptr->params.iAlertEofReachedParams.file_size_high << 32) | + ((__u32)event_ptr->params.iAlertEofReachedParams.file_size_mid << 16) | + event_ptr->params.iAlertEofReachedParams.file_size_low; + + DEBUG(8, "EOF alert\n"); + DEBUG(8, " cmd_nb = %u\n", event_ptr->params.iAlertEofReachedParams.cmd_nb); + DEBUG(8, " block id = %u\n", event_ptr->server_id); + DEBUG(8, " port_id = %u\n", event_ptr->params.iAlertEofReachedParams.port_id); + DEBUG(8, " component_id = %u\n", event_ptr->params.iAlertEofReachedParams.component_id); + DEBUG(8, " file_size_high = %u\n", event_ptr->params.iAlertEofReachedParams.file_size_high); + DEBUG(8, " file_size_mid = %u\n", event_ptr->params.iAlertEofReachedParams.file_size_mid); + DEBUG(8, " file_size_low = %u\n", event_ptr->params.iAlertEofReachedParams.file_size_low); + DEBUG(8, " origin = %u\n", event_ptr->params.iAlertEofReachedParams.origin); + + block_info = search_for_block_info(event_ptr->server_id); + if(block_info) { + spin_lock_irqsave(&(block_info->instance->message_lock),flags); + put_message(block_info->instance,&msg,SAA_BUFFER_TYPE_SHM); + spin_unlock_irqrestore(&(block_info->instance->message_lock),flags); + DEBUG(8, "EOF message posted on the message queue\n"); + }else + printk("block already deleted\n"); + +} + +void saa_change_data_format_handler(saa_event_map* event_ptr) +{ + saa_message_info msg; + struct saa_block_info *block_info; + unsigned long flags; + + msg.change_data_format.type = SAA_CHANGE_DATA_FORMAT; + msg.change_data_format.block_id = event_ptr->server_id; + msg.change_data_format.sample_freq = event_ptr->params.iAlertChangeDataFormatParams.sample_freq; + msg.change_data_format.channel_nb = event_ptr->params.iAlertChangeDataFormatParams.channel_nb; + msg.change_data_format.endianess = event_ptr->params.iAlertChangeDataFormatParams.endianess; + msg.change_data_format.interleaving = event_ptr->params.iAlertChangeDataFormatParams.interleaving; + + DEBUG(8, "\nReceived Change Data Format from block id %u\n", event_ptr->server_id); + DEBUG(8, " Channel ID = %u\n", event_ptr->params.iAlertChangeDataFormatParams.channel_id); + DEBUG(8, " Channel number = %u\n", event_ptr->params.iAlertChangeDataFormatParams.channel_nb); + DEBUG(8, " Frequency = %u\n", event_ptr->params.iAlertChangeDataFormatParams.sample_freq); + DEBUG(8, " Sample size = %u bits\n", event_ptr->params.iAlertChangeDataFormatParams.sample_size); + + block_info = search_for_block_info(event_ptr->server_id); + if(block_info) { + spin_lock_irqsave(&(block_info->instance->message_lock),flags); + put_message(block_info->instance,&msg,SAA_BUFFER_TYPE_SHM); + spin_unlock_irqrestore(&(block_info->instance->message_lock),flags); + }else + printk("block already deleted\n"); +} + +void saa_codec_error_alert_handler(saa_event_map* event_ptr) +{ + saa_message_info msg; + struct saa_block_info *block_info; + unsigned long flags; + + msg.codec_error.type = SAA_CODEC_ERROR; + msg.codec_error.block_id = event_ptr->server_id; + + DEBUG(8, "Received Codec Error from block id %u\n", event_ptr->server_id); + + block_info = search_for_block_info(event_ptr->server_id); + if(block_info) { + spin_lock_irqsave(&(block_info->instance->message_lock),flags); + put_message(block_info->instance,&msg,SAA_BUFFER_TYPE_SHM); + spin_unlock_irqrestore(&(block_info->instance->message_lock),flags); + }else + printk("block already deleted\n"); +} + +void saa_shm_bad_frame_alert_handler(saa_event_map* event_ptr) +{ + saa_message_info msg; + struct saa_block_info *block_info; + unsigned long flags; + + msg.shm_bad_frame.type = SAA_SHM_BAD_FRAME; + msg.shm_bad_frame.block_id = event_ptr->server_id; + + block_info = search_for_block_info(event_ptr->server_id); + if(block_info) { + spin_lock_irqsave(&(block_info->instance->message_lock),flags); + put_message(block_info->instance,&msg,SAA_BUFFER_TYPE_SHM); + spin_unlock_irqrestore(&(block_info->instance->message_lock),flags); + }else + printk("block already deleted\n"); +} + +void saa_stream_corrupt_alert_handler(saa_event_map* event_ptr) +{ + struct saa_block_info *block_info; + struct buffer_info* buffinfo_elem; + struct list_head* element; + + block_info = search_for_block_info(event_ptr->server_id); + if(!block_info) { + printk("block already deleted\n"); + return; + } + + buffinfo_elem = NULL; + spin_lock(&(block_info->instance->bufferinfo_lock)); + list_for_each(element,&(block_info->instance->bufferinfo_list)) { + buffinfo_elem = list_entry(element, struct buffer_info, list); + if(buffinfo_elem->block_id == event_ptr->server_id){ + if(buffinfo_elem->buf_type == SAA_BUFFER_TYPE_SHM) { + saa_shm_bad_frame_alert_handler(event_ptr); + break; + } + } + } + spin_unlock(&(block_info->instance->bufferinfo_lock)); +} + +void saa_error_detected_alert_handler(saa_event_map* event_ptr) +{ + saa_message_info msg; + struct saa_block_info *block_info; + unsigned long flags; + + msg.error_detected.type = SAA_ERROR_DETECTED; + msg.error_detected.block_id = event_ptr->server_id; + msg.error_detected.error_id = event_ptr->params.iAlertErrorDetectedParams.error_id; + + switch (msg.error_detected.error_id) + { + case ESAA_FW_WARNING_STREAM_CORRUPT: + saa_stream_corrupt_alert_handler(event_ptr); + break; + + case ESAA_FW_PROTOCOL_CODEC_ERROR: + saa_codec_error_alert_handler(event_ptr); + break; + + default: + DEBUG(8, "Received Error Detected from block id %u\n", event_ptr->server_id); + DEBUG(8, "error id = %u\n", event_ptr->params.iAlertErrorDetectedParams.error_id); + + block_info = search_for_block_info(event_ptr->server_id); + if(block_info) + { + spin_lock_irqsave(&(block_info->instance->message_lock),flags); + put_message(block_info->instance,&msg,SAA_BUFFER_TYPE_SHM); + spin_unlock_irqrestore(&(block_info->instance->message_lock),flags); + } + else + { + printk("block already deleted\n"); + } + } + + DEBUG(1,"returning for saa_error_detected_alert_handler\n"); +} + +void saa_codec_info_alert_handler(saa_event_map* event_ptr) +{ + saa_message_info msg; + struct saa_block_info *block_info; + unsigned long flags; + + msg.codec_info.type = SAA_CODEC_INFO; + msg.codec_info.block_id = event_ptr->server_id; + msg.codec_info.sample_freq = event_ptr->params.iAlertCodecInfoParams.sample_freq; + msg.codec_info.channel_nb = event_ptr->params.iAlertCodecInfoParams.channel_nb; + + DEBUG (8, "Received Codec Info from block id %u\n", event_ptr->server_id); + DEBUG (8, "Sample Freq = %u\n", event_ptr->params.iAlertCodecInfoParams.sample_freq); + DEBUG (8, "Channel number = %u\n", event_ptr->params.iAlertCodecInfoParams.channel_nb); + + block_info = search_for_block_info(event_ptr->server_id); + if(block_info) { + spin_lock_irqsave(&(block_info->instance->message_lock),flags); + put_message(block_info->instance,&msg,SAA_BUFFER_TYPE_SHM); + spin_unlock_irqrestore(&(block_info->instance->message_lock),flags); + }else + printk("block already deleted\n"); +} + + +void saa_dtmf_detected_alert_handler(saa_event_map* event_ptr) +{ + saa_message_info msg; + struct saa_block_info *block_info; + unsigned long flags; + + msg.dtmf_detected.type = SAA_DTMF_DETECTED; + msg.dtmf_detected.block_id = event_ptr->server_id; + msg.dtmf_detected.comp_id = event_ptr->params.iAlertAepDtmfParams.component_id; + msg.dtmf_detected.code = event_ptr->params.iAlertAepDtmfParams.dtmf_code; + + DEBUG (8, "\nReceived AEP DTMF from block id %u\n", event_ptr->server_id); + DEBUG (8, "\ncomponent id %u\n", event_ptr->params.iAlertAepDtmfParams.component_id); + DEBUG (8, "\nDTMF code %u\n", event_ptr->params.iAlertAepDtmfParams.dtmf_code); + + block_info = search_for_block_info(event_ptr->server_id); + if(block_info) { + spin_lock_irqsave(&(block_info->instance->message_lock),flags); + put_message(block_info->instance,&msg,SAA_BUFFER_TYPE_SHM); + spin_unlock_irqrestore(&(block_info->instance->message_lock),flags); + }else + printk("block already deleted\n"); +} + + +static t_bool saa_parse_event (saa_event_map* event_ptr) +{ + t_uint16 i; + + i = 0; +#if defined(__GNUC__) && (__GNUC__ < 4) + /* GCA FIX for wrong padding */ + for (i=15;i>=4;i--) + { + ((t_uint16*)event_ptr)[i]=((t_uint16*)event_ptr)[i-1]; + } + /* GCA END fix for wrong padding */ +#endif + + if (event_ptr->cmd_nb == 0) + { + /*this is an alert or another asynchronous message*/ + switch (event_ptr->alert_id) + { + case ESAA_FW_ALERT_BOOT_FINISHED: + saa_desc->fw_boot_done = 1; + wake_up_interruptible(&saa_desc->cmd_wait_queue); + DEBUG (1, "\nESAA_FW_ALERT_BOOT_FINISHED Received. Boot Finished\n"); + break; + + case ESAA_FW_ALERT_ERROR_DETECTED: + saa_error_detected_alert_handler(event_ptr); + break; + + case ESAA_FW_ALERT_CHANGE_DATA_FORMAT: + saa_change_data_format_handler(event_ptr); + break; + + case ESAA_FW_ALERT_EOF: + saa_eof_handler(event_ptr); + break; + + case ESAA_FW_ALERT_CODEC_INFO: + saa_codec_info_alert_handler(event_ptr); + break; + + case ESAA_FW_ALERT_HSI_RESET_CONNECTION_BB: + DEBUG (1, "\nReceived HSI Reset from block id %u\n", event_ptr->server_id); + break; + + case ESAA_FW_ALERT_AEP_DTMF: + saa_dtmf_detected_alert_handler(event_ptr); + break; + + case ESAA_FW_ALERT_SHM_BUFFER_READY: + saa_shm_ready_handler(event_ptr); + break; + + case ESAA_FW_ALERT_SHM_BUFFER_RELEASED: + saa_shm_released_handler(event_ptr); + break; + + case ESAA_FW_ALERT_AEP_AUDIO_VISU: + DEBUG (1, "\nReceived ESAA_FW_ALERT_AEP_AUDIO_VISU from block id %u\n", event_ptr->server_id); + break; + + case ESAA_FW_ALERT_READY_FOR_SLOW_SPEED: + DEBUG (1, "\nReceived ESAA_FW_ALERT_READY_FOR_SLOW_SPEED from block id %u\n", event_ptr->server_id); + break; + + case ESAA_FW_ALERT_NEED_NORMAL_SPEED: + DEBUG (1, "\nReceived ESAA_FW_ALERT_NEED_NORMAL_SPEED from block id %u\n", event_ptr->server_id); + break; + + case ESAA_FW_ALERT_HSI_BURST_COMPLETE: + DEBUG (1, "\nReceived ESAA_FW_ALERT_HSI_BURST_COMPLETE from block id %u\n", event_ptr->server_id); + break; + + case ESAA_FW_ALERT_HSI_ALLOW_SLEEP_MODE: + DEBUG (1, "\nReceived ESAA_FW_ALERT_HSI_BURST_COMPLETE from block id %u\n", event_ptr->server_id); + break; + + default: + DEBUG (1, "\nReceived unknown message id 0x%04X from block id %u\n", event_ptr->alert_id, event_ptr->server_id); + } + } + else { + /* this is an answer to a command: do nothing*/ + + DEBUG(1, "Answer for the command = %d\n",event_ptr->cmd_nb); + saa_desc->cmd_nb = event_ptr->cmd_nb; + //printk("coping the event\n"); + memcpy(&saa_desc->cmd_event_map, event_ptr, sizeof(saa_event_map)); + //printk("waking up the process\n"); + wake_up_interruptible(&saa_desc->cmd_wait_queue); + + } + + DEBUG(1,"returning for parse event\n"); + return TRUE; +} + +/** + * irqreturn_t saa_int_handler(int irq, void* p) : Hamac Audio interrupt handler. + * + * @int irq : the IRQ line that has been raised + * @void* p: interrupt line private data specified during interrupt handler registration. + * entered the interrupt context. + * + * This function is registered at driver's initialization as the interrupts service routine + * for the Hamac Audio interrupt lines. It acknowledges the interrupt source and processes + * the event. + **/ + +irqreturn_t saa_int_handler(int irq, void* p) +{ + saa_error ret; + t_uint16 nb_msg = 0; + saa_event_map event_map; + + SAA_DisableIRQSrc(ESAA_SRC_IRQ_0); + SAA_DisableIRQSrc(ESAA_SRC_IRQ_1); + DEBUG(1,"IRQ_0 interrupt %i arrived \n", irq); + + SAA_ClearIRQSrc(ESAA_SRC_IRQ_0); + ret = SAA_GetIRQSrcStatus(ESAA_SRC_IRQ_0); + if(ret != ESAA_ERROR_NONE) { + printk("SAA_DRV ERROR : SAA_GetIRQSrcStatus %i\n", ret); + SAA_EnableIRQSrc(ESAA_SRC_IRQ_0); + SAA_EnableIRQSrc(ESAA_SRC_IRQ_1); + return IRQ_HANDLED; + } + + while(SAA_GetPendingEvent((t_saa_event_desc*)&event_map, &nb_msg) != ESAA_ERROR_NO_PENDING_EVENT) { + DEBUG(1,"parsing the event no of message %d\n",nb_msg); + saa_parse_event(&event_map); + } + + DEBUG(1,"parsing of all the evnets done\n"); + SAA_EnableIRQSrc(ESAA_SRC_IRQ_0); + SAA_EnableIRQSrc(ESAA_SRC_IRQ_1); + + return IRQ_HANDLED; +} + +/** + * irqreturn_t saa_int_handler1(int irq, void* p) : Hamac Audio interrupt handler. + * + * @int irq : the IRQ line that has been raised + * @void* p: interrupt line private data specified during interrupt handler registration. + * entered the interrupt context. + * + * This function is registered at driver's initialization as the interrupts service routine + * for the Hamac Audio interrupt lines. It acknowledges the interrupt source and processes + * the event. + **/ + +irqreturn_t saa_int_handler1(int irq, void* p) +{ + saa_error ret; + + SAA_DisableIRQSrc(ESAA_SRC_IRQ_0); + SAA_DisableIRQSrc(ESAA_SRC_IRQ_1); + DEBUG(1,"IRQ_1 interrupt %i arrived \n", irq); + + SAA_ClearIRQSrc(ESAA_SRC_IRQ_1); + ret = SAA_GetIRQSrcStatus(ESAA_SRC_IRQ_1); + if(ret != ESAA_ERROR_NONE) { + printk("SAA_DRV ERROR : SAA_GetIRQSrcStatus %i\n", ret); + SAA_EnableIRQSrc(ESAA_SRC_IRQ_0); + SAA_EnableIRQSrc(ESAA_SRC_IRQ_1); + return IRQ_HANDLED; + } + + SAA_EnableIRQSrc(ESAA_SRC_IRQ_0); + SAA_EnableIRQSrc(ESAA_SRC_IRQ_1); + + return IRQ_HANDLED; +} + +static int allocate_buffer (struct instance_descriptor* id, saa_alloc_iobuff_struct* bd) +{ + struct buffer_info* new_buff = NULL; + struct list_head* element; + struct buffer_info* buffinfo_elem; + unsigned long flags; + + switch(bd->buf_type) { + case SAA_BUFFER_TYPE_DMA : + new_buff = (struct buffer_info*)kmalloc (sizeof(struct buffer_info), GFP_KERNEL); + if (new_buff == NULL) { + printk ("SAA_DRV ERROR : FATAL:No memory for buffer_info\n"); + return -ENOMEM; + } + memset (new_buff, 0, sizeof(struct buffer_info)); + + spin_lock_irqsave(&id->bufferinfo_lock,flags); + list_add (&new_buff->list, &id->bufferinfo_list); + spin_unlock_irqrestore(&id->bufferinfo_lock,flags); + + /*Do the actual buffer allocation here.*/ + new_buff->buffer_base_address_virt = dma_alloc_coherent(NULL,bd->frame_len*bd->frame_count, + &new_buff->buffer_base_address_phys,GFP_KERNEL | GFP_DMA); + + if (new_buff->buffer_base_address_virt == NULL) { + printk ("SAA_DRV ERROR : Unable to allocate buffer memory\n"); + kfree (new_buff); + return -ENOMEM; + } + + bd->offset = ((SAA_BUFFER_TYPE_DMA << SHIFT_BIT_BUF_TYPE) | (bd->block_id << SHIFT_BIT_BLOCK_ID)) ; + DEBUG(6, "DMA Buffer offset is = %x\n",bd->offset); + + DEBUG (6, "Allocated Buffer: Base phys:%08x, virt:%08x\n", + (int)new_buff->buffer_base_address_phys, (int)new_buff->buffer_base_address_virt); + + new_buff->frame_count = bd->frame_count; + break; + case SAA_BUFFER_TYPE_SHM : + DEBUG(6 , "Allocating memory for SHM mode\n"); + /*Find the given buffer in buffer list.*/ + buffinfo_elem = NULL; + spin_lock_irqsave(&id->bufferinfo_lock,flags); + list_for_each(element,&id->bufferinfo_list) { + buffinfo_elem = list_entry(element, struct buffer_info, list); + if ((buffinfo_elem->block_id) == bd->block_id) + break; + buffinfo_elem = NULL; + } + spin_unlock_irqrestore(&id->bufferinfo_lock,flags); + + if (buffinfo_elem == NULL) { + new_buff = (struct buffer_info*)kmalloc (sizeof(struct buffer_info), GFP_KERNEL); + if (new_buff == NULL) { + printk("SAA_DRV ERROR : FATAL:No memory for buffer_info\n"); + return -ENOMEM; + } + memset (new_buff, 0, sizeof(struct buffer_info)); + spin_lock_irqsave(&id->bufferinfo_lock,flags); + list_add (&new_buff->list, &id->bufferinfo_list); + spin_unlock_irqrestore(&id->bufferinfo_lock,flags); + + } else { + DEBUG(6, "SHM bufferinfo alraedy allocated\n"); + new_buff = buffinfo_elem; + } + + new_buff->shm_nb_buffers++; + bd->offset = ((SAA_BUFFER_TYPE_SHM << SHIFT_BIT_BUF_TYPE) | (bd->block_id << SHIFT_BIT_BLOCK_ID) + | (new_buff->shm_nb_buffers << SHIFT_BIT_BUFFER_NUMBER)) ; + DEBUG(6, "Buffer offset is = %x\n",bd->offset); + + new_buff->frame_count = new_buff->shm_nb_buffers; + break; + default : + break; + } + + new_buff->buf_type = bd->buf_type; + new_buff->frame_len = bd->frame_len; + new_buff->block_id = bd->block_id; + new_buff->hw_ptr = new_buff->app_ptr = 0; + new_buff->id = id; + new_buff->xfer_lock = SPIN_LOCK_UNLOCKED; + new_buff->xfer_done = 1; + init_waitqueue_head(&new_buff->xfer_queue); + + return 0; +} + +static int link_buffer(struct instance_descriptor* id, saa_link_iobuff_struct* lbb) +{ + struct list_head* element; + struct buffer_info* buffinfo_elem; + struct nmdk_dma_info pipe_params; + int dma_error; + t_uint32 page_address; + unsigned long flags; + + switch(lbb->buf_type) { + case SAA_BUFFER_TYPE_DMA : + /*Find the given buffer in buffer list.*/ + buffinfo_elem = NULL; + spin_lock_irqsave(&id->bufferinfo_lock,flags); + list_for_each(element,&id->bufferinfo_list) { + buffinfo_elem = list_entry(element, struct buffer_info, list); + if ((buffinfo_elem->block_id) == lbb->block_id) + break; + buffinfo_elem = NULL; + } + spin_unlock_irqrestore(&id->bufferinfo_lock,flags); + + if (buffinfo_elem == NULL) { + printk ("SAA_DRV ERROR : link_buffer: buffer base not found!!!"); + return -EINVAL; + } + + buffinfo_elem->direction = lbb->direction; + /*Allocate DMA pipe.*/ + if (lbb->direction == SAA_DATA_DIRECTION_IN) { + sprintf(pipename, "saa%d", lbb->config.dma.channel_id); + pipe_params.mode = DMA_QUEUE_ENABLED | DMA_EXCH_PRIORITY_UNDEFINED | DMA_PIPE_RESERVED | DMA_DOUBLE_BUFFERED | FLOW_CNTRL_DMA(MEM_TO_PERIPH); + pipe_params.srcdevtype = "mem"; + pipe_params.destdevtype = pipename; + pipe_params.config = 0; //DMA_DEVCONFIG_SRC(DMA_DEVCONFIG_WIDTH(DMA_WIDTH_HALFWORD)); +// pipe_params.config |= DMA_DEVCONFIG_DEST(DMA_DEVCONFIG_WIDTH(DMA_WIDTH_HALFWORD)); + }else { + sprintf(pipename, "saa%d", lbb->config.dma.channel_id); + pipe_params.mode = DMA_QUEUE_ENABLED | DMA_EXCH_PRIORITY_UNDEFINED | DMA_PIPE_RESERVED | DMA_DOUBLE_BUFFERED | FLOW_CNTRL_DMA(PERIPH_TO_MEM); + pipe_params.srcdevtype = pipename; + pipe_params.destdevtype = "mem"; + pipe_params.config = 0; //DMA_DEVCONFIG_SRC(DMA_DEVCONFIG_WIDTH(DMA_WIDTH_HALFWORD)); +// pipe_params.config |= DMA_DEVCONFIG_DEST(DMA_DEVCONFIG_WIDTH(DMA_WIDTH_HALFWORD)); + } + + buffinfo_elem->dma_pipe_id = request_available_dma(&pipe_params); + + if (buffinfo_elem->dma_pipe_id < 0 ) { + printk("SAA_DRV ERROR : link_buffer Opening pipe: %i\n", dma_error); + return -EIO; + } + DEBUG(1, "DMA pipe allocated id = %d transfer mode = %dn",buffinfo_elem->dma_pipe_id, pipe_params.mode); + /* Configure HA DMA device. */ + if (lbb->direction == SAA_DATA_DIRECTION_IN) { + /* saa_desc->in_dma_channel = buffinfo_elem->dma_pipe_id;*/ + __set_dma_destaddr(buffinfo_elem->dma_pipe_id, + (lbb->config.dma.buffer_address - saa_desc->baseaddr_saa + + saa_desc->baseaddr_saa_phys) ); + }else { + /* saa_desc->out_dma_channel = buffinfo_elem->dma_pipe_id;*/ + __set_dma_srcaddr(buffinfo_elem->dma_pipe_id, + (lbb->config.dma.buffer_address - saa_desc->baseaddr_saa + + saa_desc->baseaddr_saa_phys) ); + } + set_dma_count(buffinfo_elem->dma_pipe_id, (2*lbb->config.dma.buffer_size)); + + /* + * Register the callback function for Abouve requested DMA channel + * free_irq will be called by dma layer from the context of free_dma() + */ + dma_error = request_irq(IRQNO_FOR_DMACH(buffinfo_elem->dma_pipe_id), + dma_eot_handler, 0, 0, (void*)buffinfo_elem); + if (dma_error < 0) { + printk("DMA pipe callbk function allocation failed\n"); + free_dma(buffinfo_elem->dma_pipe_id); + return dma_error; + } + break; + case SAA_BUFFER_TYPE_SHM : + DEBUG(6, "Linked the buffer for SHM\n"); + /*Find the given buffer in buffer list.*/ + buffinfo_elem = NULL; + spin_lock_irqsave(&id->bufferinfo_lock,flags); + list_for_each(element,&id->bufferinfo_list) { + buffinfo_elem = list_entry(element, struct buffer_info, list); + if ((buffinfo_elem->block_id) == lbb->block_id) + break; + buffinfo_elem = NULL; + } + spin_unlock_irqrestore(&id->bufferinfo_lock,flags); + + if (buffinfo_elem == NULL) { + printk ("SAA_DRV ERROR : link_buffer: buffer base not found!!!"); + return -EINVAL; + } + + buffinfo_elem->direction = lbb->direction; + buffinfo_elem->shm_dsp_buffer_address[buffinfo_elem->shm_nb_buffers - 1] = lbb->config.shm_buffer_address; + buffinfo_elem->shm_buffer_address[buffinfo_elem->shm_nb_buffers - 1] = saa_convert_dsptoarm_address(lbb->config.shm_buffer_address); + + DEBUG(6, "ARM address for SHM buffer = %x\n",(int)buffinfo_elem->shm_buffer_address[buffinfo_elem->shm_nb_buffers - 1]); + page_address = (buffinfo_elem->shm_buffer_address[buffinfo_elem->shm_nb_buffers - 1] & PAGE_MASK); + buffinfo_elem->shm_buffer_offset[buffinfo_elem->shm_nb_buffers - 1] = buffinfo_elem->shm_buffer_address[buffinfo_elem->shm_nb_buffers - 1] - page_address; + DEBUG(6, "ARM page address for SHM buffer = %x and offset = %x\n",(int)page_address, + (int)buffinfo_elem->shm_buffer_offset[buffinfo_elem->shm_nb_buffers - 1]); + + break; + default : + break; + } + + return 0; +} + +static int get_shmbuf_offset(struct instance_descriptor* id, saa_shmbuf_offset *shmbuf) +{ + struct list_head* element; + struct buffer_info* buffinfo_elem; + unsigned long flags; + + DEBUG(6, "Getting the buffer offset for SHM\n"); + /*Find the given buffer in buffer list.*/ + buffinfo_elem = NULL; + spin_lock_irqsave(&id->bufferinfo_lock,flags); + list_for_each(element,&id->bufferinfo_list) { + buffinfo_elem = list_entry(element, struct buffer_info, list); + if ((buffinfo_elem->block_id) == shmbuf->block_id) + break; + buffinfo_elem = NULL; + } + spin_unlock_irqrestore(&id->bufferinfo_lock,flags); + + if (buffinfo_elem == NULL) { + printk ("SAA_DRV ERROR : link_buffer: buffer base not found!!!"); + return -EINVAL; + } + + shmbuf->offset = buffinfo_elem->shm_buffer_offset[buffinfo_elem->shm_nb_buffers - 1]; + return 0; +} + +static int xfer_buffer(struct instance_descriptor* id, saa_xfer_iobuff_struct *tb) +{ + struct list_head* element; + struct buffer_info* buffinfo_elem; + int err = 0; + saa_error error; + signed int shm_app_ptr=0; + unsigned long vm_start,vm_end; + unsigned long flags,bufferinfo_flags,xfer_flags; + + switch(tb->buf_type) { + case SAA_BUFFER_TYPE_DMA : + /* first, check and enable transceive, if such a case. */ + + if (id->msp_in_block.block_id == tb->block_id) { + DEBUG(2,"SAA-DRV:ENABLING MSP IN BLOCK DMA TRANSFER:\n"); + DEBUG(5, "Starting Transceive on block:pipe=%i:%i\n", tb->block_id, id->msp_in_block.msp_dma_channel); + while(dma_channel_active(id->msp_in_block.msp_dma_channel)); + enable_dma(id->msp_in_block.msp_dma_channel); + return 0; + }else if (id->msp_out_block.block_id == tb->block_id){ + DEBUG(2,"SAA-DRV:ENABLING MSP OUT BLOCK DMA TRANSFER:\n"); + DEBUG(5, "Starting Transceive on block:pipe=%i:%i\n", tb->block_id, id->msp_out_block.msp_dma_channel); + while(dma_channel_active(id->msp_out_block.msp_dma_channel)); + enable_dma(id->msp_out_block.msp_dma_channel); + return 0; + }else if((id->ssp_in_block.block_id == tb->block_id) || (id->ssp_out_block.block_id == tb->block_id)){ + if(id->spi_desc.flag_spi_transfer) { + DEBUG(8, "SAA transfer started\n"); + err = spi_async(id->spi_desc.spi, id->spi_desc.msg); + if(err) + printk("SAA : spi_async failed\n"); + }else { + DEBUG(8, "SAA transfer not started\n"); + ++id->spi_desc.flag_spi_transfer; + } + + return err; + } + + spin_lock_irqsave(&id->bufferinfo_lock,bufferinfo_flags); + if (list_empty(&id->bufferinfo_list)) { + printk ("SAA_DRV ERROR : xfer_buffer: no buffer is linked!!!"); + spin_unlock_irqrestore(&id->bufferinfo_lock,bufferinfo_flags); + return -EINVAL; + } + + /*Find the buffer queue.*/ + buffinfo_elem = NULL; + list_for_each(element,&id->bufferinfo_list) { + buffinfo_elem = list_entry(element, struct buffer_info, list); + if (buffinfo_elem->block_id == tb->block_id) + break; + buffinfo_elem = NULL; + } + spin_unlock_irqrestore(&id->bufferinfo_lock,bufferinfo_flags); + + if (buffinfo_elem == NULL) { + printk ("SAA_DRV ERROR : xfer_buffer: buffer with given blockid not found!!!"); + return -EINVAL; + } + + /* Set the new application pointer. */ + spin_lock_irqsave(&buffinfo_elem->xfer_lock,xfer_flags); + buffinfo_elem->app_ptr = tb->app_ptr; + DEBUG (6, "xfer_buffer: Got new app ptr: %u and hw_ptr = %u\n", buffinfo_elem->app_ptr, buffinfo_elem->hw_ptr); + + if((tb->type & TYPE_NOBLOCK) && (buffinfo_elem->xfer_done == 0)) { + spin_unlock_irqrestore(&buffinfo_elem->xfer_lock,xfer_flags); + DEBUG(15,"SAA-DRV: returned since ongoing transfer\n"); + return 0; + } + buffinfo_elem->xfer_done = 0; + spin_unlock_irqrestore(&buffinfo_elem->xfer_lock,xfer_flags); + + /* Set transfer params depending upton direction of transfer.*/ + if(SAA_DATA_DIRECTION_IN == buffinfo_elem->direction) { + __set_dma_srcaddr(buffinfo_elem->dma_pipe_id, + (buffinfo_elem->buffer_base_address_phys + + (buffinfo_elem->hw_ptr * buffinfo_elem->frame_len)) ); + } else { + __set_dma_destaddr(buffinfo_elem->dma_pipe_id, + (buffinfo_elem->buffer_base_address_phys + + (buffinfo_elem->hw_ptr * buffinfo_elem->frame_len)) ); + } + set_dma_count(buffinfo_elem->dma_pipe_id, buffinfo_elem->frame_len); + DEBUG(2,"SAA-DRV:ENABLING DMA TRANSFER FOR BUFFER:\n"); + + vm_start = buffinfo_elem->vma->vm_start + (buffinfo_elem->hw_ptr * buffinfo_elem->frame_len); + vm_end = vm_start + buffinfo_elem->frame_len + 1; +#if !defined(CONFIG_L2CACHE_ENABLE) + flush_cache_range(buffinfo_elem->vma,vm_start,vm_end); +#endif + DEBUG(1, "enabling the dma transfer for the pipe = %d\n",buffinfo_elem->dma_pipe_id); + if (dma_channel_active(buffinfo_elem->dma_pipe_id)) { + printk ("SAA_DRV ERROR : TRANSFERBUFF starting DMA: pipe id = %d\n", buffinfo_elem->dma_pipe_id); + printk("SAA_DRV ERROR : xfer_done = %d \n", buffinfo_elem->xfer_done); + return -EIO; + + } else { + enable_dma (buffinfo_elem->dma_pipe_id); + } + + /* if blocking mode reqd, wait for xfer completion. */ + if (tb->type & TYPE_BLOCK) + wait_event_interruptible(buffinfo_elem->xfer_queue, buffinfo_elem->xfer_done); + + break; + case SAA_BUFFER_TYPE_SHM : + spin_lock_irqsave(&id->bufferinfo_lock,bufferinfo_flags); + if (list_empty(&id->bufferinfo_list)) { + printk ("SAA_DRV ERROR : xfer_buffer: no buffer is linked!!!"); + spin_unlock_irqrestore(&id->bufferinfo_lock,bufferinfo_flags); + return -EINVAL; + } + + /*Find the buffer queue.*/ + buffinfo_elem = NULL; + list_for_each(element,&id->bufferinfo_list) { + buffinfo_elem = list_entry(element, struct buffer_info, list); + if (buffinfo_elem->block_id == tb->block_id) + break; + buffinfo_elem = NULL; + } + spin_unlock_irqrestore(&id->bufferinfo_lock,bufferinfo_flags); + + if (buffinfo_elem == NULL) { + printk ("SAA_DRV ERROR : xfer_buffer: buffer with given blockid not found!!!"); + return -EINVAL; + } + + /* Set the new application pointer. */ + buffinfo_elem->app_ptr = tb->app_ptr; + DEBUG (1, "SHM xfer_buffer: Got new app ptr: %u and hw_ptr = %u\n", buffinfo_elem->app_ptr, buffinfo_elem->hw_ptr); + + if(SAA_DATA_DIRECTION_IN == buffinfo_elem->direction) { + DEBUG(1, "Sending SHMBufferReady command\n"); + shm_app_ptr = tb->app_ptr - 1; + if(shm_app_ptr < 0) + shm_app_ptr = buffinfo_elem->frame_count - 1; + + vm_start = buffinfo_elem->shm_vma[shm_app_ptr]->vm_start; + vm_end = buffinfo_elem->shm_vma[shm_app_ptr]->vm_end; +#if !defined(CONFIG_L2CACHE_ENABLE) + flush_cache_range(buffinfo_elem->shm_vma[shm_app_ptr],vm_start,vm_end); +#endif + SAA_HCL_LOCK(flags); + error = SAA_SHMBufferReady(tb->block_id, buffinfo_elem->shm_transfer_nb++, buffinfo_elem->shm_dsp_buffer_address[shm_app_ptr], + tb->frame_size, tb->bfi); + SAA_HCL_UNLOCK(flags); + if(error != ESAA_ERROR_NONE) { + printk("SAA_SHMBufferReady failed. error = %dn",error); + return -EINVAL; + } + }else { + DEBUG(1, "Sending SHMBufferReleased command\n"); + shm_app_ptr = tb->app_ptr - 1; + if(shm_app_ptr < 0) + shm_app_ptr = buffinfo_elem->frame_count - 1; + DEBUG(6, "shm_app_ptr = %u\n",shm_app_ptr); + SAA_HCL_LOCK(flags); + error = SAA_SHMBufferReleased(tb->block_id, buffinfo_elem->shm_transfer_nb++, buffinfo_elem->shm_dsp_buffer_address[shm_app_ptr], + tb->frame_size); + SAA_HCL_UNLOCK(flags); + if(error != ESAA_ERROR_NONE) { + printk("SAA_SHMBufferReady failed. error = %dn",error); + return -EINVAL; + } + vm_start = buffinfo_elem->shm_vma[shm_app_ptr]->vm_start; + vm_end = buffinfo_elem->shm_vma[shm_app_ptr]->vm_end; +#if !defined(CONFIG_L2CACHE_ENABLE) + flush_cache_range(buffinfo_elem->shm_vma[shm_app_ptr],vm_start,vm_end); +#endif + } + + /* if blocking mode reqd, wait for xfer completion. */ + if (tb->type & TYPE_BLOCK) { + wait_event_interruptible(buffinfo_elem->xfer_queue, buffinfo_elem->xfer_done); + } + break; + default : + break; + } + return 0; +} + +/*Linking of Block with MSP. +*/ +static int link_msp (struct instance_descriptor* id, saa_msp_connect_struct* mc) +{ + struct nmdk_dma_info pipe_params; + int acodec_error = CODEC_OK; + dmach_t dmaid; + + /* + * Configure Audiocodec. + * Note:Since one block can be associated with only one direction of MSP, we + * take a single arg for codec freq, and assume the direction is not INOUT. + */ + + if((saa_desc->msp_in_flag == 0) && (saa_desc->msp_out_flag == 0)) + acodec_error = nomadik_acodec_setuser(USER_SAA); + if(acodec_error) + return acodec_error; +#ifdef VOICE_MODE_ENABLE + if((CODEC_SAMPLING_FREQ_8KHZ == mc->codec_freq) || (CODEC_SAMPLING_FREQ_16KHZ == mc->codec_freq )) { + acodec_error = nomadik_acodec_enable_voice_mode (mc->codec_direction, mc->codec_freq, mc->codec_freq,mc->msp_clock_sel,mc->msp_clock_freq, USER_SAA); + if (acodec_error != CODEC_OK) { + printk ("SAA_DRV ERROR : configuring audiocodec:%i\n", acodec_error); + return acodec_error; + } + DEBUG(3,"Audiocodec setin voice mode \n"); + }else +#endif +{ + acodec_error = nomadik_acodec_enable_audio_mode (mc->codec_direction, mc->codec_freq, mc->codec_freq,mc->msp_clock_sel,mc->msp_clock_freq, USER_SAA); + if (acodec_error != CODEC_OK) { + printk ("SAA_DRV ERROR : configuring audiocodec:%i\n", acodec_error); + return acodec_error; + } + DEBUG(3,"Audiocodec setin audio mode\n"); + } + + //no need to do default settings again... + /*Configure volume/gain settings for audiocodec*/ + /* + acodec_error = nomadik_acodec_set_volume(DEFAULT_GAIN, DEFAULT_GAIN, DEFAULT_VOLUME, DEFAULT_VOLUME, USER_SAA); + if (acodec_error != CODEC_OK) { + printk ("SAA_DRV ERROR : configuring audiocodec:%i\n", acodec_error); + return acodec_error; + } + */ + /* Check previous usage of MSP and Allocate DMA pipe. */ + pipe_params.mode = ( DMA_QUEUE_ENABLED | DMA_EXCH_PRIORITY_HIGH | DMA_PIPE_RESERVED | DMA_INFINITE_XFER | DMA_DOUBLE_BUFFERED | FLOW_CNTRL_DMA(PERIPH_TO_PERIPH) ); + if (mc->direction == SAA_DATA_DIRECTION_IN) + { + /*Configure Input source for audiocodec*/ + acodec_error = nomadik_acodec_select_input(DEFAULT_INPUT_DEVICE, USER_SAA); + if (acodec_error != CODEC_OK) { + printk ("SAA_DRV ERROR : configuring audiocodec:%i\n", acodec_error); + return acodec_error; + } + + down(&saa_desc->open_lock); + if (saa_desc->msp_in_flag != 0){ + printk ("SAA_DRV ERROR : MSP IN already used \n"); + up(&saa_desc->open_lock); + return -EBUSY; + } + saa_desc->msp_in_flag = 1; + up(&saa_desc->open_lock); + + id->msp_in_block.direction = mc->direction; + id->msp_in_block.block_id = mc->block_id; + sprintf(pipename, "saa%d",mc->dma.channel_id); + pipe_params.srcdevtype = "msp0rx"; + pipe_params.destdevtype = pipename; + + /*configure saa for srouce and MSP for dest*/ + pipe_params.config = (DMA_DEVCONFIG_SRC(/*DMA_DEVCONFIG_BSIZE(DMA_BSIZE_1) |*/ DMA_DEVCONFIG_WIDTH(mc->access_width)))/* || (DMA_DEVCONFIG_DEST(DMA_DEVCONFIG_BSIZE(DMA_BSIZE_1) | DMA_DEVCONFIG_WIDTH(DMA_WIDTH_HALFWORD)))*/; + + } + else + { + /*Configure Output sink for audiocodec*/ + acodec_error = nomadik_acodec_select_output(DEFAULT_OUTPUT_DEVICE, USER_SAA); + if (acodec_error != CODEC_OK) { + printk ("SAA_DRV ERROR : configuring audiocodec:%i\n", acodec_error); + return acodec_error; + } + + down(&saa_desc->open_lock); + if(saa_desc->msp_out_flag != 0){ + printk ("SAA_DRV ERROR : MSP OUT already used \n"); + up(&saa_desc->open_lock); + return -EBUSY; + } + saa_desc->msp_out_flag = 1; + up(&saa_desc->open_lock); + + id->msp_out_block.block_id = mc->block_id; + id->msp_out_block.direction = mc->direction; + sprintf(pipename, "saa%d",mc->dma.channel_id); + pipe_params.srcdevtype = pipename; + pipe_params.destdevtype = "msp0tx"; + + /*configure saa for dest and MSP for source*/ + pipe_params.config = (DMA_DEVCONFIG_DEST(/*DMA_DEVCONFIG_BSIZE(DMA_BSIZE_1) |*/ DMA_DEVCONFIG_WIDTH(mc->access_width))) /*|| (DMA_DEVCONFIG_SRC(DMA_DEVCONFIG_BSIZE(DMA_BSIZE_1) | DMA_DEVCONFIG_WIDTH(DMA_WIDTH_HALFWORD)))*/; + + } + + /*check and allocate available dma chanel */ + dmaid = request_available_dma(&pipe_params); + if (dmaid < 0){ + printk ("SAA_DRV ERROR : link_msp requesting DMA:%i\n", dmaid); + return dmaid; + } + DEBUG(6, " DMA pipe allocated for id = %d\n", dmaid); + + /* assign respective dma ch nos */ + if (mc->direction == SAA_DATA_DIRECTION_IN) { + id->msp_in_block.msp_dma_channel = dmaid; + saa_desc->msp_in_dma_channel = dmaid; + __set_dma_srcaddr(dmaid, NOMADIK_MSP0_BASE); + __set_dma_destaddr(dmaid, (mc->dma.buffer_address - saa_desc->baseaddr_saa + saa_desc->baseaddr_saa_phys)); + } else { + id->msp_out_block.msp_dma_channel = dmaid; + saa_desc->msp_out_dma_channel = dmaid; + __set_dma_destaddr(dmaid, NOMADIK_MSP0_BASE); + __set_dma_srcaddr(dmaid, (mc->dma.buffer_address - saa_desc->baseaddr_saa + saa_desc->baseaddr_saa_phys)); + } + set_dma_count(dmaid, (4*mc->dma.buffer_size)); /*Dma size for infinite transfer */ + + return 0; +} + +static void saa_spi_callback(void * data){ + DEBUG(8, "Call back hit for testprotocol_callback\n"); +} + +static void saa_spi_cs_control(int command){ + DEBUG(8, "Chip_select Called: with command = %d\n", command); +} + +/*Linking of Block with SSP.*/ +static int link_ssp (struct instance_descriptor* id, saa_ssp_connect_struct* sc) +{ + + if (sc->direction == SAA_DATA_DIRECTION_IN) { + down(&saa_desc->open_lock); + if (saa_desc->ssp_in_flag != 0) { + printk ("SAA_DRV ERROR : SSP IN already used \n"); + up(&saa_desc->open_lock); + return -EBUSY; + } + saa_desc->ssp_in_flag = 1; + up(&saa_desc->open_lock); + /*configure mode for first spi dma chanel*/ + id->spi_desc.spi_dma_config.rx_dma_mode = DMA_INFINITE_XFER | DMA_EXCH_PRIORITY_HIGH | DMA_PIPE_RESERVED | DMA_DOUBLE_BUFFERED; + /*user configuration for clinet dmadev*/ + sprintf(pipename_ssprx, "saa%d", sc->dma.channel_id); + id->spi_desc.spi_rx_client_dmadev_config.devtype = pipename_ssprx; + id->spi_desc.spi_rx_client_dmadev_config.config = DMA_DEVCONFIG_WIDTH(DMA_WIDTH_HALFWORD); + /*user configuration for master dmadev*/ + id->spi_desc.spi_rx_master_dmadev_config.config = DMA_DEVCONFIG_WIDTH(DMA_WIDTH_HALFWORD); + /*configure client dma address to use later form transfer*/ + id->spi_desc.spi_rx_dma_addr = sc->dma.buffer_address - saa_desc->baseaddr_saa + saa_desc->baseaddr_saa_phys; + id->ssp_in_block.direction = sc->direction; + id->ssp_in_block.block_id = sc->block_id; + }else{ + down(&saa_desc->open_lock); + if (saa_desc->ssp_out_flag != 0){ + printk ("SAA_DRV ERROR : SSP OUT already used \n"); + up(&saa_desc->open_lock); + return -EBUSY; + } + saa_desc->ssp_out_flag = 1; + up(&saa_desc->open_lock); + /*configure mode for first spi dma chanel*/ + id->spi_desc.spi_dma_config.tx_dma_mode = DMA_INFINITE_XFER | DMA_EXCH_PRIORITY_HIGH | DMA_PIPE_RESERVED | DMA_DOUBLE_BUFFERED; + /*user configuration for clinet dmadev*/ + sprintf(pipename_ssptx, "saa%d", sc->dma.channel_id); + id->spi_desc.spi_tx_client_dmadev_config.devtype = pipename_ssptx; + id->spi_desc.spi_tx_client_dmadev_config.config = DMA_DEVCONFIG_WIDTH(DMA_WIDTH_HALFWORD); + /*user configuration for master dmadev*/ + id->spi_desc.spi_tx_master_dmadev_config.config = DMA_DEVCONFIG_WIDTH(DMA_WIDTH_HALFWORD); + /*configure client dma address to use later form transfer*/ + id->spi_desc.spi_tx_dma_addr = sc->dma.buffer_address - saa_desc->baseaddr_saa + saa_desc->baseaddr_saa_phys; + + id->ssp_out_block.direction = sc->direction; + id->ssp_out_block.block_id = sc->block_id; + } + + if(!id->spi_desc.flag_spi_config) { + id->spi_desc.flag_spi_config = 1; + return 0; + } + + + id->spi_desc.spi_config.lbm = LOOPBACK_ENABLED; + id->spi_desc.spi_config.com_mode = DMA_TRANSFER; + id->spi_desc.spi_config.iface = SPI_INTERFACE_TI_SYNC_SERIAL; + id->spi_desc.spi_config.hierarchy = sc->hierarchy; + + id->spi_desc.spi_config.endian_rx = SPI_FIFO_MSB; + id->spi_desc.spi_config.endian_tx = SPI_FIFO_MSB; + id->spi_desc.spi_config.controller.ssp.data_size = SSP_DATA_BITS_16; + id->spi_desc.spi_config.controller.ssp.slave_tx_disable = 0; + id->spi_desc.spi_config.controller.ssp.rx_lev_trig = SSP_RX_4_OR_MORE_ELEM; + id->spi_desc.spi_config.controller.ssp.tx_lev_trig = SSP_TX_4_OR_MORE_EMPTY_LOC; + id->spi_desc.spi_config.controller.ssp.clk_freq.cpsdvsr = 0; + id->spi_desc.spi_config.controller.ssp.clk_freq.scr = 0; + + + id->spi_desc.spi_config.freq = 125000; + id->spi_desc.spi_config.dma_xfer_type = SPI_WITH_PERIPH; + id->spi_desc.spi_config.dma_config = &id->spi_desc.spi_dma_config; + id->spi_desc.spi_dma_config.tx_client_dmadev_config = &id->spi_desc.spi_tx_client_dmadev_config; + id->spi_desc.spi_dma_config.rx_client_dmadev_config = &id->spi_desc.spi_rx_client_dmadev_config; + id->spi_desc.spi_dma_config.tx_master_dmadev_config = &id->spi_desc.spi_tx_master_dmadev_config; + id->spi_desc.spi_dma_config.rx_master_dmadev_config = &id->spi_desc.spi_rx_master_dmadev_config; + id->spi_desc.spi_config.cs_control = (void*)saa_spi_cs_control; + + id->spi_desc.master = spi_busnum_to_master((u16)BUS_NUMBER); + if(id->spi_desc.master) + DEBUG(8, "Test Driver::::::::: Device Name is : %d :: %s\n",id->spi_desc.master->bus_num, (id->spi_desc.master->cdev).class_id ); + else + DEBUG(8, " Test Driver ::: Master is null\n"); + + id->spi_desc.xfer = kzalloc(sizeof(struct spi_transfer), GFP_KERNEL); + if(!id->spi_desc.xfer) { + printk("SAA : memory allocation for spi xfer failed\n"); + goto error; + } + id->spi_desc.msg = kzalloc(sizeof(struct spi_message), GFP_KERNEL); + if(!id->spi_desc.msg) { + printk("SAA : memory allocation for spi msg failed\n"); + goto error; + } + id->spi_desc.board_info = kzalloc(sizeof(struct spi_board_info), GFP_KERNEL); + if(!id->spi_desc.board_info) { + printk("SAA : memory allocation for spi board info failed\n"); + goto error; + } + + id->spi_desc.board_info->controller_data = &(id->spi_desc.spi_config); + id->spi_desc.board_info->bus_num = BUS_NUMBER, + id->spi_desc.board_info->chip_select = 0, + + id->spi_desc.spi = spi_new_device(id->spi_desc.master, id->spi_desc.board_info); + if(id->spi_desc.spi == NULL){ + printk("SAA : SPI SETUP Failed\n"); + return -EPERM; + } + + INIT_LIST_HEAD(&id->spi_desc.msg->transfers); + id->spi_desc.xfer->tx_buf = NULL; + id->spi_desc.xfer->rx_buf = NULL; + + id->spi_desc.xfer->tx_dma = id->spi_desc.spi_tx_dma_addr; + id->spi_desc.xfer->rx_dma = id->spi_desc.spi_rx_dma_addr; + id->spi_desc.xfer->len = (4*sc->dma.buffer_size); + spi_message_add_tail(id->spi_desc.xfer, id->spi_desc.msg); + id->spi_desc.msg->complete = saa_spi_callback; + + return 0; + +error : + if(id->spi_desc.xfer) { + kfree(id->spi_desc.xfer); + id->spi_desc.xfer = NULL; + } + + if(id->spi_desc.msg) { + kfree(id->spi_desc.msg); + id->spi_desc.msg = NULL; + } + + if(id->spi_desc.board_info) { + kfree(id->spi_desc.board_info); + id->spi_desc.board_info = NULL; + } + + return -1; +} + + +static void deallocate_buffer (struct instance_descriptor* id, saa_block_id block_id) +{ + + struct buffer_info* buffinfo_elem; + struct list_head* element; + unsigned long flags; + int acodec_error = CODEC_OK; + + /* Find if the device is MSP/SSP connected. */ + if (id->msp_in_block.block_id == block_id) { + DEBUG(6, "Aborting DMA %i\n", id->msp_in_block.msp_dma_channel); + if(id->msp_in_block.msp_dma_channel != -1) { + disable_dma(id->msp_in_block.msp_dma_channel); + free_dma(id->msp_in_block.msp_dma_channel); + saa_desc->msp_in_dma_channel = -1; + id->msp_in_block.msp_dma_channel = -1; + } + /* Disable the MSP0 */ + nomadik_msp_disable(0, MSP_BOTH_T_R_MODE, MSP_USER_SAA); + + id->msp_in_block.block_id = 0; + down(&saa_desc->open_lock); + saa_desc->msp_in_flag = 0; + up(&saa_desc->open_lock); + if((saa_desc->msp_in_flag == 0) && (saa_desc->msp_out_flag == 0)) + acodec_error = nomadik_acodec_unsetuser(USER_SAA); + return; + } + if (id->msp_out_block.block_id == block_id) { + DEBUG(6, "Aborting DMA %i\n", id->msp_out_block.msp_dma_channel); + if(id->msp_out_block.msp_dma_channel != -1) { + disable_dma(id->msp_out_block.msp_dma_channel); + free_dma(id->msp_out_block.msp_dma_channel); + saa_desc->msp_out_dma_channel = -1; + id->msp_out_block.msp_dma_channel = -1; + } + /* Disable the MSP0 */ + nomadik_msp_disable(0, MSP_BOTH_T_R_MODE, MSP_USER_SAA); + id->msp_out_block.block_id = 0; + down(&saa_desc->open_lock); + saa_desc->msp_out_flag = 0; + up(&saa_desc->open_lock); + if((saa_desc->msp_in_flag == 0) && (saa_desc->msp_out_flag == 0)) + acodec_error = nomadik_acodec_unsetuser(USER_SAA); + return; + } + if (id->ssp_in_block.block_id == block_id) { + DEBUG(6, "SAA : Aborting SPI Transfer\n"); + if(id->spi_desc.flag_spi_transfer) { + spi_async(id->spi_desc.spi, id->spi_desc.msg); + spi_unregister_device(id->spi_desc.spi); + if(id->spi_desc.xfer) { + kfree(id->spi_desc.xfer); + id->spi_desc.xfer = NULL; + } + + if(id->spi_desc.msg) { + kfree(id->spi_desc.msg); + id->spi_desc.msg = NULL; + } + + if(id->spi_desc.board_info) { + kfree(id->spi_desc.board_info); + id->spi_desc.board_info = NULL; + } + + --id->spi_desc.flag_spi_transfer; + id->spi_desc.flag_spi_config = 0; + } + + id->ssp_in_block.block_id = 0; + down(&saa_desc->open_lock); + saa_desc->ssp_in_flag = 0; + up(&saa_desc->open_lock); + return; + } + if (id->ssp_out_block.block_id == block_id) { + DEBUG(6, "SAA : Aborting SPI Transfer\n"); + if(id->spi_desc.flag_spi_transfer) { + spi_async(id->spi_desc.spi, id->spi_desc.msg); + spi_unregister_device(id->spi_desc.spi); + if(id->spi_desc.xfer) { + kfree(id->spi_desc.xfer); + id->spi_desc.xfer = NULL; + } + + if(id->spi_desc.msg) { + kfree(id->spi_desc.msg); + id->spi_desc.msg = NULL; + } + + if(id->spi_desc.board_info) { + kfree(id->spi_desc.board_info); + id->spi_desc.board_info = NULL; + } + + --id->spi_desc.flag_spi_transfer; + id->spi_desc.flag_spi_config = 0; + } + + id->ssp_out_block.block_id = 0; + down(&saa_desc->open_lock); + saa_desc->ssp_out_flag = 0; + up(&saa_desc->open_lock); + return; + } + + + buffinfo_elem = NULL; + spin_lock_irqsave(&id->bufferinfo_lock,flags); + list_for_each(element,&id->bufferinfo_list) { + buffinfo_elem = list_entry(element, struct buffer_info, list); + if (buffinfo_elem->block_id == block_id) + break; + buffinfo_elem = NULL; + } + + /* if no buffer with given block id is found, do nothing and return*/ + if(buffinfo_elem == NULL) { + spin_unlock_irqrestore(&id->bufferinfo_lock,flags); + return; + } + + /* Otherwise dallocate the buffer*/ + /* delete the element from the buffer list */ + list_del(element); + spin_unlock_irqrestore(&id->bufferinfo_lock,flags); + + /* abort the DMA associated with the buffer before deallocation */ + if(buffinfo_elem->buf_type == SAA_BUFFER_TYPE_DMA) { + DEBUG(6, "Aborting DMA %i\n", buffinfo_elem->dma_pipe_id); + disable_dma(buffinfo_elem->dma_pipe_id); +/* if(saa_desc->out_dma_channel == buffinfo_elem->dma_pipe_id) + saa_desc->out_dma_channel = -1; + else if(saa_desc->in_dma_channel == buffinfo_elem->dma_pipe_id) + saa_desc->in_dma_channel = -1; + else + printk("About to abort DMA %i\n", buffinfo_elem->dma_pipe_id); +*/ + free_dma(buffinfo_elem->dma_pipe_id); + DEBUG(6, "DMA %i aborted\n", buffinfo_elem->dma_pipe_id); + + /* free the buffer */ + if(buffinfo_elem->buffer_base_address_virt) + dma_free_coherent(NULL,buffinfo_elem->frame_len*buffinfo_elem->frame_count, + buffinfo_elem->buffer_base_address_virt, + buffinfo_elem->buffer_base_address_phys); + } + + /* free the buffer info structure */ + if(buffinfo_elem) + kfree(buffinfo_elem); + + return; +} + + +/* Hamac Audio open method. + */ + +static int saa_open(struct inode* inode, struct file* file) +{ + struct instance_descriptor* desc = NULL; + struct instance_list* list_elem = NULL; + int ret = 0; + + /* allocate memory for per open instance descriptor */ + desc = (struct instance_descriptor*) kmalloc(sizeof(struct instance_descriptor), GFP_KERNEL); + if (desc == NULL) { + printk ("SAA_DRV ERROR : Unable to allocate memory for per open instance descriptor\n"); + return -ENOMEM; + } + + /* Initially, instance_descriptor is all null. */ + memset(desc, 0, sizeof(struct instance_descriptor)); + file->private_data = desc; + + /* allocate instance_list memory */ + list_elem = (struct instance_list*) kmalloc(sizeof (struct instance_list),GFP_KERNEL); + if (list_elem == NULL) { + printk ("SAA_DRV ERROR : Unable to allocate memory for descriptor list\n"); + ret = -ENOMEM; + goto out_free_desc; + } + + DEBUG (6, "ADD to the saa instance list\n"); + down(&saa_desc->open_lock); + list_add (&list_elem->list, &saa_desc->instance_list); + list_elem->instance = desc; + + /* Allocate the message_buffer */ + desc->message_buffer = (void*)kzalloc(MSG_BUFFER_SIZE, GFP_KERNEL); + if (desc->message_buffer == NULL) { + printk ("SAA_DRV ERROR : Unable to allocate memory for message buffer\n"); + up(&saa_desc->open_lock); + ret = -ENOMEM; + goto out_free_instance_list; + } + desc->copy_msg_buffer = (void*)kzalloc(MSG_BUFFER_SIZE, GFP_KERNEL); + if (desc->copy_msg_buffer == NULL) { + printk ("SAA_DRV ERROR : Unable to allocate memory for copy of message buffer\n"); + up(&saa_desc->open_lock); + ret = -ENOMEM; + goto out_free_msgbuf; + } + + desc->current_pos = desc->message_buffer; + init_waitqueue_head(&desc->message_wqueue); + spin_lock_init(&desc->message_lock); + INIT_LIST_HEAD(&desc->bufferinfo_list); + spin_lock_init(&desc->bufferinfo_lock); + INIT_LIST_HEAD(&desc->blockinfo_list); + spin_lock_init(&desc->blockinfo_lock); + + /* reset the dma blocks associated with msp, ssp */ + desc->msp_in_block.block_id = 0; + desc->msp_out_block.block_id = 0; + desc->ssp_in_block.block_id = 0; + desc->ssp_out_block.block_id = 0; + desc->msp_in_block.msp_dma_channel = -1; + desc->msp_out_block.msp_dma_channel = -1; + up(&saa_desc->open_lock); + + return 0; + + out_free_msgbuf: + if(desc->message_buffer) + kfree(desc->message_buffer); + out_free_instance_list: + if(list_elem) + kfree(list_elem); + out_free_desc: + if(desc) + kfree (desc); + file->private_data = NULL; + + return ret; +} + +static int saa_release(struct inode* inode, struct file* file) +{ + struct list_head* element; + struct instance_list* list_elem = NULL; + struct instance_descriptor* desc = (struct instance_descriptor*)file->private_data; + + DEBUG(6, "SAA release called\n"); + + /* This is done to abort ongoing dma transfer if not done already */ + if(desc->msp_in_block.block_id) + deallocate_buffer(desc,desc->msp_in_block.block_id); + if(desc->msp_out_block.block_id) + deallocate_buffer(desc,desc->msp_out_block.block_id); + if(desc->ssp_in_block.block_id) + deallocate_buffer(desc,desc->ssp_in_block.block_id); + if(desc->ssp_out_block.block_id) + deallocate_buffer(desc,desc->ssp_out_block.block_id); + + /*for(i=0;i< desc->nb_dma_blocks;i++) + deallocate_buffer(desc,desc->dma_block_id[i]);*/ + + down(&saa_desc->open_lock); + if (list_empty(&saa_desc->instance_list)) { + printk ("SAA_DRV ERROR : instance desc not found for this instance!\n"); + up(&saa_desc->open_lock); + return 0; + } + + /* search the instance desc in the list. */ + list_for_each(element,&saa_desc->instance_list) { + list_elem = list_entry(element, struct instance_list, list); + if (list_elem->instance == desc) + { + DEBUG(6,"instance desc found. deleting it\n"); + list_del (element); + + /* free the instance_list memory */ + kfree(list_elem); + + /* release message buffer */ + if(desc->message_buffer) + kfree(desc->message_buffer); + + if(desc->copy_msg_buffer) + kfree(desc->copy_msg_buffer); + + /* release desc memory */ + if(desc) + kfree(desc); + + break; + } + } + up(&saa_desc->open_lock); + + return 0; +} + +static void saa_get_version(saa_version *version) +{ + t_version hcl_version; + int err; + + version->saa.id0 = VERSION0; + version->saa.id1 = VERSION1; + version->saa.id2 = VERSION2; + + err = SAA_GetVersion(&hcl_version); + if (ESAA_FW_ERROR_NONE != err) + { + printk("SAA_DRV ERROR : HAB_GetVersion %d\n",err); + return; + } + version->saa_hcl.id0 = hcl_version.version; + version->saa_hcl.id1 = hcl_version.major; + version->saa_hcl.id2 = hcl_version.minor; + return; +} + +static struct saa_block_info* search_for_block_info(saa_block_id block_id) +{ + struct saa_block_info* block_info = NULL; + struct list_head* element; + struct instance_list* list_elem; + struct list_head* element_instance_list; + int flag=0; + + list_for_each(element_instance_list,&saa_desc->instance_list) { + list_elem = list_entry(element_instance_list, struct instance_list, list); + + list_for_each(element,&(list_elem->instance->blockinfo_list)) { + block_info = list_entry(element, struct saa_block_info, list); + + if(block_info->block_id == block_id){ + DEBUG(1,"block id = %d\n",block_info->block_id); + flag = 1; + break; + } + } + if(flag == 1) + break; + } + + if(flag == 1) + return block_info; + else + return NULL; +} + +static int remove_block_info(struct saa_block_info* block_info) +{ + list_del(&block_info->list); + kfree(block_info); + return 0; +} + +static int saa_get_messages(struct instance_descriptor* desc,saa_message_buff_struct message_buff) +{ + unsigned long flags; + + spin_lock_irqsave(&desc->message_lock,flags); + if(((desc->current_pos - desc->message_buffer)/sizeof(saa_message_info)) >= message_buff.min_count){ + spin_unlock_irqrestore(&desc->message_lock,flags); + return 1; + } + spin_unlock_irqrestore(&desc->message_lock,flags); + return 0; +} + +/* SAA Audio ioctl method + */ + +static int saa_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) +{ + saa_error err = 0, freq; + saa_create_block_struct block_create_struct; + saa_create_port_struct port_create_struct, port_delete_struct; + saa_connection_struct port_connect_struct, port_disconnect_struct; + saa_block_id block_id, block_id_src, block_id_dest; + saa_port_id port_id, port_id_src, port_id_dest; + saa_stop_mode stop_mode; + saa_port_desc port_desc; + saa_dma_configuration_struct dma_config; + saa_dma_config config; + saa_shm_configuration_struct saa_shm_configuration; + saa_shm_config shm_config; + saa_shmbuf_offset shmbuf_offset; + saa_codec_config codec_config; + saa_aep_init aep_init; + saa_component_id component_id, cp_id_src, cp_id_dest; + saa_component_desc component_desc; + saa_component_config component_config; + saa_AEP_Component_struct AEP_component_struct; + saa_AEP_Component_Connect_struct AEP_Component_Connect_struct, AEP_Component_disconnect_struct; + saa_cmd cmd_nb; + saa_event_map event; + saa_alloc_iobuff_struct alloc_iobuff; + saa_link_iobuff_struct link_iobuff; + saa_msp_connect_struct msp_connect; + saa_ssp_connect_struct ssp_connect; + saa_xfer_iobuff_struct xfer_iobuff; + saa_flow_control_struct flow_ctrl; + saa_codec_volume_struct vol; + saa_codec_freq_struct codec_freq; + saa_codec_tonegenerator_struct tonegenerator; + saa_codec_sidetone_struct sidetone; + saa_codec_input_select input; + saa_codec_output_select output; + saa_tone_frequency_struct toneFrequency; + //saa_codec_conf conf; + saa_samplecount_struct samplecount; + saa_xfer_status_struct xfer_status; + struct list_head* element; + struct buffer_info* buffinfo_elem; + saa_message_buff_struct message_buff; + saa_version version; + saa_set_eofsize saa_eofsize; + unsigned long flags,bufferinfo_flags,blockinfo_flags; + struct saa_block_info *block_info; + unsigned long temp; +#ifdef CONFIG_CPU_FREQ + struct saa_active_net_struct* active_net_elem; +#endif + + struct instance_descriptor* desc = (struct instance_descriptor*)file->private_data; + + switch(cmd) + { + case SAAIOCTL_SERVERBLOCKCREATE: + temp = copy_from_user ((void*)&block_create_struct, (void*)arg, sizeof(saa_create_block_struct)); + + DEBUG (8, "SAA-DRV:SAAIOCTL_SERVERBLOCKCREATE: block_type=%d\n",block_create_struct.block_desc.iBlockType); + + SAA_EVENT_LOCK(flags); +#ifdef CONFIG_NOMADIK_PM + saa_block_cnt++; +#endif + + saa_desc->cmd_nb = 0; + memset(&saa_desc->cmd_event_map,0,sizeof(saa_event_map)); + err = SAA_ServerBlockCreate((saa_block_desc*)&(block_create_struct.block_desc), &cmd_nb); + + if (ESAA_ERROR_NONE == err) + { + err = wait_event_interruptible(saa_desc->cmd_wait_queue, (saa_desc->cmd_nb == cmd_nb)); + if(err){ + printk("SAA : error in wait event ( got the signal )\n"); + SAA_EVENT_UNLOCK(flags); + return err; + } + event = saa_desc->cmd_event_map; + SAA_EVENT_UNLOCK(flags); + + if (ESAA_FW_ERROR_NONE == event.params.iAnsCreateBlockParams.error_type) + { + if(block_create_struct.block_desc.iBlockType == ESAA_BLOCK_DMA) { + desc->dma_block_id[desc->nb_dma_blocks] = event.params.iAnsCreateBlockParams.block_id; + desc->nb_dma_blocks++; + } + block_create_struct.block_id = event.params.iAnsCreateBlockParams.block_id; + block_info = (struct saa_block_info *) kmalloc(sizeof(struct saa_block_info),GFP_KERNEL); + block_info->block_id = block_create_struct.block_id; + block_info->instance = desc; + spin_lock_irqsave(&desc->blockinfo_lock,blockinfo_flags); + list_add(&block_info->list,&desc->blockinfo_list); + spin_unlock_irqrestore(&desc->blockinfo_lock,blockinfo_flags); + DEBUG(6, "added block info for block id = %d\n",block_info->block_id); + DEBUG(6, "*** SAA_ServerBlockCreate EVENT OK BLOCK ID=%d\n",block_create_struct.block_id); + } + else + { + printk("SAA_DRV ERROR : No answer for Block Create (%s)\n", saa_getfwerrorname((t_saa_fw_error_type)event.params.iAnsCreateBlockParams.error_type)); + return -1; + } + } + else + { + printk ("SAA_DRV ERROR : SAA_ServerBlockCreate %d\n",err); + SAA_EVENT_UNLOCK(flags); + return -1; + } + temp = copy_to_user ((void*)arg, (void*)&block_create_struct, sizeof (saa_create_block_struct)); + return err; + + case SAAIOCTL_SERVERBLOCKDELETE: + temp = copy_from_user ((void*)&block_id, (void*)arg, sizeof(saa_block_id)); + DEBUG (8, "DELETEBLOCK: Got block id: %d\n", block_id); + + /*Deallocate buffers, if any for this block.*/ + deallocate_buffer (desc, block_id); + + SAA_EVENT_LOCK(flags); + saa_desc->cmd_nb = 0; + memset(&saa_desc->cmd_event_map,0,sizeof(saa_event_map)); + err = SAA_ServerBlockDelete(block_id, &cmd_nb); + + if (err == ESAA_ERROR_NONE) + { + err = wait_event_interruptible(saa_desc->cmd_wait_queue, (saa_desc->cmd_nb == cmd_nb)); + if(err){ + printk("SAA : error in wait event ( got the signal )\n"); + SAA_EVENT_UNLOCK(flags); + return err; + } + event = saa_desc->cmd_event_map; +#ifdef CONFIG_NOMADIK_PM + saa_block_cnt--; +#endif + SAA_EVENT_UNLOCK(flags); + + if (ESAA_FW_ERROR_NONE == event.params.iAnsDeleteBlockParams.error_type) + { + DEBUG (8, "Block Delete OK\n"); + spin_lock_irqsave(&desc->blockinfo_lock,blockinfo_flags); + if((block_info = search_for_block_info(block_id))) { + DEBUG(6, "removed block info for block id = %d\n",block_info->block_id); + remove_block_info(block_info); + } + spin_unlock_irqrestore(&desc->blockinfo_lock,blockinfo_flags); + } + else + { + printk("SAA_DRV ERROR : No answer for Block Delete (%s)\n", saa_getfwerrorname((t_saa_fw_error_type)event.params.iAnsDeleteBlockParams.error_type)); + return -1; + } + } + else + { + printk("SAA_DRV ERROR : Block Delete (%d)\n", err); + SAA_EVENT_UNLOCK(flags); + return -1; + } + return err; + + case SAAIOCTL_SERVERPORTCREATE: + + temp = copy_from_user ((void*)&port_create_struct, (void*)arg, sizeof(saa_create_port_struct)); + + DEBUG (6, "SAAIOCTL_SERVERPORTCREATE block_id = %d\n",port_create_struct.port_desc.block_id); + port_desc.block_id = port_create_struct.port_desc.block_id; + port_desc.direction = port_create_struct.port_desc.direction; + port_desc.format = port_create_struct.port_desc.format; + + SAA_EVENT_LOCK(flags); + saa_desc->cmd_nb = 0; + memset(&saa_desc->cmd_event_map,0,sizeof(saa_event_map)); + err = SAA_ServerPortCreate(&port_desc, &cmd_nb); + + if (ESAA_ERROR_NONE == err) + { + err = wait_event_interruptible(saa_desc->cmd_wait_queue, (saa_desc->cmd_nb == cmd_nb)); + if(err){ + printk("SAA : error in wait event ( got the signal )\n"); + SAA_EVENT_UNLOCK(flags); + return err; + } + event = saa_desc->cmd_event_map; + SAA_EVENT_UNLOCK(flags); + + if (ESAA_FW_ERROR_NONE == event.params.iAnsCreatePortParams.error_type) + { + port_create_struct.port_id = event.params.iAnsCreatePortParams.port_id; + DEBUG (8, "Create Port OK %d\n", event.params.iAnsCreatePortParams.port_id); + } + else + { + printk("SAA_DRV ERROR : No answer for Create Port (%s)\n", saa_getfwerrorname((t_saa_fw_error_type)event.params.iAnsCreatePortParams.error_type)); + return -1; + } + } + else + { + printk("SAA_DRV ERROR : Create Port (%d)\n", err); + SAA_EVENT_UNLOCK(flags); + return -1; + } + temp = copy_to_user ((void*)arg, (void*)&port_create_struct, sizeof (saa_create_port_struct)); + return err; + + case SAAIOCTL_SERVERPORTDELETE: + temp = copy_from_user ((void*)&port_delete_struct, (void*)arg, sizeof(saa_create_port_struct)); + DEBUG (8, "DELETEPORT: Got block id: %d, Port id %d\n",port_delete_struct.port_desc.block_id, port_delete_struct.port_id); + + block_id = port_delete_struct.port_desc.block_id; + port_id = port_delete_struct.port_id; + + SAA_EVENT_LOCK(flags); + saa_desc->cmd_nb = 0; + memset(&saa_desc->cmd_event_map,0,sizeof(saa_event_map)); + err = SAA_ServerPortDelete(block_id, port_id, &cmd_nb); + + if (err == ESAA_ERROR_NONE) + { + err = wait_event_interruptible(saa_desc->cmd_wait_queue, (saa_desc->cmd_nb == cmd_nb)); + if(err){ + printk("SAA : error in wait event ( got the signal )\n"); + SAA_EVENT_UNLOCK(flags); + return err; + } + event = saa_desc->cmd_event_map; + SAA_EVENT_UNLOCK(flags); + + if ( ESAA_FW_ERROR_NONE == event.params.iAnsDeletePortParams.error_type) + { + DEBUG (8, "Port Delete OK\n"); + } + else + { + printk("SAA_DRV ERROR : No answer for Port Delete (%s)\n", saa_getfwerrorname((t_saa_fw_error_type)event.params.iAnsDeletePortParams.error_type)); + return -1; + } + } + else + { + printk("SAA_DRV ERROR : Port Delete (%d)\n", err); + SAA_EVENT_UNLOCK(flags); + return -1; + } + return err; + + case SAAIOCTL_SERVERBLOCKFREEZE: + temp = copy_from_user ((void*)&block_id, (void*)arg, sizeof(saa_block_id)); + DEBUG (8, "SAA-DRV:SAAIOCLT_SERVERBLOCKFREEZE:\n"); + + SAA_EVENT_LOCK(flags); + saa_desc->cmd_nb = 0; + memset(&saa_desc->cmd_event_map,0,sizeof(saa_event_map)); + err = SAA_ServerBlockFreeze(block_id, &cmd_nb); + + if (err == ESAA_ERROR_NONE) + { + err = wait_event_interruptible(saa_desc->cmd_wait_queue, (saa_desc->cmd_nb == cmd_nb)); + if(err){ + printk("SAA : error in wait event ( got the signal )\n"); + SAA_EVENT_UNLOCK(flags); + return err; + } + event = saa_desc->cmd_event_map; + SAA_EVENT_UNLOCK(flags); + + if (ESAA_FW_ERROR_NONE == event.params.iAnsFreezeBlockParams.error_type) + DEBUG (8, "Block Freezed OK\n"); + else + { + printk("SAA_DRV ERROR : No answer for Block Freeze (%s)\n", saa_getfwerrorname((t_saa_fw_error_type)event.params.iAnsFreezeBlockParams.error_type)); + return -1; + } + } + else + { + printk("SAA_DRV ERROR : Block freeze (%d)\n", err); + SAA_EVENT_UNLOCK(flags); + return -1; + } + return err; + + case SAAIOCTL_SERVERPORTCONNECT: + + temp = copy_from_user ((void*)&port_connect_struct, (void*)arg, sizeof(saa_connection_struct)); + DEBUG (8, "SAA-DRV:SAAIOCTL_SERVERPORTCONNECT:\n"); + + block_id_src = port_connect_struct.block_id_src; + block_id_dest = port_connect_struct.block_id_dest; + port_id_src = port_connect_struct.port_id_src; + port_id_dest = port_connect_struct.port_id_dest; + + SAA_EVENT_LOCK(flags); + saa_desc->cmd_nb = 0; + memset(&saa_desc->cmd_event_map,0,sizeof(saa_event_map)); + err = SAA_ServerPortConnect(block_id_src, port_id_src, block_id_dest, port_id_dest, port_connect_struct.memory_bank, &cmd_nb); + + if (err == ESAA_ERROR_NONE) + { + err = wait_event_interruptible(saa_desc->cmd_wait_queue, (saa_desc->cmd_nb == cmd_nb)); + if(err){ + printk("SAA : error in wait event ( got the signal )\n"); + SAA_EVENT_UNLOCK(flags); + return err; + } + event = saa_desc->cmd_event_map; + SAA_EVENT_UNLOCK(flags); + + if (ESAA_FW_ERROR_NONE == event.params.iAnsConnectPortParams.error_type) + DEBUG (8, "Port Connect OK\n"); + else + { + printk("SAA_DRV ERROR : No answer for Port Connect (%s)\n", saa_getfwerrorname((t_saa_fw_error_type)event.params.iAnsConnectPortParams.error_type)); + return -1; + } + } + else + { + printk("SAA_DRV ERROR : Port Connect (%d)\n", err); + SAA_EVENT_UNLOCK(flags); + return -1; + } + return err; + + case SAAIOCTL_SERVERPORTDISCONNECT: + + temp = copy_from_user ((void*)&port_disconnect_struct, (void*)arg, sizeof(saa_connection_struct)); + DEBUG (8, "SAA-DRV:SAAIOCTL_SERVERPORTDISCONNECT:\n"); + + block_id_src = port_disconnect_struct.block_id_src; + block_id_dest = port_disconnect_struct.block_id_dest; + port_id_src = port_disconnect_struct.port_id_src; + port_id_dest = port_disconnect_struct.port_id_dest; + + SAA_EVENT_LOCK(flags); + saa_desc->cmd_nb = 0; + memset(&saa_desc->cmd_event_map,0,sizeof(saa_event_map)); + err = SAA_ServerPortDisconnect(block_id_src, port_id_src, block_id_dest, port_id_dest, &cmd_nb); + + if (err == ESAA_ERROR_NONE) + { + err = wait_event_interruptible(saa_desc->cmd_wait_queue, (saa_desc->cmd_nb == cmd_nb)); + if(err){ + printk("SAA : error in wait event ( got the signal )\n"); + SAA_EVENT_UNLOCK(flags); + return err; + } + event = saa_desc->cmd_event_map; + SAA_EVENT_UNLOCK(flags); + + if (ESAA_FW_ERROR_NONE == event.params.iAnsDisconnectPortParams.error_type) + DEBUG (8, "Port Disconnect OK\n"); + else + { + printk("SAA_DRV ERROR : No answer for Port Disconnect (%s)\n", saa_getfwerrorname((t_saa_fw_error_type)event.params.iAnsDisconnectPortParams.error_type)); + return -1; + } + } + else + { + printk("SAA_DRV ERROR : Port Disconnect (%d)\n", err); + SAA_EVENT_UNLOCK(flags); + return -1; + } + return err; + + case SAAIOCTL_SERVERNETWORKUPDATE: + DEBUG (8, "SAA-DRV:SAAIOCTL_SERVERNETWORKUPDATE:\n"); + + SAA_EVENT_LOCK(flags); + saa_desc->cmd_nb = 0; + memset(&saa_desc->cmd_event_map,0,sizeof(saa_event_map)); + err = SAA_ServerNetworkUpdate(&cmd_nb); + + if (err == ESAA_ERROR_NONE) + { + err = wait_event_interruptible(saa_desc->cmd_wait_queue, (saa_desc->cmd_nb == cmd_nb)); + if(err){ + printk("SAA : error in wait event ( got the signal )\n"); + SAA_EVENT_UNLOCK(flags); + return err; + } + event = saa_desc->cmd_event_map; + SAA_EVENT_UNLOCK(flags); + + if (ESAA_FW_ERROR_NONE == event.params.iAnsUpdateNetworkParams.error_type) + DEBUG (8, "Network Updation OK\n"); + else + { + printk("SAA_DRV ERROR : No answer for Network Updation (%s)\n", saa_getfwerrorname((t_saa_fw_error_type)event.params.iAnsUpdateNetworkParams.error_type)); + return -1; + } + } + else + { + printk("SAA_DRV ERROR : Network Updation %d \n", err); + SAA_EVENT_UNLOCK(flags); + return -1; + } + return err; + + case SAAIOCTL_SERVERBLOCKPRIORITYSET: + printk("SAA_DRV ERROR : SAA-DRV:SAAIOCTL_SERVERBLOCKPRIORITYSET: TBD\n"); + err = -1; + return err; + + case SAAIOCTL_SERVERGETCAPABILITIES: + printk("SAA_DRV ERROR : SAA-DRV:SAAIOCTL_SERVERGETCAPABILITIES: TBD\n"); + err = -1; + return err; + + case SAAIOCTL_DMACONFIG: + temp = copy_from_user ((void*)&dma_config, (void*)arg, sizeof(saa_dma_configuration_struct)); + DEBUG (8, "SAA-DRV:SAAIOCTL_DMACONFIG:\n"); + + config.block_id = dma_config.dma_conf.block_id; + config.params.endianess = dma_config.dma_conf.params.endianess; + config.params.sample_freq = dma_config.dma_conf.params.sample_freq; + config.params.channel_nb = dma_config.dma_conf.params.channel_nb; + config.params.interleaving = dma_config.dma_conf.params.interleaving; + config.params.sample_size = dma_config.dma_conf.params.sample_size; + config.params.real_time = dma_config.dma_conf.params.real_time; + config.params.buffer_size = dma_config.dma_conf.params.buffer_size; + config.params.eof_mode = dma_config.dma_conf.params.eof_mode; + + SAA_EVENT_LOCK(flags); + saa_desc->cmd_nb = 0; + memset(&saa_desc->cmd_event_map,0,sizeof(saa_event_map)); + err = SAA_DMAConfig(&config, &cmd_nb); + + if (err == ESAA_ERROR_NONE) + { + err = wait_event_interruptible(saa_desc->cmd_wait_queue, (saa_desc->cmd_nb == cmd_nb)); + if(err){ + printk("SAA : error in wait event ( got the signal )\n"); + SAA_EVENT_UNLOCK(flags); + return err; + } + event = saa_desc->cmd_event_map; + SAA_EVENT_UNLOCK(flags); + + if (ESAA_FW_ERROR_NONE == event.params.iAnsDmaConfigParams.error_type) + { + dma_config.buffer_size = event.params.iAnsDmaConfigParams.buffer_size; + dma_config.channel_id = event.params.iAnsDmaConfigParams.channel_id; + dma_config.buffer_address = SAA_DspToArmAddress(((t_uint32)event.params.iAnsDmaConfigParams.buffer_add_msb << 16) + | event.params.iAnsDmaConfigParams.buffer_add_lsb); + dma_config.avzone_address = SAA_DspToArmAddress(((t_uint32)event.params.iAnsDmaConfigParams.av_zone_add_msb << 16) + | event.params.iAnsDmaConfigParams.av_zone_add_lsb); + + DEBUG (8, "Buffer_address %x\n", (int)dma_config.buffer_address); + DEBUG (8, "AVZONE address %x\n", (int)dma_config.avzone_address); + DEBUG (8, "DMA Config OK (ch_id %d, buffer_size %d)\n", event.params.iAnsDmaConfigParams.channel_id, + event.params.iAnsDmaConfigParams.buffer_size); + } + else + { + printk("SAA_DRV ERROR : DMA config answer received (%s)\n", saa_getfwerrorname((t_saa_fw_error_type)event.params.iAnsDmaConfigParams.error_type)); + return -1; + } + } + else + { + printk("SAA_DRV ERROR : DMA Config %d \n", err); + SAA_EVENT_UNLOCK(flags); + return -1; + } + temp = copy_to_user ((void*)arg, (void*)&dma_config, sizeof (saa_dma_configuration_struct)); + return err; + + case SAAIOCTL_SHMCONFIG : + temp = copy_from_user ((void*)&saa_shm_configuration, (void*)arg, sizeof(saa_shm_configuration_struct)); + DEBUG (8, "SAA-DRV:SAAIOCTL_SHMCONFIG:\n"); + + shm_config.block_id = saa_shm_configuration.shm_conf.block_id; + shm_config.params.endianess = saa_shm_configuration.shm_conf.params.endianess; + shm_config.params.channel_nb = saa_shm_configuration.shm_conf.params.channel_nb; + shm_config.params.eof_mode = saa_shm_configuration.shm_conf.params.eof_mode; + shm_config.params.memory_bank = saa_shm_configuration.shm_conf.params.memory_bank; + shm_config.params.buffer_size = saa_shm_configuration.shm_conf.params.buffer_size; + shm_config.params.nb_buffers = saa_shm_configuration.shm_conf.params.nb_buffers; + + SAA_EVENT_LOCK(flags); + saa_desc->cmd_nb = 0; + memset(&saa_desc->cmd_event_map,0,sizeof(saa_event_map)); + err = SAA_SHMConfig(&shm_config, &cmd_nb); + + if (err == ESAA_ERROR_NONE) + { + err = wait_event_interruptible(saa_desc->cmd_wait_queue, (saa_desc->cmd_nb == cmd_nb)); + if(err){ + printk("SAA : error in wait event ( got the signal )\n"); + SAA_EVENT_UNLOCK(flags); + return err; + } + event = saa_desc->cmd_event_map; + SAA_EVENT_UNLOCK(flags); + + if (ESAA_FW_ERROR_NONE == event.params.iAnsShmConfigParams.error_type) + { + saa_shm_configuration.nb_buffers = event.params.iAnsShmConfigParams.nb_buffer; + saa_shm_configuration.buffer_address[0] = (((t_uint32)event.params.iAnsShmConfigParams.buffer1_add_msb << 16) + | event.params.iAnsShmConfigParams.buffer1_add_lsb); + saa_shm_configuration.buffer_address[1] = (((t_uint32)event.params.iAnsShmConfigParams.buffer2_add_msb << 16) + | event.params.iAnsShmConfigParams.buffer2_add_lsb); + saa_shm_configuration.avzone_address = SAA_DspToArmAddress(((t_uint32)event.params.iAnsShmConfigParams.av_zone_add_msb << 16) + | event.params.iAnsShmConfigParams.av_zone_add_lsb); + + DEBUG(1, " SHM Buffer address 1 ARM = %x, DSP = %x\n", (int)saa_convert_dsptoarm_address(saa_shm_configuration.buffer_address[0]), + (int)saa_shm_configuration.buffer_address[0]); + DEBUG(1, " SHM Buffer address 2 ARM = %x, DSP = %x\n", (int)saa_convert_dsptoarm_address(saa_shm_configuration.buffer_address[1]), + (int)saa_shm_configuration.buffer_address[1]); + DEBUG(1, " SHM AVZONE Buffer address = %x\n", (int)(saa_shm_configuration.avzone_address)); + DEBUG(1, "SHM Config OK \n"); + } + else + { + printk("SAA_DRV ERROR : SHM config answer received (%s)\n", saa_getfwerrorname((t_saa_fw_error_type)event.params.iAnsShmConfigParams.error_type)); + return -1; + } + } + else + { + printk("SAA_DRV ERROR : SHM Config %d \n", err); + SAA_EVENT_UNLOCK(flags); + return -1; + } + temp = copy_to_user ((void*)arg, (void*)&saa_shm_configuration, sizeof (saa_shm_configuration_struct)); + return err; + + + case SAAIOCTL_CODECCONFIG: + temp = copy_from_user ((void*)&codec_config, (void*)arg, sizeof(saa_codec_config)); + DEBUG (8, "SAA-DRV:SAAIOCTL_CODECCONFIG:\n"); + + SAA_EVENT_LOCK(flags); + saa_desc->cmd_nb = 0; + memset(&saa_desc->cmd_event_map,0,sizeof(saa_event_map)); + err = SAA_CodecConfig(&codec_config, &cmd_nb); + + if (err == ESAA_ERROR_NONE) + { + err = wait_event_interruptible(saa_desc->cmd_wait_queue, (saa_desc->cmd_nb == cmd_nb)); + if(err){ + printk("SAA : error in wait event ( got the signal )\n"); + SAA_EVENT_UNLOCK(flags); + return err; + } + event = saa_desc->cmd_event_map; + SAA_EVENT_UNLOCK(flags); + + if (ESAA_FW_ERROR_NONE == event.params.iAnsCodecConfigParams.error_type) + DEBUG (8, "CODEC Config OK\n"); + else + { + printk("SAA_DRV ERROR : CODEC config answer received (%s)\n", saa_getfwerrorname((t_saa_fw_error_type)event.params.iAnsCodecConfigParams.error_type)); + return -1; + } + } + else + { + printk("SAA_DRV ERROR : CODEC Config %d \n", err); + SAA_EVENT_UNLOCK(flags); + return -1; + } + return err; + + case SAAIOCTL_CODECGETINFO: + temp = copy_from_user ((void*)&block_id, (void*)arg, sizeof(saa_block_id)); + + DEBUG (8, "SAA-DRV:SAAIOCTL_CODECGETINFO:\n"); + + SAA_EVENT_LOCK(flags); + saa_desc->cmd_nb = 0; + memset(&saa_desc->cmd_event_map,0,sizeof(saa_event_map)); + err = SAA_CodecGetInfo(block_id, &cmd_nb); + + if (ESAA_ERROR_NONE == err) + { + err = wait_event_interruptible(saa_desc->cmd_wait_queue, (saa_desc->cmd_nb == cmd_nb)); + if(err){ + printk("SAA : error in wait event ( got the signal )\n"); + SAA_EVENT_UNLOCK(flags); + return err; + } + event = saa_desc->cmd_event_map; + SAA_EVENT_UNLOCK(flags); + + if (ESAA_FW_ERROR_NONE == event.params.iAnsCodecInfoParams.error_type) + DEBUG (8, "CODEC Info OK\n"); + + else + { + printk("SAA_DRV ERROR : CODEC Info answer (%s)\n", saa_getfwerrorname((t_saa_fw_error_type)event.params.iAnsCodecInfoParams.error_type)); + return -1; + } + + } + else + { + printk ("SAA_DRV ERROR : CODEC Info %d \n", err); + SAA_EVENT_UNLOCK(flags); + return -1; + } + return err; + + case SAAIOCTL_AEPINIT: + temp = copy_from_user ((void*)&aep_init, (void*)arg, sizeof(saa_aep_init)); + + DEBUG (8, "SAA-DRV:SAAIOCTL_AEPINIT:\n"); + + SAA_EVENT_LOCK(flags); + saa_desc->cmd_nb = 0; + memset(&saa_desc->cmd_event_map,0,sizeof(saa_event_map)); + err = SAA_AEPInit(&aep_init, &cmd_nb); + + if (ESAA_ERROR_NONE == err) + { + err = wait_event_interruptible(saa_desc->cmd_wait_queue, (saa_desc->cmd_nb == cmd_nb)); + if(err){ + printk("SAA : error in wait event ( got the signal )\n"); + SAA_EVENT_UNLOCK(flags); + return err; + } + event = saa_desc->cmd_event_map; + SAA_EVENT_UNLOCK(flags); + + if (ESAA_FW_ERROR_NONE == event.params.iAnsAepInitParams.error_type) + DEBUG (8, "AEP Init Info OK\n"); + + else + { + printk("SAA_DRV ERROR : AEP Init answer (%s)\n", saa_getfwerrorname((t_saa_fw_error_type)event.params.iAnsAepInitParams.error_type)); + return -1; + } + } + else + { + printk ("SAA_DRV ERROR : AEP Init %i \n", err); + SAA_EVENT_UNLOCK(flags); + return -1; + } + return err; + + case SAAIOCTL_AEPCOMPONENTCREATE: + temp = copy_from_user ((void*)&AEP_component_struct, (void*)arg, sizeof(saa_AEP_Component_struct)); + + DEBUG (8, "SAA-DRV:SAAIOCTL_AEPCOMPONENTCREATE:\n"); + + component_desc.block_id = AEP_component_struct.desc.block_id; + component_desc.component_type = AEP_component_struct.desc.component_type; + component_desc.params = AEP_component_struct.desc.params; + + SAA_EVENT_LOCK(flags); + saa_desc->cmd_nb = 0; + memset(&saa_desc->cmd_event_map,0,sizeof(saa_event_map)); + err = SAA_AEPComponentCreate(&component_desc, &cmd_nb); + + if (ESAA_ERROR_NONE == err) + { + err = wait_event_interruptible(saa_desc->cmd_wait_queue, (saa_desc->cmd_nb == cmd_nb)); + if(err){ + printk("SAA : error in wait event ( got the signal )\n"); + SAA_EVENT_UNLOCK(flags); + return err; + } + event = saa_desc->cmd_event_map; + SAA_EVENT_UNLOCK(flags); + + if (ESAA_FW_ERROR_NONE == event.params.iAnsCreateComponentParams.error_type) + { + DEBUG (8, "AEP Component Creation OK %d\n", event.params.iAnsCreateComponentParams.effect_id); + AEP_component_struct.component_id = event.params.iAnsCreateComponentParams.effect_id; + } + else + { + printk("SAA_DRV ERROR : AEP Component creation no answer (%s)\n", saa_getfwerrorname((t_saa_fw_error_type)event.params.iAnsCreateComponentParams.error_type)); + return -1; + } + } + else + { + printk ("SAA_DRV ERROR : SAA_ServerBlockCreate %d\n",err); + SAA_EVENT_UNLOCK(flags); + return -1; + } + temp = copy_to_user ((void*)arg, (void*)&AEP_component_struct, sizeof (saa_AEP_Component_struct)); + return err; + + case SAAIOCTL_AEPCOMPONENTDELETE: + temp = copy_from_user ((void*)&AEP_component_struct, (void*)arg, sizeof(saa_AEP_Component_struct)); + DEBUG (8, "SAA-DRV:SAAIOCTL_AEPCOMPONENTDELETE\n"); + + block_id = AEP_component_struct.desc.block_id; + component_id = AEP_component_struct.component_id; + + SAA_EVENT_LOCK(flags); + saa_desc->cmd_nb = 0; + memset(&saa_desc->cmd_event_map,0,sizeof(saa_event_map)); + err = SAA_AEPComponentDelete(block_id, component_id, &cmd_nb); + + if (err == ESAA_ERROR_NONE) + { + err = wait_event_interruptible(saa_desc->cmd_wait_queue, (saa_desc->cmd_nb == cmd_nb)); + if(err){ + printk("SAA : error in wait event ( got the signal )\n"); + SAA_EVENT_UNLOCK(flags); + return err; + } + event = saa_desc->cmd_event_map; + SAA_EVENT_UNLOCK(flags); + + if (ESAA_FW_ERROR_NONE == event.params.iAnsDeleteComponentParams.error_type) + { + DEBUG (8, "AEP component deleted OK\n"); + } + else + { + printk("SAA_DRV ERROR : No answer for AEP delete comp (%s)\n", saa_getfwerrorname((t_saa_fw_error_type)event.params.iAnsDeleteComponentParams.error_type)); + return -1; + } + } + else + { + printk("SAA_DRV ERROR : AEP delete comp (%d)\n", err); + SAA_EVENT_UNLOCK(flags); + return -1; + } + return err; + + case SAAIOCTL_AEPCOMPONENTCONNECT: + + temp = copy_from_user ((void*)&AEP_Component_Connect_struct, (void*)arg, sizeof(saa_AEP_Component_Connect_struct)); + DEBUG (8, "SAA-DRV:SAAIOCTL_SERVERPORTCONNECT:\n"); + + block_id = AEP_Component_Connect_struct.block_id; + cp_id_src = AEP_Component_Connect_struct.cp_id_src; + cp_id_dest = AEP_Component_Connect_struct.cp_id_dest; + + SAA_EVENT_LOCK(flags); + saa_desc->cmd_nb = 0; + memset(&saa_desc->cmd_event_map,0,sizeof(saa_event_map)); + err = SAA_AEPComponentConnect(block_id, cp_id_src, cp_id_dest, &cmd_nb); + + if (ESAA_ERROR_NONE == err) + { + err = wait_event_interruptible(saa_desc->cmd_wait_queue, (saa_desc->cmd_nb == cmd_nb)); + if(err){ + printk("SAA : error in wait event ( got the signal )\n"); + SAA_EVENT_UNLOCK(flags); + return err; + } + event = saa_desc->cmd_event_map; + SAA_EVENT_UNLOCK(flags); + + if (ESAA_FW_ERROR_NONE == event.params.iAnsConnectComponentParams.error_type) + DEBUG (8, "AEP connect comp OK\n"); + else + { + printk("SAA_DRV ERROR : No answer for AEP connect comp (%s)\n", saa_getfwerrorname((t_saa_fw_error_type)event.params.iAnsConnectComponentParams.error_type)); + return -1; + } + } + else + { + printk("SAA_DRV ERROR : AEP connect comp(%d)\n", err); + SAA_EVENT_UNLOCK(flags); + return -1; + } + return err; + + case SAAIOCTL_AEPCOMPONENTDISCONNECT: + temp = copy_from_user ((void*)&AEP_Component_disconnect_struct, (void*)arg, sizeof(saa_AEP_Component_Connect_struct)); + DEBUG (8, "SAA-DRV:SAAIOCTL_AEPCOMPONENTDISCONNECT:\n"); + + block_id = AEP_Component_disconnect_struct.block_id; + cp_id_src = AEP_Component_disconnect_struct.cp_id_src; + cp_id_dest = AEP_Component_disconnect_struct.cp_id_dest; + + SAA_EVENT_LOCK(flags); + saa_desc->cmd_nb = 0; + memset(&saa_desc->cmd_event_map,0,sizeof(saa_event_map)); + err = SAA_AEPComponentDisconnect(block_id, cp_id_src, cp_id_dest, &cmd_nb); + + if (err == ESAA_ERROR_NONE) + { + err = wait_event_interruptible(saa_desc->cmd_wait_queue, (saa_desc->cmd_nb == cmd_nb)); + if(err){ + printk("SAA : error in wait event ( got the signal )\n"); + SAA_EVENT_UNLOCK(flags); + return err; + } + event = saa_desc->cmd_event_map; + SAA_EVENT_UNLOCK(flags); + + if (ESAA_FW_ERROR_NONE == event.params.iAnsDisconnectComponentParams.error_type) + DEBUG (8, "AEP component disconn OK\n"); + else + { + printk("SAA_DRV ERROR : No answer for AEP comp disconn (%s)\n", saa_getfwerrorname((t_saa_fw_error_type)event.params.iAnsDisconnectComponentParams.error_type)); + return -1; + } + } + else + { + printk("SAA_DRV ERROR : AEP component disconn (%d)\n", err); + SAA_EVENT_UNLOCK(flags); + return -1; + } + return err; + + case SAAIOCTL_AEPCOMPONENTCONFIG: + temp = copy_from_user ((void*)&component_config, (void*)arg, sizeof(saa_component_config)); + DEBUG (8, "SAA-DRV:SAAIOCTL_AEPCOMPONENTCONFIG:\n"); + + SAA_EVENT_LOCK(flags); + saa_desc->cmd_nb = 0; + memset(&saa_desc->cmd_event_map,0,sizeof(saa_event_map)); + err = SAA_AEPComponentConfig(&component_config, &cmd_nb); + + if (err == ESAA_ERROR_NONE) + { + err = wait_event_interruptible(saa_desc->cmd_wait_queue, (saa_desc->cmd_nb == cmd_nb)); + if(err){ + printk("SAA : error in wait event ( got the signal )\n"); + SAA_EVENT_UNLOCK(flags); + return err; + } + event = saa_desc->cmd_event_map; + SAA_EVENT_UNLOCK(flags); + + if (ESAA_FW_ERROR_NONE == event.params.iAnsConfigComponentParams.error_type) + DEBUG (8, "AEP config OK\n"); + else + { + printk("SAA_DRV ERROR : No AEP config answer received (%s)\n", saa_getfwerrorname((t_saa_fw_error_type)event.params.iAnsConfigComponentParams.error_type)); + return -1; + } + } + else + { + printk("SAA_DRV ERROR : AEP Config FAILED (%d) \n", err); + SAA_EVENT_UNLOCK(flags); + return -1; + } + return err; + + case SAAIOCTL_GET_SHMBUF_OFFSET : + DEBUG (8, "SAA-DRV:SAAIOCTL_GET_SHMBUF_OFFSET\n"); + temp = copy_from_user ((void*)&shmbuf_offset, (void*)arg, sizeof(saa_shmbuf_offset)); + err = get_shmbuf_offset(desc, &shmbuf_offset); + temp = copy_to_user ((void*)arg, (void*)&shmbuf_offset, sizeof (saa_shmbuf_offset)); + return err; + + case SAAIOCTL_ALLOCATE_IO_BUFFER: + DEBUG (8, "SAA-DRV:SAAIOCTL_ALLOCATE_IO_BUFFER:\n"); + temp = copy_from_user ((void*)&alloc_iobuff, (void*)arg, sizeof(saa_alloc_iobuff_struct)); + err = allocate_buffer(desc, &alloc_iobuff); + temp = copy_to_user ((void*)arg, (void*)&alloc_iobuff, sizeof (saa_alloc_iobuff_struct)); + return err; + + case SAAIOCTL_LINK_IO_BUFFER: + DEBUG (8, "SAA-DRV:SAAIOCTL_LINK_IO_BUFFER:\n"); + temp = copy_from_user ((void*)&link_iobuff, (void*)arg, sizeof(saa_link_iobuff_struct)); + return link_buffer (desc, &link_iobuff); + + case SAAIOCTL_CONNECT_TO_MSP: + DEBUG (8, "SAA-DRV:SAAIOCTL_CONNECT_TO_MSP:\n"); + temp = copy_from_user ((void*)&msp_connect, (void*)arg, sizeof(saa_msp_connect_struct)); + err = link_msp(desc, &msp_connect); + return err; + + case SAAIOCTL_CONNECT_TO_SSP: + DEBUG (8, "SAA-DRV:SAAIOCTL_CONNECT_TO_SSP:\n"); + temp = copy_from_user ((void*)&ssp_connect, (void*)arg, sizeof(saa_ssp_connect_struct)); + err = link_ssp(desc, &ssp_connect); + return err; + + case SAAIOCTL_TRANSFER_IO_BUFFER: + /*DEBUG (8, "SAA-DRV:SAAIOCTL_TRANSFER_IO_BUFFER:\n");*/ + temp = copy_from_user ((void*)&xfer_iobuff, (void*)arg, sizeof(saa_xfer_iobuff_struct)); + return xfer_buffer (desc, &xfer_iobuff); + + case SAAIOCTL_FLUSH_IO_BUFFER: + printk ("SAA_DRV ERROR : SAA-DRV:SAAIOCTL_FLUSH_IO_BUFFER:TBD\n"); + err = -1; + return err; + + case SAAIOCTL_GET_TRANSFER_STATUS: + temp = copy_from_user ((void*)&xfer_status, (void*)arg, sizeof(saa_xfer_status_struct)); + DEBUG (8, "SAA-DRV:SAAIOCTL_GET_TRANSFER_STATUS:\n"); + + buffinfo_elem = NULL; + /*Find the buffer_info*/ + spin_lock_irqsave(&desc->bufferinfo_lock,bufferinfo_flags); + list_for_each(element,&desc->bufferinfo_list) { + buffinfo_elem = list_entry(element, struct buffer_info, list); + if (buffinfo_elem->block_id == xfer_status.block_id){ + break; + } + buffinfo_elem = NULL; + } + spin_unlock_irqrestore(&desc->bufferinfo_lock,bufferinfo_flags); + + if (buffinfo_elem == NULL) { + printk ("SAA_DRV ERROR : GETXFERSTATUS: buffer with given blockid not found!!!"); + return -EINVAL; + } + xfer_status.hw_ptr = buffinfo_elem->hw_ptr ; + DEBUG (8, "TRANSFER_STATUS:Block_id:%d hw_ptr:%u\n", xfer_status.block_id, xfer_status.hw_ptr); + temp = copy_to_user ((void*)arg, (void*)&xfer_status, sizeof (saa_xfer_status_struct)); + return err; + + case SAAIOCTL_SET_EOFSIZE: + temp = copy_from_user ((void*)&saa_eofsize, (void*)arg, sizeof(saa_set_eofsize)); + DEBUG (8, "SAA-DRV:SAAIOCTL_SET_EOFSIZE: for block id: %d\n", saa_eofsize.block_id); + + block_id = saa_eofsize.block_id; + port_id = saa_eofsize.port_id; + + SAA_EVENT_LOCK(flags); + saa_desc->cmd_nb = 0; + memset(&saa_desc->cmd_event_map,0,sizeof(saa_event_map)); + err = SAA_FlowSetEofSize(block_id, port_id, saa_eofsize.file_size, &cmd_nb); + + if (err == ESAA_ERROR_NONE) + { + err = wait_event_interruptible(saa_desc->cmd_wait_queue, (saa_desc->cmd_nb == cmd_nb)); + if(err){ + printk("SAA : error in wait event ( got the signal )\n"); + SAA_EVENT_UNLOCK(flags); + return err; + } + event = saa_desc->cmd_event_map; + SAA_EVENT_UNLOCK(flags); + + if (ESAA_FW_ERROR_NONE == event.params.iAnsFlowControlParams.error_type) + DEBUG (8, "Setting EOF SIZE OK\n"); + else + { + printk("SAA_DRV ERROR:No ans for setting eof size (%s)\n", saa_getfwerrorname((t_saa_fw_error_type)event.params.iAnsFlowControlParams.error_type)); + return -1; + } + } + else + { + printk("SAA_DRV ERROR : EOF size set (%d)\n", err); + SAA_EVENT_UNLOCK(flags); + return -1; + } + return err; + + case SAAIOCTL_START_NETWORK: + temp = copy_from_user ((void*)&flow_ctrl, (void*)arg, sizeof(saa_flow_control_struct)); + DEBUG (8, "SAA-DRV:SAAIOCTL_START_NETWORK: Got id: %d\n", flow_ctrl.block_id); + + block_id = flow_ctrl.block_id; + port_id = flow_ctrl.port_id; + + SAA_EVENT_LOCK(flags); + +#ifdef CONFIG_CPU_FREQ + /*Update currently active networks structure*/ + + active_net_elem = (struct saa_active_net_struct*) kmalloc(sizeof(struct saa_active_net_struct), GFP_KERNEL); + active_net_elem->block_id = block_id; + active_net_elem->port_id = port_id; + list_add (&active_net_elem->list, &saa_desc->active_net_list); +#endif + + saa_desc->cmd_nb = 0; + memset(&saa_desc->cmd_event_map,0,sizeof(saa_event_map)); + err = SAA_FlowStart(block_id, port_id, &cmd_nb); + + if (err == ESAA_ERROR_NONE) + { + err = wait_event_interruptible(saa_desc->cmd_wait_queue, (saa_desc->cmd_nb == cmd_nb)); + if(err){ + printk("SAA : error in wait event ( got the signal )\n"); + SAA_EVENT_UNLOCK(flags); + return err; + } + event = saa_desc->cmd_event_map; + SAA_EVENT_UNLOCK(flags); + + if (ESAA_FW_ERROR_NONE == event.params.iAnsFlowControlParams.error_type) + DEBUG (8, "START Network OK\n"); + else + { + printk("SAA_DRV ERROR : No ans for start network (%s)\n", saa_getfwerrorname((t_saa_fw_error_type)event.params.iAnsFlowControlParams.error_type)); + return -1; + } + } + else + { + printk("SAA_DRV ERROR : START network (%d)\n", err); + SAA_EVENT_UNLOCK(flags); + return -1; + } + return err; + + case SAAIOCTL_PAUSE_NETWORK: + temp = copy_from_user ((void*)&flow_ctrl, (void*)arg, sizeof(saa_flow_control_struct)); + DEBUG (8, "SAA-DRV:SAAIOCTL_PAUSE_NETWORK: Got id: %d\n", flow_ctrl.block_id); + + block_id = flow_ctrl.block_id; + port_id = flow_ctrl.port_id; + + SAA_EVENT_LOCK(flags); + saa_desc->cmd_nb = 0; + memset(&saa_desc->cmd_event_map,0,sizeof(saa_event_map)); + err = SAA_FlowPause(block_id, port_id, &cmd_nb); + + if (err == ESAA_ERROR_NONE) + { + err = wait_event_interruptible(saa_desc->cmd_wait_queue, (saa_desc->cmd_nb == cmd_nb)); + if(err){ + printk("SAA : error in wait event ( got the signal )\n"); + SAA_EVENT_UNLOCK(flags); + return err; + } + event = saa_desc->cmd_event_map; + SAA_EVENT_UNLOCK(flags); + + if (ESAA_FW_ERROR_NONE == event.params.iAnsFlowControlParams.error_type) + DEBUG (8, "PAUSE Network OK\n"); + else + { + printk("SAA_DRV ERROR : No ans for pause network (%s)\n", saa_getfwerrorname((t_saa_fw_error_type)event.params.iAnsFlowControlParams.error_type)); + return -1; + } + } + else + { + printk("SAA_DRV ERROR : PAUSE network (%d)\n", err); + SAA_EVENT_UNLOCK(flags); + return -1; + } + return err; + + case SAAIOCTL_UNPAUSE_NETWORK: + temp = copy_from_user ((void*)&flow_ctrl, (void*)arg, sizeof(saa_flow_control_struct)); + DEBUG (8, "SAA-DRV:SAAIOCTL_UNPAUSE_NETWORK: Got id: %i\n", flow_ctrl.block_id); + + block_id = flow_ctrl.block_id; + port_id = flow_ctrl.port_id; + + SAA_EVENT_LOCK(flags); + saa_desc->cmd_nb = 0; + memset(&saa_desc->cmd_event_map,0,sizeof(saa_event_map)); + err = SAA_FlowUnPause(block_id, port_id, &cmd_nb); + + if (err == ESAA_ERROR_NONE) + { + err = wait_event_interruptible(saa_desc->cmd_wait_queue, (saa_desc->cmd_nb == cmd_nb)); + if(err){ + printk("SAA : error in wait event ( got the signal )\n"); + SAA_EVENT_UNLOCK(flags); + return err; + } + event = saa_desc->cmd_event_map; + SAA_EVENT_UNLOCK(flags); + + if (ESAA_FW_ERROR_NONE == event.params.iAnsFlowControlParams.error_type) + DEBUG (8, "UNPAUSE Network OK\n"); + else + { + printk("SAA_DRV ERROR : No ans for unpause network (%s)\n", saa_getfwerrorname((t_saa_fw_error_type)event.params.iAnsFlowControlParams.error_type)); + return -1; + } + } + else + { + printk("SAA_DRV ERROR : UNPAUSE network (%d)\n", err); + SAA_EVENT_UNLOCK(flags); + return -1; + } + return err; + + case SAAIOCTL_STOP_NETWORK: + temp = copy_from_user ((void*)&flow_ctrl, (void*)arg, sizeof(saa_flow_control_struct)); + DEBUG (8, "SAA-DRV:SAAIOCTL_STOP_NETWORK: Got id: %i\n", flow_ctrl.block_id); + + block_id = flow_ctrl.block_id; + port_id = flow_ctrl.port_id; + stop_mode = flow_ctrl.stop_mode; + + SAA_EVENT_LOCK(flags); + +#ifdef CONFIG_CPU_FREQ + /*Update currently active networks structure*/ + active_net_elem = NULL; + if (!(list_empty(&saa_desc->active_net_list))) { + list_for_each(element,&(saa_desc->active_net_list)) { + active_net_elem = list_entry(element, struct saa_active_net_struct, list); + if(active_net_elem->block_id == block_id) { + list_del(element); + kfree(active_net_elem); + break; + } + } + } +#endif + + saa_desc->cmd_nb = 0; + memset(&saa_desc->cmd_event_map,0,sizeof(saa_event_map)); + err = SAA_FlowStop(block_id, port_id, stop_mode, &cmd_nb); + + if (err == ESAA_ERROR_NONE) + { + err = wait_event_interruptible(saa_desc->cmd_wait_queue, (saa_desc->cmd_nb == cmd_nb)); + if(err){ + printk("SAA : error in wait event ( got the signal )\n"); + SAA_EVENT_UNLOCK(flags); + return err; + } + event = saa_desc->cmd_event_map; + SAA_EVENT_UNLOCK(flags); + + if (ESAA_FW_ERROR_NONE == event.params.iAnsFlowControlParams.error_type) + DEBUG (8, "STOP Network OK\n"); + else + { + printk("SAA_DRV ERROR : No ans for stop network (%s)\n", saa_getfwerrorname((t_saa_fw_error_type)event.params.iAnsFlowControlParams.error_type)); + return -1; + } + } + else + { + printk("SAA_DRV ERROR : STOP network (%d)\n", err); + SAA_EVENT_UNLOCK(flags); + return -1; + } + return err; + + case SAAIOCTL_GET_MESSAGES: + temp = copy_from_user ((void*)&message_buff, (void*)arg, sizeof(saa_message_buff_struct)); + DEBUG (18, "SAA-DRV:SAAIOCTL_GET_MESSAGES: Got min-count: %i\n", message_buff.min_count); + + DEBUG(6, "waiting for the message\n"); + err = wait_event_interruptible(desc->message_wqueue, saa_get_messages(desc,message_buff)); + if(err){ + printk("SAA_DRV WARNING : message wait event wake up by signal\n"); + return err; + } + + spin_lock_irqsave(&desc->message_lock,flags); + if (message_buff.size < (desc->current_pos-desc->message_buffer)){ + printk ("SAA_DRV ERROR : Message buffer given by application is too small. Aborting\n"); + spin_unlock_irqrestore(&desc->message_lock,flags); + return -EINVAL; + } + memcpy(desc->copy_msg_buffer, desc->message_buffer, (long)(desc->current_pos - desc->message_buffer)); + message_buff.min_count = (desc->current_pos - desc->message_buffer)/sizeof(saa_message_info); + desc->current_pos = desc->message_buffer; + spin_unlock_irqrestore(&desc->message_lock,flags); + + temp = copy_to_user(message_buff.message, desc->copy_msg_buffer, (long)(message_buff.min_count*sizeof(saa_message_info))); + temp = copy_to_user ((void*)arg, (void*)&message_buff, sizeof (saa_message_buff_struct)); + DEBUG (8, "GETMESSAGES: Retrieved %d messages after unlock\n", message_buff.min_count); + return err; + + case SAAIOCTL_GETSAMPLECOUNT: + temp = copy_from_user ((void*)&samplecount, (void*)arg, sizeof(saa_samplecount_struct)); + DEBUG (8, "SAA-DRV: SAAIOCTL_GETSAMPLECOUNT\n"); + + err = SAA_GetSampleCount(samplecount.address, &samplecount.count, &samplecount.freq); + + if (err == ESAA_ERROR_NONE) { + DEBUG (8, "Got Sample Count OK\n"); + temp = copy_to_user ((void*)arg, (void*)&samplecount, sizeof (saa_samplecount_struct)); + return err; + }else{ + printk("SAA_DRV ERROR : Could not get Sample Count (%d)\n", err); + return -1; + } + + case SAAIOCTL_GET_VERSION: + DEBUG (8, "SAA-DRV: SAAIOCTL_GET_VERSION\n"); + temp = copy_from_user ((void*)&version, (void*)arg, sizeof(saa_version)); + saa_get_version(&version); + temp = copy_to_user ((void*)arg, (void*)&version, sizeof (saa_version)); + return err; + + case SAAIOCTL_SET_VOLUME: + temp = copy_from_user ((void*)&vol, (void*)arg, sizeof(saa_codec_volume_struct)); + DEBUG (8, "SAA-DRV:SAAIOCTL_SET_VOLUME:\n"); + err = nomadik_acodec_set_volume(vol.lvolume_in,vol.rvolume_in,vol.lvolume_out,vol.rvolume_out, USER_SAA); + return err; + + case SAAIOCTL_GET_VOLUME: + DEBUG (8, "SAA-DRV:SAAIOCTL_SET_VOLUME:\n"); + temp = copy_from_user ((void*)&vol, (void*)arg, sizeof(saa_codec_volume_struct)); + err = nomadik_acodec_get_volume(&vol, USER_SAA); + temp = copy_to_user ((void*)arg, (void*)&vol, sizeof (saa_codec_volume_struct)); + return err; + + case SAAIOCTL_SET_CODEC_FREQUENCY: + temp = copy_from_user ((void*)&codec_freq, (void*)arg, sizeof(saa_codec_freq_struct)); + DEBUG (8, "SAA-DRV:SAAIOCTL_SET_CODEC_FREQUENCY:\n"); + err = nomadik_acodec_set_frequency(codec_freq.direction,codec_freq.input_frequency,codec_freq.output_frequency, USER_SAA); + return err; + + case SAAIOCTL_ENABLE_TONEGENERATOR: + temp = copy_from_user ((void*)&tonegenerator, (void*)arg, sizeof(saa_codec_tonegenerator_struct)); + DEBUG (8, "SAA-DRV:SAAIOCTL_ENABLE_TONEGENERATOR:\n"); + err = nomadik_acodec_enable_tonegeneratormode(tonegenerator.gain,tonegenerator.mix_with_record, + tonegenerator.mix_with_playback,tonegenerator.waveShape,tonegenerator.reserved2, USER_SAA); + return err; + + case SAAIOCTL_PLAY_SINGLE_TONE: + temp = copy_from_user ((void*)&freq, (void*)arg, sizeof(int)); + DEBUG (8, "SAA-DRV:SAAIOCTL_PLAY_SINGLE_TONE:\n"); + err = nomadik_acodec_play_singletone(freq, USER_SAA); + return err; + + case SAAIOCTL_PLAY_DUAL_TONE: + temp = copy_from_user ((void*)&toneFrequency, (void*)arg, sizeof(saa_tone_frequency_struct)); + DEBUG (8, "SAA-DRV:SAAIOCTL_PLAY_DUAL_TONE:\n"); + err = nomadik_acodec_play_dualtone(toneFrequency.freqF1,toneFrequency.freqF2, USER_SAA); + return err; + + case SAAIOCTL_STOP_TONE: + DEBUG (8, "SAA-DRV:SAAIOCTL_STOP_TONE:\n"); + err = nomadik_acodec_stop_tone(USER_SAA); + return err; + + case SAAIOCTL_DISABLE_TONEGENERATOR: + DEBUG (8, "SAA-DRV:SAAIOCTL_DISABLE_TONEGENERATOR:\n"); + err = nomadik_acodec_disable_tonegeneratormode(USER_SAA); + return err; + + case SAAIOCTL_ENABLE_SIDETONE: + temp = copy_from_user((void*)&sidetone,(void*)arg,sizeof(saa_codec_sidetone_struct)); + DEBUG (8, "SAA-DRV:SAAIOCTL_ENABLE_SIDETONE:\n"); + err = nomadik_acodec_enable_sidetone(sidetone.gain,sidetone.reserved1,sidetone.reserved2, USER_SAA); + return err; + + case SAAIOCTL_DISABLE_SIDETONE: + DEBUG (8, "SAA-DRV:SAAIOCTL_DISABLE_SIDETONE:\n"); + err = nomadik_acodec_disable_sidetone(USER_SAA); + return err; + + case SAAIOCTL_SELECT_INPUT: + temp = copy_from_user ((void*)&input, (void*)arg, sizeof(saa_codec_input_select)); + DEBUG (8, "SAA-DRV:SAAIOCTL_SELECT_INPUT:\n"); + err = nomadik_acodec_select_input(input, USER_SAA); + return err; + + case SAAIOCTL_SELECT_OUTPUT: + temp = copy_from_user ((void*)&output, (void*)arg, sizeof(saa_codec_output_select)); + DEBUG (8, "SAA-DRV:SAAIOCTL_SELECT_OUTPUT:\n"); + err = nomadik_acodec_select_output(output, USER_SAA); + return err; + + case SAAIOCTL_ENABLE_BYPASS_MODE: + return err; + + case SAAIOCTL_DISABLE_BYPASS_MODE: + return err; + default: + printk("SAA_DRV ERROR : %s: Unknownd ioctl %02x\n", __func__, cmd); + return -EINVAL; + } +} + +/** + * function_name : short description + * @arg1_name: description of arg1 + * @arg2_name: description of arg2 + * + * Longer Description of function + **/ + +static int saa_mmap(struct file * file, struct vm_area_struct * vma) +{ + struct instance_descriptor* id = (struct instance_descriptor*)file->private_data; + struct list_head* element; + struct buffer_info* buffinfo_elem; + saa_block_id block_id; + unsigned int buffer_nb; + unsigned long page_address; + unsigned long flags; + unsigned long offset = vma->vm_pgoff << PAGE_SHIFT; + + DEBUG(6, "%s: offset is %x\n", __func__, (int)offset); + + block_id = ((offset >> SHIFT_BIT_BLOCK_ID) & MASK_BLOCK_ID); + DEBUG(6, "block id for mmap = %u",block_id); + + if(((offset >> SHIFT_BIT_BUF_TYPE) & MASK_BUF_TYPE) == SAA_BUFFER_TYPE_DMA) { + /*Find the buffer queue which is being mapped.*/ + buffinfo_elem = NULL; + spin_lock_irqsave(&id->bufferinfo_lock,flags); + list_for_each(element,&id->bufferinfo_list) { + buffinfo_elem = list_entry(element, struct buffer_info, list); + if (buffinfo_elem->block_id == block_id) { + DEBUG(6, "Mmapping user space addr:%x, size: %ld\n",(int)vma->vm_start,vma->vm_end - vma->vm_start); + break; + } + buffinfo_elem = NULL; + } + spin_unlock_irqrestore(&id->bufferinfo_lock,flags); + + if (buffinfo_elem == NULL) { + printk ("SAA_DRV ERROR:mmap: buffer base not found. Cannot mmap foreign buffer\n"); + return -ENOMEM; + } + + vma->vm_flags |= VM_RESERVED; +#if defined(CONFIG_L2CACHE_ENABLE) + vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); +#endif + DEBUG(6, "kernel address to be mapped = %x\n",buffinfo_elem->buffer_base_address_phys); + if (remap_pfn_range(vma,vma->vm_start, buffinfo_elem->buffer_base_address_phys >> PAGE_SHIFT, vma->vm_end-vma->vm_start, vma->vm_page_prot)) { + printk("remap_pfn_range failed\n"); + return -EAGAIN; + } +#if defined(CONFIG_L2CACHE_ENABLE) + flush_cache_range(vma, vma->vm_start, vma->vm_end); + l210_flush_range(buffinfo_elem->buffer_base_address_phys, (buffinfo_elem->buffer_base_address_phys + (vma->vm_end - vma->vm_start))); +#endif + buffinfo_elem->vma = vma; + } else if(((offset >> SHIFT_BIT_BUF_TYPE) & MASK_BUF_TYPE) == SAA_BUFFER_TYPE_SHM) { + DEBUG(6, "Mmaping the buffer for SHM\n"); + /*Find the buffer queue which is being mapped.*/ + buffinfo_elem = NULL; + spin_lock_irqsave(&id->bufferinfo_lock,flags); + list_for_each(element,&id->bufferinfo_list) { + buffinfo_elem = list_entry(element, struct buffer_info, list); + if (buffinfo_elem->block_id == block_id) { + DEBUG(6, " SHM Mmapping user space addr:%x, size: %ld\n",(int)vma->vm_start,vma->vm_end - vma->vm_start); + break; + } + buffinfo_elem = NULL; + } + spin_unlock_irqrestore(&id->bufferinfo_lock,flags); + + if (buffinfo_elem == NULL) { + printk ("SAA_DRV ERROR:mmap: buffer base not found. Cannot mmap foreign buffer\n"); + return -ENOMEM; + } + + buffer_nb = ((offset >> SHIFT_BIT_BUFFER_NUMBER) & MASK_BUFFER_NUMBER); + + vma->vm_flags |= VM_RESERVED; + +#if defined(CONFIG_L2CACHE_ENABLE) + vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); +#endif + page_address = (buffinfo_elem->shm_buffer_address[buffer_nb-1] & PAGE_MASK); + + DEBUG(6, "kernel address to be mapped = %x\n",(int)page_address); + if (remap_pfn_range(vma,vma->vm_start, page_address >> PAGE_SHIFT, vma->vm_end-vma->vm_start, vma->vm_page_prot)) { + printk("remap_pfn_range failed\n"); + return -EAGAIN; + } + +#if defined(CONFIG_L2CACHE_ENABLE) + flush_cache_range(vma, vma->vm_start, vma->vm_end); + l210_flush_range(page_address, (page_address + (vma->vm_end - vma->vm_start))); +#endif + + buffinfo_elem->shm_vma[buffer_nb-1] = vma; + } else { + printk("Mmaping the buffer for Wrong Type\n"); + return -EINVAL; + } + + return 0; + +} + + +static const char * saa_getfwerrorname(t_saa_fw_error_type fw_error) +{ + switch (fw_error) + { + case ESAA_FW_ERROR_NONE: + return "ESAA_FW_ERROR_NONE"; + /* Warnings */ + case ESAA_FW_ERROR_LEVEL_WARNING: + return "ESAA_FW_ERROR_LEVEL_WARNING"; + case ESAA_FW_WARNING_UNDERFLOW: + return "ESAA_FW_WARNING_UNDERFLOW"; + case ESAA_FW_WARNING_ERC_ON: + return "ESAA_FW_WARNING_ERC_ON"; + case ESAA_FW_WARNING_STREAM_CORRUPT: + return "ESAA_FW_WARNING_STREAM_CORRUPT"; + case ESAA_FW_WARNING_LEFT_MEM: + return "ESAA_FW_WARNING_LEFT_MEM"; + + /* resources */ + case ESAA_FW_ERROR_LEVEL_RESOURCES: + return "ESAA_FW_ERROR_LEVEL_RESOURCES"; + case ESAA_FW_RESOURCES_NO_MORE_FREE_DTIO: + return "ESAA_FW_RESOURCES_NO_MORE_FREE_DTIO"; + case ESAA_FW_RESOURCES_NOT_ENOUGH_MEMORY: + return "ESAA_FW_RESOURCES_NOT_ENOUGH_MEMORY"; + case ESAA_FW_RESOURCES_MAX_CMD_REACHED_TRY_LATER: + return "ESAA_FW_RESOURCES_MAX_CMD_REACHED_TRY_LATER"; + case ESAA_FW_RESOURCES_PIPE_FULL: + return "ESAA_FW_RESOURCES_PIPE_FULL"; + case ESAA_FW_RESOURCES_TOO_MANY_ITEMS: + return "ESAA_FW_RESOURCES_TOO_MANY_ITEMS"; + case ESAA_FW_RESOURCES_DISABLE_CYCLE_ESTIMATION: + return "ESAA_FW_RESOURCES_DISABLE_CYCLE_ESTIMATION"; + + /* bad used */ + case ESAA_FW_ERROR_LEVEL_BAD_USED: + return "ESAA_FW_ERROR_LEVEL_BAD_USED"; + case ESAA_FW_BAD_USED_BAD_SERVER_ID: + return "ESAA_FW_BAD_USED_BAD_SERVER_ID"; + case ESAA_FW_BAD_USED_BAD_ID: + return "ESAA_FW_BAD_USED_BAD_ID"; + case ESAA_FW_BAD_USED_BAD_CONNECTION: + return "ESAA_FW_BAD_USED_BAD_CONNECTION"; + case ESAA_FW_BAD_USED_PORT_CONNECTED: + return "ESAA_FW_BAD_USED_PORT_CONNECTED"; + case ESAA_FW_BAD_USED_PORT_DISCONNECTED: + return "ESAA_FW_BAD_USED_PORT_DISCONNECTED"; + case ESAA_FW_BAD_USED_WRONG_CONFIG: + return "ESAA_FW_BAD_USED_WRONG_CONFIG"; + case ESAA_FW_BAD_USED_FREEZE_CMD_NEEDED: + return "ESAA_FW_BAD_USED_FREEZE_CMD_NEEDED"; + case ESAA_FW_BAD_USED_CONFIG_CMD_NEEDED: + return "ESAA_FW_BAD_USED_CONFIG_CMD_NEEDED"; + case ESAA_FW_BAD_USED_NOT_ENOUGH_PORT: + return "ESAA_FW_BAD_USED_NOT_ENOUGH_PORT"; + case ESAA_FW_BAD_USED_TOO_MANY_PORTS: + return "ESAA_FW_BAD_USED_TOO_MANY_PORTS"; + case ESAA_FW_BAD_USED_SER_NOT_AVAILABLE: + return "ESAA_FW_BAD_USED_SER_NOT_AVAILABLE"; + case ESAA_FW_BAD_USED_INFO_NOT_AVAILABLE: + return "ESAA_FW_BAD_USED_INFO_NOT_AVAILABLE"; + case ESAA_FW_BAD_USED_CMD_REFUSED: + return "ESAA_FW_BAD_USED_CMD_REFUSED"; + case ESAA_FW_BAD_USED_AEP_INCONSISTENT_FRAMEWORK: + return "ESAA_FW_BAD_USED_AEP_INCONSISTENT_FRAMEWORK"; + case ESAA_FW_BAD_USED_UNKNOWN_CMD: + return "ESAA_FW_BAD_USED_UNKNOWN_CMD"; + case ESAA_FW_BAD_USED_PDT_HSI_POWER_MODE: + return "ESAA_FW_BAD_USED_PDT_HSI_POWER_MODE"; + case ESAA_FW_BAD_USED_PDT_HSI_BURST_SIZE: + return "ESAA_FW_BAD_USED_PDT_HSI_BURST_SIZE"; + case ESAA_FW_BAD_USED_PDT_HSI_BAD_DATA_FORMAT: + return "ESAA_FW_BAD_USED_PDT_HSI_BAD_DATA_FORMAT"; + + /* protocol */ + case ESAA_FW_ERROR_LEVEL_PROTOCOL: + return "ESAA_FW_ERROR_LEVEL_PROTOCOL"; + case ESAA_FW_PROTOCOL_LOST_SYNC: + return "ESAA_FW_PROTOCOL_LOST_SYNC"; + case ESAA_FW_PROTOCOL_SHM_BUF_TOO_SMALL: + return "ESAA_FW_PROTOCOL_SHM_BUF_TOO_SMALL"; + case ESAA_FW_PROTOCOL_CODEC_ERROR: + return "ESAA_FW_PROTOCOL_CODEC_ERROR"; + case ESAA_FW_PROTOCOL_EFFECT_ERROR: + return "ESAA_FW_PROTOCOL_EFFECT_ERROR"; + case ESAA_FW_PROTOCOL_PDT_HSI_POWER_MODE: + return "ESAA_FW_PROTOCOL_PDT_HSI_POWER_MODE"; + + /* fatal */ + case ESAA_FW_ERROR_LEVEL_FATAL: + return "ESAA_FW_ERROR_LEVEL_FATAL"; + /* fatal error into hamaca module */ + case ESAA_FW_FATAL_HA_BAD_FIFO_ID: + return "ESAA_FW_FATAL_HA_BAD_FIFO_ID"; + case ESAA_FW_FATAL_HA_BAD_PIPE_ID: + return "ESAA_FW_FATAL_HA_BAD_PIPE_ID"; + case ESAA_FW_FATAL_HA_PIPE_ERROR: + return "ESAA_FW_FATAL_HA_PIPE_ERROR"; + case ESAA_FW_FATAL_HA_BAD_CREATE_BLOCK_ANS: + return "ESAA_FW_FATAL_HA_BAD_CREATE_BLOCK_ANS"; + case ESAA_FW_FATAL_HA_BAD_DELETE_BLOCK_ANS: + return "ESAA_FW_FATAL_HA_BAD_DELETE_BLOCK_ANS"; + case ESAA_FW_FATAL_HA_BAD_CREATE_PORT_ANS: + return "ESAA_FW_FATAL_HA_BAD_CREATE_PORT_ANS"; + case ESAA_FW_FATAL_HA_FREEZE_CMD_LOST: + return "ESAA_FW_FATAL_HA_FREEZE_CMD_LOST"; + case ESAA_FW_FATAL_HA_BAD_FREEZE_ANS: + return "ESAA_FW_FATAL_HA_BAD_FREEZE_ANS"; + case ESAA_FW_FATAL_HA_CONNECT_CMD_LOST: + return "ESAA_FW_FATAL_HA_CONNECT_CMD_LOST"; + case ESAA_FW_FATAL_HA_BAD_CONNECT_ANS: + return "ESAA_FW_FATAL_HA_BAD_CONNECT_ANS"; + case ESAA_FW_FATAL_HA_DISCONNECT_CMD_LOST: + return "ESAA_FW_FATAL_HA_DISCONNECT_CMD_LOST"; + case ESAA_FW_FATAL_HA_BAD_DISCONNECT_ANS: + return "ESAA_FW_FATAL_HA_BAD_DISCONNECT_ANS"; + case ESAA_FW_FATAL_HA_UPDATE_CMD_LOST: + return "ESAA_FW_FATAL_HA_UPDATE_CMD_LOST"; + case ESAA_FW_FATAL_HA_BAD_UPDATE_ANS: + return "ESAA_FW_FATAL_HA_BAD_UPDATE_ANS"; + case ESAA_FW_FATAL_HA_PORT_LIST_LOST: + return "ESAA_FW_FATAL_HA_PORT_LIST_LOST"; + case ESAA_FW_FATAL_HA_UNKNOWN_CMD_ANS: + return "ESAA_FW_FATAL_HA_UNKNOWN_CMD_ANS"; + case ESAA_FW_FATAL_HA_PIPE1_NOT_CREATED: + return "ESAA_FW_FATAL_HA_PIPE1_NOT_CREATED"; + case ESAA_FW_FATAL_HA_PIPE_SERVER_NOT_CREATED: + return "ESAA_FW_FATAL_HA_PIPE_SERVER_NOT_CREATED"; + case ESAA_FW_FATAL_HA_SEMA_TABLE_NOT_CREATED: + return "ESAA_FW_FATAL_HA_SEMA_TABLE_NOT_CREATED"; + case ESAA_FW_FATAL_HA_BAD_DYNAMIC_MEM_ALLOC: + return "ESAA_FW_FATAL_HA_BAD_DYNAMIC_MEM_ALLOC"; + case ESAA_FW_FATAL_HA_TOO_MANY_PROCESS: + return "ESAA_FW_FATAL_HA_TOO_MANY_PROCESS"; + /* fatal error into periph module */ + case ESAA_FW_FATAL_PDT_BAD_BIRTH_CMD: + return "ESAA_FW_FATAL_PDT_BAD_BIRTH_CMD"; + case ESAA_FW_FATAL_PDT_SHM_UNDERFLOW_MGT: + return "ESAA_FW_FATAL_PDT_SHM_UNDERFLOW_MGT"; + /* error into aep module */ + case ESAA_FW_FATAL_AEP_CHECK_INPUT: + return "ESAA_FW_FATAL_AEP_CHECK_INPUT"; + case ESAA_FW_FATAL_AEP_CHECK_OUTPUT: + return "ESAA_FW_FATAL_AEP_CHECK_OUTPUT"; + case ESAA_FW_FATAL_AEP_WRITE_OUTPUT: + return "ESAA_FW_FATAL_AEP_WRITE_OUTPUT"; + case ESAA_FW_FATAL_AEP_FIFO_DATA: + return "ESAA_FW_FATAL_AEP_FIFO_DATA"; + case ESAA_FW_FATAL_AEP_DELETE_POSITION: + return "ESAA_FW_FATAL_AEP_DELETE_POSITION"; + case ESAA_FW_FATAL_AEP_FREE_PACKET: + return "ESAA_FW_FATAL_AEP_FREE_PACKET"; + /* error into rtil/fe module */ + case ESAA_FW_FATAL_FE_BAD_BIRTH_CMD: + return "ESAA_FW_FATAL_FE_BAD_BIRTH_CMD"; + case ESAA_FW_FATAL_FE_FIFO_DATA_BAD_PARAM: + return "ESAA_FW_FATAL_FE_FIFO_DATA_BAD_PARAM"; + case ESAA_FW_FATAL_FE_BAD_DESCRIPTION: + return "ESAA_FW_FATAL_FE_BAD_DESCRIPTION"; + case ESAA_FW_FATAL_FE_TOO_MANY_SAMPLES: + return "ESAA_FW_FATAL_FE_TOO_MANY_SAMPLES"; + case ESAA_FW_FATAL_FE_TOO_MANY_BITS: + return "ESAA_FW_FATAL_FE_TOO_MANY_BITS"; + case ESAA_FW_FATAL_FE_LOST_MSG: + return "ESAA_FW_FATAL_FE_LOST_MSG"; + /* stack oveflow */ + case ESAA_FW_FATAL_STACK_OVERFLOW: + return "ESAA_FW_FATAL_STACK_OVERFLOW"; + default: + return "Unknown"; + } +} + +#if 0 +static const char * saa_getfwalertname(t_uint16 fw_error) +{ + switch (fw_error) + { + case ESAA_FW_ALERT_UNKNOWN: + return "ESAA_FW_ALERT_UNKNOWN"; + case ESAA_FW_ALERT_BOOT_FINISHED: + return "ESAA_FW_ALERT_BOOT_FINISHED"; + case ESAA_FW_ALERT_ERROR_DETECTED: + return "ESAA_FW_ALERT_ERROR_DETECTED"; + case ESAA_FW_ALERT_CHANGE_DATA_FORMAT: + return "ESAA_FW_ALERT_CHANGE_DATA_FORMAT"; + case ESAA_FW_ALERT_EOF: + return "ESAA_FW_ALERT_EOF"; + case ESAA_FW_ALERT_HSI_RESET_CONNECTION_BB: + return "ESAA_FW_ALERT_HSI_RESET_CONNECTION_BB"; + case ESAA_FW_ALERT_AEP_DTMF: + return "ESAA_FW_ALERT_AEP_DTMF"; + case ESAA_FW_ALERT_CODEC_INFO: + return "ESAA_FW_ALERT_CODEC_INFO"; + case ESAA_FW_ALERT_SHM_BUFFER_READY: + return "ESAA_FW_ALERT_SHM_BUFFER_READY"; + case ESAA_FW_ALERT_SHM_BUFFER_RELEASED: + return "ESAA_FW_ALERT_SHM_BUFFER_RELEASED"; + case ESAA_FW_ALERT_NEED_NORMAL_SPEED: + return "ESAA_FW_ALERT_NEED_NORMAL_SPEED"; + case ESAA_FW_ALERT_READY_FOR_SLOW_SPEED: + return "ESAA_FW_ALERT_READY_FOR_SLOW_SPEED"; + case ESAA_FW_ALERT_AEP_AUDIO_VISU: + return "ESAA_FW_ALERT_AEP_AUDIO_VISU"; + case ESAA_FW_ALERT_HSI_BURST_COMPLETE: + return "ESAA_FW_ALERT_HSI_BURST_COMPLETE"; + case ESAA_FW_ALERT_HSI_ALLOW_SLEEP_MODE: + return "ESAA_FW_ALERT_HSI_ALLOW_SLEEP_MODE"; + default: + return "Unknown"; + } +} +/***************************************/ +/* saa_GetFwErrorAlertName */ +/***************************************/ + +static const char * saa_getfwerroralertname(t_uint16 fw_error) +{ + switch (fw_error) + { + + case ESAA_FW_ERROR_NONE: + return "ESAA_FW_ERROR_NONE"; + /* Warnings */ + case ESAA_FW_ERROR_LEVEL_WARNING: + return "ESAA_FW_ERROR_LEVEL_WARNING"; + case ESAA_FW_WARNING_UNDERFLOW: + return "ESAA_FW_WARNING_UNDERFLOW"; + case ESAA_FW_WARNING_ERC_ON: + return "ESAA_FW_WARNING_ERC_ON"; + case ESAA_FW_WARNING_STREAM_CORRUPT: + return "ESAA_FW_WARNING_STREAM_CORRUPT"; + case ESAA_FW_WARNING_LEFT_MEM: + return "ESAA_FW_WARNING_LEFT_MEM"; + + /* resources */ + case ESAA_FW_ERROR_LEVEL_RESOURCES: + return "ESAA_FW_ERROR_LEVEL_RESOURCES"; + case ESAA_FW_RESOURCES_NO_MORE_FREE_DTIO: + return "ESAA_FW_RESOURCES_NO_MORE_FREE_DTIO"; + case ESAA_FW_RESOURCES_NOT_ENOUGH_MEMORY: + return "ESAA_FW_RESOURCES_NOT_ENOUGH_MEMORY"; + case ESAA_FW_RESOURCES_MAX_CMD_REACHED_TRY_LATER: + return "ESAA_FW_RESOURCES_MAX_CMD_REACHED_TRY_LATER"; + case ESAA_FW_RESOURCES_PIPE_FULL: + return "ESAA_FW_RESOURCES_PIPE_FULL"; + case ESAA_FW_RESOURCES_TOO_MANY_ITEMS: + return "ESAA_FW_RESOURCES_TOO_MANY_ITEMS"; + case ESAA_FW_RESOURCES_DISABLE_CYCLE_ESTIMATION: + return "ESAA_FW_RESOURCES_DISABLE_CYCLE_ESTIMATION"; + + /* bad used */ + case ESAA_FW_ERROR_LEVEL_BAD_USED: + return "ESAA_FW_ERROR_LEVEL_BAD_USED"; + case ESAA_FW_BAD_USED_BAD_SERVER_ID: + return "ESAA_FW_BAD_USED_BAD_SERVER_ID"; + case ESAA_FW_BAD_USED_BAD_ID: + return "ESAA_FW_BAD_USED_BAD_ID"; + case ESAA_FW_BAD_USED_BAD_CONNECTION: + return "ESAA_FW_BAD_USED_BAD_CONNECTION"; + case ESAA_FW_BAD_USED_PORT_CONNECTED: + return "ESAA_FW_BAD_USED_PORT_CONNECTED"; + case ESAA_FW_BAD_USED_PORT_DISCONNECTED: + return "ESAA_FW_BAD_USED_PORT_DISCONNECTED"; + case ESAA_FW_BAD_USED_WRONG_CONFIG: + return "ESAA_FW_BAD_USED_WRONG_CONFIG"; + case ESAA_FW_BAD_USED_FREEZE_CMD_NEEDED: + return "ESAA_FW_BAD_USED_FREEZE_CMD_NEEDED"; + case ESAA_FW_BAD_USED_CONFIG_CMD_NEEDED: + return "ESAA_FW_BAD_USED_CONFIG_CMD_NEEDED"; + case ESAA_FW_BAD_USED_NOT_ENOUGH_PORT: + return "ESAA_FW_BAD_USED_NOT_ENOUGH_PORT"; + case ESAA_FW_BAD_USED_TOO_MANY_PORTS: + return "ESAA_FW_BAD_USED_TOO_MANY_PORTS"; + case ESAA_FW_BAD_USED_SER_NOT_AVAILABLE: + return "ESAA_FW_BAD_USED_SER_NOT_AVAILABLE"; + case ESAA_FW_BAD_USED_INFO_NOT_AVAILABLE: + return "ESAA_FW_BAD_USED_INFO_NOT_AVAILABLE"; + case ESAA_FW_BAD_USED_CMD_REFUSED: + return "ESAA_FW_BAD_USED_CMD_REFUSED"; + case ESAA_FW_BAD_USED_AEP_INCONSISTENT_FRAMEWORK: + return "ESAA_FW_BAD_USED_AEP_INCONSISTENT_FRAMEWORK"; + case ESAA_FW_BAD_USED_UNKNOWN_CMD: + return "ESAA_FW_BAD_USED_UNKNOWN_CMD"; + case ESAA_FW_BAD_USED_PDT_HSI_POWER_MODE: + return "ESAA_FW_BAD_USED_PDT_HSI_POWER_MODE"; + case ESAA_FW_BAD_USED_PDT_HSI_BURST_SIZE: + return "ESAA_FW_BAD_USED_PDT_HSI_BURST_SIZE"; + case ESAA_FW_BAD_USED_PDT_HSI_BAD_DATA_FORMAT: + return "ESAA_FW_BAD_USED_PDT_HSI_BAD_DATA_FORMAT"; + + /* protocol */ + case ESAA_FW_ERROR_LEVEL_PROTOCOL: + return "ESAA_FW_ERROR_LEVEL_PROTOCOL"; + case ESAA_FW_PROTOCOL_LOST_SYNC: + return "ESAA_FW_PROTOCOL_LOST_SYNC"; + case ESAA_FW_PROTOCOL_SHM_BUF_TOO_SMALL: + return "ESAA_FW_PROTOCOL_SHM_BUF_TOO_SMALL"; + case ESAA_FW_PROTOCOL_CODEC_ERROR: + return "ESAA_FW_PROTOCOL_CODEC_ERROR"; + case ESAA_FW_PROTOCOL_EFFECT_ERROR: + return "ESAA_FW_PROTOCOL_EFFECT_ERROR"; + case ESAA_FW_PROTOCOL_PDT_HSI_POWER_MODE: + return "ESAA_FW_PROTOCOL_PDT_HSI_POWER_MODE"; + + /* fatal */ + case ESAA_FW_ERROR_LEVEL_FATAL: + return "ESAA_FW_ERROR_LEVEL_FATAL"; + /* fatal error into hamaca module */ + case ESAA_FW_FATAL_HA_BAD_FIFO_ID: + return "ESAA_FW_FATAL_HA_BAD_FIFO_ID"; + case ESAA_FW_FATAL_HA_BAD_PIPE_ID: + return "ESAA_FW_FATAL_HA_BAD_PIPE_ID"; + case ESAA_FW_FATAL_HA_PIPE_ERROR: + return "ESAA_FW_FATAL_HA_PIPE_ERROR"; + case ESAA_FW_FATAL_HA_BAD_CREATE_BLOCK_ANS: + return "ESAA_FW_FATAL_HA_BAD_CREATE_BLOCK_ANS"; + case ESAA_FW_FATAL_HA_BAD_DELETE_BLOCK_ANS: + return "ESAA_FW_FATAL_HA_BAD_DELETE_BLOCK_ANS"; + case ESAA_FW_FATAL_HA_BAD_CREATE_PORT_ANS: + return "ESAA_FW_FATAL_HA_BAD_CREATE_PORT_ANS"; + case ESAA_FW_FATAL_HA_FREEZE_CMD_LOST: + return "ESAA_FW_FATAL_HA_FREEZE_CMD_LOST"; + case ESAA_FW_FATAL_HA_BAD_FREEZE_ANS: + return "ESAA_FW_FATAL_HA_BAD_FREEZE_ANS"; + case ESAA_FW_FATAL_HA_CONNECT_CMD_LOST: + return "ESAA_FW_FATAL_HA_CONNECT_CMD_LOST"; + case ESAA_FW_FATAL_HA_BAD_CONNECT_ANS: + return "ESAA_FW_FATAL_HA_BAD_CONNECT_ANS"; + case ESAA_FW_FATAL_HA_DISCONNECT_CMD_LOST: + return "ESAA_FW_FATAL_HA_DISCONNECT_CMD_LOST"; + case ESAA_FW_FATAL_HA_BAD_DISCONNECT_ANS: + return "ESAA_FW_FATAL_HA_BAD_DISCONNECT_ANS"; + case ESAA_FW_FATAL_HA_UPDATE_CMD_LOST: + return "ESAA_FW_FATAL_HA_UPDATE_CMD_LOST"; + case ESAA_FW_FATAL_HA_BAD_UPDATE_ANS: + return "ESAA_FW_FATAL_HA_BAD_UPDATE_ANS"; + case ESAA_FW_FATAL_HA_PORT_LIST_LOST: + return "ESAA_FW_FATAL_HA_PORT_LIST_LOST"; + case ESAA_FW_FATAL_HA_UNKNOWN_CMD_ANS: + return "ESAA_FW_FATAL_HA_UNKNOWN_CMD_ANS"; + case ESAA_FW_FATAL_HA_PIPE1_NOT_CREATED: + return "ESAA_FW_FATAL_HA_PIPE1_NOT_CREATED"; + case ESAA_FW_FATAL_HA_PIPE_SERVER_NOT_CREATED: + return "ESAA_FW_FATAL_HA_PIPE_SERVER_NOT_CREATED"; + case ESAA_FW_FATAL_HA_SEMA_TABLE_NOT_CREATED: + return "ESAA_FW_FATAL_HA_SEMA_TABLE_NOT_CREATED"; + case ESAA_FW_FATAL_HA_BAD_DYNAMIC_MEM_ALLOC: + return "ESAA_FW_FATAL_HA_BAD_DYNAMIC_MEM_ALLOC"; + case ESAA_FW_FATAL_HA_TOO_MANY_PROCESS: + return "ESAA_FW_FATAL_HA_TOO_MANY_PROCESS"; + /* fatal error into periph module */ + case ESAA_FW_FATAL_PDT_BAD_BIRTH_CMD: + return "ESAA_FW_FATAL_PDT_BAD_BIRTH_CMD"; + case ESAA_FW_FATAL_PDT_SHM_UNDERFLOW_MGT: + return "ESAA_FW_FATAL_PDT_SHM_UNDERFLOW_MGT"; + /* error into aep module */ + case ESAA_FW_FATAL_AEP_CHECK_INPUT: + return "ESAA_FW_FATAL_AEP_CHECK_INPUT"; + case ESAA_FW_FATAL_AEP_CHECK_OUTPUT: + return "ESAA_FW_FATAL_AEP_CHECK_OUTPUT"; + case ESAA_FW_FATAL_AEP_WRITE_OUTPUT: + return "ESAA_FW_FATAL_AEP_WRITE_OUTPUT"; + case ESAA_FW_FATAL_AEP_FIFO_DATA: + return "ESAA_FW_FATAL_AEP_FIFO_DATA"; + case ESAA_FW_FATAL_AEP_DELETE_POSITION: + return "ESAA_FW_FATAL_AEP_DELETE_POSITION"; + case ESAA_FW_FATAL_AEP_FREE_PACKET: + return "ESAA_FW_FATAL_AEP_FREE_PACKET"; + /* error into rtil/fe module */ + case ESAA_FW_FATAL_FE_BAD_BIRTH_CMD: + return "ESAA_FW_FATAL_FE_BAD_BIRTH_CMD"; + case ESAA_FW_FATAL_FE_FIFO_DATA_BAD_PARAM: + return "ESAA_FW_FATAL_FE_FIFO_DATA_BAD_PARAM"; + case ESAA_FW_FATAL_FE_BAD_DESCRIPTION: + return "ESAA_FW_FATAL_FE_BAD_DESCRIPTION"; + case ESAA_FW_FATAL_FE_TOO_MANY_SAMPLES: + return "ESAA_FW_FATAL_FE_TOO_MANY_SAMPLES"; + case ESAA_FW_FATAL_FE_TOO_MANY_BITS: + return "ESAA_FW_FATAL_FE_TOO_MANY_BITS"; + case ESAA_FW_FATAL_FE_LOST_MSG: + return "ESAA_FW_FATAL_FE_LOST_MSG"; + /* stack oveflow */ + case ESAA_FW_FATAL_STACK_OVERFLOW: + return "ESAA_FW_FATAL_STACK_OVERFLOW"; + + default: + return "Unknown"; + } +} +#endif +/** + * int saa_boot(struct platform_device *pdev) : Boots HAMACA FW + * + * + * This function loads Hamac Audio firmware and boots it. + * It makes use of SAA Audio and Hloader HCL functions. + **/ + +static t_saa_init saa_init_data; + +#ifdef CONFIG_NOMADIK_PM +static t_backup_config saa_backup; +#ifndef NOMADIK_MM_STATIC_MEM +static dma_addr_t physical_addr_back; +#endif +static t_uint32 log_addr_back; +#endif + +static int saa_boot(struct platform_device *pdev) +{ + int ret = 0; + t_uint32 logical_addr; + dma_addr_t physical_addr; + saa_error saa_error; + t_version saa_version, fw_version; + t_uint32 Data16Zone1_dynamic_size; + t_uint32 Data24Zone1_dynamic_size; + t_uint32 Data16Zone2_dynamic_size; + t_uint32 Data24Zone2_dynamic_size; + t_uint32 memory_available; + + ret = getfw_pointer(&fw); + if(ret) { + printk("error: Error loading firmware error %d\n",ret); + return ret; + } + if(!fw){ + printk("FW_LOAD error: Failed to alloc memory\n"); + goto out_release_firmware; + } + if(!fw->data){ + printk("FW_LOAD error : failed to copy firmware fw->data==NULL\n"); + goto out_release_firmware; + } + if(!fw->size){ + printk("FW_LOAD error : fw size ==0\n"); + goto out_release_firmware; + } + DEBUG(8, "SAA: firmware size = %x\n",fw->size); + DEBUG(8, "SAA: firmware copied\n"); + + /* Initialise the loader */ + saa_loader_config.HamacBaseAddr.logical = saa_desc->baseaddr_saa; + saa_loader_config.HamacBaseAddr.physical = saa_desc->baseaddr_saa_phys; + saa_loader_config.FirmwareBaseAddr = (t_uint32 *)fw->data; + saa_loader_config.FirmwareSize = (t_uint32)fw->size; + + ret = HLOADER_Init(&saa_loader_config); + if (ret == LOADER_OK) + DEBUG(1, "Firmware loaded ok: core_id=%d\n", saa_loader_config.Context.core_id); + else { + printk("HLOADER_Init FAILED! (%d)\n", ret); + goto out_release_firmware; + } + + ret = HLOADER_GetMemSizes(&saa_loader_config); + if (ret == LOADER_OK) { + DEBUG(8, " Program Zone1 size (SDRAM): %ld bytes\n", saa_loader_config.ProgramZone1.Size); + DEBUG(8, " Data16 Zone1 size (SDRAM): %ld bytes\n", saa_loader_config.Data16Zone1.Size); + DEBUG(8, " Data24 Zone1 size (SDRAM): %ld bytes\n", saa_loader_config.Data24Zone1.Size); + DEBUG(8, " Program Zone2 size (ESRAM): %ld bytes\n", saa_loader_config.ProgramZone2.Size); + DEBUG(8, " Data16 Zone2 size (ESRAM): %ld bytes\n", saa_loader_config.Data16Zone2.Size); + DEBUG(8, " Data24 Zone2 size (ESRAM): %ld bytes\n", saa_loader_config.Data24Zone2.Size); + } else { + printk("HLOADER_GetMemSizes FAILED! (%d)\n", ret); + goto out_release_firmware; + } + + + if(FWM_SDRAM_ALLOCATED_SIZE < (saa_loader_config.ProgramZone1.Size + saa_loader_config.Data16Zone1.Size + saa_loader_config.Data24Zone1.Size)) { + printk("allocated size is not sufficient for firmware\n"); + ret = -ENOMEM; + goto out_release_firmware; + } + +#ifdef CONFIG_NOMADIK_SAA_INIT_MEM + logical_addr = (t_uint32) saa_get_logical_address(); + physical_addr = (t_uint32) saa_get_physical_address(); +#else +#ifndef NOMADIK_MM_STATIC_MEM + /* allocate memory for Program + Data16 static & dynamic + Data24 static & dynamic*/ + //printk("\nKernel Allocating Memory for Firmware"); + logical_addr = (t_uint32) dma_alloc_coherent(NULL, FWM_SDRAM_ALLOCATED_SIZE , + &physical_addr,GFP_KERNEL | GFP_DMA); +#else + //printk("\nKernel remapping Memory for Firmware"); + //Out of 6 MB, 512KB will be for PM backup, that is why - 512*1024 + logical_addr = (t_uint32)ioremap_nocache(NOMADIK_SAA_BASE, (NOMADIK_SAA_END - NOMADIK_SAA_BASE + 1 - 512*1024)); + physical_addr = (t_uint32)(NOMADIK_SAA_BASE); + //storing for unmap + saa_desc->fw_physical_addr = (unsigned long)(physical_addr); + saa_desc->fw_logical_addr = (unsigned long)logical_addr; + +#endif +#endif + + + + if (logical_addr == NULL) { + printk("memory allocation for firmware failed\n"); + ret = -ENOMEM; + goto out_release_firmware; + } + + /* needed to free the DRAM memory */ + dram_logical_addr = (void *)logical_addr; + dram_physical_addr = physical_addr; + + saa_loader_config.ProgramZone1.Base.logical = ALIGN256((t_uint32)logical_addr); + saa_loader_config.ProgramZone1.Base.physical = ALIGN256((t_uint32)physical_addr); + logical_addr += saa_loader_config.ProgramZone1.Size; + physical_addr += saa_loader_config.ProgramZone1.Size; + DEBUG(8, " Program Base : 0x%08lX\n", saa_loader_config.ProgramZone1.Base.logical); + DEBUG(8, " (physical) Program Base : 0x%08lX\n", saa_loader_config.ProgramZone1.Base.physical); + + saa_loader_config.Data16Zone1.Base.logical = ALIGN256((t_uint32)logical_addr); + saa_loader_config.Data16Zone1.Base.physical = ALIGN256((t_uint32)physical_addr); + logical_addr += saa_loader_config.Data16Zone1.Size; + physical_addr += saa_loader_config.Data16Zone1.Size; + DEBUG(8, " Data16 Static Base : 0x%08lX\n", saa_loader_config.Data16Zone1.Base.logical); + DEBUG(8, " (phy) Data16 Static Base : 0x%08lX\n", saa_loader_config.Data16Zone1.Base.physical); + DEBUG(8, " Data16 Dynamic Base: 0x%08lX\n", saa_loader_config.Data16Zone1.Base.logical + saa_loader_config.Data16Zone1.Size); + DEBUG(8, " (phys) Data16 Dynamic Base: 0x%08lX\n", saa_loader_config.Data16Zone1.Base.physical + saa_loader_config.Data16Zone1.Size); + + memory_available = FWM_SDRAM_ALLOCATED_SIZE - (saa_loader_config.ProgramZone1.Size + saa_loader_config.Data16Zone1.Size + saa_loader_config.Data24Zone1.Size); + + Data16Zone1_dynamic_size = memory_available / 3; /* share remaining memory between Data16 and Data24*/ + logical_addr += Data16Zone1_dynamic_size; + physical_addr += Data16Zone1_dynamic_size; + + saa_loader_config.Data24Zone1.Base.logical = ALIGN256((t_uint32)logical_addr); + saa_loader_config.Data24Zone1.Base.physical = ALIGN256((t_uint32)physical_addr); + logical_addr += saa_loader_config.Data24Zone1.Size; + physical_addr += saa_loader_config.Data24Zone1.Size; + DEBUG(8, " Data24 Static Base : 0x%08lX\n", saa_loader_config.Data24Zone1.Base.logical); + DEBUG(8, " (phy) Data24 Static Base : 0x%08lX\n", saa_loader_config.Data24Zone1.Base.physical); + DEBUG(8, " Data24 Dynamic Base: 0x%08lX\n", saa_loader_config.Data24Zone1.Base.logical + saa_loader_config.Data24Zone1.Size); + DEBUG(8, " (phy) Data24 Dynamic Base: 0x%08lX\n", saa_loader_config.Data24Zone1.Base.physical + saa_loader_config.Data24Zone1.Size); + + Data24Zone1_dynamic_size = memory_available - Data16Zone1_dynamic_size; + logical_addr += Data24Zone1_dynamic_size; + physical_addr += Data24Zone1_dynamic_size; + + DEBUG(8, "\nAllocate memory in ESRAM\n"); + + /* allocate bank 0 & 1*/ + physical_addr = FWM_ESRAM_BANK0_BASE; + logical_addr = (t_uint32) ioremap(physical_addr, 2*FWM_ESRAM_BANK_SIZE); + if(!logical_addr) { + printk("ioremap for ESRAM failed\n"); + ret = -ENOMEM; + goto out_free_dram; + } + /* needed to free the mapped ESRAM memory */ + esram_logical_addr = (void *)logical_addr; + esram_physical_addr = physical_addr; + + saa_loader_config.ProgramZone2.Base.logical = ALIGN256((t_uint32)logical_addr); + saa_loader_config.ProgramZone2.Base.physical = ALIGN256((t_uint32)physical_addr); + logical_addr += saa_loader_config.ProgramZone2.Size; + physical_addr += saa_loader_config.ProgramZone2.Size; + DEBUG(8, " Program Base : 0x%08lX, ProgramZone2 size is %lu\n", saa_loader_config.ProgramZone2.Base.logical, saa_loader_config.ProgramZone2.Size); + + saa_loader_config.Data16Zone2.Base.logical = ALIGN256((t_uint32)logical_addr); + saa_loader_config.Data16Zone2.Base.physical = ALIGN256((t_uint32)physical_addr); + logical_addr += saa_loader_config.Data16Zone2.Size; + physical_addr += saa_loader_config.Data16Zone2.Size; + DEBUG(8, " Data16 Static Base : 0x%08lX\n", saa_loader_config.Data16Zone2.Base.logical); + DEBUG(8, " Data16 Dynamic Base: 0x%08lX\n", saa_loader_config.Data16Zone2.Base.logical + saa_loader_config.Data16Zone2.Size); + + memory_available = 2*FWM_ESRAM_BANK_SIZE - (saa_loader_config.ProgramZone2.Size + saa_loader_config.Data16Zone2.Size + saa_loader_config.Data24Zone2.Size); + + Data16Zone2_dynamic_size = 0; /* no dynamic allocation in ESRAM16*/ + logical_addr += Data16Zone2_dynamic_size; + physical_addr += Data16Zone2_dynamic_size; + + saa_loader_config.Data24Zone2.Base.logical = ALIGN256((t_uint32)logical_addr); + saa_loader_config.Data24Zone2.Base.physical = ALIGN256((t_uint32)physical_addr); + logical_addr += saa_loader_config.Data24Zone2.Size; + physical_addr += saa_loader_config.Data24Zone2.Size; + DEBUG(8, " Data24 Static Base : 0x%08lX\n", saa_loader_config.Data24Zone2.Base.logical); + DEBUG(8, " Data24 Dynamic Base: 0x%08lX\n", saa_loader_config.Data24Zone2.Base.logical + saa_loader_config.Data24Zone2.Size); + DEBUG(8, " (phy) Data24 Dynamic Base: 0x%08lX\n", saa_loader_config.Data24Zone2.Base.physical + saa_loader_config.Data24Zone2.Size); + + Data24Zone2_dynamic_size = memory_available - Data16Zone2_dynamic_size; + logical_addr += Data24Zone2_dynamic_size; + physical_addr += Data24Zone2_dynamic_size; + + /* Set configuration for loader*/ + saa_loader_config.LoadingInstr = (t_loader_instr)(LOAD_CODE | LOAD_DATA); + saa_loader_config.ProgramZone1.Top.logical = saa_loader_config.ProgramZone1.Base.logical + saa_loader_config.ProgramZone1.Size; + saa_loader_config.ProgramZone1.Top.physical = saa_loader_config.ProgramZone1.Base.physical + saa_loader_config.ProgramZone1.Size; + saa_loader_config.ProgramZone2.Top.logical = saa_loader_config.ProgramZone2.Base.logical + saa_loader_config.ProgramZone2.Size; + saa_loader_config.ProgramZone2.Top.physical = saa_loader_config.ProgramZone2.Base.physical + saa_loader_config.ProgramZone2.Size; + saa_loader_config.Data16Zone1.Top.logical = saa_loader_config.Data16Zone1.Base.logical + saa_loader_config.Data16Zone1.Size + Data16Zone1_dynamic_size; + saa_loader_config.Data16Zone1.Top.physical = saa_loader_config.Data16Zone1.Base.physical + saa_loader_config.Data16Zone1.Size + Data16Zone1_dynamic_size; + saa_loader_config.Data16Zone2.Top.logical = saa_loader_config.Data16Zone2.Base.logical + saa_loader_config.Data16Zone2.Size + Data16Zone2_dynamic_size; + saa_loader_config.Data16Zone2.Top.physical = saa_loader_config.Data16Zone2.Base.physical + saa_loader_config.Data16Zone2.Size + Data16Zone2_dynamic_size; + saa_loader_config.Data24Zone1.Top.logical = saa_loader_config.Data24Zone1.Base.logical + saa_loader_config.Data24Zone1.Size + Data24Zone1_dynamic_size; + saa_loader_config.Data24Zone1.Top.physical = saa_loader_config.Data24Zone1.Base.physical + saa_loader_config.Data24Zone1.Size + Data24Zone1_dynamic_size; + saa_loader_config.Data24Zone2.Top.logical = saa_loader_config.Data24Zone2.Base.logical + saa_loader_config.Data24Zone2.Size + Data24Zone2_dynamic_size; + saa_loader_config.Data24Zone2.Top.physical = saa_loader_config.Data24Zone2.Base.physical + saa_loader_config.Data24Zone2.Size + Data24Zone2_dynamic_size; + + saa_loader_config.MmioZone.Base.logical = (t_uint32)ioremap(HAMAC_EXT_MMIO_BASE,HAMAC_EXT_MMIO_END - HAMAC_EXT_MMIO_BASE); + if(!saa_loader_config.MmioZone.Base.logical){ + printk("ioremap for MMIO zone failed\n"); + ret = -ENOMEM; + goto out_free_esram; + } + saa_loader_config.MmioZone.Base.physical = (t_uint32)HAMAC_EXT_MMIO_BASE; + saa_loader_config.MmioZone.Top.logical = (saa_loader_config.MmioZone.Base.logical + (HAMAC_EXT_MMIO_END - HAMAC_EXT_MMIO_BASE)); + saa_loader_config.MmioZone.Top.physical = HAMAC_EXT_MMIO_END; + + DEBUG(8, "mmio zone base logical address = %x\n",(unsigned int)saa_loader_config.MmioZone.Base.logical); + DEBUG(8, "mmio zone base physical address = %x\n",(unsigned int)saa_loader_config.MmioZone.Base.physical); + DEBUG(8, "mmio zone base logical address = %x\n",(unsigned int)saa_loader_config.MmioZone.Top.logical); + DEBUG(8, "mmio zone base physical address = %x\n",(unsigned int)saa_loader_config.MmioZone.Top.physical); + DEBUG(8, "mmio zone Size = %x\n",(unsigned int)(HAMAC_EXT_MMIO_END - HAMAC_EXT_MMIO_BASE)); + + ret = HLOADER_AHB_base_init(&saa_loader_config); + if (ret == LOADER_OK) + DEBUG(8,"AHB base init OK\n"); + else { + printk("HLOADER_AHB_base_init FAILED! (%d)\n", ret); + ret = -EINVAL; + goto out_free_mmio; + } + + ret = HLOADER_FirmwareLoad(&saa_loader_config); + if (ret == LOADER_OK) { + DEBUG(8, " Compression : %d\n", saa_loader_config.Context.compression); + DEBUG(8, " Machine : 0x%04X\n", saa_loader_config.Machine); + DEBUG(8, " Core ID : %d\n", saa_loader_config.Context.core_id); + DEBUG(8, " Compatibility: 0x%04X\n", saa_loader_config.Context.compat); + DEBUG(8, " Tools Version: %u.%u.%u\n", (t_uint8)(saa_loader_config.ToolsVersion >> 16), + (t_uint8)(saa_loader_config.ToolsVersion >> 8), (t_uint8)saa_loader_config.ToolsVersion); + DEBUG(8, " FW Version : %s\n", saa_loader_config.FwVersion); + } else { + printk("HLOADER_FirmwareLoad FAILED! (%d)\n", ret); + ret = -EINVAL; + goto out_free_mmio; + } + + /* transmit the address and sizes to the HCL*/ + saa_init_data.SAABaseAddress = saa_loader_config.HamacBaseAddr.logical; + + saa_init_data.sdram.Data16BaseAddress = saa_loader_config.Data16Zone1.Base.logical; + saa_init_data.sdram.Data16DynamicSize = saa_loader_config.Data16Zone1.Top.logical - saa_loader_config.Data16Zone1.Base.logical - saa_loader_config.Data16Zone1.Size; + saa_init_data.sdram.Data24BaseAddress = saa_loader_config.Data24Zone1.Base.logical; + saa_init_data.sdram.Data24DynamicSize = saa_loader_config.Data24Zone1.Top.logical - saa_loader_config.Data24Zone1.Base.logical - saa_loader_config.Data24Zone1.Size; + + saa_init_data.esram.Data16BaseAddress = saa_loader_config.Data16Zone2.Base.logical; + saa_init_data.esram.Data16DynamicSize = saa_loader_config.Data16Zone2.Top.logical - saa_loader_config.Data16Zone2.Base.logical - saa_loader_config.Data16Zone2.Size; + saa_init_data.esram.Data24BaseAddress = saa_loader_config.Data24Zone2.Base.logical; + saa_init_data.esram.Data24DynamicSize = saa_loader_config.Data24Zone2.Top.logical - saa_loader_config.Data24Zone2.Base.logical - saa_loader_config.Data24Zone2.Size; + + SAA_Init(&saa_init_data); + SAA_EnableIRQSrc(ESAA_SRC_IRQ_0); + SAA_EnableIRQSrc(ESAA_SRC_IRQ_1); + + DEBUG(1, "Send boot command........."); + +#ifdef CONFIG_NOMADIK_PM +#ifndef NOMADIK_MM_STATIC_MEM + log_addr_back = ( t_uint32 )dma_alloc_coherent(NULL, 512*1024 , + &physical_addr_back,GFP_KERNEL | GFP_DMA); +#else + log_addr_back = (t_uint32)ioremap_nocache((NOMADIK_SAA_BASE+(NOMADIK_SAA_SIZE-512*1024)),512*1024); +#endif + if ( log_addr_back == NULL ) + { + printk("memory allocation for backup firmware failed\n"); + ret = -ENOMEM; + goto out_free_mmio; + } + saa_backup.BaseAddr = (t_uint32 *)ALIGN256((t_uint32)log_addr_back); +#endif + + ret = HLOADER_Boot(&saa_loader_config); + if (ret == LOADER_OK) + DEBUG(1, "LOADER_OK\n"); + else { + printk("HLOADER_Boot FAILED !!!\n"); + ret = -EINVAL; + goto out_free_backup_fw; + } + + ret = wait_event_interruptible(saa_desc->cmd_wait_queue,saa_desc->fw_boot_done == 1); + if(ret) { + printk("SAA : boot finished interrupt not received\n"); + goto out_free_backup_fw; + } + + saa_error = SAA_GetVersion(&saa_version); + saa_error |= SAA_GetFirmwareVersion(&fw_version); + if (saa_error == ESAA_ERROR_NONE){ + printk("SAA HCL: v%d.%d.%d\n", saa_version.version, saa_version.major, saa_version.minor); + printk("FW: v%d.%d.%d\n", fw_version.version, fw_version.major, fw_version.minor); + } + else + printk("SAA_GetVersion | SAA_GetFirmwareVersion FAILED !!!\n"); + + return 0; + + out_free_backup_fw: +#ifdef CONFIG_NOMADIK_PM +#ifndef NOMADIK_MM_STATIC_MEM + if(log_addr_back) + dma_free_coherent(NULL,512*1024,(void*)log_addr_back,physical_addr_back); +#else + if(log_addr_back) + iounmap((void*)log_addr_back); +#endif +#endif + + out_free_mmio: + if(saa_loader_config.MmioZone.Base.logical) + iounmap((void*)saa_loader_config.MmioZone.Base.logical); + + out_free_esram: + if(esram_logical_addr) + iounmap(esram_logical_addr); + + out_free_dram: +#ifndef CONFIG_NOMADIK_SAA_INIT_MEM + if(dram_logical_addr) + dma_free_coherent(NULL,FWM_SDRAM_ALLOCATED_SIZE,(void*)dram_logical_addr,dram_physical_addr); +#endif + + + + out_release_firmware: + ret = relfw_pointer(fw); + ret = -EINVAL; + + return ret; +} + + +static struct file_operations saa_fops = +{ + owner: THIS_MODULE, + open: saa_open, + release: saa_release, + ioctl: saa_ioctl, + mmap: saa_mmap, +}; + +static struct miscdevice saa_miscdev = +{ + 230, + "saa", + &saa_fops +}; + + + +#ifdef CONFIG_CPU_FREQ + +int nomadik_saa_pause(void) +{ + saa_event_map event; + saa_cmd cmd_nb; + saa_error err; + struct list_head* element; + struct saa_active_net_struct* active_net_elem; + + if(saa_desc->msp_in_dma_channel != -1) { + DEBUG(6, "Before suspend_dma for %d channel\n", saa_desc->msp_in_dma_channel); + suspend_dma(saa_desc->msp_in_dma_channel); + } + if(saa_desc->msp_out_dma_channel != -1) { + DEBUG(6, "Before suspend_dma for %d channel\n", saa_desc->msp_out_dma_channel); + suspend_dma(saa_desc->msp_out_dma_channel); + } +/* + if(saa_desc->in_dma_channel != -1) { + DEBUG(6, "Before suspend_dma for %d channel\n", saa_desc->in_dma_channel); + suspend_dma(saa_desc->in_dma_channel); + } + if(saa_desc->out_dma_channel != -1) { + DEBUG(6, "Before suspend_dma for %d channel\n", saa_desc->out_dma_channel); + suspend_dma(saa_desc->out_dma_channel); + } +*/ + active_net_elem = NULL; + if (list_empty(&saa_desc->active_net_list)) + return 0; + list_for_each(element,&(saa_desc->active_net_list)) { + active_net_elem = list_entry(element, struct saa_active_net_struct, list); + saa_desc->cmd_nb = 0; + memset(&saa_desc->cmd_event_map,0,sizeof(saa_event_map)); + err = SAA_FlowPause(active_net_elem->block_id, active_net_elem->port_id, &cmd_nb); + + if (err == ESAA_ERROR_NONE) + { + wait_event_interruptible(saa_desc->cmd_wait_queue, (saa_desc->cmd_nb == cmd_nb)); + event = saa_desc->cmd_event_map; + if (ESAA_FW_ERROR_NONE != event.params.iAnsFlowControlParams.error_type) + { + printk("SAA_DRV ERROR : No ans for pause network (%s)\n", saa_getfwerrorname((t_saa_fw_error_type)event.params.iAnsFlowControlParams.error_type)); + return -1; + } + } + else + { + printk("SAA_DRV ERROR : PAUSE network (%d)\n", err); + return -1; + } + } + return 0; + +} + +int nomadik_saa_unpause(void) +{ + saa_event_map event; + saa_cmd cmd_nb; + saa_error err; + struct list_head* element; + struct saa_active_net_struct* active_net_elem; + + if(saa_desc->msp_in_dma_channel != -1) { + DEBUG(6, "Before resume_dma for %d channel\n", saa_desc->msp_in_dma_channel); + resume_dma(saa_desc->msp_in_dma_channel); + } + if(saa_desc->msp_out_dma_channel != -1) { + DEBUG(6, "Before resume_dma for %d channel\n", saa_desc->msp_out_dma_channel); + resume_dma(saa_desc->msp_out_dma_channel); + } +/* + if(saa_desc->in_dma_channel != -1) { + DEBUG(6, "Before resume_dma for %d channel\n", saa_desc->in_dma_channel); + resume_dma(saa_desc->in_dma_channel); + } + if(saa_desc->out_dma_channel != -1) { + DEBUG(6, "Before resume_dma for %d channel\n", saa_desc->out_dma_channel); + resume_dma(saa_desc->out_dma_channel); + } +*/ + active_net_elem = NULL; + if (list_empty(&saa_desc->active_net_list)) + return 0; + list_for_each(element,&(saa_desc->active_net_list)) { + active_net_elem = list_entry(element, struct saa_active_net_struct, list); + saa_desc->cmd_nb = 0; + memset(&saa_desc->cmd_event_map,0,sizeof(saa_event_map)); + err = SAA_FlowUnPause(active_net_elem->block_id, active_net_elem->port_id, &cmd_nb); + + if (err == ESAA_ERROR_NONE) + { + wait_event_interruptible(saa_desc->cmd_wait_queue, (saa_desc->cmd_nb == cmd_nb)); + event = saa_desc->cmd_event_map; + if (ESAA_FW_ERROR_NONE != event.params.iAnsFlowControlParams.error_type) + { + printk("SAA_DRV ERROR : No ans for unpause network (%s)\n", saa_getfwerrorname((t_saa_fw_error_type)event.params.iAnsFlowControlParams.error_type)); + return -1; + } + } + else + { + printk("SAA_DRV ERROR : UNPAUSE network (%d)\n", err); + return -1; + } + } + return 0; +} + + +static int +saa_freq_transition(struct notifier_block *nb, unsigned long val, + void *data) +{ + switch (val) { + case CPUFREQ_PRECHANGE: + SAA_EVENT_LOCK(flags); + nomadik_saa_pause(); + break; + + case CPUFREQ_POSTCHANGE: + nomadik_saa_unpause(); + SAA_EVENT_UNLOCK(flags); + break; + } + DEBUG (8, "end of freq change\n"); + return 0; +} + +#endif + +static int saa_drv_probe(struct platform_device *pdev) +{ + int ret = 0; + struct resource *res; + + DEBUG (8, "Entering saa_drv_probe\n"); + + ret = misc_register(&saa_miscdev); + if (ret) { + printk("SAA_DRV ERROR : registering misc device fails\n"); + goto out; + } + DEBUG(5,"SAA Device Registered\n"); + + saa_desc = (struct nomadik_saa_descriptor*) kmalloc(sizeof(struct nomadik_saa_descriptor), GFP_KERNEL); + if(!saa_desc) { + printk("SAA_DRV ERROR : no memory available\n"); + ret = -ENOMEM; + goto out_misc_register; + } + memset(saa_desc, 0, sizeof(struct nomadik_saa_descriptor)); + + saa_desc->msp_in_dma_channel = -1; + saa_desc->msp_out_dma_channel = -1; +/* saa_desc->in_dma_channel = -1; + saa_desc->out_dma_channel = -1; +*/ + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "saa-data-mem"); + if(!res) { + printk("SAA_DRV ERROR : no resource found for SAA data mem region\n"); + ret = -EINVAL; + goto out_kmalloc; + } + + saa_desc->baseaddr_saa_phys = res->start; + saa_desc->baseaddr_saa = (unsigned long)ioremap_nocache(res->start,(res->end - res->start + 1)); + if(!saa_desc->baseaddr_saa) { + printk("SAA_DRV ERROR : Failed to ioremap SAA interface\n"); + ret = -ENOMEM; + goto out_kmalloc; + } + + saa_desc->irq0 = platform_get_irq_byname(pdev,"saa-irq0"); + if(!saa_desc->irq0) { + printk("SAA_DRV ERROR : no resource found for SAA iqr0\n"); + ret = -EINVAL; + goto out_ioremap; + } + + if((ret = request_irq(saa_desc->irq0, saa_int_handler, 0, "SAA0",NULL))) { + printk("SAA_DRV ERROR : Failed in requesting interrupt %u\n", saa_desc->irq0); + goto out_ioremap; + } + + + saa_desc->irq1 = platform_get_irq_byname(pdev,"saa-irq1"); + if(!saa_desc->irq1) { + printk("SAA_DRV ERROR : no resource found for SAA iqr1\n"); + ret = -EINVAL; + goto out_irq0; + } + + if((ret = request_irq(saa_desc->irq1, saa_int_handler1, 0, "SAA1",NULL))) { + printk("SAA_DRV ERROR : Failed in requesting interrupt %u\n", saa_desc->irq1); + goto out_irq0; + } + + INIT_LIST_HEAD(&saa_desc->instance_list); + init_waitqueue_head(&saa_desc->cmd_wait_queue); + init_MUTEX(&saa_desc->open_lock); + + ret = nomadik_clock_enable(NOMADIK_HCLK_SAA); + if(ret < 0) { + printk("SAA_DRV ERROR : enabling of HCLK_SAA failed\n"); + goto out_irq1; + } + + /* Boot MMDSP */ + ret = saa_boot(pdev); + if(ret) { + printk("SAA_DRV ERROR : firmware booting failed\n"); + goto out_irq1; + } + + saa_desc->msp_in_flag = 0; + saa_desc->msp_out_flag = 0; + saa_desc->ssp_in_flag = 0; + saa_desc->ssp_out_flag = 0; + +#ifdef CONFIG_CPU_FREQ + /*Set current active networks to NULL*/ + INIT_LIST_HEAD(&saa_desc->active_net_list); + + saa_desc->freq_transition.notifier_call = saa_freq_transition; + cpufreq_register_notifier(&saa_desc->freq_transition, + CPUFREQ_TRANSITION_NOTIFIER); +#endif + + return 0; + + out_irq1: + free_irq(saa_desc->irq1,NULL); + out_irq0: + free_irq(saa_desc->irq0,NULL); + out_ioremap: + iounmap((void*)saa_desc->baseaddr_saa); + out_kmalloc: + kfree(saa_desc); + saa_desc = NULL; + out_misc_register: + misc_deregister(&saa_miscdev); + out: + printk("SAA_DRV ERROR : saa probe failed\n"); + + return ret; +} + +static int saa_drv_remove(struct platform_device *pdev) +{ + + DEBUG (8, "Entering saa_drv_remove\n"); + if(saa_loader_config.MmioZone.Base.logical) + iounmap((void*)saa_loader_config.MmioZone.Base.logical); + + if(esram_logical_addr) + iounmap(esram_logical_addr); + +#ifndef CONFIG_NOMADIK_SAA_INIT_MEM +#ifndef NOMADIK_MM_STATIC_MEM + //printk("\nFreeing FW Memory"); + if(dram_logical_addr) + dma_free_coherent(NULL,FWM_SDRAM_ALLOCATED_SIZE,(void*)dram_logical_addr,dram_physical_addr); +#else + //printk("\n Unmappping FW Memory"); + if(saa_desc->fw_logical_addr) + iounmap((void*)saa_desc->fw_logical_addr); + +#endif +#endif + +#ifdef CONFIG_NOMADIK_PM +#ifndef NOMADIK_MM_STATIC_MEM + if(log_addr_back) + dma_free_coherent(NULL,512*1024,(void*)log_addr_back,physical_addr_back); +#else + if(log_addr_back) + iounmap((void*)log_addr_back); +#endif +#endif + + free_irq(saa_desc->irq0, NULL); + free_irq(saa_desc->irq1, NULL); + +#ifdef CONFIG_CPU_FREQ + cpufreq_unregister_notifier(&saa_desc->freq_transition, + CPUFREQ_TRANSITION_NOTIFIER); +#endif + + if(saa_desc->baseaddr_saa) + iounmap((void*)saa_desc->baseaddr_saa); + if(saa_desc) + kfree(saa_desc); + + /*release FW pointer*/ + relfw_pointer(fw); + + misc_deregister(&saa_miscdev); + return 0; +} + +#ifdef CONFIG_NOMADIK_PM +extern int g_nomadik_sleep_mode; +int saa_drv_suspend(struct platform_device *dev, pm_message_t state) +{ + int ret; + + SAA_EVENT_LOCK(flags); + if ( saa_block_cnt ) + { + SAA_EVENT_UNLOCK(flags); + return -EBUSY; + + } + + if ( g_nomadik_sleep_mode == DEEP_SLEEP ) + { + + ret = HLOADER_SaveEsramSaaSection(&saa_loader_config, &saa_backup); + if ( ret == LOADER_OK ) + DEBUG(1, "HLOADER_LoadEsramSaaSection OK\n"); + else + { + printk("Error %d in HLOADER_SaveEsramSaaSection\n", ret); + SAA_EVENT_UNLOCK(flags); + return -1; + } + + } + SAA_EVENT_UNLOCK(flags); + return 0; +} + +int saa_drv_resume(struct platform_device *dev) +{ + int ret; + if (g_nomadik_sleep_mode == DEEP_SLEEP) + { + ret = HLOADER_LoadEsramSaaSection(&saa_loader_config, &saa_backup); + if (ret == LOADER_OK) + DEBUG(1, "HLOADER_LoadEsramSaaSection OK\n"); + else { + printk("Error %d in HLOADER_LoadEsramSaaSection\n", ret); + return -1; + } + ret = HLOADER_PartialLoad(&saa_loader_config); + if (ret == LOADER_OK) + DEBUG(1, "HLOADER_PartialLoad OK\n"); + else { + printk("Error %d in HLOADER_PartialLoad\n", ret); + return -1; + } + SAA_Init(&saa_init_data); + SAA_EnableIRQSrc(ESAA_SRC_IRQ_0); + SAA_EnableIRQSrc(ESAA_SRC_IRQ_1); + saa_desc->fw_boot_done = 0; + ret = HLOADER_Boot(&saa_loader_config); + if (ret == LOADER_OK) + DEBUG(1, "After Deep SleepLOADER_OK\n"); + else { + printk("After Deep sleep HLOADER_Boot FAILED !!!\n"); + return -1; + } + + + ret = wait_event_interruptible(saa_desc->cmd_wait_queue,saa_desc->fw_boot_done == 1); + if(ret) { + printk("After Deep sleep boot finished interrupt not received\n"); + } + } + return 0; +} +#endif + +static struct platform_driver saa_driver = { +#ifdef CONFIG_NOMADIK_PM + .suspend = saa_drv_suspend, + .resume = saa_drv_resume, +#endif + .probe = saa_drv_probe, + .remove = saa_drv_remove, + .driver = { + .name = "saa", + }, +}; + +static int __init nomadik_saa_init(void) +{ + return platform_driver_register(&saa_driver); +} + +static void __exit nomadik_saa_exit(void) +{ + platform_driver_unregister(&saa_driver); +} + + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Abhijit Singh : Mrinmoy Nath "); +MODULE_DESCRIPTION("Nomadik Smart Audio Accelerator driver"); + +module_init(nomadik_saa_init); +module_exit(nomadik_saa_exit); --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/saa/nomadik-saa.h @@ -0,0 +1,204 @@ +/*--------------------------------------------------------------------------------------------------*/ +/*© copyright STMicroelectronics, 2007. */ +/* */ +/*This program is free software; you can redistribute it and/or modify it under */ +/*the terms of the GNU General Public License as published by the Free */ +/*Software Foundation; either version 2.1 of the License, or (at your option) */ +/*any later version. */ +/* */ +/*This program is distributed in the hope that it will be useful, but WITHOUT */ +/*ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU General Public License for more details. */ +/* */ +/*You should have received a copy of the GNU General Public License */ +/*along with this program. If not, see . */ +/*--------------------------------------------------------------------------------------------------*/ + +#ifndef _NOMADIK_SAA_H +#define _NOMADIK_SAA_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + + +/* Debugging stuff */ + +#ifndef CONFIG_DEBUG_USER +#define DEBUG_LEVEL 0 +#else +#define DEBUG_LEVEL 10 +#endif + +#if DEBUG_LEVEL > 0 +static int ha_debug = DEBUG_LEVEL; +#define DEBUG(n, args...) do { if (ha_debug>(n)) printk(args); } while (0) +#else +#define DEBUG(n, args...) do { } while (0) +#endif +#define MSG_BUFFER_SIZE 1024 + +#ifndef NOMADIK_MM_STATIC_MEM +#define FWM_SDRAM_ALLOCATED_SIZE (6*1024*1024) +#else +#define FWM_SDRAM_ALLOCATED_SIZE NOMADIK_SAA_SIZE +#endif + +#define BUS_NUMBER SSP_CONTROLLER + +struct saa_spi_desc +{ + dma_addr_t spi_rx_dma_addr; + dma_addr_t spi_tx_dma_addr; + struct nmdk_spi_master_dmadev_config spi_rx_master_dmadev_config; + struct nmdk_spi_master_dmadev_config spi_tx_master_dmadev_config; + struct nmdk_spi_client_dmadev_config spi_rx_client_dmadev_config; + struct nmdk_spi_client_dmadev_config spi_tx_client_dmadev_config; + struct nmdkspi_dma spi_dma_config; + struct nmdk_spi_config_chip spi_config; + struct spi_master *master; + struct spi_board_info *board_info; + struct spi_device *spi; + struct spi_transfer *xfer; + struct spi_message *msg; + int flag_spi_config; + int flag_spi_transfer; +}; + +struct msp_block_info +{ + saa_block_id block_id; + saa_data_direction direction; + dmach_t msp_dma_channel; + spinlock_t xfer_lock; +}; + +struct ssp_block_info +{ + saa_block_id block_id; + saa_data_direction direction; + dmach_t ssp_dma_channel; + spinlock_t xfer_lock; +}; + +/* Structure having Block id and Port id of Active networks */ +struct saa_active_net_struct{ + saa_block_id block_id; + saa_port_id port_id; + struct list_head list; +} ; + +/* Smart Audio Accelerator driver descriptor */ +struct nomadik_saa_descriptor +{ + unsigned long baseaddr_saa; + unsigned long baseaddr_saa_phys; + unsigned long fw_logical_addr; + unsigned long fw_physical_addr; + unsigned int irq0; + unsigned int irq1; + struct semaphore open_lock; + struct list_head instance_list; + wait_queue_head_t cmd_wait_queue; + saa_cmd cmd_nb; + saa_event_map cmd_event_map; + unsigned int fw_boot_done; + unsigned short is_ssp_configured; + unsigned int ssp_client_id; + unsigned int msp_in_flag; + unsigned int msp_out_flag; + unsigned int ssp_in_flag; + unsigned int ssp_out_flag; + dmach_t msp_in_dma_channel; + dmach_t msp_out_dma_channel; +/* dmach_t in_dma_channel; + dmach_t out_dma_channel; +*/ +#ifdef CONFIG_CPU_FREQ + struct list_head active_net_list; + struct notifier_block freq_transition; +#endif +}; + +struct buffer_info +{ + struct list_head list; + saa_data_direction direction; + saa_block_id block_id; + enum buffer_type buf_type; + dma_addr_t buffer_base_address_phys; + unsigned char* buffer_base_address_virt; + t_uint32 shm_buffer_address[2]; + t_uint32 shm_dsp_buffer_address[2]; + unsigned int shm_buffer_offset[2]; + struct vm_area_struct* shm_vma[2]; + unsigned int shm_nb_buffers; + unsigned int shm_transfer_nb; + struct vm_area_struct* vma; + dmach_t dma_pipe_id; + t_dma_xfer_type transfer_type; + unsigned int hw_ptr; + unsigned int app_ptr; + int frame_len; + int frame_count; + struct instance_descriptor* id; + int exchangeId; + int xfer_done; + wait_queue_head_t xfer_queue; + spinlock_t xfer_lock; +}; + +struct saa_block_info +{ + saa_block_id block_id; + struct instance_descriptor* instance; + struct list_head list; +}; + +struct instance_descriptor +{ + unsigned char* message_buffer; + unsigned char* copy_msg_buffer; + unsigned char* current_pos; + wait_queue_head_t message_wqueue; + spinlock_t message_lock; + struct list_head bufferinfo_list; + spinlock_t bufferinfo_lock; + struct list_head blockinfo_list; + spinlock_t blockinfo_lock; + long message_id; + saa_block_id dma_block_id[10]; + unsigned int nb_dma_blocks; + struct msp_block_info msp_in_block; + struct msp_block_info msp_out_block; + struct ssp_block_info ssp_in_block; + struct ssp_block_info ssp_out_block; + struct saa_spi_desc spi_desc; + t_saa_fw_error_type fw_err; +}; + +struct instance_list +{ + struct list_head list; + struct instance_descriptor* instance; +}; + + +static t_bool saa_parse_event(t_saa_event_map* event_ptr); +static const char * saa_getfwerrorname(t_saa_fw_error_type fw_error); +static struct saa_block_info* search_for_block_info(saa_block_id block_id); +static int remove_block_info(struct saa_block_info* block_info); +static int saa_get_messages(struct instance_descriptor* desc,saa_message_buff_struct message_buff); + + +#ifdef __cplusplus +} /* allow C++ to use these headers*/ +#endif /* __cplusplus*/ + +#endif /* _NOMADIK-SAA_H_*/ + +/* End of file nomadik-saa.h*/ --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/saa/saaioctl.h @@ -0,0 +1,498 @@ +/*--------------------------------------------------------------------------------------------------*/ +/*© copyright STMicroelectronics, 2007. */ +/* */ +/*This program is free software; you can redistribute it and/or modify it under */ +/*the terms of the GNU General Public License as published by the Free */ +/*Software Foundation; either version 2.1 of the License, or (at your option) */ +/*any later version. */ +/* */ +/*This program is distributed in the hope that it will be useful, but WITHOUT */ +/*ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU General Public License for more details. */ +/* */ +/*You should have received a copy of the GNU General Public License */ +/*along with this program. If not, see . */ +/*--------------------------------------------------------------------------------------------------*/ + +#ifndef __HAIOCTL_H +#define __HAIOCTL_H + +#include "saa.h" + +//#include + +#ifndef _AUDIOCODEC_H_ +#include +#endif + +#define DONT_CHANGE -100 +#define RESET -1 +#define TYPE_BLOCK (1 << 0) +#define TYPE_NOBLOCK (1 << 1) +#define USE_CREATE_STRUCT_GCA 1 + +/* local types */ + +/* saa data width */ +typedef enum { + SAA_DATA_WIDTH_8 = 8, + SAA_DATA_WIDTH_16 = 16 +} saa_data_width; + +/* msp access width */ +typedef enum { + SAA_BYTE_WIDTH = 0, //DMA_WIDTH_BYTE, + SAA_HALFWORD_WIDTH = 1UL<<18, //DMA_WIDTH_HALFWORD, + SAA_WORD_WIDTH = 2UL<<18 //DMA_WIDTH_WORD +} saa_msp_access_width; + +/* types from hcl */ +/******************************************************************* +* SAA HCL * +*******************************************************************/ + +typedef t_saa_block_id saa_block_id; +typedef t_saa_block_type saa_block_type; +typedef t_saa_port_type saa_port_type; +typedef t_saa_port_data_type saa_port_data_type ; +typedef t_saa_endianess_type saa_endianess_type; +typedef t_saa_sample_channel_nb saa_sample_channel_nb; +typedef t_saa_sample_interleaving_type saa_sample_interleaving_type; +typedef t_saa_sample_freq saa_sample_freq; +typedef t_hsem_id hsem_id; +typedef t_saa_init saa_init; +typedef t_saa_cmd saa_cmd; +typedef t_saa_command_id saa_command_id; +typedef t_saa_server_id saa_server_id; +typedef t_saa_port_id saa_port_id; +typedef t_saa_stop_mode saa_stop_mode; +typedef t_saa_block_desc saa_block_desc; +typedef t_saa_codec_config saa_codec_config; +typedef t_saa_irq_num saa_irq_num; +typedef t_saa_irq_src saa_irq_src; +typedef t_saa_port_desc saa_port_desc; +typedef t_saa_dma_config saa_dma_config; +typedef t_saa_shm_config saa_shm_config; +typedef t_saa_shm_transfer saa_shm_transfer; +typedef t_saa_aep_init saa_aep_init; +typedef t_saa_component_id saa_component_id; +typedef t_saa_component_desc saa_component_desc; +typedef t_saa_component_config saa_component_config; +typedef t_saa_cmd_desc saa_cmd_desc; +typedef t_saa_event_desc saa_event_desc; +typedef t_saa_error saa_error; +typedef t_saa_priority_level saa_priority_level; +typedef t_saa_event_map saa_event_map; + +/******************************************************************* +*******************************************************************/ + +/* typedefs from audiocodec */ +typedef t_codec_direction saa_codec_direction; +typedef t_codec_sample_frequency saa_codec_sample_frequency; +typedef codec_volume saa_codec_volume_struct; +typedef t_codec_input_select saa_codec_input_select; +typedef t_codec_output_select saa_codec_output_select; +typedef codec_tone_wave saa_codec_tone_wave; +typedef codec_configuration saa_codec_conf; + +/* audiocodec tone generator struct */ +typedef struct { + int gain; + unsigned char mix_with_record; + unsigned char mix_with_playback; + saa_codec_tone_wave waveShape; + unsigned long* reserved2; + +} saa_codec_tonegenerator_struct; + +/* audiocodec frequnecy setting structure */ +typedef struct { + saa_codec_direction direction; + saa_codec_sample_frequency input_frequency; + saa_codec_sample_frequency output_frequency; +} saa_codec_freq_struct; + + +/* tone frequencies f1 and f2 structure */ +typedef struct { + int freqF1; + int freqF2; +} saa_tone_frequency_struct; + +/* audiocodec sidetone generator struct */ +typedef struct { + int gain; + unsigned long* reserved1; + unsigned long* reserved2; +} saa_codec_sidetone_struct; + +/* Data direction. IN => to HA, OUT => from HA. */ +typedef enum { + SAA_DATA_DIRECTION_IN, + SAA_DATA_DIRECTION_OUT +} saa_data_direction; + +/**************************************************/ + +/* Block id information structure. */ +typedef struct { + saa_block_id block_id; + saa_block_desc block_desc; +} saa_info_block_struct ; + +/* DMA configuration structure */ + +typedef struct { + t_uint16 error_type; /* range is enum t_saa_fw_error */ + t_uint16 channel_id; + t_uint16 buffer_size; + t_uint32 buffer_address; + t_uint32 avzone_address; + saa_dma_config dma_conf; +} saa_dma_configuration_struct; + +typedef struct { + t_uint16 buffer_size; + t_uint16 nb_buffers; + t_uint32 buffer_address[2]; + t_uint32 avzone_address; + saa_shm_config shm_conf; +} saa_shm_configuration_struct; + +/* for setting the file size */ +typedef struct { + saa_block_id block_id; + saa_port_id port_id; + unsigned long long file_size; +} saa_set_eofsize ; + +enum buffer_type { + SAA_BUFFER_TYPE_DMA = 1, + SAA_BUFFER_TYPE_SHM +}; + +typedef struct { + saa_block_id block_id; + unsigned int offset; +} saa_shmbuf_offset; + +/* Memory buffer queue structure. */ +typedef struct { + enum buffer_type buf_type; + saa_block_id block_id; + int frame_len; + int frame_count; + unsigned int offset; +} saa_alloc_iobuff_struct; + +/*Memory buffer to block id linking structure. +*/ +typedef struct { + enum buffer_type buf_type; + saa_block_id block_id; + saa_data_direction direction; + union { + saa_dma_configuration_struct dma; + //saa_shm_configuration_struct shm; + t_uint32 shm_buffer_address; + }config; +} saa_link_iobuff_struct; + +/* MSP to block connection description structure. */ +typedef struct { + saa_dma_configuration_struct dma; + saa_block_desc block_desc; + saa_data_direction direction; + saa_codec_direction codec_direction; + saa_msp_access_width access_width; + //NOTE:only single arg for freq. + saa_codec_sample_frequency codec_freq; + saa_sample_channel_nb codec_io_channel; + codec_msp_srg_clock_sel_type msp_clock_sel; + codec_msp_in_clock_freq_type msp_clock_freq; + saa_block_id block_id; + +} saa_msp_connect_struct ; + +/* SSP hierarchy (master/slave) */ +typedef enum { + SAA_SSP_MASTER, + SAA_SSP_SLAVE +} saa_ssp_hierarchy; + +/* SSP datapath */ +typedef enum { + SAA_SSP_LOOP_ENABLE, + SAA_SSP_LOOP_DISABLE +} saa_ssp_datapath; + +/*SSP to block connection description structure. +*/ +typedef struct { + saa_dma_configuration_struct dma; + saa_block_desc block_desc; + saa_data_direction direction; + saa_ssp_hierarchy hierarchy; + saa_ssp_datapath datapath; + saa_block_id block_id; +} saa_ssp_connect_struct ; + + +/* I/O transfer buffer structure */ +typedef struct { + enum buffer_type buf_type; + saa_block_id block_id; + unsigned long type; + unsigned int app_ptr; + unsigned int frame_size; + unsigned int bfi; +} saa_xfer_iobuff_struct; + +/* SAA messages */ +typedef enum { + SAA_OVERFLOW_OCCURRED, + SAA_UNDERFLOW_OCCURRED, + SAA_EOF_REACHED, + SAA_BUFFER_PRODUCED, + SAA_BUFFER_CONSUMED, + SAA_CHANGE_DATA_FORMAT, + SAA_ERROR_DETECTED, + SAA_CODEC_ERROR, + SAA_CODEC_INFO, + SAA_SHM_BAD_FRAME, + SAA_DTMF_DETECTED +} saa_message ; + +/* SAA message info structure */ +typedef union { + struct { + saa_message type; + long message_id; + } generic_msg; + struct { + saa_message type; + long message_id; + saa_block_id block_id; + } overflow_occured; + struct { + saa_message type; + long message_id; + saa_block_id block_id; + } underflow_occured; + struct { + saa_message type; + long message_id; + saa_block_id block_id; + unsigned long long filesize; + } eof_reached; + struct { + saa_message type; + long message_id; + saa_block_id block_id; + unsigned int hw_ptr; + unsigned int frame_size; + } buffer_produced; + struct { + saa_message type; + long message_id; + saa_block_id block_id; + unsigned int hw_ptr; + } buffer_consumed; + struct { + saa_message type; + long message_id; + saa_block_id block_id; + saa_sample_freq sample_freq; + saa_endianess_type endianess; + saa_sample_channel_nb channel_nb; + saa_sample_interleaving_type interleaving; + } change_data_format; + struct { + saa_message type; + long message_id; + saa_block_id block_id; + t_uint16 error_id; + } error_detected; + struct { + saa_message type; + long message_id; + saa_block_id block_id; + } codec_error; + struct { + saa_message type; + long message_id; + saa_block_id block_id; + saa_sample_freq sample_freq; + saa_sample_channel_nb channel_nb; + } codec_info; + struct { + saa_message type; + long message_id; + saa_block_id block_id; + } shm_bad_frame; + struct { + saa_message type; + long message_id; + saa_block_id block_id; + t_uint16 comp_id; + t_uint16 code; + } dtmf_detected; +} saa_message_info; + +/* Message buffer structure */ +typedef struct { + unsigned char* message; + int min_count; + unsigned int size; +} saa_message_buff_struct ; + + +/* Transfer status structure */ +typedef struct { + saa_block_id block_id; + unsigned int hw_ptr; +} saa_xfer_status_struct ; + +/* Sample count structure */ +typedef struct { + saa_block_id block_id; + t_uint32 count; + t_uint32 address; + saa_sample_freq freq; + +} saa_samplecount_struct ; + +/* Version strcut of saa and saa-hcl */ + +typedef struct { + struct { + t_uint8 id0; + t_uint8 id1; + t_uint8 id2; + } saa; + struct { + t_uint8 id0; + t_uint8 id1; + t_uint8 id2; + } saa_hcl; +} saa_version; + +/************************************************ +* DATA STRUCTURES FOR USER/KERNEL DATA PASSING * +************************************************/ +typedef struct { + saa_block_id block_id; + saa_block_desc block_desc; +} saa_create_block_struct; + +typedef struct { + saa_port_id port_id; + saa_port_desc port_desc; +} saa_create_port_struct; + +typedef struct { + saa_block_id block_id_src; + saa_port_id port_id_src; + saa_block_id block_id_dest; + saa_port_id port_id_dest; + t_saa_memory_bank memory_bank; +} saa_connection_struct; + +typedef struct { + saa_block_id block_id; + saa_port_id port_id; +} saa_port_struct; + +typedef struct { + saa_block_id block_id; + saa_priority_level priority; +} saa_block_priority_struct; + +typedef struct { + saa_component_id component_id; + saa_component_desc desc; +} saa_AEP_Component_struct; + +typedef struct { + saa_block_id block_id; + saa_component_id cp_id_src; + saa_component_id cp_id_dest; +} saa_AEP_Component_Connect_struct; + +typedef struct { + saa_block_id block_id; + saa_port_id port_id; + saa_stop_mode stop_mode; + t_uint64 size; +} saa_flow_control_struct; + +typedef struct { + saa_block_id block_id; + saa_port_id port_id; + t_uint64 size; +} saa_flow_set_eof_size_struct; + + +/* SAA IOCTL */ + +#define SAAIOCTL_SERVERBLOCKCREATE _IOWR('S', 1, saa_create_block_struct) +#define SAAIOCTL_SERVERBLOCKDELETE _IOR('S', 2, saa_block_id) +#define SAAIOCTL_SERVERPORTCREATE _IOWR('S', 3, saa_create_port_struct) +#define SAAIOCTL_SERVERPORTDELETE _IOR('S', 4, saa_create_port_struct) +#define SAAIOCTL_SERVERBLOCKFREEZE _IOR('S', 5, saa_block_id) +#define SAAIOCTL_SERVERPORTCONNECT _IOR('S', 6, saa_connection_struct) +#define SAAIOCTL_SERVERPORTDISCONNECT _IOR('S', 7, saa_connection_struct) +#define SAAIOCTL_SERVERNETWORKUPDATE _IO('S', 8) +#define SAAIOCTL_SERVERBLOCKPRIORITYSET _IO('S', 9) /* not implemented */ +#define SAAIOCTL_SERVERGETCAPABILITIES _IO('S', 10) /* not implemented */ +#define SAAIOCTL_DMACONFIG _IOWR('S', 11, saa_dma_configuration_struct) +#define SAAIOCTL_CODECCONFIG _IOR('S', 12, saa_codec_config) +#define SAAIOCTL_CODECGETINFO _IOWR('S', 13, saa_block_id) /* need to check further*/ +#define SAAIOCTL_AEPINIT _IOR('S', 14, saa_aep_init) +#define SAAIOCTL_AEPCOMPONENTCREATE _IOWR('S', 15, saa_AEP_Component_struct) +#define SAAIOCTL_AEPCOMPONENTDELETE _IOR('S', 16, saa_AEP_Component_struct) +#define SAAIOCTL_AEPCOMPONENTCONNECT _IOR('S', 17, saa_AEP_Component_Connect_struct) +#define SAAIOCTL_AEPCOMPONENTDISCONNECT _IOR('S', 18, saa_AEP_Component_Connect_struct) +#define SAAIOCTL_AEPCOMPONENTCONFIG _IOR('S', 19, saa_component_config) +#define SAAIOCTL_SET_EOFSIZE _IOWR('S', 20, saa_set_eofsize) +#define SAAIOCTL_GETSAMPLECOUNT _IOWR('S', 21, saa_samplecount_struct) +#define SAAIOCTL_ALLOCATE_IO_BUFFER _IOWR('S', 22, saa_alloc_iobuff_struct) +#define SAAIOCTL_LINK_IO_BUFFER _IOR('S', 23, saa_link_iobuff_struct) +#define SAAIOCTL_CONNECT_TO_MSP _IOR('S', 24, saa_msp_connect_struct) +#define SAAIOCTL_CONNECT_TO_SSP _IOR('S', 25, saa_ssp_connect_struct) +#define SAAIOCTL_TRANSFER_IO_BUFFER _IOR('S', 26, saa_xfer_iobuff_struct) +#define SAAIOCTL_FLUSH_IO_BUFFER _IO('S', 27) /* not needed */ +#define SAAIOCTL_GET_TRANSFER_STATUS _IOWR('S', 28, saa_xfer_status_struct) +#define SAAIOCTL_UPDATE_NETWORK _IO('S', 29) +#define SAAIOCTL_START_NETWORK _IOR('S', 30, saa_flow_control_struct) +#define SAAIOCTL_PAUSE_NETWORK _IOR('S', 31, saa_flow_control_struct) +#define SAAIOCTL_UNPAUSE_NETWORK _IOR('S', 32, saa_flow_control_struct) +#define SAAIOCTL_STOP_NETWORK _IOR('S', 33, saa_flow_control_struct) +#define SAAIOCTL_GET_MESSAGES _IOWR('S', 34, saa_message_buff_struct) +#define SAAIOCTL_GET_VERSION _IOWR('S', 35, saa_version) +#define SAAIOCTL_SET_VOLUME _IOR('S', 36, saa_codec_volume_struct) +#define SAAIOCTL_GET_VOLUME _IOW('S', 37, saa_codec_volume_struct) +#define SAAIOCTL_SET_CODEC_FREQUENCY _IOR('S', 38, saa_codec_freq_struct) +#define SAAIOCTL_ENABLE_TONEGENERATOR _IOW('S', 39, saa_codec_tonegenerator_struct) +#define SAAIOCTL_PLAY_SINGLE_TONE _IOW('S', 40, int) +#define SAAIOCTL_PLAY_DUAL_TONE _IOW('S', 41, saa_tone_frequency_struct) +#define SAAIOCTL_STOP_TONE _IO('S', 42) +#define SAAIOCTL_DISABLE_TONEGENERATOR _IO('S', 43) +#define SAAIOCTL_ENABLE_SIDETONE _IOW('S', 44, saa_codec_sidetone_struct) +#define SAAIOCTL_DISABLE_SIDETONE _IO('S', 45) +#define SAAIOCTL_SELECT_INPUT _IOW('S', 46, saa_codec_input_select) +#define SAAIOCTL_SELECT_OUTPUT _IOW('S', 47, saa_codec_output_select) +#define SAAIOCTL_ENABLE_BYPASS_MODE _IO('S', 48) /* not implemented */ +#define SAAIOCTL_DISABLE_BYPASS_MODE _IO('S', 49) /* not implemented */ +#define SAAIOCTL_DISABLE_MESSAGES _IO('S', 50) /* not implemented */ +#define SAAIOCTL_GET_EOFSIZE _IO('S', 52) /* not implemented */ +#define SAAIOCTL_GET_SHMBUF_OFFSET _IOW('S', 53, saa_shmbuf_offset) +#define SAAIOCTL_SHMCONFIG _IOW('S', 54, saa_shm_configuration_struct) + +#endif + + + + --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/sva/Makefile @@ -0,0 +1,58 @@ +#KERNEL_PATH = /home/preetham/lastestlinux/linux-2.6.20 +#KERNEL_PATH:=../../../../../linux-2.6.20 +#NMDK_HCLDIR = /home/preetham/lastestlinux/linux-2.6.20/drivers/media/nomadik_mm/hcl +#NMDK_HCLDIR:=../hcl +OBJ_HCLDIR = ../hcl +#CC=arm-926ejs-linux-gnueabi-gcc +#LD=arm-926ejs-linux-gnueabi-ld +#AR=arm-926ejs-linux-gnueabi-ar +ifeq ($(CONFIG_NOMADIK_NDK10),y) +ifeq ($(CONFIG_NOMADIK_NDK10_CUTA),y) +HCL_CFLAGS := -D__arm -D__STN_8810=1 -D__RELEASE -D__PLATFORM_MEVKFULL +else +HCL_CFLAGS := -D__arm -D__STN_8810=20 -D__RELEASE -D__PLATFORM_MEVKFULL +endif +else +ifeq ($(CONFIG_NOMADIK_NDK15_REV2_B_06),y) +HCL_CFLAGS := -D__arm -D__STN_8815=20 -D__RELEASE -D__CC_ARM +else +ifeq ($(CONFIG_NOMADIK_NHK15),y) +HCL_CFLAGS := -D__arm -D__STN_8815=20 -D__RELEASE -D__CC_ARM +else +HCL_CFLAGS := -D__arm -D__STN_8815=10 -D__RELEASE -D__CC_ARM +endif +endif +endif + +#COMMON_CFLAGS := -I$(NMDK_HCLDIR)/include -I$(NMDK_HCLDIR)/sva -I$(NMDK_HCLDIR)/sva/include -I$(NMDK_HCLDIR)/hloader -I$(NMDK_HCLDIR)/include -I$(NMDK_HCLDIR)/debug -I$(NMDK_HCLDIR)/sva/common -I$(NMDK_HCLDIR)/sva/still_decode -I$(NMDK_HCLDIR)/sva/memory_management -I$(NMDK_HCLDIR)/sva/decode -I$(NMDK_HCLDIR)/sva/encode -I$(NMDK_HCLDIR)/sva/firmware_management -I$(NMDK_HCLDIR)/sva/encode/h264 -I$(NMDK_HCLDIR)/sva/decode/h264 -I$(NMDK_HCLDIR)/sva/tasks_management -I$(NMDK_HCLDIR)/sva/events_management -I$(NMDK_HCLDIR)/sva/encode/brc/ +COMMON_CFLAGS := -I$(src)/ -I$(src)/../hcl/include/ -I$(src)/../hcl/sva/ -I$(src)/../hcl/hloader/ -I$(src)/../hcl/sva/include/ -I$(src)/../hcl/sva/events_management/ -I$(src)/../hcl/sva/common/ -I$(src)/../hcl/sva/decode/h264/ -I$(src)/../hcl/sva/memory_management/ -I$(src)/../hcl/sva/still_decode/ -I$(src)/../hcl/sva/encode/ -I$(src)/../hcl/sva/encode/h264/ -I$(src)/../hcl/sva/tasks_management/ -I$(src)/../hcl/sva/encode/brc/ -I$(src)/../hcl/sva/decode/ -I$(src)/../hcl/sva/firmware_management/ + +# All of the (potential) objects that export symbols. +# This list comes from 'grep -l EXPORT_SYMBOL *.[hc]'. +# +#all: +# $(MAKE) -C $(KERNEL_PATH) M=`pwd` CC="$(CC)" LD="$(LD)" AR="$(AR)" +# +sva_obj := nomadik_sva.o +sva_obj += nomadik_sva_utils.o +sva_obj += nomadik_sva_mpeg4.o +sva_obj += nomadik_sva_vpip.o + +#cam_obj := nomadik_pepperpot.o + +#obj-m = nmdkmod_pepperpot.o nmdkmod_SVA.o +obj-$(CONFIG_NOMADIK_SVA) += nmdkmod_SVA.o + +#nmdkmod_pepperpot-objs := $(cam_obj) + +hcl_obj := $(OBJ_HCLDIR)/sva/firmware_management/sva_fwmgt.o $(OBJ_HCLDIR)/sva/events_management/sva_irqmgt.o $(OBJ_HCLDIR)/sva/events_management/sva_eventmgt.o $(OBJ_HCLDIR)/sva/common/sva_timemgt.o $(OBJ_HCLDIR)/sva/common/sva_internalneeds.o $(OBJ_HCLDIR)/sva/common/sva_capabilities.o $(OBJ_HCLDIR)/sva/grab/sva_grab.o $(OBJ_HCLDIR)/sva/tasks_management/sva_taskmgt.o $(OBJ_HCLDIR)/sva/tasks_management/sva_hwtaskmgt.o $(OBJ_HCLDIR)/sva/tasks_management/sva_taskschl.o $(OBJ_HCLDIR)/sva/still_encode/jpeg/sva_sec_jpeg.o $(OBJ_HCLDIR)/sva/still_encode/sva_still_encode.o $(OBJ_HCLDIR)/sva/memory_management/sva_bufferlistmgt.o $(OBJ_HCLDIR)/sva/memory_management/sva_buffermgt.o $(OBJ_HCLDIR)/sva/memory_management/sva_memorymgt.o $(OBJ_HCLDIR)/sva/decode/mpeg2/sva_dc_mpeg2.o $(OBJ_HCLDIR)/sva/decode/mpeg2/sva_dc_mpeg2p.o $(OBJ_HCLDIR)/sva/decode/mpeg4/sva_dc_mpeg4.o $(OBJ_HCLDIR)/sva/decode/mpeg4/sva_dc_mpeg4p.o $(OBJ_HCLDIR)/sva/decode/h264/sva_dc_h264.o $(OBJ_HCLDIR)/sva/decode/h264/sva_dc_h264_dpb.o $(OBJ_HCLDIR)/sva/decode/h264/sva_dc_h264_slicemap.o $(OBJ_HCLDIR)/sva/encode/h264/sva_ec_h264.o $(OBJ_HCLDIR)/sva/decode/vc1/sva_dc_vc1.o $(OBJ_HCLDIR)/sva/decode/vc1/sva_dc_vc1p.o $(OBJ_HCLDIR)/sva/decode/sva_decode.o $(OBJ_HCLDIR)/sva/decode/sva_decodep.o $(OBJ_HCLDIR)/sva/encode/mpeg4/sva_ec_mpeg4.o $(OBJ_HCLDIR)/sva/encode/brc/sva_brc.o $(OBJ_HCLDIR)/sva/encode/sva_encode.o $(OBJ_HCLDIR)/sva/openservice_management/sva_openservicemgt.o $(OBJ_HCLDIR)/sva/stab/sva_stab.o $(OBJ_HCLDIR)/sva/still_decode/jpeg/sva_sdc_jpeg.o $(OBJ_HCLDIR)/sva/still_decode/sva_still_decode.o $(OBJ_HCLDIR)/sva/sva.o $(OBJ_HCLDIR)/sva/display/sva_display.o $(OBJ_HCLDIR)/sva/tvo/sva_tvo.o $(OBJ_HCLDIR)/hloader/hloader.o + +nmdkmod_SVA-objs := $(sva_obj) $(hcl_obj) + +EXTRA_CFLAGS := $(HCL_CFLAGS) +EXTRA_CFLAGS += $(COMMON_CFLAGS) +# +#clean: +# $(MAKE) -C $(KERNEL_PATH) M=`pwd` clean; rm -f $(hcl_obj) +# + --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_camera.h @@ -0,0 +1,206 @@ +/*--------------------------------------------------------------------------------------------------*/ +/*© copyright STMicroelectronics, 2007. */ +/* */ +/*This program is free software; you can redistribute it and/or modify it under */ +/*the terms of the GNU General Public License as published by the Free */ +/*Software Foundation; either version 2.1 of the License, or (at your option) */ +/*any later version. */ +/* */ +/*This program is distributed in the hope that it will be useful, but WITHOUT */ +/*ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU General Public License for more details. */ +/* */ +/*You should have received a copy of the GNU General Public License */ +/*along with this program. If not, see . */ +/*--------------------------------------------------------------------------------------------------*/ + + + + + + + + +#ifndef __SVA_CAMERA_H__ +#define __SVA_CAMERA_H__ + +#include "nomadik_defs.h" + +/*#ifdef CONFIG_DEBUG_NOMADIK +#define DDBGPRINTK( s, args... ) printk( KERN_ALERT s, ##args ) +#else +//#define DDBGPRINTK( s, args... ) printk( KERN_ALERT s, ##args ) +#define DDBGPRINTK(x,... ) +#endif + +#define DERRPRINTK( s, args... ) printk( KERN_ALERT s, ##args ) +*/ +#define VGA_HEIGHT 480 +#define VGA_WIDTH 640 +#define CIF_HEIGHT 288 +#define CIF_WIDTH 352 +#define QVGA_HEIGHT 240 +#define QVGA_WIDTH 320 +#define QCIF_HEIGHT 144 +#define QCIF_WIDTH 176 +#define QQVGA_HEIGHT 120 +#define QQVGA_WIDTH 160 +#define QQVGA_PLUS_HEIGHT 128 +#define QQVGA_PLUS_WIDTH 160 +#define QQVGA_MINUS_HEIGHT 112 +#define QQVGA_MINUS_WIDTH 128 +#define SUBQCIF_HEIGHT 96 +#define SUBQCIF_WIDTH 128 +#define QQCIF_HEIGHT 72 +#define QQCIF_WIDTH 88 +#define CUSTOM_HEIGHT 64 +#define CUSTOM_WIDTH 80 + + +/* Defining the camera white balance supported */ +#define CAMERA_WB_OFF 0x00 +#define CAMERA_WB_AUTOMATIC 0x01 +#define CAMERA_WB_AUTOINSTANT 0x02 +#define CAMERA_WB_MANUAL 0x04 +#define CAMERA_WB_DAYLIGHT 0x05 +#define CAMERA_WB_TUNGSTEN 0x06 +#define CAMERA_WB_FLUORESCENT 0x07 +#define CAMERA_WB_HORIZON 0x08 +#define CAMERA_WB_FROZEN 0x09 + +#define CAMERA_AVOID_DIG_GAIN 0x00000001 +#define CAMERA_NOT_AVOID_DIG_GAIN 0x00000002 +#define CAMERA_INHIBIT_ROUNDUP 0x00000004 +#define CAMERA_NOT_INHIBIT_ROUNDUP 0x00000008 +#define CAMERA_SACRIFICE_EXP 0x00000010 +#define CAMERA_NOT_SACRIFICE_EXP 0x00000020 +#define CAMERA_INHIBIT_ANTIFLICKEREXP 0x00000040 +#define CAMERA_NOT_INHIBIT_ANTIFLICKEREXP 0x00000080 +#define CAMERA_INHIBIT_GAINCTRL 0x00000100 +#define CAMERA_NOT_INHIBIT_GAINCTRL 0x00000200 +#define CAMERA_FREEZE_AUTOEXP 0x00000400 +#define CAMERA_NOT_FREEZE_AUTOEXP 0x00000800 + + + +struct camera_capability { + __u8 viewfinder_bitmap; + __u8 viewfinder_direct; + __u8 image_capture; + __u8 video_capture; + __u8 contrast; + __u8 brightness; + + char white_balance; + char flash_mode; + char exposure; + int min_zoom; + int max_zoom; + int max_digital_zoom; + + int num_image_sizes; + int image_formats; + +}; + +//* Defining the camera flash modes */ +#define CAMERA_FLASH_NONE 0x00 +#define CAMERA_FLASH_AUTO 0x01 +#define CAMERA_FLASH_FORCED 0x02 +#define CAMERA_FLASH_FILLIN 0x04 +#define CAMERA_FLASH_REDEYE_REDUCE 0x08 + +/* Defining the camera exposure supported */ +#define CAMERA_EXPOSURE_AUTO 0x00 +#define CAMERA_EXPOSURE_NIGHT 0x01 +#define CAMERA_EXPOSURE_BACKLIGHT 0x02 +#define CAMERA_EXPOSURE_CENTRE 0x04 + +/* Defining the camera white balance supported */ +#define CAMERA_WB_AUTO 0x00 +#define CAMERA_WB_DAY_LIGHT 0x01 +#define CAMERA_WB_CLOUDY 0x02 +/* #define CAMERA_WB_TUNGSTEN 0x04 */ +#define CAMERA_WB_FLOURESCENT 0x08 +#define CAMERA_WB_FLASH 0x10 + +/* Defining the camera interface types */ +#define CAMERA_CCP_TYPE 0 +#define CAMERA_CCIR_TYPE 1 + +enum cameramode{ + CAMERAMODE_SLEEP=0, + CAMERAMODE_IDLE, + CAMERAMODE_VIEWFINDER, + CAMERAMODE_CAPTURE, + CAMERAMODE_LIVE, + CAMERAMODE_FLASH, + CAMERAMODE_RESERVED, + CAMERAMODE_BOOTING, + CAMERAMODE_UNKNOWN +}; + +enum camera_image_format { + IMG_FMT_RGB332 = 0, + IMG_FMT_RGB444, + IMG_FMT_RGB565, + IMG_FMT_YUV422, + IMG_FMT_JPEG, + IMG_FMT_UNKNOWN +}; + +enum camera_param_id { +FRAMERATE = 0, +CAMERAMODE, +FREQUENCY, +ZOOM, +}; + +struct camera_control { +enum camera_param_id id; +void *value; +}; + +struct camera_frequency { + __u8 msb; + __u8 lsb; +}; + +struct camera_configuration { + struct sva_image frame; + enum camera_image_format format; + __u16 frame_rate; + struct camera_frequency frequency; +}; + +struct camera { +char name[20]; +enum cameramode mode; +int type; +int height; +int width; +int bpp; +int frequency; +int frame_rate; +int capture_wait_count; +int (*init) (void); +void (*cleanup) (void); +int (*open) (void); +int (*close) (void); +int (*get_capability) (struct camera_capability *); +int (*set_params) (struct camera_configuration *); +int (*get_params) (struct camera_configuration *); +int (*set_control) (struct camera_control *ctrl); +int (*get_control) (struct camera_control *ctrl); +int (*set_jpegq) (int quality); +int (*get_jpegq) (int quality); +int (*whitebalancemode)(__u8 mode); +int (*expandcompilectrl)(__u8 ctrl); +}; + +int camera_register_device(struct camera*); +void camera_unregister_device (struct camera *); + + +#endif /*__CAMERA_H__*/ --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_defs.h @@ -0,0 +1,76 @@ +/*--------------------------------------------------------------------------------------------------*/ +/*© copyright STMicroelectronics, 2007. */ +/* */ +/*This program is free software; you can redistribute it and/or modify it under */ +/*the terms of the GNU General Public License as published by the Free */ +/*Software Foundation; either version 2.1 of the License, or (at your option) */ +/*any later version. */ +/* */ +/*This program is distributed in the hope that it will be useful, but WITHOUT */ +/*ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU General Public License for more details. */ +/* */ +/*You should have received a copy of the GNU General Public License */ +/*along with this program. If not, see . */ +/*--------------------------------------------------------------------------------------------------*/ + + + + + +#ifndef __SVA_NOMADIK_H__ +#define __SVA_NOMADIK_H__ + +#ifndef __KERNEL__ +#define __KERNEL__ +#endif + +//#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include /* tasklet functions */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +//#include +#include + +#include +#include "nomadik_sva_services.h" +#include "nomadik_camera.h" + +#define TIMERCLK 90000 +#define SVA_HCL_MEMSIZE (10 * 1024 * 1024) + +#define MAX_OPENS 8 +#define MAX_SERVICE_OPENS MAX_OPENS +#define MAX_BUFFERS 50 +#define BITS_BUF_SIZE 60 * 1024 /* 60KB*/ +#define MAX_IOCTL_SIZE 4 * 1024 +#define TWO_MB 2*1024*1024 + +#define ERR_NO_BUFFER -100 + +#endif /* __SVA_NOMADIK_H__ */ + + + --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_pepperpot.c @@ -0,0 +1,1189 @@ +/*--------------------------------------------------------------------------------------------------*/ +/*© copyright STMicroelectronics, 2007. */ +/* */ +/*This program is free software; you can redistribute it and/or modify it under */ +/*the terms of the GNU General Public License as published by the Free */ +/*Software Foundation; either version 2.1 of the License, or (at your option) */ +/*any later version. */ +/* */ +/*This program is distributed in the hope that it will be useful, but WITHOUT */ +/*ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU General Public License for more details. */ +/* */ +/*You should have received a copy of the GNU General Public License */ +/*along with this program. If not, see . */ +/*--------------------------------------------------------------------------------------------------*/ + + + + + + +#include "nomadik_pepperpot.h" +#include +#include +#include +#include +#include +#include +#include + +struct camera * pp_info; + +static int statetransition[5][5]= +{ {1,1,0,0,0},/* SLEEP */ + {1,1,1,1,1},/* IDLE */ + {0,1,0,1,1},/* VIEWFINDER */ + {0,1,1,0,1},/* CAPTURE */ + {0,1,1,1,0} /* LIVE */ +}; + +#define SVA_DEFAULT_LOG_LEVEL 3 +static int debug = SVA_DEFAULT_LOG_LEVEL; +MODULE_PARM_DESC(debug,"Debug level for messages"); +module_param(debug, int, 0644); +#define dbgprintk(num, format, args...) \ + do { \ + if(num >= debug ) \ + printk("Pepperpot:"format, ##args); \ + } while(0) + +static int sva_get_pepperpot_clockfreq(struct camera_frequency *freq) +{ + int retval; + __u8 data; + + dbgprintk(1,"Getting the frequency \n"); + + retval=nomadik_i2c_read_register(I2C_PP_CAM_CLIENT,&data, + NMDK_PEPPERPOT_REG0_EXTERNALCLKMSB,1); + if(retval<0) + { + dbgprintk(3,"nomadik_i2c_read_register() \ + failed while getting the frequency %d \n",retval); + return -EINVAL; + } + + freq->msb = data; + + retval=nomadik_i2c_read_register(I2C_PP_CAM_CLIENT,&data, + NMDK_PEPPERPOT_REG0_EXTERNALCLKLSB,1); + if(retval<0) + { + dbgprintk(3,"nomadik_i2c_read_register() \ + failed while getting the frequency %d \n",retval); + return -EINVAL; + } + + freq->lsb = data; + + dbgprintk(1,"Getting the frequency \n"); + return 0; +} + +static int sva_set_pepperpot_clockfreq(struct camera_frequency *freq) +{ + int retval; + __u8 data; + + dbgprintk(1,"Getting the frequency \n"); + + data = freq->msb; + + retval=nomadik_i2c_write_register(I2C_PP_CAM_CLIENT,&data, + NMDK_PEPPERPOT_REG0_EXTERNALCLKMSB,1); + if(retval<0) + { + dbgprintk(3,"nomadik_i2c_read_register() \ + failed while getting the frequency %d \n",retval); + return -EINVAL; + } + + data = freq->lsb; + + retval=nomadik_i2c_write_register(I2C_PP_CAM_CLIENT,&data, + NMDK_PEPPERPOT_REG0_EXTERNALCLKLSB,1); + if(retval<0) + { + dbgprintk(3,"nomadik_i2c_read_register() \ + failed while getting the frequency %d \n",retval); + return -EINVAL; + } + + retval=nomadik_i2c_read_register(I2C_PP_CAM_CLIENT,&data, + NMDK_PEPPERPOT_REG0_EXTERNALCLKMSB,1); + if(retval<0) + { + dbgprintk(3,"nomadik_i2c_read_register() \ + failed while getting the frequency %d \n",retval); + return -EINVAL; + } + + dbgprintk(1,"nomadik_i2c_read_register() getting the msb frequency %d \n",data); + + retval=nomadik_i2c_read_register(I2C_PP_CAM_CLIENT,&data, + NMDK_PEPPERPOT_REG0_EXTERNALCLKLSB,1); + if(retval<0) + { + dbgprintk(3,"nomadik_i2c_read_register() \ + failed while getting the frequency %d \n",retval); + return -EINVAL; + } + + dbgprintk(1,"nomadik_i2c_read_register() getting the frequency lsb %d \n",data); + + dbgprintk(1,"The frequency is pp_info->frequency %x\n",data); + return 0; +} + +/* Camera Mode Status*/ +static int sva_get_pepperpot_mode(void) +{ + __u8 data; + int retval; + + dbgprintk(1,"Camera Mode Status\n"); + + retval=nomadik_i2c_read_register(I2C_PP_CAM_CLIENT,&data, + NMDK_PEPPERPOT_REG0_MODESTATUS,1); + if(retval<0) + { + dbgprintk(3,"nomadik_i2c_read_register() failed :\ + camera mode status check %d\n",retval); + return -EINVAL; + } + + switch(data) + { + case NMDK_PEPPERPOT_CAMERAMODE_SLEEP : + dbgprintk(1," Mode : Sleep \n"); + retval = CAMERAMODE_SLEEP; + break; + case NMDK_PEPPERPOT_CAMERAMODE_IDLE : + dbgprintk(1," Mode : Idle \n"); + retval = CAMERAMODE_IDLE; + break; + case NMDK_PEPPERPOT_CAMERAMODE_VIEWFINDER : + dbgprintk(1," Mode : ViewFinder \n"); + retval = CAMERAMODE_VIEWFINDER; + break; + case NMDK_PEPPERPOT_CAMERAMODE_CAPTURE : + dbgprintk(1," Mode : Capture \n"); + retval = CAMERAMODE_CAPTURE; + break; + case NMDK_PEPPERPOT_CAMERAMODE_LIVE : + dbgprintk(1," Mode : Live \n"); + retval = CAMERAMODE_LIVE; + break; + case NMDK_PEPPERPOT_CAMERAMODE_RESERVED : + dbgprintk(1," Mode : Capture in progress \n"); + retval = CAMERAMODE_RESERVED; + break; + case NMDK_PEPPERPOT_CAMERAMODE_FLASH : + dbgprintk(1," Mode : Flash \n"); + retval = CAMERAMODE_FLASH; + break; + case NMDK_PEPPERPOT_CAMERAMODE_BOOTING : + dbgprintk(1," Mode : Booting \n"); + retval = CAMERAMODE_BOOTING; + break; + + default : + dbgprintk(3," Mode : Unknown value \n"); + retval = CAMERAMODE_UNKNOWN; + break ; + } + + dbgprintk(1,"Camera Mode Status successfully checked\n "); + pp_info->mode = retval; + + return retval; +} + +static int sva_set_pepperpot_mode (enum cameramode mode) +{ + __u8 data; + int curmode=0; + int retval=0; + + dbgprintk(1,"In set_pepperpot_mode %d\n",mode); + + curmode = sva_get_pepperpot_mode(); + if(curmode < 0) + return -EINVAL; + + if(!(statetransition[curmode][mode])) { + dbgprintk(1," Invalid mode transition %d\n",mode); + return -EINVAL; + } + + switch(mode) { + case CAMERAMODE_SLEEP: + data = NMDK_PEPPERPOT_CAMERAMODE_SLEEP; + break; + case CAMERAMODE_IDLE: + data = NMDK_PEPPERPOT_CAMERAMODE_IDLE; + break; + case CAMERAMODE_VIEWFINDER: + data = NMDK_PEPPERPOT_CAMERAMODE_VIEWFINDER; + break; + case CAMERAMODE_CAPTURE: + data = pp_info->capture_wait_count; + retval=nomadik_i2c_write_register(I2C_PP_CAM_CLIENT, + &data,NMDK_PEPPERPOT_REG1_DELAYTRANSFERMODE,1); + if(retval < 0) + { + dbgprintk(3,"Set delay transfer mode failed\n"); + return -EINVAL; + } + data = NMDK_PEPPERPOT_CAMERAMODE_CAPTURE; + break; + case CAMERAMODE_LIVE: + data = NMDK_PEPPERPOT_CAMERAMODE_LIVE; + break; + case CAMERAMODE_BOOTING: + data = NMDK_PEPPERPOT_CAMERAMODE_BOOTING; + break; + default: + return -EINVAL; + } + + while(curmode != data ) { + retval = nomadik_i2c_write_register(I2C_PP_CAM_CLIENT,&data, + NMDK_PEPPERPOT_REG0_MODECONTROL,1); + if(retval<0) + { + dbgprintk(3,"nomadik_i2c_write_register() failed :\ + Setting the Camera mode %d\n",retval); + return -EINVAL; + } + dbgprintk(2,"Setting Successful : Camera mode %d\n",data); + curmode = sva_get_pepperpot_mode(); + dbgprintk(2,"Getting Successful : Camera mode %d\n",curmode); + } + + pp_info->mode = mode; + dbgprintk(2,"Mode Setting Successful, mode read %d\n",data); + return retval; +} + +static int sva_get_pepperpot_imageformat(void) +{ + int retval; + __u8 data; + + dbgprintk(1," Getting the viewfinder image format \n"); + retval = nomadik_i2c_read_register(I2C_PP_CAM_CLIENT,&data, + NMDK_PEPPERPOT_REG1_LIVEIMGOUTPUTFORMAT,1); + if(retval<0) + { + dbgprintk(3,"nomadik_i2c_read_register() failed:\ + Getting the viewfinder image format %d\n",retval); + return -EINVAL; + } + + switch(data) + { + case NMDK_PEPPERPOT_IMG_FMT_RGB332 : + dbgprintk(1," Viewfinder Image format : RGB 332 \n"); + retval = IMG_FMT_RGB332; + break; + + case NMDK_PEPPERPOT_IMG_FMT_RGB444 : + dbgprintk(1," Viewfinder Image format : RGB 444 \n"); + retval = IMG_FMT_RGB444; + break; + + case NMDK_PEPPERPOT_IMG_FMT_RGB565 : + dbgprintk(1," Viewfinder Image format : RGB 565 \n"); + retval = IMG_FMT_RGB565; + break; + + case NMDK_PEPPERPOT_IMG_FMT_YUV422: + dbgprintk(1," Viewfinder Image format : YUV 422 \n"); + retval = IMG_FMT_YUV422; + break; + + case NMDK_PEPPERPOT_IMG_FMT_JPEG : + dbgprintk(1," Viewfinder Image format : JPEG \n"); + retval = IMG_FMT_JPEG; + break; + + default : + dbgprintk(3," Viewfinder Image format : unknown format\n"); + return -EINVAL; + break; + } + + + dbgprintk(1," Getting the viewfinder image format successful\n"); + + return retval; +} + +static int sva_get_pepperpot_framerate(void) +{ + int retval; + __u8 data; + + dbgprintk(1," Getting the viewfinder framerate \n"); + + retval = nomadik_i2c_read_register(I2C_PP_CAM_CLIENT,&data, + NMDK_PEPPERPOT_REG1_LIVEFRAMERATE,1); + if(retval<0) + { + dbgprintk(3,"nomadik_i2c_read_register() failed :\ + Getting the viewfinder framerate %d\n",retval); + return -EINVAL; + } + + data>>=2; + dbgprintk(1,"The framerate is %x\n",data); + + pp_info->frame_rate=data; + dbgprintk(1,"Getting the viewfinder framerate successful \n"); + return data; +} + +static int sva_get_pepperpot_imagesize(void) +{ + __u8 data; + int retval; + + dbgprintk(1," Getting the viewfinder image size \n"); + retval = nomadik_i2c_read_register(I2C_PP_CAM_CLIENT,&data, + NMDK_PEPPERPOT_REG1_LIVEIMGSIZE,1); + if(retval<0) + { + + dbgprintk(3,"nomadik_i2c_read_register() failed : \ + Getting the viewfinder image size %d\n",retval); + return -EINVAL; + } + + switch(data) + { + case NMDK_PEPPERPOT_CAMERAIMGSIZE_VGA : + dbgprintk(1," Viewfinder Image size : VGA \n"); + pp_info->width = VGA_WIDTH; + pp_info->height = VGA_HEIGHT; + + break; + + case NMDK_PEPPERPOT_CAMERAIMGSIZE_CIF : + dbgprintk(1," Viewfinder Image size : CIF \n"); + pp_info->width = CIF_WIDTH; + pp_info->height = CIF_HEIGHT; + break; + + case NMDK_PEPPERPOT_CAMERAIMGSIZE_QVGA : + dbgprintk(1," Viewfinder Image size : QVGA \n"); + pp_info->width = QVGA_WIDTH; + pp_info->height = QVGA_HEIGHT; + break; + + case NMDK_PEPPERPOT_CAMERAIMGSIZE_QCIF : + dbgprintk(1," Viewfinder Image size : QCIF \n"); + pp_info->width = QCIF_WIDTH; + pp_info->height = QCIF_HEIGHT; + break; + + case NMDK_PEPPERPOT_CAMERAIMGSIZE_QQVGA : + dbgprintk(1," Viewfinder Image size : QQVGA \n"); + pp_info->width = QQVGA_WIDTH; + pp_info->height = QQVGA_HEIGHT; + break; + + case NMDK_PEPPERPOT_CAMERAIMGSIZE_SUBQCIF : + dbgprintk(1," Viewfinder Image size : SubQCIF \n"); + pp_info->width = SUBQCIF_WIDTH; + pp_info->height = SUBQCIF_HEIGHT; + break; + + case NMDK_PEPPERPOT_CAMERAIMGSIZE_QQCIF : + dbgprintk(1," Viewfinder Image size : QQCIF \n"); + pp_info->width = QQCIF_WIDTH; + pp_info->height = QQCIF_HEIGHT; + break; + + default : + dbgprintk(3," Viewfinder Image size : unknown size \n"); + break; + } + + + dbgprintk(1," Getting the viewfinder image size successful\n"); + return data; +} + +static int sva_set_pepperpot_framerate(__u16 framerate) +{ + __u8 data; + int retval; + + dbgprintk(1,"%s entered\n",__FUNCTION__); + data = 0; + data = framerate << 2; + retval = nomadik_i2c_write_register(I2C_PP_CAM_CLIENT,&data, + NMDK_PEPPERPOT_REG1_LIVEFRAMERATE,1); + if(retval<0) + { + dbgprintk(3,"nomadik_i2c_write_register() failed : \ + setting the still n live frame rate %d\n",retval); + return -EINVAL; + } + + retval = nomadik_i2c_read_register(I2C_PP_CAM_CLIENT,&data, + NMDK_PEPPERPOT_REG1_LIVEFRAMERATE,1); + if(retval<0) + { + dbgprintk(3,"nomadik_i2c_write_register() failed : \ + setting the still n live frame rate %d\n",retval); + return -EINVAL; + } + + dbgprintk(1,"nomadik_i2c_read_register() Getting the \ + still n live frame rate %d\n",data); + dbgprintk(1,"%s Leaving Successfully \n",__FUNCTION__); + + return retval; +} + +static int sva_set_pepperpot_imagesize(int width) +{ + int retval; + __u8 data = 0; + + dbgprintk(1," Getting the viewfinder image size \n"); + + switch(width) + { + case VGA_WIDTH: + dbgprintk(1," Viewfinder Image size : VGA \n"); + data = NMDK_PEPPERPOT_CAMERAIMGSIZE_VGA; + + break; + + case CIF_WIDTH: + dbgprintk(1," Viewfinder Image size : CIF \n"); + data = NMDK_PEPPERPOT_CAMERAIMGSIZE_CIF; + + break; + + case QVGA_WIDTH: + dbgprintk(1," Viewfinder Image size : QVGA \n"); + data = NMDK_PEPPERPOT_CAMERAIMGSIZE_QVGA; + + break; + + case QCIF_WIDTH: + dbgprintk(1," Viewfinder Image size : QCIF \n"); + data = NMDK_PEPPERPOT_CAMERAIMGSIZE_QCIF; + + break; + + case QQVGA_WIDTH: + dbgprintk(1," Viewfinder Image size : QQVGA \n"); + data = NMDK_PEPPERPOT_CAMERAIMGSIZE_QQVGA; + + break; + + case QQCIF_WIDTH: + dbgprintk(1," Viewfinder Image size : QQCIF \n"); + data = NMDK_PEPPERPOT_CAMERAIMGSIZE_QQCIF; + + break; + + case SUBQCIF_WIDTH: + dbgprintk(1," Viewfinder Image size : SUBQCIF \n"); + data = NMDK_PEPPERPOT_CAMERAIMGSIZE_SUBQCIF; + + break; + + + default : + dbgprintk(3," Viewfinder Image size : unknown size \n"); + break; + } /* End switch */ + + retval = nomadik_i2c_write_register(I2C_PP_CAM_CLIENT,&data, + NMDK_PEPPERPOT_REG1_LIVEIMGSIZE,1); + if(retval<0) + { + + dbgprintk(3,"nomadik_i2c_read_register() failed : \ + Setting the viewfinder image size %d\n",retval); + return -EINVAL; + } + + retval = nomadik_i2c_read_register(I2C_PP_CAM_CLIENT,&data, + NMDK_PEPPERPOT_REG1_LIVEIMGSIZE,1); + if(retval<0) + { + + dbgprintk(3,"nomadik_i2c_read_register() failed : \ + Setting the viewfinder image size %d\n",retval); + return -EINVAL; + } + + dbgprintk(1," Getting the viewfinder image size %d\n",data); + + dbgprintk(1," Setting the viewfinder image size successful\n"); + return 0; +} + +static int sva_set_pepperpot_imageformat(enum camera_image_format fmt) +{ + int retval; + __u8 data; + + dbgprintk(1,"%s entered\n",__FUNCTION__); + + switch(fmt) + { + case IMG_FMT_RGB332 : + dbgprintk(1," Viewfinder Image format : RGB 332 \n"); + data = NMDK_PEPPERPOT_IMG_FMT_RGB332; + break; + + case IMG_FMT_RGB444 : + dbgprintk(1," Viewfinder Image format : RGB 444 \n"); + data = NMDK_PEPPERPOT_IMG_FMT_RGB444; + break; + + case IMG_FMT_RGB565 : + dbgprintk(1," Viewfinder Image format : RGB 565 \n"); + data = NMDK_PEPPERPOT_IMG_FMT_RGB565; + break; + + case IMG_FMT_YUV422: + dbgprintk(1," Viewfinder Image format : YUV 422 \n"); + data = NMDK_PEPPERPOT_IMG_FMT_YUV422; + break; + + case IMG_FMT_JPEG : + dbgprintk(1," Viewfinder Image format : JPEG \n"); + data = NMDK_PEPPERPOT_IMG_FMT_JPEG; + break; + + default : + dbgprintk(3," Viewfinder Image format : unknown format\n"); + return -EINVAL; + } + + + retval = nomadik_i2c_write_register(I2C_PP_CAM_CLIENT,&data, + NMDK_PEPPERPOT_REG1_LIVEIMGOUTPUTFORMAT,1); + + if(retval<0) + { + dbgprintk(3,"nomadik_i2c_write_register() failed : \ + Setting the still and live image format %d\n",retval); + return -EINVAL; + } + + retval = nomadik_i2c_read_register(I2C_PP_CAM_CLIENT,&data, + NMDK_PEPPERPOT_REG1_LIVEIMGOUTPUTFORMAT,1); + + if(retval<0) + { + dbgprintk(3,"nomadik_i2c_write_register() failed : \ + Setting the still and live image format %d\n",retval); + return -EINVAL; + } + + dbgprintk(1,"nomadik_i2c_read_register() : \ + Setting the still and live image format %d\n",data); + + dbgprintk(1,"%s Leaving successfully \n",__FUNCTION__); + + return 0; +} + +static int +sva_pepperpot_set_control(struct camera_control *ctrl) +{ + int ret; + + switch(ctrl->id) { + + case CAMERAMODE: + { + ret = sva_set_pepperpot_mode(*((enum cameramode *)ctrl->value)); + break; + } + + case FRAMERATE: + { + ret = sva_set_pepperpot_framerate(*((__u8 *)(ctrl->value))); + break; + } + + case FREQUENCY: + { + ret = sva_set_pepperpot_clockfreq((struct camera_frequency *)ctrl->value); + break; + } + + default: + dbgprintk(1,"Not implemented funtion\n"); + ret = -EINVAL; + + } /* End switch */ + + if(ret >= 0) + return 0; + else + return -EINVAL; + +} + +static int +sva_pepperpot_get_control(struct camera_control *ctrl) +{ + int ret; + + switch(ctrl->id) { + + case CAMERAMODE: + { + ret = sva_get_pepperpot_mode(); + *((enum cameramode *)ctrl->value) = ret; + break; + } + + case FRAMERATE: + { + ret = sva_get_pepperpot_framerate(); + *((__u16 *)ctrl->value) = ret; + break; + } + + case FREQUENCY: + { + ret = sva_get_pepperpot_clockfreq((struct camera_frequency *)ctrl->value); + break; + } + + default: + dbgprintk(1,"Not implemented funtion\n"); + ret = -EINVAL; + + } /* End switch */ + + return ret; + +} + +static struct camera_capability pepperp_capability = { + viewfinder_bitmap: 0, + viewfinder_direct: 0, + image_capture: 1, + video_capture: 1, + contrast: 0, + brightness: 0, + + white_balance: CAMERA_WB_AUTOMATIC, + flash_mode: CAMERA_FLASH_NONE, + exposure: CAMERA_EXPOSURE_AUTO, + min_zoom: 0, + max_zoom: 0, + max_digital_zoom: 0, + + num_image_sizes: 1, + image_formats: IMG_FMT_YUV422 +}; + +static struct camera camera_pepperpot /*__initdata*/ = { + name: "pepperpot", + type: CAMERA_CCIR_TYPE, + + mode:CAMERAMODE_SLEEP, + height: QCIF_HEIGHT, + width: QCIF_WIDTH, + capture_wait_count: 30, + + init: sva_pepperpot_init, + cleanup: sva_pepperpot_cleanup, + open: sva_pepperpot_open, + close: sva_pepperpot_close, + get_capability: sva_pepperpot_get_capability, + set_params: sva_pepperpot_set_params, + get_params: sva_pepperpot_get_params, + set_control: sva_pepperpot_set_control, + get_control: sva_pepperpot_get_control, + whitebalancemode:sva_set_pepperpot_whitebalancemode, + expandcompilectrl: sva_set_pepperpot_expalgoncmpctrl, + +}; + +static int sva_pepperpot_remove(struct platform_device *); +static int sva_pepperpot_probe(struct platform_device *); + +static struct platform_device *device; +static struct platform_driver pepperpot_driver = { + .driver = { + .name = "pepperpot", + }, + .probe = sva_pepperpot_probe, + .remove = sva_pepperpot_remove +}; + +static int /*__init*/ sva_pepperpot_init(void) +{ + int err; + dbgprintk(1," Entered %s():\n",__FUNCTION__); + + pp_info = &camera_pepperpot; + pp_info->mode = CAMERAMODE_SLEEP; + pp_info->height = QCIF_HEIGHT; + pp_info->width = QCIF_WIDTH; + pp_info->frequency = 0xD0; + pp_info->frame_rate = 30; +#if 0 +/*This platform specific settings are done in arch/arm/mach-nomadik/ndk10_devices.c + *the proper callback need to be implimented to support multiboard + */ +#if defined(CONFIG_NOMADIK_NDK10) + nomadik_epio_write_cob_ctl(nomadik_epio_read_cob_ctl() | CAM_SHDNnot | CAM_RSTnot); + err=0; + while (err<0xffffff) err++; + nomadik_epio_write_exp_ctrl(nomadik_epio_read_exp_ctrl() | 0x1000); + err=0; + while (err<0xffffff) err++; +#endif +#endif + device = platform_device_register_simple("pepperpot", -1 , NULL, 0); + if (IS_ERR(device)) { + return PTR_ERR(device); + } + + if ((err = platform_driver_register(&pepperpot_driver)) < 0) { + platform_device_unregister(device); + } + + dbgprintk(1," Exiting %s():\n",__FUNCTION__); + return err; +} + +static int sva_pepperpot_probe(struct platform_device *dev) +{ + __u8 firmwareversion,data; + int i,n; + int ret_val = 0; + const struct firmware *firmware=NULL; + + dbgprintk(1," Entered %s():\n",__FUNCTION__); + + if(camera_register_device(&camera_pepperpot) != 0) { + dbgprintk(3,"Couldn't register the camera module\n"); + ret_val = -EAGAIN; + goto out; + } + + ret_val=sva_set_pepperpot_mode(CAMERAMODE_SLEEP); + if(ret_val<0) + { + dbgprintk(3,"Error in function sva_set_pepperpot_mode \n"); + ret_val = -EAGAIN; + goto out; + } + + ret_val=nomadik_i2c_read_register(I2C_PP_CAM_CLIENT,&firmwareversion, + NMDK_PEPPERPOT_REG0_FIRMWAREVERSION,1); + if(ret_val<0) + { + dbgprintk(3,"nomadik_i2c_read_register() failed: \ + getting the firmware ROM version %d\n",ret_val); + ret_val = -EAGAIN; + goto out; + } + dbgprintk(1,"The firmware version is 0x%x\n",firmwareversion); + + if(firmwareversion == 0x14) + { + char *buffer_addr = NULL; + char *buffer_data = NULL; + + ret_val = request_firmware(&firmware, "pepperpot_address.bin", &device->dev); + if(ret_val) { + dbgprintk(3,"error:Loading firmware pepperpot_address.bin,error %d\n" + ,ret_val); + ret_val = -EAGAIN; + goto out; + } + + buffer_addr = vmalloc(firmware->size); + if(!buffer_addr) { + dbgprintk(3,"error: vmalloc() failed for address buffer\n"); + release_firmware(firmware); + ret_val = -ENOMEM; + goto out; + } + + memcpy(buffer_addr, firmware->data, firmware->size); + release_firmware(firmware); + + ret_val = request_firmware(&firmware, "pepperpot_data.bin", &device->dev); + if(ret_val) { + dbgprintk(3,"error:Loading firmware pepperpot_data.bin,error %d\n" + ,ret_val); + vfree(buffer_addr); + ret_val = -EAGAIN; + goto out; + } + + buffer_data = vmalloc(firmware->size); + if(!buffer_data) { + dbgprintk(3,"error: vmalloc() failed for data buffer\n"); + vfree(buffer_addr); + release_firmware(firmware); + ret_val = -ENOMEM; + goto out; + } + + n = firmware->size; + memcpy(buffer_data, firmware->data, firmware->size); + release_firmware(firmware); + + dbgprintk(1,"Total element=%d\n",n); + for(i=0; iframe.width); + if(retval<0) + { + dbgprintk(3,"setting the still n live image size failed\n"); + return -EINVAL; + } + + retval=sva_set_pepperpot_imageformat(conf->format); + if(retval<0) + { + dbgprintk(3,"setting the still n live format failed\n"); + return -EINVAL; + } + + /*setting the frame rate*/ + if(conf->frame_rate>=30) + conf->frame_rate = 30; + retval=sva_set_pepperpot_framerate(conf->frame_rate); + if(retval<0) + { + dbgprintk(3,"setting the still n live frame rate failed\n"); + return -EINVAL; + } + + retval=sva_set_pepperpot_clockfreq(&conf->frequency); + if(retval<0) + { + dbgprintk(3,"setting the still n live frequency failed\n"); + return -EINVAL; + } + + dbgprintk(1,"Exiting sva_pepperpot_set_params\n"); + + return 0; +} + +/* implement more error checking */ +static int sva_pepperpot_get_params (struct camera_configuration *conf) +{ + sva_get_pepperpot_imagesize(); + conf->frame.width = pp_info->width; + conf->frame.height = pp_info->height; + conf->format=sva_get_pepperpot_imageformat(); + conf->frame_rate = sva_get_pepperpot_framerate(); + sva_get_pepperpot_clockfreq(&conf->frequency); + + return 0; +} + +module_init(sva_pepperpot_init); +module_exit(sva_pepperpot_cleanup); +MODULE_LICENSE ("GPL"); +MODULE_AUTHOR ("Melwyn LOBO "); + + --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_pepperpot.h @@ -0,0 +1,153 @@ +/*--------------------------------------------------------------------------------------------------*/ +/*© copyright STMicroelectronics, 2007. */ +/* */ +/*This program is free software; you can redistribute it and/or modify it under */ +/*the terms of the GNU General Public License as published by the Free */ +/*Software Foundation; either version 2.1 of the License, or (at your option) */ +/*any later version. */ +/* */ +/*This program is distributed in the hope that it will be useful, but WITHOUT */ +/*ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU General Public License for more details. */ +/* */ +/*You should have received a copy of the GNU General Public License */ +/*along with this program. If not, see . */ +/*--------------------------------------------------------------------------------------------------*/ + + + + + + +#ifndef __SVA_PEPPERPOT_H__ +#define __SVA_PEPPERPOT_H__ + +#include "nomadik_camera.h" +#include + +/* Register Group 0 */ +#define NMDK_PEPPERPOT_REG0_SENSORIDMSB 0xa000 +#define NMDK_PEPPERPOT_REG0_SENSORIDLSB 0xa001 +#define NMDK_PEPPERPOT_REG0_FIRMWAREVERSION 0xa002 +#define NMDK_PEPPERPOT_REG0_EXTERNALCLKMSB 0xa004 +#define NMDK_PEPPERPOT_REG0_EXTERNALCLKLSB 0xa005 +#define NMDK_PEPPERPOT_REG0_SENSORCLKDERATE 0xa006 +#define NMDK_PEPPERPOT_REG0_MODESTATUS 0xa007 +#define NMDK_PEPPERPOT_REG0_MODECONTROL 0xa008 +#define NMDK_PEPPERPOT_REG0_STATUSREGISTER 0xa009 +#define NMDK_PEPPERPOT_REG0_IOPROTOCOL 0xa00a +#define NMDK_PEPPERPOT_REG0_DAMPERINHIBIT 0x8051 +#define NMDK_PEPPERPOT_REG0_DAMPERTYPE 0x8052 +#define NMDK_PEPPERPOT_REG0_EXPALGCOMCTRL 0x8001 + +/* Register Group 1 */ +#define NMDK_PEPPERPOT_REG1_LIVEFRAMERATE 0xa100 +#define NMDK_PEPPERPOT_REG1_LIVEIMGSIZE 0xa101 +#define NMDK_PEPPERPOT_REG1_LIVEIMGOUTPUTFORMAT 0xa102 +#define NMDK_PEPPERPOT_REG1_STILLTRANSFERMODE 0xa103 +#define NMDK_PEPPERPOT_REG1_DELAYTRANSFERMODE 0xa104 +#define NMDK_PEPPERPOT_REG1_VIEWFINDERFRAMERATE 0xa105 +#define NMDK_PEPPERPOT_REG1_VIEWFINDERIMGSIZE 0xa106 +#define NMDK_PEPPERPOT_REG1_VIEWFINDERIMGFORMAT 0xa107 + +/* Register Group 2 */ +#define NMDK_PEPPERPOT_REG2_ANTIVIGNETTINGCORRECTION 0xa200 +#define NMDK_PEPPERPOT_REG2_DEFCORCONTROL 0xa201 +#define NMDK_PEPPERPOT_REG2_NORACONTROL 0xa202 +#define NMDK_PEPPERPOT_REG2_MIRROR 0xa203 +#define NMDK_PEPPERPOT_REG2_SHARPNESSGAIN 0xa204 +#define NMDK_PEPPERPOT_REG2_SHARPNESSENABLE 0xa205 +#define NMDK_PEPPERPOT_REG2_JPEGCONTROL 0xa206 + +/* Register Group 3 */ +#define NMDK_PEPPERPOT_REG3_LIVEGAMMASTDGAIN 0xa300 +#define NMDK_PEPPERPOT_REG3_LIVESCURVEGAIN 0xa301 +#define NMDK_PEPPERPOT_REG3_LIVEGAMMAMISC 0xa302 +#define NMDK_PEPPERPOT_REG3_VIEWFINDERGAMMASTDGAIN 0xa303 +#define NMDK_PEPPERPOT_REG3_VIEWFINDERGAMMASCURVEGAIN 0xa304 +#define NMDK_PEPPERPOT_REG3_VIEWFINDERGAMMAMISC 0xa305 +#define NMDK_PEPPERPOT_REG3_YCBCRRANGE 0xa306 +#define NMDK_PEPPERPOT_REG3_YCBCRCEILING 0xa307 +#define NMDK_PEPPERPOT_REG3_YCBCRFLOOR 0xa308 +#define NMDK_PEPPERPOT_REG3_YCBCRSATURATION 0xa309 + +/* Register Group 4 */ +#define NMDK_PEPPERPOT_REG4_WHITEBALANCEMODE 0xa500 +#define NMDK_PEPPERPOT_REG4_WHITEBALANCERED 0xa501 +#define NMDK_PEPPERPOT_REG4_WHITEBALANCEGREEN 0xa502 +#define NMDK_PEPPERPOT_REG4_WHITEBALANCEBLUE 0xa503 + +/* Register Group 5 */ +#define NMDK_PEPPERPOT_REG5_ACFREQUENCY 0xa400 +#define NMDK_PEPPERPOT_REG5_EXPOSUREWEIGHTING 0xa401 +#define NMDK_PEPPERPOT_REG5_EXPOSURECOMPENSATION 0xa402 + +/* Hardware error codes as returned by the camera device hardware */ +#define NMDK_PEPPERPOT_STATUSREG_ERRORNONE 0x00 +#define NMDK_PEPPERPOT_STATUSREG_ERRORSENSORCOMM 0x21 +#define NMDK_PEPPERPOT_STATUSREG_ERROR_SENSORNOTAVAIL 0x22 +#define NMDK_PEPPERPOT_STATUSREG_ERROR_SENSORINVALID 0x23 +#define NMDK_PEPPERPOT_STATUSREG_ERROR_SERIALTXFIFOOVERLOW 0x31 +#define NMDK_PEPPERPOT_STATUSREG_ERROR_JPEGOVERFLOW 0x41 +#define NMDK_PEPPERPOT_STATUSREG_ERRORTIMEOUT 0x51 + +/* Codes of available types of protocols for picture output */ +#define NMDK_PEPPERPOT_IOPROTOCOL_SYNCI2CEMB 0x02 +#define NMDK_PEPPERPOT_IOPROTOCOL_SYNCI2CEX 0x03 +#define NMDK_PEPPERPOT_IOPROTOCOL_PARALLELINTERFACE 0x04 +#define NMDK_PEPPERPOT_IOPROTOCOL_PCI 0x05 +#define NMDK_PEPPERPOT_IOPROTOCOL_VISIONLINK 0x10 +/* confirm this value */ +#define NMDK_PEPPERPOT_IOPROTOCOL_CCP 0x20 +#define NMDK_PEPPERPOT_IOPROTOCOL_COLORBARS 0x40 +#define NMDK_PEPPERPOT_IOPROTOCOL_CCIR656 0x12 + +/* Codes of camera device operating modes */ +#define NMDK_PEPPERPOT_CAMERAMODE_SLEEP 0x00 +#define NMDK_PEPPERPOT_CAMERAMODE_IDLE 0x01 +#define NMDK_PEPPERPOT_CAMERAMODE_VIEWFINDER 0x02 +#define NMDK_PEPPERPOT_CAMERAMODE_CAPTURE 0x03 +#define NMDK_PEPPERPOT_CAMERAMODE_LIVE 0x04 +#define NMDK_PEPPERPOT_CAMERAMODE_RESERVED 0x05 +#define NMDK_PEPPERPOT_CAMERAMODE_FLASH 0x06 +/* #define NMDK_PEPPERPOT_CAMERAMODE_RESERVED 0x07 */ +#define NMDK_PEPPERPOT_CAMERAMODE_BOOTING 0x15 + +/* Codes of predefined image sizes */ +#define NMDK_PEPPERPOT_CAMERAIMGSIZE_VGA 0x0 +#define NMDK_PEPPERPOT_CAMERAIMGSIZE_CIF 0x1 +#define NMDK_PEPPERPOT_CAMERAIMGSIZE_QVGA 0x2 +#define NMDK_PEPPERPOT_CAMERAIMGSIZE_QCIF 0x3 +#define NMDK_PEPPERPOT_CAMERAIMGSIZE_QQVGA 0x4 +#define NMDK_PEPPERPOT_CAMERAIMGSIZE_SUBQCIF 0x5 +#define NMDK_PEPPERPOT_CAMERAIMGSIZE_QQCIF 0x6 +#define NMDK_PEPPERPOT_CAMERAIMGSIZE_CUSTOM 0x7 + +/* Codes of supported image bitmap formats */ +#define NMDK_PEPPERPOT_IMG_FMT_RGB332 0x00 +#define NMDK_PEPPERPOT_IMG_FMT_RGB444 0x01 +#define NMDK_PEPPERPOT_IMG_FMT_RGB565 0x02 +#define NMDK_PEPPERPOT_IMG_FMT_YUV422 0x03 +#define NMDK_PEPPERPOT_IMG_FMT_JPEG 0x04 + +#define DECIMAL_BITS_SHIFT 11 +#define MASK_INTEGER_BITS (unsigned short)(~0UL << DECIMAL_BITS_SHIFT) +#define MASK_DECIMAL_BITS (unsigned short)~MASK_INTEGER_BITS + +#define PEPPER_I2C_ADDR 0x08 + + + static int sva_pepperpot_init (void); + static void sva_pepperpot_cleanup (void); + static int sva_pepperpot_open (void); + static int sva_pepperpot_close (void); + static int sva_pepperpot_get_capability (struct camera_capability *cap); + static int sva_pepperpot_set_params (struct camera_configuration *); + static int sva_pepperpot_get_params (struct camera_configuration *); + static int sva_pepperpot_set_control (struct camera_control *); + static int sva_pepperpot_get_control (struct camera_control *); + static int sva_set_pepperpot_expalgoncmpctrl(__u8 size); + static int sva_set_pepperpot_whitebalancemode(__u8); + +#endif --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva.c @@ -0,0 +1,4951 @@ +/*--------------------------------------------------------------------------------------------------*/ +/*© copyright STMicroelectronics, 2007. */ +/* */ +/*This program is free software; you can redistribute it and/or modify it under */ +/*the terms of the GNU General Public License as published by the Free */ +/*Software Foundation; either version 2.1 of the License, or (at your option) */ +/*any later version. */ +/* */ +/*This program is distributed in the hope that it will be useful, but WITHOUT */ +/*ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU General Public License for more details. */ +/* */ +/*You should have received a copy of the GNU General Public License */ +/*along with this program. If not, see . */ +/*--------------------------------------------------------------------------------------------------*/ + + + + + + +#include "nomadik_sva.h" +#include "nomadik_sva_services.h" +#include +#include +#include +#include + +#include "nomadik_sva_vpip.h" + +void sva_ogl_suspend(void); +void sva_ogl_resume(void); + +#define SVA_DEFAULT_LOG_LEVEL 4 + +int sva_debug = SVA_DEFAULT_LOG_LEVEL; +module_param(sva_debug, int, 0644); +MODULE_PARM_DESC(sva_debug,"Debug level for messages"); +#define dbgprintk(num, format, args...) \ + do { \ + if(num >= sva_debug ) \ + printk("SVA:"format, ##args); \ + } while(0) + +int set_video_decoder_config(struct sva_service_open *srv_open, struct sva_service_struct *srv); +int set_video_encoder_config(struct sva_service_open *srv_open, struct sva_service_struct *srv); +void * sva_q_yank_bufferid(struct sva_queue *q, t_sva_buffer_id bufid); +static int init_done=0; + +#define DC_HUFF_TABLE_SIZE 12 +#define AC_HUFF_TABLE_SIZE 256 +#define QUANT_TABLE_SIZE 64 + +#ifdef CONFIG_NOMADIK_SVA_VPIP +int vpip_irp_enable=1; +#else +int vpip_irp_enable=1; +#endif + +static u8 no_of_postprocessor=0; +struct sva_device sva; +EXPORT_SYMBOL(sva); +/*static*/ struct semaphore hcl_mutex; +extern struct tasklet_struct sva_tasklet; +static const char *firmware_name[][2]= + { +#ifdef CONFIG_NOMADIK_NDK10 + { + "sva_mpeg4_decoder.mmf", + "sva_mpeg4_decoder.inf" + }, + { + "sva_mpeg4_encoder.mmf", + "sva_mpeg4_encoder.inf" + }, + { + "sva_mpeg4_encoder_vbr.mmf", + "sva_mpeg4_encoder_vbr.inf" + }, + { + "sva_mpeg4_encoder_cbr.mmf", + "sva_mpeg4_encoder_cbr.inf" + } +#elif defined CONFIG_NOMADIK_NDK15 || CONFIG_NOMADIK_NHK15 + { + "sva_vc1_decoder.mmf", + "sva_vc1_decoder.inf" + }, + { + "sva_h264_decoder.mmf", + "sva_h264_decoder.inf" + }, + { + "sva_config5.mmf", + "sva_config5.inf" + }, + { + "sva_config1.mmf", + "sva_config1.inf" + }, + { + "sva_mpeg2_decoder.mmf", + "sva_mpeg2_decoder.inf" + }, + { + "sva_config7.mmf", + "sva_config7.inf" + } + +#else + #error "Unsupported board" +#endif + + }; + +#define MAX_FIRMWARE sizeof(firmware_name)/sizeof(firmware_name[0]) +char *fw_inf_buf[MAX_FIRMWARE]; + +static void +set_postprocessor_config(struct sva_service_open *srv_open, struct sva_service_struct *srv) +{ + t_sva_postprocessor_configuration *pconf; + struct clcd_fb *fb; + struct sva_postprocessor_configuration *conf; + + fb = sva.sva_platform_data->get_paneltype(); + conf = &srv->config.postprocessor_configuration; + pconf = &srv_open->config.postprocessor_info.configuration; + + pconf->transformId = conf->capability; + pconf->isDirectScreenAccess=conf->direct_display; + pconf->isDoubleBufferMode=FALSE; + + pconf->screenFrameBufferBaseAddr=(t_physical_address) readl(fb->regs + CLCD_UBAS); + pconf->screenAlternateFrameBufferBaseAddr = NULL; + + if(conf->direct_display) { + pconf->videoFrameBufferDesc.frame.height = fb->panel->mode.yres; + pconf->videoFrameBufferDesc.frame.width = fb->panel->mode.xres; + } else { + pconf->videoFrameBufferDesc.frame.height = conf->display_window.frame.height; + pconf->videoFrameBufferDesc.frame.width = conf->display_window.frame.width; + } + + pconf->videoFrameBufferDesc.window.image.height = conf->display_window.frame.height; + pconf->videoFrameBufferDesc.window.image.width = conf->display_window.frame.width; + pconf->videoFrameBufferDesc.window.imageOffset.offsetX = conf->display_window.offset.x_offset; + pconf->videoFrameBufferDesc.window.imageOffset.offsetY = conf->display_window.offset.y_offset; + + pconf->bitsPerPixel=conf->depth; + + /* source frame */ + pconf->sourceFrameDesc.frame.height=conf->source_frame.height; + pconf->sourceFrameDesc.frame.width=conf->source_frame.width; + pconf->sourceFrameDesc.window.image.height=conf->cropped_window.frame.height; + pconf->sourceFrameDesc.window.image.width=conf->cropped_window.frame.width; + pconf->sourceFrameDesc.window.imageOffset.offsetX=conf->cropped_window.offset.x_offset; + pconf->sourceFrameDesc.window.imageOffset.offsetY=conf->cropped_window.offset.y_offset; + + /* resized */ + pconf->resizedImageDesc.height=conf->resized_frame.height; + pconf->resizedImageDesc.width=conf->resized_frame.width; + + /* clipped */ + pconf->clippedWindowDesc.image.height=conf->clipped_window.frame.height; + pconf->clippedWindowDesc.image.width=conf->clipped_window.frame.width; + pconf->clippedWindowDesc.imageOffset.offsetX=conf->clipped_window.offset.x_offset; + pconf->clippedWindowDesc.imageOffset.offsetY=conf->clipped_window.offset.y_offset; + + pconf->displaySyncLine = 1023; + + pconf->colorMatrix.matrix_coef1 = conf->matrix.matrix_coef1; + pconf->colorMatrix.matrix_coef2 = conf->matrix.matrix_coef2; + pconf->colorMatrix.matrix_coef3 = conf->matrix.matrix_coef3; + pconf->colorMatrix.matrix_coef4 = conf->matrix.matrix_coef4; + + /*full range output*/ + pconf->outputRange = conf->output_range; + + /* is ace enable */ + pconf->aceMode = conf->ace_mode; + pconf->aceStrength = conf->ace_strength; + pconf->aceRange = conf->ace_range; + + pconf->mirrorMode=conf->mirroring; + pconf->rotationMode=conf->rotation; + pconf->contrast=conf->contrast; + pconf->brightness=conf->brightness; + pconf->isDithering=conf->dithering; + pconf->deblockingFilterMode=conf->deblocking_filter; + pconf->deringingFilterMode=conf->deringing_filter; + pconf->chromaSamplingFormat=conf->chroma_sampling; + pconf->alphaKey=conf->alpha_key; + pconf->redBlueSwap=conf->red_blue_swap; + if(conf->direct_display) + pconf->syncMode=SVA_POSTPROCESSOR_EXT_DISPLAY_SYNC; + else + pconf->syncMode=SVA_POSPROCESSOR_NO_EXT_SYNC; + +/* if(conf->capability == 5) + pconf->raster_in_format = 1; */ + + + pconf->raster_in_format= conf->raster_in_format; + +} + +static void +set_tvout_config(struct sva_service_open *srv_open, struct sva_service_struct *srv) +{ + t_sva_tvo_configuration *pconf; + struct sva_tvout_configuration *conf; + t_sva_tvo_config_output config_pal_output = TVO_STD_625_LINES_CONFIG; + t_sva_tvo_config_output config_ntsc_output = TVO_STD_525_LINES_CONFIG; + + pconf = &srv_open->config.tvout_info.configuration; + conf = &srv->config.tvout_configuration; + + pconf->sourceFrameDesc.frame.height=conf->source_frame_window.frame.height; + pconf->sourceFrameDesc.frame.width=conf->source_frame_window.frame.width; + pconf->sourceFrameDesc.window.image.height=conf->source_frame_window.window.frame.height; + pconf->sourceFrameDesc.window.image.width=conf->source_frame_window.window.frame.width; + pconf->sourceFrameDesc.window.imageOffset.offsetX=conf->source_frame_window.window.offset.x_offset; + pconf->sourceFrameDesc.window.imageOffset.offsetY=conf->source_frame_window.window.offset.y_offset; + pconf->destinationWindowOffsetDesc.offsetX=conf->destination_window_offset.x_offset; + pconf->destinationWindowOffsetDesc.offsetY=conf->destination_window_offset.y_offset; + pconf->backgroundColor.Y=conf->background_yuv_color.Y; + pconf->backgroundColor.U=conf->background_yuv_color.U; + pconf->backgroundColor.V=conf->background_yuv_color.V; + pconf->clockMode=SVA_TVO_INTERNAL_CLOCK_FALLING_EDGE; + + if(conf->tvo_type == TVO_PAL) { + srv_open->config.tvout_info.type = DENC_MODE_PAL; + dbgprintk(1,"Setting PAL\n"); + pconf->configOutput = config_pal_output; + } else { + srv_open->config.tvout_info.type = DENC_MODE_NTSC; + dbgprintk(1,"Setting NTSC\n"); + pconf->configOutput = config_ntsc_output; + } +} +void print_jpeg_configuration(struct sva_service_open *srv_open) +{ + t_sva_still_decoder_configuration *pconf; + t_sva_still_algo_jpeg_decoder_configuration_params *jpeg_algo_params; + + pconf = &srv_open->config.stillimagedecoder_info.configuration; + jpeg_algo_params = (t_sva_still_algo_jpeg_decoder_configuration_params *)pconf->pAlgoConfig; + + dbgprintk(2,"\n=============================================================\n"); + dbgprintk(2,"JPEG DECODER CONF::transformId = %d \n",pconf->transformId ); + dbgprintk(2,"JPEG DECODER CONF::mode = %d \n",pconf->mode ); + dbgprintk(2,"JPEG DECODER CONF::decodedFrameDesc.height = %d \n",pconf->decodedFrameDesc.height ); + dbgprintk(2,"JPEG DECODER CONF::decodedFrameDesc.width = %d \n",pconf->decodedFrameDesc.width ); + dbgprintk(2,"JPEG DECODER CONF::crop_window.image.height = %d \n",pconf->crop_window.image.height); + dbgprintk(2,"JPEG DECODER CONF::crop_window.image.width = %d \n",pconf->crop_window.image.width); + dbgprintk(2,"JPEG DECODER CONF::crop_window.imageOffset.offsetX = %d \n",pconf->crop_window.imageOffset.offsetX); + dbgprintk(2,"JPEG DECODER CONF::crop_window.imageOffset.offsetY = %d \n",pconf->crop_window.imageOffset.offsetY); + dbgprintk(2,"JPEG DECODER CONF::aceStrength = %d \n",pconf->aceStrength ); + dbgprintk(2,"JPEG DECODER CONF::is_cropping_enabled = %d \n",pconf->is_cropping_enabled ); + dbgprintk(2,"JPEG DECODER CONF::no_slice_mode = %d \n",pconf->no_slice_mode ); + + dbgprintk(2,"JPEG DECODER CONF(ALGO_PARAMS)::colorMode = %d \n",jpeg_algo_params->colorMode ); + dbgprintk(2,"JPEG DECODER CONF(ALGO_PARAMS)::downsamplingFactor = %d \n",jpeg_algo_params->downsamplingFactor ); + dbgprintk(2,"JPEG DECODER CONF(ALGO_PARAMS)::samplingFactor.h_sampling_factor_y = %d \n",jpeg_algo_params->samplingFactor.hSamplingFactorY ); + dbgprintk(2,"JPEG DECODER CONF(ALGO_PARAMS)::samplingFactor.v_sampling_factor_y = %d \n",jpeg_algo_params->samplingFactor.vSamplingFactorY ); + dbgprintk(2,"JPEG DECODER CONF(ALGO_PARAMS)::samplingFactor.h_sampling_factor_cb = %d \n",jpeg_algo_params->samplingFactor.hSamplingFactorCb ); + dbgprintk(2,"JPEG DECODER CONF(ALGO_PARAMS)::samplingFactor.v_sampling_factor_cb = %d \n",jpeg_algo_params->samplingFactor.vSamplingFactorCb ); + dbgprintk(2,"JPEG DECODER CONF(ALGO_PARAMS)::samplingFactor.h_sampling_factor_cr = %d \n",jpeg_algo_params->samplingFactor.hSamplingFactorCr ); + dbgprintk(2,"JPEG DECODER CONF(ALGO_PARAMS)::samplingFactor.v_sampling_factor_cr = %d \n",jpeg_algo_params->samplingFactor.vSamplingFactorCr ); + dbgprintk(2,"\n=============================================================\n"); +} + + +static int +set_still_image_decoder_config(struct sva_service_open *srv_open, struct sva_service_struct *srv) +{ + t_sva_still_algo_jpeg_decoder_configuration_params *jpeg_algo_hcl_params; + struct jpeg_algo_params *algo_params; + + t_sva_still_decoder_configuration *pconf; + struct sva_stillimagedecoder_configuration *conf; + + + pconf = &srv_open->config.stillimagedecoder_info.configuration; + conf = &srv->config.stillimagedecoder_configuration; + + pconf->transformId = conf->capability; + pconf->mode = conf->mode; + pconf->decodedFrameDesc.height = conf->decoded_frame_desc.height; + pconf->decodedFrameDesc.width = conf->decoded_frame_desc.width; + pconf->crop_window.image.height=conf->crop_window.frame.height; + pconf->crop_window.image.width=conf->crop_window.frame.width; + pconf->crop_window.imageOffset.offsetX=conf->crop_window.offset.x_offset; + pconf->crop_window.imageOffset.offsetY=conf->crop_window.offset.y_offset; + pconf->aceStrength = conf->ace_strength; + pconf->is_cropping_enabled = conf->is_cropping_enabled; + pconf->no_slice_mode = conf->no_slice_mode; + + pconf->pAlgoConfig = kzalloc(sizeof(t_sva_still_algo_jpeg_decoder_configuration_params), GFP_KERNEL); + + if(!pconf->pAlgoConfig){ + dbgprintk(3,"set_still_image_decoder_config:: Cannot Allocate memory\n"); + return -1; + } + + jpeg_algo_hcl_params = (t_sva_still_algo_jpeg_decoder_configuration_params *)pconf->pAlgoConfig; + + algo_params = (struct jpeg_algo_params *)conf->sva_still_algo_configuration_params; + + jpeg_algo_hcl_params->colorMode = algo_params->color_mode ; + jpeg_algo_hcl_params->downsamplingFactor = algo_params->downsampling_factor ; + jpeg_algo_hcl_params->samplingFactor.hSamplingFactorY = algo_params->sampling_factor.h_sampling_factor_y ; + jpeg_algo_hcl_params->samplingFactor.vSamplingFactorY = algo_params->sampling_factor.v_sampling_factor_y ; + jpeg_algo_hcl_params->samplingFactor.hSamplingFactorCb = algo_params->sampling_factor.h_sampling_factor_cb ; + jpeg_algo_hcl_params->samplingFactor.vSamplingFactorCb = algo_params->sampling_factor.v_sampling_factor_cb ; + jpeg_algo_hcl_params->samplingFactor.hSamplingFactorCr = algo_params->sampling_factor.h_sampling_factor_cr ; + jpeg_algo_hcl_params->samplingFactor.vSamplingFactorCr = algo_params->sampling_factor.v_sampling_factor_cr ; + + return 0; +} + +static int +set_still_image_encoder_config(struct sva_service_open *srv_open, struct sva_service_struct *srv) +{ + t_sva_still_algo_jpeg_configuration_params *jpeg_algo_hcl_params; + struct jpeg_encoder_algo_params * algo_params; + + t_sva_still_encoder_configuration *pconf; + struct sva_stillimageencoder_configuration *conf; + int i = 0; + + pconf = &srv_open->config.stillimageencoder_info.configuration; + conf = &srv->config.stillimageencoder_configuration; + + pconf->transformId = conf->capability; + pconf->mode = conf->mode; + pconf->isSliceMode = conf->is_slice_mode; + pconf->thumbnailMode = conf->thumbnail_mode; + pconf->sourceFrameDesc.frame.height=conf->source_frame_desc.frame.height; + pconf->sourceFrameDesc.frame.width=conf->source_frame_desc.frame.width; + pconf->sourceFrameDesc.window.image.height=conf->source_frame_desc.window.frame.height; + pconf->sourceFrameDesc.window.image.width=conf->source_frame_desc.window.frame.width; + pconf->sourceFrameDesc.window.imageOffset.offsetX=conf->source_frame_desc.window.offset.x_offset; + pconf->sourceFrameDesc.window.imageOffset.offsetY=conf->source_frame_desc.window.offset.y_offset; + pconf->raster_in_format = conf->raster_in_format; + + pconf->pAlgoConfig = kzalloc(sizeof(t_sva_still_algo_jpeg_configuration_params), GFP_KERNEL); + if(!pconf->pAlgoConfig){ + dbgprintk(3,"set_still_image_encoder_config:: Cannot Allocate memory\n"); + return -1; + } + + jpeg_algo_hcl_params = (t_sva_still_algo_jpeg_configuration_params *)pconf->pAlgoConfig; + + algo_params = (struct jpeg_encoder_algo_params *)conf->sva_still_algo_configuration_params; + + jpeg_algo_hcl_params->restartInterval = algo_params->restartInterval; + jpeg_algo_hcl_params->isOptimizeQuantTableEnable = algo_params->isOptimizeQuantTableEnable; + jpeg_algo_hcl_params->isOptimizeHuffmanTableEnable = algo_params->isOptimizeHuffmanTableEnable; + jpeg_algo_hcl_params->targetBpp = algo_params->targetBpp; + jpeg_algo_hcl_params->rotation = algo_params->rotation; + + for(i=0; i<64; i++){ + jpeg_algo_hcl_params->quantizationTable.quant_y[i] = algo_params->quantizationTable.quant_y[i]; + jpeg_algo_hcl_params->quantizationTable.quant_cb[i] = algo_params->quantizationTable.quant_cb[i]; + jpeg_algo_hcl_params->quantizationTable.quant_cr[i] = algo_params->quantizationTable.quant_cr[i]; + } + + for(i=0; i<12; i++){ + jpeg_algo_hcl_params->huffmanTable.huffmanYCodeDc[i] = algo_params->huffmanTable.huffmanYCodeDc[i]; + jpeg_algo_hcl_params->huffmanTable.huffmanYSizeDc[i] = algo_params->huffmanTable.huffmanYSizeDc[i] ; + jpeg_algo_hcl_params->huffmanTable.huffmanCbCodeDc[i] = algo_params->huffmanTable.huffmanCbCodeDc[i]; + jpeg_algo_hcl_params->huffmanTable.huffmanCbSizeDc[i] = algo_params->huffmanTable.huffmanCbSizeDc[i]; + jpeg_algo_hcl_params->huffmanTable.huffmanCrCodeDc[i] = algo_params->huffmanTable.huffmanCrCodeDc[i]; + jpeg_algo_hcl_params->huffmanTable.huffmanCrSizeDc[i] = algo_params->huffmanTable.huffmanCrSizeDc[i]; + } + + for(i=0; i<256; i++){ + jpeg_algo_hcl_params->huffmanTable.huffmanYCodeAc[i] = algo_params->huffmanTable.huffmanYCodeAc[i]; + jpeg_algo_hcl_params->huffmanTable.huffmanYSizeAc[i] = algo_params->huffmanTable.huffmanYSizeAc[i]; + jpeg_algo_hcl_params->huffmanTable.huffmanCbCodeAc[i] = algo_params->huffmanTable.huffmanCbCodeAc[i]; + jpeg_algo_hcl_params->huffmanTable.huffmanCbSizeAc[i] = algo_params->huffmanTable.huffmanCbSizeAc[i]; + jpeg_algo_hcl_params->huffmanTable.huffmanCrCodeAc[i] = algo_params->huffmanTable.huffmanCrCodeAc[i]; + jpeg_algo_hcl_params->huffmanTable.huffmanCrSizeAc[i] = algo_params->huffmanTable.huffmanCrSizeAc[i]; + } + return 0; +} + + +static void +set_preprocessor_config(struct sva_service_open *srv_open, struct sva_service_struct *srv) +{ + t_sva_preprocessor_configuration *pconf; + struct sva_preprocessor_configuration *conf; + pconf = &srv_open->config.preprocessor_info.configuration; + conf = &srv->config.preprocessor_configuration; + + pconf->transformId=conf->capability; + + pconf->sourceFrameDesc.frame.height=conf->source_frame.height; + pconf->sourceFrameDesc.frame.width=conf->source_frame.width; + pconf->sourceFrameDesc.window.image.height=conf->cropped_window.frame.height; + pconf->sourceFrameDesc.window.image.width=conf->cropped_window.frame.width; + pconf->sourceFrameDesc.window.imageOffset.offsetX=conf->cropped_window.offset.x_offset; + pconf->sourceFrameDesc.window.imageOffset.offsetY=conf->cropped_window.offset.y_offset; + pconf->resizedWindowDesc.height=conf->resized_frame.height; + pconf->resizedWindowDesc.width=conf->resized_frame.width; + + /*interface settings*/ + #ifdef __STN_8815 + pconf->interfaceCConfiguration=SVA_PREPROCESSOR_CCIR656_INTERFACE_FALLING_EDGE; + #else + pconf->interfaceCConfiguration=SVA_PREPROCESSOR_CCIR656_INTERFACE_RISING_EDGE; + #endif + pconf->interfaceSyncMode=SVA_PREPROCESSOR_SYNC_EMBEDDED_CODES; + + pconf->isInputInterlaced=FALSE; + pconf->isOutputFrame=TRUE; + pconf->rawBpp=SVA_PREPROCESSOR_RAW_8BPP; + pconf->grabSyncLine=0; + + pconf->isAceEnable=conf->ace_enable; + pconf->aceStrength=conf->ace_strength; + pconf->aceRange=conf->ace_range; + pconf->outputRange=conf->output_range; + + /** SVA 8.0.0 migration */ + pconf->grabhqConfig.isChannelOffsetEnabled=0; + pconf->grabhqConfig.isGridironEnabled=0; + pconf->grabhqConfig.isScorpioEnabled=0; + + +#if 0 + if(conf->capability== SENSOR_HIGHQUALITY_YUV420_MB){ + printk("VP: configuring HighQuality parameters \n"); + pconf->cast_day = 1054146036; + pconf->cast_cool = 1051428127; + pconf->cast_inc = 1048877990; + pconf->cast_horizon = 1046495625; + pconf->gridhsize = 60; + pconf->isChannelOffsetEnabled =0; // channel offset off + pconf->isGridironEnabled = 0; // gridiron off + pconf->isScorpioEnabled = 0; // scorpio off + pconf->scorpioStrength = 0; // scorpio strength (linked to coring) + } +#endif + srv_open->config.preprocessor_info.camera_framerate = conf->frame_rate; + srv_open->config.preprocessor_info.sensor_aoi_x = conf->sensor_aoi_x; + srv_open->config.preprocessor_info.sensor_aoi_y = conf->sensor_aoi_y; + srv_open->config.preprocessor_info.prescale_factor = conf->prescale_factor; + + + +} + +int delete_hcl_service(struct sva_service_open *srv_open) +{ + if(SVA_DeleteService(srv_open->service_id) != SVA_OK) { + return -EINVAL; + } else { + srv_open->service_id = MASK_ALL32; + return 0; + } + +} +EXPORT_SYMBOL(delete_hcl_service); + +void delete_service(struct sva_device_open *open, int indx) +{ + struct sva_service_open *srv_open = open->service_open_data[indx]; + + if(srv_open->in_image_buf_q) { + kfree(srv_open->in_image_buf_q); + srv_open->in_image_buf_q = NULL; + } + if(srv_open->in_infos_buf_q) { + kfree(srv_open->in_infos_buf_q); + srv_open->in_infos_buf_q = NULL; + } + if(srv_open->in_coded_buf_q) { + kfree(srv_open->in_coded_buf_q); + srv_open->in_coded_buf_q = NULL; + } + if(srv_open->in_params_buf_q) { + kfree(srv_open->in_params_buf_q); + srv_open->in_params_buf_q = NULL; + } + + if(srv_open->out_image_buf_q) { + kfree(srv_open->out_image_buf_q); + srv_open->out_image_buf_q = NULL; + } + if(srv_open->out_infos_buf_q) { + kfree(srv_open->out_infos_buf_q); + srv_open->out_infos_buf_q = NULL; + } + if(srv_open->out_coded_buf_q) { + kfree(srv_open->out_coded_buf_q); + srv_open->out_coded_buf_q = NULL; + } + if(srv_open->out_params_buf_q) { + kfree(srv_open->out_params_buf_q); + srv_open->out_params_buf_q = NULL; + } + if(srv_open->readonly_image_buf_q) { + kfree(srv_open->readonly_image_buf_q); + srv_open->readonly_image_buf_q = NULL; + } + + if(srv_open->internal_needs) { + free_pages((unsigned long)srv_open->internal_needs, + srv_open->internal_needs_size); + srv_open->internal_needs = NULL; + srv_open->internal_needs_size = 0; + } + if(srv_open->internal_ncnb_needs.logical) { + dma_free_coherent(&sva.p_dev->dev, srv_open->internal_ncnb_needs_size,(void *)srv_open->internal_ncnb_needs.logical ,(dma_addr_t )srv_open->internal_ncnb_needs.physical); + srv_open->internal_ncnb_needs.logical = NULL; + srv_open->internal_ncnb_needs.physical = NULL; + srv_open->internal_ncnb_needs_size = 0; + } + + if(srv_open->type == SVA_VIDEO_DECODER) { + if(srv_open->config.videodecoder_info.configuration.pAlgoConfig) + kfree(srv_open->config.videodecoder_info.configuration.pAlgoConfig); + + if(srv_open->config.videodecoder_info.configuration.transformId == + SVA_DECODER_H264) { + + t_sva_video_decoder_algo_h264_slice_header_infos *psheader, *tmp; + psheader = srv_open->config.videodecoder_info.h264_infos.pHeader; + while(psheader) { + tmp = psheader; + psheader = tmp->pNextHeader; + kfree(tmp); + } + } + } + + if(srv_open->type == SVA_VIDEO_ENCODER) { + if(srv_open->config.videoencoder_info.configuration.pAlgoConfig) + kfree(srv_open->config.videoencoder_info.configuration.pAlgoConfig); + + if(srv_open->config.videoencoder_info.configuration.pBrcConfig) + kfree(srv_open->config.videoencoder_info.configuration.pBrcConfig); + + } + + if(srv_open->type == SVA_STILL_IMAGE_ENCODER) { + if(srv_open->config.stillimageencoder_info.configuration.pAlgoConfig) + kfree(srv_open->config.stillimageencoder_info.configuration.pAlgoConfig); + } + + if(srv_open->type == SVA_STILL_IMAGE_DECODER) { + if(srv_open->config.stillimagedecoder_info.configuration.pAlgoConfig) + kfree(srv_open->config.stillimagedecoder_info.configuration.pAlgoConfig); + } + + if(srv_open->service_id != MASK_ALL32) { + if(delete_hcl_service(srv_open)) + dbgprintk(3,"error: Error Deleting service %d\n",indx); + } + + if(open->service_open_data[indx]) { + kfree(open->service_open_data[indx]); + open->service_open_data[indx] = NULL; + } + +} +EXPORT_SYMBOL(delete_service); + +int +configure_service(struct sva_device_open *open, struct sva_service_struct *srv) +{ + t_sva_error sva_error; + t_size need_size; + t_size size_nc_nb; /*need size, non-cacheable, non-bufferable*/ + int ret_val = -EINVAL; + __u8 indx = srv->service_id; + struct sva_service_open *srv_open = open->service_open_data[indx]; + + lock_critical_section(&hcl_mutex); + sva_error = SVA_CreateService(srv_open->type, &srv_open->service_id); + unlock_critical_section(&hcl_mutex); + if(sva_error != SVA_OK) { + srv_open->service_id = MASK_ALL32; + goto delete_service; + } + + srv_open->state &= ~SERVICE_ACTIVATED; + srv_open->state |= SERVICE_CREATED; + + switch(srv_open->type) { + + case SVA_PREPROCESSOR: + { + set_preprocessor_config(srv_open, srv); + + lock_critical_section(&hcl_mutex); + sva_error = SVA_ConfigurePreProcessor(srv_open->service_id, + &srv_open->config.preprocessor_info.configuration); + unlock_critical_section(&hcl_mutex); + if(sva_error != SVA_OK) { + dbgprintk(3,"Error setting PREPROC config %d\n",sva_error); + goto delete_service; + } + break; + + } + case SVA_POSTPROCESSOR: + { + set_postprocessor_config(srv_open, srv); + + lock_critical_section(&hcl_mutex); + sva_error = SVA_ConfigurePostProcessor(srv_open->service_id, + &srv_open->config.postprocessor_info.configuration); + unlock_critical_section(&hcl_mutex); + if(sva_error != SVA_OK) { + dbgprintk(3,"Error setting PPP config %d\n",sva_error); + goto delete_service; + } + break; + + } + + case SVA_VIDEO_DECODER: + { + if(!srv->config.videodecoder_configuration.codec_params) { + ret_val = -EINVAL; + goto delete_service; + } + + if(set_video_decoder_config(srv_open,srv)) { + dbgprintk(3,"\n\nError setting video decoder config\n"); + goto delete_service; + } + + lock_critical_section(&hcl_mutex); + sva_error = SVA_ConfigureVideoDecoder(srv_open->service_id, + &srv_open->config.videodecoder_info.configuration); + + unlock_critical_section(&hcl_mutex); + if(sva_error != SVA_OK) { + dbgprintk(3,"Error setting VDEC config %d\n",sva_error); + goto delete_service; + } + /*if(srv_open->config.videodecoder_info.configuration.transformId == SVA_DECODER_VC1_MP_LL || + srv_open->config.videodecoder_info.configuration.transformId == SVA_DECODER_H264) { + dbgprintk(1, "Initializing the readonly work queue \n"); + INIT_WORK(&srv_open->work, update_readonly_queue, &srv_open->rd_work_data); + } */ + + break; + } + + case SVA_VIDEO_ENCODER: + { + if(!srv->config.videoencoder_configuration.codec_params || + !srv->config.videoencoder_configuration.brc_config_params) { + ret_val = -EINVAL; + goto delete_service; + } + + if(set_video_encoder_config(srv_open,srv)) { + dbgprintk(3,"Error setting video encoder config\n"); + goto delete_service; + } + + lock_critical_section(&hcl_mutex); + sva_error = SVA_ConfigureVideoEncoder(srv_open->service_id, + &srv_open->config.videoencoder_info.configuration); + + unlock_critical_section(&hcl_mutex); + if(sva_error != SVA_OK) { + dbgprintk(3,"Error setting VENC config %d\n",sva_error); + goto delete_service; + } + + break; + } + case SVA_STILL_IMAGE_DECODER: + { + if(set_still_image_decoder_config(srv_open,srv)) { + dbgprintk(3,"Error setting JPEG decoder config\n"); + goto delete_service; + } + + print_jpeg_configuration(srv_open); + + lock_critical_section(&hcl_mutex); + sva_error = SVA_ConfigureStillImageDecoder(srv_open->service_id, &srv_open->config.stillimagedecoder_info.configuration); + unlock_critical_section(&hcl_mutex); + if(sva_error != SVA_OK) { + dbgprintk(3,"Error setting JPEG decoder config %d\n",sva_error); + goto delete_service; + } + break; + } + case SVA_STILL_IMAGE_ENCODER: + { + if(set_still_image_encoder_config(srv_open,srv)) { + dbgprintk(3,"Error setting JPEG encoder config\n"); + goto delete_service; + } + lock_critical_section(&hcl_mutex); + sva_error = SVA_ConfigureStillImageEncoder(srv_open->service_id, &srv_open->config.stillimageencoder_info.configuration); + unlock_critical_section(&hcl_mutex); + if(sva_error != SVA_OK) { + dbgprintk(3,"Error setting JPEG encoder config %d\n",sva_error); + goto delete_service; + } + break; + } + case SVA_TV_OUTPUT: + { +#ifdef CONFIG_NOMADIK_NHK15 + volatile __u32 *ckg_cken,*tvo_clk_sel,*tvout_cfg_rst,*src_pckeno; +#else + volatile __u32 *ckg_cken_32,*tvo_clk_sel_32; +#endif + + if(!sva.sva_platform_data->denc_init) { + dbgprintk(3,"TVOUT not supported for this board\n"); + goto delete_service; + } + + if(nomadik_gpio_altfuncenable(GPIO_ALT_CCIR656_OUTPUT,"sva")) { + dbgprintk(3,"error:nomadik_gpio_altfuncenable() failed : CCIR656 O/P\n"); + goto delete_service; + } + +#ifdef CONFIG_NOMADIK_NHK15 + src_pckeno =(__u32 *)ioremap(0x101E0024 ,4); + tvout_cfg_rst = (__u32 *)ioremap((0xA0100000 +0x5A004),4); + ckg_cken = (__u32 *)ioremap((0xA0100000 + 0x5A008),4);//Enable clock + tvo_clk_sel = (__u32 *)ioremap((0xA0100000 + 0x5982C),4);//Select clock + + *src_pckeno = 0x00010000; + *tvout_cfg_rst = 0x0001; + *ckg_cken = 0x0010; //4th bit of CKG_CKEN + *tvo_clk_sel = 0x0001;//BIT0 of clk_sel; +#else + mdelay(1); + + ckg_cken_32 = (__u32 *)ioremap((0xA0100000 + 0x34010),4);//Enable clock + tvo_clk_sel_32 = (__u32 *)ioremap((0xA0100000 + 0x33058),4);//Select clock + + if(!ckg_cken_32 || !tvo_clk_sel_32) { + dbgprintk(3,"TVOUT clock could be enabled\n"); + goto delete_service; + } + + *ckg_cken_32 = *ckg_cken_32 | 0x10; //4th bit of CKG_CKEN + *tvo_clk_sel_32 = *tvo_clk_sel_32 | 0x1;//BIT0 of clk_sel; + + iounmap(ckg_cken_32); + iounmap(tvo_clk_sel_32); + mdelay(3); +#endif + set_tvout_config(srv_open, srv); + + lock_critical_section(&hcl_mutex); + sva_error = SVA_ConfigureTVOutput(srv_open->service_id, \ + &srv_open->config.tvout_info.configuration); + unlock_critical_section(&hcl_mutex); + if(sva_error != SVA_OK) { + dbgprintk(3,"Error setting TVOUT config %d\n",sva_error); + goto delete_service; + } + break; + } + + default: + goto delete_service; + + } /* End switch */ + + lock_critical_section(&hcl_mutex); + + + if( (srv_open->type == SVA_STILL_IMAGE_DECODER) && (srv_open->config.stillimagedecoder_info.configuration.transformId == SVA_DECODER_PROGRESSIVE_JPEG)){ + + sva_error = SVA_GetServiceInternalNeedsNCNB(srv_open->service_id,&need_size,&size_nc_nb); + srv_open->internal_ncnb_needs_size = size_nc_nb; + }else{ + sva_error = SVA_GetServiceInternalNeeds(srv_open->service_id, &need_size); + } + + unlock_critical_section(&hcl_mutex); + if(sva_error != SVA_OK) { + dbgprintk(3,"Getting Internal Needs failed:: %d\n", sva_error); + goto delete_service; + } + + /*if(srv_open->internal_needs) { + free_pages((unsigned long)srv_open->internal_needs, + get_order(srv_open->internal_needs_size)); + srv_open->internal_needs = NULL; + srv_open->internal_needs_size = 0; + }*/ + + srv_open->internal_needs_size = get_order(need_size * sizeof(char)); + + srv_open->internal_needs = (char *)__get_free_pages(GFP_KERNEL | GFP_DMA, + srv_open->internal_needs_size); + + if(!srv_open->internal_needs) { + ret_val = -ENOMEM; + goto delete_service; + } + + lock_critical_section(&hcl_mutex); + + if( (srv_open->type == SVA_STILL_IMAGE_DECODER) && (srv_open->config.stillimagedecoder_info.configuration.transformId == SVA_DECODER_PROGRESSIVE_JPEG)) + { + srv_open->internal_ncnb_needs.logical = (t_logical_address)dma_alloc_coherent(&sva.p_dev->dev, srv_open->internal_ncnb_needs_size, (dma_addr_t *)&srv_open->internal_ncnb_needs.physical, GFP_KERNEL); + + if(srv_open->internal_ncnb_needs.logical == 0){ + dbgprintk(3,"progressive JPEG decode :: Failed to allocate memory from dma_alloc_coherent() \n"); + ret_val = -ENOMEM; + goto delete_service; + } + sva_error = SVA_ProvideServiceInternalNeedsNCNB(srv_open->service_id, (t_logical_address)srv_open->internal_needs, need_size, + (t_system_address) srv_open->internal_ncnb_needs, srv_open->internal_ncnb_needs_size ); + if(sva_error != SVA_OK) { + dma_free_coherent(&sva.p_dev->dev, srv_open->internal_ncnb_needs_size,(void *)srv_open->internal_ncnb_needs.logical ,(dma_addr_t )srv_open->internal_ncnb_needs.physical); + srv_open->internal_ncnb_needs.logical = NULL; + srv_open->internal_ncnb_needs.physical = NULL; + } + }else{ + sva_error = SVA_ProvideServiceInternalNeeds(srv_open->service_id, + (t_logical_address)srv_open->internal_needs, need_size); + + } + unlock_critical_section(&hcl_mutex); + if(sva_error != SVA_OK) { + goto delete_service; + } + + srv_open->state &= ~SERVICE_CREATED; + return 0; + +delete_service: + if(srv_open->type == SVA_PREPROCESSOR) { + down(&hcl_mutex); + sva.active_preprocessor = NULL; + if(srv_open->grab_type==GRAB_PEPPERPOT) + sva.camera->close(); + up(&hcl_mutex); + } else if(srv_open->type == SVA_POSTPROCESSOR) { + down(&hcl_mutex); + if(srv_open->config.postprocessor_info.configuration.isDirectScreenAccess == TRUE) { + no_of_postprocessor--; + if(!no_of_postprocessor) + sva.sva_platform_data->disable_synchro(); + } + up(&hcl_mutex); + } else if(srv_open->type == SVA_TV_OUTPUT) { + down(&hcl_mutex); + if(nomadik_gpio_altfuncdisable(GPIO_ALT_CCIR656_OUTPUT,"sva")) + dbgprintk(3,"error:nomadik_gpio_altfuncdisable() failed : CCIR656 O/P\n"); + + sva.active_tvout = NULL; + up(&hcl_mutex); + } + + lock_critical_section(&hcl_mutex); + delete_service(open, indx); + unlock_critical_section(&hcl_mutex); + return ret_val; + +} +EXPORT_SYMBOL(configure_service); + +int +create_service (struct sva_device_open *open, struct sva_service_struct *srv) +{ + /* t_sva_error sva_error; */ + struct sva_service_open *srv_open; + int ret_val = 0; + __u8 indx = 0; + + down(&open->open_lock); + while(indx < MAX_SERVICE_OPENS && open->service_open_data[indx]) indx++; + + if(indx == MAX_SERVICE_OPENS) { + dbgprintk(3,"error: No more services possible for this open"); + up(&open->open_lock); + return -EBUSY; + } + + open->service_open_data[indx] = (struct sva_service_open *) + kzalloc(sizeof(struct sva_service_open), GFP_KERNEL); + + if(!open->service_open_data[indx]) { + up(&open->open_lock); + return -ENOMEM; + } + + srv_open = open->service_open_data[indx]; + srv_open->index = open->index; + srv_open->state = SERVICE_INACTIVATED | SERVICE_CREATED; + srv_open->service_id = MASK_ALL32; + init_MUTEX(&srv_open->service_lock); + up(&open->open_lock); + + switch(srv->service_type) { + + case PREPROCESSOR: + srv_open->type = SVA_PREPROCESSOR; + + switch(srv->config.preprocessor_configuration.capability) { + case SENSOR_HIGHQUALITY_YUV420_MB: + dbgprintk(3,"High Quality grab service is not yet supported\n"); + ret_val = -EINVAL; + goto delete; + case SENSOR_YUV420_MB : + case SENSOR_YUV422_SEP_COMP_MB : + case SENSOR_YUV420_SEP_COMP_MB : + if(vpip_irp_enable==0){ + dbgprintk(3,"VPIP service is not supported\n"); + ret_val = -EINVAL; + goto delete; + } + srv_open->grab_type= GRAB_IRP; /* VPIP */ + break; + default: + srv_open->grab_type= GRAB_PEPPERPOT; + break; + } + + if (sva.active_tvout || sva.active_preprocessor){ + ret_val = -EINVAL; + goto delete; + } + down(&hcl_mutex); + if(srv_open->grab_type==GRAB_PEPPERPOT){ + dbgprintk(1,"opening pepperpot camera for grab task\n"); + if(!(sva.camera) || sva.camera->open()) { + dbgprintk(3,"error:Cannot create preprocessor service!\n"); + ret_val = -EINVAL; + up(&hcl_mutex); + goto delete; + } + } + sva.active_preprocessor = srv_open; + up(&hcl_mutex); + + break; + + case POSTPROCESSOR: + srv_open->type = SVA_POSTPROCESSOR; + /*down(&hcl_mutex); + if(srv->config.postprocessor_configuration.direct_display == TRUE) { + if(!no_of_postprocessor) { + ret_val = sva.sva_platform_data->enable_synchro(); + if(ret_val) { + up(&hcl_mutex); + goto delete; + } + } + no_of_postprocessor++; + } + up(&hcl_mutex);*/ + break; + + case DECODE: + + if(!srv->config.videodecoder_configuration.codec_params) { + ret_val = -EINVAL; + goto free_srv; + } + + srv_open->type = SVA_VIDEO_DECODER; + + break; + + case ENCODE: + if(!srv->config.videoencoder_configuration.codec_params || + !srv->config.videoencoder_configuration.brc_config_params) { + ret_val = -EINVAL; + goto free_srv; + } + + srv_open->type = SVA_VIDEO_ENCODER; + + break; + + case TV_OUTPUT: + down(&hcl_mutex); + if (sva.active_tvout) { + dbgprintk(3,"error:TV OUT service already active!\n"); + ret_val = -EINVAL; + up(&hcl_mutex); + goto delete; + } + sva.active_tvout = srv_open; + up(&hcl_mutex); + + srv_open->type = SVA_TV_OUTPUT; + break; + + case STILL_IMAGE_DECODE: + if(!srv->config.stillimagedecoder_configuration.sva_still_algo_configuration_params ){ + ret_val = -EINVAL; + goto free_srv; + } + srv_open->type = SVA_STILL_IMAGE_DECODER; + break; + case STILL_IMAGE_ENCODE: + if(!srv->config.stillimageencoder_configuration.sva_still_algo_configuration_params ){ + ret_val = -EINVAL; + goto free_srv; + } + srv_open->type = SVA_STILL_IMAGE_ENCODER; + break; + case SW_PROCESSING: + default: + dbgprintk(3,"error: Not supported service type\n"); + ret_val = -EINVAL; + } + +/* lock_critical_section(&hcl_mutex); + sva_error = SVA_CreateService(srv_open->type, &srv_open->service_id); + unlock_critical_section(&hcl_mutex); + if(sva_error != SVA_OK) { + ret_val = -EINVAL; + goto free_srv; + } +*/ + srv->service_id = indx; + srv->index = srv_open->index; + + if(srv_open->type != SVA_PREPROCESSOR) { + srv_open->in_image_buf_q = kmalloc(sizeof(struct sva_queue_data), GFP_KERNEL); + if(!srv_open->in_image_buf_q) { + ret_val = -ENOMEM; + goto free_srv; + } else { + sva_q_init(&srv_open->in_image_buf_q->input_q); + sva_q_init(&srv_open->in_image_buf_q->internal_q); + sva_q_init(&srv_open->in_image_buf_q->output_q); + init_waitqueue_head(&(srv_open->in_image_buf_q->output_wq)); + } + } + + if(srv_open->type != SVA_TV_OUTPUT) { + srv_open->out_image_buf_q = kmalloc(sizeof(struct sva_queue_data), GFP_KERNEL); + if(!srv_open->out_image_buf_q) { + ret_val = -ENOMEM; + goto free_srv; + } else { + sva_q_init(&srv_open->out_image_buf_q->input_q); + sva_q_init(&srv_open->out_image_buf_q->internal_q); + sva_q_init(&srv_open->out_image_buf_q->output_q); + init_waitqueue_head(&(srv_open->out_image_buf_q->output_wq)); + } + } + + if(srv_open->type != SVA_POSTPROCESSOR && srv_open->type != SVA_PREPROCESSOR + && srv_open->type != SVA_TV_OUTPUT) { + srv_open->in_infos_buf_q = kmalloc(sizeof(struct sva_queue_data), GFP_KERNEL); + if(!srv_open->in_infos_buf_q) { + ret_val = -ENOMEM; + goto free_srv; + } else { + sva_q_init(&srv_open->in_infos_buf_q->input_q); + sva_q_init(&srv_open->in_infos_buf_q->internal_q); + sva_q_init(&srv_open->in_infos_buf_q->output_q); + init_waitqueue_head(&(srv_open->in_infos_buf_q->output_wq)); + } + } + + if(srv_open->type != SVA_POSTPROCESSOR && srv_open->type != SVA_PREPROCESSOR + && srv_open->type != SVA_TV_OUTPUT) { + srv_open->out_infos_buf_q = kmalloc(sizeof(struct sva_queue_data), GFP_KERNEL); + if(!srv_open->out_infos_buf_q) { + ret_val = -ENOMEM; + goto free_srv; + } else { + sva_q_init(&srv_open->out_infos_buf_q->input_q); + sva_q_init(&srv_open->out_infos_buf_q->internal_q); + sva_q_init(&srv_open->out_infos_buf_q->output_q); + init_waitqueue_head(&(srv_open->out_infos_buf_q->output_wq)); + } + } + + if(srv_open->type != SVA_POSTPROCESSOR && srv_open->type != SVA_PREPROCESSOR + && srv_open->type != SVA_TV_OUTPUT) { + srv_open->in_coded_buf_q = kmalloc(sizeof(struct sva_queue_data), GFP_KERNEL); + if(!srv_open->in_coded_buf_q) { + ret_val = -ENOMEM; + goto free_srv; + } else { + sva_q_init(&srv_open->in_coded_buf_q->input_q); + sva_q_init(&srv_open->in_coded_buf_q->internal_q); + sva_q_init(&srv_open->in_coded_buf_q->output_q); + init_waitqueue_head(&(srv_open->in_coded_buf_q->output_wq)); + } + } + + if(srv_open->type != SVA_POSTPROCESSOR && srv_open->type != SVA_PREPROCESSOR + && srv_open->type != SVA_TV_OUTPUT) { + srv_open->out_coded_buf_q = kmalloc(sizeof(struct sva_queue_data), GFP_KERNEL); + if(!srv_open->out_coded_buf_q) { + ret_val = -ENOMEM; + goto free_srv; + } else { + sva_q_init(&srv_open->out_coded_buf_q->input_q); + sva_q_init(&srv_open->out_coded_buf_q->internal_q); + sva_q_init(&srv_open->out_coded_buf_q->output_q); + init_waitqueue_head(&(srv_open->out_coded_buf_q->output_wq)); + } + } + +/* HighQuality grab needs this + if(srv_open->type != SVA_PREPROCESSOR && */ + if(srv_open->type != SVA_TV_OUTPUT) { + srv_open->in_params_buf_q = kmalloc(sizeof(struct sva_queue_data), GFP_KERNEL); + if(!srv_open->in_params_buf_q) { + ret_val = -ENOMEM; + goto free_srv; + } else { + sva_q_init(&srv_open->in_params_buf_q->input_q); + sva_q_init(&srv_open->in_params_buf_q->internal_q); + sva_q_init(&srv_open->in_params_buf_q->output_q); + init_waitqueue_head(&(srv_open->in_params_buf_q->output_wq)); + } + } + + if(srv_open->type != SVA_POSTPROCESSOR && srv_open->type != SVA_PREPROCESSOR + && srv_open->type != SVA_TV_OUTPUT) { + srv_open->out_params_buf_q = kmalloc(sizeof(struct sva_queue_data), GFP_KERNEL); + if(!srv_open->out_params_buf_q) { + ret_val = -ENOMEM; + goto free_srv; + } else { + sva_q_init(&srv_open->out_params_buf_q->input_q); + sva_q_init(&srv_open->out_params_buf_q->internal_q); + sva_q_init(&srv_open->out_params_buf_q->output_q); + init_waitqueue_head(&(srv_open->out_params_buf_q->output_wq)); + } + } + + if(srv_open->type == SVA_VIDEO_DECODER) { + srv_open->readonly_image_buf_q = kmalloc(sizeof(struct sva_queue_data), GFP_KERNEL); + if(!srv_open->readonly_image_buf_q) { + ret_val = -ENOMEM; + goto free_srv; + } else { + sva_q_init(&srv_open->readonly_image_buf_q->input_q); + sva_q_init(&srv_open->readonly_image_buf_q->internal_q); + sva_q_init(&srv_open->readonly_image_buf_q->output_q); + init_waitqueue_head(&(srv_open->readonly_image_buf_q->output_wq)); + } + } +#if 1 + if(srv_open->type == SVA_STILL_IMAGE_DECODER) { + srv_open->readonly_image_buf_q = kmalloc(sizeof(struct sva_queue_data), GFP_KERNEL); + if(!srv_open->readonly_image_buf_q) { + ret_val = -ENOMEM; + goto free_srv; + } else { + sva_q_init(&srv_open->readonly_image_buf_q->input_q); + sva_q_init(&srv_open->readonly_image_buf_q->internal_q); + sva_q_init(&srv_open->readonly_image_buf_q->output_q); + init_waitqueue_head(&(srv_open->readonly_image_buf_q->output_wq)); + } + } +#endif + + /* Initialize message queue */ + sva_q_init(&srv_open->filled_message_queue); + sva_q_init(&srv_open->empty_message_queue); + + { + int i = 0; + while(i < MAX_MESSAGES) { + srv_open->messages_array[i].message.buffer.buffer_id = -1; + srv_open->messages_array[i].buffer_id = -1; + sva_q_add_tail(&srv_open->empty_message_queue, + &srv_open->messages_array[i].qnode); + i++; + } + } + + init_waitqueue_head(&(srv_open->service_stop_wq)); + init_waitqueue_head(&(srv_open->service_activate_wq)); + init_waitqueue_head(&(srv_open->service_inactivate_wq)); + init_waitqueue_head(&(srv_open->message_wq)); + + return 0; + +free_srv: + if(srv_open->type == SVA_PREPROCESSOR) { + down(&hcl_mutex); + sva.active_preprocessor = NULL; + if(sva.camera) + sva.camera->close(); + up(&hcl_mutex); + } /*else if(srv_open->type == SVA_POSTPROCESSOR) { + down(&hcl_mutex); + if(srv->config.postprocessor_configuration.direct_display == TRUE) { + no_of_postprocessor--; + if(!no_of_postprocessor) + sva.sva_platform_data->disable_synchro(); + } + up(&hcl_mutex); + } */else if(srv_open->type == SVA_TV_OUTPUT) { + down(&hcl_mutex); + sva.active_tvout = NULL; + up(&hcl_mutex); + } + +delete: + lock_critical_section(&hcl_mutex); + delete_service(open, indx); + unlock_critical_section(&hcl_mutex); + return ret_val; + +} +EXPORT_SYMBOL(create_service); + +static void +configure_camera(struct sva_service_open *srv) +{ + t_sva_preprocessor_configuration *pconf; + int ret; + struct camera_configuration cam_conf; + + pconf = &srv->config.preprocessor_info.configuration; + cam_conf.frame.height = pconf->sourceFrameDesc.frame.height; + cam_conf.frame.width = pconf->sourceFrameDesc.frame.width; + cam_conf.format = IMG_FMT_YUV422; + cam_conf.frame_rate = srv->config.preprocessor_info.camera_framerate; + cam_conf.frequency.msb = 0x99; + cam_conf.frequency.lsb = 0x99; + + ret = sva.camera->set_params(&cam_conf); + dbgprintk(2,"set_params returns %d\n",ret); + return; +} + +static int +load_single_firmware(t_sva_fw_id fw_id) +{ + t_sva_error sva_error; + int indx = 0; + while(indx < MAX_FIRMWARE && sva.firmware_array[indx].firmware_id != fw_id) + indx++; + + if(indx == MAX_FIRMWARE) { + dbgprintk(3,"error: Firmware id %lu not found",fw_id); + return -EINVAL; + } + + lock_critical_section(&hcl_mutex); + sva_error = SVA_SetFirmwareShareArea(fw_id, (t_logical_address)sva.firmware_array[indx].buffer); + unlock_critical_section(&hcl_mutex); + if(sva_error != SVA_OK) { + dbgprintk(3,"error: Unable to share firmware id %lu\n",fw_id); + return -EINVAL; + } + + return 0; + +} + +static int +sva_activate_service(struct sva_service_open *srv_open) +{ + t_sva_error sva_error; + t_sva_fw_id fw_id; + int err; + + while(1) { + if((srv_open->state & SERVICE_ACTIVATED) == SERVICE_ACTIVATED) + break; + lock_critical_section(&hcl_mutex); + sva_error = SVA_ActivateService(srv_open->service_id, + SVA_NON_REALTIME_SERVICE, &fw_id); + unlock_critical_section(&hcl_mutex); + dbgprintk(2,"Activate service returned %d\n",sva_error); + if((sva_error != SVA_FW_SWITCH_OCCURED) && + (sva_error != SVA_FW_DOWNLOAD_NEEDED) && (sva_error != SVA_FW_SWITCH_DELAYED)) { + dbgprintk(3,"error:Activate service command failed %d\n",sva_error); + return -EINVAL; + } + + if(sva_error == SVA_FW_DOWNLOAD_NEEDED || sva_error == SVA_FW_NOT_PROVIDED) { + dbgprintk(2,"Loading firmware %lu\n",fw_id); + if(load_single_firmware(fw_id)) + return -EINVAL; + else /* Firmware loading sucessful */ + continue; + } else { + + dbgprintk(2,"Wait starting\n"); + err = wait_event_interruptible(srv_open->service_activate_wq, + (srv_open->state & SERVICE_ACTIVATED) == SERVICE_ACTIVATED); + if(err) + return err; + dbgprintk(2,"Wait over %d\n",err); + } + + }/* end while */ + + if(srv_open->type == SVA_PREPROCESSOR && srv_open->grab_type== GRAB_IRP) { +/* if(sva.last_preprocessor_grab_type ==GRAB_PEPPERPOT){ + dbgprintk(1," activating vpip service (switch occured)\n"); + if(sva.sva_platform_data->camera_deinit) + sva.sva_platform_data->camera_deinit(); + if(sva.sva_platform_data->sensor_gpio_init) + sva.sva_platform_data->sensor_gpio_init(IRP_CAMERA_SENSOR_CCP0); + } */ + if(irp_activate_service(srv_open)) + return -EINVAL; + } else if(srv_open->grab_type== GRAB_PEPPERPOT) { + /* if(sva.last_preprocessor_grab_type==GRAB_IRP){ + dbgprintk(1," activating pepperpot service (switch occured)\n"); + if(sva.sva_platform_data->sensor_gpio_deinit) + sva.sva_platform_data->sensor_gpio_deinit(IRP_CAMERA_SENSOR_CCP0); + if(sva.sva_platform_data->camera_gpio_init) + sva.sva_platform_data->camera_gpio_init(); + } + if(sva.sva_platform_data->camera_gpio_init && sva.sva_platform_data->camera_gpio_init()) { + dbgprintk(3,"Camera platform initialization failed\n"); + // nomadik_gpio_altfuncdisable(GPIO_ALT_CCIR656_INPUT, "sva"); + return -EAGAIN; + }*/ + } + + return 0; +} + +int +push_buffer(struct sva_service_open *srv, enum sva_buffer_type buf_type, enum push_type push) +{ + t_sva_push_mode push_mode; + t_sva_timestamp timestamp; + t_sva_error error; + t_uint32 system_time; + t_sva_buffer_type buffer_type; + int ret = 0; + struct sva_buffer_info *buf_info = NULL; + struct sva_queue_data *qdata = NULL; + + if(unlikely((srv->state & SERVICE_ACTIVATED) != SERVICE_ACTIVATED)) { + + if(sva_activate_service(srv)) + return -EINVAL; + } + + switch(buf_type) { + + case BUF_TYPE_IMAGE: + if(push==PUSH_IN) { + push_mode = SVA_PUSH_IN; + qdata = srv->in_image_buf_q; + } else { + push_mode = SVA_PUSH_OUT; + qdata = srv->out_image_buf_q; + } + buffer_type = SVA_IMAGE_BUFFER_TYPE; + break; + case BUF_TYPE_PARAMS: + if(push==PUSH_IN) { + push_mode = SVA_PUSH_IN; + qdata = srv->in_params_buf_q; + } else { + push_mode = SVA_PUSH_OUT; + qdata = srv->out_params_buf_q; + } + buffer_type = SVA_PARAMS_BUFFER_TYPE; + break; + case BUF_TYPE_INFOS: + if(push==PUSH_IN) { + push_mode = SVA_PUSH_IN; + qdata = srv->in_infos_buf_q; + } else { + push_mode = SVA_PUSH_OUT; + qdata = srv->out_infos_buf_q; + } + buffer_type = SVA_INFOS_BUFFER_TYPE; + break; + case BUF_TYPE_BITSTREAM: + if(push==PUSH_IN) { + push_mode = SVA_PUSH_IN; + qdata = srv->in_coded_buf_q; + } else { + push_mode = SVA_PUSH_OUT; + qdata = srv->out_coded_buf_q; + } + buffer_type = SVA_BITSTREAM_BUFFER_TYPE; + break; + default: + dbgprintk(3,"error: Invalid buffer type\n"); + return -EINVAL; + } + + if(unlikely(!qdata)){ + dbgprintk(3,"no such type of queue exists for this service\n"); + return -EINVAL; + } + + buf_info = (struct sva_buffer_info *)sva_q_del_head(&qdata->input_q); + + if(unlikely(buf_info == NULL)) + return -ENOBUFS; + + dbgprintk(2,"Push mode %d specified, Buffer id %d, SERVICE %lu\n", + buf_info->push,buf_info->buffer.buffer_id, srv->service_id); + + sva_q_add_tail(&qdata->internal_q, &buf_info->qnode); + + if(buf_info->vma) { /* Check if buffer is mapped */ +#if !defined(CONFIG_L2CACHE_ENABLE) + flush_cache_range(buf_info->vma, buf_info->vma->vm_start, buf_info->vma->vm_end); +#endif + } + + switch(buf_type) { + + case BUF_TYPE_IMAGE: + if(buf_info->buffer.timestamp != 0 && + (srv->type==SVA_POSTPROCESSOR||srv->type==SVA_VIDEO_ENCODER)) { + SVA_GetServiceSystemTime(srv->service_id,&system_time); + timestamp.type = SVA_PRESENTATION_TIMESTAMP; + timestamp.value = buf_info->buffer.timestamp; + } else { + timestamp.type = SVA_NO_TIMESTAMP; + timestamp.value = 0; + } + + lock_critical_section(&hcl_mutex); + error = SVA_PushImageBuffer(srv->service_id,buf_info->buffer_id, + push_mode,timestamp); + unlock_critical_section(&hcl_mutex); + + if(srv->config.preprocessor_info.configuration.transformId + == SVA_PREPROCESSOR_SENSOR_HIGHQUALITY_YUV420_MB){ + dbgprintk(2,"calling irp_start_ewarp_hq after pushing the image buffer \n"); + if(irp_start_ewarp_hq(srv)!= 0){ + dbgprintk(3,"irp_start_ewarp_hq failed \n"); + return -EAGAIN; + } + } + break; + + case BUF_TYPE_BITSTREAM: + lock_critical_section(&hcl_mutex); + error = SVA_PushBitstreamBuffer(srv->service_id, + buf_info->buffer_id,push_mode); + unlock_critical_section(&hcl_mutex); + + if(error != SVA_OK) { + dbgprintk(3,"error: HCL Push bitsbuffer failed, error %d\n",error); + goto out; + } + break; + + case BUF_TYPE_INFOS: + lock_critical_section(&hcl_mutex); + error = SVA_PushInfosBuffer(srv->service_id, + buf_info->buffer_id,push_mode); + unlock_critical_section(&hcl_mutex); + + break; + + case BUF_TYPE_PARAMS: + lock_critical_section(&hcl_mutex); + error = SVA_PushParamsBuffer(srv->service_id, + buf_info->buffer_id,push_mode); + unlock_critical_section(&hcl_mutex); + + break; + + default: + dbgprintk(3,"error Not supported buffer type\n"); + ret = -EINVAL; + goto out; + + } + + if(unlikely(error != SVA_OK)) { + dbgprintk(3,"error: HCL Push buffer failed, error %d\n",error); + ret = -EIO; + goto out; + } + + /* FOR TVOUT + if(srv->type == SVA_TV_OUTPUT && !init_done) { + printk("Initializing denc\n"); + nomadik_denc_init(srv->config.tvout_info.mode); + init_done = 1; + } */ + + return 0; + +out: + dbgprintk(3,"error Push_buffer failed\n"); + sva_q_del_tail(&qdata->internal_q); + sva_q_add_tail(&qdata->output_q, &buf_info->qnode); + buf_info->buffer.flags |= BUF_FLAG_ERR; + return ret; + +} + +void +flush_queue(struct sva_queue_data *qdata) +{ + struct sva_buffer_info *buf_info; + + while(1) { + buf_info = (struct sva_buffer_info *)sva_q_del_head(&qdata->input_q); + if(!buf_info) + break; + buf_info->buffer.flags &= ~BUF_FLAG_QUEUED; + } + + while(1) { + buf_info = (struct sva_buffer_info *)sva_q_del_head(&qdata->internal_q); + if(!buf_info) + break; + buf_info->buffer.flags &= ~BUF_FLAG_QUEUED; + } + + while(1) { + buf_info = (struct sva_buffer_info *)sva_q_del_head(&qdata->output_q); + if(!buf_info) + break; + buf_info->buffer.flags &= ~BUF_FLAG_QUEUED; + } + +} + +static int +flush_service(struct sva_service_open *srv_open) +{ + t_sva_error sva_error; + if(srv_open->type != SVA_PREPROCESSOR) { + lock_critical_section(&hcl_mutex); + sva_error = SVA_ControlService(srv_open->service_id, SVA_SERVICE_FLUSH_IN, 0); + unlock_critical_section(&hcl_mutex); + if(sva_error != SVA_OK) { + dbgprintk(3,"error:Control service flushin failed, error %d\n",sva_error); + return -EINVAL; + } + + while(wait_event_interruptible(srv_open->service_inactivate_wq, + (srv_open->state & SERVICE_FLUSHED_IN) == SERVICE_FLUSHED_IN) == -ERESTARTSYS); + srv_open->state &= ~SERVICE_FLUSHED_IN; + } + + if(srv_open->type != SVA_TV_OUTPUT) { + lock_critical_section(&hcl_mutex); + sva_error = SVA_ControlService(srv_open->service_id, SVA_SERVICE_FLUSH_OUT, 0); + unlock_critical_section(&hcl_mutex); + if(sva_error != SVA_OK) { + dbgprintk(3,"error:Control service flush out failed, error %d\n",sva_error); + return -EINVAL; + } + + while(wait_event_interruptible(srv_open->service_inactivate_wq, + (srv_open->state & SERVICE_FLUSHED_OUT) == SERVICE_FLUSHED_OUT) == -ERESTARTSYS); + srv_open->state &= ~SERVICE_FLUSHED_OUT; + } + + return 0; + +} + +void flush_service_queues(struct sva_service_open *srv_open) +{ +/* ret_val = flush_service(srv_open); + if(ret_val) + return ret_val; */ + + down(&srv_open->service_lock); + if(srv_open->in_image_buf_q) { + /* while(sva_q_peek_head(&srv_open->in_image_buf_q->internal_q) != NULL) ; */ + flush_queue(srv_open->in_image_buf_q); + } + + if(srv_open->in_params_buf_q) { + /* while(sva_q_peek_head(&srv_open->in_params_buf_q->internal_q) != NULL) ; */ + flush_queue(srv_open->in_params_buf_q); + } + + if(srv_open->in_coded_buf_q) { + /* while(sva_q_peek_head(&srv_open->in_coded_buf_q->internal_q) != NULL) ; */ + flush_queue(srv_open->in_coded_buf_q); + } + + if(srv_open->in_infos_buf_q) { + /* while(sva_q_peek_head(&srv_open->in_infos_buf_q->internal_q) != NULL) ; */ + flush_queue(srv_open->in_infos_buf_q); + } + + if(srv_open->out_image_buf_q) { + /* while(sva_q_peek_head(&srv_open->out_image_buf_q->internal_q) != NULL) ; */ + flush_queue(srv_open->out_image_buf_q); + } + + if(srv_open->out_params_buf_q) { + /* while(sva_q_peek_head(&srv_open->out_params_buf_q->internal_q) != NULL) ; */ + flush_queue(srv_open->out_params_buf_q); + } + + if(srv_open->out_coded_buf_q) { + /* while(sva_q_peek_head(&srv_open->out_coded_buf_q->internal_q) != NULL) ; */ + flush_queue(srv_open->out_coded_buf_q); + } + + if(srv_open->out_infos_buf_q) { + /* while(sva_q_peek_head(&srv_open->out_infos_buf_q->internal_q) != NULL) ; */ + flush_queue(srv_open->out_infos_buf_q); + } + + { + int i = 0; + + sva_q_init(&srv_open->filled_message_queue); + sva_q_init(&srv_open->empty_message_queue); + + while(i < MAX_MESSAGES) { + srv_open->messages_array[i].message.buffer.buffer_id = -1; + srv_open->messages_array[i].buffer_id = -1; + sva_q_add_tail(&srv_open->empty_message_queue, + &srv_open->messages_array[i].qnode); + i++; + } + } + + up(&srv_open->service_lock); + return; +} +EXPORT_SYMBOL(flush_service_queues); + +int +sva_service_control(struct sva_device_open *open, struct sva_control_service *srv) +{ + t_sva_error sva_error; + t_sva_service_cmd_id cmd; + struct sva_service_open *srv_open; + int err; + t_sva_timestamp timestamp = {SVA_NO_TIMESTAMP,0}; + + dbgprintk(1,"%s enter, command %d\n",__FUNCTION__,srv->command); + if(srv->service_id >= MAX_SERVICE_OPENS || srv->service_id < 0 || + !(open->service_open_data[srv->service_id])) { + dbgprintk(3,"error: Invalid service id %d\n",srv->service_id); + return -EINVAL; + } + + srv_open = open->service_open_data[srv->service_id]; + + switch(srv->command) { + + case SERVICE_START: + if((srv_open->state & SERVICE_STARTED) == SERVICE_STARTED) + return -EINVAL; + cmd = SVA_SERVICE_START; + break; + case SERVICE_ABORT: + if((srv_open->state & SERVICE_ABORTED) == SERVICE_ABORTED || + (srv_open->state & SERVICE_STOPPED) == SERVICE_STOPPED) + return -EINVAL; + cmd = SVA_SERVICE_ABORT; + break; + case SERVICE_STOP: + if((srv_open->state & SERVICE_ABORTED) == SERVICE_ABORTED || + (srv_open->state & SERVICE_STOPPED) == SERVICE_STOPPED) + return -EINVAL; + cmd = SVA_SERVICE_STOP; + break; + case SERVICE_FLUSH: + if((srv_open->state & SERVICE_ABORTED) == SERVICE_ABORTED || + (srv_open->state & SERVICE_STOPPED) == SERVICE_STOPPED) + return -EINVAL; + + return flush_service(srv_open); + break; + + default: + dbgprintk(3,"error:Invalid command %d\n",srv->command); + return -EINVAL; + } + + if(srv_open->type == SVA_PREPROCESSOR && srv->command == SERVICE_START + && srv_open->grab_type== GRAB_PEPPERPOT) { + struct camera_control ctrl; + enum cameramode mode; + int ret; + dbgprintk(1,"trying to configure pepperpot camera ..\n"); + configure_camera(srv_open); + ctrl.id = CAMERAMODE; + mode = CAMERAMODE_LIVE; + ctrl.value = &mode; + ret = sva.camera->set_control(&ctrl); + } + + if((srv_open->state & SERVICE_ACTIVATED) != SERVICE_ACTIVATED) { + + if(sva_activate_service(srv_open)) + return -EINVAL; + + }/* End if service not activated*/ + + /*err = wait_event_interruptible(srv_open->readonly_image_buf_q->output_wq, + sva_q_peek_head(&srv_open->readonly_image_buf_q->input_q)==NULL); + if(err) + return err;*/ + + if(srv_open->config.preprocessor_info.configuration.transformId + == SVA_PREPROCESSOR_SENSOR_HIGHQUALITY_YUV420_MB && cmd == SVA_SERVICE_START){ + dbgprintk(2," Ignoring SVA_SERVICE_START cmd for Grab @HighQuality service\n"); + } else { + lock_critical_section(&hcl_mutex); + sva_error = SVA_ControlService(srv_open->service_id, cmd, (t_uint32)×tamp); + unlock_critical_section(&hcl_mutex); + if(sva_error != SVA_OK) { + dbgprintk(3,"error:Control service command %d failed, error %d\n", \ + cmd, sva_error); + return -EINVAL; + } + } + + if(cmd == SVA_SERVICE_STOP) { + + dbgprintk(2,"Waiting for service to stop\n"); + err = wait_event_interruptible(srv_open->service_stop_wq, + (srv_open->state & SERVICE_STOPPED) == SERVICE_STOPPED); + if(err) { + return err; + } + dbgprintk(2,"Service stop recieved\n"); + + /* need to flush the buffers before deleting the service */ + flush_service(srv_open); + dbgprintk(1,"Flush service done\n"); + + /* lock_critical_section(&hcl_mutex); + sva_error = SVA_InactivateService(srv_open->service_id); + if(sva_error != SVA_OK) { + dbgprintk(3,"error: Inactivating service failed, \ + service id %ld, error %d",srv_open->service_id, (int)sva_error); + } else { + dbgprintk(1,"Waiting for service to inactivate\n"); + while(wait_event_interruptible(srv_open->service_inactivate_wq, + ((srv_open->state & SERVICE_INACTIVATED) + == SERVICE_INACTIVATED)) == -ERESTARTSYS); + dbgprintk(1,"Service inactivated\n"); + + } + unlock_critical_section(&hcl_mutex); */ + + + }/* cmd == SERVICE_STOP */ + + if((cmd == SVA_SERVICE_STOP || cmd == SVA_SERVICE_ABORT)) { + + if(srv_open->type == SVA_PREPROCESSOR) { + if(srv_open->grab_type==GRAB_IRP){ + /* TODO IRP stop streaming */ + if(irp_stop_ewarp(srv_open)) + dbgprintk(3,"error while stoping IRP firmware \n"); + } + else { /* pepperpot */ + struct camera_control ctrl; + enum cameramode mode; + + /* ABORT or STOP */ + ctrl.id = CAMERAMODE; + mode = CAMERAMODE_IDLE; + ctrl.value = &mode; + sva.camera->set_control(&ctrl); + } + sva.last_preprocessor_grab_type = srv_open->grab_type; + } else if(srv_open->type == SVA_POSTPROCESSOR) { + if(srv_open->config.postprocessor_info.configuration.isDirectScreenAccess == TRUE) { + no_of_postprocessor--; + if(!no_of_postprocessor) + sva.sva_platform_data->disable_synchro(); + } + } + } + + if(cmd == SVA_SERVICE_ABORT) { + down(&srv_open->service_lock); + srv_open->state &= ~SERVICE_STARTED; + srv_open->state |= SERVICE_ABORTED; + up(&srv_open->service_lock); + + } else if(cmd == SVA_SERVICE_START) { /* For SERVICE_START */ + down(&srv_open->service_lock); + srv_open->state &= ~SERVICE_ABORTED; + srv_open->state &= ~SERVICE_STOPPED; + srv_open->state |= SERVICE_STARTED; + SVA_SetServiceSystemTime(srv_open->service_id, 0); + up(&srv_open->service_lock); + + if(srv_open->in_coded_buf_q) + while(push_buffer(srv_open, BUF_TYPE_BITSTREAM, PUSH_IN) != -ENOBUFS) ; + if(srv_open->in_image_buf_q) + while(push_buffer(srv_open, BUF_TYPE_IMAGE, PUSH_IN) != -ENOBUFS) ; + if(srv_open->in_infos_buf_q) + while(push_buffer(srv_open, BUF_TYPE_INFOS, PUSH_IN) != -ENOBUFS) ; + if(srv_open->in_params_buf_q) + while(push_buffer(srv_open, BUF_TYPE_PARAMS, PUSH_IN) != -ENOBUFS) ; + + if(srv_open->out_coded_buf_q) + while(push_buffer(srv_open, BUF_TYPE_BITSTREAM, PUSH_OUT) != -ENOBUFS) ; + if(srv_open->out_image_buf_q) + while(push_buffer(srv_open, BUF_TYPE_IMAGE, PUSH_OUT) != -ENOBUFS) ; + if(srv_open->out_infos_buf_q) + while(push_buffer(srv_open, BUF_TYPE_INFOS, PUSH_OUT) != -ENOBUFS) ; + if(srv_open->out_params_buf_q) + while(push_buffer(srv_open, BUF_TYPE_PARAMS, PUSH_OUT) != -ENOBUFS) ; + + if(srv_open->type == SVA_POSTPROCESSOR) { + down(&hcl_mutex); + if(srv_open->config.postprocessor_info.configuration.isDirectScreenAccess == TRUE) { + if(!no_of_postprocessor) { + err = sva.sva_platform_data->enable_synchro(); + if(err) { + up(&hcl_mutex); + dbgprintk(3,"error:Failed to enable CLCD VSync\n"); + return -EINVAL; + } + } + no_of_postprocessor++; + } + up(&hcl_mutex); + } + dbgprintk(2,"SERVICE %lu started\n",srv_open->service_id); + + } + dbgprintk(1,"%s exit\n",__FUNCTION__); + + return 0; +} +EXPORT_SYMBOL(sva_service_control); + +int +sva_delete_service(struct sva_device_open *open, struct sva_service_struct *srv) +{ + struct sva_service_open *srv_open; + + dbgprintk(1,"%s() enter\n",__FUNCTION__); + down(&open->open_lock); + if(srv->service_id > MAX_SERVICE_OPENS || srv->service_id < 0 || + !(open->service_open_data[srv->service_id])) { + dbgprintk(3,"error: Invalid service id %d\n",srv->service_id); + up(&open->open_lock); + return -EINVAL; + } + srv_open = open->service_open_data[srv->service_id]; + + /* For a service to be stopped it must be configured and activated */ + if((srv_open->state & SERVICE_CREATED) != SERVICE_CREATED && + (srv_open->state & SERVICE_ACTIVATED) != SERVICE_ACTIVATED) + sva_activate_service(srv_open); + + if((srv_open->state & SERVICE_STARTED) == SERVICE_STARTED) { + struct sva_control_service ctrl; + ctrl.service_id = srv->service_id; + ctrl.command = SERVICE_STOP; + sva_service_control(open, &ctrl); + } + if((srv_open->type == SVA_STILL_IMAGE_DECODER) && (srv_open->infos)) + { + vfree(srv_open->infos); + srv_open->infos = NULL; + } + + /* need to flush the buffers before deleting the service */ + flush_service_queues(srv_open); + + up(&open->open_lock); + + /* stop vpip fw & sensor before we delete service */ + if(srv_open->type == SVA_PREPROCESSOR) { + sva.active_preprocessor = NULL; + if(srv_open->grab_type==GRAB_IRP){ +// if(irp_stop_ewarp(srv_open)) +// dbgprintk(3,"error while stoping IRP firmware \n"); + // irp_power_down(srv_open); + } + } + /*moving it here, cause dont delete the service before IRP stops */ + lock_critical_section(&hcl_mutex); + delete_service(open, srv->service_id); + unlock_critical_section(&hcl_mutex); + + down(&hcl_mutex); + if(srv_open->type == SVA_PREPROCESSOR) { + sva.active_preprocessor = NULL; + if(srv_open->grab_type==GRAB_PEPPERPOT) /* not vpip */ + sva.camera->close(); + } /*else if(srv_open->type == SVA_POSTPROCESSOR) { + if(srv_open->config.postprocessor_info.configuration.isDirectScreenAccess == TRUE) { + no_of_postprocessor--; + if(!no_of_postprocessor) + sva.sva_platform_data->disable_synchro(); + } + } */ else if(srv_open->type == SVA_TV_OUTPUT) { + sva.sva_platform_data->denc_deinit(); + if(nomadik_gpio_altfuncdisable(GPIO_ALT_CCIR656_OUTPUT,"sva")) + dbgprintk(3,"error:nomadik_gpio_altfuncdisable() failed : CCIR656 o/p\n"); + init_done = 0; + sva.active_tvout = NULL; + } + up(&hcl_mutex); + + + dbgprintk(1,"%s() exit\n",__FUNCTION__); + return 0; +} +EXPORT_SYMBOL(sva_delete_service); + +int +sva_q_buffer(struct sva_device_open *open, struct sva_queue_buffer *qbuf) +{ + struct sva_buffer_info *buf_info; + struct sva_service_open *srv; + struct sva_device_open *shared_open; + struct sva_queue *qdata = NULL; + + srv = open->service_open_data[qbuf->service_id]; + dbgprintk(1,"Inside queue_buffer for SERVICE %d, index %d, buffer %d\n" + ,qbuf->service_id, srv->index, qbuf->buffer.buffer_id); + + if(unlikely(qbuf->service_id < 0 || qbuf->service_id >= MAX_SERVICE_OPENS || + !open->service_open_data[qbuf->service_id])) { + dbgprintk(3," queue_buffer fails for invalid SERVICE %d, buffer %d\n" + ,qbuf->service_id, qbuf->buffer.buffer_id); + return -EINVAL; + } + + if(unlikely(qbuf->buffer.buffer_id < 0 || qbuf->buffer.buffer_id >= MAX_BUFFERS) ) { + + dbgprintk(3," queue_buffer fails for SERVICE %d, invalid buffer %d\n" + ,qbuf->service_id, qbuf->buffer.buffer_id); + return -EINVAL; + } + + down(&open->open_lock); + if(qbuf->buffer.shared) { + //printk("In shared queue\n"); + shared_open = &sva.device_open[qbuf->buffer.index]; + + if(!shared_open->buffer_info[qbuf->buffer.buffer_id]) { + dbgprintk(3,"Invalid buffer info in SERVICE %d, buffer %d\n" + ,qbuf->service_id, qbuf->buffer.buffer_id); + up(&open->open_lock); + return -EINVAL; + + } + shared_open->buffer_info[qbuf->buffer.buffer_id]->buffer.flags &= ~BUF_FLAG_DONE; + +// printk("sq_buff %d cnt %d\n",qbuf->buffer.buffer_id, shared_open->buffer_info[qbuf->buffer.buffer_id]->buffer.count); + + if(shared_open->buffer_info[qbuf->buffer.buffer_id]->buffer.count == 0) { + + if(srv->type == SVA_VIDEO_ENCODER || srv->type == SVA_POSTPROCESSOR) { + shared_open->buffer_info[qbuf->buffer.buffer_id]->buffer.flags &= BUF_FLAG_QUEUED_RO; + } else { + shared_open->buffer_info[qbuf->buffer.buffer_id]->buffer.flags &= BUF_FLAG_QUEUED; + } + shared_open->buffer_info[qbuf->buffer.buffer_id]->buffer.count++; + }else{ + if(shared_open->buffer_info[qbuf->buffer.buffer_id]->buffer.flags & BUF_FLAG_QUEUED_RO == BUF_FLAG_QUEUED_RO ) { + if(srv->type == SVA_VIDEO_ENCODER || srv->type == SVA_POSTPROCESSOR) { + shared_open->buffer_info[qbuf->buffer.buffer_id]->buffer.count++; + } else { + dbgprintk(3,"shared RO queue_buffer fails for SERVICE %d, buffer %d already queued\n" + ,qbuf->service_id, qbuf->buffer.buffer_id); + up(&open->open_lock); + return -EINVAL; + } + + }else{ + dbgprintk(3,"shared queue_buffer fails for SERVICE %d, buffer %d already queued\n" + ,qbuf->service_id, qbuf->buffer.buffer_id); + up(&open->open_lock); + return -EINVAL; + } + + } + buf_info = shared_open->buffer_info[qbuf->buffer.buffer_id]; + } else { + + buf_info = open->buffer_info[qbuf->buffer.buffer_id]; + +// printk("q_buff %d cnt %d\n", qbuf->buffer.buffer_id, buf_info->buffer.count); + + if(!open->buffer_info[qbuf->buffer.buffer_id] || + (open->buffer_info[qbuf->buffer.buffer_id]->buffer.flags & BUF_FLAG_QUEUED) + == BUF_FLAG_QUEUED) { + dbgprintk(3," queue_buffer fails for SERVICE %d, buffer %d already queued\n" + ,qbuf->service_id, qbuf->buffer.buffer_id); + up(&open->open_lock); + return -EINVAL; + } + + if(buf_info->buffer.flags & BUF_FLAG_QUEUED_RO) { + printk("RO_IS_ENABLED\n"); + } + buf_info->buffer.count++; + buf_info->buffer.flags &= ~BUF_FLAG_DONE; + buf_info->buffer.flags |= BUF_FLAG_QUEUED; + + } /* End if shared buffer */ + +// buf_info = open->buffer_info[qbuf->buffer.buffer_id]; +// buf_info->buffer.flags &= ~BUF_FLAG_DONE; +// buf_info->buffer.flags |= BUF_FLAG_QUEUED; + up(&open->open_lock); + srv = open->service_open_data[qbuf->service_id]; + + switch(qbuf->buffer.type) { + + case BUF_TYPE_IMAGE: + if(qbuf->push==PUSH_IN) { + qdata = &srv->in_image_buf_q->input_q; + } else { + if(srv->type == SVA_VIDEO_DECODER && + buf_info->buffer.read_only==1) + qdata = &srv->readonly_image_buf_q->input_q; + else if(srv->type == SVA_STILL_IMAGE_DECODER && + (buf_info->buffer.read_only==1)) + qdata = &srv->readonly_image_buf_q->input_q; + else + qdata = &srv->out_image_buf_q->input_q; + } + buf_info->buffer.timestamp = qbuf->buffer.timestamp; + break; + case BUF_TYPE_PARAMS: + if(qbuf->push==PUSH_IN) { + qdata = &srv->in_params_buf_q->input_q; + } else { + qdata = &srv->out_params_buf_q->input_q; + } + break; + case BUF_TYPE_INFOS: + if(qbuf->push==PUSH_IN) { + qdata = &srv->in_infos_buf_q->input_q; + } else { + qdata = &srv->out_infos_buf_q->input_q; + } + break; + case BUF_TYPE_BITSTREAM: + if(qbuf->push==PUSH_IN) { + qdata = &srv->in_coded_buf_q->input_q; + } else { + qdata = &srv->out_coded_buf_q->input_q; + } + break; + default: + dbgprintk(3,"error: Invalid buffer type\n"); + return -EINVAL; + } + + if(unlikely(!qdata)) { + buf_info->buffer.flags &= ~BUF_FLAG_QUEUED; + dbgprintk(3,"No such type of queue exists for this service \n"); + return -EINVAL; + } + + buf_info->push = qbuf->push; + buf_info->buffer.size = qbuf->buffer.size; + sva_q_add_tail(qdata, &buf_info->qnode); + + /* TODO: Add check for service whether it is in the activate state */ + + /* ignore for grab hq service ??? */ + if(!((srv->state & SERVICE_STARTED) == SERVICE_STARTED)){ + dbgprintk(2, "Not pushing buffer %d to input queue \n",buf_info->buffer.buffer_id); + return 0; + } + + if(buf_info->buffer.read_only==1 && qbuf->push == PUSH_OUT && qbuf->buffer.type == BUF_TYPE_IMAGE) { + return 0; /* this one is fake queue of buffer */ + } + + return push_buffer(srv, qbuf->buffer.type, qbuf->push); +} +EXPORT_SYMBOL(sva_q_buffer); + +int +sva_dqueue_buffer(struct sva_device_open *open, struct sva_queue_buffer *qbuf) +{ + struct sva_service_open *srv; + unsigned long timeout; + int err = 0; + struct sva_buffer_info *buf_info=NULL; + struct sva_queue_data *qdata = NULL; + + if(unlikely(qbuf->service_id < 0 || qbuf->service_id >= MAX_SERVICE_OPENS || + !open->service_open_data[qbuf->service_id])) + return -EINVAL; + + srv = open->service_open_data[qbuf->service_id]; + + dbgprintk(2,"Dequeue for SERVICE %lu\n",srv->service_id); + + /*if(unlikely(!((srv->state & SERVICE_STARTED) == SERVICE_STARTED))) + return -EINVAL;*/ + + switch(qbuf->buffer.type) { + + case BUF_TYPE_IMAGE: + if(qbuf->push==PUSH_IN) { + qdata = srv->in_image_buf_q; + } else { + qdata = srv->out_image_buf_q; + } + break; + case BUF_TYPE_PARAMS: + if(qbuf->push==PUSH_IN) { + qdata = srv->in_params_buf_q; + } else { + qdata = srv->out_params_buf_q; + } + break; + case BUF_TYPE_INFOS: + if(qbuf->push==PUSH_IN) { + qdata = srv->in_infos_buf_q; + } else { + qdata = srv->out_infos_buf_q; + } + break; + case BUF_TYPE_BITSTREAM: + if(qbuf->push==PUSH_IN) { + qdata = srv->in_coded_buf_q; + } else { + qdata = srv->out_coded_buf_q; + } + break; + default: + dbgprintk(3,"error: Invalid buffer type\n"); + return -EINVAL; + } + + if(unlikely(!qdata)) { + dbgprintk(3,"No queue found\n"); + return -EINVAL; + } + + if((sva_q_peek_head(&qdata->output_q) == NULL) + && sva_q_peek_head(&qdata->internal_q) == NULL) { + qbuf->buffer.buffer_id = MASK_ALL32; /* To signify dequeue not successful */ + return 0; + } + + /*if((sva_q_peek_head(&qdata->output_q) == NULL) + && sva_q_peek_head(&qdata->internal_q) == NULL) + return -EINVAL;*/ + + if(sva_q_peek_head(&qdata->output_q) != NULL) + goto success; + else if(qbuf->block == NON_BLOCK) { + qbuf->buffer.buffer_id = MASK_ALL32; /* To signify dequeue not successful */ + return 0; + } + + if(qbuf->block == BLOCK) { + + dbgprintk(1,"Waiting in BLOCK mode\n"); + err = wait_event_interruptible(qdata->output_wq, + sva_q_peek_head(&qdata->output_q) != NULL); + dbgprintk(1,"Wait in BLOCK mode over\n"); + + if(err) + return err; + + } + else { /* BLOCK_TIMEOUT */ + + timeout = qbuf->timeout * (HZ / 1000); + + err = wait_event_interruptible_timeout(qdata->output_wq, + sva_q_peek_head(&qdata->output_q) != NULL, timeout); + if(err < 0) + return err; + + if(sva_q_peek_head(&qdata->output_q) == NULL) + return -ETIME; + } + +success: + down(&open->open_lock); + buf_info = (struct sva_buffer_info *) sva_q_del_head(&qdata->output_q); + +#if 0 + if((srv->type == SVA_STILL_IMAGE_DECODER) + && ((buf_info->buffer.flags & BUF_FLAG_PARTLY_FILLED) == BUF_FLAG_PARTLY_FILLED) + && (srv->config.stillimagedecoder_info.configuration.no_slice_mode == FALSE ) ){ + sva_q_add_tail(&qdata->internal_q, &buf_info->qnode); + } + else{ + buf_info->buffer.flags &= ~BUF_FLAG_QUEUED; + buf_info->buffer.flags |= BUF_FLAG_DONE; + qbuf->buffer = buf_info->buffer; + } +#endif + +// printk("dq_buff %d cnt %d\n", buf_info->buffer_id, buf_info->buffer.count); + if(srv->type == SVA_VIDEO_ENCODER || srv->type == SVA_POSTPROCESSOR) { + buf_info->buffer.count--; + if(buf_info->buffer.count == 0) { + buf_info->buffer.flags &= ~BUF_FLAG_QUEUED_RO; + buf_info->buffer.flags |= BUF_FLAG_DONE; + } + } else { + buf_info->buffer.count--; + buf_info->buffer.flags &= ~BUF_FLAG_QUEUED; + buf_info->buffer.flags |= BUF_FLAG_DONE; + } + + qbuf->buffer = buf_info->buffer; + qbuf->buffer.phys_addr = (__u32) buf_info->buffer_addr.physical; + up(&open->open_lock); + { + int i = 0; + void *ptr; + while(i < MAX_MESSAGES && srv->messages_array[i].buffer_id !=buf_info->buffer_id) + i++; + if(i == MAX_MESSAGES) + dbgprintk(3,"error: Bug, message not found\n"); + else { + ptr = sva_q_yank_node(&srv->filled_message_queue, + &srv->messages_array[i].qnode); + if(!ptr) { + dbgprintk(3,"error: Bug, ptr message not found\n"); + } else { + srv->messages_array[i].buffer_id = -1; + srv->messages_array[i].message.buffer.buffer_id = -1; + sva_q_add_tail(&srv->empty_message_queue, + &srv->messages_array[i].qnode); + } + } + } + + /* FOR TVOUT */ + if(srv->type == SVA_TV_OUTPUT && !init_done) { + dbgprintk(2,"Initializing denc\n"); + sva.sva_platform_data->denc_init(srv->config.tvout_info.type); + init_done = 1; + } + + return 0; +} +EXPORT_SYMBOL(sva_dqueue_buffer); + +static int +sva_get_messages(void *open_id, void *arg) +{ + struct sva_service_open *srv; + unsigned long timeout; + struct sva_message msg; + struct sva_device_open *open; + int err = 0; + struct sva_queue *qptr = NULL; + + open = (struct sva_device_open *)open_id; + if(open->flags & O_NOIO) + return -EPERM; + + if(copy_from_user((void *)&msg, arg, sizeof(struct sva_message))){ + return -EACCES; + } + + if(msg.service_id < 0 || msg.service_id >= MAX_SERVICE_OPENS || + !open->service_open_data[msg.service_id]) + return -EINVAL; + + srv = open->service_open_data[msg.service_id]; + + qptr = &srv->filled_message_queue; + + if(sva_q_peek_head(qptr) != NULL) + goto success; + else if(msg.block == NON_BLOCK) { + msg.msg_count = 0; /* To signify no messages were removed */ + if(copy_to_user(arg, (void *)&msg, sizeof(struct sva_message))) + return -EACCES; + return 0; + } + + if(msg.block == BLOCK) { + err = wait_event_interruptible(srv->message_wq, + sva_q_peek_head(qptr) != NULL); + if(err) + return err; + + goto success; + } + else { /* BLOCK_TIMEOUT */ + timeout = msg.timeout * (HZ / 1000); + + err = wait_event_interruptible_timeout(srv->message_wq, + sva_q_peek_head(qptr) != NULL, timeout); + if(err) + return err; + + if(sva_q_peek_head(qptr) != NULL) + goto success; + else { + msg.msg_count = 0; /* To signify no messages were removed */ + msg.timeout = 0; + if(copy_to_user(arg, (void *)&msg, sizeof(struct sva_message))) + return -EACCES; + return -ETIME; + } + } + +success: + { + /* Got atleast 1 message */ + struct message_data msg_store[msg.msg_count]; + struct sva_message_data *msgp = NULL; + int indx = 0; + lock_critical_section(&hcl_mutex); + while(indx < msg.msg_count && + (msgp = (struct sva_message_data *)sva_q_del_head(qptr)) != NULL) { + msg_store[msg.msg_count] = msgp->message; + kfree(msgp); + msgp = NULL; + indx++; + } + unlock_critical_section(&hcl_mutex); + + if(indx) + if(copy_to_user((void *)msg.messages, (void *) msg_store, + indx * sizeof(struct message_data))) + return -EACCES; + msg.msg_count = indx; + if(copy_to_user(arg,(void *) &msg, sizeof(struct message_data))) + return -EACCES; + return 0; + } +} + +static inline int +update_preprocessor_service(struct sva_service_open *srv_open, t_uint32 value, + t_sva_preprocessor_param_id param, t_sva_update_cmd_type type) +{ + t_sva_error error; + + lock_critical_section(&hcl_mutex); + error = SVA_UpdatePreProcessorParams(srv_open->service_id,type, + param, value); + + unlock_critical_section(&hcl_mutex); + + if(error != SVA_OK) + return -EINVAL; + + return 0; +} + +static inline int +update_postprocessor_service(struct sva_service_open *srv_open, t_uint32 value, + t_sva_postprocessor_param_id param, t_sva_update_cmd_type type) +{ + t_sva_error error; + + lock_critical_section(&hcl_mutex); + error = SVA_UpdatePostProcessorParams(srv_open->service_id, type, + param, (t_uint32 *)value); + + unlock_critical_section(&hcl_mutex); + + if(error < SVA_OK) { + dbgprintk(3,"Update postprocessor failed %d\n",error); + return -EINVAL; + } + + return 0; +} + +int +allocate_buffer(struct sva_device_open *open, struct sva_buffer *buf) +{ + /*dma_addr_t phy_addr;*/ + t_sva_error sva_error; + t_sva_buffer_type buffer_type; + struct sva_buffer_info *buf_info = NULL; + int indx = 0; + int vc1_flag=0; + + buffer_type = 0; +/* +// if(!((buf->type > BUF_TYPE_NONE) && (buf->type <= BUF_TYPE_PARAMS))) { + if(!((buf->type > BUF_TYPE_NONE) && (buf->type <= BUF_TYPE_VC1_IMAGE))) { + dbgprintk(3,"error: Unknown buffer type %d\n",buf->type); + return -EINVAL; + } +*/ + down(&open->open_lock); + while((indx < MAX_BUFFERS) && open->buffer_info[indx]) indx++; + + if(indx == MAX_BUFFERS) { + dbgprintk(3,"error: Cannot allocate more than %d buffers\n",MAX_BUFFERS); + up(&open->open_lock); + return -EINVAL; + } + + open->buffer_info[indx] = kzalloc(sizeof(struct sva_buffer_info), GFP_KERNEL); + + if(!open->buffer_info[indx]) { + dbgprintk(3,"error: kmalloc for buffer struct failed\n"); + up(&open->open_lock); + return -ENOMEM; + } + + memset(open->buffer_info[indx], 0, sizeof(struct sva_buffer_info)); + + buf_info = open->buffer_info[indx]; + buf_info->buffer_usage = 0xff; /* non vc1 & non gb-hq */ + switch(buf->type) { + + case BUF_TYPE_IMAGE: + buffer_type = SVA_IMAGE_BUFFER_TYPE; + break; + + case BUF_TYPE_BITSTREAM: + buffer_type = SVA_BITSTREAM_BUFFER_TYPE; + break; + + case BUF_TYPE_INFOS: + buffer_type = SVA_INFOS_BUFFER_TYPE; + break; + + case BUF_TYPE_PARAMS: + buffer_type = SVA_PARAMS_BUFFER_TYPE; + break; + + case BUF_TYPE_VC1_IMAGE: + lock_critical_section(&hcl_mutex); + sva_error = SVA_AllocDedicatedBuffer(SVA_VC1_DEDICATED_BUFFER, + SVA_IMAGE_BUFFER_TYPE, buf->size, &buf_info->buffer_addr, + &buf_info->buffer_id); + unlock_critical_section(&hcl_mutex); + if(unlikely(sva_error != SVA_OK)) { + dbgprintk(3,"error: SVA_AllocDedicatedBuffer() failed, error: %d\n",sva_error); + return -EINVAL; + } +// buffer_type = SVA_INTERNAL_BUFFER_TYPE; /* for indicating vc1 buffer */ + buffer_type = SVA_IMAGE_BUFFER_TYPE; + buf->type = BUF_TYPE_IMAGE; + buf_info->buffer_usage = SVA_VC1_DEDICATED_BUFFER; + vc1_flag =1; + break; + +#define GRID_BUFFER_SIZE 66*50*2*4 + case BUF_TYPE_GB_HQ_PARAMS: + dbgprintk(2,"allocating SVA_GB_HQ_DEDICATED_BUFFER param buffer \n"); + buf->size = GRID_BUFFER_SIZE; + lock_critical_section(&hcl_mutex); + sva_error = SVA_AllocDedicatedBuffer(SVA_GB_HQ_DEDICATED_BUFFER, + SVA_PARAMS_BUFFER_TYPE, GRID_BUFFER_SIZE, &buf_info->buffer_addr, + &buf_info->buffer_id); + unlock_critical_section(&hcl_mutex); + if(unlikely(sva_error != SVA_OK)) { + dbgprintk(3,"error: SVA_AllocDedicatedBuffer() failed, error: %d\n",sva_error); + return -EINVAL; + } + buffer_type = SVA_PARAMS_BUFFER_TYPE; + buf->type = BUF_TYPE_PARAMS; + buf->length = ((buf->size + (PAGE_SIZE - 1)) >> PAGE_SHIFT) * PAGE_SIZE; + + buf_info->buffer_usage = SVA_GB_HQ_DEDICATED_BUFFER; + buf_info->buffer_type = buffer_type; + goto buffer_allocated; + + default: + dbgprintk(3,"error: Invalid buffer type\n"); + return -EINVAL; + } + + buf_info->buffer_type = buffer_type; + buf->length = ((buf->size + (PAGE_SIZE - 1)) >> PAGE_SHIFT) * PAGE_SIZE; + +#ifdef CONFIG_NOMADIK_SVA_INIT_MEM + if(buf_info->buffer_usage != SVA_VC1_DEDICATED_BUFFER){ + lock_critical_section(&hcl_mutex); + sva_error = SVA_AllocBuffer(buffer_type, buf->length, &buf_info->buffer_addr, + &buf_info->buffer_id); + unlock_critical_section(&hcl_mutex); + if(sva_error != SVA_OK) { + dbgprintk(3,"error: SVA_AllocBuffer() failed, error: %d\n",sva_error); + open->buffer_info[indx]->buffer_addr.logical = NULL; + open->buffer_info[indx]->buffer_addr.physical = NULL; + kfree(open->buffer_info[indx]); + open->buffer_info[indx] = NULL; + up(&open->open_lock); + return -EINVAL; + } + } +#else + if(buf_info->buffer_usage != SVA_VC1_DEDICATED_BUFFER){ + + buf_info->gfp_address = __get_free_pages(GFP_KERNEL, get_order(buf->length)); + if(!buf_info->gfp_address) { + printk("Buffer GFP failed\n"); + kfree(buf_info); + open->buffer_info[indx] = NULL; + up(&open->open_lock); + return -ENOMEM; + } + buf_info->buffer_addr.physical = (t_uint32) buf_info->gfp_address - PAGE_OFFSET; + buf_info->buffer_addr.logical = (__u32) ioremap(buf_info->buffer_addr.physical, buf->length); +/* buf_info->buffer_addr.logical = + (t_uint32 )dma_alloc_coherent(&sva.p_dev->dev, buf->length, + &phy_addr, GFP_KERNEL|GFP_DMA);*/ + + if(!(buf_info->buffer_addr.logical)) { + dbgprintk(3,"error: consistent_alloc for buffer memory failed\n"); + free_pages(buf_info->gfp_address, get_order(buf_info->buffer.length)); + kfree(buf_info); + open->buffer_info[indx] = NULL; + up(&open->open_lock); + return -ENOMEM; + } + + //buf_info->buffer_addr.physical = (t_uint32) phy_addr; + //buf_info->buffer_addr.physical = (t_uint32) buf_info->buffer_addr.logical - PAGE_OFFSET; + + lock_critical_section(&hcl_mutex); + sva_error = SVA_DefineBuffer(buffer_type, buf->length, buf_info->buffer_addr, + &buf_info->buffer_id); + unlock_critical_section(&hcl_mutex); + if(sva_error != SVA_OK) { + dbgprintk(3,"error: SVA_DefineBuffer() failed, error: %d\n",sva_error); + iounmap((void *)buf_info->buffer_addr.logical); + free_pages(buf_info->gfp_address, get_order(buf_info->buffer.length)); + /*dma_free_coherent(&sva.p_dev->dev, (size_t) buf->length, + (void *) buf_info->buffer_addr.logical, phy_addr); */ + open->buffer_info[indx]->buffer_addr.logical = NULL; + open->buffer_info[indx]->buffer_addr.physical = NULL; + kfree(open->buffer_info[indx]); + open->buffer_info[indx] = NULL; + up(&open->open_lock); + return -EINVAL; + } + } +#endif +buffer_allocated: + buf->buffer_id = indx; + buf->offset = (indx << PAGE_SHIFT); + /* Reset some values to default */ + buf->flags = 0; + buf->timestamp = 0; + buf->read_only = 0; + buf->shared = 0; + buf->count = 0; + SVA_SetBufferData(buf_info->buffer_id, (t_uint32)open->buffer_info[indx]); + open->buffer_info[indx]->buffer = *buf; + up(&open->open_lock); + return 0; +} +EXPORT_SYMBOL(allocate_buffer); + +int +deallocate_buffer(struct sva_device_open *open, unsigned long *buf) +{ + struct sva_buffer_info *buf_info; + t_sva_error sva_error; + if(*buf > MAX_BUFFERS || !open->buffer_info[*buf]) + return -EINVAL; + + down(&open->open_lock); + buf_info = open->buffer_info[*buf]; + + if((buf_info->buffer.flags & BUF_FLAG_MAPPED) == BUF_FLAG_MAPPED) { + dbgprintk(3,"error:Buffer %ld not unmapped\n",*buf); + up(&open->open_lock); + return -EINVAL; + } + + if((buf_info->buffer.flags & BUF_FLAG_QUEUED) == BUF_FLAG_QUEUED) { + dbgprintk(3,"error:Buffer %ld not dequeued\n",*buf); + up(&open->open_lock); + return -EINVAL; + } + + if(buf_info->buffer_usage == SVA_VC1_DEDICATED_BUFFER) { + + if(buf_info->buffer.read_only == 1) { + dbgprintk(3, "error: Buffer %ld is not dequeued & its readonly \n", *buf); + return -EINVAL; + } + lock_critical_section(&hcl_mutex); + sva_error = SVA_FreeDedicatedBuffer(SVA_VC1_DEDICATED_BUFFER, buf_info->buffer_id); + unlock_critical_section(&hcl_mutex); + if(unlikely(sva_error!=SVA_OK)) + dbgprintk(3,"error: Error freeing vc1 buffer %ld\n",*buf); + } else if (buf_info->buffer_usage == SVA_GB_HQ_DEDICATED_BUFFER) { + dbgprintk(2,"Freeing GB_HQ dedicated buffer %ld \n", buf_info->buffer_id); + lock_critical_section(&hcl_mutex); + sva_error = SVA_FreeDedicatedBuffer(SVA_GB_HQ_DEDICATED_BUFFER, buf_info->buffer_id); + unlock_critical_section(&hcl_mutex); + if(unlikely(sva_error!=SVA_OK)) + dbgprintk(3,"error: Error %d freeing gb hq buffer %ld\n",sva_error,*buf); + } + else { +#ifdef CONFIG_NOMADIK_SVA_INIT_MEM + + lock_critical_section(&hcl_mutex); + sva_error = SVA_FreeBuffer(buf_info->buffer_id); + unlock_critical_section(&hcl_mutex); + if(sva_error) + dbgprintk(3,"error: Error removing hcl buffer %ld\n",*buf); +#else + lock_critical_section(&hcl_mutex); + sva_error = SVA_RemoveBuffer(buf_info->buffer_id); + unlock_critical_section(&hcl_mutex); + if(sva_error) + dbgprintk(3,"error: Error removing buffer %ld\n",*buf); + + iounmap((void *)buf_info->buffer_addr.logical); + free_pages(buf_info->gfp_address, get_order(buf_info->buffer.length)); +/* dma_free_coherent(&sva.p_dev->dev, buf_info->buffer.length, + (void *)buf_info->buffer_addr.logical, + (dma_addr_t)buf_info->buffer_addr.physical); */ +#endif + } + + kfree(buf_info); + open->buffer_info[*buf] = NULL; + up(&open->open_lock); + return 0; +} +EXPORT_SYMBOL(deallocate_buffer); + +int +sva_service_update(struct sva_device_open *open, struct sva_update_service *update) +{ + struct sva_service_open *srv_open; + t_sva_preprocessor_param_id preprocessor_param; + t_sva_postprocessor_param_id postprocessor_param; + t_sva_update_cmd_type cmd_type; + int err = 0; + + if(update->service_id < 0 || update->service_id >= MAX_SERVICE_OPENS) + return -EINVAL; + + srv_open = open->service_open_data[update->service_id]; + cmd_type = (t_sva_update_cmd_type) update->type; + + switch(update->param) { + t_uint32 value; + case PREPROCESSOR_CROP: + { + t_sva_window_desc win_desc; + struct sva_window_desc *win = update->value; + + if(srv_open->type != SVA_PREPROCESSOR) + return -EINVAL; + + win_desc.image.height = win->frame.height; + win_desc.image.width = win->frame.width; + win_desc.imageOffset.offsetX = win->offset.x_offset; + win_desc.imageOffset.offsetY = win->offset.y_offset; + value = (t_uint32) &win_desc; + preprocessor_param = SVA_PREPROCESSOR_CROPPING; + err = update_preprocessor_service(srv_open, value, + preprocessor_param, cmd_type); + break; + } + + case PREPROCESSOR_RESIZE: + { + t_sva_image_desc img_desc; + struct sva_image *img = update->value; + + if(srv_open->type != SVA_PREPROCESSOR) + return -EINVAL; + + img_desc.height = img->height; + img_desc.width = img->width; + value = (t_uint32) &img_desc; + preprocessor_param = SVA_PREPROCESSOR_RESIZE; + err = update_preprocessor_service(srv_open, value, + preprocessor_param, cmd_type); + break; + } + + case PREPROCESSOR_ACE_STRENGTH: + { + t_sva_ace_strength ace_strength; + enum sva_ace_strength *strength = update->value; + + if(srv_open->type != SVA_PREPROCESSOR) + return -EINVAL; + + + ace_strength = *strength; + value = (t_uint32) ace_strength; + preprocessor_param = SVA_PREPROCESSOR_ACE_STRENGTH; + err = update_preprocessor_service(srv_open, value, + preprocessor_param, cmd_type); + break; + } + + case PREPROCESSOR_ACE_RANGE: + { + t_sva_color_range ace_range; + enum sva_color_range *range = update->value; + + if(srv_open->type != SVA_PREPROCESSOR) + return -EINVAL; + + + ace_range = *((t_sva_color_range *)range); + value = (t_uint32) ace_range; + preprocessor_param = SVA_PREPROCESSOR_ACE_RANGE; + err = update_preprocessor_service(srv_open, value, + preprocessor_param, cmd_type); + break; + } + + case PREPROCESSOR_OUTPUT_RANGE: + { + t_sva_color_range color_range; + enum sva_color_range *range = update->value; + + if(srv_open->type != SVA_PREPROCESSOR) + return -EINVAL; + + + color_range = *((t_sva_color_range *)range); + value = (t_uint32) color_range; + preprocessor_param = SVA_PREPROCESSOR_OUTPUT_RANGE; + err = update_preprocessor_service(srv_open, value, + preprocessor_param, cmd_type); + break; + } + + case PREPROCESSOR_ACE_OFFSET: + { + t_sva_ace_offset ace_offset; + enum sva_color_range *off = update->value; + + if(srv_open->type != SVA_PREPROCESSOR) + return -EINVAL; + + + ace_offset = *((t_sva_ace_offset*)off); + value = (t_uint32) &ace_offset; + preprocessor_param = SVA_PREPROCESSOR_ACE_OFFSET; + err = update_preprocessor_service(srv_open, value, + preprocessor_param, cmd_type); + break; + } + /*vpip -start*/ + case PREPROCESSOR_ZOOM_IN: + case PREPROCESSOR_ZOOM_OUT: + case PREPROCESSOR_CONTRAST: + case PREPROCESSOR_COLOUR_SATURATION: + case PREPROCESSOR_WHITEBALANCE: + case PREPROCESSOR_COLMATRIX_DAMPING: + case PREPROCESSOR_EXPOSURE: + case PREPROCESSOR_ENABLE_FUNCBLOCK: + case PREPROCESSOR_FADETOBLACK: + case PREPROCESSOR_RADIAL_PEAKING: + { + u16 update_value; + if(srv_open->grab_type!=GRAB_IRP) + return -EINVAL; + dbgprintk(1,"updating irp service Now \n"); + + /* do IRP related updations */ + update_value = *(__u16 *)update->value; + if(irp_update_service(srv_open, update->param, update_value)) { + dbgprintk(3,"Failed to update IRP parameter \n"); + return -EAGAIN; + } + break; + } + /*vpip-end*/ + case POSTPROCESSOR_CONTRAST: + { + t_uint8 contrast = *((t_uint8 *)update->value); + + if(srv_open->type != SVA_POSTPROCESSOR) + return -EINVAL; + + if(contrast > 99) + return -EINVAL; + + value = (t_uint32) &contrast; + postprocessor_param = SVA_POSTPROCESSOR_CONTRAST; + err = update_postprocessor_service(srv_open, value, + postprocessor_param, SVA_UPDATE_LAST); + break; + } + + case POSTPROCESSOR_BRIGHTNESS: + { + t_uint8 brightness = *((t_uint8 *)update->value); + + if(srv_open->type != SVA_POSTPROCESSOR) + return -EINVAL; + + if(brightness > 99) + return -EINVAL; + + value = (t_uint32) &brightness; + postprocessor_param = SVA_POSTPROCESSOR_BRIGHTNESS; + err = update_postprocessor_service(srv_open, value, + postprocessor_param, SVA_UPDATE_LAST); + break; + } + +//#ifdef PPP_TILE_PATCH + case POSTPROCESSOR_TILE: + { + + + t_sva_ppp_tile_info ppp_tile; + t_sva_ppp_tile_info **link_tile; + struct sva_ppp_tile_info *tile_info; + t_sva_ppp_tile_info *next; + t_sva_ppp_tile_info *tmp; + + tile_info = (struct sva_ppp_tile_info *)update->value; + + if(tile_info && (!tile_info->image.height || !tile_info->image.width)) + tile_info = NULL; + + if(tile_info) { + ppp_tile.image.height = tile_info->image.height; + ppp_tile.image.width = tile_info->image.width; + ppp_tile.imageOffset.offsetX = tile_info->offset.x_offset; + ppp_tile.imageOffset.offsetY = tile_info->offset.y_offset; + ppp_tile.next_tile = NULL; + link_tile = (void *)&ppp_tile.next_tile; + + while(tile_info->next_tile) { + + tile_info = tile_info->next_tile; + next = kzalloc(sizeof(t_sva_ppp_tile_info), GFP_KERNEL); + if(!next) { + dbgprintk(3,"Could not allocate memory for tile\n"); + return -ENOMEM; + } + + next->image.height = tile_info->image.height; + next->image.width = tile_info->image.width; + next->imageOffset.offsetX = tile_info->offset.x_offset; + next->imageOffset.offsetY = tile_info->offset.y_offset; + *link_tile = next; + link_tile = (void *)&next->next_tile; + } + } else { + memset(&ppp_tile, 0, sizeof(ppp_tile)); + } + + value = (t_uint32)&ppp_tile; + postprocessor_param = SVA_POSTPROCESSOR_PPP_TILE; + + err=update_postprocessor_service(srv_open,value, + postprocessor_param, UPDATE_LAST); + + next = ppp_tile.next_tile; + while(next) { + tmp = next->next_tile; + kfree(next); + next = tmp; + } + + + break; + } +//#endif + case POSTPROCESSOR_PIP: + { + t_sva_window_desc win_desc; + struct sva_window_desc *win; + int width; + + if(srv_open->type != SVA_POSTPROCESSOR) + return -EINVAL; + + width=srv_open->config.postprocessor_info.configuration.resizedImageDesc.width; + + postprocessor_param = SVA_POSTPROCESSOR_PIP; + if(update->value) { + win = (struct sva_window_desc *) update->value; + if(win->frame.width >= width) + return -EINVAL; + + if(srv_open->config.postprocessor_info.pip_activated) { + memset(&win_desc, 0, sizeof(win_desc)); + value = (t_uint32) &win_desc; + err=update_postprocessor_service(srv_open,value, + postprocessor_param, SVA_UPDATE_LAST); + if(err) + break; + + srv_open->config.postprocessor_info.pip_activated=0; + if(win->frame.width == 0) + break; /* Already deactivated */ + } + + win_desc.image.height = win->frame.height; + win_desc.image.width = win->frame.width; + win_desc.imageOffset.offsetX = win->offset.x_offset; + win_desc.imageOffset.offsetY = win->offset.y_offset; + value = (t_uint32) &win_desc; + } else { + return -EINVAL; + } + + err=update_postprocessor_service(srv_open,value, + postprocessor_param, UPDATE_LAST); + if(!err) { + if(win_desc.image.width == 0) + srv_open->config.postprocessor_info.pip_activated = 0; + else + srv_open->config.postprocessor_info.pip_activated = 1; + } + + break; + } + + case POSTPROCESSOR_CROP: + { + t_sva_window_desc win; + struct sva_window_desc *win_desc = update->value; + + if(srv_open->type != SVA_POSTPROCESSOR) + return -EINVAL; + + win.image.height = win_desc->frame.height; + win.image.width = win_desc->frame.width; + win.imageOffset.offsetX = win_desc->offset.x_offset; + win.imageOffset.offsetY = win_desc->offset.y_offset; + value = (t_uint32) &win; + postprocessor_param = SVA_POSTPROCESSOR_CROPPING; + err = update_postprocessor_service(srv_open, value, + postprocessor_param, cmd_type); + break; + } + + case POSTPROCESSOR_CLIP: + { + t_sva_window_desc win; + struct sva_window_desc *win_desc = update->value; + + if(srv_open->type != SVA_POSTPROCESSOR) + return -EINVAL; + + win.image.height = win_desc->frame.height; + win.image.width = win_desc->frame.width; + win.imageOffset.offsetX = win_desc->offset.x_offset; + win.imageOffset.offsetY = win_desc->offset.y_offset; + value = (t_uint32) &win; + postprocessor_param = SVA_POSTPROCESSOR_CLIPPING; + err = update_postprocessor_service(srv_open, value, + postprocessor_param, cmd_type); + break; + } + + case POSTPROCESSOR_RESIZE: + { + t_sva_image_desc img_desc; + struct sva_image *img = update->value; + + if(srv_open->type != SVA_POSTPROCESSOR) + return -EINVAL; + + img_desc.height = img->height; + img_desc.width = img->width; + value = (t_uint32) &img_desc; + postprocessor_param = SVA_POSTPROCESSOR_RESIZE; + err = update_postprocessor_service(srv_open, value, + postprocessor_param, cmd_type); + break; + } + + default : + err = -EINVAL; + + + } /* End switch */ + + return err; + +} +EXPORT_SYMBOL(sva_service_update); + +int +process_ioctl(void *open_id, unsigned int cmd, void *arg) +{ + int ret_val = 0; + struct sva_device_open *open = open_id; + if(!open) + return -EINVAL; + + switch(cmd) { + case SVA_CREATE_SERVICE: + { + struct sva_service_struct * service = (struct sva_service_struct *)arg; + if(open->flags & O_NOIO) { + ret_val = -EPERM; + break; + } + + dbgprintk(2,"CREATE_SERVICE:Size of structure %d\n", + sizeof(struct sva_service_struct)); + ret_val = create_service(open, service); + if(ret_val) + break; + + ret_val = configure_service(open, service); + if(ret_val){ + service->service_id = -1; + break; + } + + break; + } + + case SVA_CONTROL_SERVICE: + { + struct sva_control_service *service = arg; + if(open->flags & O_NOIO) { + ret_val = -EPERM; + break; + } + + dbgprintk(2,"CONTROL_SERVICE:Size of structure %d\n", + sizeof(struct sva_control_service)); + ret_val = sva_service_control(open, service); + break; + } + + case SVA_UPDATE_SERVICE: + { + struct sva_update_service *update_srv = arg; + if(open->flags & O_NOIO) { + ret_val = -EPERM; + break; + } + + ret_val = sva_service_update(open, update_srv); + break; + } + + case SVA_ALLOCATE_BUFFER: + { + struct sva_buffer * buf = arg; + if(open->flags & O_NOIO) { + ret_val = -EPERM; + break; + } + + dbgprintk(2,"ALLOCATE_BUFFER:Size of structure %d\n", + sizeof(struct sva_buffer)); + ret_val = allocate_buffer(open, buf); + break; + } + + case SVA_DEALLOCATE_BUFFER: + { + unsigned long *buffer_id = arg; + dbgprintk(2,"DEALLOCATE_BUFFER:Size of structure %d\n", + sizeof(unsigned long)); + ret_val = deallocate_buffer(open, buffer_id); + + break; + } + + case SVA_DELETE_SERVICE: + { + struct sva_service_struct * service = arg; + if(open->flags & O_NOIO) { + ret_val = -EPERM; + break; + } + + ret_val = sva_delete_service(open, service); + break; + } + + case SVA_QUEUE_BUFFER: + { + struct sva_queue_buffer *buf = arg; + if(open->flags & O_NOIO) { + ret_val = -EPERM; + break; + } + + dbgprintk(2,"QUEUE_BUFFER:Size of structure %d\n", + sizeof(struct sva_queue_buffer)); + ret_val = sva_q_buffer(open, buf); + break; + + } + + case SVA_DEQUEUE_BUFFER: + { + struct sva_queue_buffer *buf = arg; + if(open->flags & O_NOIO) { + ret_val = -EPERM; + break; + } + + dbgprintk(2,"DEQUEUE_BUFFER:Size of structure %d\n",sizeof(struct sva_queue_buffer)); + ret_val = sva_dqueue_buffer(open, buf); + break; + + } + + case SVA_END_BITSTREAM: + { +/* + t_sva_error sva_error; + t_sva_service_id service_id; + unsigned int *srv_id = arg; + + if(open->flags & O_NOIO) { + ret_val = -EPERM; + break; + } + + if(open->service_open_data[*srv_id]) + service_id=open->service_open_data[*srv_id]->service_id; + else { + ret_val=-EINVAL; + break; + } + + sva_error = SVA_AssertEndOfBitstream(service_id); + if(sva_error != SVA_OK) { + dbgprintk(3,"error Assert end of bitstream failed,\ + service %d\n",*srv_id); + ret_val=-EINVAL; + } +*/ + ret_val = SVA_OK; + break; + + } + + case SVA_SET_HEADER: + { + t_sva_error sva_error; + t_sva_video_decoder_algo_Mpeg2_header_infos mpeg2_infos; + t_sva_video_decoder_algo_mpeg4_header_infos mpeg4_infos; + t_sva_video_decoder_algo_vc1_header_infos vc1_infos; + struct h264_slice_header_infos psheader, *tmp; + t_sva_video_decoder_algo_h264_slice_header_infos *tpsheader; + int i; + struct sva_service_open *srv_open=NULL; + t_sva_header_infos *infos=NULL; + struct sva_buffer_info *buf_info=NULL; + __u32 bitstream_address = 0; + __u32 bitstream_offset = 0; + struct sva_codec_header_infos *pinfo = arg; + + if(open->flags & O_NOIO) { + ret_val = -EPERM; + break; + } + + if(pinfo->service_id >= MAX_SERVICE_OPENS || pinfo->service_id < 0 || + !(open->service_open_data[pinfo->service_id])) { + dbgprintk(3,"error: Invalid service id %lu\n",(unsigned long)pinfo->service_id); + ret_val = -EINVAL; + break; + } + srv_open = open->service_open_data[pinfo->service_id]; + + if(pinfo->buffer_id < 0 || pinfo->buffer_id >= MAX_BUFFERS || + !open->buffer_info[pinfo->buffer_id]) { + dbgprintk(3,"error: Invalid buffer id %lu\n",(unsigned long)pinfo->buffer_id); + ret_val = -EINVAL; + break; + } + buf_info = open->buffer_info[pinfo->buffer_id]; + + if(srv_open->config.videodecoder_info.configuration.transformId + == SVA_DECODER_MPEG4_SP_L4A) { + + mpeg4_infos.pictureCodingType=pinfo->infos.mpeg4.picture_coding_type; + mpeg4_infos.quant=pinfo->infos.mpeg4.quantization; + mpeg4_infos.roundingType=pinfo->infos.mpeg4.rounding_type; + mpeg4_infos.intraDcVlcThr=pinfo->infos.mpeg4.intra_acdc_thr; + mpeg4_infos.vopFcodeForward=pinfo->infos.mpeg4.vop_fcode_forward; + + /** SVA 8.0.0 migration + for support of advanced simple profile*/ + /** + SVA 8.0.0 is conduting error checking on this flag + and failing if this vopFcodeBackward flag is zero + please make sure always this flag should be between 1 to 7 + */ + mpeg4_infos.vopFcodeBackward=pinfo->infos.mpeg4.vop_fcode_backward; + + /** Give default values for SH & SP */ + mpeg4_infos.vop_time_increment= pinfo->infos.mpeg4.vop_time_increment; + mpeg4_infos.modulo_time_base= pinfo->infos.mpeg4.modulo_time_base; + + /** SVA 8.0.0 migration ~ ends */ + + + bitstream_address=pinfo->infos.mpeg4.bitstream_address; + bitstream_offset=pinfo->infos.mpeg4.bitstream_offset; + infos = &mpeg4_infos; + + + } else if(srv_open->config.videodecoder_info.configuration.transformId + == SVA_DECODER_H264) { + + int indx; + t_sva_video_decoder_algo_h264_header_infos *ph264_infos = + &srv_open->config.videodecoder_info.h264_infos; + + ph264_infos->chromaQpIndex = pinfo->infos.h264.chroma_qp_index; + ph264_infos->constrIntraPredFlag = pinfo->infos.h264.constr_intra_pred_flag; + + ph264_infos->numRefIdxl0ActiveMinus1 = + pinfo->infos.h264.num_ref_idx_l0_active_minus1; + + ph264_infos->slice0SliceGroupChangeCycle = + pinfo->infos.h264.slice_0_slice_group_change_cycle; + + ph264_infos->numSliceGroupsMinus1 = + pinfo->infos.h264.num_slice_groups_minus1; + + ph264_infos->sliceGroupMapType = + pinfo->infos.h264.slice_group_map_type; + + for(indx=0; indx<8; indx++) { + + ph264_infos->runLenghtMinus1[indx] = pinfo->infos.h264.run_lenght_minus1[indx]; + ph264_infos->topLeft[indx] = pinfo->infos.h264.top_left[indx]; + ph264_infos->bottomRight[indx] = pinfo->infos.h264.bottom_right[indx]; + + } + + ph264_infos->sliceGroupChangeDirFlag = + pinfo->infos.h264.slice_group_change_dir_flag; + + ph264_infos->sliceGroupChangeRateMinus1 = + pinfo->infos.h264.slice_group_change_rate_minus1; + + for(indx=0; indx<1620; indx++) + ph264_infos->sliceGroupId[indx] = pinfo->infos.h264.slice_group_id[indx]; + + ph264_infos->slice0Nut = pinfo->infos.h264.slice_0_nut; + ph264_infos->slice0Nri = pinfo->infos.h264.slice_0_nri; + ph264_infos->slice0FrameNum = pinfo->infos.h264.slice_0_frame_num; + + ph264_infos->slice0PicOrderCntLsb = + pinfo->infos.h264.slice_0_pic_order_cnt_lsb; + ph264_infos->slice0DeltaPicOrderCnt[0] = + pinfo->infos.h264.slice_0_delta_pic_order_cnt[0]; + ph264_infos->slice0DeltaPicOrderCnt[1] = + pinfo->infos.h264.slice_0_delta_pic_order_cnt[1]; + ph264_infos->slice0DeltaPicOrderCntBottom = + pinfo->infos.h264.slice_0_delta_pic_order_cnt_bottom; + ph264_infos->slice0LongTermReferenceFlag = + pinfo->infos.h264.slice_0_long_term_reference_flag; + ph264_infos->slice0NoOutputOfPriorPicsFlag = + pinfo->infos.h264.slice_0_no_output_of_prior_pics_flag; + ph264_infos->slice0AdaptiveRefPicMarkingModeFlag = + pinfo->infos.h264.slice_0_adaptive_ref_pic_marking_mode_flag; + + for(indx=0; indx<16; indx++) { + + ph264_infos->slice0MemoryManagementControlOperation[indx] = + pinfo->infos.h264.slice_0_memory_management_control_operation[indx], + + ph264_infos->slice0DifferenceOfPicNumsMinus1[indx] = + pinfo->infos.h264.slice_0_difference_of_pic_nums_minus1[indx]; + + ph264_infos->slice0MarkingLongTermPicNum[indx] = + pinfo->infos.h264.slice_0_marking_long_term_pic_num[indx]; + + ph264_infos->slice0MaxLongTermFrameIdxPlus1[indx] = + pinfo->infos.h264.slice_0_max_long_term_frame_idx_plus1[indx]; + } + + ph264_infos->nbSlicesInFrame = pinfo->infos.h264.nb_slices_in_frame; + /*memcpy(&srv_open->config.videodecoder_info.h264_infos,&pinfo->infos.h264, + sizeof(t_sva_video_decoder_algo_h264_header_infos)); */ + + tpsheader = ph264_infos->pHeader; + if(!tpsheader) { + tpsheader = + kzalloc(sizeof(t_sva_video_decoder_algo_h264_slice_header_infos), + GFP_KERNEL); + } + + if(!tpsheader) { + dbgprintk(3,"err:Kzalloc for slice header failed\n"); + ret_val = -ENOMEM; + break; + } + + ph264_infos->pHeader = tpsheader; + + if(copy_from_user(&psheader, pinfo->infos.h264.pslice_header, sizeof(psheader))){ + ret_val = -EACCES; + break; + } + + for(i=0; iconfig.videodecoder_info.h264_infos.nbSlicesInFrame;i++) { + + tpsheader->nut = psheader.nut; + tpsheader->nri = psheader.nri; + tpsheader->sliceSize = psheader.slice_size; + tpsheader->sliceBetaOffsetDiv2 = psheader.slice_beta_offset_div2; + tpsheader->firstMbInSlice = psheader.first_mb_in_slice; + tpsheader->sliceType = psheader.slice_type; + tpsheader->sliceQpDelta = psheader.slice_qp_delta; + tpsheader->sliceNum = psheader.slice_num; + tpsheader->sliceQp = psheader.slice_qp; + tpsheader->frameNum = psheader.frame_num; + + tpsheader->numRefIdx10ActiveMinus1 = + psheader.num_ref_idx_10_active_minus1; + + tpsheader->disableDeblockingFilterIdc = + psheader.disable_deblocking_filter_idc; + + tpsheader->sliceAlphaC0OffsetDiv2 = + psheader.slice_alpha_c0_offset_div2; + + tpsheader->numRefIdxActiveOverrideFlag = + psheader.num_ref_idx_active_override_flag; + + tpsheader->refPicListReorderingFlagl0 = + psheader.ref_pic_list_reordering_flag_l0; + + for(indx=0; indx<16; indx++) { + + tpsheader->reorderingOfPicNumsIdc[indx] = + psheader.reordering_of_pic_nums_idc[indx]; + + tpsheader->absDiffPicNumMinus1[indx] = + psheader.abs_diff_pic_num_minus1[indx]; + + tpsheader->longTermPicNum[indx] = + psheader.long_term_pic_num[indx]; + } + + tpsheader->sliceStartAddress.logical = + buf_info->buffer_addr.logical + psheader.slice_start_offset; + + tpsheader->sliceStartAddress.physical = + buf_info->buffer_addr.physical + psheader.slice_start_offset; + + tpsheader->sliceOffset = psheader.slice_bits_offset; + + if((i + 1) >= ph264_infos->nbSlicesInFrame) + break; + + if(!tpsheader->pNextHeader) { + tpsheader->pNextHeader = + kzalloc(sizeof(t_sva_video_decoder_algo_h264_slice_header_infos), + GFP_KERNEL); + } + + if(!tpsheader->pNextHeader) { + dbgprintk(3,"err:Kzalloc for next slice%d header failed\n",i); + ret_val = -ENOMEM; + break; + } + + tpsheader = tpsheader->pNextHeader; + tmp = psheader.next; + if(copy_from_user(&psheader, tmp, sizeof(psheader))){ + ret_val = -EACCES; + break; + } + } + + if(ret_val) + break; + + infos = &srv_open->config.videodecoder_info.h264_infos; + + } else if(srv_open->config.videodecoder_info.configuration.transformId + == SVA_DECODER_VC1_MP_LL) { + + vc1_infos.pictureCodingType = pinfo->infos.vc1.picture_coding_type; + vc1_infos.frameSize = pinfo->infos.vc1.framesize; + + bitstream_address=0; + bitstream_offset=0; + infos = &vc1_infos; + } else if(srv_open->config.videodecoder_info.configuration.transformId + == SVA_DECODER_MPEG2_MP_ML) { + + mpeg2_infos.vertical_size = pinfo->infos.mpeg2.vertical_size; + /* round to nearest multiple of coded macroblocks */ + /* ISO/IEC 13818-2 section 6.3.3 sequence_header() */ + mpeg2_infos.mb_width = (pinfo->infos.mpeg2.horizontal_size + 15) / 16; + mpeg2_infos.mb_height = pinfo->infos.mpeg2.mb_height; + for(i=0; i<64; i++) { + mpeg2_infos.intra_quantizer_matrix[i] = pinfo->infos.mpeg2.intra_quantizer_matrix[i]; + mpeg2_infos.non_intra_quantizer_matrix[i] = pinfo->infos.mpeg2.non_intra_quantizer_matrix[i]; + } + mpeg2_infos.picture_coding_type = pinfo->infos.mpeg2.picture_coding_type; + mpeg2_infos.full_pel_forward_vector = pinfo->infos.mpeg2.full_pel_forward_vector; + mpeg2_infos.forward_f_code = pinfo->infos.mpeg2.forward_f_code; + mpeg2_infos.full_pel_backward_vector = pinfo->infos.mpeg2.full_pel_backward_vector; + mpeg2_infos.backward_f_code = pinfo->infos.mpeg2.backward_f_code; + mpeg2_infos.f_code[0][0] = pinfo->infos.mpeg2.f_code[0][0]; + mpeg2_infos.f_code[1][0] = pinfo->infos.mpeg2.f_code[1][0]; + mpeg2_infos.f_code[0][1] = pinfo->infos.mpeg2.f_code[0][1]; + mpeg2_infos.f_code[1][1] = pinfo->infos.mpeg2.f_code[1][1]; + mpeg2_infos.intra_dc_precision = pinfo->infos.mpeg2.intra_dc_precision; + mpeg2_infos.picture_structure = pinfo->infos.mpeg2.picture_structure; + mpeg2_infos.top_field_first = pinfo->infos.mpeg2.top_field_first; + mpeg2_infos.frame_pred_frame_dct = pinfo->infos.mpeg2.frame_pred_frame_dct; + mpeg2_infos.concealment_motion_vectors = pinfo->infos.mpeg2.concealment_motion_vectors; + mpeg2_infos.q_scale_type = pinfo->infos.mpeg2.q_scale_type; + mpeg2_infos.intra_vlc_format = pinfo->infos.mpeg2.intra_vlc_format; + mpeg2_infos.alternate_scan = pinfo->infos.mpeg2.alternate_scan; + mpeg2_infos.scalable_mode = pinfo->infos.mpeg2.scalable_mode; + mpeg2_infos.MPEG2_Flag = pinfo->infos.mpeg2.MPEG2_Flag; + + bitstream_address = pinfo->infos.mpeg2.bitstream_address; + bitstream_offset = pinfo->infos.mpeg2.bitstream_offset; + infos = &mpeg2_infos; + } + else if( (srv_open->type == SVA_STILL_IMAGE_DECODER) + && (srv_open->config.stillimagedecoder_info.configuration.transformId == SVA_DECODER_SEQUENTIAL_JPEG)) + { + t_sva_still_decoder_configuration *pconf; + t_sva_still_algo_jpeg_decoder_configuration_params *jpeg_algo_params; + t_sva_still_decoder_algo_sequential_jpeg_header_infos * jpeg_seq_infos ; + + jpeg_seq_infos = (t_sva_still_decoder_algo_sequential_jpeg_header_infos *)vmalloc(sizeof(t_sva_still_decoder_algo_sequential_jpeg_header_infos)); + if(!jpeg_seq_infos){ + dbgprintk(3,"err: SET_HEADER :: vmalloc for JPEG seq header infos failed\n"); + ret_val = -ENOMEM; + break; + } + pconf = &srv_open->config.stillimagedecoder_info.configuration; + jpeg_algo_params = (t_sva_still_algo_jpeg_decoder_configuration_params *)pconf->pAlgoConfig; + + memcpy (&(jpeg_seq_infos->huffmanTable.huffmanYCodeDc[0]), + &(pinfo->infos.jpeg_sequential.huffmanTable.huffmanYCodeDc[0]), DC_HUFF_TABLE_SIZE*sizeof(__u16)); + memcpy (&(jpeg_seq_infos->huffmanTable.huffmanYSizeDc[0]), + &(pinfo->infos.jpeg_sequential.huffmanTable.huffmanYSizeDc[0]), DC_HUFF_TABLE_SIZE*sizeof(__u16)); + memcpy (&(jpeg_seq_infos->huffmanTable.huffmanYCodeAc[0]), + &(pinfo->infos.jpeg_sequential.huffmanTable.huffmanYCodeAc[0]), AC_HUFF_TABLE_SIZE*sizeof(__u16)); + memcpy (&(jpeg_seq_infos->huffmanTable.huffmanYSizeAc[0]), + &(pinfo->infos.jpeg_sequential.huffmanTable.huffmanYSizeAc[0]), AC_HUFF_TABLE_SIZE*sizeof(__u16)); + + if(jpeg_algo_params->colorMode == COLOR ){ + + memcpy (&(jpeg_seq_infos->huffmanTable.huffmanCbCodeDc[0]), + &(pinfo->infos.jpeg_sequential.huffmanTable.huffmanCbCodeDc[0]), DC_HUFF_TABLE_SIZE*sizeof(__u16)); + memcpy (&(jpeg_seq_infos->huffmanTable.huffmanCbSizeDc[0]), + &(pinfo->infos.jpeg_sequential.huffmanTable.huffmanCbSizeDc[0]), DC_HUFF_TABLE_SIZE*sizeof(__u16)); + memcpy (&(jpeg_seq_infos->huffmanTable.huffmanCbCodeAc[0]), + &(pinfo->infos.jpeg_sequential.huffmanTable.huffmanCbCodeAc[0]), AC_HUFF_TABLE_SIZE*sizeof(__u16)); + memcpy (&(jpeg_seq_infos->huffmanTable.huffmanCbSizeAc[0]), + &(pinfo->infos.jpeg_sequential.huffmanTable.huffmanCbSizeAc[0]), AC_HUFF_TABLE_SIZE*sizeof(__u16)); + + memcpy (&(jpeg_seq_infos->huffmanTable.huffmanCrCodeDc[0]), + &(pinfo->infos.jpeg_sequential.huffmanTable.huffmanCrCodeDc[0]), DC_HUFF_TABLE_SIZE*sizeof(__u16)); + memcpy (&(jpeg_seq_infos->huffmanTable.huffmanCrSizeDc[0]), + &(pinfo->infos.jpeg_sequential.huffmanTable.huffmanCrSizeDc[0]), DC_HUFF_TABLE_SIZE*sizeof(__u16)); + memcpy (&(jpeg_seq_infos->huffmanTable.huffmanCrCodeAc[0]), + &(pinfo->infos.jpeg_sequential.huffmanTable.huffmanCrCodeAc[0]), AC_HUFF_TABLE_SIZE*sizeof(__u16)); + memcpy (&(jpeg_seq_infos->huffmanTable.huffmanCrSizeAc[0]), + &(pinfo->infos.jpeg_sequential.huffmanTable.huffmanCrSizeAc[0]), AC_HUFF_TABLE_SIZE*sizeof(__u16)); + + /*Quantization Tables*/ + memcpy (&(jpeg_seq_infos->quantizationTable.quant_cb[0]), + &(pinfo->infos.jpeg_sequential.quantizationTable.quant_cb[0]), QUANT_TABLE_SIZE*sizeof(__u16)); + memcpy (&(jpeg_seq_infos->quantizationTable.quant_cr[0]), + &(pinfo->infos.jpeg_sequential.quantizationTable.quant_cr[0]), QUANT_TABLE_SIZE*sizeof(__u16)); + } + memcpy (&(jpeg_seq_infos->quantizationTable.quant_y[0]), + &(pinfo->infos.jpeg_sequential.quantizationTable.quant_y[0]), QUANT_TABLE_SIZE*sizeof(__u16)); + + jpeg_seq_infos->restartInterval = pinfo->infos.jpeg_sequential.restartInterval; + + + bitstream_address=0; + bitstream_offset=0; + srv_open->infos = jpeg_seq_infos; + + } + else if( (srv_open->type == SVA_STILL_IMAGE_DECODER) + && (srv_open->config.stillimagedecoder_info.configuration.transformId == SVA_DECODER_PROGRESSIVE_JPEG)) + { + t_sva_still_decoder_algo_progressive_jpeg_header_infos *jpeg_prog_infos; + t_sva_still_decoder_configuration *pconf; + t_sva_still_algo_jpeg_decoder_configuration_params *jpeg_algo_params; + + pconf = &srv_open->config.stillimagedecoder_info.configuration; + jpeg_algo_params = (t_sva_still_algo_jpeg_decoder_configuration_params *)pconf->pAlgoConfig; + + jpeg_prog_infos = (t_sva_still_decoder_algo_progressive_jpeg_header_infos *)vmalloc(sizeof(t_sva_still_decoder_algo_progressive_jpeg_header_infos)); + if(!jpeg_prog_infos){ + dbgprintk(3,"err: SET_HEADER :: vmalloc for JPEG prog header infos failed\n"); + ret_val = -ENOMEM; + break; + } + + memcpy (&(jpeg_prog_infos->huffmanTable.huffmanYCodeDc[0]), + &(pinfo->infos.jpeg_progressive.huffmanTable.huffmanYCodeDc[0]), DC_HUFF_TABLE_SIZE*sizeof(__u16)); + memcpy (&(jpeg_prog_infos->huffmanTable.huffmanYSizeDc[0]), + &(pinfo->infos.jpeg_progressive.huffmanTable.huffmanYSizeDc[0]), DC_HUFF_TABLE_SIZE*sizeof(__u16)); + memcpy (&(jpeg_prog_infos->huffmanTable.huffmanYCodeAc[0]), + &(pinfo->infos.jpeg_progressive.huffmanTable.huffmanYCodeAc[0]), AC_HUFF_TABLE_SIZE*sizeof(__u16)); + memcpy (&(jpeg_prog_infos->huffmanTable.huffmanYSizeAc[0]), + &(pinfo->infos.jpeg_progressive.huffmanTable.huffmanYSizeAc[0]), AC_HUFF_TABLE_SIZE*sizeof(__u16)); + + if(jpeg_algo_params->colorMode == COLOR ){ + + memcpy (&(jpeg_prog_infos->huffmanTable.huffmanCbCodeDc[0]), + &(pinfo->infos.jpeg_progressive.huffmanTable.huffmanCbCodeDc[0]), DC_HUFF_TABLE_SIZE*sizeof(__u16)); + memcpy (&(jpeg_prog_infos->huffmanTable.huffmanCbSizeDc[0]), + &(pinfo->infos.jpeg_progressive.huffmanTable.huffmanCbSizeDc[0]), DC_HUFF_TABLE_SIZE*sizeof(__u16)); + memcpy (&(jpeg_prog_infos->huffmanTable.huffmanCbCodeAc[0]), + &(pinfo->infos.jpeg_progressive.huffmanTable.huffmanCbCodeAc[0]), AC_HUFF_TABLE_SIZE*sizeof(__u16)); + memcpy (&(jpeg_prog_infos->huffmanTable.huffmanCbSizeAc[0]), + &(pinfo->infos.jpeg_progressive.huffmanTable.huffmanCbSizeAc[0]), AC_HUFF_TABLE_SIZE*sizeof(__u16)); + + memcpy (&(jpeg_prog_infos->huffmanTable.huffmanCrCodeDc[0]), + &(pinfo->infos.jpeg_progressive.huffmanTable.huffmanCrCodeDc[0]), DC_HUFF_TABLE_SIZE*sizeof(__u16)); + memcpy (&(jpeg_prog_infos->huffmanTable.huffmanCrSizeDc[0]), + &(pinfo->infos.jpeg_progressive.huffmanTable.huffmanCrSizeDc[0]), DC_HUFF_TABLE_SIZE*sizeof(__u16)); + memcpy (&(jpeg_prog_infos->huffmanTable.huffmanCrCodeAc[0]), + &(pinfo->infos.jpeg_progressive.huffmanTable.huffmanCrCodeAc[0]), AC_HUFF_TABLE_SIZE*sizeof(__u16)); + memcpy (&(jpeg_prog_infos->huffmanTable.huffmanCrSizeAc[0]), + &(pinfo->infos.jpeg_progressive.huffmanTable.huffmanCrSizeAc[0]), AC_HUFF_TABLE_SIZE*sizeof(__u16)); + + + memcpy (&(jpeg_prog_infos->quantizationTable.quant_cb[0]), + &(pinfo->infos.jpeg_progressive.quantizationTable.quant_cb[0]), QUANT_TABLE_SIZE*sizeof(__u16)); + memcpy (&(jpeg_prog_infos->quantizationTable.quant_cr[0]), + &(pinfo->infos.jpeg_progressive.quantizationTable.quant_cr[0]), QUANT_TABLE_SIZE*sizeof(__u16)); + } + memcpy (&(jpeg_prog_infos->quantizationTable.quant_y[0]), + &(pinfo->infos.jpeg_progressive.quantizationTable.quant_y[0]), QUANT_TABLE_SIZE*sizeof(__u16)); + + jpeg_prog_infos->restartInterval = pinfo->infos.jpeg_progressive.restartInterval; + jpeg_prog_infos->successiveApproxPosition = pinfo->infos.jpeg_progressive.successiveApproxPosition; + jpeg_prog_infos->nbScanComponents = pinfo->infos.jpeg_progressive.nbScanComponents; + jpeg_prog_infos->componentSelectorY = pinfo->infos.jpeg_progressive.componentSelectorY; + jpeg_prog_infos->componentSelectorCb = pinfo->infos.jpeg_progressive.componentSelectorCb; + jpeg_prog_infos->componentSelectorCr = pinfo->infos.jpeg_progressive.componentSelectorCr; + jpeg_prog_infos->startSpectralSelection = pinfo->infos.jpeg_progressive.startSpectralSelection; + jpeg_prog_infos->endSpectralSelection = pinfo->infos.jpeg_progressive.endSpectralSelection; + + bitstream_address=0; + bitstream_offset=0; + srv_open->infos = jpeg_prog_infos; + } + else { + ret_val = -EINVAL; + break; + } + + lock_critical_section(&hcl_mutex); + if(srv_open->type == SVA_STILL_IMAGE_DECODER) + sva_error = SVA_SetHeaderInfos(srv_open->service_id, buf_info->buffer_id, + bitstream_address,bitstream_offset,srv_open->infos); + else + sva_error = SVA_SetHeaderInfos(srv_open->service_id, buf_info->buffer_id, + bitstream_address,bitstream_offset,infos); + unlock_critical_section(&hcl_mutex); + + if(sva_error != SVA_OK) { + /* let us not print this in case of buffer needed + Just send the error to the user */ + if(sva_error != SVA_VIDEO_DECODER_IMAGE_BUFFER_NEEDED) + dbgprintk(3,"error:Setting header infos failed %d\n",sva_error); + ret_val=-EINVAL; + } + break; + + } + + case SVA_FLUSH_SERVICE: + { + struct sva_service_open *srv_open; + struct sva_service_struct * service = arg; + if(open->flags & O_NOIO) { + ret_val = -EPERM; + break; + } + + if(service->service_id >= MAX_SERVICE_OPENS || service->service_id < 0 || + !(open->service_open_data[service->service_id])) { + dbgprintk(3,"error: Invalid service id %lu\n",(unsigned long)service->service_id); + ret_val = -EINVAL; + break; + } + + srv_open = open->service_open_data[service->service_id]; + ret_val = flush_service(srv_open); + break; + } + + case SVA_GET_BITSTREAM_DATA: + { + struct sva_service_open *srv_open; + t_sva_error sva_error = SVA_OK; + t_sva_data_unit_buffer data_unit_buffer; + struct sva_codec_bitstream_data * pdata = arg; + + if(open->flags & O_NOIO) { + ret_val = -EPERM; + break; + } + + if(pdata->service_id >= MAX_SERVICE_OPENS || pdata->service_id < 0 || + !(open->service_open_data[pdata->service_id])) { + dbgprintk(3,"error: Invalid service id %lu\n",(unsigned long)pdata->service_id); + ret_val = -EINVAL; + break; + } + + srv_open = open->service_open_data[pdata->service_id]; + if(srv_open->type != SVA_VIDEO_ENCODER) { + dbgprintk(3,"error: Invalid ioctl for service type\n"); + ret_val=-EINVAL; + break; + } + + data_unit_buffer.pOBuf = pdata->buffer; + data_unit_buffer.byteCount = 0; + + lock_critical_section(&hcl_mutex); + /*sva_error = SVA_GenerateBitStreamDataUnits(srv_open->service_id, + (t_sva_data_unit_type)pdata->data_type,&data_unit_buffer); */ + unlock_critical_section(&hcl_mutex); + + if(sva_error != SVA_OK) { + dbgprintk(3,"error: GetBitstreamData failed %d\n",sva_error); + ret_val=-EINVAL; + break; + } + + pdata->length = data_unit_buffer.byteCount; + + break; + } + + case SVA_SET_SERVICE_TIME: + { + struct sva_service_open *srv_open; + struct sva_service_time *ptime = arg; + + if(open->flags & O_NOIO) { + ret_val = -EPERM; + break; + } + + if(ptime->service_id >= MAX_SERVICE_OPENS || ptime->service_id < 0 || + !(open->service_open_data[ptime->service_id])) { + dbgprintk(3,"error: Invalid service id %lu\n",(unsigned long)ptime->service_id); + ret_val = -EINVAL; + break; + } + + srv_open = open->service_open_data[ptime->service_id]; + + lock_critical_section(&hcl_mutex); + SVA_SetServiceSystemTime(srv_open->service_id, (t_uint32) ptime->time); + unlock_critical_section(&hcl_mutex); + + break; + + } + + case SVA_GET_SERVICE_TIME: + { + struct sva_service_open *srv_open; + struct sva_service_time *ptime = arg; + + if(open->flags & O_NOIO) { + ret_val = -EPERM; + break; + } + + if(ptime->service_id >= MAX_SERVICE_OPENS || ptime->service_id < 0 || + !(open->service_open_data[ptime->service_id])) { + dbgprintk(3,"error: Invalid service id %lu\n",(unsigned long)ptime->service_id); + ret_val = -EINVAL; + break; + } + + srv_open = open->service_open_data[ptime->service_id]; + + lock_critical_section(&hcl_mutex); + SVA_GetServiceSystemTime(srv_open->service_id, (t_uint32 *) &ptime->time); + unlock_critical_section(&hcl_mutex); + + break; + + } + + default: + ret_val = -EINVAL; + dbgprintk(3,"error:Unknown or unsupported command %u\n",cmd); + break; + + }/* end switch */ + + return ret_val; + +} + +static int +sva_ioctl(struct inode *inode, struct file *file, unsigned int cmd, + unsigned long arg) +{ + char args[256]; + char *targ = NULL; + int err = -EINVAL; + + if(cmd == SVA_GET_MESSAGES) + return sva_get_messages(file->private_data,(void *)arg); + + if(_IOC_SIZE(cmd) < 256) + targ = args; + else + targ = vmalloc(MAX_IOCTL_SIZE); + + if(!targ) + return -ENOMEM; + + /* Copy arguments into temp kernel buffer */ + switch (_IOC_DIR(cmd)) + { + case _IOC_NONE: + break; + case _IOC_WRITE: + case (_IOC_WRITE | _IOC_READ): + case _IOC_READ: + if (_IOC_SIZE(cmd) > MAX_IOCTL_SIZE) + { + dbgprintk(3,"error: ioctl 0x%08x arguments are " + "too big, > %d\n", cmd, MAX_IOCTL_SIZE); + + if(_IOC_SIZE(cmd) >= 256) + vfree(targ); + return -EINVAL; /* Arguments are too big. */ + } + + if(copy_from_user(targ, (void *)arg, _IOC_SIZE(cmd))) { + dbgprintk(3,"error: Fault on write ioctl 0x%08x " + "copying data from user buffer\n", cmd); + if(_IOC_SIZE(cmd) >= 256) + vfree(targ); + return -EFAULT; + } + break; + } + + err = process_ioctl(file->private_data, cmd, (void *)targ); + + /* Copy results into user buffer */ + switch (_IOC_DIR(cmd)) + { + case _IOC_READ: + case (_IOC_WRITE | _IOC_READ): + if (copy_to_user((void *)arg, (void *)targ, _IOC_SIZE(cmd))) + { + dbgprintk(3,"Fault on read ioctl 0x%08x " + "copying results to user buffer\n", cmd); + + if(_IOC_SIZE(cmd) >= 256) + vfree(targ); + + return -EFAULT; + } + break; + } + + /* Handle ioctls not recognized by the driver */ + if(_IOC_SIZE(cmd) >= 256) + vfree(targ); + return err; +} + +void +sva_vma_open(struct vm_area_struct *vma) +{ + struct file *filp = vma->vm_file; + struct sva_device_open *open = filp->private_data; + __u8 indx = 0; + + while(indx < MAX_BUFFERS) { + if(open->buffer_info[indx] && ((vma->vm_pgoff << PAGE_SHIFT) == + open->buffer_info[indx]->buffer.offset)) + break; + + indx++; + } + + if(indx == MAX_BUFFERS) { + dbgprintk(3,"error: Buffer not found\n"); + return; + } + + open->buffer_info[indx]->ref_count++; + open->buffer_info[indx]->vma = vma; + + +} +EXPORT_SYMBOL(sva_vma_open); + +void +sva_vma_close(struct vm_area_struct *vma) +{ + struct file *filp = vma->vm_file; + struct sva_device_open *open = filp->private_data; + __u8 indx = 0; + + while(indx < MAX_BUFFERS) { + if(open->buffer_info[indx] && ((vma->vm_pgoff << PAGE_SHIFT) == + open->buffer_info[indx]->buffer.offset)) + break; + + indx++; + } + + if(indx == MAX_BUFFERS) { + dbgprintk(3,"error: Buffer not found \n"); + return; + } + + open->buffer_info[indx]->ref_count--; + + if(!(open->buffer_info[indx]->ref_count)) { + open->buffer_info[indx]->buffer.flags &= ~BUF_FLAG_MAPPED; + open->buffer_info[indx]->vma = NULL; + } + + return; +} +EXPORT_SYMBOL(sva_vma_close); + +static struct vm_operations_struct sva_vma_operations = { + sva_vma_open, sva_vma_close, NULL, +}; + +int +sva_mmap(struct file *filp, struct vm_area_struct *vma) +{ + struct sva_device_open *open = filp->private_data; + __u8 indx = 0; + + while(indx < MAX_BUFFERS) { + if(open->buffer_info[indx] && (vma->vm_pgoff << PAGE_SHIFT + == open->buffer_info[indx]->buffer.offset)) + break; + indx++; + } + + if(indx == MAX_BUFFERS) { + dbgprintk(3,"sva_mmap(), buffer indx %lu not found\n",vma->vm_pgoff); + return -EINVAL; + } + + dbgprintk(2,"sva_mmap(), buffer indx %lu found\n",vma->vm_pgoff); + + if((vma->vm_end - vma->vm_start) != open->buffer_info[indx]->buffer.length) { + dbgprintk(3,"error: The vma range is invalid\n"); + return -EINVAL; + } + + vma->vm_flags |= VM_RESERVED; +#if defined(CONFIG_L2CACHE_ENABLE) + vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); +#endif + down(&open->open_lock); + if((open->buffer_info[indx]->buffer.flags & BUF_FLAG_MAPPED) == BUF_FLAG_MAPPED) { + dbgprintk(3,"error: Buffer %d already mapped\n",indx); + return -EINVAL; + } + + if(remap_pfn_range(vma,vma->vm_start,open->buffer_info[indx]->buffer_addr.physical>>PAGE_SHIFT, + (vma->vm_end - vma->vm_start), vma->vm_page_prot)) { + up(&open->open_lock); + return -EAGAIN; + } + + open->buffer_info[indx]->buffer.flags |= BUF_FLAG_MAPPED; + up(&open->open_lock); + + if(!vma->vm_ops) + vma->vm_ops = &sva_vma_operations; + if (vma->vm_ops->open) + vma->vm_ops->open (vma); + + return 0; +} +EXPORT_SYMBOL(sva_mmap); + +int +sva_release(struct inode *inode, struct file *filp) +{ + int indx = 0; + int err = 0; + struct sva_device_open *open = (struct sva_device_open *)filp->private_data; + + down(&open->open_lock); + vid_switch_ogl_resume(); + while(indx < MAX_SERVICE_OPENS) { + struct sva_service_open *srv_open; + + srv_open = open->service_open_data[indx]; + if(!srv_open) { + indx++; + continue; + } + + up(&open->open_lock); + /* Delete service */ + { + struct sva_service_struct srv; + srv.service_id = indx; + err = sva_delete_service(open, &srv); + if(err) + dbgprintk(3," Error deleting service... continuing\n"); + } + + indx++; + down(&open->open_lock); + + }/* End while */ + + indx = 0; + while(indx < MAX_BUFFERS) { + struct sva_buffer_info *buf_info; + buf_info = open->buffer_info[indx]; + if(!buf_info) { + indx++; + continue; + } + buf_info->buffer.flags &= ~BUF_FLAG_MAPPED ; + buf_info->buffer.flags &= ~BUF_FLAG_QUEUED ; + buf_info->buffer.read_only = 0; + + up(&open->open_lock); + err = deallocate_buffer(open, (unsigned long *)&(buf_info->buffer.buffer_id)); + if(err) { + dbgprintk(3,"error: Deallocate buffer %d failed\n",indx); + err = 0; + } + + indx++; + down(&open->open_lock); + } + + open->is_open = 0; + + up(&open->open_lock); + + down(&hcl_mutex); + sva.open_count--; + up(&hcl_mutex); + + dbgprintk(2,"Buffers successfully de-allocated\n"); + module_put(THIS_MODULE); + return err; + +} +EXPORT_SYMBOL(sva_release); + +int camera_register_device(struct camera *cam) +{ + try_module_get(THIS_MODULE); + + if(!sva.sva_platform_data) { + dbgprintk(3,"error:SVA platform data NULL\n"); + module_put(THIS_MODULE); + return -EAGAIN; + } + + if (cam == NULL) { + dbgprintk(3,"error:camera_register_device passed a NULL pointer\n"); + module_put(THIS_MODULE); + return -EAGAIN; + } + + if (cam->init == NULL) { + dbgprintk(3,"error:Camera has no init method\n"); + module_put(THIS_MODULE); + return -EAGAIN; + } + + if (cam->cleanup == NULL) { + dbgprintk(3,"error:Camera has no cleanup method\n"); + module_put(THIS_MODULE); + return -EAGAIN; + } + + if (sva.camera != NULL) { + dbgprintk(3,"error:Another camera device is already in use!\n"); + module_put(THIS_MODULE); + return -EAGAIN; + } + + dbgprintk(1,"using GPIO driver first call successul\n"); + + if(nomadik_gpio_altfuncenable(GPIO_ALT_CCIR656_INPUT,"sva")) + { + dbgprintk(3,"error:nomadik_gpio_altfuncenable() failed : CCIR656\n"); + module_put(THIS_MODULE); + return -EAGAIN; + } + + if(sva.sva_platform_data->camera_gpio_init && sva.sva_platform_data->camera_gpio_init()) { + dbgprintk(3,"Camera platform gpio initialization failed\n"); + nomadik_gpio_altfuncdisable(GPIO_ALT_CCIR656_INPUT, "sva"); + module_put(THIS_MODULE); + return -EAGAIN; + } + + if(sva.sva_platform_data->camera_init && sva.sva_platform_data->camera_init()) { + dbgprintk(3,"Camera platform initialization failed\n"); + nomadik_gpio_altfuncdisable(GPIO_ALT_CCIR656_INPUT, "sva"); + module_put(THIS_MODULE); + return -EAGAIN; + } + + sva.camera = cam; + return 0; +} + +void camera_unregister_device (struct camera *cam) +{ + if (sva.camera != cam) { + dbgprintk(3,"error:Bad camera unregister\n"); + module_put(THIS_MODULE); + return; + } + sva.camera = NULL; + + if(sva.sva_platform_data->camera_deinit) + sva.sva_platform_data->camera_deinit(); + + if(nomadik_gpio_altfuncdisable(GPIO_ALT_CCIR656_INPUT,"sva")) + dbgprintk(3,"error:nomadik_gpio_altfuncdisable() failed : CCIR656\n"); + + module_put(THIS_MODULE); + return; +} + +static t_system_address hcl_mem_addr; +static t_system_address hcl_mem_addr1; +static t_system_address sva_mem_sys_base_addr; +static t_system_address sva_reg_sys_base_addr; +static t_system_address eram_sys_base_addr; +static int sva_irq0; +size_t size_sram; +#ifdef CONFIG_NOMADIK_PM +static t_uint32 sram_back; +#endif + +static int sva_deinit_common(void) +{ + if (hcl_mem_addr.logical) + dma_free_coherent(&sva.p_dev->dev, SVA_HCL_MEMSIZE, (void *)hcl_mem_addr.logical, + (dma_addr_t)hcl_mem_addr.physical); + + if (hcl_mem_addr1.logical) + dma_free_coherent(&sva.p_dev->dev, 2*SVA_HCL_MEMSIZE, (void *)hcl_mem_addr1.logical, + (dma_addr_t)hcl_mem_addr1.physical); + + if (eram_sys_base_addr.logical) + iounmap((char *)eram_sys_base_addr.logical); + if (sva_mem_sys_base_addr.logical) + iounmap((char *)sva_mem_sys_base_addr.logical); + if (sva_reg_sys_base_addr.logical) + iounmap((char *)sva_reg_sys_base_addr.logical); + +#ifdef CONFIG_NOMADIK_PM + if ( sram_back ) + vfree((void *)sram_back); +#endif + + hcl_mem_addr.logical = NULL; + hcl_mem_addr.physical = NULL; + hcl_mem_addr1.logical = NULL; + hcl_mem_addr1.physical = NULL; + eram_sys_base_addr.logical = NULL; + sva_mem_sys_base_addr.logical = NULL; + sva_reg_sys_base_addr.logical = NULL; + if(sva_irq0) { + free_irq(sva_irq0,0); + sva_irq0 = 0; + } + + return 0; +} + +static int +sva_init_common(struct platform_device *pdev) +{ + int ret_val; + t_system_address mem_init_addr; + t_sva_error sva_error; + t_uint32* pmu_ctrl_reg; + struct resource *res; + + sva.sva_platform_data = (struct sva_board *)pdev->dev.platform_data; + + res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "sva-irq0"); + if(!res) + return -EINVAL; + sva_irq0 = res->start; + /* Initialise the interrupt handler */ + ret_val = request_irq(sva_irq0, nomadik_sva_interrupt, 0, "SVA0", 0); + if (ret_val < 0) { + dbgprintk(3,"error:Registering the interrupt handler failed, error %d \n" + ,ret_val); + return ret_val; + } + dbgprintk(1,"Registering the interrupt %d handler success\n",sva_irq0); + + /* map SVA registers */ + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "sva-reg-mem"); + if(!res) + return -EINVAL; + sva_reg_sys_base_addr.logical = (t_uint32)ioremap(res->start, + (size_t)res->end - res->start + 1); + + if (sva_reg_sys_base_addr.logical == 0) { + dbgprintk(3,"error:Unable to allocate memory for SVA Register Memory Area\n"); + free_irq(sva_irq0, 0); + return -EAGAIN; + } + + sva_reg_sys_base_addr.physical = (t_uint32)res->start; + + /* map SVA MMDSP memory */ + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "sva-data-mem"); + if(!res) + return -EINVAL; + sva_mem_sys_base_addr.logical = (t_uint32)ioremap(res->start, + (size_t)res->end - res->start + 1); + + if (sva_mem_sys_base_addr.logical == 0){ + dbgprintk(3,"error:Unable to allocate memory for SVA Data Memory Area\n"); + iounmap((void *)sva_reg_sys_base_addr.logical); + free_irq(sva_irq0, 0); + return -EAGAIN; + } + + dbgprintk(1,"Ioremapped 1MB memory for SVA Data Memory Area \n"); + + sva_mem_sys_base_addr.physical=(t_uint32)res->start; + + /* map embedded SRAM */ + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "sva-esram-mem"); + if(!res) + return -EINVAL; + size_sram = (size_t)(res->end - res->start + 1); + eram_sys_base_addr.logical = (t_uint32)ioremap(res->start,size_sram); + + if (eram_sys_base_addr.logical == 0) { + dbgprintk(3,"error:Unable to allocated memory for SVA Embedded SRAM\n"); + sva_deinit_common(); + return -EAGAIN; + } + eram_sys_base_addr.physical = (t_uint32)res->start; + + if(nomadik_clock_enable(NOMADIK_HCLK_SVA)<0){ + dbgprintk(3,"Failed to activate peripheral clock \n"); + return -EAGAIN; + } + + dbgprintk(2,"Calling SVA_Init \n"); + + SVA_SetBaseAddress(sva_reg_sys_base_addr.logical); + + /* initialize SVA HCL */ + sva_error = SVA_Init(sva_reg_sys_base_addr, sva_mem_sys_base_addr, eram_sys_base_addr, + (t_size)size_sram, TIMERCLK); + + if (sva_error != SVA_OK) { + dbgprintk(3,"error:Unable to init HAMAC Video HCL,error %d\n",sva_error); + sva_deinit_common(); + return -EAGAIN; + } + +#ifdef CONFIG_NOMADIK_SVA_INIT_MEM + + mem_init_addr.logical = (t_logical_address)sva.sva_platform_data->init_logical_address; + mem_init_addr.physical = (t_physical_address)sva.sva_platform_data->init_bus_address; + + if(mem_init_addr.logical == 0) { + dbgprintk(3,"error:Unable allocate initialization memory to HCL"); + sva_deinit_common(); + return -EAGAIN; + } + + /* Add memory allocated at initialisation time to HCL */ + sva_error = SVA_AddPrivateMemoryChunk(mem_init_addr, CONFIG_NOMADIK_SVA_MEM_SIZE * SZ_1M); + if (sva_error != SVA_OK) { + dbgprintk(3,"error:Unable to add initialization memory to HCL"); + sva_deinit_common(); + return -EAGAIN; + } + dbgprintk(1,"Added additional initialisation memory to HCL \n"); +#else + + hcl_mem_addr.logical = (t_logical_address)dma_alloc_coherent(&sva.p_dev->dev, + SVA_HCL_MEMSIZE, (dma_addr_t *)&hcl_mem_addr.physical, GFP_KERNEL); + + if(hcl_mem_addr.logical == 0){ + dbgprintk(3,"error:hcl memory virtual alloc failed\n"); + sva_deinit_common(); + return -EAGAIN; + } + dbgprintk(1,"%d Memory allocated successfully for HCL internal use\n",SVA_HCL_MEMSIZE); + + /* provide physically contiguous memory to HCL */ + sva_error = SVA_AddPrivateMemoryChunk(hcl_mem_addr, SVA_HCL_MEMSIZE); + if (sva_error != SVA_OK) { + dbgprintk(3,"error:Unable to add memory to HCL %d\n",sva_error); + sva_deinit_common(); + return -EAGAIN; + } + /* + hcl_mem_addr1.logical = (t_logical_address)dma_alloc_coherent(&sva.p_dev->dev, + SVA_HCL_MEMSIZE, (dma_addr_t *)&hcl_mem_addr1.physical, GFP_KERNEL); + + if(hcl_mem_addr1.logical == 0){ + dbgprintk(3,"error:hcl memory virtual alloc failed\n"); + sva_deinit_common(); + return -EAGAIN; + } + dbgprintk(1,"%d Memory allocated successfully for HCL internal use\n",SVA_HCL_MEMSIZE); + + // provide physically contiguous memory to HCL + sva_error = SVA_AddPrivateMemoryChunk(hcl_mem_addr1, SVA_HCL_MEMSIZE); + if (sva_error != SVA_OK) { + dbgprintk(3,"error:Unable to add memory1 to HCL %d\n",sva_error); + sva_deinit_common(); + return -EAGAIN; + }*/ + dbgprintk(1,"Added memory to HCL \n"); +#endif + + sva_error = SVA_ConfigurePrivateMemoryChunk(SVA_H264_INTERNAL_AREA, TWO_MB); +/*for grabHQ sva_error = SVA_ConfigurePrivateMemoryChunk(SVA_SW_PREPROC_BUFFER_AREA,11*SZ_1M);*/ + /* sva_error = SVA_ConfigurePrivateMemoryChunk(SVA_VC1_IMAGE_BUFFER_AREA, TWO_MB); */ + if (sva_error != SVA_OK) { + dbgprintk(3,"error:Unable to allocate memory for H264/VC1\n"); + sva_deinit_common(); + return -EAGAIN; + } + +#ifdef CONFIG_NOMADIK_PM + sram_back = (t_uint32)vmalloc(size_sram); + if ( !sram_back ) + { + dbgprintk(3, + "error:Unable to allocated memory for SVA Embedded SRAM backup\n"); + sva_deinit_common(); + return -EAGAIN; + } + +#endif + /* enable interrupts */ + SVA_EnableIRQSrc(SVA_IRQ); + dbgprintk(1,"Enabled IRQ\n"); + + /* enable timers through PMU control register (27th bit on) */ + pmu_ctrl_reg = (t_uint32*)IO_ADDRESS(NOMADIK_PMU_BASE); + (*pmu_ctrl_reg) |= 0x08000000; + + init_MUTEX(&hcl_mutex); + + dbgprintk(1,"Driver initialised successfully!\n "); + + return 0; +} + +static int sva_major = 100; +module_param(sva_major, int, 0644); +MODULE_PARM_DESC(sva_major, "Major number for the SVA device (default value 100)"); + +int +sva_open (struct inode *inode, struct file *filp) +{ + int i = 0; + + vid_switch_ogl_suspend(); + try_module_get(THIS_MODULE); + + down(&hcl_mutex); + while(i < MAX_OPENS && sva.device_open[i].is_open) i++; + + if(i == MAX_OPENS) { + up(&hcl_mutex); + module_put(THIS_MODULE); + return -EBUSY; + } + + sva.device_open[i].flags = filp->f_flags; + sva.device_open[i].is_open = 1; + sva.device_open[i].index = i; + + filp->private_data = &sva.device_open[i]; + sva.open_count++; + init_MUTEX(&sva.device_open[i].open_lock); + up(&hcl_mutex); + + return 0; + +} +EXPORT_SYMBOL(sva_open); + +static struct file_operations sva_fops = +{ + ioctl: sva_ioctl, + mmap: sva_mmap, + open: sva_open, + release: sva_release +}; + +static struct class *sva_class; + +void sva_driver_unregister(void) +{ + class_device_destroy(sva_class, MKDEV(sva_major, 0)); + class_destroy(sva_class); + unregister_chrdev(sva_major, "sva"); +} + +int sva_driver_register(void) +{ + int ret; + + ret = register_chrdev(sva_major, "sva", &sva_fops); + if(ret) { + dbgprintk(2,"Registering driver failed, error %d\n",ret); + return ret; + } + + sva_class = class_create(THIS_MODULE, "sva"); + + class_device_create(sva_class, NULL, + MKDEV(sva_major, 0), + NULL, "sva"); + + return 0; +} + +/* +static struct amba_id sva_ids[] __initdata = { + { + .id = 0x00080AAB, + .mask = 0xffffffff, + }, + { 0, 0 }, +}; + +static struct amba_driver sva_driver = { + .drv = { + .name = "SVA", + }, + .id_table = sva_ids, + .probe = sva_probe, + .remove = sva_remove +}; +*/ + +#ifdef CONFIG_NOMADIK_PM +int sva_suspend(struct platform_device *pdev, pm_message_t state); +int sva_resume(struct platform_device *pdev); +#endif + +struct platform_driver sva_driver = { + .driver = { + .name = "SVA" + }, + .probe = sva_probe, + .remove = sva_remove, +#ifdef CONFIG_NOMADIK_PM + .suspend = sva_suspend, + .resume = sva_resume +#endif + +}; + +int sva_remove(struct platform_device *dev) +{ + int i = 0; + dbgprintk(1, "%s enter\n",__FUNCTION__); + + sva_driver_unregister(); + + while(sva.firmware_array[i].buffer && i < MAX_FIRMWARE) + { + vfree(fw_inf_buf[i]); + vfree(sva.firmware_array[i++].buffer); + } + + if(sva.last_preprocessor_grab_type==GRAB_IRP){ + if(sva.sva_platform_data->sensor_gpio_deinit) + sva.sva_platform_data->sensor_gpio_deinit(IRP_CAMERA_SENSOR_CCP0); + } + if(vpip_irp_enable) + vpip_unload_firmware(); + vid_switch_unregister_sva_suspend_resume_fn(); + + dbgprintk(1,"%s exit\n",__FUNCTION__); + return 0; +} + +static int +sva_module_init(void) +{ + dbgprintk(2,"AMBA NOMADIK SVA driver\n"); + memset(&sva, 0, sizeof(struct sva_device)); + + return platform_driver_register(&sva_driver); +} + +static void +sva_module_deinit(void) +{ + sva_deinit_common(); + platform_driver_unregister(&sva_driver); + memset(&sva, 0, sizeof(sva)); + return; +} + +int sva_probe(struct platform_device *pdev) +{ + const struct firmware *fw; + t_sva_error sva_error; + t_sva_version version; + int i = 0; + int ret = 0; + struct sva_firmware_data *firmware = sva.firmware_array; + + dbgprintk(1, "%s enter\n",__FUNCTION__); + + sva.p_dev = pdev; + ret = sva_init_common(pdev); + if(ret) + return -EAGAIN; + + ret = sva_driver_register(); + if(ret) { + sva_deinit_common(); + dbgprintk(1,"%s exit\n",__FUNCTION__); + return -EAGAIN; + } + + fw=NULL; + while(i < MAX_FIRMWARE) { + + ret = request_firmware(&fw,firmware_name[i][0],&sva.p_dev->dev); + if(ret) { + dbgprintk(3,"error: Error loading firmware %s, error %d\n",\ + firmware_name[i][0],ret); + goto out; + } + + firmware[i].buffer = (__u8 *)vmalloc(fw->size); + + if(!firmware[i].buffer) { + dbgprintk(3,"error: kmalloc for firmware file %s failed\n", \ + firmware_name[i][0]); + release_firmware(fw); + ret = -ENOMEM; + goto out; + } + + memcpy(firmware[i].buffer, fw->data, fw->size); + release_firmware(fw); + + ret = request_firmware(&fw,firmware_name[i][1],&sva.p_dev->dev); + if(ret) { + dbgprintk(3,"error: Error loading firmware mmdsp_main_%s, error %d\n", \ + firmware_name[i][1],ret); + vfree(firmware[i].buffer); + goto out; + } + + dbgprintk(2,"Firmware %s size %d\n",firmware_name[i][1],fw->size); + + fw_inf_buf[i] = (char *)vmalloc(fw->size); + + if(!fw_inf_buf[i]) { + dbgprintk(3,"error: kmalloc for firmware file mmdsp_main_%s failed\n", \ + firmware_name[i][0]); + release_firmware(fw); + vfree(firmware[i].buffer); + firmware[i].buffer = NULL; + ret = -ENOMEM; + goto out; + } + + if (sva_debug == 1) { + int indx = 0; + __u16 *fw_data = NULL; + + dbgprintk(1,"Firmware %s size %d\n",firmware_name[i][1],fw->size); + fw_data = (__u16 *)fw->data; + while(indx < fw->size/2) { + dbgprintk(1,"%.4X ",fw_data[indx]); + indx++; + } + + } + + memcpy(fw_inf_buf[i], fw->data, fw->size); + release_firmware(fw); + + sva_error = SVA_RegisterFirmware((t_logical_address)fw_inf_buf[i], + &firmware[i].firmware_id); + if(sva_error != SVA_OK) { + dbgprintk(3,"error: Error registering firmware file %s, error %d\n",\ + firmware_name[i][1],sva_error); + vfree(fw_inf_buf[i]); + vfree(firmware[i].buffer); + firmware[i].buffer = NULL; + ret = -EINVAL; + goto out; + } + dbgprintk(1,"Register firmware file %s, id %lu\n", + firmware_name[i][1],firmware[i].firmware_id); + //vfree(fw_inf_buf); + + i++; + + } + + ret = 0; + +out: + vid_switch_register_sva_suspend_resume_fn(sva_ogl_suspend,sva_ogl_resume); + if(vpip_irp_enable){ + vpip_load_firmware(&sva.p_dev->dev); + } + dbgprintk(2,"%d firmware loaded\n",i); + if(i == 0) { + sva_driver_unregister(); + dbgprintk(3, "%s() failed\n",__FUNCTION__); + } else if (i < MAX_FIRMWARE){ + dbgprintk(3,"Warning:All firmware files could not be loaded\n"); + ret = 0; + } + SVA_GetVersion(&version); + + printk("SVA:HCL v%d.%d.%d\n",version.hclVersion.version,version.hclVersion.major, + version.hclVersion.minor); + printk("SVA:HW v%d.%d.%d\n",version.hwVersion.version,version.hwVersion.major, + version.hwVersion.minor); + + dbgprintk(1,"%s exit\n",__FUNCTION__); + return ret; +} + +#ifdef CONFIG_NOMADIK_PM +extern int g_nomadik_sleep_mode; +int sva_suspend(struct platform_device *dev, pm_message_t state) +{ + struct sva_service_open *srv_open; + struct sva_device_open *open; + int i, j; + + lock_critical_section(&hcl_mutex); + if (sva.open_count) { + for (j = 0; j < MAX_OPENS; j++) { + open = &sva.device_open[j]; + if (open->is_open) { + for (i = 0; i < MAX_SERVICE_OPENS; i++) { + srv_open = open->service_open_data[i]; + if (srv_open) { + if ((srv_open-> + state & SERVICE_CREATED) + || (srv_open-> + state & + SERVICE_INACTIVATED) + || (srv_open-> + state & + SERVICE_STOPPED)) + continue; + + goto err_suspend; + } + } + } + } + } + + if (g_nomadik_sleep_mode == DEEP_SLEEP) + { + SVA_SaveDeviceContext(); + memcpy((char *)sram_back, (char *)eram_sys_base_addr.logical, size_sram); + } + unlock_critical_section(&hcl_mutex); + + return 0; + err_suspend: + unlock_critical_section(&hcl_mutex); + return -EBUSY; + +} + +int sva_resume(struct platform_device *dev) +{ + lock_critical_section(&hcl_mutex); + if (g_nomadik_sleep_mode == DEEP_SLEEP) + { + SVA_RestoreDeviceContext(); + memcpy((char *)eram_sys_base_addr.logical, (char *)sram_back, size_sram); + } + unlock_critical_section(&hcl_mutex); + return 0; +} +#endif + + +void sva_ogl_init_common(struct platform_device *pdev) +{ + int ret_val; + t_system_address mem_init_addr; + t_sva_error sva_error; + t_uint32* pmu_ctrl_reg; + struct resource *res; + + sva.sva_platform_data = (struct sva_board *)pdev->dev.platform_data; + + res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "sva-irq0"); + if(!res) + return -EINVAL; + sva_irq0 = res->start; + /* Initialise the interrupt handler */ + ret_val = request_irq(sva_irq0, nomadik_sva_interrupt, 0, "SVA0", 0); + if (ret_val < 0) { + dbgprintk(3,"error:Registering the interrupt handler failed, error %d \n" + ,ret_val); + return ret_val; + } + dbgprintk(1,"Registering the interrupt %d handler success\n",sva_irq0); + + /* map SVA registers */ + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "sva-reg-mem"); + if(!res) + return -EINVAL; + sva_reg_sys_base_addr.logical = (t_uint32)ioremap(res->start, + (size_t)res->end - res->start + 1); + + if (sva_reg_sys_base_addr.logical == 0) { + dbgprintk(3,"error:Unable to allocate memory for SVA Register Memory Area\n"); + free_irq(sva_irq0, 0); + return -EAGAIN; + } + + sva_reg_sys_base_addr.physical = (t_uint32)res->start; + + /* map SVA MMDSP memory */ + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "sva-data-mem"); + if(!res) + return -EINVAL; + sva_mem_sys_base_addr.logical = (t_uint32)ioremap(res->start, + (size_t)res->end - res->start + 1); + + if (sva_mem_sys_base_addr.logical == 0){ + dbgprintk(3,"error:Unable to allocate memory for SVA Data Memory Area\n"); + iounmap((void *)sva_reg_sys_base_addr.logical); + free_irq(sva_irq0, 0); + return -EAGAIN; + } + + dbgprintk(1,"Ioremapped 1MB memory for SVA Data Memory Area \n"); + + sva_mem_sys_base_addr.physical=(t_uint32)res->start; + + /* map embedded SRAM */ + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "sva-esram-mem"); + if(!res) + return -EINVAL; + size_sram = (size_t)(res->end - res->start + 1); + eram_sys_base_addr.logical = (t_uint32)ioremap(res->start,size_sram); + + if (eram_sys_base_addr.logical == 0) { + dbgprintk(3,"error:Unable to allocated memory for SVA Embedded SRAM\n"); + sva_deinit_common(); + return -EAGAIN; + } + eram_sys_base_addr.physical = (t_uint32)res->start; + + if(nomadik_clock_enable(NOMADIK_HCLK_SVA)<0){ + dbgprintk(3,"Failed to activate peripheral clock \n"); + return -EAGAIN; + } + + dbgprintk(2,"Calling SVA_Init \n"); + + SVA_SetBaseAddress(sva_reg_sys_base_addr.logical); + + + /* initialize SVA HCL */ + sva_error = SVA_Init(sva_reg_sys_base_addr, sva_mem_sys_base_addr, eram_sys_base_addr, + (t_size)size_sram, TIMERCLK); + + if (sva_error != SVA_OK) { + dbgprintk(3,"error:Unable to init HAMAC Video HCL,error %d\n",sva_error); + sva_deinit_common(); + return -EAGAIN; + } + + #ifdef CONFIG_NOMADIK_SVA_INIT_MEM + + mem_init_addr.logical = (t_logical_address)sva.sva_platform_data->init_logical_address; + mem_init_addr.physical = (t_physical_address)sva.sva_platform_data->init_bus_address; + + if(mem_init_addr.logical == 0) { + dbgprintk(3,"error:Unable allocate initialization memory to HCL"); + sva_deinit_common(); + return -EAGAIN; + } + + /* Add memory allocated at initialisation time to HCL */ + sva_error = SVA_AddPrivateMemoryChunk(mem_init_addr, CONFIG_NOMADIK_SVA_MEM_SIZE * SZ_1M); + if (sva_error != SVA_OK) { + dbgprintk(3,"error:Unable to add initialization memory to HCL"); + sva_deinit_common(); + return -EAGAIN; + } + dbgprintk(1,"Added additional initialisation memory to HCL \n"); + #else + + hcl_mem_addr.logical = (t_logical_address)dma_alloc_coherent(&sva.p_dev->dev, + SVA_HCL_MEMSIZE, (dma_addr_t *)&hcl_mem_addr.physical, GFP_KERNEL); + + if(hcl_mem_addr.logical == 0){ + dbgprintk(3,"error:hcl memory virtual alloc failed\n"); + sva_deinit_common(); + return -EAGAIN; + } + dbgprintk(1,"%d Memory allocated successfully for HCL internal use\n",SVA_HCL_MEMSIZE); + + /* provide physically contiguous memory to HCL */ + sva_error = SVA_AddPrivateMemoryChunk(hcl_mem_addr, SVA_HCL_MEMSIZE); + if (sva_error != SVA_OK) { + dbgprintk(3,"error:Unable to add memory to HCL %d\n",sva_error); + sva_deinit_common(); + return -EAGAIN; + } + + dbgprintk(1,"Added memory to HCL \n"); + #endif + + sva_error = SVA_ConfigurePrivateMemoryChunk(SVA_H264_INTERNAL_AREA, TWO_MB); + /*for grabHQ sva_error = SVA_ConfigurePrivateMemoryChunk(SVA_SW_PREPROC_BUFFER_AREA,11*SZ_1M);*/ + /* sva_error = SVA_ConfigurePrivateMemoryChunk(SVA_VC1_IMAGE_BUFFER_AREA, TWO_MB); */ + if (sva_error != SVA_OK) { + dbgprintk(3,"error:Unable to allocate memory for H264/VC1\n"); + sva_deinit_common(); + return -EAGAIN; + } + + #ifdef CONFIG_NOMADIK_PM + sram_back = (t_uint32)vmalloc(size_sram); + if ( !sram_back ) + { + dbgprintk(3, + "error:Unable to allocated memory for SVA Embedded SRAM backup\n"); + sva_deinit_common(); + return -EAGAIN; + } + + #endif + /* enable interrupts */ + SVA_EnableIRQSrc(SVA_IRQ); + dbgprintk(1,"Enabled IRQ\n"); + + /* enable timers through PMU control register (27th bit on) */ + pmu_ctrl_reg = (t_uint32*)IO_ADDRESS(NOMADIK_PMU_BASE); + (*pmu_ctrl_reg) |= 0x08000000; + + init_MUTEX(&hcl_mutex); + + dbgprintk(1,"Driver initialised successfully!\n "); + + return 0; +} + + +void sva_ogl_init() +{ + const struct firmware *fw; + t_sva_error sva_error; + t_sva_version version; + int i = 0; + int ret = 0; + //char *fw_inf_buf = NULL; + struct sva_firmware_data *firmware = sva.firmware_array; + struct platform_device *pdev; + + pdev=sva.p_dev ; + sva_ogl_init_common(pdev); + if(ret) + return -EAGAIN; + + fw=NULL; + + while(i < MAX_FIRMWARE) { +#if 0 + ret = request_firmware(&fw,firmware_name[i][0],&sva.p_dev->dev); + if(ret) { + dbgprintk(3,"error: Error loading firmware %s, error %d\n",\ + firmware_name[i][0],ret); + goto out; + } + + firmware[i].buffer = (__u8 *)vmalloc(fw->size); + + if(!firmware[i].buffer) { + dbgprintk(3,"error: kmalloc for firmware file %s failed\n", \ + firmware_name[i][0]); + release_firmware(fw); + ret = -ENOMEM; + goto out; + } + + memcpy(firmware[i].buffer, fw->data, fw->size); + release_firmware(fw); + + ret = request_firmware(&fw,firmware_name[i][1],&sva.p_dev->dev); + if(ret) { + dbgprintk(3,"error: Error loading firmware mmdsp_main_%s, error %d\n", \ + firmware_name[i][1],ret); + vfree(firmware[i].buffer); + goto out; + } + + dbgprintk(2,"Firmware %s size %d\n",firmware_name[i][1],fw->size); + + fw_inf_buf = (char *)vmalloc(fw->size); + + if(!fw_inf_buf) { + dbgprintk(3,"error: kmalloc for firmware file mmdsp_main_%s failed\n", \ + firmware_name[i][0]); + release_firmware(fw); + vfree(firmware[i].buffer); + firmware[i].buffer = NULL; + ret = -ENOMEM; + goto out; + } + + if (sva_debug == 1) { + int indx = 0; + __u16 *fw_data = NULL; + + dbgprintk(1,"Firmware %s size %d\n",firmware_name[i][1],fw->size); + fw_data = (__u16 *)fw->data; + while(indx < fw->size/2) { + dbgprintk(1,"%.4X ",fw_data[indx]); + indx++; + } + + } + + memcpy(fw_inf_buf, fw->data, fw->size); + release_firmware(fw); +#endif + sva_error = SVA_RegisterFirmware((t_logical_address)fw_inf_buf[i], + &firmware[i].firmware_id); + if(sva_error != SVA_OK) { + dbgprintk(3,"error: Error registering firmware file %s, error %d\n",\ + firmware_name[i][1],sva_error); + vfree(fw_inf_buf[i]); + fw_inf_buf[i]=NULL; + vfree(firmware[i].buffer); + firmware[i].buffer = NULL; + ret = -EINVAL; + goto out; + } + dbgprintk(1,"Register firmware file %s, id %lu\n", + firmware_name[i][1],firmware[i].firmware_id); + //vfree(fw_inf_buf); + + i++; + + } + + ret = 0; + + out: + + if(vpip_irp_enable){ + vpip_load_firmware(&sva.p_dev->dev); + } + dbgprintk(2,"%d firmware loaded\n",i); + dbgprintk(1,"%s exit\n",__FUNCTION__); + return ret; +} + +void sva_ogl_deinit() +{ + int i = 0; + + sva_deinit_common(); +#if 0 + while(sva.firmware_array[i].buffer && i < MAX_FIRMWARE) + vfree(sva.firmware_array[i++].buffer); +#endif + if(sva.last_preprocessor_grab_type==GRAB_IRP){ + if(sva.sva_platform_data->sensor_gpio_deinit) + sva.sva_platform_data->sensor_gpio_deinit(IRP_CAMERA_SENSOR_CCP0); + } + if(vpip_irp_enable) + vpip_unload_firmware(); +} + + +void sva_ogl_suspend(void) +{ + sva_ogl_deinit(); + return 0; + +} + +void sva_ogl_resume(void) +{ + sva_ogl_init(); + return 0; +} +module_init(sva_module_init); +module_exit(sva_module_deinit); +MODULE_AUTHOR("Melwyn LOBO "); +MODULE_DESCRIPTION("Nomadik SVA driver"); +MODULE_LICENSE("GPL"); +EXPORT_SYMBOL(camera_register_device); +EXPORT_SYMBOL(camera_unregister_device); + --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva.h @@ -0,0 +1,225 @@ +/*--------------------------------------------------------------------------------------------------*/ +/*© copyright STMicroelectronics, 2007. */ +/* */ +/*This program is free software; you can redistribute it and/or modify it under */ +/*the terms of the GNU General Public License as published by the Free */ +/*Software Foundation; either version 2.1 of the License, or (at your option) */ +/*any later version. */ +/* */ +/*This program is distributed in the hope that it will be useful, but WITHOUT */ +/*ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU General Public License for more details. */ +/* */ +/*You should have received a copy of the GNU General Public License */ +/*along with this program. If not, see . */ +/*--------------------------------------------------------------------------------------------------*/ + + + + + + +#ifndef __SVA_SERVICE_INFO_H__ +#define __SVA_SERVICE_INFO_H__ + +#include +#include +#include "nomadik_defs.h" +#include +#include +#include +#include "nomadik_sva_utils.h" + +#define MAX_SERVICES 10 + +#define SERVICE_CREATED 0x00 +#define SERVICE_INACTIVATED 0x01 +#define SERVICE_ACTIVATED 0x02 +#define SERVICE_STARTED 0x04 +#define SERVICE_STOPPED 0x08 +#define SERVICE_ABORTED 0x10 +#define SERVICE_FLUSHED_IN 0x20 +#define SERVICE_FLUSHED_OUT 0x40 + +#define MAX_MESSAGES 60 + +struct sva_queue_data { + struct sva_queue input_q; + struct sva_queue internal_q; + struct sva_queue output_q; + wait_queue_head_t output_wq; /* wait queue for dequeue operation on output_q */ +}; + +struct sva_message_data { + struct sva_q_node qnode; + struct message_data message; + t_sva_buffer_id buffer_id; +}; + +struct sva_buffer_info{ + struct sva_q_node qnode; + __u16 flags; + __u16 ref_count; + struct sva_buffer buffer; + t_system_address buffer_addr; + unsigned long gfp_address; + t_sva_buffer_type buffer_type; + t_sva_buffer_id buffer_id; + t_sva_push_mode push; + t_sva_buffer_usage buffer_usage; + struct vm_area_struct *vma; +}; + +struct sva_postprocessor_info { + t_sva_postprocessor_configuration configuration; + __u8 pip_activated; +}; + +struct sva_preprocessor_info +{ + t_sva_preprocessor_configuration configuration; + __u16 camera_framerate; + __u16 sensor_aoi_x; + __u16 sensor_aoi_y; + __u16 prescale_factor; + +}; + +struct sva_videodecoder_info { + t_sva_video_decoder_configuration configuration; + t_sva_video_decoder_algo_h264_header_infos h264_infos; + t_uint16 vop_time_increment; +}; + + +struct sva_videoencoder_info { + t_sva_video_encoder_configuration configuration; +}; + + +struct sva_stillimagedecoder_info { + t_sva_still_decoder_configuration configuration; +}; + +struct sva_stillimageencoder_info { + t_sva_still_encoder_configuration configuration; +}; + +struct sva_tvout_info { + t_sva_tvo_configuration configuration; + enum sva_tvout_type type; +}; + +struct sva_readonly_work { + struct sva_service_open *srv_open; + t_sva_buffer_id buffer_id; +}; + +/*VPIP struct */ +struct irp_packet { + u16 readvalue; + short int packet_error; + short int rw_packet_finish; + t_sva_event_id eventId; +}; + +typedef enum { + GRAB_NONE, + GRAB_IRP, + GRAB_PEPPERPOT, + GRAB_INVALID, +} preprocessor_service_t; + +struct sva_service_open { + t_sva_service_type type; + __u8 state; + __u8 index; /* keeps track of open_data's index for closing purpose */ + struct semaphore service_lock; + char* internal_needs; + t_system_address internal_ncnb_needs; + __u32 internal_needs_size; + __u32 internal_ncnb_needs_size; + t_sva_header_infos *infos; + + union { + struct sva_preprocessor_info preprocessor_info; + struct sva_postprocessor_info postprocessor_info; + struct sva_videodecoder_info videodecoder_info; + struct sva_videoencoder_info videoencoder_info; + struct sva_stillimagedecoder_info stillimagedecoder_info; + struct sva_stillimageencoder_info stillimageencoder_info; + struct sva_tvout_info tvout_info; + }config; + + t_sva_service_id service_id; + struct sva_queue_data *in_image_buf_q; + struct sva_queue_data *out_image_buf_q; + struct sva_queue_data *readonly_image_buf_q; + struct sva_queue_data *in_coded_buf_q; + struct sva_queue_data *out_coded_buf_q; + struct sva_queue_data *in_infos_buf_q; + struct sva_queue_data *out_infos_buf_q; + struct sva_queue_data *in_params_buf_q; + struct sva_queue_data *out_params_buf_q; + struct sva_message_data messages_array[MAX_MESSAGES]; + struct sva_queue filled_message_queue; + struct sva_queue empty_message_queue; + wait_queue_head_t service_stop_wq; + wait_queue_head_t service_activate_wq; + wait_queue_head_t service_inactivate_wq; + wait_queue_head_t message_wq; + + /* VPIP */ + struct irp_packet irp_pkt; + preprocessor_service_t grab_type; +}; + +struct sva_device_open{ + __u8 flags; + __u8 services_active; + __u8 is_open; + __u8 index; + struct semaphore open_lock; + struct sva_buffer_info *buffer_info[MAX_BUFFERS]; + struct sva_service_open *service_open_data[MAX_SERVICE_OPENS]; +}; + +struct sva_firmware_data { + t_sva_fw_id firmware_id; + int firmware_index; + __u8 *buffer; +}; + +struct service_list { + int active; + struct sva_service_open *srv_open; +}; + +struct sva_device { + struct cdev c_dev; + struct platform_device *p_dev; + struct class_device class_dev; + struct sva_device_open device_open[MAX_OPENS]; + int open_count; + struct sva_service_open *active_preprocessor; + struct sva_service_open *active_tvout; + struct sva_firmware_data firmware_array[10]; + struct sva_board *sva_platform_data; + struct camera *camera; + preprocessor_service_t last_preprocessor_grab_type; +}; + +int sva_probe(struct platform_device *pdev); +int sva_remove(struct platform_device *pdev); + +irqreturn_t nomadik_sva_interrupt(int irq, void *device); +void nomadik_sva_tasklet(unsigned long); +int sva_BM_GetBufferType(t_sva_buffer_id bufferId, t_sva_buffer_type *pBufferType); + +#define lock_critical_section(x) down(x); tasklet_disable(&sva_tasklet) +#define unlock_critical_section(x) up(x); tasklet_enable(&sva_tasklet) + +#endif /* __SVA_SERVICE_INFO_H__ */ + + --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_mpeg4.c @@ -0,0 +1,432 @@ +/*--------------------------------------------------------------------------------------------------*/ +/*© copyright STMicroelectronics, 2007. */ +/* */ +/*This program is free software; you can redistribute it and/or modify it under */ +/*the terms of the GNU General Public License as published by the Free */ +/*Software Foundation; either version 2.1 of the License, or (at your option) */ +/*any later version. */ +/* */ +/*This program is distributed in the hope that it will be useful, but WITHOUT */ +/*ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU General Public License for more details. */ +/* */ +/*You should have received a copy of the GNU General Public License */ +/*along with this program. If not, see . */ +/*--------------------------------------------------------------------------------------------------*/ + + + + + + + +#include "nomadik_sva.h" + +extern int sva_debug; + +#define dbgprintk(num, format, args...) \ + do { \ + if(num >= sva_debug ) \ + printk("SVA:"format, ##args); \ + } while(0) + + +int set_video_decoder_config(struct sva_service_open *srv_open, struct sva_service_struct *srv) +{ + t_sva_video_decoder_configuration *pconf; + t_sva_video_decoder_algo_mpeg4_configuration_params *algo_params; + t_sva_video_decoder_algo_h264_configuration_params *h264_algo_params; + t_sva_video_decoder_algo_vc1_configuration_params *vc1_algo_params; + t_sva_video_decoder_algo_Mpeg2_configuration_params *mpeg2_algo_params; + struct mpeg4_algo_params *mpeg4_params; + struct h264_algo_params *h264_params; + struct vc1_algo_params *vc1_params; + struct mpeg2_algo_params *mpeg2_params; + struct sva_videodecoder_configuration *conf; + __u32 index=0; + + conf = &srv->config.videodecoder_configuration; + pconf = &srv_open->config.videodecoder_info.configuration; + + if(conf->capability == H264) { + + h264_algo_params = + kzalloc(sizeof(t_sva_video_decoder_algo_h264_configuration_params), GFP_KERNEL); + + if(!h264_algo_params) + return -1; + + pconf->pAlgoConfig = (void *)h264_algo_params; + + h264_params = (struct h264_algo_params *)conf->codec_params; + h264_algo_params->levelIdc = h264_params->level_idc; + h264_algo_params->numRefFrames = h264_params->number_ref_frames; + h264_algo_params->gapsInFrameNumValueFlag = h264_params->gaps_in_frame_num_value_flag; + h264_algo_params->log2MaxFrameNumMinus4 = h264_params->log_2_max_frame_num_minus4; + h264_algo_params->offsetForNonRefPic = h264_params->offset_for_non_ref_pic; + h264_algo_params->picOrderCntType = h264_params->pic_order_cnt_type; + + h264_algo_params->log2MaxPicOrderCntLsbMinus4 = + h264_params->log_2_max_pic_order_cnt_lsb_minus4; + + memcpy(h264_algo_params->offsetForRefFrame,h264_params->offset_for_ref_frame,256); + + h264_algo_params->numRefFramesInPicOrderCntCycle = + h264_params->num_ref_frames_in_pic_order_cnt_cycle; + + h264_algo_params->offsetForTopToBottomField = + h264_params->offset_for_top_to_bottom_field; + + } else if(conf->capability == MPEG4_SP_L4A) { + + + algo_params = + kzalloc(sizeof(t_sva_video_decoder_algo_mpeg4_configuration_params), GFP_KERNEL); + + if(!algo_params) + { + dbgprintk(3," Can not allocate memory \n"); + return -1; + } + + pconf->pAlgoConfig = (void *) algo_params; + + mpeg4_params = (struct mpeg4_algo_params *)conf->codec_params; + algo_params->flagShortHeader = mpeg4_params->short_header; + + + if(!algo_params->flagShortHeader) + srv_open->config.videodecoder_info.vop_time_increment = + conf->vop_time_increment; + + + algo_params->vopTimeIncrementResolution = mpeg4_params->vop_time_increment; + algo_params->isResyncMarkerDisable = mpeg4_params->resync_marker_disable; + algo_params->isDataPartitioned = mpeg4_params->data_partitioned; + algo_params->isReversibleVlc = mpeg4_params->reversible_vlc; + + + /** SVA 8.0.0 migration + for support of advanced simple profile */ + algo_params->isInterlaced=mpeg4_params->isInterlaced; + algo_params->profile=mpeg4_params->profile; + algo_params->isInterlaced=mpeg4_params->isInterlaced; + algo_params->low_delay=mpeg4_params->low_delay; + algo_params->quant_type=mpeg4_params->quant_type; + + for(index=0;index<64;index++) + { + algo_params->intra_quant_mat[index]=mpeg4_params->intra_quant_mat[index]; + algo_params->nonintra_quant_mat[index]=mpeg4_params->nonintra_quant_mat[index]; + } + /** SVA 8.0.0 migration ~ ends */ + + + } else if(conf->capability == VC1_MP_LL){ + /* VC1 decoder */ + vc1_algo_params = kzalloc(sizeof(t_sva_video_decoder_algo_vc1_configuration_params), + GFP_KERNEL); + if(!vc1_algo_params) + return -1; + pconf->pAlgoConfig = (void *)vc1_algo_params; + vc1_params = (struct vc1_algo_params *)conf->codec_params; + + vc1_algo_params->profile = vc1_params->profile; + vc1_algo_params->level = vc1_params->level; + vc1_algo_params->quantizer = vc1_params->quantizer; + vc1_algo_params->dquant = vc1_params->dquant; + vc1_algo_params->max_b_frames = vc1_params->max_b_frames; + vc1_algo_params->qFramerateForPostproc = vc1_params->q_framerate_for_postproc; + vc1_algo_params->qBitrateForPostproc = vc1_params->q_bitrate_for_postproc; + + vc1_algo_params->loopFilterEnabled = vc1_params->loop_filter_enabled; + vc1_algo_params->multiresCodingEnabled = vc1_params->multires_coding_enabled; + vc1_algo_params->fastUvmcEnabled = vc1_params->fast_uvmc_enabled; + vc1_algo_params->extendedMVEnabled = vc1_params->extended_mv_enabled; + vc1_algo_params->variableSizeTransformEnabled = vc1_params->variable_size_transform_enabled; + vc1_algo_params->overlapTransformEnabled = vc1_params->overlap_transform_enabled; + vc1_algo_params->syncmarkerEnabled = vc1_params->syncmarker_enabled; + vc1_algo_params->rangeredEnabled = vc1_params->rangered_enabled; + vc1_algo_params->frameInterpolationEnabled = vc1_params->frame_interpolation_enabled; + vc1_algo_params->is_smpte_conformant = vc1_params->is_smpte_conformant; + + } else if(conf->capability == MPEG2_MP_ML){ + mpeg2_algo_params = + kzalloc(sizeof(t_sva_video_decoder_algo_Mpeg2_configuration_params), GFP_KERNEL); + + if(!mpeg2_algo_params) + return -1; + + pconf->pAlgoConfig = (void *) mpeg2_algo_params; + + mpeg2_params = (struct mpeg2_algo_params *)conf->codec_params; + + mpeg2_algo_params->load_intra_quantiser_matrix = mpeg2_params->load_intra_quantiser_matrix; + mpeg2_algo_params->load_nonintra_quantiser_matrix = mpeg2_params->load_nonintra_quantiser_matrix; + mpeg2_algo_params->progressive_sequence = mpeg2_params->progressive_sequence; + mpeg2_algo_params->profile_level_indication = mpeg2_params->profile_level_indication; + mpeg2_algo_params->chroma_format = mpeg2_params->chroma_format; + mpeg2_algo_params->bit_rate = mpeg2_params->bit_rate; + } else + { + dbgprintk(3," Decoder configuraion transform ID is wrong \n"); + return -1; + } + + pconf->transformId = conf->capability; + + pconf->areInfosRequested = conf->is_infos_requested; + pconf->ercMode = SVA_BASIC_ERC; + pconf->mode = conf->mode; + + pconf->inTheLoopFilter = conf->in_filter; + pconf->outTheLoopFilter = conf->out_filter; + + pconf->imageDesc.width = conf->frame.width; + pconf->imageDesc.height = conf->frame.height; + + return 0; + +} + +int set_qp_constant_config(t_sva_video_encoder_configuration *pconf,struct sva_videoencoder_configuration *conf) +{ + t_sva_brc_qpConstant_configuration_params *config_params; + struct sva_brc_constant_qp_config_params *brc_qp_params; + + pconf->pBrcConfig = kzalloc(sizeof(t_sva_brc_qpConstant_configuration_params), GFP_KERNEL); + if(!pconf->pBrcConfig) + return -1; + config_params = (t_sva_brc_qpConstant_configuration_params *)pconf->pBrcConfig; + brc_qp_params = (struct sva_brc_constant_qp_config_params *)conf->brc_config_params; + + config_params->pictureIntraRefresh = brc_qp_params->intra_refresh; + config_params->IPictureQp = brc_qp_params->i_picture_qp; + config_params->PPictureQp = brc_qp_params->p_picture_qp; + config_params->bitRate = brc_qp_params->bit_rate;/*target bit rate in bits/s*/ + config_params->vbvBufferSize = brc_qp_params->vbv_buffer_size;/*vbv buffer size in bits*/ + config_params->vbvOccupancy = brc_qp_params->vbv_occupancy;/*initial vbv occupancy in bits*/ + config_params->swissBuffer = brc_qp_params->swiss_buffer;/*swiss buffer in bits*/ + return 0; + +} + +int set_frame_base_config(t_sva_video_encoder_configuration *pconf,struct sva_videoencoder_configuration *conf) +{ + t_sva_brc_frameBase_configuration_params *config_params; + struct sva_brc_framebase_config_params *brc_qp_params; + + pconf->pBrcConfig = kzalloc(sizeof(t_sva_brc_frameBase_configuration_params), GFP_KERNEL); + if(!pconf->pBrcConfig) + return -1; + config_params = (t_sva_brc_frameBase_configuration_params *)pconf->pBrcConfig; + brc_qp_params = (struct sva_brc_framebase_config_params *)conf->brc_config_params; + + config_params->dummy = brc_qp_params->dummy; + return 0; +} + +int set_cbr_config(t_sva_video_encoder_configuration *pconf,struct sva_videoencoder_configuration *conf) +{ + t_sva_brc_cbr_configuration_params *config_params; + struct sva_brc_cbr_config_params *brc_qp_params; + + pconf->pBrcConfig = kzalloc(sizeof(t_sva_brc_cbr_configuration_params), GFP_KERNEL); + if(!pconf->pBrcConfig) + return -1; + config_params = (t_sva_brc_cbr_configuration_params *)pconf->pBrcConfig; + brc_qp_params = (struct sva_brc_cbr_config_params *)conf->brc_config_params; + + config_params->pictureIntraRefresh = brc_qp_params->intra_refresh; + config_params->bitRate = brc_qp_params->bit_rate; + config_params->vbvBufferSize = brc_qp_params->vbv_buffer_size; + config_params->vbvOccupancy = brc_qp_params->vbv_occupancy; + config_params->swissBuffer = brc_qp_params->swiss_buffer; + return 0; +} + +int set_vbr_config(t_sva_video_encoder_configuration *pconf,struct sva_videoencoder_configuration *conf) +{ + t_sva_brc_vbr_configuration_params *config_params; + struct sva_brc_vbr_config_params *brc_qp_params; + + pconf->pBrcConfig = kzalloc(sizeof(t_sva_brc_vbr_configuration_params), GFP_KERNEL); + if(!pconf->pBrcConfig) + return -1; + config_params = (t_sva_brc_vbr_configuration_params *)pconf->pBrcConfig; + brc_qp_params = (struct sva_brc_vbr_config_params *)conf->brc_config_params; + + config_params->pictureIntraRefresh = brc_qp_params->intra_refresh; + config_params->bitRate = brc_qp_params->bit_rate; + config_params->minFrameRate = brc_qp_params->min_frame_rate; + config_params->spatialQuality = brc_qp_params->spatial_quality; + config_params->vbvBufferSize = brc_qp_params->vbv_buffer_size; + config_params->vbvOccupancy = brc_qp_params->vbv_occupancy; + config_params->swissBuffer = brc_qp_params->swiss_buffer; + return 0; +} + +int set_video_encoder_config(struct sva_service_open *srv_open, struct sva_service_struct *srv) +{ + t_sva_video_encoder_configuration *pconf; + t_sva_video_encoder_algo_mpeg4_configuration_params *algo_params; + t_sva_video_encoder_algo_h264_configuration_params *h264_algo_params; + struct mpeg4_encode_algo_params *mpeg4_params; + struct h264_encode_algo_params *h264_params; + struct sva_videoencoder_configuration *conf; + int ret = 0; + + conf = &srv->config.videoencoder_configuration; + pconf = &srv_open->config.videoencoder_info.configuration; + + /* init encode structure */ + pconf->transformId=conf->capability; + pconf->areInfosRequested=conf->is_infos_requested; + pconf->isCroppingVectorEnabled=conf->cropping_vector; + pconf->isDestinationBufferRequested=conf->destination_buffer; + pconf->mode=conf->mode; + pconf->sourceFrameDesc.frame.height=conf->source_frame_desc.frame.height; + pconf->sourceFrameDesc.frame.width=conf->source_frame_desc.frame.width; + pconf->sourceFrameDesc.window.image.height=conf->source_frame_desc.window.frame.height; + pconf->sourceFrameDesc.window.image.width=conf->source_frame_desc.window.frame.width; + pconf->sourceFrameDesc.window.imageOffset.offsetX=conf->source_frame_desc.window.offset.x_offset; + pconf->sourceFrameDesc.window.imageOffset.offsetY=conf->source_frame_desc.window.offset.y_offset; + pconf->inTheLoopFilter=conf->in_filter; + pconf->outTheLoopFilter=conf->out_filter; + + if(conf->capability == H264) { + pconf->pAlgoConfig = kzalloc(sizeof(t_sva_video_encoder_algo_h264_configuration_params), + GFP_KERNEL); + if(!pconf->pAlgoConfig) + return -1; + + h264_algo_params = pconf->pAlgoConfig; + h264_params = (struct h264_encode_algo_params *)conf->codec_params; + + /*h264_algo_params->ProfileIDC = h264_params->profile_idc;*/ + h264_algo_params->level_idc = h264_params->level_idc; + /*h264_algo_params->QPISlice = h264_params->qp_i_slice; + h264_algo_params->QPPSlice = h264_params->qp_p_slice;*/ +// h264_algo_params->no_frames = h264_params->no_frames; +// h264_algo_params->qp0 = h264_params->qp0; +// h264_algo_params->qpN = h264_params->qpn; +// h264_algo_params->hadamard = h264_params->hadamard; +// h264_algo_params->search_range = h264_params->search_range; + // h264_algo_params->jumpd = h264_params->jumpd; + // h264_algo_params->Log2MaxFrameNum = h264_params->log_2_max_frame_num; + h264_algo_params->Log2MaxFNumMinus4 = h264_params->log_2_max_fnum_minus4; + // h264_algo_params->frame_width = h264_params->frame_width; + // h264_algo_params->frame_height = h264_params->frame_height; +// h264_algo_params->width_cr = h264_params->width_cr; +// h264_algo_params->height_cr = h264_params->height_cr; + + h264_algo_params->slice_size_type = h264_params->slice_size_type; + h264_algo_params->slice_mb_size = h264_params->slice_mb_size; + h264_algo_params->slice_bit_size = h264_params->slice_bit_size; + h264_algo_params->use_constrained_intra_flag = h264_params->use_constrained_intra_pred; +// h264_algo_params->infile_header = h264_params->infile_header; + h264_algo_params->intra_period = h264_params->intra_period; + h264_algo_params->idr_enable = h264_params->idr_enable; + // h264_algo_params->start_frame = h264_params->start_frame; + h264_algo_params->annexb = h264_params->annexb; +// h264_algo_params->intra_disable = h264_params->intra_disable; + h264_algo_params->IntraDisableInterOnly = h264_params->intra_disable_inter_only; + h264_algo_params->Intra4x4ParDisable = h264_params->intra_4x4_par_disable; + h264_algo_params->Intra4x4DiagDisable = h264_params->intra_4x4_diag_disable; + h264_algo_params->Intra4x4DirDisable = h264_params->intra_4x4_dir_disable; + h264_algo_params->Intra16x16ParDisable = h264_params->intra_16x16_par_disable; + h264_algo_params->Intra16x16PlaneDisable = h264_params->intra_16x16_plane_disable; + h264_algo_params->ChromaIntraDisable = h264_params->chroma_intra_disable; + h264_algo_params->intra_disable = h264_params->intra_disable; + h264_algo_params->FrameRate = h264_params->frame_rate; + h264_algo_params->chroma_qp_index_offset = h264_params->chroma_qp_index_offset; + h264_algo_params->pic_order_cnt_type = h264_params->pic_order_cnt_type; +// h264_algo_params->ReportFrameStats = h264_params->report_frame_stats; +// h264_algo_params->brc_type = h264_params->brc_type; + h264_algo_params->bit_rate = h264_params->bit_rate; + h264_algo_params->SeinitialQP = h264_params->se_initial_qp; +// h264_algo_params->basicunit = h264_params->basic_unit; + h264_algo_params->me_type = h264_params->me_type; + h264_algo_params->HrdSendMessages = h264_params->hrd_send_messages; + h264_algo_params->CpbBufferSize = h264_params->cpb_buffer_size; + h264_algo_params->intra_refresh_type = h264_params->intra_refresh_type; + h264_algo_params->air_mb_num = h264_params->air_mb_num; +// h264_algo_params->cir_period_max = h264_params->cir_period_max; +// h264_algo_params->slice_loss_first_mb[0] = h264_params->slice_loss_first_mb[0]; +// h264_algo_params->slice_loss_mb_num[0] = h264_params->slice_loss_mb_num[0]; + h264_algo_params->aspect_ratio_info_present_flag=h264_params->aspect_ratio_info_present_flag; + h264_algo_params->aspect_ratio_idc=h264_params->aspect_ratio_idc; + h264_algo_params->sar_width=h264_params->sar_width; + h264_algo_params->sar_height=h264_params->sar_height; + h264_algo_params->disable_deblocking_filter_idc=(h264_params->disable_deblocking_filter_idc&0xF); +// h264_algo_params->slice_alpha=h264_params->slice_alpha; +// h264_algo_params->slice_beta=h264_params->slice_beta; + /*h264_algo_params->slice_alpha_c0_offset_div2=h264_params->slice_alpha; + h264_algo_params->slice_beta_offset_div2=h264_params->slice_beta;*/ + h264_algo_params->video_signal_type_present_flag=h264_params->video_signal_type_present_flag; + h264_algo_params->video_format=h264_params->video_format; + h264_algo_params->video_full_range_flag=h264_params->video_full_range_flag; + h264_algo_params->colour_description_present_flag=h264_params->colour_description_present_flag; + h264_algo_params->colour_primaries=h264_params->colour_primaries; + h264_algo_params->transfer_characteristics=h264_params->transfer_characteristics; + h264_algo_params->matrix_coefficients=h264_params->matrix_coefficients; + h264_algo_params->IntraForced=h264_params->intra_forced; + + } else if(conf->capability == MPEG4_SP_L4A) { + pconf->pAlgoConfig = kzalloc(sizeof(t_sva_video_encoder_algo_mpeg4_configuration_params), + GFP_KERNEL); + + if(!pconf->pAlgoConfig) + return -1; + + algo_params = (t_sva_video_encoder_algo_mpeg4_configuration_params *)pconf->pAlgoConfig; + mpeg4_params = (struct mpeg4_encode_algo_params *)conf->codec_params; + + /* init mpeg4 structure */ + algo_params->flagShortHeader=mpeg4_params->short_header; + algo_params->gobHeaderFrequency=mpeg4_params->gob_header_freq; + algo_params->isDataPartitionedEnable=mpeg4_params->data_partitioned; + algo_params->isReversibleVlcEnable=mpeg4_params->reversible_vlc; + algo_params->hecFreq=mpeg4_params->hec_freq; + algo_params->vpSizeType=mpeg4_params->vp_size_type; + algo_params->vpSizeMax=mpeg4_params->vp_size_max; + algo_params->vpBitSize=mpeg4_params->vp_bit_size; + algo_params->vpMbSize=mpeg4_params->vp_mb_size; + algo_params->irMode=mpeg4_params->refresh_mode; + algo_params->airMbNum=mpeg4_params->air_mb_num; + algo_params->cirPeriodMax=mpeg4_params->cir_period_max; + algo_params->rtypeMode=mpeg4_params->rtype_mode; + algo_params->isSystemHeaderAddBeforeIntra=mpeg4_params->system_header_before_intra; + algo_params->vopTimeIncrement=mpeg4_params->vop_time_increment; + algo_params->vopTimeIncrementResolution=mpeg4_params->vop_time_increment_resolution; + + } else + return -1; + + switch(conf->brc_mode) { + + case CONSTANT_QP: + ret = set_qp_constant_config(pconf,conf); + pconf->brcMode = SVA_QP_CONSTANT; + break; + case FRAME_BASE: + ret = set_frame_base_config(pconf,conf); + pconf->brcMode = SVA_FRAME_BASE; + break; + case CBR: + ret = set_cbr_config(pconf,conf); + pconf->brcMode = SVA_CBR; + break; + case VBR: + ret = set_vbr_config(pconf,conf); + pconf->brcMode = SVA_VBR; + break; + } + if(ret) + return -1; + + pconf->bufferingModel=conf->buffering_model; + return 0; +} + --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_services.h @@ -0,0 +1,3826 @@ +/*--------------------------------------------------------------------------------------------------*/ +/*© copyright STMicroelectronics, 2007. */ +/* */ +/*This program is free software; you can redistribute it and/or modify it under */ +/*the terms of the GNU General Public License as published by the Free */ +/*Software Foundation; either version 2.1 of the License, or (at your option) */ +/*any later version. */ +/* */ +/*This program is distributed in the hope that it will be useful, but WITHOUT */ +/*ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU General Public License for more details. */ +/* */ +/*You should have received a copy of the GNU General Public License */ +/*along with this program. If not, see . */ +/*--------------------------------------------------------------------------------------------------*/ + + + + + + +#ifndef __SVA_SERVICES_H__ +#define __SVA_SERVICES_H__ + +#include + +#define O_NOIO O_TRUNC + +#define BUF_FLAG_DONE 0x01 +#define BUF_FLAG_QUEUED 0x02 +#define BUF_FLAG_MAPPED 0x04 +#define BUF_FLAG_ERR 0x08 +#define BUF_FLAG_READONLY 0x10 +#define BUF_FLAG_PARTLY_FILLED 0x20 +#define BUF_FLAG_QUEUED_RO 0x40 + +typedef int Bool; + +enum sva_update_service_param { + PREPROCESSOR_CROP, + PREPROCESSOR_RESIZE, + PREPROCESSOR_ACE_ENABLE, + PREPROCESSOR_ACE_STRENGTH, + PREPROCESSOR_OUTPUT_RANGE, + PREPROCESSOR_ACE_RANGE, + PREPROCESSOR_ACE_OFFSET, +/*vpip-start*/ + PREPROCESSOR_ZOOM_IN, + PREPROCESSOR_ZOOM_OUT, + PREPROCESSOR_CONTRAST, + PREPROCESSOR_COLOUR_SATURATION, + PREPROCESSOR_WHITEBALANCE, + PREPROCESSOR_COLMATRIX_DAMPING, + PREPROCESSOR_EXPOSURE, + PREPROCESSOR_ENABLE_FUNCBLOCK, + PREPROCESSOR_FADETOBLACK, + PREPROCESSOR_RADIAL_PEAKING, +/*vpip-end*/ + POSTPROCESSOR_TILE, + POSTPROCESSOR_PIP, + POSTPROCESSOR_CONTRAST, + POSTPROCESSOR_BRIGHTNESS, + POSTPROCESSOR_DITHERING, + POSTPROCESSOR_CROP, + POSTPROCESSOR_CLIP, + POSTPROCESSOR_MIRROR, + POSTPROCESSOR_ROTATE, + POSTPROCESSOR_ALPHA_KEY, + POSTPROCESSOR_RESIZE, + POSTPROCESSOR_MATRIX_COEFF, + POSTPROCESSOR_ANTI_TEARING_EFFECT, + POSTPROCESSOR_ACE_ENABLE, + POSTPROCESSOR_ACE_STRENGTH, + POSTPROCESSOR_ACE_RANGE, + POSTPROCESSOR_OUTPUT_RANGE, + POSTPROCESSOR_REDBLUESWAP +}; + +enum sva_update_type { + UPDATE_MULTIPLE, + UPDATE_LAST +}; + +enum sva_service_type { +NONE = 0, +PREPROCESSOR = 1, +DECODE = 2, +ENCODE = 3, +POSTPROCESSOR = 4, +STILL_IMAGE_ENCODE = 5, +STILL_IMAGE_DECODE = 6, +TV_OUTPUT = 7, +SW_PROCESSING = 8 +}; + +enum service_ctrl_command { +SERVICE_START, +SERVICE_ABORT, +SERVICE_STOP, +SERVICE_FLUSH +}; + +enum sva_service_mode { + REALTIME, + NON_REALTIME +}; + +enum sva_buffer_type { +BUF_TYPE_NONE, +BUF_TYPE_IMAGE, +BUF_TYPE_BITSTREAM, +BUF_TYPE_INFOS, +BUF_TYPE_PARAMS, +/*vc1*/ +BUF_TYPE_VC1_IMAGE, +BUF_TYPE_GB_HQ_PARAMS, +}; + +enum block_type { + BLOCK, + NON_BLOCK, + BLOCK_TIMEOUT +}; + +enum push_type { + PUSH_IN, + PUSH_OUT +}; + +struct sva_buffer { +__u8 flags; +__u8 shared; +__u8 index; +__u8 read_only; /* needed for vc1 decode */ +__u32 phys_addr; +enum sva_buffer_type type; +__u32 offset; +__u32 buffer_id; +__u32 length; +__u32 size; /* also used as bytesused field*/ +__u32 info2; /* extra info2 field*/ +__u32 timestamp; +__u8 count; +}; + +struct sva_queue_buffer { +enum block_type block; +enum push_type push; +__u32 timeout; +struct sva_buffer buffer; +__u32 service_id; +}; + +struct sva_update_service { +__u32 service_id; +enum sva_update_service_param param; +enum sva_update_type type; +void *value; +}; + +struct sva_control_service { +__u32 service_id; +enum service_ctrl_command command; +}; + +enum sva_ace_strength { +ACE_STRENGTH_1 = 1, +ACE_STRENGTH_2, +ACE_STRENGTH_3, +ACE_STRENGTH_4, +ACE_STRENGTH_5, +ACE_STRENGTH_6, +ACE_STRENGTH_7, +ACE_STRENGTH_8 +}; + +struct sva_offset { +__u16 x_offset; +__u16 y_offset; +}; + +struct sva_image { +__u16 height; +__u16 width; +}; + +struct sva_window_desc { +struct sva_image frame; +struct sva_offset offset; +}; + +struct sva_window { +struct sva_image frame; +struct sva_window_desc window; +}; + +struct sva_ppp_tile_info { +struct sva_image image; +struct sva_offset offset; +void *next_tile; +}; + +struct sva_color_matrix { +__s16 matrix_coef1; +__s16 matrix_coef2; +__s16 matrix_coef3; +__s16 matrix_coef4; +}; + +struct sva_yuv_color { +__u8 Y; +__u8 U; +__u8 V; +}; + +enum postprocessor_capability { +POSTPROCESSOR_YUV420MB_TO_RGB, +POSTPROCESSOR_YUV420MB_TO_YUV422PL, +POSTPROCESSOR_YUV420PL_TO_RGB, +POSTPROCESSOR_YUV420MB_TO_YUV420MB, +POSTPROCESSOR_YUV420PL_TO_YUV422PL, +POSTPROCESSOR_YUV422PL_TO_RGB, +}; + +enum preprocessor_capability { +RAW, +YUV420_MB, +YUV420_SEP_COMP_MB, +YUV422_SEP_COMP_MB, +YUV420_RASTER_OUT, +/*vpip*/ +SENSOR_YUV420_MB, +SENSOR_YUV420_SEP_COMP_MB, +SENSOR_YUV422_SEP_COMP_MB, +SENSOR_YUV420_RASTER_OUT, +SENSOR_HIGHQUALITY_YUV420_MB, +}; + +enum videocodec_capability { +H263_P0_L10, +H263_P0_L30, +H263_P3_L10, +H263_P3_L30, +MPEG4_SP_L4A, +H264, +VC1_MP_LL, +MPEG2_MP_ML, +}; + +enum codec_mode { +IMAGE_MODE, +SEGMENTED_MODE, +STREAM_MODE +}; + +enum filter_mode { +NONE_FILTER, +DEBLOCKING, +DERINGING, +DEBLOCKING_DERINGING +}; + +enum color_range { +BT601_RANGE, +FULL_RANGE +}; + +enum sva_color_depth{ +BITS_12, +BITS_15, +BITS_16, +BITS_24, +BITS_32 +}; + +enum sva_mirroring { +NO_MIRRORING, +HORIZONTAL_MIRRORING, +VERTICAL_MIRRORING +}; + +enum sva_rotation{ +NO_ROTATION, +ROTATION_90, +ROTATION_180, +ROTATION_270 +}; + +enum sva_postprocessor_ace_mode{ +ACE_DISABLE, +ACE_INTERNAL, +ACE_EXTERNAL /* when using with Still Image Decoder */ +}; + +enum sva_deblocking_filter{ +NONE_DEBLOCKING_FILTER, +MPEG4_DEBLOCKING_FILTER, +H263_DEBLOCKING_FILTER, +H264_DEBLOCKING_FILTER, +MPEG2_DEBLOCKING_FILTER +}; + +enum sva_deringing_filter{ +NONE_DERINGING_FILTER, +MPEG4_DERINGING_FILTER, +H264_DERINGING_FILTER, +MPEG2_DERINGING_FILTER +}; + +enum sva_chroma_sampling_format{ +DEFAULT_SAMPLING_FORMAT = 0, +MPEG2_4_SAMPLING_FORMAT = 1, +MPEG1_SAMPLING_FORMAT = 2 +}; + +enum brc_intra_refresh_mode { +AIR_DISABLED_CIR_DISABLED=0, +AIR_ENABLED_CIR_DISABLED, +AIR_DISABLED_CIR_ENABLED, +AIR_ENABLED_CIR_ENABLED +}; + +enum sva_rtype_mode { +CONSTANT_ZERO, +CONSTANT_ONE, +TOGGLING +}; + +enum sva_brc_spatial_quality { +QUALITY_NONE, +QUALITY_LOW, +QUALITY_MEDIUM, +QUALITY_HIGH +}; + +enum sva_brc_mode { +CONSTANT_QP, +FRAME_BASE, +CBR, +VBR +}; + +enum brc_buffering_model { +BUFFERING_NONE, +BUFFERING_VBV, +BUFFERING_HRD, +BUFFERING_ANNEXG +}; + +/* MMCO type operations */ +enum sva_h264_mmco_type +{ +END_MMCO=0, +UNMARK_SHORT_REF =1, +UNMARK_LONG_REF, +ASSIGN_LONG_TO_SHORT, +UNMARK_LONG_REF_GREATER, +UNMARK_LONG, +ASSIGN_LONG_TO_CURRENT +}; + +enum sva_tvout_type { +TVO_PAL, +TVO_NTSC +}; + +/*Still Image*/ +enum stillimage_encoder_capability { + ENCODER_JPEG_MONOCHROME, + ENCODER_JPEG_420_SEP_COMP_MB, + ENCODER_JPEG_422_SEP_COMP_MB, + ENCODER_JPEG_444_SEP_COMP_MB, + ENCODER_JPEG_420_MB +}; + +enum stillimage_decoder_capability { + DECODER_PROGRESSIVE_JPEG, + DECODER_SEQUENTIAL_JPEG +}; + +enum sva_thumbnail_mode { + NON_THUMBNAIL, + THUMBNAIL_DC_420MB /* Specific image buffer will have to be pushed out */ +}; + +enum still_image_color_mode{ + MONOCHROME = 1, + COLOR = 3 +}; + +enum sva_downsampling_factor { + DOWNSAMPLING_FACTOR_1, + DOWNSAMPLING_FACTOR_2, + DOWNSAMPLING_FACTOR_4, + DOWNSAMPLING_FACTOR_8 +}; + +struct sva_sampling_factor { + __u16 h_sampling_factor_y; + __u16 v_sampling_factor_y; + __u16 h_sampling_factor_cb; + __u16 v_sampling_factor_cb; + __u16 h_sampling_factor_cr; + __u16 v_sampling_factor_cr;// param SamplingFactor-xx value: 1, 2 or 4 if used + //(used if componentSelector-xx = 1: if color_mode = monochrome only xSamplingFactorY used) +}; + +enum sva_jpeg_encode_on_fly_rotation { + JPEG_ENCODE_ROTATION_NONE, + JPEG_ENCODE_ROTATION_CLOCKWISE, + JPEG_ENCODE_ROTATION_ANTICLOCKWISE +}; + +struct jpeg_algo_params { + enum still_image_color_mode color_mode; + struct sva_sampling_factor sampling_factor; + enum sva_downsampling_factor downsampling_factor; +}; + +struct sva_preprocessor_configuration { +enum preprocessor_capability capability; +struct sva_image source_frame; +struct sva_window_desc cropped_window; +struct sva_image resized_frame; +enum color_range output_range; +Bool ace_enable; +enum sva_ace_strength ace_strength; +enum color_range ace_range; +__u32 frame_rate; +__u16 sensor_aoi_x; +__u16 sensor_aoi_y; +__u16 prescale_factor; + +}; + +struct sva_postprocessor_configuration { +enum postprocessor_capability capability; +Bool direct_display; +struct sva_image source_frame; +struct sva_window_desc cropped_window; +struct sva_image resized_frame; +struct sva_window_desc clipped_window; +struct sva_window_desc display_window; +struct sva_color_matrix matrix; +enum color_range output_range; +enum sva_postprocessor_ace_mode ace_mode; +enum sva_ace_strength ace_strength; +enum color_range ace_range; +enum sva_color_depth depth; +enum sva_mirroring mirroring; +enum sva_rotation rotation; +Bool dithering; +enum sva_deblocking_filter deblocking_filter; +enum sva_deringing_filter deringing_filter; +enum sva_chroma_sampling_format chroma_sampling; +__u8 brightness; +__u8 contrast; +__u8 alpha_key; +__u8 red_blue_swap; +Bool raster_in_format; +}; + +struct sva_tvout_configuration { +struct sva_window source_frame_window; +struct sva_offset destination_window_offset; +struct sva_yuv_color background_yuv_color; +enum sva_tvout_type tvo_type; +}; + +struct mpeg4_algo_params { + +Bool short_header; +__u16 vop_time_increment; +Bool resync_marker_disable; +Bool data_partitioned; +Bool reversible_vlc; + +/** + Stream Configuration info: + Added for support of advanced + simple profile + ~ SVA 8.0.0 migration */ +Bool isInterlaced; +__u16 low_delay; +__u16 quant_type; +__u16 intra_quant_mat[64] ; +__u16 nonintra_quant_mat[64]; +__u8 profile; + +}; + +struct mpeg4_header_infos { + +__u16 picture_coding_type; +__u16 quantization; +__u16 rounding_type; +__u16 intra_acdc_thr; +__u16 vop_fcode_forward; +__u32 bitstream_offset; +__u32 bitstream_address; + +/** + Frame Configuration info: + Added for support of advanced + simple profile + ~ SVA 8.0.0 migration */ +__u16 vop_fcode_backward; +__u16 vop_time_increment; +__u16 modulo_time_base; + +}; + +/* mpeg2 decode algo params & header infos */ +typedef enum { + MPEG2_PICTURE_SLICE_I = 1, + MPEG2_PICTURE_SLICE_P, + MPEG2_PICTURE_SLICE_B, + MPEG2_PICTURE_SLICE_D, + MPEG2_PICTURE_SLICE_SKIPPED +} mpeg2_picture_t; + +struct mpeg2_algo_params { +Bool load_intra_quantiser_matrix; +Bool load_nonintra_quantiser_matrix; +Bool progressive_sequence; +__u8 profile_level_indication; +__u8 chroma_format; +__u32 bit_rate; +}; + +struct mpeg2_header_infos { +__u16 horizontal_size; +__u16 vertical_size; +__u16 mb_height; + +__u16 intra_quantizer_matrix[64]; +__u16 non_intra_quantizer_matrix[64]; + +mpeg2_picture_t picture_coding_type; + +__u16 full_pel_forward_vector; +__u16 forward_f_code; +__u16 full_pel_backward_vector; +__u16 backward_f_code; + +__u16 f_code[2][2]; + +__u16 intra_dc_precision; +__u16 picture_structure; +__u16 top_field_first; +__u16 frame_pred_frame_dct; +__u16 concealment_motion_vectors; +__u16 q_scale_type; +__u16 intra_vlc_format; +__u16 alternate_scan; + +__u16 scalable_mode; +__u16 MPEG2_Flag; + +__u32 bitstream_offset; +__u32 bitstream_address; +}; + +struct h264_algo_params { +__u16 level_idc; +__u16 number_ref_frames; +__u16 gaps_in_frame_num_value_flag; +__u16 pic_order_cnt_type; +__u16 log_2_max_frame_num_minus4; +__u16 log_2_max_pic_order_cnt_lsb_minus4; +__u32 offset_for_non_ref_pic; +__u32 num_ref_frames_in_pic_order_cnt_cycle; +__u16 offset_for_ref_frame[256]; +__u32 offset_for_top_to_bottom_field; +}; + +struct h264_slice_header_infos { +__u16 nut; +__u16 nri; +__u32 slice_start_offset; +__u32 slice_bits_offset; +size_t slice_size; +__u16 slice_beta_offset_div2; +__u16 first_mb_in_slice; +__u16 slice_type; +__u16 num_ref_idx_10_active_minus1; +__s16 slice_qp_delta; +__u16 disable_deblocking_filter_idc; +__u16 slice_alpha_c0_offset_div2; +__u16 slice_num; +__u16 slice_qp ; +__u16 num_ref_idx_active_override_flag; +__u16 ref_pic_list_reordering_flag_l0; +__u16 frame_num; +__u16 reordering_of_pic_nums_idc[16]; +__u16 abs_diff_pic_num_minus1[16]; +__u16 long_term_pic_num[16]; +struct h264_slice_header_infos *next; +}; + +struct h264_header_infos +{ +__u16 chroma_qp_index; +__u16 constr_intra_pred_flag; +__u16 num_ref_idx_l0_active_minus1; +__u16 slice_0_slice_group_change_cycle; +__u16 num_slice_groups_minus1; +__u16 slice_group_map_type; +__u16 run_lenght_minus1[8]; +__u16 top_left[8]; +__u16 bottom_right[8]; +__u16 slice_group_change_dir_flag; +__u16 slice_group_change_rate_minus1; +__u16 slice_group_id[1620]; +__u16 slice_0_nut; +__u16 slice_0_nri; +__u16 slice_0_frame_num; +__u16 slice_0_pic_order_cnt_lsb; +__s32 slice_0_delta_pic_order_cnt[2]; +__s32 slice_0_delta_pic_order_cnt_bottom; +__u16 slice_0_long_term_reference_flag; +__u16 slice_0_no_output_of_prior_pics_flag; +__u16 slice_0_adaptive_ref_pic_marking_mode_flag; +enum sva_h264_mmco_type slice_0_memory_management_control_operation[16]; +__u16 slice_0_difference_of_pic_nums_minus1[16]; +__u16 slice_0_marking_long_term_pic_num[16]; +__u16 slice_0_long_term_frame_idx[16]; +__u16 slice_0_max_long_term_frame_idx_plus1[16]; +__u16 nb_slices_in_frame; +struct h264_slice_header_infos *pslice_header; /* from each slice headers */ +}; + + /* vc1 decode algo params & header infos */ +typedef enum { + VC1_PICTURE_TYPE_I = 0, + VC1_PICTURE_TYPE_P, + VC1_PICTURE_TYPE_B, + VC1_PICTURE_TYPE_BI, + VC1_PICTURE_SKIPPED +} vc1_picture_t; + +struct vc1_algo_params { + /* sequence layer parameters */ + __u8 profile; + __u8 level; + __u8 quantizer; + __u8 dquant; + __u8 max_b_frames; + __u8 q_framerate_for_postproc; + __u8 q_bitrate_for_postproc; + + Bool loop_filter_enabled; + Bool multires_coding_enabled; + Bool fast_uvmc_enabled; + Bool extended_mv_enabled; + Bool variable_size_transform_enabled; + Bool overlap_transform_enabled; + Bool syncmarker_enabled; + Bool rangered_enabled; + Bool frame_interpolation_enabled; + Bool is_smpte_conformant; +}; + +struct vc1_header_infos { + __u32 framesize; + vc1_picture_t picture_coding_type; +}; + + +/*JPEG data structures*/ + +struct sva_quantization_table { + __u16 quant_y[64]; // value range for quant_y/cb/cr params: 1 to 255 + __u16 quant_cb[64]; + __u16 quant_cr[64]; +} ; + +struct sva_huffman_table{ + __u16 huffmanYCodeDc[12]; + __u16 huffmanYSizeDc[12]; // value range for huffman-Y/Cb/Cr-Size-Dc/Ac params: 1 to 16 (if 0 it will not be used) + __u16 huffmanYCodeAc[256]; + __u16 huffmanYSizeAc[256]; + __u16 huffmanCbCodeDc[12]; + __u16 huffmanCbSizeDc[12]; + __u16 huffmanCbCodeAc[256]; + __u16 huffmanCbSizeAc[256]; + __u16 huffmanCrCodeDc[12]; + __u16 huffmanCrSizeDc[12]; + __u16 huffmanCrCodeAc[256]; + __u16 huffmanCrSizeAc[256]; +}; + +struct sva_still_decoder_algo_sequential_jpeg_header_infos{ + __u16 restartInterval; + struct sva_huffman_table huffmanTable; + struct sva_quantization_table quantizationTable; + +}; + +struct sva_still_decoder_algo_progressive_jpeg_header_infos{ + __u16 nbScanComponents; + __u16 componentSelectorY; //value: 0 = the Y component is not present in the current scan; 1 = present + __u16 componentSelectorCb; //value: 0 = the Cb component is not present in the current scan; 1 = present + __u16 componentSelectorCr; //value: 0 = the Cr component is not present in the current scan; 1 = present + __u16 startSpectralSelection; // value range: 0 to 63 + __u16 endSpectralSelection; // value range: startSpectralSelection to 63 + __u16 successiveApproxPosition; + __u16 restartInterval; + struct sva_huffman_table huffmanTable; + struct sva_quantization_table quantizationTable; +}; + +struct sva_codec_header_infos { +__u32 service_id; +__u32 buffer_id; +union { + struct mpeg4_header_infos mpeg4; + struct h264_header_infos h264; + struct vc1_header_infos vc1; + struct mpeg2_header_infos mpeg2; + struct sva_still_decoder_algo_sequential_jpeg_header_infos jpeg_sequential; + struct sva_still_decoder_algo_progressive_jpeg_header_infos jpeg_progressive; +} infos; + +}; + +struct sva_videodecoder_configuration { +enum videocodec_capability capability; +Bool is_infos_requested; +enum codec_mode mode; +enum filter_mode in_filter; +enum filter_mode out_filter; +struct sva_image frame; +void *codec_params; +__u16 vop_time_increment; +}; + +struct sva_brc_constant_qp_config_params { +__u32 intra_refresh; +__u8 i_picture_qp; +__u8 p_picture_qp; +__u32 bit_rate; +__u32 vbv_buffer_size; +__u32 vbv_occupancy; +__u32 swiss_buffer; +}; + +struct sva_brc_framebase_config_params { +__u32 dummy; +}; + +struct sva_brc_cbr_config_params { +__u32 intra_refresh; +__u32 bit_rate; +__u32 vbv_buffer_size; +__u32 vbv_occupancy; +__u32 swiss_buffer; +}; + +struct sva_brc_vbr_config_params { +__u32 intra_refresh; +__u32 bit_rate; +enum sva_brc_spatial_quality spatial_quality; +__u32 min_frame_rate; +__u32 vbv_buffer_size; +__u32 vbv_occupancy; +__u32 swiss_buffer; +}; + +struct mpeg4_encode_algo_params { +Bool short_header; +__u16 gob_header_freq; +Bool data_partitioned; +Bool reversible_vlc; +__u16 hec_freq; +__u16 vp_size_type; +__u16 vp_size_max; +__u16 vp_bit_size; +__u16 vp_mb_size; +enum brc_intra_refresh_mode refresh_mode; +__u16 air_mb_num; +__u16 cir_period_max; +enum sva_rtype_mode rtype_mode; +Bool system_header_before_intra; +__u8 profile_level; +__u16 vop_time_increment; +__u16 vop_time_increment_resolution; +}; + +struct h264_encode_algo_params{ +__s32 profile_idc; +__s32 level_idc; +//__s32 no_frames; +//__s32 qp0; +//__s32 qpn; +__s32 qp_i_slice; +__s32 qp_p_slice; +//__s32 hadamard; +__s32 search_range; +//__s32 jumpd; +//__s32 log_2_max_frame_num; +__s32 log_2_max_fnum_minus4; +//__u16 frame_width; +//__u16 frame_height; +//__s32 width_cr; +//__s32 height_cr; +__s16 slice_size_type; +__s16 slice_mb_size; +__s16 slice_bit_size; +__s32 use_constrained_intra_pred; +//__s32 infile_header; +__s32 intra_period; +__s32 idr_enable; +//__s32 start_frame; +__s32 annexb; +//__u16 intra_disable; +__s32 intra_disable_inter_only; +__s32 intra_4x4_par_disable; +__s32 intra_4x4_diag_disable; +__s32 intra_4x4_dir_disable; +__s32 intra_16x16_par_disable; +__s32 intra_16x16_plane_disable; +__s32 chroma_intra_disable; +__u16 intra_disable; +__u16 frame_rate; +__s32 chroma_qp_index_offset; +__s32 pic_order_cnt_type; +//__s32 report_frame_stats; +//__s16 brc_type; +__s32 bit_rate; +__s32 se_initial_qp; +//__s32 basic_unit; +__u16 me_type; +__s32 hrd_send_messages; +__u32 cpb_buffer_size; +__u16 intra_refresh_type; +__u16 air_mb_num; +//__u16 cir_period_max; +//__s16 slice_loss_first_mb[8]; +//__s16 slice_loss_mb_num[8]; +__s32 aspect_ratio_info_present_flag; +__s32 aspect_ratio_idc; +__s32 sar_width; +__s32 sar_height; +__s32 disable_deblocking_filter_idc; +__s32 slice_alpha; +__s32 slice_beta; +__s32 video_signal_type_present_flag; +__s32 video_format; +__s32 video_full_range_flag; +__s32 colour_description_present_flag; +__s32 colour_primaries; +__s32 transfer_characteristics; +__s32 matrix_coefficients; +__s32 intra_forced; +}; + +struct sva_videoencoder_configuration { +enum videocodec_capability capability; +Bool is_infos_requested; +Bool cropping_vector; +Bool destination_buffer; +enum codec_mode mode; +struct sva_window source_frame_desc; +enum filter_mode in_filter; +enum filter_mode out_filter; +enum sva_brc_mode brc_mode; +enum brc_buffering_model buffering_model; +void *brc_config_params; +void *codec_params; +__u16 vop_time_increment; +}; + +struct sva_stillimagedecoder_configuration { + enum stillimage_decoder_capability capability; + enum codec_mode mode; + struct sva_image decoded_frame_desc; + struct sva_window_desc crop_window; + enum sva_ace_strength ace_strength; + Bool is_cropping_enabled; + Bool no_slice_mode; + void * sva_still_algo_configuration_params; +}; + + +struct jpeg_encoder_algo_params { + __u16 restartInterval; + Bool isOptimizeQuantTableEnable; + enum sva_jpeg_encode_on_fly_rotation rotation; + Bool isOptimizeHuffmanTableEnable; + __u16 targetBpp; + struct sva_quantization_table quantizationTable; + struct sva_huffman_table huffmanTable; +}; + + + +struct sva_stillimageencoder_configuration { + enum stillimage_encoder_capability capability; + enum codec_mode mode; + Bool is_slice_mode; + enum sva_thumbnail_mode thumbnail_mode; + struct sva_window source_frame_desc; + Bool raster_in_format; + void * sva_still_algo_configuration_params; +}; + + +struct sva_service_struct { +enum sva_service_type service_type; +enum sva_service_mode mode; +__u32 service_id; +__u8 index; +union { + struct sva_preprocessor_configuration preprocessor_configuration; + struct sva_postprocessor_configuration postprocessor_configuration; + struct sva_videodecoder_configuration videodecoder_configuration; + struct sva_videoencoder_configuration videoencoder_configuration; + struct sva_stillimagedecoder_configuration stillimagedecoder_configuration; + struct sva_stillimageencoder_configuration stillimageencoder_configuration; + struct sva_tvout_configuration tvout_configuration; + }config; + +}; + +enum sva_message_type { + BUFFER_FILLED, + BUFFER_VOIDED, + EVENT_OVERFLOW, + EVENT_UNDERFLOW, + BUFFER_FILLED_READ_ONLY, + BUFFER_FILLED_PARTIALLY +}; + + +typedef enum { + + + //"DeviceParameters//" + DeviceParameters_uwDeviceId_LSByte =0 , + DeviceParameters_uwDeviceId_MSByte , + DeviceParameters_bFirmwareVersionMajor , + DeviceParameters_bFirmwareVersionMinor , + DeviceParameters_bHardwareVersionMajor , + DeviceParameters_bHardwareVersionMinor , + + //"ModeManagerControl//" , + + ModeManagerControl_bUserCommand , + ModeManagerControl_fTestStateMachine , + ModeManagerControl_fForceTestState , + ModeManagerControl_bManualNextState , + ModeManagerControl_bTestCoin , + + //"ModeManagerStatus//" , + + ModeManagerStatus_bThisLoLevelState , + ModeManagerStatus_bNextLoLevelState , + ModeManagerStatus_bHiLevelState , + ModeManagerStatus_bCycles , + ModeManagerStatus_fModeStaticSetupsChanged , + ModeManagerStatus_bTestCoin , + ModeManagerStatus_fCycleForTest , + ModeManagerStatus_bNumberOfFramesStreamed , + ModeManagerStatus_bPrevFrameCountForExposure , + + //"RunModeControl//" , + + RunModeControl_fMeteringOn , + RunModeControl_fExitOnStable , + RunModeControl_bStreamLength , + RunModeControl_fMeterBeforeStreaming , + RunModeControl_fChkForAF_Stability , + RunModeControl_fChkForExposure_Stability , + RunModeControl_fChkForWhiteBalance_Stability , + + //"ModeSetupBankSelector//" , + + ModeSetupBankSelector_bRequiredModeSetupBank , + + //"PipeSetupBankSelector//" , + + PipeSetupBankSelector_bRequiredPipe0SetupBank , + + //"ModeSetupBank0//" , + + ModeSetupBank0_uwInputImageSize_X_LSByte , + ModeSetupBank0_uwInputImageSize_X_MSByte , + ModeSetupBank0_uwInputImageSize_Y_LSByte , + ModeSetupBank0_uwInputImageSize_Y_MSByte , + ModeSetupBank0_uwMaxImageSize_X_LSByte , + ModeSetupBank0_uwMaxImageSize_X_MSByte , + ModeSetupBank0_uwMaxImageSize_Y_LSByte , + ModeSetupBank0_uwMaxImageSize_Y_MSByte , + ModeSetupBank0_uwMinImageSize_X_LSByte , + ModeSetupBank0_uwMinImageSize_X_MSByte , + ModeSetupBank0_uwMinImageSize_Y_LSByte , + ModeSetupBank0_uwMinImageSize_Y_MSByte , + ModeSetupBank0_bActiveSensor, + ModeSetupBank0_fLowPowerStreaming , + ModeSetupBank0_bTestMode , + ModeSetupBank0_bNumberOfStatusLines , + ModeSetupBank0_bNumberOfDarkLines , + ModeSetupBank0_bNumberOfBlackLines , + ModeSetupBank0_uwNumberOfInterLinePixelClocks_LSByte , + ModeSetupBank0_uwNumberOfInterLinePixelClocks_MSByte , + ModeSetupBank0_uwNumberOfInterFrameLines_LSByte , + ModeSetupBank0_uwNumberOfInterFrameLines_MSByte , + ModeSetupBank0_bNumberOfDummyColumns , + ModeSetupBank0_bInputImageSource , + ModeSetupBank0_bOutputImageDestination , + + //"PipeSetupBankA//" , + + PipeSetupBankA_uwPipeOutputSize_X_LSByte , + PipeSetupBankA_uwPipeOutputSize_X_MSByte , + PipeSetupBankA_uwPipeOutputSize_Y_LSByte , + PipeSetupBankA_uwPipeOutputSize_Y_MSByte , + PipeSetupBankA_bPipeOutputFormat , + PipeSetupBankA_bPipeStreamLength , + PipeSetupBankA_fTogglePixValid , + PipeSetupBankA_fEnableItuEmbeddedCodes , + PipeSetupBankA_bPixValidLineTypes , + PipeSetupBankA_fGenerateVSync , + PipeSetupBankA_fCb_Cr_Flip , + PipeSetupBankA_fY_CbCr_Flip , + + //"PipeSetupBankB//" , + + PipeSetupBankB_uwPipeOutputSize_X_LSByte, + PipeSetupBankB_uwPipeOutputSize_X_MSByte , + PipeSetupBankB_uwPipeOutputSize_Y_LSByte , + PipeSetupBankB_uwPipeOutputSize_Y_MSByte , + PipeSetupBankB_bPipeOutputFormat , + PipeSetupBankB_bPipeStreamLength , + PipeSetupBankB_fTogglePixValid , + PipeSetupBankB_fEnableItuEmbeddedCodes , + PipeSetupBankB_bPixValidLineTypes , + PipeSetupBankB_fGenerateVSync , + PipeSetupBankB_fCb_Cr_Flip , + PipeSetupBankB_fY_CbCr_Flip , + + //"HostInterfaceManagerControl//" , + + HostInterfaceManagerControl_bUserCommand , + HostInterfaceManagerControl_fTestStateMachine , + HostInterfaceManagerControl_fForceTestState , + HostInterfaceManagerControl_bManualNextState , + HostInterfaceManagerControl_bTestCoin , + HostInterfaceManagerControl_fAutoTransitionFromRxStopped , + HostInterfaceManagerControl_fStopSensor , + + //"HostInterfaceManagerStatus//" , + + HostInterfaceManagerStatus_bThisLoLevelState , + HostInterfaceManagerStatus_bNextLoLevelState , + HostInterfaceManagerStatus_bHiLevelState , + HostInterfaceManagerStatus_bCycles , + HostInterfaceManagerStatus_bTestCoin , + HostInterfaceManagerStatus_fCycleForTest , + + //"StreamManagerStatus//" , + + StreamManagerStatus_bStreamStatus , + StreamManagerStatus_fIsSensorRunning , + + //"ClockManagerControl//" , + + ClockManagerControl_fClockManagerInDebugState , + + //"LocalPipe0SetupBank//" , + + LocalPipe0SetupBank_uwPipeOutputSize_X_LSByte , + LocalPipe0SetupBank_uwPipeOutputSize_X_MSByte , + LocalPipe0SetupBank_uwPipeOutputSize_Y_LSByte , + LocalPipe0SetupBank_uwPipeOutputSize_Y_MSByte , + LocalPipe0SetupBank_bPipeOutputFormat , + LocalPipe0SetupBank_bPipeStreamLength , + LocalPipe0SetupBank_fTogglePixValid , + LocalPipe0SetupBank_fEnableItuEmbeddedCodes , + LocalPipe0SetupBank_bPixValidLineTypes , + LocalPipe0SetupBank_fGenerateVSync , + LocalPipe0SetupBank_fCb_Cr_Flip , + LocalPipe0SetupBank_fY_CbCr_Flip , + + //"Pipe0Control//" , + + Pipe0Control_bPipeControl , + Pipe0Control_fPipeRefreshRequired , + Pipe0Control_fSfxSolariseEnabled , + Pipe0Control_fSfxNegativeEnabled , + Pipe0Control_ReplaceRedChannel, + Pipe0Control_ReplaceGreenChannel , + Pipe0Control_ReplaceBlueChannel , + Pipe0Control_fOverrideOFCropRegisters , + Pipe0Control_uwHCropRising_LSByte , + Pipe0Control_uwHCropRising_MSByte , + Pipe0Control_uwHCropFalling_LSByte , + Pipe0Control_uwHCropFalling_MSByte , + Pipe0Control_uwVCropRisingCrse_LSByte , + Pipe0Control_uwVCropRisingCrse_MSByte , + Pipe0Control_uwVCropFallingCrse_LSByte , + Pipe0Control_uwVCropFallingCrse_MSByte , + + //"Pipe0Status//" , + + Pipe0Status_bPipeStatus , + Pipe0Status_fPipeEnablePending , + Pipe0Status_bNumberOfFramesStreamed , + Pipe0Status_fDitherEnabled , + Pipe0Status_fVidCompletePending , + + //"HostToSensorAccessControl//" , + + HostToSensorAccessControl_bRequest , + HostToSensorAccessControl_bCommandCoin , + HostToSensorAccessControl_uwSensorIndex_LSByte , + HostToSensorAccessControl_uwSensorIndex_MSByte , + + //"HostToSensorAccessStatus//" , + + HostToSensorAccessStatus_bStatusCoin , + HostToSensorAccessStatus_bHostToSensorAccessErrorCount, + + //"HostToSensorAccessData//" , + + HostToSensorAccessData_uwDataLow_LSByte , + HostToSensorAccessData_uwDataLow_MSByte , + HostToSensorAccessData_uwDataHigh_LSByte , + HostToSensorAccessData_uwDataHigh_MSByte , + + //"MasterI2cControl//" , + + MasterI2cControl_bSensorSerialAddress , + MasterI2cControl_uwClk_Sensor_Comms_mhz_LSByte , + MasterI2cControl_uwClk_Sensor_Comms_mhz_MSByte , + MasterI2cControl_uwRequiredI2cSpeed_LSByte , + MasterI2cControl_uwRequiredI2cSpeed_MSByte , + MasterI2cControl_bMaximumNumberOfGrabAttempts , + + //"MasterI2cStatus//" , + + MasterI2cStatus_bResourceStatus , + MasterI2cStatus_uwI2CClkDiv_LSByte , + MasterI2cStatus_uwI2CClkDiv_MSByte , + MasterI2cStatus_fTransactionError , + MasterI2cStatus_bNumberOfTransactionFailures , + MasterI2cStatus_bNumberOfConsecutiveGrabFailures , + MasterI2cStatus_bNumberOfForcedReleases , + MasterI2cStatus_bNumberOfMcuClockDeratingAttemptsInhibited , + + //"VideoTimingHostInputs//" , + + VideoTimingHostInputs_VideoTimingMode, + VideoTimingHostInputs_bSensorBitsPerSystemClock , + VideoTimingHostInputs_uwCsiRawFormat_LSByte , + VideoTimingHostInputs_uwCsiRawFormat_MSByte , + VideoTimingHostInputs_fpHostRxMaxDataRate_Mbps_LSByte , + VideoTimingHostInputs_fpHostRxMaxDataRate_Mbps_MSByte , + VideoTimingHostInputs_VsyncPolarity , + VideoTimingHostInputs_HsyncPolarity , + + //"VideoTimingSensorFifoControl//" , + + VideoTimingSensorFifoControl_bFiFoWaterMarkProgrammingMode , + VideoTimingSensorFifoControl_uwFifoWaterMarkPixels_LSByte , + VideoTimingSensorFifoControl_uwFifoWaterMarkPixels_MSByte , + VideoTimingSensorFifoControl_uwFifoSizePixels_LSByte , + VideoTimingSensorFifoControl_uwFifoSizePixels_MSByte , + + //"VideoTimingSensorScalingAndSubSamplingControl//" , + + VideoTimingSensorScalingAndSubSamplingControl_fpOutputClockDeratingFraction_LSByte , + VideoTimingSensorScalingAndSubSamplingControl_fpOutputClockDeratingFraction_MSByte , + VideoTimingSensorScalingAndSubSamplingControl_bOutputClockDeratingRoundingMode , + VideoTimingSensorScalingAndSubSamplingControl_fDerateVideoTimingClockForProfileZero , + + //"VideoTimingSensorConstraints//" , + + VideoTimingSensorConstraints_uwMinimumPrePllClockDiv_LSByte , + VideoTimingSensorConstraints_uwMinimumPrePllClockDiv_MSByte , + VideoTimingSensorConstraints_uwMaximumPrePllClockDiv_LSByte , + VideoTimingSensorConstraints_uwMaximumPrePllClockDiv_MSByte , + VideoTimingSensorConstraints_fpMinimumPllInputFrequency_Mhz_LSByte , + VideoTimingSensorConstraints_fpMinimumPllInputFrequency_Mhz_MSByte, + VideoTimingSensorConstraints_uwMinimumPllMultiplier_LSByte , + VideoTimingSensorConstraints_uwMinimumPllMultiplier_MSByte , + VideoTimingSensorConstraints_uwMaximumPllMultiplier_LSByte , + VideoTimingSensorConstraints_uwMaximumPllMultiplier_MSByte , + VideoTimingSensorConstraints_fpMaximumPllOutputFrequency_Mhz_LSByte , + VideoTimingSensorConstraints_fpMaximumPllOutputFrequency_Mhz_MSByte , + VideoTimingSensorConstraints_uwMinimumVTSysClockDiv_LSByte , + VideoTimingSensorConstraints_uwMinimumVTSysClockDiv_MSByte , + VideoTimingSensorConstraints_uwMaximumVTSysClockDiv_LSByte , + VideoTimingSensorConstraints_uwMaximumVTSysClockDiv_MSByte , + VideoTimingSensorConstraints_fpMaximumVTSystemClockFrequency_Mhz_LSByte , + VideoTimingSensorConstraints_fpMaximumVTSystemClockFrequency_Mhz_MSByte , + VideoTimingSensorConstraints_uwMinimumVTPixelClockDiv_LSByte , + VideoTimingSensorConstraints_uwMinimumVTPixelClockDiv_MSByte , + VideoTimingSensorConstraints_uwMaximumVTPixelClockDiv_LSByte , + VideoTimingSensorConstraints_uwMaximumVTPixelClockDiv_MSByte , + VideoTimingSensorConstraints_fpMaximumVTPixelClockFrequency_Mhz_LSByte , + VideoTimingSensorConstraints_fpMaximumVTPixelClockFrequency_Mhz_MSByte , + VideoTimingSensorConstraints_uwMinimumOPSysClockDiv_LSByte , + VideoTimingSensorConstraints_uwMinimumOPSysClockDiv_MSByte , + VideoTimingSensorConstraints_uwMaximumOPSysClockDiv_LSByte , + VideoTimingSensorConstraints_uwMaximumOPSysClockDiv_MSByte , + VideoTimingSensorConstraints_fpMaximumOPSystemClockFrequency_Mhz_LSByte , + VideoTimingSensorConstraints_fpMaximumOPSystemClockFrequency_Mhz_MSByte , + VideoTimingSensorConstraints_fpMaximumOPPixelClockFrequency_Mhz_LSByte , + VideoTimingSensorConstraints_fpMaximumOPPixelClockFrequency_Mhz_MSByte , + + //"SensorScalingSubSamplingCapabilities//" , + + SensorScalingSubSamplingCapabilities_bSensorScalingMode , + SensorScalingSubSamplingCapabilities_uwScalerMMin_LSByte, + SensorScalingSubSamplingCapabilities_uwScalerMMin_MSByte , + SensorScalingSubSamplingCapabilities_uwScalerMMax_LSByte , + SensorScalingSubSamplingCapabilities_uwScalerMMax_MSByte , + SensorScalingSubSamplingCapabilities_uwMaxOddInc_LSByte , + SensorScalingSubSamplingCapabilities_uwMaxOddInc_MSByte , + + //"VideoTimingOutput//" , + + VideoTimingOutput_uwPrePllClockDiv_LSByte , + VideoTimingOutput_uwPrePllClockDiv_MSByte , + VideoTimingOutput_fpPllInputFrequency_Mhz_LSByte , + VideoTimingOutput_fpPllInputFrequency_Mhz_MSByte , + VideoTimingOutput_uwPllMultiplier_LSByte , + VideoTimingOutput_uwPllMultiplier_MSByte , + VideoTimingOutput_fpPllOutputFrequency_Mhz_LSByte , + VideoTimingOutput_fpPllOutputFrequency_Mhz_MSByte , + VideoTimingOutput_uwVTSystemClockDiv_LSByte , + VideoTimingOutput_uwVTSystemClockDiv_MSByte , + VideoTimingOutput_fpVTSystemClockFrequency_Mhz_LSByte , + VideoTimingOutput_fpVTSystemClockFrequency_Mhz_MSByte , + VideoTimingOutput_uwVTPixelClockDiv_LSByte , + VideoTimingOutput_uwVTPixelClockDiv_MSByte , + VideoTimingOutput_fpVTPixelClockFrequency_Mhz_LSByte , + VideoTimingOutput_fpVTPixelClockFrequency_Mhz_MSByte , + VideoTimingOutput_fpVTPixelClockPeriod_us_LSByte , + VideoTimingOutput_fpVTPixelClockPeriod_us_MSByte , + VideoTimingOutput_uwOPSystemClockDiv_LSByte , + VideoTimingOutput_uwOPSystemClockDiv_MSByte , + VideoTimingOutput_fpOPSystemClockFrequency_Mhz_LSByte , + VideoTimingOutput_fpOPSystemClockFrequency_Mhz_MSByte , + VideoTimingOutput_uwOPPixelClockDiv_LSByte, + VideoTimingOutput_uwOPPixelClockDiv_MSByte , + VideoTimingOutput_fpOPPixelClockFrequency_Mhz_LSByte , + VideoTimingOutput_fpOPPixelClockFrequency_Mhz_MSByte , + VideoTimingOutput_fpOutputTimingClockDerating_LSByte , + VideoTimingOutput_fpOutputTimingClockDerating_MSByte , + + //"DummyPage5//" , + + DummyPage5_bDummyPageElement , + + //"VideoTimingInputsFarSensor//" , + + VideoTimingInputsFarSensor_VideoTimingMode , + VideoTimingInputsFarSensor_bSensorBitsPerSystemClock , + VideoTimingInputsFarSensor_uwCsiRawFormat_LSByte , + VideoTimingInputsFarSensor_uwCsiRawFormat_MSByte , + VideoTimingInputsFarSensor_fpHostRxMaxDataRate_Mbps_LSByte , + VideoTimingInputsFarSensor_fpHostRxMaxDataRate_Mbps_MSByte , + VideoTimingInputsFarSensor_VsyncPolarity , + VideoTimingInputsFarSensor_HsyncPolarity , + + //"SensorFarVideoTimingSensorFifoControl//" , + + SensorFarVideoTimingSensorFifoControl_bFiFoWaterMarkProgrammingMode , + SensorFarVideoTimingSensorFifoControl_uwFifoWaterMarkPixels_LSByte , + SensorFarVideoTimingSensorFifoControl_uwFifoWaterMarkPixels_MSByte , + SensorFarVideoTimingSensorFifoControl_uwFifoSizePixels_LSByte , + SensorFarVideoTimingSensorFifoControl_uwFifoSizePixels_MSByte , + + //"VideoTimingFarSensorConstraints//" , + + VideoTimingFarSensorConstraints_uwMinimumPrePllClockDiv_LSByte , + VideoTimingFarSensorConstraints_uwMinimumPrePllClockDiv_MSByte , + VideoTimingFarSensorConstraints_uwMaximumPrePllClockDiv_LSByte , + VideoTimingFarSensorConstraints_uwMaximumPrePllClockDiv_MSByte , + VideoTimingFarSensorConstraints_fpMinimumPllInputFrequency_Mhz_LSByte , + VideoTimingFarSensorConstraints_fpMinimumPllInputFrequency_Mhz_MSByte , + VideoTimingFarSensorConstraints_uwMinimumPllMultiplier_LSByte , + VideoTimingFarSensorConstraints_uwMinimumPllMultiplier_MSByte , + VideoTimingFarSensorConstraints_uwMaximumPllMultiplier_LSByte , + VideoTimingFarSensorConstraints_uwMaximumPllMultiplier_MSByte , + VideoTimingFarSensorConstraints_fpMaximumPllOutputFrequency_Mhz_LSByte , + VideoTimingFarSensorConstraints_fpMaximumPllOutputFrequency_Mhz_MSByte , + VideoTimingFarSensorConstraints_uwMinimumVTSysClockDiv_LSByte , + VideoTimingFarSensorConstraints_uwMinimumVTSysClockDiv_MSByte , + VideoTimingFarSensorConstraints_uwMaximumVTSysClockDiv_LSByte , + VideoTimingFarSensorConstraints_uwMaximumVTSysClockDiv_MSByte , + VideoTimingFarSensorConstraints_fpMaximumVTSystemClockFrequency_Mhz_LSByte , + VideoTimingFarSensorConstraints_fpMaximumVTSystemClockFrequency_Mhz_MSByte , + VideoTimingFarSensorConstraints_uwMinimumVTPixelClockDiv_LSByte , + VideoTimingFarSensorConstraints_uwMinimumVTPixelClockDiv_MSByte , + VideoTimingFarSensorConstraints_uwMaximumVTPixelClockDiv_LSByte , + VideoTimingFarSensorConstraints_uwMaximumVTPixelClockDiv_MSByte , + VideoTimingFarSensorConstraints_fpMaximumVTPixelClockFrequency_Mhz_LSByte , + VideoTimingFarSensorConstraints_fpMaximumVTPixelClockFrequency_Mhz_MSByte , + VideoTimingFarSensorConstraints_uwMinimumOPSysClockDiv_LSByte , + VideoTimingFarSensorConstraints_uwMinimumOPSysClockDiv_MSByte , + VideoTimingFarSensorConstraints_uwMaximumOPSysClockDiv_LSByte , + VideoTimingFarSensorConstraints_uwMaximumOPSysClockDiv_MSByte , + VideoTimingFarSensorConstraints_fpMaximumOPSystemClockFrequency_Mhz_LSByte , + VideoTimingFarSensorConstraints_fpMaximumOPSystemClockFrequency_Mhz_MSByte , + VideoTimingFarSensorConstraints_fpMaximumOPPixelClockFrequency_Mhz_LSByte, + VideoTimingFarSensorConstraints_fpMaximumOPPixelClockFrequency_Mhz_MSByte , + + //"SensorFarScalingSubSamplingCapabilities//" , + + SensorFarScalingSubSamplingCapabilities_bSensorScalingMode , + SensorFarScalingSubSamplingCapabilities_uwScalerMMin_LSByte , + SensorFarScalingSubSamplingCapabilities_uwScalerMMin_MSByte , + SensorFarScalingSubSamplingCapabilities_uwScalerMMax_LSByte , + SensorFarScalingSubSamplingCapabilities_uwScalerMMax_MSByte , + SensorFarScalingSubSamplingCapabilities_uwMaxOddInc_LSByte , + SensorFarScalingSubSamplingCapabilities_uwMaxOddInc_MSByte , + + //"VideoTimingFarOutput//" , + + VideoTimingFarOutput_uwPrePllClockDiv_LSByte , + VideoTimingFarOutput_uwPrePllClockDiv_MSByte , + VideoTimingFarOutput_fpPllInputFrequency_Mhz_LSByte , + VideoTimingFarOutput_fpPllInputFrequency_Mhz_MSByte , + VideoTimingFarOutput_uwPllMultiplier_LSByte , + VideoTimingFarOutput_uwPllMultiplier_MSByte , + VideoTimingFarOutput_fpPllOutputFrequency_Mhz_LSByte , + VideoTimingFarOutput_fpPllOutputFrequency_Mhz_MSByte , + VideoTimingFarOutput_uwVTSystemClockDiv_LSByte , + VideoTimingFarOutput_uwVTSystemClockDiv_MSByte , + VideoTimingFarOutput_fpVTSystemClockFrequency_Mhz_LSByte , + VideoTimingFarOutput_fpVTSystemClockFrequency_Mhz_MSByte , + VideoTimingFarOutput_uwVTPixelClockDiv_LSByte , + VideoTimingFarOutput_uwVTPixelClockDiv_MSByte , + VideoTimingFarOutput_fpVTPixelClockFrequency_Mhz_LSByte , + VideoTimingFarOutput_fpVTPixelClockFrequency_Mhz_MSByte , + VideoTimingFarOutput_fpVTPixelClockPeriod_us_LSByte, + VideoTimingFarOutput_fpVTPixelClockPeriod_us_MSByte , + VideoTimingFarOutput_uwOPSystemClockDiv_LSByte , + VideoTimingFarOutput_uwOPSystemClockDiv_MSByte , + VideoTimingFarOutput_fpOPSystemClockFrequency_Mhz_LSByte , + VideoTimingFarOutput_fpOPSystemClockFrequency_Mhz_MSByte , + VideoTimingFarOutput_uwOPPixelClockDiv_LSByte , + VideoTimingFarOutput_uwOPPixelClockDiv_MSByte , + VideoTimingFarOutput_fpOPPixelClockFrequency_Mhz_LSByte , + VideoTimingFarOutput_fpOPPixelClockFrequency_Mhz_MSByte , + VideoTimingFarOutput_fpOutputTimingClockDerating_LSByte , + VideoTimingFarOutput_fpOutputTimingClockDerating_MSByte , + + //"DummyPage6//" , + + DummyPage6_bDummyPageElement , + + //"VideoTimingInputsNearSensor//" , + + VideoTimingInputsNearSensor_VideoTimingMode , + VideoTimingInputsNearSensor_bSensorBitsPerSystemClock , + VideoTimingInputsNearSensor_uwCsiRawFormat_LSByte , + VideoTimingInputsNearSensor_uwCsiRawFormat_MSByte , + VideoTimingInputsNearSensor_fpHostRxMaxDataRate_Mbps_LSByte , + VideoTimingInputsNearSensor_fpHostRxMaxDataRate_Mbps_MSByte , + VideoTimingInputsNearSensor_VsyncPolarity , + VideoTimingInputsNearSensor_HsyncPolarity , + + //"SensorNearVideoTimingSensorFifoControl//" , + + SensorNearVideoTimingSensorFifoControl_bFiFoWaterMarkProgrammingMode , + SensorNearVideoTimingSensorFifoControl_uwFifoWaterMarkPixels_LSByte, + SensorNearVideoTimingSensorFifoControl_uwFifoWaterMarkPixels_MSByte , + SensorNearVideoTimingSensorFifoControl_uwFifoSizePixels_LSByte , + SensorNearVideoTimingSensorFifoControl_uwFifoSizePixels_MSByte , + + //"VideoTimingNearSensorConstraints//" , + + VideoTimingNearSensorConstraints_uwMinimumPrePllClockDiv_LSByte , + VideoTimingNearSensorConstraints_uwMinimumPrePllClockDiv_MSByte , + VideoTimingNearSensorConstraints_uwMaximumPrePllClockDiv_LSByte , + VideoTimingNearSensorConstraints_uwMaximumPrePllClockDiv_MSByte , + VideoTimingNearSensorConstraints_fpMinimumPllInputFrequency_Mhz_LSByte , + VideoTimingNearSensorConstraints_fpMinimumPllInputFrequency_Mhz_MSByte , + VideoTimingNearSensorConstraints_uwMinimumPllMultiplier_LSByte , + VideoTimingNearSensorConstraints_uwMinimumPllMultiplier_MSByte , + VideoTimingNearSensorConstraints_uwMaximumPllMultiplier_LSByte , + VideoTimingNearSensorConstraints_uwMaximumPllMultiplier_MSByte , + VideoTimingNearSensorConstraints_fpMaximumPllOutputFrequency_Mhz_LSByte , + VideoTimingNearSensorConstraints_fpMaximumPllOutputFrequency_Mhz_MSByte , + VideoTimingNearSensorConstraints_uwMinimumVTSysClockDiv_LSByte , + VideoTimingNearSensorConstraints_uwMinimumVTSysClockDiv_MSByte , + VideoTimingNearSensorConstraints_uwMaximumVTSysClockDiv_LSByte , + VideoTimingNearSensorConstraints_uwMaximumVTSysClockDiv_MSByte , + VideoTimingNearSensorConstraints_fpMaximumVTSystemClockFrequency_Mhz_LSByte , + VideoTimingNearSensorConstraints_fpMaximumVTSystemClockFrequency_Mhz_MSByte , + VideoTimingNearSensorConstraints_uwMinimumVTPixelClockDiv_LSByte , + VideoTimingNearSensorConstraints_uwMinimumVTPixelClockDiv_MSByte , + VideoTimingNearSensorConstraints_uwMaximumVTPixelClockDiv_LSByte , + VideoTimingNearSensorConstraints_uwMaximumVTPixelClockDiv_MSByte , + VideoTimingNearSensorConstraints_fpMaximumVTPixelClockFrequency_Mhz_LSByte , + VideoTimingNearSensorConstraints_fpMaximumVTPixelClockFrequency_Mhz_MSByte , + VideoTimingNearSensorConstraints_uwMinimumOPSysClockDiv_LSByte, + VideoTimingNearSensorConstraints_uwMinimumOPSysClockDiv_MSByte , + VideoTimingNearSensorConstraints_uwMaximumOPSysClockDiv_LSByte , + VideoTimingNearSensorConstraints_uwMaximumOPSysClockDiv_MSByte , + VideoTimingNearSensorConstraints_fpMaximumOPSystemClockFrequency_Mhz_LSByte , + VideoTimingNearSensorConstraints_fpMaximumOPSystemClockFrequency_Mhz_MSByte , + VideoTimingNearSensorConstraints_fpMaximumOPPixelClockFrequency_Mhz_LSByte , + VideoTimingNearSensorConstraints_fpMaximumOPPixelClockFrequency_Mhz_MSByte , + + //"SensorNearScalingSubSamplingCapabilities//" , + + SensorNearScalingSubSamplingCapabilities_bSensorScalingMode , + SensorNearScalingSubSamplingCapabilities_uwScalerMMin_LSByte , + SensorNearScalingSubSamplingCapabilities_uwScalerMMin_MSByte , + SensorNearScalingSubSamplingCapabilities_uwScalerMMax_LSByte , + SensorNearScalingSubSamplingCapabilities_uwScalerMMax_MSByte , + SensorNearScalingSubSamplingCapabilities_uwMaxOddInc_LSByte , + SensorNearScalingSubSamplingCapabilities_uwMaxOddInc_MSByte , + + //"VideoTimingNearOutput//" , + + VideoTimingNearOutput_uwPrePllClockDiv_LSByte , + VideoTimingNearOutput_uwPrePllClockDiv_MSByte , + VideoTimingNearOutput_fpPllInputFrequency_Mhz_LSByte , + VideoTimingNearOutput_fpPllInputFrequency_Mhz_MSByte , + VideoTimingNearOutput_uwPllMultiplier_LSByte , + VideoTimingNearOutput_uwPllMultiplier_MSByte , + VideoTimingNearOutput_fpPllOutputFrequency_Mhz_LSByte , + VideoTimingNearOutput_fpPllOutputFrequency_Mhz_MSByte , + VideoTimingNearOutput_uwVTSystemClockDiv_LSByte , + VideoTimingNearOutput_uwVTSystemClockDiv_MSByte , + VideoTimingNearOutput_fpVTSystemClockFrequency_Mhz_LSByte, + VideoTimingNearOutput_fpVTSystemClockFrequency_Mhz_MSByte , + VideoTimingNearOutput_uwVTPixelClockDiv_LSByte , + VideoTimingNearOutput_uwVTPixelClockDiv_MSByte , + VideoTimingNearOutput_fpVTPixelClockFrequency_Mhz_LSByte , + VideoTimingNearOutput_fpVTPixelClockFrequency_Mhz_MSByte , + VideoTimingNearOutput_fpVTPixelClockPeriod_us_LSByte , + VideoTimingNearOutput_fpVTPixelClockPeriod_us_MSByte , + VideoTimingNearOutput_uwOPSystemClockDiv_LSByte , + VideoTimingNearOutput_uwOPSystemClockDiv_MSByte , + VideoTimingNearOutput_fpOPSystemClockFrequency_Mhz_LSByte , + VideoTimingNearOutput_fpOPSystemClockFrequency_Mhz_MSByte , + VideoTimingNearOutput_uwOPPixelClockDiv_LSByte , + VideoTimingNearOutput_uwOPPixelClockDiv_MSByte , + VideoTimingNearOutput_fpOPPixelClockFrequency_Mhz_LSByte , + VideoTimingNearOutput_fpOPPixelClockFrequency_Mhz_MSByte , + VideoTimingNearOutput_fpOutputTimingClockDerating_LSByte , + VideoTimingNearOutput_fpOutputTimingClockDerating_MSByte , + + //"DummyPage7//" , + + DummyPage7_bDummyPageElement , + + //"SystemConfiguration//" , + + SystemConfiguration_fFarSensorPresent , + SystemConfiguration_CcpRxForFarSensor , + SystemConfiguration_fNearSensorPresent , + SystemConfiguration_CcpRxForNearSensor , + SystemConfiguration_uwExternalClockFrequency_Mhz_num_LSByte , + SystemConfiguration_uwExternalClockFrequency_Mhz_num_MSByte , + SystemConfiguration_bExternalClockFrequency_Mhz_den, + SystemConfiguration_fFocusLensActuatorOnSensorNearPresent , + SystemConfiguration_fFocusLensActuatorOnSensorFarPresent , + SystemConfiguration_fShutterActuatorOnSensorNearPresent , + SystemConfiguration_fShutterActuatorOnSensorFarPresent , + SystemConfiguration_fpMcuClkFrequency_MHz_LSByte , + SystemConfiguration_fpMcuClkFrequency_MHz_MSByte , + + //"SensorInformation//" , + + SensorInformation_fFarSensorAvailable , + SensorInformation_uwFarSensorModelId_LSByte , + SensorInformation_uwFarSensorModelId_MSByte , + SensorInformation_bFarSensorRevision , + SensorInformation_bFarSensorManufacturerId , + SensorInformation_bFarSensorSMIAVersion , + SensorInformation_fNearSensorAvailable , + SensorInformation_uwNearSensorModelId_LSByte , + SensorInformation_uwNearSensorModelId_MSByte , + SensorInformation_bNearSensorRevision , + SensorInformation_bNearSensorManufacturerId , + SensorInformation_bNearSensorSMIAVersion , + SensorInformation_bCurrentlyActiveSensor , + SensorInformation_fCurrentSensorAvailable , + SensorInformation_fSensorChangedSinceLastStreaming , + + //"SensorCapabilitiesFarSensor//" , + + SensorCapabilitiesFarSensor_uwSensorIntegrationTimeCapability_LSByte , + SensorCapabilitiesFarSensor_uwSensorIntegrationTimeCapability_MSByte , + SensorCapabilitiesFarSensor_uwSensorMinimumCoarseIntegrationLines_LSByte , + SensorCapabilitiesFarSensor_uwSensorMinimumCoarseIntegrationLines_MSByte, + SensorCapabilitiesFarSensor_uwSensorCoarseIntegrationTimeMaxMargin_LSByte , + SensorCapabilitiesFarSensor_uwSensorCoarseIntegrationTimeMaxMargin_MSByte , + SensorCapabilitiesFarSensor_uwSensorMinimumFineIntegrationPixels_LSByte , + SensorCapabilitiesFarSensor_uwSensorMinimumFineIntegrationPixels_MSByte , + SensorCapabilitiesFarSensor_uwSensorFineIntegrationTimeMaxMargin_LSByte , + SensorCapabilitiesFarSensor_uwSensorFineIntegrationTimeMaxMargin_MSByte , + SensorCapabilitiesFarSensor_uwSensorAnalogGainMinimum_LSByte , + SensorCapabilitiesFarSensor_uwSensorAnalogGainMinimum_MSByte , + SensorCapabilitiesFarSensor_uwSensorAnalogGainMaximum_LSByte , + SensorCapabilitiesFarSensor_uwSensorAnalogGainMaximum_MSByte , + SensorCapabilitiesFarSensor_uwSensorAnalogGainCodeStep_LSByte , + SensorCapabilitiesFarSensor_uwSensorAnalogGainCodeStep_MSByte , + SensorCapabilitiesFarSensor_uwSensorAnalogGainType_LSByte , + SensorCapabilitiesFarSensor_uwSensorAnalogGainType_MSByte , + SensorCapabilitiesFarSensor_fpSensorAnalogGainConstM0_LSByte , + SensorCapabilitiesFarSensor_fpSensorAnalogGainConstM0_MSByte , + SensorCapabilitiesFarSensor_fpSensorAnalogGainConstC0_LSByte , + SensorCapabilitiesFarSensor_fpSensorAnalogGainConstC0_MSByte , + SensorCapabilitiesFarSensor_fpSensorAnalogGainConstM1_LSByte , + SensorCapabilitiesFarSensor_fpSensorAnalogGainConstM1_MSByte , + SensorCapabilitiesFarSensor_fpSensorAnalogGainConstC1_LSByte , + SensorCapabilitiesFarSensor_fpSensorAnalogGainConstC1_MSByte , + SensorCapabilitiesFarSensor_uwSensorConstantColumns_LSByte , + SensorCapabilitiesFarSensor_uwSensorConstantColumns_MSByte , + SensorCapabilitiesFarSensor_uwStartOfActiveColumns_LSByte , + SensorCapabilitiesFarSensor_uwStartOfActiveColumns_MSByte , + SensorCapabilitiesFarSensor_bActiveColumnDescriptorNumber , + SensorCapabilitiesFarSensor_bSensorStartOfActiveLines , + SensorCapabilitiesFarSensor_uwSensorConstantRows_LSByte , + SensorCapabilitiesFarSensor_uwSensorConstantRows_MSByte , + SensorCapabilitiesFarSensor_uwSensorStatusLines_LSByte, + SensorCapabilitiesFarSensor_uwSensorStatusLines_MSByte , + SensorCapabilitiesFarSensor_bPreActiveDarkLines_LSByte , + SensorCapabilitiesFarSensor_bPreActiveDarkLines_MSByte , + SensorCapabilitiesFarSensor_bPreActiveBlackLines_LSByte , + SensorCapabilitiesFarSensor_bPreActiveBlackLines_MSByte , + SensorCapabilitiesFarSensor_bSensorVFPNLines , + SensorCapabilitiesFarSensor_uwSensorDigitalGainCapability_LSByte , + SensorCapabilitiesFarSensor_uwSensorDigitalGainCapability_MSByte , + SensorCapabilitiesFarSensor_uwSensorDigitalGainMinimum_LSByte , + SensorCapabilitiesFarSensor_uwSensorDigitalGainMinimum_MSByte , + SensorCapabilitiesFarSensor_uwSensorDataPedestal_LSByte , + SensorCapabilitiesFarSensor_uwSensorDataPedestal_MSByte , + + //"SensorCapabilitiesNearSensor//" , + + SensorCapabilitiesNearSensor_uwSensorIntegrationTimeCapability_LSByte , + SensorCapabilitiesNearSensor_uwSensorIntegrationTimeCapability_MSByte , + SensorCapabilitiesNearSensor_uwSensorMinimumCoarseIntegrationLines_LSByte , + SensorCapabilitiesNearSensor_uwSensorMinimumCoarseIntegrationLines_MSByte , + SensorCapabilitiesNearSensor_uwSensorCoarseIntegrationTimeMaxMargin_LSByte , + SensorCapabilitiesNearSensor_uwSensorCoarseIntegrationTimeMaxMargin_MSByte , + SensorCapabilitiesNearSensor_uwSensorMinimumFineIntegrationPixels_LSByte , + SensorCapabilitiesNearSensor_uwSensorMinimumFineIntegrationPixels_MSByte , + SensorCapabilitiesNearSensor_uwSensorFineIntegrationTimeMaxMargin_LSByte , + SensorCapabilitiesNearSensor_uwSensorFineIntegrationTimeMaxMargin_MSByte , + SensorCapabilitiesNearSensor_uwSensorAnalogGainMinimum_LSByte , + SensorCapabilitiesNearSensor_uwSensorAnalogGainMinimum_MSByte , + SensorCapabilitiesNearSensor_uwSensorAnalogGainMaximum_LSByte , + SensorCapabilitiesNearSensor_uwSensorAnalogGainMaximum_MSByte , + SensorCapabilitiesNearSensor_uwSensorAnalogGainCodeStep_LSByte , + SensorCapabilitiesNearSensor_uwSensorAnalogGainCodeStep_MSByte, + SensorCapabilitiesNearSensor_uwSensorAnalogGainType_LSByte , + SensorCapabilitiesNearSensor_uwSensorAnalogGainType_MSByte , + SensorCapabilitiesNearSensor_fpSensorAnalogGainConstM0_LSByte , + SensorCapabilitiesNearSensor_fpSensorAnalogGainConstM0_MSByte , + SensorCapabilitiesNearSensor_fpSensorAnalogGainConstC0_LSByte , + SensorCapabilitiesNearSensor_fpSensorAnalogGainConstC0_MSByte , + SensorCapabilitiesNearSensor_fpSensorAnalogGainConstM1_LSByte , + SensorCapabilitiesNearSensor_fpSensorAnalogGainConstM1_MSByte , + SensorCapabilitiesNearSensor_fpSensorAnalogGainConstC1_LSByte , + SensorCapabilitiesNearSensor_fpSensorAnalogGainConstC1_MSByte , + SensorCapabilitiesNearSensor_uwSensorConstantColumns_LSByte , + SensorCapabilitiesNearSensor_uwSensorConstantColumns_MSByte , + SensorCapabilitiesNearSensor_uwStartOfActiveColumns_LSByte , + SensorCapabilitiesNearSensor_uwStartOfActiveColumns_MSByte , + SensorCapabilitiesNearSensor_bActiveColumnDescriptorNumber , + SensorCapabilitiesNearSensor_bSensorStartOfActiveLines , + SensorCapabilitiesNearSensor_uwSensorConstantRows_LSByte , + SensorCapabilitiesNearSensor_uwSensorConstantRows_MSByte , + SensorCapabilitiesNearSensor_uwSensorStatusLines_LSByte , + SensorCapabilitiesNearSensor_uwSensorStatusLines_MSByte , + SensorCapabilitiesNearSensor_bPreActiveDarkLines_LSByte , + SensorCapabilitiesNearSensor_bPreActiveDarkLines_MSByte , + SensorCapabilitiesNearSensor_bPreActiveBlackLines_LSByte , + SensorCapabilitiesNearSensor_bPreActiveBlackLines_MSByte , + SensorCapabilitiesNearSensor_bSensorVFPNLines , + SensorCapabilitiesNearSensor_uwSensorDigitalGainCapability_LSByte , + SensorCapabilitiesNearSensor_uwSensorDigitalGainCapability_MSByte , + SensorCapabilitiesNearSensor_uwSensorDigitalGainMinimum_LSByte , + SensorCapabilitiesNearSensor_uwSensorDigitalGainMinimum_MSByte , + SensorCapabilitiesNearSensor_uwSensorDataPedestal_LSByte , + SensorCapabilitiesNearSensor_uwSensorDataPedestal_MSByte, + + //"SensorCapabilitiesCurrentSensor//" , + + SensorCapabilitiesCurrentSensor_uwSensorIntegrationTimeCapability_LSByte , + SensorCapabilitiesCurrentSensor_uwSensorIntegrationTimeCapability_MSByte , + SensorCapabilitiesCurrentSensor_uwSensorMinimumCoarseIntegrationLines_LSByte , + SensorCapabilitiesCurrentSensor_uwSensorMinimumCoarseIntegrationLines_MSByte , + SensorCapabilitiesCurrentSensor_uwSensorCoarseIntegrationTimeMaxMargin_LSByte , + SensorCapabilitiesCurrentSensor_uwSensorCoarseIntegrationTimeMaxMargin_MSByte , + SensorCapabilitiesCurrentSensor_uwSensorMinimumFineIntegrationPixels_LSByte , + SensorCapabilitiesCurrentSensor_uwSensorMinimumFineIntegrationPixels_MSByte , + SensorCapabilitiesCurrentSensor_uwSensorFineIntegrationTimeMaxMargin_LSByte , + SensorCapabilitiesCurrentSensor_uwSensorFineIntegrationTimeMaxMargin_MSByte , + SensorCapabilitiesCurrentSensor_uwSensorAnalogGainMinimum_LSByte , + SensorCapabilitiesCurrentSensor_uwSensorAnalogGainMinimum_MSByte , + SensorCapabilitiesCurrentSensor_uwSensorAnalogGainMaximum_LSByte , + SensorCapabilitiesCurrentSensor_uwSensorAnalogGainMaximum_MSByte , + SensorCapabilitiesCurrentSensor_uwSensorAnalogGainCodeStep_LSByte , + SensorCapabilitiesCurrentSensor_uwSensorAnalogGainCodeStep_MSByte , + SensorCapabilitiesCurrentSensor_uwSensorAnalogGainType_LSByte , + SensorCapabilitiesCurrentSensor_uwSensorAnalogGainType_MSByte , + SensorCapabilitiesCurrentSensor_fpSensorAnalogGainConstM0_LSByte , + SensorCapabilitiesCurrentSensor_fpSensorAnalogGainConstM0_MSByte , + SensorCapabilitiesCurrentSensor_fpSensorAnalogGainConstC0_LSByte , + SensorCapabilitiesCurrentSensor_fpSensorAnalogGainConstC0_MSByte , + SensorCapabilitiesCurrentSensor_fpSensorAnalogGainConstM1_LSByte , + SensorCapabilitiesCurrentSensor_fpSensorAnalogGainConstM1_MSByte , + SensorCapabilitiesCurrentSensor_fpSensorAnalogGainConstC1_LSByte , + SensorCapabilitiesCurrentSensor_fpSensorAnalogGainConstC1_MSByte , + SensorCapabilitiesCurrentSensor_uwSensorConstantColumns_LSByte , + SensorCapabilitiesCurrentSensor_uwSensorConstantColumns_MSByte, + SensorCapabilitiesCurrentSensor_uwStartOfActiveColumns_LSByte , + SensorCapabilitiesCurrentSensor_uwStartOfActiveColumns_MSByte , + SensorCapabilitiesCurrentSensor_bActiveColumnDescriptorNumber , + SensorCapabilitiesCurrentSensor_bSensorStartOfActiveLines , + SensorCapabilitiesCurrentSensor_uwSensorConstantRows_LSByte , + SensorCapabilitiesCurrentSensor_uwSensorConstantRows_MSByte , + SensorCapabilitiesCurrentSensor_uwSensorStatusLines_LSByte , + SensorCapabilitiesCurrentSensor_uwSensorStatusLines_MSByte , + SensorCapabilitiesCurrentSensor_bPreActiveDarkLines_LSByte , + SensorCapabilitiesCurrentSensor_bPreActiveDarkLines_MSByte , + SensorCapabilitiesCurrentSensor_bPreActiveBlackLines_LSByte , + SensorCapabilitiesCurrentSensor_bPreActiveBlackLines_MSByte , + SensorCapabilitiesCurrentSensor_bSensorVFPNLines , + SensorCapabilitiesCurrentSensor_uwSensorDigitalGainCapability_LSByte , + SensorCapabilitiesCurrentSensor_uwSensorDigitalGainCapability_MSByte , + SensorCapabilitiesCurrentSensor_uwSensorDigitalGainMinimum_LSByte , + SensorCapabilitiesCurrentSensor_uwSensorDigitalGainMinimum_MSByte , + SensorCapabilitiesCurrentSensor_uwSensorDataPedestal_LSByte , + SensorCapabilitiesCurrentSensor_uwSensorDataPedestal_MSByte , + + //"SensorFrameConstraintsFar//" , + + SensorFrameConstraintsFar_uwVTXAddrMin_LSByte , + SensorFrameConstraintsFar_uwVTXAddrMin_MSByte , + SensorFrameConstraintsFar_uwVTYAddrMin_LSByte , + SensorFrameConstraintsFar_uwVTYAddrMin_MSByte , + SensorFrameConstraintsFar_uwVTXAddrMax_LSByte , + SensorFrameConstraintsFar_uwVTXAddrMax_MSByte , + SensorFrameConstraintsFar_uwVTYAddrMax_LSByte , + SensorFrameConstraintsFar_uwVTYAddrMax_MSByte , + SensorFrameConstraintsFar_uwMinOPXOutputSize_LSByte, + SensorFrameConstraintsFar_uwMinOPXOutputSize_MSByte , + SensorFrameConstraintsFar_uwMinOPYOutputSize_LSByte , + SensorFrameConstraintsFar_uwMinOPYOutputSize_MSByte , + SensorFrameConstraintsFar_uwMaxOPXOutputSize_LSByte , + SensorFrameConstraintsFar_uwMaxOPXOutputSize_MSByte , + SensorFrameConstraintsFar_uwMaxOPYOutputSize_LSByte , + SensorFrameConstraintsFar_uwMaxOPYOutputSize_MSByte , + SensorFrameConstraintsFar_uwMinVTFrameLengthLines_LSByte , + SensorFrameConstraintsFar_uwMinVTFrameLengthLines_MSByte , + SensorFrameConstraintsFar_uwMaxVTFrameLengthLines_LSByte , + SensorFrameConstraintsFar_uwMaxVTFrameLengthLines_MSByte , + SensorFrameConstraintsFar_uwMinVTLineLengthPck_LSByte , + SensorFrameConstraintsFar_uwMinVTLineLengthPck_MSByte , + SensorFrameConstraintsFar_uwMaxVTLineLengthPck_LSByte , + SensorFrameConstraintsFar_uwMaxVTLineLengthPck_MSByte , + SensorFrameConstraintsFar_uwMinVTLineBlankingPck_LSByte , + SensorFrameConstraintsFar_uwMinVTLineBlankingPck_MSByte , + SensorFrameConstraintsFar_uwMinVTFrameBlanking_LSByte , + SensorFrameConstraintsFar_uwMinVTFrameBlanking_MSByte , + + //"SensorFrameConstraintsNear//" , + + SensorFrameConstraintsNear_uwVTXAddrMin_LSByte , + SensorFrameConstraintsNear_uwVTXAddrMin_MSByte , + SensorFrameConstraintsNear_uwVTYAddrMin_LSByte , + SensorFrameConstraintsNear_uwVTYAddrMin_MSByte , + SensorFrameConstraintsNear_uwVTXAddrMax_LSByte , + SensorFrameConstraintsNear_uwVTXAddrMax_MSByte , + SensorFrameConstraintsNear_uwVTYAddrMax_LSByte , + SensorFrameConstraintsNear_uwVTYAddrMax_MSByte , + SensorFrameConstraintsNear_uwMinOPXOutputSize_LSByte, + SensorFrameConstraintsNear_uwMinOPXOutputSize_MSByte , + SensorFrameConstraintsNear_uwMinOPYOutputSize_LSByte , + SensorFrameConstraintsNear_uwMinOPYOutputSize_MSByte , + SensorFrameConstraintsNear_uwMaxOPXOutputSize_LSByte , + SensorFrameConstraintsNear_uwMaxOPXOutputSize_MSByte , + SensorFrameConstraintsNear_uwMaxOPYOutputSize_LSByte , + SensorFrameConstraintsNear_uwMaxOPYOutputSize_MSByte , + SensorFrameConstraintsNear_uwMinVTFrameLengthLines_LSByte , + SensorFrameConstraintsNear_uwMinVTFrameLengthLines_MSByte , + SensorFrameConstraintsNear_uwMaxVTFrameLengthLines_LSByte , + SensorFrameConstraintsNear_uwMaxVTFrameLengthLines_MSByte , + SensorFrameConstraintsNear_uwMinVTLineLengthPck_LSByte , + SensorFrameConstraintsNear_uwMinVTLineLengthPck_MSByte , + SensorFrameConstraintsNear_uwMaxVTLineLengthPck_LSByte , + SensorFrameConstraintsNear_uwMaxVTLineLengthPck_MSByte , + SensorFrameConstraintsNear_uwMinVTLineBlankingPck_LSByte , + SensorFrameConstraintsNear_uwMinVTLineBlankingPck_MSByte , + SensorFrameConstraintsNear_uwMinVTFrameBlanking_LSByte , + SensorFrameConstraintsNear_uwMinVTFrameBlanking_MSByte , + + //"AntiFlickerExposureControls//" , + + AntiFlickerExposureControls_bMainsFrequency_Hz , + AntiFlickerExposureControls_fGuaranteeStaticFlickerFrameLength , + + //"CurrentFrameDimension//" , + + CurrentFrameDimension_uwVTFrameLengthLines_LSByte , + CurrentFrameDimension_uwVTFrameLengthLines_MSByte , + CurrentFrameDimension_uwVTLineLengthPck_LSByte , + CurrentFrameDimension_uwVTLineLengthPck_MSByte, + CurrentFrameDimension_uwVTXAddrStart_LSByte , + CurrentFrameDimension_uwVTXAddrStart_MSByte , + CurrentFrameDimension_uwVTYAddrStart_LSByte , + CurrentFrameDimension_uwVTYAddrStart_MSByte , + CurrentFrameDimension_uwVTXAddrEnd_LSByte , + CurrentFrameDimension_uwVTXAddrEnd_MSByte , + CurrentFrameDimension_uwVTYAddrEnd_LSByte , + CurrentFrameDimension_uwVTYAddrEnd_MSByte , + CurrentFrameDimension_uwOPXOutputSize_LSByte , + CurrentFrameDimension_uwOPXOutputSize_MSByte , + CurrentFrameDimension_uwOPYOutputSize_LSByte , + CurrentFrameDimension_uwOPYOutputSize_MSByte , + CurrentFrameDimension_uwVTXOutputSize_LSByte , + CurrentFrameDimension_uwVTXOutputSize_MSByte , + CurrentFrameDimension_uwVTYOutputSize_LSByte , + CurrentFrameDimension_uwVTYOutputSize_MSByte , + CurrentFrameDimension_bVTXSubSampling , + CurrentFrameDimension_uwXOddInc_LSByte , + CurrentFrameDimension_uwXOddInc_MSByte , + CurrentFrameDimension_bVTYSubSampling , + CurrentFrameDimension_uwYOddInc_LSByte , + CurrentFrameDimension_uwYOddInc_MSByte , + CurrentFrameDimension_bScalingMode , + CurrentFrameDimension_fpScaleFactor_LSByte , + CurrentFrameDimension_fpScaleFactor_MSByte , + CurrentFrameDimension_uwScalerM_LSByte , + CurrentFrameDimension_uwScalerM_MSByte , + + //"SensorFrameConstraints//" , + + SensorFrameConstraints_uwVTXAddrMin_LSByte, + SensorFrameConstraints_uwVTXAddrMin_MSByte , + SensorFrameConstraints_uwVTYAddrMin_LSByte , + SensorFrameConstraints_uwVTYAddrMin_MSByte , + SensorFrameConstraints_uwVTXAddrMax_LSByte , + SensorFrameConstraints_uwVTXAddrMax_MSByte , + SensorFrameConstraints_uwVTYAddrMax_LSByte , + SensorFrameConstraints_uwVTYAddrMax_MSByte , + SensorFrameConstraints_uwMinOPXOutputSize_LSByte , + SensorFrameConstraints_uwMinOPXOutputSize_MSByte , + SensorFrameConstraints_uwMinOPYOutputSize_LSByte , + SensorFrameConstraints_uwMinOPYOutputSize_MSByte , + SensorFrameConstraints_uwMaxOPXOutputSize_LSByte , + SensorFrameConstraints_uwMaxOPXOutputSize_MSByte , + SensorFrameConstraints_uwMaxOPYOutputSize_LSByte , + SensorFrameConstraints_uwMaxOPYOutputSize_MSByte , + SensorFrameConstraints_uwMinVTFrameLengthLines_LSByte , + SensorFrameConstraints_uwMinVTFrameLengthLines_MSByte , + SensorFrameConstraints_uwMaxVTFrameLengthLines_LSByte , + SensorFrameConstraints_uwMaxVTFrameLengthLines_MSByte , + SensorFrameConstraints_uwMinVTLineLengthPck_LSByte , + SensorFrameConstraints_uwMinVTLineLengthPck_MSByte , + SensorFrameConstraints_uwMaxVTLineLengthPck_LSByte , + SensorFrameConstraints_uwMaxVTLineLengthPck_MSByte , + SensorFrameConstraints_uwMinVTLineBlankingPck_LSByte , + SensorFrameConstraints_uwMinVTLineBlankingPck_MSByte , + SensorFrameConstraints_uwMinVTFrameBlanking_LSByte , + SensorFrameConstraints_uwMinVTFrameBlanking_MSByte , + + //"HostFrameConstraints//" , + + HostFrameConstraints_uwMinimumOPLineBlanking_pixels_LSByte, + HostFrameConstraints_uwMinimumOPLineBlanking_pixels_MSByte , + HostFrameConstraints_uwMinimumOPFrameBlanking_lines_LSByte , + HostFrameConstraints_uwMinimumOPFrameBlanking_lines_MSByte , + HostFrameConstraints_bMinimumPostScalar0LineBlanking_pixels , + HostFrameConstraints_bMinimumPostScalar1LineBlanking_pixels , + + //"FrameDimensionStatus//" , + + FrameDimensionStatus_fFrameLengthChangePending , + FrameDimensionStatus_fFrameDimensionChangePending , + FrameDimensionStatus_uwVTFrameLengthPending_lines_LSByte , + FrameDimensionStatus_uwVTFrameLengthPending_lines_MSByte , + FrameDimensionStatus_fFrameLengthChangeInhibitedForCoarseExposure , + FrameDimensionStatus_uwMinVTLineLengthAtCurrentVTXSize_pixels_LSByte , + FrameDimensionStatus_uwMinVTLineLengthAtCurrentVTXSize_pixels_MSByte , + FrameDimensionStatus_uwMinVTFrameLengthAtCurrentVTYSize_lines_LSByte , + FrameDimensionStatus_uwMinVTFrameLengthAtCurrentVTYSize_lines_MSByte , + FrameDimensionStatus_fpVTLineLength_us_LSByte , + FrameDimensionStatus_fpVTLineLength_us_MSByte , + FrameDimensionStatus_fpVTFrameLength_us_LSByte , + FrameDimensionStatus_fpVTFrameLength_us_MSByte , + FrameDimensionStatus_fpCurrentFrameRate_LSByte , + FrameDimensionStatus_fpCurrentFrameRate_MSByte , + FrameDimensionStatus_uwMaximumSensorFOVX_LSByte , + FrameDimensionStatus_uwMaximumSensorFOVX_MSByte , + FrameDimensionStatus_uwMaximumSensorFOVY_LSByte , + FrameDimensionStatus_uwMaximumSensorFOVY_MSByte , + FrameDimensionStatus_uwOPXOutputSize_LSByte , + FrameDimensionStatus_uwOPXOutputSize_MSByte , + FrameDimensionStatus_fSensorPreScaleFactorChanged , + + //"BinningControl//" , + + BinningControl_fEnableBinning , + + //"BinningStatus//" , + + BinningStatus_fBinningEnabled , + + //"Sensor0BinningInputs//" , + + Sensor0BinningInputs_uwMinVTLineLengthPck_LSByte , + Sensor0BinningInputs_uwMinVTLineLengthPck_MSByte , + Sensor0BinningInputs_uwSensorMinimumFineIntegrationPixels_LSByte , + Sensor0BinningInputs_uwSensorMinimumFineIntegrationPixels_MSByte , + + //"Sensor1BinningInputs//" , + + Sensor1BinningInputs_uwMinVTLineLengthPck_LSByte , + Sensor1BinningInputs_uwMinVTLineLengthPck_MSByte , + Sensor1BinningInputs_uwSensorMinimumFineIntegrationPixels_LSByte , + Sensor1BinningInputs_uwSensorMinimumFineIntegrationPixels_MSByte , + + //"CurrentSensorBinningInputs//" , + + CurrentSensorBinningInputs_uwMinVTLineLengthPck_LSByte , + CurrentSensorBinningInputs_uwMinVTLineLengthPck_MSByte , + CurrentSensorBinningInputs_uwSensorMinimumFineIntegrationPixels_LSByte , + CurrentSensorBinningInputs_uwSensorMinimumFineIntegrationPixels_MSByte , + + //"FlashManagerControl//" , + + FlashManagerControl_bMode , + FlashManagerControl_bFlashType , + FlashManagerControl_fOrMainAndPreFlashPulse , + FlashManagerControl_RefPointCalcMode , + FlashManagerControl_wIntegrationStartPosition_LSByte , + FlashManagerControl_wIntegrationStartPosition_MSByte , + FlashManagerControl_fOverrideIntegrationStartPosition , + FlashManagerControl_fpFlashFiringDelay_us_LSByte , + FlashManagerControl_fpFlashFiringDelay_us_MSByte , + FlashManagerControl_bNumberOfPreFlashes , + FlashManagerControl_fpPulseWidthMainFlash_us_LSByte , + FlashManagerControl_fpPulseWidthMainFlash_us_MSByte , + FlashManagerControl_fpPulseWidthPreFlash_us_LSByte , + FlashManagerControl_fpPulseWidthPreFlash_us_MSByte , + FlashManagerControl_fpTimeBetweenTwoPreFlashes_us_LSByte , + FlashManagerControl_fpTimeBetweenTwoPreFlashes_us_MSByte , + FlashManagerControl_fpTimeBetweenPreFlashAndMainFlash_us_LSByte , + FlashManagerControl_fpTimeBetweenPreFlashAndMainFlash_us_MSByte , + FlashManagerControl_cMainFlashStartFrame , + FlashManagerControl_wMainFlashStartLine_LSByte , + FlashManagerControl_wMainFlashStartLine_MSByte , + FlashManagerControl_wMainFlashStartPixel_LSByte , + FlashManagerControl_wMainFlashStartPixel_MSByte , + FlashManagerControl_cPreFlashStartFrame , + FlashManagerControl_wPreFlashStartLine_LSByte , + FlashManagerControl_wPreFlashStartLine_MSByte , + FlashManagerControl_wPreFlashStartPixel_LSByte , + FlashManagerControl_wPreFlashStartPixel_MSByte , + FlashManagerControl_bTotalFramesRequired , + + //"FlashManagerStatus//" + + FlashManagerStatus_fFlashSequencePending , + FlashManagerStatus_cNumberFramesRequiredForPreFlashes , + FlashManagerStatus_fpMainFlashPulseWidth_us_LSByte , + FlashManagerStatus_fpMainFlashPulseWidth_us_MSByte , + FlashManagerStatus_fpPreFlashPulseWidth_us_LSByte , + FlashManagerStatus_fpPreFlashPulseWidth_us_MSByte , + FlashManagerStatus_fpInterPreflashDistance_us_LSByte , + FlashManagerStatus_fpInterPreflashDistance_us_MSByte , + FlashManagerStatus_fpPreAndMainflashDistance_us_LSByte , + FlashManagerStatus_fpPreAndMainflashDistance_us_MSByte , + FlashManagerStatus_cStartFlashFrame , + FlashManagerStatus_wStartFlashLine_LSByte , + FlashManagerStatus_wStartFlashLine_MSByte , + FlashManagerStatus_wStartFlashPixel_LSByte , + FlashManagerStatus_wStartFlashPixel_MSByte , + FlashManagerStatus_cStartPreFlashFrame , + FlashManagerStatus_wStartPreFlashLine_LSByte , + FlashManagerStatus_wStartPreFlashLine_MSByte , + FlashManagerStatus_wStartPreFlashPixel_LSByte , + FlashManagerStatus_wStartPreFlashPixel_MSByte , + FlashManagerStatus_cNumberFramesRequired , + FlashManagerStatus_fPreFlashPending , + FlashManagerStatus_fMainFlashPending , + + //"ExposureControls//" , + + ExposureControls_bMode , + ExposureControls_bMetering , + ExposureControls_bManualExposureTime_s_num , + ExposureControls_bManualExposureTime_s_den, + ExposureControls_fpManualDesiredExposureTime_us_LSByte , + ExposureControls_fpManualDesiredExposureTime_us_MSByte , + ExposureControls_fpColdStartDesiredTime_us_LSByte , + ExposureControls_fpColdStartDesiredTime_us_MSByte , + ExposureControls_iExposureCompensation , + ExposureControls_bMiscSettings , + ExposureControls_uwDirectModeCoarseIntegration_lines_LSByte , + ExposureControls_uwDirectModeCoarseIntegration_lines_MSByte , + ExposureControls_uwDirectModeFineIntegration_pixels_LSByte , + ExposureControls_uwDirectModeFineIntegration_pixels_MSByte , + ExposureControls_uwDirectModeCodedAnalogGain_LSByte , + ExposureControls_uwDirectModeCodedAnalogGain_MSByte , + ExposureControls_fpDirectModeDigitalGain_LSByte , + ExposureControls_fpDirectModeDigitalGain_MSByte , + ExposureControls_uwFlashGunModeCoarseIntegration_lines_LSByte , + ExposureControls_uwFlashGunModeCoarseIntegration_lines_MSByte , + ExposureControls_uwFlashGunModeFineIntegration_pixels_LSByte , + ExposureControls_uwFlashGunModeFineIntegration_pixels_MSByte , + ExposureControls_uwFlashGunModeCodedAnalogGain_LSByte , + ExposureControls_uwFlashGunModeCodedAnalogGain_MSByte , + ExposureControls_fpFlashGunModeDigitalGain_LSByte , + ExposureControls_fpFlashGunModeDigitalGain_MSByte , + ExposureControls_fFreezeAutoExposure , + ExposureControls_fpUserMaximumIntegrationTime_us_LSByte , + ExposureControls_fpUserMaximumIntegrationTime_us_MSByte , + ExposureControls_fpRecommendFlashGunAnalogGainThreshold_LSByte , + ExposureControls_fpRecommendFlashGunAnalogGainThreshold_MSByte , + ExposureControls_fEnableHighClipForDesiredExposureTime , + ExposureControls_bAntiFlickerMode , + ExposureControls_fInhibitExposurePresetModeForFlash , + + //"ExposureStatus//" , + + ExposureStatus_bAlgorithmStatus , + ExposureStatus_bCompilerStatus , + ExposureStatus_fWhiteBalanceGainIncludedInCurrentExposure , + ExposureStatus_fBadExposureForIterativeWhiteBalance , + ExposureStatus_uwCoarseIntegrationPending_lines_LSByte , + ExposureStatus_uwCoarseIntegrationPending_lines_MSByte , + ExposureStatus_uwFineIntegrationPending_pixels_LSByte , + ExposureStatus_uwFineIntegrationPending_pixels_MSByte , + ExposureStatus_fpAnalogGainPending_LSByte , + ExposureStatus_fpAnalogGainPending_MSByte , + ExposureStatus_fpDigitalGainPending_LSByte , + ExposureStatus_fpDigitalGainPending_MSByte , + ExposureStatus_fpDesiredExposureTime_us_LSByte , + ExposureStatus_fpDesiredExposureTime_us_MSByte , + ExposureStatus_fpCompiledExposureTime_us_LSByte , + ExposureStatus_fpCompiledExposureTime_us_MSByte , + ExposureStatus_bControlLoopFailureCount , + ExposureStatus_uwUserMaximumIntegrationLines_LSByte , + ExposureStatus_uwUserMaximumIntegrationLines_MSByte , + ExposureStatus_fpTotalIntegrationTimePending_us_LSByte , + ExposureStatus_fpTotalIntegrationTimePending_us_MSByte , + ExposureStatus_uwCodedAnalogGainPending_LSByte , + ExposureStatus_uwCodedAnalogGainPending_MSByte , + ExposureStatus_fExposureIsStableforAutoFocus , + ExposureStatus_bRuntimeExposureTarget , + + //"ExposureParametersApplied//" , + + ExposureParametersApplied_uwCoarseIntegration_lines_LSByte, + ExposureParametersApplied_uwCoarseIntegration_lines_MSByte , + ExposureParametersApplied_uwFineIntegration_pixels_LSByte , + ExposureParametersApplied_uwFineIntegration_pixels_MSByte , + ExposureParametersApplied_uwCodedAnalogGain_LSByte , + ExposureParametersApplied_uwCodedAnalogGain_MSByte , + ExposureParametersApplied_fpDigitalGain_LSByte , + ExposureParametersApplied_fpDigitalGain_MSByte , + + //"ExposureStatisticsStatus//" , + + ExposureStatisticsStatus_fpMeanEnergy_LSByte , + ExposureStatisticsStatus_fpMeanEnergy_MSByte , + + //"ExposureCycleTest//" , + + ExposureCycleTest_fpInitialDesiredExposureTime_LSByte , + ExposureCycleTest_fpInitialDesiredExposureTime_MSByte , + ExposureCycleTest_fpFinalDesiredExposureTime_LSByte , + ExposureCycleTest_fpFinalDesiredExposureTime_MSByte , + ExposureCycleTest_fpExposureStep_LSByte , + ExposureCycleTest_fpExposureStep_MSByte , + ExposureCycleTest_bStepDirection , + + //"ExposureTestCoin//" , + + ExposureTestCoin_fTestCoinEnabled , + ExposureTestCoin_fRunForTest , + ExposureTestCoin_bStatusCoin , + ExposureTestCoin_bControlCoin , + + //"ExposureAlgorithmControls//" + + ExposureAlgorithmControls_fpMaximumStep_LSByte , + ExposureAlgorithmControls_fpMaximumStep_MSByte , + ExposureAlgorithmControls_fpMinimumStep_LSByte , + ExposureAlgorithmControls_fpMinimumStep_MSByte , + ExposureAlgorithmControls_fpMinimumDesiredExposureTime_us_LSByte , + ExposureAlgorithmControls_fpMinimumDesiredExposureTime_us_MSByte , + ExposureAlgorithmControls_fpStepProportion_LSByte , + ExposureAlgorithmControls_fpStepProportion_MSByte , + ExposureAlgorithmControls_fpMaximumNegativeStepThreshold_LSByte , + ExposureAlgorithmControls_fpMaximumNegativeStepThreshold_MSByte , + ExposureAlgorithmControls_fpRelativeOnTargetStabilityThreshold_LSByte , + ExposureAlgorithmControls_fpRelativeOnTargetStabilityThreshold_MSByte , + ExposureAlgorithmControls_fpDigitalGainFloor_LSByte , + ExposureAlgorithmControls_fpDigitalGainFloor_MSByte , + ExposureAlgorithmControls_fpDigitalGainCeiling_LSByte , + ExposureAlgorithmControls_fpDigitalGainCeiling_MSByte , + ExposureAlgorithmControls_fpRelativeIntTimeHysThreshold_LSByte , + ExposureAlgorithmControls_fpRelativeIntTimeHysThreshold_MSByte , + ExposureAlgorithmControls_fpRelativeDigitalGainHysThreshold_LSByte , + ExposureAlgorithmControls_fpRelativeDigitalGainHysThreshold_MSByte , + ExposureAlgorithmControls_fpRelativeCompilationProblemThreshold_LSByte , + ExposureAlgorithmControls_fpRelativeCompilationProblemThreshold_MSByte , + ExposureAlgorithmControls_fpRoundUpBunchFudge_LSByte , + ExposureAlgorithmControls_fpRoundUpBunchFudge_MSByte , + ExposureAlgorithmControls_fpFineClampThreshold_LSByte , + ExposureAlgorithmControls_fpFineClampThreshold_MSByte , + ExposureAlgorithmControls_fpMaximumManualExposureTime_s_LSByte , + ExposureAlgorithmControls_fpMaximumManualExposureTime_s_MSByte , + ExposureAlgorithmControls_fpRelativeStabilityThresholdForAutoFocus_LSByte , + ExposureAlgorithmControls_fpRelativeStabilityThresholdForAutoFocus_MSByte, + ExposureAlgorithmControls_bLeakShift , + + //"ExposureAlgorithmStatus//" , + + ExposureAlgorithmStatus_fpLeakyEnergy_LSByte , + ExposureAlgorithmStatus_fpLeakyEnergy_MSByte , + ExposureAlgorithmStatus_fpRelativeStep_LSByte , + ExposureAlgorithmStatus_fpRelativeStep_MSByte , + + //"ExposureUpdateErrorControl//" , + + ExposureUpdateErrorControl_bMaximumNumberOfFrames , + + //"ExposureUpdateErrorStatus//" , + + ExposureUpdateErrorStatus_bNumberOfForcedInputProcUpdates , + ExposureUpdateErrorStatus_bNumberOfConsecutiveDelayedFrames , + ExposureUpdateErrorStatus_fForceInputProcUpdation , + + //"WhiteBalanceControls//" , + + WhiteBalanceControls_bMode , + WhiteBalanceControls_bManualRedGain , + WhiteBalanceControls_bManualGreenGain , + WhiteBalanceControls_bManualBlueGain , + WhiteBalanceControls_bMiscSettings , + WhiteBalanceControls_fpFlashRedGain_LSByte , + WhiteBalanceControls_fpFlashRedGain_MSByte , + WhiteBalanceControls_fpFlashGreenGain_LSByte , + WhiteBalanceControls_fpFlashGreenGain_MSByte , + WhiteBalanceControls_fpFlashBlueGain_LSByte, + WhiteBalanceControls_fpFlashBlueGain_MSByte , + WhiteBalanceControls_fInhibitWhiteBalancePresetModeForFlash , + + //"WhiteBalanceAlgorithmControls//" , + + WhiteBalanceAlgorithmControls_fpStableTotalStepThreshold_LSByte , + WhiteBalanceAlgorithmControls_fpStableTotalStepThreshold_MSByte , + WhiteBalanceAlgorithmControls_fpMinimumRelativeStep_LSByte , + WhiteBalanceAlgorithmControls_fpMinimumRelativeStep_MSByte , + WhiteBalanceAlgorithmControls_fpMaximumRelativeStep_LSByte , + WhiteBalanceAlgorithmControls_fpMaximumRelativeStep_MSByte , + WhiteBalanceAlgorithmControls_fpStepProportion_LSByte , + WhiteBalanceAlgorithmControls_fpStepProportion_MSByte , + + //"WhiteBalanceStatus//" , + + WhiteBalanceStatus_bStatus , + WhiteBalanceStatus_fUnityGainsUsed , + WhiteBalanceStatus_fpRedGain_LSByte , + WhiteBalanceStatus_fpRedGain_MSByte , + WhiteBalanceStatus_fpGreenGain_LSByte , + WhiteBalanceStatus_fpGreenGain_MSByte , + WhiteBalanceStatus_fpBlueGain_LSByte , + WhiteBalanceStatus_fpBlueGain_MSByte , + + //"WhiteBalanceStatisticsControls//" , + + WhiteBalanceStatisticsControls_bLowThreshold , + + //"WhiteBalanceStatisticsStatus//" , + + WhiteBalanceStatisticsStatus_fpRedEnergy_LSByte , + WhiteBalanceStatisticsStatus_fpRedEnergy_MSByte , + WhiteBalanceStatisticsStatus_fpGreenEnergy_LSByte , + WhiteBalanceStatisticsStatus_fpGreenEnergy_MSByte , + WhiteBalanceStatisticsStatus_fpBlueEnergy_LSByte , + WhiteBalanceStatisticsStatus_fpBlueEnergy_MSByte , + + //"MinWeightedWBControls//" , + + MinWeightedWBControls_fDisable , + MinWeightedWBControls_uwSaturationThreshold_LSByte , + MinWeightedWBControls_uwSaturationThreshold_MSByte , + MinWeightedWBControls_fpRedTiltGain_LSByte , + MinWeightedWBControls_fpRedTiltGain_MSByte , + MinWeightedWBControls_fpGreen1TiltGain_LSByte , + MinWeightedWBControls_fpGreen1TiltGain_MSByte , + MinWeightedWBControls_fpGreen2TiltGain_LSByte , + MinWeightedWBControls_fpGreen2TiltGain_MSByte , + MinWeightedWBControls_fpBlueTiltGain_LSByte , + MinWeightedWBControls_fpBlueTiltGain_MSByte , + MinWeightedWBControls_GreenChannelToAccumulate , + + //"MinWeightedWBStatus//" , + + MinWeightedWBStatus_uwZone_X_Offset_LSByte , + MinWeightedWBStatus_uwZone_X_Offset_MSByte , + MinWeightedWBStatus_uwZone_Y_Offset_LSByte , + MinWeightedWBStatus_uwZone_Y_Offset_MSByte , + MinWeightedWBStatus_uwZone_X_Size_LSByte , + MinWeightedWBStatus_uwZone_X_Size_MSByte , + MinWeightedWBStatus_uwZone_Y_Size_LSByte, + MinWeightedWBStatus_uwZone_Y_Size_MSByte , + MinWeightedWBStatus_fpNumberMacroPixel_LSByte , + MinWeightedWBStatus_fpNumberMacroPixel_MSByte , + + //"MWWBStatisticsStatus//" , + + MWWBStatisticsStatus_fpRedStatistics_LSByte , + MWWBStatisticsStatus_fpRedStatistics_MSByte , + MWWBStatisticsStatus_fpGreenStatistics_LSByte , + MWWBStatisticsStatus_fpGreenStatistics_MSByte , + MWWBStatisticsStatus_fpBlueStatistics_LSByte , + MWWBStatisticsStatus_fpBlueStatistics_MSByte , + + //"MiscellaneousErrorStatus//" , + + MiscellaneousErrorStatus_bNumberOfEWBStatisticsErrors , + MiscellaneousErrorStatus_bEWBStatisticsInterruptCount , + + //"AutomaticFrameRateControl//" , + + AutomaticFrameRateControl_bMode , + AutomaticFrameRateControl_bImpliedGainThresholdLow_num , + AutomaticFrameRateControl_bImpliedGainThresholdLow_den , + AutomaticFrameRateControl_bImpliedGainThresholdHigh_num , + AutomaticFrameRateControl_bImpliedGainThresholdHigh_den , + AutomaticFrameRateControl_bUserMinimumFrameRate_Hz , + AutomaticFrameRateControl_bUserMaximumFrameRate_Hz , + AutomaticFrameRateControl_bRelativeChange_num , + AutomaticFrameRateControl_bRelativeChange_den , + AutomaticFrameRateControl_fDivorceMinFrameRateFromMaxIntegration , + + //"AutomaticFrameRateStatus//" , + + AutomaticFrameRateStatus_fpImpliedGain_LSByte , + AutomaticFrameRateStatus_fpImpliedGain_MSByte , + AutomaticFrameRateStatus_uwMaximumFrameLength_lines_LSByte , + AutomaticFrameRateStatus_uwMaximumFrameLength_lines_MSByte , + AutomaticFrameRateStatus_uwMinimumFrameLength_lines_LSByte , + AutomaticFrameRateStatus_uwMinimumFrameLength_lines_MSByte , + AutomaticFrameRateStatus_uwFrameLengthChange_lines_LSByte , + AutomaticFrameRateStatus_uwFrameLengthChange_lines_MSByte , + AutomaticFrameRateStatus_fpDesiredAutomaticFrameRate_Hz_LSByte , + AutomaticFrameRateStatus_fpDesiredAutomaticFrameRate_Hz_MSByte , + AutomaticFrameRateStatus_uwCurrentFrameLength_lines_LSByte , + AutomaticFrameRateStatus_uwCurrentFrameLength_lines_MSByte , + AutomaticFrameRateStatus_uwDesiredFrameLength_lines_LSByte , + AutomaticFrameRateStatus_uwDesiredFrameLength_lines_MSByte , + AutomaticFrameRateStatus_fAutomaticFrameRateStable , + AutomaticFrameRateStatus_fAutomaticFrameRateClip , + + //"StaticFrameRateControl//" , + + StaticFrameRateControl_uwDesiredFrameRate_Num_LSByte , + StaticFrameRateControl_uwDesiredFrameRate_Num_MSByte , + StaticFrameRateControl_bDesiredFrameRate_Den , + + //"StaticFrameRateStatus//" , + + StaticFrameRateStatus_uwRequestedFrameRate_Hz_LSByte , + StaticFrameRateStatus_uwRequestedFrameRate_Hz_MSByte , + StaticFrameRateStatus_uwMaxFrameRate_Hz_LSByte , + StaticFrameRateStatus_uwMaxFrameRate_Hz_MSByte, + StaticFrameRateStatus_uwMinFrameRate_Hz_LSByte , + StaticFrameRateStatus_uwMinFrameRate_Hz_MSByte , + StaticFrameRateStatus_fChangePending , + StaticFrameRateStatus_uwRequiredFrameLength_lines_LSByte , + StaticFrameRateStatus_uwRequiredFrameLength_lines_MSByte , + StaticFrameRateStatus_ClipFrameRate , + + //"ImageStability//" , + + ImageStability_fWhiteBalanceStable , + ImageStability_fExposureStable , + ImageStability_fFocusStable , + ImageStability_fLowPowerStreaming , + ImageStability_fStable , + ImageStability_fForcedStablility , + + //"ImageStabilityMonitorControl//" , + + ImageStabilityMonitorControl_bMaxNumberOfFramesToWaitForStability , + + //"ColdStartManagerControl//" , + + ColdStartManagerControl_bControlCoin , + + //"ColdStartManagerStatus//" , + + ColdStartManagerStatus_bStatusCoin , + + //"ColourEngine0_ColourMatrixFarSensor//" , + + ColourEngine0_ColourMatrixFarSensor_fpRInR_LSByte, + ColourEngine0_ColourMatrixFarSensor_fpRInR_MSByte , + ColourEngine0_ColourMatrixFarSensor_fpGInR_LSByte , + ColourEngine0_ColourMatrixFarSensor_fpGInR_MSByte , + ColourEngine0_ColourMatrixFarSensor_fpBInR_LSByte , + ColourEngine0_ColourMatrixFarSensor_fpBInR_MSByte , + ColourEngine0_ColourMatrixFarSensor_fpRInG_LSByte , + ColourEngine0_ColourMatrixFarSensor_fpRInG_MSByte , + ColourEngine0_ColourMatrixFarSensor_fpGInG_LSByte , + ColourEngine0_ColourMatrixFarSensor_fpGInG_MSByte , + ColourEngine0_ColourMatrixFarSensor_fpBInG_LSByte , + ColourEngine0_ColourMatrixFarSensor_fpBInG_MSByte , + ColourEngine0_ColourMatrixFarSensor_fpRInB_LSByte , + ColourEngine0_ColourMatrixFarSensor_fpRInB_MSByte , + ColourEngine0_ColourMatrixFarSensor_fpGInB_LSByte , + ColourEngine0_ColourMatrixFarSensor_fpGInB_MSByte , + ColourEngine0_ColourMatrixFarSensor_fpBInB_LSByte , + ColourEngine0_ColourMatrixFarSensor_fpBInB_MSByte , + + //"ColourEngine0_ColourMatrixNearSensor//" , + + ColourEngine0_ColourMatrixNearSensor_fpRInR_LSByte , + ColourEngine0_ColourMatrixNearSensor_fpRInR_MSByte , + ColourEngine0_ColourMatrixNearSensor_fpGInR_LSByte , + ColourEngine0_ColourMatrixNearSensor_fpGInR_MSByte , + ColourEngine0_ColourMatrixNearSensor_fpBInR_LSByte , + ColourEngine0_ColourMatrixNearSensor_fpBInR_MSByte , + ColourEngine0_ColourMatrixNearSensor_fpRInG_LSByte , + ColourEngine0_ColourMatrixNearSensor_fpRInG_MSByte , + ColourEngine0_ColourMatrixNearSensor_fpGInG_LSByte , + ColourEngine0_ColourMatrixNearSensor_fpGInG_MSByte , + ColourEngine0_ColourMatrixNearSensor_fpBInG_LSByte, + ColourEngine0_ColourMatrixNearSensor_fpBInG_MSByte , + ColourEngine0_ColourMatrixNearSensor_fpRInB_LSByte , + ColourEngine0_ColourMatrixNearSensor_fpRInB_MSByte , + ColourEngine0_ColourMatrixNearSensor_fpGInB_LSByte , + ColourEngine0_ColourMatrixNearSensor_fpGInB_MSByte , + ColourEngine0_ColourMatrixNearSensor_fpBInB_LSByte , + ColourEngine0_ColourMatrixNearSensor_fpBInB_MSByte , + + //"ColourEngine0_ColourMatrixDamped//" , + + ColourEngine0_ColourMatrixDamped_wRInR_LSByte , + ColourEngine0_ColourMatrixDamped_wRInR_MSByte , + ColourEngine0_ColourMatrixDamped_wGInR_LSByte , + ColourEngine0_ColourMatrixDamped_wGInR_MSByte , + ColourEngine0_ColourMatrixDamped_wBInR_LSByte , + ColourEngine0_ColourMatrixDamped_wBInR_MSByte , + ColourEngine0_ColourMatrixDamped_wRInG_LSByte , + ColourEngine0_ColourMatrixDamped_wRInG_MSByte , + ColourEngine0_ColourMatrixDamped_wGInG_LSByte , + ColourEngine0_ColourMatrixDamped_wGInG_MSByte , + ColourEngine0_ColourMatrixDamped_wBInG_LSByte , + ColourEngine0_ColourMatrixDamped_wBInG_MSByte , + ColourEngine0_ColourMatrixDamped_wRInB_LSByte , + ColourEngine0_ColourMatrixDamped_wRInB_MSByte , + ColourEngine0_ColourMatrixDamped_wGInB_LSByte , + ColourEngine0_ColourMatrixDamped_wGInB_MSByte , + ColourEngine0_ColourMatrixDamped_wBInB_LSByte , + ColourEngine0_ColourMatrixDamped_wBInB_MSByte , + + //"ColourEngine0_ColourMatrixDamperControl//" , + + ColourEngine0_ColourMatrixDamperControl_fDisableMatrixDamping , + ColourEngine0_ColourMatrixDamperControl_DamperLowThreshold_LSByte , + ColourEngine0_ColourMatrixDamperControl_DamperLowThreshold_MSByte , + ColourEngine0_ColourMatrixDamperControl_DamperHighThreshold_LSByte , + ColourEngine0_ColourMatrixDamperControl_DamperHighThreshold_MSByte , + ColourEngine0_ColourMatrixDamperControl_MinimumDamperOutput_LSByte , + ColourEngine0_ColourMatrixDamperControl_MinimumDamperOutput_MSByte , + + //"ColourEngine0_ApertureCorrectionControls//" , + + ColourEngine0_ApertureCorrectionControls_fDisableCorrection , + ColourEngine0_ApertureCorrectionControls_bMaxGain , + ColourEngine0_ApertureCorrectionControls_fDisableGainDamping , + ColourEngine0_ApertureCorrectionControls_DamperLowThreshold_Gain_LSByte , + ColourEngine0_ApertureCorrectionControls_DamperLowThreshold_Gain_MSByte , + ColourEngine0_ApertureCorrectionControls_DamperHighThreshold_Gain_LSByte , + ColourEngine0_ApertureCorrectionControls_DamperHighThreshold_Gain_MSByte , + ColourEngine0_ApertureCorrectionControls_MinimumDamperOutput_Gain_LSByte , + ColourEngine0_ApertureCorrectionControls_MinimumDamperOutput_Gain_MSByte , + ColourEngine0_ApertureCorrectionControls_bMinimumCoringThreshold , + ColourEngine0_ApertureCorrectionControls_fDisableCoringDamping , + ColourEngine0_ApertureCorrectionControls_bMinimumHighThreshold , + ColourEngine0_ApertureCorrectionControls_DamperLowThreshold_Coring_LSByte , + ColourEngine0_ApertureCorrectionControls_DamperLowThreshold_Coring_MSByte , + ColourEngine0_ApertureCorrectionControls_DamperHighThreshold_Coring_LSByte , + ColourEngine0_ApertureCorrectionControls_DamperHighThreshold_Coring_MSByte , + ColourEngine0_ApertureCorrectionControls_MinimumDamperOutput_Coring_LSByte , + ColourEngine0_ApertureCorrectionControls_MinimumDamperOutput_Coring_MSByte , + + //"ColourEngine0_ApertureCorrectionStatus//" , + + ColourEngine0_ApertureCorrectionStatus_bGain , + ColourEngine0_ApertureCorrectionStatus_HighThreshold , + ColourEngine0_ApertureCorrectionStatus_CoringThreshold , + + //"ColourEngine0_GammaCorrection//" , + + ColourEngine0_GammaCorrection_fEnabled , + ColourEngine0_GammaCorrection_bMode , + ColourEngine0_GammaCorrection_SharpRed , + ColourEngine0_GammaCorrection_SharpGreen , + ColourEngine0_GammaCorrection_SharpBlue , + ColourEngine0_GammaCorrection_SoftRed , + ColourEngine0_GammaCorrection_SoftGreen , + ColourEngine0_GammaCorrection_SoftBlue , + + //"NoraControls//" , + + NoraControls_fDisable , + NoraControls_fDisableNoraPromoting , + NoraControls_bMaximumValue , + NoraControls_fDifferentTextureDegreeForBlue , + NoraControls_fSplitNoiseLevel , + NoraControls_fTightGreenMatrix , + NoraControls_DamperLowThreshold_LSByte , + NoraControls_DamperLowThreshold_MSByte , + NoraControls_DamperHighThreshold_LSByte , + NoraControls_DamperHighThreshold_MSByte , + NoraControls_MinimumDamperOutput_LSByte , + NoraControls_MinimumDamperOutput_MSByte , + + //"NoraStatus//" + + NoraStatus_bNoraValue , + + //"ScytheFilterControls//" , + + ScytheFilterControls_fDisableFilter , + ScytheFilterControls_fSquareLaw , + ScytheFilterControls_fDisablePromotingLow , + ScytheFilterControls_fDisablePromotingHigh , + ScytheFilterControls_bMaxWeightLow , + ScytheFilterControls_bMaxWeightHigh , + ScytheFilterControls_fpDamperLowThresholdLow_LSByte , + ScytheFilterControls_fpDamperLowThresholdLow_MSByte , + ScytheFilterControls_fpDamperLowThresholdHigh_LSByte , + ScytheFilterControls_fpDamperLowThresholdHigh_MSByte , + ScytheFilterControls_fpDamperHighThresholdLow_LSByte , + ScytheFilterControls_fpDamperHighThresholdLow_MSByte , + ScytheFilterControls_fpDamperHighThresholdHigh_LSByte , + ScytheFilterControls_fpDamperHighThresholdHigh_MSByte , + ScytheFilterControls_fpMinimumDamperOutputLow_LSByte , + ScytheFilterControls_fpMinimumDamperOutputLow_MSByte , + ScytheFilterControls_fpMinimumDamperOutputHigh_LSByte , + ScytheFilterControls_fpMinimumDamperOutputHigh_MSByte , + + //"JackFilterControls//" , + + JackFilterControls_fDisableFilter , + JackFilterControls_fSquareLaw , + JackFilterControls_fDisablePromotingLow , + JackFilterControls_fDisablePromotingHigh , + JackFilterControls_bMaxWeightLow, + JackFilterControls_bMaxWeightHigh , + JackFilterControls_fpDamperLowThresholdLow_LSByte , + JackFilterControls_fpDamperLowThresholdLow_MSByte , + JackFilterControls_fpDamperLowThresholdHigh_LSByte , + JackFilterControls_fpDamperLowThresholdHigh_MSByte , + JackFilterControls_fpDamperHighThresholdLow_LSByte , + JackFilterControls_fpDamperHighThresholdLow_MSByte , + JackFilterControls_fpDamperHighThresholdHigh_LSByte , + JackFilterControls_fpDamperHighThresholdHigh_MSByte , + JackFilterControls_fpMinimumDamperOutputLow_LSByte , + JackFilterControls_fpMinimumDamperOutputLow_MSByte , + JackFilterControls_fpMinimumDamperOutputHigh_LSByte , + JackFilterControls_fpMinimumDamperOutputHigh_MSByte , + + //"ScytheAndJackFilterStatus//" , + + ScytheAndJackFilterStatus_bScytheWeightLo , + ScytheAndJackFilterStatus_bScytheWeightHi , + ScytheAndJackFilterStatus_bJackWeightLo , + ScytheAndJackFilterStatus_bJackWeightHi , + + //"VfpnControls//" , + + VfpnControls_fEnableCorrection , + VfpnControls_uwMaximumPixelValue_LSByte , + VfpnControls_uwMaximumPixelValue_MSByte , + VfpnControls_uwMinimumPixelValue_LSByte , + VfpnControls_uwMinimumPixelValue_MSByte , + VfpnControls_uwPixelSaturationLevel_LSByte , + VfpnControls_uwPixelSaturationLevel_MSByte , + VfpnControls_bLogThreshLog, + + //"VfpnStatus//" , + + VfpnStatus_fLowPowerStreaming , + VfpnStatus_fVfpnGainChanged , + VfpnStatus_bNumberOfBlackLines , + VfpnStatus_uwNumberOfActivePixels_LSByte , + VfpnStatus_uwNumberOfActivePixels_MSByte , + + //"AntiVignetteControls//" , + + AntiVignetteControls_fDisableFilter , + AntiVignetteControls_bFilterCoeff_R2_r , + AntiVignetteControls_bFilterCoeff_R2_gr , + AntiVignetteControls_bFilterCoeff_R2_gb , + AntiVignetteControls_bFilterCoeff_R2_b , + AntiVignetteControls_bFilterCoeff_R4_r , + AntiVignetteControls_bFilterCoeff_R4_gr , + AntiVignetteControls_bFilterCoeff_R4_gb , + AntiVignetteControls_bFilterCoeff_R4_b , + AntiVignetteControls_uwHorizontalOffset_LSByte , + AntiVignetteControls_uwHorizontalOffset_MSByte , + AntiVignetteControls_uwVerticalOffset_LSByte , + AntiVignetteControls_uwVerticalOffset_MSByte , + AntiVignetteControls_fAVOffsetSeperateFor4Channels , + AntiVignetteControls_bShiftFix_R2 , + AntiVignetteControls_uwHorizontalOffset_r_LSByte , + AntiVignetteControls_uwHorizontalOffset_r_MSByte , + AntiVignetteControls_uwHorizontalOffset_gr_LSByte , + AntiVignetteControls_uwHorizontalOffset_gr_MSByte , + AntiVignetteControls_uwHorizontalOffset_gb_LSByte, + AntiVignetteControls_uwHorizontalOffset_gb_MSByte , + AntiVignetteControls_uwHorizontalOffset_b_LSByte , + AntiVignetteControls_uwHorizontalOffset_b_MSByte , + AntiVignetteControls_uwVerticalOffset_r_LSByte , + AntiVignetteControls_uwVerticalOffset_r_MSByte , + AntiVignetteControls_uwVerticalOffset_gr_LSByte , + AntiVignetteControls_uwVerticalOffset_gr_MSByte , + AntiVignetteControls_uwVerticalOffset_gb_LSByte , + AntiVignetteControls_uwVerticalOffset_gb_MSByte , + AntiVignetteControls_uwVerticalOffset_b_LSByte , + AntiVignetteControls_uwVerticalOffset_b_MSByte , + AntiVignetteControls_bUnityOffset_r , + AntiVignetteControls_bUnityOffset_gr , + AntiVignetteControls_bUnityOffset_gb , + AntiVignetteControls_bUnityOffset_b , + AntiVignetteControls_fAdaptiveAntiVignetteEnable , + + //"AntiVignetteStatus//" , + + AntiVignetteStatus_fXScaleEnabled , + AntiVignetteStatus_bXScale , + AntiVignetteStatus_fYScaleEnabled , + AntiVignetteStatus_bYScale , + AntiVignetteStatus_uwHorizontalSize_LSByte , + AntiVignetteStatus_uwHorizontalSize_MSByte , + AntiVignetteStatus_uwVerticalSize_LSByte , + AntiVignetteStatus_uwVerticalSize_MSByte , + + //"ColourEngine0_RadialApertureCorrectionControl//" , + + ColourEngine0_RadialApertureCorrectionControl_fEnableCorrection, + + //"ColourEngine0_RadialApertureCorrectionHostInputs//" , + + ColourEngine0_RadialApertureCorrectionHostInputs_bQvec0 , + ColourEngine0_RadialApertureCorrectionHostInputs_bQvec1 , + ColourEngine0_RadialApertureCorrectionHostInputs_bCofShift , + ColourEngine0_RadialApertureCorrectionHostInputs_bOutShift , + ColourEngine0_RadialApertureCorrectionHostInputs_uwUnity_LSByte , + ColourEngine0_RadialApertureCorrectionHostInputs_uwUnity_MSByte , + + //"ColourEngine0_RadialApertureCorrectionApplicationInputs//" , + + ColourEngine0_RadialApertureCorrectionApplicationInputs_uwHOffset_LSByte , + ColourEngine0_RadialApertureCorrectionApplicationInputs_uwHOffset_MSByte , + ColourEngine0_RadialApertureCorrectionApplicationInputs_uwVOffset_LSByte , + ColourEngine0_RadialApertureCorrectionApplicationInputs_uwVOffset_MSByte , + ColourEngine0_RadialApertureCorrectionApplicationInputs_uwHScalingFactor_LSByte , + ColourEngine0_RadialApertureCorrectionApplicationInputs_uwHScalingFactor_MSByte , + ColourEngine0_RadialApertureCorrectionApplicationInputs_uwVScalingFactor_LSByte , + ColourEngine0_RadialApertureCorrectionApplicationInputs_uwVScalingFactor_MSByte , + + //"ColourEngine0_OutputCoderControls//" , + + ColourEngine0_OutputCoderControls_TransformType , + ColourEngine0_OutputCoderControls_bContrast , + ColourEngine0_OutputCoderControls_bColourSaturation , + + //"ColourEngine0_CoderOutputSignalRange//" , + + ColourEngine0_CoderOutputSignalRange_uwLumaExcursion_LSByte , + ColourEngine0_CoderOutputSignalRange_uwLumaExcursion_MSByte, + ColourEngine0_CoderOutputSignalRange_uwLumaMidpointTimes2_LSByte , + ColourEngine0_CoderOutputSignalRange_uwLumaMidpointTimes2_MSByte , + ColourEngine0_CoderOutputSignalRange_uwChromaExcursion_LSByte , + ColourEngine0_CoderOutputSignalRange_uwChromaExcursion_MSByte , + ColourEngine0_CoderOutputSignalRange_uwChromaMidpointTimes2_LSByte , + ColourEngine0_CoderOutputSignalRange_uwChromaMidpointTimes2_MSByte , + + //"ColourEngine0_OutputCoderOffsetVector//" , + + ColourEngine0_OutputCoderOffsetVector_i0_LSByte , + ColourEngine0_OutputCoderOffsetVector_i0_MSByte , + ColourEngine0_OutputCoderOffsetVector_i1_LSByte , + ColourEngine0_OutputCoderOffsetVector_i1_MSByte , + ColourEngine0_OutputCoderOffsetVector_i2_LSByte , + ColourEngine0_OutputCoderOffsetVector_i2_MSByte , + + //"ColourEngine0_OutputCoderMatrix//" , + + ColourEngine0_OutputCoderMatrix_w0_0_LSByte , + ColourEngine0_OutputCoderMatrix_w0_0_MSByte , + ColourEngine0_OutputCoderMatrix_w0_1_LSByte , + ColourEngine0_OutputCoderMatrix_w0_1_MSByte , + ColourEngine0_OutputCoderMatrix_w0_2_LSByte , + ColourEngine0_OutputCoderMatrix_w0_2_MSByte , + ColourEngine0_OutputCoderMatrix_w1_0_LSByte , + ColourEngine0_OutputCoderMatrix_w1_0_MSByte , + ColourEngine0_OutputCoderMatrix_w1_1_LSByte , + ColourEngine0_OutputCoderMatrix_w1_1_MSByte , + ColourEngine0_OutputCoderMatrix_w1_2_LSByte , + ColourEngine0_OutputCoderMatrix_w1_2_MSByte , + ColourEngine0_OutputCoderMatrix_w2_0_LSByte, + ColourEngine0_OutputCoderMatrix_w2_0_MSByte , + ColourEngine0_OutputCoderMatrix_w2_1_LSByte , + ColourEngine0_OutputCoderMatrix_w2_1_MSByte , + ColourEngine0_OutputCoderMatrix_w2_2_LSByte , + ColourEngine0_OutputCoderMatrix_w2_2_MSByte , + + //"ColourEngine0_FadeToBlack//" , + + ColourEngine0_FadeToBlack_fDisable , + ColourEngine0_FadeToBlack_fpBlackValue_LSByte , + ColourEngine0_FadeToBlack_fpBlackValue_MSByte , + ColourEngine0_FadeToBlack_fpDamperLowThreshold_LSByte , + ColourEngine0_FadeToBlack_fpDamperLowThreshold_MSByte , + ColourEngine0_FadeToBlack_fpDamperHighThreshold_LSByte , + ColourEngine0_FadeToBlack_fpDamperHighThreshold_MSByte , + ColourEngine0_FadeToBlack_fpDamperOutput_LSByte , + ColourEngine0_FadeToBlack_fpDamperOutput_MSByte , + + //"ScalerLimits//" , + + ScalerLimits_uwPipe0MinStep_LSByte , + ScalerLimits_uwPipe0MinStep_MSByte , + ScalerLimits_uwPipe0MaxStep_LSByte , + ScalerLimits_uwPipe0MaxStep_MSByte , + + //"ZoomMgrParams//" , + + ZoomMgrParams_fAntiZip , + ZoomMgrParams_bFilterCrispness0 , + ZoomMgrParams_bFilterCrispness1 , + ZoomMgrParams_fInFromOutARLock, + ZoomMgrParams_bPrescaleFactor , + ZoomMgrParams_bPrescaleType , + ZoomMgrParams_fp16ZoomRange_LSByte , + ZoomMgrParams_fp16ZoomRange_MSByte , + + //"ZoomMgrCtrl//" , + + ZoomMgrCtrl_bHostTestCoin , + ZoomMgrCtrl_bZoomCmd , + ZoomMgrCtrl_fChgOverForbidden , + ZoomMgrCtrl_fAutoZoom , + ZoomMgrCtrl_bStepFramePeriod , + ZoomMgrCtrl_bMagFactor , + ZoomMgrCtrl_bChgOverMarginShift , + ZoomMgrCtrl_fCheckDataRate , + ZoomMgrCtrl_fSetAlternateInitWOI , + ZoomMgrCtrl_fSetX_Byte0 , + ZoomMgrCtrl_fSetX_Byte1 , + ZoomMgrCtrl_fSetX_Byte2 , + ZoomMgrCtrl_fSetX_Byte3 , + ZoomMgrCtrl_fp16P0ScaleLowLimit_LSByte , + ZoomMgrCtrl_fp16P0ScaleLowLimit_MSByte , + ZoomMgrCtrl_fp16P1ScaleLowLimit_LSByte , + ZoomMgrCtrl_fp16P1ScaleLowLimit_MSByte , + + //"ZoomMgrStatus//" , + + ZoomMgrStatus_fReady , + ZoomMgrStatus_bDeviceTestCoin , + ZoomMgrStatus_bNextCmd , + ZoomMgrStatus_bLastCmd, + ZoomMgrStatus_bCommandStatus , + ZoomMgrStatus_bZoomOpStatus , + ZoomMgrStatus_fFOVX_Byte0 , + ZoomMgrStatus_fFOVX_Byte1 , + ZoomMgrStatus_fFOVX_Byte2 , + ZoomMgrStatus_fFOVX_Byte3 , + ZoomMgrStatus_fFOVY_Byte0 , + ZoomMgrStatus_fFOVY_Byte1 , + ZoomMgrStatus_fFOVY_Byte2 , + ZoomMgrStatus_fFOVY_Byte3 , + ZoomMgrStatus_bPrescaleType , + ZoomMgrStatus_fPrescaleFactor_Byte0 , + ZoomMgrStatus_fPrescaleFactor_Byte1 , + ZoomMgrStatus_fPrescaleFactor_Byte2 , + ZoomMgrStatus_fPrescaleFactor_Byte3 , + ZoomMgrStatus_boPipe0NoPrescale , + ZoomMgrStatus_bZoomPosition , + ZoomMgrStatus_fMaxFOVX_Byte0 , + ZoomMgrStatus_fMaxFOVX_Byte1 , + ZoomMgrStatus_fMaxFOVX_Byte2 , + ZoomMgrStatus_fMaxFOVX_Byte3 , + ZoomMgrStatus_fMinFOVX_Byte0 , + ZoomMgrStatus_fMinFOVX_Byte1 , + ZoomMgrStatus_fMinFOVX_Byte2 , + ZoomMgrStatus_fMinFOVX_Byte3 , + ZoomMgrStatus_uwXOrigin_LSByte , + ZoomMgrStatus_uwXOrigin_MSByte , + ZoomMgrStatus_uwYOrigin_LSByte , + ZoomMgrStatus_uwYOrigin_MSByte , + + //"WhiteBalanceConstrainerControls//" + + WhiteBalanceConstrainerControls_fpRedA_LSByte , + WhiteBalanceConstrainerControls_fpRedA_MSByte , + WhiteBalanceConstrainerControls_fpBlueA_LSByte , + WhiteBalanceConstrainerControls_fpBlueA_MSByte , + WhiteBalanceConstrainerControls_fpRedB_LSByte , + WhiteBalanceConstrainerControls_fpRedB_MSByte , + WhiteBalanceConstrainerControls_fpBlueB_LSByte , + WhiteBalanceConstrainerControls_fpBlueB_MSByte , + WhiteBalanceConstrainerControls_fpMaximumDistanceAllowedFromLocus_LSByte , + WhiteBalanceConstrainerControls_fpMaximumDistanceAllowedFromLocus_MSByte , + WhiteBalanceConstrainerControls_fEnableConstrainedWhiteBalance , + + //"WhiteBalanceConstrainerOutput//" , + + WhiteBalanceConstrainerOutput_fpOutputRedGain_LSByte , + WhiteBalanceConstrainerOutput_fpOutputRedGain_MSByte , + WhiteBalanceConstrainerOutput_fpOutputGreenGain_LSByte , + WhiteBalanceConstrainerOutput_fpOutputGreenGain_MSByte , + WhiteBalanceConstrainerOutput_fpOutputBlueGain_LSByte , + WhiteBalanceConstrainerOutput_fpOutputBlueGain_MSByte , + WhiteBalanceConstrainerOutput_fAreGainsConstrained , + + //"WhiteBalanceConstrainerInternal//" , + + WhiteBalanceConstrainerInternal_fpGradientOfLocusAB_LSByte , + WhiteBalanceConstrainerInternal_fpGradientOfLocusAB_MSByte , + WhiteBalanceConstrainerInternal_fpDistanceOfInputPointFromLocusAB_LSByte , + WhiteBalanceConstrainerInternal_fpDistanceOfInputPointFromLocusAB_MSByte , + WhiteBalanceConstrainerInternal_fpConstrainedRedPoint_LSByte , + WhiteBalanceConstrainerInternal_fpConstrainedRedPoint_MSByte, + WhiteBalanceConstrainerInternal_fpConstrainedBluePoint_LSByte , + WhiteBalanceConstrainerInternal_fpConstrainedBluePoint_MSByte , + + //"ModeSetupBank1//" , + + ModeSetupBank1_uwInputImageSize_X_LSByte , + ModeSetupBank1_uwInputImageSize_X_MSByte , + ModeSetupBank1_uwInputImageSize_Y_LSByte , + ModeSetupBank1_uwInputImageSize_Y_MSByte , + ModeSetupBank1_uwMaxImageSize_X_LSByte , + ModeSetupBank1_uwMaxImageSize_X_MSByte , + ModeSetupBank1_uwMaxImageSize_Y_LSByte , + ModeSetupBank1_uwMaxImageSize_Y_MSByte , + ModeSetupBank1_uwMinImageSize_X_LSByte , + ModeSetupBank1_uwMinImageSize_X_MSByte , + ModeSetupBank1_uwMinImageSize_Y_LSByte , + ModeSetupBank1_uwMinImageSize_Y_MSByte , + ModeSetupBank1_bActiveSensor , + ModeSetupBank1_fLowPowerStreaming , + ModeSetupBank1_bTestMode , + ModeSetupBank1_bNumberOfStatusLines , + ModeSetupBank1_bNumberOfDarkLines , + ModeSetupBank1_bNumberOfBlackLines , + ModeSetupBank1_uwNumberOfInterLinePixelClocks_LSByte , + ModeSetupBank1_uwNumberOfInterLinePixelClocks_MSByte , + ModeSetupBank1_uwNumberOfInterFrameLines_LSByte , + ModeSetupBank1_uwNumberOfInterFrameLines_MSByte , + ModeSetupBank1_bNumberOfDummyColumns , + ModeSetupBank1_bInputImageSource , + ModeSetupBank1_bOutputImageDestination , + + //"DummyPage3//" , + + DummyPage3_bDummyPageElement , + + //"DummyPage4//" , + + DummyPage4_bDummyPageElement , + + //"AntiVignetteControlsFar//" , + + AntiVignetteControlsFar_fDisableFilter , + AntiVignetteControlsFar_bFilterCoeff_R2_r , + AntiVignetteControlsFar_bFilterCoeff_R2_gr , + AntiVignetteControlsFar_bFilterCoeff_R2_gb , + AntiVignetteControlsFar_bFilterCoeff_R2_b , + AntiVignetteControlsFar_bFilterCoeff_R4_r , + AntiVignetteControlsFar_bFilterCoeff_R4_gr , + AntiVignetteControlsFar_bFilterCoeff_R4_gb , + AntiVignetteControlsFar_bFilterCoeff_R4_b , + AntiVignetteControlsFar_uwHorizontalOffset_LSByte , + AntiVignetteControlsFar_uwHorizontalOffset_MSByte , + AntiVignetteControlsFar_uwVerticalOffset_LSByte , + AntiVignetteControlsFar_uwVerticalOffset_MSByte , + AntiVignetteControlsFar_fAVOffsetSeperateFor4Channels , + AntiVignetteControlsFar_bShiftFix_R2 , + AntiVignetteControlsFar_uwHorizontalOffset_r_LSByte , + AntiVignetteControlsFar_uwHorizontalOffset_r_MSByte , + AntiVignetteControlsFar_uwHorizontalOffset_gr_LSByte , + AntiVignetteControlsFar_uwHorizontalOffset_gr_MSByte , + AntiVignetteControlsFar_uwHorizontalOffset_gb_LSByte , + AntiVignetteControlsFar_uwHorizontalOffset_gb_MSByte, + AntiVignetteControlsFar_uwHorizontalOffset_b_LSByte , + AntiVignetteControlsFar_uwHorizontalOffset_b_MSByte , + AntiVignetteControlsFar_uwVerticalOffset_r_LSByte , + AntiVignetteControlsFar_uwVerticalOffset_r_MSByte , + AntiVignetteControlsFar_uwVerticalOffset_gr_LSByte , + AntiVignetteControlsFar_uwVerticalOffset_gr_MSByte , + AntiVignetteControlsFar_uwVerticalOffset_gb_LSByte , + AntiVignetteControlsFar_uwVerticalOffset_gb_MSByte , + AntiVignetteControlsFar_uwVerticalOffset_b_LSByte , + AntiVignetteControlsFar_uwVerticalOffset_b_MSByte , + AntiVignetteControlsFar_bUnityOffset_r , + AntiVignetteControlsFar_bUnityOffset_gr , + AntiVignetteControlsFar_bUnityOffset_gb , + AntiVignetteControlsFar_bUnityOffset_b , + AntiVignetteControlsFar_fAdaptiveAntiVignetteEnable , + + //"AntiVignetteControlsNear//" , + + AntiVignetteControlsNear_fDisableFilter , + AntiVignetteControlsNear_bFilterCoeff_R2_r , + AntiVignetteControlsNear_bFilterCoeff_R2_gr , + AntiVignetteControlsNear_bFilterCoeff_R2_gb , + AntiVignetteControlsNear_bFilterCoeff_R2_b , + AntiVignetteControlsNear_bFilterCoeff_R4_r , + AntiVignetteControlsNear_bFilterCoeff_R4_gr , + AntiVignetteControlsNear_bFilterCoeff_R4_gb , + AntiVignetteControlsNear_bFilterCoeff_R4_b , + AntiVignetteControlsNear_uwHorizontalOffset_LSByte , + AntiVignetteControlsNear_uwHorizontalOffset_MSByte , + AntiVignetteControlsNear_uwVerticalOffset_LSByte , + AntiVignetteControlsNear_uwVerticalOffset_MSByte, + AntiVignetteControlsNear_fAVOffsetSeperateFor4Channels , + AntiVignetteControlsNear_bShiftFix_R2 , + AntiVignetteControlsNear_uwHorizontalOffset_r_LSByte , + AntiVignetteControlsNear_uwHorizontalOffset_r_MSByte , + AntiVignetteControlsNear_uwHorizontalOffset_gr_LSByte , + AntiVignetteControlsNear_uwHorizontalOffset_gr_MSByte , + AntiVignetteControlsNear_uwHorizontalOffset_gb_LSByte , + AntiVignetteControlsNear_uwHorizontalOffset_gb_MSByte , + AntiVignetteControlsNear_uwHorizontalOffset_b_LSByte , + AntiVignetteControlsNear_uwHorizontalOffset_b_MSByte , + AntiVignetteControlsNear_uwVerticalOffset_r_LSByte , + AntiVignetteControlsNear_uwVerticalOffset_r_MSByte , + AntiVignetteControlsNear_uwVerticalOffset_gr_LSByte , + AntiVignetteControlsNear_uwVerticalOffset_gr_MSByte , + AntiVignetteControlsNear_uwVerticalOffset_gb_LSByte , + AntiVignetteControlsNear_uwVerticalOffset_gb_MSByte , + AntiVignetteControlsNear_uwVerticalOffset_b_LSByte , + AntiVignetteControlsNear_uwVerticalOffset_b_MSByte , + AntiVignetteControlsNear_bUnityOffset_r , + AntiVignetteControlsNear_bUnityOffset_gr , + AntiVignetteControlsNear_bUnityOffset_gb , + AntiVignetteControlsNear_bUnityOffset_b , + AntiVignetteControlsNear_fAdaptiveAntiVignetteEnable , + + //"AFStatsControls//" , + + AFStatsControls_fAbsSquareEnabled , + AFStatsControls_bCoringValue , + AFStatsControls_bWindowsSystem , + AFStatsControls_bHRatio_Num , + AFStatsControls_bHRatio_Den, + AFStatsControls_bVRatio_Num , + AFStatsControls_bVRatio_Den , + AFStatsControls_bHostActiveZonesCounter , + AFStatsControls_fAutoRefresh , + + //"AFStatsStatus//" , + + AFStatsStatus_bAFStats_Error , + AFStatsStatus_fAbsSquareEnabled , + AFStatsStatus_bCoringValue , + AFStatsStatus_bWindowsSystem , + AFStatsStatus_bActiveZonesCounter , + AFStatsStatus_bHRatio_Num , + AFStatsStatus_bHRatio_Den , + AFStatsStatus_bVRatio_Num , + AFStatsStatus_bVRatio_Den , + AFStatsStatus_uwWOI_Width_LSByte , + AFStatsStatus_uwWOI_Width_MSByte , + AFStatsStatus_uwWOI_Height_LSByte , + AFStatsStatus_uwWOI_Height_MSByte , + AFStatsStatus_uwAFZones_Width_LSByte , + AFStatsStatus_uwAFZones_Width_MSByte , + AFStatsStatus_uwAFZones_Height_LSByte , + AFStatsStatus_uwAFZones_Height_MSByte , + AFStatsStatus_fForcedAFStatsIrq , + AFStatsStatus_udwMaxFocusMeasurePerPixel_Byte0 , + AFStatsStatus_udwMaxFocusMeasurePerPixel_Byte1 , + AFStatsStatus_udwMaxFocusMeasurePerPixel_Byte2 , + AFStatsStatus_udwMaxFocusMeasurePerPixel_Byte3 , + AFStatsStatus_uwStartingAFZoneLine_LSByte , + AFStatsStatus_uwStartingAFZoneLine_MSByte, + + //"AFFocusStats//" , + + AFFocusStats_udwStatsValue_0_Byte0 , + AFFocusStats_udwStatsValue_0_Byte1 , + AFFocusStats_udwStatsValue_0_Byte2 , + AFFocusStats_udwStatsValue_0_Byte3 , + AFFocusStats_udwStatsValue_1_Byte0 , + AFFocusStats_udwStatsValue_1_Byte1 , + AFFocusStats_udwStatsValue_1_Byte2 , + AFFocusStats_udwStatsValue_1_Byte3 , + AFFocusStats_udwStatsValue_2_Byte0 , + AFFocusStats_udwStatsValue_2_Byte1 , + AFFocusStats_udwStatsValue_2_Byte2 , + AFFocusStats_udwStatsValue_2_Byte3 , + AFFocusStats_udwStatsValue_3_Byte0 , + AFFocusStats_udwStatsValue_3_Byte1 , + AFFocusStats_udwStatsValue_3_Byte2 , + AFFocusStats_udwStatsValue_3_Byte3 , + AFFocusStats_udwStatsValue_4_Byte0 , + AFFocusStats_udwStatsValue_4_Byte1 , + AFFocusStats_udwStatsValue_4_Byte2 , + AFFocusStats_udwStatsValue_4_Byte3 , + AFFocusStats_udwStatsValue_5_Byte0 , + AFFocusStats_udwStatsValue_5_Byte1 , + AFFocusStats_udwStatsValue_5_Byte2 , + AFFocusStats_udwStatsValue_5_Byte3 , + AFFocusStats_udwStatsValue_6_Byte0 , + AFFocusStats_udwStatsValue_6_Byte1 , + AFFocusStats_udwStatsValue_6_Byte2 , + AFFocusStats_udwStatsValue_6_Byte3, + + //"AFLightStats//" , + + AFLightStats_bStatsValue_0 , + AFLightStats_bStatsValue_1 , + AFLightStats_bStatsValue_2 , + AFLightStats_bStatsValue_3 , + AFLightStats_bStatsValue_4 , + AFLightStats_bStatsValue_5 , + AFLightStats_bStatsValue_6 , + + //"FLADriverLowLevelParameters//" , + + FLADriverLowLevelParameters_wMinPosition_LSByte , + FLADriverLowLevelParameters_wMinPosition_MSByte , + FLADriverLowLevelParameters_wMaxPosition_LSByte , + FLADriverLowLevelParameters_wMaxPosition_MSByte , + FLADriverLowLevelParameters_wHomePosition_LSByte , + FLADriverLowLevelParameters_wHomePosition_MSByte , + FLADriverLowLevelParameters_wParkPosition_LSByte , + FLADriverLowLevelParameters_wParkPosition_MSByte , + FLADriverLowLevelParameters_bFramesToSkip , + FLADriverLowLevelParameters_AutoSkipNextFrame , + FLADriverLowLevelParameters_bLowLevelMacroPos , + FLADriverLowLevelParameters_bLowLevelInfinityPos , + FLADriverLowLevelParameters_bLowLevelPositionTolerance , + FLADriverLowLevelParameters_bLowLevelTimeLimit , + FLADriverLowLevelParameters_bMaxNumberRetries , + FLADriverLowLevelParameters_fLowLevelDriverInitialized , + FLADriverLowLevelParameters_fOverwriteLowLevelLimits , + FLADriverLowLevelParameters_bNVMRead, + FLADriverLowLevelParameters_bNVMScalingFactorInfinity , + FLADriverLowLevelParameters_bNVMScalingFactorMacro , + FLADriverLowLevelParameters_bNVM_PS_Offset , + FLADriverLowLevelParameters_bNVM_PS_Gains , + FLADriverLowLevelParameters_bNVM_PS_IBias , + FLADriverLowLevelParameters_bNVM_PS_RampGain , + FLADriverLowLevelParameters_bNVM_PS_Type , + FLADriverLowLevelParameters_uwNVM_minidriver_m_c_LSByte , + FLADriverLowLevelParameters_uwNVM_minidriver_m_c_MSByte , + + //"FLADriverControls//" , + + FLADriverControls_bMMode , + FLADriverControls_wTargetPosition_LSByte , + FLADriverControls_wTargetPosition_MSByte , + FLADriverControls_wPositionTolerance_LSByte , + FLADriverControls_wPositionTolerance_MSByte , + FLADriverControls_uwTimeLimit_ms_LSByte , + FLADriverControls_uwTimeLimit_ms_MSByte , + FLADriverControls_bTrigger , + FLADriverControls_bSlewMode , + FLADriverControls_bSlewRate , + + //"FLADriverStatus//" , + + FLADriverStatus_wLensPosition_LSByte , + FLADriverStatus_wLensPosition_MSByte , + FLADriverStatus_fLensIsMoving , + FLADriverStatus_fLimitsExceeded , + FLADriverStatus_fLensIsAtHome , + FLADriverStatus_fError, + FLADriverStatus_bSkippedFrames , + FLADriverStatus_bCycles , + FLADriverStatus_bMiniDriverTimeoutError , + FLADriverStatus_wTargetPosition , + FLADriverStatus_bLowLevelPosition , + + //"FocusControls//" , + + FocusControls_fErrorReset , + FocusControls_bRange , + FocusControls_bMode , + FocusControls_bAFCommand , + FocusControls_bLensCommand , + FocusControls_bManualStep_Size , + FocusControls_fTestCoinEnabled , + FocusControls_bControlCoin , + FocusControls_fInternalStats_Disable , + FocusControls_bActuator_Disable , + FocusControls_fInhibitAutoMetering , + + //"FocusStatus//" , + + FocusStatus_bModeStatus , + FocusStatus_bAFCommandStatus , + FocusStatus_bLensCommandStatus , + FocusStatus_fAutoFocusEnabled , + FocusStatus_bRange , + FocusStatus_fIsStable , + FocusStatus_fError , + FocusStatus_cErrorCode , + FocusStatus_fLensIsMovingAtTheSOF, + FocusStatus_bCycles , + FocusStatus_fRunForTest , + FocusStatus_bStatusCoin , + FocusStatus_fInternalStats_Disabled , + FocusStatus_bActuator_Disabled , + FocusStatus_bLastUsedAFSensor , + + //"FocusRangeConstants//" , + + FocusRangeConstants_wFullRange_LensMinPosition_LSByte , + FocusRangeConstants_wFullRange_LensMinPosition_MSByte , + FocusRangeConstants_wFullRange_LensMaxPosition_LSByte , + FocusRangeConstants_wFullRange_LensMaxPosition_MSByte , + FocusRangeConstants_wFullRange_LensRecoveryPosition_LSByte , + FocusRangeConstants_wFullRange_LensRecoveryPosition_MSByte , + FocusRangeConstants_wLandscape_LensMinPosition_LSByte , + FocusRangeConstants_wLandscape_LensMinPosition_MSByte , + FocusRangeConstants_wLandscape_LensMaxPosition_LSByte , + FocusRangeConstants_wLandscape_LensMaxPosition_MSByte , + FocusRangeConstants_wLandscape_LensRecoveryPosition_LSByte , + FocusRangeConstants_wLandscape_LensRecoveryPosition_MSByte , + FocusRangeConstants_wMacro_LensMinPosition_LSByte , + FocusRangeConstants_wMacro_LensMinPosition_MSByte , + FocusRangeConstants_wMacro_LensMaxPosition_LSByte , + FocusRangeConstants_wMacro_LensMaxPosition_MSByte , + FocusRangeConstants_wMacro_LensRecoveryPosition_LSByte , + FocusRangeConstants_wMacro_LensRecoveryPosition_MSByte , + + //"AutoFocusControls//" , + + AutoFocusControls_bHostCmd, + AutoFocusControls_fFreezeIfStable , + AutoFocusControls_fFMTesting_AutoDisable , + AutoFocusControls_fFastAFAlgoStart , + AutoFocusControls_fBackLight_Enable , + AutoFocusControls_fBackupSolution , + AutoFocusControls_fCheckExposureStable_Enable , + AutoFocusControls_fEnableSimpleCoarseThEvaluation , + AutoFocusControls_bSelectedMultizoneBehavior , + AutoFocusControls_bBackLightMethodSelected , + AutoFocusControls_bWeighedFunctionSelected , + AutoFocusControls_fMotionBlurEnable , + AutoFocusControls_fLightVariationEnable , + AutoFocusControls_fEnableTrackingThresholdEvaluation , + AutoFocusControls_fEnableHeuristicMethod , + AutoFocusControls_fEnableBackupSolution , + AutoFocusControls_fFineToCoarseAutoTransitionEnable , + AutoFocusControls_fEnableTimedFineExecution , + AutoFocusControls_fEnableTrakingZoneVariation , + AutoFocusControls_fEnableFunctionThresholdTest , + AutoFocusControls_fForceTestState , + AutoFocusControls_bManualAFNextState , + AutoFocusControls_fResetHCSPos , + + //"AutoFocusConstants//" , + + AutoFocusConstants_bCoarseStep , + AutoFocusConstants_bFineStep , + AutoFocusConstants_bFullSearchStep , + AutoFocusConstants_bLeakyIntegratorConstant , + AutoFocusConstants_uwFineThreshold_LSByte , + AutoFocusConstants_uwFineThreshold_MSByte, + AutoFocusConstants_bFineToCoarseThreshold , + AutoFocusConstants_uwBacklightThreshold_LSByte , + AutoFocusConstants_uwBacklightThreshold_MSByte , + AutoFocusConstants_uwMotionBlurInRatio_LSByte , + AutoFocusConstants_uwMotionBlurInRatio_MSByte , + AutoFocusConstants_uwMotionBlurOutRatio_LSByte , + AutoFocusConstants_uwMotionBlurOutRatio_MSByte , + AutoFocusConstants_bMaxNumberContinuouslyInstableTime , + AutoFocusConstants_bMaxNumberContinuouslyStableFrame , + AutoFocusConstants_uwMaxNumberContinuouslyThresholdTime , + AutoFocusConstants_uwFixedLowFocusMeasureValue_LSByte , + AutoFocusConstants_uwFixedLowFocusMeasureValue_MSByte , + AutoFocusConstants_bMaxFocusMeasureThreshold , + AutoFocusConstants_bLightGap , + AutoFocusConstants_uwDeltaValue_LSByte , + AutoFocusConstants_uwDeltaValue_MSByte , + AutoFocusConstants_uwMaxFineTh_LSByte , + AutoFocusConstants_uwMaxFineTh_MSByte , + + //"AutoFocusInput//" , + + AutoFocusInput_wLensPosition_LSByte , + AutoFocusInput_wLensPosition_MSByte , + AutoFocusInput_fLimitsExceeded , + AutoFocusInput_wLastStepExecuted_LSByte , + AutoFocusInput_wLastStepExecuted_MSByte , + + //"AutoFocusStatus//" , + + AutoFocusStatus_bCycles , + AutoFocusStatus_bHostCmd, + AutoFocusStatus_bAF_PrevState , + AutoFocusStatus_bAF_State , + AutoFocusStatus_bAF_NextState , + AutoFocusStatus_bAF_PrevInstableFMState , + AutoFocusStatus_bAF_NextInstableFMState , + AutoFocusStatus_fChangeDirectionStatus , + AutoFocusStatus_bHCS_State , + AutoFocusStatus_bHCS_NextState , + AutoFocusStatus_bHCS_PrevState , + AutoFocusStatus_fReserved , + AutoFocusStatus_fCoarseInvoked , + AutoFocusStatus_fFullSearchInvoked , + AutoFocusStatus_fFullSearchZero , + AutoFocusStatus_fInFocus , + AutoFocusStatus_fMotionBlurIdentified , + AutoFocusStatus_fInitialSearch , + AutoFocusStatus_wMaxStepMotorLens_LSByte , + AutoFocusStatus_wMaxStepMotorLens_MSByte , + AutoFocusStatus_wTotalStepMotorLens_LSByte , + AutoFocusStatus_wTotalStepMotorLens_MSByte , + AutoFocusStatus_bNumberOfFrames , + AutoFocusStatus_bCountFineSteps , + AutoFocusStatus_bCountTrackingFrames , + AutoFocusStatus_bNumberOfSelectedRegions , + AutoFocusStatus_bOldNumberOfSelectedRegions , + AutoFocusStatus_uwSelectedRegionsStatus_LSByte , + AutoFocusStatus_uwSelectedRegionsStatus_MSByte , + AutoFocusStatus_uwTotalCoarseVariation_LSByte , + AutoFocusStatus_uwTotalCoarseVariation_MSByte , + AutoFocusStatus_uwTotalFineVariation_LSByte , + AutoFocusStatus_uwTotalFineVariation_MSByte, + AutoFocusStatus_bCountVariationRegion , + + //"AutoFocusOutput//" , + + AutoFocusOutput_cFocusLensActuatorCommand , + AutoFocusOutput_wStep_LSByte , + AutoFocusOutput_wStep_MSByte , + AutoFocusOutput_cDirection , + + //"AutoFocusMeasureData//" , + + AutoFocusMeasureData_udwFocusMeasure_Byte0 , + AutoFocusMeasureData_udwFocusMeasure_Byte1 , + AutoFocusMeasureData_udwFocusMeasure_Byte2 , + AutoFocusMeasureData_udwFocusMeasure_Byte3 , + AutoFocusMeasureData_udwPrevFocusMeasure_Byte0 , + AutoFocusMeasureData_udwPrevFocusMeasure_Byte1 , + AutoFocusMeasureData_udwPrevFocusMeasure_Byte2 , + AutoFocusMeasureData_udwPrevFocusMeasure_Byte3 , + AutoFocusMeasureData_udwMB_FocusMeasure_Byte0 , + AutoFocusMeasureData_udwMB_FocusMeasure_Byte1 , + AutoFocusMeasureData_udwMB_FocusMeasure_Byte2 , + AutoFocusMeasureData_udwMB_FocusMeasure_Byte3 , + AutoFocusMeasureData_udwMB_PrevFocusMeasure_Byte0 , + AutoFocusMeasureData_udwMB_PrevFocusMeasure_Byte1 , + AutoFocusMeasureData_udwMB_PrevFocusMeasure_Byte2 , + AutoFocusMeasureData_udwMB_PrevFocusMeasure_Byte3 , + AutoFocusMeasureData_udwMaxFocusMeasure_Byte0 , + AutoFocusMeasureData_udwMaxFocusMeasure_Byte1 , + AutoFocusMeasureData_udwMaxFocusMeasure_Byte2 , + AutoFocusMeasureData_udwMaxFocusMeasure_Byte3, + AutoFocusMeasureData_udwOldMaxFocusMeasure_Byte0 , + AutoFocusMeasureData_udwOldMaxFocusMeasure_Byte1 , + AutoFocusMeasureData_udwOldMaxFocusMeasure_Byte2 , + AutoFocusMeasureData_udwOldMaxFocusMeasure_Byte3 , + AutoFocusMeasureData_udwPrevMaxFocusMeasure_Byte0 , + AutoFocusMeasureData_udwPrevMaxFocusMeasure_Byte1 , + AutoFocusMeasureData_udwPrevMaxFocusMeasure_Byte2 , + AutoFocusMeasureData_udwPrevMaxFocusMeasure_Byte3 , + AutoFocusMeasureData_udwNextMaxFocusMeasure_Byte0 , + AutoFocusMeasureData_udwNextMaxFocusMeasure_Byte1 , + AutoFocusMeasureData_udwNextMaxFocusMeasure_Byte2 , + AutoFocusMeasureData_udwNextMaxFocusMeasure_Byte3 , + AutoFocusMeasureData_udwWeighedFocusMeasure_Byte0 , + AutoFocusMeasureData_udwWeighedFocusMeasure_Byte1 , + AutoFocusMeasureData_udwWeighedFocusMeasure_Byte2 , + AutoFocusMeasureData_udwWeighedFocusMeasure_Byte3 , + AutoFocusMeasureData_udwMaxMaxFocusMeasure_Byte0 , + AutoFocusMeasureData_udwMaxMaxFocusMeasure_Byte1 , + AutoFocusMeasureData_udwMaxMaxFocusMeasure_Byte2 , + AutoFocusMeasureData_udwMaxMaxFocusMeasure_Byte3 , + AutoFocusMeasureData_udwTrackingFocusMeasure_Byte0 , + AutoFocusMeasureData_udwTrackingFocusMeasure_Byte1 , + AutoFocusMeasureData_udwTrackingFocusMeasure_Byte2 , + AutoFocusMeasureData_udwTrackingFocusMeasure_Byte3 , + AutoFocusMeasureData_udwTrackingFocusMeasureDifference_Byte0 , + AutoFocusMeasureData_udwTrackingFocusMeasureDifference_Byte1 , + AutoFocusMeasureData_udwTrackingFocusMeasureDifference_Byte2 , + AutoFocusMeasureData_udwTrackingFocusMeasureDifference_Byte3 , + AutoFocusMeasureData_udwCurrentFocusMeasureDifference_Byte0 , + AutoFocusMeasureData_udwCurrentFocusMeasureDifference_Byte1 , + AutoFocusMeasureData_udwCurrentFocusMeasureDifference_Byte2, + AutoFocusMeasureData_udwCurrentFocusMeasureDifference_Byte3 , + AutoFocusMeasureData_udwOldTrackingFocusMeasure_Byte0 , + AutoFocusMeasureData_udwOldTrackingFocusMeasure_Byte1 , + AutoFocusMeasureData_udwOldTrackingFocusMeasure_Byte2 , + AutoFocusMeasureData_udwOldTrackingFocusMeasure_Byte3 , + + //"AutoFocusWeightControls//" , + + AutoFocusWeightControls_bWeight_0 , + AutoFocusWeightControls_bWeight_1 , + AutoFocusWeightControls_bWeight_2 , + AutoFocusWeightControls_bWeight_3 , + AutoFocusWeightControls_bWeight_4 , + AutoFocusWeightControls_bWeight_5 , + AutoFocusWeightControls_bWeight_6 , + + //"AutoFocusDynamicWeight//" , + + AutoFocusDynamicWeight_bWeight_0 , + AutoFocusDynamicWeight_bWeight_1 , + AutoFocusDynamicWeight_bWeight_2 , + AutoFocusDynamicWeight_bWeight_3 , + AutoFocusDynamicWeight_bWeight_4 , + AutoFocusDynamicWeight_bWeight_5 , + AutoFocusDynamicWeight_bWeight_6 , + + //"AutoFocusThresholds//" , + + AutoFocusThresholds_uwCoarseThreshold_LSByte , + AutoFocusThresholds_uwCoarseThreshold_MSByte , + AutoFocusThresholds_uwFineThreshold_LSByte, + AutoFocusThresholds_uwFineThreshold_MSByte , + AutoFocusThresholds_uwBeforeMotionBlur_LSByte , + AutoFocusThresholds_uwBeforeMotionBlur_MSByte , + AutoFocusThresholds_uwAfterMotionBlur_LSByte , + AutoFocusThresholds_uwAfterMotionBlur_MSByte , + AutoFocusThresholds_udwCurrentVariation_Byte0 , + AutoFocusThresholds_udwCurrentVariation_Byte1 , + AutoFocusThresholds_udwCurrentVariation_Byte2 , + AutoFocusThresholds_udwCurrentVariation_Byte3 , + AutoFocusThresholds_udwLowFocusMeasureValue_Byte0 , + AutoFocusThresholds_udwLowFocusMeasureValue_Byte1 , + AutoFocusThresholds_udwLowFocusMeasureValue_Byte2 , + AutoFocusThresholds_udwLowFocusMeasureValue_Byte3 , + + //"AutoFocusHeuristicConstants//" , + + AutoFocusHeuristicConstants_uwLensPositionInputMax_LSByte , + AutoFocusHeuristicConstants_uwLensPositionInputMax_MSByte , + AutoFocusHeuristicConstants_uwLensPositionInputMin_LSByte , + AutoFocusHeuristicConstants_uwLensPositionInputMin_MSByte , + AutoFocusHeuristicConstants_bBrightnessInputMax , + AutoFocusHeuristicConstants_bBrightnessInputMin , + AutoFocusHeuristicConstants_uwThFineMax_LSByte , + AutoFocusHeuristicConstants_uwThFineMax_MSByte , + AutoFocusHeuristicConstants_uwThFineMin_LSByte , + AutoFocusHeuristicConstants_uwThFineMin_MSByte , + AutoFocusHeuristicConstants_uwFineToCoarseMax_LSByte , + AutoFocusHeuristicConstants_uwFineToCoarseMax_MSByte , + AutoFocusHeuristicConstants_uwFineToCoarseMin_LSByte , + AutoFocusHeuristicConstants_uwFineToCoarseMin_MSByte , + AutoFocusHeuristicConstants_bHighToMaxFMShiftFactor, + AutoFocusHeuristicConstants_bLowToHighFMShiftFactor , + + //"AutoFocusThHeuristicInput//" , + + AutoFocusThHeuristicInput_udwFocusMeasureInputMax_Byte0 , + AutoFocusThHeuristicInput_udwFocusMeasureInputMax_Byte1 , + AutoFocusThHeuristicInput_udwFocusMeasureInputMax_Byte2 , + AutoFocusThHeuristicInput_udwFocusMeasureInputMax_Byte3 , + AutoFocusThHeuristicInput_udwFocusMeasureInputMin_Byte0 , + AutoFocusThHeuristicInput_udwFocusMeasureInputMin_Byte1 , + AutoFocusThHeuristicInput_udwFocusMeasureInputMin_Byte2 , + AutoFocusThHeuristicInput_udwFocusMeasureInputMin_Byte3 , + AutoFocusThHeuristicInput_udwFocusMeasureInput_Byte0 , + AutoFocusThHeuristicInput_udwFocusMeasureInput_Byte1 , + AutoFocusThHeuristicInput_udwFocusMeasureInput_Byte2 , + AutoFocusThHeuristicInput_udwFocusMeasureInput_Byte3 , + AutoFocusThHeuristicInput_uwLensPositionInput_LSByte , + AutoFocusThHeuristicInput_uwLensPositionInput_MSByte , + AutoFocusThHeuristicInput_bBrightnessInput , + + //"AutoFocusInstableFocusMeasureStatus//" , + + AutoFocusInstableFocusMeasureStatus_bStatus_SceneDetector , + AutoFocusInstableFocusMeasureStatus_bCountInstableFocusMeasure , + AutoFocusInstableFocusMeasureStatus_bCountStableFocusMeasure , + + //"AutoFocusLFMFullSearchStatus//" , + + AutoFocusLFMFullSearchStatus_bPrevState_AFFS , + AutoFocusLFMFullSearchStatus_bState_AFFS , + AutoFocusLFMFullSearchStatus_bNextState_AFFS, + AutoFocusLFMFullSearchStatus_bCountFullSearchContinuouslyIncreaseValue , + + //"AutoFocusMZFullSearchStatus//" , + + AutoFocusMZFullSearchStatus_bFS_PrevState , + AutoFocusMZFullSearchStatus_bFS_State , + AutoFocusMZFullSearchStatus_bFS_NextState , + AutoFocusMZFullSearchStatus_bMaxMaxRegionPositionIndex , + + //"MiscPageElements//" , + + MiscPageElements_fConvertMultiByteReadsIntoSingleByte , + MiscPageElements_bDelayAfterSettingXshutdown , + MiscPageElements_fEnableIntelligentFlash , + MiscPageElements_fEligibleFrameForMetering , + MiscPageElements_fFlashGunIlluminatedFrameStreamed , + MiscPageElements_VpipCut , + MiscPageElements_bGPIOClockFrequency_Mhz , + MiscPageElements_bIntelligentFlashModeStatus , + MiscPageElements_fStartMeteringFromManualGains , + MiscPageElements_fEnableDelayWhenStartingSensor , + MiscPageElements_fEnableDelayWhenStoppingSensor , + MiscPageElements_fTriggerFlashOnStreaming , + MiscPageElements_fDoNotOutputFrameInIntelligentFlash , + MiscPageElements_fDisableToshibaInit , + MiscPageElements_bNumberofFramesTobeSkippedByRx , + + //"CutBMasterI2cStatus//" , + + CutBMasterI2cStatus_bWriteFifoUseCount , + + //"MasterI2cClockControl//" , + + MasterI2cClockControl_bCountFall , + MasterI2cClockControl_bCountRise , + MasterI2cClockControl_bCountHigh , + MasterI2cClockControl_bCountBuffer , + MasterI2cClockControl_bCountHoldData , + MasterI2cClockControl_bCountSetupData , + MasterI2cClockControl_bCountHoldStart , + MasterI2cClockControl_bCountSetupStart , + MasterI2cClockControl_bCountSetupStop , + + //"ZoomMgrFOVCtrl//" , + + ZoomMgrFOVCtrl_bShiftCenter , + ZoomMgrFOVCtrl_uwXOrigin_LSByte , + ZoomMgrFOVCtrl_uwXOrigin_MSByte , + ZoomMgrFOVCtrl_uwYOrigin_LSByte , + ZoomMgrFOVCtrl_uwYOrigin_MSByte , + ZoomMgrFOVCtrl_fRestrictMaxFOVToChosenFOV , + ZoomMgrFOVCtrl_fCalculateMinFOVAlways , + ZoomMgrFOVCtrl_fInhibitMaxFOVAtModeStaticChange , + + //"ZoomMgrSpeedInfo//" , + + ZoomMgrSpeedInfo_bNumberOfFramesOnHold , + ZoomMgrSpeedInfo_bDelay_frames , + ZoomMgrSpeedInfo_uwTotalDelay_frames_LSByte , + ZoomMgrSpeedInfo_uwTotalDelay_frames_MSByte , + ZoomMgrSpeedInfo_bNumberOfZoomSteps , + + //"ZoomMgrStripeCtrl//" , + + ZoomMgrStripeCtrl_bStripeControl , + ZoomMgrStripeCtrl_uwStripeStartAddr_LSByte , + ZoomMgrStripeCtrl_uwStripeStartAddr_MSByte , + ZoomMgrStripeCtrl_uwStripeSize_LSByte , + ZoomMgrStripeCtrl_uwStripeSize_MSByte , + ZoomMgrStripeCtrl_uwStripeInMinLineSize_LSByte , + ZoomMgrStripeCtrl_uwStripeInMinLineSize_MSByte , + ZoomMgrStripeCtrl_uwBmsFrameLength_LSByte , + ZoomMgrStripeCtrl_uwBmsFrameLength_MSByte , + + //"LftStripeParam//" , + + LftStripeParam_uwGPSISize_LSByte , + LftStripeParam_uwGPSISize_MSByte , + LftStripeParam_uwGPSOSize_LSByte , + LftStripeParam_uwGPSOSize_MSByte , + LftStripeParam_uwRightBorder_LSByte , + LftStripeParam_uwRightBorder_MSByte , + LftStripeParam_uwLeftBorder_LSByte , + LftStripeParam_uwLeftBorder_MSByte , + LftStripeParam_wGPSCropBulk_LSByte , + LftStripeParam_wGPSCropBulk_MSByte , + LftStripeParam_wGPSCropFrac_LSByte , + LftStripeParam_wGPSCropFrac_MSByte , + LftStripeParam_uwStripeInCropStart_LSByte , + LftStripeParam_uwStripeInCropStart_MSByte , + LftStripeParam_uwStripeInCropSize_LSByte , + LftStripeParam_uwStripeInCropSize_MSByte , + LftStripeParam_uwStripeOutCropStart_LSByte, + LftStripeParam_uwStripeOutCropStart_MSByte , + LftStripeParam_uwStripeOutCropSize_LSByte , + LftStripeParam_uwStripeOutCropSize_MSByte , + + //"RgtStripeParam//" , + + RgtStripeParam_uwGPSISize_LSByte , + RgtStripeParam_uwGPSISize_MSByte , + RgtStripeParam_uwGPSOSize_LSByte , + RgtStripeParam_uwGPSOSize_MSByte , + RgtStripeParam_uwRightBorder_LSByte , + RgtStripeParam_uwRightBorder_MSByte , + RgtStripeParam_uwLeftBorder_LSByte , + RgtStripeParam_uwLeftBorder_MSByte , + RgtStripeParam_wGPSCropBulk_LSByte , + RgtStripeParam_wGPSCropBulk_MSByte , + RgtStripeParam_wGPSCropFrac_LSByte , + RgtStripeParam_wGPSCropFrac_MSByte , + RgtStripeParam_uwStripeInCropStart_LSByte , + RgtStripeParam_uwStripeInCropStart_MSByte , + RgtStripeParam_uwStripeInCropSize_LSByte , + RgtStripeParam_uwStripeInCropSize_MSByte , + RgtStripeParam_uwStripeOutCropStart_LSByte , + RgtStripeParam_uwStripeOutCropStart_MSByte , + RgtStripeParam_uwStripeOutCropSize_LSByte , + RgtStripeParam_uwStripeOutCropSize_MSByte , + + //"DigitalGainStatus//" , + + DigitalGainStatus_uwCodedGreen1Gain_LSByte , + DigitalGainStatus_uwCodedGreen1Gain_MSByte, + DigitalGainStatus_uwCodedRedGain_LSByte , + DigitalGainStatus_uwCodedRedGain_MSByte , + DigitalGainStatus_uwCodedBlueGain_LSByte , + DigitalGainStatus_uwCodedBlueGain_MSByte , + DigitalGainStatus_uwCodedGreen2Gain_LSByte , + DigitalGainStatus_uwCodedGreen2Gain_MSByte , + + //"OffsetCompensationStatus//" , + + OffsetCompensationStatus_uwOffset_LSByte , + OffsetCompensationStatus_uwOffset_MSByte , + OffsetCompensationStatus_fpOffsetCompensationGain_LSByte , + OffsetCompensationStatus_fpOffsetCompensationGain_MSByte , + + //"AntiFlickerExposureStatus//" , + + AntiFlickerExposureStatus_fpFlickerFreePeriod_us_LSByte , + AntiFlickerExposureStatus_fpFlickerFreePeriod_us_MSByte , + AntiFlickerExposureStatus_fpGainedFlickerFreeTimePeriod_us_LSByte , + AntiFlickerExposureStatus_fpGainedFlickerFreeTimePeriod_us_MSByte , + AntiFlickerExposureStatus_uwMaxFlickerFreeBunches_LSByte , + AntiFlickerExposureStatus_uwMaxFlickerFreeBunches_MSByte , + AntiFlickerExposureStatus_fpConstrainedFlickerFreePeriod_us_LSByte , + AntiFlickerExposureStatus_fpConstrainedFlickerFreePeriod_us_MSByte , + + //"ModuleEnables//" , + + ModuleEnables_fDisableCho , + ModuleEnables_fDisableChg , + + //"DummyPage1//" + + DummyPage1_bDummyPageElement , + + //"DummyPage2//" , + + DummyPage2_bDummyPageElement , + + //"SensorSetupFarSensor//" , + + SensorSetupFarSensor_uwGuaranteedDataSaturationLevel_LSByte , + SensorSetupFarSensor_uwGuaranteedDataSaturationLevel_MSByte , + SensorSetupFarSensor_uwMinimumSensorRxPixelValue_LSByte , + SensorSetupFarSensor_uwMinimumSensorRxPixelValue_MSByte , + SensorSetupFarSensor_uwMaximumSensorRxPixelValue_LSByte , + SensorSetupFarSensor_uwMaximumSensorRxPixelValue_MSByte , + SensorSetupFarSensor_fpRedTiltGain_LSByte , + SensorSetupFarSensor_fpRedTiltGain_MSByte , + SensorSetupFarSensor_fpGreenTiltGain_LSByte , + SensorSetupFarSensor_fpGreenTiltGain_MSByte , + SensorSetupFarSensor_fpBlueTiltGain_LSByte , + SensorSetupFarSensor_fpBlueTiltGain_MSByte , + SensorSetupFarSensor_BlackCorrectionOffset , + + //"SensorSetupNearSensor//" , + + SensorSetupNearSensor_uwGuaranteedDataSaturationLevel_LSByte , + SensorSetupNearSensor_uwGuaranteedDataSaturationLevel_MSByte , + SensorSetupNearSensor_uwMinimumSensorRxPixelValue_LSByte , + SensorSetupNearSensor_uwMinimumSensorRxPixelValue_MSByte , + SensorSetupNearSensor_uwMaximumSensorRxPixelValue_LSByte , + SensorSetupNearSensor_uwMaximumSensorRxPixelValue_MSByte, + SensorSetupNearSensor_fpRedTiltGain_LSByte , + SensorSetupNearSensor_fpRedTiltGain_MSByte , + SensorSetupNearSensor_fpGreenTiltGain_LSByte , + SensorSetupNearSensor_fpGreenTiltGain_MSByte , + SensorSetupNearSensor_fpBlueTiltGain_LSByte , + SensorSetupNearSensor_fpBlueTiltGain_MSByte , + SensorSetupNearSensor_BlackCorrectionOffset , + + //"ToshibaOtpRead//" , + + ToshibaOtpRead_otp_inf_2 , + ToshibaOtpRead_otp_inf_1 , + ToshibaOtpRead_otp_inf_0 , + ToshibaOtpRead_otp_mac_2 , + ToshibaOtpRead_otp_mac_1 , + ToshibaOtpRead_otp_mac_0 , + ToshibaOtpRead_otp_posA_1 , + ToshibaOtpRead_otp_posA_0 , + ToshibaOtpRead_otp_posB_1 , + ToshibaOtpRead_otp_posB_0 , + ToshibaOtpRead_otp_register_map_ver , + + //"NormalisedWhiteBalanceGains//" , + + NormalisedWhiteBalanceGains_fpNormalisedRedGain_LSByte , + NormalisedWhiteBalanceGains_fpNormalisedRedGain_MSByte , + + //"ReferenceIlluminantCasts//" , + + ReferenceIlluminantCasts_fpCAST0_LSByte , + ReferenceIlluminantCasts_fpCAST0_MSByte, + ReferenceIlluminantCasts_fpCAST1_LSByte , + ReferenceIlluminantCasts_fpCAST1_MSByte , + ReferenceIlluminantCasts_fpCAST2_LSByte , + ReferenceIlluminantCasts_fpCAST2_MSByte , + ReferenceIlluminantCasts_fpCAST3_LSByte , + ReferenceIlluminantCasts_fpCAST3_MSByte , + + //"AdaptiveAVParameter_B//" , + + AdaptiveAVParameter_B_bAvUnityOffset_Day , + AdaptiveAVParameter_B_bAvCoeffR2_Day , + AdaptiveAVParameter_B_bAvCoeffR4_Day , + AdaptiveAVParameter_B_wAvHOffset_Day_LSByte , + AdaptiveAVParameter_B_wAvHOffset_Day_MSByte , + AdaptiveAVParameter_B_wAvVOffset_Day_LSByte , + AdaptiveAVParameter_B_wAvVOffset_Day_MSByte , + AdaptiveAVParameter_B_bAvUnityOffset_COO , + AdaptiveAVParameter_B_bAvCoeffR2_COO , + AdaptiveAVParameter_B_bAvCoeffR4_COO , + AdaptiveAVParameter_B_wAvHOffset_COO_LSByte , + AdaptiveAVParameter_B_wAvHOffset_COO_MSByte , + AdaptiveAVParameter_B_wAvVOffset_COO_LSByte , + AdaptiveAVParameter_B_wAvVOffset_COO_MSByte , + AdaptiveAVParameter_B_bAvUnityOffset_INC , + AdaptiveAVParameter_B_bAvCoeffR2_INC , + AdaptiveAVParameter_B_bAvCoeffR4_INC , + AdaptiveAVParameter_B_wAvHOffset_INC_LSByte , + AdaptiveAVParameter_B_wAvHOffset_INC_MSByte , + AdaptiveAVParameter_B_wAvVOffset_INC_LSByte , + AdaptiveAVParameter_B_wAvVOffset_INC_MSByte , + AdaptiveAVParameter_B_bAvUnityOffset_HOR, + AdaptiveAVParameter_B_bAvCoeffR2_HOR , + AdaptiveAVParameter_B_bAvCoeffR4_HOR , + AdaptiveAVParameter_B_wAvHOffset_HOR_LSByte , + AdaptiveAVParameter_B_wAvHOffset_HOR_MSByte , + AdaptiveAVParameter_B_wAvVOffset_HOR_LSByte , + AdaptiveAVParameter_B_wAvVOffset_HOR_MSByte , + + //"AdaptiveAVParameter_GB//" , + + AdaptiveAVParameter_GB_bAvUnityOffset_Day , + AdaptiveAVParameter_GB_bAvCoeffR2_Day , + AdaptiveAVParameter_GB_bAvCoeffR4_Day , + AdaptiveAVParameter_GB_wAvHOffset_Day_LSByte , + AdaptiveAVParameter_GB_wAvHOffset_Day_MSByte , + AdaptiveAVParameter_GB_wAvVOffset_Day_LSByte , + AdaptiveAVParameter_GB_wAvVOffset_Day_MSByte , + AdaptiveAVParameter_GB_bAvUnityOffset_COO , + AdaptiveAVParameter_GB_bAvCoeffR2_COO , + AdaptiveAVParameter_GB_bAvCoeffR4_COO , + AdaptiveAVParameter_GB_wAvHOffset_COO_LSByte , + AdaptiveAVParameter_GB_wAvHOffset_COO_MSByte , + AdaptiveAVParameter_GB_wAvVOffset_COO_LSByte , + AdaptiveAVParameter_GB_wAvVOffset_COO_MSByte , + AdaptiveAVParameter_GB_bAvUnityOffset_INC , + AdaptiveAVParameter_GB_bAvCoeffR2_INC , + AdaptiveAVParameter_GB_bAvCoeffR4_INC , + AdaptiveAVParameter_GB_wAvHOffset_INC_LSByte , + AdaptiveAVParameter_GB_wAvHOffset_INC_MSByte , + AdaptiveAVParameter_GB_wAvVOffset_INC_LSByte , + AdaptiveAVParameter_GB_wAvVOffset_INC_MSByte , + AdaptiveAVParameter_GB_bAvUnityOffset_HOR, + AdaptiveAVParameter_GB_bAvCoeffR2_HOR , + AdaptiveAVParameter_GB_bAvCoeffR4_HOR , + AdaptiveAVParameter_GB_wAvHOffset_HOR_LSByte , + AdaptiveAVParameter_GB_wAvHOffset_HOR_MSByte , + AdaptiveAVParameter_GB_wAvVOffset_HOR_LSByte , + AdaptiveAVParameter_GB_wAvVOffset_HOR_MSByte , + + //"AdaptiveAVParameter_GR//" , + + AdaptiveAVParameter_GR_bAvUnityOffset_Day , + AdaptiveAVParameter_GR_bAvCoeffR2_Day , + AdaptiveAVParameter_GR_bAvCoeffR4_Day , + AdaptiveAVParameter_GR_wAvHOffset_Day_LSByte , + AdaptiveAVParameter_GR_wAvHOffset_Day_MSByte , + AdaptiveAVParameter_GR_wAvVOffset_Day_LSByte , + AdaptiveAVParameter_GR_wAvVOffset_Day_MSByte , + AdaptiveAVParameter_GR_bAvUnityOffset_COO , + AdaptiveAVParameter_GR_bAvCoeffR2_COO , + AdaptiveAVParameter_GR_bAvCoeffR4_COO , + AdaptiveAVParameter_GR_wAvHOffset_COO_LSByte , + AdaptiveAVParameter_GR_wAvHOffset_COO_MSByte , + AdaptiveAVParameter_GR_wAvVOffset_COO_LSByte , + AdaptiveAVParameter_GR_wAvVOffset_COO_MSByte , + AdaptiveAVParameter_GR_bAvUnityOffset_INC , + AdaptiveAVParameter_GR_bAvCoeffR2_INC , + AdaptiveAVParameter_GR_bAvCoeffR4_INC , + AdaptiveAVParameter_GR_wAvHOffset_INC_LSByte , + AdaptiveAVParameter_GR_wAvHOffset_INC_MSByte , + AdaptiveAVParameter_GR_wAvVOffset_INC_LSByte , + AdaptiveAVParameter_GR_wAvVOffset_INC_MSByte , + AdaptiveAVParameter_GR_bAvUnityOffset_HOR, + AdaptiveAVParameter_GR_bAvCoeffR2_HOR , + AdaptiveAVParameter_GR_bAvCoeffR4_HOR , + AdaptiveAVParameter_GR_wAvHOffset_HOR_LSByte , + AdaptiveAVParameter_GR_wAvHOffset_HOR_MSByte , + AdaptiveAVParameter_GR_wAvVOffset_HOR_LSByte , + AdaptiveAVParameter_GR_wAvVOffset_HOR_MSByte , + + //"AdaptiveAVParameter_R//" , + + AdaptiveAVParameter_R_bAvUnityOffset_Day , + AdaptiveAVParameter_R_bAvCoeffR2_Day , + AdaptiveAVParameter_R_bAvCoeffR4_Day , + AdaptiveAVParameter_R_wAvHOffset_Day_LSByte , + AdaptiveAVParameter_R_wAvHOffset_Day_MSByte , + AdaptiveAVParameter_R_wAvVOffset_Day_LSByte , + AdaptiveAVParameter_R_wAvVOffset_Day_MSByte , + AdaptiveAVParameter_R_bAvUnityOffset_COO , + AdaptiveAVParameter_R_bAvCoeffR2_COO , + AdaptiveAVParameter_R_bAvCoeffR4_COO , + AdaptiveAVParameter_R_wAvHOffset_COO_LSByte , + AdaptiveAVParameter_R_wAvHOffset_COO_MSByte , + AdaptiveAVParameter_R_wAvVOffset_COO_LSByte , + AdaptiveAVParameter_R_wAvVOffset_COO_MSByte , + AdaptiveAVParameter_R_bAvUnityOffset_INC , + AdaptiveAVParameter_R_bAvCoeffR2_INC , + AdaptiveAVParameter_R_bAvCoeffR4_INC , + AdaptiveAVParameter_R_wAvHOffset_INC_LSByte , + AdaptiveAVParameter_R_wAvHOffset_INC_MSByte , + AdaptiveAVParameter_R_wAvVOffset_INC_LSByte , + AdaptiveAVParameter_R_wAvVOffset_INC_MSByte , + AdaptiveAVParameter_R_bAvUnityOffset_HOR, + AdaptiveAVParameter_R_bAvCoeffR2_HOR , + AdaptiveAVParameter_R_bAvCoeffR4_HOR , + AdaptiveAVParameter_R_wAvHOffset_HOR_LSByte , + AdaptiveAVParameter_R_wAvHOffset_HOR_MSByte , + AdaptiveAVParameter_R_wAvVOffset_HOR_LSByte , + AdaptiveAVParameter_R_wAvVOffset_HOR_MSByte , + + //"ContrastStretchControl//" , + + ContrastStretchControl_fEnableContrastStretch , + ContrastStretchControl_bMode , + ContrastStretchControl_bAccColour , + ContrastStretchControl_bBlackThreshold , + ContrastStretchControl_bWhiteThreshold , + + //"ContrastStretchStatus//" , + + ContrastStretchStatus_uBlackBinAThreshold_hi , + ContrastStretchStatus_uBlackBinBThreshold_hi , + ContrastStretchStatus_uWhiteBinAThreshold_lo , + ContrastStretchStatus_uWhiteBinBThreshold_lo , + ContrastStretchStatus_fpGain_LSByte , + ContrastStretchStatus_fpGain_MSByte , + + //"DynamicConstrainedWBControls//" , + + DynamicConstrainedWBControls_fpRedA_LSByte , + DynamicConstrainedWBControls_fpRedA_MSByte , + DynamicConstrainedWBControls_fpBlueA_LSByte , + DynamicConstrainedWBControls_fpBlueA_MSByte , + DynamicConstrainedWBControls_fpDamperLowThreshold_LSByte, + DynamicConstrainedWBControls_fpDamperLowThreshold_MSByte , + DynamicConstrainedWBControls_fpMinimumDamperOutput_LSByte , + DynamicConstrainedWBControls_fpMinimumDamperOutput_MSByte , + DynamicConstrainedWBControls_fpDamperHighThreshold_LSByte , + DynamicConstrainedWBControls_fpDamperHighThreshold_MSByte , + DynamicConstrainedWBControls_fDamperDisable , + + //"Toshiba_AF_NVM_Read//" , + + Toshiba_AF_NVM_Read_NVM_Far2Near_inf_LSByte , + Toshiba_AF_NVM_Read_NVM_Far2Near_inf_MSByte , + Toshiba_AF_NVM_Read_NVM_Near2Far_inf_LSByte , + Toshiba_AF_NVM_Read_NVM_Near2Far_inf_MSByte , + Toshiba_AF_NVM_Read_NVM_Far2Near_mac_LSByte , + Toshiba_AF_NVM_Read_NVM_Far2Near_mac_MSByte , + Toshiba_AF_NVM_Read_NVM_Near2Far_mac_LSByte , + Toshiba_AF_NVM_Read_NVM_Near2Far_mac_MSByte , + Toshiba_AF_NVM_Read_NVM_Pos_A_LSByte , + Toshiba_AF_NVM_Read_NVM_Pos_A_MSByte , + Toshiba_AF_NVM_Read_NVM_Pos_B_LSByte , + Toshiba_AF_NVM_Read_NVM_Pos_B_MSByte , + + //"Toshiba_Vcm_Parameters//" , + + Toshiba_Vcm_Parameters_wLowLevelMacroPos_LSByte , + Toshiba_Vcm_Parameters_wLowLevelMacroPos_MSByte , + Toshiba_Vcm_Parameters_wLowLevelInfinityPos_LSByte , + Toshiba_Vcm_Parameters_wLowLevelInfinityPos_MSByte , + Toshiba_Vcm_Parameters_bSlewControlModeEnable , + Toshiba_Vcm_Parameters_bSlewModeForSmallerStep , + Toshiba_Vcm_Parameters_bSlewRateForSmallerStep, + Toshiba_Vcm_Parameters_bSlewModeForLargerStep , + Toshiba_Vcm_Parameters_bSlewRateForLargerStep , + Toshiba_Vcm_Parameters_bThresholdStepSize , + + //"Toshiba_Vcm_Status//" , + + Toshiba_Vcm_Status_wLowLevelPos_LSByte , + Toshiba_Vcm_Status_wLowLevelPos_MSByte , + + //"AdaptiveColourMatrix//" , + + AdaptiveColourMatrix_fpNormalisedRedGain0_LSByte , + AdaptiveColourMatrix_fpNormalisedRedGain0_MSByte , + AdaptiveColourMatrix_fpNormalisedRedGain1_LSByte , + AdaptiveColourMatrix_fpNormalisedRedGain1_MSByte , + AdaptiveColourMatrix_bChooseAdaptiveColourMatrix , + + //"ColourEngine1_ColourMatrixFarSensor//" , + + ColourEngine1_ColourMatrixFarSensor_fpRInR_LSByte , + ColourEngine1_ColourMatrixFarSensor_fpRInR_MSByte , + ColourEngine1_ColourMatrixFarSensor_fpGInR_LSByte , + ColourEngine1_ColourMatrixFarSensor_fpGInR_MSByte , + ColourEngine1_ColourMatrixFarSensor_fpBInR_LSByte , + ColourEngine1_ColourMatrixFarSensor_fpBInR_MSByte , + ColourEngine1_ColourMatrixFarSensor_fpRInG_LSByte , + ColourEngine1_ColourMatrixFarSensor_fpRInG_MSByte , + ColourEngine1_ColourMatrixFarSensor_fpGInG_LSByte , + ColourEngine1_ColourMatrixFarSensor_fpGInG_MSByte , + ColourEngine1_ColourMatrixFarSensor_fpBInG_LSByte , + ColourEngine1_ColourMatrixFarSensor_fpBInG_MSByte, + ColourEngine1_ColourMatrixFarSensor_fpRInB_LSByte , + ColourEngine1_ColourMatrixFarSensor_fpRInB_MSByte , + ColourEngine1_ColourMatrixFarSensor_fpGInB_LSByte , + ColourEngine1_ColourMatrixFarSensor_fpGInB_MSByte , + ColourEngine1_ColourMatrixFarSensor_fpBInB_LSByte , + ColourEngine1_ColourMatrixFarSensor_fpBInB_MSByte , + + //"ColourEngine1_ColourMatrixNearSensor//" , + + ColourEngine1_ColourMatrixNearSensor_fpRInR_LSByte , + ColourEngine1_ColourMatrixNearSensor_fpRInR_MSByte , + ColourEngine1_ColourMatrixNearSensor_fpGInR_LSByte , + ColourEngine1_ColourMatrixNearSensor_fpGInR_MSByte , + ColourEngine1_ColourMatrixNearSensor_fpBInR_LSByte , + ColourEngine1_ColourMatrixNearSensor_fpBInR_MSByte , + ColourEngine1_ColourMatrixNearSensor_fpRInG_LSByte , + ColourEngine1_ColourMatrixNearSensor_fpRInG_MSByte , + ColourEngine1_ColourMatrixNearSensor_fpGInG_LSByte , + ColourEngine1_ColourMatrixNearSensor_fpGInG_MSByte , + ColourEngine1_ColourMatrixNearSensor_fpBInG_LSByte , + ColourEngine1_ColourMatrixNearSensor_fpBInG_MSByte , + ColourEngine1_ColourMatrixNearSensor_fpRInB_LSByte , + ColourEngine1_ColourMatrixNearSensor_fpRInB_MSByte , + ColourEngine1_ColourMatrixNearSensor_fpGInB_LSByte , + ColourEngine1_ColourMatrixNearSensor_fpGInB_MSByte , + ColourEngine1_ColourMatrixNearSensor_fpBInB_LSByte , + ColourEngine1_ColourMatrixNearSensor_fpBInB_MSByte , + + //"WhiteBalanceGainLimit//" , + + WhiteBalanceGainLimit_fpWhiteBalanceGainLimit_LSByte, + WhiteBalanceGainLimit_fpWhiteBalanceGainLimit_MSByte , + + //"ToshibaTechnicalParamTuner//" , + + ToshibaTechnicalParamTuner_uwHostLevelMacroPos_LSByte , + ToshibaTechnicalParamTuner_uwHostLevelMacroPos_MSByte , + ToshibaTechnicalParamTuner_uwHostLevelInfinityPos_LSByte , + ToshibaTechnicalParamTuner_uwHostLevelInfinityPos_MSByte , + ToshibaTechnicalParamTuner_uwDefAFMaxStandardRange_um_LSByte , + ToshibaTechnicalParamTuner_uwDefAFMaxStandardRange_um_MSByte , + ToshibaTechnicalParamTuner_bDefFineStepParam_um , + ToshibaTechnicalParamTuner_bDefCoarseStepParam_um , + ToshibaTechnicalParamTuner_fHostDefTechParam , + + + IRPLastPreviewWOI_X_Byte0 , + IRPLastPreviewWOI_X_Byte1 , + IRPLastPreviewWOI_X_Byte2 , + IRPLastPreviewWOI_X_Byte3 , + ModeSetupBank2_bActiveSensor , + ModeSetupBank3_bActiveSensor + }vpip_reg_name; + +typedef enum { + +USER_MODE_AWB_AUTO=0, +USER_MODE_AWB_DAYLIGHT, +USER_MODE_AWB_CLOUDY, +USER_MODE_AWB_TUNGSTEN, +USER_MODE_AWB_MODE_FLUORESCENT, + +USER_MODE_EC_NORMAL, +USER_MODE_EC_Plus03, +USER_MODE_EC_Plus06, +USER_MODE_EC_Plus10, +USER_MODE_EC_Plus13, +USER_MODE_EC_Plus16, +USER_MODE_EC_Plus20, +USER_MODE_EC_Minus03, +USER_MODE_EC_Minus06, +USER_MODE_EC_Minus10, +USER_MODE_EC_Minus13, +USER_MODE_EC_Minus16, +USER_MODE_EC_Minus20, + +USER_MODE_ISO_AUTO, +USER_MODE_ISO_050, +USER_MODE_ISO_100, +USER_MODE_ISO_200, +USER_MODE_ISO_400, +USER_MODE_ISO_800, + +USER_MODE_COLORTONE_NORMAL, +USER_MODE_COLORTONE_SEPIA , +USER_MODE_COLORTONE_GRAYSCALE, +USER_MODE_COLORTONE_VIVID , +USER_MODE_COLORTONE_NEGATIVE, + +USER_MODE_CONTRAST_NORMAL, +USER_MODE_CONTRAST_110, +USER_MODE_CONTRAST_120, +USER_MODE_CONTRAST_130, +USER_MODE_CONTRAST_140, +USER_MODE_CONTRAST_150, +USER_MODE_CONTRAST_160, +USER_MODE_CONTRAST_170, +USER_MODE_CONTRAST_180, +USER_MODE_CONTRAST_190, +USER_MODE_CONTRAST_200, + +USER_MODE_SHARPNESS_NORMAL, +USER_MODE_SHARPNESS_HARD, +USER_MODE_SHARPNESS_SOFT, +USER_MODE_SHARPNESS_NONE, + +USER_MODE_EXPOSURE_AUTO, +USER_MODE_EXPOSURE_NIGHT, +USER_MODE_EXPOSURE_CENTER, +USER_MODE_EXPOSURE_BACKLIGHT, +USER_MODE_EXPOSURE_SPORT + +}vpip_user_mode; + +typedef enum { +SCENE_MODE_AUTO=0, +SCENE_MODE_LANDSCAPE, +SCENE_MODE_NIGHT, +SCENE_MODE_PORTRAIT, +SCENE_MODE_SPORTS, +SCENE_MODE_CLOSEUP +}vpip_scene_mode; + +struct vpip_usermode_update{ +__u32 service_id; +vpip_user_mode user_mode; +}; + +struct vpip_autofocus_id{ +__u32 service_id; +int value; +}; + +struct message_data { + enum sva_message_type type; + struct sva_buffer buffer; +}; + +struct sva_message { + enum block_type block; + __u32 timeout; + __u32 service_id; + __u32 msg_count; + struct message_data *messages; +}; + +struct sva_codec_bitstream_data { +__u32 service_id; +__u32 data_type; +__u8 *buffer; +__u32 length; +}; + +struct sva_service_time { +__u32 service_id; +__u32 time; +}; +struct vpip_params{ +unsigned char register_name[50]; +__u16 addr; +__u16 val; +}; + +struct nomadik_vpip_param { +vpip_reg_name vpip_config_reg; +__u16 addr; +__u16 val; +__u32 index; +}; + + +#define SVA_CREATE_SERVICE _IOWR('S', 1, struct sva_service_struct) +#define SVA_CONTROL_SERVICE _IOWR('S', 2, struct sva_control_service) +#define SVA_UPDATE_SERVICE _IOWR('S', 3, struct sva_update_service) +#define SVA_ALLOCATE_BUFFER _IOWR('S', 4, struct sva_buffer) +#define SVA_DEALLOCATE_BUFFER _IOWR('S', 5, unsigned long) +#define SVA_QUEUE_BUFFER _IOWR('S', 6, struct sva_queue_buffer) +#define SVA_DEQUEUE_BUFFER _IOWR('S', 7, struct sva_queue_buffer) +#define SVA_DELETE_SERVICE _IOWR('S', 8, struct sva_service_struct) +#define SVA_GET_MESSAGES _IOWR('S', 9, struct sva_message) +#define SVA_SET_HEADER _IOW('S', 10, struct sva_codec_header_infos) +#define SVA_FLUSH_SERVICE _IOR('S', 11, struct sva_service_struct) +#define SVA_GET_BITSTREAM_DATA _IOR('S', 12, struct sva_codec_bitstream_data) +#define SVA_SET_SERVICE_TIME _IOW('S', 13, struct sva_service_time) +#define SVA_GET_SERVICE_TIME _IOR('S', 14, struct sva_service_time) +#define SVA_END_BITSTREAM _IOWR('S', 15, struct sva_service_struct) +#define SVA_COPY_VPIP_PARAMS _IOWR('S', 16, struct nomadik_vpip_param) + + + +#endif /* __SVA_SERVICES_H__*/ --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_utils.c @@ -0,0 +1,964 @@ +/*--------------------------------------------------------------------------------------------------*/ +/*© copyright STMicroelectronics, 2007. */ +/* */ +/*This program is free software; you can redistribute it and/or modify it under */ +/*the terms of the GNU General Public License as published by the Free */ +/*Software Foundation; either version 2.1 of the License, or (at your option) */ +/*any later version. */ +/* */ +/*This program is distributed in the hope that it will be useful, but WITHOUT */ +/*ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU General Public License for more details. */ +/* */ +/*You should have received a copy of the GNU General Public License */ +/*along with this program. If not, see . */ +/*--------------------------------------------------------------------------------------------------*/ + + + + + + + +#include "nomadik_sva.h" +#include +#include + +extern int sva_debug; + +#define dbgprintk(num, format, args...) \ + do { \ + if(num >= sva_debug ) \ + printk("SVA:"format, ##args); \ + } while(0) + +extern struct sva_device sva; +/* + * Simple queue management + */ +static rwlock_t rw_lock_unlocked = RW_LOCK_UNLOCKED; + +void +sva_q_init(struct sva_queue *q) +{ + if (unlikely(q == NULL)) + return; + q->qlock = rw_lock_unlocked; + q->forw = (struct sva_q_node *)q; + q->back = (struct sva_q_node *)q; +} + +void +sva_q_add_head(struct sva_queue *q, struct sva_q_node *node) +{ + //unsigned long flags; + if (unlikely(q == NULL || node == NULL)) { + return; + } + if (unlikely(q->forw == NULL || q->back == NULL)) + sva_q_init(q); + write_lock_bh(&(q->qlock)); + node->forw = q->forw; + node->back = (struct sva_q_node *)q; + q->forw->back = node; + q->forw = node; + write_unlock_bh(&(q->qlock)); +} + +void +sva_q_add_tail(struct sva_queue *q, struct sva_q_node *node) +{ + //unsigned long flags; + if (unlikely(q == NULL || node == NULL)) { + return; + } + if (unlikely(q->forw == NULL || q->back == NULL)) + sva_q_init(q); + write_lock_bh(&(q->qlock)); + node->forw = (struct sva_q_node *)q; + node->back = q->back; + q->back->forw = node; + q->back = node; + write_unlock_bh(&(q->qlock)); +} + +void * +sva_q_del_head(struct sva_queue *q) +{ + //unsigned long flags; + struct sva_q_node *node; + if (unlikely(q == NULL)) { + return NULL; + } + + write_lock_bh(&(q->qlock)); + if (unlikely(q->forw == NULL || q->back == NULL || + q->forw == (struct sva_q_node *)q || + q->back == (struct sva_q_node *)q)) + { + write_unlock_bh(&(q->qlock)); + return NULL; + } + node = q->forw; + if(likely(node->forw != NULL)){ + node->forw->back = (struct sva_q_node *)q; + q->forw = node->forw; + } + else { + dbgprintk(3,"Queue:%d not expected null here !\n",__LINE__); + q->forw->forw = q; + write_unlock_bh(&(q->qlock)); + return NULL; + } + node->forw->back = (struct sva_q_node *)q; + q->forw = node->forw; + node->forw = NULL; + node->back = NULL; + write_unlock_bh(&(q->qlock)); + return node; +} + +void * +sva_q_del_tail(struct sva_queue *q) +{ + //unsigned long flags; + struct sva_q_node *node; + if (unlikely(q == NULL)) { + return NULL; + } + write_lock_bh(&(q->qlock)); + if (unlikely(q->forw == NULL || q->back == NULL || + q->forw == (struct sva_q_node *)q || + q->back == (struct sva_q_node *)q)) + { + write_unlock_bh(&(q->qlock)); + return NULL; + } + node = q->back; + node->back->forw = (struct sva_q_node *)q; + q->back = node->back; + node->forw = NULL; + node->back = NULL; + write_unlock_bh(&(q->qlock)); + return node; +} + +void * +sva_q_peek_head(struct sva_queue *q) +{ + //unsigned long flags; + struct sva_q_node *node; + if (unlikely(q == NULL || q->forw == NULL || q->forw == (struct sva_q_node *)q)) + { + return NULL; + } + read_lock_bh(&(q->qlock)); + node = q->forw; + if(unlikely(q->forw->forw == NULL)){ + dbgprintk(3,"Queue:%d not expected null here !\n",__LINE__); + q->forw->forw = q; + } + read_unlock_bh(&(q->qlock)); + return node; +} + +void * +sva_q_peek_tail(struct sva_queue *q) +{ + //unsigned long flags; + struct sva_q_node *node; + if (unlikely(q == NULL || q->back == NULL || q->back == (struct sva_q_node *)q)) + { + return NULL; + } + read_lock_bh(&(q->qlock)); + node = q->back; + read_unlock_bh(&(q->qlock)); + return node; +} + +void * +sva_q_yank_node(struct sva_queue *q, struct sva_q_node *node) +{ + //unsigned long flags; + struct sva_q_node *t; + + if (unlikely(q == NULL || q->back == NULL || q->back == (struct sva_q_node *)q)) { + return NULL; + } + + write_lock_bh(&(q->qlock)); + for (t = q->forw; t != (struct sva_q_node *)q; t = t->forw) + if (t == node) + { + node->back->forw = node->forw; + node->forw->back = node->back; + node->forw = NULL; + node->back = NULL; + write_unlock_bh(&(q->qlock)); + return node; + } + write_unlock_bh(&(q->qlock)); + return NULL; +} + +void * +sva_q_yank_bufferid(struct sva_queue *q, t_sva_buffer_id bufid) +{ + //unsigned long flags; + struct sva_q_node *t; + struct sva_q_node *node; + struct sva_buffer_info *tmpbuf; + + if (unlikely(q == NULL || q->forw == NULL || q->forw == (struct sva_q_node *)q)) { + return NULL; + } + + write_lock_bh(&(q->qlock)); + for (t = q->forw; (t != NULL && t != (struct sva_q_node *)q); t = t->forw) { + tmpbuf = (struct sva_buffer_info *)t; + if (tmpbuf->buffer_id == bufid) + { + node = &tmpbuf->qnode; + if(node->back == NULL || node->forw == NULL) + continue; + + if(node->back->forw == NULL || node->forw->back == NULL) + continue; + node->back->forw = node->forw; + node->forw->back = node->back; + node->forw = NULL; + node->back = NULL; + write_unlock_bh(&(q->qlock)); + return node; + } + } + write_unlock_bh(&(q->qlock)); + return NULL; +} + +void * +remove_buffer_push_type(struct sva_queue *q, enum push_type push) +{ + //unsigned long flags; + struct sva_q_node *t; + struct sva_buffer_info *buf_info=NULL; + + write_lock_bh(&(q->qlock)); + + if (unlikely(q == NULL || q->forw == NULL || q->forw == (struct sva_q_node *)q)) { + write_unlock_bh(&(q->qlock)); + return NULL; + } + + for (t = q->forw; t != (struct sva_q_node *)q; t = t->forw) { + buf_info = (struct sva_buffer_info *) t; + + if (buf_info->push == push) + { + t->back->forw = t->forw; + t->forw->back = t->back; + t->forw = NULL; + t->back = NULL; + write_unlock_bh(&(q->qlock)); + return t; + } + } + write_unlock_bh(&(q->qlock)); + return NULL; +} + +int +sva_q_last(struct sva_queue *q) +{ + //unsigned long flags; + if (q == NULL) + { + return -1; + } + read_lock_bh(&(q->qlock)); + if (q->forw == NULL || q->back == NULL || + q->forw == (struct sva_q_node *)q || + q->back == (struct sva_q_node *)q) + { + read_unlock_bh(&(q->qlock)); + return -1; + } + if (q->forw == q->back) + { + read_unlock_bh(&(q->qlock)); + return 1; + } + read_unlock_bh(&(q->qlock)); + return 0; +} + +/* Interrupt and tasklet management */ + +void manage_queue(struct sva_service_open *srv_open, t_sva_event_desc *event_ptr) +{ + t_sva_buffer_type buf_type; + struct sva_queue_data *qdata; + t_sva_event_desc event_desc; + t_sva_push_mode push; + struct sva_buffer_info *buf_info = NULL; + struct sva_buffer_info *tst_buf_info = NULL; + /*struct sva_device_open *open = NULL;*/ + /*int tmp = 0;*/ + + /*open = &sva.device_open[srv_open->index]; */ + event_desc = *event_ptr; + + sva_BM_GetBufferType(event_desc.bufferId,&buf_type); + + /*while(tmp < MAX_BUFFERS) { + if(open->buffer_info[tmp] && open->buffer_info[tmp]->buffer_id == event_desc.bufferId) + break; + tmp++; + } + + if(tmp == MAX_BUFFERS) { + dbgprintk(3,"error:manage_queue() buffer not found\n"); + goto out; + } + + buf_type = open->buffer_info[tmp]->buffer_type; + push = open->buffer_info[tmp]->push;*/ + + if(event_desc.eventId == SVA_EVENT_BUFFER_VOIDED) + push = SVA_PUSH_IN; + else + push = SVA_PUSH_OUT; + + switch(buf_type) { + + case SVA_IMAGE_BUFFER_TYPE: + { + dbgprintk(1," manage_queue -> IMAGE BUFFER TYPE\n"); + if(push == SVA_PUSH_IN) + qdata = srv_open->in_image_buf_q; + else + qdata = srv_open->out_image_buf_q; + break; + } + + case SVA_BITSTREAM_BUFFER_TYPE: + { + dbgprintk(1," manage_queue -> BITS BUFFER TYPE\n"); + if(push == SVA_PUSH_IN) + qdata = srv_open->in_coded_buf_q; + else + qdata = srv_open->out_coded_buf_q; + break; + } + + case SVA_INFOS_BUFFER_TYPE: + { + dbgprintk(1," manage_queue -> INFOS BUFFER TYPE\n"); + if(push == SVA_PUSH_IN) + qdata = srv_open->in_infos_buf_q; + else + qdata = srv_open->out_infos_buf_q; + break; + } + + case SVA_PARAMS_BUFFER_TYPE: + { + dbgprintk(1," manage_queue -> PARAMS BUFFER TYPE\n"); + if(push == SVA_PUSH_IN) + qdata = srv_open->in_params_buf_q; + else + qdata = srv_open->out_params_buf_q; + break; + } + + default: + dbgprintk(3,"error: Not supported buffer type\n"); + return ; + + } /* End switch */ + + if(!qdata) { + dbgprintk(3,"error:No qdata ptr, service id %lu\n", srv_open->service_id); + goto out; + } + + buf_info = (struct sva_buffer_info *)sva_q_yank_bufferid(&qdata->internal_q, event_desc.bufferId); + SVA_GetBufferData(event_desc.bufferId, (t_uint32 *)&tst_buf_info); + + if( (srv_open->type == SVA_STILL_IMAGE_DECODER) + && (tst_buf_info->buffer_type == SVA_IMAGE_BUFFER_TYPE) + && (srv_open->config.stillimagedecoder_info.configuration.no_slice_mode == FALSE )) + { + if(event_desc.eventId == SVA_EVENT_BUFFER_FILLED) + { + dbgprintk(1,"SLICEMODE DECODE:: Fully Filled........\n"); + tst_buf_info->buffer.read_only = 0; + tst_buf_info->buffer.flags &= ~BUF_FLAG_PARTLY_FILLED; + tst_buf_info->buffer.flags &= ~BUF_FLAG_QUEUED; + tst_buf_info->buffer.flags |= BUF_FLAG_DONE; + return; + } + else if( event_desc.eventId == SVA_EVENT_BUFFER_PARTLY_FILLED ) + { + dbgprintk(1,"DECODE:: Partly Filled.......\n"); + if(buf_info){ + dbgprintk(1,"DECODE:: Setting Readonly Flag .......\n"); + buf_info->buffer.read_only =1; + buf_info->buffer.size += event_desc.extraInfo; /*its No of Bytes written for partly decoded Image Buffer(slice mode)*/ + buf_info->buffer.flags |= BUF_FLAG_PARTLY_FILLED; + } + else + { + dbgprintk(1,"DECODE:: buf_info is NULL.......\n"); + return; + } + + } + } + + + if(buf_info != tst_buf_info) { + printk("BUFFER ERROR SOmething wrong\n"); + } + if(!buf_info) { + dbgprintk(3,"error:Buffer not present, service id %lu\n", srv_open->service_id); + goto out; + } + buf_info->buffer.flags &= ~BUF_FLAG_QUEUED; + buf_info->buffer.flags |= BUF_FLAG_DONE; + + if(srv_open->type == SVA_STILL_IMAGE_ENCODER){ + if((event_desc.eventId == SVA_EVENT_BUFFER_PARTLY_FILLED) && (buf_info->buffer_type == SVA_BITSTREAM_BUFFER_TYPE)){ + buf_info->buffer.size = event_desc.extraInfo; /*slice mode: for each bitstream buffer generated*/ + buf_info->buffer.info2 = event_desc.extraInfo2; + } + else if(( event_desc.eventId == SVA_EVENT_BUFFER_FILLED ) && (buf_info->buffer_type == SVA_IMAGE_BUFFER_TYPE)) + buf_info->buffer.size = event_desc.extraInfo;/*Thumbnail Image size in bits*/ + else if(( event_desc.eventId == SVA_EVENT_BUFFER_FILLED ) && (buf_info->buffer_type == SVA_BITSTREAM_BUFFER_TYPE)){ + buf_info->buffer.size = event_desc.extraInfo; /*slice mode: for each bitstream buffer generated*/ + buf_info->buffer.info2 = event_desc.extraInfo2; + } + } + + if(event_desc.eventId == SVA_EVENT_BUFFER_FILLED){ + if((srv_open->type == SVA_VIDEO_ENCODER) && (buf_info->buffer_type == SVA_BITSTREAM_BUFFER_TYPE)) + buf_info->buffer.size = event_desc.extraInfo; + else if(srv_open->type == SVA_PREPROCESSOR) + buf_info->buffer.timestamp = event_desc.extraInfo; + } + + /*vc1 decoder */ + if(srv_open->type == SVA_VIDEO_DECODER && + (srv_open->config.videodecoder_info.configuration.transformId == SVA_DECODER_VC1_MP_LL + || srv_open->config.videodecoder_info.configuration.transformId == SVA_DECODER_H264 + || srv_open->config.videodecoder_info.configuration.transformId == SVA_DECODER_MPEG2_MP_ML) + && buf_info->buffer_type == SVA_IMAGE_BUFFER_TYPE) { + if(event_desc.eventId == SVA_EVENT_BUFFER_FILLED) { + buf_info->buffer.read_only =0; + } else if(event_desc.eventId == SVA_EVENT_BUFFER_FILLED_READ_ONLY) { + buf_info->buffer.read_only =1; + } + } + + + sva_q_add_tail(&qdata->output_q, &buf_info->qnode); + wake_up_interruptible(&qdata->output_wq); +out: + return; +} + +int +push_buffer(struct sva_service_open *srv, enum sva_buffer_type buf_type, enum push_type push); + +void update_readonly_queue(void *data) +{ + struct sva_readonly_work *work_d = ( struct sva_readonly_work *)data; + struct sva_q_node *t; + struct sva_queue *q; + struct sva_queue_data *qdata; + struct sva_buffer_info *buf_info = NULL; + struct sva_service_open *srv_open; + + if (unlikely(data == NULL )) + return; + + srv_open = work_d->srv_open; + + if (unlikely(srv_open->readonly_image_buf_q == NULL )) + return; + qdata = srv_open->readonly_image_buf_q; + + q = &qdata->input_q; + if (unlikely(sva_q_peek_head(q) == NULL )) { + wake_up_interruptible(&srv_open->readonly_image_buf_q->output_wq); + return; + } + + write_lock_bh(&(q->qlock)); + for (t = q->forw; t!=(struct sva_q_node *)q || t!=NULL; ) { + + /*if(t == (struct sva_q_node *)q) + break; */ + + buf_info = (struct sva_buffer_info *) t; + if ( buf_info->buffer_id == work_d->buffer_id) { + struct sva_q_node *pnode; + pnode = t->forw; + t->back->forw = t->forw; + t->forw->back = t->back; + t->forw = NULL; + t->back = NULL; + write_unlock_bh(&(q->qlock)); + buf_info->buffer.read_only = 0; + if((srv_open->state & SERVICE_STOPPED) == SERVICE_STOPPED) { + sva_q_add_tail(&srv_open->out_image_buf_q->output_q, t); + wake_up_interruptible(&srv_open->out_image_buf_q->output_wq); + } else { + sva_q_add_tail(&srv_open->out_image_buf_q->input_q, t); + push_buffer(srv_open, buf_info->buffer.type, buf_info->push); + } + write_lock_bh(&(q->qlock)); + dbgprintk(2,"Queue: after readonly update, queue is [%p<-->%p<-->%p]\n", q, q->forw, q->forw->forw); + break; + } else { + t = t->forw; + } + + } + write_unlock_bh(&(q->qlock)); + + if (unlikely(sva_q_peek_head(q) == NULL )) { + wake_up_interruptible(&srv_open->readonly_image_buf_q->output_wq); + } + return; +} + +static void update_readonly_buffer_status(struct sva_device_open *open, + struct sva_service_open *srv_open, t_sva_event_desc *event_ptr) +{ + t_sva_event_desc event_desc; + struct sva_readonly_work rd_work; + struct sva_buffer_info *buf_info = NULL; + /*int tmp = 0;*/ + + if(!open || !srv_open || !event_ptr) + return; + + event_desc = *event_ptr; + + /*while(tmp < MAX_BUFFERS) { + if(open->buffer_info[tmp] && open->buffer_info[tmp]->buffer_id == event_desc.bufferId) + break; + tmp++; + } + + if(tmp == MAX_BUFFERS) { + dbgprintk(3,"error:%s buffer not found\n",__FUNCTION__); + return; + } + + buf_info = (struct sva_buffer_info *)open->buffer_info[tmp];*/ + + SVA_GetBufferData(event_desc.bufferId, (t_uint32 *)&buf_info); + + buf_info->buffer.read_only = 0; + + rd_work.srv_open = srv_open; + rd_work.buffer_id = event_desc.bufferId; + + update_readonly_queue(&rd_work); + return; +} + +static void +add_message_queue(struct sva_service_open *srv, t_sva_event_desc *event_ptr) +{ + struct sva_device_open *open; + struct message_data message; + struct sva_message_data *msg = NULL; + /*int indx = 0;*/ + + message.buffer.buffer_id = -1; + switch(event_ptr->eventId) { + case SVA_EVENT_BUFFER_VOIDED: + { + message.type = BUFFER_VOIDED; + break; + } + + case SVA_EVENT_BUFFER_FILLED: + { + message.type = BUFFER_FILLED; + break; + + } + + case SVA_EVENT_UNDERFLOW: + { + message.type = EVENT_UNDERFLOW; + break; + + } + + case SVA_EVENT_OVERFLOW: + { + message.type = EVENT_OVERFLOW; + break; + + } + + case SVA_EVENT_BUFFER_FILLED_READ_ONLY: + { + message.type = BUFFER_FILLED_READ_ONLY; + break; + + } + case SVA_EVENT_BUFFER_PARTLY_FILLED: + { + message.type = BUFFER_FILLED_READ_ONLY; + break; + } + + default: + goto out; + } /* End switch */ + + open = &sva.device_open[srv->index]; + + msg = (struct sva_message_data *)sva_q_del_head(&srv->empty_message_queue); + + if(unlikely(msg == NULL)) { + dbgprintk(3,"error: No more free message nodes in\ + empty message queue, service id %lu\n", srv->service_id); + goto out; + } + + if(likely(event_ptr->bufferId != INVALID_BUFFER_ID)) { + /*while(indx < MAX_BUFFERS) { + if(open->buffer_info[indx] && (open->buffer_info[indx]->buffer_id + == event_ptr->bufferId)) + break; + + indx++; + } + + if(indx == MAX_BUFFERS) { + dbgprintk(3,"error: Buffer not found,\ + service id %lu\n", srv->service_id); + goto out; + } + + buf_info = open->buffer_info[indx];*/ + + dbgprintk(1," Add message for buffer %lu in SERVICE %lu \n", + event_ptr->bufferId,srv->service_id); + + msg->buffer_id = event_ptr->bufferId; + } + + msg->message = message; + sva_q_add_tail(&srv->filled_message_queue, &msg->qnode); +out: + return; +} + +void handle_device(struct sva_device_open * data) +{ + t_sva_error sva_error; + t_sva_event_desc event; + struct sva_service_open *srv_open; + __u8 srv_indx = 0; + + dbgprintk(1,"In handle device open index:%u\n",data->index); + + while(srv_indx < MAX_SERVICE_OPENS) { + + if(!data->service_open_data[srv_indx]) { + srv_indx++; + continue; + } + + srv_open = data->service_open_data[srv_indx]; + if (SVA_AreServicePendingEvents(srv_open->service_id) == 1) { + dbgprintk(1,"Processing SERVICE %lu... indx %d some events pending\n", + srv_open->service_id, srv_indx); + do { + sva_error = SVA_GetServicePendingEvents(srv_open->service_id, &event); + dbgprintk(1,"EVENT ID: %d,EVENT BUFID = %lu\n",event.eventId,event.bufferId); + + switch(event.eventId) { + + case SVA_EVENT_BUFFER_FILLED_READ_ONLY: + { + t_sva_buffer_type bufferType; + sva_BM_GetBufferType(event.bufferId,&bufferType); + if((srv_open->config.videodecoder_info.configuration.transformId == SVA_DECODER_VC1_MP_LL + || srv_open->config.videodecoder_info.configuration.transformId == SVA_DECODER_H264 + || srv_open->config.videodecoder_info.configuration.transformId == SVA_DECODER_MPEG2_MP_ML + || srv_open->config.videodecoder_info.configuration.transformId == SVA_DECODER_MPEG4_SP_L4A) + && bufferType == SVA_IMAGE_BUFFER_TYPE + && srv_open->type == SVA_VIDEO_DECODER){ + manage_queue(srv_open, &event); + add_message_queue(srv_open, &event); + + } + + dbgprintk(1,"SVA_EVENT_BUFFER_FILLED_READ_ONLY**************\n"); + + break; + } + case SVA_EVENT_BUFFER_PARTLY_FILLED: + { + t_sva_buffer_type bufferType; + sva_BM_GetBufferType(event.bufferId,&bufferType); + manage_queue(srv_open, &event); + add_message_queue(srv_open, &event); + + dbgprintk(1,"SVA_EVENT_BUFFER_PARTLY_FILLED**************\n"); + + break; + } + case SVA_EVENT_BUFFER_FILLED: + { + t_sva_buffer_type bufferType; + sva_BM_GetBufferType(event.bufferId,&bufferType); + if((srv_open->config.videodecoder_info.configuration.transformId == SVA_DECODER_VC1_MP_LL + || srv_open->config.videodecoder_info.configuration.transformId == SVA_DECODER_H264 + || srv_open->config.videodecoder_info.configuration.transformId == SVA_DECODER_MPEG2_MP_ML + || srv_open->config.videodecoder_info.configuration.transformId == SVA_DECODER_MPEG4_SP_L4A) + && bufferType == SVA_IMAGE_BUFFER_TYPE + && srv_open->type == SVA_VIDEO_DECODER){ + update_readonly_buffer_status(data, srv_open, &event); + + break; + } +#if 0 + if( (srv_open->config.stillimagedecoder_info.configuration.transformId == SVA_DECODER_SEQUENTIAL_JPEG) + &&(srv_open->config.stillimagedecoder_info.configuration.no_slice_mode == FALSE ) + && (bufferType == SVA_IMAGE_BUFFER_TYPE) && (srv_open->type == SVA_STILL_IMAGE_DECODER) ) + { + update_readonly_buffer_status(data, srv_open, &event); + break; + } +#endif + + manage_queue(srv_open, &event); + add_message_queue(srv_open, &event); + + dbgprintk(1,"SVA_EVENT_BUFFER_FILLED**************\n"); + + break; + } + case SVA_EVENT_BUFFER_VOIDED: /* Fall through as handling same for both */ + manage_queue(srv_open, &event); + add_message_queue(srv_open, &event); + + dbgprintk(1,"SVA_EVENT_BUFFER_VOIDED**************\n"); + + break; + + case SVA_EVENT_UNDERFLOW: + { + //add_message_queue(srv_open, &event); + + dbgprintk(1,"SVA_EVENT_UNDERFLOW**************\n"); + + break; + + } + case SVA_EVENT_OVERFLOW: + { + //add_message_queue(srv_open, &event); + + dbgprintk(1,"SVA_EVENT_OVERFLOW**************\n"); + + break; + } + + case SVA_EVENT_SERVICE_FLUSHED_IN: + { + srv_open->state |= SERVICE_FLUSHED_IN; + wake_up_interruptible(&srv_open->service_inactivate_wq); + + dbgprintk(1,"SVA_EVENT_SERVICE_FLUSHED_IN**************\n"); + + break; + } + + case SVA_EVENT_SERVICE_FLUSHED_OUT: + { + srv_open->state |= SERVICE_FLUSHED_OUT; + wake_up_interruptible(&srv_open->service_inactivate_wq); + + dbgprintk(1,"SVA_EVENT_SERVICE_FLUSHED_OUT**************\n"); + + break; + } + + case SVA_EVENT_SERVICE_STOPPED: + { + srv_open->state &= ~SERVICE_STARTED; + srv_open->state |= SERVICE_STOPPED; + wake_up_interruptible(&srv_open->service_stop_wq); + + dbgprintk(1,"SVA_EVENT_SERVICE_STOPPED**************\n"); + + break; + } + case SVA_EVENT_SERVICE_ACTIVATED: + { + srv_open->state &= ~SERVICE_INACTIVATED; + srv_open->state |= SERVICE_ACTIVATED; + wake_up_interruptible(&srv_open->service_activate_wq); + + dbgprintk(1,"SVA_EVENT_SERVICE_ACTIVATED**************\n"); + + break; + } + case SVA_EVENT_SERVICE_INACTIVATED: + { + srv_open->state &= ~SERVICE_ACTIVATED; + srv_open->state |= SERVICE_INACTIVATED; + wake_up_interruptible(&srv_open->service_inactivate_wq); + + dbgprintk(1,"SVA_EVENT_SERVICE_INACTIVATED**************\n"); + + break; + } + + case SVA_EVENT_PREPROCESSOR_LINE_SYNCHRO: + dbgprintk(1," grab SYNC interrupt received\n"); + + dbgprintk(1,"SVA_EVENT_PREPROCESSOR_LINE_SYNCHRO**************\n"); + + break; + case SVA_EVENT_SERVICE_ERROR: + { + t_sva_timestamp emptyTimeStamp={SVA_NO_TIMESTAMP,0}; +#if 0 + dbgprintk(3,"error:Service Error occured\n"); + dbgprintk(3,"error:eventDate %lu\n",event.eventDate); + dbgprintk(3,"error:eventTimestamp %lu\n",event.eventTimestamp); + dbgprintk(3,"error:serviceId %lu\n",event.serviceId); + dbgprintk(3,"error:bufferId %lu\n",event.bufferId); + dbgprintk(3,"error:extraInfo %lu\n",event.extraInfo); +#endif + dbgprintk(2,"Service error:extraInfo2 %lu\n",event.extraInfo2); + + /*reset service*/ + sva_error=SVA_ControlService(srv_open->service_id,SVA_SERVICE_RESET,0); + if (sva_error!=SVA_OK) { + dbgprintk(3,"error:Resetting service failed %d\n",sva_error); + break; + } + sva_error=SVA_ControlService(srv_open->service_id,SVA_SERVICE_START, + (t_uint32) &emptyTimeStamp); + if (sva_error!=SVA_OK) { + dbgprintk(3,"error:Restarting service after reset failed %d\n",sva_error); + break; + } + break; + } + case SVA_EVENT_POSTPROCESSOR_LINE_SYNCHRO: + case SVA_EVENT_POSTPROCESSOR_ALT_SYNCHRO: + break; + + /* vpip event handling */ + case SVA_EVENT_PACKET_READ: + srv_open->irp_pkt.readvalue = event.extraInfo; + srv_open->irp_pkt.rw_packet_finish = 1; + srv_open->irp_pkt.eventId = SVA_EVENT_PACKET_READ; + wake_up_interruptible(&srv_open->service_inactivate_wq); + break; + case SVA_EVENT_PACKET_WRITE: + srv_open->irp_pkt.rw_packet_finish = 1; + srv_open->irp_pkt.eventId = SVA_EVENT_PACKET_WRITE; + wake_up_interruptible(&srv_open->service_inactivate_wq); + break; + case SVA_EVENT_PACKET_ERROR: /* we can combine write & error together */ + dbgprintk(3,"sva: irp packet error event arrived %d\n",event.eventId); + srv_open->irp_pkt.rw_packet_finish = 1; + srv_open->irp_pkt.eventId = event.eventId; + wake_up_interruptible(&srv_open->service_inactivate_wq); + break; + + default: + { + dbgprintk(1, "==========DEFAULT CASE==============\n"); + break; + } + } + SVA_AcknowledgeEvent(&event); + + }while(sva_error == SVA_REMAINING_PENDING_EVENTS); + + dbgprintk(1,"Processing SERVICE %lu...Done!!!\n",srv_open->service_id); + } else { + dbgprintk(1," No events pending for SERVICE %lu\n",srv_open->service_id); + } + + srv_indx++; + + }/* while all services not scanned*/ + dbgprintk(1,"Returning from handle_device....\n"); +} + +#define MAX_INTERRUPTS 30 +__u8 writeIndex = 0; +__u8 readIndex = 0; +__u8 no_of_interrupts; +t_sva_irq_status sva_irq_status_array[MAX_INTERRUPTS]; + +DECLARE_TASKLET(sva_tasklet, nomadik_sva_tasklet, 0); +spinlock_t irq_lock = SPIN_LOCK_UNLOCKED; + + +irqreturn_t nomadik_sva_interrupt(int irq, void *device) +{ + spin_lock(&irq_lock); + SVA_GetIRQSrcStatus((t_sva_irq_src)irq, &sva_irq_status_array[writeIndex]); + spin_unlock(&irq_lock); + writeIndex = ((writeIndex + 1)%MAX_INTERRUPTS); + no_of_interrupts++; + if(no_of_interrupts > (MAX_INTERRUPTS - 1)) + dbgprintk(3,"Error:Overflow in interrupt handler\n"); + tasklet_schedule(&sva_tasklet); + return IRQ_HANDLED; +} + +void nomadik_sva_tasklet(unsigned long tasklet_data) +{ + unsigned int i,count; + unsigned long flags; + t_sva_irq_status sva_irq_status; + t_sva_error sva_err; + + dbgprintk(1,"Enters nomadik_sva_tasklet\n"); + spin_lock_irqsave(&irq_lock, flags); + count = no_of_interrupts; + no_of_interrupts = 0; + spin_unlock_irqrestore(&irq_lock, flags); + + while(count--) { + spin_lock_irqsave(&irq_lock, flags); + sva_irq_status = sva_irq_status_array[readIndex]; + spin_unlock_irqrestore(&irq_lock, flags); + readIndex = ((readIndex + 1) % MAX_INTERRUPTS); + sva_err = SVA_ProcessIRQSrc(&sva_irq_status); + if(sva_err != SVA_NO_MORE_PENDING_EVENT){ + dbgprintk(3,"error: ProcessIrqSrc failed \n"); + return ; + } + + for(i=0;i < MAX_OPENS;i++) { + if(sva.device_open[i].is_open) + handle_device(&sva.device_open[i]); + } /* End for */ + + } /* End while */ + dbgprintk(1," Returns from nomadik_sva_tasklet\n"); +} + + --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_utils.h @@ -0,0 +1,49 @@ +/*--------------------------------------------------------------------------------------------------*/ +/*© copyright STMicroelectronics, 2007. */ +/* */ +/*This program is free software; you can redistribute it and/or modify it under */ +/*the terms of the GNU General Public License as published by the Free */ +/*Software Foundation; either version 2.1 of the License, or (at your option) */ +/*any later version. */ +/* */ +/*This program is distributed in the hope that it will be useful, but WITHOUT */ +/*ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU General Public License for more details. */ +/* */ +/*You should have received a copy of the GNU General Public License */ +/*along with this program. If not, see . */ +/*--------------------------------------------------------------------------------------------------*/ + + + + + + +#ifndef __SVA_UTILS_H__ +#define __SVA_UTILS_H__ + +/* Simple queue management */ + +struct sva_q_node +{ + struct sva_q_node *forw, *back; +}; + +struct sva_queue +{ + struct sva_q_node *forw, *back; + rwlock_t qlock; +}; + +extern void sva_q_init(struct sva_queue *q); +extern void sva_q_add_head(struct sva_queue *q, struct sva_q_node *node); +extern void sva_q_add_tail(struct sva_queue *q, struct sva_q_node *node); +extern void *sva_q_del_head(struct sva_queue *q); +extern void *sva_q_del_tail(struct sva_queue *q); +extern void *sva_q_peek_head(struct sva_queue *q); +extern void *sva_q_peek_tail(struct sva_queue *q); +extern void *sva_q_yank_node(struct sva_queue *q, struct sva_q_node *node); +extern int sva_q_last(struct sva_queue *q); + +#endif --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c @@ -0,0 +1,6984 @@ +/*--------------------------------------------------------------------------------------------------*/ +/*© copyright STMicroelectronics, 2007. */ +/* */ +/*This program is free software; you can redistribute it and/or modify it under */ +/*the terms of the GNU General Public License as published by the Free */ +/*Software Foundation; either version 2.1 of the License, or (at your option) */ +/*any later version. */ +/* */ +/*This program is distributed in the hope that it will be useful, but WITHOUT */ +/*ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU General Public License for more details. */ +/* */ +/*You should have received a copy of the GNU General Public License */ +/*along with this program. If not, see . */ +/*--------------------------------------------------------------------------------------------------*/ + + + + + + +/* Added 3MP sensor (815/850) settings & configuration. + * Dec, 2007 Vinayak Pane + */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "nomadik_sva_vpip.h" + +#define VPIP_DEFAULT_LOG_LEVEL 4 + +int vpip_debug = VPIP_DEFAULT_LOG_LEVEL; +module_param(vpip_debug, int, 0644); +MODULE_PARM_DESC(vpip_debug,"Debug level for VPIP messages"); + +#define dbgprintk(num, format, args...) \ + do { \ + if(num >= vpip_debug ) \ + printk("vpip: "format, ##args); \ + } while(0) + +#define IRP_ASSERT(function) \ + if(function != SVA_OK ){ \ + printk("SVA: %s has failed at %d\n", #function,__LINE__); \ + return -1; \ + } + +#define MAX_LINES 1000 +#define MAX_PARAM_IN_LINE 4 +#define MAX_CHAR_IN_PARAM 256 + +extern int vpip_irp_enable; +extern struct semaphore hcl_mutex; +extern struct tasklet_struct sva_tasklet; +extern struct sva_device sva; + +static int block_until_irppacket_finish(struct sva_service_open *srv_open, __u16 *readvalue); +static int irp_start_fw(struct sva_service_open *srv_open, unsigned long framerate); +static int irp_boot_ewarp(struct sva_service_open *srv_open); +int irp_stop_ewarp(struct sva_service_open *srv_open); +int irp_power_up(struct sva_service_open *srv_open); +int irp_power_down(struct sva_service_open *srv_open); + +int VPIP_VERSION=0; +EXPORT_SYMBOL(VPIP_VERSION); + + + + + +const struct WB_MODE_vpip user_mode_wb[]= +{ + + {//WB_AUTO + { 0x2280, 0x1 }, + { 0x3909, 0x3af2 }, + { 0x390d, 0x3acf }, + { 0x3911, 0x2e8e }, + { 0x3914, 0x1 }, + { 0x5581, 0x3887 }, + { 0x5585, 0x3c68 }, + { 0x5594, 0x0 }, + }, + + + {//WB_DAYLIGHT + { 0x2280, 0x1 }, + { 0x3909, 0x3ae9 }, + { 0x390d, 0x3ad9 }, + { 0x3911, 0x2e8e }, + { 0x3914, 0x1 }, + { 0x5781, 0x3ac1 }, + { 0x5785, 0x3b0a }, + { 0x5794, 0x1 }, + + }, + + {//WB_CLOUDY + { 0x2280, 0x1 }, + { 0x3909, 0x3ab6 }, + { 0x390d, 0x3b16 }, + { 0x3911, 0x2e8e }, + { 0x3914, 0x1 }, + { 0x5781, 0x3a83 }, + { 0x5785, 0x3b52 }, + { 0x5794, 0x1 }, + }, + + {//WB_TUNGSTEN + { 0x2280, 0x1 }, + { 0x3909, 0x39aa }, + { 0x390d, 0x3c10 }, + { 0x3911, 0x2e8e }, + { 0x3914, 0x1 }, + { 0x5781, 0x38c9 }, + { 0x5785, 0x3c53 }, + { 0x5594, 0x0 }, + }, + + {//WB_FLUORESCENT + { 0x2280, 0x1 }, + { 0x3909, 0x3a79 }, + { 0x390d, 0x3b5e }, + { 0x3911, 0x2e8e }, + { 0x3914, 0x1 }, + { 0x5781, 0x39e7 }, + { 0x5785, 0x3bfc }, + { 0x5794, 0x1 } + } + + }; + + +const struct EC_MODE_vpip user_mode_ec[]= +{ //EC_NORMAL + { + { 0x1d90, 0xff }, + }, + + {//Plus03 + { 0x1d90, 0x1 }, + }, + {//Plus06 + { 0x1d90, 0x3 }, + }, + {//Plus10 + { 0x1d90, 0x5 }, + }, + {//Plus13 + { 0x1d90, 0x7 }, + }, + {//Plus16 + { 0x1d90, 0x9 }, + }, + {//Plus20 + { 0x1d90, 0xb }, + }, + + {//Minus03 + { 0x1d90, 0xfd }, + }, + + {//Minus06 + { 0x1d90, 0xfb }, + }, + + {//Minus10 + { 0x1d90, 0xf9 }, + }, + + {//Minus13 + { 0x1d90, 0xf7 }, + }, + + {//Minus16 + { 0x1d90, 0xf5 }, + }, + + {//Minus20 + { 0x1d90, 0xf3 }, + } +}; + + +const struct ISO_MODE_vpip user_mode_iso[]= +{ + { //ISO_AUTO + { 0x1519, 0x80 }, + { 0x1515, 0x20 }, + { 0x2099, 0x3e00 }, + { 0x209d, 0x4080 }, + }, + //ISO_050 + { + { 0x1519, 0x26 }, + { 0x1515, 0x26 }, + { 0x2099, 0x3e00 }, + { 0x209d, 0x3e80 }, + }, + + {//ISO_100 + { 0x1519, 0x49 }, + { 0x1515, 0x49 }, + { 0x2099, 0x3e00 }, + { 0x209d, 0x3e80 }, + }, + + {//ISO_200 + { 0x1519, 0x91 }, + { 0x1515, 0x91 }, + { 0x2099, 0x3e00 }, + { 0x209d, 0x3e80 }, + }, + + + {//ISO_400 + { 0x1519, 0xff }, + { 0x1515, 0xff }, + { 0x2099, 0x3e45 }, + { 0x209d, 0x3ed6 }, + }, + + {//ISO_800 + { 0x1519, 0xff }, + { 0x1515, 0xff }, + { 0x2099, 0x4051 }, + { 0x209d, 0x4e06 } + } + +}; + +//Color tones default values : +/* +{ 0x2e04, 0x13 }, +{ 0x2e06, 0x13 }, +{ 0x2e08, 0x13 }, +{ 0x2e0a, 0x13 }, +{ 0x2e0c, 0x13 }, +{ 0x2e0e, 0x13 }, +{ 0x2b01, 0x3fd3 }, +{ 0x2b05, 0xbce0 }, +{ 0x2b09, 0xb919 }, +{ 0x2b0d, 0xba76 }, +{ 0x2b11, 0x3f7a }, +{ 0x2b15, 0xbb71 }, +{ 0x2b19, 0xb717 }, +{ 0x2b1d, 0xbd29 }, +{ 0x2b21, 0x3fc6 }, +{ 0x3484, 0x69 }, +{ 0x706, 0x0 }, +{ 0x5788, 0x1 }, +*/ + + +const struct COLORTONES_MODE_vpip user_mode_colortone[]= +{ + {//COLORTONES_NORMAL + { 0x2e04, 0x13 }, + { 0x2e06, 0x13 }, + { 0x2e08, 0x13 }, + { 0x2e0a, 0x13 }, + { 0x2e0c, 0x13 }, + { 0x2e0e, 0x13 }, + { 0x2b01, 0x3fd3 }, + { 0x2b05, 0xbce0 }, + { 0x2b09, 0xb919 }, + { 0x2b0d, 0xba76 }, + { 0x2b11, 0x3f7a }, + { 0x2b15, 0xbb71 }, + { 0x2b19, 0xb717 }, + { 0x2b1d, 0xbd29 }, + { 0x2b21, 0x3fc6 }, + { 0x3484, 0x64 }, + { 0x706, 0x0 }, + { 0x5788, 0x1 }, + }, + + + {//SEPIA + { 0x2e04, 0x19 }, + { 0x2e06, 0x10 }, + { 0x2e08, 0x5 }, + { 0x2e0a, 0x19 }, + { 0x2e0c, 0x10 }, + { 0x2e0e, 0x5 }, + { 0x2b01, 0x3aab }, + { 0x2b05, 0x3aab }, + { 0x2b09, 0x3aab }, + { 0x2b0d, 0x3aab }, + { 0x2b11, 0x3aab }, + { 0x2b15, 0x3aab }, + { 0x2b19, 0x3aab }, + { 0x2b1d, 0x3aab }, + { 0x2b21, 0x3aab }, +{ 0x3484, 0x69 }, +{ 0x706, 0x0 }, + { 0x5788, 0x0 }, + }, + + {//GRAYSCALE + { 0x2e04, 0x13 }, + { 0x2e06, 0x13 }, + { 0x2e08, 0x13 }, + { 0x2e0a, 0x13 }, + { 0x2e0c, 0x13 }, + { 0x2e0e, 0x13 }, + { 0x2b01, 0x3aab }, + { 0x2b05, 0x3aab }, + { 0x2b09, 0x3aab }, + { 0x2b0d, 0x3aab }, + { 0x2b11, 0x3aab }, + { 0x2b15, 0x3aab }, + { 0x2b19, 0x3aab }, + { 0x2b1d, 0x3aab }, + { 0x2b21, 0x3aab }, + { 0x3484, 0x0 }, +{ 0x706, 0x0 }, + { 0x5788, 0x0 }, + }, + + { //VIVID +{ 0x2e04, 0x13 }, +{ 0x2e06, 0x13 }, +{ 0x2e08, 0x13 }, +{ 0x2e0a, 0x13 }, +{ 0x2e0c, 0x13 }, +{ 0x2e0e, 0x13 }, +{ 0x2b01, 0x3fd3 }, +{ 0x2b05, 0xbce0 }, +{ 0x2b09, 0xb919 }, +{ 0x2b0d, 0xba76 }, +{ 0x2b11, 0x3f7a }, +{ 0x2b15, 0xbb71 }, +{ 0x2b19, 0xb717 }, +{ 0x2b1d, 0xbd29 }, +{ 0x2b21, 0x3fc6 }, + { 0x3484, 0x80 }, +{ 0x706, 0x0 }, + { 0x5788, 0x1 }, + }, + + {//NEGATIVE +{ 0x2e04, 0x13 }, +{ 0x2e06, 0x13 }, +{ 0x2e08, 0x13 }, +{ 0x2e0a, 0x13 }, +{ 0x2e0c, 0x13 }, +{ 0x2e0e, 0x13 }, +{ 0x2b01, 0x3fd3 }, +{ 0x2b05, 0xbce0 }, +{ 0x2b09, 0xb919 }, +{ 0x2b0d, 0xba76 }, +{ 0x2b11, 0x3f7a }, +{ 0x2b15, 0xbb71 }, +{ 0x2b19, 0xb717 }, +{ 0x2b1d, 0xbd29 }, +{ 0x2b21, 0x3fc6 }, +{ 0x3484, 0x69 }, + { 0x706, 0x1 }, + { 0x5788, 0x1 }, + }, + + +}; + +const struct CONTRAST_MODE_vpip user_mode_contrast[]= +{ + +{ //CONTRAST_NORMAL + { 0x3482, 0x64 }, +}, + +{//CONTRAST_110 + { 0x3482, 0x6e }, +}, +{//CONTRAST_120 + { 0x3482, 0x79 }, +}, +{//CONTRAST_130 + { 0x3482, 0x85 }, +}, +{//CONTRAST_140 + { 0x3482, 0x92 }, +}, +{//CONTRAST_150 + { 0x3482, 0xa1 }, +}, +{//CONTRAST_160 + { 0x3482, 0xb1 }, +}, +{//CONTRAST_170 + { 0x3482, 0xc3 }, +}, +{//CONTRAST_180 + { 0x3482, 0xd6 }, +}, +{//CONTRAST_190 + { 0x3482, 0xec }, +}, +{//CONTRAST_200 + { 0x3482, 0xff }, +}, +{//CONTRAST_090 + { 0x3482, 0x5a }, +}, +{//CONTRAST_080 + { 0x3482, 0x51 }, +}, +{//CONTRAST_070 + { 0x3482, 0x49 }, +}, +{//CONTRAST_060 + { 0x3482, 0x42 }, +}, +{//CONTRAST_050 + { 0x3482, 0x3b }, +}, +{//CONTRAST_040 + { 0x3482, 0x35 }, +}, +{//CONTRAST_030 + { 0x3482, 0x30 }, +}, +{//CONTRAST_020 + { 0x3482, 0x2b }, +}, +{//CONTRAST_010 + { 0x3482, 0x27 }, +}, +{//CONTRAST_000 + { 0x3482, 0x23 }, +} +}; + + + +const struct SHARPNESS_MODE_vpip user_mode_sharpness[]= +{ + {//SHARPNESS_NORMAL + { 0x2d02, 0x10 }, + }, + {//HARD + { 0x2d02, 0x18 }, + }, + {//SOFT + { 0x2d02, 0x8 }, + }, + {//SHARPNESS_NONE + { 0x2d02, 0x0 }, + } +}; + + + + +const struct EXPOSURE_MODE_vpip user_mode_exposure[]= +{ + { //EXPOSURE_AUTO + { 0x1d82, 0x2 }, + { 0x2700, 0x1 }, + { 0x2702, 0x1 }, + { 0x2704, 0x1 }, + { 0x2706, 0x3 }, + { 0x2708, 0x2 }, + { 0x270a, 0xf }, + { 0x270c, 0x1e }, + }, + + { //NIGHT + { 0x1d82, 0x2 }, + { 0x2700, 0x1 }, + { 0x2702, 0x1 }, + { 0x2704, 0x1 }, + { 0x2706, 0x3 }, + { 0x2708, 0x2 }, + { 0x270a, 0x5 }, + { 0x270c, 0xf }, + }, + + { //CENTER + { 0x1d82, 0x2 }, + { 0x2700, 0x1 }, + { 0x2702, 0x1 }, + { 0x2704, 0x1 }, + { 0x2706, 0x3 }, + { 0x2708, 0x2 }, + { 0x270a, 0xf }, + { 0x270c, 0x1e }, + }, + + { //BACKLIGHT + { 0x1d82, 0x2 }, + { 0x2700, 0x1 }, + { 0x2702, 0x1 }, + { 0x2704, 0x1 }, + { 0x2706, 0x3 }, + { 0x2708, 0x2 }, + { 0x270a, 0xf }, + { 0x270c, 0x1e }, + }, + + { //SPORT + { 0x1d82, 0x2 }, + { 0x2700, 0x1 }, + { 0x2702, 0x1 }, + { 0x2704, 0x1 }, + { 0x2706, 0x3 }, + { 0x2708, 0x2 }, + { 0x270a, 0x1e }, + { 0x270c, 0x1e }, + } +}; + + +static int irp_write_packet(struct sva_service_open *srv_open, __u16 offset, __u16 writevalue); +static int irp_read_packet(struct sva_service_open *srv_open, __u16 offset, __u16 *readvalue); + + +int write_pages_wb(struct sva_device_open *open,struct vpip_usermode_update *mode) +{ + +int ret_val = 0; + +vpip_user_mode param=mode->user_mode; +struct sva_service_open *srv_open; + +srv_open = open->service_open_data[mode->service_id]; + +IRP_ASSERT(irp_write_packet(srv_open, + user_mode_wb[param].UM_WhiteBalanceControls_bMode.addr, + user_mode_wb[param].UM_WhiteBalanceControls_bMode.val)); + +IRP_ASSERT(irp_write_packet(srv_open, + user_mode_wb[param].UM_WhiteBalanceConstrainerControls_fpRedB_MSByte.addr, + user_mode_wb[param].UM_WhiteBalanceConstrainerControls_fpRedB_MSByte.val)); + +IRP_ASSERT(irp_write_packet(srv_open, + user_mode_wb[param].UM_WhiteBalanceConstrainerControls_fpBlueB_MSByte.addr, + user_mode_wb[param].UM_WhiteBalanceConstrainerControls_fpBlueB_MSByte.val)); + +IRP_ASSERT(irp_write_packet(srv_open, + user_mode_wb[param].UM_WhiteBalanceConstrainerControls_fpMaximumDistanceAllowedFromLocus_MSByte.addr, + user_mode_wb[param].UM_WhiteBalanceConstrainerControls_fpMaximumDistanceAllowedFromLocus_MSByte.val)); + +IRP_ASSERT(irp_write_packet(srv_open, + user_mode_wb[param].UM_WhiteBalanceConstrainerControls_fEnableConstrainedWhiteBalance.addr, + user_mode_wb[param].UM_WhiteBalanceConstrainerControls_fEnableConstrainedWhiteBalance.val)); + +IRP_ASSERT(irp_write_packet(srv_open, + user_mode_wb[param].UM_DynamicConstrainedWBControls_fpRedA_MSByte.addr, + user_mode_wb[param].UM_DynamicConstrainedWBControls_fpRedA_MSByte.val)); + +IRP_ASSERT(irp_write_packet(srv_open, + user_mode_wb[param].UM_DynamicConstrainedWBControls_fpBlueA_MSByte.addr, + user_mode_wb[param].UM_DynamicConstrainedWBControls_fpBlueA_MSByte.val)); + +IRP_ASSERT(irp_write_packet(srv_open, + user_mode_wb[param].UM_DynamicConstrainedWBControls_fDamperDisable.addr, + user_mode_wb[param].UM_DynamicConstrainedWBControls_fDamperDisable.val)); + +return ret_val; +} +EXPORT_SYMBOL(write_pages_wb); + + +int write_pages_ec(struct sva_device_open *open,struct vpip_usermode_update *mode) +{ + +int ret_val = 0; +vpip_user_mode param=mode->user_mode; +struct sva_service_open *srv_open; + +srv_open = open->service_open_data[mode->service_id]; + +IRP_ASSERT(irp_write_packet(srv_open, + user_mode_ec[param].UM_ExposureControls_iExposureCompensation.addr, + user_mode_ec[param].UM_ExposureControls_iExposureCompensation.val)); + +return ret_val; + +}EXPORT_SYMBOL(write_pages_ec); + + +int write_pages_iso(struct sva_device_open *open,struct vpip_usermode_update *mode) + +{ +int ret_val = 0; +vpip_user_mode param=mode->user_mode; +struct sva_service_open *srv_open; + +srv_open = open->service_open_data[mode->service_id]; +IRP_ASSERT(irp_write_packet(srv_open, + user_mode_iso[param].UM_SensorCapabilitiesFarSensor_uwSensorAnalogGainMaximum_MSByte.addr, + user_mode_iso[param].UM_SensorCapabilitiesFarSensor_uwSensorAnalogGainMaximum_MSByte.val)); + + +IRP_ASSERT(irp_write_packet(srv_open, + user_mode_iso[param].UM_SensorCapabilitiesFarSensor_uwSensorAnalogGainMinimum_MSByte.addr, + user_mode_iso[param].UM_SensorCapabilitiesFarSensor_uwSensorAnalogGainMinimum_MSByte.val)); + +IRP_ASSERT(irp_write_packet(srv_open, + user_mode_iso[param].UM_ExposureAlgorithmControls_fpDigitalGainFloor_MSByte.addr, + user_mode_iso[param].UM_ExposureAlgorithmControls_fpDigitalGainFloor_MSByte.val)); + +IRP_ASSERT(irp_write_packet(srv_open, + user_mode_iso[param].UM_ExposureAlgorithmControls_fpDigitalGainCeiling_MSByte.addr, + user_mode_iso[param].UM_ExposureAlgorithmControls_fpDigitalGainCeiling_MSByte.val)); + +return ret_val; + +}EXPORT_SYMBOL(write_pages_iso); + + +int write_pages_colortone(struct sva_device_open *open,struct vpip_usermode_update *mode) + +{ +int ret_val = 0; +vpip_user_mode param=mode->user_mode; +struct sva_service_open *srv_open; + +srv_open = open->service_open_data[mode->service_id]; + +IRP_ASSERT(irp_write_packet(srv_open, + user_mode_colortone[param].UM_ColourEngine0_GammaCorrection_SharpRed.addr, + user_mode_colortone[param].UM_ColourEngine0_GammaCorrection_SharpRed.val)); + +IRP_ASSERT(irp_write_packet(srv_open, + user_mode_colortone[param].UM_ColourEngine0_GammaCorrection_SharpGreen.addr, + user_mode_colortone[param].UM_ColourEngine0_GammaCorrection_SharpGreen.val)); + +IRP_ASSERT(irp_write_packet(srv_open, + user_mode_colortone[param].UM_ColourEngine0_GammaCorrection_SharpBlue.addr, + user_mode_colortone[param].UM_ColourEngine0_GammaCorrection_SharpBlue.val)); + +IRP_ASSERT(irp_write_packet(srv_open, + user_mode_colortone[param].UM_ColourEngine0_GammaCorrection_SoftRed.addr, + user_mode_colortone[param].UM_ColourEngine0_GammaCorrection_SoftRed.val)); + +IRP_ASSERT(irp_write_packet(srv_open, + user_mode_colortone[param].UM_ColourEngine0_GammaCorrection_SoftGreen.addr, + user_mode_colortone[param].UM_ColourEngine0_GammaCorrection_SoftGreen.val)); + +IRP_ASSERT(irp_write_packet(srv_open, + user_mode_colortone[param].UM_ColourEngine0_GammaCorrection_SoftBlue.addr, + user_mode_colortone[param].UM_ColourEngine0_GammaCorrection_SoftBlue.val)); + +IRP_ASSERT(irp_write_packet(srv_open, + user_mode_colortone[param].UM_ColourEngine0_ColourMatrixFarSensor_fpRInR_MSByte.addr, + user_mode_colortone[param].UM_ColourEngine0_ColourMatrixFarSensor_fpRInR_MSByte.val)); + +IRP_ASSERT(irp_write_packet(srv_open, + user_mode_colortone[param].UM_ColourEngine0_ColourMatrixFarSensor_fpGInR_MSByte.addr, + user_mode_colortone[param].UM_ColourEngine0_ColourMatrixFarSensor_fpGInR_MSByte.val)); + +IRP_ASSERT(irp_write_packet(srv_open, + user_mode_colortone[param].UM_ColourEngine0_ColourMatrixFarSensor_fpBInR_MSByte.addr, + user_mode_colortone[param].UM_ColourEngine0_ColourMatrixFarSensor_fpBInR_MSByte.val)); + +IRP_ASSERT(irp_write_packet(srv_open, + user_mode_colortone[param].UM_ColourEngine0_ColourMatrixFarSensor_fpRInG_MSByte.addr, + user_mode_colortone[param].UM_ColourEngine0_ColourMatrixFarSensor_fpRInG_MSByte.val)); + +IRP_ASSERT(irp_write_packet(srv_open, + user_mode_colortone[param].UM_ColourEngine0_ColourMatrixFarSensor_fpGInG_MSByte.addr, + user_mode_colortone[param].UM_ColourEngine0_ColourMatrixFarSensor_fpGInG_MSByte.val)); + + +IRP_ASSERT(irp_write_packet(srv_open, + user_mode_colortone[param].UM_ColourEngine0_ColourMatrixFarSensor_fpBInG_MSByte.addr, + user_mode_colortone[param].UM_ColourEngine0_ColourMatrixFarSensor_fpBInG_MSByte.val)); + +IRP_ASSERT(irp_write_packet(srv_open, + user_mode_colortone[param].UM_ColourEngine0_ColourMatrixFarSensor_fpRInB_MSByte.addr, + user_mode_colortone[param].UM_ColourEngine0_ColourMatrixFarSensor_fpRInB_MSByte.val)); + +IRP_ASSERT(irp_write_packet(srv_open, + user_mode_colortone[param].UM_ColourEngine0_ColourMatrixFarSensor_fpGInB_MSByte.addr, + user_mode_colortone[param].UM_ColourEngine0_ColourMatrixFarSensor_fpGInB_MSByte.val)); + +IRP_ASSERT(irp_write_packet(srv_open, + user_mode_colortone[param].UM_ColourEngine0_ColourMatrixFarSensor_fpBInB_MSByte.addr, + user_mode_colortone[param].UM_ColourEngine0_ColourMatrixFarSensor_fpBInB_MSByte.val)); + +IRP_ASSERT(irp_write_packet(srv_open, + user_mode_colortone[param].UM_ColourEngine0_OutputCoderControls_bColourSaturation.addr, + user_mode_colortone[param].UM_ColourEngine0_OutputCoderControls_bColourSaturation.val)); + +IRP_ASSERT(irp_write_packet(srv_open, + user_mode_colortone[param].UM_Pipe0Control_fSfxNegativeEnabled.addr, + user_mode_colortone[param].UM_Pipe0Control_fSfxNegativeEnabled.val)); + +IRP_ASSERT(irp_write_packet(srv_open, + user_mode_colortone[param].UM_AdaptiveColourMatrix_bChooseAdaptiveColourMatrix.addr, + user_mode_colortone[param].UM_AdaptiveColourMatrix_bChooseAdaptiveColourMatrix.val)); + +return ret_val; + +}EXPORT_SYMBOL(write_pages_colortone); + + +int write_pages_contrast(struct sva_device_open *open,struct vpip_usermode_update *mode) + +{ +int ret_val = 0; +vpip_user_mode param=mode->user_mode; +struct sva_service_open *srv_open; + +srv_open = open->service_open_data[mode->service_id]; +printk("\nuser mode value:%d \n",param); +printk("contrast address: %d\n",user_mode_contrast[param].UM_ColourEngine0_OutputCoderControls_bContrast.addr); +printk("contrast val: %d\n",user_mode_contrast[param].UM_ColourEngine0_OutputCoderControls_bContrast.val); +IRP_ASSERT(irp_write_packet(srv_open, + user_mode_contrast[param].UM_ColourEngine0_OutputCoderControls_bContrast.addr, + user_mode_contrast[param].UM_ColourEngine0_OutputCoderControls_bContrast.val)); +return ret_val; +}EXPORT_SYMBOL(write_pages_contrast); + + + +int write_pages_sharpness(struct sva_device_open *open,struct vpip_usermode_update *mode) + +{ +int ret_val = 0; +vpip_user_mode param=mode->user_mode; +struct sva_service_open *srv_open; + +srv_open = open->service_open_data[mode->service_id]; + +IRP_ASSERT(irp_write_packet(srv_open, + user_mode_sharpness[param].UM_ColourEngine0_ApertureCorrectionControls_bMaxGain.addr, + user_mode_sharpness[param].UM_ColourEngine0_ApertureCorrectionControls_bMaxGain.val)); + +return ret_val; +}EXPORT_SYMBOL(write_pages_sharpness); + +int write_pages_exposure(struct sva_device_open *open,struct vpip_usermode_update *mode) + +{ + +int ret_val = 0; +vpip_user_mode param=mode->user_mode; +struct sva_service_open *srv_open; + +srv_open = open->service_open_data[mode->service_id]; + +IRP_ASSERT(irp_write_packet(srv_open, + user_mode_exposure[param].UM_ExposureControls_bMetering.addr, + user_mode_exposure[param].UM_ExposureControls_bMetering.val)); + +IRP_ASSERT(irp_write_packet(srv_open, + user_mode_exposure[param].UM_AutomaticFrameRateControl_bMode.addr, + user_mode_exposure[param].UM_AutomaticFrameRateControl_bMode.val)); + +IRP_ASSERT(irp_write_packet(srv_open, + user_mode_exposure[param].UM_AutomaticFrameRateControl_bImpliedGainThresholdLow_num.addr, + user_mode_exposure[param].UM_AutomaticFrameRateControl_bImpliedGainThresholdLow_num.val)); + +IRP_ASSERT(irp_write_packet(srv_open, + user_mode_exposure[param].UM_AutomaticFrameRateControl_bImpliedGainThresholdLow_den.addr, + user_mode_exposure[param].UM_AutomaticFrameRateControl_bImpliedGainThresholdLow_den.val)); + +IRP_ASSERT(irp_write_packet(srv_open, + user_mode_exposure[param].UM_AutomaticFrameRateControl_bImpliedGainThresholdHigh_num.addr, + user_mode_exposure[param].UM_AutomaticFrameRateControl_bImpliedGainThresholdHigh_num.val)); + +IRP_ASSERT(irp_write_packet(srv_open, + user_mode_exposure[param].UM_AutomaticFrameRateControl_bImpliedGainThresholdHigh_den.addr, + user_mode_exposure[param].UM_AutomaticFrameRateControl_bImpliedGainThresholdHigh_den.val)); + +IRP_ASSERT(irp_write_packet(srv_open, + user_mode_exposure[param].UM_AutomaticFrameRateControl_bUserMinimumFrameRate_Hz.addr, + user_mode_exposure[param].UM_AutomaticFrameRateControl_bUserMinimumFrameRate_Hz.val)); + +IRP_ASSERT(irp_write_packet(srv_open, + user_mode_exposure[param].UM_AutomaticFrameRateControl_bUserMaximumFrameRate_Hz.addr, + user_mode_exposure[param].UM_AutomaticFrameRateControl_bUserMaximumFrameRate_Hz.val)); + +return ret_val; +}EXPORT_SYMBOL(write_pages_exposure); + + + + //unsigned char vpip_def_param[800][MAX_PARAM_IN_LINE][MAX_CHAR_IN_PARAM]= +struct nomadik_vpip_param vpip_default_params[2700]= +{ +{ DeviceParameters_uwDeviceId_LSByte , 0x0002, 0x0000 }, +{ DeviceParameters_uwDeviceId_MSByte , 0x0001, 0x0000 }, +{ DeviceParameters_bFirmwareVersionMajor , 0x0004, 0x0000 }, +{ DeviceParameters_bFirmwareVersionMinor , 0x0006, 0x0000 }, +{ DeviceParameters_bHardwareVersionMajor , 0x0008, 0x0000 }, +{ DeviceParameters_bHardwareVersionMinor , 0x000a, 0x0000 }, +{ ModeManagerControl_bUserCommand , 0x0080, 0x0000 }, +{ ModeManagerControl_fTestStateMachine , 0x0082, 0x0000 }, +{ ModeManagerControl_fForceTestState , 0x0084, 0x0000 }, +{ ModeManagerControl_bManualNextState , 0x0086, 0x0000 }, +{ ModeManagerControl_bTestCoin , 0x0088, 0x0000 }, +{ ModeManagerStatus_bThisLoLevelState , 0x0100, 0x0000 }, +{ ModeManagerStatus_bNextLoLevelState , 0x0102, 0x0000 }, +{ ModeManagerStatus_bHiLevelState , 0x0104, 0x0000 }, +{ ModeManagerStatus_bCycles , 0x0106, 0x0000 }, +{ ModeManagerStatus_fModeStaticSetupsChanged , 0x0108, 0x0000 }, +{ ModeManagerStatus_bTestCoin , 0x010a, 0x0000 }, +{ ModeManagerStatus_fCycleForTest , 0x010c, 0x0000 }, +{ ModeManagerStatus_bNumberOfFramesStreamed , 0x010e, 0x0000 }, +{ ModeManagerStatus_bPrevFrameCountForExposure , 0x0110, 0x0000 }, +{ RunModeControl_fMeteringOn , 0x0180, 0x0001 }, +{ RunModeControl_fExitOnStable , 0x0182, 0x0000 }, +{ RunModeControl_bStreamLength , 0x0184, 0x0000 }, +{ RunModeControl_fMeterBeforeStreaming , 0x0186, 0x0000 }, +{ RunModeControl_fChkForAF_Stability , 0x0188, 0x0000 }, +{ RunModeControl_fChkForExposure_Stability , 0x018a, 0x0000 }, +{ RunModeControl_fChkForWhiteBalance_Stability , 0x018c, 0x0000 }, +{ ModeSetupBankSelector_bRequiredModeSetupBank , 0x0200, 0x0000 }, +{ PipeSetupBankSelector_bRequiredPipe0SetupBank , 0x0280, 0x0000 }, +{ ModeSetupBank0_uwInputImageSize_X_LSByte , 0x0302, 0x0000 }, +{ ModeSetupBank0_uwInputImageSize_X_MSByte , 0x0301, 0x0648 }, +{ ModeSetupBank0_uwInputImageSize_Y_LSByte , 0x0306, 0x0000 }, +{ ModeSetupBank0_uwInputImageSize_Y_MSByte , 0x0305, 0x04b8 }, +{ ModeSetupBank0_uwMaxImageSize_X_LSByte , 0x030a, 0x0000 }, +{ ModeSetupBank0_uwMaxImageSize_X_MSByte , 0x0309, 0x0640 }, +{ ModeSetupBank0_uwMaxImageSize_Y_LSByte , 0x030e, 0x0000 }, +{ ModeSetupBank0_uwMaxImageSize_Y_MSByte , 0x030d, 0x04b0 }, +{ ModeSetupBank0_uwMinImageSize_X_LSByte , 0x0312, 0x0000 }, +{ ModeSetupBank0_uwMinImageSize_X_MSByte , 0x0311, 0x0058 }, +{ ModeSetupBank0_uwMinImageSize_Y_LSByte , 0x0316, 0x0000 }, +{ ModeSetupBank0_uwMinImageSize_Y_MSByte , 0x0315, 0x0048 }, +{ ModeSetupBank0_bActiveSensor , 0x0318, 0x0002 }, +{ ModeSetupBank0_fLowPowerStreaming , 0x031a, 0x0000 }, +{ ModeSetupBank0_bTestMode , 0x031c, 0x0000 }, +{ ModeSetupBank0_bNumberOfStatusLines , 0x031e, 0x0003 }, +{ ModeSetupBank0_bNumberOfDarkLines , 0x0320, 0x0002 }, +{ ModeSetupBank0_bNumberOfBlackLines , 0x0322, 0x0004 }, +{ ModeSetupBank0_uwNumberOfInterLinePixelClocks_LSByte , 0x0326, 0x0000 }, +{ ModeSetupBank0_uwNumberOfInterLinePixelClocks_MSByte , 0x0325, 0x0011 }, +{ ModeSetupBank0_uwNumberOfInterFrameLines_LSByte , 0x032a, 0x0000 }, +{ ModeSetupBank0_uwNumberOfInterFrameLines_MSByte , 0x0329, 0x0000 }, +{ ModeSetupBank0_bNumberOfDummyColumns , 0x032c, 0x0008 }, +{ ModeSetupBank0_bInputImageSource , 0x032e, 0x0000 }, +{ ModeSetupBank0_bOutputImageDestination , 0x0330, 0x0001 }, +{ PipeSetupBankA_uwPipeOutputSize_X_LSByte , 0x0382, 0x0000 }, +{ PipeSetupBankA_uwPipeOutputSize_X_MSByte , 0x0381, 0x0800 }, +{ PipeSetupBankA_uwPipeOutputSize_Y_LSByte , 0x0386, 0x0000 }, +{ PipeSetupBankA_uwPipeOutputSize_Y_MSByte , 0x0385, 0x0600 }, +{ PipeSetupBankA_bPipeOutputFormat , 0x0388, 0x0003 }, +{ PipeSetupBankA_bPipeStreamLength , 0x038a, 0x0000 }, +{ PipeSetupBankA_fTogglePixValid , 0x038c, 0x0000 }, +{ PipeSetupBankA_fEnableItuEmbeddedCodes , 0x038e, 0x0000 }, +{ PipeSetupBankA_bPixValidLineTypes , 0x0390, 0x0020 }, +{ PipeSetupBankA_fGenerateVSync , 0x0392, 0x1 }, +{ PipeSetupBankA_fCb_Cr_Flip , 0x0394, 0x0000 }, +{ PipeSetupBankA_fY_CbCr_Flip , 0x0396, 0x0000 }, +{ PipeSetupBankB_uwPipeOutputSize_X_LSByte , 0x0402, 0x0000 }, +{ PipeSetupBankB_uwPipeOutputSize_X_MSByte , 0x0401, 0x0000 }, +{ PipeSetupBankB_uwPipeOutputSize_Y_LSByte , 0x0406, 0x0000 }, +{ PipeSetupBankB_uwPipeOutputSize_Y_MSByte , 0x0405, 0x0000 }, +{ PipeSetupBankB_bPipeOutputFormat , 0x0408, 0x0000 }, +{ PipeSetupBankB_bPipeStreamLength , 0x040a, 0x0000 }, +{ PipeSetupBankB_fTogglePixValid , 0x040c, 0x0000 }, +{ PipeSetupBankB_fEnableItuEmbeddedCodes , 0x040e, 0x0000 }, +{ PipeSetupBankB_bPixValidLineTypes , 0x0410, 0x0000 }, +{ PipeSetupBankB_fGenerateVSync , 0x0412, 0x0000 }, +{ PipeSetupBankB_fCb_Cr_Flip , 0x0414, 0x0000 }, +{ PipeSetupBankB_fY_CbCr_Flip , 0x0416, 0x0000 }, +{ HostInterfaceManagerControl_bUserCommand , 0x0480, 0x0000 }, +{ HostInterfaceManagerControl_fTestStateMachine , 0x0482, 0x0000 }, +{ HostInterfaceManagerControl_fForceTestState , 0x0484, 0x0000 }, +{ HostInterfaceManagerControl_bManualNextState , 0x0486, 0x0000 }, +{ HostInterfaceManagerControl_bTestCoin , 0x0488, 0x0000 }, +{ HostInterfaceManagerControl_fAutoTransitionFromRxStopped , 0x048a, 0x0000 }, +{ HostInterfaceManagerControl_fStopSensor , 0x048c, 0x0001 }, +{ HostInterfaceManagerStatus_bThisLoLevelState , 0x0500, 0x0000 }, +{ HostInterfaceManagerStatus_bNextLoLevelState , 0x0502, 0x0000 }, +{ HostInterfaceManagerStatus_bHiLevelState , 0x0504, 0x0000 }, +{ HostInterfaceManagerStatus_bCycles , 0x0506, 0x0000 }, +{ HostInterfaceManagerStatus_bTestCoin , 0x0508, 0x0000 }, +{ HostInterfaceManagerStatus_fCycleForTest , 0x050a, 0x0000 }, +{ StreamManagerStatus_bStreamStatus , 0x0580, 0x0000 }, +{ StreamManagerStatus_fIsSensorRunning , 0x0582, 0x0000 }, +{ ClockManagerControl_fClockManagerInDebugState , 0x0600, 0x0000 }, +{ LocalPipe0SetupBank_uwPipeOutputSize_X_LSByte , 0x0682, 0x0000 }, +{ LocalPipe0SetupBank_uwPipeOutputSize_X_MSByte , 0x0681, 0x0000 }, +{ LocalPipe0SetupBank_uwPipeOutputSize_Y_LSByte , 0x0686, 0x0000 }, +{ LocalPipe0SetupBank_uwPipeOutputSize_Y_MSByte , 0x0685, 0x0000 }, +{ LocalPipe0SetupBank_bPipeOutputFormat , 0x0688, 0x0000 }, +{ LocalPipe0SetupBank_bPipeStreamLength , 0x068a, 0x0000 }, +{ LocalPipe0SetupBank_fTogglePixValid , 0x068c, 0x0000 }, +{ LocalPipe0SetupBank_fEnableItuEmbeddedCodes , 0x068e, 0x0000 }, +{ LocalPipe0SetupBank_bPixValidLineTypes , 0x0690, 0x0000 }, +{ LocalPipe0SetupBank_fGenerateVSync , 0x0692, 0x0000 }, +{ LocalPipe0SetupBank_fCb_Cr_Flip , 0x0694, 0x0000 }, +{ LocalPipe0SetupBank_fY_CbCr_Flip , 0x0696, 0x0000 }, +{ Pipe0Control_bPipeControl , 0x0700, 0x0000 }, +{ Pipe0Control_fPipeRefreshRequired , 0x0702, 0x0000 }, +{ Pipe0Control_fSfxSolariseEnabled , 0x0704, 0x0000 }, +{ Pipe0Control_fSfxNegativeEnabled , 0x0706, 0x0000 }, +{ Pipe0Control_ReplaceRedChannel , 0x0708, 0x0000 }, +{ Pipe0Control_ReplaceGreenChannel , 0x070a, 0x0001 }, +{ Pipe0Control_ReplaceBlueChannel , 0x070c, 0x0002 }, +{ Pipe0Control_fOverrideOFCropRegisters , 0x070e, 0x0000 }, +{ Pipe0Control_uwHCropRising_LSByte , 0x0712, 0x0000 }, +{ Pipe0Control_uwHCropRising_MSByte , 0x0711, 0x0000 }, +{ Pipe0Control_uwHCropFalling_LSByte , 0x0716, 0x0000 }, +{ Pipe0Control_uwHCropFalling_MSByte , 0x0715, 0x0000 }, +{ Pipe0Control_uwVCropRisingCrse_LSByte , 0x071a, 0x0000 }, +{ Pipe0Control_uwVCropRisingCrse_MSByte , 0x0719, 0x0000 }, +{ Pipe0Control_uwVCropFallingCrse_LSByte , 0x071e, 0x0000 }, +{ Pipe0Control_uwVCropFallingCrse_MSByte , 0x071d, 0x0000 }, +{ Pipe0Status_bPipeStatus , 0x0780, 0x0000 }, +{ Pipe0Status_fPipeEnablePending , 0x0782, 0x0000 }, +{ Pipe0Status_bNumberOfFramesStreamed , 0x0784, 0x0000 }, +{ Pipe0Status_fDitherEnabled , 0x0786, 0x0000 }, +{ Pipe0Status_fVidCompletePending , 0x0788, 0x0000 }, +{ HostToSensorAccessControl_bRequest , 0x0800, 0x0000 }, +{ HostToSensorAccessControl_bCommandCoin , 0x0802, 0x0000 }, +{ HostToSensorAccessControl_uwSensorIndex_LSByte , 0x0806, 0x0000 }, +{ HostToSensorAccessControl_uwSensorIndex_MSByte , 0x0805, 0x0000 }, +{ HostToSensorAccessStatus_bStatusCoin , 0x0880, 0x0000 }, +{ HostToSensorAccessStatus_bHostToSensorAccessErrorCount , 0x0882, 0x0000 }, +{ HostToSensorAccessData_uwDataLow_LSByte , 0x0902, 0x0000 }, +{ HostToSensorAccessData_uwDataLow_MSByte , 0x0901, 0x0000 }, +{ HostToSensorAccessData_uwDataHigh_LSByte , 0x0906, 0x0000 }, +{ HostToSensorAccessData_uwDataHigh_MSByte , 0x0905, 0x0000 }, +{ MasterI2cControl_bSensorSerialAddress , 0x0980, 0x0000 }, +{ MasterI2cControl_uwClk_Sensor_Comms_mhz_LSByte , 0x0984, 0x0000 }, +{ MasterI2cControl_uwClk_Sensor_Comms_mhz_MSByte , 0x0983, 0x0000 }, +{ MasterI2cControl_uwRequiredI2cSpeed_LSByte , 0x0988, 0x0000 }, +{ MasterI2cControl_uwRequiredI2cSpeed_MSByte , 0x0987, 0x0190 }, +{ MasterI2cControl_bMaximumNumberOfGrabAttempts , 0x098a, 0x0000 }, +{ MasterI2cStatus_bResourceStatus , 0x0a00, 0x0000 }, +{ MasterI2cStatus_uwI2CClkDiv_LSByte , 0x0a04, 0x0000 }, +{ MasterI2cStatus_uwI2CClkDiv_MSByte , 0x0a03, 0x0000 }, +{ MasterI2cStatus_fTransactionError , 0x0a06, 0x0000 }, +{ MasterI2cStatus_bNumberOfTransactionFailures , 0x0a08, 0x0000 }, +{ MasterI2cStatus_bNumberOfConsecutiveGrabFailures , 0x0a0a, 0x0000 }, +{ MasterI2cStatus_bNumberOfForcedReleases , 0x0a0c, 0x0000 }, +{ MasterI2cStatus_bNumberOfMcuClockDeratingAttemptsInhibited , 0x0a0e, 0x0000 }, +{ VideoTimingHostInputs_VideoTimingMode , 0x0a80, 0x0001 }, +{ VideoTimingHostInputs_bSensorBitsPerSystemClock , 0x0a82, 0x0002 }, +{ VideoTimingHostInputs_uwCsiRawFormat_LSByte , 0x0a86, 0x0000 }, +{ VideoTimingHostInputs_uwCsiRawFormat_MSByte , 0x0a85, 0x0808 }, +{ VideoTimingHostInputs_fpHostRxMaxDataRate_Mbps_LSByte , 0x0a8a, 0x0000 }, +{ VideoTimingHostInputs_fpHostRxMaxDataRate_Mbps_MSByte , 0x0a89, 0x508a }, +{ VideoTimingHostInputs_VsyncPolarity , 0x0a8c, 0x0000 }, +{ VideoTimingHostInputs_HsyncPolarity , 0x0a8e, 0x0000 }, +{ VideoTimingSensorFifoControl_bFiFoWaterMarkProgrammingMode , 0x0b00, 0x0000 }, +{ VideoTimingSensorFifoControl_uwFifoWaterMarkPixels_LSByte , 0x0b04, 0x0000 }, +{ VideoTimingSensorFifoControl_uwFifoWaterMarkPixels_MSByte , 0x0b03, 0x0000 }, +{ VideoTimingSensorFifoControl_uwFifoSizePixels_LSByte , 0x0b08, 0x0000 }, +{ VideoTimingSensorFifoControl_uwFifoSizePixels_MSByte , 0x0b07, 0x0000 }, +{ VideoTimingSensorScalingAndSubSamplingControl_fpOutputClockDeratingFraction_LSByte , 0x0b82, 0x0000 }, +{ VideoTimingSensorScalingAndSubSamplingControl_fpOutputClockDeratingFraction_MSByte , 0x0b81, 0x0000 }, +{ VideoTimingSensorScalingAndSubSamplingControl_bOutputClockDeratingRoundingMode , 0x0b84, 0x0000 }, +{ VideoTimingSensorScalingAndSubSamplingControl_fDerateVideoTimingClockForProfileZero , 0x0b86, 0x0000 }, +{ VideoTimingSensorConstraints_uwMinimumPrePllClockDiv_LSByte , 0x0c02, 0x0000 }, +{ VideoTimingSensorConstraints_uwMinimumPrePllClockDiv_MSByte , 0x0c01, 0x0000 }, +{ VideoTimingSensorConstraints_uwMaximumPrePllClockDiv_LSByte , 0x0c06, 0x0000 }, +{ VideoTimingSensorConstraints_uwMaximumPrePllClockDiv_MSByte , 0x0c05, 0x0000 }, +{ VideoTimingSensorConstraints_fpMinimumPllInputFrequency_Mhz_LSByte , 0x0c0a, 0x0000 }, +{ VideoTimingSensorConstraints_fpMinimumPllInputFrequency_Mhz_MSByte , 0x0c09, 0x0000 }, +{ VideoTimingSensorConstraints_uwMinimumPllMultiplier_LSByte , 0x0c0e, 0x0000 }, +{ VideoTimingSensorConstraints_uwMinimumPllMultiplier_MSByte , 0x0c0d, 0x0000 }, +{ VideoTimingSensorConstraints_uwMaximumPllMultiplier_LSByte , 0x0c12, 0x0000 }, +{ VideoTimingSensorConstraints_uwMaximumPllMultiplier_MSByte , 0x0c11, 0x0000 }, +{ VideoTimingSensorConstraints_fpMaximumPllOutputFrequency_Mhz_LSByte , 0x0c16, 0x0190 }, +{ VideoTimingSensorConstraints_fpMaximumPllOutputFrequency_Mhz_MSByte , 0x0c15, 0x0000 }, +{ VideoTimingSensorConstraints_uwMinimumVTSysClockDiv_LSByte , 0x0c1a, 0x0000 }, +{ VideoTimingSensorConstraints_uwMinimumVTSysClockDiv_MSByte , 0x0c19, 0x0000 }, +{ VideoTimingSensorConstraints_uwMaximumVTSysClockDiv_LSByte , 0x0c1e, 0x0000 }, +{ VideoTimingSensorConstraints_uwMaximumVTSysClockDiv_MSByte , 0x0c1d, 0x0000 }, +{ VideoTimingSensorConstraints_fpMaximumVTSystemClockFrequency_Mhz_LSByte , 0x0c22, 0x0000 }, +{ VideoTimingSensorConstraints_fpMaximumVTSystemClockFrequency_Mhz_MSByte , 0x0c21, 0x0000 }, +{ VideoTimingSensorConstraints_uwMinimumVTPixelClockDiv_LSByte , 0x0c26, 0x0000 }, +{ VideoTimingSensorConstraints_uwMinimumVTPixelClockDiv_MSByte , 0x0c25, 0x0000 }, +{ VideoTimingSensorConstraints_uwMaximumVTPixelClockDiv_LSByte , 0x0c2a, 0x0000 }, +{ VideoTimingSensorConstraints_uwMaximumVTPixelClockDiv_MSByte , 0x0c29, 0x0000 }, +{ VideoTimingSensorConstraints_fpMaximumVTPixelClockFrequency_Mhz_LSByte , 0x0c2e, 0x0000 }, +{ VideoTimingSensorConstraints_fpMaximumVTPixelClockFrequency_Mhz_MSByte , 0x0c2d, 0x0000 }, +{ VideoTimingSensorConstraints_uwMinimumOPSysClockDiv_LSByte , 0x0c32, 0x0000 }, +{ VideoTimingSensorConstraints_uwMinimumOPSysClockDiv_MSByte , 0x0c31, 0x0000 }, +{ VideoTimingSensorConstraints_uwMaximumOPSysClockDiv_LSByte , 0x0c36, 0x0000 }, +{ VideoTimingSensorConstraints_uwMaximumOPSysClockDiv_MSByte , 0x0c35, 0x0000 }, +{ VideoTimingSensorConstraints_fpMaximumOPSystemClockFrequency_Mhz_LSByte , 0x0c3a, 0x0000 }, +{ VideoTimingSensorConstraints_fpMaximumOPSystemClockFrequency_Mhz_MSByte , 0x0c39, 0x0000 }, +{ VideoTimingSensorConstraints_fpMaximumOPPixelClockFrequency_Mhz_LSByte , 0x0c3e, 0x0000 }, +{ VideoTimingSensorConstraints_fpMaximumOPPixelClockFrequency_Mhz_MSByte , 0x0c3d, 0x0000 }, +{ SensorScalingSubSamplingCapabilities_bSensorScalingMode , 0x0c80, 0x0000 }, +{ SensorScalingSubSamplingCapabilities_uwScalerMMin_LSByte , 0x0c84, 0x0000 }, +{ SensorScalingSubSamplingCapabilities_uwScalerMMin_MSByte , 0x0c83, 0x0000 }, +{ SensorScalingSubSamplingCapabilities_uwScalerMMax_LSByte , 0x0c88, 0x0000 }, +{ SensorScalingSubSamplingCapabilities_uwScalerMMax_MSByte , 0x0c87, 0x0000 }, +{ SensorScalingSubSamplingCapabilities_uwMaxOddInc_LSByte , 0x0c8c, 0x0000 }, +{ SensorScalingSubSamplingCapabilities_uwMaxOddInc_MSByte , 0x0c8b, 0x0000 }, +{ VideoTimingOutput_uwPrePllClockDiv_LSByte , 0x0d02, 0x0000 }, +{ VideoTimingOutput_uwPrePllClockDiv_MSByte , 0x0d01, 0x0000 }, +{ VideoTimingOutput_fpPllInputFrequency_Mhz_LSByte , 0x0d06, 0x0000 }, +{ VideoTimingOutput_fpPllInputFrequency_Mhz_MSByte , 0x0d05, 0x0000 }, +{ VideoTimingOutput_uwPllMultiplier_LSByte , 0x0d0a, 0x0000 }, +{ VideoTimingOutput_uwPllMultiplier_MSByte , 0x0d09, 0x0000 }, +{ VideoTimingOutput_fpPllOutputFrequency_Mhz_LSByte , 0x0d0e, 0x0000 }, +{ VideoTimingOutput_fpPllOutputFrequency_Mhz_MSByte , 0x0d0d, 0x0000 }, +{ VideoTimingOutput_uwVTSystemClockDiv_LSByte , 0x0d12, 0x0000 }, +{ VideoTimingOutput_uwVTSystemClockDiv_MSByte , 0x0d11, 0x0000 }, +{ VideoTimingOutput_fpVTSystemClockFrequency_Mhz_LSByte , 0x0d16, 0x0000 }, +{ VideoTimingOutput_fpVTSystemClockFrequency_Mhz_MSByte , 0x0d15, 0x0000 }, +{ VideoTimingOutput_uwVTPixelClockDiv_LSByte , 0x0d1a, 0x0000 }, +{ VideoTimingOutput_uwVTPixelClockDiv_MSByte , 0x0d19, 0x0000 }, +{ VideoTimingOutput_fpVTPixelClockFrequency_Mhz_LSByte , 0x0d1e, 0x0000 }, +{ VideoTimingOutput_fpVTPixelClockFrequency_Mhz_MSByte , 0x0d1d, 0x0000 }, +{ VideoTimingOutput_fpVTPixelClockPeriod_us_LSByte , 0x0d22, 0x0000 }, +{ VideoTimingOutput_fpVTPixelClockPeriod_us_MSByte , 0x0d21, 0x0000 }, +{ VideoTimingOutput_uwOPSystemClockDiv_LSByte , 0x0d26, 0x0000 }, +{ VideoTimingOutput_uwOPSystemClockDiv_MSByte , 0x0d25, 0x0000 }, +{ VideoTimingOutput_fpOPSystemClockFrequency_Mhz_LSByte , 0x0d2a, 0x0000 }, +{ VideoTimingOutput_fpOPSystemClockFrequency_Mhz_MSByte , 0x0d29, 0x0000 }, +{ VideoTimingOutput_uwOPPixelClockDiv_LSByte , 0x0d2e, 0x0000 }, +{ VideoTimingOutput_uwOPPixelClockDiv_MSByte , 0x0d2d, 0x0000 }, +{ VideoTimingOutput_fpOPPixelClockFrequency_Mhz_LSByte , 0x0d32, 0x0000 }, +{ VideoTimingOutput_fpOPPixelClockFrequency_Mhz_MSByte , 0x0d31, 0x0000 }, +{ VideoTimingOutput_fpOutputTimingClockDerating_LSByte , 0x0d36, 0x0000 }, +{ VideoTimingOutput_fpOutputTimingClockDerating_MSByte , 0x0d35, 0x0000 }, +{ DummyPage5_bDummyPageElement , 0x0d80, 0x0000 }, +{ VideoTimingInputsFarSensor_VideoTimingMode , 0x0e00, 0x0001 }, +{ VideoTimingInputsFarSensor_bSensorBitsPerSystemClock , 0x0e02, 0x0002 }, +{ VideoTimingInputsFarSensor_uwCsiRawFormat_LSByte , 0x0e06, 0x0000 }, +{ VideoTimingInputsFarSensor_uwCsiRawFormat_MSByte , 0x0e05, 0x0808 }, +{ VideoTimingInputsFarSensor_fpHostRxMaxDataRate_Mbps_LSByte , 0x0e0a, 0x0000 }, +{ VideoTimingInputsFarSensor_fpHostRxMaxDataRate_Mbps_MSByte , 0x0e09, 0x508a }, +{ VideoTimingInputsFarSensor_VsyncPolarity , 0x0e0c, 0x0000 }, +{ VideoTimingInputsFarSensor_HsyncPolarity , 0x0e0e, 0x0000 }, +{ SensorFarVideoTimingSensorFifoControl_bFiFoWaterMarkProgrammingMode , 0x0e80, 0x0000 }, +{ SensorFarVideoTimingSensorFifoControl_uwFifoWaterMarkPixels_LSByte , 0x0e84, 0x0000 }, +{ SensorFarVideoTimingSensorFifoControl_uwFifoWaterMarkPixels_MSByte , 0x0e83, 0x0000 }, +{ SensorFarVideoTimingSensorFifoControl_uwFifoSizePixels_LSByte , 0x0e88, 0x0000 }, +{ SensorFarVideoTimingSensorFifoControl_uwFifoSizePixels_MSByte , 0x0e87, 0x0000 }, +{ VideoTimingFarSensorConstraints_uwMinimumPrePllClockDiv_LSByte , 0x0f02, 0x0000 }, +{ VideoTimingFarSensorConstraints_uwMinimumPrePllClockDiv_MSByte , 0x0f01, 0x0000 }, +{ VideoTimingFarSensorConstraints_uwMaximumPrePllClockDiv_LSByte , 0x0f06, 0x0000 }, +{ VideoTimingFarSensorConstraints_uwMaximumPrePllClockDiv_MSByte , 0x0f05, 0x0000 }, +{ VideoTimingFarSensorConstraints_fpMinimumPllInputFrequency_Mhz_LSByte , 0x0f0a, 0x0000 }, +{ VideoTimingFarSensorConstraints_fpMinimumPllInputFrequency_Mhz_MSByte , 0x0f09, 0x0000 }, +{ VideoTimingFarSensorConstraints_uwMinimumPllMultiplier_LSByte , 0x0f0e, 0x0000 }, +{ VideoTimingFarSensorConstraints_uwMinimumPllMultiplier_MSByte , 0x0f0d, 0x0000 }, +{ VideoTimingFarSensorConstraints_uwMaximumPllMultiplier_LSByte , 0x0f12, 0x0000 }, +{ VideoTimingFarSensorConstraints_uwMaximumPllMultiplier_MSByte , 0x0f11, 0x0000 }, +{ VideoTimingFarSensorConstraints_fpMaximumPllOutputFrequency_Mhz_LSByte , 0x0f16, 0x0000 }, +{ VideoTimingFarSensorConstraints_fpMaximumPllOutputFrequency_Mhz_MSByte , 0x0f15, 0x0000 }, +{ VideoTimingFarSensorConstraints_uwMinimumVTSysClockDiv_LSByte , 0x0f1a, 0x0000 }, +{ VideoTimingFarSensorConstraints_uwMinimumVTSysClockDiv_MSByte , 0x0f19, 0x0000 }, +{ VideoTimingFarSensorConstraints_uwMaximumVTSysClockDiv_LSByte , 0x0f1e, 0x0000 }, +{ VideoTimingFarSensorConstraints_uwMaximumVTSysClockDiv_MSByte , 0x0f1d, 0x0000 }, +{ VideoTimingFarSensorConstraints_fpMaximumVTSystemClockFrequency_Mhz_LSByte , 0x0f22, 0x0000 }, +{ VideoTimingFarSensorConstraints_fpMaximumVTSystemClockFrequency_Mhz_MSByte , 0x0f21, 0x0000 }, +{ VideoTimingFarSensorConstraints_uwMinimumVTPixelClockDiv_LSByte , 0x0f26, 0x0000 }, +{ VideoTimingFarSensorConstraints_uwMinimumVTPixelClockDiv_MSByte , 0x0f25, 0x0000 }, +{ VideoTimingFarSensorConstraints_uwMaximumVTPixelClockDiv_LSByte , 0x0f2a, 0x0000 }, +{ VideoTimingFarSensorConstraints_uwMaximumVTPixelClockDiv_MSByte , 0x0f29, 0x0000 }, +{ VideoTimingFarSensorConstraints_fpMaximumVTPixelClockFrequency_Mhz_LSByte , 0x0f2e, 0x0000 }, +{ VideoTimingFarSensorConstraints_fpMaximumVTPixelClockFrequency_Mhz_MSByte , 0x0f2d, 0x0000 }, +{ VideoTimingFarSensorConstraints_uwMinimumOPSysClockDiv_LSByte , 0x0f32, 0x0000 }, +{ VideoTimingFarSensorConstraints_uwMinimumOPSysClockDiv_MSByte , 0x0f31, 0x0000 }, +{ VideoTimingFarSensorConstraints_uwMaximumOPSysClockDiv_LSByte , 0x0f36, 0x0000 }, +{ VideoTimingFarSensorConstraints_uwMaximumOPSysClockDiv_MSByte , 0x0f35, 0x0000 }, +{ VideoTimingFarSensorConstraints_fpMaximumOPSystemClockFrequency_Mhz_LSByte , 0x0f3a, 0x0000 }, +{ VideoTimingFarSensorConstraints_fpMaximumOPSystemClockFrequency_Mhz_MSByte , 0x0f39, 0x0000 }, +{ VideoTimingFarSensorConstraints_fpMaximumOPPixelClockFrequency_Mhz_LSByte , 0x0f3e, 0x0000 }, +{ VideoTimingFarSensorConstraints_fpMaximumOPPixelClockFrequency_Mhz_MSByte , 0x0f3d, 0x0000 }, +{ SensorFarScalingSubSamplingCapabilities_bSensorScalingMode , 0x0f80, 0x0000 }, +{ SensorFarScalingSubSamplingCapabilities_uwScalerMMin_LSByte , 0x0f84, 0x0000 }, +{ SensorFarScalingSubSamplingCapabilities_uwScalerMMin_MSByte , 0x0f83, 0x0000 }, +{ SensorFarScalingSubSamplingCapabilities_uwScalerMMax_LSByte , 0x0f88, 0x0000 }, +{ SensorFarScalingSubSamplingCapabilities_uwScalerMMax_MSByte , 0x0f87, 0x0000 }, +{ SensorFarScalingSubSamplingCapabilities_uwMaxOddInc_LSByte , 0x0f8c, 0x0000 }, +{ SensorFarScalingSubSamplingCapabilities_uwMaxOddInc_MSByte , 0x0f8b, 0x0000 }, +{ VideoTimingFarOutput_uwPrePllClockDiv_LSByte , 0x1002, 0x0000 }, +{ VideoTimingFarOutput_uwPrePllClockDiv_MSByte , 0x1001, 0x0000 }, +{ VideoTimingFarOutput_fpPllInputFrequency_Mhz_LSByte , 0x1006, 0x0000 }, +{ VideoTimingFarOutput_fpPllInputFrequency_Mhz_MSByte , 0x1005, 0x0000 }, +{ VideoTimingFarOutput_uwPllMultiplier_LSByte , 0x100a, 0x0000 }, +{ VideoTimingFarOutput_uwPllMultiplier_MSByte , 0x1009, 0x0000 }, +{ VideoTimingFarOutput_fpPllOutputFrequency_Mhz_LSByte , 0x100e, 0x0000 }, +{ VideoTimingFarOutput_fpPllOutputFrequency_Mhz_MSByte , 0x100d, 0x0000 }, +{ VideoTimingFarOutput_uwVTSystemClockDiv_LSByte , 0x1012, 0x0000 }, +{ VideoTimingFarOutput_uwVTSystemClockDiv_MSByte , 0x1011, 0x0000 }, +{ VideoTimingFarOutput_fpVTSystemClockFrequency_Mhz_LSByte , 0x1016, 0x0000 }, +{ VideoTimingFarOutput_fpVTSystemClockFrequency_Mhz_MSByte , 0x1015, 0x0000 }, +{ VideoTimingFarOutput_uwVTPixelClockDiv_LSByte , 0x101a, 0x0000 }, +{ VideoTimingFarOutput_uwVTPixelClockDiv_MSByte , 0x1019, 0x0000 }, +{ VideoTimingFarOutput_fpVTPixelClockFrequency_Mhz_LSByte , 0x101e, 0x0000 }, +{ VideoTimingFarOutput_fpVTPixelClockFrequency_Mhz_MSByte , 0x101d, 0x0000 }, +{ VideoTimingFarOutput_fpVTPixelClockPeriod_us_LSByte , 0x1022, 0x0000 }, +{ VideoTimingFarOutput_fpVTPixelClockPeriod_us_MSByte , 0x1021, 0x0000 }, +{ VideoTimingFarOutput_uwOPSystemClockDiv_LSByte , 0x1026, 0x0000 }, +{ VideoTimingFarOutput_uwOPSystemClockDiv_MSByte , 0x1025, 0x0000 }, +{ VideoTimingFarOutput_fpOPSystemClockFrequency_Mhz_LSByte , 0x102a, 0x0000 }, +{ VideoTimingFarOutput_fpOPSystemClockFrequency_Mhz_MSByte , 0x1029, 0x0000 }, +{ VideoTimingFarOutput_uwOPPixelClockDiv_LSByte , 0x102e, 0x0000 }, +{ VideoTimingFarOutput_uwOPPixelClockDiv_MSByte , 0x102d, 0x0000 }, +{ VideoTimingFarOutput_fpOPPixelClockFrequency_Mhz_LSByte , 0x1032, 0x0000 }, +{ VideoTimingFarOutput_fpOPPixelClockFrequency_Mhz_MSByte , 0x1031, 0x0000 }, +{ VideoTimingFarOutput_fpOutputTimingClockDerating_LSByte , 0x1036, 0x0000 }, +{ VideoTimingFarOutput_fpOutputTimingClockDerating_MSByte , 0x1035, 0x0000 }, +{ DummyPage6_bDummyPageElement , 0x1080, 0x0000 }, +{ VideoTimingInputsNearSensor_VideoTimingMode , 0x1100, 0x0001 }, +{ VideoTimingInputsNearSensor_bSensorBitsPerSystemClock , 0x1102, 0x0002 }, +{ VideoTimingInputsNearSensor_uwCsiRawFormat_LSByte , 0x1106, 0x0000 }, +{ VideoTimingInputsNearSensor_uwCsiRawFormat_MSByte , 0x1105, 0x0808 }, +{ VideoTimingInputsNearSensor_fpHostRxMaxDataRate_Mbps_LSByte , 0x110a, 0x0000 }, +{ VideoTimingInputsNearSensor_fpHostRxMaxDataRate_Mbps_MSByte , 0x1109, 0x508a }, +{ VideoTimingInputsNearSensor_VsyncPolarity , 0x110c, 0x0000 }, +{ VideoTimingInputsNearSensor_HsyncPolarity , 0x110e, 0x0000 }, +{ SensorNearVideoTimingSensorFifoControl_bFiFoWaterMarkProgrammingMode , 0x1180, 0x0000 }, +{ SensorNearVideoTimingSensorFifoControl_uwFifoWaterMarkPixels_LSByte , 0x1184, 0x0000 }, +{ SensorNearVideoTimingSensorFifoControl_uwFifoWaterMarkPixels_MSByte , 0x1183, 0x0000 }, +{ SensorNearVideoTimingSensorFifoControl_uwFifoSizePixels_LSByte , 0x1188, 0x0000 }, +{ SensorNearVideoTimingSensorFifoControl_uwFifoSizePixels_MSByte , 0x1187, 0x0000 }, +{ VideoTimingNearSensorConstraints_uwMinimumPrePllClockDiv_LSByte , 0x1202, 0x0000 }, +{ VideoTimingNearSensorConstraints_uwMinimumPrePllClockDiv_MSByte , 0x1201, 0x0000 }, +{ VideoTimingNearSensorConstraints_uwMaximumPrePllClockDiv_LSByte , 0x1206, 0x0000 }, +{ VideoTimingNearSensorConstraints_uwMaximumPrePllClockDiv_MSByte , 0x1205, 0x0000 }, +{ VideoTimingNearSensorConstraints_fpMinimumPllInputFrequency_Mhz_LSByte , 0x120a, 0x0000 }, +{ VideoTimingNearSensorConstraints_fpMinimumPllInputFrequency_Mhz_MSByte , 0x1209, 0x0000 }, +{ VideoTimingNearSensorConstraints_uwMinimumPllMultiplier_LSByte , 0x120e, 0x0000 }, +{ VideoTimingNearSensorConstraints_uwMinimumPllMultiplier_MSByte , 0x120d, 0x0000 }, +{ VideoTimingNearSensorConstraints_uwMaximumPllMultiplier_LSByte , 0x1212, 0x0000 }, +{ VideoTimingNearSensorConstraints_uwMaximumPllMultiplier_MSByte , 0x1211, 0x0000 }, +{ VideoTimingNearSensorConstraints_fpMaximumPllOutputFrequency_Mhz_LSByte , 0x1216, 0x0000 }, +{ VideoTimingNearSensorConstraints_fpMaximumPllOutputFrequency_Mhz_MSByte , 0x1215, 0x0000 }, +{ VideoTimingNearSensorConstraints_uwMinimumVTSysClockDiv_LSByte , 0x121a, 0x0000 }, +{ VideoTimingNearSensorConstraints_uwMinimumVTSysClockDiv_MSByte , 0x1219, 0x0000 }, +{ VideoTimingNearSensorConstraints_uwMaximumVTSysClockDiv_LSByte , 0x121e, 0x0000 }, +{ VideoTimingNearSensorConstraints_uwMaximumVTSysClockDiv_MSByte , 0x121d, 0x0000 }, +{ VideoTimingNearSensorConstraints_fpMaximumVTSystemClockFrequency_Mhz_LSByte , 0x1222, 0x0000 }, +{ VideoTimingNearSensorConstraints_fpMaximumVTSystemClockFrequency_Mhz_MSByte , 0x1221, 0x0000 }, +{ VideoTimingNearSensorConstraints_uwMinimumVTPixelClockDiv_LSByte , 0x1226, 0x0000 }, +{ VideoTimingNearSensorConstraints_uwMinimumVTPixelClockDiv_MSByte , 0x1225, 0x0000 }, +{ VideoTimingNearSensorConstraints_uwMaximumVTPixelClockDiv_LSByte , 0x122a, 0x0000 }, +{ VideoTimingNearSensorConstraints_uwMaximumVTPixelClockDiv_MSByte , 0x1229, 0x0000 }, +{ VideoTimingNearSensorConstraints_fpMaximumVTPixelClockFrequency_Mhz_LSByte , 0x122e, 0x0000 }, +{ VideoTimingNearSensorConstraints_fpMaximumVTPixelClockFrequency_Mhz_MSByte , 0x122d, 0x0000 }, +{ VideoTimingNearSensorConstraints_uwMinimumOPSysClockDiv_LSByte , 0x1232, 0x0000 }, +{ VideoTimingNearSensorConstraints_uwMinimumOPSysClockDiv_MSByte , 0x1231, 0x0000 }, +{ VideoTimingNearSensorConstraints_uwMaximumOPSysClockDiv_LSByte , 0x1236, 0x0000 }, +{ VideoTimingNearSensorConstraints_uwMaximumOPSysClockDiv_MSByte , 0x1235, 0x0000 }, +{ VideoTimingNearSensorConstraints_fpMaximumOPSystemClockFrequency_Mhz_LSByte , 0x123a, 0x0000 }, +{ VideoTimingNearSensorConstraints_fpMaximumOPSystemClockFrequency_Mhz_MSByte , 0x1239, 0x0000 }, +{ VideoTimingNearSensorConstraints_fpMaximumOPPixelClockFrequency_Mhz_LSByte , 0x123e, 0x0000 }, +{ VideoTimingNearSensorConstraints_fpMaximumOPPixelClockFrequency_Mhz_MSByte , 0x123d, 0x0000 }, +{ SensorNearScalingSubSamplingCapabilities_bSensorScalingMode , 0x1280, 0x0000 }, +{ SensorNearScalingSubSamplingCapabilities_uwScalerMMin_LSByte , 0x1284, 0x0000 }, +{ SensorNearScalingSubSamplingCapabilities_uwScalerMMin_MSByte , 0x1283, 0x0000 }, +{ SensorNearScalingSubSamplingCapabilities_uwScalerMMax_LSByte , 0x1288, 0x0000 }, +{ SensorNearScalingSubSamplingCapabilities_uwScalerMMax_MSByte , 0x1287, 0x0000 }, +{ SensorNearScalingSubSamplingCapabilities_uwMaxOddInc_LSByte , 0x128c, 0x0000 }, +{ SensorNearScalingSubSamplingCapabilities_uwMaxOddInc_MSByte , 0x128b, 0x0000 }, +{ VideoTimingNearOutput_uwPrePllClockDiv_LSByte , 0x1302, 0x0000 }, +{ VideoTimingNearOutput_uwPrePllClockDiv_MSByte , 0x1301, 0x0000 }, +{ VideoTimingNearOutput_fpPllInputFrequency_Mhz_LSByte , 0x1306, 0x0000 }, +{ VideoTimingNearOutput_fpPllInputFrequency_Mhz_MSByte , 0x1305, 0x0000 }, +{ VideoTimingNearOutput_uwPllMultiplier_LSByte , 0x130a, 0x0000 }, +{ VideoTimingNearOutput_uwPllMultiplier_MSByte , 0x1309, 0x0000 }, +{ VideoTimingNearOutput_fpPllOutputFrequency_Mhz_LSByte , 0x130e, 0x0000 }, +{ VideoTimingNearOutput_fpPllOutputFrequency_Mhz_MSByte , 0x130d, 0x0000 }, +{ VideoTimingNearOutput_uwVTSystemClockDiv_LSByte , 0x1312, 0x0000 }, +{ VideoTimingNearOutput_uwVTSystemClockDiv_MSByte , 0x1311, 0x0000 }, +{ VideoTimingNearOutput_fpVTSystemClockFrequency_Mhz_LSByte , 0x1316, 0x0000 }, +{ VideoTimingNearOutput_fpVTSystemClockFrequency_Mhz_MSByte , 0x1315, 0x0000 }, +{ VideoTimingNearOutput_uwVTPixelClockDiv_LSByte , 0x131a, 0x0000 }, +{ VideoTimingNearOutput_uwVTPixelClockDiv_MSByte , 0x1319, 0x0000 }, +{ VideoTimingNearOutput_fpVTPixelClockFrequency_Mhz_LSByte , 0x131e, 0x0000 }, +{ VideoTimingNearOutput_fpVTPixelClockFrequency_Mhz_MSByte , 0x131d, 0x0000 }, +{ VideoTimingNearOutput_fpVTPixelClockPeriod_us_LSByte , 0x1322, 0x0000 }, +{ VideoTimingNearOutput_fpVTPixelClockPeriod_us_MSByte , 0x1321, 0x0000 }, +{ VideoTimingNearOutput_uwOPSystemClockDiv_LSByte , 0x1326, 0x0000 }, +{ VideoTimingNearOutput_uwOPSystemClockDiv_MSByte , 0x1325, 0x0000 }, +{ VideoTimingNearOutput_fpOPSystemClockFrequency_Mhz_LSByte , 0x132a, 0x0000 }, +{ VideoTimingNearOutput_fpOPSystemClockFrequency_Mhz_MSByte , 0x1329, 0x0000 }, +{ VideoTimingNearOutput_uwOPPixelClockDiv_LSByte , 0x132e, 0x0000 }, +{ VideoTimingNearOutput_uwOPPixelClockDiv_MSByte , 0x132d, 0x0000 }, +{ VideoTimingNearOutput_fpOPPixelClockFrequency_Mhz_LSByte , 0x1332, 0x0000 }, +{ VideoTimingNearOutput_fpOPPixelClockFrequency_Mhz_MSByte , 0x1331, 0x0000 }, +{ VideoTimingNearOutput_fpOutputTimingClockDerating_LSByte , 0x1336, 0x0000 }, +{ VideoTimingNearOutput_fpOutputTimingClockDerating_MSByte , 0x1335, 0x0000 }, +{ DummyPage7_bDummyPageElement , 0x1380, 0x0000 }, +{ SystemConfiguration_fFarSensorPresent , 0x1400, 0x0001 }, +{ SystemConfiguration_CcpRxForFarSensor , 0x1402, 0x0000 }, +{ SystemConfiguration_fNearSensorPresent , 0x1404, 0x0001 }, +{ SystemConfiguration_CcpRxForNearSensor , 0x1406, 0x0001 }, +{ SystemConfiguration_uwExternalClockFrequency_Mhz_num_LSByte , 0x140a, 0x0000 }, +{ SystemConfiguration_uwExternalClockFrequency_Mhz_num_MSByte , 0x1409, 0x0060 }, +{ SystemConfiguration_bExternalClockFrequency_Mhz_den , 0x140c, 0x0005 }, +{ SystemConfiguration_fFocusLensActuatorOnSensorNearPresent , 0x140e, 0x1 },//0x0000 }, +{ SystemConfiguration_fFocusLensActuatorOnSensorFarPresent , 0x1410, 0x1 },//0x0000 },//for auto focus +{ SystemConfiguration_fShutterActuatorOnSensorNearPresent , 0x1412, 0x0000 }, +{ SystemConfiguration_fShutterActuatorOnSensorFarPresent , 0x1414, 0x0000 }, +{ SystemConfiguration_fpMcuClkFrequency_MHz_LSByte , 0x1418, 0x0000 }, +{ SystemConfiguration_fpMcuClkFrequency_MHz_MSByte , 0x1417, 0x0000 }, +{ SensorInformation_fFarSensorAvailable , 0x1480, 0x0000 }, +{ SensorInformation_uwFarSensorModelId_LSByte , 0x1484, 0x0000 }, +{ SensorInformation_uwFarSensorModelId_MSByte , 0x1483, 0x0000 }, +{ SensorInformation_bFarSensorRevision , 0x1486, 0x0000 }, +{ SensorInformation_bFarSensorManufacturerId , 0x1488, 0x0000 }, +{ SensorInformation_bFarSensorSMIAVersion , 0x148a, 0x0000 }, +{ SensorInformation_fNearSensorAvailable , 0x148c, 0x0000 }, +{ SensorInformation_uwNearSensorModelId_LSByte , 0x1490, 0x0000 }, +{ SensorInformation_uwNearSensorModelId_MSByte , 0x148f, 0x0000 }, +{ SensorInformation_bNearSensorRevision , 0x1492, 0x0000 }, +{ SensorInformation_bNearSensorManufacturerId , 0x1494, 0x0000 }, +{ SensorInformation_bNearSensorSMIAVersion , 0x1496, 0x0000 }, +{ SensorInformation_bCurrentlyActiveSensor , 0x1498, 0x0000 }, +{ SensorInformation_fCurrentSensorAvailable , 0x149a, 0x0000 }, +{ SensorInformation_fSensorChangedSinceLastStreaming , 0x149c, 0x0000 }, +{ SensorCapabilitiesFarSensor_uwSensorIntegrationTimeCapability_LSByte , 0x1502, 0x0000 }, +{ SensorCapabilitiesFarSensor_uwSensorIntegrationTimeCapability_MSByte , 0x1501, 0x0000 }, +{ SensorCapabilitiesFarSensor_uwSensorMinimumCoarseIntegrationLines_LSByte , 0x1506, 0x0000 }, +{ SensorCapabilitiesFarSensor_uwSensorMinimumCoarseIntegrationLines_MSByte , 0x1505, 0x0000 }, +{ SensorCapabilitiesFarSensor_uwSensorCoarseIntegrationTimeMaxMargin_LSByte , 0x150a, 0x0000 }, +{ SensorCapabilitiesFarSensor_uwSensorCoarseIntegrationTimeMaxMargin_MSByte , 0x1509, 0x0000 }, +{ SensorCapabilitiesFarSensor_uwSensorMinimumFineIntegrationPixels_LSByte , 0x150e, 0x0000 }, +{ SensorCapabilitiesFarSensor_uwSensorMinimumFineIntegrationPixels_MSByte , 0x150d, 0x0000 }, +{ SensorCapabilitiesFarSensor_uwSensorFineIntegrationTimeMaxMargin_LSByte , 0x1512, 0x0000 }, +{ SensorCapabilitiesFarSensor_uwSensorFineIntegrationTimeMaxMargin_MSByte , 0x1511, 0x0000 }, +{ SensorCapabilitiesFarSensor_uwSensorAnalogGainMinimum_LSByte , 0x1516, 0x0000 }, +{ SensorCapabilitiesFarSensor_uwSensorAnalogGainMinimum_MSByte , 0x1515, 0x0020 }, +{ SensorCapabilitiesFarSensor_uwSensorAnalogGainMaximum_LSByte , 0x151a, 0x0000 }, +{ SensorCapabilitiesFarSensor_uwSensorAnalogGainMaximum_MSByte , 0x1519, 0x0080 }, +{ SensorCapabilitiesFarSensor_uwSensorAnalogGainCodeStep_LSByte , 0x151e, 0x0000 }, +{ SensorCapabilitiesFarSensor_uwSensorAnalogGainCodeStep_MSByte , 0x151d, 0x0000 }, +{ SensorCapabilitiesFarSensor_uwSensorAnalogGainType_LSByte , 0x1522, 0x0000 }, +{ SensorCapabilitiesFarSensor_uwSensorAnalogGainType_MSByte , 0x1521, 0x0000 }, +{ SensorCapabilitiesFarSensor_fpSensorAnalogGainConstM0_LSByte , 0x1526, 0x0000 }, +{ SensorCapabilitiesFarSensor_fpSensorAnalogGainConstM0_MSByte , 0x1525, 0x0000 }, +{ SensorCapabilitiesFarSensor_fpSensorAnalogGainConstC0_LSByte , 0x152a, 0x0000 }, +{ SensorCapabilitiesFarSensor_fpSensorAnalogGainConstC0_MSByte , 0x1529, 0x0000 }, +{ SensorCapabilitiesFarSensor_fpSensorAnalogGainConstM1_LSByte , 0x152e, 0x0000 }, +{ SensorCapabilitiesFarSensor_fpSensorAnalogGainConstM1_MSByte , 0x152d, 0x0000 }, +{ SensorCapabilitiesFarSensor_fpSensorAnalogGainConstC1_LSByte , 0x1532, 0x0000 }, +{ SensorCapabilitiesFarSensor_fpSensorAnalogGainConstC1_MSByte , 0x1531, 0x0000 }, +{ SensorCapabilitiesFarSensor_uwSensorConstantColumns_LSByte , 0x1536, 0x0000 }, +{ SensorCapabilitiesFarSensor_uwSensorConstantColumns_MSByte , 0x1535, 0x0000 }, +{ SensorCapabilitiesFarSensor_uwStartOfActiveColumns_LSByte , 0x153a, 0x0000 }, +{ SensorCapabilitiesFarSensor_uwStartOfActiveColumns_MSByte , 0x1539, 0x0000 }, +{ SensorCapabilitiesFarSensor_bActiveColumnDescriptorNumber , 0x153c, 0x0000 }, +{ SensorCapabilitiesFarSensor_bSensorStartOfActiveLines , 0x153e, 0x0000 }, +{ SensorCapabilitiesFarSensor_uwSensorConstantRows_LSByte , 0x1542, 0x0000 }, +{ SensorCapabilitiesFarSensor_uwSensorConstantRows_MSByte , 0x1541, 0x0000 }, +{ SensorCapabilitiesFarSensor_uwSensorStatusLines_LSByte , 0x1546, 0x0000 }, +{ SensorCapabilitiesFarSensor_uwSensorStatusLines_MSByte , 0x1545, 0x0000 }, +{ SensorCapabilitiesFarSensor_bPreActiveDarkLines_LSByte , 0x154a, 0x0000 }, +{ SensorCapabilitiesFarSensor_bPreActiveDarkLines_MSByte , 0x1549, 0x0000 }, +{ SensorCapabilitiesFarSensor_bPreActiveBlackLines_LSByte , 0x154e, 0x0000 }, +{ SensorCapabilitiesFarSensor_bPreActiveBlackLines_MSByte , 0x154d, 0x0000 }, +{ SensorCapabilitiesFarSensor_bSensorVFPNLines , 0x1550, 0x0000 }, +{ SensorCapabilitiesFarSensor_uwSensorDigitalGainCapability_LSByte , 0x1554, 0x0000 }, +{ SensorCapabilitiesFarSensor_uwSensorDigitalGainCapability_MSByte , 0x1553, 0x0000 }, +{ SensorCapabilitiesFarSensor_uwSensorDigitalGainMinimum_LSByte , 0x1558, 0x0000 }, +{ SensorCapabilitiesFarSensor_uwSensorDigitalGainMinimum_MSByte , 0x1557, 0x0000 }, +{ SensorCapabilitiesFarSensor_uwSensorDataPedestal_LSByte , 0x155c, 0x0000 }, +{ SensorCapabilitiesFarSensor_uwSensorDataPedestal_MSByte , 0x155b, 0x0040 }, +{ SensorCapabilitiesNearSensor_uwSensorIntegrationTimeCapability_LSByte , 0x1582, 0x0000 }, +{ SensorCapabilitiesNearSensor_uwSensorIntegrationTimeCapability_MSByte , 0x1581, 0x0000 }, +{ SensorCapabilitiesNearSensor_uwSensorMinimumCoarseIntegrationLines_LSByte , 0x1586, 0x0000 }, +{ SensorCapabilitiesNearSensor_uwSensorMinimumCoarseIntegrationLines_MSByte , 0x1585, 0x0000 }, +{ SensorCapabilitiesNearSensor_uwSensorCoarseIntegrationTimeMaxMargin_LSByte , 0x158a, 0x0000 }, +{ SensorCapabilitiesNearSensor_uwSensorCoarseIntegrationTimeMaxMargin_MSByte , 0x1589, 0x0000 }, +{ SensorCapabilitiesNearSensor_uwSensorMinimumFineIntegrationPixels_LSByte , 0x158e, 0x0000 }, +{ SensorCapabilitiesNearSensor_uwSensorMinimumFineIntegrationPixels_MSByte , 0x158d, 0x0000 }, +{ SensorCapabilitiesNearSensor_uwSensorFineIntegrationTimeMaxMargin_LSByte , 0x1592, 0x0000 }, +{ SensorCapabilitiesNearSensor_uwSensorFineIntegrationTimeMaxMargin_MSByte , 0x1591, 0x0000 }, +{ SensorCapabilitiesNearSensor_uwSensorAnalogGainMinimum_LSByte , 0x1596, 0x0000 }, +{ SensorCapabilitiesNearSensor_uwSensorAnalogGainMinimum_MSByte , 0x1595, 0x0000 }, +{ SensorCapabilitiesNearSensor_uwSensorAnalogGainMaximum_LSByte , 0x159a, 0x0000 }, +{ SensorCapabilitiesNearSensor_uwSensorAnalogGainMaximum_MSByte , 0x1599, 0x00f0 }, +{ SensorCapabilitiesNearSensor_uwSensorAnalogGainCodeStep_LSByte , 0x159e, 0x0000 }, +{ SensorCapabilitiesNearSensor_uwSensorAnalogGainCodeStep_MSByte , 0x159d, 0x0000 }, +{ SensorCapabilitiesNearSensor_uwSensorAnalogGainType_LSByte , 0x15a2, 0x0000 }, +{ SensorCapabilitiesNearSensor_uwSensorAnalogGainType_MSByte , 0x15a1, 0x0000 }, +{ SensorCapabilitiesNearSensor_fpSensorAnalogGainConstM0_LSByte , 0x15a6, 0x0000 }, +{ SensorCapabilitiesNearSensor_fpSensorAnalogGainConstM0_MSByte , 0x15a5, 0x0000 }, +{ SensorCapabilitiesNearSensor_fpSensorAnalogGainConstC0_LSByte , 0x15aa, 0x0000 }, +{ SensorCapabilitiesNearSensor_fpSensorAnalogGainConstC0_MSByte , 0x15a9, 0x0000 }, +{ SensorCapabilitiesNearSensor_fpSensorAnalogGainConstM1_LSByte , 0x15ae, 0x0000 }, +{ SensorCapabilitiesNearSensor_fpSensorAnalogGainConstM1_MSByte , 0x15ad, 0x0000 }, +{ SensorCapabilitiesNearSensor_fpSensorAnalogGainConstC1_LSByte , 0x15b2, 0x0000 }, +{ SensorCapabilitiesNearSensor_fpSensorAnalogGainConstC1_MSByte , 0x15b1, 0x0000 }, +{ SensorCapabilitiesNearSensor_uwSensorConstantColumns_LSByte , 0x15b6, 0x0000 }, +{ SensorCapabilitiesNearSensor_uwSensorConstantColumns_MSByte , 0x15b5, 0x0000 }, +{ SensorCapabilitiesNearSensor_uwStartOfActiveColumns_LSByte , 0x15ba, 0x0000 }, +{ SensorCapabilitiesNearSensor_uwStartOfActiveColumns_MSByte , 0x15b9, 0x0000 }, +{ SensorCapabilitiesNearSensor_bActiveColumnDescriptorNumber , 0x15bc, 0x0000 }, +{ SensorCapabilitiesNearSensor_bSensorStartOfActiveLines , 0x15be, 0x0000 }, +{ SensorCapabilitiesNearSensor_uwSensorConstantRows_LSByte , 0x15c2, 0x0000 }, +{ SensorCapabilitiesNearSensor_uwSensorConstantRows_MSByte , 0x15c1, 0x0000 }, +{ SensorCapabilitiesNearSensor_uwSensorStatusLines_LSByte , 0x15c6, 0x0000 }, +{ SensorCapabilitiesNearSensor_uwSensorStatusLines_MSByte , 0x15c5, 0x0000 }, +{ SensorCapabilitiesNearSensor_bPreActiveDarkLines_LSByte , 0x15ca, 0x0000 }, +{ SensorCapabilitiesNearSensor_bPreActiveDarkLines_MSByte , 0x15c9, 0x0000 }, +{ SensorCapabilitiesNearSensor_bPreActiveBlackLines_LSByte , 0x15ce, 0x0000 }, +{ SensorCapabilitiesNearSensor_bPreActiveBlackLines_MSByte , 0x15cd, 0x0000 }, +{ SensorCapabilitiesNearSensor_bSensorVFPNLines , 0x15d0, 0x0000 }, +{ SensorCapabilitiesNearSensor_uwSensorDigitalGainCapability_LSByte , 0x15d4, 0x0000 }, +{ SensorCapabilitiesNearSensor_uwSensorDigitalGainCapability_MSByte , 0x15d3, 0x0000 }, +{ SensorCapabilitiesNearSensor_uwSensorDigitalGainMinimum_LSByte , 0x15d8, 0x0000 }, +{ SensorCapabilitiesNearSensor_uwSensorDigitalGainMinimum_MSByte , 0x15d7, 0x0000 }, +{ SensorCapabilitiesNearSensor_uwSensorDataPedestal_LSByte , 0x15dc, 0x0000 }, +{ SensorCapabilitiesNearSensor_uwSensorDataPedestal_MSByte , 0x15db, 0x0000 }, +{ SensorCapabilitiesCurrentSensor_uwSensorIntegrationTimeCapability_LSByte , 0x1602, 0x0000 }, +{ SensorCapabilitiesCurrentSensor_uwSensorIntegrationTimeCapability_MSByte , 0x1601, 0x0000 }, +{ SensorCapabilitiesCurrentSensor_uwSensorMinimumCoarseIntegrationLines_LSByte , 0x1606, 0x0000 }, +{ SensorCapabilitiesCurrentSensor_uwSensorMinimumCoarseIntegrationLines_MSByte , 0x1605, 0x0000 }, +{ SensorCapabilitiesCurrentSensor_uwSensorCoarseIntegrationTimeMaxMargin_LSByte , 0x160a, 0x0000 }, +{ SensorCapabilitiesCurrentSensor_uwSensorCoarseIntegrationTimeMaxMargin_MSByte , 0x1609, 0x0000 }, +{ SensorCapabilitiesCurrentSensor_uwSensorMinimumFineIntegrationPixels_LSByte , 0x160e, 0x0000 }, +{ SensorCapabilitiesCurrentSensor_uwSensorMinimumFineIntegrationPixels_MSByte , 0x160d, 0x0000 }, +{ SensorCapabilitiesCurrentSensor_uwSensorFineIntegrationTimeMaxMargin_LSByte , 0x1612, 0x0000 }, +{ SensorCapabilitiesCurrentSensor_uwSensorFineIntegrationTimeMaxMargin_MSByte , 0x1611, 0x0000 }, +{ SensorCapabilitiesCurrentSensor_uwSensorAnalogGainMinimum_LSByte , 0x1616, 0x0000 }, +{ SensorCapabilitiesCurrentSensor_uwSensorAnalogGainMinimum_MSByte , 0x1615, 0x0020 }, +{ SensorCapabilitiesCurrentSensor_uwSensorAnalogGainMaximum_LSByte , 0x161a, 0x0000 }, +{ SensorCapabilitiesCurrentSensor_uwSensorAnalogGainMaximum_MSByte , 0x1619, 0x0080 }, +{ SensorCapabilitiesCurrentSensor_uwSensorAnalogGainCodeStep_LSByte , 0x161e, 0x0000 }, +{ SensorCapabilitiesCurrentSensor_uwSensorAnalogGainCodeStep_MSByte , 0x161d, 0x0000 }, +{ SensorCapabilitiesCurrentSensor_uwSensorAnalogGainType_LSByte , 0x1622, 0x0000 }, +{ SensorCapabilitiesCurrentSensor_uwSensorAnalogGainType_MSByte , 0x1621, 0x0000 }, +{ SensorCapabilitiesCurrentSensor_fpSensorAnalogGainConstM0_LSByte , 0x1626, 0x0000 }, +{ SensorCapabilitiesCurrentSensor_fpSensorAnalogGainConstM0_MSByte , 0x1625, 0x0000 }, +{ SensorCapabilitiesCurrentSensor_fpSensorAnalogGainConstC0_LSByte , 0x162a, 0x0000 }, +{ SensorCapabilitiesCurrentSensor_fpSensorAnalogGainConstC0_MSByte , 0x1629, 0x0000 }, +{ SensorCapabilitiesCurrentSensor_fpSensorAnalogGainConstM1_LSByte , 0x162e, 0x0000 }, +{ SensorCapabilitiesCurrentSensor_fpSensorAnalogGainConstM1_MSByte , 0x162d, 0x0000 }, +{ SensorCapabilitiesCurrentSensor_fpSensorAnalogGainConstC1_LSByte , 0x1632, 0x0000 }, +{ SensorCapabilitiesCurrentSensor_fpSensorAnalogGainConstC1_MSByte , 0x1631, 0x0000 }, +{ SensorCapabilitiesCurrentSensor_uwSensorConstantColumns_LSByte , 0x1636, 0x0000 }, +{ SensorCapabilitiesCurrentSensor_uwSensorConstantColumns_MSByte , 0x1635, 0x0000 }, +{ SensorCapabilitiesCurrentSensor_uwStartOfActiveColumns_LSByte , 0x163a, 0x0000 }, +{ SensorCapabilitiesCurrentSensor_uwStartOfActiveColumns_MSByte , 0x1639, 0x0000 }, +{ SensorCapabilitiesCurrentSensor_bActiveColumnDescriptorNumber , 0x163c, 0x0000 }, +{ SensorCapabilitiesCurrentSensor_bSensorStartOfActiveLines , 0x163e, 0x0000 }, +{ SensorCapabilitiesCurrentSensor_uwSensorConstantRows_LSByte , 0x1642, 0x0000 }, +{ SensorCapabilitiesCurrentSensor_uwSensorConstantRows_MSByte , 0x1641, 0x0000 }, +{ SensorCapabilitiesCurrentSensor_uwSensorStatusLines_LSByte , 0x1646, 0x0000 }, +{ SensorCapabilitiesCurrentSensor_uwSensorStatusLines_MSByte , 0x1645, 0x0000 }, +{ SensorCapabilitiesCurrentSensor_bPreActiveDarkLines_LSByte , 0x164a, 0x0000 }, +{ SensorCapabilitiesCurrentSensor_bPreActiveDarkLines_MSByte , 0x1649, 0x0000 }, +{ SensorCapabilitiesCurrentSensor_bPreActiveBlackLines_LSByte , 0x164e, 0x0000 }, +{ SensorCapabilitiesCurrentSensor_bPreActiveBlackLines_MSByte , 0x164d, 0x0000 }, +{ SensorCapabilitiesCurrentSensor_bSensorVFPNLines , 0x1650, 0x0000 }, +{ SensorCapabilitiesCurrentSensor_uwSensorDigitalGainCapability_LSByte , 0x1654, 0x0000 }, +{ SensorCapabilitiesCurrentSensor_uwSensorDigitalGainCapability_MSByte , 0x1653, 0x0000 }, +{ SensorCapabilitiesCurrentSensor_uwSensorDigitalGainMinimum_LSByte , 0x1658, 0x0000 }, +{ SensorCapabilitiesCurrentSensor_uwSensorDigitalGainMinimum_MSByte , 0x1657, 0x0000 }, +{ SensorCapabilitiesCurrentSensor_uwSensorDataPedestal_LSByte , 0x165c, 0x0000 }, +{ SensorCapabilitiesCurrentSensor_uwSensorDataPedestal_MSByte , 0x165b, 0x0000 }, +{ SensorFrameConstraintsFar_uwVTXAddrMin_LSByte , 0x1682, 0x0000 }, +{ SensorFrameConstraintsFar_uwVTXAddrMin_MSByte , 0x1681, 0x0000 }, +{ SensorFrameConstraintsFar_uwVTYAddrMin_LSByte , 0x1686, 0x0000 }, +{ SensorFrameConstraintsFar_uwVTYAddrMin_MSByte , 0x1685, 0x0000 }, +{ SensorFrameConstraintsFar_uwVTXAddrMax_LSByte , 0x168a, 0x0000 }, +{ SensorFrameConstraintsFar_uwVTXAddrMax_MSByte , 0x1689, 0x0000 }, +{ SensorFrameConstraintsFar_uwVTYAddrMax_LSByte , 0x168e, 0x0000 }, +{ SensorFrameConstraintsFar_uwVTYAddrMax_MSByte , 0x168d, 0x0000 }, +{ SensorFrameConstraintsFar_uwMinOPXOutputSize_LSByte , 0x1692, 0x0000 }, +{ SensorFrameConstraintsFar_uwMinOPXOutputSize_MSByte , 0x1691, 0x0000 }, +{ SensorFrameConstraintsFar_uwMinOPYOutputSize_LSByte , 0x1696, 0x0000 }, +{ SensorFrameConstraintsFar_uwMinOPYOutputSize_MSByte , 0x1695, 0x0000 }, +{ SensorFrameConstraintsFar_uwMaxOPXOutputSize_LSByte , 0x169a, 0x0000 }, +{ SensorFrameConstraintsFar_uwMaxOPXOutputSize_MSByte , 0x1699, 0x0000 }, +{ SensorFrameConstraintsFar_uwMaxOPYOutputSize_LSByte , 0x169e, 0x0000 }, +{ SensorFrameConstraintsFar_uwMaxOPYOutputSize_MSByte , 0x169d, 0x0000 }, +{ SensorFrameConstraintsFar_uwMinVTFrameLengthLines_LSByte , 0x16a2, 0x0000 }, +{ SensorFrameConstraintsFar_uwMinVTFrameLengthLines_MSByte , 0x16a1, 0x0000 }, +{ SensorFrameConstraintsFar_uwMaxVTFrameLengthLines_LSByte , 0x16a6, 0x0000 }, +{ SensorFrameConstraintsFar_uwMaxVTFrameLengthLines_MSByte , 0x16a5, 0x0000 }, +{ SensorFrameConstraintsFar_uwMinVTLineLengthPck_LSByte , 0x16aa, 0x0000 }, +{ SensorFrameConstraintsFar_uwMinVTLineLengthPck_MSByte , 0x16a9, 0x0000 }, +{ SensorFrameConstraintsFar_uwMaxVTLineLengthPck_LSByte , 0x16ae, 0x0000 }, +{ SensorFrameConstraintsFar_uwMaxVTLineLengthPck_MSByte , 0x16ad, 0x0000 }, +{ SensorFrameConstraintsFar_uwMinVTLineBlankingPck_LSByte , 0x16b2, 0x0000 }, +{ SensorFrameConstraintsFar_uwMinVTLineBlankingPck_MSByte , 0x16b1, 0x0000 }, +{ SensorFrameConstraintsFar_uwMinVTFrameBlanking_LSByte , 0x16b6, 0x0000 }, +{ SensorFrameConstraintsFar_uwMinVTFrameBlanking_MSByte , 0x16b5, 0x0000 }, +{ SensorFrameConstraintsNear_uwVTXAddrMin_LSByte , 0x1702, 0x0000 }, +{ SensorFrameConstraintsNear_uwVTXAddrMin_MSByte , 0x1701, 0x0000 }, +{ SensorFrameConstraintsNear_uwVTYAddrMin_LSByte , 0x1706, 0x0000 }, +{ SensorFrameConstraintsNear_uwVTYAddrMin_MSByte , 0x1705, 0x0000 }, +{ SensorFrameConstraintsNear_uwVTXAddrMax_LSByte , 0x170a, 0x0000 }, +{ SensorFrameConstraintsNear_uwVTXAddrMax_MSByte , 0x1709, 0x0000 }, +{ SensorFrameConstraintsNear_uwVTYAddrMax_LSByte , 0x170e, 0x0000 }, +{ SensorFrameConstraintsNear_uwVTYAddrMax_MSByte , 0x170d, 0x0000 }, +{ SensorFrameConstraintsNear_uwMinOPXOutputSize_LSByte , 0x1712, 0x0000 }, +{ SensorFrameConstraintsNear_uwMinOPXOutputSize_MSByte , 0x1711, 0x0000 }, +{ SensorFrameConstraintsNear_uwMinOPYOutputSize_LSByte , 0x1716, 0x0000 }, +{ SensorFrameConstraintsNear_uwMinOPYOutputSize_MSByte , 0x1715, 0x0000 }, +{ SensorFrameConstraintsNear_uwMaxOPXOutputSize_LSByte , 0x171a, 0x0000 }, +{ SensorFrameConstraintsNear_uwMaxOPXOutputSize_MSByte , 0x1719, 0x0000 }, +{ SensorFrameConstraintsNear_uwMaxOPYOutputSize_LSByte , 0x171e, 0x0000 }, +{ SensorFrameConstraintsNear_uwMaxOPYOutputSize_MSByte , 0x171d, 0x0000 }, +{ SensorFrameConstraintsNear_uwMinVTFrameLengthLines_LSByte , 0x1722, 0x0000 }, +{ SensorFrameConstraintsNear_uwMinVTFrameLengthLines_MSByte , 0x1721, 0x0000 }, +{ SensorFrameConstraintsNear_uwMaxVTFrameLengthLines_LSByte , 0x1726, 0x0000 }, +{ SensorFrameConstraintsNear_uwMaxVTFrameLengthLines_MSByte , 0x1725, 0x0000 }, +{ SensorFrameConstraintsNear_uwMinVTLineLengthPck_LSByte , 0x172a, 0x0000 }, +{ SensorFrameConstraintsNear_uwMinVTLineLengthPck_MSByte , 0x1729, 0x0000 }, +{ SensorFrameConstraintsNear_uwMaxVTLineLengthPck_LSByte , 0x172e, 0x0000 }, +{ SensorFrameConstraintsNear_uwMaxVTLineLengthPck_MSByte , 0x172d, 0x0000 }, +{ SensorFrameConstraintsNear_uwMinVTLineBlankingPck_LSByte , 0x1732, 0x0000 }, +{ SensorFrameConstraintsNear_uwMinVTLineBlankingPck_MSByte , 0x1731, 0x0000 }, +{ SensorFrameConstraintsNear_uwMinVTFrameBlanking_LSByte , 0x1736, 0x0000 }, +{ SensorFrameConstraintsNear_uwMinVTFrameBlanking_MSByte , 0x1735, 0x0000 }, +{ AntiFlickerExposureControls_bMainsFrequency_Hz , 0x1780, 0x0032 }, +{ AntiFlickerExposureControls_fGuaranteeStaticFlickerFrameLength , 0x1782, 0x0000 }, +{ CurrentFrameDimension_uwVTFrameLengthLines_LSByte , 0x1802, 0x0000 }, +{ CurrentFrameDimension_uwVTFrameLengthLines_MSByte , 0x1801, 0x0000 }, +{ CurrentFrameDimension_uwVTLineLengthPck_LSByte , 0x1806, 0x0000 }, +{ CurrentFrameDimension_uwVTLineLengthPck_MSByte , 0x1805, 0x0000 }, +{ CurrentFrameDimension_uwVTXAddrStart_LSByte , 0x180a, 0x0000 }, +{ CurrentFrameDimension_uwVTXAddrStart_MSByte , 0x1809, 0x0000 }, +{ CurrentFrameDimension_uwVTYAddrStart_LSByte , 0x180e, 0x0000 }, +{ CurrentFrameDimension_uwVTYAddrStart_MSByte , 0x180d, 0x0000 }, +{ CurrentFrameDimension_uwVTXAddrEnd_LSByte , 0x1812, 0x0000 }, +{ CurrentFrameDimension_uwVTXAddrEnd_MSByte , 0x1811, 0x0000 }, +{ CurrentFrameDimension_uwVTYAddrEnd_LSByte , 0x1816, 0x0000 }, +{ CurrentFrameDimension_uwVTYAddrEnd_MSByte , 0x1815, 0x0000 }, +{ CurrentFrameDimension_uwOPXOutputSize_LSByte , 0x181a, 0x0000 }, +{ CurrentFrameDimension_uwOPXOutputSize_MSByte , 0x1819, 0x0000 }, +{ CurrentFrameDimension_uwOPYOutputSize_LSByte , 0x181e, 0x0000 }, +{ CurrentFrameDimension_uwOPYOutputSize_MSByte , 0x181d, 0x0000 }, +{ CurrentFrameDimension_uwVTXOutputSize_LSByte , 0x1822, 0x0000 }, +{ CurrentFrameDimension_uwVTXOutputSize_MSByte , 0x1821, 0x0000 }, +{ CurrentFrameDimension_uwVTYOutputSize_LSByte , 0x1826, 0x0000 }, +{ CurrentFrameDimension_uwVTYOutputSize_MSByte , 0x1825, 0x0000 }, +{ CurrentFrameDimension_bVTXSubSampling , 0x1828, 0x0000 }, +{ CurrentFrameDimension_uwXOddInc_LSByte , 0x182c, 0x0000 }, +{ CurrentFrameDimension_uwXOddInc_MSByte , 0x182b, 0x0000 }, +{ CurrentFrameDimension_bVTYSubSampling , 0x182e, 0x0000 }, +{ CurrentFrameDimension_uwYOddInc_LSByte , 0x1832, 0x0000 }, +{ CurrentFrameDimension_uwYOddInc_MSByte , 0x1831, 0x0000 }, +{ CurrentFrameDimension_bScalingMode , 0x1834, 0x0000 }, +{ CurrentFrameDimension_fpScaleFactor_LSByte , 0x1838, 0x0000 }, +{ CurrentFrameDimension_fpScaleFactor_MSByte , 0x1837, 0x0000 }, +{ CurrentFrameDimension_uwScalerM_LSByte , 0x183c, 0x0000 }, +{ CurrentFrameDimension_uwScalerM_MSByte , 0x183b, 0x0000 }, +{ SensorFrameConstraints_uwVTXAddrMin_LSByte , 0x1882, 0x0000 }, +{ SensorFrameConstraints_uwVTXAddrMin_MSByte , 0x1881, 0x0000 }, +{ SensorFrameConstraints_uwVTYAddrMin_LSByte , 0x1886, 0x0000 }, +{ SensorFrameConstraints_uwVTYAddrMin_MSByte , 0x1885, 0x0000 }, +{ SensorFrameConstraints_uwVTXAddrMax_LSByte , 0x188a, 0x0000 }, +{ SensorFrameConstraints_uwVTXAddrMax_MSByte , 0x1889, 0x0000 }, +{ SensorFrameConstraints_uwVTYAddrMax_LSByte , 0x188e, 0x0000 }, +{ SensorFrameConstraints_uwVTYAddrMax_MSByte , 0x188d, 0x0000 }, +{ SensorFrameConstraints_uwMinOPXOutputSize_LSByte , 0x1892, 0x0000 }, +{ SensorFrameConstraints_uwMinOPXOutputSize_MSByte , 0x1891, 0x0000 }, +{ SensorFrameConstraints_uwMinOPYOutputSize_LSByte , 0x1896, 0x0000 }, +{ SensorFrameConstraints_uwMinOPYOutputSize_MSByte , 0x1895, 0x0000 }, +{ SensorFrameConstraints_uwMaxOPXOutputSize_LSByte , 0x189a, 0x0000 }, +{ SensorFrameConstraints_uwMaxOPXOutputSize_MSByte , 0x1899, 0x0000 }, +{ SensorFrameConstraints_uwMaxOPYOutputSize_LSByte , 0x189e, 0x0000 }, +{ SensorFrameConstraints_uwMaxOPYOutputSize_MSByte , 0x189d, 0x0000 }, +{ SensorFrameConstraints_uwMinVTFrameLengthLines_LSByte , 0x18a2, 0x0000 }, +{ SensorFrameConstraints_uwMinVTFrameLengthLines_MSByte , 0x18a1, 0x0000 }, +{ SensorFrameConstraints_uwMaxVTFrameLengthLines_LSByte , 0x18a6, 0x0000 }, +{ SensorFrameConstraints_uwMaxVTFrameLengthLines_MSByte , 0x18a5, 0x0000 }, +{ SensorFrameConstraints_uwMinVTLineLengthPck_LSByte , 0x18aa, 0x0000 }, +{ SensorFrameConstraints_uwMinVTLineLengthPck_MSByte , 0x18a9, 0x0000 }, +{ SensorFrameConstraints_uwMaxVTLineLengthPck_LSByte , 0x18ae, 0x0000 }, +{ SensorFrameConstraints_uwMaxVTLineLengthPck_MSByte , 0x18ad, 0x0000 }, +{ SensorFrameConstraints_uwMinVTLineBlankingPck_LSByte , 0x18b2, 0x0000 }, +{ SensorFrameConstraints_uwMinVTLineBlankingPck_MSByte , 0x18b1, 0x0000 }, +{ SensorFrameConstraints_uwMinVTFrameBlanking_LSByte , 0x18b6, 0x0000 }, +{ SensorFrameConstraints_uwMinVTFrameBlanking_MSByte , 0x18b5, 0x0000 }, +{ HostFrameConstraints_uwMinimumOPLineBlanking_pixels_LSByte , 0x1902, 0x0000 }, +{ HostFrameConstraints_uwMinimumOPLineBlanking_pixels_MSByte , 0x1901, 0x0000 }, +{ HostFrameConstraints_uwMinimumOPFrameBlanking_lines_LSByte , 0x1906, 0x0000 }, +{ HostFrameConstraints_uwMinimumOPFrameBlanking_lines_MSByte , 0x1905, 0x0000 }, +{ HostFrameConstraints_bMinimumPostScalar0LineBlanking_pixels , 0x1908, 0x0000 }, +{ HostFrameConstraints_bMinimumPostScalar1LineBlanking_pixels , 0x190a, 0x0000 }, +{ FrameDimensionStatus_fFrameLengthChangePending , 0x1980, 0x0000 }, +{ FrameDimensionStatus_fFrameDimensionChangePending , 0x1982, 0x0000 }, +{ FrameDimensionStatus_uwVTFrameLengthPending_lines_LSByte , 0x1986, 0x0000 }, +{ FrameDimensionStatus_uwVTFrameLengthPending_lines_MSByte , 0x1985, 0x0000 }, +{ FrameDimensionStatus_fFrameLengthChangeInhibitedForCoarseExposure , 0x1988, 0x0000 }, +{ FrameDimensionStatus_uwMinVTLineLengthAtCurrentVTXSize_pixels_LSByte , 0x198c, 0x0000 }, +{ FrameDimensionStatus_uwMinVTLineLengthAtCurrentVTXSize_pixels_MSByte , 0x198b, 0x0000 }, +{ FrameDimensionStatus_uwMinVTFrameLengthAtCurrentVTYSize_lines_LSByte , 0x1990, 0x0000 }, +{ FrameDimensionStatus_uwMinVTFrameLengthAtCurrentVTYSize_lines_MSByte , 0x198f, 0x0000 }, +{ FrameDimensionStatus_fpVTLineLength_us_LSByte , 0x1994, 0x0000 }, +{ FrameDimensionStatus_fpVTLineLength_us_MSByte , 0x1993, 0x0000 }, +{ FrameDimensionStatus_fpVTFrameLength_us_LSByte , 0x1998, 0x0000 }, +{ FrameDimensionStatus_fpVTFrameLength_us_MSByte , 0x1997, 0x0000 }, +{ FrameDimensionStatus_fpCurrentFrameRate_LSByte , 0x199c, 0x0000 }, +{ FrameDimensionStatus_fpCurrentFrameRate_MSByte , 0x199b, 0x0000 }, +{ FrameDimensionStatus_uwMaximumSensorFOVX_LSByte , 0x19a0, 0x0000 }, +{ FrameDimensionStatus_uwMaximumSensorFOVX_MSByte , 0x199f, 0x0000 }, +{ FrameDimensionStatus_uwMaximumSensorFOVY_LSByte , 0x19a4, 0x0000 }, +{ FrameDimensionStatus_uwMaximumSensorFOVY_MSByte , 0x19a3, 0x0000 }, +{ FrameDimensionStatus_uwOPXOutputSize_LSByte , 0x19a8, 0x0000 }, +{ FrameDimensionStatus_uwOPXOutputSize_MSByte , 0x19a7, 0x0000 }, +{ FrameDimensionStatus_fSensorPreScaleFactorChanged , 0x19aa, 0x0000 }, +{ BinningControl_fEnableBinning , 0x1a00, 0x0000 }, +{ BinningStatus_fBinningEnabled , 0x1a80, 0x0000 }, +{ Sensor0BinningInputs_uwMinVTLineLengthPck_LSByte , 0x1b02, 0x0000 }, +{ Sensor0BinningInputs_uwMinVTLineLengthPck_MSByte , 0x1b01, 0x0000 }, +{ Sensor0BinningInputs_uwSensorMinimumFineIntegrationPixels_LSByte , 0x1b06, 0x0000 }, +{ Sensor0BinningInputs_uwSensorMinimumFineIntegrationPixels_MSByte , 0x1b05, 0x0000 }, +{ Sensor1BinningInputs_uwMinVTLineLengthPck_LSByte , 0x1b82, 0x0000 }, +{ Sensor1BinningInputs_uwMinVTLineLengthPck_MSByte , 0x1b81, 0x0000 }, +{ Sensor1BinningInputs_uwSensorMinimumFineIntegrationPixels_LSByte , 0x1b86, 0x0000 }, +{ Sensor1BinningInputs_uwSensorMinimumFineIntegrationPixels_MSByte , 0x1b85, 0x0000 }, +{ CurrentSensorBinningInputs_uwMinVTLineLengthPck_LSByte , 0x1c02, 0x0000 }, +{ CurrentSensorBinningInputs_uwMinVTLineLengthPck_MSByte , 0x1c01, 0x0000 }, +{ CurrentSensorBinningInputs_uwSensorMinimumFineIntegrationPixels_LSByte , 0x1c06, 0x0000 }, +{ CurrentSensorBinningInputs_uwSensorMinimumFineIntegrationPixels_MSByte , 0x1c05, 0x0000 }, +{ FlashManagerControl_bMode , 0x1c80, 0x0000 }, +{ FlashManagerControl_bFlashType , 0x1c82, 0x0002 }, +{ FlashManagerControl_fOrMainAndPreFlashPulse , 0x1c84, 0x0001 }, +{ FlashManagerControl_RefPointCalcMode , 0x1c86, 0x0000 }, +{ FlashManagerControl_wIntegrationStartPosition_LSByte , 0x1c8a, 0x0000 }, +{ FlashManagerControl_wIntegrationStartPosition_MSByte , 0x1c88, 0x0000 }, +{ FlashManagerControl_fOverrideIntegrationStartPosition , 0x1c8a, 0x0000 }, +{ FlashManagerControl_fpFlashFiringDelay_us_LSByte , 0x1c90, 0x0000 }, +{ FlashManagerControl_fpFlashFiringDelay_us_MSByte , 0x1c8c, 0x0000 }, +{ FlashManagerControl_bNumberOfPreFlashes , 0x1c8e, 0x0000 }, +{ FlashManagerControl_fpPulseWidthMainFlash_us_LSByte , 0x1c96, 0x0000 }, +{ FlashManagerControl_fpPulseWidthMainFlash_us_MSByte , 0x1c90, 0x0000 }, +{ FlashManagerControl_fpPulseWidthPreFlash_us_LSByte , 0x1c9a, 0x0000 }, +{ FlashManagerControl_fpPulseWidthPreFlash_us_MSByte , 0x1c92, 0x0000 }, +{ FlashManagerControl_fpTimeBetweenTwoPreFlashes_us_LSByte , 0x1c9e, 0x0000 }, +{ FlashManagerControl_fpTimeBetweenTwoPreFlashes_us_MSByte , 0x1c94, 0x0000 }, +{ FlashManagerControl_fpTimeBetweenPreFlashAndMainFlash_us_LSByte , 0x1ca2, 0x0000 }, +{ FlashManagerControl_fpTimeBetweenPreFlashAndMainFlash_us_MSByte , 0x1c96, 0x0000 }, +{ FlashManagerControl_cMainFlashStartFrame , 0x1c98, 0x0000 }, +{ FlashManagerControl_wMainFlashStartLine_LSByte , 0x1ca8, 0x0000 }, +{ FlashManagerControl_wMainFlashStartLine_MSByte , 0x1c9a, 0x0000 }, +{ FlashManagerControl_wMainFlashStartPixel_LSByte , 0x1cac, 0x0000 }, +{ FlashManagerControl_wMainFlashStartPixel_MSByte , 0x1c9c, 0x0000 }, +{ FlashManagerControl_cPreFlashStartFrame , 0x1c9e, 0x0000 }, +{ FlashManagerControl_wPreFlashStartLine_LSByte , 0x1cb2, 0x0000 }, +{ FlashManagerControl_wPreFlashStartLine_MSByte , 0x1ca0, 0x0000 }, +{ FlashManagerControl_wPreFlashStartPixel_LSByte , 0x1cb6, 0x0000 }, +{ FlashManagerControl_wPreFlashStartPixel_MSByte , 0x1ca2, 0x0000 }, +{ FlashManagerControl_bTotalFramesRequired , 0x1ca4, 0x0000 }, +{ FlashManagerStatus_fFlashSequencePending , 0x1d00, 0x0000 }, +{ FlashManagerStatus_cNumberFramesRequiredForPreFlashes , 0x1d02, 0x0000 }, +{ FlashManagerStatus_fpMainFlashPulseWidth_us_LSByte , 0x1d06, 0x0000 }, +{ FlashManagerStatus_fpMainFlashPulseWidth_us_MSByte , 0x1d05, 0x0000 }, +{ FlashManagerStatus_fpPreFlashPulseWidth_us_LSByte , 0x1d0a, 0x0000 }, +{ FlashManagerStatus_fpPreFlashPulseWidth_us_MSByte , 0x1d09, 0x0000 }, +{ FlashManagerStatus_fpInterPreflashDistance_us_LSByte , 0x1d0e, 0x0000 }, +{ FlashManagerStatus_fpInterPreflashDistance_us_MSByte , 0x1d0d, 0x0000 }, +{ FlashManagerStatus_fpPreAndMainflashDistance_us_LSByte , 0x1d12, 0x0000 }, +{ FlashManagerStatus_fpPreAndMainflashDistance_us_MSByte , 0x1d11, 0x0000 }, +{ FlashManagerStatus_cStartFlashFrame , 0x1d14, 0x0000 }, +{ FlashManagerStatus_wStartFlashLine_LSByte , 0x1d18, 0x0000 }, +{ FlashManagerStatus_wStartFlashLine_MSByte , 0x1d17, 0x0000 }, +{ FlashManagerStatus_wStartFlashPixel_LSByte , 0x1d1c, 0x0000 }, +{ FlashManagerStatus_wStartFlashPixel_MSByte , 0x1d1b, 0x0000 }, +{ FlashManagerStatus_cStartPreFlashFrame , 0x1d1e, 0x0000 }, +{ FlashManagerStatus_wStartPreFlashLine_LSByte , 0x1d22, 0x0000 }, +{ FlashManagerStatus_wStartPreFlashLine_MSByte , 0x1d21, 0x0000 }, +{ FlashManagerStatus_wStartPreFlashPixel_LSByte , 0x1d26, 0x0000 }, +{ FlashManagerStatus_wStartPreFlashPixel_MSByte , 0x1d25, 0x0000 }, +{ FlashManagerStatus_cNumberFramesRequired , 0x1d28, 0x0000 }, +{ FlashManagerStatus_fPreFlashPending , 0x1d2a, 0x0000 }, +{ FlashManagerStatus_fMainFlashPending , 0x1d2c, 0x0000 }, +{ ExposureControls_bMode , 0x1d80, 0x0000 }, +{ ExposureControls_bMetering , 0x1d82, 0x0002 }, +{ ExposureControls_bManualExposureTime_s_num , 0x1d84, 0x0000 }, +{ ExposureControls_bManualExposureTime_s_den , 0x1d86, 0x0000 }, +{ ExposureControls_fpManualDesiredExposureTime_us_LSByte , 0x1d8a, 0x0000 }, +{ ExposureControls_fpManualDesiredExposureTime_us_MSByte , 0x1d89, 0x0000 }, +{ ExposureControls_fpColdStartDesiredTime_us_LSByte , 0x1d8e, 0x0000 }, +{ ExposureControls_fpColdStartDesiredTime_us_MSByte , 0x1d8d, 0x59aa }, +{ ExposureControls_iExposureCompensation , 0x1d90, 0x0000 }, +{ ExposureControls_bMiscSettings , 0x1d92, 0x0000 }, +{ ExposureControls_uwDirectModeCoarseIntegration_lines_LSByte , 0x1d96, 0x0000 }, +{ ExposureControls_uwDirectModeCoarseIntegration_lines_MSByte , 0x1d95, 0x0000 }, +{ ExposureControls_uwDirectModeFineIntegration_pixels_LSByte , 0x1d9a, 0x0000 }, +{ ExposureControls_uwDirectModeFineIntegration_pixels_MSByte , 0x1d99, 0x0000 }, +{ ExposureControls_uwDirectModeCodedAnalogGain_LSByte , 0x1d9e, 0x0000 }, +{ ExposureControls_uwDirectModeCodedAnalogGain_MSByte , 0x1d9d, 0x0000 }, +{ ExposureControls_fpDirectModeDigitalGain_LSByte , 0x1da2, 0x0000 }, +{ ExposureControls_fpDirectModeDigitalGain_MSByte , 0x1da1, 0x0000 }, +{ ExposureControls_uwFlashGunModeCoarseIntegration_lines_LSByte , 0x1da6, 0x0000 }, +{ ExposureControls_uwFlashGunModeCoarseIntegration_lines_MSByte , 0x1da5, 0x0000 }, +{ ExposureControls_uwFlashGunModeFineIntegration_pixels_LSByte , 0x1daa, 0x0000 }, +{ ExposureControls_uwFlashGunModeFineIntegration_pixels_MSByte , 0x1da9, 0x0000 }, +{ ExposureControls_uwFlashGunModeCodedAnalogGain_LSByte , 0x1dae, 0x0000 }, +{ ExposureControls_uwFlashGunModeCodedAnalogGain_MSByte , 0x1dad, 0x0000 }, +{ ExposureControls_fpFlashGunModeDigitalGain_LSByte , 0x1db2, 0x0000 }, +{ ExposureControls_fpFlashGunModeDigitalGain_MSByte , 0x1db1, 0x0000 }, +{ ExposureControls_fFreezeAutoExposure , 0x1db4, 0x0000 }, +{ ExposureControls_fpUserMaximumIntegrationTime_us_LSByte , 0x1db8, 0x0000 }, +{ ExposureControls_fpUserMaximumIntegrationTime_us_MSByte , 0x1db7, 0x65d1 }, +{ ExposureControls_fpRecommendFlashGunAnalogGainThreshold_LSByte , 0x1dbc, 0x0000 }, +{ ExposureControls_fpRecommendFlashGunAnalogGainThreshold_MSByte , 0x1dbb, 0x624a }, +{ ExposureControls_fEnableHighClipForDesiredExposureTime , 0x1dbe, 0x0001 }, +{ ExposureControls_bAntiFlickerMode , 0x1dc0, 0x0001 }, +{ ExposureControls_fInhibitExposurePresetModeForFlash , 0x1dc2, 0x0000 }, +{ ExposureStatus_bAlgorithmStatus , 0x1e00, 0x0000 }, +{ ExposureStatus_bCompilerStatus , 0x1e02, 0x0000 }, +{ ExposureStatus_fWhiteBalanceGainIncludedInCurrentExposure , 0x1e04, 0x0000 }, +{ ExposureStatus_fBadExposureForIterativeWhiteBalance , 0x1e06, 0x0000 }, +{ ExposureStatus_uwCoarseIntegrationPending_lines_LSByte , 0x1e0a, 0x0000 }, +{ ExposureStatus_uwCoarseIntegrationPending_lines_MSByte , 0x1e09, 0x0000 }, +{ ExposureStatus_uwFineIntegrationPending_pixels_LSByte , 0x1e0e, 0x0000 }, +{ ExposureStatus_uwFineIntegrationPending_pixels_MSByte , 0x1e0d, 0x0000 }, +{ ExposureStatus_fpAnalogGainPending_LSByte , 0x1e12, 0x0000 }, +{ ExposureStatus_fpAnalogGainPending_MSByte , 0x1e11, 0x0000 }, +{ ExposureStatus_fpDigitalGainPending_LSByte , 0x1e16, 0x0000 }, +{ ExposureStatus_fpDigitalGainPending_MSByte , 0x1e15, 0x0000 }, +{ ExposureStatus_fpDesiredExposureTime_us_LSByte , 0x1e1a, 0x0000 }, +{ ExposureStatus_fpDesiredExposureTime_us_MSByte , 0x1e19, 0x0000 }, +{ ExposureStatus_fpCompiledExposureTime_us_LSByte , 0x1e1e, 0x0000 }, +{ ExposureStatus_fpCompiledExposureTime_us_MSByte , 0x1e1d, 0x0000 }, +{ ExposureStatus_bControlLoopFailureCount , 0x1e20, 0x0000 }, +{ ExposureStatus_uwUserMaximumIntegrationLines_LSByte , 0x1e24, 0x0000 }, +{ ExposureStatus_uwUserMaximumIntegrationLines_MSByte , 0x1e23, 0x0000 }, +{ ExposureStatus_fpTotalIntegrationTimePending_us_LSByte , 0x1e28, 0x0000 }, +{ ExposureStatus_fpTotalIntegrationTimePending_us_MSByte , 0x1e27, 0x0000 }, +{ ExposureStatus_uwCodedAnalogGainPending_LSByte , 0x1e2c, 0x0000 }, +{ ExposureStatus_uwCodedAnalogGainPending_MSByte , 0x1e2b, 0x0000 }, +{ ExposureStatus_fExposureIsStableforAutoFocus , 0x1e2e, 0x0000 }, +{ ExposureStatus_bRuntimeExposureTarget , 0x1e30, 0x0000 }, +{ ExposureParametersApplied_uwCoarseIntegration_lines_LSByte , 0x1e82, 0x0000 }, +{ ExposureParametersApplied_uwCoarseIntegration_lines_MSByte , 0x1e81, 0x0000 }, +{ ExposureParametersApplied_uwFineIntegration_pixels_LSByte , 0x1e86, 0x0000 }, +{ ExposureParametersApplied_uwFineIntegration_pixels_MSByte , 0x1e85, 0x0000 }, +{ ExposureParametersApplied_uwCodedAnalogGain_LSByte , 0x1e8a, 0x0000 }, +{ ExposureParametersApplied_uwCodedAnalogGain_MSByte , 0x1e89, 0x0000 }, +{ ExposureParametersApplied_fpDigitalGain_LSByte , 0x1e8e, 0x0000 }, +{ ExposureParametersApplied_fpDigitalGain_MSByte , 0x1e8d, 0x0000 }, +{ ExposureStatisticsStatus_fpMeanEnergy_LSByte , 0x1f02, 0x0000 }, +{ ExposureStatisticsStatus_fpMeanEnergy_MSByte , 0x1f01, 0x0000 }, +{ ExposureCycleTest_fpInitialDesiredExposureTime_LSByte , 0x1f82, 0x0000 }, +{ ExposureCycleTest_fpInitialDesiredExposureTime_MSByte , 0x1f81, 0x0000 }, +{ ExposureCycleTest_fpFinalDesiredExposureTime_LSByte , 0x1f86, 0x0000 }, +{ ExposureCycleTest_fpFinalDesiredExposureTime_MSByte , 0x1f85, 0x0000 }, +{ ExposureCycleTest_fpExposureStep_LSByte , 0x1f8a, 0x0000 }, +{ ExposureCycleTest_fpExposureStep_MSByte , 0x1f89, 0x0000 }, +{ ExposureCycleTest_bStepDirection , 0x1f8c, 0x0000 }, +{ ExposureTestCoin_fTestCoinEnabled , 0x2000, 0x0000 }, +{ ExposureTestCoin_fRunForTest , 0x2002, 0x0000 }, +{ ExposureTestCoin_bStatusCoin , 0x2004, 0x0000 }, +{ ExposureTestCoin_bControlCoin , 0x2006, 0x0000 }, +{ ExposureAlgorithmControls_fpMaximumStep_LSByte , 0x2082, 0x0000 }, +{ ExposureAlgorithmControls_fpMaximumStep_MSByte , 0x2081, 0x0000 }, +{ ExposureAlgorithmControls_fpMinimumStep_LSByte , 0x2086, 0x0000 }, +{ ExposureAlgorithmControls_fpMinimumStep_MSByte , 0x2085, 0x0000 }, +{ ExposureAlgorithmControls_fpMinimumDesiredExposureTime_us_LSByte , 0x208a, 0x0000 }, +{ ExposureAlgorithmControls_fpMinimumDesiredExposureTime_us_MSByte , 0x2089, 0x0000 }, +{ ExposureAlgorithmControls_fpStepProportion_LSByte , 0x208e, 0x0000 }, +{ ExposureAlgorithmControls_fpStepProportion_MSByte , 0x208d, 0x0000 }, +{ ExposureAlgorithmControls_fpMaximumNegativeStepThreshold_LSByte , 0x2092, 0x0000 }, +{ ExposureAlgorithmControls_fpMaximumNegativeStepThreshold_MSByte , 0x2091, 0x0000 }, +{ ExposureAlgorithmControls_fpRelativeOnTargetStabilityThreshold_LSByte , 0x2096, 0x0000 }, +{ ExposureAlgorithmControls_fpRelativeOnTargetStabilityThreshold_MSByte , 0x2095, 0x0000 }, +{ ExposureAlgorithmControls_fpDigitalGainFloor_LSByte , 0x209a, 0x0000 }, +{ ExposureAlgorithmControls_fpDigitalGainFloor_MSByte , 0x2099, 0x3e00 }, +{ ExposureAlgorithmControls_fpDigitalGainCeiling_LSByte , 0x209e, 0x0000 }, +{ ExposureAlgorithmControls_fpDigitalGainCeiling_MSByte , 0x209d, 0x4080 }, +{ ExposureAlgorithmControls_fpRelativeIntTimeHysThreshold_LSByte , 0x20a2, 0x0000 }, +{ ExposureAlgorithmControls_fpRelativeIntTimeHysThreshold_MSByte , 0x20a1, 0x0000 }, +{ ExposureAlgorithmControls_fpRelativeDigitalGainHysThreshold_LSByte , 0x20a6, 0x0000 }, +{ ExposureAlgorithmControls_fpRelativeDigitalGainHysThreshold_MSByte , 0x20a5, 0x0000 }, +{ ExposureAlgorithmControls_fpRelativeCompilationProblemThreshold_LSByte , 0x20aa, 0x0000 }, +{ ExposureAlgorithmControls_fpRelativeCompilationProblemThreshold_MSByte , 0x20a9, 0x0000 }, +{ ExposureAlgorithmControls_fpRoundUpBunchFudge_LSByte , 0x20ae, 0x0000 }, +{ ExposureAlgorithmControls_fpRoundUpBunchFudge_MSByte , 0x20ad, 0x0000 }, +{ ExposureAlgorithmControls_fpFineClampThreshold_LSByte , 0x20b2, 0x0000 }, +{ ExposureAlgorithmControls_fpFineClampThreshold_MSByte , 0x20b1, 0x0000 }, +{ ExposureAlgorithmControls_fpMaximumManualExposureTime_s_LSByte , 0x20b6, 0x0000 }, +{ ExposureAlgorithmControls_fpMaximumManualExposureTime_s_MSByte , 0x20b5, 0x0000 }, +{ ExposureAlgorithmControls_fpRelativeStabilityThresholdForAutoFocus_LSByte , 0x20ba, 0x0000 }, +{ ExposureAlgorithmControls_fpRelativeStabilityThresholdForAutoFocus_MSByte , 0x20b9, 0x0000 }, +{ ExposureAlgorithmControls_bLeakShift , 0x20bc, 0x0000 }, +{ ExposureAlgorithmStatus_fpLeakyEnergy_LSByte , 0x2102, 0x0000 }, +{ ExposureAlgorithmStatus_fpLeakyEnergy_MSByte , 0x2101, 0x0000 }, +{ ExposureAlgorithmStatus_fpRelativeStep_LSByte , 0x2106, 0x0000 }, +{ ExposureAlgorithmStatus_fpRelativeStep_MSByte , 0x2105, 0x0000 }, +{ ExposureUpdateErrorControl_bMaximumNumberOfFrames , 0x2180, 0x0000 }, +{ ExposureUpdateErrorStatus_bNumberOfForcedInputProcUpdates , 0x2200, 0x0000 }, +{ ExposureUpdateErrorStatus_bNumberOfConsecutiveDelayedFrames , 0x2202, 0x0000 }, +{ ExposureUpdateErrorStatus_fForceInputProcUpdation , 0x2204, 0x0000 }, +{ WhiteBalanceControls_bMode , 0x2280, 0x0001 }, +{ WhiteBalanceControls_bManualRedGain , 0x2282, 0x0000 }, +{ WhiteBalanceControls_bManualGreenGain , 0x2284, 0x0000 }, +{ WhiteBalanceControls_bManualBlueGain , 0x2286, 0x0000 }, +{ WhiteBalanceControls_bMiscSettings , 0x2288, 0x0000 }, +{ WhiteBalanceControls_fpFlashRedGain_LSByte , 0x228c, 0x0000 }, +{ WhiteBalanceControls_fpFlashRedGain_MSByte , 0x228b, 0x3e66 }, +{ WhiteBalanceControls_fpFlashGreenGain_LSByte , 0x2290, 0x0000 }, +{ WhiteBalanceControls_fpFlashGreenGain_MSByte , 0x228f, 0x3e00 }, +{ WhiteBalanceControls_fpFlashBlueGain_LSByte , 0x2294, 0x0000 }, +{ WhiteBalanceControls_fpFlashBlueGain_MSByte , 0x2293, 0x3f0a }, +{ WhiteBalanceControls_fInhibitWhiteBalancePresetModeForFlash , 0x2296, 0x0000 }, +{ WhiteBalanceAlgorithmControls_fpStableTotalStepThreshold_LSByte , 0x2302, 0x0000 }, +{ WhiteBalanceAlgorithmControls_fpStableTotalStepThreshold_MSByte , 0x2301, 0x2c00 }, +{ WhiteBalanceAlgorithmControls_fpMinimumRelativeStep_LSByte , 0x2306, 0x0000 }, +{ WhiteBalanceAlgorithmControls_fpMinimumRelativeStep_MSByte , 0x2305, 0x2a00 }, +{ WhiteBalanceAlgorithmControls_fpMaximumRelativeStep_LSByte , 0x230a, 0x0000 }, +{ WhiteBalanceAlgorithmControls_fpMaximumRelativeStep_MSByte , 0x2309, 0x3800 }, +{ WhiteBalanceAlgorithmControls_fpStepProportion_LSByte , 0x230e, 0x0000 }, +{ WhiteBalanceAlgorithmControls_fpStepProportion_MSByte , 0x230d, 0x3d00 }, +{ WhiteBalanceStatus_bStatus , 0x2380, 0x0000 }, +{ WhiteBalanceStatus_fUnityGainsUsed , 0x2382, 0x0000 }, +{ WhiteBalanceStatus_fpRedGain_LSByte , 0x2386, 0x0000 }, +{ WhiteBalanceStatus_fpRedGain_MSByte , 0x2385, 0x0000 }, +{ WhiteBalanceStatus_fpGreenGain_LSByte , 0x238a, 0x0000 }, +{ WhiteBalanceStatus_fpGreenGain_MSByte , 0x2389, 0x0000 }, +{ WhiteBalanceStatus_fpBlueGain_LSByte , 0x238e, 0x0000 }, +{ WhiteBalanceStatus_fpBlueGain_MSByte , 0x238d, 0x0000 }, +{ WhiteBalanceStatisticsControls_bLowThreshold , 0x2400, 0x0000 }, +{ WhiteBalanceStatisticsStatus_fpRedEnergy_LSByte , 0x2482, 0x0000 }, +{ WhiteBalanceStatisticsStatus_fpRedEnergy_MSByte , 0x2481, 0x0000 }, +{ WhiteBalanceStatisticsStatus_fpGreenEnergy_LSByte , 0x2486, 0x0000 }, +{ WhiteBalanceStatisticsStatus_fpGreenEnergy_MSByte , 0x2485, 0x0000 }, +{ WhiteBalanceStatisticsStatus_fpBlueEnergy_LSByte , 0x248a, 0x0000 }, +{ WhiteBalanceStatisticsStatus_fpBlueEnergy_MSByte , 0x2489, 0x0000 }, +{ MinWeightedWBControls_fDisable , 0x2500, 0x0000 }, +{ MinWeightedWBControls_uwSaturationThreshold_LSByte , 0x2504, 0x0000 }, +{ MinWeightedWBControls_uwSaturationThreshold_MSByte , 0x2503, 0x0300 }, +{ MinWeightedWBControls_fpRedTiltGain_LSByte , 0x2508, 0x0000 }, +{ MinWeightedWBControls_fpRedTiltGain_MSByte , 0x2507, 0x3e00 }, +{ MinWeightedWBControls_fpGreen1TiltGain_LSByte , 0x250c, 0x0000 }, +{ MinWeightedWBControls_fpGreen1TiltGain_MSByte , 0x250b, 0x3e40 }, +{ MinWeightedWBControls_fpGreen2TiltGain_LSByte , 0x2510, 0x0000 }, +{ MinWeightedWBControls_fpGreen2TiltGain_MSByte , 0x250f, 0x3e40 }, +{ MinWeightedWBControls_fpBlueTiltGain_LSByte , 0x2514, 0x0000 }, +{ MinWeightedWBControls_fpBlueTiltGain_MSByte , 0x2513, 0x3e40 }, +{ MinWeightedWBControls_GreenChannelToAccumulate , 0x2516, 0x0000 }, +{ MinWeightedWBStatus_uwZone_X_Offset_LSByte , 0x2582, 0x0000 }, +{ MinWeightedWBStatus_uwZone_X_Offset_MSByte , 0x2581, 0x0000 }, +{ MinWeightedWBStatus_uwZone_Y_Offset_LSByte , 0x2586, 0x0000 }, +{ MinWeightedWBStatus_uwZone_Y_Offset_MSByte , 0x2585, 0x0000 }, +{ MinWeightedWBStatus_uwZone_X_Size_LSByte , 0x258a, 0x0000 }, +{ MinWeightedWBStatus_uwZone_X_Size_MSByte , 0x2589, 0x0000 }, +{ MinWeightedWBStatus_uwZone_Y_Size_LSByte , 0x258e, 0x0000 }, +{ MinWeightedWBStatus_uwZone_Y_Size_MSByte , 0x258d, 0x0000 }, +{ MinWeightedWBStatus_fpNumberMacroPixel_LSByte , 0x2592, 0x0000 }, +{ MinWeightedWBStatus_fpNumberMacroPixel_MSByte , 0x2591, 0x0000 }, +{ MWWBStatisticsStatus_fpRedStatistics_LSByte , 0x2602, 0x0000 }, +{ MWWBStatisticsStatus_fpRedStatistics_MSByte , 0x2601, 0x0000 }, +{ MWWBStatisticsStatus_fpGreenStatistics_LSByte , 0x2606, 0x0000 }, +{ MWWBStatisticsStatus_fpGreenStatistics_MSByte , 0x2605, 0x0000 }, +{ MWWBStatisticsStatus_fpBlueStatistics_LSByte , 0x260a, 0x0000 }, +{ MWWBStatisticsStatus_fpBlueStatistics_MSByte , 0x2609, 0x0000 }, +{ MiscellaneousErrorStatus_bNumberOfEWBStatisticsErrors , 0x2680, 0x0000 }, +{ MiscellaneousErrorStatus_bEWBStatisticsInterruptCount , 0x2682, 0x0000 }, +{ AutomaticFrameRateControl_bMode , 0x2700, 0x0001 }, +{ AutomaticFrameRateControl_bImpliedGainThresholdLow_num , 0x2702, 0x0001 }, +{ AutomaticFrameRateControl_bImpliedGainThresholdLow_den , 0x2704, 0x0001 }, +{ AutomaticFrameRateControl_bImpliedGainThresholdHigh_num , 0x2706, 0x0003 }, +{ AutomaticFrameRateControl_bImpliedGainThresholdHigh_den , 0x2708, 0x0002 }, +{ AutomaticFrameRateControl_bUserMinimumFrameRate_Hz , 0x270a, 0x000f }, +{ AutomaticFrameRateControl_bUserMaximumFrameRate_Hz , 0x270c, 0x001e }, +{ AutomaticFrameRateControl_bRelativeChange_num , 0x270e, 0x0001 }, +{ AutomaticFrameRateControl_bRelativeChange_den , 0x2710, 0x0008 }, +{ AutomaticFrameRateControl_fDivorceMinFrameRateFromMaxIntegration , 0x2712, 0x0001 }, +{ AutomaticFrameRateStatus_fpImpliedGain_LSByte , 0x2782, 0x0000 }, +{ AutomaticFrameRateStatus_fpImpliedGain_MSByte , 0x2781, 0x0000 }, +{ AutomaticFrameRateStatus_uwMaximumFrameLength_lines_LSByte , 0x2786, 0x0000 }, +{ AutomaticFrameRateStatus_uwMaximumFrameLength_lines_MSByte , 0x2785, 0x0000 }, +{ AutomaticFrameRateStatus_uwMinimumFrameLength_lines_LSByte , 0x278a, 0x0000 }, +{ AutomaticFrameRateStatus_uwMinimumFrameLength_lines_MSByte , 0x2789, 0x0000 }, +{ AutomaticFrameRateStatus_uwFrameLengthChange_lines_LSByte , 0x278e, 0x0000 }, +{ AutomaticFrameRateStatus_uwFrameLengthChange_lines_MSByte , 0x278d, 0x0000 }, +{ AutomaticFrameRateStatus_fpDesiredAutomaticFrameRate_Hz_LSByte , 0x2792, 0x0000 }, +{ AutomaticFrameRateStatus_fpDesiredAutomaticFrameRate_Hz_MSByte , 0x2791, 0x0000 }, +{ AutomaticFrameRateStatus_uwCurrentFrameLength_lines_LSByte , 0x2796, 0x0000 }, +{ AutomaticFrameRateStatus_uwCurrentFrameLength_lines_MSByte , 0x2795, 0x0000 }, +{ AutomaticFrameRateStatus_uwDesiredFrameLength_lines_LSByte , 0x279a, 0x0000 }, +{ AutomaticFrameRateStatus_uwDesiredFrameLength_lines_MSByte , 0x2799, 0x0000 }, +{ AutomaticFrameRateStatus_fAutomaticFrameRateStable , 0x279c, 0x0000 }, +{ AutomaticFrameRateStatus_fAutomaticFrameRateClip , 0x279e, 0x0000 }, +{ StaticFrameRateControl_uwDesiredFrameRate_Num_LSByte , 0x2802, 0x0000 }, +{ StaticFrameRateControl_uwDesiredFrameRate_Num_MSByte , 0x2802, 0x001e }, +{ StaticFrameRateControl_bDesiredFrameRate_Den , 0x2804, 0x0001 }, +{ StaticFrameRateStatus_uwRequestedFrameRate_Hz_LSByte , 0x2882, 0x0000 }, +{ StaticFrameRateStatus_uwRequestedFrameRate_Hz_MSByte , 0x2881, 0x0000 }, +{ StaticFrameRateStatus_uwMaxFrameRate_Hz_LSByte , 0x2886, 0x0000 }, +{ StaticFrameRateStatus_uwMaxFrameRate_Hz_MSByte , 0x2885, 0x0000 }, +{ StaticFrameRateStatus_uwMinFrameRate_Hz_LSByte , 0x288a, 0x0000 }, +{ StaticFrameRateStatus_uwMinFrameRate_Hz_MSByte , 0x2889, 0x0000 }, +{ StaticFrameRateStatus_fChangePending , 0x288c, 0x0000 }, +{ StaticFrameRateStatus_uwRequiredFrameLength_lines_LSByte , 0x2890, 0x0000 }, +{ StaticFrameRateStatus_uwRequiredFrameLength_lines_MSByte , 0x288f, 0x0000 }, +{ StaticFrameRateStatus_ClipFrameRate , 0x2892, 0x0000 }, +{ ImageStability_fWhiteBalanceStable , 0x2900, 0x0000 }, +{ ImageStability_fExposureStable , 0x2902, 0x0000 }, +{ ImageStability_fFocusStable , 0x2904, 0x0000 }, +{ ImageStability_fLowPowerStreaming , 0x2906, 0x0000 }, +{ ImageStability_fStable , 0x2908, 0x0000 }, +{ ImageStability_fForcedStablility , 0x290a, 0x0000 }, +{ ImageStabilityMonitorControl_bMaxNumberOfFramesToWaitForStability , 0x2980, 0x0000 }, +{ ColdStartManagerControl_bControlCoin , 0x2a00, 0x0000 }, +{ ColdStartManagerStatus_bStatusCoin , 0x2a80, 0x0000 }, +{ ColourEngine0_ColourMatrixFarSensor_fpRInR_LSByte , 0x2b02, 0x0000 }, +{ ColourEngine0_ColourMatrixFarSensor_fpRInR_MSByte , 0x2b01, 0x3fd3 }, +{ ColourEngine0_ColourMatrixFarSensor_fpGInR_LSByte , 0x2b06, 0x0000 }, +{ ColourEngine0_ColourMatrixFarSensor_fpGInR_MSByte , 0x2b05, 0xbce0 }, +{ ColourEngine0_ColourMatrixFarSensor_fpBInR_LSByte , 0x2b0a, 0x0000 }, +{ ColourEngine0_ColourMatrixFarSensor_fpBInR_MSByte , 0x2b09, 0xb919 }, +{ ColourEngine0_ColourMatrixFarSensor_fpRInG_LSByte , 0x2b0e, 0x0000 }, +{ ColourEngine0_ColourMatrixFarSensor_fpRInG_MSByte , 0x2b0d, 0xba76 }, +{ ColourEngine0_ColourMatrixFarSensor_fpGInG_LSByte , 0x2b12, 0x0000 }, +{ ColourEngine0_ColourMatrixFarSensor_fpGInG_MSByte , 0x2b11, 0x3f7a }, +{ ColourEngine0_ColourMatrixFarSensor_fpBInG_LSByte , 0x2b16, 0x0000 }, +{ ColourEngine0_ColourMatrixFarSensor_fpBInG_MSByte , 0x2b15, 0xbb71 }, +{ ColourEngine0_ColourMatrixFarSensor_fpRInB_LSByte , 0x2b1a, 0x0000 }, +{ ColourEngine0_ColourMatrixFarSensor_fpRInB_MSByte , 0x2b19, 0xb717 }, +{ ColourEngine0_ColourMatrixFarSensor_fpGInB_LSByte , 0x2b1e, 0x0000 }, +{ ColourEngine0_ColourMatrixFarSensor_fpGInB_MSByte , 0x2b1d, 0xbd29 }, +{ ColourEngine0_ColourMatrixFarSensor_fpBInB_LSByte , 0x2b22, 0x0000 }, +{ ColourEngine0_ColourMatrixFarSensor_fpBInB_MSByte , 0x2b21, 0x3fc6 }, +{ ColourEngine0_ColourMatrixNearSensor_fpRInR_LSByte , 0x2b82, 0x0002 }, +{ ColourEngine0_ColourMatrixNearSensor_fpRInR_MSByte , 0x2b81, 0x6400 }, +{ ColourEngine0_ColourMatrixNearSensor_fpGInR_LSByte , 0x2b86, 0x0002 }, +{ ColourEngine0_ColourMatrixNearSensor_fpGInR_MSByte , 0x2b85, 0x6400 }, +{ ColourEngine0_ColourMatrixNearSensor_fpBInR_LSByte , 0x2b8a, 0x0002 }, +{ ColourEngine0_ColourMatrixNearSensor_fpBInR_MSByte , 0x2b89, 0x6400 }, +{ ColourEngine0_ColourMatrixNearSensor_fpRInG_LSByte , 0x2b8e, 0x0004 }, +{ ColourEngine0_ColourMatrixNearSensor_fpRInG_MSByte , 0x2b8d, 0xb200 }, +{ ColourEngine0_ColourMatrixNearSensor_fpGInG_LSByte , 0x2b92, 0x0004 }, +{ ColourEngine0_ColourMatrixNearSensor_fpGInG_MSByte , 0x2b91, 0xb200 }, +{ ColourEngine0_ColourMatrixNearSensor_fpBInG_LSByte , 0x2b96, 0x0004 }, +{ ColourEngine0_ColourMatrixNearSensor_fpBInG_MSByte , 0x2b95, 0xb200 }, +{ ColourEngine0_ColourMatrixNearSensor_fpRInB_LSByte , 0x2b9a, 0x0000 }, +{ ColourEngine0_ColourMatrixNearSensor_fpRInB_MSByte , 0x2b99, 0xe900 }, +{ ColourEngine0_ColourMatrixNearSensor_fpGInB_LSByte , 0x2b9e, 0x0000 }, +{ ColourEngine0_ColourMatrixNearSensor_fpGInB_MSByte , 0x2b9d, 0xe900 }, +{ ColourEngine0_ColourMatrixNearSensor_fpBInB_LSByte , 0x2ba2, 0x0000 }, +{ ColourEngine0_ColourMatrixNearSensor_fpBInB_MSByte , 0x2ba1, 0xe900 }, +{ ColourEngine0_ColourMatrixDamped_wRInR_LSByte , 0x2c02, 0x0000 }, +{ ColourEngine0_ColourMatrixDamped_wRInR_MSByte , 0x2c01, 0x0000 }, +{ ColourEngine0_ColourMatrixDamped_wGInR_LSByte , 0x2c06, 0x0000 }, +{ ColourEngine0_ColourMatrixDamped_wGInR_MSByte , 0x2c05, 0x0000 }, +{ ColourEngine0_ColourMatrixDamped_wBInR_LSByte , 0x2c0a, 0x0000 }, +{ ColourEngine0_ColourMatrixDamped_wBInR_MSByte , 0x2c09, 0x0000 }, +{ ColourEngine0_ColourMatrixDamped_wRInG_LSByte , 0x2c0e, 0x0000 }, +{ ColourEngine0_ColourMatrixDamped_wRInG_MSByte , 0x2c0d, 0x0000 }, +{ ColourEngine0_ColourMatrixDamped_wGInG_LSByte , 0x2c12, 0x0000 }, +{ ColourEngine0_ColourMatrixDamped_wGInG_MSByte , 0x2c11, 0x0000 }, +{ ColourEngine0_ColourMatrixDamped_wBInG_LSByte , 0x2c16, 0x0000 }, +{ ColourEngine0_ColourMatrixDamped_wBInG_MSByte , 0x2c15, 0x0000 }, +{ ColourEngine0_ColourMatrixDamped_wRInB_LSByte , 0x2c1a, 0x0000 }, +{ ColourEngine0_ColourMatrixDamped_wRInB_MSByte , 0x2c19, 0x0000 }, +{ ColourEngine0_ColourMatrixDamped_wGInB_LSByte , 0x2c1e, 0x0000 }, +{ ColourEngine0_ColourMatrixDamped_wGInB_MSByte , 0x2c1d, 0x0000 }, +{ ColourEngine0_ColourMatrixDamped_wBInB_LSByte , 0x2c22, 0x0000 }, +{ ColourEngine0_ColourMatrixDamped_wBInB_MSByte , 0x2c21, 0x0000 }, +{ ColourEngine0_ColourMatrixDamperControl_fDisableMatrixDamping , 0x2c80, 0x0000 }, +{ ColourEngine0_ColourMatrixDamperControl_DamperLowThreshold_LSByte , 0x2c84, 0x0000 }, +{ ColourEngine0_ColourMatrixDamperControl_DamperLowThreshold_MSByte , 0x2c83, 0x62ac }, +{ ColourEngine0_ColourMatrixDamperControl_DamperHighThreshold_LSByte , 0x2c88, 0x0000 }, +{ ColourEngine0_ColourMatrixDamperControl_DamperHighThreshold_MSByte , 0x2c87, 0x64ac }, +{ ColourEngine0_ColourMatrixDamperControl_MinimumDamperOutput_LSByte , 0x2c8c, 0x0000 }, +{ ColourEngine0_ColourMatrixDamperControl_MinimumDamperOutput_MSByte , 0x2c8b, 0x0000 }, +{ ColourEngine0_ApertureCorrectionControls_fDisableCorrection , 0x2d00, 0x0000 }, +{ ColourEngine0_ApertureCorrectionControls_bMaxGain , 0x2d02, 0x0010 }, +{ ColourEngine0_ApertureCorrectionControls_fDisableGainDamping , 0x2d04, 0x0000 }, +{ ColourEngine0_ApertureCorrectionControls_DamperLowThreshold_Gain_LSByte , 0x2d08, 0x0000 }, +{ ColourEngine0_ApertureCorrectionControls_DamperLowThreshold_Gain_MSByte , 0x2d07, 0x5871 }, +{ ColourEngine0_ApertureCorrectionControls_DamperHighThreshold_Gain_LSByte , 0x2d0c, 0x0000 }, +{ ColourEngine0_ApertureCorrectionControls_DamperHighThreshold_Gain_MSByte , 0x2d0b, 0x63d1 }, +{ ColourEngine0_ApertureCorrectionControls_MinimumDamperOutput_Gain_LSByte , 0x2d10, 0x0000 }, +{ ColourEngine0_ApertureCorrectionControls_MinimumDamperOutput_Gain_MSByte , 0x2d0f, 0x3a00 }, +{ ColourEngine0_ApertureCorrectionControls_bMinimumCoringThreshold , 0x2d12, 0x003c }, +{ ColourEngine0_ApertureCorrectionControls_fDisableCoringDamping , 0x2d14, 0x0000 }, +{ ColourEngine0_ApertureCorrectionControls_bMinimumHighThreshold , 0x2d16, 0x0028 }, +{ ColourEngine0_ApertureCorrectionControls_DamperLowThreshold_Coring_LSByte , 0x2d1a, 0x0000 }, +{ ColourEngine0_ApertureCorrectionControls_DamperLowThreshold_Coring_MSByte , 0x2d19, 0x5871 }, +{ ColourEngine0_ApertureCorrectionControls_DamperHighThreshold_Coring_LSByte , 0x2d1e, 0x0000 }, +{ ColourEngine0_ApertureCorrectionControls_DamperHighThreshold_Coring_MSByte , 0x2d1d, 0x63d1 }, +{ ColourEngine0_ApertureCorrectionControls_MinimumDamperOutput_Coring_LSByte , 0x2d22, 0x0000 }, +{ ColourEngine0_ApertureCorrectionControls_MinimumDamperOutput_Coring_MSByte , 0x2d21, 0x3a00 }, +{ ColourEngine0_ApertureCorrectionStatus_bGain , 0x2d80, 0x0000 }, +{ ColourEngine0_ApertureCorrectionStatus_HighThreshold , 0x2d82, 0x0000 }, +{ ColourEngine0_ApertureCorrectionStatus_CoringThreshold , 0x2d84, 0x0000 }, +{ ColourEngine0_GammaCorrection_fEnabled , 0x2e00, 0x0001 }, +{ ColourEngine0_GammaCorrection_bMode , 0x2e02, 0x0001 }, +{ ColourEngine0_GammaCorrection_SharpRed , 0x2e04, 0x0013 }, +{ ColourEngine0_GammaCorrection_SharpGreen , 0x2e06, 0x0013 }, +{ ColourEngine0_GammaCorrection_SharpBlue , 0x2e08, 0x0013 }, +{ ColourEngine0_GammaCorrection_SoftRed , 0x2e0a, 0x0013 }, +{ ColourEngine0_GammaCorrection_SoftGreen , 0x2e0c, 0x0013 }, +{ ColourEngine0_GammaCorrection_SoftBlue , 0x2e0e, 0x0013 }, +{ NoraControls_fDisable , 0x2e80, 0x0001 }, +{ NoraControls_fDisableNoraPromoting , 0x2e82, 0x0000 }, +{ NoraControls_bMaximumValue , 0x2e84, 0x0001 }, +{ NoraControls_fDifferentTextureDegreeForBlue , 0x2e86, 0x0000 }, +{ NoraControls_fSplitNoiseLevel , 0x2e88, 0x0000 }, +{ NoraControls_fTightGreenMatrix , 0x2e8a, 0x0000 }, +{ NoraControls_DamperLowThreshold_LSByte , 0x2e8e, 0x0000 }, +{ NoraControls_DamperLowThreshold_MSByte , 0x2e8d, 0x4000 }, +{ NoraControls_DamperHighThreshold_LSByte , 0x2e92, 0x0000 }, +{ NoraControls_DamperHighThreshold_MSByte , 0x2e91, 0x4500 }, +{ NoraControls_MinimumDamperOutput_LSByte , 0x2e96, 0x0000 }, +{ NoraControls_MinimumDamperOutput_MSByte , 0x2e95, 0x0000 }, +{ NoraStatus_bNoraValue , 0x2f00, 0x0000 }, +{ ScytheFilterControls_fDisableFilter , 0x2f80, 0x0000 }, +{ ScytheFilterControls_fSquareLaw , 0x2f82, 0x0000 }, +{ ScytheFilterControls_fDisablePromotingLow , 0x2f84, 0x0000 }, +{ ScytheFilterControls_fDisablePromotingHigh , 0x2f86, 0x0000 }, +{ ScytheFilterControls_bMaxWeightLow , 0x2f88, 0x0010 }, +{ ScytheFilterControls_bMaxWeightHigh , 0x2f8a, 0x0010 }, +{ ScytheFilterControls_fpDamperLowThresholdLow_LSByte , 0x2f8e, 0x0000 }, +{ ScytheFilterControls_fpDamperLowThresholdLow_MSByte , 0x2f8d, 0x5d0d }, +{ ScytheFilterControls_fpDamperLowThresholdHigh_LSByte , 0x2f92, 0x0000 }, +{ ScytheFilterControls_fpDamperLowThresholdHigh_MSByte , 0x2f91, 0x5d0d }, +{ ScytheFilterControls_fpDamperHighThresholdLow_LSByte , 0x2f96, 0x0000 }, +{ ScytheFilterControls_fpDamperHighThresholdLow_MSByte , 0x2f95, 0x68dc }, +{ ScytheFilterControls_fpDamperHighThresholdHigh_LSByte , 0x2f9a, 0x0000 }, +{ ScytheFilterControls_fpDamperHighThresholdHigh_MSByte , 0x2f99, 0x68dc }, +{ ScytheFilterControls_fpMinimumDamperOutputLow_LSByte , 0x2f9e, 0x0000 }, +{ ScytheFilterControls_fpMinimumDamperOutputLow_MSByte , 0x2f9d, 0x3a00 }, +{ ScytheFilterControls_fpMinimumDamperOutputHigh_LSByte , 0x2fa2, 0x0000 }, +{ ScytheFilterControls_fpMinimumDamperOutputHigh_MSByte , 0x2fa1, 0x3a00 }, +{ JackFilterControls_fDisableFilter , 0x3000, 0x0000 }, +{ JackFilterControls_fSquareLaw , 0x3002, 0x0000 }, +{ JackFilterControls_fDisablePromotingLow , 0x3004, 0x0000 }, +{ JackFilterControls_fDisablePromotingHigh , 0x3006, 0x0000 }, +{ JackFilterControls_bMaxWeightLow , 0x3008, 0x0010 }, +{ JackFilterControls_bMaxWeightHigh , 0x300a, 0x0010 }, +{ JackFilterControls_fpDamperLowThresholdLow_LSByte , 0x300e, 0x0000 }, +{ JackFilterControls_fpDamperLowThresholdLow_MSByte , 0x300d, 0x63d1 }, +{ JackFilterControls_fpDamperLowThresholdHigh_LSByte , 0x3012, 0x0000 }, +{ JackFilterControls_fpDamperLowThresholdHigh_MSByte , 0x3011, 0x63d1 }, +{ JackFilterControls_fpDamperHighThresholdLow_LSByte , 0x3016, 0x0000 }, +{ JackFilterControls_fpDamperHighThresholdLow_MSByte , 0x3015, 0x68dc }, +{ JackFilterControls_fpDamperHighThresholdHigh_LSByte , 0x301a, 0x0000 }, +{ JackFilterControls_fpDamperHighThresholdHigh_MSByte , 0x3019, 0x68dc }, +{ JackFilterControls_fpMinimumDamperOutputLow_LSByte , 0x301e, 0x0000 }, +{ JackFilterControls_fpMinimumDamperOutputLow_MSByte , 0x301d, 0x0000 }, +{ JackFilterControls_fpMinimumDamperOutputHigh_LSByte , 0x3022, 0x0000 }, +{ JackFilterControls_fpMinimumDamperOutputHigh_MSByte , 0x3021, 0x0000 }, +{ ScytheAndJackFilterStatus_bScytheWeightLo , 0x3080, 0x0000 }, +{ ScytheAndJackFilterStatus_bScytheWeightHi , 0x3082, 0x0000 }, +{ ScytheAndJackFilterStatus_bJackWeightLo , 0x3084, 0x0000 }, +{ ScytheAndJackFilterStatus_bJackWeightHi , 0x3086, 0x0000 }, +{ VfpnControls_fEnableCorrection , 0x3100, 0x0000 }, +{ VfpnControls_uwMaximumPixelValue_LSByte , 0x3104, 0x0000 }, +{ VfpnControls_uwMaximumPixelValue_MSByte , 0x3103, 0x03ff }, +{ VfpnControls_uwMinimumPixelValue_LSByte , 0x3108, 0x0000 }, +{ VfpnControls_uwMinimumPixelValue_MSByte , 0x3107, 0x0000 }, +{ VfpnControls_uwPixelSaturationLevel_LSByte , 0x310c, 0x0000 }, +{ VfpnControls_uwPixelSaturationLevel_MSByte , 0x310b, 0x03ff }, +{ VfpnControls_bLogThreshLog , 0x310e, 0x0004 }, +{ VfpnStatus_fLowPowerStreaming , 0x3180, 0x0000 }, +{ VfpnStatus_fVfpnGainChanged , 0x3182, 0x0000 }, +{ VfpnStatus_bNumberOfBlackLines , 0x3184, 0x0000 }, +{ VfpnStatus_uwNumberOfActivePixels_LSByte , 0x3188, 0x0000 }, +{ VfpnStatus_uwNumberOfActivePixels_MSByte , 0x3187, 0x0000 }, +{ AntiVignetteControls_fDisableFilter , 0x3200, 0x0000 }, +{ AntiVignetteControls_bFilterCoeff_R2_r , 0x3202, 0x0000 }, +{ AntiVignetteControls_bFilterCoeff_R2_gr , 0x3204, 0x0080 }, +{ AntiVignetteControls_bFilterCoeff_R2_gb , 0x3206, 0x0080 }, +{ AntiVignetteControls_bFilterCoeff_R2_b , 0x3208, 0x0000 }, +{ AntiVignetteControls_bFilterCoeff_R4_r , 0x320a, 0x0000 }, +{ AntiVignetteControls_bFilterCoeff_R4_gr , 0x320c, 0x0000 }, +{ AntiVignetteControls_bFilterCoeff_R4_gb , 0x320e, 0x0000 }, +{ AntiVignetteControls_bFilterCoeff_R4_b , 0x3210, 0x0000 }, +{ AntiVignetteControls_uwHorizontalOffset_LSByte , 0x3214, 0x0000 }, +{ AntiVignetteControls_uwHorizontalOffset_MSByte , 0x3213, 0x0000 }, +{ AntiVignetteControls_uwVerticalOffset_LSByte , 0x3218, 0x0000 }, +{ AntiVignetteControls_uwVerticalOffset_MSByte , 0x3217, 0x0000 }, +{ AntiVignetteControls_fAVOffsetSeperateFor4Channels , 0x321a, 0x0001 }, +{ AntiVignetteControls_bShiftFix_R2 , 0x321c, 0x0012 }, +{ AntiVignetteControls_uwHorizontalOffset_r_LSByte , 0x3220, 0x0000 }, +{ AntiVignetteControls_uwHorizontalOffset_r_MSByte , 0x321f, 0x0000 }, +{ AntiVignetteControls_uwHorizontalOffset_gr_LSByte , 0x3224, 0x0000 }, +{ AntiVignetteControls_uwHorizontalOffset_gr_MSByte , 0x3223, 0x0000 }, +{ AntiVignetteControls_uwHorizontalOffset_gb_LSByte , 0x3228, 0x0000 }, +{ AntiVignetteControls_uwHorizontalOffset_gb_MSByte , 0x3227, 0x0000 }, +{ AntiVignetteControls_uwHorizontalOffset_b_LSByte , 0x322c, 0x0000 }, +{ AntiVignetteControls_uwHorizontalOffset_b_MSByte , 0x322b, 0x0000 }, +{ AntiVignetteControls_uwVerticalOffset_r_LSByte , 0x3230, 0x0000 }, +{ AntiVignetteControls_uwVerticalOffset_r_MSByte , 0x3200, 0x002f }, +{ AntiVignetteControls_uwVerticalOffset_gr_LSByte , 0x3234, 0x0000 }, +{ AntiVignetteControls_uwVerticalOffset_gr_MSByte , 0x3233, 0x0000 }, +{ AntiVignetteControls_uwVerticalOffset_gb_LSByte , 0x3238, 0x0000 }, +{ AntiVignetteControls_uwVerticalOffset_gb_MSByte , 0x3237, 0x0000 }, +{ AntiVignetteControls_uwVerticalOffset_b_LSByte , 0x323c, 0x0000 }, +{ AntiVignetteControls_uwVerticalOffset_b_MSByte , 0x323b, 0x0000 }, +{ AntiVignetteControls_bUnityOffset_r , 0x323e, 0x0040 }, +{ AntiVignetteControls_bUnityOffset_gr , 0x3240, 0x0040 }, +{ AntiVignetteControls_bUnityOffset_gb , 0x3242, 0x0040 }, +{ AntiVignetteControls_bUnityOffset_b , 0x3244, 0x0040 }, +{ AntiVignetteControls_fAdaptiveAntiVignetteEnable , 0x3246, 0x0001 }, +{ AntiVignetteStatus_fXScaleEnabled , 0x3280, 0x0000 }, +{ AntiVignetteStatus_bXScale , 0x3282, 0x0000 }, +{ AntiVignetteStatus_fYScaleEnabled , 0x3284, 0x0000 }, +{ AntiVignetteStatus_bYScale , 0x3286, 0x0000 }, +{ AntiVignetteStatus_uwHorizontalSize_LSByte , 0x328a, 0x0000 }, +{ AntiVignetteStatus_uwHorizontalSize_MSByte , 0x3289, 0x0000 }, +{ AntiVignetteStatus_uwVerticalSize_LSByte , 0x328e, 0x0000 }, +{ AntiVignetteStatus_uwVerticalSize_MSByte , 0x328d, 0x0000 }, +{ ColourEngine0_RadialApertureCorrectionControl_fEnableCorrection , 0x3300, 0x0000 }, +{ ColourEngine0_RadialApertureCorrectionHostInputs_bQvec0 , 0x3380, 0x0010 }, +{ ColourEngine0_RadialApertureCorrectionHostInputs_bQvec1 , 0x3382, 0x003f }, +{ ColourEngine0_RadialApertureCorrectionHostInputs_bCofShift , 0x3384, 0x0000 }, +{ ColourEngine0_RadialApertureCorrectionHostInputs_bOutShift , 0x3386, 0x0003 }, +{ ColourEngine0_RadialApertureCorrectionHostInputs_uwUnity_LSByte , 0x338a, 0x0000 }, +{ ColourEngine0_RadialApertureCorrectionHostInputs_uwUnity_MSByte , 0x3389, 0x0001 }, +{ ColourEngine0_RadialApertureCorrectionApplicationInputs_uwHOffset_LSByte , 0x3402, 0x0000 }, +{ ColourEngine0_RadialApertureCorrectionApplicationInputs_uwHOffset_MSByte , 0x3401, 0x0000 }, +{ ColourEngine0_RadialApertureCorrectionApplicationInputs_uwVOffset_LSByte , 0x3406, 0x0000 }, +{ ColourEngine0_RadialApertureCorrectionApplicationInputs_uwVOffset_MSByte , 0x3405, 0x0000 }, +{ ColourEngine0_RadialApertureCorrectionApplicationInputs_uwHScalingFactor_LSByte , 0x340a, 0x0000 }, +{ ColourEngine0_RadialApertureCorrectionApplicationInputs_uwHScalingFactor_MSByte , 0x3409, 0x0000 }, +{ ColourEngine0_RadialApertureCorrectionApplicationInputs_uwVScalingFactor_LSByte , 0x340e, 0x0000 }, +{ ColourEngine0_RadialApertureCorrectionApplicationInputs_uwVScalingFactor_MSByte , 0x340d, 0x0000 }, +{ ColourEngine0_OutputCoderControls_TransformType , 0x3480, 0x0001 }, +{ ColourEngine0_OutputCoderControls_bContrast , 0x3482, 0x0064 }, +{ ColourEngine0_OutputCoderControls_bColourSaturation , 0x3484, 0x0069 }, +{ ColourEngine0_CoderOutputSignalRange_uwLumaExcursion_LSByte , 0x3502, 0x0000 }, +{ ColourEngine0_CoderOutputSignalRange_uwLumaExcursion_MSByte , 0x3501, 0x0000 }, +{ ColourEngine0_CoderOutputSignalRange_uwLumaMidpointTimes2_LSByte , 0x3506, 0x0000 }, +{ ColourEngine0_CoderOutputSignalRange_uwLumaMidpointTimes2_MSByte , 0x3505, 0x0000 }, +{ ColourEngine0_CoderOutputSignalRange_uwChromaExcursion_LSByte , 0x350a, 0x0000 }, +{ ColourEngine0_CoderOutputSignalRange_uwChromaExcursion_MSByte , 0x3509, 0x0000 }, +{ ColourEngine0_CoderOutputSignalRange_uwChromaMidpointTimes2_LSByte , 0x350e, 0x0000 }, +{ ColourEngine0_CoderOutputSignalRange_uwChromaMidpointTimes2_MSByte , 0x350d, 0x0000 }, +{ ColourEngine0_OutputCoderOffsetVector_i0_LSByte , 0x3582, 0x0000 }, +{ ColourEngine0_OutputCoderOffsetVector_i0_MSByte , 0x3581, 0x0000 }, +{ ColourEngine0_OutputCoderOffsetVector_i1_LSByte , 0x3586, 0x0000 }, +{ ColourEngine0_OutputCoderOffsetVector_i1_MSByte , 0x3585, 0x0000 }, +{ ColourEngine0_OutputCoderOffsetVector_i2_LSByte , 0x358a, 0x0000 }, +{ ColourEngine0_OutputCoderOffsetVector_i2_MSByte , 0x3589, 0x0000 }, +{ ColourEngine0_OutputCoderMatrix_w0_0_LSByte , 0x3602, 0x0000 }, +{ ColourEngine0_OutputCoderMatrix_w0_0_MSByte , 0x3601, 0x0000 }, +{ ColourEngine0_OutputCoderMatrix_w0_1_LSByte , 0x3606, 0x0000 }, +{ ColourEngine0_OutputCoderMatrix_w0_1_MSByte , 0x3605, 0x0000 }, +{ ColourEngine0_OutputCoderMatrix_w0_2_LSByte , 0x360a, 0x0000 }, +{ ColourEngine0_OutputCoderMatrix_w0_2_MSByte , 0x3609, 0x0000 }, +{ ColourEngine0_OutputCoderMatrix_w1_0_LSByte , 0x360e, 0x0000 }, +{ ColourEngine0_OutputCoderMatrix_w1_0_MSByte , 0x360d, 0x0000 }, +{ ColourEngine0_OutputCoderMatrix_w1_1_LSByte , 0x3612, 0x0000 }, +{ ColourEngine0_OutputCoderMatrix_w1_1_MSByte , 0x3611, 0x0000 }, +{ ColourEngine0_OutputCoderMatrix_w1_2_LSByte , 0x3616, 0x0000 }, +{ ColourEngine0_OutputCoderMatrix_w1_2_MSByte , 0x3615, 0x0000 }, +{ ColourEngine0_OutputCoderMatrix_w2_0_LSByte , 0x361a, 0x0000 }, +{ ColourEngine0_OutputCoderMatrix_w2_0_MSByte , 0x3619, 0x0000 }, +{ ColourEngine0_OutputCoderMatrix_w2_1_LSByte , 0x361e, 0x0000 }, +{ ColourEngine0_OutputCoderMatrix_w2_1_MSByte , 0x361d, 0x0000 }, +{ ColourEngine0_OutputCoderMatrix_w2_2_LSByte , 0x3622, 0x0000 }, +{ ColourEngine0_OutputCoderMatrix_w2_2_MSByte , 0x3621, 0x0000 }, +{ ColourEngine0_FadeToBlack_fDisable , 0x3680, 0x0001 }, +{ ColourEngine0_FadeToBlack_fpBlackValue_LSByte , 0x3684, 0x0000 }, +{ ColourEngine0_FadeToBlack_fpBlackValue_MSByte , 0x3683, 0x0000 }, +{ ColourEngine0_FadeToBlack_fpDamperLowThreshold_LSByte , 0x3688, 0x0000 }, +{ ColourEngine0_FadeToBlack_fpDamperLowThreshold_MSByte , 0x3687, 0x63d1 }, +{ ColourEngine0_FadeToBlack_fpDamperHighThreshold_LSByte , 0x368c, 0x0000 }, +{ ColourEngine0_FadeToBlack_fpDamperHighThreshold_MSByte , 0x368b, 0x656f }, +{ ColourEngine0_FadeToBlack_fpDamperOutput_LSByte , 0x3690, 0x0000 }, +{ ColourEngine0_FadeToBlack_fpDamperOutput_MSByte , 0x368f, 0x0000 }, +{ ScalerLimits_uwPipe0MinStep_LSByte , 0x3702, 0x0000 }, +{ ScalerLimits_uwPipe0MinStep_MSByte , 0x3701, 0x0000 }, +{ ScalerLimits_uwPipe0MaxStep_LSByte , 0x3706, 0x0000 }, +{ ScalerLimits_uwPipe0MaxStep_MSByte , 0x3705, 0x0000 }, +{ ZoomMgrParams_fAntiZip , 0x3780, 0x0000 }, +{ ZoomMgrParams_bFilterCrispness0 , 0x3782, 0x0000 }, +{ ZoomMgrParams_bFilterCrispness1 , 0x3784, 0x0000 }, +{ ZoomMgrParams_fInFromOutARLock , 0x3786, 0x0000 }, +{ ZoomMgrParams_bPrescaleFactor , 0x3788, 0x0000 }, +{ ZoomMgrParams_bPrescaleType , 0x378a, 0x0000 }, +{ ZoomMgrParams_fp16ZoomRange_LSByte , 0x378e, 0x0000 }, +{ ZoomMgrParams_fp16ZoomRange_MSByte , 0x378d, 0x100 }, +{ ZoomMgrCtrl_bHostTestCoin , 0x3800, 0x0001 }, +{ ZoomMgrCtrl_bZoomCmd , 0x3802, 0x0000 }, +{ ZoomMgrCtrl_fChgOverForbidden , 0x3804, 0x0000 }, +{ ZoomMgrCtrl_fAutoZoom , 0x3806, 0x0000 }, +{ ZoomMgrCtrl_bStepFramePeriod , 0x3808, 0x0000 }, +{ ZoomMgrCtrl_bMagFactor , 0x380a, 0x0014},//0x000a }, +{ ZoomMgrCtrl_bChgOverMarginShift , 0x380c, 0x0000 }, +{ ZoomMgrCtrl_fCheckDataRate , 0x380e, 0x0000 }, +{ ZoomMgrCtrl_fSetAlternateInitWOI , 0x3810, 0x0000 }, +{ ZoomMgrCtrl_fSetX_Byte0 , 0x3812, 0x0000 }, +{ ZoomMgrCtrl_fSetX_Byte1 , 0x3814, 0x0000 }, +{ ZoomMgrCtrl_fSetX_Byte2 , 0x3816, 0x0000 }, +{ ZoomMgrCtrl_fSetX_Byte3 , 0x3818, 0x0000 }, +{ ZoomMgrCtrl_fp16P0ScaleLowLimit_LSByte , 0x381c, 0x0000 }, +{ ZoomMgrCtrl_fp16P0ScaleLowLimit_MSByte , 0x381b, 0x0000 }, +{ ZoomMgrCtrl_fp16P1ScaleLowLimit_LSByte , 0x3820, 0x0000 }, +{ ZoomMgrCtrl_fp16P1ScaleLowLimit_MSByte , 0x381f, 0x0000 }, +{ ZoomMgrStatus_fReady , 0x3880, 0x0000 }, +{ ZoomMgrStatus_bDeviceTestCoin , 0x3882, 0x0000 }, +{ ZoomMgrStatus_bNextCmd , 0x3884, 0x0000 }, +{ ZoomMgrStatus_bLastCmd , 0x3886, 0x0000 }, +{ ZoomMgrStatus_bCommandStatus , 0x3888, 0x0000 }, +{ ZoomMgrStatus_bZoomOpStatus , 0x388a, 0x0000 }, +{ ZoomMgrStatus_fFOVX_Byte0 , 0x388c, 0x0000 }, +{ ZoomMgrStatus_fFOVX_Byte1 , 0x388e, 0x0000 }, +{ ZoomMgrStatus_fFOVX_Byte2 , 0x3890, 0x0000 }, +{ ZoomMgrStatus_fFOVX_Byte3 , 0x3892, 0x0000 }, +{ ZoomMgrStatus_fFOVY_Byte0 , 0x3894, 0x0000 }, +{ ZoomMgrStatus_fFOVY_Byte1 , 0x3896, 0x0000 }, +{ ZoomMgrStatus_fFOVY_Byte2 , 0x3898, 0x0000 }, +{ ZoomMgrStatus_fFOVY_Byte3 , 0x389a, 0x0000 }, +{ ZoomMgrStatus_bPrescaleType , 0x389c, 0x0000 }, +{ ZoomMgrStatus_fPrescaleFactor_Byte0 , 0x389e, 0x0000 }, +{ ZoomMgrStatus_fPrescaleFactor_Byte1 , 0x38a0, 0x0000 }, +{ ZoomMgrStatus_fPrescaleFactor_Byte2 , 0x38a2, 0x0000 }, +{ ZoomMgrStatus_fPrescaleFactor_Byte3 , 0x38a4, 0x0000 }, +{ ZoomMgrStatus_boPipe0NoPrescale , 0x38a6, 0x0000 }, +{ ZoomMgrStatus_bZoomPosition , 0x38a8, 0x0000 }, +{ ZoomMgrStatus_fMaxFOVX_Byte0 , 0x38aa, 0x0000 }, +{ ZoomMgrStatus_fMaxFOVX_Byte1 , 0x38ac, 0x0000 }, +{ ZoomMgrStatus_fMaxFOVX_Byte2 , 0x38ae, 0x0000 }, +{ ZoomMgrStatus_fMaxFOVX_Byte3 , 0x38b0, 0x0000 }, +{ ZoomMgrStatus_fMinFOVX_Byte0 , 0x38b2, 0x0000 }, +{ ZoomMgrStatus_fMinFOVX_Byte1 , 0x38b4, 0x0000 }, +{ ZoomMgrStatus_fMinFOVX_Byte2 , 0x38b6, 0x0000 }, +{ ZoomMgrStatus_fMinFOVX_Byte3 , 0x38b8, 0x0000 }, +{ ZoomMgrStatus_uwXOrigin_LSByte , 0x38bc, 0x0000 }, +{ ZoomMgrStatus_uwXOrigin_MSByte , 0x38bb, 0x0000 }, +{ ZoomMgrStatus_uwYOrigin_LSByte , 0x38c0, 0x0000 }, +{ ZoomMgrStatus_uwYOrigin_MSByte , 0x38bf, 0x0000 }, +{ WhiteBalanceConstrainerControls_fpRedA_LSByte , 0x3902, 0x0000 }, +{ WhiteBalanceConstrainerControls_fpRedA_MSByte , 0x3901, 0x0000 }, +{ WhiteBalanceConstrainerControls_fpBlueA_LSByte , 0x3906, 0x0000 }, +{ WhiteBalanceConstrainerControls_fpBlueA_MSByte , 0x3905, 0x0000 }, +{ WhiteBalanceConstrainerControls_fpRedB_LSByte , 0x390a, 0x0000 }, +{ WhiteBalanceConstrainerControls_fpRedB_MSByte , 0x3909, 0x3af2 }, +{ WhiteBalanceConstrainerControls_fpBlueB_LSByte , 0x390e, 0x0000 }, +{ WhiteBalanceConstrainerControls_fpBlueB_MSByte , 0x390d, 0x3acf }, +{ WhiteBalanceConstrainerControls_fpMaximumDistanceAllowedFromLocus_LSByte , 0x3912, 0x0000 }, +{ WhiteBalanceConstrainerControls_fpMaximumDistanceAllowedFromLocus_MSByte , 0x3911, 0x2e8e }, +{ WhiteBalanceConstrainerControls_fEnableConstrainedWhiteBalance , 0x3914, 0x0001 }, +{ WhiteBalanceConstrainerOutput_fpOutputRedGain_LSByte , 0x3982, 0x0000 }, +{ WhiteBalanceConstrainerOutput_fpOutputRedGain_MSByte , 0x3981, 0x0000 }, +{ WhiteBalanceConstrainerOutput_fpOutputGreenGain_LSByte , 0x3986, 0x0000 }, +{ WhiteBalanceConstrainerOutput_fpOutputGreenGain_MSByte , 0x3985, 0x0000 }, +{ WhiteBalanceConstrainerOutput_fpOutputBlueGain_LSByte , 0x398a, 0x0000 }, +{ WhiteBalanceConstrainerOutput_fpOutputBlueGain_MSByte , 0x3989, 0x0000 }, +{ WhiteBalanceConstrainerOutput_fAreGainsConstrained , 0x398c, 0x0000 }, +{ WhiteBalanceConstrainerInternal_fpGradientOfLocusAB_LSByte , 0x3a02, 0x0000 }, +{ WhiteBalanceConstrainerInternal_fpGradientOfLocusAB_MSByte , 0x3a01, 0x0000 }, +{ WhiteBalanceConstrainerInternal_fpDistanceOfInputPointFromLocusAB_LSByte , 0x3a06, 0x0000 }, +{ WhiteBalanceConstrainerInternal_fpDistanceOfInputPointFromLocusAB_MSByte , 0x3a05, 0x0000 }, +{ WhiteBalanceConstrainerInternal_fpConstrainedRedPoint_LSByte , 0x3a0a, 0x0000 }, +{ WhiteBalanceConstrainerInternal_fpConstrainedRedPoint_MSByte , 0x3a09, 0x0000 }, +{ WhiteBalanceConstrainerInternal_fpConstrainedBluePoint_LSByte , 0x3a0e, 0x0000 }, +{ WhiteBalanceConstrainerInternal_fpConstrainedBluePoint_MSByte , 0x3a0d, 0x0000 }, +{ ModeSetupBank1_uwInputImageSize_X_LSByte , 0x3a82, 0x0000 }, +{ ModeSetupBank1_uwInputImageSize_X_MSByte , 0x3a81, 0x0000 }, +{ ModeSetupBank1_uwInputImageSize_Y_LSByte , 0x3a86, 0x0000 }, +{ ModeSetupBank1_uwInputImageSize_Y_MSByte , 0x3a85, 0x0000 }, +{ ModeSetupBank1_uwMaxImageSize_X_LSByte , 0x3a8a, 0x0000 }, +{ ModeSetupBank1_uwMaxImageSize_X_MSByte , 0x3a89, 0x0000 }, +{ ModeSetupBank1_uwMaxImageSize_Y_LSByte , 0x3a8e, 0x0000 }, +{ ModeSetupBank1_uwMaxImageSize_Y_MSByte , 0x3a8d, 0x0000 }, +{ ModeSetupBank1_uwMinImageSize_X_LSByte , 0x3a92, 0x0000 }, +{ ModeSetupBank1_uwMinImageSize_X_MSByte , 0x3a91, 0x0000 }, +{ ModeSetupBank1_uwMinImageSize_Y_LSByte , 0x3a96, 0x0000 }, +{ ModeSetupBank1_uwMinImageSize_Y_MSByte , 0x3a95, 0x0000 }, +{ ModeSetupBank1_bActiveSensor , 0x3a98, 0x0002 }, +{ ModeSetupBank1_fLowPowerStreaming , 0x3a9a, 0x0000 }, +{ ModeSetupBank1_bTestMode , 0x3a9c, 0x0000 }, +{ ModeSetupBank1_bNumberOfStatusLines , 0x3a9e, 0x0000 }, +{ ModeSetupBank1_bNumberOfDarkLines , 0x3aa0, 0x0000 }, +{ ModeSetupBank1_bNumberOfBlackLines , 0x3aa2, 0x0000 }, +{ ModeSetupBank1_uwNumberOfInterLinePixelClocks_LSByte , 0x3aa6, 0x0000 }, +{ ModeSetupBank1_uwNumberOfInterLinePixelClocks_MSByte , 0x3aa5, 0x0000 }, +{ ModeSetupBank1_uwNumberOfInterFrameLines_LSByte , 0x3aaa, 0x0000 }, +{ ModeSetupBank1_uwNumberOfInterFrameLines_MSByte , 0x3aa9, 0x0000 }, +{ ModeSetupBank1_bNumberOfDummyColumns , 0x3aac, 0x0000 }, +{ ModeSetupBank1_bInputImageSource , 0x3aae, 0x0000 }, +{ ModeSetupBank1_bOutputImageDestination , 0x3ab0, 0x0000 }, +{ DummyPage3_bDummyPageElement , 0x3b00, 0x0000 }, +{ DummyPage4_bDummyPageElement , 0x3b80, 0x0000 }, +{ AntiVignetteControlsFar_fDisableFilter , 0x3c00, 0x0001 }, +{ AntiVignetteControlsFar_bFilterCoeff_R2_r , 0x3c02, 0x0000 }, +{ AntiVignetteControlsFar_bFilterCoeff_R2_gr , 0x3c04, 0x0000 }, +{ AntiVignetteControlsFar_bFilterCoeff_R2_gb , 0x3c06, 0x0000 }, +{ AntiVignetteControlsFar_bFilterCoeff_R2_b , 0x3c08, 0x0000 }, +{ AntiVignetteControlsFar_bFilterCoeff_R4_r , 0x3c0a, 0x0000 }, +{ AntiVignetteControlsFar_bFilterCoeff_R4_gr , 0x3c0c, 0x0000 }, +{ AntiVignetteControlsFar_bFilterCoeff_R4_gb , 0x3c0e, 0x0000 }, +{ AntiVignetteControlsFar_bFilterCoeff_R4_b , 0x3c10, 0x0000 }, +{ AntiVignetteControlsFar_uwHorizontalOffset_LSByte , 0x3c14, 0x0000 }, +{ AntiVignetteControlsFar_uwHorizontalOffset_MSByte , 0x3c13, 0x0000 }, +{ AntiVignetteControlsFar_uwVerticalOffset_LSByte , 0x3c18, 0x0000 }, +{ AntiVignetteControlsFar_uwVerticalOffset_MSByte , 0x3c17, 0x0000 }, +{ AntiVignetteControlsFar_fAVOffsetSeperateFor4Channels , 0x3c1a, 0x0000 }, +{ AntiVignetteControlsFar_bShiftFix_R2 , 0x3c1c, 0x0000 }, +{ AntiVignetteControlsFar_uwHorizontalOffset_r_LSByte , 0x3c20, 0x0000 }, +{ AntiVignetteControlsFar_uwHorizontalOffset_r_MSByte , 0x3c1f, 0x0000 }, +{ AntiVignetteControlsFar_uwHorizontalOffset_gr_LSByte , 0x3c24, 0x0000 }, +{ AntiVignetteControlsFar_uwHorizontalOffset_gr_MSByte , 0x3c23, 0x0000 }, +{ AntiVignetteControlsFar_uwHorizontalOffset_gb_LSByte , 0x3c28, 0x0000 }, +{ AntiVignetteControlsFar_uwHorizontalOffset_gb_MSByte , 0x3c27, 0x0000 }, +{ AntiVignetteControlsFar_uwHorizontalOffset_b_LSByte , 0x3c2c, 0x0000 }, +{ AntiVignetteControlsFar_uwHorizontalOffset_b_MSByte , 0x3c2b, 0x0000 }, +{ AntiVignetteControlsFar_uwVerticalOffset_r_LSByte , 0x3c30, 0x0000 }, +{ AntiVignetteControlsFar_uwVerticalOffset_r_MSByte , 0x3c2f, 0x0000 }, +{ AntiVignetteControlsFar_uwVerticalOffset_gr_LSByte , 0x3c34, 0x0000 }, +{ AntiVignetteControlsFar_uwVerticalOffset_gr_MSByte , 0x3c33, 0x0000 }, +{ AntiVignetteControlsFar_uwVerticalOffset_gb_LSByte , 0x3c38, 0x0000 }, +{ AntiVignetteControlsFar_uwVerticalOffset_gb_MSByte , 0x3c37, 0x0000 }, +{ AntiVignetteControlsFar_uwVerticalOffset_b_LSByte , 0x3c3c, 0x0000 }, +{ AntiVignetteControlsFar_uwVerticalOffset_b_MSByte , 0x3c3b, 0x0000 }, +{ AntiVignetteControlsFar_bUnityOffset_r , 0x3c3e, 0x0000 }, +{ AntiVignetteControlsFar_bUnityOffset_gr , 0x3c40, 0x0000 }, +{ AntiVignetteControlsFar_bUnityOffset_gb , 0x3c42, 0x0000 }, +{ AntiVignetteControlsFar_bUnityOffset_b , 0x3c44, 0x0000 }, +{ AntiVignetteControlsFar_fAdaptiveAntiVignetteEnable , 0x3c46, 0x0000 }, +{ AntiVignetteControlsNear_fDisableFilter , 0x3c80, 0x0001 }, +{ AntiVignetteControlsNear_bFilterCoeff_R2_r , 0x3c82, 0x0000 }, +{ AntiVignetteControlsNear_bFilterCoeff_R2_gr , 0x3c84, 0x0000 }, +{ AntiVignetteControlsNear_bFilterCoeff_R2_gb , 0x3c86, 0x0000 }, +{ AntiVignetteControlsNear_bFilterCoeff_R2_b , 0x3c88, 0x0000 }, +{ AntiVignetteControlsNear_bFilterCoeff_R4_r , 0x3c8a, 0x0000 }, +{ AntiVignetteControlsNear_bFilterCoeff_R4_gr , 0x3c8c, 0x0000 }, +{ AntiVignetteControlsNear_bFilterCoeff_R4_gb , 0x3c8e, 0x0000 }, +{ AntiVignetteControlsNear_bFilterCoeff_R4_b , 0x3c90, 0x0000 }, +{ AntiVignetteControlsNear_uwHorizontalOffset_LSByte , 0x3c94, 0x0000 }, +{ AntiVignetteControlsNear_uwHorizontalOffset_MSByte , 0x3c93, 0x0000 }, +{ AntiVignetteControlsNear_uwVerticalOffset_LSByte , 0x3c98, 0x0000 }, +{ AntiVignetteControlsNear_uwVerticalOffset_MSByte , 0x3c97, 0x0000 }, +{ AntiVignetteControlsNear_fAVOffsetSeperateFor4Channels , 0x3c9a, 0x0000 }, +{ AntiVignetteControlsNear_bShiftFix_R2 , 0x3c9c, 0x0000 }, +{ AntiVignetteControlsNear_uwHorizontalOffset_r_LSByte , 0x3ca0, 0x0000 }, +{ AntiVignetteControlsNear_uwHorizontalOffset_r_MSByte , 0x3c9f, 0x0000 }, +{ AntiVignetteControlsNear_uwHorizontalOffset_gr_LSByte , 0x3ca4, 0x0000 }, +{ AntiVignetteControlsNear_uwHorizontalOffset_gr_MSByte , 0x3ca3, 0x0000 }, +{ AntiVignetteControlsNear_uwHorizontalOffset_gb_LSByte , 0x3ca8, 0x0000 }, +{ AntiVignetteControlsNear_uwHorizontalOffset_gb_MSByte , 0x3ca7, 0x0000 }, +{ AntiVignetteControlsNear_uwHorizontalOffset_b_LSByte , 0x3cac, 0x0000 }, +{ AntiVignetteControlsNear_uwHorizontalOffset_b_MSByte , 0x3cab, 0x0000 }, +{ AntiVignetteControlsNear_uwVerticalOffset_r_LSByte , 0x3cb0, 0x0000 }, +{ AntiVignetteControlsNear_uwVerticalOffset_r_MSByte , 0x3caf, 0x0000 }, +{ AntiVignetteControlsNear_uwVerticalOffset_gr_LSByte , 0x3cb4, 0x0000 }, +{ AntiVignetteControlsNear_uwVerticalOffset_gr_MSByte , 0x3cb3, 0x0000 }, +{ AntiVignetteControlsNear_uwVerticalOffset_gb_LSByte , 0x3cb8, 0x0000 }, +{ AntiVignetteControlsNear_uwVerticalOffset_gb_MSByte , 0x3cb7, 0x0000 }, +{ AntiVignetteControlsNear_uwVerticalOffset_b_LSByte , 0x3cbc, 0x0000 }, +{ AntiVignetteControlsNear_uwVerticalOffset_b_MSByte , 0x3cbb, 0x0000 }, +{ AntiVignetteControlsNear_bUnityOffset_r , 0x3cbe, 0x0000 }, +{ AntiVignetteControlsNear_bUnityOffset_gr , 0x3cc0, 0x0000 }, +{ AntiVignetteControlsNear_bUnityOffset_gb , 0x3cc2, 0x0000 }, +{ AntiVignetteControlsNear_bUnityOffset_b , 0x3cc4, 0x0000 }, +{ AntiVignetteControlsNear_fAdaptiveAntiVignetteEnable , 0x3cc6, 0x0000 }, +{ AFStatsControls_fAbsSquareEnabled , 0x3d00, 0x0000 }, +{ AFStatsControls_bCoringValue , 0x3d02, 0x0000 }, +{ AFStatsControls_bWindowsSystem , 0x3d04, 0x0000 }, +{ AFStatsControls_bHRatio_Num , 0x3d06, 0x0000 }, +{ AFStatsControls_bHRatio_Den , 0x3d08, 0x0000 }, +{ AFStatsControls_bVRatio_Num , 0x3d0a, 0x0000 }, +{ AFStatsControls_bVRatio_Den , 0x3d0c, 0x0000 }, +{ AFStatsControls_bHostActiveZonesCounter , 0x3d0e, 0x0000 }, +{ AFStatsControls_fAutoRefresh , 0x3d10, 0x0000 }, +{ AFStatsStatus_bAFStats_Error , 0x3d80, 0x0000 }, +{ AFStatsStatus_fAbsSquareEnabled , 0x3d82, 0x0000 }, +{ AFStatsStatus_bCoringValue , 0x3d84, 0x0000 }, +{ AFStatsStatus_bWindowsSystem , 0x3d86, 0x0000 }, +{ AFStatsStatus_bActiveZonesCounter , 0x3d88, 0x0000 }, +{ AFStatsStatus_bHRatio_Num , 0x3d8a, 0x0000 }, +{ AFStatsStatus_bHRatio_Den , 0x3d8c, 0x0000 }, +{ AFStatsStatus_bVRatio_Num , 0x3d8e, 0x0000 }, +{ AFStatsStatus_bVRatio_Den , 0x3d90, 0x0000 }, +{ AFStatsStatus_uwWOI_Width_LSByte , 0x3d94, 0x0000 }, +{ AFStatsStatus_uwWOI_Width_MSByte , 0x3d93, 0x0000 }, +{ AFStatsStatus_uwWOI_Height_LSByte , 0x3d98, 0x0000 }, +{ AFStatsStatus_uwWOI_Height_MSByte , 0x3d97, 0x0000 }, +{ AFStatsStatus_uwAFZones_Width_LSByte , 0x3d9c, 0x0000 }, +{ AFStatsStatus_uwAFZones_Width_MSByte , 0x3d9b, 0x0000 }, +{ AFStatsStatus_uwAFZones_Height_LSByte , 0x3da0, 0x0000 }, +{ AFStatsStatus_uwAFZones_Height_MSByte , 0x3d9f, 0x0000 }, +{ AFStatsStatus_fForcedAFStatsIrq , 0x3da2, 0x0000 }, +{ AFStatsStatus_udwMaxFocusMeasurePerPixel_Byte0 , 0x3da4, 0x0000 }, +{ AFStatsStatus_udwMaxFocusMeasurePerPixel_Byte1 , 0x3da6, 0x0000 }, +{ AFStatsStatus_udwMaxFocusMeasurePerPixel_Byte2 , 0x3da8, 0x0000 }, +{ AFStatsStatus_udwMaxFocusMeasurePerPixel_Byte3 , 0x3daa, 0x0000 }, +{ AFStatsStatus_uwStartingAFZoneLine_LSByte , 0x3dae, 0x0000 }, +{ AFStatsStatus_uwStartingAFZoneLine_MSByte , 0x3dad, 0x0000 }, +{ AFFocusStats_udwStatsValue_0_Byte0 , 0x3e00, 0x0000 }, +{ AFFocusStats_udwStatsValue_0_Byte1 , 0x3e02, 0x0000 }, +{ AFFocusStats_udwStatsValue_0_Byte2 , 0x3e04, 0x0000 }, +{ AFFocusStats_udwStatsValue_0_Byte3 , 0x3e06, 0x0000 }, +{ AFFocusStats_udwStatsValue_1_Byte0 , 0x3e08, 0x0000 }, +{ AFFocusStats_udwStatsValue_1_Byte1 , 0x3e0a, 0x0000 }, +{ AFFocusStats_udwStatsValue_1_Byte2 , 0x3e0c, 0x0000 }, +{ AFFocusStats_udwStatsValue_1_Byte3 , 0x3e0e, 0x0000 }, +{ AFFocusStats_udwStatsValue_2_Byte0 , 0x3e10, 0x0000 }, +{ AFFocusStats_udwStatsValue_2_Byte1 , 0x3e12, 0x0000 }, +{ AFFocusStats_udwStatsValue_2_Byte2 , 0x3e14, 0x0000 }, +{ AFFocusStats_udwStatsValue_2_Byte3 , 0x3e16, 0x0000 }, +{ AFFocusStats_udwStatsValue_3_Byte0 , 0x3e18, 0x0000 }, +{ AFFocusStats_udwStatsValue_3_Byte1 , 0x3e1a, 0x0000 }, +{ AFFocusStats_udwStatsValue_3_Byte2 , 0x3e1c, 0x0000 }, +{ AFFocusStats_udwStatsValue_3_Byte3 , 0x3e1e, 0x0000 }, +{ AFFocusStats_udwStatsValue_4_Byte0 , 0x3e20, 0x0000 }, +{ AFFocusStats_udwStatsValue_4_Byte1 , 0x3e22, 0x0000 }, +{ AFFocusStats_udwStatsValue_4_Byte2 , 0x3e24, 0x0000 }, +{ AFFocusStats_udwStatsValue_4_Byte3 , 0x3e26, 0x0000 }, +{ AFFocusStats_udwStatsValue_5_Byte0 , 0x3e28, 0x0000 }, +{ AFFocusStats_udwStatsValue_5_Byte1 , 0x3e2a, 0x0000 }, +{ AFFocusStats_udwStatsValue_5_Byte2 , 0x3e2c, 0x0000 }, +{ AFFocusStats_udwStatsValue_5_Byte3 , 0x3e2e, 0x0000 }, +{ AFFocusStats_udwStatsValue_6_Byte0 , 0x3e30, 0x0000 }, +{ AFFocusStats_udwStatsValue_6_Byte1 , 0x3e32, 0x0000 }, +{ AFFocusStats_udwStatsValue_6_Byte2 , 0x3e34, 0x0000 }, +{ AFFocusStats_udwStatsValue_6_Byte3 , 0x3e36, 0x0000 }, +{ AFLightStats_bStatsValue_0 , 0x3e80, 0x0000 }, +{ AFLightStats_bStatsValue_1 , 0x3e82, 0x0000 }, +{ AFLightStats_bStatsValue_2 , 0x3e84, 0x0000 }, +{ AFLightStats_bStatsValue_3 , 0x3e86, 0x0000 }, +{ AFLightStats_bStatsValue_4 , 0x3e88, 0x0000 }, +{ AFLightStats_bStatsValue_5 , 0x3e8a, 0x0000 }, +{ AFLightStats_bStatsValue_6 , 0x3e8c, 0x0000 }, +{ FLADriverLowLevelParameters_wMinPosition_LSByte , 0x3f02, 0x0000 }, +{ FLADriverLowLevelParameters_wMinPosition_MSByte , 0x3f01, 0x0000 }, +{ FLADriverLowLevelParameters_wMaxPosition_LSByte , 0x3f06, 0x0000 }, +{ FLADriverLowLevelParameters_wMaxPosition_MSByte , 0x3f05, 0x0000 }, +{ FLADriverLowLevelParameters_wHomePosition_LSByte , 0x3f0a, 0x0000 }, +{ FLADriverLowLevelParameters_wHomePosition_MSByte , 0x3f09, 0x0000 }, +{ FLADriverLowLevelParameters_wParkPosition_LSByte , 0x3f0e, 0x0000 }, +{ FLADriverLowLevelParameters_wParkPosition_MSByte , 0x3f0d, 0x0000 }, +{ FLADriverLowLevelParameters_bFramesToSkip , 0x3f10, 0x0000 }, +{ FLADriverLowLevelParameters_AutoSkipNextFrame , 0x3f12, 0x0000 }, +{ FLADriverLowLevelParameters_bLowLevelMacroPos , 0x3f14, 0x0000 }, +{ FLADriverLowLevelParameters_bLowLevelInfinityPos , 0x3f16, 0x0000 }, +{ FLADriverLowLevelParameters_bLowLevelPositionTolerance , 0x3f18, 0x0000 }, +{ FLADriverLowLevelParameters_bLowLevelTimeLimit , 0x3f1a, 0x0000 }, +{ FLADriverLowLevelParameters_bMaxNumberRetries , 0x3f1c, 0x000a }, +{ FLADriverLowLevelParameters_fLowLevelDriverInitialized , 0x3f1e, 0x0001 }, +{ FLADriverLowLevelParameters_fOverwriteLowLevelLimits , 0x3f20, 0x0001 }, +{ FLADriverLowLevelParameters_bNVMRead , 0x3f22, 0x0000 }, +{ FLADriverLowLevelParameters_bNVMScalingFactorInfinity , 0x3f24, 0x0000 }, +{ FLADriverLowLevelParameters_bNVMScalingFactorMacro , 0x3f26, 0x0000 }, +{ FLADriverLowLevelParameters_bNVM_PS_Offset , 0x3f28, 0x0000 }, +{ FLADriverLowLevelParameters_bNVM_PS_Gains , 0x3f2a, 0x0000 }, +{ FLADriverLowLevelParameters_bNVM_PS_IBias , 0x3f2c, 0x0000 }, +{ FLADriverLowLevelParameters_bNVM_PS_RampGain , 0x3f2e, 0x0000 }, +{ FLADriverLowLevelParameters_bNVM_PS_Type , 0x3f30, 0x0000 }, +{ FLADriverLowLevelParameters_uwNVM_minidriver_m_c_LSByte , 0x3f34, 0x0000 }, +{ FLADriverLowLevelParameters_uwNVM_minidriver_m_c_MSByte , 0x3f33, 0x0000 }, +{ FLADriverControls_bMMode , 0x3f80, 0x0000 }, +{ FLADriverControls_wTargetPosition_LSByte , 0x3f84, 0x0000 }, +{ FLADriverControls_wTargetPosition_MSByte , 0x3f83, 0x0000 }, +{ FLADriverControls_wPositionTolerance_LSByte , 0x3f88, 0x0000 }, +{ FLADriverControls_wPositionTolerance_MSByte , 0x3f87, 0x0000 }, +{ FLADriverControls_uwTimeLimit_ms_LSByte , 0x3f8c, 0x0000 }, +{ FLADriverControls_uwTimeLimit_ms_MSByte , 0x3f8b, 0x0000 }, +{ FLADriverControls_bTrigger , 0x3f8e, 0x0000 }, +{ FLADriverControls_bSlewMode , 0x3f90, 0x0000 }, +{ FLADriverControls_bSlewRate , 0x3f92, 0x0000 }, +{ FLADriverStatus_wLensPosition_LSByte , 0x4002, 0x0000 }, +{ FLADriverStatus_wLensPosition_MSByte , 0x4001, 0x0000 }, +{ FLADriverStatus_fLensIsMoving , 0x4004, 0x0000 }, +{ FLADriverStatus_fLimitsExceeded , 0x4006, 0x0000 }, +{ FLADriverStatus_fLensIsAtHome , 0x4008, 0x0000 }, +{ FLADriverStatus_fError , 0x400a, 0x0000 }, +{ FLADriverStatus_bSkippedFrames , 0x400c, 0x0000 }, +{ FLADriverStatus_bCycles , 0x400e, 0x0000 }, +{ FLADriverStatus_bMiniDriverTimeoutError , 0x4010, 0x0000 }, +{ FLADriverStatus_wTargetPosition , 0x4012, 0x0000 }, +{ FLADriverStatus_bLowLevelPosition , 0x4014, 0x0000 }, +{ FocusControls_fErrorReset , 0x4080, 0x0000 }, +{ FocusControls_bRange , 0x4082, 0x0000 }, +{ FocusControls_bMode , 0x4084, 0x0000 }, +{ FocusControls_bAFCommand , 0x4086, 0x0000 }, +{ FocusControls_bLensCommand , 0x4088, 0x0000 }, +{ FocusControls_bManualStep_Size , 0x408a, 0x0000 }, +{ FocusControls_fTestCoinEnabled , 0x408c, 0x0000 }, +{ FocusControls_bControlCoin , 0x408e, 0x0000 }, +{ FocusControls_fInternalStats_Disable , 0x4090, 0x0000 }, +{ FocusControls_bActuator_Disable , 0x4092, 0x0000 }, +{ FocusControls_fInhibitAutoMetering , 0x4094, 0x0000 }, +{ FocusStatus_bModeStatus , 0x4100, 0x0000 }, +{ FocusStatus_bAFCommandStatus , 0x4102, 0x0000 }, +{ FocusStatus_bLensCommandStatus , 0x4104, 0x0000 }, +{ FocusStatus_fAutoFocusEnabled , 0x4106, 0x0000 }, +{ FocusStatus_bRange , 0x4108, 0x0000 }, +{ FocusStatus_fIsStable , 0x410a, 0x0000 }, +{ FocusStatus_fError , 0x410c, 0x0000 }, +{ FocusStatus_cErrorCode , 0x410e, 0x0000 }, +{ FocusStatus_fLensIsMovingAtTheSOF , 0x4110, 0x0000 }, +{ FocusStatus_bCycles , 0x4112, 0x0000 }, +{ FocusStatus_fRunForTest , 0x4114, 0x0000 }, +{ FocusStatus_bStatusCoin , 0x4116, 0x0000 }, +{ FocusStatus_fInternalStats_Disabled , 0x4118, 0x0000 }, +{ FocusStatus_bActuator_Disabled , 0x411a, 0x0000 }, +{ FocusStatus_bLastUsedAFSensor , 0x411c, 0x0000 }, +{ FocusRangeConstants_wFullRange_LensMinPosition_LSByte , 0x4182, 0x0000 }, +{ FocusRangeConstants_wFullRange_LensMinPosition_MSByte , 0x4181, 0x0000 }, +{ FocusRangeConstants_wFullRange_LensMaxPosition_LSByte , 0x4186, 0x0000 }, +{ FocusRangeConstants_wFullRange_LensMaxPosition_MSByte , 0x4185, 0x03ff }, +{ FocusRangeConstants_wFullRange_LensRecoveryPosition_LSByte , 0x418a, 0x0000 }, +{ FocusRangeConstants_wFullRange_LensRecoveryPosition_MSByte , 0x4189, 0x01ff }, +{ FocusRangeConstants_wLandscape_LensMinPosition_LSByte , 0x418e, 0x0000 }, +{ FocusRangeConstants_wLandscape_LensMinPosition_MSByte , 0x418d, 0x0000 }, +{ FocusRangeConstants_wLandscape_LensMaxPosition_LSByte , 0x4192, 0x0000 }, +{ FocusRangeConstants_wLandscape_LensMaxPosition_MSByte , 0x4191, 0x03ff }, +{ FocusRangeConstants_wLandscape_LensRecoveryPosition_LSByte , 0x4196, 0x0000 }, +{ FocusRangeConstants_wLandscape_LensRecoveryPosition_MSByte , 0x4195, 0x01ff }, +{ FocusRangeConstants_wMacro_LensMinPosition_LSByte , 0x419a, 0x0000 }, +{ FocusRangeConstants_wMacro_LensMinPosition_MSByte , 0x4199, 0x0000 }, +{ FocusRangeConstants_wMacro_LensMaxPosition_LSByte , 0x419e, 0x0000 }, +{ FocusRangeConstants_wMacro_LensMaxPosition_MSByte , 0x419d, 0x03ff }, +{ FocusRangeConstants_wMacro_LensRecoveryPosition_LSByte , 0x41a2, 0x0000 }, +{ FocusRangeConstants_wMacro_LensRecoveryPosition_MSByte , 0x41a1, 0x01ff }, +{ AutoFocusControls_bHostCmd , 0x4200, 0x0000 }, +{ AutoFocusControls_fFreezeIfStable , 0x4202, 0x0000 }, +{ AutoFocusControls_fFMTesting_AutoDisable , 0x4204, 0x0001 }, +{ AutoFocusControls_fFastAFAlgoStart , 0x4206, 0x0000 }, +{ AutoFocusControls_fBackLight_Enable , 0x4208, 0x0000 }, +{ AutoFocusControls_fBackupSolution , 0x420a, 0x000f }, +{ AutoFocusControls_fCheckExposureStable_Enable , 0x420c, 0x0000 }, +{ AutoFocusControls_fEnableSimpleCoarseThEvaluation , 0x420e, 0x0000 }, +{ AutoFocusControls_bSelectedMultizoneBehavior , 0x4210, 0x0000 }, +{ AutoFocusControls_bBackLightMethodSelected , 0x4212, 0x0001 }, +{ AutoFocusControls_bWeighedFunctionSelected , 0x4214, 0x0002 }, +{ AutoFocusControls_fMotionBlurEnable , 0x4216, 0x0001 }, +{ AutoFocusControls_fLightVariationEnable , 0x4218, 0x0001 }, +{ AutoFocusControls_fEnableTrackingThresholdEvaluation , 0x421a, 0x0001 }, +{ AutoFocusControls_fEnableHeuristicMethod , 0x421c, 0x0001 }, +{ AutoFocusControls_fEnableBackupSolution , 0x421e, 0x0000 }, +{ AutoFocusControls_fFineToCoarseAutoTransitionEnable , 0x4220, 0x0001 }, +{ AutoFocusControls_fEnableTimedFineExecution , 0x4222, 0x0001 }, +{ AutoFocusControls_fEnableTrakingZoneVariation , 0x4224, 0x0000 }, +{ AutoFocusControls_fEnableFunctionThresholdTest , 0x4226, 0x0001 }, +{ AutoFocusControls_fForceTestState , 0x4228, 0x0000 }, +{ AutoFocusControls_bManualAFNextState , 0x422a, 0x0000 }, +{ AutoFocusControls_fResetHCSPos , 0x422c, 0x0001 }, +{ AutoFocusConstants_bCoarseStep , 0x4280, 0x0078 }, +{ AutoFocusConstants_bFineStep , 0x4282, 0x0014 }, +{ AutoFocusConstants_bFullSearchStep , 0x4284, 0x0000 }, +{ AutoFocusConstants_bLeakyIntegratorConstant , 0x4286, 0x0000 }, +{ AutoFocusConstants_uwFineThreshold_LSByte , 0x428a, 0x0000 }, +{ AutoFocusConstants_uwFineThreshold_MSByte , 0x4289, 0x0000 }, +{ AutoFocusConstants_bFineToCoarseThreshold , 0x428c, 0x0000 }, +{ AutoFocusConstants_uwBacklightThreshold_LSByte , 0x4290, 0x0000 }, +{ AutoFocusConstants_uwBacklightThreshold_MSByte , 0x428f, 0x0000 }, +{ AutoFocusConstants_uwMotionBlurInRatio_LSByte , 0x4294, 0x0000 }, +{ AutoFocusConstants_uwMotionBlurInRatio_MSByte , 0x4293, 0x0000 }, +{ AutoFocusConstants_uwMotionBlurOutRatio_LSByte , 0x4298, 0x0000 }, +{ AutoFocusConstants_uwMotionBlurOutRatio_MSByte , 0x4297, 0x0000 }, +{ AutoFocusConstants_bMaxNumberContinuouslyInstableTime , 0x429a, 0x0000 }, +{ AutoFocusConstants_bMaxNumberContinuouslyStableFrame , 0x429c, 0x0000 }, +{ AutoFocusConstants_uwMaxNumberContinuouslyThresholdTime , 0x429e, 0x0000 }, +{ AutoFocusConstants_uwFixedLowFocusMeasureValue_LSByte , 0x42a2, 0x0000 }, +{ AutoFocusConstants_uwFixedLowFocusMeasureValue_MSByte , 0x42a1, 0x0000 }, +{ AutoFocusConstants_bMaxFocusMeasureThreshold , 0x42a4, 0x0000 }, +{ AutoFocusConstants_bLightGap , 0x42a6, 0x0000 }, +{ AutoFocusConstants_uwDeltaValue_LSByte , 0x42aa, 0x0000 }, +{ AutoFocusConstants_uwDeltaValue_MSByte , 0x42a9, 0x0000 }, +{ AutoFocusConstants_uwMaxFineTh_LSByte , 0x42ae, 0x0000 }, +{ AutoFocusConstants_uwMaxFineTh_MSByte , 0x42ad, 0x0000 }, +{ AutoFocusInput_wLensPosition_LSByte , 0x4302, 0x0000 }, +{ AutoFocusInput_wLensPosition_MSByte , 0x4301, 0x0000 }, +{ AutoFocusInput_fLimitsExceeded , 0x4304, 0x0000 }, +{ AutoFocusInput_wLastStepExecuted_LSByte , 0x4308, 0x0000 }, +{ AutoFocusInput_wLastStepExecuted_MSByte , 0x4307, 0x0000 }, +{ AutoFocusStatus_bCycles , 0x4380, 0x0000 }, +{ AutoFocusStatus_bHostCmd , 0x4382, 0x0000 }, +{ AutoFocusStatus_bAF_PrevState , 0x4384, 0x0000 }, +{ AutoFocusStatus_bAF_State , 0x4386, 0x0000 }, +{ AutoFocusStatus_bAF_NextState , 0x4388, 0x0000 }, +{ AutoFocusStatus_bAF_PrevInstableFMState , 0x438a, 0x0000 }, +{ AutoFocusStatus_bAF_NextInstableFMState , 0x438c, 0x0000 }, +{ AutoFocusStatus_fChangeDirectionStatus , 0x438e, 0x0000 }, +{ AutoFocusStatus_bHCS_State , 0x4390, 0x0000 }, +{ AutoFocusStatus_bHCS_NextState , 0x4392, 0x0000 }, +{ AutoFocusStatus_bHCS_PrevState , 0x4394, 0x0000 }, +{ AutoFocusStatus_fReserved , 0x4396, 0x0000 }, +{ AutoFocusStatus_fCoarseInvoked , 0x4398, 0x0000 }, +{ AutoFocusStatus_fFullSearchInvoked , 0x439a, 0x0000 }, +{ AutoFocusStatus_fFullSearchZero , 0x439c, 0x0000 }, +{ AutoFocusStatus_fInFocus , 0x439e, 0x0000 }, +{ AutoFocusStatus_fMotionBlurIdentified , 0x43a0, 0x0000 }, +{ AutoFocusStatus_fInitialSearch , 0x43a2, 0x0000 }, +{ AutoFocusStatus_wMaxStepMotorLens_LSByte , 0x43a6, 0x0000 }, +{ AutoFocusStatus_wMaxStepMotorLens_MSByte , 0x43a5, 0x0000 }, +{ AutoFocusStatus_wTotalStepMotorLens_LSByte , 0x43aa, 0x0000 }, +{ AutoFocusStatus_wTotalStepMotorLens_MSByte , 0x43a9, 0x0000 }, +{ AutoFocusStatus_bNumberOfFrames , 0x43ac, 0x0000 }, +{ AutoFocusStatus_bCountFineSteps , 0x43ae, 0x0000 }, +{ AutoFocusStatus_bCountTrackingFrames , 0x43b0, 0x0000 }, +{ AutoFocusStatus_bNumberOfSelectedRegions , 0x43b2, 0x0000 }, +{ AutoFocusStatus_bOldNumberOfSelectedRegions , 0x43b4, 0x0000 }, +{ AutoFocusStatus_uwSelectedRegionsStatus_LSByte , 0x43b8, 0x0000 }, +{ AutoFocusStatus_uwSelectedRegionsStatus_MSByte , 0x43b7, 0x0000 }, +{ AutoFocusStatus_uwTotalCoarseVariation_LSByte , 0x43bc, 0x0000 }, +{ AutoFocusStatus_uwTotalCoarseVariation_MSByte , 0x43bb, 0x0000 }, +{ AutoFocusStatus_uwTotalFineVariation_LSByte , 0x43c0, 0x0000 }, +{ AutoFocusStatus_uwTotalFineVariation_MSByte , 0x43bf, 0x0000 }, +{ AutoFocusStatus_bCountVariationRegion , 0x43c2, 0x0000 }, +{ AutoFocusOutput_cFocusLensActuatorCommand , 0x4400, 0x0000 }, +{ AutoFocusOutput_wStep_LSByte , 0x4404, 0x0000 }, +{ AutoFocusOutput_wStep_MSByte , 0x4403, 0x0000 }, +{ AutoFocusOutput_cDirection , 0x4406, 0x0000 }, +{ AutoFocusMeasureData_udwFocusMeasure_Byte0 , 0x4480, 0x0000 }, +{ AutoFocusMeasureData_udwFocusMeasure_Byte1 , 0x4482, 0x0000 }, +{ AutoFocusMeasureData_udwFocusMeasure_Byte2 , 0x4484, 0x0000 }, +{ AutoFocusMeasureData_udwFocusMeasure_Byte3 , 0x4486, 0x0000 }, +{ AutoFocusMeasureData_udwPrevFocusMeasure_Byte0 , 0x4488, 0x0000 }, +{ AutoFocusMeasureData_udwPrevFocusMeasure_Byte1 , 0x448a, 0x0000 }, +{ AutoFocusMeasureData_udwPrevFocusMeasure_Byte2 , 0x448c, 0x0000 }, +{ AutoFocusMeasureData_udwPrevFocusMeasure_Byte3 , 0x448e, 0x0000 }, +{ AutoFocusMeasureData_udwMB_FocusMeasure_Byte0 , 0x4490, 0x0000 }, +{ AutoFocusMeasureData_udwMB_FocusMeasure_Byte1 , 0x4492, 0x0000 }, +{ AutoFocusMeasureData_udwMB_FocusMeasure_Byte2 , 0x4494, 0x0000 }, +{ AutoFocusMeasureData_udwMB_FocusMeasure_Byte3 , 0x4496, 0x0000 }, +{ AutoFocusMeasureData_udwMB_PrevFocusMeasure_Byte0 , 0x4498, 0x0000 }, +{ AutoFocusMeasureData_udwMB_PrevFocusMeasure_Byte1 , 0x449a, 0x0000 }, +{ AutoFocusMeasureData_udwMB_PrevFocusMeasure_Byte2 , 0x449c, 0x0000 }, +{ AutoFocusMeasureData_udwMB_PrevFocusMeasure_Byte3 , 0x449e, 0x0000 }, +{ AutoFocusMeasureData_udwMaxFocusMeasure_Byte0 , 0x44a0, 0x0000 }, +{ AutoFocusMeasureData_udwMaxFocusMeasure_Byte1 , 0x44a2, 0x0000 }, +{ AutoFocusMeasureData_udwMaxFocusMeasure_Byte2 , 0x44a4, 0x0000 }, +{ AutoFocusMeasureData_udwMaxFocusMeasure_Byte3 , 0x44a6, 0x0000 }, +{ AutoFocusMeasureData_udwOldMaxFocusMeasure_Byte0 , 0x44a8, 0x0000 }, +{ AutoFocusMeasureData_udwOldMaxFocusMeasure_Byte1 , 0x44aa, 0x0000 }, +{ AutoFocusMeasureData_udwOldMaxFocusMeasure_Byte2 , 0x44ac, 0x0000 }, +{ AutoFocusMeasureData_udwOldMaxFocusMeasure_Byte3 , 0x44ae, 0x0000 }, +{ AutoFocusMeasureData_udwPrevMaxFocusMeasure_Byte0 , 0x44b0, 0x0000 }, +{ AutoFocusMeasureData_udwPrevMaxFocusMeasure_Byte1 , 0x44b2, 0x0000 }, +{ AutoFocusMeasureData_udwPrevMaxFocusMeasure_Byte2 , 0x44b4, 0x0000 }, +{ AutoFocusMeasureData_udwPrevMaxFocusMeasure_Byte3 , 0x44b6, 0x0000 }, +{ AutoFocusMeasureData_udwNextMaxFocusMeasure_Byte0 , 0x44b8, 0x0000 }, +{ AutoFocusMeasureData_udwNextMaxFocusMeasure_Byte1 , 0x44ba, 0x0000 }, +{ AutoFocusMeasureData_udwNextMaxFocusMeasure_Byte2 , 0x44bc, 0x0000 }, +{ AutoFocusMeasureData_udwNextMaxFocusMeasure_Byte3 , 0x44be, 0x0000 }, +{ AutoFocusMeasureData_udwWeighedFocusMeasure_Byte0 , 0x44c0, 0x0000 }, +{ AutoFocusMeasureData_udwWeighedFocusMeasure_Byte1 , 0x44c2, 0x0000 }, +{ AutoFocusMeasureData_udwWeighedFocusMeasure_Byte2 , 0x44c4, 0x0000 }, +{ AutoFocusMeasureData_udwWeighedFocusMeasure_Byte3 , 0x44c6, 0x0000 }, +{ AutoFocusMeasureData_udwMaxMaxFocusMeasure_Byte0 , 0x44c8, 0x0000 }, +{ AutoFocusMeasureData_udwMaxMaxFocusMeasure_Byte1 , 0x44ca, 0x0000 }, +{ AutoFocusMeasureData_udwMaxMaxFocusMeasure_Byte2 , 0x44cc, 0x0000 }, +{ AutoFocusMeasureData_udwMaxMaxFocusMeasure_Byte3 , 0x44ce, 0x0000 }, +{ AutoFocusMeasureData_udwTrackingFocusMeasure_Byte0 , 0x44d0, 0x0000 }, +{ AutoFocusMeasureData_udwTrackingFocusMeasure_Byte1 , 0x44d2, 0x0000 }, +{ AutoFocusMeasureData_udwTrackingFocusMeasure_Byte2 , 0x44d4, 0x0000 }, +{ AutoFocusMeasureData_udwTrackingFocusMeasure_Byte3 , 0x44d6, 0x0000 }, +{ AutoFocusMeasureData_udwTrackingFocusMeasureDifference_Byte0 , 0x44d8, 0x0000 }, +{ AutoFocusMeasureData_udwTrackingFocusMeasureDifference_Byte1 , 0x44da, 0x0000 }, +{ AutoFocusMeasureData_udwTrackingFocusMeasureDifference_Byte2 , 0x44dc, 0x0000 }, +{ AutoFocusMeasureData_udwTrackingFocusMeasureDifference_Byte3 , 0x44de, 0x0000 }, +{ AutoFocusMeasureData_udwCurrentFocusMeasureDifference_Byte0 , 0x44e0, 0x0000 }, +{ AutoFocusMeasureData_udwCurrentFocusMeasureDifference_Byte1 , 0x44e2, 0x0000 }, +{ AutoFocusMeasureData_udwCurrentFocusMeasureDifference_Byte2 , 0x44e4, 0x0000 }, +{ AutoFocusMeasureData_udwCurrentFocusMeasureDifference_Byte3 , 0x44e6, 0x0000 }, +{ AutoFocusMeasureData_udwOldTrackingFocusMeasure_Byte0 , 0x44e8, 0x0000 }, +{ AutoFocusMeasureData_udwOldTrackingFocusMeasure_Byte1 , 0x44ea, 0x0000 }, +{ AutoFocusMeasureData_udwOldTrackingFocusMeasure_Byte2 , 0x44ec, 0x0000 }, +{ AutoFocusMeasureData_udwOldTrackingFocusMeasure_Byte3 , 0x44ee, 0x0000 }, +{ AutoFocusWeightControls_bWeight_0 , 0x4500, 0x0000 }, +{ AutoFocusWeightControls_bWeight_1 , 0x4502, 0x0000 }, +{ AutoFocusWeightControls_bWeight_2 , 0x4504, 0x0000 }, +{ AutoFocusWeightControls_bWeight_3 , 0x4506, 0x0000 }, +{ AutoFocusWeightControls_bWeight_4 , 0x4508, 0x0000 }, +{ AutoFocusWeightControls_bWeight_5 , 0x450a, 0x0000 }, +{ AutoFocusWeightControls_bWeight_6 , 0x450c, 0x0000 }, +{ AutoFocusDynamicWeight_bWeight_0 , 0x4580, 0x0000 }, +{ AutoFocusDynamicWeight_bWeight_1 , 0x4582, 0x0000 }, +{ AutoFocusDynamicWeight_bWeight_2 , 0x4584, 0x0000 }, +{ AutoFocusDynamicWeight_bWeight_3 , 0x4586, 0x0000 }, +{ AutoFocusDynamicWeight_bWeight_4 , 0x4588, 0x0000 }, +{ AutoFocusDynamicWeight_bWeight_5 , 0x458a, 0x0000 }, +{ AutoFocusDynamicWeight_bWeight_6 , 0x458c, 0x0000 }, +{ AutoFocusThresholds_uwCoarseThreshold_LSByte , 0x4602, 0x0000 }, +{ AutoFocusThresholds_uwCoarseThreshold_MSByte , 0x4601, 0x0000 }, +{ AutoFocusThresholds_uwFineThreshold_LSByte , 0x4606, 0x0000 }, +{ AutoFocusThresholds_uwFineThreshold_MSByte , 0x4605, 0x0000 }, +{ AutoFocusThresholds_uwBeforeMotionBlur_LSByte , 0x460a, 0x0000 }, +{ AutoFocusThresholds_uwBeforeMotionBlur_MSByte , 0x4609, 0x0000 }, +{ AutoFocusThresholds_uwAfterMotionBlur_LSByte , 0x460e, 0x0000 }, +{ AutoFocusThresholds_uwAfterMotionBlur_MSByte , 0x460d, 0x0000 }, +{ AutoFocusThresholds_udwCurrentVariation_Byte0 , 0x4610, 0x0000 }, +{ AutoFocusThresholds_udwCurrentVariation_Byte1 , 0x4612, 0x0000 }, +{ AutoFocusThresholds_udwCurrentVariation_Byte2 , 0x4614, 0x0000 }, +{ AutoFocusThresholds_udwCurrentVariation_Byte3 , 0x4616, 0x0000 }, +{ AutoFocusThresholds_udwLowFocusMeasureValue_Byte0 , 0x4618, 0x0000 }, +{ AutoFocusThresholds_udwLowFocusMeasureValue_Byte1 , 0x461a, 0x0000 }, +{ AutoFocusThresholds_udwLowFocusMeasureValue_Byte2 , 0x461c, 0x0000 }, +{ AutoFocusThresholds_udwLowFocusMeasureValue_Byte3 , 0x461e, 0x0000 }, +{ AutoFocusHeuristicConstants_uwLensPositionInputMax_LSByte , 0x4682, 0x0000 }, +{ AutoFocusHeuristicConstants_uwLensPositionInputMax_MSByte , 0x4681, 0x0000 }, +{ AutoFocusHeuristicConstants_uwLensPositionInputMin_LSByte , 0x4686, 0x0000 }, +{ AutoFocusHeuristicConstants_uwLensPositionInputMin_MSByte , 0x4685, 0x0000 }, +{ AutoFocusHeuristicConstants_bBrightnessInputMax , 0x4688, 0x0000 }, +{ AutoFocusHeuristicConstants_bBrightnessInputMin , 0x468a, 0x0000 }, +{ AutoFocusHeuristicConstants_uwThFineMax_LSByte , 0x468e, 0x0000 }, +{ AutoFocusHeuristicConstants_uwThFineMax_MSByte , 0x468d, 0x0000 }, +{ AutoFocusHeuristicConstants_uwThFineMin_LSByte , 0x4692, 0x0000 }, +{ AutoFocusHeuristicConstants_uwThFineMin_MSByte , 0x4691, 0x0000 }, +{ AutoFocusHeuristicConstants_uwFineToCoarseMax_LSByte , 0x4696, 0x0000 }, +{ AutoFocusHeuristicConstants_uwFineToCoarseMax_MSByte , 0x4695, 0x0000 }, +{ AutoFocusHeuristicConstants_uwFineToCoarseMin_LSByte , 0x469a, 0x0000 }, +{ AutoFocusHeuristicConstants_uwFineToCoarseMin_MSByte , 0x4699, 0x0000 }, +{ AutoFocusHeuristicConstants_bHighToMaxFMShiftFactor , 0x469c, 0x0000 }, +{ AutoFocusHeuristicConstants_bLowToHighFMShiftFactor , 0x469e, 0x0000 }, +{ AutoFocusThHeuristicInput_udwFocusMeasureInputMax_Byte0 , 0x4700, 0x0000 }, +{ AutoFocusThHeuristicInput_udwFocusMeasureInputMax_Byte1 , 0x4702, 0x0000 }, +{ AutoFocusThHeuristicInput_udwFocusMeasureInputMax_Byte2 , 0x4704, 0x0000 }, +{ AutoFocusThHeuristicInput_udwFocusMeasureInputMax_Byte3 , 0x4706, 0x0000 }, +{ AutoFocusThHeuristicInput_udwFocusMeasureInputMin_Byte0 , 0x4708, 0x0000 }, +{ AutoFocusThHeuristicInput_udwFocusMeasureInputMin_Byte1 , 0x470a, 0x0000 }, +{ AutoFocusThHeuristicInput_udwFocusMeasureInputMin_Byte2 , 0x470c, 0x0000 }, +{ AutoFocusThHeuristicInput_udwFocusMeasureInputMin_Byte3 , 0x470e, 0x0000 }, +{ AutoFocusThHeuristicInput_udwFocusMeasureInput_Byte0 , 0x4710, 0x0000 }, +{ AutoFocusThHeuristicInput_udwFocusMeasureInput_Byte1 , 0x4712, 0x0000 }, +{ AutoFocusThHeuristicInput_udwFocusMeasureInput_Byte2 , 0x4714, 0x0000 }, +{ AutoFocusThHeuristicInput_udwFocusMeasureInput_Byte3 , 0x4716, 0x0000 }, +{ AutoFocusThHeuristicInput_uwLensPositionInput_LSByte , 0x471a, 0x0000 }, +{ AutoFocusThHeuristicInput_uwLensPositionInput_MSByte , 0x4719, 0x0000 }, +{ AutoFocusThHeuristicInput_bBrightnessInput , 0x471c, 0x0000 }, +{ AutoFocusInstableFocusMeasureStatus_bStatus_SceneDetector , 0x4780, 0x0000 }, +{ AutoFocusInstableFocusMeasureStatus_bCountInstableFocusMeasure , 0x4782, 0x0000 }, +{ AutoFocusInstableFocusMeasureStatus_bCountStableFocusMeasure , 0x4784, 0x0000 }, +{ AutoFocusLFMFullSearchStatus_bPrevState_AFFS , 0x4800, 0x0000 }, +{ AutoFocusLFMFullSearchStatus_bState_AFFS , 0x4802, 0x0000 }, +{ AutoFocusLFMFullSearchStatus_bNextState_AFFS , 0x4804, 0x0000 }, +{ AutoFocusLFMFullSearchStatus_bCountFullSearchContinuouslyIncreaseValue , 0x4806, 0x0000 }, +{ AutoFocusMZFullSearchStatus_bFS_PrevState , 0x4880, 0x0000 }, +{ AutoFocusMZFullSearchStatus_bFS_State , 0x4882, 0x0000 }, +{ AutoFocusMZFullSearchStatus_bFS_NextState , 0x4884, 0x0000 }, +{ AutoFocusMZFullSearchStatus_bMaxMaxRegionPositionIndex , 0x4886, 0x0000 }, +{ MiscPageElements_fConvertMultiByteReadsIntoSingleByte , 0x4900, 0x0001 }, +{ MiscPageElements_bDelayAfterSettingXshutdown , 0x4902, 0x00f0 }, +{ MiscPageElements_fEnableIntelligentFlash , 0x4904, 0x0000 }, +{ MiscPageElements_fEligibleFrameForMetering , 0x4906, 0x0000 }, +{ MiscPageElements_fFlashGunIlluminatedFrameStreamed , 0x4908, 0x0000 }, +{ MiscPageElements_VpipCut , 0x490a, 0x0000 }, +{ MiscPageElements_bGPIOClockFrequency_Mhz , 0x490c, 0x0000 }, +{ MiscPageElements_bIntelligentFlashModeStatus , 0x490e, 0x0000 }, +{ MiscPageElements_fStartMeteringFromManualGains , 0x4910, 0x0000 }, +{ MiscPageElements_fEnableDelayWhenStartingSensor , 0x4912, 0x0000 }, +{ MiscPageElements_fEnableDelayWhenStoppingSensor , 0x4914, 0x0000 }, +{ MiscPageElements_fTriggerFlashOnStreaming , 0x4916, 0x0000 }, +{ MiscPageElements_fDoNotOutputFrameInIntelligentFlash , 0x4918, 0x0000 }, +{ MiscPageElements_fDisableToshibaInit , 0x491a, 0x0000 }, +{ MiscPageElements_bNumberofFramesTobeSkippedByRx , 0x491c, 0x0000 }, +{ CutBMasterI2cStatus_bWriteFifoUseCount , 0x4980, 0x0000 }, +{ MasterI2cClockControl_bCountFall , 0x4a00, 0x0000 }, +{ MasterI2cClockControl_bCountRise , 0x4a02, 0x0000 }, +{ MasterI2cClockControl_bCountHigh , 0x4a04, 0x0000 }, +{ MasterI2cClockControl_bCountBuffer , 0x4a06, 0x0000 }, +{ MasterI2cClockControl_bCountHoldData , 0x4a08, 0x0000 }, +{ MasterI2cClockControl_bCountSetupData , 0x4a0a, 0x0000 }, +{ MasterI2cClockControl_bCountHoldStart , 0x4a0c, 0x0000 }, +{ MasterI2cClockControl_bCountSetupStart , 0x4a0e, 0x0000 }, +{ MasterI2cClockControl_bCountSetupStop , 0x4a10, 0x0000 }, +{ ZoomMgrFOVCtrl_bShiftCenter , 0x4a80, 0x0000 }, +{ ZoomMgrFOVCtrl_uwXOrigin_LSByte , 0x4a84, 0x0000 }, +{ ZoomMgrFOVCtrl_uwXOrigin_MSByte , 0x4a83, 0x0000 }, +{ ZoomMgrFOVCtrl_uwYOrigin_LSByte , 0x4a88, 0x0000 }, +{ ZoomMgrFOVCtrl_uwYOrigin_MSByte , 0x4a87, 0x0000 }, +{ ZoomMgrFOVCtrl_fRestrictMaxFOVToChosenFOV , 0x4a8a, 0x0000 }, +{ ZoomMgrFOVCtrl_fCalculateMinFOVAlways , 0x4a8c, 0x0000 }, +{ ZoomMgrFOVCtrl_fInhibitMaxFOVAtModeStaticChange , 0x4a8e, 0x0000 }, +{ ZoomMgrSpeedInfo_bNumberOfFramesOnHold , 0x4b00, 0x0000 }, +{ ZoomMgrSpeedInfo_bDelay_frames , 0x4b02, 0x0000 }, +{ ZoomMgrSpeedInfo_uwTotalDelay_frames_LSByte , 0x4b06, 0x0000 }, +{ ZoomMgrSpeedInfo_uwTotalDelay_frames_MSByte , 0x4b05, 0x0000 }, +{ ZoomMgrSpeedInfo_bNumberOfZoomSteps , 0x4b08, 0x0000 }, +{ ZoomMgrStripeCtrl_bStripeControl , 0x4b80, 0x0000 }, +{ ZoomMgrStripeCtrl_uwStripeStartAddr_LSByte , 0x4b84, 0x0000 }, +{ ZoomMgrStripeCtrl_uwStripeStartAddr_MSByte , 0x4b83, 0x0000 }, +{ ZoomMgrStripeCtrl_uwStripeSize_LSByte , 0x4b88, 0x0000 }, +{ ZoomMgrStripeCtrl_uwStripeSize_MSByte , 0x4b87, 0x0000 }, +{ ZoomMgrStripeCtrl_uwStripeInMinLineSize_LSByte , 0x4b8c, 0x0000 }, +{ ZoomMgrStripeCtrl_uwStripeInMinLineSize_MSByte , 0x4b8b, 0x0000 }, +{ ZoomMgrStripeCtrl_uwBmsFrameLength_LSByte , 0x4b90, 0x0000 }, +{ ZoomMgrStripeCtrl_uwBmsFrameLength_MSByte , 0x4b8f, 0x0000 }, +{ LftStripeParam_uwGPSISize_LSByte , 0x4c02, 0x0000 }, +{ LftStripeParam_uwGPSISize_MSByte , 0x4c01, 0x0000 }, +{ LftStripeParam_uwGPSOSize_LSByte , 0x4c06, 0x0000 }, +{ LftStripeParam_uwGPSOSize_MSByte , 0x4c05, 0x0000 }, +{ LftStripeParam_uwRightBorder_LSByte , 0x4c0a, 0x0000 }, +{ LftStripeParam_uwRightBorder_MSByte , 0x4c09, 0x0000 }, +{ LftStripeParam_uwLeftBorder_LSByte , 0x4c0e, 0x0000 }, +{ LftStripeParam_uwLeftBorder_MSByte , 0x4c0d, 0x0000 }, +{ LftStripeParam_wGPSCropBulk_LSByte , 0x4c12, 0x0000 }, +{ LftStripeParam_wGPSCropBulk_MSByte , 0x4c11, 0x0000 }, +{ LftStripeParam_wGPSCropFrac_LSByte , 0x4c16, 0x0000 }, +{ LftStripeParam_wGPSCropFrac_MSByte , 0x4c15, 0x0000 }, +{ LftStripeParam_uwStripeInCropStart_LSByte , 0x4c1a, 0x0000 }, +{ LftStripeParam_uwStripeInCropStart_MSByte , 0x4c19, 0x0000 }, +{ LftStripeParam_uwStripeInCropSize_LSByte , 0x4c1e, 0x0000 }, +{ LftStripeParam_uwStripeInCropSize_MSByte , 0x4c1d, 0x0000 }, +{ LftStripeParam_uwStripeOutCropStart_LSByte , 0x4c22, 0x0000 }, +{ LftStripeParam_uwStripeOutCropStart_MSByte , 0x4c21, 0x0000 }, +{ LftStripeParam_uwStripeOutCropSize_LSByte , 0x4c26, 0x0000 }, +{ LftStripeParam_uwStripeOutCropSize_MSByte , 0x4c25, 0x0000 }, +{ RgtStripeParam_uwGPSISize_LSByte , 0x4c82, 0x0000 }, +{ RgtStripeParam_uwGPSISize_MSByte , 0x4c81, 0x0000 }, +{ RgtStripeParam_uwGPSOSize_LSByte , 0x4c86, 0x0000 }, +{ RgtStripeParam_uwGPSOSize_MSByte , 0x4c85, 0x0000 }, +{ RgtStripeParam_uwRightBorder_LSByte , 0x4c8a, 0x0000 }, +{ RgtStripeParam_uwRightBorder_MSByte , 0x4c89, 0x0000 }, +{ RgtStripeParam_uwLeftBorder_LSByte , 0x4c8e, 0x0000 }, +{ RgtStripeParam_uwLeftBorder_MSByte , 0x4c8d, 0x0000 }, +{ RgtStripeParam_wGPSCropBulk_LSByte , 0x4c92, 0x0000 }, +{ RgtStripeParam_wGPSCropBulk_MSByte , 0x4c91, 0x0000 }, +{ RgtStripeParam_wGPSCropFrac_LSByte , 0x4c96, 0x0000 }, +{ RgtStripeParam_wGPSCropFrac_MSByte , 0x4c95, 0x0000 }, +{ RgtStripeParam_uwStripeInCropStart_LSByte , 0x4c9a, 0x0000 }, +{ RgtStripeParam_uwStripeInCropStart_MSByte , 0x4c99, 0x0000 }, +{ RgtStripeParam_uwStripeInCropSize_LSByte , 0x4c9e, 0x0000 }, +{ RgtStripeParam_uwStripeInCropSize_MSByte , 0x4c9d, 0x0000 }, +{ RgtStripeParam_uwStripeOutCropStart_LSByte , 0x4ca2, 0x0000 }, +{ RgtStripeParam_uwStripeOutCropStart_MSByte , 0x4ca1, 0x0000 }, +{ RgtStripeParam_uwStripeOutCropSize_LSByte , 0x4ca6, 0x0000 }, +{ RgtStripeParam_uwStripeOutCropSize_MSByte , 0x4ca5, 0x0000 }, +{ DigitalGainStatus_uwCodedGreen1Gain_LSByte , 0x4d02, 0x0000 }, +{ DigitalGainStatus_uwCodedGreen1Gain_MSByte , 0x4d01, 0x0000 }, +{ DigitalGainStatus_uwCodedRedGain_LSByte , 0x4d06, 0x0000 }, +{ DigitalGainStatus_uwCodedRedGain_MSByte , 0x4d05, 0x0000 }, +{ DigitalGainStatus_uwCodedBlueGain_LSByte , 0x4d0a, 0x0000 }, +{ DigitalGainStatus_uwCodedBlueGain_MSByte , 0x4d09, 0x0000 }, +{ DigitalGainStatus_uwCodedGreen2Gain_LSByte , 0x4d0e, 0x0000 }, +{ DigitalGainStatus_uwCodedGreen2Gain_MSByte , 0x4d0d, 0x0000 }, +{ OffsetCompensationStatus_uwOffset_LSByte , 0x4d82, 0x0000 }, +{ OffsetCompensationStatus_uwOffset_MSByte , 0x4d81, 0x0000 }, +{ OffsetCompensationStatus_fpOffsetCompensationGain_LSByte , 0x4d86, 0x0000 }, +{ OffsetCompensationStatus_fpOffsetCompensationGain_MSByte , 0x4d85, 0x0000 }, +{ AntiFlickerExposureStatus_fpFlickerFreePeriod_us_LSByte , 0x4e02, 0x0000 }, +{ AntiFlickerExposureStatus_fpFlickerFreePeriod_us_MSByte , 0x4e01, 0x0000 }, +{ AntiFlickerExposureStatus_fpGainedFlickerFreeTimePeriod_us_LSByte , 0x4e06, 0x0000 }, +{ AntiFlickerExposureStatus_fpGainedFlickerFreeTimePeriod_us_MSByte , 0x4e05, 0x0000 }, +{ AntiFlickerExposureStatus_uwMaxFlickerFreeBunches_LSByte , 0x4e0a, 0x0000 }, +{ AntiFlickerExposureStatus_uwMaxFlickerFreeBunches_MSByte , 0x4e09, 0x0000 }, +{ AntiFlickerExposureStatus_fpConstrainedFlickerFreePeriod_us_LSByte , 0x4e0e, 0x0000 }, +{ AntiFlickerExposureStatus_fpConstrainedFlickerFreePeriod_us_MSByte , 0x4e0d, 0x0000 }, +{ ModuleEnables_fDisableCho , 0x4e80, 0x0000 }, +{ ModuleEnables_fDisableChg , 0x4e82, 0x0000 }, +{ DummyPage1_bDummyPageElement , 0x4f00, 0x0000 }, +{ DummyPage2_bDummyPageElement , 0x4f80, 0x0000 }, +{ SensorSetupFarSensor_uwGuaranteedDataSaturationLevel_LSByte , 0x5002, 0x0000 }, +{ SensorSetupFarSensor_uwGuaranteedDataSaturationLevel_MSByte , 0x5001, 0x043f }, +{ SensorSetupFarSensor_uwMinimumSensorRxPixelValue_LSByte , 0x5006, 0x0000 }, +{ SensorSetupFarSensor_uwMinimumSensorRxPixelValue_MSByte , 0x5005, 0x0004 }, +{ SensorSetupFarSensor_uwMaximumSensorRxPixelValue_LSByte , 0x500a, 0x0000 }, +{ SensorSetupFarSensor_uwMaximumSensorRxPixelValue_MSByte , 0x5009, 0x043f }, +{ SensorSetupFarSensor_fpRedTiltGain_LSByte , 0x500e, 0x0000 }, +{ SensorSetupFarSensor_fpRedTiltGain_MSByte , 0x500d, 0x3e00 }, +{ SensorSetupFarSensor_fpGreenTiltGain_LSByte , 0x5012, 0x0000 }, +{ SensorSetupFarSensor_fpGreenTiltGain_MSByte , 0x5011, 0x3e00 }, +{ SensorSetupFarSensor_fpBlueTiltGain_LSByte , 0x5016, 0x0000 }, +{ SensorSetupFarSensor_fpBlueTiltGain_MSByte , 0x5015, 0x3e00 }, +{ SensorSetupFarSensor_BlackCorrectionOffset , 0x5018, 0x0000 }, +{ SensorSetupNearSensor_uwGuaranteedDataSaturationLevel_LSByte , 0x5082, 0x0000 }, +{ SensorSetupNearSensor_uwGuaranteedDataSaturationLevel_MSByte , 0x5081, 0x0000 }, +{ SensorSetupNearSensor_uwMinimumSensorRxPixelValue_LSByte , 0x5086, 0x0000 }, +{ SensorSetupNearSensor_uwMinimumSensorRxPixelValue_MSByte , 0x5085, 0x0000 }, +{ SensorSetupNearSensor_uwMaximumSensorRxPixelValue_LSByte , 0x508a, 0x0000 }, +{ SensorSetupNearSensor_uwMaximumSensorRxPixelValue_MSByte , 0x5089, 0x0000 }, +{ SensorSetupNearSensor_fpRedTiltGain_LSByte , 0x508e, 0x0000 }, +{ SensorSetupNearSensor_fpRedTiltGain_MSByte , 0x508d, 0x0000 }, +{ SensorSetupNearSensor_fpGreenTiltGain_LSByte , 0x5092, 0x0000 }, +{ SensorSetupNearSensor_fpGreenTiltGain_MSByte , 0x5091, 0x0000 }, +{ SensorSetupNearSensor_fpBlueTiltGain_LSByte , 0x5096, 0x0000 }, +{ SensorSetupNearSensor_fpBlueTiltGain_MSByte , 0x5095, 0x0000 }, +{ SensorSetupNearSensor_BlackCorrectionOffset , 0x5098, 0x0000 }, +{ ToshibaOtpRead_otp_inf_2 , 0x5100, 0x0000 }, +{ ToshibaOtpRead_otp_inf_1 , 0x5102, 0x0000 }, +{ ToshibaOtpRead_otp_inf_0 , 0x5104, 0x0000 }, +{ ToshibaOtpRead_otp_mac_2 , 0x5106, 0x0000 }, +{ ToshibaOtpRead_otp_mac_1 , 0x5108, 0x0000 }, +{ ToshibaOtpRead_otp_mac_0 , 0x510a, 0x0000 }, +{ ToshibaOtpRead_otp_posA_1 , 0x510c, 0x0000 }, +{ ToshibaOtpRead_otp_posA_0 , 0x510e, 0x0000 }, +{ ToshibaOtpRead_otp_posB_1 , 0x5110, 0x0000 }, +{ ToshibaOtpRead_otp_posB_0 , 0x5112, 0x0000 }, +{ ToshibaOtpRead_otp_register_map_ver , 0x5114, 0x0000 }, +{ NormalisedWhiteBalanceGains_fpNormalisedRedGain_LSByte , 0x5182, 0x0000 }, +{ NormalisedWhiteBalanceGains_fpNormalisedRedGain_MSByte , 0x5181, 0x0000 }, +{ ReferenceIlluminantCasts_fpCAST0_LSByte , 0x5202, 0x0000 }, +{ ReferenceIlluminantCasts_fpCAST0_MSByte , 0x5201, 0x38b8 }, +{ ReferenceIlluminantCasts_fpCAST1_LSByte , 0x5206, 0x0000 }, +{ ReferenceIlluminantCasts_fpCAST1_MSByte , 0x5205, 0x396d }, +{ ReferenceIlluminantCasts_fpCAST2_LSByte , 0x520a, 0x0000 }, +{ ReferenceIlluminantCasts_fpCAST2_MSByte , 0x5209, 0x3a1b }, +{ ReferenceIlluminantCasts_fpCAST3_LSByte , 0x520e, 0x0000 }, +{ ReferenceIlluminantCasts_fpCAST3_MSByte , 0x520d, 0x3af2 }, +{ AdaptiveAVParameter_B_bAvUnityOffset_Day , 0x5280, 0x0040 }, +{ AdaptiveAVParameter_B_bAvCoeffR2_Day , 0x5282, 0x003e }, +{ AdaptiveAVParameter_B_bAvCoeffR4_Day , 0x5284, 0x00e8 }, +{ AdaptiveAVParameter_B_wAvHOffset_Day_LSByte , 0x5288, 0x0000 }, +{ AdaptiveAVParameter_B_wAvHOffset_Day_MSByte , 0x5287, 0x0003 }, +{ AdaptiveAVParameter_B_wAvVOffset_Day_LSByte , 0x528c, 0x0000 }, +{ AdaptiveAVParameter_B_wAvVOffset_Day_MSByte , 0x528b, 0x000d }, +{ AdaptiveAVParameter_B_bAvUnityOffset_COO , 0x528e, 0x0040 }, +{ AdaptiveAVParameter_B_bAvCoeffR2_COO , 0x5290, 0x003d }, +{ AdaptiveAVParameter_B_bAvCoeffR4_COO , 0x5292, 0x00ed }, +{ AdaptiveAVParameter_B_wAvHOffset_COO_LSByte , 0x5296, 0x0000 }, +{ AdaptiveAVParameter_B_wAvHOffset_COO_MSByte , 0x5295, 0x0006 }, +{ AdaptiveAVParameter_B_wAvVOffset_COO_LSByte , 0x529a, 0x0000 }, +{ AdaptiveAVParameter_B_wAvVOffset_COO_MSByte , 0x5299, 0x0011 }, +{ AdaptiveAVParameter_B_bAvUnityOffset_INC , 0x529c, 0x0040 }, +{ AdaptiveAVParameter_B_bAvCoeffR2_INC , 0x529e, 0x0035 }, +{ AdaptiveAVParameter_B_bAvCoeffR4_INC , 0x52a0, 0x00f4 }, +{ AdaptiveAVParameter_B_wAvHOffset_INC_LSByte , 0x52a4, 0x0000 }, +{ AdaptiveAVParameter_B_wAvHOffset_INC_MSByte , 0x52a3, 0x0009 }, +{ AdaptiveAVParameter_B_wAvVOffset_INC_LSByte , 0x52a8, 0x0000 }, +{ AdaptiveAVParameter_B_wAvVOffset_INC_MSByte , 0x52a7, 0x0015 }, +{ AdaptiveAVParameter_B_bAvUnityOffset_HOR , 0x52aa, 0x0040 }, +{ AdaptiveAVParameter_B_bAvCoeffR2_HOR , 0x52ac, 0x0037 }, +{ AdaptiveAVParameter_B_bAvCoeffR4_HOR , 0x52ae, 0x00f0 }, +{ AdaptiveAVParameter_B_wAvHOffset_HOR_LSByte , 0x52b2, 0x0000 }, +{ AdaptiveAVParameter_B_wAvHOffset_HOR_MSByte , 0x52b1, 0x000b }, +{ AdaptiveAVParameter_B_wAvVOffset_HOR_LSByte , 0x52b6, 0x0000 }, +{ AdaptiveAVParameter_B_wAvVOffset_HOR_MSByte , 0x52b5, 0x001d }, +{ AdaptiveAVParameter_GB_bAvUnityOffset_Day , 0x5300, 0x0040 }, +{ AdaptiveAVParameter_GB_bAvCoeffR2_Day , 0x5302, 0x0047 }, +{ AdaptiveAVParameter_GB_bAvCoeffR4_Day , 0x5304, 0x00ec }, +{ AdaptiveAVParameter_GB_wAvHOffset_Day_LSByte , 0x5308, 0x0000 }, +{ AdaptiveAVParameter_GB_wAvHOffset_Day_MSByte , 0x5307, 0x000a }, +{ AdaptiveAVParameter_GB_wAvVOffset_Day_LSByte , 0x530c, 0x0000 }, +{ AdaptiveAVParameter_GB_wAvVOffset_Day_MSByte , 0x530b, 0x000f }, +{ AdaptiveAVParameter_GB_bAvUnityOffset_COO , 0x530e, 0x0040 }, +{ AdaptiveAVParameter_GB_bAvCoeffR2_COO , 0x5310, 0x0046 }, +{ AdaptiveAVParameter_GB_bAvCoeffR4_COO , 0x5312, 0x00ed }, +{ AdaptiveAVParameter_GB_wAvHOffset_COO_LSByte , 0x5316, 0x0000 }, +{ AdaptiveAVParameter_GB_wAvHOffset_COO_MSByte , 0x5315, 0x000b }, +{ AdaptiveAVParameter_GB_wAvVOffset_COO_LSByte , 0x531a, 0x0000 }, +{ AdaptiveAVParameter_GB_wAvVOffset_COO_MSByte , 0x5319, 0x0010 }, +{ AdaptiveAVParameter_GB_bAvUnityOffset_INC , 0x531c, 0x0040 }, +{ AdaptiveAVParameter_GB_bAvCoeffR2_INC , 0x531e, 0x003e }, +{ AdaptiveAVParameter_GB_bAvCoeffR4_INC , 0x5320, 0x00f3 }, +{ AdaptiveAVParameter_GB_wAvHOffset_INC_LSByte , 0x5324, 0x0000 }, +{ AdaptiveAVParameter_GB_wAvHOffset_INC_MSByte , 0x5323, 0x000b }, +{ AdaptiveAVParameter_GB_wAvVOffset_INC_LSByte , 0x5328, 0x0000 }, +{ AdaptiveAVParameter_GB_wAvVOffset_INC_MSByte , 0x5327, 0x0010 }, +{ AdaptiveAVParameter_GB_bAvUnityOffset_HOR , 0x532a, 0x0040 }, +{ AdaptiveAVParameter_GB_bAvCoeffR2_HOR , 0x532c, 0x0040 }, +{ AdaptiveAVParameter_GB_bAvCoeffR4_HOR , 0x532e, 0x00f0 }, +{ AdaptiveAVParameter_GB_wAvHOffset_HOR_LSByte , 0x5332, 0x0000 }, +{ AdaptiveAVParameter_GB_wAvHOffset_HOR_MSByte , 0x5331, 0x000c }, +{ AdaptiveAVParameter_GB_wAvVOffset_HOR_LSByte , 0x5336, 0x0000 }, +{ AdaptiveAVParameter_GB_wAvVOffset_HOR_MSByte , 0x5335, 0x0014 }, +{ AdaptiveAVParameter_GR_bAvUnityOffset_Day , 0x5380, 0x0040 }, +{ AdaptiveAVParameter_GR_bAvCoeffR2_Day , 0x5382, 0x0048 }, +{ AdaptiveAVParameter_GR_bAvCoeffR4_Day , 0x5384, 0x00e8 }, +{ AdaptiveAVParameter_GR_wAvHOffset_Day_LSByte , 0x5388, 0x0000 }, +{ AdaptiveAVParameter_GR_wAvHOffset_Day_MSByte , 0x5387, 0x0009 }, +{ AdaptiveAVParameter_GR_wAvVOffset_Day_LSByte , 0x538c, 0x0000 }, +{ AdaptiveAVParameter_GR_wAvVOffset_Day_MSByte , 0x538b, 0x0004 }, +{ AdaptiveAVParameter_GR_bAvUnityOffset_COO , 0x538e, 0x0040 }, +{ AdaptiveAVParameter_GR_bAvCoeffR2_COO , 0x5390, 0x0046 }, +{ AdaptiveAVParameter_GR_bAvCoeffR4_COO , 0x5392, 0x00ea }, +{ AdaptiveAVParameter_GR_wAvHOffset_COO_LSByte , 0x5396, 0x0000 }, +{ AdaptiveAVParameter_GR_wAvHOffset_COO_MSByte , 0x5395, 0x000b }, +{ AdaptiveAVParameter_GR_wAvVOffset_COO_LSByte , 0x539a, 0x0000 }, +{ AdaptiveAVParameter_GR_wAvVOffset_COO_MSByte , 0x5399, 0x0004 }, +{ AdaptiveAVParameter_GR_bAvUnityOffset_INC , 0x539c, 0x0040 }, +{ AdaptiveAVParameter_GR_bAvCoeffR2_INC , 0x539e, 0x003f }, +{ AdaptiveAVParameter_GR_bAvCoeffR4_INC , 0x53a0, 0x00f1 }, +{ AdaptiveAVParameter_GR_wAvHOffset_INC_LSByte , 0x53a4, 0x0000 }, +{ AdaptiveAVParameter_GR_wAvHOffset_INC_MSByte , 0x53a3, 0x000b }, +{ AdaptiveAVParameter_GR_wAvVOffset_INC_LSByte , 0x53a8, 0x0000 }, +{ AdaptiveAVParameter_GR_wAvVOffset_INC_MSByte , 0x53a7, 0x0002 }, +{ AdaptiveAVParameter_GR_bAvUnityOffset_HOR , 0x53aa, 0x0040 }, +{ AdaptiveAVParameter_GR_bAvCoeffR2_HOR , 0x53ac, 0x0040 }, +{ AdaptiveAVParameter_GR_bAvCoeffR4_HOR , 0x53ae, 0x00ef }, +{ AdaptiveAVParameter_GR_wAvHOffset_HOR_LSByte , 0x53b2, 0x0000 }, +{ AdaptiveAVParameter_GR_wAvHOffset_HOR_MSByte , 0x53b1, 0x000c }, +{ AdaptiveAVParameter_GR_wAvVOffset_HOR_LSByte , 0x53b6, 0x0000 }, +{ AdaptiveAVParameter_GR_wAvVOffset_HOR_MSByte , 0x53b5, 0x0001 }, +{ AdaptiveAVParameter_R_bAvUnityOffset_Day , 0x5400, 0x0040 }, +{ AdaptiveAVParameter_R_bAvCoeffR2_Day , 0x5402, 0x0067 }, +{ AdaptiveAVParameter_R_bAvCoeffR4_Day , 0x5404, 0x00f6 }, +{ AdaptiveAVParameter_R_wAvHOffset_Day_LSByte , 0x5408, 0x0000 }, +{ AdaptiveAVParameter_R_wAvHOffset_Day_MSByte , 0x5407, 0x000a }, +{ AdaptiveAVParameter_R_wAvVOffset_Day_LSByte , 0x540c, 0x0000 }, +{ AdaptiveAVParameter_R_wAvVOffset_Day_MSByte , 0x540b, 0x0008 }, +{ AdaptiveAVParameter_R_bAvUnityOffset_COO , 0x540e, 0x0040 }, +{ AdaptiveAVParameter_R_bAvCoeffR2_COO , 0x5410, 0x0063 }, +{ AdaptiveAVParameter_R_bAvCoeffR4_COO , 0x5412, 0x00f7 }, +{ AdaptiveAVParameter_R_wAvHOffset_COO_LSByte , 0x5416, 0x0000 }, +{ AdaptiveAVParameter_R_wAvHOffset_COO_MSByte , 0x5415, 0x000b }, +{ AdaptiveAVParameter_R_wAvVOffset_COO_LSByte , 0x541a, 0x0000 }, +{ AdaptiveAVParameter_R_wAvVOffset_COO_MSByte , 0x5419, 0x0007 }, +{ AdaptiveAVParameter_R_bAvUnityOffset_INC , 0x541c, 0x0040 }, +{ AdaptiveAVParameter_R_bAvCoeffR2_INC , 0x541e, 0x0041 }, +{ AdaptiveAVParameter_R_bAvCoeffR4_INC , 0x5420, 0x0002 }, +{ AdaptiveAVParameter_R_wAvHOffset_INC_LSByte , 0x5424, 0x0000 }, +{ AdaptiveAVParameter_R_wAvHOffset_INC_MSByte , 0x5423, 0x000b }, +{ AdaptiveAVParameter_R_wAvVOffset_INC_LSByte , 0x5428, 0x0000 }, +{ AdaptiveAVParameter_R_wAvVOffset_INC_MSByte , 0x5427, 0x0007 }, +{ AdaptiveAVParameter_R_bAvUnityOffset_HOR , 0x542a, 0x0040 }, +{ AdaptiveAVParameter_R_bAvCoeffR2_HOR , 0x542c, 0x0052 }, +{ AdaptiveAVParameter_R_bAvCoeffR4_HOR , 0x542e, 0x00f7 }, +{ AdaptiveAVParameter_R_wAvHOffset_HOR_LSByte , 0x5432, 0x0000 }, +{ AdaptiveAVParameter_R_wAvHOffset_HOR_MSByte , 0x5431, 0x000a }, +{ AdaptiveAVParameter_R_wAvVOffset_HOR_LSByte , 0x5436, 0x0000 }, +{ AdaptiveAVParameter_R_wAvVOffset_HOR_MSByte , 0x5435, 0x0004 }, +{ ContrastStretchControl_fEnableContrastStretch , 0x5480, 0x0000 }, +{ ContrastStretchControl_bMode , 0x5482, 0x0000 }, +{ ContrastStretchControl_bAccColour , 0x5484, 0x0000 }, +{ ContrastStretchControl_bBlackThreshold , 0x5486, 0x0000 }, +{ ContrastStretchControl_bWhiteThreshold , 0x5488, 0x0000 }, +{ ContrastStretchStatus_uBlackBinAThreshold_hi , 0x5500, 0x0000 }, +{ ContrastStretchStatus_uBlackBinBThreshold_hi , 0x5502, 0x0000 }, +{ ContrastStretchStatus_uWhiteBinAThreshold_lo , 0x5504, 0x0000 }, +{ ContrastStretchStatus_uWhiteBinBThreshold_lo , 0x5506, 0x0000 }, +{ ContrastStretchStatus_fpGain_LSByte , 0x550a, 0x0000 }, +{ ContrastStretchStatus_fpGain_MSByte , 0x5509, 0x0000 }, +{ DynamicConstrainedWBControls_fpRedA_LSByte , 0x5582, 0x0000 }, +{ DynamicConstrainedWBControls_fpRedA_MSByte , 0x5581, 0x3881 }, +{ DynamicConstrainedWBControls_fpBlueA_LSByte , 0x5586, 0x0000 }, +{ DynamicConstrainedWBControls_fpBlueA_MSByte , 0x5585, 0x3c68 }, +{ DynamicConstrainedWBControls_fpDamperLowThreshold_LSByte , 0x558a, 0x0000 }, +{ DynamicConstrainedWBControls_fpDamperLowThreshold_MSByte , 0x5589, 0x53e8 }, +{ DynamicConstrainedWBControls_fpMinimumDamperOutput_LSByte , 0x558e, 0x0000 }, +{ DynamicConstrainedWBControls_fpMinimumDamperOutput_MSByte , 0x558d, 0x3a66 }, +{ DynamicConstrainedWBControls_fpDamperHighThreshold_LSByte , 0x5592, 0x0000 }, +{ DynamicConstrainedWBControls_fpDamperHighThreshold_MSByte , 0x5591, 0x5a71 }, +{ DynamicConstrainedWBControls_fDamperDisable , 0x5594, 0x0000 }, +{ Toshiba_AF_NVM_Read_NVM_Far2Near_inf_LSByte , 0x5602, 0x0000 }, +{ Toshiba_AF_NVM_Read_NVM_Far2Near_inf_MSByte , 0x5601, 0x0000 }, +{ Toshiba_AF_NVM_Read_NVM_Near2Far_inf_LSByte , 0x5606, 0x0000 }, +{ Toshiba_AF_NVM_Read_NVM_Near2Far_inf_MSByte , 0x5605, 0x0000 }, +{ Toshiba_AF_NVM_Read_NVM_Far2Near_mac_LSByte , 0x560a, 0x0000 }, +{ Toshiba_AF_NVM_Read_NVM_Far2Near_mac_MSByte , 0x5609, 0x0000 }, +{ Toshiba_AF_NVM_Read_NVM_Near2Far_mac_LSByte , 0x560e, 0x0000 }, +{ Toshiba_AF_NVM_Read_NVM_Near2Far_mac_MSByte , 0x560d, 0x0000 }, +{ Toshiba_AF_NVM_Read_NVM_Pos_A_LSByte , 0x5612, 0x0000 }, +{ Toshiba_AF_NVM_Read_NVM_Pos_A_MSByte , 0x5611, 0x0000 }, +{ Toshiba_AF_NVM_Read_NVM_Pos_B_LSByte , 0x5616, 0x0000 }, +{ Toshiba_AF_NVM_Read_NVM_Pos_B_MSByte , 0x5615, 0x0000 }, +{ Toshiba_Vcm_Parameters_wLowLevelMacroPos_LSByte , 0x5682, 0x0000 }, +{ Toshiba_Vcm_Parameters_wLowLevelMacroPos_MSByte , 0x5681, 0x0000 }, +{ Toshiba_Vcm_Parameters_wLowLevelInfinityPos_LSByte , 0x5686, 0x0000 }, +{ Toshiba_Vcm_Parameters_wLowLevelInfinityPos_MSByte , 0x5685, 0x0000 }, +{ Toshiba_Vcm_Parameters_bSlewControlModeEnable , 0x5688, 0x0000 }, +{ Toshiba_Vcm_Parameters_bSlewModeForSmallerStep , 0x568a, 0x0001 }, +{ Toshiba_Vcm_Parameters_bSlewRateForSmallerStep , 0x568c, 0x0004 }, +{ Toshiba_Vcm_Parameters_bSlewModeForLargerStep , 0x568e, 0x0008 }, +{ Toshiba_Vcm_Parameters_bSlewRateForLargerStep , 0x5690, 0x0007 }, +{ Toshiba_Vcm_Parameters_bThresholdStepSize , 0x5692, 0x00b0 }, +{ Toshiba_Vcm_Status_wLowLevelPos_LSByte , 0x5702, 0x0000 }, +{ Toshiba_Vcm_Status_wLowLevelPos_MSByte , 0x5701, 0x0000 }, +{ AdaptiveColourMatrix_fpNormalisedRedGain0_LSByte , 0x5782, 0x0000 }, +{ AdaptiveColourMatrix_fpNormalisedRedGain0_MSByte , 0x5781, 0x3adf }, +{ AdaptiveColourMatrix_fpNormalisedRedGain1_LSByte , 0x5786, 0x0000 }, +{ AdaptiveColourMatrix_fpNormalisedRedGain1_MSByte , 0x5785, 0x393f }, +{ AdaptiveColourMatrix_bChooseAdaptiveColourMatrix , 0x5788, 0x0001 }, +{ ColourEngine1_ColourMatrixFarSensor_fpRInR_LSByte , 0x5802, 0x0000 }, +{ ColourEngine1_ColourMatrixFarSensor_fpRInR_MSByte , 0x5801, 0x3f0c }, +{ ColourEngine1_ColourMatrixFarSensor_fpGInR_LSByte , 0x5806, 0x0000 }, +{ ColourEngine1_ColourMatrixFarSensor_fpGInR_MSByte , 0x5805, 0xb887 }, +{ ColourEngine1_ColourMatrixFarSensor_fpBInR_LSByte , 0x580a, 0x0000 }, +{ ColourEngine1_ColourMatrixFarSensor_fpBInR_MSByte , 0x5809, 0xbaec }, +{ ColourEngine1_ColourMatrixFarSensor_fpRInG_LSByte , 0x580e, 0x0000 }, +{ ColourEngine1_ColourMatrixFarSensor_fpRInG_MSByte , 0x580d, 0xbaba }, +{ ColourEngine1_ColourMatrixFarSensor_fpGInG_LSByte , 0x5812, 0x0000 }, +{ ColourEngine1_ColourMatrixFarSensor_fpGInG_MSByte , 0x5811, 0x3fa5 }, +{ ColourEngine1_ColourMatrixFarSensor_fpBInG_LSByte , 0x5816, 0x0000 }, +{ ColourEngine1_ColourMatrixFarSensor_fpBInG_MSByte , 0x5815, 0xbbd9 }, +{ ColourEngine1_ColourMatrixFarSensor_fpRInB_LSByte , 0x581a, 0x0000 }, +{ ColourEngine1_ColourMatrixFarSensor_fpRInB_MSByte , 0x5819, 0xbc6e }, +{ ColourEngine1_ColourMatrixFarSensor_fpGInB_LSByte , 0x581e, 0x0000 }, +{ ColourEngine1_ColourMatrixFarSensor_fpGInB_MSByte , 0x581d, 0xc01b }, +{ ColourEngine1_ColourMatrixFarSensor_fpBInB_LSByte , 0x5822, 0x0000 }, +{ ColourEngine1_ColourMatrixFarSensor_fpBInB_MSByte , 0x5821, 0x41b7 }, +{ ColourEngine1_ColourMatrixNearSensor_fpRInR_LSByte , 0x5882, 0x0000 }, +{ ColourEngine1_ColourMatrixNearSensor_fpRInR_MSByte , 0x5881, 0x0000 }, +{ ColourEngine1_ColourMatrixNearSensor_fpGInR_LSByte , 0x5886, 0x0000 }, +{ ColourEngine1_ColourMatrixNearSensor_fpGInR_MSByte , 0x5885, 0x0000 }, +{ ColourEngine1_ColourMatrixNearSensor_fpBInR_LSByte , 0x588a, 0x0000 }, +{ ColourEngine1_ColourMatrixNearSensor_fpBInR_MSByte , 0x5889, 0x0000 }, +{ ColourEngine1_ColourMatrixNearSensor_fpRInG_LSByte , 0x588e, 0x0000 }, +{ ColourEngine1_ColourMatrixNearSensor_fpRInG_MSByte , 0x588d, 0x0000 }, +{ ColourEngine1_ColourMatrixNearSensor_fpGInG_LSByte , 0x5892, 0x0000 }, +{ ColourEngine1_ColourMatrixNearSensor_fpGInG_MSByte , 0x5891, 0x0000 }, +{ ColourEngine1_ColourMatrixNearSensor_fpBInG_LSByte , 0x5896, 0x0000 }, +{ ColourEngine1_ColourMatrixNearSensor_fpBInG_MSByte , 0x5895, 0x0000 }, +{ ColourEngine1_ColourMatrixNearSensor_fpRInB_LSByte , 0x589a, 0x0000 }, +{ ColourEngine1_ColourMatrixNearSensor_fpRInB_MSByte , 0x5899, 0x0000 }, +{ ColourEngine1_ColourMatrixNearSensor_fpGInB_LSByte , 0x589e, 0x0000 }, +{ ColourEngine1_ColourMatrixNearSensor_fpGInB_MSByte , 0x589d, 0x0000 }, +{ ColourEngine1_ColourMatrixNearSensor_fpBInB_LSByte , 0x58a2, 0x0000 }, +{ ColourEngine1_ColourMatrixNearSensor_fpBInB_MSByte , 0x58a1, 0x0000 }, +{ WhiteBalanceGainLimit_fpWhiteBalanceGainLimit_LSByte , 0x5902, 0x0000 }, +{ WhiteBalanceGainLimit_fpWhiteBalanceGainLimit_MSByte , 0x5901, 0x4200 }, +{ ToshibaTechnicalParamTuner_uwHostLevelMacroPos_LSByte , 0x5982, 0x0000 }, +{ ToshibaTechnicalParamTuner_uwHostLevelMacroPos_MSByte , 0x5981, 0x0000 }, +{ ToshibaTechnicalParamTuner_uwHostLevelInfinityPos_LSByte , 0x5986, 0x0000 }, +{ ToshibaTechnicalParamTuner_uwHostLevelInfinityPos_MSByte , 0x5985, 0x0000 }, +{ ToshibaTechnicalParamTuner_uwDefAFMaxStandardRange_um_LSByte , 0x598a, 0x0000 }, +{ ToshibaTechnicalParamTuner_uwDefAFMaxStandardRange_um_MSByte , 0x5989, 0x012c }, +{ ToshibaTechnicalParamTuner_bDefFineStepParam_um , 0x598c, 0x0008 }, +{ ToshibaTechnicalParamTuner_bDefCoarseStepParam_um , 0x598e, 0x0030 }, +{ ToshibaTechnicalParamTuner_fHostDefTechParam , 0x5990, 0x0002 }, + +{ IRPLastPreviewWOI_X_Byte0 , 0x800c, 0x0000 }, +{ IRPLastPreviewWOI_X_Byte1 , 0x800e, 0x0000 }, +{ IRPLastPreviewWOI_X_Byte2 , 0x8010, 0x0000 }, +{ IRPLastPreviewWOI_X_Byte3 , 0x8012, 0x0000 }, + +{ ModeSetupBank2_bActiveSensor , 0x3b18, 0x0002 }, +{ ModeSetupBank3_bActiveSensor , 0x3b98,0x2}, + + + }; +EXPORT_SYMBOL(vpip_default_params); + + +struct nomadik_vpip_param vpip_default_params_orig[2700]= + + + +{ +{ DeviceParameters_uwDeviceId_LSByte , 0x0002, 0x0000 }, +{ DeviceParameters_uwDeviceId_MSByte , 0x0001, 0x0000 }, +{ DeviceParameters_bFirmwareVersionMajor , 0x0004, 0x0000 }, +{ DeviceParameters_bFirmwareVersionMinor , 0x0006, 0x0000 }, +{ DeviceParameters_bHardwareVersionMajor , 0x0008, 0x0000 }, +{ DeviceParameters_bHardwareVersionMinor , 0x000a, 0x0000 }, +{ ModeManagerControl_bUserCommand , 0x0080, 0x0000 }, +{ ModeManagerControl_fTestStateMachine , 0x0082, 0x0000 }, +{ ModeManagerControl_fForceTestState , 0x0084, 0x0000 }, +{ ModeManagerControl_bManualNextState , 0x0086, 0x0000 }, +{ ModeManagerControl_bTestCoin , 0x0088, 0x0000 }, +{ ModeManagerStatus_bThisLoLevelState , 0x0100, 0x0000 }, +{ ModeManagerStatus_bNextLoLevelState , 0x0102, 0x0000 }, +{ ModeManagerStatus_bHiLevelState , 0x0104, 0x0000 }, +{ ModeManagerStatus_bCycles , 0x0106, 0x0000 }, +{ ModeManagerStatus_fModeStaticSetupsChanged , 0x0108, 0x0000 }, +{ ModeManagerStatus_bTestCoin , 0x010a, 0x0000 }, +{ ModeManagerStatus_fCycleForTest , 0x010c, 0x0000 }, +{ ModeManagerStatus_bNumberOfFramesStreamed , 0x010e, 0x0000 }, +{ ModeManagerStatus_bPrevFrameCountForExposure , 0x0110, 0x0000 }, +{ RunModeControl_fMeteringOn , 0x0180, 0x0001 }, +{ RunModeControl_fExitOnStable , 0x0182, 0x0000 }, +{ RunModeControl_bStreamLength , 0x0184, 0x0000 }, +{ RunModeControl_fMeterBeforeStreaming , 0x0186, 0x0000 }, +{ RunModeControl_fChkForAF_Stability , 0x0188, 0x0000 }, +{ RunModeControl_fChkForExposure_Stability , 0x018a, 0x0000 }, +{ RunModeControl_fChkForWhiteBalance_Stability , 0x018c, 0x0000 }, +{ ModeSetupBankSelector_bRequiredModeSetupBank , 0x0200, 0x0000 }, +{ PipeSetupBankSelector_bRequiredPipe0SetupBank , 0x0280, 0x0000 }, +{ ModeSetupBank0_uwInputImageSize_X_LSByte , 0x0302, 0x0000 }, +{ ModeSetupBank0_uwInputImageSize_X_MSByte , 0x0301, 0x0648 }, +{ ModeSetupBank0_uwInputImageSize_Y_LSByte , 0x0306, 0x0000 }, +{ ModeSetupBank0_uwInputImageSize_Y_MSByte , 0x0305, 0x04b8 }, +{ ModeSetupBank0_uwMaxImageSize_X_LSByte , 0x030a, 0x0000 }, +{ ModeSetupBank0_uwMaxImageSize_X_MSByte , 0x0309, 0x0640 }, +{ ModeSetupBank0_uwMaxImageSize_Y_LSByte , 0x030e, 0x0000 }, +{ ModeSetupBank0_uwMaxImageSize_Y_MSByte , 0x030d, 0x04b0 }, +{ ModeSetupBank0_uwMinImageSize_X_LSByte , 0x0312, 0x0000 }, +{ ModeSetupBank0_uwMinImageSize_X_MSByte , 0x0311, 0x0058 }, +{ ModeSetupBank0_uwMinImageSize_Y_LSByte , 0x0316, 0x0000 }, +{ ModeSetupBank0_uwMinImageSize_Y_MSByte , 0x0315, 0x0048 }, +{ ModeSetupBank0_bActiveSensor , 0x0318, 0x0002 }, +{ ModeSetupBank0_fLowPowerStreaming , 0x031a, 0x0000 }, +{ ModeSetupBank0_bTestMode , 0x031c, 0x0000 }, +{ ModeSetupBank0_bNumberOfStatusLines , 0x031e, 0x0003 }, +{ ModeSetupBank0_bNumberOfDarkLines , 0x0320, 0x0002 }, +{ ModeSetupBank0_bNumberOfBlackLines , 0x0322, 0x0004 }, +{ ModeSetupBank0_uwNumberOfInterLinePixelClocks_LSByte , 0x0326, 0x0000 }, +{ ModeSetupBank0_uwNumberOfInterLinePixelClocks_MSByte , 0x0325, 0x0011 }, +{ ModeSetupBank0_uwNumberOfInterFrameLines_LSByte , 0x032a, 0x0000 }, +{ ModeSetupBank0_uwNumberOfInterFrameLines_MSByte , 0x0329, 0x0000 }, +{ ModeSetupBank0_bNumberOfDummyColumns , 0x032c, 0x0008 }, +{ ModeSetupBank0_bInputImageSource , 0x032e, 0x0000 }, +{ ModeSetupBank0_bOutputImageDestination , 0x0330, 0x0001 }, +{ PipeSetupBankA_uwPipeOutputSize_X_LSByte , 0x0382, 0x0000 }, +{ PipeSetupBankA_uwPipeOutputSize_X_MSByte , 0x0381, 0x0800 }, +{ PipeSetupBankA_uwPipeOutputSize_Y_LSByte , 0x0386, 0x0000 }, +{ PipeSetupBankA_uwPipeOutputSize_Y_MSByte , 0x0385, 0x0600 }, +{ PipeSetupBankA_bPipeOutputFormat , 0x0388, 0x0003 }, +{ PipeSetupBankA_bPipeStreamLength , 0x038a, 0x0000 }, +{ PipeSetupBankA_fTogglePixValid , 0x038c, 0x0000 }, +{ PipeSetupBankA_fEnableItuEmbeddedCodes , 0x038e, 0x0000 }, +{ PipeSetupBankA_bPixValidLineTypes , 0x0390, 0x0020 }, +{ PipeSetupBankA_fGenerateVSync , 0x0392, 0x1 }, +{ PipeSetupBankA_fCb_Cr_Flip , 0x0394, 0x0000 }, +{ PipeSetupBankA_fY_CbCr_Flip , 0x0396, 0x0000 }, +{ PipeSetupBankB_uwPipeOutputSize_X_LSByte , 0x0402, 0x0000 }, +{ PipeSetupBankB_uwPipeOutputSize_X_MSByte , 0x0401, 0x0000 }, +{ PipeSetupBankB_uwPipeOutputSize_Y_LSByte , 0x0406, 0x0000 }, +{ PipeSetupBankB_uwPipeOutputSize_Y_MSByte , 0x0405, 0x0000 }, +{ PipeSetupBankB_bPipeOutputFormat , 0x0408, 0x0000 }, +{ PipeSetupBankB_bPipeStreamLength , 0x040a, 0x0000 }, +{ PipeSetupBankB_fTogglePixValid , 0x040c, 0x0000 }, +{ PipeSetupBankB_fEnableItuEmbeddedCodes , 0x040e, 0x0000 }, +{ PipeSetupBankB_bPixValidLineTypes , 0x0410, 0x0000 }, +{ PipeSetupBankB_fGenerateVSync , 0x0412, 0x0000 }, +{ PipeSetupBankB_fCb_Cr_Flip , 0x0414, 0x0000 }, +{ PipeSetupBankB_fY_CbCr_Flip , 0x0416, 0x0000 }, +{ HostInterfaceManagerControl_bUserCommand , 0x0480, 0x0000 }, +{ HostInterfaceManagerControl_fTestStateMachine , 0x0482, 0x0000 }, +{ HostInterfaceManagerControl_fForceTestState , 0x0484, 0x0000 }, +{ HostInterfaceManagerControl_bManualNextState , 0x0486, 0x0000 }, +{ HostInterfaceManagerControl_bTestCoin , 0x0488, 0x0000 }, +{ HostInterfaceManagerControl_fAutoTransitionFromRxStopped , 0x048a, 0x0000 }, +{ HostInterfaceManagerControl_fStopSensor , 0x048c, 0x0001 }, +{ HostInterfaceManagerStatus_bThisLoLevelState , 0x0500, 0x0000 }, +{ HostInterfaceManagerStatus_bNextLoLevelState , 0x0502, 0x0000 }, +{ HostInterfaceManagerStatus_bHiLevelState , 0x0504, 0x0000 }, +{ HostInterfaceManagerStatus_bCycles , 0x0506, 0x0000 }, +{ HostInterfaceManagerStatus_bTestCoin , 0x0508, 0x0000 }, +{ HostInterfaceManagerStatus_fCycleForTest , 0x050a, 0x0000 }, +{ StreamManagerStatus_bStreamStatus , 0x0580, 0x0000 }, +{ StreamManagerStatus_fIsSensorRunning , 0x0582, 0x0000 }, +{ ClockManagerControl_fClockManagerInDebugState , 0x0600, 0x0000 }, +{ LocalPipe0SetupBank_uwPipeOutputSize_X_LSByte , 0x0682, 0x0000 }, +{ LocalPipe0SetupBank_uwPipeOutputSize_X_MSByte , 0x0681, 0x0000 }, +{ LocalPipe0SetupBank_uwPipeOutputSize_Y_LSByte , 0x0686, 0x0000 }, +{ LocalPipe0SetupBank_uwPipeOutputSize_Y_MSByte , 0x0685, 0x0000 }, +{ LocalPipe0SetupBank_bPipeOutputFormat , 0x0688, 0x0000 }, +{ LocalPipe0SetupBank_bPipeStreamLength , 0x068a, 0x0000 }, +{ LocalPipe0SetupBank_fTogglePixValid , 0x068c, 0x0000 }, +{ LocalPipe0SetupBank_fEnableItuEmbeddedCodes , 0x068e, 0x0000 }, +{ LocalPipe0SetupBank_bPixValidLineTypes , 0x0690, 0x0000 }, +{ LocalPipe0SetupBank_fGenerateVSync , 0x0692, 0x0000 }, +{ LocalPipe0SetupBank_fCb_Cr_Flip , 0x0694, 0x0000 }, +{ LocalPipe0SetupBank_fY_CbCr_Flip , 0x0696, 0x0000 }, +{ Pipe0Control_bPipeControl , 0x0700, 0x0000 }, +{ Pipe0Control_fPipeRefreshRequired , 0x0702, 0x0000 }, +{ Pipe0Control_fSfxSolariseEnabled , 0x0704, 0x0000 }, +{ Pipe0Control_fSfxNegativeEnabled , 0x0706, 0x0000 }, +{ Pipe0Control_ReplaceRedChannel , 0x0708, 0x0000 }, +{ Pipe0Control_ReplaceGreenChannel , 0x070a, 0x0001 }, +{ Pipe0Control_ReplaceBlueChannel , 0x070c, 0x0002 }, +{ Pipe0Control_fOverrideOFCropRegisters , 0x070e, 0x0000 }, +{ Pipe0Control_uwHCropRising_LSByte , 0x0712, 0x0000 }, +{ Pipe0Control_uwHCropRising_MSByte , 0x0711, 0x0000 }, +{ Pipe0Control_uwHCropFalling_LSByte , 0x0716, 0x0000 }, +{ Pipe0Control_uwHCropFalling_MSByte , 0x0715, 0x0000 }, +{ Pipe0Control_uwVCropRisingCrse_LSByte , 0x071a, 0x0000 }, +{ Pipe0Control_uwVCropRisingCrse_MSByte , 0x0719, 0x0000 }, +{ Pipe0Control_uwVCropFallingCrse_LSByte , 0x071e, 0x0000 }, +{ Pipe0Control_uwVCropFallingCrse_MSByte , 0x071d, 0x0000 }, +{ Pipe0Status_bPipeStatus , 0x0780, 0x0000 }, +{ Pipe0Status_fPipeEnablePending , 0x0782, 0x0000 }, +{ Pipe0Status_bNumberOfFramesStreamed , 0x0784, 0x0000 }, +{ Pipe0Status_fDitherEnabled , 0x0786, 0x0000 }, +{ Pipe0Status_fVidCompletePending , 0x0788, 0x0000 }, +{ HostToSensorAccessControl_bRequest , 0x0800, 0x0000 }, +{ HostToSensorAccessControl_bCommandCoin , 0x0802, 0x0000 }, +{ HostToSensorAccessControl_uwSensorIndex_LSByte , 0x0806, 0x0000 }, +{ HostToSensorAccessControl_uwSensorIndex_MSByte , 0x0805, 0x0000 }, +{ HostToSensorAccessStatus_bStatusCoin , 0x0880, 0x0000 }, +{ HostToSensorAccessStatus_bHostToSensorAccessErrorCount , 0x0882, 0x0000 }, +{ HostToSensorAccessData_uwDataLow_LSByte , 0x0902, 0x0000 }, +{ HostToSensorAccessData_uwDataLow_MSByte , 0x0901, 0x0000 }, +{ HostToSensorAccessData_uwDataHigh_LSByte , 0x0906, 0x0000 }, +{ HostToSensorAccessData_uwDataHigh_MSByte , 0x0905, 0x0000 }, +{ MasterI2cControl_bSensorSerialAddress , 0x0980, 0x0000 }, +{ MasterI2cControl_uwClk_Sensor_Comms_mhz_LSByte , 0x0984, 0x0000 }, +{ MasterI2cControl_uwClk_Sensor_Comms_mhz_MSByte , 0x0983, 0x0000 }, +{ MasterI2cControl_uwRequiredI2cSpeed_LSByte , 0x0988, 0x0000 }, +{ MasterI2cControl_uwRequiredI2cSpeed_MSByte , 0x0987, 0x0190 }, +{ MasterI2cControl_bMaximumNumberOfGrabAttempts , 0x098a, 0x0000 }, +{ MasterI2cStatus_bResourceStatus , 0x0a00, 0x0000 }, +{ MasterI2cStatus_uwI2CClkDiv_LSByte , 0x0a04, 0x0000 }, +{ MasterI2cStatus_uwI2CClkDiv_MSByte , 0x0a03, 0x0000 }, +{ MasterI2cStatus_fTransactionError , 0x0a06, 0x0000 }, +{ MasterI2cStatus_bNumberOfTransactionFailures , 0x0a08, 0x0000 }, +{ MasterI2cStatus_bNumberOfConsecutiveGrabFailures , 0x0a0a, 0x0000 }, +{ MasterI2cStatus_bNumberOfForcedReleases , 0x0a0c, 0x0000 }, +{ MasterI2cStatus_bNumberOfMcuClockDeratingAttemptsInhibited , 0x0a0e, 0x0000 }, +{ VideoTimingHostInputs_VideoTimingMode , 0x0a80, 0x0001 }, +{ VideoTimingHostInputs_bSensorBitsPerSystemClock , 0x0a82, 0x0002 }, +{ VideoTimingHostInputs_uwCsiRawFormat_LSByte , 0x0a86, 0x0000 }, +{ VideoTimingHostInputs_uwCsiRawFormat_MSByte , 0x0a85, 0x0808 }, +{ VideoTimingHostInputs_fpHostRxMaxDataRate_Mbps_LSByte , 0x0a8a, 0x0000 }, +{ VideoTimingHostInputs_fpHostRxMaxDataRate_Mbps_MSByte , 0x0a89, 0x508a }, +{ VideoTimingHostInputs_VsyncPolarity , 0x0a8c, 0x0000 }, +{ VideoTimingHostInputs_HsyncPolarity , 0x0a8e, 0x0000 }, +{ VideoTimingSensorFifoControl_bFiFoWaterMarkProgrammingMode , 0x0b00, 0x0000 }, +{ VideoTimingSensorFifoControl_uwFifoWaterMarkPixels_LSByte , 0x0b04, 0x0000 }, +{ VideoTimingSensorFifoControl_uwFifoWaterMarkPixels_MSByte , 0x0b03, 0x0000 }, +{ VideoTimingSensorFifoControl_uwFifoSizePixels_LSByte , 0x0b08, 0x0000 }, +{ VideoTimingSensorFifoControl_uwFifoSizePixels_MSByte , 0x0b07, 0x0000 }, +{ VideoTimingSensorScalingAndSubSamplingControl_fpOutputClockDeratingFraction_LSByte , 0x0b82, 0x0000 }, +{ VideoTimingSensorScalingAndSubSamplingControl_fpOutputClockDeratingFraction_MSByte , 0x0b81, 0x0000 }, +{ VideoTimingSensorScalingAndSubSamplingControl_bOutputClockDeratingRoundingMode , 0x0b84, 0x0000 }, +{ VideoTimingSensorScalingAndSubSamplingControl_fDerateVideoTimingClockForProfileZero , 0x0b86, 0x0000 }, +{ VideoTimingSensorConstraints_uwMinimumPrePllClockDiv_LSByte , 0x0c02, 0x0000 }, +{ VideoTimingSensorConstraints_uwMinimumPrePllClockDiv_MSByte , 0x0c01, 0x0000 }, +{ VideoTimingSensorConstraints_uwMaximumPrePllClockDiv_LSByte , 0x0c06, 0x0000 }, +{ VideoTimingSensorConstraints_uwMaximumPrePllClockDiv_MSByte , 0x0c05, 0x0000 }, +{ VideoTimingSensorConstraints_fpMinimumPllInputFrequency_Mhz_LSByte , 0x0c0a, 0x0000 }, +{ VideoTimingSensorConstraints_fpMinimumPllInputFrequency_Mhz_MSByte , 0x0c09, 0x0000 }, +{ VideoTimingSensorConstraints_uwMinimumPllMultiplier_LSByte , 0x0c0e, 0x0000 }, +{ VideoTimingSensorConstraints_uwMinimumPllMultiplier_MSByte , 0x0c0d, 0x0000 }, +{ VideoTimingSensorConstraints_uwMaximumPllMultiplier_LSByte , 0x0c12, 0x0000 }, +{ VideoTimingSensorConstraints_uwMaximumPllMultiplier_MSByte , 0x0c11, 0x0000 }, +{ VideoTimingSensorConstraints_fpMaximumPllOutputFrequency_Mhz_LSByte , 0x0c16, 0x0190 }, +{ VideoTimingSensorConstraints_fpMaximumPllOutputFrequency_Mhz_MSByte , 0x0c15, 0x0000 }, +{ VideoTimingSensorConstraints_uwMinimumVTSysClockDiv_LSByte , 0x0c1a, 0x0000 }, +{ VideoTimingSensorConstraints_uwMinimumVTSysClockDiv_MSByte , 0x0c19, 0x0000 }, +{ VideoTimingSensorConstraints_uwMaximumVTSysClockDiv_LSByte , 0x0c1e, 0x0000 }, +{ VideoTimingSensorConstraints_uwMaximumVTSysClockDiv_MSByte , 0x0c1d, 0x0000 }, +{ VideoTimingSensorConstraints_fpMaximumVTSystemClockFrequency_Mhz_LSByte , 0x0c22, 0x0000 }, +{ VideoTimingSensorConstraints_fpMaximumVTSystemClockFrequency_Mhz_MSByte , 0x0c21, 0x0000 }, +{ VideoTimingSensorConstraints_uwMinimumVTPixelClockDiv_LSByte , 0x0c26, 0x0000 }, +{ VideoTimingSensorConstraints_uwMinimumVTPixelClockDiv_MSByte , 0x0c25, 0x0000 }, +{ VideoTimingSensorConstraints_uwMaximumVTPixelClockDiv_LSByte , 0x0c2a, 0x0000 }, +{ VideoTimingSensorConstraints_uwMaximumVTPixelClockDiv_MSByte , 0x0c29, 0x0000 }, +{ VideoTimingSensorConstraints_fpMaximumVTPixelClockFrequency_Mhz_LSByte , 0x0c2e, 0x0000 }, +{ VideoTimingSensorConstraints_fpMaximumVTPixelClockFrequency_Mhz_MSByte , 0x0c2d, 0x0000 }, +{ VideoTimingSensorConstraints_uwMinimumOPSysClockDiv_LSByte , 0x0c32, 0x0000 }, +{ VideoTimingSensorConstraints_uwMinimumOPSysClockDiv_MSByte , 0x0c31, 0x0000 }, +{ VideoTimingSensorConstraints_uwMaximumOPSysClockDiv_LSByte , 0x0c36, 0x0000 }, +{ VideoTimingSensorConstraints_uwMaximumOPSysClockDiv_MSByte , 0x0c35, 0x0000 }, +{ VideoTimingSensorConstraints_fpMaximumOPSystemClockFrequency_Mhz_LSByte , 0x0c3a, 0x0000 }, +{ VideoTimingSensorConstraints_fpMaximumOPSystemClockFrequency_Mhz_MSByte , 0x0c39, 0x0000 }, +{ VideoTimingSensorConstraints_fpMaximumOPPixelClockFrequency_Mhz_LSByte , 0x0c3e, 0x0000 }, +{ VideoTimingSensorConstraints_fpMaximumOPPixelClockFrequency_Mhz_MSByte , 0x0c3d, 0x0000 }, +{ SensorScalingSubSamplingCapabilities_bSensorScalingMode , 0x0c80, 0x0000 }, +{ SensorScalingSubSamplingCapabilities_uwScalerMMin_LSByte , 0x0c84, 0x0000 }, +{ SensorScalingSubSamplingCapabilities_uwScalerMMin_MSByte , 0x0c83, 0x0000 }, +{ SensorScalingSubSamplingCapabilities_uwScalerMMax_LSByte , 0x0c88, 0x0000 }, +{ SensorScalingSubSamplingCapabilities_uwScalerMMax_MSByte , 0x0c87, 0x0000 }, +{ SensorScalingSubSamplingCapabilities_uwMaxOddInc_LSByte , 0x0c8c, 0x0000 }, +{ SensorScalingSubSamplingCapabilities_uwMaxOddInc_MSByte , 0x0c8b, 0x0000 }, +{ VideoTimingOutput_uwPrePllClockDiv_LSByte , 0x0d02, 0x0000 }, +{ VideoTimingOutput_uwPrePllClockDiv_MSByte , 0x0d01, 0x0000 }, +{ VideoTimingOutput_fpPllInputFrequency_Mhz_LSByte , 0x0d06, 0x0000 }, +{ VideoTimingOutput_fpPllInputFrequency_Mhz_MSByte , 0x0d05, 0x0000 }, +{ VideoTimingOutput_uwPllMultiplier_LSByte , 0x0d0a, 0x0000 }, +{ VideoTimingOutput_uwPllMultiplier_MSByte , 0x0d09, 0x0000 }, +{ VideoTimingOutput_fpPllOutputFrequency_Mhz_LSByte , 0x0d0e, 0x0000 }, +{ VideoTimingOutput_fpPllOutputFrequency_Mhz_MSByte , 0x0d0d, 0x0000 }, +{ VideoTimingOutput_uwVTSystemClockDiv_LSByte , 0x0d12, 0x0000 }, +{ VideoTimingOutput_uwVTSystemClockDiv_MSByte , 0x0d11, 0x0000 }, +{ VideoTimingOutput_fpVTSystemClockFrequency_Mhz_LSByte , 0x0d16, 0x0000 }, +{ VideoTimingOutput_fpVTSystemClockFrequency_Mhz_MSByte , 0x0d15, 0x0000 }, +{ VideoTimingOutput_uwVTPixelClockDiv_LSByte , 0x0d1a, 0x0000 }, +{ VideoTimingOutput_uwVTPixelClockDiv_MSByte , 0x0d19, 0x0000 }, +{ VideoTimingOutput_fpVTPixelClockFrequency_Mhz_LSByte , 0x0d1e, 0x0000 }, +{ VideoTimingOutput_fpVTPixelClockFrequency_Mhz_MSByte , 0x0d1d, 0x0000 }, +{ VideoTimingOutput_fpVTPixelClockPeriod_us_LSByte , 0x0d22, 0x0000 }, +{ VideoTimingOutput_fpVTPixelClockPeriod_us_MSByte , 0x0d21, 0x0000 }, +{ VideoTimingOutput_uwOPSystemClockDiv_LSByte , 0x0d26, 0x0000 }, +{ VideoTimingOutput_uwOPSystemClockDiv_MSByte , 0x0d25, 0x0000 }, +{ VideoTimingOutput_fpOPSystemClockFrequency_Mhz_LSByte , 0x0d2a, 0x0000 }, +{ VideoTimingOutput_fpOPSystemClockFrequency_Mhz_MSByte , 0x0d29, 0x0000 }, +{ VideoTimingOutput_uwOPPixelClockDiv_LSByte , 0x0d2e, 0x0000 }, +{ VideoTimingOutput_uwOPPixelClockDiv_MSByte , 0x0d2d, 0x0000 }, +{ VideoTimingOutput_fpOPPixelClockFrequency_Mhz_LSByte , 0x0d32, 0x0000 }, +{ VideoTimingOutput_fpOPPixelClockFrequency_Mhz_MSByte , 0x0d31, 0x0000 }, +{ VideoTimingOutput_fpOutputTimingClockDerating_LSByte , 0x0d36, 0x0000 }, +{ VideoTimingOutput_fpOutputTimingClockDerating_MSByte , 0x0d35, 0x0000 }, +{ DummyPage5_bDummyPageElement , 0x0d80, 0x0000 }, +{ VideoTimingInputsFarSensor_VideoTimingMode , 0x0e00, 0x0001 }, +{ VideoTimingInputsFarSensor_bSensorBitsPerSystemClock , 0x0e02, 0x0002 }, +{ VideoTimingInputsFarSensor_uwCsiRawFormat_LSByte , 0x0e06, 0x0000 }, +{ VideoTimingInputsFarSensor_uwCsiRawFormat_MSByte , 0x0e05, 0x0808 }, +{ VideoTimingInputsFarSensor_fpHostRxMaxDataRate_Mbps_LSByte , 0x0e0a, 0x0000 }, +{ VideoTimingInputsFarSensor_fpHostRxMaxDataRate_Mbps_MSByte , 0x0e09, 0x508a }, +{ VideoTimingInputsFarSensor_VsyncPolarity , 0x0e0c, 0x0000 }, +{ VideoTimingInputsFarSensor_HsyncPolarity , 0x0e0e, 0x0000 }, +{ SensorFarVideoTimingSensorFifoControl_bFiFoWaterMarkProgrammingMode , 0x0e80, 0x0000 }, +{ SensorFarVideoTimingSensorFifoControl_uwFifoWaterMarkPixels_LSByte , 0x0e84, 0x0000 }, +{ SensorFarVideoTimingSensorFifoControl_uwFifoWaterMarkPixels_MSByte , 0x0e83, 0x0000 }, +{ SensorFarVideoTimingSensorFifoControl_uwFifoSizePixels_LSByte , 0x0e88, 0x0000 }, +{ SensorFarVideoTimingSensorFifoControl_uwFifoSizePixels_MSByte , 0x0e87, 0x0000 }, +{ VideoTimingFarSensorConstraints_uwMinimumPrePllClockDiv_LSByte , 0x0f02, 0x0000 }, +{ VideoTimingFarSensorConstraints_uwMinimumPrePllClockDiv_MSByte , 0x0f01, 0x0000 }, +{ VideoTimingFarSensorConstraints_uwMaximumPrePllClockDiv_LSByte , 0x0f06, 0x0000 }, +{ VideoTimingFarSensorConstraints_uwMaximumPrePllClockDiv_MSByte , 0x0f05, 0x0000 }, +{ VideoTimingFarSensorConstraints_fpMinimumPllInputFrequency_Mhz_LSByte , 0x0f0a, 0x0000 }, +{ VideoTimingFarSensorConstraints_fpMinimumPllInputFrequency_Mhz_MSByte , 0x0f09, 0x0000 }, +{ VideoTimingFarSensorConstraints_uwMinimumPllMultiplier_LSByte , 0x0f0e, 0x0000 }, +{ VideoTimingFarSensorConstraints_uwMinimumPllMultiplier_MSByte , 0x0f0d, 0x0000 }, +{ VideoTimingFarSensorConstraints_uwMaximumPllMultiplier_LSByte , 0x0f12, 0x0000 }, +{ VideoTimingFarSensorConstraints_uwMaximumPllMultiplier_MSByte , 0x0f11, 0x0000 }, +{ VideoTimingFarSensorConstraints_fpMaximumPllOutputFrequency_Mhz_LSByte , 0x0f16, 0x0000 }, +{ VideoTimingFarSensorConstraints_fpMaximumPllOutputFrequency_Mhz_MSByte , 0x0f15, 0x0000 }, +{ VideoTimingFarSensorConstraints_uwMinimumVTSysClockDiv_LSByte , 0x0f1a, 0x0000 }, +{ VideoTimingFarSensorConstraints_uwMinimumVTSysClockDiv_MSByte , 0x0f19, 0x0000 }, +{ VideoTimingFarSensorConstraints_uwMaximumVTSysClockDiv_LSByte , 0x0f1e, 0x0000 }, +{ VideoTimingFarSensorConstraints_uwMaximumVTSysClockDiv_MSByte , 0x0f1d, 0x0000 }, +{ VideoTimingFarSensorConstraints_fpMaximumVTSystemClockFrequency_Mhz_LSByte , 0x0f22, 0x0000 }, +{ VideoTimingFarSensorConstraints_fpMaximumVTSystemClockFrequency_Mhz_MSByte , 0x0f21, 0x0000 }, +{ VideoTimingFarSensorConstraints_uwMinimumVTPixelClockDiv_LSByte , 0x0f26, 0x0000 }, +{ VideoTimingFarSensorConstraints_uwMinimumVTPixelClockDiv_MSByte , 0x0f25, 0x0000 }, +{ VideoTimingFarSensorConstraints_uwMaximumVTPixelClockDiv_LSByte , 0x0f2a, 0x0000 }, +{ VideoTimingFarSensorConstraints_uwMaximumVTPixelClockDiv_MSByte , 0x0f29, 0x0000 }, +{ VideoTimingFarSensorConstraints_fpMaximumVTPixelClockFrequency_Mhz_LSByte , 0x0f2e, 0x0000 }, +{ VideoTimingFarSensorConstraints_fpMaximumVTPixelClockFrequency_Mhz_MSByte , 0x0f2d, 0x0000 }, +{ VideoTimingFarSensorConstraints_uwMinimumOPSysClockDiv_LSByte , 0x0f32, 0x0000 }, +{ VideoTimingFarSensorConstraints_uwMinimumOPSysClockDiv_MSByte , 0x0f31, 0x0000 }, +{ VideoTimingFarSensorConstraints_uwMaximumOPSysClockDiv_LSByte , 0x0f36, 0x0000 }, +{ VideoTimingFarSensorConstraints_uwMaximumOPSysClockDiv_MSByte , 0x0f35, 0x0000 }, +{ VideoTimingFarSensorConstraints_fpMaximumOPSystemClockFrequency_Mhz_LSByte , 0x0f3a, 0x0000 }, +{ VideoTimingFarSensorConstraints_fpMaximumOPSystemClockFrequency_Mhz_MSByte , 0x0f39, 0x0000 }, +{ VideoTimingFarSensorConstraints_fpMaximumOPPixelClockFrequency_Mhz_LSByte , 0x0f3e, 0x0000 }, +{ VideoTimingFarSensorConstraints_fpMaximumOPPixelClockFrequency_Mhz_MSByte , 0x0f3d, 0x0000 }, +{ SensorFarScalingSubSamplingCapabilities_bSensorScalingMode , 0x0f80, 0x0000 }, +{ SensorFarScalingSubSamplingCapabilities_uwScalerMMin_LSByte , 0x0f84, 0x0000 }, +{ SensorFarScalingSubSamplingCapabilities_uwScalerMMin_MSByte , 0x0f83, 0x0000 }, +{ SensorFarScalingSubSamplingCapabilities_uwScalerMMax_LSByte , 0x0f88, 0x0000 }, +{ SensorFarScalingSubSamplingCapabilities_uwScalerMMax_MSByte , 0x0f87, 0x0000 }, +{ SensorFarScalingSubSamplingCapabilities_uwMaxOddInc_LSByte , 0x0f8c, 0x0000 }, +{ SensorFarScalingSubSamplingCapabilities_uwMaxOddInc_MSByte , 0x0f8b, 0x0000 }, +{ VideoTimingFarOutput_uwPrePllClockDiv_LSByte , 0x1002, 0x0000 }, +{ VideoTimingFarOutput_uwPrePllClockDiv_MSByte , 0x1001, 0x0000 }, +{ VideoTimingFarOutput_fpPllInputFrequency_Mhz_LSByte , 0x1006, 0x0000 }, +{ VideoTimingFarOutput_fpPllInputFrequency_Mhz_MSByte , 0x1005, 0x0000 }, +{ VideoTimingFarOutput_uwPllMultiplier_LSByte , 0x100a, 0x0000 }, +{ VideoTimingFarOutput_uwPllMultiplier_MSByte , 0x1009, 0x0000 }, +{ VideoTimingFarOutput_fpPllOutputFrequency_Mhz_LSByte , 0x100e, 0x0000 }, +{ VideoTimingFarOutput_fpPllOutputFrequency_Mhz_MSByte , 0x100d, 0x0000 }, +{ VideoTimingFarOutput_uwVTSystemClockDiv_LSByte , 0x1012, 0x0000 }, +{ VideoTimingFarOutput_uwVTSystemClockDiv_MSByte , 0x1011, 0x0000 }, +{ VideoTimingFarOutput_fpVTSystemClockFrequency_Mhz_LSByte , 0x1016, 0x0000 }, +{ VideoTimingFarOutput_fpVTSystemClockFrequency_Mhz_MSByte , 0x1015, 0x0000 }, +{ VideoTimingFarOutput_uwVTPixelClockDiv_LSByte , 0x101a, 0x0000 }, +{ VideoTimingFarOutput_uwVTPixelClockDiv_MSByte , 0x1019, 0x0000 }, +{ VideoTimingFarOutput_fpVTPixelClockFrequency_Mhz_LSByte , 0x101e, 0x0000 }, +{ VideoTimingFarOutput_fpVTPixelClockFrequency_Mhz_MSByte , 0x101d, 0x0000 }, +{ VideoTimingFarOutput_fpVTPixelClockPeriod_us_LSByte , 0x1022, 0x0000 }, +{ VideoTimingFarOutput_fpVTPixelClockPeriod_us_MSByte , 0x1021, 0x0000 }, +{ VideoTimingFarOutput_uwOPSystemClockDiv_LSByte , 0x1026, 0x0000 }, +{ VideoTimingFarOutput_uwOPSystemClockDiv_MSByte , 0x1025, 0x0000 }, +{ VideoTimingFarOutput_fpOPSystemClockFrequency_Mhz_LSByte , 0x102a, 0x0000 }, +{ VideoTimingFarOutput_fpOPSystemClockFrequency_Mhz_MSByte , 0x1029, 0x0000 }, +{ VideoTimingFarOutput_uwOPPixelClockDiv_LSByte , 0x102e, 0x0000 }, +{ VideoTimingFarOutput_uwOPPixelClockDiv_MSByte , 0x102d, 0x0000 }, +{ VideoTimingFarOutput_fpOPPixelClockFrequency_Mhz_LSByte , 0x1032, 0x0000 }, +{ VideoTimingFarOutput_fpOPPixelClockFrequency_Mhz_MSByte , 0x1031, 0x0000 }, +{ VideoTimingFarOutput_fpOutputTimingClockDerating_LSByte , 0x1036, 0x0000 }, +{ VideoTimingFarOutput_fpOutputTimingClockDerating_MSByte , 0x1035, 0x0000 }, +{ DummyPage6_bDummyPageElement , 0x1080, 0x0000 }, +{ VideoTimingInputsNearSensor_VideoTimingMode , 0x1100, 0x0001 }, +{ VideoTimingInputsNearSensor_bSensorBitsPerSystemClock , 0x1102, 0x0002 }, +{ VideoTimingInputsNearSensor_uwCsiRawFormat_LSByte , 0x1106, 0x0000 }, +{ VideoTimingInputsNearSensor_uwCsiRawFormat_MSByte , 0x1105, 0x0808 }, +{ VideoTimingInputsNearSensor_fpHostRxMaxDataRate_Mbps_LSByte , 0x110a, 0x0000 }, +{ VideoTimingInputsNearSensor_fpHostRxMaxDataRate_Mbps_MSByte , 0x1109, 0x508a }, +{ VideoTimingInputsNearSensor_VsyncPolarity , 0x110c, 0x0000 }, +{ VideoTimingInputsNearSensor_HsyncPolarity , 0x110e, 0x0000 }, +{ SensorNearVideoTimingSensorFifoControl_bFiFoWaterMarkProgrammingMode , 0x1180, 0x0000 }, +{ SensorNearVideoTimingSensorFifoControl_uwFifoWaterMarkPixels_LSByte , 0x1184, 0x0000 }, +{ SensorNearVideoTimingSensorFifoControl_uwFifoWaterMarkPixels_MSByte , 0x1183, 0x0000 }, +{ SensorNearVideoTimingSensorFifoControl_uwFifoSizePixels_LSByte , 0x1188, 0x0000 }, +{ SensorNearVideoTimingSensorFifoControl_uwFifoSizePixels_MSByte , 0x1187, 0x0000 }, +{ VideoTimingNearSensorConstraints_uwMinimumPrePllClockDiv_LSByte , 0x1202, 0x0000 }, +{ VideoTimingNearSensorConstraints_uwMinimumPrePllClockDiv_MSByte , 0x1201, 0x0000 }, +{ VideoTimingNearSensorConstraints_uwMaximumPrePllClockDiv_LSByte , 0x1206, 0x0000 }, +{ VideoTimingNearSensorConstraints_uwMaximumPrePllClockDiv_MSByte , 0x1205, 0x0000 }, +{ VideoTimingNearSensorConstraints_fpMinimumPllInputFrequency_Mhz_LSByte , 0x120a, 0x0000 }, +{ VideoTimingNearSensorConstraints_fpMinimumPllInputFrequency_Mhz_MSByte , 0x1209, 0x0000 }, +{ VideoTimingNearSensorConstraints_uwMinimumPllMultiplier_LSByte , 0x120e, 0x0000 }, +{ VideoTimingNearSensorConstraints_uwMinimumPllMultiplier_MSByte , 0x120d, 0x0000 }, +{ VideoTimingNearSensorConstraints_uwMaximumPllMultiplier_LSByte , 0x1212, 0x0000 }, +{ VideoTimingNearSensorConstraints_uwMaximumPllMultiplier_MSByte , 0x1211, 0x0000 }, +{ VideoTimingNearSensorConstraints_fpMaximumPllOutputFrequency_Mhz_LSByte , 0x1216, 0x0000 }, +{ VideoTimingNearSensorConstraints_fpMaximumPllOutputFrequency_Mhz_MSByte , 0x1215, 0x0000 }, +{ VideoTimingNearSensorConstraints_uwMinimumVTSysClockDiv_LSByte , 0x121a, 0x0000 }, +{ VideoTimingNearSensorConstraints_uwMinimumVTSysClockDiv_MSByte , 0x1219, 0x0000 }, +{ VideoTimingNearSensorConstraints_uwMaximumVTSysClockDiv_LSByte , 0x121e, 0x0000 }, +{ VideoTimingNearSensorConstraints_uwMaximumVTSysClockDiv_MSByte , 0x121d, 0x0000 }, +{ VideoTimingNearSensorConstraints_fpMaximumVTSystemClockFrequency_Mhz_LSByte , 0x1222, 0x0000 }, +{ VideoTimingNearSensorConstraints_fpMaximumVTSystemClockFrequency_Mhz_MSByte , 0x1221, 0x0000 }, +{ VideoTimingNearSensorConstraints_uwMinimumVTPixelClockDiv_LSByte , 0x1226, 0x0000 }, +{ VideoTimingNearSensorConstraints_uwMinimumVTPixelClockDiv_MSByte , 0x1225, 0x0000 }, +{ VideoTimingNearSensorConstraints_uwMaximumVTPixelClockDiv_LSByte , 0x122a, 0x0000 }, +{ VideoTimingNearSensorConstraints_uwMaximumVTPixelClockDiv_MSByte , 0x1229, 0x0000 }, +{ VideoTimingNearSensorConstraints_fpMaximumVTPixelClockFrequency_Mhz_LSByte , 0x122e, 0x0000 }, +{ VideoTimingNearSensorConstraints_fpMaximumVTPixelClockFrequency_Mhz_MSByte , 0x122d, 0x0000 }, +{ VideoTimingNearSensorConstraints_uwMinimumOPSysClockDiv_LSByte , 0x1232, 0x0000 }, +{ VideoTimingNearSensorConstraints_uwMinimumOPSysClockDiv_MSByte , 0x1231, 0x0000 }, +{ VideoTimingNearSensorConstraints_uwMaximumOPSysClockDiv_LSByte , 0x1236, 0x0000 }, +{ VideoTimingNearSensorConstraints_uwMaximumOPSysClockDiv_MSByte , 0x1235, 0x0000 }, +{ VideoTimingNearSensorConstraints_fpMaximumOPSystemClockFrequency_Mhz_LSByte , 0x123a, 0x0000 }, +{ VideoTimingNearSensorConstraints_fpMaximumOPSystemClockFrequency_Mhz_MSByte , 0x1239, 0x0000 }, +{ VideoTimingNearSensorConstraints_fpMaximumOPPixelClockFrequency_Mhz_LSByte , 0x123e, 0x0000 }, +{ VideoTimingNearSensorConstraints_fpMaximumOPPixelClockFrequency_Mhz_MSByte , 0x123d, 0x0000 }, +{ SensorNearScalingSubSamplingCapabilities_bSensorScalingMode , 0x1280, 0x0000 }, +{ SensorNearScalingSubSamplingCapabilities_uwScalerMMin_LSByte , 0x1284, 0x0000 }, +{ SensorNearScalingSubSamplingCapabilities_uwScalerMMin_MSByte , 0x1283, 0x0000 }, +{ SensorNearScalingSubSamplingCapabilities_uwScalerMMax_LSByte , 0x1288, 0x0000 }, +{ SensorNearScalingSubSamplingCapabilities_uwScalerMMax_MSByte , 0x1287, 0x0000 }, +{ SensorNearScalingSubSamplingCapabilities_uwMaxOddInc_LSByte , 0x128c, 0x0000 }, +{ SensorNearScalingSubSamplingCapabilities_uwMaxOddInc_MSByte , 0x128b, 0x0000 }, +{ VideoTimingNearOutput_uwPrePllClockDiv_LSByte , 0x1302, 0x0000 }, +{ VideoTimingNearOutput_uwPrePllClockDiv_MSByte , 0x1301, 0x0000 }, +{ VideoTimingNearOutput_fpPllInputFrequency_Mhz_LSByte , 0x1306, 0x0000 }, +{ VideoTimingNearOutput_fpPllInputFrequency_Mhz_MSByte , 0x1305, 0x0000 }, +{ VideoTimingNearOutput_uwPllMultiplier_LSByte , 0x130a, 0x0000 }, +{ VideoTimingNearOutput_uwPllMultiplier_MSByte , 0x1309, 0x0000 }, +{ VideoTimingNearOutput_fpPllOutputFrequency_Mhz_LSByte , 0x130e, 0x0000 }, +{ VideoTimingNearOutput_fpPllOutputFrequency_Mhz_MSByte , 0x130d, 0x0000 }, +{ VideoTimingNearOutput_uwVTSystemClockDiv_LSByte , 0x1312, 0x0000 }, +{ VideoTimingNearOutput_uwVTSystemClockDiv_MSByte , 0x1311, 0x0000 }, +{ VideoTimingNearOutput_fpVTSystemClockFrequency_Mhz_LSByte , 0x1316, 0x0000 }, +{ VideoTimingNearOutput_fpVTSystemClockFrequency_Mhz_MSByte , 0x1315, 0x0000 }, +{ VideoTimingNearOutput_uwVTPixelClockDiv_LSByte , 0x131a, 0x0000 }, +{ VideoTimingNearOutput_uwVTPixelClockDiv_MSByte , 0x1319, 0x0000 }, +{ VideoTimingNearOutput_fpVTPixelClockFrequency_Mhz_LSByte , 0x131e, 0x0000 }, +{ VideoTimingNearOutput_fpVTPixelClockFrequency_Mhz_MSByte , 0x131d, 0x0000 }, +{ VideoTimingNearOutput_fpVTPixelClockPeriod_us_LSByte , 0x1322, 0x0000 }, +{ VideoTimingNearOutput_fpVTPixelClockPeriod_us_MSByte , 0x1321, 0x0000 }, +{ VideoTimingNearOutput_uwOPSystemClockDiv_LSByte , 0x1326, 0x0000 }, +{ VideoTimingNearOutput_uwOPSystemClockDiv_MSByte , 0x1325, 0x0000 }, +{ VideoTimingNearOutput_fpOPSystemClockFrequency_Mhz_LSByte , 0x132a, 0x0000 }, +{ VideoTimingNearOutput_fpOPSystemClockFrequency_Mhz_MSByte , 0x1329, 0x0000 }, +{ VideoTimingNearOutput_uwOPPixelClockDiv_LSByte , 0x132e, 0x0000 }, +{ VideoTimingNearOutput_uwOPPixelClockDiv_MSByte , 0x132d, 0x0000 }, +{ VideoTimingNearOutput_fpOPPixelClockFrequency_Mhz_LSByte , 0x1332, 0x0000 }, +{ VideoTimingNearOutput_fpOPPixelClockFrequency_Mhz_MSByte , 0x1331, 0x0000 }, +{ VideoTimingNearOutput_fpOutputTimingClockDerating_LSByte , 0x1336, 0x0000 }, +{ VideoTimingNearOutput_fpOutputTimingClockDerating_MSByte , 0x1335, 0x0000 }, +{ DummyPage7_bDummyPageElement , 0x1380, 0x0000 }, +{ SystemConfiguration_fFarSensorPresent , 0x1400, 0x0001 }, +{ SystemConfiguration_CcpRxForFarSensor , 0x1402, 0x0000 }, +{ SystemConfiguration_fNearSensorPresent , 0x1404, 0x0001 }, +{ SystemConfiguration_CcpRxForNearSensor , 0x1406, 0x0001 }, +{ SystemConfiguration_uwExternalClockFrequency_Mhz_num_LSByte , 0x140a, 0x0000 }, +{ SystemConfiguration_uwExternalClockFrequency_Mhz_num_MSByte , 0x1409, 0x0060 }, +{ SystemConfiguration_bExternalClockFrequency_Mhz_den , 0x140c, 0x0005 }, +{ SystemConfiguration_fFocusLensActuatorOnSensorNearPresent , 0x140e, 0x1 },//0x0000 },for auto focus +{ SystemConfiguration_fFocusLensActuatorOnSensorFarPresent , 0x1410, 0x1 },//0x0000 }, +{ SystemConfiguration_fShutterActuatorOnSensorNearPresent , 0x1412, 0x0000 }, +{ SystemConfiguration_fShutterActuatorOnSensorFarPresent , 0x1414, 0x0000 }, +{ SystemConfiguration_fpMcuClkFrequency_MHz_LSByte , 0x1418, 0x0000 }, +{ SystemConfiguration_fpMcuClkFrequency_MHz_MSByte , 0x1417, 0x0000 }, +{ SensorInformation_fFarSensorAvailable , 0x1480, 0x0000 }, +{ SensorInformation_uwFarSensorModelId_LSByte , 0x1484, 0x0000 }, +{ SensorInformation_uwFarSensorModelId_MSByte , 0x1483, 0x0000 }, +{ SensorInformation_bFarSensorRevision , 0x1486, 0x0000 }, +{ SensorInformation_bFarSensorManufacturerId , 0x1488, 0x0000 }, +{ SensorInformation_bFarSensorSMIAVersion , 0x148a, 0x0000 }, +{ SensorInformation_fNearSensorAvailable , 0x148c, 0x0000 }, +{ SensorInformation_uwNearSensorModelId_LSByte , 0x1490, 0x0000 }, +{ SensorInformation_uwNearSensorModelId_MSByte , 0x148f, 0x0000 }, +{ SensorInformation_bNearSensorRevision , 0x1492, 0x0000 }, +{ SensorInformation_bNearSensorManufacturerId , 0x1494, 0x0000 }, +{ SensorInformation_bNearSensorSMIAVersion , 0x1496, 0x0000 }, +{ SensorInformation_bCurrentlyActiveSensor , 0x1498, 0x0000 }, +{ SensorInformation_fCurrentSensorAvailable , 0x149a, 0x0000 }, +{ SensorInformation_fSensorChangedSinceLastStreaming , 0x149c, 0x0000 }, +{ SensorCapabilitiesFarSensor_uwSensorIntegrationTimeCapability_LSByte , 0x1502, 0x0000 }, +{ SensorCapabilitiesFarSensor_uwSensorIntegrationTimeCapability_MSByte , 0x1501, 0x0000 }, +{ SensorCapabilitiesFarSensor_uwSensorMinimumCoarseIntegrationLines_LSByte , 0x1506, 0x0000 }, +{ SensorCapabilitiesFarSensor_uwSensorMinimumCoarseIntegrationLines_MSByte , 0x1505, 0x0000 }, +{ SensorCapabilitiesFarSensor_uwSensorCoarseIntegrationTimeMaxMargin_LSByte , 0x150a, 0x0000 }, +{ SensorCapabilitiesFarSensor_uwSensorCoarseIntegrationTimeMaxMargin_MSByte , 0x1509, 0x0000 }, +{ SensorCapabilitiesFarSensor_uwSensorMinimumFineIntegrationPixels_LSByte , 0x150e, 0x0000 }, +{ SensorCapabilitiesFarSensor_uwSensorMinimumFineIntegrationPixels_MSByte , 0x150d, 0x0000 }, +{ SensorCapabilitiesFarSensor_uwSensorFineIntegrationTimeMaxMargin_LSByte , 0x1512, 0x0000 }, +{ SensorCapabilitiesFarSensor_uwSensorFineIntegrationTimeMaxMargin_MSByte , 0x1511, 0x0000 }, +{ SensorCapabilitiesFarSensor_uwSensorAnalogGainMinimum_LSByte , 0x1516, 0x0000 }, +{ SensorCapabilitiesFarSensor_uwSensorAnalogGainMinimum_MSByte , 0x1515, 0x0020 }, +{ SensorCapabilitiesFarSensor_uwSensorAnalogGainMaximum_LSByte , 0x151a, 0x0000 }, +{ SensorCapabilitiesFarSensor_uwSensorAnalogGainMaximum_MSByte , 0x1519, 0x0080 }, +{ SensorCapabilitiesFarSensor_uwSensorAnalogGainCodeStep_LSByte , 0x151e, 0x0000 }, +{ SensorCapabilitiesFarSensor_uwSensorAnalogGainCodeStep_MSByte , 0x151d, 0x0000 }, +{ SensorCapabilitiesFarSensor_uwSensorAnalogGainType_LSByte , 0x1522, 0x0000 }, +{ SensorCapabilitiesFarSensor_uwSensorAnalogGainType_MSByte , 0x1521, 0x0000 }, +{ SensorCapabilitiesFarSensor_fpSensorAnalogGainConstM0_LSByte , 0x1526, 0x0000 }, +{ SensorCapabilitiesFarSensor_fpSensorAnalogGainConstM0_MSByte , 0x1525, 0x0000 }, +{ SensorCapabilitiesFarSensor_fpSensorAnalogGainConstC0_LSByte , 0x152a, 0x0000 }, +{ SensorCapabilitiesFarSensor_fpSensorAnalogGainConstC0_MSByte , 0x1529, 0x0000 }, +{ SensorCapabilitiesFarSensor_fpSensorAnalogGainConstM1_LSByte , 0x152e, 0x0000 }, +{ SensorCapabilitiesFarSensor_fpSensorAnalogGainConstM1_MSByte , 0x152d, 0x0000 }, +{ SensorCapabilitiesFarSensor_fpSensorAnalogGainConstC1_LSByte , 0x1532, 0x0000 }, +{ SensorCapabilitiesFarSensor_fpSensorAnalogGainConstC1_MSByte , 0x1531, 0x0000 }, +{ SensorCapabilitiesFarSensor_uwSensorConstantColumns_LSByte , 0x1536, 0x0000 }, +{ SensorCapabilitiesFarSensor_uwSensorConstantColumns_MSByte , 0x1535, 0x0000 }, +{ SensorCapabilitiesFarSensor_uwStartOfActiveColumns_LSByte , 0x153a, 0x0000 }, +{ SensorCapabilitiesFarSensor_uwStartOfActiveColumns_MSByte , 0x1539, 0x0000 }, +{ SensorCapabilitiesFarSensor_bActiveColumnDescriptorNumber , 0x153c, 0x0000 }, +{ SensorCapabilitiesFarSensor_bSensorStartOfActiveLines , 0x153e, 0x0000 }, +{ SensorCapabilitiesFarSensor_uwSensorConstantRows_LSByte , 0x1542, 0x0000 }, +{ SensorCapabilitiesFarSensor_uwSensorConstantRows_MSByte , 0x1541, 0x0000 }, +{ SensorCapabilitiesFarSensor_uwSensorStatusLines_LSByte , 0x1546, 0x0000 }, +{ SensorCapabilitiesFarSensor_uwSensorStatusLines_MSByte , 0x1545, 0x0000 }, +{ SensorCapabilitiesFarSensor_bPreActiveDarkLines_LSByte , 0x154a, 0x0000 }, +{ SensorCapabilitiesFarSensor_bPreActiveDarkLines_MSByte , 0x1549, 0x0000 }, +{ SensorCapabilitiesFarSensor_bPreActiveBlackLines_LSByte , 0x154e, 0x0000 }, +{ SensorCapabilitiesFarSensor_bPreActiveBlackLines_MSByte , 0x154d, 0x0000 }, +{ SensorCapabilitiesFarSensor_bSensorVFPNLines , 0x1550, 0x0000 }, +{ SensorCapabilitiesFarSensor_uwSensorDigitalGainCapability_LSByte , 0x1554, 0x0000 }, +{ SensorCapabilitiesFarSensor_uwSensorDigitalGainCapability_MSByte , 0x1553, 0x0000 }, +{ SensorCapabilitiesFarSensor_uwSensorDigitalGainMinimum_LSByte , 0x1558, 0x0000 }, +{ SensorCapabilitiesFarSensor_uwSensorDigitalGainMinimum_MSByte , 0x1557, 0x0000 }, +{ SensorCapabilitiesFarSensor_uwSensorDataPedestal_LSByte , 0x155c, 0x0000 }, +{ SensorCapabilitiesFarSensor_uwSensorDataPedestal_MSByte , 0x155b, 0x0040 }, +{ SensorCapabilitiesNearSensor_uwSensorIntegrationTimeCapability_LSByte , 0x1582, 0x0000 }, +{ SensorCapabilitiesNearSensor_uwSensorIntegrationTimeCapability_MSByte , 0x1581, 0x0000 }, +{ SensorCapabilitiesNearSensor_uwSensorMinimumCoarseIntegrationLines_LSByte , 0x1586, 0x0000 }, +{ SensorCapabilitiesNearSensor_uwSensorMinimumCoarseIntegrationLines_MSByte , 0x1585, 0x0000 }, +{ SensorCapabilitiesNearSensor_uwSensorCoarseIntegrationTimeMaxMargin_LSByte , 0x158a, 0x0000 }, +{ SensorCapabilitiesNearSensor_uwSensorCoarseIntegrationTimeMaxMargin_MSByte , 0x1589, 0x0000 }, +{ SensorCapabilitiesNearSensor_uwSensorMinimumFineIntegrationPixels_LSByte , 0x158e, 0x0000 }, +{ SensorCapabilitiesNearSensor_uwSensorMinimumFineIntegrationPixels_MSByte , 0x158d, 0x0000 }, +{ SensorCapabilitiesNearSensor_uwSensorFineIntegrationTimeMaxMargin_LSByte , 0x1592, 0x0000 }, +{ SensorCapabilitiesNearSensor_uwSensorFineIntegrationTimeMaxMargin_MSByte , 0x1591, 0x0000 }, +{ SensorCapabilitiesNearSensor_uwSensorAnalogGainMinimum_LSByte , 0x1596, 0x0000 }, +{ SensorCapabilitiesNearSensor_uwSensorAnalogGainMinimum_MSByte , 0x1595, 0x0000 }, +{ SensorCapabilitiesNearSensor_uwSensorAnalogGainMaximum_LSByte , 0x159a, 0x0000 }, +{ SensorCapabilitiesNearSensor_uwSensorAnalogGainMaximum_MSByte , 0x1599, 0x00f0 }, +{ SensorCapabilitiesNearSensor_uwSensorAnalogGainCodeStep_LSByte , 0x159e, 0x0000 }, +{ SensorCapabilitiesNearSensor_uwSensorAnalogGainCodeStep_MSByte , 0x159d, 0x0000 }, +{ SensorCapabilitiesNearSensor_uwSensorAnalogGainType_LSByte , 0x15a2, 0x0000 }, +{ SensorCapabilitiesNearSensor_uwSensorAnalogGainType_MSByte , 0x15a1, 0x0000 }, +{ SensorCapabilitiesNearSensor_fpSensorAnalogGainConstM0_LSByte , 0x15a6, 0x0000 }, +{ SensorCapabilitiesNearSensor_fpSensorAnalogGainConstM0_MSByte , 0x15a5, 0x0000 }, +{ SensorCapabilitiesNearSensor_fpSensorAnalogGainConstC0_LSByte , 0x15aa, 0x0000 }, +{ SensorCapabilitiesNearSensor_fpSensorAnalogGainConstC0_MSByte , 0x15a9, 0x0000 }, +{ SensorCapabilitiesNearSensor_fpSensorAnalogGainConstM1_LSByte , 0x15ae, 0x0000 }, +{ SensorCapabilitiesNearSensor_fpSensorAnalogGainConstM1_MSByte , 0x15ad, 0x0000 }, +{ SensorCapabilitiesNearSensor_fpSensorAnalogGainConstC1_LSByte , 0x15b2, 0x0000 }, +{ SensorCapabilitiesNearSensor_fpSensorAnalogGainConstC1_MSByte , 0x15b1, 0x0000 }, +{ SensorCapabilitiesNearSensor_uwSensorConstantColumns_LSByte , 0x15b6, 0x0000 }, +{ SensorCapabilitiesNearSensor_uwSensorConstantColumns_MSByte , 0x15b5, 0x0000 }, +{ SensorCapabilitiesNearSensor_uwStartOfActiveColumns_LSByte , 0x15ba, 0x0000 }, +{ SensorCapabilitiesNearSensor_uwStartOfActiveColumns_MSByte , 0x15b9, 0x0000 }, +{ SensorCapabilitiesNearSensor_bActiveColumnDescriptorNumber , 0x15bc, 0x0000 }, +{ SensorCapabilitiesNearSensor_bSensorStartOfActiveLines , 0x15be, 0x0000 }, +{ SensorCapabilitiesNearSensor_uwSensorConstantRows_LSByte , 0x15c2, 0x0000 }, +{ SensorCapabilitiesNearSensor_uwSensorConstantRows_MSByte , 0x15c1, 0x0000 }, +{ SensorCapabilitiesNearSensor_uwSensorStatusLines_LSByte , 0x15c6, 0x0000 }, +{ SensorCapabilitiesNearSensor_uwSensorStatusLines_MSByte , 0x15c5, 0x0000 }, +{ SensorCapabilitiesNearSensor_bPreActiveDarkLines_LSByte , 0x15ca, 0x0000 }, +{ SensorCapabilitiesNearSensor_bPreActiveDarkLines_MSByte , 0x15c9, 0x0000 }, +{ SensorCapabilitiesNearSensor_bPreActiveBlackLines_LSByte , 0x15ce, 0x0000 }, +{ SensorCapabilitiesNearSensor_bPreActiveBlackLines_MSByte , 0x15cd, 0x0000 }, +{ SensorCapabilitiesNearSensor_bSensorVFPNLines , 0x15d0, 0x0000 }, +{ SensorCapabilitiesNearSensor_uwSensorDigitalGainCapability_LSByte , 0x15d4, 0x0000 }, +{ SensorCapabilitiesNearSensor_uwSensorDigitalGainCapability_MSByte , 0x15d3, 0x0000 }, +{ SensorCapabilitiesNearSensor_uwSensorDigitalGainMinimum_LSByte , 0x15d8, 0x0000 }, +{ SensorCapabilitiesNearSensor_uwSensorDigitalGainMinimum_MSByte , 0x15d7, 0x0000 }, +{ SensorCapabilitiesNearSensor_uwSensorDataPedestal_LSByte , 0x15dc, 0x0000 }, +{ SensorCapabilitiesNearSensor_uwSensorDataPedestal_MSByte , 0x15db, 0x0000 }, +{ SensorCapabilitiesCurrentSensor_uwSensorIntegrationTimeCapability_LSByte , 0x1602, 0x0000 }, +{ SensorCapabilitiesCurrentSensor_uwSensorIntegrationTimeCapability_MSByte , 0x1601, 0x0000 }, +{ SensorCapabilitiesCurrentSensor_uwSensorMinimumCoarseIntegrationLines_LSByte , 0x1606, 0x0000 }, +{ SensorCapabilitiesCurrentSensor_uwSensorMinimumCoarseIntegrationLines_MSByte , 0x1605, 0x0000 }, +{ SensorCapabilitiesCurrentSensor_uwSensorCoarseIntegrationTimeMaxMargin_LSByte , 0x160a, 0x0000 }, +{ SensorCapabilitiesCurrentSensor_uwSensorCoarseIntegrationTimeMaxMargin_MSByte , 0x1609, 0x0000 }, +{ SensorCapabilitiesCurrentSensor_uwSensorMinimumFineIntegrationPixels_LSByte , 0x160e, 0x0000 }, +{ SensorCapabilitiesCurrentSensor_uwSensorMinimumFineIntegrationPixels_MSByte , 0x160d, 0x0000 }, +{ SensorCapabilitiesCurrentSensor_uwSensorFineIntegrationTimeMaxMargin_LSByte , 0x1612, 0x0000 }, +{ SensorCapabilitiesCurrentSensor_uwSensorFineIntegrationTimeMaxMargin_MSByte , 0x1611, 0x0000 }, +{ SensorCapabilitiesCurrentSensor_uwSensorAnalogGainMinimum_LSByte , 0x1616, 0x0000 }, +{ SensorCapabilitiesCurrentSensor_uwSensorAnalogGainMinimum_MSByte , 0x1615, 0x0020 }, +{ SensorCapabilitiesCurrentSensor_uwSensorAnalogGainMaximum_LSByte , 0x161a, 0x0000 }, +{ SensorCapabilitiesCurrentSensor_uwSensorAnalogGainMaximum_MSByte , 0x1619, 0x0080 }, +{ SensorCapabilitiesCurrentSensor_uwSensorAnalogGainCodeStep_LSByte , 0x161e, 0x0000 }, +{ SensorCapabilitiesCurrentSensor_uwSensorAnalogGainCodeStep_MSByte , 0x161d, 0x0000 }, +{ SensorCapabilitiesCurrentSensor_uwSensorAnalogGainType_LSByte , 0x1622, 0x0000 }, +{ SensorCapabilitiesCurrentSensor_uwSensorAnalogGainType_MSByte , 0x1621, 0x0000 }, +{ SensorCapabilitiesCurrentSensor_fpSensorAnalogGainConstM0_LSByte , 0x1626, 0x0000 }, +{ SensorCapabilitiesCurrentSensor_fpSensorAnalogGainConstM0_MSByte , 0x1625, 0x0000 }, +{ SensorCapabilitiesCurrentSensor_fpSensorAnalogGainConstC0_LSByte , 0x162a, 0x0000 }, +{ SensorCapabilitiesCurrentSensor_fpSensorAnalogGainConstC0_MSByte , 0x1629, 0x0000 }, +{ SensorCapabilitiesCurrentSensor_fpSensorAnalogGainConstM1_LSByte , 0x162e, 0x0000 }, +{ SensorCapabilitiesCurrentSensor_fpSensorAnalogGainConstM1_MSByte , 0x162d, 0x0000 }, +{ SensorCapabilitiesCurrentSensor_fpSensorAnalogGainConstC1_LSByte , 0x1632, 0x0000 }, +{ SensorCapabilitiesCurrentSensor_fpSensorAnalogGainConstC1_MSByte , 0x1631, 0x0000 }, +{ SensorCapabilitiesCurrentSensor_uwSensorConstantColumns_LSByte , 0x1636, 0x0000 }, +{ SensorCapabilitiesCurrentSensor_uwSensorConstantColumns_MSByte , 0x1635, 0x0000 }, +{ SensorCapabilitiesCurrentSensor_uwStartOfActiveColumns_LSByte , 0x163a, 0x0000 }, +{ SensorCapabilitiesCurrentSensor_uwStartOfActiveColumns_MSByte , 0x1639, 0x0000 }, +{ SensorCapabilitiesCurrentSensor_bActiveColumnDescriptorNumber , 0x163c, 0x0000 }, +{ SensorCapabilitiesCurrentSensor_bSensorStartOfActiveLines , 0x163e, 0x0000 }, +{ SensorCapabilitiesCurrentSensor_uwSensorConstantRows_LSByte , 0x1642, 0x0000 }, +{ SensorCapabilitiesCurrentSensor_uwSensorConstantRows_MSByte , 0x1641, 0x0000 }, +{ SensorCapabilitiesCurrentSensor_uwSensorStatusLines_LSByte , 0x1646, 0x0000 }, +{ SensorCapabilitiesCurrentSensor_uwSensorStatusLines_MSByte , 0x1645, 0x0000 }, +{ SensorCapabilitiesCurrentSensor_bPreActiveDarkLines_LSByte , 0x164a, 0x0000 }, +{ SensorCapabilitiesCurrentSensor_bPreActiveDarkLines_MSByte , 0x1649, 0x0000 }, +{ SensorCapabilitiesCurrentSensor_bPreActiveBlackLines_LSByte , 0x164e, 0x0000 }, +{ SensorCapabilitiesCurrentSensor_bPreActiveBlackLines_MSByte , 0x164d, 0x0000 }, +{ SensorCapabilitiesCurrentSensor_bSensorVFPNLines , 0x1650, 0x0000 }, +{ SensorCapabilitiesCurrentSensor_uwSensorDigitalGainCapability_LSByte , 0x1654, 0x0000 }, +{ SensorCapabilitiesCurrentSensor_uwSensorDigitalGainCapability_MSByte , 0x1653, 0x0000 }, +{ SensorCapabilitiesCurrentSensor_uwSensorDigitalGainMinimum_LSByte , 0x1658, 0x0000 }, +{ SensorCapabilitiesCurrentSensor_uwSensorDigitalGainMinimum_MSByte , 0x1657, 0x0000 }, +{ SensorCapabilitiesCurrentSensor_uwSensorDataPedestal_LSByte , 0x165c, 0x0000 }, +{ SensorCapabilitiesCurrentSensor_uwSensorDataPedestal_MSByte , 0x165b, 0x0000 }, +{ SensorFrameConstraintsFar_uwVTXAddrMin_LSByte , 0x1682, 0x0000 }, +{ SensorFrameConstraintsFar_uwVTXAddrMin_MSByte , 0x1681, 0x0000 }, +{ SensorFrameConstraintsFar_uwVTYAddrMin_LSByte , 0x1686, 0x0000 }, +{ SensorFrameConstraintsFar_uwVTYAddrMin_MSByte , 0x1685, 0x0000 }, +{ SensorFrameConstraintsFar_uwVTXAddrMax_LSByte , 0x168a, 0x0000 }, +{ SensorFrameConstraintsFar_uwVTXAddrMax_MSByte , 0x1689, 0x0000 }, +{ SensorFrameConstraintsFar_uwVTYAddrMax_LSByte , 0x168e, 0x0000 }, +{ SensorFrameConstraintsFar_uwVTYAddrMax_MSByte , 0x168d, 0x0000 }, +{ SensorFrameConstraintsFar_uwMinOPXOutputSize_LSByte , 0x1692, 0x0000 }, +{ SensorFrameConstraintsFar_uwMinOPXOutputSize_MSByte , 0x1691, 0x0000 }, +{ SensorFrameConstraintsFar_uwMinOPYOutputSize_LSByte , 0x1696, 0x0000 }, +{ SensorFrameConstraintsFar_uwMinOPYOutputSize_MSByte , 0x1695, 0x0000 }, +{ SensorFrameConstraintsFar_uwMaxOPXOutputSize_LSByte , 0x169a, 0x0000 }, +{ SensorFrameConstraintsFar_uwMaxOPXOutputSize_MSByte , 0x1699, 0x0000 }, +{ SensorFrameConstraintsFar_uwMaxOPYOutputSize_LSByte , 0x169e, 0x0000 }, +{ SensorFrameConstraintsFar_uwMaxOPYOutputSize_MSByte , 0x169d, 0x0000 }, +{ SensorFrameConstraintsFar_uwMinVTFrameLengthLines_LSByte , 0x16a2, 0x0000 }, +{ SensorFrameConstraintsFar_uwMinVTFrameLengthLines_MSByte , 0x16a1, 0x0000 }, +{ SensorFrameConstraintsFar_uwMaxVTFrameLengthLines_LSByte , 0x16a6, 0x0000 }, +{ SensorFrameConstraintsFar_uwMaxVTFrameLengthLines_MSByte , 0x16a5, 0x0000 }, +{ SensorFrameConstraintsFar_uwMinVTLineLengthPck_LSByte , 0x16aa, 0x0000 }, +{ SensorFrameConstraintsFar_uwMinVTLineLengthPck_MSByte , 0x16a9, 0x0000 }, +{ SensorFrameConstraintsFar_uwMaxVTLineLengthPck_LSByte , 0x16ae, 0x0000 }, +{ SensorFrameConstraintsFar_uwMaxVTLineLengthPck_MSByte , 0x16ad, 0x0000 }, +{ SensorFrameConstraintsFar_uwMinVTLineBlankingPck_LSByte , 0x16b2, 0x0000 }, +{ SensorFrameConstraintsFar_uwMinVTLineBlankingPck_MSByte , 0x16b1, 0x0000 }, +{ SensorFrameConstraintsFar_uwMinVTFrameBlanking_LSByte , 0x16b6, 0x0000 }, +{ SensorFrameConstraintsFar_uwMinVTFrameBlanking_MSByte , 0x16b5, 0x0000 }, +{ SensorFrameConstraintsNear_uwVTXAddrMin_LSByte , 0x1702, 0x0000 }, +{ SensorFrameConstraintsNear_uwVTXAddrMin_MSByte , 0x1701, 0x0000 }, +{ SensorFrameConstraintsNear_uwVTYAddrMin_LSByte , 0x1706, 0x0000 }, +{ SensorFrameConstraintsNear_uwVTYAddrMin_MSByte , 0x1705, 0x0000 }, +{ SensorFrameConstraintsNear_uwVTXAddrMax_LSByte , 0x170a, 0x0000 }, +{ SensorFrameConstraintsNear_uwVTXAddrMax_MSByte , 0x1709, 0x0000 }, +{ SensorFrameConstraintsNear_uwVTYAddrMax_LSByte , 0x170e, 0x0000 }, +{ SensorFrameConstraintsNear_uwVTYAddrMax_MSByte , 0x170d, 0x0000 }, +{ SensorFrameConstraintsNear_uwMinOPXOutputSize_LSByte , 0x1712, 0x0000 }, +{ SensorFrameConstraintsNear_uwMinOPXOutputSize_MSByte , 0x1711, 0x0000 }, +{ SensorFrameConstraintsNear_uwMinOPYOutputSize_LSByte , 0x1716, 0x0000 }, +{ SensorFrameConstraintsNear_uwMinOPYOutputSize_MSByte , 0x1715, 0x0000 }, +{ SensorFrameConstraintsNear_uwMaxOPXOutputSize_LSByte , 0x171a, 0x0000 }, +{ SensorFrameConstraintsNear_uwMaxOPXOutputSize_MSByte , 0x1719, 0x0000 }, +{ SensorFrameConstraintsNear_uwMaxOPYOutputSize_LSByte , 0x171e, 0x0000 }, +{ SensorFrameConstraintsNear_uwMaxOPYOutputSize_MSByte , 0x171d, 0x0000 }, +{ SensorFrameConstraintsNear_uwMinVTFrameLengthLines_LSByte , 0x1722, 0x0000 }, +{ SensorFrameConstraintsNear_uwMinVTFrameLengthLines_MSByte , 0x1721, 0x0000 }, +{ SensorFrameConstraintsNear_uwMaxVTFrameLengthLines_LSByte , 0x1726, 0x0000 }, +{ SensorFrameConstraintsNear_uwMaxVTFrameLengthLines_MSByte , 0x1725, 0x0000 }, +{ SensorFrameConstraintsNear_uwMinVTLineLengthPck_LSByte , 0x172a, 0x0000 }, +{ SensorFrameConstraintsNear_uwMinVTLineLengthPck_MSByte , 0x1729, 0x0000 }, +{ SensorFrameConstraintsNear_uwMaxVTLineLengthPck_LSByte , 0x172e, 0x0000 }, +{ SensorFrameConstraintsNear_uwMaxVTLineLengthPck_MSByte , 0x172d, 0x0000 }, +{ SensorFrameConstraintsNear_uwMinVTLineBlankingPck_LSByte , 0x1732, 0x0000 }, +{ SensorFrameConstraintsNear_uwMinVTLineBlankingPck_MSByte , 0x1731, 0x0000 }, +{ SensorFrameConstraintsNear_uwMinVTFrameBlanking_LSByte , 0x1736, 0x0000 }, +{ SensorFrameConstraintsNear_uwMinVTFrameBlanking_MSByte , 0x1735, 0x0000 }, +{ AntiFlickerExposureControls_bMainsFrequency_Hz , 0x1780, 0x0032 }, +{ AntiFlickerExposureControls_fGuaranteeStaticFlickerFrameLength , 0x1782, 0x0000 }, +{ CurrentFrameDimension_uwVTFrameLengthLines_LSByte , 0x1802, 0x0000 }, +{ CurrentFrameDimension_uwVTFrameLengthLines_MSByte , 0x1801, 0x0000 }, +{ CurrentFrameDimension_uwVTLineLengthPck_LSByte , 0x1806, 0x0000 }, +{ CurrentFrameDimension_uwVTLineLengthPck_MSByte , 0x1805, 0x0000 }, +{ CurrentFrameDimension_uwVTXAddrStart_LSByte , 0x180a, 0x0000 }, +{ CurrentFrameDimension_uwVTXAddrStart_MSByte , 0x1809, 0x0000 }, +{ CurrentFrameDimension_uwVTYAddrStart_LSByte , 0x180e, 0x0000 }, +{ CurrentFrameDimension_uwVTYAddrStart_MSByte , 0x180d, 0x0000 }, +{ CurrentFrameDimension_uwVTXAddrEnd_LSByte , 0x1812, 0x0000 }, +{ CurrentFrameDimension_uwVTXAddrEnd_MSByte , 0x1811, 0x0000 }, +{ CurrentFrameDimension_uwVTYAddrEnd_LSByte , 0x1816, 0x0000 }, +{ CurrentFrameDimension_uwVTYAddrEnd_MSByte , 0x1815, 0x0000 }, +{ CurrentFrameDimension_uwOPXOutputSize_LSByte , 0x181a, 0x0000 }, +{ CurrentFrameDimension_uwOPXOutputSize_MSByte , 0x1819, 0x0000 }, +{ CurrentFrameDimension_uwOPYOutputSize_LSByte , 0x181e, 0x0000 }, +{ CurrentFrameDimension_uwOPYOutputSize_MSByte , 0x181d, 0x0000 }, +{ CurrentFrameDimension_uwVTXOutputSize_LSByte , 0x1822, 0x0000 }, +{ CurrentFrameDimension_uwVTXOutputSize_MSByte , 0x1821, 0x0000 }, +{ CurrentFrameDimension_uwVTYOutputSize_LSByte , 0x1826, 0x0000 }, +{ CurrentFrameDimension_uwVTYOutputSize_MSByte , 0x1825, 0x0000 }, +{ CurrentFrameDimension_bVTXSubSampling , 0x1828, 0x0000 }, +{ CurrentFrameDimension_uwXOddInc_LSByte , 0x182c, 0x0000 }, +{ CurrentFrameDimension_uwXOddInc_MSByte , 0x182b, 0x0000 }, +{ CurrentFrameDimension_bVTYSubSampling , 0x182e, 0x0000 }, +{ CurrentFrameDimension_uwYOddInc_LSByte , 0x1832, 0x0000 }, +{ CurrentFrameDimension_uwYOddInc_MSByte , 0x1831, 0x0000 }, +{ CurrentFrameDimension_bScalingMode , 0x1834, 0x0000 }, +{ CurrentFrameDimension_fpScaleFactor_LSByte , 0x1838, 0x0000 }, +{ CurrentFrameDimension_fpScaleFactor_MSByte , 0x1837, 0x0000 }, +{ CurrentFrameDimension_uwScalerM_LSByte , 0x183c, 0x0000 }, +{ CurrentFrameDimension_uwScalerM_MSByte , 0x183b, 0x0000 }, +{ SensorFrameConstraints_uwVTXAddrMin_LSByte , 0x1882, 0x0000 }, +{ SensorFrameConstraints_uwVTXAddrMin_MSByte , 0x1881, 0x0000 }, +{ SensorFrameConstraints_uwVTYAddrMin_LSByte , 0x1886, 0x0000 }, +{ SensorFrameConstraints_uwVTYAddrMin_MSByte , 0x1885, 0x0000 }, +{ SensorFrameConstraints_uwVTXAddrMax_LSByte , 0x188a, 0x0000 }, +{ SensorFrameConstraints_uwVTXAddrMax_MSByte , 0x1889, 0x0000 }, +{ SensorFrameConstraints_uwVTYAddrMax_LSByte , 0x188e, 0x0000 }, +{ SensorFrameConstraints_uwVTYAddrMax_MSByte , 0x188d, 0x0000 }, +{ SensorFrameConstraints_uwMinOPXOutputSize_LSByte , 0x1892, 0x0000 }, +{ SensorFrameConstraints_uwMinOPXOutputSize_MSByte , 0x1891, 0x0000 }, +{ SensorFrameConstraints_uwMinOPYOutputSize_LSByte , 0x1896, 0x0000 }, +{ SensorFrameConstraints_uwMinOPYOutputSize_MSByte , 0x1895, 0x0000 }, +{ SensorFrameConstraints_uwMaxOPXOutputSize_LSByte , 0x189a, 0x0000 }, +{ SensorFrameConstraints_uwMaxOPXOutputSize_MSByte , 0x1899, 0x0000 }, +{ SensorFrameConstraints_uwMaxOPYOutputSize_LSByte , 0x189e, 0x0000 }, +{ SensorFrameConstraints_uwMaxOPYOutputSize_MSByte , 0x189d, 0x0000 }, +{ SensorFrameConstraints_uwMinVTFrameLengthLines_LSByte , 0x18a2, 0x0000 }, +{ SensorFrameConstraints_uwMinVTFrameLengthLines_MSByte , 0x18a1, 0x0000 }, +{ SensorFrameConstraints_uwMaxVTFrameLengthLines_LSByte , 0x18a6, 0x0000 }, +{ SensorFrameConstraints_uwMaxVTFrameLengthLines_MSByte , 0x18a5, 0x0000 }, +{ SensorFrameConstraints_uwMinVTLineLengthPck_LSByte , 0x18aa, 0x0000 }, +{ SensorFrameConstraints_uwMinVTLineLengthPck_MSByte , 0x18a9, 0x0000 }, +{ SensorFrameConstraints_uwMaxVTLineLengthPck_LSByte , 0x18ae, 0x0000 }, +{ SensorFrameConstraints_uwMaxVTLineLengthPck_MSByte , 0x18ad, 0x0000 }, +{ SensorFrameConstraints_uwMinVTLineBlankingPck_LSByte , 0x18b2, 0x0000 }, +{ SensorFrameConstraints_uwMinVTLineBlankingPck_MSByte , 0x18b1, 0x0000 }, +{ SensorFrameConstraints_uwMinVTFrameBlanking_LSByte , 0x18b6, 0x0000 }, +{ SensorFrameConstraints_uwMinVTFrameBlanking_MSByte , 0x18b5, 0x0000 }, +{ HostFrameConstraints_uwMinimumOPLineBlanking_pixels_LSByte , 0x1902, 0x0000 }, +{ HostFrameConstraints_uwMinimumOPLineBlanking_pixels_MSByte , 0x1901, 0x0000 }, +{ HostFrameConstraints_uwMinimumOPFrameBlanking_lines_LSByte , 0x1906, 0x0000 }, +{ HostFrameConstraints_uwMinimumOPFrameBlanking_lines_MSByte , 0x1905, 0x0000 }, +{ HostFrameConstraints_bMinimumPostScalar0LineBlanking_pixels , 0x1908, 0x0000 }, +{ HostFrameConstraints_bMinimumPostScalar1LineBlanking_pixels , 0x190a, 0x0000 }, +{ FrameDimensionStatus_fFrameLengthChangePending , 0x1980, 0x0000 }, +{ FrameDimensionStatus_fFrameDimensionChangePending , 0x1982, 0x0000 }, +{ FrameDimensionStatus_uwVTFrameLengthPending_lines_LSByte , 0x1986, 0x0000 }, +{ FrameDimensionStatus_uwVTFrameLengthPending_lines_MSByte , 0x1985, 0x0000 }, +{ FrameDimensionStatus_fFrameLengthChangeInhibitedForCoarseExposure , 0x1988, 0x0000 }, +{ FrameDimensionStatus_uwMinVTLineLengthAtCurrentVTXSize_pixels_LSByte , 0x198c, 0x0000 }, +{ FrameDimensionStatus_uwMinVTLineLengthAtCurrentVTXSize_pixels_MSByte , 0x198b, 0x0000 }, +{ FrameDimensionStatus_uwMinVTFrameLengthAtCurrentVTYSize_lines_LSByte , 0x1990, 0x0000 }, +{ FrameDimensionStatus_uwMinVTFrameLengthAtCurrentVTYSize_lines_MSByte , 0x198f, 0x0000 }, +{ FrameDimensionStatus_fpVTLineLength_us_LSByte , 0x1994, 0x0000 }, +{ FrameDimensionStatus_fpVTLineLength_us_MSByte , 0x1993, 0x0000 }, +{ FrameDimensionStatus_fpVTFrameLength_us_LSByte , 0x1998, 0x0000 }, +{ FrameDimensionStatus_fpVTFrameLength_us_MSByte , 0x1997, 0x0000 }, +{ FrameDimensionStatus_fpCurrentFrameRate_LSByte , 0x199c, 0x0000 }, +{ FrameDimensionStatus_fpCurrentFrameRate_MSByte , 0x199b, 0x0000 }, +{ FrameDimensionStatus_uwMaximumSensorFOVX_LSByte , 0x19a0, 0x0000 }, +{ FrameDimensionStatus_uwMaximumSensorFOVX_MSByte , 0x199f, 0x0000 }, +{ FrameDimensionStatus_uwMaximumSensorFOVY_LSByte , 0x19a4, 0x0000 }, +{ FrameDimensionStatus_uwMaximumSensorFOVY_MSByte , 0x19a3, 0x0000 }, +{ FrameDimensionStatus_uwOPXOutputSize_LSByte , 0x19a8, 0x0000 }, +{ FrameDimensionStatus_uwOPXOutputSize_MSByte , 0x19a7, 0x0000 }, +{ FrameDimensionStatus_fSensorPreScaleFactorChanged , 0x19aa, 0x0000 }, +{ BinningControl_fEnableBinning , 0x1a00, 0x0000 }, +{ BinningStatus_fBinningEnabled , 0x1a80, 0x0000 }, +{ Sensor0BinningInputs_uwMinVTLineLengthPck_LSByte , 0x1b02, 0x0000 }, +{ Sensor0BinningInputs_uwMinVTLineLengthPck_MSByte , 0x1b01, 0x0000 }, +{ Sensor0BinningInputs_uwSensorMinimumFineIntegrationPixels_LSByte , 0x1b06, 0x0000 }, +{ Sensor0BinningInputs_uwSensorMinimumFineIntegrationPixels_MSByte , 0x1b05, 0x0000 }, +{ Sensor1BinningInputs_uwMinVTLineLengthPck_LSByte , 0x1b82, 0x0000 }, +{ Sensor1BinningInputs_uwMinVTLineLengthPck_MSByte , 0x1b81, 0x0000 }, +{ Sensor1BinningInputs_uwSensorMinimumFineIntegrationPixels_LSByte , 0x1b86, 0x0000 }, +{ Sensor1BinningInputs_uwSensorMinimumFineIntegrationPixels_MSByte , 0x1b85, 0x0000 }, +{ CurrentSensorBinningInputs_uwMinVTLineLengthPck_LSByte , 0x1c02, 0x0000 }, +{ CurrentSensorBinningInputs_uwMinVTLineLengthPck_MSByte , 0x1c01, 0x0000 }, +{ CurrentSensorBinningInputs_uwSensorMinimumFineIntegrationPixels_LSByte , 0x1c06, 0x0000 }, +{ CurrentSensorBinningInputs_uwSensorMinimumFineIntegrationPixels_MSByte , 0x1c05, 0x0000 }, +{ FlashManagerControl_bMode , 0x1c80, 0x0000 }, +{ FlashManagerControl_bFlashType , 0x1c82, 0x0002 }, +{ FlashManagerControl_fOrMainAndPreFlashPulse , 0x1c84, 0x0001 }, +{ FlashManagerControl_RefPointCalcMode , 0x1c86, 0x0000 }, +{ FlashManagerControl_wIntegrationStartPosition_LSByte , 0x1c8a, 0x0000 }, +{ FlashManagerControl_wIntegrationStartPosition_MSByte , 0x1c88, 0x0000 }, +{ FlashManagerControl_fOverrideIntegrationStartPosition , 0x1c8a, 0x0000 }, +{ FlashManagerControl_fpFlashFiringDelay_us_LSByte , 0x1c90, 0x0000 }, +{ FlashManagerControl_fpFlashFiringDelay_us_MSByte , 0x1c8c, 0x0000 }, +{ FlashManagerControl_bNumberOfPreFlashes , 0x1c8e, 0x0000 }, +{ FlashManagerControl_fpPulseWidthMainFlash_us_LSByte , 0x1c96, 0x0000 }, +{ FlashManagerControl_fpPulseWidthMainFlash_us_MSByte , 0x1c90, 0x0000 }, +{ FlashManagerControl_fpPulseWidthPreFlash_us_LSByte , 0x1c9a, 0x0000 }, +{ FlashManagerControl_fpPulseWidthPreFlash_us_MSByte , 0x1c92, 0x0000 }, +{ FlashManagerControl_fpTimeBetweenTwoPreFlashes_us_LSByte , 0x1c9e, 0x0000 }, +{ FlashManagerControl_fpTimeBetweenTwoPreFlashes_us_MSByte , 0x1c94, 0x0000 }, +{ FlashManagerControl_fpTimeBetweenPreFlashAndMainFlash_us_LSByte , 0x1ca2, 0x0000 }, +{ FlashManagerControl_fpTimeBetweenPreFlashAndMainFlash_us_MSByte , 0x1c96, 0x0000 }, +{ FlashManagerControl_cMainFlashStartFrame , 0x1c98, 0x0000 }, +{ FlashManagerControl_wMainFlashStartLine_LSByte , 0x1ca8, 0x0000 }, +{ FlashManagerControl_wMainFlashStartLine_MSByte , 0x1c9a, 0x0000 }, +{ FlashManagerControl_wMainFlashStartPixel_LSByte , 0x1cac, 0x0000 }, +{ FlashManagerControl_wMainFlashStartPixel_MSByte , 0x1c9c, 0x0000 }, +{ FlashManagerControl_cPreFlashStartFrame , 0x1c9e, 0x0000 }, +{ FlashManagerControl_wPreFlashStartLine_LSByte , 0x1cb2, 0x0000 }, +{ FlashManagerControl_wPreFlashStartLine_MSByte , 0x1ca0, 0x0000 }, +{ FlashManagerControl_wPreFlashStartPixel_LSByte , 0x1cb6, 0x0000 }, +{ FlashManagerControl_wPreFlashStartPixel_MSByte , 0x1ca2, 0x0000 }, +{ FlashManagerControl_bTotalFramesRequired , 0x1ca4, 0x0000 }, +{ FlashManagerStatus_fFlashSequencePending , 0x1d00, 0x0000 }, +{ FlashManagerStatus_cNumberFramesRequiredForPreFlashes , 0x1d02, 0x0000 }, +{ FlashManagerStatus_fpMainFlashPulseWidth_us_LSByte , 0x1d06, 0x0000 }, +{ FlashManagerStatus_fpMainFlashPulseWidth_us_MSByte , 0x1d05, 0x0000 }, +{ FlashManagerStatus_fpPreFlashPulseWidth_us_LSByte , 0x1d0a, 0x0000 }, +{ FlashManagerStatus_fpPreFlashPulseWidth_us_MSByte , 0x1d09, 0x0000 }, +{ FlashManagerStatus_fpInterPreflashDistance_us_LSByte , 0x1d0e, 0x0000 }, +{ FlashManagerStatus_fpInterPreflashDistance_us_MSByte , 0x1d0d, 0x0000 }, +{ FlashManagerStatus_fpPreAndMainflashDistance_us_LSByte , 0x1d12, 0x0000 }, +{ FlashManagerStatus_fpPreAndMainflashDistance_us_MSByte , 0x1d11, 0x0000 }, +{ FlashManagerStatus_cStartFlashFrame , 0x1d14, 0x0000 }, +{ FlashManagerStatus_wStartFlashLine_LSByte , 0x1d18, 0x0000 }, +{ FlashManagerStatus_wStartFlashLine_MSByte , 0x1d17, 0x0000 }, +{ FlashManagerStatus_wStartFlashPixel_LSByte , 0x1d1c, 0x0000 }, +{ FlashManagerStatus_wStartFlashPixel_MSByte , 0x1d1b, 0x0000 }, +{ FlashManagerStatus_cStartPreFlashFrame , 0x1d1e, 0x0000 }, +{ FlashManagerStatus_wStartPreFlashLine_LSByte , 0x1d22, 0x0000 }, +{ FlashManagerStatus_wStartPreFlashLine_MSByte , 0x1d21, 0x0000 }, +{ FlashManagerStatus_wStartPreFlashPixel_LSByte , 0x1d26, 0x0000 }, +{ FlashManagerStatus_wStartPreFlashPixel_MSByte , 0x1d25, 0x0000 }, +{ FlashManagerStatus_cNumberFramesRequired , 0x1d28, 0x0000 }, +{ FlashManagerStatus_fPreFlashPending , 0x1d2a, 0x0000 }, +{ FlashManagerStatus_fMainFlashPending , 0x1d2c, 0x0000 }, +{ ExposureControls_bMode , 0x1d80, 0x0000 }, +{ ExposureControls_bMetering , 0x1d82, 0x0002 }, +{ ExposureControls_bManualExposureTime_s_num , 0x1d84, 0x0000 }, +{ ExposureControls_bManualExposureTime_s_den , 0x1d86, 0x0000 }, +{ ExposureControls_fpManualDesiredExposureTime_us_LSByte , 0x1d8a, 0x0000 }, +{ ExposureControls_fpManualDesiredExposureTime_us_MSByte , 0x1d89, 0x0000 }, +{ ExposureControls_fpColdStartDesiredTime_us_LSByte , 0x1d8e, 0x0000 }, +{ ExposureControls_fpColdStartDesiredTime_us_MSByte , 0x1d8d, 0x59aa }, +{ ExposureControls_iExposureCompensation , 0x1d90, 0x0000 }, +{ ExposureControls_bMiscSettings , 0x1d92, 0x0000 }, +{ ExposureControls_uwDirectModeCoarseIntegration_lines_LSByte , 0x1d96, 0x0000 }, +{ ExposureControls_uwDirectModeCoarseIntegration_lines_MSByte , 0x1d95, 0x0000 }, +{ ExposureControls_uwDirectModeFineIntegration_pixels_LSByte , 0x1d9a, 0x0000 }, +{ ExposureControls_uwDirectModeFineIntegration_pixels_MSByte , 0x1d99, 0x0000 }, +{ ExposureControls_uwDirectModeCodedAnalogGain_LSByte , 0x1d9e, 0x0000 }, +{ ExposureControls_uwDirectModeCodedAnalogGain_MSByte , 0x1d9d, 0x0000 }, +{ ExposureControls_fpDirectModeDigitalGain_LSByte , 0x1da2, 0x0000 }, +{ ExposureControls_fpDirectModeDigitalGain_MSByte , 0x1da1, 0x0000 }, +{ ExposureControls_uwFlashGunModeCoarseIntegration_lines_LSByte , 0x1da6, 0x0000 }, +{ ExposureControls_uwFlashGunModeCoarseIntegration_lines_MSByte , 0x1da5, 0x0000 }, +{ ExposureControls_uwFlashGunModeFineIntegration_pixels_LSByte , 0x1daa, 0x0000 }, +{ ExposureControls_uwFlashGunModeFineIntegration_pixels_MSByte , 0x1da9, 0x0000 }, +{ ExposureControls_uwFlashGunModeCodedAnalogGain_LSByte , 0x1dae, 0x0000 }, +{ ExposureControls_uwFlashGunModeCodedAnalogGain_MSByte , 0x1dad, 0x0000 }, +{ ExposureControls_fpFlashGunModeDigitalGain_LSByte , 0x1db2, 0x0000 }, +{ ExposureControls_fpFlashGunModeDigitalGain_MSByte , 0x1db1, 0x0000 }, +{ ExposureControls_fFreezeAutoExposure , 0x1db4, 0x0000 }, +{ ExposureControls_fpUserMaximumIntegrationTime_us_LSByte , 0x1db8, 0x0000 }, +{ ExposureControls_fpUserMaximumIntegrationTime_us_MSByte , 0x1db7, 0x65d1 }, +{ ExposureControls_fpRecommendFlashGunAnalogGainThreshold_LSByte , 0x1dbc, 0x0000 }, +{ ExposureControls_fpRecommendFlashGunAnalogGainThreshold_MSByte , 0x1dbb, 0x624a }, +{ ExposureControls_fEnableHighClipForDesiredExposureTime , 0x1dbe, 0x0001 }, +{ ExposureControls_bAntiFlickerMode , 0x1dc0, 0x0001 }, +{ ExposureControls_fInhibitExposurePresetModeForFlash , 0x1dc2, 0x0000 }, +{ ExposureStatus_bAlgorithmStatus , 0x1e00, 0x0000 }, +{ ExposureStatus_bCompilerStatus , 0x1e02, 0x0000 }, +{ ExposureStatus_fWhiteBalanceGainIncludedInCurrentExposure , 0x1e04, 0x0000 }, +{ ExposureStatus_fBadExposureForIterativeWhiteBalance , 0x1e06, 0x0000 }, +{ ExposureStatus_uwCoarseIntegrationPending_lines_LSByte , 0x1e0a, 0x0000 }, +{ ExposureStatus_uwCoarseIntegrationPending_lines_MSByte , 0x1e09, 0x0000 }, +{ ExposureStatus_uwFineIntegrationPending_pixels_LSByte , 0x1e0e, 0x0000 }, +{ ExposureStatus_uwFineIntegrationPending_pixels_MSByte , 0x1e0d, 0x0000 }, +{ ExposureStatus_fpAnalogGainPending_LSByte , 0x1e12, 0x0000 }, +{ ExposureStatus_fpAnalogGainPending_MSByte , 0x1e11, 0x0000 }, +{ ExposureStatus_fpDigitalGainPending_LSByte , 0x1e16, 0x0000 }, +{ ExposureStatus_fpDigitalGainPending_MSByte , 0x1e15, 0x0000 }, +{ ExposureStatus_fpDesiredExposureTime_us_LSByte , 0x1e1a, 0x0000 }, +{ ExposureStatus_fpDesiredExposureTime_us_MSByte , 0x1e19, 0x0000 }, +{ ExposureStatus_fpCompiledExposureTime_us_LSByte , 0x1e1e, 0x0000 }, +{ ExposureStatus_fpCompiledExposureTime_us_MSByte , 0x1e1d, 0x0000 }, +{ ExposureStatus_bControlLoopFailureCount , 0x1e20, 0x0000 }, +{ ExposureStatus_uwUserMaximumIntegrationLines_LSByte , 0x1e24, 0x0000 }, +{ ExposureStatus_uwUserMaximumIntegrationLines_MSByte , 0x1e23, 0x0000 }, +{ ExposureStatus_fpTotalIntegrationTimePending_us_LSByte , 0x1e28, 0x0000 }, +{ ExposureStatus_fpTotalIntegrationTimePending_us_MSByte , 0x1e27, 0x0000 }, +{ ExposureStatus_uwCodedAnalogGainPending_LSByte , 0x1e2c, 0x0000 }, +{ ExposureStatus_uwCodedAnalogGainPending_MSByte , 0x1e2b, 0x0000 }, +{ ExposureStatus_fExposureIsStableforAutoFocus , 0x1e2e, 0x0000 }, +{ ExposureStatus_bRuntimeExposureTarget , 0x1e30, 0x0000 }, +{ ExposureParametersApplied_uwCoarseIntegration_lines_LSByte , 0x1e82, 0x0000 }, +{ ExposureParametersApplied_uwCoarseIntegration_lines_MSByte , 0x1e81, 0x0000 }, +{ ExposureParametersApplied_uwFineIntegration_pixels_LSByte , 0x1e86, 0x0000 }, +{ ExposureParametersApplied_uwFineIntegration_pixels_MSByte , 0x1e85, 0x0000 }, +{ ExposureParametersApplied_uwCodedAnalogGain_LSByte , 0x1e8a, 0x0000 }, +{ ExposureParametersApplied_uwCodedAnalogGain_MSByte , 0x1e89, 0x0000 }, +{ ExposureParametersApplied_fpDigitalGain_LSByte , 0x1e8e, 0x0000 }, +{ ExposureParametersApplied_fpDigitalGain_MSByte , 0x1e8d, 0x0000 }, +{ ExposureStatisticsStatus_fpMeanEnergy_LSByte , 0x1f02, 0x0000 }, +{ ExposureStatisticsStatus_fpMeanEnergy_MSByte , 0x1f01, 0x0000 }, +{ ExposureCycleTest_fpInitialDesiredExposureTime_LSByte , 0x1f82, 0x0000 }, +{ ExposureCycleTest_fpInitialDesiredExposureTime_MSByte , 0x1f81, 0x0000 }, +{ ExposureCycleTest_fpFinalDesiredExposureTime_LSByte , 0x1f86, 0x0000 }, +{ ExposureCycleTest_fpFinalDesiredExposureTime_MSByte , 0x1f85, 0x0000 }, +{ ExposureCycleTest_fpExposureStep_LSByte , 0x1f8a, 0x0000 }, +{ ExposureCycleTest_fpExposureStep_MSByte , 0x1f89, 0x0000 }, +{ ExposureCycleTest_bStepDirection , 0x1f8c, 0x0000 }, +{ ExposureTestCoin_fTestCoinEnabled , 0x2000, 0x0000 }, +{ ExposureTestCoin_fRunForTest , 0x2002, 0x0000 }, +{ ExposureTestCoin_bStatusCoin , 0x2004, 0x0000 }, +{ ExposureTestCoin_bControlCoin , 0x2006, 0x0000 }, +{ ExposureAlgorithmControls_fpMaximumStep_LSByte , 0x2082, 0x0000 }, +{ ExposureAlgorithmControls_fpMaximumStep_MSByte , 0x2081, 0x0000 }, +{ ExposureAlgorithmControls_fpMinimumStep_LSByte , 0x2086, 0x0000 }, +{ ExposureAlgorithmControls_fpMinimumStep_MSByte , 0x2085, 0x0000 }, +{ ExposureAlgorithmControls_fpMinimumDesiredExposureTime_us_LSByte , 0x208a, 0x0000 }, +{ ExposureAlgorithmControls_fpMinimumDesiredExposureTime_us_MSByte , 0x2089, 0x0000 }, +{ ExposureAlgorithmControls_fpStepProportion_LSByte , 0x208e, 0x0000 }, +{ ExposureAlgorithmControls_fpStepProportion_MSByte , 0x208d, 0x0000 }, +{ ExposureAlgorithmControls_fpMaximumNegativeStepThreshold_LSByte , 0x2092, 0x0000 }, +{ ExposureAlgorithmControls_fpMaximumNegativeStepThreshold_MSByte , 0x2091, 0x0000 }, +{ ExposureAlgorithmControls_fpRelativeOnTargetStabilityThreshold_LSByte , 0x2096, 0x0000 }, +{ ExposureAlgorithmControls_fpRelativeOnTargetStabilityThreshold_MSByte , 0x2095, 0x0000 }, +{ ExposureAlgorithmControls_fpDigitalGainFloor_LSByte , 0x209a, 0x0000 }, +{ ExposureAlgorithmControls_fpDigitalGainFloor_MSByte , 0x2099, 0x3e00 }, +{ ExposureAlgorithmControls_fpDigitalGainCeiling_LSByte , 0x209e, 0x0000 }, +{ ExposureAlgorithmControls_fpDigitalGainCeiling_MSByte , 0x209d, 0x4080 }, +{ ExposureAlgorithmControls_fpRelativeIntTimeHysThreshold_LSByte , 0x20a2, 0x0000 }, +{ ExposureAlgorithmControls_fpRelativeIntTimeHysThreshold_MSByte , 0x20a1, 0x0000 }, +{ ExposureAlgorithmControls_fpRelativeDigitalGainHysThreshold_LSByte , 0x20a6, 0x0000 }, +{ ExposureAlgorithmControls_fpRelativeDigitalGainHysThreshold_MSByte , 0x20a5, 0x0000 }, +{ ExposureAlgorithmControls_fpRelativeCompilationProblemThreshold_LSByte , 0x20aa, 0x0000 }, +{ ExposureAlgorithmControls_fpRelativeCompilationProblemThreshold_MSByte , 0x20a9, 0x0000 }, +{ ExposureAlgorithmControls_fpRoundUpBunchFudge_LSByte , 0x20ae, 0x0000 }, +{ ExposureAlgorithmControls_fpRoundUpBunchFudge_MSByte , 0x20ad, 0x0000 }, +{ ExposureAlgorithmControls_fpFineClampThreshold_LSByte , 0x20b2, 0x0000 }, +{ ExposureAlgorithmControls_fpFineClampThreshold_MSByte , 0x20b1, 0x0000 }, +{ ExposureAlgorithmControls_fpMaximumManualExposureTime_s_LSByte , 0x20b6, 0x0000 }, +{ ExposureAlgorithmControls_fpMaximumManualExposureTime_s_MSByte , 0x20b5, 0x0000 }, +{ ExposureAlgorithmControls_fpRelativeStabilityThresholdForAutoFocus_LSByte , 0x20ba, 0x0000 }, +{ ExposureAlgorithmControls_fpRelativeStabilityThresholdForAutoFocus_MSByte , 0x20b9, 0x0000 }, +{ ExposureAlgorithmControls_bLeakShift , 0x20bc, 0x0000 }, +{ ExposureAlgorithmStatus_fpLeakyEnergy_LSByte , 0x2102, 0x0000 }, +{ ExposureAlgorithmStatus_fpLeakyEnergy_MSByte , 0x2101, 0x0000 }, +{ ExposureAlgorithmStatus_fpRelativeStep_LSByte , 0x2106, 0x0000 }, +{ ExposureAlgorithmStatus_fpRelativeStep_MSByte , 0x2105, 0x0000 }, +{ ExposureUpdateErrorControl_bMaximumNumberOfFrames , 0x2180, 0x0000 }, +{ ExposureUpdateErrorStatus_bNumberOfForcedInputProcUpdates , 0x2200, 0x0000 }, +{ ExposureUpdateErrorStatus_bNumberOfConsecutiveDelayedFrames , 0x2202, 0x0000 }, +{ ExposureUpdateErrorStatus_fForceInputProcUpdation , 0x2204, 0x0000 }, +{ WhiteBalanceControls_bMode , 0x2280, 0x0001 }, +{ WhiteBalanceControls_bManualRedGain , 0x2282, 0x0000 }, +{ WhiteBalanceControls_bManualGreenGain , 0x2284, 0x0000 }, +{ WhiteBalanceControls_bManualBlueGain , 0x2286, 0x0000 }, +{ WhiteBalanceControls_bMiscSettings , 0x2288, 0x0000 }, +{ WhiteBalanceControls_fpFlashRedGain_LSByte , 0x228c, 0x0000 }, +{ WhiteBalanceControls_fpFlashRedGain_MSByte , 0x228b, 0x3e66 }, +{ WhiteBalanceControls_fpFlashGreenGain_LSByte , 0x2290, 0x0000 }, +{ WhiteBalanceControls_fpFlashGreenGain_MSByte , 0x228f, 0x3e00 }, +{ WhiteBalanceControls_fpFlashBlueGain_LSByte , 0x2294, 0x0000 }, +{ WhiteBalanceControls_fpFlashBlueGain_MSByte , 0x2293, 0x3f0a }, +{ WhiteBalanceControls_fInhibitWhiteBalancePresetModeForFlash , 0x2296, 0x0000 }, +{ WhiteBalanceAlgorithmControls_fpStableTotalStepThreshold_LSByte , 0x2302, 0x0000 }, +{ WhiteBalanceAlgorithmControls_fpStableTotalStepThreshold_MSByte , 0x2301, 0x2c00 }, +{ WhiteBalanceAlgorithmControls_fpMinimumRelativeStep_LSByte , 0x2306, 0x0000 }, +{ WhiteBalanceAlgorithmControls_fpMinimumRelativeStep_MSByte , 0x2305, 0x2a00 }, +{ WhiteBalanceAlgorithmControls_fpMaximumRelativeStep_LSByte , 0x230a, 0x0000 }, +{ WhiteBalanceAlgorithmControls_fpMaximumRelativeStep_MSByte , 0x2309, 0x3800 }, +{ WhiteBalanceAlgorithmControls_fpStepProportion_LSByte , 0x230e, 0x0000 }, +{ WhiteBalanceAlgorithmControls_fpStepProportion_MSByte , 0x230d, 0x3d00 }, +{ WhiteBalanceStatus_bStatus , 0x2380, 0x0000 }, +{ WhiteBalanceStatus_fUnityGainsUsed , 0x2382, 0x0000 }, +{ WhiteBalanceStatus_fpRedGain_LSByte , 0x2386, 0x0000 }, +{ WhiteBalanceStatus_fpRedGain_MSByte , 0x2385, 0x0000 }, +{ WhiteBalanceStatus_fpGreenGain_LSByte , 0x238a, 0x0000 }, +{ WhiteBalanceStatus_fpGreenGain_MSByte , 0x2389, 0x0000 }, +{ WhiteBalanceStatus_fpBlueGain_LSByte , 0x238e, 0x0000 }, +{ WhiteBalanceStatus_fpBlueGain_MSByte , 0x238d, 0x0000 }, +{ WhiteBalanceStatisticsControls_bLowThreshold , 0x2400, 0x0000 }, +{ WhiteBalanceStatisticsStatus_fpRedEnergy_LSByte , 0x2482, 0x0000 }, +{ WhiteBalanceStatisticsStatus_fpRedEnergy_MSByte , 0x2481, 0x0000 }, +{ WhiteBalanceStatisticsStatus_fpGreenEnergy_LSByte , 0x2486, 0x0000 }, +{ WhiteBalanceStatisticsStatus_fpGreenEnergy_MSByte , 0x2485, 0x0000 }, +{ WhiteBalanceStatisticsStatus_fpBlueEnergy_LSByte , 0x248a, 0x0000 }, +{ WhiteBalanceStatisticsStatus_fpBlueEnergy_MSByte , 0x2489, 0x0000 }, +{ MinWeightedWBControls_fDisable , 0x2500, 0x0000 }, +{ MinWeightedWBControls_uwSaturationThreshold_LSByte , 0x2504, 0x0000 }, +{ MinWeightedWBControls_uwSaturationThreshold_MSByte , 0x2503, 0x0300 }, +{ MinWeightedWBControls_fpRedTiltGain_LSByte , 0x2508, 0x0000 }, +{ MinWeightedWBControls_fpRedTiltGain_MSByte , 0x2507, 0x3e00 }, +{ MinWeightedWBControls_fpGreen1TiltGain_LSByte , 0x250c, 0x0000 }, +{ MinWeightedWBControls_fpGreen1TiltGain_MSByte , 0x250b, 0x3e40 }, +{ MinWeightedWBControls_fpGreen2TiltGain_LSByte , 0x2510, 0x0000 }, +{ MinWeightedWBControls_fpGreen2TiltGain_MSByte , 0x250f, 0x3e40 }, +{ MinWeightedWBControls_fpBlueTiltGain_LSByte , 0x2514, 0x0000 }, +{ MinWeightedWBControls_fpBlueTiltGain_MSByte , 0x2513, 0x3e40 }, +{ MinWeightedWBControls_GreenChannelToAccumulate , 0x2516, 0x0000 }, +{ MinWeightedWBStatus_uwZone_X_Offset_LSByte , 0x2582, 0x0000 }, +{ MinWeightedWBStatus_uwZone_X_Offset_MSByte , 0x2581, 0x0000 }, +{ MinWeightedWBStatus_uwZone_Y_Offset_LSByte , 0x2586, 0x0000 }, +{ MinWeightedWBStatus_uwZone_Y_Offset_MSByte , 0x2585, 0x0000 }, +{ MinWeightedWBStatus_uwZone_X_Size_LSByte , 0x258a, 0x0000 }, +{ MinWeightedWBStatus_uwZone_X_Size_MSByte , 0x2589, 0x0000 }, +{ MinWeightedWBStatus_uwZone_Y_Size_LSByte , 0x258e, 0x0000 }, +{ MinWeightedWBStatus_uwZone_Y_Size_MSByte , 0x258d, 0x0000 }, +{ MinWeightedWBStatus_fpNumberMacroPixel_LSByte , 0x2592, 0x0000 }, +{ MinWeightedWBStatus_fpNumberMacroPixel_MSByte , 0x2591, 0x0000 }, +{ MWWBStatisticsStatus_fpRedStatistics_LSByte , 0x2602, 0x0000 }, +{ MWWBStatisticsStatus_fpRedStatistics_MSByte , 0x2601, 0x0000 }, +{ MWWBStatisticsStatus_fpGreenStatistics_LSByte , 0x2606, 0x0000 }, +{ MWWBStatisticsStatus_fpGreenStatistics_MSByte , 0x2605, 0x0000 }, +{ MWWBStatisticsStatus_fpBlueStatistics_LSByte , 0x260a, 0x0000 }, +{ MWWBStatisticsStatus_fpBlueStatistics_MSByte , 0x2609, 0x0000 }, +{ MiscellaneousErrorStatus_bNumberOfEWBStatisticsErrors , 0x2680, 0x0000 }, +{ MiscellaneousErrorStatus_bEWBStatisticsInterruptCount , 0x2682, 0x0000 }, +{ AutomaticFrameRateControl_bMode , 0x2700, 0x0001 }, +{ AutomaticFrameRateControl_bImpliedGainThresholdLow_num , 0x2702, 0x0001 }, +{ AutomaticFrameRateControl_bImpliedGainThresholdLow_den , 0x2704, 0x0001 }, +{ AutomaticFrameRateControl_bImpliedGainThresholdHigh_num , 0x2706, 0x0003 }, +{ AutomaticFrameRateControl_bImpliedGainThresholdHigh_den , 0x2708, 0x0002 }, +{ AutomaticFrameRateControl_bUserMinimumFrameRate_Hz , 0x270a, 0x000f }, +{ AutomaticFrameRateControl_bUserMaximumFrameRate_Hz , 0x270c, 0x001e }, +{ AutomaticFrameRateControl_bRelativeChange_num , 0x270e, 0x0001 }, +{ AutomaticFrameRateControl_bRelativeChange_den , 0x2710, 0x0008 }, +{ AutomaticFrameRateControl_fDivorceMinFrameRateFromMaxIntegration , 0x2712, 0x0001 }, +{ AutomaticFrameRateStatus_fpImpliedGain_LSByte , 0x2782, 0x0000 }, +{ AutomaticFrameRateStatus_fpImpliedGain_MSByte , 0x2781, 0x0000 }, +{ AutomaticFrameRateStatus_uwMaximumFrameLength_lines_LSByte , 0x2786, 0x0000 }, +{ AutomaticFrameRateStatus_uwMaximumFrameLength_lines_MSByte , 0x2785, 0x0000 }, +{ AutomaticFrameRateStatus_uwMinimumFrameLength_lines_LSByte , 0x278a, 0x0000 }, +{ AutomaticFrameRateStatus_uwMinimumFrameLength_lines_MSByte , 0x2789, 0x0000 }, +{ AutomaticFrameRateStatus_uwFrameLengthChange_lines_LSByte , 0x278e, 0x0000 }, +{ AutomaticFrameRateStatus_uwFrameLengthChange_lines_MSByte , 0x278d, 0x0000 }, +{ AutomaticFrameRateStatus_fpDesiredAutomaticFrameRate_Hz_LSByte , 0x2792, 0x0000 }, +{ AutomaticFrameRateStatus_fpDesiredAutomaticFrameRate_Hz_MSByte , 0x2791, 0x0000 }, +{ AutomaticFrameRateStatus_uwCurrentFrameLength_lines_LSByte , 0x2796, 0x0000 }, +{ AutomaticFrameRateStatus_uwCurrentFrameLength_lines_MSByte , 0x2795, 0x0000 }, +{ AutomaticFrameRateStatus_uwDesiredFrameLength_lines_LSByte , 0x279a, 0x0000 }, +{ AutomaticFrameRateStatus_uwDesiredFrameLength_lines_MSByte , 0x2799, 0x0000 }, +{ AutomaticFrameRateStatus_fAutomaticFrameRateStable , 0x279c, 0x0000 }, +{ AutomaticFrameRateStatus_fAutomaticFrameRateClip , 0x279e, 0x0000 }, +{ StaticFrameRateControl_uwDesiredFrameRate_Num_LSByte , 0x2802, 0x0000 }, +{ StaticFrameRateControl_uwDesiredFrameRate_Num_MSByte , 0x2802, 0x001e }, +{ StaticFrameRateControl_bDesiredFrameRate_Den , 0x2804, 0x0001 }, +{ StaticFrameRateStatus_uwRequestedFrameRate_Hz_LSByte , 0x2882, 0x0000 }, +{ StaticFrameRateStatus_uwRequestedFrameRate_Hz_MSByte , 0x2881, 0x0000 }, +{ StaticFrameRateStatus_uwMaxFrameRate_Hz_LSByte , 0x2886, 0x0000 }, +{ StaticFrameRateStatus_uwMaxFrameRate_Hz_MSByte , 0x2885, 0x0000 }, +{ StaticFrameRateStatus_uwMinFrameRate_Hz_LSByte , 0x288a, 0x0000 }, +{ StaticFrameRateStatus_uwMinFrameRate_Hz_MSByte , 0x2889, 0x0000 }, +{ StaticFrameRateStatus_fChangePending , 0x288c, 0x0000 }, +{ StaticFrameRateStatus_uwRequiredFrameLength_lines_LSByte , 0x2890, 0x0000 }, +{ StaticFrameRateStatus_uwRequiredFrameLength_lines_MSByte , 0x288f, 0x0000 }, +{ StaticFrameRateStatus_ClipFrameRate , 0x2892, 0x0000 }, +{ ImageStability_fWhiteBalanceStable , 0x2900, 0x0000 }, +{ ImageStability_fExposureStable , 0x2902, 0x0000 }, +{ ImageStability_fFocusStable , 0x2904, 0x0000 }, +{ ImageStability_fLowPowerStreaming , 0x2906, 0x0000 }, +{ ImageStability_fStable , 0x2908, 0x0000 }, +{ ImageStability_fForcedStablility , 0x290a, 0x0000 }, +{ ImageStabilityMonitorControl_bMaxNumberOfFramesToWaitForStability , 0x2980, 0x0000 }, +{ ColdStartManagerControl_bControlCoin , 0x2a00, 0x0000 }, +{ ColdStartManagerStatus_bStatusCoin , 0x2a80, 0x0000 }, +{ ColourEngine0_ColourMatrixFarSensor_fpRInR_LSByte , 0x2b02, 0x0000 }, +{ ColourEngine0_ColourMatrixFarSensor_fpRInR_MSByte , 0x2b01, 0x3fd3 }, +{ ColourEngine0_ColourMatrixFarSensor_fpGInR_LSByte , 0x2b06, 0x0000 }, +{ ColourEngine0_ColourMatrixFarSensor_fpGInR_MSByte , 0x2b05, 0xbce0 }, +{ ColourEngine0_ColourMatrixFarSensor_fpBInR_LSByte , 0x2b0a, 0x0000 }, +{ ColourEngine0_ColourMatrixFarSensor_fpBInR_MSByte , 0x2b09, 0xb919 }, +{ ColourEngine0_ColourMatrixFarSensor_fpRInG_LSByte , 0x2b0e, 0x0000 }, +{ ColourEngine0_ColourMatrixFarSensor_fpRInG_MSByte , 0x2b0d, 0xba76 }, +{ ColourEngine0_ColourMatrixFarSensor_fpGInG_LSByte , 0x2b12, 0x0000 }, +{ ColourEngine0_ColourMatrixFarSensor_fpGInG_MSByte , 0x2b11, 0x3f7a }, +{ ColourEngine0_ColourMatrixFarSensor_fpBInG_LSByte , 0x2b16, 0x0000 }, +{ ColourEngine0_ColourMatrixFarSensor_fpBInG_MSByte , 0x2b15, 0xbb71 }, +{ ColourEngine0_ColourMatrixFarSensor_fpRInB_LSByte , 0x2b1a, 0x0000 }, +{ ColourEngine0_ColourMatrixFarSensor_fpRInB_MSByte , 0x2b19, 0xb717 }, +{ ColourEngine0_ColourMatrixFarSensor_fpGInB_LSByte , 0x2b1e, 0x0000 }, +{ ColourEngine0_ColourMatrixFarSensor_fpGInB_MSByte , 0x2b1d, 0xbd29 }, +{ ColourEngine0_ColourMatrixFarSensor_fpBInB_LSByte , 0x2b22, 0x0000 }, +{ ColourEngine0_ColourMatrixFarSensor_fpBInB_MSByte , 0x2b21, 0x3fc6 }, +{ ColourEngine0_ColourMatrixNearSensor_fpRInR_LSByte , 0x2b82, 0x0002 }, +{ ColourEngine0_ColourMatrixNearSensor_fpRInR_MSByte , 0x2b81, 0x6400 }, +{ ColourEngine0_ColourMatrixNearSensor_fpGInR_LSByte , 0x2b86, 0x0002 }, +{ ColourEngine0_ColourMatrixNearSensor_fpGInR_MSByte , 0x2b85, 0x6400 }, +{ ColourEngine0_ColourMatrixNearSensor_fpBInR_LSByte , 0x2b8a, 0x0002 }, +{ ColourEngine0_ColourMatrixNearSensor_fpBInR_MSByte , 0x2b89, 0x6400 }, +{ ColourEngine0_ColourMatrixNearSensor_fpRInG_LSByte , 0x2b8e, 0x0004 }, +{ ColourEngine0_ColourMatrixNearSensor_fpRInG_MSByte , 0x2b8d, 0xb200 }, +{ ColourEngine0_ColourMatrixNearSensor_fpGInG_LSByte , 0x2b92, 0x0004 }, +{ ColourEngine0_ColourMatrixNearSensor_fpGInG_MSByte , 0x2b91, 0xb200 }, +{ ColourEngine0_ColourMatrixNearSensor_fpBInG_LSByte , 0x2b96, 0x0004 }, +{ ColourEngine0_ColourMatrixNearSensor_fpBInG_MSByte , 0x2b95, 0xb200 }, +{ ColourEngine0_ColourMatrixNearSensor_fpRInB_LSByte , 0x2b9a, 0x0000 }, +{ ColourEngine0_ColourMatrixNearSensor_fpRInB_MSByte , 0x2b99, 0xe900 }, +{ ColourEngine0_ColourMatrixNearSensor_fpGInB_LSByte , 0x2b9e, 0x0000 }, +{ ColourEngine0_ColourMatrixNearSensor_fpGInB_MSByte , 0x2b9d, 0xe900 }, +{ ColourEngine0_ColourMatrixNearSensor_fpBInB_LSByte , 0x2ba2, 0x0000 }, +{ ColourEngine0_ColourMatrixNearSensor_fpBInB_MSByte , 0x2ba1, 0xe900 }, +{ ColourEngine0_ColourMatrixDamped_wRInR_LSByte , 0x2c02, 0x0000 }, +{ ColourEngine0_ColourMatrixDamped_wRInR_MSByte , 0x2c01, 0x0000 }, +{ ColourEngine0_ColourMatrixDamped_wGInR_LSByte , 0x2c06, 0x0000 }, +{ ColourEngine0_ColourMatrixDamped_wGInR_MSByte , 0x2c05, 0x0000 }, +{ ColourEngine0_ColourMatrixDamped_wBInR_LSByte , 0x2c0a, 0x0000 }, +{ ColourEngine0_ColourMatrixDamped_wBInR_MSByte , 0x2c09, 0x0000 }, +{ ColourEngine0_ColourMatrixDamped_wRInG_LSByte , 0x2c0e, 0x0000 }, +{ ColourEngine0_ColourMatrixDamped_wRInG_MSByte , 0x2c0d, 0x0000 }, +{ ColourEngine0_ColourMatrixDamped_wGInG_LSByte , 0x2c12, 0x0000 }, +{ ColourEngine0_ColourMatrixDamped_wGInG_MSByte , 0x2c11, 0x0000 }, +{ ColourEngine0_ColourMatrixDamped_wBInG_LSByte , 0x2c16, 0x0000 }, +{ ColourEngine0_ColourMatrixDamped_wBInG_MSByte , 0x2c15, 0x0000 }, +{ ColourEngine0_ColourMatrixDamped_wRInB_LSByte , 0x2c1a, 0x0000 }, +{ ColourEngine0_ColourMatrixDamped_wRInB_MSByte , 0x2c19, 0x0000 }, +{ ColourEngine0_ColourMatrixDamped_wGInB_LSByte , 0x2c1e, 0x0000 }, +{ ColourEngine0_ColourMatrixDamped_wGInB_MSByte , 0x2c1d, 0x0000 }, +{ ColourEngine0_ColourMatrixDamped_wBInB_LSByte , 0x2c22, 0x0000 }, +{ ColourEngine0_ColourMatrixDamped_wBInB_MSByte , 0x2c21, 0x0000 }, +{ ColourEngine0_ColourMatrixDamperControl_fDisableMatrixDamping , 0x2c80, 0x0000 }, +{ ColourEngine0_ColourMatrixDamperControl_DamperLowThreshold_LSByte , 0x2c84, 0x0000 }, +{ ColourEngine0_ColourMatrixDamperControl_DamperLowThreshold_MSByte , 0x2c83, 0x62ac }, +{ ColourEngine0_ColourMatrixDamperControl_DamperHighThreshold_LSByte , 0x2c88, 0x0000 }, +{ ColourEngine0_ColourMatrixDamperControl_DamperHighThreshold_MSByte , 0x2c87, 0x64ac }, +{ ColourEngine0_ColourMatrixDamperControl_MinimumDamperOutput_LSByte , 0x2c8c, 0x0000 }, +{ ColourEngine0_ColourMatrixDamperControl_MinimumDamperOutput_MSByte , 0x2c8b, 0x0000 }, +{ ColourEngine0_ApertureCorrectionControls_fDisableCorrection , 0x2d00, 0x0000 }, +{ ColourEngine0_ApertureCorrectionControls_bMaxGain , 0x2d02, 0x0010 }, +{ ColourEngine0_ApertureCorrectionControls_fDisableGainDamping , 0x2d04, 0x0000 }, +{ ColourEngine0_ApertureCorrectionControls_DamperLowThreshold_Gain_LSByte , 0x2d08, 0x0000 }, +{ ColourEngine0_ApertureCorrectionControls_DamperLowThreshold_Gain_MSByte , 0x2d07, 0x5871 }, +{ ColourEngine0_ApertureCorrectionControls_DamperHighThreshold_Gain_LSByte , 0x2d0c, 0x0000 }, +{ ColourEngine0_ApertureCorrectionControls_DamperHighThreshold_Gain_MSByte , 0x2d0b, 0x63d1 }, +{ ColourEngine0_ApertureCorrectionControls_MinimumDamperOutput_Gain_LSByte , 0x2d10, 0x0000 }, +{ ColourEngine0_ApertureCorrectionControls_MinimumDamperOutput_Gain_MSByte , 0x2d0f, 0x3a00 }, +{ ColourEngine0_ApertureCorrectionControls_bMinimumCoringThreshold , 0x2d12, 0x003c }, +{ ColourEngine0_ApertureCorrectionControls_fDisableCoringDamping , 0x2d14, 0x0000 }, +{ ColourEngine0_ApertureCorrectionControls_bMinimumHighThreshold , 0x2d16, 0x0028 }, +{ ColourEngine0_ApertureCorrectionControls_DamperLowThreshold_Coring_LSByte , 0x2d1a, 0x0000 }, +{ ColourEngine0_ApertureCorrectionControls_DamperLowThreshold_Coring_MSByte , 0x2d19, 0x5871 }, +{ ColourEngine0_ApertureCorrectionControls_DamperHighThreshold_Coring_LSByte , 0x2d1e, 0x0000 }, +{ ColourEngine0_ApertureCorrectionControls_DamperHighThreshold_Coring_MSByte , 0x2d1d, 0x63d1 }, +{ ColourEngine0_ApertureCorrectionControls_MinimumDamperOutput_Coring_LSByte , 0x2d22, 0x0000 }, +{ ColourEngine0_ApertureCorrectionControls_MinimumDamperOutput_Coring_MSByte , 0x2d21, 0x3a00 }, +{ ColourEngine0_ApertureCorrectionStatus_bGain , 0x2d80, 0x0000 }, +{ ColourEngine0_ApertureCorrectionStatus_HighThreshold , 0x2d82, 0x0000 }, +{ ColourEngine0_ApertureCorrectionStatus_CoringThreshold , 0x2d84, 0x0000 }, +{ ColourEngine0_GammaCorrection_fEnabled , 0x2e00, 0x0001 }, +{ ColourEngine0_GammaCorrection_bMode , 0x2e02, 0x0001 }, +{ ColourEngine0_GammaCorrection_SharpRed , 0x2e04, 0x0013 }, +{ ColourEngine0_GammaCorrection_SharpGreen , 0x2e06, 0x0013 }, +{ ColourEngine0_GammaCorrection_SharpBlue , 0x2e08, 0x0013 }, +{ ColourEngine0_GammaCorrection_SoftRed , 0x2e0a, 0x0013 }, +{ ColourEngine0_GammaCorrection_SoftGreen , 0x2e0c, 0x0013 }, +{ ColourEngine0_GammaCorrection_SoftBlue , 0x2e0e, 0x0013 }, +{ NoraControls_fDisable , 0x2e80, 0x0001 }, +{ NoraControls_fDisableNoraPromoting , 0x2e82, 0x0000 }, +{ NoraControls_bMaximumValue , 0x2e84, 0x0001 }, +{ NoraControls_fDifferentTextureDegreeForBlue , 0x2e86, 0x0000 }, +{ NoraControls_fSplitNoiseLevel , 0x2e88, 0x0000 }, +{ NoraControls_fTightGreenMatrix , 0x2e8a, 0x0000 }, +{ NoraControls_DamperLowThreshold_LSByte , 0x2e8e, 0x0000 }, +{ NoraControls_DamperLowThreshold_MSByte , 0x2e8d, 0x4000 }, +{ NoraControls_DamperHighThreshold_LSByte , 0x2e92, 0x0000 }, +{ NoraControls_DamperHighThreshold_MSByte , 0x2e91, 0x4500 }, +{ NoraControls_MinimumDamperOutput_LSByte , 0x2e96, 0x0000 }, +{ NoraControls_MinimumDamperOutput_MSByte , 0x2e95, 0x0000 }, +{ NoraStatus_bNoraValue , 0x2f00, 0x0000 }, +{ ScytheFilterControls_fDisableFilter , 0x2f80, 0x0000 }, +{ ScytheFilterControls_fSquareLaw , 0x2f82, 0x0000 }, +{ ScytheFilterControls_fDisablePromotingLow , 0x2f84, 0x0000 }, +{ ScytheFilterControls_fDisablePromotingHigh , 0x2f86, 0x0000 }, +{ ScytheFilterControls_bMaxWeightLow , 0x2f88, 0x0010 }, +{ ScytheFilterControls_bMaxWeightHigh , 0x2f8a, 0x0010 }, +{ ScytheFilterControls_fpDamperLowThresholdLow_LSByte , 0x2f8e, 0x0000 }, +{ ScytheFilterControls_fpDamperLowThresholdLow_MSByte , 0x2f8d, 0x5d0d }, +{ ScytheFilterControls_fpDamperLowThresholdHigh_LSByte , 0x2f92, 0x0000 }, +{ ScytheFilterControls_fpDamperLowThresholdHigh_MSByte , 0x2f91, 0x5d0d }, +{ ScytheFilterControls_fpDamperHighThresholdLow_LSByte , 0x2f96, 0x0000 }, +{ ScytheFilterControls_fpDamperHighThresholdLow_MSByte , 0x2f95, 0x68dc }, +{ ScytheFilterControls_fpDamperHighThresholdHigh_LSByte , 0x2f9a, 0x0000 }, +{ ScytheFilterControls_fpDamperHighThresholdHigh_MSByte , 0x2f99, 0x68dc }, +{ ScytheFilterControls_fpMinimumDamperOutputLow_LSByte , 0x2f9e, 0x0000 }, +{ ScytheFilterControls_fpMinimumDamperOutputLow_MSByte , 0x2f9d, 0x3a00 }, +{ ScytheFilterControls_fpMinimumDamperOutputHigh_LSByte , 0x2fa2, 0x0000 }, +{ ScytheFilterControls_fpMinimumDamperOutputHigh_MSByte , 0x2fa1, 0x3a00 }, +{ JackFilterControls_fDisableFilter , 0x3000, 0x0000 }, +{ JackFilterControls_fSquareLaw , 0x3002, 0x0000 }, +{ JackFilterControls_fDisablePromotingLow , 0x3004, 0x0000 }, +{ JackFilterControls_fDisablePromotingHigh , 0x3006, 0x0000 }, +{ JackFilterControls_bMaxWeightLow , 0x3008, 0x0010 }, +{ JackFilterControls_bMaxWeightHigh , 0x300a, 0x0010 }, +{ JackFilterControls_fpDamperLowThresholdLow_LSByte , 0x300e, 0x0000 }, +{ JackFilterControls_fpDamperLowThresholdLow_MSByte , 0x300d, 0x63d1 }, +{ JackFilterControls_fpDamperLowThresholdHigh_LSByte , 0x3012, 0x0000 }, +{ JackFilterControls_fpDamperLowThresholdHigh_MSByte , 0x3011, 0x63d1 }, +{ JackFilterControls_fpDamperHighThresholdLow_LSByte , 0x3016, 0x0000 }, +{ JackFilterControls_fpDamperHighThresholdLow_MSByte , 0x3015, 0x68dc }, +{ JackFilterControls_fpDamperHighThresholdHigh_LSByte , 0x301a, 0x0000 }, +{ JackFilterControls_fpDamperHighThresholdHigh_MSByte , 0x3019, 0x68dc }, +{ JackFilterControls_fpMinimumDamperOutputLow_LSByte , 0x301e, 0x0000 }, +{ JackFilterControls_fpMinimumDamperOutputLow_MSByte , 0x301d, 0x0000 }, +{ JackFilterControls_fpMinimumDamperOutputHigh_LSByte , 0x3022, 0x0000 }, +{ JackFilterControls_fpMinimumDamperOutputHigh_MSByte , 0x3021, 0x0000 }, +{ ScytheAndJackFilterStatus_bScytheWeightLo , 0x3080, 0x0000 }, +{ ScytheAndJackFilterStatus_bScytheWeightHi , 0x3082, 0x0000 }, +{ ScytheAndJackFilterStatus_bJackWeightLo , 0x3084, 0x0000 }, +{ ScytheAndJackFilterStatus_bJackWeightHi , 0x3086, 0x0000 }, +{ VfpnControls_fEnableCorrection , 0x3100, 0x0000 }, +{ VfpnControls_uwMaximumPixelValue_LSByte , 0x3104, 0x0000 }, +{ VfpnControls_uwMaximumPixelValue_MSByte , 0x3103, 0x03ff }, +{ VfpnControls_uwMinimumPixelValue_LSByte , 0x3108, 0x0000 }, +{ VfpnControls_uwMinimumPixelValue_MSByte , 0x3107, 0x0000 }, +{ VfpnControls_uwPixelSaturationLevel_LSByte , 0x310c, 0x0000 }, +{ VfpnControls_uwPixelSaturationLevel_MSByte , 0x310b, 0x03ff }, +{ VfpnControls_bLogThreshLog , 0x310e, 0x0004 }, +{ VfpnStatus_fLowPowerStreaming , 0x3180, 0x0000 }, +{ VfpnStatus_fVfpnGainChanged , 0x3182, 0x0000 }, +{ VfpnStatus_bNumberOfBlackLines , 0x3184, 0x0000 }, +{ VfpnStatus_uwNumberOfActivePixels_LSByte , 0x3188, 0x0000 }, +{ VfpnStatus_uwNumberOfActivePixels_MSByte , 0x3187, 0x0000 }, +{ AntiVignetteControls_fDisableFilter , 0x3200, 0x0000 }, +{ AntiVignetteControls_bFilterCoeff_R2_r , 0x3202, 0x0000 }, +{ AntiVignetteControls_bFilterCoeff_R2_gr , 0x3204, 0x0080 }, +{ AntiVignetteControls_bFilterCoeff_R2_gb , 0x3206, 0x0080 }, +{ AntiVignetteControls_bFilterCoeff_R2_b , 0x3208, 0x0000 }, +{ AntiVignetteControls_bFilterCoeff_R4_r , 0x320a, 0x0000 }, +{ AntiVignetteControls_bFilterCoeff_R4_gr , 0x320c, 0x0000 }, +{ AntiVignetteControls_bFilterCoeff_R4_gb , 0x320e, 0x0000 }, +{ AntiVignetteControls_bFilterCoeff_R4_b , 0x3210, 0x0000 }, +{ AntiVignetteControls_uwHorizontalOffset_LSByte , 0x3214, 0x0000 }, +{ AntiVignetteControls_uwHorizontalOffset_MSByte , 0x3213, 0x0000 }, +{ AntiVignetteControls_uwVerticalOffset_LSByte , 0x3218, 0x0000 }, +{ AntiVignetteControls_uwVerticalOffset_MSByte , 0x3217, 0x0000 }, +{ AntiVignetteControls_fAVOffsetSeperateFor4Channels , 0x321a, 0x0001 }, +{ AntiVignetteControls_bShiftFix_R2 , 0x321c, 0x0012 }, +{ AntiVignetteControls_uwHorizontalOffset_r_LSByte , 0x3220, 0x0000 }, +{ AntiVignetteControls_uwHorizontalOffset_r_MSByte , 0x321f, 0x0000 }, +{ AntiVignetteControls_uwHorizontalOffset_gr_LSByte , 0x3224, 0x0000 }, +{ AntiVignetteControls_uwHorizontalOffset_gr_MSByte , 0x3223, 0x0000 }, +{ AntiVignetteControls_uwHorizontalOffset_gb_LSByte , 0x3228, 0x0000 }, +{ AntiVignetteControls_uwHorizontalOffset_gb_MSByte , 0x3227, 0x0000 }, +{ AntiVignetteControls_uwHorizontalOffset_b_LSByte , 0x322c, 0x0000 }, +{ AntiVignetteControls_uwHorizontalOffset_b_MSByte , 0x322b, 0x0000 }, +{ AntiVignetteControls_uwVerticalOffset_r_LSByte , 0x3230, 0x0000 }, +{ AntiVignetteControls_uwVerticalOffset_r_MSByte , 0x3200, 0x002f }, +{ AntiVignetteControls_uwVerticalOffset_gr_LSByte , 0x3234, 0x0000 }, +{ AntiVignetteControls_uwVerticalOffset_gr_MSByte , 0x3233, 0x0000 }, +{ AntiVignetteControls_uwVerticalOffset_gb_LSByte , 0x3238, 0x0000 }, +{ AntiVignetteControls_uwVerticalOffset_gb_MSByte , 0x3237, 0x0000 }, +{ AntiVignetteControls_uwVerticalOffset_b_LSByte , 0x323c, 0x0000 }, +{ AntiVignetteControls_uwVerticalOffset_b_MSByte , 0x323b, 0x0000 }, +{ AntiVignetteControls_bUnityOffset_r , 0x323e, 0x0040 }, +{ AntiVignetteControls_bUnityOffset_gr , 0x3240, 0x0040 }, +{ AntiVignetteControls_bUnityOffset_gb , 0x3242, 0x0040 }, +{ AntiVignetteControls_bUnityOffset_b , 0x3244, 0x0040 }, +{ AntiVignetteControls_fAdaptiveAntiVignetteEnable , 0x3246, 0x0001 }, +{ AntiVignetteStatus_fXScaleEnabled , 0x3280, 0x0000 }, +{ AntiVignetteStatus_bXScale , 0x3282, 0x0000 }, +{ AntiVignetteStatus_fYScaleEnabled , 0x3284, 0x0000 }, +{ AntiVignetteStatus_bYScale , 0x3286, 0x0000 }, +{ AntiVignetteStatus_uwHorizontalSize_LSByte , 0x328a, 0x0000 }, +{ AntiVignetteStatus_uwHorizontalSize_MSByte , 0x3289, 0x0000 }, +{ AntiVignetteStatus_uwVerticalSize_LSByte , 0x328e, 0x0000 }, +{ AntiVignetteStatus_uwVerticalSize_MSByte , 0x328d, 0x0000 }, +{ ColourEngine0_RadialApertureCorrectionControl_fEnableCorrection , 0x3300, 0x0000 }, +{ ColourEngine0_RadialApertureCorrectionHostInputs_bQvec0 , 0x3380, 0x0010 }, +{ ColourEngine0_RadialApertureCorrectionHostInputs_bQvec1 , 0x3382, 0x003f }, +{ ColourEngine0_RadialApertureCorrectionHostInputs_bCofShift , 0x3384, 0x0000 }, +{ ColourEngine0_RadialApertureCorrectionHostInputs_bOutShift , 0x3386, 0x0003 }, +{ ColourEngine0_RadialApertureCorrectionHostInputs_uwUnity_LSByte , 0x338a, 0x0000 }, +{ ColourEngine0_RadialApertureCorrectionHostInputs_uwUnity_MSByte , 0x3389, 0x0001 }, +{ ColourEngine0_RadialApertureCorrectionApplicationInputs_uwHOffset_LSByte , 0x3402, 0x0000 }, +{ ColourEngine0_RadialApertureCorrectionApplicationInputs_uwHOffset_MSByte , 0x3401, 0x0000 }, +{ ColourEngine0_RadialApertureCorrectionApplicationInputs_uwVOffset_LSByte , 0x3406, 0x0000 }, +{ ColourEngine0_RadialApertureCorrectionApplicationInputs_uwVOffset_MSByte , 0x3405, 0x0000 }, +{ ColourEngine0_RadialApertureCorrectionApplicationInputs_uwHScalingFactor_LSByte , 0x340a, 0x0000 }, +{ ColourEngine0_RadialApertureCorrectionApplicationInputs_uwHScalingFactor_MSByte , 0x3409, 0x0000 }, +{ ColourEngine0_RadialApertureCorrectionApplicationInputs_uwVScalingFactor_LSByte , 0x340e, 0x0000 }, +{ ColourEngine0_RadialApertureCorrectionApplicationInputs_uwVScalingFactor_MSByte , 0x340d, 0x0000 }, +{ ColourEngine0_OutputCoderControls_TransformType , 0x3480, 0x0001 }, +{ ColourEngine0_OutputCoderControls_bContrast , 0x3482, 0x0064 }, +{ ColourEngine0_OutputCoderControls_bColourSaturation , 0x3484, 0x0069 }, +{ ColourEngine0_CoderOutputSignalRange_uwLumaExcursion_LSByte , 0x3502, 0x0000 }, +{ ColourEngine0_CoderOutputSignalRange_uwLumaExcursion_MSByte , 0x3501, 0x0000 }, +{ ColourEngine0_CoderOutputSignalRange_uwLumaMidpointTimes2_LSByte , 0x3506, 0x0000 }, +{ ColourEngine0_CoderOutputSignalRange_uwLumaMidpointTimes2_MSByte , 0x3505, 0x0000 }, +{ ColourEngine0_CoderOutputSignalRange_uwChromaExcursion_LSByte , 0x350a, 0x0000 }, +{ ColourEngine0_CoderOutputSignalRange_uwChromaExcursion_MSByte , 0x3509, 0x0000 }, +{ ColourEngine0_CoderOutputSignalRange_uwChromaMidpointTimes2_LSByte , 0x350e, 0x0000 }, +{ ColourEngine0_CoderOutputSignalRange_uwChromaMidpointTimes2_MSByte , 0x350d, 0x0000 }, +{ ColourEngine0_OutputCoderOffsetVector_i0_LSByte , 0x3582, 0x0000 }, +{ ColourEngine0_OutputCoderOffsetVector_i0_MSByte , 0x3581, 0x0000 }, +{ ColourEngine0_OutputCoderOffsetVector_i1_LSByte , 0x3586, 0x0000 }, +{ ColourEngine0_OutputCoderOffsetVector_i1_MSByte , 0x3585, 0x0000 }, +{ ColourEngine0_OutputCoderOffsetVector_i2_LSByte , 0x358a, 0x0000 }, +{ ColourEngine0_OutputCoderOffsetVector_i2_MSByte , 0x3589, 0x0000 }, +{ ColourEngine0_OutputCoderMatrix_w0_0_LSByte , 0x3602, 0x0000 }, +{ ColourEngine0_OutputCoderMatrix_w0_0_MSByte , 0x3601, 0x0000 }, +{ ColourEngine0_OutputCoderMatrix_w0_1_LSByte , 0x3606, 0x0000 }, +{ ColourEngine0_OutputCoderMatrix_w0_1_MSByte , 0x3605, 0x0000 }, +{ ColourEngine0_OutputCoderMatrix_w0_2_LSByte , 0x360a, 0x0000 }, +{ ColourEngine0_OutputCoderMatrix_w0_2_MSByte , 0x3609, 0x0000 }, +{ ColourEngine0_OutputCoderMatrix_w1_0_LSByte , 0x360e, 0x0000 }, +{ ColourEngine0_OutputCoderMatrix_w1_0_MSByte , 0x360d, 0x0000 }, +{ ColourEngine0_OutputCoderMatrix_w1_1_LSByte , 0x3612, 0x0000 }, +{ ColourEngine0_OutputCoderMatrix_w1_1_MSByte , 0x3611, 0x0000 }, +{ ColourEngine0_OutputCoderMatrix_w1_2_LSByte , 0x3616, 0x0000 }, +{ ColourEngine0_OutputCoderMatrix_w1_2_MSByte , 0x3615, 0x0000 }, +{ ColourEngine0_OutputCoderMatrix_w2_0_LSByte , 0x361a, 0x0000 }, +{ ColourEngine0_OutputCoderMatrix_w2_0_MSByte , 0x3619, 0x0000 }, +{ ColourEngine0_OutputCoderMatrix_w2_1_LSByte , 0x361e, 0x0000 }, +{ ColourEngine0_OutputCoderMatrix_w2_1_MSByte , 0x361d, 0x0000 }, +{ ColourEngine0_OutputCoderMatrix_w2_2_LSByte , 0x3622, 0x0000 }, +{ ColourEngine0_OutputCoderMatrix_w2_2_MSByte , 0x3621, 0x0000 }, +{ ColourEngine0_FadeToBlack_fDisable , 0x3680, 0x0001 }, +{ ColourEngine0_FadeToBlack_fpBlackValue_LSByte , 0x3684, 0x0000 }, +{ ColourEngine0_FadeToBlack_fpBlackValue_MSByte , 0x3683, 0x0000 }, +{ ColourEngine0_FadeToBlack_fpDamperLowThreshold_LSByte , 0x3688, 0x0000 }, +{ ColourEngine0_FadeToBlack_fpDamperLowThreshold_MSByte , 0x3687, 0x63d1 }, +{ ColourEngine0_FadeToBlack_fpDamperHighThreshold_LSByte , 0x368c, 0x0000 }, +{ ColourEngine0_FadeToBlack_fpDamperHighThreshold_MSByte , 0x368b, 0x656f }, +{ ColourEngine0_FadeToBlack_fpDamperOutput_LSByte , 0x3690, 0x0000 }, +{ ColourEngine0_FadeToBlack_fpDamperOutput_MSByte , 0x368f, 0x0000 }, +{ ScalerLimits_uwPipe0MinStep_LSByte , 0x3702, 0x0000 }, +{ ScalerLimits_uwPipe0MinStep_MSByte , 0x3701, 0x0000 }, +{ ScalerLimits_uwPipe0MaxStep_LSByte , 0x3706, 0x0000 }, +{ ScalerLimits_uwPipe0MaxStep_MSByte , 0x3705, 0x0000 }, +{ ZoomMgrParams_fAntiZip , 0x3780, 0x0000 }, +{ ZoomMgrParams_bFilterCrispness0 , 0x3782, 0x0000 }, +{ ZoomMgrParams_bFilterCrispness1 , 0x3784, 0x0000 }, +{ ZoomMgrParams_fInFromOutARLock , 0x3786, 0x0000 }, +{ ZoomMgrParams_bPrescaleFactor , 0x3788, 0x0000 }, +{ ZoomMgrParams_bPrescaleType , 0x378a, 0x0000 }, +{ ZoomMgrParams_fp16ZoomRange_LSByte , 0x378e, 0x0000 }, +{ ZoomMgrParams_fp16ZoomRange_MSByte , 0x378d, 0x100 }, +{ ZoomMgrCtrl_bHostTestCoin , 0x3800, 0x0001 }, +{ ZoomMgrCtrl_bZoomCmd , 0x3802, 0x0000 }, +{ ZoomMgrCtrl_fChgOverForbidden , 0x3804, 0x0000 }, +{ ZoomMgrCtrl_fAutoZoom , 0x3806, 0x0000 }, +{ ZoomMgrCtrl_bStepFramePeriod , 0x3808, 0x0000 }, +{ ZoomMgrCtrl_bMagFactor , 0x380a, 0x0014},//0x000a }, +{ ZoomMgrCtrl_bChgOverMarginShift , 0x380c, 0x0000 }, +{ ZoomMgrCtrl_fCheckDataRate , 0x380e, 0x0000 }, +{ ZoomMgrCtrl_fSetAlternateInitWOI , 0x3810, 0x0000 }, +{ ZoomMgrCtrl_fSetX_Byte0 , 0x3812, 0x0000 }, +{ ZoomMgrCtrl_fSetX_Byte1 , 0x3814, 0x0000 }, +{ ZoomMgrCtrl_fSetX_Byte2 , 0x3816, 0x0000 }, +{ ZoomMgrCtrl_fSetX_Byte3 , 0x3818, 0x0000 }, +{ ZoomMgrCtrl_fp16P0ScaleLowLimit_LSByte , 0x381c, 0x0000 }, +{ ZoomMgrCtrl_fp16P0ScaleLowLimit_MSByte , 0x381b, 0x0000 }, +{ ZoomMgrCtrl_fp16P1ScaleLowLimit_LSByte , 0x3820, 0x0000 }, +{ ZoomMgrCtrl_fp16P1ScaleLowLimit_MSByte , 0x381f, 0x0000 }, +{ ZoomMgrStatus_fReady , 0x3880, 0x0000 }, +{ ZoomMgrStatus_bDeviceTestCoin , 0x3882, 0x0000 }, +{ ZoomMgrStatus_bNextCmd , 0x3884, 0x0000 }, +{ ZoomMgrStatus_bLastCmd , 0x3886, 0x0000 }, +{ ZoomMgrStatus_bCommandStatus , 0x3888, 0x0000 }, +{ ZoomMgrStatus_bZoomOpStatus , 0x388a, 0x0000 }, +{ ZoomMgrStatus_fFOVX_Byte0 , 0x388c, 0x0000 }, +{ ZoomMgrStatus_fFOVX_Byte1 , 0x388e, 0x0000 }, +{ ZoomMgrStatus_fFOVX_Byte2 , 0x3890, 0x0000 }, +{ ZoomMgrStatus_fFOVX_Byte3 , 0x3892, 0x0000 }, +{ ZoomMgrStatus_fFOVY_Byte0 , 0x3894, 0x0000 }, +{ ZoomMgrStatus_fFOVY_Byte1 , 0x3896, 0x0000 }, +{ ZoomMgrStatus_fFOVY_Byte2 , 0x3898, 0x0000 }, +{ ZoomMgrStatus_fFOVY_Byte3 , 0x389a, 0x0000 }, +{ ZoomMgrStatus_bPrescaleType , 0x389c, 0x0000 }, +{ ZoomMgrStatus_fPrescaleFactor_Byte0 , 0x389e, 0x0000 }, +{ ZoomMgrStatus_fPrescaleFactor_Byte1 , 0x38a0, 0x0000 }, +{ ZoomMgrStatus_fPrescaleFactor_Byte2 , 0x38a2, 0x0000 }, +{ ZoomMgrStatus_fPrescaleFactor_Byte3 , 0x38a4, 0x0000 }, +{ ZoomMgrStatus_boPipe0NoPrescale , 0x38a6, 0x0000 }, +{ ZoomMgrStatus_bZoomPosition , 0x38a8, 0x0000 }, +{ ZoomMgrStatus_fMaxFOVX_Byte0 , 0x38aa, 0x0000 }, +{ ZoomMgrStatus_fMaxFOVX_Byte1 , 0x38ac, 0x0000 }, +{ ZoomMgrStatus_fMaxFOVX_Byte2 , 0x38ae, 0x0000 }, +{ ZoomMgrStatus_fMaxFOVX_Byte3 , 0x38b0, 0x0000 }, +{ ZoomMgrStatus_fMinFOVX_Byte0 , 0x38b2, 0x0000 }, +{ ZoomMgrStatus_fMinFOVX_Byte1 , 0x38b4, 0x0000 }, +{ ZoomMgrStatus_fMinFOVX_Byte2 , 0x38b6, 0x0000 }, +{ ZoomMgrStatus_fMinFOVX_Byte3 , 0x38b8, 0x0000 }, +{ ZoomMgrStatus_uwXOrigin_LSByte , 0x38bc, 0x0000 }, +{ ZoomMgrStatus_uwXOrigin_MSByte , 0x38bb, 0x0000 }, +{ ZoomMgrStatus_uwYOrigin_LSByte , 0x38c0, 0x0000 }, +{ ZoomMgrStatus_uwYOrigin_MSByte , 0x38bf, 0x0000 }, +{ WhiteBalanceConstrainerControls_fpRedA_LSByte , 0x3902, 0x0000 }, +{ WhiteBalanceConstrainerControls_fpRedA_MSByte , 0x3901, 0x0000 }, +{ WhiteBalanceConstrainerControls_fpBlueA_LSByte , 0x3906, 0x0000 }, +{ WhiteBalanceConstrainerControls_fpBlueA_MSByte , 0x3905, 0x0000 }, +{ WhiteBalanceConstrainerControls_fpRedB_LSByte , 0x390a, 0x0000 }, +{ WhiteBalanceConstrainerControls_fpRedB_MSByte , 0x3909, 0x3af2 }, +{ WhiteBalanceConstrainerControls_fpBlueB_LSByte , 0x390e, 0x0000 }, +{ WhiteBalanceConstrainerControls_fpBlueB_MSByte , 0x390d, 0x3acf }, +{ WhiteBalanceConstrainerControls_fpMaximumDistanceAllowedFromLocus_LSByte , 0x3912, 0x0000 }, +{ WhiteBalanceConstrainerControls_fpMaximumDistanceAllowedFromLocus_MSByte , 0x3911, 0x2e8e }, +{ WhiteBalanceConstrainerControls_fEnableConstrainedWhiteBalance , 0x3914, 0x0001 }, +{ WhiteBalanceConstrainerOutput_fpOutputRedGain_LSByte , 0x3982, 0x0000 }, +{ WhiteBalanceConstrainerOutput_fpOutputRedGain_MSByte , 0x3981, 0x0000 }, +{ WhiteBalanceConstrainerOutput_fpOutputGreenGain_LSByte , 0x3986, 0x0000 }, +{ WhiteBalanceConstrainerOutput_fpOutputGreenGain_MSByte , 0x3985, 0x0000 }, +{ WhiteBalanceConstrainerOutput_fpOutputBlueGain_LSByte , 0x398a, 0x0000 }, +{ WhiteBalanceConstrainerOutput_fpOutputBlueGain_MSByte , 0x3989, 0x0000 }, +{ WhiteBalanceConstrainerOutput_fAreGainsConstrained , 0x398c, 0x0000 }, +{ WhiteBalanceConstrainerInternal_fpGradientOfLocusAB_LSByte , 0x3a02, 0x0000 }, +{ WhiteBalanceConstrainerInternal_fpGradientOfLocusAB_MSByte , 0x3a01, 0x0000 }, +{ WhiteBalanceConstrainerInternal_fpDistanceOfInputPointFromLocusAB_LSByte , 0x3a06, 0x0000 }, +{ WhiteBalanceConstrainerInternal_fpDistanceOfInputPointFromLocusAB_MSByte , 0x3a05, 0x0000 }, +{ WhiteBalanceConstrainerInternal_fpConstrainedRedPoint_LSByte , 0x3a0a, 0x0000 }, +{ WhiteBalanceConstrainerInternal_fpConstrainedRedPoint_MSByte , 0x3a09, 0x0000 }, +{ WhiteBalanceConstrainerInternal_fpConstrainedBluePoint_LSByte , 0x3a0e, 0x0000 }, +{ WhiteBalanceConstrainerInternal_fpConstrainedBluePoint_MSByte , 0x3a0d, 0x0000 }, +{ ModeSetupBank1_uwInputImageSize_X_LSByte , 0x3a82, 0x0000 }, +{ ModeSetupBank1_uwInputImageSize_X_MSByte , 0x3a81, 0x0000 }, +{ ModeSetupBank1_uwInputImageSize_Y_LSByte , 0x3a86, 0x0000 }, +{ ModeSetupBank1_uwInputImageSize_Y_MSByte , 0x3a85, 0x0000 }, +{ ModeSetupBank1_uwMaxImageSize_X_LSByte , 0x3a8a, 0x0000 }, +{ ModeSetupBank1_uwMaxImageSize_X_MSByte , 0x3a89, 0x0000 }, +{ ModeSetupBank1_uwMaxImageSize_Y_LSByte , 0x3a8e, 0x0000 }, +{ ModeSetupBank1_uwMaxImageSize_Y_MSByte , 0x3a8d, 0x0000 }, +{ ModeSetupBank1_uwMinImageSize_X_LSByte , 0x3a92, 0x0000 }, +{ ModeSetupBank1_uwMinImageSize_X_MSByte , 0x3a91, 0x0000 }, +{ ModeSetupBank1_uwMinImageSize_Y_LSByte , 0x3a96, 0x0000 }, +{ ModeSetupBank1_uwMinImageSize_Y_MSByte , 0x3a95, 0x0000 }, +{ ModeSetupBank1_bActiveSensor , 0x3a98, 0x0002 }, +{ ModeSetupBank1_fLowPowerStreaming , 0x3a9a, 0x0000 }, +{ ModeSetupBank1_bTestMode , 0x3a9c, 0x0000 }, +{ ModeSetupBank1_bNumberOfStatusLines , 0x3a9e, 0x0000 }, +{ ModeSetupBank1_bNumberOfDarkLines , 0x3aa0, 0x0000 }, +{ ModeSetupBank1_bNumberOfBlackLines , 0x3aa2, 0x0000 }, +{ ModeSetupBank1_uwNumberOfInterLinePixelClocks_LSByte , 0x3aa6, 0x0000 }, +{ ModeSetupBank1_uwNumberOfInterLinePixelClocks_MSByte , 0x3aa5, 0x0000 }, +{ ModeSetupBank1_uwNumberOfInterFrameLines_LSByte , 0x3aaa, 0x0000 }, +{ ModeSetupBank1_uwNumberOfInterFrameLines_MSByte , 0x3aa9, 0x0000 }, +{ ModeSetupBank1_bNumberOfDummyColumns , 0x3aac, 0x0000 }, +{ ModeSetupBank1_bInputImageSource , 0x3aae, 0x0000 }, +{ ModeSetupBank1_bOutputImageDestination , 0x3ab0, 0x0000 }, +{ DummyPage3_bDummyPageElement , 0x3b00, 0x0000 }, +{ DummyPage4_bDummyPageElement , 0x3b80, 0x0000 }, +{ AntiVignetteControlsFar_fDisableFilter , 0x3c00, 0x0001 }, +{ AntiVignetteControlsFar_bFilterCoeff_R2_r , 0x3c02, 0x0000 }, +{ AntiVignetteControlsFar_bFilterCoeff_R2_gr , 0x3c04, 0x0000 }, +{ AntiVignetteControlsFar_bFilterCoeff_R2_gb , 0x3c06, 0x0000 }, +{ AntiVignetteControlsFar_bFilterCoeff_R2_b , 0x3c08, 0x0000 }, +{ AntiVignetteControlsFar_bFilterCoeff_R4_r , 0x3c0a, 0x0000 }, +{ AntiVignetteControlsFar_bFilterCoeff_R4_gr , 0x3c0c, 0x0000 }, +{ AntiVignetteControlsFar_bFilterCoeff_R4_gb , 0x3c0e, 0x0000 }, +{ AntiVignetteControlsFar_bFilterCoeff_R4_b , 0x3c10, 0x0000 }, +{ AntiVignetteControlsFar_uwHorizontalOffset_LSByte , 0x3c14, 0x0000 }, +{ AntiVignetteControlsFar_uwHorizontalOffset_MSByte , 0x3c13, 0x0000 }, +{ AntiVignetteControlsFar_uwVerticalOffset_LSByte , 0x3c18, 0x0000 }, +{ AntiVignetteControlsFar_uwVerticalOffset_MSByte , 0x3c17, 0x0000 }, +{ AntiVignetteControlsFar_fAVOffsetSeperateFor4Channels , 0x3c1a, 0x0000 }, +{ AntiVignetteControlsFar_bShiftFix_R2 , 0x3c1c, 0x0000 }, +{ AntiVignetteControlsFar_uwHorizontalOffset_r_LSByte , 0x3c20, 0x0000 }, +{ AntiVignetteControlsFar_uwHorizontalOffset_r_MSByte , 0x3c1f, 0x0000 }, +{ AntiVignetteControlsFar_uwHorizontalOffset_gr_LSByte , 0x3c24, 0x0000 }, +{ AntiVignetteControlsFar_uwHorizontalOffset_gr_MSByte , 0x3c23, 0x0000 }, +{ AntiVignetteControlsFar_uwHorizontalOffset_gb_LSByte , 0x3c28, 0x0000 }, +{ AntiVignetteControlsFar_uwHorizontalOffset_gb_MSByte , 0x3c27, 0x0000 }, +{ AntiVignetteControlsFar_uwHorizontalOffset_b_LSByte , 0x3c2c, 0x0000 }, +{ AntiVignetteControlsFar_uwHorizontalOffset_b_MSByte , 0x3c2b, 0x0000 }, +{ AntiVignetteControlsFar_uwVerticalOffset_r_LSByte , 0x3c30, 0x0000 }, +{ AntiVignetteControlsFar_uwVerticalOffset_r_MSByte , 0x3c2f, 0x0000 }, +{ AntiVignetteControlsFar_uwVerticalOffset_gr_LSByte , 0x3c34, 0x0000 }, +{ AntiVignetteControlsFar_uwVerticalOffset_gr_MSByte , 0x3c33, 0x0000 }, +{ AntiVignetteControlsFar_uwVerticalOffset_gb_LSByte , 0x3c38, 0x0000 }, +{ AntiVignetteControlsFar_uwVerticalOffset_gb_MSByte , 0x3c37, 0x0000 }, +{ AntiVignetteControlsFar_uwVerticalOffset_b_LSByte , 0x3c3c, 0x0000 }, +{ AntiVignetteControlsFar_uwVerticalOffset_b_MSByte , 0x3c3b, 0x0000 }, +{ AntiVignetteControlsFar_bUnityOffset_r , 0x3c3e, 0x0000 }, +{ AntiVignetteControlsFar_bUnityOffset_gr , 0x3c40, 0x0000 }, +{ AntiVignetteControlsFar_bUnityOffset_gb , 0x3c42, 0x0000 }, +{ AntiVignetteControlsFar_bUnityOffset_b , 0x3c44, 0x0000 }, +{ AntiVignetteControlsFar_fAdaptiveAntiVignetteEnable , 0x3c46, 0x0000 }, +{ AntiVignetteControlsNear_fDisableFilter , 0x3c80, 0x0001 }, +{ AntiVignetteControlsNear_bFilterCoeff_R2_r , 0x3c82, 0x0000 }, +{ AntiVignetteControlsNear_bFilterCoeff_R2_gr , 0x3c84, 0x0000 }, +{ AntiVignetteControlsNear_bFilterCoeff_R2_gb , 0x3c86, 0x0000 }, +{ AntiVignetteControlsNear_bFilterCoeff_R2_b , 0x3c88, 0x0000 }, +{ AntiVignetteControlsNear_bFilterCoeff_R4_r , 0x3c8a, 0x0000 }, +{ AntiVignetteControlsNear_bFilterCoeff_R4_gr , 0x3c8c, 0x0000 }, +{ AntiVignetteControlsNear_bFilterCoeff_R4_gb , 0x3c8e, 0x0000 }, +{ AntiVignetteControlsNear_bFilterCoeff_R4_b , 0x3c90, 0x0000 }, +{ AntiVignetteControlsNear_uwHorizontalOffset_LSByte , 0x3c94, 0x0000 }, +{ AntiVignetteControlsNear_uwHorizontalOffset_MSByte , 0x3c93, 0x0000 }, +{ AntiVignetteControlsNear_uwVerticalOffset_LSByte , 0x3c98, 0x0000 }, +{ AntiVignetteControlsNear_uwVerticalOffset_MSByte , 0x3c97, 0x0000 }, +{ AntiVignetteControlsNear_fAVOffsetSeperateFor4Channels , 0x3c9a, 0x0000 }, +{ AntiVignetteControlsNear_bShiftFix_R2 , 0x3c9c, 0x0000 }, +{ AntiVignetteControlsNear_uwHorizontalOffset_r_LSByte , 0x3ca0, 0x0000 }, +{ AntiVignetteControlsNear_uwHorizontalOffset_r_MSByte , 0x3c9f, 0x0000 }, +{ AntiVignetteControlsNear_uwHorizontalOffset_gr_LSByte , 0x3ca4, 0x0000 }, +{ AntiVignetteControlsNear_uwHorizontalOffset_gr_MSByte , 0x3ca3, 0x0000 }, +{ AntiVignetteControlsNear_uwHorizontalOffset_gb_LSByte , 0x3ca8, 0x0000 }, +{ AntiVignetteControlsNear_uwHorizontalOffset_gb_MSByte , 0x3ca7, 0x0000 }, +{ AntiVignetteControlsNear_uwHorizontalOffset_b_LSByte , 0x3cac, 0x0000 }, +{ AntiVignetteControlsNear_uwHorizontalOffset_b_MSByte , 0x3cab, 0x0000 }, +{ AntiVignetteControlsNear_uwVerticalOffset_r_LSByte , 0x3cb0, 0x0000 }, +{ AntiVignetteControlsNear_uwVerticalOffset_r_MSByte , 0x3caf, 0x0000 }, +{ AntiVignetteControlsNear_uwVerticalOffset_gr_LSByte , 0x3cb4, 0x0000 }, +{ AntiVignetteControlsNear_uwVerticalOffset_gr_MSByte , 0x3cb3, 0x0000 }, +{ AntiVignetteControlsNear_uwVerticalOffset_gb_LSByte , 0x3cb8, 0x0000 }, +{ AntiVignetteControlsNear_uwVerticalOffset_gb_MSByte , 0x3cb7, 0x0000 }, +{ AntiVignetteControlsNear_uwVerticalOffset_b_LSByte , 0x3cbc, 0x0000 }, +{ AntiVignetteControlsNear_uwVerticalOffset_b_MSByte , 0x3cbb, 0x0000 }, +{ AntiVignetteControlsNear_bUnityOffset_r , 0x3cbe, 0x0000 }, +{ AntiVignetteControlsNear_bUnityOffset_gr , 0x3cc0, 0x0000 }, +{ AntiVignetteControlsNear_bUnityOffset_gb , 0x3cc2, 0x0000 }, +{ AntiVignetteControlsNear_bUnityOffset_b , 0x3cc4, 0x0000 }, +{ AntiVignetteControlsNear_fAdaptiveAntiVignetteEnable , 0x3cc6, 0x0000 }, +{ AFStatsControls_fAbsSquareEnabled , 0x3d00, 0x0000 }, +{ AFStatsControls_bCoringValue , 0x3d02, 0x0000 }, +{ AFStatsControls_bWindowsSystem , 0x3d04, 0x0000 }, +{ AFStatsControls_bHRatio_Num , 0x3d06, 0x0000 }, +{ AFStatsControls_bHRatio_Den , 0x3d08, 0x0000 }, +{ AFStatsControls_bVRatio_Num , 0x3d0a, 0x0000 }, +{ AFStatsControls_bVRatio_Den , 0x3d0c, 0x0000 }, +{ AFStatsControls_bHostActiveZonesCounter , 0x3d0e, 0x0000 }, +{ AFStatsControls_fAutoRefresh , 0x3d10, 0x0000 }, +{ AFStatsStatus_bAFStats_Error , 0x3d80, 0x0000 }, +{ AFStatsStatus_fAbsSquareEnabled , 0x3d82, 0x0000 }, +{ AFStatsStatus_bCoringValue , 0x3d84, 0x0000 }, +{ AFStatsStatus_bWindowsSystem , 0x3d86, 0x0000 }, +{ AFStatsStatus_bActiveZonesCounter , 0x3d88, 0x0000 }, +{ AFStatsStatus_bHRatio_Num , 0x3d8a, 0x0000 }, +{ AFStatsStatus_bHRatio_Den , 0x3d8c, 0x0000 }, +{ AFStatsStatus_bVRatio_Num , 0x3d8e, 0x0000 }, +{ AFStatsStatus_bVRatio_Den , 0x3d90, 0x0000 }, +{ AFStatsStatus_uwWOI_Width_LSByte , 0x3d94, 0x0000 }, +{ AFStatsStatus_uwWOI_Width_MSByte , 0x3d93, 0x0000 }, +{ AFStatsStatus_uwWOI_Height_LSByte , 0x3d98, 0x0000 }, +{ AFStatsStatus_uwWOI_Height_MSByte , 0x3d97, 0x0000 }, +{ AFStatsStatus_uwAFZones_Width_LSByte , 0x3d9c, 0x0000 }, +{ AFStatsStatus_uwAFZones_Width_MSByte , 0x3d9b, 0x0000 }, +{ AFStatsStatus_uwAFZones_Height_LSByte , 0x3da0, 0x0000 }, +{ AFStatsStatus_uwAFZones_Height_MSByte , 0x3d9f, 0x0000 }, +{ AFStatsStatus_fForcedAFStatsIrq , 0x3da2, 0x0000 }, +{ AFStatsStatus_udwMaxFocusMeasurePerPixel_Byte0 , 0x3da4, 0x0000 }, +{ AFStatsStatus_udwMaxFocusMeasurePerPixel_Byte1 , 0x3da6, 0x0000 }, +{ AFStatsStatus_udwMaxFocusMeasurePerPixel_Byte2 , 0x3da8, 0x0000 }, +{ AFStatsStatus_udwMaxFocusMeasurePerPixel_Byte3 , 0x3daa, 0x0000 }, +{ AFStatsStatus_uwStartingAFZoneLine_LSByte , 0x3dae, 0x0000 }, +{ AFStatsStatus_uwStartingAFZoneLine_MSByte , 0x3dad, 0x0000 }, +{ AFFocusStats_udwStatsValue_0_Byte0 , 0x3e00, 0x0000 }, +{ AFFocusStats_udwStatsValue_0_Byte1 , 0x3e02, 0x0000 }, +{ AFFocusStats_udwStatsValue_0_Byte2 , 0x3e04, 0x0000 }, +{ AFFocusStats_udwStatsValue_0_Byte3 , 0x3e06, 0x0000 }, +{ AFFocusStats_udwStatsValue_1_Byte0 , 0x3e08, 0x0000 }, +{ AFFocusStats_udwStatsValue_1_Byte1 , 0x3e0a, 0x0000 }, +{ AFFocusStats_udwStatsValue_1_Byte2 , 0x3e0c, 0x0000 }, +{ AFFocusStats_udwStatsValue_1_Byte3 , 0x3e0e, 0x0000 }, +{ AFFocusStats_udwStatsValue_2_Byte0 , 0x3e10, 0x0000 }, +{ AFFocusStats_udwStatsValue_2_Byte1 , 0x3e12, 0x0000 }, +{ AFFocusStats_udwStatsValue_2_Byte2 , 0x3e14, 0x0000 }, +{ AFFocusStats_udwStatsValue_2_Byte3 , 0x3e16, 0x0000 }, +{ AFFocusStats_udwStatsValue_3_Byte0 , 0x3e18, 0x0000 }, +{ AFFocusStats_udwStatsValue_3_Byte1 , 0x3e1a, 0x0000 }, +{ AFFocusStats_udwStatsValue_3_Byte2 , 0x3e1c, 0x0000 }, +{ AFFocusStats_udwStatsValue_3_Byte3 , 0x3e1e, 0x0000 }, +{ AFFocusStats_udwStatsValue_4_Byte0 , 0x3e20, 0x0000 }, +{ AFFocusStats_udwStatsValue_4_Byte1 , 0x3e22, 0x0000 }, +{ AFFocusStats_udwStatsValue_4_Byte2 , 0x3e24, 0x0000 }, +{ AFFocusStats_udwStatsValue_4_Byte3 , 0x3e26, 0x0000 }, +{ AFFocusStats_udwStatsValue_5_Byte0 , 0x3e28, 0x0000 }, +{ AFFocusStats_udwStatsValue_5_Byte1 , 0x3e2a, 0x0000 }, +{ AFFocusStats_udwStatsValue_5_Byte2 , 0x3e2c, 0x0000 }, +{ AFFocusStats_udwStatsValue_5_Byte3 , 0x3e2e, 0x0000 }, +{ AFFocusStats_udwStatsValue_6_Byte0 , 0x3e30, 0x0000 }, +{ AFFocusStats_udwStatsValue_6_Byte1 , 0x3e32, 0x0000 }, +{ AFFocusStats_udwStatsValue_6_Byte2 , 0x3e34, 0x0000 }, +{ AFFocusStats_udwStatsValue_6_Byte3 , 0x3e36, 0x0000 }, +{ AFLightStats_bStatsValue_0 , 0x3e80, 0x0000 }, +{ AFLightStats_bStatsValue_1 , 0x3e82, 0x0000 }, +{ AFLightStats_bStatsValue_2 , 0x3e84, 0x0000 }, +{ AFLightStats_bStatsValue_3 , 0x3e86, 0x0000 }, +{ AFLightStats_bStatsValue_4 , 0x3e88, 0x0000 }, +{ AFLightStats_bStatsValue_5 , 0x3e8a, 0x0000 }, +{ AFLightStats_bStatsValue_6 , 0x3e8c, 0x0000 }, +{ FLADriverLowLevelParameters_wMinPosition_LSByte , 0x3f02, 0x0000 }, +{ FLADriverLowLevelParameters_wMinPosition_MSByte , 0x3f01, 0x0000 }, +{ FLADriverLowLevelParameters_wMaxPosition_LSByte , 0x3f06, 0x0000 }, +{ FLADriverLowLevelParameters_wMaxPosition_MSByte , 0x3f05, 0x0000 }, +{ FLADriverLowLevelParameters_wHomePosition_LSByte , 0x3f0a, 0x0000 }, +{ FLADriverLowLevelParameters_wHomePosition_MSByte , 0x3f09, 0x0000 }, +{ FLADriverLowLevelParameters_wParkPosition_LSByte , 0x3f0e, 0x0000 }, +{ FLADriverLowLevelParameters_wParkPosition_MSByte , 0x3f0d, 0x0000 }, +{ FLADriverLowLevelParameters_bFramesToSkip , 0x3f10, 0x0000 }, +{ FLADriverLowLevelParameters_AutoSkipNextFrame , 0x3f12, 0x0000 }, +{ FLADriverLowLevelParameters_bLowLevelMacroPos , 0x3f14, 0x0000 }, +{ FLADriverLowLevelParameters_bLowLevelInfinityPos , 0x3f16, 0x0000 }, +{ FLADriverLowLevelParameters_bLowLevelPositionTolerance , 0x3f18, 0x0000 }, +{ FLADriverLowLevelParameters_bLowLevelTimeLimit , 0x3f1a, 0x0000 }, +{ FLADriverLowLevelParameters_bMaxNumberRetries , 0x3f1c, 0x000a }, +{ FLADriverLowLevelParameters_fLowLevelDriverInitialized , 0x3f1e, 0x0001 }, +{ FLADriverLowLevelParameters_fOverwriteLowLevelLimits , 0x3f20, 0x0001 }, +{ FLADriverLowLevelParameters_bNVMRead , 0x3f22, 0x0000 }, +{ FLADriverLowLevelParameters_bNVMScalingFactorInfinity , 0x3f24, 0x0000 }, +{ FLADriverLowLevelParameters_bNVMScalingFactorMacro , 0x3f26, 0x0000 }, +{ FLADriverLowLevelParameters_bNVM_PS_Offset , 0x3f28, 0x0000 }, +{ FLADriverLowLevelParameters_bNVM_PS_Gains , 0x3f2a, 0x0000 }, +{ FLADriverLowLevelParameters_bNVM_PS_IBias , 0x3f2c, 0x0000 }, +{ FLADriverLowLevelParameters_bNVM_PS_RampGain , 0x3f2e, 0x0000 }, +{ FLADriverLowLevelParameters_bNVM_PS_Type , 0x3f30, 0x0000 }, +{ FLADriverLowLevelParameters_uwNVM_minidriver_m_c_LSByte , 0x3f34, 0x0000 }, +{ FLADriverLowLevelParameters_uwNVM_minidriver_m_c_MSByte , 0x3f33, 0x0000 }, +{ FLADriverControls_bMMode , 0x3f80, 0x0000 }, +{ FLADriverControls_wTargetPosition_LSByte , 0x3f84, 0x0000 }, +{ FLADriverControls_wTargetPosition_MSByte , 0x3f83, 0x0000 }, +{ FLADriverControls_wPositionTolerance_LSByte , 0x3f88, 0x0000 }, +{ FLADriverControls_wPositionTolerance_MSByte , 0x3f87, 0x0000 }, +{ FLADriverControls_uwTimeLimit_ms_LSByte , 0x3f8c, 0x0000 }, +{ FLADriverControls_uwTimeLimit_ms_MSByte , 0x3f8b, 0x0000 }, +{ FLADriverControls_bTrigger , 0x3f8e, 0x0000 }, +{ FLADriverControls_bSlewMode , 0x3f90, 0x0000 }, +{ FLADriverControls_bSlewRate , 0x3f92, 0x0000 }, +{ FLADriverStatus_wLensPosition_LSByte , 0x4002, 0x0000 }, +{ FLADriverStatus_wLensPosition_MSByte , 0x4001, 0x0000 }, +{ FLADriverStatus_fLensIsMoving , 0x4004, 0x0000 }, +{ FLADriverStatus_fLimitsExceeded , 0x4006, 0x0000 }, +{ FLADriverStatus_fLensIsAtHome , 0x4008, 0x0000 }, +{ FLADriverStatus_fError , 0x400a, 0x0000 }, +{ FLADriverStatus_bSkippedFrames , 0x400c, 0x0000 }, +{ FLADriverStatus_bCycles , 0x400e, 0x0000 }, +{ FLADriverStatus_bMiniDriverTimeoutError , 0x4010, 0x0000 }, +{ FLADriverStatus_wTargetPosition , 0x4012, 0x0000 }, +{ FLADriverStatus_bLowLevelPosition , 0x4014, 0x0000 }, +{ FocusControls_fErrorReset , 0x4080, 0x0000 }, +{ FocusControls_bRange , 0x4082, 0x0000 }, +{ FocusControls_bMode , 0x4084, 0x0000 }, +{ FocusControls_bAFCommand , 0x4086, 0x0000 }, +{ FocusControls_bLensCommand , 0x4088, 0x0000 }, +{ FocusControls_bManualStep_Size , 0x408a, 0x0000 }, +{ FocusControls_fTestCoinEnabled , 0x408c, 0x0000 }, +{ FocusControls_bControlCoin , 0x408e, 0x0000 }, +{ FocusControls_fInternalStats_Disable , 0x4090, 0x0000 }, +{ FocusControls_bActuator_Disable , 0x4092, 0x0000 }, +{ FocusControls_fInhibitAutoMetering , 0x4094, 0x0000 }, +{ FocusStatus_bModeStatus , 0x4100, 0x0000 }, +{ FocusStatus_bAFCommandStatus , 0x4102, 0x0000 }, +{ FocusStatus_bLensCommandStatus , 0x4104, 0x0000 }, +{ FocusStatus_fAutoFocusEnabled , 0x4106, 0x0000 }, +{ FocusStatus_bRange , 0x4108, 0x0000 }, +{ FocusStatus_fIsStable , 0x410a, 0x0000 }, +{ FocusStatus_fError , 0x410c, 0x0000 }, +{ FocusStatus_cErrorCode , 0x410e, 0x0000 }, +{ FocusStatus_fLensIsMovingAtTheSOF , 0x4110, 0x0000 }, +{ FocusStatus_bCycles , 0x4112, 0x0000 }, +{ FocusStatus_fRunForTest , 0x4114, 0x0000 }, +{ FocusStatus_bStatusCoin , 0x4116, 0x0000 }, +{ FocusStatus_fInternalStats_Disabled , 0x4118, 0x0000 }, +{ FocusStatus_bActuator_Disabled , 0x411a, 0x0000 }, +{ FocusStatus_bLastUsedAFSensor , 0x411c, 0x0000 }, +{ FocusRangeConstants_wFullRange_LensMinPosition_LSByte , 0x4182, 0x0000 }, +{ FocusRangeConstants_wFullRange_LensMinPosition_MSByte , 0x4181, 0x0000 }, +{ FocusRangeConstants_wFullRange_LensMaxPosition_LSByte , 0x4186, 0x0000 }, +{ FocusRangeConstants_wFullRange_LensMaxPosition_MSByte , 0x4185, 0x03ff }, +{ FocusRangeConstants_wFullRange_LensRecoveryPosition_LSByte , 0x418a, 0x0000 }, +{ FocusRangeConstants_wFullRange_LensRecoveryPosition_MSByte , 0x4189, 0x01ff }, +{ FocusRangeConstants_wLandscape_LensMinPosition_LSByte , 0x418e, 0x0000 }, +{ FocusRangeConstants_wLandscape_LensMinPosition_MSByte , 0x418d, 0x0000 }, +{ FocusRangeConstants_wLandscape_LensMaxPosition_LSByte , 0x4192, 0x0000 }, +{ FocusRangeConstants_wLandscape_LensMaxPosition_MSByte , 0x4191, 0x03ff }, +{ FocusRangeConstants_wLandscape_LensRecoveryPosition_LSByte , 0x4196, 0x0000 }, +{ FocusRangeConstants_wLandscape_LensRecoveryPosition_MSByte , 0x4195, 0x01ff }, +{ FocusRangeConstants_wMacro_LensMinPosition_LSByte , 0x419a, 0x0000 }, +{ FocusRangeConstants_wMacro_LensMinPosition_MSByte , 0x4199, 0x0000 }, +{ FocusRangeConstants_wMacro_LensMaxPosition_LSByte , 0x419e, 0x0000 }, +{ FocusRangeConstants_wMacro_LensMaxPosition_MSByte , 0x419d, 0x03ff }, +{ FocusRangeConstants_wMacro_LensRecoveryPosition_LSByte , 0x41a2, 0x0000 }, +{ FocusRangeConstants_wMacro_LensRecoveryPosition_MSByte , 0x41a1, 0x01ff }, +{ AutoFocusControls_bHostCmd , 0x4200, 0x0000 }, +{ AutoFocusControls_fFreezeIfStable , 0x4202, 0x0000 }, +{ AutoFocusControls_fFMTesting_AutoDisable , 0x4204, 0x0001 }, +{ AutoFocusControls_fFastAFAlgoStart , 0x4206, 0x0000 }, +{ AutoFocusControls_fBackLight_Enable , 0x4208, 0x0000 }, +{ AutoFocusControls_fBackupSolution , 0x420a, 0x000f }, +{ AutoFocusControls_fCheckExposureStable_Enable , 0x420c, 0x0000 }, +{ AutoFocusControls_fEnableSimpleCoarseThEvaluation , 0x420e, 0x0000 }, +{ AutoFocusControls_bSelectedMultizoneBehavior , 0x4210, 0x0000 }, +{ AutoFocusControls_bBackLightMethodSelected , 0x4212, 0x0001 }, +{ AutoFocusControls_bWeighedFunctionSelected , 0x4214, 0x0002 }, +{ AutoFocusControls_fMotionBlurEnable , 0x4216, 0x0001 }, +{ AutoFocusControls_fLightVariationEnable , 0x4218, 0x0001 }, +{ AutoFocusControls_fEnableTrackingThresholdEvaluation , 0x421a, 0x0001 }, +{ AutoFocusControls_fEnableHeuristicMethod , 0x421c, 0x0001 }, +{ AutoFocusControls_fEnableBackupSolution , 0x421e, 0x0000 }, +{ AutoFocusControls_fFineToCoarseAutoTransitionEnable , 0x4220, 0x0001 }, +{ AutoFocusControls_fEnableTimedFineExecution , 0x4222, 0x0001 }, +{ AutoFocusControls_fEnableTrakingZoneVariation , 0x4224, 0x0000 }, +{ AutoFocusControls_fEnableFunctionThresholdTest , 0x4226, 0x0001 }, +{ AutoFocusControls_fForceTestState , 0x4228, 0x0000 }, +{ AutoFocusControls_bManualAFNextState , 0x422a, 0x0000 }, +{ AutoFocusControls_fResetHCSPos , 0x422c, 0x0001 }, +{ AutoFocusConstants_bCoarseStep , 0x4280, 0x0078 }, +{ AutoFocusConstants_bFineStep , 0x4282, 0x0014 }, +{ AutoFocusConstants_bFullSearchStep , 0x4284, 0x0000 }, +{ AutoFocusConstants_bLeakyIntegratorConstant , 0x4286, 0x0000 }, +{ AutoFocusConstants_uwFineThreshold_LSByte , 0x428a, 0x0000 }, +{ AutoFocusConstants_uwFineThreshold_MSByte , 0x4289, 0x0000 }, +{ AutoFocusConstants_bFineToCoarseThreshold , 0x428c, 0x0000 }, +{ AutoFocusConstants_uwBacklightThreshold_LSByte , 0x4290, 0x0000 }, +{ AutoFocusConstants_uwBacklightThreshold_MSByte , 0x428f, 0x0000 }, +{ AutoFocusConstants_uwMotionBlurInRatio_LSByte , 0x4294, 0x0000 }, +{ AutoFocusConstants_uwMotionBlurInRatio_MSByte , 0x4293, 0x0000 }, +{ AutoFocusConstants_uwMotionBlurOutRatio_LSByte , 0x4298, 0x0000 }, +{ AutoFocusConstants_uwMotionBlurOutRatio_MSByte , 0x4297, 0x0000 }, +{ AutoFocusConstants_bMaxNumberContinuouslyInstableTime , 0x429a, 0x0000 }, +{ AutoFocusConstants_bMaxNumberContinuouslyStableFrame , 0x429c, 0x0000 }, +{ AutoFocusConstants_uwMaxNumberContinuouslyThresholdTime , 0x429e, 0x0000 }, +{ AutoFocusConstants_uwFixedLowFocusMeasureValue_LSByte , 0x42a2, 0x0000 }, +{ AutoFocusConstants_uwFixedLowFocusMeasureValue_MSByte , 0x42a1, 0x0000 }, +{ AutoFocusConstants_bMaxFocusMeasureThreshold , 0x42a4, 0x0000 }, +{ AutoFocusConstants_bLightGap , 0x42a6, 0x0000 }, +{ AutoFocusConstants_uwDeltaValue_LSByte , 0x42aa, 0x0000 }, +{ AutoFocusConstants_uwDeltaValue_MSByte , 0x42a9, 0x0000 }, +{ AutoFocusConstants_uwMaxFineTh_LSByte , 0x42ae, 0x0000 }, +{ AutoFocusConstants_uwMaxFineTh_MSByte , 0x42ad, 0x0000 }, +{ AutoFocusInput_wLensPosition_LSByte , 0x4302, 0x0000 }, +{ AutoFocusInput_wLensPosition_MSByte , 0x4301, 0x0000 }, +{ AutoFocusInput_fLimitsExceeded , 0x4304, 0x0000 }, +{ AutoFocusInput_wLastStepExecuted_LSByte , 0x4308, 0x0000 }, +{ AutoFocusInput_wLastStepExecuted_MSByte , 0x4307, 0x0000 }, +{ AutoFocusStatus_bCycles , 0x4380, 0x0000 }, +{ AutoFocusStatus_bHostCmd , 0x4382, 0x0000 }, +{ AutoFocusStatus_bAF_PrevState , 0x4384, 0x0000 }, +{ AutoFocusStatus_bAF_State , 0x4386, 0x0000 }, +{ AutoFocusStatus_bAF_NextState , 0x4388, 0x0000 }, +{ AutoFocusStatus_bAF_PrevInstableFMState , 0x438a, 0x0000 }, +{ AutoFocusStatus_bAF_NextInstableFMState , 0x438c, 0x0000 }, +{ AutoFocusStatus_fChangeDirectionStatus , 0x438e, 0x0000 }, +{ AutoFocusStatus_bHCS_State , 0x4390, 0x0000 }, +{ AutoFocusStatus_bHCS_NextState , 0x4392, 0x0000 }, +{ AutoFocusStatus_bHCS_PrevState , 0x4394, 0x0000 }, +{ AutoFocusStatus_fReserved , 0x4396, 0x0000 }, +{ AutoFocusStatus_fCoarseInvoked , 0x4398, 0x0000 }, +{ AutoFocusStatus_fFullSearchInvoked , 0x439a, 0x0000 }, +{ AutoFocusStatus_fFullSearchZero , 0x439c, 0x0000 }, +{ AutoFocusStatus_fInFocus , 0x439e, 0x0000 }, +{ AutoFocusStatus_fMotionBlurIdentified , 0x43a0, 0x0000 }, +{ AutoFocusStatus_fInitialSearch , 0x43a2, 0x0000 }, +{ AutoFocusStatus_wMaxStepMotorLens_LSByte , 0x43a6, 0x0000 }, +{ AutoFocusStatus_wMaxStepMotorLens_MSByte , 0x43a5, 0x0000 }, +{ AutoFocusStatus_wTotalStepMotorLens_LSByte , 0x43aa, 0x0000 }, +{ AutoFocusStatus_wTotalStepMotorLens_MSByte , 0x43a9, 0x0000 }, +{ AutoFocusStatus_bNumberOfFrames , 0x43ac, 0x0000 }, +{ AutoFocusStatus_bCountFineSteps , 0x43ae, 0x0000 }, +{ AutoFocusStatus_bCountTrackingFrames , 0x43b0, 0x0000 }, +{ AutoFocusStatus_bNumberOfSelectedRegions , 0x43b2, 0x0000 }, +{ AutoFocusStatus_bOldNumberOfSelectedRegions , 0x43b4, 0x0000 }, +{ AutoFocusStatus_uwSelectedRegionsStatus_LSByte , 0x43b8, 0x0000 }, +{ AutoFocusStatus_uwSelectedRegionsStatus_MSByte , 0x43b7, 0x0000 }, +{ AutoFocusStatus_uwTotalCoarseVariation_LSByte , 0x43bc, 0x0000 }, +{ AutoFocusStatus_uwTotalCoarseVariation_MSByte , 0x43bb, 0x0000 }, +{ AutoFocusStatus_uwTotalFineVariation_LSByte , 0x43c0, 0x0000 }, +{ AutoFocusStatus_uwTotalFineVariation_MSByte , 0x43bf, 0x0000 }, +{ AutoFocusStatus_bCountVariationRegion , 0x43c2, 0x0000 }, +{ AutoFocusOutput_cFocusLensActuatorCommand , 0x4400, 0x0000 }, +{ AutoFocusOutput_wStep_LSByte , 0x4404, 0x0000 }, +{ AutoFocusOutput_wStep_MSByte , 0x4403, 0x0000 }, +{ AutoFocusOutput_cDirection , 0x4406, 0x0000 }, +{ AutoFocusMeasureData_udwFocusMeasure_Byte0 , 0x4480, 0x0000 }, +{ AutoFocusMeasureData_udwFocusMeasure_Byte1 , 0x4482, 0x0000 }, +{ AutoFocusMeasureData_udwFocusMeasure_Byte2 , 0x4484, 0x0000 }, +{ AutoFocusMeasureData_udwFocusMeasure_Byte3 , 0x4486, 0x0000 }, +{ AutoFocusMeasureData_udwPrevFocusMeasure_Byte0 , 0x4488, 0x0000 }, +{ AutoFocusMeasureData_udwPrevFocusMeasure_Byte1 , 0x448a, 0x0000 }, +{ AutoFocusMeasureData_udwPrevFocusMeasure_Byte2 , 0x448c, 0x0000 }, +{ AutoFocusMeasureData_udwPrevFocusMeasure_Byte3 , 0x448e, 0x0000 }, +{ AutoFocusMeasureData_udwMB_FocusMeasure_Byte0 , 0x4490, 0x0000 }, +{ AutoFocusMeasureData_udwMB_FocusMeasure_Byte1 , 0x4492, 0x0000 }, +{ AutoFocusMeasureData_udwMB_FocusMeasure_Byte2 , 0x4494, 0x0000 }, +{ AutoFocusMeasureData_udwMB_FocusMeasure_Byte3 , 0x4496, 0x0000 }, +{ AutoFocusMeasureData_udwMB_PrevFocusMeasure_Byte0 , 0x4498, 0x0000 }, +{ AutoFocusMeasureData_udwMB_PrevFocusMeasure_Byte1 , 0x449a, 0x0000 }, +{ AutoFocusMeasureData_udwMB_PrevFocusMeasure_Byte2 , 0x449c, 0x0000 }, +{ AutoFocusMeasureData_udwMB_PrevFocusMeasure_Byte3 , 0x449e, 0x0000 }, +{ AutoFocusMeasureData_udwMaxFocusMeasure_Byte0 , 0x44a0, 0x0000 }, +{ AutoFocusMeasureData_udwMaxFocusMeasure_Byte1 , 0x44a2, 0x0000 }, +{ AutoFocusMeasureData_udwMaxFocusMeasure_Byte2 , 0x44a4, 0x0000 }, +{ AutoFocusMeasureData_udwMaxFocusMeasure_Byte3 , 0x44a6, 0x0000 }, +{ AutoFocusMeasureData_udwOldMaxFocusMeasure_Byte0 , 0x44a8, 0x0000 }, +{ AutoFocusMeasureData_udwOldMaxFocusMeasure_Byte1 , 0x44aa, 0x0000 }, +{ AutoFocusMeasureData_udwOldMaxFocusMeasure_Byte2 , 0x44ac, 0x0000 }, +{ AutoFocusMeasureData_udwOldMaxFocusMeasure_Byte3 , 0x44ae, 0x0000 }, +{ AutoFocusMeasureData_udwPrevMaxFocusMeasure_Byte0 , 0x44b0, 0x0000 }, +{ AutoFocusMeasureData_udwPrevMaxFocusMeasure_Byte1 , 0x44b2, 0x0000 }, +{ AutoFocusMeasureData_udwPrevMaxFocusMeasure_Byte2 , 0x44b4, 0x0000 }, +{ AutoFocusMeasureData_udwPrevMaxFocusMeasure_Byte3 , 0x44b6, 0x0000 }, +{ AutoFocusMeasureData_udwNextMaxFocusMeasure_Byte0 , 0x44b8, 0x0000 }, +{ AutoFocusMeasureData_udwNextMaxFocusMeasure_Byte1 , 0x44ba, 0x0000 }, +{ AutoFocusMeasureData_udwNextMaxFocusMeasure_Byte2 , 0x44bc, 0x0000 }, +{ AutoFocusMeasureData_udwNextMaxFocusMeasure_Byte3 , 0x44be, 0x0000 }, +{ AutoFocusMeasureData_udwWeighedFocusMeasure_Byte0 , 0x44c0, 0x0000 }, +{ AutoFocusMeasureData_udwWeighedFocusMeasure_Byte1 , 0x44c2, 0x0000 }, +{ AutoFocusMeasureData_udwWeighedFocusMeasure_Byte2 , 0x44c4, 0x0000 }, +{ AutoFocusMeasureData_udwWeighedFocusMeasure_Byte3 , 0x44c6, 0x0000 }, +{ AutoFocusMeasureData_udwMaxMaxFocusMeasure_Byte0 , 0x44c8, 0x0000 }, +{ AutoFocusMeasureData_udwMaxMaxFocusMeasure_Byte1 , 0x44ca, 0x0000 }, +{ AutoFocusMeasureData_udwMaxMaxFocusMeasure_Byte2 , 0x44cc, 0x0000 }, +{ AutoFocusMeasureData_udwMaxMaxFocusMeasure_Byte3 , 0x44ce, 0x0000 }, +{ AutoFocusMeasureData_udwTrackingFocusMeasure_Byte0 , 0x44d0, 0x0000 }, +{ AutoFocusMeasureData_udwTrackingFocusMeasure_Byte1 , 0x44d2, 0x0000 }, +{ AutoFocusMeasureData_udwTrackingFocusMeasure_Byte2 , 0x44d4, 0x0000 }, +{ AutoFocusMeasureData_udwTrackingFocusMeasure_Byte3 , 0x44d6, 0x0000 }, +{ AutoFocusMeasureData_udwTrackingFocusMeasureDifference_Byte0 , 0x44d8, 0x0000 }, +{ AutoFocusMeasureData_udwTrackingFocusMeasureDifference_Byte1 , 0x44da, 0x0000 }, +{ AutoFocusMeasureData_udwTrackingFocusMeasureDifference_Byte2 , 0x44dc, 0x0000 }, +{ AutoFocusMeasureData_udwTrackingFocusMeasureDifference_Byte3 , 0x44de, 0x0000 }, +{ AutoFocusMeasureData_udwCurrentFocusMeasureDifference_Byte0 , 0x44e0, 0x0000 }, +{ AutoFocusMeasureData_udwCurrentFocusMeasureDifference_Byte1 , 0x44e2, 0x0000 }, +{ AutoFocusMeasureData_udwCurrentFocusMeasureDifference_Byte2 , 0x44e4, 0x0000 }, +{ AutoFocusMeasureData_udwCurrentFocusMeasureDifference_Byte3 , 0x44e6, 0x0000 }, +{ AutoFocusMeasureData_udwOldTrackingFocusMeasure_Byte0 , 0x44e8, 0x0000 }, +{ AutoFocusMeasureData_udwOldTrackingFocusMeasure_Byte1 , 0x44ea, 0x0000 }, +{ AutoFocusMeasureData_udwOldTrackingFocusMeasure_Byte2 , 0x44ec, 0x0000 }, +{ AutoFocusMeasureData_udwOldTrackingFocusMeasure_Byte3 , 0x44ee, 0x0000 }, +{ AutoFocusWeightControls_bWeight_0 , 0x4500, 0x0000 }, +{ AutoFocusWeightControls_bWeight_1 , 0x4502, 0x0000 }, +{ AutoFocusWeightControls_bWeight_2 , 0x4504, 0x0000 }, +{ AutoFocusWeightControls_bWeight_3 , 0x4506, 0x0000 }, +{ AutoFocusWeightControls_bWeight_4 , 0x4508, 0x0000 }, +{ AutoFocusWeightControls_bWeight_5 , 0x450a, 0x0000 }, +{ AutoFocusWeightControls_bWeight_6 , 0x450c, 0x0000 }, +{ AutoFocusDynamicWeight_bWeight_0 , 0x4580, 0x0000 }, +{ AutoFocusDynamicWeight_bWeight_1 , 0x4582, 0x0000 }, +{ AutoFocusDynamicWeight_bWeight_2 , 0x4584, 0x0000 }, +{ AutoFocusDynamicWeight_bWeight_3 , 0x4586, 0x0000 }, +{ AutoFocusDynamicWeight_bWeight_4 , 0x4588, 0x0000 }, +{ AutoFocusDynamicWeight_bWeight_5 , 0x458a, 0x0000 }, +{ AutoFocusDynamicWeight_bWeight_6 , 0x458c, 0x0000 }, +{ AutoFocusThresholds_uwCoarseThreshold_LSByte , 0x4602, 0x0000 }, +{ AutoFocusThresholds_uwCoarseThreshold_MSByte , 0x4601, 0x0000 }, +{ AutoFocusThresholds_uwFineThreshold_LSByte , 0x4606, 0x0000 }, +{ AutoFocusThresholds_uwFineThreshold_MSByte , 0x4605, 0x0000 }, +{ AutoFocusThresholds_uwBeforeMotionBlur_LSByte , 0x460a, 0x0000 }, +{ AutoFocusThresholds_uwBeforeMotionBlur_MSByte , 0x4609, 0x0000 }, +{ AutoFocusThresholds_uwAfterMotionBlur_LSByte , 0x460e, 0x0000 }, +{ AutoFocusThresholds_uwAfterMotionBlur_MSByte , 0x460d, 0x0000 }, +{ AutoFocusThresholds_udwCurrentVariation_Byte0 , 0x4610, 0x0000 }, +{ AutoFocusThresholds_udwCurrentVariation_Byte1 , 0x4612, 0x0000 }, +{ AutoFocusThresholds_udwCurrentVariation_Byte2 , 0x4614, 0x0000 }, +{ AutoFocusThresholds_udwCurrentVariation_Byte3 , 0x4616, 0x0000 }, +{ AutoFocusThresholds_udwLowFocusMeasureValue_Byte0 , 0x4618, 0x0000 }, +{ AutoFocusThresholds_udwLowFocusMeasureValue_Byte1 , 0x461a, 0x0000 }, +{ AutoFocusThresholds_udwLowFocusMeasureValue_Byte2 , 0x461c, 0x0000 }, +{ AutoFocusThresholds_udwLowFocusMeasureValue_Byte3 , 0x461e, 0x0000 }, +{ AutoFocusHeuristicConstants_uwLensPositionInputMax_LSByte , 0x4682, 0x0000 }, +{ AutoFocusHeuristicConstants_uwLensPositionInputMax_MSByte , 0x4681, 0x0000 }, +{ AutoFocusHeuristicConstants_uwLensPositionInputMin_LSByte , 0x4686, 0x0000 }, +{ AutoFocusHeuristicConstants_uwLensPositionInputMin_MSByte , 0x4685, 0x0000 }, +{ AutoFocusHeuristicConstants_bBrightnessInputMax , 0x4688, 0x0000 }, +{ AutoFocusHeuristicConstants_bBrightnessInputMin , 0x468a, 0x0000 }, +{ AutoFocusHeuristicConstants_uwThFineMax_LSByte , 0x468e, 0x0000 }, +{ AutoFocusHeuristicConstants_uwThFineMax_MSByte , 0x468d, 0x0000 }, +{ AutoFocusHeuristicConstants_uwThFineMin_LSByte , 0x4692, 0x0000 }, +{ AutoFocusHeuristicConstants_uwThFineMin_MSByte , 0x4691, 0x0000 }, +{ AutoFocusHeuristicConstants_uwFineToCoarseMax_LSByte , 0x4696, 0x0000 }, +{ AutoFocusHeuristicConstants_uwFineToCoarseMax_MSByte , 0x4695, 0x0000 }, +{ AutoFocusHeuristicConstants_uwFineToCoarseMin_LSByte , 0x469a, 0x0000 }, +{ AutoFocusHeuristicConstants_uwFineToCoarseMin_MSByte , 0x4699, 0x0000 }, +{ AutoFocusHeuristicConstants_bHighToMaxFMShiftFactor , 0x469c, 0x0000 }, +{ AutoFocusHeuristicConstants_bLowToHighFMShiftFactor , 0x469e, 0x0000 }, +{ AutoFocusThHeuristicInput_udwFocusMeasureInputMax_Byte0 , 0x4700, 0x0000 }, +{ AutoFocusThHeuristicInput_udwFocusMeasureInputMax_Byte1 , 0x4702, 0x0000 }, +{ AutoFocusThHeuristicInput_udwFocusMeasureInputMax_Byte2 , 0x4704, 0x0000 }, +{ AutoFocusThHeuristicInput_udwFocusMeasureInputMax_Byte3 , 0x4706, 0x0000 }, +{ AutoFocusThHeuristicInput_udwFocusMeasureInputMin_Byte0 , 0x4708, 0x0000 }, +{ AutoFocusThHeuristicInput_udwFocusMeasureInputMin_Byte1 , 0x470a, 0x0000 }, +{ AutoFocusThHeuristicInput_udwFocusMeasureInputMin_Byte2 , 0x470c, 0x0000 }, +{ AutoFocusThHeuristicInput_udwFocusMeasureInputMin_Byte3 , 0x470e, 0x0000 }, +{ AutoFocusThHeuristicInput_udwFocusMeasureInput_Byte0 , 0x4710, 0x0000 }, +{ AutoFocusThHeuristicInput_udwFocusMeasureInput_Byte1 , 0x4712, 0x0000 }, +{ AutoFocusThHeuristicInput_udwFocusMeasureInput_Byte2 , 0x4714, 0x0000 }, +{ AutoFocusThHeuristicInput_udwFocusMeasureInput_Byte3 , 0x4716, 0x0000 }, +{ AutoFocusThHeuristicInput_uwLensPositionInput_LSByte , 0x471a, 0x0000 }, +{ AutoFocusThHeuristicInput_uwLensPositionInput_MSByte , 0x4719, 0x0000 }, +{ AutoFocusThHeuristicInput_bBrightnessInput , 0x471c, 0x0000 }, +{ AutoFocusInstableFocusMeasureStatus_bStatus_SceneDetector , 0x4780, 0x0000 }, +{ AutoFocusInstableFocusMeasureStatus_bCountInstableFocusMeasure , 0x4782, 0x0000 }, +{ AutoFocusInstableFocusMeasureStatus_bCountStableFocusMeasure , 0x4784, 0x0000 }, +{ AutoFocusLFMFullSearchStatus_bPrevState_AFFS , 0x4800, 0x0000 }, +{ AutoFocusLFMFullSearchStatus_bState_AFFS , 0x4802, 0x0000 }, +{ AutoFocusLFMFullSearchStatus_bNextState_AFFS , 0x4804, 0x0000 }, +{ AutoFocusLFMFullSearchStatus_bCountFullSearchContinuouslyIncreaseValue , 0x4806, 0x0000 }, +{ AutoFocusMZFullSearchStatus_bFS_PrevState , 0x4880, 0x0000 }, +{ AutoFocusMZFullSearchStatus_bFS_State , 0x4882, 0x0000 }, +{ AutoFocusMZFullSearchStatus_bFS_NextState , 0x4884, 0x0000 }, +{ AutoFocusMZFullSearchStatus_bMaxMaxRegionPositionIndex , 0x4886, 0x0000 }, +{ MiscPageElements_fConvertMultiByteReadsIntoSingleByte , 0x4900, 0x0001 }, +{ MiscPageElements_bDelayAfterSettingXshutdown , 0x4902, 0x00f0 }, +{ MiscPageElements_fEnableIntelligentFlash , 0x4904, 0x0000 }, +{ MiscPageElements_fEligibleFrameForMetering , 0x4906, 0x0000 }, +{ MiscPageElements_fFlashGunIlluminatedFrameStreamed , 0x4908, 0x0000 }, +{ MiscPageElements_VpipCut , 0x490a, 0x0000 }, +{ MiscPageElements_bGPIOClockFrequency_Mhz , 0x490c, 0x0000 }, +{ MiscPageElements_bIntelligentFlashModeStatus , 0x490e, 0x0000 }, +{ MiscPageElements_fStartMeteringFromManualGains , 0x4910, 0x0000 }, +{ MiscPageElements_fEnableDelayWhenStartingSensor , 0x4912, 0x0000 }, +{ MiscPageElements_fEnableDelayWhenStoppingSensor , 0x4914, 0x0000 }, +{ MiscPageElements_fTriggerFlashOnStreaming , 0x4916, 0x0000 }, +{ MiscPageElements_fDoNotOutputFrameInIntelligentFlash , 0x4918, 0x0000 }, +{ MiscPageElements_fDisableToshibaInit , 0x491a, 0x0000 }, +{ MiscPageElements_bNumberofFramesTobeSkippedByRx , 0x491c, 0x0000 }, +{ CutBMasterI2cStatus_bWriteFifoUseCount , 0x4980, 0x0000 }, +{ MasterI2cClockControl_bCountFall , 0x4a00, 0x0000 }, +{ MasterI2cClockControl_bCountRise , 0x4a02, 0x0000 }, +{ MasterI2cClockControl_bCountHigh , 0x4a04, 0x0000 }, +{ MasterI2cClockControl_bCountBuffer , 0x4a06, 0x0000 }, +{ MasterI2cClockControl_bCountHoldData , 0x4a08, 0x0000 }, +{ MasterI2cClockControl_bCountSetupData , 0x4a0a, 0x0000 }, +{ MasterI2cClockControl_bCountHoldStart , 0x4a0c, 0x0000 }, +{ MasterI2cClockControl_bCountSetupStart , 0x4a0e, 0x0000 }, +{ MasterI2cClockControl_bCountSetupStop , 0x4a10, 0x0000 }, +{ ZoomMgrFOVCtrl_bShiftCenter , 0x4a80, 0x0000 }, +{ ZoomMgrFOVCtrl_uwXOrigin_LSByte , 0x4a84, 0x0000 }, +{ ZoomMgrFOVCtrl_uwXOrigin_MSByte , 0x4a83, 0x0000 }, +{ ZoomMgrFOVCtrl_uwYOrigin_LSByte , 0x4a88, 0x0000 }, +{ ZoomMgrFOVCtrl_uwYOrigin_MSByte , 0x4a87, 0x0000 }, +{ ZoomMgrFOVCtrl_fRestrictMaxFOVToChosenFOV , 0x4a8a, 0x0000 }, +{ ZoomMgrFOVCtrl_fCalculateMinFOVAlways , 0x4a8c, 0x0000 }, +{ ZoomMgrFOVCtrl_fInhibitMaxFOVAtModeStaticChange , 0x4a8e, 0x0000 }, +{ ZoomMgrSpeedInfo_bNumberOfFramesOnHold , 0x4b00, 0x0000 }, +{ ZoomMgrSpeedInfo_bDelay_frames , 0x4b02, 0x0000 }, +{ ZoomMgrSpeedInfo_uwTotalDelay_frames_LSByte , 0x4b06, 0x0000 }, +{ ZoomMgrSpeedInfo_uwTotalDelay_frames_MSByte , 0x4b05, 0x0000 }, +{ ZoomMgrSpeedInfo_bNumberOfZoomSteps , 0x4b08, 0x0000 }, +{ ZoomMgrStripeCtrl_bStripeControl , 0x4b80, 0x0000 }, +{ ZoomMgrStripeCtrl_uwStripeStartAddr_LSByte , 0x4b84, 0x0000 }, +{ ZoomMgrStripeCtrl_uwStripeStartAddr_MSByte , 0x4b83, 0x0000 }, +{ ZoomMgrStripeCtrl_uwStripeSize_LSByte , 0x4b88, 0x0000 }, +{ ZoomMgrStripeCtrl_uwStripeSize_MSByte , 0x4b87, 0x0000 }, +{ ZoomMgrStripeCtrl_uwStripeInMinLineSize_LSByte , 0x4b8c, 0x0000 }, +{ ZoomMgrStripeCtrl_uwStripeInMinLineSize_MSByte , 0x4b8b, 0x0000 }, +{ ZoomMgrStripeCtrl_uwBmsFrameLength_LSByte , 0x4b90, 0x0000 }, +{ ZoomMgrStripeCtrl_uwBmsFrameLength_MSByte , 0x4b8f, 0x0000 }, +{ LftStripeParam_uwGPSISize_LSByte , 0x4c02, 0x0000 }, +{ LftStripeParam_uwGPSISize_MSByte , 0x4c01, 0x0000 }, +{ LftStripeParam_uwGPSOSize_LSByte , 0x4c06, 0x0000 }, +{ LftStripeParam_uwGPSOSize_MSByte , 0x4c05, 0x0000 }, +{ LftStripeParam_uwRightBorder_LSByte , 0x4c0a, 0x0000 }, +{ LftStripeParam_uwRightBorder_MSByte , 0x4c09, 0x0000 }, +{ LftStripeParam_uwLeftBorder_LSByte , 0x4c0e, 0x0000 }, +{ LftStripeParam_uwLeftBorder_MSByte , 0x4c0d, 0x0000 }, +{ LftStripeParam_wGPSCropBulk_LSByte , 0x4c12, 0x0000 }, +{ LftStripeParam_wGPSCropBulk_MSByte , 0x4c11, 0x0000 }, +{ LftStripeParam_wGPSCropFrac_LSByte , 0x4c16, 0x0000 }, +{ LftStripeParam_wGPSCropFrac_MSByte , 0x4c15, 0x0000 }, +{ LftStripeParam_uwStripeInCropStart_LSByte , 0x4c1a, 0x0000 }, +{ LftStripeParam_uwStripeInCropStart_MSByte , 0x4c19, 0x0000 }, +{ LftStripeParam_uwStripeInCropSize_LSByte , 0x4c1e, 0x0000 }, +{ LftStripeParam_uwStripeInCropSize_MSByte , 0x4c1d, 0x0000 }, +{ LftStripeParam_uwStripeOutCropStart_LSByte , 0x4c22, 0x0000 }, +{ LftStripeParam_uwStripeOutCropStart_MSByte , 0x4c21, 0x0000 }, +{ LftStripeParam_uwStripeOutCropSize_LSByte , 0x4c26, 0x0000 }, +{ LftStripeParam_uwStripeOutCropSize_MSByte , 0x4c25, 0x0000 }, +{ RgtStripeParam_uwGPSISize_LSByte , 0x4c82, 0x0000 }, +{ RgtStripeParam_uwGPSISize_MSByte , 0x4c81, 0x0000 }, +{ RgtStripeParam_uwGPSOSize_LSByte , 0x4c86, 0x0000 }, +{ RgtStripeParam_uwGPSOSize_MSByte , 0x4c85, 0x0000 }, +{ RgtStripeParam_uwRightBorder_LSByte , 0x4c8a, 0x0000 }, +{ RgtStripeParam_uwRightBorder_MSByte , 0x4c89, 0x0000 }, +{ RgtStripeParam_uwLeftBorder_LSByte , 0x4c8e, 0x0000 }, +{ RgtStripeParam_uwLeftBorder_MSByte , 0x4c8d, 0x0000 }, +{ RgtStripeParam_wGPSCropBulk_LSByte , 0x4c92, 0x0000 }, +{ RgtStripeParam_wGPSCropBulk_MSByte , 0x4c91, 0x0000 }, +{ RgtStripeParam_wGPSCropFrac_LSByte , 0x4c96, 0x0000 }, +{ RgtStripeParam_wGPSCropFrac_MSByte , 0x4c95, 0x0000 }, +{ RgtStripeParam_uwStripeInCropStart_LSByte , 0x4c9a, 0x0000 }, +{ RgtStripeParam_uwStripeInCropStart_MSByte , 0x4c99, 0x0000 }, +{ RgtStripeParam_uwStripeInCropSize_LSByte , 0x4c9e, 0x0000 }, +{ RgtStripeParam_uwStripeInCropSize_MSByte , 0x4c9d, 0x0000 }, +{ RgtStripeParam_uwStripeOutCropStart_LSByte , 0x4ca2, 0x0000 }, +{ RgtStripeParam_uwStripeOutCropStart_MSByte , 0x4ca1, 0x0000 }, +{ RgtStripeParam_uwStripeOutCropSize_LSByte , 0x4ca6, 0x0000 }, +{ RgtStripeParam_uwStripeOutCropSize_MSByte , 0x4ca5, 0x0000 }, +{ DigitalGainStatus_uwCodedGreen1Gain_LSByte , 0x4d02, 0x0000 }, +{ DigitalGainStatus_uwCodedGreen1Gain_MSByte , 0x4d01, 0x0000 }, +{ DigitalGainStatus_uwCodedRedGain_LSByte , 0x4d06, 0x0000 }, +{ DigitalGainStatus_uwCodedRedGain_MSByte , 0x4d05, 0x0000 }, +{ DigitalGainStatus_uwCodedBlueGain_LSByte , 0x4d0a, 0x0000 }, +{ DigitalGainStatus_uwCodedBlueGain_MSByte , 0x4d09, 0x0000 }, +{ DigitalGainStatus_uwCodedGreen2Gain_LSByte , 0x4d0e, 0x0000 }, +{ DigitalGainStatus_uwCodedGreen2Gain_MSByte , 0x4d0d, 0x0000 }, +{ OffsetCompensationStatus_uwOffset_LSByte , 0x4d82, 0x0000 }, +{ OffsetCompensationStatus_uwOffset_MSByte , 0x4d81, 0x0000 }, +{ OffsetCompensationStatus_fpOffsetCompensationGain_LSByte , 0x4d86, 0x0000 }, +{ OffsetCompensationStatus_fpOffsetCompensationGain_MSByte , 0x4d85, 0x0000 }, +{ AntiFlickerExposureStatus_fpFlickerFreePeriod_us_LSByte , 0x4e02, 0x0000 }, +{ AntiFlickerExposureStatus_fpFlickerFreePeriod_us_MSByte , 0x4e01, 0x0000 }, +{ AntiFlickerExposureStatus_fpGainedFlickerFreeTimePeriod_us_LSByte , 0x4e06, 0x0000 }, +{ AntiFlickerExposureStatus_fpGainedFlickerFreeTimePeriod_us_MSByte , 0x4e05, 0x0000 }, +{ AntiFlickerExposureStatus_uwMaxFlickerFreeBunches_LSByte , 0x4e0a, 0x0000 }, +{ AntiFlickerExposureStatus_uwMaxFlickerFreeBunches_MSByte , 0x4e09, 0x0000 }, +{ AntiFlickerExposureStatus_fpConstrainedFlickerFreePeriod_us_LSByte , 0x4e0e, 0x0000 }, +{ AntiFlickerExposureStatus_fpConstrainedFlickerFreePeriod_us_MSByte , 0x4e0d, 0x0000 }, +{ ModuleEnables_fDisableCho , 0x4e80, 0x0000 }, +{ ModuleEnables_fDisableChg , 0x4e82, 0x0000 }, +{ DummyPage1_bDummyPageElement , 0x4f00, 0x0000 }, +{ DummyPage2_bDummyPageElement , 0x4f80, 0x0000 }, +{ SensorSetupFarSensor_uwGuaranteedDataSaturationLevel_LSByte , 0x5002, 0x0000 }, +{ SensorSetupFarSensor_uwGuaranteedDataSaturationLevel_MSByte , 0x5001, 0x043f }, +{ SensorSetupFarSensor_uwMinimumSensorRxPixelValue_LSByte , 0x5006, 0x0000 }, +{ SensorSetupFarSensor_uwMinimumSensorRxPixelValue_MSByte , 0x5005, 0x0004 }, +{ SensorSetupFarSensor_uwMaximumSensorRxPixelValue_LSByte , 0x500a, 0x0000 }, +{ SensorSetupFarSensor_uwMaximumSensorRxPixelValue_MSByte , 0x5009, 0x043f }, +{ SensorSetupFarSensor_fpRedTiltGain_LSByte , 0x500e, 0x0000 }, +{ SensorSetupFarSensor_fpRedTiltGain_MSByte , 0x500d, 0x3e00 }, +{ SensorSetupFarSensor_fpGreenTiltGain_LSByte , 0x5012, 0x0000 }, +{ SensorSetupFarSensor_fpGreenTiltGain_MSByte , 0x5011, 0x3e00 }, +{ SensorSetupFarSensor_fpBlueTiltGain_LSByte , 0x5016, 0x0000 }, +{ SensorSetupFarSensor_fpBlueTiltGain_MSByte , 0x5015, 0x3e00 }, +{ SensorSetupFarSensor_BlackCorrectionOffset , 0x5018, 0x0000 }, +{ SensorSetupNearSensor_uwGuaranteedDataSaturationLevel_LSByte , 0x5082, 0x0000 }, +{ SensorSetupNearSensor_uwGuaranteedDataSaturationLevel_MSByte , 0x5081, 0x0000 }, +{ SensorSetupNearSensor_uwMinimumSensorRxPixelValue_LSByte , 0x5086, 0x0000 }, +{ SensorSetupNearSensor_uwMinimumSensorRxPixelValue_MSByte , 0x5085, 0x0000 }, +{ SensorSetupNearSensor_uwMaximumSensorRxPixelValue_LSByte , 0x508a, 0x0000 }, +{ SensorSetupNearSensor_uwMaximumSensorRxPixelValue_MSByte , 0x5089, 0x0000 }, +{ SensorSetupNearSensor_fpRedTiltGain_LSByte , 0x508e, 0x0000 }, +{ SensorSetupNearSensor_fpRedTiltGain_MSByte , 0x508d, 0x0000 }, +{ SensorSetupNearSensor_fpGreenTiltGain_LSByte , 0x5092, 0x0000 }, +{ SensorSetupNearSensor_fpGreenTiltGain_MSByte , 0x5091, 0x0000 }, +{ SensorSetupNearSensor_fpBlueTiltGain_LSByte , 0x5096, 0x0000 }, +{ SensorSetupNearSensor_fpBlueTiltGain_MSByte , 0x5095, 0x0000 }, +{ SensorSetupNearSensor_BlackCorrectionOffset , 0x5098, 0x0000 }, +{ ToshibaOtpRead_otp_inf_2 , 0x5100, 0x0000 }, +{ ToshibaOtpRead_otp_inf_1 , 0x5102, 0x0000 }, +{ ToshibaOtpRead_otp_inf_0 , 0x5104, 0x0000 }, +{ ToshibaOtpRead_otp_mac_2 , 0x5106, 0x0000 }, +{ ToshibaOtpRead_otp_mac_1 , 0x5108, 0x0000 }, +{ ToshibaOtpRead_otp_mac_0 , 0x510a, 0x0000 }, +{ ToshibaOtpRead_otp_posA_1 , 0x510c, 0x0000 }, +{ ToshibaOtpRead_otp_posA_0 , 0x510e, 0x0000 }, +{ ToshibaOtpRead_otp_posB_1 , 0x5110, 0x0000 }, +{ ToshibaOtpRead_otp_posB_0 , 0x5112, 0x0000 }, +{ ToshibaOtpRead_otp_register_map_ver , 0x5114, 0x0000 }, +{ NormalisedWhiteBalanceGains_fpNormalisedRedGain_LSByte , 0x5182, 0x0000 }, +{ NormalisedWhiteBalanceGains_fpNormalisedRedGain_MSByte , 0x5181, 0x0000 }, +{ ReferenceIlluminantCasts_fpCAST0_LSByte , 0x5202, 0x0000 }, +{ ReferenceIlluminantCasts_fpCAST0_MSByte , 0x5201, 0x38b8 }, +{ ReferenceIlluminantCasts_fpCAST1_LSByte , 0x5206, 0x0000 }, +{ ReferenceIlluminantCasts_fpCAST1_MSByte , 0x5205, 0x396d }, +{ ReferenceIlluminantCasts_fpCAST2_LSByte , 0x520a, 0x0000 }, +{ ReferenceIlluminantCasts_fpCAST2_MSByte , 0x5209, 0x3a1b }, +{ ReferenceIlluminantCasts_fpCAST3_LSByte , 0x520e, 0x0000 }, +{ ReferenceIlluminantCasts_fpCAST3_MSByte , 0x520d, 0x3af2 }, +{ AdaptiveAVParameter_B_bAvUnityOffset_Day , 0x5280, 0x0040 }, +{ AdaptiveAVParameter_B_bAvCoeffR2_Day , 0x5282, 0x003e }, +{ AdaptiveAVParameter_B_bAvCoeffR4_Day , 0x5284, 0x00e8 }, +{ AdaptiveAVParameter_B_wAvHOffset_Day_LSByte , 0x5288, 0x0000 }, +{ AdaptiveAVParameter_B_wAvHOffset_Day_MSByte , 0x5287, 0x0003 }, +{ AdaptiveAVParameter_B_wAvVOffset_Day_LSByte , 0x528c, 0x0000 }, +{ AdaptiveAVParameter_B_wAvVOffset_Day_MSByte , 0x528b, 0x000d }, +{ AdaptiveAVParameter_B_bAvUnityOffset_COO , 0x528e, 0x0040 }, +{ AdaptiveAVParameter_B_bAvCoeffR2_COO , 0x5290, 0x003d }, +{ AdaptiveAVParameter_B_bAvCoeffR4_COO , 0x5292, 0x00ed }, +{ AdaptiveAVParameter_B_wAvHOffset_COO_LSByte , 0x5296, 0x0000 }, +{ AdaptiveAVParameter_B_wAvHOffset_COO_MSByte , 0x5295, 0x0006 }, +{ AdaptiveAVParameter_B_wAvVOffset_COO_LSByte , 0x529a, 0x0000 }, +{ AdaptiveAVParameter_B_wAvVOffset_COO_MSByte , 0x5299, 0x0011 }, +{ AdaptiveAVParameter_B_bAvUnityOffset_INC , 0x529c, 0x0040 }, +{ AdaptiveAVParameter_B_bAvCoeffR2_INC , 0x529e, 0x0035 }, +{ AdaptiveAVParameter_B_bAvCoeffR4_INC , 0x52a0, 0x00f4 }, +{ AdaptiveAVParameter_B_wAvHOffset_INC_LSByte , 0x52a4, 0x0000 }, +{ AdaptiveAVParameter_B_wAvHOffset_INC_MSByte , 0x52a3, 0x0009 }, +{ AdaptiveAVParameter_B_wAvVOffset_INC_LSByte , 0x52a8, 0x0000 }, +{ AdaptiveAVParameter_B_wAvVOffset_INC_MSByte , 0x52a7, 0x0015 }, +{ AdaptiveAVParameter_B_bAvUnityOffset_HOR , 0x52aa, 0x0040 }, +{ AdaptiveAVParameter_B_bAvCoeffR2_HOR , 0x52ac, 0x0037 }, +{ AdaptiveAVParameter_B_bAvCoeffR4_HOR , 0x52ae, 0x00f0 }, +{ AdaptiveAVParameter_B_wAvHOffset_HOR_LSByte , 0x52b2, 0x0000 }, +{ AdaptiveAVParameter_B_wAvHOffset_HOR_MSByte , 0x52b1, 0x000b }, +{ AdaptiveAVParameter_B_wAvVOffset_HOR_LSByte , 0x52b6, 0x0000 }, +{ AdaptiveAVParameter_B_wAvVOffset_HOR_MSByte , 0x52b5, 0x001d }, +{ AdaptiveAVParameter_GB_bAvUnityOffset_Day , 0x5300, 0x0040 }, +{ AdaptiveAVParameter_GB_bAvCoeffR2_Day , 0x5302, 0x0047 }, +{ AdaptiveAVParameter_GB_bAvCoeffR4_Day , 0x5304, 0x00ec }, +{ AdaptiveAVParameter_GB_wAvHOffset_Day_LSByte , 0x5308, 0x0000 }, +{ AdaptiveAVParameter_GB_wAvHOffset_Day_MSByte , 0x5307, 0x000a }, +{ AdaptiveAVParameter_GB_wAvVOffset_Day_LSByte , 0x530c, 0x0000 }, +{ AdaptiveAVParameter_GB_wAvVOffset_Day_MSByte , 0x530b, 0x000f }, +{ AdaptiveAVParameter_GB_bAvUnityOffset_COO , 0x530e, 0x0040 }, +{ AdaptiveAVParameter_GB_bAvCoeffR2_COO , 0x5310, 0x0046 }, +{ AdaptiveAVParameter_GB_bAvCoeffR4_COO , 0x5312, 0x00ed }, +{ AdaptiveAVParameter_GB_wAvHOffset_COO_LSByte , 0x5316, 0x0000 }, +{ AdaptiveAVParameter_GB_wAvHOffset_COO_MSByte , 0x5315, 0x000b }, +{ AdaptiveAVParameter_GB_wAvVOffset_COO_LSByte , 0x531a, 0x0000 }, +{ AdaptiveAVParameter_GB_wAvVOffset_COO_MSByte , 0x5319, 0x0010 }, +{ AdaptiveAVParameter_GB_bAvUnityOffset_INC , 0x531c, 0x0040 }, +{ AdaptiveAVParameter_GB_bAvCoeffR2_INC , 0x531e, 0x003e }, +{ AdaptiveAVParameter_GB_bAvCoeffR4_INC , 0x5320, 0x00f3 }, +{ AdaptiveAVParameter_GB_wAvHOffset_INC_LSByte , 0x5324, 0x0000 }, +{ AdaptiveAVParameter_GB_wAvHOffset_INC_MSByte , 0x5323, 0x000b }, +{ AdaptiveAVParameter_GB_wAvVOffset_INC_LSByte , 0x5328, 0x0000 }, +{ AdaptiveAVParameter_GB_wAvVOffset_INC_MSByte , 0x5327, 0x0010 }, +{ AdaptiveAVParameter_GB_bAvUnityOffset_HOR , 0x532a, 0x0040 }, +{ AdaptiveAVParameter_GB_bAvCoeffR2_HOR , 0x532c, 0x0040 }, +{ AdaptiveAVParameter_GB_bAvCoeffR4_HOR , 0x532e, 0x00f0 }, +{ AdaptiveAVParameter_GB_wAvHOffset_HOR_LSByte , 0x5332, 0x0000 }, +{ AdaptiveAVParameter_GB_wAvHOffset_HOR_MSByte , 0x5331, 0x000c }, +{ AdaptiveAVParameter_GB_wAvVOffset_HOR_LSByte , 0x5336, 0x0000 }, +{ AdaptiveAVParameter_GB_wAvVOffset_HOR_MSByte , 0x5335, 0x0014 }, +{ AdaptiveAVParameter_GR_bAvUnityOffset_Day , 0x5380, 0x0040 }, +{ AdaptiveAVParameter_GR_bAvCoeffR2_Day , 0x5382, 0x0048 }, +{ AdaptiveAVParameter_GR_bAvCoeffR4_Day , 0x5384, 0x00e8 }, +{ AdaptiveAVParameter_GR_wAvHOffset_Day_LSByte , 0x5388, 0x0000 }, +{ AdaptiveAVParameter_GR_wAvHOffset_Day_MSByte , 0x5387, 0x0009 }, +{ AdaptiveAVParameter_GR_wAvVOffset_Day_LSByte , 0x538c, 0x0000 }, +{ AdaptiveAVParameter_GR_wAvVOffset_Day_MSByte , 0x538b, 0x0004 }, +{ AdaptiveAVParameter_GR_bAvUnityOffset_COO , 0x538e, 0x0040 }, +{ AdaptiveAVParameter_GR_bAvCoeffR2_COO , 0x5390, 0x0046 }, +{ AdaptiveAVParameter_GR_bAvCoeffR4_COO , 0x5392, 0x00ea }, +{ AdaptiveAVParameter_GR_wAvHOffset_COO_LSByte , 0x5396, 0x0000 }, +{ AdaptiveAVParameter_GR_wAvHOffset_COO_MSByte , 0x5395, 0x000b }, +{ AdaptiveAVParameter_GR_wAvVOffset_COO_LSByte , 0x539a, 0x0000 }, +{ AdaptiveAVParameter_GR_wAvVOffset_COO_MSByte , 0x5399, 0x0004 }, +{ AdaptiveAVParameter_GR_bAvUnityOffset_INC , 0x539c, 0x0040 }, +{ AdaptiveAVParameter_GR_bAvCoeffR2_INC , 0x539e, 0x003f }, +{ AdaptiveAVParameter_GR_bAvCoeffR4_INC , 0x53a0, 0x00f1 }, +{ AdaptiveAVParameter_GR_wAvHOffset_INC_LSByte , 0x53a4, 0x0000 }, +{ AdaptiveAVParameter_GR_wAvHOffset_INC_MSByte , 0x53a3, 0x000b }, +{ AdaptiveAVParameter_GR_wAvVOffset_INC_LSByte , 0x53a8, 0x0000 }, +{ AdaptiveAVParameter_GR_wAvVOffset_INC_MSByte , 0x53a7, 0x0002 }, +{ AdaptiveAVParameter_GR_bAvUnityOffset_HOR , 0x53aa, 0x0040 }, +{ AdaptiveAVParameter_GR_bAvCoeffR2_HOR , 0x53ac, 0x0040 }, +{ AdaptiveAVParameter_GR_bAvCoeffR4_HOR , 0x53ae, 0x00ef }, +{ AdaptiveAVParameter_GR_wAvHOffset_HOR_LSByte , 0x53b2, 0x0000 }, +{ AdaptiveAVParameter_GR_wAvHOffset_HOR_MSByte , 0x53b1, 0x000c }, +{ AdaptiveAVParameter_GR_wAvVOffset_HOR_LSByte , 0x53b6, 0x0000 }, +{ AdaptiveAVParameter_GR_wAvVOffset_HOR_MSByte , 0x53b5, 0x0001 }, +{ AdaptiveAVParameter_R_bAvUnityOffset_Day , 0x5400, 0x0040 }, +{ AdaptiveAVParameter_R_bAvCoeffR2_Day , 0x5402, 0x0067 }, +{ AdaptiveAVParameter_R_bAvCoeffR4_Day , 0x5404, 0x00f6 }, +{ AdaptiveAVParameter_R_wAvHOffset_Day_LSByte , 0x5408, 0x0000 }, +{ AdaptiveAVParameter_R_wAvHOffset_Day_MSByte , 0x5407, 0x000a }, +{ AdaptiveAVParameter_R_wAvVOffset_Day_LSByte , 0x540c, 0x0000 }, +{ AdaptiveAVParameter_R_wAvVOffset_Day_MSByte , 0x540b, 0x0008 }, +{ AdaptiveAVParameter_R_bAvUnityOffset_COO , 0x540e, 0x0040 }, +{ AdaptiveAVParameter_R_bAvCoeffR2_COO , 0x5410, 0x0063 }, +{ AdaptiveAVParameter_R_bAvCoeffR4_COO , 0x5412, 0x00f7 }, +{ AdaptiveAVParameter_R_wAvHOffset_COO_LSByte , 0x5416, 0x0000 }, +{ AdaptiveAVParameter_R_wAvHOffset_COO_MSByte , 0x5415, 0x000b }, +{ AdaptiveAVParameter_R_wAvVOffset_COO_LSByte , 0x541a, 0x0000 }, +{ AdaptiveAVParameter_R_wAvVOffset_COO_MSByte , 0x5419, 0x0007 }, +{ AdaptiveAVParameter_R_bAvUnityOffset_INC , 0x541c, 0x0040 }, +{ AdaptiveAVParameter_R_bAvCoeffR2_INC , 0x541e, 0x0041 }, +{ AdaptiveAVParameter_R_bAvCoeffR4_INC , 0x5420, 0x0002 }, +{ AdaptiveAVParameter_R_wAvHOffset_INC_LSByte , 0x5424, 0x0000 }, +{ AdaptiveAVParameter_R_wAvHOffset_INC_MSByte , 0x5423, 0x000b }, +{ AdaptiveAVParameter_R_wAvVOffset_INC_LSByte , 0x5428, 0x0000 }, +{ AdaptiveAVParameter_R_wAvVOffset_INC_MSByte , 0x5427, 0x0007 }, +{ AdaptiveAVParameter_R_bAvUnityOffset_HOR , 0x542a, 0x0040 }, +{ AdaptiveAVParameter_R_bAvCoeffR2_HOR , 0x542c, 0x0052 }, +{ AdaptiveAVParameter_R_bAvCoeffR4_HOR , 0x542e, 0x00f7 }, +{ AdaptiveAVParameter_R_wAvHOffset_HOR_LSByte , 0x5432, 0x0000 }, +{ AdaptiveAVParameter_R_wAvHOffset_HOR_MSByte , 0x5431, 0x000a }, +{ AdaptiveAVParameter_R_wAvVOffset_HOR_LSByte , 0x5436, 0x0000 }, +{ AdaptiveAVParameter_R_wAvVOffset_HOR_MSByte , 0x5435, 0x0004 }, +{ ContrastStretchControl_fEnableContrastStretch , 0x5480, 0x0000 }, +{ ContrastStretchControl_bMode , 0x5482, 0x0000 }, +{ ContrastStretchControl_bAccColour , 0x5484, 0x0000 }, +{ ContrastStretchControl_bBlackThreshold , 0x5486, 0x0000 }, +{ ContrastStretchControl_bWhiteThreshold , 0x5488, 0x0000 }, +{ ContrastStretchStatus_uBlackBinAThreshold_hi , 0x5500, 0x0000 }, +{ ContrastStretchStatus_uBlackBinBThreshold_hi , 0x5502, 0x0000 }, +{ ContrastStretchStatus_uWhiteBinAThreshold_lo , 0x5504, 0x0000 }, +{ ContrastStretchStatus_uWhiteBinBThreshold_lo , 0x5506, 0x0000 }, +{ ContrastStretchStatus_fpGain_LSByte , 0x550a, 0x0000 }, +{ ContrastStretchStatus_fpGain_MSByte , 0x5509, 0x0000 }, +{ DynamicConstrainedWBControls_fpRedA_LSByte , 0x5582, 0x0000 }, +{ DynamicConstrainedWBControls_fpRedA_MSByte , 0x5581, 0x3881 }, +{ DynamicConstrainedWBControls_fpBlueA_LSByte , 0x5586, 0x0000 }, +{ DynamicConstrainedWBControls_fpBlueA_MSByte , 0x5585, 0x3c68 }, +{ DynamicConstrainedWBControls_fpDamperLowThreshold_LSByte , 0x558a, 0x0000 }, +{ DynamicConstrainedWBControls_fpDamperLowThreshold_MSByte , 0x5589, 0x53e8 }, +{ DynamicConstrainedWBControls_fpMinimumDamperOutput_LSByte , 0x558e, 0x0000 }, +{ DynamicConstrainedWBControls_fpMinimumDamperOutput_MSByte , 0x558d, 0x3a66 }, +{ DynamicConstrainedWBControls_fpDamperHighThreshold_LSByte , 0x5592, 0x0000 }, +{ DynamicConstrainedWBControls_fpDamperHighThreshold_MSByte , 0x5591, 0x5a71 }, +{ DynamicConstrainedWBControls_fDamperDisable , 0x5594, 0x0000 }, +{ Toshiba_AF_NVM_Read_NVM_Far2Near_inf_LSByte , 0x5602, 0x0000 }, +{ Toshiba_AF_NVM_Read_NVM_Far2Near_inf_MSByte , 0x5601, 0x0000 }, +{ Toshiba_AF_NVM_Read_NVM_Near2Far_inf_LSByte , 0x5606, 0x0000 }, +{ Toshiba_AF_NVM_Read_NVM_Near2Far_inf_MSByte , 0x5605, 0x0000 }, +{ Toshiba_AF_NVM_Read_NVM_Far2Near_mac_LSByte , 0x560a, 0x0000 }, +{ Toshiba_AF_NVM_Read_NVM_Far2Near_mac_MSByte , 0x5609, 0x0000 }, +{ Toshiba_AF_NVM_Read_NVM_Near2Far_mac_LSByte , 0x560e, 0x0000 }, +{ Toshiba_AF_NVM_Read_NVM_Near2Far_mac_MSByte , 0x560d, 0x0000 }, +{ Toshiba_AF_NVM_Read_NVM_Pos_A_LSByte , 0x5612, 0x0000 }, +{ Toshiba_AF_NVM_Read_NVM_Pos_A_MSByte , 0x5611, 0x0000 }, +{ Toshiba_AF_NVM_Read_NVM_Pos_B_LSByte , 0x5616, 0x0000 }, +{ Toshiba_AF_NVM_Read_NVM_Pos_B_MSByte , 0x5615, 0x0000 }, +{ Toshiba_Vcm_Parameters_wLowLevelMacroPos_LSByte , 0x5682, 0x0000 }, +{ Toshiba_Vcm_Parameters_wLowLevelMacroPos_MSByte , 0x5681, 0x0000 }, +{ Toshiba_Vcm_Parameters_wLowLevelInfinityPos_LSByte , 0x5686, 0x0000 }, +{ Toshiba_Vcm_Parameters_wLowLevelInfinityPos_MSByte , 0x5685, 0x0000 }, +{ Toshiba_Vcm_Parameters_bSlewControlModeEnable , 0x5688, 0x0000 }, +{ Toshiba_Vcm_Parameters_bSlewModeForSmallerStep , 0x568a, 0x0001 }, +{ Toshiba_Vcm_Parameters_bSlewRateForSmallerStep , 0x568c, 0x0004 }, +{ Toshiba_Vcm_Parameters_bSlewModeForLargerStep , 0x568e, 0x0008 }, +{ Toshiba_Vcm_Parameters_bSlewRateForLargerStep , 0x5690, 0x0007 }, +{ Toshiba_Vcm_Parameters_bThresholdStepSize , 0x5692, 0x00b0 }, +{ Toshiba_Vcm_Status_wLowLevelPos_LSByte , 0x5702, 0x0000 }, +{ Toshiba_Vcm_Status_wLowLevelPos_MSByte , 0x5701, 0x0000 }, +{ AdaptiveColourMatrix_fpNormalisedRedGain0_LSByte , 0x5782, 0x0000 }, +{ AdaptiveColourMatrix_fpNormalisedRedGain0_MSByte , 0x5781, 0x3adf }, +{ AdaptiveColourMatrix_fpNormalisedRedGain1_LSByte , 0x5786, 0x0000 }, +{ AdaptiveColourMatrix_fpNormalisedRedGain1_MSByte , 0x5785, 0x393f }, +{ AdaptiveColourMatrix_bChooseAdaptiveColourMatrix , 0x5788, 0x0001 }, +{ ColourEngine1_ColourMatrixFarSensor_fpRInR_LSByte , 0x5802, 0x0000 }, +{ ColourEngine1_ColourMatrixFarSensor_fpRInR_MSByte , 0x5801, 0x3f0c }, +{ ColourEngine1_ColourMatrixFarSensor_fpGInR_LSByte , 0x5806, 0x0000 }, +{ ColourEngine1_ColourMatrixFarSensor_fpGInR_MSByte , 0x5805, 0xb887 }, +{ ColourEngine1_ColourMatrixFarSensor_fpBInR_LSByte , 0x580a, 0x0000 }, +{ ColourEngine1_ColourMatrixFarSensor_fpBInR_MSByte , 0x5809, 0xbaec }, +{ ColourEngine1_ColourMatrixFarSensor_fpRInG_LSByte , 0x580e, 0x0000 }, +{ ColourEngine1_ColourMatrixFarSensor_fpRInG_MSByte , 0x580d, 0xbaba }, +{ ColourEngine1_ColourMatrixFarSensor_fpGInG_LSByte , 0x5812, 0x0000 }, +{ ColourEngine1_ColourMatrixFarSensor_fpGInG_MSByte , 0x5811, 0x3fa5 }, +{ ColourEngine1_ColourMatrixFarSensor_fpBInG_LSByte , 0x5816, 0x0000 }, +{ ColourEngine1_ColourMatrixFarSensor_fpBInG_MSByte , 0x5815, 0xbbd9 }, +{ ColourEngine1_ColourMatrixFarSensor_fpRInB_LSByte , 0x581a, 0x0000 }, +{ ColourEngine1_ColourMatrixFarSensor_fpRInB_MSByte , 0x5819, 0xbc6e }, +{ ColourEngine1_ColourMatrixFarSensor_fpGInB_LSByte , 0x581e, 0x0000 }, +{ ColourEngine1_ColourMatrixFarSensor_fpGInB_MSByte , 0x581d, 0xc01b }, +{ ColourEngine1_ColourMatrixFarSensor_fpBInB_LSByte , 0x5822, 0x0000 }, +{ ColourEngine1_ColourMatrixFarSensor_fpBInB_MSByte , 0x5821, 0x41b7 }, +{ ColourEngine1_ColourMatrixNearSensor_fpRInR_LSByte , 0x5882, 0x0000 }, +{ ColourEngine1_ColourMatrixNearSensor_fpRInR_MSByte , 0x5881, 0x0000 }, +{ ColourEngine1_ColourMatrixNearSensor_fpGInR_LSByte , 0x5886, 0x0000 }, +{ ColourEngine1_ColourMatrixNearSensor_fpGInR_MSByte , 0x5885, 0x0000 }, +{ ColourEngine1_ColourMatrixNearSensor_fpBInR_LSByte , 0x588a, 0x0000 }, +{ ColourEngine1_ColourMatrixNearSensor_fpBInR_MSByte , 0x5889, 0x0000 }, +{ ColourEngine1_ColourMatrixNearSensor_fpRInG_LSByte , 0x588e, 0x0000 }, +{ ColourEngine1_ColourMatrixNearSensor_fpRInG_MSByte , 0x588d, 0x0000 }, +{ ColourEngine1_ColourMatrixNearSensor_fpGInG_LSByte , 0x5892, 0x0000 }, +{ ColourEngine1_ColourMatrixNearSensor_fpGInG_MSByte , 0x5891, 0x0000 }, +{ ColourEngine1_ColourMatrixNearSensor_fpBInG_LSByte , 0x5896, 0x0000 }, +{ ColourEngine1_ColourMatrixNearSensor_fpBInG_MSByte , 0x5895, 0x0000 }, +{ ColourEngine1_ColourMatrixNearSensor_fpRInB_LSByte , 0x589a, 0x0000 }, +{ ColourEngine1_ColourMatrixNearSensor_fpRInB_MSByte , 0x5899, 0x0000 }, +{ ColourEngine1_ColourMatrixNearSensor_fpGInB_LSByte , 0x589e, 0x0000 }, +{ ColourEngine1_ColourMatrixNearSensor_fpGInB_MSByte , 0x589d, 0x0000 }, +{ ColourEngine1_ColourMatrixNearSensor_fpBInB_LSByte , 0x58a2, 0x0000 }, +{ ColourEngine1_ColourMatrixNearSensor_fpBInB_MSByte , 0x58a1, 0x0000 }, +{ WhiteBalanceGainLimit_fpWhiteBalanceGainLimit_LSByte , 0x5902, 0x0000 }, +{ WhiteBalanceGainLimit_fpWhiteBalanceGainLimit_MSByte , 0x5901, 0x4200 }, +{ ToshibaTechnicalParamTuner_uwHostLevelMacroPos_LSByte , 0x5982, 0x0000 }, +{ ToshibaTechnicalParamTuner_uwHostLevelMacroPos_MSByte , 0x5981, 0x0000 }, +{ ToshibaTechnicalParamTuner_uwHostLevelInfinityPos_LSByte , 0x5986, 0x0000 }, +{ ToshibaTechnicalParamTuner_uwHostLevelInfinityPos_MSByte , 0x5985, 0x0000 }, +{ ToshibaTechnicalParamTuner_uwDefAFMaxStandardRange_um_LSByte , 0x598a, 0x0000 }, +{ ToshibaTechnicalParamTuner_uwDefAFMaxStandardRange_um_MSByte , 0x5989, 0x012c }, +{ ToshibaTechnicalParamTuner_bDefFineStepParam_um , 0x598c, 0x0008 }, +{ ToshibaTechnicalParamTuner_bDefCoarseStepParam_um , 0x598e, 0x0030 }, +{ ToshibaTechnicalParamTuner_fHostDefTechParam , 0x5990, 0x0002 }, +{ IRPLastPreviewWOI_X_Byte0 , 0x800c, 0x0000 }, +{ IRPLastPreviewWOI_X_Byte1 , 0x800e, 0x0000 }, +{ IRPLastPreviewWOI_X_Byte2 , 0x8010, 0x0000 }, +{ IRPLastPreviewWOI_X_Byte3 , 0x8012, 0x0000 }, +{ ModeSetupBank2_bActiveSensor , 0x3b18, 0x0002 }, +{ ModeSetupBank3_bActiveSensor , 0x3b98,0x2}, + + }; + + +int sva_vpip_auto_focus(struct sva_device_open *open, struct vpip_autofocus_id *mode) +{ + +struct sva_service_open *srv_open; +u16 vpip_state=0; +int ret=0; +srv_open = open->service_open_data[mode->service_id]; + +//printk("\n ..............Inside auto focus driver 0\n"); + + IRP_ASSERT(irp_write_packet(srv_open, + vpip_default_params[FocusControls_bLensCommand].addr, + 11)); // LA_CMD_INIT + + + //printk("\nauto focus driver 1\n"); + msleep(10); + IRP_ASSERT(irp_read_packet(srv_open, vpip_default_params[FLADriverLowLevelParameters_fLowLevelDriverInitialized].addr, + &vpip_state)); + // printk("\nauto focus driver 2\n"); + + while( 1 != vpip_state)// VPIP_TRUE + { + msleep(10); + IRP_ASSERT(irp_read_packet(srv_open, vpip_default_params[FLADriverLowLevelParameters_fLowLevelDriverInitialized].addr, + &vpip_state)); + } + // printk("\nauto focus driver 3\n"); + + + + msleep(10); + IRP_ASSERT(irp_read_packet(srv_open, vpip_default_params[FLADriverLowLevelParameters_bNVMRead].addr,// FLADriverLowLevelParameters_bMSMConfig + &vpip_state)); + //printk("\nauto focus driver 4\n"); + while( 7 != vpip_state) + { + msleep(10); + IRP_ASSERT(irp_read_packet(srv_open, vpip_default_params[FLADriverLowLevelParameters_bNVMRead].addr, + &vpip_state)); + } + //printk("\nauto focus driver 5\n"); + + + + + IRP_ASSERT(irp_write_packet(srv_open, + vpip_default_params[FocusControls_bMode].addr, + 1));// FC_TLI_MODE_AF_CONTINUOUS_FOCUS + //printk("\nauto focus driver 6\n"); + + +return ret; + + +}EXPORT_SYMBOL(sva_vpip_auto_focus); + + + + + + + +__u16 irp_sensor750_settings[32][2]; + +__u16 irp_start_sequence[14][2]; + +u16 page_elem_boot_table[32][2]; + +u16 mode_setup_bank0[16][2]; + +int init_struct(){ +int i,m; + +#if 0 +__u16 irp_sensor750_settings2[32][2] = + + { + {vpip_default_params[0].addr,3}, + + + {vpip_default_params[3].addr,0x3103}, + {vpip_default_params[5].addr,15}, + {vpip_default_params[1].addr,1}, + + {vpip_default_params[0].addr,3}, + {vpip_default_params[3].addr,0x3103}, + {vpip_default_params[5].addr,15}, + {vpip_default_params[1].addr, 2}, + + {vpip_default_params[0].addr, 3}, + {vpip_default_params[3].addr, 0x3114}, + {vpip_default_params[5].addr, 11}, + {vpip_default_params[1].addr, 1}, + + {vpip_default_params[0].addr, 3}, + {vpip_default_params[3].addr, 0x3116}, + {vpip_default_params[5].addr, 2}, + {vpip_default_params[1].addr, 2}, + + {vpip_default_params[0].addr, 3}, + {vpip_default_params[3].addr, 0x311a}, + {vpip_default_params[5].addr, 11}, + {vpip_default_params[1].addr, 1}, + + {vpip_default_params[0].addr, 3}, + {vpip_default_params[3].addr, 0x3118}, + {vpip_default_params[5].addr, 62}, + {vpip_default_params[1].addr, 2}, + + {vpip_default_params[0].addr, 3}, + {vpip_default_params[3].addr, 0x3117}, + {vpip_default_params[5].addr, 12}, //14 + {vpip_default_params[1].addr, 1} +}; +#endif + + + + + +__u16 irp_sensor750_settings2[32][2] = + + { + {vpip_default_params[HostToSensorAccessControl_bRequest].addr,3}, + + + {vpip_default_params[HostToSensorAccessControl_uwSensorIndex_MSByte].addr,0x3103}, + {vpip_default_params[HostToSensorAccessData_uwDataLow_LSByte].addr,15}, + {vpip_default_params[HostToSensorAccessControl_bCommandCoin].addr,1}, + + {vpip_default_params[HostToSensorAccessControl_bRequest].addr,3}, + {vpip_default_params[HostToSensorAccessControl_uwSensorIndex_MSByte].addr,0x3103}, + {vpip_default_params[HostToSensorAccessData_uwDataLow_LSByte].addr,15}, + {vpip_default_params[HostToSensorAccessControl_bCommandCoin].addr, 2}, + + {vpip_default_params[HostToSensorAccessControl_bRequest].addr, 3}, + {vpip_default_params[HostToSensorAccessControl_uwSensorIndex_MSByte].addr, 0x3114}, + {vpip_default_params[HostToSensorAccessData_uwDataLow_LSByte].addr, 11}, + {vpip_default_params[HostToSensorAccessControl_bCommandCoin].addr, 1}, + + {vpip_default_params[HostToSensorAccessControl_bRequest].addr, 3}, + {vpip_default_params[HostToSensorAccessControl_uwSensorIndex_MSByte].addr, 0x3116}, + {vpip_default_params[HostToSensorAccessData_uwDataLow_LSByte].addr, 2}, + {vpip_default_params[HostToSensorAccessControl_bCommandCoin].addr, 2}, + + {vpip_default_params[HostToSensorAccessControl_bRequest].addr, 3}, + {vpip_default_params[HostToSensorAccessControl_uwSensorIndex_MSByte].addr, 0x311a}, + {vpip_default_params[HostToSensorAccessData_uwDataLow_LSByte].addr, 11}, + {vpip_default_params[HostToSensorAccessControl_bCommandCoin].addr, 1}, + + {vpip_default_params[HostToSensorAccessControl_bRequest].addr, 3}, + {vpip_default_params[HostToSensorAccessControl_uwSensorIndex_MSByte].addr, 0x3118}, + {vpip_default_params[HostToSensorAccessData_uwDataLow_LSByte].addr, 62}, + {vpip_default_params[HostToSensorAccessControl_bCommandCoin].addr, 2}, + + {vpip_default_params[HostToSensorAccessControl_bRequest].addr, 3}, + {vpip_default_params[HostToSensorAccessControl_uwSensorIndex_MSByte].addr, 0x3117}, + {vpip_default_params[HostToSensorAccessData_uwDataLow_LSByte].addr, 12}, //14 + {vpip_default_params[HostToSensorAccessControl_bCommandCoin].addr, 1} +}; + + +__u16 page_elem_boot_table2[32][2] +//vpip_default_params[FLADriverLowLevelParameters_AutoSkipNextFrame].addr + + = { + {vpip_default_params[SystemConfiguration_fNearSensorPresent].addr,vpip_default_params[SystemConfiguration_fNearSensorPresent].val},//0x01}, // System config NEAR SENSOR present (YES) + {vpip_default_params[SystemConfiguration_fFarSensorPresent].addr,vpip_default_params[SystemConfiguration_fFarSensorPresent].val},//0x01}, // System config FAR SENSOR present (NO) + {vpip_default_params[SystemConfiguration_CcpRxForNearSensor].addr,vpip_default_params[SystemConfiguration_CcpRxForNearSensor].val},//0x01}, //1 SystemConfiguration_CcpRxForNearSensor + {vpip_default_params[SystemConfiguration_CcpRxForFarSensor].addr,vpip_default_params[SystemConfiguration_CcpRxForFarSensor].val},//0x00}, //0 SystemConfiguration_CcpRxForFarSensor +#ifdef CONFIG_NOMADIK_NHK15 + {vpip_default_params[SystemConfiguration_uwExternalClockFrequency_Mhz_num_MSByte].addr,vpip_default_params[SystemConfiguration_uwExternalClockFrequency_Mhz_num_MSByte].val},//0x60}, + {vpip_default_params[SystemConfiguration_bExternalClockFrequency_Mhz_den].addr,vpip_default_params[SystemConfiguration_bExternalClockFrequency_Mhz_den].val},//0x05}, +#else + {vpip_default_params[SystemConfiguration_uwExternalClockFrequency_Mhz_num_MSByte].addr,0x0c}, + {vpip_default_params[SystemConfiguration_bExternalClockFrequency_Mhz_den].addr,0x01}, +#endif + {vpip_default_params[MasterI2cControl_uwRequiredI2cSpeed_MSByte].addr,vpip_default_params[MasterI2cControl_uwRequiredI2cSpeed_MSByte].val},//400}, //MasterI2cControl_uwRequiredI2cSpeed_MSByte + {vpip_default_params[MiscPageElements_bDelayAfterSettingXshutdown].addr,vpip_default_params[MiscPageElements_bDelayAfterSettingXshutdown].val},//0xf0}, //for 850 sensor (yes, affects other too...) +// {0x4902,0xff}, //for 850 sensor (yes, affects other too...) //fw-change + {vpip_default_params[MiscPageElements_fConvertMultiByteReadsIntoSingleByte].addr,vpip_default_params[MiscPageElements_fConvertMultiByteReadsIntoSingleByte].val},//1}, +// {MiscPageElements_VpipCut, 0}, /*851 0=Cut_B, 1=Cut_A */ + {vpip_default_params[ModeSetupBank0_bActiveSensor].addr,0x0}, //ModeSetupBank0_bActiveSensor + {vpip_default_params[ModeSetupBank1_bActiveSensor].addr,0x0}, //ModeSetupBank1_bActiveSensor + {vpip_default_params[VideoTimingInputsNearSensor_VideoTimingMode].addr,vpip_default_params[VideoTimingInputsNearSensor_VideoTimingMode].val},//0x01}, //VideoTimingMode_Automatic + {vpip_default_params[VideoTimingInputsNearSensor_fpHostRxMaxDataRate_Mbps_MSByte].addr,vpip_default_params[VideoTimingInputsNearSensor_fpHostRxMaxDataRate_Mbps_MSByte].val},//0x508a}, //Float + {vpip_default_params[VideoTimingInputsNearSensor_uwCsiRawFormat_MSByte].addr,vpip_default_params[VideoTimingInputsNearSensor_uwCsiRawFormat_MSByte].val},//0x0808}, + {vpip_default_params[VideoTimingInputsNearSensor_bSensorBitsPerSystemClock].addr,vpip_default_params[VideoTimingInputsNearSensor_bSensorBitsPerSystemClock].val},//0x02}, + + {vpip_default_params[VideoTimingInputsFarSensor_VideoTimingMode].addr,vpip_default_params[VideoTimingInputsFarSensor_VideoTimingMode].val},//0x01}, + {vpip_default_params[VideoTimingInputsFarSensor_fpHostRxMaxDataRate_Mbps_MSByte].addr,vpip_default_params[VideoTimingInputsFarSensor_fpHostRxMaxDataRate_Mbps_MSByte].val},//0x508a }, + + {vpip_default_params[VideoTimingInputsFarSensor_uwCsiRawFormat_MSByte].addr,vpip_default_params[VideoTimingInputsFarSensor_uwCsiRawFormat_MSByte].val},//0x0808}, + {vpip_default_params[VideoTimingInputsFarSensor_bSensorBitsPerSystemClock].addr,vpip_default_params[VideoTimingInputsFarSensor_bSensorBitsPerSystemClock].val},//0x02}, + {vpip_default_params[VideoTimingHostInputs_VideoTimingMode].addr,vpip_default_params[VideoTimingHostInputs_VideoTimingMode].val},//0x01}, + {vpip_default_params[VideoTimingHostInputs_bSensorBitsPerSystemClock].addr,vpip_default_params[VideoTimingHostInputs_bSensorBitsPerSystemClock].val},//0x02}, + {vpip_default_params[VideoTimingHostInputs_uwCsiRawFormat_MSByte].addr,vpip_default_params[VideoTimingHostInputs_uwCsiRawFormat_MSByte].val},//0x0808}, + {vpip_default_params[VideoTimingHostInputs_fpHostRxMaxDataRate_Mbps_MSByte].addr,vpip_default_params[VideoTimingHostInputs_fpHostRxMaxDataRate_Mbps_MSByte].val},//0x508a}, + {vpip_default_params[SystemConfiguration_fFocusLensActuatorOnSensorNearPresent].addr,vpip_default_params[SystemConfiguration_fFocusLensActuatorOnSensorNearPresent].val},//0x00}, + {vpip_default_params[SystemConfiguration_fFocusLensActuatorOnSensorFarPresent].addr,vpip_default_params[SystemConfiguration_fFocusLensActuatorOnSensorFarPresent].val},//0x00}, + /* 851 */ + {vpip_default_params[FLADriverLowLevelParameters_AutoSkipNextFrame].addr,vpip_default_params[FLADriverLowLevelParameters_AutoSkipNextFrame].val},//0x1}, + {vpip_default_params[FLADriverLowLevelParameters_bMaxNumberRetries].addr, vpip_default_params[FLADriverLowLevelParameters_bMaxNumberRetries].val},//0xa}, + {vpip_default_params[FLADriverLowLevelParameters_fOverwriteLowLevelLimits].addr,vpip_default_params[FLADriverLowLevelParameters_fOverwriteLowLevelLimits].val},// 0x1}, + {vpip_default_params[FLADriverLowLevelParameters_fLowLevelDriverInitialized].addr,vpip_default_params[FLADriverLowLevelParameters_fLowLevelDriverInitialized].val},// 0x1}, + {vpip_default_params[BinningControl_fEnableBinning].addr,vpip_default_params[BinningControl_fEnableBinning].val},// 0} +}; + + + + __u16 irp_start_sequence2[14][2] + + + = { + {vpip_default_params[PipeSetupBankA_uwPipeOutputSize_X_MSByte].addr,128}, + {vpip_default_params[PipeSetupBankA_uwPipeOutputSize_Y_MSByte].addr,96}, + {vpip_default_params[PipeSetupBankA_bPipeOutputFormat].addr,vpip_default_params[PipeSetupBankA_bPipeOutputFormat].val},//3, /* yuv 422 */ + {vpip_default_params[PipeSetupBankA_bPipeStreamLength].addr,vpip_default_params[PipeSetupBankA_bPipeStreamLength].val},//0, /* infinite */ + {vpip_default_params[PipeSetupBankA_fTogglePixValid].addr,vpip_default_params[PipeSetupBankA_fTogglePixValid].val},//0}, /* ? */ + {vpip_default_params[PipeSetupBankA_fEnableItuEmbeddedCodes].addr,vpip_default_params[PipeSetupBankA_fEnableItuEmbeddedCodes].val},//0}, /* no embedded code */ + {vpip_default_params[PipeSetupBankA_bPixValidLineTypes].addr,vpip_default_params[PipeSetupBankA_bPixValidLineTypes].val},//0x20}, /* ? */ + {vpip_default_params[PipeSetupBankA_fGenerateVSync].addr,vpip_default_params[PipeSetupBankA_fGenerateVSync].val},//1}, /*vertical sync need ? */ + {vpip_default_params[PipeSetupBankA_fCb_Cr_Flip].addr,vpip_default_params[PipeSetupBankA_fCb_Cr_Flip].val},//0}, + {vpip_default_params[PipeSetupBankA_fY_CbCr_Flip].addr,vpip_default_params[PipeSetupBankA_fY_CbCr_Flip].val},//0}, + {vpip_default_params[StaticFrameRateControl_uwDesiredFrameRate_Num_MSByte].addr, 0}, + {vpip_default_params[RunModeControl_fMeteringOn].addr,vpip_default_params[RunModeControl_fMeteringOn].val},//1}, /* auto exposure and white balance on */ + {vpip_default_params[RunModeControl_bStreamLength].addr,vpip_default_params[RunModeControl_bStreamLength].val},//0}, /* infinite streaming */ //851 =1 , 750=0 + }; + +#if 0 +u16 mode_setup_bank02[16][2] = { + {vpip_default_params[ModeSetupBank0_uwInputImageSize_X_MSByte].addr,vpip_default_params[ModeSetupBank0_uwInputImageSize_X_MSByte].val}, + {vpip_default_params[ModeSetupBank0_uwInputImageSize_Y_MSByte].addr,vpip_default_params[ModeSetupBank0_uwInputImageSize_Y_MSByte].val}, + {vpip_default_params[ModeSetupBank0_uwMaxImageSize_X_MSByte].addr,vpip_default_params[ModeSetupBank0_uwMaxImageSize_X_MSByte].val}, + {vpip_default_params[ModeSetupBank0_uwMaxImageSize_Y_MSByte].addr,vpip_default_params[ModeSetupBank0_uwMaxImageSize_Y_MSByte].val}, + {vpip_default_params[ModeSetupBank0_uwMinImageSize_X_MSByte].addr,0x0160}, + {vpip_default_params[ModeSetupBank0_uwMinImageSize_Y_MSByte].addr,0x0120}, + {vpip_default_params[ModeSetupBank0_fLowPowerStreaming].addr,vpip_default_params[ModeSetupBank0_fLowPowerStreaming].val},//0 + {vpip_default_params[ModeSetupBank0_bTestMode].addr,0}, + {vpip_default_params[ModeSetupBank0_bNumberOfStatusLines].addr,0x03}, + {vpip_default_params[ModeSetupBank0_bNumberOfDarkLines].addr,0x02}, + {vpip_default_params[ModeSetupBank0_bNumberOfBlackLines].addr,0x04}, + {vpip_default_params[ModeSetupBank0_uwNumberOfInterLinePixelClocks_MSByte].addr,0x11}, + {vpip_default_params[ModeSetupBank0_uwNumberOfInterFrameLines_MSByte].addr ,0}, + {vpip_default_params[ModeSetupBank0_bNumberOfDummyColumns].addr,0x08}, + {vpip_default_params[ModeSetupBank0_bInputImageSource].addr,vpip_default_params[ModeSetupBank0_bInputImageSource].val}, +/* fixme {ModeSetupBank0_bOutputImageDestination,0},*/ +}; +#endif +u16 mode_setup_bank02[16][2] = { + {vpip_default_params[ModeSetupBank0_uwInputImageSize_X_MSByte].addr, vpip_default_params[ModeSetupBank0_uwInputImageSize_X_MSByte].val}, + {vpip_default_params[ModeSetupBank0_uwInputImageSize_Y_MSByte].addr, vpip_default_params[ModeSetupBank0_uwInputImageSize_Y_MSByte].val}, + {vpip_default_params[ModeSetupBank0_uwMaxImageSize_X_MSByte].addr, vpip_default_params[ModeSetupBank0_uwMaxImageSize_X_MSByte].val}, + {vpip_default_params[ModeSetupBank0_uwMaxImageSize_Y_MSByte].addr, vpip_default_params[ModeSetupBank0_uwMaxImageSize_Y_MSByte].val}, + {vpip_default_params[ModeSetupBank0_uwMinImageSize_X_MSByte].addr, vpip_default_params[ModeSetupBank0_uwMinImageSize_X_MSByte].val},//0x0160}, + {vpip_default_params[ModeSetupBank0_uwMinImageSize_Y_MSByte].addr, vpip_default_params[ModeSetupBank0_uwMinImageSize_Y_MSByte].val},//0x0120}, + {vpip_default_params[ModeSetupBank0_fLowPowerStreaming].addr, vpip_default_params[ModeSetupBank0_fLowPowerStreaming].val},//0 + {vpip_default_params[ModeSetupBank0_bTestMode].addr, vpip_default_params[ModeSetupBank0_bTestMode].val},//0}, + {vpip_default_params[ModeSetupBank0_bNumberOfStatusLines].addr, vpip_default_params[ModeSetupBank0_bNumberOfStatusLines].val},//0x03}, + {vpip_default_params[ModeSetupBank0_bNumberOfDarkLines].addr, vpip_default_params[ModeSetupBank0_bNumberOfDarkLines].val},//0x02}, + {vpip_default_params[ModeSetupBank0_bNumberOfBlackLines].addr, vpip_default_params[ModeSetupBank0_bNumberOfBlackLines].val},//0x04}, + {vpip_default_params[ModeSetupBank0_uwNumberOfInterLinePixelClocks_MSByte].addr, vpip_default_params[ModeSetupBank0_uwNumberOfInterLinePixelClocks_MSByte].val},//0x11}, + {vpip_default_params[ModeSetupBank0_uwNumberOfInterFrameLines_MSByte].addr , vpip_default_params[ModeSetupBank0_uwNumberOfInterFrameLines_MSByte].val},//0}, + {vpip_default_params[ModeSetupBank0_bNumberOfDummyColumns].addr, vpip_default_params[ModeSetupBank0_bNumberOfDummyColumns].val},//0x08}, + {vpip_default_params[ModeSetupBank0_bInputImageSource].addr, vpip_default_params[ModeSetupBank0_bInputImageSource].val}, +/* fixme {ModeSetupBank0_bOutputImageDestination,0},*/ +}; + + for(m=0;m<32;m++) + for(i=0;i<2;i++) + irp_sensor750_settings[m][i]=irp_sensor750_settings2[m][i]; + + for(m=0;m<32;m++) + for(i=0;i<2;i++) + page_elem_boot_table[m][i]=page_elem_boot_table2[m][i]; + +for(m=0;m<14;m++) + for(i=0;i<2;i++) + irp_start_sequence[m][i]=irp_start_sequence2[m][i]; + +for(m=0;m<16;m++) + for(i=0;i<2;i++) + mode_setup_bank0[m][i]=mode_setup_bank02[m][i]; + + +return 0; +} + +void reset_vpip_to_default(void) +{int index=0; +//restore original default configuration for page elements +for(index=0;index<2208;index++) +memcpy(&vpip_default_params[index],&vpip_default_params_orig[index],sizeof(struct nomadik_vpip_param)); + +} + + + +static int irp_start_read_packet(t_sva_service_id service_id, __u16 index) +{ + t_sva_packet packet; + t_sva_error hcl_sva_err= SVA_OK; + + packet.address = index; + packet.value =0; + + + lock_critical_section(&hcl_mutex); + dbgprintk(1,"vpip: packet read sent at index =0x%x.\n", index); + hcl_sva_err = SVA_UpdatePreProcessorParams(service_id, SVA_UPDATE_LAST, + SVA_PREPROCESSOR_PACKET_READ, (u32)&packet); + unlock_critical_section(&hcl_mutex); + return hcl_sva_err; +} + +static int irp_start_write_packet(t_sva_service_id service_id, __u16 index, __u16 value) +{ + t_sva_packet packet; + t_sva_error hcl_sva_err= SVA_OK; + + packet.address = index; + packet.value = value; + + lock_critical_section(&hcl_mutex); + hcl_sva_err = SVA_UpdatePreProcessorParams(service_id, + SVA_UPDATE_LAST,SVA_PREPROCESSOR_PACKET_WRITE,(u32) &packet); + unlock_critical_section(&hcl_mutex); + return hcl_sva_err; +} + +static int irp_write_packet(struct sva_service_open *srv_open, __u16 offset, __u16 writevalue) +{ + int packet_error=0; + __u16 readvalue; + t_sva_error sva_err; + + dbgprintk(1,"vpip: packet write sent with index=0x%x & value=0x%x.\n", offset, writevalue); + sva_err = irp_start_write_packet(srv_open->service_id, offset, writevalue); + if(sva_err != SVA_OK && sva_err !=SVA_CONFIGURATION_IN_PROGRESS) { + dbgprintk(3," failed to start write command to irp %d \n", sva_err); + return -1; + } + + packet_error= block_until_irppacket_finish(srv_open, &readvalue); + if(packet_error == -1) + return -1; + return SVA_OK; +} + +static int irp_read_packet(struct sva_service_open *srv_open, __u16 offset, __u16 *readvalue) +{ + int packet_error=0; + t_sva_error sva_err; + + sva_err = irp_start_read_packet(srv_open->service_id, offset); + if(sva_err != SVA_OK) { + dbgprintk(3," failed to start read command to irp %d \n", sva_err); + return -1; + } + + packet_error= block_until_irppacket_finish(srv_open, readvalue); + if(packet_error) + return -1; + return SVA_OK; +} + +static int block_until_irppacket_finish(struct sva_service_open *srv_open, __u16 *readvalue) +{ + int packet_error = 0; + + wait_event_interruptible(srv_open->service_inactivate_wq, + (srv_open->irp_pkt.rw_packet_finish==1)); + + srv_open->irp_pkt.rw_packet_finish = 0; + switch(srv_open->irp_pkt.eventId) { + case SVA_EVENT_PACKET_ERROR: + dbgprintk(3," packet error event arrived \n"); + packet_error = -1; + break; + case SVA_EVENT_PACKET_READ: + *readvalue = srv_open->irp_pkt.readvalue; + break; + case SVA_EVENT_PACKET_WRITE: + break; + default: + dbgprintk(2," invalid event Id for irp packet \n"); + return -1; + break; + } + srv_open->irp_pkt.eventId = 0; + return packet_error; +} + +int sensor_default_param_add(struct nomadik_vpip_param *camparam){ +int add=0; +camparam=&vpip_default_params[0]; +//printk("\....Inside ..sensor_default_param_add: name %s\n",vpip_default_params[0].register_name); +//printk("\nvpip_default_params: name %s\n",camparam->register_name); + +return add; +}EXPORT_SYMBOL(sensor_default_param_add); + + + + + +int irp_update_service(struct sva_service_open *srv_open, + enum sva_update_service_param param, __u16 update_value) +{ + int ret =0; + int zoom_range=0; + int zoom_pos=0; + t_sva_error sva_err = SVA_OK; + + static int test_coin=1; + + + //int test_coin= update_value; + dbgprintk(1,"updating IRP paramer %d with value %d\n", param, update_value); + + switch(param) { + case PREPROCESSOR_ZOOM_IN: + + //IRP_ASSERT(irp_write_packet(srv_open, vpip_default_params[ZoomMgrCtrl_bHostTestCoin].addr, test_coin++)); + + sva_err = irp_write_packet(srv_open, vpip_default_params[ZoomMgrCtrl_bZoomCmd].addr,1); //zoom_in + if(sva_err != SVA_OK){ + dbgprintk(3,"Could not update zoom parameter \n"); + ret = -1; + break; + } + + __udelay(1000); + + IRP_ASSERT(irp_write_packet(srv_open, vpip_default_params[ZoomMgrCtrl_bHostTestCoin].addr, test_coin++)); + __udelay(1000); + + sva_err = irp_write_packet(srv_open, vpip_default_params[ZoomMgrCtrl_bZoomCmd].addr,4); /* stop zoom */ + __udelay(1000); + IRP_ASSERT(irp_write_packet(srv_open, vpip_default_params[ZoomMgrCtrl_bHostTestCoin].addr, test_coin++)); + + IRP_ASSERT(irp_read_packet(srv_open, vpip_default_params[ZoomMgrParams_fp16ZoomRange_MSByte].addr, &zoom_range)); + + if(sva_err != SVA_OK){ + dbgprintk(3,"Could not update zoom parameter \n"); + ret = -1; + } + + + break; + case PREPROCESSOR_ZOOM_OUT: + + sva_err = irp_write_packet(srv_open, vpip_default_params[ZoomMgrCtrl_bZoomCmd].addr,2); //zoom_out + if(sva_err != SVA_OK){ + dbgprintk(3,"Could not update zoom parameter \n"); + ret = -1; + break; + } + + __udelay(1000); + + + IRP_ASSERT(irp_write_packet(srv_open, vpip_default_params[ZoomMgrCtrl_bHostTestCoin].addr, test_coin++)); + __udelay(1000); + + + sva_err = irp_write_packet(srv_open, vpip_default_params[ZoomMgrCtrl_bZoomCmd].addr,4); /* stop zoom */ + __udelay(1000); + IRP_ASSERT(irp_write_packet(srv_open, vpip_default_params[ZoomMgrCtrl_bHostTestCoin].addr, test_coin++)); + + IRP_ASSERT(irp_read_packet(srv_open, vpip_default_params[ZoomMgrParams_fp16ZoomRange_MSByte].addr, &zoom_range)); + + + + if(sva_err != SVA_OK){ + dbgprintk(3,"Could not update zoom parameter \n"); + ret = -1; + } + + + + break; + case PREPROCESSOR_CONTRAST: + dbgprintk(1," changing the contrast value to %d \n",update_value); + sva_err = irp_write_packet(srv_open, vpip_default_params[ColourEngine0_OutputCoderControls_bContrast].addr, update_value); + if(sva_err != SVA_OK){ + dbgprintk(3,"failed to change contrast parameter \n"); + ret = -1; + } + break; + case PREPROCESSOR_COLOUR_SATURATION: + dbgprintk(1,"changing the color saturation value to %d \n",update_value); + sva_err = irp_write_packet(srv_open, vpip_default_params[ColourEngine0_OutputCoderControls_bColourSaturation].addr, + update_value); + if(sva_err != SVA_OK){ + dbgprintk(3,"failed to change colour saturation parameter \n"); + ret = -1; + } + break; + + case PREPROCESSOR_WHITEBALANCE: + if(update_value >8){ + dbgprintk(3,"invalid change value for whitebalance control.\n"); + ret =-1; + break; + } + sva_err = irp_write_packet(srv_open, vpip_default_params[WhiteBalanceControls_bMode].addr, + update_value); + if(sva_err != SVA_OK){ + dbgprintk(3,"failed to change whitebalance mode.\n"); + ret = -1; + } + break; + + case PREPROCESSOR_COLMATRIX_DAMPING: + { + int i=0; + __u16 colour_matrix_update[][2] = { + {vpip_default_params[ColourEngine0_ColourMatrixNearSensor_fpRInR_LSByte].addr,vpip_default_params[ColourEngine0_ColourMatrixNearSensor_fpRInR_LSByte].val},//0x0002}, //0.299 + {vpip_default_params[ColourEngine0_ColourMatrixNearSensor_fpRInR_MSByte].addr,vpip_default_params[ColourEngine0_ColourMatrixNearSensor_fpRInR_MSByte].val},//0x6400}, + {vpip_default_params[ColourEngine0_ColourMatrixNearSensor_fpGInR_LSByte].addr,vpip_default_params[ColourEngine0_ColourMatrixNearSensor_fpGInR_LSByte].val},//0x0002}, + {vpip_default_params[ColourEngine0_ColourMatrixNearSensor_fpGInR_MSByte].addr,vpip_default_params[ColourEngine0_ColourMatrixNearSensor_fpGInR_MSByte].val},//0x6400}, + {vpip_default_params[ColourEngine0_ColourMatrixNearSensor_fpBInR_LSByte].addr,vpip_default_params[ColourEngine0_ColourMatrixNearSensor_fpGInR_MSByte].val},//0x02}, + {vpip_default_params[ColourEngine0_ColourMatrixNearSensor_fpBInR_MSByte].addr,vpip_default_params[ColourEngine0_ColourMatrixNearSensor_fpBInR_MSByte].val},//0x6400}, + {vpip_default_params[ColourEngine0_ColourMatrixNearSensor_fpRInG_LSByte].addr,vpip_default_params[ColourEngine0_ColourMatrixNearSensor_fpRInG_LSByte].val},//0x0004}, //0.587 + {vpip_default_params[ColourEngine0_ColourMatrixNearSensor_fpRInG_MSByte].addr,vpip_default_params[ColourEngine0_ColourMatrixNearSensor_fpRInG_MSByte].val},//0xB200}, + {vpip_default_params[ColourEngine0_ColourMatrixNearSensor_fpGInG_LSByte].addr,vpip_default_params[ColourEngine0_ColourMatrixNearSensor_fpGInG_LSByte].val},// 0x0004}, + {vpip_default_params[ColourEngine0_ColourMatrixNearSensor_fpGInG_MSByte].addr,vpip_default_params[ColourEngine0_ColourMatrixNearSensor_fpGInG_MSByte].val},//0xB200}, + {vpip_default_params[ColourEngine0_ColourMatrixNearSensor_fpBInG_LSByte].addr,vpip_default_params[ColourEngine0_ColourMatrixNearSensor_fpBInG_LSByte].val},// 0x0004}, + {vpip_default_params[ColourEngine0_ColourMatrixNearSensor_fpBInG_MSByte].addr,vpip_default_params[ColourEngine0_ColourMatrixNearSensor_fpBInG_MSByte].val},// 0xB200}, + {vpip_default_params[ColourEngine0_ColourMatrixNearSensor_fpRInB_LSByte].addr,vpip_default_params[ColourEngine0_ColourMatrixNearSensor_fpRInB_LSByte].val},// 0x0000}, + {vpip_default_params[ColourEngine0_ColourMatrixNearSensor_fpRInB_MSByte].addr,vpip_default_params[ColourEngine0_ColourMatrixNearSensor_fpRInB_MSByte].val},// 0xe900}, + {vpip_default_params[ColourEngine0_ColourMatrixNearSensor_fpGInB_LSByte].addr,vpip_default_params[ColourEngine0_ColourMatrixNearSensor_fpGInB_LSByte].val},//0x0000}, + {vpip_default_params[ColourEngine0_ColourMatrixNearSensor_fpGInB_MSByte].addr,vpip_default_params[ColourEngine0_ColourMatrixNearSensor_fpGInB_MSByte].val},//0xe900}, + {vpip_default_params[ColourEngine0_ColourMatrixNearSensor_fpBInB_LSByte].addr,vpip_default_params[ColourEngine0_ColourMatrixNearSensor_fpBInB_LSByte].val},//0x0000}, + {vpip_default_params[ColourEngine0_ColourMatrixNearSensor_fpBInB_MSByte].addr,vpip_default_params[ColourEngine0_ColourMatrixNearSensor_fpBInB_MSByte].val}//0xe900} + }; + if(update_value != 0 || update_value != 1){ + ret =-1; + break; + } + + for(i=0; i< sizeof(colour_matrix_update)/4; i++){ + sva_err = irp_write_packet(srv_open, colour_matrix_update[i][0], + colour_matrix_update[i][1]); + if(sva_err != SVA_OK){ + dbgprintk(3,"failed to change colourMatrix damper.\n"); + ret = -1; + break; + } + } + sva_err = irp_write_packet(srv_open, vpip_default_params[ColourEngine0_ColourMatrixDamperControl_fDisableMatrixDamping].addr, + update_value); /* 0 or 1 */ + if(sva_err != SVA_OK){ + dbgprintk(3,"failed to enable/disable damper effect.\n"); + ret = -1; + } + } + break; + case PREPROCESSOR_EXPOSURE: + if(update_value > EXPO_CYCLETEST_MODE){ + ret =-1; + break; + } + sva_err = irp_write_packet(srv_open, vpip_default_params[ExposureControls_bMode].addr, + update_value); + if(sva_err != SVA_OK){ + dbgprintk(3,"failed to change exposure control mode.\n"); + ret = -1; + } + break; + case PREPROCESSOR_ENABLE_FUNCBLOCK: + { + int i; + __u16 func_block_update[][2] = { + {vpip_default_params[VfpnControls_fEnableCorrection].addr,1}, //0.299 + {vpip_default_params[AntiVignetteControls_fDisableFilter].addr,vpip_default_params[AntiVignetteControls_fDisableFilter].val},//0}, + {vpip_default_params[ScytheFilterControls_fDisableFilter].addr,vpip_default_params[ScytheFilterControls_fDisableFilter].val},//0}, + {vpip_default_params[NoraControls_fDisable].addr,vpip_default_params[NoraControls_fDisable].val},//0}, + {vpip_default_params[JackFilterControls_fDisableFilter].addr,vpip_default_params[JackFilterControls_fDisableFilter].val},//0} + }; + for(i=0; i< sizeof(func_block_update)/4; i++){ + sva_err = irp_write_packet(srv_open, func_block_update[i][0], + func_block_update[i][1]); + if(sva_err != SVA_OK){ + dbgprintk(3,"failed to enable function block.\n"); + ret = -1; + break; + } + } + break; + } + case PREPROCESSOR_FADETOBLACK: + IRP_ASSERT(irp_write_packet(srv_open, vpip_default_params[ColourEngine0_FadeToBlack_fpBlackValue_LSByte].addr, + update_value)); + IRP_ASSERT(irp_write_packet(srv_open, vpip_default_params[ColourEngine0_FadeToBlack_fpBlackValue_MSByte].addr, + update_value)); + IRP_ASSERT(irp_write_packet(srv_open, vpip_default_params[ColourEngine0_FadeToBlack_fDisable].addr, + update_value)); +/* if(irp_stop_ewarp(srv_open)) + return -1; + + sva_err = irp_write_packet(srv_open, HostInterfaceManagerControl_bUserCommand, EWARP_START); + if(sva_err != SVA_OK){ + dbgprintk(3,"%d: Failed to write to vpip \n", __LINE__); + return -1; + } +*/ + break; + case PREPROCESSOR_RADIAL_PEAKING: + if(update_value !=0 || update_value != 1){ + ret =-1; + break; + } + sva_err = irp_write_packet(srv_open, vpip_default_params[ColourEngine0_RadialApertureCorrectionControl_fEnableCorrection].addr, update_value); + if(sva_err != SVA_OK){ + dbgprintk(3,"failed to change exposure control mode.\n"); + ret = -1; + } + break; + default: + break; + } + return ret; +} +static int firmware_size=0; +static unsigned char *irp_fw_ptr=NULL; + +int irp_activate_service(struct sva_service_open *srv_open) +{ + t_sva_error sva_err=SVA_OK; + t_bool status; + int retry=0; + union { + struct { + t_uint8 byte3; + t_uint8 byte2; + t_uint8 byte1; + t_uint8 byte0; + } multibyte; + float toto; + } converter; + converter.toto=640; + + init_struct(); + + /* XXX Logic for irp fw switch can be added here */ + lock_critical_section(&hcl_mutex); + sva_err = SVA_IrpInit((t_logical_address)irp_fw_ptr, firmware_size); + unlock_critical_section(&hcl_mutex); + if(sva_err!=SVA_OK){ + dbgprintk(3,"Failed to register IRP firmware %d\n", sva_err); + return -1; + } + + mdelay(300); + + dbgprintk(2,"Checking for boot status ewarp \n"); + do { + status = SVA_IrpBootStatus(); + if(status!=TRUE){ + dbgprintk(3,"IRP fw boot failed %d \n", status); + if(retry++==10)return -1; + } + else { + dbgprintk(2,"IRP fw boot Success %d\n", status); + break; + } + mdelay(300); + }while (status!=TRUE); + + + /* start the IRP if not yet started */ + if(irp_start_fw(srv_open, + srv_open->config.preprocessor_info.camera_framerate)!=SVA_OK) { + dbgprintk(3,"Failed to start irp firmware \n"); + return -1; + } + +#if 0 + //IRP_ASSERT(irp_write_packet(srv_open, vpip_default_params[HostInterfaceManagerControl_bUserCommand].addr, EWARP_STOP)); + //irp_stop_ewarp(srv_open); + IRP_ASSERT(irp_write_packet(srv_open, vpip_default_params[ZoomMgrCtrl_bHostTestCoin].addr, 1)); + IRP_ASSERT(irp_write_packet(srv_open, vpip_default_params[ZoomMgrCtrl_fAutoZoom].addr, 0)); + __udelay(100); + IRP_ASSERT(irp_write_packet(srv_open, vpip_default_params[ZoomMgrCtrl_fSetX_Byte0].addr,0)); + IRP_ASSERT(irp_write_packet(srv_open, vpip_default_params[ZoomMgrCtrl_fSetX_Byte1].addr,0)); + IRP_ASSERT(irp_write_packet(srv_open, vpip_default_params[ZoomMgrCtrl_fSetX_Byte2].addr,0)); + IRP_ASSERT(irp_write_packet(srv_open, vpip_default_params[ZoomMgrCtrl_fSetX_Byte3].addr,0)); + __udelay(100); + + //IRP_ASSERT(irp_write_packet(srv_open, vpip_default_params[ZoomMgrCtrl_bMagFactor].addr,128)); //set magFactor + + + + + IRP_ASSERT(irp_write_packet(srv_open, vpip_default_params[ZoomMgrCtrl_fSetX_Byte0].addr,converter.multibyte.byte0)); + IRP_ASSERT(irp_write_packet(srv_open, vpip_default_params[ZoomMgrCtrl_fSetX_Byte1].addr,converter.multibyte.byte1)); + IRP_ASSERT(irp_write_packet(srv_open, vpip_default_params[ZoomMgrCtrl_fSetX_Byte2].addr,converter.multibyte.byte2)); + IRP_ASSERT(irp_write_packet(srv_open, vpip_default_params[ZoomMgrCtrl_fSetX_Byte3].addr,converter.multibyte.byte3)); + + IRP_ASSERT(irp_write_packet(srv_open, vpip_default_params[ZoomMgrCtrl_fSetAlternateInitWOI].addr,1)); + IRP_ASSERT(irp_write_packet(srv_open, vpip_default_params[ZoomMgrCtrl_bZoomCmd].addr,5)); //zoom-in + + __udelay(100); + + //IRP_ASSERT(irp_write_packet(srv_open, 0x322,0x4)); + IRP_ASSERT(irp_write_packet(srv_open, vpip_default_params[ZoomMgrCtrl_bHostTestCoin].addr, 2));//toggle + __udelay(100); +// IRP_ASSERT(irp_write_packet(srv_open, vpip_default_params[HostInterfaceManagerControl_bUserCommand].addr, EWARP_START)); +// if(irp_write_packet(srv_open, vpip_default_params[HostInterfaceManagerControl_bUserCommand].addr,EWARP_START)!=SVA_OK) +// return -EAGAIN; +// __udelay(3000); +#endif + + + + +#if 0 + if(srv_open->config.preprocessor_info.configuration.transformId + == SVA_PREPROCESSOR_SENSOR_HIGHQUALITY_YUV420_MB){ + if((sva_err=irp_start_ewarp_hq(srv_open))!= 0){ + printk("irp_start_ewarp_hq failed with %d \n", sva_err); + return -1; + } + } +#endif + dbgprintk(1,"# IRP service started successfully \n"); + return 0; +} + +static int irp_start_fw(struct sva_service_open *srv_open, unsigned long framerate) +{ + u16 vpip_state; + sensor_type_t sensor_type; + int i; + t_sva_error sva_error=SVA_OK; + t_sva_preprocessor_configuration *pconf; + int vpip_update_iteration; + + //vpip_def_param[0][1] + //irp_sensor750_settings[0][0]=strtol(vpip_def_param[0][1],NULL,0); + //,3}; + + pconf = &srv_open->config.preprocessor_info.configuration; + + dbgprintk(1,"irp_start_fw has started with framerate=%ld, looking at current state\n",framerate); + sva_error = irp_read_packet(srv_open, vpip_default_params[ModeManagerStatus_bHiLevelState].addr, + &vpip_state); + if(sva_error !=SVA_OK){ + dbgprintk(3,"Failed to get the state of ewarp\n"); + return -1; + } + if(framerate == 0) + framerate =30; + + dbgprintk(1,"current state of vpip is 0x%x\n",vpip_state); + switch(vpip_state) { + case IRP_INIT_DONE: + /* only init is done, needs bootup */ + dbgprintk(1,"setting sensor settings \n"); + if(sva.sva_platform_data->sensor_init(IRP_CAMERA_SENSOR_CCP0)) { + dbgprintk(3,"Failed to initialize the sensor %d\n",IRP_CAMERA_SENSOR_CCP0); + return -EINVAL; + } + if(sva.sva_platform_data->sensor_gpio_init(IRP_CAMERA_SENSOR_CCP0)){ + dbgprintk(3,"error in allocating gpio pins \n"); + return -EAGAIN; + } + dbgprintk(1,"IRP only init is done, needs to booting\n"); + sva_error = irp_boot_ewarp(srv_open); + if(sva_error != SVA_OK) { + dbgprintk(3,"Failed to boot ewarp \n"); + return -EAGAIN; + } + break; + case IRP_RUNNING: + /* running, need to stop */ + dbgprintk(1,"IRP is presently in running state, needs to stop\n"); + sva_error = irp_stop_ewarp(srv_open); + if(sva_error != SVA_OK) { + dbgprintk(3,"Failed to stop ewarp fw\n"); + return -1; + } + + case IRP_STOPPED: + /* stopped, need to bring in running state */ + IRP_ASSERT(irp_write_packet(srv_open,vpip_default_params[PipeSetupBankA_uwPipeOutputSize_X_MSByte].addr,pconf->resizedWindowDesc.width)); + IRP_ASSERT(irp_write_packet(srv_open,vpip_default_params[PipeSetupBankA_uwPipeOutputSize_Y_MSByte].addr,pconf->resizedWindowDesc.height)); + IRP_ASSERT(irp_write_packet(srv_open, vpip_default_params[StaticFrameRateControl_uwDesiredFrameRate_Num_MSByte].addr,framerate)); + /* irp_write_packet(srv_open,Pipe0Control_fPipeRefreshRequired, 1); */ + + if(irp_write_packet(srv_open, vpip_default_params[HostInterfaceManagerControl_bUserCommand].addr,EWARP_START)!=SVA_OK) + return -EAGAIN; + __udelay(3000); + + sva_error = irp_read_packet(srv_open, vpip_default_params[HostInterfaceManagerStatus_bThisLoLevelState].addr, &vpip_state); + if(sva_error != SVA_OK) + return -EAGAIN; + + dbgprintk(1," Firmware HostInterfaceManagerStatus_bThisLoLevelState =%d state \n", vpip_state); + return 0; + case IRP_SLEEPING: + irp_power_up(srv_open); + + IRP_ASSERT(irp_read_packet(srv_open, vpip_default_params[HostInterfaceManagerStatus_bThisLoLevelState].addr, &vpip_state)); + dbgprintk(1,"Irp sleeping detected HostInterfaceManagerStatus_bThisLoLevelState=%d state\n",vpip_state); + break; + default: + dbgprintk(3,"Invalid state of firmware detected %d.\n", vpip_state); + return -EAGAIN; + } + + /* irp start sequence */ + irp_start_sequence[0][1] = pconf->resizedWindowDesc.width; + irp_start_sequence[1][1] = pconf->resizedWindowDesc.height; + dbgprintk(2,"starting sensor & IPP with size %dx%d at framerate=%ld\n", + pconf->resizedWindowDesc.width, pconf->resizedWindowDesc.height, framerate); + + /* read model id of ccp sensor type */ + IRP_ASSERT(irp_read_packet(srv_open, vpip_default_params[SensorInformation_uwFarSensorModelId_MSByte].addr, &vpip_state)); + dbgprintk(1,"status value at index SensorInformation_uwFarSensorModelId = %d \n", vpip_state); + sensor_type= vpip_state; + if(vpip_state != SENSOR_MODEL_ID_3MP_850 && vpip_state != SENSOR_MODEL_ID_2MP + && vpip_state!=SENSOR_MODEL_ID_3MP_851){ + dbgprintk(3," Far Sensor type =%d is not supported \n", vpip_state); + return -1; + } + + IRP_ASSERT(irp_read_packet(srv_open, vpip_default_params[SensorInformation_uwNearSensorModelId_MSByte].addr, &vpip_state)); + dbgprintk(1,"status value at index SensorInformation_uwNearSensorModelId = %d \n", vpip_state); + if(vpip_state != SENSOR_MODEL_ID_3MP_850 && vpip_state != SENSOR_MODEL_ID_2MP + && vpip_state!=SENSOR_MODEL_ID_3MP_851){ + dbgprintk(3," Near Sensor type =%d is not supported \n", vpip_state); + return -1; + } + + if(sensor_type==SENSOR_MODEL_ID_3MP_850 || sensor_type==SENSOR_MODEL_ID_3MP_851){ + dbgprintk(3," 3MegaPixel sensor has model id=%d \n", sensor_type); + IRP_ASSERT(irp_write_packet(srv_open,vpip_default_params[ModeSetupBank0_uwMinImageSize_X_MSByte].addr,88)); + IRP_ASSERT(irp_write_packet(srv_open,vpip_default_params[ModeSetupBank0_uwMinImageSize_Y_MSByte].addr,72)); + IRP_ASSERT(irp_write_packet(srv_open,vpip_default_params[ModeSetupBank0_fLowPowerStreaming].addr,0)); //false + IRP_ASSERT(irp_write_packet(srv_open,vpip_default_params[ModeSetupBank0_bTestMode].addr,0)); //disable + + /*sensor 851 specific init */ + IRP_ASSERT(irp_write_packet(srv_open,vpip_default_params[ColourEngine0_ApertureCorrectionControls_bMinimumCoringThreshold].addr,vpip_default_params[ColourEngine0_ApertureCorrectionControls_bMinimumCoringThreshold].val));//21)); + IRP_ASSERT(irp_write_packet(srv_open,vpip_default_params[ColourEngine0_ApertureCorrectionControls_bMaxGain].addr,vpip_default_params[ColourEngine0_ApertureCorrectionControls_bMaxGain].val));//21)); + IRP_ASSERT(irp_write_packet(srv_open,vpip_default_params[ScytheFilterControls_bMaxWeightLow].addr,vpip_default_params[ScytheFilterControls_bMaxWeightLow].val));//22)); + IRP_ASSERT(irp_write_packet(srv_open,vpip_default_params[ScytheFilterControls_bMaxWeightHigh].addr,vpip_default_params[ScytheFilterControls_bMaxWeightHigh].val));//22)); + IRP_ASSERT(irp_write_packet(srv_open,vpip_default_params[StaticFrameRateControl_uwDesiredFrameRate_Num_MSByte].addr,7)); + IRP_ASSERT(irp_write_packet(srv_open,vpip_default_params[ZoomMgrCtrl_fSetAlternateInitWOI].addr,vpip_default_params[ZoomMgrCtrl_fSetAlternateInitWOI].val));//0)); + IRP_ASSERT(irp_write_packet(srv_open,vpip_default_params[ZoomMgrCtrl_fChgOverForbidden].addr,vpip_default_params[ZoomMgrCtrl_fChgOverForbidden].val));//0)); + + IRP_ASSERT(irp_write_packet(srv_open,vpip_default_params[ColourEngine0_OutputCoderControls_TransformType].addr,vpip_default_params[ColourEngine0_OutputCoderControls_TransformType].val));//0)); + + //hq colour engine settings +/* IRP_ASSERT(irp_write_packet(srv_open,VideoTimingSensorConstraints_fpMaximumPllOutputFrequency_Mhz_LSByte,400)); + + IRP_ASSERT(irp_write_packet(srv_open,ColourEngine0_ColourMatrixNearSensor_fpRInR_MSByte,0x40cf)); + IRP_ASSERT(irp_write_packet(srv_open,ColourEngine0_ColourMatrixNearSensor_fpGInR_MSByte,0xbfae)); + IRP_ASSERT(irp_write_packet(srv_open,ColourEngine0_ColourMatrixNearSensor_fpBInR_MSByte,0x33d7)); + IRP_ASSERT(irp_write_packet(srv_open,ColourEngine0_ColourMatrixNearSensor_fpRInG_MSByte,0xba8e)); + IRP_ASSERT(irp_write_packet(srv_open,ColourEngine0_ColourMatrixNearSensor_fpGInG_MSByte,0x3fa4)); + IRP_ASSERT(irp_write_packet(srv_open,ColourEngine0_ColourMatrixNearSensor_fpBInG_MSByte,0xbc00)); + IRP_ASSERT(irp_write_packet(srv_open,ColourEngine0_ColourMatrixNearSensor_fpRInB_MSByte,0xb9d7)); + IRP_ASSERT(irp_write_packet(srv_open,ColourEngine0_ColourMatrixNearSensor_fpGInB_MSByte,0xbe14)); + IRP_ASSERT(irp_write_packet(srv_open,ColourEngine0_ColourMatrixNearSensor_fpBInB_MSByte,0x4048)); + + IRP_ASSERT(irp_write_packet(srv_open,ColourEngine0_CoderOutputSignalRange_uwChromaExcursion_LSByte,21)); + IRP_ASSERT(irp_write_packet(srv_open,ColourEngine0_CoderOutputSignalRange_uwChromaExcursion_MSByte,0)); +*/ + } + IRP_ASSERT(irp_read_packet(srv_open, vpip_default_params[SensorInformation_bFarSensorRevision].addr, &vpip_state)); + dbgprintk(2,"status value at index 0x1492 = %d \n", vpip_state); + + if(sensor_type == SENSOR_MODEL_ID_2MP) { + /* sensor 750 settings */ + dbgprintk(3,"2MPixel sensor has model id=%d\n", sensor_type); + for(i=0; i < sizeof(irp_sensor750_settings)/4; i++){ + IRP_ASSERT(irp_write_packet(srv_open, irp_sensor750_settings[i][0], + irp_sensor750_settings[i][1])); + } + IRP_ASSERT(irp_write_packet(srv_open, vpip_default_params[SensorCapabilitiesNearSensor_uwSensorAnalogGainMaximum_MSByte].addr,vpip_default_params[SensorCapabilitiesNearSensor_uwSensorAnalogGainMaximum_MSByte].val));//0x00f0)); + IRP_ASSERT(irp_write_packet(srv_open, vpip_default_params[SensorCapabilitiesFarSensor_uwSensorAnalogGainMaximum_MSByte].addr,vpip_default_params[SensorCapabilitiesFarSensor_uwSensorAnalogGainMaximum_MSByte].val));//0x00f0)); + } + IRP_ASSERT(irp_write_packet(srv_open, vpip_default_params[ColourEngine0_FadeToBlack_fDisable].addr,1)); + IRP_ASSERT(irp_write_packet(srv_open, vpip_default_params[AutomaticFrameRateControl_bMode].addr,vpip_default_params[AutomaticFrameRateControl_bMode].val));//0)); + IRP_ASSERT(irp_write_packet(srv_open, vpip_default_params[ZoomMgrCtrl_fChgOverForbidden].addr,vpip_default_params[ZoomMgrCtrl_fChgOverForbidden].val));//0)); + + /* near sensor present */ + for(i=0; i < sizeof(mode_setup_bank0)/4; i++){ + IRP_ASSERT(irp_write_packet(srv_open, mode_setup_bank0[i][0], + mode_setup_bank0[i][1])); + } + __udelay(3000); + /* pipesetup bank */ + for(i=0; i < sizeof(irp_start_sequence)/4; i++){ + IRP_ASSERT(irp_write_packet(srv_open, irp_start_sequence[i][0], + irp_start_sequence[i][1])); + } + + if(sensor_type==SENSOR_MODEL_ID_3MP_850 || sensor_type==SENSOR_MODEL_ID_3MP_851){ + /* reconfigure sensor settings for 3mpl */ + dbgprintk(2,"reconfiguring 3mpl sensor \n"); + //IRP_ASSERT(irp_write_packet(srv_open, ModeSetupBank0_uwInputImageSize_X_MSByte,2048+8)); + //IRP_ASSERT(irp_write_packet(srv_open, ModeSetupBank0_uwInputImageSize_Y_MSByte,1536+8)); + + IRP_ASSERT(irp_write_packet(srv_open, vpip_default_params[ModeSetupBank0_uwInputImageSize_X_MSByte].addr,srv_open->config.preprocessor_info.sensor_aoi_x +8)); + IRP_ASSERT(irp_write_packet(srv_open, vpip_default_params[ModeSetupBank0_uwInputImageSize_Y_MSByte].addr,srv_open->config.preprocessor_info.sensor_aoi_y+8)); + + + + IRP_ASSERT(irp_write_packet(srv_open, vpip_default_params[ModeSetupBank0_uwMaxImageSize_X_MSByte].addr,2048)); + IRP_ASSERT(irp_write_packet(srv_open, vpip_default_params[ModeSetupBank0_uwMaxImageSize_Y_MSByte].addr,1536)); + if(srv_open->config.preprocessor_info.configuration.transformId + == SVA_PREPROCESSOR_SENSOR_HIGHQUALITY_YUV420_MB){ + dbgprintk(2,"Grab_HQ has outputImage destination as RAM \n"); +//850/851 viewfinder stucks + IRP_ASSERT(irp_write_packet(srv_open, vpip_default_params[ModeSetupBank0_bOutputImageDestination].addr,1)); //OutputImageDestination_RAM + IRP_ASSERT(irp_write_packet(srv_open, vpip_default_params[ModeSetupBank0_bInputImageSource].addr,vpip_default_params[ModeSetupBank0_bInputImageSource].val));//0));//InputImageSource_Sensor + IRP_ASSERT(irp_write_packet(srv_open, vpip_default_params[AntiVignetteControlsFar_fDisableFilter].addr,vpip_default_params[AntiVignetteControlsFar_fDisableFilter].val));//1)); + IRP_ASSERT(irp_write_packet(srv_open, vpip_default_params[AntiVignetteControlsNear_fDisableFilter].addr,vpip_default_params[AntiVignetteControlsNear_fDisableFilter].val));//1)); + IRP_ASSERT(irp_write_packet(srv_open, vpip_default_params[RunModeControl_bStreamLength].addr,1)); //conflict 2mpl + } + + IRP_ASSERT(irp_write_packet(srv_open, vpip_default_params[PipeSetupBankA_uwPipeOutputSize_X_MSByte].addr,2048)); + IRP_ASSERT(irp_write_packet(srv_open, vpip_default_params[PipeSetupBankA_uwPipeOutputSize_Y_MSByte].addr,1536)); + IRP_ASSERT(irp_write_packet(srv_open, vpip_default_params[PipeSetupBankA_bPipeOutputFormat].addr,vpip_default_params[PipeSetupBankA_bPipeOutputFormat].val));//3));//yuv + + IRP_ASSERT(irp_write_packet(srv_open, vpip_default_params[ZoomMgrParams_bPrescaleType].addr,srv_open->config.preprocessor_info.prescale_factor));//no prescale + IRP_ASSERT(irp_write_packet(srv_open, vpip_default_params[VfpnControls_fEnableCorrection].addr,0)); + IRP_ASSERT(irp_write_packet(srv_open, vpip_default_params[AntiFlickerExposureControls_fGuaranteeStaticFlickerFrameLength].addr,vpip_default_params[AntiFlickerExposureControls_fGuaranteeStaticFlickerFrameLength].val));//0)); + + IRP_ASSERT(irp_write_packet(srv_open, vpip_default_params[JackFilterControls_fDisablePromotingLow].addr,vpip_default_params[JackFilterControls_fDisablePromotingLow].val));//1)); + IRP_ASSERT(irp_write_packet(srv_open, vpip_default_params[JackFilterControls_fDisablePromotingHigh].addr,vpip_default_params[JackFilterControls_fDisablePromotingHigh].val));//1)); + IRP_ASSERT(irp_write_packet(srv_open, vpip_default_params[JackFilterControls_bMaxWeightLow].addr,vpip_default_params[JackFilterControls_bMaxWeightLow].val));//5)); + IRP_ASSERT(irp_write_packet(srv_open, vpip_default_params[JackFilterControls_bMaxWeightHigh].addr,vpip_default_params[JackFilterControls_bMaxWeightHigh].val));//5)); + + IRP_ASSERT(irp_write_packet(srv_open, vpip_default_params[NoraControls_fDisableNoraPromoting].addr,vpip_default_params[NoraControls_fDisableNoraPromoting].val));//1)); + IRP_ASSERT(irp_write_packet(srv_open, vpip_default_params[NoraControls_bMaximumValue].addr,vpip_default_params[NoraControls_bMaximumValue].val));//0)); + IRP_ASSERT(irp_write_packet(srv_open, vpip_default_params[ScytheFilterControls_fDisablePromotingLow].addr,vpip_default_params[ScytheFilterControls_fDisablePromotingLow].val));//1)); + IRP_ASSERT(irp_write_packet(srv_open, vpip_default_params[ScytheFilterControls_fDisablePromotingHigh].addr,vpip_default_params[ScytheFilterControls_fDisablePromotingHigh].addr));//1)); + IRP_ASSERT(irp_write_packet(srv_open, vpip_default_params[ZoomMgrCtrl_bMagFactor].addr,vpip_default_params[ZoomMgrCtrl_bMagFactor].val));//10)); + IRP_ASSERT(irp_write_packet(srv_open, vpip_default_params[WhiteBalanceControls_bMode].addr,vpip_default_params[WhiteBalanceControls_bMode].val));//1)); + IRP_ASSERT(irp_write_packet(srv_open, vpip_default_params[MinWeightedWBControls_fDisable].addr,vpip_default_params[MinWeightedWBControls_fDisable].val));//1)); + IRP_ASSERT(irp_write_packet(srv_open, vpip_default_params[FlashManagerControl_bMode].addr,vpip_default_params[FlashManagerControl_bMode].val));//0)); + IRP_ASSERT(irp_write_packet(srv_open, vpip_default_params[NoraControls_fDisable].addr,vpip_default_params[NoraControls_fDisable].val));//0)); + IRP_ASSERT(irp_write_packet(srv_open, vpip_default_params[ScytheFilterControls_fDisableFilter].addr,vpip_default_params[ScytheFilterControls_fDisableFilter].val));//0)); + IRP_ASSERT(irp_write_packet(srv_open, vpip_default_params[JackFilterControls_fDisableFilter].addr,vpip_default_params[JackFilterControls_fDisableFilter].val));//0)); + IRP_ASSERT(irp_write_packet(srv_open, vpip_default_params[AntiVignetteControls_fDisableFilter].addr,vpip_default_params[AntiVignetteControls_fDisableFilter].val));//0)); + IRP_ASSERT(irp_write_packet(srv_open, vpip_default_params[ColourEngine0_RadialApertureCorrectionControl_fEnableCorrection].addr,vpip_default_params[ColourEngine0_RadialApertureCorrectionControl_fEnableCorrection].val));//1)); + IRP_ASSERT(irp_write_packet(srv_open, vpip_default_params[ColourEngine0_ColourMatrixDamperControl_fDisableMatrixDamping].addr,vpip_default_params[ColourEngine0_ColourMatrixDamperControl_fDisableMatrixDamping].val));//1)); + IRP_ASSERT(irp_write_packet(srv_open, vpip_default_params[ColourEngine0_ApertureCorrectionControls_fDisableCorrection].addr,vpip_default_params[ColourEngine0_ApertureCorrectionControls_fDisableCorrection].val));//1)); + IRP_ASSERT(irp_write_packet(srv_open, vpip_default_params[ColourEngine0_ApertureCorrectionControls_fDisableCoringDamping].addr,vpip_default_params[ColourEngine0_ApertureCorrectionControls_fDisableCoringDamping].val));//1)); + IRP_ASSERT(irp_write_packet(srv_open, vpip_default_params[ColourEngine0_ApertureCorrectionControls_fDisableGainDamping].addr,vpip_default_params[ColourEngine0_ApertureCorrectionControls_fDisableGainDamping].val));//1)); +/* + IRP_ASSERT(irp_write_packet(srv_open, ColourEngine0_GammaCorrection_SharpRed,16)); + IRP_ASSERT(irp_write_packet(srv_open, ColourEngine0_GammaCorrection_SharpGreen,16)); + IRP_ASSERT(irp_write_packet(srv_open, ColourEngine0_GammaCorrection_SharpBlue,16)); + IRP_ASSERT(irp_write_packet(srv_open, ColourEngine0_GammaCorrection_SoftRed,16)); + IRP_ASSERT(irp_write_packet(srv_open, ColourEngine0_GammaCorrection_SoftGreen,16)); + IRP_ASSERT(irp_write_packet(srv_open, ColourEngine0_GammaCorrection_SoftBlue,16)); +*/ + } + + IRP_ASSERT(irp_write_packet(srv_open, vpip_default_params[ModeSetupBank0_bActiveSensor].addr,0x2)); + IRP_ASSERT(irp_write_packet(srv_open, vpip_default_params[ModeSetupBank1_bActiveSensor].addr,0x2)); + IRP_ASSERT(irp_write_packet(srv_open, vpip_default_params[ModeSetupBank2_bActiveSensor].addr,0x2)); + IRP_ASSERT(irp_write_packet(srv_open, vpip_default_params[ModeSetupBank3_bActiveSensor].addr,0x2)); + IRP_ASSERT(irp_write_packet(srv_open, vpip_default_params[ModeSetupBankSelector_bRequiredModeSetupBank].addr,vpip_default_params[ModeSetupBankSelector_bRequiredModeSetupBank].val));//0)); + + /* prepare vpip */ + IRP_ASSERT(irp_write_packet(srv_open,vpip_default_params[HostInterfaceManagerControl_bUserCommand].addr, EWARP_PREPARE)); + /* check if prepared */ + IRP_ASSERT(irp_read_packet(srv_open, vpip_default_params[ModeManagerStatus_bThisLoLevelState].addr, &vpip_state)); + if(vpip_state != 0x33) + dbgprintk(2,"warning, firmware state=%d is not prepared yet ...\n",vpip_state); + + + IRP_ASSERT(irp_write_packet(srv_open, vpip_default_params[PipeSetupBankA_uwPipeOutputSize_X_MSByte].addr, pconf->resizedWindowDesc.width)); + IRP_ASSERT(irp_write_packet(srv_open, vpip_default_params[PipeSetupBankA_uwPipeOutputSize_Y_MSByte].addr, pconf->resizedWindowDesc.height)); + + IRP_ASSERT(irp_write_packet(srv_open, vpip_default_params[StaticFrameRateControl_bDesiredFrameRate_Den].addr,vpip_default_params[StaticFrameRateControl_bDesiredFrameRate_Den].val));//0x01)); //FrameRate Den + IRP_ASSERT(irp_write_packet(srv_open, vpip_default_params[StaticFrameRateControl_uwDesiredFrameRate_Num_MSByte].addr,framerate));//FrameRate Num + + IRP_ASSERT(irp_write_packet(srv_open, vpip_default_params[WhiteBalanceControls_bMode].addr,vpip_default_params[WhiteBalanceControls_bMode].val));// 1)); + + IRP_ASSERT(irp_write_packet(srv_open,vpip_default_params[PipeSetupBankSelector_bRequiredPipe0SetupBank].addr,vpip_default_params[PipeSetupBankSelector_bRequiredPipe0SetupBank].val));//0)); + IRP_ASSERT(irp_write_packet(srv_open, vpip_default_params[ColourEngine0_OutputCoderControls_bContrast].addr,vpip_default_params[ColourEngine0_OutputCoderControls_bContrast].val));// 0x64)); + IRP_ASSERT(irp_write_packet(srv_open, vpip_default_params[ColourEngine0_OutputCoderControls_bColourSaturation].addr,vpip_default_params[ColourEngine0_OutputCoderControls_bColourSaturation].val));// 0x64)); + IRP_ASSERT(irp_write_packet(srv_open, vpip_default_params[VfpnControls_uwMaximumPixelValue_MSByte].addr, 0x3ff)); + + IRP_ASSERT(irp_write_packet(srv_open, vpip_default_params[ExposureControls_bMode].addr, vpip_default_params[ExposureControls_bMode].val));//0)); //green channel off + if(sensor_type==SENSOR_MODEL_ID_2MP){ + IRP_ASSERT(irp_write_packet(srv_open, vpip_default_params[VfpnControls_fEnableCorrection].addr, 1)); + IRP_ASSERT(irp_write_packet(srv_open, vpip_default_params[AntiFlickerExposureControls_fGuaranteeStaticFlickerFrameLength].addr,1)); + IRP_ASSERT(irp_write_packet(srv_open, vpip_default_params[ColourEngine0_RadialApertureCorrectionControl_fEnableCorrection].addr,0)); + /* ? FIXME: it throughs error if written */ + IRP_ASSERT(irp_write_packet(srv_open,vpip_default_params[ModeSetupBank0_bOutputImageDestination].addr,0)); // output to pixel pipe + } + IRP_ASSERT(irp_write_packet(srv_open, vpip_default_params[VfpnControls_uwMinimumPixelValue_MSByte].addr,vpip_default_params[VfpnControls_uwMinimumPixelValue_MSByte].val));// 0)); + IRP_ASSERT(irp_write_packet(srv_open, vpip_default_params[VfpnControls_uwPixelSaturationLevel_MSByte].addr,vpip_default_params[VfpnControls_uwPixelSaturationLevel_MSByte].val));// 0x3ff)); + IRP_ASSERT(irp_write_packet(srv_open, vpip_default_params[VfpnControls_bLogThreshLog].addr,vpip_default_params[VfpnControls_bLogThreshLog].val));// 0x4)); + IRP_ASSERT(irp_write_packet(srv_open, vpip_default_params[AntiFlickerExposureControls_bMainsFrequency_Hz].addr,vpip_default_params[AntiFlickerExposureControls_bMainsFrequency_Hz].val));// 0x32)); + + + + for(vpip_update_iteration=0;vpip_update_iteration<2207;vpip_update_iteration++){//1836 + + + switch (vpip_update_iteration) { + + /* these are control register has to be update during ewarp boot only + case SystemConfiguration_fNearSensorPresent : + case SystemConfiguration_fFarSensorPresent : + case SystemConfiguration_CcpRxForNearSensor : + case SystemConfiguration_CcpRxForFarSensor : + case SystemConfiguration_uwExternalClockFrequency_Mhz_num_MSByte : + case SystemConfiguration_bExternalClockFrequency_Mhz_den : + case MasterI2cControl_uwRequiredI2cSpeed_MSByte : + case MiscPageElements_bDelayAfterSettingXshutdown : + case MiscPageElements_fConvertMultiByteReadsIntoSingleByte : + case ModeSetupBank0_bActiveSensor : + case ModeSetupBank1_bActiveSensor : + case VideoTimingInputsNearSensor_VideoTimingMode : + case VideoTimingInputsNearSensor_fpHostRxMaxDataRate_Mbps_MSByte : + case VideoTimingInputsNearSensor_uwCsiRawFormat_MSByte : + case VideoTimingInputsNearSensor_bSensorBitsPerSystemClock : + case VideoTimingInputsFarSensor_VideoTimingMode : + case VideoTimingInputsFarSensor_fpHostRxMaxDataRate_Mbps_MSByte : + case VideoTimingInputsFarSensor_uwCsiRawFormat_MSByte : + case VideoTimingInputsFarSensor_bSensorBitsPerSystemClock : + case VideoTimingHostInputs_VideoTimingMode : + case VideoTimingHostInputs_bSensorBitsPerSystemClock : + case VideoTimingHostInputs_uwCsiRawFormat_MSByte : + case VideoTimingHostInputs_fpHostRxMaxDataRate_Mbps_MSByte : + case SystemConfiguration_fFocusLensActuatorOnSensorNearPresent : + case SystemConfiguration_fFocusLensActuatorOnSensorFarPresent : + case FLADriverLowLevelParameters_AutoSkipNextFrame : + case FLADriverLowLevelParameters_bMaxNumberRetries : + case FLADriverLowLevelParameters_fOverwriteLowLevelLimits : + case FLADriverLowLevelParameters_fLowLevelDriverInitialized : + case BinningControl_fEnableBinning : + case PipeSetupBankA_uwPipeOutputSize_X_MSByte : + case PipeSetupBankA_uwPipeOutputSize_Y_MSByte : + case PipeSetupBankA_bPipeOutputFormat : + case PipeSetupBankA_bPipeStreamLength : + case PipeSetupBankA_fTogglePixValid : + case PipeSetupBankA_fEnableItuEmbeddedCodes : + case PipeSetupBankA_bPixValidLineTypes : + case PipeSetupBankA_fGenerateVSync : + case PipeSetupBankA_fCb_Cr_Flip : + case PipeSetupBankA_fY_CbCr_Flip : + case StaticFrameRateControl_uwDesiredFrameRate_Num_MSByte : + case RunModeControl_fMeteringOn : + case RunModeControl_bStreamLength : + case HostToSensorAccessControl_bRequest: + case HostToSensorAccessControl_uwSensorIndex_MSByte: + case HostToSensorAccessData_uwDataLow_LSByte: + case HostToSensorAccessControl_bCommandCoin: + printk("not written val of i: %d\n",vpip_update_iteration); + + break; + */ + + /** + Update only configuration registers + */ + case PipeSetupBankB_fCb_Cr_Flip : + + case PipeSetupBankB_fY_CbCr_Flip : + case Pipe0Control_fSfxSolariseEnabled : + case Pipe0Control_fSfxNegativeEnabled : + case Pipe0Control_ReplaceRedChannel : + case Pipe0Control_ReplaceGreenChannel : + case Pipe0Control_ReplaceBlueChannel : + + case SensorCapabilitiesFarSensor_uwSensorAnalogGainMinimum_MSByte : + case SensorCapabilitiesFarSensor_uwSensorAnalogGainMaximum_MSByte : + case SensorCapabilitiesFarSensor_uwSensorDataPedestal_MSByte : + case SensorCapabilitiesCurrentSensor_uwSensorAnalogGainMinimum_MSByte : + case SensorCapabilitiesCurrentSensor_uwSensorAnalogGainMaximum_MSByte : + case FlashManagerControl_bMode : + case FlashManagerControl_bFlashType : + case FlashManagerControl_fOrMainAndPreFlashPulse : + case FlashManagerControl_RefPointCalcMode : + case FlashManagerControl_wIntegrationStartPosition_MSByte : + case FlashManagerControl_fOverrideIntegrationStartPosition : + case FlashManagerControl_fpFlashFiringDelay_us_MSByte : + case FlashManagerControl_bNumberOfPreFlashes : + case FlashManagerControl_fpPulseWidthMainFlash_us_MSByte : + case FlashManagerControl_fpPulseWidthPreFlash_us_MSByte : + case FlashManagerControl_fpTimeBetweenTwoPreFlashes_us_MSByte : + case FlashManagerControl_fpTimeBetweenPreFlashAndMainFlash_us_MSByte : + case FlashManagerControl_cMainFlashStartFrame : + case FlashManagerControl_wMainFlashStartLine_MSByte : + case FlashManagerControl_wMainFlashStartPixel_MSByte : + case FlashManagerControl_cPreFlashStartFrame : + case FlashManagerControl_wPreFlashStartLine_MSByte : + case FlashManagerControl_wPreFlashStartPixel_MSByte : + + + case FlashManagerControl_bTotalFramesRequired : + case ExposureControls_bMode : + case ExposureControls_bMetering : + case ExposureControls_fpColdStartDesiredTime_us_MSByte : + case ExposureControls_iExposureCompensation : + case ExposureControls_bMiscSettings : + case ExposureControls_fpDirectModeDigitalGain_MSByte : + case ExposureControls_uwFlashGunModeCoarseIntegration_lines_MSByte : + case ExposureControls_uwFlashGunModeFineIntegration_pixels_MSByte : + case ExposureControls_uwFlashGunModeCodedAnalogGain_MSByte : + case ExposureControls_fpFlashGunModeDigitalGain_MSByte : + case ExposureControls_fFreezeAutoExposure : + case ExposureControls_fpUserMaximumIntegrationTime_us_MSByte : + case ExposureControls_fpRecommendFlashGunAnalogGainThreshold_MSByte : + case ExposureControls_fEnableHighClipForDesiredExposureTime : + case ExposureControls_bAntiFlickerMode : + case ExposureControls_fInhibitExposurePresetModeForFlash : + case ExposureAlgorithmControls_fpDigitalGainFloor_MSByte : + case ExposureAlgorithmControls_fpDigitalGainCeiling_MSByte : + case WhiteBalanceControls_bMode : + case WhiteBalanceControls_bManualRedGain : + case WhiteBalanceControls_bManualGreenGain : + case WhiteBalanceControls_bManualBlueGain : + case WhiteBalanceControls_bMiscSettings : + case WhiteBalanceControls_fpFlashRedGain_MSByte : + case WhiteBalanceControls_fpFlashGreenGain_MSByte : + case WhiteBalanceControls_fpFlashBlueGain_MSByte : + case WhiteBalanceControls_fInhibitWhiteBalancePresetModeForFlash : + case WhiteBalanceStatisticsControls_bLowThreshold : + case MinWeightedWBControls_fDisable : + case MinWeightedWBControls_uwSaturationThreshold_MSByte : + case MinWeightedWBControls_fpRedTiltGain_MSByte : + case MinWeightedWBControls_fpGreen1TiltGain_MSByte : + case MinWeightedWBControls_fpGreen2TiltGain_MSByte : + case MinWeightedWBControls_fpBlueTiltGain_MSByte : + case MinWeightedWBControls_GreenChannelToAccumulate : + case AutomaticFrameRateControl_bMode : + case AutomaticFrameRateControl_bImpliedGainThresholdLow_num : + case AutomaticFrameRateControl_bImpliedGainThresholdLow_den : + case AutomaticFrameRateControl_bImpliedGainThresholdHigh_num : + case AutomaticFrameRateControl_bImpliedGainThresholdHigh_den : + case AutomaticFrameRateControl_bUserMinimumFrameRate_Hz : + case AutomaticFrameRateControl_bUserMaximumFrameRate_Hz : + case AutomaticFrameRateControl_bRelativeChange_num : + case AutomaticFrameRateControl_bRelativeChange_den : + case AutomaticFrameRateControl_fDivorceMinFrameRateFromMaxIntegration : + + + case StaticFrameRateControl_bDesiredFrameRate_Den : + case ColourEngine0_ColourMatrixFarSensor_fpRInR_MSByte : + case ColourEngine0_ColourMatrixFarSensor_fpGInR_MSByte : + case ColourEngine0_ColourMatrixFarSensor_fpBInR_MSByte : + case ColourEngine0_ColourMatrixFarSensor_fpRInG_MSByte : + case ColourEngine0_ColourMatrixFarSensor_fpGInG_MSByte : + case ColourEngine0_ColourMatrixFarSensor_fpBInG_MSByte : + case ColourEngine0_ColourMatrixFarSensor_fpRInB_MSByte : + case ColourEngine0_ColourMatrixFarSensor_fpGInB_MSByte : + case ColourEngine0_ColourMatrixFarSensor_fpBInB_MSByte : + case ColourEngine1_ColourMatrixFarSensor_fpRInR_MSByte : + case ColourEngine1_ColourMatrixFarSensor_fpGInR_MSByte : + case ColourEngine1_ColourMatrixFarSensor_fpBInR_MSByte : + case ColourEngine1_ColourMatrixFarSensor_fpRInG_MSByte : + case ColourEngine1_ColourMatrixFarSensor_fpGInG_MSByte : + case ColourEngine1_ColourMatrixFarSensor_fpBInG_MSByte : + case ColourEngine1_ColourMatrixFarSensor_fpRInB_MSByte : + case ColourEngine1_ColourMatrixFarSensor_fpGInB_MSByte : + case ColourEngine1_ColourMatrixFarSensor_fpBInB_MSByte : + case ColourEngine0_ColourMatrixDamperControl_fDisableMatrixDamping : + case ColourEngine0_ColourMatrixDamperControl_DamperLowThreshold_MSByte : + case ColourEngine0_ColourMatrixDamperControl_DamperHighThreshold_MSByte : + case ColourEngine0_ColourMatrixDamperControl_MinimumDamperOutput_MSByte : + case ColourEngine0_ApertureCorrectionControls_fDisableCorrection : + case ColourEngine0_ApertureCorrectionControls_bMaxGain : + case ColourEngine0_ApertureCorrectionControls_fDisableGainDamping : + case ColourEngine0_ApertureCorrectionControls_DamperLowThreshold_Gain_MSByte : + case ColourEngine0_ApertureCorrectionControls_DamperHighThreshold_Gain_MSByte : + case ColourEngine0_ApertureCorrectionControls_MinimumDamperOutput_Gain_MSByte : + case ColourEngine0_ApertureCorrectionControls_bMinimumCoringThreshold : + case ColourEngine0_ApertureCorrectionControls_fDisableCoringDamping : + case ColourEngine0_ApertureCorrectionControls_bMinimumHighThreshold : + case ColourEngine0_ApertureCorrectionControls_DamperLowThreshold_Coring_MSByte : + case ColourEngine0_ApertureCorrectionControls_DamperHighThreshold_Coring_MSByte : + case ColourEngine0_ApertureCorrectionControls_MinimumDamperOutput_Coring_MSByte : + case ColourEngine0_GammaCorrection_fEnabled : + case ColourEngine0_GammaCorrection_bMode : + case ColourEngine0_GammaCorrection_SharpRed : + case ColourEngine0_GammaCorrection_SharpGreen : + case ColourEngine0_GammaCorrection_SharpBlue : + case ColourEngine0_GammaCorrection_SoftRed : + case ColourEngine0_GammaCorrection_SoftGreen : + case ColourEngine0_GammaCorrection_SoftBlue : + + case NoraControls_fDisable : + case NoraControls_fDisableNoraPromoting : + case NoraControls_bMaximumValue : + case NoraControls_fDifferentTextureDegreeForBlue : + case NoraControls_fSplitNoiseLevel : + case NoraControls_fTightGreenMatrix : + case NoraControls_DamperLowThreshold_MSByte : + case NoraControls_DamperHighThreshold_MSByte : + case NoraControls_MinimumDamperOutput_MSByte : + case ScytheFilterControls_fDisableFilter : + case ScytheFilterControls_fSquareLaw : + case ScytheFilterControls_fDisablePromotingLow : + case ScytheFilterControls_fDisablePromotingHigh : + case ScytheFilterControls_bMaxWeightLow : + case ScytheFilterControls_bMaxWeightHigh : + case ScytheFilterControls_fpDamperLowThresholdLow_MSByte : + case ScytheFilterControls_fpDamperLowThresholdHigh_MSByte : + case ScytheFilterControls_fpDamperHighThresholdLow_MSByte : + case ScytheFilterControls_fpDamperHighThresholdHigh_MSByte : + case ScytheFilterControls_fpMinimumDamperOutputLow_MSByte : + case ScytheFilterControls_fpMinimumDamperOutputHigh_MSByte : + case JackFilterControls_fDisableFilter : + case JackFilterControls_fSquareLaw : + case JackFilterControls_fDisablePromotingLow : + case JackFilterControls_fDisablePromotingHigh : + case JackFilterControls_bMaxWeightLow : + case JackFilterControls_bMaxWeightHigh : + case JackFilterControls_fpDamperLowThresholdLow_MSByte : + case JackFilterControls_fpDamperLowThresholdHigh_MSByte : + case JackFilterControls_fpDamperHighThresholdLow_MSByte : + case JackFilterControls_fpDamperHighThresholdHigh_MSByte : + case JackFilterControls_fpMinimumDamperOutputLow_MSByte : + case JackFilterControls_fpMinimumDamperOutputHigh_MSByte : + case AntiVignetteControls_fDisableFilter : + case AntiVignetteControls_bFilterCoeff_R2_r : + case AntiVignetteControls_bFilterCoeff_R2_gr : + case AntiVignetteControls_bFilterCoeff_R2_gb : + case AntiVignetteControls_bFilterCoeff_R2_b : + case AntiVignetteControls_bFilterCoeff_R4_r : + case AntiVignetteControls_bFilterCoeff_R4_gr : + case AntiVignetteControls_bFilterCoeff_R4_gb : + case AntiVignetteControls_bFilterCoeff_R4_b : + case AntiVignetteControls_uwHorizontalOffset_MSByte : + case AntiVignetteControls_uwVerticalOffset_MSByte : + case AntiVignetteControls_fAVOffsetSeperateFor4Channels : + case AntiVignetteControls_bShiftFix_R2 : + case AntiVignetteControls_uwHorizontalOffset_r_MSByte : + case AntiVignetteControls_uwHorizontalOffset_gr_MSByte : + case AntiVignetteControls_uwHorizontalOffset_gb_MSByte : + case AntiVignetteControls_uwHorizontalOffset_b_MSByte : + case AntiVignetteControls_uwVerticalOffset_r_MSByte : + case AntiVignetteControls_uwVerticalOffset_gr_MSByte : + case AntiVignetteControls_uwVerticalOffset_gb_MSByte : + case AntiVignetteControls_uwVerticalOffset_b_MSByte : + case AntiVignetteControls_bUnityOffset_r : + case AntiVignetteControls_bUnityOffset_gr : + case AntiVignetteControls_bUnityOffset_gb : + case AntiVignetteControls_bUnityOffset_b : + case AntiVignetteControls_fAdaptiveAntiVignetteEnable : + case ColourEngine0_RadialApertureCorrectionControl_fEnableCorrection : + case ColourEngine0_RadialApertureCorrectionHostInputs_bQvec0 : + case ColourEngine0_RadialApertureCorrectionHostInputs_bQvec1 : + case ColourEngine0_RadialApertureCorrectionHostInputs_bCofShift : + case ColourEngine0_RadialApertureCorrectionHostInputs_bOutShift : + case ColourEngine0_RadialApertureCorrectionHostInputs_uwUnity_MSByte : + case ColourEngine0_OutputCoderControls_TransformType : + case ColourEngine0_OutputCoderControls_bContrast : + case ColourEngine0_OutputCoderControls_bColourSaturation : + case ColourEngine0_CoderOutputSignalRange_uwLumaExcursion_MSByte : + case ColourEngine0_CoderOutputSignalRange_uwLumaMidpointTimes2_MSByte : + case ColourEngine0_CoderOutputSignalRange_uwChromaExcursion_MSByte : + case ColourEngine0_CoderOutputSignalRange_uwChromaMidpointTimes2_MSByte : + case ColourEngine0_FadeToBlack_fDisable : + case ColourEngine0_FadeToBlack_fpBlackValue_MSByte : + case ColourEngine0_FadeToBlack_fpDamperLowThreshold_MSByte : + case ColourEngine0_FadeToBlack_fpDamperHighThreshold_MSByte : + case WhiteBalanceConstrainerControls_fpRedB_MSByte : + case WhiteBalanceConstrainerControls_fpBlueB_MSByte : + case WhiteBalanceConstrainerControls_fpMaximumDistanceAllowedFromLocus_MSByte : + case WhiteBalanceConstrainerControls_fEnableConstrainedWhiteBalance : + case WhiteBalanceGainLimit_fpWhiteBalanceGainLimit_MSByte : + case FLADriverLowLevelParameters_bFramesToSkip : + + case FocusRangeConstants_wFullRange_LensMinPosition_MSByte : + case FocusRangeConstants_wFullRange_LensMaxPosition_MSByte : + case FocusRangeConstants_wFullRange_LensRecoveryPosition_MSByte : + case FocusRangeConstants_wLandscape_LensMinPosition_MSByte : + case FocusRangeConstants_wLandscape_LensMaxPosition_MSByte : + case FocusRangeConstants_wLandscape_LensRecoveryPosition_MSByte : + case FocusRangeConstants_wMacro_LensMinPosition_MSByte : + case FocusRangeConstants_wMacro_LensMaxPosition_MSByte : + case FocusRangeConstants_wMacro_LensRecoveryPosition_MSByte : + case AutoFocusControls_fFMTesting_AutoDisable : + case AutoFocusControls_fBackLight_Enable : + case AutoFocusControls_fBackupSolution : + case AutoFocusControls_fCheckExposureStable_Enable : + case AutoFocusControls_fEnableSimpleCoarseThEvaluation : + case AutoFocusControls_bSelectedMultizoneBehavior : + case AutoFocusControls_bBackLightMethodSelected : + case AutoFocusControls_bWeighedFunctionSelected : + case AutoFocusControls_fMotionBlurEnable : + case AutoFocusControls_fLightVariationEnable : + case AutoFocusControls_fEnableTrackingThresholdEvaluation : + case AutoFocusControls_fEnableHeuristicMethod : + case AutoFocusControls_fEnableBackupSolution : + case AutoFocusControls_fFineToCoarseAutoTransitionEnable : + case AutoFocusControls_fEnableTimedFineExecution : + case AutoFocusControls_fEnableTrakingZoneVariation : + case AutoFocusControls_fEnableFunctionThresholdTest : + case AutoFocusControls_fResetHCSPos : + case AutoFocusConstants_bCoarseStep : + case AutoFocusConstants_bFineStep : + case ToshibaTechnicalParamTuner_uwDefAFMaxStandardRange_um_MSByte : + case ToshibaTechnicalParamTuner_bDefFineStepParam_um : + case ToshibaTechnicalParamTuner_bDefCoarseStepParam_um : + case ToshibaTechnicalParamTuner_fHostDefTechParam : + case SensorSetupFarSensor_uwGuaranteedDataSaturationLevel_MSByte : + case SensorSetupFarSensor_uwMinimumSensorRxPixelValue_MSByte : + case SensorSetupFarSensor_uwMaximumSensorRxPixelValue_MSByte : + case SensorSetupFarSensor_fpRedTiltGain_MSByte : + case SensorSetupFarSensor_fpGreenTiltGain_MSByte : + case SensorSetupFarSensor_fpBlueTiltGain_MSByte : + case SensorSetupFarSensor_BlackCorrectionOffset : + case ReferenceIlluminantCasts_fpCAST0_MSByte : + case ReferenceIlluminantCasts_fpCAST1_MSByte : + case ReferenceIlluminantCasts_fpCAST2_MSByte : + case ReferenceIlluminantCasts_fpCAST3_MSByte : + case AdaptiveAVParameter_B_bAvUnityOffset_Day : + case AdaptiveAVParameter_B_bAvCoeffR2_Day : + case AdaptiveAVParameter_B_bAvCoeffR4_Day : + case AdaptiveAVParameter_B_wAvHOffset_Day_MSByte : + case AdaptiveAVParameter_B_wAvVOffset_Day_MSByte : + case AdaptiveAVParameter_B_bAvUnityOffset_COO : + case AdaptiveAVParameter_B_bAvCoeffR2_COO : + case AdaptiveAVParameter_B_bAvCoeffR4_COO : + case AdaptiveAVParameter_B_wAvHOffset_COO_MSByte : + case AdaptiveAVParameter_B_wAvVOffset_COO_MSByte : + case AdaptiveAVParameter_B_bAvUnityOffset_INC : + case AdaptiveAVParameter_B_bAvCoeffR2_INC : + case AdaptiveAVParameter_B_bAvCoeffR4_INC : + case AdaptiveAVParameter_B_wAvHOffset_INC_MSByte : + case AdaptiveAVParameter_B_wAvVOffset_INC_MSByte : + case AdaptiveAVParameter_B_bAvUnityOffset_HOR : + case AdaptiveAVParameter_B_bAvCoeffR2_HOR : + case AdaptiveAVParameter_B_bAvCoeffR4_HOR : + case AdaptiveAVParameter_B_wAvHOffset_HOR_MSByte : + case AdaptiveAVParameter_B_wAvVOffset_HOR_MSByte : + case AdaptiveAVParameter_GB_bAvUnityOffset_Day : + case AdaptiveAVParameter_GB_bAvCoeffR2_Day : + case AdaptiveAVParameter_GB_bAvCoeffR4_Day : + case AdaptiveAVParameter_GB_wAvHOffset_Day_MSByte : + case AdaptiveAVParameter_GB_wAvVOffset_Day_MSByte : + case AdaptiveAVParameter_GB_bAvUnityOffset_COO : + case AdaptiveAVParameter_GB_bAvCoeffR2_COO : + case AdaptiveAVParameter_GB_bAvCoeffR4_COO : + case AdaptiveAVParameter_GB_wAvHOffset_COO_MSByte : + case AdaptiveAVParameter_GB_wAvVOffset_COO_MSByte : + case AdaptiveAVParameter_GB_bAvUnityOffset_INC : + case AdaptiveAVParameter_GB_bAvCoeffR2_INC : + case AdaptiveAVParameter_GB_bAvCoeffR4_INC : + case AdaptiveAVParameter_GB_wAvHOffset_INC_MSByte : + case AdaptiveAVParameter_GB_wAvVOffset_INC_MSByte : + case AdaptiveAVParameter_GB_bAvUnityOffset_HOR : + case AdaptiveAVParameter_GB_bAvCoeffR2_HOR : + case AdaptiveAVParameter_GB_bAvCoeffR4_HOR : + case AdaptiveAVParameter_GB_wAvHOffset_HOR_MSByte : + case AdaptiveAVParameter_GB_wAvVOffset_HOR_MSByte : + case AdaptiveAVParameter_GR_bAvUnityOffset_Day : + case AdaptiveAVParameter_GR_bAvCoeffR2_Day : + case AdaptiveAVParameter_GR_bAvCoeffR4_Day : + case AdaptiveAVParameter_GR_wAvHOffset_Day_MSByte : + case AdaptiveAVParameter_GR_wAvVOffset_Day_MSByte : + case AdaptiveAVParameter_GR_bAvUnityOffset_COO : + case AdaptiveAVParameter_GR_bAvCoeffR2_COO : + case AdaptiveAVParameter_GR_bAvCoeffR4_COO : + case AdaptiveAVParameter_GR_wAvHOffset_COO_MSByte : + case AdaptiveAVParameter_GR_wAvVOffset_COO_MSByte : + case AdaptiveAVParameter_GR_bAvUnityOffset_INC : + case AdaptiveAVParameter_GR_bAvCoeffR2_INC : + case AdaptiveAVParameter_GR_bAvCoeffR4_INC : + case AdaptiveAVParameter_GR_wAvHOffset_INC_MSByte : + case AdaptiveAVParameter_GR_wAvVOffset_INC_MSByte : + case AdaptiveAVParameter_GR_bAvUnityOffset_HOR : + case AdaptiveAVParameter_GR_bAvCoeffR2_HOR : + case AdaptiveAVParameter_GR_bAvCoeffR4_HOR : + case AdaptiveAVParameter_GR_wAvHOffset_HOR_MSByte : + case AdaptiveAVParameter_GR_wAvVOffset_HOR_MSByte : + case AdaptiveAVParameter_R_bAvUnityOffset_Day : + case AdaptiveAVParameter_R_bAvCoeffR2_Day : + case AdaptiveAVParameter_R_bAvCoeffR4_Day : + case AdaptiveAVParameter_R_wAvHOffset_Day_MSByte : + case AdaptiveAVParameter_R_wAvVOffset_Day_MSByte : + case AdaptiveAVParameter_R_bAvUnityOffset_COO : + case AdaptiveAVParameter_R_bAvCoeffR2_COO : + case AdaptiveAVParameter_R_bAvCoeffR4_COO : + case AdaptiveAVParameter_R_wAvHOffset_COO_MSByte : + case AdaptiveAVParameter_R_wAvVOffset_COO_MSByte : + case AdaptiveAVParameter_R_bAvUnityOffset_INC : + case AdaptiveAVParameter_R_bAvCoeffR2_INC : + case AdaptiveAVParameter_R_bAvCoeffR4_INC : + case AdaptiveAVParameter_R_wAvHOffset_INC_MSByte : + case AdaptiveAVParameter_R_wAvVOffset_INC_MSByte : + case AdaptiveAVParameter_R_bAvUnityOffset_HOR : + case AdaptiveAVParameter_R_bAvCoeffR2_HOR : + case AdaptiveAVParameter_R_bAvCoeffR4_HOR : + case AdaptiveAVParameter_R_wAvHOffset_HOR_MSByte : + case AdaptiveAVParameter_R_wAvVOffset_HOR_MSByte : + case ContrastStretchControl_fEnableContrastStretch : + case ContrastStretchControl_bMode : + case ContrastStretchControl_bAccColour : + case ContrastStretchControl_bBlackThreshold : + case ContrastStretchControl_bWhiteThreshold : + case DynamicConstrainedWBControls_fpRedA_MSByte : + case DynamicConstrainedWBControls_fpBlueA_MSByte : + case DynamicConstrainedWBControls_fpDamperLowThreshold_MSByte : + case DynamicConstrainedWBControls_fpMinimumDamperOutput_MSByte : + case DynamicConstrainedWBControls_fpDamperHighThreshold_MSByte : + case DynamicConstrainedWBControls_fDamperDisable : + case WhiteBalanceAlgorithmControls_fpStableTotalStepThreshold_MSByte : + case WhiteBalanceAlgorithmControls_fpMinimumRelativeStep_MSByte : + case WhiteBalanceAlgorithmControls_fpMaximumRelativeStep_MSByte : + case WhiteBalanceAlgorithmControls_fpStepProportion_MSByte : + case Toshiba_Vcm_Parameters_bSlewControlModeEnable : + case Toshiba_Vcm_Parameters_bSlewModeForSmallerStep : + case Toshiba_Vcm_Parameters_bSlewRateForSmallerStep : + case Toshiba_Vcm_Parameters_bSlewModeForLargerStep : + case Toshiba_Vcm_Parameters_bSlewRateForLargerStep : + case Toshiba_Vcm_Parameters_bThresholdStepSize : + case AdaptiveColourMatrix_fpNormalisedRedGain0_MSByte : + case AdaptiveColourMatrix_fpNormalisedRedGain1_MSByte : + case AdaptiveColourMatrix_bChooseAdaptiveColourMatrix: + + IRP_ASSERT(irp_write_packet(srv_open, vpip_default_params[vpip_update_iteration].addr,vpip_default_params[vpip_update_iteration].val));// 0)); + + + //printk(".........written val of i: %d\n",vpip_update_iteration); + break; + + default: + + //if(vpip_update_iteration>1835)printk("....val of i: %d\n",vpip_update_iteration); + //IRP_ASSERT(irp_write_packet(srv_open, vpip_default_params[vpip_update_iteration].addr,vpip_default_params[vpip_update_iteration].val));// 0)); + break; + + + } + } + + + + + + + + + + + + + + /* debug: depict whether the firmware was able to talk to sensor */ + IRP_ASSERT(irp_read_packet(srv_open, vpip_default_params[SensorInformation_fFarSensorAvailable].addr, &vpip_state)); + dbgprintk(1,"checking for SensorInformation=%d FAR sensor state \n", vpip_state); + IRP_ASSERT(irp_read_packet(srv_open, vpip_default_params[SensorInformation_fNearSensorAvailable].addr, &vpip_state)); + dbgprintk(1,"checking for SensorInformation=%d NEAR sensor state \n", vpip_state); + IRP_ASSERT(irp_read_packet(srv_open, vpip_default_params[SensorInformation_bCurrentlyActiveSensor].addr, &vpip_state)); + dbgprintk(1,"checking for bCurrentlyActiveSensor=%d sensor \n", vpip_state); + + + + + /* send start command */ + if(srv_open->config.preprocessor_info.configuration.transformId + != SVA_PREPROCESSOR_SENSOR_HIGHQUALITY_YUV420_MB){ + IRP_ASSERT(irp_write_packet(srv_open, vpip_default_params[HostInterfaceManagerControl_bUserCommand].addr, EWARP_START)); + dbgprintk(2," started irp fw to running state \n"); + } + else { + dbgprintk(2," Cant start irp fw here, for HIGHQUALITY task \n"); + IRP_ASSERT(irp_write_packet(srv_open, vpip_default_params[HostInterfaceManagerControl_bUserCommand].addr, EWARP_STOP)); + + mdelay(100); + + IRP_ASSERT(irp_read_packet(srv_open, vpip_default_params[ModeManagerStatus_bHiLevelState].addr, &vpip_state)); + while(vpip_state != IRP_STOPPED ){ + IRP_ASSERT(irp_read_packet(srv_open, vpip_default_params[ModeManagerStatus_bHiLevelState].addr, &vpip_state)); + dbgprintk(3,"HostInterfaceManagerStatus_bThisLoLevelState is not IRP_STOPPED \n"); + break; + } + + IRP_ASSERT(irp_write_packet(srv_open, vpip_default_params[HostInterfaceManagerControl_fStopSensor].addr,vpip_default_params[HostInterfaceManagerControl_fStopSensor].val));//1)); + } + + mdelay(300); + + /*debug */ +#if 0 + irp_read_packet(srv_open, vpip_default_params[StreamManagerStatus_bStreamStatus].addr, &vpip_state); + dbgprintk(3,"after start-command StreamManagerStatus_bStreamStatus=%d state \n", vpip_state); + irp_read_packet(srv_open, vpip_default_params[StreamManagerStatus_fIsSensorRunning].addr, &vpip_state); + dbgprintk(3,"after start-command StreamManagerStatus_fIsSensorRunning=%d state \n", vpip_state); + sva_error = irp_read_packet(srv_open, vpip_default_params[ModeManagerStatus_bThisLoLevelState].addr, &vpip_state); + dbgprintk(3,"after start-command ModeManagerStatus_bThisLoLevelState=%d state \n", vpip_state); + irp_read_packet(srv_open, vpip_default_params[ModeManagerStatus_bHiLevelState].addr, &vpip_state); + dbgprintk(3," ModeManagerStatus_bHiLevelState=%d state \n", vpip_state); + irp_read_packet(srv_open, vpip_default_params[Pipe0Status_bNumberOfFramesStreamed].addr, &vpip_state); + dbgprintk(3," Pipe0Status_bNumberOfFramesStreamed=%d state \n", vpip_state); + irp_read_packet(srv_open, vpip_default_params[PipeSetupBankA_uwPipeOutputSize_X_MSByte].addr, &vpip_state); + dbgprintk(3," PipeSetupBankA_uwPipeOutputSize_X_MSByte=%d state \n", vpip_state); + irp_read_packet(srv_open, vpip_default_params[PipeSetupBankA_uwPipeOutputSize_Y_MSByte].addr, &vpip_state); + dbgprintk(3," PipeSetupBankA_uwPipeOutputSize_Y_MSByte=%d state \n", vpip_state); + irp_read_packet(srv_open, vpip_default_params[HostInterfaceManagerStatus_bThisLoLevelState].addr, &vpip_state); + dbgprintk(3,"Firmware shoot cmd HostInterfaceManagerStatus_bThisLoLevelState =%d state \n", vpip_state); + if(vpip_state != 49) { + dbgprintk(2,"The HostInterfaceManagerStatus_bThisLoLevelState is not LOW_LEVEL_RUNNING !!\n"); + mdelay(30); +// return -1; + } +#endif + return 0; +} + +static int irp_boot_ewarp(struct sva_service_open *srv_open) +{ + short int read_value; + unsigned int i, retry=0; + int major=0,minor=0; + + /* send boot sequence */ + dbgprintk(1," writting boot_table[%d] to vpip\n", sizeof(page_elem_boot_table)/4); + for(i=0; i< sizeof(page_elem_boot_table)/4; i++){ + IRP_ASSERT(irp_write_packet(srv_open, page_elem_boot_table[i][0], + page_elem_boot_table[i][1])); + } + + /* sending the boot command */ + dbgprintk(1," Now sending the EWARP_BOOT command \n"); + IRP_ASSERT(irp_write_packet(srv_open, vpip_default_params[HostInterfaceManagerControl_bUserCommand].addr, EWARP_BOOT)); + + __udelay(3000); + /* wait till, fw comes in STOP state */ + IRP_ASSERT(irp_read_packet(srv_open, vpip_default_params[ModeManagerStatus_bHiLevelState].addr,&read_value)); + + while(read_value != IRP_STOPPED || retry++ != 10) { + IRP_ASSERT(irp_read_packet(srv_open, vpip_default_params[ModeManagerStatus_bHiLevelState].addr,&read_value)); + } + dbgprintk(1,"after boot IRP is in state =%d\n", read_value); + + if(read_value != IRP_STOPPED){ + dbgprintk(3," IRP is not in IRP_STOPPED state after boot=%d\n", read_value); + return -1; + } + /*debug */ + irp_read_packet(srv_open, vpip_default_params[DeviceParameters_bFirmwareVersionMajor].addr, &read_value); + printk("IRP firmware VERSION : %d.", read_value); + major=read_value; + irp_read_packet(srv_open, vpip_default_params[DeviceParameters_bFirmwareVersionMinor].addr, &read_value); + minor=read_value; + printk("%d \n", read_value); + + VPIP_VERSION=((major*100)+(minor)); + + return 0; +} + +int irp_stop_ewarp(struct sva_service_open *srv_open) +{ + short int read_value, retry=0; + t_sva_error sva_err; + + + dbgprintk(1,"%s stopping vpip service-id=%ld:state=%d\n", + __FUNCTION__, srv_open->service_id, srv_open->state); + IRP_ASSERT(irp_read_packet(srv_open, vpip_default_params[HostInterfaceManagerStatus_bThisLoLevelState].addr, &read_value)); + if(read_value == IRP_STOPPED){ + dbgprintk(3,"IRP is already in stopped state\n"); + return 0; + } + + dbgprintk(1,"sending STOP command to vpip, current state=%d.\n", read_value); + IRP_ASSERT(irp_write_packet(srv_open, vpip_default_params[ModeManagerControl_bUserCommand].addr, EWARP_STOP)); + IRP_ASSERT(irp_write_packet(srv_open, vpip_default_params[HostInterfaceManagerControl_bUserCommand].addr, EWARP_STOP)); + + mdelay(400); + + IRP_ASSERT(irp_read_packet(srv_open, vpip_default_params[HostInterfaceManagerStatus_bThisLoLevelState].addr, &read_value)); + while(read_value != IRP_STOPPED ){ + IRP_ASSERT(irp_read_packet(srv_open, vpip_default_params[HostInterfaceManagerStatus_bThisLoLevelState].addr, &read_value)); + if(retry++ > 10) + break; + } + + IRP_ASSERT(irp_write_packet(srv_open, vpip_default_params[HostInterfaceManagerControl_fStopSensor].addr,1)); + mdelay(300); + /* shutdown the sensor */ + if(sva.sva_platform_data->sensor_shutdown(IRP_CAMERA_SENSOR_CCP0)){ + dbgprintk(3,"error in shutting down the sensor \n"); + return -EAGAIN; + } + /* debug */ + IRP_ASSERT(irp_read_packet(srv_open, vpip_default_params[HostInterfaceManagerStatus_bThisLoLevelState].addr, &read_value)); + if(read_value != 34){ + dbgprintk(2,"after stop IRP, service is in state =%d\n", read_value); + /* sva_error = irp_write_packet(srv_open, ModeManagerControl_bUserCommand, 0); */ + } + + sva_err = SVA_IrpReset(); + if(sva_err != SVA_OK) + dbgprintk(2,"VP: IrpReset fw failed .. \n"); + + dbgprintk(2,"VP: IrpReset fw done ...\n"); + reset_vpip_to_default(); + + return 0; +} + +t_sva_error irp_start_ewarp_hq(struct sva_service_open *srv_open) +{ + +#if 0 + + short int read_value, retry=0; + t_sva_error sva_err; + t_sva_gb_hq_status hqstatus; + t_sva_timestamp empty_timestamp={SVA_NO_TIMESTAMP,0}; + + dbgprintk(3,"%s starting vpip service-id=%ld:state=%d\n", + __FUNCTION__, srv_open->service_id, srv_open->state); + + IRP_ASSERT(irp_read_packet(srv_open, vpip_default_params[HostInterfaceManagerStatus_bThisLoLevelState].addr, &read_value)); + if(read_value == IRP_RUNNING){ + dbgprintk(3,"IRP is already in running state\n"); + return 0; + } +#if 0 + hqstatus.tst = 1; + sva_err = SVA_UpdatePreProcessorParams(srv_open->service_id, + SVA_UPDATE_LAST, SVA_PREPROCESSOR_HQ_STATUS_TST,(t_uint32)&hqstatus); + if(sva_err != SVA_OK) + return sva_err; + printk("1. the HQ status tst hqstatus.status=%d, hqstatus.tst=%d \n", hqstatus.status, hqstatus.tst); +#endif + /* start SVA service here */ + sva_err = SVA_ControlService(srv_open->service_id, SVA_SERVICE_START,(t_uint32) &empty_timestamp); + if(sva_err != SVA_OK) + return sva_err; + + dbgprintk(3,"sending RUN command to vpip, current state=%d.\n", read_value); + IRP_ASSERT(irp_write_packet(srv_open, vpip_default_params[HostInterfaceManagerControl_bUserCommand].addr, EWARP_START)); + +/* mdelay(300); + sva_err = irp_read_packet(srv_open, HostInterfaceManagerStatus_bThisLoLevelState, &read_value); + dbgprintk(3,"Firmware shoot cmd HostInterfaceManagerStatus_bThisLoLevelState =%d state \n", read_value); + if(read_value != 49) { + dbgprintk(2,"The HostInterfaceManagerStatus_bThisLoLevelState is not LOW_LEVEL_RUNNING !!\n"); + __udelay(3000); + } +*/ + /* poll for hqstatus */ + hqstatus.status = 0; + do { + sva_err = SVA_UpdatePreProcessorParams(srv_open->service_id, + SVA_UPDATE_LAST, SVA_PREPROCESSOR_HQ_STATUS_READ,(t_uint32)&hqstatus); + if(sva_err != SVA_OK) + return sva_err; + printk("2. reading the HQ status tst hqstatus.status=%ld, hqstatus.tst=%ld \n", hqstatus.status, hqstatus.tst); +/* + mdelay(300); + hqstatus.tst = 0; + sva_err = SVA_UpdatePreProcessorParams(srv_open->service_id, + SVA_UPDATE_LAST,SVA_PREPROCESSOR_HQ_STATUS_TST,(t_uint32)&hqstatus); + if(sva_err != SVA_OK) + return sva_err; + printk("3. reading the HQ status tst hqstatus.status=%d, hqstatus.tst=%d \n", hqstatus.status, hqstatus.tst); +*/ + if(retry++ >= 10) + break; /* return -1;*/ + } while (hqstatus.status != 5 ); + + printk(" started grab hq service \n"); + mdelay(300); +#if 1 + irp_read_packet(srv_open, vpip_default_params[HostInterfaceManagerStatus_bThisLoLevelState].addr, &read_value); + dbgprintk(3,"Firmware shoot cmd HostInterfaceManagerStatus_bThisLoLevelState =%d state \n", read_value); + if(read_value != 49) + dbgprintk(3,"The HostInterfaceManagerStatus_bThisLoLevelState is not LOW_LEVEL_RUNNING !!\n"); +#endif + +#endif + + return 0; +} + +int irp_power_down(struct sva_service_open *srv_open) +{ + dbgprintk(1,"powering down the device \n"); + + IRP_ASSERT(irp_write_packet(srv_open, vpip_default_params[HostInterfaceManagerControl_fStopSensor].addr, 1)); + + IRP_ASSERT(irp_write_packet(srv_open, vpip_default_params[HostInterfaceManagerControl_bUserCommand].addr, EWARP_SLEEP)); + return 0; +} + +int irp_power_up(struct sva_service_open *srv_open) +{ + t_sva_error sva_error; + u16 vpip_state; + dbgprintk(1,"powering UP the device \n"); + + IRP_ASSERT(irp_write_packet(srv_open, vpip_default_params[HostInterfaceManagerControl_bUserCommand].addr, EWARP_WAKEUP)); + + sva_error = irp_read_packet(srv_open, vpip_default_params[ModeManagerStatus_bHiLevelState].addr, + &vpip_state); + if(sva_error !=SVA_OK){ + dbgprintk(3,"Failed to get the state of ewarp\n"); + return -1; + } + dbgprintk(1,"after power up the state of vpip is 0x%x\n",vpip_state); + + return 0; +} + + +int vpip_load_firmware( struct device *dev) +{ + const struct firmware *fw=NULL; + char * firmware_name; + int ret; + firmware_name = EWARP_FIRMWARE; + + fw=NULL; + ret = request_firmware(&fw, firmware_name, dev); + if(ret) { + dbgprintk(3,"error loading ewarp firmware\n"); + return -1; + } + + firmware_size = fw->size; + + irp_fw_ptr = kmalloc(firmware_size, GFP_KERNEL); + if(irp_fw_ptr==NULL){ + dbgprintk(3,"failed to allocate memory for fw of size=%d \n", firmware_size); + release_firmware(fw); + return -1; + } + + memcpy(irp_fw_ptr,fw->data,firmware_size); + + /*register fw with hcl */ + dbgprintk(1,"irp firmware registered with hcl successfully \n"); + release_firmware(fw); + return 0; +} + +int vpip_unload_firmware(void) +{ + dbgprintk(2,"Unloading irp firmware \n"); + if(irp_fw_ptr) + kfree(irp_fw_ptr); + return 0; +} --- /dev/null +++ linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.h @@ -0,0 +1,589 @@ +/*--------------------------------------------------------------------------------------------------*/ +/*© copyright STMicroelectronics, 2007. */ +/* */ +/*This program is free software; you can redistribute it and/or modify it under */ +/*the terms of the GNU General Public License as published by the Free */ +/*Software Foundation; either version 2.1 of the License, or (at your option) */ +/*any later version. */ +/* */ +/*This program is distributed in the hope that it will be useful, but WITHOUT */ +/*ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU General Public License for more details. */ +/* */ +/*You should have received a copy of the GNU General Public License */ +/*along with this program. If not, see . */ +/*--------------------------------------------------------------------------------------------------*/ + + + + + + +#ifndef __SVA_VPIP_H +#define __SVA_VPIP_H +#include "nomadik_sva.h" +#include + +//VP migrating to hcl-5.0.0 //#define EWARP_FIRMWARE "vpip8815_fw.bin" +#define EWARP_FIRMWARE "smia.bin" + + /* page "HostToSensorAccessControl" */ +//#define HostToSensorAccessControl_bRequest 0x0800 +//#define HostToSensorAccessControl_bCommandCoin 0x0802 +//#define HostToSensorAccessControl_uwSensorIndex_LSByte 0x0806 +//#define HostToSensorAccessControl_uwSensorIndex_MSByte 0x0805 + +//#define HostToSensorAccessStatus_bStatusCoin 0x0880 + + /* page "HostToSensorAccessData" */ +//#define HostToSensorAccessData_uwDataLow_LSByte 0x0902 +//#define HostToSensorAccessData_uwDataLow_MSByte 0x0901 +//#define HostToSensorAccessData_uwDataHigh_LSByte 0x0906 +//#define HostToSensorAccessData_uwDataHigh_MSByte 0x0905 + + /* page "PipeSetupBankA" */ +//#define PipeSetupBankA_uwPipeOutputSize_X_LSByte 0x0382 +//#define PipeSetupBankA_uwPipeOutputSize_X_MSByte 0x0381 +//#define PipeSetupBankA_uwPipeOutputSize_Y_LSByte 0x0386 +//#define PipeSetupBankA_uwPipeOutputSize_Y_MSByte 0x0385 +//#define PipeSetupBankA_bPipeOutputFormat 0x0388 +//#define PipeSetupBankA_bPipeStreamLength 0x038a +//#define PipeSetupBankA_fTogglePixValid 0x038c +//#define PipeSetupBankA_fEnableItuEmbeddedCodes 0x038e +//#define PipeSetupBankA_bPixValidLineTypes 0x0390 +//#define PipeSetupBankA_fGenerateVSync 0x0392 +//#define PipeSetupBankA_fCb_Cr_Flip 0x0394 +//#define PipeSetupBankA_fY_CbCr_Flip 0x0396 + + /* page "StaticFrameRateControl" */ +//#define StaticFrameRateControl_uwDesiredFrameRate_Num_LSByte 0x2802 +//#define StaticFrameRateControl_uwDesiredFrameRate_Num_MSByte 0x2801 +//#define StaticFrameRateControl_bDesiredFrameRate_Den 0x2804 + + /* page "RunModeControl" */ +//#define RunModeControl_fMeteringOn 0x0180 +//#define RunModeControl_fExitOnStable 0x0182 +//#define RunModeControl_bStreamLength 0x0184 + + /* page "ModeManagerStatus" [read only] */ +//#define ModeManagerStatus_bThisLoLevelState 0x0100 +//#define ModeManagerStatus_bNextLoLevelState 0x0102 +//#define ModeManagerStatus_bHiLevelState 0x0104 +//#define ModeManagerStatus_bCycles 0x0106 +//#define ModeManagerStatus_fModeStaticSetupsChanged 0x0108 +//#define ModeManagerStatus_bTestCoin 0x010a +//#define ModeManagerStatus_fCycleForTest 0x010c +//#define ModeManagerStatus_bNumberOfFramesStreamed 0x010e + + /* page "HostInterfaceManagerControl" */ +//#define HostInterfaceManagerControl_bUserCommand 0x0480 +//#define HostInterfaceManagerControl_fTestStateMachine 0x0482 +//#define HostInterfaceManagerControl_fForceTestState 0x0484 +//#define HostInterfaceManagerControl_bManualNextState 0x0486 +//#define HostInterfaceManagerControl_bTestCoin 0x0488 +//#define HostInterfaceManagerControl_fAutoTransitionFromRxStopped 0x048a +//#define HostInterfaceManagerControl_fStopSensor 0x048c + + /* page "MasterI2cControl" */ +//#define MasterI2cControl_bSensorSerialAddress 0x0980 +//#define MasterI2cControl_uwClk_Sensor_Comms_mhz_LSByte 0x0984 +//#define MasterI2cControl_uwClk_Sensor_Comms_mhz_MSByte 0x0983 +//#define MasterI2cControl_uwRequiredI2cSpeed_LSByte 0x0988 +//#define MasterI2cControl_uwRequiredI2cSpeed_MSByte 0x0987 + + + /* page "SystemConfiguration" */ +////#define SystemConfiguration_fFarSensorPresent 0x1400 +//#define SystemConfiguration_CcpRxForFarSensor 0x1402 +////#define SystemConfiguration_fNearSensorPresent 0x1404 +////#define SystemConfiguration_CcpRxForNearSensor 0x1406 +//#define SystemConfiguration_uwExternalClockFrequency_Mhz_num_LSByte 0x140a +//#define SystemConfiguration_uwExternalClockFrequency_Mhz_num_MSByte 0x1409 +//#define SystemConfiguration_bExternalClockFrequency_Mhz_den 0x140c +//#define SystemConfiguration_fFocusLensActuatorOnSensorNearPresent 0x140e +//#define SystemConfiguration_fFocusLensActuatorOnSensorFarPresent 0x1410 +//#define SystemConfiguration_fShutterActuatorOnSensorNearPresent 0x1412 +//#define SystemConfiguration_fShutterActuatorOnSensorFarPresent 0x1414 + + /* page "VideoTimingHostInputs" [mode static] */ +//#define VideoTimingHostInputs_VideoTimingMode 0x0a80 +//#define VideoTimingHostInputs_bSensorBitsPerSystemClock 0x0a82 +//#define VideoTimingHostInputs_uwCsiRawFormat_LSByte 0x0a86 +//#define VideoTimingHostInputs_uwCsiRawFormat_MSByte 0x0a85 +//#define VideoTimingHostInputs_fpHostRxMaxDataRate_Mbps_LSByte 0x0a8a +//#define VideoTimingHostInputs_fpHostRxMaxDataRate_Mbps_MSByte 0x0a89 +//#define VideoTimingHostInputs_VsyncPolarity 0x0a8c +//#define VideoTimingHostInputs_HsyncPolarity 0x0a8e +//#define VideoTimingSensorConstraints_fpMaximumPllOutputFrequency_Mhz_LSByte 0x0c16 + + /* page "VideoTimingInputsFarSensor" [mode static] */ +//#define VideoTimingInputsFarSensor_VideoTimingMode 0x0e00 +//#define VideoTimingInputsFarSensor_bSensorBitsPerSystemClock 0x0e02 +//#define VideoTimingInputsFarSensor_uwCsiRawFormat_LSByte 0x0e06 +//#define VideoTimingInputsFarSensor_uwCsiRawFormat_MSByte 0x0e05 +//#define VideoTimingInputsFarSensor_fpHostRxMaxDataRate_Mbps_LSByte 0x0e0a +//#define VideoTimingInputsFarSensor_fpHostRxMaxDataRate_Mbps_MSByte 0x0e09 +//#define VideoTimingInputsFarSensor_VsyncPolarity 0x0e0c +//#define VideoTimingInputsFarSensor_HsyncPolarity 0x0e0e + + /* page "VideoTimingInputsNearSensor" [mode static] */ +//#define VideoTimingInputsNearSensor_VideoTimingMode 0x1100 +//#define VideoTimingInputsNearSensor_bSensorBitsPerSystemClock 0x1102 +//#define VideoTimingInputsNearSensor_uwCsiRawFormat_LSByte 0x1106 +//#define VideoTimingInputsNearSensor_uwCsiRawFormat_MSByte 0x1105 +//#define VideoTimingInputsNearSensor_fpHostRxMaxDataRate_Mbps_LSByte 0x110a +//#define VideoTimingInputsNearSensor_fpHostRxMaxDataRate_Mbps_MSByte 0x1109 +//#define VideoTimingInputsNearSensor_VsyncPolarity 0x110c +//#define VideoTimingInputsNearSensor_HsyncPolarity 0x110e + + /* page "MiscPageElements" */ +//#define MiscPageElements_fConvertMultiByteReadsIntoSingleByte 0x4900 +//#define MiscPageElements_bDelayAfterSettingXshutdown 0x4902 +//#define MiscPageElements_fEnableIntelligentFlash 0x4904 +//#define MiscPageElements_fEligibleFrameForMetering 0x4906 +//#define MiscPageElements_fFlashGunIlluminatedFrameStreamed 0x4908 +//#define MiscPageElements_VpipCut 0x490a + + /* page "ZoomMgrCtrl" */ +//#define ZoomMgrCtrl_bHostTestCoin 0x3800 +//#define ZoomMgrCtrl_bZoomCmd 0x3802 +//#define ZoomMgrCtrl_fChgOverForbidden 0x3804 +//#define ZoomMgrCtrl_fAutoZoom 0x3806 +//#define ZoomMgrCtrl_bStepFramePeriod 0x3808 +//#define ZoomMgrCtrl_bMagFactor 0x380a +//#define ZoomMgrCtrl_bChgOverMarginShift 0x380c +//#define ZoomMgrCtrl_fCheckDataRate 0x380e +//#define ZoomMgrCtrl_fSetAlternateInitWOI 0x3810 +//#define ZoomMgrCtrl_fSetX_Byte0 0x3812 +//#define ZoomMgrCtrl_fSetX_Byte1 0x3814 +//#define ZoomMgrCtrl_fSetX_Byte2 0x3816 +//#define ZoomMgrCtrl_fSetX_Byte3 0x3818 +//#define ZoomMgrCtrl_fp16P0ScaleLowLimit_LSByte 0x381c +//#define ZoomMgrCtrl_fp16P0ScaleLowLimit_MSByte 0x381b +//#define ZoomMgrCtrl_fp16P1ScaleLowLimit_LSByte 0x3820 +//#define ZoomMgrCtrl_fp16P1ScaleLowLimit_MSByte 0x381f + +//#define ZoomMgrParams_bPrescaleFactor 0x3788 +//#define ZoomMgrParams_bPrescaleType 0x378a + + /* page "ColourEngine0_OutputCoderControls" */ +//#define ColourEngine0_OutputCoderControls_TransformType 0x3480 //0x3000 +//#define ColourEngine0_OutputCoderControls_bContrast 0x3482 //0x3002 +//#define ColourEngine0_OutputCoderControls_bColourSaturation 0x3484 //0x3004 + + /* page "PipeSetupBankSelector" */ +//#define PipeSetupBankSelector_bRequiredPipe0SetupBank 0x0280 + + /* page "ModeSetupBankSelector" [mode static] */ +//#define ModeSetupBankSelector_bRequiredModeSetupBank 0x0200 + + /* page "ModeSetupBank0" [mode static] */ +//#define ModeSetupBank0_uwInputImageSize_X_LSByte 0x0302 +//#define ModeSetupBank0_uwInputImageSize_X_MSByte 0x0301 +//#define ModeSetupBank0_uwInputImageSize_Y_LSByte 0x0306 +//#define ModeSetupBank0_uwInputImageSize_Y_MSByte 0x0305 +//#define ModeSetupBank0_uwMaxImageSize_X_LSByte 0x030a +//#define ModeSetupBank0_uwMaxImageSize_X_MSByte 0x0309 +//#define ModeSetupBank0_uwMaxImageSize_Y_LSByte 0x030e +//#define ModeSetupBank0_uwMaxImageSize_Y_MSByte 0x030d +//#define ModeSetupBank0_uwMinImageSize_X_LSByte 0x0312 +//#define ModeSetupBank0_uwMinImageSize_X_MSByte 0x0311 +//#define ModeSetupBank0_uwMinImageSize_Y_LSByte 0x0316 +//#define ModeSetupBank0_uwMinImageSize_Y_MSByte 0x0315 +//#define ModeSetupBank0_bActiveSensor 0x0318 +//#define ModeSetupBank0_fLowPowerStreaming 0x031a +//#define ModeSetupBank0_bTestMode 0x031c +//#define ModeSetupBank0_bNumberOfStatusLines 0x031e +//#define ModeSetupBank0_bNumberOfDarkLines 0x0320 +//#define ModeSetupBank0_bNumberOfBlackLines 0x0322 +//#define ModeSetupBank0_uwNumberOfInterLinePixelClocks_LSByte 0x0326 +//#define ModeSetupBank0_uwNumberOfInterLinePixelClocks_MSByte 0x0325 +//#define ModeSetupBank0_uwNumberOfInterFrameLines_LSByte 0x032a +//#define ModeSetupBank0_uwNumberOfInterFrameLines_MSByte 0x0329 +//#define ModeSetupBank0_bNumberOfDummyColumns 0x032c +//#define ModeSetupBank0_bInputImageSource 0x032e +//#define ModeSetupBank0_bOutputImageDestination 0x0330 + +//#define ModeSetupBank1_bActiveSensor 0x3a98 //0x3698 +//#define ModeSetupBank2_bActiveSensor 0x3b18 //0x3718 +//#define ModeSetupBank3_bActiveSensor 0x3b98 + + /* page "HostInterfaceManagerStatus" [read only] */ +//#define HostInterfaceManagerStatus_bThisLoLevelState 0x0500 +//#define HostInterfaceManagerStatus_bNextLoLevelState 0x0502 +//#define HostInterfaceManagerStatus_bHiLevelState 0x0504 +//#define HostInterfaceManagerStatus_bCycles 0x0506 +//#define HostInterfaceManagerStatus_bTestCoin 0x0508 +//#define HostInterfaceManagerStatus_fCycleForTest 0x050a + + /* page "Pipe0Control" */ +//#define Pipe0Control_bPipeControl 0x0700 +//#define Pipe0Control_fPipeRefreshRequired 0x0702 +//#define Pipe0Control_ReplaceRedChannel 0x0708 +//#define Pipe0Control_ReplaceGreenChannel 0x070a +//#define Pipe0Control_ReplaceBlueChannel 0x070c + + /* debug perpose of Sensor information */ +//#define SensorInformation_fFarSensorAvailable 0x1480 //0x1080 +//#define SensorInformation_uwFarSensorModelId_LSByte 0x1484 +//#define SensorInformation_uwFarSensorModelId_MSByte 0x1483 +//#define SensorInformation_bFarSensorRevision 0x1486 +//#define SensorInformation_fNearSensorAvailable 0x148c //0x108c +//#define SensorInformation_uwNearSensorModelId_LSByte 0x1490 +//#define SensorInformation_uwNearSensorModelId_MSByte 0x148f +//#define SensorInformation_bNearSensorRevision 0x1492 +//#define SensorInformation_bCurrentlyActiveSensor 0x1498 //0x1098 + + /* page "SensorCapabilitiesNearSensor" and far */ +//#define SensorCapabilitiesNearSensor_uwSensorAnalogGainMaximum_LSByte 0x159a +//#define SensorCapabilitiesNearSensor_uwSensorAnalogGainMaximum_MSByte 0x1599 +//#define SensorCapabilitiesFarSensor_uwSensorAnalogGainMaximum_LSByte 0x151a +//#define SensorCapabilitiesFarSensor_uwSensorAnalogGainMaximum_MSByte 0x1519 +//#define SensorCapabilitiesNearSensor_uwSensorDigitalGainCapability_LSByte 0x15d4 +//#define SensorCapabilitiesFarSensor_uwSensorDigitalGainCapability_LSByte 0x1554 + + /* Mode manager control & status */ +//#define ModeManagerStatus_bThisLoLevelState 0x0100 +//#define ModeManagerControl_bUserCommand 0x0080 +//#define ModeManagerControl_bManualNextState 0x0086 + +//#define StreamManagerStatus_bStreamStatus 0x0580 +//#define StreamManagerStatus_fIsSensorRunning 0x0582 + + /* page "Pipe0Status" [read only] */ +//#define Pipe0Status_bPipeStatus 0x0780 +//#define Pipe0Status_fPipeEnablePending 0x0782 +//#define Pipe0Status_bNumberOfFramesStreamed 0x0784 +//#define Pipe0Status_fDitherEnabled 0x0786 +//#define Pipe0Status_fVidCompletePending 0x0788 + + + /* page "VfpnControls" */ +//#define VfpnControls_fEnableCorrection 0x3100 +//#define VfpnControls_uwMaximumPixelValue_LSByte 0x3104 +//#define VfpnControls_uwMaximumPixelValue_MSByte 0x3103 +//#define VfpnControls_uwMinimumPixelValue_LSByte 0x3108 +//#define VfpnControls_uwMinimumPixelValue_MSByte 0x3107 +//#define VfpnControls_uwPixelSaturationLevel_LSByte 0x310c +//#define VfpnControls_uwPixelSaturationLevel_MSByte 0x310b +//#define VfpnControls_bLogThreshLog 0x310e + + /* page "AntiFlickerExposureControls" */ +//#define AntiFlickerExposureControls_bMainsFrequency_Hz 0x1780 +//#define AntiFlickerExposureControls_fGuaranteeStaticFlickerFrameLength 0x1782 + + /* page "DeviceParameters" [read only] */ +//#define DeviceParameters_bFirmwareVersionMajor 0x0004 +//#define DeviceParameters_bFirmwareVersionMinor 0x0006 + + /* page "ColourEngine0_ColourMatrixNearSensor" */ +//#define ColourEngine0_ColourMatrixNearSensor_fpRInR_LSByte 0x2b82 +//#define ColourEngine0_ColourMatrixNearSensor_fpRInR_MSByte 0x2b81 +//#define ColourEngine0_ColourMatrixNearSensor_fpGInR_LSByte 0x2b86 +//#define ColourEngine0_ColourMatrixNearSensor_fpGInR_MSByte 0x2b85 +//#define ColourEngine0_ColourMatrixNearSensor_fpBInR_LSByte 0x2b8a +//#define ColourEngine0_ColourMatrixNearSensor_fpBInR_MSByte 0x2b89 +//#define ColourEngine0_ColourMatrixNearSensor_fpRInG_LSByte 0x2b8e +//#define ColourEngine0_ColourMatrixNearSensor_fpRInG_MSByte 0x2b8d +//#define ColourEngine0_ColourMatrixNearSensor_fpGInG_LSByte 0x2b92 +//#define ColourEngine0_ColourMatrixNearSensor_fpGInG_MSByte 0x2b91 +//#define ColourEngine0_ColourMatrixNearSensor_fpBInG_LSByte 0x2b96 +//#define ColourEngine0_ColourMatrixNearSensor_fpBInG_MSByte 0x2b95 +//#define ColourEngine0_ColourMatrixNearSensor_fpRInB_LSByte 0x2b9a +//#define ColourEngine0_ColourMatrixNearSensor_fpRInB_MSByte 0x2b99 +//#define ColourEngine0_ColourMatrixNearSensor_fpGInB_LSByte 0x2b9e +//#define ColourEngine0_ColourMatrixNearSensor_fpGInB_MSByte 0x2b9d +//#define ColourEngine0_ColourMatrixNearSensor_fpBInB_LSByte 0x2ba2 +//#define ColourEngine0_ColourMatrixNearSensor_fpBInB_MSByte 0x2ba1 + /* page "ColourEngine0_ColourMatrixFarSensor" */ +//#define ColourEngine0_ColourMatrixFarSensor_fpRInR_LSByte 0x2b02 +//#define ColourEngine0_ColourMatrixFarSensor_fpRInR_MSByte 0x2b01 +//#define ColourEngine0_ColourMatrixFarSensor_fpGInR_LSByte 0x2b06 +//#define ColourEngine0_ColourMatrixFarSensor_fpGInR_MSByte 0x2b05 +//#define ColourEngine0_ColourMatrixFarSensor_fpBInR_LSByte 0x2b0a +//#define ColourEngine0_ColourMatrixFarSensor_fpBInR_MSByte 0x2b09 +//#define ColourEngine0_ColourMatrixFarSensor_fpRInG_LSByte 0x2b0e +//#define ColourEngine0_ColourMatrixFarSensor_fpRInG_MSByte 0x2b0d +//#define ColourEngine0_ColourMatrixFarSensor_fpGInG_LSByte 0x2b12 +//#define ColourEngine0_ColourMatrixFarSensor_fpGInG_MSByte 0x2b11 +//#define ColourEngine0_ColourMatrixFarSensor_fpBInG_LSByte 0x2b16 +//#define ColourEngine0_ColourMatrixFarSensor_fpBInG_MSByte 0x2b15 +//#define ColourEngine0_ColourMatrixFarSensor_fpRInB_LSByte 0x2b1a +//#define ColourEngine0_ColourMatrixFarSensor_fpRInB_MSByte 0x2b19 +//#define ColourEngine0_ColourMatrixFarSensor_fpGInB_LSByte 0x2b1e +//#define ColourEngine0_ColourMatrixFarSensor_fpGInB_MSByte 0x2b1d +//#define ColourEngine0_ColourMatrixFarSensor_fpBInB_LSByte 0x2b22 +//#define ColourEngine0_ColourMatrixFarSensor_fpBInB_MSByte 0x2b21 + + /* page "ColourEngine0_ColourMatrixDamperControl"*/ +//#define ColourEngine0_ColourMatrixDamperControl_fDisableMatrixDamping 0x2c80 +//#define ColourEngine0_ColourMatrixDamperControl_DamperLowThreshold_LSByte 0x2c84 +//#define ColourEngine0_ColourMatrixDamperControl_DamperLowThreshold_MSByte 0x2c83 +//#define ColourEngine0_ColourMatrixDamperControl_DamperHighThreshold_LSByte 0x2c88 +//#define ColourEngine0_ColourMatrixDamperControl_DamperHighThreshold_MSByte 0x2c87 +//#define ColourEngine0_ColourMatrixDamperControl_MinimumDamperOutput_LSByte 0x2c8c +//#define ColourEngine0_ColourMatrixDamperControl_MinimumDamperOutput_MSByte 0x2c8b + + /* page "ColourEngine0_GammaCorrection" */ +//#define ColourEngine0_GammaCorrection_fEnabled 0x2e00 +//#define ColourEngine0_GammaCorrection_bMode 0x2e02 +//#define ColourEngine0_GammaCorrection_SharpRed 0x2e04 +//#define ColourEngine0_GammaCorrection_SharpGreen 0x2e06 +//#define ColourEngine0_GammaCorrection_SharpBlue 0x2e08 +//#define ColourEngine0_GammaCorrection_SoftRed 0x2e0a +//#define ColourEngine0_GammaCorrection_SoftGreen 0x2e0c +//#define ColourEngine0_GammaCorrection_SoftBlue 0x2e0e + + + /* page "ColourEngine0_RadialApertureCorrectionControl" */ +//#define ColourEngine0_RadialApertureCorrectionControl_fEnableCorrection 0x3300 + + /* page "ColourEngine0_ApertureCorrectionControls" */ +//#define ColourEngine0_ApertureCorrectionControls_fDisableCorrection 0x2d00 +//#define ColourEngine0_ApertureCorrectionControls_bMaxGain 0x2d02 +//#define ColourEngine0_ApertureCorrectionControls_fDisableGainDamping 0x2d04 +//#define ColourEngine0_ApertureCorrectionControls_bMinimumCoringThreshold 0x2d12 +//#define ColourEngine0_ApertureCorrectionControls_fDisableCoringDamping 0x2d14 + +//#define ColourEngine0_CoderOutputSignalRange_uwChromaExcursion_MSByte 0x3509 +//#define ColourEngine0_CoderOutputSignalRange_uwChromaExcursion_LSByte 0x350a + + /* page "NoraControls" */ +//#define NoraControls_fDisable 0x2e80 +//#define NoraControls_fDisableNoraPromoting 0x2e82 +//#define NoraControls_bMaximumValue 0x2e84 + + /* page "WhiteBalanceControls" */ +//#define WhiteBalanceControls_bMode 0x2280 +//#define WhiteBalanceControls_bManualRedGain 0x2282 +//#define WhiteBalanceControls_bManualGreenGain 0x2284 +//#define WhiteBalanceControls_bManualBlueGain 0x2286 +//#define WhiteBalanceControls_bMiscSettings 0x2288 +//#define WhiteBalanceControls_fpFlashRedGain_LSByte 0x228c +//#define WhiteBalanceControls_fpFlashRedGain_MSByte 0x228b +//#define WhiteBalanceControls_fpFlashGreenGain_LSByte 0x2290 +//#define WhiteBalanceControls_fpFlashGreenGain_MSByte 0x228f +//#define WhiteBalanceControls_fpFlashBlueGain_LSByte 0x2294 +//#define WhiteBalanceControls_fpFlashBlueGain_MSByte 0x2293 +//#define WhiteBalanceControls_fInhibitWhiteBalancePresetModeForFlash 0x2296 + + /* page "MinWeightedWBControls" */ +//#define MinWeightedWBControls_fDisable 0x2500 + + /* page "ExposureControls" */ +//#define ExposureControls_bMode 0x1d80 +//#define ExposureControls_bMetering 0x1d82 +//#define ExposureControls_bMiscSettings 0x1d92 +//#define ExposureControls_fpDirectModeDigitalGain_LSByte 0x1da2 +//#define ExposureControls_fpDirectModeDigitalGain_MSByte 0x1da1 + + /* page "ExposureStatus" [read only] */ +//#define ExposureStatus_bAlgorithmStatus 0x1e00 +//#define ExposureStatus_bCompilerStatus 0x1e02 + + /* page "AntiVignetteControls" */ +//#define AntiVignetteControls_fDisableFilter 0x3200 + /* page "AntiVignetteControlsFar" */ +//#define AntiVignetteControlsFar_fDisableFilter 0x3c00 + + /* page "ScytheFilterControls" */ +//#define ScytheFilterControls_fDisableFilter 0x2f80 + /* page "JackFilterControls" */ +//#define JackFilterControls_fDisableFilter 0x3000 +//#define JackFilterControls_fSquareLaw 0x3002 +//#define JackFilterControls_fDisablePromotingLow 0x3004 +//#define JackFilterControls_fDisablePromotingHigh 0x3006 +//#define JackFilterControls_bMaxWeightLow 0x3008 +//#define JackFilterControls_bMaxWeightHigh 0x300a + + /* page "FlashManagerControl" */ +//#define FlashManagerControl_bMode 0x1c80 +//#define FlashManagerControl_bFlashType 0x1c82 + + /* page "ColourEngine0_FadeToBlack" */ +//#define ColourEngine0_FadeToBlack_fDisable 0x3680 +//#define ColourEngine0_FadeToBlack_fpBlackValue_LSByte 0x3684 +//#define ColourEngine0_FadeToBlack_fpBlackValue_MSByte 0x3683 +//#define ColourEngine0_FadeToBlack_fpDamperLowThreshold_LSByte 0x3688 +//#define ColourEngine0_FadeToBlack_fpDamperLowThreshold_MSByte 0x3687 +//#define ColourEngine0_FadeToBlack_fpDamperHighThreshold_LSByte 0x368c +//#define ColourEngine0_FadeToBlack_fpDamperHighThreshold_MSByte 0x368b +//#define ColourEngine0_FadeToBlack_fpDamperOutput_LSByte 0x3690 +//#define ColourEngine0_FadeToBlack_fpDamperOutput_MSByte 0x368f + + /* page "AutomaticFrameRateControl" */ +//#define AutomaticFrameRateControl_bMode 0x2700 + + /* page "ScytheFilterControls" */ +//#define ScytheFilterControls_fDisableFilter 0x2f80 +//#define ScytheFilterControls_fSquareLaw 0x2f82 +//#define ScytheFilterControls_fDisablePromotingLow 0x2f84 +//#define ScytheFilterControls_fDisablePromotingHigh 0x2f86 +//#define ScytheFilterControls_bMaxWeightLow 0x2f88 +//#define ScytheFilterControls_bMaxWeightHigh 0x2f8a + + /* page "AntiVignetteControlsFar" */ +//#define AntiVignetteControlsFar_fDisableFilter 0x3c00 + + /* page "AntiVignetteControlsNear" */ +//#define AntiVignetteControlsNear_fDisableFilter 0x3c80 + + /* page "FLADriverLowLevelParameters" */ +//#define FLADriverLowLevelParameters_AutoSkipNextFrame 0x3f12 +//#define FLADriverLowLevelParameters_bMaxNumberRetries 0x3f1c +//#define FLADriverLowLevelParameters_fOverwriteLowLevelLimits 0x3f20 +//#define FLADriverLowLevelParameters_fLowLevelDriverInitialized 0x3f1e + + /* page "BinningControl" [mode static] */ +//#define BinningControl_fEnableBinning 0x1a00 + +//VPIP product level user mode/scene mode + +struct nomadik_vpip_page { + +__u16 addr; +__u16 val; + +}; + + +struct WB_MODE_vpip{ +struct nomadik_vpip_page UM_WhiteBalanceControls_bMode; +struct nomadik_vpip_page UM_WhiteBalanceConstrainerControls_fpRedB_MSByte; +struct nomadik_vpip_page UM_WhiteBalanceConstrainerControls_fpBlueB_MSByte; +struct nomadik_vpip_page UM_WhiteBalanceConstrainerControls_fpMaximumDistanceAllowedFromLocus_MSByte; +struct nomadik_vpip_page UM_WhiteBalanceConstrainerControls_fEnableConstrainedWhiteBalance; +struct nomadik_vpip_page UM_DynamicConstrainedWBControls_fpRedA_MSByte; +struct nomadik_vpip_page UM_DynamicConstrainedWBControls_fpBlueA_MSByte; +struct nomadik_vpip_page UM_DynamicConstrainedWBControls_fDamperDisable; +}; + +struct EC_MODE_vpip{ +struct nomadik_vpip_page UM_ExposureControls_iExposureCompensation; +}; + +struct ISO_MODE_vpip{ +struct nomadik_vpip_page UM_SensorCapabilitiesFarSensor_uwSensorAnalogGainMaximum_MSByte; +struct nomadik_vpip_page UM_SensorCapabilitiesFarSensor_uwSensorAnalogGainMinimum_MSByte; +struct nomadik_vpip_page UM_ExposureAlgorithmControls_fpDigitalGainFloor_MSByte; +struct nomadik_vpip_page UM_ExposureAlgorithmControls_fpDigitalGainCeiling_MSByte; +}; + + +struct COLORTONES_MODE_vpip{ +struct nomadik_vpip_page UM_ColourEngine0_GammaCorrection_SharpRed; +struct nomadik_vpip_page UM_ColourEngine0_GammaCorrection_SharpGreen; +struct nomadik_vpip_page UM_ColourEngine0_GammaCorrection_SharpBlue; +struct nomadik_vpip_page UM_ColourEngine0_GammaCorrection_SoftRed; +struct nomadik_vpip_page UM_ColourEngine0_GammaCorrection_SoftGreen; +struct nomadik_vpip_page UM_ColourEngine0_GammaCorrection_SoftBlue; +struct nomadik_vpip_page UM_ColourEngine0_ColourMatrixFarSensor_fpRInR_MSByte; +struct nomadik_vpip_page UM_ColourEngine0_ColourMatrixFarSensor_fpGInR_MSByte; +struct nomadik_vpip_page UM_ColourEngine0_ColourMatrixFarSensor_fpBInR_MSByte; +struct nomadik_vpip_page UM_ColourEngine0_ColourMatrixFarSensor_fpRInG_MSByte; +struct nomadik_vpip_page UM_ColourEngine0_ColourMatrixFarSensor_fpGInG_MSByte; +struct nomadik_vpip_page UM_ColourEngine0_ColourMatrixFarSensor_fpBInG_MSByte; +struct nomadik_vpip_page UM_ColourEngine0_ColourMatrixFarSensor_fpRInB_MSByte; +struct nomadik_vpip_page UM_ColourEngine0_ColourMatrixFarSensor_fpGInB_MSByte; +struct nomadik_vpip_page UM_ColourEngine0_ColourMatrixFarSensor_fpBInB_MSByte; +struct nomadik_vpip_page UM_ColourEngine0_OutputCoderControls_bColourSaturation; +struct nomadik_vpip_page UM_Pipe0Control_fSfxNegativeEnabled; +struct nomadik_vpip_page UM_AdaptiveColourMatrix_bChooseAdaptiveColourMatrix; +}; + + +struct CONTRAST_MODE_vpip{ +struct nomadik_vpip_page UM_ColourEngine0_OutputCoderControls_bContrast; +}; + +struct SHARPNESS_MODE_vpip{ +struct nomadik_vpip_page UM_ColourEngine0_ApertureCorrectionControls_bMaxGain; +}; + + + + +struct EXPOSURE_MODE_vpip{ +struct nomadik_vpip_page UM_ExposureControls_bMetering; +struct nomadik_vpip_page UM_AutomaticFrameRateControl_bMode; +struct nomadik_vpip_page UM_AutomaticFrameRateControl_bImpliedGainThresholdLow_num; +struct nomadik_vpip_page UM_AutomaticFrameRateControl_bImpliedGainThresholdLow_den; +struct nomadik_vpip_page UM_AutomaticFrameRateControl_bImpliedGainThresholdHigh_num; +struct nomadik_vpip_page UM_AutomaticFrameRateControl_bImpliedGainThresholdHigh_den; +struct nomadik_vpip_page UM_AutomaticFrameRateControl_bUserMinimumFrameRate_Hz; +struct nomadik_vpip_page UM_AutomaticFrameRateControl_bUserMaximumFrameRate_Hz; +}; + + + + + + + + +enum vpip_state { + IRP_INIT_DONE=16, + IRP_BOOTING=32, + IRP_STOPPED=48, + IRP_RUNNING=64, + IRP_SLEEPING=80, +}; + +enum ewarp_command { + EWARP_UNINITIALIZED=0, + EWARP_BOOT=1, + EWARP_START, + EWARP_STOP, + EWARP_PREPARE, + EWARP_SLEEP, + EWARP_AUTOSTOP, /* autostop is set by mode manager when moving from RUN to STOP */ + EWARP_WAKEUP, /* power up vpip*/ +}; +/* +typedef enum { + IRP_CAMERA_SENSOR_CCIR, + IRP_CAMERA_SENSOR_CCP0, + IRP_CAMERA_SENSOR_CCP1, +} irp_sensor_t; +*/ +typedef enum { + IRP_UPDATE_CONTRAST, + IRP_UPDATE_ZOOM, + IRP_UPDATE_CROPPING, +} sva_irp_param_t; + +typedef enum { + EXPO_AUTOMATIC_MODE, + EXPO_COMPILED_MANUAL_MODE, + EXPO_DIRECT_MANUAL_MODE, + EXPO_FLASHGUN_MODE, + EXPO_CYCLETEST_MODE +} irp_exposure_ctrl_mode_t; + +typedef enum { + WHB_OFF, + WHB_AUTOMATIC, + WHB_AUTO_INSTANT, + WHB_MANUAL_RGB, + WHB_DAYLIGHT_PRESET, + WHB_TUNGSTEN_PRESET, + WHB_FLUORESCENT_PRESET, + WHB_HORIZON_PRESET, + WHB_FLASHGUN_PRESET, +} irp_white_balance_mode_t; + +typedef int sensor_type_t ; +#define SENSOR_MODEL_ID_2MP 750 +#define SENSOR_MODEL_ID_3MP_850 850 +#define SENSOR_MODEL_ID_3MP_851 851 + +int irp_activate_service(struct sva_service_open *srv_open); +int irp_update_service(struct sva_service_open *srv_open, + enum sva_update_service_param param, __u16 value); +int vpip_load_firmware(struct device *dev); +int vpip_unload_firmware(void); +int irp_stop_ewarp(struct sva_service_open *srv_open); +t_sva_error irp_start_ewarp_hq(struct sva_service_open *srv_open); + +#endif --- linux-2.6.20.orig/drivers/media/video/Kconfig +++ linux-2.6.20/drivers/media/video/Kconfig @@ -761,6 +761,13 @@ source "drivers/media/video/zc0301/Kconf source "drivers/media/video/pwc/Kconfig" endmenu # V4L USB devices +config VIDEO_NOMADIK + boolean "V4L2 compatiblity module for Nomadik SVA" + depends on VIDEO_DEV + ---help--- + Say Y here to compile v4l2 compatiblity module over Nomadik + SVA driver. + endmenu --- linux-2.6.20.orig/drivers/media/video/Makefile +++ linux-2.6.20/drivers/media/video/Makefile @@ -7,10 +7,12 @@ zr36067-objs := zoran_procfs.o zoran_dev tuner-objs := tuner-core.o tuner-types.o tuner-simple.o \ mt20xx.o tda8290.o tea5767.o tda9887.o msp3400-objs := msp3400-driver.o msp3400-kthreads.o +nmdkmod_v4l2-objs:= v4l2-nomadik.o + obj-$(CONFIG_VIDEO_DEV) += videodev.o v4l2-common.o compat_ioctl32.o ifeq ($(CONFIG_VIDEO_V4L1_COMPAT),y) obj-$(CONFIG_VIDEO_DEV) += v4l1-compat.o endif @@ -82,10 +84,14 @@ obj-$(CONFIG_VIDEO_TUNER) += tuner.o obj-$(CONFIG_VIDEO_BUF) += video-buf.o obj-$(CONFIG_VIDEO_BUF_DVB) += video-buf-dvb.o obj-$(CONFIG_VIDEO_BTCX) += btcx-risc.o obj-$(CONFIG_VIDEO_TVEEPROM) += tveeprom.o +ifeq ($(CONFIG_VIDEO_NOMADIK),y) + obj-m := nmdkmod_v4l2.o +endif + obj-$(CONFIG_VIDEO_M32R_AR_M64278) += arv.o obj-$(CONFIG_VIDEO_CX25840) += cx25840/ obj-$(CONFIG_VIDEO_UPD64031A) += upd64031a.o obj-$(CONFIG_VIDEO_UPD64083) += upd64083.o @@ -110,7 +116,7 @@ obj-$(CONFIG_USB_KONICAWC) += usbvi obj-$(CONFIG_USB_VICAM) += usbvideo/ obj-$(CONFIG_USB_QUICKCAM_MESSENGER) += usbvideo/ obj-$(CONFIG_VIDEO_VIVI) += vivi.o -EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core +EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core -I$(TOPDIR)/../multimedia/sva -I$(TOPDIR)/../multimedia/hcl/include -I$(TOPDIR)/../multimedia/hcl/sva extra-cflags-$(CONFIG_VIDEO_V4L1_COMPAT) += -DCONFIG_VIDEO_V4L1_COMPAT --- /dev/null +++ linux-2.6.20/drivers/media/video/hcl_defs.h @@ -0,0 +1,280 @@ +/****************************************************************************** + * C STMicroelectronics + * Reproduction and Communication of this document is + * strictly prohibited unless specifically autorized in + * writing by STMicroelectronics. + *----------------------------------------------------------------------------- + * + * Purpose : Basics definitions + * + *****************************************************************************/ + + + +#ifndef _HCL_DEFS_H +#define _HCL_DEFS_H + +#include "platform_os.h" + +/*----------------------------------------------------------------------------- + * Type definition + *---------------------------------------------------------------------------*/ +typedef unsigned char t_uint8; +typedef signed char t_sint8; +typedef unsigned short t_uint16; +typedef signed short t_sint16; +typedef unsigned long t_uint32; +typedef signed long t_sint32; + +#ifdef _WIN32_WCE +typedef unsigned __int64 t_uint64; +typedef __int64 t_sint64; +#else +/* typedef unsigned long long t_uint64; move to platform_os.h */ +/* typedef signed long long t_sint64; move to platform_os.h */ +#endif + +typedef unsigned int t_bitfield; + +#if !defined(FALSE) && !defined(TRUE) +typedef enum {FALSE, TRUE} t_bool; +#else /* FALSE & TRUE already defined */ +typedef enum {BOOL_FALSE, BOOL_TRUE} t_bool; +#endif /* !defined(FALSE) && !defined(TRUE) */ + +/* + * Definition of the different kind of addresses manipulated into a system with MMU + * (handle physical AND logical addresses) + */ +typedef t_uint32 t_physical_address; +typedef t_uint32 t_logical_address; + + + +/* + * Global frequency enumuration + * Added to avoid frequency conversion function which is required to convert one HCL + * frequency enumuration values to another HCL frequency enumuration values. + */ + +typedef enum { + HCL_FREQ_NOT_SUPPORTED=-1, + HCL_FREQ_8KHZ , + HCL_FREQ_11_25KHZ, + HCL_FREQ_12KHZ, + HCL_FREQ_16KHZ, + HCL_FREQ_22_05KHZ, + HCL_FREQ_22_5KHZ, + HCL_FREQ_24KHZ, + HCL_FREQ_32KHZ, + HCL_FREQ_44KHZ, + HCL_FREQ_44_1KHZ, + HCL_FREQ_48KHZ, + HCL_FREQ_64KHZ, + HCL_FREQ_88KHZ, + HCL_FREQ_88_2KHZ, + HCL_FREQ_96KHZ, + HCL_FREQ_128KHZ, + HCL_FREQ_176_4KHZ, + HCL_FREQ_192KHZ, + HCL_FREQ_1MHZ, + HCL_FREQ_2MHZ, + HCL_FREQ_3MHZ, + HCL_FREQ_4MHZ, + HCL_FREQ_5MHZ, + HCL_FREQ_6MHZ, + HCL_FREQ_8MHZ, + HCL_FREQ_11MHZ, + HCL_FREQ_12MHZ, + HCL_FREQ_16MHZ, + HCL_FREQ_22MHZ, + HCL_FREQ_24MHZ, + HCL_FREQ_48MHZ +} t_frequency; + + + +typedef struct { + t_physical_address physical; + t_logical_address logical; +} t_system_address; + + +/* + * Define a type used to manipulate size of various buffers + */ +typedef t_uint32 t_size; + +typedef struct { + t_bitfield minor:8; + t_bitfield major:8; + t_bitfield version:16; +} t_version; + + + + +/*----------------------------------------------------------------------------- + * Keyword definition + *---------------------------------------------------------------------------*/ +#define PUBLIC /* Extern by default */ +#define PRIVATE static + +#ifndef NULL +#define NULL (0) +#endif /* ndef NULL */ + +#define HCL_INTERNAL_ERROR (-8) +#define HCL_NOT_CONFIGURED (-7) +#define HCL_REQUEST_PENDING (-6) +#define HCL_REQUEST_NOT_APPLICABLE (-5) +#define HCL_INVALID_PARAMETER (-4) +#define HCL_UNSUPPORTED_FEATURE (-3) +#define HCL_UNSUPPORTED_HW (-2) +#define HCL_ERROR (-1) +#define HCL_OK ( 0) +#define HCL_INTERNAL_EVENT ( 1) +#define HCL_REMAINING_PENDING_EVENTS ( 2) +#define HCL_REMAINING_FILTER_PENDING_EVENTS ( 3) +#define HCL_NO_MORE_PENDING_EVENT ( 4) +#define HCL_NO_MORE_FILTER_PENDING_EVENT ( 5) +#define HCL_NO_PENDING_EVENT_ERROR ( 7) + + +#define HCL_MAX_ERROR_VALUE (-65) /* HCL specific error codes + * should start from this offset + */ + +/*----------------------------------------------------------------------------- + * Bit setting or clearing + *---------------------------------------------------------------------------*/ +#define HCL_SET_BITS(reg,mask) ((reg) |= (mask)) +#define HCL_CLEAR_BITS(reg,mask) ((reg) &= ~(mask)) +#define HCL_READ_BITS(reg,mask) ((reg) & (mask)) +#define HCL_WRITE_BITS(reg,val,mask) ((reg) = (((reg) & ~(mask)) | ((val) & (mask)))) +#define HCL_READ_REG(reg) (reg) +#define HCL_WRITE_REG(reg,val) ((reg) = (val)) + +/*----------------------------------------------------------------------------- + * field offset extraction from a structure + *---------------------------------------------------------------------------*/ +#define FIELD_OFFSET(typeName, fieldName) (t_uint32)(&(((typeName *)0)->fieldName)) +#define HCL_BITFIELD_OFFSET(typeName, fieldName) (t_uint32)(&(((typeName *)0)->fieldName)) + +/*----------------------------------------------------------------------------- + * Bit mask definition + *---------------------------------------------------------------------------*/ +#define MASK_NULL8 0x00 +#define MASK_NULL16 0x0000 +#define MASK_NULL32 0x00000000 +#define MASK_ALL8 0xFF +#define MASK_ALL16 0xFFFF +#define MASK_ALL32 0xFFFFFFFF + +#define MASK_BIT0 (1UL<<0) +#define MASK_BIT1 (1UL<<1) +#define MASK_BIT2 (1UL<<2) +#define MASK_BIT3 (1UL<<3) +#define MASK_BIT4 (1UL<<4) +#define MASK_BIT5 (1UL<<5) +#define MASK_BIT6 (1UL<<6) +#define MASK_BIT7 (1UL<<7) +#define MASK_BIT8 (1UL<<8) +#define MASK_BIT9 (1UL<<9) +#define MASK_BIT10 (1UL<<10) +#define MASK_BIT11 (1UL<<11) +#define MASK_BIT12 (1UL<<12) +#define MASK_BIT13 (1UL<<13) +#define MASK_BIT14 (1UL<<14) +#define MASK_BIT15 (1UL<<15) +#define MASK_BIT16 (1UL<<16) +#define MASK_BIT17 (1UL<<17) +#define MASK_BIT18 (1UL<<18) +#define MASK_BIT19 (1UL<<19) +#define MASK_BIT20 (1UL<<20) +#define MASK_BIT21 (1UL<<21) +#define MASK_BIT22 (1UL<<22) +#define MASK_BIT23 (1UL<<23) +#define MASK_BIT24 (1UL<<24) +#define MASK_BIT25 (1UL<<25) +#define MASK_BIT26 (1UL<<26) +#define MASK_BIT27 (1UL<<27) +#define MASK_BIT28 (1UL<<28) +#define MASK_BIT29 (1UL<<29) +#define MASK_BIT30 (1UL<<30) +#define MASK_BIT31 (1UL<<31) + +/*----------------------------------------------------------------------------- + * quartet shift definition + *---------------------------------------------------------------------------*/ +#define MASK_QUARTET (0xFUL) +#define SHIFT_QUARTET0 0 +#define SHIFT_QUARTET1 4 +#define SHIFT_QUARTET2 8 +#define SHIFT_QUARTET3 12 +#define SHIFT_QUARTET4 16 +#define SHIFT_QUARTET5 20 +#define SHIFT_QUARTET6 24 +#define SHIFT_QUARTET7 28 +#define MASK_QUARTET0 (MASK_QUARTET << SHIFT_QUARTET0) +#define MASK_QUARTET1 (MASK_QUARTET << SHIFT_QUARTET1) +#define MASK_QUARTET2 (MASK_QUARTET << SHIFT_QUARTET2) +#define MASK_QUARTET3 (MASK_QUARTET << SHIFT_QUARTET3) +#define MASK_QUARTET4 (MASK_QUARTET << SHIFT_QUARTET4) +#define MASK_QUARTET5 (MASK_QUARTET << SHIFT_QUARTET5) +#define MASK_QUARTET6 (MASK_QUARTET << SHIFT_QUARTET6) +#define MASK_QUARTET7 (MASK_QUARTET << SHIFT_QUARTET7) + +/*----------------------------------------------------------------------------- + * Byte shift definition + *---------------------------------------------------------------------------*/ +#define MASK_BYTE (0xFFUL) +#define SHIFT_BYTE0 0 +#define SHIFT_BYTE1 8 +#define SHIFT_BYTE2 16 +#define SHIFT_BYTE3 24 +#define MASK_BYTE0 (MASK_BYTE << SHIFT_BYTE0) +#define MASK_BYTE1 (MASK_BYTE << SHIFT_BYTE1) +#define MASK_BYTE2 (MASK_BYTE << SHIFT_BYTE2) +#define MASK_BYTE3 (MASK_BYTE << SHIFT_BYTE3) + +/*----------------------------------------------------------------------------- + * Halfword shift definition + *---------------------------------------------------------------------------*/ +#define MASK_HALFWORD (0xFFFFUL) +#define SHIFT_HALFWORD0 0 +#define SHIFT_HALFWORD1 16 +#define MASK_HALFWORD0 (MASK_HALFWORD << SHIFT_HALFWORD0) +#define MASK_HALFWORD1 (MASK_HALFWORD << SHIFT_HALFWORD1) + +/*----------------------------------------------------------------------------- + * Global constants definition + *---------------------------------------------------------------------------*/ + #define ONE_KB (1024) + #define ONE_MB (ONE_KB * ONE_KB) + + +/*----------------------------------------------------------------------------- + * Address translation macros declaration + *---------------------------------------------------------------------------*/ +#if defined(__PLATFORM_MEK0) || defined(__PLATFORM_MEK1) || defined(__PLATFORM_MEK2) || defined(__PLATFORM_MEK3) || defined(__PLATFORM_MEK4) + +#define ARM_TO_AHB_ADDR(addr) (addr | MASK_BIT31) +#define AHB_TO_ARM_ADDR(addr) (addr & ~MASK_BIT31) +#endif /* defined(__PLATFORM_MEK0) || defined(__PLATFORM_MEK1) || defined(__PLATFORM_MEK2) || defined(__PLATFORM_MEK3) */ + +#if defined(__PLATFORM_MEVKLITE) || defined(__PLATFORM_MEVKFULL) +#define ARM_TO_AHB_ADDR(addr) (addr) +#define AHB_TO_ARM_ADDR(addr) (addr) +#endif /* defined(__PLATFORM_MEVKLITE) || defined(__PLATFORM_MEVKFULL) */ + +/* For input parameters - would not be changed by the API */ +#define IN +/* For output parameters - would be changes by the API */ +#define OUT +/* For input-output parameters - provides input to the API but would be changed by the API */ +#define INOUT + +#endif /* _HCL_DEFS_H */ + +/* End of file hcl_defs.h */ --- /dev/null +++ linux-2.6.20/drivers/media/video/nomadik_camera.h @@ -0,0 +1,206 @@ +/*--------------------------------------------------------------------------------------------------*/ +/*© copyright STMicroelectronics, 2007. */ +/* */ +/*This program is free software; you can redistribute it and/or modify it under */ +/*the terms of the GNU General Public License as published by the Free */ +/*Software Foundation; either version 2.1 of the License, or (at your option) */ +/*any later version. */ +/* */ +/*This program is distributed in the hope that it will be useful, but WITHOUT */ +/*ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU General Public License for more details. */ +/* */ +/*You should have received a copy of the GNU General Public License */ +/*along with this program. If not, see . */ +/*--------------------------------------------------------------------------------------------------*/ + + + + + + + + +#ifndef __SVA_CAMERA_H__ +#define __SVA_CAMERA_H__ + +#include "nomadik_defs.h" + +/*#ifdef CONFIG_DEBUG_NOMADIK +#define DDBGPRINTK( s, args... ) printk( KERN_ALERT s, ##args ) +#else +//#define DDBGPRINTK( s, args... ) printk( KERN_ALERT s, ##args ) +#define DDBGPRINTK(x,... ) +#endif + +#define DERRPRINTK( s, args... ) printk( KERN_ALERT s, ##args ) +*/ +#define VGA_HEIGHT 480 +#define VGA_WIDTH 640 +#define CIF_HEIGHT 288 +#define CIF_WIDTH 352 +#define QVGA_HEIGHT 240 +#define QVGA_WIDTH 320 +#define QCIF_HEIGHT 144 +#define QCIF_WIDTH 176 +#define QQVGA_HEIGHT 120 +#define QQVGA_WIDTH 160 +#define QQVGA_PLUS_HEIGHT 128 +#define QQVGA_PLUS_WIDTH 160 +#define QQVGA_MINUS_HEIGHT 112 +#define QQVGA_MINUS_WIDTH 128 +#define SUBQCIF_HEIGHT 96 +#define SUBQCIF_WIDTH 128 +#define QQCIF_HEIGHT 72 +#define QQCIF_WIDTH 88 +#define CUSTOM_HEIGHT 64 +#define CUSTOM_WIDTH 80 + + +/* Defining the camera white balance supported */ +#define CAMERA_WB_OFF 0x00 +#define CAMERA_WB_AUTOMATIC 0x01 +#define CAMERA_WB_AUTOINSTANT 0x02 +#define CAMERA_WB_MANUAL 0x04 +#define CAMERA_WB_DAYLIGHT 0x05 +#define CAMERA_WB_TUNGSTEN 0x06 +#define CAMERA_WB_FLUORESCENT 0x07 +#define CAMERA_WB_HORIZON 0x08 +#define CAMERA_WB_FROZEN 0x09 + +#define CAMERA_AVOID_DIG_GAIN 0x00000001 +#define CAMERA_NOT_AVOID_DIG_GAIN 0x00000002 +#define CAMERA_INHIBIT_ROUNDUP 0x00000004 +#define CAMERA_NOT_INHIBIT_ROUNDUP 0x00000008 +#define CAMERA_SACRIFICE_EXP 0x00000010 +#define CAMERA_NOT_SACRIFICE_EXP 0x00000020 +#define CAMERA_INHIBIT_ANTIFLICKEREXP 0x00000040 +#define CAMERA_NOT_INHIBIT_ANTIFLICKEREXP 0x00000080 +#define CAMERA_INHIBIT_GAINCTRL 0x00000100 +#define CAMERA_NOT_INHIBIT_GAINCTRL 0x00000200 +#define CAMERA_FREEZE_AUTOEXP 0x00000400 +#define CAMERA_NOT_FREEZE_AUTOEXP 0x00000800 + + + +struct camera_capability { + __u8 viewfinder_bitmap; + __u8 viewfinder_direct; + __u8 image_capture; + __u8 video_capture; + __u8 contrast; + __u8 brightness; + + char white_balance; + char flash_mode; + char exposure; + int min_zoom; + int max_zoom; + int max_digital_zoom; + + int num_image_sizes; + int image_formats; + +}; + +//* Defining the camera flash modes */ +#define CAMERA_FLASH_NONE 0x00 +#define CAMERA_FLASH_AUTO 0x01 +#define CAMERA_FLASH_FORCED 0x02 +#define CAMERA_FLASH_FILLIN 0x04 +#define CAMERA_FLASH_REDEYE_REDUCE 0x08 + +/* Defining the camera exposure supported */ +#define CAMERA_EXPOSURE_AUTO 0x00 +#define CAMERA_EXPOSURE_NIGHT 0x01 +#define CAMERA_EXPOSURE_BACKLIGHT 0x02 +#define CAMERA_EXPOSURE_CENTRE 0x04 + +/* Defining the camera white balance supported */ +#define CAMERA_WB_AUTO 0x00 +#define CAMERA_WB_DAY_LIGHT 0x01 +#define CAMERA_WB_CLOUDY 0x02 +/* #define CAMERA_WB_TUNGSTEN 0x04 */ +#define CAMERA_WB_FLOURESCENT 0x08 +#define CAMERA_WB_FLASH 0x10 + +/* Defining the camera interface types */ +#define CAMERA_CCP_TYPE 0 +#define CAMERA_CCIR_TYPE 1 + +enum cameramode{ + CAMERAMODE_SLEEP=0, + CAMERAMODE_IDLE, + CAMERAMODE_VIEWFINDER, + CAMERAMODE_CAPTURE, + CAMERAMODE_LIVE, + CAMERAMODE_FLASH, + CAMERAMODE_RESERVED, + CAMERAMODE_BOOTING, + CAMERAMODE_UNKNOWN +}; + +enum camera_image_format { + IMG_FMT_RGB332 = 0, + IMG_FMT_RGB444, + IMG_FMT_RGB565, + IMG_FMT_YUV422, + IMG_FMT_JPEG, + IMG_FMT_UNKNOWN +}; + +enum camera_param_id { +FRAMERATE = 0, +CAMERAMODE, +FREQUENCY, +ZOOM, +}; + +struct camera_control { +enum camera_param_id id; +void *value; +}; + +struct camera_frequency { + __u8 msb; + __u8 lsb; +}; + +struct camera_configuration { + struct sva_image frame; + enum camera_image_format format; + __u16 frame_rate; + struct camera_frequency frequency; +}; + +struct camera { +char name[20]; +enum cameramode mode; +int type; +int height; +int width; +int bpp; +int frequency; +int frame_rate; +int capture_wait_count; +int (*init) (void); +void (*cleanup) (void); +int (*open) (void); +int (*close) (void); +int (*get_capability) (struct camera_capability *); +int (*set_params) (struct camera_configuration *); +int (*get_params) (struct camera_configuration *); +int (*set_control) (struct camera_control *ctrl); +int (*get_control) (struct camera_control *ctrl); +int (*set_jpegq) (int quality); +int (*get_jpegq) (int quality); +int (*whitebalancemode)(__u8 mode); +int (*expandcompilectrl)(__u8 ctrl); +}; + +int camera_register_device(struct camera*); +void camera_unregister_device (struct camera *); + + +#endif /*__CAMERA_H__*/ --- /dev/null +++ linux-2.6.20/drivers/media/video/nomadik_defs.h @@ -0,0 +1,76 @@ +/*--------------------------------------------------------------------------------------------------*/ +/*© copyright STMicroelectronics, 2007. */ +/* */ +/*This program is free software; you can redistribute it and/or modify it under */ +/*the terms of the GNU General Public License as published by the Free */ +/*Software Foundation; either version 2.1 of the License, or (at your option) */ +/*any later version. */ +/* */ +/*This program is distributed in the hope that it will be useful, but WITHOUT */ +/*ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU General Public License for more details. */ +/* */ +/*You should have received a copy of the GNU General Public License */ +/*along with this program. If not, see . */ +/*--------------------------------------------------------------------------------------------------*/ + + + + + +#ifndef __SVA_NOMADIK_H__ +#define __SVA_NOMADIK_H__ + +#ifndef __KERNEL__ +#define __KERNEL__ +#endif + +//#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include /* tasklet functions */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +//#include +#include + +#include "sva.h" +#include "nomadik_sva_services.h" +#include "nomadik_camera.h" + +#define TIMERCLK 90000 +#define SVA_HCL_MEMSIZE (10 * 1024 * 1024) + +#define MAX_OPENS 8 +#define MAX_SERVICE_OPENS MAX_OPENS +#define MAX_BUFFERS 50 +#define BITS_BUF_SIZE 60 * 1024 /* 60KB*/ +#define MAX_IOCTL_SIZE 4 * 1024 +#define TWO_MB 2*1024*1024 + +#define ERR_NO_BUFFER -100 + +#endif /* __SVA_NOMADIK_H__ */ + + + --- /dev/null +++ linux-2.6.20/drivers/media/video/nomadik_sva.h @@ -0,0 +1,225 @@ +/*--------------------------------------------------------------------------------------------------*/ +/*© copyright STMicroelectronics, 2007. */ +/* */ +/*This program is free software; you can redistribute it and/or modify it under */ +/*the terms of the GNU General Public License as published by the Free */ +/*Software Foundation; either version 2.1 of the License, or (at your option) */ +/*any later version. */ +/* */ +/*This program is distributed in the hope that it will be useful, but WITHOUT */ +/*ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU General Public License for more details. */ +/* */ +/*You should have received a copy of the GNU General Public License */ +/*along with this program. If not, see . */ +/*--------------------------------------------------------------------------------------------------*/ + + + + + + +#ifndef __SVA_SERVICE_INFO_H__ +#define __SVA_SERVICE_INFO_H__ + +#include +#include +#include "nomadik_defs.h" +#include +#include +#include +#include "nomadik_sva_utils.h" + +#define MAX_SERVICES 10 + +#define SERVICE_CREATED 0x00 +#define SERVICE_INACTIVATED 0x01 +#define SERVICE_ACTIVATED 0x02 +#define SERVICE_STARTED 0x04 +#define SERVICE_STOPPED 0x08 +#define SERVICE_ABORTED 0x10 +#define SERVICE_FLUSHED_IN 0x20 +#define SERVICE_FLUSHED_OUT 0x40 + +#define MAX_MESSAGES 60 + +struct sva_queue_data { + struct sva_queue input_q; + struct sva_queue internal_q; + struct sva_queue output_q; + wait_queue_head_t output_wq; /* wait queue for dequeue operation on output_q */ +}; + +struct sva_message_data { + struct sva_q_node qnode; + struct message_data message; + t_sva_buffer_id buffer_id; +}; + +struct sva_buffer_info{ + struct sva_q_node qnode; + __u16 flags; + __u16 ref_count; + struct sva_buffer buffer; + t_system_address buffer_addr; + unsigned long gfp_address; + t_sva_buffer_type buffer_type; + t_sva_buffer_id buffer_id; + t_sva_push_mode push; + t_sva_buffer_usage buffer_usage; + struct vm_area_struct *vma; +}; + +struct sva_postprocessor_info { + t_sva_postprocessor_configuration configuration; + __u8 pip_activated; +}; + +struct sva_preprocessor_info +{ + t_sva_preprocessor_configuration configuration; + __u16 camera_framerate; + __u16 sensor_aoi_x; + __u16 sensor_aoi_y; + __u16 prescale_factor; + +}; + +struct sva_videodecoder_info { + t_sva_video_decoder_configuration configuration; + t_sva_video_decoder_algo_h264_header_infos h264_infos; + t_uint16 vop_time_increment; +}; + + +struct sva_videoencoder_info { + t_sva_video_encoder_configuration configuration; +}; + + +struct sva_stillimagedecoder_info { + t_sva_still_decoder_configuration configuration; +}; + +struct sva_stillimageencoder_info { + t_sva_still_encoder_configuration configuration; +}; + +struct sva_tvout_info { + t_sva_tvo_configuration configuration; + enum sva_tvout_type type; +}; + +struct sva_readonly_work { + struct sva_service_open *srv_open; + t_sva_buffer_id buffer_id; +}; + +/*VPIP struct */ +struct irp_packet { + u16 readvalue; + short int packet_error; + short int rw_packet_finish; + t_sva_event_id eventId; +}; + +typedef enum { + GRAB_NONE, + GRAB_IRP, + GRAB_PEPPERPOT, + GRAB_INVALID, +} preprocessor_service_t; + +struct sva_service_open { + t_sva_service_type type; + __u8 state; + __u8 index; /* keeps track of open_data's index for closing purpose */ + struct semaphore service_lock; + char* internal_needs; + t_system_address internal_ncnb_needs; + __u32 internal_needs_size; + __u32 internal_ncnb_needs_size; + t_sva_header_infos *infos; + + union { + struct sva_preprocessor_info preprocessor_info; + struct sva_postprocessor_info postprocessor_info; + struct sva_videodecoder_info videodecoder_info; + struct sva_videoencoder_info videoencoder_info; + struct sva_stillimagedecoder_info stillimagedecoder_info; + struct sva_stillimageencoder_info stillimageencoder_info; + struct sva_tvout_info tvout_info; + }config; + + t_sva_service_id service_id; + struct sva_queue_data *in_image_buf_q; + struct sva_queue_data *out_image_buf_q; + struct sva_queue_data *readonly_image_buf_q; + struct sva_queue_data *in_coded_buf_q; + struct sva_queue_data *out_coded_buf_q; + struct sva_queue_data *in_infos_buf_q; + struct sva_queue_data *out_infos_buf_q; + struct sva_queue_data *in_params_buf_q; + struct sva_queue_data *out_params_buf_q; + struct sva_message_data messages_array[MAX_MESSAGES]; + struct sva_queue filled_message_queue; + struct sva_queue empty_message_queue; + wait_queue_head_t service_stop_wq; + wait_queue_head_t service_activate_wq; + wait_queue_head_t service_inactivate_wq; + wait_queue_head_t message_wq; + + /* VPIP */ + struct irp_packet irp_pkt; + preprocessor_service_t grab_type; +}; + +struct sva_device_open{ + __u8 flags; + __u8 services_active; + __u8 is_open; + __u8 index; + struct semaphore open_lock; + struct sva_buffer_info *buffer_info[MAX_BUFFERS]; + struct sva_service_open *service_open_data[MAX_SERVICE_OPENS]; +}; + +struct sva_firmware_data { + t_sva_fw_id firmware_id; + int firmware_index; + __u8 *buffer; +}; + +struct service_list { + int active; + struct sva_service_open *srv_open; +}; + +struct sva_device { + struct cdev c_dev; + struct platform_device *p_dev; + struct class_device class_dev; + struct sva_device_open device_open[MAX_OPENS]; + int open_count; + struct sva_service_open *active_preprocessor; + struct sva_service_open *active_tvout; + struct sva_firmware_data firmware_array[10]; + struct sva_board *sva_platform_data; + struct camera *camera; + preprocessor_service_t last_preprocessor_grab_type; +}; + +int sva_probe(struct platform_device *pdev); +int sva_remove(struct platform_device *pdev); + +irqreturn_t nomadik_sva_interrupt(int irq, void *device); +void nomadik_sva_tasklet(unsigned long); +int sva_BM_GetBufferType(t_sva_buffer_id bufferId, t_sva_buffer_type *pBufferType); + +#define lock_critical_section(x) down(x); tasklet_disable(&sva_tasklet) +#define unlock_critical_section(x) up(x); tasklet_enable(&sva_tasklet) + +#endif /* __SVA_SERVICE_INFO_H__ */ + + --- /dev/null +++ linux-2.6.20/drivers/media/video/nomadik_sva_services.h @@ -0,0 +1,3832 @@ +/*--------------------------------------------------------------------------------------------------*/ +/*© copyright STMicroelectronics, 2007. */ +/* */ +/*This program is free software; you can redistribute it and/or modify it under */ +/*the terms of the GNU General Public License as published by the Free */ +/*Software Foundation; either version 2.1 of the License, or (at your option) */ +/*any later version. */ +/* */ +/*This program is distributed in the hope that it will be useful, but WITHOUT */ +/*ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU General Public License for more details. */ +/* */ +/*You should have received a copy of the GNU General Public License */ +/*along with this program. If not, see . */ +/*--------------------------------------------------------------------------------------------------*/ + + + + + + +#ifndef __SVA_SERVICES_H__ +#define __SVA_SERVICES_H__ + +#include + +#define O_NOIO O_TRUNC + +#define BUF_FLAG_DONE 0x01 +#define BUF_FLAG_QUEUED 0x02 +#define BUF_FLAG_MAPPED 0x04 +#define BUF_FLAG_ERR 0x08 +#define BUF_FLAG_READONLY 0x10 +#define BUF_FLAG_PARTLY_FILLED 0x20 +#define BUF_FLAG_QUEUED_RO 0x40 + +typedef int Bool; + +enum sva_update_service_param { + PREPROCESSOR_CROP, + PREPROCESSOR_RESIZE, + PREPROCESSOR_ACE_ENABLE, + PREPROCESSOR_ACE_STRENGTH, + PREPROCESSOR_OUTPUT_RANGE, + PREPROCESSOR_ACE_RANGE, + PREPROCESSOR_ACE_OFFSET, +/*vpip-start*/ + PREPROCESSOR_ZOOM_IN, + PREPROCESSOR_ZOOM_OUT, + PREPROCESSOR_CONTRAST, + PREPROCESSOR_COLOUR_SATURATION, + PREPROCESSOR_WHITEBALANCE, + PREPROCESSOR_COLMATRIX_DAMPING, + PREPROCESSOR_EXPOSURE, + PREPROCESSOR_ENABLE_FUNCBLOCK, + PREPROCESSOR_FADETOBLACK, + PREPROCESSOR_RADIAL_PEAKING, +/*vpip-end*/ + POSTPROCESSOR_TILE, + POSTPROCESSOR_PIP, + POSTPROCESSOR_CONTRAST, + POSTPROCESSOR_BRIGHTNESS, + POSTPROCESSOR_DITHERING, + POSTPROCESSOR_CROP, + POSTPROCESSOR_CLIP, + POSTPROCESSOR_MIRROR, + POSTPROCESSOR_ROTATE, + POSTPROCESSOR_ALPHA_KEY, + POSTPROCESSOR_RESIZE, + POSTPROCESSOR_MATRIX_COEFF, + POSTPROCESSOR_ANTI_TEARING_EFFECT, + POSTPROCESSOR_ACE_ENABLE, + POSTPROCESSOR_ACE_STRENGTH, + POSTPROCESSOR_ACE_RANGE, + POSTPROCESSOR_OUTPUT_RANGE, + POSTPROCESSOR_REDBLUESWAP +}; + +enum sva_update_type { + UPDATE_MULTIPLE, + UPDATE_LAST +}; + +enum sva_service_type { +NONE = 0, +PREPROCESSOR = 1, +DECODE = 2, +ENCODE = 3, +POSTPROCESSOR = 4, +STILL_IMAGE_ENCODE = 5, +STILL_IMAGE_DECODE = 6, +TV_OUTPUT = 7, +SW_PROCESSING = 8 +}; + +enum service_ctrl_command { +SERVICE_START, +SERVICE_ABORT, +SERVICE_STOP, +SERVICE_FLUSH +}; + +enum sva_service_mode { + REALTIME, + NON_REALTIME +}; + +enum sva_buffer_type { +BUF_TYPE_NONE, +BUF_TYPE_IMAGE, +BUF_TYPE_BITSTREAM, +BUF_TYPE_INFOS, +BUF_TYPE_PARAMS, +/*vc1*/ +BUF_TYPE_VC1_IMAGE, +BUF_TYPE_GB_HQ_PARAMS, +}; + +enum block_type { + BLOCK, + NON_BLOCK, + BLOCK_TIMEOUT +}; + +enum push_type { + PUSH_IN, + PUSH_OUT +}; + +struct sva_buffer { +__u8 flags; +__u8 shared; +__u8 index; +__u8 read_only; /* needed for vc1 decode */ +__u32 phys_addr; +enum sva_buffer_type type; +__u32 offset; +__u32 buffer_id; +__u32 length; +__u32 size; /* also used as bytesused field*/ +__u32 info2; /* extra info2 field*/ +__u32 timestamp; +__u8 count; +}; + +struct sva_queue_buffer { +enum block_type block; +enum push_type push; +__u32 timeout; +struct sva_buffer buffer; +__u32 service_id; +}; + +struct sva_update_service { +__u32 service_id; +enum sva_update_service_param param; +enum sva_update_type type; +void *value; +}; + +struct sva_control_service { +__u32 service_id; +enum service_ctrl_command command; +}; + +enum sva_ace_strength { +ACE_STRENGTH_1 = 1, +ACE_STRENGTH_2, +ACE_STRENGTH_3, +ACE_STRENGTH_4, +ACE_STRENGTH_5, +ACE_STRENGTH_6, +ACE_STRENGTH_7, +ACE_STRENGTH_8 +}; + +struct sva_offset { +__u16 x_offset; +__u16 y_offset; +}; + +struct sva_image { +__u16 height; +__u16 width; +}; + +struct sva_window_desc { +struct sva_image frame; +struct sva_offset offset; +}; + +struct sva_window { +struct sva_image frame; +struct sva_window_desc window; +}; + +struct sva_ppp_tile_info { +struct sva_image image; +struct sva_offset offset; +void *next_tile; +}; + +struct sva_color_matrix { +__s16 matrix_coef1; +__s16 matrix_coef2; +__s16 matrix_coef3; +__s16 matrix_coef4; +}; + +struct sva_yuv_color { +__u8 Y; +__u8 U; +__u8 V; +}; + +enum postprocessor_capability { +POSTPROCESSOR_YUV420MB_TO_RGB, +POSTPROCESSOR_YUV420MB_TO_YUV422PL, +POSTPROCESSOR_YUV420PL_TO_RGB, +POSTPROCESSOR_YUV420MB_TO_YUV420MB, +POSTPROCESSOR_YUV420PL_TO_YUV422PL, +POSTPROCESSOR_YUV422PL_TO_RGB, +}; + +enum preprocessor_capability { +RAW, +YUV420_MB, +YUV420_SEP_COMP_MB, +YUV422_SEP_COMP_MB, +YUV420_RASTER_OUT, +/*vpip*/ +SENSOR_YUV420_MB, +SENSOR_YUV420_SEP_COMP_MB, +SENSOR_YUV422_SEP_COMP_MB, +SENSOR_YUV420_RASTER_OUT, +SENSOR_HIGHQUALITY_YUV420_MB, +}; + +enum videocodec_capability { +H263_P0_L10, +H263_P0_L30, +H263_P3_L10, +H263_P3_L30, +MPEG4_SP_L4A, +H264, +VC1_MP_LL, +MPEG2_MP_ML, +}; + +enum codec_mode { +IMAGE_MODE, +SEGMENTED_MODE, +STREAM_MODE +}; + +enum filter_mode { +NONE_FILTER, +DEBLOCKING, +DERINGING, +DEBLOCKING_DERINGING +}; + +enum color_range { +BT601_RANGE, +FULL_RANGE +}; + +enum sva_color_depth{ +BITS_12, +BITS_15, +BITS_16, +BITS_24, +BITS_32 +}; + +enum sva_mirroring { +NO_MIRRORING, +HORIZONTAL_MIRRORING, +VERTICAL_MIRRORING +}; + +enum sva_rotation{ +NO_ROTATION, +ROTATION_90, +ROTATION_180, +ROTATION_270 +}; + +enum sva_postprocessor_ace_mode{ +ACE_DISABLE, +ACE_INTERNAL, +ACE_EXTERNAL /* when using with Still Image Decoder */ +}; + +enum sva_deblocking_filter{ +NONE_DEBLOCKING_FILTER, +MPEG4_DEBLOCKING_FILTER, +H263_DEBLOCKING_FILTER, +H264_DEBLOCKING_FILTER, +MPEG2_DEBLOCKING_FILTER +}; + +enum sva_deringing_filter{ +NONE_DERINGING_FILTER, +MPEG4_DERINGING_FILTER, +H264_DERINGING_FILTER, +MPEG2_DERINGING_FILTER +}; + +enum sva_chroma_sampling_format{ +DEFAULT_SAMPLING_FORMAT = 0, +MPEG2_4_SAMPLING_FORMAT = 1, +MPEG1_SAMPLING_FORMAT = 2 +}; + +enum brc_intra_refresh_mode { +AIR_DISABLED_CIR_DISABLED=0, +AIR_ENABLED_CIR_DISABLED, +AIR_DISABLED_CIR_ENABLED, +AIR_ENABLED_CIR_ENABLED +}; + +enum sva_rtype_mode { +CONSTANT_ZERO, +CONSTANT_ONE, +TOGGLING +}; + +enum sva_brc_spatial_quality { +QUALITY_NONE, +QUALITY_LOW, +QUALITY_MEDIUM, +QUALITY_HIGH +}; + +enum sva_brc_mode { +CONSTANT_QP, +FRAME_BASE, +CBR, +VBR +}; + +enum brc_buffering_model { +BUFFERING_NONE, +BUFFERING_VBV, +BUFFERING_HRD, +BUFFERING_ANNEXG +}; + +/* MMCO type operations */ +enum sva_h264_mmco_type +{ +END_MMCO=0, +UNMARK_SHORT_REF =1, +UNMARK_LONG_REF, +ASSIGN_LONG_TO_SHORT, +UNMARK_LONG_REF_GREATER, +UNMARK_LONG, +ASSIGN_LONG_TO_CURRENT +}; + +enum sva_tvout_type { +TVO_PAL, +TVO_NTSC +}; + +/*Still Image*/ +enum stillimage_encoder_capability { + ENCODER_JPEG_MONOCHROME, + ENCODER_JPEG_420_SEP_COMP_MB, + ENCODER_JPEG_422_SEP_COMP_MB, + ENCODER_JPEG_444_SEP_COMP_MB, + ENCODER_JPEG_420_MB +}; + +enum stillimage_decoder_capability { + DECODER_PROGRESSIVE_JPEG, + DECODER_SEQUENTIAL_JPEG +}; + +enum sva_thumbnail_mode { + NON_THUMBNAIL, + THUMBNAIL_DC_420MB /* Specific image buffer will have to be pushed out */ +}; + +enum still_image_color_mode{ + MONOCHROME = 1, + COLOR = 3 +}; + +enum sva_downsampling_factor { + DOWNSAMPLING_FACTOR_1, + DOWNSAMPLING_FACTOR_2, + DOWNSAMPLING_FACTOR_4, + DOWNSAMPLING_FACTOR_8 +}; + +struct sva_sampling_factor { + __u16 h_sampling_factor_y; + __u16 v_sampling_factor_y; + __u16 h_sampling_factor_cb; + __u16 v_sampling_factor_cb; + __u16 h_sampling_factor_cr; + __u16 v_sampling_factor_cr;// param SamplingFactor-xx value: 1, 2 or 4 if used + //(used if componentSelector-xx = 1: if color_mode = monochrome only xSamplingFactorY used) +}; + +enum sva_jpeg_encode_on_fly_rotation { + JPEG_ENCODE_ROTATION_NONE, + JPEG_ENCODE_ROTATION_CLOCKWISE, + JPEG_ENCODE_ROTATION_ANTICLOCKWISE +}; + +struct jpeg_algo_params { + enum still_image_color_mode color_mode; + struct sva_sampling_factor sampling_factor; + enum sva_downsampling_factor downsampling_factor; +}; + +struct sva_preprocessor_configuration { +enum preprocessor_capability capability; +struct sva_image source_frame; +struct sva_window_desc cropped_window; +struct sva_image resized_frame; +enum color_range output_range; +Bool ace_enable; +enum sva_ace_strength ace_strength; +enum color_range ace_range; +__u32 frame_rate; +__u16 sensor_aoi_x; +__u16 sensor_aoi_y; +__u16 prescale_factor; + +}; + +struct sva_postprocessor_configuration { +enum postprocessor_capability capability; +Bool direct_display; +struct sva_image source_frame; +struct sva_window_desc cropped_window; +struct sva_image resized_frame; +struct sva_window_desc clipped_window; +struct sva_window_desc display_window; +struct sva_color_matrix matrix; +enum color_range output_range; +enum sva_postprocessor_ace_mode ace_mode; +enum sva_ace_strength ace_strength; +enum color_range ace_range; +enum sva_color_depth depth; +enum sva_mirroring mirroring; +enum sva_rotation rotation; +Bool dithering; +enum sva_deblocking_filter deblocking_filter; +enum sva_deringing_filter deringing_filter; +enum sva_chroma_sampling_format chroma_sampling; +__u8 brightness; +__u8 contrast; +__u8 alpha_key; +__u8 red_blue_swap; +Bool raster_in_format; +}; + +struct sva_tvout_configuration { +struct sva_window source_frame_window; +struct sva_offset destination_window_offset; +struct sva_yuv_color background_yuv_color; +enum sva_tvout_type tvo_type; +}; + +struct mpeg4_algo_params { + +Bool short_header; +__u16 vop_time_increment; +Bool resync_marker_disable; +Bool data_partitioned; +Bool reversible_vlc; + +/** + Stream Configuration info: + Added for support of advanced + simple profile + ~ SVA 8.0.0 migration */ +Bool isInterlaced; +__u16 low_delay; +__u16 quant_type; +__u16 intra_quant_mat[64] ; +__u16 nonintra_quant_mat[64]; +__u8 profile; + +}; + +struct mpeg4_header_infos { + +__u16 picture_coding_type; +__u16 quantization; +__u16 rounding_type; +__u16 intra_acdc_thr; +__u16 vop_fcode_forward; +__u32 bitstream_offset; +__u32 bitstream_address; + +/** + Frame Configuration info: + Added for support of advanced + simple profile + ~ SVA 8.0.0 migration */ +__u16 vop_fcode_backward; +__u16 vop_time_increment; +__u16 modulo_time_base; + +}; + +/* mpeg2 decode algo params & header infos */ +typedef enum { + MPEG2_PICTURE_SLICE_I = 1, + MPEG2_PICTURE_SLICE_P, + MPEG2_PICTURE_SLICE_B, + MPEG2_PICTURE_SLICE_D, + MPEG2_PICTURE_SLICE_SKIPPED +} mpeg2_picture_t; + +struct mpeg2_algo_params { +Bool load_intra_quantiser_matrix; +Bool load_nonintra_quantiser_matrix; +Bool progressive_sequence; +__u8 profile_level_indication; +__u8 chroma_format; +__u32 bit_rate; +}; + +struct mpeg2_header_infos { +__u16 horizontal_size; +__u16 vertical_size; +__u16 mb_height; + +__u16 intra_quantizer_matrix[64]; +__u16 non_intra_quantizer_matrix[64]; + +mpeg2_picture_t picture_coding_type; + +__u16 full_pel_forward_vector; +__u16 forward_f_code; +__u16 full_pel_backward_vector; +__u16 backward_f_code; + +__u16 f_code[2][2]; + +__u16 intra_dc_precision; +__u16 picture_structure; +__u16 top_field_first; +__u16 frame_pred_frame_dct; +__u16 concealment_motion_vectors; +__u16 q_scale_type; +__u16 intra_vlc_format; +__u16 alternate_scan; + +__u16 scalable_mode; +__u16 MPEG2_Flag; + +__u32 bitstream_offset; +__u32 bitstream_address; +}; + +struct h264_algo_params { +__u16 level_idc; +__u16 number_ref_frames; +__u16 gaps_in_frame_num_value_flag; +__u16 pic_order_cnt_type; +__u16 log_2_max_frame_num_minus4; +__u16 log_2_max_pic_order_cnt_lsb_minus4; +__u32 offset_for_non_ref_pic; +__u32 num_ref_frames_in_pic_order_cnt_cycle; +__u16 offset_for_ref_frame[256]; +__u32 offset_for_top_to_bottom_field; +}; + +struct h264_slice_header_infos { +__u16 nut; +__u16 nri; +__u32 slice_start_offset; +__u32 slice_bits_offset; +size_t slice_size; +__u16 slice_beta_offset_div2; +__u16 first_mb_in_slice; +__u16 slice_type; +__u16 num_ref_idx_10_active_minus1; +__s16 slice_qp_delta; +__u16 disable_deblocking_filter_idc; +__u16 slice_alpha_c0_offset_div2; +__u16 slice_num; +__u16 slice_qp ; +__u16 num_ref_idx_active_override_flag; +__u16 ref_pic_list_reordering_flag_l0; +__u16 frame_num; +__u16 reordering_of_pic_nums_idc[16]; +__u16 abs_diff_pic_num_minus1[16]; +__u16 long_term_pic_num[16]; +struct h264_slice_header_infos *next; +}; + +struct h264_header_infos +{ +__u16 chroma_qp_index; +__u16 constr_intra_pred_flag; +__u16 num_ref_idx_l0_active_minus1; +__u16 slice_0_slice_group_change_cycle; +__u16 num_slice_groups_minus1; +__u16 slice_group_map_type; +__u16 run_lenght_minus1[8]; +__u16 top_left[8]; +__u16 bottom_right[8]; +__u16 slice_group_change_dir_flag; +__u16 slice_group_change_rate_minus1; +__u16 slice_group_id[1620]; +__u16 slice_0_nut; +__u16 slice_0_nri; +__u16 slice_0_frame_num; +__u16 slice_0_pic_order_cnt_lsb; +__s32 slice_0_delta_pic_order_cnt[2]; +__s32 slice_0_delta_pic_order_cnt_bottom; +__u16 slice_0_long_term_reference_flag; +__u16 slice_0_no_output_of_prior_pics_flag; +__u16 slice_0_adaptive_ref_pic_marking_mode_flag; +enum sva_h264_mmco_type slice_0_memory_management_control_operation[16]; +__u16 slice_0_difference_of_pic_nums_minus1[16]; +__u16 slice_0_marking_long_term_pic_num[16]; +__u16 slice_0_long_term_frame_idx[16]; +__u16 slice_0_max_long_term_frame_idx_plus1[16]; +__u16 nb_slices_in_frame; +struct h264_slice_header_infos *pslice_header; /* from each slice headers */ +}; + + /* vc1 decode algo params & header infos */ +typedef enum { + VC1_PICTURE_TYPE_I = 0, + VC1_PICTURE_TYPE_P, + VC1_PICTURE_TYPE_B, + VC1_PICTURE_TYPE_BI, + VC1_PICTURE_SKIPPED +} vc1_picture_t; + +struct vc1_algo_params { + /* sequence layer parameters */ + __u8 profile; + __u8 level; + __u8 quantizer; + __u8 dquant; + __u8 max_b_frames; + __u8 q_framerate_for_postproc; + __u8 q_bitrate_for_postproc; + + Bool loop_filter_enabled; + Bool multires_coding_enabled; + Bool fast_uvmc_enabled; + Bool extended_mv_enabled; + Bool variable_size_transform_enabled; + Bool overlap_transform_enabled; + Bool syncmarker_enabled; + Bool rangered_enabled; + Bool frame_interpolation_enabled; + Bool is_smpte_conformant; +}; + +struct vc1_header_infos { + __u32 framesize; + vc1_picture_t picture_coding_type; +}; + + +/*JPEG data structures*/ + +struct sva_quantization_table { + __u16 quant_y[64]; // value range for quant_y/cb/cr params: 1 to 255 + __u16 quant_cb[64]; + __u16 quant_cr[64]; +} ; + +struct sva_huffman_table{ + __u16 huffmanYCodeDc[12]; + __u16 huffmanYSizeDc[12]; // value range for huffman-Y/Cb/Cr-Size-Dc/Ac params: 1 to 16 (if 0 it will not be used) + __u16 huffmanYCodeAc[256]; + __u16 huffmanYSizeAc[256]; + __u16 huffmanCbCodeDc[12]; + __u16 huffmanCbSizeDc[12]; + __u16 huffmanCbCodeAc[256]; + __u16 huffmanCbSizeAc[256]; + __u16 huffmanCrCodeDc[12]; + __u16 huffmanCrSizeDc[12]; + __u16 huffmanCrCodeAc[256]; + __u16 huffmanCrSizeAc[256]; +}; + +struct sva_still_decoder_algo_sequential_jpeg_header_infos{ + __u16 restartInterval; + struct sva_huffman_table huffmanTable; + struct sva_quantization_table quantizationTable; + +}; + +struct sva_still_decoder_algo_progressive_jpeg_header_infos{ + __u16 nbScanComponents; + __u16 componentSelectorY; //value: 0 = the Y component is not present in the current scan; 1 = present + __u16 componentSelectorCb; //value: 0 = the Cb component is not present in the current scan; 1 = present + __u16 componentSelectorCr; //value: 0 = the Cr component is not present in the current scan; 1 = present + __u16 startSpectralSelection; // value range: 0 to 63 + __u16 endSpectralSelection; // value range: startSpectralSelection to 63 + __u16 successiveApproxPosition; + __u16 restartInterval; + struct sva_huffman_table huffmanTable; + struct sva_quantization_table quantizationTable; +}; + +struct sva_codec_header_infos { +__u32 service_id; +__u32 buffer_id; +union { + struct mpeg4_header_infos mpeg4; + struct h264_header_infos h264; + struct vc1_header_infos vc1; + struct mpeg2_header_infos mpeg2; + struct sva_still_decoder_algo_sequential_jpeg_header_infos jpeg_sequential; + struct sva_still_decoder_algo_progressive_jpeg_header_infos jpeg_progressive; +} infos; + +}; + +struct sva_videodecoder_configuration { +enum videocodec_capability capability; +Bool is_infos_requested; +enum codec_mode mode; +enum filter_mode in_filter; +enum filter_mode out_filter; +struct sva_image frame; +void *codec_params; +__u16 vop_time_increment; +}; + +struct sva_brc_constant_qp_config_params { +__u32 intra_refresh; +__u8 i_picture_qp; +__u8 p_picture_qp; +__u32 bit_rate; +__u32 vbv_buffer_size; +__u32 vbv_occupancy; +__u32 swiss_buffer; +}; + +struct sva_brc_framebase_config_params { +__u32 dummy; +}; + +struct sva_brc_cbr_config_params { +__u32 intra_refresh; +__u32 bit_rate; +__u32 vbv_buffer_size; +__u32 vbv_occupancy; +__u32 swiss_buffer; +}; + +struct sva_brc_vbr_config_params { +__u32 intra_refresh; +__u32 bit_rate; +enum sva_brc_spatial_quality spatial_quality; +__u32 min_frame_rate; +__u32 vbv_buffer_size; +__u32 vbv_occupancy; +__u32 swiss_buffer; +}; + +struct mpeg4_encode_algo_params { +Bool short_header; +__u16 gob_header_freq; +Bool data_partitioned; +Bool reversible_vlc; +__u16 hec_freq; +__u16 vp_size_type; +__u16 vp_size_max; +__u16 vp_bit_size; +__u16 vp_mb_size; +enum brc_intra_refresh_mode refresh_mode; +__u16 air_mb_num; +__u16 cir_period_max; +enum sva_rtype_mode rtype_mode; +Bool system_header_before_intra; +__u8 profile_level; +__u16 vop_time_increment; +__u16 vop_time_increment_resolution; +}; + +struct h264_encode_algo_params{ +__s32 profile_idc; +__s32 level_idc; +//__s32 no_frames; +//__s32 qp0; +//__s32 qpn; +__s32 qp_i_slice; +__s32 qp_p_slice; +//__s32 hadamard; +__s32 search_range; +//__s32 jumpd; +//__s32 log_2_max_frame_num; +__s32 log_2_max_fnum_minus4; +//__u16 frame_width; +//__u16 frame_height; +//__s32 width_cr; +//__s32 height_cr; +__s16 slice_size_type; +__s16 slice_mb_size; +__s16 slice_bit_size; +__s32 use_constrained_intra_pred; +//__s32 infile_header; +__s32 intra_period; +__s32 idr_enable; +//__s32 start_frame; +__s32 annexb; +//__u16 intra_disable; +__s32 intra_disable_inter_only; +__s32 intra_4x4_par_disable; +__s32 intra_4x4_diag_disable; +__s32 intra_4x4_dir_disable; +__s32 intra_16x16_par_disable; +__s32 intra_16x16_plane_disable; +__s32 chroma_intra_disable; +__u16 intra_disable; +__u16 frame_rate; +__s32 chroma_qp_index_offset; +__s32 pic_order_cnt_type; +//__s32 report_frame_stats; +//__s16 brc_type; +__s32 bit_rate; +__s32 se_initial_qp; +//__s32 basic_unit; +__u16 me_type; +__s32 hrd_send_messages; +__u32 cpb_buffer_size; +__u16 intra_refresh_type; +__u16 air_mb_num; +//__u16 cir_period_max; +//__s16 slice_loss_first_mb[8]; +//__s16 slice_loss_mb_num[8]; +__s32 aspect_ratio_info_present_flag; +__s32 aspect_ratio_idc; +__s32 sar_width; +__s32 sar_height; +__s32 disable_deblocking_filter_idc; +__s32 slice_alpha; +__s32 slice_beta; +__s32 video_signal_type_present_flag; +__s32 video_format; +__s32 video_full_range_flag; +__s32 colour_description_present_flag; +__s32 colour_primaries; +__s32 transfer_characteristics; +__s32 matrix_coefficients; +__s32 intra_forced; +}; + +struct sva_videoencoder_configuration { +enum videocodec_capability capability; +Bool is_infos_requested; +Bool cropping_vector; +Bool destination_buffer; +enum codec_mode mode; +struct sva_window source_frame_desc; +enum filter_mode in_filter; +enum filter_mode out_filter; +enum sva_brc_mode brc_mode; +enum brc_buffering_model buffering_model; +void *brc_config_params; +void *codec_params; +__u16 vop_time_increment; +}; + +struct sva_stillimagedecoder_configuration { + enum stillimage_decoder_capability capability; + enum codec_mode mode; + struct sva_image decoded_frame_desc; + struct sva_window_desc crop_window; + enum sva_ace_strength ace_strength; + Bool is_cropping_enabled; + Bool no_slice_mode; + void * sva_still_algo_configuration_params; +}; + + +struct jpeg_encoder_algo_params { + __u16 restartInterval; + Bool isOptimizeQuantTableEnable; + enum sva_jpeg_encode_on_fly_rotation rotation; + Bool isOptimizeHuffmanTableEnable; + __u16 targetBpp; + struct sva_quantization_table quantizationTable; + struct sva_huffman_table huffmanTable; +}; + + + +struct sva_stillimageencoder_configuration { + enum stillimage_encoder_capability capability; + enum codec_mode mode; + Bool is_slice_mode; + enum sva_thumbnail_mode thumbnail_mode; + struct sva_window source_frame_desc; + Bool raster_in_format; + void * sva_still_algo_configuration_params; +}; + + +struct sva_service_struct { +enum sva_service_type service_type; +enum sva_service_mode mode; +__u32 service_id; +__u8 index; +union { + struct sva_preprocessor_configuration preprocessor_configuration; + struct sva_postprocessor_configuration postprocessor_configuration; + struct sva_videodecoder_configuration videodecoder_configuration; + struct sva_videoencoder_configuration videoencoder_configuration; + struct sva_stillimagedecoder_configuration stillimagedecoder_configuration; + struct sva_stillimageencoder_configuration stillimageencoder_configuration; + struct sva_tvout_configuration tvout_configuration; + }config; + +}; + +enum sva_message_type { + BUFFER_FILLED, + BUFFER_VOIDED, + EVENT_OVERFLOW, + EVENT_UNDERFLOW, + BUFFER_FILLED_READ_ONLY, + BUFFER_FILLED_PARTIALLY +}; + + +typedef enum { + + + + //"DeviceParameters//" + DeviceParameters_uwDeviceId_LSByte =0 , + DeviceParameters_uwDeviceId_MSByte , + DeviceParameters_bFirmwareVersionMajor , + DeviceParameters_bFirmwareVersionMinor , + DeviceParameters_bHardwareVersionMajor , + DeviceParameters_bHardwareVersionMinor , + + //"ModeManagerControl//" , + + ModeManagerControl_bUserCommand , + ModeManagerControl_fTestStateMachine , + ModeManagerControl_fForceTestState , + ModeManagerControl_bManualNextState , + ModeManagerControl_bTestCoin , + + //"ModeManagerStatus//" , + + ModeManagerStatus_bThisLoLevelState , + ModeManagerStatus_bNextLoLevelState , + ModeManagerStatus_bHiLevelState , + ModeManagerStatus_bCycles , + ModeManagerStatus_fModeStaticSetupsChanged , + ModeManagerStatus_bTestCoin , + ModeManagerStatus_fCycleForTest , + ModeManagerStatus_bNumberOfFramesStreamed , + ModeManagerStatus_bPrevFrameCountForExposure , + + //"RunModeControl//" , + + RunModeControl_fMeteringOn , + RunModeControl_fExitOnStable , + RunModeControl_bStreamLength , + RunModeControl_fMeterBeforeStreaming , + RunModeControl_fChkForAF_Stability , + RunModeControl_fChkForExposure_Stability , + RunModeControl_fChkForWhiteBalance_Stability , + + //"ModeSetupBankSelector//" , + + ModeSetupBankSelector_bRequiredModeSetupBank , + + //"PipeSetupBankSelector//" , + + PipeSetupBankSelector_bRequiredPipe0SetupBank , + + //"ModeSetupBank0//" , + + ModeSetupBank0_uwInputImageSize_X_LSByte , + ModeSetupBank0_uwInputImageSize_X_MSByte , + ModeSetupBank0_uwInputImageSize_Y_LSByte , + ModeSetupBank0_uwInputImageSize_Y_MSByte , + ModeSetupBank0_uwMaxImageSize_X_LSByte , + ModeSetupBank0_uwMaxImageSize_X_MSByte , + ModeSetupBank0_uwMaxImageSize_Y_LSByte , + ModeSetupBank0_uwMaxImageSize_Y_MSByte , + ModeSetupBank0_uwMinImageSize_X_LSByte , + ModeSetupBank0_uwMinImageSize_X_MSByte , + ModeSetupBank0_uwMinImageSize_Y_LSByte , + ModeSetupBank0_uwMinImageSize_Y_MSByte , + ModeSetupBank0_bActiveSensor, + ModeSetupBank0_fLowPowerStreaming , + ModeSetupBank0_bTestMode , + ModeSetupBank0_bNumberOfStatusLines , + ModeSetupBank0_bNumberOfDarkLines , + ModeSetupBank0_bNumberOfBlackLines , + ModeSetupBank0_uwNumberOfInterLinePixelClocks_LSByte , + ModeSetupBank0_uwNumberOfInterLinePixelClocks_MSByte , + ModeSetupBank0_uwNumberOfInterFrameLines_LSByte , + ModeSetupBank0_uwNumberOfInterFrameLines_MSByte , + ModeSetupBank0_bNumberOfDummyColumns , + ModeSetupBank0_bInputImageSource , + ModeSetupBank0_bOutputImageDestination , + + //"PipeSetupBankA//" , + + PipeSetupBankA_uwPipeOutputSize_X_LSByte , + PipeSetupBankA_uwPipeOutputSize_X_MSByte , + PipeSetupBankA_uwPipeOutputSize_Y_LSByte , + PipeSetupBankA_uwPipeOutputSize_Y_MSByte , + PipeSetupBankA_bPipeOutputFormat , + PipeSetupBankA_bPipeStreamLength , + PipeSetupBankA_fTogglePixValid , + PipeSetupBankA_fEnableItuEmbeddedCodes , + PipeSetupBankA_bPixValidLineTypes , + PipeSetupBankA_fGenerateVSync , + PipeSetupBankA_fCb_Cr_Flip , + PipeSetupBankA_fY_CbCr_Flip , + + //"PipeSetupBankB//" , + + PipeSetupBankB_uwPipeOutputSize_X_LSByte, + PipeSetupBankB_uwPipeOutputSize_X_MSByte , + PipeSetupBankB_uwPipeOutputSize_Y_LSByte , + PipeSetupBankB_uwPipeOutputSize_Y_MSByte , + PipeSetupBankB_bPipeOutputFormat , + PipeSetupBankB_bPipeStreamLength , + PipeSetupBankB_fTogglePixValid , + PipeSetupBankB_fEnableItuEmbeddedCodes , + PipeSetupBankB_bPixValidLineTypes , + PipeSetupBankB_fGenerateVSync , + PipeSetupBankB_fCb_Cr_Flip , + PipeSetupBankB_fY_CbCr_Flip , + + //"HostInterfaceManagerControl//" , + + HostInterfaceManagerControl_bUserCommand , + HostInterfaceManagerControl_fTestStateMachine , + HostInterfaceManagerControl_fForceTestState , + HostInterfaceManagerControl_bManualNextState , + HostInterfaceManagerControl_bTestCoin , + HostInterfaceManagerControl_fAutoTransitionFromRxStopped , + HostInterfaceManagerControl_fStopSensor , + + //"HostInterfaceManagerStatus//" , + + HostInterfaceManagerStatus_bThisLoLevelState , + HostInterfaceManagerStatus_bNextLoLevelState , + HostInterfaceManagerStatus_bHiLevelState , + HostInterfaceManagerStatus_bCycles , + HostInterfaceManagerStatus_bTestCoin , + HostInterfaceManagerStatus_fCycleForTest , + + //"StreamManagerStatus//" , + + StreamManagerStatus_bStreamStatus , + StreamManagerStatus_fIsSensorRunning , + + //"ClockManagerControl//" , + + ClockManagerControl_fClockManagerInDebugState , + + //"LocalPipe0SetupBank//" , + + LocalPipe0SetupBank_uwPipeOutputSize_X_LSByte , + LocalPipe0SetupBank_uwPipeOutputSize_X_MSByte , + LocalPipe0SetupBank_uwPipeOutputSize_Y_LSByte , + LocalPipe0SetupBank_uwPipeOutputSize_Y_MSByte , + LocalPipe0SetupBank_bPipeOutputFormat , + LocalPipe0SetupBank_bPipeStreamLength , + LocalPipe0SetupBank_fTogglePixValid , + LocalPipe0SetupBank_fEnableItuEmbeddedCodes , + LocalPipe0SetupBank_bPixValidLineTypes , + LocalPipe0SetupBank_fGenerateVSync , + LocalPipe0SetupBank_fCb_Cr_Flip , + LocalPipe0SetupBank_fY_CbCr_Flip , + + //"Pipe0Control//" , + + Pipe0Control_bPipeControl , + Pipe0Control_fPipeRefreshRequired , + Pipe0Control_fSfxSolariseEnabled , + Pipe0Control_fSfxNegativeEnabled , + Pipe0Control_ReplaceRedChannel, + Pipe0Control_ReplaceGreenChannel , + Pipe0Control_ReplaceBlueChannel , + Pipe0Control_fOverrideOFCropRegisters , + Pipe0Control_uwHCropRising_LSByte , + Pipe0Control_uwHCropRising_MSByte , + Pipe0Control_uwHCropFalling_LSByte , + Pipe0Control_uwHCropFalling_MSByte , + Pipe0Control_uwVCropRisingCrse_LSByte , + Pipe0Control_uwVCropRisingCrse_MSByte , + Pipe0Control_uwVCropFallingCrse_LSByte , + Pipe0Control_uwVCropFallingCrse_MSByte , + + //"Pipe0Status//" , + + Pipe0Status_bPipeStatus , + Pipe0Status_fPipeEnablePending , + Pipe0Status_bNumberOfFramesStreamed , + Pipe0Status_fDitherEnabled , + Pipe0Status_fVidCompletePending , + + //"HostToSensorAccessControl//" , + + HostToSensorAccessControl_bRequest , + HostToSensorAccessControl_bCommandCoin , + HostToSensorAccessControl_uwSensorIndex_LSByte , + HostToSensorAccessControl_uwSensorIndex_MSByte , + + //"HostToSensorAccessStatus//" , + + HostToSensorAccessStatus_bStatusCoin , + HostToSensorAccessStatus_bHostToSensorAccessErrorCount, + + //"HostToSensorAccessData//" , + + HostToSensorAccessData_uwDataLow_LSByte , + HostToSensorAccessData_uwDataLow_MSByte , + HostToSensorAccessData_uwDataHigh_LSByte , + HostToSensorAccessData_uwDataHigh_MSByte , + + //"MasterI2cControl//" , + + MasterI2cControl_bSensorSerialAddress , + MasterI2cControl_uwClk_Sensor_Comms_mhz_LSByte , + MasterI2cControl_uwClk_Sensor_Comms_mhz_MSByte , + MasterI2cControl_uwRequiredI2cSpeed_LSByte , + MasterI2cControl_uwRequiredI2cSpeed_MSByte , + MasterI2cControl_bMaximumNumberOfGrabAttempts , + + //"MasterI2cStatus//" , + + MasterI2cStatus_bResourceStatus , + MasterI2cStatus_uwI2CClkDiv_LSByte , + MasterI2cStatus_uwI2CClkDiv_MSByte , + MasterI2cStatus_fTransactionError , + MasterI2cStatus_bNumberOfTransactionFailures , + MasterI2cStatus_bNumberOfConsecutiveGrabFailures , + MasterI2cStatus_bNumberOfForcedReleases , + MasterI2cStatus_bNumberOfMcuClockDeratingAttemptsInhibited , + + //"VideoTimingHostInputs//" , + + VideoTimingHostInputs_VideoTimingMode, + VideoTimingHostInputs_bSensorBitsPerSystemClock , + VideoTimingHostInputs_uwCsiRawFormat_LSByte , + VideoTimingHostInputs_uwCsiRawFormat_MSByte , + VideoTimingHostInputs_fpHostRxMaxDataRate_Mbps_LSByte , + VideoTimingHostInputs_fpHostRxMaxDataRate_Mbps_MSByte , + VideoTimingHostInputs_VsyncPolarity , + VideoTimingHostInputs_HsyncPolarity , + + //"VideoTimingSensorFifoControl//" , + + VideoTimingSensorFifoControl_bFiFoWaterMarkProgrammingMode , + VideoTimingSensorFifoControl_uwFifoWaterMarkPixels_LSByte , + VideoTimingSensorFifoControl_uwFifoWaterMarkPixels_MSByte , + VideoTimingSensorFifoControl_uwFifoSizePixels_LSByte , + VideoTimingSensorFifoControl_uwFifoSizePixels_MSByte , + + //"VideoTimingSensorScalingAndSubSamplingControl//" , + + VideoTimingSensorScalingAndSubSamplingControl_fpOutputClockDeratingFraction_LSByte , + VideoTimingSensorScalingAndSubSamplingControl_fpOutputClockDeratingFraction_MSByte , + VideoTimingSensorScalingAndSubSamplingControl_bOutputClockDeratingRoundingMode , + VideoTimingSensorScalingAndSubSamplingControl_fDerateVideoTimingClockForProfileZero , + + //"VideoTimingSensorConstraints//" , + + VideoTimingSensorConstraints_uwMinimumPrePllClockDiv_LSByte , + VideoTimingSensorConstraints_uwMinimumPrePllClockDiv_MSByte , + VideoTimingSensorConstraints_uwMaximumPrePllClockDiv_LSByte , + VideoTimingSensorConstraints_uwMaximumPrePllClockDiv_MSByte , + VideoTimingSensorConstraints_fpMinimumPllInputFrequency_Mhz_LSByte , + VideoTimingSensorConstraints_fpMinimumPllInputFrequency_Mhz_MSByte, + VideoTimingSensorConstraints_uwMinimumPllMultiplier_LSByte , + VideoTimingSensorConstraints_uwMinimumPllMultiplier_MSByte , + VideoTimingSensorConstraints_uwMaximumPllMultiplier_LSByte , + VideoTimingSensorConstraints_uwMaximumPllMultiplier_MSByte , + VideoTimingSensorConstraints_fpMaximumPllOutputFrequency_Mhz_LSByte , + VideoTimingSensorConstraints_fpMaximumPllOutputFrequency_Mhz_MSByte , + VideoTimingSensorConstraints_uwMinimumVTSysClockDiv_LSByte , + VideoTimingSensorConstraints_uwMinimumVTSysClockDiv_MSByte , + VideoTimingSensorConstraints_uwMaximumVTSysClockDiv_LSByte , + VideoTimingSensorConstraints_uwMaximumVTSysClockDiv_MSByte , + VideoTimingSensorConstraints_fpMaximumVTSystemClockFrequency_Mhz_LSByte , + VideoTimingSensorConstraints_fpMaximumVTSystemClockFrequency_Mhz_MSByte , + VideoTimingSensorConstraints_uwMinimumVTPixelClockDiv_LSByte , + VideoTimingSensorConstraints_uwMinimumVTPixelClockDiv_MSByte , + VideoTimingSensorConstraints_uwMaximumVTPixelClockDiv_LSByte , + VideoTimingSensorConstraints_uwMaximumVTPixelClockDiv_MSByte , + VideoTimingSensorConstraints_fpMaximumVTPixelClockFrequency_Mhz_LSByte , + VideoTimingSensorConstraints_fpMaximumVTPixelClockFrequency_Mhz_MSByte , + VideoTimingSensorConstraints_uwMinimumOPSysClockDiv_LSByte , + VideoTimingSensorConstraints_uwMinimumOPSysClockDiv_MSByte , + VideoTimingSensorConstraints_uwMaximumOPSysClockDiv_LSByte , + VideoTimingSensorConstraints_uwMaximumOPSysClockDiv_MSByte , + VideoTimingSensorConstraints_fpMaximumOPSystemClockFrequency_Mhz_LSByte , + VideoTimingSensorConstraints_fpMaximumOPSystemClockFrequency_Mhz_MSByte , + VideoTimingSensorConstraints_fpMaximumOPPixelClockFrequency_Mhz_LSByte , + VideoTimingSensorConstraints_fpMaximumOPPixelClockFrequency_Mhz_MSByte , + + //"SensorScalingSubSamplingCapabilities//" , + + SensorScalingSubSamplingCapabilities_bSensorScalingMode , + SensorScalingSubSamplingCapabilities_uwScalerMMin_LSByte, + SensorScalingSubSamplingCapabilities_uwScalerMMin_MSByte , + SensorScalingSubSamplingCapabilities_uwScalerMMax_LSByte , + SensorScalingSubSamplingCapabilities_uwScalerMMax_MSByte , + SensorScalingSubSamplingCapabilities_uwMaxOddInc_LSByte , + SensorScalingSubSamplingCapabilities_uwMaxOddInc_MSByte , + + //"VideoTimingOutput//" , + + VideoTimingOutput_uwPrePllClockDiv_LSByte , + VideoTimingOutput_uwPrePllClockDiv_MSByte , + VideoTimingOutput_fpPllInputFrequency_Mhz_LSByte , + VideoTimingOutput_fpPllInputFrequency_Mhz_MSByte , + VideoTimingOutput_uwPllMultiplier_LSByte , + VideoTimingOutput_uwPllMultiplier_MSByte , + VideoTimingOutput_fpPllOutputFrequency_Mhz_LSByte , + VideoTimingOutput_fpPllOutputFrequency_Mhz_MSByte , + VideoTimingOutput_uwVTSystemClockDiv_LSByte , + VideoTimingOutput_uwVTSystemClockDiv_MSByte , + VideoTimingOutput_fpVTSystemClockFrequency_Mhz_LSByte , + VideoTimingOutput_fpVTSystemClockFrequency_Mhz_MSByte , + VideoTimingOutput_uwVTPixelClockDiv_LSByte , + VideoTimingOutput_uwVTPixelClockDiv_MSByte , + VideoTimingOutput_fpVTPixelClockFrequency_Mhz_LSByte , + VideoTimingOutput_fpVTPixelClockFrequency_Mhz_MSByte , + VideoTimingOutput_fpVTPixelClockPeriod_us_LSByte , + VideoTimingOutput_fpVTPixelClockPeriod_us_MSByte , + VideoTimingOutput_uwOPSystemClockDiv_LSByte , + VideoTimingOutput_uwOPSystemClockDiv_MSByte , + VideoTimingOutput_fpOPSystemClockFrequency_Mhz_LSByte , + VideoTimingOutput_fpOPSystemClockFrequency_Mhz_MSByte , + VideoTimingOutput_uwOPPixelClockDiv_LSByte, + VideoTimingOutput_uwOPPixelClockDiv_MSByte , + VideoTimingOutput_fpOPPixelClockFrequency_Mhz_LSByte , + VideoTimingOutput_fpOPPixelClockFrequency_Mhz_MSByte , + VideoTimingOutput_fpOutputTimingClockDerating_LSByte , + VideoTimingOutput_fpOutputTimingClockDerating_MSByte , + + //"DummyPage5//" , + + DummyPage5_bDummyPageElement , + + //"VideoTimingInputsFarSensor//" , + + VideoTimingInputsFarSensor_VideoTimingMode , + VideoTimingInputsFarSensor_bSensorBitsPerSystemClock , + VideoTimingInputsFarSensor_uwCsiRawFormat_LSByte , + VideoTimingInputsFarSensor_uwCsiRawFormat_MSByte , + VideoTimingInputsFarSensor_fpHostRxMaxDataRate_Mbps_LSByte , + VideoTimingInputsFarSensor_fpHostRxMaxDataRate_Mbps_MSByte , + VideoTimingInputsFarSensor_VsyncPolarity , + VideoTimingInputsFarSensor_HsyncPolarity , + + //"SensorFarVideoTimingSensorFifoControl//" , + + SensorFarVideoTimingSensorFifoControl_bFiFoWaterMarkProgrammingMode , + SensorFarVideoTimingSensorFifoControl_uwFifoWaterMarkPixels_LSByte , + SensorFarVideoTimingSensorFifoControl_uwFifoWaterMarkPixels_MSByte , + SensorFarVideoTimingSensorFifoControl_uwFifoSizePixels_LSByte , + SensorFarVideoTimingSensorFifoControl_uwFifoSizePixels_MSByte , + + //"VideoTimingFarSensorConstraints//" , + + VideoTimingFarSensorConstraints_uwMinimumPrePllClockDiv_LSByte , + VideoTimingFarSensorConstraints_uwMinimumPrePllClockDiv_MSByte , + VideoTimingFarSensorConstraints_uwMaximumPrePllClockDiv_LSByte , + VideoTimingFarSensorConstraints_uwMaximumPrePllClockDiv_MSByte , + VideoTimingFarSensorConstraints_fpMinimumPllInputFrequency_Mhz_LSByte , + VideoTimingFarSensorConstraints_fpMinimumPllInputFrequency_Mhz_MSByte , + VideoTimingFarSensorConstraints_uwMinimumPllMultiplier_LSByte , + VideoTimingFarSensorConstraints_uwMinimumPllMultiplier_MSByte , + VideoTimingFarSensorConstraints_uwMaximumPllMultiplier_LSByte , + VideoTimingFarSensorConstraints_uwMaximumPllMultiplier_MSByte , + VideoTimingFarSensorConstraints_fpMaximumPllOutputFrequency_Mhz_LSByte , + VideoTimingFarSensorConstraints_fpMaximumPllOutputFrequency_Mhz_MSByte , + VideoTimingFarSensorConstraints_uwMinimumVTSysClockDiv_LSByte , + VideoTimingFarSensorConstraints_uwMinimumVTSysClockDiv_MSByte , + VideoTimingFarSensorConstraints_uwMaximumVTSysClockDiv_LSByte , + VideoTimingFarSensorConstraints_uwMaximumVTSysClockDiv_MSByte , + VideoTimingFarSensorConstraints_fpMaximumVTSystemClockFrequency_Mhz_LSByte , + VideoTimingFarSensorConstraints_fpMaximumVTSystemClockFrequency_Mhz_MSByte , + VideoTimingFarSensorConstraints_uwMinimumVTPixelClockDiv_LSByte , + VideoTimingFarSensorConstraints_uwMinimumVTPixelClockDiv_MSByte , + VideoTimingFarSensorConstraints_uwMaximumVTPixelClockDiv_LSByte , + VideoTimingFarSensorConstraints_uwMaximumVTPixelClockDiv_MSByte , + VideoTimingFarSensorConstraints_fpMaximumVTPixelClockFrequency_Mhz_LSByte , + VideoTimingFarSensorConstraints_fpMaximumVTPixelClockFrequency_Mhz_MSByte , + VideoTimingFarSensorConstraints_uwMinimumOPSysClockDiv_LSByte , + VideoTimingFarSensorConstraints_uwMinimumOPSysClockDiv_MSByte , + VideoTimingFarSensorConstraints_uwMaximumOPSysClockDiv_LSByte , + VideoTimingFarSensorConstraints_uwMaximumOPSysClockDiv_MSByte , + VideoTimingFarSensorConstraints_fpMaximumOPSystemClockFrequency_Mhz_LSByte , + VideoTimingFarSensorConstraints_fpMaximumOPSystemClockFrequency_Mhz_MSByte , + VideoTimingFarSensorConstraints_fpMaximumOPPixelClockFrequency_Mhz_LSByte, + VideoTimingFarSensorConstraints_fpMaximumOPPixelClockFrequency_Mhz_MSByte , + + //"SensorFarScalingSubSamplingCapabilities//" , + + SensorFarScalingSubSamplingCapabilities_bSensorScalingMode , + SensorFarScalingSubSamplingCapabilities_uwScalerMMin_LSByte , + SensorFarScalingSubSamplingCapabilities_uwScalerMMin_MSByte , + SensorFarScalingSubSamplingCapabilities_uwScalerMMax_LSByte , + SensorFarScalingSubSamplingCapabilities_uwScalerMMax_MSByte , + SensorFarScalingSubSamplingCapabilities_uwMaxOddInc_LSByte , + SensorFarScalingSubSamplingCapabilities_uwMaxOddInc_MSByte , + + //"VideoTimingFarOutput//" , + + VideoTimingFarOutput_uwPrePllClockDiv_LSByte , + VideoTimingFarOutput_uwPrePllClockDiv_MSByte , + VideoTimingFarOutput_fpPllInputFrequency_Mhz_LSByte , + VideoTimingFarOutput_fpPllInputFrequency_Mhz_MSByte , + VideoTimingFarOutput_uwPllMultiplier_LSByte , + VideoTimingFarOutput_uwPllMultiplier_MSByte , + VideoTimingFarOutput_fpPllOutputFrequency_Mhz_LSByte , + VideoTimingFarOutput_fpPllOutputFrequency_Mhz_MSByte , + VideoTimingFarOutput_uwVTSystemClockDiv_LSByte , + VideoTimingFarOutput_uwVTSystemClockDiv_MSByte , + VideoTimingFarOutput_fpVTSystemClockFrequency_Mhz_LSByte , + VideoTimingFarOutput_fpVTSystemClockFrequency_Mhz_MSByte , + VideoTimingFarOutput_uwVTPixelClockDiv_LSByte , + VideoTimingFarOutput_uwVTPixelClockDiv_MSByte , + VideoTimingFarOutput_fpVTPixelClockFrequency_Mhz_LSByte , + VideoTimingFarOutput_fpVTPixelClockFrequency_Mhz_MSByte , + VideoTimingFarOutput_fpVTPixelClockPeriod_us_LSByte, + VideoTimingFarOutput_fpVTPixelClockPeriod_us_MSByte , + VideoTimingFarOutput_uwOPSystemClockDiv_LSByte , + VideoTimingFarOutput_uwOPSystemClockDiv_MSByte , + VideoTimingFarOutput_fpOPSystemClockFrequency_Mhz_LSByte , + VideoTimingFarOutput_fpOPSystemClockFrequency_Mhz_MSByte , + VideoTimingFarOutput_uwOPPixelClockDiv_LSByte , + VideoTimingFarOutput_uwOPPixelClockDiv_MSByte , + VideoTimingFarOutput_fpOPPixelClockFrequency_Mhz_LSByte , + VideoTimingFarOutput_fpOPPixelClockFrequency_Mhz_MSByte , + VideoTimingFarOutput_fpOutputTimingClockDerating_LSByte , + VideoTimingFarOutput_fpOutputTimingClockDerating_MSByte , + + //"DummyPage6//" , + + DummyPage6_bDummyPageElement , + + //"VideoTimingInputsNearSensor//" , + + VideoTimingInputsNearSensor_VideoTimingMode , + VideoTimingInputsNearSensor_bSensorBitsPerSystemClock , + VideoTimingInputsNearSensor_uwCsiRawFormat_LSByte , + VideoTimingInputsNearSensor_uwCsiRawFormat_MSByte , + VideoTimingInputsNearSensor_fpHostRxMaxDataRate_Mbps_LSByte , + VideoTimingInputsNearSensor_fpHostRxMaxDataRate_Mbps_MSByte , + VideoTimingInputsNearSensor_VsyncPolarity , + VideoTimingInputsNearSensor_HsyncPolarity , + + //"SensorNearVideoTimingSensorFifoControl//" , + + SensorNearVideoTimingSensorFifoControl_bFiFoWaterMarkProgrammingMode , + SensorNearVideoTimingSensorFifoControl_uwFifoWaterMarkPixels_LSByte, + SensorNearVideoTimingSensorFifoControl_uwFifoWaterMarkPixels_MSByte , + SensorNearVideoTimingSensorFifoControl_uwFifoSizePixels_LSByte , + SensorNearVideoTimingSensorFifoControl_uwFifoSizePixels_MSByte , + + //"VideoTimingNearSensorConstraints//" , + + VideoTimingNearSensorConstraints_uwMinimumPrePllClockDiv_LSByte , + VideoTimingNearSensorConstraints_uwMinimumPrePllClockDiv_MSByte , + VideoTimingNearSensorConstraints_uwMaximumPrePllClockDiv_LSByte , + VideoTimingNearSensorConstraints_uwMaximumPrePllClockDiv_MSByte , + VideoTimingNearSensorConstraints_fpMinimumPllInputFrequency_Mhz_LSByte , + VideoTimingNearSensorConstraints_fpMinimumPllInputFrequency_Mhz_MSByte , + VideoTimingNearSensorConstraints_uwMinimumPllMultiplier_LSByte , + VideoTimingNearSensorConstraints_uwMinimumPllMultiplier_MSByte , + VideoTimingNearSensorConstraints_uwMaximumPllMultiplier_LSByte , + VideoTimingNearSensorConstraints_uwMaximumPllMultiplier_MSByte , + VideoTimingNearSensorConstraints_fpMaximumPllOutputFrequency_Mhz_LSByte , + VideoTimingNearSensorConstraints_fpMaximumPllOutputFrequency_Mhz_MSByte , + VideoTimingNearSensorConstraints_uwMinimumVTSysClockDiv_LSByte , + VideoTimingNearSensorConstraints_uwMinimumVTSysClockDiv_MSByte , + VideoTimingNearSensorConstraints_uwMaximumVTSysClockDiv_LSByte , + VideoTimingNearSensorConstraints_uwMaximumVTSysClockDiv_MSByte , + VideoTimingNearSensorConstraints_fpMaximumVTSystemClockFrequency_Mhz_LSByte , + VideoTimingNearSensorConstraints_fpMaximumVTSystemClockFrequency_Mhz_MSByte , + VideoTimingNearSensorConstraints_uwMinimumVTPixelClockDiv_LSByte , + VideoTimingNearSensorConstraints_uwMinimumVTPixelClockDiv_MSByte , + VideoTimingNearSensorConstraints_uwMaximumVTPixelClockDiv_LSByte , + VideoTimingNearSensorConstraints_uwMaximumVTPixelClockDiv_MSByte , + VideoTimingNearSensorConstraints_fpMaximumVTPixelClockFrequency_Mhz_LSByte , + VideoTimingNearSensorConstraints_fpMaximumVTPixelClockFrequency_Mhz_MSByte , + VideoTimingNearSensorConstraints_uwMinimumOPSysClockDiv_LSByte, + VideoTimingNearSensorConstraints_uwMinimumOPSysClockDiv_MSByte , + VideoTimingNearSensorConstraints_uwMaximumOPSysClockDiv_LSByte , + VideoTimingNearSensorConstraints_uwMaximumOPSysClockDiv_MSByte , + VideoTimingNearSensorConstraints_fpMaximumOPSystemClockFrequency_Mhz_LSByte , + VideoTimingNearSensorConstraints_fpMaximumOPSystemClockFrequency_Mhz_MSByte , + VideoTimingNearSensorConstraints_fpMaximumOPPixelClockFrequency_Mhz_LSByte , + VideoTimingNearSensorConstraints_fpMaximumOPPixelClockFrequency_Mhz_MSByte , + + //"SensorNearScalingSubSamplingCapabilities//" , + + SensorNearScalingSubSamplingCapabilities_bSensorScalingMode , + SensorNearScalingSubSamplingCapabilities_uwScalerMMin_LSByte , + SensorNearScalingSubSamplingCapabilities_uwScalerMMin_MSByte , + SensorNearScalingSubSamplingCapabilities_uwScalerMMax_LSByte , + SensorNearScalingSubSamplingCapabilities_uwScalerMMax_MSByte , + SensorNearScalingSubSamplingCapabilities_uwMaxOddInc_LSByte , + SensorNearScalingSubSamplingCapabilities_uwMaxOddInc_MSByte , + + //"VideoTimingNearOutput//" , + + VideoTimingNearOutput_uwPrePllClockDiv_LSByte , + VideoTimingNearOutput_uwPrePllClockDiv_MSByte , + VideoTimingNearOutput_fpPllInputFrequency_Mhz_LSByte , + VideoTimingNearOutput_fpPllInputFrequency_Mhz_MSByte , + VideoTimingNearOutput_uwPllMultiplier_LSByte , + VideoTimingNearOutput_uwPllMultiplier_MSByte , + VideoTimingNearOutput_fpPllOutputFrequency_Mhz_LSByte , + VideoTimingNearOutput_fpPllOutputFrequency_Mhz_MSByte , + VideoTimingNearOutput_uwVTSystemClockDiv_LSByte , + VideoTimingNearOutput_uwVTSystemClockDiv_MSByte , + VideoTimingNearOutput_fpVTSystemClockFrequency_Mhz_LSByte, + VideoTimingNearOutput_fpVTSystemClockFrequency_Mhz_MSByte , + VideoTimingNearOutput_uwVTPixelClockDiv_LSByte , + VideoTimingNearOutput_uwVTPixelClockDiv_MSByte , + VideoTimingNearOutput_fpVTPixelClockFrequency_Mhz_LSByte , + VideoTimingNearOutput_fpVTPixelClockFrequency_Mhz_MSByte , + VideoTimingNearOutput_fpVTPixelClockPeriod_us_LSByte , + VideoTimingNearOutput_fpVTPixelClockPeriod_us_MSByte , + VideoTimingNearOutput_uwOPSystemClockDiv_LSByte , + VideoTimingNearOutput_uwOPSystemClockDiv_MSByte , + VideoTimingNearOutput_fpOPSystemClockFrequency_Mhz_LSByte , + VideoTimingNearOutput_fpOPSystemClockFrequency_Mhz_MSByte , + VideoTimingNearOutput_uwOPPixelClockDiv_LSByte , + VideoTimingNearOutput_uwOPPixelClockDiv_MSByte , + VideoTimingNearOutput_fpOPPixelClockFrequency_Mhz_LSByte , + VideoTimingNearOutput_fpOPPixelClockFrequency_Mhz_MSByte , + VideoTimingNearOutput_fpOutputTimingClockDerating_LSByte , + VideoTimingNearOutput_fpOutputTimingClockDerating_MSByte , + + //"DummyPage7//" , + + DummyPage7_bDummyPageElement , + + //"SystemConfiguration//" , + + SystemConfiguration_fFarSensorPresent , + SystemConfiguration_CcpRxForFarSensor , + SystemConfiguration_fNearSensorPresent , + SystemConfiguration_CcpRxForNearSensor , + SystemConfiguration_uwExternalClockFrequency_Mhz_num_LSByte , + SystemConfiguration_uwExternalClockFrequency_Mhz_num_MSByte , + SystemConfiguration_bExternalClockFrequency_Mhz_den, + SystemConfiguration_fFocusLensActuatorOnSensorNearPresent , + SystemConfiguration_fFocusLensActuatorOnSensorFarPresent , + SystemConfiguration_fShutterActuatorOnSensorNearPresent , + SystemConfiguration_fShutterActuatorOnSensorFarPresent , + SystemConfiguration_fpMcuClkFrequency_MHz_LSByte , + SystemConfiguration_fpMcuClkFrequency_MHz_MSByte , + + //"SensorInformation//" , + + SensorInformation_fFarSensorAvailable , + SensorInformation_uwFarSensorModelId_LSByte , + SensorInformation_uwFarSensorModelId_MSByte , + SensorInformation_bFarSensorRevision , + SensorInformation_bFarSensorManufacturerId , + SensorInformation_bFarSensorSMIAVersion , + SensorInformation_fNearSensorAvailable , + SensorInformation_uwNearSensorModelId_LSByte , + SensorInformation_uwNearSensorModelId_MSByte , + SensorInformation_bNearSensorRevision , + SensorInformation_bNearSensorManufacturerId , + SensorInformation_bNearSensorSMIAVersion , + SensorInformation_bCurrentlyActiveSensor , + SensorInformation_fCurrentSensorAvailable , + SensorInformation_fSensorChangedSinceLastStreaming , + + //"SensorCapabilitiesFarSensor//" , + + SensorCapabilitiesFarSensor_uwSensorIntegrationTimeCapability_LSByte , + SensorCapabilitiesFarSensor_uwSensorIntegrationTimeCapability_MSByte , + SensorCapabilitiesFarSensor_uwSensorMinimumCoarseIntegrationLines_LSByte , + SensorCapabilitiesFarSensor_uwSensorMinimumCoarseIntegrationLines_MSByte, + SensorCapabilitiesFarSensor_uwSensorCoarseIntegrationTimeMaxMargin_LSByte , + SensorCapabilitiesFarSensor_uwSensorCoarseIntegrationTimeMaxMargin_MSByte , + SensorCapabilitiesFarSensor_uwSensorMinimumFineIntegrationPixels_LSByte , + SensorCapabilitiesFarSensor_uwSensorMinimumFineIntegrationPixels_MSByte , + SensorCapabilitiesFarSensor_uwSensorFineIntegrationTimeMaxMargin_LSByte , + SensorCapabilitiesFarSensor_uwSensorFineIntegrationTimeMaxMargin_MSByte , + SensorCapabilitiesFarSensor_uwSensorAnalogGainMinimum_LSByte , + SensorCapabilitiesFarSensor_uwSensorAnalogGainMinimum_MSByte , + SensorCapabilitiesFarSensor_uwSensorAnalogGainMaximum_LSByte , + SensorCapabilitiesFarSensor_uwSensorAnalogGainMaximum_MSByte , + SensorCapabilitiesFarSensor_uwSensorAnalogGainCodeStep_LSByte , + SensorCapabilitiesFarSensor_uwSensorAnalogGainCodeStep_MSByte , + SensorCapabilitiesFarSensor_uwSensorAnalogGainType_LSByte , + SensorCapabilitiesFarSensor_uwSensorAnalogGainType_MSByte , + SensorCapabilitiesFarSensor_fpSensorAnalogGainConstM0_LSByte , + SensorCapabilitiesFarSensor_fpSensorAnalogGainConstM0_MSByte , + SensorCapabilitiesFarSensor_fpSensorAnalogGainConstC0_LSByte , + SensorCapabilitiesFarSensor_fpSensorAnalogGainConstC0_MSByte , + SensorCapabilitiesFarSensor_fpSensorAnalogGainConstM1_LSByte , + SensorCapabilitiesFarSensor_fpSensorAnalogGainConstM1_MSByte , + SensorCapabilitiesFarSensor_fpSensorAnalogGainConstC1_LSByte , + SensorCapabilitiesFarSensor_fpSensorAnalogGainConstC1_MSByte , + SensorCapabilitiesFarSensor_uwSensorConstantColumns_LSByte , + SensorCapabilitiesFarSensor_uwSensorConstantColumns_MSByte , + SensorCapabilitiesFarSensor_uwStartOfActiveColumns_LSByte , + SensorCapabilitiesFarSensor_uwStartOfActiveColumns_MSByte , + SensorCapabilitiesFarSensor_bActiveColumnDescriptorNumber , + SensorCapabilitiesFarSensor_bSensorStartOfActiveLines , + SensorCapabilitiesFarSensor_uwSensorConstantRows_LSByte , + SensorCapabilitiesFarSensor_uwSensorConstantRows_MSByte , + SensorCapabilitiesFarSensor_uwSensorStatusLines_LSByte, + SensorCapabilitiesFarSensor_uwSensorStatusLines_MSByte , + SensorCapabilitiesFarSensor_bPreActiveDarkLines_LSByte , + SensorCapabilitiesFarSensor_bPreActiveDarkLines_MSByte , + SensorCapabilitiesFarSensor_bPreActiveBlackLines_LSByte , + SensorCapabilitiesFarSensor_bPreActiveBlackLines_MSByte , + SensorCapabilitiesFarSensor_bSensorVFPNLines , + SensorCapabilitiesFarSensor_uwSensorDigitalGainCapability_LSByte , + SensorCapabilitiesFarSensor_uwSensorDigitalGainCapability_MSByte , + SensorCapabilitiesFarSensor_uwSensorDigitalGainMinimum_LSByte , + SensorCapabilitiesFarSensor_uwSensorDigitalGainMinimum_MSByte , + SensorCapabilitiesFarSensor_uwSensorDataPedestal_LSByte , + SensorCapabilitiesFarSensor_uwSensorDataPedestal_MSByte , + + //"SensorCapabilitiesNearSensor//" , + + SensorCapabilitiesNearSensor_uwSensorIntegrationTimeCapability_LSByte , + SensorCapabilitiesNearSensor_uwSensorIntegrationTimeCapability_MSByte , + SensorCapabilitiesNearSensor_uwSensorMinimumCoarseIntegrationLines_LSByte , + SensorCapabilitiesNearSensor_uwSensorMinimumCoarseIntegrationLines_MSByte , + SensorCapabilitiesNearSensor_uwSensorCoarseIntegrationTimeMaxMargin_LSByte , + SensorCapabilitiesNearSensor_uwSensorCoarseIntegrationTimeMaxMargin_MSByte , + SensorCapabilitiesNearSensor_uwSensorMinimumFineIntegrationPixels_LSByte , + SensorCapabilitiesNearSensor_uwSensorMinimumFineIntegrationPixels_MSByte , + SensorCapabilitiesNearSensor_uwSensorFineIntegrationTimeMaxMargin_LSByte , + SensorCapabilitiesNearSensor_uwSensorFineIntegrationTimeMaxMargin_MSByte , + SensorCapabilitiesNearSensor_uwSensorAnalogGainMinimum_LSByte , + SensorCapabilitiesNearSensor_uwSensorAnalogGainMinimum_MSByte , + SensorCapabilitiesNearSensor_uwSensorAnalogGainMaximum_LSByte , + SensorCapabilitiesNearSensor_uwSensorAnalogGainMaximum_MSByte , + SensorCapabilitiesNearSensor_uwSensorAnalogGainCodeStep_LSByte , + SensorCapabilitiesNearSensor_uwSensorAnalogGainCodeStep_MSByte, + SensorCapabilitiesNearSensor_uwSensorAnalogGainType_LSByte , + SensorCapabilitiesNearSensor_uwSensorAnalogGainType_MSByte , + SensorCapabilitiesNearSensor_fpSensorAnalogGainConstM0_LSByte , + SensorCapabilitiesNearSensor_fpSensorAnalogGainConstM0_MSByte , + SensorCapabilitiesNearSensor_fpSensorAnalogGainConstC0_LSByte , + SensorCapabilitiesNearSensor_fpSensorAnalogGainConstC0_MSByte , + SensorCapabilitiesNearSensor_fpSensorAnalogGainConstM1_LSByte , + SensorCapabilitiesNearSensor_fpSensorAnalogGainConstM1_MSByte , + SensorCapabilitiesNearSensor_fpSensorAnalogGainConstC1_LSByte , + SensorCapabilitiesNearSensor_fpSensorAnalogGainConstC1_MSByte , + SensorCapabilitiesNearSensor_uwSensorConstantColumns_LSByte , + SensorCapabilitiesNearSensor_uwSensorConstantColumns_MSByte , + SensorCapabilitiesNearSensor_uwStartOfActiveColumns_LSByte , + SensorCapabilitiesNearSensor_uwStartOfActiveColumns_MSByte , + SensorCapabilitiesNearSensor_bActiveColumnDescriptorNumber , + SensorCapabilitiesNearSensor_bSensorStartOfActiveLines , + SensorCapabilitiesNearSensor_uwSensorConstantRows_LSByte , + SensorCapabilitiesNearSensor_uwSensorConstantRows_MSByte , + SensorCapabilitiesNearSensor_uwSensorStatusLines_LSByte , + SensorCapabilitiesNearSensor_uwSensorStatusLines_MSByte , + SensorCapabilitiesNearSensor_bPreActiveDarkLines_LSByte , + SensorCapabilitiesNearSensor_bPreActiveDarkLines_MSByte , + SensorCapabilitiesNearSensor_bPreActiveBlackLines_LSByte , + SensorCapabilitiesNearSensor_bPreActiveBlackLines_MSByte , + SensorCapabilitiesNearSensor_bSensorVFPNLines , + SensorCapabilitiesNearSensor_uwSensorDigitalGainCapability_LSByte , + SensorCapabilitiesNearSensor_uwSensorDigitalGainCapability_MSByte , + SensorCapabilitiesNearSensor_uwSensorDigitalGainMinimum_LSByte , + SensorCapabilitiesNearSensor_uwSensorDigitalGainMinimum_MSByte , + SensorCapabilitiesNearSensor_uwSensorDataPedestal_LSByte , + SensorCapabilitiesNearSensor_uwSensorDataPedestal_MSByte, + + //"SensorCapabilitiesCurrentSensor//" , + + SensorCapabilitiesCurrentSensor_uwSensorIntegrationTimeCapability_LSByte , + SensorCapabilitiesCurrentSensor_uwSensorIntegrationTimeCapability_MSByte , + SensorCapabilitiesCurrentSensor_uwSensorMinimumCoarseIntegrationLines_LSByte , + SensorCapabilitiesCurrentSensor_uwSensorMinimumCoarseIntegrationLines_MSByte , + SensorCapabilitiesCurrentSensor_uwSensorCoarseIntegrationTimeMaxMargin_LSByte , + SensorCapabilitiesCurrentSensor_uwSensorCoarseIntegrationTimeMaxMargin_MSByte , + SensorCapabilitiesCurrentSensor_uwSensorMinimumFineIntegrationPixels_LSByte , + SensorCapabilitiesCurrentSensor_uwSensorMinimumFineIntegrationPixels_MSByte , + SensorCapabilitiesCurrentSensor_uwSensorFineIntegrationTimeMaxMargin_LSByte , + SensorCapabilitiesCurrentSensor_uwSensorFineIntegrationTimeMaxMargin_MSByte , + SensorCapabilitiesCurrentSensor_uwSensorAnalogGainMinimum_LSByte , + SensorCapabilitiesCurrentSensor_uwSensorAnalogGainMinimum_MSByte , + SensorCapabilitiesCurrentSensor_uwSensorAnalogGainMaximum_LSByte , + SensorCapabilitiesCurrentSensor_uwSensorAnalogGainMaximum_MSByte , + SensorCapabilitiesCurrentSensor_uwSensorAnalogGainCodeStep_LSByte , + SensorCapabilitiesCurrentSensor_uwSensorAnalogGainCodeStep_MSByte , + SensorCapabilitiesCurrentSensor_uwSensorAnalogGainType_LSByte , + SensorCapabilitiesCurrentSensor_uwSensorAnalogGainType_MSByte , + SensorCapabilitiesCurrentSensor_fpSensorAnalogGainConstM0_LSByte , + SensorCapabilitiesCurrentSensor_fpSensorAnalogGainConstM0_MSByte , + SensorCapabilitiesCurrentSensor_fpSensorAnalogGainConstC0_LSByte , + SensorCapabilitiesCurrentSensor_fpSensorAnalogGainConstC0_MSByte , + SensorCapabilitiesCurrentSensor_fpSensorAnalogGainConstM1_LSByte , + SensorCapabilitiesCurrentSensor_fpSensorAnalogGainConstM1_MSByte , + SensorCapabilitiesCurrentSensor_fpSensorAnalogGainConstC1_LSByte , + SensorCapabilitiesCurrentSensor_fpSensorAnalogGainConstC1_MSByte , + SensorCapabilitiesCurrentSensor_uwSensorConstantColumns_LSByte , + SensorCapabilitiesCurrentSensor_uwSensorConstantColumns_MSByte, + SensorCapabilitiesCurrentSensor_uwStartOfActiveColumns_LSByte , + SensorCapabilitiesCurrentSensor_uwStartOfActiveColumns_MSByte , + SensorCapabilitiesCurrentSensor_bActiveColumnDescriptorNumber , + SensorCapabilitiesCurrentSensor_bSensorStartOfActiveLines , + SensorCapabilitiesCurrentSensor_uwSensorConstantRows_LSByte , + SensorCapabilitiesCurrentSensor_uwSensorConstantRows_MSByte , + SensorCapabilitiesCurrentSensor_uwSensorStatusLines_LSByte , + SensorCapabilitiesCurrentSensor_uwSensorStatusLines_MSByte , + SensorCapabilitiesCurrentSensor_bPreActiveDarkLines_LSByte , + SensorCapabilitiesCurrentSensor_bPreActiveDarkLines_MSByte , + SensorCapabilitiesCurrentSensor_bPreActiveBlackLines_LSByte , + SensorCapabilitiesCurrentSensor_bPreActiveBlackLines_MSByte , + SensorCapabilitiesCurrentSensor_bSensorVFPNLines , + SensorCapabilitiesCurrentSensor_uwSensorDigitalGainCapability_LSByte , + SensorCapabilitiesCurrentSensor_uwSensorDigitalGainCapability_MSByte , + SensorCapabilitiesCurrentSensor_uwSensorDigitalGainMinimum_LSByte , + SensorCapabilitiesCurrentSensor_uwSensorDigitalGainMinimum_MSByte , + SensorCapabilitiesCurrentSensor_uwSensorDataPedestal_LSByte , + SensorCapabilitiesCurrentSensor_uwSensorDataPedestal_MSByte , + + //"SensorFrameConstraintsFar//" , + + SensorFrameConstraintsFar_uwVTXAddrMin_LSByte , + SensorFrameConstraintsFar_uwVTXAddrMin_MSByte , + SensorFrameConstraintsFar_uwVTYAddrMin_LSByte , + SensorFrameConstraintsFar_uwVTYAddrMin_MSByte , + SensorFrameConstraintsFar_uwVTXAddrMax_LSByte , + SensorFrameConstraintsFar_uwVTXAddrMax_MSByte , + SensorFrameConstraintsFar_uwVTYAddrMax_LSByte , + SensorFrameConstraintsFar_uwVTYAddrMax_MSByte , + SensorFrameConstraintsFar_uwMinOPXOutputSize_LSByte, + SensorFrameConstraintsFar_uwMinOPXOutputSize_MSByte , + SensorFrameConstraintsFar_uwMinOPYOutputSize_LSByte , + SensorFrameConstraintsFar_uwMinOPYOutputSize_MSByte , + SensorFrameConstraintsFar_uwMaxOPXOutputSize_LSByte , + SensorFrameConstraintsFar_uwMaxOPXOutputSize_MSByte , + SensorFrameConstraintsFar_uwMaxOPYOutputSize_LSByte , + SensorFrameConstraintsFar_uwMaxOPYOutputSize_MSByte , + SensorFrameConstraintsFar_uwMinVTFrameLengthLines_LSByte , + SensorFrameConstraintsFar_uwMinVTFrameLengthLines_MSByte , + SensorFrameConstraintsFar_uwMaxVTFrameLengthLines_LSByte , + SensorFrameConstraintsFar_uwMaxVTFrameLengthLines_MSByte , + SensorFrameConstraintsFar_uwMinVTLineLengthPck_LSByte , + SensorFrameConstraintsFar_uwMinVTLineLengthPck_MSByte , + SensorFrameConstraintsFar_uwMaxVTLineLengthPck_LSByte , + SensorFrameConstraintsFar_uwMaxVTLineLengthPck_MSByte , + SensorFrameConstraintsFar_uwMinVTLineBlankingPck_LSByte , + SensorFrameConstraintsFar_uwMinVTLineBlankingPck_MSByte , + SensorFrameConstraintsFar_uwMinVTFrameBlanking_LSByte , + SensorFrameConstraintsFar_uwMinVTFrameBlanking_MSByte , + + //"SensorFrameConstraintsNear//" , + + SensorFrameConstraintsNear_uwVTXAddrMin_LSByte , + SensorFrameConstraintsNear_uwVTXAddrMin_MSByte , + SensorFrameConstraintsNear_uwVTYAddrMin_LSByte , + SensorFrameConstraintsNear_uwVTYAddrMin_MSByte , + SensorFrameConstraintsNear_uwVTXAddrMax_LSByte , + SensorFrameConstraintsNear_uwVTXAddrMax_MSByte , + SensorFrameConstraintsNear_uwVTYAddrMax_LSByte , + SensorFrameConstraintsNear_uwVTYAddrMax_MSByte , + SensorFrameConstraintsNear_uwMinOPXOutputSize_LSByte, + SensorFrameConstraintsNear_uwMinOPXOutputSize_MSByte , + SensorFrameConstraintsNear_uwMinOPYOutputSize_LSByte , + SensorFrameConstraintsNear_uwMinOPYOutputSize_MSByte , + SensorFrameConstraintsNear_uwMaxOPXOutputSize_LSByte , + SensorFrameConstraintsNear_uwMaxOPXOutputSize_MSByte , + SensorFrameConstraintsNear_uwMaxOPYOutputSize_LSByte , + SensorFrameConstraintsNear_uwMaxOPYOutputSize_MSByte , + SensorFrameConstraintsNear_uwMinVTFrameLengthLines_LSByte , + SensorFrameConstraintsNear_uwMinVTFrameLengthLines_MSByte , + SensorFrameConstraintsNear_uwMaxVTFrameLengthLines_LSByte , + SensorFrameConstraintsNear_uwMaxVTFrameLengthLines_MSByte , + SensorFrameConstraintsNear_uwMinVTLineLengthPck_LSByte , + SensorFrameConstraintsNear_uwMinVTLineLengthPck_MSByte , + SensorFrameConstraintsNear_uwMaxVTLineLengthPck_LSByte , + SensorFrameConstraintsNear_uwMaxVTLineLengthPck_MSByte , + SensorFrameConstraintsNear_uwMinVTLineBlankingPck_LSByte , + SensorFrameConstraintsNear_uwMinVTLineBlankingPck_MSByte , + SensorFrameConstraintsNear_uwMinVTFrameBlanking_LSByte , + SensorFrameConstraintsNear_uwMinVTFrameBlanking_MSByte , + + //"AntiFlickerExposureControls//" , + + AntiFlickerExposureControls_bMainsFrequency_Hz , + AntiFlickerExposureControls_fGuaranteeStaticFlickerFrameLength , + + //"CurrentFrameDimension//" , + + CurrentFrameDimension_uwVTFrameLengthLines_LSByte , + CurrentFrameDimension_uwVTFrameLengthLines_MSByte , + CurrentFrameDimension_uwVTLineLengthPck_LSByte , + CurrentFrameDimension_uwVTLineLengthPck_MSByte, + CurrentFrameDimension_uwVTXAddrStart_LSByte , + CurrentFrameDimension_uwVTXAddrStart_MSByte , + CurrentFrameDimension_uwVTYAddrStart_LSByte , + CurrentFrameDimension_uwVTYAddrStart_MSByte , + CurrentFrameDimension_uwVTXAddrEnd_LSByte , + CurrentFrameDimension_uwVTXAddrEnd_MSByte , + CurrentFrameDimension_uwVTYAddrEnd_LSByte , + CurrentFrameDimension_uwVTYAddrEnd_MSByte , + CurrentFrameDimension_uwOPXOutputSize_LSByte , + CurrentFrameDimension_uwOPXOutputSize_MSByte , + CurrentFrameDimension_uwOPYOutputSize_LSByte , + CurrentFrameDimension_uwOPYOutputSize_MSByte , + CurrentFrameDimension_uwVTXOutputSize_LSByte , + CurrentFrameDimension_uwVTXOutputSize_MSByte , + CurrentFrameDimension_uwVTYOutputSize_LSByte , + CurrentFrameDimension_uwVTYOutputSize_MSByte , + CurrentFrameDimension_bVTXSubSampling , + CurrentFrameDimension_uwXOddInc_LSByte , + CurrentFrameDimension_uwXOddInc_MSByte , + CurrentFrameDimension_bVTYSubSampling , + CurrentFrameDimension_uwYOddInc_LSByte , + CurrentFrameDimension_uwYOddInc_MSByte , + CurrentFrameDimension_bScalingMode , + CurrentFrameDimension_fpScaleFactor_LSByte , + CurrentFrameDimension_fpScaleFactor_MSByte , + CurrentFrameDimension_uwScalerM_LSByte , + CurrentFrameDimension_uwScalerM_MSByte , + + //"SensorFrameConstraints//" , + + SensorFrameConstraints_uwVTXAddrMin_LSByte, + SensorFrameConstraints_uwVTXAddrMin_MSByte , + SensorFrameConstraints_uwVTYAddrMin_LSByte , + SensorFrameConstraints_uwVTYAddrMin_MSByte , + SensorFrameConstraints_uwVTXAddrMax_LSByte , + SensorFrameConstraints_uwVTXAddrMax_MSByte , + SensorFrameConstraints_uwVTYAddrMax_LSByte , + SensorFrameConstraints_uwVTYAddrMax_MSByte , + SensorFrameConstraints_uwMinOPXOutputSize_LSByte , + SensorFrameConstraints_uwMinOPXOutputSize_MSByte , + SensorFrameConstraints_uwMinOPYOutputSize_LSByte , + SensorFrameConstraints_uwMinOPYOutputSize_MSByte , + SensorFrameConstraints_uwMaxOPXOutputSize_LSByte , + SensorFrameConstraints_uwMaxOPXOutputSize_MSByte , + SensorFrameConstraints_uwMaxOPYOutputSize_LSByte , + SensorFrameConstraints_uwMaxOPYOutputSize_MSByte , + SensorFrameConstraints_uwMinVTFrameLengthLines_LSByte , + SensorFrameConstraints_uwMinVTFrameLengthLines_MSByte , + SensorFrameConstraints_uwMaxVTFrameLengthLines_LSByte , + SensorFrameConstraints_uwMaxVTFrameLengthLines_MSByte , + SensorFrameConstraints_uwMinVTLineLengthPck_LSByte , + SensorFrameConstraints_uwMinVTLineLengthPck_MSByte , + SensorFrameConstraints_uwMaxVTLineLengthPck_LSByte , + SensorFrameConstraints_uwMaxVTLineLengthPck_MSByte , + SensorFrameConstraints_uwMinVTLineBlankingPck_LSByte , + SensorFrameConstraints_uwMinVTLineBlankingPck_MSByte , + SensorFrameConstraints_uwMinVTFrameBlanking_LSByte , + SensorFrameConstraints_uwMinVTFrameBlanking_MSByte , + + //"HostFrameConstraints//" , + + HostFrameConstraints_uwMinimumOPLineBlanking_pixels_LSByte, + HostFrameConstraints_uwMinimumOPLineBlanking_pixels_MSByte , + HostFrameConstraints_uwMinimumOPFrameBlanking_lines_LSByte , + HostFrameConstraints_uwMinimumOPFrameBlanking_lines_MSByte , + HostFrameConstraints_bMinimumPostScalar0LineBlanking_pixels , + HostFrameConstraints_bMinimumPostScalar1LineBlanking_pixels , + + //"FrameDimensionStatus//" , + + FrameDimensionStatus_fFrameLengthChangePending , + FrameDimensionStatus_fFrameDimensionChangePending , + FrameDimensionStatus_uwVTFrameLengthPending_lines_LSByte , + FrameDimensionStatus_uwVTFrameLengthPending_lines_MSByte , + FrameDimensionStatus_fFrameLengthChangeInhibitedForCoarseExposure , + FrameDimensionStatus_uwMinVTLineLengthAtCurrentVTXSize_pixels_LSByte , + FrameDimensionStatus_uwMinVTLineLengthAtCurrentVTXSize_pixels_MSByte , + FrameDimensionStatus_uwMinVTFrameLengthAtCurrentVTYSize_lines_LSByte , + FrameDimensionStatus_uwMinVTFrameLengthAtCurrentVTYSize_lines_MSByte , + FrameDimensionStatus_fpVTLineLength_us_LSByte , + FrameDimensionStatus_fpVTLineLength_us_MSByte , + FrameDimensionStatus_fpVTFrameLength_us_LSByte , + FrameDimensionStatus_fpVTFrameLength_us_MSByte , + FrameDimensionStatus_fpCurrentFrameRate_LSByte , + FrameDimensionStatus_fpCurrentFrameRate_MSByte , + FrameDimensionStatus_uwMaximumSensorFOVX_LSByte , + FrameDimensionStatus_uwMaximumSensorFOVX_MSByte , + FrameDimensionStatus_uwMaximumSensorFOVY_LSByte , + FrameDimensionStatus_uwMaximumSensorFOVY_MSByte , + FrameDimensionStatus_uwOPXOutputSize_LSByte , + FrameDimensionStatus_uwOPXOutputSize_MSByte , + FrameDimensionStatus_fSensorPreScaleFactorChanged , + + //"BinningControl//" , + + BinningControl_fEnableBinning , + + //"BinningStatus//" , + + BinningStatus_fBinningEnabled , + + //"Sensor0BinningInputs//" , + + Sensor0BinningInputs_uwMinVTLineLengthPck_LSByte , + Sensor0BinningInputs_uwMinVTLineLengthPck_MSByte , + Sensor0BinningInputs_uwSensorMinimumFineIntegrationPixels_LSByte , + Sensor0BinningInputs_uwSensorMinimumFineIntegrationPixels_MSByte , + + //"Sensor1BinningInputs//" , + + Sensor1BinningInputs_uwMinVTLineLengthPck_LSByte , + Sensor1BinningInputs_uwMinVTLineLengthPck_MSByte , + Sensor1BinningInputs_uwSensorMinimumFineIntegrationPixels_LSByte , + Sensor1BinningInputs_uwSensorMinimumFineIntegrationPixels_MSByte , + + //"CurrentSensorBinningInputs//" , + + CurrentSensorBinningInputs_uwMinVTLineLengthPck_LSByte , + CurrentSensorBinningInputs_uwMinVTLineLengthPck_MSByte , + CurrentSensorBinningInputs_uwSensorMinimumFineIntegrationPixels_LSByte , + CurrentSensorBinningInputs_uwSensorMinimumFineIntegrationPixels_MSByte , + + //"FlashManagerControl//" , + + FlashManagerControl_bMode , + FlashManagerControl_bFlashType , + FlashManagerControl_fOrMainAndPreFlashPulse , + FlashManagerControl_RefPointCalcMode , + FlashManagerControl_wIntegrationStartPosition_LSByte , + FlashManagerControl_wIntegrationStartPosition_MSByte , + FlashManagerControl_fOverrideIntegrationStartPosition , + FlashManagerControl_fpFlashFiringDelay_us_LSByte , + FlashManagerControl_fpFlashFiringDelay_us_MSByte , + FlashManagerControl_bNumberOfPreFlashes , + FlashManagerControl_fpPulseWidthMainFlash_us_LSByte , + FlashManagerControl_fpPulseWidthMainFlash_us_MSByte , + FlashManagerControl_fpPulseWidthPreFlash_us_LSByte , + FlashManagerControl_fpPulseWidthPreFlash_us_MSByte , + FlashManagerControl_fpTimeBetweenTwoPreFlashes_us_LSByte , + FlashManagerControl_fpTimeBetweenTwoPreFlashes_us_MSByte , + FlashManagerControl_fpTimeBetweenPreFlashAndMainFlash_us_LSByte , + FlashManagerControl_fpTimeBetweenPreFlashAndMainFlash_us_MSByte , + FlashManagerControl_cMainFlashStartFrame , + FlashManagerControl_wMainFlashStartLine_LSByte , + FlashManagerControl_wMainFlashStartLine_MSByte , + FlashManagerControl_wMainFlashStartPixel_LSByte , + FlashManagerControl_wMainFlashStartPixel_MSByte , + FlashManagerControl_cPreFlashStartFrame , + FlashManagerControl_wPreFlashStartLine_LSByte , + FlashManagerControl_wPreFlashStartLine_MSByte , + FlashManagerControl_wPreFlashStartPixel_LSByte , + FlashManagerControl_wPreFlashStartPixel_MSByte , + FlashManagerControl_bTotalFramesRequired , + + //"FlashManagerStatus//" + + FlashManagerStatus_fFlashSequencePending , + FlashManagerStatus_cNumberFramesRequiredForPreFlashes , + FlashManagerStatus_fpMainFlashPulseWidth_us_LSByte , + FlashManagerStatus_fpMainFlashPulseWidth_us_MSByte , + FlashManagerStatus_fpPreFlashPulseWidth_us_LSByte , + FlashManagerStatus_fpPreFlashPulseWidth_us_MSByte , + FlashManagerStatus_fpInterPreflashDistance_us_LSByte , + FlashManagerStatus_fpInterPreflashDistance_us_MSByte , + FlashManagerStatus_fpPreAndMainflashDistance_us_LSByte , + FlashManagerStatus_fpPreAndMainflashDistance_us_MSByte , + FlashManagerStatus_cStartFlashFrame , + FlashManagerStatus_wStartFlashLine_LSByte , + FlashManagerStatus_wStartFlashLine_MSByte , + FlashManagerStatus_wStartFlashPixel_LSByte , + FlashManagerStatus_wStartFlashPixel_MSByte , + FlashManagerStatus_cStartPreFlashFrame , + FlashManagerStatus_wStartPreFlashLine_LSByte , + FlashManagerStatus_wStartPreFlashLine_MSByte , + FlashManagerStatus_wStartPreFlashPixel_LSByte , + FlashManagerStatus_wStartPreFlashPixel_MSByte , + FlashManagerStatus_cNumberFramesRequired , + FlashManagerStatus_fPreFlashPending , + FlashManagerStatus_fMainFlashPending , + + //"ExposureControls//" , + + ExposureControls_bMode , + ExposureControls_bMetering , + ExposureControls_bManualExposureTime_s_num , + ExposureControls_bManualExposureTime_s_den, + ExposureControls_fpManualDesiredExposureTime_us_LSByte , + ExposureControls_fpManualDesiredExposureTime_us_MSByte , + ExposureControls_fpColdStartDesiredTime_us_LSByte , + ExposureControls_fpColdStartDesiredTime_us_MSByte , + ExposureControls_iExposureCompensation , + ExposureControls_bMiscSettings , + ExposureControls_uwDirectModeCoarseIntegration_lines_LSByte , + ExposureControls_uwDirectModeCoarseIntegration_lines_MSByte , + ExposureControls_uwDirectModeFineIntegration_pixels_LSByte , + ExposureControls_uwDirectModeFineIntegration_pixels_MSByte , + ExposureControls_uwDirectModeCodedAnalogGain_LSByte , + ExposureControls_uwDirectModeCodedAnalogGain_MSByte , + ExposureControls_fpDirectModeDigitalGain_LSByte , + ExposureControls_fpDirectModeDigitalGain_MSByte , + ExposureControls_uwFlashGunModeCoarseIntegration_lines_LSByte , + ExposureControls_uwFlashGunModeCoarseIntegration_lines_MSByte , + ExposureControls_uwFlashGunModeFineIntegration_pixels_LSByte , + ExposureControls_uwFlashGunModeFineIntegration_pixels_MSByte , + ExposureControls_uwFlashGunModeCodedAnalogGain_LSByte , + ExposureControls_uwFlashGunModeCodedAnalogGain_MSByte , + ExposureControls_fpFlashGunModeDigitalGain_LSByte , + ExposureControls_fpFlashGunModeDigitalGain_MSByte , + ExposureControls_fFreezeAutoExposure , + ExposureControls_fpUserMaximumIntegrationTime_us_LSByte , + ExposureControls_fpUserMaximumIntegrationTime_us_MSByte , + ExposureControls_fpRecommendFlashGunAnalogGainThreshold_LSByte , + ExposureControls_fpRecommendFlashGunAnalogGainThreshold_MSByte , + ExposureControls_fEnableHighClipForDesiredExposureTime , + ExposureControls_bAntiFlickerMode , + ExposureControls_fInhibitExposurePresetModeForFlash , + + //"ExposureStatus//" , + + ExposureStatus_bAlgorithmStatus , + ExposureStatus_bCompilerStatus , + ExposureStatus_fWhiteBalanceGainIncludedInCurrentExposure , + ExposureStatus_fBadExposureForIterativeWhiteBalance , + ExposureStatus_uwCoarseIntegrationPending_lines_LSByte , + ExposureStatus_uwCoarseIntegrationPending_lines_MSByte , + ExposureStatus_uwFineIntegrationPending_pixels_LSByte , + ExposureStatus_uwFineIntegrationPending_pixels_MSByte , + ExposureStatus_fpAnalogGainPending_LSByte , + ExposureStatus_fpAnalogGainPending_MSByte , + ExposureStatus_fpDigitalGainPending_LSByte , + ExposureStatus_fpDigitalGainPending_MSByte , + ExposureStatus_fpDesiredExposureTime_us_LSByte , + ExposureStatus_fpDesiredExposureTime_us_MSByte , + ExposureStatus_fpCompiledExposureTime_us_LSByte , + ExposureStatus_fpCompiledExposureTime_us_MSByte , + ExposureStatus_bControlLoopFailureCount , + ExposureStatus_uwUserMaximumIntegrationLines_LSByte , + ExposureStatus_uwUserMaximumIntegrationLines_MSByte , + ExposureStatus_fpTotalIntegrationTimePending_us_LSByte , + ExposureStatus_fpTotalIntegrationTimePending_us_MSByte , + ExposureStatus_uwCodedAnalogGainPending_LSByte , + ExposureStatus_uwCodedAnalogGainPending_MSByte , + ExposureStatus_fExposureIsStableforAutoFocus , + ExposureStatus_bRuntimeExposureTarget , + + //"ExposureParametersApplied//" , + + ExposureParametersApplied_uwCoarseIntegration_lines_LSByte, + ExposureParametersApplied_uwCoarseIntegration_lines_MSByte , + ExposureParametersApplied_uwFineIntegration_pixels_LSByte , + ExposureParametersApplied_uwFineIntegration_pixels_MSByte , + ExposureParametersApplied_uwCodedAnalogGain_LSByte , + ExposureParametersApplied_uwCodedAnalogGain_MSByte , + ExposureParametersApplied_fpDigitalGain_LSByte , + ExposureParametersApplied_fpDigitalGain_MSByte , + + //"ExposureStatisticsStatus//" , + + ExposureStatisticsStatus_fpMeanEnergy_LSByte , + ExposureStatisticsStatus_fpMeanEnergy_MSByte , + + //"ExposureCycleTest//" , + + ExposureCycleTest_fpInitialDesiredExposureTime_LSByte , + ExposureCycleTest_fpInitialDesiredExposureTime_MSByte , + ExposureCycleTest_fpFinalDesiredExposureTime_LSByte , + ExposureCycleTest_fpFinalDesiredExposureTime_MSByte , + ExposureCycleTest_fpExposureStep_LSByte , + ExposureCycleTest_fpExposureStep_MSByte , + ExposureCycleTest_bStepDirection , + + //"ExposureTestCoin//" , + + ExposureTestCoin_fTestCoinEnabled , + ExposureTestCoin_fRunForTest , + ExposureTestCoin_bStatusCoin , + ExposureTestCoin_bControlCoin , + + //"ExposureAlgorithmControls//" + + ExposureAlgorithmControls_fpMaximumStep_LSByte , + ExposureAlgorithmControls_fpMaximumStep_MSByte , + ExposureAlgorithmControls_fpMinimumStep_LSByte , + ExposureAlgorithmControls_fpMinimumStep_MSByte , + ExposureAlgorithmControls_fpMinimumDesiredExposureTime_us_LSByte , + ExposureAlgorithmControls_fpMinimumDesiredExposureTime_us_MSByte , + ExposureAlgorithmControls_fpStepProportion_LSByte , + ExposureAlgorithmControls_fpStepProportion_MSByte , + ExposureAlgorithmControls_fpMaximumNegativeStepThreshold_LSByte , + ExposureAlgorithmControls_fpMaximumNegativeStepThreshold_MSByte , + ExposureAlgorithmControls_fpRelativeOnTargetStabilityThreshold_LSByte , + ExposureAlgorithmControls_fpRelativeOnTargetStabilityThreshold_MSByte , + ExposureAlgorithmControls_fpDigitalGainFloor_LSByte , + ExposureAlgorithmControls_fpDigitalGainFloor_MSByte , + ExposureAlgorithmControls_fpDigitalGainCeiling_LSByte , + ExposureAlgorithmControls_fpDigitalGainCeiling_MSByte , + ExposureAlgorithmControls_fpRelativeIntTimeHysThreshold_LSByte , + ExposureAlgorithmControls_fpRelativeIntTimeHysThreshold_MSByte , + ExposureAlgorithmControls_fpRelativeDigitalGainHysThreshold_LSByte , + ExposureAlgorithmControls_fpRelativeDigitalGainHysThreshold_MSByte , + ExposureAlgorithmControls_fpRelativeCompilationProblemThreshold_LSByte , + ExposureAlgorithmControls_fpRelativeCompilationProblemThreshold_MSByte , + ExposureAlgorithmControls_fpRoundUpBunchFudge_LSByte , + ExposureAlgorithmControls_fpRoundUpBunchFudge_MSByte , + ExposureAlgorithmControls_fpFineClampThreshold_LSByte , + ExposureAlgorithmControls_fpFineClampThreshold_MSByte , + ExposureAlgorithmControls_fpMaximumManualExposureTime_s_LSByte , + ExposureAlgorithmControls_fpMaximumManualExposureTime_s_MSByte , + ExposureAlgorithmControls_fpRelativeStabilityThresholdForAutoFocus_LSByte , + ExposureAlgorithmControls_fpRelativeStabilityThresholdForAutoFocus_MSByte, + ExposureAlgorithmControls_bLeakShift , + + //"ExposureAlgorithmStatus//" , + + ExposureAlgorithmStatus_fpLeakyEnergy_LSByte , + ExposureAlgorithmStatus_fpLeakyEnergy_MSByte , + ExposureAlgorithmStatus_fpRelativeStep_LSByte , + ExposureAlgorithmStatus_fpRelativeStep_MSByte , + + //"ExposureUpdateErrorControl//" , + + ExposureUpdateErrorControl_bMaximumNumberOfFrames , + + //"ExposureUpdateErrorStatus//" , + + ExposureUpdateErrorStatus_bNumberOfForcedInputProcUpdates , + ExposureUpdateErrorStatus_bNumberOfConsecutiveDelayedFrames , + ExposureUpdateErrorStatus_fForceInputProcUpdation , + + //"WhiteBalanceControls//" , + + WhiteBalanceControls_bMode , + WhiteBalanceControls_bManualRedGain , + WhiteBalanceControls_bManualGreenGain , + WhiteBalanceControls_bManualBlueGain , + WhiteBalanceControls_bMiscSettings , + WhiteBalanceControls_fpFlashRedGain_LSByte , + WhiteBalanceControls_fpFlashRedGain_MSByte , + WhiteBalanceControls_fpFlashGreenGain_LSByte , + WhiteBalanceControls_fpFlashGreenGain_MSByte , + WhiteBalanceControls_fpFlashBlueGain_LSByte, + WhiteBalanceControls_fpFlashBlueGain_MSByte , + WhiteBalanceControls_fInhibitWhiteBalancePresetModeForFlash , + + //"WhiteBalanceAlgorithmControls//" , + + WhiteBalanceAlgorithmControls_fpStableTotalStepThreshold_LSByte , + WhiteBalanceAlgorithmControls_fpStableTotalStepThreshold_MSByte , + WhiteBalanceAlgorithmControls_fpMinimumRelativeStep_LSByte , + WhiteBalanceAlgorithmControls_fpMinimumRelativeStep_MSByte , + WhiteBalanceAlgorithmControls_fpMaximumRelativeStep_LSByte , + WhiteBalanceAlgorithmControls_fpMaximumRelativeStep_MSByte , + WhiteBalanceAlgorithmControls_fpStepProportion_LSByte , + WhiteBalanceAlgorithmControls_fpStepProportion_MSByte , + + //"WhiteBalanceStatus//" , + + WhiteBalanceStatus_bStatus , + WhiteBalanceStatus_fUnityGainsUsed , + WhiteBalanceStatus_fpRedGain_LSByte , + WhiteBalanceStatus_fpRedGain_MSByte , + WhiteBalanceStatus_fpGreenGain_LSByte , + WhiteBalanceStatus_fpGreenGain_MSByte , + WhiteBalanceStatus_fpBlueGain_LSByte , + WhiteBalanceStatus_fpBlueGain_MSByte , + + //"WhiteBalanceStatisticsControls//" , + + WhiteBalanceStatisticsControls_bLowThreshold , + + //"WhiteBalanceStatisticsStatus//" , + + WhiteBalanceStatisticsStatus_fpRedEnergy_LSByte , + WhiteBalanceStatisticsStatus_fpRedEnergy_MSByte , + WhiteBalanceStatisticsStatus_fpGreenEnergy_LSByte , + WhiteBalanceStatisticsStatus_fpGreenEnergy_MSByte , + WhiteBalanceStatisticsStatus_fpBlueEnergy_LSByte , + WhiteBalanceStatisticsStatus_fpBlueEnergy_MSByte , + + //"MinWeightedWBControls//" , + + MinWeightedWBControls_fDisable , + MinWeightedWBControls_uwSaturationThreshold_LSByte , + MinWeightedWBControls_uwSaturationThreshold_MSByte , + MinWeightedWBControls_fpRedTiltGain_LSByte , + MinWeightedWBControls_fpRedTiltGain_MSByte , + MinWeightedWBControls_fpGreen1TiltGain_LSByte , + MinWeightedWBControls_fpGreen1TiltGain_MSByte , + MinWeightedWBControls_fpGreen2TiltGain_LSByte , + MinWeightedWBControls_fpGreen2TiltGain_MSByte , + MinWeightedWBControls_fpBlueTiltGain_LSByte , + MinWeightedWBControls_fpBlueTiltGain_MSByte , + MinWeightedWBControls_GreenChannelToAccumulate , + + //"MinWeightedWBStatus//" , + + MinWeightedWBStatus_uwZone_X_Offset_LSByte , + MinWeightedWBStatus_uwZone_X_Offset_MSByte , + MinWeightedWBStatus_uwZone_Y_Offset_LSByte , + MinWeightedWBStatus_uwZone_Y_Offset_MSByte , + MinWeightedWBStatus_uwZone_X_Size_LSByte , + MinWeightedWBStatus_uwZone_X_Size_MSByte , + MinWeightedWBStatus_uwZone_Y_Size_LSByte, + MinWeightedWBStatus_uwZone_Y_Size_MSByte , + MinWeightedWBStatus_fpNumberMacroPixel_LSByte , + MinWeightedWBStatus_fpNumberMacroPixel_MSByte , + + //"MWWBStatisticsStatus//" , + + MWWBStatisticsStatus_fpRedStatistics_LSByte , + MWWBStatisticsStatus_fpRedStatistics_MSByte , + MWWBStatisticsStatus_fpGreenStatistics_LSByte , + MWWBStatisticsStatus_fpGreenStatistics_MSByte , + MWWBStatisticsStatus_fpBlueStatistics_LSByte , + MWWBStatisticsStatus_fpBlueStatistics_MSByte , + + //"MiscellaneousErrorStatus//" , + + MiscellaneousErrorStatus_bNumberOfEWBStatisticsErrors , + MiscellaneousErrorStatus_bEWBStatisticsInterruptCount , + + //"AutomaticFrameRateControl//" , + + AutomaticFrameRateControl_bMode , + AutomaticFrameRateControl_bImpliedGainThresholdLow_num , + AutomaticFrameRateControl_bImpliedGainThresholdLow_den , + AutomaticFrameRateControl_bImpliedGainThresholdHigh_num , + AutomaticFrameRateControl_bImpliedGainThresholdHigh_den , + AutomaticFrameRateControl_bUserMinimumFrameRate_Hz , + AutomaticFrameRateControl_bUserMaximumFrameRate_Hz , + AutomaticFrameRateControl_bRelativeChange_num , + AutomaticFrameRateControl_bRelativeChange_den , + AutomaticFrameRateControl_fDivorceMinFrameRateFromMaxIntegration , + + //"AutomaticFrameRateStatus//" , + + AutomaticFrameRateStatus_fpImpliedGain_LSByte , + AutomaticFrameRateStatus_fpImpliedGain_MSByte , + AutomaticFrameRateStatus_uwMaximumFrameLength_lines_LSByte , + AutomaticFrameRateStatus_uwMaximumFrameLength_lines_MSByte , + AutomaticFrameRateStatus_uwMinimumFrameLength_lines_LSByte , + AutomaticFrameRateStatus_uwMinimumFrameLength_lines_MSByte , + AutomaticFrameRateStatus_uwFrameLengthChange_lines_LSByte , + AutomaticFrameRateStatus_uwFrameLengthChange_lines_MSByte , + AutomaticFrameRateStatus_fpDesiredAutomaticFrameRate_Hz_LSByte , + AutomaticFrameRateStatus_fpDesiredAutomaticFrameRate_Hz_MSByte , + AutomaticFrameRateStatus_uwCurrentFrameLength_lines_LSByte , + AutomaticFrameRateStatus_uwCurrentFrameLength_lines_MSByte , + AutomaticFrameRateStatus_uwDesiredFrameLength_lines_LSByte , + AutomaticFrameRateStatus_uwDesiredFrameLength_lines_MSByte , + AutomaticFrameRateStatus_fAutomaticFrameRateStable , + AutomaticFrameRateStatus_fAutomaticFrameRateClip , + + //"StaticFrameRateControl//" , + + StaticFrameRateControl_uwDesiredFrameRate_Num_LSByte , + StaticFrameRateControl_uwDesiredFrameRate_Num_MSByte , + StaticFrameRateControl_bDesiredFrameRate_Den , + + //"StaticFrameRateStatus//" , + + StaticFrameRateStatus_uwRequestedFrameRate_Hz_LSByte , + StaticFrameRateStatus_uwRequestedFrameRate_Hz_MSByte , + StaticFrameRateStatus_uwMaxFrameRate_Hz_LSByte , + StaticFrameRateStatus_uwMaxFrameRate_Hz_MSByte, + StaticFrameRateStatus_uwMinFrameRate_Hz_LSByte , + StaticFrameRateStatus_uwMinFrameRate_Hz_MSByte , + StaticFrameRateStatus_fChangePending , + StaticFrameRateStatus_uwRequiredFrameLength_lines_LSByte , + StaticFrameRateStatus_uwRequiredFrameLength_lines_MSByte , + StaticFrameRateStatus_ClipFrameRate , + + //"ImageStability//" , + + ImageStability_fWhiteBalanceStable , + ImageStability_fExposureStable , + ImageStability_fFocusStable , + ImageStability_fLowPowerStreaming , + ImageStability_fStable , + ImageStability_fForcedStablility , + + //"ImageStabilityMonitorControl//" , + + ImageStabilityMonitorControl_bMaxNumberOfFramesToWaitForStability , + + //"ColdStartManagerControl//" , + + ColdStartManagerControl_bControlCoin , + + //"ColdStartManagerStatus//" , + + ColdStartManagerStatus_bStatusCoin , + + //"ColourEngine0_ColourMatrixFarSensor//" , + + ColourEngine0_ColourMatrixFarSensor_fpRInR_LSByte, + ColourEngine0_ColourMatrixFarSensor_fpRInR_MSByte , + ColourEngine0_ColourMatrixFarSensor_fpGInR_LSByte , + ColourEngine0_ColourMatrixFarSensor_fpGInR_MSByte , + ColourEngine0_ColourMatrixFarSensor_fpBInR_LSByte , + ColourEngine0_ColourMatrixFarSensor_fpBInR_MSByte , + ColourEngine0_ColourMatrixFarSensor_fpRInG_LSByte , + ColourEngine0_ColourMatrixFarSensor_fpRInG_MSByte , + ColourEngine0_ColourMatrixFarSensor_fpGInG_LSByte , + ColourEngine0_ColourMatrixFarSensor_fpGInG_MSByte , + ColourEngine0_ColourMatrixFarSensor_fpBInG_LSByte , + ColourEngine0_ColourMatrixFarSensor_fpBInG_MSByte , + ColourEngine0_ColourMatrixFarSensor_fpRInB_LSByte , + ColourEngine0_ColourMatrixFarSensor_fpRInB_MSByte , + ColourEngine0_ColourMatrixFarSensor_fpGInB_LSByte , + ColourEngine0_ColourMatrixFarSensor_fpGInB_MSByte , + ColourEngine0_ColourMatrixFarSensor_fpBInB_LSByte , + ColourEngine0_ColourMatrixFarSensor_fpBInB_MSByte , + + //"ColourEngine0_ColourMatrixNearSensor//" , + + ColourEngine0_ColourMatrixNearSensor_fpRInR_LSByte , + ColourEngine0_ColourMatrixNearSensor_fpRInR_MSByte , + ColourEngine0_ColourMatrixNearSensor_fpGInR_LSByte , + ColourEngine0_ColourMatrixNearSensor_fpGInR_MSByte , + ColourEngine0_ColourMatrixNearSensor_fpBInR_LSByte , + ColourEngine0_ColourMatrixNearSensor_fpBInR_MSByte , + ColourEngine0_ColourMatrixNearSensor_fpRInG_LSByte , + ColourEngine0_ColourMatrixNearSensor_fpRInG_MSByte , + ColourEngine0_ColourMatrixNearSensor_fpGInG_LSByte , + ColourEngine0_ColourMatrixNearSensor_fpGInG_MSByte , + ColourEngine0_ColourMatrixNearSensor_fpBInG_LSByte, + ColourEngine0_ColourMatrixNearSensor_fpBInG_MSByte , + ColourEngine0_ColourMatrixNearSensor_fpRInB_LSByte , + ColourEngine0_ColourMatrixNearSensor_fpRInB_MSByte , + ColourEngine0_ColourMatrixNearSensor_fpGInB_LSByte , + ColourEngine0_ColourMatrixNearSensor_fpGInB_MSByte , + ColourEngine0_ColourMatrixNearSensor_fpBInB_LSByte , + ColourEngine0_ColourMatrixNearSensor_fpBInB_MSByte , + + //"ColourEngine0_ColourMatrixDamped//" , + + ColourEngine0_ColourMatrixDamped_wRInR_LSByte , + ColourEngine0_ColourMatrixDamped_wRInR_MSByte , + ColourEngine0_ColourMatrixDamped_wGInR_LSByte , + ColourEngine0_ColourMatrixDamped_wGInR_MSByte , + ColourEngine0_ColourMatrixDamped_wBInR_LSByte , + ColourEngine0_ColourMatrixDamped_wBInR_MSByte , + ColourEngine0_ColourMatrixDamped_wRInG_LSByte , + ColourEngine0_ColourMatrixDamped_wRInG_MSByte , + ColourEngine0_ColourMatrixDamped_wGInG_LSByte , + ColourEngine0_ColourMatrixDamped_wGInG_MSByte , + ColourEngine0_ColourMatrixDamped_wBInG_LSByte , + ColourEngine0_ColourMatrixDamped_wBInG_MSByte , + ColourEngine0_ColourMatrixDamped_wRInB_LSByte , + ColourEngine0_ColourMatrixDamped_wRInB_MSByte , + ColourEngine0_ColourMatrixDamped_wGInB_LSByte , + ColourEngine0_ColourMatrixDamped_wGInB_MSByte , + ColourEngine0_ColourMatrixDamped_wBInB_LSByte , + ColourEngine0_ColourMatrixDamped_wBInB_MSByte , + + //"ColourEngine0_ColourMatrixDamperControl//" , + + ColourEngine0_ColourMatrixDamperControl_fDisableMatrixDamping , + ColourEngine0_ColourMatrixDamperControl_DamperLowThreshold_LSByte , + ColourEngine0_ColourMatrixDamperControl_DamperLowThreshold_MSByte , + ColourEngine0_ColourMatrixDamperControl_DamperHighThreshold_LSByte , + ColourEngine0_ColourMatrixDamperControl_DamperHighThreshold_MSByte , + ColourEngine0_ColourMatrixDamperControl_MinimumDamperOutput_LSByte , + ColourEngine0_ColourMatrixDamperControl_MinimumDamperOutput_MSByte , + + //"ColourEngine0_ApertureCorrectionControls//" , + + ColourEngine0_ApertureCorrectionControls_fDisableCorrection , + ColourEngine0_ApertureCorrectionControls_bMaxGain , + ColourEngine0_ApertureCorrectionControls_fDisableGainDamping , + ColourEngine0_ApertureCorrectionControls_DamperLowThreshold_Gain_LSByte , + ColourEngine0_ApertureCorrectionControls_DamperLowThreshold_Gain_MSByte , + ColourEngine0_ApertureCorrectionControls_DamperHighThreshold_Gain_LSByte , + ColourEngine0_ApertureCorrectionControls_DamperHighThreshold_Gain_MSByte , + ColourEngine0_ApertureCorrectionControls_MinimumDamperOutput_Gain_LSByte , + ColourEngine0_ApertureCorrectionControls_MinimumDamperOutput_Gain_MSByte , + ColourEngine0_ApertureCorrectionControls_bMinimumCoringThreshold , + ColourEngine0_ApertureCorrectionControls_fDisableCoringDamping , + ColourEngine0_ApertureCorrectionControls_bMinimumHighThreshold , + ColourEngine0_ApertureCorrectionControls_DamperLowThreshold_Coring_LSByte , + ColourEngine0_ApertureCorrectionControls_DamperLowThreshold_Coring_MSByte , + ColourEngine0_ApertureCorrectionControls_DamperHighThreshold_Coring_LSByte , + ColourEngine0_ApertureCorrectionControls_DamperHighThreshold_Coring_MSByte , + ColourEngine0_ApertureCorrectionControls_MinimumDamperOutput_Coring_LSByte , + ColourEngine0_ApertureCorrectionControls_MinimumDamperOutput_Coring_MSByte , + + //"ColourEngine0_ApertureCorrectionStatus//" , + + ColourEngine0_ApertureCorrectionStatus_bGain , + ColourEngine0_ApertureCorrectionStatus_HighThreshold , + ColourEngine0_ApertureCorrectionStatus_CoringThreshold , + + //"ColourEngine0_GammaCorrection//" , + + ColourEngine0_GammaCorrection_fEnabled , + ColourEngine0_GammaCorrection_bMode , + ColourEngine0_GammaCorrection_SharpRed , + ColourEngine0_GammaCorrection_SharpGreen , + ColourEngine0_GammaCorrection_SharpBlue , + ColourEngine0_GammaCorrection_SoftRed , + ColourEngine0_GammaCorrection_SoftGreen , + ColourEngine0_GammaCorrection_SoftBlue , + + //"NoraControls//" , + + NoraControls_fDisable , + NoraControls_fDisableNoraPromoting , + NoraControls_bMaximumValue , + NoraControls_fDifferentTextureDegreeForBlue , + NoraControls_fSplitNoiseLevel , + NoraControls_fTightGreenMatrix , + NoraControls_DamperLowThreshold_LSByte , + NoraControls_DamperLowThreshold_MSByte , + NoraControls_DamperHighThreshold_LSByte , + NoraControls_DamperHighThreshold_MSByte , + NoraControls_MinimumDamperOutput_LSByte , + NoraControls_MinimumDamperOutput_MSByte , + + //"NoraStatus//" + + NoraStatus_bNoraValue , + + //"ScytheFilterControls//" , + + ScytheFilterControls_fDisableFilter , + ScytheFilterControls_fSquareLaw , + ScytheFilterControls_fDisablePromotingLow , + ScytheFilterControls_fDisablePromotingHigh , + ScytheFilterControls_bMaxWeightLow , + ScytheFilterControls_bMaxWeightHigh , + ScytheFilterControls_fpDamperLowThresholdLow_LSByte , + ScytheFilterControls_fpDamperLowThresholdLow_MSByte , + ScytheFilterControls_fpDamperLowThresholdHigh_LSByte , + ScytheFilterControls_fpDamperLowThresholdHigh_MSByte , + ScytheFilterControls_fpDamperHighThresholdLow_LSByte , + ScytheFilterControls_fpDamperHighThresholdLow_MSByte , + ScytheFilterControls_fpDamperHighThresholdHigh_LSByte , + ScytheFilterControls_fpDamperHighThresholdHigh_MSByte , + ScytheFilterControls_fpMinimumDamperOutputLow_LSByte , + ScytheFilterControls_fpMinimumDamperOutputLow_MSByte , + ScytheFilterControls_fpMinimumDamperOutputHigh_LSByte , + ScytheFilterControls_fpMinimumDamperOutputHigh_MSByte , + + //"JackFilterControls//" , + + JackFilterControls_fDisableFilter , + JackFilterControls_fSquareLaw , + JackFilterControls_fDisablePromotingLow , + JackFilterControls_fDisablePromotingHigh , + JackFilterControls_bMaxWeightLow, + JackFilterControls_bMaxWeightHigh , + JackFilterControls_fpDamperLowThresholdLow_LSByte , + JackFilterControls_fpDamperLowThresholdLow_MSByte , + JackFilterControls_fpDamperLowThresholdHigh_LSByte , + JackFilterControls_fpDamperLowThresholdHigh_MSByte , + JackFilterControls_fpDamperHighThresholdLow_LSByte , + JackFilterControls_fpDamperHighThresholdLow_MSByte , + JackFilterControls_fpDamperHighThresholdHigh_LSByte , + JackFilterControls_fpDamperHighThresholdHigh_MSByte , + JackFilterControls_fpMinimumDamperOutputLow_LSByte , + JackFilterControls_fpMinimumDamperOutputLow_MSByte , + JackFilterControls_fpMinimumDamperOutputHigh_LSByte , + JackFilterControls_fpMinimumDamperOutputHigh_MSByte , + + //"ScytheAndJackFilterStatus//" , + + ScytheAndJackFilterStatus_bScytheWeightLo , + ScytheAndJackFilterStatus_bScytheWeightHi , + ScytheAndJackFilterStatus_bJackWeightLo , + ScytheAndJackFilterStatus_bJackWeightHi , + + //"VfpnControls//" , + + VfpnControls_fEnableCorrection , + VfpnControls_uwMaximumPixelValue_LSByte , + VfpnControls_uwMaximumPixelValue_MSByte , + VfpnControls_uwMinimumPixelValue_LSByte , + VfpnControls_uwMinimumPixelValue_MSByte , + VfpnControls_uwPixelSaturationLevel_LSByte , + VfpnControls_uwPixelSaturationLevel_MSByte , + VfpnControls_bLogThreshLog, + + //"VfpnStatus//" , + + VfpnStatus_fLowPowerStreaming , + VfpnStatus_fVfpnGainChanged , + VfpnStatus_bNumberOfBlackLines , + VfpnStatus_uwNumberOfActivePixels_LSByte , + VfpnStatus_uwNumberOfActivePixels_MSByte , + + //"AntiVignetteControls//" , + + AntiVignetteControls_fDisableFilter , + AntiVignetteControls_bFilterCoeff_R2_r , + AntiVignetteControls_bFilterCoeff_R2_gr , + AntiVignetteControls_bFilterCoeff_R2_gb , + AntiVignetteControls_bFilterCoeff_R2_b , + AntiVignetteControls_bFilterCoeff_R4_r , + AntiVignetteControls_bFilterCoeff_R4_gr , + AntiVignetteControls_bFilterCoeff_R4_gb , + AntiVignetteControls_bFilterCoeff_R4_b , + AntiVignetteControls_uwHorizontalOffset_LSByte , + AntiVignetteControls_uwHorizontalOffset_MSByte , + AntiVignetteControls_uwVerticalOffset_LSByte , + AntiVignetteControls_uwVerticalOffset_MSByte , + AntiVignetteControls_fAVOffsetSeperateFor4Channels , + AntiVignetteControls_bShiftFix_R2 , + AntiVignetteControls_uwHorizontalOffset_r_LSByte , + AntiVignetteControls_uwHorizontalOffset_r_MSByte , + AntiVignetteControls_uwHorizontalOffset_gr_LSByte , + AntiVignetteControls_uwHorizontalOffset_gr_MSByte , + AntiVignetteControls_uwHorizontalOffset_gb_LSByte, + AntiVignetteControls_uwHorizontalOffset_gb_MSByte , + AntiVignetteControls_uwHorizontalOffset_b_LSByte , + AntiVignetteControls_uwHorizontalOffset_b_MSByte , + AntiVignetteControls_uwVerticalOffset_r_LSByte , + AntiVignetteControls_uwVerticalOffset_r_MSByte , + AntiVignetteControls_uwVerticalOffset_gr_LSByte , + AntiVignetteControls_uwVerticalOffset_gr_MSByte , + AntiVignetteControls_uwVerticalOffset_gb_LSByte , + AntiVignetteControls_uwVerticalOffset_gb_MSByte , + AntiVignetteControls_uwVerticalOffset_b_LSByte , + AntiVignetteControls_uwVerticalOffset_b_MSByte , + AntiVignetteControls_bUnityOffset_r , + AntiVignetteControls_bUnityOffset_gr , + AntiVignetteControls_bUnityOffset_gb , + AntiVignetteControls_bUnityOffset_b , + AntiVignetteControls_fAdaptiveAntiVignetteEnable , + + //"AntiVignetteStatus//" , + + AntiVignetteStatus_fXScaleEnabled , + AntiVignetteStatus_bXScale , + AntiVignetteStatus_fYScaleEnabled , + AntiVignetteStatus_bYScale , + AntiVignetteStatus_uwHorizontalSize_LSByte , + AntiVignetteStatus_uwHorizontalSize_MSByte , + AntiVignetteStatus_uwVerticalSize_LSByte , + AntiVignetteStatus_uwVerticalSize_MSByte , + + //"ColourEngine0_RadialApertureCorrectionControl//" , + + ColourEngine0_RadialApertureCorrectionControl_fEnableCorrection, + + //"ColourEngine0_RadialApertureCorrectionHostInputs//" , + + ColourEngine0_RadialApertureCorrectionHostInputs_bQvec0 , + ColourEngine0_RadialApertureCorrectionHostInputs_bQvec1 , + ColourEngine0_RadialApertureCorrectionHostInputs_bCofShift , + ColourEngine0_RadialApertureCorrectionHostInputs_bOutShift , + ColourEngine0_RadialApertureCorrectionHostInputs_uwUnity_LSByte , + ColourEngine0_RadialApertureCorrectionHostInputs_uwUnity_MSByte , + + //"ColourEngine0_RadialApertureCorrectionApplicationInputs//" , + + ColourEngine0_RadialApertureCorrectionApplicationInputs_uwHOffset_LSByte , + ColourEngine0_RadialApertureCorrectionApplicationInputs_uwHOffset_MSByte , + ColourEngine0_RadialApertureCorrectionApplicationInputs_uwVOffset_LSByte , + ColourEngine0_RadialApertureCorrectionApplicationInputs_uwVOffset_MSByte , + ColourEngine0_RadialApertureCorrectionApplicationInputs_uwHScalingFactor_LSByte , + ColourEngine0_RadialApertureCorrectionApplicationInputs_uwHScalingFactor_MSByte , + ColourEngine0_RadialApertureCorrectionApplicationInputs_uwVScalingFactor_LSByte , + ColourEngine0_RadialApertureCorrectionApplicationInputs_uwVScalingFactor_MSByte , + + //"ColourEngine0_OutputCoderControls//" , + + ColourEngine0_OutputCoderControls_TransformType , + ColourEngine0_OutputCoderControls_bContrast , + ColourEngine0_OutputCoderControls_bColourSaturation , + + //"ColourEngine0_CoderOutputSignalRange//" , + + ColourEngine0_CoderOutputSignalRange_uwLumaExcursion_LSByte , + ColourEngine0_CoderOutputSignalRange_uwLumaExcursion_MSByte, + ColourEngine0_CoderOutputSignalRange_uwLumaMidpointTimes2_LSByte , + ColourEngine0_CoderOutputSignalRange_uwLumaMidpointTimes2_MSByte , + ColourEngine0_CoderOutputSignalRange_uwChromaExcursion_LSByte , + ColourEngine0_CoderOutputSignalRange_uwChromaExcursion_MSByte , + ColourEngine0_CoderOutputSignalRange_uwChromaMidpointTimes2_LSByte , + ColourEngine0_CoderOutputSignalRange_uwChromaMidpointTimes2_MSByte , + + //"ColourEngine0_OutputCoderOffsetVector//" , + + ColourEngine0_OutputCoderOffsetVector_i0_LSByte , + ColourEngine0_OutputCoderOffsetVector_i0_MSByte , + ColourEngine0_OutputCoderOffsetVector_i1_LSByte , + ColourEngine0_OutputCoderOffsetVector_i1_MSByte , + ColourEngine0_OutputCoderOffsetVector_i2_LSByte , + ColourEngine0_OutputCoderOffsetVector_i2_MSByte , + + //"ColourEngine0_OutputCoderMatrix//" , + + ColourEngine0_OutputCoderMatrix_w0_0_LSByte , + ColourEngine0_OutputCoderMatrix_w0_0_MSByte , + ColourEngine0_OutputCoderMatrix_w0_1_LSByte , + ColourEngine0_OutputCoderMatrix_w0_1_MSByte , + ColourEngine0_OutputCoderMatrix_w0_2_LSByte , + ColourEngine0_OutputCoderMatrix_w0_2_MSByte , + ColourEngine0_OutputCoderMatrix_w1_0_LSByte , + ColourEngine0_OutputCoderMatrix_w1_0_MSByte , + ColourEngine0_OutputCoderMatrix_w1_1_LSByte , + ColourEngine0_OutputCoderMatrix_w1_1_MSByte , + ColourEngine0_OutputCoderMatrix_w1_2_LSByte , + ColourEngine0_OutputCoderMatrix_w1_2_MSByte , + ColourEngine0_OutputCoderMatrix_w2_0_LSByte, + ColourEngine0_OutputCoderMatrix_w2_0_MSByte , + ColourEngine0_OutputCoderMatrix_w2_1_LSByte , + ColourEngine0_OutputCoderMatrix_w2_1_MSByte , + ColourEngine0_OutputCoderMatrix_w2_2_LSByte , + ColourEngine0_OutputCoderMatrix_w2_2_MSByte , + + //"ColourEngine0_FadeToBlack//" , + + ColourEngine0_FadeToBlack_fDisable , + ColourEngine0_FadeToBlack_fpBlackValue_LSByte , + ColourEngine0_FadeToBlack_fpBlackValue_MSByte , + ColourEngine0_FadeToBlack_fpDamperLowThreshold_LSByte , + ColourEngine0_FadeToBlack_fpDamperLowThreshold_MSByte , + ColourEngine0_FadeToBlack_fpDamperHighThreshold_LSByte , + ColourEngine0_FadeToBlack_fpDamperHighThreshold_MSByte , + ColourEngine0_FadeToBlack_fpDamperOutput_LSByte , + ColourEngine0_FadeToBlack_fpDamperOutput_MSByte , + + //"ScalerLimits//" , + + ScalerLimits_uwPipe0MinStep_LSByte , + ScalerLimits_uwPipe0MinStep_MSByte , + ScalerLimits_uwPipe0MaxStep_LSByte , + ScalerLimits_uwPipe0MaxStep_MSByte , + + //"ZoomMgrParams//" , + + ZoomMgrParams_fAntiZip , + ZoomMgrParams_bFilterCrispness0 , + ZoomMgrParams_bFilterCrispness1 , + ZoomMgrParams_fInFromOutARLock, + ZoomMgrParams_bPrescaleFactor , + ZoomMgrParams_bPrescaleType , + ZoomMgrParams_fp16ZoomRange_LSByte , + ZoomMgrParams_fp16ZoomRange_MSByte , + + //"ZoomMgrCtrl//" , + + ZoomMgrCtrl_bHostTestCoin , + ZoomMgrCtrl_bZoomCmd , + ZoomMgrCtrl_fChgOverForbidden , + ZoomMgrCtrl_fAutoZoom , + ZoomMgrCtrl_bStepFramePeriod , + ZoomMgrCtrl_bMagFactor , + ZoomMgrCtrl_bChgOverMarginShift , + ZoomMgrCtrl_fCheckDataRate , + ZoomMgrCtrl_fSetAlternateInitWOI , + ZoomMgrCtrl_fSetX_Byte0 , + ZoomMgrCtrl_fSetX_Byte1 , + ZoomMgrCtrl_fSetX_Byte2 , + ZoomMgrCtrl_fSetX_Byte3 , + ZoomMgrCtrl_fp16P0ScaleLowLimit_LSByte , + ZoomMgrCtrl_fp16P0ScaleLowLimit_MSByte , + ZoomMgrCtrl_fp16P1ScaleLowLimit_LSByte , + ZoomMgrCtrl_fp16P1ScaleLowLimit_MSByte , + + //"ZoomMgrStatus//" , + + ZoomMgrStatus_fReady , + ZoomMgrStatus_bDeviceTestCoin , + ZoomMgrStatus_bNextCmd , + ZoomMgrStatus_bLastCmd, + ZoomMgrStatus_bCommandStatus , + ZoomMgrStatus_bZoomOpStatus , + ZoomMgrStatus_fFOVX_Byte0 , + ZoomMgrStatus_fFOVX_Byte1 , + ZoomMgrStatus_fFOVX_Byte2 , + ZoomMgrStatus_fFOVX_Byte3 , + ZoomMgrStatus_fFOVY_Byte0 , + ZoomMgrStatus_fFOVY_Byte1 , + ZoomMgrStatus_fFOVY_Byte2 , + ZoomMgrStatus_fFOVY_Byte3 , + ZoomMgrStatus_bPrescaleType , + ZoomMgrStatus_fPrescaleFactor_Byte0 , + ZoomMgrStatus_fPrescaleFactor_Byte1 , + ZoomMgrStatus_fPrescaleFactor_Byte2 , + ZoomMgrStatus_fPrescaleFactor_Byte3 , + ZoomMgrStatus_boPipe0NoPrescale , + ZoomMgrStatus_bZoomPosition , + ZoomMgrStatus_fMaxFOVX_Byte0 , + ZoomMgrStatus_fMaxFOVX_Byte1 , + ZoomMgrStatus_fMaxFOVX_Byte2 , + ZoomMgrStatus_fMaxFOVX_Byte3 , + ZoomMgrStatus_fMinFOVX_Byte0 , + ZoomMgrStatus_fMinFOVX_Byte1 , + ZoomMgrStatus_fMinFOVX_Byte2 , + ZoomMgrStatus_fMinFOVX_Byte3 , + ZoomMgrStatus_uwXOrigin_LSByte , + ZoomMgrStatus_uwXOrigin_MSByte , + ZoomMgrStatus_uwYOrigin_LSByte , + ZoomMgrStatus_uwYOrigin_MSByte , + + //"WhiteBalanceConstrainerControls//" + + WhiteBalanceConstrainerControls_fpRedA_LSByte , + WhiteBalanceConstrainerControls_fpRedA_MSByte , + WhiteBalanceConstrainerControls_fpBlueA_LSByte , + WhiteBalanceConstrainerControls_fpBlueA_MSByte , + WhiteBalanceConstrainerControls_fpRedB_LSByte , + WhiteBalanceConstrainerControls_fpRedB_MSByte , + WhiteBalanceConstrainerControls_fpBlueB_LSByte , + WhiteBalanceConstrainerControls_fpBlueB_MSByte , + WhiteBalanceConstrainerControls_fpMaximumDistanceAllowedFromLocus_LSByte , + WhiteBalanceConstrainerControls_fpMaximumDistanceAllowedFromLocus_MSByte , + WhiteBalanceConstrainerControls_fEnableConstrainedWhiteBalance , + + //"WhiteBalanceConstrainerOutput//" , + + WhiteBalanceConstrainerOutput_fpOutputRedGain_LSByte , + WhiteBalanceConstrainerOutput_fpOutputRedGain_MSByte , + WhiteBalanceConstrainerOutput_fpOutputGreenGain_LSByte , + WhiteBalanceConstrainerOutput_fpOutputGreenGain_MSByte , + WhiteBalanceConstrainerOutput_fpOutputBlueGain_LSByte , + WhiteBalanceConstrainerOutput_fpOutputBlueGain_MSByte , + WhiteBalanceConstrainerOutput_fAreGainsConstrained , + + //"WhiteBalanceConstrainerInternal//" , + + WhiteBalanceConstrainerInternal_fpGradientOfLocusAB_LSByte , + WhiteBalanceConstrainerInternal_fpGradientOfLocusAB_MSByte , + WhiteBalanceConstrainerInternal_fpDistanceOfInputPointFromLocusAB_LSByte , + WhiteBalanceConstrainerInternal_fpDistanceOfInputPointFromLocusAB_MSByte , + WhiteBalanceConstrainerInternal_fpConstrainedRedPoint_LSByte , + WhiteBalanceConstrainerInternal_fpConstrainedRedPoint_MSByte, + WhiteBalanceConstrainerInternal_fpConstrainedBluePoint_LSByte , + WhiteBalanceConstrainerInternal_fpConstrainedBluePoint_MSByte , + + //"ModeSetupBank1//" , + + ModeSetupBank1_uwInputImageSize_X_LSByte , + ModeSetupBank1_uwInputImageSize_X_MSByte , + ModeSetupBank1_uwInputImageSize_Y_LSByte , + ModeSetupBank1_uwInputImageSize_Y_MSByte , + ModeSetupBank1_uwMaxImageSize_X_LSByte , + ModeSetupBank1_uwMaxImageSize_X_MSByte , + ModeSetupBank1_uwMaxImageSize_Y_LSByte , + ModeSetupBank1_uwMaxImageSize_Y_MSByte , + ModeSetupBank1_uwMinImageSize_X_LSByte , + ModeSetupBank1_uwMinImageSize_X_MSByte , + ModeSetupBank1_uwMinImageSize_Y_LSByte , + ModeSetupBank1_uwMinImageSize_Y_MSByte , + ModeSetupBank1_bActiveSensor , + ModeSetupBank1_fLowPowerStreaming , + ModeSetupBank1_bTestMode , + ModeSetupBank1_bNumberOfStatusLines , + ModeSetupBank1_bNumberOfDarkLines , + ModeSetupBank1_bNumberOfBlackLines , + ModeSetupBank1_uwNumberOfInterLinePixelClocks_LSByte , + ModeSetupBank1_uwNumberOfInterLinePixelClocks_MSByte , + ModeSetupBank1_uwNumberOfInterFrameLines_LSByte , + ModeSetupBank1_uwNumberOfInterFrameLines_MSByte , + ModeSetupBank1_bNumberOfDummyColumns , + ModeSetupBank1_bInputImageSource , + ModeSetupBank1_bOutputImageDestination , + + //"DummyPage3//" , + + DummyPage3_bDummyPageElement , + + //"DummyPage4//" , + + DummyPage4_bDummyPageElement , + + //"AntiVignetteControlsFar//" , + + AntiVignetteControlsFar_fDisableFilter , + AntiVignetteControlsFar_bFilterCoeff_R2_r , + AntiVignetteControlsFar_bFilterCoeff_R2_gr , + AntiVignetteControlsFar_bFilterCoeff_R2_gb , + AntiVignetteControlsFar_bFilterCoeff_R2_b , + AntiVignetteControlsFar_bFilterCoeff_R4_r , + AntiVignetteControlsFar_bFilterCoeff_R4_gr , + AntiVignetteControlsFar_bFilterCoeff_R4_gb , + AntiVignetteControlsFar_bFilterCoeff_R4_b , + AntiVignetteControlsFar_uwHorizontalOffset_LSByte , + AntiVignetteControlsFar_uwHorizontalOffset_MSByte , + AntiVignetteControlsFar_uwVerticalOffset_LSByte , + AntiVignetteControlsFar_uwVerticalOffset_MSByte , + AntiVignetteControlsFar_fAVOffsetSeperateFor4Channels , + AntiVignetteControlsFar_bShiftFix_R2 , + AntiVignetteControlsFar_uwHorizontalOffset_r_LSByte , + AntiVignetteControlsFar_uwHorizontalOffset_r_MSByte , + AntiVignetteControlsFar_uwHorizontalOffset_gr_LSByte , + AntiVignetteControlsFar_uwHorizontalOffset_gr_MSByte , + AntiVignetteControlsFar_uwHorizontalOffset_gb_LSByte , + AntiVignetteControlsFar_uwHorizontalOffset_gb_MSByte, + AntiVignetteControlsFar_uwHorizontalOffset_b_LSByte , + AntiVignetteControlsFar_uwHorizontalOffset_b_MSByte , + AntiVignetteControlsFar_uwVerticalOffset_r_LSByte , + AntiVignetteControlsFar_uwVerticalOffset_r_MSByte , + AntiVignetteControlsFar_uwVerticalOffset_gr_LSByte , + AntiVignetteControlsFar_uwVerticalOffset_gr_MSByte , + AntiVignetteControlsFar_uwVerticalOffset_gb_LSByte , + AntiVignetteControlsFar_uwVerticalOffset_gb_MSByte , + AntiVignetteControlsFar_uwVerticalOffset_b_LSByte , + AntiVignetteControlsFar_uwVerticalOffset_b_MSByte , + AntiVignetteControlsFar_bUnityOffset_r , + AntiVignetteControlsFar_bUnityOffset_gr , + AntiVignetteControlsFar_bUnityOffset_gb , + AntiVignetteControlsFar_bUnityOffset_b , + AntiVignetteControlsFar_fAdaptiveAntiVignetteEnable , + + //"AntiVignetteControlsNear//" , + + AntiVignetteControlsNear_fDisableFilter , + AntiVignetteControlsNear_bFilterCoeff_R2_r , + AntiVignetteControlsNear_bFilterCoeff_R2_gr , + AntiVignetteControlsNear_bFilterCoeff_R2_gb , + AntiVignetteControlsNear_bFilterCoeff_R2_b , + AntiVignetteControlsNear_bFilterCoeff_R4_r , + AntiVignetteControlsNear_bFilterCoeff_R4_gr , + AntiVignetteControlsNear_bFilterCoeff_R4_gb , + AntiVignetteControlsNear_bFilterCoeff_R4_b , + AntiVignetteControlsNear_uwHorizontalOffset_LSByte , + AntiVignetteControlsNear_uwHorizontalOffset_MSByte , + AntiVignetteControlsNear_uwVerticalOffset_LSByte , + AntiVignetteControlsNear_uwVerticalOffset_MSByte, + AntiVignetteControlsNear_fAVOffsetSeperateFor4Channels , + AntiVignetteControlsNear_bShiftFix_R2 , + AntiVignetteControlsNear_uwHorizontalOffset_r_LSByte , + AntiVignetteControlsNear_uwHorizontalOffset_r_MSByte , + AntiVignetteControlsNear_uwHorizontalOffset_gr_LSByte , + AntiVignetteControlsNear_uwHorizontalOffset_gr_MSByte , + AntiVignetteControlsNear_uwHorizontalOffset_gb_LSByte , + AntiVignetteControlsNear_uwHorizontalOffset_gb_MSByte , + AntiVignetteControlsNear_uwHorizontalOffset_b_LSByte , + AntiVignetteControlsNear_uwHorizontalOffset_b_MSByte , + AntiVignetteControlsNear_uwVerticalOffset_r_LSByte , + AntiVignetteControlsNear_uwVerticalOffset_r_MSByte , + AntiVignetteControlsNear_uwVerticalOffset_gr_LSByte , + AntiVignetteControlsNear_uwVerticalOffset_gr_MSByte , + AntiVignetteControlsNear_uwVerticalOffset_gb_LSByte , + AntiVignetteControlsNear_uwVerticalOffset_gb_MSByte , + AntiVignetteControlsNear_uwVerticalOffset_b_LSByte , + AntiVignetteControlsNear_uwVerticalOffset_b_MSByte , + AntiVignetteControlsNear_bUnityOffset_r , + AntiVignetteControlsNear_bUnityOffset_gr , + AntiVignetteControlsNear_bUnityOffset_gb , + AntiVignetteControlsNear_bUnityOffset_b , + AntiVignetteControlsNear_fAdaptiveAntiVignetteEnable , + + //"AFStatsControls//" , + + AFStatsControls_fAbsSquareEnabled , + AFStatsControls_bCoringValue , + AFStatsControls_bWindowsSystem , + AFStatsControls_bHRatio_Num , + AFStatsControls_bHRatio_Den, + AFStatsControls_bVRatio_Num , + AFStatsControls_bVRatio_Den , + AFStatsControls_bHostActiveZonesCounter , + AFStatsControls_fAutoRefresh , + + //"AFStatsStatus//" , + + AFStatsStatus_bAFStats_Error , + AFStatsStatus_fAbsSquareEnabled , + AFStatsStatus_bCoringValue , + AFStatsStatus_bWindowsSystem , + AFStatsStatus_bActiveZonesCounter , + AFStatsStatus_bHRatio_Num , + AFStatsStatus_bHRatio_Den , + AFStatsStatus_bVRatio_Num , + AFStatsStatus_bVRatio_Den , + AFStatsStatus_uwWOI_Width_LSByte , + AFStatsStatus_uwWOI_Width_MSByte , + AFStatsStatus_uwWOI_Height_LSByte , + AFStatsStatus_uwWOI_Height_MSByte , + AFStatsStatus_uwAFZones_Width_LSByte , + AFStatsStatus_uwAFZones_Width_MSByte , + AFStatsStatus_uwAFZones_Height_LSByte , + AFStatsStatus_uwAFZones_Height_MSByte , + AFStatsStatus_fForcedAFStatsIrq , + AFStatsStatus_udwMaxFocusMeasurePerPixel_Byte0 , + AFStatsStatus_udwMaxFocusMeasurePerPixel_Byte1 , + AFStatsStatus_udwMaxFocusMeasurePerPixel_Byte2 , + AFStatsStatus_udwMaxFocusMeasurePerPixel_Byte3 , + AFStatsStatus_uwStartingAFZoneLine_LSByte , + AFStatsStatus_uwStartingAFZoneLine_MSByte, + + //"AFFocusStats//" , + + AFFocusStats_udwStatsValue_0_Byte0 , + AFFocusStats_udwStatsValue_0_Byte1 , + AFFocusStats_udwStatsValue_0_Byte2 , + AFFocusStats_udwStatsValue_0_Byte3 , + AFFocusStats_udwStatsValue_1_Byte0 , + AFFocusStats_udwStatsValue_1_Byte1 , + AFFocusStats_udwStatsValue_1_Byte2 , + AFFocusStats_udwStatsValue_1_Byte3 , + AFFocusStats_udwStatsValue_2_Byte0 , + AFFocusStats_udwStatsValue_2_Byte1 , + AFFocusStats_udwStatsValue_2_Byte2 , + AFFocusStats_udwStatsValue_2_Byte3 , + AFFocusStats_udwStatsValue_3_Byte0 , + AFFocusStats_udwStatsValue_3_Byte1 , + AFFocusStats_udwStatsValue_3_Byte2 , + AFFocusStats_udwStatsValue_3_Byte3 , + AFFocusStats_udwStatsValue_4_Byte0 , + AFFocusStats_udwStatsValue_4_Byte1 , + AFFocusStats_udwStatsValue_4_Byte2 , + AFFocusStats_udwStatsValue_4_Byte3 , + AFFocusStats_udwStatsValue_5_Byte0 , + AFFocusStats_udwStatsValue_5_Byte1 , + AFFocusStats_udwStatsValue_5_Byte2 , + AFFocusStats_udwStatsValue_5_Byte3 , + AFFocusStats_udwStatsValue_6_Byte0 , + AFFocusStats_udwStatsValue_6_Byte1 , + AFFocusStats_udwStatsValue_6_Byte2 , + AFFocusStats_udwStatsValue_6_Byte3, + + //"AFLightStats//" , + + AFLightStats_bStatsValue_0 , + AFLightStats_bStatsValue_1 , + AFLightStats_bStatsValue_2 , + AFLightStats_bStatsValue_3 , + AFLightStats_bStatsValue_4 , + AFLightStats_bStatsValue_5 , + AFLightStats_bStatsValue_6 , + + //"FLADriverLowLevelParameters//" , + + FLADriverLowLevelParameters_wMinPosition_LSByte , + FLADriverLowLevelParameters_wMinPosition_MSByte , + FLADriverLowLevelParameters_wMaxPosition_LSByte , + FLADriverLowLevelParameters_wMaxPosition_MSByte , + FLADriverLowLevelParameters_wHomePosition_LSByte , + FLADriverLowLevelParameters_wHomePosition_MSByte , + FLADriverLowLevelParameters_wParkPosition_LSByte , + FLADriverLowLevelParameters_wParkPosition_MSByte , + FLADriverLowLevelParameters_bFramesToSkip , + FLADriverLowLevelParameters_AutoSkipNextFrame , + FLADriverLowLevelParameters_bLowLevelMacroPos , + FLADriverLowLevelParameters_bLowLevelInfinityPos , + FLADriverLowLevelParameters_bLowLevelPositionTolerance , + FLADriverLowLevelParameters_bLowLevelTimeLimit , + FLADriverLowLevelParameters_bMaxNumberRetries , + FLADriverLowLevelParameters_fLowLevelDriverInitialized , + FLADriverLowLevelParameters_fOverwriteLowLevelLimits , + FLADriverLowLevelParameters_bNVMRead, + FLADriverLowLevelParameters_bNVMScalingFactorInfinity , + FLADriverLowLevelParameters_bNVMScalingFactorMacro , + FLADriverLowLevelParameters_bNVM_PS_Offset , + FLADriverLowLevelParameters_bNVM_PS_Gains , + FLADriverLowLevelParameters_bNVM_PS_IBias , + FLADriverLowLevelParameters_bNVM_PS_RampGain , + FLADriverLowLevelParameters_bNVM_PS_Type , + FLADriverLowLevelParameters_uwNVM_minidriver_m_c_LSByte , + FLADriverLowLevelParameters_uwNVM_minidriver_m_c_MSByte , + + //"FLADriverControls//" , + + FLADriverControls_bMMode , + FLADriverControls_wTargetPosition_LSByte , + FLADriverControls_wTargetPosition_MSByte , + FLADriverControls_wPositionTolerance_LSByte , + FLADriverControls_wPositionTolerance_MSByte , + FLADriverControls_uwTimeLimit_ms_LSByte , + FLADriverControls_uwTimeLimit_ms_MSByte , + FLADriverControls_bTrigger , + FLADriverControls_bSlewMode , + FLADriverControls_bSlewRate , + + //"FLADriverStatus//" , + + FLADriverStatus_wLensPosition_LSByte , + FLADriverStatus_wLensPosition_MSByte , + FLADriverStatus_fLensIsMoving , + FLADriverStatus_fLimitsExceeded , + FLADriverStatus_fLensIsAtHome , + FLADriverStatus_fError, + FLADriverStatus_bSkippedFrames , + FLADriverStatus_bCycles , + FLADriverStatus_bMiniDriverTimeoutError , + FLADriverStatus_wTargetPosition , + FLADriverStatus_bLowLevelPosition , + + //"FocusControls//" , + + FocusControls_fErrorReset , + FocusControls_bRange , + FocusControls_bMode , + FocusControls_bAFCommand , + FocusControls_bLensCommand , + FocusControls_bManualStep_Size , + FocusControls_fTestCoinEnabled , + FocusControls_bControlCoin , + FocusControls_fInternalStats_Disable , + FocusControls_bActuator_Disable , + FocusControls_fInhibitAutoMetering , + + //"FocusStatus//" , + + FocusStatus_bModeStatus , + FocusStatus_bAFCommandStatus , + FocusStatus_bLensCommandStatus , + FocusStatus_fAutoFocusEnabled , + FocusStatus_bRange , + FocusStatus_fIsStable , + FocusStatus_fError , + FocusStatus_cErrorCode , + FocusStatus_fLensIsMovingAtTheSOF, + FocusStatus_bCycles , + FocusStatus_fRunForTest , + FocusStatus_bStatusCoin , + FocusStatus_fInternalStats_Disabled , + FocusStatus_bActuator_Disabled , + FocusStatus_bLastUsedAFSensor , + + //"FocusRangeConstants//" , + + FocusRangeConstants_wFullRange_LensMinPosition_LSByte , + FocusRangeConstants_wFullRange_LensMinPosition_MSByte , + FocusRangeConstants_wFullRange_LensMaxPosition_LSByte , + FocusRangeConstants_wFullRange_LensMaxPosition_MSByte , + FocusRangeConstants_wFullRange_LensRecoveryPosition_LSByte , + FocusRangeConstants_wFullRange_LensRecoveryPosition_MSByte , + FocusRangeConstants_wLandscape_LensMinPosition_LSByte , + FocusRangeConstants_wLandscape_LensMinPosition_MSByte , + FocusRangeConstants_wLandscape_LensMaxPosition_LSByte , + FocusRangeConstants_wLandscape_LensMaxPosition_MSByte , + FocusRangeConstants_wLandscape_LensRecoveryPosition_LSByte , + FocusRangeConstants_wLandscape_LensRecoveryPosition_MSByte , + FocusRangeConstants_wMacro_LensMinPosition_LSByte , + FocusRangeConstants_wMacro_LensMinPosition_MSByte , + FocusRangeConstants_wMacro_LensMaxPosition_LSByte , + FocusRangeConstants_wMacro_LensMaxPosition_MSByte , + FocusRangeConstants_wMacro_LensRecoveryPosition_LSByte , + FocusRangeConstants_wMacro_LensRecoveryPosition_MSByte , + + //"AutoFocusControls//" , + + AutoFocusControls_bHostCmd, + AutoFocusControls_fFreezeIfStable , + AutoFocusControls_fFMTesting_AutoDisable , + AutoFocusControls_fFastAFAlgoStart , + AutoFocusControls_fBackLight_Enable , + AutoFocusControls_fBackupSolution , + AutoFocusControls_fCheckExposureStable_Enable , + AutoFocusControls_fEnableSimpleCoarseThEvaluation , + AutoFocusControls_bSelectedMultizoneBehavior , + AutoFocusControls_bBackLightMethodSelected , + AutoFocusControls_bWeighedFunctionSelected , + AutoFocusControls_fMotionBlurEnable , + AutoFocusControls_fLightVariationEnable , + AutoFocusControls_fEnableTrackingThresholdEvaluation , + AutoFocusControls_fEnableHeuristicMethod , + AutoFocusControls_fEnableBackupSolution , + AutoFocusControls_fFineToCoarseAutoTransitionEnable , + AutoFocusControls_fEnableTimedFineExecution , + AutoFocusControls_fEnableTrakingZoneVariation , + AutoFocusControls_fEnableFunctionThresholdTest , + AutoFocusControls_fForceTestState , + AutoFocusControls_bManualAFNextState , + AutoFocusControls_fResetHCSPos , + + //"AutoFocusConstants//" , + + AutoFocusConstants_bCoarseStep , + AutoFocusConstants_bFineStep , + AutoFocusConstants_bFullSearchStep , + AutoFocusConstants_bLeakyIntegratorConstant , + AutoFocusConstants_uwFineThreshold_LSByte , + AutoFocusConstants_uwFineThreshold_MSByte, + AutoFocusConstants_bFineToCoarseThreshold , + AutoFocusConstants_uwBacklightThreshold_LSByte , + AutoFocusConstants_uwBacklightThreshold_MSByte , + AutoFocusConstants_uwMotionBlurInRatio_LSByte , + AutoFocusConstants_uwMotionBlurInRatio_MSByte , + AutoFocusConstants_uwMotionBlurOutRatio_LSByte , + AutoFocusConstants_uwMotionBlurOutRatio_MSByte , + AutoFocusConstants_bMaxNumberContinuouslyInstableTime , + AutoFocusConstants_bMaxNumberContinuouslyStableFrame , + AutoFocusConstants_uwMaxNumberContinuouslyThresholdTime , + AutoFocusConstants_uwFixedLowFocusMeasureValue_LSByte , + AutoFocusConstants_uwFixedLowFocusMeasureValue_MSByte , + AutoFocusConstants_bMaxFocusMeasureThreshold , + AutoFocusConstants_bLightGap , + AutoFocusConstants_uwDeltaValue_LSByte , + AutoFocusConstants_uwDeltaValue_MSByte , + AutoFocusConstants_uwMaxFineTh_LSByte , + AutoFocusConstants_uwMaxFineTh_MSByte , + + //"AutoFocusInput//" , + + AutoFocusInput_wLensPosition_LSByte , + AutoFocusInput_wLensPosition_MSByte , + AutoFocusInput_fLimitsExceeded , + AutoFocusInput_wLastStepExecuted_LSByte , + AutoFocusInput_wLastStepExecuted_MSByte , + + //"AutoFocusStatus//" , + + AutoFocusStatus_bCycles , + AutoFocusStatus_bHostCmd, + AutoFocusStatus_bAF_PrevState , + AutoFocusStatus_bAF_State , + AutoFocusStatus_bAF_NextState , + AutoFocusStatus_bAF_PrevInstableFMState , + AutoFocusStatus_bAF_NextInstableFMState , + AutoFocusStatus_fChangeDirectionStatus , + AutoFocusStatus_bHCS_State , + AutoFocusStatus_bHCS_NextState , + AutoFocusStatus_bHCS_PrevState , + AutoFocusStatus_fReserved , + AutoFocusStatus_fCoarseInvoked , + AutoFocusStatus_fFullSearchInvoked , + AutoFocusStatus_fFullSearchZero , + AutoFocusStatus_fInFocus , + AutoFocusStatus_fMotionBlurIdentified , + AutoFocusStatus_fInitialSearch , + AutoFocusStatus_wMaxStepMotorLens_LSByte , + AutoFocusStatus_wMaxStepMotorLens_MSByte , + AutoFocusStatus_wTotalStepMotorLens_LSByte , + AutoFocusStatus_wTotalStepMotorLens_MSByte , + AutoFocusStatus_bNumberOfFrames , + AutoFocusStatus_bCountFineSteps , + AutoFocusStatus_bCountTrackingFrames , + AutoFocusStatus_bNumberOfSelectedRegions , + AutoFocusStatus_bOldNumberOfSelectedRegions , + AutoFocusStatus_uwSelectedRegionsStatus_LSByte , + AutoFocusStatus_uwSelectedRegionsStatus_MSByte , + AutoFocusStatus_uwTotalCoarseVariation_LSByte , + AutoFocusStatus_uwTotalCoarseVariation_MSByte , + AutoFocusStatus_uwTotalFineVariation_LSByte , + AutoFocusStatus_uwTotalFineVariation_MSByte, + AutoFocusStatus_bCountVariationRegion , + + //"AutoFocusOutput//" , + + AutoFocusOutput_cFocusLensActuatorCommand , + AutoFocusOutput_wStep_LSByte , + AutoFocusOutput_wStep_MSByte , + AutoFocusOutput_cDirection , + + //"AutoFocusMeasureData//" , + + AutoFocusMeasureData_udwFocusMeasure_Byte0 , + AutoFocusMeasureData_udwFocusMeasure_Byte1 , + AutoFocusMeasureData_udwFocusMeasure_Byte2 , + AutoFocusMeasureData_udwFocusMeasure_Byte3 , + AutoFocusMeasureData_udwPrevFocusMeasure_Byte0 , + AutoFocusMeasureData_udwPrevFocusMeasure_Byte1 , + AutoFocusMeasureData_udwPrevFocusMeasure_Byte2 , + AutoFocusMeasureData_udwPrevFocusMeasure_Byte3 , + AutoFocusMeasureData_udwMB_FocusMeasure_Byte0 , + AutoFocusMeasureData_udwMB_FocusMeasure_Byte1 , + AutoFocusMeasureData_udwMB_FocusMeasure_Byte2 , + AutoFocusMeasureData_udwMB_FocusMeasure_Byte3 , + AutoFocusMeasureData_udwMB_PrevFocusMeasure_Byte0 , + AutoFocusMeasureData_udwMB_PrevFocusMeasure_Byte1 , + AutoFocusMeasureData_udwMB_PrevFocusMeasure_Byte2 , + AutoFocusMeasureData_udwMB_PrevFocusMeasure_Byte3 , + AutoFocusMeasureData_udwMaxFocusMeasure_Byte0 , + AutoFocusMeasureData_udwMaxFocusMeasure_Byte1 , + AutoFocusMeasureData_udwMaxFocusMeasure_Byte2 , + AutoFocusMeasureData_udwMaxFocusMeasure_Byte3, + AutoFocusMeasureData_udwOldMaxFocusMeasure_Byte0 , + AutoFocusMeasureData_udwOldMaxFocusMeasure_Byte1 , + AutoFocusMeasureData_udwOldMaxFocusMeasure_Byte2 , + AutoFocusMeasureData_udwOldMaxFocusMeasure_Byte3 , + AutoFocusMeasureData_udwPrevMaxFocusMeasure_Byte0 , + AutoFocusMeasureData_udwPrevMaxFocusMeasure_Byte1 , + AutoFocusMeasureData_udwPrevMaxFocusMeasure_Byte2 , + AutoFocusMeasureData_udwPrevMaxFocusMeasure_Byte3 , + AutoFocusMeasureData_udwNextMaxFocusMeasure_Byte0 , + AutoFocusMeasureData_udwNextMaxFocusMeasure_Byte1 , + AutoFocusMeasureData_udwNextMaxFocusMeasure_Byte2 , + AutoFocusMeasureData_udwNextMaxFocusMeasure_Byte3 , + AutoFocusMeasureData_udwWeighedFocusMeasure_Byte0 , + AutoFocusMeasureData_udwWeighedFocusMeasure_Byte1 , + AutoFocusMeasureData_udwWeighedFocusMeasure_Byte2 , + AutoFocusMeasureData_udwWeighedFocusMeasure_Byte3 , + AutoFocusMeasureData_udwMaxMaxFocusMeasure_Byte0 , + AutoFocusMeasureData_udwMaxMaxFocusMeasure_Byte1 , + AutoFocusMeasureData_udwMaxMaxFocusMeasure_Byte2 , + AutoFocusMeasureData_udwMaxMaxFocusMeasure_Byte3 , + AutoFocusMeasureData_udwTrackingFocusMeasure_Byte0 , + AutoFocusMeasureData_udwTrackingFocusMeasure_Byte1 , + AutoFocusMeasureData_udwTrackingFocusMeasure_Byte2 , + AutoFocusMeasureData_udwTrackingFocusMeasure_Byte3 , + AutoFocusMeasureData_udwTrackingFocusMeasureDifference_Byte0 , + AutoFocusMeasureData_udwTrackingFocusMeasureDifference_Byte1 , + AutoFocusMeasureData_udwTrackingFocusMeasureDifference_Byte2 , + AutoFocusMeasureData_udwTrackingFocusMeasureDifference_Byte3 , + AutoFocusMeasureData_udwCurrentFocusMeasureDifference_Byte0 , + AutoFocusMeasureData_udwCurrentFocusMeasureDifference_Byte1 , + AutoFocusMeasureData_udwCurrentFocusMeasureDifference_Byte2, + AutoFocusMeasureData_udwCurrentFocusMeasureDifference_Byte3 , + AutoFocusMeasureData_udwOldTrackingFocusMeasure_Byte0 , + AutoFocusMeasureData_udwOldTrackingFocusMeasure_Byte1 , + AutoFocusMeasureData_udwOldTrackingFocusMeasure_Byte2 , + AutoFocusMeasureData_udwOldTrackingFocusMeasure_Byte3 , + + //"AutoFocusWeightControls//" , + + AutoFocusWeightControls_bWeight_0 , + AutoFocusWeightControls_bWeight_1 , + AutoFocusWeightControls_bWeight_2 , + AutoFocusWeightControls_bWeight_3 , + AutoFocusWeightControls_bWeight_4 , + AutoFocusWeightControls_bWeight_5 , + AutoFocusWeightControls_bWeight_6 , + + //"AutoFocusDynamicWeight//" , + + AutoFocusDynamicWeight_bWeight_0 , + AutoFocusDynamicWeight_bWeight_1 , + AutoFocusDynamicWeight_bWeight_2 , + AutoFocusDynamicWeight_bWeight_3 , + AutoFocusDynamicWeight_bWeight_4 , + AutoFocusDynamicWeight_bWeight_5 , + AutoFocusDynamicWeight_bWeight_6 , + + //"AutoFocusThresholds//" , + + AutoFocusThresholds_uwCoarseThreshold_LSByte , + AutoFocusThresholds_uwCoarseThreshold_MSByte , + AutoFocusThresholds_uwFineThreshold_LSByte, + AutoFocusThresholds_uwFineThreshold_MSByte , + AutoFocusThresholds_uwBeforeMotionBlur_LSByte , + AutoFocusThresholds_uwBeforeMotionBlur_MSByte , + AutoFocusThresholds_uwAfterMotionBlur_LSByte , + AutoFocusThresholds_uwAfterMotionBlur_MSByte , + AutoFocusThresholds_udwCurrentVariation_Byte0 , + AutoFocusThresholds_udwCurrentVariation_Byte1 , + AutoFocusThresholds_udwCurrentVariation_Byte2 , + AutoFocusThresholds_udwCurrentVariation_Byte3 , + AutoFocusThresholds_udwLowFocusMeasureValue_Byte0 , + AutoFocusThresholds_udwLowFocusMeasureValue_Byte1 , + AutoFocusThresholds_udwLowFocusMeasureValue_Byte2 , + AutoFocusThresholds_udwLowFocusMeasureValue_Byte3 , + + //"AutoFocusHeuristicConstants//" , + + AutoFocusHeuristicConstants_uwLensPositionInputMax_LSByte , + AutoFocusHeuristicConstants_uwLensPositionInputMax_MSByte , + AutoFocusHeuristicConstants_uwLensPositionInputMin_LSByte , + AutoFocusHeuristicConstants_uwLensPositionInputMin_MSByte , + AutoFocusHeuristicConstants_bBrightnessInputMax , + AutoFocusHeuristicConstants_bBrightnessInputMin , + AutoFocusHeuristicConstants_uwThFineMax_LSByte , + AutoFocusHeuristicConstants_uwThFineMax_MSByte , + AutoFocusHeuristicConstants_uwThFineMin_LSByte , + AutoFocusHeuristicConstants_uwThFineMin_MSByte , + AutoFocusHeuristicConstants_uwFineToCoarseMax_LSByte , + AutoFocusHeuristicConstants_uwFineToCoarseMax_MSByte , + AutoFocusHeuristicConstants_uwFineToCoarseMin_LSByte , + AutoFocusHeuristicConstants_uwFineToCoarseMin_MSByte , + AutoFocusHeuristicConstants_bHighToMaxFMShiftFactor, + AutoFocusHeuristicConstants_bLowToHighFMShiftFactor , + + //"AutoFocusThHeuristicInput//" , + + AutoFocusThHeuristicInput_udwFocusMeasureInputMax_Byte0 , + AutoFocusThHeuristicInput_udwFocusMeasureInputMax_Byte1 , + AutoFocusThHeuristicInput_udwFocusMeasureInputMax_Byte2 , + AutoFocusThHeuristicInput_udwFocusMeasureInputMax_Byte3 , + AutoFocusThHeuristicInput_udwFocusMeasureInputMin_Byte0 , + AutoFocusThHeuristicInput_udwFocusMeasureInputMin_Byte1 , + AutoFocusThHeuristicInput_udwFocusMeasureInputMin_Byte2 , + AutoFocusThHeuristicInput_udwFocusMeasureInputMin_Byte3 , + AutoFocusThHeuristicInput_udwFocusMeasureInput_Byte0 , + AutoFocusThHeuristicInput_udwFocusMeasureInput_Byte1 , + AutoFocusThHeuristicInput_udwFocusMeasureInput_Byte2 , + AutoFocusThHeuristicInput_udwFocusMeasureInput_Byte3 , + AutoFocusThHeuristicInput_uwLensPositionInput_LSByte , + AutoFocusThHeuristicInput_uwLensPositionInput_MSByte , + AutoFocusThHeuristicInput_bBrightnessInput , + + //"AutoFocusInstableFocusMeasureStatus//" , + + AutoFocusInstableFocusMeasureStatus_bStatus_SceneDetector , + AutoFocusInstableFocusMeasureStatus_bCountInstableFocusMeasure , + AutoFocusInstableFocusMeasureStatus_bCountStableFocusMeasure , + + //"AutoFocusLFMFullSearchStatus//" , + + AutoFocusLFMFullSearchStatus_bPrevState_AFFS , + AutoFocusLFMFullSearchStatus_bState_AFFS , + AutoFocusLFMFullSearchStatus_bNextState_AFFS, + AutoFocusLFMFullSearchStatus_bCountFullSearchContinuouslyIncreaseValue , + + //"AutoFocusMZFullSearchStatus//" , + + AutoFocusMZFullSearchStatus_bFS_PrevState , + AutoFocusMZFullSearchStatus_bFS_State , + AutoFocusMZFullSearchStatus_bFS_NextState , + AutoFocusMZFullSearchStatus_bMaxMaxRegionPositionIndex , + + //"MiscPageElements//" , + + MiscPageElements_fConvertMultiByteReadsIntoSingleByte , + MiscPageElements_bDelayAfterSettingXshutdown , + MiscPageElements_fEnableIntelligentFlash , + MiscPageElements_fEligibleFrameForMetering , + MiscPageElements_fFlashGunIlluminatedFrameStreamed , + MiscPageElements_VpipCut , + MiscPageElements_bGPIOClockFrequency_Mhz , + MiscPageElements_bIntelligentFlashModeStatus , + MiscPageElements_fStartMeteringFromManualGains , + MiscPageElements_fEnableDelayWhenStartingSensor , + MiscPageElements_fEnableDelayWhenStoppingSensor , + MiscPageElements_fTriggerFlashOnStreaming , + MiscPageElements_fDoNotOutputFrameInIntelligentFlash , + MiscPageElements_fDisableToshibaInit , + MiscPageElements_bNumberofFramesTobeSkippedByRx , + + //"CutBMasterI2cStatus//" , + + CutBMasterI2cStatus_bWriteFifoUseCount , + + //"MasterI2cClockControl//" , + + MasterI2cClockControl_bCountFall , + MasterI2cClockControl_bCountRise , + MasterI2cClockControl_bCountHigh , + MasterI2cClockControl_bCountBuffer , + MasterI2cClockControl_bCountHoldData , + MasterI2cClockControl_bCountSetupData , + MasterI2cClockControl_bCountHoldStart , + MasterI2cClockControl_bCountSetupStart , + MasterI2cClockControl_bCountSetupStop , + + //"ZoomMgrFOVCtrl//" , + + ZoomMgrFOVCtrl_bShiftCenter , + ZoomMgrFOVCtrl_uwXOrigin_LSByte , + ZoomMgrFOVCtrl_uwXOrigin_MSByte , + ZoomMgrFOVCtrl_uwYOrigin_LSByte , + ZoomMgrFOVCtrl_uwYOrigin_MSByte , + ZoomMgrFOVCtrl_fRestrictMaxFOVToChosenFOV , + ZoomMgrFOVCtrl_fCalculateMinFOVAlways , + ZoomMgrFOVCtrl_fInhibitMaxFOVAtModeStaticChange , + + //"ZoomMgrSpeedInfo//" , + + ZoomMgrSpeedInfo_bNumberOfFramesOnHold , + ZoomMgrSpeedInfo_bDelay_frames , + ZoomMgrSpeedInfo_uwTotalDelay_frames_LSByte , + ZoomMgrSpeedInfo_uwTotalDelay_frames_MSByte , + ZoomMgrSpeedInfo_bNumberOfZoomSteps , + + //"ZoomMgrStripeCtrl//" , + + ZoomMgrStripeCtrl_bStripeControl , + ZoomMgrStripeCtrl_uwStripeStartAddr_LSByte , + ZoomMgrStripeCtrl_uwStripeStartAddr_MSByte , + ZoomMgrStripeCtrl_uwStripeSize_LSByte , + ZoomMgrStripeCtrl_uwStripeSize_MSByte , + ZoomMgrStripeCtrl_uwStripeInMinLineSize_LSByte , + ZoomMgrStripeCtrl_uwStripeInMinLineSize_MSByte , + ZoomMgrStripeCtrl_uwBmsFrameLength_LSByte , + ZoomMgrStripeCtrl_uwBmsFrameLength_MSByte , + + //"LftStripeParam//" , + + LftStripeParam_uwGPSISize_LSByte , + LftStripeParam_uwGPSISize_MSByte , + LftStripeParam_uwGPSOSize_LSByte , + LftStripeParam_uwGPSOSize_MSByte , + LftStripeParam_uwRightBorder_LSByte , + LftStripeParam_uwRightBorder_MSByte , + LftStripeParam_uwLeftBorder_LSByte , + LftStripeParam_uwLeftBorder_MSByte , + LftStripeParam_wGPSCropBulk_LSByte , + LftStripeParam_wGPSCropBulk_MSByte , + LftStripeParam_wGPSCropFrac_LSByte , + LftStripeParam_wGPSCropFrac_MSByte , + LftStripeParam_uwStripeInCropStart_LSByte , + LftStripeParam_uwStripeInCropStart_MSByte , + LftStripeParam_uwStripeInCropSize_LSByte , + LftStripeParam_uwStripeInCropSize_MSByte , + LftStripeParam_uwStripeOutCropStart_LSByte, + LftStripeParam_uwStripeOutCropStart_MSByte , + LftStripeParam_uwStripeOutCropSize_LSByte , + LftStripeParam_uwStripeOutCropSize_MSByte , + + //"RgtStripeParam//" , + + RgtStripeParam_uwGPSISize_LSByte , + RgtStripeParam_uwGPSISize_MSByte , + RgtStripeParam_uwGPSOSize_LSByte , + RgtStripeParam_uwGPSOSize_MSByte , + RgtStripeParam_uwRightBorder_LSByte , + RgtStripeParam_uwRightBorder_MSByte , + RgtStripeParam_uwLeftBorder_LSByte , + RgtStripeParam_uwLeftBorder_MSByte , + RgtStripeParam_wGPSCropBulk_LSByte , + RgtStripeParam_wGPSCropBulk_MSByte , + RgtStripeParam_wGPSCropFrac_LSByte , + RgtStripeParam_wGPSCropFrac_MSByte , + RgtStripeParam_uwStripeInCropStart_LSByte , + RgtStripeParam_uwStripeInCropStart_MSByte , + RgtStripeParam_uwStripeInCropSize_LSByte , + RgtStripeParam_uwStripeInCropSize_MSByte , + RgtStripeParam_uwStripeOutCropStart_LSByte , + RgtStripeParam_uwStripeOutCropStart_MSByte , + RgtStripeParam_uwStripeOutCropSize_LSByte , + RgtStripeParam_uwStripeOutCropSize_MSByte , + + //"DigitalGainStatus//" , + + DigitalGainStatus_uwCodedGreen1Gain_LSByte , + DigitalGainStatus_uwCodedGreen1Gain_MSByte, + DigitalGainStatus_uwCodedRedGain_LSByte , + DigitalGainStatus_uwCodedRedGain_MSByte , + DigitalGainStatus_uwCodedBlueGain_LSByte , + DigitalGainStatus_uwCodedBlueGain_MSByte , + DigitalGainStatus_uwCodedGreen2Gain_LSByte , + DigitalGainStatus_uwCodedGreen2Gain_MSByte , + + //"OffsetCompensationStatus//" , + + OffsetCompensationStatus_uwOffset_LSByte , + OffsetCompensationStatus_uwOffset_MSByte , + OffsetCompensationStatus_fpOffsetCompensationGain_LSByte , + OffsetCompensationStatus_fpOffsetCompensationGain_MSByte , + + //"AntiFlickerExposureStatus//" , + + AntiFlickerExposureStatus_fpFlickerFreePeriod_us_LSByte , + AntiFlickerExposureStatus_fpFlickerFreePeriod_us_MSByte , + AntiFlickerExposureStatus_fpGainedFlickerFreeTimePeriod_us_LSByte , + AntiFlickerExposureStatus_fpGainedFlickerFreeTimePeriod_us_MSByte , + AntiFlickerExposureStatus_uwMaxFlickerFreeBunches_LSByte , + AntiFlickerExposureStatus_uwMaxFlickerFreeBunches_MSByte , + AntiFlickerExposureStatus_fpConstrainedFlickerFreePeriod_us_LSByte , + AntiFlickerExposureStatus_fpConstrainedFlickerFreePeriod_us_MSByte , + + //"ModuleEnables//" , + + ModuleEnables_fDisableCho , + ModuleEnables_fDisableChg , + + //"DummyPage1//" + + DummyPage1_bDummyPageElement , + + //"DummyPage2//" , + + DummyPage2_bDummyPageElement , + + //"SensorSetupFarSensor//" , + + SensorSetupFarSensor_uwGuaranteedDataSaturationLevel_LSByte , + SensorSetupFarSensor_uwGuaranteedDataSaturationLevel_MSByte , + SensorSetupFarSensor_uwMinimumSensorRxPixelValue_LSByte , + SensorSetupFarSensor_uwMinimumSensorRxPixelValue_MSByte , + SensorSetupFarSensor_uwMaximumSensorRxPixelValue_LSByte , + SensorSetupFarSensor_uwMaximumSensorRxPixelValue_MSByte , + SensorSetupFarSensor_fpRedTiltGain_LSByte , + SensorSetupFarSensor_fpRedTiltGain_MSByte , + SensorSetupFarSensor_fpGreenTiltGain_LSByte , + SensorSetupFarSensor_fpGreenTiltGain_MSByte , + SensorSetupFarSensor_fpBlueTiltGain_LSByte , + SensorSetupFarSensor_fpBlueTiltGain_MSByte , + SensorSetupFarSensor_BlackCorrectionOffset , + + //"SensorSetupNearSensor//" , + + SensorSetupNearSensor_uwGuaranteedDataSaturationLevel_LSByte , + SensorSetupNearSensor_uwGuaranteedDataSaturationLevel_MSByte , + SensorSetupNearSensor_uwMinimumSensorRxPixelValue_LSByte , + SensorSetupNearSensor_uwMinimumSensorRxPixelValue_MSByte , + SensorSetupNearSensor_uwMaximumSensorRxPixelValue_LSByte , + SensorSetupNearSensor_uwMaximumSensorRxPixelValue_MSByte, + SensorSetupNearSensor_fpRedTiltGain_LSByte , + SensorSetupNearSensor_fpRedTiltGain_MSByte , + SensorSetupNearSensor_fpGreenTiltGain_LSByte , + SensorSetupNearSensor_fpGreenTiltGain_MSByte , + SensorSetupNearSensor_fpBlueTiltGain_LSByte , + SensorSetupNearSensor_fpBlueTiltGain_MSByte , + SensorSetupNearSensor_BlackCorrectionOffset , + + //"ToshibaOtpRead//" , + + ToshibaOtpRead_otp_inf_2 , + ToshibaOtpRead_otp_inf_1 , + ToshibaOtpRead_otp_inf_0 , + ToshibaOtpRead_otp_mac_2 , + ToshibaOtpRead_otp_mac_1 , + ToshibaOtpRead_otp_mac_0 , + ToshibaOtpRead_otp_posA_1 , + ToshibaOtpRead_otp_posA_0 , + ToshibaOtpRead_otp_posB_1 , + ToshibaOtpRead_otp_posB_0 , + ToshibaOtpRead_otp_register_map_ver , + + //"NormalisedWhiteBalanceGains//" , + + NormalisedWhiteBalanceGains_fpNormalisedRedGain_LSByte , + NormalisedWhiteBalanceGains_fpNormalisedRedGain_MSByte , + + //"ReferenceIlluminantCasts//" , + + ReferenceIlluminantCasts_fpCAST0_LSByte , + ReferenceIlluminantCasts_fpCAST0_MSByte, + ReferenceIlluminantCasts_fpCAST1_LSByte , + ReferenceIlluminantCasts_fpCAST1_MSByte , + ReferenceIlluminantCasts_fpCAST2_LSByte , + ReferenceIlluminantCasts_fpCAST2_MSByte , + ReferenceIlluminantCasts_fpCAST3_LSByte , + ReferenceIlluminantCasts_fpCAST3_MSByte , + + //"AdaptiveAVParameter_B//" , + + AdaptiveAVParameter_B_bAvUnityOffset_Day , + AdaptiveAVParameter_B_bAvCoeffR2_Day , + AdaptiveAVParameter_B_bAvCoeffR4_Day , + AdaptiveAVParameter_B_wAvHOffset_Day_LSByte , + AdaptiveAVParameter_B_wAvHOffset_Day_MSByte , + AdaptiveAVParameter_B_wAvVOffset_Day_LSByte , + AdaptiveAVParameter_B_wAvVOffset_Day_MSByte , + AdaptiveAVParameter_B_bAvUnityOffset_COO , + AdaptiveAVParameter_B_bAvCoeffR2_COO , + AdaptiveAVParameter_B_bAvCoeffR4_COO , + AdaptiveAVParameter_B_wAvHOffset_COO_LSByte , + AdaptiveAVParameter_B_wAvHOffset_COO_MSByte , + AdaptiveAVParameter_B_wAvVOffset_COO_LSByte , + AdaptiveAVParameter_B_wAvVOffset_COO_MSByte , + AdaptiveAVParameter_B_bAvUnityOffset_INC , + AdaptiveAVParameter_B_bAvCoeffR2_INC , + AdaptiveAVParameter_B_bAvCoeffR4_INC , + AdaptiveAVParameter_B_wAvHOffset_INC_LSByte , + AdaptiveAVParameter_B_wAvHOffset_INC_MSByte , + AdaptiveAVParameter_B_wAvVOffset_INC_LSByte , + AdaptiveAVParameter_B_wAvVOffset_INC_MSByte , + AdaptiveAVParameter_B_bAvUnityOffset_HOR, + AdaptiveAVParameter_B_bAvCoeffR2_HOR , + AdaptiveAVParameter_B_bAvCoeffR4_HOR , + AdaptiveAVParameter_B_wAvHOffset_HOR_LSByte , + AdaptiveAVParameter_B_wAvHOffset_HOR_MSByte , + AdaptiveAVParameter_B_wAvVOffset_HOR_LSByte , + AdaptiveAVParameter_B_wAvVOffset_HOR_MSByte , + + //"AdaptiveAVParameter_GB//" , + + AdaptiveAVParameter_GB_bAvUnityOffset_Day , + AdaptiveAVParameter_GB_bAvCoeffR2_Day , + AdaptiveAVParameter_GB_bAvCoeffR4_Day , + AdaptiveAVParameter_GB_wAvHOffset_Day_LSByte , + AdaptiveAVParameter_GB_wAvHOffset_Day_MSByte , + AdaptiveAVParameter_GB_wAvVOffset_Day_LSByte , + AdaptiveAVParameter_GB_wAvVOffset_Day_MSByte , + AdaptiveAVParameter_GB_bAvUnityOffset_COO , + AdaptiveAVParameter_GB_bAvCoeffR2_COO , + AdaptiveAVParameter_GB_bAvCoeffR4_COO , + AdaptiveAVParameter_GB_wAvHOffset_COO_LSByte , + AdaptiveAVParameter_GB_wAvHOffset_COO_MSByte , + AdaptiveAVParameter_GB_wAvVOffset_COO_LSByte , + AdaptiveAVParameter_GB_wAvVOffset_COO_MSByte , + AdaptiveAVParameter_GB_bAvUnityOffset_INC , + AdaptiveAVParameter_GB_bAvCoeffR2_INC , + AdaptiveAVParameter_GB_bAvCoeffR4_INC , + AdaptiveAVParameter_GB_wAvHOffset_INC_LSByte , + AdaptiveAVParameter_GB_wAvHOffset_INC_MSByte , + AdaptiveAVParameter_GB_wAvVOffset_INC_LSByte , + AdaptiveAVParameter_GB_wAvVOffset_INC_MSByte , + AdaptiveAVParameter_GB_bAvUnityOffset_HOR, + AdaptiveAVParameter_GB_bAvCoeffR2_HOR , + AdaptiveAVParameter_GB_bAvCoeffR4_HOR , + AdaptiveAVParameter_GB_wAvHOffset_HOR_LSByte , + AdaptiveAVParameter_GB_wAvHOffset_HOR_MSByte , + AdaptiveAVParameter_GB_wAvVOffset_HOR_LSByte , + AdaptiveAVParameter_GB_wAvVOffset_HOR_MSByte , + + //"AdaptiveAVParameter_GR//" , + + AdaptiveAVParameter_GR_bAvUnityOffset_Day , + AdaptiveAVParameter_GR_bAvCoeffR2_Day , + AdaptiveAVParameter_GR_bAvCoeffR4_Day , + AdaptiveAVParameter_GR_wAvHOffset_Day_LSByte , + AdaptiveAVParameter_GR_wAvHOffset_Day_MSByte , + AdaptiveAVParameter_GR_wAvVOffset_Day_LSByte , + AdaptiveAVParameter_GR_wAvVOffset_Day_MSByte , + AdaptiveAVParameter_GR_bAvUnityOffset_COO , + AdaptiveAVParameter_GR_bAvCoeffR2_COO , + AdaptiveAVParameter_GR_bAvCoeffR4_COO , + AdaptiveAVParameter_GR_wAvHOffset_COO_LSByte , + AdaptiveAVParameter_GR_wAvHOffset_COO_MSByte , + AdaptiveAVParameter_GR_wAvVOffset_COO_LSByte , + AdaptiveAVParameter_GR_wAvVOffset_COO_MSByte , + AdaptiveAVParameter_GR_bAvUnityOffset_INC , + AdaptiveAVParameter_GR_bAvCoeffR2_INC , + AdaptiveAVParameter_GR_bAvCoeffR4_INC , + AdaptiveAVParameter_GR_wAvHOffset_INC_LSByte , + AdaptiveAVParameter_GR_wAvHOffset_INC_MSByte , + AdaptiveAVParameter_GR_wAvVOffset_INC_LSByte , + AdaptiveAVParameter_GR_wAvVOffset_INC_MSByte , + AdaptiveAVParameter_GR_bAvUnityOffset_HOR, + AdaptiveAVParameter_GR_bAvCoeffR2_HOR , + AdaptiveAVParameter_GR_bAvCoeffR4_HOR , + AdaptiveAVParameter_GR_wAvHOffset_HOR_LSByte , + AdaptiveAVParameter_GR_wAvHOffset_HOR_MSByte , + AdaptiveAVParameter_GR_wAvVOffset_HOR_LSByte , + AdaptiveAVParameter_GR_wAvVOffset_HOR_MSByte , + + //"AdaptiveAVParameter_R//" , + + AdaptiveAVParameter_R_bAvUnityOffset_Day , + AdaptiveAVParameter_R_bAvCoeffR2_Day , + AdaptiveAVParameter_R_bAvCoeffR4_Day , + AdaptiveAVParameter_R_wAvHOffset_Day_LSByte , + AdaptiveAVParameter_R_wAvHOffset_Day_MSByte , + AdaptiveAVParameter_R_wAvVOffset_Day_LSByte , + AdaptiveAVParameter_R_wAvVOffset_Day_MSByte , + AdaptiveAVParameter_R_bAvUnityOffset_COO , + AdaptiveAVParameter_R_bAvCoeffR2_COO , + AdaptiveAVParameter_R_bAvCoeffR4_COO , + AdaptiveAVParameter_R_wAvHOffset_COO_LSByte , + AdaptiveAVParameter_R_wAvHOffset_COO_MSByte , + AdaptiveAVParameter_R_wAvVOffset_COO_LSByte , + AdaptiveAVParameter_R_wAvVOffset_COO_MSByte , + AdaptiveAVParameter_R_bAvUnityOffset_INC , + AdaptiveAVParameter_R_bAvCoeffR2_INC , + AdaptiveAVParameter_R_bAvCoeffR4_INC , + AdaptiveAVParameter_R_wAvHOffset_INC_LSByte , + AdaptiveAVParameter_R_wAvHOffset_INC_MSByte , + AdaptiveAVParameter_R_wAvVOffset_INC_LSByte , + AdaptiveAVParameter_R_wAvVOffset_INC_MSByte , + AdaptiveAVParameter_R_bAvUnityOffset_HOR, + AdaptiveAVParameter_R_bAvCoeffR2_HOR , + AdaptiveAVParameter_R_bAvCoeffR4_HOR , + AdaptiveAVParameter_R_wAvHOffset_HOR_LSByte , + AdaptiveAVParameter_R_wAvHOffset_HOR_MSByte , + AdaptiveAVParameter_R_wAvVOffset_HOR_LSByte , + AdaptiveAVParameter_R_wAvVOffset_HOR_MSByte , + + //"ContrastStretchControl//" , + + ContrastStretchControl_fEnableContrastStretch , + ContrastStretchControl_bMode , + ContrastStretchControl_bAccColour , + ContrastStretchControl_bBlackThreshold , + ContrastStretchControl_bWhiteThreshold , + + //"ContrastStretchStatus//" , + + ContrastStretchStatus_uBlackBinAThreshold_hi , + ContrastStretchStatus_uBlackBinBThreshold_hi , + ContrastStretchStatus_uWhiteBinAThreshold_lo , + ContrastStretchStatus_uWhiteBinBThreshold_lo , + ContrastStretchStatus_fpGain_LSByte , + ContrastStretchStatus_fpGain_MSByte , + + //"DynamicConstrainedWBControls//" , + + DynamicConstrainedWBControls_fpRedA_LSByte , + DynamicConstrainedWBControls_fpRedA_MSByte , + DynamicConstrainedWBControls_fpBlueA_LSByte , + DynamicConstrainedWBControls_fpBlueA_MSByte , + DynamicConstrainedWBControls_fpDamperLowThreshold_LSByte, + DynamicConstrainedWBControls_fpDamperLowThreshold_MSByte , + DynamicConstrainedWBControls_fpMinimumDamperOutput_LSByte , + DynamicConstrainedWBControls_fpMinimumDamperOutput_MSByte , + DynamicConstrainedWBControls_fpDamperHighThreshold_LSByte , + DynamicConstrainedWBControls_fpDamperHighThreshold_MSByte , + DynamicConstrainedWBControls_fDamperDisable , + + //"Toshiba_AF_NVM_Read//" , + + Toshiba_AF_NVM_Read_NVM_Far2Near_inf_LSByte , + Toshiba_AF_NVM_Read_NVM_Far2Near_inf_MSByte , + Toshiba_AF_NVM_Read_NVM_Near2Far_inf_LSByte , + Toshiba_AF_NVM_Read_NVM_Near2Far_inf_MSByte , + Toshiba_AF_NVM_Read_NVM_Far2Near_mac_LSByte , + Toshiba_AF_NVM_Read_NVM_Far2Near_mac_MSByte , + Toshiba_AF_NVM_Read_NVM_Near2Far_mac_LSByte , + Toshiba_AF_NVM_Read_NVM_Near2Far_mac_MSByte , + Toshiba_AF_NVM_Read_NVM_Pos_A_LSByte , + Toshiba_AF_NVM_Read_NVM_Pos_A_MSByte , + Toshiba_AF_NVM_Read_NVM_Pos_B_LSByte , + Toshiba_AF_NVM_Read_NVM_Pos_B_MSByte , + + //"Toshiba_Vcm_Parameters//" , + + Toshiba_Vcm_Parameters_wLowLevelMacroPos_LSByte , + Toshiba_Vcm_Parameters_wLowLevelMacroPos_MSByte , + Toshiba_Vcm_Parameters_wLowLevelInfinityPos_LSByte , + Toshiba_Vcm_Parameters_wLowLevelInfinityPos_MSByte , + Toshiba_Vcm_Parameters_bSlewControlModeEnable , + Toshiba_Vcm_Parameters_bSlewModeForSmallerStep , + Toshiba_Vcm_Parameters_bSlewRateForSmallerStep, + Toshiba_Vcm_Parameters_bSlewModeForLargerStep , + Toshiba_Vcm_Parameters_bSlewRateForLargerStep , + Toshiba_Vcm_Parameters_bThresholdStepSize , + + //"Toshiba_Vcm_Status//" , + + Toshiba_Vcm_Status_wLowLevelPos_LSByte , + Toshiba_Vcm_Status_wLowLevelPos_MSByte , + + //"AdaptiveColourMatrix//" , + + AdaptiveColourMatrix_fpNormalisedRedGain0_LSByte , + AdaptiveColourMatrix_fpNormalisedRedGain0_MSByte , + AdaptiveColourMatrix_fpNormalisedRedGain1_LSByte , + AdaptiveColourMatrix_fpNormalisedRedGain1_MSByte , + AdaptiveColourMatrix_bChooseAdaptiveColourMatrix , + + //"ColourEngine1_ColourMatrixFarSensor//" , + + ColourEngine1_ColourMatrixFarSensor_fpRInR_LSByte , + ColourEngine1_ColourMatrixFarSensor_fpRInR_MSByte , + ColourEngine1_ColourMatrixFarSensor_fpGInR_LSByte , + ColourEngine1_ColourMatrixFarSensor_fpGInR_MSByte , + ColourEngine1_ColourMatrixFarSensor_fpBInR_LSByte , + ColourEngine1_ColourMatrixFarSensor_fpBInR_MSByte , + ColourEngine1_ColourMatrixFarSensor_fpRInG_LSByte , + ColourEngine1_ColourMatrixFarSensor_fpRInG_MSByte , + ColourEngine1_ColourMatrixFarSensor_fpGInG_LSByte , + ColourEngine1_ColourMatrixFarSensor_fpGInG_MSByte , + ColourEngine1_ColourMatrixFarSensor_fpBInG_LSByte , + ColourEngine1_ColourMatrixFarSensor_fpBInG_MSByte, + ColourEngine1_ColourMatrixFarSensor_fpRInB_LSByte , + ColourEngine1_ColourMatrixFarSensor_fpRInB_MSByte , + ColourEngine1_ColourMatrixFarSensor_fpGInB_LSByte , + ColourEngine1_ColourMatrixFarSensor_fpGInB_MSByte , + ColourEngine1_ColourMatrixFarSensor_fpBInB_LSByte , + ColourEngine1_ColourMatrixFarSensor_fpBInB_MSByte , + + //"ColourEngine1_ColourMatrixNearSensor//" , + + ColourEngine1_ColourMatrixNearSensor_fpRInR_LSByte , + ColourEngine1_ColourMatrixNearSensor_fpRInR_MSByte , + ColourEngine1_ColourMatrixNearSensor_fpGInR_LSByte , + ColourEngine1_ColourMatrixNearSensor_fpGInR_MSByte , + ColourEngine1_ColourMatrixNearSensor_fpBInR_LSByte , + ColourEngine1_ColourMatrixNearSensor_fpBInR_MSByte , + ColourEngine1_ColourMatrixNearSensor_fpRInG_LSByte , + ColourEngine1_ColourMatrixNearSensor_fpRInG_MSByte , + ColourEngine1_ColourMatrixNearSensor_fpGInG_LSByte , + ColourEngine1_ColourMatrixNearSensor_fpGInG_MSByte , + ColourEngine1_ColourMatrixNearSensor_fpBInG_LSByte , + ColourEngine1_ColourMatrixNearSensor_fpBInG_MSByte , + ColourEngine1_ColourMatrixNearSensor_fpRInB_LSByte , + ColourEngine1_ColourMatrixNearSensor_fpRInB_MSByte , + ColourEngine1_ColourMatrixNearSensor_fpGInB_LSByte , + ColourEngine1_ColourMatrixNearSensor_fpGInB_MSByte , + ColourEngine1_ColourMatrixNearSensor_fpBInB_LSByte , + ColourEngine1_ColourMatrixNearSensor_fpBInB_MSByte , + + //"WhiteBalanceGainLimit//" , + + WhiteBalanceGainLimit_fpWhiteBalanceGainLimit_LSByte, + WhiteBalanceGainLimit_fpWhiteBalanceGainLimit_MSByte , + + //"ToshibaTechnicalParamTuner//" , + + ToshibaTechnicalParamTuner_uwHostLevelMacroPos_LSByte , + ToshibaTechnicalParamTuner_uwHostLevelMacroPos_MSByte , + ToshibaTechnicalParamTuner_uwHostLevelInfinityPos_LSByte , + ToshibaTechnicalParamTuner_uwHostLevelInfinityPos_MSByte , + ToshibaTechnicalParamTuner_uwDefAFMaxStandardRange_um_LSByte , + ToshibaTechnicalParamTuner_uwDefAFMaxStandardRange_um_MSByte , + ToshibaTechnicalParamTuner_bDefFineStepParam_um , + ToshibaTechnicalParamTuner_bDefCoarseStepParam_um , + ToshibaTechnicalParamTuner_fHostDefTechParam , + + + IRPLastPreviewWOI_X_Byte0 , + IRPLastPreviewWOI_X_Byte1 , + IRPLastPreviewWOI_X_Byte2 , + IRPLastPreviewWOI_X_Byte3 , + ModeSetupBank2_bActiveSensor , + ModeSetupBank3_bActiveSensor + +} vpip_reg_name; + +typedef enum { + +USER_MODE_AWB_AUTO=0, +USER_MODE_AWB_DAYLIGHT, +USER_MODE_AWB_CLOUDY, +USER_MODE_AWB_TUNGSTEN, +USER_MODE_AWB_MODE_FLUORESCENT, + +USER_MODE_EC_NORMAL, +USER_MODE_EC_Plus03, +USER_MODE_EC_Plus06, +USER_MODE_EC_Plus10, +USER_MODE_EC_Plus13, +USER_MODE_EC_Plus16, +USER_MODE_EC_Plus20, +USER_MODE_EC_Minus03, +USER_MODE_EC_Minus06, +USER_MODE_EC_Minus10, +USER_MODE_EC_Minus13, +USER_MODE_EC_Minus16, +USER_MODE_EC_Minus20, + +USER_MODE_ISO_AUTO, +USER_MODE_ISO_050, +USER_MODE_ISO_100, +USER_MODE_ISO_200, +USER_MODE_ISO_400, +USER_MODE_ISO_800, + +USER_MODE_COLORTONE_NORMAL, +USER_MODE_COLORTONE_SEPIA , +USER_MODE_COLORTONE_GRAYSCALE, +USER_MODE_COLORTONE_VIVID , +USER_MODE_COLORTONE_NEGATIVE, + +USER_MODE_CONTRAST_NORMAL, +USER_MODE_CONTRAST_110, +USER_MODE_CONTRAST_120, +USER_MODE_CONTRAST_130, +USER_MODE_CONTRAST_140, +USER_MODE_CONTRAST_150, +USER_MODE_CONTRAST_160, +USER_MODE_CONTRAST_170, +USER_MODE_CONTRAST_180, +USER_MODE_CONTRAST_190, +USER_MODE_CONTRAST_200, + +USER_MODE_SHARPNESS_NORMAL, +USER_MODE_SHARPNESS_HARD, +USER_MODE_SHARPNESS_SOFT, +USER_MODE_SHARPNESS_NONE, + +USER_MODE_EXPOSURE_AUTO, +USER_MODE_EXPOSURE_NIGHT, +USER_MODE_EXPOSURE_CENTER, +USER_MODE_EXPOSURE_BACKLIGHT, +USER_MODE_EXPOSURE_SPORT + +}vpip_user_mode; + +typedef enum { +SCENE_MODE_AUTO=0, +SCENE_MODE_LANDSCAPE, +SCENE_MODE_NIGHT, +SCENE_MODE_PORTRAIT, +SCENE_MODE_SPORTS, +SCENE_MODE_CLOSEUP +}vpip_scene_mode; + + +struct vpip_usermode_update{ +__u32 service_id; +vpip_user_mode user_mode; +}; + + +struct vpip_autofocus_id{ +__u32 service_id; +int value; +}; + + + +struct message_data { + enum sva_message_type type; + struct sva_buffer buffer; +}; + +struct sva_message { + enum block_type block; + __u32 timeout; + __u32 service_id; + __u32 msg_count; + struct message_data *messages; +}; + +struct sva_codec_bitstream_data { +__u32 service_id; +__u32 data_type; +__u8 *buffer; +__u32 length; +}; + +struct sva_service_time { +__u32 service_id; +__u32 time; +}; +struct vpip_params{ +unsigned char register_name[50]; +__u16 addr; +__u16 val; +}; + +struct nomadik_vpip_param { +vpip_reg_name vpip_config_reg; +__u16 addr; +__u16 val; +__u32 index; +}; + + +#define SVA_CREATE_SERVICE _IOWR('S', 1, struct sva_service_struct) +#define SVA_CONTROL_SERVICE _IOWR('S', 2, struct sva_control_service) +#define SVA_UPDATE_SERVICE _IOWR('S', 3, struct sva_update_service) +#define SVA_ALLOCATE_BUFFER _IOWR('S', 4, struct sva_buffer) +#define SVA_DEALLOCATE_BUFFER _IOWR('S', 5, unsigned long) +#define SVA_QUEUE_BUFFER _IOWR('S', 6, struct sva_queue_buffer) +#define SVA_DEQUEUE_BUFFER _IOWR('S', 7, struct sva_queue_buffer) +#define SVA_DELETE_SERVICE _IOWR('S', 8, struct sva_service_struct) +#define SVA_GET_MESSAGES _IOWR('S', 9, struct sva_message) +#define SVA_SET_HEADER _IOW('S', 10, struct sva_codec_header_infos) +#define SVA_FLUSH_SERVICE _IOR('S', 11, struct sva_service_struct) +#define SVA_GET_BITSTREAM_DATA _IOR('S', 12, struct sva_codec_bitstream_data) +#define SVA_SET_SERVICE_TIME _IOW('S', 13, struct sva_service_time) +#define SVA_GET_SERVICE_TIME _IOR('S', 14, struct sva_service_time) +#define SVA_END_BITSTREAM _IOWR('S', 15, struct sva_service_struct) +#define SVA_COPY_VPIP_PARAMS _IOWR('S', 16, struct nomadik_vpip_param) + + + +#endif /* __SVA_SERVICES_H__*/ --- /dev/null +++ linux-2.6.20/drivers/media/video/nomadik_sva_utils.h @@ -0,0 +1,49 @@ +/*--------------------------------------------------------------------------------------------------*/ +/*© copyright STMicroelectronics, 2007. */ +/* */ +/*This program is free software; you can redistribute it and/or modify it under */ +/*the terms of the GNU General Public License as published by the Free */ +/*Software Foundation; either version 2.1 of the License, or (at your option) */ +/*any later version. */ +/* */ +/*This program is distributed in the hope that it will be useful, but WITHOUT */ +/*ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU General Public License for more details. */ +/* */ +/*You should have received a copy of the GNU General Public License */ +/*along with this program. If not, see . */ +/*--------------------------------------------------------------------------------------------------*/ + + + + + + +#ifndef __SVA_UTILS_H__ +#define __SVA_UTILS_H__ + +/* Simple queue management */ + +struct sva_q_node +{ + struct sva_q_node *forw, *back; +}; + +struct sva_queue +{ + struct sva_q_node *forw, *back; + rwlock_t qlock; +}; + +extern void sva_q_init(struct sva_queue *q); +extern void sva_q_add_head(struct sva_queue *q, struct sva_q_node *node); +extern void sva_q_add_tail(struct sva_queue *q, struct sva_q_node *node); +extern void *sva_q_del_head(struct sva_queue *q); +extern void *sva_q_del_tail(struct sva_queue *q); +extern void *sva_q_peek_head(struct sva_queue *q); +extern void *sva_q_peek_tail(struct sva_queue *q); +extern void *sva_q_yank_node(struct sva_queue *q, struct sva_q_node *node); +extern int sva_q_last(struct sva_queue *q); + +#endif --- /dev/null +++ linux-2.6.20/drivers/media/video/platform_os.h @@ -0,0 +1,55 @@ +/* Dummy file used to define some conditionnal compilation flags */ +#ifndef __INC_PLATFORM_OS_H +#define __INC_PLATFORM_OS_H + +#include +#undef NULL + +/* + * Define alignment macro + */ +#undef ALIGN +#if defined(__CC_ARM) +#define ALIGN(a) /* __align(a) */ __attribute__ ((aligned (a))) +#elif defined(__GNUC__) +#define ALIGN(a) __attribute__ ((aligned (a))) +#else +#define ALIGN(a) +#endif + +/* + * Define assertion macro + */ +#define HCL_ASSERT(a) ((a)?(void)0:do_exit(0)) + +/* + * Define assertion macro for debug only + */ +#ifdef __DEBUG + #define HCL_DEBUG_ASSERT(a) HCL_ASSERT(a) +#else + #define HCL_DEBUG_ASSERT(a) {if(a){(void)0;}} +#endif + +/* + * Define the SPRINTF macro use inside hv_XX_debugPrintf functions + * This routine SHALL support a format parameter with %d, %x, %s and width qualifiers + * AND return the number of bytes written in the output string + */ +#define SPRINTF(current, max, buffer, ...) \ + { \ + if ((current + 80) > max) {break;} \ + current += sprintf(buffer, __VA_ARGS__); \ + } + +/* + * Define extended ANSI C unsigned long long type + * could be redefine for each OS + * ie: for WINCE: + * typedef unsigned __int64 t_uint64; + * typedef __int64 t_sint64; + */ +typedef unsigned long long t_uint64; +typedef signed long long t_sint64; + +#endif /* __INC_PLATFORM_OS_H */ --- /dev/null +++ linux-2.6.20/drivers/media/video/sva.h @@ -0,0 +1,2148 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ + +#ifndef __INC_SVA_H +#define __INC_SVA_H + +#include "hcl_defs.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* + * Definition of the HCL SVA Version numbers + */ +#define SVA_HCL_VERSION_ID 8 +#define SVA_HCL_MAJOR_ID 0 +#define SVA_HCL_MINOR_ID 0 + +/* + * Definition of unknown version number + + */ +#define UNDEFINED_VERSION {MASK_ALL8,MASK_ALL8,MASK_ALL16} + +/* + * define symbol to disallow grab sync line generation + */ +#define SVA_NO_GRABSYNC_LINE 0x3ff + +/* + * define search window size in ESRAM (encode and stab) + */ + +#define SVA_EC_SEARCHWINDOW_SIZE (48*1024) + +/* Maximum number of video packets generated by Firmware per frame */ +/**<\brief positions of the first video packets (up to 32) +* that have been written by an MPEG4encode subtask. It is +* used only when flag_short_header=0. The positions are +* given in bytes,relatively to the beginning of the +* bitstream that has been written,including the header. +*/ +#define SVA_EC_MPEG4_VP_POS_COUNT 32 + +/* Maximum number of video slices generated by Firmware per frame */ +/* Positions of the 1st slices (up to 32) */ +#define SVA_EC_H263_SLICE_POS_COUNT 32 + +/* Maximum number of video slices generated by Firmware Per frame */ +/**<\brief positions of the first slices (up to 1320 enough for SDTV) that have been written by an H264 encode subtask. */ +//\/ Sarvesh: This size has been increased from 32 to 1320 for H264 Encode and to 1620 with FW 3.6.0 +#define SVA_EC_H264_SLICE_POS_COUNT 1620 + +#define SVA_LAST_IAD_EOT_ERR_RESET_VAL 0x45524F52UL + +typedef enum { + SVA_IRQ +} t_sva_irq_src; + +/* + * Define type used to memorize the current status of the IRQ sources + */ +typedef struct { + t_uint32 dummy_tab[30]; +}t_sva_irq_status; + +typedef enum { +SVA_LAST_ERROR = -64, +/* Internal HCL errors */ +SVA_INTERNAL_MEMORY_MGT_ERROR, +SVA_INTERNAL_VIDEO_DECODER_ERROR, +SVA_INTERNAL_VIDEO_ENCODER_ERROR, +SVA_INTERNAL_STILL_DECODER_ERROR, +SVA_INTERNAL_STILL_ENCODER_ERROR, +SVA_INTERNAL_POSTPROCESSOR_ERROR, +SVA_INTERNAL_PREPROCESSOR_ERROR, +SVA_INTERNAL_TV_OUTPUT_ERROR, +SVA_INTERNAL_SWPROCESSOR_ERROR, +SVA_INTERNAL_EVENT_MGT_ERROR, +SVA_INTERNAL_NEEDS_ERROR, +SVA_INTERNAL_TASK_MGT_ERROR, +/* Wrong HCL usage */ +SVA_IMAGE_BUFFER_TOO_SMALL, +SVA_INCOHERENT_CONFIGURATION, +SVA_UNEXPECTED_API_CALL, +SVA_MISALIGNED_BUFFER, +SVA_BUFFER_IS_IN_USE, +SVA_UNKNOWN_SERVICE_ID, +SVA_INCOHERENT_SERVICE_TYPE, +SVA_UNKNOWN_CMD_ID, +SVA_UNKNOWN_BUFFER_ID, +SVA_INVALID_BUFFER_TYPE, +SVA_OUT_OF_MEMORY, +SVA_NO_MORE_CHUNK, +SVA_NO_MORE_FW_ID, +SVA_UNKNOWN_FW_ID, +SVA_FW_CONFLICT, +SVA_FW_NOT_PROVIDED, +SVA_INCOHERENT_FW_PROVIDED, +SVA_NOT_SUPPORTED_YET, +SVA_UNREGISTERED_FIRMWARE_ID, +SVA_NO_MORE_FIRMWARE_ID, +SVA_FATAL_ERROR = -4, +SVA_INTERNAL_FIFOS_FULL, +SVA_FW_DOWNLOAD_NEEDED, +SVA_OK = HCL_OK, +SVA_REMAINING_PENDING_EVENTS = HCL_REMAINING_PENDING_EVENTS, +SVA_NO_MORE_PENDING_EVENT = HCL_NO_MORE_PENDING_EVENT, +SVA_NO_PENDING_EVENT_ERROR = HCL_NO_PENDING_EVENT_ERROR, +SVA_IMMEDIATE_UPDATE, +SVA_DELAYED_UPDATE, +SVA_FW_SWITCH_OCCURED, +SVA_FW_SWITCH_DELAYED, +SVA_CONFIGURATION_IN_PROGRESS, +SVA_VIDEO_DECODER_IMAGE_BUFFER_NEEDED, +SVA_VIDEO_ENCODER_DATA_ERROR, +SVA_INSUFFICIENT_MEMORY, +} t_sva_error; + + +typedef enum { +SVA_IRQ_0, +SVA_IRQ_1 +}t_sva_irq_num; + + +typedef enum { +SVA_SERVICE_NONE = 0, +SVA_PREPROCESSOR = 1, +SVA_VIDEO_DECODER = 2, +SVA_VIDEO_ENCODER = 3, +SVA_POSTPROCESSOR = 4, +SVA_STILL_IMAGE_ENCODER = 5, +SVA_STILL_IMAGE_DECODER = 6, +SVA_TV_OUTPUT = 7, +SVA_SW_PROCESSING = 8, +SVA_OPEN_SERVICE_0 = 128, +SVA_OPEN_SERVICE_1 = 129, +SVA_OPEN_SERVICE_2 = 130, +SVA_OPEN_SERVICE_3 = 131, +SVA_OPEN_SERVICE_4 = 132, +SVA_OPEN_SERVICE_5 = 133, +SVA_OPEN_SERVICE_6 = 134, +SVA_OPEN_SERVICE_7 = 135 +}t_sva_service_type; + + +typedef enum { +SVA_REALTIME_SERVICE, +SVA_NON_REALTIME_SERVICE +} t_sva_service_mode; + + +typedef enum { +SVA_SERVICE_NOT_INITIALIZED = MASK_BIT0, +SVA_SERVICE_WAIT_FOR_CONFIGURATION = MASK_BIT1, +SVA_SERVICE_WAIT_FOR_INTERNAL_NEEDS = MASK_BIT2, +SVA_SERVICE_WAIT_FOR_ACTIVATE = MASK_BIT3, +SVA_SERVICE_WAIT_FOR_START = MASK_BIT4, +SVA_SERVICE_FLUSHING = MASK_BIT5, +SVA_SERVICE_WAIT_FOR_DATA = MASK_BIT6, +SVA_SERVICE_RUNNING = MASK_BIT7, +SVA_SERVICE_ABORT_REQUESTED = MASK_BIT8, +SVA_SERVICE_STOP_REQUESTED = MASK_BIT9, +SVA_SERVICE_ERROR = MASK_BIT10 +} t_sva_service_state; + + +typedef enum { +SVA_UNKNOWN_BUFFER_TYPE = 0, +SVA_BITSTREAM_BUFFER_TYPE, +SVA_IMAGE_BUFFER_TYPE, +SVA_INFOS_BUFFER_TYPE, +SVA_PARAMS_BUFFER_TYPE, +SVA_INTERNAL_BUFFER_TYPE +} t_sva_buffer_type; + +typedef enum { +SVA_VC1_DEDICATED_BUFFER, +SVA_GB_HQ_DEDICATED_BUFFER +} t_sva_buffer_usage; + +typedef enum { +SVA_BUFFER_NOT_INIT, +SVA_BUFFER_NOT_USED, +SVA_BUFFER_IN_USE, +SVA_BUFFER_VOIDED, +SVA_BUFFER_FILLED +} t_sva_buffer_state; + + +typedef enum { +SVA_PUSH_IN, +SVA_PUSH_OUT +} t_sva_push_mode; + + +typedef enum { +SVA_INOUT_STREAM, +SVA_INOUT_BITSTREAM_BUFFER, +SVA_INOUT_IMAGE_BUFFER, +SVA_INOUT_INFOS_BUFFER, +SVA_INOUT_PARAMS_BUFFER +} t_sva_inout_type; + + +typedef enum { +SVA_INOUT_BINARY, // this format will be used for buffer whose internal organization is +// unknown or contain data of a unique type (Y/U/V) (JPEG case) +SVA_INOUT_YUV422, +SVA_INOUT_YUV420, +SVA_INOUT_RGB444, +SVA_INOUT_RGB555, +SVA_INOUT_RGB565, +SVA_INOUT_RGB888_PACKED, +SVA_INOUT_RGB888_UNPACKED, +SVA_INOUT_PARAMS_DEBLOCKING, //identify a buffer containing the deblocking filter parameters +SVA_INOUT_PARAMS_ACE, //identify a buffer containing the ACE offset from JPEG decode +// List various type of info buffer those could be provided by the various services +SVA_INOUT_INFO_VIDEO_ENCODER, // linked to the codec (MPEG4/H263/...) +SVA_INOUT_INFO_VIDEO_DECODER // linked to the codec (MPEG4/H263/...) +} t_sva_inout_format; + + +typedef enum { +SVA_PREPROCESSOR_RAW, +SVA_PREPROCESSOR_YUV420_MB, +SVA_PREPROCESSOR_YUV420_SEP_COMP_MB, +SVA_PREPROCESSOR_YUV422_SEP_COMP_MB, +SVA_PREPROCESSOR_YUV420_RASTER_OUT, +SVA_PREPROCESSOR_SENSOR_YUV420_MB, +SVA_PREPROCESSOR_SENSOR_YUV420_SEP_COMP_MB, +SVA_PREPROCESSOR_SENSOR_YUV422_SEP_COMP_MB, +SVA_PREPROCESSOR_SENSOR_YUV420_RASTER_OUT, +SVA_PREPROCESSOR_SENSOR_HIGHQUALITY_YUV420_MB +} t_sva_preprocessor_capability_id; + + +typedef enum { +SVA_POSTPROCESSOR_RGB=0, // YUV420 Macroblock tiled to RGB +SVA_POSTPROCESSOR_YUV=1, // YUV422 format (used as TVO input) + +SVA_POSTPROCESSOR_YUV420PL_TO_RGB=2, // YUV420 planar raster to RGB +SVA_POSTPROCESSOR_YUV420MB_TO_YUV420MB=3, // YUV420 MB tiled to YUV420 MB tiled +SVA_POSTPROCESSOR_YUV420PL_TO_YUV422PL=4, +SVA_POSTPROCESSOR_YUV422PL_TO_RGB=5, // NOT SUPPORTED!!!! +SVA_POSTPROCESSOR_YUV420MB_TO_RGB = SVA_POSTPROCESSOR_RGB, // YUV420 Macroblock tiled to RGB +SVA_POSTPROCESSOR_YUV420MB_TO_YUV422PL = SVA_POSTPROCESSOR_YUV, // YUV420 MB tiled to YUV422 planar raster (TVO input) +SVA_POSTPROCESSOR_YUV420MB_TO_YUV420_SEP_COMP_MB=6, +SVA_POSTPROCESSOR_YUV420MB_TO_YUV422_SEP_COMP_MB=7, +} t_sva_postprocessor_capability_id; + + +typedef enum { +SVA_DECODER_H263_P0_L10, +SVA_DECODER_H263_P0_L30, +SVA_DECODER_H263_P3_L10, +SVA_DECODER_H263_P3_L30, +SVA_DECODER_MPEG4_SP_L4A, +SVA_DECODER_H264, +SVA_DECODER_VC1_MP_LL, +SVA_DECODER_MPEG2_MP_ML +} t_sva_video_decoder_capability_id; + + +typedef enum { +SVA_ENCODER_H263_P0_L10, +SVA_ENCODER_H263_P0_L30, +SVA_ENCODER_H263_P3_L10, +SVA_ENCODER_H263_P3_L30, +SVA_ENCODER_MPEG4_SP_L4A, +SVA_ENCODER_H264 +} t_sva_video_encoder_capability_id; + + +typedef enum { + SVA_IMAGE_STABILIZATION +} t_sva_sw_processing_capability_id; + + +typedef enum { +SVA_ENCODER_JPEG_MONOCHROME, +SVA_ENCODER_JPEG_420_SEP_COMP_MB, +SVA_ENCODER_JPEG_422_SEP_COMP_MB, +SVA_ENCODER_JPEG_444_SEP_COMP_MB, +SVA_ENCODER_JPEG_420_MB +} t_sva_still_image_encoder_capability_id; + + +typedef enum { +SVA_DECODER_PROGRESSIVE_JPEG, +SVA_DECODER_SEQUENTIAL_JPEG +} t_sva_still_image_decoder_capability_id; + + +typedef enum { +SVA_NO_MIRRORING, +SVA_HORIZONTAL_MIRRORING, +SVA_VERTICAL_MIRRORING +} t_sva_mirroring_mode; + + +typedef enum { +SVA_NO_ROTATION, +SVA_ROTATION_90, +SVA_ROTATION_180, +SVA_ROTATION_270 +} t_sva_rotation_mode; + + +#define NUMBER_OF_DEBLOCKING_FILTER_MODE 4 +typedef enum { +SVA_NONE_DEBLOCKING_FILTER, +SVA_MPEG4_DEBLOCKING_FILTER, +SVA_H263_DEBLOCKING_FILTER, +SVA_H264_DEBLOCKING_FILTER, +SVA_MPEG2_DEBLOCKING_FILTER +} t_sva_deblocking_filter_mode; + + +#define NUMBER_OF_DERINGING_FILTER_MODE 3 +typedef enum { +SVA_NONE_DERINGING_FILTER, +SVA_MPEG4_DERINGING_FILTER, +SVA_H264_DERINGING_FILTER, +SVA_MPEG2_DERINGING_FILTER +} t_sva_deringing_filter_mode; + + +typedef enum { +SVA_CODEC_IMAGE_MODE, +SVA_CODEC_SEGMENTED_MODE, +SVA_CODEC_STREAM_MODE +//SVA_CODEC_CIRCULAR_MODE +} t_sva_codec_mode; + +typedef enum { +SVA_VC1_IMAGE_BUFFER_AREA, +SVA_H264_INTERNAL_AREA, +SVA_H264_ENC_FW_PROG_ZONE1_AREA, +SVA_SW_PREPROC_BUFFER_AREA +}t_sva_dedicated_area_purpose; + +/* + * Define the type used to provide parameters related to a given algorithm + * when configuring a Codec (decoder or encoder) + * (static parameters (bitstream related vs frame related)). + * For each kind of codec supported (MPEG4, H263,..), we provide + * a specific t_sva__algo__configuration_params type. + */ +typedef void * tp_sva_codec_algo_configuration_params; + +typedef enum { +SVA_PREPROCESSING_RESIZE = MASK_BIT0, +SVA_PREPROCESSING_CROP = MASK_BIT1 +} t_sva_preprocessing_transform_type; + + +typedef enum { +SVA_ENCODING_CROP = MASK_BIT0 +} t_sva_encoding_transform_type; + +typedef enum { +SVA_POSTPROCESSING_RESIZE = MASK_BIT0, +SVA_POSTPROCESSING_CROP = MASK_BIT1, +SVA_POSTPROCESSING_CLIP = MASK_BIT2, +SVA_POSTPROCESSING_MIRROR_H = MASK_BIT3, +SVA_POSTPROCESSING_MIRROR_V = MASK_BIT4, +SVA_POSTPROCESSING_ROTATE_90 = MASK_BIT5, +SVA_POSTPROCESSING_ROTATE_180 = MASK_BIT6, +SVA_POSTPROCESSING_ROTATE_270 = MASK_BIT7, +SVA_POSTPROCESSING_DITHERING = MASK_BIT8, +SVA_POSTPROCESSING_DEBLOCKING_FILTER = MASK_BIT9, +SVA_POSTPROCESSING_DERINGING_FILTER = MASK_BIT10 +} t_sva_postprocessing_transform_type; + + +typedef enum { +SVA_SERVICE_RESET = 1, +SVA_SERVICE_ABORT, +SVA_SERVICE_STOP, +SVA_SERVICE_START, +SVA_SERVICE_FLUSH_IN, +SVA_SERVICE_FLUSH_OUT +} t_sva_service_cmd_id; + + +typedef enum { +SVA_UPDATE_MULTIPLE, +SVA_UPDATE_LAST, +SVA_UPDATE_REVERT +} t_sva_update_cmd_type; + + +typedef enum { +/* no dynamic param identified today */ +SVA_VIDEO_DECODER_PARAM_DUMMY +} t_sva_video_decoder_param_id; + + +typedef enum { +SVA_ENCODER_REQUEST_INTRA, //parameter: a pointer to a structure t_sva_intra_request +SVA_ENCODER_BITRATE, // parameter : new bitrate in bit/s +SVA_ENCODER_FRAME_RATE, // parameter : value of new source frame rate => use only as info whensource frame rate change +SVA_ENCODER_SPATIAL_QUALITY, // parameter : t_sva_spatial_quality value +SVA_ENCODER_MIN_FRAME_RATE, // parameter : new mininum output frame rate +SVA_ENCODER_PICTURE_INTRA_REFRESH, // parameter : new interval between two I pictures +SVA_ENCODER_HEADER_FREQUENCY, // parameter : new gobHeaderFrequency in short header / newhecFreq in simple profile +SVA_ENCODER_AIR_MB_NUM, // parameter : new air macroblock number +SVA_ENCODER_CIR_PERIOD, // parameter : new refresh period for cir mode +SVA_ENCODER_PACKET_SIZE, // parameter : new packet size in bit +SVA_ENCODER_PACKET_SIZE_INFO // added for cr 190 +} t_sva_video_encoder_param_id; + +typedef enum { +SVA_PREPROCESSOR_CROPPING, /* parameter: a pointer to a t_sva_window_desc structure */ +SVA_PREPROCESSOR_RESIZE, /* parameter: a pointer to a t_sva_image_desc structure */ +SVA_PREPROCESSOR_GRAB_LINE_NUMBER_SYNC, /* parameter: line number */ +SVA_PREPROCESSOR_ACE_ENABLE, /* parameter : a boolean : TRUE => enable ace / FALSE => disable ace */ +SVA_PREPROCESSOR_ACE_STRENGTH, /* parameter : a t_sva_ace_strength value */ +SVA_PREPROCESSOR_ACE_RANGE, /* parameter : a t_sva_color_range value */ +SVA_PREPROCESSOR_OUTPUT_RANGE, /* parameter : a t_sva_color_range value */ +SVA_PREPROCESSOR_ACE_OFFSET, /* parameter: a pointer to a t_sva_ace_offset structure */ +SVA_PREPROCESSOR_PACKET_WRITE, /* parameter: a pointer to a t_sva_packet structure */ +SVA_PREPROCESSOR_PACKET_READ, /* parameter: a pointer to a t_sva_packet structure */ +SVA_PREPROCESSOR_HQ_STATUS_READ, /* Gives the status of HQ Grab substask, parameter: a pointer to a t_sva_gb_hq_status structure */ +SVA_PREPROCESSOR_HQ_STATUS_TST, /* Used to test geabHQ, set this to one when you need to stop at each stage */ +SVA_PREPROCESSOR_HQ_PREPROC, /* Dynamic update of grabhq preproc params */ +SVA_PREPROCESSOR_HQ_READ_NB_FAILURE_BML_PROCESS /* Read status of BML retries made for a BML process, Parameter: A pointer to a t_uint32 value */ +} t_sva_preprocessor_param_id; + +typedef enum { +SVA_POSTPROCESSOR_PPP_TILE, +SVA_POSTPROCESSOR_PIP, // parameter: a pointer to a t_sva_window_desc structure +// (if pointer NULL, then PIP disabled) +SVA_POSTPROCESSOR_CONTRAST, // a pointer to t_uint32 value which points to contrast range [0, 100] +SVA_POSTPROCESSOR_BRIGHTNESS, // a pointer to t_uint32 value which points to brightness in range [0, 100] +SVA_POSTPROCESSOR_DITHERING, // a pointer to t_uint32 value which points to Dithering 0: off - 1: on +SVA_POSTPROCESSOR_MIRRORING, // a pointer to t_uint32 value 0:off-1(SVA_HORIZONTAL_MIRRORING)-2(SVA_VERTICAL_MIRRORING) +SVA_POSTPROCESSOR_ROTATION, //a pointer to t_uint32 value 0:off-90(SVA_ROTATE_90)-180(SVA_ROTATE_180)-270(SVA_ROTATE_270) +SVA_POSTPROCESSOR_FRAME_ALPHAKEY, //a pointer to t_uint32 value,new alpha key value +SVA_POSTPROCESSOR_CROPPING, // parameter: a pointer to a t_sva_window_desc structure (input) +SVA_POSTPROCESSOR_RESIZE, // parameter: a pointer to a t_sva_image_desc structure +SVA_POSTPROCESSOR_CLIPPING, // parameter: a pointer to a t_sva_window_desc structure (output) +SVA_POSTPROCESSOR_SOURCEFRAME_SIZE,//NOT IMPLEMENTED YET // parameter: a pointer to t_sva_image_desc (input) +SVA_POSTPROCESSOR_VIDEOFRAME_SIZE,//NOT IMPLEMENTED YET // parameter: a pointer to t_sva_image_desc (output) +SVA_POSTPROCESSOR_SCREEN_WINDOW_OFFSET,// parameter: pointer to t_sva_offset_desc structure +SVA_POSTPROCESSOR_SCREEN_BUFFER_ADDR, // parameter: a t_physical_address value +SVA_POSTPROCESSOR_ALT_SCREEN_BUFFER_ADDR, // parameter: a t_physical_address value +SVA_POSTPROCESSOR_MATRIX_COEFF, // parameter: a pointer to t_sva_postprocessor_color_matrix +SVA_POSTPROCESSOR_ANTI_TEARING_EFFECT, // parameter: 0: off - 1: on +SVA_POSTPROCESSOR_ACE_ENABLE, // not used anymore +SVA_POSTPROCESSOR_ACE_STRENGTH, // parameter : a t_sva_ace_strength value +SVA_POSTPROCESSOR_ACE_RANGE, // parameter : a t_sva_color_range value +SVA_POSTPROCESSOR_ACE_OFFSET, // parameter: a pointer to a t_sva_ace_offset structure (see §4.38) +SVA_POSTPROCESSOR_OUTPUT_RANGE, // parameter : a t_sva_color_range value +SVA_POSTPROCESSOR_REDBLUESWAP +} t_sva_postprocessor_param_id; + + +typedef enum { +/* no dynamic param identified today */ +SVA_SW_PROCESSING_PARAM_DUMMY +} t_sva_sw_processing_param_id; + + +typedef enum { +/* no dynamic param identified today */ +SVA_STILL_ENCODER_PARAM_DUMMY +} t_sva_still_encoder_param_id; + + +typedef enum { +/* no dynamic param identified today */ +SVA_STILL_DECODER_PARAM_DUMMY +} t_sva_still_decoder_param_id; + + +typedef enum { +SVA_TVO_CROPPING, // parameter: a pointer to a t_sva_window_desc structure +SVA_TVO_WINDOW_OFFSET, // parameter: pointer to t_sva_offset_desc structure +SVA_TVO_BACKGROUND_COLOR // parameter: pointer to t_sva_yuv_color structure +} t_sva_tvo_param_id; + + +typedef enum { +SVA_NO_TIMESTAMP, +SVA_PRESENTATION_TIMESTAMP, +SVA_DECODING_TIMESTAMP, +SVA_GRABBING_TIMESTAMP +} t_sva_timestamp_type; + + +typedef enum { +SVA_COLOR_12BITS, +SVA_COLOR_15BITS, +SVA_COLOR_16BITS, +SVA_COLOR_24BITS, +SVA_COLOR_32BITS +} t_sva_color_depth; + +typedef enum { +SVA_FULL_RANGE, +SVA_BT601_RANGE +} t_sva_color_range; + +typedef enum { +SVA_DEFAULT_SAMPLING_FORMAT = 0, +SVA_MPEG2_4_SAMPLING_FORMAT = 1, +SVA_MPEG1_SAMPLING_FORMAT = 2 +} t_sva_sampling_format; + + +typedef enum { +SVA_MONOCHROME = 1, +SVA_COLOR = 3 +} t_sva_still_image_color_mode; + + +typedef enum { +SVA_DOWNSAMPLING_FACTOR_1, +SVA_DOWNSAMPLING_FACTOR_2, +SVA_DOWNSAMPLING_FACTOR_4, +SVA_DOWNSAMPLING_FACTOR_8 +} t_sva_downsampling_factor; + + +typedef enum { +SVA_ACE_STRENGTH_1 = 1, +SVA_ACE_STRENGTH_2, +SVA_ACE_STRENGTH_3, +SVA_ACE_STRENGTH_4, +SVA_ACE_STRENGTH_5, +SVA_ACE_STRENGTH_6, +SVA_ACE_STRENGTH_7, +SVA_ACE_STRENGTH_8 +} t_sva_ace_strength; + + +typedef enum { +SVA_POSTPROCESSOR_ACE_DISABLE, +SVA_POSTPROCESSOR_ACE_INTERNAL, +SVA_POSTPROCESSOR_ACE_EXTERNAL // when using with Still Image Decoder +} t_sva_postprocessor_ace_mode; + +typedef enum { +SVA_POSPROCESSOR_NO_EXT_SYNC, +SVA_POSTPROCESSOR_EXT_DISPLAY_SYNC // The external DISPLAY_SYNC signal is used. That means the display is synchronized by + // external hardware signal mainly provided by display engine. + // WARNING : To be used ONLY with valid hardware synchro, otherwise, display will be + // stucked !!! +} t_sva_postprocessor_external_sync_mode; + + +typedef enum { +SVA_PREPROCESSOR_RAW_8BPP, +SVA_PREPROCESSOR_RAW_10BPP +} t_sva_preprocessor_ccir_raw_bpp; + + +typedef enum { +SVA_PREPROCESSOR_SYNC_EMBEDDED_CODES, /* 0x0 */ +SVA_PREPROCESSOR_SYNC_EXTERNAL_MODE1, /* 0x1 */ +SVA_PREPROCESSOR_SYNC_EXTERNAL_MODE2 /* 0x2 */ +} t_sva_preprocessor_ccir_input_sync_mode; + +typedef enum { +SVA_PREPROCESSOR_CCP0_INTERFACE_RISING_EDGE, /* 0x0 */ +SVA_PREPROCESSOR_CCIR656_INTERFACE_RISING_EDGE, /* 0x1 */ +SVA_PREPROCESSOR_CCP0_INTERFACE_FALLING_EDGE, /* 0x2 */ +SVA_PREPROCESSOR_CCIR656_INTERFACE_FALLING_EDGE, /* 0x3 */ +SVA_PREPROCESSOR_CCP0_INTERFACE_RISING_EDGE_STROBE_ENABLE, /* 0x4 */ +SVA_PREPROCESSOR_CCP0_INTERFACE_FALLING_EDGE_STROBE_ENABLE, /* 0x5 */ +SVA_PREPROCESSOR_CCP1_INTERFACE_RISING_EDGE, /* 0x6 */ +SVA_PREPROCESSOR_CCP1_INTERFACE_FALLING_EDGE, /* 0x7 */ +SVA_PREPROCESSOR_CCP1_INTERFACE_RISING_EDGE_STROBE_ENABLE, /* 0x8 */ +SVA_PREPROCESSOR_CCP1_INTERFACE_FALLING_EDGE_STROBE_ENABLE, /* 0x9 */ +SVA_PREPROCESSOR_CCP_INTERFACE_RISING_EDGE = SVA_PREPROCESSOR_CCP0_INTERFACE_RISING_EDGE, /* 0x0 */ +SVA_PREPROCESSOR_CCP_INTERFACE_FALLING_EDGE = SVA_PREPROCESSOR_CCP0_INTERFACE_FALLING_EDGE, /* 0x2 */ +SVA_PREPROCESSOR_CCP_INTERFACE_RISING_EDGE_STROBE_ENABLE = SVA_PREPROCESSOR_CCP0_INTERFACE_RISING_EDGE_STROBE_ENABLE, /* 0x4 */ +SVA_PREPROCESSOR_CCP_INTERFACE_FALLING_EDGE_STROBE_ENABLE = SVA_PREPROCESSOR_CCP0_INTERFACE_FALLING_EDGE_STROBE_ENABLE /* 0x5 */ +} t_sva_preprocessor_input_mode; + + +typedef enum { +SVA_TVO_EXTERNAL_CLOCK_FALLING_EDGE, +SVA_TVO_EXTERNAL_CLOCK_RISING_EDGE, +SVA_TVO_INTERNAL_CLOCK_FALLING_EDGE, +SVA_TVO_INTERNAL_CLOCK_RISING_EDGE +} t_sva_tvo_clock_mode; + + +typedef enum { +SVA_BASIC_ERC, /* for h264 : file does not contain any error */ +SVA_FULL_ERC /* for h264, file contain error */ +} t_sva_erc_mode; + + +typedef enum { +SVA_QP_CONSTANT=0, +SVA_FRAME_BASE, /* user provide frame size for each picture to encode */ +SVA_CBR, +SVA_VBR +} t_sva_brc_mode; + + +typedef enum { +SVA_SPATIAL_QUALITY_NONE, +SVA_SPATIAL_QUALITY_LOW, +SVA_SPATIAL_QUALITY_MEDIUM, +SVA_SPATIAL_QUALITY_HIGH +} t_sva_brc_spatial_quality; + +typedef enum { +SVA_BUFFERING_NONE, +SVA_BUFFERING_VBV, +SVA_BUFFERING_HRD, +SVA_BUFFERING_ANNEXG +} t_sva_brc_buffering_model; + +typedef enum { +SVA_AIR_DISABLED_CIR_DISABLED=0, +SVA_AIR_ENABLED_CIR_DISABLED, +SVA_AIR_DISABLED_CIR_ENABLED, +SVA_AIR_ENABLED_CIR_ENABLED +} t_sva_brc_intra_refresh_mode; + + +typedef enum { +SVA_RTYPE_MODE_CONSTANT_ZERO, +SVA_RTYPE_MODE_CONSTANT_ONE, +SVA_RTYPE_MODE_TOGGLING +} t_sva_rtype_mode; + + +#define NUMBER_OF_FILTER_MODE 5 +typedef enum { +SVA_NONE_FILTER, +SVA_DEBLOCKING_FILTER, +SVA_DERINGING_FILTER , +SVA_DEBLOCKING_DERINGING_FILTER, +SVA_H264_DEBLOCKING_OPTIMIZED_FILTER = SVA_DEBLOCKING_DERINGING_FILTER + +} t_sva_filter_mode; + +typedef enum { +SVA_H264_FULL_FRAME_DEBLOCKING_FILTER, +SVA_H264_NONE_FILTER, +SVA_H264_SLICE_BOUNDRIES_DEBLOCKING_FILTER, +} t_sva_h264_filter_mode; + +typedef enum { +// TO BE COMPLETED +SVA_DECODER_TASK_PARAMETER_ERROR = -1, +SVA_DECODER_NO_ERROR = 0 +} t_sva_video_decoder_error_id; + + +typedef enum { +// TO BE COMPLETED +SVA_VIDEO_ENCODER_ERROR_DUMMY +} t_sva_video_encoder_error_id; + + +typedef enum { +SVA_PREPROCESSOR_TASK_PARAMETER_ERROR = -1, +SVA_PREPROCESSOR_NO_ERROR = 0 +// TO BE COMPLETED +} t_sva_preprocessor_error_id; + + +typedef enum { +SVA_POSTPROCESSOR_TASK_PARAMETER_ERROR = -1, +SVA_POSTPROCESSOR_NO_ERROR = 0 +// TO BE COMPLETED +} t_sva_postprocessor_error_id; + +typedef enum { +// TO BE COMPLETED +SVA_SW_PROCESSING_ERROR_DUMMY +} t_sva_sw_processing_error_id; + +typedef enum { +SVA_JPEG_ENCODER_ERROR, +SVA_STILL_ENCODER_NO_ERROR = 0 +} t_sva_still_image_encoder_error_id; + +typedef enum { +SVA_STILL_DECODER_TASK_PARAMETER_ERROR = -1, +SVA_STILL_DECODER_NO_ERROR = 0 +} t_sva_still_image_decoder_error_id; + +typedef enum { +// TO BE COMPLETED +SVA_TVO_ERROR +} t_sva_tvo_error_id; + + +typedef enum { +SVA_EVENT_BUFFER_VOIDED = 1,// the buffer has been read and is under user control +SVA_EVENT_BUFFER_FILLED, // the buffer has been written and is under user control +SVA_EVENT_BUFFER_PARTLY_FILLED, // the buffer has been partly written +// but remains under HCL control in order to continue to fill it +SVA_EVENT_BUFFER_FILLED_READ_ONLY, // the buffer has been written but remains under HCL control +SVA_EVENT_SERVICE_STOPPED, // the given service is stopped +SVA_EVENT_SERVICE_ACTIVATED, // the given service has been activated +SVA_EVENT_SERVICE_INACTIVATED, // the given service has been inactivated +SVA_EVENT_SERVICE_FLUSHED_IN, // the given service has been flushed (input bufferization) +SVA_EVENT_SERVICE_FLUSHED_OUT, // the given service has been flushed (output bufferization) +SVA_EVENT_SERVICE_ERROR, // the given service is in error state +SVA_EVENT_UNDERFLOW, // lack of data in input +SVA_EVENT_OVERFLOW, // lack of buffer in output +SVA_EVENT_PREPROCESSOR_LINE_SYNCHRO, // see t_sva_preprocessor_configuration type description +SVA_EVENT_POSTPROCESSOR_LINE_SYNCHRO, // see t_sva_postprocessor_configuration type description +SVA_EVENT_POSTPROCESSOR_SYNCHRO, // see t_sva_postprocessor_configuration type description +SVA_EVENT_POSTPROCESSOR_ALT_SYNCHRO, // see t_sva_postprocessor_configuration type description +SVA_EVENT_FW_NO_MORE_NEEDED, // the given firmware can be removed from the shared memory +SVA_EVENT_PACKET_READ, // an irp packet read is finish +SVA_EVENT_PACKET_WRITE, // an irp packet write is finish +SVA_EVENT_PACKET_ERROR // an irp packet error occur +} t_sva_event_id; + + + + +typedef t_uint32 t_sva_service_id; +typedef t_uint32 t_sva_fw_id; +typedef t_uint32 t_sva_buffer_id; +typedef t_uint32 t_sva_timestamp_value; +typedef void * tp_sva_codec_algo_static_params; +typedef void * tp_sva_brc_configuration_params; +typedef void * tp_sva_still_algo_configuration_params; +typedef void * tp_sva_open_service_methods; + +/* + * Define the constant value used to flag an invalid buffer identifier + */ +#define INVALID_BUFFER_ID MASK_ALL32 + +typedef struct { +t_sva_timestamp_type type; +t_sva_timestamp_value value; +} t_sva_timestamp; + +/* ------------------------ */ +/* Structure */ +/* -------------------------*/ + +typedef struct { +t_uint16 vpBitSize; +t_uint16 vpMbSize; +t_uint16 vpSizeMax; +t_uint16 vpSizeType; +}t_sva_ec_mp4_packetsize_info; + + +typedef struct { +t_version hclVersion; +t_version fwVersion; +t_version hwVersion; +} t_sva_version; + +typedef struct { +t_uint16 height; +t_uint16 width; +} t_sva_image_desc; + + +typedef struct { +t_uint16 offsetX; +t_uint16 offsetY; +} t_sva_offset_desc; + +typedef struct{ +t_sva_image_desc image; +t_sva_offset_desc imageOffset; +void* next_tile; // it is treated as (t_sva_ppp_tile_info*) +}t_sva_ppp_tile_info; + +typedef struct { +t_sva_image_desc image; +t_sva_offset_desc imageOffset; +} t_sva_window_desc; + + +typedef struct { +t_sva_image_desc frame; +t_sva_window_desc window; +} t_sva_windowed_frame_desc; + +/* BML clock diviser for FW Version >= 3.14.1.1 */ +typedef enum { +SVA_GRAB_HQ_BML_FREQ_CLK72_DIV2 = 2, +SVA_GRAB_HQ_BML_FREQ_CLK72_DIV3 = 3, +SVA_GRAB_HQ_BML_FREQ_CLK72_DIV4 = 4 +} t_sva_grab_hq_bml_clock_divisor; + +/* Configuration parameters related to GrabHQ only, Added after CR133 implementation */ +typedef struct { +t_bool isChannelOffsetEnabled; /* Channel Offset On/Off switch */ +t_bool isGridironEnabled; /* Gridiron On/Off switch */ +t_bool isScorpioEnabled; /* Scorpio On/Off switch */ +t_uint16 scorpioStrength; /* Scorpio strength */ +t_uint32 castDay; +t_uint32 castCool; +t_uint32 castInc; +t_uint32 castHorizon; +t_sint32 gridHSize; +t_sva_grab_hq_bml_clock_divisor bmlClockDivisor; /* BML Clock diviser */ +/* nbMaxBmlRetiesOnFailure is only valid if FW>=3.14.1.2 */ +t_uint32 nbMaxBmlRetiesOnFailure; /* Number of maximum BML reties to be made, if all the these reties have failed then FW will through and error */ +} t_sva_preprocessor_grabhq_configuration; + +typedef struct { +t_uint16 errorType; +t_uint16 pictureLoss; +t_uint16 sliceLossFirstMb[8]; +t_uint16 sliceLossMbNum[8]; +t_uint16 concealedMbNum; +t_uint16 concealedVpSliceNum; +t_uint16 decodedVpSliceNum; +t_uint16 reserved_1; +t_uint32 reserved_2; +} t_sva_video_decoder_infos; + +typedef struct +{ + t_uint16 error_type; + t_uint16 picture_loss; + t_uint16 slice_loss_first_mb[8]; + t_uint16 slice_loss_mb_num[8]; + t_uint16 concealed_mb_num; + t_uint16 concealed_vp_num; + t_uint16 decoded_vp_num; + + t_uint16 reserved_1; + t_uint32 reserved_2; +} t_sva_video_decoder_mpeg4_infos; + +typedef struct +{ + t_uint16 error_type; + t_uint16 reserved_1; + t_uint32 reserved_2; + t_uint32 reserved_3; + t_uint32 reserved_4; +} t_sva_video_decoder_Mpeg2_infos; +typedef struct +{ + t_uint16 error_type; + t_uint16 picture_loss; + t_uint16 slice_loss_first_mb[8]; + t_uint16 slice_loss_mb_num[8]; + t_uint16 concealed_mb_num; + t_uint16 concealed_vp_num; + t_uint16 decoded_vp_num; + t_uint16 reserved_1; + t_uint32 reserved_2; +} t_sva_video_decoder_h263_infos; + +typedef struct +{ + t_uint16 picture_loss; + t_uint16 mb_count; + t_uint32 reserved_2; + t_uint32 reserved_3; + t_uint32 reserved_4; + t_uint16 slice_loss_first_mb[8]; + t_uint16 slice_loss_mb_num[8]; +} t_sva_video_decoder_h264_infos; + +typedef struct +{ + t_uint16 error_type; + t_uint16 frame_interpolation_hint_enabled; + t_uint16 range_reduction_frame_enabled; + t_uint16 b_fraction_numerator; + t_uint16 b_fraction_denominator; + t_uint16 buffer_fullness; + t_uint16 picture_res; + t_uint16 max_picture_width; + t_uint16 max_picture_height; + t_uint16 picture_width; + t_uint16 picture_height; + t_uint16 picture_type; + t_uint32 padding1; + t_uint32 padding2; +} t_sva_video_decoder_vc1_infos; + + +typedef struct +{ + t_uint16 error_type; + t_uint16 reserved_1; + t_uint16 ace_offset0; + t_uint16 ace_offset1; + t_uint16 ace_offset2; + t_uint16 ace_offset3; + t_uint32 reserved_2; +} t_sva_still_decoder_jpeg_infos; + +/* Status of the GrabHQ subtask for FW Version >= 3.13.0 */ +typedef enum { +SVA_GRAB_HQ_SUBTASK_NOT_STARTED = 0, +SVA_GRAB_HQ_FIRST_STRIPE_FISRT_BML_DONE = 1, +SVA_GRAB_HQ_BMS_ENDED = 2, +SVA_GRAB_HQ_PREPROCESSING_STARTED = 2, +SVA_GRAB_HQ_PREPROCESSING_ENDED = 3, +SVA_GRAB_HQ_FIRST_BML_STARTED = 4, +SVA_GRAB_HQ_SUBTASK_ENDED = 5, +SVA_GRAB_HQ_SECOND_BML_STARTED = 6, +SVA_GRAB_HQ_SECOND_STRIPE_FIRST_BML_DONE = 6, +SVA_GRAB_HQ_FIRST_STRIPE_SECOND_BML_DONE = 7, +} t_sva_grab_hq_subtask_status; + +typedef struct { + t_bool isGrabHqTestModeEnabled; + t_sva_grab_hq_subtask_status grabHqSubtaskStatus; + t_uint16 cfgIrpGrabhqGridcastL; + t_uint16 cfgIrpGrabhqGridcastH; + t_uint16 cfgIrpGrabhqGridG1; + t_uint16 cfgIrpGrabhqGridG2; + t_uint16 cfgIrpGrabhqGridR; + t_uint16 cfgIrpGrabhqGridB; +} t_sva_gb_hq_status; + +#ifdef SVA_USE_GENERIC_ENCODER_INFOS +/******************************************************************************** + * SARVESH: Beware of using t_sva_video_encoder_infos instead of using codec * + * specific infos structure e.g. t_sva_video_encoder_mpeg4_infos or * + * t_sva_video_encoder_h264_infos. May lead to code break if you don't take care* + * of enough memory allocation. It is recommended to use service specific infos * + ********************************************************************************/ +typedef struct { +t_uint32 encodedFrameSize; /* size (in byte) of the encoded frame */ +/*(including header and stuffing bits) */ +t_uint32 vpSliceNum; +t_uint32 vpSlicePos[1620]; //\/ This size has been increased from 32 to 1320 for H264 Encode and to 1620 with FW 3.6.0 +} t_sva_video_encoder_infos; +#else /* SVA_USE_GENERIC_ENCODER_INFOS */ +typedef struct { +t_uint32 encodedFrameSize; /* size (in byte) of the encoded frame */ +/*(including header and stuffing bits) */ +t_uint32 vpSliceNum; +t_uint32 vpSlicePos[SVA_EC_MPEG4_VP_POS_COUNT]; +} t_sva_video_encoder_mpeg4_infos; + +typedef struct { +t_uint32 encodedFrameSize; /* size (in byte) of the encoded frame */ +/*(including header and stuffing bits) */ +t_uint32 sliceNum; +t_uint32 slicePos[SVA_EC_H263_SLICE_POS_COUNT]; +} t_sva_video_encoder_h263_infos; + +typedef struct { +t_uint32 encodedFrameSize; /* size (in byte) of the encoded frame */ +/*(including header and stuffing bits) */ +t_uint32 sliceNum; +t_uint32 slicePos[SVA_EC_H264_SLICE_POS_COUNT]; //\/ This size has been increased from 32 to 1320 for H264 Encode and to 1620 with FW 3.6.0 +t_uint32 stuffingBits; /* Number of stuffing bits(INOUT_OUT param from FW side) added in the bitstream during the encode subtask. It is not used if brc_method=0/1/3. */ +} t_sva_video_encoder_h264_infos; +#endif /* SVA_USE_GENERIC_ENCODER_INFOS */ + +typedef struct { +t_sva_inout_type type; +t_sva_inout_format format; +t_sva_image_desc maxSize; +} t_sva_inout_desc; + +typedef struct { +t_uint16 pictureCodingType; /* 0: intra / 1: inter */ +t_uint16 frameTargetSize; /* frame base target size (in byte) */ +} t_sva_brc_user_request; + +typedef struct { +t_uint32 minScaleFactor; // scaleFactor = (1/minScaleFactor) +t_uint32 maxScaleFactor; // scaleFactor = (maxScaleFactor) +t_uint32 scaleStep; // if ZERO (0) then continous resizing +} t_sva_resize_desc; + +typedef struct { +t_uint32 voidedCounter; // Buffer Voided event counter +t_uint32 filledCounter; // Buffer Filled event counter +t_uint32 partlyCounter; // Buffer Partly Filled event counter +t_uint32 readOnlyCounter; // Buffer Filled Read Only event counter +t_uint32 underflowCounter; // Underflow event counter +t_uint32 overflowCounter; // Overflow event counter +t_uint32 errorCounter; // Service Error event counter +} t_sva_service_event_stats; + + +typedef struct { +t_uint32 inLevel; // level of bufferization at input of a given service +t_uint32 outLevel; // level of bufferization at output of a given service +} t_sva_service_bufferization_stats; + + +typedef struct { +t_sva_preprocessor_capability_id capabilityId; +t_sva_inout_desc input; // camera interface +t_sva_inout_desc output[2]; // grabbed image and infos +t_sva_preprocessing_transform_type supportedTransformation; +t_sva_resize_desc resizeEngineFactors; +} t_sva_preprocessor_capabilities; + + +typedef struct { +t_sva_video_decoder_capability_id capabilityId; +t_sva_inout_desc input; // bitstream +t_sva_inout_desc output[3]; // decoded image and infos +// [and optional deblocking filter parameters] +} t_sva_video_decoder_capabilities; + + +typedef struct { +t_sva_video_encoder_capability_id capabilityId; +t_sva_inout_desc input; // image to encode +t_sva_inout_desc output[3]; // bitstream and infos [and optional deblocking filter parameters] +t_sva_encoding_transform_type supportedTransformation; +} t_sva_video_encoder_capabilities; + + +typedef struct { +t_sva_postprocessor_capability_id capabilityId; +t_sva_inout_desc input[2]; // image to postprocess [and optional deblocking filter parameters] +t_sva_inout_desc output; // postprocessed image +t_sva_postprocessing_transform_type supportedTransformation; +t_sva_resize_desc resizeEngineFactors; +} t_sva_postprocessor_capabilities; + + +typedef struct { +t_sva_sw_processing_capability_id capabilityId; +t_sva_inout_desc input[2]; // two grabbed images +t_sva_inout_desc output; // stabilization vector (infos) +} t_sva_sw_processing_capabilities; + +typedef struct { +t_sva_still_image_decoder_capability_id capabilityId; +t_sva_inout_desc input[3]; // three separate component image +t_sva_inout_desc output; // encoded image +} t_sva_still_decoder_capabilities; + +typedef struct { +t_sva_still_image_encoder_capability_id capabilityId; +t_sva_inout_desc input[3]; // three separate component image +t_sva_inout_desc output; // encoded image +t_sva_encoding_transform_type supportedTransformation; +} t_sva_still_encoder_capabilities; + +typedef const struct ts_sva_capabilities{ +t_uint8 nbSupportedPreprocessorTransforms; +t_sva_preprocessor_capabilities *preprocessorCapabilitiesArray; +t_uint8 nbSupportedDecoderTransforms; +t_sva_video_decoder_capabilities *decoderCapabilitiesArray; +t_uint8 nbSupportedSwProcessingTransforms; +t_sva_sw_processing_capabilities *swProcessingCapabilitiesArray; +t_uint8 nbSupportedEncoderTransforms; +t_sva_video_encoder_capabilities *encoderCapabilitiesArray; +t_uint8 nbSupportedPostprocessorTransforms; +t_sva_postprocessor_capabilities *postprocessorCapabilitiesArray; +t_uint8 nbSupportedStillDecoderTransforms; +t_sva_still_decoder_capabilities *stillDecoderCapabilitiesArray; +t_uint8 nbSupportedStillEncoderTransforms; +t_sva_still_encoder_capabilities *stillEncoderCapabilitiesArray; +} t_sva_capabilities, *tp_sva_capabilities; + +/********************************************/ +/* Common decoder structures */ +/********************************************/ +typedef struct { +t_sva_video_decoder_capability_id transformId; +t_bool areInfosRequested; // TRUE => User wants for each decoded image the related infos buffer +// The user SHALL provide all Infos buffers through SVA_PushInfosBuffer() +// FALSE => Infos buffers are not exported +t_sva_erc_mode ercMode; // The user SHALL provide all Infos buffers through SVA_PushInfosBuffer() +t_sva_codec_mode mode; // see §2.9: decoder => bitstream buffer as input +/*choose filter to use. Not all combinaison are possible*/ +t_sva_filter_mode inTheLoopFilter; +t_sva_filter_mode outTheLoopFilter; +t_sva_image_desc imageDesc; +t_bool raster_out_format; +tp_sva_codec_algo_configuration_params pAlgoConfig; +} t_sva_video_decoder_configuration; + + +typedef struct { +t_sva_service_state state; +t_sva_video_decoder_error_id errorId; +t_uint32 nbBytesDecoded; +t_uint32 nbImagesDecoded; +t_uint32 nbCompressedDataBufferized; // number of bytes inside input bitstream fifo +t_sva_service_event_stats eventStats; +t_sva_service_bufferization_stats bufferizationStats; +} t_sva_video_decoder_status; + +/********************************************/ +/* Codecs-dependant decoder structures */ +/********************************************/ +///////////// MPEG4 /////////////////// +typedef struct { +t_bool flagShortHeader; +t_uint16 vopTimeIncrementResolution; // range value: 1 to 65535 +t_bool isResyncMarkerDisable; +t_bool isDataPartitioned; +t_bool isReversibleVlc; +t_bool isInterlaced; +t_uint16 low_delay; +t_uint16 quant_type; +t_uint16 intra_quant_mat[64] ; +t_uint16 nonintra_quant_mat[64]; +t_uint8 profile; +} t_sva_video_decoder_algo_mpeg4_configuration_params; + +/*t_sva_video_decoder_algo_mpeg4_header_infos*/ +typedef struct { +t_uint16 pictureCodingType; // 0: Intra-coded, 1: Predictive-coded +t_uint16 quant; // value range: 1 to 31 +t_uint16 roundingType; // if used, value range: 0 to 1 +t_uint16 intraDcVlcThr; // if used, value range: 0 to 7 +t_uint16 vopFcodeForward; // if used, value range: 1 to 7 +t_uint16 vopFcodeBackward; +t_uint16 vop_time_increment; +t_uint16 modulo_time_base; + +} t_sva_video_decoder_algo_mpeg4_header_infos; + + +/********************************************/ +/* Codecs-dependant decoder structures */ +/********************************************/ +///////////// Start MPEG2 /////////////////// + +//Added for mpeg2 field picture support +typedef enum { + PICTURE_STRUCTURE_FRAME = 3, /** Frame picture structure*/ + PICTURE_STRUCTURE_BOTTOMFIELD = 2, /** Bottom Field */ + PICTURE_STRUCTURE_TOPFIELD = 1, /** Top Field */ + PICTURE_STRUCTURE_NONE = 0, /** Not applicable */ + } t_sva_Mpeg2_picture_structure; + +typedef struct { +t_bool load_intra_quantiser_matrix; +t_bool load_nonintra_quantiser_matrix; +t_bool progressive_sequence; +t_uint8 profile_level_indication; +t_uint8 chroma_format; +t_uint32 bit_rate; +} t_sva_video_decoder_algo_Mpeg2_configuration_params; + +/*t_sva_video_decoder_algo_mpeg4_header_infos*/ +typedef struct { +// not used t_ushort_value horizontal_size; + t_uint16 vertical_size; + t_uint16 mb_width; + t_uint16 mb_height; + // not used t_ushort_value progressive_sequence; + // not used t_ushort_value low_delay; + + t_uint16 intra_quantizer_matrix[64]; + t_uint16 non_intra_quantizer_matrix[64]; + + // not used t_ulong_value frame_rate; + // not used t_ulong_value bit_rate_value; + + // not used t_ulong_value vbv_buffer_size; + // not used t_ushort_value gop_flag; + // not used t_ushort_value closed_gop; + + // not used t_ushort_value broken_link; + // not used t_ushort_value temporal_reference; + t_uint16 picture_coding_type; + // not used t_ushort_value vbv_delay; + + t_uint16 full_pel_forward_vector; + t_uint16 forward_f_code; + t_uint16 full_pel_backward_vector; + t_uint16 backward_f_code; + + t_uint16 f_code[2][2]; + + t_uint16 intra_dc_precision; + t_uint16 picture_structure; + t_uint16 top_field_first; + t_uint16 frame_pred_frame_dct; + t_uint16 concealment_motion_vectors; + t_uint16 q_scale_type; + t_uint16 intra_vlc_format; + t_uint16 alternate_scan; + + // not used t_ushort_value repeat_first_field; + // not used t_ushort_value chroma_420_type; + // not used t_ushort_value progressive_frame; + t_uint16 scalable_mode; + t_uint16 MPEG2_Flag; + +} t_sva_video_decoder_algo_Mpeg2_header_infos; + +typedef enum { + PICTURE_SLICE_I = 1, /** I Picture / Field - can be used as a reference */ + PICTURE_SLICE_P = 2, /** P Picture / Field - can be used as a reference */ + PICTURE_SLICE_B = 3, /** B Picture / Field */ + PICTURE_SLICE_D = 4, /** D Picture / Field */ + PICTURE_SLICE_SKIPPED = 5 /** Picture Skipped / Field */ +} t_sva_Mpeg2_picture_type; + + +////////////// VC1 ///////////////////// +typedef enum { + PICTURE_TYPE_I = 0, /** I Picture / Field - can be used as a reference */ + PICTURE_TYPE_P = 1, /** P Picture / Field - can be used as a reference */ + PICTURE_TYPE_B = 2, /** B Picture / Field */ + PICTURE_TYPE_BI = 3, /** BI Picture / Field */ + PICTURE_SKIPPED = 4 /** Picture Skipped / Field */ +} t_sva_vc1_picture_type; + +typedef enum +{ + PICTURE_CODE_I = 0, /** I-Intra Picture */ + PICTURE_CODE_P = 1, /** P- Predictive Picture can be used as a reference */ + PICTURE_CODE_B = 2, /** B-Bidirectional Picture / Field */ +} t_sva_mp4_picture_type; + +typedef struct { // Sequence Layer parameters + t_uint8 profile; /** See standard */ + t_uint8 level; /** See standard */ + + t_uint8 quantizer; /** See standard */ + t_uint8 dquant; /** See standard */ + t_uint8 max_b_frames; /** See standard */ + t_uint8 qFramerateForPostproc; /** See standard */ + t_uint8 qBitrateForPostproc; /** See standard */ + + t_bool loopFilterEnabled; /** See standard */ + t_bool multiresCodingEnabled; /** See standard */ + t_bool fastUvmcEnabled; /** See standard */ + t_bool extendedMVEnabled; /** See standard */ + t_bool variableSizeTransformEnabled; /** See standard */ + t_bool overlapTransformEnabled; /** See standard */ + t_bool syncmarkerEnabled; /** See standard */ + t_bool rangeredEnabled; /** See standard */ + t_bool frameInterpolationEnabled; /** See standard */ + t_bool is_smpte_conformant; /** See standard */ + t_bool overboost; /** flag activating maximum performance decoding. 0=normal decode, 1=deblocking+overlap disabled with MB output instead of raster */ + t_bool simplified_filter; /** enable this flag if you want to use Intra filter for inter pictures as well. This improves performance for low bitrates. Output is raster in this case */ +} t_sva_video_decoder_algo_vc1_configuration_params; + +typedef struct { + t_uint32 frameSize; + t_sva_vc1_picture_type pictureCodingType; +} t_sva_video_decoder_algo_vc1_header_infos; + +////////////// H.264 /////////////////////// +typedef struct +{ + // size we have it in imageDesc. + t_uint16 levelIdc; + t_uint16 numRefFrames; + t_uint16 gapsInFrameNumValueFlag; + t_uint16 picOrderCntType; + t_uint16 log2MaxFrameNumMinus4; + t_uint16 log2MaxPicOrderCntLsbMinus4; + t_sint32 offsetForNonRefPic; /*t_sint32 ok */ + t_uint16 numRefFramesInPicOrderCntCycle; + t_sint32 offsetForRefFrame[256]; /*t_sint32 ok */ + t_sint32 offsetForTopToBottomField; +}t_sva_video_decoder_algo_h264_configuration_params; + +/* MMCO type operations */ +typedef enum +{ + SVA_DC_H264_DPB_END_MMCO=0, + SVA_DC_H264_DPB_UNMARK_SHORT_REF =1, + SVA_DC_H264_DPB_UNMARK_LONG_REF, + SVA_DC_H264_DPB_ASSIGN_LONG_TO_SHORT, + SVA_DC_H264_DPB_UNMARK_LONG_REF_GREATER, + SVA_DC_H264_DPB_UNMARK_LONG, + SVA_DC_H264_DPB_ASSIGN_LONG_TO_CURRENT +}t_sva_video_decoder_algo_h264_mmco_type; + +/* params to be given for each slice and taken from active pps, sps, slice header */ +typedef struct st_sva_video_decoder_algo_h264_slice_header_infos { + /* these are obtained by parsing */ + t_uint16 nut; + t_uint16 nri; + t_system_address sliceStartAddress; + t_uint32 sliceOffset;//bit position at sliceStartAdress + t_size sliceSize; + /* then taken from active pps, sps, slice header */ + t_uint16 sliceBetaOffsetDiv2; /*t_sint16 but ushort ProgModel*/ + t_uint16 firstMbInSlice; + t_uint16 sliceType; + t_uint16 numRefIdx10ActiveMinus1; + t_sint16 sliceQpDelta; /* t_sint16 ok */ + t_uint16 disableDeblockingFilterIdc; + t_uint16 sliceAlphaC0OffsetDiv2; /*t_sint16 but ushort in Progmodel */ + t_uint16 sliceNum; + t_uint16 sliceQp ; /*t_sint16 but ushort in Progmodel */ + /* to generate list0*/ + t_uint16 numRefIdxActiveOverrideFlag; + t_uint16 refPicListReorderingFlagl0; + t_uint16 frameNum; + t_uint16 reorderingOfPicNumsIdc[16]; + t_uint16 absDiffPicNumMinus1[16]; + t_uint16 longTermPicNum[16]; + struct st_sva_video_decoder_algo_h264_slice_header_infos *pNextHeader; +}t_sva_video_decoder_algo_h264_slice_header_infos; + +/*t_sva_video_decoder_algo_h264_header_infos*/ +typedef struct +{ + /* from PPS for vdc_h264_slice */ + t_uint16 chromaQpIndex; /*t_sint16 but ushort in Progmodel */ + t_uint16 constrIntraPredFlag; + t_uint16 numRefIdxl0ActiveMinus1; + /* from PPS and slice0 to compute sliceMap */ + t_uint16 slice0SliceGroupChangeCycle; + t_uint16 numSliceGroupsMinus1; + t_uint16 sliceGroupMapType; + t_uint16 runLenghtMinus1[8]; + t_uint16 topLeft[8]; + t_uint16 bottomRight[8]; + t_uint16 sliceGroupChangeDirFlag; + t_uint16 sliceGroupChangeRateMinus1; + t_uint16 sliceGroupId[1620]; + /* from active SPS: to be given to DPB */ + /* + t_uint16 numRefFrames; + t_uint16 gapsInFrameNumValueFlag; + t_uint16 picOrderCntType; + t_uint16 log2MaxFrameNumMinus4; + t_uint16 log2MaxPicOrderCntLsbMinus4; + t_sint32 offsetForNonRefPic; //t_sint32 + t_uint16 numRefFramesInPicOrderCntCycle; + t_sint32 offsetForRefFrame[256]; //t_sint32 + t_sint32 offsetForTopToBottomField; + */ + + /*from slice0: to be given to DPB */ + t_uint16 slice0Nut; + t_uint16 slice0Nri; + t_uint16 slice0FrameNum; + t_uint16 slice0PicOrderCntLsb; + t_sint32 slice0DeltaPicOrderCnt[2]; + t_sint32 slice0DeltaPicOrderCntBottom; + t_uint16 slice0LongTermReferenceFlag; + t_uint16 slice0NoOutputOfPriorPicsFlag; + t_uint16 slice0AdaptiveRefPicMarkingModeFlag; + t_sva_video_decoder_algo_h264_mmco_type slice0MemoryManagementControlOperation[16]; + t_uint16 slice0DifferenceOfPicNumsMinus1[16]; + t_uint16 slice0MarkingLongTermPicNum[16]; + t_uint16 slice0LongTermFrameIdx[16]; + t_uint16 slice0MaxLongTermFrameIdxPlus1[16]; + t_uint16 nbSlicesInFrame; + t_sva_video_decoder_algo_h264_slice_header_infos *pHeader; /* from each slice headers */ +}t_sva_video_decoder_algo_h264_header_infos; + +///////////// H.263 /////////////////////// +typedef struct { +/* today none configuration parameter is identified */ + t_uint32 dummy; +} t_sva_video_decoder_algo_h263_configuration_params; + +/*t_sva_video_decoder_algo_h263_header_infos*/ +typedef struct { +t_uint16 pictureCodingType; +t_uint16 quant; +t_uint16 roundingType; +t_uint16 enableAnnexes; +} t_sva_video_decoder_algo_h263_header_infos; + +////////////// End of decoder structures /////////////////// + + +typedef struct { +t_sva_video_encoder_capability_id transformId; +t_bool areInfosRequested; // TRUE => User wants for each encoded image the related infos buffer +// The user SHALL provide all Infos buffers through SVA_PushInfosBuffer() +// FALSE => Infos buffers are not exported +t_bool isCroppingVectorEnabled; // TRUE => User must provide for each image a cropping vector +// FALSE => No buffer of this type should be provide +t_bool isDestinationBufferRequested; // TRUE => User has to provide destination buffers for each image +// FALSE => No buffer of this type should be provide +t_sva_codec_mode mode; // see §2.9: encoder => bitstream buffer as output +t_sva_windowed_frame_desc sourceFrameDesc; +/*choose filter to use. Not all combinaison are possible*/ +t_sva_filter_mode inTheLoopFilter; +t_sva_filter_mode outTheLoopFilter; +/*choose brc to use. Not all combinaison allowed between brcMode/bufferingModel/algo */ +t_sva_brc_mode brcMode; +t_sva_brc_buffering_model bufferingModel; +tp_sva_brc_configuration_params pBrcConfig; +t_bool raster_in_format; +t_bool no_search_window; +tp_sva_codec_algo_configuration_params pAlgoConfig; +} t_sva_video_encoder_configuration; + + +typedef struct { +t_sva_service_state state; +t_sva_video_encoder_error_id errorId; +t_uint32 nbBytesEncoded; +t_uint32 nbImagesEncoded; +t_uint32 nbImagesSkipped; +t_sva_service_event_stats eventStats; +t_sva_service_bufferization_stats bufferizationStats; +} t_sva_video_encoder_status; + + +typedef struct { +t_bool flagShortHeader; +t_uint16 gobHeaderFrequency;/*when 0 then gob header insertion is disable*/ +t_bool isDataPartitionedEnable; +t_bool isReversibleVlcEnable; +t_uint16 hecFreq; // if used, value range: 0(HEC information disabled) to SourceWindowWidth*SourceWindowHeight/256 +t_uint16 vpSizeType; // if used, value range: 0 to 3 +t_uint16 vpSizeMax; // if used, value range: 0 to 2048(for Simple Profile Level=0/1) or 4096 (for SPL=2) or 8192 (for SPL=3) +t_uint16 vpBitSize; // if used, value range: 0 to vpSizeMax +t_uint16 vpMbSize; // if used, value range: 0 to window_width*window_height/256 +t_sva_brc_intra_refresh_mode irMode; +t_uint16 airMbNum; +t_uint16 cirPeriodMax; +t_sva_rtype_mode rtypeMode; +t_bool isSystemHeaderAddBeforeIntra; +t_uint8 profileAndLevel;// profile_and_level_indication field of VOS. Only use in SP and when +// isSystemHeaderAddBeforeIntra is true. This value will be copy in VOS header. +t_uint16 vopTimeIncrement; +t_uint16 vopTimeIncrementResolution; +} t_sva_video_encoder_algo_mpeg4_configuration_params; + + +#define FILE_NAME_SIZE 200 + +typedef struct { + t_sint32 ProfileIDC; /* profile idc */ + t_sint32 level_idc; /* level idc */ + +//\/ t_sint32 no_frames; /* number of frames to be encoded */ + t_sint32 QPISlice; /* QP of I pictures in case of no BRC (fix Qp encoding) */ + t_sint32 QPPSlice; /* QP of P pictures in case of no BRC (fix Qp encoding) */ + /* t_sint32 hadamard; */ /*!< 0: 'normal' SAD in 1/3 pixel search. 1: use 4x4 Haphazard transform and ' + Sum of absolute transform difference' in 1/3 pixel search */ + /* t_sint32 search_range; */ /*!< search range - integer pel search and 16x16 blocks. The search window is + generally around the predicted vector. Max vector is 2xmcrange. For 8x8 + and 4x4 block sizes the search range is 1/2 of that for 16x16 blocks. */ +//\/ t_sint32 Log2MaxFrameNum; + t_sint32 Log2MaxFNumMinus4; + + t_uint16 algo_config; /**<\brief 0b11 for performances (> 15 fps) , + unsetting bit 0 for complex intra in P slices , + unsetting bit 1 for complex inter in P slices */ +//\/ t_uint16 frame_width; /* image width (must be a multiple of 16 pels) */ +//\/ t_uint16 frame_height; /* image height (must be a multiple of 16 pels) */ +//\/ t_sint32 width_cr; /* HCL: We can remove this parameter from input parametrs */ +//\/ t_sint32 height_cr; /* HCL: We can remove this parameter from input parametrs */ + + + t_sint16 slice_size_type; /* Indicate what algorithm to use for setting slices */ + t_sint16 slice_mb_size; /* Argument when fixed # of MB in slice selected */ + t_sint16 slice_bit_size; /* Argument when fixed # of bytes in slice selected */ + t_sint32 use_constrained_intra_flag; /* 0: Inter MB pixels are allowed for intra prediction 1: Not allowed */ +//\/ t_sint32 infile_header; /* If input file has a header set this to the length of the header */ +//\/ char infile[FILE_NAME_SIZE]; /* YUV 4:2:0 input format */ +//\/ char outfile[FILE_NAME_SIZE]; /* H.264 compressed output bitstream */ +//\/ char ReconFile[FILE_NAME_SIZE]; /* Reconstructed Pictures */ +//\/ char TraceFile[FILE_NAME_SIZE]; /* Trace Outputs */ + t_sint32 intra_period; /* Random Access period though intra */ + + t_sint32 idr_enable; /* Encode intra slices as IDR */ +//\/ t_sint32 start_frame; /* Encode sequence starting from Frame start_frame */ + + t_sint32 annexb; /* Specifies the mode of the output file */ + +//\/ t_sint32 InterSearch16x16; +//\/ t_sint32 InterSearch16x8; +//\/ t_sint32 InterSearch8x16; +//\/ t_sint32 InterSearch8x8; +//\/ t_sint32 InterSearch8x4; +//\/ t_sint32 InterSearch4x8; +//\/ t_sint32 InterSearch4x4; + + t_sint32 IntraDisableInterOnly; + t_sint32 Intra4x4ParDisable; + t_sint32 Intra4x4DiagDisable; + t_sint32 Intra4x4DirDisable; + t_sint32 Intra16x16ParDisable; + t_sint32 Intra16x16PlaneDisable; + t_sint32 ChromaIntraDisable; + t_uint16 intra_disable; + + t_uint16 FrameRate; +//\/ double FrameRate_parser; + + t_sint32 chroma_qp_index_offset; +//\/#ifdef _FULL_SEARCH_RANGE_ +//\/ t_sint32 full_search; +//\/#endif + + t_sint32 pic_order_cnt_type; /* POC200301 */ + + /* Rate Control on JVT standard */ +//\/ t_sint16 brc_type; + t_sint32 bit_rate; + t_sint32 SeinitialQP; + t_uint16 me_type; /* M.E. Algorithm selection */ + + t_sint32 HrdSendMessages; + t_uint32 CpbBufferSize; + +//\/ char DynoptFileName[FILE_NAME_SIZE]; +//\/ char TimeStampsFileName[FILE_NAME_SIZE]; + + t_uint16 intra_refresh_type; /* 0=disabled 1=AIR */ + t_uint16 air_mb_num; +//\/ t_sint16 slice_loss_first_mb_parser; /* first MB lost (to be forced INTRA) JUST for parser use */ +//\/ t_sint16 slice_loss_mb_num_parser; /* number MBs lost (to be forced INTRA) JUST for parser use */ +//\/ t_sint16 slice_loss_first_mb[8]; /* first MB lost (to be forced INTRA) */ +//\/ t_sint16 slice_loss_mb_num[8]; /* number MBs lost (to be forced INTRA) */ + + /* pixel aspect ratio input parameters */ + t_sint32 aspect_ratio_info_present_flag;/* enable aspect ratio stuff in VUI */ + t_sint32 aspect_ratio_idc; /* aspect ratio idc */ + t_sint32 sar_width; /* used defined pixel width for aspect ratio */ + t_sint32 sar_height; /* used defined pixel height for aspect ratio */ + + /* deblocking filter stuff */ + t_sint32 disable_deblocking_filter_idc; + t_sint32 slice_alpha_c0_offset_div2; + t_sint32 slice_beta_offset_div2; + + t_sint32 video_signal_type_present_flag; + t_sint32 video_format; + t_sint32 video_full_range_flag; + t_sint32 colour_description_present_flag; + t_sint32 colour_primaries; + t_sint32 transfer_characteristics; + t_sint32 matrix_coefficients; + + t_sint32 IntraForced; /* force an Intra at this frame */ +} t_sva_video_encoder_algo_h264_configuration_params; + +typedef struct { +t_uint16 enableAnnexes; +t_uint16 gobHeaderFrequency;/*when 0 then gob header insertion is disable*/ +t_uint16 sliceSizeType; +t_uint16 sliceSizeMax; +t_uint16 sliceBitSize; +t_uint16 sliceMbSize; +t_sva_brc_intra_refresh_mode irMode; +t_uint16 airMbNum; +t_uint16 cirPeriodMax; +t_sva_rtype_mode rtypeMode; +} t_sva_video_encoder_algo_h263_configuration_params; + + +typedef struct { +t_uint32 pictureIntraRefresh;/*Give number of P picture between 2 I.*/ +t_uint8 IPictureQp;/*give the quantification value to use for I picture (2<=IPictureQp<=31)*/ +t_uint8 PPictureQp;/*give the quantification value to use for P picture (2<=PPictureQp<=31)*/ +/* Following field are only need when buffering model is different of SVA_BUFFERING_NONE*/ +t_uint32 bitRate;/*target bit rate in bits/s*/ +t_uint32 vbvBufferSize;/*vbv buffer size in bits*/ +t_uint32 vbvOccupancy;/*initial vbv occupancy in bits*/ +t_uint32 swissBuffer;/*swiss buffer in bits*/ +} t_sva_brc_qpConstant_configuration_params; + + +typedef struct { + t_uint32 dummy; +} t_sva_brc_frameBase_configuration_params; + + +typedef struct { +t_uint32 pictureIntraRefresh;/*Give number of P picture between 2 I.*/ +t_uint32 bitRate;/*target bit rate in bits/s*/ +t_uint32 vbvBufferSize;/*vbv buffer size in bits*/ +t_uint32 vbvOccupancy;/*initial vbv occupancy in bits*/ +t_uint32 swissBuffer;/*swiss buffer in bits*/ +} t_sva_brc_cbr_configuration_params; + + +typedef struct { +t_uint32 pictureIntraRefresh;/*Give number of P picture between 2 I.*/ +t_uint32 bitRate;/*target bit rate in bits/s*/ +t_sva_brc_spatial_quality spatialQuality; +t_uint32 minFrameRate;/*minimum output frame rate*/ +t_uint32 vbvBufferSize;/*vbv buffer size in bits*/ +t_uint32 vbvOccupancy;/*initial vbv occupancy in bits*/ +t_uint32 swissBuffer;/*swiss buffer in bits*/ +} t_sva_brc_vbr_configuration_params; + + +typedef struct { +t_bool isIntraFullPicture; // if true then request for an I picture, +// else only some Mb are request to be intra coded +t_uint16 sliceIntraFirstMb[8]; +t_uint16 sliceIntraMbNumber[8]; +} t_sva_intra_request; + + +typedef struct { +t_uint16 ace_offset_0; +t_uint16 ace_offset_1; +t_uint16 ace_offset_2; +t_uint16 ace_offset_3; +} t_sva_ace_offset; + +typedef struct { + t_uint16 address; + t_uint16 value; /* Not use for a read access */ +} t_sva_packet; + +typedef struct { +t_sva_preprocessor_capability_id transformId; +t_sva_windowed_frame_desc sourceFrameDesc; +t_sva_image_desc resizedWindowDesc; +t_sva_image_desc snapshotImageDesc; +t_sva_preprocessor_input_mode interfaceCConfiguration; /* CCP or CCIR656 */ +t_sva_preprocessor_ccir_input_sync_mode interfaceSyncMode; /* External or embedded synchronisation */ +t_bool isInputInterlaced; +t_bool isOutputFrame; +t_sva_preprocessor_ccir_raw_bpp rawBpp; /* If CCIR data bus is in 10 bits */ +/* This allow to grab raw data using full bus width */ +/* Only valid with transformId == SVA_PREPROCESSOR_RAW */ +/* and interfaceSyncMode != SVA_PREPROCESSOR_SYNC_EMBEDDED_CODES */ +t_uint32 grabSyncLine; /* define the grabbed line when raising the SVA_EVENT_PREPROCESSOR_SYNCHRO */ +/* to disable event generation please use SVA_NO_GRABSYNC_LINE (1023=0x3FF) value; value range: 0 to 1023 */ +t_sva_color_range outputRange; +t_bool isAceEnable; /* Enable or disable automatic contrast enhancement */ +t_sva_ace_strength aceStrength; +t_sva_color_range aceRange; +t_sva_preprocessor_grabhq_configuration grabhqConfig; +} t_sva_preprocessor_configuration; + +typedef struct { +t_sva_service_state state; +t_sva_preprocessor_error_id errorId; +t_uint32 nbGrabbedImage; +t_bool isAceEnable; +t_sva_ace_offset aceOffset; +t_sva_service_event_stats eventStats; +t_sva_service_bufferization_stats bufferizationStats; +} t_sva_preprocessor_status; + + +typedef struct { +t_sint16 matrix_coef1; +t_sint16 matrix_coef2; +t_sint16 matrix_coef3; +t_sint16 matrix_coef4; +} t_sva_postprocessor_color_matrix; + +typedef struct { +t_uint16 quant_y[64]; // value range for quant_y/cb/cr params: 1 to 255 +t_uint16 quant_cb[64]; +t_uint16 quant_cr[64]; +} t_sva_quantization_table; + + +typedef struct { +t_uint16 huffmanYCodeDc[12]; +t_uint16 huffmanYSizeDc[12]; // value range for huffman-Y/Cb/Cr-Size-Dc/Ac params: 1 to 16 (if 0 it will not be used) +t_uint16 huffmanYCodeAc[256]; +t_uint16 huffmanYSizeAc[256]; +t_uint16 huffmanCbCodeDc[12]; +t_uint16 huffmanCbSizeDc[12]; +t_uint16 huffmanCbCodeAc[256]; +t_uint16 huffmanCbSizeAc[256]; +t_uint16 huffmanCrCodeDc[12]; +t_uint16 huffmanCrSizeDc[12]; +t_uint16 huffmanCrCodeAc[256]; +t_uint16 huffmanCrSizeAc[256]; +} t_sva_huffman_table; + +typedef struct { +t_sva_postprocessor_capability_id transformId; +t_sva_postprocessor_external_sync_mode syncMode; +t_bool isDirectScreenAccess; // TRUE => screenFrameBufferBaseAddr SHALL be provided +// FALSE => the output buffer(s) will be provided one by one +// through SVA_PushImageBuffer() call +t_bool isDoubleBufferMode; // Only meaning if isDirectScreenAccess == TRUE +// TRUE => toggle between the 2 next frame buffers +// FALSE => use only the first one +// N.B: if isDirectScreenAccess == TRUE and isDoubleBufferMode == TRUE +// then the HCL will raised alternatively SVA_EVENT_POSTPROCESSOR_SYNCHRO and SVA_EVENT_POSTPROCESSOR_ALT_SYNCHRO events +// else (isDoubleBufferMode == FALSE) only SVA_EVENT_POSTPROCESSOR_SYNCHRO will be raised +t_physical_address screenFrameBufferBaseAddr; +t_physical_address screenAlternateFrameBufferBaseAddr; +t_sva_windowed_frame_desc sourceFrameDesc; +t_sva_image_desc resizedImageDesc; +t_sva_window_desc clippedWindowDesc; +t_sva_windowed_frame_desc videoFrameBufferDesc; +t_uint32 displaySyncLine; // SVA_EVENT_POSTPROCESSOR_LINE_SYNCHRO event will be raised +// when displaying the displaySyncLine line +// to disable event generation please use SVA_NO_GRABSYNC_LINE (1023=0x3FF) value +// if enable (!=1023) must be multiple of 16 and value range: 16 to source_window_height +t_sva_postprocessor_color_matrix colorMatrix; // matrix coef range: -1024 to 1023 +t_sva_color_range outputRange; +t_sva_postprocessor_ace_mode aceMode; +t_sva_ace_strength aceStrength; +t_sva_color_range aceRange; +t_sva_color_depth bitsPerPixel; +t_sva_mirroring_mode mirrorMode; +t_sva_rotation_mode rotationMode; +t_uint8 contrast; // values in [0..100] range. 50 is the standard value +t_uint8 brightness; // values in [0..100] range. 50 is the standard value +t_bool isDithering; +t_sva_deblocking_filter_mode deblockingFilterMode; +t_sva_deringing_filter_mode deringingFilterMode; +t_sva_sampling_format chromaSamplingFormat; +t_uint8 alphaKey; +t_bool redBlueSwap; +t_bool raster_in_format; +} t_sva_postprocessor_configuration; + + +typedef struct { +t_sva_service_state state; +t_sva_postprocessor_error_id errorId; +t_uint32 nbInputImagesPostProcessed; +t_uint32 nbOutputImagesDisplayed; +t_bool isAceEnable; +t_sva_ace_offset aceOffset; +t_sva_service_event_stats eventStats; +t_sva_service_bufferization_stats bufferizationStats; +} t_sva_postprocessor_status; + +typedef struct { +t_sva_sw_processing_capability_id transformId; +t_sva_image_desc originalPicture; +t_bool isUsingCustomZoneOfInterestBitmap; +t_sva_offset_desc startCroppingOffset; +t_uint32 horizontalThreshold; +t_uint32 verticalThreshold; +t_uint16 customZoneOfInterestBitmap[84]; +t_bool raster_in_format; +t_bool no_search_window; +} t_sva_sw_processing_configuration; + + +typedef struct { +t_sva_service_state state; +t_sva_sw_processing_error_id errorId; +t_uint32 nbImagesStabilized; +t_sva_service_event_stats eventStats; +t_sva_service_bufferization_stats bufferizationStats; +} t_sva_sw_processing_status; + + + +typedef enum { +SVA_NON_THUMBNAIL, +SVA_THUMBNAIL_DC_420MB /* Specific image buffer will have to be pushed out */ +} t_sva_thumbnail_mode; + + +typedef struct { +t_sva_still_image_encoder_capability_id transformId; +t_sva_codec_mode mode; // see §2.9: encoder => bitstream buffer as output +t_bool isSliceMode; +t_sva_thumbnail_mode thumbnailMode; +t_sva_windowed_frame_desc sourceFrameDesc; // if isSliceMode === TRUE, then no cropping possible +// sourceFrameDesc.window "==" sourceFrameDesc.frame +t_bool raster_in_format; +tp_sva_still_algo_configuration_params pAlgoConfig; +} t_sva_still_encoder_configuration; + +typedef enum +{ + SVA_JPEG_ENCODE_ROTATION_NONE, + SVA_JPEG_ENCODE_ROTATION_ANTICLOCKWISE, + SVA_JPEG_ENCODE_ROTATION_CLOCKWISE + }t_sva_jpeg_encode_on_fly_rotation; + +typedef struct { +t_uint16 restartInterval; +t_bool isOptimizeQuantTableEnable; +t_sva_jpeg_encode_on_fly_rotation rotation; +t_bool isOptimizeHuffmanTableEnable; +t_uint16 targetBpp; /* unit is 1/256 bpp */ +t_sva_quantization_table quantizationTable; /* WARNING: encoder use only one chroma table */ +/* (here quant_cb) */ +/* could be undefined if isOptimizeQuantTableEnable==TRUE */ +// value range for quant_y/cb/cr params: 1 to 255 +t_sva_huffman_table huffmanTable; /* could be undefined if isOptimizeHuffmanTableEnable==TRUE */ +// value range for huffman-Y/Cb/Cr-Size-Dc/Ac params: 1 to 16 (if 0 it will not be used) +} t_sva_still_algo_jpeg_configuration_params; + + +typedef struct { +t_sva_service_state state; +t_sva_still_image_encoder_error_id errorId; +t_uint32 nbBytesEncoded; +t_uint32 nbImagesEncoded; +t_sva_service_event_stats eventStats; +t_sva_service_bufferization_stats bufferizationStats; +} t_sva_still_encoder_status; + + +typedef struct { +t_uint16 hSamplingFactorY; +t_uint16 vSamplingFactorY; +t_uint16 hSamplingFactorCb; +t_uint16 vSamplingFactorCb; +t_uint16 hSamplingFactorCr; +t_uint16 vSamplingFactorCr;// param SamplingFactor-xx value: 1, 2 or 4 if used +//(used if componentSelector-xx = 1: if color_mode = monochrome only xSamplingFactorY used) +} t_sva_sampling_factor; + + +typedef struct { +t_uint16 restartInterval; +t_sva_huffman_table huffmanTable; +t_sva_quantization_table quantizationTable; +} t_sva_still_decoder_algo_sequential_jpeg_header_infos; + + +typedef struct { +t_uint16 nbScanComponents; +t_uint16 componentSelectorY; //value: 0 = the Y component is not present in the current scan; 1 = present +t_uint16 componentSelectorCb; //value: 0 = the Cb component is not present in the current scan; 1 = present +t_uint16 componentSelectorCr; //value: 0 = the Cr component is not present in the current scan; 1 = present +t_uint16 startSpectralSelection; // value range: 0 to 63 +t_uint16 endSpectralSelection; // value range: startSpectralSelection to 63 +t_uint16 successiveApproxPosition; +t_uint16 restartInterval; +t_sva_huffman_table huffmanTable; +t_sva_quantization_table quantizationTable; +} t_sva_still_decoder_algo_progressive_jpeg_header_infos; + + +typedef struct { +t_sva_still_image_decoder_capability_id transformId; +t_sva_codec_mode mode; // see §2.9: decoder => bitstream buffer as input +t_sva_image_desc decodedFrameDesc; +t_sva_window_desc crop_window; /*cropping is only supported from FW 3.6.0 onwards and HCL 3.4.0 onwards */ +t_sva_ace_strength aceStrength; +t_bool is_cropping_enabled; +t_bool no_slice_mode; +tp_sva_still_algo_configuration_params pAlgoConfig; +} t_sva_still_decoder_configuration; + + +typedef struct { +t_sva_still_image_color_mode colorMode; +t_sva_sampling_factor samplingFactor; // param SamplingFactor-xx value: 1, 2 or 4 if used +//(used if componentSelector-xx = 1: if colormode = monochrome only SamplingFactorY used) +t_sva_downsampling_factor downsamplingFactor; +} t_sva_still_algo_jpeg_decoder_configuration_params; + + +typedef struct { +t_sva_service_state state; +t_sva_still_image_decoder_error_id errorId; +t_uint32 nbBytesDecoded; +t_uint32 nbImagesDecoded; +t_sva_service_event_stats eventStats; +t_sva_service_bufferization_stats bufferizationStats; +} t_sva_still_decoder_status; + + +typedef struct { +t_bool isInterlacedEnabled; +t_uint16 numberOfLines ;// 6<=numberOfLines<=2047 +t_uint16 field1BlankingStartLine ; //FSB1: 1<=FBS1<=numberOfLines +//if isInterlacedEnabled=FALSE: FBS1!=FBE1 +//if isInterlacedEnabled=TRUE: (FBS1. */ +/*---------------------------------------------------------------------------*/ + +#include "v4l2-nomadik.h" + + +#define V4L2_SVA_DEFAULT_LOG_LEVEL 3 +#define V4L2_PRIV_ZOOM (V4L2_CID_BASE+25) + +#define NOMADIK_DEFAULT_FRAMERATE_NUMERATOR 25 +#define NOMADIK_DEFAULT_FRAMERATE_DENOMINATOR 1 + +static int v4l2_nomadik_debug = V4L2_SVA_DEFAULT_LOG_LEVEL; +module_param(v4l2_nomadik_debug, int, 0640); +MODULE_PARM_DESC(v4l2_nomadik_debug,"Debug level for messages"); +#define dbgprintk(num, format, args...) \ + do { \ + if(num >= v4l2_nomadik_debug ) \ + printk("V4L2-NOMADIK:"format, ##args); \ + } while(0) + +struct v4l2_sva_dev *dev; +extern struct sva_device sva; +static struct semaphore driver_mutex; +int g_prescale=0; + +extern struct nomadik_vpip_param vpip_default_params[];//defined in nomadik_sva_vpip.c +extern int VPIP_VERSION; + +int sva_vpip_auto_focus(struct sva_device_open *open, struct vpip_autofocus_id *mode); +int write_pages_wb(struct sva_device_open *open,struct vpip_usermode_update *mode); +int write_pages_ec(struct sva_device_open *open,struct vpip_usermode_update *mode); +int write_pages_iso(struct sva_device_open *open,struct vpip_usermode_update *mode); +int write_pages_colortone(struct sva_device_open *open,struct vpip_usermode_update *mode); +int write_pages_contrast(struct sva_device_open *open,struct vpip_usermode_update *mode); +int write_pages_sharpness(struct sva_device_open *open,struct vpip_usermode_update *mode); + +void configure_preprocessor(struct video_open *id) +{ + struct sva_preprocessor_configuration *preprocessor_config = + &id->config.preprocessor_config; +#ifdef CONFIG_NOMADIK_SVA_VPIP + preprocessor_config->capability = SENSOR_YUV420_MB; +#else + preprocessor_config->capability = YUV420_MB; +#endif + if(id->cropcap.bounds.width == 0) { + preprocessor_config->source_frame.height = id->pix.height; + preprocessor_config->source_frame.width = id->pix.width; + preprocessor_config->cropped_window.frame.height = id->pix.height; + preprocessor_config->cropped_window.frame.width = id->pix.width; + preprocessor_config->cropped_window.offset.x_offset = 0; + preprocessor_config->cropped_window.offset.y_offset = 0; + } else { + struct v4l2_cropcap *cropcap = &id->cropcap; + preprocessor_config->source_frame.height = cropcap->bounds.height; + preprocessor_config->source_frame.width = cropcap->bounds.width; + preprocessor_config->cropped_window.frame.height = cropcap->defrect.height; + preprocessor_config->cropped_window.frame.width = cropcap->defrect.width; + preprocessor_config->cropped_window.offset.x_offset = cropcap->defrect.left; + preprocessor_config->cropped_window.offset.y_offset = cropcap->defrect.top; + } + preprocessor_config->resized_frame.height = id->pix.height; + preprocessor_config->resized_frame.width = id->pix.width; + preprocessor_config->output_range = FULL_RANGE; + preprocessor_config->ace_enable = ACE_DISABLE; + preprocessor_config->ace_strength = ACE_STRENGTH_1; + preprocessor_config->ace_range = FULL_RANGE; + + preprocessor_config->frame_rate = 30; + preprocessor_config->prescale_factor= g_prescale; + preprocessor_config->sensor_aoi_x= 2048;//1280;//2048; + preprocessor_config->sensor_aoi_y= 1536;//960; +} + +void configure_postprocessor(struct video_open *id) +{ + struct v4l2_window *win = &id->win; + struct sva_postprocessor_configuration *postprocessor_config = + postprocessor_config = &id->config.postprocessor_config; + + postprocessor_config->direct_display = 1; + postprocessor_config->capability = 0; + if(id->cropcap.bounds.width == 0) { + postprocessor_config->source_frame.height = win->w.height; + postprocessor_config->source_frame.width = win->w.width; + postprocessor_config->cropped_window.frame.height = win->w.height; + postprocessor_config->cropped_window.frame.width = win->w.width; + postprocessor_config->cropped_window.offset.x_offset = 0; + postprocessor_config->cropped_window.offset.y_offset = 0; + } else { + struct v4l2_cropcap *cropcap = &id->cropcap; + postprocessor_config->source_frame.height = cropcap->bounds.height; + postprocessor_config->source_frame.width = cropcap->bounds.width; + postprocessor_config->cropped_window.frame.height = cropcap->defrect.height; + postprocessor_config->cropped_window.frame.width = cropcap->defrect.width; + postprocessor_config->cropped_window.offset.x_offset = cropcap->defrect.left; + postprocessor_config->cropped_window.offset.y_offset = cropcap->defrect.top; + } + + postprocessor_config->resized_frame.height = win->w.height; + postprocessor_config->resized_frame.width = win->w.width; + + if(win->clips) { + postprocessor_config->clipped_window.frame.height = win->clips->c.height; + postprocessor_config->clipped_window.frame.width = win->clips->c.width; + postprocessor_config->clipped_window.offset.x_offset = win->clips->c.left; + postprocessor_config->clipped_window.offset.y_offset = win->clips->c.top; + postprocessor_config->display_window.frame.height = win->clips->c.height; + postprocessor_config->display_window.frame.width = win->clips->c.width; + } else { + postprocessor_config->clipped_window.frame.height = win->w.height; + postprocessor_config->clipped_window.frame.width = win->w.width; + postprocessor_config->clipped_window.offset.x_offset = 0; + postprocessor_config->clipped_window.offset.y_offset = 0; + postprocessor_config->display_window.frame.height = win->w.height; + postprocessor_config->display_window.frame.width = win->w.width; + } + postprocessor_config->display_window.offset.x_offset = win->w.left; + postprocessor_config->display_window.offset.y_offset = win->w.top; + + postprocessor_config->matrix.matrix_coef1 = 204; + postprocessor_config->matrix.matrix_coef2 = -50; + postprocessor_config->matrix.matrix_coef3 = -104; + postprocessor_config->matrix.matrix_coef4 = 258; + + postprocessor_config->output_range = 1; + postprocessor_config->ace_mode = 0; + postprocessor_config->ace_strength = 4; + postprocessor_config->ace_range = 1; + +#ifdef CONFIG_NOMADIK_NHK15 + postprocessor_config->depth = BITS_24; +#else + postprocessor_config->depth = 1; +#endif + postprocessor_config->mirroring = 0; + postprocessor_config->rotation = 0; + postprocessor_config->dithering = 1; + postprocessor_config->deblocking_filter = 0; + postprocessor_config->deringing_filter = 0; + postprocessor_config->chroma_sampling = MPEG2_4_SAMPLING_FORMAT; + postprocessor_config->brightness = 50; + postprocessor_config->contrast = 50; + postprocessor_config->alpha_key = 0; + postprocessor_config->red_blue_swap = 0; +} + + +static int +sva_g_fmt( struct video_open * id, struct v4l2_format * arg) +{ + /* can't set the format if buffer are already requested or device + * is streaming */ + + if(unlikely(id->streaming)) + return -EINVAL; + + if(id->type == VID_TYPE_CAPTURE) { + + down(&id->open_lock); + switch(arg->type) { + case V4L2_BUF_TYPE_VIDEO_CAPTURE: + { + //if (unlikely(!arg->fmt.pix.pixelformat == V4L2_PIX_FMT_YUV420_MB)) + //return -EINVAL; + arg->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + //arg->fmt.pix.width = width; + //arg->fmt.pix.height = height; + arg->fmt.pix.pixelformat = V4L2_PIX_FMT_YUV420_YUMB; + break; + } + + default: + return -EINVAL; + } + + //configure_preprocessor(id); + up(&id->open_lock); + + return 0 ; + + } + +} + + +static int +sva_s_fmt( struct video_open * id, struct v4l2_format * arg) +{ + /* can't set the format if buffer are already requested or device + * is streaming */ + + if(unlikely(id->streaming)) + return -EINVAL; + + if(id->type == VID_TYPE_CAPTURE) { + + down(&id->open_lock); + switch(arg->type) { + case V4L2_BUF_TYPE_VIDEO_CAPTURE: + { + if (!((arg->fmt.pix.pixelformat == V4L2_PIX_FMT_YUV420_MB) || (arg->fmt.pix.pixelformat == V4L2_PIX_FMT_YUV420_YUMB))) + { + printk("Error in Setting Format \n"); + return -EINVAL; + } + + id->pix = arg->fmt.pix; + break; + } + + default: + return -EINVAL; + } + + configure_preprocessor(id); + up(&id->open_lock); + + } else if (id->type == VID_TYPE_OVERLAY) { + + down(&id->open_lock); + switch(arg->type) { + case V4L2_BUF_TYPE_VIDEO_OVERLAY: + { + id->win = arg->fmt.win; + break; + } + default: + return -EINVAL; + } + + if(unlikely(arg->fmt.win.clips)) { + dbgprintk(2,"Clipping requested for overlay device\n"); + if(!id->win.clips) { + id->win.clips = kzalloc(sizeof(struct v4l2_clip), GFP_KERNEL); + if(unlikely(!id->win.clips)) + return -ENOMEM; + } + + if(copy_from_user(id->win.clips, arg->fmt.win.clips, + sizeof(struct v4l2_clip)) != sizeof(struct v4l2_clip)) { + dbgprintk(3,"Access failed for clips\n"); + kfree(id->win.clips); + return -EACCES; + } + } + + configure_postprocessor(id); + up(&id->open_lock); + } else { + dbgprintk(3,"Invalid buffer type\n"); + return -EINVAL; + } + + return 0; +} + +int sva_reqbufs(struct video_open *id, struct v4l2_requestbuffers *req) +{ + int i; + int err = 0; + struct sva_buffer buffer; + if(unlikely(req->memory != V4L2_MEMORY_MMAP || req->count > MAX_BUFFERS)) + return -EINVAL; + + if(unlikely(req->type != V4L2_BUF_TYPE_VIDEO_CAPTURE && + req->type != V4L2_BUF_TYPE_VIDEO_OVERLAY)) + return -EINVAL; + + down(&id->open_lock); + if(unlikely(id->buffers_requested || !req->count)) { + dbgprintk(3,"Warning:Reallocating buffers count %d\n",req->count); + i = id->buffers_requested; + while(i--) { + if(!id->bufs[i].length) + continue; + buffer.type = BUF_TYPE_IMAGE; + buffer.buffer_id = i; + err = deallocate_buffer(&sva.device_open[id->device_id], + (unsigned long *)&buffer.buffer_id); + if(err) + goto out; + + id->bufs[i].length = 0; + id->bufs[i].bytesused = 0; + } + + } /* End if */ + + id->buffers_requested = req->count; + for(i=0;ibuffers_requested;i++) + id->bufs[i].type = req->type; + +out: + up(&id->open_lock); + return err; +} + +static int sva_querybuf(struct video_open *id, struct v4l2_buffer *arg) +{ + struct sva_buffer buffer; + int i = arg->index; + int err = -EINVAL; + + if (unlikely(arg->type != id->bufs[i].type)) + return -EINVAL; + if (unlikely(i < 0 || i >= id->buffers_requested )) + return -EINVAL; + + down(&id->open_lock); + if(unlikely(id->bufs[i].length)) { + err = 0; + goto out; /* Buffer already allocated */ + } + + if(id->type == VID_TYPE_CAPTURE) { + + switch(arg->type) { + case V4L2_BUF_TYPE_VIDEO_CAPTURE: + { + break; + } + + default: + goto out; + } + + if(!id->config.preprocessor_config.resized_frame.width) { + dbgprintk(2,"Need to call VIDIOC_S_FMT ioctl to set image size\n"); + goto out; + } + + buffer.size = id->config.preprocessor_config.resized_frame.height * + id->config.preprocessor_config.resized_frame.width * 3 / 2; + + + } else if (id->type == VID_TYPE_OVERLAY) { + + switch(arg->type) { + case V4L2_BUF_TYPE_VIDEO_OVERLAY: + { + break; + } + default: + goto out; + } + + if(!id->config.postprocessor_config.source_frame.width) { + dbgprintk(2,"Need to call VIDIOC_S_FMT ioctl to set image size\n"); + goto out; + } + + buffer.size = id->config.postprocessor_config.source_frame.height * + id->config.postprocessor_config.source_frame.width * 3 / 2; + + } + else + goto out; + + buffer.type = BUF_TYPE_IMAGE; + + err = allocate_buffer(&sva.device_open[id->device_id], &buffer); + if(err) + goto out; + + id->bufs[i].m.offset = buffer.offset; + id->bufs[i].type = arg->type; + id->bufs[i].index = buffer.buffer_id; + id->bufs[i].length = buffer.length; + id->bufs[i].bytesused = buffer.size; + id->bufs[i].memory = V4L2_MEMORY_MMAP; + +out: + *arg = id->bufs[i]; + up(&id->open_lock); + return err; +} + +static int sva_streamon(struct video_open *open) +{ + struct sva_control_service ctrl; + struct sva_service_struct service; + struct sva_device_open *dev_open = &sva.device_open[open->device_id]; + int err = -EINVAL; + + down(&open->open_lock); + + if(open->type == VID_TYPE_CAPTURE) + service.config.preprocessor_configuration + = open->config.preprocessor_config; + else + service.config.postprocessor_configuration + = open->config.postprocessor_config; + + service.service_id = open->service_id; + + if(unlikely(open->streaming)) + goto out; + + err = configure_service(dev_open, &service); + if(err) + goto out; + + ctrl.service_id = open->service_id; + ctrl.command = SERVICE_START; + + err = sva_service_control(dev_open, &ctrl); + if(err) + goto out; + + open->streaming = 1; + +out: + up(&open->open_lock); + if(err) + dbgprintk(3,"V4L2 Streamon failed\n"); + return err; +} + +static int sva_streamoff(struct video_open *open) +{ + struct sva_control_service ctrl; + struct sva_device_open *dev_open = &sva.device_open[open->device_id]; + int err = -EINVAL; + + ctrl.service_id = open->service_id; + ctrl.command = SERVICE_STOP; + + down(&open->open_lock); + if(unlikely(!open->streaming)) + goto out; + + err = sva_service_control(dev_open, &ctrl); + if(err) + goto out; + + err = delete_hcl_service(dev_open->service_open_data[open->service_id]); + if(err) + goto out; + + flush_service_queues(dev_open->service_open_data[open->service_id]); + + open->streaming = 0; + +out: + up(&open->open_lock); + if(err) + dbgprintk(3,"V4L2 Streamoff failed\n"); + return err; +} + +static int sva_qbuf(struct video_open *open, struct v4l2_buffer *arg) +{ + int err; + struct sva_queue_buffer qbuf; + + if (unlikely(arg->index < 0 || arg->index >= open->buffers_requested)) + return -EINVAL; + if (unlikely(arg->type != open->bufs[arg->index].type || + !open->bufs[arg->index].length)) + return -EINVAL; + + memset(&qbuf, 0, sizeof(qbuf)); + + if(open->type == VID_TYPE_CAPTURE) { + + qbuf.push = PUSH_OUT; + + } else if(open->type == VID_TYPE_OVERLAY) { + + qbuf.push = PUSH_IN; + qbuf.buffer.timestamp = (arg->timestamp.tv_sec * 1000 + + arg->timestamp.tv_usec / 1000) * 90; /* In SVA ticks*/ + } + else + return -EINVAL; + + qbuf.buffer.type = BUF_TYPE_IMAGE; + qbuf.buffer.buffer_id = arg->index; + qbuf.service_id = open->service_id; + + down(&open->open_lock); + err = sva_q_buffer(&sva.device_open[open->device_id], &qbuf); + if(err) + goto out; + + open->bufs[arg->index].flags &= ~V4L2_BUF_FLAG_DONE; + open->bufs[arg->index].flags |= V4L2_BUF_FLAG_QUEUED; + arg->flags = open->bufs[arg->index].flags; + +out: + up(&open->open_lock); + return err; +} + + +static int sva_vpip_version(struct video_open *open, int *arg) +{ +int err; +err=0; +*arg=VPIP_VERSION; +return err; + +} + +static int sva_copy_cam_params(struct video_open *open, struct nomadik_vpip_param *arg) +{ +int err; + +struct nomadik_vpip_param *mystr_ser; + +err=0; + + + +mystr_ser=(struct nomadik_vpip_param *)arg; + + +memcpy(&vpip_default_params[mystr_ser->vpip_config_reg],mystr_ser,sizeof(struct nomadik_vpip_param)); + +//printk("\nvpip_default_params: addr %d\n",vpip_default_params[mystr_ser->vpip_config_reg].addr); +//printk("\nvpip_default_params: valus %d\n",vpip_default_params[mystr_ser->vpip_config_reg].val); + +return err; + +} + +int sva_vpip_prescale_mode(struct video_open *open, int *arg) +{ + +int err = 0; +g_prescale= *arg; + + +return err; + +} + +int sva_vpip_auto_focus_mode(struct video_open *open, int *arg) +{ +struct vpip_autofocus_id upd; + +struct sva_device_open *srv_open = &sva.device_open[open->device_id]; + + +upd.service_id = open->service_id; +upd.value = *arg; +sva_vpip_auto_focus(srv_open,&upd); + +} + +int sva_vpip_user_mode(struct video_open *open, vpip_user_mode *arg); + +int sva_vpip_scene_mode(struct video_open *open, vpip_scene_mode *arg) +{ +vpip_scene_mode param; +int err = -EINVAL; +param=*arg; +switch(param) +{ +case SCENE_MODE_AUTO: + +err =sva_vpip_user_mode(open,(vpip_user_mode *)USER_MODE_EXPOSURE_AUTO); +err =sva_vpip_user_mode(open,(vpip_user_mode *)USER_MODE_AWB_AUTO); +err =sva_vpip_user_mode(open,(vpip_user_mode *)USER_MODE_SHARPNESS_NORMAL); +err =sva_vpip_user_mode(open,(vpip_user_mode *)USER_MODE_CONTRAST_NORMAL); +err =sva_vpip_user_mode(open,(vpip_user_mode *)USER_MODE_ISO_AUTO); +err =sva_vpip_user_mode(open,(vpip_user_mode *)USER_MODE_EC_NORMAL); +break; + +case SCENE_MODE_LANDSCAPE: + +err =sva_vpip_user_mode(open,(vpip_user_mode *)USER_MODE_EXPOSURE_AUTO); +err =sva_vpip_user_mode(open,(vpip_user_mode *)USER_MODE_AWB_DAYLIGHT); +err =sva_vpip_user_mode(open,(vpip_user_mode *)USER_MODE_SHARPNESS_HARD); +err =sva_vpip_user_mode(open,(vpip_user_mode *)USER_MODE_CONTRAST_NORMAL); +err =sva_vpip_user_mode(open,(vpip_user_mode *)USER_MODE_ISO_AUTO); +err =sva_vpip_user_mode(open,(vpip_user_mode *)USER_MODE_EC_NORMAL); +break; + +case SCENE_MODE_PORTRAIT: +err =sva_vpip_user_mode(open,(vpip_user_mode *)USER_MODE_EXPOSURE_BACKLIGHT); +err =sva_vpip_user_mode(open,(vpip_user_mode *)USER_MODE_AWB_AUTO); +err =sva_vpip_user_mode(open,(vpip_user_mode *)USER_MODE_SHARPNESS_SOFT); +err =sva_vpip_user_mode(open,(vpip_user_mode *)USER_MODE_CONTRAST_NORMAL); +err =sva_vpip_user_mode(open,(vpip_user_mode *)USER_MODE_ISO_AUTO); +err =sva_vpip_user_mode(open,(vpip_user_mode *)USER_MODE_EC_NORMAL); +break; + +case SCENE_MODE_NIGHT: + +err =sva_vpip_user_mode(open,(vpip_user_mode *)USER_MODE_EXPOSURE_NIGHT); +err =sva_vpip_user_mode(open,(vpip_user_mode *)USER_MODE_AWB_AUTO); +err =sva_vpip_user_mode(open,(vpip_user_mode *)USER_MODE_SHARPNESS_NORMAL); +err =sva_vpip_user_mode(open,(vpip_user_mode *)USER_MODE_CONTRAST_NORMAL); +err =sva_vpip_user_mode(open,(vpip_user_mode *)USER_MODE_ISO_AUTO); +err =sva_vpip_user_mode(open,(vpip_user_mode *)USER_MODE_EC_NORMAL); +break; + +case SCENE_MODE_SPORTS: +err =sva_vpip_user_mode(open,(vpip_user_mode *)USER_MODE_EXPOSURE_SPORT); +err =sva_vpip_user_mode(open,(vpip_user_mode *)USER_MODE_AWB_AUTO); +err =sva_vpip_user_mode(open,(vpip_user_mode *)USER_MODE_SHARPNESS_NORMAL); +err =sva_vpip_user_mode(open,(vpip_user_mode *)USER_MODE_CONTRAST_NORMAL); +err =sva_vpip_user_mode(open,(vpip_user_mode *)USER_MODE_ISO_AUTO); +err =sva_vpip_user_mode(open,(vpip_user_mode *)USER_MODE_EC_NORMAL); +break; +case SCENE_MODE_CLOSEUP: +err =sva_vpip_user_mode(open,(vpip_user_mode *)USER_MODE_EXPOSURE_AUTO); +err =sva_vpip_user_mode(open,(vpip_user_mode *)USER_MODE_AWB_AUTO); +err =sva_vpip_user_mode(open,(vpip_user_mode *)USER_MODE_SHARPNESS_NORMAL); +err =sva_vpip_user_mode(open,(vpip_user_mode *)USER_MODE_CONTRAST_NORMAL); +err =sva_vpip_user_mode(open,(vpip_user_mode *)USER_MODE_ISO_AUTO); +err =sva_vpip_user_mode(open,(vpip_user_mode *)USER_MODE_EC_NORMAL); +break; + +default: + +err=-EINVAL; +}//end switch + + +return err; + +} + + + + +int sva_vpip_user_mode(struct video_open *open, vpip_user_mode *arg) +{ + + +vpip_user_mode param,param2; +int err = -EINVAL; +struct vpip_usermode_update upd; + +param=*arg; + +struct sva_device_open *srv_open = &sva.device_open[open->device_id]; + +upd.service_id = open->service_id; +upd.user_mode = *arg; + +switch(param) { + +case USER_MODE_AWB_AUTO: +case USER_MODE_AWB_DAYLIGHT: +case USER_MODE_AWB_CLOUDY: +case USER_MODE_AWB_TUNGSTEN: +case USER_MODE_AWB_MODE_FLUORESCENT: + +err = write_pages_wb(srv_open,&upd); + +break; + +case USER_MODE_EC_NORMAL: +case USER_MODE_EC_Plus03: +case USER_MODE_EC_Plus06: +case USER_MODE_EC_Plus10: +case USER_MODE_EC_Plus13: +case USER_MODE_EC_Plus16: +case USER_MODE_EC_Plus20: +case USER_MODE_EC_Minus03: +case USER_MODE_EC_Minus06: +case USER_MODE_EC_Minus10: +case USER_MODE_EC_Minus13: +case USER_MODE_EC_Minus16: +case USER_MODE_EC_Minus20: +upd.user_mode=(upd.user_mode-5);//offset from enum for particular group of user mode +err = write_pages_ec(srv_open,&upd); + + +break; + +case USER_MODE_ISO_AUTO: +case USER_MODE_ISO_050: +case USER_MODE_ISO_100: +case USER_MODE_ISO_200: +case USER_MODE_ISO_400: +case USER_MODE_ISO_800: +upd.user_mode=(upd.user_mode-18); +err = write_pages_iso(srv_open,&upd); + +break; + +case USER_MODE_COLORTONE_NORMAL: +case USER_MODE_COLORTONE_SEPIA : +case USER_MODE_COLORTONE_GRAYSCALE: +case USER_MODE_COLORTONE_VIVID : +case USER_MODE_COLORTONE_NEGATIVE: +upd.user_mode=(upd.user_mode-24); +err = write_pages_colortone(srv_open,&upd); + + +break; + +case USER_MODE_CONTRAST_NORMAL: +case USER_MODE_CONTRAST_110: +case USER_MODE_CONTRAST_120: +case USER_MODE_CONTRAST_130: +case USER_MODE_CONTRAST_140: +case USER_MODE_CONTRAST_150: +case USER_MODE_CONTRAST_160: +case USER_MODE_CONTRAST_170: +case USER_MODE_CONTRAST_180: +case USER_MODE_CONTRAST_190: +case USER_MODE_CONTRAST_200: + +upd.user_mode=(upd.user_mode-29); +err = write_pages_contrast(srv_open,&upd); + +break; + + +case USER_MODE_SHARPNESS_NORMAL: +case USER_MODE_SHARPNESS_HARD: +case USER_MODE_SHARPNESS_SOFT: +case USER_MODE_SHARPNESS_NONE: +upd.user_mode=(upd.user_mode-40); +err = write_pages_sharpness(srv_open,&upd); + +break; + +case USER_MODE_EXPOSURE_AUTO: +case USER_MODE_EXPOSURE_NIGHT: +case USER_MODE_EXPOSURE_CENTER: +case USER_MODE_EXPOSURE_BACKLIGHT: +case USER_MODE_EXPOSURE_SPORT: +upd.user_mode=(upd.user_mode-44); +err = write_pages_exposure(srv_open,&upd); + + +break; +default: + +err=-EINVAL; + + }//end switch +return err; +} + +static int sva_cropcap(struct video_open *id, struct v4l2_cropcap *arg) +{ + /* can't set the format if buffer are already requested or device + * is streaming */ + + if(unlikely(id->streaming)) + return -EINVAL; + + if(id->type == VID_TYPE_CAPTURE) { + + down(&id->open_lock); + switch(arg->type) { + case V4L2_BUF_TYPE_VIDEO_CAPTURE: + { + if(arg->bounds.width == 0) { +#ifdef CONFIG_NOMADIK_SVA_VPIP + arg->bounds.height = 1536; + arg->bounds.width = 2048; +#else + arg->bounds.height = 480; + arg->bounds.width = 640; +#endif + } else { + id->cropcap = *arg; + } + break; + } + + default: + return -EINVAL; + } + + configure_preprocessor(id); + up(&id->open_lock); + + } else if (id->type == VID_TYPE_OVERLAY) { + + down(&id->open_lock); + switch(arg->type) { + case V4L2_BUF_TYPE_VIDEO_OVERLAY: + { + if(arg->bounds.width == 0) { +#ifdef CONFIG_NOMADIK_SVA_VPIP + arg->bounds.height = 1536; + arg->bounds.width = 2048; +#else + arg->bounds.height = 480; + arg->bounds.width = 640; +#endif + } else { + id->cropcap = *arg; + } + break; + } + default: + return -EINVAL; + } + configure_postprocessor(id); + up(&id->open_lock); + } + else + return -EINVAL; + + return 0; +} + +int sva_s_ctrl(struct video_open *id, struct v4l2_control *arg) +{ + switch(arg->id) { + case V4L2_CID_BRIGHTNESS: + { + struct sva_update_service upd; + + if(arg->value < 0 || arg->value > 99) + return -EINVAL; + + if(id->type != VID_TYPE_OVERLAY) + return -EINVAL; + + upd.service_id = id->service_id; + upd.param = POSTPROCESSOR_BRIGHTNESS; + upd.value = &arg->value; + upd.type = UPDATE_LAST; + + return sva_service_update(&sva.device_open[id->device_id], &upd); + } + + case V4L2_CID_CONTRAST: + { + struct sva_update_service upd; + + if(id->type != VID_TYPE_OVERLAY) + return -EINVAL; + + if(arg->value < 0 || arg->value > 99) + return -EINVAL; + + upd.service_id = id->service_id; + upd.param = POSTPROCESSOR_CONTRAST; + upd.value = &arg->value; + upd.type = UPDATE_LAST; + + return sva_service_update(&sva.device_open[id->device_id], &upd); + } + + case V4L2_CID_CROP: + { + struct sva_update_service upd; + struct sva_window_desc win_desc; + struct v4l2_rect *rect = (struct v4l2_rect *)arg->value; + + win_desc.frame.height = rect->height; + win_desc.frame.width = rect->width; + win_desc.offset.x_offset = rect->left; + win_desc.offset.y_offset = rect->top; + + if(id->type == VID_TYPE_CAPTURE) + upd.param = PREPROCESSOR_CROP; + else + upd.param = POSTPROCESSOR_CROP; + + upd.service_id = id->service_id; + upd.value = &win_desc; + upd.type = UPDATE_LAST; + + return sva_service_update(&sva.device_open[id->device_id], &upd); + } + + case V4L2_CID_RESIZE: + { + struct sva_update_service upd; + struct sva_image image; + struct v4l2_rect *rect = (struct v4l2_rect *)arg->value; + + image.height = rect->height; + image.width = rect->width; + + if(id->type == VID_TYPE_CAPTURE) { + upd.param = PREPROCESSOR_RESIZE; + } else { + struct sva_window_desc win; + + win.frame.height = rect->height; + win.frame.width = rect->width; + win.offset.x_offset = 0; + win.offset.y_offset = 0; + + upd.param = POSTPROCESSOR_CLIP; + upd.service_id = id->service_id; + upd.value = &win; + upd.type = UPDATE_MULTIPLE; + + if(sva_service_update(&sva.device_open[id->device_id], &upd)) + return -EINVAL; + + upd.param = POSTPROCESSOR_RESIZE; + } + + upd.service_id = id->service_id; + upd.value = ℑ + upd.type = UPDATE_LAST; + + return sva_service_update(&sva.device_open[id->device_id], &upd); + } + + + default: + return -EINVAL; + } + +} + + +int sva_private_ioctl(struct video_open *id, struct v4l2_control *arg) +{ + +switch(arg->id) { + + case PREPROCESSOR_CROP: + case PREPROCESSOR_RESIZE: + case PREPROCESSOR_ACE_ENABLE: + case PREPROCESSOR_ACE_STRENGTH: + case PREPROCESSOR_OUTPUT_RANGE: + case PREPROCESSOR_ACE_RANGE: + case PREPROCESSOR_ACE_OFFSET: + + case PREPROCESSOR_ZOOM_IN: + case PREPROCESSOR_ZOOM_OUT: + case PREPROCESSOR_CONTRAST: + case PREPROCESSOR_COLOUR_SATURATION: + case PREPROCESSOR_WHITEBALANCE: + case PREPROCESSOR_COLMATRIX_DAMPING: + case PREPROCESSOR_EXPOSURE: + case PREPROCESSOR_ENABLE_FUNCBLOCK: + case PREPROCESSOR_FADETOBLACK: +case PREPROCESSOR_RADIAL_PEAKING: + + { + struct sva_update_service upd; + + if(arg->value < 0 || arg->value > 99) + return -EINVAL; + + upd.service_id = id->service_id; + upd.param = arg->id;//PREPROCESSOR_ZOOM_IN; + upd.value = &arg->value; + upd.type = UPDATE_LAST; + + return sva_service_update(&sva.device_open[id->device_id], &upd); + } + + default: + return -EINVAL; +} + + } + +static int sva_dqbuf(struct video_open *open, struct v4l2_buffer *arg, int nonblock) +{ + int err; + struct sva_queue_buffer qbuf; + + if(open->type == VID_TYPE_CAPTURE) { + + switch(arg->type) { + case V4L2_BUF_TYPE_VIDEO_CAPTURE: + { + break; + } + + default: + return -EINVAL; + } + + } else if (open->type == VID_TYPE_OVERLAY) { + + switch(arg->type) { + case V4L2_BUF_TYPE_VIDEO_OVERLAY: + { + break; + } + default: + return -EINVAL; + } + } + + dbgprintk(2,"Mode specified %d\n",nonblock); + + if(nonblock) + qbuf.block = NON_BLOCK; + else + qbuf.block = BLOCK; + + if(open->type == VID_TYPE_CAPTURE) { + + qbuf.buffer.type = BUF_TYPE_IMAGE; + qbuf.push = PUSH_OUT; + qbuf.service_id = open->service_id; + + } else if(open->type == VID_TYPE_OVERLAY) { + + qbuf.buffer.type = BUF_TYPE_IMAGE; + qbuf.push = PUSH_IN; + qbuf.service_id = open->service_id; + + } + else + return -EINVAL; + + down(&open->open_lock); + err = sva_dqueue_buffer(&sva.device_open[open->device_id], &qbuf); + if(err) { + open->bufs[qbuf.buffer.buffer_id].flags &= ~V4L2_BUF_FLAG_QUEUED; + open->bufs[qbuf.buffer.buffer_id].flags &= ~V4L2_BUF_FLAG_DONE; + up(&open->open_lock); + return err; + } + + open->bufs[qbuf.buffer.buffer_id].flags |= V4L2_BUF_FLAG_DONE; + open->bufs[qbuf.buffer.buffer_id].flags &= ~V4L2_BUF_FLAG_QUEUED; + up(&open->open_lock); + arg->flags = open->bufs[qbuf.buffer.buffer_id].flags; + arg->index = qbuf.buffer.buffer_id; + arg->reserved = sva.device_open[open->device_id].index ; + + arg->bytesused = open->bufs[qbuf.buffer.buffer_id].bytesused; + //printk("KERNEL : arg->bytesused = %d",arg->bytesused); + + if(open->type == VID_TYPE_CAPTURE) { + unsigned long timestamp = qbuf.buffer.timestamp / 90; + if(timestamp > 999999) { + arg->timestamp.tv_sec = timestamp / 1000; + arg->timestamp.tv_usec = (timestamp % 1000) * 1000; + } + } + + return 0; +} + +/* + * This function is _not_ called directly, but from + * video_generic_ioctl (and maybe others). userspace + * copying is done already, arg is a kernel pointer. + */ +static int video_do_ioctl(struct inode *inode, struct file *filp, + unsigned int cmd, void *arg) +{ + + struct video_open *open = filp->private_data; + + switch (cmd) { + + /* --- capabilities ------------------------------------------ */ + case VIDIOC_QUERYCAP: + { + struct v4l2_capability *cap = arg; + + if(open->type == VID_TYPE_CAPTURE) { + memset(cap,0,sizeof(*cap)); + strcpy(cap->driver, "v4l2-nomadik-capture"); + sprintf(cap->bus_info,"AMBA:sva"); + cap->version = KERNEL_VERSION(2,6,16); + cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; + } else { + memset(cap,0,sizeof(*cap)); + strcpy(cap->driver, "v4l2-nomadik-display"); + sprintf(cap->bus_info,"AMBA:sva"); + cap->version = KERNEL_VERSION(2,6,16); + cap->capabilities = V4L2_CAP_VIDEO_OVERLAY | V4L2_CAP_STREAMING; + } + + return 0; + } + + case VIDIOC_S_FMT: + { + struct v4l2_format *f = arg; + if(open->streaming) + return -EINVAL; + return sva_s_fmt(open,f); + } + + case VIDIOC_S_CTRL: + { + struct v4l2_control *ctrl = arg; + return sva_s_ctrl(open, ctrl); + } + + case VIDIOC_CROPCAP: + { + struct v4l2_cropcap *cropcap = arg; + return sva_cropcap(open, cropcap); + } + + case VIDIOC_REQBUFS: + if(open->streaming) + return -EINVAL; + return sva_reqbufs(open, arg); + + case VIDIOC_QUERYBUF: + return sva_querybuf(open, arg); + + case VIDIOC_QBUF: + return sva_qbuf(open, arg); + + case VIDIOC_DQBUF: + return sva_dqbuf(open, arg, filp->f_flags & O_NONBLOCK); + + case VIDIOC_STREAMON: + { + return sva_streamon(open); + } + case VIDIOC_STREAMOFF: + { + return sva_streamoff(open); + } + + case VIDIOC_G_INPUT: + { + int *i = arg; + *i = 0; /* Only one INPUT is supported */ + //printk("case VIDIOC_G_INPUT called\n"); + return 0; + } + case VIDIOC_S_INPUT: + { + int *i = arg; + printk("case VIDIOC_S_INPUT called\n"); + if ( *i ) { /* Only one INPUT is supported */ + //printk("Only one input source is supported with this webcam.\n"); + return -EINVAL; + } + return 0; + } + case VIDIOC_G_FMT: + { + struct v4l2_format *f = arg; + if(open->streaming) + return -EINVAL; + return sva_g_fmt(open,f); + } + case VIDIOC_G_PARM: + { + struct v4l2_streamparm *sp = arg; + sp->parm.capture.timeperframe.numerator = NOMADIK_DEFAULT_FRAMERATE_DENOMINATOR; + sp->parm.capture.timeperframe.denominator = NOMADIK_DEFAULT_FRAMERATE_NUMERATOR; + return 0 ; + } + case VIDIOC_S_PARM: + { + struct v4l2_streamparm *sp = arg; + //NEED TO PUT CODE FOR SETTING THE FRAMERATE IN SVA DRIVER + return 0 ; + } + + case VIDIOC_SVA_CONFIG: + + { + + struct v4l2_control *ctrl = arg; + + return sva_private_ioctl(open, ctrl); + } + + case VIDIOC_COPY_CAM_PARAMS: + { + return sva_copy_cam_params(open,arg); + } + + case VIDIOC_VPIP_VERSION: + { + return sva_vpip_version(open,arg); + } + + case VIDIOC_VPIP_USER_MODE: + { + return sva_vpip_user_mode(open,arg); + } + + case VIDIOC_VPIP_SCENE_MODE: + { + return sva_vpip_scene_mode(open,arg); + } + + case VIDIOC_VPIP_AUTO_FOCUS: + { + return sva_vpip_auto_focus_mode(open,arg); + } + + case VIDIOC_VPIP_PRESCALE: + { + return sva_vpip_prescale_mode(open,arg); + } + + default: + return -ENOIOCTLCMD; + } +} + + +void +v4l2_vma_open(struct vm_area_struct *vma) +{ + struct file *filp = vma->vm_file; + struct video_open *open = filp->private_data; + __u8 indx = 0; + + while(indx < MAX_BUFFERS) { + if(((vma->vm_pgoff << PAGE_SHIFT)==open->bufs[indx].m.offset)) + break; + + indx++; + } + + if(unlikely(indx == MAX_BUFFERS)) { + dbgprintk(3,"error: %s() buffer %lu not found\n",__FUNCTION__, + vma->vm_pgoff << PAGE_SHIFT); + return; + } + + down(&open->open_lock); + vma->vm_file->private_data = &sva.device_open[open->device_id]; + sva_vma_open(vma); + vma->vm_file->private_data = open; + up(&open->open_lock); + + return; +} + +void +v4l2_vma_close(struct vm_area_struct *vma) +{ + struct file *filp = vma->vm_file; + struct video_open *open=filp->private_data; + __u8 indx = 0; + + while(indx < MAX_BUFFERS) { + if((vma->vm_pgoff << PAGE_SHIFT)==open->bufs[indx].m.offset) + break; + + indx++; + } + + if(unlikely(indx == MAX_BUFFERS)) { + dbgprintk(3,"error: %s() buffer %lu not found\n",__FUNCTION__, + vma->vm_pgoff << PAGE_SHIFT); + return; + } + + down(&open->open_lock); + filp->private_data = &sva.device_open[open->device_id]; + sva_vma_close(vma); + filp->private_data = open; + if(!(sva.device_open[open->device_id].buffer_info[indx]->buffer.flags & BUF_FLAG_MAPPED)) + open->bufs[indx].flags &= ~V4L2_BUF_FLAG_MAPPED; + + up(&open->open_lock); + return; +} + +static int video_ioctl(struct inode *inode, struct file *file, + unsigned int cmd, unsigned long arg) +{ + return video_usercopy(inode, file, cmd, arg, video_do_ioctl); +} + +static struct vm_operations_struct v4l2_vma_operations = { + v4l2_vma_open, v4l2_vma_close, NULL, +}; + +static int +video_mmap(struct file *file, struct vm_area_struct * vma) +{ + int err; + struct video_open *open = file->private_data; + __u8 indx = 0; + + down(&open->open_lock); + while(indx < MAX_BUFFERS) { + if((vma->vm_pgoff << PAGE_SHIFT)==open->bufs[indx].m.offset) + break; + + indx++; + } + + if(unlikely(indx == MAX_BUFFERS)) { + dbgprintk(3,"error:%s (), buffer indx %lu not found\n", + __FUNCTION__,vma->vm_pgoff); + up(&open->open_lock); + return -EINVAL; + } + + dbgprintk(2,"%s(), buffer indx %lu found\n",__FUNCTION__,vma->vm_pgoff); + + file->private_data = &sva.device_open[open->device_id]; + vma->vm_file->private_data = file->private_data; + err = sva_mmap(file, vma); + file->private_data = open; + vma->vm_file->private_data = open; + if(err) { + up(&open->open_lock); + return err; + } + + vma->vm_ops = &v4l2_vma_operations; + + open->bufs[indx].flags |= V4L2_BUF_FLAG_MAPPED; + + up(&open->open_lock); + + return 0; + +} + +static int video_open(struct inode *inode, struct file *file) +{ + int minor; + struct sva_service_struct service; + struct video_open *open; + int err; + int i = 0; + + down(&driver_mutex); + while(i < MAX_OPENS && dev->opens[i]) + i++; + + if(i >= MAX_OPENS) { + err = -EBUSY; + goto out; + } + + dev->opens[i] = kzalloc(sizeof(struct video_open), GFP_KERNEL); + if(!dev->opens[i]) { + err = -ENOMEM; + goto out; + } + + open = dev->opens[i]; + open->self_id = i; + + minor = MINOR(inode->i_rdev); + if(minor == 0) { + dbgprintk(1,"Capture device opened\n"); + open->type = VID_TYPE_CAPTURE; /* capture device */ + service.service_type = PREPROCESSOR; +#ifdef CONFIG_NOMADIK_SVA_VPIP + service.config.preprocessor_configuration.capability = SENSOR_YUV420_MB; +#else + service.config.preprocessor_configuration.capability = YUV420_MB; +#endif + + } + else if(minor == 1) { + dbgprintk(1,"Overlay device opened\n"); + open->type = VID_TYPE_OVERLAY; + service.service_type = POSTPROCESSOR; + } + else { + err = -ENODEV; + goto out; + } + + err = sva_open(inode, file); + if(err) { + goto out; + } + + open->device_id = (struct sva_device_open*)file->private_data - + &sva.device_open[0]; + + file->private_data = open; + err = create_service(&sva.device_open[open->device_id], &service); + if(err) { + file->private_data=&sva.device_open[open->device_id]; + sva_release(inode, file); + file->private_data = open; + goto out; + } + + open->service_id = service.service_id; + init_MUTEX(&open->open_lock); + up(&driver_mutex); + return 0; + +out: + if(i < MAX_OPENS && dev->opens[i]) { + kfree(dev->opens[i]); + dev->opens[i] = NULL; + } + up(&driver_mutex); + + return err; +} + +static int video_release(struct inode *inode, struct file *file) +{ + struct video_open *open = file->private_data; + int open_index = open->self_id; + + down(&driver_mutex); + file->private_data = &sva.device_open[open->device_id]; + sva_release(inode, file); + file->private_data = open; + if(open->win.clips) + kfree(open->win.clips); + + if(likely(dev->opens[open_index])) { + kfree(dev->opens[open_index]); + dev->opens[open_index]=NULL; + } + up(&driver_mutex); + + return 0; +} + +static struct file_operations video_fops = +{ + .owner = THIS_MODULE, + .open = video_open, + .release = video_release, + .mmap = video_mmap, + .ioctl = video_ioctl, +}; + +static struct video_device sva_video_template = +{ + .name = "sva", + .type = VID_TYPE_CAPTURE, + .hardware = 0, + .fops = &video_fops, + .minor = -1, +}; + +struct video_device *sva_vdev_init(struct video_device *template, + char *type) +{ + struct video_device *vfd; + + vfd = video_device_alloc(); + if (NULL == vfd) + return NULL; + *vfd = *template; + vfd->minor = -1; + vfd->dev = NULL; + vfd->release = video_device_release; + snprintf(vfd->name, sizeof(vfd->name), "%s%s", + "v4l2-nomadik-", type); + return vfd; +} + +static void v4l2_sva_unregister(struct v4l2_sva_dev *dev) +{ + if (dev->capture_video_dev) { + if (-1 != dev->capture_video_dev->minor) + video_unregister_device(dev->capture_video_dev); + else + video_device_release(dev->capture_video_dev); + dev->capture_video_dev = NULL; + } + + if (dev->display_video_dev) { + if (-1 != dev->display_video_dev->minor) + video_unregister_device(dev->display_video_dev); + else + video_device_release(dev->display_video_dev); + dev->display_video_dev = NULL; + } +} +static int nomadik_v4l2_probe(struct platform_device *device) +{ + int err = 0; + + dev = kzalloc(sizeof(*dev),GFP_KERNEL); + if (NULL == dev) { + return -ENOMEM; + } + + /* register v4l2 devices */ + dev->capture_video_dev = sva_vdev_init(&sva_video_template,"capture"); + if(!dev->capture_video_dev) { + dbgprintk(3,"error:Capture device register failed\n"); + err = -EAGAIN; + goto fail_reg; + } + err = video_register_device(dev->capture_video_dev,VFL_TYPE_GRABBER,0); + + if (err < 0) { + dbgprintk(3,"error:%s: can't register video device\n", + dev->capture_video_dev->name); + goto fail_reg; + } + + sva_video_template.type = VID_TYPE_OVERLAY; + dev->display_video_dev = sva_vdev_init(&sva_video_template,"display"); + if(!dev->display_video_dev) { + dbgprintk(3,"error:Display device register failed\n"); + err = -EAGAIN; + goto fail_reg; + } + err = video_register_device(dev->display_video_dev,VFL_TYPE_GRABBER,1); + if (err < 0) { + dbgprintk(3,"error:%s: can't register video device\n", + dev->display_video_dev->name); + goto fail_reg; + } + + dbgprintk(3,"%s: registered device video%d [v4l2]\n", + dev->capture_video_dev->name, dev->capture_video_dev->minor & 0x1f); + + dbgprintk(3,"%s: registered device video%d [v4l2]\n", + dev->display_video_dev->name, dev->display_video_dev->minor & 0x1f); + + return 0; + +fail_reg: + v4l2_sva_unregister(dev); + kfree(dev); + dev = NULL; + return err; +} + +static int nomadik_v4l2_remove(struct platform_device *device) +{ + v4l2_sva_unregister(dev); + return 0; +} + +static struct platform_device *device; +static struct platform_driver nmdk_v4l2_driver = { + .driver = { + .name = "Nomadik-V4L2", + }, + .probe = nomadik_v4l2_probe, + .remove = nomadik_v4l2_remove +}; + +static int v4l2_sva_init(void) +{ + int err; + init_MUTEX(&driver_mutex); + + device = platform_device_register_simple("Nomadik-V4L2", -1 , NULL, 0); + if (IS_ERR(device)) { + return PTR_ERR(device); + } + + if ((err = platform_driver_register(&nmdk_v4l2_driver)) < 0) { + platform_device_unregister(device); + } + + return err; +} + +static void v4l2_sva_fini(void) +{ + platform_driver_unregister(&nmdk_v4l2_driver); + platform_device_unregister(device); + + if(dev) + kfree(dev); + + dev=NULL; +} + +module_init(v4l2_sva_init); +module_exit(v4l2_sva_fini); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Melwyn LOBO "); + + --- /dev/null +++ linux-2.6.20/drivers/media/video/v4l2-nomadik.h @@ -0,0 +1,70 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ +/* information, STMicroelectronics reserves the right to license this */ +/* software concurrently under separate license conditions. */ +/* */ +/* This program is free software; you can redistribute it and/or modify it */ +/* under the terms of the GNU Lesser General Public License as published */ +/* by the Free Software Foundation; either version 2.1 of the License, */ +/* or (at your option)any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with this program. If not, see . */ +/*---------------------------------------------------------------------------*/ + +#include +#include +#include +#include "nomadik_sva.h" +#include +#include + +struct video_open { + __u32 type; + __u8 buffers_requested; + __u8 streaming; + __u8 device_id; + __u8 self_id; + struct v4l2_cropcap cropcap; + struct v4l2_window win; + struct v4l2_pix_format pix; + struct v4l2_buffer bufs[MAX_BUFFERS]; + __u32 service_id; + union { + struct sva_preprocessor_configuration preprocessor_config; + struct sva_postprocessor_configuration postprocessor_config; + } config; + struct semaphore open_lock; + +}; + +struct v4l2_sva_dev { + struct video_device *capture_video_dev; + struct video_device *display_video_dev; + struct video_open *opens[MAX_OPENS]; + +}; + +void sva_vma_open(struct vm_area_struct *vma); +void sva_vma_close(struct vm_area_struct *vma); +int sva_mmap(struct file *filp, struct vm_area_struct *vma); +int sva_release(struct inode *inode, struct file *filp); +int sva_open (struct inode *inode, struct file *filp); +int create_service (struct sva_device_open *open, struct sva_service_struct *srv); +void delete_service (struct sva_device_open *open, int); +int delete_hcl_service(struct sva_service_open* srv_open); +int configure_service (struct sva_device_open *open, struct sva_service_struct *srv); +int sva_service_control(struct sva_device_open *open, struct sva_control_service *srv); +int sva_delete_service(struct sva_device_open *open, struct sva_service_struct *srv); +int sva_q_buffer(struct sva_device_open *open, struct sva_queue_buffer *qbuf); +int sva_dqueue_buffer(struct sva_device_open *open, struct sva_queue_buffer *qbuf); +int allocate_buffer(struct sva_device_open *open, struct sva_buffer *buf); +int deallocate_buffer(struct sva_device_open *open, unsigned long *buf); +int sva_service_update(struct sva_device_open *open, struct sva_update_service *update); + + --- linux-2.6.20.orig/drivers/misc/Kconfig +++ linux-2.6.20/drivers/misc/Kconfig @@ -1,11 +1,33 @@ # # Misc strange devices # +# depends on ARCH_NOMADIK NOMADIK_SSP NOMADIK_GPIO + menu "Misc devices" + +config STMPE_NOMADIK + tristate "Port expander driver for Nomadik board" + depends on NOMADIK_NHK15 + help + Say Y here if you have a port expander in your platform. + +config SIF_NOMADIK + tristate "Display protocol driver for nhk15" + depends on NOMADIK_NHK15 + help + Say Y here if you want to change the gamma, brightness and contrast values + for the display + +config ETM_NOMADIK + tristate "ETM support nhk15" + depends on NOMADIK_NHK15 + help + Say Y here if you want ETM support for debugging. + config IBM_ASM tristate "Device driver for IBM RSA service processor" depends on X86 && PCI && EXPERIMENTAL ---help--- This option enables device driver support for in-band access to the @@ -86,6 +108,11 @@ config MSI_LAPTOP More information about this driver is available at . If you have an MSI S270 laptop, say Y or M here. +config BATT_NOMADIK + tristate "Battery charger driver for Nomadik board" + depends on NOMADIK_NHK15 + help + Say Y here if you have a port expander in your platform. endmenu --- linux-2.6.20.orig/drivers/misc/Makefile +++ linux-2.6.20/drivers/misc/Makefile @@ -8,5 +8,9 @@ obj-$(CONFIG_HDPU_FEATURES) += hdpuftrs/ obj-$(CONFIG_MSI_LAPTOP) += msi-laptop.o obj-$(CONFIG_LKDTM) += lkdtm.o obj-$(CONFIG_TIFM_CORE) += tifm_core.o obj-$(CONFIG_TIFM_7XX1) += tifm_7xx1.o obj-$(CONFIG_SGI_IOC4) += ioc4.o +obj-$(CONFIG_STMPE_NOMADIK) += pexp-nomadik.o +obj-$(CONFIG_SIF_NOMADIK) += sif-nomadik.o +obj-$(CONFIG_ETM_NOMADIK) += etm-nomadik.o +obj-$(CONFIG_BATT_NOMADIK) += batt-nomadik.o \ No newline at end of file --- /dev/null +++ linux-2.6.20/drivers/misc/batt-nomadik.c @@ -0,0 +1,1307 @@ +/* + * Overview: + * Driver for ST4102 device (battery charger) using i2c interface on Nomadik Platforms + * + * Copyright (C) 2007 STMicroelectronics Pvt. Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#include +#include +#include +#include +#include +#include +#include + +#define DEBUG 1 + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("STMicroelectronics"); +MODULE_DESCRIPTION("Battery charger driver for ST4102 device"); +MODULE_SUPPORTED_DEVICE("stbat"); + + +static struct timer_list notify_timer; +struct work_struct workq; +static unsigned long watchdog_timeout; + +/* BEGIN +ALl functions beneath were taken from t_stw4102.c which is part of the HTT package and adapted for the Linux Kernel +*/ +typedef enum { + REG_CHG0 = 0x0, + REG_CHG1, + REG_WDOG, + REG_CG, + REG_CHARGE_LOW, + REG_CHARGE_MID, + REG_CHARGE_HIGH, + REG_DISCHARGE_LOW, + REG_DISCHARGE_MID, + REG_DISCHARGE_HIGH, + REG_CONVDATA_LOW =0x10, + REG_CONVDATA_HIGH =0x11, + REG_CONVNUMBER_LOW =0x12, + REG_CONVNUMBER_HIGH =0x13, + REG_ADCTRL =0x14, + REG_ADDATA_LOW =0x15, + REG_ADDATA_HIGH =0x16 +} REGs; + +/* Charge Control and status Register*/ +#define REG_CHG0_CHARGERUN 0x01 +#define REG_CHG0_MAINDETECT 0x02 +#define REG_CHG0_USBDETECT 0x04 +#define REG_CHG0_VCHG_LOW 0x08 +#define REG_CHG0_VCHG_HIGH 0x10 +#define REG_CHG0_SEL_DC_USB 0x20 +#define REG_CHG0_USB_ICHG_LOW 0x40 +#define REG_CHG0_USB_ICHG_HIGH 0x80 +/* Charge enable Register*/ +#define REG_CHG1_CHG_ENA 0x01 +#define REG_CHG1_FORCECHARGER 0x10 +#define REG_CHG1_SEL_IS 0x20 +/* WatchDog register*/ +#define REG_WDOG_WDOG_EN 0x01 +#define REG_WDOG_WDOG_TIME_LOW 0x02 +#define REG_WDOG_WDOG_TIME_HIGH 0x04 +#define REG_WDOG_WDOG_RST 0x08 +#define REG_WDOG_INT 0x40 +/* Gas Guage Control*/ +#define REG_CG_CG_ENA 0x01 +#define REG_CG_RST_CHRG 0x02 +#define REG_CG_RST_DCHRG 0x04 +#define REG_CG_RST_COUNTER 0x08 +#define REG_CG_RD_REQ 0x10 +#define REG_CG_CG_CAL 0x20 +#define REG_CG_CG_EOC 0x40 +/* Battery Monitor Control*/ +#define REG_ADCTRL_ADPOWERON 0x01 +#define REG_ADCTRL_ONSTATE 0x02 +#define REG_ADCTRL_ADSTART 0x04 +#define REG_ADCTRL_ADRUN 0x08 +#define REG_ADCTRL_ADRESOLUTION 0x10 +#define REG_ADCTRL_ADCAL 0x20 + +typedef enum +{ + WATCHDOG_1MIN, + WATCHDOG_15MIN = 0x02, + WATCHDOG_30MIN = 0x04, + WATCHDOG_60MIN = 0x06, + WATCHDOG_DISABLE +} t_STw4102_watchdog; + + +typedef enum +{ + VCHG_4_10V, + VCHG_4_20V = 0x08, + VCHG_4_30V = 0x10, + VCHG_4_35V = 0x18 + +}t_STw4102_vchg; + +typedef enum +{ + USB_ICHG_60mA, + USB_ICHG_200mA = 0x40, + USB_ICHG_400mA = 0x80, + USB_ICHG_OFF = 0xC0 + +}t_STw4102_usb_ichg; + +typedef enum +{ + RES_7BIT, + RES_12BIT +}t_STw4102_adc_res; + +typedef enum +{ + SOURCE_BATT, + SOURCE_EXT +}t_STw4102_source; + +typedef enum +{ + STATE_DISABLE= 0, + STATE_ENABLE = 1 +}state; + +struct config_info { + t_STw4102_vchg vchg; + t_STw4102_usb_ichg ichg; + t_STw4102_watchdog wdogtime; + t_STw4102_adc_res adcres; + t_STw4102_source source; + state charger; + state watchdog; + +}; + +struct config_info current_config = +{ + VCHG_4_20V, + USB_ICHG_200mA, + WATCHDOG_DISABLE, + RES_7BIT, + SOURCE_BATT, + STATE_ENABLE, + STATE_DISABLE +}; + +/* Declaration of stcharg.c functions */ +void nomadik_stcharg_exit(void); +int nomadik_stcharg_init(void); +static int ST4102_Read(uint8 offset,uint8 *buffer, uint8 NbBytes); +static int ST4102_Write(uint8 offset, uint8 DataValue ); +int STw4102_standby(state); +int STw4102_reset(state); +int STw4102_disable(void); +int STw4102_enable(void); +int STw4102_setwatchdog(t_STw4102_watchdog,state); +int STw4102_init(void); +int STw4102_getremainingcharge(uint32 *remCharge); +int STw4102_getbatteryvoltage(uint16 *battvolt); + +/* Sys interfaces*/ + +static struct kobject *stcharg_kobj; + +static ssize_t stcharg_show(struct kobject* kobj, struct attribute* attr, char* buf) +{ + int error = 0; + uint32 remCharge = 0; + uint16 battvolt = 0; + uint8 data = 0; + + if (strcmp(attr->name, "getcharge") == 0){ + error = STw4102_getremainingcharge(&remCharge); + sprintf(buf, "%d\n",remCharge ); + } + else if (strcmp(attr->name, "getvoltage") == 0){ + error = STw4102_getbatteryvoltage(&battvolt); + sprintf(buf, "%d\n",battvolt ); + } + else if (strcmp(attr->name, "chargingvoltage") == 0){ + error = ST4102_Read(REG_CHG0,&data, 1); + switch(data & (REG_CHG0_VCHG_LOW|REG_CHG0_VCHG_HIGH)) + { + case VCHG_4_10V: + sprintf(buf, "%s\n","4.1v" ); + break; + case VCHG_4_20V: + sprintf(buf, "%s\n","4.2v" ); + break; + case VCHG_4_30V: + sprintf(buf, "%s\n","4.3v" ); + break; + case VCHG_4_35V: + sprintf(buf, "%s\n","4.35v" ); + break; + } + } + else if (strcmp(attr->name, "usbchargingcurrent") == 0){ + + error = ST4102_Read(REG_CHG0,&data, 1); + if(data ®_CHG0_SEL_DC_USB){ + + switch(data & (REG_CHG0_USB_ICHG_LOW|REG_CHG0_USB_ICHG_HIGH)) + { + case USB_ICHG_60mA: + sprintf(buf, "%s\n","60mA" ); + break; + case USB_ICHG_200mA: + sprintf(buf, "%s\n","200mA" ); + break; + case USB_ICHG_400mA: + sprintf(buf, "%s\n","400mA" ); + break; + case USB_ICHG_OFF: + sprintf(buf, "%s\n","OFF" ); + break; + } + } + else{ + sprintf(buf, "%s\n","OFF" ); + } + } + else if (strcmp(attr->name, "selectsource") == 0){ + + error = ST4102_Read(REG_CHG1,&data, 1); + if(data & REG_CHG1_SEL_IS){ + sprintf(buf, "%s\n","BATT" ); + } + else{ + sprintf(buf, "%s\n","EXT" ); + } + } + else if (strcmp(attr->name, "watchdogtime") == 0){ + + error = ST4102_Read(REG_WDOG,&data, 1); + + switch(data & (REG_WDOG_WDOG_TIME_LOW|REG_WDOG_WDOG_TIME_HIGH)) + { + case WATCHDOG_1MIN: + sprintf(buf, "%s\n","1min" ); + break; + case WATCHDOG_15MIN: + sprintf(buf, "%s\n","15min" ); + break; + case WATCHDOG_30MIN: + sprintf(buf, "%s\n","30min" ); + break; + case WATCHDOG_60MIN: + sprintf(buf, "%s\n","60min" ); + break; + } + } + else if (strcmp(attr->name, "adcresol") == 0){ + + error = ST4102_Read(REG_ADCTRL,&data, 1); + + if(data & REG_ADCTRL_ADRESOLUTION){ + sprintf(buf, "%s\n","12bit" ); + } + else{ + sprintf(buf, "%s\n","7bit" ); + } + } + else if (strcmp(attr->name, "getchargingstatus") == 0){ + + error = ST4102_Read(REG_CHG0,&data, 1); + + if(data & REG_CHG0_CHARGERUN){ + sprintf(buf, "%s\n","CHARGING" ); + } + else { + + sprintf(buf, "%s\n","DRAINING" ); + + if(data & (REG_CHG0_MAINDETECT | REG_CHG0_USBDETECT)) + { + error = ST4102_Read(REG_CHG1,&data, 1); + + if(data & REG_CHG1_CHG_ENA ) + + sprintf(buf, "%s\n","FULL" ); + + } + } + } + else if(strcmp(attr->name, "operatecharger") == 0) { + + error = ST4102_Read(REG_CHG1,&data, 1); + + if(data & REG_CHG1_CHG_ENA){ + sprintf(buf, "%s\n","ON" ); + } + else{ + sprintf(buf, "%s\n","OFF" ); + } + } + else if(strcmp(attr->name, "operatewatchdog") == 0) { + + error = ST4102_Read(REG_WDOG,&data, 1); + + if(data & REG_WDOG_WDOG_EN){ + sprintf(buf, "%s\n","ON" ); + } + else{ + sprintf(buf, "%s\n","OFF" ); + } + } + else if(strcmp(attr->name, "powersource") == 0) { + + sprintf(buf, "%s\n","UNAVAILABLE" ); + + error = ST4102_Read(REG_CHG0,&data, 1); + + if(data & REG_CHG0_USBDETECT){ + sprintf(buf, "%s\n","USB" ); + } + + if(data & REG_CHG0_MAINDETECT){ + sprintf(buf, "%s\n","MAIN" ); + } + } + return error ==0 ? strlen(buf): 0; +} + + +/** \ingroup SYS_IMPLEMENTATION + * Kobject store implementations + * Used to set/unset constraints from user space + */ +static ssize_t stcharg_store(struct kobject *kobj, struct attribute *attr, const char *buf, size_t count) +{ + char buffer[30]; + int error =0; + uint8 data = 0; + sscanf(buf, "%s", &buffer); + + if (strcmp(attr->name, "operatecharger") == 0){ + if(strcmp(buffer, "start") == 0){ + error = STw4102_enable(); + } + else if(strcmp(buffer, "stop") == 0){ + error = STw4102_disable(); + } + else + error =-EBADRQC; + + } + else if(strcmp(attr->name, "chargingvoltage") == 0){ + + error = ST4102_Read(REG_CHG0,&data, 1); + /* clear the current charging voltage*/ + data &= ~VCHG_4_35V; + + if(strcmp(buffer, "4.1v") == 0){ + data |= VCHG_4_10V; + } + else if(strcmp(buffer, "4.2v") == 0){ + data |= VCHG_4_20V; + } + else if(strcmp(buffer, "4.3v") == 0){ + data |= VCHG_4_30V; + } + else if(strcmp(buffer, "4.35v") == 0){ + data |= VCHG_4_35V; + } + else + error =-EBADRQC; + if(!error) + error = ST4102_Write(REG_CHG0,data); + } + else if(strcmp(attr->name, "usbchargingcurrent") == 0){ + + error = ST4102_Read(REG_CHG0,&data, 1); + + /* clear the current charging current*/ + data &= ~USB_ICHG_OFF; + + if(strcmp(buffer, "60mA") == 0){ + data |= USB_ICHG_60mA; + } + else if(strcmp(buffer, "200mA") == 0){ + data |= USB_ICHG_200mA; + } + else if(strcmp(buffer, "400mA") == 0){ + data |= USB_ICHG_400mA; + } + else if(strcmp(buffer, "OFF") == 0){ + data |= USB_ICHG_OFF; + } + else + error =-EBADRQC; + if(!error) + error = ST4102_Write(REG_CHG0,data); + } + else if(strcmp(attr->name, "selectsource") == 0){ + + error = ST4102_Read(REG_CHG1,&data, 1); + + if(strcmp(buffer, "BATT") == 0){ + data |= REG_CHG1_SEL_IS; + } + else if(strcmp(buffer, "EXT") == 0){ + data &= ~REG_CHG1_SEL_IS; + } + else + error =-EBADRQC; + if(!error) + error = ST4102_Write(REG_CHG1,data); + } + else if(strcmp(attr->name, "watchdogtime") == 0){ + + if(strcmp(buffer, "1min") == 0){ + data = WATCHDOG_1MIN; + } + else if(strcmp(buffer, "15min") == 0){ + data = WATCHDOG_15MIN; + } + else if(strcmp(buffer, "30min") == 0){ + data = WATCHDOG_30MIN; + } + else if(strcmp(buffer, "60min") == 0){ + data = WATCHDOG_60MIN; + } + else + error =-EBADRQC; + if(!error) + error = STw4102_setwatchdog(data,STATE_DISABLE); + } + else if(strcmp(attr->name, "operatewatchdog") == 0){ + + if(strcmp(buffer, "start") == 0){ + error = STw4102_setwatchdog(WATCHDOG_DISABLE,STATE_ENABLE); + } + else if(strcmp(buffer, "stop") == 0){ + error = STw4102_setwatchdog(WATCHDOG_DISABLE,STATE_DISABLE); + } + else + error =-EBADRQC; + } + else if(strcmp(attr->name, "calibrate") == 0){ + + if(strcmp(buffer, "ADC") == 0){ + error = ST4102_Read(REG_ADCTRL,&data, 1); + data |= REG_ADCTRL_ADCAL; + if(!error) + error = ST4102_Write(REG_ADCTRL,data); + /*TBD*/ + } + else if(strcmp(buffer, "GASGAUGE") == 0){ + error = ST4102_Read(REG_CG,&data, 1); + data |= REG_CG_CG_CAL; + if(!error) + error = ST4102_Write(REG_CG,data); + /*TBD*/ + } + else + error =-EBADRQC; + } + else if(strcmp(attr->name, "adcresol") == 0){ + + error = ST4102_Read(REG_ADCTRL,&data, 1); + + if(strcmp(buffer, "7bit") == 0){ + data &= ~REG_ADCTRL_ADRESOLUTION; + } + else if(strcmp(buffer, "12bit") == 0){ + data |= REG_ADCTRL_ADRESOLUTION; + } + else + error =-EBADRQC; + if(!error) + error = ST4102_Write(REG_ADCTRL,data); + } + return error == 0? count: error; +} + +static struct attribute operatecharger_attribute = {.name = "operatecharger", .mode = S_IRUGO | S_IWUGO }; +static struct attribute getcharge_attribute = {.name = "getcharge", .mode = S_IRUGO}; +static struct attribute getvoltage_attribute = {.name = "getvoltage", .mode = S_IRUGO}; +static struct attribute chargingvoltage_attribute = {.name = "chargingvoltage", .mode = S_IRUGO | S_IWUGO}; +static struct attribute usbchargingcurrent_attribute = {.name = "usbchargingcurrent", .mode = S_IRUGO | S_IWUGO}; +static struct attribute selsource_attribute = {.name = "selectsource", .mode = S_IRUGO | S_IWUGO}; +static struct attribute watchdogtime_attribute = {.name = "watchdogtime", .mode = S_IRUGO | S_IWUGO}; +static struct attribute operatewatchdog_attribute = {.name = "operatewatchdog", .mode = S_IRUGO | S_IWUGO }; +static struct attribute calibrate_attribute = {.name = "calibrate", .mode = S_IWUGO }; +static struct attribute adcresol_attribute = {.name = "adcresol", .mode = S_IRUGO | S_IWUGO }; +static struct attribute getchargingstatus_attribute = {.name = "getchargingstatus", .mode = S_IRUGO}; +static struct attribute powersource_attribute = {.name = "powersource", .mode = S_IRUGO}; + + +static struct attribute* stcharg[] = { + &operatecharger_attribute, + &getcharge_attribute, + &getvoltage_attribute, + &chargingvoltage_attribute, + &usbchargingcurrent_attribute, + &selsource_attribute, + &watchdogtime_attribute, + &operatewatchdog_attribute, + &calibrate_attribute, + &adcresol_attribute, + &getchargingstatus_attribute, + &powersource_attribute, + NULL +}; + +struct sysfs_ops stcharg_sysfs_ops = { + .show = stcharg_show, + .store = stcharg_store, +}; + +static struct kobj_type ktype_stcharg = { + .sysfs_ops = &stcharg_sysfs_ops, + .default_attrs = stcharg, +}; + +/////////////////////////////////////////////////////////////////////////////// +// This function read via I2C on the selected ST4102 device +// the first BYTE must be the internal register offset. +// +// Parameter +// offset = internal register offset +// buffer = pointer to data buffer +// nByte = number of byte to be read +/////////////////////////////////////////////////////////////////////////////// + + +static int ST4102_Read(uint8 offset,uint8 *buffer, uint8 NbBytes) +{ + int result = 0; + + result = nomadik_i2c_read_register(I2C_GAS_GAUGE_CLIENT,(__u8 *)buffer,offset, NbBytes); + + if (result < 0) + printk("<1>STw4102_Read Error %x, offset:%x\n", result, offset); + return result; + +} + +/////////////////////////////////////////////////////////////////////////////// +// This function write a single byte via I2C on the selected ST4201 +// +// Parameter +// offset = internal register offset +// DataValue = byte to be written +/////////////////////////////////////////////////////////////////////////////// + +static int ST4102_Write(uint8 offset, uint8 DataValue ) +{ + int result = 0; + uint8 data = DataValue; + + result = nomadik_i2c_write_register(I2C_GAS_GAUGE_CLIENT, (__u8 *)&data, offset, 1); + if (result < 0) + printk("<1>STw4102_Write Error %x, offset:%x, value:%x\n", result, offset, DataValue); + + return result; + +} + +static void timer_work_callback(struct work_struct *work) +{ + int i2c_error = 0; + uint8 data; + uint8 watchdog; + + printk("timer_work_callback==>\n"); + + do{ + + i2c_error = ST4102_Read(REG_WDOG, &watchdog,1); + + if(i2c_error) + break; + + /* reset watchdog */ + data = REG_WDOG_WDOG_RST | watchdog; + + i2c_error = ST4102_Write(REG_WDOG, data); + + if(i2c_error) + break; + + mdelay(200); + + data &= ~REG_WDOG_WDOG_RST; + + printk("timer_work_callback:%x\n",data); + + i2c_error = ST4102_Write(REG_WDOG, data); + + if(i2c_error) + break; + + /* watchdog elapsed already */ + if(watchdog & REG_WDOG_INT){ + + /* start watchdog and charging again */ + + i2c_error = ST4102_Read(REG_CHG1, &data,1); + + if(i2c_error) + break; + + data |= REG_CHG1_CHG_ENA; + + i2c_error = ST4102_Write(REG_CHG1, data); + + printk("timer_work_callback:timed out already\n"); + + break; + } + + i2c_error = ST4102_Read(REG_CHG1, &data,1); + + if((i2c_error== 0) && (data & REG_CHG1_CHG_ENA)){ + + + i2c_error = ST4102_Read(REG_CHG0, &data,1); + + if(i2c_error) + break; + + /* no power source avaliable */ + if(!(data & (REG_CHG0_MAINDETECT | REG_CHG0_USBDETECT)) || + !(data & REG_CHG0_CHARGERUN)){ + goto stop; + } + else + break; + } +stop: + printk("timer_work_callback:stopped timer\n"); + /* stop charging,stop watchdog and delete timer */ + i2c_error = ST4102_Read(REG_CHG1, &data,1); + + if(i2c_error) + break; + + data &= ~REG_CHG1_CHG_ENA; + + i2c_error = ST4102_Write(REG_CHG1, data); + + data = watchdog & ~REG_WDOG_WDOG_EN; + + data |= REG_WDOG_WDOG_RST; + + i2c_error = ST4102_Write(REG_WDOG, data); + + del_timer(¬ify_timer); + + return; + + }while(0); + + if(!i2c_error) + mod_timer(¬ify_timer, jiffies + msecs_to_jiffies(watchdog_timeout)); + printk("timer_work_callback:modified timer\n"); +} + +static void STw4102_status_change_monitor(unsigned long uContext) +{ + schedule_work(&workq); +} + + +/* + * Initialize the 4102 chip to the default + * value required for the platform. + * @param. + * @return. + * + */ +int STw4102_init(void) +{ + int i2c_error = 0; + uint8 data; + state enable; + + do + { + /* Clear reset */ + if(STw4102_reset(STATE_ENABLE)){ + i2c_error = -EREMOTEIO; + break; + } + + /* Clear Standby */ + if(STw4102_standby(STATE_ENABLE)){ + i2c_error = -EREMOTEIO; + break; + } + + /* set initial configuration*/ + + /* configure watchdog*/ + enable = (current_config.watchdog == STATE_ENABLE)?STATE_ENABLE:STATE_DISABLE; + + if(STw4102_setwatchdog(current_config.wdogtime,enable)){ + i2c_error = -EREMOTEIO; + break; + } + + STw4102_disable(); + + /* configure charging voltage & current*/ + data = (current_config.vchg | current_config.ichg | REG_CHG0_SEL_DC_USB); + + i2c_error = ST4102_Write(REG_CHG0, data); + + if(i2c_error){ + break; + } + + /* select internal power source */ + data = 0; + + if(current_config.source == SOURCE_BATT) + data = REG_CHG1_SEL_IS; + + i2c_error = ST4102_Write(REG_CHG1, data); + + if(i2c_error){ + break; + } + + /* configure the charger intial state*/ + if(current_config.charger) + i2c_error = STw4102_enable(); + + /* set adc resolution*/ + data = 0; + + if(current_config.adcres == RES_12BIT) + data = REG_ADCTRL_ADRESOLUTION; + + i2c_error = ST4102_Write(REG_ADCTRL, data); + + }while(0); + + return i2c_error; +} + +/* + * De-Initialize the 4102 chip before unloading + * the driver. + * @param. + * @return. + * + */ +int STw4102_deinit(void) +{ + int result=0; + + /* Disable Charging */ + STw4102_disable(); + + /* reset*/ + if(STw4102_reset(STATE_DISABLE)) + { + result=-EREMOTEIO; + } + + return result; + +} + +/* + * Disable the charger + * @param + * @return 0 on sucess else return error value return by ST4102 write + * + */ +int STw4102_disable(void) +{ + uint8 data; + int i2c_error = 0; + + i2c_error = ST4102_Read(REG_CHG1, &data, 1); + + if(i2c_error == 0) + { + + data &= ~REG_CHG1_CHG_ENA; //charger disabled + + i2c_error= ST4102_Write(REG_CHG1, data); + } + + if (i2c_error < 0 ) + printk("<1>STw4102_disable:Error ST4102_Write(REG_CHG0), : %d\n", i2c_error); + + return i2c_error; +} + +/* + * Enable the charger + * @param + * @return 0 on sucess else return error value return by ST4102 write + * + */ +int STw4102_enable(void) +{ + uint8 data; + int i2c_error = 0; + + i2c_error = ST4102_Read(REG_CHG1, &data, 1); + + if(i2c_error == 0) + { + + data |= REG_CHG1_CHG_ENA; //charger enabled + + i2c_error= ST4102_Write(REG_CHG1, data); + } + + if (i2c_error < 0 ) + printk("<1>STw4102_enable:Error ST4102_Write(REG_CHG0), : %d\n", i2c_error); + + return i2c_error; +} + +/* + * Enable the charger + * @param remCharge, will return the difference between icharge and idischarge + * @return 0 on sucess else return error value will be returned. + * + */ +int STw4102_getremainingcharge(uint32 *remCharge) +{ + int i2c_error = 0; + uint8 data; + uint8 count = 0; + uint32 iCharge; + uint32 iDischarge; + uint8 data_bytes[3]; + + do{ + /*reset all the accumulators*/ + data = REG_CG_RST_CHRG | REG_CG_RST_DCHRG | REG_CG_RST_COUNTER; + i2c_error = ST4102_Write(REG_CG, data); + + if(i2c_error){ + break; + } + /* transfer the data to registers*/ + data = REG_CG_RD_REQ; + i2c_error = ST4102_Write(REG_CG, data); + + if(i2c_error){ + break; + } + + mdelay(200); + /* wait for reset bits to get cleared*/ + do + { + mdelay(250); + /* break if we wait for more than 250 * 10 ms*/ + if(count++ > 10){ + i2c_error = -ETIME; + goto end; + } + + i2c_error = ST4102_Read(REG_CG, &data, 1); + if(i2c_error){ + goto end; + } + + }while(data & (REG_CG_RST_CHRG | REG_CG_RST_DCHRG | REG_CG_RST_COUNTER)); + + /* enable the gas gauge */ + data = REG_CG_CG_ENA; + i2c_error = ST4102_Write(REG_CG, data); + if(i2c_error){ + break; + } + /* wait for conversion to get over*/ + count = 0; + do{ + mdelay(250); + + if(count++ > 10){ + i2c_error = -ETIME; + goto end; + } + i2c_error = ST4102_Read(REG_CG, &data, 1); + if(i2c_error){ + goto end; + } + }while(!(data & REG_CG_CG_EOC)); + + /* transfer the data to registers*/ + data |= REG_CG_RD_REQ; + i2c_error = ST4102_Write(REG_CG, data); + + if(i2c_error){ + break; + } + count = 0; + /* wait for transfer to get over*/ + do{ + mdelay(250); + if(count++ > 10){ + i2c_error = -ETIME; + goto end; + } + i2c_error = ST4102_Read(REG_CG, &data, 1); + if(i2c_error){ + goto end; + } + }while(data & REG_CG_RD_REQ); + + /* read the charging current*/ + i2c_error = ST4102_Read(REG_CHARGE_LOW, data_bytes, 3); + if(i2c_error){ + break; + } + iCharge = ((uint32) data_bytes[2]) << 16; + iCharge= iCharge | (((uint32) data_bytes[1]) << 8); + iCharge= iCharge | data_bytes[0]; + + /* read the discharge current*/ + i2c_error = ST4102_Read(REG_DISCHARGE_LOW, data_bytes, 3); + if(i2c_error){ + break; + } + iDischarge = ((uint32) data_bytes[2]) << 16; + iDischarge= iDischarge | (((uint32) data_bytes[1]) << 8); + iDischarge= iDischarge | data_bytes[0]; + + *remCharge = iCharge-iDischarge; + + }while(0); +end: + /* disable the gas gauge*/ + data = 0; + ST4102_Write(REG_CG, data); + return i2c_error; + +} + +/* + * Current battery voltage + * @param battvolt, will return the current battery voltage. + * @return 0 on sucess else return error value will be returned. + * + */ +int STw4102_getbatteryvoltage(uint16 *battvolt) +{ + int i2c_error = 0; + uint8 data; + uint8 count = 0; + uint8 data_bytes[2]; + + do{ + i2c_error = ST4102_Read(REG_ADCTRL, &data, 1); + + if(i2c_error){ + break; + } + /* enable ADC*/ + data |= REG_ADCTRL_ADPOWERON; + i2c_error = ST4102_Write(REG_ADCTRL, data); + if(i2c_error){ + break; + } + /* wait for ADC to be ready*/ + do{ + mdelay(200); + if(count++ > 10) + { + i2c_error = -ETIME; + goto end; + } + i2c_error = ST4102_Read(REG_ADCTRL, &data, 1); + + if(i2c_error){ + goto end; + } + }while(!(data & REG_ADCTRL_ONSTATE)); + + /* start conversion*/ + data |= REG_ADCTRL_ADSTART; + i2c_error = ST4102_Write(REG_ADCTRL, data); + if(i2c_error){ + break; + } + + count = 0; + /* wait for ADC conversion to get over*/ + do{ + mdelay(250); + if(count++ > 10) + { + i2c_error = -ETIME; + goto end; + } + i2c_error = ST4102_Read(REG_ADCTRL, &data, 1); + + if(i2c_error){ + goto end; + } + }while(data & REG_ADCTRL_ADRUN); + + /* read battery voltage from ADC register*/ + i2c_error = ST4102_Read(REG_ADDATA_LOW, data_bytes, 2); + if(i2c_error){ + break; + } + + if(data & REG_ADCTRL_ADRESOLUTION){ + *battvolt = ((uint16) (data_bytes[1] & 0xF)) << 8; + *battvolt = *battvolt | data_bytes[0]; + } + else{ + *battvolt= (data_bytes[0] &0x7F); + } + }while(0); +end: + /*disable ADC*/ + data &= REG_ADCTRL_ADRESOLUTION; + ST4102_Write(REG_ADCTRL, data); + return i2c_error; +} + +/* This function set the watchdog value + * Value 0 : Disables Watchdog => Battery will start charging when power is plugged in + * Values : + * WATCHDOG_1MIN, + * WATCHDOG_15MIN, + * WATCHDOG_30MIN, + * WATCHDOG_60MIN : Battery will stop charging after xx min unless this function is called again + */ + +int STw4102_setwatchdog(t_STw4102_watchdog watchdog,state enable) +{ + int i2c_error =0; + uint8 data = 0; + t_STw4102_watchdog timeout; + + do{ + + i2c_error = ST4102_Read(REG_WDOG, &data,1); + + if(i2c_error != 0){ + break; + } + /* Reset the watchdog before doing anything*/ + data |= REG_WDOG_WDOG_RST; + + i2c_error = ST4102_Write(REG_WDOG, data); + + if(i2c_error != 0){ + break; + } + + /* Wait for reset to be effective */ + mdelay(100); + + /* after reset all the bit will be cleared + * it is required to restore the timeout values. + */ + data &= ~(REG_WDOG_WDOG_RST | REG_WDOG_WDOG_EN); + + i2c_error = ST4102_Write(REG_WDOG, data); + + if(i2c_error != 0){ + break; + } + + if(watchdog != WATCHDOG_DISABLE) + data = watchdog; + + if(enable){ + + data |= REG_WDOG_WDOG_EN; + + timeout = (t_STw4102_watchdog)data & (REG_WDOG_WDOG_TIME_LOW | REG_WDOG_WDOG_TIME_HIGH); + + switch(timeout) + { + case WATCHDOG_1MIN: + watchdog_timeout = 1000*40;// 40sec + break; + case WATCHDOG_15MIN: + watchdog_timeout = 1000*60*15 - 20;// 14.40min + break; + case WATCHDOG_30MIN: + watchdog_timeout = 1000*60*30 - 20;// 29.40min + break; + case WATCHDOG_60MIN: + watchdog_timeout = 1000*60*60 - 20;// 59.40min + } + notify_timer.expires = jiffies + msecs_to_jiffies(watchdog_timeout); + + printk("watchdog_timeout:%x\n",watchdog_timeout); + + del_timer(¬ify_timer); + mdelay(100); + add_timer(¬ify_timer); + } + else + { + data &= ~REG_WDOG_WDOG_EN; + del_timer(¬ify_timer); + printk("watchdog_timeout canceled:%x\n"); + } + + i2c_error = ST4102_Write(REG_WDOG, data); + + if(i2c_error != 0 ){ + break; + } + }while(0); + + return i2c_error; +} +/* + * Reset the ST 4102 controller depending on the state parameter. + * @param state, STATE_ENABLE will enable the chip. + * STATE_DISABLE will disable. + * @return 0 on sucess else return error value. + * + */ +int STw4102_reset(state enable) +{ + uint8 stmpeId=STMPE1; + uint8 PinIndex=EGPIO_PIN_19; + t_STMPE2401_error stmpe2401_error = 0; + + // Disable RESETn + do{ + + stmpe2401_error=STMPE2401_SetGpioAltFunction(stmpeId,PinIndex,STMPE2401_PRIMARY_FUNCTION ); + if(stmpe2401_error != STMPE2401_OK){ + printk("<1>Error in STMPE2401_SetGpioAltFunction:%x\n",stmpe2401_error); + break; + } + + stmpe2401_error=STMPE2401_SetGpioDir( stmpeId, PinIndex,STMPE2401_GPIO_OUT); + if(stmpe2401_error != STMPE2401_OK){ + printk("<1>Error in STMPE2401_SetGpioDir\n"); + break; + } + stmpe2401_error=STMPE2401_SetGpioVal(stmpeId,PinIndex,enable); + if(stmpe2401_error != STMPE2401_OK){ + printk("<1>Error in STMPE2401_SetGpioVal\n"); + break; + } + }while(0); + + return stmpe2401_error; +} + +int STw4102_standby(state enable) +{ + + uint8 stmpeId=STMPE1; + uint8 PinIndex=EGPIO_PIN_20; + t_STMPE2401_error stmpe2401_error = 0; + + do{ + // Disable STBYn + stmpe2401_error=STMPE2401_SetGpioAltFunction(stmpeId,PinIndex,STMPE2401_PRIMARY_FUNCTION ); + if(stmpe2401_error != STMPE2401_OK){ + printk("<1>Error in STMPE2401_SetGpioAltFunction(2)\n"); + break; + } + + stmpe2401_error=STMPE2401_SetGpioDir( stmpeId, PinIndex,STMPE2401_GPIO_OUT); + if(stmpe2401_error != STMPE2401_OK){ + printk("<1>Error in STMPE2401_SetGpioDir(2)\n"); + break; + } + + stmpe2401_error=STMPE2401_SetGpioVal(stmpeId,PinIndex,enable); + if(stmpe2401_error != STMPE2401_OK){ + printk("<1>Error in STMPE2401_SetGpioVal(2)\r\n"); + break; + } + }while(0); + + return stmpe2401_error; +} + +/* + * Initialize the driver and register the driver with kernel. + * @param + * @return 0 on sucess else return error value. + * + */ +int nomadik_stcharg_init(void) { + + int i2c_error = 0; + + do{ + + /* Registering device */ + stcharg_kobj = kzalloc(sizeof(struct kobject), GFP_KERNEL); + + if(stcharg_kobj == NULL){ + i2c_error = -ENOMEM; + break; + } + + kobject_init(stcharg_kobj); + + stcharg_kobj->ktype = &ktype_stcharg; + + i2c_error = kobject_set_name(stcharg_kobj, "stcharg"); + + if(i2c_error){ + kfree(stcharg_kobj); + break; + } + + i2c_error = kobject_add(stcharg_kobj); + + if(i2c_error){ + kfree(stcharg_kobj); + break; + } + + printk("Done with sysfs registering\n"); + + init_timer(¬ify_timer); + notify_timer.expires = jiffies + msecs_to_jiffies(100); + notify_timer.function = STw4102_status_change_monitor; + notify_timer.data = NULL; + + INIT_WORK(&workq, timer_work_callback); + + /* Initializes the STw4102 controller */ + if(STw4102_init()){ + i2c_error = -ENODEV; + break; + } + return 0; + + }while(0); + + nomadik_stcharg_exit(); + + return i2c_error; +} + +/* + * Deinitializes the driver. + * @param. + * @return. + * + */ +void nomadik_stcharg_exit(void) { + + del_timer(¬ify_timer); + kobject_del(stcharg_kobj); + kobject_put(stcharg_kobj); + kfree(stcharg_kobj); + + STw4102_deinit(); + + printk("<1>Removing stcharg module\n"); +} + +/* Declaration of the init and exit functions */ + +module_init(nomadik_stcharg_init); +module_exit(nomadik_stcharg_exit); + --- /dev/null +++ linux-2.6.20/drivers/misc/etm-nomadik.c @@ -0,0 +1,207 @@ +/* + * Overview: + * Driver for ETM on Nomadik nhk15 Platforms + * + * Copyright (C) 2008 STMicroelectronics Pvt. Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#define ETM_MINOR 23 + +/*file operation members*/ +static int nomadik_etm_ioctl(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg); +static int nomadik_etm_open(struct inode *inode, struct file *filp); +static int nomadik_etm_release(struct inode *inode, struct file *filp); + + +static int nomadik_etm_ioctl(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg) +{ +#if 0 + int err = 0; + int rval = 0; + unsigned char byte_val; + + if (_IOC_DIR(cmd) & _IOC_READ) + err = !access_ok(VERIFY_WRITE, (void *)arg, _IOC_SIZE(cmd)); + else if (_IOC_DIR(cmd) & _IOC_WRITE) + err = !access_ok(VERIFY_READ, (void *)arg, _IOC_SIZE(cmd)); + if (err) + return -EFAULT; + + switch (cmd) { + + case ETM_ENABLE: + { + int __user *argp = (struct contrast __user *)arg; + /*if (copy_from_user(&ctr ,argp, sizeof(struct contrast))) + return -EFAULT; + + }*/ + + break; + case ETM_DISABLE: + { + int __user *argp = (struct bright __user *)arg; + /*if (copy_from_user(&bright ,argp, sizeof(struct bright))) + return -EFAULT; + }*/ + break; + default: + return -EINVAL; + } +#endif + return 0; +} +/** + * nomadik_etm_open - open sys call for etm device + * @inode: pointer to the inode structure for the etm device + * @filp: pointer to the file structure for the etm device + * + * This function opens the etm device for file operations. + */ +static int nomadik_etm_open(struct inode *inode, struct file *filp) +{ + return (0); +} + +/** + * nomadik_etm_release - close sys call for etm device + * @inode: pointer to the inode structure for the etm device + * @filp: pointer to the file structure for the etm device + * + * This function is called when the etm device is closed. + */ +static int nomadik_etm_release(struct inode *inode, struct file *filp) +{ + return (0); +} + +/** + * struct file_operations etm_fops - user space file operations + * + * Define (fill in) the user space file operations for this driver + * and initialize the etm driver as a "miscdevice": + * Character device + * Major(10) --- Non-serial mice, misc features + * Minor(23) --- /dev/etm + */ +static struct file_operations etm_fops = { + owner:THIS_MODULE, + ioctl:nomadik_etm_ioctl, + open:nomadik_etm_open, + release:nomadik_etm_release, +}; + +static struct miscdevice etm_dev = { + minor:ETM_MINOR, + name:"etm", + fops:&etm_fops, +}; + +static int __init etm_nomadik_init(void) +{ + int ret=0; + gpio_error gpio_err=0; + + printk("initializing ETM interface..\n"); + /*make sure CCIR interface is disabled*/ + + gpio_err = nomadik_gpio_altfuncdisable(GPIO_ALT_CCIR656_INPUT,"ccirip"); + if(gpio_err != GPIO_OK) { + printk("Failed to disable GPIO altf A for CCIR i/p interface \n"); +// return -1; + } + gpio_err = nomadik_gpio_altfuncdisable(GPIO_ALT_CCIR656_OUTPUT,"ccirop"); + if(gpio_err != GPIO_OK) { + printk("Failed to disable GPIO altf A for CCIR o/p interface \n"); +// return -1; + } + + /*disable the camera-I2C1 interace*/ + gpio_err = nomadik_gpio_altfuncdisable(GPIO_ALT_I2C_1,"I2C_1"); + if(gpio_err != GPIO_OK) { + printk("Failed to disable GPIO altf for I2C_1 interface \n"); +// return -1; + } + + /*enable the ALT functions for ETM*/ + ret = nomadik_gpio_altfuncenable(GPIO_ALT_ETM, "etm"); + if(ret) { + printk("Alt func enable for ETM failed\n"); +// return -1; + } + + /*enalbe the EGPIO*/ +/* ret = STMPE2401_SetGpioAltFunction(STMPE1 ,EGPIO_PIN_1, STMPE2401_PRIMARY_FUNCTION ); + if (ret != STMPE2401_OK) + printk("Couldn't set STMPE1 %d as STMPE2401_PRIMARY_FUNCTION \n",EGPIO_PIN_1); + ret = STMPE2401_SetGpioDir(STMPE1,EGPIO_PIN_1,STMPE2401_GPIO_OUT); + if (ret != STMPE2401_OK) + printk("Couldn't set STMPE1 %d as GPIO direction \n",EGPIO_PIN_1); + ret = STMPE2401_SetGpioVal(STMPE1,EGPIO_PIN_1,1); + if(ret != STMPE2401_OK ) + printk( " writing STMPE0 EGPIO_PIN_1 FAIL\n"); +*/ + ret = misc_register(&etm_dev); + if (ret) { + printk("%s: could not register etm erro =%d", __FILE__, + ret); + return ret; + } + printk("loaded ETM driver...\n"); + return 0; +} + +module_init(etm_nomadik_init); +static void __exit etm_nomadik_exit(void) +{ + gpio_error gpio_err=0; +/* gpio_err = nomadik_gpio_altfuncdisable(GPIO_ALT_ETM, "etm"); + if(gpio_err != GPIO_OK) { + printk("Failed to disable the altf A for ETM\n"); + } +*/ + misc_deregister(&etm_dev); + return; +} + +module_exit(etm_nomadik_exit); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("ST Microelectronics"); +MODULE_DESCRIPTION("ETM module for Nomadik (nhk15) Platform"); --- /dev/null +++ linux-2.6.20/drivers/misc/pexp-nomadik.c @@ -0,0 +1,2847 @@ +/* + * Overview: + * Driver for STMPE2401 on Nomadik Platforms + * + * Copyright (C) 2007 STMicroelectronics Pvt. Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#define DEBUG 0 + + +/* + Internal macros +*/ +#define LONG_TO_MSB(par) ((par >> 16) & 0xFF) +#define LONG_TO_CSB(par) ((par >> 8) & 0xFF) +#define LONG_TO_LSB(par) (par & 0xFF) + +#define GPIO_BASE 0x101E6000 +#define GPIO_SLPM_REG (GPIO_BASE + 0x01C) +#define GPIO_FALLINGEDGE_WAKEUP (GPIO_BASE + 0x054) +#define GPIO_RAISINGEDGE_WAKEUP (GPIO_BASE + 0x050) + +/* + Internal defines +*/ + +#define STMPE2401_WAIT_RESET_TIMEOUT 100 +#define STMPE2401_I2C_TIMEOUT 1000 + +/*STMP interrupt numbers*/ +#define STMP0_INTR GPIO_PIN_76 +#define STMP1_INTR GPIO_PIN_78 + + +/*pwm istruction mask*/ + +#define SMIN_ISTRUCTION 0x00FF +#define SMAX_ISTRUCTION 0x007F +#define RAMP_UP_SLOW 0x7F01 +#define RAMP_DN_SLOW 0x7F81 +#define RAMP_UP(step) step +#define RAMP_DN(step) (step | 0x0080) +#define BRANCH_TO(add) (add | 0xA000) +#define GTS_ISTRUCTION 0x0000 + +/*Register definition*/ + +/*System registers Index*/ +#define CHIP_ID_Index 0x80 +#define VERSION_ID_Index 0x81 +#define SYSCON_Index 0x02 + +#define GPIO_OFFSET + +/*Interrupt registers Index*/ +#define ICR_Msb_Index 0x10 /*Interrupt Control register*/ +#define ICR_Lsb_Index 0x11 +#define IER_Msb_Index 0x12 /*Interrupt Enable Mask register*/ +#define IER_Lsb_Index 0x13 +#define ISR_Msb_Index 0x14 /*Interrupt Status register*/ +#define ISR_Lsb_Index 0x15 +#define IEGPIOR_Msb_Index 0x16 /*Interrupt Enable GPIO Mask register*/ +#define IEGPIOR_Csb_Index 0x17 /*Interrupt Enable GPIO Mask register*/ +#define IEGPIOR_Lsb_Index 0x18 +#define ISGPIOR_Msb_Index 0x19 /*Interrupt Status GPIO registers*/ +#define ISGPIOR_Csb_Index 0x1A +#define ISGPIOR_Lsb_Index 0x1B + +/*Pwm register index*/ +#define PWMCS_Index 0x30 /*Pwm control and status register*/ +#define PWMIC0_Index 0x38 /*Pwm*/ +#define PWMIC1_Index 0x39 +#define PWMIC2_Index 0x3A + + +/*Keypad Controller Registers*/ +#define KPC_COL_Index 0x60 /*Keypad column register I2C index*/ +#define KPC_ROW_Msb_Index 0x61 +#define KPC_ROW_Lsb_Index 0x62 +#define KPC_CTRL_Msb_Index 0x63 +#define KPC_CTRL_Lsb_Index 0x64 +#define KPC_DATA_BYTE0_Index 0x68 +#define KPC_DATA_BYTE1_Index 0x69 +#define KPC_DATA_BYTE2_Index 0x6a + +/*Gpio's defines*/ +/*GPIO Monitor Pin register Index*/ +#define GPMR_Msb_Index 0xA2 +#define GPMR_Csb_Index 0xA3 +#define GPMR_Lsb_Index 0xA4 +/*GPIO Set Pin State register Index*/ +#define GPSR_Msb_Index 0x83 +#define GPSR_Csb_Index 0x84 +#define GPSR_Lsb_Index 0x85 +/*GPIO Clear Pin State register Index*/ +#define GPCR_Msb_Index 0x86 +#define GPCR_Csb_Index 0x87 +#define GPCR_Lsb_Index 0x88 +/*GPIO Set Pin Direction register*/ +#define GPDR_Msb_Index 0x89 +#define GPDR_Csb_Index 0x8A +#define GPDR_Lsb_Index 0x8B +/*GPIO Edge Detect Status register*/ +#define GPEDR_Msb_Index 0x8C +#define GPEDR_Csb_Index 0x8D +#define GPEDR_Lsb_Index 0x8E +/*GPIO Rising Edge register*/ +#define GPRER_Msb_Index 0x8F +#define GPRER_Csb_Index 0x90 +#define GPRER_Lsb_Index 0x91 +/*GPIO Falling Edge register*/ +#define GPFER_Msb_Index 0x92 +#define GPFER_Csb_Index 0x93 +#define GPFER_Lsb_Index 0x94 +/*GPIO Pull Up register*/ +#define GPPUR_Msb_Index 0x95 +#define GPPUR_Csb_Index 0x96 +#define GPPUR_Lsb_Index 0x97 +/*GPIO Pull Down register*/ +#define GPPDR_Msb_Index 0x98 +#define GPPDR_Csb_Index 0x99 +#define GPPDR_Lsb_Index 0x9A + +/*GPIO Alternate Function register*/ +#define GPAFR_U_Msb_Index 0x9b /*Gpio alternate function register*/ +#define GPAFR_U_Csb_Index 0x9c +#define GPAFR_U_Lsb_Index 0x9d + +#define GPAFR_L_Msb_Index 0x9e +#define GPAFR_L_Csb_Index 0x9f +#define GPAFR_L_Lsb_Index 0xA0 + +/* + Internal functions +*/ + +/*file operation members*/ +static int nomadik_stmpe_ioctl(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg); +static int nomadik_stmpe_open(struct inode *inode, struct file *filp); +static int nomadik_stmpe_release(struct inode *inode, struct file *filp); + +/*Gpio functions*/ +static t_STMPE2401_error STMPE2401_Gpio_Parameter_Check(uint8 stmpeId, uint8 PinIndex); +static t_STMPE2401_error STMPE2401_Bit_Calc( uint8 PinIndex, uint8 PinValue,uint8 *Register, uint32 *RegValue, uint8 *RegByte); +/*I2C functions*/ +static t_STMPE2401_error STMPE2401_Write(uint8 stmpeId,uint8 *buffer, uint8 nByte ); +static t_STMPE2401_error STMPE2401_WriteByte(uint8 stmpeId,uint8 offset, uint8 DataValue ); +static t_STMPE2401_error STMPE2401_Read(uint8 stmpeId,uint8 offset,uint8 *buffer, uint8 nByte ); + +/*fix for soft reboot*/ +t_STMPE2401_error STMPE2401_reboot(void); + +static void EmptyCallback(void *parameter); /*dummy function*/ + +/* + Internal constant +*/ +uint8 const DEVICE_MASK[MAX_STMPE2401_DEVICE] = {0x01,0x02,0x04,0x08}; + +/*Internal variables*/ +uint8 DeviceInitializationCheck = 0; +t_STMPE2401_device_config Devices[MAX_STMPE2401_DEVICE]; +uint32 CallbackInstallationCheck[MAX_STMPE2401_DEVICE] = {0,0,0,0}; +uint32 InterruptActive[MAX_STMPE2401_DEVICE] = {0,0,0,0}; +uint16 InterruptRuntimeErrors[MAX_STMPE2401_DEVICE] = {0,0,0,0}; +uint8 PwmInitializationCheck[MAX_STMPE2401_DEVICE] = {0,0,0,0}; + +/*work queues*/ +static void nomadik_stmpe0_wq(void * data); +static void nomadik_stmpe1_wq(void * data); + +static DECLARE_WORK(work0,nomadik_stmpe0_wq); +static DECLARE_WORK(work1,nomadik_stmpe1_wq); + +/** + * int nomadik_stmpe_ioctl - provides a mechanism for passing control + * @inode: pointer to the inode structure for the stmpedevice + * @filp: pointer to the file structure for the stmpe device + * @cmd: user cmd to the driver + * @arg: pointer for data transfer between the driver and application + * + * This function provides a mechanism for passing control and status + * nmdk_information between the application and driver. + * RETURN: Zero or negative nmdk_error code + */ +static int nomadik_stmpe_ioctl(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg) +{ + int err = 0; + int bklight = 0; + int __user *argp = (int __user *)arg; + + if (_IOC_DIR(cmd) & _IOC_READ) + err = !access_ok(VERIFY_WRITE, (void *)arg, _IOC_SIZE(cmd)); + else if (_IOC_DIR(cmd) & _IOC_WRITE) + err = !access_ok(VERIFY_READ, (void *)arg, _IOC_SIZE(cmd)); + if (err) + return -EFAULT; + + switch (cmd) { + + case STMPE_SET_BACKLIGHT: + copy_from_user(&bklight ,argp, sizeof(int)); + if (bklight < 0 || bklight > 255 ) { + printk("Wrong range of backlight [should be 0(0v) - 255(1.8v)] \n"); + return -EINVAL; + } + err = STMPE2401_SetPwm(STMPE0, STMPE2401_PWM1, bklight); + if(err != STMPE2401_OK) + { + printk("Error in Setting PWM controller of STMPE%d device\n",STMPE0); + return err; + } + break; + default: + return -EINVAL; + } + return 0; +} +/** + * nomadik_stmpe_open - open sys call for stmpe device + * @inode: pointer to the inode structure for the stmpe device + * @filp: pointer to the file structure for the stmpe device + * + * This function opens the stmpe device for file operations. + */ +static int nomadik_stmpe_open(struct inode *inode, struct file *filp) +{ + return (0); +} + +/** + * nomadik_stmpe_release - close sys call for stmpe device + * @inode: pointer to the inode structure for the stmpe device + * @filp: pointer to the file structure for the stmpe device + * + * This function is called when the stmpe device is closed. + */ +static int nomadik_stmpe_release(struct inode *inode, struct file *filp) +{ + return (0); +} + +/** + * struct file_operations stmpe_fops - user space file operations + * + * Define (fill in) the user space file operations for this driver + * and initialize the stmpe driver as a "miscdevice": + * Character device + * Major(10) --- Non-serial mice, misc features + * Minor(20) --- /dev/stmpe + */ +static struct file_operations stmpe_fops = { + owner:THIS_MODULE, + ioctl:nomadik_stmpe_ioctl, + open:nomadik_stmpe_open, + release:nomadik_stmpe_release, +}; + +static struct miscdevice stmpe_dev = { + minor:STMPE_MINOR, + name:"stmpe", + fops:&stmpe_fops, +}; + +/* + Platform dependant initialization function. This routine configure the + STMPE2401 and this utils for NHK15 board +*/ +static int nomadik_stmpe_probe(struct platform_device *pdev) +{ + struct nomadik_stmpe_platform_data *pdata = pdev->dev.platform_data; + int ret; + t_STMPE2401_error retval = STMPE2401_OK; + t_STMPE2401_gpio_config PinConfigSTMPE; + gpio_config PinConfig,rst_pin; + /*t_STMPE2401_key_config KeyConfig;*/ + + if(!pdata->init) { + printk("STMPE ::: platform init() function is not present\n"); + return -1; + } + /*issue hard reset to the STMPE devices*/ + rst_pin.mode = GPIO_MODE_SOFTWARE; + rst_pin.direction = GPIO_DIR_OUTPUT; + rst_pin.trig = GPIO_TRIG_DISABLE; + rst_pin.debounce = GPIO_DEBOUNCE_DISABLE; + rst_pin.dev_name = "stmpe"; + + ret = nomadik_gpio_setpinconfig(GPIO_PIN_77, &rst_pin); + if (ret) { + printk("Error in setting GPIO_PIN_77"); + } + ret = nomadik_gpio_writepin(GPIO_PIN_77, GPIO_DATA_HIGH,rst_pin.dev_name); + if (ret) { + printk("Error in setting GPIO_PIN_77 value to LOW"); + } + ret = nomadik_gpio_setpinconfig(GPIO_PIN_79, &rst_pin); + if (ret) { + printk("Error in setting GPIO_PIN_79"); + } + ret = nomadik_gpio_writepin(GPIO_PIN_79, GPIO_DATA_HIGH,rst_pin.dev_name ); + if (ret) { + printk("Error in setting GPIO_PIN_79 value to LOW"); + } + /*probe the STMPE device*/ + retval = STMPE2401_Init(STMPE0); //, I2C0,0x86 ); + if(retval != STMPE2401_OK) + { + printk("STMPE2401: Error in initializing STMPE0 device\n"); + return retval; + }else + printk("STMPE2401 Device %d Initialized\n",STMPE0); + + //retval = STMPE2401_Init(STMPE1, I2C0,0x88 ); + retval = STMPE2401_Init(STMPE1); //, I2C0,0x88 ); + if(retval != STMPE2401_OK) + { + printk("STMPE2401: Error in initializing STMPE1 device\n"); + return retval; + }else + printk("STMPE2401 Device %d Initialized\n",STMPE1); + + PinConfigSTMPE.Output_State = 0x000030; /*0x000020; 0000 0000 0000 0000 0010 0000 */ + PinConfigSTMPE.Direction = 0x351F30; /*0011 0101 0001 1111 0011 0000*/ + PinConfigSTMPE.EdgeDetect = 0; + PinConfigSTMPE.RisingEdge = 0; + PinConfigSTMPE.FallingEdge = 0; + PinConfigSTMPE.PullUp = 0; + PinConfigSTMPE.PullDown = 0; + PinConfigSTMPE.AltFunctionUpper = 0; + PinConfigSTMPE.AltFunctionLower = 0; + + + retval = STMPE2401_Gpio_Configuration( STMPE0, &PinConfigSTMPE); + if(retval != STMPE2401_OK) + { + printk("STMPE2401[0]: Error in GPIO configuration\n"); + return retval; + } + + PinConfigSTMPE.Output_State = 0x08050B; /*0x08040B;//0000 1000 0000 0100 0000 1011*/ + PinConfigSTMPE.Direction = 0x18072F; /*0001 1000 0000 0111 0010 1111*/ + PinConfigSTMPE.EdgeDetect = 0; + PinConfigSTMPE.RisingEdge = 0; + PinConfigSTMPE.FallingEdge = 0; + PinConfigSTMPE.PullUp = 0; + PinConfigSTMPE.PullDown = 0; + PinConfigSTMPE.AltFunctionUpper = 0; + PinConfigSTMPE.AltFunctionLower = 0; + + retval = STMPE2401_Gpio_Configuration( STMPE1, &PinConfigSTMPE); + if(retval != STMPE2401_OK) + { + printk("STMPE2401[1]: Error in GPIO configuration\n"); + return retval; + } + + PinConfig.mode = GPIO_MODE_SOFTWARE; + PinConfig.direction = GPIO_DIR_INPUT; + PinConfig.trig = GPIO_TRIG_FALLING_EDGE; + PinConfig.debounce = GPIO_DEBOUNCE_UNCHANGED; + + /*init PWM*/ + retval = STMPE2401_PwmInit(STMPE0, STMPE2401_PWM1); + if(retval != STMPE2401_OK) + { + printk("Error in Initializing PWM controller of STMPE%d device\n",STMPE0); + return retval; + } + /*Set the WVGA backlight to the maximum upon system boot*/ + retval = STMPE2401_SetPwm(STMPE0, STMPE2401_PWM1, 255); + if(retval != STMPE2401_OK) + { + printk("Error in Setting PWM controller of STMPE%d device\n",STMPE0); + return retval; + } + retval = STMPE2401_Interrupt_Init(STMPE0, STMP0_INTR, PinConfig); + if(retval != STMPE2401_OK) + { + return retval; + } + retval = STMPE2401_Interrupt_Init(STMPE1, STMP1_INTR, PinConfig); + if(retval != STMPE2401_OK) + { + return retval; + } + /*enable periferal functions*/ + retval = STMPE2401_WriteByte( STMPE0, SYSCON_Index, 0x0E ); + if(retval == STMPE2401_OK) + { + Devices[STMPE0].Syscon = 0x0E; + } else + printk("Error in enabling STMPE0 device...\n"); + + /*FIXME - This must happen earlier, but we need STMPE to + * to get initialized to do this + */ + if(pdata->init()){ + printk("Platform Initialization of NHK15 failed\n"); + return -EIO; + } + + /*register the device as misc device*/ + ret = misc_register(&stmpe_dev); + if (ret) { + printk("%s: could not register stmpe erro =%d", __FILE__, + ret); + return ret; + } + + /*storing the reset configuration value for both + * STMP0 and STMP1 when the system enters into deepsleep*/ + nomadik_gpio_slpmreg_config(GPIO_PIN_77); + nomadik_gpio_slpmreg_config(GPIO_PIN_79); + + return retval; +} + +/* +*Configuration of a single STMPE2401 device. Can be configured for up to 4 devices. +*Parameter +*stmpeId = index of the device (0-3) +*i2cnum = index of Nomadik i2c controller +*i2c_address = STMPE2401 i2c adress +*/ +t_STMPE2401_error STMPE2401_Init(uint8 stmpeId) +{ + t_STMPE2401_error retval = STMPE2401_OK; + t_STMPE2401_info tempInfo; + uint32 maxWait; + + if(stmpeId >= MAX_STMPE2401_DEVICE) + { + /*number of device exeded*/ + retval = STMPE2401_BAD_PARAMETER; + } + else + { + /*Set the device as initialized*/ + DeviceInitializationCheck |= DEVICE_MASK[stmpeId]; + } + + /*all function disabled*/ + Devices[stmpeId].Syscon = 0; + + /*soft reset*/ + retval = STMPE2401_WriteByte( stmpeId, SYSCON_Index, 0x80 ); + if(retval != STMPE2401_OK) + { + printk("Couldn't reset the STMPE device\n"); + return retval; + } + + /*wait for device restart*/ + maxWait = STMPE2401_WAIT_RESET_TIMEOUT; + while(maxWait > 0) + { + if(STMPE2401_Info( stmpeId, &tempInfo ) == STMPE2401_OK) + { + break; + } + maxWait--; + } + return retval; +} +/* +*This function read STMPE2401 chip and version ID +* +* Parameter +* stmpeId = index of the device (0-3) +* info = device info +*/ +t_STMPE2401_error STMPE2401_Info(uint8 stmpeId, t_STMPE2401_info *info ) +{ + t_STMPE2401_error retval = STMPE2401_OK; + + retval = STMPE2401_Gpio_Parameter_Check(stmpeId, (uint8)NULL ); + if(retval != STMPE2401_OK) + { + return retval; + } + retval = STMPE2401_Read( stmpeId,CHIP_ID_Index, &info->chip_ID, 1 ); + if(retval == STMPE2401_OK) + { + retval = STMPE2401_Read( stmpeId,VERSION_ID_Index, &info->version_ID, 1 ); + } + return retval; +} + +/* +* This function configure the STMPE2401 gpio +* Parameter +* stmpeId = index of the device (0-3) +* config = configuration structure +*/ +t_STMPE2401_error STMPE2401_Gpio_Configuration(uint8 stmpeId, t_STMPE2401_gpio_config* config) +{ + t_STMPE2401_error retval = STMPE2401_OK; + uint8 tempBuffer[35]; /*"GPSR_Msb_Index" to "GPAFR_L_Lsb_Index" + 5 spare*/ + uint32 tempLong; + uint32 nByte; + uint8 tempByte; + + retval = STMPE2401_Gpio_Parameter_Check(stmpeId,(uint8)NULL ); + if(retval != STMPE2401_OK) + { + return retval; + } + Devices[stmpeId].Gpio = *config; + + /*fill the temp buffer in the same order of STMPE internal register + "GPSR_Msb_Index" is the first, "GPAFR_L_Lsb_Index" the last + */ + + /*Output_State + based on and + */ + tempLong = config->Output_State; + /*tempLong &= Direction;*/ /*remove input pin [..TBD..]*/ + + /*I2C slave internal address*/ + tempBuffer[0] = GPSR_Msb_Index; + + tempBuffer[1] = LONG_TO_MSB(tempLong); + tempBuffer[2] = LONG_TO_CSB(tempLong); + tempBuffer[3] = LONG_TO_LSB(tempLong); + + tempLong = ~config->Output_State; + + tempBuffer[4] = LONG_TO_MSB(tempLong); + tempBuffer[5] = LONG_TO_CSB(tempLong); + tempBuffer[6] = LONG_TO_LSB(tempLong); + + /*Direction configuration*/ + tempBuffer[7] = LONG_TO_MSB(config->Direction); + tempBuffer[8] = LONG_TO_CSB(config->Direction); + tempBuffer[9] = LONG_TO_LSB(config->Direction); + + /*Edge Detect Status register*/ + tempBuffer[10] = LONG_TO_MSB(config->EdgeDetect); + tempBuffer[11] = LONG_TO_CSB(config->EdgeDetect); + tempBuffer[12] = LONG_TO_LSB(config->EdgeDetect); + + /*Rising Edge register*/ + tempBuffer[13] = LONG_TO_MSB(config->RisingEdge); + tempBuffer[14] = LONG_TO_CSB(config->RisingEdge); + tempBuffer[15] = LONG_TO_LSB(config->RisingEdge); + + /*Falling Edge register*/ + tempBuffer[16] = LONG_TO_MSB(config->FallingEdge); + tempBuffer[17] = LONG_TO_CSB(config->FallingEdge); + tempBuffer[18] = LONG_TO_LSB(config->FallingEdge); + + /*Pull Up register*/ + tempBuffer[19] = LONG_TO_MSB(config->PullUp); + tempBuffer[20] = LONG_TO_CSB(config->PullUp); + tempBuffer[21] = LONG_TO_LSB(config->PullUp); + + /*Pull Down register*/ + tempBuffer[22] = LONG_TO_MSB(config->PullDown); + tempBuffer[23] = LONG_TO_CSB(config->PullDown); + tempBuffer[24] = LONG_TO_LSB(config->PullDown); + + /*Alternate Function registers*/ + tempBuffer[25] = LONG_TO_MSB(config->AltFunctionUpper); + tempBuffer[26] = LONG_TO_CSB(config->AltFunctionUpper); + tempBuffer[27] = LONG_TO_LSB(config->AltFunctionUpper); + + tempBuffer[28] = LONG_TO_MSB(config->AltFunctionLower); + tempBuffer[29] = LONG_TO_CSB(config->AltFunctionLower); + tempBuffer[30] = LONG_TO_LSB(config->AltFunctionLower); + + nByte = 31; +/* + retval = STMPE2401_Write(stmpeId, tempBuffer, nByte ); +*/ + for(tempByte=1; tempByte<31; tempByte++) + { + retval = STMPE2401_WriteByte( stmpeId, (GPSR_Msb_Index + tempByte) - 1, tempBuffer[tempByte] ); + if(retval != STMPE2401_OK) + { + return retval; + } + } + return retval; +} + + +/* +*This function read STMPE2401 gpio configuration and save it on *config +* Parameter +* stmpeId = index of the device (0-3) +* config = configuration structure +*/ +t_STMPE2401_error STMPE2401_Get_Gpio_Configuration(uint8 stmpeId, t_STMPE2401_gpio_config* config) +{ + t_STMPE2401_error retval = STMPE2401_OK; + + retval = STMPE2401_Gpio_Parameter_Check(stmpeId, (uint8)NULL ); + if(retval != STMPE2401_OK) + { + return retval; + } + /*read back configuration - FIXME TODO - currently not used + memcpy(config, &Devices[stmpeId].Gpio, sizeof(t_STMPE2401_gpio_config));*/ + return retval; +} + +/* +* This function set STMPE2401 gpio value (output) +* Parameter +* stmpeId = index of the device (0-3) +* PinIndex = pin to be set (0-23) +* Value = 1 High, 0 Low +*/ +t_STMPE2401_error STMPE2401_SetGpioVal(uint8 stmpeId, uint8 PinIndex, uint8 Value) +{ + + t_STMPE2401_error retval = STMPE2401_OK; + uint8 offset, DataValue; + + retval = STMPE2401_Gpio_Parameter_Check(stmpeId, PinIndex ); + if(retval != STMPE2401_OK) + { + return retval; + } + /*register selection*/ + if(Value == 0) + { + offset = GPCR_Msb_Index; + /*save configuration */ + Devices[stmpeId].Gpio.Output_State &=~ ((uint32)1 << PinIndex); + } + else if(Value == 1) + { + offset = GPSR_Msb_Index; + /*save configuration */ + Devices[stmpeId].Gpio.Output_State |= ((uint32)1 << PinIndex); + } + else + { + /*invalid value*/ + retval = STMPE2401_BAD_PARAMETER; + return retval; + } + + if(PinIndex < 8) + { + /*XXX_Lsb_Index*/ + offset += 2; + DataValue = 1 << PinIndex; + } + else if(PinIndex < 16) + { + /*XXX_Csb_Index*/ + offset ++; + DataValue = 1 << (PinIndex-8); + } + else + { + /*XXX_Msb_Index*/ + DataValue = 1 << (PinIndex-16); + } + retval = STMPE2401_WriteByte(stmpeId, offset, DataValue ); + return retval; +} + +/* +*This function read STMPE2401 gpio value (input) +* +* Parameter +* stmpeId = index of the device (0-3) +* PinIndex = pin to be set (0-23) +* Value = 1 High, 0 Low +*/ +t_STMPE2401_error STMPE2401_GetGpioVal(uint8 stmpeId, uint8 PinIndex, uint8 *Value) +{ + t_STMPE2401_error retval = STMPE2401_OK; + uint8 tempBuffer[3]; + uint8 offset,mask; + + retval = STMPE2401_Gpio_Parameter_Check(stmpeId, PinIndex ); + if(retval != STMPE2401_OK) + { + return retval; + } + + if(PinIndex < 8) + { + offset = GPMR_Lsb_Index; + mask = 1 << PinIndex; + } + else if(PinIndex < 16) + { + offset = GPMR_Csb_Index; + mask = 1 << (PinIndex-8); + } + else + { + offset = GPMR_Msb_Index; + mask = 1 << (PinIndex-16); + } + + retval = STMPE2401_Read(stmpeId, offset,tempBuffer, 1 ); + if(retval != STMPE2401_OK) + { + return retval; + } + + if((tempBuffer[0] & mask) == 0) + { + *Value = 0; + } + else + { + *Value = 1; + } + return retval; +} +/* + This function set STMPE2401 gpio direction + + Parameter + stmpeId = index of the device (0-3) + PinIndex = pin to be set (0-23) + Value = STMPE2401_GPIO_IN input + STMPE2401_GPIO_OUT output +*/ +t_STMPE2401_error STMPE2401_SetGpioDir(uint8 stmpeId, uint8 PinIndex, uint8 Value) +{ + t_STMPE2401_error retval = STMPE2401_OK; + uint32 tempLong; + uint8 offset, tempbyte; + + retval = STMPE2401_Gpio_Parameter_Check(stmpeId, PinIndex ); + if(retval != STMPE2401_OK) + { + return retval; + } + + /*read STMPE2401 configuration*/ + tempLong = Devices[stmpeId].Gpio.Direction; + offset = GPDR_Msb_Index; + + retval = STMPE2401_Bit_Calc( PinIndex, Value, &offset, &tempLong, &tempbyte); + if(retval != STMPE2401_OK) + { + return retval; + } + + retval = STMPE2401_WriteByte( stmpeId, offset, tempbyte ); + if(retval != STMPE2401_OK) + { + return retval; + } + + /*save STMPE2401 configuration*/ + Devices[stmpeId].Gpio.Direction = tempLong; + + return retval; +} + +/* + This function configure STMPE2401 gpio edge detection + + Parameter + stmpeId = index of the device (0-3) + PinIndex = pin to be set (0-23) + OffRiseFall = STMPE2401_NO_EDGE edge detection disabled + STMPE2401_FALL_EDGE falling edge detection + STMPE2401_RISE_EDGE rising edge detection + STMPE2401_BOTH_EDGE falling and rising edge detection +*/ +t_STMPE2401_error STMPE2401_SetGpioEdgeDetect(uint8 stmpeId, uint8 PinIndex,uint8 OffRiseFall ) +{ + t_STMPE2401_error retval = STMPE2401_OK; + uint8 offset,tempbyte,tempValueFALL,tempValueRISE; + uint32 tempLong; + + retval = STMPE2401_Gpio_Parameter_Check(stmpeId, PinIndex ); + if(retval != STMPE2401_OK) + { + return retval; + } + + switch(OffRiseFall) + { + case STMPE2401_NO_EDGE: + tempValueFALL = 0; + tempValueRISE = 0; + break; + case STMPE2401_FALL_EDGE: + tempValueFALL = 1; + tempValueRISE = 0; + break; + case STMPE2401_RISE_EDGE: + tempValueFALL = 0; + tempValueRISE = 1; + break; + case STMPE2401_BOTH_EDGE: + tempValueFALL = 1; + tempValueRISE = 1; + break; + default : + retval = STMPE2401_BAD_PARAMETER; + break; + } + + if(retval == STMPE2401_OK) + { + /*read STMPE2401 configuration*/ + tempLong = Devices[stmpeId].Gpio.FallingEdge; + offset = GPFER_Msb_Index; + + retval = STMPE2401_Bit_Calc( PinIndex, tempValueFALL, &offset, &tempLong, &tempbyte); + if(retval == STMPE2401_OK) + { + retval = STMPE2401_WriteByte( stmpeId, offset, tempbyte ); + } + + if(retval == STMPE2401_OK) + { + /*save STMPE2401 configuration*/ + Devices[stmpeId].Gpio.FallingEdge = tempLong; + } + } + if(retval == STMPE2401_OK) + { + /*read STMPE2401 configuration*/ + tempLong = Devices[stmpeId].Gpio.RisingEdge; + offset = GPRER_Msb_Index; + + retval = STMPE2401_Bit_Calc( PinIndex, tempValueRISE, &offset, &tempLong, &tempbyte); + if(retval == STMPE2401_OK) + { + retval = STMPE2401_WriteByte( stmpeId, offset, tempbyte ); + } + + if(retval == STMPE2401_OK) + { + Devices[stmpeId].Gpio.RisingEdge = tempLong; + } + } + + return retval; +} + +/* + This function read STMPE2401 gpio edge detection status, the status bits + must be cleared using "STMPE2401_ClearGpioEdgeStatus" function + + Parameter + stmpeId = index of the device (0-3) + status = 24 least significant bits, 0 no edge detected 1 rise or fall edge + detected +*/ +t_STMPE2401_error STMPE2401_GetGpioEdgeStatus(uint8 stmpeId,uint32 *status ) +{ + t_STMPE2401_error retval = STMPE2401_OK; + uint8 tempBuffer[5]; + + retval = STMPE2401_Gpio_Parameter_Check(stmpeId, (uint8)NULL ); + if(retval != STMPE2401_OK) + { + return retval; + } + + retval = STMPE2401_Read(stmpeId, GPEDR_Msb_Index,tempBuffer, 3 ); + + *status = (uint32) 0; + *status = tempBuffer[0]; + *status = *status << 8; + *status |= tempBuffer[1]; + *status = *status << 8; + *status |= tempBuffer[2]; + + return retval; +} + +/* This function reset STMPE2401 gpio edge detection status bits + + Parameter + stmpeId = index of the device (0-3) + mask = 24 least significant bits, 0 has no effect ,1 clear corresponding + status bit +*/ +t_STMPE2401_error STMPE2401_ClearGpioEdgeStatus(uint8 stmpeId,uint32 mask ) +{ + t_STMPE2401_error retval = STMPE2401_OK; + uint8 tempBuffer[5]; + + retval = STMPE2401_Gpio_Parameter_Check(stmpeId, (uint8)NULL ); + if(retval != STMPE2401_OK) + { + return retval; + } + tempBuffer[0] = GPEDR_Msb_Index; + tempBuffer[1] = (mask >> 16) & 0xFF; + tempBuffer[2] = (mask >> 8) & 0xFF; + tempBuffer[3] = (mask ) & 0xFF; + + retval = STMPE2401_Write( stmpeId, tempBuffer, 4 ); + return retval; +} + +/* + This function configure STMPE2401 gpio pull-up and pull-down + + Parameter + stmpeId = index of the device (0-3) + PinIndex = pin to be set (0-23) + OffUpDown = STMPE2401_FLOATING + STMPE2401_PULL_UP + STMPE2401_PULL_DOWN +*/ +t_STMPE2401_error STMPE2401_SetGpioPull(uint8 stmpeId, uint8 PinIndex, uint8 OffUpDown ) +{ + t_STMPE2401_error retval = STMPE2401_OK; + uint8 offset,tempbyte,tempValueUP,tempValueDOWN; + uint32 tempLong; + + retval = STMPE2401_Gpio_Parameter_Check(stmpeId, PinIndex ); + if(retval != STMPE2401_OK) + { + return retval; + } + + switch(OffUpDown) + { + case STMPE2401_FLOATING: + tempValueUP = 0; + tempValueDOWN = 0; + break; + case STMPE2401_PULL_UP: + tempValueUP = 1; + tempValueDOWN = 0; + break; + case STMPE2401_PULL_DOWN: + tempValueUP = 0; + tempValueDOWN = 1; + break; + default : + retval = STMPE2401_BAD_PARAMETER; + break; + } + + if(retval == STMPE2401_OK) + { + tempLong = Devices[stmpeId].Gpio.PullUp; + offset = GPPUR_Msb_Index; + + retval = STMPE2401_Bit_Calc( PinIndex, tempValueUP, &offset, &tempLong, &tempbyte); + if(retval == STMPE2401_OK) + { + retval = STMPE2401_WriteByte( stmpeId, offset, tempbyte ); + } + + if(retval == STMPE2401_OK) + { + Devices[stmpeId].Gpio.PullUp = tempLong; + } + } + if(retval == STMPE2401_OK) + { + tempLong = Devices[stmpeId].Gpio.PullDown; + offset = GPPDR_Msb_Index; + + retval = STMPE2401_Bit_Calc( PinIndex, tempValueDOWN, &offset, &tempLong, &tempbyte); + if(retval == STMPE2401_OK) + { + retval = STMPE2401_WriteByte( stmpeId, offset, tempbyte ); + } + + if(retval == STMPE2401_OK) + { + Devices[stmpeId].Gpio.PullDown = tempLong; + } + } + + return retval; +} + +/* + This function configure STMPE2401 gpio pull-up and pull-down + + Parameter + stmpeId = index of the device (0-3) + PinIndex = pin to be set (0-23) + OffUpDown = STMPE2401_PRIMARY_FUNCTION + STMPE2401_ALT_FUNCTION_1 + STMPE2401_ALT_FUNCTION_2 + STMPE2401_ALT_FUNCTION_3 +*/ +t_STMPE2401_error STMPE2401_SetGpioAltFunction(uint8 stmpeId, uint8 PinIndex, uint8 Function ) +{ + t_STMPE2401_error retval = STMPE2401_OK; + uint8 offset,tempbyte,shift; + uint32 tempLong; + + retval = STMPE2401_Gpio_Parameter_Check(stmpeId, PinIndex ); + if(retval != STMPE2401_OK) + { + return retval; + } + if(Function > STMPE2401_ALT_FUNCTION_3) + { + retval = STMPE2401_BAD_PARAMETER; + return retval; + } + if(PinIndex >= 12) + { + /*Gpio from 12 to 23 in upper register*/ + offset = GPAFR_U_Lsb_Index; + tempLong = Devices[stmpeId].Gpio.AltFunctionUpper; + } + else + { + /*Gpio from 0 to 11 in lower register*/ + offset = GPAFR_L_Lsb_Index; + tempLong = Devices[stmpeId].Gpio.AltFunctionLower; + } + + offset -= (PinIndex%12) / 4; + shift = (PinIndex%12) * 2; + + tempLong &=~ ((uint32)3 << shift); + tempLong |= ((uint32)Function << shift); + + tempbyte = tempLong >> (((PinIndex%12)/4) * 8); + + retval = STMPE2401_WriteByte( stmpeId, offset, tempbyte ); + + if(retval == STMPE2401_OK) + { + if(PinIndex >= 12) + { + Devices[stmpeId].Gpio.AltFunctionUpper = tempLong; + } + else + { + Devices[stmpeId].Gpio.AltFunctionLower = tempLong; + } + } + return retval; +} + + +/* + This function init selected pwm channel + MUST be called after GPIO initializzation. + + Parameter + stmpeId = index of the device (0-3) + channels = bit mask, indicate channel to be initialized + use STMPE2401_PWM1, STMPE2401_PWM2 or STMPE2401_PWM3 + +*/ +t_STMPE2401_error STMPE2401_PwmInit(uint8 stmpeId, uint8 channels) +{ + t_STMPE2401_error retval = STMPE2401_OK; + + retval = STMPE2401_Gpio_Parameter_Check(stmpeId,(uint8)NULL); + if(retval != STMPE2401_OK) + { + return retval; + } + if(channels > 0x07) + { + retval = STMPE2401_BAD_PARAMETER; + return retval; + } + if(channels & STMPE2401_PWM1) + { + if(retval == STMPE2401_OK) + { + retval = STMPE2401_SetGpioDir( stmpeId, STMPE2401_PWM1_GPIO, STMPE2401_GPIO_OUT ); + } + if(retval == STMPE2401_OK) + { + retval = STMPE2401_SetGpioAltFunction( stmpeId, STMPE2401_PWM1_GPIO, STMPE2401_ALT_FUNCTION_1 ); + } + } + if(channels & STMPE2401_PWM2) + { + if(retval == STMPE2401_OK) + { + retval = STMPE2401_SetGpioDir( stmpeId, STMPE2401_PWM2_GPIO, STMPE2401_GPIO_OUT ); + } + if(retval == STMPE2401_OK) + { + retval = STMPE2401_SetGpioAltFunction( stmpeId, STMPE2401_PWM2_GPIO, STMPE2401_ALT_FUNCTION_1 ); + } + } + if(channels & STMPE2401_PWM3) + { + if(retval == STMPE2401_OK) + { + retval = STMPE2401_SetGpioDir( stmpeId, STMPE2401_PWM3_GPIO, STMPE2401_GPIO_OUT ); + } + if(retval == STMPE2401_OK) + { + retval = STMPE2401_SetGpioAltFunction( stmpeId, STMPE2401_PWM3_GPIO, STMPE2401_ALT_FUNCTION_1 ); + } + } + if(retval == STMPE2401_OK) + { + /*All Pwm disabled*/ + STMPE2401_WriteByte( stmpeId,PWMCS_Index, 0 ); + } + if(retval == STMPE2401_OK) + { + /*Save configuration*/ + Devices[stmpeId].Pwm.ControlRegister = 0; + Devices[stmpeId].Pwm.PwmValue = 0; + PwmInitializationCheck[stmpeId] = channels; + } + return retval; +} + +/* + This function Set PWM output value + Parameter + stmpeId = index of the device (0-3) + channel = accept STMPE2401_PWM1, STMPE2401_PWM2 or STMPE2401_PWM3 + Value = pwm value. Range 0-255. + - 0 = 0V + - 255 = 1,8V +*/ +t_STMPE2401_error STMPE2401_SetPwm(uint8 stmpeId, uint8 channel, uint8 Value) +{ + t_STMPE2401_error retval = STMPE2401_OK; + uint8 tempbyte,len,delta = 0; + uint8 tempAdd; + uint16 Istructions[15]; + signed int sign = 0; + + retval = STMPE2401_Gpio_Parameter_Check(stmpeId,(uint8)NULL); + if(retval != STMPE2401_OK) + { + return retval; + } + + if((PwmInitializationCheck[stmpeId] & channel) == 0) + { + retval = STMPE2401_INITIALIZATION_ERROR; + return retval; + } + + /* + Istruction calculation. + example for set pwm at 100: + + adress opcode istruction + -------------------------------- + + 0000 00FF SMAX ; set output to 0V + 0001 00E4 RAMP_DN 64 ; step, immediate action + _label: + 0002 7F01 RAMP_UP_SLOW ; + 0003 7F81 RAMP_DN_SLOW ; + 0004 a002 BRANCH _label ; infinite loop + */ + + len = 0; + if(Value == 0) + { + Istructions[0] = SMAX_ISTRUCTION; + len++; + Istructions[1] = GTS_ISTRUCTION; + len++; + } + else if(Value == 255) + { + Istructions[0] = SMIN_ISTRUCTION; + len++; + Istructions[1] = GTS_ISTRUCTION; + len++; + } + else + { + if(Value == Devices[stmpeId].Pwm.PwmValue) + { + /*pwm already set, nothing to do*/ + return retval; + } + else if(Value > Devices[stmpeId].Pwm.PwmValue ) + { + delta = Value - Devices[stmpeId].Pwm.PwmValue; + sign = 1; + } + else if(Value < Devices[stmpeId].Pwm.PwmValue ) + { + delta = Devices[stmpeId].Pwm.PwmValue - Value; + sign = -1; + } + + if(Devices[stmpeId].Pwm.PwmValue == 0) + { + Istructions[0] = SMAX_ISTRUCTION; + len++; + } + /*insert ramp istructions*/ + while(delta > 0) + { + if(delta > 126) + { + tempbyte = 126; + delta -= 126; + } + else + { + tempbyte = delta; + delta = 0; + } + if(sign == -1) + { + Istructions[len] = RAMP_UP(tempbyte); + } + else + { + Istructions[len] = RAMP_DN(tempbyte); + } + len++; + } + /*insert a semi-flat ramp*/ + tempAdd = len; + + if(sign == -1) + { + /*slow ramp down first, needed for direction inversion*/ + Istructions[len] = RAMP_DN_SLOW; + len++; + Istructions[len] = RAMP_UP_SLOW; + len++; + } + else + { + /*slow ramp up first, needed for direction inversion*/ + Istructions[len] = RAMP_UP_SLOW; + len++; + Istructions[len] = RAMP_DN_SLOW; + len++; + } + /*infinite loop*/ + Istructions[len] = BRANCH_TO(tempAdd); + len++; + } + retval = STMPE2401_SetPwmIstructions( stmpeId, channel, Istructions, len); + + if(retval == STMPE2401_OK) + { + Devices[stmpeId].Pwm.PwmValue = Value; + } + else + { + Devices[stmpeId].Pwm.PwmValue = 0; + } + + return retval; +} + +/* + This function write end execute the pwm microcode passed by "*Istructions" + + Parameter + stmpeId = index of the device (0-3) + channel = accept STMPE2401_PWM1, STMPE2401_PWM2 or STMPE2401_PWM3 + Istructions = user microcode + len = code len +*/ +t_STMPE2401_error STMPE2401_SetPwmIstructions(uint8 stmpeId, uint8 channel, uint16 Istructions[],uint8 len) +{ + + t_STMPE2401_error retval = STMPE2401_OK; + uint8 tempbyte; + uint8 tempbuffer[130], bufferLen; + uint8 checkbuffer[130]; + t_STMPE2401_info tempInfo; + uint8 i; + + retval = STMPE2401_Gpio_Parameter_Check(stmpeId,(uint8)NULL); + if(retval != STMPE2401_OK) + { + return retval; + } + + if((PwmInitializationCheck[stmpeId] & channel) == 0) + { + retval = STMPE2401_INITIALIZATION_ERROR; + return retval; + } + + if(len > 64) + { + /*max istruction allowed = 64*/ + retval = STMPE2401_BAD_PARAMETER; + return retval; + } + switch(channel) + { + case STMPE2401_PWM1: + tempbuffer[0] = PWMIC0_Index; + break; + case STMPE2401_PWM2: + tempbuffer[0] = PWMIC1_Index; + break; + case STMPE2401_PWM3: + tempbuffer[0] = PWMIC2_Index; + break; + default : + retval = STMPE2401_BAD_PARAMETER; + return retval; + break; + } + bufferLen = 1; + + /*disable pwm channel*/ + tempbyte = Devices[stmpeId].Pwm.ControlRegister; + tempbyte &=~ channel; + retval = STMPE2401_WriteByte( stmpeId,PWMCS_Index, tempbyte ); + if(retval != STMPE2401_OK) + { + return retval; + } + /*dummy read*/ + i = 0; + do + { + retval = STMPE2401_Info( stmpeId, &tempInfo ); + i++; + if(i >= 10) + { + /*execute max 10 tries*/ + return retval; + } + } + while(retval != STMPE2401_OK); + /*write istructions on STMPE*/ + for(i=0;i> 8 ) & 0xFF; + bufferLen++; + tempbuffer[bufferLen] = Istructions[i] & 0xFF; + bufferLen++; + } + retval = STMPE2401_Write( stmpeId, tempbuffer, bufferLen ); + if(retval != STMPE2401_OK) + { + return retval; + } + /*dummy read*/ + i = 0; + do + { + retval = STMPE2401_Info( stmpeId, &tempInfo ); + i++; + if(i >= 10) + { + /*execute max 10 tries*/ + return retval; + } + } + while(retval != STMPE2401_OK); + /*read back istruction for verification*/ + retval = STMPE2401_Read( stmpeId,tempbuffer[0],&checkbuffer[1], bufferLen-1 ); + if(retval != STMPE2401_OK) + { + return retval; + } + tempbyte = memcmp(&tempbuffer[1], &checkbuffer[1], bufferLen-1); + if(tempbyte != 0) + { + retval = STMPE2401_INTERNAL_ERROR; + return retval; + } + /*enable pwm channel & save configuration*/ + tempbyte |= channel; + Devices[stmpeId].Pwm.ControlRegister = tempbyte; + retval = STMPE2401_WriteByte( stmpeId,PWMCS_Index, tempbyte ); + if(retval != STMPE2401_OK) + { + return retval; + } + /*check if there is a invalid istruction*/ + retval = STMPE2401_Read( stmpeId,PWMCS_Index,&tempbyte, 1 ); + if(retval != STMPE2401_OK) + { + return retval; + } + if((tempbyte & 0x38) != 0) + { + /*invalid istruction encountered*/ + retval = STMPE2401_INTERNAL_ERROR; + } + return retval; +} + +static irqreturn_t stmp_intr_handler(int irq, void *args) +{ + int stmp_intr = irq - MAX_CHIP_IRQ; + if(stmp_intr == STMP0_INTR) + schedule_work(&work0); + else if(stmp_intr == STMP1_INTR) + schedule_work(&work1); + return IRQ_HANDLED; +} + + +/* + This function init interrupt system base configuration and reset device + register to default. + + Parameter + stmpeId = index of the device (0-3) + ndkGpio = nomadik gpio pin defined in "hcl\gpio.h" + NdkPinConfig = nomadik gpio pin configuration +*/ +t_STMPE2401_error STMPE2401_Interrupt_Init(uint8 stmpeId,gpio_pin NdkPin, gpio_config NdkPinConfig) +{ + t_STMPE2401_error retval = STMPE2401_OK; + uint8 tempBuffer[20],i ; + int err; + + retval = STMPE2401_Gpio_Parameter_Check(stmpeId,(uint8)NULL); + + if(retval != STMPE2401_OK) + { + return retval; + } + + /*reset to default value*/ + tempBuffer[0] = ICR_Lsb_Index; + + /*ICR_Lsb_Index contents*/ + switch(NdkPinConfig.trig) + { + case GPIO_TRIG_LEAVE_UNCHANGED: /*Parameter will be ignored by the function*/ + retval = STMPE2401_BAD_PARAMETER; /*not allowed*/ + break; + case GPIO_TRIG_DISABLE: /*Triggers no IT*/ + tempBuffer[1] = 0x02; /*dummy*/ + break; + case GPIO_TRIG_RISING_EDGE: /*Triggers an IT on a rising edge*/ + tempBuffer[1] = 0x06; /*edge (0x2) + rising (0x4)*/ + break; + case GPIO_TRIG_FALLING_EDGE: /*Triggers an IT on a falling edge*/ + tempBuffer[1] = 0x02; /*edge (0x2) + falling (0x0)*/ + break; + case GPIO_TRIG_BOTH_EDGES: /*Triggers an IT on a rising and a falling edge*/ + retval = STMPE2401_BAD_PARAMETER;/*not allowed*/ + break; + case GPIO_TRIG_HIGH_LEVEL: /*Triggers an IT on a high level*/ + tempBuffer[1] = 0x04; /*level (0x0) + high (0x4)*/ + break; + case GPIO_TRIG_LOW_LEVEL: /*Triggers an IT on a low level*/ + tempBuffer[1] = 0x00; /*level (0x0) + low (0x0)*/ + break; + default : + break; + } + + if(retval != STMPE2401_OK) + { + return retval; + } + + /*saving configuration*/ + Devices[stmpeId].Interrupt.ControlReg = tempBuffer[1]; + + /*all interrupt disabled exept gpio */ + tempBuffer[2] = 0x01; + tempBuffer[3] = 0x00; + + /*saving configuration*/ + /*gpio global interrupt source enabled by default, + gpio single source are disabled in "GpioMaskReg" + */ + + Devices[stmpeId].Interrupt.EnableReg = 0x0100; + + /*clear all interrupt flag*/ + tempBuffer[4] = 0x01; /*ISR_Msb_Index*/ + tempBuffer[5] = 0xFF; /*ISR_Lsb_Index*/ + + /*all gpio interrupt disabled*/ + tempBuffer[6] = 0x00; /*IEGPIOR_Msb_Index*/ + tempBuffer[7] = 0x00; /*IEGPIOR_Csb_Index*/ + tempBuffer[8] = 0x00; /*IEGPIOR_Lsb_Index*/ + /*saving configuration*/ + Devices[stmpeId].Interrupt.GpioMaskReg = 0; + + /*clear all gpio interrupt fl/seag*/ + tempBuffer[9] = 0xFF; /*IEGPIOR_Msb_Index*/ + tempBuffer[10] = 0xFF; /*IEGPIOR_Csb_Index*/ + tempBuffer[11] = 0xFF; /*IEGPIOR_Lsb_Index*/ + + retval = STMPE2401_Write( stmpeId,tempBuffer, 12 ); + + for(i=0;i 0x00FF) + { + /*max 8 columns*/ + retval = STMPE2401_BAD_PARAMETER; + } + else if(Settings.rows > 0x0FFF) + { + /*max 12 rows*/ + retval = STMPE2401_BAD_PARAMETER; + } + else if(Settings.nCycles > 15) + { + retval = STMPE2401_BAD_PARAMETER; + } + else if(Settings.debounce > 127) + { + retval = STMPE2401_BAD_PARAMETER; + } + + if(retval != STMPE2401_OK) + { + return retval; + } + + /*setting GPIO alternate function + columns 0-7 are connected to gpio 0-7*/ + for(i=0; i<8; i++ ) + { + if((Settings.columns & (1<> 8) & 0x0F) | 0xC0; /*upper 4 rows*/ + tempBuffer[3] = (Settings.rows) & 0xFF; /*lower 8 rows*/ + tempBuffer[4] = (Settings.nCycles << 4) & 0xF0; /*ctrl reg msb*/ + tempBuffer[5] = (Settings.debounce << 1) & 0xFE; /*ctrl reg lsb*/ + + retval = STMPE2401_Write(stmpeId, tempBuffer, 6); + if(retval != STMPE2401_OK) + { + return retval; + } + return retval; +} + +/* + This function start/stop keypad scannig + Parameter + stmpeId = index of the device (0-3) + status = STMPE2401_SCAN_ON or STMPE2401_SCAN_OFF +*/ +t_STMPE2401_error STMPE2401_Keypad_scan(uint8 stmpeId, uint8 status) +{ + t_STMPE2401_error retval = STMPE2401_OK; + uint8 tempByte; + + retval = STMPE2401_Gpio_Parameter_Check(stmpeId,(uint8)NULL); + if(retval != STMPE2401_OK) + { + return retval; + } + tempByte = (Devices[stmpeId].Key.debounce << 1); + + switch(status) + { + case STMPE2401_SCAN_ON: + tempByte |= 1; + break; + case STMPE2401_SCAN_OFF: + tempByte &=~ 1; + break; + default : + retval = STMPE2401_BAD_PARAMETER; + break; + } + + if(retval == STMPE2401_OK) + { + retval = STMPE2401_WriteByte(stmpeId,KPC_CTRL_Lsb_Index, tempByte ); + } + if(retval == STMPE2401_OK) + { + Devices[stmpeId].Key.scan = status; + } + return retval; +} +/* + This function read keypad data registers, can be used in both polling or + interrupt usage. + Parameter + stmpeId = index of the device (0-3) + keys = keys pressed +*/ +t_STMPE2401_error STMPE2401_Keypressed(uint8 stmpeId, t_STMPE2401_key_status *keys) +{ + t_STMPE2401_error retval = STMPE2401_OK; + static uint8 tempBuffer[10]; + + keys->buttonPressed = 0; + keys->buttonReleased = 0; + + retval = STMPE2401_Read( stmpeId,KPC_DATA_BYTE0_Index,tempBuffer, 1 ); + retval = STMPE2401_Read( stmpeId,KPC_DATA_BYTE1_Index,&tempBuffer[1], 1 ); + + if((tempBuffer[0] & STMPE2401_MASK_NO_KEY) != STMPE2401_MASK_NO_KEY ) + { + if((tempBuffer[0] & 0x80) == 0) + { + keys->button[0] = tempBuffer[0] & 0x7F; + keys->buttonPressed++; + } + else + { + keys->released[0] = tempBuffer[0] & 0x7F; + keys->buttonReleased++; + } + } + if((tempBuffer[1] & STMPE2401_MASK_NO_KEY) != STMPE2401_MASK_NO_KEY ) + { + if((tempBuffer[1] & 0x80) == 0) + { + keys->button[keys->buttonPressed] = tempBuffer[1] & 0x7F; + keys->buttonPressed++; + } + else + { + keys->released[keys->buttonReleased] = tempBuffer[1] & 0x7F; + keys->buttonReleased++; + } + } + + return retval; +} + +/* + This function install a interrupt callback + Parameter + stmpeId = index of the device (0-3) + HwSource = interrupt source + Callback = pointer to callback function + CallbackParam = pointer to callback parameter +*/ +t_STMPE2401_error STMPE2401_Install_Callback(uint8 stmpeId,uint8 HwSource,void (*Callback)(void *parameter), + void *CallbackParam) +{ + t_STMPE2401_error retval = STMPE2401_OK; + + retval = STMPE2401_Gpio_Parameter_Check( stmpeId,(uint8)NULL); + if(HwSource >= MAX_STMPE2401_CALLBACK) + { + retval = STMPE2401_BAD_PARAMETER; + } + if(retval != STMPE2401_OK) + { + return retval; + } + switch(HwSource) + { + case STMPE2401_WAKEUP_IRQ: + break; + case STMPE2401_KEYPAD_IRQ: + break; + case STMPE2401_KEYPAD_OVERFLOW_IRQ: + break; + case STMPE2401_ROTATOR_IRQ: + retval = STMPE2401_FEAT_NOT_SUPPORTED; + break; + case STMPE2401_ROTATOR_OVERFLOW_IRQ: + retval = STMPE2401_FEAT_NOT_SUPPORTED; + break; + case STMPE2401_PWM0_IRQ: + retval = STMPE2401_FEAT_NOT_SUPPORTED; + break; + case STMPE2401_PWM1_IRQ: + retval = STMPE2401_FEAT_NOT_SUPPORTED; + break; + case STMPE2401_PWM2_IRQ: + retval = STMPE2401_FEAT_NOT_SUPPORTED; + break; + default : + + break; + } + Devices[stmpeId].Interrupt.Callback[HwSource] = Callback; + Devices[stmpeId].Interrupt.CallbackParam[HwSource] = CallbackParam; + /*Set the callback as installed*/ + CallbackInstallationCheck[stmpeId] |= ((uint32)1 << HwSource); + return retval; +} + +/* + This function remove a interrupt callback + The interrupt source MUST be disabled first for safety pourpose + Parameter + stmpeId = index of the device (0-3) + HwSource = interrupt source +*/ +t_STMPE2401_error STMPE2401_Remove_Callback(uint8 stmpeId, uint8 HwSource) +{ + t_STMPE2401_error retval = STMPE2401_OK; + + retval = STMPE2401_Gpio_Parameter_Check( stmpeId,(uint8)NULL); + if(HwSource >= MAX_STMPE2401_CALLBACK) + { + retval = STMPE2401_BAD_PARAMETER; + } + if(retval != STMPE2401_OK) + { + return retval; + } + /*check if interrupt is already active*/ + if(InterruptActive[stmpeId] & ((uint32)1 << HwSource)) + { + /*source already active, remove the callback + can port a system instability + */ + retval = STMPE2401_ERROR; + return retval; + } + Devices[stmpeId].Interrupt.Callback[HwSource] = &EmptyCallback; + Devices[stmpeId].Interrupt.CallbackParam[HwSource] = NULL; + + /*Set the callback as installed*/ + CallbackInstallationCheck[stmpeId] &=~ ((uint32)1 << HwSource); + + return retval; +} + +/* + This function enable/disable a interrupt source + In case of interrupt abilitation the interrupt callback MUST be installed + first for safety pourpose. + + Parameter + stmpeId = index of the device (0-3) + HwSource = interrupt source + Abilitation = state to be set (STMPE2401_ENABLE_INTERRUPT or + STMPE2401_DISABLE_INTERRUPT) +*/ +t_STMPE2401_error STMPE2401_InterruptSourceAbilitation(uint8 stmpeId, uint8 HwSource, uint8 Abilitation ) +{ + t_STMPE2401_error retval = STMPE2401_OK; + uint8 tempByte,offset; + uint16 mask=0,tempWord; + uint32 tempLong; + + retval = STMPE2401_Gpio_Parameter_Check( stmpeId,(uint8)NULL); + if(HwSource >= MAX_STMPE2401_CALLBACK) + { + retval = STMPE2401_BAD_PARAMETER; + } + + if(retval != STMPE2401_OK) + { + return retval; + } + + switch(HwSource) + { + case STMPE2401_WAKEUP_IRQ: + mask = 0x0001; + break; + case STMPE2401_KEYPAD_IRQ: + mask = 0x0002; + break; + case STMPE2401_KEYPAD_OVERFLOW_IRQ: + mask = 0x0004; + break; + case STMPE2401_ROTATOR_IRQ: + retval = STMPE2401_FEAT_NOT_SUPPORTED; + break; + case STMPE2401_ROTATOR_OVERFLOW_IRQ: + retval = STMPE2401_FEAT_NOT_SUPPORTED; + break; + case STMPE2401_PWM0_IRQ: + retval = STMPE2401_FEAT_NOT_SUPPORTED; + break; + case STMPE2401_PWM1_IRQ: + retval = STMPE2401_FEAT_NOT_SUPPORTED; + break; + case STMPE2401_PWM2_IRQ: + retval = STMPE2401_FEAT_NOT_SUPPORTED; + break; + default : + /*already enabled*/ + break; + } + if(retval != STMPE2401_OK) + { + return retval; + } + + tempWord = Devices[stmpeId].Interrupt.EnableReg; + tempLong = Devices[stmpeId].Interrupt.GpioMaskReg; + + switch(Abilitation) + { + case STMPE2401_ENABLE_INTERRUPT: + /*check callback installation*/ + if((CallbackInstallationCheck[stmpeId] & ((uint32)1 << HwSource)) == 0 ) + { + /*there is no callback for this source.*/ + retval = STMPE2401_ERROR; + } + else if(Devices[stmpeId].Interrupt.Callback[HwSource] == &EmptyCallback) + { + /*there is no callback for this source*/ + retval = STMPE2401_ERROR; + } + else if(Devices[stmpeId].Interrupt.Callback[HwSource] == NULL) + { + /*there is no callback for this source*/ + retval = STMPE2401_ERROR; + } + else + { + if(HwSource <= STMPE2401_GPIO_IRQ(23)) + { + tempLong |= ((uint32)1 << HwSource); + } + else + { + tempWord |= mask; + } + } + break; + case STMPE2401_DISABLE_INTERRUPT: + + if(HwSource <= STMPE2401_GPIO_IRQ(23)) + { + tempLong &=~ ((uint32)1 << HwSource); + } + else + { + tempWord &=~ mask; + } + break; + default: + retval = STMPE2401_BAD_PARAMETER; + break; + } + if(retval == STMPE2401_OK) + { + if(HwSource <= STMPE2401_GPIO_IRQ(23)) + { + /*update only gpio mask register*/ + tempByte = (tempLong >> ((HwSource / 8) * 8)) & 0xFF; + offset = IEGPIOR_Lsb_Index - (HwSource / 8); + retval = STMPE2401_WriteByte( stmpeId, offset, tempByte ); + } + else + { + tempByte = tempWord & 0xFF; + retval = STMPE2401_WriteByte( stmpeId, IER_Lsb_Index, tempByte ); + } + } + if(retval == STMPE2401_OK) + { + Devices[stmpeId].Interrupt.EnableReg = tempWord; + Devices[stmpeId].Interrupt.GpioMaskReg = tempLong; + + if(Abilitation == STMPE2401_ENABLE_INTERRUPT) + { + InterruptActive[stmpeId] |= ((uint32)1 << HwSource); + } + else + { + InterruptActive[stmpeId] &=~ ((uint32)1 << HwSource); + } + } + return retval; + +} + +/* Modified version : enables/disables only global interrupt inside the STMPE2401*/ +t_STMPE2401_error STMPE2401_InterruptAbilitation(uint8 stmpeId, uint8 Abilitation ) +{ + t_STMPE2401_error retval = STMPE2401_OK; + uint8 tempByte[2]; + + tempByte[0] = Devices[stmpeId].Interrupt.ControlReg >>8; + tempByte[1] = Devices[stmpeId].Interrupt.ControlReg & 0xFF; + + retval = STMPE2401_Gpio_Parameter_Check( stmpeId, (uint8)NULL); + if(retval == STMPE2401_OK ) + { + switch(Abilitation) + { + case STMPE2401_ENABLE_INTERRUPT: + /*set Global Interrupt Mask bit*/ + tempByte[1] |= 0x01; + Devices[stmpeId].Interrupt.ControlReg |= 0x01; + retval = STMPE2401_WriteByte( stmpeId,ICR_Lsb_Index, tempByte[1] ); + break; + case STMPE2401_DISABLE_INTERRUPT: + /*clear Global Interrupt Mask bit*/ + tempByte[1] &=~ 0x01; + Devices[stmpeId].Interrupt.ControlReg &=~ 0x01; + retval = STMPE2401_WriteByte( stmpeId,ICR_Lsb_Index, tempByte[1] ); + /*clear pending flags ??*/ + break; + default : + retval = STMPE2401_BAD_PARAMETER; + break; + } + } + return retval; +} + +/*acknowledge the interrupt*/ +t_STMPE2401_error STMPE2401_Acknowledge(uint8 stmpeId, uint16 irqSource, uint32 irqGpioSource) +{ + t_STMPE2401_error err = STMPE2401_OK; + uint8 tempBuffer[5]; + + /* acknowledge in the general interrutpt status register*/ + tempBuffer[0] = ISR_Msb_Index; + tempBuffer[1] = (uint8)(irqSource >> 8); + tempBuffer[2] = (uint8)(irqSource & 0xFF); + err = STMPE2401_Write( stmpeId,tempBuffer, 3 ); + + /* if it's a GPIO interrupt then acknowledge the GPIO interrupt status as well*/ + if(irqSource & 0x100) + { + /*write back flags for interrupt request clearing*/ + tempBuffer[0] = ISGPIOR_Msb_Index; + tempBuffer[1] = (uint8)((irqGpioSource >> 16) & 0xFF); + tempBuffer[2] = (uint8)((irqGpioSource >> 8) & 0xFF); + tempBuffer[3] = (uint8)((irqGpioSource >> 0) & 0xFF); + err = STMPE2401_Write( stmpeId, tempBuffer, 4 ); + tempBuffer[0] = GPEDR_Msb_Index; + err = STMPE2401_Write( stmpeId, tempBuffer, 4 ); + } + return err; +} + +/*IRQ function. +*/ +static void nomadik_stmpe0_wq(void * data) +{ + t_STMPE2401_error err = STMPE2401_OK; + uint8 vector, ISx, ISGx; + uint8 tempBuffer[5]; + uint16 irqSource = 0, shift; + uint32 irqGpioSource = 0; + /*unsigned long flags; */ + uint8 stmpeId = STMPE0; + + /*spin_lock_irqsave(&stmpe_list_lock, flags);*/ + /*check the interruption sources reading the "Interrupt status register" + and if needed "Interrupt status GPIO register" + */ + err = STMPE2401_Read( stmpeId,ISR_Msb_Index, &tempBuffer[1], 2 ); + if(err == STMPE2401_OK) + { + irqSource = tempBuffer[1]; + irqSource = irqSource << 8; + irqSource |= tempBuffer[2]; + irqSource &= 0x1FF; /*remove non ISx bits*/ + if(irqSource == 0) + { + /*error, no STMPE2401 irq request find !!!*/ + err = STMPE2401_INTERNAL_ERROR; + } + else + { + /*write back flags for interrupt request clearing*/ + tempBuffer[0] = ISR_Msb_Index; + err = STMPE2401_Write( stmpeId,tempBuffer, 3 ); + if(irqSource & 0x100) + { + /*irqGpioSource*/ + err = STMPE2401_Read( stmpeId,ISGPIOR_Msb_Index,&tempBuffer[1], 3 ); + if(err == STMPE2401_OK) + { + irqGpioSource = (tempBuffer[1] << 16) | (tempBuffer[2] << 8) | (tempBuffer[3]); + } + if(irqGpioSource == 0) + { + /*error, no STMPE2401 gpio irq request find !!!*/ + err = STMPE2401_INTERNAL_ERROR; + } + else + { + /*write back flags for interrupt request clearing*/ + tempBuffer[0] = ISGPIOR_Msb_Index; + err = STMPE2401_Write( stmpeId, tempBuffer, 4 ); + /*And clear the edge detect status + err = STMPE2401_ClearGpioEdgeStatus(stmpeId,irqGpioSource); + */ + } + /*GpioEdgeDetectStatus*/ + err = STMPE2401_Read( stmpeId,GPEDR_Msb_Index,&tempBuffer[1], 3 ); + if(err == STMPE2401_OK) + { + irqGpioSource = (tempBuffer[1] << 16) | (tempBuffer[2] << 8) | (tempBuffer[3]); + } + if(irqGpioSource == 0) + { + /*error, no STMPE2401 edge detect status found*/ + err = STMPE2401_INTERNAL_ERROR; + } + else + { + /*write back flags for interrupt request clearing*/ + tempBuffer[0] = GPEDR_Msb_Index; + err = STMPE2401_Write( stmpeId, tempBuffer, 4 ); + } + } + } + } + if(err == STMPE2401_OK) + { + while(irqSource != 0) + { + ISx = 8; + for(shift = 0x100; shift > 0 ; shift = shift >> 1 ) + { + if((irqSource & shift) != 0) + { + break; + } + ISx --; + } + if(ISx == 8) + { + for(ISGx=0;ISGx<24;ISGx ++ ) + { + if(irqGpioSource & ((uint32)1 << ISGx )) + { + break; + } + } + /*clear gpio request bit*/ + irqGpioSource &=~ ((uint32)1 << ISGx); + vector = ISGx; + if(irqGpioSource == 0) + { + /*no other gpio request, clear request bit*/ + irqSource &=~ 0x100; + } + } + else + { + /*clear request bit*/ + irqSource &=~ shift; + vector = ISx + STMPE2401_WAKEUP_IRQ; + if(vector >= STMPE2401_ROTATOR_IRQ) + { + STMPE2401_InterruptSourceAbilitation( stmpeId, vector, STMPE2401_DISABLE_INTERRUPT ); + err = STMPE2401_FEAT_NOT_SUPPORTED; + } + } + /*Interrupt abilitation check*/ + if((CallbackInstallationCheck[stmpeId] & ((uint32)1 << vector)) == 0) + { + err = STMPE2401_INTERNAL_ERROR; + } + else if((InterruptActive[stmpeId] & ((uint32)1 << vector)) == 0) + { + err = STMPE2401_INTERNAL_ERROR; + } + else if(Devices[stmpeId].Interrupt.Callback[vector] == EmptyCallback) + { + err = STMPE2401_INTERNAL_ERROR; + } + else if(Devices[stmpeId].Interrupt.Callback[vector] == NULL) + { + err = STMPE2401_INTERNAL_ERROR; + } + + if(err == STMPE2401_OK) + { + /*Callback execution*/ + Devices[stmpeId].Interrupt.Callback[vector](Devices[stmpeId].Interrupt.CallbackParam[vector]); + /*clear runtime errors count*/ + InterruptRuntimeErrors[stmpeId] = 0; + } + else + { + break; + } + } + } + if(err != STMPE2401_OK) + { + if(InterruptRuntimeErrors[stmpeId] >= MAX_STMPE2401_RUNTIME_ERROR) + { + /*try to disable this interrupt source*/ + STMPE2401_InterruptAbilitation( stmpeId, STMPE2401_DISABLE_INTERRUPT ); + } + else + { + InterruptRuntimeErrors[stmpeId] ++; + } + } +} + +static void nomadik_stmpe1_wq(void * data) +{ + t_STMPE2401_error err = STMPE2401_OK; + uint8 vector, ISx, ISGx; + uint8 tempBuffer[5]; + uint16 irqSource = 0, shift; + uint32 irqGpioSource = 0; + /*unsigned long flags; */ + uint8 stmpeId = STMPE1; + + /*check the interruption sources reading the "Interrupt status register" + and if needed "Interrupt status GPIO register" + */ + err = STMPE2401_Read( stmpeId,ISR_Msb_Index, &tempBuffer[1], 2 ); + if(err == STMPE2401_OK) + { + irqSource = tempBuffer[1]; + irqSource = irqSource << 8; + irqSource |= tempBuffer[2]; + irqSource &= 0x1FF; /*remove non ISx bits*/ + + if(irqSource == 0) + { + /*error, no STMPE2401 irq request find !!!*/ + err = STMPE2401_INTERNAL_ERROR; + } + else + { + /*write back flags for interrupt request clearing*/ + tempBuffer[0] = ISR_Msb_Index; + err = STMPE2401_Write( stmpeId,tempBuffer, 3 ); + + + if(irqSource & 0x100) + { + /*irqGpioSource*/ + err = STMPE2401_Read( stmpeId,ISGPIOR_Msb_Index,&tempBuffer[1], 3 ); + if(err == STMPE2401_OK) + { + irqGpioSource = (tempBuffer[1] << 16) | (tempBuffer[2] << 8) | (tempBuffer[3]); + } + + if(irqGpioSource == 0) + { + /*error, no STMPE2401 gpio irq request find !!!*/ + err = STMPE2401_INTERNAL_ERROR; + } + else + { + /*write back flags for interrupt request clearing*/ + tempBuffer[0] = ISGPIOR_Msb_Index; + err = STMPE2401_Write( stmpeId, tempBuffer, 4 ); + /* And clear the edge detect status + err = STMPE2401_ClearGpioEdgeStatus(stmpeId,irqGpioSource); + */ + } + /*GpioEdgeDetectStatus*/ + err = STMPE2401_Read( stmpeId,GPEDR_Msb_Index,&tempBuffer[1], 3 ); + if(err == STMPE2401_OK) + { + irqGpioSource = (tempBuffer[1] << 16) | (tempBuffer[2] << 8) | (tempBuffer[3]); + } + if(irqGpioSource == 0) + { + /*error, no STMPE2401 edge detect status found*/ + err = STMPE2401_INTERNAL_ERROR; + } + else + { + /*write back flags for interrupt request clearing*/ + tempBuffer[0] = GPEDR_Msb_Index; + err = STMPE2401_Write( stmpeId, tempBuffer, 4 ); + } + + } + } + } + if(err == STMPE2401_OK) + { + while(irqSource != 0) + { + ISx = 8; + for(shift = 0x100; shift > 0 ; shift = shift >> 1 ) + { + if((irqSource & shift) != 0) + { + + break; + } + ISx --; + } + if(ISx == 8) + { + + for(ISGx=0;ISGx<24;ISGx ++ ) + { + if(irqGpioSource & ((uint32)1 << ISGx )) + { + break; + } + } + /*clear gpio request bit*/ + irqGpioSource &=~ ((uint32)1 << ISGx); + vector = ISGx; + + if(irqGpioSource == 0) + { + /*no other gpio request, clear request bit*/ + irqSource &=~ 0x100; + } + + } + else + { + /*clear request bit*/ + irqSource &=~ shift; + + vector = ISx + STMPE2401_WAKEUP_IRQ; + if(vector >= STMPE2401_ROTATOR_IRQ) + { + STMPE2401_InterruptSourceAbilitation( stmpeId, vector, STMPE2401_DISABLE_INTERRUPT ); + err = STMPE2401_FEAT_NOT_SUPPORTED; + } + } + /*Interrupt abilitation check*/ + if((CallbackInstallationCheck[stmpeId] & ((uint32)1 << vector)) == 0) + { + err = STMPE2401_INTERNAL_ERROR; + } + else if((InterruptActive[stmpeId] & ((uint32)1 << vector)) == 0) + { + err = STMPE2401_INTERNAL_ERROR; + } + else if(Devices[stmpeId].Interrupt.Callback[vector] == EmptyCallback) + { + err = STMPE2401_INTERNAL_ERROR; + } + else if(Devices[stmpeId].Interrupt.Callback[vector] == NULL) + { + err = STMPE2401_INTERNAL_ERROR; + } + + if(err == STMPE2401_OK) + { + /*Callback execution*/ + Devices[stmpeId].Interrupt.Callback[vector](Devices[stmpeId].Interrupt.CallbackParam[vector]); + /*clear runtime errors count*/ + InterruptRuntimeErrors[stmpeId] = 0; + } + else + { + break; + } + } + } + + if(err != STMPE2401_OK) + { + if(InterruptRuntimeErrors[stmpeId] >= MAX_STMPE2401_RUNTIME_ERROR) + { + /*try to disable this interrupt source*/ + STMPE2401_InterruptAbilitation( stmpeId, STMPE2401_DISABLE_INTERRUPT ); + } + else + { + InterruptRuntimeErrors[stmpeId] ++; + } + } +} + +/* +This function check common gpio function parameter + + Parameter + stmpeId = index of the device (0-3) + PinIndex = pin to be set (0-23) + use NULL if don't care +*/ +static t_STMPE2401_error STMPE2401_Gpio_Parameter_Check(uint8 stmpeId, uint8 PinIndex) +{ + if(stmpeId >= MAX_STMPE2401_DEVICE) + { + /*number of device exceeded*/ + return STMPE2401_BAD_PARAMETER; + } + if((DeviceInitializationCheck & DEVICE_MASK[stmpeId]) == 0) + { + /*device uninitialized*/ + return STMPE2401_INITIALIZATION_ERROR; + } + if(PinIndex >= MAX_STMPE2401_GPIO) + { + /*number of pin exceeded*/ + return STMPE2401_BAD_PARAMETER; + } + return STMPE2401_OK; +} + +/* + This function execute common gpio bit calculation + + Parameter + PinIndex = pin to be set (0-23) + PinValue = value to be set (0-1) + Offset = in - base register XXXX_Msb_Index + out - correct register + RegValue = in - current register value + out - new value +*/ +static t_STMPE2401_error STMPE2401_Bit_Calc( uint8 PinIndex, uint8 PinValue,uint8 *Register, uint32 *RegValue, uint8 *RegByte) +{ + uint8 mask; + + mask = 1 << (PinIndex % 8); + *RegByte = (*RegValue >> ((PinIndex / 8) * 8)) & 0xFF; + + if(PinValue == 0) + { + *RegByte &=~ mask; + *RegValue &=~ ((uint32)1 << PinIndex); + } + else if(PinValue == 1) + { + *RegByte |= mask; + *RegValue |= ((uint32)1 << PinIndex); + } + else + { + return STMPE2401_BAD_PARAMETER; + } + if(PinIndex < 8) + { + *Register += 2; + } + else if(PinIndex < 16) + { + *Register += 1; + } + else + { + /*register already correct*/ + } + return STMPE2401_OK; +} + +/* + This function write via I2C on the selected STMPE2401 + the first BYTE must be the internal register offset. + + Parameter + stmpeId = index of the device (0-3) + buffer = pointer to data buffer + nByte = number of byte to be written +*/ +static t_STMPE2401_error STMPE2401_Write(uint8 stmpeId,uint8 *buffer, uint8 nByte ) +{ + int ret_val; + + if (stmpeId == 0) { + ret_val=nomadik_i2c_write_register(I2C_STMPE0_CLIENT,&buffer[1],buffer[0],nByte); + }else { + ret_val=nomadik_i2c_write_register(I2C_STMPE1_CLIENT,&buffer[1],buffer[0],nByte); + } + + if (ret_val) { + printk("Error in writing value to STMPE register\n"); + return ret_val; + } + + return STMPE2401_OK; + +} + +/* + This function write a single byte via I2C on the selected STMPE2401 + + Parameter + stmpeId = index of the device (0-3) + offset = internal register offset + DataValue = byte to be written +*/ +static uint8 buffer[2]; + +static t_STMPE2401_error STMPE2401_WriteByte(uint8 stmpeId,uint8 offset, uint8 DataValue ) +{ + buffer[0] = offset; + buffer[1] = DataValue; + return STMPE2401_Write( stmpeId, buffer, 1 ); +} + +/* + This function read via I2C on the selected STMPE2401 + the first BYTE must be the internal register offset. + + Parameter + stmpeId = index of the device (0-3) + offset = internal register offset + buffer = pointer to data buffer + nByte = number of byte to be written +*/ +static t_STMPE2401_error STMPE2401_Read(uint8 stmpeId,uint8 offset,uint8 *buffer, uint8 nByte ) +{ + int ret_val = 0; + + if (stmpeId == STMPE0) { + ret_val=nomadik_i2c_read_register(I2C_STMPE0_CLIENT,(__u8 *)buffer,offset,nByte); + if (ret_val) return ret_val; + }else { + ret_val=nomadik_i2c_read_register(I2C_STMPE1_CLIENT,(__u8 *)buffer,offset,nByte); + if (ret_val) return ret_val; + } + return STMPE2401_OK; +} + +/*issue reset to STMPE device for soft reboot*/ +t_STMPE2401_error STMPE2401_reboot() +{ + t_STMPE2401_error retval = STMPE2401_OK; + /*soft reset*/ + retval = STMPE2401_WriteByte( STMPE0, SYSCON_Index, 0x80 ); + + if(retval != STMPE2401_OK) + { + printk("Couldn't reset the STMPE device\n"); + return retval; + } + retval = STMPE2401_WriteByte( STMPE1, SYSCON_Index, 0x80 ); + + if(retval != STMPE2401_OK) + { + printk("Couldn't reset the STMPE device\n"); + return retval; + } + return retval; +} + +t_stmpe2401_syscon_ds syscont[MAX_STMPE2401_DEVICE]; +t_stmpe2401_interrupt_ds intconf[MAX_STMPE2401_DEVICE]; +t_stmpe2401_pwm_ds pwmconf[MAX_STMPE2401_DEVICE]; +t_stmpe2401_kpc_ds kpcconf[MAX_STMPE2401_DEVICE]; +t_stmpe2401_gpio_ds gpioconf[MAX_STMPE2401_DEVICE]; + +static t_STMPE2401_error STMPE2401_Save_Register_Context(void) +{ + int i; + t_STMPE2401_error err = STMPE2401_OK; + + for(i=0; i<2; i++) { + /*syscontrol*/ + STMPE2401_Read(i, SYSCON_Index, &syscont[i].syscon_data, 1); + /*Interrupt Conf*/ + STMPE2401_Read(i, ICR_Msb_Index, &intconf[i].icr_msb_data, 1); + STMPE2401_Read(i, ICR_Lsb_Index, &intconf[i].icr_lsb_data, 1); + + STMPE2401_Read(i, IER_Msb_Index, &intconf[i].ier_msb_data, 1); + intconf[i].ier_msb_data |= 0xFF; + STMPE2401_WriteByte(i, IER_Msb_Index, intconf[i].ier_msb_data); + STMPE2401_Read(i, IER_Msb_Index, &intconf[i].ier_msb_data, 1); + + STMPE2401_Read(i, IER_Lsb_Index, &intconf[i].ier_lsb_data, 1); + intconf[i].ier_lsb_data |= 0xFF; + STMPE2401_WriteByte(i, IER_Lsb_Index, intconf[i].ier_lsb_data); + STMPE2401_Read(i, IER_Lsb_Index, &intconf[i].ier_lsb_data, 1); + STMPE2401_WriteByte(i, ISR_Msb_Index, 0x01 ); + STMPE2401_WriteByte(i, ISR_Lsb_Index, 0x03 ); + + STMPE2401_Read(i, IEGPIOR_Msb_Index, &intconf[i].iegpior_msb_data, 1); + STMPE2401_Read(i, IEGPIOR_Csb_Index, &intconf[i].iegpior_csb_data, 1); + STMPE2401_Read(i, IEGPIOR_Lsb_Index, &intconf[i].iegpior_lsb_data, 1); + STMPE2401_WriteByte(i, ISGPIOR_Msb_Index, 0xFF ); + STMPE2401_WriteByte(i, ISGPIOR_Csb_Index, 0xFF ); + STMPE2401_WriteByte(i, ISGPIOR_Lsb_Index, 0xFF ); + + /*Powermanagenet*/ + STMPE2401_Read(i, PWMCS_Index, &pwmconf[i].pwmcs_data, 1); + STMPE2401_Read(i, PWMIC0_Index, &pwmconf[i].pwmic0_data, 1); + STMPE2401_Read(i, PWMIC1_Index, &pwmconf[i].pwmic1_data, 1); + STMPE2401_Read(i, PWMIC2_Index, &pwmconf[i].pwmic2_data, 1); + /*GPIO conf*/ + STMPE2401_Read(i, GPMR_Msb_Index, &gpioconf[i].gpmr_msb_data, 1); + STMPE2401_Read(i, GPMR_Csb_Index, &gpioconf[i].gpmr_csb_data, 1); + STMPE2401_Read(i, GPMR_Lsb_Index, &gpioconf[i].gpmr_lsb_data, 1); + + STMPE2401_Read(i, GPSR_Msb_Index, &gpioconf[i].gpsr_msb_data, 1); + STMPE2401_Read(i, GPSR_Csb_Index, &gpioconf[i].gpsr_csb_data, 1); + STMPE2401_Read(i, GPSR_Lsb_Index, &gpioconf[i].gpsr_lsb_data, 1); + + STMPE2401_Read(i, GPCR_Msb_Index, &gpioconf[i].gpcr_msb_data, 1); + STMPE2401_Read(i, GPCR_Csb_Index, &gpioconf[i].gpcr_csb_data, 1); + STMPE2401_Read(i, GPCR_Lsb_Index, &gpioconf[i].gpcr_lsb_data, 1); + + STMPE2401_Read(i, GPDR_Msb_Index, &gpioconf[i].gpdr_msb_data, 1); + STMPE2401_Read(i, GPDR_Csb_Index, &gpioconf[i].gpdr_csb_data, 1); + STMPE2401_Read(i, GPDR_Lsb_Index, &gpioconf[i].gpdr_lsb_data, 1); + + STMPE2401_Read(i, GPEDR_Msb_Index, &gpioconf[i].gpedr_msb_data, 1); + STMPE2401_Read(i, GPEDR_Csb_Index, &gpioconf[i].gpedr_csb_data, 1); + STMPE2401_Read(i, GPEDR_Lsb_Index, &gpioconf[i].gpedr_lsb_data, 1); + + STMPE2401_Read(i, GPRER_Msb_Index, &gpioconf[i].gprer_msb_data, 1); + STMPE2401_Read(i, GPRER_Csb_Index, &gpioconf[i].gprer_csb_data, 1); + STMPE2401_Read(i, GPRER_Lsb_Index, &gpioconf[i].gprer_lsb_data, 1); + + STMPE2401_Read(i, GPFER_Msb_Index, &gpioconf[i].gpfer_msb_data, 1); + STMPE2401_Read(i, GPFER_Csb_Index, &gpioconf[i].gpfer_csb_data, 1); + STMPE2401_Read(i, GPFER_Lsb_Index, &gpioconf[i].gpfer_lsb_data, 1); + + STMPE2401_Read(i, GPPUR_Msb_Index, &gpioconf[i].gppur_msb_data, 1); + STMPE2401_Read(i, GPPUR_Csb_Index, &gpioconf[i].gppur_csb_data, 1); + STMPE2401_Read(i, GPPUR_Lsb_Index, &gpioconf[i].gppur_lsb_data, 1); + + STMPE2401_Read(i, GPPDR_Msb_Index, &gpioconf[i].gppdr_msb_data, 1); + STMPE2401_Read(i, GPPDR_Csb_Index, &gpioconf[i].gppdr_csb_data, 1); + STMPE2401_Read(i, GPPDR_Lsb_Index, &gpioconf[i].gppdr_lsb_data, 1); + + STMPE2401_Read(i, GPAFR_U_Msb_Index, &gpioconf[i].gpafr_u_msb_data, 1); + STMPE2401_Read(i, GPAFR_U_Csb_Index, &gpioconf[i].gpafr_u_csb_data, 1); + STMPE2401_Read(i, GPAFR_U_Lsb_Index, &gpioconf[i].gpafr_u_lsb_data, 1); + + STMPE2401_Read(i, GPAFR_L_Msb_Index, &gpioconf[i].gpafr_l_msb_data, 1); + STMPE2401_Read(i, GPAFR_L_Csb_Index, &gpioconf[i].gpafr_l_csb_data, 1); + STMPE2401_Read(i, GPAFR_L_Lsb_Index, &gpioconf[i].gpafr_l_lsb_data, 1); + + } + + return err; +} + +static t_STMPE2401_error STMPE2401_Restore_Register_Context(void) + +{ + int i,var; + t_STMPE2401_error err = STMPE2401_OK; + + STMPE2401_WriteByte(0, IER_Msb_Index, 0x01 ); + STMPE2401_WriteByte(0, IER_Lsb_Index, 0x02); + STMPE2401_WriteByte(1, IER_Msb_Index, 0x01 ); + STMPE2401_WriteByte(1, IER_Lsb_Index, 0x0); + + for(i=0; i<2; i++) { + /*syscontrol*/ + STMPE2401_WriteByte(i, SYSCON_Index, syscont[i].syscon_data); + /*Interrupt Conf*/ + STMPE2401_WriteByte(i, ICR_Msb_Index, intconf[i].icr_msb_data); + STMPE2401_WriteByte(i, ICR_Lsb_Index, intconf[i].icr_lsb_data); + STMPE2401_WriteByte(i, ISR_Msb_Index, 0x01 ); + STMPE2401_WriteByte(i, ISR_Lsb_Index, 0x03 ); + + STMPE2401_WriteByte(i, IEGPIOR_Msb_Index, intconf[i].iegpior_msb_data); + STMPE2401_WriteByte(i, IEGPIOR_Csb_Index, intconf[i].iegpior_csb_data); + STMPE2401_WriteByte(i, IEGPIOR_Lsb_Index, intconf[i].iegpior_lsb_data); + STMPE2401_WriteByte(i, ISGPIOR_Msb_Index, 0xFF ); + STMPE2401_WriteByte(i, ISGPIOR_Csb_Index, 0xFF ); + STMPE2401_WriteByte(i, ISGPIOR_Lsb_Index, 0xFF ); + /*Powermanagenet*/ + STMPE2401_WriteByte(i, PWMCS_Index, pwmconf[i].pwmcs_data); + STMPE2401_WriteByte(i, PWMIC0_Index, pwmconf[i].pwmic0_data); + STMPE2401_WriteByte(i, PWMIC1_Index, pwmconf[i].pwmic1_data); + STMPE2401_WriteByte(i, PWMIC2_Index, pwmconf[i].pwmic2_data); + /*GPIO conf*/ + STMPE2401_WriteByte(i, GPMR_Msb_Index, gpioconf[i].gpmr_msb_data); + STMPE2401_WriteByte(i, GPMR_Csb_Index, gpioconf[i].gpmr_csb_data); + STMPE2401_WriteByte(i, GPMR_Lsb_Index, gpioconf[i].gpmr_lsb_data); + + STMPE2401_WriteByte(i, GPSR_Msb_Index, gpioconf[i].gpsr_msb_data); + STMPE2401_WriteByte(i, GPSR_Csb_Index, gpioconf[i].gpsr_csb_data); + STMPE2401_WriteByte(i, GPSR_Lsb_Index, gpioconf[i].gpsr_lsb_data); + + STMPE2401_WriteByte(i, GPCR_Msb_Index, gpioconf[i].gpcr_msb_data); + STMPE2401_WriteByte(i, GPCR_Csb_Index, gpioconf[i].gpcr_csb_data); + STMPE2401_WriteByte(i, GPCR_Lsb_Index, gpioconf[i].gpcr_lsb_data); + + STMPE2401_WriteByte(i, GPDR_Msb_Index, gpioconf[i].gpdr_msb_data); + STMPE2401_WriteByte(i, GPDR_Csb_Index, gpioconf[i].gpdr_csb_data); + STMPE2401_WriteByte(i, GPDR_Lsb_Index, gpioconf[i].gpdr_lsb_data); + + STMPE2401_WriteByte(i, GPEDR_Msb_Index, gpioconf[i].gpedr_msb_data); + STMPE2401_WriteByte(i, GPEDR_Csb_Index, gpioconf[i].gpedr_csb_data); + STMPE2401_WriteByte(i, GPEDR_Lsb_Index, gpioconf[i].gpedr_lsb_data); + + STMPE2401_WriteByte(i, GPRER_Msb_Index, gpioconf[i].gprer_msb_data); + STMPE2401_WriteByte(i, GPRER_Csb_Index, gpioconf[i].gprer_csb_data); + STMPE2401_WriteByte(i, GPRER_Lsb_Index, gpioconf[i].gprer_lsb_data); + + STMPE2401_WriteByte(i, GPFER_Msb_Index, gpioconf[i].gpfer_msb_data); + STMPE2401_WriteByte(i, GPFER_Csb_Index, gpioconf[i].gpfer_csb_data); + STMPE2401_WriteByte(i, GPFER_Lsb_Index, gpioconf[i].gpfer_lsb_data); + + STMPE2401_WriteByte(i, GPPUR_Msb_Index, gpioconf[i].gppur_msb_data); + STMPE2401_WriteByte(i, GPPUR_Csb_Index, gpioconf[i].gppur_csb_data); + STMPE2401_WriteByte(i, GPPUR_Lsb_Index, gpioconf[i].gppur_lsb_data); + + STMPE2401_WriteByte(i, GPPDR_Msb_Index, gpioconf[i].gppdr_msb_data); + STMPE2401_WriteByte(i, GPPDR_Csb_Index, gpioconf[i].gppdr_csb_data); + STMPE2401_WriteByte(i, GPPDR_Lsb_Index, gpioconf[i].gppdr_lsb_data); + + STMPE2401_WriteByte(i, GPAFR_U_Msb_Index, gpioconf[i].gpafr_u_msb_data); + STMPE2401_WriteByte(i, GPAFR_U_Csb_Index, gpioconf[i].gpafr_u_csb_data); + STMPE2401_WriteByte(i, GPAFR_U_Lsb_Index, gpioconf[i].gpafr_u_lsb_data); + + STMPE2401_WriteByte(i, GPAFR_L_Msb_Index, gpioconf[i].gpafr_l_msb_data); + STMPE2401_WriteByte(i, GPAFR_L_Csb_Index, gpioconf[i].gpafr_l_csb_data); + STMPE2401_WriteByte(i, GPAFR_L_Lsb_Index, gpioconf[i].gpafr_l_lsb_data); + + } + + return err; +} +/* + This function is used for disabled callback. + Reduce the danger of execution of null poiter. +*/ +static void EmptyCallback(void *parameter) +{ + +} +/* + * Clean up routine + */ +static int nomadik_stmpe_remove(struct platform_device *pdev) +{ + return 0; +} + +#ifdef CONFIG_PM +int nomadik_stmpe_suspend(struct platform_device *pdev, pm_message_t state) +{ + STMPE2401_Save_Register_Context(); + return 0; +} +int nomadik_stmpe_resume(struct platform_device *pdev) +{ + STMPE2401_Restore_Register_Context(); + STMPE2401_SetGpioAltFunction(STMPE1,EGPIO_PIN_5,STMPE2401_PRIMARY_FUNCTION); + STMPE2401_SetGpioDir( STMPE1,EGPIO_PIN_5,STMPE2401_GPIO_OUT ); + STMPE2401_SetGpioVal( STMPE1, EGPIO_PIN_5, 1); + + return 0; +} +#else +#define nomadik_stmpe_suspend NULL +#define nomadik_stmpe_resume NULL +#endif + +static struct platform_driver nomadik_stmpe_driver = { + .probe = nomadik_stmpe_probe, + .remove = nomadik_stmpe_remove, + .driver = { + .owner = THIS_MODULE, + .name = "NOMADIK-STMPE", + }, + .suspend = nomadik_stmpe_suspend, + .resume = nomadik_stmpe_resume, +}; + +static int __init stmpe_nomadik_init(void) +{ + return platform_driver_register(&nomadik_stmpe_driver); +} + +module_init(stmpe_nomadik_init); +static void __exit stmpe_nomadik_exit(void) +{ + platform_driver_unregister(&nomadik_stmpe_driver); + return; +} + +module_exit(stmpe_nomadik_exit); + +EXPORT_SYMBOL(STMPE2401_ClearGpioEdgeStatus); +EXPORT_SYMBOL(STMPE2401_SetGpioEdgeDetect); +EXPORT_SYMBOL(STMPE2401_Install_Callback); +EXPORT_SYMBOL(STMPE2401_SetGpioDir); +EXPORT_SYMBOL(STMPE2401_SetGpioAltFunction); +EXPORT_SYMBOL(STMPE2401_InterruptSourceAbilitation); +EXPORT_SYMBOL(STMPE2401_InterruptAbilitation); +EXPORT_SYMBOL(STMPE2401_GetGpioVal); +EXPORT_SYMBOL(STMPE2401_SetGpioVal); +EXPORT_SYMBOL(STMPE2401_Read); +EXPORT_SYMBOL(STMPE2401_Acknowledge); +EXPORT_SYMBOL(STMPE2401_SetGpioPull); +EXPORT_SYMBOL(STMPE2401_reboot); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("ST Microelectronics"); +MODULE_DESCRIPTION("STMPE driver for Nomadik Platform"); --- /dev/null +++ linux-2.6.20/drivers/misc/sif-nomadik.c @@ -0,0 +1,560 @@ +/* + * Overview: + * Driver for CLCD protocol on Nomadik Platforms + * + * Copyright (C) 2007 STMicroelectronics Pvt. Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#define SIF_SDA GPIO_PIN_4 +#define SIF_SCL GPIO_PIN_5 +#define SIF_SCEN GPIO_PIN_6 + +#define SIF_MINOR 22 + +struct contrast { + + unsigned char r; + unsigned char g; + unsigned char b; +}; +struct bright { + + unsigned char r; + unsigned char g; + unsigned char b; +}; + +struct gamma { + + unsigned char gamma0; + unsigned char gamma8; + unsigned char gamma16; + unsigned char gamma32; + unsigned char gamma64; + unsigned char gamma96; + unsigned char gamma128; + unsigned char gamma192; + unsigned char gamma224; + unsigned char gamma240; + unsigned char gamma248; + unsigned char gamma256; + +}; + +#define SIF_IOC_MAGIC 'f' +#define SIF_READ_CHIP_ID_REV _IOR(SIF_IOC_MAGIC, 45, int) +#define SIF_CONTRAST _IOW(SIF_IOC_MAGIC, 46, struct contrast) +#define SIF_BRIGHTNESS _IOW(SIF_IOC_MAGIC, 47,struct bright) +#define SIF_GAMMA_CORRECTION _IOW(SIF_IOC_MAGIC, 48,struct gamma) + +/*SIF offsets. Naming convention just considering the first MSB:(*/ +#define SIF_CHIPID_VER 0x01 +#define SIF_DIM 0x02 +#define SIF_HW_RES_STDBY 0x03 +#define SIF_VGL_PUMP_FREQ 0x04 +#define SIF_HOR_SYNC 0x05 +#define SIF_VER_SYNC 0x06 +#define SIF_CKH_HPW 0x07 +#define SIF_CKH_NONOVRLAP 0x08 +#define SIF_ENB_CKH_NNOVRLAP 0x09 +#define SIF_ENB_LPW 0x0A +/*contrast*/ +#define SIF_RGAIN_CONTRAST 0x0B +#define SIF_GGAIN_CONTRAST 0x0C +#define SIF_BGAIN_CONTRAST 0x0D +/*brightness*/ +#define SIF_OFFSET_RBRIGHTNESS 0x0E +#define SIF_OFFSET_GBRIGHTNESS 0x0F +#define SIF_OFFSET_BBRIGHTNESS 0x10 +/*gama*/ +#define SIF_GAMMA0_32 0x11 +#define SIF_GAMMA64_192 0x12 +#define SIF_GAMMA224_256 0x13 + +#define SIF_GAMMA0 0x14 +#define SIF_GAMMA8 0x15 +#define SIF_GAMMA16 0x16 +#define SIF_GAMMA32 0x17 +#define SIF_GAMMA64 0x18 +#define SIF_GAMMA96 0x19 +#define SIF_GAMMA128 0x1A +#define SIF_GAMMA192 0x1B +#define SIF_GAMMA224 0x1C +#define SIF_GAMMA240 0x1D +#define SIF_GAMMA248 0x1E +#define SIF_GAMMA256 0x1F + +#define SIF_GAMMA_PVOLTAGE 0x20 +#define SIF_GAMMA_NVOLTAGE 0x21 +#define SIF_DC_VCOM 0x22 + + +/*file operation members*/ +static int nomadik_sif_ioctl(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg); +static int nomadik_sif_open(struct inode *inode, struct file *filp); +static int nomadik_sif_release(struct inode *inode, struct file *filp); + +/*dummy sif delay*/ +static void sif_wait150ns() +{ + int i; + for(i=0;i<100;i++) + {} +} +/*Read protocol*/ +static unsigned char sif_read_databit() +{ + gpio_data gpio_value;int ret; + unsigned char bit; + sif_wait150ns(); // setup time + ret = nomadik_gpio_writepin(SIF_SCL,1,"sif"); + if (ret) { + printk("1)Error in setting GPIO_PIN_05"); + } + + + //GPIO_SetGpioPin(scl); + nomadik_gpio_readpin(SIF_SDA,&gpio_value); + //GPIO_ReadGpioPin(sda,&gpio_value); + switch(gpio_value) + { + case GPIO_DATA_LOW: + bit=0; + break; + case GPIO_DATA_HIGH: + bit=1; + break; + default: + break; + } + sif_wait150ns(); // hold time + //GPIO_ClearGpioPin(scl); + nomadik_gpio_writepin(SIF_SCL,0,"sif"); + + return bit; +} + +/*Write protocol*/ +static void sif_write_databit(unsigned char bit) +{ + int ret; + switch(bit) + { + case 1: + //GPIO_SetGpioPin(sda); + ret = nomadik_gpio_writepin(SIF_SDA,1,"sif"); + if (ret) { + printk("2)Error in setting GPIO_PIN_04"); + } + break; + case 0: + //GPIO_ClearGpioPin(sda); + nomadik_gpio_writepin(SIF_SDA,0,"sif"); + break; + default: + break; + } + sif_wait150ns(); // setup time + ret = nomadik_gpio_writepin(SIF_SCL,1,"sif"); + if (ret) { + printk("3)Error in setting GPIO_PIN_05"); + } + //GPIO_SetGpioPin(scl); + sif_wait150ns(); // hold time + + nomadik_gpio_writepin(SIF_SCL,0,"sif"); + //GPIO_ClearGpioPin(scl); +} + +/*Read from the offset*/ +int sif_read(unsigned char index, unsigned char* p_databyte) +{ + int i,result=0, ret=0; + gpio_config gpio_config; + unsigned char bit=0; + + *p_databyte = 0x0; +/* + gpio_config.dev_name = "sif"; + gpio_config.mode = GPIO_MODE_SOFTWARE; + gpio_config.direction = GPIO_DIR_OUTPUT; + gpio_config.trig = GPIO_TRIG_LEAVE_UNCHANGED; + gpio_config.debounce = GPIO_DEBOUNCE_UNCHANGED; + //GPIO_SetPinConfig(sda,gpio_config); + ret = nomadik_gpio_setpinconfig(SIF_SDA, &gpio_config); + if (ret) { + printk("Error in setting GPIO_PIN_04"); + } +*/ + sif_wait150ns(); + // start + //GPIO_ClearGpioPin(scen); + nomadik_gpio_writepin(SIF_SCEN,0,"sif"); + + // transmitting index + sif_write_databit((index>>5) & 0x1); + sif_write_databit((index>>4) & 0x1); + sif_write_databit((index>>3) & 0x1); + sif_write_databit((index>>2) & 0x1); + sif_write_databit((index>>1) & 0x1); + sif_write_databit((index) & 0x1); + + // Read bit + sif_write_databit(1); + + + nomadik_gpio_resetpinconfig(SIF_SDA, "sif"); + + // turn-round cycle + gpio_config.dev_name = "sif"; + gpio_config.mode = GPIO_MODE_SOFTWARE; + gpio_config.direction = GPIO_DIR_INPUT; + gpio_config.trig = GPIO_TRIG_LEAVE_UNCHANGED; + gpio_config.debounce = GPIO_DEBOUNCE_UNCHANGED; + + //GPIO_SetPinConfig(sda,gpio_config); + ret = nomadik_gpio_setpinconfig(SIF_SDA, &gpio_config); + if (ret) { + printk("4)Error in setting GPIO_PIN_04"); + } + + sif_wait150ns(); // setup time + //GPIO_SetGpioPin(scl); + + ret = nomadik_gpio_writepin(SIF_SCL, 1, "sif"); + //ret = nomadik_gpio_setpinconfig(SIF_SCL, &sif_pin); + if (ret) { + printk("5)Error in setting GPIO_PIN_05"); + } + + sif_wait150ns(); // hold time + //GPIO_ClearGpioPin(scl); + nomadik_gpio_writepin(SIF_SCL,0,"sif"); + // receiving data byte + for(i=7;i>=0;i--) + { + bit = sif_read_databit(); + *p_databyte = *p_databyte | (bit << i); + } + + /* + *p_databyte = *p_databyte | (sif_read_databit() << 7); + *p_databyte = *p_databyte | (sif_read_databit() << 6); + *p_databyte = *p_databyte | (sif_read_databit() << 5); + *p_databyte = *p_databyte | (sif_read_databit() << 4); + *p_databyte = *p_databyte | (sif_read_databit() << 3); + *p_databyte = *p_databyte | (sif_read_databit() << 2); + *p_databyte = *p_databyte | (sif_read_databit() << 1); + *p_databyte = *p_databyte | (sif_read_databit() << 0); + */ + sif_wait150ns(); + //GPIO_SetGpioPin(scen); + ret = nomadik_gpio_writepin(SIF_SCEN, 1, "sif"); + if (ret) { + printk("6)Error in setting GPIO_PIN_06"); + } + + udelay(100); + return 0; + +} + +static void sif_write(unsigned char index, unsigned char databyte) +{ + int ret; + gpio_config sif_pin; + + sif_pin.dev_name = "sif"; + sif_pin.mode = GPIO_MODE_SOFTWARE; + sif_pin.direction = GPIO_DIR_OUTPUT; + //sif_pin.trig = GPIO_TRIG_DISABLE; + //sif_pin.debounce = GPIO_DEBOUNCE_DISABLE; + + sif_pin.trig = GPIO_TRIG_LEAVE_UNCHANGED; + sif_pin.debounce = GPIO_DEBOUNCE_UNCHANGED; + +/* ret = nomadik_gpio_setpinconfig(SIF_SDA, &sif_pin); + if (ret) { + printk("7)Error in setting GPIO_PIN_04"); + } +*/ + //udelay(100); + sif_wait150ns(); + + nomadik_gpio_writepin(SIF_SCEN,0,"sif"); + + // transmitting index + sif_write_databit((index>>5) & 0x1); + sif_write_databit((index>>4) & 0x1); + sif_write_databit((index>>3) & 0x1); + sif_write_databit((index>>2) & 0x1); + sif_write_databit((index>>1) & 0x1); + sif_write_databit((index) & 0x1); + + // Write bit + sif_write_databit(0); + + // turn-round cycle + sif_write_databit(0); + + // transmitting data byte + sif_write_databit((databyte>>7)&0x1); + sif_write_databit((databyte>>6)&0x1); + sif_write_databit((databyte>>5)&0x1); + sif_write_databit((databyte>>4)&0x1); + sif_write_databit((databyte>>3)&0x1); + sif_write_databit((databyte>>2)&0x1); + sif_write_databit((databyte>>1)&0x1); + sif_write_databit((databyte>>0)&0x1); + + //udelay(100); + sif_wait150ns(); + + ret = nomadik_gpio_writepin(SIF_SCEN,1,"sif"); + if (ret) { + printk("8)Error in setting GPIO_PIN_06"); + } +} + +static int nomadik_sif_ioctl(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg) +{ + int err = 0; + int rval = 0; + unsigned char byte_val; + struct contrast ctr; + struct bright bright; + struct gamma gamma; + + + if (_IOC_DIR(cmd) & _IOC_READ) + err = !access_ok(VERIFY_WRITE, (void *)arg, _IOC_SIZE(cmd)); + else if (_IOC_DIR(cmd) & _IOC_WRITE) + err = !access_ok(VERIFY_READ, (void *)arg, _IOC_SIZE(cmd)); + if (err) + return -EFAULT; + + switch (cmd) { + + case SIF_READ_CHIP_ID_REV: + //copy_from_user(&bklight ,argp, sizeof(int)); + //sif_read(SIF_CHIPID_VER,&byte_val); + //copy_to_user(arg,byte_val,1); + break; + case SIF_CONTRAST: + { + int __user *argp = (struct contrast __user *)arg; + if (copy_from_user(&ctr ,argp, sizeof(struct contrast))) + return -EFAULT; + + printk("RGB contrast = %x %x %x\n",ctr.r,ctr.g, ctr.b); + sif_write(SIF_RGAIN_CONTRAST,ctr.r); + sif_write(SIF_GGAIN_CONTRAST,ctr.g); + sif_write(SIF_BGAIN_CONTRAST,ctr.b); + } + break; + case SIF_BRIGHTNESS: + { + int __user *argp = (struct bright __user *)arg; + if (copy_from_user(&bright ,argp, sizeof(struct bright))) + return -EFAULT; + + printk("RGB brightness = %x %x %x\n",bright.r,bright.g,bright.b); + sif_write(SIF_OFFSET_RBRIGHTNESS,bright.r); + sif_write(SIF_OFFSET_GBRIGHTNESS,bright.g); + sif_write(SIF_OFFSET_BBRIGHTNESS,bright.b); + } + break; + + case SIF_GAMMA_CORRECTION: + { + int __user *argp = (struct gamma __user *)arg; + + if (copy_from_user(&gamma ,argp, sizeof(struct gamma))) + return -EFAULT; + + printk("gamma values = %x %x %x %x %x %x %x %x %x %x %x %x\n",gamma.gamma0,gamma.gamma8,gamma.gamma16,gamma.gamma32,gamma.gamma64,gamma.gamma96,gamma.gamma128,gamma.gamma192,gamma.gamma224,gamma.gamma240,gamma.gamma248,gamma.gamma256); + + sif_write(SIF_GAMMA0, gamma.gamma0); + sif_write(SIF_GAMMA8, gamma.gamma8); + sif_write(SIF_GAMMA16, gamma.gamma16); + sif_write(SIF_GAMMA32, gamma.gamma32); + sif_write(SIF_GAMMA64, gamma.gamma64); + sif_write(SIF_GAMMA96, gamma.gamma96); + sif_write(SIF_GAMMA128, gamma.gamma128); + sif_write(SIF_GAMMA192, gamma.gamma192); + sif_write(SIF_GAMMA224, gamma.gamma224); + sif_write(SIF_GAMMA240, gamma.gamma240); + sif_write(SIF_GAMMA248, gamma.gamma248); + sif_write(SIF_GAMMA256, gamma.gamma256); + } + break; + default: + return -EINVAL; + } + return 0; +} +/** + * nomadik_sif_open - open sys call for sif device + * @inode: pointer to the inode structure for the sif device + * @filp: pointer to the file structure for the sif device + * + * This function opens the sif device for file operations. + */ +static int nomadik_sif_open(struct inode *inode, struct file *filp) +{ + return (0); +} + +/** + * nomadik_sif_release - close sys call for sif device + * @inode: pointer to the inode structure for the sif device + * @filp: pointer to the file structure for the sif device + * + * This function is called when the sif device is closed. + */ +static int nomadik_sif_release(struct inode *inode, struct file *filp) +{ + return (0); +} + +/** + * struct file_operations sif_fops - user space file operations + * + * Define (fill in) the user space file operations for this driver + * and initialize the sif driver as a "miscdevice": + * Character device + * Major(10) --- Non-serial mice, misc features + * Minor(22) --- /dev/sif + */ +static struct file_operations sif_fops = { + owner:THIS_MODULE, + ioctl:nomadik_sif_ioctl, + open:nomadik_sif_open, + release:nomadik_sif_release, +}; + +static struct miscdevice sif_dev = { + minor:SIF_MINOR, + name:"sif", + fops:&sif_fops, +}; + +static int __init sif_nomadik_init(void) +{ + int ret=0; + unsigned char byte_value; + + gpio_config sif_pin; + sif_pin.dev_name = "sif"; + sif_pin.mode = GPIO_MODE_SOFTWARE; + sif_pin.direction = GPIO_DIR_OUTPUT; + sif_pin.trig = GPIO_TRIG_LEAVE_UNCHANGED; + sif_pin.debounce = GPIO_DEBOUNCE_UNCHANGED; + + ret = nomadik_gpio_setpinconfig(SIF_SDA, &sif_pin); + if (ret) { + printk("9)Error in setting GPIO_PIN_04"); + } + + ret = nomadik_gpio_setpinconfig(SIF_SCL, &sif_pin); + if (ret) { + printk("10)Error in setting GPIO_PIN_05"); + } + ret = nomadik_gpio_setpinconfig(SIF_SCEN, &sif_pin); + if (ret) { + printk("11)Error in setting SIF_SCEN"); + } + udelay(100); + + + nomadik_gpio_writepin(SIF_SDA,0,"sif"); + nomadik_gpio_writepin(SIF_SCL,0,"sif"); + nomadik_gpio_writepin(SIF_SCEN,1,"sif"); + + + ret = misc_register(&sif_dev); + if (ret) { + printk("%s: could not register sif erro =%d", __FILE__, + ret); + return ret; + } + /*set the default brightness and contrast*/ + sif_write(SIF_RGAIN_CONTRAST,24); + sif_write(SIF_GGAIN_CONTRAST,23); + sif_write(SIF_BGAIN_CONTRAST,23); + + sif_write(SIF_OFFSET_RBRIGHTNESS,63); + sif_write(SIF_OFFSET_GBRIGHTNESS,63); + sif_write(SIF_OFFSET_BBRIGHTNESS,63); + + /*set the default gamma values */ + sif_write(SIF_GAMMA0, 0); //gamma.gamma0); + sif_write(SIF_GAMMA8,130); // gamma.gamma8); + sif_write(SIF_GAMMA16, 190); //gamma.gamma16); + sif_write(SIF_GAMMA32, 255); //gamma.gamma32); + sif_write(SIF_GAMMA64, 170); //gamma.gamma64); + sif_write(SIF_GAMMA96, 255); //gamma.gamma96); + sif_write(SIF_GAMMA128, 100);//gamma.gamma128); + sif_write(SIF_GAMMA192, 20); //gamma.gamma192); + sif_write(SIF_GAMMA224, 128);//gamma.gamma224); + sif_write(SIF_GAMMA240, 192);//gamma.gamma240); + sif_write(SIF_GAMMA248, 224);//gamma.gamma248); + sif_write(SIF_GAMMA256, 255);//gamma.gamma256); + + + printk("loaded SIF driver...\n"); + return 0; + //return platform_driver_register(&nomadik_sif_driver); +} + +module_init(sif_nomadik_init); +static void __exit sif_nomadik_exit(void) +{ + + nomadik_gpio_resetpinconfig(SIF_SDA, "sif"); + nomadik_gpio_resetpinconfig(SIF_SCL, "sif"); + nomadik_gpio_resetpinconfig(SIF_SCEN, "sif"); + misc_deregister(&sif_dev); + return; +} + +module_exit(sif_nomadik_exit); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("ST Microelectronics"); +MODULE_DESCRIPTION("CLCD proptocol driver for Nomadik Platform"); --- linux-2.6.20.orig/drivers/mmc/Kconfig +++ linux-2.6.20/drivers/mmc/Kconfig @@ -123,6 +123,33 @@ config MMC_TIFM_SD (TIFM_7XX1)'. To compile this driver as a module, choose M here: the module will be called tifm_sd. +config MMC_NOMADIK + tristate "Nomadik MMC Card Interface support" + depends on ARM_AMBA && MMC && ARCH_NOMADIK && NOMADIK_DMA + help + This selects the Nomadik Multimedia card interface. + If you have a Nomadik platform with a MMC slot, say Y or M here. + Depends on Nomadik DMA driver. + + If unsure, say N. + choice + prompt "Driver mode" + depends on MMC_NOMADIK + default NOMADIK_MMC_DMA + + config NOMADIK_MMC_DMA + depends on MMC_NOMADIK + bool "DMA mode" + + config NOMADIK_MMC_POLL + depends on MMC_NOMADIK + bool "Polling mode" + + config NOMADIK_MMC_INTR + depends on MMC_NOMADIK + bool "Interrupt mode" + endchoice + endmenu --- linux-2.6.20.orig/drivers/mmc/Makefile +++ linux-2.6.20/drivers/mmc/Makefile @@ -4,25 +4,26 @@ # # Core # obj-$(CONFIG_MMC) += mmc_core.o - # # Media drivers # obj-$(CONFIG_MMC_BLOCK) += mmc_block.o - # # Host drivers # obj-$(CONFIG_MMC_ARMMMCI) += mmci.o obj-$(CONFIG_MMC_PXA) += pxamci.o -obj-$(CONFIG_MMC_IMX) += imxmmc.o -obj-$(CONFIG_MMC_SDHCI) += sdhci.o obj-$(CONFIG_MMC_WBSD) += wbsd.o obj-$(CONFIG_MMC_AU1X) += au1xmmc.o +obj-$(CONFIG_MMC_NOMADIK) += nmdkmod_mmc.o + +nmdkmod_mmc-objs := mmc-nomadik.o +obj-$(CONFIG_MMC_IMX) += imxmmc.o +obj-$(CONFIG_MMC_SDHCI) += sdhci.o obj-$(CONFIG_MMC_OMAP) += omap.o obj-$(CONFIG_MMC_AT91) += at91_mci.o obj-$(CONFIG_MMC_TIFM_SD) += tifm_sd.o mmc_core-y := mmc.o mmc_sysfs.o --- /dev/null +++ linux-2.6.20/drivers/mmc/mmc-nomadik.c @@ -0,0 +1,1435 @@ +/* + * linux/drivers/mmc/mmc-nomadik.c - ARM PrimeCell MMCI PL180 driver + * + * Support for MMC/SD card on STn8810/8815 (Nomadik) chips. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#define DRIVER_NAME "NMDK_MMC" + +//#define DMA_SCATERGATHER + +/* + #define CONFIG_MMC_DEBUG_NOMADIK + */ +#define DERRPRINTK( s, args... ) printk( KERN_ERR s, ##args ) + +/* + * Added for having the option of removing only success leg messages + */ + +#ifdef CONFIG_MMC_DEBUG_NOMADIK +#define DEBUG( s, args... ) printk( KERN_WARNING s, ##args ) +#else +#define DEBUG( x... ) +#endif + +#if defined CONFIG_NOMADIK_MMC_POLL +const int devicemode = MCI_POLLINGMODE; +#elif defined CONFIG_NOMADIK_MMC_INTR +const int devicemode = MCI_INTERRUPTMODE; +#elif defined CONFIG_NOMADIK_MMC_DMA +const int devicemode = MCI_DMAMODE; +#endif + +#if !defined CONFIG_NOMADIK_MMC_INTR +static unsigned int fmax = CLK_MAX / 2; +#else +static unsigned int fmax = CLK_MAX / 8; +#endif + +static struct amba_device *nomadik_mmc_dev = NULL; + +static u16 data_length; +static int dma_flag_error = 0; + +static void nomadik_mmci_start_command(struct nomadik_mmci_host *host, + struct mmc_command *cmd); +static void nomadik_mmci_data_irq(struct nomadik_mmci_host *host, + u32 hoststatus); +static void nomadik_mmci_cmd_irq(struct nomadik_mmci_host *host, + u32 hoststatus); + +/* + * Taken for DMA + */ +dmach_t dmach_mem2mmc = INVALID_PIPEID; +dmach_t dmach_mmc2mem = INVALID_PIPEID; + +#if defined CONFIG_NOMADIK_MMC_DMA +#define MMC_LOCK(lock,flag) spin_lock(&lock) +#define MMC_UNLOCK(lock,flag) spin_unlock(&lock) +#else +#define MMC_LOCK(lock,flag) spin_lock_irqsave(&lock,flag) +#define MMC_UNLOCK(lock,flag) spin_unlock_irqrestore(&lock,flag) +#endif + +static inline void +nomadik_mmci_init_sg(struct nomadik_mmci_host *host, struct mmc_data *data) +{ + /* + * Ideally, we want the higher levels to pass us a scatter list. + */ + host->sg_len = data->sg_len; + host->sg_ptr = data->sg; + host->sg_off = 0; +} + +static inline void nomadik_mmc_clearirqsrc(void *base, u32 irqsrc) +{ + u32 nmdk_reg; + + nmdk_reg = readl(base + MMCICLEAR); + nmdk_reg |= irqsrc; + writel(nmdk_reg, (base + MMCICLEAR)); +} + +static inline void nomadik_mmc_disableirqsrc(void *base, u32 irqsrc) +{ + u32 nmdk_reg; + + nmdk_reg = readl(base + MMCIMASK0); + nmdk_reg &= ~irqsrc; + writel(nmdk_reg, (base + MMCIMASK0)); +} + +static inline void nomadik_mmc_enableirqsrc(void *base, u32 irqsrc) +{ + u32 nmdk_reg; + + nmdk_reg = readl(base + MMCIMASK0); + nmdk_reg |= irqsrc; + writel(nmdk_reg, (base + MMCIMASK0)); +} + +static void +nomadik_mmci_request_end(struct nomadik_mmci_host *host, + struct mmc_request *mrq) +{ +#ifndef CONFIG_NOMADIK_MMC_DMA + unsigned long flag_lock = 0; +#endif + MMC_LOCK(host->lock, flag_lock); + host->mrq = NULL; + host->cmd = NULL; + if (mrq->data) + mrq->data->bytes_xfered = host->data_xfered; + /* + * Need to drop the host lock here; mmc_request_done may call + * back into the driver... + */ + MMC_UNLOCK(host->lock, flag_lock); + mmc_request_done(host->mmc, mrq); +} + +static void nomadik_mmci_stop_data(struct nomadik_mmci_host *host) +{ +#ifndef CONFIG_NOMADIK_MMC_DMA + unsigned long flag_lock = 0; +#endif + MMC_LOCK(host->lock, flag_lock); + writel(0, host->base + MMCIDATACTRL); + writel(0, host->base + MMCIMASK1); + host->data = NULL; + MMC_UNLOCK(host->lock, flag_lock); +} + +static void nomadik_mmc_send_cmd(void *base, u32 cmd, u32 arg, u32 flags) +{ + u32 c, irqmask; + + DEBUG("Sending CMD%d, arg=%08x\n", cmd, arg); + + /* Clear any previous command */ + if ((readl(base + MMCICOMMAND) & MCI_CPSM_ENABLE)) { + writel(0, (base + MMCICOMMAND)); + udelay(1); + } + + c = cmd | MCI_CPSM_ENABLE; + irqmask = MCI_CMDCRCFAIL | MCI_CMDTIMEOUT; + if (flags & MMC_RSP_PRESENT) { + if (flags & MMC_RSP_136) { + c |= MCI_CPSM_LONGRSP; + } + c |= MCI_CPSM_RESPONSE; + irqmask |= MCI_CMDRESPEND; + } else { + irqmask |= MCI_CMDSENT; + } + if ( /*interrupt */ 0) + c |= MCI_CPSM_INTERRUPT; + + writel(arg, (base + MMCIARGUMENT)); + writel(c, (base + MMCICOMMAND)); + if (devicemode != MCI_POLLINGMODE) { + nomadik_mmc_enableirqsrc(base, irqmask); + } +} + +static void process_command_end(struct nomadik_mmci_host *host, u32 hoststatus) +{ + struct mmc_command *cmd; + void __iomem *base; + + base = host->base; + cmd = host->cmd; + + nomadik_mmc_disableirqsrc(base, MCI_CMD_IRQ); + nomadik_mmc_clearirqsrc(base, MCI_CMD_IRQ); + + cmd->resp[0] = readl(base + MMCIRESPONSE0); + cmd->resp[1] = readl(base + MMCIRESPONSE1); + cmd->resp[2] = readl(base + MMCIRESPONSE2); + cmd->resp[3] = readl(base + MMCIRESPONSE3); + + if ((hoststatus & MCI_CMDTIMEOUT)) { + DEBUG("Command Timeout\n"); + cmd->error = MMC_ERR_TIMEOUT; + } else if ((hoststatus & MCI_CMDCRCFAIL) && (cmd->flags & MMC_RSP_CRC)) { + DEBUG("Command CRC Fail\n"); + cmd->error = MMC_ERR_BADCRC; + } else if ((cmd->flags & MMC_RSP_OPCODE) && + readl(base + MMCIRESPCMD) != cmd->opcode) { + DEBUG("Command failed opcode check\n"); + cmd->error = MMC_ERR_INVALID; + } else { + cmd->error = MMC_ERR_NONE; + } + DEBUG("CMD%d error=%d response:0x%08x 0x%08x 0x%08x 0x%08x\n", + cmd->opcode, cmd->error, cmd->resp[0], cmd->resp[1], cmd->resp[2], + cmd->resp[3]); +} + +static void wait_for_command_end(struct nomadik_mmci_host *host) +{ + u32 hoststatus, statusmask; + struct mmc_command *cmd; + void __iomem *base; + + base = host->base; + cmd = host->cmd; + + statusmask = MCI_CMDTIMEOUT | MCI_CMDCRCFAIL; + if ((cmd->flags & MMC_RSP_PRESENT)) { + statusmask |= MCI_CMDRESPEND; + } else { + statusmask |= MCI_CMDSENT; + } + + do { + hoststatus = readl(base + MMCISTATUS) & statusmask; + } while (!hoststatus); + + nomadik_mmci_cmd_irq(host, hoststatus); +} + +static int check_for_data_err(u32 hoststatus) +{ + int error = MMC_ERR_NONE; + if (hoststatus & + (MCI_DATACRCFAIL | MCI_DATATIMEOUT | MCI_TXUNDERRUN | MCI_RXOVERRUN + | MCI_STBITERR)) { + if ((hoststatus & MCI_DATATIMEOUT)) + error = MMC_ERR_TIMEOUT; + + else if (hoststatus & MCI_DATACRCFAIL) + error = MMC_ERR_BADCRC; + + else if (hoststatus & MCI_RXOVERRUN) + error = MMC_ERR_FIFO; + + else if (hoststatus & MCI_TXUNDERRUN) + error = MMC_ERR_FIFO; + + else if (hoststatus & MCI_STBITERR) + error = MMC_ERR_FAILED; + } + return error; +} + + +static irqreturn_t nomadik_mmc_dmaclbk(int irq, void *dev_id) +{ + struct nomadik_mmci_host *host = dev_id; + complete(host->dma_done); + return IRQ_HANDLED; +} + +static void nomadik_mmc_dmaclbk1(struct nomadik_mmci_host *host) +{ + int dma_error; + struct mmc_data *data; + void __iomem *base; + u32 hoststatus; + + base = host->base; + data = host->data; + + if (dma_flag_error) { + data->error = MMC_ERR_BADCRC; + goto out; + } else + dma_error = MMC_ERR_NONE; + + { + spin_lock(&host->lock); + host->data_xfered += data_length; + spin_unlock(&host->lock); + + if (host->data_xfered < host->size) { + /* + * We hit an error condition. Ensure that any data + * partially written to a page is properly coherent. + */ + flush_dcache_page(host->sg_ptr->page); + data->error = MMC_ERR_FAILED; + goto out; + } + + nomadik_mmci_stop_data(host); + DEBUG("DMA_EVENT_TC \ndata transferred is %d\n", + host->data_xfered); + hoststatus = (readl(base + MMCISTATUS) & MCI_ALLINTERRUPTS); + if (host->data_xfered == host->size) + data->error = check_for_data_err(hoststatus); + + if ((data->error == MMC_ERR_NONE) + && (host->data_xfered == host->size)) + DEBUG("No error in Read / Write \n"); + + if (data->error) + DERRPRINTK("Error while DMA, data error is %d\n", + data->error); + nomadik_mmc_clearirqsrc(base, MMCCLRSTATICFLAGS); + if (!data->stop) + nomadik_mmci_request_end(host, data->mrq); + else + nomadik_mmci_start_command(host, data->stop); + } + out: + if (data->error != MMC_ERR_NONE) { + if (!data->stop) + nomadik_mmci_request_end(host, data->mrq); + else + nomadik_mmci_start_command(host, data->stop); + } +#ifdef DMA_SCATERGATHER + dma_unmap_sg(mmc_dev(host->mmc),data->sg,data->sg_len, + ((data->flags & MMC_DATA_READ) ? + DMA_FROM_DEVICE: DMA_TO_DEVICE) ); +#endif +} + +static void nomadik_mmc_set_dma(struct nomadik_mmci_host *host) +{ + struct mmc_data *data; +#ifndef DMA_SCATERGATHER + u32 *buffer, *ptr; + unsigned long flag_lock = 0; +#endif + + data = host->data; +#ifdef DMA_SCATERGATHER + dma_map_sg(mmc_dev(host->mmc), data->sg, + data->sg_len, ((data->flags & MMC_DATA_READ) + ? DMA_FROM_DEVICE: DMA_TO_DEVICE)); +#else + spin_lock_irqsave(&host->lock, flag_lock); + ptr = (void *)(page_address(host->sg_ptr->page) + host->sg_ptr->offset); + buffer = (u32 *) virt_to_dma(NULL, ptr); + spin_unlock_irqrestore(&host->lock, flag_lock); +#endif + data_length = host->size; + if (data->flags & MMC_DATA_READ) { + set_dma_count(dmach_mmc2mem, data_length); +#ifdef DMA_SCATERGATHER + set_dma_sg(dmach_mmc2mem, data->sg, data->sg_len); +#else + __set_dma_destaddr(dmach_mmc2mem, (physical_address *) buffer); +#endif + /* before enable_dma make sure count are set properly*/ + while(dma_channel_active(dmach_mmc2mem)); + enable_dma(dmach_mmc2mem); + } else { + set_dma_count(dmach_mem2mmc, data_length); +#ifdef DMA_SCATERGATHER + set_dma_sg(dmach_mem2mmc, data->sg, data->sg_len); +#else + __set_dma_srcaddr(dmach_mem2mmc, (physical_address *) buffer); +#endif + /* before enable_dma make sure count are set properly*/ + while(dma_channel_active(dmach_mem2mmc)); + enable_dma(dmach_mem2mmc); + } +} + +static int nomadik_mmci_read(struct nomadik_mmci_host *host, u32 * buffer, + unsigned int remain, u32 hoststatus) +{ + void __iomem *base; + int count, max_count; + unsigned int data_xfered = 0; + + base = host->base; + while ((remain > 0) && !(hoststatus & MCI_DATA_IRQ)) { + + if ((hoststatus & MCI_RXFIFOHALFFULL) && (remain >= 32)) + max_count = MCI_FIFOHALFSIZE; + else if ((hoststatus & MCI_RXDATAAVLBL) && (remain < 32)) + max_count = 1; + else + max_count = 0; + + for (count = 0; count < max_count; count++) { + *buffer = readl(base + MMCIFIFO); + buffer++; + data_xfered += 4; + remain -= 4; + } + + hoststatus = readl(base + MMCISTATUS); + } + if (remain) { + DEBUG + ("While READ, Remain is %d, hoststatus is %x, data_xfered is %d\n", + remain, hoststatus, data_xfered); + } + + return data_xfered; +} + +static int nomadik_mmci_write(struct nomadik_mmci_host *host, u32 * buffer, + unsigned int remain, u32 hoststatus) +{ + void __iomem *base; + int count, max_count; + unsigned int data_xfered = 0; + + base = host->base; + + while ((remain > 0) && !(hoststatus & MCI_DATA_IRQ)) { + if ((hoststatus & MCI_TXFIFOEMPTY) && (remain >= 64)) + max_count = MCI_FIFOSIZE; + else if ((hoststatus & MCI_TXFIFOHALFEMPTY) && (remain >= 32)) + max_count = MCI_FIFOHALFSIZE; + else if (remain < 32) + max_count = 1; + else + max_count = 0; + + for (count = 0; count < max_count; count++) { + writel(*buffer, (base + MMCIFIFO)); + buffer++; + data_xfered += 4; + remain -= 4; + } + + hoststatus = readl(base + MMCISTATUS); + } + if (remain) { + DEBUG + ("While WRITE, Remain is %d, hoststatus is %x, data_xfered is %d\n", + remain, hoststatus, data_xfered); + } + + return data_xfered; +} + +static void nomadik_mmci_read_write(struct nomadik_mmci_host *host) +{ + void __iomem *base; + u32 *buffer; + u32 hoststatus; + struct mmc_data *data; + unsigned int remain, len; + unsigned long flags; + + base = host->base; + data = host->data; + + hoststatus = readl(base + MMCISTATUS); + + while (host->data_xfered < host->size && + (hoststatus & (MCI_TXFIFOHALFEMPTY | MCI_RXDATAAVLBL))) { + /*Do not add any printk or DEBUG at this location */ + if (data->flags & MMC_DATA_READ) { + buffer = host->buffer; + remain = host->size; + } else { + buffer = + (u32 *) (page_address(host->sg_ptr->page) + + host->sg_ptr->offset) + host->sg_off; + remain = host->sg_ptr->length - host->sg_off; + } + + if (devicemode == MCI_POLLINGMODE) + local_irq_save(flags); + len = 0; + if (hoststatus & MCI_RXACTIVE) { + len = + nomadik_mmci_read(host, buffer, remain, hoststatus); + } else if (hoststatus & MCI_TXACTIVE) { + len = + nomadik_mmci_write(host, buffer, remain, + hoststatus); + } + + if (devicemode == MCI_POLLINGMODE) + local_irq_restore(flags); + + spin_lock(&host->lock); + host->sg_off += len; + host->data_xfered += len; + remain -= len; + + if (remain) { + DEBUG + ("Remain is %d, hoststatus is %x, host->size is %d, host->data_xfered is %d\n", + remain, readl(base + MMCISTATUS), host->size, + host->data_xfered); + spin_unlock(&host->lock); + break; + } + if ((--host->sg_len) && (data->flags & MMC_DATA_WRITE)) { + host->sg_ptr++; + host->sg_off = 0; + } else { + spin_unlock(&host->lock); + break; + } + spin_unlock(&host->lock); + + hoststatus = readl(base + MMCISTATUS); + } + + if (devicemode == MCI_INTERRUPTMODE) { + /* If we're nearing the end of the read, switch to + * "any data available" mode */ + if ((hoststatus & MCI_RXACTIVE) && + (host->size - host->data_xfered) < MCI_FIFOSIZE) { + nomadik_mmc_enableirqsrc(base, MCI_RXDATAAVLBL); + } + + /* + * If we run out of data, disable the data IRQs; this + * prevents a race where the FIFO becomes empty before + * the chip itself has disabled the data path, and + * stops us racing with our data end IRQ. + */ + if (host->size == host->data_xfered) { + nomadik_mmc_disableirqsrc(base, MCI_XFER_IRQ_MASK); + } + } else if (devicemode == MCI_POLLINGMODE) { + nomadik_mmci_cmd_irq(host, hoststatus); + nomadik_mmci_data_irq(host, hoststatus); + } +} + +static int convert_from_bytes_to_power_of_two(unsigned int x) +{ + int y=0; + y=(x & 0xAAAA)? 1:0; + y|=((x & 0xCCCC)? 1:0)<<1; + y|=((x & 0xF0F0)? 1:0)<<2; + y|=((x & 0xFF00)? 1:0)<<3; + + return y; +} +static void start_data_xfer(struct nomadik_mmci_host *host) +{ + void __iomem *base; + struct mmc_data *data; + unsigned int size; + u32 nmdk_reg; + unsigned int temp; + + data = host->data; + base = host->base; + size = host->size; + + BUG_ON(!data); + BUG_ON(!(data->flags & (MMC_DATA_READ | MMC_DATA_WRITE))); + BUG_ON((data->flags & MMC_DATA_READ) && (data->flags & MMC_DATA_WRITE)); + + writel(0x000FFFFF, (base + MMCIDATATIMER)); + writel(size, (base + MMCIDATALENGTH)); + + temp = convert_from_bytes_to_power_of_two(data->blksz); + nmdk_reg = MCI_DPSM_ENABLE | ((temp & 0xF) << 4); + if (devicemode == MCI_DMAMODE) { + /* Enable the DMA mode of the MMC Host Controller */ + nmdk_reg |= MCI_DPSM_DMAENABLE; + } + if ((data->flags & MMC_DATA_READ)) { + nmdk_reg |= MCI_DPSM_DIRECTION; + } + + if (devicemode == MCI_DMAMODE) { + nomadik_mmc_enableirqsrc(base, MCI_DATA_ERR); + } else if (devicemode == MCI_INTERRUPTMODE) { + nomadik_mmc_enableirqsrc(base, (MCI_DATA_IRQ | MCI_XFER_IRQ)); + if (host->size < MCI_FIFOSIZE) { + nomadik_mmc_enableirqsrc(base, MCI_RXDATAAVLBL); + } + } + + writel(nmdk_reg, (base + MMCIDATACTRL)); +} + +static void nomadik_mmci_xfer_irq(struct nomadik_mmci_host *host, + u32 hoststatus) +{ + hoststatus &= MCI_XFER_IRQ_MASK; + + if (!hoststatus) { + return; + } + + BUG_ON(devicemode != MCI_INTERRUPTMODE); + + nomadik_mmci_read_write(host); +} + +static void nomadik_mmci_cmd_irq(struct nomadik_mmci_host *host, u32 hoststatus) +{ + void __iomem *base; + struct mmc_command *cmd; + struct mmc_data *data; + u32 cmdstatusmask; + + cmd = host->cmd; + data = host->data; + base = host->base; + + if (cmd) { + cmdstatusmask = MCI_CMDTIMEOUT | MCI_CMDCRCFAIL; + if ((cmd->flags & MMC_RSP_PRESENT)) { + cmdstatusmask |= MCI_CMDRESPEND; + } else { + cmdstatusmask |= MCI_CMDSENT; + } + } else { + cmdstatusmask = 0; + } + + hoststatus &= cmdstatusmask; + + if (!hoststatus) { + return; + } + + process_command_end(host, hoststatus); + + if (!cmd->data || cmd->error != MMC_ERR_NONE) { + if (cmd->error != MMC_ERR_NONE && data) { + nomadik_mmci_stop_data(host); + if (!data->stop) { + nomadik_mmci_request_end(host, data->mrq); + } else { + nomadik_mmci_start_command(host, data->stop); + } + } else { + nomadik_mmci_request_end(host, cmd->mrq); + } + } else if (!(cmd->data->flags & MMC_DATA_READ)) { + start_data_xfer(host); + } + + nomadik_mmc_clearirqsrc(base, hoststatus); +} + +static void nomadik_mmci_data_irq(struct nomadik_mmci_host *host, + u32 hoststatus) +{ + struct mmc_data *data; + struct mmc_command *cmd; + + hoststatus &= MCI_DATA_IRQ; + + if (!hoststatus) { + return; + } + + cmd = host->cmd; + + data = host->data; + if (!data) { + goto clear_data_irq; + } + + data->error = check_for_data_err(hoststatus); + + if (data->error != MMC_ERR_NONE) { + DEBUG + ("In %d Cmd, data_irq, data->error is %d, data_xfered is %d\n", + cmd->opcode, data->error, host->data_xfered); + } + + if (devicemode == MCI_DMAMODE && data->error != MMC_ERR_NONE) { + /* This is to work around a bug in the DMA. We can't + * cancel the DMA here, because it may be in the middle + * of completing the DMA and cancelling would cause a + * kernel oops. However, if we don't cancel, the DMA may + * never complete, and the MMC request will never end. */ + if (data->error == MMC_ERR_BADCRC) { + dma_flag_error = 1; + goto clear_data_irq; + } + } + + if (!data->error) { + if ((data->flags & MMC_DATA_READ) + && (devicemode != MCI_DMAMODE)) { + u32 *buffer_local, *buffer; + nomadik_mmci_init_sg(host, data); + buffer_local = host->buffer; + while (host->sg_len--) { + buffer = + (u32 + *) (page_address(host->sg_ptr-> + page) + + host->sg_ptr->offset); + memcpy(buffer, buffer_local, + host->sg_ptr->length); + buffer_local += host->sg_ptr->length / 4; + host->sg_ptr++; + host->sg_off = 0; + } + } + } + + nomadik_mmci_stop_data(host); + + if (!data->stop) { + nomadik_mmci_request_end(host, data->mrq); + } else { + nomadik_mmci_start_command(host, data->stop); + } + + clear_data_irq: + nomadik_mmc_clearirqsrc(host->base, hoststatus); +} + +static irqreturn_t nomadik_mmci_irq(int irq, void *dev_id) +{ + struct nomadik_mmci_host *host = dev_id; + void __iomem *base; + u32 hoststatus; + + base = host->base; + + hoststatus = readl(base + MMCISTATUS); + hoststatus &= readl(base + MMCIMASK0); + while (hoststatus) { + if ((hoststatus & MCI_XFER_IRQ_MASK)) { + nomadik_mmci_xfer_irq(host, hoststatus); + } + if ((hoststatus & MCI_CMD_IRQ)) { + nomadik_mmci_cmd_irq(host, hoststatus); + } + if ((hoststatus & MCI_DATA_IRQ)) { + nomadik_mmci_data_irq(host, hoststatus); + } + + hoststatus = readl(base + MMCISTATUS); + hoststatus &= readl(base + MMCIMASK0); + } + + return IRQ_HANDLED; +} + +static void nomadik_mmci_start_data(struct nomadik_mmci_host *host, + struct mmc_data *data, + struct mmc_command *cmd) +{ + DECLARE_COMPLETION_ONSTACK(complete); + void __iomem *base; + u32 nmdk_reg; + u32 polling_freq = 1; + unsigned long flag_lock = 0; + + dma_flag_error = 0; + + spin_lock_irqsave(&host->lock, flag_lock); + host->data = data; + host->cmd = cmd; + host->size = data->blocks * data->blksz; + host->data_xfered = 0; + base = host->base; + spin_unlock_irqrestore(&host->lock, flag_lock); + + nomadik_mmci_init_sg(host, data); + + if (devicemode == MCI_INTERRUPTMODE) + polling_freq = 10; + else + polling_freq = 0; + cmd->error = MMC_ERR_NONE; + data->error = MMC_ERR_NONE; + + DEBUG + ("host->sg_len is %d\nhost->sg_ptr->length is %d cmd is %d, cmd->arg is %d, host->size is %d\n", + host->sg_len, host->sg_ptr->length, cmd->opcode, cmd->arg, + host->size); + + nmdk_reg = readl(base + MMCICLOCK); + nmdk_reg = (nmdk_reg & ~(0xFF)) | ((u8) polling_freq & 0xFF); + writel(nmdk_reg, (base + MMCICLOCK)); + + if (devicemode == MCI_DMAMODE) { + nomadik_mmc_set_dma(host); + } + + /* For a read we need to write to the data ctrl register first, then + * send the command. For writes, the order is reversed. + */ + if ((data->flags & MMC_DATA_READ)) { + start_data_xfer(host); + } + + nomadik_mmc_send_cmd(base, cmd->opcode, cmd->arg, cmd->flags); + + if (devicemode == MCI_POLLINGMODE) { + if (!(data->flags & MMC_DATA_READ)) { + wait_for_command_end(host); + } + while (data->error == MMC_ERR_NONE && host->data) { + nomadik_mmci_read_write(host); + schedule(); + } + } else if (devicemode == MCI_DMAMODE) { + host->dma_done = &complete; + wait_for_completion(&complete); + nomadik_mmc_dmaclbk1(host); + } + + return; +} + +static void +nomadik_mmci_start_command(struct nomadik_mmci_host *host, + struct mmc_command *cmd) +{ + void __iomem *base = host->base; + unsigned long flag_lock = 0; + + spin_lock_irqsave(&host->lock, flag_lock); + host->cmd = cmd; + spin_unlock_irqrestore(&host->lock, flag_lock); + nomadik_mmc_send_cmd(base, cmd->opcode, cmd->arg, cmd->flags); + if (devicemode == MCI_POLLINGMODE) { + wait_for_command_end(host); + } + return; +} + +/** + * nomadik_mmci_request - Processes the request recieved from MMC framework + * + * @mmc_host - The host structure for MMC. + * @mmc_request - The request structure + * + **/ +static void nomadik_mmci_request(struct mmc_host *mmc, struct mmc_request *mrq) +{ + struct nomadik_mmci_host *host = mmc_priv(mmc); + unsigned long flag_lock = 0; + + WARN_ON(host->mrq != NULL); + + spin_lock_irqsave(&host->lock, flag_lock); + host->mrq = mrq; + spin_unlock_irqrestore(&host->lock, flag_lock); + + if (mrq->data && mrq->data->flags & (MMC_DATA_READ | MMC_DATA_WRITE)) + nomadik_mmci_start_data(host, mrq->data, mrq->cmd); + + else + nomadik_mmci_start_command(host, mrq->cmd); + +} + +/** + * nomadik_mmci_set_ios - Perform configuration related settings for MMC host + * + * @mmc_host - The host structure for MMC. + * @mmc_ios - The configuration settings to be done + * + **/ +static void nomadik_mmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) +{ + struct nomadik_mmci_host *host = mmc_priv(mmc); + u32 clk = 0, pwr = 0; + + DEBUG("%s: clock %uHz busmode %u powermode %u Vdd %u bus_width %u\n", + mmc_hostname(mmc), ios->clock, ios->bus_mode, ios->power_mode, + ios->vdd, ios->bus_width); + + /* Make sure we aren't changing the control registers too soon after + * writing data. */ + udelay(1); + + /* Set the clock rate and bus width */ + if (ios->clock) { + if (ios->clock >= host->mclk) { + clk = MCI_CLK_BYPASS; + host->cclk = host->mclk; + } else { + clk = (host->mclk / ios->clock) - 2; + if (clk > 256) { + clk = 255; + } + host->cclk = host->mclk / (clk + 2); + if (host->cclk > ios->clock) { + clk += 1; + host->cclk = host->mclk / (clk + 2); + } + } + clk |= MCI_CLK_ENABLE; + pwr |= MCI_FBCLK_ENABLE; + } + + switch (ios->bus_width) { + case MMC_BUS_WIDTH_1: + clk |= MCI_BUS_WIDTH_1; + pwr |= MCI_DIREN_1BIT; + break; + case MMC_BUS_WIDTH_4: + DEBUG("nomadik_mmci_setios(): Enabling 4 bit mode\n"); + clk |= MCI_BUS_WIDTH_4; + pwr |= MCI_DIREN_4BIT; + break; + default: + break; + } + writel(clk, host->base + MMCICLOCK); + + /* Set the bus and power modes */ + switch (ios->power_mode) { + case MMC_POWER_OFF: + break; + case MMC_POWER_UP: + pwr |= MCI_PWR_UP; + break; + case MMC_POWER_ON: + pwr |= MCI_PWR_ON; + break; + } + + if (ios->bus_mode == MMC_BUSMODE_OPENDRAIN) + pwr |= MCI_OPEN_DRAIN; + + if (host->pwr != pwr) { + u32 nmdk_reg; + host->pwr = pwr; + nmdk_reg = readl(host->base + MMCIPOWER); + nmdk_reg &= ~(MCI_POWER_IOS_MASK); + nmdk_reg |= pwr & (MCI_POWER_IOS_MASK); + DEBUG("wrote MMCIPOWER register\n"); + writel(nmdk_reg, host->base + MMCIPOWER); + } +} + +static struct mmc_host_ops nomadik_mmci_ops = { + .request = nomadik_mmci_request, + .set_ios = nomadik_mmci_set_ios, +}; + +static void nomadik_mmci_check_status(unsigned long data) +{ + struct amba_device *dev = nomadik_mmc_dev; /*(struct amba_device *)data; */ + struct nomadik_mmci_host *host; + gpio_data status; + int err; + unsigned char byte_value; + + + struct mmc_host *mmc; + mmc = amba_get_drvdata(nomadik_mmc_dev); + host = mmc_priv(mmc); + +//Adding This AK +#if 0 + nomadik_gpio_readpin(GPIO_PIN_FOR_IRQ(dev->irq[1]), &status); + if (status) + DEBUG("Card is not present\n"); + else + DEBUG("Card present\n"); +#endif + + err = STMPE2401_GetGpioVal(STMPE1,EGPIO_PIN_7,&byte_value); + if(err != STMPE2401_OK ) + { + DEBUG( " error in reading the card detecxt signal....\n"); + } + //nomadik_gpio_readpin(sdCardDetect,&pinval); + mdelay(50); + //nomadik_gpio_readpin(sdCardDetect,&pinval); + err = STMPE2401_GetGpioVal(STMPE1,EGPIO_PIN_7,&byte_value); + if(err != STMPE2401_OK ) + { + DEBUG( " error in reading the card detecxt signal....\n"); + } + + + if(byte_value) + { + status = GPIO_DATA_HIGH ; + printk("\n Check Status --- Card Not Present\n") ; + } + else + { status = GPIO_DATA_LOW ; + printk("\n Check Status --- Card Present\n") ; + } + + + if (status ^ host->oldstat) + { + printk("\n mmc_detect_change called\n"); + mmc_detect_change(host->mmc, 0); + } + + host->oldstat = status; + + return; +} + + + +//--- Changes this Callback Function . AK +#if 1 //ak FOR TEST +static irqreturn_t nomadik_mmc_detect_int(int irq, void *dev_id) +{ + struct nomadik_mmci_host *host = (struct nomadik_mmci_host *)dev_id; + /* + * Used to implement S/W debounce + */ + mod_timer(&host->timer, jiffies + HZ); + return IRQ_HANDLED; +} +#endif + +static void nomadik_mmc_detect(void *dev_id) +//static irqreturn_t nomadik_mmc_detect_int(int irq, void *dev_id) +{ + int err; + unsigned char byte_value; + struct nomadik_mmci_host *host = (struct nomadik_mmci_host *)dev_id; + int ret; + /* + * Used to implement S/W debounce + */ + // --- Added Ak + printk("\n Got the Card Dectect Interrupt\n") ; + err = STMPE2401_GetGpioVal(STMPE1,EGPIO_PIN_7,&byte_value); + if(err != STMPE2401_OK ) + { + DEBUG( " error in reading the card detecxt signal....\n"); + } + if(byte_value) + { + printk("\n Probe --- Card Not Present\n") ; + } + else + { + printk("\n Probe --- Card Present\n") ; + } + mod_timer(&host->timer, jiffies + HZ); +// return IRQ_HANDLED; +} +static int nomadik_mmci_probe(struct amba_device *dev, void *id) +{ + struct nomadik_mmci_host *host; + struct mmc_host *mmc; + int ret; + struct mmc_board *board = dev->dev.platform_data; + struct nmdk_dma_info pipe_info; + int err; + + + if (!board) { + DEBUG(KERN_INFO "mmc: Platform data not set\n"); + return -EINVAL; + } + + nomadik_mmc_dev = dev; + + ret = board->init(dev); + if (ret) { + DERRPRINTK("\n Error in configuring MMC"); + goto out; + } + + ret = amba_request_regions(dev, DRIVER_NAME); + if (ret) { + DERRPRINTK("\n Error in amba_request_region"); + goto configure_mmc; + } + + mmc = mmc_alloc_host(sizeof(struct nomadik_mmci_host), &dev->dev); + if (!mmc) { + ret = -ENOMEM; + goto rel_regions; + } + + host = mmc_priv(mmc); + + host->oldstat = -1; + host->mclk = CLK_MAX; + host->vmcc = DEFAULT_VMMC; + host->mmc = mmc; + + host->buffer = vmalloc(MAX_DATA); + if (!host->buffer) { + ret = -ENOMEM; + goto free_mmc; + } + host->base = ioremap(dev->res.start, SZ_4K); + if (!host->base) { + ret = -ENOMEM; + goto host_free; + } + mmc->ops = &nomadik_mmci_ops; + mmc->f_max = min(host->mclk, fmax); + mmc->f_min = CLK_MAX / 257; + mmc->ocr_avail = OCR_AVAIL; + mmc->caps = MMC_CAP_4_BIT_DATA ; + + /* + * We can do SGIO + */ + if (devicemode == MCI_DMAMODE) { + /* Can't do scatter/gather DMA */ + mmc->max_hw_segs = 1; + mmc->max_phys_segs = 1; + } else { + mmc->max_hw_segs = 16; + mmc->max_phys_segs = NR_SG; + } + + /* + * Since we only have a 16-bit data length register, we must + * ensure that we don't exceed 2^16-1 bytes in a single request. + * Choose 64 (512-byte) sectors as the limit. + */ + mmc->max_sectors = 64; + + /* + * Set the maximum segment size. + */ + mmc->max_seg_size = mmc->max_sectors << 9; + + spin_lock_init(&host->lock); + + writel(0, host->base + MMCIMASK0); + writel(0xfff, host->base + MMCICLEAR); + + if (devicemode != MCI_POLLINGMODE) { + ret = + request_irq(dev->irq[0], nomadik_mmci_irq, SA_INTERRUPT, + DRIVER_NAME " (data)", host); + if (ret) + goto unmap; + } + + amba_set_drvdata(dev, mmc); + + ret = mmc_add_host(mmc); + if (ret) { + if (devicemode != MCI_POLLINGMODE) + goto irq0_free; + else + goto unmap; + } + + DEBUG(KERN_INFO "%s: MMCI rev %x cfg %02x at 0x%08lx irq %d\n", + mmc_hostname(mmc), amba_rev(dev), amba_config(dev), + dev->res.start, dev->irq[0]); + + init_timer(&host->timer); + host->timer.data = (unsigned long)host; + host->timer.function = nomadik_mmci_check_status; + host->timer.expires = jiffies + HZ; + /* + * Card detection interrupt request + */ +// --- Addition Starts AK + err = STMPE2401_SetGpioVal(STMPE1,EGPIO_PIN_2, 0); + if (err != STMPE2401_OK) + { + DEBUG(KERN_ALERT "Couldn't set STMPE GPIO0\n"); + } + err = STMPE2401_SetGpioDir(STMPE1,EGPIO_PIN_7,STMPE2401_GPIO_IN); + if (err != STMPE2401_OK) + { + DEBUG("Couldn't set STMPE1 %d as GPIO direction \n",EGPIO_PIN_7); + } + err = STMPE2401_SetGpioEdgeDetect(STMPE1, EGPIO_PIN_7, STMPE2401_BOTH_EDGE); + if (err != STMPE2401_OK) + { + DEBUG("error in seetting the GPIO edge.\n"); + } + //err = STMPE2401_Install_Callback(STMPE1,EGPIO_PIN_7,(void *)nomadik_mmc_detect_int,host); + err = STMPE2401_Install_Callback(STMPE1,EGPIO_PIN_7,(void *)nomadik_mmc_detect,host); + + if (err != STMPE2401_OK) + { + DEBUG(KERN_ALERT "Couldn't setup codec callback\n"); + } + err = STMPE2401_ClearGpioEdgeStatus( STMPE1,(0x1<irq[1], nomadik_mmc_detect_int, + (SA_TRIGGER_RISING | SA_TRIGGER_FALLING), + "mmc_detect", host); + if (ret) { + DEBUG(KERN_INFO "mmc detect interrupt request failed ..."); + goto remove_host; + } +#endif + + // Addition Ends + + + if (devicemode == MCI_DMAMODE) { + /* + * Request dmapipe for mmc to mem operation + */ + pipe_info.mode = FLOW_CNTRL_PERIPH(PERIPH_TO_MEM); + pipe_info.srcdevtype = "sdmmc"; + pipe_info.destdevtype = "mem"; + pipe_info.config = 0; + /*dummy value needed to be updated before enable dma by calling __set_dma_destadr API*/ + + /* find and request free dma chanel */ + dmach_mmc2mem = request_available_dma(&pipe_info); + if (dmach_mmc2mem < 0) { + DERRPRINTK("\n Failed... Request DMA channel for mmc2mem"); + ret= dmach_mmc2mem; + goto mmc2mem_dmareq_failed; + } + __set_dma_srcaddr(dmach_mmc2mem, (dma_addr_t *)(NOMADIK_SDI_BASE + SD_MMC_TX_RX_REG_OFFSET)); + /* + * Request interrrupt to notify mmc2mem dma xfer finish + * free_irq will be called by dma layer from the context of free_dma() + */ + request_irq(IRQNO_FOR_DMACH(dmach_mmc2mem), nomadik_mmc_dmaclbk, + 0, 0, host); + DEBUG(" DMACH %d configured for mem2mmc\n"); + + + /* + * Request dmapipe for mem to mmc operation + */ + pipe_info.mode = FLOW_CNTRL_PERIPH(MEM_TO_PERIPH); + pipe_info.srcdevtype = "mem"; + pipe_info.destdevtype = "sdmmc"; + pipe_info.config = 0; + + /* find and request free dma chanel */ + dmach_mem2mmc = request_available_dma(&pipe_info); + if (dmach_mem2mmc < 0) { + DERRPRINTK("\n Failed... Request DMA channel for mem2mmc"); + ret= dmach_mem2mmc; + goto mem2mmc_dmareq_failed; + } + __set_dma_destaddr(dmach_mem2mmc, (dma_addr_t *)(NOMADIK_SDI_BASE + SD_MMC_TX_RX_REG_OFFSET)); + /* + * Request interrrupt to notify mmc2mem dma xfer finish + * free_irq will be called by dma layer from the context of free_dma() + */ + request_irq(IRQNO_FOR_DMACH(dmach_mem2mmc), nomadik_mmc_dmaclbk, + 0, 0, host); + DEBUG(" DMACH %d configured for mem2mmc\n"); + } +// nmdk_info("Module initialized Ver("MMC_VER")"); + return 0; + + mem2mmc_dmareq_failed: + free_dma(dmach_mmc2mem); + dmach_mmc2mem = -1; + mmc2mem_dmareq_failed: + dmach_mem2mmc = -1; + free_irq(dev->irq[1], host); + remove_host: + mmc_remove_host(mmc); + irq0_free: + free_irq(dev->irq[0], host); + unmap: + iounmap(host->base); + host_free: + vfree(host->buffer); + free_mmc: + mmc_free_host(mmc); + rel_regions: + amba_release_regions(dev); + configure_mmc: + board->exit(dev); + out: + return ret; +} + +static int nomadik_mmci_remove(struct amba_device *dev) +{ + struct mmc_board *board = dev->dev.platform_data; + struct mmc_host *mmc = amba_get_drvdata(dev); + + if (!board) + return -EINVAL; + + amba_set_drvdata(dev, NULL); + + if (mmc) { + struct nomadik_mmci_host *host = mmc_priv(mmc); + + free_dma(dmach_mmc2mem); + dmach_mmc2mem = -1; + free_dma(dmach_mem2mmc); + dmach_mem2mmc = -1; + + free_irq(dev->irq[1], host); + + del_timer_sync(&host->timer); + + mmc_remove_host(mmc); + + writel(0, host->base + MMCIMASK0); + + writel(0, host->base + MMCICOMMAND); + writel(0, host->base + MMCIDATACTRL); + + free_irq(dev->irq[0], host); + + iounmap(host->base); + + vfree(host->buffer); + + mmc_free_host(mmc); + + amba_release_regions(dev); + + board->exit(dev); + } +// nmdk_info("Module removed"); + + return 0; +} + +#ifdef CONFIG_PM +static int nomadik_mmci_suspend(struct amba_device *dev, pm_message_t state) +{ + struct mmc_host *mmc = amba_get_drvdata(dev); + int ret = 0; + + if (mmc) { + struct nomadik_mmci_host *host = mmc_priv(mmc); + + ret = mmc_suspend_host(mmc, state); + if (ret == 0) + writel(0, host->base + MMCIMASK0); + } + + return ret; +} + +static int nomadik_mmci_resume(struct amba_device *dev) +{ + struct mmc_host *mmc = amba_get_drvdata(dev); + int ret = 0; + + if (mmc) { + struct nomadik_mmci_host *host = mmc_priv(mmc); + + writel(MCI_IRQENABLE, host->base + MMCIMASK0); + + ret = mmc_resume_host(mmc); + } + + return ret; +} +#else +#define nomadik_mmci_suspend NULL +#define nomadik_mmci_resume NULL +#endif + +static struct amba_id nomadik_mmci_ids[] = { + { + .id = SDI_PER_ID, + .mask = SDI_PER_MASK, + }, + {0, 0, 0}, +}; + +static struct amba_driver nomadik_mmci_driver = { + .drv = { + .name = DRIVER_NAME, + }, + .probe = nomadik_mmci_probe, + .remove = nomadik_mmci_remove, + .suspend = nomadik_mmci_suspend, + .resume = nomadik_mmci_resume, + .id_table = nomadik_mmci_ids, +}; + +static int __init nomadik_mmci_init(void) +{ + return amba_driver_register(&nomadik_mmci_driver); +} + +static void __exit nomadik_mmci_exit(void) +{ + amba_driver_unregister(&nomadik_mmci_driver); +} + +module_init(nomadik_mmci_init); +module_exit(nomadik_mmci_exit); + +MODULE_AUTHOR("Vaibhav Agarwal (vaibhav.agarwal@st.com)"); +MODULE_DESCRIPTION("ARM PrimeCell PL180 Multimedia Card Interface driver"); +MODULE_LICENSE("GPL"); --- linux-2.6.20.orig/drivers/mtd/maps/Kconfig +++ linux-2.6.20/drivers/mtd/maps/Kconfig @@ -67,10 +67,17 @@ config MTD_PHYSMAP_OF This provides a 'mapping' driver which allows the NOR Flash and ROM driver code to communicate with chips which are mapped physically into the CPU's memory. The mapping description here is taken from OF device tree. +config MTD_NOMADIK + tristate "NOR flash support for Nomadik Platform" + depends on ARCH_NOMADIK && MTD_CFI + default y + help + This provides the nor flash chip support for nomadik platform. + config MTD_SUN_UFLASH tristate "Sun Microsystems userflash support" depends on SPARC && MTD_CFI help This provides a 'mapping' driver which supports the way in --- linux-2.6.20.orig/drivers/mtd/maps/Makefile +++ linux-2.6.20/drivers/mtd/maps/Makefile @@ -5,11 +5,16 @@ ifeq ($(CONFIG_MTD_COMPLEX_MAPPINGS),y) obj-$(CONFIG_MTD) += map_funcs.o endif +ifdef NORFLASH_DEBUG +CFLAGS += -DNORFLASH_DEBUG=$(NORFLASH_DEBUG) +endif + # Chip mappings +obj-$(CONFIG_MTD_NOMADIK) += norflash-nomadik.o obj-$(CONFIG_MTD_CDB89712) += cdb89712.o obj-$(CONFIG_MTD_ARM_INTEGRATOR)+= integrator-flash.o obj-$(CONFIG_MTD_BAST) += bast-flash.o obj-$(CONFIG_MTD_CFI_FLAGADM) += cfi_flagadm.o obj-$(CONFIG_MTD_DC21285) += dc21285.o @@ -23,19 +28,19 @@ obj-$(CONFIG_MTD_TSUNAMI) += tsunami_fla obj-$(CONFIG_MTD_LUBBOCK) += lubbock-flash.o obj-$(CONFIG_MTD_MAINSTONE) += mainstone-flash.o obj-$(CONFIG_MTD_MBX860) += mbx860.o obj-$(CONFIG_MTD_CEIVA) += ceiva.o obj-$(CONFIG_MTD_OCTAGON) += octagon-5066.o -obj-$(CONFIG_MTD_PHYSMAP) += physmap.o +obj-$(CONFIG_MTD_PHYSMAP) += physmap.oCONFIG_MTD_NOMADIK obj-$(CONFIG_MTD_PHYSMAP_OF) += physmap_of.o obj-$(CONFIG_MTD_PNC2000) += pnc2000.o obj-$(CONFIG_MTD_PCMCIA) += pcmciamtd.o obj-$(CONFIG_MTD_RPXLITE) += rpxlite.o obj-$(CONFIG_MTD_TQM8XXL) += tqm8xxl.o obj-$(CONFIG_MTD_SA1100) += sa1100-flash.o obj-$(CONFIG_MTD_IPAQ) += ipaq-flash.o -obj-$(CONFIG_MTD_SBC_GXX) += sbc_gxx.o +obj-$(CONFIG_MTD_SBC_GXX) += sbc_gxx.oCONFIG_MTD_NOMADIK obj-$(CONFIG_MTD_SC520CDP) += sc520cdp.o obj-$(CONFIG_MTD_NETSC520) += netsc520.o obj-$(CONFIG_MTD_TS5500) += ts5500_flash.o obj-$(CONFIG_MTD_SUN_UFLASH) += sun_uflash.o obj-$(CONFIG_MTD_VMAX) += vmax301.o @@ -70,5 +75,7 @@ obj-$(CONFIG_MTD_DMV182) += dmv182.o obj-$(CONFIG_MTD_SHARP_SL) += sharpsl-flash.o obj-$(CONFIG_MTD_PLATRAM) += plat-ram.o obj-$(CONFIG_MTD_OMAP_NOR) += omap_nor.o obj-$(CONFIG_MTD_MTX1) += mtx-1_flash.o obj-$(CONFIG_MTD_TQM834x) += tqm834x.o + + --- /dev/null +++ linux-2.6.20/drivers/mtd/maps/norflash-nomadik.c @@ -0,0 +1,411 @@ +/* + * drivers/mtd/maps/norflash-nomadik.c + * + * Mapping for the NOMADIK board + * STMicroelectronics Pvt Ltd. + * + * + * Based on ADI BRH map written by Deepak Saxena + * Based on iq80310 map written by Nicolas Pitre + * + * 02-05-2007: Sachin Verma (sachin.verma@st.com) + * - Rewritten Driver to use standard kernel interfaces. + * - Added Power Management Routines for suspend()/resume() + * - Removed static mtd_info structures, replacing them with platform data + * - Removed Header File asm/arch/norflash-nomadik.h + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* to enable nor flash debug messages pass parameter to make as "make NORFLASH_DEBUG=0x"*/ +#ifndef NORFLSH_DEBUG +#define NORFLASH_DEBUG 0 /* default debug messages are disabled */ +#endif + +#define NMDK_DEBUG NORFLASH_DEBUG /* enables/disables debug msgs */ +#define NMDK_DEBUG_PFX "nmdknor" /* msg header represents this module */ +#define NMDK_DBG KERN_ERR /* message level */ + +struct nomadik_subdev_info { + char name[16]; + struct map_info map; + struct mtd_info *mtd; + struct flash_platform_data *plat; +}; + +struct nor_flash_device { + struct mtd_partition *parts; + struct mtd_info *mtd; + int num_subdev; + unsigned int nr_parts; + struct nomadik_subdev_info subdev[0]; +}; + +/** + * nomadik_norflash_unlock - unlocks the entire nor flash blocks for a bank + * + */ +static void nomadik_norflash_unlock(struct mtd_info *mtd) +{ + /* Unlock the flash device. */ + nmdk_dbg_ftrace(); + nmdk_dbg("Trying to unlock the flash\n"); + if (mtd->unlock) { + int i; + for (i = 0; i < mtd->numeraseregions; i++) { + int j; + for (j = 0; j < mtd->eraseregions[i].numblocks; j++) { + mtd->unlock(mtd, + mtd->eraseregions[i].offset + + j * mtd->eraseregions[i].erasesize, + mtd->eraseregions[i].erasesize); + } + } + } +} +static void nomadik_destroy_subdev(struct nomadik_subdev_info *subdev) +{ + if (subdev->mtd) + map_destroy(subdev->mtd); + if (subdev->map.virt) + iounmap(subdev->map.virt); + release_mem_region(subdev->map.phys, subdev->map.size); +} + +static void nomadik_destroy(struct nor_flash_device *info, + struct flash_platform_data *plat) +{ + int i; + + if (info->mtd) { + if (info->nr_parts == 0) + del_mtd_device(info->mtd); +#ifdef CONFIG_MTD_PARTITIONS + else + del_mtd_partitions(info->mtd); +#endif +#ifdef CONFIG_MTD_CONCAT + if (info->mtd != info->subdev[0].mtd) + mtd_concat_destroy(info->mtd); +#endif + } + + kfree(info->parts); + + for (i = info->num_subdev - 1; i >= 0; i--) + nomadik_destroy_subdev(&info->subdev[i]); + kfree(info); + + if (plat->exit) + plat->exit(); +} + +static int nomadik_probe_subdev(struct nomadik_subdev_info *subdev, + struct resource *res) +{ + unsigned long phys; + unsigned int size; + int ret; + + phys = res->start; + size = res->end - phys + 1; + + GET_BANK_WIDTH(subdev->map.bankwidth, phys); + + nmdk_dbg("BCR BANK_WIDTH = %d\n", subdev->map.bankwidth); + + if (!request_mem_region(phys, size, subdev->name)) { + ret = -EBUSY; + goto out; + } + + subdev->map.phys = phys; + subdev->map.size = size; + subdev->map.virt = ioremap(phys, size); + if (!subdev->map.virt) { + ret = -ENOMEM; + goto err; + } + + simple_map_init(&subdev->map); + + /* + * Now let's probe for the actual flash. Do it here since + * specific machine settings might have been set above. + */ + subdev->mtd = do_map_probe(subdev->plat->map_name, &subdev->map); + if (subdev->mtd == NULL) { + ret = -ENXIO; + goto err; + } + subdev->mtd->owner = THIS_MODULE; + nomadik_norflash_unlock(subdev->mtd); + + nmdk_dbg("Nomadik flash: CFI device at 0x%08lx, %dMiB, " + "%d-bit\n", phys, subdev->mtd->size >> 20, + subdev->map.bankwidth * 8); + return 0; + err: + nomadik_destroy_subdev(subdev); + out: + return ret; +} + +static struct nor_flash_device *__init +nomadik_setup_mtd(struct platform_device *pdev, + struct flash_platform_data *plat) +{ + struct nor_flash_device *info; + int nr, size, i, ret = 0; + + /* + * Count number of devices (SACHIN:: banks?? or physical controllers whose physical address etc are provided in resources.....???). + */ + for (nr = 0;; nr++) + if (!platform_get_resource(pdev, IORESOURCE_MEM, nr)) + break; + + if (nr == 0) { + ret = -ENODEV; + goto out; + } + + size = + sizeof(struct nor_flash_device) + + sizeof(struct nomadik_subdev_info) * nr; + + /* + * Allocate the map_info structs in one go. + */ + info = kmalloc(size, GFP_KERNEL); + if (!info) { + ret = -ENOMEM; + goto out; + } + + memset(info, 0, size); + + if (plat->init) { + ret = plat->init(); + if (ret) + goto err; + } + + /* + * Claim and then map the memory regions. + */ + for (i = 0; i < nr; i++) { + struct nomadik_subdev_info *subdev = &info->subdev[i]; + struct resource *res; + + res = platform_get_resource(pdev, IORESOURCE_MEM, i); + if (!res) + break; + + subdev->map.name = subdev->name; + sprintf(subdev->name, "%s-%d", plat->name, i); + subdev->plat = plat; + + ret = nomadik_probe_subdev(subdev, res); + if (ret) + break; + } + + info->num_subdev = i; + + /* + * ENXIO is special. It means we didn't find a chip when we probed. + */ + if (ret != 0 && !(ret == -ENXIO && info->num_subdev > 0)) + goto err; + + /* + * If we found one device, don't bother with concat support. If + * we found multiple devices, use concat if we have it available, + * otherwise fail. Either way, it'll be called "nomadik_nor". + */ + if (info->num_subdev == 1) { + strcpy(info->subdev[0].name, plat->name); + info->mtd = info->subdev[0].mtd; + ret = 0; + } else if (info->num_subdev > 1) { +#ifdef CONFIG_MTD_CONCAT + struct mtd_info *cdev[nr]; + /* + * We detected multiple devices. Concatenate them together. + */ + for (i = 0; i < info->num_subdev; i++) + cdev[i] = info->subdev[i].mtd; + + info->mtd = + mtd_concat_create(cdev, info->num_subdev, + (char *)plat->name); + if (info->mtd == NULL) + ret = -ENXIO; +#else + nmdk_dbg(KERN_ERR "Nomadik flash: multiple devices " + "found but MTD concat support disabled.\n"); + ret = -ENXIO; +#endif + } + + if (ret == 0) + return info; + + err: + nomadik_destroy(info, plat); + out: + return ERR_PTR(ret); +} + +static const char *part_probes[] = { "cmdlinepart", "RedBoot", NULL }; + +/** + * nomadik_nor_probe - nor module probe function + */ +static int nomadik_nor_probe(struct platform_device *pdev) +{ + struct flash_platform_data *plat = pdev->dev.platform_data; + struct mtd_partition *parts; + const char *part_type = NULL; + struct nor_flash_device *info; + int err, nr_parts = 0; + + if (!plat) + return -ENODEV; + + info = nomadik_setup_mtd(pdev, plat); + if (IS_ERR(info)) { + err = PTR_ERR(info); + goto out; + } + + /* + * Partition selection stuff. + */ +#ifdef CONFIG_MTD_PARTITIONS + nr_parts = parse_mtd_partitions(info->mtd, part_probes, &parts, 0); + if (nr_parts > 0) { + info->parts = parts; + part_type = "dynamic"; + } else +#endif + { + parts = plat->parts; + nr_parts = plat->nr_parts; + part_type = "static"; + } + + if (nr_parts == 0) { + nmdk_dbg(KERN_NOTICE "Nomadik flash: no partition info " + "available, registering whole flash\n"); + add_mtd_device(info->mtd); + } else { + nmdk_dbg(KERN_NOTICE "Nomadik flash: using %s partition " + "definition\n", part_type); + add_mtd_partitions(info->mtd, parts, nr_parts); + } + + info->nr_parts = nr_parts; + + platform_set_drvdata(pdev, info); + err = 0; + + out: + return err; + +} + +/** + * nomadik_nor_remove - nor module remove function + */ +static int nomadik_nor_remove(struct platform_device *pdev) +{ + struct nor_flash_device *info = platform_get_drvdata(pdev); + struct flash_platform_data *plat = pdev->dev.platform_data; + + platform_set_drvdata(pdev, NULL); + nomadik_destroy(info, plat); + + return 0; +} + +#ifdef CONFIG_PM +int nomadik_nor_suspend(struct platform_device *pdev, pm_message_t state) +{ + struct nor_flash_device *info = platform_get_drvdata(pdev); + int ret = 0; + nmdk_dbg_ftrace(); + if (info) { + ret = info->mtd->suspend(info->mtd); + } + return ret; +} + +int nomadik_nor_resume(struct platform_device *pdev) +{ + struct nor_flash_device *info = platform_get_drvdata(pdev); + nmdk_dbg_ftrace(); + if (info) { + info->mtd->resume(info->mtd); + nomadik_norflash_unlock(info->mtd); + return 0; + } else + return -1; +} + +#else +#define nomadik_nor_suspend NULL +#define nomadik_nor_resume NULL + +#endif + +static struct platform_driver nomadik_nor_driver = { + .probe = nomadik_nor_probe, + .remove = nomadik_nor_remove, + .driver = { + .owner = THIS_MODULE, + .name = "NOMADIK-NOR", + }, + .suspend = nomadik_nor_suspend, + .resume = nomadik_nor_resume, +}; + +static int __init nomadik_nor_init(void) +{ + return platform_driver_register(&nomadik_nor_driver); +} + +static void __exit nomadik_nor_exit(void) +{ + platform_driver_unregister(&nomadik_nor_driver); +} + +module_init(nomadik_nor_init); +module_exit(nomadik_nor_exit); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("ST Microelectronics (prafulla.wadaskar@st.com)"); +MODULE_DESCRIPTION("MTD map driver for Nomadik Platform"); --- linux-2.6.20.orig/drivers/mtd/nand/Kconfig +++ linux-2.6.20/drivers/mtd/nand/Kconfig @@ -11,10 +11,16 @@ config MTD_NAND help This enables support for accessing all type of NAND flash devices. For further information see . +config MTD_NAND_NOMADIK + tristate "NAND NOMADIK Device Support" + depends on ARCH_NOMADIK && MTD && MTD_NAND + help + this enabled nand support for nomadik + config MTD_NAND_VERIFY_WRITE bool "Verify NAND page writes" depends on MTD_NAND help This adds an extra check when data is written to the flash. The --- linux-2.6.20.orig/drivers/mtd/nand/Makefile +++ linux-2.6.20/drivers/mtd/nand/Makefile @@ -22,8 +22,13 @@ obj-$(CONFIG_MTD_NAND_SHARPSL) += sharp obj-$(CONFIG_MTD_NAND_TS7250) += ts7250.o obj-$(CONFIG_MTD_NAND_NANDSIM) += nandsim.o obj-$(CONFIG_MTD_NAND_CS553X) += cs553x_nand.o obj-$(CONFIG_MTD_NAND_NDFC) += ndfc.o obj-$(CONFIG_MTD_NAND_AT91) += at91_nand.o +obj-$(CONFIG_MTD_NAND_NOMADIK) += nandflash-nomadik.o + +ifdef NAND_DEBUG +CFLAGS += -DNMDK_NAND_DEBUG=$(NAND_DEBUG) +endif nand-objs := nand_base.o nand_bbt.o cafe_nand-objs := cafe.o cafe_ecc.o --- /dev/null +++ linux-2.6.20/drivers/mtd/nand/nandflash-nomadik.c @@ -0,0 +1,296 @@ +/* + * drivers/mtd/nand/nandflash-nomadik.c + * + * Overview: + * Driver for on-board NAND flash on Nomadik Platforms + * + * Copyright (C) 2007 STMicroelectronics Pvt. Ltd. + * + * Author: Sachin Verma + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#define NMDK_NAND_NAME "NOMADIK_NAND" + +#ifndef NMDK_NAND_DEBUG +#define NMDK_NAND_DEBUG 0 +#endif + +#define NMDK_DEBUG NMDK_NAND_DEBUG /* enables/disables nmdk_dbg msgs */ +#define NMDK_DEBUG_PFX NMDK_NAND_NAME /* msg header represents this module */ +#define NMDK_DBG KERN_ERR /* message level */ +#define NMDK_ECC_BYTES 3 + +int nand_nomadik_bbt(struct mtd_info *mtd); + +static int nomadik_nand_correct_data(struct mtd_info *mtd, u_char *dat, + u_char *read_ecc, u_char *calc_ecc) +{ + nmdk_dbg("nomadik_nand_correct_data(%p,%p,%p,%p)\n", mtd, dat, read_ecc, calc_ecc); + + nmdk_dbg("eccs: read %02x,%02x,%02x vs calc %02x,%02x,%02x\n", + read_ecc[0], read_ecc[1], read_ecc[2], calc_ecc[0], calc_ecc[1], calc_ecc[2]); + + if (read_ecc[0] == calc_ecc[0] && read_ecc[1] == calc_ecc[1] && read_ecc[2] == calc_ecc[2]) + return 0; + + /* we curently have no method for correcting the error */ + + return -1; +} + +static void nomadik_nand_enable_hwecc(struct mtd_info *mtd, int mode) +{ + nmdk_dbg("nomadik_nand_enable_hwecc()\n"); +} + + +static int nomadik_nand_probe(struct platform_device *pdev) +{ + struct nomadik_nand_platform_data *pdata = pdev->dev.platform_data; + struct nomadik_nand_info *data = NULL; + struct resource *res = NULL; + int ret = 0; + dma_addr_t nand_databuf_phys; + nmdk_dbg_ftrace(); + + /* Allocate memory for the device structure (and zero it) */ + data = (void *)kzalloc(sizeof(struct nomadik_nand_info), GFP_KERNEL); + + if (!data) { + dev_err(&pdev->dev, "failed to allocate device structure.\n"); + return -ENOMEM; + } + + memset(&data->chip,0,sizeof(struct nand_chip)); + memset(&data->mtd,0,sizeof(struct mtd_info)); + + if (!(pdata->init)) { + ret = -EIO; + goto err; + } + + if(pdata->init()){ + dev_err(&pdev->dev, "Initialization function failed for Nand failed\n"); + ret = -EIO; + goto err; + } + + res = + platform_get_resource_byname(pdev, IORESOURCE_MEM, "cmem_address"); + if (!res) { + ret = -EIO; + goto err; + } + + data->cmema_va = ioremap(res->start, res->end - res->start + 1); + if (!data->cmema_va) { + ret = -ENOMEM; + goto err; + } + + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "cmem_data"); + if (!res) { + ret = -EIO; + goto out_ior; + } + + data->cmemd_va = ioremap(res->start, res->end - res->start + 1); + if (!data->cmemd_va) { + ret = -ENOMEM; + goto out_ior; + } + + res = + platform_get_resource_byname(pdev, IORESOURCE_MEM, "cmem_command"); + if (!res) { + ret = -EIO; + goto out_ior; + } + + data->cmemc_va = ioremap(res->start, res->end - res->start + 1); + if (!data->cmemc_va) { + ret = -ENOMEM; + goto out_ior; + } + + data->chip.priv = &data; + data->mtd.priv = &data->chip; + data->mtd.owner = THIS_MODULE; + data->chip.IO_ADDR_R = data->cmemd_va; + data->chip.IO_ADDR_W = data->cmemd_va; + data->chip.cmd_ctrl = pdata->hwcontrol; + + data->chip.ecc.mode = NAND_ECC_HW; + data->chip.ecc.layout = pdata->nand_oob; + data->chip.ecc.calculate = pdata->compute_ecc; + data->chip.ecc.correct = nomadik_nand_correct_data; + data->chip.ecc.hwctl = nomadik_nand_enable_hwecc; + data->chip.ecc.size = pdata->eccsize; + data->chip.ecc.steps = pdata->eccsteps; + data->chip.ecc.bytes = NMDK_ECC_BYTES; + + data->chip.options = pdata->lp_options; + data->chip.scan_bbt = nand_nomadik_bbt; + data->bbt_desc = pdata->bbt_desc; + + /* Allocate chip buffers */ + data->chip.buffers = dma_alloc_coherent(NULL,sizeof(*(data->chip.buffers)),&nand_databuf_phys, GFP_KERNEL | GFP_DMA); + if(data->chip.buffers == NULL) { + printk("nomadik_nand : nand data buffer allocation failed\n"); + } + data->chip.options |= NAND_OWN_BUFFERS; + + + /* + * Scan to find existance of the device + */ + if (nand_scan(&data->mtd, 1)) { + ret = -ENXIO; + nmdk_dbg("NO NOMADIK NAND Device found!\n"); + goto out_ior; + } + + data->chip.badblockpos = pdata->badblockpos; + add_mtd_partitions(&data->mtd, pdata->parts, pdata->num_parts); + platform_set_drvdata(pdev, data); + return 0; + + out_ior: + if (data->cmema_va) + iounmap(data->cmema_va); + if (data->cmemd_va) + iounmap(data->cmemd_va); + if (data->cmemc_va) + iounmap(data->cmemc_va); + err: + kfree(data); + return ret; +} + +/** + * nand_default_bbt - [NAND Interface] Select a default bad block table for the device + * @mtd: MTD device structure + * + * This function selects the default bad block table + * support for the device and calls the nand_scan_bbt function + * +*/ +int nand_nomadik_bbt(struct mtd_info *mtd) +{ + struct nomadik_nand_info *drvdata = + container_of(mtd, struct nomadik_nand_info, mtd); + struct nand_chip *this = mtd->priv; + this->bbt_td = NULL; + this->bbt_md = NULL; + + return nand_scan_bbt(mtd, drvdata->bbt_desc); +} + +/* + * Clean up routine + */ +static int nomadik_nand_remove(struct platform_device *pdev) +{ + struct nomadik_nand_info *data = platform_get_drvdata(pdev); + struct nomadik_nand_platform_data *pdata = pdev->dev.platform_data; + + if(data) + nand_release(&data->mtd); + + if (pdata->exit){ + if(pdata->exit()){ + nmdk_dbg("Unable to cleanup resources completely...\n"); + } + } + + /* unmap physical addresses */ + if(data){ + iounmap(data->cmema_va); + iounmap(data->cmemd_va); + iounmap(data->cmemc_va); + kfree(data); + } + return 0; +} + +#ifdef CONFIG_PM +int nomadik_nand_suspend(struct platform_device *pdev, pm_message_t state) +{ + struct nomadik_nand_info *data = platform_get_drvdata(pdev); + int ret = 0; + nmdk_dbg_ftrace(); + if (data) + ret = data->mtd.suspend(&data->mtd); + return ret; +} + +int nomadik_nand_resume(struct platform_device *pdev) +{ + struct nomadik_nand_info *data = platform_get_drvdata(pdev); + nmdk_dbg_ftrace(); + if (data) + data->mtd.resume(&data->mtd); + return 0; +} + +#else +#define nomadik_nand_suspend NULL +#define nomadik_nand_resume NULL + +#endif + +static struct platform_driver nomadik_nand_driver = { + .probe = nomadik_nand_probe, + .remove = nomadik_nand_remove, + .driver = { + .owner = THIS_MODULE, + .name = "NOMADIK-NAND", + }, + .suspend = nomadik_nand_suspend, + .resume = nomadik_nand_resume, +}; + +static int __init nand_nomadik_init(void) +{ + return platform_driver_register(&nomadik_nand_driver); +} + +module_init(nand_nomadik_init); +static void __exit nand_nomadik_exit(void) +{ + platform_driver_unregister(&nomadik_nand_driver); + return; +} + +module_exit(nand_nomadik_exit); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("ST Microelectronics (sachin.verma@st.com)"); +MODULE_DESCRIPTION("NAND driver for Nomadik Platform"); --- linux-2.6.20.orig/drivers/mtd/onenand/Kconfig +++ linux-2.6.20/drivers/mtd/onenand/Kconfig @@ -1,39 +1,35 @@ # # linux/drivers/mtd/onenand/Kconfig # -menu "OneNAND Flash Device Drivers" - depends on MTD != n - -config MTD_ONENAND +menuconfig MTD_ONENAND tristate "OneNAND Device Support" depends on MTD help This enables support for accessing all type of OneNAND flash devices. For further information see - . + +if MTD_ONENAND config MTD_ONENAND_VERIFY_WRITE bool "Verify OneNAND page writes" - depends on MTD_ONENAND help This adds an extra check when data is written to the flash. The OneNAND flash device internally checks only bits transitioning from 1 to 0. There is a rare possibility that even though the device thinks the write was successful, a bit could have been flipped accidentally due to device wear or something else. config MTD_ONENAND_GENERIC tristate "OneNAND Flash device via platform device driver" - depends on MTD_ONENAND && ARM + depends on ARM help Support for OneNAND flash via platform device driver. config MTD_ONENAND_OTP bool "OneNAND OTP Support" - depends on MTD_ONENAND help One Block of the NAND Flash Array memory is reserved as a One-Time Programmable Block memory area. Also, 1st Block of NAND Flash Array can be used as OTP. @@ -41,6 +37,30 @@ config MTD_ONENAND_OTP operations as any other NAND Flash Array memory block. OTP block cannot be erased. OTP block is fully-guaranteed to be a valid block. -endmenu +config MTD_ONENAND_2X_PROGRAM + bool "OneNAND 2X program support" + help + The 2X Program is an extension of Program Operation. + Since the device is equipped with two DataRAMs, and two-plane NAND + Flash memory array, these two component enables simultaneous program + of 4KiB. Plane1 has only even blocks such as block0, block2, block4 + while Plane2 has only odd blocks such as block1, block3, block5. + So MTD regards it as 4KiB page size and 256KiB block size + + Now the following chips support it. (KFXXX16Q2M) + Demux: KFG2G16Q2M, KFH4G16Q2M, KFW8G16Q2M, + Mux: KFM2G16Q2M, KFN4G16Q2M, + + And more recent chips + +config MTD_ONENAND_SIM + tristate "OneNAND simulator support" + depends on MTD_PARTITIONS + help + The simulator may simulate various OneNAND flash chips for the + OneNAND MTD layer. + +endif # MTD_ONENAND + --- linux-2.6.20.orig/drivers/mtd/onenand/Makefile +++ linux-2.6.20/drivers/mtd/onenand/Makefile @@ -6,6 +6,9 @@ obj-$(CONFIG_MTD_ONENAND) += onenand.o # Board specific. obj-$(CONFIG_MTD_ONENAND_GENERIC) += generic.o +# Simulator +obj-$(CONFIG_MTD_ONENAND_SIM) += onenand_sim.o + onenand-objs = onenand_base.o onenand_bbt.o --- linux-2.6.20.orig/drivers/mtd/onenand/generic.c +++ linux-2.6.20/drivers/mtd/onenand/generic.c @@ -17,10 +17,11 @@ #include #include #include #include #include +#include #include #include #define DRIVER_NAME "onenand" @@ -34,24 +35,34 @@ struct onenand_info { struct mtd_info mtd; struct mtd_partition *parts; struct onenand_chip onenand; }; -static int __devinit generic_onenand_probe(struct device *dev) +static int __devinit generic_onenand_probe(struct platform_device *pdev) { struct onenand_info *info; - struct platform_device *pdev = to_platform_device(dev); struct flash_platform_data *pdata = pdev->dev.platform_data; struct resource *res = pdev->resource; unsigned long size = res->end - res->start + 1; int err; + /* ST Specific part */ + #ifdef CONFIG_ARCH_NOMADIK + int x; + x=pdata->init(); + if(x==-1) + { printk("Init failed\n"); + err=-EPERM; + return err; + } + #endif + info = kzalloc(sizeof(struct onenand_info), GFP_KERNEL); if (!info) return -ENOMEM; - if (!request_mem_region(res->start, size, dev->driver->name)) { + if (!request_mem_region(res->start, size, pdev->name)) { err = -EBUSY; goto out_free_info; } info->onenand.base = ioremap(res->start, size); @@ -94,15 +105,16 @@ out_free_info: kfree(info); return err; } -static int __devexit generic_onenand_remove(struct device *dev) +static int generic_onenand_remove(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); struct onenand_info *info = dev_get_drvdata(&pdev->dev); struct resource *res = pdev->resource; + struct flash_platform_data *pdata = pdev->dev.platform_data; unsigned long size = res->end - res->start + 1; dev_set_drvdata(&pdev->dev, NULL); if (info) { @@ -114,31 +126,61 @@ static int __devexit generic_onenand_rem onenand_release(&info->mtd); release_mem_region(res->start, size); iounmap(info->onenand.base); kfree(info); } + #ifdef CONFIG_ARCH_NOMADIK + pdata->exit(); + #endif return 0; } -static struct device_driver generic_onenand_driver = { - .name = DRIVER_NAME, - .bus = &platform_bus_type, +#ifdef CONFIG_PM +int nomadik_onenand_suspend(struct platform_device *pdev, pm_message_t state) +{ + struct onenand_info *data = platform_get_drvdata(pdev); + int ret = 0; + if (data) + ret = data->mtd.suspend(&data->mtd); + return ret; +} + +int nomadik_onenand_resume(struct platform_device *pdev) +{ + struct onenand_info *data = platform_get_drvdata(pdev); + if (data) + data->mtd.resume(&data->mtd); + return 0; +} + +#else +#define nomadik_onenand_suspend NULL +#define nomadik_onenand_resume NULL +#endif + +static struct platform_driver generic_onenand_driver = { .probe = generic_onenand_probe, - .remove = __devexit_p(generic_onenand_remove), + .remove = generic_onenand_remove, + .driver = { + .owner = THIS_MODULE, + .name = DRIVER_NAME, + }, + .suspend = nomadik_onenand_suspend, + .resume = nomadik_onenand_resume, }; MODULE_ALIAS(DRIVER_NAME); static int __init generic_onenand_init(void) { - return driver_register(&generic_onenand_driver); + return platform_driver_register(&generic_onenand_driver); } static void __exit generic_onenand_exit(void) { - driver_unregister(&generic_onenand_driver); + platform_driver_unregister(&generic_onenand_driver); } module_init(generic_onenand_init); module_exit(generic_onenand_exit); --- linux-2.6.20.orig/drivers/mtd/onenand/onenand_base.c +++ linux-2.6.20/drivers/mtd/onenand/onenand_base.c @@ -31,12 +31,12 @@ static struct nand_ecclayout onenand_oob 24, 25, 26, 27, 28, 40, 41, 42, 43, 44, 56, 57, 58, 59, 60, }, .oobfree = { - {2, 3}, {14, 2}, {18, 3}, {30, 2}, - {34, 3}, {46, 2}, {50, 3}, {62, 2} + {13, 11}, {29, 11}, + {45, 11}, {61, 3}, } }; /** * onenand_oob_32 - oob info for middle (1KB) page @@ -59,10 +59,21 @@ static const unsigned char ffchars[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 48 */ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 64 */ }; +void *imemcopy(void * dest,const void *src,size_t count) +{ + u16 *tmp = (u16 *) dest, *s = (u16 *) src; + + count = count/2; + while (count--) + *tmp++ = *s++; + + return dest; +} + /** * onenand_readw - [OneNAND Interface] Read OneNAND register * @param addr address to read * * Read OneNAND register @@ -92,20 +103,13 @@ static void onenand_writew(unsigned shor * * Setup Start Address 1 Register (F100h) */ static int onenand_block_address(struct onenand_chip *this, int block) { - if (this->device_id & ONENAND_DEVICE_IS_DDP) { /* Device Flash Core select, NAND Flash Block Address */ - int dfs = 0; - if (block & this->density_mask) - dfs = 1; - - return (dfs << ONENAND_DDP_SHIFT) | - (block & (this->density_mask - 1)); - } + return ONENAND_DDP_CHIP1 | (block ^ this->density_mask); return block; } /** @@ -116,21 +120,15 @@ static int onenand_block_address(struct * * Setup Start Address 2 Register (F101h) for DDP */ static int onenand_bufferram_address(struct onenand_chip *this, int block) { - if (this->device_id & ONENAND_DEVICE_IS_DDP) { /* Device BufferRAM Select */ - int dbs = 0; - if (block & this->density_mask) - dbs = 1; - - return (dbs << ONENAND_DDP_SHIFT); - } + return ONENAND_DDP_CHIP1; - return 0; + return ONENAND_DDP_CHIP0; } /** * onenand_page_address - [DEFAULT] Get page address * @param page the page address @@ -212,20 +210,33 @@ static int onenand_command(struct mtd_in break; default: block = (int) (addr >> this->erase_shift); page = (int) (addr >> this->page_shift); + + if (ONENAND_IS_2PLANE(this)) { + /* Make the even block number */ + block &= ~1; + /* Is it the odd plane? */ + if (addr & this->writesize) + block++; + page >>= 1; + } page &= this->page_mask; break; } /* NOTE: The setting order of the registers is very important! */ if (cmd == ONENAND_CMD_BUFFERRAM) { /* Select DataRAM for DDP */ value = onenand_bufferram_address(this, block); this->write_word(value, this->base + ONENAND_REG_START_ADDRESS2); + if (ONENAND_IS_2PLANE(this)) + /* It is always BufferRAM0 */ + ONENAND_SET_BUFFERRAM0(this); + else /* Switch to the next data buffer */ ONENAND_SET_NEXT_BUFFERRAM(this); return 0; } @@ -253,10 +264,12 @@ static int onenand_command(struct mtd_in dataram = ONENAND_SET_NEXT_BUFFERRAM(this); readcmd = 1; break; default: + if (ONENAND_IS_2PLANE(this) && cmd == ONENAND_CMD_PROG) + cmd = ONENAND_CMD_2X_PROG; dataram = ONENAND_CURRENT_BUFFERRAM(this); break; } /* Write 'FPA, FSA' of Flash */ @@ -315,27 +328,32 @@ static int onenand_wait(struct mtd_info interrupt = this->read_word(this->base + ONENAND_REG_INTERRUPT); ctrl = this->read_word(this->base + ONENAND_REG_CTRL_STATUS); if (ctrl & ONENAND_CTRL_ERROR) { - DEBUG(MTD_DEBUG_LEVEL0, "onenand_wait: controller error = 0x%04x\n", ctrl); + printk(KERN_ERR "onenand_wait: controller error = 0x%04x\n", ctrl); if (ctrl & ONENAND_CTRL_LOCK) - DEBUG(MTD_DEBUG_LEVEL0, "onenand_wait: it's locked error.\n"); - return ctrl; + printk(KERN_ERR "onenand_wait: it's locked error.\n"); + return -EIO; } if (interrupt & ONENAND_INT_READ) { int ecc = this->read_word(this->base + ONENAND_REG_ECC_STATUS); if (ecc) { - DEBUG(MTD_DEBUG_LEVEL0, "onenand_wait: ECC error = 0x%04x\n", ecc); if (ecc & ONENAND_ECC_2BIT_ALL) { + printk(KERN_ERR "onenand_wait: ECC error = 0x%04x\n", ecc); mtd->ecc_stats.failed++; - return ecc; - } else if (ecc & ONENAND_ECC_1BIT_ALL) + return -EBADMSG; + } else if (ecc & ONENAND_ECC_1BIT_ALL) { + printk(KERN_INFO "onenand_wait: correctable ECC error = 0x%04x\n", ecc); mtd->ecc_stats.corrected++; } } + } else if (state == FL_READING) { + printk(KERN_ERR "onenand_wait: read timeout! ctrl=0x%04x intr=0x%04x\n", ctrl, interrupt); + return -EIO; + } return 0; } /* @@ -345,11 +363,11 @@ static int onenand_wait(struct mtd_info * * complete the work */ static irqreturn_t onenand_interrupt(int irq, void *data) { - struct onenand_chip *this = (struct onenand_chip *) data; + struct onenand_chip *this = data; /* To handle shared interrupt */ if (!this->complete.done) complete(&this->complete); @@ -448,12 +466,13 @@ static void onenand_setup_wait(struct mt static inline int onenand_bufferram_offset(struct mtd_info *mtd, int area) { struct onenand_chip *this = mtd->priv; if (ONENAND_CURRENT_BUFFERRAM(this)) { + /* Note: the 'this->writesize' is a real page size */ if (area == ONENAND_DATARAM) - return mtd->writesize; + return this->writesize; if (area == ONENAND_SPARERAM) return mtd->oobsize; } return 0; @@ -472,28 +491,24 @@ static inline int onenand_bufferram_offs static int onenand_read_bufferram(struct mtd_info *mtd, int area, unsigned char *buffer, int offset, size_t count) { struct onenand_chip *this = mtd->priv; void __iomem *bufferram; - + int *dest=NULL; bufferram = this->base + area; bufferram += onenand_bufferram_offset(mtd, area); - if (ONENAND_CHECK_BYTE_ACCESS(count)) { unsigned short word; - /* Align with word(16-bit) size */ count--; /* Read word and save byte */ word = this->read_word(bufferram + offset + count); buffer[count] = (word & 0xff); } - - memcpy(buffer, bufferram + offset, count); - + dest=imemcopy(buffer, bufferram + offset, count); return 0; } /** * onenand_sync_read_bufferram - [OneNAND Interface] Read the bufferram area with Sync. Burst mode @@ -508,11 +523,11 @@ static int onenand_read_bufferram(struct static int onenand_sync_read_bufferram(struct mtd_info *mtd, int area, unsigned char *buffer, int offset, size_t count) { struct onenand_chip *this = mtd->priv; void __iomem *bufferram; - + int *dest=NULL; bufferram = this->base + area; bufferram += onenand_bufferram_offset(mtd, area); this->mmcontrol(mtd, ONENAND_SYS_CFG1_SYNC_READ); @@ -526,12 +541,11 @@ static int onenand_sync_read_bufferram(s /* Read word and save byte */ word = this->read_word(bufferram + offset + count); buffer[count] = (word & 0xff); } - memcpy(buffer, bufferram + offset, count); - + dest=imemcopy(buffer, bufferram + offset, count); this->mmcontrol(mtd, 0); return 0; } @@ -548,10 +562,11 @@ static int onenand_sync_read_bufferram(s static int onenand_write_bufferram(struct mtd_info *mtd, int area, const unsigned char *buffer, int offset, size_t count) { struct onenand_chip *this = mtd->priv; void __iomem *bufferram; + int *dest=NULL; bufferram = this->base + area; bufferram += onenand_bufferram_offset(mtd, area); @@ -569,77 +584,134 @@ static int onenand_write_bufferram(struc word = this->read_word(bufferram + byte_offset); word = (word & ~0xff) | buffer[count]; this->write_word(word, bufferram + byte_offset); } - memcpy(bufferram + offset, buffer, count); - + dest=imemcopy(bufferram + offset, buffer, count); return 0; } /** + * onenand_get_2x_blockpage - [GENERIC] Get blockpage at 2x program mode + * @param mtd MTD data structure + * @param addr address to check + * @return blockpage address + * + * Get blockpage address at 2x program mode + */ +static int onenand_get_2x_blockpage(struct mtd_info *mtd, loff_t addr) +{ + struct onenand_chip *this = mtd->priv; + int blockpage, block, page; + + /* Calculate the even block number */ + block = (int) (addr >> this->erase_shift) & ~1; + /* Is it the odd plane? */ + if (addr & this->writesize) + block++; + page = (int) (addr >> (this->page_shift + 1)) & this->page_mask; + blockpage = (block << 7) | page; + + return blockpage; +} + +/** * onenand_check_bufferram - [GENERIC] Check BufferRAM information * @param mtd MTD data structure * @param addr address to check * @return 1 if there are valid data, otherwise 0 * * Check bufferram if there is data we required */ static int onenand_check_bufferram(struct mtd_info *mtd, loff_t addr) { struct onenand_chip *this = mtd->priv; - int block, page; - int i; + int blockpage, found = 0; + unsigned int i; - block = (int) (addr >> this->erase_shift); - page = (int) (addr >> this->page_shift); - page &= this->page_mask; + if (ONENAND_IS_2PLANE(this)) + blockpage = onenand_get_2x_blockpage(mtd, addr); + else + blockpage = (int) (addr >> this->page_shift); + /* Is there valid data? */ i = ONENAND_CURRENT_BUFFERRAM(this); + if (this->bufferram[i].blockpage == blockpage) + found = 1; + else { + /* Check another BufferRAM */ + i = ONENAND_NEXT_BUFFERRAM(this); + if (this->bufferram[i].blockpage == blockpage) { + ONENAND_SET_NEXT_BUFFERRAM(this); + found = 1; + } + } - /* Is there valid data? */ - if (this->bufferram[i].block == block && - this->bufferram[i].page == page && - this->bufferram[i].valid) - return 1; + if (found && ONENAND_IS_DDP(this)) { + /* Select DataRAM for DDP */ + int block = (int) (addr >> this->erase_shift); + int value = onenand_bufferram_address(this, block); + this->write_word(value, this->base + ONENAND_REG_START_ADDRESS2); + } - return 0; + return found; } /** * onenand_update_bufferram - [GENERIC] Update BufferRAM information * @param mtd MTD data structure * @param addr address to update * @param valid valid flag * * Update BufferRAM information */ -static int onenand_update_bufferram(struct mtd_info *mtd, loff_t addr, +static void onenand_update_bufferram(struct mtd_info *mtd, loff_t addr, int valid) { struct onenand_chip *this = mtd->priv; - int block, page; - int i; + int blockpage; + unsigned int i; - block = (int) (addr >> this->erase_shift); - page = (int) (addr >> this->page_shift); - page &= this->page_mask; + if (ONENAND_IS_2PLANE(this)) + blockpage = onenand_get_2x_blockpage(mtd, addr); + else + blockpage = (int) (addr >> this->page_shift); - /* Invalidate BufferRAM */ - for (i = 0; i < MAX_BUFFERRAM; i++) { - if (this->bufferram[i].block == block && - this->bufferram[i].page == page) - this->bufferram[i].valid = 0; - } + /* Invalidate another BufferRAM */ + i = ONENAND_NEXT_BUFFERRAM(this); + if (this->bufferram[i].blockpage == blockpage) + this->bufferram[i].blockpage = -1; /* Update BufferRAM */ i = ONENAND_CURRENT_BUFFERRAM(this); - this->bufferram[i].block = block; - this->bufferram[i].page = page; - this->bufferram[i].valid = valid; + if (valid) + this->bufferram[i].blockpage = blockpage; + else + this->bufferram[i].blockpage = -1; +} - return 0; +/** + * onenand_invalidate_bufferram - [GENERIC] Invalidate BufferRAM information + * @param mtd MTD data structure + * @param addr start address to invalidate + * @param len length to invalidate + * + * Invalidate BufferRAM information + */ +static void onenand_invalidate_bufferram(struct mtd_info *mtd, loff_t addr, + unsigned int len) +{ + struct onenand_chip *this = mtd->priv; + int i; + loff_t end_addr = addr + len; + + /* Invalidate BufferRAM */ + for (i = 0; i < MAX_BUFFERRAM; i++) { + loff_t buf_addr = this->bufferram[i].blockpage << this->page_shift; + if (buf_addr >= addr && buf_addr < end_addr) + this->bufferram[i].blockpage = -1; + } } /** * onenand_get_device - [GENERIC] Get chip for selected access * @param mtd MTD device structure @@ -692,167 +764,246 @@ static void onenand_release_device(struc wake_up(&this->wq); spin_unlock(&this->chip_lock); } /** - * onenand_read - [MTD Interface] Read data from flash + * onenand_transfer_auto_oob - [Internal] oob auto-placement transfer + * @param mtd MTD device structure + * @param buf destination address + * @param column oob offset to read from + * @param thislen oob length to read + */ +static int onenand_transfer_auto_oob(struct mtd_info *mtd, uint8_t *buf, int column, + int thislen) +{ + struct onenand_chip *this = mtd->priv; + struct nand_oobfree *free; + int readcol = column; + int readend = column + thislen; + int lastgap = 0; + unsigned int i; + uint8_t *oob_buf = this->oob_buf; + + free = this->ecclayout->oobfree; + for (i = 0; i < MTD_MAX_OOBFREE_ENTRIES && free->length; i++, free++) { + if (readcol >= lastgap) + readcol += free->offset - lastgap; + if (readend >= lastgap) + readend += free->offset - lastgap; + lastgap = free->offset + free->length; + } + this->read_bufferram(mtd, ONENAND_SPARERAM, oob_buf, 0, mtd->oobsize); + free = this->ecclayout->oobfree; + for (i = 0; i < MTD_MAX_OOBFREE_ENTRIES && free->length; i++, free++) { + int free_end = free->offset + free->length; + if (free->offset < readend && free_end > readcol) { + int st = max_t(int,free->offset,readcol); + int ed = min_t(int,free_end,readend); + int n = ed - st; + memcpy(buf, oob_buf + st, n); + buf += n; + } else if (column == 0) + break; + } + return 0; +} + +/** + * onenand_read_ops_nolock - [OneNAND Interface] OneNAND read main and/or out-of-band * @param mtd MTD device structure * @param from offset to read from - * @param len number of bytes to read - * @param retlen pointer to variable to store the number of read bytes - * @param buf the databuffer to put data + * @param ops: oob operation description structure * - * Read with ecc + * OneNAND read main and/or out-of-band data */ -static int onenand_read(struct mtd_info *mtd, loff_t from, size_t len, - size_t *retlen, u_char *buf) +static int onenand_read_ops_nolock(struct mtd_info *mtd, loff_t from, + struct mtd_oob_ops *ops) { struct onenand_chip *this = mtd->priv; struct mtd_ecc_stats stats; - int read = 0, column; - int thislen; + size_t len = ops->len; + size_t ooblen = ops->ooblen; + u_char *buf = ops->datbuf; + u_char *oobbuf = ops->oobbuf; + int read = 0, column, thislen; + int oobread = 0, oobcolumn, thisooblen, oobsize; int ret = 0, boundary = 0; + int writesize = this->writesize; + + DEBUG(MTD_DEBUG_LEVEL3, "onenand_read_ops_nolock: from = 0x%08x, len = %i\n", (unsigned int) from, (int) len); - DEBUG(MTD_DEBUG_LEVEL3, "onenand_read: from = 0x%08x, len = %i\n", (unsigned int) from, (int) len); + if (ops->mode == MTD_OOB_AUTO) + oobsize = this->ecclayout->oobavail; + else + oobsize = mtd->oobsize; + + oobcolumn = from & (mtd->oobsize - 1); /* Do not allow reads past end of device */ if ((from + len) > mtd->size) { - DEBUG(MTD_DEBUG_LEVEL0, "onenand_read: Attempt read beyond end of device\n"); - *retlen = 0; + ops->retlen = 0; + ops->oobretlen = 0; return -EINVAL; } - /* Grab the lock and see if the device is available */ - onenand_get_device(mtd, FL_READING); - - /* TODO handling oob */ - stats = mtd->ecc_stats; /* Read-while-load method */ /* Do first load to bufferRAM */ if (read < len) { if (!onenand_check_bufferram(mtd, from)) { - this->command(mtd, ONENAND_CMD_READ, from, mtd->writesize); + this->command(mtd, ONENAND_CMD_READ, from, writesize); ret = this->wait(mtd, FL_READING); onenand_update_bufferram(mtd, from, !ret); } } - thislen = min_t(int, mtd->writesize, len - read); - column = from & (mtd->writesize - 1); - if (column + thislen > mtd->writesize) - thislen = mtd->writesize - column; + thislen = min_t(int, writesize, len - read); + column = from & (writesize - 1); + if (column + thislen > writesize) + thislen = writesize - column; while (!ret) { /* If there is more to load then start next load */ from += thislen; if (read + thislen < len) { - this->command(mtd, ONENAND_CMD_READ, from, mtd->writesize); + this->command(mtd, ONENAND_CMD_READ, from, writesize); /* * Chip boundary handling in DDP * Now we issued chip 1 read and pointed chip 1 * bufferam so we have to point chip 0 bufferam. */ - if (this->device_id & ONENAND_DEVICE_IS_DDP && + if (ONENAND_IS_DDP(this) && unlikely(from == (this->chipsize >> 1))) { - this->write_word(0, this->base + ONENAND_REG_START_ADDRESS2); + this->write_word(ONENAND_DDP_CHIP0, this->base + ONENAND_REG_START_ADDRESS2); boundary = 1; - } else + } else{ boundary = 0; + } ONENAND_SET_PREV_BUFFERRAM(this); } /* While load is going, read from last bufferRAM */ this->read_bufferram(mtd, ONENAND_DATARAM, buf, column, thislen); + /* Read oob area if needed */ + if (oobbuf) { + thisooblen = oobsize - oobcolumn; + thisooblen = min_t(int, thisooblen, ooblen - oobread); + + if (ops->mode == MTD_OOB_AUTO){ + onenand_transfer_auto_oob(mtd, oobbuf, oobcolumn, thisooblen); + } + else{ + this->read_bufferram(mtd, ONENAND_SPARERAM, oobbuf, oobcolumn, thisooblen); + } + oobread += thisooblen; + oobbuf += thisooblen; + oobcolumn = 0; + } /* See if we are done */ read += thislen; if (read == len) break; /* Set up for next read from bufferRAM */ - if (unlikely(boundary)) - this->write_word(0x8000, this->base + ONENAND_REG_START_ADDRESS2); + if (unlikely(boundary)){ + this->write_word(ONENAND_DDP_CHIP1, this->base + ONENAND_REG_START_ADDRESS2); + } ONENAND_SET_NEXT_BUFFERRAM(this); buf += thislen; - thislen = min_t(int, mtd->writesize, len - read); + thislen = min_t(int, writesize, len - read); column = 0; cond_resched(); /* Now wait for load */ ret = this->wait(mtd, FL_READING); onenand_update_bufferram(mtd, from, !ret); } - /* Deselect and wake up anyone waiting on the device */ - onenand_release_device(mtd); - /* * Return success, if no ECC failures, else -EBADMSG * fs driver will take care of that, because * retlen == desired len and result == -EBADMSG */ - *retlen = read; + ops->retlen = read; + ops->oobretlen = oobread; if (mtd->ecc_stats.failed - stats.failed) - return -EBADMSG; + { return -EBADMSG; + } if (ret) - return ret; - + { return ret; + } return mtd->ecc_stats.corrected - stats.corrected ? -EUCLEAN : 0; } /** - * onenand_do_read_oob - [MTD Interface] OneNAND read out-of-band + * onenand_read_oob_nolock - [MTD Interface] OneNAND read out-of-band * @param mtd MTD device structure * @param from offset to read from - * @param len number of bytes to read - * @param retlen pointer to variable to store the number of read bytes - * @param buf the databuffer to put data + * @param ops: oob operation description structure * * OneNAND read out-of-band data from the spare area */ -int onenand_do_read_oob(struct mtd_info *mtd, loff_t from, size_t len, - size_t *retlen, u_char *buf) +static int onenand_read_oob_nolock(struct mtd_info *mtd, loff_t from, + struct mtd_oob_ops *ops) { struct onenand_chip *this = mtd->priv; - int read = 0, thislen, column; + int read = 0, thislen, column, oobsize; + size_t len = ops->ooblen; + mtd_oob_mode_t mode = ops->mode; + u_char *buf = ops->oobbuf; int ret = 0; - DEBUG(MTD_DEBUG_LEVEL3, "onenand_read_oob: from = 0x%08x, len = %i\n", (unsigned int) from, (int) len); + from += ops->ooboffs; - /* Initialize return length value */ - *retlen = 0; + DEBUG(MTD_DEBUG_LEVEL3, "onenand_read_oob_nolock: from = 0x%08x, len = %i\n", (unsigned int) from, (int) len); - /* Do not allow reads past end of device */ - if (unlikely((from + len) > mtd->size)) { - DEBUG(MTD_DEBUG_LEVEL0, "onenand_read_oob: Attempt read beyond end of device\n"); - return -EINVAL; - } + /* Initialize return length value */ + ops->oobretlen = 0; - /* Grab the lock and see if the device is available */ - onenand_get_device(mtd, FL_READING); + if (mode == MTD_OOB_AUTO) + oobsize = this->ecclayout->oobavail; + else + oobsize = mtd->oobsize; column = from & (mtd->oobsize - 1); + if (unlikely(column >= oobsize)) { + printk(KERN_ERR "onenand_read_oob_nolock: Attempted to start read outside oob\n"); + return -EINVAL; + } + + /* Do not allow reads past end of device */ + if (unlikely(from >= mtd->size || + column + len > ((mtd->size >> this->page_shift) - + (from >> this->page_shift)) * oobsize)) { + printk(KERN_ERR "onenand_read_oob_nolock: Attempted to read beyond end of device\n"); + return -EINVAL; + } while (read < len) { cond_resched(); - thislen = mtd->oobsize - column; + thislen = oobsize - column; thislen = min_t(int, thislen, len); this->command(mtd, ONENAND_CMD_READOOB, from, mtd->oobsize); onenand_update_bufferram(mtd, from, 0); - ret = this->wait(mtd, FL_READING); /* First copy data and check return value for ECC handling */ + if (mode == MTD_OOB_AUTO) + { onenand_transfer_auto_oob(mtd, buf, column, thislen); + } + else + { this->read_bufferram(mtd, ONENAND_SPARERAM, buf, column, thislen); + } if (ret) { - DEBUG(MTD_DEBUG_LEVEL0, "onenand_read_oob: read failed = 0x%x\n", ret); - goto out; + printk(KERN_ERR "onenand_read_oob_nolock: read failed = 0x%x\n", ret); + break; } read += thislen; if (read == len) @@ -866,184 +1017,417 @@ int onenand_do_read_oob(struct mtd_info from += mtd->writesize; column = 0; } } -out: - /* Deselect and wake up anyone waiting on the device */ + ops->oobretlen = read; + return ret; +} + +/** + * onenand_read - [MTD Interface] Read data from flash + * @param mtd MTD device structure + * @param from offset to read from + * @param len number of bytes to read + * @param retlen pointer to variable to store the number of read bytes + * @param buf the databuffer to put data + * + * Read with ecc +*/ +static int onenand_read(struct mtd_info *mtd, loff_t from, size_t len, + size_t *retlen, u_char *buf) +{ + struct mtd_oob_ops ops = { + .len = len, + .ooblen = 0, + .datbuf = buf, + .oobbuf = NULL, + }; + int ret; + + onenand_get_device(mtd, FL_READING); + ret = onenand_read_ops_nolock(mtd, from, &ops); onenand_release_device(mtd); - *retlen = read; + *retlen = ops.retlen; return ret; } /** - * onenand_read_oob - [MTD Interface] NAND write data and/or out-of-band - * @mtd: MTD device structure - * @from: offset to read from - * @ops: oob operation description structure + * onenand_read_oob - [MTD Interface] Read main and/or out-of-band + * @param mtd: MTD device structure + * @param from: offset to read from + * @param ops: oob operation description structure + + * Read main and/or out-of-band */ static int onenand_read_oob(struct mtd_info *mtd, loff_t from, struct mtd_oob_ops *ops) { - BUG_ON(ops->mode != MTD_OOB_PLACE); + int ret; + + switch (ops->mode) { + case MTD_OOB_PLACE: + case MTD_OOB_AUTO: + break; + case MTD_OOB_RAW: + /* Not implemented yet */ + default: + return -EINVAL; + } + + onenand_get_device(mtd, FL_READING); + if (ops->datbuf) + ret = onenand_read_ops_nolock(mtd, from, ops); + else + ret = onenand_read_oob_nolock(mtd, from, ops); + onenand_release_device(mtd); + + return ret; +} + +/** + * onenand_bbt_wait - [DEFAULT] wait until the command is done + * @param mtd MTD device structure + * @param state state to select the max. timeout value + * + * Wait for command done. + */ +static int onenand_bbt_wait(struct mtd_info *mtd, int state) +{ + struct onenand_chip *this = mtd->priv; + unsigned long timeout; + unsigned int interrupt; + unsigned int ctrl; - return onenand_do_read_oob(mtd, from + ops->ooboffs, ops->ooblen, - &ops->oobretlen, ops->oobbuf); + /* The 20 msec is enough */ + timeout = jiffies + msecs_to_jiffies(20); + while (time_before(jiffies, timeout)) { + interrupt = this->read_word(this->base + ONENAND_REG_INTERRUPT); + if (interrupt & ONENAND_INT_MASTER) + break; + } + /* To get correct interrupt status in timeout case */ + interrupt = this->read_word(this->base + ONENAND_REG_INTERRUPT); + ctrl = this->read_word(this->base + ONENAND_REG_CTRL_STATUS); + + if (ctrl & ONENAND_CTRL_ERROR) { + printk(KERN_DEBUG "onenand_bbt_wait: controller error = 0x%04x\n", ctrl); + /* Initial bad block case */ + if (ctrl & ONENAND_CTRL_LOAD) + return ONENAND_BBT_READ_ERROR; + return ONENAND_BBT_READ_FATAL_ERROR; + } + + if (interrupt & ONENAND_INT_READ) { + int ecc = this->read_word(this->base + ONENAND_REG_ECC_STATUS); + if (ecc & ONENAND_ECC_2BIT_ALL) + return ONENAND_BBT_READ_ERROR; + } else { + printk(KERN_ERR "onenand_bbt_wait: read timeout!" + "ctrl=0x%04x intr=0x%04x\n", ctrl, interrupt); + return ONENAND_BBT_READ_FATAL_ERROR; + } + + return 0; +} + +/** + * onenand_bbt_read_oob - [MTD Interface] OneNAND read out-of-band for bbt scan + * @param mtd MTD device structure + * @param from offset to read from + * @param ops oob operation description structure + * + * OneNAND read out-of-band data from the spare area for bbt scan + */ +int onenand_bbt_read_oob(struct mtd_info *mtd, loff_t from, + struct mtd_oob_ops *ops) +{ + struct onenand_chip *this = mtd->priv; + int read = 0, thislen, column; + int ret = 0; + size_t len = ops->ooblen; + u_char *buf = ops->oobbuf; + + DEBUG(MTD_DEBUG_LEVEL3, "onenand_bbt_read_oob: from = 0x%08x, len = %zi\n", (unsigned int) from, len); + + /* Initialize return value */ + ops->oobretlen = 0; + + /* Do not allow reads past end of device */ + if (unlikely((from + len) > mtd->size)) { + printk(KERN_ERR "onenand_bbt_read_oob: Attempt read beyond end of device\n"); + return ONENAND_BBT_READ_FATAL_ERROR; + } + + /* Grab the lock and see if the device is available */ + onenand_get_device(mtd, FL_READING); + + column = from & (mtd->oobsize - 1); + + while (read < len) { + cond_resched(); + + thislen = mtd->oobsize - column; + thislen = min_t(int, thislen, len); + + this->command(mtd, ONENAND_CMD_READOOB, from, mtd->oobsize); + + onenand_update_bufferram(mtd, from, 0); + + ret = onenand_bbt_wait(mtd, FL_READING); + if (ret) + break; + + this->read_bufferram(mtd, ONENAND_SPARERAM, buf, column, thislen); + read += thislen; + if (read == len) + break; + + buf += thislen; + + /* Read more? */ + if (read < len) { + /* Update Page size */ + from += this->writesize; + column = 0; + } + } + + /* Deselect and wake up anyone waiting on the device */ + onenand_release_device(mtd); + + ops->oobretlen = read; + return ret; } #ifdef CONFIG_MTD_ONENAND_VERIFY_WRITE /** * onenand_verify_oob - [GENERIC] verify the oob contents after a write * @param mtd MTD device structure * @param buf the databuffer to verify * @param to offset to read from - * @param len number of bytes to read and compare - * */ -static int onenand_verify_oob(struct mtd_info *mtd, const u_char *buf, loff_t to, int len) +static int onenand_verify_oob(struct mtd_info *mtd, const u_char *buf, loff_t to) { struct onenand_chip *this = mtd->priv; - char *readp = this->page_buf; - int column = to & (mtd->oobsize - 1); + char oobbuf[64]; int status, i; this->command(mtd, ONENAND_CMD_READOOB, to, mtd->oobsize); onenand_update_bufferram(mtd, to, 0); status = this->wait(mtd, FL_READING); if (status) return status; - this->read_bufferram(mtd, ONENAND_SPARERAM, readp, column, len); - - for(i = 0; i < len; i++) - if (buf[i] != 0xFF && buf[i] != readp[i]) + this->read_bufferram(mtd, ONENAND_SPARERAM, oobbuf, 0, mtd->oobsize); + for (i = 0; i < mtd->oobsize; i++) + if (buf[i] != 0xFF && buf[i] != oobbuf[i]) return -EBADMSG; return 0; } /** - * onenand_verify_page - [GENERIC] verify the chip contents after a write + * onenand_verify - [GENERIC] verify the chip contents after a write * @param mtd MTD device structure * @param buf the databuffer to verify - * - * Check DataRAM area directly + * @param addr offset to read from + * @param len number of bytes to read and compare */ -static int onenand_verify_page(struct mtd_info *mtd, u_char *buf, loff_t addr) +static int onenand_verify(struct mtd_info *mtd, const u_char *buf, loff_t addr, size_t len) { struct onenand_chip *this = mtd->priv; - void __iomem *dataram0, *dataram1; + void __iomem *dataram; int ret = 0; + int thislen, column; - /* In partial page write, just skip it */ - if ((addr & (mtd->writesize - 1)) != 0) - return 0; + while (len != 0) { + thislen = min_t(int, this->writesize, len); + column = addr & (this->writesize - 1); + if (column + thislen > this->writesize) + thislen = this->writesize - column; - this->command(mtd, ONENAND_CMD_READ, addr, mtd->writesize); + this->command(mtd, ONENAND_CMD_READ, addr, this->writesize); + + onenand_update_bufferram(mtd, addr, 0); ret = this->wait(mtd, FL_READING); if (ret) return ret; onenand_update_bufferram(mtd, addr, 1); - /* Check, if the two dataram areas are same */ - dataram0 = this->base + ONENAND_DATARAM; - dataram1 = dataram0 + mtd->writesize; + dataram = this->base + ONENAND_DATARAM; + dataram += onenand_bufferram_offset(mtd, ONENAND_DATARAM); - if (memcmp(dataram0, dataram1, mtd->writesize)) + if (memcmp(buf, dataram + column, thislen)) return -EBADMSG; + len -= thislen; + buf += thislen; + addr += thislen; + } + return 0; } #else -#define onenand_verify_page(...) (0) +#define onenand_verify(...) (0) #define onenand_verify_oob(...) (0) #endif #define NOTALIGNED(x) ((x & (this->subpagesize - 1)) != 0) /** - * onenand_write - [MTD Interface] write buffer to FLASH + * onenand_fill_auto_oob - [Internal] oob auto-placement transfer + * @param mtd MTD device structure + * @param oob_buf oob buffer + * @param buf source address + * @param column oob offset to write to + * @param thislen oob length to write + */ +static int onenand_fill_auto_oob(struct mtd_info *mtd, u_char *oob_buf, + const u_char *buf, int column, int thislen) +{ + struct onenand_chip *this = mtd->priv; + struct nand_oobfree *free; + int writecol = column; + int writeend = column + thislen; + int lastgap = 0; + unsigned int i; + + free = this->ecclayout->oobfree; + for (i = 0; i < MTD_MAX_OOBFREE_ENTRIES && free->length; i++, free++) { + if (writecol >= lastgap) + writecol += free->offset - lastgap; + if (writeend >= lastgap) + writeend += free->offset - lastgap; + lastgap = free->offset + free->length; + } + free = this->ecclayout->oobfree; + for (i = 0; i < MTD_MAX_OOBFREE_ENTRIES && free->length; i++, free++) { + int free_end = free->offset + free->length; + if (free->offset < writeend && free_end > writecol) { + int st = max_t(int,free->offset,writecol); + int ed = min_t(int,free_end,writeend); + int n = ed - st; + memcpy(oob_buf + st, buf, n); + buf += n; + } else if (column == 0) + break; + } + return 0; +} + +/** + * onenand_write_ops_nolock - [OneNAND Interface] write main and/or out-of-band * @param mtd MTD device structure * @param to offset to write to - * @param len number of bytes to write - * @param retlen pointer to variable to store the number of written bytes - * @param buf the data to write + * @param ops oob operation description structure * - * Write with ECC + * Write main and/or oob with ECC */ -static int onenand_write(struct mtd_info *mtd, loff_t to, size_t len, - size_t *retlen, const u_char *buf) +static int onenand_write_ops_nolock(struct mtd_info *mtd, loff_t to, + struct mtd_oob_ops *ops) { struct onenand_chip *this = mtd->priv; - int written = 0; + int written = 0, column, thislen, subpage; + int oobwritten = 0, oobcolumn, thisooblen, oobsize; + size_t len = ops->len; + size_t ooblen = ops->ooblen; + const u_char *buf = ops->datbuf; + const u_char *oob = ops->oobbuf; + u_char *oobbuf; int ret = 0; - int column, subpage; - DEBUG(MTD_DEBUG_LEVEL3, "onenand_write: to = 0x%08x, len = %i\n", (unsigned int) to, (int) len); + DEBUG(MTD_DEBUG_LEVEL3, "onenand_write_ops_nolock: to = 0x%08x, len = %i\n", (unsigned int) to, (int) len); /* Initialize retlen, in case of early exit */ - *retlen = 0; + ops->retlen = 0; + ops->oobretlen = 0; /* Do not allow writes past end of device */ if (unlikely((to + len) > mtd->size)) { - DEBUG(MTD_DEBUG_LEVEL0, "onenand_write: Attempt write to past end of device\n"); + printk(KERN_ERR "onenand_write_ops_nolock: Attempt write to past end of device\n"); return -EINVAL; } /* Reject writes, which are not page aligned */ if (unlikely(NOTALIGNED(to)) || unlikely(NOTALIGNED(len))) { - DEBUG(MTD_DEBUG_LEVEL0, "onenand_write: Attempt to write not page aligned data\n"); + printk(KERN_ERR "onenand_write_ops_nolock: Attempt to write not page aligned data\n"); return -EINVAL; } - column = to & (mtd->writesize - 1); - subpage = column || (len & (mtd->writesize - 1)); + if (ops->mode == MTD_OOB_AUTO) + oobsize = this->ecclayout->oobavail; + else + oobsize = mtd->oobsize; - /* Grab the lock and see if the device is available */ - onenand_get_device(mtd, FL_WRITING); + oobcolumn = to & (mtd->oobsize - 1); + + column = to & (mtd->writesize - 1); /* Loop until all data write */ while (written < len) { - int bytes = mtd->writesize; - int thislen = min_t(int, bytes, len - written); u_char *wbuf = (u_char *) buf; + thislen = min_t(int, mtd->writesize - column, len - written); + thisooblen = min_t(int, oobsize - oobcolumn, ooblen - oobwritten); + cond_resched(); - this->command(mtd, ONENAND_CMD_BUFFERRAM, to, bytes); + this->command(mtd, ONENAND_CMD_BUFFERRAM, to, thislen); /* Partial page write */ + subpage = thislen < mtd->writesize; if (subpage) { - bytes = min_t(int, bytes - column, (int) len); memset(this->page_buf, 0xff, mtd->writesize); - memcpy(this->page_buf + column, buf, bytes); + memcpy(this->page_buf + column, buf, thislen); wbuf = this->page_buf; - /* Even though partial write, we need page size */ - thislen = mtd->writesize; } - this->write_bufferram(mtd, ONENAND_DATARAM, wbuf, 0, thislen); - this->write_bufferram(mtd, ONENAND_SPARERAM, ffchars, 0, mtd->oobsize); + this->write_bufferram(mtd, ONENAND_DATARAM, wbuf, 0, mtd->writesize); + + if (oob) { + oobbuf = this->oob_buf; + + /* We send data to spare ram with oobsize + * to prevent byte access */ + memset(oobbuf, 0xff, mtd->oobsize); + if (ops->mode == MTD_OOB_AUTO) + onenand_fill_auto_oob(mtd, oobbuf, oob, oobcolumn, thisooblen); + else + memcpy(oobbuf + oobcolumn, oob, thisooblen); + + oobwritten += thisooblen; + oob += thisooblen; + oobcolumn = 0; + } else + oobbuf = (u_char *) ffchars; + + this->write_bufferram(mtd, ONENAND_SPARERAM, oobbuf, 0, mtd->oobsize); this->command(mtd, ONENAND_CMD_PROG, to, mtd->writesize); + ret = this->wait(mtd, FL_WRITING); + /* In partial page write we don't update bufferram */ - onenand_update_bufferram(mtd, to, !subpage); + onenand_update_bufferram(mtd, to, !ret && !subpage); + if (ONENAND_IS_2PLANE(this)) { + ONENAND_SET_BUFFERRAM1(this); + onenand_update_bufferram(mtd, to + this->writesize, !ret && !subpage); + } - ret = this->wait(mtd, FL_WRITING); if (ret) { - DEBUG(MTD_DEBUG_LEVEL0, "onenand_write: write filaed %d\n", ret); + printk(KERN_ERR "onenand_write_ops_nolock: write filaed %d\n", ret); break; } /* Only check verify write turn on */ - ret = onenand_verify_page(mtd, (u_char *) wbuf, to); + ret = onenand_verify(mtd, (u_char *) wbuf, to, thislen); if (ret) { - DEBUG(MTD_DEBUG_LEVEL0, "onenand_write: verify failed %d\n", ret); + printk(KERN_ERR "onenand_write_ops_nolock: verify failed %d\n", ret); break; } written += thislen; @@ -1056,122 +1440,195 @@ static int onenand_write(struct mtd_info } /* Deselect and wake up anyone waiting on the device */ onenand_release_device(mtd); - *retlen = written; + ops->retlen = written; return ret; } + /** - * onenand_do_write_oob - [Internal] OneNAND write out-of-band + * onenand_write_oob_nolock - [Internal] OneNAND write out-of-band * @param mtd MTD device structure * @param to offset to write to * @param len number of bytes to write * @param retlen pointer to variable to store the number of written bytes * @param buf the data to write + * @param mode operation mode * * OneNAND write out-of-band */ -static int onenand_do_write_oob(struct mtd_info *mtd, loff_t to, size_t len, - size_t *retlen, const u_char *buf) +static int onenand_write_oob_nolock(struct mtd_info *mtd, loff_t to, + struct mtd_oob_ops *ops) { struct onenand_chip *this = mtd->priv; - int column, ret = 0; + int column, ret = 0, oobsize; int written = 0; + u_char *oobbuf; + size_t len = ops->ooblen; + const u_char *buf = ops->oobbuf; + mtd_oob_mode_t mode = ops->mode; + + to += ops->ooboffs; - DEBUG(MTD_DEBUG_LEVEL3, "onenand_write_oob: to = 0x%08x, len = %i\n", (unsigned int) to, (int) len); + DEBUG(MTD_DEBUG_LEVEL3, "onenand_write_oob_nolock: to = 0x%08x, len = %i\n", (unsigned int) to, (int) len); /* Initialize retlen, in case of early exit */ - *retlen = 0; + ops->oobretlen = 0; - /* Do not allow writes past end of device */ - if (unlikely((to + len) > mtd->size)) { - DEBUG(MTD_DEBUG_LEVEL0, "onenand_write_oob: Attempt write to past end of device\n"); + if (mode == MTD_OOB_AUTO) + oobsize = this->ecclayout->oobavail; + else + oobsize = mtd->oobsize; + + column = to & (mtd->oobsize - 1); + + if (unlikely(column >= oobsize)) { + printk(KERN_ERR "onenand_write_oob_nolock: Attempted to start write outside oob\n"); return -EINVAL; } - /* Grab the lock and see if the device is available */ - onenand_get_device(mtd, FL_WRITING); + /* For compatibility with NAND: Do not allow write past end of page */ + if (unlikely(column + len > oobsize)) { + printk(KERN_ERR "onenand_write_oob_nolock: " + "Attempt to write past end of page\n"); + return -EINVAL; + } + + /* Do not allow reads past end of device */ + if (unlikely(to >= mtd->size || + column + len > ((mtd->size >> this->page_shift) - + (to >> this->page_shift)) * oobsize)) { + printk(KERN_ERR "onenand_write_oob_nolock: Attempted to write past end of device\n"); + return -EINVAL; + } + + oobbuf = this->oob_buf; /* Loop until all data write */ while (written < len) { - int thislen = min_t(int, mtd->oobsize, len - written); + int thislen = min_t(int, oobsize, len - written); cond_resched(); - column = to & (mtd->oobsize - 1); - this->command(mtd, ONENAND_CMD_BUFFERRAM, to, mtd->oobsize); /* We send data to spare ram with oobsize * to prevent byte access */ - memset(this->page_buf, 0xff, mtd->oobsize); - memcpy(this->page_buf + column, buf, thislen); - this->write_bufferram(mtd, ONENAND_SPARERAM, this->page_buf, 0, mtd->oobsize); + memset(oobbuf, 0xff, mtd->oobsize); + if (mode == MTD_OOB_AUTO) + onenand_fill_auto_oob(mtd, oobbuf, buf, column, thislen); + else + memcpy(oobbuf + column, buf, thislen); + this->write_bufferram(mtd, ONENAND_SPARERAM, oobbuf, 0, mtd->oobsize); this->command(mtd, ONENAND_CMD_PROGOOB, to, mtd->oobsize); onenand_update_bufferram(mtd, to, 0); + if (ONENAND_IS_2PLANE(this)) { + ONENAND_SET_BUFFERRAM1(this); + onenand_update_bufferram(mtd, to + this->writesize, 0); + } ret = this->wait(mtd, FL_WRITING); if (ret) { - DEBUG(MTD_DEBUG_LEVEL0, "onenand_write_oob: write filaed %d\n", ret); - goto out; + printk(KERN_ERR "onenand_write_oob_nolock: write failed %d\n", ret); + break; } - ret = onenand_verify_oob(mtd, buf, to, thislen); + ret = onenand_verify_oob(mtd, oobbuf, to); if (ret) { - DEBUG(MTD_DEBUG_LEVEL0, "onenand_write_oob: verify failed %d\n", ret); - goto out; + printk(KERN_ERR "onenand_write_oob_nolock: verify failed %d\n", ret); + break; } written += thislen; - if (written == len) break; - to += thislen; + to += mtd->writesize; buf += thislen; + column = 0; } -out: - /* Deselect and wake up anyone waiting on the device */ - onenand_release_device(mtd); + ops->oobretlen = written; + + return ret; +} - *retlen = written; +/** + * onenand_write - [MTD Interface] write buffer to FLASH + * @param mtd MTD device structure + * @param to offset to write to + * @param len number of bytes to write + * @param retlen pointer to variable to store the number of written bytes + * @param buf the data to write + * + * Write with ECC + */ +static int onenand_write(struct mtd_info *mtd, loff_t to, size_t len, + size_t *retlen, const u_char *buf) +{ + struct mtd_oob_ops ops = { + .len = len, + .ooblen = 0, + .datbuf = (u_char *) buf, + .oobbuf = NULL, + }; + int ret; + onenand_get_device(mtd, FL_WRITING); + ret = onenand_write_ops_nolock(mtd, to, &ops); + onenand_release_device(mtd); + + *retlen = ops.retlen; return ret; } /** * onenand_write_oob - [MTD Interface] NAND write data and/or out-of-band - * @mtd: MTD device structure - * @from: offset to read from - * @ops: oob operation description structure + * @param mtd: MTD device structure + * @param to: offset to write + * @param ops: oob operation description structure */ static int onenand_write_oob(struct mtd_info *mtd, loff_t to, struct mtd_oob_ops *ops) { - BUG_ON(ops->mode != MTD_OOB_PLACE); + int ret; + + switch (ops->mode) { + case MTD_OOB_PLACE: + case MTD_OOB_AUTO: + break; + case MTD_OOB_RAW: + /* Not implemented yet */ + default: + return -EINVAL; + } + + onenand_get_device(mtd, FL_WRITING); + if (ops->datbuf) + ret = onenand_write_ops_nolock(mtd, to, ops); + else + ret = onenand_write_oob_nolock(mtd, to, ops); + onenand_release_device(mtd); - return onenand_do_write_oob(mtd, to + ops->ooboffs, ops->ooblen, - &ops->oobretlen, ops->oobbuf); + return ret; } /** - * onenand_block_checkbad - [GENERIC] Check if a block is marked bad + * onenand_block_isbad_nolock - [GENERIC] Check if a block is marked bad * @param mtd MTD device structure * @param ofs offset from device start - * @param getchip 0, if the chip is already selected * @param allowbbt 1, if its allowed to access the bbt area * * Check, if the block is bad. Either by reading the bad block table or * calling of the scan function. */ -static int onenand_block_checkbad(struct mtd_info *mtd, loff_t ofs, int getchip, int allowbbt) +static int onenand_block_isbad_nolock(struct mtd_info *mtd, loff_t ofs, int allowbbt) { struct onenand_chip *this = mtd->priv; struct bbm_info *bbm = this->bbm; /* Return info from the table */ @@ -1197,23 +1654,23 @@ static int onenand_erase(struct mtd_info block_size = (1 << this->erase_shift); /* Start address must align on block boundary */ if (unlikely(instr->addr & (block_size - 1))) { - DEBUG(MTD_DEBUG_LEVEL0, "onenand_erase: Unaligned address\n"); + printk(KERN_ERR "onenand_erase: Unaligned address\n"); return -EINVAL; } /* Length must align on block boundary */ if (unlikely(instr->len & (block_size - 1))) { - DEBUG(MTD_DEBUG_LEVEL0, "onenand_erase: Length not block aligned\n"); + printk(KERN_ERR "onenand_erase: Length not block aligned\n"); return -EINVAL; } /* Do not allow erase past end of device */ if (unlikely((instr->len + instr->addr) > mtd->size)) { - DEBUG(MTD_DEBUG_LEVEL0, "onenand_erase: Erase past end of device\n"); + printk(KERN_ERR "onenand_erase: Erase past end of device\n"); return -EINVAL; } instr->fail_addr = 0xffffffff; @@ -1228,22 +1685,24 @@ static int onenand_erase(struct mtd_info while (len) { cond_resched(); /* Check if we have a bad block, we do not erase bad blocks */ - if (onenand_block_checkbad(mtd, addr, 0, 0)) { + if (onenand_block_isbad_nolock(mtd, addr, 0)) { printk (KERN_WARNING "onenand_erase: attempt to erase a bad block at addr 0x%08x\n", (unsigned int) addr); instr->state = MTD_ERASE_FAILED; goto erase_exit; } this->command(mtd, ONENAND_CMD_ERASE, addr, block_size); + onenand_invalidate_bufferram(mtd, addr, block_size); + ret = this->wait(mtd, FL_ERASING); /* Check, if it is write protected */ if (ret) { - DEBUG(MTD_DEBUG_LEVEL0, "onenand_erase: Failed erase, block %d\n", (unsigned) (addr >> this->erase_shift)); + printk(KERN_ERR "onenand_erase: Failed erase, block %d\n", (unsigned) (addr >> this->erase_shift)); instr->state = MTD_ERASE_FAILED; instr->fail_addr = addr; goto erase_exit; } @@ -1254,17 +1713,18 @@ static int onenand_erase(struct mtd_info instr->state = MTD_ERASE_DONE; erase_exit: ret = instr->state == MTD_ERASE_DONE ? 0 : -EIO; - /* Do call back function */ - if (!ret) - mtd_erase_callback(instr); /* Deselect and wake up anyone waiting on the device */ onenand_release_device(mtd); + /* Do call back function */ + if (!ret) + mtd_erase_callback(instr); + return ret; } /** * onenand_sync - [MTD Interface] sync @@ -1290,15 +1750,20 @@ static void onenand_sync(struct mtd_info * * Check whether the block is bad */ static int onenand_block_isbad(struct mtd_info *mtd, loff_t ofs) { + int ret; + /* Check for invalid offset */ if (ofs > mtd->size) return -EINVAL; - return onenand_block_checkbad(mtd, ofs, 1, 0); + onenand_get_device(mtd, FL_READING); + ret = onenand_block_isbad_nolock(mtd, ofs, 0); + onenand_release_device(mtd); + return ret; } /** * onenand_default_block_markbad - [DEFAULT] mark a block bad * @param mtd MTD device structure @@ -1310,21 +1775,26 @@ static int onenand_block_isbad(struct mt static int onenand_default_block_markbad(struct mtd_info *mtd, loff_t ofs) { struct onenand_chip *this = mtd->priv; struct bbm_info *bbm = this->bbm; u_char buf[2] = {0, 0}; - size_t retlen; + struct mtd_oob_ops ops = { + .mode = MTD_OOB_PLACE, + .ooblen = 2, + .oobbuf = buf, + .ooboffs = 0, + }; int block; /* Get block number */ block = ((int) ofs) >> bbm->bbt_erase_shift; if (bbm->bbt) bbm->bbt[block >> 2] |= 0x01 << ((block & 0x03) << 1); /* We write two bytes, so we dont have to mess with 16 bit access */ ofs += mtd->oobsize + (bbm->badblockpos & ~0x01); - return onenand_do_write_oob(mtd, ofs , 2, &retlen, buf); + return onenand_write_oob_nolock(mtd, ofs, &ops); } /** * onenand_block_markbad - [MTD Interface] Mark the block at the given offset as bad * @param mtd MTD device structure @@ -1343,18 +1813,22 @@ static int onenand_block_markbad(struct if (ret > 0) return 0; return ret; } - return this->block_markbad(mtd, ofs); + onenand_get_device(mtd, FL_WRITING); + ret = this->block_markbad(mtd, ofs); + onenand_release_device(mtd); + return ret; } /** * onenand_do_lock_cmd - [OneNAND Interface] Lock or unlock block(s) * @param mtd MTD device structure * @param ofs offset relative to mtd start * @param len number of bytes to lock or unlock + * @param cmd lock or unlock command * * Lock or unlock one or more blocks */ static int onenand_do_lock_cmd(struct mtd_info *mtd, loff_t ofs, size_t len, int cmd) { @@ -1433,11 +1907,16 @@ static int onenand_do_lock_cmd(struct mt * * Lock one or more blocks */ static int onenand_lock(struct mtd_info *mtd, loff_t ofs, size_t len) { - return onenand_do_lock_cmd(mtd, ofs, len, ONENAND_CMD_LOCK); + int ret; + + onenand_get_device(mtd, FL_LOCKING); + ret = onenand_do_lock_cmd(mtd, ofs, len, ONENAND_CMD_LOCK); + onenand_release_device(mtd); + return ret; } /** * onenand_unlock - [MTD Interface] Unlock block(s) * @param mtd MTD device structure @@ -1446,11 +1925,16 @@ static int onenand_lock(struct mtd_info * * Unlock one or more blocks */ static int onenand_unlock(struct mtd_info *mtd, loff_t ofs, size_t len) { - return onenand_do_lock_cmd(mtd, ofs, len, ONENAND_CMD_UNLOCK); + int ret; + + onenand_get_device(mtd, FL_LOCKING); + ret = onenand_do_lock_cmd(mtd, ofs, len, ONENAND_CMD_UNLOCK); + onenand_release_device(mtd); + return ret; } /** * onenand_check_lock_status - [OneNAND Interface] Check lock status * @param this onenand chip data structure @@ -1489,10 +1973,12 @@ static void onenand_check_lock_status(st static int onenand_unlock_all(struct mtd_info *mtd) { struct onenand_chip *this = mtd->priv; if (this->options & ONENAND_HAS_UNLOCK_ALL) { + /* Set start block address */ + this->write_word(0, this->base + ONENAND_REG_START_BLOCK_ADDRESS); /* Write unlock command */ this->command(mtd, ONENAND_CMD_UNLOCK_ALL, 0, 0); /* There's no return value */ this->wait(mtd, FL_LOCKING); @@ -1501,27 +1987,24 @@ static int onenand_unlock_all(struct mtd while (this->read_word(this->base + ONENAND_REG_CTRL_STATUS) & ONENAND_CTRL_ONGO) continue; /* Workaround for all block unlock in DDP */ - if (this->device_id & ONENAND_DEVICE_IS_DDP) { - loff_t ofs; - size_t len; - + if (ONENAND_IS_DDP(this)) { /* 1st block on another chip */ - ofs = this->chipsize >> 1; - len = 1 << this->erase_shift; + loff_t ofs = this->chipsize >> 1; + size_t len = mtd->erasesize; - onenand_unlock(mtd, ofs, len); + onenand_do_lock_cmd(mtd, ofs, len, ONENAND_CMD_UNLOCK); } onenand_check_lock_status(this); return 0; } - onenand_unlock(mtd, 0x0, this->chipsize); + onenand_do_lock_cmd(mtd, 0x0, this->chipsize, ONENAND_CMD_UNLOCK); return 0; } #ifdef CONFIG_MTD_ONENAND_OTP @@ -1542,17 +2025,23 @@ typedef int (*otp_op_t)(struct mtd_info */ static int do_otp_read(struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf) { struct onenand_chip *this = mtd->priv; + struct mtd_oob_ops ops = { + .len = len, + .ooblen = 0, + .datbuf = buf, + .oobbuf = NULL, + }; int ret; /* Enter OTP access mode */ this->command(mtd, ONENAND_CMD_OTP_ACCESS, 0, 0); this->wait(mtd, FL_OTPING); - ret = mtd->read(mtd, from, len, retlen, buf); + ret = onenand_read_ops_nolock(mtd, from, &ops); /* Exit OTP access mode */ this->command(mtd, ONENAND_CMD_RESET, 0, 0); this->wait(mtd, FL_RESETING); @@ -1560,23 +2049,24 @@ static int do_otp_read(struct mtd_info * } /** * do_otp_write - [DEFAULT] Write OTP block area * @param mtd MTD device structure - * @param from The offset to write + * @param to The offset to write * @param len number of bytes to write * @param retlen pointer to variable to store the number of write bytes * @param buf the databuffer to put/get data * * Write OTP block area. */ -static int do_otp_write(struct mtd_info *mtd, loff_t from, size_t len, +static int do_otp_write(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, u_char *buf) { struct onenand_chip *this = mtd->priv; unsigned char *pbuf = buf; int ret; + struct mtd_oob_ops ops; /* Force buffer page aligned */ if (len < mtd->writesize) { memcpy(this->page_buf, buf, len); memset(this->page_buf + len, 0xff, mtd->writesize - len); @@ -1586,11 +2076,16 @@ static int do_otp_write(struct mtd_info /* Enter OTP access mode */ this->command(mtd, ONENAND_CMD_OTP_ACCESS, 0, 0); this->wait(mtd, FL_OTPING); - ret = mtd->write(mtd, from, len, retlen, pbuf); + ops.len = len; + ops.ooblen = 0; + ops.datbuf = pbuf; + ops.oobbuf = NULL; + ret = onenand_write_ops_nolock(mtd, to, &ops); + *retlen = ops.retlen; /* Exit OTP access mode */ this->command(mtd, ONENAND_CMD_RESET, 0, 0); this->wait(mtd, FL_RESETING); @@ -1609,17 +2104,25 @@ static int do_otp_write(struct mtd_info */ static int do_otp_lock(struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf) { struct onenand_chip *this = mtd->priv; + struct mtd_oob_ops ops = { + .mode = MTD_OOB_PLACE, + .ooblen = len, + .oobbuf = buf, + .ooboffs = 0, + }; int ret; /* Enter OTP access mode */ this->command(mtd, ONENAND_CMD_OTP_ACCESS, 0, 0); this->wait(mtd, FL_OTPING); - ret = onenand_do_write_oob(mtd, from, len, retlen, buf); + ret = onenand_write_oob_nolock(mtd, from, &ops); + + *retlen = ops.oobretlen; /* Exit OTP access mode */ this->command(mtd, ONENAND_CMD_RESET, 0, 0); this->wait(mtd, FL_RESETING); @@ -1662,17 +2165,20 @@ static int onenand_otp_walk(struct mtd_i /* Check User/Factory boundary */ if (((mtd->writesize * otp_pages) - (from + len)) < 0) return 0; + onenand_get_device(mtd, FL_OTPING); while (len > 0 && otp_pages > 0) { if (!action) { /* OTP Info functions */ struct otp_info *otpinfo; len -= sizeof(struct otp_info); - if (len <= 0) - return -ENOSPC; + if (len <= 0) { + ret = -ENOSPC; + break; + } otpinfo = (struct otp_info *) buf; otpinfo->start = from; otpinfo->length = mtd->writesize; otpinfo->locked = 0; @@ -1688,17 +2194,18 @@ static int onenand_otp_walk(struct mtd_i buf += size; len -= size; *retlen += size; - if (ret < 0) - return ret; + if (ret) + break; } otp_pages--; } + onenand_release_device(mtd); - return 0; + return ret; } /** * onenand_get_fact_prot_info - [MTD Interface] Read factory OTP info * @param mtd MTD device structure @@ -1821,61 +2328,79 @@ static int onenand_lock_user_prot_reg(st return ret ? : retlen; } #endif /* CONFIG_MTD_ONENAND_OTP */ /** - * onenand_lock_scheme - Check and set OneNAND lock scheme + * onenand_check_features - Check and set OneNAND features * @param mtd MTD data structure * - * Check and set OneNAND lock scheme + * Check and set OneNAND features + * - lock scheme + * - two plane */ -static void onenand_lock_scheme(struct mtd_info *mtd) +static void onenand_check_features(struct mtd_info *mtd) { struct onenand_chip *this = mtd->priv; unsigned int density, process; /* Lock scheme depends on density and process */ density = this->device_id >> ONENAND_DEVICE_DENSITY_SHIFT; process = this->version_id >> ONENAND_VERSION_PROCESS_SHIFT; /* Lock scheme */ - if (density >= ONENAND_DEVICE_DENSITY_1Gb) { + switch (density) { + case ONENAND_DEVICE_DENSITY_4Gb: + this->options |= ONENAND_HAS_2PLANE; + + case ONENAND_DEVICE_DENSITY_2Gb: + /* 2Gb DDP don't have 2 plane */ + if (!ONENAND_IS_DDP(this)) + this->options |= ONENAND_HAS_2PLANE; + this->options |= ONENAND_HAS_UNLOCK_ALL; + + case ONENAND_DEVICE_DENSITY_1Gb: /* A-Die has all block unlock */ - if (process) { - printk(KERN_DEBUG "Chip support all block unlock\n"); + if (process) this->options |= ONENAND_HAS_UNLOCK_ALL; - } - } else { - /* Some OneNAND has continues lock scheme */ - if (!process) { - printk(KERN_DEBUG "Lock scheme is Continues Lock\n"); + break; + + default: + /* Some OneNAND has continuous lock scheme */ + if (!process) this->options |= ONENAND_HAS_CONT_LOCK; + break; } - } + + if (this->options & ONENAND_HAS_CONT_LOCK) + printk(KERN_DEBUG "Lock scheme is Continuous Lock\n"); + if (this->options & ONENAND_HAS_UNLOCK_ALL) + printk(KERN_DEBUG "Chip support all block unlock\n"); + if (this->options & ONENAND_HAS_2PLANE) + printk(KERN_DEBUG "Chip has 2 plane\n"); } /** - * onenand_print_device_info - Print device ID + * onenand_print_device_info - Print device & version ID * @param device device ID + * @param version version ID * - * Print device ID + * Print device & version ID */ static void onenand_print_device_info(int device, int version) { int vcc, demuxed, ddp, density; - vcc = device & ONENAND_DEVICE_VCC_MASK; demuxed = device & ONENAND_DEVICE_IS_DEMUX; ddp = device & ONENAND_DEVICE_IS_DDP; density = device >> ONENAND_DEVICE_DENSITY_SHIFT; printk(KERN_INFO "%sOneNAND%s %dMB %sV 16-bit (0x%02x)\n", demuxed ? "" : "Muxed ", ddp ? "(DDP)" : "", (16 << density), vcc ? "2.65/3.3" : "1.8", device); - printk(KERN_DEBUG "OneNAND version = 0x%04x\n", version); + printk(KERN_INFO "OneNAND version = 0x%04x\n", version); } static const struct onenand_manufacturers onenand_manuf_ids[] = { {ONENAND_MFR_SAMSUNG, "Samsung"}, }; @@ -1909,16 +2434,16 @@ static int onenand_check_maf(int manuf) /** * onenand_probe - [OneNAND Interface] Probe the OneNAND device * @param mtd MTD device structure * * OneNAND detection method: - * Compare the the values from command with ones from register + * Compare the values from command with ones from register */ static int onenand_probe(struct mtd_info *mtd) { struct onenand_chip *this = mtd->priv; - int bram_maf_id, bram_dev_id, maf_id, dev_id, ver_id; + int bram_maf_id, bram_dev_id, maf_id, dev_id, ver_id,tech_id; int density; int syscfg; /* Save system configuration 1 */ syscfg = this->read_word(this->base + ONENAND_REG_SYS_CFG1); @@ -1946,10 +2471,11 @@ static int onenand_probe(struct mtd_info /* Read manufacturer and device IDs from Register */ maf_id = this->read_word(this->base + ONENAND_REG_MANUFACTURER_ID); dev_id = this->read_word(this->base + ONENAND_REG_DEVICE_ID); ver_id = this->read_word(this->base + ONENAND_REG_VERSION_ID); + tech_id=this->read_word(this->base + ONENAND_REG_TECHNOLOGY); /* Check OneNAND device */ if (maf_id != bram_maf_id || dev_id != bram_dev_id) return -ENXIO; @@ -1959,30 +2485,45 @@ static int onenand_probe(struct mtd_info this->version_id = ver_id; density = dev_id >> ONENAND_DEVICE_DENSITY_SHIFT; this->chipsize = (16 << density) << 20; /* Set density mask. it is used for DDP */ + if (ONENAND_IS_DDP(this)) this->density_mask = (1 << (density + 6)); + else + this->density_mask = 0; /* OneNAND page size & block size */ /* The data buffer size is equal to page size */ mtd->writesize = this->read_word(this->base + ONENAND_REG_DATA_BUFFER_SIZE); mtd->oobsize = mtd->writesize >> 5; - /* Pagers per block is always 64 in OneNAND */ + /* Pages per a block are always 64 in OneNAND */ mtd->erasesize = mtd->writesize << 6; this->erase_shift = ffs(mtd->erasesize) - 1; this->page_shift = ffs(mtd->writesize) - 1; - this->ppb_shift = (this->erase_shift - this->page_shift); - this->page_mask = (mtd->erasesize / mtd->writesize) - 1; + this->page_mask = (1 << (this->erase_shift - this->page_shift)) - 1; + /* It's real page size */ + this->writesize = mtd->writesize; /* REVIST: Multichip handling */ mtd->size = this->chipsize; - /* Check OneNAND lock scheme */ - onenand_lock_scheme(mtd); + /* Check OneNAND features */ + onenand_check_features(mtd); + + /* + * We emulate the 4KiB page and 256KiB erase block size + * But oobsize is still 64 bytes. + * It is only valid if you turn on 2X program support, + * Otherwise it will be ignored by compiler. + */ + if (ONENAND_IS_2PLANE(this)) { + mtd->writesize <<= 1; + mtd->erasesize <<= 1; + } return 0; } /** @@ -2019,10 +2560,11 @@ static void onenand_resume(struct mtd_in * The flash ID is read and the mtd/chip structures are * filled with the appropriate values. */ int onenand_scan(struct mtd_info *mtd, int maxchips) { + int i; struct onenand_chip *this = mtd->priv; if (!this->read_word) this->read_word = onenand_readw; if (!this->write_word) @@ -2042,29 +2584,41 @@ int onenand_scan(struct mtd_info *mtd, i this->block_markbad = onenand_default_block_markbad; if (!this->scan_bbt) this->scan_bbt = onenand_default_bbt; if (onenand_probe(mtd)) + { printk("Error at probe \n"); return -ENXIO; + } /* Set Sync. Burst Read after probing */ if (this->mmcontrol) { printk(KERN_INFO "OneNAND Sync. Burst Read support\n"); this->read_bufferram = onenand_sync_read_bufferram; } /* Allocate buffers, if necessary */ if (!this->page_buf) { - size_t len; - len = mtd->writesize + mtd->oobsize; - this->page_buf = kmalloc(len, GFP_KERNEL); + this->page_buf = kzalloc(mtd->writesize, GFP_KERNEL); if (!this->page_buf) { printk(KERN_ERR "onenand_scan(): Can't allocate page_buf\n"); return -ENOMEM; } this->options |= ONENAND_PAGEBUF_ALLOC; } + if (!this->oob_buf) { + this->oob_buf = kzalloc(mtd->oobsize, GFP_KERNEL); + if (!this->oob_buf) { + printk(KERN_ERR "onenand_scan(): Can't allocate oob_buf\n"); + if (this->options & ONENAND_PAGEBUF_ALLOC) { + this->options &= ~ONENAND_PAGEBUF_ALLOC; + kfree(this->page_buf); + } + return -ENOMEM; + } + this->options |= ONENAND_OOBBUF_ALLOC; + } this->state = FL_READY; init_waitqueue_head(&this->wq); spin_lock_init(&this->chip_lock); @@ -2090,16 +2644,27 @@ int onenand_scan(struct mtd_info *mtd, i this->ecclayout = &onenand_oob_32; break; } this->subpagesize = mtd->writesize >> mtd->subpage_sft; + + /* + * The number of bytes available for a client to place data into + * the out of band area + */ + this->ecclayout->oobavail = 0; + for (i = 0; i < MTD_MAX_OOBFREE_ENTRIES && + this->ecclayout->oobfree[i].length; i++) + this->ecclayout->oobavail += + this->ecclayout->oobfree[i].length; + mtd->oobavail = this->ecclayout->oobavail; + mtd->ecclayout = this->ecclayout; /* Fill in remaining MTD driver data */ mtd->type = MTD_NANDFLASH; mtd->flags = MTD_CAP_NANDFLASH; - mtd->ecctype = MTD_ECC_SW; mtd->erase = onenand_erase; mtd->point = NULL; mtd->unpoint = NULL; mtd->read = onenand_read; mtd->write = onenand_write; @@ -2142,18 +2707,24 @@ void onenand_release(struct mtd_info *mt #endif /* Deregister the device */ del_mtd_device (mtd); /* Free bad block table memory, if allocated */ - if (this->bbm) + if (this->bbm) { + struct bbm_info *bbm = this->bbm; + kfree(bbm->bbt); kfree(this->bbm); - /* Buffer allocated by onenand_scan */ + } + /* Buffers allocated by onenand_scan */ if (this->options & ONENAND_PAGEBUF_ALLOC) kfree(this->page_buf); + if (this->options & ONENAND_OOBBUF_ALLOC) + kfree(this->oob_buf); } EXPORT_SYMBOL_GPL(onenand_scan); EXPORT_SYMBOL_GPL(onenand_release); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Kyungmin Park "); MODULE_DESCRIPTION("Generic OneNAND flash driver code"); + --- linux-2.6.20.orig/drivers/mtd/onenand/onenand_bbt.c +++ linux-2.6.20/drivers/mtd/onenand/onenand_bbt.c @@ -8,19 +8,24 @@ * * Derived from nand_bbt.c * * TODO: * Split BBT core and chip specific BBT. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * */ #include #include #include #include -extern int onenand_do_read_oob(struct mtd_info *mtd, loff_t from, size_t len, - size_t *retlen, u_char *buf); +extern int onenand_bbt_read_oob(struct mtd_info *mtd, loff_t from, + struct mtd_oob_ops *ops); /** * check_short_pattern - [GENERIC] check if a pattern is in the buffer * @param buf the buffer to search * @param len the length of buffer to search @@ -63,14 +68,15 @@ static int create_bbt(struct mtd_info *m struct bbm_info *bbm = this->bbm; int i, j, numblocks, len, scanlen; int startblock; loff_t from; size_t readlen, ooblen; + struct mtd_oob_ops ops; printk(KERN_INFO "Scanning device for bad blocks\n"); - len = 1; + len = 2; /* We need only read few bytes from the OOB area */ scanlen = ooblen = 0; readlen = bd->len; @@ -80,26 +86,28 @@ static int create_bbt(struct mtd_info *m */ numblocks = mtd->size >> (bbm->bbt_erase_shift - 1); startblock = 0; from = 0; + ops.mode = MTD_OOB_PLACE; + ops.ooblen = readlen; + ops.oobbuf = buf; + ops.len = ops.ooboffs = ops.retlen = ops.oobretlen = 0; + for (i = startblock; i < numblocks; ) { int ret; for (j = 0; j < len; j++) { - size_t retlen; - /* No need to read pages fully, * just read required OOB bytes */ - ret = onenand_do_read_oob(mtd, from + j * mtd->writesize + bd->offs, - readlen, &retlen, &buf[0]); + ret = onenand_bbt_read_oob(mtd, from + j * mtd->writesize + bd->offs, &ops); /* If it is a initial bad block, just ignore it */ - if (ret && !(ret & ONENAND_CTRL_LOAD)) - return ret; + if (ret == ONENAND_BBT_READ_FATAL_ERROR) + return -EIO; - if (check_short_pattern(&buf[j * scanlen], scanlen, mtd->writesize, bd)) { + if (ret || check_short_pattern(&buf[j * scanlen], scanlen, mtd->writesize, bd)) { bbm->bbt[i >> 3] |= 0x03 << (i & 0x6); printk(KERN_WARNING "Bad eraseblock %d at 0x%08x\n", i >> 1, (unsigned int) from); mtd->ecc_stats.badblocks++; break; @@ -165,13 +173,12 @@ static int onenand_isbad_bbt(struct mtd_ * * The function checks, if a bad block table(s) is/are already * available. If not it scans the device for manufacturer * marked good / bad blocks and writes the bad block table(s) to * the selected place. - * - * The bad block table memory is allocated here. It must be freed - * by calling the onenand_free_bbt function. + * The bad block table memory is allocated here. It is freed + * by the onenand_release function. * */ int onenand_scan_bbt(struct mtd_info *mtd, struct nand_bbt_descr *bd) { struct onenand_chip *this = mtd->priv; --- /dev/null +++ linux-2.6.20/drivers/mtd/onenand/onenand_sim.c @@ -0,0 +1,495 @@ +/* + * linux/drivers/mtd/onenand/onenand_sim.c + * + * The OneNAND simulator + * + * Copyright © 2005-2007 Samsung Electronics + * Kyungmin Park + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include + +#ifndef CONFIG_ONENAND_SIM_MANUFACTURER +#define CONFIG_ONENAND_SIM_MANUFACTURER 0xec +#endif +#ifndef CONFIG_ONENAND_SIM_DEVICE_ID +#define CONFIG_ONENAND_SIM_DEVICE_ID 0x04 +#endif +#ifndef CONFIG_ONENAND_SIM_VERSION_ID +#define CONFIG_ONENAND_SIM_VERSION_ID 0x1e +#endif + +static int manuf_id = CONFIG_ONENAND_SIM_MANUFACTURER; +static int device_id = CONFIG_ONENAND_SIM_DEVICE_ID; +static int version_id = CONFIG_ONENAND_SIM_VERSION_ID; + +struct onenand_flash { + void __iomem *base; + void __iomem *data; +}; + +#define ONENAND_CORE(flash) (flash->data) +#define ONENAND_CORE_SPARE(flash, this, offset) \ + ((flash->data) + (this->chipsize) + (offset >> 5)) + +#define ONENAND_MAIN_AREA(this, offset) \ + (this->base + ONENAND_DATARAM + offset) + +#define ONENAND_SPARE_AREA(this, offset) \ + (this->base + ONENAND_SPARERAM + offset) + +#define ONENAND_GET_WP_STATUS(this) \ + (readw(this->base + ONENAND_REG_WP_STATUS)) + +#define ONENAND_SET_WP_STATUS(v, this) \ + (writew(v, this->base + ONENAND_REG_WP_STATUS)) + +/* It has all 0xff chars */ +#define MAX_ONENAND_PAGESIZE (2048 + 64) +static unsigned char *ffchars; + +static struct mtd_partition os_partitions[] = { + { + .name = "OneNAND simulator partition", + .offset = 0, + .size = MTDPART_SIZ_FULL, + }, +}; + +/* + * OneNAND simulator mtd + */ +struct onenand_info { + struct mtd_info mtd; + struct mtd_partition *parts; + struct onenand_chip onenand; + struct onenand_flash flash; +}; + +static struct onenand_info *info; + +#define DPRINTK(format, args...) \ +do { \ + printk(KERN_DEBUG "%s[%d]: " format "\n", __func__, \ + __LINE__, ##args); \ +} while (0) + +/** + * onenand_lock_handle - Handle Lock scheme + * @this: OneNAND device structure + * @cmd: The command to be sent + * + * Send lock command to OneNAND device. + * The lock scheme depends on chip type. + */ +static void onenand_lock_handle(struct onenand_chip *this, int cmd) +{ + int block_lock_scheme; + int status; + + status = ONENAND_GET_WP_STATUS(this); + block_lock_scheme = !(this->options & ONENAND_HAS_CONT_LOCK); + + switch (cmd) { + case ONENAND_CMD_UNLOCK: + if (block_lock_scheme) + ONENAND_SET_WP_STATUS(ONENAND_WP_US, this); + else + ONENAND_SET_WP_STATUS(status | ONENAND_WP_US, this); + break; + + case ONENAND_CMD_LOCK: + if (block_lock_scheme) + ONENAND_SET_WP_STATUS(ONENAND_WP_LS, this); + else + ONENAND_SET_WP_STATUS(status | ONENAND_WP_LS, this); + break; + + case ONENAND_CMD_LOCK_TIGHT: + if (block_lock_scheme) + ONENAND_SET_WP_STATUS(ONENAND_WP_LTS, this); + else + ONENAND_SET_WP_STATUS(status | ONENAND_WP_LTS, this); + break; + + default: + break; + } +} + +/** + * onenand_bootram_handle - Handle BootRAM area + * @this: OneNAND device structure + * @cmd: The command to be sent + * + * Emulate BootRAM area. It is possible to do basic operation using BootRAM. + */ +static void onenand_bootram_handle(struct onenand_chip *this, int cmd) +{ + switch (cmd) { + case ONENAND_CMD_READID: + writew(manuf_id, this->base); + writew(device_id, this->base + 2); + writew(version_id, this->base + 4); + break; + + default: + /* REVIST: Handle other commands */ + break; + } +} + +/** + * onenand_update_interrupt - Set interrupt register + * @this: OneNAND device structure + * @cmd: The command to be sent + * + * Update interrupt register. The status depends on command. + */ +static void onenand_update_interrupt(struct onenand_chip *this, int cmd) +{ + int interrupt = ONENAND_INT_MASTER; + + switch (cmd) { + case ONENAND_CMD_READ: + case ONENAND_CMD_READOOB: + interrupt |= ONENAND_INT_READ; + break; + + case ONENAND_CMD_PROG: + case ONENAND_CMD_PROGOOB: + interrupt |= ONENAND_INT_WRITE; + break; + + case ONENAND_CMD_ERASE: + interrupt |= ONENAND_INT_ERASE; + break; + + case ONENAND_CMD_RESET: + interrupt |= ONENAND_INT_RESET; + break; + + default: + break; + } + + writew(interrupt, this->base + ONENAND_REG_INTERRUPT); +} + +/** + * onenand_check_overwrite - Check if over-write happened + * @dest: The destination pointer + * @src: The source pointer + * @count: The length to be check + * + * Returns: 0 on same, otherwise 1 + * + * Compare the source with destination + */ +static int onenand_check_overwrite(void *dest, void *src, size_t count) +{ + unsigned int *s = (unsigned int *) src; + unsigned int *d = (unsigned int *) dest; + int i; + + count >>= 2; + for (i = 0; i < count; i++) + if ((*s++ ^ *d++) != 0) + return 1; + + return 0; +} + +/** + * onenand_data_handle - Handle OneNAND Core and DataRAM + * @this: OneNAND device structure + * @cmd: The command to be sent + * @dataram: Which dataram used + * @offset: The offset to OneNAND Core + * + * Copy data from OneNAND Core to DataRAM (read) + * Copy data from DataRAM to OneNAND Core (write) + * Erase the OneNAND Core (erase) + */ +static void onenand_data_handle(struct onenand_chip *this, int cmd, + int dataram, unsigned int offset) +{ + struct mtd_info *mtd = &info->mtd; + struct onenand_flash *flash = this->priv; + int main_offset, spare_offset; + void __iomem *src; + void __iomem *dest; + unsigned int i; + + if (dataram) { + main_offset = mtd->writesize; + spare_offset = mtd->oobsize; + } else { + main_offset = 0; + spare_offset = 0; + } + + switch (cmd) { + case ONENAND_CMD_READ: + src = ONENAND_CORE(flash) + offset; + dest = ONENAND_MAIN_AREA(this, main_offset); + memcpy(dest, src, mtd->writesize); + /* Fall through */ + + case ONENAND_CMD_READOOB: + src = ONENAND_CORE_SPARE(flash, this, offset); + dest = ONENAND_SPARE_AREA(this, spare_offset); + memcpy(dest, src, mtd->oobsize); + break; + + case ONENAND_CMD_PROG: + src = ONENAND_MAIN_AREA(this, main_offset); + dest = ONENAND_CORE(flash) + offset; + /* To handle partial write */ + for (i = 0; i < (1 << mtd->subpage_sft); i++) { + int off = i * this->subpagesize; + if (!memcmp(src + off, ffchars, this->subpagesize)) + continue; + if (memcmp(dest + off, ffchars, this->subpagesize) && + onenand_check_overwrite(dest + off, src + off, this->subpagesize)) + printk(KERN_ERR "over-write happend at 0x%08x\n", offset); + memcpy(dest + off, src + off, this->subpagesize); + } + /* Fall through */ + + case ONENAND_CMD_PROGOOB: + src = ONENAND_SPARE_AREA(this, spare_offset); + /* Check all data is 0xff chars */ + if (!memcmp(src, ffchars, mtd->oobsize)) + break; + + dest = ONENAND_CORE_SPARE(flash, this, offset); + if (memcmp(dest, ffchars, mtd->oobsize) && + onenand_check_overwrite(dest, src, mtd->oobsize)) + printk(KERN_ERR "OOB: over-write happend at 0x%08x\n", + offset); + memcpy(dest, src, mtd->oobsize); + break; + + case ONENAND_CMD_ERASE: + memset(ONENAND_CORE(flash) + offset, 0xff, mtd->erasesize); + memset(ONENAND_CORE_SPARE(flash, this, offset), 0xff, + (mtd->erasesize >> 5)); + break; + + default: + break; + } +} + +/** + * onenand_command_handle - Handle command + * @this: OneNAND device structure + * @cmd: The command to be sent + * + * Emulate OneNAND command. + */ +static void onenand_command_handle(struct onenand_chip *this, int cmd) +{ + unsigned long offset = 0; + int block = -1, page = -1, bufferram = -1; + int dataram = 0; + + switch (cmd) { + case ONENAND_CMD_UNLOCK: + case ONENAND_CMD_LOCK: + case ONENAND_CMD_LOCK_TIGHT: + case ONENAND_CMD_UNLOCK_ALL: + onenand_lock_handle(this, cmd); + break; + + case ONENAND_CMD_BUFFERRAM: + /* Do nothing */ + return; + + default: + block = (int) readw(this->base + ONENAND_REG_START_ADDRESS1); + if (block & (1 << ONENAND_DDP_SHIFT)) { + block &= ~(1 << ONENAND_DDP_SHIFT); + /* The half of chip block */ + block += this->chipsize >> (this->erase_shift + 1); + } + if (cmd == ONENAND_CMD_ERASE) + break; + + page = (int) readw(this->base + ONENAND_REG_START_ADDRESS8); + page = (page >> ONENAND_FPA_SHIFT); + bufferram = (int) readw(this->base + ONENAND_REG_START_BUFFER); + bufferram >>= ONENAND_BSA_SHIFT; + bufferram &= ONENAND_BSA_DATARAM1; + dataram = (bufferram == ONENAND_BSA_DATARAM1) ? 1 : 0; + break; + } + + if (block != -1) + offset += block << this->erase_shift; + + if (page != -1) + offset += page << this->page_shift; + + onenand_data_handle(this, cmd, dataram, offset); + + onenand_update_interrupt(this, cmd); +} + +/** + * onenand_writew - [OneNAND Interface] Emulate write operation + * @value: value to write + * @addr: address to write + * + * Write OneNAND register with value + */ +static void onenand_writew(unsigned short value, void __iomem * addr) +{ + struct onenand_chip *this = info->mtd.priv; + + /* BootRAM handling */ + if (addr < this->base + ONENAND_DATARAM) { + onenand_bootram_handle(this, value); + return; + } + /* Command handling */ + if (addr == this->base + ONENAND_REG_COMMAND) + onenand_command_handle(this, value); + + writew(value, addr); +} + +/** + * flash_init - Initialize OneNAND simulator + * @flash: OneNAND simulator data strucutres + * + * Initialize OneNAND simulator. + */ +static int __init flash_init(struct onenand_flash *flash) +{ + int density, size; + int buffer_size; + + flash->base = kzalloc(131072, GFP_KERNEL); + if (!flash->base) { + printk(KERN_ERR "Unable to allocate base address.\n"); + return -ENOMEM; + } + + density = device_id >> ONENAND_DEVICE_DENSITY_SHIFT; + size = ((16 << 20) << density); + + ONENAND_CORE(flash) = vmalloc(size + (size >> 5)); + if (!ONENAND_CORE(flash)) { + printk(KERN_ERR "Unable to allocate nand core address.\n"); + kfree(flash->base); + return -ENOMEM; + } + + memset(ONENAND_CORE(flash), 0xff, size + (size >> 5)); + + /* Setup registers */ + writew(manuf_id, flash->base + ONENAND_REG_MANUFACTURER_ID); + writew(device_id, flash->base + ONENAND_REG_DEVICE_ID); + writew(version_id, flash->base + ONENAND_REG_VERSION_ID); + + if (density < 2) + buffer_size = 0x0400; /* 1KiB page */ + else + buffer_size = 0x0800; /* 2KiB page */ + writew(buffer_size, flash->base + ONENAND_REG_DATA_BUFFER_SIZE); + + return 0; +} + +/** + * flash_exit - Clean up OneNAND simulator + * @flash: OneNAND simulator data structures + * + * Clean up OneNAND simulator. + */ +static void flash_exit(struct onenand_flash *flash) +{ + vfree(ONENAND_CORE(flash)); + kfree(flash->base); +} + +static int __init onenand_sim_init(void) +{ + /* Allocate all 0xff chars pointer */ + ffchars = kmalloc(MAX_ONENAND_PAGESIZE, GFP_KERNEL); + if (!ffchars) { + printk(KERN_ERR "Unable to allocate ff chars.\n"); + return -ENOMEM; + } + memset(ffchars, 0xff, MAX_ONENAND_PAGESIZE); + + /* Allocate OneNAND simulator mtd pointer */ + info = kzalloc(sizeof(struct onenand_info), GFP_KERNEL); + if (!info) { + printk(KERN_ERR "Unable to allocate core structures.\n"); + kfree(ffchars); + return -ENOMEM; + } + + /* Override write_word function */ + info->onenand.write_word = onenand_writew; + + if (flash_init(&info->flash)) { + printk(KERN_ERR "Unable to allocate flash.\n"); + kfree(ffchars); + kfree(info); + return -ENOMEM; + } + + info->parts = os_partitions; + + info->onenand.base = info->flash.base; + info->onenand.priv = &info->flash; + + info->mtd.name = "OneNAND simulator"; + info->mtd.priv = &info->onenand; + info->mtd.owner = THIS_MODULE; + + if (onenand_scan(&info->mtd, 1)) { + flash_exit(&info->flash); + kfree(ffchars); + kfree(info); + return -ENXIO; + } + + add_mtd_partitions(&info->mtd, info->parts, ARRAY_SIZE(os_partitions)); + + return 0; +} + +static void __exit onenand_sim_exit(void) +{ + struct onenand_chip *this = info->mtd.priv; + struct onenand_flash *flash = this->priv; + + onenand_release(&info->mtd); + flash_exit(flash); + kfree(ffchars); + kfree(info); +} + +module_init(onenand_sim_init); +module_exit(onenand_sim_exit); + +MODULE_AUTHOR("Kyungmin Park "); +MODULE_DESCRIPTION("The OneNAND flash simulator"); +MODULE_LICENSE("GPL"); --- linux-2.6.20.orig/drivers/net/Makefile +++ linux-2.6.20/drivers/net/Makefile @@ -211,9 +211,10 @@ obj-$(CONFIG_HAMRADIO) += hamradio/ obj-$(CONFIG_IRDA) += irda/ obj-$(CONFIG_ETRAX_ETHERNET) += cris/ obj-$(CONFIG_ENP2611_MSF_NET) += ixp2000/ obj-$(CONFIG_NETCONSOLE) += netconsole.o +obj-$(CONFIG_KGDBOE) += kgdboe.o obj-$(CONFIG_FS_ENET) += fs_enet/ obj-$(CONFIG_NETXEN_NIC) += netxen/ --- /dev/null +++ linux-2.6.20/drivers/net/kgdboe.c @@ -0,0 +1,294 @@ +/* + * drivers/net/kgdboe.c + * + * A network interface for GDB. + * Based upon 'gdbserial' by David Grothe + * and Scott Foehner + * + * Maintainers: Amit S. Kale and + * Tom Rini + * + * 2004 (c) Amit S. Kale + * 2004-2005 (c) MontaVista Software, Inc. + * 2005 (c) Wind River Systems, Inc. + * + * Contributors at various stages not listed above: + * San Mehat , Robert Walsh , + * wangdi , Matt Mackall , + * Pavel Machek , Jason Wessel + * + * This file is licensed under the terms of the GNU General Public License + * version 2. This program is licensed "as is" without any warranty of any + * kind, whether express or implied. + */ + +#include +#include +#include +#include +#include +#include + +#include + +#define IN_BUF_SIZE 512 /* power of 2, please */ +#define NOT_CONFIGURED_STRING "not_configured" +#define OUT_BUF_SIZE 30 /* We don't want to send too big of a packet. */ +#define MAX_KGDBOE_CONFIG_STR 256 + +static char in_buf[IN_BUF_SIZE], out_buf[OUT_BUF_SIZE]; +static int in_head, in_tail, out_count; +static atomic_t in_count; +/* 0 = unconfigured, 1 = netpoll options parsed, 2 = fully configured. */ +static int configured; +static struct kgdb_io local_kgdb_io_ops; +static int use_dynamic_mac; + +MODULE_DESCRIPTION("KGDB driver for network interfaces"); +MODULE_LICENSE("GPL"); +static char config[MAX_KGDBOE_CONFIG_STR] = NOT_CONFIGURED_STRING; +static struct kparam_string kps = { + .string = config, + .maxlen = MAX_KGDBOE_CONFIG_STR, +}; + +static void rx_hook(struct netpoll *np, int port, char *msg, int len, + struct sk_buff *skb) +{ + int i; + + np->remote_port = port; + + /* Copy the MAC address if we need to. */ + if (use_dynamic_mac) { + memcpy(np->remote_mac, eth_hdr(skb)->h_source, + sizeof(np->remote_mac)); + use_dynamic_mac = 0; + } + + /* + * This could be GDB trying to attach. But it could also be GDB + * finishing up a session, with kgdb_connected=0 but GDB sending + * an ACK for the final packet. To make sure we don't try and + * make a breakpoint when GDB is leaving, make sure that if + * !kgdb_connected the only len == 1 packet we allow is ^C. + */ + if (!kgdb_connected && (len != 1 || msg[0] == 3) && + !atomic_read(&kgdb_setting_breakpoint)) { + tasklet_schedule(&kgdb_tasklet_breakpoint); + } + + for (i = 0; i < len; i++) { + if (msg[i] == 3) + tasklet_schedule(&kgdb_tasklet_breakpoint); + + if (atomic_read(&in_count) >= IN_BUF_SIZE) { + /* buffer overflow, clear it */ + in_head = in_tail = 0; + atomic_set(&in_count, 0); + break; + } + in_buf[in_head++] = msg[i]; + in_head &= (IN_BUF_SIZE - 1); + atomic_inc(&in_count); + } +} + +static struct netpoll np = { + .dev_name = "eth0", + .name = "kgdboe", + .rx_hook = rx_hook, + .local_port = 6443, + .remote_port = 6442, + .remote_mac = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }, +}; + +static void eth_pre_exception_handler(void) +{ + /* Increment the module count when the debugger is active */ + if (!kgdb_connected) + try_module_get(THIS_MODULE); + netpoll_set_trap(1); +} + +static void eth_post_exception_handler(void) +{ + /* decrement the module count when the debugger detaches */ + if (!kgdb_connected) + module_put(THIS_MODULE); + netpoll_set_trap(0); +} + +static int eth_get_char(void) +{ + int chr; + + while (atomic_read(&in_count) == 0) + netpoll_poll(&np); + + chr = in_buf[in_tail++]; + in_tail &= (IN_BUF_SIZE - 1); + atomic_dec(&in_count); + return chr; +} + +static void eth_flush_buf(void) +{ + if (out_count && np.dev) { + netpoll_send_udp(&np, out_buf, out_count); + memset(out_buf, 0, sizeof(out_buf)); + out_count = 0; + } +} + +static void eth_put_char(u8 chr) +{ + out_buf[out_count++] = chr; + if (out_count == OUT_BUF_SIZE) + eth_flush_buf(); +} + +static int option_setup(char *opt) +{ + char opt_scratch[MAX_KGDBOE_CONFIG_STR]; + + /* If we're being given a new configuration, copy it in. */ + if (opt != config) + strcpy(config, opt); + /* But work on a copy as netpoll_parse_options will eat it. */ + strcpy(opt_scratch, opt); + configured = !netpoll_parse_options(&np, opt_scratch); + + use_dynamic_mac = 1; + + return 0; +} +__setup("kgdboe=", option_setup); + +/* With our config string set by some means, configure kgdboe. */ +static int configure_kgdboe(void) +{ + /* Try out the string. */ + option_setup(config); + + if (!configured) { + printk(KERN_ERR "kgdboe: configuration incorrect - kgdboe not " + "loaded.\n"); + printk(KERN_ERR " Usage: kgdboe=[src-port]@[src-ip]/[dev]," + "[tgt-port]@/\n"); + return -EINVAL; + } + + /* Bring it up. */ + if (netpoll_setup(&np)) { + printk(KERN_ERR "kgdboe: netpoll_setup failed kgdboe failed\n"); + return -EINVAL; + } + + if (kgdb_register_io_module(&local_kgdb_io_ops)) { + netpoll_cleanup(&np); + return -EINVAL; + } + + configured = 2; + + return 0; +} + +static int init_kgdboe(void) +{ + int ret; + + /* Already done? */ + if (configured == 2) + return 0; + + /* OK, go ahead and do it. */ + ret = configure_kgdboe(); + + if (configured == 2) + printk(KERN_INFO "kgdboe: debugging over ethernet enabled\n"); + + return ret; +} + +static void cleanup_kgdboe(void) +{ + netpoll_cleanup(&np); + configured = 0; + kgdb_unregister_io_module(&local_kgdb_io_ops); +} + +static int param_set_kgdboe_var(const char *kmessage, struct kernel_param *kp) +{ + char kmessage_save[MAX_KGDBOE_CONFIG_STR]; + int msg_len = strlen(kmessage); + + if (msg_len + 1 > MAX_KGDBOE_CONFIG_STR) { + printk(KERN_ERR "%s: string doesn't fit in %u chars.\n", + kp->name, MAX_KGDBOE_CONFIG_STR - 1); + return -ENOSPC; + } + + if (kgdb_connected) { + printk(KERN_ERR "kgdboe: Cannot reconfigure while KGDB is " + "connected.\n"); + return 0; + } + + /* Start the reconfiguration process by saving the old string */ + strncpy(kmessage_save, config, sizeof(kmessage_save)); + + + /* Copy in the new param and strip out invalid characters so we + * can optionally specify the MAC. + */ + strncpy(config, kmessage, sizeof(config)); + msg_len--; + while (msg_len > 0 && + (config[msg_len] < ',' || config[msg_len] > 'f')) { + config[msg_len] = '\0'; + msg_len--; + } + + /* Check to see if we are unconfiguring the io module and that it + * was in a fully configured state, as this is the only time that + * netpoll_cleanup should get called + */ + if (configured == 2 && strcmp(config, NOT_CONFIGURED_STRING) == 0) { + printk(KERN_INFO "kgdboe: reverting to unconfigured state\n"); + cleanup_kgdboe(); + return 0; + } else + /* Go and configure with the new params. */ + configure_kgdboe(); + + if (configured == 2) + return 0; + + /* If the new string was invalid, revert to the previous state, which + * is at a minimum not_configured. */ + strncpy(config, kmessage_save, sizeof(config)); + if (strcmp(kmessage_save, NOT_CONFIGURED_STRING) != 0) { + printk(KERN_INFO "kgdboe: reverting to prior configuration\n"); + /* revert back to the original config */ + strncpy(config, kmessage_save, sizeof(config)); + configure_kgdboe(); + } + return 0; +} + +static struct kgdb_io local_kgdb_io_ops = { + .read_char = eth_get_char, + .write_char = eth_put_char, + .init = init_kgdboe, + .flush = eth_flush_buf, + .pre_exception = eth_pre_exception_handler, + .post_exception = eth_post_exception_handler +}; + +module_init(init_kgdboe); +module_exit(cleanup_kgdboe); +module_param_call(kgdboe, param_set_kgdboe_var, param_get_string, &kps, 0644); +MODULE_PARM_DESC(kgdboe, " kgdboe=[src-port]@[src-ip]/[dev]," + "[tgt-port]@/\n"); --- linux-2.6.20.orig/drivers/net/smc91x.c +++ linux-2.6.20/drivers/net/smc91x.c @@ -1,5 +1,6 @@ + /* * smc91x.c * This is a driver for SMSC's 91C9x/91C1xx single-chip Ethernet devices. * * Copyright (C) 1996 by Erik Stahlman @@ -63,11 +64,10 @@ static const char version[] = /* Debugging level */ #ifndef SMC_DEBUG #define SMC_DEBUG 0 #endif - #include #include #include #include #include @@ -88,10 +88,12 @@ static const char version[] = #include #include "smc91x.h" +#include + #ifdef CONFIG_ISA /* * the LAN91C111 can be at any of the following port addresses. To change, * for a slightly different card, you can add it to the array. Keep in * mind that the array must end in zero. @@ -266,11 +268,10 @@ static void PRINT_PKT(u_char *buf, int l } #else #define PRINT_PKT(x...) do { } while(0) #endif - /* this enables an interrupt in the interrupt mask register */ #define SMC_ENABLE_INT(x) do { \ unsigned char mask; \ spin_lock_irq(&lp->lock); \ mask = SMC_GET_INT_MASK(); \ @@ -306,11 +307,10 @@ static void PRINT_PKT(u_char *buf, int l cpu_relax(); \ } \ } \ } while (0) - /* * this does a soft reset on the device */ static void smc_reset(struct net_device *dev) { @@ -492,12 +492,11 @@ static inline void smc_rcv(struct net_d /* First two words are status and packet length */ SMC_GET_PKT_HDR(status, packet_len); packet_len &= 0x07ff; /* mask off top bits */ DBG(2, "%s: RX PNR 0x%x STATUS 0x%04x LENGTH 0x%04x (%d)\n", - dev->name, packet_number, status, - packet_len, packet_len); + dev->name, packet_number, status, packet_len, packet_len); back: if (unlikely(packet_len < 6 || status & RS_ERRORS)) { if (status & RS_TOOLONG && packet_len <= (1514 + 4 + 6)) { /* accept VLAN packets */ @@ -833,11 +832,10 @@ static void smc_tx(struct net_device *de SMC_SELECT_BANK(0); SMC_SET_TCR(lp->tcr_cur_mode); SMC_SELECT_BANK(2); } - /*---PHY CONTROL AND CONFIGURATION-----------------------------------------*/ static void smc_mii_out(struct net_device *dev, unsigned int val, int bits) { struct smc_local *lp = netdev_priv(dev); @@ -925,11 +923,13 @@ static void smc_phy_write(struct net_dev /* Idle - 32 ones */ smc_mii_out(dev, 0xffffffff, 32); /* Start code (01) + write (01) + phyaddr + phyreg + turnaround + phydata */ - smc_mii_out(dev, 5 << 28 | phyaddr << 23 | phyreg << 18 | 2 << 16 | phydata, 32); + smc_mii_out(dev, + 5 << 28 | phyaddr << 23 | phyreg << 18 | 2 << 16 | phydata, + 32); /* Return to idle state */ SMC_SET_MII(SMC_GET_MII() & ~(MII_MCLK|MII_MDOE|MII_MDO)); DBG(3, "%s: phyaddr=0x%x, phyreg=0x%x, phydata=0x%x\n", @@ -959,12 +959,11 @@ static void smc_phy_detect(struct net_de /* Read the PHY identifiers */ id1 = smc_phy_read(dev, phyaddr & 31, MII_PHYSID1); id2 = smc_phy_read(dev, phyaddr & 31, MII_PHYSID2); - DBG(3, "%s: phy_id1=0x%x, phy_id2=0x%x\n", - dev->name, id1, id2); + DBG(3, "%s: phy_id1=0x%x, phy_id2=0x%x\n", dev->name, id1, id2); /* Make sure it is a valid identifier */ if (id1 != 0x0000 && id1 != 0xffff && id1 != 0x8000 && id2 != 0x0000 && id2 != 0xffff && id2 != 0x8000) { /* Save the PHY's address */ @@ -1182,11 +1181,13 @@ static void smc_phy_configure(struct wor if (my_phy_caps & BMSR_10HALF) my_ad_caps |= ADVERTISE_10HALF; /* Disable capabilities not selected by our user */ if (lp->ctl_rspeed != 100) - my_ad_caps &= ~(ADVERTISE_100BASE4|ADVERTISE_100FULL|ADVERTISE_100HALF); + my_ad_caps &= + ~(ADVERTISE_100BASE4 | ADVERTISE_100FULL | + ADVERTISE_100HALF); if (!lp->ctl_rfduplx) my_ad_caps &= ~(ADVERTISE_100FULL|ADVERTISE_10FULL); /* Update our Auto-Neg Advertisement Register */ @@ -1312,15 +1313,16 @@ static irqreturn_t smc_interrupt(int irq do { status = SMC_GET_INT(); DBG(2, "%s: INT 0x%02x MASK 0x%02x MEM 0x%04x FIFO 0x%04x\n", - dev->name, status, mask, - ({ int meminfo; SMC_SELECT_BANK(0); + dev->name, status, mask, ( { + int meminfo; + SMC_SELECT_BANK(0); meminfo = SMC_GET_MIR(); - SMC_SELECT_BANK(2); meminfo; }), - SMC_GET_FIFO()); + SMC_SELECT_BANK(2); + meminfo;}), SMC_GET_FIFO()); status &= mask; if (!status) break; @@ -1352,14 +1354,22 @@ static irqreturn_t smc_interrupt(int irq card_stats >>= 4; /* multiple collisions */ lp->stats.collisions += card_stats & 0xF; } else if (status & IM_RX_OVRN_INT) { - DBG(1, "%s: RX overrun (EPH_ST 0x%04x)\n", dev->name, - ({ int eph_st; SMC_SELECT_BANK(0); - eph_st = SMC_GET_EPH_STATUS(); - SMC_SELECT_BANK(2); eph_st; }) ); + DBG(1, "%s: RX overrun (EPH_ST 0x%04x)\n", dev->name, ( { + int + eph_st; + SMC_SELECT_BANK + (0); + eph_st + = + SMC_GET_EPH_STATUS + (); + SMC_SELECT_BANK + (2); + eph_st;})); SMC_ACK_INT(IM_RX_OVRN_INT); lp->stats.rx_errors++; lp->stats.rx_fifo_errors++; } else if (status & IM_EPH_INT) { smc_eph_interrupt(dev); @@ -1498,11 +1508,12 @@ static void smc_set_multicast_list(struc else if (dev->mc_count) { int i; struct dev_mc_list *cur_addr; /* table for flipping the order of 3 bits */ - static const unsigned char invert3[] = {0, 4, 2, 6, 1, 5, 3, 7}; + static const unsigned char invert3[] = + { 0, 4, 2, 6, 1, 5, 3, 7 }; /* start with a table of all zeros: reject all */ memset(multicast_table, 0, sizeof(multicast_table)); cur_addr = dev->mc_list; @@ -1551,18 +1562,16 @@ static void smc_set_multicast_list(struc } SMC_SELECT_BANK(2); spin_unlock_irq(&lp->lock); } - /* * Open and Initialize the board * * Set up everything, reset the card, etc.. */ -static int -smc_open(struct net_device *dev) +static int smc_open(struct net_device *dev) { struct smc_local *lp = netdev_priv(dev); DBG(2, "%s: %s\n", dev->name, __FUNCTION__); @@ -1657,22 +1666,22 @@ smc_ethtool_getsettings(struct net_devic spin_lock_irq(&lp->lock); ret = mii_ethtool_gset(&lp->mii, cmd); spin_unlock_irq(&lp->lock); } else { cmd->supported = SUPPORTED_10baseT_Half | - SUPPORTED_10baseT_Full | - SUPPORTED_TP | SUPPORTED_AUI; + SUPPORTED_10baseT_Full | SUPPORTED_TP | SUPPORTED_AUI; if (lp->ctl_rspeed == 10) cmd->speed = SPEED_10; else if (lp->ctl_rspeed == 100) cmd->speed = SPEED_100; cmd->autoneg = AUTONEG_DISABLE; cmd->transceiver = XCVR_INTERNAL; cmd->port = 0; - cmd->duplex = lp->tcr_cur_mode & TCR_SWFDUP ? DUPLEX_FULL : DUPLEX_HALF; + cmd->duplex = + lp->tcr_cur_mode & TCR_SWFDUP ? DUPLEX_FULL : DUPLEX_HALF; ret = 0; } return ret; @@ -1689,12 +1698,12 @@ smc_ethtool_setsettings(struct net_devic ret = mii_ethtool_sset(&lp->mii, cmd); spin_unlock_irq(&lp->lock); } else { if (cmd->autoneg != AUTONEG_DISABLE || cmd->speed != SPEED_10 || - (cmd->duplex != DUPLEX_HALF && cmd->duplex != DUPLEX_FULL) || - (cmd->port != PORT_TP && cmd->port != PORT_AUI)) + (cmd->duplex != DUPLEX_HALF && cmd->duplex != DUPLEX_FULL) + || (cmd->port != PORT_TP && cmd->port != PORT_AUI)) return -EINVAL; // lp->port = cmd->port; lp->ctl_rfduplx = cmd->duplex == DUPLEX_FULL; @@ -1710,11 +1719,12 @@ smc_ethtool_setsettings(struct net_devic static void smc_ethtool_getdrvinfo(struct net_device *dev, struct ethtool_drvinfo *info) { strncpy(info->driver, CARDNAME, sizeof(info->driver)); strncpy(info->version, version, sizeof(info->version)); - strncpy(info->bus_info, dev->class_dev.dev->bus_id, sizeof(info->bus_info)); + strncpy(info->bus_info, dev->class_dev.dev->bus_id, + sizeof(info->bus_info)); } static int smc_ethtool_nwayreset(struct net_device *dev) { struct smc_local *lp = netdev_priv(dev); @@ -1837,11 +1847,11 @@ static int __init smc_findirq(void __iom * o set up my private data * o configure the dev structure with my subroutines * o actually GRAB the irq. * o GRAB the region */ -static int __init smc_probe(struct net_device *dev, void __iomem *ioaddr) +int __init smc_probe(struct net_device *dev, void __iomem * ioaddr) { struct smc_local *lp = netdev_priv(dev); static int version_printed = 0; int i, retval; unsigned int val, revision_register; @@ -1878,10 +1888,12 @@ static int __init smc_probe(struct net_d * time won't hurt. This time, I need to switch the bank * register to bank 1, so I can access the base address * register */ SMC_SELECT_BANK(1); + mdelay(100); + val = SMC_CURRENT_BANK(); val = SMC_GET_BASE(); val = ((val & 0x1F00) >> 3) << SMC_IO_SHIFT; if (((unsigned int)ioaddr & (0x3e0 << SMC_IO_SHIFT)) != val) { printk("%s: IOADDR %p doesn't match configuration (%x).\n", CARDNAME, ioaddr, val); @@ -1916,10 +1928,11 @@ static int __init smc_probe(struct net_d lp->version = revision_register & 0xff; spin_lock_init(&lp->lock); /* Get the MAC address */ SMC_SELECT_BANK(1); + SMC_GET_MAC_ADDR(dev->dev_addr); /* now, reset the chip, and put it into a known state */ smc_reset(dev); @@ -2003,11 +2016,15 @@ static int __init smc_probe(struct net_d lp->ctl_rfduplx = 1; lp->ctl_rspeed = 100; } /* Grab the IRQ */ - retval = request_irq(dev->irq, &smc_interrupt, SMC_IRQ_FLAGS, dev->name, dev); + printk("dev->irq = %d\n", dev->irq); + + retval = + request_irq(dev->irq, smc_interrupt, SMC_IRQ_FLAGS, dev->name, dev); + if (retval) goto err_out; #ifdef SMC_USE_PXA_DMA { @@ -2043,11 +2060,12 @@ static int __init smc_probe(struct net_d } if (lp->phy_type == 0) { PRINTK("%s: No PHY found\n", dev->name); } else if ((lp->phy_type & 0xfffffff0) == 0x0016f840) { - PRINTK("%s: PHY LAN83C183 (LAN91C111 Internal)\n", dev->name); + PRINTK("%s: PHY LAN83C183 (LAN91C111 Internal)\n", + dev->name); } else if ((lp->phy_type & 0xfffffff0) == 0x02821c50) { PRINTK("%s: PHY LAN83C180\n", dev->name); } } @@ -2064,11 +2082,12 @@ static int smc_enable_device(struct plat unsigned long flags; unsigned char ecor, ecsr; void __iomem *addr; struct resource * res; - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "smc91x-attrib"); + res = + platform_get_resource_byname(pdev, IORESOURCE_MEM, "smc91x-attrib"); if (!res) return 0; /* * Map the attribute space. This is overkill, but clean. @@ -2120,11 +2139,12 @@ static int smc_enable_device(struct plat return 0; } static int smc_request_attrib(struct platform_device *pdev) { - struct resource * res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "smc91x-attrib"); + struct resource *res = + platform_get_resource_byname(pdev, IORESOURCE_MEM, "smc91x-attrib"); if (!res) return 0; if (!request_mem_region(res->start, ATTRIB_SIZE, CARDNAME)) @@ -2133,11 +2153,12 @@ static int smc_request_attrib(struct pla return 0; } static void smc_release_attrib(struct platform_device *pdev) { - struct resource * res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "smc91x-attrib"); + struct resource *res = + platform_get_resource_byname(pdev, IORESOURCE_MEM, "smc91x-attrib"); if (res) release_mem_region(res->start, ATTRIB_SIZE); } @@ -2157,12 +2178,16 @@ static inline void smc_request_datacs(st lp->datacs = ioremap(res->start, SMC_DATA_EXTENT); } } -static void smc_release_datacs(struct platform_device *pdev, struct net_device *ndev) +static void smc_release_datacs(struct platform_device *pdev, + struct net_device *ndev) { +// struct smc_local *lp = netdev_priv(ndev); +// struct resource *res = +// platform_get_resource_byname(pdev, IORESOURCE_MEM, "smc91x-data32"); if (SMC_CAN_USE_DATACS) { struct smc_local *lp = netdev_priv(ndev); struct resource * res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "smc91x-data32"); if (lp->datacs) @@ -2199,11 +2224,10 @@ static int smc_drv_probe(struct platform if (!res) { ret = -ENODEV; goto out; } - if (!request_mem_region(res->start, SMC_IO_EXTENT, CARDNAME)) { ret = -EBUSY; goto out; } @@ -2238,10 +2262,11 @@ static int smc_drv_probe(struct platform ret = -ENOMEM; goto out_release_attrib; } platform_set_drvdata(pdev, ndev); + ret = smc_probe(ndev, addr); if (ret != 0) goto out_iounmap; #ifdef SMC_USE_PXA_DMA else { @@ -2276,11 +2301,10 @@ static int smc_drv_remove(struct platfor struct resource *res; platform_set_drvdata(pdev, NULL); unregister_netdev(ndev); - free_irq(ndev->irq, ndev); #ifdef SMC_USE_PXA_DMA if (ndev->dma != (unsigned char)-1) pxa_free_dma(ndev->dma); @@ -2346,12 +2370,10 @@ static int __init smc_init(void) { #ifdef MODULE #ifdef CONFIG_ISA if (io == -1) printk(KERN_WARNING - "%s: You shouldn't use auto-probing with insmod!\n", - CARDNAME); #endif #endif return platform_driver_register(&smc_driver); } --- linux-2.6.20.orig/drivers/net/smc91x.h +++ linux-2.6.20/drivers/net/smc91x.h @@ -32,11 +32,10 @@ . ---------------------------------------------------------------------------*/ #ifndef _SMC91X_H_ #define _SMC91X_H_ - /* * Define your architecture specific bus configuration parameters here. */ #if defined(CONFIG_ARCH_LUBBOCK) @@ -161,12 +160,11 @@ #define SMC_outl(v, a, r) writel(v, (a) + (r)) #define SMC_insl(a, r, p, l) readsl((a) + (r), p, l) #define SMC_outsl(a, r, p, l) writesl((a) + (r), p, l) /* We actually can't write halfwords properly if not word aligned */ -static inline void -SMC_outw(u16 val, void __iomem *ioaddr, int reg) +static inline void SMC_outw(u16 val, void __iomem * ioaddr, int reg) { if (reg & 2) { unsigned int v = val << 16; v |= readl(ioaddr + (reg & ~2)) & 0xffff; writel(v, ioaddr + (reg & ~2)); @@ -197,10 +195,81 @@ SMC_outw(u16 val, void __iomem *ioaddr, || machine_is_omap_h3() \ || machine_is_omap_h4() \ || (machine_is_omap_innovator() && !cpu_is_omap1510()) \ ) ? IRQF_TRIGGER_FALLING : IRQF_TRIGGER_RISING) +#elif defined(CONFIG_ARCH_NOMADIK) + +#include + +#define SMC_CAN_USE_8BIT 0 +#define SMC_CAN_USE_16BIT 1 +#define SMC_CAN_USE_32BIT 0 +#define SMC_IO_SHIFT 0 +#define SMC_NOWAIT 0 + +#define SMC_inb(a, r) readb((a) + (r)) +#define SMC_outb(v, a, r) writeb(v, (a) + (r)) +#define SMC_inw(a, r) readw((a) + (r)) +#define SMC_outw(v, a, r) writew(v, (a) + (r)) +#define SMC_insw(a, r, p, l) readsw((a) + (r), p, l) +#define SMC_outsw(a, r, p, l) writesw((a) + (r), p, l) +#define SMC_inl(a, r) readl((a) + (r)) +#define SMC_outl(v, a, r) writel(v, (a) + (r)) +#define SMC_insl(a, r, p, l) readsl((a) + (r), p, l) +#define SMC_outsl(a, r, p, l) writesl((a) + (r), p, l) + +#ifdef CONFIG_NOMADIK_NHK15 +#define SMC_IRQ_FLAGS SA_TRIGGER_RISING +#else +#define SMC_IRQ_FLAGS (SA_SHIRQ) +#endif + +static unsigned char new_mac_addr[MAX_ADDR_LEN] = + { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; + +static int smc_mac_setup(char *opt) +{ + char *cur = opt, *delim; + if (*cur != 0) { + /* Get the new MAC address */ + if ((delim = strchr(cur, ':')) == NULL) + goto parse_failed; + *delim = 0; + new_mac_addr[0] = (*cur - '0') * 16 + (*(cur + 1) - '0'); + new_mac_addr[0] &= 0xFE; /* clear multicast bit */ + new_mac_addr[0] |= 0x02; /* set local assignment bit (IEEE802) */ + cur = delim + 1; + if ((delim = strchr(cur, ':')) == NULL) + goto parse_failed; + *delim = 0; + new_mac_addr[1] = (*cur - '0') * 16 + (*(cur + 1) - '0'); + cur = delim + 1; + if ((delim = strchr(cur, ':')) == NULL) + goto parse_failed; + *delim = 0; + new_mac_addr[2] = (*cur - '0') * 16 + (*(cur + 1) - '0'); + cur = delim + 1; + if ((delim = strchr(cur, ':')) == NULL) + goto parse_failed; + *delim = 0; + new_mac_addr[3] = (*cur - '0') * 16 + (*(cur + 1) - '0'); + cur = delim + 1; + if ((delim = strchr(cur, ':')) == NULL) + goto parse_failed; + *delim = 0; + new_mac_addr[4] = (*cur - '0') * 16 + (*(cur + 1) - '0'); + cur = delim + 1; + new_mac_addr[5] = (*cur - '0') * 16 + (*(cur + 1) - '0'); + } + return 0; +parse_failed: + printk(KERN_INFO "mac=: couldn't parse config at %s!\n", cur); + return -1; +} + +__setup("mac=", smc_mac_setup); #elif defined(CONFIG_SH_SH4202_MICRODEV) #define SMC_CAN_USE_8BIT 0 #define SMC_CAN_USE_16BIT 1 @@ -475,24 +544,25 @@ smc_pxa_dma_irq(int dma, void *dummy) { DCSR(dma) = 0; } #endif /* SMC_USE_PXA_DMA */ - /* * Everything a particular hardware setup needs should have been defined * at this point. Add stubs for the undefined cases, mainly to avoid * compilation warnings since they'll be optimized away, or to prevent buggy * use of them. */ +#if 0 /*Vaibhav*/ #if ! SMC_CAN_USE_32BIT #define SMC_inl(ioaddr, reg) ({ BUG(); 0; }) #define SMC_outl(x, ioaddr, reg) BUG() #define SMC_insl(a, r, p, l) BUG() #define SMC_outsl(a, r, p, l) BUG() #endif +#endif #if !defined(SMC_insl) || !defined(SMC_outsl) #define SMC_insl(a, r, p, l) BUG() #define SMC_outsl(a, r, p, l) BUG() #endif @@ -520,18 +590,22 @@ smc_pxa_dma_irq(int dma, void *dummy) #define SMC_insw(a, r, p, l) BUG() #define SMC_outsw(a, r, p, l) BUG() #endif +#if 0 /*Vaibhav*/ #if !defined(SMC_insw) || !defined(SMC_outsw) #define SMC_insw(a, r, p, l) BUG() #define SMC_outsw(a, r, p, l) BUG() #endif +#endif #if ! SMC_CAN_USE_8BIT +#if 0 /*Vaibhav*/ #define SMC_inb(ioaddr, reg) ({ BUG(); 0; }) #define SMC_outb(x, ioaddr, reg) BUG() +#endif #define SMC_insb(a, r, p, l) BUG() #define SMC_outsb(a, r, p, l) BUG() #endif #if !defined(SMC_insb) || !defined(SMC_outsb) @@ -567,11 +641,10 @@ smc_pxa_dma_irq(int dma, void *dummy) . xx = bank number . yyyy yyyy = 0x33, for identification purposes. */ #define BANK_SELECT (14 << SMC_IO_SHIFT) - // Transmit Control Register /* BANK 0 */ #define TCR_REG SMC_REG(0x0000, 0) #define TCR_ENABLE 0x0001 // When 1 we can transmit #define TCR_LOOP 0x0002 // Controls output pin LBK @@ -586,11 +659,10 @@ smc_pxa_dma_irq(int dma, void *dummy) #define TCR_CLEAR 0 /* do NOTHING */ /* the default settings for the TCR register : */ #define TCR_DEFAULT (TCR_ENABLE | TCR_PAD_EN) - // EPH Status Register /* BANK 0 */ #define EPH_STATUS_REG SMC_REG(0x0002, 0) #define ES_TX_SUC 0x0001 // Last TX was successful #define ES_SNGL_COL 0x0002 // Single collision detected for last tx @@ -605,11 +677,10 @@ smc_pxa_dma_irq(int dma, void *dummy) #define ES_EXC_DEF 0x0800 // Excessive Deferral #define ES_CTR_ROL 0x1000 // Counter Roll Over indication #define ES_LINK_OK 0x4000 // Driven by inverted value of nLNK pin #define ES_TXUNRN 0x8000 // Tx Underrun - // Receive Control Register /* BANK 0 */ #define RCR_REG SMC_REG(0x0004, 0) #define RCR_RX_ABORT 0x0001 // Set if a rx frame was aborted #define RCR_PRMS 0x0002 // Enable promiscuous mode @@ -622,21 +693,18 @@ smc_pxa_dma_irq(int dma, void *dummy) /* the normal settings for the RCR register : */ #define RCR_DEFAULT (RCR_STRIP_CRC | RCR_RXEN) #define RCR_CLEAR 0x0 // set it to a base state - // Counter Register /* BANK 0 */ #define COUNTER_REG SMC_REG(0x0006, 0) - // Memory Information Register /* BANK 0 */ #define MIR_REG SMC_REG(0x0008, 0) - // Receive/Phy Control Register /* BANK 0 */ #define RPC_REG SMC_REG(0x000A, 0) #define RPC_SPEED 0x2000 // When 1 PHY is in 100Mbps mode. #define RPC_DPLX 0x1000 // When 1 PHY is in Full-Duplex Mode @@ -659,18 +727,16 @@ smc_pxa_dma_irq(int dma, void *dummy) #define RPC_LSB_DEFAULT RPC_LED_FD #endif #define RPC_DEFAULT (RPC_ANEG | (RPC_LSA_DEFAULT << RPC_LSXA_SHFT) | (RPC_LSB_DEFAULT << RPC_LSXB_SHFT) | RPC_SPEED | RPC_DPLX) - /* Bank 0 0x0C is reserved */ // Bank Select Register /* All Banks */ #define BSR_REG 0x000E - // Configuration Reg /* BANK 1 */ #define CONFIG_REG SMC_REG(0x0000, 1) #define CONFIG_EXT_PHY 0x0200 // 1=external MII, 0=internal Phy #define CONFIG_GPCNTRL 0x0400 // Inverse value drives pin nCNTRL @@ -678,28 +744,24 @@ smc_pxa_dma_irq(int dma, void *dummy) #define CONFIG_EPH_POWER_EN 0x8000 // When 0 EPH is placed into low power mode. // Default is powered-up, Internal Phy, Wait States, and pin nCNTRL=low #define CONFIG_DEFAULT (CONFIG_EPH_POWER_EN) - // Base Address Register /* BANK 1 */ #define BASE_REG SMC_REG(0x0002, 1) - // Individual Address Registers /* BANK 1 */ #define ADDR0_REG SMC_REG(0x0004, 1) #define ADDR1_REG SMC_REG(0x0006, 1) #define ADDR2_REG SMC_REG(0x0008, 1) - // General Purpose Register /* BANK 1 */ #define GP_REG SMC_REG(0x000A, 1) - // Control Register /* BANK 1 */ #define CTL_REG SMC_REG(0x000C, 1) #define CTL_RCV_BAD 0x4000 // When 1 bad CRC packets are received #define CTL_AUTO_RELEASE 0x0800 // When 1 tx pages are released automatically @@ -708,11 +770,10 @@ smc_pxa_dma_irq(int dma, void *dummy) #define CTL_TE_ENABLE 0x0020 // When 1 enables Transmit Error interrupt #define CTL_EEPROM_SELECT 0x0004 // Controls EEPROM reload & store #define CTL_RELOAD 0x0002 // When set reads EEPROM into registers #define CTL_STORE 0x0001 // When set stores registers into EEPROM - // MMU Command Register /* BANK 2 */ #define MMU_CMD_REG SMC_REG(0x0000, 2) #define MC_BUSY 1 // When 1 the last release has not completed #define MC_NOP (0<<5) // No Op @@ -722,22 +783,19 @@ smc_pxa_dma_irq(int dma, void *dummy) #define MC_RELEASE (4<<5) // Remove and release the current rx packet #define MC_FREEPKT (5<<5) // Release packet in PNR register #define MC_ENQUEUE (6<<5) // Enqueue the packet for transmit #define MC_RSTTXFIFO (7<<5) // Reset the TX FIFOs - // Packet Number Register /* BANK 2 */ #define PN_REG SMC_REG(0x0002, 2) - // Allocation Result Register /* BANK 2 */ #define AR_REG SMC_REG(0x0003, 2) #define AR_FAILED 0x80 // Alocation Failed - // TX FIFO Ports Register /* BANK 2 */ #define TXFIFO_REG SMC_REG(0x0004, 2) #define TXFIFO_TEMPTY 0x80 // TX FIFO Empty @@ -753,21 +811,18 @@ smc_pxa_dma_irq(int dma, void *dummy) #define PTR_REG SMC_REG(0x0006, 2) #define PTR_RCV 0x8000 // 1=Receive area, 0=Transmit area #define PTR_AUTOINC 0x4000 // Auto increment the pointer on each access #define PTR_READ 0x2000 // When 1 the operation is a read - // Data Register /* BANK 2 */ #define DATA_REG SMC_REG(0x0008, 2) - // Interrupt Status/Acknowledge Register /* BANK 2 */ #define INT_REG SMC_REG(0x000C, 2) - // Interrupt Mask Register /* BANK 2 */ #define IM_REG SMC_REG(0x000D, 2) #define IM_MDINT 0x80 // PHY MI Register 18 Interrupt #define IM_ERCV_INT 0x40 // Early Receive Interrupt @@ -776,48 +831,42 @@ smc_pxa_dma_irq(int dma, void *dummy) #define IM_ALLOC_INT 0x08 // Set when allocation request is completed #define IM_TX_EMPTY_INT 0x04 // Set if the TX FIFO goes empty #define IM_TX_INT 0x02 // Transmit Interrupt #define IM_RCV_INT 0x01 // Receive Interrupt - // Multicast Table Registers /* BANK 3 */ #define MCAST_REG1 SMC_REG(0x0000, 3) #define MCAST_REG2 SMC_REG(0x0002, 3) #define MCAST_REG3 SMC_REG(0x0004, 3) #define MCAST_REG4 SMC_REG(0x0006, 3) - // Management Interface Register (MII) /* BANK 3 */ #define MII_REG SMC_REG(0x0008, 3) #define MII_MSK_CRS100 0x4000 // Disables CRS100 detection during tx half dup #define MII_MDOE 0x0008 // MII Output Enable #define MII_MCLK 0x0004 // MII Clock, pin MDCLK #define MII_MDI 0x0002 // MII Input, pin MDI #define MII_MDO 0x0001 // MII Output, pin MDO - // Revision Register /* BANK 3 */ /* ( hi: chip id low: rev # ) */ #define REV_REG SMC_REG(0x000A, 3) - // Early RCV Register /* BANK 3 */ /* this is NOT on SMC9192 */ #define ERCV_REG SMC_REG(0x000C, 3) #define ERCV_RCV_DISCRD 0x0080 // When 1 discards a packet being received #define ERCV_THRESHOLD 0x001F // ERCV Threshold Mask - // External Register /* BANK 7 */ #define EXT_REG SMC_REG(0x0000, 7) - #define CHIP_9192 3 #define CHIP_9194 4 #define CHIP_9195 5 #define CHIP_9196 6 #define CHIP_91100 7 @@ -832,12 +881,12 @@ static const char * chip_ids[ 16 ] = { /* 6 */ "SMC91C96", /* 7 */ "SMC91C100", /* 8 */ "SMC91C100FD", /* 9 */ "SMC91C11xFD", NULL, NULL, NULL, - NULL, NULL, NULL}; - + NULL, NULL, NULL +}; /* . Receive status bits */ #define RS_ALGNERR 0x8000 @@ -847,11 +896,10 @@ static const char * chip_ids[ 16 ] = { #define RS_TOOLONG 0x0800 #define RS_TOOSHORT 0x0400 #define RS_MULTICAST 0x0001 #define RS_ERRORS (RS_ALGNERR | RS_BADCRC | RS_TOOLONG | RS_TOOSHORT) - /* * PHY IDs * LAN83C183 == LAN91C111 Internal PHY */ #define PHY_LAN83C183 0x0016f840 @@ -877,11 +925,10 @@ static const char * chip_ids[ 16 ] = { #define PHY_CFG1_RLVL0 0x0040 // 1=Rx Squelch level reduced by 4.5db #define PHY_CFG1_TLVL_SHIFT 2 // Transmit Output Level Adjust #define PHY_CFG1_TLVL_MASK 0x003C #define PHY_CFG1_TRF_MASK 0x0003 // Transmitter Rise/Fall time - // PHY Configuration Register 2 #define PHY_CFG2_REG 0x11 #define PHY_CFG2_APOLDIS 0x0020 // 1=Auto Polarity Correction disabled #define PHY_CFG2_JABDIS 0x0010 // 1=Jabber disabled #define PHY_CFG2_MREG 0x0008 // 1=Multiple register access (MII mgt) @@ -902,11 +949,10 @@ static const char * chip_ids[ 16 ] = { // PHY Interrupt/Status Mask Register #define PHY_MASK_REG 0x13 // Interrupt Mask // Uses the same bit definitions as PHY_INT_REG - /* * SMC91C96 ethernet config and status registers. * These are in the "attribute" space. */ #define ECOR 0x8000 @@ -920,11 +966,10 @@ static const char * chip_ids[ 16 ] = { #define ECSR_PWRDWN 0x04 #define ECSR_INT 0x02 #define ATTRIB_SIZE ((64*1024) << SMC_IO_SHIFT) - /* * Macros to abstract register access according to the data bus * capabilities. Please use those and not the in/out primitives. * Note: the following macros do *not* select the bank -- this must * be done separately as needed in the main code. The SMC_REG() macro @@ -1087,10 +1132,27 @@ static const char * chip_ids[ 16 ] = { #define SMC_GET_TCR() SMC_inw(ioaddr, TCR_REG) #define SMC_SET_TCR(x) SMC_outw(x, ioaddr, TCR_REG) #ifndef SMC_GET_MAC_ADDR +#ifdef CONFIG_ARCH_NOMADIK +#define SMC_GET_MAC_ADDR(addr) \ + if (new_mac_addr[0] == 0xFF) { \ + printk("%s: Setting Random MAC addr\n", CARDNAME); \ + random_ether_addr(new_mac_addr); \ + } \ + SMC_SET_MAC_ADDR(new_mac_addr); \ + do { \ + unsigned int __v; \ + __v = SMC_inw( ioaddr, ADDR0_REG ); \ + addr[0] = __v; addr[1] = __v >> 8; \ + __v = SMC_inw( ioaddr, ADDR1_REG ); \ + addr[2] = __v; addr[3] = __v >> 8; \ + __v = SMC_inw( ioaddr, ADDR2_REG ); \ + addr[4] = __v; addr[5] = __v >> 8; \ + } while (0) +#else #define SMC_GET_MAC_ADDR(addr) \ do { \ unsigned int __v; \ __v = SMC_inw( ioaddr, ADDR0_REG ); \ addr[0] = __v; addr[1] = __v >> 8; \ @@ -1098,10 +1160,11 @@ static const char * chip_ids[ 16 ] = { addr[2] = __v; addr[3] = __v >> 8; \ __v = SMC_inw( ioaddr, ADDR2_REG ); \ addr[4] = __v; addr[5] = __v >> 8; \ } while (0) #endif +#endif #define SMC_SET_MAC_ADDR(addr) \ do { \ SMC_outw( addr[0]|(addr[1] << 8), ioaddr, ADDR0_REG ); \ SMC_outw( addr[2]|(addr[3] << 8), ioaddr, ADDR1_REG ); \ --- linux-2.6.20.orig/drivers/serial/amba-pl011.c +++ linux-2.6.20/drivers/serial/amba-pl011.c @@ -50,17 +50,36 @@ #include #include #include #include +#include +#include -#define UART_NR 14 +/* + * Definations here is used instead of this which is defined in platform.h + */ + +#ifndef UART_NR +#define UART_NR 14 /*default generic value */ +#endif + +#ifndef UART_FIFO_SIZE +#define UART_FIFO_SIZE 16 /*default generic value */ +#endif + +#ifndef UART_PER_ID +#define UART_PER_ID 0x00041011 /*default uart peripharal id */ +#endif + +#ifndef UART_PER_MASK +#define UART_PER_MASK 0x000fffff /*default uart peripharal mask */ +#endif #define SERIAL_AMBA_MAJOR 204 #define SERIAL_AMBA_MINOR 64 #define SERIAL_AMBA_NR UART_NR - #define AMBA_ISR_PASS_LIMIT 256 #define UART_DR_ERROR (UART011_DR_OE|UART011_DR_BE|UART011_DR_PE|UART011_DR_FE) #define UART_DUMMY_DR_RX (1 << 16) @@ -100,23 +119,31 @@ static void pl011_stop_rx(struct uart_po } static void pl011_enable_ms(struct uart_port *port) { struct uart_amba_port *uap = (struct uart_amba_port *)port; + unsigned cr; - uap->im |= UART011_RIMIM|UART011_CTSMIM|UART011_DCDMIM|UART011_DSRMIM; + uap->im |= + UART011_RIMIM | UART011_CTSMIM | UART011_DCDMIM | UART011_DSRMIM; writew(uap->im, uap->port.membase + UART011_IMSC); + + cr = readw(uap->port.membase + UART011_CR); + barrier(); + cr = cr | UART_CONTROL_MASK_CTSFLOW | UART_CONTROL_MASK_RTSFLOW; + writew(cr, uap->port.membase + UART011_CR); } static void pl011_rx_chars(struct uart_amba_port *uap) { struct tty_struct *tty = uap->port.info->tty; unsigned int status, ch, flag, max_count = 256; status = readw(uap->port.membase + UART01x_FR); while ((status & UART01x_FR_RXFE) == 0 && max_count--) { ch = readw(uap->port.membase + UART01x_DR) | UART_DUMMY_DR_RX; + flag = TTY_NORMAL; uap->port.icount.rx++; /* * Note that the error handling code is @@ -172,11 +199,13 @@ static void pl011_tx_chars(struct uart_a pl011_stop_tx(&uap->port); return; } count = uap->port.fifosize >> 1; + do { + writew(xmit->buf[xmit->tail], uap->port.membase + UART01x_DR); xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); uap->port.icount.tx++; if (uart_circ_empty(xmit)) break; @@ -316,10 +345,11 @@ static void pl011_break_ctl(struct uart_ static int pl011_startup(struct uart_port *port) { struct uart_amba_port *uap = (struct uart_amba_port *)port; unsigned int cr; int retval; + int status, ch; /* * Try to enable the clock producer. */ retval = clk_enable(uap->clk); @@ -329,36 +359,54 @@ static int pl011_startup(struct uart_por uap->port.uartclk = clk_get_rate(uap->clk); /* * Allocate the IRQ */ - retval = request_irq(uap->port.irq, pl011_int, 0, "uart-pl011", uap); + retval = + request_irq(uap->port.irq, pl011_int, SA_SHIRQ, "uart-pl011", uap); if (retval) goto clk_dis; - writew(UART011_IFLS_RX4_8|UART011_IFLS_TX4_8, - uap->port.membase + UART011_IFLS); + /* + *writew(UART011_IFLS_RX4_8|UART011_IFLS_TX4_8, + *uap->port.membase + UART011_IFLS); + */ + + writew(UART_TX_RX_HALF, uap->port.membase + UART011_IFLS); + /* Clearing interrupts */ + writew(0x7ff, uap->port.membase + UART011_ICR); /* * Provoke TX FIFO interrupt into asserting. */ cr = UART01x_CR_UARTEN | UART011_CR_TXE | UART011_CR_LBE; writew(cr, uap->port.membase + UART011_CR); writew(0, uap->port.membase + UART011_FBRD); writew(1, uap->port.membase + UART011_IBRD); writew(0, uap->port.membase + UART011_LCRH); - writew(0, uap->port.membase + UART01x_DR); + writew('Z', uap->port.membase + UART01x_DR); + + barrier(); + ch = readw(uap->port.membase + UART01x_DR); + while (readw(uap->port.membase + UART01x_FR) & UART01x_FR_BUSY) barrier(); cr = UART01x_CR_UARTEN | UART011_CR_RXE | UART011_CR_TXE; writew(cr, uap->port.membase + UART011_CR); /* * initialise the old status of the modem signals */ - uap->old_status = readw(uap->port.membase + UART01x_FR) & UART01x_FR_MODEM_ANY; + uap->old_status = + readw(uap->port.membase + UART01x_FR) & UART01x_FR_MODEM_ANY; + + status = readw(uap->port.membase + UART01x_FR); + while ((status & UART01x_FR_RXFE) == 0) { + ch = readw(uap->port.membase + UART01x_DR); + status = readw(uap->port.membase + UART01x_FR); + } /* * Finally, enable interrupts */ spin_lock_irq(&uap->port.lock); @@ -394,11 +442,12 @@ static void pl011_shutdown(struct uart_p free_irq(uap->port.irq, uap); /* * disable the port */ - writew(UART01x_CR_UARTEN | UART011_CR_TXE, uap->port.membase + UART011_CR); + writew(UART01x_CR_UARTEN | UART011_CR_TXE, + uap->port.membase + UART011_CR); /* * disable break condition and fifos */ val = readw(uap->port.membase + UART011_LCRH); @@ -656,10 +705,11 @@ static int __init pl011_console_setup(st /* * Check whether an invalid uart number has been specified, and * if so, search for the first available port that does have * console support. */ + if (co->index >= UART_NR) co->index = 0; uap = amba_ports[co->index]; if (!uap) return -ENODEV; @@ -698,10 +748,32 @@ static struct uart_driver amba_reg = { .minor = SERIAL_AMBA_MINOR, .nr = UART_NR, .cons = AMBA_CONSOLE, }; +#ifdef CONFIG_PM +static int pl011_suspend(struct amba_device *dev, pm_message_t state) +{ + struct uart_amba_port *uap = amba_get_drvdata(dev); + + if (uap) + uart_suspend_port(&amba_reg, &uap->port); + + return 0; +} + +static int pl011_resume(struct amba_device *dev) +{ + struct uart_amba_port *uap = amba_get_drvdata(dev); + + if (uap) + uart_resume_port(&amba_reg, &uap->port); + + return 0; +} +#endif + static int pl011_probe(struct amba_device *dev, void *id) { struct uart_amba_port *uap; void __iomem *base; int i, ret; @@ -737,13 +809,14 @@ static int pl011_probe(struct amba_devic uap->port.dev = &dev->dev; uap->port.mapbase = dev->res.start; uap->port.membase = base; uap->port.iotype = UPIO_MEM; uap->port.irq = dev->irq[0]; - uap->port.fifosize = 16; + uap->port.fifosize = UART_FIFO_SIZE; uap->port.ops = &amba_pl011_pops; uap->port.flags = UPF_BOOT_AUTOCONF; + uap->port.line = i; amba_ports[i] = uap; amba_set_drvdata(dev, uap); @@ -780,12 +853,12 @@ static int pl011_remove(struct amba_devi return 0; } static struct amba_id pl011_ids[] __initdata = { { - .id = 0x00041011, - .mask = 0x000fffff, + .id = UART_PER_ID, + .mask = UART_PER_MASK, }, { 0, 0 }, }; static struct amba_driver pl011_driver = { @@ -793,10 +866,14 @@ static struct amba_driver pl011_driver = .name = "uart-pl011", }, .id_table = pl011_ids, .probe = pl011_probe, .remove = pl011_remove, +#ifdef CONFIG_PM + .suspend = pl011_suspend, + .resume = pl011_resume, +#endif }; static int __init pl011_init(void) { int ret; --- linux-2.6.20.orig/drivers/spi/Kconfig +++ linux-2.6.20/drivers/spi/Kconfig @@ -63,10 +63,18 @@ config SPI_BITBANG This is library code, and is automatically selected by drivers that need it. You only need to select this explicitly to support driver modules that aren't part of this kernel tree. +config NOMADIK_SPI + tristate "Nomadik SPI master" + depends on SPI_MASTER && EXPERIMENTAL + default y + help + This enables using the Nomadik SPI controller in master + mode. + config SPI_BUTTERFLY tristate "Parallel port adapter for AVR Butterfly (DEVELOPMENT)" depends on SPI_MASTER && PARPORT && EXPERIMENTAL select SPI_BITBANG help --- linux-2.6.20.orig/drivers/spi/Makefile +++ linux-2.6.20/drivers/spi/Makefile @@ -10,10 +10,12 @@ endif # config declarations into driver model code obj-$(CONFIG_SPI_MASTER) += spi.o # SPI master controller drivers (bus) obj-$(CONFIG_SPI_BITBANG) += spi_bitbang.o +obj-$(CONFIG_NOMADIK_SPI) += nmdkmod_spi.o +nmdkmod_spi-objs := spi-nomadik.o obj-$(CONFIG_SPI_BUTTERFLY) += spi_butterfly.o obj-$(CONFIG_SPI_PXA2XX) += pxa2xx_spi.o obj-$(CONFIG_SPI_MPC83xx) += spi_mpc83xx.o obj-$(CONFIG_SPI_S3C24XX_GPIO) += spi_s3c24xx_gpio.o obj-$(CONFIG_SPI_S3C24XX) += spi_s3c24xx.o --- /dev/null +++ linux-2.6.20/drivers/spi/spi-nomadik.c @@ -0,0 +1,1000 @@ +/* + * drivers/spi/spi-nomadik.c + * + * Copyright (C) 2006 STMicroelectronics Pvt. Ltd. + * + * Author: Sachin Verma + * Vaibhav Agarwal +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +/***************************************************************************/ + +#define NMDK_SPI_NAME "NOMADIK_SPI" + +#ifndef SPI_DEBUG +#define SPI_DEBUG 0 +#endif + +#define NMDK_DEBUG SPI_DEBUG /* enables/disables nmdk_dbg msgs */ +#define NMDK_DEBUG_PFX NMDK_SPI_NAME /* msg header represents this module */ +#define NMDK_DBG KERN_ERR /* message level */ + +/***************************************************************************/ + +#define FALSE (0) +#define TRUE (1) + +#define DO_NOT_QUEUE_DMA (0) +#define QUEUE_DMA (1) + +/*####################################################################### + Queue State +######################################################################### + */ +#define QUEUE_RUNNING (0) +#define QUEUE_STOPPED (1) + +/***************************************************************************/ +static void print_dma_info(u32 xfer_type, struct chip_data *chip){ + nmdk_dbg("Rx Pipe : mode = %08x\n", chip->dma_info->rx_dma_info.mode); + nmdk_dbg("Rx Pipe : config = %08x\n", chip->dma_info->rx_dma_info.config); + nmdk_dbg("Rx Pipe : srcdevtype = %s\n", chip->dma_info->rx_dma_info.srcdevtype); + nmdk_dbg("Rx Pipe : destdevtype = %s\n", chip->dma_info->rx_dma_info.destdevtype); + + nmdk_dbg("Tx Pipe : mode = %08x\n", chip->dma_info->tx_dma_info.mode); + nmdk_dbg("Tx Pipe : config = %08x\n", chip->dma_info->tx_dma_info.config); + nmdk_dbg("Tx Pipe : srcdevtype = %s\n", chip->dma_info->tx_dma_info.srcdevtype); + nmdk_dbg("Tx Pipe : destdevtype = %s\n", chip->dma_info->tx_dma_info.destdevtype); +} +/***************************************************************************/ + +/** + * null_cs_control - Dummy chip select function + * @command: select/delect the chip + * + * If no chip select function is provided by client this is used as dummy + * chip select + */ +void null_cs_control(u32 command) +{ + nmdk_dbg_ftrace(); + nmdk_dbg("::::Dummy chip select control\n"); +} +EXPORT_SYMBOL(null_cs_control); + +void nomadik_spi_tasklet(unsigned long param) +{ + struct driver_data *drv_data = (struct driver_data *)param; + struct spi_message *msg = drv_data->cur_msg; + struct spi_transfer *previous = NULL; + /*DMA complete. schedule next xfer */ + /*DISABLE DMA, and flush FIFO of SPI Controller */ + drv_data->execute_cmd(drv_data, DISABLE_DMA); + drv_data->execute_cmd(drv_data, FLUSH_FIFO); + msg->actual_length += drv_data->cur_transfer->len; + if (drv_data->cur_transfer->cs_change) + drv_data->cur_chip->cs_control(SPI_CHIP_DESELECT); + msg->state = next_transfer(drv_data); + if (msg->state == ERROR_STATE) + goto handle_dma_error; + else if (msg->state == DONE_STATE) { + drv_data->execute_cmd(drv_data, DISABLE_CONTROLLER); + msg->status = 0; + giveback(msg, drv_data); + return ; + } + /* Delay if requested at end of transfer */ + else if (msg->state == RUNNING_STATE) { + previous = + list_entry(drv_data->cur_transfer->transfer_list. + prev, struct spi_transfer, + transfer_list); + if (previous->delay_usecs) + udelay(previous->delay_usecs); + if (previous->cs_change) + drv_data->cur_chip->cs_control(SPI_CHIP_SELECT); + } else goto handle_dma_error; + + if (drv_data->cur_transfer->tx_dma) { + atomic_inc(&drv_data->dma_cnt); + __set_dma_srcaddr(drv_data->cur_chip->dma_info->tx_dmach, (dma_addr_t) (drv_data->cur_transfer->tx_dma)); + __set_dma_destaddr(drv_data->cur_chip->dma_info->tx_dmach, + (dma_addr_t) (drv_data->master_info->dma_srcaddr)); + set_dma_count(drv_data->cur_chip->dma_info->tx_dmach, (drv_data->cur_transfer->len)); + enable_dma(drv_data->cur_chip->dma_info->tx_dmach); + } + if (drv_data->cur_transfer->rx_dma) { + atomic_inc(&drv_data->dma_cnt); + __set_dma_srcaddr(drv_data->cur_chip->dma_info->rx_dmach, + (dma_addr_t) (drv_data->master_info->dma_destaddr)); + __set_dma_destaddr(drv_data->cur_chip->dma_info->rx_dmach, (dma_addr_t) (drv_data->cur_transfer->rx_dma)); + set_dma_count(drv_data->cur_chip->dma_info->rx_dmach, (drv_data->cur_transfer->len)); + enable_dma(drv_data->cur_chip->dma_info->rx_dmach); + } + /*Enable DMA for this chip */ + drv_data->execute_cmd(drv_data, ENABLE_DMA); + return ; + + handle_dma_error: + atomic_set(&drv_data->dma_cnt, 0); + drv_data->execute_cmd(drv_data, DISABLE_DMA); + msg->status = -EIO; + giveback(msg, drv_data); + return ; +} +EXPORT_SYMBOL(nomadik_spi_tasklet); + +/** + * spi_dma_callback_handler - This function is invoked when dma xfer is complete + * @param: context data which is drivers private data + * @event: Status of current DMA transfer + * + * This function checks if DMA transfer is complete for current transfer + * It fills the Rx Tx buffer pointers again and launch dma for next + * transfer from this callback handler itself + * + */ +irqreturn_t spi_dma_callback_handler(int irq, void *param) +{ + struct driver_data *drv_data = (struct driver_data *)param; + int flag = 0; + + nmdk_dbg_ftrace(); + + smp_mb(); + if (atomic_dec_and_test(&drv_data->dma_cnt)) { + flag = 1; + } + smp_mb(); + if (flag == 1) { + tasklet_schedule(&drv_data->spi_dma_tasklet); + } + return IRQ_HANDLED; +} +EXPORT_SYMBOL(spi_dma_callback_handler); + +/** + * giveback - current spi_message is over, schedule next spi_message and call callback of this msg + * @message: current SPI message + * @drv_data: spi driver private data structure + * + */ +void giveback(struct spi_message *message, struct driver_data *drv_data) +{ + struct spi_transfer *last_transfer; + unsigned long flags; + struct spi_message *msg; + void (*curr_cs_control) (u32 command); + + spin_lock_irqsave(&drv_data->lock, flags); + msg = drv_data->cur_msg; + + curr_cs_control = drv_data->cur_chip->cs_control; + drv_data->cur_msg = NULL; + drv_data->cur_transfer = NULL; + drv_data->cur_chip = NULL; +#ifdef SPI_WORKQUEUE + queue_work(drv_data->workqueue, &drv_data->spi_work); +#endif + spin_unlock_irqrestore(&drv_data->lock, flags); + + schedule_work(&drv_data->spi_work); + + last_transfer = list_entry(msg->transfers.prev, + struct spi_transfer, transfer_list); + if (!last_transfer->cs_change) + curr_cs_control(SPI_CHIP_DESELECT); + msg->state = NULL; + if (msg->complete) + msg->complete(msg->context); + drv_data->execute_cmd(drv_data, DISABLE_CONTROLLER); +} +EXPORT_SYMBOL(giveback); + +/** + * next_transfer - Move to the Next transfer in the current spi message + * @drv_data: spi driver private data structure + * + * This function moves though the linked list of spi transfers in the + * current spi message and returns with the state of current spi + * message i.e whether its last transfer is done(DONE_STATE) or + * Next transfer is ready(RUNNING_STATE) + */ +void *next_transfer(struct driver_data *drv_data) +{ + struct spi_message *msg = drv_data->cur_msg; + struct spi_transfer *trans = drv_data->cur_transfer; + /* Move to next transfer */ + if (trans->transfer_list.next != &msg->transfers) { + drv_data->cur_transfer = + list_entry(trans->transfer_list.next, + struct spi_transfer, transfer_list); + return RUNNING_STATE; + } + return DONE_STATE; +} +EXPORT_SYMBOL(next_transfer); + +/** + * ssp_null_writer - To Write Dummy Data in Data register + * @drv_data: spi driver private data structure + * + * This function is set as a write function for transfer which have + * Tx transfer buffer as NULL. It simply writes '0' in the Data + * register + */ +static void ssp_null_writer(struct driver_data *drv_data) +{ + while ((readl(SSP_SR(drv_data->regs)) & SSP_SR_MASK_TNF) + && (drv_data->tx < drv_data->tx_end)) { + /*Write '0' Data to Data Register */ + writel(0x0, SSP_DR(drv_data->regs)); + drv_data->tx += (drv_data->cur_chip->n_bytes); + } +} + +/** + * ssp_null_reader - To read data from Data register and discard it + * @drv_data: spi driver private data structure + * + * This function is set as a reader function for transfer which have + * Rx Transfer buffer as null. Read Data is rejected + * + */ +static void ssp_null_reader(struct driver_data *drv_data) +{ + while ((readl(SSP_SR(drv_data->regs)) & SSP_SR_MASK_RNE) + && (drv_data->rx < drv_data->rx_end)) { + readl(SSP_DR(drv_data->regs)); + drv_data->rx += (drv_data->cur_chip->n_bytes); + } +} + +/** + * msp_null_writer - To Write Dummy Data in Data register + * @drv_data: spi driver private data structure + * + * This function is set as a write function for transfer which have + * Tx transfer buffer as NULL. It simply writes '0' in the Data + * register + */ +static void msp_null_writer(struct driver_data *drv_data) +{ + u32 cur_write = 0; + u32 status; + while(1){ + status = readl(MSP_FLR(drv_data->regs)); + if((status & MSP_FLR_MASK_TFU) || (drv_data->tx >= drv_data->tx_end)) + return; + writel( 0x0, MSP_DR(drv_data->regs)); + drv_data->tx += (drv_data->cur_chip->n_bytes); + cur_write ++; + if(cur_write == 8) + return; + } +} + +/** + * msp_null_reader - To read data from Data register and discard it + * @drv_data: spi driver private data structure + * + * This function is set as a reader function for transfer which have + * Rx Transfer buffer as null. Read Data is rejected + * + */ +static void msp_null_reader(struct driver_data *drv_data) +{ + u32 status; + while(1){ + status = readl(MSP_FLR(drv_data->regs)); + if( (status & MSP_FLR_MASK_RFE) || ( drv_data->rx >= drv_data->rx_end)) + return; + readl(MSP_DR(drv_data->regs)); + drv_data->rx += (drv_data->cur_chip->n_bytes); + } +} + +/** + * pump_transfers - Tasklet function which schedules next interrupt xfer + * @data: spi driver private data structure + * + */ +static void pump_transfers(unsigned long data) +{ + struct driver_data *drv_data = (struct driver_data *)data; + struct spi_message *message = NULL; + struct spi_transfer *transfer = NULL; + struct spi_transfer *previous = NULL; + + nmdk_dbg_ftrace(); + + message = drv_data->cur_msg; + /* Handle for abort */ + if (message->state == ERROR_STATE) { + message->status = -EIO; + giveback(message, drv_data); + return; + } + /* Handle end of message */ + if (message->state == DONE_STATE) { + message->status = 0; + giveback(message, drv_data); + return; + } + transfer = drv_data->cur_transfer; + /* Delay if requested at end of transfer */ + if (message->state == RUNNING_STATE) { + previous = + list_entry(transfer->transfer_list.prev, + struct spi_transfer, transfer_list); + if (previous->delay_usecs) + udelay(previous->delay_usecs); + if (previous->cs_change) + drv_data->cur_chip->cs_control(SPI_CHIP_SELECT); + } else { + /* START_STATE */ + message->state = RUNNING_STATE; + } + drv_data->tx = (void *)transfer->tx_buf; + drv_data->tx_end = drv_data->tx + drv_data->cur_transfer->len; + drv_data->rx = (void *)transfer->rx_buf; + drv_data->rx_end = drv_data->rx + drv_data->cur_transfer->len; + + if(drv_data->master->bus_num == SSP_CONTROLLER){ + drv_data->write = drv_data->tx ? drv_data->cur_chip->write : ssp_null_writer; + drv_data->read = drv_data->rx ? drv_data->cur_chip->read : ssp_null_reader; + } + else{ + drv_data->write = drv_data->tx ? drv_data->cur_chip->write : msp_null_writer; + drv_data->read = drv_data->rx ? drv_data->cur_chip->read : msp_null_reader; + } + + drv_data->execute_cmd(drv_data, FLUSH_FIFO); + drv_data->execute_cmd(drv_data, ENABLE_ALL_INTERRUPT); +} + +/** + * do_dma_transfer - It handles transfers of the current message if it is DMA xfer + * @data: spi driver's private data structure + * + * + * + */ +static void do_dma_transfer(void *data) +{ + struct driver_data *drv_data = (struct driver_data *)data; + + atomic_set(&drv_data->dma_cnt, 0); + drv_data->cur_chip->cs_control(SPI_CHIP_SELECT); + + if ((drv_data->cur_chip->dma_info->dma_xfer_type == SPI_WITH_MEM) || + (drv_data->cur_chip->dma_info->dma_xfer_type == SPI_WITH_PERIPH)) { + if (drv_data->cur_chip->dma_info->tx_dmach >= 0) { + atomic_inc(&drv_data->dma_cnt); + __set_dma_srcaddr(drv_data->cur_chip->dma_info->tx_dmach, + (dma_addr_t) (drv_data->cur_transfer->tx_dma)); + __set_dma_destaddr(drv_data->cur_chip->dma_info->tx_dmach, + (dma_addr_t) (drv_data->master_info->dma_srcaddr)); + set_dma_count(drv_data->cur_chip->dma_info->tx_dmach, + (drv_data->cur_transfer->len)); + enable_dma(drv_data->cur_chip->dma_info->tx_dmach); + } + if (drv_data->cur_chip->dma_info->rx_dmach >= 0) { + atomic_inc(&drv_data->dma_cnt); + __set_dma_srcaddr(drv_data->cur_chip->dma_info->rx_dmach, + (dma_addr_t) (drv_data->master_info->dma_destaddr)); + __set_dma_destaddr(drv_data->cur_chip->dma_info->rx_dmach, + (dma_addr_t) (drv_data->cur_transfer->rx_dma)); + set_dma_count(drv_data->cur_chip->dma_info->rx_dmach, + (drv_data->cur_transfer->len)); + enable_dma(drv_data->cur_chip->dma_info->rx_dmach); + } + if((drv_data->cur_chip->dma_info->tx_dma_info.mode & DMA_INFINITE_XFER) && + (drv_data->cur_chip->dma_info->rx_dma_info.mode & DMA_INFINITE_XFER)){ + /*Only if it is an infinite transfer, we will deploy mechanism to stop it*/ + nmdk_dbg("Only if it is an infinite transfer, we will deploy mechanism to stop it"); + drv_data->dma_ongoing = 1; + } + } else { + nmdk_dbg(":::: Invalid DMA xfer type \n"); + goto err_dma_transfer; + } + /*Enable SPI Controller */ + drv_data->execute_cmd(drv_data, ENABLE_CONTROLLER); + return; + + err_dma_transfer: + drv_data->cur_msg->state = ERROR_STATE; + drv_data->cur_msg->status = -EIO; + giveback(drv_data->cur_msg, drv_data); + return; +} + +static void do_interrupt_transfer(void *data) +{ + struct driver_data *drv_data = (struct driver_data *)data; + + drv_data->tx = (void *)drv_data->cur_transfer->tx_buf; + drv_data->tx_end = drv_data->tx + drv_data->cur_transfer->len; + drv_data->rx = (void *)drv_data->cur_transfer->rx_buf; + drv_data->rx_end = drv_data->rx + drv_data->cur_transfer->len; + + if(drv_data->master->bus_num == SSP_CONTROLLER){ + drv_data->write = drv_data->tx ? drv_data->cur_chip->write : ssp_null_writer; + drv_data->read = drv_data->rx ? drv_data->cur_chip->read : ssp_null_reader; + } + else{ + drv_data->write = drv_data->tx ? drv_data->cur_chip->write : msp_null_writer; + drv_data->read = drv_data->rx ? drv_data->cur_chip->read : msp_null_reader; + } + + drv_data->cur_chip->cs_control(SPI_CHIP_SELECT); + + drv_data->execute_cmd(drv_data, ENABLE_ALL_INTERRUPT); + drv_data->execute_cmd(drv_data, ENABLE_CONTROLLER); +} + +static void do_polling_transfer(void *data) +{ + struct driver_data *drv_data = (struct driver_data *)data; + struct spi_message *message = NULL; + struct spi_transfer *transfer = NULL; + struct spi_transfer *previous = NULL; + struct chip_data *chip; + unsigned long limit = 0; + + chip = drv_data->cur_chip; + message = drv_data->cur_msg; + + while (message->state != DONE_STATE) { + /* Handle for abort */ + if (message->state == ERROR_STATE) + break; + transfer = drv_data->cur_transfer; + + /* Delay if requested at end of transfer */ + if (message->state == RUNNING_STATE) { + previous = + list_entry(transfer->transfer_list.prev, + struct spi_transfer, transfer_list); + if (previous->delay_usecs) + udelay(previous->delay_usecs); + if (previous->cs_change) + drv_data->cur_chip->cs_control(SPI_CHIP_SELECT); + } else { + /* START_STATE */ + message->state = RUNNING_STATE; + drv_data->cur_chip->cs_control(SPI_CHIP_SELECT); + } + + /*Configuration Changing Per Transfer */ + drv_data->tx = (void *)transfer->tx_buf; + drv_data->tx_end = drv_data->tx + drv_data->cur_transfer->len; + drv_data->rx = (void *)transfer->rx_buf; + drv_data->rx_end = drv_data->rx + drv_data->cur_transfer->len; + + if(drv_data->master->bus_num == SSP_CONTROLLER){ + drv_data->write = drv_data->tx ? drv_data->cur_chip->write : ssp_null_writer; + drv_data->read = drv_data->rx ? drv_data->cur_chip->read : ssp_null_reader; + } + else{ + drv_data->write = drv_data->tx ? drv_data->cur_chip->write : msp_null_writer; + drv_data->read = drv_data->rx ? drv_data->cur_chip->read : msp_null_reader; + } + + drv_data->execute_cmd(drv_data, FLUSH_FIFO); + drv_data->execute_cmd(drv_data, ENABLE_CONTROLLER); + + nmdk_dbg(":::: POLLING TRANSFER ONGOING ... \n"); + while (drv_data->tx < drv_data->tx_end) { + drv_data->read(drv_data); + drv_data->write(drv_data); + } + + limit = loops_per_jiffy << 1; + + while ((drv_data->rx < drv_data->rx_end) && (limit--)){ + drv_data->read(drv_data); + } + + /* Update total byte transfered */ + message->actual_length += drv_data->cur_transfer->len; + if (drv_data->cur_transfer->cs_change) + drv_data->cur_chip->cs_control(SPI_CHIP_DESELECT); + drv_data->execute_cmd(drv_data, DISABLE_CONTROLLER); + + /* Move to next transfer */ + message->state = next_transfer(drv_data); + } + + /* Handle end of message */ + if (message->state == DONE_STATE) + message->status = 0; + else + message->status = -EIO; + + giveback(message, drv_data); + return; +} +/** + * pump_messages - Workqueue function which processes spi message queue + * @data: pointer to private data of spi driver + * + * This function checks if there is any spi message in the queue that + * needs processing and delegate control to appropriate function + * do_polling_transfer()/do_interrupt_transfer()/do_dma_transfer() + * based on the kind of the transfer + * + */ +static void pump_messages(struct work_struct *work) +{ + struct driver_data *drv_data = container_of(work, struct driver_data,spi_work); + unsigned long flags; + + /* Lock queue and check for queue work */ + spin_lock_irqsave(&drv_data->lock, flags); + if (list_empty(&drv_data->queue) || drv_data->run == QUEUE_STOPPED) { + nmdk_dbg(":::: work_queue: Queue Empty\n"); + drv_data->busy = 0; + spin_unlock_irqrestore(&drv_data->lock, flags); + return; + } + /* Make sure we are not already running a message */ + if (drv_data->cur_msg) { + spin_unlock_irqrestore(&drv_data->lock, flags); + return; + } + + /* Extract head of queue */ + drv_data->cur_msg = + list_entry(drv_data->queue.next, struct spi_message, queue); + + list_del_init(&drv_data->cur_msg->queue); + drv_data->busy = 1; + spin_unlock_irqrestore(&drv_data->lock, flags); + + /* Initial message state */ + drv_data->cur_msg->state = START_STATE; + drv_data->cur_transfer = list_entry(drv_data->cur_msg->transfers.next, + struct spi_transfer, transfer_list); + + /* Setup the SPI using the per chip configuration */ + drv_data->cur_chip = spi_get_ctldata(drv_data->cur_msg->spi); + drv_data->execute_cmd(drv_data, RESTORE_STATE); + drv_data->execute_cmd(drv_data, FLUSH_FIFO); + + if (drv_data->cur_chip->xfer_type == POLLING_TRANSFER) + do_polling_transfer(drv_data); + else if (drv_data->cur_chip->xfer_type == INTERRUPT_TRANSFER) + do_interrupt_transfer(drv_data); + else /* DMA_TRANSFER*/ + do_dma_transfer(drv_data); +} + +int init_queue(struct driver_data *drv_data) +{ + INIT_LIST_HEAD(&drv_data->queue); + spin_lock_init(&drv_data->lock); + + drv_data->run = QUEUE_STOPPED; + drv_data->busy = 0; + + tasklet_init(&drv_data->pump_transfers, pump_transfers, + (unsigned long)drv_data); + INIT_WORK(&drv_data->spi_work, pump_messages); +#ifdef SPI_WORKQUEUE + drv_data->workqueue = create_singlethread_workqueue(drv_data->master->cdev.dev->bus_id); + if (drv_data->workqueue == NULL) + return -EBUSY; +#endif + return 0; +} +EXPORT_SYMBOL(init_queue); + +int start_queue(struct driver_data *drv_data) +{ + unsigned long flags; + spin_lock_irqsave(&drv_data->lock, flags); + if (drv_data->run == QUEUE_RUNNING || drv_data->busy) { + spin_unlock_irqrestore(&drv_data->lock, flags); + return -EBUSY; + } + drv_data->run = QUEUE_RUNNING; + drv_data->cur_msg = NULL; + drv_data->cur_transfer = NULL; + drv_data->cur_chip = NULL; + spin_unlock_irqrestore(&drv_data->lock, flags); + /*queue_work(drv_data->workqueue, &drv_data->pump_messages);*/ + /*schedule_work(&drv_data->spi_work);*/ + return 0; +} +EXPORT_SYMBOL(start_queue); + +int stop_queue(struct driver_data *drv_data) +{ + unsigned long flags; + unsigned limit = 500; + int status = 0; + + spin_lock_irqsave(&drv_data->lock, flags); + + /* This is a bit lame, but is optimized for the common execution path. + * A wait_queue on the drv_data->busy could be used, but then the common + * execution path (pump_messages) would be required to call wake_up or + * friends on every SPI message. Do this instead */ + drv_data->run = QUEUE_STOPPED; + while (!list_empty(&drv_data->queue) && drv_data->busy && limit--) { + spin_unlock_irqrestore(&drv_data->lock, flags); + msleep(10); + spin_lock_irqsave(&drv_data->lock, flags); + } + if (!list_empty(&drv_data->queue) || drv_data->busy) + status = -EBUSY; + + spin_unlock_irqrestore(&drv_data->lock, flags); + + return status; +} +EXPORT_SYMBOL(stop_queue); + +int destroy_queue(struct driver_data *drv_data) +{ + int status; + status = stop_queue(drv_data); + if (status != 0) + return status; +#ifdef SPI_WORKQUEUE + destroy_workqueue(drv_data->workqueue); +#endif + return 0; +} +EXPORT_SYMBOL(destroy_queue); + +/** + * nomadik_spi_transfer - transfer function registered to SPI master framework + * @spi: spi device which is requesting transfer + * @msg: spi message which is to handled is queued to driver queue + * + * This function is registered to the SPI framework for this SPI master + * controller. It will queue the spi_message in the queue of driver if + * the queue is not stopped and return. + */ +int nomadik_spi_transfer(struct spi_device *spi, struct spi_message *msg) +{ + struct driver_data *drv_data = spi_master_get_devdata(spi->master); + unsigned long flags; + +#if (defined(CONFIG_NOMADIK_MSP) || defined(CONFIG_NOMADIK_MSP_MODULE)) + struct spi_master *master; + int status = 0; +#endif + + nmdk_dbg_ftrace(); + +#if (defined(CONFIG_NOMADIK_MSP) || defined(CONFIG_NOMADIK_MSP_MODULE)) + master = drv_data->master; + switch(master->bus_num) { + case MSP_0_CONTROLLER: if(drv_data->flag_msp0->user != SPI_USER_MSP) { + status = -EINVAL; + printk("MSP0 already in use in %d mode", drv_data->flag_msp0->user); + } + break; + case MSP_1_CONTROLLER: if(drv_data->flag_msp1->user != SPI_USER_MSP) { + status = -EINVAL; + printk("MSP1 already in use in %d mode", drv_data->flag_msp1->user); + } + break; + case MSP_2_CONTROLLER: if(drv_data->flag_msp2->user != SPI_USER_MSP) { + status = -EINVAL; + printk("MSP2 already in use in %d mode", drv_data->flag_msp2->user); + } + break; + } + if(status) + return status; +#endif + spin_lock_irqsave(&drv_data->lock, flags); + + + if (drv_data->run == QUEUE_STOPPED) { + spin_unlock_irqrestore(&drv_data->lock, flags); + return -ESHUTDOWN; + } + if(drv_data->dma_ongoing){ + struct chip_data *chip; + chip = spi_get_ctldata(spi); + nmdk_dbg(":::: Current chip(%p), Chip Id Requesting New Xfer: %d\n", drv_data->cur_chip, chip->chip_id); + nmdk_dbg(":::: Current chip Id (doing infinite DMA): %d -- Chip Id Requesting New Xfer: %d\n", drv_data->cur_chip->chip_id, chip->chip_id); + if(drv_data->cur_chip->chip_id != chip->chip_id){ + nmdk_dbg(":::: Chip_id are not same, Hence current DMA xfer not disabled \n"); + } + else{ + nmdk_dbg(":::: Chip_id are same. Disabling current infinite DMA xfer\n"); + + drv_data->dma_ongoing = 0; + + if (drv_data->cur_chip->dma_info->tx_dmach != -1) { + free_dma(drv_data->cur_chip->dma_info->tx_dmach); + drv_data->cur_chip->dma_info->tx_dmach = -1; + } + if (drv_data->cur_chip->dma_info->rx_dmach != -1) { + free_dma(drv_data->cur_chip->dma_info->rx_dmach); + drv_data->cur_chip->dma_info->rx_dmach = -1; + } + drv_data->execute_cmd(drv_data, DISABLE_DMA); + drv_data->execute_cmd(drv_data, DISABLE_CONTROLLER); + drv_data->cur_msg = NULL; + drv_data->cur_transfer = NULL; + drv_data->cur_chip = NULL; +#ifdef SPI_WORKQUEUE + queue_work(drv_data->workqueue, &drv_data->spi_work); +#else + schedule_work(&drv_data->spi_work); +#endif + } + spin_unlock_irqrestore(&drv_data->lock, flags); + return 0; + } + + nmdk_dbg(":::: Regular request (No infinite DMA ongoing)\n"); + + msg->actual_length = 0; + msg->status = -EINPROGRESS; + msg->state = START_STATE; + + list_add_tail(&msg->queue, &drv_data->queue); + if (drv_data->run == QUEUE_RUNNING && !drv_data->busy) +#ifdef SPI_WORKQUEUE + queue_work(drv_data->workqueue, &drv_data->spi_work); +#else + schedule_work(&drv_data->spi_work); +#endif + + spin_unlock_irqrestore(&drv_data->lock, flags); + return 0; +} +EXPORT_SYMBOL(nomadik_spi_transfer); + +int calculate_effective_freq(int freq, t_ssp_clock_params * clk_freq) +{ + /*Lets calculate the frequency parameters */ + uint32 cpsdvsr = 2; + uint32 scr = 0; + bool_t freq_found = FALSE; + uint32 max_tclk; + uint32 min_tclk; + + nmdk_dbg_ftrace(); + + max_tclk = (NMDK_SSP_CLOCK_FREQ / (MIN_CPSDVR * (1 + MIN_SCR))); /* cpsdvscr = 2 & scr 0 */ + min_tclk = (NMDK_SSP_CLOCK_FREQ / (MAX_CPSDVR * (1 + MAX_SCR))); /* cpsdvsr = 254 & scr = 255 */ + + if ((freq <= max_tclk) && (freq >= min_tclk)) { + while (cpsdvsr <= MAX_CPSDVR && !freq_found) { + while (scr <= MAX_SCR && !freq_found) { + if ((NMDK_SSP_CLOCK_FREQ / + (cpsdvsr * (1 + scr))) > freq) + scr += 1; + else { + /* This bool is made TRUE when effective frequency >= target frequency is found */ + freq_found = TRUE; + if ((NMDK_SSP_CLOCK_FREQ / + (cpsdvsr * (1 + scr))) != freq) { + if (scr == MIN_SCR) { + cpsdvsr -= 2; + scr = MAX_SCR; + } else + scr -= 1; + } + } + } + if (!freq_found) { + cpsdvsr += 2; + scr = MIN_SCR; + } + } + if (cpsdvsr != 0) { + nmdk_dbg(":::: SSP Effective Frequency is %ld\n", (NMDK_SSP_CLOCK_FREQ / (cpsdvsr * (1 + scr)))); + clk_freq->cpsdvsr = (uint8) (cpsdvsr & 0xFF); + clk_freq->scr = (uint8) (scr & 0xFF); + nmdk_dbg(":::: SSP cpsdvsr = %d, scr = %d\n", + clk_freq->cpsdvsr, clk_freq->scr); + } + } else { + /*User is asking for out of range Freq. */ + nmdk_dbg(":::: setup - controller data is incorrect: Out of Range Frequency"); + return -EINVAL; + } + return 0; +} +EXPORT_SYMBOL(calculate_effective_freq); + +/** + * process_dma_info - Processes the DMA info provided by client drivers + * @chip_info: chip info provided by client device + * @chip: Runtime state maintained by the spi controller for each spi device + * + * This function processes and stores DMA config provided by client driver + * into the runtime state maintained by the spi controller driver + */ +int process_dma_info(struct nmdk_spi_config_chip *chip_info, + struct chip_data *chip, void * data) +{ + struct driver_data *drv_data = (struct driver_data *)data; + + /* default setup required for any SPI dma transfer*/ + chip->dma_info->rx_dma_info.srcdevtype = drv_data->master_info->dma_srcdevtype; + chip->dma_info->rx_dma_info.config = 0; + + chip->dma_info->tx_dma_info.destdevtype = drv_data->master_info->dma_destdevtype; + chip->dma_info->tx_dma_info.config = 0; + + if (chip_info->dma_xfer_type == SPI_WITH_MEM) { + chip->dma_info->rx_dma_info.mode = FLOW_CNTRL_DMA(PERIPH_TO_MEM); + chip->dma_info->rx_dma_info.destdevtype = "mem"; + + chip->dma_info->tx_dma_info.mode = FLOW_CNTRL_DMA(MEM_TO_PERIPH); + chip->dma_info->tx_dma_info.srcdevtype = "mem"; + if (chip_info->dma_config) { + chip->dma_info->rx_dma_info.mode |= chip_info->dma_config->tx_dma_mode & ~(FLOW_CNTRL_DEST_PERIPH(PERIPH_TO_PERIPH)); + chip->dma_info->tx_dma_info.mode |= chip_info->dma_config->rx_dma_mode & ~(FLOW_CNTRL_DEST_PERIPH(PERIPH_TO_PERIPH)); + if (chip_info->dma_config->tx_client_dmadev_config) { + chip->dma_info->rx_dma_info.config |= DMA_DEVCONFIG_DEST(chip_info->dma_config->tx_client_dmadev_config->config); + } + if (chip_info->dma_config->rx_client_dmadev_config) { + chip->dma_info->tx_dma_info.config |= DMA_DEVCONFIG_DEST(chip_info->dma_config->rx_client_dmadev_config->config); + } + if (chip_info->dma_config->tx_master_dmadev_config) { + chip->dma_info->rx_dma_info.config |= DMA_DEVCONFIG_SRC(chip_info->dma_config->tx_master_dmadev_config->config); + } + if (chip_info->dma_config->rx_master_dmadev_config) { + chip->dma_info->tx_dma_info.config |= DMA_DEVCONFIG_SRC(chip_info->dma_config->rx_master_dmadev_config->config); + } + } + } else { /*SPI_WITH_PERIPH*/ + chip->dma_info->rx_dma_info.mode = FLOW_CNTRL_DMA(PERIPH_TO_PERIPH); + chip->dma_info->tx_dma_info.mode = FLOW_CNTRL_DMA(PERIPH_TO_PERIPH); + if (chip_info->dma_config) { + chip->dma_info->rx_dma_info.mode |= chip_info->dma_config->tx_dma_mode & ~(FLOW_CNTRL_DEST_PERIPH(PERIPH_TO_PERIPH)); + chip->dma_info->tx_dma_info.mode |= chip_info->dma_config->rx_dma_mode & ~(FLOW_CNTRL_DEST_PERIPH(PERIPH_TO_PERIPH)); + if (chip_info->dma_config->tx_client_dmadev_config) { + chip->dma_info->rx_dma_info.config |= DMA_DEVCONFIG_DEST(chip_info->dma_config->tx_client_dmadev_config->config); + chip->dma_info->rx_dma_info.destdevtype = chip_info->dma_config->tx_client_dmadev_config->devtype; + } + if (chip_info->dma_config->rx_client_dmadev_config) { + chip->dma_info->tx_dma_info.config |= DMA_DEVCONFIG_DEST(chip_info->dma_config->rx_client_dmadev_config->config); + chip->dma_info->tx_dma_info.srcdevtype = chip_info->dma_config->rx_client_dmadev_config->devtype; + } + if (chip_info->dma_config->tx_master_dmadev_config) { + chip->dma_info->rx_dma_info.config |= DMA_DEVCONFIG_SRC(chip_info->dma_config->tx_master_dmadev_config->config); + } + if (chip_info->dma_config->rx_master_dmadev_config) { + chip->dma_info->tx_dma_info.config |= DMA_DEVCONFIG_SRC(chip_info->dma_config->rx_master_dmadev_config->config); + } + } else return -EINVAL; + } + + print_dma_info(chip_info->dma_xfer_type, chip); + return 0; +} + +EXPORT_SYMBOL(process_dma_info); + +/** + * nomadik_spi_cleanup - cleanup function registered to SPI master framework + * @spi: spi device which is requesting cleanup + * + * This function is registered to the SPI framework for this SPI master + * controller. It will free the runtime state of chip. + */ +void nomadik_spi_cleanup(const struct spi_device *spi) +{ + struct chip_data *chip = spi_get_ctldata((struct spi_device *)spi); + struct driver_data *drv_data = spi_master_get_devdata(spi->master); + struct spi_master *master; +#if (defined(CONFIG_NOMADIK_MSP) || defined(CONFIG_NOMADIK_MSP_MODULE)) + int status =0; +#endif + nmdk_dbg_ftrace(); + + master = drv_data->master; + +#if (defined(CONFIG_NOMADIK_MSP) || defined(CONFIG_NOMADIK_MSP_MODULE)) + switch(master->bus_num) { + case MSP_0_CONTROLLER: if(drv_data->flag_msp0->user == SPI_USER_MSP) { + down(&drv_data->flag_msp0->lock); + drv_data->flag_msp0->user = SPI_NO_MSP_USER; + up(&drv_data->flag_msp0->lock); + nmdk_dbg("Flag cleanup for MSP0\n"); + } + else { + printk("Error in nomadik_spi_cleanup Trying to free MSP from SPI-mode , already configured in mode%d\n", (drv_data->flag_msp0->user)); + status = -EFAULT; + } + break; + case MSP_1_CONTROLLER: if(drv_data->flag_msp1->user == SPI_USER_MSP) { + down(&drv_data->flag_msp1->lock); + drv_data->flag_msp1->user = SPI_NO_MSP_USER; + up(&drv_data->flag_msp1->lock); + nmdk_dbg("Flag cleanup for MSP1\n"); + } + else { + printk("Error in nomadik_spi_cleanup Trying to free MSP from SPI-mode , already configured in mode%d\n", drv_data->flag_msp1->user); + status = -EFAULT; + } + break; + case MSP_2_CONTROLLER: if(drv_data->flag_msp2->user == SPI_USER_MSP) { + down(&drv_data->flag_msp2->lock); + drv_data->flag_msp2->user = SPI_NO_MSP_USER; + up(&drv_data->flag_msp2->lock); + nmdk_dbg("Flag cleanup for MSP2\n"); + } + else { + printk("Error in nomadik_spi_cleanup Trying to free MSP from SPI-mode , already configured in mode%d\n", drv_data->flag_msp2->user); + status = -EFAULT; + } + break; + } + if(status) + return ; +#endif + if((master->bus_num == MSP_0_CONTROLLER) ||(master->bus_num == MSP_1_CONTROLLER) || (master->bus_num == MSP_2_CONTROLLER)) { + nomadik_gpio_altfuncdisable(drv_data->master_info->gpio_alt_func, drv_data->master_info->device_name); + free_irq(drv_data->adev->irq[0], drv_data); + } + if (chip){ + if(chip->dma_info) { + if (chip->dma_info->tx_dmach != -1) { + free_dma(chip->dma_info->tx_dmach); + chip->dma_info->tx_dmach = -1; + } + if (chip->dma_info->rx_dmach != -1) { + free_dma(chip->dma_info->rx_dmach); + chip->dma_info->rx_dmach = -1; + } + kfree(chip->dma_info); + } + kfree(chip); + } +} +EXPORT_SYMBOL(nomadik_spi_cleanup); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Sachin Verma : Vaibhav Agarwal to control the + + NOTE: this is different from supporting /proc filesystem; + + If you do not know what this is, please say N. + +config USB_INVENTRA_HCD_CUSTOM_OPTIONS + depends on USB_INVENTRA_HCD + string 'Custom compile options (Advanced)' + default '' + help + Specify a custom compile options (Advanced) + +config USB_INVENTRA_HCD_POLLING + depends on USB_INVENTRA_HCD + bool 'Use polling driver (debug only)' + default false + help + Enable polling mode (events won't be triggered by IRQs); usefule + for debugging. + + If you do not know what this is, please say N. + +config USB_INVENTRA_HCD_LOGGING + depends on USB_INVENTRA_HCD + int 'Logging Level (0 - none / 3 - annoying)' + default 0 + help + Set the logging level. 0 disable the debugging altogether (no + code will be added to the) + + If you do not know what this is, please say N. + --- /dev/null +++ linux-2.6.20/drivers/usb/nomadik/Makefile @@ -0,0 +1,97 @@ +MUSB_VERSION=2.2.2 +HCD_TYPE=hcd + + +obj-$(CONFIG_USB_INVENTRA_HCD) += musb-hcd.o + + + +ifeq ($(CONFIG_PROC_FS),y) + musb-$(HCD_TYPE)-objs += musb_procfs.o +endif + + +ifneq ($(CONFIG_USB_INVENTRA_MUSB_BOARD_FILE),"") + EXTRA_CFLAGS += -DMUSB_BOARD_FILE +endif + +ifneq ($(CONFIG_USB_INVENTRA_MUSB_HDR_CCNF_FILE),"") +EXTRA_CFLAGS += -DMUSB_HDR_CCNF_FILE +endif + +ifeq ($(CONFIG_USB_INVENTRA_STATIC_CONFIG),y) +ifneq ($(CONFIG_USB_INVENTRA_MUSB_EPFIFOCONFIG_FILE),"") +EXTRA_CFLAGS += -DMUSB_EPFIFOCONFIG_FILE +endif +endif + +ifneq ($(CONFIG_USB_INVENTRA_HCD_CUSTOM_OPTIONS),"") +EXTRA_CFLAGS += $(CONFIG_USB_INVENTRA_HCD_CUSTOM_OPTIONS) +endif + + + EXTRA_CFLAGS += -DMUSB_C_DYNFIFO_DEF + EXTRA_CFLAGS += -DMUSB_EPDISCRIPTORS_FILE + +ifeq ($(CONFIG_USB_INVENTRA_MUSB_HAS_AHB_ID),y) + EXTRA_CFLAGS += -DMUSB_AHB_ID +endif + +ifeq ($(CONFIG_USB_INVENTRA_DMA),y) + EXTRA_CFLAGS += -DMUSB_DMA + musb-$(HCD_TYPE)-objs += musbhsdma.o +endif + +EXTRA_CFLAGS += -DMUSB_VERSION='"$(MUSB_VERSION)"' -DHCD_NAME=$(HCD_NAME) + +ifeq ($(CONFIG_USB_INVENTRA_STATIC_CONFIG),y) + EXTRA_CFLAGS += -DMUSB_STATIC_CONFIG +endif + +ifeq ($(CONFIG_USB_INVENTRA_HCD_OTG),y) + GADGET_API=y + MUSB_HOSTMODE=y + EXTRA_CFLAGS += -DMUSB_OTG + musb-$(HCD_TYPE)-objs += otg.o +endif + +ifeq ($(CONFIG_USB_INVENTRA_HCD_GADGET_API),y) + GADGET_API=y +endif + +#ifneq ($(GADGET_API),) + +# GADGET_DIRS=y +# EXTRA_CFLAGS += -DMUSB_GADGET +# musb-$(HCD_TYPE)-objs += musb_gadgetcommon.o g_ep0.o musb_gadget.o +#endif + + +ifeq ($(CONFIG_USB_INVENTRA_HCD_HOST),y) + MUSB_HOSTMODE=y +endif + + +ifeq ($(MUSB_HOSTMODE),y) + EXTRA_CFLAGS += -DMUSB_HOST + musb-$(HCD_TYPE)-objs += musb_virthub.o musb_host.o musb-hcd.o musb_plat_uds.o musb_bus_direct.o musb_epfifocfg.o musb_ioctl.o nomadik_udc.o otg_pwm.o otg_func.o + +endif + +ifndef DEBUG + DEBUG=0 +endif + +MUSB_DEBUG=$(CONFIG_USB_INVENTRA_HCD_LOGGING) +ifeq ("$(strip $(MUSB_DEBUG))","") + MUSB_DEBUG:=$(DEBUG) +endif + + +ifneq ($(MUSB_DEBUG),0) + EXTRA_CFLAGS += -g + musb-$(HCD_TYPE)-objs += musb_debug.o +endif + +EXTRA_CFLAGS += -DMUSB_DEBUG=$(MUSB_DEBUG) + --- /dev/null +++ linux-2.6.20/drivers/usb/nomadik/board.h @@ -0,0 +1,58 @@ +/* + * linux/drivers/usb/nomadik/board.h + * + * Copyright 2007, STMicroelectronics + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +/* + * Example board-specific definitions. + * $Revision: 1.6 $ + * + * It is suggested to: + * 1. Copy this file to one named after your target: + * cp board.h board-mytarget.h + * 2. Save this file for future reference: + * mv board.h board-example.h + * 3. Link board.h to yours: + * ln -s board-mytarget.h board.h + * 4. Edit yours, providing, for each controller: + * - controller type (MUSB_CONTROLLER_HDRC or MUSB_CONTROLLER_MHDRC) + * - physical base address in kernel space + * - interrupt number (interpretation is platform-specific) + */ + +/** Array of information about hard-wired controllers + * This will be liked to the first module that includes this file. + */ + +#ifndef __MUSB_LINUX_BOARD_H__ +#define __MUSB_LINUX_BOARD_H__ +#include + +#include +#define INT_USBOTG IRQ_USBOTG + +MUSB_LinuxController MUSB_aLinuxController[] = +{ + { MUSB_CONTROLLER_HDRC, (void*)NOMADIK_USB_BASE, INT_USBOTG } + /* + { MUSB_CONTROLLER_HDRC, (void*)0xc0000000, 9 } + */ +}; + +#endif /* multiple inclusion protection */ --- /dev/null +++ linux-2.6.20/drivers/usb/nomadik/debug.h @@ -0,0 +1,104 @@ +/* + * linux/drivers/usb/nomadik/debug.h + * + * Copyright 2007, STMicroelectronics + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __MUSB_LINUX_DEBUG_H__ +#define __MUSB_LINUX_DEBUG_H__ + +/* + * Linux HCD (Host Controller Driver) for HDRC and/or MHDRC. + * Debug support routines + * + */ + +#define MUSB_MONITOR_DATA + +#define yprintk(facility, format, args...) do { printk(facility "%s %d: " format , \ + __FUNCTION__, __LINE__ , ## args); } while (0) +#define WARN(fmt, args...) yprintk(KERN_WARNING,fmt, ## args) +#define INFO(fmt,args...) yprintk(KERN_INFO,fmt, ## args) +#define ERR(fmt,args...) yprintk(KERN_INFO,fmt, ## args) + +#if MUSB_DEBUG > 0 + +#define STATIC +#define MGC_GetDebugLevel() (MGC_DebugLevel) +#define MGC_EnableDebug() do { MGC_DebugDisable=0; } while(0) +#define MGC_DisableDebug() do { MGC_DebugDisable=1; } while(0) + +#define _dbg_level(level) ( !MGC_DebugDisable && ((level>=-1 && MGC_GetDebugLevel()>=level) || MGC_GetDebugLevel()==level) ) + +#define xprintk(level, facility, format, args...) do { if ( _dbg_level(level) ) { \ + printk(facility "%s %d: " format , __FUNCTION__, __LINE__ , ## args); } } while (0) + +#define PARANOID( x ) do {} while (0) +#define DBG(level,fmt,args...) xprintk(level,KERN_INFO,fmt, ## args) +#define DEBUG_CODE(level, code) do { if ( _dbg_level(level) ) { code } } while (0) +#define TRACE(n) DEBUG_CODE(n, printk(KERN_INFO "%s:%s:%d: trace\n", \ + __FILE__, __FUNCTION__, __LINE__); ) + +#define ASSERT_SPINLOCK_LOCKED(_x) +#define ASSERT_SPINLOCK_UNLOCKED(_x) +/* #define ASSERT_SPINLOCK_LOCKED(_x) do { if (!spin_is_locked(_x)) \ + ERR("@pre clause failed, _x must be locked\n"); } while (0) +#define ASSERT_SPINLOCK_UNLOCKED(_x) do { if (spin_is_locked(_x)) \ + ERR("@pre clause failed, _x must be unlocked\n"); } while (0) */ + +/* debug no defined */ + +#else + +#define STATIC static +#define MGC_GetDebugLevel() 0 +#define MGC_EnableDebug() +#define MGC_DisableDebug() + +#define PARANOID( x ) do {} while (0) +#define DBG(fmt,args...) do {} while (0) +#define DEBUG_CODE(x, y) do {} while (0) +#define TRACE(n) do {} while (0) + +#define ASSERT_SPINLOCK_LOCKED(_x) +#define ASSERT_SPINLOCK_UNLOCKED(_x) + +#endif + +/*----------------------- DEBUG function/macros -----------------------------*/ + +#if MUSB_DEBUG > 0 +struct usb_ep; +struct list_head; +struct usb_request; +struct usb_ctrlrequest; + +extern int MGC_DebugLevel; +extern int MGC_DebugDisable; + +extern void dump_urb(void *urb); +extern char *decode_csr0(uint16_t csr0); +extern char *decode_txcsr(uint16_t txcsr); +extern char *decode_devctl(uint16_t devclt); +extern char *decode_ep0stage(uint8_t stage); +extern char *dump_node(struct list_head *node); +extern char *decode_usb_ctrlrequest(const struct usb_ctrlrequest *pControlRequest); +extern char *decode_request(struct usb_ctrlrequest*) ; +extern void MGC_HdrcDumpRegs(uint8_t* pBase, int multipoint, uint8_t bEnd); +#endif + +#endif // __MUSB_LINUX_DEBUG_H__ --- /dev/null +++ linux-2.6.20/drivers/usb/nomadik/dma.h @@ -0,0 +1,308 @@ +/* + * linux/drivers/usb/nomadik/dma.h + * + * Copyright 2007, STMicroelectronics + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __MUSB_DMA_H__ +#define __MUSB_DMA_H__ + +/** + * Introduction. + * The purpose of the DMA Controller Abstraction (DCA) is to allow the ICD + * to use any DMA controller, + * since this is an option in the Inventra USB cores. + * The assumptions are: + *
    + *
  • A DMA controller will be tied to an Inventra USB core in the + * way specified in the Inventra core product specification. + *
  • A DMA controller's base address in the memory map correlates + * somehow to the Inventra USB core it serves. + *
+ * The responsibilities of an implementation include: + *
    + *
  • Allocating/releasing buffers for use with DMA + * (this may be specific to a DMA controller, intervening busses, + * and a target's capabilities, + * so the ICD cannot make assumptions or provide services here) + *
  • Handling the details of moving multiple USB packets + * in cooperation with the Inventra USB core. + *
  • Knowing the correlation between channels and the + * Inventra core's local endpoint resources and data direction, + * and maintaining a list of allocated/available channels. + *
  • Updating channel status on interrupts, + * whether shared with the Inventra core or separate. + *
  • If the DMA interrupt is shared with the Inventra core, + * handling it when called, and reporting whether it was the + * source of interrupt. + *
+ */ + +/*************************** CONSTANTS ****************************/ + +/** + * DMA channel status. + */ +typedef enum +{ + /** A channel's status is unknown */ + MGC_DMA_STATUS_UNKNOWN, + /** A channel is available (not busy and no errors) */ + MGC_DMA_STATUS_FREE, + /** A channel is busy (not finished attempting its transactions) */ + MGC_DMA_STATUS_BUSY, + /** A channel aborted its transactions due to a local bus error */ + MGC_DMA_STATUS_BUS_ABORT, + /** A channel aborted its transactions due to a core error */ + MGC_DMA_STATUS_CORE_ABORT +} MGC_DmaChannelStatus; + +/***************************** TYPES ******************************/ + +/** + * MGC_DmaChannel. + * A DMA channel. + * @field pPrivateData channel-private data; not to be interpreted by the ICD + * @field wMaxLength the maximum number of bytes the channel can move + * in one transaction (typically representing many USB maximum-sized packets) + * @field dwActualLength how many bytes have been transferred + * @field bStatus current channel status (updated e.g. on interrupt) + * @field bDesiredMode TRUE if mode 1 is desired; FALSE if mode 0 is desired + */ +typedef struct +{ + void* pPrivateData; + uint32_t dwMaxLength; + uint32_t dwActualLength; + MGC_DmaChannelStatus bStatus; + uint8_t bDesiredMode; +} MGC_DmaChannel; + +/** + * Start a DMA controller. + * @param pPrivateData private data pointer from MGC_DmaController + * @return TRUE on success + * @return FALSE on failure (e.g. no DMAC appears present) + */ +typedef uint8_t (*MGC_pfDmaStartController)(void* pPrivateData); + +/** + * Stop a DMA controller. + * @param pPrivateData the controller's private data pointer + * @return TRUE on success + * @return FALSE on failure; the ICD may try again + */ +typedef uint8_t (*MGC_pfDmaStopController)(void* pPrivateData); + +/** + * Allocate a DMA channel. + * Allocate a DMA channel suitable for the given conditions. + * @param pPrivateData the controller's private data pointer + * @param bLocalEnd the local endpoint index (1-15) + * @param bTransmit TRUE for transmit; FALSE for receive + * @param bProtocol the USB protocol, as per USB 2.0 chapter 9 + * (0 => control, 1 => isochronous, 2 => bulk, 3 => interrupt) + * @param wMaxPacketSize maximum packet size + * @return a non-NULL pointer on success + * @return NULL on failure (no channel available) + */ +typedef MGC_DmaChannel* (*MGC_pfDmaAllocateChannel)( + void* pPrivateData, uint8_t bLocalEnd, + uint8_t bTransmit, uint8_t bProtocol, uint16_t wMaxPacketSize); + +/** + * Release a DMA channel. + * Release a previously-allocated DMA channel. + * The ICD guarantess to no longer reference this channel. + * @param pChannel pointer to a channel obtained by + * a successful call to pController->pfDmaAllocateChannel + */ +typedef void (*MGC_pfDmaReleaseChannel)(MGC_DmaChannel* pChannel); + +/** + * Allocate DMA buffer. + * Allocate a buffer suitable for DMA operations with the given channel. + * @param pChannel pointer to a channel obtained by + * a successful call to pController->pfDmaAllocateChannel + * @param dwLength length, in bytes, desired for the buffer + * @return a non-NULL pointer to a suitable region (in processor space) + * on success + * @return NULL on failure + */ +typedef uint8_t* (*MGC_pfDmaAllocateBuffer)(MGC_DmaChannel* pChannel, + uint32_t dwLength); + +/** + * Release DMA buffer. + * Release a DMA buffer previously acquiring by a successful call + * to pController->pfDmaAllocateBuffer. + * @param pChannel pointer to a channel obtained by + * a successful call to pController->pfDmaAllocateChannel + * @param pBuffer the buffer pointer + * @return TRUE on success + * @return FALSE on failure (e.g. the controller owns the buffer at present) + */ +typedef uint8_t (*MGC_pfDmaReleaseBuffer)(MGC_DmaChannel* pChannel, + uint8_t* pBuffer); + +/** + * Program a DMA channel. + * Program a DMA channel to move data at the core's request. + * The local core endpoint and direction should already be known, + * since they are specified in the pfDmaAllocateChannel call. + * @param pChannel pointer to a channel obtained by + * a successful call to pController->pfDmaAllocateChannel + * @param wPacketSize the packet size + * @param bMode TRUE if mode 1; FALSE if mode 0 + * @param pBuffer base address of data (in processor space) + * @param dwLength the number of bytes to transfer; + * guaranteed by the ICD to be no larger than the channel's reported dwMaxLength + * @return TRUE on success + * @return FALSE on error + */ +typedef uint8_t (*MGC_pfDmaProgramChannel)(MGC_DmaChannel* pChannel, + uint16_t wPacketSize, uint8_t bMode, + const uint8_t* pBuffer, + uint32_t dwLength); + +/** + * Get DMA channel status. + * Get the current status of a DMA channel, if the hardware allows. + * @param pChannel pointer to a channel obtained by + * a successful call to pController->DmaAllocateChannel + * @return current status + * (MGC_DMA_STATUS_UNKNOWN if hardware does not have readable status) + */ +typedef MGC_DmaChannelStatus (*MGC_pfDmaGetChannelStatus)( + MGC_DmaChannel* pChannel); + +/** + * DMA ISR. + * If present, this function is called by the ICD on every interrupt. + * This is necessary because with the built-in DMA controller + * (and probably some other configurations), + * the DMA interrupt is shared with other core interrupts. + * Therefore, this function should return quickly + * when there is no DMA interrupt. + * When there is a DMA interrupt, this function should + * perform any implementations-specific operations, + * and update the status of all appropriate channels. + * If the DMA controller has its own dedicated interrupt, + * this function should do nothing. + * This function is called BEFORE the ICD handles other interrupts. + * @param pPrivateData the controller's private data pointer + * @return TRUE if an interrupt was serviced + * @return FALSE if no interrupt required servicing + */ +typedef uint8_t (*MGC_pfDmaControllerIsr)(void* pPrivateData); + +/** + * MGC_DmaController. + * A DMA Controller. + * This is in a struct to allow the ICD to support + * multiple cores of different types, + * since each may use a different type of DMA controller. + * @field pPrivateData controller-private data; + * not to be interpreted by the ICD + * @field pfDmaStartController ICD calls this to start a DMA controller + * @field pfDmaStopController ICD calls this to stop a DMA controller + * @field pfDmaAllocateChannel ICD calls this to allocate a DMA channel + * @field pfDmaReleaseChannel ICD calls this to release a DMA channel + * @field pfDmaAllocateBuffer ICD calls this to allocate a DMA buffer + * @field pfDmaReleaseBuffer ICD calls this to release a DMA buffer + * @field pfDmaGetChannelStatus ICD calls this to get a DMA channel's status + * @field pfDmaControllerIsr ICD calls this (if non-NULL) from its ISR + */ +typedef struct +{ + void* pPrivateData; + MGC_pfDmaStartController pfDmaStartController; + MGC_pfDmaStopController pfDmaStopController; + MGC_pfDmaAllocateChannel pfDmaAllocateChannel; + MGC_pfDmaReleaseChannel pfDmaReleaseChannel; + MGC_pfDmaAllocateBuffer pfDmaAllocateBuffer; + MGC_pfDmaReleaseBuffer pfDmaReleaseBuffer; + MGC_pfDmaProgramChannel pfDmaProgramChannel; + MGC_pfDmaGetChannelStatus pfDmaGetChannelStatus; + MGC_pfDmaControllerIsr pfDmaControllerIsr; +} MGC_DmaController; + +/** + * A DMA channel has new status. + * This may be used to notify the ICD of channel status changes asynchronously. + * This is useful if the DMA interrupt is different from the USB controller's + * interrupt, so on some systems there may be no control over the order of + * USB controller and DMA controller assertion. + * @param pPrivateData the controller's private data pointer + * @param bLocalEnd the local endpoint index (1-15) + * @param bTransmit TRUE for transmit; FALSE for receive + * @return TRUE if an IRP was completed as a result of this call; + * FALSE otherwise + */ +typedef uint8_t (*MGC_pfDmaChannelStatusChanged)( + void* pPrivateData, uint8_t bLocalEnd, + uint8_t bTransmit); + +/** + * Instantiate a DMA controller. + * Instantiate a software object representing a DMA controller. + * @param pfDmaChannelStatusChanged channel status change notification function. + * Normally, the ICD requests status in its interrupt handler. + * For some DMA controllers, this may not be the correct time. + * @param pDmaPrivate parameter for pfDmaChannelStatusChanged + * @param pCoreBase the base address (in kernel space) of the core + * It is assumed the DMA controller's registers' base address will be related + * to this in some way. + * @return non-NULL pointer on success + * @return NULL on failure (out of memory or exhausted + * a fixed number of controllers) + */ +typedef MGC_DmaController* (*MGC_pfNewDmaController)( + MGC_pfDmaChannelStatusChanged pfDmaChannelStatusChanged, + void* pDmaPrivate, + uint8_t* pCoreBase); + +/** + * Destroy DMA controller. + * Destroy a previously-instantiated DMA controller. + */ +typedef void (*MGC_pfDestroyDmaController)( + MGC_DmaController* pController); + +/** + * MGC_DmaControllerFactory. + * A DMA controller factory. + * To allow for multi-core implementations and different + * types of cores and DMA controllers to co-exist, + * it is necessary to create them from factories. + * @field wCoreRegistersExtent the total size of the core's + * register region with the DMA controller present, + * for use in mapping the core into system memory. + * For example, the MHDRC core takes 0x200 bytes of address space. + * If your DMA controller starts at 0x200 and takes 0x100 bytes, + * set this to 0x300. + * @field pfNewDmaController create a DMA controller + * @field pfDestroyDmaController destroy a DMA controller + */ +typedef struct +{ + uint16_t wCoreRegistersExtent; + MGC_pfNewDmaController pfNewDmaController; + MGC_pfDestroyDmaController pfDestroyDmaController; +} MGC_DmaControllerFactory; + +#endif /* multiple inclusion protection */ --- /dev/null +++ linux-2.6.20/drivers/usb/nomadik/g_ep0.c @@ -0,0 +1,858 @@ +/* + * linux/drivers/usb/nomadik/g_ep0.c + * + * Copyright 2007, STMicroelectronics + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include +#include + +#if defined(MUSB_V24) && !defined(MUSB_LINUX_MV21) +/* dealing with Linux headers */ +struct usb_tt { + struct usb_device *hub; /* upstream highspeed hub */ + int multi; /* true means one TT per port */ +}; +#include "hcd.h" +#endif + +#include +#include +#include "musbdefs.h" +#include "musb_gadgetdefs.h" + + +/* ---------------------------------------------------------------------- */ + +/** + * Identifies a transmit request. + * @param pControlRequest the control request + * @return true for USB_REQ_GET_CONFIGURATION, USB_REQ_GET_INTERFACE, + * USB_REQ_GET_DESCRIPTOR, USB_REQ_GET_STATUS, USB_REQ_SYNC_FRAME + */ +uint8_t is_tx_request(const struct usb_ctrlrequest *pControlRequest) +{ + return ( pControlRequest->bRequestType & USB_DIR_IN ); +} + +/** + * Identifies a zero data request. + * @param pControlRequest the control request + * @return true for USB_REQ_SET_INTERFACE, USB_REQ_SET_CONFIGURATION, + * USB_REQ_SET_ADDRESS, USB_REQ_CLEAR_FEATURE, USB_REQ_SET_FEATURE + * + */ +uint8_t is_zerodata_request(const struct usb_ctrlrequest *pControlRequest) +{ + return ( 0==pControlRequest->wLength ) && !is_tx_request(pControlRequest); +} + +/** + * Identifies a receive request. + * @param pControlRequest the control request + * @return true for USB_REQ_SET_DESCRIPTOR + */ +uint8_t is_rx_request(const struct usb_ctrlrequest *pControlRequest) +{ + return pControlRequest->bRequest==USB_REQ_SET_DESCRIPTOR; +} + +/* ---------------------------------------------------------------------- */ + +/** + * Forward a request to the driver. + * + * FROM: usb_gadget.h + * Accordingly, the driver's setup() callback must always implement all + * get_descriptor requests, returning at least a device descriptor and + * a configuration descriptor. Drivers must make sure the endpoint + * descriptors match any hardware constraints. Some hardware also constrains + * other descriptors. (The pxa250 allows only configurations 1, 2, or 3). + * + * The driver's setup() callback must also implement set_configuration, + * and should also implement set_interface, get_configuration, and + * get_interface. Setting a configuration (or interface) is where + * endpoints should be activated or (config 0) shut down. + * + * @param pControlRequest the usb control request to forward to the driver + */ +static int forward_to_driver(const struct usb_ctrlrequest *pControlRequest) +{ + int handled=-EOPNOTSUPP; + MGC_LinuxCd* pThis=MGC_GetDriverByName(NULL); + + + DBG(2, "<== pThis->pGadgetDriver=%p, pControlRequest=%p\n", + pThis->pGadgetDriver, pControlRequest); + +#ifdef MUSB_PARANOID + ASSERT_SPINLOCK_UNLOCKED(&pThis->Lock); + ASSERT_SPINLOCK_UNLOCKED(&MGC_aGadgetLocalEnd[0]); +#endif + + if ( pThis->pGadgetDriver ){ + handled=pThis->pGadgetDriver->setup(pThis->pGadget, + pControlRequest); + } + else{ + printk("Error case\n"); + } + + DBG(2, "==> handled=%d\n", handled); + return handled; +} + +/* ---------------------------------------------------------------------- */ + +/** + * Service a receive request. Currently forward to the driver. + * @param pControlRequest the usb control request to service. + * @see is_rx_request + */ +static int service_rx_request(struct usb_ctrlrequest *pControlRequest) +{ +#ifdef MUSB_PARANOID + ASSERT_SPINLOCK_UNLOCKED(&pThis->Lock); + ASSERT_SPINLOCK_UNLOCKED(&MGC_aGadgetLocalEnd[0]); +#endif + return forward_to_driver(pControlRequest); +} + +/** + * Service a transmit request. + * @param pControlRequest the request to service + * @see is_tx_request + */ +void service_tx_status_request(const struct usb_ctrlrequest *pControlRequest) +{ + uint8_t handled=1; + uint8_t bResult[2], bEnd=0; + MGC_LinuxCd* pThis=MGC_GetDriverByName(NULL); + const uint8_t* pBase = (uint8_t*)pThis->pRegs; + const uint8_t bRecip=pControlRequest->bRequestType & USB_RECIP_MASK; + + /* ack the request */ + DBG(3, "acking request %s\n", decode_csr0(MGC_M_CSR0_P_SVDRXPKTRDY) ); + spin_lock(&pThis->Lock); + MGC_SelectEnd(pBase, 0); + MGC_WriteCsr16(pBase, MGC_O_HDRC_CSR0, 0, MGC_M_CSR0_P_SVDRXPKTRDY); + spin_unlock(&pThis->Lock); + + switch (bRecip) { + + case USB_RECIP_DEVICE: + DBG(3, "USB_RECIP_DEVICE()\n"); + bResult[0] = pThis->bIsSelfPowered ? 1 : 0; + bResult[0] |= 2; + bResult[1] = 0; + MGC_HdrcLoadFifo(pBase, 0, 2, (uint8_t*)&bResult); + break; + + case USB_RECIP_ENDPOINT: + { + uint16_t wTest; + + DBG(3, "USB_RECIP_ENDPOINT()\n"); + + bEnd = (uint8_t)pControlRequest->wIndex; + + spin_lock(&pThis->Lock); + MGC_SelectEnd(pBase, bEnd); + wTest = MGC_ReadCsr16(pBase, MGC_O_HDRC_TXCSR, bEnd); + MGC_SelectEnd(pBase, 0); + bResult[0] = (wTest & MGC_M_TXCSR_P_SENDSTALL) ? 1 : 0; + bResult[1] = 0; + MGC_HdrcLoadFifo(pBase, 0, 2, (uint8_t*)&bResult); + spin_unlock(&pThis->Lock); + } + break; + + default: + handled=0; + break; + } + + /* send it out! (this will trigger the ep0 completition IRQ) + * serviced in interrupt_complete() */ + if ( handled ) { + pThis->bEnd0Stage=MGC_END0_STAGE_STATUSOUT; + + spin_lock(&pThis->Lock); + MGC_SelectEnd(pBase, bEnd); + MGC_WriteCsr16(pBase, MGC_O_HDRC_CSR0, 0, + MGC_M_CSR0_TXPKTRDY | MGC_M_CSR0_P_DATAEND); + spin_unlock(&pThis->Lock); + } +} + +/** + * Service a transmit a request. End0 buffer contains the current + * request (a standard control request). Assumes the fifo to be at least + * bytes long. Requests handled here are: USB_REQ_GET_CONFIGURATION, + * USB_REQ_GET_INTERFACE, USB_REQ_GET_DESCRIPTOR, USB_REQ_GET_STATUS, + * USB_REQ_SYNC_FRAME. + * + * @param pControlRequest the request to service + * @return 0 if the request was NOT HANDLED, < 0 when error (ENOSUPP not + * supprorted), > 0 when the request is processed + * @see is_tx_request + */ +static int service_tx_request(const struct usb_ctrlrequest *pControlRequest) +{ + int handled=0; /* not handled */ + +#ifdef MUSB_PARANOID + ASSERT_SPINLOCK_UNLOCKED(&pThis->Lock); + ASSERT_SPINLOCK_UNLOCKED(&MGC_aGadgetLocalEnd[0]); +#endif + + if ( USB_TYPE_STANDARD!=(pControlRequest->bRequestType&USB_TYPE_MASK )) { + return forward_to_driver(pControlRequest); + } + + switch (pControlRequest->bRequest) { + case USB_REQ_GET_CONFIGURATION: + DBG(3, "USB_REQ_GET_CONFIGURATION()\n"); + break; + + case USB_REQ_GET_INTERFACE: + DBG(3, "USB_REQ_GET_INTERFACE()\n"); + break; + + case USB_REQ_GET_DESCRIPTOR: + DBG(3, "USB_REQ_GET_DESCRIPTOR()\n"); + break; + + case USB_REQ_GET_STATUS: { + DBG(3, "USB_REQ_GET_STATUS()\n"); + service_tx_status_request(pControlRequest); + } + break; + + /* case USB_REQ_SYNC_FRAME: + break; */ + + default: + break; + } + + if ( !handled ) { + handled=forward_to_driver(pControlRequest); + } + + /* now tx! */ + return handled; +} + +/** + * Service a zero data request. + * Called for USB_REQ_SET_INTERFACE, USB_REQ_SET_CONFIGURATION, + * USB_REQ_SET_ADDRESS, USB_REQ_CLEAR_FEATURE, USB_REQ_SET_FEATURE. + * + * @param pThis the controller instance + * @param pControlRequest the control request to service. + * @warning USB_REQ_SET_ADDRESS should be executed QUICKLY + * @see is_zerodata_request + */ +static int service_zero_data_request(MGC_LinuxCd* pThis, + struct usb_ctrlrequest *pControlRequest) +{ + int handled=1; /* handled, DO NOT not pass down */ + const uint8_t* pBase = (uint8_t*)pThis->pRegs; + const uint8_t bRecip=pControlRequest->bRequestType & USB_RECIP_MASK; + + DBG(-1002, "<==\n"); + +#ifdef MUSB_PARANOID + ASSERT_SPINLOCK_UNLOCKED(&pThis->Lock); + ASSERT_SPINLOCK_UNLOCKED(&MGC_aGadgetLocalEnd[0]); +#endif + + /* non standard requests are piped to the gadget */ + if ( USB_TYPE_STANDARD!=(pControlRequest->bRequestType&USB_TYPE_MASK )) { + return forward_to_driver(pControlRequest); + } + + /* zero data phase */ + switch (pControlRequest->bRequest) { + + case USB_REQ_SET_INTERFACE: + DBG(3, "USB_REQ_SET_INTERFACE()\n"); + handled=0; /* pass it to the gadget */ + break; + + case USB_REQ_SET_CONFIGURATION: + /* remember state & handle on the end status stage interrupt */ + DBG(3, "USB_REQ_SET_CONFIGURATION()\n"); + pThis->bDeviceState = (pControlRequest->wValue & 0xff) + ? MGC_STATE_CONFIGURED : MGC_STATE_ADDRESS; + handled=0; /* pass it to the gadget */ + break; + + case USB_REQ_SET_ADDRESS: + /* remember state & handle on the end status stage interrupt */ + DBG(3, "USB_REQ_SET_ADDRESS(0x%x)\n",(uint8_t) + (pControlRequest->wValue & 0x7f)); + + pThis->bSetAddress = TRUE; + pThis->bAddress = (uint8_t)(pControlRequest->wValue & 0x7f); + pThis->bDeviceState = MGC_STATE_ADDRESS; + break; + + case USB_REQ_CLEAR_FEATURE: + DBG(3, "USB_REQ_CLEAR_FEATURE()\n"); + + switch (bRecip) { + + case USB_RECIP_DEVICE: + DBG(3, "USB_RECIP_DEVICE()\n"); + break; + + case USB_RECIP_INTERFACE: + DBG(3, "USB_RECIP_INTERFACE()\n"); + break; + + case USB_RECIP_ENDPOINT: { + const uint8_t bEnd = (uint8_t)pControlRequest->wIndex & 0x7f ; + MGC_GadgetLocalEnd* pEnd=&MGC_aGadgetLocalEnd[ bEnd ]; + + DBG(-1, "CLEAR_FEATURE: USB_RECIP_ENDPOINT() %d\n", bEnd ); + MGC_GadgetSetHalt( &pEnd->end_point, 0); + /* select ep0 again */ + MGC_SelectEnd(pBase, 0); + } + break; + + default: + break; + } + break; /* END: CLEAR_FEATURE */ + + case USB_REQ_SET_FEATURE: + DBG(3, "USB_REQ_SET_FEATURE()\n"); + + switch (bRecip) { + + case USB_RECIP_DEVICE: + DBG(3, "USB_RECIP_DEVICE()\n"); + + switch (pControlRequest->wValue) { + + case 1: + DBG(3, "REMOTE_WAKEUP()\n"); + while (0) { } /* remote wakeup */ + break; + + case 2: + if (pControlRequest->wIndex & 0xff) { + handled=-EINVAL; + } else { + uint16_t wTest; + + DBG(3, "ENTERING TESTMODE\n"); + pThis->bTestMode = TRUE; + wTest = (uint8_t)pControlRequest->wIndex >> 8; + switch(wTest) { + + case 1: + DBG(3, "TEST_J\n"); + /* TEST_J */ + pThis->bTestModeValue = MGC_M_TEST_J; + break; + + case 2: + /* TEST_K */ + DBG(3, "TEST_K\n"); + pThis->bTestModeValue = MGC_M_TEST_K; + break; + + case 3: + /* TEST_SE0_NAK */ + DBG(3, "TEST_SE0_NAK\n"); + pThis->bTestModeValue = MGC_M_TEST_SE0_NAK; + break; + + case 4: + /* TEST_PACKET */ + DBG(3, "TEST_PACKET\n"); + pThis->bTestModeValue = MGC_M_TEST_PACKET; + break; + + default: + /* my gadget might know what to do with it */ + break; + } + } + break; +#ifdef MUSB_OTG + case 3: + GADGET_SET_B_HNP_ENABLE(pThis->pGadget, 1); + MGC_OtgMachineSetFeature(&(pThis->OtgMachine), + pControlRequest->wValue); + break; + + case 4: + GADGET_SET_A_HNP_SUPPORT(pThis->pGadget, 1); + MGC_OtgMachineSetFeature(&(pThis->OtgMachine), + pControlRequest->wValue); + break; + + case 5: + GADGET_SET_A_ALT_HNP_SUPPORT(pThis->pGadget, 1); + MGC_OtgMachineSetFeature(&(pThis->OtgMachine), + pControlRequest->wValue); + break; +#endif + } + break; + + case USB_RECIP_INTERFACE: + DBG(3, "USB_RECIP_INTERFACE()\n"); + break; + + case USB_RECIP_ENDPOINT: { + const uint8_t bEnd = (uint8_t)pControlRequest->wIndex & 0x7f ; + MGC_GadgetLocalEnd* pEnd=&MGC_aGadgetLocalEnd[ bEnd ]; + + DBG(3, "SET_FEATURE: USB_RECIP_ENDPOINT() %d\n", bEnd ); + MGC_GadgetSetHalt(&pEnd->end_point, 1); + + /* select ep0 again */ + MGC_SelectEnd(pBase, 0); + } + break; + + } + break; /* END: SET_FEATURE */ + + default: + handled=0; + break; + } + + /* standard request not handed by this code go to the gadget */ + if ( !handled ) { + handled=forward_to_driver(pControlRequest); + } + + DBG(-1002, "==>\n"); + return handled; +} + +/* ---------------------------------------------------------------------- */ + +/** + * Complete a request on enpdpoint 0. This is called after a competition + * IRQ on ep0 has occourred. + * @warning Executed @ interrupt time; complete CANNOT sleep. + */ +void mgc_complete_ep0_request(void) +{ + struct usb_request *pRequest; + MGC_LinuxCd* pThis=MGC_GetDriverByName(NULL); + +#ifdef MUSB_PARANOID + ASSERT_SPINLOCK_UNLOCKED(&pThis->Lock); + ASSERT_SPINLOCK_LOCKED(&MGC_aGadgetLocalEnd[0]); +#endif + + spin_lock( &MGC_aGadgetLocalEnd[0].Lock ); + pRequest=MGC_CurrentRequest( &MGC_aGadgetLocalEnd[0] ); + + DBG(3, "completing request pRequest=%p\n", pRequest); + + /* this is interrupt code, it cannot sleep! */ + if ( pRequest ) { + list_del( &pRequest->list ); + INIT_LIST_HEAD( &MGC_aGadgetLocalEnd[0].req_list ); + + spin_unlock( &MGC_aGadgetLocalEnd[0].Lock ); + if ( pRequest->complete ) { + pRequest->complete(&MGC_aGadgetLocalEnd[0].end_point, + pRequest); + } + } else { + spin_unlock( &MGC_aGadgetLocalEnd[0].Lock ); + } + + pThis->bEnd0Stage = MGC_END0_STAGE_SETUP; +} + +/** + * handle the completition interrupt on endpoint 0. + */ +static void handle_ep0_completition_irq(void) +{ + MGC_LinuxCd* pThis=MGC_GetDriverByName(NULL); + const uint8_t* pBase = (uint8_t*)pThis->pRegs; + + DBG(3, "<==\n"); + DBG(4, "post event interrupts ep0stage=%s\n", + decode_ep0stage(pThis->bEnd0Stage)); + +#ifdef MUSB_PARANOID + ASSERT_SPINLOCK_UNLOCKED(&pThis->Lock); + ASSERT_SPINLOCK_UNLOCKED(&MGC_aGadgetLocalEnd[0]); +#endif + + switch (pThis->bEnd0Stage) { + + /* end of sequence #2 (RX state) or #3 (no data) */ + case MGC_END0_STAGE_STATUSIN: + DBG(-1001, "MGC_END0_STAGE_STATUSIN request\n"); + + /* update address (if needed) only @ the end of the + * status phase per standard. The guide is WRONG! + */ + if(pThis->bSetAddress) { + pThis->bSetAddress = FALSE; + MGC_Write8(pBase, MGC_O_HDRC_FADDR, pThis->bAddress); +#ifdef MUSB_MONITOR_DATA + MGC_EnableDebug(); +#endif + } + + /* enter test mode if needed */ + if(pThis->bTestMode) { + DBG(-1001, "entering TESTMODE\n"); + + if (MGC_M_TEST_PACKET == pThis->bTestModeValue) { + MGC_HdrcLoadFifo(pBase, 0, sizeof(MGC_aTestPacket), + MGC_aTestPacket); + } + + spin_lock(&pThis->Lock); + MGC_SelectEnd(pBase, 0); /* select ep0 */ + MGC_Write8(pBase, MGC_O_HDRC_TESTMODE, + pThis->bTestModeValue); + spin_unlock(&pThis->Lock); + } + + DBG(-1001, "completing posted request (if any)\n"); + mgc_complete_ep0_request(); + break; + + /* sequence #1: write to host (TX state) */ + case MGC_END0_STAGE_STATUSOUT: + DBG(-1001, "completing posted request (if any)\n"); + mgc_complete_ep0_request(); + break; + + case MGC_END0_STAGE_TX: + DBG(-1001, "TX changeing ep status\n"); + if ( MGC_CurrentRequest(&MGC_aGadgetLocalEnd[0])->status!=-EINPROGRESS ) { + pThis->bEnd0Stage=MGC_END0_STAGE_STATUSOUT; + } + break; + + case MGC_END0_STAGE_RX: + DBG(-1001, "RX changeing ep status\n"); + if ( MGC_CurrentRequest(&MGC_aGadgetLocalEnd[0])->status!=-EINPROGRESS ) { + pThis->bEnd0Stage=MGC_END0_STAGE_STATUSIN; + } + break; + + default: /* IT WAS STALLED */ + DBG(-1002, "recovering from stall? ep0stage=%s\n", + decode_ep0stage(pThis->bEnd0Stage)); + pThis->bEnd0Stage = MGC_END0_STAGE_SETUP; + break; + } + + DBG(3, "==>\n"); +} + + +/* ---------------------------------------------------------------------- */ + +/** + * Handle ep0 in receive state. Called to start a receie and on each interrupt + * when receiving data on ep0. + */ +int ep0_rxstate(void) { + MGC_LinuxCd* pThis=MGC_GetDriverByName(NULL); + const uint8_t* pBase = (uint8_t*)pThis->pRegs; + MGC_GadgetLocalEnd* pEnd = &(MGC_aGadgetLocalEnd[0]); + struct usb_request *pRequest=MGC_CurrentRequest(pEnd); + + /* nothign for now */ + DBG(-1002, "<==\n"); + + if ( pRequest->actual==0 ) { + /* ack the request first */ + DBG(4, "acking request %s\n", decode_csr0(MGC_M_CSR0_P_SVDRXPKTRDY) ); + spin_lock(&pThis->Lock); + MGC_SelectEnd(pBase, 0); + MGC_WriteCsr16(pBase, MGC_O_HDRC_CSR0, 0, + MGC_M_CSR0_P_SVDRXPKTRDY); + spin_unlock(&pThis->Lock); + } + +#ifdef MUSB_PARANOID + ASSERT_SPINLOCK_UNLOCKED(&pThis->Lock); + ASSERT_SPINLOCK_LOCKED(&pEnd->Lock); +#endif + + DBG(-1002, "==>\n"); + + return 0; +} + +/** + * Handle ep0 in transmit state. Called to start a receie and on each interrupt + * when transmitting data on ep0. + */ +int ep0_txstate(void) +{ + unsigned long flags; + MGC_LinuxCd* pThis=MGC_GetDriverByName(NULL); + const uint8_t* pBase = (uint8_t*)pThis->pRegs; + MGC_GadgetLocalEnd* pEnd = &(MGC_aGadgetLocalEnd[0]); + struct usb_request *pRequest=MGC_CurrentRequest(pEnd); + uint16_t wCsrVal = MGC_M_CSR0_TXPKTRDY; + uint8_t* pFifoSource; + uint8_t wFifoCount; + + DBG(-1002, "<==\n"); + +#ifdef MUSB_PARANOID + if ( !pThis || !pRequest ) { + ERR("pThis=%p, pRequest=%p", pThis, pRequest); + return -EINVAL; + } +#endif + +#ifdef MUSB_PARANOID + ASSERT_SPINLOCK_UNLOCKED(&pThis->Lock); + ASSERT_SPINLOCK_LOCKED(&pEnd->Lock); +#endif + + spin_lock_irqsave(&pThis->Lock, flags); + MGC_SelectEnd(pBase, 0); + + if ( pRequest->actual==0 ) { + /* ack the request first */ + DBG(4, "acking request %s\n", decode_csr0(MGC_M_CSR0_P_SVDRXPKTRDY) ); + MGC_WriteCsr16(pBase, MGC_O_HDRC_CSR0, 0, + MGC_M_CSR0_P_SVDRXPKTRDY); + } + + /* load the data */ + pFifoSource = (uint8_t*)pRequest->buf+pRequest->actual; + wFifoCount =min((int)MGC_END0_FIFOSIZE, (int)(pRequest->length-pRequest->actual)); + MGC_HdrcLoadFifo(pBase, 0, wFifoCount, pFifoSource); + pRequest->actual+=wFifoCount; /* done */ + + /* update the flags */ + if ( wFifoCount < MUSB_MAX_END0_PACKET ) { + wCsrVal |= MGC_M_CSR0_P_DATAEND; + pRequest->status=0; /* done */ + } + + /* send it out! (this will trigger the ep0 completition IRQ) + * serviced in interrupt_complete() + */ + DBG(4, "wrote wFifoCount=%d bytes, wCsrVal=%s\n", wFifoCount, + decode_csr0(wCsrVal) ); + MGC_WriteCsr16(pBase, MGC_O_HDRC_CSR0, 0, wCsrVal); + spin_unlock_irqrestore(&pThis->Lock, flags); + + DBG(-1002, "==>\n"); + return 0; +} + +/* ---------------------------------------------------------------------- */ + +/** + * Handle ep0 interrupt of a device, lock & release pThis. This is the main + * entry point of the gadget Ep0 handling code. + * @param pThis the controller + */ +uint8_t MGC_HdrcServiceFunctionEp0(MGC_LinuxCd* pThis) +{ + uint16_t wCsrVal; /* */ + uint16_t wCount; /* bytes available */ + const uint8_t* pBase = (uint8_t*)pThis->pRegs; + + DBG(2, "<==\n"); + + spin_lock(&pThis->Lock); + MGC_SelectEnd(pBase, 0); /* select ep0 */ + wCsrVal = MGC_ReadCsr16(pBase, MGC_O_HDRC_CSR0, 0); + wCount = MGC_ReadCsr8(pBase, MGC_O_HDRC_COUNT0, 0); + + DEBUG_CODE(4, { uint8_t myaddr=MGC_Read8(pBase, MGC_O_HDRC_FADDR); \ + uint8_t devctl = MGC_Read8(pBase, MGC_O_HDRC_DEVCTL); \ + printk(KERN_INFO "%s: wCrsVal=0x%x, wCount=%d, myaddr=%0x, mode=%s, ep0stage=%s\n", \ + __FUNCTION__, wCsrVal, wCount, myaddr, decode_devctl(devctl), \ + decode_ep0stage(pThis->bEnd0Stage) ); } ); + + /* I sent a stall.. need to acknowledge it now.. */ + if(wCsrVal & MGC_M_CSR0_P_SENTSTALL) { + DBG(-1002, "acking stall while in ep0stage=%s\n", + decode_ep0stage(pThis->bEnd0Stage)); + + MGC_WriteCsr16(pBase, MGC_O_HDRC_CSR0, 0, + wCsrVal & ~MGC_M_CSR0_P_SENTSTALL ); + pThis->bEnd0Stage=MGC_END0_STAGE_SETUP; + } + + /* setup ended prematurely, abort it */ + if (wCsrVal & MGC_M_CSR0_P_SETUPEND) { + DBG(-1002, "acking setupend while in ep0stage=%s\n", + decode_ep0stage(pThis->bEnd0Stage)); + + /* clearing it */ + MGC_WriteCsr16(pBase, MGC_O_HDRC_CSR0, 0, + MGC_M_CSR0_P_SVDSETUPEND ); + pThis->bEnd0Stage=MGC_END0_STAGE_SETUP; + } + + spin_unlock(&pThis->Lock); + + /* handle completition interrupt */ + if ( !wCsrVal && !wCount ) { + handle_ep0_completition_irq(); + return TRUE; + } + + switch( pThis->bEnd0Stage ) { + /* done transmitting */ + case MGC_END0_STAGE_STATUSOUT: + case MGC_END0_STAGE_STATUSIN: + mgc_complete_ep0_request(); + break; + } + + switch( pThis->bEnd0Stage ) { + /* im alrewady writing to host, TX state, + * sequence #1 initiated during the setup + */ + case MGC_END0_STAGE_TX: + if ( wCsrVal & MGC_M_CSR0_TXPKTRDY ) { + DBG(-1001, "MGC_END0_STAGE_TX\n"); + ep0_txstate(); + } break; + + /* im alrewady receiving from host, RX state, + * sequence #2 initiated during the setup + */ + case MGC_END0_STAGE_RX: + if ( wCsrVal & MGC_M_CSR0_RXPKTRDY ) { + DBG(-1001, "MGC_END0_STAGE_RX\n"); + ep0_rxstate(); + } + break; + + /* received from host, RX State, header */ + case MGC_END0_STAGE_SETUP: + if ( wCsrVal & MGC_M_CSR0_RXPKTRDY ) { + int count=0, handled=0; + + count=MGC_ReadUSBControlRequest(pThis, wCount); + if ( count<0 ) { + /* ack the request */ + ERR("error reading the control request: this is bad (tm)\n"); + } else if ( 0==count ) { /* I got the full packet, GREAT! */ + struct usb_ctrlrequest *pControlRequest=(struct usb_ctrlrequest*) + pThis->pEnd0Buffer; + + DBG(-1002, "%s\n", decode_request(pControlRequest)); + + /* sequence #3 */ + if ( is_zerodata_request(pControlRequest) ) { + uint16_t wCsrVal= MGC_M_CSR0_P_SVDRXPKTRDY + | MGC_M_CSR0_P_DATAEND; + + pThis->bEnd0Stage = MGC_END0_STAGE_STATUSIN; + handled=service_zero_data_request(pThis, + pControlRequest); + if ( handled<0 && handled!=-EOPNOTSUPP ) { + wCsrVal |= MGC_M_CSR0_P_SENDSTALL; + } + + /* ack the request */ + DBG(3, "handled=%d, wCsrVal=%s, ep0stage=%s\n", handled, + decode_csr0(wCsrVal), + decode_ep0stage(pThis->bEnd0Stage) ); + + spin_lock(&pThis->Lock); + MGC_SelectEnd(pBase, 0); + MGC_WriteCsr16(pBase, MGC_O_HDRC_CSR0, 0, wCsrVal); + spin_unlock(&pThis->Lock); + } else { + /* sequence #1 */ + if ( is_tx_request(pControlRequest) ) { + /* write to host, a request is posted on ep0 */ + pThis->bEnd0Stage=MGC_END0_STAGE_TX; + handled=service_tx_request(pControlRequest); + /* sequence #2, a request is posted on ep0 */ + } else if ( is_rx_request(pControlRequest) ) { + pThis->bEnd0Stage=MGC_END0_STAGE_RX; + handled=service_rx_request(pControlRequest); + } + + if ( handled<0 ) { + /* stall it!!! application stall */ + spin_lock(&pThis->Lock); + MGC_SelectEnd(pBase, 0); + MGC_WriteCsr16(pBase, MGC_O_HDRC_CSR0, 0, + MGC_M_CSR0_P_SVDRXPKTRDY | MGC_M_CSR0_P_SENDSTALL); + spin_unlock(&pThis->Lock); + } + } + + } + } else { + + } + break; + + + /* handle the application stall on Ep0 */ + default: + { + uint16_t wCsrVal = MGC_M_CSR0_P_SENDSTALL; + + switch ( pThis->bEnd0Stage & ~MGC_END0_STAGE_STALL_BIT ) { + + case MGC_END0_STAGE_TX: + wCsrVal|=MGC_M_CSR0_TXPKTRDY; + break; + + case MGC_END0_STAGE_RX: + wCsrVal|=MGC_M_CSR0_RXPKTRDY; + break; + + } + + DBG(3, "Application stall from ep0stage=%s\n", + decode_ep0stage(pThis->bEnd0Stage)); + spin_lock(&pThis->Lock); + MGC_SelectEnd(pBase, 0); + MGC_WriteCsr16(pBase, MGC_O_HDRC_CSR0, 0, wCsrVal); + spin_unlock(&pThis->Lock); + + pThis->bEnd0Stage = MGC_END0_STAGE_SETUP; + } + break; + } + + return 1; +} --- /dev/null +++ linux-2.6.20/drivers/usb/nomadik/logx @@ -0,0 +1 @@ +make: *** No rule to make target `vmlinux'. Stop. --- /dev/null +++ linux-2.6.20/drivers/usb/nomadik/musb_bus_direct.c @@ -0,0 +1,371 @@ +/* + * linux/drivers/usb/nomadik/musb_bus_direct.c + * + * Copyright 2007, STMicroelectronics + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +#include "musbdefs.h" +#include + +#ifdef MUSB_BOARD_FILE +#include CONFIG_USB_INVENTRA_MUSB_BOARD_FILE +#else +#include "board.h" +#endif + +#ifndef MUSB_BOARD_DEFAULT_SIZE +#define MUSB_DEFAULT_ADDRESS_SPACE_SIZE 0x00001000 +#endif + +#ifdef MUSB_V26 +#include +#endif + +/****************************** sysfs stuff *****************************/ + +#define kobj_to_direct_driver(obj) container_of(obj, struct device_driver, kobj) +#define attr_to_driver_attribute(obj) container_of(obj, struct driver_attribute, attr) + +/**************************** instance vars *****************************/ + +#ifndef MUSB_USE_HCD_DRIVER +static int MGC_InstancesCount=0; +static MGC_LinuxCd** MGC_DriverInstances; +#endif + +void *g_pDevice; +/********************* under 26 thigs changes a bit *************************/ + +#ifdef MUSB_V26 +#if 1 +struct device MGC_ControllerDevice = +{ + +}; + +struct device_driver MGC_ControllerDriver= +{ + .name = "musb-hcd", +}; +#endif + +#ifndef MUSB_USE_HCD_DRIVER + +static inline ssize_t +store_new_id(struct device_driver *driver, const char *buf, size_t count); + + +static DRIVER_ATTR(new_id, S_IWUSR, NULL, store_new_id); + +static ssize_t driver_count=0; + +/* probably we don't need to be a system device in this case */ +struct device MGC_ControllerDevice = +{ + +}; + +struct device_driver MGC_ControllerDriver= +{ + .name = "musb-hcd", +}; + +/** + * store_new_id + * + * Adds a new dynamic device ID to this driver, + * and causes the driver to probe for all devices again. + */ +static inline ssize_t +store_new_id(struct device_driver *driver, const char *buf, size_t count) +{ + return driver_count++; +} + + +static ssize_t +direct_driver_attr_store(struct kobject * kobj, struct attribute *attr, + const char *buf, size_t count) +{ + struct device_driver *driver = kobj_to_direct_driver(kobj); + struct driver_attribute *dattr = attr_to_driver_attribute(attr); + ssize_t ret = 0; + + if (get_driver(driver)) { + if (dattr->store) + ret = dattr->store(driver, buf, count); + put_driver(driver); + } + return ret; +} + +static ssize_t +direct_driver_attr_show(struct kobject * kobj, struct attribute *attr, char *buf) +{ + struct device_driver *driver = kobj_to_direct_driver(kobj); + struct driver_attribute *dattr = attr_to_driver_attribute(attr); + ssize_t ret = 0; + + if ( get_driver(driver) ) { + if (dattr->show) + ret = dattr->show(driver, buf); + put_driver(driver); + } + return ret; +} + +static struct sysfs_ops direct_driver_sysfs_ops = { + .show = direct_driver_attr_show, + .store = direct_driver_attr_store, +}; +static struct kobj_type direct_driver_kobj_type = { + .sysfs_ops = &direct_driver_sysfs_ops, +}; + +static int +direct_create_newid_file(struct device_driver *drv) +{ + int error = 0; + if (drv->probe != NULL) + error = sysfs_create_file(&drv->kobj, + &driver_attr_new_id.attr); + return error; +} + +static int +direct_populate_driver_dir(struct device_driver *drv) +{ + return direct_create_newid_file(drv); +} + +/* ------------------------ let the ball rolling -------------------------*/ + +/* customize for different behavior */ +static int direct_hotplug (struct device *dev, char **envp, int num_envp, + char *buffer, int buffer_size) +{ + return -ENODEV; +} + +static int direct_device_suspend(struct device * dev, u32 state) +{ + return 0; +} + +/* customize for different behavior */ +static int direct_device_resume(struct device * dev) +{ + return 0; +} + +static int direct_bus_match(struct device * dev, struct device_driver * drv) { + return (&MGC_ControllerDriver==drv)?1:0; +} + +struct bus_type direct_bus_type = { + .name = "system", + .match = direct_bus_match, + .hotplug = direct_hotplug, + .suspend = direct_device_suspend, + .resume = direct_device_resume, +}; + +/** + * direct_register_driver - register a new driver + * @drv: the driver structure to register + * + * Adds the driver structure to the list of registered drivers + * Returns the number of devices which were claimed by the driver + * during registration. The driver remains registered even if the + * return value is zero. + */ +static int +direct_register_driver(struct device_driver *drv, struct bus_type *btype) +{ + int count = 0; + + /* initialize common driver fields */ + drv->bus = (btype)?btype:&direct_bus_type; + drv->kobj.ktype = &direct_driver_kobj_type; + + /* register with core */ + count = driver_register( drv ); + if (count >= 0) { + direct_populate_driver_dir( drv ); + } + + return count ? count : 1; +} + +/** + * unregister_driver - unregister a driver + * @drv: the driver structure to unregister + * + * Deletes the driver structure from the list of registered drivers, + * gives it a chance to clean up by calling its remove() function for + * each device it was responsible for, and marks those devices as + * driverless. + */ + +static void +direct_unregister_driver(struct device_driver *drv) +{ + driver_unregister( drv ); +} + +#endif +#endif + +/* ------------------------------------------------------------------- */ +/* ------------------------------------------------------------------- */ +/* ------------------------------------------------------------------- */ + +#ifdef MUSB_CUSTOM_DIRECT_BUS_FILE +#include MUSB_CUSTOM_DIRECT_BUS_FILE +#else +/** + * Discover and initialize the drivers on the direct bus. + */ +int +direct_bus_init(void) { + + int rc= -1; + char name[32]; + void* pDevice = NULL; + +#ifdef MUSB_USE_HCD_DRIVER + MGC_LinuxCd* pThis; + + /* already initialized */ + if ( MGC_nIndex ) { + return 0; + } + snprintf(name, 32, "musbhdrc%d", MGC_nIndex++); + + pDevice = &MGC_ControllerDevice; + g_pDevice=pDevice; + kobject_set_name(&((struct device*)pDevice)->kobj, "musbdev"); + + rc = kobject_register(&((struct device*)pDevice)->kobj); + + if(rc < 0){ + ERR("failed to register:%d\n", rc); + return rc; + } + + INIT_LIST_HEAD( (struct list_head*)&((struct device*)pDevice)->klist_children ); + + ((struct device *)pDevice)->driver = &MGC_ControllerDriver; + + sprintf (&((struct device *)pDevice)->bus_id[0], "usb%d", rc); + + pThis = MGC_LinuxInitController(pDevice, MUSB_CONTROLLER_HDRC, INT_USBOTG, + ioremap(NOMADIK_USB_BASE, 0x100000), 0x00100000, name); + + if(pThis) { + DBG(3, "MGC_LinuxInitController success MGC_struct:0x%p \n", pThis); + rc = 0; + MGC_VirtualHubStart( &(pThis->RootHub) ); + } + return(rc); + +#else + const int nCount = sizeof(MUSB_aLinuxController) + / sizeof(MUSB_LinuxController); + int nIndex; + + INFO("Probing direct bus [direct=%d]\n", nCount); + + if ( !nCount ) { + return 0; + } + + KMALLOC(MGC_DriverInstances, nCount*sizeof(MGC_LinuxCd*), GFP_ATOMIC); + if ( !MGC_DriverInstances ) { + return -ENOMEM; + } + +#ifdef MUSB_V26 + pDevice = &MGC_ControllerDevice; + kobject_set_name(&((struct device*)pDevice)->kobj, "musbdev"); + rc = kobject_register(&((struct device*)pDevice)->kobj); + if(rc < 0){ + ERR("failed to register:%d\n", rc); + return rc; + } + + INIT_LIST_HEAD( &((struct device*)pDevice)->children ); + + ((struct device *)pDevice)->driver = &MGC_ControllerDriver; + sprintf (&((struct device *)pDevice)->bus_id[0], "usb%d", rc); + bus_register( &direct_bus_type ); + direct_register_driver(&MGC_ControllerDriver, NULL); +#endif + + /* NON PCI machines */ + for (nIndex = 0; !rc && nIndex < nCount; nIndex++) { + MUSB_LinuxController* pStaticController=&(MUSB_aLinuxController[nIndex]); + + snprintf(name, 32, "musbhdrc%d", MGC_nIndex++); + MGC_DriverInstances[nIndex]=MGC_LinuxInitController(pDevice, + pStaticController->wType, pStaticController->dwIrq, + pStaticController->pBase, + (pStaticController->dwSize)? pStaticController->dwSize + : MUSB_DEFAULT_ADDRESS_SPACE_SIZE, name); + + if( MGC_DriverInstances[nIndex] ) { +#ifdef MUSB_VIRTHUB + MGC_VirtualHubStart( &(MGC_DriverInstances[nIndex]->RootHub) ); +#endif + MGC_InstancesCount++; + } else { + ERR("controller %d failed to initialize\n", nIndex); + direct_bus_shutdown(); + rc=-1; + } + } + return MGC_InstancesCount; +#endif + +} + +/** + * + */ +void direct_bus_shutdown(void) +{ +#ifdef MUSB_USE_HCD_DRIVER + kobject_unregister(&((struct device*)g_pDevice)->kobj); /* shoudl check the hcd drivers */ + + +#else + int nIndex=0; + + /* free the instances */ + for (nIndex = 0; nIndex < MGC_InstancesCount; nIndex++) { + MGC_LinuxCdFree( MGC_DriverInstances[nIndex] ); + } + + KFREE(MGC_DriverInstances); +#ifdef MUSB_V26 + direct_unregister_driver(&MGC_ControllerDriver); +#endif +#endif + +} +#endif --- /dev/null +++ linux-2.6.20/drivers/usb/nomadik/musb_cross.h @@ -0,0 +1,131 @@ +/* + * linux/drivers/usb/nomadik/musb_cross.h + * + * Copyright 2007, STMicroelectronics + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __MUSB_CROSS_H +#define __MUSB_CROSS_H + +#include + +/****************************** KERNEL VERSION MACROS ************************/ + +#if ( LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) && LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) ) +#undef MUSB_V26 + +#ifndef MUSB_V24 +#define MUSB_V24 +#endif + +#endif + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) +#undef MUSB_V24 +#ifndef MUSB_V26 +#define MUSB_V26 +#endif +#endif + +#ifdef MUSB_V26 + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,11) +#ifndef MUSB_V26_POST10 +#define MUSB_V26_POST10 +#endif +#endif + + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,12) +#ifndef MUSB_USE_HCD_DRIVER +#define MUSB_USE_HCD_DRIVER +#endif +#endif + +#endif + + +/*********************************** WEIRDNESS ******************************/ + +#ifdef MUSB_V26_POST10 +#define MUSB_MEMFLAG_TYPE unsigned int +#else +#define MUSB_MEMFLAG_TYPE int +#endif + +/****************************** SYSTEM PROPERTIES ***************************/ + +#if defined(MUSB_V26) || defined(MUSB_V24) +#define MUSB_HAS_BUSNAME +#endif + +#ifndef MUSB_LINUX_MV21 +#define HAS_USB_TT_MULTI +#endif + +#ifdef CONFIG_PREEMPT +/* warning??? */ +#endif + +/* gstorage is liked to the driver: the init code lives there */ +#ifdef MUSB_GSTORAGE +#define MUSB_SKIP_INIT +#endif + +/* When compiled in the kernel, the init function is needed only when gadget + * gadget API is not compiled (usb_register_driver takes care of the init) + */ +#if defined(MUSB_BUILTIN) && !defined(MUSB_GADGET) +#ifndef MUSB_SKIP_INIT +#define MUSB_SKIP_INIT +#endif +#endif + +/* -------------------------------- OTG ----------------------------- */ + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,10) +#define MUSB_HAS_OTG +#define HAS_HNP_SUPPORT +#endif + +/* -------------------------------- DMA ----------------------------- */ + +#define DMA_ADDR_INVALID (~(dma_addr_t)0) + +/* MVL21 doesn't support DMA */ +#if defined(MUSB_LINUX_MV21) +#ifdef MUSB_DMA +#error "DMA Mode not supported in MontaVista 2.1" +#endif + +/* DMA supported from 2.4 'till 2.6.10 */ +#elif defined(MUSB_V24) || (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,9)) +#ifndef MUSB_HAS_DMA_URBS +#define MUSB_HAS_DMA_URBS +#endif + +/* DMA not supported on versions >= 2.6.10 */ +#elif ( LINUX_VERSION_CODE > KERNEL_VERSION(2,6,13) ) + +#ifdef MUSB_DMA +#error "DMA Mode MIGHT not be supported in kernels > 2.6.10" +#endif + +#endif + +/* -------------------------------- GADGETS ----------------------------- */ +#endif --- /dev/null +++ linux-2.6.20/drivers/usb/nomadik/musb_debug.c @@ -0,0 +1,190 @@ +/* + * linux/drivers/usb/nomadik/musb_debug.c + * + * Copyright 2007, STMicroelectronics + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include +#include + +#include + +#include "debug.h" +#include "musbdefs.h" + +#define IPRINTF(_f, _m) printk(KERN_INFO "%s"_f, indent, _m) +#define isspace(c) (c==' ' || c=='\t') +#define LABEL KERN_INFO "dump: " + +/******************************************************************/ + +int MGC_DebugLevel=MUSB_DEBUG; +int MGC_DebugDisable=0; + +/******************************************************************/ + +/* Decode CSR0 value to a string. Not reentrant + */ +char *decode_csr0(uint16_t csr0) { + static char buf[64]; + sprintf(buf, "(%s%s%s%s)", + csr0&MGC_M_CSR0_TXPKTRDY ? "[TXPKTRDY]":"", + csr0&MGC_M_CSR0_P_SVDRXPKTRDY ? "[SVDRXPKTRDY]":"", + csr0&MGC_M_CSR0_P_SENDSTALL ? "[stalled]":"", + csr0&MGC_M_CSR0_P_DATAEND ? "[dataend]":""); + return buf; +} + +/* Decode a value to binary. + */ +char *decode_bits(uint16_t value) { + int i=0; + static char buf[64]; + + for (; i<16;i++) { + buf[15-i]=(value&(1<urb_list)); +#ifdef V24 + printk (LABEL "next :%p\n", purb->next); +#endif + printk (LABEL "dev :%p\n", purb->dev); + printk (LABEL "pipe :%08X\n", purb->pipe); + printk (LABEL "status :%d\n", purb->status); + printk (LABEL "transfer_flags :%08X\n", purb->transfer_flags); + printk (LABEL "transfer_buffer :%p\n", purb->transfer_buffer); + printk (LABEL "transfer_buffer_length:%d\n", purb->transfer_buffer_length); + printk (LABEL "actual_length :%d\n", purb->actual_length); + printk (LABEL "setup_packet :%p\n", purb->setup_packet); + printk (LABEL "start_frame :%d\n", purb->start_frame); + printk (LABEL "number_of_packets :%d\n", purb->number_of_packets); + printk (LABEL "interval :%d\n", purb->interval); + printk (LABEL "error_count :%d\n", purb->error_count); + printk (LABEL "context :%p\n", purb->context); + printk (LABEL "complete :%p\n", purb->complete); +} + +/** + * Dump core registers whose reads are non-destructive. + * @param pThis + * @param bEnd + */ +void MGC_HdrcDumpRegs(uint8_t* pBase, int multipoint, uint8_t bEnd) +{ + MGC_SelectEnd(pBase, bEnd); + + if(!bEnd) { + printk(KERN_INFO " 0: CSR0=%04x, Count0=%02x, Type0=%02x, NAKlimit0=%02x\n", + MGC_ReadCsr16(pBase, MGC_O_HDRC_CSR0, 0), + MGC_ReadCsr8(pBase, MGC_O_HDRC_COUNT0, 0), + MGC_ReadCsr8(pBase, MGC_O_HDRC_TYPE0, 0), + MGC_ReadCsr8(pBase, MGC_O_HDRC_NAKLIMIT0, 0)); + } else { + printk(KERN_INFO "%2d: TxCSR=%04x, TxMaxP=%04x, TxType=%02x, TxInterval=%02x\n", + bEnd, + MGC_ReadCsr16(pBase, MGC_O_HDRC_TXCSR, bEnd), + MGC_ReadCsr16(pBase, MGC_O_HDRC_TXMAXP, bEnd), + MGC_ReadCsr8(pBase, MGC_O_HDRC_TXTYPE, bEnd), + MGC_ReadCsr8(pBase, MGC_O_HDRC_TXINTERVAL, bEnd)); + printk(KERN_INFO " RxCSR=%04x, RxMaxP=%04x, RxType=%02x, RxInterval=%02x, RxCount=%04x\n", + MGC_ReadCsr16(pBase, MGC_O_HDRC_TXCSR, bEnd), + MGC_ReadCsr16(pBase, MGC_O_HDRC_TXMAXP, bEnd), + MGC_ReadCsr8(pBase, MGC_O_HDRC_TXTYPE, bEnd), + MGC_ReadCsr8(pBase, MGC_O_HDRC_TXINTERVAL, bEnd), + MGC_ReadCsr16(pBase, MGC_O_HDRC_RXCOUNT, bEnd)); + } + + if( multipoint) { + printk(KERN_INFO " TxAddr=%02x, TxHubAddr=%02x, TxHubPort=%02x\n", + MGC_Read8(pBase, MGC_BUSCTL_OFFSET(bEnd, MGC_O_HDRC_TXFUNCADDR)), + MGC_Read8(pBase, MGC_BUSCTL_OFFSET(bEnd, MGC_O_HDRC_TXHUBADDR)), + MGC_Read8(pBase, MGC_BUSCTL_OFFSET(bEnd, MGC_O_HDRC_TXHUBPORT))); + printk(KERN_INFO " RxAddr=%02x, RxHubAddr=%02x, RxHubPort=%02x\n", + MGC_Read8(pBase, MGC_BUSCTL_OFFSET(bEnd, MGC_O_HDRC_RXFUNCADDR)), + MGC_Read8(pBase, MGC_BUSCTL_OFFSET(bEnd, MGC_O_HDRC_RXHUBADDR)), + MGC_Read8(pBase, MGC_BUSCTL_OFFSET(bEnd, MGC_O_HDRC_RXHUBPORT))); + } +} + + +/* list related */ + +/* + * NOT REENTRANT! + */ +char *dump_node(struct list_head *node) { + static char buf[64]; + sprintf(buf, "[n=%p,p=%p]", node->next, node->prev); + return buf; +} + + --- /dev/null +++ linux-2.6.20/drivers/usb/nomadik/musb_epdescriptors.h @@ -0,0 +1,48 @@ +/* + * linux/drivers/usb/nomadik/musb_epdescriptors.h + * + * Copyright 2007, STMicroelectronics + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +struct MUSB_EpFifoDescriptor MUSB_aEpFifoDescriptors[MUSB_C_NUM_EPS] = { + +{}, /* EP0 use the default */ +{ MUSB_EPD_T_BULK, MUSB_EPD_D_TX, 512 }, +{ MUSB_EPD_T_BULK, MUSB_EPD_D_RX, 512 }, +{ MUSB_EPD_T_INTR, MUSB_EPD_D_RX, 512 } +}; + +/** +struct MGC_EpFifoDescriptor { + uint8_t bType; 0 for autoconfig, CNTR, ISOC, BULK, INTR + uint8_t bDir; 0 for autoconfig, INOUT, IN, OUT + uint16_t wSize; 0 for autoconfig, or the size + uint 8_t bDbe; double buffering 0 disabled, 1 enabled +}; + +#define MUSB_EPD_AUTOCONFIG 0 + +#define MUSB_EPD_T_CNTRL 1 +#define MUSB_EPD_T_ISOC 2 +#define MUSB_EPD_T_BULK 3 +#define MUSB_EPD_T_INTR 4 + +#define MUSB_EPD_D_INOUT 0 +#define MUSB_EPD_D_TX 1 +#define MUSB_EPD_D_RX 2 +*/ + --- /dev/null +++ linux-2.6.20/drivers/usb/nomadik/musb_epfifocfg.c @@ -0,0 +1,429 @@ +/* + * linux/drivers/usb/nomadik/musb_epfifocfg.c + * + * Copyright 2007, STMicroelectronics + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "musbdefs.h" +#include "musb_epdescriptors.h" + +#ifdef MUSB_EPFIFOCONFIG_FILE +#include CONFIG_USB_INVENTRA_MUSB_EPFIFOCONFIG_FILE +#endif + +#define DYN_FIFO_SIZE (1<<(MUSB_C_RAM_BITS+2)) +#define CONFIGURE_FIFO(_pThis, _pEnd, _Dsc, _wFifoOffset) \ + configure_fifo(_pThis, _pEnd, (_Dsc)->bDir, (_Dsc)->wSize, (_Dsc)->bDbe, _wFifoOffset) + + +/* force array based */ +#ifdef MUSB_C_DYNFIFO_DEF + +#ifdef MUSB_EPDISCRIPTORS_FILE +/** + * configure the fifo and make sure the pThis endmask is updated. + * + * @param pThis + * @param pEnd the end to configure + * @param bDir the direction (in, out, inout) + * @param wSize the fifo size, real fifo size + * @param bDbe double buffering enabled? + * @param wFifoOffset the current offset + */ +static uint16_t configure_fifo(MGC_LinuxCd* pThis, MGC_LinuxLocalEnd* pEnd, + uint8_t bDir, uint16_t wSize, uint8_t bDbe, uint16_t wFifoOffset) +{ + uint16_t offset=wSize; + void* pBase = pThis->pRegs; + uint8_t szValue=wSize>>3; + uint16_t addValue=wFifoOffset>>3; + + /* when double buffering is enabled endpoint needs twice the size */ + if (bDbe) { + szValue |= (1<<4); + offset*=2; + } + + /* configure the FIFO */ + MGC_SelectEnd(pBase, pEnd->bEnd); + switch ( bDir ) { + case MUSB_EPD_D_TX: + MGC_Write8(pBase, MGC_O_HDRC_TXFIFOSZ, 0x6); + MGC_Write16(pBase, MGC_O_HDRC_TXFIFOADD, 64 >> 3); + + pEnd->wMaxPacketSizeTx = wSize; + pEnd->wMaxPacketSizeRx = 0; + pEnd->bIsSharedFifo = FALSE; + break; + case MUSB_EPD_D_RX: + MGC_Write8(pBase, MGC_O_HDRC_RXFIFOSZ, 0x6); + MGC_Write16(pBase, MGC_O_HDRC_RXFIFOADD, (64 + 512 ) >> 3); + + pEnd->wMaxPacketSizeTx = 0; + pEnd->wMaxPacketSizeRx = wSize; + pEnd->bIsSharedFifo = FALSE; + break; + case MUSB_EPD_D_INOUT: + MGC_Write8(pBase, MGC_O_HDRC_TXFIFOSZ, szValue); + MGC_Write16(pBase, MGC_O_HDRC_TXFIFOADD, addValue); + + MGC_Write8(pBase, MGC_O_HDRC_RXFIFOSZ, szValue); + MGC_Write16(pBase, MGC_O_HDRC_RXFIFOADD, addValue); + + pEnd->wMaxPacketSizeTx=pEnd->wMaxPacketSizeRx=wSize; + pEnd->bIsSharedFifo = TRUE; + break; + + default: + ERR("direction %d not supported\n", bDir); + offset=0; + break; + } + + /* make sure the endmask is right */ + if ( offset ) { + pThis->wEndMask |= (1 << pEnd->bEnd); + } + + /* TODO: flush the FIFO after an ep size change */ + + + return offset; +} + +/** + * Configure the end points for DYNAMIC FIFO: array based End point + * configuration. + * @param pThis the controller + */ +void MGC_HdrcConfigureEps(MGC_LinuxCd* pThis) { + uint8_t bEnd, bSkip; + MGC_LinuxLocalEnd* pEnd; + uint16_t wFifoOffset=0; + + /* use the defined end points */ + pThis->bEndCount=MUSB_C_NUM_EPS; + +#ifdef MUSB_PARANOID + if ( MUSB_aEpFifoDescriptors[0].bType!=MUSB_EPD_T_CNTRL + && MUSB_aEpFifoDescriptors[0].bType!=MUSB_EPD_AUTOCONFIG) + { + WARN("ep0 must be control with fixed size of %d\n", + MGC_END0_FIFOSIZE); + } +#endif + + /* entry 0 is ep0, the default control endpoint */ + for (bEnd=0; bEndaLocalEnd[bEnd]); + pEnd->bEnd=bEnd; + pEnd->bIsSharedFifo = FALSE; + pEnd->wMaxPacketSizeTx=pEnd->wMaxPacketSizeRx=0; + + switch ( MUSB_aEpFifoDescriptors[bEnd].bType ) { + case MUSB_EPD_T_CNTRL: + if ( bEnd ) { + bSkip=1; + WARN("Control ep when ep!=0 (ep%d); skipping\n", bEnd); + } + break; + + case MUSB_EPD_T_ISOC: break; + + case MUSB_EPD_T_BULK: + switch ( MUSB_aEpFifoDescriptors[bEnd].bDir ) { + case MUSB_EPD_D_TX: pThis->bBulkTxEnd = bEnd; break; + case MUSB_EPD_D_RX: pThis->bBulkRxEnd = bEnd; break; + case MUSB_EPD_D_INOUT: + WARN("INOUTBULK: sharing ep%d\n", bEnd); + break; + default: + bSkip=1; + ERR("direction %d not supported for ep%d\n", + MUSB_aEpFifoDescriptors[bEnd].bDir, bEnd); + break; + } + break; + + case MUSB_EPD_T_INTR: break; + case MUSB_EPD_AUTOCONFIG: break; + + default: + bSkip=1; + ERR("ep%d type %d not supported\n", bEnd, + MUSB_aEpFifoDescriptors[bEnd].bType); + break; + } + + if ( !MUSB_aEpFifoDescriptors[bEnd].wSize ) { + continue; /* postpone to autoconfig */ + } + + if ( !bSkip ) { + uint16_t offset=CONFIGURE_FIFO(pThis, &(pThis->aLocalEnd[bEnd]), + &MUSB_aEpFifoDescriptors[bEnd], wFifoOffset ); + if ( offset ) { + wFifoOffset += offset; + } + } + + } + +#ifdef MUSB_PARANOID + if ( wFifoOffset > 64 ) { + ERR("Allocated %d bytes, more than the allowed %d\n", + wFifoOffset, 64); + } else { + INFO("Allocated %d bytes, out of %d\n", wFifoOffset, + 64); + } +#endif + +} + +#else +/** + * Configure the end points for DYNAMIC FIFO (old method). + * @param pThis the controller + */ +void MGC_HdrcConfigureEps(MGC_LinuxCd* pThis) { + uint8_t bEnd=1; + MGC_LinuxLocalEnd* pEnd; + void* pBase = pThis->pRegs; + uint16_t wFifoOffset=MGC_END0_FIFOSIZE; + + DBG(2, "<==\n"); + + /* use the defined end points */ + pThis->bEndCount=MUSB_C_NUM_EPS; + + /* Dynamic FIFO sizing: use pre-computed values for EP0 */ + MGC_SelectEnd(pBase, 0); + MGC_Write8(pBase, MGC_O_HDRC_TXFIFOSZ, 3); + MGC_Write8(pBase, MGC_O_HDRC_RXFIFOSZ, 3); + MGC_Write16(pBase, MGC_O_HDRC_TXFIFOADD, 0); + MGC_Write16(pBase, MGC_O_HDRC_RXFIFOADD, 0); + pThis->wEndMask = 1; + +#if MGC_DFIFO_ISO_TX >= 0 + MGC_SelectEnd(pBase, bEnd); + pEnd = &(pThis->aLocalEnd[bEnd]); + pEnd->bEnd=bEnd; + + /* reserve ISO Tx */ + MGC_Write8(pBase, MGC_O_HDRC_TXFIFOSZ, MGC_DFIFO_ISO_TX_VAL); + pEnd->wMaxPacketSizeTx = 1 << ((MGC_DFIFO_ISO_TX_VAL & 0xf)+3+(MGC_DFIFO_ISO_TX_VAL>>4)); + pEnd->wMaxPacketSizeRx = 0; + MGC_Write16(pBase, MGC_O_HDRC_TXFIFOADD, wFifoOffset >> 3); + /* move to next */ + wFifoOffset += pEnd->wMaxPacketSizeTx; + pEnd->bIsSharedFifo = FALSE; + pThis->wEndMask |= (1 << bEnd); + bEnd++; +#endif + +#if MGC_DFIFO_ISO_RX >= 0 + MGC_SelectEnd(pBase, bEnd); + pEnd = &(pThis->aLocalEnd[bEnd]); + pEnd->bEnd=bEnd; + + /* reserve ISO Rx */ + MGC_Write8(pBase, MGC_O_HDRC_RXFIFOSZ, MGC_DFIFO_ISO_RX_VAL); + pEnd->wMaxPacketSizeTx = 0; + pEnd->wMaxPacketSizeRx = 1 << ((MGC_DFIFO_ISO_RX_VAL & 0xf)+3+(MGC_DFIFO_ISO_RX_VAL>>4)); + MGC_Write16(pBase, MGC_O_HDRC_RXFIFOADD, wFifoOffset >> 3); + + /* move to next */ + wFifoOffset += pEnd->wMaxPacketSizeRx; + pEnd->bIsSharedFifo = FALSE; + pThis->wEndMask |= (1 << bEnd); + bEnd++; +#endif + + MGC_SelectEnd(pBase, bEnd); + pEnd = &(pThis->aLocalEnd[bEnd]); + pEnd->bEnd=bEnd; + + /* reserve bulk */ + pEnd->wMaxPacketSizeRx= 0; + pEnd->wMaxPacketSizeTx = 1 << ((MGC_DFIFO_BLK_VAL & 0xf)+3+(MGC_DFIFO_BLK_VAL>>4)); + MGC_Write8(pBase, MGC_O_HDRC_TXFIFOSZ, MGC_DFIFO_BLK_VAL); + MGC_Write16(pBase, MGC_O_HDRC_TXFIFOADD, wFifoOffset >> 3); + pThis->bBulkTxEnd = bEnd; + /* move to next */ + wFifoOffset += pEnd->wMaxPacketSizeTx; + pThis->wEndMask |= (1 << bEnd); + bEnd++; + + MGC_SelectEnd(pBase, bEnd); + pEnd = &(pThis->aLocalEnd[bEnd]); + pEnd->bEnd=bEnd; + + pEnd->wMaxPacketSizeTx= 0; + pEnd->wMaxPacketSizeRx = 1 << ((MGC_DFIFO_BLK_VAL & 0xf)+3+(MGC_DFIFO_BLK_VAL>>4)); + MGC_Write8(pBase, MGC_O_HDRC_RXFIFOSZ, MGC_DFIFO_BLK_VAL); + MGC_Write16(pBase, MGC_O_HDRC_RXFIFOADD, wFifoOffset >> 3); + pThis->bBulkRxEnd = bEnd; + /* move to next */ + wFifoOffset += pEnd->wMaxPacketSizeRx; + pThis->wEndMask |= (1 << bEnd); + bEnd++; + + /* take care of the remaining eps */ + for(; bEnd < MUSB_C_NUM_EPS; bEnd++) { + MGC_SelectEnd(pBase, bEnd); + pEnd = &(pThis->aLocalEnd[bEnd]); + pEnd->bEnd=bEnd; + + MGC_Write8(pBase, MGC_O_HDRC_TXFIFOSZ, MGC_DFIFO_ALL_VAL); + MGC_Write8(pBase, MGC_O_HDRC_RXFIFOSZ, MGC_DFIFO_ALL_VAL); + pEnd->wMaxPacketSizeTx = pEnd->wMaxPacketSizeRx = 1 << (MGC_DFIFO_ALL_VAL+3); + pEnd->bIsSharedFifo = TRUE; + MGC_Write16(pBase, MGC_O_HDRC_TXFIFOADD, wFifoOffset >> 3); + MGC_Write16(pBase, MGC_O_HDRC_RXFIFOADD, wFifoOffset >> 3); + + wFifoOffset += pEnd->wMaxPacketSizeRx; + pThis->wEndMask |= (1 << bEnd); + } + +#ifdef MUSB_PARANOID + if ( wFifoOffset > 64 ) { + ERR("Allocated %d bytes, more than the allowed %d\n", + wFifoOffset, 64); + } else { + INFO("Allocated %d bytes, out of %d\n", + wFifoOffset, 64); + } +#endif + + DBG(2, "==>\n"); +} +#endif + +#else +/** + * Detect and configure the end points (no dynamic fifos). + * @param pThis the controller + */ +void MGC_HdrcConfigureEps(MGC_LinuxCd* pThis) { + uint8_t bEnd=0, reg; + MGC_LinuxLocalEnd* pEnd; + void* pBase = pThis->pRegs; + /* how many of a given size/direction found: */ + uint8_t b2kTxEndCount = 0; + uint8_t b2kRxEndCount = 0; + uint8_t b1kTxEndCount = 0; + uint8_t b1kRxEndCount = 0; + /* the smallest 2k or 1k ends in Tx or Rx direction: */ + uint8_t b2kTxEnd = 0; + uint8_t b2kRxEnd = 0; + uint8_t b1kTxEnd = 0; + uint8_t b1kRxEnd = 0; + /* for tracking smallest: */ + uint16_t w2kTxSize = 0; + uint16_t w1kTxSize = 0; + uint16_t w2kRxSize = 0; + uint16_t w1kRxSize = 0; + + DBG(2, ">==\n"); + + for(bEnd = 1; bEnd < MUSB_C_NUM_EPS; bEnd++) { + MGC_SelectEnd(pBase, bEnd); + pEnd = &(pThis->aLocalEnd[bEnd]); + pEnd->bEnd=bEnd; + + /* read from core */ + reg = MGC_ReadCsr8(pBase, MGC_O_HDRC_FIFOSIZE, bEnd); + if(!reg) { + /* 0's returned when no more endpoints */ + break; + } + + pEnd->wMaxPacketSizeTx = 1 << (reg & 0x0f); + /* shared TX/RX FIFO? */ + if((reg & 0xf0) == 0xf0) { + pEnd->wMaxPacketSizeRx = 1 << (reg & 0x0f); + pEnd->bIsSharedFifo = TRUE; + } else { + pEnd->wMaxPacketSizeRx = 1 << ((reg & 0xf0) >> 4); + pEnd->bIsSharedFifo = FALSE; + } + + /* track certain sizes to try to reserve a bulk resource */ + if(pEnd->wMaxPacketSizeTx >= 2048) { + b2kTxEndCount++; + if(!b2kTxEnd || (pEnd->wMaxPacketSizeTx < w2kTxSize)) { + b2kTxEnd = bEnd; + w2kTxSize = pEnd->wMaxPacketSizeTx; + } + } + + if(pEnd->wMaxPacketSizeRx >= 2048) { + b2kRxEndCount++; + if(!b2kRxEnd || (pEnd->wMaxPacketSizeRx < w2kRxSize)) { + b2kRxEnd = bEnd; + w2kRxSize = pEnd->wMaxPacketSizeRx; + } + } + + if(pEnd->wMaxPacketSizeTx >= 1024) { + b1kTxEndCount++; + if(!b1kTxEnd || (pEnd->wMaxPacketSizeTx < w1kTxSize)) { + b1kTxEnd = bEnd; + w1kTxSize = pEnd->wMaxPacketSizeTx; + } + } + + if(pEnd->wMaxPacketSizeRx >= 1024) { + b1kRxEndCount++; + if(!b1kRxEnd || (pEnd->wMaxPacketSizeRx < w1kTxSize)) { + b1kRxEnd = bEnd; + w1kRxSize = pEnd->wMaxPacketSizeRx; + } + } + + pThis->bEndCount++; + pThis->wEndMask |= (1 << bEnd); + } /* init queues etc. etc. etc. */ + + /* if possible, reserve the smallest 2k-capable Tx end for bulk */ + if(b2kTxEnd && (b2kTxEndCount > 1)) { + pThis->bBulkTxEnd = b2kTxEnd; + INFO("Reserved end %d for bulk double-buffered Tx\n", b2kTxEnd); + } + /* ...or try 1k */ + else if(b1kTxEnd && (b1kTxEndCount > 1)) { + pThis->bBulkTxEnd = b1kTxEnd; + INFO("Reserved end %d for bulk Tx\n", b1kTxEnd); + } + + /* if possible, reserve the smallest 2k-capable Rx end for bulk */ + if(b2kRxEnd && (b2kRxEndCount > 1)) { + pThis->bBulkRxEnd = b2kRxEnd; + INFO("Reserved end %d for bulk double-buffered Rx\n", b2kRxEnd); + } + /* ...or try 1k */ + else if(b1kRxEnd && (b1kRxEndCount > 1)) { + pThis->bBulkRxEnd = b1kRxEnd; + INFO("Reserved end %d for bulk Rx\n", b1kRxEnd); + } + + DBG(2, "<==\n"); +} +#endif + --- /dev/null +++ linux-2.6.20/drivers/usb/nomadik/musb_hcd.c @@ -0,0 +1,869 @@ +/* + * linux/drivers/usb/nomadik/musb_hcd.c + * + * Copyright 2007, STMicroelectronics + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +static void mgc_hcd_stop(struct usb_hcd *hcd); +static int __devinit mgc_hcd_start(struct usb_hcd *hcd); +static int mgc_hcd_submit_urb(struct usb_hcd *hcd,struct usb_host_endpoint *ep, + struct urb *pUrb, MUSB_MEMFLAG_TYPE iMemFlags); +static int mgc_hcd_unlink_urb(struct usb_hcd *hcd, struct urb *pUrb); +static int mgc_hcd_get_frame_number(struct usb_hcd *hcd); +static irqreturn_t mgc_hcd_isr(struct usb_hcd *hcd); +static void mgc_hcd_disable_endpoint(struct usb_hcd *hcd, + struct usb_host_endpoint *ep); +static int mgc_hcd_find_end(MGC_LinuxCd* pThis, struct urb* pUrb); + +static int mgc_root_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, + u16 wIndex, char *pData, u16 wLength); +static int mgc_root_hub_status(struct usb_hcd *hcd, char *pData); +int Urb_status=0; +/* ------------------------------------------------------- */ +static int mgc_bus_resume(struct usb_hcd *phcd) +{ + MGC_LinuxCd* pThis=hcd_to_musbstruct(phcd); + char* pBase = (char*)pThis->pRegs; + + nomadik_gpio_altfuncenable(GPIO_ALT_USB_OTG,"OTG"); + /* Reinitialize the interrupt*/ + MGC_Write8(pBase, MGC_O_HDRC_POWER, 0x20); + MGC_Write16(pBase, MGC_O_HDRC_INTRTXE, 0xFFFF); + MGC_Write16(pBase, MGC_O_HDRC_INTRRXE, 0xFFFE); + MGC_Write8(pBase, MGC_O_HDRC_INTRUSBE, 0xF7); + MGC_Write8(pBase, MGC_O_HDRC_INDEX ,0x00); + + /* Configure the endpoints*/ + MGC_HdrcConfigureEps(pThis); + MGC_Write8(pThis->pRegs, MGC_O_HDRC_ULPI_VBUSCTL, 0x3); + mod_timer(¬ify_timer, jiffies + msecs_to_jiffies(1000)); + + printk("Got Bus Resume:\n"); + return 0; +} +static int mgc_bus_suspend(struct usb_hcd *phcd) +{ + uint8_t power; + uint8_t devctrl; + uint8_t topctrl; + MGC_LinuxCd* pThis=hcd_to_musbstruct(phcd); + char* pBase = (char*)pThis->pRegs; + + /* Delete Timer*/ + del_timer(¬ify_timer); + MUSB_A_IDLE_MODE(pThis); + + /* + * Device mode? disconnect the device and then + * proceed + */ + if(MUSB_IS_DEV(pThis)){ + udc_disconnect_isr(); + power = MGC_Read8(pBase, MGC_O_HDRC_POWER); + MGC_Write8(pBase, MGC_O_HDRC_POWER, power & ~MGC_M_POWER_SOFTCONN); + devctrl=MGC_Read8(pBase, MGC_O_HDRC_DEVCTL); + MUSB_B_IDLE_MODE(pThis); + MGC_Write8(pBase, MGC_O_HDRC_DEVCTL, devctrl & ~MGC_M_DEVCTL_SESSION); + dev_safe_remove =0; + } + /* Reset the controller*/ + topctrl = MGC_Read8(pBase, MGC_O_HDRC_TOPCONTROL); + MGC_Write8(pBase, MGC_O_HDRC_TOPCONTROL, (topctrl |MGC_M_TOPCTRL_MODE_SRST)); + power = MGC_Read8(pBase, MGC_O_HDRC_POWER); + MGC_Write8(pBase, MGC_O_HDRC_POWER, power | MGC_M_POWER_ENSUSPEND); + + nomadik_gpio_altfuncdisable(GPIO_ALT_USB_OTG,"OTG"); + + printk("Got Bus Suspend:\n"); + return 0; +} +#ifdef CONFIG_USB_SUSPEND +static int mgc_suspend (struct usb_hcd *phcd, pm_message_t message) +{ + uint8_t power; + MGC_LinuxCd* pThis=hcd_to_musbstruct(phcd); + char* pBase = (char*)pThis->pRegs; + power = MGC_Read8(pBase, MGC_O_HDRC_POWER); + MGC_Write8(pBase, MGC_O_HDRC_POWER, power | MGC_M_POWER_SUSPENDM); + printk("Got Suspend\n"); + return 0; +} +static int mgc_resume(struct usb_hcd *phcd) +{ + uint8_t power; + MGC_LinuxCd* pThis=hcd_to_musbstruct(phcd); + char* pBase = (char*)pThis->pRegs; + power = MGC_Read8(pBase, MGC_O_HDRC_POWER); + MGC_Write8(pBase, MGC_O_HDRC_POWER, power | MGC_M_POWER_RESUME); + mdelay(15); + power = MGC_Read8(pBase, MGC_O_HDRC_POWER); + MGC_Write8(pBase, MGC_O_HDRC_POWER, power & ~MGC_M_POWER_RESUME); + printk("Got Resume\n"); + return 0; +} +#endif +/* as platform_data */ +struct plat_musb_hcd { + unsigned long mapbase; + unsigned irq; + unsigned index; + char name[32]; +}; + +const struct hc_driver musb_ahb_hc_driver = { + .description = MGC_HcdName, + .product_desc = "MUSB HCD", + + /* this will allocate a MGC_LinuxCd at the end of it */ + .hcd_priv_size = sizeof(MGC_LinuxCd), + + /* + * generic hardware linkage + */ +#ifdef MUSB_POLL + .irq = NULL, +#else + .irq = mgc_hcd_isr, +#endif + + /* USB version 2 & memeory usage */ + .flags = HCD_USB2 | HCD_MEMORY, + + /* + * basic lifecycle operations + */ + .start = mgc_hcd_start, + .stop = mgc_hcd_stop, + + /* + * managing i/o requests and associated device resources + */ + .urb_enqueue = mgc_hcd_submit_urb, + .urb_dequeue = mgc_hcd_unlink_urb, + + .endpoint_disable = mgc_hcd_disable_endpoint, + + /* + * scheduling support + */ + .get_frame_number = mgc_hcd_get_frame_number, + + /* + * root hub support + */ + .hub_status_data = mgc_root_hub_status, + .hub_control = mgc_root_hub_control, + + .bus_suspend = mgc_bus_suspend, + .bus_resume = mgc_bus_resume, +#ifdef CONFIG_USB_SUSPEND + .suspend= mgc_suspend, + .resume= mgc_resume, +#endif + + .start_port_reset = NULL, +}; + +/* -------------------------------------------------------------------- */ + + +/* + * Scan the urb returning the urb the precede a give urb. When in the musb_hcd + * queue, urbs are linked to each other using the pUrb->hcdpriv field; the last + * urb has pUrb->hcpriv=NULL + * @param pThs the controller + * @param pUrb the urbn to search for + * @return NULL or pUrb1 such that (pUrb1->hcpriv==pUrb) + * + */ +static struct urb* mgc_hcd_urb_find_prev(mgc_hcd_urb_queue *pQueue, struct urb* pUrb) { + struct urb* temp=pQueue->urb_queue_head; + + if ( temp==pUrb ) { + return pQueue->urb_queue_head; /* to make clear */ + } + + while ( temp!=NULL && temp->hcpriv!=pUrb) { + temp=(struct urb*)temp->hcpriv; + } + + return temp; +} + +/* + * push back an urb to the hcd queue. + * @param pThs the controller + * @param pUrb the urb push in queue + * @return <0 if error, 0 when the queue is idle, >0 otherwise + */ +inline static int mgc_hcd_urb_pushback(mgc_hcd_urb_queue *pQueue, struct urb* pUrb) { +#ifdef MUSB_PARANOID + if (!pUrb) { + ERR("*** cannot push NULL urb\n"); + return -ENODEV; + } +#endif + + pQueue->urb_queue_count++; + pUrb->hcpriv=pQueue->urb_queue_head; + pQueue->urb_queue_head=pUrb; + if ( !pQueue->urb_queue_tail ) { + pQueue->urb_queue_tail=pUrb; + } + + return 0; +} + +/* + * Queue at an urb to the hcd queue. + * @return <0 if error, 0 when the queue is idle, >0 otherwise + */ +inline static int mgc_hcd_queue_urb(mgc_hcd_urb_queue *pQueue, struct urb* pUrb) { + int status=0; + +#ifdef MUSB_PARANOID + if (!pUrb) { + ERR("*** cannot queue NULL urb\n"); + return -ENODEV; + } +#endif + + spin_lock(&pQueue->urb_queue_lock); + if ( !pQueue->urb_queue_head ) { /* idle */ + pQueue->urb_queue_head=pUrb; + pQueue->urb_queue_tail=pUrb; + pQueue->urb_queue_count++; + } else { /* queue */ + if ( pQueue->urb_queue_tail ) { + ((struct urb*)pQueue->urb_queue_tail)->hcpriv=pUrb; + pQueue->urb_queue_tail=pUrb; + pQueue->urb_queue_count++; + status=pQueue->urb_queue_count; /* queued */ + } else { + ERR("*** pThis->urb_queue_head=%p, pThis->urb_queue_tail=%p; this is BAD (TM)\n", + pQueue->urb_queue_head, pQueue->urb_queue_tail); + + status=-ENODEV; + } + } + spin_unlock(&pQueue->urb_queue_lock); + + return status; +} + +/* + * top of the scheduler queue. + * @param pThis the controller + * @return next urb to be queued to hardware, NULL if idle + */ +inline static struct urb* mgc_hcd_urb_top(mgc_hcd_urb_queue *pQueue) { + return pQueue->urb_queue_head; +} + +/* + * + */ +inline static struct urb* mgc_hcd_urb_pop(mgc_hcd_urb_queue *pQueue) { + struct urb* pUrb=pQueue->urb_queue_head; + + if ( pUrb ) { + pQueue->urb_queue_count--; + pQueue->urb_queue_head=pUrb->hcpriv; + if ( !pQueue->urb_queue_head ) { + pQueue->urb_queue_tail=NULL; + } + } else { + pQueue->urb_queue_count=0; /* paranoid */ + pQueue->urb_queue_head=NULL; + pQueue->urb_queue_tail=NULL; + } + + return pUrb; +} + +/* ------------------------------------------------------------------- */ + +static void mgc_hcd_stop(struct usb_hcd *hcd) +{ + MGC_LinuxCd* pThis=hcd_to_musbstruct(hcd); + +#ifdef MUSB_PARANOID + if ( !pThis ) { + ERR("pThis is null"); + return; + } +#endif + + mgc_hdrc_disable(pThis); +} + +static int __devinit mgc_hcd_start(struct usb_hcd *hcd) +{ + int rc=0; + MGC_LinuxCd* pThis=hcd_to_musbstruct(hcd); + + DBG(2, "<== Starting hcd=%p\n", hcd); + +#ifdef MUSB_PARANOID + if ( !pThis ) { + ERR("pThis is null"); + return -ENODEV; + } +#endif + + hcd->state = HC_STATE_RUNNING; + pThis->pBus = &hcd->self; + pThis->pBus->bus_name = pThis->aName; + pThis->pBus->hcpriv = (void *)hcd; + + rc=mgc_init_root_hub(pThis); + if ( rc==0 ) { + DBG(3, "New bus @%p\n", pThis->pBus); + } else { + ERR("*** could not initialize the root hub\n"); + return -ENODEV; /* return if not success !! */ + } + + DBG(2, "==> rc=0\n"); + return 0; +} + +/* ------------------------------------------------------------------- */ + +/** + * + */ +mgc_hcd_urb_queue * mgc_hcd_get_urb_queue(MGC_LinuxCd* pThis) { + return &pThis->LocalQueue; +} + +/* ------------------------------------------------------------------- */ + +/** + * + */ +void mgc_hcd_flush(MGC_LinuxCd* pThis) { + struct urb* pUrb; + mgc_hcd_urb_queue *pQueue=mgc_hcd_get_urb_queue(pThis); + + DBG(2, "<== flushing\n"); + spin_lock(&pQueue->urb_queue_lock); + do { + pUrb=mgc_hcd_urb_pop(pQueue); + if ( pUrb ) { + DBG(3, "flushed=%p\n", pUrb); + pUrb->status=-ENOENT; + usb_kill_urb(pUrb); + } else { + + } + } while ( pUrb ); + spin_unlock(&pQueue->urb_queue_lock); + DBG(2, "==>\n"); +} + +/** + * + */ +void mgc_hcd_complete_urb(MGC_LinuxCd* pThis, struct urb *pUrb) +{ + mgc_hcd_get_urb_queue(pThis)->urb_exec_count--; + + usb_hcd_giveback_urb(musbstruct_to_hcd(pThis), pUrb); /* this call complete */ + + /*printk("Yes completed:%d\n",usb_pipeendpoint(pUrb->pipe));*/ +} + +/** + * Schedule the urb to the hardware. + * @param pThis the controller + */ +int mgc_hcd_schedule_urb(MGC_LinuxCd* pThis) +{ + + + int rc=0, nEnd; + struct urb*pUrb; + MGC_LinuxLocalEnd *pEnd; + mgc_hcd_urb_queue *pQueue=mgc_hcd_get_urb_queue(pThis); + + do { + + DBG(2, "<== pQueue->urb_queue_count=%d, pQueue->urb_exec_count=%d\n", + pQueue->urb_queue_count, pQueue->urb_exec_count); + + if ( !MUSB_IS_HST(pThis) ) { + break; /* nothing to do */ + } + + spin_lock(&pQueue->urb_queue_lock); + pUrb=mgc_hcd_urb_pop(pQueue); + if ( !pUrb ) { + DBG(3, "scheduler is idle\n"); + spin_unlock(&pQueue->urb_queue_lock); + break; + } + + DBG(3, "pUrb=%p, (proto=%s)\n", pUrb, decode_urb_protocol(pUrb)); + nEnd=mgc_hcd_find_end(pThis, pUrb); + if ( nEnd<0 ) { + spin_unlock(&pQueue->urb_queue_lock); + ERR("***> no resource for proto=%s, addr=%d, end=%d\n", + decode_urb_protocol(pUrb), usb_pipedevice(pUrb->pipe), + usb_pipeendpoint(pUrb->pipe)); + if ( !pQueue->urb_exec_count ) { + /* push it back and give it another chance */ + mgc_hcd_urb_pushback(pQueue, pUrb); + ERR("??? schedule of pUrb=%p to nEnd=%d FAILED rc=%d\n", + pUrb, nEnd, rc); + break; + } else { + /* the urb will never be scheduled, kill it and move to next */ + usb_kill_urb(pUrb); + ERR("** ABORTING pUrb=%p to nEnd=%d; this is BAD (TM)\n", + pUrb, nEnd); + continue; + } + } + + pEnd=&pThis->aLocalEnd[nEnd]; + if ( mgc_ep_is_idle(pEnd) ) { + DBG(3, "(%d/%d) pUrb=%p, nEnd=%d, %s \n", + pQueue->urb_queue_count, pQueue->urb_exec_count, + pUrb, nEnd, mgc_ep_is_idle(pEnd)?"idle":"busy"); + spin_unlock(&pQueue->urb_queue_lock); + rc=mgc_schedule_urb(pThis, pEnd, pUrb); + if ( rc!=0 ) { + if ( !pQueue->urb_exec_count ) { + /* the urb will never be scheduled, kill it */ + usb_kill_urb(pUrb); + ERR("** ABORTING pUrb=%p to nEnd=%d; this is BAD (TM)\n", + pUrb, nEnd); + } else { + /* push it back and give it another chance */ + mgc_hcd_urb_pushback(pQueue, pUrb); + ERR("??? schedule of pUrb=%p to nEnd=%d FAILED rc=%d\n", + pUrb, nEnd, rc); + } + } else { + /* removed from the queue, scheduled to hardware */ + pQueue->urb_exec_count++; + break; + } + } else { /* too fast ? */ + mgc_hcd_urb_pushback(pQueue, pUrb); + spin_unlock(&pQueue->urb_queue_lock); + DBG(3, "???> cannot schedule pUrb=%p to nEnd=%d yet (busy with pEnd->pCurrentUrb=%p)\n", + pUrb, nEnd, MGC_GetCurrentUrb(pEnd)); + break; + } + + } while ( 1 ); + + DBG(2, "==> rc=%d\n", rc); + return rc; +} + +/* ------------------------------------------------------------------ */ + +/** + * Find a local endpoint suitable for transmitting the given urb minimizing + * the reconfigurations. The best localendpoint is selceted using the following + * criterion: + * - ep0 is used for control Urbs + * - for bulk Urbs only (when available) choose the Tx or Rx reserved end + * - determine direction, size and traffic type + * + * @param pThis instance pointer + * @param pURB URB pointer + * @return suitable local endpoint + * @return -1 if nothing appropriate + */ +static int mgc_hcd_find_end(MGC_LinuxCd* pThis, struct urb* pUrb) +{ + return mgc_linux_find_end(pThis, pUrb); +} + +/** + * Submit an urb to our HCD driver. The urb will be queued and (sooner or later) + * scheduled to the hardware driver. The Urb had been queued to the ep from the + * kernel, DON'T modify with the urb_list otherwise BAD THINGS WILL + * HAPPEN (TM). + * @param hcd the HCD driver + * @param pURB URB pointer + */ +static int mgc_hcd_submit_urb(struct usb_hcd *hcd, struct usb_host_endpoint *ep, + struct urb *pUrb, MUSB_MEMFLAG_TYPE iMemFlags) +{ + + int rc=0; + + MGC_LinuxCd* pThis=hcd_to_musbstruct(hcd); + + if(Urb_status==1) + { + pUrb->status=-ENODEV; + rc=-ENODEV; + return rc; + } + +#ifdef MUSB_PARANOID + if ( !pThis ) { + ERR("***==> pThis is null\n"); + return -ENODEV; + } + + if ( !pUrb ) { + ERR("***==> pUrb is NULL\n"); + return -ENODEV; + } + + pUrb->hcpriv=NULL; /* paranoid!! */ + pUrb->status=-EINPROGRESS; /* paranoid!! */ +#endif + + DBG(2, "<== submit pUrb=%p, pUrb->hcpriv=%p, (proto=%s), bRemoteAddress=%d, bRemoteEnd=%d\n", + pUrb, pUrb->hcpriv, decode_urb_protocol(pUrb), usb_pipedevice(pUrb->pipe), + usb_pipeendpoint(pUrb->pipe)); + + if ( pUrb->hcpriv ) { + ERR("***==> on submission pUrb->hcpriv=%p; this is BAD (TM)\n", pUrb->hcpriv); + return -ENODEV; + } + + { + mgc_hcd_urb_queue *pQueue=mgc_hcd_get_urb_queue(pThis); + int count=mgc_hcd_queue_urb(pQueue, pUrb); + if ( count<0 ) { + rc=-ENODEV; + } else if ( count==0 ) { + rc=mgc_hcd_schedule_urb(pThis); + /*printk("Queued for scheduled:%d\n",usb_pipeendpoint(pUrb->pipe));*/ + } /* count>0 it's been queued */ + /*else + { + printk("Count> 0:%d\n",usb_pipeendpoint(pUrb->pipe)); + }*/ + } + + + + DBG(2, "==> rc=%d\n", rc); + return rc; +} + +/** + * unlink an urb, hcd version. First check if the urb was queued to the + * hardware, if not search it in the hcd queue, if not... this is BAD + * (TM). + * @param hcd the HCD driver + * @param pURB URB pointer + */ +static int mgc_hcd_unlink_urb(struct usb_hcd *hcd, struct urb *pUrb) +{ + int rc=0; + MGC_LinuxLocalEnd* pEnd; + MGC_LinuxCd* pThis=hcd_to_musbstruct(hcd); + mgc_hcd_urb_queue *pQueue=mgc_hcd_get_urb_queue(pThis); + +#ifdef MUSB_PARANOID + if ( !pThis ) { + ERR("pThis is null"); + return -ENODEV; + } +#endif + + DBG(-1, "<== Unlinking pUrb=%p (%s), pUrb->hcpriv=%p\n", pUrb, + decode_urb_protocol(pUrb), pUrb->hcpriv); + spin_lock(&pQueue->urb_queue_lock); + pEnd=mgc_ep_find_end(pThis, pUrb); + if ( pEnd ) { /* was submitted */ + spin_unlock(&pQueue->urb_queue_lock); + rc=mgc_unlink_urb(pThis, pUrb); + } else { /* remove the urb */ + struct urb* prev; + prev=mgc_hcd_urb_find_prev(pQueue, pUrb); + if ( prev==NULL ) { /* not mine! */ + ERR("*** cannot find pUrb=%p: is not mine! this is bad (tm)\n", + pUrb); + } else if ( prev==pUrb ) { /* list head */ + pQueue->urb_queue_head=prev->hcpriv; + if ( pQueue->urb_queue_tail==prev ) { + pQueue->urb_queue_tail=prev->hcpriv; + } + } else { + prev->hcpriv=pUrb->hcpriv; + } + spin_unlock(&pQueue->urb_queue_lock); + } + + DBG(2, "==> Unlinked urb=%p\n", pUrb); + return rc; +} + +/** + * return the frame number + * @param hcd the HCD driver + * @return the frame number + */ +static int mgc_hcd_get_frame_number(struct usb_hcd *hcd) { + return mgc_get_frame_number( hcd_to_musbstruct(hcd) ); +} + +/** + * Interrupt service routine, redirect it to the main routine/ + * @param hcd the HCD driver + * @param r the pt registers + * @return + */ +static irqreturn_t mgc_hcd_isr(struct usb_hcd *hcd) +{ + return mgc_linux_isr( hcd_to_musbstruct(hcd) ); +} + +/** + * @param hcd the HCD driver + * @param ep the endpoint to disable + */ +static void mgc_hcd_disable_endpoint(struct usb_hcd *hcd, + struct usb_host_endpoint *ep) +{ + DBG(-1, "hw sync with ep=%d (%s) list_empty(&ep->urb_list)=%d\n", + 0x7f&ep->desc.bEndpointAddress, (ep->desc.bEndpointAddress==0) ? "in/out" + : (ep->desc.bEndpointAddress>=0x80)?"in":"out", + list_empty(&ep->urb_list) ); + + DBG(2, "<== disable endpoint %d (%s)\n", 0x7f&ep->desc.bEndpointAddress, + (ep->desc.bEndpointAddress==0) ? "in/out" + : (ep->desc.bEndpointAddress>=0x80)?"in":"out"); + + DBG(2, "==>disabled endpoint %d\n", 0x7f&ep->desc.bEndpointAddress); +} + +/* --------------------------------------------------------------- */ +/* Virtual hub */ +/* --------------------------------------------------------------- */ + +/** + * Report the virtual hub status. + * + * @param hcd the hcd + * @param pData the buffer to store the status in + */ +static int mgc_root_hub_status(struct usb_hcd *hcd, char *pData) +{ + MGC_LinuxCd* pThis = hcd_to_musbstruct(hcd); + MGC_VirtualHub* pHub = &(pThis->RootHub); + int len = 0; + + spin_lock(&pHub->Lock); + len = mgc_rh_port_status(pHub, pData); + pHub->bIsChanged = FALSE; + spin_unlock(&pHub->Lock); + DBG(5, "len=%d, status=%02x\n", len, pData[0]); + return len; +} + +/** MGC_VirtualhubControl Instead of MGC_VirtualHubSubmitUrb + * @param hcd the HCD driver + */ +static int mgc_root_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, + u16 wIndex, char *pData, u16 wLength) +{ + MGC_LinuxCd* pThis = hcd_to_musbstruct(hcd); + MGC_VirtualHub* pHub = &(pThis->RootHub); + uint8_t bPort = (uint8_t)(wIndex & 0xff) - 1; + uint16_t wSize = 0xffff; + int retval = 0; + int ports = (pHub->bPortCount + 1); + + DBG("<==\n"); + DBG("Setup_Data: bmReqtype-bmRequest=%04x | wValue=%x | wIndex=%x | wLength=%04x \n", \ + typeReq, wValue, wIndex, wLength); + DBG("Setup_Data: wValue=%04x | wIndex=%04x | wLength=%04x | \n", \ + wValue, wIndex, wLength); + + switch (typeReq) { + case ClearHubFeature: + switch (wValue) { + case C_HUB_LOCAL_POWER: + case C_HUB_OVER_CURRENT: + wSize = 0; + break; + default: + goto error; + } + break; + case ClearPortFeature: + if (!wIndex || wIndex > ports) + goto error; + wIndex--; + switch (wValue) { + case USB_PORT_FEAT_ENABLE: + DBG("enable port %d\n", bPort); + pHub->pPortServices->pfSetPortEnable( + pHub->pPortServices->pPrivateData, bPort, FALSE); + wSize = 0; + break; + case USB_PORT_FEAT_C_ENABLE: + DBG("ack enable port %d\n", bPort); + pHub->aPortStatusChange[bPort].wChange &= ~USB_PORT_STAT_ENABLE; + wSize = 0; + break; + case USB_PORT_FEAT_SUSPEND: + DBG("suspend port %d\n", bPort); + pHub->pPortServices->pfSetPortSuspend( + pHub->pPortServices->pPrivateData, bPort, FALSE); + wSize = 0; + break; + case USB_PORT_FEAT_C_SUSPEND: + DBG("ack suspend port %d\n", bPort); + pHub->aPortStatusChange[bPort].wChange &= ~USB_PORT_STAT_SUSPEND; + wSize = 0; + break; + case USB_PORT_FEAT_POWER: + DBG("feat feat power port %d\n", bPort); + wSize = 0; + break; + case USB_PORT_FEAT_C_CONNECTION: + DBG("ack connection port %d\n", bPort); + pHub->aPortStatusChange[bPort].wChange &= ~1; + wSize = 0; + break; + case USB_PORT_FEAT_C_OVER_CURRENT: + DBG("ack over current port %d\n", bPort); + wSize = 0; + break; + case USB_PORT_FEAT_C_RESET: + DBG("ack reset port %d\n", bPort); + pHub->aPortStatusChange[bPort].wChange &= ~USB_PORT_STAT_RESET; + wSize = 0; + break; + default: + goto error; + } + break; + case GetHubDescriptor: + DBG("GET_CLASS_DESCRIPTOR()\n"); + pData[0] = 9; + pData[1] = 0x29; + pData[2] = pHub->bPortCount; + /* min characteristics */ + pData[3] = 1; /* invidual port power switching */ + pData[4] = 0; + /* PowerOn2PowerGood */ + pData[5] = 50; + /* no current */ + pData[6] = 0; + /* removable ports */ + pData[7] = 0; + /* reserved */ + pData[8] = 0xff; + wSize = pData[0]; + break; + case GetHubStatus: + /* hub status */ + memset(pData, 0, 4); + wSize = 4; + DBG("hub statusreport=%02x%02x%02x%02x\n", + pData[0], pData[1], pData[2], pData[3]); + break; + case GetPortStatus: + if (!wIndex || wIndex > ports) + goto error; + /* port status/change report */ + memcpy(pData, &(pHub->aPortStatusChange[wIndex-1].wStatus), 2); + memcpy(&(pData[2]), &(pHub->aPortStatusChange[wIndex-1].wChange), 2); + /* reset change (TODO: lock) */ + pHub->aPortStatusChange[wIndex-1].wChange = 0; + wSize = 4; + DBG("port status report=%02x%02x%02x%02x\n", + pData[0], pData[1], pData[2], pData[3]); + break; + + case SetHubFeature: + switch (wValue) { + case C_HUB_OVER_CURRENT: + case C_HUB_LOCAL_POWER: + break; + default: + goto error; + } + break; + case SetPortFeature: + if (!wIndex || wIndex > ports) + goto error; + switch (wValue) { + case USB_PORT_FEAT_SUSPEND: + DBG("suspend port %d\n", bPort); + pHub->pPortServices->pfSetPortSuspend( + pHub->pPortServices->pPrivateData, bPort, TRUE); + pHub->aPortStatusChange[bPort].wStatus |= USB_PORT_STAT_SUSPEND; + pHub->bIsChanged = TRUE; + wSize = 0; + break; + case USB_PORT_FEAT_POWER: + DBG("power port %d\n", bPort); + + #if 1 + { + int err; + err = STMPE2401_SetGpioAltFunction(STMPE1,EGPIO_PIN_0,STMPE2401_PRIMARY_FUNCTION); + if (err != STMPE2401_OK) + DBG("Couldn't set STMPE%d %d as primary function\n",STMPE1,EGPIO_PIN_0); + err = STMPE2401_SetGpioDir( STMPE1,EGPIO_PIN_0,STMPE2401_GPIO_OUT ); + if (err != STMPE2401_OK) + DBG("Couldn't set STMPE EGPIO:%d in Output direction\n", EGPIO_PIN_0); + err = STMPE2401_SetGpioVal( STMPE1, EGPIO_PIN_0, 0); + if (err != STMPE2401_OK) + DBG("Couldn't set STMPE GPIO12\n"); + + } + #endif + pHub->pPortServices->pfSetPortPower(pHub->pPortServices->pPrivateData, + bPort,TRUE); + pHub->aPortStatusChange[bPort].wStatus |= USB_PORT_STAT_POWER; + wSize = 0; + + break; + case USB_PORT_FEAT_RESET: + DBG("USB_Class set feature USB_PORT_FEAT_RESET Port_no:%d \n", + bPort); + pHub->aPortStatusChange[bPort].wStatus |= USB_PORT_STAT_RESET; + pHub->aPortStatusChange[bPort].wStatus |= USB_PORT_STAT_ENABLE; + pHub->aPortStatusChange[bPort].wChange |= USB_PORT_STAT_RESET; + pHub->bIsChanged = TRUE; + + pHub->pPortServices->pfSetPortReset( + pHub->pPortServices->pPrivateData, bPort, TRUE); + wSize = 0; + break; + default: + goto error; + } + break; + + default: +error: + /* "protocol stall" on error */ + retval = -EPIPE; + } + + DBG("==> retval=%d\n", retval); + return retval; +} --- /dev/null +++ linux-2.6.20/drivers/usb/nomadik/musb_host.c @@ -0,0 +1,2791 @@ +/* + * linux/drivers/usb/nomadik/musb_host.c + * + * Copyright 2007, STMicroelectronics + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#ifdef CONFIG_USB_DEBUG + #define DEBUG +#else + #undef DEBUG +#endif + +#include + +#include "musbdefs.h" +#include "musb_host.h" +#include "../core/hub.h" + +#ifdef MUSB_USE_HCD_DRIVER +#define HAS_USB_TT_MULTI +#include "../core/hcd.h" +#endif + +/** how much to "scale" response timeouts */ +#define MUSB_MAX_RETRIES 8 + +/*************************** Forwards ***************************/ + +/* HCD helpers */ +static uint8_t find_first1(unsigned int nValue); +static void mgc_linux_start_next_urb(MGC_LinuxCd* pThis, uint8_t bEnd); +static void mgc_linux_kickstart_urb(MGC_LinuxCd* pThis, uint8_t bEnd); +static void mgc_ep_linux_clear(MGC_LinuxLocalEnd* pEnd,MGC_LinuxCd* pThis); +int *Urb_test; +extern int Urb_status; +/************************************************************************** + * + **************************************************************************/ + +#ifndef MGC_SLOW_DEVICE_KLUDGE_DELAY +#define MGC_SLOW_DEVICE_KLUDGE_DELAY 0 +#endif + +#ifndef MGC_SLOW_DEVICE_KLUDGE_DELAY_MIN +#define MGC_SLOW_DEVICE_KLUDGE_DELAY_MIN 0 +#endif + +#ifndef DEBUG +#endif + +int mgc_slow_device_kludge_delay=MGC_SLOW_DEVICE_KLUDGE_DELAY; + +#define MGC_SLOW_DEVICE_KLUDGE_DELAY_INCREASE { } +#define MGC_SLOW_DEVICE_KLUDGE_DELAY_DECREASE { } +#define MGC_SLOW_DEVICE_KLUDGE_DELAY_TOP { } + +/************************************************************************** + * Glue for virtual root hub +**************************************************************************/ + +#ifdef MUSB_CONFIG_PROC_FS +/** + * Decode an host endpoint protocol. + * @param pUrn the uRb protocol shoudl be decoded + * @return a const char* to the name of the protocol. + */ +char* decode_hst_ep_protocol(MGC_LinuxCd* pThis, unsigned bEnd) { + char* pProto = "Err "; + + switch(pThis->aLocalEnd[bEnd].bTrafficType) { + case PIPE_ISOCHRONOUS: pProto = "Isoc"; break; + case PIPE_INTERRUPT: pProto = "Intr"; break; + case PIPE_CONTROL: pProto = "Ctrl"; break; + case PIPE_BULK: pProto = "Bulk"; break; + } + + return pProto; +} +#endif + +/** + * Decode an urb protocol. + * @param pUrn the uRb protocol shoudl be decoded + * @return a const char* to the name of the protocol. + */ +char* decode_urb_protocol(struct urb* pUrb) { + static char buffer[8]; + + if ( !pUrb ) { + strcpy(&buffer[0], "NULL"); + return buffer; + } + + buffer[0]=usb_pipein(pUrb->pipe)?'I':'O'; + if ( usb_pipeint(pUrb->pipe) ) { + strcpy(&buffer[1], " int"); + } else if ( usb_pipeisoc(pUrb->pipe) ) { + strcpy(&buffer[1], " isoc"); + } else if ( usb_pipebulk(pUrb->pipe) ) { + strcpy(&buffer[1], " bulk"); + } else if ( usb_pipecontrol(pUrb->pipe) ) { + strcpy(&buffer[0], " ctl"); + } + + return buffer; +} + +/* Root speed need to be translated (addapted) + */ +static uint8_t MGC_TranslateVirtualHubSpeed(uint8_t source) { + uint8_t speed=2; + + switch ( source ) { + case 3: speed=0; break; + case 2: speed=1; break; + } + + return speed; +} + +/** + * Timer completion callback to turn off reset and get connection speed + */ +static void MGC_HdrcResetOff(unsigned long param) +{ + uint8_t power; + MGC_LinuxCd* pThis = (MGC_LinuxCd*)param; + void* pBase = pThis->pRegs; + unsigned long flags; + + DBG(2, "<== Stopping root port reset...\n"); + + SPIN_LOCK_IRQSAVE(&pThis->Lock, flags); + pThis->bIgnoreDisconnect = FALSE; + power = MGC_Read8(pBase, MGC_O_HDRC_POWER); + MGC_Write8(pBase, MGC_O_HDRC_POWER, power & ~MGC_M_POWER_RESET); + + /* check for high-speed and set in root device if so */ + power = MGC_Read8(pBase, MGC_O_HDRC_POWER); + if(power & MGC_M_POWER_HSMODE) { + DBG(3, "high-speed device connected\n"); + pThis->bRootSpeed = 1; + } + +#ifdef MUSB_VIRTHUB + MGC_VirtualHubPortResetDone(&(pThis->RootHub), 0, + MGC_TranslateVirtualHubSpeed(pThis->bRootSpeed)); +#endif + + DBG(2, "==>\n"); + SPIN_UNLOCK_IRQRESTORE(&pThis->Lock, flags); +} + +/* see virthub.h */ +void MGC_LinuxSetPortPower(void* pPrivateData, uint8_t bPortIndex, + uint8_t bPower) +{ + DBG(2, "<==\n"); + if(bPower) { + DBG(3, "Root port power on\n"); + MGC_HdrcStart((MGC_LinuxCd*)pPrivateData); + } else { + DBG(3, "Root port power off\n"); + MGC_HdrcStop((MGC_LinuxCd*)pPrivateData); + } + DBG(2, "==>\n"); +} + +/* see virthub.h */ +void MGC_LinuxSetPortEnable(void* pPrivateData, uint8_t bPortIndex, + uint8_t bEnable) +{ + DBG(2, "<==\n"); + if (bEnable) { + DBG(3, "Root port power enabled\n"); + } else { + DBG(3, "Root port power disabled\n"); + } + + DBG(2, "==>\n"); +} + +/* see virthub.h */ +void MGC_LinuxSetPortSuspend(void* pPrivateData, uint8_t bPortIndex, + uint8_t bSuspend) +{ + uint8_t power; + MGC_LinuxCd* pThis = (MGC_LinuxCd*)pPrivateData; + void* pBase = pThis->pRegs; + + DBG(2, "<==\n"); + + power = MGC_Read8(pBase, MGC_O_HDRC_POWER); + if(bSuspend) { + DBG(3, "Root port power suspended\n"); + MGC_Write8(pBase, MGC_O_HDRC_POWER, power | MGC_M_POWER_SUSPENDM); + } else if(power & MGC_M_POWER_SUSPENDM) { + DBG(3, "Root port power resumed\n"); + power &= ~(MGC_M_POWER_SUSPENDM | MGC_M_POWER_RESUME); + MGC_Write8(pBase, MGC_O_HDRC_POWER, power | MGC_M_POWER_RESUME); + WAIT_MS(20); + MGC_Write8(pBase, MGC_O_HDRC_POWER, power); + } + + DBG(2, "==>\n"); +} + +/* see virthub.h */ +void MGC_LinuxSetPortReset(void* pPrivateData, uint8_t bPortIndex, + uint8_t bReset) +{ + uint8_t power; + MGC_LinuxCd* pThis = (MGC_LinuxCd*)pPrivateData; + void* pBase = pThis->pRegs; + + DBG(2, "<==\n"); + + power = MGC_Read8(pBase, MGC_O_HDRC_POWER) & 0xf0; + if (bReset) { + pThis->bIgnoreDisconnect = TRUE; + MGC_Write8(pBase, MGC_O_HDRC_POWER, power | MGC_M_POWER_RESET); + MGC_LinuxSetTimer(pThis, MGC_HdrcResetOff, (unsigned long)pThis, 60); + } else if(power & MGC_M_POWER_RESET) { + DBG(3, "root port reset stopped\n"); + MGC_Write8(pBase, MGC_O_HDRC_POWER, power & ~MGC_M_POWER_RESET); + } + + DBG(2, "==>\n"); +} + +/************************************************************************** + * + **************************************************************************/ + + /** + * return the current urb for a given endpoint. Caller is responsible for + * locking + * @param pEnd the end point (pEnd!=NULL) + * @return the urb or NULL when the end point is idle + */ +struct urb* MGC_GetCurrentUrb(MGC_LinuxLocalEnd *pEnd) { +#ifdef MUSB_USE_HCD_DRIVER + return pEnd->pCurrentUrb; +#else + DBG(8 ,"GetCurrentUrb urb_list_ptr:0x%p \n",&(pEnd->urb_list)); + DBG(8 ,"GetCurrentUrb urb_list->next:0x%p \n",pEnd->urb_list.next); + DBG(8 ,"GetCurrentUrb urb_list->prev:0x%p \n",pEnd->urb_list.prev); + return list_empty(&(pEnd->urb_list)) ? NULL + : list_entry(pEnd->urb_list.next, struct urb, urb_list); +#endif +} + +/** + * Test whether a local endpoint is idle. + * @param pEnd the endpoint + * @return !=0 when idle, 0 otherwise + */ +int mgc_ep_is_idle(MGC_LinuxLocalEnd* pEnd) +{ +#ifdef MUSB_USE_HCD_DRIVER + return (pEnd->pCurrentUrb)==NULL; +#else + return list_empty(&pEnd->urb_list); +#endif +} + + +void mgc_ep_idle(MGC_LinuxLocalEnd* pEnd) { +#ifdef MUSB_USE_HCD_DRIVER + pEnd->pCurrentUrb=NULL; +#else + INIT_LIST_HEAD(&(pEnd->urb_list)); +#endif +} + + +/** + * Dequeue an urb from an endpoint. + * @param pEnd the endpoint + * @param pUrb the urb to be removed + */ +static int mgc_ep_dequeue_urb(MGC_LinuxLocalEnd* pEnd, struct urb *pUrb,MGC_LinuxCd* pThis) +{ + int rc=0; + +#ifdef MUSB_USE_HCD_DRIVER + if ( pEnd->pCurrentUrb==pUrb ) { + pUrb->hcpriv=NULL; + pEnd->pCurrentUrb=NULL; + } else { + rc=-EINVAL; + ERR("*** Trying to dequeue pUrb=%p from ep%d while pEnd->pCurrentUrb=%p\n", + pUrb, pEnd->bEnd, pEnd->pCurrentUrb); + } +#else + pUrb->hcpriv=NULL; + list_del_init(&pUrb->urb_list); +#endif + + /* clear endpoint status (preserving the softstate for find_end() ) */ + mgc_ep_linux_clear(pEnd,pThis); + + DBG(1, "==> dequeued pUrb=%p from pEnd->bEnd=%d rc=%d\n", + pUrb, pEnd->bEnd, rc); + return rc=0; +} + +/** + * @return 0 success, != when the ep is busy with another request + */ +static int mgc_ep_enqueue_urb(MGC_LinuxLocalEnd* pEnd, struct urb* pUrb) +{ + int rc=0; + +#ifdef MUSB_USE_HCD_DRIVER + if ( pEnd->pCurrentUrb ) { + ERR("*** urb=%p, ep=%d wile busy with urb=%p, this is BAD (tm)\n", + pUrb, pEnd->bEnd, pEnd->pCurrentUrb); + rc=-EBUSY; + } else { + pEnd->pCurrentUrb=pUrb; + } +#else + list_add_tail(&(pUrb->urb_list), &(pEnd->urb_list)); +#endif + + return rc; +} + +/** + * find the end an urb is posted to + * @param pUrb + * @return the pEnd or NULL when not found. + */ +MGC_LinuxLocalEnd* mgc_ep_find_end(MGC_LinuxCd *pThis, struct urb *pUrb) +{ + int bEnd=0; + + for (bEnd=0; bEndaLocalEnd[bEnd])==pUrb ) { + return &pThis->aLocalEnd[bEnd]; + } + } + + return NULL; +} + +/************************************************************************** + * + **************************************************************************/ + +void mgc_complete_urb(MGC_LinuxCd *pThis, struct urb *pUrb) { + /* give it back */ + usb_put_urb(pUrb); + if (pUrb->status) { + DBG(1, "completing urb=%p,status=%d\n", pUrb, pUrb->status); + } + +#ifdef MUSB_USE_HCD_DRIVER + mgc_hcd_complete_urb(pThis, pUrb); +#else + if ( pUrb->complete ) { + COMPLETE_URB(pUrb, NULL); + } +#endif + + if (pUrb->status) { + DBG(1, "done completing pUrb=%p\n", pUrb); + } +} + +/** + * complete an urb. Since urb completion generally post new urbs via + * submit urn, this make sure the ep won't kickstart it during the + * completion. + * + * @param pEnd the end point urb is posted to + * @param pUrb the urb to complete !=NULL + * @return 0 success + */ +static inline int mgc_linux_complete_urb(MGC_LinuxCd *pThis, + MGC_LinuxLocalEnd* pEnd, struct urb *pUrb) +{ + + int periodic=mgc_urb_is_periodic(pUrb); + int status=periodic; /* 0 needs start next */ + int error=(pUrb->status==-ENOENT) || (pUrb->status==-ECONNRESET) || + (pUrb->status==-ESHUTDOWN) || (pUrb->status==-ETIMEDOUT) + || (pUrb->status==-EBUSY); + + DBG(2, "<== completing URB %p, on pEnd->bEnd=%d status=%d, proto=%s\n", + pUrb, pEnd->bEnd, pUrb->status, decode_urb_protocol(pUrb)); + + if ( error && periodic ) { + pEnd->bIsClaimed=FALSE; + } + + /* prevents locking&kickstarting */ + pEnd->bBusyCompleting=1; + + mgc_complete_urb(pThis, pUrb); + +#ifdef MUSB_V24 + /* Under 2.4 interrupt IN URBs must be re-submitted from the driver + * unless they are unlinked; 2.6 urbs do that from the completition + * routine. ENODEV means we raced disconnect() */ + if ( !error && periodic ) { + DBG(1, "periodic pUrb=%p, proto=%s, (status=%d)\n", pUrb, + decode_urb_protovol(pUrb), pUrb->status); + status=mgc_schedule_urb(pThis, pEnd, pUrb); + if ( (status!= 0) && (status != -ENODEV) ) { + DBG(3, "error resubmitting intr URB %p (status=%d)\n", + pUrb, status); + } + + } +#else + status=0; /* kickstart next */ +#endif + + /* allows locking&kickstarting again */ + pEnd->bBusyCompleting=0; + + DBG(2, "==> status=%d, periodic=%d\n", status, periodic); + return status; +} + +/** + * Start transmit. Caller is responsible for locking the ep. + * On EP0 only PING is disabled. + * + * @param pThis instance pointer + * @param bEnd local endpoint + */ +void MGC_HdrcStartTx(MGC_LinuxCd* pThis, uint8_t bEnd) +{ + uint16_t wCsr; + uint8_t* pBase = (uint8_t*)pThis->pRegs; + + DBG(2, "<== bEnd=%d ==>\n", bEnd); + /* NOTE: no locks here; caller should lock */ + MGC_SelectEnd(pBase, bEnd); + if(bEnd) { + wCsr = MGC_ReadCsr16(pBase, MGC_O_HDRC_TXCSR, bEnd); + wCsr |= MGC_M_TXCSR_TXPKTRDY; + MGC_WriteCsr16(pBase, MGC_O_HDRC_TXCSR, bEnd, wCsr); + } else { + MGC_WriteCsr16(pBase, MGC_O_HDRC_CSR0, 0, + MGC_M_CSR0_H_NO_PING | MGC_M_CSR0_H_SETUPPKT | MGC_M_CSR0_TXPKTRDY); + } +} + +/************************************************************************** + * + **************************************************************************/ + + /** + * return the buffer associated to an urb (map it too) + */ +static inline uint8_t* get_urb_buffer(struct urb* pUrb) { + uint8_t *pBuffer=NULL; + +#ifdef MUSB_PARANOID + if ( !pUrb ) { + return NULL; + } +#endif + + pBuffer=pUrb->transfer_buffer; +#ifndef MUSB_LINUX_MV21 + if ( !pBuffer ) { + pBuffer=(void*)phys_to_virt(pUrb->transfer_dma); + } +#endif + + return pBuffer; +} + +/** + * Xmit a packet. pEnd->dwOffset is updated as well + * @param pThis + * @param bEnd the EP urb is queued to + */ +static uint8_t mgc_linux_packet_tx(MGC_LinuxCd* pThis, uint8_t bEnd) { + uint32_t wLength=0; + uint8_t bDone = FALSE; + uint8_t *pBase = (uint8_t*)pThis->pRegs; + MGC_LinuxLocalEnd* pEnd = &(pThis->aLocalEnd[bEnd]); + struct urb* pUrb=MGC_GetCurrentUrb(pEnd); + uint8_t *pBuffer=get_urb_buffer(pUrb); + int nPipe = pUrb ? pUrb->pipe : 0; + + DBG(2, "<== bEnd=%d\n", bEnd); + + /* abort the transfer */ + if ( !pBuffer ) { + ERR("***> no buffer was given, BAD things are happening (TM)!\n"); + return TRUE; + } + + /* see if more transactions are needed */ +#ifdef MUSB_DMA + if(pEnd->pDmaChannel) { + if (MGC_DMA_STATUS_FREE == + pThis->pDmaController->pfDmaGetChannelStatus(pEnd->pDmaChannel) + ) { + pEnd->dwOffset += pEnd->pDmaChannel->dwActualLength; + } + } else { + pEnd->dwOffset += pEnd->dwRequestSize; + } +#else + pEnd->dwOffset += pEnd->dwRequestSize; +#endif + + if (usb_pipeisoc(nPipe)) { + /* isoch case */ + if(++pEnd->dwIsoPacket >= pUrb->number_of_packets) { + bDone = TRUE; + } else { + pBuffer += pUrb->iso_frame_desc[pEnd->dwIsoPacket].offset; + wLength = pUrb->iso_frame_desc[pEnd->dwIsoPacket].length; + } + } else { + pBuffer += pEnd->dwOffset; + wLength = min((uint32_t)(pEnd->wPacketSize), + (uint32_t)(pUrb->transfer_buffer_length - pEnd->dwOffset)); + if(pEnd->dwOffset >= pUrb->transfer_buffer_length) { + /* sent everything; see if we need to send a null */ + if(!((pEnd->dwRequestSize == pEnd->wPacketSize) && + (pUrb->transfer_flags & USB_ZERO_PACKET))) + { + bDone = TRUE; + } + } + } + + if (bDone) { + pUrb->status=0; + } else if ( wLength ) { /* @assert bDone && !wLength */ + MGC_HdrcLoadFifo(pBase, bEnd, wLength, pBuffer); + pEnd->dwRequestSize = wLength; + } + +#ifdef MUSB_CONFIG_PROC_FS + pEnd->dwTotalTxBytes += pEnd->dwRequestSize; + pEnd->dwTotalTxPackets++; +#endif + + DBG(2, "==> bDone=%d\n", bDone); + return bDone; +} + + +/** + * Receive a packet (or part of it). + * @requires pThis->Lock locked + * @param pThis + * @param bEnd + * @param bIsochError + * @return TRUE if URB is complete + */ +static uint8_t mgc_linux_packet_rx(MGC_LinuxCd* pThis, uint8_t bEnd, + uint16_t wRxCount, uint8_t bIsochError) +{ + uint16_t wLength, wCsr; + uint8_t bDone = FALSE; + uint8_t* pBase = (uint8_t*)pThis->pRegs; + MGC_LinuxLocalEnd* pEnd = &(pThis->aLocalEnd[bEnd]); + struct urb* pUrb = MGC_GetCurrentUrb(pEnd); + uint8_t* pBuffer=get_urb_buffer(pUrb); + int nPipe = pUrb ? pUrb->pipe : 0; + + DBG(2, "<== end %d RxCount=%04x\n", bEnd, wRxCount); + +#ifdef MUSB_PARANOID + if ( !pUrb || ((pUrb->transfer_buffer_length - pEnd->dwOffset)<0) ) { + ERR("***> Rx error: pUrb=%p, pUrb->transfer_buffer_length=%d pEnd->dwOffset=%d\n", \ + pUrb, pUrb->transfer_buffer_length, pEnd->dwOffset ); + return TRUE; + } +#endif + + DBG(3, "bEnd=%d, pUrb->transfer_flags=0x%x pUrb->transfer_buffer=%p\n", \ + bEnd, pUrb->transfer_flags, pUrb->transfer_buffer); + DBG(3, "pUrb->transfer_buffer_length=%d, pEnd->dwOffset=%d, wRxCount=%d\n", + pUrb->transfer_buffer_length, pEnd->dwOffset, wRxCount); + + /* abort the transfer */ + if ( !pBuffer ) { + ERR("***> pBuffer=NULL, BAD things are happening (TM)!\n"); + return TRUE; + } + + /* unload FIFO */ + if( usb_pipeisoc(nPipe) ) { + /* isoch case */ + pBuffer += pUrb->iso_frame_desc[pEnd->dwIsoPacket].offset; + wLength = min((unsigned int)wRxCount, + pUrb->iso_frame_desc[pEnd->dwIsoPacket].length); + pUrb->actual_length += wLength; + + /* update actual & status */ + pUrb->iso_frame_desc[pEnd->dwIsoPacket].actual_length = wLength; + if(bIsochError) { + pUrb->iso_frame_desc[pEnd->dwIsoPacket].status = USB_ST_CRC; + pUrb->error_count++; + } else { + pUrb->iso_frame_desc[pEnd->dwIsoPacket].status = USB_ST_NOERROR; + } + + /* see if we are done */ + bDone = (++pEnd->dwIsoPacket >= pUrb->number_of_packets); + + DBG(3, "pEnd->dwIsoPacket=%d, pUrb->number_of_packets=%d, wLength=%d\n", + pEnd->dwIsoPacket, pUrb->number_of_packets, wLength); + DEBUG_CODE(3, if ( bDone ) { \ + INFO("completing %d-packet isoch URB; len=%x, errors=%d\n", \ + pUrb->number_of_packets, pUrb->actual_length, pUrb->error_count); \ + } ); + } else { + DBG(3, "(bEnd=%d), wRxCount=%d, pUrb->transfer_buffer_length=%d, pEnd->dwOffset=%d, pEnd->wPacketSize=%d\n", + bEnd, wRxCount, pUrb->transfer_buffer_length, pEnd->dwOffset, pEnd->wPacketSize); + + /* non-isoch */ + pBuffer += pEnd->dwOffset; + wLength = min((unsigned int)wRxCount, + pUrb->transfer_buffer_length - pEnd->dwOffset); + pUrb->actual_length += wLength; + pEnd->dwOffset += wLength; + + /* see if we are done */ + bDone = (pEnd->dwOffset >= pUrb->transfer_buffer_length) + || (wRxCount < pEnd->wPacketSize); + + DEBUG_CODE(3, if ( bDone ) { \ + INFO("will complete URB; pUrb=%p (%s) len=%x, errors=%d\n", \ + pUrb, decode_urb_protocol(pUrb), pUrb->actual_length, \ + pUrb->error_count); \ + } ); + } + + if ( wLength ) { + MGC_HdrcUnloadFifo(pBase, bEnd, wLength, pBuffer); + } + +#ifdef MUSB_CONFIG_PROC_FS + pEnd->dwTotalRxBytes += wLength; + pEnd->dwTotalRxPackets++; +#endif + + if( wRxCount <= wLength ) { /* test for short packet */ + wCsr = MGC_ReadCsr16(pBase, MGC_O_HDRC_RXCSR, bEnd); + MGC_WriteCsr16(pBase, MGC_O_HDRC_RXCSR, bEnd, + wCsr & ~MGC_M_RXCSR_RXPKTRDY); + } + if ( bEnd && bDone ) { + pUrb->status=0; + } + + DBG(2, "==> bDone=%d\n", bDone); + return bDone; +} + +/* ************************************************************************* + * + **************************************************************************/ + +/** + * Find first (lowest-order) 1 bit + * @param nValue value in which to search + * @return bit position (0 could mean no bit; caller should check) + */ +static uint8_t find_first1(unsigned int nValue) +{ + uint8_t bResult; + unsigned int nWork = nValue; + + for(bResult = 0; bResult < 32; bResult++) { + if(nWork & 1) { + return bResult; + } + nWork >>= 1; + } + + return bResult; +} + +/** + * @param nPipe + */ +static inline char *pipe_type(const unsigned int nPipe) { + if ( usb_pipeisoc(nPipe) ) { + return "isoc"; + } else if ( usb_pipebulk(nPipe) ) { + return "bulk"; + } else if ( usb_pipeint(nPipe) ) { + return "int"; + } else { + return "cntl"; + } +} + +/** Calculate the interval (or NAK limit for bulk) for isoc and + * inter requests. + * @param pUrb the urb interval should be determined for + * @return the interval + */ +static uint8_t hdrc_interval(struct urb* pUrb) { + const unsigned int nPipe = pUrb->pipe; + uint8_t bInterval = (uint8_t)pUrb->interval; + + if( usb_pipeint(nPipe) ) { + /* correct interval for high-speed */ + if((USB_SPEED_HIGH == ((uint8_t)pUrb->dev->speed)) && (pUrb->interval > 255)) { + bInterval = find_first1(pUrb->interval); + } + } else { + /* normalize value */ + if(pUrb->interval > 16) { + bInterval = find_first1(pUrb->interval); + } + + if(usb_pipeisoc(nPipe) && (bInterval < 1)) { + bInterval = 1; + } + + if( usb_pipebulk(nPipe) && (bInterval < 2)) { + /* this is the NACK time */ + bInterval = 0;/*16;*/ + } + } + + DBG(2, "pipe_type=%s bInterval=%d\n", pipe_type(nPipe), bInterval); + + return bInterval; +} + +/** + * @param pUrb + */ +static inline uint8_t hdrc_type(struct urb* pUrb) { + uint8_t bStdType = 0; + const unsigned int nPipe = pUrb->pipe; + + if(usb_pipeisoc(nPipe)) { + bStdType = 1; + } else if(usb_pipeint(nPipe)) { + bStdType = 3; + } else if( usb_pipebulk(nPipe) ) { + bStdType = 2; + } + + return bStdType; +} + +/** + * program hdrc_registers for the device address of a given urb. + * @param pTjos + * @param pUrb + * @param bEnd + * @param bXmt + */ +static void hdrc_set_address(MGC_LinuxCd* pThis, struct urb* pUrb, uint8_t bEnd, + unsigned int bXmt) +{ +#ifdef MUSB_LINUX_MV21 + struct usb_device* pParent; +#endif + uint8_t* pBase = (uint8_t*)pThis->pRegs; + uint8_t bAddress = (uint8_t)usb_pipedevice(pUrb->pipe); + uint8_t bHubAddr = 0, bHubPort = 0, bIsMulti = FALSE; + + + /* NOTE: there is always a parent due to the virtual root hub */ + bHubAddr = (uint8_t)pUrb->dev->parent->devnum; + /* but not if parent is our virtual root hub */ + if(bHubAddr == pThis->RootHub.bAddress) { + bHubAddr = 0; + } + +#ifdef MUSB_LINUX_MV21 + /* parent hub address */ + pParent = pUrb->dev->parent; + + /* this distribution doesn't support directly, so try to find ourselves */ + if((USB_SPEED_HIGH!=((uint8_t)pUrb->dev->speed)) && + (pParent->devnum != pThis->RootHub.bAddress)) + { + int nChild; + struct usb_device* pDevice; + + /* walk up to first high-speed hub and remember our subtree's child */ + pDevice = pUrb->dev; + while(pParent && (USB_SPEED_HIGH != pParent->speed) && + (pParent->devnum != pThis->RootHub.bAddress)) + { + pDevice = pParent; + pParent = pParent->parent; + } + + if(pParent && (pParent->devnum != pThis->RootHub.bAddress)) { + /* correlate to port and check for multi-TT */ + for(nChild = 0; nChild < pParent->maxchild; nChild++) { + if(pParent->children[nChild] == pDevice) { + bHubPort = nChild + 1; + bIsMulti = (2 == pParent->descriptor.bDeviceProtocol); + break; + } + } + } + } +#else + /* if tt pointer, use its info */ + if(pUrb->dev->tt) { + bHubPort = (uint8_t)pUrb->dev->ttport; +#ifdef HAS_USB_TT_MULTI + bIsMulti = (uint8_t)pUrb->dev->tt->multi; +#endif + } +#endif + + if ( bIsMulti ) { + bHubAddr |=0x80; + } + + /* tx address */ + if(pThis->bIsMultipoint) { + /* target addr & hub addr/port */ + MGC_Write8(pBase, MGC_BUSCTL_OFFSET(bEnd, MGC_O_HDRC_TXFUNCADDR), + bAddress); + MGC_Write8(pBase, MGC_BUSCTL_OFFSET(bEnd, MGC_O_HDRC_TXHUBADDR), + bHubAddr); + MGC_Write8(pBase, MGC_BUSCTL_OFFSET(bEnd, MGC_O_HDRC_TXHUBPORT), + bHubPort); + + /* also, try Rx (this is a bug ion the core: I always need to to do + * both (at least for ep0), needs to be changed when the core is + * fixed */ + MGC_Write8(pBase, MGC_BUSCTL_OFFSET(bEnd, MGC_O_HDRC_RXFUNCADDR), + bAddress); + MGC_Write8(pBase, MGC_BUSCTL_OFFSET(bEnd, MGC_O_HDRC_RXHUBADDR), + bHubAddr); + MGC_Write8(pBase, MGC_BUSCTL_OFFSET(bEnd, MGC_O_HDRC_RXHUBPORT), + bHubPort); + } else { + /* non-multipoint core */ + + MGC_Write8(pBase, 0x80 + 8*bEnd, bAddress); + MGC_Write8(pBase, 0x84 + 8*bEnd, bAddress); + + } + + DBG(2, "end %d, device %d, parent %d, port %d, multi-tt: %d, speed:%d\n", \ + bEnd, pUrb->dev->devnum, bHubAddr, bHubPort, bIsMulti, pUrb->dev->speed ); +} + +/** + * @param pThis + * @param pUrb + * @param bEnd + * @param bXmt + */ +static void hdrc_set_protocol(MGC_LinuxCd* pThis, struct urb* pUrb, + uint8_t bEnd, unsigned int bXmt) +{ + uint8_t reg; + uint8_t bStdType = hdrc_type(pUrb); + unsigned int nPipe = pUrb->pipe; + uint8_t* pBase = (uint8_t*)pThis->pRegs; + + reg = (bStdType << 4 ) | + (((uint8_t)usb_pipeendpoint(nPipe)) & 0xf); + switch( ((uint8_t)pUrb->dev->speed) ) { + case USB_SPEED_LOW: + reg |= 0xc0; + break; + case USB_SPEED_FULL: + reg |= 0x80; + break; + default: + reg |= 0x40; + } + + if ( bXmt ) { + if(bEnd) { + MGC_WriteCsr8(pBase, MGC_O_HDRC_TXTYPE, bEnd, reg); + } else if(pThis->bIsMultipoint) { + MGC_WriteCsr8(pBase, MGC_O_HDRC_TYPE0, 0, reg & 0xc0); + } + } else { + if(bEnd) { + MGC_WriteCsr8(pBase, MGC_O_HDRC_RXTYPE, bEnd, reg); + } else if(pThis->bIsMultipoint) { + MGC_WriteCsr8(pBase, MGC_O_HDRC_TYPE0, 0, reg & 0xc0); + } + } +} + +static void mgc_hdrc_flush_fifo(MGC_LinuxCd* pThis, uint8_t bEnd, int rx) +{ + if ( rx ) { + /* twice in case of double packet buffering */ + MGC_WriteCsr16((uint8_t*)pThis->pRegs, MGC_O_HDRC_RXCSR, bEnd, + MGC_M_RXCSR_FLUSHFIFO | MGC_M_RXCSR_CLRDATATOG); + MGC_WriteCsr16((uint8_t*)pThis->pRegs, MGC_O_HDRC_RXCSR, bEnd, + MGC_M_RXCSR_FLUSHFIFO | MGC_M_RXCSR_CLRDATATOG); + } +} + +static void mgc_hdrc_flush_end(MGC_LinuxCd* pThis, uint8_t bEnd) { + uint8_t* pBase = (uint8_t*)pThis->pRegs; + MGC_LinuxLocalEnd* pEnd = &(pThis->aLocalEnd[bEnd]); + + if(bEnd) { + /* general endpoint */ + /* if not ready, flush and restore data toggle */ + if(!pEnd->bIsReady && pThis->bIsMultipoint) { + pEnd->bIsReady = TRUE; + + /* twice in case of double packet buffering */ + MGC_WriteCsr16(pBase, MGC_O_HDRC_TXCSR, bEnd, + MGC_M_TXCSR_FLUSHFIFO | MGC_M_TXCSR_CLRDATATOG); + MGC_WriteCsr16(pBase, MGC_O_HDRC_TXCSR, bEnd, + MGC_M_TXCSR_FLUSHFIFO | MGC_M_TXCSR_CLRDATATOG); + } + } else { + /* endpoint 0: just flush */ + MGC_WriteCsr16(pBase, MGC_O_HDRC_CSR0, bEnd, + MGC_M_CSR0_FLUSHFIFO); + MGC_WriteCsr16(pBase, MGC_O_HDRC_CSR0, bEnd, + MGC_M_CSR0_FLUSHFIFO); + } +} + +/** + * Program an HDRC endpoint as per the given URB + * @param pThis instance pointer + * @param bEnd local endpoint + * @param pURB URB pointer + * @param nOut zero for Rx; non-zero for Tx + * @param pBuffer buffer pointer + * @param dwLength how many bytes to transmit or expect to receive + */ +static void mgc_hdrc_program_end(MGC_LinuxCd* pThis, uint8_t bEnd, + struct urb* pUrb, unsigned int nOut, unsigned int bXmt, + uint8_t* pBuffer, uint32_t dwLength) +{ + uint16_t wIntrTxE; + uint8_t bDone = FALSE; + uint8_t* pBase = (uint8_t*)pThis->pRegs; + unsigned int nPipe = pUrb->pipe; + uint16_t wPacketSize = usb_maxpacket(pUrb->dev, nPipe, nOut); + uint8_t bIsBulk = usb_pipebulk(nPipe); + uint8_t bInterval=hdrc_interval(pUrb); + MGC_LinuxLocalEnd* pEnd = &(pThis->aLocalEnd[bEnd]); + uint8_t bStdType = hdrc_type(pUrb); + uint8_t bDmaOk=FALSE; +#ifdef MUSB_DMA + MGC_DmaChannel* pDmaChannel; + MGC_DmaController* pDmaController; +#endif + unsigned long flags; + + DBG(2, "<==(bEnd=%d, pUrb=%p) bRemoteAddress=%d\n", bEnd, pUrb, (uint8_t)usb_pipedevice(nPipe)); + DBG(3, "end %d, device %d, speed:%d\n", bEnd, pUrb->dev->devnum, + pUrb->dev->speed ); + + /* prepare endpoint registers according to flags */ + SPIN_LOCK_IRQSAVE(&pThis->Lock, flags); + MGC_SelectEnd(pBase, bEnd); + + if ( bStdType==0 ) { + bXmt=TRUE; + } + + hdrc_set_protocol(pThis, pUrb, bEnd, bXmt); + hdrc_set_address(pThis, pUrb, bEnd, bXmt); + + +#ifdef MUSB_DMA + pDmaController = pThis->pDmaController; + pDmaChannel = pEnd->pDmaChannel; + + if( !WANTS_DMA(pUrb) && pDmaChannel) { + /* release previously-allocated channel */ + pDmaController->pfDmaReleaseChannel(pDmaChannel); + pEnd->pDmaChannel = NULL; + } else if( WANTS_DMA(pUrb) ) { + + /* candidate for DMA */ + if(pDmaController && !pDmaChannel) { + pDmaChannel = pEnd->pDmaChannel = pDmaController->pfDmaAllocateChannel( + pDmaController->pPrivateData, bEnd, nOut ? TRUE : FALSE, + bStdType, wPacketSize); + + } + + if(pDmaChannel) { + pDmaChannel->dwActualLength = 0L; + pEnd->dwRequestSize = min(dwLength, pDmaChannel->dwMaxLength); + bDmaOk = pDmaController->pfDmaProgramChannel(pDmaChannel, + wPacketSize, pDmaChannel->bDesiredMode, DMA_BUFFER(pUrb), + pEnd->dwRequestSize); + if(!bDmaOk) { + pDmaController->pfDmaReleaseChannel(pDmaChannel); + pEnd->pDmaChannel = NULL; + } + } + } +#endif + + if ( bXmt ) { /* transmit */ + uint16_t wLoadCount=0; + uint16_t wCsr= MGC_M_TXCSR_MODE; + + if ( !bDmaOk ) { + if( bIsBulk && pThis->bBulkSplit ) { + wLoadCount = min((uint32_t)pEnd->wMaxPacketSizeTx, dwLength); + } else { + wLoadCount = min((uint32_t)wPacketSize, dwLength); + } + } + + /* disable interrupt in case we flush */ + wIntrTxE = MGC_Read16(pBase, MGC_O_HDRC_INTRTXE); + MGC_Write16(pBase, MGC_O_HDRC_INTRTXE, wIntrTxE & ~(1 << bEnd)); + + /* data toggle, make sure nothing is there! */ + mgc_hdrc_flush_end(pThis, bEnd); + + if( bEnd) { + wCsr |= MGC_M_TXCSR_H_WR_DATATOGGLE; + if(usb_gettoggle(pUrb->dev, pEnd->bEnd, 1)) { + wCsr |= MGC_M_TXCSR_H_DATATOGGLE; + } else { + wCsr &= ~MGC_M_TXCSR_H_DATATOGGLE; + } + + /* protocol/endpoint/interval/NAKlimit */ + if(bIsBulk && pThis->bBulkSplit) { + MGC_WriteCsr16(pBase, MGC_O_HDRC_TXMAXP, bEnd, + wPacketSize | + ((pEnd->wMaxPacketSizeTx / wPacketSize) - 1) << 11); + } else { + MGC_WriteCsr16(pBase, MGC_O_HDRC_TXMAXP, bEnd, wPacketSize); + } + MGC_WriteCsr8(pBase, MGC_O_HDRC_TXINTERVAL, bEnd, bInterval); + +#ifdef MUSB_DMA + if (bDmaOk) { + wCsr |= (MGC_M_TXCSR_AUTOSET | MGC_M_TXCSR_DMAENAB | + (pDmaChannel->bDesiredMode ? MGC_M_TXCSR_DMAMODE : 0)); + } +#endif + + mgc_linux_packet_tx(pThis, bEnd); + } else { + /* protocol/endpoint/interval/NAKlimit */ + MGC_WriteCsr8(pBase, MGC_O_HDRC_NAKLIMIT0, 0, bInterval); + if ( wLoadCount ) { + pEnd->dwRequestSize = wLoadCount; + MGC_HdrcLoadFifo(pThis->pRegs, bEnd, wLoadCount, pBuffer); + } + } + + /* re-enable interrupt and write CSR to transmit */ + MGC_Write16(pBase, MGC_O_HDRC_INTRTXE, wIntrTxE); + + if (bEnd) { + MGC_WriteCsr16(pBase, MGC_O_HDRC_TXCSR, bEnd, wCsr); + } + } else { /* receive */ + + /* if was programmed for Tx, be sure it is ready for re-use */ + uint16_t wCsr=MGC_ReadCsr16(pBase, MGC_O_HDRC_TXCSR, bEnd); + if ( pEnd->bIsSharedFifo && wCsr & MGC_M_TXCSR_MODE) { + pEnd->bIsReady = FALSE; + + DBG(1, "reprogramming ep%d for rx\n", bEnd); + + if ( wCsr & MGC_M_TXCSR_FIFONOTEMPTY ) { + /* this shouldn't happen */ + MGC_WriteCsr16(pBase, MGC_O_HDRC_TXCSR, bEnd, + MGC_M_TXCSR_FRCDATATOG); + MGC_WriteCsr16(pBase, MGC_O_HDRC_TXCSR, bEnd, + MGC_M_TXCSR_FRCDATATOG); + + ERR("*** switching end %d to Rx but Tx FIFO not empty\n", bEnd); + MGC_SLOW_DEVICE_KLUDGE_DELAY_TOP; + } + + /* clear mode (and everything else) to enable Rx */ + MGC_WriteCsr16(pBase, MGC_O_HDRC_TXCSR, bEnd, 0); + } + + /* grab Rx residual if any */ + wCsr = MGC_ReadCsr16(pBase, MGC_O_HDRC_RXCSR, bEnd); + if (wCsr & MGC_M_RXCSR_RXPKTRDY) { + uint16_t wRxCount = MGC_ReadCsr16(pBase, MGC_O_HDRC_RXCOUNT, bEnd); + bDone = mgc_linux_packet_rx(pThis, bEnd, wRxCount, FALSE); + DBG(1, "residual found bDone=%d\n", bDone); + } + + /* protocol/endpoint/interval/NAKlimit */ + if(bEnd) { +#if 0 + /* doesn't work reliably */ + if(bIsBulk && pThis->bBulkCombine) { + MGC_WriteCsr16(pBase, MGC_O_HDRC_RXMAXP, bEnd, wPacketSize | + ((min(pEnd->wMaxPacketSizeRx, dwLength) / wPacketSize) - 1) << 11); + } else { + MGC_WriteCsr16(pBase, MGC_O_HDRC_RXMAXP, bEnd, wPacketSize); + } +#endif + MGC_WriteCsr16(pBase, MGC_O_HDRC_RXMAXP, bEnd, wPacketSize); + MGC_WriteCsr8(pBase, MGC_O_HDRC_RXINTERVAL, bEnd, bInterval); + } + + /* first time or re-program and shared FIFO, flush & clear toggle */ + if(!pEnd->bIsReady && pEnd->bIsSharedFifo) { + DBG(4, "shared fifo\n"); + + /* twice in case of double packet buffering */ + MGC_WriteCsr16(pBase, MGC_O_HDRC_RXCSR, bEnd, + MGC_M_RXCSR_FLUSHFIFO | MGC_M_RXCSR_CLRDATATOG); + MGC_WriteCsr16(pBase, MGC_O_HDRC_RXCSR, bEnd, + MGC_M_RXCSR_FLUSHFIFO | MGC_M_RXCSR_CLRDATATOG); + pEnd->bIsReady = TRUE; + } + + /* program data toggle if possibly switching use */ + if(!pEnd->bIsReady && pThis->bIsMultipoint) { + DBG(4, "multipoint\n"); + + wCsr = MGC_M_RXCSR_H_WR_DATATOGGLE; + if(usb_gettoggle(pUrb->dev, pEnd->bEnd, 0)) { + wCsr |= MGC_M_RXCSR_H_DATATOGGLE; + } + + MGC_WriteCsr16(pBase, MGC_O_HDRC_RXCSR, bEnd, wCsr); + } + + /* kick things off */ + if( bEnd && !bDone) { + wCsr = MGC_M_RXCSR_H_REQPKT; + if(usb_pipeint(nPipe)) { + wCsr |= MGC_M_RXCSR_DISNYET; + } +#ifdef MUSB_DMA + if(bDmaOk) { + wCsr &= ~MGC_M_RXCSR_H_REQPKT; + wCsr |= MGC_M_RXCSR_H_AUTOREQ; + wCsr |= (MGC_M_RXCSR_AUTOCLEAR | MGC_M_RXCSR_DMAENAB | + (pDmaChannel->bDesiredMode ? MGC_M_RXCSR_DMAMODE : 0)); + } +#endif + MGC_WriteCsr16(pBase, MGC_O_HDRC_RXCSR, bEnd, wCsr); + } + } + SPIN_UNLOCK_IRQRESTORE(&pThis->Lock, flags); + DBG(2, "==>\n"); +} + +/* ************************************************************************* + * + **************************************************************************/ + +static void mgc_ep_linux_clear(MGC_LinuxLocalEnd* pEnd,MGC_LinuxCd* pThis) +{ + uint16_t wVal=0; + unsigned long flags; + uint8_t* pBase = (uint8_t*)pThis->pRegs; + + pEnd->dwOffset = 0; + pEnd->dwRequestSize = 0; + pEnd->dwIsoPacket = 0; + pEnd->dwWaitFrame = 0; + pEnd->bRetries = 0; + + /* do the proper sequence to abort the transfer */ + SPIN_LOCK_IRQSAVE(&pThis->Lock, flags); + + MGC_SelectEnd(pBase, pEnd->bEnd); + + if((pEnd->bRemoteEnd & 0x0F) == 0) + { + wVal |= MGC_M_CSR0_FLUSHFIFO; + wVal &= ~MGC_M_CSR0_H_REQPKT; + wVal &= ~MGC_M_CSR0_TXPKTRDY; + + MGC_WriteCsr16(pBase, MGC_O_HDRC_CSR0, 0, wVal); + } + else + { + if(pEnd->bIsTx) + { + wVal &= ~MGC_M_TXCSR_FIFONOTEMPTY; + wVal |= MGC_M_TXCSR_FLUSHFIFO; + MGC_WriteCsr16(pBase, MGC_O_HDRC_TXCSR, pEnd->bEnd, wVal); + MGC_WriteCsr16(pBase, MGC_O_HDRC_TXCSR, pEnd->bEnd, wVal); + MGC_WriteCsr8(pBase, MGC_O_HDRC_TXINTERVAL, pEnd->bEnd, 0); + } + else + { + wVal &= ~MGC_M_RXCSR_H_REQPKT; + MGC_WriteCsr16(pBase, MGC_O_HDRC_RXCSR, pEnd->bEnd, wVal); + MGC_WriteCsr8(pBase, MGC_O_HDRC_RXINTERVAL, pEnd->bEnd, 0); + } + } + + SPIN_UNLOCK_IRQRESTORE(&pThis->Lock, flags); + +#ifdef MUSB_USE_HCD_DRIVER + pEnd->pCurrentUrb=NULL; +#endif +} + +/** + * Start the current URB on an endpoint; wants ep to be + * locked and pThis to be locked as well; end must be claimed + * from the caller. + * + * @param pThis instance pointer + * @param bEnd local endpoint + * @pre the endpoint is locked from the caller + * @pre pThis is NOT locked + */ +static void mgc_linux_kickstart_urb(MGC_LinuxCd* pThis, uint8_t bEnd) +{ + uint16_t wFrame; + uint32_t dwLength; + void* pBuffer; + uint8_t* pBase = (uint8_t*)pThis->pRegs; + MGC_LinuxLocalEnd* pEnd = &(pThis->aLocalEnd[bEnd]); + struct urb* pUrb = MGC_GetCurrentUrb(pEnd); + unsigned int nPipe, nOut, bXmt; + uint16_t wPacketSize; + uint8_t bRemoteAddress, bRemoteEnd; + + /* I should not have called!!! */ + if ( !pUrb ) { + ERR("***> bEnd=%d is idle!\n", bEnd); + return; + } + + if ( pUrb->hcpriv ) { + ERR("==> pUrb=%p, pUrb->hcpriv=%p, pEnd=%p, bEnd=%d (%s) was kickstarted already! this is not good (TM)\n", + pUrb, pUrb->hcpriv, pEnd, bEnd, decode_urb_protocol(pUrb)); + } + + nPipe = pUrb->pipe; + nOut = usb_pipeout(nPipe); + bXmt = nOut ? TRUE : FALSE; + wPacketSize = usb_maxpacket(pUrb->dev, nPipe, nOut); + bRemoteAddress = (uint8_t)usb_pipedevice(nPipe); + bRemoteEnd = (uint8_t)usb_pipeendpoint(nPipe); + + DBG(2, "<== pUrb=%p, bEnd=%d, wPacketSize=%d, bRemoteAddress=%d, bRemoteEnd=%d, nOut=%d\n", + pUrb, bEnd, wPacketSize, bRemoteAddress, bRemoteEnd, nOut); + + /* if no root device, assume this must be it */ + if(!pThis->pRootDevice) { + pThis->pRootDevice = pUrb->dev; + switch(pThis->bRootSpeed) { + case 1: + pThis->pRootDevice->speed = USB_SPEED_HIGH; + break; + case 2: + pThis->pRootDevice->speed = USB_SPEED_FULL; + break; + case 3: + pThis->pRootDevice->speed = USB_SPEED_LOW; + break; + } + } + + /* indicate in progress */ + pUrb->actual_length = 0; + pUrb->error_count = 0; + pUrb->hcpriv = pEnd; + /* remember software state - find_end() will use this - */ + pEnd->bRemoteAddress = bRemoteAddress; + pEnd->bRemoteEnd = bRemoteEnd; + pEnd->bTrafficType = (uint8_t)usb_pipetype(nPipe); + pEnd->bIsTx=bXmt; + + /* init urb */ + pEnd->dwOffset = 0; + pEnd->dwRequestSize = 0; + pEnd->dwIsoPacket = 0; + pEnd->dwWaitFrame = 0; + pEnd->bRetries = 0; + pEnd->wPacketSize = wPacketSize; + +#ifdef MUSB_USE_HCD_DRIVER + pEnd->pCurrentUrb=pUrb; +#endif + + /* pEnd->bIsClaimed=(usb_pipeisoc(nPipe) || usb_pipeint(nPipe)) ?TRUE:FALSE; + * end must be claimed from my caller + */ + if( usb_pipecontrol(nPipe) ) { + /* control transfers always start with an OUT */ + bXmt=TRUE; + pEnd->bIsTx=TRUE; + pThis->bEnd0Stage = MGC_END0_START; + } + + /* gather right source of data */ + if( usb_pipeisoc(nPipe) ) { + pBuffer = pUrb->transfer_buffer + pUrb->iso_frame_desc[0].offset; + dwLength = pUrb->iso_frame_desc[0].length; + } else if(usb_pipecontrol(nPipe)) { + pBuffer = pUrb->setup_packet; + dwLength = 8; + } else { + /* - */ + pBuffer = pUrb->transfer_buffer; + dwLength = pUrb->transfer_buffer_length; + } + +#ifndef MUSB_LINUX_MV21 + if ( !pBuffer ) { + pBuffer=(void*)phys_to_virt(pUrb->transfer_dma); + } +#endif + + /* abort the transfer */ + if ( !pBuffer ) { + ERR("Rx requested but no buffer was given, BAD things are happening (TM)! aborting\n"); + return; + } + + DBG(3, "(%p): dir=%s, type=%d, wPacketSize=%d, bRemoteAddress=%d, bRemoteEnd=%d, pBuffer=%p\n", \ + pUrb, (nOut)?"out":"in", usb_pipetype(nPipe), wPacketSize, bRemoteAddress, + bRemoteEnd, pBuffer); + + /* Configure endpoint */ + mgc_hdrc_program_end(pThis, bEnd, pUrb, nOut, bXmt, pBuffer, dwLength); + + /* if transmit, start it if it is time */ + if ( !bXmt ) { + DBG(2, "==>\n"); + return; + } + + /* determine if the time is right for a periodic transfer */ + if( usb_pipeisoc(nPipe) || usb_pipeint(nPipe) ) { + DBG(3, "check whether there's still time for periodic Tx\n"); + pEnd->dwIsoPacket = 0; + wFrame = MGC_Read16(pBase, MGC_O_HDRC_FRAME); + + if((pUrb->transfer_flags & USB_ISO_ASAP) || + (wFrame >= pUrb->start_frame)) + { + pEnd->dwWaitFrame = 0; + MGC_HdrcStartTx(pThis, bEnd); + } else { + pEnd->dwWaitFrame = pUrb->start_frame; + /* enable SOF interrupt so we can count down */ + MGC_Write8(pBase, MGC_O_HDRC_INTRUSBE, 0xff); + } + } else { + MGC_HdrcStartTx(pThis, bEnd); + } + + DBG(2, "==>\n"); +} + +/** + * Start the next URB on an endpoint. Wants the _endpoint_ to be locked. + * It might call MGC_LinuxStartUrb pThis needs to be locked as well.. + * THIS UNLOCK THE END POINT. + * + * @param pThis instance pointer + * @param bEnd local endpoint + */ +static void mgc_linux_start_next_urb(MGC_LinuxCd* pThis, uint8_t bEnd) +{ +#ifndef MUSB_USE_HCD_DRIVER + struct urb* pUrb; + MGC_LinuxLocalEnd* pEnd = &(pThis->aLocalEnd[bEnd]); + + DBG(1, "<== bEnd=%d\n", bEnd); + pUrb=MGC_GetCurrentUrb(pEnd); + if ( !pUrb ) { + DBG(2, "==> bEnd=%d idle\n", bEnd); + return; + } + + /* introduce a delay between urbs, to accomodate slow devices. The counter + * is increased on every NAK/TIMEOUT and decreased on successful transfers + * (eps != 0 ) + */ + if ( mgc_slow_device_kludge_delay ) { + DBG(1, "Delay mgc_slow_device_kludge_delay=%d\n", + mgc_slow_device_kludge_delay); + udelay( mgc_slow_device_kludge_delay*20 ); + } + + /* check for linked URB and jump start the next one */ + mgc_linux_kickstart_urb(pThis, bEnd); +#else + DBG(1, "<== bEnd=%d\n", bEnd); + if ( MUSB_IS_HST(pThis) ) { + mgc_hcd_schedule_urb(pThis); + } +#endif + DBG(1, "==>\n"); +} + +/* ************************************************************************* + * + **************************************************************************/ + +/** + * Try to stop traffic on the given local endpoint. Don;t worry about the + * urbs, they will be flushed from the system (later on). + * + * @param pThis the controller + * @param bEnd the endpoint number. + */ +void MGC_HdrcStopEnd(MGC_LinuxCd* pThis, uint8_t bEnd) +{ + uint16_t wCsr; + uint8_t* pBase = (uint8_t*)pThis->pRegs; + const uint8_t reg=(bEnd)?MGC_O_HDRC_RXCSR:MGC_O_HDRC_CSR0; + + DBG(2, "<== ep%d\n", bEnd); + wCsr = MGC_ReadCsr16(pBase, reg, bEnd); + wCsr &= (bEnd)?~MGC_M_RXCSR_H_REQPKT:~MGC_M_CSR0_H_REQPKT; + MGC_WriteCsr16(pBase, reg, bEnd, wCsr); + DBG(2, "==>\n"); +} + +/* ************************************************************************* + * + **************************************************************************/ + +/** + * Service the default endpoint (ep0) as host. + * @param pThis this + * @param wCount current byte count in FIFO + * @param pUrb URB pointer for EP0 + * @return TRUE if more packets are required for this transaction + */ +static uint8_t mgc_hdrc_service_host_default(MGC_LinuxCd* pThis, + uint16_t wCount, struct urb* pUrb) +{ + uint8_t bMore = FALSE; + uint8_t* pFifoDest = NULL; + uint16_t wFifoCount = 0; + uint8_t* pBase = (uint8_t*)pThis->pRegs; + MGC_LinuxLocalEnd* pEnd = &(pThis->aLocalEnd[0]); + MUSB_DeviceRequest* pRequest = (MUSB_DeviceRequest*)pUrb->setup_packet; + + DBG(2, "<== (wCount=%04x, pUrb=%lx, bStage=%02x)\n", + wCount, (unsigned long)pUrb, pThis->bEnd0Stage); + + if(MGC_END0_IN == pThis->bEnd0Stage) { + /* we are receiving from peripheral */ + pFifoDest = pUrb->transfer_buffer + pUrb->actual_length; + wFifoCount = min(wCount, ((uint16_t)(pUrb->transfer_buffer_length - pUrb->actual_length))); + + DBG(3, "Receiving %d bytes in &%p[%d] (pUrb->actual_length=%u)\n", + wFifoCount, pUrb->transfer_buffer, (unsigned int)pUrb->actual_length, + pUrb->actual_length ); + + MGC_HdrcUnloadFifo(pBase, 0, wFifoCount, pFifoDest); + +#ifdef MUSB_CONFIG_PROC_FS + pEnd->dwTotalRxBytes += wFifoCount; + pEnd->dwTotalRxPackets++; +#endif + + pUrb->actual_length += wFifoCount; + if((pUrb->actual_length < pUrb->transfer_buffer_length) && + (wCount == pEnd->wPacketSize)) + { + bMore = TRUE; + } + } else { + /* we are sending to peripheral */ + if((MGC_END0_START == pThis->bEnd0Stage) && + (pRequest->bmRequestType & USB_DIR_IN)) + { + DBG(3, "just did setup, switching to IN\n"); + + /* this means we just did setup; switch to IN */ + pThis->bEnd0Stage = MGC_END0_IN; + bMore = TRUE; + +#ifdef MUSB_CONFIG_PROC_FS + pEnd->dwTotalTxBytes += 8; + pEnd->dwTotalTxPackets++; +#endif + } else if(pRequest->wLength && (MGC_END0_START == pThis->bEnd0Stage)) { + pThis->bEnd0Stage = MGC_END0_OUT; + pFifoDest = (uint8_t*)(pUrb->transfer_buffer + pUrb->actual_length); + wFifoCount = min(pEnd->wPacketSize, + ((uint16_t)(pUrb->transfer_buffer_length - pUrb->actual_length))); + DBG(3, "Sending %d bytes to %p\n", wFifoCount, pFifoDest); + MGC_HdrcLoadFifo(pBase, 0, wFifoCount, pFifoDest); + +#ifdef MUSB_CONFIG_PROC_FS + pEnd->dwTotalTxBytes += wFifoCount; + pEnd->dwTotalTxPackets++; +#endif + pEnd->dwRequestSize = wFifoCount; + pUrb->actual_length += wFifoCount; + if(wFifoCount) { + bMore = TRUE; + } + } + } + + return bMore; +} + +/* ************************************************************************* + * Default end (end 0) + **************************************************************************/ + +/** + * Handle default endpoint interrupt as host. Only called in IRQ time + * from the LinuxIsr() interrupt service routine. + * @param pThis this + */ +void MGC_HdrcServiceDefaultEnd(MGC_LinuxCd* pThis) +{ + struct urb* pUrb; + unsigned long flags; + uint16_t wCsrVal, wCount; + int status = USB_ST_NOERROR; + uint8_t* pBase = (uint8_t*)pThis->pRegs; + MGC_LinuxLocalEnd* pEnd = &(pThis->aLocalEnd[0]); + uint8_t bVal, bOutVal = 0, bComplete = FALSE, bError = FALSE; + struct usb_descriptor_header *header; + MUSB_DeviceRequest* pRequest; + + DBG(2, "<==\n"); + + spin_lock(&pEnd->Lock); + pUrb = MGC_GetCurrentUrb(pEnd); + + /* check URB */ +#ifdef MUSB_PARANOID + if( pUrb && (pUrb->hcpriv!=pEnd)) { + ERR("==> corrupt URB %p!!! from now on \"bad things will happen\"\n", + pUrb); + spin_unlock(&pEnd->Lock); + return; + } +#endif + + SPIN_LOCK_IRQSAVE(&pThis->Lock, flags); + MGC_SelectEnd(pBase, 0); + wCsrVal = MGC_ReadCsr16(pBase, MGC_O_HDRC_CSR0, 0); + wCount = MGC_ReadCsr8(pBase, MGC_O_HDRC_COUNT0, 0); + bVal = (uint8_t)wCsrVal; + + DBG(2, "<== CSR0=%04x, wCount=%04x\n", wCsrVal, wCount); + + /* if we just did status stage, we are done */ + if(MGC_END0_STATUS == pThis->bEnd0Stage) { + bComplete = TRUE; + } + + /* prepare status */ + if((MGC_END0_START == pThis->bEnd0Stage) && !wCount && + (wCsrVal & MGC_M_CSR0_RXPKTRDY)) + { + DBG(2, "missed data\n"); + + /* just started and got Rx with no data, so probably missed data */ + status = USB_ST_SHORT_PACKET; + bError = TRUE; + + MGC_WriteCsr16(pBase, MGC_O_HDRC_CSR0, 0, MGC_M_CSR0_FLUSHFIFO); + MGC_WriteCsr16(pBase, MGC_O_HDRC_CSR0, 0, MGC_M_CSR0_FLUSHFIFO); + } + + if(bVal & MGC_M_CSR0_H_RXSTALL) { + DBG(2, "STALLING ENDPOINT 0\n"); + status = USB_ST_STALL; + bError = TRUE; + } else if(bVal & MGC_M_CSR0_H_ERROR) { + DBG(3, "ep0 no response (error)\n"); + DEBUG_CODE(3, MGC_HDRC_DUMPREGS(pThis, 0); ); + + status = USB_ST_NORESPONSE; + bError = TRUE; + } else if(bVal & MGC_M_CSR0_H_NAKTIMEOUT) { + DBG(2, "ep0 NAK timeout pEnd->bRetries=%d\n", pEnd->bRetries); + + if( ++pEnd->bRetries < MUSB_MAX_RETRIES) { + /* cover it up if retries not exhausted */ + MGC_WriteCsr16(pBase, MGC_O_HDRC_CSR0, 0, 0); + } else { + DBG(3, "no response (NAK timeout)\n"); + DEBUG_CODE(3, MGC_HDRC_DUMPREGS(pThis, 0); ); + pEnd->bRetries=0; + status = USB_ST_NORESPONSE; + bError = TRUE; + } + } + + if(USB_ST_NORESPONSE == status) { + DBG(2, "ep0 aborting\n"); + + /* use the proper sequence to abort the transfer */ + if(bVal & MGC_M_CSR0_H_REQPKT) { + bVal &= ~MGC_M_CSR0_H_REQPKT; + MGC_WriteCsr16(pBase, MGC_O_HDRC_CSR0, 0, bVal); + bVal &= ~MGC_M_CSR0_H_NAKTIMEOUT; + MGC_WriteCsr16(pBase, MGC_O_HDRC_CSR0, 0, bVal); + } else { + bVal |= MGC_M_CSR0_FLUSHFIFO; + MGC_WriteCsr16(pBase, MGC_O_HDRC_CSR0, 0, bVal); + MGC_WriteCsr16(pBase, MGC_O_HDRC_CSR0, 0, bVal); + bVal &= ~MGC_M_CSR0_H_NAKTIMEOUT; + MGC_WriteCsr16(pBase, MGC_O_HDRC_CSR0, 0, bVal); + } + + MGC_WriteCsr8(pBase, MGC_O_HDRC_NAKLIMIT0, 0, 0); + } + + if(bError) { + DBG(3, "ep0 handling error\n"); + + /* clear it */ + MGC_WriteCsr16(pBase, MGC_O_HDRC_CSR0, 0, 0); + +#ifdef MUSB_CONFIG_PROC_FS + switch(pThis->bEnd0Stage) { + case MGC_END0_START: + case MGC_END0_OUT: + pEnd->dwErrorTxPackets++; + break; + case MGC_END0_IN: + pEnd->dwErrorRxPackets++; + break; + } +#endif + + } + + if(!pUrb) { + /* stop endpoint since we have no place for its data, this + * SHOULD NEVER HAPPEN! */ + DBG(1, "no URB for end 0\n"); + + MGC_WriteCsr16(pBase, MGC_O_HDRC_CSR0, 0, MGC_M_CSR0_FLUSHFIFO); + MGC_WriteCsr16(pBase, MGC_O_HDRC_CSR0, 0, MGC_M_CSR0_FLUSHFIFO); + MGC_WriteCsr16(pBase, MGC_O_HDRC_CSR0, 0, 0); + + /* start next URB that might be queued for it */ + spin_unlock(&pEnd->Lock); + DBG(2, "==>\n"); + SPIN_UNLOCK_IRQRESTORE(&pThis->Lock, flags); + return; + } + + if(!bComplete && !bError) { + + /* call common logic and prepare response */ + if( mgc_hdrc_service_host_default(pThis, wCount, pUrb) ) { + /* more packets required */ + bOutVal = (MGC_END0_IN == pThis->bEnd0Stage) ? + MGC_M_CSR0_H_REQPKT : MGC_M_CSR0_TXPKTRDY; + DBG(3, "Need more bytes bOutVal=%04x\n", bOutVal); + } else { + /* data transfer complete; perform status phase */ + bOutVal = MGC_M_CSR0_H_STATUSPKT | + (usb_pipeout(pUrb->pipe) ? MGC_M_CSR0_H_REQPKT : + MGC_M_CSR0_TXPKTRDY); + + /* flag status stage */ + pThis->bEnd0Stage = MGC_END0_STATUS; + DBG(3, "Data transfer complete, status phase bOutVal=%04x\n", \ + bOutVal); + } + } + + /* write CSR0 if needed */ + if(bOutVal) { + MGC_WriteCsr16(pBase, MGC_O_HDRC_CSR0, 0, bOutVal); + } + + /* call completion handler if done */ + if(bComplete || bError) { + DBG(3, "completing cntrl URB %p, status=%d, len=%x\n", \ + pUrb, status, pUrb->actual_length); + + /* Hub Class not supported */ + if((pUrb->dev == pThis->pRootDevice)) + { + pRequest = (MUSB_DeviceRequest*)pUrb->setup_packet; + + if((USB_REQ_GET_DESCRIPTOR == pRequest->bRequest) && + (USB_DIR_IN == pRequest->bmRequestType) && + (USB_DT_DEVICE == pUrb->setup_packet[3]) && + (pUrb->setup_packet[6] >= USB_DT_DEVICE_SIZE)) + { + + header = (struct usb_descriptor_header*)pUrb->transfer_buffer; + if((header->bDescriptorType == USB_DT_DEVICE) && + (*((char*)pUrb->transfer_buffer + 4) == USB_CLASS_HUB)) + { + printk("Hub Class NOT support \n"); + /* Will pass error to upper stack */ + status = -ENODEV; + } + } + } + if ( mgc_ep_dequeue_urb(pEnd, pUrb,pThis)==0 ) { + spin_unlock(&pEnd->Lock); + pUrb->status = status; + if ( mgc_linux_complete_urb(pThis, pEnd, pUrb)==0 ) { + mgc_linux_start_next_urb(pThis, 0); + } + } else { + ERR("*** pUrb=%p is not queued to bEnd=%d\n", pUrb, + pEnd->bEnd); + } + } else { + spin_unlock(&pEnd->Lock); + } + + DBG(2, "==>\n"); + SPIN_UNLOCK_IRQRESTORE(&pThis->Lock, flags); +} + +/************************************************************************** + * EP1-n Tx and Rx data + **************************************************************************/ + +static void complete_ep_urb(MGC_LinuxCd* pThis, MGC_LinuxLocalEnd* pEnd, + struct urb* pUrb, int toggle) +{ + + if (pUrb->status==USB_ST_STALL) { + toggle=0; + } + + /* save data toggle */ + + usb_settoggle(pUrb->dev, pEnd->bEnd, (pEnd->bIsTx)?1:0, toggle); + /* we re-use bulk, so re-programming required */ + pEnd->bIsReady = FALSE; + + if (pUrb->status) { + DBG(1, "completing Tx URB=%p, status=%d, len=%x\n", \ + pUrb, pUrb->status, pUrb->actual_length); + } + + if ( mgc_ep_dequeue_urb(pEnd, pUrb,pThis)==0 ) { + spin_unlock(&pEnd->Lock); + if ( mgc_linux_complete_urb(pThis, pEnd, pUrb)==0 ) { + mgc_linux_start_next_urb(pThis, pEnd->bEnd); + } + } else { + ERR("*** pUrb=%p is not queued to bEnd=%d, this is BAD!\n", pUrb, + pEnd->bEnd); + } +} + +/** + * Service a Tx-Available interrupt for the given endpoint. + + * @param pThis instance pointer + * @param bEnd local endpoint + */ +void MGC_HdrcServiceTxAvail(MGC_LinuxCd* pThis, uint8_t bEnd) +{ + int skip=0; + struct urb* pUrb; + unsigned long flags; + uint16_t wTxCsrVal, wVal=0; + MGC_LinuxLocalEnd* pEnd = &(pThis->aLocalEnd[bEnd]); + uint8_t* pBase = (uint8_t*)pThis->pRegs; + uint32_t dev_status = 0; + + DBG(1, "<==\n"); + + spin_lock(&pEnd->Lock); + pUrb = MGC_GetCurrentUrb(pEnd); + if ( !pUrb ) { + MGC_SLOW_DEVICE_KLUDGE_DELAY_DECREASE; + spin_unlock(&pEnd->Lock); + DBG(2, "==> tx ep empty\n"); + return; + } + + if ( !pUrb->hcpriv ) { + DBG(2, "==> kickstarting it\n"); + mgc_linux_kickstart_urb(pThis, bEnd); + spin_unlock(&pEnd->Lock); + return; + } + + if ( !MUSB_IS_HST(pThis) ) { + complete_ep_urb(pThis, pEnd, pUrb, 0); + return; + } + + + SPIN_LOCK_IRQSAVE(&pThis->Lock, flags); + MGC_SelectEnd(pBase, bEnd); + + wVal = wTxCsrVal = MGC_ReadCsr16(pBase, MGC_O_HDRC_TXCSR, bEnd); + +#if MUSB_DEBUG > 0 + /* check URB */ + if( pUrb && (pUrb->hcpriv != pEnd) ) { + ERR("==> end %d has corrupt URB %lx!\n", bEnd, (unsigned long)pUrb); + spin_unlock(&pEnd->Lock); + SPIN_UNLOCK_IRQRESTORE(&pThis->Lock, flags); + return; + } +#endif + + DBG(3, "end %d wTxCsrVal=%04x\n", bEnd, wTxCsrVal); + + do { + uint32_t status = 0; + + /* check for errors */ + if(wTxCsrVal & MGC_M_TXCSR_H_RXSTALL) { + pEnd->bStalled=TRUE; + DBG(1, "TX end %d stall\n", bEnd); + status = USB_ST_STALL; + MGC_SLOW_DEVICE_KLUDGE_DELAY_INCREASE; + } else if(wTxCsrVal & MGC_M_TXCSR_H_ERROR) { + WARN("TX data error on ep=%d\n", bEnd); + status = USB_ST_NORESPONSE; + dev_status = status; + /* do the proper sequence to abort the transfer */ + wVal &= ~MGC_M_TXCSR_FIFONOTEMPTY; + wVal |= MGC_M_TXCSR_FLUSHFIFO; + + MGC_WriteCsr16(pBase, MGC_O_HDRC_TXCSR, bEnd, wVal); + MGC_WriteCsr16(pBase, MGC_O_HDRC_TXCSR, bEnd, wVal); + +#ifdef MUSB_CONFIG_PROC_FS + pEnd->dwErrorTxPackets++; +#endif + } + else if( wTxCsrVal & MGC_M_TXCSR_H_NAKTIMEOUT ) { + /* cover it up if retries not exhausted */ + if( pUrb->status==-EINPROGRESS && ++pEnd->bRetries < MUSB_MAX_RETRIES ) + { + MGC_WriteCsr16(pBase, MGC_O_HDRC_CSR0, 0, + MGC_M_TXCSR_TXPKTRDY); + + MGC_SLOW_DEVICE_KLUDGE_DELAY_INCREASE; + DBG(2, "tx error on ep%d, mgc_slow_device_kludge_delay=%d\n", + bEnd, mgc_slow_device_kludge_delay); + spin_unlock(&pEnd->Lock); + DBG(2, "==> cover tx error\n"); + SPIN_UNLOCK_IRQRESTORE(&pThis->Lock, flags); + return; + } + + if ( pUrb->status==-EINPROGRESS ) { + status = -ECONNRESET; + } + + WARN("device not responding on ep=%d\n", bEnd); + + + /* do the proper sequence to abort the transfer */ + wVal &= ~MGC_M_TXCSR_FIFONOTEMPTY; + wVal |= MGC_M_TXCSR_FLUSHFIFO; + MGC_WriteCsr16(pBase, MGC_O_HDRC_TXCSR, bEnd, wVal); + MGC_WriteCsr16(pBase, MGC_O_HDRC_TXCSR, bEnd, wVal); + MGC_WriteCsr8(pBase, MGC_O_HDRC_TXINTERVAL, bEnd, 0); + +#ifdef MUSB_CONFIG_PROC_FS + pEnd->dwErrorTxPackets++; +#endif + pEnd->bRetries=0; + } else if( wTxCsrVal & MGC_M_TXCSR_FIFONOTEMPTY ) { + /* whopps, dbould buffering better be enabled */ +#ifdef MUSB_PARANOID + /* guess what?? */ +#endif + skip=TRUE; + break; + } + + if ( status ) { + + pUrb->status=status; /* */ + + if ( USB_ST_STALL!=status ) { + DBG(1, "Tx error on bEnd=%d, pUrb=%p, status=%d, proto=%s\n", + bEnd, pUrb, status, decode_urb_protocol(pUrb)); + DEBUG_CODE(3, MGC_HDRC_DUMPREGS(pThis, bEnd); ); + } + + /* reset error bits */ + wVal &= ~(MGC_M_TXCSR_H_ERROR | MGC_M_TXCSR_H_RXSTALL | + MGC_M_TXCSR_H_NAKTIMEOUT); + wVal |= MGC_M_TXCSR_FRCDATATOG; + MGC_WriteCsr16(pBase, MGC_O_HDRC_TXCSR, bEnd, wVal); + } + + } while (0); + + + if ( !skip && pUrb->status==-EINPROGRESS ) { + mgc_linux_packet_tx(pThis, bEnd); + } + + /* complete the current request or start next tx transaction */ + if ( pUrb->status!=-EINPROGRESS ) { + int toggle=(pUrb->status==USB_ST_STALL) + ? 0 + : ((wVal & MGC_M_TXCSR_H_DATATOGGLE) ? 1 : 0); + pUrb->actual_length = pEnd->dwOffset; + SPIN_UNLOCK_IRQRESTORE(&pThis->Lock, flags); + complete_ep_urb(pThis, pEnd, pUrb, toggle); + } else { + spin_unlock(&pEnd->Lock); + if ( !skip ) { + + MGC_WriteCsr16(pBase, MGC_O_HDRC_TXCSR, bEnd, + MGC_M_TXCSR_TXPKTRDY); + } + DBG(1, "==>\n"); + SPIN_UNLOCK_IRQRESTORE(&pThis->Lock, flags); + } +} + +/** + * Service an Rx-Ready interrupt for the given endpoint; see section 18.2.1 + * of the manual for details. + * @param pThis instance pointer + * @param bEnd local endpoint + */ +void MGC_HdrcServiceRxReady(MGC_LinuxCd* pThis, uint8_t bEnd) +{ + struct urb* pUrb; + unsigned long flags; + uint16_t wRxCount, wRxCsrVal, wVal=0; + uint8_t bIsochError = FALSE; + MGC_LinuxLocalEnd* pEnd = &(pThis->aLocalEnd[bEnd]); + uint8_t* pBase = (uint8_t*)pThis->pRegs; + + DBG(2, "<== end%d\n", bEnd); + spin_lock(&pEnd->Lock); + DBG(3, "locked end%d, pUrb=%p\n", bEnd, MGC_GetCurrentUrb(pEnd)); + + pUrb = MGC_GetCurrentUrb(pEnd); + if ( !pUrb ) { + /* THIS SHOULD NEVER HAPPEN */ + /* stop endpoint since we have no place for its data */ + MGC_SLOW_DEVICE_KLUDGE_DELAY_DECREASE; + spin_unlock(&pEnd->Lock); + DBG(1, "==> no RX URB on end %d!\n", bEnd); + return; + } + + if ( !pUrb->hcpriv ) { + DBG(1, "==> kickstarting it\n"); + mgc_linux_kickstart_urb(pThis, bEnd); + spin_unlock(&pEnd->Lock); + return; + } + +#ifdef MUSB_PARANOID + /* check URB */ + if ( pUrb->hcpriv!=pEnd ) { + ERR("==> pUrb=%p on bEnd=%d (hcpriv=%p) is corrupt!\n", pUrb, bEnd, pUrb->hcpriv); + /* about the urb? */ + spin_unlock(&pEnd->Lock); + return; + } +#endif + + if ( !MUSB_IS_HST(pThis) ) { + complete_ep_urb(pThis, pEnd, pUrb, 0); + return; + } + + SPIN_LOCK_IRQSAVE(&pThis->Lock, flags); + MGC_SelectEnd(pBase, bEnd); + wVal = wRxCsrVal = MGC_ReadCsr16(pBase, MGC_O_HDRC_RXCSR, bEnd); + wRxCount = MGC_ReadCsr16(pBase, MGC_O_HDRC_RXCOUNT, bEnd); + + DBG(3, "end %d wRxCsrVal=%04x, wRxCount=%d, pUrb->actual_length=%d\n", bEnd, + wRxCsrVal, wRxCount, pUrb->actual_length); + + do { + uint32_t status = 0; + + /* check for errors, concurrent stall & unlink is not really + * handled yet! */ + if ( wRxCsrVal & MGC_M_RXCSR_H_RXSTALL ) { + pEnd->bStalled=TRUE; + DBG(1, "RX end %d STALL\n", bEnd); + status = USB_ST_STALL; + } else if(wRxCsrVal & MGC_M_RXCSR_H_ERROR) { + DBG(1, "end %d Rx error\n", bEnd); + DEBUG_CODE(1, MGC_HDRC_DUMPREGS(pThis, bEnd); ); + status=-ECONNRESET; + + /* do the proper sequence to abort the transfer */ + wVal &= ~MGC_M_RXCSR_H_REQPKT; + MGC_WriteCsr16(pBase, MGC_O_HDRC_RXCSR, bEnd, wVal); + MGC_WriteCsr8(pBase, MGC_O_HDRC_RXINTERVAL, bEnd, 0); + +#ifdef MUSB_CONFIG_PROC_FS + pEnd->dwErrorRxPackets++; +#endif + } else if(wRxCsrVal & MGC_M_RXCSR_DATAERROR) { + + if (PIPE_BULK == pEnd->bTrafficType) { + /* cover it up if retries not exhausted, slow devices might + * not answer quickly enough: I was expecting a packet but the + * packet didn't come. The interrupt is generated after 3 failed + * attempts, it make MUSB_MAX_RETRIESx3 attempts total.. + */ + if ( pUrb->status==-EINPROGRESS && + ++pEnd->bRetries < MUSB_MAX_RETRIES) + { + /* silently ignore it */ + wRxCsrVal &= ~ MGC_M_RXCSR_DATAERROR; + wRxCsrVal &= ~MGC_M_RXCSR_RXPKTRDY; + MGC_WriteCsr16(pBase, MGC_O_HDRC_RXCSR, bEnd, + wRxCsrVal | MGC_M_RXCSR_H_REQPKT); + + MGC_SLOW_DEVICE_KLUDGE_DELAY_INCREASE; + DBG(1, "rx error on ep%d, mgc_slow_device_kludge_delay=%d\n", + bEnd, mgc_slow_device_kludge_delay); + spin_unlock(&pEnd->Lock); + DBG(2, "==> cover rx error\n"); + SPIN_UNLOCK_IRQRESTORE(&pThis->Lock, flags); + return; + } + + if ( pUrb->status==-EINPROGRESS ) { + DBG(-1, "urb=%p, protocol=%s timed out\n", pUrb, + decode_urb_protocol(pUrb)); + status=-ECONNRESET; + } + + wVal &= ~MGC_M_RXCSR_H_REQPKT; + MGC_WriteCsr16(pBase, MGC_O_HDRC_RXCSR, bEnd, wVal); + MGC_WriteCsr8(pBase, MGC_O_HDRC_RXINTERVAL, bEnd, 0); + pEnd->bRetries=0; + + /* do the proper sequence to abort the transfer; + * am I dealing with a slow device maybe? */ + DBG(3, "end=%d device not responding\n", bEnd); + + } else if(PIPE_ISOCHRONOUS == pEnd->bTrafficType) { + DBG(3, "bEnd=%d Isochronous error\n", bEnd); + bIsochError = TRUE; + } + +#ifdef MUSB_CONFIG_PROC_FS + pEnd->dwErrorRxPackets++; +#endif + } + + /* an error won't process the data */ + if ( status ) { + pUrb->status=status; + + /* data errors are signaled */ + if ( USB_ST_STALL!=status ) { + DBG(3, "end %d Rx error, status=%d\n", bEnd, status); + DEBUG_CODE(3, MGC_HDRC_DUMPREGS(pThis, bEnd); ); + } else { + mgc_hdrc_flush_fifo(pThis, bEnd, 1); + } + + DBG(3, "clearing all error bits, right away\n"); + wVal &= ~(MGC_M_RXCSR_H_ERROR | MGC_M_RXCSR_DATAERROR | + MGC_M_RXCSR_H_RXSTALL ); + wVal &= ~MGC_M_RXCSR_RXPKTRDY; + MGC_WriteCsr16(pBase, MGC_O_HDRC_RXCSR, bEnd, wVal); + } + + } while (0); + + /* no errors, unload... */ + if ( pUrb->status==-EINPROGRESS ) { + + /* be sure a packet is ready for unloading */ + if( !wRxCsrVal & MGC_M_RXCSR_RXPKTRDY ) { + pUrb->status = USB_ST_INTERNALERROR; + /* do the proper sequence to abort the transfer */ + wVal &= ~MGC_M_RXCSR_H_REQPKT; + MGC_WriteCsr16(pBase, MGC_O_HDRC_RXCSR, bEnd, wVal); + DBG(3, "Rx interrupt with no errors or packet!\n"); + } else { + /* we are expecting traffic */ +#ifdef MUSB_DMA + if(pEnd->pDmaChannel) { + if(MGC_DMA_STATUS_FREE== + pThis->pDmaController->pfDmaGetChannelStatus(pEnd->pDmaChannel)) + { + pEnd->dwOffset += pEnd->pDmaChannel->dwActualLength; + } + } +#endif + mgc_linux_packet_rx(pThis, bEnd, wRxCount, bIsochError); + } + } + + /* complete the current request or start next one clearing RxPktRdy + * and setting ReqPkt */ + if ( pUrb->status!=-EINPROGRESS ) { + int toggle=(pUrb->status==USB_ST_STALL) + ? 0 + : ((wVal & MGC_M_RXCSR_H_DATATOGGLE) ? 1 : 0); + SPIN_UNLOCK_IRQRESTORE(&pThis->Lock, flags); + complete_ep_urb(pThis, pEnd, pUrb, toggle); + DBG(2, "==>\n"); + } else { + spin_unlock(&pEnd->Lock); + wVal |= MGC_M_RXCSR_H_REQPKT; + wVal &= ~MGC_M_RXCSR_RXPKTRDY; + MGC_WriteCsr16(pBase, MGC_O_HDRC_RXCSR, bEnd, wVal); + DBG(2, "==>\n"); + SPIN_UNLOCK_IRQRESTORE(&pThis->Lock, flags); + } +} + +/* ************************************************************************* + * + **************************************************************************/ + +/** + * Find a local endpoint suitable for transmitting the given urb minimizing + * the reconfigurations. The best localendpoint is selceted using the following + * criterion: + * - ep0 is used for control Urbs + * - for bulk Urbs only (when available) choose the Tx or Rx reserved end + * - determine direction, size and traffic type + * + * @param pThis instance pointer + * @param pURB URB pointer + * @return suitable local endpoint + * @return -1 if nothing appropriate + */ +int mgc_linux_find_end(MGC_LinuxCd* pThis, struct urb* pUrb) +{ + MGC_LinuxLocalEnd* pEnd; + int32_t dwDiff; + uint16_t wBestDiff = 0xffff; + uint16_t wBestExactDiff = 0xffff; + uint8_t bDirOk, bTrafficOk, bSizeOk, bExact; + int nEnd=-1, nBestEnd = -1, nBestExactEnd = -1; + unsigned int nOut = usb_pipeout( pUrb->pipe ); + uint16_t wPacketSize = usb_maxpacket(pUrb->dev, pUrb->pipe, nOut); + uint8_t bRemoteEnd = usb_pipeendpoint(pUrb->pipe); + uint8_t bIsBulk = usb_pipebulk(pUrb->pipe); + uint8_t bRemoteAddress = (uint8_t)usb_pipedevice(pUrb->pipe); + + DBG(2, "<== pUrb=%p\n", pUrb); + + /* control is always EP0, and can always be queued */ + if ( usb_pipecontrol(pUrb->pipe) ) { + DBG(2, "==> is a control pipe use ep0\n"); + return 0; + } + + /* use a reserved one for bulk if any */ + if (bIsBulk) { + if (nOut && pThis->bBulkTxEnd) { + DBG(3, "==> use the bulk tx end (%d)\n", pThis->bBulkTxEnd); + return pThis->bBulkTxEnd; + } else if(!nOut && pThis->bBulkRxEnd) { + DBG(3, "==> use the bulk rx end (%d)\n", pThis->bBulkRxEnd); + return pThis->bBulkRxEnd; + } + } + + /* scan, remembering exact match and best match */ + for(nEnd = 1; nEnd < pThis->bEndCount; nEnd++) { + pEnd = &(pThis->aLocalEnd[nEnd]); + + /* consider only if direction is possible */ + bDirOk = (nOut && pEnd->wMaxPacketSizeTx) || + (!nOut && pEnd->wMaxPacketSizeRx); + /* consider only if size is possible (in the given direction) */ + bSizeOk = (nOut && (pEnd->wMaxPacketSizeTx >= wPacketSize)) || + (!nOut && (pEnd->wMaxPacketSizeRx >= wPacketSize)); + /* consider only traffic type */ + bTrafficOk = (usb_pipetype(pUrb->pipe) == pEnd->bTrafficType); + + if (bDirOk && bSizeOk) { + /* convenient computations */ + dwDiff = nOut ? (pEnd->wMaxPacketSizeTx - wPacketSize) : + (pEnd->wMaxPacketSizeRx - wPacketSize); + bExact = bTrafficOk && (pEnd->bRemoteEnd == bRemoteEnd) && + (pEnd->bRemoteAddress == bRemoteAddress); + + /* bulk: best size match not claimed (we only claim periodic) */ + if(bIsBulk && !pEnd->bIsClaimed && (wBestDiff > dwDiff)) { + wBestDiff = (uint16_t)dwDiff; + nBestEnd = nEnd; + + /* prefer end already in right direction (to avoid flush) */ + if((wBestExactDiff > dwDiff) && (nOut == (int)pEnd->bIsTx)) { + wBestExactDiff = (uint16_t)dwDiff; + nBestExactEnd = nEnd; + } + + } else if(!bIsBulk && (nEnd != pThis->bBulkTxEnd) && + (nEnd != pThis->bBulkRxEnd)) + { + /* periodic: exact match if present; otherwise best unclaimed */ + if (bExact) { + nBestExactEnd = nEnd; + break; + } else if(!pEnd->bIsClaimed && (wBestDiff > dwDiff)) { + wBestDiff = (uint16_t)dwDiff; + nBestEnd = nEnd; + } + } + } + + } + + return (nBestExactEnd >= 0) ? nBestExactEnd : nBestEnd; +} + +static int mgc_check_bandwidth(struct urb* pUrb) { + unsigned int pipe = pUrb ? pUrb->pipe : 0; +#ifdef MUSB_V24 + struct urb* pNextUrb; +#endif + + /* some drivers try to confuse us by linking periodic URBs BOTH ways */ + if(!pUrb->bandwidth && (usb_pipeisoc(pipe) || usb_pipeint(pipe))) { + int bustime = usb_check_bandwidth(pUrb->dev, pUrb); + if(bustime < 0) { + return bustime; + } + + usb_claim_bandwidth(pUrb->dev, pUrb, bustime, + usb_pipeisoc(pipe) ? 1 : 0); + +#ifdef MUSB_V24 + /* propagate through linked URBs */ + pNextUrb = pUrb->next; + while(pNextUrb && (0 == pNextUrb->bandwidth)) { + pNextUrb->bandwidth = bustime; + pNextUrb = pNextUrb->next; + } +#endif + } + + return 0; +} + +/** + * Schedule an urb on an endpoint. Assumes the ep locked. + * @param pThis the conotroller + * @param pEnd the endpoint the urb shoudl be queued to + * @param pUrb the urb to queue + */ +int mgc_schedule_urb(MGC_LinuxCd *pThis, MGC_LinuxLocalEnd* pEnd, + struct urb* pUrb) +{ + DBG(2, "<== pUrb=%p ep=%d\n", pUrb, pEnd->bEnd); + + /* increment urb's reference count, we now control it. */ + pUrb = usb_get_urb(pUrb); + pUrb->hcpriv = NULL; /* paranoid */ + + /* async unlink?? */ + if( pUrb->status!=-EINPROGRESS ) { + + mgc_linux_complete_urb(pThis, pEnd, pUrb); + return 0; + } + + DEBUG_CODE(3, if(pEnd->bEnd==0) { \ + MUSB_DeviceRequest* pRequest = (MUSB_DeviceRequest*)pUrb->setup_packet;\ + INFO("ctl-request: bmRequestType=%02x, bRequest=%02x, wLength=%04x\n",\ + pRequest->bmRequestType, pRequest->bRequest,\ + le16_to_cpu(pRequest->wLength));\ + } ); + + { + const int bustime=mgc_check_bandwidth(pUrb); + if ( bustime<0 ) { + ERR("==> not enough bustime for it\n"); + return bustime; + } + } + + /* claim the urb for periodic transfers */ + pEnd->bIsClaimed=mgc_urb_is_periodic(pUrb); + if ( pEnd->bIsClaimed ) { + DBG(3, "end %d claimed for proto %s\n", pEnd->bEnd, + decode_urb_protocol(pUrb) ); + } + + { /* queue the urb and start it */ + int idle=mgc_ep_is_idle(pEnd); + + if ( mgc_ep_enqueue_urb(pEnd, pUrb)!=0 ) { + ERR("**>cannot queue pUrb=%p to pEnd=%p! this is bad (TM)\n", pUrb, pEnd); + return -EBUSY; + } + + DBG(3, "queued URB %p (current %p) to end %d (bRemoteAddress=%d, bRemoteEnd=%d proto=%d) (idle=%d) pEnd->bBusyCompleting=%d\n", + pUrb, MGC_GetCurrentUrb(pEnd), pEnd->bEnd, (uint8_t)usb_pipedevice(pUrb->pipe), + (uint8_t)usb_pipeendpoint(pUrb->pipe), usb_pipetype(pUrb->pipe), idle, pEnd->bBusyCompleting); + + /* when using the HCD driver, idle BETTER be 1 :)) */ + if ( idle ) { + mgc_linux_kickstart_urb(pThis, pEnd->bEnd); + } + } + +#ifdef MUSB_PARANOID + DEBUG_CODE(5, dump_urb(pUrb); ); + if ( MGC_ISCORRUPT(pThis) ) { + ERR("stopping after submit\n"); + MGC_HdrcStop(pThis); + MUSB_ERR_MODE(pThis, MUSB_ERR_CORRUPTED); + DBG(2, "==> -ENOENT\n"); + return -ENODEV; /* like a disconect */ + } +#endif + + DBG(2, "==>\n"); + return 0; +} + +/** + * Submit an URB, either to the virtual root hut or to a real device; + * it also checks the URB to make sure it's valid. + * This is called by the Linux USB core. TSubmit Urb lock pThis + * and the End to use, so make sure the caller releases its locks. + * + * @param pThis the controller + * @param pUrb URB pointer (urb = USB request block data structure) + * @param iMemFlags memeory flags (see kernel docs) + * @return status code (0 succes) + */ +int mgc_submit_urb(MGC_LinuxCd* pThis, struct urb* pUrb, + MUSB_MEMFLAG_TYPE iMemFlags) +{ + int nEnd=0, rc; + + DBG(2, "<== pUrb=%p, pUrb->hcpriv=%p proto=%s\n", + pUrb, pUrb->hcpriv, decode_urb_protocol(pUrb)); + +#ifdef MUSB_PARANOID + if( MGC_ISCORRUPT(pThis) ) { + ERR("==> pThis corrupted: stopping before submit\n"); + MGC_HdrcStop(pThis); + MUSB_ERR_MODE(pThis, MUSB_ERR_CORRUPTED); + return -ENOENT; + } +#endif + +#ifndef MUSB_USE_HCD_DRIVER + /* if it is a request to the virtual root hub, delegate */ + /* if( usb_pipedevice(pipe) == pThis->RootHub.bAddress) */ + + /* pUrb->dev->parent==null means that the device is the root hub, + this should be fine on every platform. */ + if( !pUrb->dev->parent ) { +/* + if(pThis->bDelayPortPowerOff) + { + return -ENODEV; + } +*/ + const int rc=MGC_VirtualHubSubmitUrb(&(pThis->RootHub), pUrb); + DBG(2, "==> sbmitted to vhub rc=%d\n", rc); + return rc; + } +#endif + + /* find appropriate local endpoint to do it */ + nEnd=mgc_linux_find_end(pThis, pUrb); + DBG(3, "pUrb=%p, end=%d, bufsize=%x\n", pUrb, \ + nEnd, pUrb->transfer_buffer_length); + +#ifdef MUSB_PARANOID + if (nEnd < 0) { + unsigned int pipe = pUrb ? pUrb->pipe : 0; + pUrb->status = USB_ST_URB_REQUEST_ERROR; + ERR("==> no resource for proto=%d, addr=%d, end=%d\n", \ + usb_pipetype(pipe), usb_pipedevice(pipe), \ + usb_pipeendpoint(pipe)); + return USB_ST_URB_REQUEST_ERROR; + } +#endif + + /* if no root device, assume this must be it */ + if ( !pThis->pRootDevice ) { + pThis->pRootDevice = pUrb->dev; + } + + { /* queue */ + unsigned long flags=0; + MGC_LinuxLocalEnd *pEnd=&pThis->aLocalEnd[nEnd]; + + if ( !pEnd->bBusyCompleting ) { + SPIN_LOCK_IRQSAVE(&pEnd->Lock, flags); + } + + pUrb->status=-EINPROGRESS; + rc=mgc_schedule_urb(pThis, pEnd, pUrb); + + if ( ! pEnd->bBusyCompleting ) { + SPIN_UNLOCK_IRQRESTORE(&pEnd->Lock, flags); + } + } + + return rc; +} + +/** + * Generic v26 version (pre10). + */ +static inline int + mgc_linux_submit_urb_common(struct urb* pUrb, MUSB_MEMFLAG_TYPE iMemFlags) +{ + MGC_LinuxCd* pThis; + + DBG(2, "<== pUrb=%p, pUrb->hcpriv=%p proto=%s\n", + pUrb, pUrb->hcpriv, decode_urb_protocol(pUrb)); + +#ifdef MUSB_PARANOID + if (!pUrb || !pUrb->dev || !pUrb->dev->bus ) { + DBG(2, "==> invalid URB"); + return -EINVAL; + } +#endif + + pThis = (MGC_LinuxCd*)pUrb->hcpriv; + if ( !pThis ) { + DBG(2, "==> invalid URB: pThis is null"); + return -EINVAL; + } + + return mgc_submit_urb(pThis, pUrb, iMemFlags); +} + + +#ifdef MUSB_V26 +int MGC_LinuxSubmitUrb26(struct urb *pUrb, MUSB_MEMFLAG_TYPE iMemFlags) +{ + return mgc_linux_submit_urb_common(pUrb, iMemFlags); +} +#endif + +#ifdef MUSB_V24 +int MGC_LinuxSubmitUrb24(struct urb* pUrb) +{ + return mgc_linux_submit_urb_common(pUrb, GFP_ATOMIC); +} +#endif + +/* --------------------------------------------------------------------- */ + +/** + * Cross version unlink + * + * @param pThis the controller + * @param pUrb the Urb to unlink + * @return + */ +int mgc_unlink_urb(MGC_LinuxCd* pThis, struct urb* pUrb) +{ + unsigned long flags; + MGC_LinuxLocalEnd* pEnd; + + DBG(-1, "<== pUrb=%p, pUrb->hcpriv=%p proto=%s \n", pUrb, pUrb->hcpriv, + decode_urb_protocol(pUrb)); + +#ifdef MUSB_PARANOID + if(MGC_ISCORRUPT(pThis)) { + ERR("pThis corrupted: stopping before unlink\n"); + MGC_HdrcStop(pThis); + MUSB_ERR_MODE(pThis, MUSB_ERR_CORRUPTED); + DBG(2, "==>\n"); + return -EINVAL; + } +#endif + +#ifndef MUSB_USE_HCD_DRIVER + /* if it is a request to the virtual root hub, delegate */ + /* if (usb_pipedevice (pUrb->pipe) == pThis->RootHub.bAddress) */ + if( !pUrb->dev->parent ) { + int rc=MGC_VirtualHubUnlinkUrb(&(pThis->RootHub), pUrb); + DBG(2, "==> VirtualHub rc=%d\n", rc); + return rc; + } +#endif + + /* which end was the urb queued? */ + pEnd=(MGC_LinuxLocalEnd*)pUrb->hcpriv; + if ( pEnd ) + + /* somehow, we got passed a dangling URB pointer */ + if((pEnd < &(pThis->aLocalEnd[0])) || + (pEnd > &(pThis->aLocalEnd[MUSB_C_NUM_EPS-1]))) + { +#ifdef MUSB_USE_HCD_DRIVER + DBG(-1, "==> cannot unlink pUrb=%p, pEnd=%p is invalid\n", pUrb, + pEnd); + return -EINVAL; +#endif + } + + if ( MUSB_IS_HST(pThis) && pUrb->transfer_flags & USB_ASYNC_UNLINK ) { + DBG(-1, "Asyncronous unlink of pUrb=%p (pUrb->status=%d)\n", + pUrb, pUrb->status); + } else { + DBG(-1, "Syncronous unlink of pUrb=%p (pUrb->status=%d)\n", pUrb, + pUrb->status); + + SPIN_LOCK_IRQSAVE(&pEnd->Lock, flags); + if ( mgc_ep_dequeue_urb(pEnd, pUrb,pThis)==0 ) { + int status; + + SPIN_UNLOCK_IRQRESTORE(&pEnd->Lock, flags); + status=mgc_linux_complete_urb(pThis, pEnd, pUrb); + if ( status==-EINVAL ) { + ERR("*** cannot unlink pUrb=%p from bEnd=%d (current=%p)\n", pUrb, + pEnd->bEnd, MGC_GetCurrentUrb(pEnd)); + } + } else { + SPIN_UNLOCK_IRQRESTORE(&pEnd->Lock, flags); + ERR("*** pUrb=%p is not queued to bEnd=%d, this is BAD!\n", pUrb, + pEnd->bEnd); + } + } + +#ifdef MUSB_PARANOID + if(MGC_ISCORRUPT(pThis)) { + ERR("stopping after unlink\n"); + MGC_HdrcStop(pThis); + MUSB_ERR_MODE(pThis, MUSB_ERR_CORRUPTED); + return -EINVAL; + } +#endif + + DBG(-1, "==> rc=0\n"); + return 0; +} + +/** + * unlink an urb, common code. + * @param pUrb the urb to unlink + */ +static int mgc_linux_unlink_urb(struct urb* pUrb, int status) +{ + MGC_LinuxCd* pThis; + + DBG(2, "<== pUrb=%p\n", pUrb); + + /* sanity */ + if (!pUrb || !pUrb->hcpriv) { + DBG(2, "==> invalid urb%p, pUrb->hcpriv=%p\n", pUrb, + (pUrb)?pUrb->hcpriv:NULL); + return -EINVAL; + } + + if (!pUrb->dev || !pUrb->dev->bus) { + DBG(2, "==>\n"); + return -ENODEV; + } + + pThis = (MGC_LinuxCd*)pUrb->hcpriv; + if(!pThis) { + ERR("==> pThis is null: stopping before unlink\n"); + return -ENODEV; + } + + pUrb->status =status; + return mgc_unlink_urb(pThis, pUrb); +} + +/** + * Cancel URB. + * @param pUrb URB pointer + */ +#ifdef MUSB_V26 +int MGC_LinuxUnlinkUrb26(struct urb* pUrb, int status) { + return mgc_linux_unlink_urb(pUrb, status); +} +#endif + +#ifdef MUSB_V24 + /* ENOENT=kill ECONNRESET=unlink */ +int MGC_LinuxUnlinkUrb24(struct urb* pUrb) { + return mgc_linux_unlink_urb(pUrb, -ENOENT); +} +#endif + + +/* --------------------------------------------------------------------- */ + +/** + * Initialize the local end points; pThis->bEndCount must be initialized. + * @param pThis the controller + */ +void MGC_InitLocalEndPoints(MGC_LinuxCd* pThis) { + uint8_t bEnd; + MGC_LinuxLocalEnd* pEnd; + +#ifdef MUSB_PARANOID + if ( !pThis ) { + ERR("Controller not initialized\n"); + return; + } + + if ( !pThis->bEndCount ) { + WARN("pThis->bEndCount=%d might be wrong\n", pThis->bEndCount); + } +#endif + + for(bEnd = 0; bEnd < pThis->bEndCount; bEnd++) { + pEnd = &(pThis->aLocalEnd[bEnd]); + pEnd->bEnd=bEnd; + +#ifdef MUSB_PARANOID + if ( bEnd ) { + if ( spin_is_locked(&pEnd->Lock) ) { + WARN("End=%d is locked\n", bEnd); + } + + if ( !mgc_ep_is_idle( pEnd ) ){ + WARN("pEnd=%d pEnd->urb_list=%p: not idle\n", pEnd->bEnd, + MGC_GetCurrentUrb(pEnd)); + } + } +#endif + + mgc_ep_idle( pEnd ); + spin_lock_init( &pEnd->Lock ); + + /* restore the pads */ +#if MUSB_DEBUG > 0 + pEnd->dwPadFront = MGC_PAD_FRONT; + pEnd->dwPadBack = MGC_PAD_BACK; +#endif + + /* reset the counters */ +#ifdef MUSB_CONFIG_PROC_FS + pEnd->dwTotalRxBytes = 0; + pEnd->dwTotalRxPackets = 0; + pEnd->dwErrorRxPackets = 0; + pEnd->dwTotalTxBytes = 0; + pEnd->dwTotalTxPackets = 0; + pEnd->dwErrorTxPackets = 0; + pEnd->dwWaitFrame = 0; +#endif + + /* reset the softstate */ + pThis->aLocalEnd[bEnd].bIsClaimed=FALSE; + pEnd->wPacketSize = 0; + pEnd->bRemoteAddress = 0; + pEnd->bRemoteEnd = 0; + pEnd->bTrafficType = 0; + pEnd->bIsTx=0; + } + + mgc_slow_device_kludge_delay=MGC_SLOW_DEVICE_KLUDGE_DELAY; +} + +/** + * initialize the root hub. + * @param pThis the controller. + * @return 0 for success, <0 for error + * @warning I will move this to virthub.c + */ +int mgc_init_root_hub(MGC_LinuxCd *pThis) { + int rc=0; + + pThis->PortServices.pPrivateData = pThis; + pThis->PortServices.pfSetPortPower = MGC_LinuxSetPortPower; + pThis->PortServices.pfSetPortEnable = MGC_LinuxSetPortEnable; + pThis->PortServices.pfSetPortSuspend = MGC_LinuxSetPortSuspend; + pThis->PortServices.pfSetPortReset = MGC_LinuxSetPortReset; + + rc=MGC_VirtualHubInit(&(pThis->RootHub), pThis->pBus, 1, + &(pThis->PortServices)); + + return rc; +} + + +#if 0 +#if MUSB_DEBUG > 0 +/* + * Test endpoint FIFO (only endpoint 0 until the others have a way) + */ +static uint8_t MGC_HdrcTestFifo(uint8_t* pBase, uint8_t bEnd, + uint8_t bDatum, uint16_t wCount) +{ + uint8_t aTest[64]; + uint16_t wReg, wIndex, wReadCount; + uint8_t bReadVal, bReg; + uint8_t bResult = TRUE; + + INFO("Testing FIFO on endpoint %d...\n", bEnd); + + for(wIndex = 0; wIndex < min(wCount, (uint16_t)64); wIndex++) { + aTest[wIndex] = bDatum; + } + + wReg = MGC_Read16(pBase, MGC_O_HDRC_INTRTX); + MGC_Write16(pBase, MGC_O_HDRC_INTRTX, wReg & ~1); + MGC_SelectEnd(pBase, bEnd); + if(bEnd) { + } else { + MGC_WriteCsr16(pBase, MGC_O_HDRC_CSR0, 0, + MGC_M_CSR0_FLUSHFIFO); + } + MGC_HdrcLoadFifo(pBase, bEnd, wCount, aTest); + MGC_Write8(pBase, MGC_O_HDRC_TESTMODE, MGC_M_TEST_FIFO_ACCESS); + memset(aTest, 0, 64); + do { + bReg = MGC_Read8(pBase, MGC_O_HDRC_TESTMODE); + } while(bReg & MGC_M_TEST_FIFO_ACCESS); + + if(bEnd) { + wReadCount = MGC_ReadCsr16(pBase, MGC_O_HDRC_RXCOUNT, bEnd); + } else { + wReadCount = MGC_ReadCsr8(pBase, MGC_O_HDRC_COUNT0, 0); + } + + if(wReadCount != wCount) { + ERR("Error: loaded FIFO with %04x bytes, RxCount=%04x\n", + wCount, wReadCount); + bResult = FALSE; + } + wReadCount = min(wReadCount, (uint16_t)64); + MGC_HdrcUnloadFifo(pBase, bEnd, wReadCount, aTest); + if(bEnd) { + MGC_WriteCsr16(pBase, MGC_O_HDRC_RXCSR, bEnd, 0); + } else { + MGC_WriteCsr16(pBase, MGC_O_HDRC_CSR0, 0, MGC_M_CSR0_P_SVDRXPKTRDY); + } + + MGC_Write16(pBase, MGC_O_HDRC_INTRTX, wReg); + for(wIndex = 0; wIndex < wReadCount; wIndex++) { + if(bDatum != aTest[wIndex]) { + ERR("Error: FIFO Tx data=%02x, Rx data=%02x\n", bDatum, + aTest[wIndex]); + bResult = FALSE; + } + } + return bResult; +} +#endif +#endif + --- /dev/null +++ linux-2.6.20/drivers/usb/nomadik/musb_host.h @@ -0,0 +1,101 @@ +/* + * linux/drivers/usb/nomadik/musb_host.h + * + * Copyright 2007, STMicroelectronics + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _MUSB_HOST_H +#define _MUSB_HOST_H + +extern int mgc_slow_device_kludge_delay; + +#define SPIN_LOCK_IRQSAVE(l, f) do { spin_lock_irqsave(l, f); if ( mgc_slow_device_kludge_delay) { udelay(mgc_slow_device_kludge_delay*2); } DBG(3, "IRQ DISABLED\n"); } while (0) +#define SPIN_UNLOCK_IRQRESTORE(l,f) do { DBG(3, "IRQ ENABLED\n"); spin_unlock_irqrestore(l, f); } while (0) + +struct urb; + +int mgc_init_root_hub(MGC_LinuxCd *pThis); +int mgc_ep_is_idle(MGC_LinuxLocalEnd* pEnd); +MGC_LinuxLocalEnd* mgc_ep_find_end(MGC_LinuxCd *pThis, struct urb *pUrb); + +int mgc_linux_find_end(MGC_LinuxCd* pThis, struct urb* pUrb); +int mgc_schedule_urb(MGC_LinuxCd *pThis, MGC_LinuxLocalEnd* pEnd, + struct urb* pUrb); + +static inline int mgc_urb_is_periodic(struct urb *pUrb) { + return (usb_pipeint(pUrb->pipe) || usb_pipeisoc(pUrb->pipe)); +} + +extern char* decode_urb_protocol(struct urb* pUrb); + + +#ifdef MUSB_USE_HCD_DRIVER +int mgc_hcd_schedule_urb(MGC_LinuxCd* pThis); +#endif + +#ifdef MUSB_HOST +extern int mgc_unlink_urb(MGC_LinuxCd* pThis, struct urb* pUrb); +extern int mgc_submit_urb(MGC_LinuxCd* pThis, struct urb* pUrb, MUSB_MEMFLAG_TYPE iMemFlags); + +#ifdef MUSB_V26 +extern int MGC_LinuxSubmitUrb26(struct urb* pUrb, MUSB_MEMFLAG_TYPE iMemFlags); +extern int MGC_LinuxUnlinkUrb26(struct urb* pUrb, int status); +#endif + +#ifdef MUSB_V24 +extern int MGC_LinuxSubmitUrb24(struct urb* pUrb); +extern int MGC_LinuxUnlinkUrb24(struct urb* pUrb); +#endif + +extern void MGC_HdrcServiceRxReady(MGC_LinuxCd* pThis, uint8_t bEnd); +extern void MGC_HdrcStartTx(MGC_LinuxCd* pThis, uint8_t bEnd); +extern void MGC_HdrcStopEnd(MGC_LinuxCd* pThis, uint8_t bEnd); +extern void MGC_HdrcServiceTxAvail(MGC_LinuxCd* pThis, uint8_t bEnd); +extern void MGC_HdrcServiceDefaultEnd(MGC_LinuxCd* pThis); + + +#else /* host not defined */ + +#ifdef MUSB_V26_POST10 +extern int MGC_LinuxHubSuspend(struct usb_bus *pBus); +extern int MGC_LinuxHubResume(struct usb_bus *pBus); +#endif + +inline void MGC_HdrcStartTx(MGC_LinuxCd* pThis, uint8_t bEnd) { + DBG(3, "#HOST DISABLED\n"); +} + +inline void MGC_HdrcStopEnd(MGC_LinuxCd* pThis, uint8_t bEnd) { + DBG(3, "#HOST DISABLED\n"); +} + +inline void MGC_HdrcServiceRxReady(MGC_LinuxCd* pThis, uint8_t bEnd) { + DBG(3, "#HOST DISABLED\n"); +} + +inline void MGC_HdrcServiceTxAvail(MGC_LinuxCd* pThis, uint8_t bEnd) { + DBG(3, "#HOST DISABLED\n"); +} + +inline void MGC_HdrcServiceDefaultEnd(MGC_LinuxCd* pThis) { + DBG(3, "#HOST DISABLED\n"); +} +#endif + + +#endif /* _MUSB_HOST_H */ + --- /dev/null +++ linux-2.6.20/drivers/usb/nomadik/musb_ioctl.c @@ -0,0 +1,321 @@ +/* + * linux/drivers/usb/nomadik/musb_ioctl.c + * + * Copyright 2007, STMicroelectronics + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include + +#include + +#include "musbdefs.h" +#include "musb_host.h" + +#ifdef MUSB_DEBUG +extern int mgc_slow_device_kludge_delay; +#endif + +/** + * Zap the driver (warm start) + * @param pThis the controller + */ +void MGC_Zap(MGC_LinuxCd* pThis) { + +#ifdef MUSB_PARANOID + if ( !pThis ) { + ERR("Controller not initialized\n"); + return; + } +#endif + + MGC_HdrcStop(pThis); + +#ifdef MUSB_VIRTHUB + MGC_VirtualHubPortDisconnected(&(pThis->RootHub), 0); + pThis->pRootDevice = NULL; + mgc_hcd_flush(pThis); +#endif + + WARN("Controller Stopped\n"); + + +#ifdef MUSB_HOST + MGC_InitLocalEndPoints(pThis); +#endif + +#ifdef MUSB_GADGET + +#endif + + WAIT_MS(1000); + MGC_HdrcStart( pThis ); + WARN("Controller Restarted\n"); +} + +/** + * Start a session. Depeing on the controller mode (cable end) it will + * pwer VBUS/initiate SRP and/or it will behave like a gadget. + * @param pThis the controller + * + */ +void MGC_Session(MGC_LinuxCd* pThis) { + uint8_t bReg, sesn=0; + +#ifdef MUSB_PARANOID + if ( !pThis ) { + ERR("Controller not initialized\n"); + return; + } +#endif + + if ( MUSB_IS_ERR(pThis) ) { + WARN("Error mode, zap the driver first\n"); + } + + + if ( sesn ) { + ERR("A %s session is active; terminate it first\n", + MUSB_MODE(pThis)); + return; + } + + + /* WHY!?!?! this looks like a race condition to me */ + bReg = MGC_Read8(pThis->pRegs, MGC_O_HDRC_DEVCTL); + MGC_Write8(pThis->pRegs, MGC_O_HDRC_DEVCTL, bReg | MGC_M_DEVCTL_SESSION); +} + + +/** + * Change the debug level. + * @param level the new level + */ +void MGC_SetDebugLevel(int level) { +#if MUSB_DEBUG > 0 + MGC_DebugLevel=level; + INFO("MGC_DebugLevel=%d\n", MGC_DebugLevel); +#endif +} + +/** + * Change the slow device delay. + * @param delay the new delay + */ +int MGC_SetDeviceDelay(int delay) { + if ( delay>0 ) { + mgc_slow_device_kludge_delay=delay; + } + return mgc_slow_device_kludge_delay; +} + +/** Dump the current status and compile options. + * @param pThis the device driver instance + * @param buffer where to dump the status; it must be big enough hold the + * result otherwise "BAD THINGS HAPPENS(TM)". + */ +int dump_header_stats(MGC_LinuxCd* pThis, char *buffer) { + int code, count=0; + const uint8_t* pBase=pThis->pRegs; + + *buffer=0; + + code=sprintf(&buffer[count], + "Compile Options: [debug=%d][dma=%s][gadget=%s][otg=%s][eps=%d]\n", +#if MUSB_DEBUG>0 + MGC_DebugLevel +#else + -1 +#endif + , +#ifdef MUSB_DMA + "yes" +#else + "no" +#endif + , +#ifdef MUSB_GADGET + "yes" +#else + "no" +#endif + , +#ifdef MUSB_OTG + "yes" +#else + "no" +#endif + ,pThis->bEndCount); + if ( code<0 ) { + ERR("A problem generating the report\n"); + return count; + } else { + count+=code; + } + + code=sprintf(&buffer[count], + "Current Status: %sDRC, Mode=%s (%s=%d) (Power=%02x, DevCtl=%02x)\n", + ( pThis->bIsMultipoint ? "MH" : "H"), + MUSB_MODE(pThis), +#ifdef MUSB_GADGET + "address", + (MUSB_IS_DEV(pThis)?pThis->bAddress:0, +#else + "delay", + mgc_slow_device_kludge_delay, +#endif + MGC_Read8(pBase, MGC_O_HDRC_POWER), + MGC_Read8(pBase, MGC_O_HDRC_DEVCTL)); + if ( code<0 ) { + ERR("A problem generating the report\n"); + return count; + } else { + count+=code; + } + +#ifdef MUSB_USE_HCD_DRIVER + { + int i=0; + mgc_hcd_urb_queue *pQueue=mgc_hcd_get_urb_queue(pThis); + + code=sprintf(&buffer[count], + "HCD: urb_queue_count=%d urb_exec_count=%d\n", + pQueue->urb_queue_count, pQueue->urb_exec_count); + if ( code<0 ) { + ERR("A problem generating the report\n"); + return count; + } else { + count+=code; + } + + for (i=0; ibEndCount; i++) { + if ( !mgc_ep_is_idle( &pThis->aLocalEnd[i] ) ) { + code=sprintf(&buffer[count], "ep%d, current=%p\n", + i, MGC_GetCurrentUrb(&pThis->aLocalEnd[i])); + if ( code<0 ) { + ERR("A problem generating the report\n"); + return count; + } else { + count+=code; + } + } + } + } +#endif + + return count; +} + + +/** + * decode (convert to a name) the protocol used on an endpoint. + * @param pThis the controller + * @param bEnd the endpoint + */ +static char* decode_protocol(MGC_LinuxCd* pThis, unsigned bEnd) { + char* pProto = "Err "; + + if ( MUSB_IS_DEV(pThis) ) { +#ifdef MUSB_GAGDET + pProto=decode_dev_ep_protocol(pThis, bEnd); +#endif + } else if ( MUSB_IS_HST(pThis) ) { +#ifdef MUSB_HOST + pProto=decode_hst_ep_protocol(pThis, bEnd); +#endif + } + + return pProto; +} + +#ifdef MUSB_HOST + +/** + * Dump statistics for a local end (driver operaiting in host mode). + * @param pThis the device driver instance + * @param bEnd + * @param aBuffer the buffer to print the report to + */ +int dump_end_stats(MGC_LinuxCd* pThis, uint8_t bEnd, char* aBuffer) { + int code, count=0; + MGC_LinuxLocalEnd* pEnd=&pThis->aLocalEnd[bEnd]; + + spin_lock(&pEnd->Lock); + + do { + + if ( mgc_ep_is_idle(pEnd) ) { + code=snprintf(aBuffer, 256-count, + "End-%01x: Idle (%s, proto=%s, pktsize=%04x, address=%02x, end=%02x\n", + bEnd, ( pEnd->bIsTx ? "Tx" : "Rx" ), decode_protocol(pThis, bEnd), + pEnd->wPacketSize, pEnd->bRemoteAddress, pEnd->bRemoteEnd); + } else { + code=snprintf(aBuffer, 256-count, + "End-%01x: %s (urb=%p), %s, proto=%s, pkt size=%04x, address=%02x, end=%02x\n", + bEnd, "Busy", MGC_GetCurrentUrb(pEnd), + ( pEnd->bIsTx ? "Tx" : "Rx" ), + decode_protocol(pThis, bEnd), + pEnd->wPacketSize, + pEnd->bRemoteAddress, + pEnd->bRemoteEnd); + } + + if ( code<0 ) { + break; + } else { + count+=code; + } + + if ( MUSB_IS_HST(pThis) ) { + code = snprintf(&aBuffer[count], 256-count, + " %10ld bytes Rx in %10ld pkts; %10ld errs, %10ld overruns\n", + pEnd->dwTotalRxBytes, + pEnd->dwTotalRxPackets, + pEnd->dwErrorRxPackets, + pEnd->dwMissedRxPackets); + if ( code<0 ) { + break; + } else { + count+=code; + } + + code=snprintf(&aBuffer[count], 256-count, + " %10ld bytes Tx in %10ld pkts; %10ld errs, %10ld underruns\n", + pEnd->dwTotalTxBytes, + pEnd->dwTotalTxPackets, + pEnd->dwErrorTxPackets, + pEnd->dwMissedTxPackets); + if ( code<0 ) { + break; + } else { + count+=code; + } + } else { + /* no stats for gadget, yet! */ + } + } while(0); + + spin_unlock(&pEnd->Lock); + if ( code<0 ) { + ERR("An error generating the report"); + return code; + } + + return count; +} +#endif + --- /dev/null +++ linux-2.6.20/drivers/usb/nomadik/musb_ioctl.h @@ -0,0 +1,32 @@ +/* + * linux/drivers/usb/nomadik/musb_ioctl.h + * + * Copyright 2007, STMicroelectronics + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "musbdefs.h" + +void MGC_Zap(MGC_LinuxCd* pThis); +void MGC_Session(MGC_LinuxCd* pThis); +void MGC_SetDebugLevel(int level); +int MGC_SetDeviceDelay(int delay); +int dump_header_stats(MGC_LinuxCd* pThis, char *buffer); +char*decode_protocol(MGC_LinuxCd* pThis, unsigned bEnd); +#ifdef MUSB_HOST +int dump_end_stats(MGC_LinuxCd* pThis, uint8_t bEnd, char* aBuffer); +#endif + --- /dev/null +++ linux-2.6.20/drivers/usb/nomadik/musb_plat_uds.c @@ -0,0 +1,2306 @@ +/* + * linux/drivers/usb/nomadik/musb_plat_uds.c + * + * Copyright 2007, STMicroelectronics + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* + * Introduction. + * The ICD works like the other Linux HCDs/Gadgets: it is threadless, + * so it does everything either in response to an interrupt, + * or during a call from an upper layer. + * It implements a virtual root hub, so as to make uniform use + * of the Linux hub driver.Linux + + * + * The Linux (host-side) USB core has no concept of binding (the authors + * apparently missed the point of the pipe discussion in the USB spec). + * Instead, class drivers simply submit URBs, and an HCD may reject + * or defer them if sufficient resources are not available. + * This means class drivers have no way to know if their requirements + * can possibly be fulfilled, and may be blocked indefinitely by others, + * without the end-user knowing why. + * Therefore, whether things will work depends on the order of URB submissions + * (which is dictated by the order of device insertion and/or driver loading + * and thread scheduling). + * + * The URB encodes pipe information in an integer, + * requiring table searches (hurting performance). + * + * For the HDRC, local endpoint 0 is the only choice for control traffic, + * so it is reprogrammed as needed, and locked during transfers. + * Bulk transfers are queued to the available local endpoint with + * the smallest possible FIFO in the given direction + * that will accomodate the transactions. + * + * A typical response to the completion of a periodic URB is immediate + * submission of another one, so the HCD does not assume it can reprogram + * a local periodic-targetted endpoint for another purpose. + * Instead, submission of a periodic URB is taken as a permanent situation, + * so that endpoint is untouched. + * One could imagine reprogramming periodic endpoints for other uses + * between their polling intervals, effectively interleaving traffic on them. + * Unfortunately, this assumes no device would ever NAK periodic tokens. + * This is because the core no notification to software when an attempted + * periodic transaction is NAKed (its NAKlimit feature is only for + * control/bulk). + */ + +/* + * Optional macros: + * + * MUSB_FLAT_REG if defined, use the core's flag register model + * + * MUSB_DEBUG 0 => absolutely no diagnostics + * 1 => minimal diagnostics (basic operational states) + * 2 => 1 + detailed debugging of interface with USB core + * 3 => 2 + internal debugging (e.g. every register write) + * 4 => 3 + shared-IRQ-related checking + * + * MUSB_DMA if defined, include DMA support. + * The DMA code to use is included below, + * so may need to be edited if a non-Inventra DMA + * controller is used with the Inventra core. + * + * MUSB_AHB_ID if defined, the core's identity is read from offset 0x400 + * to verify that the expected core is present + * + * MUSB_CONFIG_PROC_FS enables statistics/state info in /proc/musbhdrc + * where 0 <= n < number of instances of driver + * + * + * MUSB_HARD_IRQ try SA_INTERRUPT first when acquiring the irq (fallback to + * SA_SHIRQ when that fails. + * + * + * Options taken from linux/config.h: + * CONFIG_PM enables power-management + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#ifdef CONFIG_USB_DEBUG +#define DEBUG +#else +#undef DEBUG +#endif + + +#include "musbdefs.h" +#include "musb_host.h" +#include "../core/hcd.h" +#include +#include +/********************** RETURN TYPES FOR IRQ ********************************/ + +#ifdef MUSB_V26 +#define RETURN_IRQ_HANDLED return(IRQ_HANDLED) +#define RETURN_IRQ_NONE return(IRQ_NONE) +#endif + +#ifdef MUSB_V24 +typedef void irqreturn_t; +#define RETURN_IRQ_HANDLED return +#define RETURN_IRQ_NONE return +#endif + + +/* define this on command line */ +#ifndef MUSB_DEFAULT_IRQTYPE +#define MUSB_DEFAULT_IRQTYPE SA_SHIRQ +#endif + +/****************************** CONSTANTS ********************************/ + +#define DRIVER_AUTHOR "STMicroelectronics" +#define DRIVER_DESC "Nomadik USB Driver" + +#ifndef MUSB_VERSION +#define MUSB_VERSION "x.x" +#endif + +#define DRIVER_INFO DRIVER_DESC "v" MUSB_VERSION +#define DRIVER_NAME "HCD_NAME" + +static const char longname[] = DRIVER_INFO; +static const char shortname[] = DRIVER_NAME; + +/* this module is always GPL, the gadget might not... */ +MODULE_DESCRIPTION (DRIVER_INFO); +MODULE_AUTHOR (DRIVER_AUTHOR); +MODULE_LICENSE ("GPL"); + +/* time (millseconds) to wait before a restart */ +#define MUSB_RESTART_TIME 5000 +/* how many babbles to allow before giving up */ +#define MUSB_MAX_BABBLE_COUNT 10 +/* how many buss errors before stopping the operations */ +#define MUSB_MAX_VBUS_ERRORS 3 + +/* WEIRD KLUDGE! */ +#define IS_INVALID_ADDRESS(_x) (((unsigned long)_x)<(unsigned long)1024) + +#define A_IDLE 1 +#define B_IDLE 2 +#define PERIPHERAL 3 +#define HOST 4 + +#define MAJOR_NUMBER_OTG 0x0 +#define OTG_DEEP_SLEEP 0x1 +#define OTG_WAKEUP 0x2 +#define SRP_TEST 0x3 +#define HNP_TEST 0x4 +#define PRINT_REG 0x5 +#define HOST_A_IDLE 0x6 +#define OTG_SUSPEND 0x7 +#define OTG_RESUME 0x8 + +#define SUSPEND 0x0 +#define RESUME 0x1 + + +/******************************* FORWARDS ********************************/ +MGC_LinuxCd *udc_address; +struct usb_hcd *hcd1; +int udcinitmonitorflag_isr=0,udcinitmonitorflag_init=0; +extern void driver_change_mode_handler(uint8_t role); +void otg_disconnect(MGC_LinuxCd *pThis); +int dev_safe_remove=0; +extern int Urb_status; +struct urb *Urb_struct; +uint8_t temp; +uint8_t b_hnp_suspend=0; +uint8_t b_hnp_init=0; +void del_timer_func(void); +extern int udc_setup(void); +extern void udc_reset(void); +extern void udc_resume(void); +extern void udc_suspend(void); +extern void udc_intr_disable(void); +extern uint8_t host_a_idle; +static void funct_host_notify_timer(unsigned long pThis); +static struct timer_list notify_timer; +extern int nomadik_udc_init(MGC_LinuxCd *pThis); +extern void musb_reset_isr(void); +extern void udc_disconnect_isr(void); +extern uint8_t udc_ep0_irq(void); +extern void udc_ep_tx_irq(uint8_t bEnd) ; +extern void udc_ep_rx_irq(uint8_t bEnd) ; + +#ifndef MUSB_USE_HCD_DRIVER +#ifdef MUSB_VIRTHUB +#ifndef MUSB_V26_POST10 +/* Linux USBD glue */ +STATIC int mgc_linux_alloc_device(struct usb_device* pDevice); +STATIC int mgc_linux_free_device(struct usb_device* pDevice); +#endif +STATIC int MGC_LinuxGetFrameNumber(struct usb_device* pDevice); +#endif +#endif + +STATIC void mgc_reset(MGC_LinuxCd* pThis); +uint8_t MGC_HdrcReadUlpiReg(MGC_LinuxCd* pThis, uint8_t bAddr, uint8_t* pbData); +/* Interrupt service routine */ +#ifndef MUSB_USE_HCD_DRIVER +STATIC irqreturn_t MGC_LinuxIsr(int irq, void *__hci, struct pt_regs *r); +#endif + +#ifdef MUSB_USE_HCD_DRIVER +void mgc_hcd_flush(MGC_LinuxCd* pThis); +#endif + +/* HDRC functions */ +STATIC void MGC_HdrcDropResume(unsigned long pParam); +STATIC void MGC_HdrcRestart(unsigned long pParam); + +STATIC uint8_t MGC_HdrcInit(uint16_t wType, MGC_LinuxCd* pThis); + +#ifdef MUSB_V26 +void* MGC_LinuxBufferAlloc(struct usb_bus* pBus, size_t nSize, + unsigned iMemFlags, dma_addr_t* pDmaAddress); +void MGC_LinuxBufferFree(struct usb_bus* pBus, size_t nSize, + void* address, dma_addr_t DmaAddress); +#endif + +STATIC void mgc_hdrc_disable(MGC_LinuxCd* pThis); + +#ifdef MUSB_V26_POST10 +struct usb_bus; +int MGC_LinuxHubSuspend(struct usb_bus *pBus); +int MGC_LinuxHubResume(struct usb_bus *pBus); +#endif + +#ifdef MUSB_V26 +void mgc_linux_disable(struct usb_device* pDevice, int bEndpointAddress); +#endif + + +/******************************* GLOBALS *********************************/ + + +MGC_LinuxCd *hcd_to_musbstruct(void *ptr) +{ +#ifdef MUSB_USE_HCD_DRIVER + return (MGC_LinuxCd*)((struct usb_hcd *)ptr)->hcd_priv; +#else + return (MGC_LinuxCd*)ptr; +#endif +} + +struct usb_hcd* musbstruct_to_hcd(const MGC_LinuxCd *pThis) +{ +#ifdef MUSB_USE_HCD_DRIVER + return container_of((void*)pThis, struct usb_hcd, hcd_priv); +#else + return NULL; +#endif +} + +/******************************* GLOBALS *********************************/ + +unsigned int MGC_nIndex = 0; + +static const char MGC_HcdName [] = "musb-hcd"; + +#ifndef MUSB_USE_HCD_DRIVER +/** + * Virtual hub functions: Linux USBD calls these + */ +#ifdef MUSB_VIRTHUB +static struct usb_operations MGC_LinuxOperations = +{ +#ifndef MUSB_V26_POST10 + .allocate = mgc_linux_alloc_device, + .deallocate = mgc_linux_free_device, +#endif + + .get_frame_number = MGC_LinuxGetFrameNumber, + +#ifdef MUSB_V24 + .submit_urb = MGC_LinuxSubmitUrb24, +#endif + +#ifdef MUSB_V26 + .submit_urb = MGC_LinuxSubmitUrb26, +#endif + +#ifdef MUSB_V24 + .unlink_urb = MGC_LinuxUnlinkUrb24, +#endif +#ifdef MUSB_V26 + .unlink_urb = MGC_LinuxUnlinkUrb26, +#endif + +#ifdef MUSB_V26 + .buffer_alloc = MGC_LinuxBufferAlloc, + .buffer_free = MGC_LinuxBufferFree, + .disable = mgc_linux_disable, +#endif + +#ifdef MUSB_V26_POST10 + .hub_suspend = MGC_LinuxHubSuspend, + .hub_resume = MGC_LinuxHubResume, +#endif +}; +#endif +#endif + +const uint8_t MGC_aTestPacket[MGC_TEST_PACKET_SIZE] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, + 0xee, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xbf, 0xdf, + 0xef, 0xf7, 0xfb, 0xfd, 0xfc, 0x7e, 0xbf, 0xdf, + 0xef, 0xf7, 0xfb, 0xfd, 0x7e +}; + + + +int otg_ioctl (struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); +int otg_open (struct inode *inode, struct file *file); +int otg_close (struct inode *inode, struct file *file); +extern void otg_deep_sleep(void); +extern void otg_wakeup(void); +extern void set_host_a_idle(void); +extern void hnp_initiate(void); +extern void srp_initiate(void); + +static struct file_operations otg_fops = { + owner: THIS_MODULE, + read: NULL, + write: NULL, + ioctl: otg_ioctl, + open: otg_open, + flush: NULL, + release: otg_close, +}; + + +/******************************* GLOBALS *********************************/ + +int otg_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) +{ + /* to prevent compiler warnings */ + inode=inode; + filp=filp; + arg=arg; + + switch(cmd) { + + case OTG_DEEP_SLEEP: + del_timer(¬ify_timer); + otg_deep_sleep(); + break ; + + case OTG_WAKEUP: + otg_wakeup(); + break ; + + case HOST_A_IDLE: + set_host_a_idle (); + break; + + case SRP_TEST: + srp_initiate(); + break ; + + case HNP_TEST: + hnp_initiate(); + break ; + + case PRINT_REG: + break; + + case OTG_SUSPEND: + break ; + + case OTG_RESUME: + break ; + } + + return 0; +} + + +int otg_open (struct inode *inode, struct file *file) +{ + /* to prevent compiler warnings */ + inode=inode; + file=file; + + return 0; +} + + +int otg_close (struct inode *inode, struct file *file) +{ + /* to prevent compiler warnings */ + inode = inode; + file = file; + + return 0; +} + + + + + +/************************************************************************** + * HDRC functions +**************************************************************************/ + +/** + * Timer completion callback to finish resume handling started in ISR + * @param pParam the driver instance + */ +STATIC void MGC_HdrcDropResume(unsigned long pParam) +{ + uint8_t power; + MGC_LinuxCd* pThis = (MGC_LinuxCd*)pParam; + void* pBase = pThis->pRegs; + + DBG(2, "<==\n"); + + power = MGC_Read8(pBase, MGC_O_HDRC_POWER); + MGC_Write8(pBase, MGC_O_HDRC_POWER, power & ~MGC_M_POWER_RESUME); + +#ifdef MUSB_VIRTHUB + MGC_VirtualHubPortResumed(&(pThis->RootHub), 0); +#endif +} + +/** + * Timer completion callback to request session again + * (to avoid self-connecting) + * @param pParam the driver instance + */ +STATIC void MGC_HdrcRestart(unsigned long pParam) +{ + MGC_HdrcStart((MGC_LinuxCd*)pParam); +} + +/* ------------------------------------------------------------------------- + * + * ------------------------------------------------------------------------ */ + +/** + * Load an HDRC FIFO + * + * @param pBase base address of HDRC + * @param bEnd local endpoint + * @param wCount how many bytes to load + * @param pSource data buffer + */ +void MGC_HdrcLoadFifo(const uint8_t* pBase, uint8_t bEnd, + uint16_t wCount, const uint8_t* pSource) +{ + uint16_t wIndex, wIndex32; + uint16_t wCount32 = wCount >> 2; + uint8_t bFifoOffset = MGC_FIFO_OFFSET(bEnd); + DBG(2, "pBase=%p, bEnd=%d, wCount=0x%04x, pSrc=%p\n", + pBase, bEnd, wCount, pSource); + +#ifdef MUSB_PARANOID + if ( IS_INVALID_ADDRESS(pSource) ) { + ERR("loading fifo from a null buffer; why did u do that????\n"); + return; + } +#endif + + /* doublewords when possible */ + for(wIndex = wIndex32 = 0; wIndex32 < wCount32; wIndex32++, wIndex += 4) { + MGC_Write32(pBase, bFifoOffset, *((uint32_t*)&(pSource[wIndex]))); + } + + for(; wIndex < wCount; wIndex++) { + MGC_Write8(pBase, bFifoOffset, pSource[wIndex]); + } +} + +/** + * Unload an HDRC FIFO + * + * @param pBase base address of HDRC + * @param bEnd local endpoint + * @param wCount how many bytes to unload + * @param pDest data buffer + */ +void MGC_HdrcUnloadFifo(const uint8_t* pBase, uint8_t bEnd, + uint16_t wCount, uint8_t* pDest) +{ + uint16_t wIndex=0, wIndex32; + uint16_t wCount32 = wCount >> 2; + uint8_t bFifoOffset = MGC_FIFO_OFFSET(bEnd); + +#ifdef MUSB_PARANOID + if ( IS_INVALID_ADDRESS(pDest) ) { + ERR("unloading fifo from a null buffer\n"); + return; + } +#endif + + DBG(2, "pBase=%p, bEnd=%d, wCount=0x%04x, pDest=%p\n", pBase, bEnd, + wCount, pDest); + + /* doublewords when possible */ + for(wIndex = wIndex32 = 0; wIndex32 < wCount32; wIndex32++, wIndex += 4) { + *((uint32_t*)&(pDest[wIndex])) = MGC_Read32(pBase, bFifoOffset); + } + + while(wIndex < wCount) { + pDest[wIndex++]=MGC_Read8(pBase, bFifoOffset); + } +} + +/* ------------------------------------------------------------------------- + * + * ------------------------------------------------------------------------ */ + +/** + * Stop the host controller driver. Stop the controller and disconnect the + * virtual hub. + * @param pThis the controller + * @param vberr !=0 if a VBUs error was discovered. + */ +static void hdrc_stop_host(MGC_LinuxCd* pThis, int vberr) +{ + MGC_HdrcStop(pThis); + +#ifdef MUSB_VIRTHUB + MGC_VirtualHubPortDisconnected(&(pThis->RootHub), 0); + pThis->pRootDevice = NULL; + mgc_hcd_flush(pThis); +#endif + +} + +/** + * Interrupt Service Routine to record USB "global" interrupts. + * Since these do not happen often and signify things of + * paramount importance, it seems OK to check them individually; + * there is an ORDER to perform the tests check p35 of the MUSBHDRC + * manual. + * + * @param pThis instance pointer + * @param bIntrUSB register contents + * @param devctl + * @param power + */ +static int mgc_hdrc_service_usb_stage0(MGC_LinuxCd* pThis, uint8_t bIntrUSB, + uint8_t devctl, uint8_t power) +{ + int handled=0; +#ifdef MUSB_HOST + uint8_t bSpeed = 1; + uint8_t bHubSpeed = 2; +#endif + uint8_t bResetBabble = FALSE; + uint8_t* pBase = (uint8_t*)pThis->pRegs; + + /* in host mode when a device resume me (from power save) + * in device mode when the host resume me; it shold not change + * "identity". + */ + if (bIntrUSB & MGC_M_INTR_RESUME) { + handled++; + DBG(2, "RESUME\n"); + + if (devctl & MGC_M_DEVCTL_HM) { +#ifdef MUSB_HOST + printk("Host Mode : resume\n"); + power &= ~MGC_M_POWER_SUSPENDM; + MGC_Write8(pBase, MGC_O_HDRC_POWER, power | MGC_M_POWER_RESUME); + MGC_LinuxSetTimer(pThis, MGC_HdrcDropResume, + (unsigned long)pThis, 40); +#endif + } + else { + udc_resume(); + printk("Device Mode : resume\n"); + } + } + + /* p35 MUSBHDRC manual for the order of the tests */ + if (bIntrUSB & MGC_M_INTR_SESSREQ) { + DBG(2, "SESSION_REQUEST\n"); + + /* NOTE i might get a sesison request WHILE switchign between B and A + * device investigatge about that; check p35 of the manual + */ +#ifdef MUSB_PARANOID + if ( HDRC_IS_DEV(pThis) ) { + ERR("Received a SESSION_REQUEST when connected to the B end; am I switching?!\n"); + } +#endif + + /* time critical code (turn on VBUS); inherent race condition */ + MGC_Write8(pBase, MGC_O_HDRC_DEVCTL, MGC_M_DEVCTL_SESSION); + pThis->bEnd0Stage = MGC_END0_START; + + handled++; + + } + + /* VBUSError is bad, shutdown & go to error mode and ignore + * the other interrups; p35 MUSBHDRC manual for the order + of the tests */ + if (bIntrUSB & MGC_M_INTR_VBUSERROR) { + handled++; + +#ifdef MUSB_PARANOID + if ( !(devctl & MGC_M_DEVCTL_HM) ) { + ERR("Received a MGC_M_INTR_VBUSERROR when connected to the B end!\n"); + hdrc_stop_host(pThis, FALSE); + return handled; + } +#endif + + DBG(2, "V_BUS ERROR??? this is bad (TM)\n"); + if ( pThis->bVbusErrors++ > MUSB_MAX_VBUS_ERRORS ) { + printk("Vbus Error\n"); + hdrc_stop_host(pThis, TRUE); + MUSB_ERR_MODE(pThis, MUSB_ERR_VBUS); + } + } + + /* connect is valid only when in host mode; ignore it if in device mode; + p35 MUSBHDRC manual for the order of the tests */ + + + if(bIntrUSB & MGC_M_INTR_CONNECT) { + handled++; + Urb_status=0; + + if(host_a_idle==1){ + host_a_idle=0; + } + DBG(2, "RECEIVED A CONNECT (goto host mode)\n"); + printk("connect interrupt\n"); +#ifdef MUSB_PARANOID + if ( !(devctl & MGC_M_DEVCTL_HM) ) { + ERR("Received a CONNECT when connected to the B end!\n"); + } +#endif + MGC_Write16(pBase, MGC_O_HDRC_INTRTXE, pThis->wEndMask); + MGC_Write16(pBase, MGC_O_HDRC_INTRRXE, pThis->wEndMask & 0xfffe); + +#ifdef MUSB_HOST + pThis->pRootDevice = NULL; + pThis->bEnd0Stage = MGC_END0_START; + + /* reset the addres... probably not needed*/ + MGC_Write8(pThis->pRegs, MGC_O_HDRC_FADDR, 0); + /* flush endpoints when transitioning from Device Mode*/ + if ( MUSB_IS_A_IDLE(pThis) ) { + uint8_t bEnd; + + for(bEnd = 0; bEnd < pThis->bEndCount; bEnd++) { + MGC_HdrcStopEnd(pThis, bEnd); + } + } + + + if(devctl & MGC_M_DEVCTL_LSDEV) { + bSpeed = 3; + bHubSpeed = 0; + } else if(devctl & MGC_M_DEVCTL_FSDEV) { + /* NOTE: full-speed is "speculative" until reset */ + bSpeed = 2; + bHubSpeed = 1; + } + + pThis->bRootSpeed = bSpeed; + if(pThis->bIsMultipoint) { + /* set speed for EP0 */ + MGC_SelectEnd(pBase, 0); + MGC_WriteCsr8(pBase, MGC_O_HDRC_TYPE0, 0, + (bSpeed << 6)); + } + + MUSB_HST_MODE(pThis); + + /* indicate new connection to OTG machine */ + MGC_VirtualHubPortConnected(&(pThis->RootHub), 0, + bHubSpeed); +#endif + } + + /* saved one bit: bus reset and babble share the same bit; + * If I am host is a babble! i must be the only one allowed + * to reset the bus; when in otg mode it means that I have + * to switch to device + */ + if (bIntrUSB & MGC_M_INTR_RESET) { + +#ifndef MUSB_OTG + + /* This is added since, Mentor IP same bit is shared for RESET and BABBLE. + * In host mode if this bit is set to indicate BABBLE, but when this bit + * get set the controller clears the session bit and the host mode bit in + * device control register and driver reads it as RESET and tries to enter + * in device mode. So if OTG is not set we will check the driver status and + * the appropriate action. + */ + + if(MUSB_IS_HST(pThis)){ + bResetBabble = TRUE; + } +#else + bResetBabble = devctl & MGC_M_DEVCTL_HM; +#endif + DBG(2, "BUS RESET\n"); + + if (bResetBabble) { + printk("Host Mode : reset\n"); + hdrc_stop_host(pThis, FALSE); + /* restart session after cooldown unless threshold reached */ + if( pThis->nBabbleCount++ < MUSB_MAX_BABBLE_COUNT) { + MGC_LinuxSetTimer(pThis, MGC_HdrcRestart, + (unsigned long)pThis, MUSB_RESTART_TIME); + } + } else { + + del_timer(¬ify_timer); + pThis->bEnd0Stage = MGC_END0_START; + MUSB_DEV_MODE(pThis); + printk("Device Mode : reset\n"); + + if(b_hnp_init == 1){ + otg_disconnect(udc_address); + driver_change_mode_handler(2); + devctl = MGC_Read8(pBase, MGC_O_HDRC_DEVCTL); + + } + + if(udcinitmonitorflag_isr==0){ + nomadik_udc_init(udc_address); + } + udcinitmonitorflag_init=1; + power = MGC_Read8(pBase, MGC_O_HDRC_POWER); + musb_reset_isr(); + dev_safe_remove=1; + } + handled++; + } + + return handled; +} + + +/** + * Interrupt Service Routine to record USB "global" interrupts. + * Since these do not happen often and signify things of + * paramount importance, it seems OK to check them individually; + * there is an ORDER to perform the tests check p35 of the MUSBHDRC + * manual. + * + * @param pThis instance pointer + * @param bIntrUSB register contents + * @param devctl + * @param power + */ +static int mgc_hdrc_service_usb_stage1(MGC_LinuxCd* pThis, uint8_t bIntrUSB, + uint8_t devctl, uint8_t power) + +{ + int handled=0; + uint8_t bEnd; + uint16_t wFrame; + uint8_t state; + uint8_t* pBase = (uint8_t*)pThis->pRegs; + /* p35 MUSBHDRC manual for the order of the tests */ + if(bIntrUSB & MGC_M_INTR_SOF) { + DBG(2, "START_OF_FRAME\n"); + handled++; + + /* start any periodic Tx transfers waiting for current frame */ + wFrame = MGC_Read16(pBase, MGC_O_HDRC_FRAME); + for(bEnd = 1; + (bEnd < pThis->bEndCount) && (pThis->wEndMask >= (1 << bEnd)); + bEnd++) + { + if(pThis->aLocalEnd[bEnd].dwWaitFrame && + pThis->aLocalEnd[bEnd].dwWaitFrame >= wFrame) + { + pThis->aLocalEnd[bEnd].dwWaitFrame = 0; + MGC_HdrcStartTx(pThis, bEnd); + } + } + } + + /* p35 MUSBHDRC manual for the order of the tests */ + if((bIntrUSB & MGC_M_INTR_DISCONNECT) && !pThis->bIgnoreDisconnect) { + DBG(2, "DISCONNECT()\n"); + + mdelay(500); + handled++; + /* need to check it against pThis, because the devctl is going + * low as soon as the device gets disconnected */ + if ( MUSB_IS_HST(pThis) ) { + printk("Host Disconnect\n"); + DBG(3, "Disconnecting a port of VirtualHub\n"); + +#ifdef MUSB_VIRTHUB + MGC_VirtualHubPortDisconnected(&(pThis->RootHub), 0); + pThis->pRootDevice = NULL; + + Urb_status=1; + /* flush endpoints */ + for(bEnd = 0; bEnd < pThis->bEndCount; bEnd++) { + MGC_HdrcStopEnd(pThis, bEnd); + } + + mgc_hcd_flush(pThis); + + MUSB_A_IDLE_MODE(pThis); + mod_timer(¬ify_timer, jiffies + msecs_to_jiffies(1000)); + +#endif + +#ifdef MUSB_CONFIG_PROC_FS + if(pThis->pfDisconnectListener) { + pThis->pfDisconnectListener(pThis->pDisconnectListenerParam); + } +#endif + } + else if (MUSB_IS_DEV(pThis) ){ + + if(b_hnp_init == 1){ + del_timer(¬ify_timer); + b_hnp_init=0; + } + + else { + printk("Device Disconnect\n"); + udc_disconnect_isr(); + MUSB_B_IDLE_MODE(pThis); + mod_timer(¬ify_timer, jiffies + msecs_to_jiffies(1000)); + } + } + + /* KLUDGE: race condition, doing this right away might prevent + * the virtual hub/usbcore to process the last urbs. As a matter + * of facts this code should be called after the "disconnect" */ + } + + /* I cannot get suspend while in host mode! go to error mode and ignore + * the other signals; need to be last (see manual p35)s */ + if (bIntrUSB & MGC_M_INTR_SUSPEND) { + DBG(2, "RECEIVED SUSPEND\n"); + if( b_hnp_suspend ==1) + { + uint8_t linestate; + MGC_HdrcReadUlpiReg(pThis, 0x15, &linestate); + b_hnp_suspend = 0; + driver_change_mode_handler(1); + } + handled++; + + if(devctl & MGC_M_DEVCTL_HM) { + hdrc_stop_host(pThis, FALSE); + } + if(dev_safe_remove==1) + { + udc_suspend(); + printk("Device Removed Safely \n"); + dev_safe_remove=0; + state=MGC_Read8(pBase, MGC_O_HDRC_DEVCTL); + MGC_Write8(pBase, MGC_O_HDRC_DEVCTL, state & ~MGC_M_DEVCTL_SESSION); + } + } + + return handled; +} + + +/** +* Program the HDRC to start (enable interrupts, etc.). + * @param pThis the controller +*/ +void MGC_HdrcStart(MGC_LinuxCd* pThis) +{ + uint8_t bEnd=1; + uint8_t* pBase = (uint8_t*)pThis->pRegs; + + DBG(2, "<==\n"); + + /* init the local ends */ +#ifdef MUSB_CONFIG_PROC_FS + pThis->aLocalEnd[0].dwTotalRxBytes = 0; + pThis->aLocalEnd[0].dwTotalRxPackets = 0; + pThis->aLocalEnd[0].dwErrorRxPackets = 0; + pThis->aLocalEnd[0].dwTotalTxBytes = 0; + pThis->aLocalEnd[0].dwTotalTxPackets = 0; + pThis->aLocalEnd[0].dwErrorTxPackets = 0; +#endif + + /* init counters and local data */ + for(bEnd=1; bEnd < pThis->bEndCount; bEnd++) { + spin_lock( &pThis->aLocalEnd[bEnd].Lock ); +#ifdef MUSB_CONFIG_PROC_FS + pThis->aLocalEnd[bEnd].dwTotalRxBytes = 0; + pThis->aLocalEnd[bEnd].dwTotalRxPackets = 0; + pThis->aLocalEnd[bEnd].dwErrorRxPackets = 0; + pThis->aLocalEnd[bEnd].dwTotalTxBytes = 0; + pThis->aLocalEnd[bEnd].dwTotalTxPackets = 0; + pThis->aLocalEnd[bEnd].dwErrorTxPackets = 0; +#endif +#ifndef MUSB_USE_HCD_DRIVER + INIT_LIST_HEAD( &(pThis->aLocalEnd[bEnd].urb_list) ); +#endif + pThis->aLocalEnd[bEnd].bIsClaimed=FALSE; + spin_unlock( &pThis->aLocalEnd[bEnd].Lock ); + } + + /* reset the counters */ + pThis->bVbusErrors=0; + + /* Set INT enable registers, enable interrupts */ + MGC_Write16(pBase, MGC_O_HDRC_INTRTXE, pThis->wEndMask); + MGC_Write16(pBase, MGC_O_HDRC_INTRRXE, pThis->wEndMask & 0xfffe); + MGC_Write8(pBase, MGC_O_HDRC_INTRUSBE, 0xf7); /* don't enable suspend! */ + + DBG(1, "INTRUSBE reg:0x%x \n", MGC_Read8(pBase, MGC_O_HDRC_INTRUSBE)); + DBG(1, "INTRTXE reg:0x%x \n", MGC_Read8(pBase, MGC_O_HDRC_INTRTXE)); + DBG(1, "INTRRXE reg:0x%x \n", MGC_Read8(pBase, MGC_O_HDRC_INTRRXE)); + + /* TODO: always set ISOUPDATE in POWER (periph mode) and leave it on! */ + MGC_Write8(pBase, MGC_O_HDRC_TESTMODE, 0); + + /* enable high-speed/low-power and start session */ + MGC_Write8(pBase, MGC_O_HDRC_POWER, + MGC_M_POWER_SOFTCONN | MGC_M_POWER_HSENAB); + + +#ifndef MUSB_GADGET + /* enable high-speed/low-power and start session & suspend IM host*/ + MGC_Write8(pBase, MGC_O_HDRC_DEVCTL, MGC_M_DEVCTL_SESSION); +#else + { + uint8_t state=MGC_Read8(pBase, MGC_O_HDRC_DEVCTL); + MGC_Write8(pBase, MGC_O_HDRC_DEVCTL, state & ~MGC_M_DEVCTL_SESSION); + } +#endif + + DBG(2, "==>\n"); +} + +/** + * Disable the HDRC (disable & flush interrupts); + * @param pThis the controller to disable + */ +STATIC void mgc_hdrc_disable(MGC_LinuxCd* pThis) +{ + uint16_t temp; + uint8_t* pBase = (uint8_t*)pThis->pRegs; + + DBG(2, "<==\n"); + + /* disable interrupts */ + MGC_Write8(pBase, MGC_O_HDRC_INTRUSBE, 0); + MGC_Write16(pBase, MGC_O_HDRC_INTRTXE, 0); + MGC_Write16(pBase, MGC_O_HDRC_INTRRXE, 0); + + MGC_Write8(pBase, MGC_O_HDRC_DEVCTL, 0); + MGC_Write8(pBase, MGC_O_HDRC_DEVCTL, 1); + + /* flush pending interrupts */ + temp = MGC_Read8(pBase, MGC_O_HDRC_INTRUSB); + temp = MGC_Read16(pBase, MGC_O_HDRC_INTRTX); + temp = MGC_Read16(pBase, MGC_O_HDRC_INTRRX); + + DBG(2, "==> HDRC Interrupts disabled\n"); +} + + +STATIC void mgc_reset(MGC_LinuxCd* pThis) +{ + uint8_t* pBase = (uint8_t*)pThis->pRegs; + uint8_t temp; + + DBG(2, "<==\n"); + + temp = MGC_Read8(pBase, MGC_O_HDRC_POWER); + MGC_Write8(pBase, MGC_O_HDRC_POWER, temp | MGC_M_POWER_RESET); + DBG(1, "%s power reg:0x%x \n", __FUNCTION__,MGC_Read8(pBase, MGC_O_HDRC_POWER)); + +} + +/** + * Enable the HDRC + * @param pThis the controller to disable + */ +void mgc_hdrc_enable(MGC_LinuxCd* pThis) +{ + uint8_t* pBase = (uint8_t*)pThis->pRegs; + + DBG(2, "<==\n"); + + /* Set INT enable registers, enable interrupts */ + MGC_Write16(pBase, MGC_O_HDRC_INTRTXE, pThis->wEndMask); + MGC_Write16(pBase, MGC_O_HDRC_INTRRXE, pThis->wEndMask & 0xfffe); + /* don't enable suspend mode! */ + MGC_Write8(pBase, MGC_O_HDRC_INTRUSBE, 0xf7); + + DBG(1, "%s INTRUSBE reg:0x%x \n", __FUNCTION__,MGC_Read8(pBase, MGC_O_HDRC_INTRUSBE)); + DBG(1, "%s INTRTXE reg:0x%x \n", __FUNCTION__,MGC_Read8(pBase, MGC_O_HDRC_INTRTXE)); + DBG(1, "%s INTRRXE reg:0x%x \n", __FUNCTION__,MGC_Read8(pBase, MGC_O_HDRC_INTRRXE)); + + /* no test mode */ + MGC_Write8(pBase, MGC_O_HDRC_TESTMODE, 0); + +#ifndef MUSB_GADGET + /* enable high-speed/low-power and start session & suspend IM host*/ + MGC_Write8(pBase, MGC_O_HDRC_DEVCTL, MGC_M_DEVCTL_SESSION); +#else + { + uint8_t state=MGC_Read8(pBase, MGC_O_HDRC_DEVCTL); + MGC_Write8(pBase, MGC_O_HDRC_DEVCTL, state & ~MGC_M_DEVCTL_SESSION); + } +#endif + +} + +/** +* Program the HDRC to stop (disable interrupts, etc.). +*/ +void MGC_HdrcStop(MGC_LinuxCd* pThis) +{ + DBG(2, "<==\n"); + + /* flush endpoints */ +#ifdef MUSB_VIRTHUB + { + uint8_t bEnd; + + mgc_hdrc_disable(pThis); + for(bEnd = 0; bEnd < min(16, (int)pThis->bEndCount); bEnd++) { + MGC_HdrcStopEnd(pThis, bEnd); + } + } +#endif +} + +/* ------------------------------------------------------------------------ */ + +#define MUSB_HDRC_ULPI_ACCESS +#ifdef MUSB_HDRC_ULPI_ACCESS + +uint8_t MGC_HdrcUlpiVbusControl(MGC_LinuxCd* pThis, uint8_t bExtSource, uint8_t bExtIndicator) +{ + uint8_t bVal; + uint8_t* pBase = pThis->pRegs; + + /* ensure not powered down */ + if(MGC_Read8(pBase, MGC_O_HDRC_POWER) & MGC_M_POWER_ENSUSPEND) { + return FALSE; + } + + bVal = bExtSource ? MGC_M_ULPI_VBUSCTL_USEEXTVBUS : 0; + bVal |= bExtIndicator ? MGC_M_ULPI_VBUSCTL_USEEXTVBUSIND : 0; + MGC_Write8(pBase, MGC_O_HDRC_ULPI_VBUSCTL, bVal); + + return TRUE; +} + +uint8_t MGC_HdrcReadUlpiReg(MGC_LinuxCd* pThis, uint8_t bAddr, uint8_t* pbData) +{ + uint8_t bCtl = 0; + uint8_t* pBase = pThis->pRegs; + + /* ensure not powered down */ + if(MGC_Read8(pBase, MGC_O_HDRC_POWER) & MGC_M_POWER_ENSUSPEND) { + return FALSE; + } + + /* polled */ + MGC_Write8(pBase, MGC_O_HDRC_ULPI_REGADDR, bAddr); + MGC_Write8(pBase, MGC_O_HDRC_ULPI_REGCTL, + MGC_M_ULPI_REGCTL_READNOTWRITE | MGC_M_ULPI_REGCTL_REG); + + + while(!(MGC_M_ULPI_REGCTL_COMPLETE & bCtl)) { + bCtl = MGC_Read8(pBase, MGC_O_HDRC_ULPI_REGCTL); + } + + *pbData = MGC_Read8(pBase, MGC_O_HDRC_ULPI_REGDATA); + MGC_Write8(pBase, MGC_O_HDRC_ULPI_REGCTL, 0); + return TRUE; +} + +uint8_t MGC_HdrcWriteUlpiReg(MGC_LinuxCd* pThis, uint8_t bAddr, uint8_t bData) +{ + uint8_t bCtl = 0; + uint8_t* pBase = pThis->pRegs; + + /* ensure not powered down */ + if(MGC_Read8(pBase, MGC_O_HDRC_POWER) & MGC_M_POWER_ENSUSPEND) { + return FALSE; + } + + /* polled */ + MGC_Write8(pBase, MGC_O_HDRC_ULPI_REGADDR, bAddr); + MGC_Write8(pBase, MGC_O_HDRC_ULPI_REGDATA, bData); + MGC_Write8(pBase, MGC_O_HDRC_ULPI_REGCTL, MGC_M_ULPI_REGCTL_REG); + + while(!(MGC_M_ULPI_REGCTL_COMPLETE & bCtl)) { + bCtl = MGC_Read8(pBase, MGC_O_HDRC_ULPI_REGCTL); + } + + MGC_Write8(pBase, MGC_O_HDRC_ULPI_REGCTL, 0); + + return TRUE; +} +#endif + +/* ------------------------------------------------------------------------ */ + +/** +* Discover HDRC configuration. +* @param wType +* @param pThis the controller instance +*/ +STATIC uint8_t MGC_HdrcInit(uint16_t wType, MGC_LinuxCd* pThis) +{ +#ifdef MUSB_AHB_ID + uint32_t dwData; +#endif + uint8_t reg, bType=0; + uint16_t wRelease, wRelMajor, wRelMinor; + char aInfo[78], aRevision[32], aDate[12]; + void* pBase = pThis->pRegs; + + DBG(2, "<==\n"); + + /* log core options */ + MGC_SelectEnd(pBase, 0); + reg = MGC_ReadCsr8(pBase, MGC_O_HDRC_CONFIGDATA, 0); + + strcpy(aInfo,(reg & MGC_M_CONFIGDATA_UTMIDW)?"UTMI-16":"UTMI-8"); + if(reg & MGC_M_CONFIGDATA_DYNFIFO) { + strcat(aInfo, ", dyn FIFOs"); + } + if(reg & MGC_M_CONFIGDATA_MPRXE) { + strcat(aInfo, ", bulk combine"); + } + if(reg & MGC_M_CONFIGDATA_MPTXE) { + strcat(aInfo, ", bulk split"); + } + if(reg & MGC_M_CONFIGDATA_HBRXE) { + strcat(aInfo, ", HB-ISO Rx"); + } + if(reg & MGC_M_CONFIGDATA_HBTXE) { + strcat(aInfo, ", HB-ISO Tx"); + } + if(reg & MGC_M_CONFIGDATA_SOFTCONE) { + strcat(aInfo, ", SoftConn"); + } + + INFO("ConfigData=0x%02x (%s)\n", reg, aInfo); + +#ifdef MUSB_AHB_ID + dwData = MGC_Read32(pBase, 0x404); + sprintf(aDate, "%04d-%02x-%02x", (dwData & 0xffff), + (dwData >> 16) & 0xff, + (dwData >> 24) & 0xff); + dwData = MGC_Read32(pBase, 0x408); + printk("ID2=%lx\n", (long unsigned)dwData); + dwData = MGC_Read32(pBase, 0x40c); + printk("ID3=%lx\n", (long unsigned)dwData); + bType = MGC_Read8(pBase, 0x400); + pThis->bIsMultipoint=('M' == bType) + ? TRUE : FALSE; +#else + bType = 'x'; + pThis->bIsMultipoint=(MUSB_CONTROLLER_MHDRC == wType) + ? TRUE : FALSE; +#endif + + /* log release info */ + wRelease = MGC_Read16(pBase, 0x6c); + wRelMajor = (wRelease >> 10) & 0x1f; + wRelMinor = wRelease & 0x3ff; + snprintf(aRevision, 32, "%d.%d%s", wRelMajor, + wRelMinor, (wRelease & 0x8000) ? "RC" : ""); + INFO("%cDRC version %s %s\n", bType, aRevision, aDate); + + + /* configure ep0 */ + pThis->aLocalEnd[0].wMaxPacketSizeTx = MGC_END0_FIFOSIZE; + pThis->aLocalEnd[0].wMaxPacketSizeRx = MGC_END0_FIFOSIZE; + + /* discover endpoint configuration */ + pThis->bBulkTxEnd = 0; + pThis->bBulkRxEnd = 0; + pThis->bEndCount = 1; + pThis->wEndMask = 1; + +#ifdef MUSB_C_DYNFIFO_DEF + if(!(reg & MGC_M_CONFIGDATA_DYNFIFO)) { + ERR("Dynamic FIFOs not detected in hardware; please rebuild software\n"); + return FALSE; + } +#else + if (reg & MGC_M_CONFIGDATA_DYNFIFO) { + ERR("Dynamic FIFOs detected in hardware; please rebuild\n"); + return FALSE; + } +#endif + + MGC_HdrcConfigureEps(pThis); + +#ifdef MUSB_HOST + MGC_InitLocalEndPoints(pThis); +#endif + + /* claim the bulk tx/rx ends */ + if(pThis->bBulkTxEnd) { + pThis->aLocalEnd[pThis->bBulkTxEnd].bIsClaimed = TRUE; + } + + if(pThis->bBulkRxEnd) { + pThis->aLocalEnd[pThis->bBulkRxEnd].bIsClaimed = TRUE; + } + + return TRUE; +} + +/************************************************************************** + * Linux HCD functions +**************************************************************************/ + +#ifdef MUSB_V26 +#define IS_TIMER_INITILIZED(_t) ((_t)->magic==TIMER_MAGIC) +#else +#define IS_TIMER_INITILIZED(_t) (1) +#endif + +/** + * Generic timer creation. + * @param pThis instance pointer + * @param pfFunc timer fire callback + * @param pParam parameter for callback + * @param millisecs how many milliseconds to set + */ +void MGC_LinuxSetTimer(MGC_LinuxCd* pThis, void (*pfFunc)(unsigned long), + unsigned long pParam, unsigned long millisecs) +{ + DBG(2, "<==\n"); + + init_timer(&(pThis->Timer)); + pThis->Timer.function = pfFunc; + pThis->Timer.data = (unsigned long)pParam; + pThis->Timer.expires = jiffies + (HZ * millisecs) / 1000; + add_timer( &(pThis->Timer) ); +} + +#ifdef MUSB_V26 +void* MGC_LinuxBufferAlloc(struct usb_bus* pBus, size_t nSize, + unsigned iMemFlags, dma_addr_t* pDmaAddress) +{ + /* for now, just kmalloc it */ + MGC_LinuxCd* pThis=hcd_to_musbstruct(pBus->hcpriv); + +#ifdef MUSB_PARANOID + if ( !pThis ) { + ERR("cannot find the controller, cannot allocate the memory\n"); + return 0; + } +#endif + + DBG(2, "<== allocating memory on bus (%s), %d, pDmaAddress=%p\n", + pBus->bus_name, pBus->busnum, pDmaAddress ); + return MGC_AllocBufferMemory(pThis, nSize, iMemFlags, pDmaAddress); +} + +void MGC_LinuxBufferFree(struct usb_bus* pBus, size_t nSize, + void* address, dma_addr_t dma) +{ + MGC_LinuxCd* pThis=hcd_to_musbstruct(pBus->hcpriv); + +#ifdef MUSB_PARANOID + if ( !pThis ) { + KFREE(address); + ERR("cannot find the controller, cannot free the memory properly\n"); + return; + } +#endif + + MGC_FreeBufferMemory(pThis, nSize, address, dma); +} +#endif + + +#if defined(MUSB_V26) || defined(MUSB_GADGET) +/** + * Allocate memory for a buffer that might use DMA. + * + * @param pThis + * @param bytes + * @param gfp_flags + * @param dma NULL when DMAble memeory is not requested. + */ +void* MGC_AllocBufferMemory(MGC_LinuxCd* pThis, size_t bytes, int gfp_flags, dma_addr_t* dma) { + void* addr = NULL; + + if ( dma ) { + *dma = DMA_ADDR_INVALID; + } + +#if !defined(USE_KMALLOC) && !defined(MUSB_LINUX_MV21) + { + KMALLOC(addr, bytes, gfp_flags); + if ( addr && dma ) { + *dma = virt_to_phys(addr); + } + DBG(2, "mallocd addr=%p, pDmaAddress=%p\n", addr, dma); + } +#else + { + KMALLOC(addr, bytes, gfp_flags); + if ( addr && dma ) { + *dma = virt_to_phys(addr); + } + + DBG(2, "mallocd addr=%p, pDmaAddress=%p\n", addr, dma); + } +#endif + + if ( addr ) { + memset(addr, 0, bytes); + } + + return addr; +} + +/** + * Free memory previously allocated with AllocBufferMemory. + * @param pThis + * @param bytes + * @param dma + */ +void MGC_FreeBufferMemory(MGC_LinuxCd* pThis, size_t bytes, void *address, dma_addr_t dma) { + + DBG(2, "<== freeing bytes=%d, address=%p, dma=%p\n", bytes, address, (void*)dma); + +#if !defined(USE_KMALLOC) && !defined(MUSB_LINUX_MV21) + DBG(2, "==>\n"); +#else + { + KFREE(address); + } +#endif + DBG(2, "==>\n"); +} +#endif + +/* ------------------------------------------------------------------------ */ + +#ifndef MUSB_V26_POST10 +/** + * Private per-device allocation + * @param pDevice Linux USBD device pointer + * @return status code + */ +STATIC int mgc_linux_alloc_device(struct usb_device *pDevice) +{ + + DBG(2, "<==>\n"); + return 0; + +} + +/** + * Private per-device cleanup + * @param pDevice Linux USBD device pointer + * @return 0 (success) + */ +STATIC int mgc_linux_free_device(struct usb_device * pDevice) +{ + DBG(2, "<==>\n"); + return 0; +} + +int MGC_LinuxHubSuspend(struct usb_bus *pBus) { + return 0; +} + +int MGC_LinuxHubResume(struct usb_bus *pBus) { + return 0; +} + +#endif + +/* ------------------------------------------------------------------------ */ + +/** + * Get the current frame number. + * @param struct usb_hcd pointer to usb_hcd structure + * @return frame number + */ +static inline int mgc_get_frame_number(MGC_LinuxCd* pThis) { + uint8_t* pBase = (uint8_t*)pThis->pRegs; + const int no=(int)MGC_Read16(pBase, MGC_O_HDRC_FRAME); + + DBG(2, "<==> %d\n", no); + return no; +} + +/* + */ +int MGC_LinuxGetFrameNumber(struct usb_device* pDevice) +{ + MGC_LinuxCd* pThis=hcd_to_musbstruct(pDevice->bus->hcpriv); + return mgc_get_frame_number( pThis ); +} + + +/************************************************************************** + * Linux driver hooks +**************************************************************************/ + +/** + * Generic Interrupt Service Routine. + * @param pThis the controller + */ +static irqreturn_t mgc_linux_isr(MGC_LinuxCd* pThis) +{ + uint32_t nSource; +#if MUSB_DEBUG > 0 + uint16_t wIntrTxCheck, wIntrRxCheck; +#endif + const void* pBase = pThis->pRegs; + uint8_t devctl = MGC_Read8(pBase, MGC_O_HDRC_DEVCTL); + + uint8_t power = MGC_Read8(pBase, MGC_O_HDRC_POWER); + + uint8_t bIntrUsbValue=MGC_Read8(pBase, MGC_O_HDRC_INTRUSB); + uint16_t wIntrTxValue=MGC_Read16(pBase, MGC_O_HDRC_INTRTX); + uint16_t wIntrRxValue=MGC_Read16(pBase, MGC_O_HDRC_INTRRX); + + nSource = bIntrUsbValue | wIntrTxValue | wIntrRxValue; + DEBUG_CODE(10, if (!nSource) { \ + INFO("IRQ [mode=%s] nSource=%d\n", MUSB_MODE(pThis), nSource); } ); + + + if (!nSource) { + RETURN_IRQ_NONE; + } + + DBG(2, "<== [%ld]: IRQ RECEIVED [devmode=%s, hwmode=%s] IntrUSB=%02x, IntrUSBE=%02x, IntrTx=%04x, IntrRx=%04x\n", + jiffies, MUSB_MODE(pThis), (devctl & MGC_M_DEVCTL_HM)?"host":"function", + bIntrUsbValue, MGC_Read8(pBase, MGC_O_HDRC_INTRUSBE), + wIntrTxValue, wIntrRxValue); + + + /* Recent IPs return the right values (not the masked one) */ + bIntrUsbValue &= MGC_Read8(pBase, MGC_O_HDRC_INTRUSBE); + + + /* corruption check */ +#ifdef MUSB_PARANOID + if ( MGC_ISCORRUPT(pThis) ) { + INFO("stopping before ISR, the controller structure is corrupted\n"); + MGC_HdrcStop(pThis); + MUSB_ERR_MODE(pThis, MUSB_ERR_CORRUPTED); + + RETURN_IRQ_HANDLED; + } +#endif + +#ifdef MUSB_DMA + /* ### DMA intr handler added */ + if ( pThis->pDmaController->pfDmaControllerIsr(pThis->pDmaController->pPrivateData) ) { + DBG(1, "%s: ******** DMA interrupt *************\n",__FUNCTION__); + nSource |= 1; + } +#endif + + + /* the core can interrupt us for multiple reasons, I.E. more than an + * interrupt line can be asserted; service the globa interrupt first. + * Global interrups are used to signal connect/disconnect/vbuserr + * etc. processed in two phase */ + if ( bIntrUsbValue ) { + DBG(3, "** IRQ [mode=%s] nSource=%d | DEVCTL :0x%x | IntrUsb:0x%x \n", \ + MUSB_MODE(pThis), nSource, MGC_Read8(pBase, MGC_O_HDRC_DEVCTL), bIntrUsbValue); + mgc_hdrc_service_usb_stage0(pThis, bIntrUsbValue, devctl, power); + } + +#ifdef MUSB_PARANOID + if ( wIntrTxValue || wIntrRxValue ) { /* got data! */ + if ( ((devctl & MGC_M_DEVCTL_HM) && (!MUSB_IS_HST(pThis))) + || (!(devctl & MGC_M_DEVCTL_HM) && (!MUSB_IS_DEV(pThis))) ) + { + if ( bIntrUsbValue ) { + mgc_hdrc_service_usb_stage1(pThis, bIntrUsbValue, devctl, power); + } else { + WARN("early interrupt while in hm=%d: otg machine hasn't done yet\n", + devctl & MGC_M_DEVCTL_HM); + } + + RETURN_IRQ_HANDLED; + } + } +#endif + + /* ignore requests when in error */ + if( MUSB_IS_ERR(pThis) ) { + if ( bIntrUsbValue) { + mgc_hdrc_service_usb_stage1(pThis, bIntrUsbValue, devctl, power); + } else { + ERR("Error mode, please ZAP the driver!\n"); + mgc_hdrc_disable(pThis); + } + + RETURN_IRQ_HANDLED; + } + + /* handle tx/rx on endpoints; each bit of wIntrTxValue is an endpoint, + * endpoint 0 first (p35 of the manual) bc is "SPECIAL" treatment; + * WARNING: when operating as device you might start receving traffic + * to ep0 before anything else happens so be ready for it */ + do { + uint8_t bShift=0; + uint32_t reg=wIntrTxValue; + + if(reg & 1 ) { /* EP0 */ + if (devctl & MGC_M_DEVCTL_HM) { +#ifdef MUSB_CONFIG_PROC_FS + if(pThis->pfDefaultEndHandler) { + pThis->pfDefaultEndHandler(pThis->pDefaultEndHandlerParam); + } else +#endif + MGC_HdrcServiceDefaultEnd(pThis); + } else { + udc_ep0_irq(); + } + } + +#ifdef MUSB_PARANOID + if( MGC_ISCORRUPT(pThis) ) { + INFO("after servicing Ep0 interrupt\n"); + break; + } +#endif + + /* TX on endpoints 1-15 */ + bShift = 1; + reg >>= 1; + while(reg) { + if(reg & 1) { + if(devctl & MGC_M_DEVCTL_HM) { + MGC_HdrcServiceTxAvail(pThis, bShift); + } else { + udc_ep_tx_irq(bShift) ; + } + } + reg >>= 1; + bShift++; + } + + DEBUG_CODE(10, wIntrTxCheck = MGC_Read16(pBase, MGC_O_HDRC_INTRTX); \ + if(wIntrTxCheck && (wIntrTxCheck == wIntrTxValue)) { \ + ERR("Unhandled TX interrupt, wIntrTx=%04x wIntrTxCheck=%04x; DRC stopped\n",\ + wIntrTxValue, wIntrTxCheck); \ + for(bShift = 0; bShift < pThis->bEndCount; bShift++) { \ + MGC_HdrcDumpRegs(pThis->pRegs, \ + MUSB_IS_HST(pThis) && pThis->bIsMultipoint, bShift); \ + } \ + MGC_HdrcStop(pThis); \ + MUSB_ERR_MODE(pThis, MUSB_ERR_IRQ); \ + MGC_VirtualHubPortDisconnected(&(pThis->RootHub), 0); \ + pThis->pRootDevice = NULL; \ + } ); + +#ifdef MUSB_PARANOID + if( MGC_ISCORRUPT(pThis) ) { + INFO("after servicing Tx interrupt\n"); + break; + } +#endif + + /* RX on endpoints 1-15 */ + reg = wIntrRxValue; + bShift = 1; + reg >>= 1; + while(reg) { + if(reg & 1) { + if(devctl & MGC_M_DEVCTL_HM) { + MGC_HdrcServiceRxReady(pThis, bShift); + } else { + udc_ep_rx_irq(bShift) ; + } + } + + reg >>= 1; + bShift++; + } + + DEBUG_CODE(10, wIntrRxCheck = MGC_Read16(pBase, MGC_O_HDRC_INTRRX); \ + if(wIntrRxCheck && (wIntrRxCheck == wIntrRxValue)) { \ + DBG(1, "Unhandled RX interrupt, IntrRx=%04x; IntrRxCheck=%04x DRC stopped\n", \ + wIntrRxValue, wIntrRxCheck); \ + for(bShift = 0; bShift < pThis->bEndCount; bShift++) { \ + MGC_HdrcDumpRegs(pThis->pRegs, \ + MUSB_IS_HST(pThis) && pThis->bIsMultipoint, bShift); \ + } \ + MGC_HdrcStop(pThis); \ + MUSB_ERR_MODE(pThis, MUSB_ERR_IRQ); \ + MGC_VirtualHubPortDisconnected(&(pThis->RootHub), 0); \ + pThis->pRootDevice = NULL; \ + }); + + /* Global interrups are used to signal connect/disconnect/vbuserr + * etc. processed in two phase */ + if (bIntrUsbValue) { + mgc_hdrc_service_usb_stage1(pThis, bIntrUsbValue, devctl, power); + } + +#ifdef MUSB_PARANOID + if( MGC_ISCORRUPT(pThis) ) { + INFO("stopping after servicing Rx interrupt\n"); + } +#endif + } while (0); + +#ifdef MUSB_PARANOID + if( MGC_ISCORRUPT(pThis) ) { + MGC_HdrcStop(pThis); + MUSB_ERR_MODE(pThis, MUSB_ERR_CORRUPTED); + } +#endif + + DBG(2, "==> IRQ HANDLED [devmode=%s]\n", MUSB_MODE(pThis)); + RETURN_IRQ_HANDLED; +} + + +/** + * Interrupt service routine. + * @param irq interrupt line associated with the controller + * @param hci data structure for the host controller + * @param r holds the snapshot of the processor's context before + * the processor entered interrupt code. (not used here) + */ +#ifndef MUSB_USE_HCD_DRIVER +irqreturn_t MGC_LinuxIsr(int irq, void *__hci, struct pt_regs *r) +{ + + MGC_LinuxCd* pThis = (MGC_LinuxCd*)__hci; + return mgc_linux_isr(pThis); +} +#endif + +/*****************************************************/ + +void goto_host_mode(MGC_LinuxCd* pThis) { + /* TODO: graceful Gadget shutdown */ + MUSB_HST_MODE(pThis); +#ifdef MUSB_USE_HCD_DRIVER + +#else + +#endif +} + +void goto_device_mode(MGC_LinuxCd* pThis) { + /* TODO: graceful host shutdown */ + MUSB_DEV_MODE(pThis); +} + + +/* -------------------------------------------------------------------------- + * Init function + * + */ + +#ifndef MUSB_USE_HCD_DRIVER +/** attach to the IRQ and update the controller structure. + * @param nIrq the Irq number + * @param pThis the controller + * @return 0 if success (pThis is also update), negative is error + */ +static int mgc_request_irq(int nIrq, MGC_LinuxCd* pThis) { + int rc=-ENODEV; + + pThis->nIrq = nIrq; + /* the hcd driver will take care of that */ + do { + +#ifdef MUSB_HARD_IRQ + if ( 0==request_irq(nIrq, MGC_LinuxIsr, SA_INTERRUPT, + pThis->aName, pThis)) + { + rc=0; + pThis->nIrqType=SA_INTERRUPT; + break; + } +#endif + if ( 0==request_irq(nIrq, MGC_LinuxIsr, SA_SHIRQ, + pThis->aName, pThis)) + { + rc=0; + pThis->nIrqType=SA_SHIRQ; + break; + } + } while (0); + + return rc; +} + +/** + * release in irq previously allocated with mgc_request_irq(). +* @param pTHis the controller the IRQ was allocated for + */ +static void mgc_free_irq(MGC_LinuxCd* pThis) { + free_irq(pThis->nIrq, pThis); +} +#endif + +#ifdef MUSB_VIRTHUB +#ifndef MUSB_USE_HCD_DRIVER +static int mgc_init_bus(MGC_LinuxCd *pThis, void* pDevice) +{ + int rc=0; + + /* allocate and register bus */ + pThis->pBus=usb_alloc_bus( &MGC_LinuxOperations ); + if (!pThis->pBus ) { + return -ENODEV; + } + +#ifdef MUSB_V26 + pThis->pBus->controller =(struct device*)pDevice; +#endif + +#ifdef MUSB_HAS_BUSNAME + pThis->pBus->bus_name = pThis->aName; +#endif + + /* when using the HCD driver (USE_HCD_DRIVER) + pThis->pBus->hcpriv points to the hcd driver + */ + pThis->pBus->hcpriv = (void *)pThis; + + usb_register_bus(pThis->pBus); + INFO("Registered new bus @%p\n", pThis->pBus); + + rc=mgc_init_root_hub(pThis); + if ( rc!=0 ) { + usb_deregister_bus(pThis->pBus); + } else { + pThis->pBus->root_hub = pThis->RootHub.pDevice; + } + + return rc; +} + +static void mgc_free_bus(struct usb_bus *bus) { +#ifdef MUSB_V26 + usb_deregister_bus(bus); +#endif +} + +#endif +#endif + +/* disable an endpoint */ +#ifdef MUSB_V26 +void mgc_linux_disable(struct usb_device* pDevice, int bEndpointAddress) +{ + /* to do */ +} +#endif + + +/* -------------------------------------------------------------------------- + * HOST DMA related code + * + */ + +#ifdef MUSB_DMA +/** + * used ONLY in host mode, I'll be moved to musb_host + * @param pPrivateData + * @param bLocalEnd + * @param bTransmit + */ +STATIC uint8_t MGC_LinuxDmaChannelStatusChanged( + void* pPrivateData, uint8_t bLocalEnd, uint8_t bTransmit) +{ + MGC_LinuxCd* pThis = (MGC_LinuxCd*)pPrivateData; + MGC_LinuxLocalEnd* pEnd = &(pThis->aLocalEnd[bLocalEnd]); + struct urb* pUrb = MGC_GetCurrentUrb(pEnd); + const void* pBase = pThis->pRegs; + uint8_t devctl = MGC_Read8(pBase, MGC_O_HDRC_DEVCTL); + + if(!bLocalEnd) { + /* endpoint 0 */ + if(devctl & MGC_M_DEVCTL_HM) { +#ifdef MUSB_CONFIG_PROC_FS + if(pThis->pfDefaultEndHandler) { + pThis->pfDefaultEndHandler(pThis->pDefaultEndHandlerParam); + } else +#endif + MGC_HdrcServiceDefaultEnd(pThis); + } else { + MGC_HdrcServiceDeviceDefaultEnd(pThis); + } + } else { + /* endpoints 1..15 */ + if(bTransmit) { + if(devctl & MGC_M_DEVCTL_HM) { + MGC_HdrcServiceTxAvail(pThis, bLocalEnd); + } else { + MGC_HdrcServiceDeviceTxAvail(pThis, bLocalEnd); + } + } else { + /* receive */ + if(devctl & MGC_M_DEVCTL_HM) { + MGC_HdrcServiceRxReady(pThis, bLocalEnd); + } else { + MGC_HdrcServiceDeviceRxReady(pThis, bLocalEnd); + } + } + } + + /* trick: if end's URB changed; previous one completed; + * probably not needed now... */ + return (pUrb == MGC_GetCurrentUrb(pEnd)) ? FALSE : TRUE; +} +#endif + +/*-------------------------------------------------------------------------*/ + +#ifdef MUSB_USE_HCD_DRIVER +#include "musb_hcd.c" +#endif + +/** + * Perform generic per-controller initialization. + * + * @param pDevice + * @param nIrq IRQ (interpretation is system-dependent) + * @param pRegs pointer to controller registers, + * assumed already mapped into kernel space + * @param pName name for bus + */ + +MGC_LinuxCd* MGC_LinuxInitController(void* pDevice, uint16_t wType, + int nIrq, void* pRegs, u64 len, const char* pName) +{ + uint8_t bEnd; + MGC_LinuxCd* pThis; +#ifdef MUSB_USE_HCD_DRIVER + struct usb_hcd *hcd = NULL; +#endif + MGC_LinuxLocalEnd* pEnd; + uint16_t temp; + DBG(2, "<==\n"); + + /* allocate */ + INFO("MUSB Driver [Base Address(PA)=0x%p] [IRQ = %d] [pDevice=%p]\n", + pRegs , nIrq, pDevice); + +#ifdef MUSB_USE_HCD_DRIVER + /////////////////////////////////////////////////////////////////////////////// + /* allocate */ + + + hcd = usb_create_hcd(&musb_ahb_hc_driver, (struct device*)pDevice, + ((struct device*)pDevice)->bus_id); + hcd1=hcd; + if ( !hcd ) { + return NULL; + } + + hcd->rsrc_len = len; + /* register Base address (VA)*/ + hcd->regs = pRegs; + /////////////////////////////////////////////////////////////////////////////// + + pThis=hcd_to_musbstruct(hcd); + udc_address=pThis; + spin_lock_init(&pThis->LocalQueue.urb_queue_lock); + init_waitqueue_head(&pThis->waitqh); +#else + KMALLOC(pThis, sizeof(MGC_LinuxCd), GFP_ATOMIC); + if(!pThis) { + ERR("kmalloc driver instance data failed\n"); + return NULL; + } + memset (pThis, 0, sizeof(MGC_LinuxCd)); +#endif + + + + pThis->pRegs = pRegs; + + strcpy(pThis->aName, pName); + spin_lock_init(&pThis->Lock); + +#if MUSB_DEBUG > 0 + pThis->dwPadFront = MGC_PAD_FRONT; + pThis->dwPadBack = MGC_PAD_BACK; +#endif + +#ifdef MUSB_DMA + pThis->pDmaController = MGC_HdrcDmaControllerFactory + .pfNewDmaController(MGC_LinuxDmaChannelStatusChanged, pThis, (uint8_t*)pRegs); + if(pThis->pDmaController) { + DBG(2, "DMA initialized&enabled Address: 0x%p\n", pThis->pDmaController); + pThis->pDmaController->pfDmaStartController( + pThis->pDmaController->pPrivateData); + } +#endif + + + mgc_reset(pThis); + + /* be sure interrupts are disabled before connecting ISR */ + mgc_hdrc_disable(pThis); + + // Reset the device, otherwise the controller + // can be in unknown state. + temp = MGC_Read16(pThis->pRegs, MGC_O_HDRC_TOPCONTROL); + + MGC_Write16(pThis->pRegs, MGC_O_HDRC_TOPCONTROL, (temp |MGC_M_TOPCTRL_MODE_SRST)); + + /* discover configuration */ + if ( !MGC_HdrcInit(wType, pThis) ) { +#ifdef MUSB_USE_HCD_DRIVER + /* free memory ? */ +#else + /* free memory ? */ +#endif + return NULL; + } + /*for nhk15 this a must for powering up the STULPI + */ + /*power up the STULPI tranceiver*/ + MGC_Write8(pThis->pRegs, MGC_O_HDRC_ULPI_VBUSCTL, 0x3); + + /* print config */ + for(bEnd = 0; bEnd < pThis->bEndCount; bEnd++) { + pEnd = &(pThis->aLocalEnd[bEnd]); + if(pEnd->wMaxPacketSizeTx || pEnd->wMaxPacketSizeRx) { + INFO("End %02d: %sFIFO TxSize=%04x/RxSize=%04x\n", + bEnd, pEnd->bIsSharedFifo ? "Shared " : "", + pEnd->wMaxPacketSizeTx, pEnd->wMaxPacketSizeRx); + } else { + INFO("End %02d: not configured\n", bEnd); + } + } + + /* procfs and testing interface */ + MGC_LinuxCreateProcFs(pThis->aName, pThis); + +#ifdef MUSB_PROC_TESTMUSB + MGC_LinuxCreateTestProcFs(pThis->aName, pThis); +#endif + + MUSB_B_IDLE_MODE(pThis); + DBG(1, "MUSB_B_IDLE mode \n"); + temp = MGC_Read8(pThis->pRegs, MGC_O_HDRC_DEVCTL ); + + /* connect ISR */ + + +#ifdef MUSB_USE_HCD_DRIVER + /* by default allocate shared IRQ */ + pThis->nIrq=nIrq; + pThis->nIrqType=MUSB_DEFAULT_IRQTYPE; +#else + + + if ( mgc_request_irq(nIrq, pThis)!=0 ) { + err("request_irq %d failed!", nIrq); + return NULL; + } +#endif + + + +if(udcinitmonitorflag_init==0){ +nomadik_udc_init(udc_address); +} + +#ifdef MUSB_VIRTHUB +#ifdef MUSB_USE_HCD_DRIVER + if ( usb_add_hcd(hcd, pThis->nIrq, pThis->nIrqType)!=0 ) { + DBG(2, "==> Usb_add_hcd failed \n"); + return NULL; + } +#else + if( 0!=mgc_init_bus(pThis, pDevice) ) { + dbg("usb_alloc_bus fail"); + mgc_free_irq(pThis); + return NULL; + } + +#endif +#endif +udcinitmonitorflag_isr=1; +init_timer(¬ify_timer); +notify_timer.expires = jiffies + msecs_to_jiffies(1000); +notify_timer.function = funct_host_notify_timer; +notify_timer.data = (unsigned long)pThis; +add_timer(¬ify_timer); + + return pThis; +} + +static void funct_host_notify_timer(unsigned long uContext) +{ + MGC_LinuxCd *pThis = (MGC_LinuxCd*) uContext; + uint8_t* pBase = (uint8_t*)pThis->pRegs; + uint8_t devctl = 0; + uint8_t power = 0; + + if(MUSB_IS_B_IDLE(pThis)) { + MGC_HdrcReadUlpiReg(pThis, 0x13, &temp); + if (!(temp & 0x10)) + { + MUSB_A_IDLE_MODE(pThis); + if(host_a_idle==0) + { + devctl=MGC_Read8(pBase, MGC_O_HDRC_DEVCTL); + MGC_Write8(pBase, MGC_O_HDRC_DEVCTL, 1); + power=MGC_Read8(pBase, MGC_O_HDRC_POWER); + MGC_Write8(pBase, MGC_O_HDRC_POWER,power &0xBF ); + } + else{ + power=MGC_Read8(pBase, MGC_O_HDRC_POWER); + MGC_Write8(pBase, MGC_O_HDRC_POWER,power &0xBF ); + } + } + mod_timer(¬ify_timer, jiffies + msecs_to_jiffies(1000)); + } + else if (MUSB_IS_A_IDLE(pThis)) { + MGC_HdrcReadUlpiReg(pThis, 0x13, &temp); + if(temp==0x08){ + + devctl=MGC_Read8(pBase, MGC_O_HDRC_DEVCTL); + MGC_Write8(pBase, MGC_O_HDRC_DEVCTL, 1); + } + else + { + MUSB_B_IDLE_MODE(pThis); + devctl=MGC_Read8(pBase, MGC_O_HDRC_DEVCTL); + MGC_Write8(pBase, MGC_O_HDRC_DEVCTL, devctl &0xFE); + power=MGC_Read8(pBase, MGC_O_HDRC_POWER); + MGC_Write8(pBase, MGC_O_HDRC_POWER,power | MGC_M_POWER_SOFTCONN ); + } + mod_timer(¬ify_timer, jiffies + msecs_to_jiffies(1000)); + } + else if (MUSB_IS_DEV(pThis)) { + del_timer(¬ify_timer); + } + else if (MUSB_IS_HST(pThis)) { + + del_timer(¬ify_timer); + } +} + + +void del_timer_func(void) +{ + del_timer(¬ify_timer); +} + +void otg_disconnect(MGC_LinuxCd* pThis) +{ + uint8_t bEnd, devctl = 0; + + devctl &= ~MGC_M_DEVCTL_SESSION; + + MGC_VirtualHubPortDisconnected(&(pThis->RootHub), 0); + + /* flush endpoints */ + for(bEnd = 0; bEnd < pThis->bEndCount; bEnd++) { + MGC_HdrcStopEnd(pThis, bEnd); + } + + mgc_hcd_flush(pThis); + + pThis->pRootDevice = NULL; + + MGC_Write8(pThis->pRegs, MGC_O_HDRC_DEVCTL, devctl); +} + +/* A couple of hooks to enable HSET */ +#ifdef MUSB_CONFIG_PROC_FS +/** + * Set a listener for disconnect interrupts. + * @param pfListener listener, or NULL for none + * @param pParam parameter to pass listener + */ +void MGC_HdrcSetDisconnectListener(MGC_LinuxCd* pCd, + MGC_pfDisconnectListener pfListener, void* pParam) +{ + pCd->pfDisconnectListener = pfListener; + pCd->pDisconnectListenerParam = pParam; +} + +/** + * Set a new handler for the default endpoint interrupt. + * @param pfHandler new handler, or NULL to restore default handler + * @param pParam parameter to pass handler + */ +void MGC_HdrcSetDefaultEndHandler(MGC_LinuxCd* pCd, + MGC_pfDefaultEndHandler pfHandler, void* pParam) +{ + pCd->pfDefaultEndHandler = pfHandler; + pCd->pDefaultEndHandlerParam = pParam; +} +#endif + + + +/* + * Release resources acquired by driver + */ +void MGC_LinuxCdFree(MGC_LinuxCd* pThis) +{ + DBG(2, "<==\n"); + + MGC_HdrcStop(pThis); + MUSB_ERR_MODE(pThis, MUSB_ERR_SHUTDOWN); + +#ifdef MUSB_CONFIG_PROC_FS + MGC_LinuxDeleteProcFs(pThis); +#endif + +#ifdef MUSB_PROC_TESTMUSB + MGC_LinuxDeleteTestProcFs(pThis->aName, pThis); +#endif + +#ifdef MUSB_DMA + if(pThis->pDmaController) { + pThis->pDmaController->pfDmaStopController( + pThis->pDmaController->pPrivateData); + MGC_HdrcDmaControllerFactory.pfDestroyDmaController( + pThis->pDmaController); + } +#endif + + MGC_VirtualHubStop(&pThis->RootHub); + MGC_VirtualHubDestroy(&pThis->RootHub); + +#ifndef MUSB_USE_HCD_DRIVER + if (pThis->pBus->root_hub) { + usb_disconnect(&(pThis->pBus->root_hub)); + } + + WAIT_MS(1); + + if(pThis->nIrq) { + mgc_free_irq(pThis); + } + + mgc_free_bus(pThis->pBus); + KFREE(pThis); +#endif + + DBG(2, "==>\n"); +} + + + +/** + * Initialize the driver. + */ +int MGC_DriverInit(void) +{ + int rc=-ENODEV; + int result; + DBG(2, "<==\n"); + + nomadik_gpio_altfuncenable(GPIO_ALT_USB_OTG,"OTG"); + + /* the driver was already initialized, no need to repeat this */ + if ( MGC_nIndex ) { + DBG(2, "==>\n"); + return 0; + } + + if ( !usb_disabled() ) { + do { + + int direct_bus=-ENODEV; + + direct_bus=direct_bus_init(); + + if ( direct_bus<0 ) { + + ERR("Error initializing controller on the direct bus\n"); + rc=-ENODEV; break; + } + + rc = 0; + + } while (0); + } else { + DBG(2, "USB Disabled , exiting\n"); + } + + result = register_chrdev (MAJOR_NUMBER_OTG, "st-otg", &otg_fops); + + if (result <0){ + + printk (KERN_WARNING "host can't get major %d\n", MAJOR_NUMBER_OTG); + return result; + } + + DBG(2, "==> rc=%d\n", rc); + return rc; +} + +EXPORT_SYMBOL(MGC_DriverInit); + +/** + * release everything... + */ +void MGC_DriverCleanup(void) +{ + int chr = 0; + + DBG(2, "<==\n"); + + if ( MGC_nIndex ) { + + chr = unregister_chrdev (MAJOR_NUMBER_OTG, "st-otg"); + if (chr < 0) + printk (KERN_INFO"OTG Device cannot unregister %d %d\n", MAJOR_NUMBER_OTG, chr); + + usb_remove_hcd(hcd1); + direct_bus_shutdown(); + free_irq(udc_address->nIrq,udc_address); + MGC_LinuxDeleteProcFs(udc_address); + nomadik_gpio_altfuncdisable(GPIO_ALT_USB_OTG, "OTG"); + iounmap(udc_address->pRegs); + del_timer(¬ify_timer); + usb_put_hcd(hcd1); + + } + + MGC_nIndex=0; + DBG(2, "==>\n"); +} +EXPORT_SYMBOL(MGC_DriverCleanup); + +/*-------------------------------------------------------------------------*/ + +/* gstorage is liked to the driver: the init code lives there */ +/* When compiled in the kernel, the init function is needed only when gadget + * gadget API is not compiled (usb_register_driver takes care of the init + * using MGC_DriverInit & MGC_DriverCleanup) + */ +#ifndef MUSB_SKIP_INIT + +/** + * Required initialization for any module. + */ +int __init MGC_ModuleInit (void) +{ + return MGC_DriverInit(); +} + +/** + * Required cleanup for any module + */ +void __exit MGC_ModuleCleanup (void) +{ + + MGC_DriverCleanup(); +} + +module_init(MGC_ModuleInit); +module_exit(MGC_ModuleCleanup); +#endif + --- /dev/null +++ linux-2.6.20/drivers/usb/nomadik/musb_procfs.c @@ -0,0 +1,413 @@ +/* + * linux/drivers/usb/nomadik/musb_procfs.c + * + * Copyright 2007, STMicroelectronics + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include + +#include +#include + +#include +#include "musbdefs.h" +#include "musb_ioctl.h" + +/* ----------------------------------------------------------------------- */ + +#if MUSB_DEBUG > 0 +static int atoi(char* buffer, int base, int len) { + int result=0, digit=0; + + while ( len-->0 && (*buffer) ) { + digit=((*buffer>='0') && (*buffer<='9')) + ? *buffer-'0' + : ((*buffer>='a') && (*buffer<='f')) + ? *buffer-'a' + : -1; + + if ( digit<0 ) { + break; + } + + buffer++; + result=result*base+digit; + } + + return result; +} + +static int atoi_from_user(const char* buffer, int count) { + char digits[8]; + int len=min(count, 8); + copy_from_user(&digits, buffer, len); + return atoi(digits, 10, len); +} + + +static const char* decode_address(int index) { + static const char* COMMON_REGISTER_MAP[] = { + "FAddr", "Power", "IntrTx", "IntrRx", + "IntrTxE", "IntrRxE", "IntrUSB", "IntrUSBE", + "Frame", "Index","TestMode" }; + return (index<11) ? COMMON_REGISTER_MAP[index]:NULL; +} +#endif + +/* ----------------------------------------------------------------------- */ + + +/* Write to ProcFS + * + * C soft-connect + * c soft-disconnect + * I enable HS + * i disable HS + * R resume bus + * S start session (OTG-friendly when OTG-compiled) + * s stop session + * F force session (OTG-unfriendly) + * E rElinquish bus (OTG) + * H request host mode + * h cancel host request + * P disable the low-power mode that kills us in peripheral mode + * D set/query the debug level + * Z zap + */ +static int MGC_ProcWrite(struct file *file, const char *buffer, + unsigned long count, void *data) +{ + char cmd; + uint8_t bReg; + uint8_t* pBase=((MGC_LinuxCd*)data)->pRegs; + + /* MOD_INC_USE_COUNT; */ + + if(copy_from_user(&cmd, buffer, 1) == 0){ + switch(cmd) { + case 'C': + if ( pBase ) { + bReg = MGC_Read8(pBase, MGC_O_HDRC_POWER) | MGC_M_POWER_SOFTCONN; + MGC_Write8(pBase, MGC_O_HDRC_POWER, bReg); + } + break; + + case 'c': + if ( pBase ) { + bReg = MGC_Read8(pBase, MGC_O_HDRC_POWER) & ~MGC_M_POWER_SOFTCONN; + MGC_Write8(pBase, MGC_O_HDRC_POWER, bReg); + } + break; + + case 'I': + if ( pBase ) { + bReg = MGC_Read8(pBase, MGC_O_HDRC_POWER) | MGC_M_POWER_HSENAB; + MGC_Write8(pBase, MGC_O_HDRC_POWER, bReg); + } + break; + + case 'i': + if ( pBase ) { + bReg = MGC_Read8(pBase, MGC_O_HDRC_POWER) & ~MGC_M_POWER_HSENAB; + MGC_Write8(pBase, MGC_O_HDRC_POWER, bReg); + } + break; + + case 'R': + if ( pBase ) { + bReg = MGC_Read8(pBase, MGC_O_HDRC_POWER); + MGC_Write8(pBase, MGC_O_HDRC_POWER, bReg | MGC_M_POWER_RESUME); + WAIT_MS(10); + MGC_Write8(pBase, MGC_O_HDRC_POWER, bReg); + WARN("Power Resumed\n"); + } break; + + case 'S': + MGC_Session((MGC_LinuxCd*)data); + break; + + + case 's': + bReg = MGC_Read8(pBase, MGC_O_HDRC_DEVCTL); + bReg &= ~MGC_M_DEVCTL_SESSION; + MGC_Write8(pBase, MGC_O_HDRC_DEVCTL, bReg); + break; + + case 'F': + bReg = MGC_Read8(pBase, MGC_O_HDRC_DEVCTL); + bReg |= MGC_M_DEVCTL_SESSION; + MGC_Write8(pBase, MGC_O_HDRC_DEVCTL, bReg); + break; + + case 'H': + if ( pBase ) { + bReg = MGC_Read8(pBase, MGC_O_HDRC_DEVCTL); + bReg |= MGC_M_DEVCTL_HR; + MGC_Write8(pBase, MGC_O_HDRC_DEVCTL, bReg); + } + break; + + case 'h': + if ( pBase ) { + bReg = MGC_Read8(pBase, MGC_O_HDRC_DEVCTL); + bReg &= ~MGC_M_DEVCTL_HR; + MGC_Write8(pBase, MGC_O_HDRC_DEVCTL, bReg); + } + break; + + /* Xap the controller */ + case 'Z': + MGC_Zap((MGC_LinuxCd*)data); + break; + +#if (MUSB_DEBUG>0) + /* read & write registers */ + case 'r': + case 'w': { + uint8_t index=0; + uint32_t value=0; + char command[64]; + + memset(command, 0, sizeof(command)); + copy_from_user(command, buffer, min(count, (unsigned long)63)); + + /* detrermine the index, + * only the adrress now */ + index=atoi(&command[2], 16, count-2); + if ( index>0 && pBase ) { + const char *address=decode_address(index); + + if ( buffer[0]=='r' ) { + value=(command[1]=='8') + ? MGC_Read8(pBase, index) + : (command[1]=='f') + ? MGC_Read16(pBase, index) + : 0; + } else { + /* not write, not yet... */ + index=-1; + } + + if ( address ) { + INFO("%s=0x%x\n", address, value); + } else { + INFO("0x%x=0x%x\n", index, value); + } + } + } break; + + /* set/read debug level */ + case 'D': { + if ( count>1 ) { + int level=0; + level=atoi_from_user(&buffer[1], count-1); + MGC_SetDebugLevel(level); + } else { + INFO("MGC_DebugLevel=%d\n", MGC_DebugLevel); + /* & dump the status to syslog */ + } + } break; + + /* display queue status */ + case 'Q': { + int index=-1; + char endb[256]; + MGC_LinuxCd* pThis=(MGC_LinuxCd*)data; + + if (count>2) { + index=atoi_from_user(&buffer[1], count-1); + } + + if ( dump_header_stats(pThis, endb)>0 ) { + printk(KERN_INFO"%s", endb); + } + +#ifdef MUSB_HOST + if( MUSB_IS_HST(pThis) ) { + if ( index<0 ) { + uint8_t bEnd; + + /* generate the report for the end points */ + for (bEnd = 0; bEnd < pThis->bEndCount; bEnd++) { + if ( dump_end_stats(pThis, bEnd, endb)>0 ) { + printk(KERN_INFO"%s", endb); + } + } + + } else { + if ( dump_end_stats(pThis, index, endb)>0 ) { + printk(KERN_INFO"%s", endb); + } + } + } +#endif + + + } break; + + case 'd': { + if ( count>1 ) { + int delay=atoi_from_user(&buffer[1], count-1); + MGC_SetDeviceDelay(delay); + } + INFO("mgc_slow_device_kludge_delay=%d\n", + MGC_SetDeviceDelay(-1)); + } break; + + /* flush */ + case '?': + INFO("?: you are seeing it\n"); + INFO("C/c: soft connect enable/disable\n"); + INFO("I/i: hispeed enable/disable\n"); + INFO("S/s: session set/clear\n"); + INFO("F: \n"); + INFO("H: host mode\n"); + INFO("r/w: read write register\n"); + INFO("Z: zap\n"); + INFO("D: set/read dbug level\n"); + INFO("Q: show queue status\n"); + break; +#endif + + default: + ERR("Command %c not implemented\n", cmd); + break; + } + } + + return count; +} + + +/** + * Read from /proc filesystem. + * @param + * @param + * @param + * @param + * @param + * @param + */ +static int MGC_ProcRead(char *page, char **start, + off_t off, int count, int *eof, void *data) +{ + off_t len=0; + char *buffer; + int rc=0, code=0; + unsigned long flags; + MGC_LinuxCd* pThis=(MGC_LinuxCd*)data; + + spin_lock_irqsave(&pThis->Lock, flags); + + buffer=kmalloc(4*1024, GFP_USER); + if ( !buffer ) { + ERR("Out of memory\n"); + return -1; + } + + /* generate the report for the end points */ + code=dump_header_stats(pThis, buffer); + if ( code>0 ) { + len+=code; + } + +#ifdef MUSB_HOST + if( MUSB_IS_HST(pThis) ) { + + uint8_t bEnd; + + for(bEnd = 0; bEnd < pThis->bEndCount; bEnd++) { + code=dump_end_stats(pThis, bEnd, &buffer[len]); + if ( code>0 ) { + len+=code; + } + } + } +#endif + + if ( offcount ) { + togo=count; + } + + while ( i++Lock, flags); + return rc; +} + + +/** + * TODO: 2.4 and 2.6 create the pseudo-device in 2 different points + * @param data the controller instance + */ +void MGC_LinuxDeleteProcFs(MGC_LinuxCd* data) { + remove_proc_entry(data->pProcEntry->name, NULL); +} + +/** + * TODO: 2.4 and 2.6 create the pseudo-device in 2 different points + * @param data the controller instance + */ +void MGC_LinuxRemoveProcFs(MGC_LinuxCd* data) { + remove_proc_entry(data->pProcEntry->name, NULL); +} + +/** + * TODO: 2.4 and 2.6 create the pseudo-device in 2 different points + * @param name + * @param data the controller instance + */ +struct proc_dir_entry* MGC_LinuxCreateProcFs(char *name, MGC_LinuxCd* data) { + if ( !name ) { + name=data->aName; + } + + data->pProcEntry=create_proc_entry(name, + S_IFREG | S_IRUGO | S_IWUSR, NULL); + if( data->pProcEntry ) + { + data->pProcEntry->data = data; +#ifdef MUSB_V26 + data->pProcEntry->owner=THIS_MODULE; +#endif + + data->pProcEntry->read_proc = MGC_ProcRead; + data->pProcEntry->write_proc = MGC_ProcWrite; + + data->pProcEntry->size = 0; + + dbg("Registered /proc/%s\n", name); + } else { + dbg ("Cannot create a valid proc file entry"); + } + + return data->pProcEntry; +} + --- /dev/null +++ linux-2.6.20/drivers/usb/nomadik/musb_virthub.c @@ -0,0 +1,840 @@ +/* + * linux/drivers/usb/nomadik/musb_virthub.c + * + * Copyright 2007, STMicroelectronics + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +//#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#ifndef MUSB_LINUX_MV21 +#include "../core/hcd.h" +#define HAS_USB_TT_MULTI +#else +#include +#endif + +#include "musbdefs.h" + +/******************************* FORWARDS ********************************/ + +static void MGC_VirtualHubActivateTimer(MGC_VirtualHub* pHub, + void (*pfExpired)(unsigned long), unsigned long timeout); +static void MGC_VirtualHubCompleteIrq(MGC_VirtualHub* pHub, struct urb* pUrb); +static void MGC_VirtualHubTimerExpired(unsigned long ptr); + +/******************************* GLOBALS *********************************/ + +/** device descriptor */ +static uint8_t MGC_aVirtualHubDeviceDesc[] = +{ + USB_DT_DEVICE_SIZE, + USB_DT_DEVICE, + 0x00, 0x02, /* bcdUSB */ + USB_CLASS_HUB, /* bDeviceClass */ + 0, /* bDeviceSubClass */ + 1, /* bDeviceProtocol (single TT) */ + 64, /* bMaxPacketSize0 */ + 0xd6, 0x4, /* idVendor */ + 0, 0, /* idProduct */ + 0, 0, /* bcdDevice */ + 0, /* iManufacturer */ + 0, /* iProduct */ + 0, /* iSerialNumber */ + 1 /* bNumConfigurations */ +}; + +/** device qualifier */ +static uint8_t MGC_aVirtualHubQualifierDesc[] = +{ + USB_DT_DEVICE_QUALIFIER_SIZE, + USB_DT_DEVICE_QUALIFIER, + 0x00, 0x02, /* bcdUSB */ + USB_CLASS_HUB, /* bDeviceClass */ + 0, /* bDeviceSubClass */ + 0, /* bDeviceProtocol */ + 64, /* bMaxPacketSize0 */ + 0xd6, 0x4, /* idVendor */ + 0, 0, /* idProduct */ + 0, 0, /* bcdDevice */ + 0, /* iManufacturer */ + 0, /* iProduct */ + 0, /* iSerialNumber */ + 1 /* bNumConfigurations */ +}; + +/** Configuration descriptor */ +static uint8_t MGC_VirtualHubConfigDesc[] = +{ + USB_DT_CONFIG_SIZE, + USB_DT_CONFIG, + USB_DT_CONFIG_SIZE + USB_DT_INTERFACE_SIZE + USB_DT_ENDPOINT_SIZE, 0, + 0x01, /* bNumInterfaces */ + 0x01, /* bConfigurationValue */ + 0x00, /* iConfiguration */ + 0xE0, /* bmAttributes (self-powered, remote wake) */ + 0x00, /* MaxPower */ + + /* interface */ + USB_DT_INTERFACE_SIZE, + USB_DT_INTERFACE, + 0x00, /* bInterfaceNumber */ + 0x00, /* bAlternateSetting */ + 0x01, /* bNumEndpoints */ + USB_CLASS_HUB, /* bInterfaceClass */ + 0x00, /* bInterfaceSubClass */ + 0x00, /* bInterfaceProtocol */ + 0x00, /* iInterface */ + + /* endpoint */ + USB_DT_ENDPOINT_SIZE, + USB_DT_ENDPOINT, + USB_DIR_IN | 1, /* bEndpointAddress: IN Endpoint 1 */ + USB_ENDPOINT_XFER_INT, /* bmAttributes: Interrupt */ + (MGC_VIRTUALHUB_MAX_PORTS + 8) / 8, 0, /* wMaxPacketSize */ + 12 /* bInterval: 256 ms */ +}; + +/** other-speed Configuration descriptor */ +static uint8_t MGC_VirtualHubOtherConfigDesc[] = +{ + USB_DT_CONFIG_SIZE, + USB_DT_OTHER_SPEED, + USB_DT_CONFIG_SIZE + USB_DT_INTERFACE_SIZE + USB_DT_ENDPOINT_SIZE, 0, + 0x01, /* bNumInterfaces */ + 0x01, /* bConfigurationValue */ + 0x00, /* iConfiguration */ + 0xE0, /* bmAttributes (self-powered, remote wake) */ + 0x00, /* MaxPower */ + + /* interface */ + USB_DT_INTERFACE_SIZE, + USB_DT_INTERFACE, + 0x00, /* bInterfaceNumber */ + 0x00, /* bAlternateSetting */ + 0x01, /* bNumEndpoints */ + USB_CLASS_HUB, /* bInterfaceClass */ + 0x00, /* bInterfaceSubClass */ + 0x00, /* bInterfaceProtocol */ + 0x00, /* iInterface */ + + /* endpoint */ + USB_DT_ENDPOINT_SIZE, + USB_DT_ENDPOINT, + USB_DIR_IN | 1, /* bEndpointAddress: IN Endpoint 1 */ + USB_ENDPOINT_XFER_INT, /* bmAttributes: Interrupt */ + (MGC_VIRTUALHUB_MAX_PORTS + 8) / 8, 0, /* wMaxPacketSize */ + 0xff /* bInterval: 255 ms */ +}; + +/****************************** FUNCTIONS ********************************/ + +/** + * Generic timer activation helper. Requires the hub structure to + * be locked. + * + * @param pHub pointer to hub struct + * @param pfExpired callback function + * @param timeout millisecs + * @requires spin_lock(pHub->Lock) + */ +static void MGC_VirtualHubActivateTimer(MGC_VirtualHub* pHub, + void (*pfExpired)(unsigned long), unsigned long timeout) +{ + DBG(2, "<== pHub=%p, pHub->pUrb=%p\n", pHub, pHub->pUrb); + del_timer(&pHub->Timer); /* make sure another timer is not running */ + init_timer(&(pHub->Timer)); + pHub->Timer.function = pfExpired; + pHub->Timer.data = (unsigned long)pHub; + pHub->Timer.expires = jiffies + timeout * HZ / 1000; + add_timer( &(pHub->Timer) ); +} + +/** + * Report the VHUB status bits. Assumes that pData has enough + * storage for all of them. + * @param pHub the hub + * @param pData the data buffer status shoudl be written to + * @return + */ +int mgc_rh_port_status(MGC_VirtualHub* pHub, uint8_t* pData) { + int nPort, length=1; + uint8_t bData=0, bBit=1; + + /* count 1..N to accomodate hub status bit */ + for(nPort = 1; nPort <= pHub->bPortCount + 1; nPort++) { + if(pHub->aPortStatusChange[nPort-1].wChange & 1) { + bData |= 1 << bBit; + } + + if(++bBit > 7) { + *pData++ = bData; + bData = bBit = 0; + length++; + } + } + + if(bBit) { + *pData++ = bData; + } + + return length; +} + +/* + * assumes pHub to be locked! + * @requires spin_lock(pHub->Lock) + */ +static void MGC_VirtualHubCompleteIrq(MGC_VirtualHub* pHub, struct urb* pUrb) +{ + pHub->bIsChanged = FALSE; + + pUrb->actual_length=mgc_rh_port_status(pHub, (uint8_t*)pUrb->transfer_buffer); + if (pUrb->actual_length && pUrb->complete) { + COMPLETE_URB(pUrb, NULL); + } +} + +/** + * Timer expiration function to complete the interrupt URB on changes + * @param ptr standard expiration param (hub pointer) + */ +static void MGC_VirtualHubTimerExpired(unsigned long ptr) +{ + struct urb* pUrb; + MGC_VirtualHub* pHub = (MGC_VirtualHub*)ptr; + + DBG(2, "<== pHub=%p, pHub->pUrb=%p, pUrb->hcpriv=%p\n", pHub, + pHub->pUrb, (pHub->pUrb)?((struct urb*)pHub->pUrb)->hcpriv:NULL); + + spin_lock(&pHub->Lock); + pUrb=pHub->pUrb; + if(pUrb && (pUrb->hcpriv == pHub)) { + uint8_t bPort; + + for(bPort = 0; bPort < pHub->bPortCount; bPort++) { + if ( pHub->aPortStatusChange[bPort].wChange ) { + pUrb->status=0; + MGC_VirtualHubCompleteIrq(pHub, pUrb); + break; + } + } + + /* re-activate timer only when the urb is still mine; pUrb->hcpriv is + * set to NULL on port disconnect */ + MGC_VirtualHubActivateTimer(pHub, MGC_VirtualHubTimerExpired, + pHub->wInterval); + } else { + DBG(3, "pUrb=%p, for me =%d\n", pUrb, (pUrb)?((pUrb->hcpriv)?1:0):-1 ); + } + spin_unlock(&pHub->Lock); +} + +/** + * Initialize the virtual hub. + * @param pHub + * @param pBus + * @param bPortCount + * @param pPortServices + * @return 0 success, <0 when errror + */ +int MGC_VirtualHubInit(MGC_VirtualHub* pHub, struct usb_bus* pBus, + uint8_t bPortCount, MGC_PortServices* pPortServices) +{ + uint8_t bPort; + + if(bPortCount > MGC_VIRTUALHUB_MAX_PORTS) { + ERR("Cannot allocate a %d-port device (too many ports)", bPortCount); + return -EINVAL; + } + +#if defined(MUSB_REGISTER_ROOT_HUB) || !defined(MUSB_USE_HCD_DRIVER) + /* allocate device, the hcd driver allocate */ + pHub->pDevice=USB_ALLOC_DEV(NULL, pBus, 0); + if(!pHub->pDevice) { + ERR("Cannot allocate a %d-port device", bPortCount); + return -ENODEV; + } + + pHub->pDevice->speed=USB_SPEED_HIGH; +#endif + + DBG(3, "New device (%d-port virtual hub) @%#lx allocated\n", \ + bPortCount, (unsigned long)pHub->pDevice); + + pHub->pBus = pBus; + + spin_lock_init(&pHub->Lock); + pHub->pUrb = NULL; + pHub->pPortServices = pPortServices; + pHub->bPortCount = bPortCount; + pHub->bIsChanged = FALSE; + init_timer(&(pHub->Timer)); /* I will need this later */ + + for(bPort = 0; bPort < bPortCount; bPort++) { + pHub->aPortStatusChange[bPort].wStatus = 0; + pHub->aPortStatusChange[bPort].wChange = 0; + } + +#ifdef MUSB_V24 + usb_connect(pHub->pDevice); +#endif + + return 0; /* OK */ +} + +/** + * Destroy a virtual hub + * @param pHub the vhub to destroy + */ +void MGC_VirtualHubDestroy(MGC_VirtualHub* pHub) +{ +#ifdef MUSB_USE_HCD_DRIVER + ERR("** you shoudl not call %s when using the HCD driver\n", __FUNCTION__); +#endif +} + +/** + * Start a virtual hub. Set the address and create a new device for it. + * @param pHub the vhub to start. + */ +void MGC_VirtualHubStart(MGC_VirtualHub* pHub) +{ + DBG(2, "<== announcing pHub=%p to usbcore\n", pHub); + pHub->bAddress=1; + +#ifdef MUSB_REGISTER_ROOT_HUB +#ifndef MUSB_USE_HCD_DRIVER + if ( USB_NEW_DEVICE(pHub) ) { + ERR("usb_new_device failed\n"); + } +#endif +#endif + + DBG(2, "==>\n"); +} + +/** + * Stop a virtual hub. + * @param pHub the vhub to stop + */ +void MGC_VirtualHubStop(MGC_VirtualHub* pHub) +{ +#ifndef MUSB_USE_HCD_DRIVER + /* stop interrupt timer */ + del_timer_sync(&pHub->Timer); +#endif +} + +/** Submit an URB to the virtual hub. + * bRequest: + * 00 + * 01 + * 03 + * + * bmRequestType: + * 0x23 + * 0xa3 + * + * @param pHub the hub urb should be submitted to + * @param pUrb the urb to submit + */ +int MGC_VirtualHubSubmitUrb(MGC_VirtualHub* pHub, struct urb* pUrb) +{ + uint8_t bRecip; /* from standard request */ + uint8_t bReqType; /* from standard request */ + uint8_t bType; /* requested descriptor type */ + uint16_t wValue; /* from standard request */ + uint16_t wIndex; /* from standard request */ + uint16_t wLength; /* from standard request */ + uint8_t bPort; + const MUSB_DeviceRequest* pRequest; + uint16_t wSize = 0xffff; + uint8_t* pData = (uint8_t*)pUrb->transfer_buffer; + unsigned int pipe = pUrb->pipe; + + DBG(-1, "<== pUrb=%p\n", pUrb); + +#ifdef MUSB_USE_HCD_DRIVER + ERR("** you shoudl not call %s when using the HCD driver\n", __FUNCTION__); +#endif + + spin_lock(&pHub->Lock); + usb_get_urb(pUrb); + + pUrb->hcpriv = pHub; + pUrb->status = -EINPROGRESS; + + if ( usb_pipeint(pipe) ) { + DBG(-1, "pUrb=%p is periodic status/change event\n", pUrb ); + + /* this is the one for periodic status/change events */ + pHub->pUrb = pUrb; + pHub->wInterval = (pUrb->interval < 16) ? (1 << (pUrb->interval - 1)) : + pUrb->interval; + spin_unlock(&pHub->Lock); + return 0; + } + + /* handle hub requests/commands */ + pRequest = (const MUSB_DeviceRequest*)pUrb->setup_packet; + bReqType = pRequest->bmRequestType & USB_TYPE_MASK; + bRecip = pRequest->bmRequestType & USB_RECIP_MASK; + wValue = le16_to_cpu(pRequest->wValue); + wIndex = le16_to_cpu(pRequest->wIndex); + wLength = le16_to_cpu(pRequest->wLength); + + DBG(3, "pRequest->bRequest=%02x, pRequest->bmRequestType=%02x, wLength=%04x\n", + pRequest->bRequest, pRequest->bmRequestType, wLength); + + switch (pRequest->bRequest) { + case USB_REQ_GET_STATUS: + DBG(3, "GET_STATUS(), bType=%02x, bRecip=%02x, wIndex=%04x\n", \ + bReqType, bRecip, wIndex); + + if(USB_TYPE_STANDARD == bReqType) { + /* self-powered */ + pData[0] = (USB_RECIP_DEVICE == bRecip) ? 1 : 0; + pData[1] = 0; + wSize = 2; + } else if(USB_TYPE_CLASS == bReqType) { + if((USB_RECIP_OTHER == bRecip) && (wIndex <= pHub->bPortCount)) { + /* port status/change report */ + memcpy(pData, &(pHub->aPortStatusChange[wIndex-1].wStatus), 2); + memcpy(&(pData[2]), &(pHub->aPortStatusChange[wIndex-1].wChange), + 2); + + /* reset change (TODO: lock) */ + pHub->aPortStatusChange[wIndex-1].wChange = 0; + wSize = 4; + } else { + /* hub status */ + memset(pData, 0, 4); + wSize = 4; + } + + DBG(2, "status report=%02x%02x%02x%02x\n", \ + pData[0], pData[1], pData[2], pData[3]); + } + break; + + case USB_REQ_CLEAR_FEATURE: + bPort = (uint8_t)(wIndex & 0xff) - 1; + DBG(3, "CLR_FEAT bReqType=0x%x, wValue=0x%x, wIndex=0x%x\n", + bReqType, wValue, (wIndex & 0xff) ); + if((USB_TYPE_STANDARD == bReqType) && (USB_RECIP_ENDPOINT == bRecip)) + { + wSize = 0; + DBG(3, "END POINT FEATURE!\n"); + } else if(USB_TYPE_CLASS == bReqType) { + + if(USB_RECIP_OTHER == bRecip) + { + bPort = (uint8_t)(wIndex & 0xff) - 1; + DBG(3, "CLEAR_PORT_FEATURE(%d), port %d\n", \ + wValue, bPort); + switch(wValue) { + case USB_PORT_FEAT_CONNECTION: + case USB_PORT_FEAT_OVER_CURRENT: + case USB_PORT_FEAT_POWER: + case USB_PORT_FEAT_LOWSPEED: + case USB_PORT_FEAT_HIGHSPEED: + case USB_PORT_FEAT_TEST: + case USB_PORT_FEAT_INDICATOR: + DBG(3, "feat 0x%02x, wIndex=%d\n", wValue, bPort); + wSize = 0; + break; + case USB_PORT_FEAT_ENABLE: + DBG(4, "enable port %d\n", bPort); + pHub->pPortServices->pfSetPortEnable( + pHub->pPortServices->pPrivateData, bPort, FALSE); + wSize = 0; + break; + case USB_PORT_FEAT_SUSPEND: + DBG(3, "suspend port %d\n", bPort); + pHub->pPortServices->pfSetPortSuspend( + pHub->pPortServices->pPrivateData, bPort, FALSE); + wSize = 0; + break; + case USB_PORT_FEAT_RESET: + DBG(4, "reset port %d\n", bPort); + pHub->pPortServices->pfSetPortReset( + pHub->pPortServices->pPrivateData, bPort, FALSE); + wSize = 0; + break; + + /* acknowledge changes: */ + case USB_PORT_FEAT_C_CONNECTION: + DBG(3, "ack connection port %d\n", bPort); + pHub->aPortStatusChange[bPort].wChange &= ~1; + wSize = 0; + break; + case USB_PORT_FEAT_C_ENABLE: + DBG(3, "ack enable port %d\n", bPort); + pHub->aPortStatusChange[bPort].wChange &= ~USB_PORT_STAT_ENABLE; + wSize = 0; + break; + case USB_PORT_FEAT_C_SUSPEND: + DBG(3, "ack suspend port %d\n", bPort); + + pHub->aPortStatusChange[bPort].wChange &= ~USB_PORT_STAT_SUSPEND; + wSize = 0; + break; + case USB_PORT_FEAT_C_RESET: + DBG(3, "ack reset port %d\n", bPort); + pHub->aPortStatusChange[bPort].wChange &= ~USB_PORT_STAT_RESET; + wSize = 0; + break; + case USB_PORT_FEAT_C_OVER_CURRENT: + DBG(3, "ack over current port %d\n", bPort); + wSize = 0; + break; + + default: + INFO("clear feature 0x%02x on port=%d unknown\n", wValue, bPort); + break; + } + } else { + DBG(3, "clear wValue=%d on port=%d\n", wValue, bPort); + switch(wValue) { + case C_HUB_LOCAL_POWER: + case C_HUB_OVER_CURRENT: + wSize = 0; + break; + } + } + pHub->bIsChanged = TRUE; + } + break; + + case USB_REQ_SET_FEATURE: + if((USB_TYPE_CLASS == bReqType) && (USB_RECIP_OTHER == bRecip)) + { + bPort = (uint8_t)(wIndex & 0xff) - 1; + DBG(3, "SET_PORT_FEATURE(0x%02x), port %d\n", wValue, bPort); + switch(wValue) { + case USB_PORT_FEAT_SUSPEND: + DBG(3, "suspend port %d\n", bPort); + pHub->pPortServices->pfSetPortSuspend( + pHub->pPortServices->pPrivateData, bPort, TRUE); + pHub->aPortStatusChange[bPort].wStatus |= USB_PORT_STAT_SUSPEND; + pHub->bIsChanged = TRUE; + wSize = 0; + break; + + case USB_PORT_FEAT_RESET: + DBG(3, "reset port %d\n", bPort); + pHub->aPortStatusChange[bPort].wStatus |= USB_PORT_STAT_RESET; + pHub->aPortStatusChange[bPort].wStatus |= USB_PORT_STAT_ENABLE; + pHub->aPortStatusChange[bPort].wChange |= USB_PORT_STAT_RESET; + pHub->bIsChanged = TRUE; + pHub->pPortServices->pfSetPortReset(pHub->pPortServices->pPrivateData, + bPort, TRUE); + wSize = 0; + break; + + case USB_PORT_FEAT_POWER: + DBG(3, "power port %d\n", bPort); + pHub->pPortServices->pfSetPortPower(pHub->pPortServices->pPrivateData, + bPort, TRUE); + pHub->aPortStatusChange[bPort].wStatus |= USB_PORT_STAT_POWER; + wSize = 0; + break; + + case USB_PORT_FEAT_ENABLE: + DBG(3, "enable port %d\n", bPort); + pHub->pPortServices->pfSetPortEnable(pHub->pPortServices->pPrivateData, + bPort, TRUE); + pHub->aPortStatusChange[bPort].wStatus |= USB_PORT_STAT_ENABLE; + wSize = 0; + break; + } + } else { + DBG(3, "SET_FEATURE(%04x), but feature unknown\n", wValue); + } + break; + + case USB_REQ_SET_ADDRESS: + pHub->bAddress = (wValue & 0x7f); + DBG(3, "SET_ADDRESS(%x) \n", pHub->bAddress); + wSize = 0; + break; + + case USB_REQ_GET_DESCRIPTOR: + if(USB_TYPE_CLASS == bReqType) { + DBG(3, "GET_CLASS_DESCRIPTOR()\n"); + + pData[0] = 9; + pData[1] = 0x29; + pData[2] = pHub->bPortCount; + /* min characteristics */ + pData[3] = 1; /* invidual port power switching */ + pData[4] = 0; + /* PowerOn2PowerGood */ + pData[5] = 50; + /* no current */ + pData[6] = 0; + /* removable ports */ + pData[7] = 0; + /* reserved */ + pData[8] = 0xff; + wSize = pData[0]; + } else { + bType = (uint8_t)(wValue >> 8); + DBG(3, "GET_DESCRIPTOR(%d)\n", bType); + switch(bType) { + case USB_DT_DEVICE: /* 1 */ + wSize = min(wLength, (uint16_t)MGC_aVirtualHubDeviceDesc[0]); + memcpy(pData, MGC_aVirtualHubDeviceDesc, wSize); + break; + case USB_DT_DEVICE_QUALIFIER: + wSize = min(wLength, (uint16_t)MGC_aVirtualHubQualifierDesc[0]); + memcpy(pData, MGC_aVirtualHubQualifierDesc, wSize); + break; + case USB_DT_CONFIG: /* 2 */ + wSize = min(wLength, (uint16_t)MGC_VirtualHubConfigDesc[2]); + memcpy(pData, MGC_VirtualHubConfigDesc, wSize); + break; + case USB_DT_OTHER_SPEED: + wSize = min(wLength, (uint16_t)MGC_VirtualHubOtherConfigDesc[2]); + memcpy(pData, MGC_VirtualHubOtherConfigDesc, wSize); + break; + } + } + break; + + case USB_REQ_GET_CONFIGURATION: + DBG(3, "GET_CONFIG() => 1\n"); + pData[0] = 1; + wSize = 1; + break; + + case USB_REQ_SET_CONFIGURATION: + DBG(3, "SET_CONFIG(%04x)\n", wValue); + wSize = 0; + break; + + } /* END: switch on request type */ + + if(0xffff == wSize) { + pUrb->status = USB_ST_STALL; + } else { + pUrb->actual_length = wSize; + pUrb->status = 0; + } + + spin_unlock(&pHub->Lock); + if (pUrb->complete) { + DBG(3, "completing URB status=%d\n", pUrb->status ); + COMPLETE_URB(pUrb, NULL); + pUrb->hcpriv = NULL; + usb_put_urb(pUrb); + DBG(4, "URB completed\n"); + } + + DBG(2, "==> pUrb->status=%d %s, length=%d, completed=%s\n", pUrb->status, \ + (pUrb->status)?"(STALL)":"", pUrb->actual_length, + (pUrb->complete)?"yes":"no"); + + return 0; +} + +/** + * Unlink an URB from a virtual hub. + * @param pHub pointer to hub initialized by successful MGC_VirtualHubInit + * @param pUrb URB pointer + * @return Linux status code + * @see #MGC_VirtualHubInit + */ +int MGC_VirtualHubUnlinkUrb(MGC_VirtualHub* pHub, struct urb* pUrb) +{ + DBG(2, "<== pUrb=%p\n", pUrb); + +#ifdef MUSB_USE_HCD_DRIVER + ERR("** you shoudl not call %s when using the HCD driver\n", __FUNCTION__); +#endif + + spin_lock(&pHub->Lock); + if(pUrb && (pHub->pUrb == pUrb) && (pUrb->hcpriv == pHub)) { + pHub->bIsChanged = FALSE; + + if (pUrb->transfer_flags & USB_ASYNC_UNLINK) { + pUrb->status = -ECONNRESET; + if (pUrb->complete) { + COMPLETE_URB(pUrb, NULL); + } + } else { + pUrb->status = -ENOENT; + } + + pUrb->hcpriv = NULL; + pHub->pUrb = NULL; + } + + spin_unlock(&pHub->Lock); + usb_put_urb(pUrb); + + DBG(2, "==>\n"); + return 0; +} + + +/** + * assumes bPortIndex < MGC_VIRTUALHUB_MAX_PORTS + * AND pHub->Lock to be... locked :) + */ +STATIC void MGC_SetVirtualHubPortSpeed(MGC_VirtualHub* pHub, + uint8_t bPortIndex, uint8_t bSpeed +) { + uint16_t wSpeedMask = 0; + + DBG(2, "<== bPortIndex=%d, bSpeed=%d\n", bPortIndex, bSpeed); + + switch(bSpeed) { + case 0: + wSpeedMask = USB_PORT_STAT_LOW_SPEED; + break; + case 2: + wSpeedMask = USB_PORT_STAT_HIGH_SPEED; + break; + } + + pHub->aPortStatusChange[bPortIndex].wStatus &= + ~(USB_PORT_STAT_LOW_SPEED | USB_PORT_STAT_HIGH_SPEED); + pHub->aPortStatusChange[bPortIndex].wStatus |= 1 | wSpeedMask; + pHub->bIsChanged = TRUE; + DBG(2, "==>\n"); +} + +/** + * A port reset is complete + * @param pHub pointer to hub initialized by successful MGC_VirtualHubInit + * @param bPortIndex 0-based index of port + * @see #MGC_VirtualHubInit + */ +void MGC_VirtualHubPortResetDone(MGC_VirtualHub* pHub, uint8_t bPortIndex, + uint8_t bHubSpeed) +{ + DBG(2, "<==port %d reset complete\n", bPortIndex); + + if(bPortIndex < MGC_VIRTUALHUB_MAX_PORTS) { + MGC_SetVirtualHubPortSpeed(pHub, bPortIndex, bHubSpeed); + + pHub->aPortStatusChange[bPortIndex].wStatus &= ~USB_PORT_STAT_RESET; + pHub->aPortStatusChange[bPortIndex].wStatus |= USB_PORT_STAT_ENABLE; + pHub->aPortStatusChange[bPortIndex].wChange = USB_PORT_STAT_RESET | + USB_PORT_STAT_ENABLE; + pHub->bIsChanged = TRUE; + } + DBG(2, "==>\n"); +} + +/** + * A device has effectively been connected to a virtual hub port + * @param pHub pointer to hub initialized by successful MGC_VirtualHubInit + * @param bPortIndex 0-based index of port with connected device + * @param bSpeed device speed (0=>low, 1=>full, 2=>high) + * @see #MGC_VirtualHubInit + */ +void MGC_VirtualHubPortConnected(MGC_VirtualHub* pHub, uint8_t bPortIndex, + uint8_t bSpeed) +{ + DBG(2, "<== port %d connected, core reports speed=%d\n", bPortIndex, bSpeed); + if (bPortIndex < MGC_VIRTUALHUB_MAX_PORTS) { + struct urb* pUrb=pHub->pUrb; + + MGC_SetVirtualHubPortSpeed(pHub, bPortIndex, bSpeed); + pHub->aPortStatusChange[bPortIndex].wChange |= 1; + + /* shorter time... it want it NOW! */ + DBG(2, "<== pHub=%p, pHub->pUrb=%p, pHub->pUrb->hcpriv=%p\n", pHub, + pUrb, (pUrb)?pUrb->hcpriv:NULL); + if ( pUrb && ( (!pUrb->hcpriv) || (pUrb->hcpriv== pHub))) { + pUrb->hcpriv=pHub; + MGC_VirtualHubActivateTimer(pHub, MGC_VirtualHubTimerExpired, 1); + } + } + DBG(2, "==>\n"); +} + +/** + * A device has effectively been disconnected from a virtual hub port + * @param pHub pointer to hub initialized by successful MGC_VirtualHubInit + * @param bPortIndex 0-based index of port of disconnected device + * @see #MGC_VirtualHubInit + */ +void MGC_VirtualHubPortDisconnected(MGC_VirtualHub* pHub, uint8_t bPortIndex) +{ + struct urb* pUrb; + + DBG(-1, "<== Port %d disconnected\n", bPortIndex); + + if(bPortIndex >= MGC_VIRTUALHUB_MAX_PORTS) { + DBG(-1, "==>"); + return; + } + +#ifndef MUSB_USE_HCD_DRIVER + del_timer_sync(&pHub->Timer); +#endif + + pUrb= pHub->pUrb; + pHub->aPortStatusChange[bPortIndex].wStatus &= ~1; + pHub->aPortStatusChange[bPortIndex].wChange |= 1; + pHub->bIsChanged = TRUE; + + if (pUrb && (pUrb->hcpriv == pHub)) { + pUrb->status=0; + MGC_VirtualHubCompleteIrq(pHub, pUrb); + } + + DBG(-1, "==>\n"); +} + +/** + * A device has effectively resumed a virtual hub port + * @param pHub pointer to hub initialized by successful MGC_VirtualHubInit + * @param bPortIndex 0-based index of port of resume + * @see #MGC_VirtualHubInit + */ +void MGC_VirtualHubPortResumed(MGC_VirtualHub* pHub, uint8_t bPortIndex) +{ + DBG(2, "<== Resume port %d\n", bPortIndex); +#ifdef MUSB_USE_HCD_DRIVER + ERR("** you shoudl not call %s when using the HCD driver\n", __FUNCTION__); +#endif + + if(bPortIndex >= MGC_VIRTUALHUB_MAX_PORTS) { + return; + } + + pHub->aPortStatusChange[bPortIndex].wStatus &= ~USB_PORT_STAT_SUSPEND; + pHub->aPortStatusChange[bPortIndex].wChange |= USB_PORT_STAT_SUSPEND; + pHub->bIsChanged = TRUE; + DBG(2, "==>\n"); +} --- /dev/null +++ linux-2.6.20/drivers/usb/nomadik/musb_virthub.h @@ -0,0 +1,240 @@ +/* + * linux/drivers/usb/nomadik/musb_virthub.h + * + * Copyright 2007, STMicroelectronics + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __MUSB_LINUX_VIRTUALHUB_H__ +#define __MUSB_LINUX_VIRTUALHUB_H__ + +#include +#include +#include + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,4) +#define USB_NEW_DEVICE(_vh) usb_register_root_hub((_vh)->pDevice, (_vh)->pBus->controller) +#else +#ifdef __bluecat__ +#define USB_NEW_DEVICE(_vh) usb_new_device((_vh)->pDevice, (((_vh)->pDevice)->parent)?&((_vh)->pDevice)->parent->dev:NULL ) +#else +#define USB_NEW_DEVICE(_vh) usb_new_device((_vh)->pDevice) +#endif +#endif + +#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,12) +#define MUSB_REGISTER_ROOT_HUB +#endif + +struct urb; +struct usb_bus; + +#ifdef MUSB_USE_HCD_DRIVER +struct usb_hcd; +#endif + +/** + * Introduction. + * For USB controllers lacking embedded root hubs, + * this module can be used as a virtual root hub, + * with one or more controllers as the virtual hub's ports. + */ + +/****************************** CONSTANTS ********************************/ + +/** Maximum number of ports to accomodate */ +#define MGC_VIRTUALHUB_MAX_PORTS 7 + +/******************************** TYPES **********************************/ + +/** + * Set a port's power on or off. + * @param pPrivateData pPrivateData from port services + * @param bPortIndex 0-based index of port + * @param bPower TRUE to power on the port; FALSE to power off + */ +typedef void (*MGC_pfSetPortPower)(void* pPrivateData, uint8_t bPortIndex, + uint8_t bPower); + +/** + * Enable or disable a port. + * @param pPrivateData pPrivateData from port services + * @param bPortIndex 0-based index of port + * @param bEnable TRUE to enable port; FALSE to disable + */ +typedef void (*MGC_pfSetPortEnable)(void* pPrivateData, uint8_t bPortIndex, + uint8_t bEnable); + +/** + * Set a port's suspend mode on or off. + * @param pPrivateData pPrivateData from port services + * @param bPortIndex 0-based index of port + * @param bSuspend TRUE to suspend port; FALSE to resume + */ +typedef void (*MGC_pfSetPortSuspend)(void* pPrivateData, uint8_t bPortIndex, + uint8_t bSuspend); + +/** + * Set a port's reset on or off. + * @param pPrivateData pPrivateData from port services + * @param bPortIndex 0-based index of port + * @param bReset TRUE to assert reset on the bus behind a port; FALSE to deassert + */ +typedef void (*MGC_pfSetPortReset)(void* pPrivateData, uint8_t bPortIndex, + uint8_t bReset); + +/** + * MGC_PortServices. + * Services provided to a virtual by a USB port controller. + * @field pPrivateData port controller's implementation data; + * not to be interpreted by virtual hub + * @param pfSetPortPower set-port-power call + * @param pfSetPortEnable set-port-enable call + * @param pfSetPortSuspend set-port-suspend call + * @param pfSetPortReset set-port-reset call + */ +typedef struct +{ + void* pPrivateData; + MGC_pfSetPortPower pfSetPortPower; + MGC_pfSetPortEnable pfSetPortEnable; + MGC_pfSetPortSuspend pfSetPortSuspend; + MGC_pfSetPortReset pfSetPortReset; +} MGC_PortServices; + +/** + * MGC_HubPortStatusChange. + * @field wStatus status + * @field wChange change + */ +typedef struct +{ + uint16_t wStatus; + uint16_t wChange; +} MGC_HubPortStatusChange; + +/** + * MGC_VirtualHub. + * Virtual USB hub instance data. + * @field Lock spinlock + * @field pBus our bus pointer + * @field pDevice our device pointer + * @field pUrb pointer to interrupt URB for status change + * @field pPortServices pointer to port services + * @field Timer interval timer for status change interrupts + * @field aPortStatusChange status/change array + * @field bPortCount how many ports + * @field wInterval actual interval in milliseconds + * @field bIsChanged TRUE if changes to report + * @field bAddress address assigned by usbcore + */ +typedef struct +{ + spinlock_t Lock; + struct usb_bus* pBus; + struct usb_device* pDevice; + + void *pUrb; + MGC_PortServices* pPortServices; + struct timer_list Timer; + MGC_HubPortStatusChange aPortStatusChange[MGC_VIRTUALHUB_MAX_PORTS]; + uint8_t bPortCount; + uint16_t wInterval; + uint8_t bIsChanged; + uint8_t bAddress; + +} MGC_VirtualHub; + +/******************************** Protos **********************************/ + +extern int mgc_rh_port_status(MGC_VirtualHub* pHub, uint8_t* pData); + +#ifdef MUSB_VIRTHUB +void MGC_LinuxSetPortPower(void* pPrivateData, uint8_t bPortIndex, + uint8_t bPower); +void MGC_LinuxSetPortEnable(void* pPrivateData, uint8_t bPortIndex, + uint8_t bEnable); +void MGC_LinuxSetPortSuspend(void* pPrivateData, uint8_t bPortIndex, + uint8_t bSuspend); +void MGC_LinuxSetPortReset(void* pPrivateData, uint8_t bPortIndex, + uint8_t bReset); + +extern int MGC_VirtualHubInit(MGC_VirtualHub* pHub, struct usb_bus* pBus, + uint8_t bPortCount, MGC_PortServices* pPortServices); +extern void MGC_VirtualHubDestroy(MGC_VirtualHub* pHub); +extern void MGC_VirtualHubStart(MGC_VirtualHub* pHub); +extern void MGC_VirtualHubStop(MGC_VirtualHub* pHub); +extern int MGC_VirtualHubSubmitUrb(MGC_VirtualHub* pHub, struct urb* pUrb); +extern int MGC_VirtualHubUnlinkUrb(MGC_VirtualHub* pHub, struct urb* pUrb); +extern void MGC_VirtualHubPortResetDone(MGC_VirtualHub* pHub, + uint8_t bPortIndex, uint8_t bHubSpeed); +extern void MGC_VirtualHubPortConnected(MGC_VirtualHub* pHub, + uint8_t bPortIndex, uint8_t bSpeed); +extern void MGC_VirtualHubPortResumed(MGC_VirtualHub* pHub, + uint8_t bPortIndex); +extern void MGC_VirtualHubPortDisconnected(MGC_VirtualHub* pHub, + uint8_t bPortIndex); + +#else /* #ifdef MUSB_VIRTHUB */ + +static int uint8_t MGC_VirtualHubInit(MGC_VirtualHub* pHub, + struct usb_bus* pBus, uint8_t bPortCount, + MGC_PortServices* pPortServices) +{ + DBG(-1, "this should not be called"); + return -ENODEV; +}; +static inline void MGC_VirtualHubDestroy(MGC_VirtualHub* pHub) { + DBG(-1, "this should not be called"); +}; +static inline void MGC_VirtualHubStart(MGC_VirtualHub* pHub) { + DBG(-1, "this should not be called"); +}; +static inline void MGC_VirtualHubStop(MGC_VirtualHub* pHub) { + DBG(-1, "this should not be called"); +}; +static inline int MGC_VirtualHubSubmitUrb(MGC_VirtualHub* pHub, struct urb* pUrb) { + DBG(-1, "this should not be called"); + return -ENODEV; +}; + +static inline int MGC_VirtualHubUnlinkUrb(MGC_VirtualHub* pHub, struct urb* pUrb) { + DBG(-1, "this should not be called"); + return -ENODEV; +}; + +static inline void MGC_VirtualHubPortResetDone(MGC_VirtualHub* pHub, + uint8_t bPortIndex, uint8_t bHubSpeed) { + DBG(-1, "this should not be called"); +}; +static inline void MGC_VirtualHubPortConnected(MGC_VirtualHub* pHub, + uint8_t bPortIndex, uint8_t bSpeed) { + DBG(-1, "this should not be called"); +}; +static inline void MGC_VirtualHubPortResumed(MGC_VirtualHub* pHub, + uint8_t bPortIndex) { + DBG(-1, "this should not be called"); +}; +static inline void MGC_VirtualHubPortDisconnected(MGC_VirtualHub* pHub, +uint8_t bPortIndex) { + DBG(-1, "this should not be called"); +}; + +#endif + + +#endif /* multiple inclusion protection */ + --- /dev/null +++ linux-2.6.20/drivers/usb/nomadik/musbdefs.h @@ -0,0 +1,828 @@ +/* + * linux/drivers/usb/nomadik/musbdefs.h + * + * Copyright 2007, STMicroelectronics + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __MUSB_MUSBDEFS_H__ +#define __MUSB_MUSBDEFS_H__ + +#include +#include +#include +#include + +#ifdef MUSB_CONFIG_PROC_FS +#include +#endif + +/* useful for compiling across linux version & debug definitions */ +#include "musb_cross.h" +#include "debug.h" + +/* Board-specific definitions (hard-wired controller locations/IRQs) */ +#include "plat_cnf.h" +#include "plat_arc.h" +#include "musbhdrc.h" + +/****************************** VERIFY THE DEFINES ************************** + * determine how to compile the driver; MUSB_GADGET->as gadget driver, + * MUSB_HOST as host mode, MUSB_OTG -> otg mode (host and gadget) + * + * OTG => GADGET + */ + +#ifdef MUSB_GSTORAGE + +/* for now */ +#ifndef MUSB_OTG +#define MUSB_OTG +#endif + +#endif + +#ifdef MUSB_OTG +#endif +#ifndef MUSB_HOST +#define MUSB_HOST +#endif + +#ifdef CONFIG_PROC_FS +#ifndef MUSB_CONFIG_PROC_FS +#define MUSB_CONFIG_PROC_FS +#endif +#endif + +#ifdef MUSB_PROC_TESTMUSB + +#ifndef CONFIG_PROC_FS +#error "TestMusb needs CONFIG_PROC_FS" +#endif + +#ifndef MUSB_HOST +#error "TestMusb needs HOST MODE" +#endif + +#endif + +#ifdef MUSB_HOST +#define MUSB_VIRTHUB +#endif + +/************************* DEFINES DEPENDENT INCLUDES ************************/ + +/* virtual hub */ +#include "musb_virthub.h" + +/****************************** USB CONSTANTS ********************************/ + +#ifndef USB_DT_DEVICE_QUALIFIER +#define USB_DT_DEVICE_QUALIFIER 6 +#endif + +#ifndef USB_DT_DEVICE_QUALIFIER_SIZE +#define USB_DT_DEVICE_QUALIFIER_SIZE 10 +#endif + +#ifndef USB_DT_OTHER_SPEED +#define USB_DT_OTHER_SPEED 7 +#endif + +#ifndef USB_MAXCHILDREN +#define USB_MAXCHILDREN (16) +#endif + +/****************************** DEBUG CONSTANTS ********************************/ + +#define MGC_PAD_FRONT 0xa5deadfe +#define MGC_PAD_BACK 0xabadcafe +#define MGC_TEST_PACKET_SIZE 53 + +/****************************** CONSTANTS ********************************/ + +#if MUSB_DEBUG > 0 +#define STATIC +#define MUSB_PARANOID +#else +#define STATIC static +#endif + +#ifndef TRUE +#define TRUE 1 +#endif +#ifndef FALSE +#define FALSE 0 +#endif + +#ifndef MUSB_C_NUM_EPS +#define MUSB_C_NUM_EPS ((uint8_t)16) +#endif + +#ifndef MUSB_MAX_END0_PACKET +#define MUSB_MAX_END0_PACKET ((uint16_t)MGC_END0_FIFOSIZE) +#endif + +#define MGC_END0_START 0x0 +#define MGC_END0_OUT 0x2 +#define MGC_END0_IN 0x4 +#define MGC_END0_STATUS 0x8 + +#define MGC_END0_STAGE_SETUP 0x0 +#define MGC_END0_STAGE_TX 0x2 +#define MGC_END0_STAGE_RX 0x4 +#define MGC_END0_STAGE_STATUSIN 0x8 +#define MGC_END0_STAGE_STATUSOUT 0xf +#define MGC_END0_STAGE_STALL_BIT 0x10 + +/* obsolete */ +#define MGC_END0_STAGE_DATAIN MGC_END0_STAGE_TX +#define MGC_END0_STAGE_DATAOUT MGC_END0_STAGE_RX + +/* EASY GUESS */ +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0) +#define USB_ALLOC_DEV( _parent, _usb_bus, _port) usb_alloc_dev(_parent, _usb_bus, _port) +#else +/* 2.4, mvl21, bc5 */ +#define USB_ALLOC_DEV( _parent, _usb_bus, _port) usb_alloc_dev(_parent, _usb_bus) +#endif + + +/* 2.4/2.6 compatibility */ +#ifdef MUSB_V26 + +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,9) +#define USB_HALT_ENDPOINT(_dev, _pipe_ep, _pipe_out) ((_dev)->bus->op->disable(_dev, _pipe_ep)) +#define USB_RUN_ENDPOINT(_dev, _pipe_ep, _pipe_out) usb_endpoint_running(_dev, _pipe_ep, _pipe_out) +#define USB_ENDPOINT_HALTED(_dev, _pipe_ep, _pipe_out) ( 0 ) +#else +#define USB_HALT_ENDPOINT(_dev, _pipe_ep, _pipe_out) usb_endpoint_halt(_dev, _pipe_ep, _pipe_out) +#define USB_RUN_ENDPOINT(_dev, _pipe_ep, _pipe_out) usb_endpoint_running(_dev, _pipe_ep, _pipe_out) +#define USB_ENDPOINT_HALTED(_dev, _pipe_ep, _pipe_out) usb_endpoint_halted(_dev, _pipe_ep, _pipe_out) +#endif + +/*#define COMPLETE_URB(_pUrb, _p) _pUrb->complete(_pUrb, _p)*/ +#define COMPLETE_URB(_pUrb, _p) (_pUrb->complete=_p) +#define WAIT_MS(_ms) mdelay(_ms) + +#define USB_ISO_ASAP 0x0002 +#define USB_ASYNC_UNLINK 0x0008 + +#define USB_ST_NOERROR (0) +#define USB_ST_CRC (-EILSEQ) +#define USB_ST_BITSTUFF (-EPROTO) +#define USB_ST_NORESPONSE (-ETIMEDOUT) /* device not responding/handshaking */ +#define USB_ST_DATAOVERRUN (-EOVERFLOW) +#define USB_ST_DATAUNDERRUN (-EREMOTEIO) +#define USB_ST_BUFFEROVERRUN (-ECOMM) +#define USB_ST_BUFFERUNDERRUN (-ENOSR) +#define USB_ST_INTERNALERROR (-EPROTO) /* unknown error */ +#define USB_ST_SHORT_PACKET (-EREMOTEIO) +#define USB_ST_PARTIAL_ERROR (-EXDEV) /* ISO transfer only partially completed */ +#define USB_ST_URB_KILLED (-ENOENT) /* URB canceled by user */ +#define USB_ST_URB_PENDING (-EINPROGRESS) +#define USB_ST_REMOVED (-ENODEV) /* device not existing or removed */ +#define USB_ST_TIMEOUT (-ETIMEDOUT) /* communication timed out, also in urb->status**/ +#define USB_ST_NOTSUPPORTED (-ENOSYS) +#define USB_ST_BANDWIDTH_ERROR (-ENOSPC) /* too much bandwidth used */ +#define USB_ST_URB_INVALID_ERROR (-EINVAL) /* invalid value/transfer type */ +#define USB_ST_URB_REQUEST_ERROR (-ENXIO) /* invalid endpoint */ +#define USB_ST_STALL (-EPIPE) /* pipe stalled, also in urb->status*/ + +#define USB_ZERO_PACKET 0x0040 /* Finish bulk OUTs always with zero length packet */ + +#endif + +#ifdef MUSB_V24 +#define usb_disabled() 0 +#define COMPLETE_URB(_pUrb, _p) _pUrb->complete(_pUrb) +#define WAIT_MS(_ms) wait_ms(_ms) +#define USB_HALT_ENDPOINT(_dev, _pipe_ep, _pipe_out) usb_endpoint_halt(_dev, _pipe_ep, _pipe_out) +#define USB_ENDPOINT_HALTED(_dev, _pipe_ep, _pipe_out) usb_endpoint_halted(_dev, _pipe_ep, _pipe_out) + +#ifdef MUSB_LINUX_MV21 +#define usb_get_urb(_pUrb) _pUrb +#define usb_put_urb(_pUrb) +#undef MUSB_HAS_BUSNAME +#endif + +#endif + +typedef enum +{ + MGC_STATE_DEFAULT, + MGC_STATE_ADDRESS, + MGC_STATE_CONFIGURED +} MGC_DeviceState; + +/* failure codes */ +#define MUSB_ERR_WAITING 1 +#define MUSB_ERR_VBUS -1 +#define MUSB_ERR_BABBLE -2 +#define MUSB_ERR_CORRUPTED -3 +#define MUSB_ERR_IRQ -4 +#define MUSB_ERR_SHUTDOWN -5 +#define MUSB_ERR_RESTART -6 + +/****************************** FUNCTIONS ********************************/ + +#define KMALLOC(a,b,c) { lock_kernel(); a=kmalloc(b,c); unlock_kernel(); } +#define KFREE(p) { lock_kernel(); kfree(p); unlock_kernel(); } + +/*************************** REGISTER ACCESS ********************************/ + +/* indexed vs. flat register model */ +#ifdef MUSB_FLAT_REG +#define MGC_SelectEnd(_pBase, _bEnd) +#define MGC_ReadCsr8(_pBase, _bOffset, _bEnd) \ + MGC_Read8(_pBase, MGC_END_OFFSET(_bEnd, _bOffset)) +#define MGC_ReadCsr16(_pBase, _bOffset, _bEnd) \ + MGC_Read16(_pBase, MGC_END_OFFSET(_bEnd, _bOffset)) +#define MGC_WriteCsr8(_pBase, _bOffset, _bEnd, _bData) \ + MGC_Write8(_pBase, MGC_END_OFFSET(_bEnd, _bOffset), _bData) +#define MGC_WriteCsr16(_pBase, _bOffset, _bEnd, _bData) \ + MGC_Write16(_pBase, MGC_END_OFFSET(_bEnd, _bOffset), _bData) +#else +#define MGC_SelectEnd(_pBase, _bEnd) \ + MGC_Write8(_pBase, MGC_O_HDRC_INDEX, _bEnd) +#define MGC_ReadCsr8(_pBase, _bOffset, _bEnd) \ + MGC_Read8(_pBase, (_bOffset + 0x10)) +#define MGC_ReadCsr16(_pBase, _bOffset, _bEnd) \ + MGC_Read16(_pBase, (_bOffset + 0x10)) +#define MGC_WriteCsr8(_pBase, _bOffset, _bEnd, _bData) \ + MGC_Write8(_pBase, (_bOffset + 0x10), _bData) +#define MGC_WriteCsr16(_pBase, _bOffset, _bEnd, _bData) \ + MGC_Write16(_pBase, (_bOffset + 0x10), _bData) +#endif + + +/************************** ULPI Registers ********************************/ + +/* Added in HDRC 1.9(?) & MHDRC 1.4 */ +/* ULPI pass-through */ +#define MGC_O_HDRC_ULPI_VBUSCTL 0x70 +#define MGC_O_HDRC_ULPI_REGDATA 0x74 +#define MGC_O_HDRC_ULPI_REGADDR 0x75 +#define MGC_O_HDRC_ULPI_REGCTL 0x76 + +/* extended config & PHY control */ +#define MGC_O_HDRC_ENDCOUNT 0x78 +#define MGC_O_HDRC_DMARAMCFG 0x79 +#define MGC_O_HDRC_PHYWAIT 0x7A +#define MGC_O_HDRC_PHYVPLEN 0x7B /* units of 546.1 us */ +#define MGC_O_HDRC_HSEOF1 0x7C /* units of 133.3 ns */ +#define MGC_O_HDRC_FSEOF1 0x7D /* units of 533.3 ns */ +#define MGC_O_HDRC_LSEOF1 0x7E /* units of 1.067 us */ + +/* Added in HDRC 1.9(?) & MHDRC 1.4 */ +/* ULPI */ +#define MGC_M_ULPI_VBUSCTL_USEEXTVBUSIND 0x02 +#define MGC_M_ULPI_VBUSCTL_USEEXTVBUS 0x01 +#define MGC_M_ULPI_REGCTL_INT_ENABLE 0x08 +#define MGC_M_ULPI_REGCTL_READNOTWRITE 0x04 +#define MGC_M_ULPI_REGCTL_COMPLETE 0x02 +#define MGC_M_ULPI_REGCTL_REG 0x01 +/* extended config & PHY control */ +#define MGC_M_ENDCOUNT_TXENDS 0x0f +#define MGC_S_ENDCOUNT_TXENDS 0 +#define MGC_M_ENDCOUNT_RXENDS 0xf0 +#define MGC_S_ENDCOUNT_RXENDS 4 +#define MGC_M_DMARAMCFG_RAMBITS 0x0f /* RAMBITS-1 */ +#define MGC_S_DMARAMCFG_RAMBITS 0 +#define MGC_M_DMARAMCFG_DMACHS 0xf0 +#define MGC_S_DMARAMCFG_DMACHS 4 +#define MGC_M_PHYWAIT_WAITID 0x0f /* units of 4.369 ms */ +#define MGC_S_PHYWAIT_WAITID 0 +#define MGC_M_PHYWAIT_WAITCON 0xf0 /* units of 533.3 ns */ +#define MGC_S_PHYWAIT_WAITCON 4 + +/****************************** FUNCTIONS ********************************/ + +#define MUSB_HST_MODE(_pthis) { (_pthis)->bIsHost=TRUE; (_pthis)->bIsDevice=FALSE; \ + (_pthis)->bIsA=1; (_pthis)->bFailCode=0; } +#define MUSB_DEV_MODE(_pthis) { (_pthis)->bIsHost=FALSE; (_pthis)->bIsDevice=TRUE; \ + (_pthis)->bIsA=0; (_pthis)->bFailCode=0; } +#define MUSB_B_IDLE_MODE(_pthis) { (_pthis)->bIsHost=FALSE; (_pthis)->bIsDevice=FALSE; \ + (_pthis)->bIsA=0; (_pthis)->bFailCode=MUSB_ERR_WAITING; } +#define MUSB_A_IDLE_MODE(_pthis) { (_pthis)->bIsHost=FALSE; (_pthis)->bIsDevice=FALSE; \ + (_pthis)->bIsA=1; (_pthis)->bFailCode=MUSB_ERR_WAITING; } +#define MUSB_ERR_MODE(_pthis, _cause) { (_pthis)->bIsHost=FALSE; (_pthis)->bIsDevice=FALSE; \ + (_pthis)->bFailCode=_cause; } + +#define MUSB_IS_ERR(_x) ( (_x)->bFailCode<0 ) +#define MUSB_IS_HST(_x) ( !MUSB_IS_ERR(_x) && (_x)->bIsHost && !(_x)->bIsDevice ) +#define MUSB_IS_DEV(_x) ( !MUSB_IS_ERR(_x) && !(_x)->bIsHost && (_x)->bIsDevice ) +#define MUSB_IS_B_IDLE(_x) ( !MUSB_IS_ERR(_x) && !(_x)->bIsHost && !(_x)->bIsDevice && !(_x)->bIsA ) +#define MUSB_IS_A_IDLE(_x) ( !MUSB_IS_ERR(_x) && !(_x)->bIsHost && !(_x)->bIsDevice && (_x)->bIsA ) + +#define MUSB_MODE(_x) ( MUSB_IS_HST(_x)?"HOST":( MUSB_IS_DEV(_x)?"FUNCTION":(MUSB_IS_B_IDLE(_x)?"B_IDLE":(MUSB_IS_A_IDLE(_x)?"A_IDLE":"ERROR"))) ) + +#define HDRC_IS_HST(_x) ( MGC_Read8((_x)->pRegs, MGC_O_HDRC_DEVCTL)&MGC_M_DEVCTL_HM ) +#define HDRC_IS_DEV(_x) ( !HDRC_IS_HST(_x) ) + + +/******************************** DMA TYPES **********************************/ + +#ifdef MUSB_DMA +#include "dma.h" + +#ifndef MGC_HSDMA_CHANNELS +#define MGC_HSDMA_CHANNELS 8 +#endif + +#ifdef MUSB_HAS_DMA_URBS +#define WANTS_DMA(_pUrb) ((_pUrb)->transfer_dma && (_pUrb->flags & URB_NO_TRANSFER_DMA_MAP)) +#define DMA_BUFFER(_pUrb) ((_pUrb)->transfer_dma) +#else +#define WANTS_DMA(_pUrb) (0) +#define DMA_BUFFER(pUrb) ((void*)0x000666) +#endif + +extern MGC_DmaControllerFactory MGC_HdrcDmaControllerFactory; +#endif + + +/************************** Ep Configuration ********************************/ + +/** The End point descriptor */ +struct MUSB_EpFifoDescriptor { + uint8_t bType; /* 0 for autoconfig, CNTR, ISOC, BULK, INTR */ + uint8_t bDir; /* 0 for autoconfig, INOUT, IN, OUT */ + uint16_t wSize; /* 0 for autoconfig, or the size */ + uint8_t bDbe; /* Double buffering: 0 disabled, 1 enabled */ +}; + +#define MUSB_EPD_AUTOCONFIG 0 + +#define MUSB_EPD_T_CNTRL 1 +#define MUSB_EPD_T_ISOC 2 +#define MUSB_EPD_T_BULK 3 +#define MUSB_EPD_T_INTR 4 + +#define MUSB_EPD_D_INOUT 0 +#define MUSB_EPD_D_TX 1 +#define MUSB_EPD_D_RX 2 + +/******************************** TYPES *************************************/ + +struct urb; +struct usb_device; +struct usb_gadget; +struct usb_hcd; + +/** + * The device request. + */ +typedef struct __attribute__((packed)) { + uint8_t bmRequestType; + uint8_t bRequest; + uint16_t wValue; + uint16_t wIndex; + uint16_t wLength; +} MUSB_DeviceRequest; + +/** + * MGC_LinuxLocalEnd. + * Local endpoint resource. + * @field Lock spinlock + * @field pUrb current URB + * @field urb_list list + * @field dwOffset current buffer offset + * @field dwRequestSize how many bytes were last requested to move + * @field wMaxPacketSizeTx local Tx FIFO size + * @field wMaxPacketSizeRx local Rx FIFO size + * @field wPacketSize programmed packet size + * @field bIsSharedFifo TRUE if FIFO is shared between Tx and Rx + * @field bAddress programmed bus address + * @field bEnd programmed remote endpoint address + * @field bTrafficType programmed traffic type + * @field bIsClaimed TRUE if claimed + * @field bIsTx TRUE if current direction is Tx + * @field bIsReady TRUE if ready (available for new URB) + */ +typedef struct +{ +#if MUSB_DEBUG > 0 + uint32_t dwPadFront; +#endif + spinlock_t Lock; + uint8_t bEnd; /* ep number */ + +#ifdef MUSB_USE_HCD_DRIVER + struct urb* pCurrentUrb; +#else + struct list_head urb_list; +#endif + + uint8_t bBusyCompleting; /* TRUE on Tx when the current urb is completing */ + + unsigned int dwOffset; /* offset int the current request */ + unsigned int dwRequestSize; /* request size */ + unsigned int dwIsoPacket; + unsigned int dwWaitFrame; + uint8_t bRetries; + +#ifdef MUSB_DMA + MGC_DmaChannel* pDmaChannel; +#endif + +#ifdef MUSB_CONFIG_PROC_FS + unsigned long dwTotalTxBytes; + unsigned long dwTotalRxBytes; + unsigned long dwTotalTxPackets; + unsigned long dwTotalRxPackets; + unsigned long dwErrorTxPackets; + unsigned long dwErrorRxPackets; + unsigned long dwMissedTxPackets; + unsigned long dwMissedRxPackets; +#endif + + uint16_t wMaxPacketSizeTx; + uint16_t wMaxPacketSizeRx; + uint16_t wPacketSize; + uint8_t bDisableDma; /* not used now! */ + uint8_t bIsSharedFifo; + + /* softstate, used from find_end() to determine a good match */ + uint8_t bRemoteAddress; + uint8_t bRemoteEnd; + uint8_t bTrafficType; + uint8_t bIsClaimed; /* only for isoc and int traffic */ + uint8_t bIsTx; + uint8_t bIsReady; + uint8_t bStalled; /* the ep has been halted */ + +#if MUSB_DEBUG > 0 + uint32_t dwPadBack; +#endif +} MGC_LinuxLocalEnd; + +/** A listener for disconnection */ +typedef void (*MGC_pfDisconnectListener)(void*); +/** A handler for the default endpoint interrupt */ +typedef void (*MGC_pfDefaultEndHandler)(void*); + +#ifdef MUSB_USE_HCD_DRIVER +typedef struct { + spinlock_t urb_queue_lock; + int urb_queue_count; + int urb_exec_count; + void *urb_queue_head; + void *urb_queue_tail; +} mgc_hcd_urb_queue; +#endif + +/** + * MGC_LinuxCd. + * Driver instance data. + * @field Lock spinlock + * @field Timer interval timer for various things + * @field pBus pointer to Linux USBD bus + * @field RootHub virtual root hub + * @field PortServices services provided to virtual root hub + * @field pRootDevice root device pointer, to track connection speed + * @field nIrq IRQ number (needed by free_irq) + * @field bIsMultipoint TRUE if multi-point core + * @field bIsHost TRUE if host + * @field bIsDevice TRUE if peripheral + * @field pRegs pointer to mapped registers + */ +typedef struct +{ +#if MUSB_DEBUG > 0 + uint32_t dwPadFront; +#endif + spinlock_t Lock; + struct timer_list Timer; + struct usb_bus *pBus; + char aName[32]; + MGC_VirtualHub RootHub; + MGC_PortServices PortServices; + struct usb_device* pRootDevice; + +#ifdef MUSB_DMA + MGC_DmaController* pDmaController; +#endif + + int nIrq; + int nIrqType; + + int nBabbleCount; + void* pRegs; + + MGC_LinuxLocalEnd aLocalEnd[MUSB_C_NUM_EPS]; + +#ifdef MUSB_USE_HCD_DRIVER + mgc_hcd_urb_queue LocalQueue; + wait_queue_head_t waitqh; +#endif + + uint16_t wEndMask; + uint8_t bEndCount; + uint8_t bRootSpeed; + uint8_t bIsMultipoint; + uint8_t bIsHost; + uint8_t bIsDevice; + uint8_t bIsA; + uint8_t bIgnoreDisconnect; /* during bus resets I got fake disconnects */ + uint8_t bVbusErrors; /* bus errors found */ + + int bFailCode; /* one of MUSB_ERR_* failure code */ + + uint8_t bBulkTxEnd; + uint8_t bBulkRxEnd; + uint8_t bBulkSplit; + uint8_t bBulkCombine; + + uint8_t bEnd0Stage; /* end0 stage while in host or device mode */ + +#ifdef MUSB_GADGET + uint8_t bDeviceState; + uint8_t bIsSelfPowered; + uint8_t bSetAddress; + uint8_t bAddress; + uint8_t bTestMode; + uint8_t bTestModeValue; + + struct usb_gadget* pGadget; /* the gadget */ + struct usb_gadget_driver* pGadgetDriver; /* it's driver */ + + /* Endpoint 0 buffer and its buffer code; can be customized for + * devices that are not usign the default USB headers. Default + * values are: + * + * . pfFillBuffer is MGC_HdrcReadUSBControlRequest() + * . pEnd0Buffer is an instance of MGC_End0Buffer + **/ + int (*pfReadHeader)(void*, uint16_t); /* NULL==MGC_HdrcReadUSBControlRequest*/ + void* pEnd0Buffer; /* this is the buffer, default implementation uses MGC_End0Buffer */ + + /* compatibility, need to be osoleted used from gstorage */ + uint16_t wEnd0Offset; +#endif + +#ifdef MUSB_OTG + MGC_OtgMachine OtgMachine; + MGC_OtgServices OtgServices; + uint8_t bDelayPortPowerOff; + uint8_t bOtgError; +#endif + +#if MUSB_DEBUG > 0 + uint32_t dwPadBack; +#endif + +#ifdef MUSB_CONFIG_PROC_FS + struct proc_dir_entry* pProcEntry; + + /* A couple of hooks to enable HSET */ + MGC_pfDisconnectListener pfDisconnectListener; + void* pDisconnectListenerParam; + MGC_pfDefaultEndHandler pfDefaultEndHandler; + void* pDefaultEndHandlerParam; +#endif + +} MGC_LinuxCd; + +#ifdef MUSB_USE_HCD_DRIVER +void mgc_hcd_complete_urb(MGC_LinuxCd *pThis, struct urb* pUrb); +mgc_hcd_urb_queue * mgc_hcd_get_urb_queue(MGC_LinuxCd* pThis); +#endif + + +/***************************** Glue it together *****************************/ + + +extern unsigned int MGC_nIndex; + +extern int MGC_DriverInit(void); +extern void MGC_DriverCleanup(void); + +extern void MGC_HdrcStart(MGC_LinuxCd* pThis); +extern void MGC_HdrcStop(MGC_LinuxCd* pThis); +extern void MGC_HdrcServiceUsb(MGC_LinuxCd* pThis, uint8_t reg); +extern void MGC_HdrcLoadFifo(const uint8_t* pBase, uint8_t bEnd, + uint16_t wCount, const uint8_t* pSource); +extern void MGC_HdrcUnloadFifo(const uint8_t* pBase, uint8_t bEnd, + uint16_t wCount, uint8_t* pDest); + +extern MGC_LinuxCd* MGC_LinuxInitController(void* pDevice, uint16_t wType, + int nIrq, void* pRegs, u64 len, const char* pName); +extern void MGC_LinuxSetTimer(MGC_LinuxCd* pThis, void (*pfFunc)(unsigned long), + unsigned long pParam, unsigned long millisecs); + +extern void MGC_LinuxCdFree(MGC_LinuxCd* pThis); + +extern struct urb* MGC_GetCurrentUrb(MGC_LinuxLocalEnd *pEnd); + +extern int queue_length(struct list_head *lh); + +/* Conditionally-compiled to update OTG state machine when necessary */ +extern void MGC_OtgUpdate(MGC_LinuxCd* pThis, uint8_t bVbusError, + uint8_t bConnect); + +extern void MGC_HdrcConfigureEps(MGC_LinuxCd* pThis); +extern MGC_LinuxCd *hcd_to_musbstruct(void *ptr); +extern struct usb_hcd* musbstruct_to_hcd(const MGC_LinuxCd *pThis); + +/*-------------------------- available buses ---------------------*/ + +extern int direct_bus_init(void); +extern void direct_bus_shutdown(void); + +/*-------------------------- ProcFS definitions ---------------------*/ + +struct MGC_TestProcData; +struct proc_dir_entry; + +#ifdef MUSB_CONFIG_PROC_FS +extern char* decode_hst_ep_protocol(MGC_LinuxCd* pThis, unsigned bEnd); +extern char* decode_dev_ep_protocol(MGC_LinuxCd* pThis, unsigned bEnd); +#endif + +#ifdef MUSB_CONFIG_PROC_FS +extern void MGC_HdrcSetDisconnectListener(MGC_LinuxCd* pCd, + MGC_pfDisconnectListener pfListener, void* pParam); +extern void MGC_HdrcSetDefaultEndHandler(MGC_LinuxCd* pCd, + MGC_pfDefaultEndHandler pfHandler, void* pParam); +extern struct proc_dir_entry* MGC_LinuxCreateProcFs(char *name, + MGC_LinuxCd* data); +extern void MGC_LinuxDeleteProcFs(MGC_LinuxCd* data); +#else +#define PROC_FS_DISABLED(_x) { DBG(3, "#PROC_FS DISABLED"); _x } + +static inline void MGC_HdrcSetDisconnectListener(MGC_LinuxCd* pCd, + MGC_pfDisconnectListener pfListener, void* pParam) PROC_FS_DISABLED(;) +static inline void MGC_HdrcSetDefaultEndHandler(MGC_LinuxCd* pCd, + MGC_pfDefaultEndHandler pfHandler, void* pParam) PROC_FS_DISABLED(;) +static inline struct proc_dir_entry* MGC_LinuxCreateProcFs(char *name, + MGC_LinuxCd* data) PROC_FS_DISABLED(;) +static inline void MGC_LinuxDeleteProcFs(MGC_LinuxCd* data) + PROC_FS_DISABLED(;) +#endif + +/*-------------------------- TestProcFS definitions ---------------------*/ + +#ifdef MUSB_PROC_TESTMUSB +extern struct proc_dir_entry* MGC_LinuxCreateTestProcFs(char *name, MGC_LinuxCd* data); +extern void MGC_LinuxDeleteTestProcFs(char *name, MGC_LinuxCd* data); +#endif + +/*------------------------------ IOCTLS/PROCFS -----------------------*/ + +extern void MGC_Zap(MGC_LinuxCd* pThis); /* zap the driver */ +extern void MGC_Session(MGC_LinuxCd* pThis); /* start a session */ +extern void MGC_SetDebugLevel(int level); /* set the debug level */ +extern int dump_header_stats(MGC_LinuxCd* pThis, char *buffer); /* compile options etc */ +#ifdef MUSB_HOST +int dump_end_stats(MGC_LinuxCd* pThis, uint8_t bEnd, char* aBuffer); +#endif + + + +/*-------------------------- DEBUG Definitions ---------------------*/ + + +#ifdef MUSB_PARANOID +#define MGC_HDRC_DUMPREGS(_t, _s) MGC_HdrcDumpRegs((_t)->pRegs, MUSB_IS_HST(_t) && _t->bIsMultipoint, _s) +#define MGC_ISCORRUPT(_x) mgc_is_corrupt((_x), __FUNCTION__,__LINE__) + +/** + * Test whether the struct is corrupted. + * @param pThis + */ +static inline uint8_t mgc_is_corrupt(MGC_LinuxCd* pThis, const char *function, int line) { +#ifdef MUSB_HOST + uint8_t bEnd; + MGC_LinuxLocalEnd* pEnd; +#endif + + if(MGC_PAD_FRONT != pThis->dwPadFront) { + printk(KERN_INFO"musb %s:%d: pThis front pad corrupted (%x)\n", + function, line, pThis->dwPadFront); + return TRUE; + } + + if(MGC_PAD_BACK != pThis->dwPadBack) { + printk(KERN_INFO"musb %s:%d: pThis back pad corrupted (%x)\n", + function, line, pThis->dwPadBack); + return TRUE; + } + +#ifdef MUSB_HOST + for(bEnd = 0; bEnd < pThis->bEndCount; bEnd++) { + pEnd = &(pThis->aLocalEnd[bEnd]); + + if(MGC_PAD_FRONT != pEnd->dwPadFront) { + printk(KERN_INFO"musb %s:%d: end %d front pad corrupted (%x)\n", + function, line, bEnd, pEnd->dwPadFront); + return TRUE; + } + + if(MGC_PAD_BACK != pEnd->dwPadBack) { + printk(KERN_INFO"musb %s:%d: end %d back pad corrupted (%x)\n", + function, line, bEnd, pEnd->dwPadBack); + return TRUE; + } + } +#endif + +#ifdef MUSB_GADGET + /* do something about it */ +#endif + + return FALSE; +} + +#else +#define MGG_IsCorrupt(_x) (_x) +#define MGC_HDRC_DUMPREGS(_t, _s) +#endif + +/* -------------------------- Host Definitions ------------------------ */ + +#ifdef MUSB_HOST +extern void MGC_InitLocalEndPoints(MGC_LinuxCd* pThis); +#endif + +/* -------------------------- Gadget Definitions --------------------- */ + +struct usb_ep; + +extern const uint8_t MGC_aTestPacket[MGC_TEST_PACKET_SIZE]; + +#if defined(MUSB_GADGET) || defined(MUSB_V26) +void* MGC_AllocBufferMemory(MGC_LinuxCd* pThis, size_t bytes, int gfp_flags, dma_addr_t* dma); +void MGC_FreeBufferMemory(MGC_LinuxCd* pThis, size_t bytes, void *address, dma_addr_t dma); +#endif + +#ifdef MUSB_GADGET +extern void* MGC_MallocEp0Buffer(const MGC_LinuxCd* pThis); +#endif + +/* Gadget functions */ +#ifdef MUSB_GADGET +struct usb_gadget; + +extern MGC_LinuxCd* MGC_GetDriverByName(const char *name); +extern int MGC_GadgetFindEnd(struct usb_ep* pGadgetEnd); +extern void mgc_init_gadget_endpoints(MGC_LinuxCd *pThis, struct usb_gadget *gadget); +extern void MGC_GadgetReset(MGC_LinuxCd* pThis); +extern void MGC_GadgetResume(MGC_LinuxCd* pThis); +extern void MGC_GadgetSuspend(MGC_LinuxCd* pThis); +extern void MGC_GadgetDisconnect(MGC_LinuxCd* pThis); +extern void MGC_HdrcServiceDeviceDefaultEnd(MGC_LinuxCd* pThis); +extern void MGC_HdrcServiceDeviceTxAvail(MGC_LinuxCd* pThis, uint8_t bEnd); +extern void MGC_HdrcServiceDeviceRxReady(MGC_LinuxCd* pThis, uint8_t bEnd); + +extern void dump_ep_status(MGC_LinuxCd* pThis); +extern void dump_ep_queue(int index, int verbose); + +/* + * Gadget disabled + */ +#else +#define GADGET_DISABLED(_x) { DBG(0, "#GADGET DISABLED"); _x } + +static inline MGC_LinuxCd* MGC_GetDriverByName(const char *name) + GADGET_DISABLED( return NULL; ) +static inline int MGC_GadgetFindEnd(struct usb_ep* pGadgetEnd) + GADGET_DISABLED( return -1; ) +static inline void MGC_InitGadgetEndPoints(MGC_LinuxCd *pThis) + GADGET_DISABLED(;) +static inline void MGC_GadgetReset(MGC_LinuxCd* pThis) + GADGET_DISABLED(;) +static inline void MGC_GadgetResume(MGC_LinuxCd* pThis) + GADGET_DISABLED(;) +static inline void MGC_GadgetSuspend(MGC_LinuxCd* pThis) + GADGET_DISABLED(;) +static inline void MGC_GadgetDisconnect(MGC_LinuxCd* pThis) + GADGET_DISABLED(;) +static inline void MGC_HdrcServiceDeviceDefaultEnd(MGC_LinuxCd* pThis) + GADGET_DISABLED(;) +static inline void MGC_HdrcServiceDeviceTxAvail(MGC_LinuxCd* pThis, uint8_t bEnd) + GADGET_DISABLED(;) +static inline void MGC_HdrcServiceDeviceRxReady(MGC_LinuxCd* pThis, uint8_t bEnd) + GADGET_DISABLED(;) + +static inline void dump_ep_status(MGC_LinuxCd* pThis) + GADGET_DISABLED(;) +static inline void dump_ep_queue(int index, int verbose) + GADGET_DISABLED(;) +#endif + + +#endif /* multiple inclusion protection */ --- /dev/null +++ linux-2.6.20/drivers/usb/nomadik/musbhdrc.h @@ -0,0 +1,315 @@ +/* + * linux/drivers/usb/nomadik/musbhdrc.h + * + * Copyright 2007, STMicroelectronics + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __MUSB_HDRC_DEFS_H__ +#define __MUSB_HDRC_DEFS_H__ + +/* + * HDRC-specific definitions + * $Revision: 1.8 $ + */ + +#define MGC_MAX_USB_ENDS 16 + +#define MGC_END0_FIFOSIZE 64 /* this is non-configurable */ + +/* + * MUSBMHDRC Register map + */ + +/* Common USB registers */ + +#define MGC_O_HDRC_FADDR 0x00 /* 8-bit */ +#define MGC_O_HDRC_POWER 0x01 /* 8-bit */ + +#define MGC_O_HDRC_INTRTX 0x02 /* 16-bit */ +#define MGC_O_HDRC_INTRRX 0x04 +#define MGC_O_HDRC_INTRTXE 0x06 +#define MGC_O_HDRC_INTRRXE 0x08 +#define MGC_O_HDRC_INTRUSB 0x0A /* 8 bit */ +#define MGC_O_HDRC_INTRUSBE 0x0B /* 8 bit */ +#define MGC_O_HDRC_FRAME 0x0C +#define MGC_O_HDRC_INDEX 0x0E /* 8 bit */ +#define MGC_O_HDRC_TESTMODE 0x0F /* 8 bit */ + +/* Get offset for a given FIFO */ +#define MGC_FIFO_OFFSET(_bEnd) (0x20 + (_bEnd * 4)) + +/* Additional Control Registers */ + +#define MGC_O_HDRC_DEVCTL 0x60 /* 8 bit */ + +/* These are actually indexed: */ +#define MGC_O_HDRC_TXFIFOSZ 0x62 /* 8-bit (see masks) */ +#define MGC_O_HDRC_RXFIFOSZ 0x63 /* 8-bit (see masks) */ +#define MGC_O_HDRC_TXFIFOADD 0x64 /* 16-bit offset shifted right 3 */ +#define MGC_O_HDRC_RXFIFOADD 0x66 /* 16-bit offset shifted right 3 */ + +#define MGC_O_HDRC_TOPCONTROL 0x204 /* top control register 16-bit */ + +/* offsets to registers in flat model */ +#define MGC_O_HDRC_TXMAXP 0x00 +#define MGC_O_HDRC_TXCSR 0x02 +#define MGC_O_HDRC_CSR0 MGC_O_HDRC_TXCSR /* re-used for EP0 */ +#define MGC_O_HDRC_RXMAXP 0x04 +#define MGC_O_HDRC_RXCSR 0x06 +#define MGC_O_HDRC_RXCOUNT 0x08 +#define MGC_O_HDRC_COUNT0 MGC_O_HDRC_RXCOUNT /* re-used for EP0 */ +#define MGC_O_HDRC_TXTYPE 0x0A +#define MGC_O_HDRC_TYPE0 MGC_O_HDRC_TXTYPE /* re-used for EP0 */ +#define MGC_O_HDRC_TXINTERVAL 0x0B +#define MGC_O_HDRC_NAKLIMIT0 MGC_O_HDRC_TXINTERVAL /* re-used for EP0 */ +#define MGC_O_HDRC_RXTYPE 0x0C +#define MGC_O_HDRC_RXINTERVAL 0x0D +#define MGC_O_HDRC_FIFOSIZE 0x0F +#define MGC_O_HDRC_CONFIGDATA MGC_O_HDRC_FIFOSIZE /* re-used for EP0 */ + +#define MGC_END_OFFSET(_bEnd, _bOffset) (0x100 + (0x10*_bEnd) + _bOffset) + +/* "bus control" registers */ +#define MGC_O_HDRC_TXFUNCADDR 0x00 +#define MGC_O_HDRC_TXHUBADDR 0x02 +#define MGC_O_HDRC_TXHUBPORT 0x03 + +#define MGC_O_HDRC_RXFUNCADDR 0x04 +#define MGC_O_HDRC_RXHUBADDR 0x06 +#define MGC_O_HDRC_RXHUBPORT 0x07 + +#define MGC_BUSCTL_OFFSET(_bEnd, _bOffset) (0x80 + (8*_bEnd) + _bOffset) + +/* + * MUSBHDRC Register bit masks + */ + +/* POWER */ + +#define MGC_M_POWER_ISOUPDATE 0x80 +#define MGC_M_POWER_SOFTCONN 0x40 +#define MGC_M_POWER_HSENAB 0x20 +#define MGC_M_POWER_HSMODE 0x10 +#define MGC_M_POWER_RESET 0x08 +#define MGC_M_POWER_RESUME 0x04 +#define MGC_M_POWER_SUSPENDM 0x02 +#define MGC_M_POWER_ENSUSPEND 0x01 + +/* INTRUSB */ +#define MGC_M_INTR_SUSPEND 0x01 +#define MGC_M_INTR_RESUME 0x02 +#define MGC_M_INTR_RESET 0x04 +#define MGC_M_INTR_BABBLE 0x04 +#define MGC_M_INTR_SOF 0x08 +#define MGC_M_INTR_CONNECT 0x10 +#define MGC_M_INTR_DISCONNECT 0x20 +#define MGC_M_INTR_SESSREQ 0x40 +#define MGC_M_INTR_VBUSERROR 0x80 /* FOR SESSION END */ +#define MGC_M_INTR_EP0 0x01 /* FOR EP0 INTERRUPT */ + +/* DEVCTL */ +#define MGC_M_DEVCTL_BDEVICE 0x80 +#define MGC_M_DEVCTL_FSDEV 0x40 +#define MGC_M_DEVCTL_LSDEV 0x20 +#define MGC_M_DEVCTL_VBUS 0x18 +#define MGC_S_DEVCTL_VBUS 3 +#define MGC_M_DEVCTL_HM 0x04 +#define MGC_M_DEVCTL_HR 0x02 +#define MGC_M_DEVCTL_SESSION 0x01 + +/* TESTMODE */ + +#define MGC_M_TEST_FORCE_HOST 0x80 +#define MGC_M_TEST_FIFO_ACCESS 0x40 +#define MGC_M_TEST_FORCE_FS 0x20 +#define MGC_M_TEST_FORCE_HS 0x10 +#define MGC_M_TEST_PACKET 0x08 +#define MGC_M_TEST_K 0x04 +#define MGC_M_TEST_J 0x02 +#define MGC_M_TEST_SE0_NAK 0x01 + +/* allocate for double-packet buffering (effectively doubles assigned _SIZE) */ +#define MGC_M_FIFOSZ_DPB 0x10 +/* allocation size (8, 16, 32, ... 4096) */ +#define MGC_M_FIFOSZ_SIZE 0x0f + +/* CSR0 */ +#define MGC_M_CSR0_FLUSHFIFO 0x0100 +#define MGC_M_CSR0_TXPKTRDY 0x0002 +#define MGC_M_CSR0_RXPKTRDY 0x0001 + +/* CSR0 in Peripheral mode */ +#define MGC_M_CSR0_P_SVDSETUPEND 0x0080 +#define MGC_M_CSR0_P_SVDRXPKTRDY 0x0040 +#define MGC_M_CSR0_P_SENDSTALL 0x0020 +#define MGC_M_CSR0_P_SETUPEND 0x0010 +#define MGC_M_CSR0_P_DATAEND 0x0008 +#define MGC_M_CSR0_P_SENTSTALL 0x0004 + +/* CSR0 in Host mode */ +#define MGC_M_CSR0_H_NO_PING 0x0800 +#define MGC_M_CSR0_H_WR_DATATOGGLE 0x0400 /* set to allow setting: */ +#define MGC_M_CSR0_H_DATATOGGLE 0x0200 /* data toggle control */ +#define MGC_M_CSR0_H_NAKTIMEOUT 0x0080 +#define MGC_M_CSR0_H_STATUSPKT 0x0040 +#define MGC_M_CSR0_H_REQPKT 0x0020 +#define MGC_M_CSR0_H_ERROR 0x0010 +#define MGC_M_CSR0_H_SETUPPKT 0x0008 +#define MGC_M_CSR0_H_RXSTALL 0x0004 + +/* TxType/RxType */ +#define MGC_M_TYPE_SPEED 0xc0 +#define MGC_S_TYPE_SPEED 6 +#define MGC_TYPE_SPEED_HIGH 1 +#define MGC_TYPE_SPEED_FULL 2 +#define MGC_TYPE_SPEED_LOW 3 +#define MGC_M_TYPE_PROTO 0x30 +#define MGC_S_TYPE_PROTO 4 +#define MGC_M_TYPE_REMOTE_END 0xf + +/* CONFIGDATA */ + +#define MGC_M_CONFIGDATA_MPRXE 0x80 /* auto bulk pkt combining */ +#define MGC_M_CONFIGDATA_MPTXE 0x40 /* auto bulk pkt splitting */ +#define MGC_M_CONFIGDATA_BIGENDIAN 0x20 +#define MGC_M_CONFIGDATA_HBRXE 0x10 /* HB-ISO for RX */ +#define MGC_M_CONFIGDATA_HBTXE 0x08 /* HB-ISO for TX */ +#define MGC_M_CONFIGDATA_DYNFIFO 0x04 /* dynamic FIFO sizing */ +#define MGC_M_CONFIGDATA_SOFTCONE 0x02 /* SoftConnect */ +#define MGC_M_CONFIGDATA_UTMIDW 0x01 /* data width 0 => 8bits, 1 => 16bits */ + +/* TXCSR in Peripheral and Host mode */ + +#define MGC_M_TXCSR_AUTOSET 0x8000 +#define MGC_M_TXCSR_ISO 0x4000 +#define MGC_M_TXCSR_MODE 0x2000 +#define MGC_M_TXCSR_DMAENAB 0x1000 +#define MGC_M_TXCSR_FRCDATATOG 0x0800 +#define MGC_M_TXCSR_DMAMODE 0x0400 +#define MGC_M_TXCSR_CLRDATATOG 0x0040 +#define MGC_M_TXCSR_FLUSHFIFO 0x0008 +#define MGC_M_TXCSR_FIFONOTEMPTY 0x0002 +#define MGC_M_TXCSR_TXPKTRDY 0x0001 + +/* TXCSR in Peripheral mode */ + +#define MGC_M_TXCSR_P_INCOMPTX 0x0080 +#define MGC_M_TXCSR_P_SENTSTALL 0x0020 +#define MGC_M_TXCSR_P_SENDSTALL 0x0010 +#define MGC_M_TXCSR_P_UNDERRUN 0x0004 + +/* TXCSR in Host mode */ + +#define MGC_M_TXCSR_H_WR_DATATOGGLE 0x0200 +#define MGC_M_TXCSR_H_DATATOGGLE 0x0100 +#define MGC_M_TXCSR_H_NAKTIMEOUT 0x0080 +#define MGC_M_TXCSR_H_RXSTALL 0x0020 +#define MGC_M_TXCSR_H_ERROR 0x0004 + +/* RXCSR in Peripheral and Host mode */ + +#define MGC_M_RXCSR_AUTOCLEAR 0x8000 +#define MGC_M_RXCSR_DMAENAB 0x2000 +#define MGC_M_RXCSR_DISNYET 0x1000 +#define MGC_M_RXCSR_DMAMODE 0x0800 +#define MGC_M_RXCSR_INCOMPRX 0x0100 +#define MGC_M_RXCSR_CLRDATATOG 0x0080 +#define MGC_M_RXCSR_FLUSHFIFO 0x0010 +#define MGC_M_RXCSR_DATAERROR 0x0008 +#define MGC_M_RXCSR_FIFOFULL 0x0002 +#define MGC_M_RXCSR_RXPKTRDY 0x0001 + +/* RXCSR in Peripheral mode */ + +#define MGC_M_RXCSR_P_ISO 0x4000 +#define MGC_M_RXCSR_P_SENTSTALL 0x0040 +#define MGC_M_RXCSR_P_SENDSTALL 0x0020 +#define MGC_M_RXCSR_P_OVERRUN 0x0004 + +/* RXCSR in Host mode */ + +#define MGC_M_RXCSR_H_AUTOREQ 0x4000 +#define MGC_M_RXCSR_H_WR_DATATOGGLE 0x0400 +#define MGC_M_RXCSR_H_DATATOGGLE 0x0200 +#define MGC_M_RXCSR_H_RXSTALL 0x0040 +#define MGC_M_RXCSR_H_REQPKT 0x0020 +#define MGC_M_RXCSR_H_ERROR 0x0004 + +/* HUBADDR */ +#define MGC_M_HUBADDR_MULTI_TT 0x80 + + +/* TXCSR in Peripheral and Host mode */ + +#define MGC_M_TXCSR2_AUTOSET 0x80 +#define MGC_M_TXCSR2_ISO 0x40 +#define MGC_M_TXCSR2_MODE 0x20 +#define MGC_M_TXCSR2_DMAENAB 0x10 +#define MGC_M_TXCSR2_FRCDATATOG 0x08 +#define MGC_M_TXCSR2_DMAMODE 0x04 + +#define MGC_M_TXCSR1_CLRDATATOG 0x40 +#define MGC_M_TXCSR1_FLUSHFIFO 0x08 +#define MGC_M_TXCSR1_FIFONOTEMPTY 0x02 +#define MGC_M_TXCSR1_TXPKTRDY 0x01 + +/* TXCSR in Peripheral mode */ + +#define MGC_M_TXCSR1_P_INCOMPTX 0x80 +#define MGC_M_TXCSR1_P_SENTSTALL 0x20 +#define MGC_M_TXCSR1_P_SENDSTALL 0x10 +#define MGC_M_TXCSR1_P_UNDERRUN 0x04 + +/* TXCSR in Host mode */ + +#define MGC_M_TXCSR1_H_NAKTIMEOUT 0x80 +#define MGC_M_TXCSR1_H_RXSTALL 0x20 +#define MGC_M_TXCSR1_H_ERROR 0x04 + +/* RXCSR in Peripheral and Host mode */ + +#define MGC_M_RXCSR2_AUTOCLEAR 0x80 +#define MGC_M_RXCSR2_DMAENAB 0x20 +#define MGC_M_RXCSR2_DISNYET 0x10 +#define MGC_M_RXCSR2_DMAMODE 0x08 +#define MGC_M_RXCSR2_INCOMPRX 0x01 + +#define MGC_M_RXCSR1_CLRDATATOG 0x80 +#define MGC_M_RXCSR1_FLUSHFIFO 0x10 +#define MGC_M_RXCSR1_DATAERROR 0x08 +#define MGC_M_RXCSR1_FIFOFULL 0x02 +#define MGC_M_RXCSR1_RXPKTRDY 0x01 + +/* RXCSR in Peripheral mode */ + +#define MGC_M_RXCSR2_P_ISO 0x40 +#define MGC_M_RXCSR1_P_SENTSTALL 0x40 +#define MGC_M_RXCSR1_P_SENDSTALL 0x20 +#define MGC_M_RXCSR1_P_OVERRUN 0x04 + +/* RXCSR in Host mode */ + +#define MGC_M_RXCSR2_H_AUTOREQ 0x40 +#define MGC_M_RXCSR1_H_RXSTALL 0x40 +#define MGC_M_RXCSR1_H_REQPKT 0x20 +#define MGC_M_RXCSR1_H_ERROR 0x04 + +/* Top control register */ +#define MGC_M_TOPCTRL_MODE_ULPI 0x09 +#define MGC_M_TOPCTRL_MODE_SRST 0x04 + +#endif /* multiple inclusion protection */ --- /dev/null +++ linux-2.6.20/drivers/usb/nomadik/musbhsfc.h @@ -0,0 +1,150 @@ +/* + * linux/drivers/usb/nomadik/musbhsfc.h + * + * Copyright 2007, STMicroelectronics + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __MUSB_HSFC_DEFS_H__ +#define __MUSB_HSFC_DEFS_H__ + +#define MGC_MAX_USB_ENDS 16 + +#define MGC_END0_FIFOSIZE 64 /* this is non-configurable */ + +#define MGC_M_FIFO_EP0 0x20 + +/* + * MUSBHSFC Register map + */ + +/* Common USB registers */ + +#define MGC_O_HSFC_FADDR 0x00 /* 8-bit */ +#define MGC_O_HSFC_POWER 0x01 /* 8-bit */ + +#define MGC_O_HSFC_INTRIN 0x02 /* 16-bit */ +#define MGC_O_HSFC_INTROUT 0x04 +#define MGC_O_HSFC_INTRINE 0x06 +#define MGC_O_HSFC_INTROUTE 0x08 +#define MGC_O_HSFC_INTRUSB 0x0A /* 8 bit */ +#define MGC_O_HSFC_INTRUSBE 0x0B /* 8 bit */ +#define MGC_O_HSFC_FRAME 0x0C +#define MGC_O_HSFC_INDEX 0x0E /* 8 bit */ +#define MGC_O_HSFC_TESTMODE 0x0F /* 8 bit */ + +/* These are actually indexed: */ +#define MGC_O_HSFC_TXFIFOSZ 0x1a /* 8-bit (see masks) */ +#define MGC_O_HSFC_RXFIFOSZ 0x1b /* 8-bit (see masks) */ +#define MGC_O_HSFC_TXFIFOADD 0x1c /* 16-bit offset shifted right 3 */ +#define MGC_O_HSFC_RXFIFOADD 0x1e /* 16-bit offset shifted right 3 */ + +/* Endpoint registers */ +#define MGC_O_HSFC_TXMAXP 0x00 +#define MGC_O_HSFC_TXCSR 0x02 +#define MGC_O_HSFC_CSR0 MGC_O_HSFC_TXCSR /* re-used for EP0 */ +#define MGC_O_HSFC_RXMAXP 0x04 +#define MGC_O_HSFC_RXCSR 0x06 +#define MGC_O_HSFC_RXCOUNT 0x08 +#define MGC_O_HSFC_COUNT0 MGC_O_HSFC_RXCOUNT /* re-used for EP0 */ + +/* + * MUSBHSFC Register bit masks + */ + +/* POWER */ + +#define MGC_M_POWER_ISOUPDATE 0x80 +#define MGC_M_POWER_SOFTCONN 0x40 +#define MGC_M_POWER_HSENAB 0x20 +#define MGC_M_POWER_HSMODE 0x10 +#define MGC_M_POWER_RESET 0x08 +#define MGC_M_POWER_RESUME 0x04 +#define MGC_M_POWER_SUSPENDM 0x02 +#define MGC_M_POWER_ENSUSPEND 0x01 + +/* Interrupt register bit masks */ +#define MGC_M_INTR_SUSPEND 0x01 +#define MGC_M_INTR_RESUME 0x02 +#define MGC_M_INTR_RESET 0x04 +#define MGC_M_INTR_SOF 0x08 + +/* TESTMODE */ + +#define MGC_M_TEST_FORCEFS 0x20 +#define MGC_M_TEST_FORCEHS 0x10 +#define MGC_M_TEST_PACKET 0x08 +#define MGC_M_TEST_K 0x04 +#define MGC_M_TEST_J 0x02 +#define MGC_M_TEST_SE0_NAK 0x01 + +/* allocate for double-packet buffering (effectively doubles assigned _SIZE) */ +#define MGC_M_FIFOSZ_DPB 0x10 +/* allocation size (8, 16, 32, ... 4096) */ +#define MGC_M_FIFOSZ_SIZE 0x0f + +/* CSR0 */ + +#define MGC_M_CSR0_P_SVDSETUPEND 0x0080 +#define MGC_M_CSR0_P_SVDRXPKTRDY 0x0040 +#define MGC_M_CSR0_P_SENDSTALL 0x0020 +#define MGC_M_CSR0_P_SETUPEND 0x0010 +#define MGC_M_CSR0_P_DATAEND 0x0008 +#define MGC_M_CSR0_P_SENTSTALL 0x0004 +#define MGC_M_CSR0_TXPKTRDY 0x0002 +#define MGC_M_CSR0_RXPKTRDY 0x0001 + +/* TXCSR */ + +#define MGC_M_TXCSR_AUTOSET 0x8000 +#define MGC_M_TXCSR_ISO 0x4000 +#define MGC_M_TXCSR_MODE 0x2000 +#define MGC_M_TXCSR_DMAENAB 0x1000 +#define MGC_M_TXCSR_FRCDATATOG 0x0800 +#define MGC_M_TXCSR_P_INCOMPTX 0x0080 +#define MGC_M_TXCSR_CLRDATATOG 0x0040 +#define MGC_M_TXCSR_P_SENTSTALL 0x0020 +#define MGC_M_TXCSR_P_SENDSTALL 0x0010 +#define MGC_M_TXCSR_FLUSHFIFO 0x0008 +#define MGC_M_TXCSR_P_UNDERRUN 0x0004 +#define MGC_M_TXCSR_FIFONOTEMPTY 0x0002 +#define MGC_M_TXCSR_TXPKTRDY 0x0001 + +/* RXCSR */ + +#define MGC_M_RXCSR_AUTOCLEAR 0x8000 +#define MGC_M_RXCSR_P_ISO 0x4000 +#define MGC_M_RXCSR_DMAENAB 0x2000 +#define MGC_M_RXCSR_DISNYET 0x1000 +#define MGC_M_RXCSR_DMAMODE 0x0800 +#define MGC_M_RXCSR_INCOMPRX 0x0100 +#define MGC_M_RXCSR_CLRDATATOG 0x0080 +#define MGC_M_RXCSR_P_SENTSTALL 0x0040 +#define MGC_M_RXCSR_P_SENDSTALL 0x0020 +#define MGC_M_RXCSR_FLUSHFIFO 0x0010 +#define MGC_M_RXCSR_DATAERR 0x0008 +#define MGC_M_RXCSR_P_OVERRUN 0x0004 +#define MGC_M_RXCSR_FIFOFULL 0x0002 +#define MGC_M_RXCSR_RXPKTRDY 0x0001 + +/* + * register access macros + */ + +/* Get offset for a given FIFO */ +#define MGC_FIFO_OFFSET(_bEnd) (MGC_M_FIFO_EP0 + (_bEnd * 4)) + +#endif /* multiple inclusion protection */ --- /dev/null +++ linux-2.6.20/drivers/usb/nomadik/nomadik_udc.c @@ -0,0 +1,2845 @@ +/* + * linux/drivers/usb/gadget/nomadik_udc.c + * + * Copyright 2007, STMicroelectronics + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +#undef DEBUG + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "musbdefs.h" +#include "nomadik_udc.h" +#include + + +/* + * This driver handles the USB Device Controller (UDC) in Nomadik + * series processors. + * There are fifteen endpoints, in addition to ep0. + * + * Such controller drivers work with a gadget driver. The gadget driver + * returns descriptors, implements configuration and data protocols used + * by the host to interact with this device, and allocates endpoints to + * the different protocol interfaces. The controller driver virtualizes + * usb hardware so that the gadget drivers will be more portable. + * + * This UDC hardware wants to implement a bit too much USB protocol, so + * it constrains the sorts of USB configuration change events that work. + */ + +/** + * Schedule a request for completion; executed @ IRQ time + * + * @param req_ptr the request to schedule for completition + * @param status the status to complete the request with + * @pre spinlock_is_locked; + */ +int udc_complete_request(struct usb_request *req_ptr, int status) +{ + DBG(4, "<==\n"); + req_ptr->status=status; + return complete_request(req_ptr); +} + +/** + * IOCTls for the gadget (not implemented yet) + * @param gadget the gadget + * @param code the IOCTL call code + * @param param the ioctl argument + * @return same as MUSB_HdrcServiceFunctionEp0 + */ +int udc_gadget_ioctl(struct usb_gadget *gadget, + unsigned code, unsigned long param) +{ + DBG(4, "<==\n" ); + return -EINVAL; +} + +/** + * Wake's up the device + * @param gadget the gadget + * @param code the IOCTL call code + * @param param the ioctl argument + * @return same as MUSB_HdrcServiceFunctionEp0 + */ +int udc_gadget_wakeup(struct usb_gadget *gadget) +{ + uint8_t power; + + u8 *base_addr = ( u8 *)udc_base_addr; + DBG(4, "<==\n" ); + + power = MUSB_READ8(base_addr, MUSB_O_HDRC_POWER); + power |= MUSB_M_POWER_RESUME; + MUSB_WRITE8(base_addr, MUSB_O_HDRC_POWER, power); + return 0; +} + +/** + * Current Frame number will be returned + * @param gadget the gadget + * @return Frame Number + */ +int udc_gadget_getframe(struct usb_gadget *gadget) +{ + return (int)MUSB_READ16(udc_base_addr, MUSB_O_HDRC_FRAME); +} + +/** + * Set the device power mode. + * @param gadget the gadget + * @param power state + * @return Frame Number + */ +int udc_gadget_setselfpowered(struct usb_gadget *gadget, + int is_selfpowered) +{ + DBG(4, "<==\n" ); + dev_context->is_selfpowered = (uint8_t)is_selfpowered; + return 0; +} + +/*-------------------------------------------------------------------------*/ + +/** + * Complete an usb request. + * @param req_ptr the request to complete. + * @return the request status + */ +int complete_request(struct usb_request *req_ptr) +{ + uint8_t bEnd; + + bEnd=((struct nomadik_req *)req_ptr)->end_number; + + if ( req_ptr->complete ) { + req_ptr->complete(&dev_context->end[bEnd].ep,req_ptr); + } + + DBG(3, "==> completed on bEnd=%d\n", bEnd); + return req_ptr->status; +} + +void done(struct nomadik_ep *ep, struct nomadik_req *req, int status) +{ + unsigned stopped = ep->stopped; + + list_del_init(&req->req.list); + + if (req->req.status == -EINPROGRESS) + req->req.status = status; + else + status = req->req.status; + + + if (use_dma && ep->has_dma) + { + if (req->mapped) + { + dma_unmap_single(ep->udc->gadget.dev.parent, + req->req.dma, req->req.length, + (ep->is_tx) + ? DMA_TO_DEVICE + : DMA_FROM_DEVICE); + req->req.dma = DMA_ADDR_INVALID; + req->mapped = 0; + } + else + { + dma_sync_single_for_cpu(ep->udc->gadget.dev.parent, + req->req.dma, req->req.length, + (ep->is_tx) + ? DMA_TO_DEVICE + : DMA_FROM_DEVICE); + } + } + +#ifndef USB_TRACE + /*if (status && status != -ESHUTDOWN)*/ +#endif + + + /* don't modify queue heads during completion callback */ + ep->stopped = 1; + spin_unlock(&ep->udc->lock); + if ( req->req.complete ) { + req->req.complete(&ep->ep,&req->req); + } + spin_lock(&ep->udc->lock); + ep->stopped = stopped; +} + + +/*-------------------------------------------------------------------------*/ + +/* dequeue ALL requests; caller holds udc->lock */ +void nuke(struct nomadik_ep *ep, int status) +{ + struct nomadik_req *req; + struct usb_request* req1; + ep->stopped = 1; + + req1 = udc_current_request(ep); + + if (use_dma && ep->dma_channel){ + dma_channel_release(ep); + } + + use_ep(ep); + + while (!list_empty(&ep->req_list)) + { + req = (struct nomadik_req*)list_entry(ep->req_list.next, struct usb_request, list); + done(ep, req, status); + } +} + +void use_ep(struct nomadik_ep *ep) +{ + u16 num = EP_NUMBER(ep); + u8 *base_addr = ( u8 *)udc_base_addr; + + MUSB_SELECTEND(base_addr, num); +} + +int nomadik_ep_enable(struct usb_ep *_ep, + const struct usb_endpoint_descriptor *desc) +{ + struct nomadik_ep *ep = container_of(_ep, struct nomadik_ep, ep); + struct nomadik_udc *udc; + unsigned long flags; + u16 maxp; + const uint8_t bEnd=EP_NUMBER(ep); + u8 *base_addr = (u8 *)udc_base_addr; + uint16_t intr_txe = 0; + uint16_t intr_rxe = 0; + + maxp = le16_to_cpu (desc->wMaxPacketSize); + +#ifdef USE_ISO + if ((desc->bmAttributes == USB_ENDPOINT_XFER_ISOC + && desc->bInterval != 1)) { + /* hardware wants period = 1; USB allows 2^(Interval-1) */ + ERR( "%s, unsupported ISO period %dms\n", _ep->name, + 1 << (desc->bInterval - 1)); + return -EDOM; + } +#else + if (desc->bmAttributes == USB_ENDPOINT_XFER_ISOC) { + DBG(2, "%s, ISO nyet\n", _ep->name); + return -EDOM; + } +#endif + + /* xfer types must match, except that interrupt ~= bulk */ + if (ep->bmAttributes != desc->bmAttributes + && ep->bmAttributes != USB_ENDPOINT_XFER_BULK + && desc->bmAttributes != USB_ENDPOINT_XFER_INT) { + ERR( "%s, %s type mismatch\n", __FUNCTION__, _ep->name); + return -EINVAL; + } + + udc = ep->udc; + if (!udc->driver || udc->gadget.speed == USB_SPEED_UNKNOWN) { + ERR( "%s, bogus device state\n", __FUNCTION__); + return -ESHUTDOWN; + } + + + ep->desc = desc; + ep->maxpacket = ep->ep.maxpacket = maxp; + ep->binactive = MUSB_GADGET_EP_ACTIVE; + ep->stopped=0; + + if (ep->bmAttributes == USB_ENDPOINT_XFER_ISOC) + list_add(&ep->iso, &udc->iso); + + spin_lock_irqsave(&udc->lock, flags); + use_ep(ep); + if ( desc->bEndpointAddress & USB_ENDPOINT_DIR_MASK ) { + intr_txe = MUSB_READ16(base_addr, MUSB_O_HDRC_INTRTXE); + intr_txe |= (1 <wMaxPacketSize); + } else { + intr_rxe = MUSB_READ16(base_addr, MUSB_O_HDRC_INTRRXE); + intr_rxe |= (1 <wMaxPacketSize); + } + + /* ep size might have been changed, flush the FIFOs */ + spin_lock_irqsave(&(dev_context->lock), flags); + intr_txe = MUSB_READ16(base_addr, MUSB_O_HDRC_INTRTXE); + MUSB_WRITE16(base_addr, MUSB_O_HDRC_INTRTXE, intr_txe & ~(1 << bEnd)); + + + if(bEnd) + { + uint16_t csr = MUSB_READCSR16(base_addr, MUSB_O_HDRC_TXCSR, (uint8_t)bEnd); + csr |= MUSB_M_TXCSR_FRCDATATOG; + MUSB_WRITECSR16(base_addr, MUSB_O_HDRC_TXCSR, (uint8_t)bEnd, csr); + MUSB_WRITECSR16(base_addr, MUSB_O_HDRC_TXCSR, (uint8_t)bEnd, csr); + /* tx flush fifo */ + csr = MUSB_READCSR16(base_addr, MUSB_O_HDRC_TXCSR, (uint8_t)bEnd); + csr |=MUSB_M_TXCSR_FLUSHFIFO ; + MUSB_WRITECSR16(base_addr, MUSB_O_HDRC_TXCSR, (uint8_t)bEnd, csr); + MUSB_WRITECSR16(base_addr, MUSB_O_HDRC_TXCSR, (uint8_t)bEnd, csr); + /* rx flush fifo */ + csr = MUSB_READCSR16(base_addr, MUSB_O_HDRC_RXCSR, (uint8_t)bEnd); + csr |= MUSB_M_RXCSR_FLUSHFIFO; + MUSB_WRITECSR16(base_addr, MUSB_O_HDRC_RXCSR, (uint8_t)bEnd, csr); + MUSB_WRITECSR16(base_addr, MUSB_O_HDRC_RXCSR, (uint8_t)bEnd, csr); + + } + else { + MUSB_WRITECSR16(base_addr, MUSB_O_HDRC_CSR0, 0, MUSB_M_CSR0_FLUSHFIFO); + } + + /* re-enable interrupt */ + MUSB_WRITE16(base_addr, MUSB_O_HDRC_INTRTXE, intr_txe); + spin_unlock_irqrestore(&(dev_context->lock), flags); + + if(bEnd){ + + if ( ep->is_tx ){ + /* clear_bulk_in_halt */ + uint16_t csr= MUSB_READCSR16(base_addr, MUSB_O_HDRC_TXCSR, bEnd); + csr &= ~MUSB_M_TXCSR_P_SENDSTALL; + MUSB_WRITECSR16(base_addr, MUSB_O_HDRC_TXCSR, bEnd, csr); + /* reset tx data toggle */ + csr =MUSB_READCSR16(base_addr, MUSB_O_HDRC_TXCSR, bEnd); + csr |=MUSB_M_TXCSR_CLRDATATOG; + MUSB_WRITECSR16(base_addr, MUSB_O_HDRC_TXCSR, bEnd, csr); + } + else{ + /* clear_bulk_out_halt */ + uint16_t csr = MUSB_READCSR16(base_addr, MUSB_O_HDRC_RXCSR, bEnd); + csr &= ~MUSB_M_RXCSR_P_SENDSTALL; + MUSB_WRITECSR16(base_addr, MUSB_O_HDRC_RXCSR, bEnd, csr); + /* reset rx data toggle */ + csr = MUSB_READCSR16(base_addr, MUSB_O_HDRC_RXCSR, bEnd); + csr |=MUSB_M_RXCSR_CLRDATATOG; + MUSB_WRITECSR16(base_addr, MUSB_O_HDRC_RXCSR, bEnd, csr); + } + } + else{ + /* clear ep0 halt */ + uint16_t csr = MUSB_READCSR16(base_addr, MUSB_O_HDRC_CSR0,MUSB_M_CSR0_P_SENDSTALL); + csr &= ~MUSB_M_CSR0_P_SENDSTALL; + MUSB_WRITECSR16(base_addr, MUSB_O_HDRC_CSR0,0, csr); + } + + spin_unlock_irqrestore(&udc->lock, flags); + DBG(3,"%s enabled\n", _ep->name); + return 0; +} + +int nomadik_ep_disable(struct usb_ep *_ep) +{ + struct nomadik_ep *ep = container_of(_ep, struct nomadik_ep, ep); + unsigned long flags; + u8 *base_addr = ( u8 *)udc_base_addr; + const struct usb_endpoint_descriptor *desc = (const struct usb_endpoint_descriptor *)ep->desc; + uint8_t bEnd = EP_NUMBER(ep); + + if (!ep || !ep->desc) { + DBG(3, "%s, %s not enabled\n", __FUNCTION__, + ep ? ep->ep.name : NULL); + return -EINVAL; + } + + + spin_lock_irqsave(&ep->udc->lock, flags); + + if ( desc->bEndpointAddress & USB_ENDPOINT_DIR_MASK ) { + uint16_t intr_txe = MUSB_READ16(base_addr, MUSB_O_HDRC_INTRTXE); + intr_txe&= ~(1 <udc->lock, flags); + ep->desc = NULL; + nuke (ep, -ESHUTDOWN); + ep->ep.maxpacket = ep->maxpacket; + ep->binactive = MUSB_GADGET_EP_DISABLED; + + if (ep->bmAttributes == USB_ENDPOINT_XFER_ISOC) + list_del_init(&ep->iso); + + + DBG(4,"%s disabled\n", _ep->name); + return 0; +} + +/*-------------------------------------------------------------------------*/ + +struct usb_request * +nomadik_alloc_request(struct usb_ep *ep, gfp_t gfp_flags) +{ + struct nomadik_req *req; + + + req = (struct nomadik_req *)kzalloc(sizeof *req, gfp_flags); + DBG(4, "==> allocated request at %p for ep %d\n", req, \ + EP_NUMBER(ep)); + if (req) { + req->req.dma = DMA_ADDR_INVALID; + INIT_LIST_HEAD(&req->req.list); + req->end_number = EP_NUMBER(ep); + + } + return &req->req; +} + +void +nomadik_free_request(struct usb_ep *ep, struct usb_request *_req) +{ + struct nomadik_req *req = container_of(_req, struct nomadik_req, req); + + if (_req) + kfree (req); +} + +/*-------------------------------------------------------------------------*/ + +void * +nomadik_alloc_buffer( + struct usb_ep *_ep, + unsigned bytes, + dma_addr_t *dma, + gfp_t gfp_flags + ) +{ + void *retval; + struct nomadik_ep *ep; + + ep = container_of(_ep, struct nomadik_ep, ep); + if (use_dma && ep->has_dma) { + static int warned; + if (!warned && bytes < PAGE_SIZE) { + dev_warn(ep->udc->gadget.dev.parent, + "using dma_alloc_coherent for " + "small allocations wastes memory\n"); + warned++; + } + return dma_alloc_coherent(ep->udc->gadget.dev.parent, + bytes, dma, gfp_flags); + } + + retval = kmalloc(bytes, gfp_flags); + if (retval) + *dma = virt_to_phys(retval); + return retval; +} + +void nomadik_free_buffer( + struct usb_ep *_ep, + void *buf, + dma_addr_t dma, + unsigned bytes + ) +{ + struct nomadik_ep *ep; + + ep = container_of(_ep, struct nomadik_ep, ep); + if (use_dma && _ep && ep->has_dma) + dma_free_coherent(ep->udc->gadget.dev.parent, bytes, buf, dma); + else + kfree (buf); +} + + + +/*-------------------------------------------------------------------------*/ + +int queue_length(struct list_head *lh) { + int count=0; + struct list_head *p=lh; + + while ( p && (p->next!=lh) ) { + count++; + p=p->next; + } + + return count; +} + + + + +char* dump_usb_request(struct usb_request *req) { + static char buff[256]; + if ( req ) { + sprintf(buff, "req=%p, req->request.length=0x%0x, req->request.zero=0x%x, " + "req->request.actual=0x%x, req->request.status=%d", + req, req->length, req->zero, req->actual, req->status ); + } else { + sprintf(buff, "null request"); + } + + return buff; +} + +/** + * Set clear the halt bit of an endpoint. A halted enpoint won't tx/rx any + * data but will queue requests. + * @param ep the endpoint + * @param value != 0 => halt, 0 == active + */ +int nomadik_ep_set_halt(struct usb_ep *_ep, int value) +{ + struct nomadik_ep *ep = container_of(_ep, struct nomadik_ep, ep); + uint16_t csr; + unsigned long flags; + const uint8_t bEnd=EP_NUMBER(ep); + u8 *base_addr = ( u8 *)udc_base_addr; + struct nomadik_req *req_ptr; + + DBG(4, "<== end=%d, value=%d\n", bEnd, value); + + spin_lock_irqsave(&dev_context->lock, flags); + MUSB_SELECTEND(base_addr, bEnd ); + if ( 0==bEnd ) + { + /* end 0 should never stall! */ + csr = MUSB_READCSR16(base_addr, MUSB_O_HDRC_CSR0, 0); + if ( value ) + { + csr |= MUSB_M_CSR0_P_SENDSTALL; + } else + { + csr &= ~MUSB_M_CSR0_P_SENDSTALL; + } + + MUSB_WRITECSR16(base_addr, MUSB_O_HDRC_CSR0, 0, csr); + spin_unlock_irqrestore(&dev_context->lock, flags ); + return 0; + } + + /* prevent further request to be executed, this will prevent next + * request to be scheduled oin the completiotion of the current + * one + */ + ep->binactive=(value) + ? MUSB_GADGET_EP_HALTED + : MUSB_GADGET_EP_ACTIVE; + + if ( value ) + DBG(4, "<== end halted=%d\n", bEnd); + else + DBG(4, "<== end activated=%d,d\n", bEnd); + + /* cannot abort the current request if the FIFO is full */ + req_ptr=(struct nomadik_req*)udc_current_request(ep); + if ( value && ep->is_tx ) + { + csr = MUSB_READCSR16(base_addr, MUSB_O_HDRC_TXCSR, bEnd); + if ( csr & MUSB_M_TXCSR_FIFONOTEMPTY ) { + spin_unlock_irqrestore(&dev_context->lock, flags); + return -EAGAIN; + } + + } + /* set/clear the stall bit */ + if ( ep->is_tx ) + { + if ( value ) + { + csr = MUSB_READCSR16(base_addr, MUSB_O_HDRC_TXCSR, bEnd); + csr |= MUSB_M_TXCSR_P_SENDSTALL; + MUSB_WRITECSR16(base_addr, MUSB_O_HDRC_TXCSR, bEnd, csr) + } + else + { + csr= MUSB_READCSR16(base_addr, MUSB_O_HDRC_TXCSR, bEnd); + csr &= ~MUSB_M_TXCSR_P_SENDSTALL; + MUSB_WRITECSR16(base_addr, MUSB_O_HDRC_TXCSR, bEnd, csr); + /* reset tx data toggle */ + csr =MUSB_READCSR16(base_addr, MUSB_O_HDRC_TXCSR, bEnd); + csr |=MUSB_M_TXCSR_CLRDATATOG; + MUSB_WRITECSR16(base_addr, MUSB_O_HDRC_TXCSR, bEnd, csr); + } + + } + else + { + if( value ) + { + csr = MUSB_READCSR16(base_addr, MUSB_O_HDRC_RXCSR, bEnd); + csr |= MUSB_M_RXCSR_P_SENDSTALL; + MUSB_WRITECSR16(base_addr, MUSB_O_HDRC_RXCSR, bEnd, csr); + + } + else + { + csr = MUSB_READCSR16(base_addr, MUSB_O_HDRC_RXCSR, bEnd); + csr &= ~MUSB_M_RXCSR_P_SENDSTALL; + MUSB_WRITECSR16(base_addr, MUSB_O_HDRC_RXCSR, bEnd, csr); + /* reset rx data toggle */ + csr = MUSB_READCSR16(base_addr, MUSB_O_HDRC_RXCSR, bEnd); + csr |=MUSB_M_RXCSR_CLRDATATOG; + MUSB_WRITECSR16(base_addr, MUSB_O_HDRC_RXCSR, bEnd, csr); + } + + } + + spin_unlock_irqrestore(&dev_context->lock, flags); + + /* the ep has been re-activated, re-start the request if one + * is pending*/ + if ( !value && req_ptr ) + { + DBG(3, "restarting the request\n"); + udc_restart_request(dev_context, (struct usb_request*)req_ptr); + } + + DBG(4, "==>\n" ); + return 0; +} + +void nomadik_release_udc(void) +{ + if ( dev_context ) + { + if ( dev_context->end0_buffer_ptr) + kfree(dev_context->end0_buffer_ptr); + kfree(dev_context); + } + return; +} + +int alloc_n_config_udc(void) +{ + dev_context = kzalloc(sizeof(*dev_context), GFP_KERNEL); + if ( !dev_context ) { + ERR("Error in allocating private /*struct*/ure dev_context\n"); + return -ENOMEM; + } + + dev_context->end0_buffer_ptr = kzalloc(sizeof(struct t_udc_end0_buffer), GFP_KERNEL); + if ( !dev_context->end0_buffer_ptr ){ + kfree(dev_context); + ERR("Error in allocating end0 buffer\n"); + return -ENOMEM; + } + + spin_lock_init(&dev_context->lock); + return 0; +} + + + +/* Before this controller can enumerate, we need to pick an endpoint + * configuration, or "fifo_mode" That involves allocating 2KB of packet + * buffer space among the endpoints we'll be operating. + * + */ +unsigned __init nomadik_ep_setup(char *name, u8 dir, u8 type, + unsigned buf, unsigned maxp, int dbuf) +{ + struct nomadik_ep *ep; + u16 epn_rxtx = 0; + u8 ep_index = dev_context->end_count; + u8 *base_addr = (u8 *)udc_base_addr; + + dev_context->end_count++; + dev_context->end_mask |= 1 << ep_index; + ep = &dev_context->end[ep_index]; + MUSB_SELECTEND(base_addr, ep_index); + + /* chip setup ... bit values are same for IN, OUT */ + switch (maxp) { + case 8: epn_rxtx = 0 ; break; + case 16: epn_rxtx = 1 ; break; + case 32: epn_rxtx = 2 ; break; + case 64: epn_rxtx = 3 ; break; + case 128: epn_rxtx = 4 ; break; + case 256: epn_rxtx = 5 ; break; + case 512: epn_rxtx = 6 ; break; + default: ERR("Invalid max pkt size\n"); + } + if (dbuf && ep_index){ + DBG(3, "dbe enabled for %d\n",ep_index); + epn_rxtx |= 0x10; + } + +#if 0 + init_timer(&ep->timer); + ep->timer.function = pio_out_timer; + ep->timer.data = (unsigned long) ep; +#endif + + DBG(3, "%s addr %02x rxtx %04x maxp %d%s buf %d\n", + name, dir, epn_rxtx, maxp, dbuf ? "x2" : "", buf); + + if ( ep_index) { + if (dir & USB_DIR_IN) + { + MUSB_WRITE8(base_addr, MUSB_O_HDRC_TXFIFOSZ, epn_rxtx); + MUSB_WRITE16(base_addr, MUSB_O_HDRC_TXFIFOADD, buf >> 3); + ep->is_tx = 1; + } + else + { + MUSB_WRITE8(base_addr, MUSB_O_HDRC_RXFIFOSZ, epn_rxtx); + MUSB_WRITE16(base_addr, MUSB_O_HDRC_RXFIFOADD, buf >> 3); + ep->is_tx = 0; + } + } + + /* next endpoint's buffer starts after this one's */ + buf += maxp; + if (dbuf) + buf += maxp; + BUG_ON(buf > 2048); + + /* set up driver data structures */ + BUG_ON(strlen(name) >= sizeof ep->name); + strlcpy(ep->name, name, sizeof ep->name); + INIT_LIST_HEAD(&ep->req_list); + INIT_LIST_HEAD(&ep->iso); + ep->end_number = ep_index; + ep->bmAttributes = type; + ep->double_buf = dbuf; + ep->udc = dev_context; + ep->has_dma = 0; + + ep->ep.name = ep->name; + ep->ep.ops = &nomadik_ep_ops; + ep->ep.maxpacket = ep->maxpacket = maxp; + list_add_tail (&ep->ep.ep_list, &dev_context->gadget.ep_list); + ep->binactive = MUSB_GADGET_EP_DISABLED; + + return buf; +} + +void nomadik_udc_release(struct device *dev) +{ + complete(dev_context->done); + kfree (dev_context); + dev_context = NULL; +} + + +int __init udc_setup(void) +{ + unsigned buf; + + spin_lock_init( &udc_scheduler_queue.lock ); + INIT_LIST_HEAD( &udc_scheduler_queue.req_list ); + + INIT_LIST_HEAD(&dev_context->iso); + + dev_context->gadget.ops = &nomadik_gadget_ops; + dev_context->gadget.ep0 = &dev_context->end[0].ep; + INIT_LIST_HEAD(&dev_context->gadget.ep_list); + dev_context->gadget.speed = USB_SPEED_UNKNOWN; + dev_context->gadget.name = driver_name; + + device_initialize(&dev_context->gadget.dev); + strcpy (dev_context->gadget.dev.bus_id, "gadget"); + dev_context->gadget.dev.release = nomadik_udc_release; + dev_context->gadget.dev.parent = NULL; + + dev_context->end_count = 0; + dev_context->end_mask = 0; + /* + ep0 is special; put it right after the SETUP buffer + */ + buf = nomadik_ep_setup("ep0",0, USB_ENDPOINT_XFER_CONTROL, + 0 /* after SETUP */, 64 /* maxpacket */, 0); + list_del_init(&dev_context->end[0].ep.ep_list); + + +#define NOMADIK_BULK_EP(name,dir) \ + buf = nomadik_ep_setup(name "-bulk", dir, \ + USB_ENDPOINT_XFER_BULK, buf,512, 0); +#define NOMADIK_INT_EP(name,dir, maxp) \ + buf = nomadik_ep_setup(name "-int", dir, \ + USB_ENDPOINT_XFER_INT,buf, maxp, 0); +#define NOMADIK_ISO_EP(name,dir, maxp) \ + buf = nomadik_ep_setup(name "-iso", dir, \ + USB_ENDPOINT_XFER_ISOC, buf, maxp, 0); + + switch (fifo_mode) { + case 0: + NOMADIK_BULK_EP("ep1in", USB_DIR_IN ); + NOMADIK_BULK_EP("ep2out", USB_DIR_OUT ); + NOMADIK_INT_EP("ep3in", USB_DIR_IN , 16); + break; + case 1: + NOMADIK_BULK_EP("ep1in", USB_DIR_IN ); + NOMADIK_BULK_EP("ep2out", USB_DIR_OUT ); + NOMADIK_INT_EP("ep9in", USB_DIR_IN , 16); + + NOMADIK_BULK_EP("ep3in", USB_DIR_IN ); + NOMADIK_BULK_EP("ep4out", USB_DIR_OUT ); + NOMADIK_INT_EP("ep10in", USB_DIR_IN , 16); + + NOMADIK_BULK_EP("ep5in", USB_DIR_IN ); + NOMADIK_BULK_EP("ep5out", USB_DIR_OUT ); + NOMADIK_INT_EP("ep11in", USB_DIR_IN , 16); + + NOMADIK_BULK_EP("ep6in", USB_DIR_IN ); + NOMADIK_BULK_EP("ep6out", USB_DIR_OUT ); + NOMADIK_INT_EP("ep12in", USB_DIR_IN , 16); + + NOMADIK_BULK_EP("ep7in", USB_DIR_IN ); + NOMADIK_BULK_EP("ep7out", USB_DIR_OUT ); + NOMADIK_INT_EP("ep13in", USB_DIR_IN , 16); + NOMADIK_INT_EP("ep13out", USB_DIR_OUT , 16); + + NOMADIK_BULK_EP("ep8in", USB_DIR_IN ); + NOMADIK_BULK_EP("ep8out", USB_DIR_OUT ); + NOMADIK_INT_EP("ep14in", USB_DIR_IN , 16); + NOMADIK_INT_EP("ep14out", USB_DIR_OUT , 16); + + NOMADIK_BULK_EP("ep15in", USB_DIR_IN ); + NOMADIK_BULK_EP("ep15out", USB_DIR_OUT ); + + break; + +#ifdef USE_ISO + case 2: /* mixed iso/bulk */ + NOMADIK_ISO_EP("ep1in", USB_DIR_IN , 256); + NOMADIK_ISO_EP("ep2out", USB_DIR_OUT , 256); + NOMADIK_ISO_EP("ep3in", USB_DIR_IN , 128); + NOMADIK_ISO_EP("ep4out", USB_DIR_OUT , 128); + + NOMADIK_INT_EP("ep5in", USB_DIR_IN , 16); + + NOMADIK_BULK_EP("ep6in", USB_DIR_IN ); + NOMADIK_BULK_EP("ep7out", USB_DIR_OUT ); + NOMADIK_INT_EP("ep8in", USB_DIR_IN , 16); + break; + case 3: /* mixed bulk/iso */ + NOMADIK_BULK_EP("ep1in", USB_DIR_IN ); + NOMADIK_BULK_EP("ep2out", USB_DIR_OUT ); + NOMADIK_INT_EP("ep3in", USB_DIR_IN , 16); + + NOMADIK_BULK_EP("ep4in", USB_DIR_IN ); + NOMADIK_BULK_EP("ep5out", USB_DIR_OUT ); + NOMADIK_INT_EP("ep6in", USB_DIR_IN , 16); + + NOMADIK_ISO_EP("ep7in", USB_DIR_IN , 256); + NOMADIK_ISO_EP("ep8out", USB_DIR_OUT , 256); + NOMADIK_INT_EP("ep9in", USB_DIR_IN , 16); + break; +#endif + + /* add more modes as needed */ + + default: + ERR("unsupported fifo_mode #%d\n", fifo_mode); + return -ENODEV; + } + return 0; +} + +void udc_intr_disable(void) +{ + u8 *base_addr = ( u8 *)udc_base_addr; + DBG(4,"\n"); + + MUSB_WRITE8(base_addr, MUSB_O_HDRC_INTRUSBE, 0x0); + MUSB_WRITE16(base_addr, MUSB_O_HDRC_INTRTXE, 0x0); + MUSB_WRITE16(base_addr, MUSB_O_HDRC_INTRRXE, 0x0); +} + + +void udc_reset() +{ + volatile u8 *base_addr = ( u8 *)udc_base_addr; + uint8_t power; + uint16_t top; + + + MUSB_WRITE16(base_addr, MUSB_O_HDRC_TOPCONTROL, MUSB_MODE_ULPI); + top = MUSB_READ16(base_addr, MUSB_O_HDRC_TOPCONTROL); + + MUSB_WRITE16(base_addr, MUSB_O_HDRC_TOPCONTROL,( top | MUSB_MODE_SRST)); + + power = MUSB_READ8(base_addr, MUSB_O_HDRC_POWER); + /* Enabling high speed */ + power = power |(MUSB_M_POWER_HSENAB); + /* disabling high speed */ + MUSB_WRITE8(base_addr, MUSB_O_HDRC_POWER, power | MUSB_M_POWER_SOFTCONN); +} + +/* ---------------------------------------------------------------------- */ + +/** + * Identifies a transmit request. + * @param control_request_ptr the control request + * @return true for USB_REQ_GET_CONFIGURATION, USB_REQ_GET_INTERFACE, + * USB_REQ_GET_DESCRIPTOR, USB_REQ_GET_STATUS, USB_REQ_SYNC_FRAME + */ +uint8_t is_tx_request(const struct usb_ctrlrequest *control_request_ptr) { + return ( control_request_ptr->bRequestType & USB_DIR_IN ); +} + +/** + * Identifies a zero data request. + * @param control_request_ptr the control request + * @return true for USB_REQ_SET_INTERFACE, USB_REQ_SET_CONFIGURATION, + * USB_REQ_SET_ADDRESS, USB_REQ_CLEAR_FEATURE, USB_REQ_SET_FEATURE + * + */ +uint8_t is_zerodata_request(const struct usb_ctrlrequest *control_request_ptr) { + return ( 0==control_request_ptr->wLength ) && !is_tx_request(control_request_ptr); +} + +/** + * Identifies a receive request. + * @param control_request_ptr the control request + * @return true for USB_REQ_SET_DESCRIPTOR + */ +uint8_t is_rx_request(const struct usb_ctrlrequest *control_request_ptr) { + return control_request_ptr->bRequest==USB_REQ_SET_DESCRIPTOR; +} + +/** + * Load FIFO + * + * @param base_ptr base address of HDRC + * @param bEnd local endpoint + * @param wcount how many bytes to load + * @param pSource data buffer + */ +void udc_load_fifo(const uint8_t* base_ptr, uint8_t bEnd, + uint16_t wcount, const uint8_t* pSource) +{ + uint16_t windex, windex32; + uint16_t wcount32 = wcount >> 2; + uint8_t fifo_offset = MUSB_FIFO_OFFSET(bEnd); + DBG(3, "base_ptr=%p, bEnd=%d, wcount=0x%04x, pSrc=%p\n", + base_ptr, bEnd, wcount, pSource); + +#ifdef MUSB_PARANOID + if ( IS_INVALID_ADDRESS(pSource) ) + { + ERR("loading fifo from a null buffer; why did u do that????\n"); + return; + } +#endif + + + for(windex =0, windex32 = 0; windex32 < wcount32; windex32++, windex += 4) + { + MUSB_WRITE32(base_ptr, fifo_offset, *((uint32_t*)&(pSource[windex]))); + } + + for(; windex < wcount; windex++) + { + MUSB_WRITE8(base_ptr, fifo_offset, pSource[windex]); + } + +} + +/** + * Unload an HDRC FIFO + * + * @param base_ptr base address of HDRC + * @param bEnd local endpoint + * @param wcount how many bytes to unload + * @param dest_ptr data buffer + */ +void udc_unload_fifo(const uint8_t* base_ptr, uint8_t bEnd, + uint16_t wcount, uint8_t* dest_ptr) +{ + uint16_t windex=0; + uint16_t windex32=0; + uint16_t wcount32 = wcount >> 2; + uint8_t fifo_offset = MUSB_FIFO_OFFSET(bEnd); + + +#ifdef MUSB_PARANOID + if ( IS_INVALID_ADDRESS(dest_ptr) ) { + ERR("unloading fifo from a null buffer\n"); + return; + } +#endif + + DBG(3, "base_ptr=%p, bEnd=%d, wcount=0x%04x, dest_ptr=%p\n", base_ptr, bEnd, + wcount, dest_ptr); + + for(windex = 0, windex32 = 0; windex32 < wcount32; windex32++, windex += 4) { + *((uint32_t*)&(dest_ptr[windex])) = MUSB_READ32(base_ptr, fifo_offset); + } + + while(windex < wcount) { + dest_ptr[windex++]=MUSB_READ8(base_ptr, fifo_offset); + } +} + + +/* ---------------------------------------------------------------------- */ + +/** + * Forward a request to the driver. + * + * FROM: usb_gadget.h + * Accordingly, the driver's setup() callback must always implement all + * get_descriptor requests, returning at least a device descriptor and + * a configuration descriptor. Drivers must make sure the endpoint + * descriptors match any hardware constraints. Some hardware also constrains + * other descriptors. (The pxa250 allows only configurations 1, 2, or 3). + * + * The driver's setup() callback must also implement set_configuration, + * and should also implement set_interface, get_configuration, and + * get_interface. Setting a configuration (or interface) is where + * endpoints should be activated or (config 0) shut down. + * + * @param control_request_ptr the usb control request to forward to the driver + */ +int forward_to_driver(const struct usb_ctrlrequest *control_request_ptr) +{ + int handled=-EOPNOTSUPP; + DBG(3, "<== dev_context->driver=%p, control_request_ptr=%p\n", + dev_context->driver, control_request_ptr); + +#ifdef MUSB_PARANOID + ASSERT_SPINLOCK_UNLOCKED(&dev_context->lock); + ASSERT_SPINLOCK_UNLOCKED(&dev_context->end[0]); +#endif + + if ( dev_context->driver ){ + DBG(1, "calling mrt_setup\n"); + handled=dev_context->driver->setup(&dev_context->gadget, + control_request_ptr); + } + else + { + ERR("Error case\n"); + } + + DBG(4, "==> handled=%d\n", handled); + return handled; +} + +/* ---------------------------------------------------------------------- */ + +/** + * Service a receive request. Currently forward to the driver. + * @param control_request_ptr the usb control request to service. + * @see is_rx_request + */ +int service_rx_request(struct usb_ctrlrequest *control_request_ptr) +{ +#ifdef MUSB_PARANOID + ASSERT_SPINLOCK_UNLOCKED(&dev_context->lock); + ASSERT_SPINLOCK_UNLOCKED(&dev_context->end[0]); +#endif + return forward_to_driver(control_request_ptr); +} + +/** + * Service a transmit request. + * @param control_request_ptr the request to service + * @see is_tx_request + */ +void service_tx_status_request(const struct usb_ctrlrequest *control_request_ptr) { + uint8_t handled=1; + uint8_t bResult[2], bEnd=0; + uint16_t csrval; + const uint8_t* base_addr = (uint8_t*)udc_base_addr; + const uint8_t bRecip=control_request_ptr->bRequestType + & USB_RECIP_MASK; + + /* ack the request */ + DBG(3, "acking request %s\n", decode_csr0(MUSB_M_CSR0_P_SVDRXPKTRDY) ); + spin_lock(&dev_context->lock); + MUSB_SELECTEND(base_addr, 0); + MUSB_WRITECSR16(base_addr, MUSB_O_HDRC_CSR0, 0, + MUSB_M_CSR0_P_SVDRXPKTRDY); + spin_unlock(&dev_context->lock); + + switch(bRecip) { + case USB_RECIP_DEVICE: + DBG(1, "USB_RECIP_DEVICE()\n"); + bResult[0] = dev_context->is_selfpowered ? 1 : 0; + bResult[0] |= 2; + bResult[1] = 0; + udc_load_fifo(base_addr, 0, 2, (uint8_t*)&bResult); + csrval = MUSB_M_CSR0_TXPKTRDY | MUSB_M_CSR0_P_DATAEND; + MUSB_WRITECSR16(base_addr, MUSB_O_HDRC_CSR0, 0, csrval); + break; + + case USB_RECIP_ENDPOINT: + { + uint16_t wTest; + + DBG(1, "USB_RECIP_ENDPOINT()\n"); + bEnd = (uint8_t)control_request_ptr->wIndex; + spin_lock(&dev_context->lock); + MUSB_SELECTEND(base_addr, bEnd); + /* in EP */ + if(bEnd & 0x80) + { + wTest = MUSB_READCSR16(base_addr, MUSB_O_HDRC_TXCSR, bEnd); + bResult[0] = (wTest & MUSB_M_TXCSR_P_SENDSTALL) ? 1 : 0; + } + else + { + wTest = MUSB_READCSR16(base_addr, MUSB_O_HDRC_RXCSR, bEnd); + bResult[0] = (wTest & MUSB_M_RXCSR_P_SENDSTALL) ? 1 : 0; + } + + MUSB_SELECTEND(base_addr, 0); + bResult[1] = 0; + udc_load_fifo(base_addr, 0, 2, (uint8_t*)&bResult); + csrval = MUSB_M_CSR0_TXPKTRDY | MUSB_M_CSR0_P_DATAEND; + MUSB_WRITECSR16(base_addr, MUSB_O_HDRC_CSR0, 0, csrval); + spin_unlock(&dev_context->lock); + } break; + + default: + handled=0; + break; + } + + /* send it out! (this will trigger the ep0 completition IRQ) + * serviced in interrupt_complete() + */ + if ( handled ) { + dev_context->end0_stage=MUSB_END0_STAGE_STATUSOUT; + + spin_lock(&dev_context->lock); + MUSB_SELECTEND(base_addr, bEnd); + MUSB_WRITECSR16(base_addr, MUSB_O_HDRC_CSR0, 0, + MUSB_M_CSR0_TXPKTRDY | MUSB_M_CSR0_P_DATAEND); + spin_unlock(&dev_context->lock); + } +} + +/** + * Service a transmit a request. End0 buffer contains the current + * request (a standard control request). Assumes the fifo to be at least + * bytes long. Requests handled here are: USB_REQ_GET_CONFIGURATION, + * USB_REQ_GET_INTERFACE, USB_REQ_GET_DESCRIPTOR, USB_REQ_GET_STATUS, + * USB_REQ_SYNC_FRAME. + * + * @param control_request_ptr the request to service + * @return 0 if the request was NOT HANDLED, < 0 when error (ENOSUPP not + * supprorted), > 0 when the request is processed + * @see is_tx_request + */ +int service_tx_request(const struct usb_ctrlrequest *control_request_ptr) +{ + int handled=0; /* not handled */ +#ifdef MUSB_PARANOID + ASSERT_SPINLOCK_UNLOCKED(&dev_context->lock); + ASSERT_SPINLOCK_UNLOCKED(&dev_context->end[0]); +#endif + + if ( USB_TYPE_STANDARD!=(control_request_ptr->bRequestType&USB_TYPE_MASK )) { + return forward_to_driver(control_request_ptr); + } + switch(control_request_ptr->bRequest) { + case USB_REQ_GET_CONFIGURATION: + DBG(1, "USB_REQ_GET_CONFIGURATION()\n"); + break; + + case USB_REQ_GET_INTERFACE: + DBG(1, "USB_REQ_GET_INTERFACE()\n"); + break; + + case USB_REQ_GET_DESCRIPTOR: + DBG(1, "USB_REQ_GET_DESCRIPTOR()\n"); + break; + + case USB_REQ_GET_STATUS: { + DBG(1, "USB_REQ_GET_STATUS()\n"); + service_tx_status_request(control_request_ptr); + handled = 1; + } break; + +/* case USB_REQ_SYNC_FRAME: + break; */ + + default: + break; + } + + if ( !handled ) { + handled=forward_to_driver(control_request_ptr); + } + + /* now tx! */ + return handled; +} + +/** + * Service a zero data request. + * Called for USB_REQ_SET_INTERFACE, USB_REQ_SET_CONFIGURATION, + * USB_REQ_SET_ADDRESS, USB_REQ_CLEAR_FEATURE, USB_REQ_SET_FEATURE. + * + * @param dev_context the controller instance + * @param control_request_ptr the control request to service. + * @warning USB_REQ_SET_ADDRESS should be executed QUICKLY + * @see is_zerodata_request + */ +int service_zero_data_request(struct nomadik_udc* dev_context, + struct usb_ctrlrequest *control_request_ptr) +{ + + int handled=1; /* handled, DO NOT not pass down */ + const uint8_t* base_addr = (uint8_t*)udc_base_addr; + const uint8_t bRecip=control_request_ptr->bRequestType + & USB_RECIP_MASK; + + DBG(4, "<==\n"); + +#ifdef MUSB_PARANOID + ASSERT_SPINLOCK_UNLOCKED(&dev_context->lock); + ASSERT_SPINLOCK_UNLOCKED(&dev_context->end[0]); +#endif + + /* non standard requests are piped to the gadget */ + if ( USB_TYPE_STANDARD!=(control_request_ptr->bRequestType&USB_TYPE_MASK )) { + return forward_to_driver(control_request_ptr); + } + + /* zero data phase */ + switch (control_request_ptr->bRequest) { + + case USB_REQ_SET_INTERFACE: + DBG(1, "USB_REQ_SET_INTERFACE()\n"); + handled=0; /* pass it to the gadget */ + break; + + case USB_REQ_SET_CONFIGURATION: + + /* remember state & handle on the end status stage interrupt */ + DBG(1, "USB_REQ_SET_CONFIGURATION()\n"); + dev_context->set_config_flag = 1; + handled=0; /* pass it to the gadget */ + break; + + case USB_REQ_SET_ADDRESS: + /* remember state & handle on the end status stage interrupt */ + DBG(1, "USB_REQ_SET_ADDRESS(0x%x)\n",(uint8_t) + (control_request_ptr->wValue & 0x7f)); + + dev_context->set_address_flag = 1; + dev_context->address = (uint8_t)(control_request_ptr->wValue & 0x7f); + break; + + case USB_REQ_CLEAR_FEATURE: + DBG(1, "USB_REQ_CLEAR_FEATURE()\n"); + + switch(bRecip) { + case USB_RECIP_DEVICE: + DBG(3, "USB_RECIP_DEVICE()\n"); + break; + case USB_RECIP_INTERFACE: + DBG(3, "USB_RECIP_INTERFACE()\n"); + break; + case USB_RECIP_ENDPOINT: + { + const uint8_t bEnd = (uint8_t)control_request_ptr->wIndex & 0x7f ; + struct nomadik_ep* end_ptr=&dev_context->end[ bEnd ]; + + DBG(-1, "CLEAR_FEATURE: USB_RECIP_ENDPOINT() %d\n", bEnd ); + nomadik_ep_set_halt( &end_ptr->ep, 0); + /* select ep0 again */ + MUSB_SELECTEND(base_addr, 0); + } break; + default: + break; + } + break; /* END: CLEAR_FEATURE */ + + case USB_REQ_SET_FEATURE: + DBG(3, "USB_REQ_SET_FEATURE()\n"); + switch(bRecip) { + case USB_RECIP_DEVICE: + DBG(3, "USB_RECIP_DEVICE()\n"); + switch(control_request_ptr->wValue) { + case 1: + DBG(3, "REMOTE_WAKEUP()\n"); + while (0) { } /* remote wakeup */ + break; + case 2: + if (control_request_ptr->wIndex & 0xff) { + handled=-EINVAL; + } else { + uint16_t wTest; + + DBG(3, "ENTERING TESTMODE\n"); + dev_context->test_mode_flag = 1; + wTest = (uint8_t)control_request_ptr->wIndex >> 8; + switch(wTest) { + case 1: + DBG(3, "TEST_J\n"); + /* TEST_J */ + dev_context->test_mode_value = MUSB_M_TEST_J; + break; + case 2: + /* TEST_K */ + DBG(3, "TEST_K\n"); + dev_context->test_mode_value = MUSB_M_TEST_K; + break; + case 3: + /* TEST_SE0_NAK */ + DBG(3, "TEST_SE0_NAK\n"); + dev_context->test_mode_value = MUSB_M_TEST_SE0_NAK; + break; + case 4: + /* TEST_PACKET */ + DBG(3, "TEST_PACKET\n"); + dev_context->test_mode_value = MUSB_M_TEST_PACKET; + break; + default: + /* my gadget might know what to do with it */ + break; + } + } + break; + case 3: + printk("set feature enabled\n"); + b_hnp_suspend = 1; + break; + case 4: + break; + case 5: + break; + + } + break; + + case USB_RECIP_INTERFACE: + DBG(3, "USB_RECIP_INTERFACE()\n"); + break; + + case USB_RECIP_ENDPOINT: + { + const uint8_t bEnd = (uint8_t)control_request_ptr->wIndex & 0x7f ; + struct nomadik_ep* end_ptr=&dev_context->end[ bEnd ]; + + DBG(3, "SET_FEATURE: USB_RECIP_ENDPOINT() %d\n", bEnd ); + nomadik_ep_set_halt(&end_ptr->ep, 1); + + /* select ep0 again */ + MUSB_SELECTEND(base_addr, 0); + } break; + + } + break; /* END: SET_FEATURE */ + + default: + handled=0; + break; + } + + /* standard request not handed by this code go to the gadget */ + if ( !handled ) { + handled=forward_to_driver(control_request_ptr); + } + + DBG(4, "==>\n"); + return handled; +} + +/* ---------------------------------------------------------------------- */ + +/** + * Complete a request on enpdpoint 0. This is called after a competition + * IRQ on ep0 has occourred. + * @warning Executed @ interrupt time; complete CANNOT sleep. + */ +void mgc_complete_ep0_request(void) +{ + struct usb_request *reqptr; +#ifdef MUSB_PARANOID + ASSERT_SPINLOCK_UNLOCKED(&dev_context->lock); + ASSERT_SPINLOCK_LOCKED(&dev_context->end[0]); +#endif + + spin_lock( &dev_context->end[0].lock ); + reqptr=udc_current_request( &dev_context->end[0] ); + + /* this is interrupt code, it cannot sleep! */ + if ( reqptr ) { + list_del( &reqptr->list ); + INIT_LIST_HEAD( &dev_context->end[0].req_list ); + + spin_unlock( &dev_context->end[0].lock ); + if ( reqptr->complete ) { + reqptr->complete(&dev_context->end[0].ep, + reqptr); + } + } else { + spin_unlock( &dev_context->end[0].lock ); + } + + dev_context->end0_stage = MUSB_END0_STAGE_SETUP; +} + +/** + * handle the completition interrupt on endpoint 0. + */ +void handle_ep0_completition_irq(void) +{ + const uint8_t* base_addr = (uint8_t*)udc_base_addr; + struct nomadik_ep* end_ptr = &(dev_context->end[0]); + struct usb_request *reqptr=udc_current_request(end_ptr); + + DBG(3, "<==\n"); + DBG(4, "post event interrupts ep0stage=%s\n", + decode_ep0stage(dev_context->end0_stage)); + switch (dev_context->end0_stage) { + + /* end of sequence #2 (RX state) or #3 (no data) */ + case MUSB_END0_STAGE_STATUSIN: + DBG(3, "MUSB_END0_STAGE_STATUSIN request\n"); + + /* update address (if needed) only @ the end of the + * status phase per standard. The guide is WRONG! + */ + if(dev_context->set_address_flag) { + dev_context->set_address_flag = 0; + MUSB_WRITE8(base_addr, MUSB_O_HDRC_FADDR, dev_context->address); + } + + /* enter test mode if needed */ + if(dev_context->test_mode_flag) { + DBG(3, "entering TESTMODE\n"); + if (MUSB_M_TEST_PACKET == dev_context->test_mode_value) { + udc_load_fifo(base_addr, 0, sizeof(musb_test_pkt), + musb_test_pkt); + } + + spin_lock(&dev_context->lock); + MUSB_SELECTEND(base_addr, 0); /* select ep0 */ + MUSB_WRITE8(base_addr, MUSB_O_HDRC_TESTMODE, + dev_context->test_mode_value); + spin_unlock(&dev_context->lock); + } + + DBG(2, "completing posted request (if any)\n"); + mgc_complete_ep0_request(); + break; + + /* sequence #1: write to host (TX state) */ + case MUSB_END0_STAGE_STATUSOUT: + DBG(2, "completing posted request (if any)\n"); + mgc_complete_ep0_request(); + break; + + case MUSB_END0_STAGE_TX: + DBG(2, "TX changeing ep status\n"); + if(reqptr->actual < reqptr->length) + { + ep0_txstate(); /* sequence #1, TX State */ + } + if ( udc_current_request(&dev_context->end[0])->status!=-EINPROGRESS ) { + dev_context->end0_stage=MUSB_END0_STAGE_STATUSOUT; + } + break; + case MUSB_END0_STAGE_RX: + DBG(2, "RX changeing ep status\n"); + if ( udc_current_request(&dev_context->end[0])->status!=-EINPROGRESS ) { + dev_context->end0_stage=MUSB_END0_STAGE_STATUSIN; + } + break; + + default: /* IT WAS STALLED */ + DBG(2, "recovering from stall? ep0stage=%s\n", + decode_ep0stage(dev_context->end0_stage)); + dev_context->end0_stage = MUSB_END0_STAGE_SETUP; + break; + } + + DBG(4, "==>\n"); +} + + +/* ---------------------------------------------------------------------- */ + +/** + * Handle ep0 in receive state. Called to start a receie and on each interrupt + * when receiving data on ep0. + */ +int ep0_rxstate(void) { + const uint8_t* base_addr = (uint8_t*)udc_base_addr; + struct nomadik_ep* end_ptr = &(dev_context->end[0]); + struct usb_request *reqptr=udc_current_request(end_ptr); + + /* nothign for now */ + DBG(4, "<==\n"); + + if ( reqptr->actual==0 ) { + /* ack the request first */ + DBG(4, "acking request %s\n", decode_csr0(MUSB_M_CSR0_P_SVDRXPKTRDY) ); + spin_lock(&dev_context->lock); + MUSB_SELECTEND(base_addr, 0); + MUSB_WRITECSR16(base_addr, MUSB_O_HDRC_CSR0, 0, + MUSB_M_CSR0_P_SVDRXPKTRDY); + spin_unlock(&dev_context->lock); + } + +#ifdef MUSB_PARANOID + ASSERT_SPINLOCK_UNLOCKED(&dev_context->lock); + ASSERT_SPINLOCK_LOCKED(&end_ptr->lock); +#endif + + DBG(4, "==>\n"); + + return 0; +} + +/** + * Handle ep0 in transmit state. Called to start a receie and on each interrupt + * when transmitting data on ep0. + */ +int ep0_txstate(void) { + unsigned long flags; + const uint8_t* base_addr = (uint8_t*)udc_base_addr; + struct nomadik_ep* end_ptr = &(dev_context->end[0]); + struct usb_request *reqptr=udc_current_request(end_ptr); + uint16_t csrval = MUSB_M_CSR0_TXPKTRDY; + uint8_t* fifo_source; + uint8_t fifo_count; + + DBG(4, "<==\n"); + +#ifdef MUSB_PARANOID + if ( !dev_context || !reqptr ) { + ERR("dev_context=%p, reqptr=%p", dev_context, reqptr); + return -EINVAL; + } +#endif + +#ifdef MUSB_PARANOID + ASSERT_SPINLOCK_UNLOCKED(&dev_context->lock); + ASSERT_SPINLOCK_LOCKED(&end_ptr->lock); +#endif + + spin_lock_irqsave(&dev_context->lock, flags); + MUSB_SELECTEND(base_addr, 0); + + if ( reqptr->actual==0 ) { + /* ack the request first */ + DBG(4, "acking request %s\n", decode_csr0(MUSB_M_CSR0_P_SVDRXPKTRDY) ); + MUSB_WRITECSR16(base_addr, MUSB_O_HDRC_CSR0, 0, + MUSB_M_CSR0_P_SVDRXPKTRDY); + } + + /* load the data */ + fifo_source = (uint8_t*)reqptr->buf+reqptr->actual; + fifo_count =min((int)MUSB_END0_FIFOSIZE, (int)(reqptr->length-reqptr->actual)); + udc_load_fifo(base_addr, 0, fifo_count, fifo_source); + reqptr->actual+=fifo_count; /* done */ + + /* update the flags */ + if ( fifo_count < MUSB_MAX_END0_PACKET ) { + csrval |= MUSB_M_CSR0_P_DATAEND; + reqptr->status=0; /* done */ + } + + /* send it out! (this will trigger the ep0 completition IRQ) + * serviced in interrupt_complete() */ + DBG(4, "wrote fifo_count=%d bytes, csrval=%s\n", fifo_count, + decode_csr0(csrval) ); + MUSB_WRITECSR16(base_addr, MUSB_O_HDRC_CSR0, 0, csrval); + spin_unlock_irqrestore(&dev_context->lock, flags); + + DBG(4, "==>\n"); + return 0; +} + +/** + * Read a FULL header packet from the hardware. The buffer starts with + * struct usb_ctrlrequest (fields are converted to device specific + * byte order). + * + * @param wcount>0 + * @return 0 when the packet is complete, a negative number when an error + * occurred, a positive number when still there are bytes to read. + */ +int udc_read_control_request(struct nomadik_udc* dev_context, uint16_t wcount) { + const uint8_t* base_ptr = ( u8 *)udc_base_addr; + struct t_udc_end0_buffer* end0_buffer_ptr=(struct t_udc_end0_buffer*)dev_context->end0_buffer_ptr; + struct usb_ctrlrequest* control_req_ptr=(struct usb_ctrlrequest*)end0_buffer_ptr; + + DBG(3, "<==\n"); + DBG(4,"wcount=%u, end0_buffer_ptr->count=%u\n", wcount, + end0_buffer_ptr->count); + + /* what did u call me for?? */ + if (!wcount) { + return -EINVAL; + } + + /* buffer overrun, it should never happen */ + if ( wcount>(MUSB_MAX_END0_PACKET-sizeof(struct usb_ctrlrequest)) ) { + ERR("buffer overrun! wcount=%d\n", wcount ); + return -EINVAL; + } + + /* need to have at least enough bytes for the control request + * comment this out to enable fifo size < 8 bytes + */ + if ( wcountlock); +#endif + + spin_lock(&dev_context->lock); + MUSB_SELECTEND(base_ptr, 0); /* select ep0 */ + + /* count=0 means that I'm reading the USB standard header: + * that's the first thing I need to read from the FIFO (8 bytes). + */ + if ( 0==end0_buffer_ptr->count ) { + DBG(4, "reading header\n" ); + udc_unload_fifo(base_ptr, 0, sizeof(struct usb_ctrlrequest), + (uint8_t*)control_req_ptr); + wcount-=sizeof(struct usb_ctrlrequest); + DBG(6, "header read\n"); + + /* data from the USB bus must be converted from LSB to + * host-specific byte ordering; the control request header + * tell me the payload length etc. + */ + le16_to_cpus( control_req_ptr->wLength ); + le16_to_cpus( control_req_ptr->wIndex ); + le16_to_cpus( control_req_ptr->wValue ); + + DBG(4, "bRequest=%02x, kind=%s, wValue=%04x, wIndex=%04x, wLength=%04x\n", + control_req_ptr->bRequest, decode_request(control_req_ptr), + control_req_ptr->wValue, control_req_ptr->wIndex, + control_req_ptr->wLength); + + if( control_req_ptr->bRequestType & USB_DIR_IN ) { + /* write to host: up to wLength bytes */ + end0_buffer_ptr->count=0; + dev_context->end0_stage = MUSB_END0_STAGE_TX; + } else if( control_req_ptr->bRequestType & USB_DIR_OUT ) { + /* out to function: wLength to go for the payload */ + end0_buffer_ptr->count=control_req_ptr->wLength; + dev_context->end0_stage = MUSB_END0_STAGE_RX; + } + } + + if ( wcount>0 ) { + /* now Im reading the rest of it, this will never be executed I guess */ + uint16_t offset=sizeof(struct usb_ctrlrequest)+ /* read past the header */ + (control_req_ptr->wLength)-(end0_buffer_ptr->count); + udc_unload_fifo(base_ptr, 0, wcount, &end0_buffer_ptr->data[offset]); + end0_buffer_ptr->count-=wcount; + } + + DBG(5, "end0_buffer_ptr->count=%d, ep0stage=%s, %s\n", + end0_buffer_ptr->count, decode_ep0stage(dev_context->end0_stage), + (end0_buffer_ptr->count)?"still to go":"header completed"); + DBG(3, "==>\n"); + + spin_unlock(&dev_context->lock); + + /* 0 header completed, <0 error, >0 bytes to go*/ + return (end0_buffer_ptr->count); +} + +/* ---------------------------------------------------------------------- */ + +/** + * Handle ep0 interrupt of a device, lock & release dev_context. This is the main + * entry point of the gadget Ep0 handling code. + * @param dev_context the controller + */ +uint8_t udc_ep0_irq(void) +{ + + uint16_t csrval; /* */ + uint16_t wcount; /* bytes available */ + const uint8_t* base_addr = (uint8_t*)udc_base_addr; + DBG(2, "<==\n"); + spin_lock(&dev_context->lock); + MUSB_SELECTEND(base_addr, 0); /* select ep0 */ + csrval = MUSB_READCSR16(base_addr, MUSB_O_HDRC_CSR0, 0); + wcount = MUSB_READCSR8(base_addr, MUSB_O_HDRC_COUNT0, 0); + + /* I sent a stall.. need to acknowledge it now.. */ + if(csrval & MUSB_M_CSR0_P_SENTSTALL) { + MUSB_WRITECSR16(base_addr, MUSB_O_HDRC_CSR0, 0, + csrval & ~MUSB_M_CSR0_P_SENTSTALL ); + dev_context->end0_stage=MUSB_END0_STAGE_SETUP; + } + + /* setup ended prematurely, abort it */ + if (csrval & MUSB_M_CSR0_P_SETUPEND) { + /* clearing it */ + MUSB_WRITECSR16(base_addr, MUSB_O_HDRC_CSR0, 0, + MUSB_M_CSR0_P_SVDSETUPEND ); + dev_context->end0_stage=MUSB_END0_STAGE_SETUP; + } + + spin_unlock(&dev_context->lock); + + /* handle completition interrupt */ + if ( !csrval && !wcount ) { + handle_ep0_completition_irq(); + return 1; + } + switch( dev_context->end0_stage ) { + /* done transmitting */ + case MUSB_END0_STAGE_STATUSOUT: + case MUSB_END0_STAGE_STATUSIN: + if(!dev_context->set_config_flag) + mgc_complete_ep0_request(); + break; + } + switch( dev_context->end0_stage ) { + /* im alrewady writing to host, TX state, + sequence #1 initiated during the setup */ + case MUSB_END0_STAGE_TX: + if ( csrval & MUSB_M_CSR0_TXPKTRDY ) { + ep0_txstate(); + } break; + + /* im alrewady receiving from host, RX state, + sequence #2 initiated during the setup */ + case MUSB_END0_STAGE_RX: + if ( csrval & MUSB_M_CSR0_RXPKTRDY ) { + ep0_rxstate(); + } + break; + + /* received from host, RX State, header */ + case MUSB_END0_STAGE_SETUP: + if ( csrval & MUSB_M_CSR0_RXPKTRDY ) { + int count=0, handled=0; + + count=udc_read_control_request(dev_context, wcount); + if ( count<0 ) { + /* ack the request */ + ERR("error reading the control request: this is bad (tm)\n"); + } else if ( 0==count ) { /* I got the full packet, GREAT! */ + struct usb_ctrlrequest *control_request_ptr=(struct usb_ctrlrequest*) + dev_context->end0_buffer_ptr; + + /* sequence #3 */ + if ( is_zerodata_request(control_request_ptr) ) { + uint16_t csrval= MUSB_M_CSR0_P_SVDRXPKTRDY + | MUSB_M_CSR0_P_DATAEND; + + handled=service_zero_data_request(dev_context, + control_request_ptr); + if ( handled<0 && handled!=-EOPNOTSUPP ) { + csrval |= MUSB_M_CSR0_P_SENDSTALL; + } + + dev_context->end0_stage = MUSB_END0_STAGE_STATUSIN; + + /* ack the request */ + DBG(3, "handled=%d, csrval=%s, ep0stage=%s\n", handled, + decode_csr0(csrval), + decode_ep0stage(dev_context->end0_stage) ); + + if(!dev_context->set_config_flag) + { + spin_lock(&dev_context->lock); + MUSB_SELECTEND(base_addr, 0); + MUSB_WRITECSR16(base_addr, MUSB_O_HDRC_CSR0, 0, csrval); + spin_unlock(&dev_context->lock); + } + } else { + /* sequence #1 */ + if ( is_tx_request(control_request_ptr) ) { + /* write to host, a request is posted on ep0 */ + dev_context->end0_stage=MUSB_END0_STAGE_TX; + handled=service_tx_request(control_request_ptr); + /* sequence #2, a request is posted on ep0 */ + } else if ( is_rx_request(control_request_ptr) ) { + dev_context->end0_stage=MUSB_END0_STAGE_RX; + handled=service_rx_request(control_request_ptr); + } + + if ( handled<0 ) { + /* stall it!!! application stall */ + spin_lock(&dev_context->lock); + MUSB_SELECTEND(base_addr, 0); + MUSB_WRITECSR16(base_addr, MUSB_O_HDRC_CSR0, 0, + MUSB_M_CSR0_P_SVDRXPKTRDY | MUSB_M_CSR0_P_SENDSTALL); + spin_unlock(&dev_context->lock); + } + } + + } + } else { + + } + break; + + + /* handle the application stall on Ep0 */ + default: + { + uint16_t csrval = MUSB_M_CSR0_P_SENDSTALL; + switch ( dev_context->end0_stage & ~MUSB_END0_STAGE_STALL_BIT ) { + case MUSB_END0_STAGE_TX: + csrval|=MUSB_M_CSR0_TXPKTRDY; + break; + case MUSB_END0_STAGE_RX: + csrval|=MUSB_M_CSR0_RXPKTRDY; + break; + } + + DBG(3, "Application stall from ep0stage=%s\n", + decode_ep0stage(dev_context->end0_stage)); + spin_lock(&dev_context->lock); + MUSB_SELECTEND(base_addr, 0); + MUSB_WRITECSR16(base_addr, MUSB_O_HDRC_CSR0, 0, csrval); + spin_unlock(&dev_context->lock); + + dev_context->end0_stage = MUSB_END0_STAGE_SETUP; + } + break; + } + + return 1; +} + + + + +/** + * Determine the packet size for an endpoint. + * @param dev_context the controller + * @param bEnd the endpoint number + * @return the packet size + */ +inline int get_ep_packet_size(struct nomadik_udc* dev_context, uint8_t bEnd) +{ + int size=dev_context->end[bEnd].maxpacket; + + if ( (USB_ENDPOINT_XFER_BULK == dev_context->end[bEnd].bmAttributes) + && dev_context->bulk_split) + { + size=dev_context->end[bEnd].maxpacket; + } + + return size; +} + + +inline struct usb_request* udc_current_request( struct nomadik_ep * end_ptr) { + return ( list_empty(&((end_ptr)->req_list) )? NULL : list_entry((end_ptr)->req_list.next, struct usb_request, list) ); +} + + +/** + * Queue requests to endpoints for execution. + * @param ep the endpoint the request shall be queued to + * @param req_ptr the request + * @param gfp_flags memory flags + */ +int nomadik_ep_queue(struct usb_ep *_ep, struct usb_request *_req, + gfp_t gfp_flags) +{ + unsigned long lockflags; + + struct nomadik_ep *ep = container_of(_ep, struct nomadik_ep, ep); + struct nomadik_req *req_ptr = container_of(_req, struct nomadik_req, req); + const uint8_t* base_addr = (uint8_t*)udc_base_addr; + const uint8_t bEnd=EP_NUMBER(ep); + int is_iso = 0; + + /* catch various bogus parameters */ + if (!req_ptr || !req_ptr->req.complete || !req_ptr->req.buf + /*|| !list_empty(&req_ptr->completion_list)*/) { + ERR("%s, bad params\n", __FUNCTION__); + return -EINVAL; + } + + if (ep->bmAttributes == USB_ENDPOINT_XFER_ISOC) { + if (req_ptr->req.length > ep->ep.maxpacket) + return -EMSGSIZE; + is_iso = 1; + } + + /* this isn't bogus, but NOMADIK DMA isn't the only hardware to + * have a hard time with partial packet reads... reject it. + */ + if (use_dma + && ep->has_dma + && ep->end_number != 0 + && (ep->is_tx == 0 ) + && (req_ptr->req.length % ep->ep.maxpacket) != 0) { + ERR("%s, no partial packet OUT reads\n", __FUNCTION__); + return -EMSGSIZE; + } + + if (!dev_context->driver || dev_context->gadget.speed == USB_SPEED_UNKNOWN) + return -ESHUTDOWN; + + if (use_dma && ep->has_dma) { + if (req_ptr->req.dma == DMA_ADDR_INVALID) { + req_ptr->req.dma = dma_map_single( + ep->udc->gadget.dev.parent, + req_ptr->req.buf, + req_ptr->req.length, + (ep->is_tx ) + ? DMA_TO_DEVICE + : DMA_FROM_DEVICE); + req_ptr->mapped = 1; + } else { + dma_sync_single_for_device( + ep->udc->gadget.dev.parent, + req_ptr->req.dma, req_ptr->req.length, + (ep->is_tx ) + ? DMA_TO_DEVICE + : DMA_FROM_DEVICE); + req_ptr->mapped = 0; + } + } + + DBG(2,"%s queue req %p, len %d buf %p\n", + ep->ep.name, _req, _req->length, _req->buf); + + + + /* request is mine now... */ + req_ptr->req.actual=0; + req_ptr->req.status=-EINPROGRESS; + req_ptr->end_number=bEnd; + req_ptr->is_tx=ep->is_tx; + + /* for now... */ + INIT_LIST_HEAD( &req_ptr->req.list ); + + /* lock the endpoint */ + EP_SPIN_LOCK_IRQSAVE(ep, lockflags); + + /* add req_ptr to the list */ + list_add_tail( &(req_ptr->req.list), &(ep->req_list) ); + /* it this is not the head of the queue, done... */ + if ( req_ptr!=(struct nomadik_req*)udc_current_request(ep) ) { + EP_SPIN_UNLOCK_IRQRESTORE( ep,lockflags ); + return 0; + } + +#ifdef MUSB_PARANOID + if ( bEnd==ReqEnd ) { + ReqCount++; + } + + if ( ReqCount>=ReqCap ) { + WARN("ReqCount=%d on ep%d\n", ReqCount, bEnd); + EP_SPIN_UNLOCK_IRQRESTORE( ep,lockflags ); + return 0; + } +#endif + + /* start the request otherwise; the EP MUST BE UNLOCKED */ + if ( bEnd==0 ) { + if(dev_context->set_config_flag) + { + uint16_t csrval; + dev_context->set_config_flag = 0; + spin_lock(&dev_context->lock); + MUSB_SELECTEND(base_addr, 0); + csrval= MUSB_M_CSR0_P_SVDRXPKTRDY | MUSB_M_CSR0_P_DATAEND; + MUSB_WRITECSR16(base_addr, MUSB_O_HDRC_CSR0, 0, csrval); + spin_unlock(&dev_context->lock); + } + + EP_SPIN_UNLOCK_IRQRESTORE( ep,lockflags ); + + + switch ( dev_context->end0_stage ) + { + case MUSB_END0_STAGE_TX: + + ep0_txstate(); /* sequence #1, TX State */ + break; + + + case MUSB_END0_STAGE_RX: + + ep0_rxstate(); /* sequence #2, RX State */ + break; + + /* certain gadged may keep ep0 busy; g_file_storage + does it after a set_config command.*/ + default: { + + mdelay(5); + + req_ptr->req.status=(req_ptr->req.actual==req_ptr->req.length) + ? 0 : -EINVAL; + mgc_complete_ep0_request(); + } + break; + + } + + } else + { + udc_restart_request(dev_context, (struct usb_request *)req_ptr); + EP_SPIN_UNLOCK_IRQRESTORE( ep,lockflags ); + } + + DBG(4, "==>\n"); + return 0; +} + +/** + * Restart (Start) a request on an endpoint. + * @param dev_context the controller + * @param req_ptr the request to start (not NULL) + */ +void udc_restart_request(struct nomadik_udc *dev_context, struct usb_request *req_ptr) +{ + DBG(3, "<== restarting (%s) request req_ptr=%p on ep=%d\n", + ((struct nomadik_req*)req_ptr)->is_tx ? "tx" : "rx", + req_ptr, ((struct nomadik_req*)req_ptr)->end_number); + +#ifdef MUSB_PARANOID + if ( !req_ptr ) { + ERR("null req_ptr\n"); + return; + } +#endif + + if( ((struct nomadik_req*)req_ptr)->is_tx ) { + txstate(dev_context, (struct nomadik_req*)req_ptr); + } else { + rxstate(dev_context, (struct nomadik_req*)req_ptr); + } +} + +/** + * Dequeue a request + * @param ep the endpoint + * @param req_ptr the request to dequeue + * @return 0 if success, or negative when error + */ +int nomadik_ep_dequeue(struct usb_ep *ep, struct usb_request *req_ptr) +{ + struct nomadik_ep * end_ptr =( struct nomadik_ep *)ep; + + DBG(4, "<==\n" ); + DBG(3, "dequeuing from nEnd=0x%x, end_ptr=%p, req_ptr=%p\n", \ + EP_NUMBER(end_ptr), end_ptr, req_ptr); + + + /* flush the request returning -EINVAL; syncronnous */ + EP_SPIN_LOCK( end_ptr ); + req_ptr->status=-EINVAL; + if ( req_ptr->complete ) { + list_del( &req_ptr->list ); + EP_SPIN_UNLOCK( end_ptr ); + req_ptr->complete((struct usb_ep *)end_ptr, req_ptr); + } else { + EP_SPIN_UNLOCK( end_ptr ); + } + + return 0; +} + + + +/** + * An endpoint is transmitting data. This can be called either from + * the IRQ routine or from GadgetQueue to kickstart a request on an + * endpoint. + * + * @warning ep locked & IRQ disabled + * @param dev_context the controller + * @param req the request on ep0 + */ +void txstate(struct nomadik_udc* dev_context, struct nomadik_req* req) +{ + uint8_t bEnd; + struct nomadik_ep* end_ptr; + struct usb_request *reqptr; + uint16_t fifo_count = 0, csrval; + const uint8_t* base_addr = (uint8_t*)udc_base_addr; + + DBG(4, "<==\n"); + +#ifdef MUSB_PARANOID + if ( !req ) { + ERR("cannot call txstate without request\n"); + return; + } +#endif + + bEnd=req->end_number; + reqptr=&req->req; + end_ptr=&(dev_context->end[req->end_number]); + + fifo_count = min(get_ep_packet_size(dev_context, bEnd), + (int)(reqptr->length-reqptr->actual)); + /* read TXCSR before */ + MUSB_SELECTEND(base_addr, bEnd); + csrval=MUSB_READCSR16(base_addr, MUSB_O_HDRC_TXCSR, bEnd); + + if (USB_ENDPOINT_XFER_ISOC == end_ptr->bmAttributes) { + csrval |= MUSB_M_TXCSR_ISO; + } + +#ifdef MUSB_PARANOID + if ( reqptr->length-reqptr->actual<0 ) { + ERR("NEGATIVE FIFOCOUNT! reqptr->actual=%d, fifo_count=%d, reqptr->length=%d\n", \ + reqptr->actual, fifo_count, reqptr->length); + fifo_count=0; + } + + if ( reqptr->actual+fifo_count>reqptr->length ) { + ERR("trying to write PAST length! reqptr->actual=%d, fifo_count=%d, reqptr->length=%d\n", \ + reqptr->actual, fifo_count, reqptr->length); + fifo_count=reqptr->length-reqptr->actual; + } +#endif + + DBG(3, "bEnd=0x%x, end_ptr->maxpacket=0x%x, fifo_count=%d, %s\n", \ + bEnd, end_ptr->maxpacket, fifo_count, dump_usb_request(reqptr) ); + + + /* stalled?? */ + if ( csrval & MUSB_M_TXCSR_P_SENDSTALL ) { + DBG(2, "completing stalled request reqptr=%p\n", reqptr); + list_del( &reqptr->list ); + udc_complete_request(reqptr, 0); + return; + } + + +#ifdef MUSB_NO_ZEROPACKET_KLUDGE + if ( !fifo_count ) { + DBG(2, "==> Skipping zero packet\n"); + } +#endif + + udc_load_fifo(base_addr, bEnd, fifo_count, + (uint8_t*)(reqptr->buf+reqptr->actual)); + reqptr->actual+=fifo_count; + + + + csrval = MUSB_M_TXCSR_MODE | MUSB_M_TXCSR_TXPKTRDY; /* add my stuff */ + + + /* now write out the thing */ + DBG(3, "xmit a packet reqptr->length=%d, reqptr->actual=%d, \n", + reqptr->length, reqptr->actual); + + MUSB_WRITECSR16(base_addr, MUSB_O_HDRC_TXCSR, bEnd, csrval); + + DBG(4, "==>\n"); +} + +/** + * Data ready for a request; called from IRQ; no need to disable the + * IRQS bc they are already disabled. The end point CANNOT be locked + * when entering this routine because it would deadlock. By design, + * this is called only after txstate has been called. + * + * @param dev_context + * @param bEnd + */ +void udc_ep_tx_irq(uint8_t bEnd) { + uint16_t csrval; + unsigned long flags; + struct usb_request *reqptr; + uint8_t* base_addr = (uint8_t*)udc_base_addr; + struct nomadik_ep* end_ptr = &(dev_context->end[bEnd]); + + DBG(4, "<== bEnd=%d\n", bEnd ); + + do { + spin_lock_irqsave(&dev_context->lock, flags); + MUSB_SELECTEND(base_addr, bEnd); + csrval = MUSB_READCSR16(base_addr, MUSB_O_HDRC_TXCSR, bEnd); + DBG(1, "udc_ep_tx_irq bEnd = %d txcsr = 0x%x\n",bEnd,csrval); + + if (csrval & MUSB_M_TXCSR_P_SENTSTALL) { + csrval &= ~MUSB_M_TXCSR_P_SENTSTALL; + MUSB_WRITECSR16(base_addr, MUSB_O_HDRC_TXCSR, bEnd, csrval); + + DBG(2, "request was stalled, completing it\n"); + reqptr=udc_current_request(end_ptr); + if ( reqptr ) { + list_del( &reqptr->list ); + spin_unlock_irqrestore(&dev_context->lock, flags); + udc_complete_request(reqptr, -EOPNOTSUPP); /* complete */ + } else { + WARN("Acking sent stall, but no request!\n"); + } + + break; + } + + if(csrval & MUSB_M_TXCSR_P_UNDERRUN) { +#ifdef NMDK_CONFIG_PROC_FS + dev_context->end[bEnd].dwMissedTxPackets++; +#endif + csrval &= ~MUSB_M_TXCSR_P_UNDERRUN; + MUSB_WRITECSR16(base_addr, MUSB_O_HDRC_TXCSR, bEnd, csrval); + DBG(2, "underrun on ep%d\n", bEnd); + } + + reqptr=udc_current_request(end_ptr); + if ( reqptr ) { + + /* the zero flag request the transmission of a zero data pkt + * (when required). The zero flag is reset to zero, + * after the zero packet has been submitted. */ + if ( reqptr->actual==reqptr->length ) { + + if ( reqptr->zero && + ( reqptr->length && (reqptr->length%get_ep_packet_size(dev_context, bEnd))==0 ) + && !(csrval & MUSB_M_TXCSR_P_SENTSTALL) + ) { + const uint16_t csrval=MUSB_M_TXCSR_MODE + | MUSB_M_TXCSR_TXPKTRDY; + + reqptr->zero=0; + + DBG(3, "sending zero pkt\n"); + + MUSB_SELECTEND(base_addr, bEnd); + MUSB_WRITECSR16(base_addr, MUSB_O_HDRC_TXCSR, bEnd, csrval); + spin_unlock_irqrestore(&dev_context->lock, flags); + break; + } + + list_del( &reqptr->list ); + udc_complete_request(reqptr, 0); /* async complete */ + + /* kickstart next request if available */ + reqptr=(end_ptr->binactive) ? NULL + : udc_current_request(end_ptr); + if ( !reqptr ) { + DBG(3, "bEnd=0x%x idle now\n", bEnd); + DBG( 2, "bEnd=0x%x idle now\n", bEnd); + break; + } + } + + /* txstate unlock the ep before writing */ + txstate(dev_context, (struct nomadik_req*)reqptr); + } + + } while (0); + + spin_unlock_irqrestore(&dev_context->lock, flags); + DBG(2, "==>\n" ); +} + +/* ------------------------------------------------------------ */ + +/** + * Receving on an endpoint. Called from the IRQ routine and when + * starting receving. + * @warning ep locked & IRQ disabled + * @param dev_context the controller + * @param req the request + * @see udc_ep_rx_irq + */ +void rxstate(struct nomadik_udc* dev_context, struct nomadik_req* req) +{ + uint16_t csrval=0; + const uint8_t bEnd=req->end_number; + struct usb_request *reqptr=&req->req; + const uint8_t* base_addr = (uint8_t*)udc_base_addr; + struct nomadik_ep* end_ptr = &(dev_context->end[bEnd]); + uint16_t fifo_count = 0, wcount=end_ptr->maxpacket; + + + MUSB_SELECTEND(base_addr, bEnd); + csrval = MUSB_READCSR16(base_addr, MUSB_O_HDRC_RXCSR, bEnd); + if ( csrval& MUSB_M_RXCSR_RXPKTRDY ) { + + /* this also handle residual (if any) */ + wcount = MUSB_READCSR16(base_addr, MUSB_O_HDRC_RXCOUNT, bEnd); + if ( reqptr->actual < reqptr->length ) { + + fifo_count = (uint16_t)min((int)wcount, + (int)(reqptr->length - reqptr->actual)); + udc_unload_fifo(base_addr, bEnd, fifo_count, + (uint8_t*)(reqptr->buf + reqptr->actual)); + reqptr->actual += fifo_count; + + DBG(3, "fifo_count=%d, bEnd=0x%x, end_ptr->maxpacket=0x%x, wcount=0x%x, %s\n",\ + fifo_count, bEnd, end_ptr->maxpacket, wcount, dump_usb_request(reqptr)); + + /* ack the read! */ + csrval &= ~MUSB_M_RXCSR_RXPKTRDY; + MUSB_WRITECSR16(base_addr, MUSB_O_HDRC_RXCSR, bEnd, csrval); + } + } + + /* reach the end or short packet detected */ + if ( reqptr->actual==reqptr->length || wcountmaxpacket ) { + reqptr->status=0; + + DBG(3, "completing reqptr=%p on bEnd=0x%x\n", reqptr, bEnd); + list_del( &reqptr->list ); + DBG(3, "queuing completion\n"); + udc_complete_request(reqptr, reqptr->status); /* async complete */ + } + + DBG(2, "==>"); +} + +/** + * Data ready for a request; called from IRQ + * @param dev_context the controller + * @param req the request + */ +void udc_ep_rx_irq(uint8_t bEnd) +{ + uint16_t csrval; + unsigned long flags; + struct usb_request* reqptr=NULL; + uint8_t* base_addr = (uint8_t*)udc_base_addr; + struct nomadik_ep* end_ptr = &(dev_context->end[bEnd]); + + DBG(1, "<==\n" ); + + /* executed from interrupt no need to disable them */ + spin_lock_irqsave(&dev_context->lock, flags); + MUSB_SELECTEND(base_addr, bEnd); + csrval = MUSB_READCSR16(base_addr, MUSB_O_HDRC_RXCSR, bEnd); + if(csrval & MUSB_M_RXCSR_P_SENTSTALL) { + csrval &= ~MUSB_M_RXCSR_P_SENTSTALL; + MUSB_WRITECSR16(base_addr, MUSB_O_HDRC_RXCSR, bEnd, csrval); + DBG(2, "received stall on ep%d\n", bEnd); + spin_unlock_irqrestore(&dev_context->lock, flags); + return; + } + + if(csrval & MUSB_M_RXCSR_P_OVERRUN) { +#ifdef NMDK_CONFIG_PROC_FS + dev_context->end[bEnd].dwMissedRxPackets++; +#endif + csrval &= ~MUSB_M_RXCSR_P_OVERRUN; + MUSB_WRITECSR16(base_addr, MUSB_O_HDRC_RXCSR, bEnd, csrval); + DBG(2, "Received overrun on ep%d\n", bEnd); + } + +#ifdef NMDK_CONFIG_PROC_FS + if(csrval & MUSB_M_RXCSR_INCOMPRX) { + dev_context->end[bEnd].dwErrorRxPackets++; + } +#endif + + /* analyze request if the ep is not inactive */ + reqptr=(end_ptr->binactive) ? NULL : udc_current_request(end_ptr); + if ( reqptr ) { + DBG( 1, "Going into rxstate\n"); + rxstate(dev_context, (struct nomadik_req*)reqptr); + } else { + DBG(3, "Rx: bytes waiting on ep=0x%x\n", bEnd); + DBG(1, "Rx: bytes waiting on ep=0x%x\n", bEnd); + } + + spin_unlock_irqrestore(&dev_context->lock, flags); + DBG(4, "==>\n" ); +} + +/********************************************************************** +* +*/ + +/** + * @pre dev_context!=NULL + */ +void udc_resume(void) { + DBG(4, "<==\n" ); + if( dev_context->driver && dev_context->driver->resume) { + dev_context->driver->resume( &dev_context->gadget ); + } +} + +/** + * @pre dev_context!=NULL + */ +void udc_suspend(void) { + DBG(4, "<==\n" ); + if( dev_context->driver && dev_context->driver->suspend) { + dev_context->driver->suspend( &dev_context->gadget ); + } +} + +/** + * @pre dev_context!=NULL + */ +void udc_disconnect_isr(void) { + DBG(4, "<==\n" ); + if( dev_context->driver && dev_context->driver->disconnect) { + dev_context->driver->disconnect(& dev_context->gadget ); + } + DBG(4, "==>\n" ); + +} + +/** + * + * @pre dev_context!=NULL + */ +void musb_reset_isr(void) +{ + const uint8_t* base_addr = (uint8_t*)udc_base_addr; + uint8_t devctl = MUSB_READ8(base_addr, MUSB_O_HDRC_DEVCTL); + DBG(4, "<==\n"); + + DBG(3, "<== mode=%s, addr=%x\n", (devctl&MUSB_M_DEVCTL_HM)?"host":"function", + MUSB_READ8(base_addr, MUSB_O_HDRC_FADDR)); + + /* HR does NOT clear itself */ + if(devctl & MUSB_M_DEVCTL_HR) { + + MUSB_WRITE8(base_addr, MUSB_O_HDRC_DEVCTL, MUSB_M_DEVCTL_SESSION); + } + + /* unconfigured */ + dev_context->address=0; + dev_context->end0_stage=MUSB_END0_STAGE_SETUP; + if ( dev_context->driver ) { + + uint8_t bEnd; + + uint8_t power = MUSB_READ8(base_addr, MUSB_O_HDRC_POWER); + dev_context->gadget.speed = (power & MUSB_M_POWER_HSMODE)? USB_SPEED_HIGH : USB_SPEED_FULL; + /* disable the endpoints */ + for(bEnd = 1; bEnd < dev_context->end_count; bEnd++) + { + nomadik_ep_disable(&dev_context->end[bEnd].ep); + } + (dev_context->end[0]).binactive = MUSB_GADGET_EP_ACTIVE; + + } + DBG(4, "==>\n"); +} + +/********************************************************************** +* FIFO functions +* +*/ + +/** + * FLUSH the FIFO for an endpoint + * + * @pre ep + */ +void nomadik_ep_fifo_flush(struct usb_ep *ep) +{ + uint16_t csr, intr_txe; + unsigned long flags; + uint8_t* base_addr = (u8 *)udc_base_addr; + int nEnd = EP_NUMBER(ep); + + DBG(4, "<==\n" ); + +#ifdef MUSB_PARANOID + if (!dev_context) { + ERR("Gadget not initialized, dev_context=NULL\n"); + return; + } + + if ( nEnd<0 ) { + ERR("invalid endpoint ep=%p\n", ep); + return; + } + + ASSERT_SPINLOCK_UNLOCKED(&dev_context->lock); +#endif + + spin_lock_irqsave(&(dev_context->lock), flags); + MUSB_SELECTEND(base_addr, (uint8_t)nEnd); + + /* disable interrupts */ + intr_txe = MUSB_READ16(base_addr, MUSB_O_HDRC_INTRTXE); + MUSB_WRITE16(base_addr, MUSB_O_HDRC_INTRTXE, intr_txe & ~(1 << nEnd)); + + if(nEnd) { + csr = MUSB_READCSR16(base_addr, MUSB_O_HDRC_TXCSR, (uint8_t)nEnd); + MUSB_WRITECSR16(base_addr, MUSB_O_HDRC_TXCSR, (uint8_t)nEnd, csr); + MUSB_WRITECSR16(base_addr, MUSB_O_HDRC_TXCSR, (uint8_t)nEnd, csr); + + csr = MUSB_READCSR16(base_addr, MUSB_O_HDRC_RXCSR, (uint8_t)nEnd); + csr |= MUSB_M_RXCSR_FLUSHFIFO; + MUSB_WRITECSR16(base_addr, MUSB_O_HDRC_RXCSR, (uint8_t)nEnd, csr); + MUSB_WRITECSR16(base_addr, MUSB_O_HDRC_RXCSR, (uint8_t)nEnd, csr); + } else { + MUSB_WRITECSR16(base_addr, MUSB_O_HDRC_CSR0, 0, MUSB_M_CSR0_FLUSHFIFO); + } + + /* re-enable interrupt */ + MUSB_WRITE16(base_addr, MUSB_O_HDRC_INTRTXE, intr_txe); + spin_unlock_irqrestore(&(dev_context->lock), flags); + + DBG(4, "==>\n" ); +} + + +/** + * Return the FIFO status. + * + * @param ep the end point + */ +int nomadik_ep_fifo_status(struct usb_ep *ep) +{ + unsigned long flags; + int result = 0; + uint8_t* base_addr= (u8 *)udc_base_addr; + int bEnd = EP_NUMBER(ep); + + DBG(4, "<==\n" ); + +#ifdef MUSB_PARANOID + ASSERT_SPINLOCK_UNLOCKED(&dev_context->lock); + + if( MUSB_GadgetFindEnd(ep)<0 ) { + ERR("invalid endpoint ep=%p\n", ep); + return -EINVAL; + } +#endif + + spin_lock_irqsave(&(dev_context->lock), flags); + MUSB_SELECTEND(base_addr, bEnd); + result = MUSB_READCSR16(base_addr, + (bEnd)? MUSB_O_HDRC_RXCOUNT:MUSB_O_HDRC_COUNT0, + bEnd); + spin_unlock_irqrestore(&(dev_context->lock), flags); + + DBG(4, "==> %d\n", result); + return result; +} + + + + +#ifdef DEBUG_LEVEL +/** + * Decode a control request to a string. + * @param pControlRequest the control request + * @return a char* to a static buffer. + * @warning not thread safe + */ +static char * +decode_request(struct usb_ctrlrequest *req) +{ + static char buf [8]; + + sprintf(buf, "%s%s",( USB_TYPE_STANDARD==(req->bRequestType&USB_TYPE_MASK )?"S":"N" ), + is_tx_request(req) ? "TX" + : is_rx_request(req) ? "RX" + : is_zerodata_request(req) ? "Z" + : "-" ); + return buf; +} + +/* Decode CSR0 value to a string. Not reentrant + */ +static char *decode_csr0(uint16_t csr0) { + static char buf[64]; + sprintf(buf, "(%s%s%s%s)", + csr0&MUSB_M_CSR0_TXPKTRDY ? "[TXPKTRDY]":"", + csr0&MUSB_M_CSR0_P_SVDRXPKTRDY ? "[SVDRXPKTRDY]":"", + csr0&MUSB_M_CSR0_P_SENDSTALL ? "[stalled]":"", + csr0&MUSB_M_CSR0_P_DATAEND ? "[dataend]":""); + return buf; +} + +/* Decode a value to binary. + */ +static char *decode_bits(uint16_t value) { + int i=0; + static char buf[64]; + + for (; i<16;i++) { + buf[15-i]=(value&(1<end_count ;ep++) + udc_dump_regs((u8 *)udc_base_addr, 0, ep); +} + +/** + * Dump core registers whose reads are non-destructive. + * @param base_addr + * @param multipoint + * @param bEnd + */ +void udc_dump_regs(uint8_t* base_addr, int multipoint, uint8_t bEnd) +{ + + + MUSB_SELECTEND(base_addr, bEnd); + + if(!bEnd) { + printk(KERN_INFO " 0: CSR0=%04x, Count0=%02x, Type0=%02x, NAKlimit0=%02x\n", + MUSB_READCSR16(base_addr, MUSB_O_HDRC_CSR0, 0), + MUSB_READCSR8(base_addr, MUSB_O_HDRC_COUNT0, 0), + MUSB_READCSR8(base_addr, MUSB_O_HDRC_TYPE0, 0), + MUSB_READCSR8(base_addr, MUSB_O_HDRC_NAKLIMIT0, 0)); + } else { + printk(KERN_INFO "%2d: TxCSR=%04x, TxMaxP=%04x, TxType=%02x, TxInterval=%02x\n", + bEnd, + MUSB_READCSR16(base_addr, MUSB_O_HDRC_TXCSR, bEnd), + MUSB_READCSR16(base_addr, MUSB_O_HDRC_TXMAXP, bEnd), + MUSB_READCSR8(base_addr, MUSB_O_HDRC_TXTYPE, bEnd), + MUSB_READCSR8(base_addr, MUSB_O_HDRC_TXINTERVAL, bEnd)); + printk(KERN_INFO " RxCSR=%04x, RxMaxP=%04x, RxType=%02x, RxInterval=%02x, RxCount=%04x\n", + MUSB_READCSR16(base_addr, MUSB_O_HDRC_TXCSR, bEnd), + MUSB_READCSR16(base_addr, MUSB_O_HDRC_TXMAXP, bEnd), + MUSB_READCSR8(base_addr, MUSB_O_HDRC_TXTYPE, bEnd), + MUSB_READCSR8(base_addr, MUSB_O_HDRC_TXINTERVAL, bEnd), + MUSB_READCSR16(base_addr, MUSB_O_HDRC_RXCOUNT, bEnd)); + } + + if( multipoint) { + printk(KERN_INFO " TxAddr=%02x, TxHubAddr=%02x, TxHubPort=%02x\n", + MUSB_READ8(base_addr, MUSB_BUSCTL_OFFSET(bEnd, MUSB_O_HDRC_TXFUNCADDR)), + MUSB_READ8(base_addr, MUSB_BUSCTL_OFFSET(bEnd, MUSB_O_HDRC_TXHUBADDR)), + MUSB_READ8(base_addr, MUSB_BUSCTL_OFFSET(bEnd, MUSB_O_HDRC_TXHUBPORT))); + printk(KERN_INFO " RxAddr=%02x, RxHubAddr=%02x, RxHubPort=%02x\n", + MUSB_READ8(base_addr, MUSB_BUSCTL_OFFSET(bEnd, MUSB_O_HDRC_RXFUNCADDR)), + MUSB_READ8(base_addr, MUSB_BUSCTL_OFFSET(bEnd, MUSB_O_HDRC_RXHUBADDR)), + MUSB_READ8(base_addr, MUSB_BUSCTL_OFFSET(bEnd, MUSB_O_HDRC_RXHUBPORT))); + } +} + +#endif + + +/** + * Enable the Controller + */ +void musb_enable(void) +{ + uint8_t* udc_base = (uint8_t*)udc_base_addr; + + DBG(4, "<==\n"); + + /* Set INT enable registers, enable interrupts */ + MUSB_WRITE16(udc_base, MUSB_O_HDRC_INTRTXE, dev_context->end_mask); + MUSB_WRITE16(udc_base, MUSB_O_HDRC_INTRRXE, dev_context->end_mask & 0xfffe); + /* don't enable suspend mode! */ + MUSB_WRITE8(udc_base, MUSB_O_HDRC_INTRUSBE, 0xf7); + + + DBG(3, "%s INTRUSBE reg:0x%x \n", __FUNCTION__,MUSB_READ8(udc_base, MUSB_O_HDRC_INTRUSBE)); + DBG(3, "%s INTRTXE reg:0x%x \n", __FUNCTION__,MUSB_READ8(udc_base, MUSB_O_HDRC_INTRTXE)); + DBG(3, "%s INTRRXE reg:0x%x \n", __FUNCTION__,MUSB_READ8(udc_base, MUSB_O_HDRC_INTRRXE)); +} + + + +/** + * Register the gadget driver. Used by the gadget when + * registering themselves with the controller. + * + * + * @param driver the gadget driver + * @return <0 if error, 0 if everything is fine + */ +int usb_gadget_register_driver(struct usb_gadget_driver *driver) +{ + int retval; + + DBG(4, "<==\n"); + + + dev_context->driver=driver; + + do { + struct usb_gadget *gadget = &dev_context->gadget; + u8 *base_addr = ( u8 *)udc_base_addr; + + uint8_t power = MUSB_READ8(base_addr, MUSB_O_HDRC_POWER); + + gadget->name = driver->function; + driver->driver.bus=0; + gadget->dev.driver=&driver->driver; + + retval = device_add(&gadget->dev); + if(retval) + { + ERR("add driver %s failed --> %d\n", + driver->driver.name, retval); + return retval; + } + + gadget->speed = (power & MUSB_M_POWER_HSMODE) ? USB_SPEED_HIGH : USB_SPEED_FULL; + gadget->is_dualspeed=1; + + retval=driver->bind( gadget ); + + DBG(2, "bind complete with retval = %d\n",retval); + if (retval) { + ERR("bind to driver %s failed --> %d\n", + driver->driver.name, retval); + device_del (&gadget->dev); + gadget->dev.driver = NULL; + dev_context->driver = NULL; + return(retval); + } + + DBG(2, "bind complete 2\n"); + + musb_enable(); + } while (0); + return 0; +} + +/** + * Unregister the gadget driver. Used by the gadget when + * unregistering themselves from the controller. + * + * @param driver the gadget driver to unregister + */ +int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) +{ + DBG(4, "<==\n" ); + + + INFO("unregistering gadget %s\n", driver->function); + + /* shall I flush/abort the pending requests?? */ + if ( dev_context->driver ) { + struct usb_gadget *gadget=&dev_context->gadget; + driver->unbind( gadget ); + + gadget->dev.driver = NULL; + dev_context->driver = NULL; + device_del(&gadget->dev); + + DBG(4, "unregister driver\n" ); + } + + return 0; +} + +int nomadik_udc_init(MGC_LinuxCd *pThis) +{ + int status = -ENODEV; + DBG(4,"nomadik_udc_init"); + udc_base_addr = (unsigned long)pThis->pRegs; + status = alloc_n_config_udc(); + status = udc_setup(); + return status; +} + +int nomadik_udc_exit(void) +{ + DECLARE_COMPLETION(done); + if (!dev_context) + return -ENODEV; + + dev_context->done = &done; + nomadik_release_udc(); + return 0; +} + +EXPORT_SYMBOL(usb_gadget_register_driver); +EXPORT_SYMBOL(usb_gadget_unregister_driver); --- /dev/null +++ linux-2.6.20/drivers/usb/nomadik/nomadik_udc.h @@ -0,0 +1,663 @@ +/* + * linux/drivers/usb/nomadik/nomadik_udc.h + * + * Copyright 2007, STMicroelectronics + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#define DMA_ADDR_INVALID (~(dma_addr_t)0) + +#define MUSB_MAX_USB_ENDS 16 + +#define MUSB_END0_FIFOSIZE 64 /* this is non-configurable */ + +#ifndef MUSB_C_NUM_EPS +#define MUSB_C_NUM_EPS ((uint8_t)16) +#endif + +#ifndef MUSB_MAX_END0_PACKET +#define MUSB_MAX_END0_PACKET ((uint16_t)MUSB_END0_FIFOSIZE) +#endif + +#define MUSB_END0_START 0x0 +#define MUSB_END0_OUT 0x2 +#define MUSB_END0_IN 0x4 +#define MUSB_END0_STATUS 0x8 + +#define MUSB_END0_STAGE_SETUP 0x0 +#define MUSB_END0_STAGE_TX 0x2 +#define MUSB_END0_STAGE_RX 0x4 +#define MUSB_END0_STAGE_STATUSIN 0x8 +#define MUSB_END0_STAGE_STATUSOUT 0xf +#define MUSB_END0_STAGE_STALL_BIT 0x10 + + +/* + * MUSBMHDRC Register map + */ + +/* Common USB registers */ + +#define MUSB_O_HDRC_FADDR 0x00 /* 8-bit */ +#define MUSB_O_HDRC_POWER 0x01 /* 8-bit */ + +#define MUSB_O_HDRC_INTRTX 0x02 /* 16-bit */ +#define MUSB_O_HDRC_INTRRX 0x04 +#define MUSB_O_HDRC_INTRTXE 0x06 +#define MUSB_O_HDRC_INTRRXE 0x08 +#define MUSB_O_HDRC_INTRUSB 0x0A /* 8 bit */ +#define MUSB_O_HDRC_INTRUSBE 0x0B /* 8 bit */ +#define MUSB_O_HDRC_FRAME 0x0C +#define MUSB_O_HDRC_INDEX 0x0E /* 8 bit */ +#define MUSB_O_HDRC_TESTMODE 0x0F /* 8 bit */ + + +/* Additional Control Registers */ + +#define MUSB_O_HDRC_DEVCTL 0x60 /* 8 bit */ + +/* These are actually indexed: */ +#define MUSB_O_HDRC_TXFIFOSZ 0x62 /* 8-bit (see masks) */ +#define MUSB_O_HDRC_RXFIFOSZ 0x63 /* 8-bit (see masks) */ +#define MUSB_O_HDRC_TXFIFOADD 0x64 /* 16-bit offset shifted right 3 */ +#define MUSB_O_HDRC_RXFIFOADD 0x66 /* 16-bit offset shifted right 3 */ + + + +#define MUSB_O_HDRC_TOPCONTROL 0x204 /* top control register 16-bit */ + +/* offsets to registers in flat model */ +#define MUSB_O_HDRC_TXMAXP 0x00 +#define MUSB_O_HDRC_TXCSR 0x02 +#define MUSB_O_HDRC_CSR0 MUSB_O_HDRC_TXCSR /* re-used for EP0 */ +#define MUSB_O_HDRC_RXMAXP 0x04 +#define MUSB_O_HDRC_RXCSR 0x06 +#define MUSB_O_HDRC_RXCOUNT 0x08 +#define MUSB_O_HDRC_COUNT0 MUSB_O_HDRC_RXCOUNT /* re-used for EP0 */ +#define MUSB_O_HDRC_TXTYPE 0x0A +#define MUSB_O_HDRC_TYPE0 MUSB_O_HDRC_TXTYPE /* re-used for EP0 */ +#define MUSB_O_HDRC_TXINTERVAL 0x0B +#define MUSB_O_HDRC_NAKLIMIT0 MUSB_O_HDRC_TXINTERVAL /* re-used for EP0 */ +#define MUSB_O_HDRC_RXTYPE 0x0C +#define MUSB_O_HDRC_RXINTERVAL 0x0D +#define MUSB_O_HDRC_FIFOSIZE 0x0F +#define MUSB_O_HDRC_CONFIGDATA MUSB_O_HDRC_FIFOSIZE /* re-used for EP0 */ + +#define MUSB_END_OFFSET(end, offset) (0x100 + (0x10*end) + offset) + +/* "bus control" registers */ +#define MUSB_O_HDRC_TXFUNCADDR 0x00 +#define MUSB_O_HDRC_TXHUBADDR 0x02 +#define MUSB_O_HDRC_TXHUBPORT 0x03 + +#define MUSB_O_HDRC_RXFUNCADDR 0x04 +#define MUSB_O_HDRC_RXHUBADDR 0x06 +#define MUSB_O_HDRC_RXHUBPORT 0x07 + +#define MUSB_BUSCTL_OFFSET(end, offset) (0x80 + (8*end) + offset) + +/* + * MUSBHDRC Register bit masks + */ + +/* POWER */ + +#define MUSB_M_POWER_ISOUPDATE 0x80 +#define MUSB_M_POWER_SOFTCONN 0x40 +#define MUSB_M_POWER_HSENAB 0x20 +#define MUSB_M_POWER_HSMODE 0x10 +#define MUSB_M_POWER_RESET 0x08 +#define MUSB_M_POWER_RESUME 0x04 +#define MUSB_M_POWER_SUSPENDM 0x02 +#define MUSB_M_POWER_ENSUSPEND 0x01 + +/* INTRUSB */ +#define MUSB_M_INTR_SUSPEND 0x01 +#define MUSB_M_INTR_RESUME 0x02 +#define MUSB_M_INTR_RESET 0x04 +#define MUSB_M_INTR_BABBLE 0x04 +#define MUSB_M_INTR_SOF 0x08 +#define MUSB_M_INTR_CONNECT 0x10 +#define MUSB_M_INTR_DISCONNECT 0x20 +#define MUSB_M_INTR_SESSREQ 0x40 +#define MUSB_M_INTR_VBUSERROR 0x80 /* FOR SESSION END */ +#define MUSB_M_INTR_EP0 0x01 /* FOR EP0 INTERRUPT */ + +/* DEVCTL */ +#define MUSB_M_DEVCTL_BDEVICE 0x80 +#define MUSB_M_DEVCTL_FSDEV 0x40 +#define MUSB_M_DEVCTL_LSDEV 0x20 +#define MUSB_M_DEVCTL_VBUS 0x18 +#define MUSB_S_DEVCTL_VBUS 3 +#define MUSB_M_DEVCTL_HM 0x04 +#define MUSB_M_DEVCTL_HR 0x02 +#define MUSB_M_DEVCTL_SESSION 0x01 + +/* TESTMODE */ + +#define MUSB_M_TEST_FORCE_HOST 0x80 +#define MUSB_M_TEST_FIFO_ACCESS 0x40 +#define MUSB_M_TEST_FORCE_FS 0x20 +#define MUSB_M_TEST_FORCE_HS 0x10 +#define MUSB_M_TEST_PACKET 0x08 +#define MUSB_M_TEST_K 0x04 +#define MUSB_M_TEST_J 0x02 +#define MUSB_M_TEST_SE0_NAK 0x01 + +/* allocate for double-packet buffering (effectively doubles assigned _SIZE) */ +#define MUSB_M_FIFOSZ_DPB 0x10 +/* allocation size (8, 16, 32, ... 4096) */ +#define MUSB_M_FIFOSZ_SIZE 0x0f + +/* CSR0 */ +#define MUSB_M_CSR0_FLUSHFIFO 0x0100 +#define MUSB_M_CSR0_TXPKTRDY 0x0002 +#define MUSB_M_CSR0_RXPKTRDY 0x0001 + +/* CSR0 in Peripheral mode */ +#define MUSB_M_CSR0_P_SVDSETUPEND 0x0080 +#define MUSB_M_CSR0_P_SVDRXPKTRDY 0x0040 +#define MUSB_M_CSR0_P_SENDSTALL 0x0020 +#define MUSB_M_CSR0_P_SETUPEND 0x0010 +#define MUSB_M_CSR0_P_DATAEND 0x0008 +#define MUSB_M_CSR0_P_SENTSTALL 0x0004 + +/* CSR0 in Host mode */ +#define MUSB_M_CSR0_H_NO_PING 0x0800 +#define MUSB_M_CSR0_H_WR_DATATOGGLE 0x0400 /* set to allow setting: */ +#define MUSB_M_CSR0_H_DATATOGGLE 0x0200 /* data toggle control */ +#define MUSB_M_CSR0_H_NAKTIMEOUT 0x0080 +#define MUSB_M_CSR0_H_STATUSPKT 0x0040 +#define MUSB_M_CSR0_H_REQPKT 0x0020 +#define MUSB_M_CSR0_H_ERROR 0x0010 +#define MUSB_M_CSR0_H_SETUPPKT 0x0008 +#define MUSB_M_CSR0_H_RXSTALL 0x0004 + +/* TxType/RxType */ +#define MUSB_M_TYPE_SPEED 0xc0 +#define MUSB_S_TYPE_SPEED 6 +#define MUSB_TYPE_SPEED_HIGH 1 +#define MUSB_TYPE_SPEED_FULL 2 +#define MUSB_TYPE_SPEED_LOW 3 +#define MUSB_M_TYPE_PROTO 0x30 +#define MUSB_S_TYPE_PROTO 4 +#define MUSB_M_TYPE_REMOTE_END 0xf + +/* CONFIGDATA */ + +#define MUSB_M_CONFIGDATA_MPRXE 0x80 /* auto bulk pkt combining */ +#define MUSB_M_CONFIGDATA_MPTXE 0x40 /* auto bulk pkt splitting */ +#define MUSB_M_CONFIGDATA_BIGENDIAN 0x20 +#define MUSB_M_CONFIGDATA_HBRXE 0x10 /* HB-ISO for RX */ +#define MUSB_M_CONFIGDATA_HBTXE 0x08 /* HB-ISO for TX */ +#define MUSB_M_CONFIGDATA_DYNFIFO 0x04 /* dynamic FIFO sizing */ +#define MUSB_M_CONFIGDATA_SOFTCONE 0x02 /* SoftConnect */ +#define MUSB_M_CONFIGDATA_UTMIDW 0x01 /* data width 0 => 8bits, 1 => 16bits */ + +/* TXCSR in Peripheral and Host mode */ + +#define MUSB_M_TXCSR_AUTOSET 0x8000 +#define MUSB_M_TXCSR_ISO 0x4000 +#define MUSB_M_TXCSR_MODE 0x2000 +#define MUSB_M_TXCSR_DMAENAB 0x1000 +#define MUSB_M_TXCSR_FRCDATATOG 0x0800 +#define MUSB_M_TXCSR_DMAMODE 0x0400 +#define MUSB_M_TXCSR_CLRDATATOG 0x0040 +#define MUSB_M_TXCSR_FLUSHFIFO 0x0008 +#define MUSB_M_TXCSR_FIFONOTEMPTY 0x0002 +#define MUSB_M_TXCSR_TXPKTRDY 0x0001 + +/* TXCSR in Peripheral mode */ + +#define MUSB_M_TXCSR_P_INCOMPTX 0x0080 +#define MUSB_M_TXCSR_P_SENTSTALL 0x0020 +#define MUSB_M_TXCSR_P_SENDSTALL 0x0010 +#define MUSB_M_TXCSR_P_UNDERRUN 0x0004 + +/* TXCSR in Host mode */ + +#define MUSB_M_TXCSR_H_WR_DATATOGGLE 0x0200 +#define MUSB_M_TXCSR_H_DATATOGGLE 0x0100 +#define MUSB_M_TXCSR_H_NAKTIMEOUT 0x0080 +#define MUSB_M_TXCSR_H_RXSTALL 0x0020 +#define MUSB_M_TXCSR_H_ERROR 0x0004 + +/* RXCSR in Peripheral and Host mode */ + +#define MUSB_M_RXCSR_AUTOCLEAR 0x8000 +#define MUSB_M_RXCSR_DMAENAB 0x2000 +#define MUSB_M_RXCSR_DISNYET 0x1000 +#define MUSB_M_RXCSR_DMAMODE 0x0800 +#define MUSB_M_RXCSR_INCOMPRX 0x0100 +#define MUSB_M_RXCSR_CLRDATATOG 0x0080 +#define MUSB_M_RXCSR_FLUSHFIFO 0x0010 +#define MUSB_M_RXCSR_DATAERROR 0x0008 +#define MUSB_M_RXCSR_FIFOFULL 0x0002 +#define MUSB_M_RXCSR_RXPKTRDY 0x0001 + +/* RXCSR in Peripheral mode */ + +#define MUSB_M_RXCSR_P_ISO 0x4000 +#define MUSB_M_RXCSR_P_SENTSTALL 0x0040 +#define MUSB_M_RXCSR_P_SENDSTALL 0x0020 +#define MUSB_M_RXCSR_P_OVERRUN 0x0004 + +/* RXCSR in Host mode */ + +#define MUSB_M_RXCSR_H_AUTOREQ 0x4000 +#define MUSB_M_RXCSR_H_WR_DATATOGGLE 0x0400 +#define MUSB_M_RXCSR_H_DATATOGGLE 0x0200 +#define MUSB_M_RXCSR_H_RXSTALL 0x0040 +#define MUSB_M_RXCSR_H_REQPKT 0x0020 +#define MUSB_M_RXCSR_H_ERROR 0x0004 + +/* HUBADDR */ +#define MUSB_M_HUBADDR_MULTI_TT 0x80 + + +/* TXCSR in Peripheral and Host mode */ + +#define MUSB_M_TXCSR2_AUTOSET 0x80 +#define MUSB_M_TXCSR2_ISO 0x40 +#define MUSB_M_TXCSR2_MODE 0x20 +#define MUSB_M_TXCSR2_DMAENAB 0x10 +#define MUSB_M_TXCSR2_FRCDATATOG 0x08 +#define MUSB_M_TXCSR2_DMAMODE 0x04 + +#define MUSB_M_TXCSR1_CLRDATATOG 0x40 +#define MUSB_M_TXCSR1_FLUSHFIFO 0x08 +#define MUSB_M_TXCSR1_FIFONOTEMPTY 0x02 +#define MUSB_M_TXCSR1_TXPKTRDY 0x01 + +/* TXCSR in Peripheral mode */ + +#define MUSB_M_TXCSR1_P_INCOMPTX 0x80 +#define MUSB_M_TXCSR1_P_SENTSTALL 0x20 +#define MUSB_M_TXCSR1_P_SENDSTALL 0x10 +#define MUSB_M_TXCSR1_P_UNDERRUN 0x04 + +/* TXCSR in Host mode */ + +#define MUSB_M_TXCSR1_H_NAKTIMEOUT 0x80 +#define MUSB_M_TXCSR1_H_RXSTALL 0x20 +#define MUSB_M_TXCSR1_H_ERROR 0x04 + +/* RXCSR in Peripheral and Host mode */ + +#define MUSB_M_RXCSR2_AUTOCLEAR 0x80 +#define MUSB_M_RXCSR2_DMAENAB 0x20 +#define MUSB_M_RXCSR2_DISNYET 0x10 +#define MUSB_M_RXCSR2_DMAMODE 0x08 +#define MUSB_M_RXCSR2_INCOMPRX 0x01 + +#define MUSB_M_RXCSR1_CLRDATATOG 0x80 +#define MUSB_M_RXCSR1_FLUSHFIFO 0x10 +#define MUSB_M_RXCSR1_DATAERROR 0x08 +#define MUSB_M_RXCSR1_FIFOFULL 0x02 +#define MUSB_M_RXCSR1_RXPKTRDY 0x01 + +/* RXCSR in Peripheral mode */ + +#define MUSB_M_RXCSR2_P_ISO 0x40 +#define MUSB_M_RXCSR1_P_SENTSTALL 0x40 +#define MUSB_M_RXCSR1_P_SENDSTALL 0x20 +#define MUSB_M_RXCSR1_P_OVERRUN 0x04 + +/* RXCSR in Host mode */ + +#define MUSB_M_RXCSR2_H_AUTOREQ 0x40 +#define MUSB_M_RXCSR1_H_RXSTALL 0x40 +#define MUSB_M_RXCSR1_H_REQPKT 0x20 +#define MUSB_M_RXCSR1_H_ERROR 0x04 + +/* Top control register */ +#define MUSB_MODE_ULPI 0x9 +#define MUSB_MODE_SRST 0x4 + + +/* ---------------------------- end point status ------------------------- */ + +#define MUSB_GADGET_EP_ACTIVE 0 +#define MUSB_GADGET_EP_HALTED 1 +#define MUSB_GADGET_EP_DISABLED 2 + +struct nomadik_ep { + spinlock_t lock; + struct usb_ep ep; + struct list_head req_list; + unsigned long irqs; + struct list_head iso; + const struct usb_endpoint_descriptor *desc; + char name[14]; + u16 maxpacket; + u8 bmAttributes; + u8 binactive; + unsigned double_buf:1; + unsigned stopped:1; + unsigned fnf:1; + unsigned has_dma:1; + u8 ackwait; + u8 dma_channel; + u8 is_tx; + u8 end_number; + u16 dma_counter; + int lch; + struct nomadik_udc *udc; + struct timer_list timer; +}; + +struct nomadik_req { + struct usb_request req; + struct list_head completion_list; + u8 is_tx; + u8 end_number; + unsigned dma_bytes; + unsigned mapped:1; +}; + +struct nomadik_udc{ + spinlock_t lock; + char name[32]; + u8 bulk_tx_end; + u8 bulk_rx_end; + u8 end0_stage; + u8 bulk_split; + u8 bulk_combine; + u8 address; + u8 set_address_flag; + u8 set_config_flag; + u8 is_selfpowered; + uint8_t bDeviceState; + uint8_t test_mode_flag; + uint8_t test_mode_value; + uint8_t end_count; + uint32_t end_mask; + struct nomadik_ep end[MUSB_MAX_USB_ENDS]; + struct usb_gadget gadget; + struct usb_gadget_driver *driver; + void *end0_buffer_ptr; + struct list_head iso; + struct completion *done; + struct device *dev; +} ; + +struct t_udc_end0_buffer { + u8 data[MUSB_END0_FIFOSIZE]; + u16 count; +}; + +struct t_ep_desc{ + u8 type; + u8 dir; + u16 size; + u8 dbe; +} ; + + +#define MUSB_EPD_AUTOCONFIG 0 + +#define MUSB_EPD_T_CNTRL 1 +#define MUSB_EPD_T_ISOC 2 +#define MUSB_EPD_T_BULK 3 +#define MUSB_EPD_T_INTR 4 + +#define MUSB_EPD_D_INOUT 0 +#define MUSB_EPD_D_TX 1 +#define MUSB_EPD_D_RX 2 + +#define MUSB_FIFO_OFFSET(end) (0x20 + (end * 4)) + +#define MUSB_READ8(base_ptr, offset) *((volatile uint8_t*)((unsigned long)base_ptr + offset)) +#define MUSB_READ16(base_ptr, offset) *((volatile uint16_t*)((unsigned long)base_ptr + offset)) +#define MUSB_READ32(base_ptr, offset) *((volatile uint32_t*)((unsigned long)base_ptr + offset)) + + +#undef MUSB_WRITE8 +#define MUSB_WRITE8(base_ptr, offset, data) { \ + DBG(4, "WRITE8(%p, %x, %02x)\n", base_ptr, offset, data); \ + wmb(); \ + *(volatile uint8_t*)((unsigned long)base_ptr + offset) = data; \ + } + +#undef MUSB_WRITE16 +#define MUSB_WRITE16(base_ptr, offset, data) { \ + DBG(4, "WRITE16(%p, %x, %04x)\n", base_ptr, offset, data); \ + wmb(); \ + *(volatile uint16_t*)((unsigned long)base_ptr + offset) = data; \ + } + + +#undef MUSB_WRITE32 +#define MUSB_WRITE32(base_ptr, offset, data) { \ + DBG(4, "WRITE32(%p, %x, %08x)\n", base_ptr, offset, data); \ + wmb(); \ + *(volatile uint32_t*)((unsigned long)base_ptr + offset) = data; \ + } + +#define MUSB_SELECTEND(base_ptr, end) \ + MUSB_WRITE8(base_ptr, MUSB_O_HDRC_INDEX, end) + +#define MUSB_READCSR8(base_ptr, offset, end) \ + MUSB_READ8(base_ptr, (offset + 0x10)) + +#define MUSB_READCSR16(base_ptr, offset, end) \ + MUSB_READ16(base_ptr, (offset + 0x10)) + +#define MUSB_WRITECSR8(base_ptr, offset, end, data) \ + MUSB_WRITE8(base_ptr, (offset + 0x10), data) + +#define MUSB_WRITECSR16(base_ptr, offset, end, data) \ + MUSB_WRITE16(base_ptr, (offset + 0x10), data) + + +#ifdef USE_ISO +static unsigned fifo_mode = 3; +#else +static unsigned fifo_mode = 0; +#endif + + +#define MUSB_TEST_PACKET_SIZE 53 +const uint8_t musb_test_pkt[MUSB_TEST_PACKET_SIZE] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, + 0xee, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xbf, 0xdf, + 0xef, 0xf7, 0xfb, 0xfd, 0xfc, 0x7e, 0xbf, 0xdf, + 0xef, 0xf7, 0xfb, 0xfd, 0x7e +}; + +#define EP_NUMBER(ep) ( ((struct nomadik_ep *)(ep))->end_number ) + + +#define EP_SPIN_LOCK(_ep) spin_lock( &(( struct nomadik_ep *)(_ep))->lock ) +#define EP_SPIN_UNLOCK(_ep) spin_unlock( &(( struct nomadik_ep *)(_ep))->lock ) + +#define EP_SPIN_LOCK_IRQSAVE(_ep, _flags) spin_lock_irqsave(&(( struct nomadik_ep *)(_ep))->lock, _flags ) +#define EP_SPIN_UNLOCK_IRQRESTORE(_ep, _flags) spin_unlock_irqrestore( &(( struct nomadik_ep *)(_ep))->lock, _flags) + +#ifdef USE_DMA +static unsigned use_dma = 1; + +/* "modprobe nomadik_udc use_dma=y", or else as a kernel + * boot parameter "nomadik_udc:use_dma=y" + */ +module_param (use_dma, bool, 0); +MODULE_PARM_DESC (use_dma, "enable/disable DMA"); +#else /* !USE_DMA */ + + /* save a bit of code */ +#define use_dma 0 +#endif /* !USE_DMA */ + +#define DRIVER_DESC "NOMADIK USB driver" +static const char driver_name[] = "NOMADIK USBDEV"; +static const char driver_desc[] = DRIVER_DESC; + +extern uint8_t b_hnp_suspend; +extern MGC_LinuxCd *udc_address; +static struct nomadik_udc *dev_context; +static unsigned long udc_base_addr; + +/* + * Function declarations + */ + +#ifdef DEBUG_LEVEL +void udc_print_regs(void); +static char *decode_csr0(uint16_t csr0) ; +static char *decode_bits(uint16_t value) ; +static char *decode_txcsr(uint16_t txcsr) ; +static char *decode_devctl(uint16_t devctl) ; +static char *decode_ep0stage(uint8_t stage) ; +static char * decode_request(struct usb_ctrlrequest *req); +void udc_dump_regs(uint8_t* base_addr, int multipoint, uint8_t bEnd); +#endif + +/* + * Gadget Register/De-Register Operations + */ +int usb_gadget_register_driver(struct usb_gadget_driver *driver); +int usb_gadget_unregister_driver(struct usb_gadget_driver *driver); + +/* + * Gadget Operations + */ +int udc_gadget_wakeup(struct usb_gadget *gadget); +int udc_gadget_getframe(struct usb_gadget *gadget); +int udc_gadget_setselfpowered(struct usb_gadget *gadget, int is_selfpowered); +int udc_gadget_ioctl(struct usb_gadget *gadget, unsigned code, unsigned long param); + +/* + * Gadget Endpoint Operations + */ +void * nomadik_alloc_buffer( + struct usb_ep *_ep, + unsigned bytes, + dma_addr_t *dma, + gfp_t gfp_flags + ); +void nomadik_free_buffer( + struct usb_ep *_ep, + void *buf, + dma_addr_t dma, + unsigned bytes + ); + +int nomadik_ep_disable(struct usb_ep *_ep); +int nomadik_ep_set_halt(struct usb_ep *_ep, int value); +int nomadik_ep_dequeue(struct usb_ep *ep, struct usb_request *req_ptr); +void nomadik_free_request(struct usb_ep *ep, struct usb_request *_req); +int nomadik_ep_queue(struct usb_ep *ep, struct usb_request *req, gfp_t gfp_flags); +int nomadik_ep_enable(struct usb_ep *_ep, const struct usb_endpoint_descriptor *desc); +struct usb_request * nomadik_alloc_request(struct usb_ep *ep, gfp_t gfp_flags); + +/* + * Gadget Endpoint/Interrupt Operation + */ +int ep0_rxstate(void); +int ep0_txstate(void); +uint8_t udc_ep0_irq(void); +void udc_ep_tx_irq(uint8_t bEnd); +void udc_ep_rx_irq(uint8_t bEnd); +void mgc_complete_ep0_request(void) ; +void handle_ep0_completition_irq(void) ; +int service_rx_request(struct usb_ctrlrequest *control_request_ptr); +void txstate(struct nomadik_udc* dev_context, struct nomadik_req* req); +void rxstate(struct nomadik_udc* dev_context, struct nomadik_req* req); +uint8_t is_rx_request(const struct usb_ctrlrequest *control_request_ptr); +uint8_t is_tx_request(const struct usb_ctrlrequest *control_request_ptr); +int service_tx_request(const struct usb_ctrlrequest *control_request_ptr); +inline int get_ep_packet_size(struct nomadik_udc* dev_context, uint8_t bEnd); +uint8_t is_zerodata_request(const struct usb_ctrlrequest *control_request_ptr); +int udc_read_control_request(struct nomadik_udc* dev_context, uint16_t wcount); +void service_tx_status_request(const struct usb_ctrlrequest *control_request_ptr); +int service_zero_data_request(struct nomadik_udc* dev_context, struct usb_ctrlrequest *control_request_ptr); + +/* + * Gadget FIFO Operations + */ +int nomadik_ep_fifo_status(struct usb_ep *ep); +void nomadik_ep_fifo_flush(struct usb_ep *ep); +void udc_unload_fifo(const uint8_t* base_ptr, uint8_t bEnd, uint16_t wcount, uint8_t* dest_ptr); +void udc_load_fifo(const uint8_t* base_ptr, uint8_t bEnd, uint16_t wcount, const uint8_t* pSource); + +/* + * Gadget Queue Operations + */ +int queue_length(struct list_head *lh) ; + +/* + * USB System interrupt handler + */ +void udc_resume(void) ; +void udc_suspend(void) ; +void udc_disconnect_isr(void) ; + +/* + * Common handlers + */ +void udc_reset(void) ; +void musb_reset_isr(void); +int __init udc_setup(void); +void udc_intr_disable(void); +int alloc_n_config_udc(void); +void nomadik_release_udc(void); +void use_ep(struct nomadik_ep *ep); +void nuke(struct nomadik_ep *ep, int status); +void nomadik_udc_release(struct device *dev); +int complete_request(struct usb_request *req_ptr); +int udc_complete_request(struct usb_request *req_ptr, int status); +irqreturn_t nomadik_udc_irq(int irq, void *udc, struct pt_regs *r); +void done(struct nomadik_ep *ep, struct nomadik_req *req, int status); +int forward_to_driver(const struct usb_ctrlrequest *control_request_ptr); +inline struct usb_request* udc_current_request( struct nomadik_ep * end_ptr); +void udc_restart_request(struct nomadik_udc *dev_context, struct usb_request *req_ptr); +unsigned __init nomadik_ep_setup(char *name, u8 dir, u8 type, unsigned buf, unsigned maxp, int dbuf); + + +static struct usb_ep_ops nomadik_ep_ops = { + .enable = nomadik_ep_enable, + .disable = nomadik_ep_disable, + + .alloc_request = nomadik_alloc_request, + .free_request = nomadik_free_request, + + .alloc_buffer = nomadik_alloc_buffer, + .free_buffer = nomadik_free_buffer, + + .queue = nomadik_ep_queue, + .dequeue = nomadik_ep_dequeue, + + .set_halt = nomadik_ep_set_halt, + +}; + +const struct usb_gadget_ops nomadik_gadget_ops = { + get_frame : udc_gadget_getframe, + wakeup : udc_gadget_wakeup, + set_selfpowered : udc_gadget_setselfpowered, + ioctl : udc_gadget_ioctl +}; + + + +static struct { + spinlock_t lock; + struct list_head req_list; +} udc_scheduler_queue; + --- /dev/null +++ linux-2.6.20/drivers/usb/nomadik/otg_func.c @@ -0,0 +1,196 @@ +/* + * linux/drivers/usb/nomadik/otg_func.c + * + * Copyright 2007, STMicroelectronics + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/************************************************** + OTG - HNP and SRP +**************************************************/ + +#include +#include +#include +#include "musbdefs.h" +extern int nomadik_udc_init(MGC_LinuxCd *pThis); +extern int __init udc_setup(void) ; +extern void udc_intr_disable(void); +extern void udc_reset(void) ; +extern uint8_t MGC_HdrcReadUlpiReg(MGC_LinuxCd* pThis, uint8_t bAddr, uint8_t* pbData); +extern void nomadik_release_udc(void); +extern void mgc_hdrc_enable(MGC_LinuxCd* pThis); +extern struct usb_hcd *hcd1; +extern MGC_LinuxCd *udc_address; +void set_host_a_idle(void); +void srp_initiate(void); +void hnp_initiate(void); +void driver_change_mode_handler(uint8_t role); +int otg_send_set_hnp_feature(void); +extern uint8_t b_hnp_suspend; +extern uint8_t b_hnp_init; +extern void otg_disconnect(MGC_LinuxCd *pThis); +extern void udc_disconnect_isr(void); +extern void del_timer_func(void); +uint8_t htd; +uint8_t host_a_idle=0; + +int otg_send_set_hnp_feature(void) +{ + unsigned int result; + struct usb_device *dev; + printk(" Before crash 1 \n "); + dev = udc_address->pRootDevice; + result = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), USB_REQ_SET_FEATURE,USB_RECIP_DEVICE, 3, 0, NULL, 0, + HZ * USB_CTRL_SET_TIMEOUT); + if (result < 0) { + printk(KERN_INFO"set feature returned %d\n", result); + return result; + } + return 0; +} + +void set_host_a_idle(void) +{ + host_a_idle=1; + printk(" set_host_a_idle invoke \n "); +} + +void srp_initiate(void) +{ + uint8_t* pBase = (uint8_t*)udc_address->pRegs; + uint8_t devctl=MGC_Read8(pBase, MGC_O_HDRC_DEVCTL); + MGC_Write8(pBase, MGC_O_HDRC_DEVCTL, (devctl|1)); + + printk(" srp_initiate \n "); +} + +void hnp_initiate(void) +{ + uint8_t* pBase = (uint8_t*)udc_address->pRegs; + uint8_t devctl = MGC_Read8(pBase, MGC_O_HDRC_DEVCTL); + int result= otg_send_set_hnp_feature(); + int temp = 0; + + b_hnp_init=1; + + if(result<0) + { + printk("hnp feature failed \n"); + return ; + } + + temp = MGC_Read8(pBase, MGC_O_HDRC_POWER); + MGC_Write8(pBase, MGC_O_HDRC_POWER, temp | MGC_M_POWER_ENSUSPEND); + + temp = MGC_Read8(pBase, MGC_O_HDRC_POWER); + + MGC_Write8(pBase, MGC_O_HDRC_POWER, temp | MGC_M_POWER_SUSPENDM); + temp = MGC_Read8(pBase, MGC_O_HDRC_POWER); + + devctl = MGC_Read8(pBase, MGC_O_HDRC_DEVCTL); + MGC_Write8(pBase, MGC_O_HDRC_DEVCTL, devctl | MGC_M_DEVCTL_HR); + devctl = MGC_Read8(pBase, MGC_O_HDRC_DEVCTL); + devctl = MGC_Read8(pBase, MGC_O_HDRC_DEVCTL); + + printk("devtcl after suspend %x\n",devctl); + printk(" hnp_initiate \n "); + +} + + +void driver_change_mode_handler(uint8_t role) +{ + uint8_t* pBase = (uint8_t*)udc_address->pRegs; + uint8_t linestate = 0; + uint8_t devctl = MGC_Read8(pBase, MGC_O_HDRC_DEVCTL); + uint8_t power = 0; + + /*1=Device to Host), 2= Host to Device */ + if ( role == 1){ + printk ("Device to Host \n"); + + MGC_HdrcReadUlpiReg(udc_address, 0x15, &linestate); + printk("line state %x\n",linestate); + printk("timer deleted \n"); + + del_timer_func(); + devctl = MGC_Read8(pBase, MGC_O_HDRC_DEVCTL); + + power=MGC_Read8(pBase, MGC_O_HDRC_POWER); + MGC_Write8(pBase, MGC_O_HDRC_POWER,power &0xBF); + + power=MGC_Read8(pBase, MGC_O_HDRC_POWER); + printk("power = %x \n",power); + udc_disconnect_isr(); + mgc_hdrc_enable(udc_address); + + MGC_Write8(pBase, MGC_O_HDRC_DEVCTL, devctl | 0x01); + devctl = MGC_Read8(pBase, MGC_O_HDRC_DEVCTL); + printk("devtcl setting host request and session %x\n",devctl); + + + MGC_HdrcReadUlpiReg(udc_address, 0x15, &linestate); + printk("line state end %x\n",linestate); + role=0; + } + /* Host to Device */ + else + { + uint8_t power; + printk ("Host to Device\n"); + + MGC_HdrcReadUlpiReg(udc_address, 0x13, &htd); + printk("temp in host to device%x \n",htd); + + del_timer_func(); + MGC_Write8(pBase, MGC_O_HDRC_DEVCTL, devctl & ~MGC_M_DEVCTL_HR); + power=MGC_Read8(pBase, MGC_O_HDRC_POWER); + MGC_Write8(pBase, MGC_O_HDRC_POWER,power | MGC_M_POWER_SOFTCONN ); + del_timer_func(); + + MGC_HdrcReadUlpiReg(udc_address, 0x13, &htd); + printk("temp in host to device end%x \n",htd); + + role=0; + } +} + + +void otg_dev_deinit(void) +{ + +} + +void otg_dev_init(void) +{ + +} + +void otg_host_init(void) +{ + + +} + +void otg_host_deinit(void) +{ + +} + + + + --- /dev/null +++ linux-2.6.20/drivers/usb/nomadik/otg_pwm.c @@ -0,0 +1,46 @@ +/* + * linux/drivers/usb/nomadik/otg_pwm.c + * + * Copyright 2007, STMicroelectronics + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/*********************************** + Power Mangement Routines +***********************************/ +#include "musbdefs.h" +#include +#include +#include + +void otg_deep_sleep(void); +void otg_wakeup(void); + +void otg_deep_sleep(void) +{ + printk(" otg_deep_sleep invoked \n"); + nomadik_gpio_altfuncdisable(GPIO_ALT_USB_OTG,"OTG"); + +} +void otg_wakeup(void) +{ + DBG(2, "<==\n"); + printk(" otg_wakeup invoked \n"); + + nomadik_gpio_altfuncenable(GPIO_ALT_USB_OTG,"OTG"); + + direct_bus_init(); +} --- /dev/null +++ linux-2.6.20/drivers/usb/nomadik/plat_arc.h @@ -0,0 +1,92 @@ +/* + * linux/drivers/usb/nomadik/plat_arc.h + * + * Copyright 2007, STMicroelectronics + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __MUSB_LINUX_PLATFORM_ARCH_H__ +#define __MUSB_LINUX_PLATFORM_ARCH_H__ + +/* This configuration needs a few more write barriers */ +#ifndef MUSB_WMB +# ifdef CONFIG_ATI_XILLEON +# define MUSB_WMB() wmb() +# else +# define MUSB_WMB() +# endif +#endif + +#if 1 + +#define MGC_Read8(_pBase, _offset) *((volatile uint8_t*)(_pBase + _offset)) +#define MGC_Read16(_pBase, _offset) *((volatile uint16_t*)(_pBase + _offset)) +#define MGC_Read32(_pBase, _offset) *((volatile uint32_t*)(_pBase + _offset)) + +#else +static inline uint8_t MGC_Read8(void *_pBase, uint32_t _offset) +{ + uint8_t val = *(volatile uint8_t*)((uint32_t)_pBase + _offset); + DBG(9, "Read8(0x%p, 0x%08x) -> 0x%02x\n", _pBase, _offset, val); + return val; +} + +static inline uint16_t MGC_Read16(void *_pBase, uint32_t _offset) +{ + uint16_t val = *(volatile uint16_t*)(_pBase + _offset); + DBG(9, "Read16(0x%p, 0x%08x) -> 0x%04x\n", _pBase, _offset, val); + return val; +} + +static inline uint32_t MGC_Read32(void *_pBase, uint32_t _offset) +{ + uint32_t val = *(volatile uint32_t*)(_pBase + _offset); + DBG(9, "Read32(0x%p, 0x%08x) -> 0x%08x\n", _pBase, _offset, val); + return val; +} + +#endif + +#if 0 + +#define MGC_Write8(_pBase, _offset, _data) MGC_Read8(_pBase, _offset) = _data +#define MGC_Write16(_pBase, _offset, _data) MGC_Read16(_pBase, _offset) = _data +#define MGC_Write32(_pBase, _offset, _data) MGC_Read32(_pBase, _offset) = _data + +#endif + +#undef MGC_Write8 +#define MGC_Write8(_pBase, _offset, _data) { \ + DBG(4, "Write8(%p, %x, %02x)\n", _pBase, _offset, _data); \ + MUSB_WMB(); \ + *(volatile uint8_t*)(_pBase + _offset) = _data; \ +} + +#undef MGC_Write16 +#define MGC_Write16(_pBase, _offset, _data) { \ + DBG(4, "Write16(%p, %x, %04x)\n", _pBase, _offset, _data); \ + MUSB_WMB(); \ + *(volatile uint16_t*)(_pBase + _offset) = _data; \ +} + +#undef MGC_Write32 +#define MGC_Write32(_pBase, _offset, _data) { \ + DBG(4, "Write32(%p, %x, %08x)\n", _pBase, _offset, _data); \ + MUSB_WMB(); \ + *(volatile uint32_t*)(_pBase + _offset) = _data; \ +} + +#endif /* multiple inclusion protection */ --- /dev/null +++ linux-2.6.20/drivers/usb/nomadik/plat_cnf.h @@ -0,0 +1,208 @@ +/* + * usb/nomadik/plat_cnf.h + * + * Copyright 2007, STMicroelectronics + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __MUSB_LINUX_CONFIG_H__ +#define __MUSB_LINUX_CONFIG_H__ + +/* MUSB_AHB_ID is now passed as argument */ + +#ifdef MUSB_STATIC_CONFIG + +/* + * Get core configuration from a header converted (by cfg_conv) + * from the Verilog config file generated by the core config utility + */ +/** Core configuration */ +#ifdef MUSB_HDR_CCNF_FILE +#include CONFIG_USB_INVENTRA_MUSB_HDR_CCNF_FILE +#else + +#define MUSB_C_RAM_BITS 2 +#define MUSB_C_NUM_EPS 16 +#endif + +/* + * Handle dynamic FIFO sizing in a way that doesn't create more code + * (but could make your brain hurt) + */ +#ifdef MUSB_C_DYNFIFO_DEF +#define MGC_DFIFO_TOTAL (1 << (MUSB_C_RAM_BITS + 2)) + +/* values for the SZ field */ +#define MGC_BLK_SZ 6 /* 512 bytes */ +#define MGC_CTL_SZ 3 /* 64 bytes */ +#define MGC_ALL_SZ 0 /* 8 bytes minimum for anything (hubs to 64 ports, most HIDs) */ + +#ifdef MUSB_C_HB_TX +#define MGC_ISO_TX_SZ 9 /* 4096 bytes for high-bandwidth (needs 3072) */ +#else +#define MGC_ISO_TX_SZ 7 /* 1024 bytes for normal-bandwidth */ +#endif + +#ifdef MUSB_C_HB_RX +#define MGC_ISO_RX_SZ 9 /* 4096 bytes for high-bandwidth (needs 3072) */ +#else +#define MGC_ISO_RX_SZ 7 /* 1024 bytes for normal-bandwidth */ +#endif + +/* + * Define desires by subtracting all, so impossible ones become negatives + */ +#if MUSB_C_NUM_EPS > 2 +#define MGC_BLK_DB 1 +/* isoch Tx: try a double-buffered one with a double-buffered bulk */ +#define MGC_ISO_TX_DB 1 +#define MGC_DFIFO_ISO_TX (MGC_DFIFO_TOTAL - (1 << (MGC_ISO_TX_SZ+4)) - (1 << (MGC_BLK_SZ+3+MGC_BLK_DB)) - (1 << (MGC_CTL_SZ+3)) - ((MUSB_C_NUM_EPS - 3) * (1 << (MGC_ALL_SZ+3)))) +#if MGC_DFIFO_ISO_TX < 0 +/* no good; try with a single-buffered bulk */ +#undef MGC_BLK_DB +#define MGC_BLK_DB 0 +#undef MGC_DFIFO_ISO_TX +#define MGC_DFIFO_ISO_TX (MGC_DFIFO_TOTAL - (1 << (MGC_ISO_TX_SZ+4)) - (1 << (MGC_BLK_SZ+3+MGC_BLK_DB)) - (1 << (MGC_CTL_SZ+3)) - ((MUSB_C_NUM_EPS - 3) * (1 << (MGC_ALL_SZ+3)))) +#endif +#if MGC_DFIFO_ISO_TX < 0 +/* still no good; try single-buffered isoch Tx */ +#undef MGC_DFIFO_ISO_TX +#undef MGC_ISO_TX_DB +#define MGC_ISO_TX_DB 0 +#define MGC_DFIFO_ISO_TX (MGC_DFIFO_TOTAL - (1 << (MGC_ISO_TX_SZ+3)) - (1 << (MGC_BLK_SZ+3+MGC_BLK_DB)) - (1 << (MGC_CTL_SZ+3)) - ((MUSB_C_NUM_EPS - 3) * (1 << (MGC_ALL_SZ+3)))) +#endif +/* actual isoch Tx size */ +#define MGC_DFIFO_ISO_TX_SIZE ((MGC_DFIFO_ISO_TX < 0) ? 0 : (1 << (MGC_ISO_TX_SZ+3+MGC_ISO_TX_DB))) + +/* isoch Rx: try a double-buffered one with a (current)-buffered bulk */ +#define MGC_ISO_RX_DB 1 +#define MGC_DFIFO_ISO_RX (MGC_DFIFO_TOTAL - MGC_DFIFO_ISO_TX_SIZE - (1 << (MGC_ISO_RX_SZ+4)) - (1 << (MGC_BLK_SZ+3+MGC_BLK_DB)) - (1 << (MGC_CTL_SZ+3)) - ((MUSB_C_NUM_EPS - 3) * (1 << (MGC_ALL_SZ+3)))) +#if MGC_DFIFO_ISO_RX < 0 +/* no good; try with a single-buffered bulk */ +#undef MGC_BLK_DB +#define MGC_BLK_DB 0 +#undef MGC_DFIFO_ISO_RX +#define MGC_DFIFO_ISO_RX (MGC_DFIFO_TOTAL - MGC_DFIFO_ISO_TX_SIZE - (1 << (MGC_ISO_RX_SZ+4)) - (1 << (MGC_BLK_SZ+3+MGC_BLK_DB)) - (1 << (MGC_CTL_SZ+3)) - ((MUSB_C_NUM_EPS - 3) * (1 << (MGC_ALL_SZ+3)))) +#endif +#if MGC_DFIFO_ISO_RX < 0 +/* still no good; try single-buffered isoch Rx */ +#undef MGC_DFIFO_ISO_RX +#undef MGC_ISO_RX_DB +#define MGC_ISO_RX_DB 0 +#define MGC_DFIFO_ISO_RX (MGC_DFIFO_TOTAL - MGC_DFIFO_ISO_TX_SIZE - (1 << (MGC_ISO_RX_SZ+3)) - (1 << (MGC_BLK_SZ+3+MGC_BLK_DB)) - (1 << (MGC_CTL_SZ+3)) - ((MUSB_C_NUM_EPS - 3) * (1 << (MGC_ALL_SZ+3)))) +#endif +/* actual isoch Rx size */ +#define MGC_DFIFO_ISO_RX_SIZE ((MGC_DFIFO_ISO_RX < 0) ? 0 : (1 << (MGC_ISO_RX_SZ+3+MGC_ISO_RX_DB))) + +/* register values the code may use */ +#define MGC_DFIFO_ISO_TX_VAL ((MGC_ISO_TX_DB << 4) | MGC_ISO_TX_SZ) +#define MGC_DFIFO_ISO_RX_VAL ((MGC_ISO_RX_DB << 4) | MGC_ISO_RX_SZ) +#define MGC_DFIFO_BLK_VAL ((MGC_BLK_DB << 4) | MGC_BLK_SZ) + +#else /* !(MUSB_C_NUM_EPS > 2) */ + +/* <= 2 endpoints; make one suitable for bulk */ +#if MGC_DFIFO_TOTAL > 1024 +#define MGC_BLK_DB 1 +#else +#define MGC_BLK_DB 0 +#endif +#define MGC_DFIFO_BLK_VAL ((MGC_BLK_DB << 4) | MGC_BLK_SZ) +#define MGC_DFIFO_ISO_TX -1 +#define MGC_DFIFO_ISO_TX_SIZE 0 +#define MGC_DFIFO_ISO_RX -1 +#define MGC_DFIFO_ISO_RX_SIZE 0 + +#endif /* MUSB_C_NUM_EPS > 2 */ + +/* now compute actual size per remaining end */ +#define MGC_DFIFO_BLK_SIZE (1 << (MGC_BLK_SZ+3+MGC_BLK_DB)) +#define MGC_DFIFO_CTL_SIZE (1 << (MGC_CTL_SZ+3)) +#define MGC_DFIFO_REMAIN (MGC_DFIFO_TOTAL - MGC_DFIFO_ISO_TX_SIZE - MGC_DFIFO_ISO_RX_SIZE - MGC_DFIFO_BLK_SIZE - MGC_DFIFO_CTL_SIZE) + +/* but, if there's a problem, throw out bulk and try again */ +#if MGC_DFIFO_REMAIN < 0 +#undef MGC_DFIFO_BLK_SIZE +#undef MGC_DFIFO_BLK_VAL +#define MGC_DFIFO_BLK_SIZE 0 +#define MGC_DFIFO_BLK_VAL 0 +#define MGC_DFIFO_REMAIN (MGC_DFIFO_TOTAL - MGC_DFIFO_ISO_TX_SIZE - MGC_DFIFO_ISO_RX_SIZE - MGC_DFIFO_BLK_SIZE - MGC_DFIFO_CTL_SIZE) +#endif + +#define MGC_DFIFO_ALL_COUNT (MUSB_C_NUM_EPS - ((MGC_DFIFO_ISO_TX < 0) ? 0 : 1) - ((MGC_DFIFO_ISO_RX < 0) ? 0 : 1) - (MGC_DFIFO_BLK_SIZE ? 1 : 0) - 1) +#if MGC_DFIFO_ALL_COUNT > 0 +#define MGC_DFIFO_ALL_SIZE (MGC_DFIFO_REMAIN / MGC_DFIFO_ALL_COUNT) +#else +#define MGC_DFIFO_ALL_SIZE 0 +#endif +/* set value for remaining */ +#if MGC_DFIFO_ALL_SIZE >= 4096 +#define MGC_DFIFO_ALL_VAL 9 +#elif MGC_DFIFO_ALL_SIZE >= 2048 +#define MGC_DFIFO_ALL_VAL 8 +#elif MGC_DFIFO_ALL_SIZE >= 1024 +#define MGC_DFIFO_ALL_VAL 7 +#elif MGC_DFIFO_ALL_SIZE >= 512 +#define MGC_DFIFO_ALL_VAL 6 +#elif MGC_DFIFO_ALL_SIZE >= 256 +#define MGC_DFIFO_ALL_VAL 5 +#elif MGC_DFIFO_ALL_SIZE >= 128 +#define MGC_DFIFO_ALL_VAL 4 +#elif MGC_DFIFO_ALL_SIZE >= 64 +#define MGC_DFIFO_ALL_VAL 3 +#elif MGC_DFIFO_ALL_SIZE >= 32 +#define MGC_DFIFO_ALL_VAL 2 +#elif MGC_DFIFO_ALL_SIZE >= 16 +#define MGC_DFIFO_ALL_VAL 1 +#else +#define MGC_DFIFO_ALL_VAL 0 +#endif + +#endif /* MUSB_C_DYNFIFO_DEF */ + +#endif /* MUSB_STATIC_CONFIG */ + +/* + * Target-specific configuration declarations + */ + +/** HDRC */ +#define MUSB_CONTROLLER_HDRC 1 + +/** MHDRC */ +#define MUSB_CONTROLLER_MHDRC 2 + +/** + * Board-specific information about a controller + * @field wType one of the MUSB_CONTROLLER_* constants + * @field pBase base address for hard-wired controller + * @field dSize address base size (0==default) + * @field dwIrq IRQ for hard-wired controller + */ +typedef struct +{ + uint16_t wType; + void* pBase; + uint32_t dwIrq; + uint32_t dwSize; +} MUSB_LinuxController; + +/* + * Board-specific array of controller information + */ +extern MUSB_LinuxController MUSB_aLinuxController[]; + +#endif /* multiple inclusion protection */ --- linux-2.6.20.orig/drivers/video/Makefile +++ linux-2.6.20/drivers/video/Makefile @@ -28,10 +28,11 @@ obj-$(CONFIG_FB_CLPS711X) += clp obj-$(CONFIG_FB_CYBER) += cyberfb.o obj-$(CONFIG_FB_CYBER2000) += cyber2000fb.o obj-$(CONFIG_FB_PM2) += pm2fb.o obj-$(CONFIG_FB_PM3) += pm3fb.o +obj-$(CONFIG_FB_NOMADIK_ACCLN) += nomadik/ obj-$(CONFIG_FB_MATROX) += matrox/ obj-$(CONFIG_FB_RIVA) += riva/ vgastate.o obj-$(CONFIG_FB_NVIDIA) += nvidia/ obj-$(CONFIG_FB_ATY) += aty/ macmodes.o obj-$(CONFIG_FB_ATY128) += aty/ macmodes.o --- linux-2.6.20.orig/drivers/video/amba-clcd.c +++ linux-2.6.20/drivers/video/amba-clcd.c @@ -7,10 +7,14 @@ * This file is subject to the terms and conditions of the GNU General Public * License. See the file COPYING in the main directory of this archive * for more details. * * ARM PrimeCell PL110 Color LCD Controller + * + * History: + * 27/06/07 Prafulla Wadaskar + * RGB/BGR convertion logic is inverted in clcdfb_set_bitfields */ #include #include #include #include @@ -22,22 +26,32 @@ #include #include #include #include #include - #include +#include +#include -#define to_clcd(info) container_of(info, struct clcd_fb, fb) +#ifndef CLCD_PER_ID +#define CLCD_PER_ID 0x00041110 +#endif -/* This is limited to 16 characters when displayed by X startup */ -static const char *clcd_name = "CLCD FB"; +#ifndef CLCD_PER_MASK +#define CLCD_PER_MASK 0x000ffffe +#endif -/* +#define to_clcd(info) container_of(info, struct clcd_fb, fb) + +/** + * clcdfb_sleep - Introduces delay or puts the process to sleep + * + * @ms - Duration of sleep or delay + * * Unfortunately, the enable/disable functions may be called either from * process or IRQ context, and we _need_ to delay. This is _not_ good. - */ + **/ static inline void clcdfb_sleep(unsigned int ms) { if (in_atomic()) { mdelay(ms); } else { @@ -115,10 +129,11 @@ clcdfb_set_bitfields(struct clcd_fb *fb, { int ret = 0; memset(&var->transp, 0, sizeof(var->transp)); + var->transp.offset = 15; var->red.msb_right = 0; var->green.msb_right = 0; var->blue.msb_right = 0; switch (var->bits_per_pixel) { @@ -138,13 +153,16 @@ clcdfb_set_bitfields(struct clcd_fb *fb, var->blue.length = 5; /* * Green length can be 5 or 6 depending whether * we're operating in RGB555 or RGB565 mode. */ - if (var->green.length != 5 && var->green.length != 6) - var->green.length = 6; + if (var->green.length != 6) + var->green.length = 5; break; +#ifdef CONFIG_ARCH_NOMADIK + case 24: /*24 bpp packed */ +#endif case 32: if (fb->panel->cntl & CNTL_LCDTFT) { var->red.length = 8; var->green.length = 8; var->blue.length = 8; @@ -159,18 +177,27 @@ clcdfb_set_bitfields(struct clcd_fb *fb, * >= 16bpp displays have separate colour component bitfields * encoded in the pixel data. Calculate their position from * the bitfield length defined above. */ if (ret == 0 && var->bits_per_pixel >= 16) { +#ifdef CONFIG_ARCH_NOMADIK + /* + * this may be critical bug, not tested on other SOCs + * hence encapsulated with ifdef + */ + if (!(fb->panel->cntl & CNTL_BGR)) { +#else if (fb->panel->cntl & CNTL_BGR) { +#endif var->blue.offset = 0; var->green.offset = var->blue.offset + var->blue.length; var->red.offset = var->green.offset + var->green.length; } else { var->red.offset = 0; var->green.offset = var->red.offset + var->red.length; - var->blue.offset = var->green.offset + var->green.length; + var->blue.offset = + var->green.offset + var->green.length; } } return ret; } @@ -205,10 +232,11 @@ static int clcdfb_set_par(struct fb_info if (fb->fb.var.bits_per_pixel <= 8) fb->fb.fix.visual = FB_VISUAL_PSEUDOCOLOR; else fb->fb.fix.visual = FB_VISUAL_TRUECOLOR; + fb->board->decode(fb, ®s); clcdfb_disable(fb); writel(regs.tim0, fb->regs + CLCD_TIM0); @@ -242,14 +270,10 @@ static inline u32 convert_bitfield(int v unsigned int mask = (1 << bf->length) - 1; return (val >> (16 - bf->length) & mask) << bf->offset; } -/* - * Set a single color register. The values supplied have a 16 bit - * magnitude. Return != 0 for invalid regno. - */ static int clcdfb_setcolreg(unsigned int regno, unsigned int red, unsigned int green, unsigned int blue, unsigned int transp, struct fb_info *info) { struct clcd_fb *fb = to_clcd(info); @@ -261,15 +285,23 @@ clcdfb_setcolreg(unsigned int regno, uns convert_bitfield(red, &fb->fb.var.red); if (fb->fb.fix.visual == FB_VISUAL_PSEUDOCOLOR && regno < 256) { int hw_reg = CLCD_PALETTE + ((regno * 2) & ~3); u32 val, mask, newval; - +#ifdef CONFIG_FB_NOMADIK_PANEL_8BPP + /* Reads from the registers return 0xFFFFFFFF, so the values */ + /* must be saved */ + static u32 LCD_PALx[128]; + + newval = red & 0xf800; + newval |= (green >> 5) & 0x07e0; + newval |= (blue >> 11) & 0x001f; +#else newval = (red >> 11) & 0x001f; newval |= (green >> 6) & 0x03e0; newval |= (blue >> 1) & 0x7c00; - +#endif /* * 3.2.11: if we're configured for big endian * byte order, the palette entries are swapped. */ if (fb->clcd_cntl & CNTL_BEBO) @@ -280,27 +312,38 @@ clcdfb_setcolreg(unsigned int regno, uns mask = 0x0000ffff; } else { mask = 0xffff0000; } +#ifdef CONFIG_FB_NOMADIK_PANEL_8BPP + val = LCD_PALx[hw_reg-CLCD_PALETTE] & mask; + LCD_PALx[hw_reg-CLCD_PALETTE] = val | newval; +#else val = readl(fb->regs + hw_reg) & mask; +#endif writel(val | newval, fb->regs + hw_reg); } return regno > 255; } -/* +/** + * clcdfb_blank - Disable/Enables the clcd controller + * + * @blank_mode - Enable/Disable the controller + * @info - Framebuffer information + * * Blank the screen if blank_mode != 0, else unblank. If blank == NULL * then the caller blanks by setting the CLUT (Color Look Up Table) to all * black. Return 0 if blanking succeeded, != 0 if un-/blanking failed due * to e.g. a video mode which doesn't support it. Implements VESA suspend * and powerdown modes on hardware that supports disabling hsync/vsync: * blank_mode == 2: suspend vsync * blank_mode == 3: suspend hsync * blank_mode == 4: powerdown - */ + **/ + static int clcdfb_blank(int blank_mode, struct fb_info *info) { struct clcd_fb *fb = to_clcd(info); if (blank_mode != 0) { @@ -309,12 +352,11 @@ static int clcdfb_blank(int blank_mode, clcdfb_enable(fb, fb->clcd_cntl); } return 0; } -static int clcdfb_mmap(struct fb_info *info, - struct vm_area_struct *vma) +static int clcdfb_mmap(struct fb_info *info, struct vm_area_struct *vma) { struct clcd_fb *fb = to_clcd(info); unsigned long len, off = vma->vm_pgoff << PAGE_SHIFT; int ret = -EINVAL; @@ -361,11 +403,11 @@ static int clcdfb_register(struct clcd_f fb->fb.fbops = &clcdfb_ops; fb->fb.flags = FBINFO_FLAG_DEFAULT; fb->fb.pseudo_palette = fb->cmap; - strncpy(fb->fb.fix.id, clcd_name, sizeof(fb->fb.fix.id)); + strncpy(fb->fb.fix.id, fb->panel->mode.name, sizeof(fb->fb.fix.id)); fb->fb.fix.type = FB_TYPE_PACKED_PIXELS; fb->fb.fix.type_aux = 0; fb->fb.fix.xpanstep = 0; fb->fb.fix.ypanstep = 0; fb->fb.fix.ywrapstep = 0; @@ -430,10 +472,30 @@ static int clcdfb_register(struct clcd_f clk_put(fb->clk); out: return ret; } +#ifdef CONFIG_PM +static int clcdfb_suspend(struct amba_device *dev, pm_message_t state) +{ + struct clcd_fb *fb = amba_get_drvdata(dev); + clcdfb_disable(fb); + return 0; + +} + +static int clcdfb_resume(struct amba_device *dev) +{ + struct clcd_fb *fb = amba_get_drvdata(dev); + clcdfb_set_par(&fb->fb); + return 0; + +} + +#endif + + static int clcdfb_probe(struct amba_device *dev, void *id) { struct clcd_board *board = dev->dev.platform_data; struct clcd_fb *fb; int ret; @@ -447,11 +509,12 @@ static int clcdfb_probe(struct amba_devi goto out; } fb = kmalloc(sizeof(struct clcd_fb), GFP_KERNEL); if (!fb) { - printk(KERN_INFO "CLCD: could not allocate new clcd_fb struct\n"); + printk(KERN_INFO + "CLCD: could not allocate new clcd_fb struct\n"); ret = -ENOMEM; goto free_region; } memset(fb, 0, sizeof(struct clcd_fb)); @@ -479,10 +542,11 @@ static int clcdfb_probe(struct amba_devi static int clcdfb_remove(struct amba_device *dev) { struct clcd_fb *fb = amba_get_drvdata(dev); + amba_set_drvdata(dev, NULL); clcdfb_disable(fb); unregister_framebuffer(&fb->fb); iounmap(fb->regs); @@ -497,12 +561,12 @@ static int clcdfb_remove(struct amba_dev return 0; } static struct amba_id clcdfb_id_table[] = { { - .id = 0x00041110, - .mask = 0x000ffffe, + .id = CLCD_PER_ID, + .mask = CLCD_PER_MASK, }, { 0, 0 }, }; static struct amba_driver clcd_driver = { @@ -510,10 +574,15 @@ static struct amba_driver clcd_driver = .name = "clcd-pl11x", }, .probe = clcdfb_probe, .remove = clcdfb_remove, .id_table = clcdfb_id_table, + +#ifdef CONFIG_PM + .suspend = clcdfb_suspend, + .resume = clcdfb_resume, +#endif }; static int __init amba_clcdfb_init(void) { if (fb_get_options("ambafb", NULL)) --- linux-2.6.20.orig/drivers/video/fbmem.c +++ linux-2.6.20/drivers/video/fbmem.c @@ -232,11 +232,10 @@ static void fb_set_logo_directpalette(st const struct linux_logo *logo, u32 *palette) { int redshift, greenshift, blueshift; int i; - redshift = info->var.red.offset; greenshift = info->var.green.offset; blueshift = info->var.blue.offset; for (i = 32; i < logo->clutsize; i++) --- /dev/null +++ linux-2.6.20/drivers/video/nomadik/Makefile @@ -0,0 +1,15 @@ +# +# Makefile for the Nomadik framebuffer driver +# +ifdef CONFIG_FB_NOMADIK_ACCLN +CFLAGS += -D__STN_8815 -D__RELEASE + +obj-$(CONFIG_FB_NOMADIK_ACCLN) += nomadikfb.o +#obj-m += nomadikfb.ko + +endif + +nomadikfb-y := sga_main.o sga_ioctlfns.o hcl/sga.o hcl/sga_irq.o + + +nomadikfb-objs := $(nomadikfb-y) --- /dev/null +++ linux-2.6.20/drivers/video/nomadik/hcl/debug.h @@ -0,0 +1,313 @@ +/****************************************************************************** + * Copyright 2007, STMicroelectronics + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + * + * Description : Public Header file for DEBUG module + * + *****************************************************************************/ + +#ifndef __INC_DBG_H +#define __INC_DBG_H + +/*--------------------------------------------------------------------------* + * Includes * + *--------------------------------------------------------------------------*/ +#include "hcl_defs.h" + +#ifdef __DEBUG +#include +#endif + +/*--------------------------------------------------------------------------* + * C++ * + *--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/*--------------------------------------------------------------------------* + * Constants and new types * + *--------------------------------------------------------------------------*/ + +/*Defines for Version */ +#define DBG_HCL_VERSION_ID 3 +#define DBG_HCL_MAJOR_ID 2 +#define DBG_HCL_MINOR_ID 0 + + +/* Store a submitter ID, unique for each HCL. */ + +typedef enum +{ + UNKNOWN_HCL_DBG_ID, + APPLI_DBG_ID, + TEST_DBG_ID, + DEBUG_HCL_DBG_ID, + UART_HCL_DBG_ID, + VIC_HCL_DBG_ID, + DMA_HCL_DBG_ID, + HA_HCL_DBG_ID, + SAA_HCL_DBG_ID, + RTC_HCL_DBG_ID, + TIMER_HCL_DBG_ID, + WATCHDOG_HCL_DBG_ID, + I2C_HCL_DBG_ID, + CODEC_HCL_DBG_ID, + MSP_HCL_DBG_ID, + HV_HCL_DBG_ID, + SVA_HCL_DBG_ID, + FLASH_HCL_DBG_ID, + SDRAM_HCL_DBG_ID, + GPIO_HCL_DBG_ID, + POWER_HCL_DBG_ID, + PLL_HCL_DBG_ID, + HSI_HCL_DBG_ID, + DIF_HCL_DBG_ID, + SDMM_HCL_DBG_ID, + FIRDA_HCL_DBG_ID, + SSP_HCL_DBG_ID, + CLCD_HCL_DBG_ID, + SRC_HCL_DBG_ID, + RTT_HCL_DBG_ID, + USB_HCL_DBG_ID, + PWL_HCL_DBG_ID, + OWM_HCL_DBG_ID, + TSP_HCL_DBG_ID, + SSM_HCL_DBG_ID, + SECR_HCL_DBG_ID, + TDES_HCL_DBG_ID, + /*SHA1_HCL_DBG_ID,*/ + HASH_HCL_DBG_ID, + RNG_HCL_DBG_ID, + MSHC_HCL_DBG_ID, + SKE_HCL_DBG_ID, + SGA_HCL_DBG_ID, + CRYP_HCL_DBG_ID, + HPI_HCL_DBG_ID +} t_dbg_id; +/* Define the debug level. */ + +#define DEBUG_LEVEL0 DBGL_OFF +#define DEBUG_LEVEL1 ((t_uint32)DBGL_PUBLIC_FUNC_IN|(t_uint32)DBGL_PUBLIC_FUNC_OUT|(t_uint32)DBGL_ERROR|(t_uint32)DBGL_WARNING) +#define DEBUG_LEVEL2 ((t_uint32)DBGL_IN_ARGS|(t_uint32)DBGL_OUT_ARGS|(t_uint32)DBGL_RET_CODE) +#define DEBUG_LEVEL3 DBGL_INTERNAL +#define DEBUG_LEVEL4 DBGL_HCL_DEV + + +typedef enum +{ + DBGL_OFF = 0, + DBGL_PUBLIC_FUNC_IN = MASK_BIT0, + DBGL_PUBLIC_FUNC_OUT = MASK_BIT1, + DBGL_ERROR = MASK_BIT2, + DBGL_WARNING = MASK_BIT3, + DBGL_IN_ARGS = MASK_BIT4, + DBGL_OUT_ARGS = MASK_BIT5, + DBGL_RET_CODE = MASK_BIT6, + DBGL_INTERNAL = MASK_BIT7, + DBGL_HCL_DEV = MASK_BIT8, + DBGL_PRIV_FUNC_IN = MASK_BIT9, + DBGL_PRIV_FUNC_OUT = MASK_BIT10, + DBGL_PRIV_IN_ARGS = MASK_BIT11, + DBGL_PRIV_OUT_ARGS = MASK_BIT12, + DBGL_USER_1 = MASK_BIT13, + DBGL_USER_2 = MASK_BIT14, + DBGL_USER_3 = MASK_BIT15, + DBGL_USER_4 = MASK_BIT16, + DBGL_USER_5 = MASK_BIT17, + DBGL_USER_6 = MASK_BIT18, + DBGL_USER_7 = MASK_BIT19, + DBGL_USER_8 = MASK_BIT20, + DBGL_USER_9 = MASK_BIT21, + DBGL_RESERVED_0 = MASK_BIT22, + DBGL_RESERVED_1 = MASK_BIT23, + DBGL_RESERVED_2 = MASK_BIT24, + DBGL_RESERVED_3 = MASK_BIT25, + DBGL_RESERVED_4 = MASK_BIT26, + DBGL_RESERVED_5 = MASK_BIT27, + DBGL_RESERVED_6 = MASK_BIT28, + DBGL_RESERVED_7 = MASK_BIT29, + DBGL_RESERVED_8 = MASK_BIT30 +} t_dbg_level; + + + +#ifdef __DEBUG + +/*--------------------------------------------------------------------------* + * Macro * + *--------------------------------------------------------------------------*/ + +/* Begin of Private definitions */ + +/* + * Compiler define __ARMCC_VERSION returns PVtbbb where: + * P is the major version (1 for ADS and 2 for RVCT v2.1) + * V is the minor version + * t is the patch release + * bbb is the build +*/ +#if ((__ARMCC_VERSION >= 100000) && (__ARMCC_VERSION < 200000)) +/* ADS Compiler */ +#define DBGFUNCNAME __func__ +#elif (__ARMCC_VERSION < 300000) +/* RVCT Compiler */ +#define DBGFUNCNAME __FILE__ +#else +/* To be added - depends on the compiler to be used. Currently is left as empty */ +#define DBGFUNCNAME "" +#endif + + +/* End of Private definitions */ + + +/* Exit Macros */ + +#define DBGEXIT0(cr) \ + ((DBGL_PUBLIC_FUNC_OUT & MY_DEBUG_LEVEL_VAR_NAME) != DBGL_OFF)? \ + logMsg(MY_DEBUG_ID, DBGFUNCNAME, 0, "Exiting",0, 0, 0, 0, 0, 0, cr): \ + (0) + +#define DBGEXIT1(cr,ch,p1) \ + ((DBGL_PUBLIC_FUNC_OUT & MY_DEBUG_LEVEL_VAR_NAME) != DBGL_OFF)? \ + logMsg(MY_DEBUG_ID, DBGFUNCNAME, ch, "Exiting",(unsigned long)(p1), 0, 0, 0, 0, 0,cr): \ + (0) + +#define DBGEXIT2(cr,ch,p1,p2) \ + ((DBGL_PUBLIC_FUNC_OUT & MY_DEBUG_LEVEL_VAR_NAME) != DBGL_OFF)? \ + logMsg(MY_DEBUG_ID, DBGFUNCNAME, ch, "Exiting",(unsigned long)(p1), (unsigned long)(p2), 0, 0, 0, 0,cr): \ + (0) + +#define DBGEXIT3(cr,ch,p1,p2,p3) \ + ((DBGL_PUBLIC_FUNC_OUT & MY_DEBUG_LEVEL_VAR_NAME) != DBGL_OFF)? \ + logMsg(MY_DEBUG_ID, DBGFUNCNAME, ch, "Exiting",(unsigned long)(p1), (unsigned long)(p2), (unsigned long)(p3), 0, 0, 0,cr): \ + (0) + +#define DBGEXIT4(cr,ch,p1,p2,p3,p4) \ + ((DBGL_PUBLIC_FUNC_OUT & MY_DEBUG_LEVEL_VAR_NAME) != DBGL_OFF)? \ + logMsg(MY_DEBUG_ID, DBGFUNCNAME, ch, "Exiting",(unsigned long)(p1), (unsigned long)(p2), (unsigned long)(p3), (unsigned long)(p4), 0, 0,cr): \ + (0) + + +#define DBGEXIT5(cr,ch,p1,p2,p3,p4,p5) \ + ((DBGL_PUBLIC_FUNC_OUT & MY_DEBUG_LEVEL_VAR_NAME) != DBGL_OFF)? \ + logMsg(MY_DEBUG_ID, DBGFUNCNAME, ch, "Exiting",(unsigned long)(p1), (unsigned long)(p2), (unsigned long)(p3), (unsigned long)(p4), (unsigned long)(p5), 0,cr): \ + (0) + +#define DBGEXIT6(cr,ch,p1,p2,p3,p4,p5,p6) \ + ((DBGL_PUBLIC_FUNC_OUT & MY_DEBUG_LEVEL_VAR_NAME) != DBGL_OFF)? \ + logMsg(MY_DEBUG_ID, DBGFUNCNAME, ch, "Exiting",(unsigned long)(p1), (unsigned long)(p2), (unsigned long)(p3), (unsigned long)(p4), (unsigned long)(p5), (unsigned long)(p6),cr): \ + (0) + +/* Enter macro's */ + +#define DBGENTER0() \ + ((DBGL_PUBLIC_FUNC_IN & MY_DEBUG_LEVEL_VAR_NAME) != DBGL_OFF)? \ + logMsg(MY_DEBUG_ID, DBGFUNCNAME, 0, "Entering Function",0, 0, 0, 0, 0, 0, 0): \ + (0) + +#define DBGENTER1(ch,p1) \ + ((DBGL_PUBLIC_FUNC_IN & MY_DEBUG_LEVEL_VAR_NAME) != DBGL_OFF)? \ + logMsg(MY_DEBUG_ID, DBGFUNCNAME, ch, "Entering Function",(unsigned long)(p1), 0, 0, 0, 0, 0,0): \ + (0) + +#define DBGENTER2(ch,p1,p2) \ + ((DBGL_PUBLIC_FUNC_IN & MY_DEBUG_LEVEL_VAR_NAME) != DBGL_OFF)? \ + logMsg(MY_DEBUG_ID, DBGFUNCNAME, ch, "Entering Function",(unsigned long)(p1), (unsigned long)(p2), 0, 0, 0, 0, 0): \ + (0) + +#define DBGENTER3(ch,p1,p2,p3) \ + ((DBGL_PUBLIC_FUNC_IN & MY_DEBUG_LEVEL_VAR_NAME) != DBGL_OFF)? \ + logMsg(MY_DEBUG_ID, DBGFUNCNAME, ch, "Entering Function",(unsigned long)(p1), (unsigned long)(p2), (unsigned long)(p3), 0, 0, 0, 0): \ + (0) + +#define DBGENTER4(ch,p1,p2,p3,p4) \ + ((DBGL_PUBLIC_FUNC_IN & MY_DEBUG_LEVEL_VAR_NAME) != DBGL_OFF)? \ + logMsg(MY_DEBUG_ID, DBGFUNCNAME, ch, "Entering Function",(unsigned long)(p1), (unsigned long)(p2), (unsigned long)(p3), (unsigned long)(p4), 0, 0, 0):\ + (0) + +#define DBGENTER5(ch,p1,p2,p3,p4,p5) \ + ((DBGL_PUBLIC_FUNC_IN & MY_DEBUG_LEVEL_VAR_NAME) != DBGL_OFF)? \ + logMsg(MY_DEBUG_ID, DBGFUNCNAME, ch, "Entering Function",(unsigned long)(p1), (unsigned long)(p2), (unsigned long)(p3), (unsigned long)(p4), (unsigned long)(p5), 0, 0):\ + (0) + +#define DBGENTER6(ch,p1,p2,p3,p4,p5,p6) \ + ((DBGL_PUBLIC_FUNC_IN & MY_DEBUG_LEVEL_VAR_NAME) != DBGL_OFF)? \ + logMsg(MY_DEBUG_ID, DBGFUNCNAME, ch, "Entering Function",(unsigned long)(p1), (unsigned long)(p2), (unsigned long)(p3), (unsigned long)(p4), (unsigned long)(p5), (unsigned long)(p6), 0):\ + (0) + + +#define DBGEXIT DBGEXIT0 +#define DBGENTER DBGENTER0 + +#define DBGPRINT(dbg_level,ch) \ + ((dbg_level & MY_DEBUG_LEVEL_VAR_NAME) != DBGL_OFF)? \ + logMsg(MY_DEBUG_ID, DBGFUNCNAME, ch, "",0, 0, 0, 0, 0, 0, 0): \ + (0) + +#define DBGPRINTHEX(dbg_level,ch, uint32) \ + ((dbg_level & MY_DEBUG_LEVEL_VAR_NAME) != DBGL_OFF)? \ + logMsg(MY_DEBUG_ID, DBGFUNCNAME, ch, "",(unsigned long)uint32, 0, 0, 0, 0, 0, 0): \ + (0) + +#define DBGPRINTDEC(dbg_level,ch, uint32) \ + ((dbg_level & MY_DEBUG_LEVEL_VAR_NAME) != DBGL_OFF)? \ + logMsg(MY_DEBUG_ID, DBGFUNCNAME, ch, "",(unsigned long)uint32, 0, 0, 0, 0, 0, 0): \ + (0) + +#endif /* __DEBUG */ + +#ifdef __RELEASE + +#define DBGEXIT(cr) +#define DBGEXIT0(cr) +#define DBGEXIT1(cr,ch,p1) +#define DBGEXIT2(cr,ch,p1,p2) +#define DBGEXIT3(cr,ch,p1,p2,p3) +#define DBGEXIT4(cr,ch,p1,p2,p3,p4) +#define DBGEXIT5(cr,ch,p1,p2,p3,p4,p5) +#define DBGEXIT6(cr,ch,p1,p2,p3,p4,p5,p6) + +#define DBGENTER() +#define DBGENTER0() +#define DBGENTER1(ch,p1) +#define DBGENTER2(ch,p1,p2) +#define DBGENTER3(ch,p1,p2,p3) +#define DBGENTER4(ch,p1,p2,p3,p4) +#define DBGENTER5(ch,p1,p2,p3,p4,p5) +#define DBGENTER6(ch,p1,p2,p3,p4,p5,p6) + + + +#define DBGPRINT(dbg_level,dbg_string) +#define DBGPRINTHEX(dbg_level,dbg_string,uint32) +#define DBGPRINTDEC(dbg_level,dbg_string,uint32) + +#endif /* __RELEASE */ + + +/*--------------------------------------------------------------------------* + * C++ * + *--------------------------------------------------------------------------*/ +#ifdef __cplusplus +} /* allow C++ to use these headers */ +#endif /* __cplusplus */ + + +#endif /* __INC_DBG_H */ + +/* End of file - debug.h */ + + --- /dev/null +++ linux-2.6.20/drivers/video/nomadik/hcl/hcl_defs.h @@ -0,0 +1,286 @@ +/****************************************************************************** + * Copyright 2007, STMicroelectronics + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + * + * Description : Basic definitions + * + *****************************************************************************/ + +#ifndef _HCL_DEFS_H +#define _HCL_DEFS_H + +#include "platform_os.h" + +/*----------------------------------------------------------------------------- + * Type definition + *---------------------------------------------------------------------------*/ +typedef unsigned char t_uint8; +typedef signed char t_sint8; +typedef unsigned short t_uint16; +typedef signed short t_sint16; +typedef unsigned long t_uint32; +typedef signed long t_sint32; + +#ifdef _WIN32_WCE +typedef unsigned __int64 t_uint64; +typedef __int64 t_sint64; +#else +/* typedef unsigned long long t_uint64; move to platform_os.h */ +/* typedef signed long long t_sint64; move to platform_os.h */ +#endif + +typedef unsigned int t_bitfield; + +#if !defined(FALSE) && !defined(TRUE) +typedef enum {FALSE, TRUE} t_bool; +#else /* FALSE & TRUE already defined */ +typedef enum {BOOL_FALSE, BOOL_TRUE} t_bool; +#endif /* !defined(FALSE) && !defined(TRUE) */ + +/* + * Definition of the different kind of addresses manipulated into a system with MMU + * (handle physical AND logical addresses) + */ +typedef t_uint32 t_physical_address; +typedef t_uint32 t_logical_address; + + + +/* + * Global frequency enumuration + * Added to avoid frequency conversion function which is required to convert one HCL + * frequency enumuration values to another HCL frequency enumuration values. + */ + +typedef enum { + HCL_FREQ_NOT_SUPPORTED=-1, + HCL_FREQ_8KHZ , + HCL_FREQ_11_25KHZ, + HCL_FREQ_12KHZ, + HCL_FREQ_16KHZ, + HCL_FREQ_22_05KHZ, + HCL_FREQ_22_5KHZ, + HCL_FREQ_24KHZ, + HCL_FREQ_32KHZ, + HCL_FREQ_44KHZ, + HCL_FREQ_44_1KHZ, + HCL_FREQ_48KHZ, + HCL_FREQ_64KHZ, + HCL_FREQ_88KHZ, + HCL_FREQ_88_2KHZ, + HCL_FREQ_96KHZ, + HCL_FREQ_128KHZ, + HCL_FREQ_176_4KHZ, + HCL_FREQ_192KHZ, + + HCL_FREQ_1MHZ, + HCL_FREQ_2MHZ, + HCL_FREQ_3MHZ, + HCL_FREQ_4MHZ, + HCL_FREQ_5MHZ, + HCL_FREQ_6MHZ, + HCL_FREQ_8MHZ, + HCL_FREQ_11MHZ, + HCL_FREQ_12MHZ, + HCL_FREQ_16MHZ, + HCL_FREQ_22MHZ, + HCL_FREQ_24MHZ, + HCL_FREQ_48MHZ +} t_frequency; + + + +typedef struct { + t_physical_address physical; + t_logical_address logical; +} t_system_address; + + +/* + * Define a type used to manipulate size of various buffers + */ +typedef t_uint32 t_size; + +typedef struct { + t_bitfield minor:8; + t_bitfield major:8; + t_bitfield version:16; +} t_version; + + + + +/*----------------------------------------------------------------------------- + * Keyword definition + *---------------------------------------------------------------------------*/ +#define PUBLIC /* Extern by default */ +#define PRIVATE static + +#ifndef NULL +#define NULL (0) +#endif /* ndef NULL */ + +#define HCL_INTERNAL_ERROR (-8) +#define HCL_NOT_CONFIGURED (-7) +#define HCL_REQUEST_PENDING (-6) +#define HCL_REQUEST_NOT_APPLICABLE (-5) +#define HCL_INVALID_PARAMETER (-4) +#define HCL_UNSUPPORTED_FEATURE (-3) +#define HCL_UNSUPPORTED_HW (-2) +#define HCL_ERROR (-1) +#define HCL_OK ( 0) +#define HCL_INTERNAL_EVENT ( 1) +#define HCL_REMAINING_PENDING_EVENTS ( 2) +#define HCL_REMAINING_FILTER_PENDING_EVENTS ( 3) +#define HCL_NO_MORE_PENDING_EVENT ( 4) +#define HCL_NO_MORE_FILTER_PENDING_EVENT ( 5) +#define HCL_NO_PENDING_EVENT_ERROR ( 7) + + +#define HCL_MAX_ERROR_VALUE (-65) /* HCL specific error codes + * should start from this offset + */ + +/*----------------------------------------------------------------------------- + * Bit setting or clearing + *---------------------------------------------------------------------------*/ +#define HCL_SET_BITS(reg,mask) ((reg) |= (mask)) +#define HCL_CLEAR_BITS(reg,mask) ((reg) &= ~(mask)) +#define HCL_READ_BITS(reg,mask) ((reg) & (mask)) +#define HCL_WRITE_BITS(reg,val,mask) ((reg) = (((reg) & ~(mask)) | ((val) & (mask)))) +#define HCL_READ_REG(reg) (reg) +#define HCL_WRITE_REG(reg,val) ((reg) = (val)) + +/*----------------------------------------------------------------------------- + * field offset extraction from a structure + *---------------------------------------------------------------------------*/ +#define HCL_BITFIELD_OFFSET(typeName, fieldName) (t_uint32)(&(((typeName *)0)->fieldName)) + +/*----------------------------------------------------------------------------- + * Bit mask definition + *---------------------------------------------------------------------------*/ +#define MASK_NULL8 0x00 +#define MASK_NULL16 0x0000 +#define MASK_NULL32 0x00000000 +#define MASK_ALL8 0xFF +#define MASK_ALL16 0xFFFF +#define MASK_ALL32 0xFFFFFFFF + +#define MASK_BIT0 (1UL<<0) +#define MASK_BIT1 (1UL<<1) +#define MASK_BIT2 (1UL<<2) +#define MASK_BIT3 (1UL<<3) +#define MASK_BIT4 (1UL<<4) +#define MASK_BIT5 (1UL<<5) +#define MASK_BIT6 (1UL<<6) +#define MASK_BIT7 (1UL<<7) +#define MASK_BIT8 (1UL<<8) +#define MASK_BIT9 (1UL<<9) +#define MASK_BIT10 (1UL<<10) +#define MASK_BIT11 (1UL<<11) +#define MASK_BIT12 (1UL<<12) +#define MASK_BIT13 (1UL<<13) +#define MASK_BIT14 (1UL<<14) +#define MASK_BIT15 (1UL<<15) +#define MASK_BIT16 (1UL<<16) +#define MASK_BIT17 (1UL<<17) +#define MASK_BIT18 (1UL<<18) +#define MASK_BIT19 (1UL<<19) +#define MASK_BIT20 (1UL<<20) +#define MASK_BIT21 (1UL<<21) +#define MASK_BIT22 (1UL<<22) +#define MASK_BIT23 (1UL<<23) +#define MASK_BIT24 (1UL<<24) +#define MASK_BIT25 (1UL<<25) +#define MASK_BIT26 (1UL<<26) +#define MASK_BIT27 (1UL<<27) +#define MASK_BIT28 (1UL<<28) +#define MASK_BIT29 (1UL<<29) +#define MASK_BIT30 (1UL<<30) +#define MASK_BIT31 (1UL<<31) + +/*----------------------------------------------------------------------------- + * quartet shift definition + *---------------------------------------------------------------------------*/ +#define MASK_QUARTET (0xFUL) +#define SHIFT_QUARTET0 0 +#define SHIFT_QUARTET1 4 +#define SHIFT_QUARTET2 8 +#define SHIFT_QUARTET3 12 +#define SHIFT_QUARTET4 16 +#define SHIFT_QUARTET5 20 +#define SHIFT_QUARTET6 24 +#define SHIFT_QUARTET7 28 +#define MASK_QUARTET0 (MASK_QUARTET << SHIFT_QUARTET0) +#define MASK_QUARTET1 (MASK_QUARTET << SHIFT_QUARTET1) +#define MASK_QUARTET2 (MASK_QUARTET << SHIFT_QUARTET2) +#define MASK_QUARTET3 (MASK_QUARTET << SHIFT_QUARTET3) +#define MASK_QUARTET4 (MASK_QUARTET << SHIFT_QUARTET4) +#define MASK_QUARTET5 (MASK_QUARTET << SHIFT_QUARTET5) +#define MASK_QUARTET6 (MASK_QUARTET << SHIFT_QUARTET6) +#define MASK_QUARTET7 (MASK_QUARTET << SHIFT_QUARTET7) + +/*----------------------------------------------------------------------------- + * Byte shift definition + *---------------------------------------------------------------------------*/ +#define MASK_BYTE (0xFFUL) +#define SHIFT_BYTE0 0 +#define SHIFT_BYTE1 8 +#define SHIFT_BYTE2 16 +#define SHIFT_BYTE3 24 +#define MASK_BYTE0 (MASK_BYTE << SHIFT_BYTE0) +#define MASK_BYTE1 (MASK_BYTE << SHIFT_BYTE1) +#define MASK_BYTE2 (MASK_BYTE << SHIFT_BYTE2) +#define MASK_BYTE3 (MASK_BYTE << SHIFT_BYTE3) + +/*----------------------------------------------------------------------------- + * Halfword shift definition + *---------------------------------------------------------------------------*/ +#define MASK_HALFWORD (0xFFFFUL) +#define SHIFT_HALFWORD0 0 +#define SHIFT_HALFWORD1 16 +#define MASK_HALFWORD0 (MASK_HALFWORD << SHIFT_HALFWORD0) +#define MASK_HALFWORD1 (MASK_HALFWORD << SHIFT_HALFWORD1) + +/*----------------------------------------------------------------------------- + * Global constants definition + *---------------------------------------------------------------------------*/ + #define ONE_KB (1024) + #define ONE_MB (ONE_KB * ONE_KB) + + +/*----------------------------------------------------------------------------- + * Address translation macros declaration + *---------------------------------------------------------------------------*/ +#if defined(__EMUL) + +#define ARM_TO_AHB_ADDR(addr) (addr | MASK_BIT31) +#define AHB_TO_ARM_ADDR(addr) (addr & ~MASK_BIT31) +#endif /* efined(__EMUL) */ + +#if defined(__STN_8800) || defined(__STN_8810) || defined(__STN_8815) +#define ARM_TO_AHB_ADDR(addr) (addr) +#define AHB_TO_ARM_ADDR(addr) (addr) +#endif /* defined(__STN_8800) || defined(__STN_8810) || defined(__STN_8815) */ + +/* For input parameters - would not be changed by the API */ +#define IN +/* For output parameters - would be changes by the API */ +#define OUT +/* For input-output parameters - provides input to the API but would be changed by the API */ +#define INOUT + +#endif /* _HCL_DEFS_H */ + +/* End of file hcl_defs.h */ --- /dev/null +++ linux-2.6.20/drivers/video/nomadik/hcl/platform_os.h @@ -0,0 +1,79 @@ +/****************************************************************************** + * Copyright 2007, STMicroelectronics + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + * + *****************************************************************************/ +/* Dummy file used to define some conditionnal compilation flags */ +#ifndef __INC_PLATFORM_OS_H +#define __INC_PLATFORM_OS_H + +#undef NULL + +#ifdef __DEBUG +int logMsg( unsigned long debug_id, char* function_name, + char* arg_string, char* arg1, + unsigned long arg2, unsigned long arg3, + unsigned long arg4, unsigned long arg5, + unsigned long arg6, unsigned long arg7, + long exit_param + ); +#endif + +/* + * Define alignment macro + */ +#ifndef ALIGN +#if defined(__CC_ARM) +#define ALIGN(a) __align(a) +#elif defined(__GNUC__) +#define ALIGN(a) __attribute__ ((aligned (a))) +#else +#define ALIGN(a) +#endif +#endif +/* + * Define assertion macro + */ +#define HCL_ASSERT(a) ((a)?(void)0:exit(0)) + +/* + * Define assertion macro for debug only + */ +#ifdef __DEBUG + #define HCL_DEBUG_ASSERT(a) HCL_ASSERT(a) +#else + #define HCL_DEBUG_ASSERT(a) {if(a){(void)0;}} +#endif + +/* + * Define the SPRINTF macro use inside hv_XX_debugPrintf functions + * This routine SHALL support a format parameter with %d, %x, %s and width qualifiers + * AND return the number of bytes written in the output string + */ +#define SPRINTF(current, max, buffer, ...) \ + { \ + if ((current + 80) > max) {break;} \ + current += sprintf(buffer, __VA_ARGS__); \ + } + +/* + * Define extended ANSI C unsigned long long type + * could be redefine for each OS + * typedef unsigned __int64 t_uint64; + * typedef __int64 t_sint64; + */ +typedef unsigned long long t_uint64; +typedef signed long long t_sint64; + +#endif /* __INC_PLATFORM_OS_H */ --- /dev/null +++ linux-2.6.20/drivers/video/nomadik/hcl/sga.c @@ -0,0 +1,3161 @@ +/****************************************************************************** + * Copyright 2007, STMicroelectronics + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + * + * Description : This module provides API routines for the NOMADIK SGA + * + *****************************************************************************/ +#include "sga.h" +#include "sga_p.h" +#include "sga_irqp.h" +#include "debug.h" + +/*------------------------------------------------------------------------ + * Global Variables + *----------------------------------------------------------------------*/ +PRIVATE volatile t_sga_system_context g_sga_system_context; + +/*----------------------------------------------------------------------------- + * DEBUG STUFF + *---------------------------------------------------------------------------*/ +#ifdef __DEBUG +#define MY_DEBUG_LEVEL_VAR_NAME myDebugLevel_SGA +#define MY_DEBUG_ID myDebugID_SGA + +t_dbg_level MY_DEBUG_LEVEL_VAR_NAME = DEBUG_LEVEL0; +t_dbg_id MY_DEBUG_ID = SGA_HCL_DBG_ID; +#endif + +/*--------------------------------------------------------------------------- +* Public Functions +*---------------------------------------------------------------------------*/ +/****************************************************************************/ +/* NAME : SGA_Init() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION : This routine initializes the SGA registers, checks */ +/* Peripheral and PCell Id and clears all interrupts. */ +/* PARAMETERS : */ +/* IN :t_logical_address : sga_base_address:sga registers base */ +/* address */ +/* InOut :None */ +/* OUT :None */ +/* RETURN :t_sga_error : SGA error code */ +/* SGA_OK */ +/* SGA_INVALID_PARAMETER :if input argument is invalid */ +/*--------------------------------------------------------------------------*/ +/* Type : PUBLIC */ +/* REENTRANCY : Non Re-entrant */ +/* REENTRANCY ISSUES : */ + +/****************************************************************************/ +PUBLIC t_sga_error SGA_Init(IN t_logical_address sga_base_address) +{ + t_sga_error sga_error; + + DBGENTER1("Setting Base Address for registers to %lx", sga_base_address); + + if (NULL == sga_base_address) + { + return(SGA_INVALID_PARAMETER); + } + + g_sga_system_context.p_sga_registers = (t_sga_registers *) sga_base_address; + + /*Check Peripheral and pcell ids of the SGA */ + if + ( + (SGA_PERIPHERAL_ID0 == g_sga_system_context.p_sga_registers->sga_periphid0) + && (SGA_PERIPHERAL_ID1 == g_sga_system_context.p_sga_registers->sga_periphid1) + && (SGA_PERIPHERAL_ID2 == g_sga_system_context.p_sga_registers->sga_periphid2) + && (SGA_PERIPHERAL_ID3 == g_sga_system_context.p_sga_registers->sga_periphid3) + && (SGA_PCELL_ID0 == g_sga_system_context.p_sga_registers->sga_pcellid0) + && (SGA_PCELL_ID1 == g_sga_system_context.p_sga_registers->sga_pcellid1) + && (SGA_PCELL_ID2 == g_sga_system_context.p_sga_registers->sga_pcellid2) + && (SGA_PCELL_ID3 == g_sga_system_context.p_sga_registers->sga_pcellid3) + ) + { + sga_error = SGA_OK; + } + else + { + return(SGA_UNSUPPORTED_HW); + } + + g_sga_system_context.p_main_batch_add = NULL; + g_sga_system_context.p_default_batch_add = NULL; + + /*Flag the all semaphores as available resources */ + g_sga_system_context.batch_sem_id = 0; + + /*Flag the all interrupts as available resources */ + g_sga_system_context.interrupt_id = 0; + + DBGEXIT0(sga_error); + return(sga_error); +} + +/****************************************************************************/ +/* NAME : SGA_SetDbgLevel() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION : This routine enables to choose between different */ +/* debug comment levels */ +/* PARAMETERS : */ +/* IN :t_dbg_level sga_dbg_level:identify SGA debug level */ +/* InOut :None */ +/* OUT :None */ +/* RETURN :t_sga_error : SGA error code */ +/* SGA_OK : if it is ok */ +/* SGA_INVALID_PARAMETER if debug level exceed the certain */ +/* level */ +/*--------------------------------------------------------------------------*/ +/* Type : PUBLIC */ +/* REENTRANCY : Non Re-entrant */ +/* REENTRANCY ISSUES : */ + +/****************************************************************************/ +PUBLIC t_sga_error SGA_SetDbgLevel(IN t_dbg_level sga_dbg_level) +{ + t_sga_error error = SGA_OK; + + DBGENTER1("Setting Debug Level to %d", sga_dbg_level); + +#ifdef __DEBUG + if (sga_dbg_level < 0xFFFFFFFF) /*Debug level should not exceed */ + { + MY_DEBUG_LEVEL_VAR_NAME = sga_dbg_level; + error = SGA_OK; + } + else + { + error = SGA_INVALID_PARAMETER; + } +#endif + DBGEXIT0(error); + return(error); +} + +/****************************************************************************/ +/* NAME : SGA_SetDeviceConfig() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION : This routine configure the SGA Device */ +/* PARAMETERS : */ +/* IN :t_sga_device_config *p_dev_config:Pointer to structure */ +/* contaning the configuration values */ +/* InOut :None */ +/* OUT :None */ +/* RETURN :t_sga_error : SGA error code */ +/* SGA_OK : if it is ok */ +/* SGA_INVALID_PARAMETER if input parameter is invalid */ +/*--------------------------------------------------------------------------*/ +/* Type : PUBLIC */ +/* REENTRANCY : Non Re-entrant */ +/* REENTRANCY ISSUES : */ + +/****************************************************************************/ +PUBLIC t_sga_error SGA_SetDeviceConfig(IN t_sga_device_config *p_dev_config) +{ + DBGENTER1("Setting Device configuration %lx", p_dev_config); + if (NULL == p_dev_config) + { + DBGEXIT0(SGA_INVALID_PARAMETER); + return(SGA_INVALID_PARAMETER); + } + + /*configure the interupt clear mode */ + SGA_WRITE_FIELD + ( + g_sga_system_context.p_sga_registers->sga_gcr, + SGA_GCR_INTCMOD_MASK, + SGA_GCR_INTCMOD_SHIFT, + (t_uint32) p_dev_config->int_mode0 + ); + + /*Configure the FCLK gating enable */ + SGA_WRITE_FIELD + ( + g_sga_system_context.p_sga_registers->sga_gcr, + SGA_GCR_FCLKGEN_MASK, + SGA_GCR_FCLKGEN_SHIFT, + (t_uint32) p_dev_config->fclk_en + ); + + /*Configure the HCLK gating enable */ + SGA_WRITE_FIELD + ( + g_sga_system_context.p_sga_registers->sga_gcr, + SGA_GCR_HCLKGEN_MASK, + SGA_GCR_HCLKGEN_SHIFT, + (t_uint32) p_dev_config->hclk_en + ); + + /*Configure the Interrupt1 clear mode */ + SGA_WRITE_FIELD + ( + g_sga_system_context.p_sga_registers->sga_gcr, + SGA_GCR_INTCMOD1_MASK, + SGA_GCR_INTCMOD1_SHIFT, + (t_uint32) p_dev_config->int_mode1 + ); + + DBGEXIT0(SGA_OK); + return(SGA_OK); +} + +/****************************************************************************/ +/* NAME : SGA_Reset() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION : This routine reset the SGA hardware */ +/* PARAMETERS : */ +/* IN :None */ +/* InOut :None */ +/* OUT :None */ +/* RETURN :t_sga_error : SGA error code */ +/* SGA_OK : if it is ok */ +/* SGA_INVALID_PARAMETER if input parameter is invalid */ +/*--------------------------------------------------------------------------*/ +/* Type : PUBLIC */ +/* REENTRANCY : Non Re-entrant */ +/* REENTRANCY ISSUES : */ + +/****************************************************************************/ +PUBLIC void SGA_Reset(void) +{ + DBGENTER0(); + SGA_SET_BIT(g_sga_system_context.p_sga_registers->sga_ctcmd, SGA_CTCMD_GRST_MASK); + + /*Reset the System context to default */ + g_sga_system_context.batch_sem_id = 0; + g_sga_system_context.interrupt_id = 0; + g_sga_system_context.p_main_batch_add = NULL; + g_sga_system_context.p_default_batch_add = NULL; + + /*Clear the all semaphore bits */ + g_sga_system_context.p_sga_registers->sga_citr = 0; + + /*Clear the all interrupts for ARM and MMDSP */ + g_sga_system_context.p_sga_registers->sga_icr = 0xFFFFFFFF; + DBGEXIT0(SGA_OK); +} + +/****************************************************************************/ +/* NAME : SGA_SetControlCommand() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION : Set the specific control command of the SGA */ +/* PARAMETERS : */ +/* IN :t_sga_ctrl_cmd command: Specify the control command to be*/ +/* set in the SGA */ +/* InOut :None */ +/* OUT :None */ +/* RETURN :t_sga_error : SGA error code */ +/* SGA_OK : if it is ok */ +/* SGA_INVALID_PARAMETER if input parameter is invalid */ +/*--------------------------------------------------------------------------*/ +/* Type : PUBLIC */ +/* REENTRANCY : Non Re-entrant */ +/* REENTRANCY ISSUES : */ +/****************************************************************************/ +PUBLIC void SGA_SetControlCommand(IN t_sga_ctrl_cmd command) +{ + DBGENTER1("SGA Control Command (%d)", command); + switch (command) + { + case SGA_CTRL_CMD_GLOBAL_INIT: + SGA_SET_BIT(g_sga_system_context.p_sga_registers->sga_ctcmd, SGA_CTCMD_GINIT_MASK); + break; + + case SGA_CTRL_CMD_GLOBAL_HALT: + SGA_SET_BIT(g_sga_system_context.p_sga_registers->sga_ctcmd, SGA_CTCMD_GHALT_MASK); + break; + + case SGA_CTRL_CMD_GLOBAL_RESUME: + SGA_SET_BIT(g_sga_system_context.p_sga_registers->sga_ctcmd, SGA_CTCMD_GRESUME_MASK); + break; + + case SGA_CTRL_CMD_INSTR_HALT: + SGA_SET_BIT(g_sga_system_context.p_sga_registers->sga_ctcmd, SGA_CTCMD_IHALT_MASK); + break; + + case SGA_CTRL_CMD_INSTR_RESUME: + SGA_SET_BIT(g_sga_system_context.p_sga_registers->sga_ctcmd, SGA_CTCMD_IRESUME_MASK); + break; + + case SGA_CTRL_CMD_INSTR_FLUSH: + SGA_SET_BIT(g_sga_system_context.p_sga_registers->sga_ctcmd, SGA_CTCMD_IFLUSH_MASK); + break; + + case SGA_CTRL_CMD_AUTO_FETCH_STOP: + SGA_SET_BIT(g_sga_system_context.p_sga_registers->sga_ctcmd, SGA_CTCMD_AFSTOP_MASK); + break; + + case SGA_CTRL_CMD_AUTO_FETCH_RUN: + SGA_SET_BIT(g_sga_system_context.p_sga_registers->sga_ctcmd, SGA_CTCMD_AFRUN_MASK); + break; + + default: + break; + } + + DBGEXIT0(SGA_OK); +} + +/****************************************************************************/ +/* NAME : SGA_GetStatus() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION : Get the status of the Smart Graphics Accelerator */ +/* PARAMETERS : */ +/* IN :t_sga_status status: contain the SGA status info to */ +/* be get */ +/* InOut :None */ +/* OUT :None */ +/* RETURN :t_uint32 contain the status value. */ +/*--------------------------------------------------------------------------*/ +/* Type : PUBLIC */ +/* REENTRANCY : Non Re-entrant */ +/* REENTRANCY ISSUES : */ +/****************************************************************************/ +PUBLIC t_uint32 SGA_GetStatus(IN t_sga_status status) +{ + t_uint32 stat_value = 0; + + DBGENTER1("status (%d)", status); + switch (status) + { + case SGA_STATUS_GLOBAL_EN: + stat_value = SGA_READ_FIELD + ( + g_sga_system_context.p_sga_registers->sga_ctstat, + SGA_CTSTAT_GEN_MASK, + SGA_CTSTAT_GEN_SHIFT + ); + break; + + case SGA_STATUS_INST_PROCESS_EN: + stat_value = SGA_READ_FIELD + ( + g_sga_system_context.p_sga_registers->sga_ctstat, + SGA_CTSTAT_IPEN_MASK, + SGA_CTSTAT_IPEN_SHIFT + ); + break; + + case SGA_STATUS_AUTOFETCH: + stat_value = SGA_READ_FIELD + ( + g_sga_system_context.p_sga_registers->sga_ctstat, + SGA_CTSTAT_AFSTAT_MASK, + SGA_CTSTAT_AFSTAT_SHIFT + ); + break; + + case SGA_STATUS_INST_FIFO_EMPTY: + stat_value = SGA_READ_FIELD + ( + g_sga_system_context.p_sga_registers->sga_ctstat, + SGA_CTSTAT_IFEMPTY_MASK, + SGA_CTSTAT_IFEMPTY_SHIFT + ); + break; + + case SGA_STATUS_PIXELPIPE_EMPTY: + stat_value = SGA_READ_FIELD + ( + g_sga_system_context.p_sga_registers->sga_ctstat, + SGA_CTSTAT_PXPEMPTY_MASK, + SGA_CTSTAT_PXPEMPTY_SHIFT + ); + break; + + case SGA_STATUS_TOTALPIPE_EMPTY: + stat_value = SGA_READ_FIELD + ( + g_sga_system_context.p_sga_registers->sga_ctstat, + SGA_CTSTAT_TPEMPTY_MASK, + SGA_CTSTAT_TPEMPTY_SHIFT + ); + break; + + case SGA_STATUS_TOTALPIPE_CACHE_EMPTY: + stat_value = SGA_READ_FIELD + ( + g_sga_system_context.p_sga_registers->sga_ctstat, + SGA_CTSTAT_TPCEMPTY_MASK, + SGA_CTSTAT_TPCEMPTY_SHIFT + ); + break; + + case SGA_STATUS_RESTART_CNT: + stat_value = SGA_READ_FIELD + ( + g_sga_system_context.p_sga_registers->sga_ctstat, + SGA_CTSTAT_RESTARTCNT_MASK, + SGA_CTSTAT_RESTARTCNT_SHIFT + ); + break; + + default: + break; + } + + DBGEXIT0(stat_value); + return(stat_value); +} + +/****************************************************************************/ +/* NAME : SGA_GetStatistics() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION : Get the statistics of the Drawn primitives of */ +/* Smart Graphics Accelerator */ +/* PARAMETERS : */ +/* IN :t_sga_statistics_req statistics: contain the SGA status */ +/* info to be get */ +/* InOut :None */ +/* OUT :None */ +/* RETURN :t_uint32 contain the statistics value. */ +/*--------------------------------------------------------------------------*/ +/* Type : PUBLIC */ +/* REENTRANCY : Non Re-entrant */ +/* REENTRANCY ISSUES : */ +/****************************************************************************/ +PUBLIC t_uint32 SGA_GetStatistics(IN t_sga_statistics_req statistics) +{ + t_uint32 stat_value = 0; + + DBGENTER1("statistics (%d)", statistics); + + switch (statistics) + { + case SGA_STATISTICS_TRIANGLE_REQ: + stat_value = g_sga_system_context.p_sga_registers->sga_sttr; + break; + + case SGA_STATISTICS_FRAG_RAW_REQ: + stat_value = g_sga_system_context.p_sga_registers->sga_stfr; + break; + + case SGA_STATISTICS_FRAG_DEPTH_REQ: + stat_value = g_sga_system_context.p_sga_registers->sga_stfz; + break; + + case SGA_STATISTICS_TEXT_CACHE_REQ: + stat_value = g_sga_system_context.p_sga_registers->sga_sttx; + break; + + case SGA_STATISTICS_FRAME_CACHE_REQ: + stat_value = g_sga_system_context.p_sga_registers->sga_stfmrf; + break; + + case SGA_STATISTICS_TEXT_CACHE_REFILLS_REQ: + stat_value = g_sga_system_context.p_sga_registers->sga_sttxrf; + break; + + case SGA_STATISTICS_INSTRUCT_REFILL_REQ: + stat_value = g_sga_system_context.p_sga_registers->sga_stinrf; + break; + + case SGA_STATISTICS_CLK_CYCLES_REQ: + stat_value = g_sga_system_context.p_sga_registers->sga_stck; + break; + + default: + break; + } + + DBGEXIT0(stat_value); + return(stat_value); +} + +/****************************************************************************/ +/* NAME : SGA_GetCurrentInstrPointer() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION : Get the Current instruction pointer in side the */ +/* instruction list of the Smart Graphics Accelerator */ +/* PARAMETERS : */ +/* IN :None */ +/* InOut :None */ +/* OUT :None */ +/* RETURN :t_uint32 address of the current instruction pointer */ +/*--------------------------------------------------------------------------*/ +/* Type : PUBLIC */ +/* REENTRANCY : Non Re-entrant */ +/* REENTRANCY ISSUES : */ +/****************************************************************************/ +PUBLIC t_uint32 SGA_GetCurrentInstrPointer(void) +{ + return((t_uint32) g_sga_system_context.p_sga_registers->sga_cipr); +} + +/****************************************************************************/ +/* NAME : SGA_GetCurrentGotoCounter() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION : Get the Current goto counter of the Smart Graphics */ +/* Accelerator */ +/* PARAMETERS : */ +/* IN :None */ +/* InOut :None */ +/* OUT :None */ +/* RETURN :t_uint32 Current go to counter value */ +/*--------------------------------------------------------------------------*/ +/* Type : PUBLIC */ +/* REENTRANCY : Non Re-entrant */ +/* REENTRANCY ISSUES : */ + +/****************************************************************************/ +PUBLIC t_uint16 SGA_GetCurrentGotoCounter(void) +{ + return((t_uint16) g_sga_system_context.p_sga_registers->sga_cgcr); +} + +/****************************************************************************/ +/* NAME : SGA_GetVersion() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION : Return the version of the current SGA HCL API */ +/* PARAMETERS : */ +/* IN :None */ +/* InOut :None */ +/* OUT :t_version *p_version: contain the version of the HCL */ +/* RETURN :t_sga_error : SGA error code */ +/* SGA_OK : if it is ok */ +/* SGA_INVALID_PARAMETER if input parameter is invalid */ +/*--------------------------------------------------------------------------*/ +/* Type : PUBLIC */ +/* REENTRANCY : Non Re-entrant */ +/* REENTRANCY ISSUES : */ +/****************************************************************************/ +PUBLIC t_sga_error SGA_GetVersion(t_version *p_version) +{ + DBGENTER1("Get Version %lx", p_version); + if (NULL == p_version) + { + return(SGA_INVALID_PARAMETER); + } + + p_version->version = SGA_HCL_VERSION_ID; + p_version->major = SGA_HCL_MAJOR_ID; + p_version->minor = SGA_HCL_MINOR_ID; + + DBGEXIT0(SGA_OK); + return(SGA_OK); +} + +/****************************************************************************/ +/* NAME : SGA_GetBatchID() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION : Get the Batch id resource of the SGA */ +/* PARAMETERS : */ +/* IN :void */ +/* InOut :None */ +/* OUT :t_uint8* batch_id: contain SGA batch resource id */ +/* (Range is 0-15) */ +/* RETURN :t_sga_error : SGA error code */ +/* SGA_OK : if it is ok */ +/* SGA_RESOURCE_NOT_AVIALABLE if requested resource is not */ +/* available */ +/* SGA_INVALID_PARAMETER if input parameter is invalid */ +/*--------------------------------------------------------------------------*/ +/* Type : PUBLIC */ +/* REENTRANCY : Non Re-entrant */ +/* REENTRANCY ISSUES : */ +/****************************************************************************/ +PUBLIC t_sga_error SGA_GetBatchID(OUT t_uint8 *p_batch_id) +{ + t_uint8 i; + + DBGENTER1("Batch Id %lx", p_batch_id); + if (NULL == p_batch_id) + { + return(SGA_INVALID_PARAMETER); + } + + /*Check the available batch id */ + for (i = 0; i < 16; i++) + { + if (!((g_sga_system_context.batch_sem_id & (1 << i)) >> i)) + { + g_sga_system_context.batch_sem_id |= (1 << i); + break; + } + } + + if (16 == i) + { + DBGEXIT0(SGA_RESOURCE_NOT_AVIALABLE); + return(SGA_RESOURCE_NOT_AVIALABLE); + } + else + { + *p_batch_id = i; + DBGEXIT0(SGA_OK); + return(SGA_OK); + } +} + +/****************************************************************************/ +/* NAME : SGA_GetSemaphoreID() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION : Get the Semaphore id of the SGA */ +/* PARAMETERS : */ +/* IN :void */ +/* InOut :None */ +/* OUT :t_uint8* p_sem_id:contain SGA semaphore resource id */ +/* (Range is 0-15) */ +/* RETURN :t_sga_error : SGA error code */ +/* SGA_OK : if it is ok */ +/* SGA_RESOURCE_NOT_AVIALABLE if requested resource is not */ +/* available */ +/* SGA_INVALID_PARAMETER if input parameter is invalid */ +/*--------------------------------------------------------------------------*/ +/* Type : PUBLIC */ +/* REENTRANCY : Non Re-entrant */ +/* REENTRANCY ISSUES : */ +/****************************************************************************/ +PUBLIC t_sga_error SGA_GetSemaphoreID(t_uint8 *p_sem_id) +{ + t_uint8 i; + + DBGENTER1("Sem Id %lx", p_sem_id); + if (NULL == p_sem_id) + { + return(SGA_INVALID_PARAMETER); + } + + /*Check the available Semaphore ids */ + for (i = 16; i < 32; i++) + { + if (!((g_sga_system_context.batch_sem_id & (1 << i)) >> i)) + { + g_sga_system_context.batch_sem_id |= (1 << i); + break; + } + } + + if (32 == i) + { + DBGEXIT0(SGA_RESOURCE_NOT_AVIALABLE); + return(SGA_RESOURCE_NOT_AVIALABLE); + } + else + { + *p_sem_id = i; + + DBGEXIT0(SGA_OK); + return(SGA_OK); + } +} + +/****************************************************************************/ +/* NAME : SGA_GetIntID() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION : Get the interrupt id of the SGA */ +/* PARAMETERS : */ +/* IN :None */ +/* InOut :None */ +/* OUT :t_uint8* p_ int_id:contain SGA semaphore interrupt id */ +/* (Range is 0-15) */ +/* RETURN :t_sga_error : SGA error code */ +/* SGA_OK : if it is ok */ +/* SGA_RESOURCE_NOT_AVIALABLE if requested resource is not */ +/* available */ +/* SGA_INVALID_PARAMETER if input parameter is invalid */ +/*--------------------------------------------------------------------------*/ +/* Type : PUBLIC */ +/* REENTRANCY : Non Re-entrant */ +/* REENTRANCY ISSUES : */ +/****************************************************************************/ +PUBLIC t_sga_error SGA_GetIntID(OUT t_uint8 *p_int_id) +{ + t_uint8 i; + DBGENTER1("Interrupt Id %lx", p_int_id); + + if (NULL == p_int_id) + { + return(SGA_INVALID_PARAMETER); + } + + /*Check the available interrupts ids */ + for (i = 0; i < 26; i++) + { + if (!((g_sga_system_context.interrupt_id & (1 << i)) >> i)) + { + g_sga_system_context.interrupt_id |= (1 << i); + break; + } + } + + if (26 == i) + { + DBGEXIT0(SGA_RESOURCE_NOT_AVIALABLE); + return(SGA_RESOURCE_NOT_AVIALABLE); + } + else + { + *p_int_id = i; + + DBGEXIT0(SGA_OK); + return(SGA_OK); + } +} + +/****************************************************************************/ +/* NAME : SGA_ReleaseBatchID() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION : Release the SGA batch ID resource */ +/* PARAMETERS : */ +/* IN :t_uint8 batch_id: contain the batch id to be released */ +/* InOut :None */ +/* OUT :None */ +/* RETURN :t_sga_error : SGA error code */ +/* SGA_OK : if it is ok */ +/* SGA_INVALID_PARAMETER if input parameter is invalid */ +/*--------------------------------------------------------------------------*/ +/* Type : PUBLIC */ +/* REENTRANCY : Non Re-entrant */ +/* REENTRANCY ISSUES : */ +/****************************************************************************/ +PUBLIC t_sga_error SGA_ReleaseBatchID(IN t_uint8 batch_id) +{ + DBGENTER1("Relased Batch Id (%d)", batch_id); + + if (batch_id > 15) + { + DBGEXIT0(SGA_INVALID_PARAMETER); + return(SGA_INVALID_PARAMETER); + } + + /* Flag off the released batch id */ + g_sga_system_context.batch_sem_id &= (~(t_uint32) (1 << batch_id)); + + DBGEXIT0(SGA_OK); + return(SGA_OK); +} + +/****************************************************************************/ +/* NAME : SGA_ReleaseSemaphoreID() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION : Release the SGA batch semaphore resource ID. */ +/* PARAMETERS : */ +/* IN :t_uint32 sem_id:contain the semaphore id to be released */ +/* InOut :None */ +/* OUT :None */ +/* RETURN :t_sga_error : SGA error code */ +/* SGA_OK : if it is ok */ +/* SGA_INVALID_PARAMETER if input parameter is invalid */ +/*--------------------------------------------------------------------------*/ +/* Type : PUBLIC */ +/* REENTRANCY : Non Re-entrant */ +/* REENTRANCY ISSUES : */ +/****************************************************************************/ +PUBLIC t_sga_error SGA_ReleaseSemaphoreID(IN t_uint8 sem_id) +{ + DBGENTER1("Relased Sem Id (%d)", sem_id); + if ((sem_id < 16) || (sem_id > 31)) + { + DBGEXIT0(SGA_INVALID_PARAMETER); + return(SGA_INVALID_PARAMETER); + } + + /*Flag off the released semaphore id */ + g_sga_system_context.batch_sem_id &= (~(t_uint32) (1 << sem_id)); + + DBGEXIT0(SGA_OK); + return(SGA_OK); +} + +/****************************************************************************/ +/* NAME : SGA_ReleaseIntID() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION : Release the SGA interrupt resource ID. */ +/* PARAMETERS : */ +/* IN :t_uint8 int_id: contain the interrupt id to be released */ +/* InOut :None */ +/* OUT :None */ +/* RETURN :t_sga_error : SGA error code */ +/* SGA_OK : if it is ok */ +/* SGA_INVALID_PARAMETER if input parameter is invalid */ +/*--------------------------------------------------------------------------*/ +/* Type : PUBLIC */ +/* REENTRANCY : Non Re-entrant */ +/* REENTRANCY ISSUES : */ +/****************************************************************************/ +PUBLIC t_sga_error SGA_ReleaseIntID(IN t_uint8 int_id) +{ + DBGENTER1("Relased Interrupt Id (%d)", int_id); + if (int_id > 25) + { + DBGEXIT0(SGA_INVALID_PARAMETER); + return(SGA_INVALID_PARAMETER); + } + + /* Flag off the Released interrupt id */ + g_sga_system_context.interrupt_id &= (~(t_uint32) (1 << int_id)); + + DBGEXIT0(SGA_OK); + return(SGA_OK); +} + +/****************************************************************************/ +/* NAME : SGA_SetSemaphore() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION : Set the semaphore directly */ +/* PARAMETERS : */ +/* IN :t_uint8 sem_id: contain the semaphore id to be set in the */ +/* SGA registers */ +/* InOut :None */ +/* OUT :None */ +/* RETURN :void */ +/*--------------------------------------------------------------------------*/ +/* Type : PUBLIC */ +/* REENTRANCY : Non Re-entrant */ +/* REENTRANCY ISSUES : */ +/****************************************************************************/ +PUBLIC void SGA_SetSemaphore(IN t_uint8 sem_id) +{ + /*Set the corresponding test register bit */ + g_sga_system_context.p_sga_registers->sga_sitr |= (1 << sem_id); +} + +/****************************************************************************/ +/* NAME : SGA_ResetSemaphore() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION : Reset the semaphore directly */ +/* PARAMETERS : */ +/* IN :t_uint8 sem_id: contain the semaphore id to be reset in */ +/* the SGA registers */ +/* InOut :None */ +/* OUT :None */ +/* RETURN :void */ +/*--------------------------------------------------------------------------*/ +/* Type : PUBLIC */ +/* REENTRANCY : Non Re-entrant */ +/* REENTRANCY ISSUES : */ +/****************************************************************************/ +PUBLIC void SGA_ResetSemaphore(IN t_uint8 sem_id) +{ + /*Reset the corresponding test register bit */ + g_sga_system_context.p_sga_registers->sga_citr |= (1 << sem_id); +} + +/****************************************************************************/ +/* NAME : SGA_TestSemaphore() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION : Test the given semaphore state */ +/* PARAMETERS : */ +/* IN :t_uint8 sem_id:Semaphore id to be tested(range is 0 - 31) */ +/* InOut :None */ +/* OUT :None */ +/* RETURN :void */ +/*--------------------------------------------------------------------------*/ +/* Type : PUBLIC */ +/* REENTRANCY : Non Re-entrant */ +/* REENTRANCY ISSUES : */ +/****************************************************************************/ +PUBLIC t_bool SGA_TestSemaphore(IN t_uint8 sem_id) +{ + /*read the requested test id bit */ + return((t_bool) SGA_READ_FIELD(g_sga_system_context.p_sga_registers->sga_gitr, (1 << sem_id), sem_id)); +} + +/****************************************************************************/ +/* NAME : SGA_LinkBatch() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION : Set the batch address in the main firmware corresponding */ +/* to the batch id */ +/* PARAMETERS : */ +/* IN :t_uint8 batch_id: Batch id */ +/* t_uint32* p_batch_add: contain the starting location of */ +/* the batch firmware */ +/* InOut :None */ +/* OUT :None */ +/* RETURN :t_sga_error : SGA error code */ +/* SGA_OK : if it is ok */ +/* SGA_INVALID_PARAMETER if input parameter is invalid */ +/*--------------------------------------------------------------------------*/ +/* Type : PUBLIC */ +/* REENTRANCY : Non Re-entrant */ +/* REENTRANCY ISSUES : */ +/****************************************************************************/ +PUBLIC t_sga_error SGA_LinkBatch(IN t_uint8 batch_id, IN t_uint32 *p_batch_add) +{ + t_uint32 *p_batch_fw_add; /* batch FirmWare address */ + + if ((NULL == p_batch_add) || (batch_id >= MAX_BATCHES) || (((t_uint32) p_batch_add) & 0x7)) + { + DBGEXIT0(SGA_INVALID_PARAMETER); + return(SGA_INVALID_PARAMETER); + } + p_batch_fw_add = g_sga_system_context.p_logical_main_batch_add + (2 * batch_id + 1); + + /*Halt the main batch firmware executing by setting Instruction Halt bit in the */ + /* cotrol command register */ + SGA_SET_BIT(g_sga_system_context.p_sga_registers->sga_ctcmd, SGA_CTCMD_IHALT_MASK); + + /*update the batch firmware address in the main batch program */ + *p_batch_fw_add = GOSUB | (((t_uint32) p_batch_add) >> 3); + + /*Resume instructions execution */ + SGA_SET_BIT(g_sga_system_context.p_sga_registers->sga_ctcmd, SGA_CTCMD_IRESUME_MASK); + + DBGEXIT0(SGA_OK); + return(SGA_OK); +} + +/****************************************************************************/ +/* NAME : SGA_StartBatch() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION : Set the semaphore to start batch execution */ +/* PARAMETERS : */ +/* IN :t_uint8 batch_id: Batch id of the firmware */ +/* InOut :None */ +/* OUT :None */ +/* RETURN :t_sga_error : SGA error code */ +/* SGA_OK : if it is ok */ +/* SGA_INVALID_PARAMETER if input parameter is invalid */ +/*--------------------------------------------------------------------------*/ +/* Type : PUBLIC */ +/* REENTRANCY : Non Re-entrant */ +/* REENTRANCY ISSUES : */ +/****************************************************************************/ +PUBLIC t_sga_error SGA_StartBatch(IN t_uint8 batch_id) +{ + if (batch_id >= 16) + { + DBGEXIT0(SGA_INVALID_PARAMETER); + return(SGA_INVALID_PARAMETER); + } + /*Set the corresponding test register bit */ + g_sga_system_context.p_sga_registers->sga_sitr |= (1 << batch_id); + DBGEXIT0(SGA_OK); + return(SGA_OK); +} + +/****************************************************************************/ +/* NAME : SGA_BuildStopInstrFirmware() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION :This routine is used to build the stop instruction firmware*/ +/* PARAMETERS : */ +/* IN :None */ +/* InOut :None */ +/* OUT :t_uint32* p_no_cmd:contain the number of commands inserted */ +/* at the memory location */ +/* t_uint32* p_instr_add:Memory location to write the build */ +/* firmware */ +/* RETURN :t_sga_error : SGA error code */ +/* SGA_OK : if it is ok */ +/* SGA_INVALID_PARAMETER if input parameter is invalid */ +/*--------------------------------------------------------------------------*/ +/* Type : PUBLIC */ +/* REENTRANCY : Non Re-entrant */ +/* REENTRANCY ISSUES : */ +/****************************************************************************/ +PUBLIC t_sga_error SGA_BuildStopInstrFirmware(OUT t_uint32 *p_instr_add, OUT t_uint32 *p_no_cmd) +{ + DBGENTER0(); + + if (NULL == p_instr_add || NULL == p_no_cmd) + { + DBGEXIT0(SGA_INVALID_PARAMETER); + return(SGA_INVALID_PARAMETER); + } + + *p_instr_add = STOP; + *p_no_cmd = 1; + + DBGEXIT0(SGA_OK); + return(SGA_OK); +} + +/****************************************************************************/ +/* NAME : SGA_BuildReturnInstrFirmware() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION :This routine is used to build the return instruction */ +/* firmware */ +/* PARAMETERS : */ +/* IN :None */ +/* InOut :None */ +/* OUT :t_uint32* p_no_cmd:contain the number of commands inserted */ +/* at the memory location */ +/* t_uint32* p_instr_add:Memory location to write the build */ +/* firmware */ +/* RETURN :t_sga_error : SGA error code */ +/* SGA_OK : if it is ok */ +/* SGA_INVALID_PARAMETER if input parameter is invalid */ +/*--------------------------------------------------------------------------*/ +/* Type : PUBLIC */ +/* REENTRANCY : Non Re-entrant */ +/* REENTRANCY ISSUES : */ +/****************************************************************************/ +PUBLIC t_sga_error SGA_BuildReturnInstrFirmware(OUT t_uint32 *p_instr_add, OUT t_uint32 *p_no_cmd) +{ + DBGENTER0(); + + if ((NULL == p_instr_add) || (NULL == p_no_cmd)) + { + DBGEXIT0(SGA_INVALID_PARAMETER); + return(SGA_INVALID_PARAMETER); + } + + *p_instr_add = RETURN; + *p_no_cmd = 1; + + DBGEXIT0(SGA_OK); + return(SGA_OK); +} + +/****************************************************************************/ +/* NAME : SGA_BuildSendSynchroFirmware() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION :This routine is used to build the SendSynchro instruction */ +/* firmware */ +/* PARAMETERS : */ +/* IN :None */ +/* InOut :None */ +/* OUT :t_uint32* p_no_cmd:contain the number of commands inserted */ +/* at the memory location */ +/* t_uint32* p_instr_add:Memory location to write the build */ +/* firmware */ +/* RETURN :t_sga_error : SGA error code */ +/* SGA_OK : if it is ok */ +/* SGA_INVALID_PARAMETER if input parameter is invalid */ +/*--------------------------------------------------------------------------*/ +/* Type : PUBLIC */ +/* REENTRANCY : Non Re-entrant */ +/* REENTRANCY ISSUES : */ +/****************************************************************************/ +PUBLIC t_sga_error SGA_BuildSendSynchroFirmware(OUT t_uint32 *p_instr_add, OUT t_uint32 *p_no_cmd) +{ + DBGENTER0(); + + if ((NULL == p_instr_add) || (NULL == p_no_cmd)) + { + DBGEXIT0(SGA_INVALID_PARAMETER); + return(SGA_INVALID_PARAMETER); + } + + *p_instr_add = SEND_SYNCHRO; + + /* number of commands inserted at the memory location */ + *p_no_cmd = 1; + + DBGEXIT0(SGA_OK); + return(SGA_OK); +} + +/****************************************************************************/ +/* NAME : SGA_BuildSemaphoreConfigFirmware() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION :This routine is used to build the firmware for semaphore */ +/* configuration. */ +/* PARAMETERS : */ +/* IN :t_uint8 sem_id: Semaphore id */ +/* t_sga_semaphore_state sem_state:Semaphore state */ +/* (set or reset ) */ +/* InOut :None */ +/* OUT :t_uint32* p_no_cmd:contain the number of commands inserted */ +/* at the memory location */ +/* t_uint32* p_instr_add:Memory location to write the build */ +/* firmware */ +/* RETURN :t_sga_error : SGA error code */ +/* SGA_OK : if it is ok */ +/* SGA_INVALID_PARAMETER if input parameter is invalid */ +/*--------------------------------------------------------------------------*/ +/* Type : PUBLIC */ +/* REENTRANCY : Non Re-entrant */ +/* REENTRANCY ISSUES : */ +/****************************************************************************/ +PUBLIC t_sga_error SGA_BuildSemaphoreConfigFirmware +( + IN t_uint8 sem_id, + IN t_sga_semaphore_state sem_state, + OUT t_uint32 *p_instr_add, + OUT t_uint32 *p_no_cmd +) +{ + DBGENTER0(); + + if ((NULL == p_instr_add) || (NULL == p_no_cmd) || (sem_id >= 32)) + { + DBGEXIT0(SGA_INVALID_PARAMETER); + return(SGA_INVALID_PARAMETER); + } + + switch (sem_state) + { + case SGA_SEMAPHORE_SET: + *p_instr_add = SET_INSTR_TEST_REG | sem_id; + break; + + case SGA_SEMAPHORE_RESET: + *p_instr_add = CLR_INSTR_TEST_REG | sem_id; + break; + } + + /*number of commands inserted at the memory location */ + *p_no_cmd = 1; + + DBGEXIT0(SGA_OK); + return(SGA_OK); +} + +/****************************************************************************/ +/* NAME : SGA_BuildTestSemaphoreFirmware() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION :This routine is used to build the firmware for */ +/* test Semaphore instruction. */ +/* PARAMETERS : */ +/* IN :t_uint8 sem_id: Semaphore id */ +/* InOut :None */ +/* OUT :t_uint32* p_no_cmd:contain the number of commands inserted */ +/* at the memory location */ +/* t_uint32* p_instr_add:Memory location to write the build */ +/* firmware */ +/* RETURN :t_sga_error : SGA error code */ +/* SGA_OK : if it is ok */ +/* SGA_INVALID_PARAMETER if input parameter is invalid */ +/*--------------------------------------------------------------------------*/ +/* Type : PUBLIC */ +/* REENTRANCY : Non Re-entrant */ +/* REENTRANCY ISSUES : */ +/****************************************************************************/ +PUBLIC t_sga_error SGA_BuildTestSemaphoreFirmware(IN t_uint8 sem_id, OUT t_uint32 *p_instr_add, OUT t_uint32 *p_no_cmd) +{ + DBGENTER0(); + + if ((NULL == p_instr_add) || (NULL == p_no_cmd) || (sem_id > 31)) + { + DBGEXIT0(SGA_INVALID_PARAMETER); + return(SGA_INVALID_PARAMETER); + } + + *p_instr_add = TST_INSTR_TEST_REG | sem_id; + + /* number of instructions inserted at memory location */ + *p_no_cmd = 1; + + DBGEXIT0(SGA_OK); + return(SGA_OK); +} + +/****************************************************************************/ +/* NAME : SGA_BuildSetIntFirmware() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION :This routine is used to build the firmware for */ +/* set instruction. */ +/* PARAMETERS : */ +/* IN :t_uint32 int_id: Interrupt id(rage 0-25) */ +/* InOut :None */ +/* OUT :t_uint32* p_no_cmd:contain the number of commands inserted */ +/* at the memory location */ +/* t_uint32* p_instr_add:Memory location to write the build */ +/* firmware */ +/* RETURN :t_sga_error : SGA error code */ +/* SGA_OK : if it is ok */ +/* SGA_INVALID_PARAMETER if input parameter is invalid */ +/*--------------------------------------------------------------------------*/ +/* Type : PUBLIC */ +/* REENTRANCY : Non Re-entrant */ +/* REENTRANCY ISSUES : */ +/****************************************************************************/ +PUBLIC t_sga_error SGA_BuildSetIntFirmware(IN t_uint32 int_id, OUT t_uint32 *p_instr_add, OUT t_uint32 *p_no_cmd) +{ + DBGENTER0(); + + if ((NULL == p_instr_add) || (NULL == p_no_cmd) || (int_id >= 26)) + { + DBGEXIT0(SGA_INVALID_PARAMETER); + return(SGA_INVALID_PARAMETER); + } + + *p_instr_add = SEND_INTERRUPT | int_id; + + /*number of commands inserted at the memory location */ + *p_no_cmd = 1; + + DBGEXIT0(SGA_OK); + return(SGA_OK); +} + +/****************************************************************************/ +/* NAME : SGA_BuildWaitInstrFirmware() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION :This routine is used to build the firmware for Wait */ +/* instructions */ +/* PARAMETERS : */ +/* IN :t_sga_wait_config *p_wait:contain the wait instruction to */ +/* be build and associated parameters */ +/* InOut :None */ +/* OUT :t_uint32* p_no_cmd:contain the number of commands inserted */ +/* at the memory location */ +/* t_uint32* p_instr_add:Memory location to write the build */ +/* firmware */ +/* RETURN :t_sga_error : SGA error code */ +/* SGA_OK : if it is ok */ +/* SGA_INVALID_PARAMETER if input parameter is invalid */ +/*--------------------------------------------------------------------------*/ +/* Type : PUBLIC */ +/* REENTRANCY : Non Re-entrant */ +/* REENTRANCY ISSUES : */ +/****************************************************************************/ +PUBLIC t_sga_error SGA_BuildWaitInstrFirmware +( + IN t_sga_wait_config *p_wait, + OUT t_uint32 *p_instr_add, + OUT t_uint32 *p_no_cmd +) +{ + DBGENTER0(); + if ((NULL == p_instr_add) || (NULL == p_no_cmd) || (NULL == p_wait)) + { + DBGEXIT0(SGA_INVALID_PARAMETER); + return(SGA_INVALID_PARAMETER); + } + + switch (p_wait->wait) + { + case SGA_WAIT_SYNCHRO: + *p_instr_add = WAIT_SYNCHRO | ((0xFFFFF & p_wait->wait_time) << 4) | (0x3 & p_wait->synchro_port); + break; + + case SGA_WAIT_NEWSYNCHRO: + *p_instr_add = WAIT_NEW_SYNCHRO | ((0xFFFFF & p_wait->wait_time) << 4) | (0x3 & p_wait->synchro_port); + break; + + case SGA_WAIT_N_CYCLES: + *p_instr_add = WAIT_N_CYCLES | (0xFFFFFF & p_wait->wait_time); + break; + + case SGA_WAIT_PIPE_EMPTY: + *p_instr_add = WAIT_PIPE_EMPTY | (0x1 & (t_uint32) p_wait->pipe_empty_type); + break; + + default: + break; + } + + /*store the number of commands inserted at the memory location */ + *p_no_cmd = 1; + + DBGEXIT0(SGA_OK); + return(SGA_OK); +} + +/****************************************************************************/ +/* NAME : SGA_BuildAhbInstrFirmware() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION :This routine is used to build the firmware for AHB */ +/* instruction */ +/* PARAMETERS : */ +/* IN :t_sga_ahb_config* p_ahb:contain the Ahb instruction */ +/* settings */ +/* InOut :None */ +/* OUT :t_uint32* p_no_cmd:contain the number of commands inserted */ +/* at the memory location */ +/* t_uint32* p_instr_add:Memory location to write the build */ +/* firmware */ +/* RETURN :t_sga_error : SGA error code */ +/* SGA_OK : if it is ok */ +/* SGA_INVALID_PARAMETER if input parameter is invalid */ +/*--------------------------------------------------------------------------*/ +/* Type : PUBLIC */ +/* REENTRANCY : Non Re-entrant */ +/* REENTRANCY ISSUES : */ +/****************************************************************************/ +PUBLIC t_sga_error SGA_BuildAhbInstrFirmware +( + IN t_sga_ahb_config *p_ahb, + OUT t_uint32 *p_instr_add, + OUT t_uint32 *p_no_cmd +) +{ + DBGENTER0(); + + if ((NULL == p_instr_add) || (NULL == p_no_cmd) || (NULL == p_ahb)) + { + DBGEXIT0(SGA_INVALID_PARAMETER); + return(SGA_INVALID_PARAMETER); + } + + *p_instr_add = AHB | ((((t_uint32) p_ahb->active_autofetch) &0x1) << 8) | ((((t_uint32) p_ahb->hclk_lock) & 0x1) << 6) | ((0x3 & ((t_uint32) p_ahb->burst_type)) << 4) | (0xF & p_ahb->hprot); + + /*number of commands inserted at memory location */ + *p_no_cmd = 1; + + DBGEXIT0(SGA_OK); + return(SGA_OK); +} + +/****************************************************************************/ +/* NAME : SGA_BuildGotoInstrFirmware() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION :This routine is used to build the firmware for Goto */ +/* instruction */ +/* PARAMETERS : */ +/* IN :t_uint32 addr :contain goto (jump) address */ +/* (it must be quad word aligned, ie 3 lsb bits must be zero)*/ +/* InOut :None */ +/* OUT :t_uint32* p_no_cmd:contain the number of commands inserted */ +/* at the memory location */ +/* t_uint32* p_instr_add:Memory location to write the build */ +/* firmware */ +/* RETURN :t_sga_error : SGA error code */ +/* SGA_OK : if it is ok */ +/* SGA_INVALID_PARAMETER if input parameter is invalid */ +/*--------------------------------------------------------------------------*/ +/* Type : PUBLIC */ +/* REENTRANCY : Non Re-entrant */ +/* REENTRANCY ISSUES : */ +/****************************************************************************/ +PUBLIC t_sga_error SGA_BuildGotoInstrFirmware(IN t_uint32 addr, OUT t_uint32 *p_instr_add, OUT t_uint32 *p_no_cmd) +{ + DBGENTER0(); + + if ((NULL == p_instr_add) || (NULL == p_no_cmd) || (NULL == addr) || (0x7 & ((t_uint32) addr))) + { + DBGEXIT0(SGA_INVALID_PARAMETER); + return(SGA_INVALID_PARAMETER); + } + + *p_instr_add = GOTO | (((t_uint32) addr) >> 3); + + /*number of commands inserted at memory location */ + *p_no_cmd = 1; + + DBGEXIT0(SGA_OK); + return(SGA_OK); +} + +/****************************************************************************/ +/* NAME : SGA_BuildNoOpInstrFirmware() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION :This routine is used to build the firmware for NoOp */ +/* instruction */ +/* PARAMETERS : */ +/* IN :None */ +/* InOut :None */ +/* OUT :t_uint32* p_no_cmd:contain the number of commands inserted */ +/* at the memory location */ +/* t_uint32* p_instr_add:Memory location to write the build */ +/* firmware */ +/* RETURN :t_sga_error : SGA error code */ +/* SGA_OK : if it is ok */ +/* SGA_INVALID_PARAMETER if input parameter is invalid */ +/*--------------------------------------------------------------------------*/ +/* Type : PUBLIC */ +/* REENTRANCY : Non Re-entrant */ +/* REENTRANCY ISSUES : */ +/****************************************************************************/ +PUBLIC t_sga_error SGA_BuildNoOpInstrFirmware(OUT t_uint32 *p_instr_add, OUT t_uint32 *p_no_cmd) +{ + DBGENTER0(); + if ((NULL == p_instr_add) || (NULL == p_no_cmd)) + { + DBGEXIT0(SGA_INVALID_PARAMETER); + return(SGA_INVALID_PARAMETER); + } + + *p_instr_add = NO_OP; + + /*Number of commands inserted at memory location */ + *p_no_cmd = 1; + + DBGEXIT0(SGA_OK); + return(SGA_OK); +} + +/****************************************************************************/ +/* NAME : SGA_BuildGoSubInstrFirmware() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION :This routine is used to build the firmware for GoSub */ +/* instruction */ +/* PARAMETERS : */ +/* IN :t_uint32 addr :contain GoSub (jump) address */ +/* (it must be quad word aligned, ie 3 lsb bits must be zero)*/ +/* InOut :None */ +/* OUT :t_uint32* p_no_cmd:contain the number of commands inserted */ +/* at the memory location */ +/* t_uint32* p_instr_add:Memory location to write the build */ +/* firmware */ +/* RETURN :t_sga_error : SGA error code */ +/* SGA_OK : if it is ok */ +/* SGA_INVALID_PARAMETER if input parameter is invalid */ +/*--------------------------------------------------------------------------*/ +/* Type : PUBLIC */ +/* REENTRANCY : Non Re-entrant */ +/* REENTRANCY ISSUES : */ +/****************************************************************************/ +PUBLIC t_sga_error SGA_BuildGoSubInstrFirmware(IN t_uint32 addr, OUT t_uint32 *p_instr_add, OUT t_uint32 *p_no_cmd) +{ + DBGENTER0(); + if ((NULL == p_instr_add) || (NULL == p_no_cmd) || (NULL == addr) || (0x7 & ((t_uint32) addr))) + { + DBGEXIT0(SGA_INVALID_PARAMETER); + return(SGA_INVALID_PARAMETER); + } + + *p_instr_add = GOSUB | (((t_uint32) addr) >> 3); + + /*number of commands inserted at memory location */ + *p_no_cmd = 1; + + DBGEXIT0(SGA_OK); + return(SGA_OK); +} + +/****************************************************************************/ +/* NAME : SGA_BuildCacheControlFirmware() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION :This routine is used to build the firmware for Cache */ +/* instruction */ +/* PARAMETERS : */ +/* IN :t_sga_cache_config* p_cache: contain the cache control */ +/* settings */ +/* InOut :None */ +/* OUT :t_uint32* p_no_cmd:contain the number of commands inserted */ +/* at the memory location */ +/* t_uint32* p_instr_add:Memory location to write the build */ +/* firmware */ +/* RETURN :t_sga_error : SGA error code */ +/* SGA_OK : if it is ok */ +/* SGA_INVALID_PARAMETER if input parameter is invalid */ +/*--------------------------------------------------------------------------*/ +/* Type : PUBLIC */ +/* REENTRANCY : Non Re-entrant */ +/* REENTRANCY ISSUES : */ +/****************************************************************************/ +PUBLIC t_sga_error SGA_BuildCacheControlFirmware +( + IN t_sga_cache_config *p_cache, + OUT t_uint32 *p_instr_add, + OUT t_uint32 *p_no_cmd +) +{ + DBGENTER0(); + + if ((NULL == p_instr_add) || (NULL == p_no_cmd) || (NULL == p_cache)) + { + DBGEXIT0(SGA_INVALID_PARAMETER); + return(SGA_INVALID_PARAMETER); + } + + /*build the CacheControl command */ + *p_instr_add = CACHE_CTRL | ((((t_uint32) p_cache->bank_optm_disable ) &0x1) << 18) | + ((((t_uint32) p_cache->hardinit_text) & 0x1) << 17) | ((((t_uint32) p_cache->hardinit_out) &0x1) << 16) | + ((((t_uint32) p_cache->hardinit_in0) & 0x1) << 15) | ((((t_uint32) p_cache->autoinit_text) & 0x1) << 14) | + ((((t_uint32) p_cache->autoinit_out) & 0x1) << 13) | ((((t_uint32) p_cache->autoinit_in0) & 0x1) << 12) | + ((((t_uint32) p_cache->manualflush_text) & 0x1) << 11) | ((((t_uint32) p_cache->manualflush_out) &0x1) << 10) | + ((((t_uint32) p_cache->manualflush_in0) & 0x1) << 9) | ((((t_uint32) p_cache->autoflush_text) & 0x1) << 8) | + ((((t_uint32) p_cache->autoflush_out) & 0x1) << 7) | ((((t_uint32) p_cache->autoflush_in0) & 0x1) << 6) | + ( + (((t_uint32) p_cache->mode) & 0x3) << + 4 + ) | + ((((t_uint32) p_cache->cache_topo_out) & 0x1) << 3) | + ((((t_uint32) p_cache->cache_topo_in2) & 0x1) << 2) | + ((((t_uint32) p_cache->cache_topo_in1) & 0x1)<< 1) | + ((((t_uint32) p_cache->cache_topo_in0) & 0x1) << 0); + + /*Number of commands inserted at memory location */ + *p_no_cmd = 1; + + DBGEXIT0(SGA_OK); + return(SGA_OK); +} + +/****************************************************************************/ +/* NAME : SGA_BuildBufferConfigFirmware() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION :This routine is used to build the firmware for */ +/* buffer(in0, in1,in2 and OUT) instructions */ +/* PARAMETERS : */ +/* IN :t_sga_image_buffer buffer : specify the buffer */ +/* ( in0/ in1/in2 /OUT) */ +/* t_sga_buffer_config* p_buf_config: contain the buffer */ +/* configuration details */ +/* t_sga_buffer_pixel_settings * p_pix_config:Contain the */ +/* pixel configuration details for the buffer */ +/* InOut :None */ +/* OUT :t_uint32* p_no_cmd:contain the number of commands inserted */ +/* at the memory location */ +/* t_uint32* p_instr_add:Memory location to write the build */ +/* firmware */ +/* RETURN :t_sga_error : SGA error code */ +/* SGA_OK : if it is ok */ +/* SGA_INVALID_PARAMETER if input parameter is invalid */ +/*--------------------------------------------------------------------------*/ +/* Type : PUBLIC */ +/* REENTRANCY : Non Re-entrant */ +/* REENTRANCY ISSUES : */ +/****************************************************************************/ +PUBLIC t_sga_error SGA_BuildBufferConfigFirmware +( + IN t_sga_image_buffer buffer, + IN t_sga_buffer_config *p_buf_config, + IN t_sga_buffer_pixel_settings *p_pix_config, + OUT t_uint32 *p_instr_add, + OUT t_uint32 *p_no_cmd +) +{ + t_uint32 i = 0, temp = 0; + + DBGENTER0(); + + if ((NULL == p_instr_add) || (NULL == p_no_cmd) || (NULL == p_pix_config) || (NULL == p_buf_config)) + { + DBGEXIT0(SGA_INVALID_PARAMETER); + return(SGA_INVALID_PARAMETER); + } + + switch (buffer) + { + case SGA_IMAGE_BUFFER_IN0: + p_instr_add[i++] = IN0_BASE_ADD_MSB | (0xFF & (p_buf_config->buffer_address >> 24)); + p_instr_add[i++] = IN0_BASE_ADD | (0xFFFFFF & (p_buf_config->buffer_address)); + p_instr_add[i++] = IN0_SET_LINE_JUMP | (0x1FFF & p_buf_config->line_jump); + p_instr_add[i++] = IN0_SET_SIZE_XY | ((0x7FF & p_buf_config->x_size) << 12) | (0x7FF & p_buf_config->y_size); + + /*Buliding the firmware for in0 set delta XY */ + temp = (((p_buf_config->x_shift) & 0xFFF) << 12) | ((p_buf_config->y_shift) & 0xFFF); + + p_instr_add[i++] = IN0_SET_DELTA_XY | temp; + + /*building the firmware for in0 set pixel type */ + temp = IN0_SET_PIXEL_TYPE | ((((t_uint32) p_pix_config->colour_to_zero) & 0x1) << 18) | + ((((t_uint32) p_pix_config->colour_conversion) & 0x1) << 17) | ((((t_uint32) p_pix_config->yuv_rgb) & 0x1) << 16) | + ( + (((t_uint32) p_pix_config->truncate_to_16_235) & 0x1) << + 15 + ) | + ((((t_uint32) p_pix_config->activate_depack) & 0x1) << 14) | + ((((t_uint32) p_pix_config->activate_flow) & 0x1) << 12) | + ((((t_uint32) p_pix_config->freeze_ahb_address) & 0x1) << 11) | + ((((t_uint32) p_pix_config->memory_bypass) & 0x1) << 10) | + ((((t_uint32) p_pix_config->dma_synchro) & 0x1) << 9) | + ((((t_uint32) p_pix_config->alpha_to_255)& 0x1) << 8) | + ((((t_uint32) p_pix_config->stencil_mode) & 0x3) << 6) | + ((((t_uint32) p_pix_config->exchange_red_blue) & 0x1) << 5) | + ((((t_uint32) p_pix_config->endian) & 0x1) << 4) | + (0xF & ((t_uint32) p_pix_config->pixel_format)); + +/* if (SGA_PIXEL_FORMAT_ARGB24 == p_pix_config->pixel_format) + { + temp |= (1 << 14); + } +*/ + p_instr_add[i++] = temp; + + break; + + case SGA_IMAGE_BUFFER_IN1: + p_instr_add[i++] = IN1_BASE_ADD_MSB | (0xFF & (p_buf_config->buffer_address >> 24)); + p_instr_add[i++] = IN1_BASE_ADD | (0xFFFFFF & p_buf_config->buffer_address); + p_instr_add[i++] = IN1_SET_LINE_JUMP | (0x1FFF & p_buf_config->line_jump); + p_instr_add[i++] = IN1_SET_SIZE_XY | ((0x7FF & p_buf_config->x_size) << 12) | (0x7FF & p_buf_config->y_size); + + /*buliding the firmware for in1SetDeltaXY instruction */ + temp = ((p_buf_config->x_shift & 0xFFF) << 12) | (p_buf_config->y_shift & 0xFFF); + + p_instr_add[i++] = IN1_SET_DELTA_XY | temp; + + /*building the firmware for in1 set pixel type */ + temp = IN1_SET_PIXEL_TYPE | ((((t_uint32) p_pix_config->colour_to_zero) & 0x1) << 18) | + ((((t_uint32) p_pix_config->colour_conversion) & 0x1) << 17) | ((((t_uint32) p_pix_config->yuv_rgb) & 0x1) << 16) | + ((((t_uint32) p_pix_config->truncate_to_16_235) & 0x1) << 15) | ((((t_uint32) p_pix_config->bilinear_mode) & 0x1) << 13) | + ((((t_uint32) p_pix_config->activate_depack) & 0x1) << 14) | + ((((t_uint32) p_pix_config->activate_flow) & 0x1) << 12) | + ((((t_uint32) p_pix_config->freeze_ahb_address) & 0x1) << 11) | + ((((t_uint32) p_pix_config->memory_bypass) & 0x1) << 10) | + ((((t_uint32) p_pix_config->dma_synchro) & 0x1) << 9) | + ((((t_uint32) p_pix_config->alpha_to_255) & 0x1) << 8) | + ((((t_uint32) p_pix_config->exchange_red_blue) & 0x1) << 5) | + ((((t_uint32) p_pix_config->endian) & 0x1) << 4) | + (0xF & ((t_uint32) p_pix_config->pixel_format)); + +/* if (SGA_PIXEL_FORMAT_ARGB24 == p_pix_config->pixel_format) + { + temp |= (1 << 14); + } +*/ + p_instr_add[i++] = temp; + + break; + + case SGA_IMAGE_BUFFER_IN2: + p_instr_add[i++] = IN2_BASE_ADD_MSB | (0xFF & (p_buf_config->buffer_address >> 24)); + p_instr_add[i++] = IN2_BASE_ADD | (0xFFFFFF & p_buf_config->buffer_address); + p_instr_add[i++] = IN2_SET_LINE_JUMP | (0x1FFF & p_buf_config->line_jump); + p_instr_add[i++] = IN2_SET_SIZE_XY | ((0x7FF & p_buf_config->x_size) << 12) | (0x7FF & p_buf_config->y_size); + + /*buliding the firmware for in2 set delta XY */ + temp = ((p_buf_config->x_shift & 0xFFF) << 12) | (p_buf_config->y_shift & 0xFFF); + + p_instr_add[i++] = IN2_SET_DELTA_XY | temp; + + /*building the firmware for in2 set pixel type */ + temp = IN2_SET_PIXEL_TYPE | ((((t_uint32) p_pix_config->colour_to_zero) & 0x1) << 18) | + ((((t_uint32) p_pix_config->colour_conversion) & 0x1) << 17) | ((((t_uint32) p_pix_config->yuv_rgb) & 0x1) << 16) | + ((((t_uint32) p_pix_config->truncate_to_16_235) & 0x1) << 15) | ((((t_uint32) p_pix_config->bilinear_mode) & 0x1) << 13) | + ((((t_uint32) p_pix_config->activate_depack) & 0x1) << 14) | + ((((t_uint32) p_pix_config->activate_flow) & 0x1) << 12) | + ((((t_uint32) p_pix_config->freeze_ahb_address) & 0x1) << 11) | + ((((t_uint32) p_pix_config->memory_bypass) & 0x1) << 10) | + ((((t_uint32) p_pix_config->dma_synchro) & 0x1) << 9) | + ((((t_uint32) p_pix_config->alpha_to_255) & 0x1) << 8) | + ((((t_uint32) p_pix_config->exchange_red_blue) & 0x1) << 5) | + ((((t_uint32) p_pix_config->endian) & 0x1) << 4) | + (0xF & ((t_uint32) p_pix_config->pixel_format)); + +/* if (SGA_PIXEL_FORMAT_ARGB24 == p_pix_config->pixel_format) + { + temp |= (1 << 14); + } +*/ + p_instr_add[i++] = temp; + + break; + + case SGA_IMAGE_BUFFER_OUT: + p_instr_add[i++] = OUT_BASE_ADD_MSB | (0xFF & (p_buf_config->buffer_address >> 24)); + p_instr_add[i++] = OUT_BASE_ADD | (0xFFFFFF & p_buf_config->buffer_address); + p_instr_add[i++] = OUT_SET_LINE_JUMP | (0x1FFF & p_buf_config->line_jump); + p_instr_add[i++] = OUT_SET_SIZE_XY | ((0x7FF & p_buf_config->x_size) << 12) | (0x7FF & p_buf_config->y_size); + p_instr_add[i++] = OUT_SET_BASE_XY | ((0x7FF & p_buf_config->scissor_clip_x) << 12) | (0x7FFF & p_buf_config->scissor_clip_y); + + /*building the firmware for OutSetPixel type instruction*/ + temp = OUT_SET_PIXEL_TYPE | ((((t_uint32) p_pix_config->activate_depack) & 0x1) << 14) | ((((t_uint32) p_pix_config->freeze_ahb_address) & 0x1) << 11) | + ((((t_uint32) p_pix_config->dma_synchro) & 0x1) << 9) | ((((t_uint32) p_pix_config->stencil_mode) & 0x3) << 6) | + ((((t_uint32) p_pix_config->exchange_red_blue) & 0x1) << 5) | ((((t_uint32) p_pix_config->endian) & 0x1) << 4) | + (0xF & ((t_uint32) p_pix_config->pixel_format)); + +/* if (SGA_PIXEL_FORMAT_ARGB24 == p_pix_config->pixel_format) + { + temp |= (1 << 14); + } +*/ + p_instr_add[i++] = temp; + + break; + + default: + break; + } + + /* number of commands inserted at memory location */ + *p_no_cmd = i; + + DBGEXIT0(SGA_OK); + return(SGA_OK); +} + +/****************************************************************************/ +/* NAME : SGA_BuildDrawPrimitiveFirmware() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION :This routine is used to build the firmware for drawing */ +/* primitives. */ +/* PARAMETERS : */ +/* IN :t_sga_graphic_command* p_command:contain drawing request */ +/* and parameters for setting the drawing points and colours */ +/* InOut :None */ +/* OUT :t_uint32* p_no_cmd:contain the number of commands inserted */ +/* at the memory location */ +/* t_uint32* p_instr_add:Memory location to write the build */ +/* firmware */ +/* RETURN :t_sga_error : SGA error code */ +/* SGA_OK : if it is ok */ +/* SGA_INVALID_PARAMETER if input parameter is invalid */ +/*--------------------------------------------------------------------------*/ +/* Type : PUBLIC */ +/* REENTRANCY : Non Re-entrant */ +/* REENTRANCY ISSUES : */ +/****************************************************************************/ +PUBLIC t_sga_error SGA_BuildDrawPrimitiveFirmware +( + IN t_sga_graphic_command *p_command, + OUT t_uint32 *p_instr_add, + OUT t_uint32 *p_no_cmd +) +{ + t_uint32 i = 0; + + DBGENTER0(); + + if ((NULL == p_instr_add) || (NULL == p_no_cmd) || (NULL == p_no_cmd)) + { + DBGEXIT0(SGA_INVALID_PARAMETER); + return(SGA_INVALID_PARAMETER); + } + + switch (p_command->graphic_type) + { + case SGA_GRAPHIC_DRAWPOINT: + if (TRUE == p_command->colour_set) + { + /*Set the colour */ + p_instr_add[i++] = SET_COLOR | (0xFFFFFF & p_command->rgb_colour); + } + else + { + /*Set the interpolation or decimation increment values */ + p_instr_add[i++] = SET_COLOR | ((0x7 & p_command->interpol_inc_x_int) << 21) | + ((0x1FF & p_command->interpol_inc_x_dec) << 12) | ((0x7 & p_command->interpol_inc_y_int) << 9) | + (0x1FF & p_command->interpol_inc_y_dec); + } + + if (TRUE == p_command->set_bypass_zs) + { + /*Set Z and S component of the colour used to draw when pixel operator is in */ + /*by pass mode */ + p_instr_add[i++] = SET_BYPASS_ZS | ((0xFFFF & p_command->z_colour) << 8) | (0xFF & p_command->s_colour); + } + + /*Set the Draw Point command */ + p_instr_add[i++] = DRAW_POINT | ((0x7FF & p_command->point_x0) << 12) | (0x7FF & p_command->point_y0); + break; + + case SGA_GRAPHIC_DRAWLINE: + p_instr_add[i++] = SET_POINT0 | ((0x7FF & p_command->point_x0) << 12) | (0x7FF & p_command->point_y0); + p_instr_add[i++] = SET_POINT1 | ((0x7FF & p_command->point_x1) << 12) | (0x7FF & p_command->point_y1); + + if (TRUE == p_command->colour_set) + { + /*Set the colour */ + p_instr_add[i++] = SET_COLOR | (0xFFFFFF & p_command->rgb_colour); + } + else + { + /*Set the interpolation or decimation increment values */ + p_instr_add[i++] = SET_COLOR | ((0x7 & p_command->interpol_inc_x_int) << 21) | + ((0x1FF & p_command->interpol_inc_x_dec) << 12) | ((0x7 & p_command->interpol_inc_y_int) << 9) | + (0x1FF & p_command->interpol_inc_y_dec); + } + + /*set the line stippling factor */ + p_instr_add[i++] = LINE_STIPPLING | ((0xFF & p_command->stippling_factor) << 16) | (0xFFFF & p_command->stippling_mask); + + if (TRUE == p_command->set_bypass_zs) + { + /*Set Z and S component of the colour used to draw when pixel operator is in */ + /*by pass mode */ + p_instr_add[i++] = SET_BYPASS_ZS | ((0xFFFF & p_command->z_colour) << 8) | (0xFF & p_command->s_colour); + } + + /*set the Draw line command */ + p_instr_add[i++] = DRAW_LINE; + break; + + case SGA_GRAPHIC_DRAWTRIANGLE: + p_instr_add[i++] = SET_POINT0 | ((0x7FF & p_command->point_x0) << 12) | (0x7FF & p_command->point_y0); + p_instr_add[i++] = SET_POINT1 | ((0x7FF & p_command->point_x1) << 12) | (0x7FF & p_command->point_y1); + p_instr_add[i++] = SET_POINT2 | ((0x7FF & p_command->point_x2) << 12) | (0x7FF & p_command->point_y2); + + if (TRUE == p_command->colour_set) + { + /*Set the colour */ + p_instr_add[i++] = SET_COLOR | (0xFFFFFF & p_command->rgb_colour); + } + else + { + /*Set the interpolation or decimation increment values */ + p_instr_add[i++] = SET_COLOR | ((0x7 & p_command->interpol_inc_x_int) << 21) | + ((0x1FF & p_command->interpol_inc_x_dec) << 12) | ((0x7 & p_command->interpol_inc_y_int) << 9) | + (0x1FF & p_command->interpol_inc_y_dec); + } + + if (TRUE == p_command->set_bypass_zs) + { + /*Set Z and S component of the colour used to draw when pixel operator is in */ + /*by pass mode */ + p_instr_add[i++] = SET_BYPASS_ZS | ((0xFFFF & p_command->z_colour) << 8) | (0xFF & p_command->s_colour); + } + + /*set the Draw Triangle command */ + p_instr_add[i++] = DRAW_TRIANGLE; + break; + + case SGA_GRAPHIC_DRAWRECTANGLE: + p_instr_add[i++] = SET_POINT0 | ((0x7FF & p_command->point_x0) << 12) | (0x7FF & p_command->point_y0); + p_instr_add[i++] = SET_POINT1 | ((0x7FF & p_command->point_x1) << 12) | (0x7FF & p_command->point_y1); + + if (TRUE == p_command->colour_set) + { + /*Set the colour */ + p_instr_add[i++] = SET_COLOR | (0xFFFFFF & p_command->rgb_colour); + } + else + { + /*Set the interpolation or decimation increment values */ + p_instr_add[i++] = SET_COLOR | ((0x7 & p_command->interpol_inc_x_int) << 21) | + ((0x1FF & p_command->interpol_inc_x_dec) << 12) | ((0x7 & p_command->interpol_inc_y_int) << 9) | + (0x1FF & p_command->interpol_inc_y_dec); + } + + if (TRUE == p_command->set_bypass_zs) + { + /*Set Z and S component of the colour used to draw when pixel operator is in */ + /*by pass mode */ + p_instr_add[i++] = SET_BYPASS_ZS | ((0xFFFF & p_command->z_colour) << 8) | (0xFF & p_command->s_colour); + } + + /*set the Draw Triangle command */ + p_instr_add[i++] = DRAW_RECTANGLE; + break; + + case SGA_GRAPHIC_LINE_SHIFT: + if (TRUE == p_command->colour_set) + { + /*Set the colour */ + p_instr_add[i++] = SET_COLOR | (0xFFFFFF & p_command->rgb_colour); + } + else + { + /*Set the interpolation or decimation increment values */ + p_instr_add[i++] = SET_COLOR | ((0x7 & p_command->interpol_inc_x_int) << 21) | + ((0x1FF & p_command->interpol_inc_x_dec) << 12) | ((0x7 & p_command->interpol_inc_y_int) << 9) | + (0x1FF & p_command->interpol_inc_y_dec); + } + + /*set the line stippling factor */ + p_instr_add[i++] = LINE_STIPPLING | ((0xFF & p_command->stippling_factor) << 16) | (0xFFFF & p_command->stippling_mask); + + if (TRUE == p_command->set_bypass_zs) + { + /*Set Z and S component of the colour used to draw when pixel operator is in */ + /*by pass mode */ + p_instr_add[i++] = SET_BYPASS_ZS | ((0xFFFF & p_command->z_colour) << 8) | (0xFF & p_command->s_colour); + } + + /*Set the DrawLineShift command */ + p_instr_add[i++] = DRAW_LINE_SHIFT | ((0x7FF & p_command->point_x0) << 12) | (0x7FF & p_command->point_y0); + break; + + case SGA_GRAPHIC_TRIANGLE_SHIFT: + if (TRUE == p_command->colour_set) + { + /*Set the colour */ + p_instr_add[i++] = SET_COLOR | (0xFFFFFF & p_command->rgb_colour); + } + else + { + /*Set the interpolation or decimation increment values */ + p_instr_add[i++] = SET_COLOR | ((0x7 & p_command->interpol_inc_x_int) << 21) | + ((0x1FF & p_command->interpol_inc_x_dec) << 12) | ((0x7 & p_command->interpol_inc_y_int) << 9) | + (0x1FF & p_command->interpol_inc_y_dec); + } + + if (TRUE == p_command->set_bypass_zs) + { + /*Set Z and S component of the colour used to draw when pixel operator is in */ + /*by pass mode */ + p_instr_add[i++] = SET_BYPASS_ZS | ((0xFFFF & p_command->z_colour) << 8) | (0xFF & p_command->s_colour); + } + + /*Set the DrawLineShift command */ + p_instr_add[i++] = DRAW_TRIANGLE_SHIFT | ((0x7FF & p_command->point_x0) << 12) | (0x7FF & p_command->point_y0); + break; + + default: + break; + } + + /*Number of commands inserted at memory location */ + *p_no_cmd = i; + + DBGEXIT0(SGA_OK); + return(SGA_OK); +} + +/****************************************************************************/ +/* NAME : SGA_BuildTransparencyFirmware() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION :This routine is used to build the firmware for Transparency*/ +/* configuration instructions */ +/* PARAMETERS : */ +/* IN :t_sga_transp_config* p_transp:contain the transparency */ +/* configuration. */ +/* InOut :None */ +/* OUT :t_uint32* p_no_cmd:contain the number of commands inserted */ +/* at the memory location */ +/* t_uint32* p_instr_add:Memory location to write the build */ +/* firmware */ +/* RETURN :t_sga_error : SGA error code */ +/* SGA_OK : if it is ok */ +/* SGA_INVALID_PARAMETER if input parameter is invalid */ +/*--------------------------------------------------------------------------*/ +/* Type : PUBLIC */ +/* REENTRANCY : Non Re-entrant */ +/* REENTRANCY ISSUES : */ +/****************************************************************************/ +PUBLIC t_sga_error SGA_BuildTransparencyFirmware +( + IN t_sga_transp_config *p_transp, + OUT t_uint32 *p_instr_add, + OUT t_uint32 *p_no_cmd +) +{ + t_uint32 i = 0; + + DBGENTER0(); + + if ((NULL == p_instr_add) || (NULL == p_no_cmd) || (NULL == p_transp)) + { + DBGEXIT0(SGA_INVALID_PARAMETER); + return(SGA_INVALID_PARAMETER); + } + + p_instr_add[i++] = TRANSP_COLORMSB | ((0xFF & (p_transp->in_transp_colour >> 24)) << 8) | (0xFF & (p_transp->out_transp_colour >> 24)); + p_instr_add[i++] = TRANSP_IN_COLOR | (0xFFFFFF & p_transp->in_transp_colour); + p_instr_add[i++] = TRANSP_OUT_COLOR | (0xFFFFFF & p_transp->out_transp_colour); + + /* transparency mode */ +#if (__STN_8815 == 10) + p_instr_add[i++] = TRANSP_MODE | ((((t_uint32) p_transp->video_mode) & 0x1) << 6) | + ((((t_uint32) p_transp->active_on_input) & 0x1) << 5) | ((0x3 & ((t_uint32) p_transp->transp_in_mode)) << 3) | + ((((t_uint32) p_transp->active_on_output) & 0x1) << 2) | (0x3 & ((t_uint32) p_transp->transp_out_mode)); + +#else /*8815 CutB0 chip */ + p_instr_add[i++] = TRANSP_MODE | ((((t_uint32) p_transp->transp_active_in2) & 0x1) << 9) \ + | ((((t_uint32) p_transp->transp_active_in1) & 0x1) << 8) \ + | ((((t_uint32) p_transp->transp_active_in0) & 0x1) << 7) \ + | ((((t_uint32) p_transp->video_mode) & 0x1) << 6)\ + | ((((t_uint32) p_transp->active_on_input) & 0x1) << 5)\ + | ((0x3 & ((t_uint32) p_transp->transp_in_mode)) << 3)\ + | ((((t_uint32) p_transp->active_on_output) & 0x1) << 2)\ + | (0x3 & ((t_uint32) p_transp->transp_out_mode)); + + +#endif + + /*number of commands inserted at memory location */ + *p_no_cmd = i; + DBGEXIT0(SGA_OK); + return(SGA_OK); +} + +/****************************************************************************/ +/* NAME : SGA_BuildFlashFirmware() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION :This routine is used to build the firmware for Flash */ +/* configuration instructions */ +/* PARAMETERS : */ +/* IN :t_sga_flash_config* p_flash :contain the flash */ +/* configuration. */ +/* InOut :None */ +/* OUT :t_uint32* p_no_cmd:contain the number of commands inserted */ +/* at the memory location */ +/* t_uint32* p_instr_add:Memory location to write the build */ +/* firmware */ +/* RETURN :t_sga_error : SGA error code */ +/* SGA_OK : if it is ok */ +/* SGA_INVALID_PARAMETER if input parameter is invalid */ +/*--------------------------------------------------------------------------*/ +/* Type : PUBLIC */ +/* REENTRANCY : Non Re-entrant */ +/* REENTRANCY ISSUES : */ +/****************************************************************************/ +PUBLIC t_sga_error SGA_BuildFlashFirmware +( + IN t_sga_flash_config *p_flash, + OUT t_uint32 *p_instr_add, + OUT t_uint32 *p_no_cmd +) +{ + t_uint32 i = 0; + + DBGENTER0(); + + /*check validity of input parameters */ + if ((NULL == p_instr_add) || (NULL == p_no_cmd) || (NULL == p_flash)) + { + DBGEXIT0(SGA_INVALID_PARAMETER); + return(SGA_INVALID_PARAMETER); + } + + p_instr_add[i++] = FLASH_COLOR_MSB | ((0xFF & (p_flash->flash_id_colour >> 24)) << 8) | (0xFF & (p_flash->flash_new_colour >> 24)); + p_instr_add[i++] = FLASH_COLOR_ID | (0xFFFFFF & p_flash->flash_id_colour); + p_instr_add[i++] = FLASH_COLOR_NEW | (0xFFFFFF & p_flash->flash_new_colour); + + /*set the Flash mode command */ +#if (__STN_8815 == 10) + p_instr_add[i++] = FLASH_MODE | ((((t_uint32) p_flash->flash_mode) & 0x1) << 1) | (((t_uint32) p_flash->flash_active) & 0x1); + +#else /*8815 CutB0 chip */ + p_instr_add[i++] = FLASH_MODE | ((((t_uint32) p_flash->flash_active_in2) & 0x1) << 4)\ + | ((((t_uint32) p_flash->flash_active_in1) & 0x1) << 3)\ + | ((((t_uint32) p_flash->flash_active_in0) & 0x1) << 2)\ + | ((((t_uint32) p_flash->flash_mode) & 0x1) << 1)\ + | (((t_uint32) p_flash->flash_active) & 0x1); + +#endif + /*number of commands inserted at given memory location */ + *p_no_cmd = i; + + DBGEXIT0(SGA_OK); + return(SGA_OK); +} + +/****************************************************************************/ +/* NAME : SGA_BuildXYWCoeffFirmware() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION :This routine is used to build the firmware for */ +/* XYW cofficients instructions used in the resize and */ +/* rotate operations. */ +/* PARAMETERS : */ +/* IN :t_sga_xyw_coefficient* p_xyw_coeff:contain the XYW */ +/* coefficients configuration details */ +/* InOut :None */ +/* OUT :t_uint32* p_no_cmd:contain the number of commands inserted */ +/* at the memory location */ +/* t_uint32* p_instr_add:Memory location to write the build */ +/* firmware */ +/* RETURN :t_sga_error : SGA error code */ +/* SGA_OK : if it is ok */ +/* SGA_INVALID_PARAMETER if input parameter is invalid */ +/*--------------------------------------------------------------------------*/ +/* Type : PUBLIC */ +/* REENTRANCY : Non Re-entrant */ +/* REENTRANCY ISSUES : */ +/****************************************************************************/ +PUBLIC t_sga_error SGA_BuildXYWCoeffFirmware +( + IN t_sga_xyw_coefficient *p_xyw_coeff, + OUT t_uint32 *p_instr_add, + OUT t_uint32 *p_no_cmd +) +{ + t_uint32 i = 0; + + DBGENTER0(); + + /* Check the validity of input parameters */ + if ((NULL == p_instr_add) || (NULL == p_no_cmd) || (NULL == p_xyw_coeff)) + { + DBGEXIT0(SGA_INVALID_PARAMETER); + return(SGA_INVALID_PARAMETER); + } + + switch (p_xyw_coeff->dyn_coeff) + { + case SGA_XY_DYN_COEF_NORMAL: + /*build the SetXxCoef command */ + p_instr_add[i++] = SET_XX_COEF |((((t_uint32)p_xyw_coeff->source) & 0x1) << 23) |((0x1F & p_xyw_coeff->xx_int_coef) << 12) | (0xFFE & p_xyw_coeff->xx_dec_coef); + + /*build the SetXycoef command */ + p_instr_add[i++] = SET_XY_COEF |((((t_uint32)p_xyw_coeff->source) & 0x1) << 23) | ((0x1F & p_xyw_coeff->xy_int_coef) << 12) | (0xFFE & p_xyw_coeff->xy_dec_coef); + + /*build the SetYxCoef command */ + p_instr_add[i++] = SET_YX_COEF |((((t_uint32)p_xyw_coeff->source) & 0x1) << 23) | ((0x1F & p_xyw_coeff->yx_int_coef) << 12) | (0xFFE & p_xyw_coeff->yx_dec_coef); + + /* build the SetYycoef command */ + p_instr_add[i++] = SET_YY_COEF |((((t_uint32)p_xyw_coeff->source) & 0x1) << 23) | ((0x1F & p_xyw_coeff->yy_int_coef) << 12) | (0xFFE & p_xyw_coeff->yy_dec_coef); + break; + + case SGA_XY_DYN_COEF_X_4: + /*build the SetXxCoef command */ + p_instr_add[i++] = SET_XX_COEF |((((t_uint32)p_xyw_coeff->source) & 0x1) << 23) | ((0x7F & p_xyw_coeff->xx_int_coef) << 10) | (0x3FE & p_xyw_coeff->xx_dec_coef); + + /*build the SetXycoef command */ + p_instr_add[i++] = SET_XY_COEF |((((t_uint32)p_xyw_coeff->source) & 0x1) << 23) | ((0x7F & p_xyw_coeff->xy_int_coef) << 10) | (0x3FE & p_xyw_coeff->xy_dec_coef); + + /*build the SetYxCoef command */ + p_instr_add[i++] = SET_YX_COEF |((((t_uint32)p_xyw_coeff->source) & 0x1) << 23) | ((0x7F & p_xyw_coeff->yx_int_coef) << 10) | (0x3FE & p_xyw_coeff->yx_dec_coef); + + /* build the SetYycoef command */ + p_instr_add[i++] = SET_YY_COEF |((((t_uint32)p_xyw_coeff->source) & 0x1) << 23) | ((0x7F & p_xyw_coeff->yy_int_coef) << 10) | (0x3FE & p_xyw_coeff->yy_dec_coef); + break; + + case SGA_XY_DYN_COEF_X_16: + /*build the SetXxCoef command */ + p_instr_add[i++] = SET_XX_COEF |((((t_uint32)p_xyw_coeff->source) & 0x1) << 23) | ((0x1FF & p_xyw_coeff->xx_int_coef) << 8) | (0xFE & p_xyw_coeff->xx_dec_coef); + + /*build the SetXycoef command */ + p_instr_add[i++] = SET_XY_COEF |((((t_uint32)p_xyw_coeff->source) & 0x1) << 23) | ((0x1FF & p_xyw_coeff->xy_int_coef) << 8) | (0xFE & p_xyw_coeff->xy_dec_coef); + + /*build the SetYxCoef command */ + p_instr_add[i++] = SET_YX_COEF |((((t_uint32)p_xyw_coeff->source) & 0x1) << 23) | ((0x1FF & p_xyw_coeff->yx_int_coef) << 8) | (0xFE & p_xyw_coeff->yx_dec_coef); + + /* build the SetYycoef command */ + p_instr_add[i++] = SET_YY_COEF |((((t_uint32)p_xyw_coeff->source) & 0x1) << 23) | ((0x1FF & p_xyw_coeff->yy_int_coef) << 8) | (0xFE & p_xyw_coeff->yy_dec_coef); + break; + + case SGA_XY_DYN_COEF_X_64: + /*build the SetXxCoef command */ + p_instr_add[i++] = SET_XX_COEF |((((t_uint32)p_xyw_coeff->source) & 0x1) << 23) | ((0x7FF & p_xyw_coeff->xx_int_coef) << 6) | (0x3E & p_xyw_coeff->xx_dec_coef); + + /*build the SetXycoef command */ + p_instr_add[i++] = SET_XY_COEF |((((t_uint32)p_xyw_coeff->source) & 0x1) << 23) | ((0x7FF & p_xyw_coeff->xy_int_coef) << 6) | (0x3E & p_xyw_coeff->xy_dec_coef); + + /*build the SetYxCoef command */ + p_instr_add[i++] = SET_YX_COEF |((((t_uint32)p_xyw_coeff->source) & 0x1) << 23) | ((0x7FF & p_xyw_coeff->yx_int_coef) << 6) | (0x3E & p_xyw_coeff->yx_dec_coef); + + /* build the SetYycoef command */ + p_instr_add[i++] = SET_YY_COEF |((((t_uint32)p_xyw_coeff->source) & 0x1) << 23) | ((0x7FF & p_xyw_coeff->yy_int_coef) << 6) | (0x3E & p_xyw_coeff->yy_dec_coef); + break; + + default: + break; + } + + /*build SetXoffset command */ + p_instr_add[i++] = SET_X_OFFSET |((((t_uint32)p_xyw_coeff->source) & 0x1) << 23) | ((0xFFFF & p_xyw_coeff->x_int_offset) << 2) | (0x3 & p_xyw_coeff->x_dec_offset); + + /*build SetYoffset command */ + p_instr_add[i++] = SET_Y_OFFSET |((((t_uint32)p_xyw_coeff->source) & 0x1) << 23) | ((0xFFFF & p_xyw_coeff->y_int_offset) << 2) | (0x3 & p_xyw_coeff->y_dec_offset); + + if (TRUE == p_xyw_coeff->active_corrected_mode) + { + switch (p_xyw_coeff->dyn_coeff) + { + case SGA_XY_DYN_COEF_NORMAL: + /*build the SetWxCoef command */ + p_instr_add[i++] = SET_WX_COEF |((((t_uint32)p_xyw_coeff->source) & 0x1) << 23) | ((0x1F & p_xyw_coeff->wx_int_coef) << 12) | (0xFFE & p_xyw_coeff->wx_dec_coef); + + /* build the SetWyCoef command */ + p_instr_add[i++] = SET_WY_COEF |((((t_uint32)p_xyw_coeff->source) & 0x1) << 23) | ((0x1F & p_xyw_coeff->wy_int_coef) << 12) | (0xFFE & p_xyw_coeff->wy_dec_coef); + break; + + case SGA_XY_DYN_COEF_X_4: + /*build the SetWxCoef command */ + p_instr_add[i++] = SET_WX_COEF |((((t_uint32)p_xyw_coeff->source) & 0x1) << 23) | ((0x7F & p_xyw_coeff->wx_int_coef) << 10) | (0x3FE & p_xyw_coeff->wx_dec_coef); + + /* build the SetWyCoef command */ + p_instr_add[i++] = SET_WY_COEF |((((t_uint32)p_xyw_coeff->source) & 0x1) << 23) | ((0x7F & p_xyw_coeff->wy_int_coef) << 10) | (0x3FE & p_xyw_coeff->wy_dec_coef); + break; + + case SGA_XY_DYN_COEF_X_16: + /*build the SetWxCoef command */ + p_instr_add[i++] = SET_WX_COEF |((((t_uint32)p_xyw_coeff->source) & 0x1) << 23) | ((0x1FF & p_xyw_coeff->wx_int_coef) << 8) | (0xFE & p_xyw_coeff->wx_dec_coef); + + /* build the SetWyCoef command */ + p_instr_add[i++] = SET_WY_COEF |((((t_uint32)p_xyw_coeff->source) & 0x1) << 23) | ((0x1FF & p_xyw_coeff->wy_int_coef) << 8) | (0xFE & p_xyw_coeff->wy_dec_coef); + break; + + case SGA_XY_DYN_COEF_X_64: + /*build the SetWxCoef command */ + p_instr_add[i++] = SET_WX_COEF |((((t_uint32)p_xyw_coeff->source) & 0x1) << 23) | ((0x7FF & p_xyw_coeff->wx_int_coef) << 6) | (0x3E & p_xyw_coeff->wx_dec_coef); + + /* build the SetWyCoef command */ + p_instr_add[i++] = SET_WY_COEF |((((t_uint32)p_xyw_coeff->source) & 0x1) << 23) | ((0x7FF & p_xyw_coeff->wy_int_coef) << 6) | (0x3E & p_xyw_coeff->wy_dec_coef); + break; + + default: + break; + } + + /*build SetWoffset command */ + p_instr_add[i++] = SET_W_OFFSET |((((t_uint32)p_xyw_coeff->source) & 0x1) << 23) | ((0xFFFF & p_xyw_coeff->w_int_offset) << 2) | (0x3 & p_xyw_coeff->w_dec_offset); + } + + /*build XY Dyn command */ + p_instr_add[i++] = SET_XY_DYN |((((t_uint32)p_xyw_coeff->source) & 0x1) << 23) | (0x3 & ((t_uint32) p_xyw_coeff->dyn_coeff)); + + /*number of commands inserted at memory locations*/ + *p_no_cmd = i; + + DBGEXIT0(SGA_OK); + return(SGA_OK); +} + +/****************************************************************************/ +/* NAME : SGA_BuildXYModeFirmware() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION :This routine is used to build the firmware for */ +/* XYMode(XY Rotation/Resize) configuration instruction */ +/* PARAMETERS : */ +/* IN :t_sga_rotate_resize_config* p_config:contain the */ +/* XY rotation configuration */ +/* InOut :None */ +/* OUT :t_uint32* p_no_cmd:contain the number of commands inserted */ +/* at the memory location */ +/* t_uint32* p_instr_add:Memory location to write the build */ +/* firmware */ +/* RETURN :t_sga_error : SGA error code */ +/* SGA_OK : if it is ok */ +/* SGA_INVALID_PARAMETER if input parameter is invalid */ +/*--------------------------------------------------------------------------*/ +/* Type : PUBLIC */ +/* REENTRANCY : Non Re-entrant */ +/* REENTRANCY ISSUES : */ +/****************************************************************************/ +PUBLIC t_sga_error SGA_BuildXYModeFirmware +( + IN t_sga_rotate_resize_config *p_config, + OUT t_uint32 *p_instr_add, + OUT t_uint32 *p_no_cmd +) +{ + DBGENTER0(); + + /*Check the validity of the input parameters */ + if ((NULL == p_instr_add) || (NULL == p_no_cmd) || (NULL == p_config)) + { + DBGEXIT0(SGA_INVALID_PARAMETER); + return(SGA_INVALID_PARAMETER); + } + + /*build the XYMode command */ + *p_instr_add = SET_XY_MODE | ((((t_uint32) p_config->source) & 0x1) << 23) | + ((((t_uint32) p_config->active_corrected_mode) & 0x1) << 13) | ((0xF & ((t_uint32) p_config->x_modulo_size)) << 9) | + ((0x3 & ((t_uint32) p_config->x_clip)) << 7) | ((0xF & ((t_uint32) p_config->y_modulo_size)) << 3) | + ((0x3 & ((t_uint32) p_config->y_clip)) << 1) | (((t_uint32) p_config->active_rotate) & 0x1); + + /*number of commands inserted at given memory location */ + *p_no_cmd = 1; + + DBGEXIT0(SGA_OK); + return(SGA_OK); +} + +/****************************************************************************/ +/* NAME : SGA_BuildOpModeFirmware() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION :This routine is used to build the firmware for */ +/* OpMode configuration instruction */ +/* PARAMETERS : */ +/* IN :t_sga_pixel_opmode_config* p_config: contain the OpMode */ +/* configuration */ +/* InOut :None */ +/* OUT :t_uint32* p_no_cmd:contain the number of commands inserted */ +/* at the memory location */ +/* t_uint32* p_instr_add:Memory location to write the build */ +/* firmware */ +/* RETURN :t_sga_error : SGA error code */ +/* SGA_OK : if it is ok */ +/* SGA_INVALID_PARAMETER if input parameter is invalid */ +/*--------------------------------------------------------------------------*/ +/* Type : PUBLIC */ +/* REENTRANCY : Non Re-entrant */ +/* REENTRANCY ISSUES : */ +/****************************************************************************/ +PUBLIC t_sga_error SGA_BuildOpModeFirmware +( + IN t_sga_pixel_opmode_config *p_config, + OUT t_uint32 *p_instr_add, + OUT t_uint32 *p_no_cmd +) +{ + DBGENTER0(); + + /*Check the validity of the input parameters */ + if ((NULL == p_instr_add) || (NULL == p_no_cmd) || (NULL == p_config)) + { + DBGEXIT0(SGA_INVALID_PARAMETER); + return(SGA_INVALID_PARAMETER); + } + + /*build the OpMode Firmware */ +#if (__STN_8815 == 10) + *p_instr_add = PIXEL_OP_MODE | ((((t_uint32) p_config->mode) & 0x1) << 18) | ((((t_uint32) p_config->freeze_index_cnt) & 0x1) << 17) | + ((((t_uint32) p_config->stop_concatenate) & 0x1) << 16) | ((((t_uint32) p_config->mask_z_bits) & 0x1) << 15) | + ((((t_uint32) p_config->mask_s1_bits) & 0x1) << 14) | ((((t_uint32) p_config->mask_s0_bits) & 0x1) << 13) | + ((((t_uint32) p_config->mask_a_bits) & 0x1) << 12) | ((((t_uint32) p_config->mask_r_bits) & 0x1) << 11) | + ((((t_uint32) p_config->mask_g_bits) & 0x1) << 10) | ((((t_uint32) p_config->mask_b_bits) & 0x1) << 9) | + ((((t_uint32) p_config->dithering_mode) & 0x3) << 7) | ((((t_uint32) p_config->rop_blend) & 0x1) << 6) | + ((0xF & ((t_uint32) p_config->rop_type)) << 2) | + ((((t_uint32) p_config->active_scissor) & 0x1) << 1) | (((t_uint32) p_config->active_tribreak) & 0x1); +#else + *p_instr_add = PIXEL_OP_MODE | ((((t_uint32) p_config->precision) & 0x3) << 19) | ((((t_uint32) p_config->mode) & 0x1) << 18) | ((((t_uint32) p_config->freeze_index_cnt) & 0x1) << 17) | + ((((t_uint32) p_config->stop_concatenate) & 0x1) << 16) | ((((t_uint32) p_config->mask_z_bits) & 0x1) << 15) | + ((((t_uint32) p_config->mask_s1_bits) & 0x1) << 14) | ((((t_uint32) p_config->mask_s0_bits) & 0x1) << 13) | + ((((t_uint32) p_config->mask_a_bits) & 0x1) << 12) | ((((t_uint32) p_config->mask_r_bits) & 0x1) << 11) | + ((((t_uint32) p_config->mask_g_bits) & 0x1) << 10) | ((((t_uint32) p_config->mask_b_bits) & 0x1) << 9) | + ((((t_uint32) p_config->dithering_mode) & 0x3) << 7) | ((((t_uint32) p_config->rop_blend) & 0x1) << 6) | + ((0xF & ((t_uint32) p_config->rop_type)) << 2) | + ((((t_uint32) p_config->active_scissor) & 0x1) << 1) | (((t_uint32) p_config->active_tribreak) & 0x1); +#endif + + /*Number of commands inserted at memory location */ + *p_no_cmd = 1; + + DBGEXIT0(SGA_OK); + return(SGA_OK); +} + +/****************************************************************************/ +/* NAME : SGA_BuildDepthInstrFirmware() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION :This routine is used to build the firmware for */ +/* Depth configuration instruction */ +/* PARAMETERS : */ +/* IN :t_sga_z_coefficient* p_z_coef: contain the Depth */ +/* configuration details */ +/* InOut :None */ +/* OUT :t_uint32* p_no_cmd:contain the number of commands inserted */ +/* at the memory location */ +/* t_uint32* p_instr_add:Memory location to write the build */ +/* firmware */ +/* RETURN :t_sga_error : SGA error code */ +/* SGA_OK : if it is ok */ +/* SGA_INVALID_PARAMETER if input parameter is invalid */ +/*--------------------------------------------------------------------------*/ +/* Type : PUBLIC */ +/* REENTRANCY : Non Re-entrant */ +/* REENTRANCY ISSUES : */ +/****************************************************************************/ +PUBLIC t_sga_error SGA_BuildDepthInstrFirmware +( + IN t_sga_z_coef_config *p_z_coef, + OUT t_uint32 *p_instr_add, + OUT t_uint32 *p_no_cmd +) +{ + t_uint32 i = 0; + DBGENTER0(); + + /*Check the validity of the input parameters */ + if ((NULL == p_instr_add) || (NULL == p_no_cmd) || (NULL == p_z_coef)) + { + DBGEXIT0(SGA_INVALID_PARAMETER); + return(SGA_INVALID_PARAMETER); + } + + switch (p_z_coef->z_dyn) + { + case SGA_Z_DYN_COEF_NORMAL: + /*Build the Zx Coefficient */ + p_instr_add[i++] = SET_ZX_COEF | ((0xFF & p_z_coef->zx_int_coeff) << 12) | (0xFFE & p_z_coef->zx_dec_coeff); + + /*Build the Zy Coefficient */ + p_instr_add[i++] = SET_ZY_COEF | ((0xFF & p_z_coef->zy_int_coeff) << 12) | (0xFFE & p_z_coef->zy_dec_coeff); + break; + + case SGA_Z_DYN_COEF_X_8: + /*Build the Zx Coefficient */ + p_instr_add[i++] = SET_ZX_COEF | ((0x7FF & p_z_coef->zx_int_coeff) << 9) | (0x1FE & p_z_coef->zx_dec_coeff); + + /*Build the Zy Coefficient */ + p_instr_add[i++] = SET_ZY_COEF | ((0x7FF & p_z_coef->zy_int_coeff) << 9) | (0x1FE & p_z_coef->zy_dec_coeff); + break; + + case SGA_Z_DYN_COEF_X_64: + /*Build the Zx Coefficient */ + p_instr_add[i++] = SET_ZX_COEF | ((0x3FFF & p_z_coef->zx_int_coeff) << 6) | (0x3E & p_z_coef->zx_dec_coeff); + + /*Build the Zy Coefficient */ + p_instr_add[i++] = SET_ZY_COEF | ((0x3FFF & p_z_coef->zy_int_coeff) << 6) | (0x3E & p_z_coef->zy_dec_coeff); + break; + + case SGA_Z_DYN_COEF_X_512: + /*Build the Zx Coefficient */ + p_instr_add[i++] = SET_ZX_COEF | ((0x1FFFF & p_z_coef->zx_int_coeff) << 3) | (0x6 & p_z_coef->zx_dec_coeff); + + /*Build the Zy Coefficient */ + p_instr_add[i++] = SET_ZY_COEF | ((0x1FFFF & p_z_coef->zy_int_coeff) << 3) | (0x6 & p_z_coef->zy_dec_coeff); + break; + + default: + break; + } + + p_instr_add[i++] = SET_Z_OFFSET | (0x3FFFF & p_z_coef->z_offset); + + p_instr_add[i++] = SET_Z_DYN | (0x3 & ((t_uint32) p_z_coef->z_dyn)); + + /*number of commands inserted at given memory location */ + *p_no_cmd = i; + + DBGEXIT0(SGA_OK); + return(SGA_OK); +} + +/****************************************************************************/ +/* NAME : SGA_BuildGouraudCoeffFirmware() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION :This routine is used to build the firmware for */ +/* Gouraud shading Cofficients instruction */ +/* PARAMETERS : */ +/* IN :t_sga_gourad_coeff_config* p_config : contain the Gouraud */ +/* coefficients details */ +/* InOut :None */ +/* OUT :t_uint32* p_no_cmd:contain the number of commands inserted */ +/* at the memory location */ +/* t_uint32* p_instr_add:Memory location to write the build */ +/* firmware */ +/* RETURN :t_sga_error : SGA error code */ +/* SGA_OK : if it is ok */ +/* SGA_INVALID_PARAMETER if input parameter is invalid */ +/*--------------------------------------------------------------------------*/ +/* Type : PUBLIC */ +/* REENTRANCY : Non Re-entrant */ +/* REENTRANCY ISSUES : */ +/****************************************************************************/ +PUBLIC t_sga_error SGA_BuildGouraudCoeffFirmware +( + IN t_sga_gouraud_coeff_config *p_config, + OUT t_uint32 *p_instr_add, + OUT t_uint32 *p_no_cmd +) +{ + t_uint32 i = 0; + + DBGENTER0(); + + /*Check the validity of the input parameters */ + if ((NULL == p_instr_add) || (NULL == p_no_cmd) || (NULL == p_config)) + { + DBGEXIT0(SGA_INVALID_PARAMETER); + return(SGA_INVALID_PARAMETER); + } + + switch (p_config->dyn_coef) + { + case SGA_DYN_COEF_DIV_BY_256: + /*build the firmware for SetCoeffAxAy command */ + p_instr_add[i++] = SET_COEF_AXAY | ((0xF & p_config->ax_int_grad) << 20) | + ((0xFF & p_config->ax_dec_grad) << 12) | ((0xF & p_config->ay_int_grad) << 8) | + (0xFF & p_config->ay_dec_grad); + + /*build the firmware for SetCoefRxRy command */ + p_instr_add[i++] = SET_COEF_RXRY | ((0xF & p_config->rx_int_grad) << 20) | + ((0xFF & p_config->rx_dec_grad) << 12) | ((0xF & p_config->ry_int_grad) << 8) | + (0xFF & p_config->ry_dec_grad); + + /*build the firmware for SetCoefGxGy command */ + p_instr_add[i++] = SET_COEF_GXGY | ((0xF & p_config->gx_int_grad) << 20) | + ((0xFF & p_config->gx_dec_grad) << 12) | ((0xF & p_config->gy_int_grad) << 8) | + (0xFF & p_config->gy_dec_grad); + + /*build the firmware for SetCoefBxBy command */ + p_instr_add[i++] = SET_COEF_BXBY | ((0xF & p_config->bx_int_grad) << 20) | + ((0xFF & p_config->bx_dec_grad) << 12) | ((0xF & p_config->by_int_grad) << 8) | + (0xFF & p_config->by_dec_grad); + break; + + case SGA_DYN_COEF_DIV_BY_64: + /*build the firmware for SetCoeffAxAy command */ + p_instr_add[i++] = SET_COEF_AXAY | ((0x3F & p_config->ax_int_grad) << 18) | + ((0x3F & p_config->ax_dec_grad) << 12) | ((0x3F & p_config->ay_int_grad) << 6) | + (0x3F & p_config->ay_dec_grad); + + /*build the firmware for SetCoefRxRy command */ + p_instr_add[i++] = SET_COEF_RXRY | ((0x3F & p_config->rx_int_grad) << 18) | + ((0x3F & p_config->rx_dec_grad) << 12) | ((0x3F & p_config->ry_int_grad) << 6) | + (0x3F & p_config->ry_dec_grad); + + /*build the firmware for SetCoefGxGy command */ + p_instr_add[i++] = SET_COEF_GXGY | ((0x3F & p_config->gx_int_grad) << 18) | + ((0x3F & p_config->gx_dec_grad) << 12) | ((0x3F & p_config->gy_int_grad) << 6) | + (0x3F & p_config->gy_dec_grad); + + /*build the firmware for SetCoefBxBy command */ + p_instr_add[i++] = SET_COEF_BXBY | ((0x3F & p_config->bx_int_grad) << 18) | + ((0x3F & p_config->bx_dec_grad) << 12) | ((0x3F & p_config->by_int_grad) << 6) | + (0x3F & p_config->by_dec_grad); + break; + + case SGA_DYN_COEF_DIV_BY_16: + /*build the firmware for SetCoeffAxAy command */ + p_instr_add[i++] = SET_COEF_AXAY | ((0xFF & p_config->ax_int_grad) << 16) | + ((0xF & p_config->ax_dec_grad) << 12) | ((0xFF & p_config->ay_int_grad) << 4) | + (0xF & p_config->ay_dec_grad); + + /*build the firmware for SetCoefRxRy command */ + p_instr_add[i++] = SET_COEF_RXRY | ((0xFF & p_config->rx_int_grad) << 16) | + ((0xF & p_config->rx_dec_grad) << 12) | ((0xFF & p_config->ry_int_grad) << 4) | + (0xF & p_config->ry_dec_grad); + + /*build the firmware for SetCoefGxGy command */ + p_instr_add[i++] = SET_COEF_GXGY | ((0xFF & p_config->gx_int_grad) << 16) | + ((0xF & p_config->gx_dec_grad) << 12) | ((0xFF & p_config->gy_int_grad) << 4) | + (0xF & p_config->gy_dec_grad); + + /*build the firmware for SetCoefBxBy command */ + p_instr_add[i++] = SET_COEF_BXBY | ((0xFF & p_config->bx_int_grad) << 16) | + ((0xF & p_config->bx_dec_grad) << 12) | ((0xFF & p_config->by_int_grad) << 4) | + (0xF & p_config->by_dec_grad); + break; + + case SGA_DYN_COEF_DIV_BY_4: + /*build the firmware for SetCoeffAxAy command */ + p_instr_add[i++] = SET_COEF_AXAY | ((0x3FF & p_config->ax_int_grad) << 14) | + ((0x3 & p_config->ax_dec_grad) << 12) | ((0x3FF & p_config->ay_int_grad) << 2) | + (0x3 & p_config->ay_dec_grad); + + /*build the firmware for SetCoefRxRy command */ + p_instr_add[i++] = SET_COEF_RXRY | ((0x3FF & p_config->rx_int_grad) << 14) | + ((0x3 & p_config->rx_dec_grad) << 12) | ((0x3FF & p_config->ry_int_grad) << 2) | + (0x3 & p_config->ry_dec_grad); + + /*build the firmware for SetCoefGxGy command */ + p_instr_add[i++] = SET_COEF_GXGY | ((0x3FF & p_config->gx_int_grad) << 14) | + ((0x3 & p_config->gx_dec_grad) << 12) | ((0x3FF & p_config->gy_int_grad) << 2) | + (0x3 & p_config->gy_dec_grad); + + /*build the firmware for SetCoefBxBy command */ + p_instr_add[i++] = SET_COEF_BXBY | ((0x3FF & p_config->bx_int_grad) << 14) | + ((0x3 & p_config->bx_dec_grad) << 12) | ((0x3FF & p_config->by_int_grad) << 2) | + (0x3 & p_config->by_dec_grad); + break; + + default: + break; + } + + /* build the firmware for SetCoefAo command */ + p_instr_add[i++] = SET_COEF_A0 | (0xFFF & p_config->ao_offset); + + /* build the firmware for SetCoefRo command */ + p_instr_add[i++] = SET_COEF_R0 | (0xFFF & p_config->ro_offset); + + /* build the firmware for SetCoefGo command */ + p_instr_add[i++] = SET_COEF_G0 | (0xFFF & p_config->go_offset); + + /* build the firmware for SetCoefBo command */ + p_instr_add[i++] = SET_COEF_B0 | (0xFFF & p_config->bo_offset); + + /*build the firmware for the SetCoefdyn command */ + p_instr_add[i++] = SET_COEF_DYN | (((t_uint32) p_config->dyn_coef) & 3); + + /* number of commands inserted at memory location */ + *p_no_cmd = i; + + DBGEXIT0(SGA_OK); + return(SGA_OK); +} + +/****************************************************************************/ +/* NAME : SGA_BuildTextureConfigFirmware() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION :This routine is used to build the firmware for */ +/* Texture configuration instructions */ +/* PARAMETERS : */ +/* IN :t_sga_texture_config* p_config : contain the texture */ +/* cconfiguration */ +/* InOut :None */ +/* OUT :t_uint32* p_no_cmd:contain the number of commands inserted */ +/* at the memory location */ +/* t_uint32* p_instr_add:Memory location address to write the */ +/* build firmware */ +/* RETURN :t_sga_error : SGA error code */ +/* SGA_OK : if it is ok */ +/* SGA_INVALID_PARAMETER if input parameter is invalid */ +/*--------------------------------------------------------------------------*/ +/* Type : PUBLIC */ +/* REENTRANCY : Non Re-entrant */ +/* REENTRANCY ISSUES : */ +/****************************************************************************/ +PUBLIC t_sga_error SGA_BuildTextureConfigFirmware +( + IN t_sga_texture_config *p_config, + OUT t_uint32 *p_instr_add, + OUT t_uint32 *p_no_cmd +) +{ + DBGENTER0(); + + /*Check the validity of the input parameters */ + if ((NULL == p_instr_add) || (NULL == p_no_cmd) || (NULL == p_config)) + { + DBGEXIT0(SGA_INVALID_PARAMETER); + return(SGA_INVALID_PARAMETER); + } + + *p_instr_add++ = SET_TEX_COLORMSB | ((((t_uint32) p_config->tex_id) & 0x1) << 23) | (p_config->argb_colour >> 16); + + *p_instr_add++ = SET_TEX_COLORLSB | ((((t_uint32) p_config->tex_id) & 0x1) << 23) | (0xFFFF & p_config->argb_colour); + + *p_instr_add++ = SET_TEX_ENV_MSB | ((((t_uint32) p_config->tex_id) & 0x1) << 23) | ((((t_uint32) p_config->rgb_fct) & 0x7) << 15) | + ((((t_uint32) p_config->a_fct) & 0x7) << 12) | ((((t_uint32) p_config->source_0_rgb) & 0x3) << 10) | + ((((t_uint32) p_config->source_1_rgb) & 0x3) << 8) | ((((t_uint32) p_config->source_2_rgb) & 0x3) << 6) | + ((((t_uint32) p_config->source_0_a) & 0x3) << 4) | ((((t_uint32) p_config->source_1_a) & 0x3) << 2) | + (((t_uint32) p_config->source_2_a) & 0x3); + + *p_instr_add++ = SET_TEX_ENN_LSB | ((((t_uint32) p_config->tex_id) & 0x1) << 23) | + ((((t_uint32) p_config->operand_0_rgb) & 0x3) << 7) | ((((t_uint32) p_config->operand_1_rgb) & 0x3) << 5) | + ((((t_uint32) p_config->operand_2_rgb) & 0x3) << 3) | ((((t_uint32) p_config->operand_0_a) & 0x1) << 2) | + ((((t_uint32) p_config->operand_1_a) & 0x1) << 1) | (((t_uint32) p_config->operand_2_a) & 0x1); + + *p_instr_add++ = SET_TEX_SCALE | ((((t_uint32) p_config->tex_id) & 0x1) << 23) | (p_config->rgb_scale << 8) | (p_config->a_scale); + + /*number of commands inserted at given memory location */ + *p_no_cmd = 5; + + DBGEXIT0(SGA_OK); + return(SGA_OK); +} + +/****************************************************************************/ +/* NAME : SGA_BuildFogConfigFirmware() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION :This routine is used to build the firmware for */ +/* Fog configuration instructions */ +/* PARAMETERS : */ +/* IN :t_sga_fog_config* p_fog: contain the Fog configuration */ +/* InOut :None */ +/* OUT :t_uint32* p_no_cmd:contain the number of commands inserted */ +/* at the memory location */ +/* t_uint32* p_instr_add:Memory location address to write the */ +/* build firmware */ +/* RETURN :t_sga_error : SGA error code */ +/* SGA_OK : if it is ok */ +/* SGA_INVALID_PARAMETER if input parameter is invalid */ +/*--------------------------------------------------------------------------*/ +/* Type : PUBLIC */ +/* REENTRANCY : Non Re-entrant */ +/* REENTRANCY ISSUES : */ +/****************************************************************************/ +PUBLIC t_sga_error SGA_BuildFogConfigFirmware +( + IN t_sga_fog_config *p_fog, + OUT t_uint32 *p_instr_add, + OUT t_uint32 *p_no_cmd +) +{ + DBGENTER0(); + + /*Check the validity of the input parameter*/ + if ((NULL == p_fog) || (NULL == p_instr_add) || (NULL == p_no_cmd)) + { + DBGEXIT0(SGA_INVALID_PARAMETER); + return(SGA_INVALID_PARAMETER); + } + + switch (p_fog->coef_type) + { + case SGA_DYN_COEF_DIV_BY_256: + *p_instr_add++ = SET_COEF_FXFY | ((0xF & p_fog->fx_grad_int) << 20) | ((0xFF & p_fog->fx_grad_dec) << 12) | ((0xF & p_fog->fy_grad_int) << 8) | (0xFF & p_fog->fy_grad_dec); + + break; + + case SGA_DYN_COEF_DIV_BY_64: + *p_instr_add++ = SET_COEF_FXFY | ((0x3F & p_fog->fx_grad_int) << 18) | ((0x3F & p_fog->fx_grad_dec) << 12) | ((0x3F & p_fog->fy_grad_int) << 6) | (0x3F & p_fog->fy_grad_dec); + + break; + + case SGA_DYN_COEF_DIV_BY_16: + *p_instr_add++ = SET_COEF_FXFY | ((0xFF & p_fog->fx_grad_int) << 16) | ((0xF & p_fog->fx_grad_dec) << 12) | ((0xFF & p_fog->fy_grad_int) << 4) | (0xF & p_fog->fy_grad_dec); + + break; + + case SGA_DYN_COEF_DIV_BY_4: + *p_instr_add++ = SET_COEF_FXFY | ((0x3FF & p_fog->fx_grad_int) << 14) | ((0x3 & p_fog->fx_grad_dec) << 12) | ((0x3FF & p_fog->fy_grad_int) << 2) | (0x3 & p_fog->fy_grad_dec); + + break; + + default: + break; + } + + /*build the SetCoefFo command */ + *p_instr_add++ = SET_COEF_F0 | (0xFFF & p_fog->fo_offset); + + /*build the SetColorF command */ + *p_instr_add++ = SET_COLOR_F0 | (0xFFFFFF & p_fog->rgb_fog); + + /*build the SetCoefDyn command */ + *p_instr_add++ = SET_COEF_DYN | (((t_uint32) p_fog->coef_type) & 0x3); + + /*number of commands inserted at memory location */ + *p_no_cmd = 4; + + DBGEXIT0(SGA_OK); + return(SGA_OK); +} + +/****************************************************************************/ +/* NAME : SGA_BuildFrameBlendFirmware() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION :This routine is used to build the firmware for */ +/* Frame blend configuration instructions */ +/* PARAMETERS : */ +/* IN :t_sga_blend_config* p_blend: contain the Frame blend */ +/* configuration */ +/* InOut :None */ +/* OUT :t_uint32* p_no_cmd:contain the number of commands inserted */ +/* at the memory location */ +/* t_uint32* p_instr_add:Memory location address to write the */ +/* build firmware */ +/* RETURN :t_sga_error : SGA error code */ +/* SGA_OK : if it is ok */ +/* SGA_INVALID_PARAMETER if input parameter is invalid */ +/*--------------------------------------------------------------------------*/ +/* Type : PUBLIC */ +/* REENTRANCY : Non Re-entrant */ +/* REENTRANCY ISSUES : */ +/****************************************************************************/ +PUBLIC t_sga_error SGA_BuildFrameBlendFirmware +( + IN t_sga_blend_config *p_blend, + OUT t_uint32 *p_instr_add, + OUT t_uint32 *p_no_cmd +) +{ + DBGENTER0(); + + /*Check the validity of the input parameters */ + if ((NULL == p_instr_add) || (NULL == p_no_cmd) || (NULL == p_blend)) + { + DBGEXIT0(SGA_INVALID_PARAMETER); + return(SGA_INVALID_PARAMETER); + } + + /*build the SetBlendColorMsb command */ + *p_instr_add++ = SET_BLEND_COLORMSB | (p_blend->argb_colour >> 24); + + /*build the SetColor command */ + *p_instr_add++ = SET_COLOR | (0xFFFFFF & p_blend->argb_colour); + + /*build the SetBlendEnv command */ + *p_instr_add++ = SET_BLEND_ENV | ((0x7 & ((t_uint32) p_blend->blend_op)) << 16) | + ((((t_uint32) p_blend->rgb_fragment) & 0xF) << 12) | ((((t_uint32) p_blend->a_fragment) & 0xF) << 8) | + ((((t_uint32) p_blend->rgb_frame)& 0xF) << 4) | (((t_uint32) p_blend->a_frame) & 0xF); + + /*number of instructions inseted at given memory location */ + *p_no_cmd = 3; + + DBGEXIT0(SGA_OK); + return(SGA_OK); +} + +/****************************************************************************/ +/* NAME : SGA_BuildAlphaTestFirmware() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION :This routine is used to build the firmware for */ +/* Alpha test instruction */ +/* PARAMETERS : */ +/* IN :t_sga_alphatest_config *p_alpha: contain the Alpha test */ +/* configuration */ +/* InOut :None */ +/* OUT :t_uint32* p_no_cmd:contain the number of commands inserted */ +/* at the memory location */ +/* t_uint32* p_instr_add:Memory location address to write the */ +/* build firmware */ +/* RETURN :t_sga_error : SGA error code */ +/* SGA_OK : if it is ok */ +/* SGA_INVALID_PARAMETER if input parameter is invalid */ +/*--------------------------------------------------------------------------*/ +/* Type : PUBLIC */ +/* REENTRANCY : Non Re-entrant */ +/* REENTRANCY ISSUES : */ +/****************************************************************************/ +PUBLIC t_sga_error SGA_BuildAlphaTestFirmware +( + IN t_sga_alphatest_config *p_alpha, + OUT t_uint32 *p_instr_add, + OUT t_uint32 *p_no_cmd +) +{ + DBGENTER0(); + + if ((NULL == p_instr_add) || (NULL == p_no_cmd) || (NULL == p_alpha)) + { + DBGEXIT0(SGA_INVALID_PARAMETER); + return(SGA_INVALID_PARAMETER); + } + + *p_instr_add = SET_ALPHA_TEST | ((((t_uint32) p_alpha->enable) & 0x1) << 23) | ((((t_uint32) p_alpha->func) & 0x7) << 20) | (p_alpha->reference); + + *p_no_cmd = 1; + + DBGEXIT0(SGA_OK); + return(SGA_OK); +} + +/****************************************************************************/ +/* NAME : SGA_BuildStencilTestFirmware() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION :This routine is used to build the firmware for */ +/* Stencil test instruction */ +/* PARAMETERS : */ +/* IN :t_sga_stenciltest_config *p_stencil: contain the stencil */ +/* test configuration */ +/* InOut :None */ +/* OUT :t_uint32* p_no_cmd:contain the number of commands inserted */ +/* at the memory location */ +/* t_uint32* p_instr_add:Memory location address to write the */ +/* build firmware */ +/* RETURN :t_sga_error : SGA error code */ +/* SGA_OK : if it is ok */ +/* SGA_INVALID_PARAMETER if input parameter is invalid */ +/*--------------------------------------------------------------------------*/ +/* Type : PUBLIC */ +/* REENTRANCY : Non Re-entrant */ +/* REENTRANCY ISSUES : */ +/****************************************************************************/ +PUBLIC t_sga_error SGA_BuildStencilTestFirmware +( + IN t_sga_stenciltest_config *p_stencil, + OUT t_uint32 *p_instr_add, + OUT t_uint32 *p_no_cmd +) +{ + DBGENTER0(); + + if ((NULL == p_instr_add) || (NULL == p_no_cmd) || (NULL == p_stencil)) + { + DBGEXIT0(SGA_INVALID_PARAMETER); + return(SGA_INVALID_PARAMETER); + } + + *p_instr_add = SET_STENCIL_TEST | ((((t_uint32) p_stencil->enable) & 0x1) << 23) | ((((t_uint32) p_stencil->func) & 0x7) << 20) | + ((((t_uint32) p_stencil->stencil_dpfail) & 0x7) << 14) | ((((t_uint32) p_stencil->stencil_dppass) & 0x7) << 11) | + ( + (((t_uint32) p_stencil->stencil_sfail) & 0x7) << + 8 + ) | + ((0xF & p_stencil->mask) << 4) | + (0xF & p_stencil->reference); + + /*Number of commands inserted at memory location */ + *p_no_cmd = 1; + DBGEXIT0(SGA_OK); + return(SGA_OK); +} + +/****************************************************************************/ +/* NAME : SGA_BuildDepthTestFirmware() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION :This routine is used to build the firmware for */ +/* Depth test instruction */ +/* PARAMETERS : */ +/* IN :t_bool enable: Enable or disable the Depth test */ +/* t_sga_test_function depth_func:specifies the depth test */ +/* function */ +/* InOut :None */ +/* OUT :t_uint32* p_no_cmd:contain the number of commands inserted */ +/* at the memory location */ +/* t_uint32* p_instr_add:Memory location address to write the */ +/* build firmware */ +/* RETURN :t_sga_error : SGA error code */ +/* SGA_OK : if it is ok */ +/* SGA_INVALID_PARAMETER if input parameter is invalid */ +/*--------------------------------------------------------------------------*/ +/* Type : PUBLIC */ +/* REENTRANCY : Non Re-entrant */ +/* REENTRANCY ISSUES : */ +/****************************************************************************/ +PUBLIC t_sga_error SGA_BuildDepthTestFirmware +( + IN t_bool enable, + IN t_sga_test_function depth_func, + OUT t_uint32 *p_instr_add, + OUT t_uint32 *p_no_cmd +) +{ + DBGENTER0(); + if ((NULL == p_instr_add) || (NULL == p_no_cmd)) + { + DBGEXIT0(SGA_INVALID_PARAMETER); + return(SGA_INVALID_PARAMETER); + } + + *p_instr_add = SET_DEPTH_TEST | ((((t_uint32) enable) & 0x1) << 23) | ((((t_uint32) depth_func) & 0x3) << 20); + + /*number of commands inseted at memory location */ + *p_no_cmd = 1; + + DBGEXIT0(SGA_OK); + return(SGA_OK); +} + +/****************************************************************************/ +/* NAME : SGA_BuildBufferDeActivateFirmware() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION :This routine is used to build the firmware to */ +/* Deactivate the given input buffer */ +/* PARAMETERS : */ +/* IN :t_sga_image_buffer buffer:Specify the Buffer to be */ +/* DeActivated */ +/* InOut :None */ +/* OUT :t_uint32* p_no_cmd:contain the number of commands inserted */ +/* at the memory location */ +/* t_uint32* p_instr_add:Memory location address to write the */ +/* build firmware */ +/* RETURN :t_sga_error : SGA error code */ +/* SGA_OK : if it is ok */ +/* SGA_INVALID_PARAMETER if input parameter is invalid */ +/*--------------------------------------------------------------------------*/ +/* Type : PUBLIC */ +/* REENTRANCY : Non Re-entrant */ +/* REENTRANCY ISSUES : */ +/****************************************************************************/ +t_sga_error SGA_BuildBufferDeActivateFirmware +( + IN t_sga_image_buffer buffer, + OUT t_uint32 *p_instr_add, + OUT t_uint32 *p_no_cmd +) +{ + DBGENTER0(); + if ((NULL == p_instr_add) || (NULL == p_no_cmd) || (SGA_IMAGE_BUFFER_OUT == buffer)) + { + DBGEXIT0(SGA_INVALID_PARAMETER); + return(SGA_INVALID_PARAMETER); + } + + switch (buffer) + { + case SGA_IMAGE_BUFFER_IN0: + *p_instr_add = IN0_SET_PIXEL_TYPE; + break; + + case SGA_IMAGE_BUFFER_IN1: + *p_instr_add = IN1_SET_PIXEL_TYPE; + break; + + case SGA_IMAGE_BUFFER_IN2: + *p_instr_add = IN2_SET_PIXEL_TYPE; + break; + + default: + break; + } + + /*number of commands inseted at memory location */ + *p_no_cmd = 1; + + DBGEXIT0(SGA_OK); + return(SGA_OK); +} + +/****************************************************************************/ +/* NAME : SGA_BuildFlashDeActivateFirmware () */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION :This routine is used to build the firmware to */ +/* Deactivate the Flash */ +/* PARAMETERS : */ +/* IN :None */ +/* InOut :None */ +/* OUT :t_uint32* p_no_cmd:contain the number of commands inserted */ +/* at the memory location */ +/* t_uint32* p_instr_add:Memory location address to write the */ +/* build firmware */ +/* RETURN :t_sga_error : SGA error code */ +/* SGA_OK : if it is ok */ +/* SGA_INVALID_PARAMETER if input parameter is invalid */ +/*--------------------------------------------------------------------------*/ +/* Type : PUBLIC */ +/* REENTRANCY : Non Re-entrant */ +/* REENTRANCY ISSUES : */ +/****************************************************************************/ +t_sga_error SGA_BuildFlashDeActivateFirmware(OUT t_uint32 *p_instr_add, OUT t_uint32 *p_no_cmd) +{ + DBGENTER0(); + if ((NULL == p_instr_add) || (NULL == p_no_cmd)) + { + DBGEXIT0(SGA_INVALID_PARAMETER); + return(SGA_INVALID_PARAMETER); + } + + *p_instr_add = FLASH_MODE; + + /*number of commands inseted at memory location */ + *p_no_cmd = 1; + + DBGEXIT0(SGA_OK); + return(SGA_OK); +} + +/****************************************************************************/ +/* NAME : SGA_BuildTransparencyDeActivateFirmware() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION :This routine is used to build the firmware to */ +/* Deactivate the Transparency */ +/* PARAMETERS : */ +/* IN :t_sga_image_buffer buffer:Specify the Buffer to be */ +/* DeActivated */ +/* InOut :None */ +/* OUT :t_uint32* p_no_cmd:contain the number of commands inserted */ +/* at the memory location */ +/* t_uint32* p_instr_add:Memory location address to write the */ +/* build firmware */ +/* RETURN :t_sga_error : SGA error code */ +/* SGA_OK : if it is ok */ +/* SGA_INVALID_PARAMETER if input parameter is invalid */ +/*--------------------------------------------------------------------------*/ +/* Type : PUBLIC */ +/* REENTRANCY : Non Re-entrant */ +/* REENTRANCY ISSUES : */ +/****************************************************************************/ +PUBLIC t_sga_error SGA_BuildTransparencyDeActivateFirmware(OUT t_uint32 *p_instr_add, OUT t_uint32 *p_no_cmd) +{ + DBGENTER0(); + if ((NULL == p_instr_add) || (NULL == p_no_cmd)) + { + DBGEXIT0(SGA_INVALID_PARAMETER); + return(SGA_INVALID_PARAMETER); + } + + *p_instr_add = TRANSP_MODE; + + /*number of commands inseted at memory location */ + *p_no_cmd = 1; + + DBGEXIT0(SGA_OK); + return(SGA_OK); +} + +/****************************************************************************/ +/* NAME : SGA_BuildMainBatchFirmware() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION :This routine is used to build the main batch firmware */ +/* (SGA Batch Server ) */ +/* PARAMETERS : */ +/* IN :None */ +/* InOut :None */ +/* OUT :t_uint32* p_no_cmd:contain the number of commands inserted */ +/* at the memory location */ +/* t_uint32* p_main_add:Memory location address to write the */ +/* main firmware */ +/* t_uint32* p_default_batch_add: contain the default batch */ +/* frimware address. */ +/* RETURN :t_sga_error : SGA error code */ +/* SGA_OK : if it is ok */ +/* SGA_INVALID_PARAMETER if input parameter is invalid */ +/*--------------------------------------------------------------------------*/ +/* Type : PUBLIC */ +/* REENTRANCY : Non Re-entrant */ +/* REENTRANCY ISSUES : */ +/****************************************************************************/ +PUBLIC t_sga_error SGA_BuildMainBatchFirmware +( + OUT t_uint32 *p_phy_main_add, + OUT t_uint32 *p_logical_main_add, + OUT t_uint32 *p_phy_default_batch_add, + OUT t_uint32 *p_logical_default_batch_add, + OUT t_uint32 *p_no_cmd +) +{ + t_uint32 main_add, batch_add; + t_uint32 i = 0; + + DBGENTER0(); + /*Check the validity of the input parameters */ + if + ( + (NULL == p_phy_main_add) + || (NULL == p_no_cmd) + || (NULL == p_logical_default_batch_add) + || (((t_uint32) p_phy_main_add) & 0x7) + || (((t_uint32) p_logical_default_batch_add) & 0x7) + ) + { + DBGEXIT0(SGA_INVALID_PARAMETER); + return(SGA_INVALID_PARAMETER); + } + g_sga_system_context.p_main_batch_add = p_phy_main_add; + g_sga_system_context.p_logical_main_batch_add = p_logical_main_add; + g_sga_system_context.p_default_batch_add = p_logical_default_batch_add; + main_add = (t_uint32) p_phy_main_add; + batch_add = ((t_uint32) p_phy_default_batch_add >> 3); + + /*Main Batch firmware */ + p_logical_main_add[i++] = TST_INSTR_TEST_REG | 0; + p_logical_main_add[i++] = GOSUB | batch_add; + p_logical_main_add[i++] = TST_INSTR_TEST_REG | 1; + p_logical_main_add[i++] = GOSUB | batch_add; + p_logical_main_add[i++] = TST_INSTR_TEST_REG | 2; + p_logical_main_add[i++] = GOSUB | batch_add; + p_logical_main_add[i++] = TST_INSTR_TEST_REG | 3; + p_logical_main_add[i++] = GOSUB | batch_add; + p_logical_main_add[i++] = TST_INSTR_TEST_REG | 4; + p_logical_main_add[i++] = GOSUB | batch_add; + p_logical_main_add[i++] = TST_INSTR_TEST_REG | 5; + p_logical_main_add[i++] = GOSUB | batch_add; + p_logical_main_add[i++] = TST_INSTR_TEST_REG | 6; + p_logical_main_add[i++] = GOSUB | batch_add; + p_logical_main_add[i++] = TST_INSTR_TEST_REG | 7; + p_logical_main_add[i++] = GOSUB | batch_add; + p_logical_main_add[i++] = TST_INSTR_TEST_REG | 8; + p_logical_main_add[i++] = GOSUB | batch_add; + p_logical_main_add[i++] = TST_INSTR_TEST_REG | 9; + p_logical_main_add[i++] = GOSUB | batch_add; + p_logical_main_add[i++] = TST_INSTR_TEST_REG | 10; + p_logical_main_add[i++] = GOSUB | batch_add; + p_logical_main_add[i++] = TST_INSTR_TEST_REG | 11; + p_logical_main_add[i++] = GOSUB | batch_add; + p_logical_main_add[i++] = TST_INSTR_TEST_REG | 12; + p_logical_main_add[i++] = GOSUB | batch_add; + p_logical_main_add[i++] = TST_INSTR_TEST_REG | 13; + p_logical_main_add[i++] = GOSUB | batch_add; + p_logical_main_add[i++] = TST_INSTR_TEST_REG | 14; + p_logical_main_add[i++] = GOSUB | batch_add; + p_logical_main_add[i++] = TST_INSTR_TEST_REG | 15; + p_logical_main_add[i++] = GOSUB | batch_add; + if (MAX_BATCHES == 26) +{ + p_logical_main_add[i++] = TST_INSTR_TEST_REG | 16; + p_logical_main_add[i++] = GOSUB | batch_add; + p_logical_main_add[i++] = TST_INSTR_TEST_REG | 17; + p_logical_main_add[i++] = GOSUB | batch_add; + p_logical_main_add[i++] = TST_INSTR_TEST_REG | 18; + p_logical_main_add[i++] = GOSUB | batch_add; + p_logical_main_add[i++] = TST_INSTR_TEST_REG | 19; + p_logical_main_add[i++] = GOSUB | batch_add; + p_logical_main_add[i++] = TST_INSTR_TEST_REG | 20; + p_logical_main_add[i++] = GOSUB | batch_add; + p_logical_main_add[i++] = TST_INSTR_TEST_REG | 21; + p_logical_main_add[i++] = GOSUB | batch_add; + p_logical_main_add[i++] = TST_INSTR_TEST_REG | 22; + p_logical_main_add[i++] = GOSUB | batch_add; + p_logical_main_add[i++] = TST_INSTR_TEST_REG | 23; + p_logical_main_add[i++] = GOSUB | batch_add; + p_logical_main_add[i++] = TST_INSTR_TEST_REG | 24; + p_logical_main_add[i++] = GOSUB | batch_add; + p_logical_main_add[i++] = TST_INSTR_TEST_REG | 25; + p_logical_main_add[i++] = GOSUB | batch_add; +} + p_logical_main_add[i++] = WAIT_INSTR_TEST_REG; + p_logical_main_add[i++] = GOTO | (main_add / 8); + + /*insert the the "Return" command at default batch firmware memory location */ + *p_logical_default_batch_add = STOP; + + /*Number of commands inserted at given memory location */ + *p_no_cmd = i; + DBGEXIT0(SGA_OK); + return(SGA_OK); +} + +/****************************************************************************/ +/* NAME : SGA_RunMainBatchFirmware() */ +/*--------------------------------------------------------------------------*/ +/* DESCRIPTION : This routine is used to run the main batch firmware */ +/* (SGA Batch Server ) */ +/* PARAMETERS : */ +/* IN :None */ +/* InOut :None */ +/* OUT :None */ +/* RETURN :t_sga_error : SGA error code */ +/* SGA_OK : if it is ok */ +/* SGA_MAIN_FIRMWARE_NOT_BUILD if starting location of main */ +/* firmware has not yet set */ +/*--------------------------------------------------------------------------*/ +/* Type : PUBLIC */ +/* REENTRANCY : Non Re-entrant */ +/* REENTRANCY ISSUES : */ +/****************************************************************************/ +PUBLIC t_sga_error SGA_RunMainBatchFirmware(void) +{ + t_uint32 cmd; + + DBGENTER0(); + if (NULL == g_sga_system_context.p_main_batch_add) + { + DBGEXIT0(SGA_MAIN_FIRMWARE_NOT_BUILD); + return(SGA_MAIN_FIRMWARE_NOT_BUILD); + } + cmd = GOTO | (((t_uint32) g_sga_system_context.p_main_batch_add) >> 3); + + /*start the main batch firmware */ + g_sga_system_context.p_sga_registers->sga_instr = cmd; + + /*Cache Configuration */ + g_sga_system_context.p_sga_registers->sga_instr = CACHE_CTRL | (0x71c0); + + /*Auto Fetch Active */ + g_sga_system_context.p_sga_registers->sga_instr = AHB | (0x120); + /*Enable the SGA Global resume bit */ + SGA_SET_BIT(g_sga_system_context.p_sga_registers->sga_ctcmd, SGA_CTCMD_GRESUME_MASK); + /*Enable the SGA Instructions resume bit */ + SGA_SET_BIT(g_sga_system_context.p_sga_registers->sga_ctcmd, SGA_CTCMD_IRESUME_MASK); + DBGEXIT0(SGA_OK); + return(SGA_OK); +} --- /dev/null +++ linux-2.6.20/drivers/video/nomadik/hcl/sga.h @@ -0,0 +1,937 @@ +/****************************************************************************** + * Copyright 2007, STMicroelectronics + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + * + * Description : Public Header file of Smart Graphic Accelarator (SGA) module + * + *****************************************************************************/ +#ifndef _SGA_H_ +#define _SGA_H_ + +/*--------------------------------------------------------------------------* + * Includes * + *--------------------------------------------------------------------------*/ +#include "debug.h" +#include "hcl_defs.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + +/*--------------------------------------------------------------------------* + * Constants and new types * + *--------------------------------------------------------------------------*/ +#define SGA_HCL_VERSION_ID 3 +#define SGA_HCL_MAJOR_ID 0 +#define SGA_HCL_MINOR_ID 0 + +/* SGA Peripheral IDs */ +#define SGA_PERIPHERAL_ID0 0x2 +#define SGA_PERIPHERAL_ID1 0x62 +#define SGA_PERIPHERAL_ID2 0x2D +#define SGA_PERIPHERAL_ID3 0x0 + +/* SGA P CELL ids */ +#define SGA_PCELL_ID0 0xD +#define SGA_PCELL_ID1 0xF0 +#define SGA_PCELL_ID2 0x05 +#define SGA_PCELL_ID3 0xB1 + +//26 +#ifndef MAX_BATCHES + #define MAX_BATCHES 16 +#endif + +/*----------------------------------------------------------------------------- + Typedefs +-----------------------------------------------------------------------------*/ + +/* Defines the SGA Device Configuration settings */ +typedef struct +{ + t_bool int_mode1; /* Activates the read reset feature of the interrupt1 register */ + t_bool hclk_en; /* Activates the clock gating functionality for HCLK domain */ + t_bool fclk_en; /* Activates the clock gating functionality for FCLK domain */ + t_bool int_mode0; /* Activates the read reset feature of the interrupt register */ +}t_sga_device_config; + + +/* Fetch the statistics of the drawn primities */ +typedef enum +{ + SGA_STATISTICS_TRIANGLE_REQ, + SGA_STATISTICS_FRAG_RAW_REQ, + SGA_STATISTICS_FRAG_DEPTH_REQ, + SGA_STATISTICS_TEXT_CACHE_REQ, + SGA_STATISTICS_FRAME_CACHE_REQ, + SGA_STATISTICS_TEXT_CACHE_REFILLS_REQ, + SGA_STATISTICS_INSTRUCT_REFILL_REQ, + SGA_STATISTICS_CLK_CYCLES_REQ +}t_sga_statistics_req; + +/* Define the SGA conrol settings */ +typedef enum +{ + SGA_CTRL_CMD_GLOBAL_INIT, + SGA_CTRL_CMD_GLOBAL_HALT, + SGA_CTRL_CMD_GLOBAL_RESUME, + SGA_CTRL_CMD_INSTR_HALT, + SGA_CTRL_CMD_INSTR_RESUME, + SGA_CTRL_CMD_INSTR_FLUSH, + SGA_CTRL_CMD_AUTO_FETCH_STOP, + SGA_CTRL_CMD_AUTO_FETCH_RUN +}t_sga_ctrl_cmd; + + +/*Define the the image buffer */ +typedef enum +{ + SGA_IMAGE_BUFFER_IN0, /*Input buffer source in0 */ + SGA_IMAGE_BUFFER_IN1, /*Input buffer source in1 */ + SGA_IMAGE_BUFFER_IN2, /*Input buffer source in2 */ + SGA_IMAGE_BUFFER_OUT /*Output/Destination buffer source OUT */ +}t_sga_image_buffer; + + +/* Define the Primitives to be drawn */ +typedef enum +{ + SGA_GRAPHIC_DRAWPOINT, /*Draw Point */ + SGA_GRAPHIC_DRAWLINE, /*Draw Line */ + SGA_GRAPHIC_DRAWTRIANGLE, /*Draw Triangle */ + SGA_GRAPHIC_DRAWRECTANGLE, /*Draw Rectangle */ + SGA_GRAPHIC_LINE_SHIFT, /*Draw line shift */ + SGA_GRAPHIC_TRIANGLE_SHIFT /*Draw Triangle shift */ +}t_sga_graphic_type; + + +/* Define the Graphic command and associated paramers */ +typedef struct +{ + t_sga_graphic_type graphic_type; /*specify the primitive to drawn */ + t_uint16 point_x0; /* Range 0 - 511 */ + t_uint16 point_y0; /* Range 0 - 511 */ + t_uint16 point_x1; /* Range 0 - 511 */ + t_uint16 point_y1; /* Range 0 - 511 */ + t_uint16 point_x2; /* Range 0 - 511 */ + t_uint16 point_y2; /* Range 0 - 511 */ + t_uint16 stippling_factor; /* defines the mask for pattern lines*/ + t_uint16 stippling_mask; /* defines the mask for pattern lines*/ + t_bool colour_set; /* TRUE- colour to set,FALSE -interpolation to be set */ + t_uint32 rgb_colour; /* Color value in the RGB format */ + t_uint16 interpol_inc_x_dec; /* Decimal value of the x increment for interpolator */ + t_uint16 interpol_inc_y_dec; /* Decimal value of the y increment for interpolator */ + t_uint8 interpol_inc_x_int; /* intiger value of the x increment for interpolator */ + t_uint8 interpol_inc_y_int; /* Decimal value of the y increment for interpolator */ + t_bool set_bypass_zs; /*TRUE- Z S components present in the colour */ + t_uint16 z_colour; + t_uint8 s_colour; +}t_sga_graphic_command; + + +/*Defines the ROP Operation */ +typedef enum +{ + SGA_ROP_CLEAR, + SGA_ROP_NOTIN0_AND_NOTIN1, + SGA_ROP_NOTIN0_AND_IN1, + SGA_ROP_IN0_AND_NOTIN1, + SGA_ROP_IN0_AND_IN1, + SGA_ROP_NOTIN0_OR_NOTIN1, + SGA_ROP_NOTIN0_OR_IN1, + SGA_ROP_IN0_OR_NOTIN1, + SGA_ROP_IN0_OR_IN1, + SGA_ROP_IN0_XOR_IN1, + SGA_ROP_NOTIN0_XOR_IN1, + SGA_ROP_NOTIN0, + SGA_ROP_NOTIN1, + SGA_ROP_0, + SGA_ROP_1, + SGA_ROP_SET +}t_sga_rop_operation; + + +/*Define the Pixel formats */ +typedef enum +{ + SGA_PIXEL_FORMAT_MONO_1BPP, + SGA_PIXEL_FORMAT_MONO_2BPP, + SGA_PIXEL_FORMAT_MONO_4BPP, + SGA_PIXEL_FORMAT_MONO_8BPP, + SGA_PIXEL_FORMAT_RGB8, + SGA_PIXEL_FORMAT_ARGB12, + SGA_PIXEL_FORMAT_RGBA12, + SGA_PIXEL_FORMAT_RGBA15, + SGA_PIXEL_FORMAT_RGB16, + SGA_PIXEL_FORMAT_ARGB15, + SGA_PIXEL_FORMAT_ARGB24, + SGA_PIXEL_FORMAT_RGBA24, + SGA_PIXEL_FORMAT_YUV422, + SGA_PIXEL_FORMAT_LA16, + SGA_PIXEL_FORMAT_ZARGB14, + SGA_PIXEL_FORMAT_ZARGB16 +}t_sga_pixel_format; + + +/*Defines the Stencil buffer mode for in0 and OUT buffers. This active only for Pixel format ZARGB16 */ +typedef enum +{ + SGA_STENCIL_BUFFER_OFF , + SGA_STENCIL_BUFFER_0BPP, + SGA_STENCIL_BUFFER_1BPP, + SGA_STENCIL_BUFFER_2BPP +}t_sga_stencil_buffer_mode; + + +/*Define the endian mode of the Image buffer pixels data */ +typedef enum +{ + SGA_ENDIAN_BIG, + SGA_ENDIAN_LITTLE +}t_sga_endian_mode; + + +/* Defines the Bilinear interpolation state for the in1 and in2 buffers */ +typedef enum +{ + SGA_BILINEAR_INACTIVE, + SGA_BILINEAR_ACTIVE +}t_sga_bilinear_mode; + + + +/*Defines the colour conversion state for the input buffers */ +typedef enum +{ + SGA_COLOUR_CONVERSION_INACTIVE, + SGA_COLOUR_CONVERSION_ACTIVE +}t_sga_colour_conversion; + + +/* Define the buffer Pixel settings for in0,in1,in2 and out buffers */ +/* Note : bilinear_mode - only applicable for the in1 and in2 buffers + stencil_mode - only applicable for the in0 and Out buffers */ +typedef struct +{ + t_sga_colour_conversion colour_conversion; /* Activate/Deactive the colour conversion */ + t_bool yuv_rgb; /* TRUE - (YUV-RGB), FALSE- (RGB-YUV) */ + t_bool truncate_to_16_235; /* TRUE- Truncate result to 16-235 */ + t_bool activate_flow; /* TRUE -Active this flow, FLASE - Deactive this flow*/ + t_bool freeze_ahb_address; /* TRUE- Freeze the AHB address */ + t_bool memory_bypass; /* TRUE - bypass the memory access */ + t_bool dma_synchro; /* TRUE - Activate the DMA synchro */ + t_bool colour_to_zero; /* TRUE - Force the colour components to zero*/ + t_bool alpha_to_255; /* TRUE - force the Alpha component to 255 */ + t_bool exchange_red_blue; /* TRUE - Exchange Red and Blue compnt (BGR instead of RGB) */ + t_bool activate_depack; /* TRUE - Activate Depacking mode, used for ARGB24 format */ + t_sga_endian_mode endian; /* endian mode */ + t_sga_bilinear_mode bilinear_mode; + t_sga_stencil_buffer_mode stencil_mode; + t_sga_pixel_format pixel_format; +}t_sga_buffer_pixel_settings; + + + +/* Define the Dithering operting mode */ +typedef enum +{ + SGA_DITHERING_OFF, + SGA_DITHERING_ALPHA, + SGA_DITHERING_RGB, + SGA_DITHERING_RGB_ALPHA +}t_sga_dithering_mode; + + +/* Define the Pixel Operator state */ +typedef enum +{ + SGA_PIXEL_OPERATOR_ACTIVE, + SGA_PIXEL_OPERATOR_BYPASS +}t_sga_pixel_op_mode; + + +/* Define the PixelOp mode operation */ +typedef enum +{ + SGA_FRAME_BLEND_ACTIVE, /*Activates the Frame Blending Operation */ + SGA_ROP4_ACTIVE /*Activates the ROP Operation */ +}t_sga_rop_blend; + + +/*Define the Rasterizer Precision */ +typedef enum +{ + SGA_RASTER_PRCS_LSB_NORMAL, + SGA_RASTER_PRCS_LSB_1, + SGA_RASTER_PRCS_LSB_2, + SGA_RASTER_PRCS_LSB_3 +}t_sga_raster_precision; + + + +/* Define the Pixle OpMode instruction settings.*/ +typedef struct +{ + t_sga_raster_precision precision; /*Only for STn8815 CutB0 chip */ + t_sga_pixel_op_mode mode; /* TRUE - Bypass the pixel Operator */ + t_bool freeze_index_cnt; /* TRUE - Freeze the index counter */ + t_bool stop_concatenate; /* TRUE - stop concatenate */ + t_bool mask_z_bits; /* TRUE - mask z bits */ + t_bool mask_s1_bits; /* TRUE - mask s1 bits */ + t_bool mask_s0_bits; /* TRUE - mask s0 bits */ + t_bool mask_a_bits; /* TRUE - mask a bits */ + t_bool mask_r_bits; /* TRUE - mask r bits */ + t_bool mask_g_bits; /* TRUE - mask g bits */ + t_bool mask_b_bits; /* TRUE - mask b bits */ + t_sga_dithering_mode dithering_mode; + t_sga_rop_blend rop_blend; + t_sga_rop_operation rop_type; + t_bool active_scissor; /* TRUE - Activates the scissor operator */ + t_bool active_tribreak; /* TRUE - Activates the Tie Break */ +}t_sga_pixel_opmode_config; + + +/* Defines the source (in0,in1 and in2 ) buffer and Destination buffer (OUT) configuration */ +/* Note: X, Y Shift fileds are applicable for in0 ,in1 and in2 buffers + scissor_clip_x and scissor_clip_y fields are applicable for Out configure */ +typedef struct +{ + t_uint32 buffer_address; /* Source or Destination buffer address*/ + t_uint16 line_jump; /* amount of bytes to jump between 2 lines */ + t_uint16 x_size; /* X size, in pixels (0 .. 2047) */ + t_uint16 y_size; /* Y size, in pixels (0 .. 2047) */ + t_sint16 x_shift; /* X shift (-2048 .. 2047) */ + t_sint16 y_shift; /* Y Shift (-2048 .. 2047) */ + t_uint16 scissor_clip_x; /* upper left position of the Scissor clipping area. X (0 .. 2047)*/ + t_uint16 scissor_clip_y; /* upper left position of the Scissor clipping area. Y(0 .. 2047) */ +}t_sga_buffer_config; + + +/* Define the mode to extract the transparency status in the input flows */ +typedef enum +{ + SGA_TRANSP_IN_INACTIVE, + SGA_TRANSP_IN_RGB, + SGA_TRANSP_IN_ARGB, + SGA_TRANSP_IN_ALFA_NULL +}t_sga_transp_in_mode; + + +/*Defines the mode to handle the transparency on the output flow */ +typedef enum +{ + SGA_TRANSP_OUT_NOT_WRITTEN, + SGA_TRANSP_OUT_RGB, + SGA_TRANSP_OUT_ARGB, + SGA_TRANSP_OUT_ALFA_NULL +}t_sga_transp_out_mode; + + + +/*The Transparency configuration for input and output buffers */ +typedef struct +{ + t_uint32 in_transp_colour; /*Input transparency keying colour in ARGB format */ + t_uint32 out_transp_colour; /* Output transparency keying colour in ARGB format */ + t_bool video_mode; /* TRUE - tranparency is active on video */ + t_bool active_on_input; /* TRUE - active on the input flows */ + t_bool active_on_output; /* TRUE - active on the output flows */ + t_sga_transp_in_mode transp_in_mode; + t_sga_transp_out_mode transp_out_mode; + t_bool transp_active_in0; /*Only for STn8815 CutB0 chip */ + t_bool transp_active_in1; /*Only for STn8815 CutB0 chip */ + t_bool transp_active_in2; /*Only for STn8815 CutB0 chip */ +}t_sga_transp_config; + + +/* Define the Flash mode */ +typedef enum +{ + SGA_FLASH_RGB, + SGA_FLASH_ARGB +}t_sga_flash_mode; + + +/* Defines the Flash configuration for the input and output buffers */ +typedef struct +{ + t_uint32 flash_id_colour; + t_uint32 flash_new_colour; + t_bool flash_active; /* TRUE - flash active */ + t_sga_flash_mode flash_mode; + t_bool flash_active_in0; /*Only for STn8815 CutB0 chip */ + t_bool flash_active_in1; /*Only for STn8815 CutB0 chip */ + t_bool flash_active_in2; /*Only for STn8815 CutB0 chip */ +}t_sga_flash_config; + + +typedef enum +{ + SGA_OK = HCL_OK, /* No error.*/ + SGA_NO_PENDING_EVENT_ERROR = HCL_NO_PENDING_EVENT_ERROR, + SGA_NO_MORE_FILTER_PENDING_EVENT = HCL_NO_MORE_FILTER_PENDING_EVENT, + SGA_NO_MORE_PENDING_EVENT = HCL_NO_MORE_PENDING_EVENT, + SGA_REMAINING_FILTER_PENDING_EVENTS = HCL_REMAINING_FILTER_PENDING_EVENTS, + SGA_REMAINING_PENDING_EVENTS = HCL_REMAINING_PENDING_EVENTS, + SGA_INTERNAL_EVENT = HCL_INTERNAL_EVENT, + SGA_INTERNAL_ERROR = HCL_INTERNAL_ERROR, + SGA_NOT_CONFIGURED = HCL_NOT_CONFIGURED, + SGA_REQUEST_PENDING = HCL_REQUEST_PENDING, + SGA_REQUEST_NOT_APPLICABLE = HCL_REQUEST_NOT_APPLICABLE, + SGA_INVALID_PARAMETER = HCL_INVALID_PARAMETER, + SGA_UNSUPPORTED_FEATURE = HCL_UNSUPPORTED_FEATURE, + SGA_UNSUPPORTED_HW = HCL_UNSUPPORTED_HW, + SGA_RESOURCE_NOT_AVIALABLE =(HCL_MAX_ERROR_VALUE -1), + SGA_MAIN_FIRMWARE_NOT_BUILD =(HCL_MAX_ERROR_VALUE -2) +}t_sga_error; + +/* Defines the SGA Status */ +typedef enum +{ + SGA_STATUS_GLOBAL_EN, + SGA_STATUS_INST_PROCESS_EN, + SGA_STATUS_AUTOFETCH, + SGA_STATUS_INST_FIFO_EMPTY, + SGA_STATUS_PIXELPIPE_EMPTY, + SGA_STATUS_TOTALPIPE_EMPTY, + SGA_STATUS_TOTALPIPE_CACHE_EMPTY, + SGA_STATUS_RESTART_CNT +}t_sga_status; + +/* Defines the dynamic configuration coefficients multiplying the X & Y components */ +typedef enum +{ + SGA_XY_DYN_COEF_NORMAL, + SGA_XY_DYN_COEF_X_4, + SGA_XY_DYN_COEF_X_16, + SGA_XY_DYN_COEF_X_64 +}t_sga_xy_dyn_coef_type; + +/* Define the rotate or resize source */ +typedef enum +{ + SGA_ROTATE_RESIZE_IN1, /* source in1 or Texture0 */ + SGA_ROTATE_RESIZE_IN2 /* source in2 or Texture1 */ +}t_sga_rotate_resize_source; + + + +/*Defines the XYZ coefficients for Rotation or Resize */ +typedef struct +{ + t_uint8 x_dec_offset; /*range is 0 -3 */ + t_uint8 y_dec_offset; /*range is 0 -3 */ + t_uint8 w_dec_offset; /*range is 0 -3 */ + t_sint16 xx_int_coef; + t_sint16 xy_int_coef; + t_sint16 yx_int_coef; + t_sint16 yy_int_coef; + t_sint16 wx_int_coef; + t_sint16 wy_int_coef; + t_uint16 xx_dec_coef; + t_uint16 xy_dec_coef; + t_uint16 yx_dec_coef; + t_uint16 yy_dec_coef; + t_uint16 wx_dec_coef; + t_uint16 wy_dec_coef; + t_sint16 x_int_offset; /*range is -32k to 32k-1 */ + t_sint16 y_int_offset; /*range is -32k to 32k-1 */ + t_sint16 w_int_offset; /*range is -32k to 32k-1 */ + t_bool active_corrected_mode; /*TRUE - active corrective mode */ + t_sga_xy_dyn_coef_type dyn_coeff; + t_sga_rotate_resize_source source; +}t_sga_xyw_coefficient; + + + +/* Define the X & Y modulo size of the Pixel */ +typedef enum +{ + SGA_XY_MODULO_SIZE_1, + SGA_XY_MODULO_SIZE_2, + SGA_XY_MODULO_SIZE_4, + SGA_XY_MODULO_SIZE_8, + SGA_XY_MODULO_SIZE_16, + SGA_XY_MODULO_SIZE_32, + SGA_XY_MODULO_SIZE_64, + SGA_XY_MODULO_SIZE_128, + SGA_XY_MODULO_SIZE_256, + SGA_XY_MODULO_SIZE_512, + SGA_XY_MODULO_SIZE_1024 + }t_sga_xy_modulo_size; + + +/* Defines the type of clipping used for flow in0 for X & Y, when after roatation, + the co ordinate is out of defined picture */ +typedef enum +{ + SGA_CLIPPING_NONE, /* No clipping performed */ + SGA_CLIPPING_CLAMPING, /* Coordinate set to largest X and Y values */ + SGA_CLIPPING_MODULO, /* X and Y with defined modulo size */ + SGA_CLIPPING_MIRROR /* X and Y mirrored with defined modulo */ +}t_sga_clipping_type; + + + +/* Define the XY rotation / Resize configuration */ +typedef struct +{ + t_sga_rotate_resize_source source; + t_bool active_corrected_mode; /* TRUE - Activate Auto corrective mode */ + t_sga_xy_modulo_size x_modulo_size; + t_sga_xy_modulo_size y_modulo_size; + t_sga_clipping_type x_clip; + t_sga_clipping_type y_clip; + t_bool active_rotate; /* Activate the XY roatation */ +}t_sga_rotate_resize_config; + + + +/* Defines the Cache flow for flow in0 or OUT */ +typedef enum +{ + SGA_CACHE_FLOW_CACHE, /* banks 0..3 are In0 as Cache, bank 4..7 for Out Cache. */ + SGA_CACHE_FLOW_FIFO, /* banks 0..3 are In0 as Cache, bank 4..7 for Out Fifo. */ + SGA_CACHE_FLOW_UNIFIED, /* banks 0..7 are In0 and Out as unified Cache. */ + SGA_CACHE_FLOW_RESERVED /* reserved */ +}t_sga_cache_flow_mode; + + +/* Defines the Cache instruction configuration */ +typedef struct +{ + t_bool bank_optm_disable; + t_bool hardinit_text; + t_bool hardinit_out; + t_bool hardinit_in0; + t_bool autoinit_text; + t_bool autoinit_out; + t_bool autoinit_in0; + t_bool manualflush_text; + t_bool manualflush_out; + t_bool manualflush_in0; + t_bool autoflush_text; + t_bool autoflush_out; + t_bool autoflush_in0; + t_bool cache_topo_out; + t_bool cache_topo_in2; + t_bool cache_topo_in1; + t_bool cache_topo_in0; + t_sga_cache_flow_mode mode; +}t_sga_cache_config; + + +/*Defines the Sempahore state */ +typedef enum +{ + SGA_SEMAPHORE_RESET, + SGA_SEMAPHORE_SET +}t_sga_semaphore_state; + + /* Define the Wait instruction to be firmwared */ +typedef enum +{ + SGA_WAIT_SYNCHRO, + SGA_WAIT_NEWSYNCHRO, + SGA_WAIT_N_CYCLES, + SGA_WAIT_PIPE_EMPTY +}t_sga_wait_type; + +/*Define the Wait pipe empty type */ +typedef enum +{ + SGA_WAIT_PIPE_EMP_COMPLETE, + SGA_WAIT_PIPE_EMP_OPERATIVE +}t_sga_wait_pipe_emp_type; + + +/*Define the Wait instruction to be build and its settings */ +/*Note : wait time is not applicable for SGA_WAIT_PIPE_EMPTY instruction. + Synchro port is only applicable for SGA_WAIT_SYNCHRO and SGA_WAIT_NEWSYNCHRO + pipe_empty_type is only applicable for SGA_WAIT_PIPE_EMPTY instruction */ +typedef struct +{ + t_sga_wait_type wait; /* Wait instruction to be used */ + t_uint32 wait_time; /* Wait period * 256 clock cycles for wait synchro instructions */ + t_uint32 synchro_port; /* Synchro port id */ + t_sga_wait_pipe_emp_type pipe_empty_type; +}t_sga_wait_config; + + +/* Defines the dynamic configuration of coefficients multiplaying Z components */ +typedef enum +{ + SGA_Z_DYN_COEF_NORMAL, + SGA_Z_DYN_COEF_X_8, + SGA_Z_DYN_COEF_X_64, + SGA_Z_DYN_COEF_X_512 +}t_sga_z_dyn_coef_type; + + +/* Define the Depth instructions configuration. */ +typedef struct +{ + t_uint16 zx_dec_coeff; + t_uint16 zy_dec_coeff; + t_sint32 zx_int_coeff; + t_sint32 zy_int_coeff; + t_sint32 z_offset; + t_sga_z_dyn_coef_type z_dyn; + }t_sga_z_coef_config; + +/* Defines the AHB burst type to be generated */ +typedef enum +{ + SGA_AHB_BURST_1, + SGA_AHB_BURST_4, + SGA_AHB_BURST_8, + SGA_AHB_BURST_16 +}t_sga_ahb_burst_type; + + +/* Define AHB instruction configuration */ +typedef struct +{ + t_bool active_autofetch; /* Allows DmaFsm to fetch directly instructions */ + t_bool hclk_lock; + t_uint8 hprot; /* HProt Fixed value range 0 -15 */ + t_sga_ahb_burst_type burst_type; /* Burst type generated */ +}t_sga_ahb_config; + + +/*Defines the dynamic configuration of coefficients multiplication ( for Gouraud and FOG ) */ +typedef enum +{ + SGA_DYN_COEF_DIV_BY_256, + SGA_DYN_COEF_DIV_BY_64, + SGA_DYN_COEF_DIV_BY_16, + SGA_DYN_COEF_DIV_BY_4 +}t_sga_dyn_coef_type; + + +/* Define the Gouraud shadding coefficients configuration */ +typedef struct +{ + t_uint8 ax_dec_grad; + t_uint8 ay_dec_grad; + t_uint8 rx_dec_grad; + t_uint8 ry_dec_grad; + t_uint8 gx_dec_grad; + t_uint8 gy_dec_grad; + t_uint8 bx_dec_grad; + t_uint8 by_dec_grad; + t_sint16 ax_int_grad; + t_sint16 ay_int_grad; + t_sint16 rx_int_grad; + t_sint16 ry_int_grad; + t_sint16 gx_int_grad; + t_sint16 gy_int_grad; + t_sint16 bx_int_grad; + t_sint16 by_int_grad; + t_sint16 ao_offset; /* range is - 2048 to 2047 */ + t_sint16 ro_offset; /* range is - 2048 to 2047 */ + t_sint16 go_offset; /* range is - 2048 to 2047 */ + t_sint16 bo_offset; /* range is - 2048 to 2047 */ + t_sga_dyn_coef_type dyn_coef; + }t_sga_gouraud_coeff_config; + + +/* Defines Texture source id */ +typedef enum +{ + SGA_TEX_SOURCE_0, + SGA_TEX_SOURCE_1 +}t_sga_tex_source_id; + +/*Defines the Textures Environment function for RGB or Alpha components */ +typedef enum +{ + SGA_TEX_ENV_REPLACE, + SGA_TEX_ENV_MODULATE, + SGA_TEX_ENV_ADD, + SGA_TEX_ENV_ADD_SIGNED, + SGA_TEX_ENV_INTERPOLATE, + SGA_TEX_ENV_SUBSTRACT, + SGA_TEX_ENV_DOT3RGB, + SGA_TEX_ENV_DOT4RGB +}t_sga_tex_env_function; + + +/*Defines the texture source environment Source for RGB or Alpha components */ +typedef enum +{ + SGA_TEX_ENV_SOURCE_TEXTURE, + SGA_TEX_ENV_SOURCE_CST_COLOUR, + SGA_TEX_ENV_SOURCE_GOURAUD_COL, /* Gouraud colour */ + SGA_TEX_ENV_SOURCE_PREVIOUS_COL /* Previous colour */ +}t_sga_tex_env_source; + +/*Defines the Texture Blending environment for RGB Operand */ +typedef enum +{ + SGA_TEX_ENV_RGB_OPR_COLOUR, + SGA_TEX_ENV_RGB_OPR_1_COLOR, + SGA_TEX_ENV_RGB_OPR_ALPHA, + SGA_TEX_ENV_RGB_OPR_1_ALPHA +}t_sga_tex_env_rgb_operand; + +typedef enum +{ + SGA_TEX_ENV_A_OPR_ALPHA, + SGA_TEX_ENV_A_OPR_1_ALPHA +}t_sga_tex_env_a_operand; + + +/* Define the Texture environement blending configuration. */ +typedef struct +{ + t_sga_tex_source_id tex_id; + t_uint32 argb_colour; /* Constant colour in ARGB format */ + t_sga_tex_env_function rgb_fct; + t_sga_tex_env_function a_fct; + t_sga_tex_env_source source_0_rgb; + t_sga_tex_env_source source_1_rgb; + t_sga_tex_env_source source_2_rgb; + t_sga_tex_env_source source_0_a; + t_sga_tex_env_source source_1_a; + t_sga_tex_env_source source_2_a; + t_sga_tex_env_rgb_operand operand_0_rgb; + t_sga_tex_env_rgb_operand operand_1_rgb; + t_sga_tex_env_rgb_operand operand_2_rgb; + t_sga_tex_env_a_operand operand_0_a; + t_sga_tex_env_a_operand operand_1_a; + t_sga_tex_env_a_operand operand_2_a; + t_uint8 rgb_scale; + t_uint8 a_scale; +}t_sga_texture_config; + + +/* Define the fog instructions configuration*/ +typedef struct +{ + t_uint8 fx_grad_dec; + t_uint8 fy_grad_dec; + t_sint16 fx_grad_int; + t_sint16 fy_grad_int; + t_sint16 fo_offset; /*range is -2048 to 2047 */ + t_uint32 rgb_fog; /* FOG colour in RGB24 format */ + t_sga_dyn_coef_type coef_type; +}t_sga_fog_config; + + +/* Defines Frame Blend Operation */ +typedef enum +{ + SGA_BLEND_OP_ADD, + SGA_BLEND_OP_SUB, + SGA_BLEND_OP_REV_SUB, + SGA_BLEND_OP_MIN, + SGA_BLEND_OP_MAX +}t_sga_blend_operation; + +/* Defines the Source Frame Blending Environment source coffecients */ +typedef enum +{ + SGA_BLEND_SRC_COEF_0, + SGA_BLEND_SRC_COEF_1, + SGA_BLEND_SRC_COEF_RGB_FRAGMENT, + SGA_BLEND_SRC_COEF_1_RGB_FRAGMENT, + SGA_BLEND_SRC_COEF_RGB_FRAME, + SGA_BLEND_SRC_COEF_1_RGB_FRAME, + SGA_BLEND_SRC_COEF_A_FRAGMENT, + SGA_BLEND_SRC_COEF_1_A_FRAGMENT, + SGA_BLEND_SRC_COEF_A_FRAME, + SGA_BLEND_SRC_COEF_1_A_FRAME, + SGA_BLEND_SRC_COEF_RGB_CST_CLR, + SGA_BLEND_SRC_COEF_1_RGB_CST_CLR, + SGA_BLEND_SRC_COEF_A_CST_CLR, + SGA_BLEND_SRC_COEF_1_A_CST_CLR, + SGA_BLEND_SRC_COEF_MIN +}t_sga_blend_src_coef_type; + + + +/* Define the Frame Blending instructions configurations.*/ +typedef struct +{ + t_uint32 argb_colour; /*Define the colour value in ARGB format */ + t_sga_blend_operation blend_op; + t_sga_blend_src_coef_type rgb_fragment; + t_sga_blend_src_coef_type a_fragment; + t_sga_blend_src_coef_type rgb_frame; + t_sga_blend_src_coef_type a_frame; + }t_sga_blend_config; + + +typedef enum +{ + SGA_TEST_FUN_ALWAYS, + SGA_TEST_FUN_NEVER, + SGA_TEST_FUN_LESS, + SGA_TEST_FUN_LEQUAL, + SGA_TEST_FUN_EQUAL, + SGA_TEST_FUN_GEQUAL, + SGA_TEST_FUN_GREATER, + SGA_TEST_FUN_NOTEQUAL +}t_sga_test_function; + + +typedef struct +{ + t_bool enable; + t_sga_test_function func; + t_uint8 reference; +}t_sga_alphatest_config; + + +typedef enum +{ + SGA_STENCIL_TEST_KEEP, + SGA_STENCIL_TEST_ZERO, + SGA_STENCIL_TEST_REPLACE, + SGA_STENCIL_TEST_INCR, /*Increment */ + SGA_STENCIL_TEST_DECR, /*decrement */ + SGA_STENCIL_TEST_INVERT, + SGA_STENCIL_TEST_INCRWRAP, /*Increment Wrap */ + SGA_STENCIL_TEST_DECRWRAP /*Decrement Wrap */ +}t_sga_stencil_test; + +typedef struct +{ + t_bool enable; + t_sga_test_function func; + t_sga_stencil_test stencil_dpfail; + t_sga_stencil_test stencil_dppass; + t_sga_stencil_test stencil_sfail; + t_uint8 mask; /*range is 0 -15 */ + t_uint8 reference; /*range is 0 -15 */ +}t_sga_stenciltest_config; + + + +/*----------------------------------------------------------------------------- + Configuration functions +-----------------------------------------------------------------------------*/ +PUBLIC t_sga_error SGA_Init(IN t_logical_address address); +PUBLIC t_sga_error SGA_SetDeviceConfig(IN t_sga_device_config *p_dev_config); +PUBLIC void SGA_Reset(void); +PUBLIC void SGA_SetControlCommand(IN t_sga_ctrl_cmd command); +PUBLIC t_sga_error SGA_SetDbgLevel(IN t_dbg_level sga_dbg_level); +/*----------------------------------------------------------------------------- + Get Status functions +-----------------------------------------------------------------------------*/ +PUBLIC t_uint32 SGA_GetStatus(IN t_sga_status status); +PUBLIC t_uint32 SGA_GetStatistics(IN t_sga_statistics_req); +PUBLIC t_uint32 SGA_GetCurrentInstrPointer(void); +PUBLIC t_uint16 SGA_GetCurrentGotoCounter(void); +PUBLIC t_sga_error SGA_GetVersion(t_version *p_version); + +/*----------------------------------------------------------------------------- + SGA Server Resource Management functions +-----------------------------------------------------------------------------*/ +PUBLIC t_sga_error SGA_GetBatchID(OUT t_uint8* p_batch_id); +PUBLIC t_sga_error SGA_GetSemaphoreID(t_uint8* p_sem_id); +PUBLIC t_sga_error SGA_GetIntID(OUT t_uint8* p_int_id); + +PUBLIC t_sga_error SGA_ReleaseBatchID(IN t_uint8 batch_id); +PUBLIC t_sga_error SGA_ReleaseSemaphoreID(IN t_uint8 sem_id); +PUBLIC t_sga_error SGA_ReleaseIntID(IN t_uint8 int_id); + +PUBLIC void SGA_SetSemaphore(IN t_uint8 sem_id); +PUBLIC void SGA_ResetSemaphore(IN t_uint8 sem_id); +PUBLIC t_bool SGA_TestSemaphore(IN t_uint8 sem_id); + +PUBLIC t_sga_error SGA_LinkBatch(IN t_uint8 batch_id,IN t_uint32* p_batch_add); +PUBLIC t_sga_error SGA_StartBatch(IN t_uint8 batch_id); + + + +/*----------------------------------------------------------------------------- + Firmware building functions +-----------------------------------------------------------------------------*/ + +PUBLIC t_sga_error SGA_BuildStopInstrFirmware(OUT t_uint32* p_instr_add, OUT t_uint32* p_no_cmd ); +PUBLIC t_sga_error SGA_BuildReturnInstrFirmware(OUT t_uint32* p_instr_add, OUT t_uint32* p_no_cmd ); +PUBLIC t_sga_error SGA_BuildSendSynchroFirmware(OUT t_uint32* p_instr_add, OUT t_uint32* p_no_cmd ); + +PUBLIC t_sga_error SGA_BuildSemaphoreConfigFirmware(IN t_uint8 sem_id,IN t_sga_semaphore_state sem_state, + OUT t_uint32* p_instr_add,OUT t_uint32* p_no_cmd); +PUBLIC t_sga_error SGA_BuildTestSemaphoreFirmware(IN t_uint8 sem_id,OUT t_uint32* p_instr_add,OUT t_uint32* p_no_cmd); + +PUBLIC t_sga_error SGA_BuildSetIntFirmware(IN t_uint32 int_id,OUT t_uint32* p_instr_add,OUT t_uint32* p_no_cmd ); +PUBLIC t_sga_error SGA_BuildWaitInstrFirmware(IN t_sga_wait_config* p_wait, OUT t_uint32* p_instr_add, + OUT t_uint32* p_no_cmd ); +PUBLIC t_sga_error SGA_BuildAhbInstrFirmware(IN t_sga_ahb_config* p_ahb,OUT t_uint32* p_instr_add, + OUT t_uint32* p_no_cmd ); +PUBLIC t_sga_error SGA_BuildCacheControlFirmware(IN t_sga_cache_config* p_cache, OUT t_uint32* p_instr_add, + OUT t_uint32* p_no_cmd ); +PUBLIC t_sga_error SGA_BuildGotoInstrFirmware(IN t_uint32 addr, OUT t_uint32* p_instr_add, OUT t_uint32* p_no_cmd ); +PUBLIC t_sga_error SGA_BuildNoOpInstrFirmware(OUT t_uint32* p_instr_add, OUT t_uint32* p_no_cmd ); +PUBLIC t_sga_error SGA_BuildGoSubInstrFirmware(IN t_uint32 addr, OUT t_uint32* p_instr_add, OUT t_uint32* p_no_cmd ); + +PUBLIC t_sga_error SGA_BuildBufferConfigFirmware(IN t_sga_image_buffer buffer,IN t_sga_buffer_config* p_buf_config, + IN t_sga_buffer_pixel_settings* p_pix_config, OUT t_uint32* p_instr_add,OUT t_uint32* p_no_cmd ); +PUBLIC t_sga_error SGA_BuildDrawPrimitiveFirmware(IN t_sga_graphic_command* p_command,OUT t_uint32* p_instr_add, + OUT t_uint32* p_no_cmd ); + + +PUBLIC t_sga_error SGA_BuildTransparencyFirmware(IN t_sga_transp_config* p_transp, OUT t_uint32* p_instr_add, + OUT t_uint32* p_no_cmd); +PUBLIC t_sga_error SGA_BuildFlashFirmware(IN t_sga_flash_config* p_flash, OUT t_uint32* p_instr_add, + OUT t_uint32* p_no_cmd); +PUBLIC t_sga_error SGA_BuildXYWCoeffFirmware(IN t_sga_xyw_coefficient* p_xyw_coeff,OUT t_uint32* p_instr_add, + OUT t_uint32* p_no_cmd); +PUBLIC t_sga_error SGA_BuildXYModeFirmware(IN t_sga_rotate_resize_config* p_config,OUT t_uint32* p_instr_add, + OUT t_uint32* p_no_cmd); +PUBLIC t_sga_error SGA_BuildOpModeFirmware(IN t_sga_pixel_opmode_config* p_config, OUT t_uint32* p_instr_add, OUT t_uint32* p_no_cmd); + +PUBLIC t_sga_error SGA_BuildDepthInstrFirmware(IN t_sga_z_coef_config* p_z_coef, OUT t_uint32* p_instr_add, OUT t_uint32* p_no_cmd ); +PUBLIC t_sga_error SGA_BuildGouraudCoeffFirmware(IN t_sga_gouraud_coeff_config* p_config , + OUT t_uint32* p_instr_add, OUT t_uint32* p_no_cmd ); +PUBLIC t_sga_error SGA_BuildTextureConfigFirmware(IN t_sga_texture_config* p_config, OUT t_uint32* p_instr_add,OUT t_uint32* p_no_cmd); +PUBLIC t_sga_error SGA_BuildFogConfigFirmware(IN t_sga_fog_config* p_fog, OUT t_uint32* p_instr_add, OUT t_uint32* p_no_cmd); +PUBLIC t_sga_error SGA_BuildFrameBlendFirmware(IN t_sga_blend_config* p_blend,OUT t_uint32* p_instr_add, OUT t_uint32* p_no_cmd); + +PUBLIC t_sga_error SGA_BuildAlphaTestFirmware(IN t_sga_alphatest_config *p_alpha,OUT t_uint32* p_instr_add, OUT t_uint32* p_no_cmd); +PUBLIC t_sga_error SGA_BuildStencilTestFirmware(IN t_sga_stenciltest_config *p_stencil, OUT t_uint32* p_instr_add, OUT t_uint32* p_no_cmd); +PUBLIC t_sga_error SGA_BuildDepthTestFirmware(IN t_bool enable,IN t_sga_test_function depth_func, + OUT t_uint32* p_instr_add, OUT t_uint32* p_no_cmd); + +PUBLIC t_sga_error SGA_BuildBufferDeActivateFirmware(IN t_sga_image_buffer buffer,OUT t_uint32* p_instr_add, OUT t_uint32* p_no_cmd); +PUBLIC t_sga_error SGA_BuildFlashDeActivateFirmware(OUT t_uint32* p_instr_add, OUT t_uint32* p_no_cmd); +PUBLIC t_sga_error SGA_BuildTransparencyDeActivateFirmware(OUT t_uint32* p_instr_add, OUT t_uint32* p_no_cmd); + + + +/*----------------------------------------------------------------------------- + Main Batch Firmware functions +-----------------------------------------------------------------------------*/ + +PUBLIC t_sga_error SGA_BuildMainBatchFirmware +( + OUT t_uint32 *p_phy_main_add, + OUT t_uint32 *p_logical_main_add, + OUT t_uint32 *p_phy_default_batch_add, + OUT t_uint32 *p_logical_default_batch_add, + OUT t_uint32 *p_no_cmd +); +PUBLIC t_sga_error SGA_RunMainBatchFirmware(void); + + + +#ifdef __cplusplus +} /* allow C++ to use these headers */ +#endif /* __cplusplus */ +#endif /* _SGA_H_ */ --- /dev/null +++ linux-2.6.20/drivers/video/nomadik/hcl/sga_irq.c @@ -0,0 +1,206 @@ +/****************************************************************************** + * Copyright 2007, STMicroelectronics + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + * + * Description : This module provides interrupt routines for the + * NOMADIK SGA Controller + *****************************************************************************/ +/*--------------------------------------------------------------------------* + * Includes * + *--------------------------------------------------------------------------*/ +#include "sga_irq.h" +#include "sga_irqp.h" +#include "hcl_defs.h" + +/*--------------------------------------------------------------------------* + * Defines * + *--------------------------------------------------------------------------*/ +/*--------------------------------------------------------------------------* + * Private variables * + *--------------------------------------------------------------------------*/ +/*--------------------------------------------------------------------------* + * Defines * + *--------------------------------------------------------------------------*/ +/*--------------------------------------------------------------------------* + * Private variables * + *--------------------------------------------------------------------------*/ +PRIVATE t_sga_registers *gp_sga_registers; + +/**************************************************************************** +* NAME: SGA_SetBaseAddress() +*---------------------------------------------------------------------------* +* DESCRIPTION : This routine initializes SGA HCL. +* PARAMETERS : +* IN : t_logical_address base_address +* INOUT : None +* OUT : None +* RETURN VALUE : none +* TYPE : Public +*--------------------------------------------------------------------------- +* REENTRANCY: NA +*****************************************************************************/ +PUBLIC void SGA_SetBaseAddress(t_logical_address base_address) +{ + /* initializating the SGA base address */ + gp_sga_registers = (t_sga_registers *) base_address; +} + +/*************************************************************************** +* NAME: SGA_EnableIRQSrc() +*--------------------------------------------------------------------------- +* DESCRIPTION :This routine allows to enable a specific interrupt +* PARAMETERS : +* IN : t_sga_int_to_core core define the processor to route this +* interrupt +* irq_src: ORed value of interrupt sources to be enabled. +* (can also be used to enable all interrupts) +* INOUT : None +* OUT : None +* RETURN VALUE : none +* TYPE : Public +*-------------------------------------------------------------------------- +*REENTRANCY: NA +*****************************************************************************/ +PUBLIC void SGA_EnableIRQSrc(IN t_sga_int_to_core core, IN t_sga_irq_src irq_src) +{ + switch (core) + { + case SGA_INT_TO_ARM: + SGA_CLR_BIT(gp_sga_registers->sga_imsc, irq_src); + break; + + case SGA_INT_TO_MMDSP: + SGA_CLR_BIT(gp_sga_registers->sga_imsc1, irq_src); + break; + } +} + +/*************************************************************************** +* NAME: SGA_DisableIRQSrc() +*--------------------------------------------------------------------------- +* DESCRIPTION :This routine allows to disable a specific interrupt +* PARAMETERS : +* IN :t_sga_int_to_core core define the processor to route this +* interrupt +* irq_src: ORed value of interrupt sources to be disabled. +* (can also be used to enable all interrupts) +* INOUT : None +* OUT : None +* RETURN VALUE : none +* TYPE : Public +*-------------------------------------------------------------------------- +*REENTRANCY: NA +*****************************************************************************/ +PUBLIC void SGA_DisableIRQSrc(IN t_sga_int_to_core core, IN t_sga_irq_src irq_src) +{ + switch (core) + { + case SGA_INT_TO_ARM: + SGA_SET_BIT(gp_sga_registers->sga_imsc, irq_src); + break; + + case SGA_INT_TO_MMDSP: + SGA_SET_BIT(gp_sga_registers->sga_imsc1, irq_src); + break; + } +} + +/*************************************************************************** +*NAME: SGA_GetIRQSrc() * +*--------------------------------------------------------------------------* +*DESCRIPTION :This routine allows to read it status * +*(only valid for enabled IT) * +*PARAMETERS : * +*IN : t_sga_int_to_core core define the processor to route * +* this interrupt * +*INOUT : None * +*OUT : None * +*RETURN VALUE :ORed value of all the active interrupt sources * +*TYPE : Public * +*--------------------------------------------------------------------------* +*REENTRANCY: NA * +****************************************************************************/ +PUBLIC t_sga_irq_src SGA_GetIRQSrc(IN t_sga_int_to_core core) +{ + if (SGA_INT_TO_ARM == core) + { + return(gp_sga_registers->sga_mis); + } + else + { + return(gp_sga_registers->sga_mis1); + } +} + +/**************************************************************************** +* NAME: SGA_ClearIRQSrc() * +*---------------------------------------------------------------------------* +* DESCRIPTION :This routine allows to clear interrupt status * +*(clear in fact raw status) * +* PARAMETERS : * +* IN : t_sga_int_to_core core define the processor to route * +* this interrupt * +* irq_src: ORed value of interrupt sourcesto be cleared * +* (all interrupts can also be cleared together) * +* INOUT : None * +* OUT : None * +* RETURN VALUE : none: * +* TYPE : Public * +*---------------------------------------------------------------------------* +*REENTRANCY: Non Reentrant * +*****************************************************************************/ +PUBLIC void SGA_ClearIRQSrc(IN t_sga_irq_src irq_src) +{ + SGA_SET_BIT(gp_sga_registers->sga_icr, irq_src); +} + +/**************************************************************************** +* NAME: SGA_IsPendingIRQSrc() * +*---------------------------------------------------------------------------* +* DESCRIPTION :This routine allows to check the interrupt status of a * +* single irq * +* PARAMETERS : * +* IN : irq_src: ORed value of interrupt sources * +* INOUT : None * +* OUT : None * +* RETURN VALUE : none: * +* TYPE : Public * +*---------------------------------------------------------------------------* +*REENTRANCY: Re-entrant * +*****************************************************************************/ +PUBLIC t_bool SGA_IsPendingIRQSrc(IN t_sga_int_to_core core, IN t_sga_irq_src irq_src) +{ + if (SGA_INT_TO_ARM == core) + { + if (SGA_TEST_BIT(gp_sga_registers->sga_mis, irq_src)) + { + return(TRUE); + } + else + { + return(FALSE); + } + } + else + { + if (SGA_TEST_BIT(gp_sga_registers->sga_mis1, irq_src)) + { + return(TRUE); + } + else + { + return(FALSE); + } + } +} --- /dev/null +++ linux-2.6.20/drivers/video/nomadik/hcl/sga_irq.h @@ -0,0 +1,99 @@ +/****************************************************************************** + * Copyright 2007, STMicroelectronics + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + * + * Description : Public Header file of Smart Graphics Accelerator + * module containing interrupts APIs + *****************************************************************************/ + +#ifndef _SGA_IRQ_H_ +#define _SGA_IRQ_H_ + +#ifndef _HCL_DEFS_H +#include "hcl_defs.h" +#endif + +#ifdef __cplusplus +extern "C" +{ /* In case C++ needs to use this header.*/ +#endif + + +/*----------------------------------------------------------------------------- + Typedefs +-----------------------------------------------------------------------------*/ + +/*Define macros for SGA irq src id */ + +#define SGA_IRQ_SRC_INT_0 0x1 +#define SGA_IRQ_SRC_INT_1 0x2 +#define SGA_IRQ_SRC_FIFO_EMPTY 0x4 +#define SGA_IRQ_SRC_FIFO_OVERRUN 0x8 +#define SGA_IRQ_SRC_HANGING 0x10 +#define SGA_IRQ_SRC_AHB_ERROR 0x20 +#define SGA_IRQ_SRC_INSTR_RESUME_0 0x40 +#define SGA_IRQ_SRC_INSTR_RESUME_1 0x80 +#define SGA_IRQ_SRC_INT_2 0x100 +#define SGA_IRQ_SRC_INT_3 0x200 +#define SGA_IRQ_SRC_INT_4 0x400 +#define SGA_IRQ_SRC_INT_5 0x800 +#define SGA_IRQ_SRC_INT_6 0x1000 +#define SGA_IRQ_SRC_INT_7 0x2000 +#define SGA_IRQ_SRC_INT_8 0x4000 +#define SGA_IRQ_SRC_INT_9 0x8000 +#define SGA_IRQ_SRC_INT_10 0x10000 +#define SGA_IRQ_SRC_INT_11 0x20000 +#define SGA_IRQ_SRC_INT_12 0x40000 +#define SGA_IRQ_SRC_INT_13 0x80000 +#define SGA_IRQ_SRC_INT_14 0x100000 +#define SGA_IRQ_SRC_INT_15 0x200000 +#define SGA_IRQ_SRC_INT_16 0x400000 +#define SGA_IRQ_SRC_INT_17 0x800000 +#define SGA_IRQ_SRC_INT_18 0x1000000 +#define SGA_IRQ_SRC_INT_19 0x2000000 +#define SGA_IRQ_SRC_INT_20 0x4000000 +#define SGA_IRQ_SRC_INT_21 0x8000000 +#define SGA_IRQ_SRC_INT_22 0x10000000 +#define SGA_IRQ_SRC_INT_23 0x20000000 +#define SGA_IRQ_SRC_INT_24 0x40000000 +#define SGA_IRQ_SRC_INT_25 0x80000000 +#define SGA_IRQ_SRC_ALL 0xFFFFFFFF + + +typedef enum +{ + SGA_INT_TO_ARM, + SGA_INT_TO_MMDSP +}t_sga_int_to_core; + +typedef t_uint32 t_sga_irq_src; /*Combination of various interrupt sources + described by sga irq sources macros */ + +/*----------------------------------------------------------------------------- + Events and interrupts management functions +-----------------------------------------------------------------------------*/ +PUBLIC void SGA_SetBaseAddress (IN t_logical_address address ); +PUBLIC void SGA_EnableIRQSrc (IN t_sga_int_to_core core ,IN t_sga_irq_src irq_src); +PUBLIC void SGA_DisableIRQSrc (IN t_sga_int_to_core core ,IN t_sga_irq_src irq_src); +PUBLIC t_sga_irq_src SGA_GetIRQSrc (IN t_sga_int_to_core core ); +PUBLIC void SGA_ClearIRQSrc (IN t_sga_irq_src irq_src); +PUBLIC t_bool SGA_IsPendingIRQSrc (IN t_sga_int_to_core core ,IN t_sga_irq_src irq_src); + + + +#ifdef __cplusplus +} /* Allow C++ to use this header */ +#endif /* __cplusplus */ + +#endif /* _SGA_IRQ_H_ */ --- /dev/null +++ linux-2.6.20/drivers/video/nomadik/hcl/sga_irqp.h @@ -0,0 +1,239 @@ +/****************************************************************************** + * Copyright 2007, STMicroelectronics + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + * + * Description : Private Header file of SGA Controller module + * + *****************************************************************************/ + +#ifndef _SGA_IRQP_H_ +#define _SGA_IRQP_H_ + +/*------------------------------------------------------------------------ + * Includes + *----------------------------------------------------------------------*/ +#ifndef _HCL_DEFS_H +#include "hcl_defs.h" +#endif + +/*----------------------------------------------------------------------------- + + Generic Macros + +-----------------------------------------------------------------------------*/ + +#define SGA_SET_BIT(reg_name,mask) HCL_SET_BITS(reg_name,mask) +#define SGA_CLR_BIT(reg_name,mask) HCL_CLEAR_BITS(reg_name,mask) +#define SGA_WRITE_BIT(reg_name,val,mask) HCL_WRITE_BITS(reg_name,val,mask) +#define SGA_TEST_BIT(reg_name,val) HCL_READ_BITS(reg_name,val) +#define SGA_WRITE_REG(reg_name,val) HCL_WRITE_REG(reg_name,val) +#define SGA_READ_REG(reg_name) HCL_READ_REG(reg_name) +#define SGA_CLEAR MASK_NULL32 + + +#define SGA_WRITE_FIELD(reg_name,mask,shift,value) \ + (reg_name = ((reg_name & ~mask) | (value << shift))) + + +#define SGA_READ_FIELD(reg_name,mask,shift) ((reg_name & mask) >> shift ) + + + +/*----------------------------------------------------------------------------- + SGA Registers Description +-----------------------------------------------------------------------------*/ +typedef volatile struct +{ + t_uint32 sga_instr; /* Manual instruction input register 0x0 */ + t_uint32 sga_gcr; /* Global configuration register 0x04 */ + t_uint32 sga_ctcmd; /* Controller command register 0x08 */ + t_uint32 sga_ctstat; /* Controller status register 0x0C */ + t_uint32 sga_ris; /* Raw interrupt status register 0x10 */ + t_uint32 sga_mis; /* Masked interrupt status register 0x14 */ + t_uint32 sga_imsc; /* Interrpt mask register 0x18 */ + t_uint32 sga_icr; /* Interrupt clear register 0x1C */ + t_uint32 sga_reserved; /* Reserved 0x20 */ + t_uint32 sga_cipr; /* Current instruction pointer 0x24 */ + t_uint32 sga_cgcr; /* Current goto counter 0x28 */ + t_uint32 sga_dbgr; /* Debug register 0x2C */ + t_uint32 sga_sitr; /* Set instruction test register 0x30 */ + t_uint32 sga_citr; /* Clear Instruction register 0x34 */ + t_uint32 sga_gitr; /* Get instruction test register 0x38 */ + t_uint32 sga_sttr; /* Statistics on ammount of Traingles drawn 0x3C */ + t_uint32 sga_stfr; /* Statistics on ammount of Raw Fragment drawn 0x40 */ + t_uint32 sga_stfz; /* Statistics on ammount of z-tested fragment drawn 0x44 */ + t_uint32 sga_sttx; /* Statistics on ammount of Texture requests 0x48 */ + t_uint32 sga_stfmrf; /* Statistics on ammount of FrameBuffer cahce refills 0x4C */ + t_uint32 sga_sttxrf; /* Statistics on ammount of Texture cache Refills 0x50 */ + t_uint32 sga_stinrf; /* Statistics on ammount of Instruction Refills 0x54 */ + t_uint32 sga_stck; /* Statistics on ammount of clock cycles 0x58 */ + t_uint32 sga_mis1; /* Masked interrupt1 status register 0x5C */ + t_uint32 sga_imsc1; /* Interrupt mask1 register 0x60 */ + t_uint32 sga_reserved1[479]; /* Reserved address 0x64 -0x7DC */ + t_uint32 sga_periphid0; /* Pheripheral Identification 0 0x7E0 */ + t_uint32 sga_periphid1; /* Pheripheral Identification 1 0x7E4 */ + t_uint32 sga_periphid2; /* Pheripheral Identification 2 0x7E8 */ + t_uint32 sga_periphid3; /* Pheripheral Identification 3 0x7EC */ + t_uint32 sga_pcellid0; /* Pcell identification 0 0x7F0 */ + t_uint32 sga_pcellid1; /* Pcell identification 1 0x7F4 */ + t_uint32 sga_pcellid2; /* Pcell identification 2 0x7F8 */ + t_uint32 sga_pcellid3; /* Pcell identification 3 0x7Fc */ +}t_sga_registers; + + +/*----------------------------------------------------------------------------- + SGA Global Configuration register fields description +-----------------------------------------------------------------------------*/ + /*Shift values for Golbal configuration register */ +#define SGA_GCR_INTCMOD_SHIFT 0 /*Interrupt clear mode select bit */ +#define SGA_GCR_FCLKGEN_SHIFT 1 /*FCLK clock gating enable bit */ +#define SGA_GCR_HCLKGEN_SHIFT 2 /*Hclk Clock gating enable bit */ +#define SGA_GCR_INTCMOD1_SHIFT 3 /*Interrupt clear mode select */ + /*Mask values for Golbal configuration register */ +#define SGA_GCR_INTCMOD_MASK MASK_BIT0 /*Interrupt clear mode select bit */ +#define SGA_GCR_FCLKGEN_MASK MASK_BIT1 /*FCLK clock gating enable bit */ +#define SGA_GCR_HCLKGEN_MASK MASK_BIT2 /*Hclk Clock gating enable bit */ +#define SGA_GCR_INTCMOD1_MASK MASK_BIT3 /*Interrupt clear mode select */ + + +/*----------------------------------------------------------------------------- + SGA Controller command register fields description +-----------------------------------------------------------------------------*/ + /*Shift values for Controller command register */ +#define SGA_CTCMD_GINIT_SHIFT 0 /* Global initialisation bit */ +#define SGA_CTCMD_GHALT_SHIFT 1 /* Global Halt bit */ +#define SGA_CTCMD_GRESUME_SHIFT 2 /* Global Resume bit */ +#define SGA_CTCMD_IHALT_SHIFT 3 /* Instruction halt bit */ +#define SGA_CTCMD_IRESUME_SHIFT 4 /* Instruction resume bit */ +#define SGA_CTCMD_IFLUSH_SHIFT 5 /* Instruction flush bit */ +#define SGA_CTCMD_AFSTOP_SHIFT 6 /* AutoFetch Stopbit */ +#define SGA_CTCMD_AFRUN_SHIFT 7 /* AutoFetchRun bit */ +#define SGA_CTCMD_GRST_SHIFT 8 /* Global Reset bit */ + /*Mask values for Controller command register */ +#define SGA_CTCMD_GINIT_MASK MASK_BIT0 /* Global initialisation bit */ +#define SGA_CTCMD_GHALT_MASK MASK_BIT1 /* Global Halt bit */ +#define SGA_CTCMD_GRESUME_MASK MASK_BIT2 /* Global Resume bit */ +#define SGA_CTCMD_IHALT_MASK MASK_BIT3 /* Instruction halt bit */ +#define SGA_CTCMD_IRESUME_MASK MASK_BIT4 /* Instruction resume bit */ +#define SGA_CTCMD_IFLUSH_MASK MASK_BIT5 /* Instruction flush bit */ +#define SGA_CTCMD_AFSTOP_MASK MASK_BIT6 /* AutoFetch Stopbit */ +#define SGA_CTCMD_AFRUN_MASK MASK_BIT7 /* AutoFetchRun bit */ +#define SGA_CTCMD_GRST_MASK MASK_BIT8 /* Global Reset bit */ + +/*----------------------------------------------------------------------------- + SGA Controller status register fields description +-----------------------------------------------------------------------------*/ + /*Shift values for Controller status register */ +#define SGA_CTSTAT_GEN_SHIFT 0 /* Global enable status */ +#define SGA_CTSTAT_IPEN_SHIFT 1 /* Instruction processing enable status */ +#define SGA_CTSTAT_AFSTAT_SHIFT 2 /* Auto fetch mode status */ +#define SGA_CTSTAT_IFEMPTY_SHIFT 3 /* Instruction fifo empty */ +#define SGA_CTSTAT_PXPEMPTY_SHIFT 4 /* Pixel pipe empty */ +#define SGA_CTSTAT_TPEMPTY_SHIFT 5 /* Total Pipe empty */ +#define SGA_CTSTAT_TPCEMPTY_SHIFT 6 /* Total Pipe and Cache Empty */ +#define SGA_CTSTAT_RESTARTCNT_SHIFT 16 /* Restart Counter */ + /*Mask values for Controller status register */ +#define SGA_CTSTAT_GEN_MASK MASK_BIT0 /* Global enable status */ +#define SGA_CTSTAT_IPEN_MASK MASK_BIT1 /* Instruction processing enable status */ +#define SGA_CTSTAT_AFSTAT_MASK MASK_BIT2 /* Auto fetch mode status */ +#define SGA_CTSTAT_IFEMPTY_MASK MASK_BIT3 /* Instruction fifo empty */ +#define SGA_CTSTAT_PXPEMPTY_MASK MASK_BIT4 /* Pixel pipe empty */ +#define SGA_CTSTAT_TPEMPTY_MASK MASK_BIT5 /* Total Pipe empty */ +#define SGA_CTSTAT_TPCEMPTY_MASK MASK_BIT6 /* Total Pipe and Cache Empty */ +#define SGA_CTSTAT_RESTARTCNT_MASK 0xFFFF0000 /* Restart Counter */ + + +/*----------------------------------------------------------------------------- + SGA Controller Interrupt register fields description +-----------------------------------------------------------------------------*/ + /*Shift values for Controller status register */ + + + +/*----------------------------------------------------------------------------- + SGA Controller Debug register fields description +-----------------------------------------------------------------------------*/ + /*Shift values for Controller Debug register */ +#define SGA_DEBUG_TPIPE_SHIFT 0 /*Total Pipe Empty bit */ +#define SGA_DEBUG_SPIPE_SHIFT 1 /*Source Pipe Empty bit */ +#define SGA_DEBUG_AHBME_SHIFT 2 /*AHB Master empty bit */ +#define SGA_DEBUG_DDMAFSME_SHIFT 3 /*Destination DMAFSM flows empty bit*/ +#define SGA_DEBUG_SDMAFSME_SHIFT 4 /*Source DMAFSM flows empty bit */ +#define SGA_DEBUG_CACBNK2_SHIFT 5 /*Cache Bank 0 empty bit */ +#define SGA_DEBUG_CACBNK1_SHIFT 6 /*Cache Bank 1 empty bit */ +#define SGA_DEBUG_CACBNK0_SHIFT 7 /*Cache Bank 2 empty bit */ +#define SGA_DEBUG_CACFRMOUT_SHIFT 8 /*Cache Frame out empty bit */ +#define SGA_DEBUG_ADDFRMOUT_SHIFT 9 /*Address operator frame out empty bit */ +#define SGA_DEBUG_DFIFORDE_SHIFT 10 /*Destination FIFO read empty bit */ +#define SGA_DEBUG_PIXOP_SHIFT 11 /*Pixel Operator empty bit */ +#define SGA_DEBUG_SFIFOWRE_SHIFT 12 /*Source FIFO write empty bit*/ +#define SGA_DEBUG_COLCONV_SHIFT 13 /*Colour conversion empty bit*/ +#define SGA_DEBUG_PIXBIL_SHIFT 14 /*Pixel Bilinear Operator Empty bit */ +#define SGA_DEBUG_TRSOP_SHIFT 15 /*Transparency operator empty bit*/ +#define SGA_DEBUG_PIXSER_SHIFT 16 /*Pixel Serialiser Operator Empty bit */ +#define SGA_DEBUG_DEPATEX_SHIFT 17 /*Depacker Texture Empty bit */ +#define SGA_DEBUG_CACHEPE_SHIFT 18 /*Cache Texture empty flow bit */ +#define SGA_DEBUG_ADDTEX_SHIFT 19 /*Address operator texture empty bit */ +#define SGA_DEBUG_XYMOD_SHIFT 20 /*XY Modulo operator empty bit */ +#define SGA_DEBUG_XYROT_SHIFT 21 /*XY Rotation operator empty bit */ +#define SGA_DEBUG_TEXSER_SHIFT 22 /*Texture Serialiser empty bit */ +#define SGA_DEBUG_FFIFORD_SHIFT 23 /*Fifo Read empty bit */ +#define SGA_DEBUG_FFIFOWR_SHIFT 24 /*Fifo Write empty bit */ +#define SGA_DEBUG_DEPTST_SHIFT 25 /*Depth test empty bit */ +#define SGA_DEBUG_DEPACFRM_SHIFT 26 /*DePacker Operator Frame Empty bit */ +#define SGA_DEBUG_CACHFRMIN_SHIFT 27 /*Cache Frame in Empty bit */ +#define SGA_DEBUG_ADDFRMIN_SHIFT 28 /*Address Operator Frame in Empty bit */ +#define SGA_DEBUG_SEGOP_SHIFT 29 /*Segmentation Operator empty bit */ +#define SGA_DEBUG_SCIOP_SHIFT 30 /*Scissor Operator empty bit */ +#define SGA_DEBUG_TRIOPE_SHIFT 31 /*Traingle Operator empty bit */ + + /*Mask values for Controller Debug register */ +#define SGA_DEBUG_TPIPE_MASK MASK_BIT0 /*Total Pipe Empty bit */ +#define SGA_DEBUG_SPIPE_MASK MASK_BIT1 /*Source Pipe Empty bit */ +#define SGA_DEBUG_AHBME_MASK MASK_BIT2 /*AHB Master empty bit */ +#define SGA_DEBUG_DDMAFSME_MASK MASK_BIT3 /*Destination DMAFSM flows empty bit*/ +#define SGA_DEBUG_SDMAFSME_MASK MASK_BIT4 /*Source DMAFSM flows empty bit */ +#define SGA_DEBUG_CACBNK2_MASK MASK_BIT5 /*Cache Bank 0 empty bit */ +#define SGA_DEBUG_CACBNK1_MASK MASK_BIT6 /*Cache Bank 1 empty bit */ +#define SGA_DEBUG_CACBNK0_MASK MASK_BIT7 /*Cache Bank 2 empty bit */ +#define SGA_DEBUG_CACFRMOUT_MASK MASK_BIT8 /*Cache Frame out empty bit */ +#define SGA_DEBUG_ADDFRMOUT_MASK MASK_BIT9 /*Address operator frame out empty bit */ +#define SGA_DEBUG_DFIFORDE_MASK MASK_BIT10 /*Destination FIFO read empty bit */ +#define SGA_DEBUG_PIXOP_MASK MASK_BIT11 /*Pixel Operator empty bit */ +#define SGA_DEBUG_SFIFOWRE_MASK MASK_BIT12 /*Source FIFO write empty bit*/ +#define SGA_DEBUG_COLCONV_MASK MASK_BIT13 /*Colour conversion empty bit*/ +#define SGA_DEBUG_PIXBIL_MASK MASK_BIT14 /*Pixel Bilinear Operator Empty bit */ +#define SGA_DEBUG_TRSOP_MASK MASK_BIT15 /*Transparency operator empty bit*/ +#define SGA_DEBUG_PIXSER_MASK MASK_BIT16 /*Pixel Serialiser Operator Empty bit */ +#define SGA_DEBUG_DEPATEX_MASK MASK_BIT17 /*Depacker Texture Empty bit */ +#define SGA_DEBUG_CACHEPE_MASK MASK_BIT18 /*Cache Texture empty flow bit */ +#define SGA_DEBUG_ADDTEX_MASK MASK_BIT19 /*Address operator texture empty bit */ +#define SGA_DEBUG_XYMOD_MASK MASK_BIT20 /*XY Modulo operator empty bit */ +#define SGA_DEBUG_XYROT_MASK MASK_BIT21 /*XY Rotation operator empty bit */ +#define SGA_DEBUG_TEXSER_MASK MASK_BIT22 /*Texture Serialiser empty bit */ +#define SGA_DEBUG_FFIFORD_MASK MASK_BIT23 /*Fifo Read empty bit */ +#define SGA_DEBUG_FFIFOWR_MASK MASK_BIT24 /*Fifo Write empty bit */ +#define SGA_DEBUG_DEPTST_MASK MASK_BIT25 /*Depth test empty bit */ +#define SGA_DEBUG_DEPACFRM_MASK MASK_BIT26 /*DePacker Operator Frame Empty bit */ +#define SGA_DEBUG_CACHFRMIN_MASK MASK_BIT27 /*Cache Frame in Empty bit */ +#define SGA_DEBUG_ADDFRMIN_MASK MASK_BIT28 /*Address Operator Frame in Empty bit */ +#define SGA_DEBUG_SEGOP_MASK MASK_BIT29 /*Segmentation Operator empty bit */ +#define SGA_DEBUG_SCIOP_MASK MASK_BIT30 /*Scissor Operator empty bit */ +#define SGA_DEBUG_TRIOPE_MASK MASK_BIT31 /*Traingle Operator empty bit */ + + +#endif /* _SGA_IRQP_H_ */ + +/* End of file sga_irqp.h */ + --- /dev/null +++ linux-2.6.20/drivers/video/nomadik/hcl/sga_p.h @@ -0,0 +1,175 @@ +/****************************************************************************** + * Copyright 2007, STMicroelectronics + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + * + * Description : Private Header file of Smart Graphics Accelerator + * module containing interrupts APIs + *****************************************************************************/ +#ifndef _SGA_P_H_ +#define _SGA_P_H_ + +/*--------------------------------------------------------------------------* + * Includes * + *--------------------------------------------------------------------------*/ +#include "debug.h" +#include "hcl_defs.h" +#include "sga_irqp.h" +#ifdef __cplusplus +extern "C" +{ +#endif + +/*--------------------------------------------------------------------------* + * Constants and new types * + *--------------------------------------------------------------------------*/ + +/* Defining the instrunctions opcodes */ + +#define STOP 0 +#define GOTO 0x20000000 +#define GOSUB 0x40000000 +#define NO_OP 0x60000000 +#define RETURN 0x61000000 +#define WAIT_SYNCHRO 0x80000000 +#define WAIT_NEW_SYNCHRO 0x81000000 +#define WAIT_PIPE_EMPTY 0x82000000 +#define WAIT_N_CYCLES 0x83000000 +#define SEND_SYNCHRO 0x84000000 +#define SEND_INTERRUPT 0x85000000 +#define AHB 0x86000000 +#define CACHE_CTRL 0x87000000 +#define SET_INSTR_TEST_REG 0x88000000 +#define CLR_INSTR_TEST_REG 0x89000000 +#define TST_INSTR_TEST_REG 0x8A000000 +#define WAIT_INSTR_TEST_REG 0x8B000000 + +#define IN0_BASE_ADD_MSB 0xA0000000 +#define IN0_BASE_ADD 0xA1000000 +#define IN0_SET_LINE_JUMP 0xA2000000 +#define IN0_SET_SIZE_XY 0xA3000000 +#define IN0_SET_DELTA_XY 0xA4000000 +#define IN0_SET_PIXEL_TYPE 0xA5000000 + +#define IN1_BASE_ADD_MSB 0xA8000000 +#define IN1_BASE_ADD 0xA9000000 +#define IN1_SET_LINE_JUMP 0xAA000000 +#define IN1_SET_SIZE_XY 0xAB000000 +#define IN1_SET_DELTA_XY 0xAC000000 +#define IN1_SET_PIXEL_TYPE 0xAD000000 + + +#define IN2_BASE_ADD_MSB 0xB0000000 +#define IN2_BASE_ADD 0xB1000000 +#define IN2_SET_LINE_JUMP 0xB2000000 +#define IN2_SET_SIZE_XY 0xB3000000 +#define IN2_SET_DELTA_XY 0xB4000000 +#define IN2_SET_PIXEL_TYPE 0xB5000000 + +#define OUT_BASE_ADD_MSB 0xB8000000 +#define OUT_BASE_ADD 0xB9000000 +#define OUT_SET_LINE_JUMP 0xBA000000 +#define OUT_SET_SIZE_XY 0xBB000000 +#define OUT_SET_BASE_XY 0xBC000000 +#define OUT_SET_PIXEL_TYPE 0xBD000000 + + +#define SET_POINT0 0xC0000000 +#define SET_POINT1 0xC1000000 +#define SET_POINT2 0xC2000000 +#define SET_COLOR 0xC3000000 +#define SET_BYPASS_ZS 0xC4000000 +#define LINE_STIPPLING 0xC5000000 +#define DRAW_RECTANGLE 0xC6000000 +#define DRAW_TRIANGLE 0xC7000000 +#define DRAW_LINE 0xC8000000 +#define DRAW_POINT 0xC9000000 +#define DRAW_TRIANGLE_SHIFT 0xCA000000 +#define DRAW_LINE_SHIFT 0xCB000000 + +#define SET_ZX_COEF 0xCC000000 +#define SET_ZY_COEF 0xCD000000 +#define SET_Z_OFFSET 0xCE000000 +#define SET_Z_DYN 0xCF000000 + +#define SET_XX_COEF 0xD0000000 +#define SET_XY_COEF 0xD1000000 +#define SET_YX_COEF 0xD2000000 +#define SET_YY_COEF 0xD3000000 +#define SET_WX_COEF 0xD4000000 +#define SET_WY_COEF 0xD5000000 +#define SET_X_OFFSET 0xD6000000 +#define SET_Y_OFFSET 0xD7000000 +#define SET_W_OFFSET 0xD8000000 +#define SET_XY_MODE 0xD9000000 +#define SET_XY_DYN 0xDA000000 + +#define TRANSP_COLORMSB 0xE0000000 +#define TRANSP_IN_COLOR 0xE1000000 +#define TRANSP_OUT_COLOR 0xE2000000 +#define TRANSP_MODE 0xE3000000 + +#define FLASH_COLOR_MSB 0xE4000000 +#define FLASH_COLOR_ID 0xE5000000 +#define FLASH_COLOR_NEW 0xE6000000 +#define FLASH_MODE 0xE7000000 + +#define SET_COEF_AXAY 0xE8000000 +#define SET_COEF_A0 0xE9000000 +#define SET_COEF_RXRY 0xEA000000 +#define SET_COEF_R0 0xEB000000 +#define SET_COEF_GXGY 0xEC000000 +#define SET_COEF_G0 0xED000000 +#define SET_COEF_BXBY 0xEE000000 +#define SET_COEF_B0 0xEF000000 +#define SET_COEF_DYN 0xF0000000 + +#define SET_TEX_COLORMSB 0xF1000000 +#define SET_TEX_COLORLSB 0xF2000000 +#define SET_TEX_ENV_MSB 0xF3000000 +#define SET_TEX_ENN_LSB 0xF4000000 +#define SET_TEX_SCALE 0xF5000000 +#define SET_COEF_FXFY 0xF6000000 +#define SET_COEF_F0 0xF7000000 +#define SET_COLOR_F0 0xF8000000 +#define SET_BLEND_COLORMSB 0xF9000000 +#define SET_BLEND_ENV 0xFA000000 + +#define PIXEL_OP_MODE 0xFB000000 + +#define SET_ALPHA_TEST 0xFC000000 +#define SET_STENCIL_TEST 0xFD000000 +#define SET_DEPTH_TEST 0xFE000000 + +typedef struct +{ + /*contain the SGA memory mapped registers address */ + t_sga_registers *p_sga_registers; + /*store the all interrupt resource availability status */ + t_uint32 interrupt_id; + /*store the all batch id and semaphore id resources availability status */ + t_uint32 batch_sem_id; + /*contain the main batch firmware memory physical address */ + t_uint32* p_main_batch_add; + /*contain the main batch firmware memory address */ + t_uint32* p_logical_main_batch_add; + /*contain the default batch firmware memory address */ + t_uint32* p_default_batch_add; +}t_sga_system_context; + + +#ifdef __cplusplus +} /* allow C++ to use these headers */ +#endif /* __cplusplus */ +#endif /* _SGA_H_ */ + --- /dev/null +++ linux-2.6.20/drivers/video/nomadik/sga_defs.h @@ -0,0 +1,87 @@ +/******************************************************************************* +** Copyright 2007, STMicroelectronics +** This program is free software; you can redistribute it and/or modify +** it under the terms of the GNU General Public License as published by +** the Free Software Foundation; either version 3 of the License, or +** (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program. If not, see . +** +** +** MODULE : SGA Device Driver +** +** FILE : sga_defs.h +** +** DESCRIPTION : Contains all the constants, macros, registers, bitmasks and +** enumerated types. +** +** NOTES : +** +*******************************************************************************/ + + +#ifndef _SGA_DEFS_H +#define _SGA_DEFS_H + +/* following define is for command parser usage */ +#define SGA_DRV_VERSION "rel_1_5" + +//----------------------------------------------------------------------------- +// Set the BLOCKING_TASKRUN_IOCTL define below if the ioctl should sleep until +// the task is complete. If the start batch ioctl should return even if +// the task is not completed, then BLOCKING_TASKRUN_IOCTL should be undefined. +#define BLOCKING_TASKRUN_IOCTL + +//----------------------------------------------------------------------------- +// Set the ENABLE_SGA_INTERRUPTS define below if SGA interrupts are to be +// enabled in the driver. If only status of raw interrupts is to be checked +// from the library (user level polling), this should remain undefined. +//#define ENABLE_SGA_INTERRUPTS + +/******************************************************************************/ +/* COMMONLY USED CONSTANTS */ +/******************************************************************************/ + +/* Major number of the device */ +#define SGA_MAJOR_NUM 0 + +// Number of devices +#ifndef SGADEV_COUNT +#define SGADEV_COUNT 1 +#endif + +// Name of the sga driver +#ifndef SGADEV_NAME +#define SGADEV_NAME "SGA" +#endif + +// First minor number +#ifndef SGADEV_MINOR_START +#define SGADEV_MINOR_START 0 +#endif + +#define RST_COUNTER 0xFFFFFFF + +#ifndef MAX_BATCHES + #define MAX_BATCHES 16 +#endif + +#define NPAGES 16*8 +#define TRUE 1 +#define FALSE 0 + + + +/* Device ID constants */ + +/******************************************************************************/ +/* ENUMERATED TYPES */ +/******************************************************************************/ + +#endif /* _SGA_DEFS_H */ --- /dev/null +++ linux-2.6.20/drivers/video/nomadik/sga_err.h @@ -0,0 +1,45 @@ +/******************************************************************************* +** Copyright 2007, STMicroelectronics +** This program is free software; you can redistribute it and/or modify +** it under the terms of the GNU General Public License as published by +** the Free Software Foundation; either version 3 of the License, or +** (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program. If not, see . +** +** MODULE : SGA Device Driver +** +** FILE : sga_err.h +** +** DESCRIPTION : Defines all the error codes returned by the SGA driver +** +** NOTES : The user should modify SGA_ERR_BASE so that the error code +** values do not overlap those of any other module +** +*******************************************************************************/ + +#ifndef _SGA_ERR_H +#define _SGA_ERR_H + +/* modify this so that SGA error codes do not overlap other error codes */ +#define SGA_ERR_BASE (-100) + +typedef enum { + SGA_SUCCESS = 0, + SGA_ERR_IOCTL = -1, + SGA_FAILURE = SGA_ERR_BASE, + SGA_ERR_MEM_ALLOC, + SGA_ERR_INVALID_ARG, + SGA_ERR_INVALID_DEV, + SGA_ERR_INVALID_DBG_LEVEL, + SGA_ERR_NOTINITIALIZED, + SGA_FAILURE_OPEN, +}t_sgadrv_err; + +#endif /* _SGA_ERR_H */ --- /dev/null +++ linux-2.6.20/drivers/video/nomadik/sga_interface.h @@ -0,0 +1,119 @@ +/****************************************************************************** + * Copyright 2007, STMicroelectronics + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + * + * Subsystem : SGA Device Driver + * Module : Ioctl structures and API command list + * File : sga_interface.h + * Description : This file contains the hash defines for ioctl + * commands as well as the structures used by the + * application files to call the kernel functions. + * See Help block below. + * Author : Anand Bodas + * Dept. : ST/HPC + * Created : 09.04.2007 + * Version : 0.2 + * Revision history : + * 09.04.2007 : Anand Bodas - Created + * 17.05.2007 : Anand Bodas - Removed unnecessary ioctls + * 31.08.2007 : Anand Bodas - Cleanup and comments + * + *****************************************************************************/ +/*********************** HELP BLOCK ******************************** +* +* The commands defined in this file are called from the Application through +* ioctl calls with required parameters. The parameters will be passed through +* the union of individual structures. Before calling each command, it is +* required to fill the necessary fields of the required data structures. All +* the required structures are declared here. The union variable type can be +* made in application and the same can be used to pass the data. +* +************************ END of HELP BLOCK ********************************/ + +#ifndef __SGA_IOCTL_HEADER_SGA__ +#define __SGA_IOCTL_HEADER_SGA__ + +#include "hcl/sga.h" // for structure definitions +#include "hcl/sga_irq.h" // for structure definitions +#include "sga_typs.h" +#include "sga_defs.h" +#include "sga_err.h" + +#define SGA_COMMAND_NUMBER 0 + +/* Enum containing the list of all ioctl commands */ +typedef enum SGA_ioctl_e +{ + SGA_RESET = SGA_COMMAND_NUMBER, // to reset SGA + SGA_INITIALIZE, // to initialize sga and setup and run main fw + SGA_GETSTATUS, // to get status of SGA + SGA_GETSTATISTICS, // to get statistics of SGA + SGA_LINKBATCH, // required if batch has not been linked + SGA_STARTBATCH, // to start execution + SGA_MAX_IOCTL_CMD +}SGA_IOCTL_E; + +// enum identifying memory to map +enum { + FW_MEMORY = 0, + SHM_MEMORY, + DEV_MEMORY +}; + +enum { + SGALIB_BATCH = 0, + OGLLIB_BATCH +}; + +/* Enum containing the list of structures */ +typedef struct _sSGA_NoParam +{ + UINT4 result; +} +SGA_NoParam_T; + +typedef struct _sSGA_Batch +{ + UINT1 batch_id; + UINT1 batch_type; + UINT4 batch_addr; + UINT4 result; +} +SGA_Batch_T; + +typedef struct _sSGA_Status +{ + t_sga_status status; + UINT4 value; + UINT4 result; +} +SGA_Status_T; + +typedef struct _sSGA_Statistics +{ + t_sga_statistics_req statistics; + UINT4 value; + UINT4 result; +} +SGA_Statistics_T; + +typedef struct _sSGA_TaskCounts_T +{ + INT4 task_allocated_count; + INT4 task_complete_count; +} +SGA_TaskCounts_T; + +#endif // __SGA_IOCTL_HEADER_SGA__ + --- /dev/null +++ linux-2.6.20/drivers/video/nomadik/sga_ioctlfns.c @@ -0,0 +1,473 @@ +/****************************************************************************** + * Copyright 2007, STMicroelectronics + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + * + * Subsystem : SGA Device Driver + * Module : Fops structure operations + * File : sga_ioctlfns.c + * Description : This file contains the various ioctl that the sga + * driver supports. + * Author : Anand Bodas + * Dept. : ST/HPC + * Created : 09.04.2007 + * Version : 0.4 + * Revision history : + * 09.04.2007 : Anand Bodas - Created + * 17.05.2007 : Anand Bodas - Removed unnecessary ioctls + * 21.05.2007 : Anand Bodas - Aligned with 2.6 calls + * 23.05.2007 : Anand Bodas - Code cleanup + * 01.06.2007 : Anand Bodas - First level performance optimization + * 31.08.2007 : Anand Bodas - Cleanup and comments + * + *****************************************************************************/ + +/////////////////////////////////////////////////////////////////////////////// +// Include files +/////////////////////////////////////////////////////////////////////////////// + +#include "sga_main.h" +#include "sga_interface.h" +#include "sga_ioctlfns.h" + +/////////////////////////////////////////////////////////////////////////////// +// Globals - definitions +/////////////////////////////////////////////////////////////////////////////// +extern unsigned int clcd_phy_start; + +// internal functions limited only to this file. +static UINT4 Addr_Translate_V2P(SGA_Dev_T *pSD, UINT4 virt); +static UINT4 SGA_Initialize(SGA_Dev_T *pSD); +/////////////////////////////////////////////////////////////////////////////// +// Function implementations +/////////////////////////////////////////////////////////////////////////////// + +/****************************************************************************** +* +* SGA_Drv_Reset +* ___________________________________________________________________________ +* +* DESCRIPTION: This functions resets SGA device. +* +* INPUTS: pSD : Pointer to device specific private data +* arg : SGA_NoParam_T type for passing result to caller +* +* OUTPUTS: arg : SGA_NoParam_T type for passing result to caller +* +* RETURNS: SGA_SUCCESS on success and SGA_ERR_IOCTL on failure. +* data.result contains error from one of t_sgadrv_err. +* +* REMARKS: After this function, device needs to be initialized before a +* batch can be run on it. +* +******************************************************************************/ +UINT4 SGA_Drv_Reset(SGA_Dev_T *pSD, unsigned long arg) +{ + SGA_NoParam_T data; + + if (!access_ok(VERIFY_WRITE, (void __user *)arg, sizeof(SGA_NoParam_T) + )) { + data.result = SGA_ERR_INVALID_ARG; + return SGA_ERR_IOCTL; + } + + copy_from_user((void*)&data,(void*)arg,sizeof(SGA_NoParam_T)); + + SGA_Reset(); + data.result = SGA_SUCCESS; + pSD->init_flag = 0; // reset the SGA initialized flag + + copy_to_user((void*)arg,(void*)&data,sizeof(SGA_NoParam_T)); + + return SGA_SUCCESS; +} + +/****************************************************************************** +* +* SGA_Drv_Initialize +* ___________________________________________________________________________ +* +* DESCRIPTION: This functions initializes the SGA device. +* +* INPUTS: pSD : Pointer to device specific private data +* arg : SGA_NoParam_T type for passing result to caller +* +* OUTPUTS: arg : SGA_NoParam_T type for passing result to caller +* +* RETURNS: SGA_SUCCESS on success and SGA_ERR_IOCTL on failure. +* data.result contains error from one of t_sgadrv_err. +* +* REMARKS: None +* +******************************************************************************/ +UINT4 SGA_Drv_Initialize(SGA_Dev_T *pSD, unsigned long arg) +{ + SGA_NoParam_T data; + t_sga_error sga_error; + + if (!access_ok(VERIFY_WRITE, (void __user *)arg, sizeof(SGA_NoParam_T) + )) { + data.result = SGA_ERR_INVALID_ARG; + return SGA_ERR_IOCTL; + } + + copy_from_user((void*)&data,(void*)arg,sizeof(SGA_NoParam_T)); + + sga_error = SGA_Initialize(pSD); + if (sga_error == SGA_OK) + data.result = SGA_SUCCESS; + + copy_to_user((void*)arg,(void*)&data,sizeof(SGA_NoParam_T)); + + if (data.result!= SGA_SUCCESS) { + return SGA_ERR_IOCTL; + } + return SGA_SUCCESS; +} + +/****************************************************************************** +* +* SGA_Drv_GetStatus +* ___________________________________________________________________________ +* +* DESCRIPTION: This functions gets status of the SGA device. +* +* INPUTS: pSD : Pointer to device specific private data +* arg : SGA_Status_T type for passing result and status +* +* OUTPUTS: arg : SGA_Status_T type for passing result and status +* +* RETURNS: SGA_SUCCESS on success and SGA_ERR_IOCTL on failure. +* data.result contains error from one of t_sgadrv_err. +* +* REMARKS: None +* +******************************************************************************/ +UINT4 SGA_Drv_GetStatus(SGA_Dev_T *pSD, unsigned long arg) +{ + SGA_Status_T data; + + if (!access_ok(VERIFY_WRITE, (void __user *)arg, sizeof(SGA_Status_T) + )) { + data.result = SGA_ERR_INVALID_ARG; + return SGA_ERR_IOCTL; + } + + copy_from_user((void*)&data,(void*)arg,sizeof(SGA_Status_T)); + + data.value = SGA_GetStatus(data.status); + data.result = SGA_SUCCESS; + + copy_to_user((void*)arg,(void*)&data,sizeof(SGA_Status_T)); + + return SGA_SUCCESS; +} + +/****************************************************************************** +* +* SGA_Drv_GetStatistics +* ___________________________________________________________________________ +* +* DESCRIPTION: This functions gets status of the SGA device. +* +* INPUTS: pSD : Pointer to device specific private data +* arg : SGA_Statistics_T identifying type of statistics +* +* OUTPUTS: arg : SGA_Statistics_T type for passing result +* and statistics to caller +* +* RETURNS: SGA_SUCCESS on success and SGA_ERR_IOCTL on failure. +* data.result contains error from one of t_sgadrv_err. +* +* REMARKS: None +* +******************************************************************************/ +UINT4 SGA_Drv_GetStatistics(SGA_Dev_T *pSD, unsigned long arg) +{ + SGA_Statistics_T data; + + if (!access_ok(VERIFY_WRITE, (void __user *)arg, + sizeof(SGA_Statistics_T))) { + data.result = SGA_ERR_INVALID_ARG; + return SGA_ERR_IOCTL; + } + + copy_from_user((void*)&data,(void*)arg,sizeof(SGA_Statistics_T)); + + data.value = SGA_GetStatistics(data.statistics); + data.result = SGA_SUCCESS; + + copy_to_user((void*)arg,(void*)&data,sizeof(SGA_Statistics_T)); + + return SGA_SUCCESS; +} + +/****************************************************************************** +* +* SGA_Drv_LinkBatch +* ___________________________________________________________________________ +* +* DESCRIPTION: This functions links a batch to the main fw +* +* INPUTS: pSD : Pointer to device specific private data +* arg : SGA_Batch_T type for passing batch id +* +* OUTPUTS: arg : SGA_Batch_T type for passing result +* +* RETURNS: SGA_SUCCESS on success and SGA_ERR_IOCTL on failure. +* data.result contains error from one of t_sgadrv_err. +* +* REMARKS: This is a prerequisite for running a batch on the SGA. +* +******************************************************************************/ +UINT4 SGA_Drv_LinkBatch(SGA_Dev_T *pSD, unsigned long arg) +{ + SGA_Batch_T data; + UINT4 *inst_addr, sga_error; + + if (!access_ok(VERIFY_WRITE, (void __user *)arg, sizeof(SGA_Batch_T) + )) { + data.result = SGA_ERR_INVALID_ARG; + return SGA_ERR_IOCTL; + } + + copy_from_user((void*)&data,(void*)arg,sizeof(SGA_Batch_T)); + + if (!pSD->init_flag) { + data.result = SGA_ERR_NOTINITIALIZED; + } else + + { + if(data.batch_type == SGALIB_BATCH) + { + inst_addr = (UINT4 *)Addr_Translate_V2P(pSD, data.batch_addr); + if (!inst_addr) { + data.result = SGA_ERR_INVALID_ARG; + } + } + else + { + if ((0 == data.batch_id)||(1 == data.batch_id)) + inst_addr = data.batch_addr; + else + return SGA_ERR_IOCTL; + } + + sga_error = SGA_LinkBatch(data.batch_id, inst_addr); + if (sga_error == SGA_OK) + data.result = SGA_SUCCESS; + else + data.result = SGA_FAILURE; + + } + copy_to_user((void*)arg,(void*)&data,sizeof(SGA_Batch_T)); + + if (data.result!= SGA_SUCCESS) { + return SGA_ERR_IOCTL; + } + + return SGA_SUCCESS; +} + +/****************************************************************************** +* +* SGA_Drv_StartBatch +* ___________________________________________________________________________ +* +* DESCRIPTION: This functions schedules a batch to run on the SGA +* +* INPUTS: pSD : Pointer to device specific private data +* arg : SGA_Batch_T type for passing batch id +* +* OUTPUTS: arg : SGA_Batch_T type for passing result +* +* RETURNS: SGA_SUCCESS on success and SGA_ERR_IOCTL on failure. +* data.result contains error from one of t_sgadrv_err. +* +* REMARKS: Batch should be linked before it can be started. Should onle be +* used when interrupts are enabled for SGA. +* +******************************************************************************/ +UINT4 SGA_Drv_StartBatch(SGA_Dev_T *pSD, unsigned long arg) +{ + SGA_Batch_T data; + UINT4 sga_error; + + if (!access_ok(VERIFY_WRITE, (void __user *)arg, sizeof(SGA_Batch_T) + )) { + data.result = SGA_ERR_INVALID_ARG; + return SGA_ERR_IOCTL; + } + + copy_from_user((void*)&data,(void*)arg,sizeof(SGA_Batch_T)); + + if (!pSD->init_flag) { + data.result = SGA_ERR_NOTINITIALIZED; + } else { + pSD->sga_interruptflag = 0; + sga_error = SGA_StartBatch(data.batch_id); + if (sga_error == SGA_OK) { + data.result = SGA_SUCCESS; +#ifdef BLOCKING_TASKRUN_IOCTL + wait_event_interruptible(pSD->SGAPollQ, + (pSD->sga_interruptflag != 0)); + pSD->sga_interruptflag = 0; +#endif + } + else + data.result = SGA_FAILURE; + } + copy_to_user((void*)arg,(void*)&data,sizeof(SGA_Batch_T)); + + if (data.result!= SGA_SUCCESS) { + return SGA_ERR_IOCTL; + } + + return SGA_SUCCESS; +} + +/////////////////////////////////////////////////////////////////////////////// +// SGA Driver Internal Functions +/////////////////////////////////////////////////////////////////////////////// + + +/****************************************************************************** +* +* Addr_Translate_V2P +* ___________________________________________________________________________ +* +* DESCRIPTION: This functions schedules a batch to run on the SGA +* +* INPUTS: pSD : Pointer to device specific private data +* virt : Virtual address to be translated +* +* OUTPUTS: None +* +* RETURNS: Physical address. Returns NULL if argument is invalid. +* +* REMARKS: This function only works for memories allocated by SGA +* +******************************************************************************/ +static UINT4 Addr_Translate_V2P(SGA_Dev_T *pSD, UINT4 virt) +{ + UINT4 mem_start, mem_end; + + mem_start = (UINT4)pSD->fw_mem_virt; + mem_end = mem_start + PAGE_SIZE * NPAGES - 1; + if ((mem_start <= virt ) && (virt <= mem_end)) { + return ((UINT4)pSD->fw_mem_phy + (virt - mem_start)); + } + return NULL; +} + +/****************************************************************************** +* +* SGA_Initialize +* ___________________________________________________________________________ +* +* DESCRIPTION: This functions initializes the SGA, builds the main fw and runs +* it. It also enables interrupts for all the batches that can run +* on the SGA. +* +* INPUTS: pSD : Pointer to device specific private data +* +* OUTPUTS: None. +* +* RETURNS: Translated Physical address. NULL if argument is invalid. +* +* REMARKS: This is required in order to run any batch on the SGA. It also +* sets a flag to indicate device initialized state. +* +******************************************************************************/ +static UINT4 SGA_Initialize(SGA_Dev_T *pSD) +{ + t_sga_error sga_error; + t_sga_device_config dev_config; +#ifdef ENABLE_SGA_INTERRUPTS + t_sga_irq_src irq_src; + t_sga_int_to_core core; +#endif + unsigned int size; + UINT4 *virt_maininst_addr, *virt_defbatch_addr; + UINT4 *phy_maininst_addr, *phy_defbatch_addr; + + dev_config.int_mode1 = (t_bool) FALSE; + dev_config.hclk_en = (t_bool) FALSE; + dev_config.fclk_en = (t_bool) FALSE; + dev_config.int_mode0 = (t_bool) FALSE; + + sga_error = SGA_SetDeviceConfig(&dev_config); + if (sga_error != SGA_OK) + return sga_error; +#ifdef ENABLE_SGA_INTERRUPTS + core = SGA_INT_TO_ARM; + irq_src = + SGA_IRQ_SRC_INT_0|SGA_IRQ_SRC_INT_1|SGA_IRQ_SRC_INT_2|\ + SGA_IRQ_SRC_INT_3|SGA_IRQ_SRC_INT_4|SGA_IRQ_SRC_INT_5|\ + SGA_IRQ_SRC_INT_6|SGA_IRQ_SRC_INT_7|SGA_IRQ_SRC_INT_8|\ + SGA_IRQ_SRC_INT_9|SGA_IRQ_SRC_INT_10|SGA_IRQ_SRC_INT_11|\ + SGA_IRQ_SRC_INT_12|SGA_IRQ_SRC_INT_13|SGA_IRQ_SRC_INT_14|\ + SGA_IRQ_SRC_INT_15|SGA_IRQ_SRC_INT_16|SGA_IRQ_SRC_INT_17|\ + SGA_IRQ_SRC_INT_18|SGA_IRQ_SRC_INT_19|SGA_IRQ_SRC_INT_20|\ + SGA_IRQ_SRC_INT_21|SGA_IRQ_SRC_INT_22|SGA_IRQ_SRC_INT_23|\ + SGA_IRQ_SRC_INT_24|SGA_IRQ_SRC_INT_25; + + SGA_EnableIRQSrc(core, irq_src); +#endif + virt_maininst_addr = (UINT4 *)(pSD->fw_kvmem_base + NPAGES*PAGE_SIZE); + virt_defbatch_addr = + (UINT4 *)((unsigned long)pSD->fw_kvmem_base + \ + (NPAGES + 1) * PAGE_SIZE); + phy_maininst_addr = (UINT4 *)(pSD->fw_mem_phy + NPAGES * PAGE_SIZE); + phy_defbatch_addr = (UINT4 *)((unsigned long)pSD->fw_mem_phy + \ + (NPAGES + 1) * PAGE_SIZE); + + sga_error = SGA_BuildMainBatchFirmware(phy_maininst_addr, \ + virt_maininst_addr, \ + phy_defbatch_addr, \ + virt_defbatch_addr, \ + (t_uint32 *)&size); + if (sga_error != SGA_OK) + return sga_error; + + sga_error = SGA_RunMainBatchFirmware(); + if (sga_error != SGA_OK) + return sga_error; + + pSD->init_flag = 1; + + return SGA_OK; +} + +/****************************************************************************** +* +* dbg_printk +* ___________________________________________________________________________ +* +* DESCRIPTION: Used to disable printk's for release version +* +* INPUTS: same as printk +* +* OUTPUTS: None +* +* RETURNS: Nothing +* +* REMARKS: None +* +******************************************************************************/ +int dbg_printk(const char *format, ...) +{ + return NULL; +} + +// end of sga_ioctlfns.c --- /dev/null +++ linux-2.6.20/drivers/video/nomadik/sga_ioctlfns.h @@ -0,0 +1,50 @@ +/****************************************************************************** + * Copyright 2007, STMicroelectronics + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + * + * Subsystem : SGA Device Driver + * Module : Ioctl function declarations + * File : sga_ioctlfns.h + * Description : This file contains the ioctl function declarations that are + * used by the applications. The definition of all the functions + * is present in sga_ioctlfns.c. It also contains the internal + * data structures to the driver. + * Author : Anand Bodas + * Dept. : ST/HPC + * Created : 05.04.2007 + * Version : 0.1 + * Revision history : + * 05.04.2007 : Anand Bodas - Created + * 31.08.2007 : Anand Bodas - Cleanup and comments + * + *****************************************************************************/ + + +#ifndef SGA_IOCTL_FUNC_H_SGA_ +#define SGA_IOCTL_FUNC_H_SGA_ + +UINT4 SGA_Drv_Reset(SGA_Dev_T *pSD, unsigned long arg); +UINT4 SGA_Drv_Initialize(SGA_Dev_T *pSD, unsigned long arg); + +UINT4 SGA_Drv_GetStatus(SGA_Dev_T *pSD, unsigned long arg); +UINT4 SGA_Drv_GetStatistics(SGA_Dev_T *pSD, unsigned long arg); + +UINT4 SGA_Drv_LinkBatch(SGA_Dev_T *pSD, unsigned long arg); +UINT4 SGA_Drv_StartBatch(SGA_Dev_T *pSD, unsigned long arg); + + + + +#endif + --- /dev/null +++ linux-2.6.20/drivers/video/nomadik/sga_main.c @@ -0,0 +1,651 @@ +/****************************************************************************** + * Copyright 2007, STMicroelectronics + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + * + * Subsystem : SGA Device Driver + * Module : Fops structure operations + * File : sga_main.c + * Description : This file contains the various basic operations that + * a driver can perform. + * on the device. + * Author : Anand Bodas + * Dept. : ST/HPC + * Created : 05.04.2007 + * Version : 0.4 + * Revision histor + * 05.04.2007 : Anand Bodas - Created + * 17.05.2007 : Anand Bodas - Removed unnecessary ioctls + * 21.05.2007 : Anand Bodas - Aligned with 2.6 calls + * 24.05.2007 : Anand Bodas - Code cleanup + * 01.06.2007 : Anand Bodas - First level performance optimization + * 31.08.2007 : Anand Bodas - Cleanup and comments + * + *****************************************************************************/ + +/////////////////////////////////////////////////////////////////////////////// +// Include files +/////////////////////////////////////////////////////////////////////////////// + +#include "sga_main.h" +#include "sga_interface.h" +#include "sga_ioctlfns.h" + + +/* Module information */ +MODULE_LICENSE("LGPL"); +MODULE_AUTHOR("Anand Bodas"); +MODULE_DESCRIPTION("SGA Device Driver Module"); +MODULE_SUPPORTED_DEVICE("none"); + +/////////////////////////////////////////////////////////////////////////////// +// Globals - definitions +/////////////////////////////////////////////////////////////////////////////// + +/* Wait Queue Declaration */ +static SGA_Dev_T *pSga_device; // Contains the sga devices +static dev_t dev; // Contains major and first minor number + +/* Ioctl Commands Function Pointer and Array */ + +typedef unsigned long (*FUNCPTR) (SGA_Dev_T * , unsigned long); + +/* This array contains the function pointers to all the commands that are + supported by the SGA driver. Note that the position of the funciton pointers + in the array is consistent with the position of the commands in the enum of + SGAAPI_Interface.h file + */ +FUNCPTR SGA_ioctl_array[SGA_MAX_IOCTL_CMD] = + { + SGA_Drv_Reset, + SGA_Drv_Initialize, + SGA_Drv_GetStatus, + SGA_Drv_GetStatistics, + SGA_Drv_LinkBatch, + SGA_Drv_StartBatch, + }; + +struct device *nomadik_get_sgadevice(void); + +/////////////////////////////////////////////////////////////////////////////// +// Function implementations +/////////////////////////////////////////////////////////////////////////////// + +/****************************************************************************** +* +* sga_interrupt_handler +* ___________________________________________________________________________ +* +* DESCRIPTION: This function is the interrupt handler for SGA device +* +* INPUTS: irq : interrupt +* dev_id : private, device specific data +* regs : not used +* +* OUTPUTS: Updates dev_id->sga_interruptmask with the interrupt sources +* +* RETURNS: IRQ_HANDLED +* +* REMARKS: None +* TBD --> need to handle SGA_INT_TO_MMDSP for synchronization +* --> need to disable/reenable interrupts and do queuing +* --> need to use msg queues for communication +* +******************************************************************************/ +static irqreturn_t sga_interrupt_handler(int irq, void *dev_id, + struct pt_regs *regs) +{ + t_sga_irq_src sga_irq_src; + SGA_Dev_T *pSD = dev_id; + int count = 0; + + int *pCount = (int *)pSD->shm_kvmem_base ; + + pCount++; + + if (NULL == pSD) + { + return SGA_ERR_INVALID_DEV; + } + + pSD->sga_interruptflag = 1; + + sga_irq_src = SGA_GetIRQSrc(SGA_INT_TO_ARM); + + SGA_ClearIRQSrc(sga_irq_src); + +#ifndef BLOCKING_TASKRUN_IOCTL + //check how many interrupts are present + for(i = 0; i < 32; i++) { + count += (sga_irq_src >> i) & 1; + } +#else + count = 1; + + pSD->sga_interruptcount += count; + + if(RST_COUNTER == pSD->sga_interruptcount) { + pSD->sga_interruptcount = 0; // restart condition + } + + *pCount = pSD->sga_interruptcount; + +#ifdef BLOCKING_TASKRUN_IOCTL + pSD->sga_interruptmask |= sga_irq_src; + + if (waitqueue_active((wait_queue_head_t *)&pSD->SGAPollQ)) + { + wake_up_interruptible((wait_queue_head_t *)&pSD->SGAPollQ); + } +#endif +#endif + return IRQ_HANDLED; +} + + +/****************************************************************************** +* +* SGA_open +* ___________________________________________________________________________ +* +* DESCRIPTION: This function is used to open a device for later operations. +* This function internally increments the usuage count and also +* identifies the minor number of the device. It stores the +* private data for future use. +* +* INPUTS: inode : pointer to get cdev structure +* filp : (pointer to) file descriptor of device +* +* OUTPUTS: None +* +* RETURNS: SGA_SUCCESS on success and SGA_FAILURE on failure. +* +* REMARKS: Only one instance of the SGA driver is allowed. +* +******************************************************************************/ +int SGA_open(struct inode *inode, struct file *filp) +{ + UINT2 minor; + SGA_Dev_T *pSD; + + // This macro takes a pointer to a field of type 'container_field', + // within a strcture of type 'container_type' and returns a pointer + // to the containing structure. + pSD = container_of(inode->i_cdev, SGA_Dev_T, cdev); + // Store the pointer for future access + filp->private_data = pSD; + minor = MINOR(filp->f_dentry->d_inode->i_rdev); + + if (pSD->sga_instance) + { + ERR_PRINTK("ERROR! Instance already open\n"); + return SGA_FAILURE_OPEN; + } + + if (SGA_OK != SGA_Init(IO_ADDRESS(NOMADIK_SGA_BASE))) + { + ERR_PRINTK("ERROR! in SGA Initialisation\n"); + return SGA_FAILURE; + } + + SGA_SetBaseAddress(IO_ADDRESS(NOMADIK_SGA_BASE)); + + printk("SGA Device Successfully opened with Minor num = %d\n",minor); + pSD->sga_interruptcount = 0; + pSD->sga_instance++; + return SGA_SUCCESS; +} + +/****************************************************************************** +* +* SGA_close +* ___________________________________________________________________________ +* +* DESCRIPTION: This function deallocates all resources allocated by the +* SGA_open function. It decrements the usuage count +* internally and shuts down the device on last close. +* +* INPUTS: inode : inode pointer +* filp : (pointer to) file descriptor of device +* +* OUTPUTS: None +* +* RETURNS: SGA_SUCCESS on success else return SGA_ERR_INVALID_DEV +* +* REMARKS: Only one instance of the SGA driver is allowed. +* +******************************************************************************/ +int SGA_close(struct inode *inode, struct file *filp) +{ + SGA_Dev_T *pSD = filp->private_data; + + printk("Closing the SGA device \n"); + + if (!pSD->sga_instance) + return SGA_ERR_INVALID_DEV; + pSD->sga_interruptcount = 0; + pSD->sga_instance--; + return SGA_SUCCESS; +} + +/****************************************************************************** +* +* SGA_Poll +* ___________________________________________________________________________ +* +* DESCRIPTION: This function is called whenever the use-space program performs +* a poll system call. It is used to poll for interrupts. +* +* +* INPUTS: filp : (pointer to) file descriptor of device +* wait : (pointer to) the poll_table within the kernel +* +* +* OUTPUTS: None +* +* RETURNS: On success, a positive number is returned, where the number +* returned indicates the number of structures which have non-zero +* events fields (in other words, those descriptors with events +* or errors reported). A value of 0 indicates that the call +* timed out and no file descriptors have been selected. +* On error, -1 is returned. +* +* REMARKS: None +* +******************************************************************************/ +static unsigned int SGA_Poll(struct file *filp, poll_table *wait) +{ + return NULL; +} + +/****************************************************************************** +* +* SGA_ioctl +* ___________________________________________________________________________ +* +* DESCRIPTION: This function is called whenever an ioctl system call is made +* by the user-space application. This function offers a way to +* issue device specific commands. +* +* INPUTS: filp : (pointer to) file descriptor of device +* cmd : Control command +* arg : pointer to the passed structures +* +* OUTPUTS: None +* +* RETURNS: On success zero is returned. On error, -1 is returned. +* +* REMARKS: None +* +******************************************************************************/ +int SGA_ioctl(struct inode *inode,struct file *filp, unsigned int cmd, + unsigned long arg) +{ + UINT4 ret = -1; + SGA_Dev_T *pSD = filp->private_data; + + DBG_PRINTK("\n The command in kernel : %d\n", cmd); + ret = ( * SGA_ioctl_array[cmd])(pSD, arg); + + return ret; +} + +/****************************************************************************** +* +* SGA_mmap +* ___________________________________________________________________________ +* +* DESCRIPTION: This function is called whenever an mmap system call is +* made by the userspace application. This function offers a +* way to share kernel memory with the user space application. +* +* +* INPUTS: filp : (pointer to) file descriptor of device +* vma : pointer to memory VMM memory area +* +* +* OUTPUTS: None +* +* RETURNS: On success zero is returned. Else error value is returned. +* +* REMARKS: vma->vm_pgoff is used to identify the type of memory to be mapped. +* Other than that it does not have any significance and is reset to +* zero during the mapping operation. The memories mapped with this +* function are Firmware memory, Device Registers memory and Shared +* memory. The first 2 are used always but the Shared memory is used +* only under specific configurations done at compile time. It is +* required only in case interrupts are enabled. +* +******************************************************************************/ +int SGA_mmap(struct file *filp, struct vm_area_struct *vma) +{ + SGA_Dev_T *pSD = filp->private_data; + int ret = NULL; + long length = vma->vm_end - vma->vm_start; + char memory_area = vma->vm_pgoff; + + vma->vm_pgoff = 0; // we don't really want any offset, so set to zero + + switch (memory_area) + { + case FW_MEMORY: + // check length - do not allow larger mappings + // than the number of pages allocated + if (length > NPAGES * PAGE_SIZE) + return SGA_ERR_INVALID_ARG; + ret = dma_mmap_coherent(pSD->pSGA_dev, vma, + (void *)pSD->fw_kvmem_base, + pSD->fw_mem_phy, + NPAGES * PAGE_SIZE); + pSD->fw_mem_virt = (UINT4 *)vma->vm_start; + DBG_PRINTK("mmap %x %x %x %x\n", + (unsigned int)pSD->fw_kvmem_base, + (unsigned int)vma->vm_start, + (unsigned int)pSD->fw_mem_phy, + (unsigned int)vma); + + break; + case SHM_MEMORY: + + // check length - do not allow larger mappings + if (length > 1 * PAGE_SIZE) + return SGA_ERR_INVALID_ARG; + ret = dma_mmap_coherent(pSD->pSGA_dev, vma, + (void *)pSD->shm_kvmem_base, + pSD->shm_mem_phy, + 1 * PAGE_SIZE); + pSD->shm_mem_virt = (UINT4 *)vma->vm_start; + DBG_PRINTK("mmap %x %x %x %x\n", + (unsigned int)pSD->shm_kvmem_base, + (unsigned int)vma->vm_start, + (unsigned int)pSD->shm_mem_phy, + (unsigned int)vma); + break; + case DEV_MEMORY: + vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot); + // check length - do not allow larger mappings + if (length > 1 * PAGE_SIZE) + return SGA_ERR_INVALID_ARG; + ret = remap_pfn_range(vma, vma->vm_start, + NOMADIK_SGA_BASE>>PAGE_SHIFT, + length, vma->vm_page_prot); + break; + + default: + ret = SGA_ERR_INVALID_ARG; + break; + } + return ret; +} + +/***********************************************************/ +/***************** FILE OPERATIONS STRUCTURE ****************/ +/***********************************************************/ + +struct file_operations SGA_fops = + { + open : SGA_open, + release : SGA_close, + poll : SGA_Poll, + ioctl : SGA_ioctl, + mmap : SGA_mmap + }; + +UINT2 SGA_major_number; + +/****************************************************************************** +* +* SGA_init_module +* ___________________________________________________________________________ +* +* DESCRIPTION: This function registers the functionalities offered by the +* module that can be accessed by an application. It internally +* loads the module image into kernel space and runs the module's +* init function. This function also registers a character device +* with the kernel. +* +* INPUTS: None +* +* OUTPUTS: None +* +* RETURNS: On success, zero is returned. On error, -1 is returned. +* +* REMARKS: None +* +******************************************************************************/ +static int __init SGA_init_module(void) +{ + int ret = 0; + SGA_Dev_T *pSD; + + + /* Allocate the resources */ + + pSga_device = kmalloc(sizeof(SGA_Dev_T), GFP_KERNEL); + if (NULL == pSga_device) { + ERR_PRINTK(KERN_ERR "SGA: unable to allocate device memory\n"); + return SGA_ERR_MEM_ALLOC; + } + memset(pSga_device, 0, sizeof(SGA_Dev_T)); + pSD = pSga_device; + + pSD->pSGA_dev = (struct device *)nomadik_get_sgadevice(); + init_waitqueue_head(&pSD->SGAPollQ); + + pSD->shm_kvmem_base = dma_alloc_coherent(pSD->pSGA_dev, + 1 * PAGE_SIZE, + &pSD->shm_mem_phy, + GFP_KERNEL | GFP_DMA); + if (!pSD->shm_kvmem_base) { + ERR_PRINTK(KERN_ERR "SGA: unable to allocate shm buffers\n"); + return SGA_ERR_MEM_ALLOC; + } + + + pSD->fw_kvmem_base = dma_alloc_coherent(pSD->pSGA_dev, + (NPAGES+2) * PAGE_SIZE, + &pSD->fw_mem_phy, + GFP_KERNEL | GFP_DMA); + if (!pSD->fw_kvmem_base) { + ERR_PRINTK(KERN_ERR "SGA: unable to allocate fw buffers\n"); + return SGA_ERR_MEM_ALLOC; + } + + // Allocate and enable interrput + ret = request_irq(IRQ_SGA_IT, &sga_interrupt_handler, 0, "SGA", pSD); + if (ret) { + // failed to get interrupt + ERR_PRINTK("Could not allocate SGA interrupt : %d\n", ret); + return ret; + } + + ret = alloc_chrdev_region(&dev,SGADEV_MINOR_START, + SGADEV_COUNT, SGADEV_NAME); + if (ret) { + printk(KERN_WARNING "sga: could not allocate device\n"); + } else { + printk(KERN_WARNING "sga: registered with major number:%i\n", + MAJOR(dev)); + } + + cdev_init(&pSD->cdev, &SGA_fops); + pSD->cdev.owner = THIS_MODULE; + pSD->cdev.ops = &SGA_fops; + + ret = cdev_add(&pSD->cdev,MKDEV(MAJOR(dev), MINOR(dev)) ,1); + if (ret) { + printk(KERN_NOTICE "Error %d adding sga\n", ret); + } else { + printk(KERN_NOTICE "SGA added\n"); + } + + return ret; +} + +/****************************************************************************** +* +* SGA_cleanup_module +* ___________________________________________________________________________ +* +* DESCRIPTION: This function attempts to remove an unused loadable module +* entry. It also unregisters the character device that was +* registered with the kernel by the init_module function. +* +* INPUTS: None +* +* OUTPUTS: None +* +* RETURNS: void +* +* REMARKS: None +* +******************************************************************************/ +static void __exit SGA_cleanup_module(void) +{ + SGA_Dev_T *pSD = pSga_device; + + /* De-allocate all resources before quitting */ + disable_irq(IRQ_SGA_IT); + free_irq(IRQ_SGA_IT, NULL); + if (pSD) { + if (pSD->fw_kvmem_base) { + dma_free_coherent(pSD->pSGA_dev, (NPAGES+2) * PAGE_SIZE, + pSD->fw_kvmem_base, + pSD->fw_mem_phy); + } + + if (pSD->shm_kvmem_base) { + dma_free_coherent(pSD->pSGA_dev, (1) * PAGE_SIZE, + pSD->shm_kvmem_base, + pSD->shm_mem_phy); + } + + cdev_del(&pSD->cdev); + kfree(pSga_device); + pSga_device = NULL; + } + /* Unregister the device */ + unregister_chrdev_region(dev,SGADEV_COUNT); + + return; +} + +/*****************************************************************/ +/**********Video Switching Related Implentaion***********************/ +/*****************************************************************/ + +static void (*vid_switch_sva_suspend_fnptr)(void); +static void (*vid_switch_sva_resume_fnptr)(void); +static void (*vid_switch_ogl_suspend_fnptr)(void); +static void (*vid_switch_ogl_resume_fnptr)(void); + +#define SVA_FIRMWARE_ACTIVE (0x0001) +#define OGL_FIRMWARE_ACTIVE (0x0010) +#define SVA_FIRMWARE_INACTIVE (0x0100) + +static int g_SVA_Fw_Status=SVA_FIRMWARE_INACTIVE; + + +int vid_switch_register_sva_suspend_resume_fn(void(*suspend)(),void(*resume)()) +{ + vid_switch_sva_suspend_fnptr=suspend; + vid_switch_sva_resume_fnptr=resume; + + g_SVA_Fw_Status = SVA_FIRMWARE_ACTIVE; + +} +EXPORT_SYMBOL(vid_switch_register_sva_suspend_resume_fn); + +int vid_switch_register_ogl_suspend_resume_fn(void(*suspend)(),void(*resume)()) +{ + vid_switch_ogl_suspend_fnptr=suspend; + vid_switch_ogl_resume_fnptr=resume; +} + +EXPORT_SYMBOL(vid_switch_register_ogl_suspend_resume_fn); + + +int vid_switch_unregister_sva_suspend_resume_fn(void) +{ + vid_switch_sva_suspend_fnptr=0; + vid_switch_sva_resume_fnptr=0; +} +EXPORT_SYMBOL(vid_switch_unregister_sva_suspend_resume_fn); + +int vid_switch_unregister_ogl_suspend_resume_fn(void) +{ + vid_switch_ogl_suspend_fnptr=0; + vid_switch_ogl_resume_fnptr=0; +} +EXPORT_SYMBOL(vid_switch_unregister_ogl_suspend_resume_fn); + + +void vid_switch_sva_suspend() +{ + /*if SVA is active then reload the OpenGL FW*/ + if(g_SVA_Fw_Status == SVA_FIRMWARE_ACTIVE) + { + if(vid_switch_sva_suspend_fnptr) + (*vid_switch_sva_suspend_fnptr)(); + + if(vid_switch_ogl_resume_fnptr) + (*vid_switch_ogl_resume_fnptr)(); + + g_SVA_Fw_Status = OGL_FIRMWARE_ACTIVE; + } + +} +EXPORT_SYMBOL(vid_switch_sva_suspend); + +void vid_switch_sva_resume() +{ +#if 0 + if(vid_switch_sva_resume_fnptr) + { + (*vid_switch_sva_resume_fnptr)(); + } +#endif + +} +EXPORT_SYMBOL(vid_switch_sva_resume); + +void vid_switch_ogl_suspend() +{ + /*if Open GL active then reload the SVA FW*/ + if(g_SVA_Fw_Status == OGL_FIRMWARE_ACTIVE) + { + if(vid_switch_ogl_suspend_fnptr) + (*vid_switch_ogl_suspend_fnptr)(); + + if(vid_switch_sva_resume_fnptr) + (*vid_switch_sva_resume_fnptr)(); + + g_SVA_Fw_Status = SVA_FIRMWARE_ACTIVE; + } + +} +EXPORT_SYMBOL(vid_switch_ogl_suspend); + +void vid_switch_ogl_resume() +{ +#if 0 + if(vid_switch_ogl_resume_fnptr) + (*vid_switch_ogl_resume_fnptr)(); +#endif + +} +EXPORT_SYMBOL(vid_switch_ogl_resume); + +module_init(SGA_init_module); +module_exit(SGA_cleanup_module); + --- /dev/null +++ linux-2.6.20/drivers/video/nomadik/sga_main.h @@ -0,0 +1,123 @@ +/******************************************************************************* +** Copyright 2007, STMicroelectronics +** This program is free software; you can redistribute it and/or modify +** it under the terms of the GNU General Public License as published by +** the Free Software Foundation; either version 3 of the License, or +** (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program. If not, see . +** +** MODULE : SGA Device Driver +** +** FILE : sga_main.h +** +** DESCRIPTION : This file contains all the definitions & declarations +** that are required by external applications. The application +** code need only include this header file. +** +** NOTES : +** +*******************************************************************************/ + + +#ifndef _SGA_API_H +#define _SGA_API_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "sga_typs.h" +#include "sga_defs.h" +#include "sga_err.h" + + +#ifndef NULL +#define NULL 0 +#endif + +/* more defines */ +#if 1 +#define DBG_PRINTK dbg_printk + +int dbg_printk(const char *format, ...); +#else +#define DBG_PRINTK printk +#endif +#define ERR_PRINTK printk + +#if 1 +#define ASSERT(x, y) ((x)==(y))?:printk("Fatal Error ! Assert failed ! %s, %d\n", __FUNCTION__, __LINE__); +#else +#define ASSERT(x,y) do{}while(0) +#endif + +#ifndef MAX +#define MAX(a, b) (((a) > (b)) ? (a) : (b)) +#endif + + +/* structures */ +typedef struct _SGA_Dev_T +{ + int sga_interruptcount, sga_interruptflag; + unsigned int sga_interruptmask; + unsigned int new_sga_interruptmask; + char sga_instance; + char __iomem *dev_kvmem_base; + char __iomem *shm_kvmem_base; + char __iomem *fw_kvmem_base; + wait_queue_head_t SGAPollQ; + char init_flag; + UINT4 *dev_mem_virt; + UINT4 *shm_mem_virt; + UINT4 *fw_mem_virt; + dma_addr_t dev_mem_phy; + dma_addr_t shm_mem_phy; + dma_addr_t fw_mem_phy; + struct device *pSGA_dev; + struct cdev cdev; // Char device structure +} +SGA_Dev_T; + +/* functions */ + +/* MISC */ + + + + +#endif /* _SGA_API_H */ --- /dev/null +++ linux-2.6.20/drivers/video/nomadik/sga_typs.h @@ -0,0 +1,37 @@ +/******************************************************************************* +** Copyright 2007, STMicroelectronics +** This program is free software; you can redistribute it and/or modify +** it under the terms of the GNU General Public License as published by +** the Free Software Foundation; either version 3 of the License, or +** (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program. If not, see . +** +** MODULE : SGA Device Driver +** +** FILE : sga_typs.h +** +** DESCRIPTION : Contains the variable type definitions used by the +** SGA driver +** +** NOTES : +** +*******************************************************************************/ + +#ifndef _SGA_TYPS_H +#define _SGA_TYPS_H + +typedef unsigned char UINT1; +typedef char INT1; +typedef unsigned short UINT2; +typedef short INT2; +typedef unsigned long UINT4; +typedef long INT4; + +#endif /* _SGA_TYPS_H */ --- linux-2.6.20.orig/fs/Kconfig +++ linux-2.6.20/fs/Kconfig @@ -1194,10 +1194,14 @@ config EFS_FS about EFS see its home page at . To compile the EFS file system support as a module, choose M here: the module will be called efs. + +# Patched by YAFFS +source "fs/yaffs2/Kconfig" + config JFFS_FS tristate "Journalling Flash File System (JFFS) support" depends on MTD && BLOCK && BROKEN help JFFS is the Journalling Flash File System developed by Axis --- linux-2.6.20.orig/fs/Makefile +++ linux-2.6.20/fs/Makefile @@ -113,5 +113,8 @@ obj-$(CONFIG_BEFS_FS) += befs/ obj-$(CONFIG_HOSTFS) += hostfs/ obj-$(CONFIG_HPPFS) += hppfs/ obj-$(CONFIG_DEBUG_FS) += debugfs/ obj-$(CONFIG_OCFS2_FS) += ocfs2/ obj-$(CONFIG_GFS2_FS) += gfs2/ + +# Patched by YAFFS +obj-$(CONFIG_YAFFS_FS) += yaffs2/ --- linux-2.6.20.orig/fs/proc/proc_misc.c +++ linux-2.6.20/fs/proc/proc_misc.c @@ -63,10 +63,11 @@ * wrappers, but this needs further analysis wrt potential overflows. */ extern int get_hardware_list(char *); extern int get_stram_list(char *); extern int get_filesystem_list(char *); +extern int get_gpio_list(char *); extern int get_exec_domain_list(char *); extern int get_dma_list(char *); extern int get_locks_status (char *, char **, off_t, int); static int proc_calc_metrics(char *page, char **start, off_t off, @@ -610,10 +611,33 @@ static int filesystems_read_proc(char *p { int len = get_filesystem_list(page); return proc_calc_metrics(page, start, off, count, eof, len); } +#ifdef CONFIG_GPIO_PROC +static int gpio_read_proc(char *page, char **start, off_t off, + int count, int *eof, void *data) +{ + int len = get_gpio_list(page); + return proc_calc_metrics(page, start, off, count, eof, len); +} +#endif +extern nomadik_busfreq_get(char *); +static int busfreq_read_proc(char *page, char **start, off_t off, + int count, int *eof, void *data) +{ + int len = nomadik_busfreq_get(page); + return proc_calc_metrics(page, start, off, count, eof, len); +} + +static int dma_read_proc(char *page, char **start, off_t off, + int count, int *eof, void *data) +{ + int len = get_dma_list(page); + return proc_calc_metrics(page, start, off, count, eof, len); +} + static int cmdline_read_proc(char *page, char **start, off_t off, int count, int *eof, void *data) { int len; @@ -685,15 +709,23 @@ void __init proc_misc_init(void) {"hardware", hardware_read_proc}, #endif #ifdef CONFIG_STRAM_PROC {"stram", stram_read_proc}, #endif - {"filesystems", filesystems_read_proc}, - {"cmdline", cmdline_read_proc}, - {"locks", locks_read_proc}, - {"execdomains", execdomains_read_proc}, - {NULL,} + { + "filesystems", filesystems_read_proc}, +#ifdef CONFIG_GPIO_PROC + { + "gpio", gpio_read_proc}, +#endif + {"busfreq" , busfreq_read_proc}, + { + "dma", dma_read_proc}, { + "cmdline", cmdline_read_proc}, { + "locks", locks_read_proc}, { + "execdomains", execdomains_read_proc}, { + NULL,} }; for (p = simple_ones; p->name; p++) create_proc_read_entry(p->name, 0, NULL, p->read_proc, NULL); proc_symlink("mounts", NULL, "self/mounts"); --- /dev/null +++ linux-2.6.20/fs/yaffs2/Kconfig @@ -0,0 +1,156 @@ +# +# YAFFS file system configurations +# + +config YAFFS_FS + tristate "YAFFS2 file system support" + default n + depends on MTD + select YAFFS_YAFFS1 + select YAFFS_YAFFS2 + help + YAFFS2, or Yet Another Flash Filing System, is a filing system + optimised for NAND Flash chips. + + To compile the YAFFS2 file system support as a module, choose M + here: the module will be called yaffs2. + + If unsure, say N. + + Further information on YAFFS2 is available at + . + +config YAFFS_YAFFS1 + bool "512 byte / page devices" + depends on YAFFS_FS + default y + help + Enable YAFFS1 support -- yaffs for 512 byte / page devices + + Not needed for 2K-page devices. + + If unsure, say Y. + +config YAFFS_9BYTE_TAGS + bool "Use older-style on-NAND data format with pageStatus byte" + depends on YAFFS_YAFFS1 + default n + help + + Older-style on-NAND data format has a "pageStatus" byte to record + chunk/page state. This byte is zero when the page is discarded. + Choose this option if you have existing on-NAND data using this + format that you need to continue to support. New data written + also uses the older-style format. Note: Use of this option + generally requires that MTD's oob layout be adjusted to use the + older-style format. See notes on tags formats and MTD versions + in yaffs_mtdif1.c. + + If unsure, say N. + +config YAFFS_DOES_ECC + bool "Lets Yaffs do its own ECC" + depends on YAFFS_FS && YAFFS_YAFFS1 && !YAFFS_9BYTE_TAGS + default n + help + This enables Yaffs to use its own ECC functions instead of using + the ones from the generic MTD-NAND driver. + + If unsure, say N. + +config YAFFS_ECC_WRONG_ORDER + bool "Use the same ecc byte order as Steven Hill's nand_ecc.c" + depends on YAFFS_FS && YAFFS_DOES_ECC && !YAFFS_9BYTE_TAGS + default n + help + This makes yaffs_ecc.c use the same ecc byte order as Steven + Hill's nand_ecc.c. If not set, then you get the same ecc byte + order as SmartMedia. + + If unsure, say N. + +config YAFFS_YAFFS2 + bool "2048 byte (or larger) / page devices" + depends on YAFFS_FS + default y + help + Enable YAFFS2 support -- yaffs for >= 2K bytes per page devices + + If unsure, say Y. + +config YAFFS_AUTO_YAFFS2 + bool "Autoselect yaffs2 format" + depends on YAFFS_YAFFS2 + default y + help + Without this, you need to explicitely use yaffs2 as the file + system type. With this, you can say "yaffs" and yaffs or yaffs2 + will be used depending on the device page size (yaffs on + 512-byte page devices, yaffs2 on 2K page devices). + + If unsure, say Y. + +config YAFFS_DISABLE_LAZY_LOAD + bool "Disable lazy loading" + depends on YAFFS_YAFFS2 + default n + help + "Lazy loading" defers loading file details until they are + required. This saves mount time, but makes the first look-up + a bit longer. + + Lazy loading will only happen if enabled by this option being 'n' + and if the appropriate tags are available, else yaffs2 will + automatically fall back to immediate loading and do the right + thing. + + Lazy laoding will be required by checkpointing. + + Setting this to 'y' will disable lazy loading. + + If unsure, say N. + + +config YAFFS_DISABLE_WIDE_TNODES + bool "Turn off wide tnodes" + depends on YAFFS_FS + default n + help + Wide tnodes are only used for NAND arrays >=32MB for 512-byte + page devices and >=128MB for 2k page devices. They use slightly + more RAM but are faster since they eliminate chunk group + searching. + + Setting this to 'y' will force tnode width to 16 bits and save + memory but make large arrays slower. + + If unsure, say N. + +config YAFFS_ALWAYS_CHECK_CHUNK_ERASED + bool "Force chunk erase check" + depends on YAFFS_FS + default n + help + Normally YAFFS only checks chunks before writing until an erased + chunk is found. This helps to detect any partially written + chunks that might have happened due to power loss. + + Enabling this forces on the test that chunks are erased in flash + before writing to them. This takes more time but is potentially + a bit more secure. + + Suggest setting Y during development and ironing out driver + issues etc. Suggest setting to N if you want faster writing. + + If unsure, say Y. + +config YAFFS_SHORT_NAMES_IN_RAM + bool "Cache short names in RAM" + depends on YAFFS_FS + default y + help + If this config is set, then short names are stored with the + yaffs_Object. This costs an extra 16 bytes of RAM per object, + but makes look-ups faster. + + If unsure, say Y. --- /dev/null +++ linux-2.6.20/fs/yaffs2/Makefile @@ -0,0 +1,10 @@ +# +# Makefile for the linux YAFFS filesystem routines. +# + +obj-$(CONFIG_YAFFS_FS) += yaffs.o + +yaffs-y := yaffs_ecc.o yaffs_fs.o yaffs_guts.o yaffs_checkptrw.o +yaffs-y += yaffs_packedtags1.o yaffs_packedtags2.o yaffs_nand.o yaffs_qsort.o +yaffs-y += yaffs_tagscompat.o yaffs_tagsvalidity.o +yaffs-y += yaffs_mtdif.o yaffs_mtdif1.o yaffs_mtdif2.o --- /dev/null +++ linux-2.6.20/fs/yaffs2/devextras.h @@ -0,0 +1,264 @@ +/* + * YAFFS: Yet another Flash File System . A NAND-flash specific file system. + * + * Copyright (C) 2002-2007 Aleph One Ltd. + * for Toby Churchill Ltd and Brightstar Engineering + * + * Created by Charles Manning + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 2.1 as + * published by the Free Software Foundation. + * + * Note: Only YAFFS headers are LGPL, YAFFS C code is covered by GPL. + */ + +/* + * This file is just holds extra declarations used during development. + * Most of these are from kernel includes placed here so we can use them in + * applications. + * + */ + +#ifndef __EXTRAS_H__ +#define __EXTRAS_H__ + +#if defined WIN32 +#define __inline__ __inline +#define new newHack +#endif + +#if !(defined __KERNEL__) || (defined WIN32) + +/* User space defines */ + +typedef unsigned char __u8; +typedef unsigned short __u16; +typedef unsigned __u32; + +/* + * Simple doubly linked list implementation. + * + * Some of the internal functions ("__xxx") are useful when + * manipulating whole lists rather than single entries, as + * sometimes we already know the next/prev entries and we can + * generate better code by using them directly rather than + * using the generic single-entry routines. + */ + +#define prefetch(x) 1 + +struct list_head { + struct list_head *next, *prev; +}; + +#define LIST_HEAD_INIT(name) { &(name), &(name) } + +#define LIST_HEAD(name) \ + struct list_head name = LIST_HEAD_INIT(name) + +#define INIT_LIST_HEAD(ptr) do { \ + (ptr)->next = (ptr); (ptr)->prev = (ptr); \ +} while (0) + +/* + * Insert a new entry between two known consecutive entries. + * + * This is only for internal list manipulation where we know + * the prev/next entries already! + */ +static __inline__ void __list_add(struct list_head *new, + struct list_head *prev, + struct list_head *next) +{ + next->prev = new; + new->next = next; + new->prev = prev; + prev->next = new; +} + +/** + * list_add - add a new entry + * @new: new entry to be added + * @head: list head to add it after + * + * Insert a new entry after the specified head. + * This is good for implementing stacks. + */ +static __inline__ void list_add(struct list_head *new, struct list_head *head) +{ + __list_add(new, head, head->next); +} + +/** + * list_add_tail - add a new entry + * @new: new entry to be added + * @head: list head to add it before + * + * Insert a new entry before the specified head. + * This is useful for implementing queues. + */ +static __inline__ void list_add_tail(struct list_head *new, + struct list_head *head) +{ + __list_add(new, head->prev, head); +} + +/* + * Delete a list entry by making the prev/next entries + * point to each other. + * + * This is only for internal list manipulation where we know + * the prev/next entries already! + */ +static __inline__ void __list_del(struct list_head *prev, + struct list_head *next) +{ + next->prev = prev; + prev->next = next; +} + +/** + * list_del - deletes entry from list. + * @entry: the element to delete from the list. + * Note: list_empty on entry does not return true after this, the entry is + * in an undefined state. + */ +static __inline__ void list_del(struct list_head *entry) +{ + __list_del(entry->prev, entry->next); +} + +/** + * list_del_init - deletes entry from list and reinitialize it. + * @entry: the element to delete from the list. + */ +static __inline__ void list_del_init(struct list_head *entry) +{ + __list_del(entry->prev, entry->next); + INIT_LIST_HEAD(entry); +} + +/** + * list_empty - tests whether a list is empty + * @head: the list to test. + */ +static __inline__ int list_empty(struct list_head *head) +{ + return head->next == head; +} + +/** + * list_splice - join two lists + * @list: the new list to add. + * @head: the place to add it in the first list. + */ +static __inline__ void list_splice(struct list_head *list, + struct list_head *head) +{ + struct list_head *first = list->next; + + if (first != list) { + struct list_head *last = list->prev; + struct list_head *at = head->next; + + first->prev = head; + head->next = first; + + last->next = at; + at->prev = last; + } +} + +/** + * list_entry - get the struct for this entry + * @ptr: the &struct list_head pointer. + * @type: the type of the struct this is embedded in. + * @member: the name of the list_struct within the struct. + */ +#define list_entry(ptr, type, member) \ + ((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member))) + +/** + * list_for_each - iterate over a list + * @pos: the &struct list_head to use as a loop counter. + * @head: the head for your list. + */ +#define list_for_each(pos, head) \ + for (pos = (head)->next, prefetch(pos->next); pos != (head); \ + pos = pos->next, prefetch(pos->next)) + +/** + * list_for_each_safe - iterate over a list safe against removal + * of list entry + * @pos: the &struct list_head to use as a loop counter. + * @n: another &struct list_head to use as temporary storage + * @head: the head for your list. + */ +#define list_for_each_safe(pos, n, head) \ + for (pos = (head)->next, n = pos->next; pos != (head); \ + pos = n, n = pos->next) + +/* + * File types + */ +#define DT_UNKNOWN 0 +#define DT_FIFO 1 +#define DT_CHR 2 +#define DT_DIR 4 +#define DT_BLK 6 +#define DT_REG 8 +#define DT_LNK 10 +#define DT_SOCK 12 +#define DT_WHT 14 + +#ifndef WIN32 +#include +#endif + +/* + * Attribute flags. These should be or-ed together to figure out what + * has been changed! + */ +#define ATTR_MODE 1 +#define ATTR_UID 2 +#define ATTR_GID 4 +#define ATTR_SIZE 8 +#define ATTR_ATIME 16 +#define ATTR_MTIME 32 +#define ATTR_CTIME 64 +#define ATTR_ATIME_SET 128 +#define ATTR_MTIME_SET 256 +#define ATTR_FORCE 512 /* Not a change, but a change it */ +#define ATTR_ATTR_FLAG 1024 + +struct iattr { + unsigned int ia_valid; + unsigned ia_mode; + unsigned ia_uid; + unsigned ia_gid; + unsigned ia_size; + unsigned ia_atime; + unsigned ia_mtime; + unsigned ia_ctime; + unsigned int ia_attr_flags; +}; + +#define KERN_DEBUG + +#else + +#ifndef WIN32 +#include +#include +#include +#include +#endif + +#endif + +#if defined WIN32 +#undef new +#endif + +#endif --- /dev/null +++ linux-2.6.20/fs/yaffs2/moduleconfig.h @@ -0,0 +1,65 @@ +/* + * YAFFS: Yet another Flash File System . A NAND-flash specific file system. + * + * Copyright (C) 2002-2007 Aleph One Ltd. + * for Toby Churchill Ltd and Brightstar Engineering + * + * Created by Martin Fouts + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 2.1 as + * published by the Free Software Foundation. + * + * Note: Only YAFFS headers are LGPL, YAFFS C code is covered by GPL. + */ + +#ifndef __YAFFS_CONFIG_H__ +#define __YAFFS_CONFIG_H__ + +#ifdef YAFFS_OUT_OF_TREE + +/* DO NOT UNSET THESE THREE. YAFFS2 will not compile if you do. */ +#define CONFIG_YAFFS_FS +#define CONFIG_YAFFS_YAFFS1 +#define CONFIG_YAFFS_YAFFS2 + +/* These options are independent of each other. Select those that matter. */ + +/* Default: Not selected */ +/* Meaning: Yaffs does its own ECC, rather than using MTD ECC */ +//#define CONFIG_YAFFS_DOES_ECC + +/* Default: Not selected */ +/* Meaning: ECC byte order is 'wrong'. Only meaningful if */ +/* CONFIG_YAFFS_DOES_ECC is set */ +//#define CONFIG_YAFFS_ECC_WRONG_ORDER + +/* Default: Selected */ +/* Meaning: Disables testing whether chunks are erased before writing to them*/ +#define CONFIG_YAFFS_DISABLE_CHUNK_ERASED_CHECK + +/* Default: Selected */ +/* Meaning: Cache short names, taking more RAM, but faster look-ups */ +#define CONFIG_YAFFS_SHORT_NAMES_IN_RAM + +/* Default: 10 */ +/* Meaning: set the count of blocks to reserve for checkpointing */ +#define CONFIG_YAFFS_CHECKPOINT_RESERVED_BLOCKS 10 + +/* +Older-style on-NAND data format has a "pageStatus" byte to record +chunk/page state. This byte is zeroed when the page is discarded. +Choose this option if you have existing on-NAND data in this format +that you need to continue to support. New data written also uses the +older-style format. +Note: Use of this option generally requires that MTD's oob layout be +adjusted to use the older-style format. See notes on tags formats and +MTD versions in yaffs_mtdif1.c. +*/ +/* Default: Not selected */ +/* Meaning: Use older-style on-NAND data format with pageStatus byte */ +//#define CONFIG_YAFFS_9BYTE_TAGS + +#endif /* YAFFS_OUT_OF_TREE */ + +#endif /* __YAFFS_CONFIG_H__ */ --- /dev/null +++ linux-2.6.20/fs/yaffs2/yaffs_checkptrw.c @@ -0,0 +1,404 @@ +/* + * YAFFS: Yet Another Flash File System. A NAND-flash specific file system. + * + * Copyright (C) 2002-2007 Aleph One Ltd. + * for Toby Churchill Ltd and Brightstar Engineering + * + * Created by Charles Manning + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +const char *yaffs_checkptrw_c_version = + "$Id: yaffs_checkptrw.c,v 1.15 2007/12/13 15:35:17 wookey Exp $"; + + +#include "yaffs_checkptrw.h" + + +static int yaffs_CheckpointSpaceOk(yaffs_Device *dev) +{ + + int blocksAvailable = dev->nErasedBlocks - dev->nReservedBlocks; + + T(YAFFS_TRACE_CHECKPOINT, + (TSTR("checkpt blocks available = %d" TENDSTR), + blocksAvailable)); + + + return (blocksAvailable <= 0) ? 0 : 1; +} + + +static int yaffs_CheckpointErase(yaffs_Device *dev) +{ + + int i; + + + if(!dev->eraseBlockInNAND) + return 0; + T(YAFFS_TRACE_CHECKPOINT,(TSTR("checking blocks %d to %d"TENDSTR), + dev->internalStartBlock,dev->internalEndBlock)); + + for(i = dev->internalStartBlock; i <= dev->internalEndBlock; i++) { + yaffs_BlockInfo *bi = yaffs_GetBlockInfo(dev,i); + if(bi->blockState == YAFFS_BLOCK_STATE_CHECKPOINT){ + T(YAFFS_TRACE_CHECKPOINT,(TSTR("erasing checkpt block %d"TENDSTR),i)); + if(dev->eraseBlockInNAND(dev,i- dev->blockOffset /* realign */)){ + bi->blockState = YAFFS_BLOCK_STATE_EMPTY; + dev->nErasedBlocks++; + dev->nFreeChunks += dev->nChunksPerBlock; + } + else { + dev->markNANDBlockBad(dev,i); + bi->blockState = YAFFS_BLOCK_STATE_DEAD; + } + } + } + + dev->blocksInCheckpoint = 0; + + return 1; +} + + +static void yaffs_CheckpointFindNextErasedBlock(yaffs_Device *dev) +{ + int i; + int blocksAvailable = dev->nErasedBlocks - dev->nReservedBlocks; + T(YAFFS_TRACE_CHECKPOINT, + (TSTR("allocating checkpt block: erased %d reserved %d avail %d next %d "TENDSTR), + dev->nErasedBlocks,dev->nReservedBlocks,blocksAvailable,dev->checkpointNextBlock)); + + if(dev->checkpointNextBlock >= 0 && + dev->checkpointNextBlock <= dev->internalEndBlock && + blocksAvailable > 0){ + + for(i = dev->checkpointNextBlock; i <= dev->internalEndBlock; i++){ + yaffs_BlockInfo *bi = yaffs_GetBlockInfo(dev,i); + if(bi->blockState == YAFFS_BLOCK_STATE_EMPTY){ + dev->checkpointNextBlock = i + 1; + dev->checkpointCurrentBlock = i; + T(YAFFS_TRACE_CHECKPOINT,(TSTR("allocating checkpt block %d"TENDSTR),i)); + return; + } + } + } + T(YAFFS_TRACE_CHECKPOINT,(TSTR("out of checkpt blocks"TENDSTR))); + + dev->checkpointNextBlock = -1; + dev->checkpointCurrentBlock = -1; +} + +static void yaffs_CheckpointFindNextCheckpointBlock(yaffs_Device *dev) +{ + int i; + yaffs_ExtendedTags tags; + + T(YAFFS_TRACE_CHECKPOINT,(TSTR("find next checkpt block: start: blocks %d next %d" TENDSTR), + dev->blocksInCheckpoint, dev->checkpointNextBlock)); + + if(dev->blocksInCheckpoint < dev->checkpointMaxBlocks) + for(i = dev->checkpointNextBlock; i <= dev->internalEndBlock; i++){ + int chunk = i * dev->nChunksPerBlock; + int realignedChunk = chunk - dev->chunkOffset; + + dev->readChunkWithTagsFromNAND(dev,realignedChunk,NULL,&tags); + T(YAFFS_TRACE_CHECKPOINT,(TSTR("find next checkpt block: search: block %d oid %d seq %d eccr %d" TENDSTR), + i, tags.objectId,tags.sequenceNumber,tags.eccResult)); + + if(tags.sequenceNumber == YAFFS_SEQUENCE_CHECKPOINT_DATA){ + /* Right kind of block */ + dev->checkpointNextBlock = tags.objectId; + dev->checkpointCurrentBlock = i; + dev->checkpointBlockList[dev->blocksInCheckpoint] = i; + dev->blocksInCheckpoint++; + T(YAFFS_TRACE_CHECKPOINT,(TSTR("found checkpt block %d"TENDSTR),i)); + return; + } + } + + T(YAFFS_TRACE_CHECKPOINT,(TSTR("found no more checkpt blocks"TENDSTR))); + + dev->checkpointNextBlock = -1; + dev->checkpointCurrentBlock = -1; +} + + +int yaffs_CheckpointOpen(yaffs_Device *dev, int forWriting) +{ + + /* Got the functions we need? */ + if (!dev->writeChunkWithTagsToNAND || + !dev->readChunkWithTagsFromNAND || + !dev->eraseBlockInNAND || + !dev->markNANDBlockBad) + return 0; + + if(forWriting && !yaffs_CheckpointSpaceOk(dev)) + return 0; + + if(!dev->checkpointBuffer) + dev->checkpointBuffer = YMALLOC_DMA(dev->nDataBytesPerChunk); + if(!dev->checkpointBuffer) + return 0; + + + dev->checkpointPageSequence = 0; + + dev->checkpointOpenForWrite = forWriting; + + dev->checkpointByteCount = 0; + dev->checkpointSum = 0; + dev->checkpointXor = 0; + dev->checkpointCurrentBlock = -1; + dev->checkpointCurrentChunk = -1; + dev->checkpointNextBlock = dev->internalStartBlock; + + /* Erase all the blocks in the checkpoint area */ + if(forWriting){ + memset(dev->checkpointBuffer,0,dev->nDataBytesPerChunk); + dev->checkpointByteOffset = 0; + return yaffs_CheckpointErase(dev); + + + } else { + int i; + /* Set to a value that will kick off a read */ + dev->checkpointByteOffset = dev->nDataBytesPerChunk; + /* A checkpoint block list of 1 checkpoint block per 16 block is (hopefully) + * going to be way more than we need */ + dev->blocksInCheckpoint = 0; + dev->checkpointMaxBlocks = (dev->internalEndBlock - dev->internalStartBlock)/16 + 2; + dev->checkpointBlockList = YMALLOC(sizeof(int) * dev->checkpointMaxBlocks); + for(i = 0; i < dev->checkpointMaxBlocks; i++) + dev->checkpointBlockList[i] = -1; + } + + return 1; +} + +int yaffs_GetCheckpointSum(yaffs_Device *dev, __u32 *sum) +{ + __u32 compositeSum; + compositeSum = (dev->checkpointSum << 8) | (dev->checkpointXor & 0xFF); + *sum = compositeSum; + return 1; +} + +static int yaffs_CheckpointFlushBuffer(yaffs_Device *dev) +{ + + int chunk; + int realignedChunk; + + yaffs_ExtendedTags tags; + + if(dev->checkpointCurrentBlock < 0){ + yaffs_CheckpointFindNextErasedBlock(dev); + dev->checkpointCurrentChunk = 0; + } + + if(dev->checkpointCurrentBlock < 0) + return 0; + + tags.chunkDeleted = 0; + tags.objectId = dev->checkpointNextBlock; /* Hint to next place to look */ + tags.chunkId = dev->checkpointPageSequence + 1; + tags.sequenceNumber = YAFFS_SEQUENCE_CHECKPOINT_DATA; + tags.byteCount = dev->nDataBytesPerChunk; + if(dev->checkpointCurrentChunk == 0){ + /* First chunk we write for the block? Set block state to + checkpoint */ + yaffs_BlockInfo *bi = yaffs_GetBlockInfo(dev,dev->checkpointCurrentBlock); + bi->blockState = YAFFS_BLOCK_STATE_CHECKPOINT; + dev->blocksInCheckpoint++; + } + + chunk = dev->checkpointCurrentBlock * dev->nChunksPerBlock + dev->checkpointCurrentChunk; + + + T(YAFFS_TRACE_CHECKPOINT,(TSTR("checkpoint wite buffer nand %d(%d:%d) objid %d chId %d" TENDSTR), + chunk, dev->checkpointCurrentBlock, dev->checkpointCurrentChunk,tags.objectId,tags.chunkId)); + + realignedChunk = chunk - dev->chunkOffset; + + dev->writeChunkWithTagsToNAND(dev,realignedChunk,dev->checkpointBuffer,&tags); + dev->checkpointByteOffset = 0; + dev->checkpointPageSequence++; + dev->checkpointCurrentChunk++; + if(dev->checkpointCurrentChunk >= dev->nChunksPerBlock){ + dev->checkpointCurrentChunk = 0; + dev->checkpointCurrentBlock = -1; + } + memset(dev->checkpointBuffer,0,dev->nDataBytesPerChunk); + + return 1; +} + + +int yaffs_CheckpointWrite(yaffs_Device *dev,const void *data, int nBytes) +{ + int i=0; + int ok = 1; + + + __u8 * dataBytes = (__u8 *)data; + + + + if(!dev->checkpointBuffer) + return 0; + + if(!dev->checkpointOpenForWrite) + return -1; + + while(i < nBytes && ok) { + + + + dev->checkpointBuffer[dev->checkpointByteOffset] = *dataBytes ; + dev->checkpointSum += *dataBytes; + dev->checkpointXor ^= *dataBytes; + + dev->checkpointByteOffset++; + i++; + dataBytes++; + dev->checkpointByteCount++; + + + if(dev->checkpointByteOffset < 0 || + dev->checkpointByteOffset >= dev->nDataBytesPerChunk) + ok = yaffs_CheckpointFlushBuffer(dev); + + } + + return i; +} + +int yaffs_CheckpointRead(yaffs_Device *dev, void *data, int nBytes) +{ + int i=0; + int ok = 1; + yaffs_ExtendedTags tags; + + + int chunk; + int realignedChunk; + + __u8 *dataBytes = (__u8 *)data; + + if(!dev->checkpointBuffer) + return 0; + + if(dev->checkpointOpenForWrite) + return -1; + + while(i < nBytes && ok) { + + + if(dev->checkpointByteOffset < 0 || + dev->checkpointByteOffset >= dev->nDataBytesPerChunk) { + + if(dev->checkpointCurrentBlock < 0){ + yaffs_CheckpointFindNextCheckpointBlock(dev); + dev->checkpointCurrentChunk = 0; + } + + if(dev->checkpointCurrentBlock < 0) + ok = 0; + else { + + chunk = dev->checkpointCurrentBlock * dev->nChunksPerBlock + + dev->checkpointCurrentChunk; + + realignedChunk = chunk - dev->chunkOffset; + + /* read in the next chunk */ + /* printf("read checkpoint page %d\n",dev->checkpointPage); */ + dev->readChunkWithTagsFromNAND(dev, realignedChunk, + dev->checkpointBuffer, + &tags); + + if(tags.chunkId != (dev->checkpointPageSequence + 1) || + tags.sequenceNumber != YAFFS_SEQUENCE_CHECKPOINT_DATA) + ok = 0; + + dev->checkpointByteOffset = 0; + dev->checkpointPageSequence++; + dev->checkpointCurrentChunk++; + + if(dev->checkpointCurrentChunk >= dev->nChunksPerBlock) + dev->checkpointCurrentBlock = -1; + } + } + + if(ok){ + *dataBytes = dev->checkpointBuffer[dev->checkpointByteOffset]; + dev->checkpointSum += *dataBytes; + dev->checkpointXor ^= *dataBytes; + dev->checkpointByteOffset++; + i++; + dataBytes++; + dev->checkpointByteCount++; + } + } + + return i; +} + +int yaffs_CheckpointClose(yaffs_Device *dev) +{ + + if(dev->checkpointOpenForWrite){ + if(dev->checkpointByteOffset != 0) + yaffs_CheckpointFlushBuffer(dev); + } else { + int i; + for(i = 0; i < dev->blocksInCheckpoint && dev->checkpointBlockList[i] >= 0; i++){ + yaffs_BlockInfo *bi = yaffs_GetBlockInfo(dev,dev->checkpointBlockList[i]); + if(bi->blockState == YAFFS_BLOCK_STATE_EMPTY) + bi->blockState = YAFFS_BLOCK_STATE_CHECKPOINT; + else { + // Todo this looks odd... + } + } + YFREE(dev->checkpointBlockList); + dev->checkpointBlockList = NULL; + } + + dev->nFreeChunks -= dev->blocksInCheckpoint * dev->nChunksPerBlock; + dev->nErasedBlocks -= dev->blocksInCheckpoint; + + + T(YAFFS_TRACE_CHECKPOINT,(TSTR("checkpoint byte count %d" TENDSTR), + dev->checkpointByteCount)); + + if(dev->checkpointBuffer){ + /* free the buffer */ + YFREE(dev->checkpointBuffer); + dev->checkpointBuffer = NULL; + return 1; + } + else + return 0; + +} + +int yaffs_CheckpointInvalidateStream(yaffs_Device *dev) +{ + /* Erase the first checksum block */ + + T(YAFFS_TRACE_CHECKPOINT,(TSTR("checkpoint invalidate"TENDSTR))); + + if(!yaffs_CheckpointSpaceOk(dev)) + return 0; + + return yaffs_CheckpointErase(dev); +} + + + --- /dev/null +++ linux-2.6.20/fs/yaffs2/yaffs_checkptrw.h @@ -0,0 +1,35 @@ +/* + * YAFFS: Yet another Flash File System . A NAND-flash specific file system. + * + * Copyright (C) 2002-2007 Aleph One Ltd. + * for Toby Churchill Ltd and Brightstar Engineering + * + * Created by Charles Manning + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 2.1 as + * published by the Free Software Foundation. + * + * Note: Only YAFFS headers are LGPL, YAFFS C code is covered by GPL. + */ + +#ifndef __YAFFS_CHECKPTRW_H__ +#define __YAFFS_CHECKPTRW_H__ + +#include "yaffs_guts.h" + +int yaffs_CheckpointOpen(yaffs_Device *dev, int forWriting); + +int yaffs_CheckpointWrite(yaffs_Device *dev,const void *data, int nBytes); + +int yaffs_CheckpointRead(yaffs_Device *dev,void *data, int nBytes); + +int yaffs_GetCheckpointSum(yaffs_Device *dev, __u32 *sum); + +int yaffs_CheckpointClose(yaffs_Device *dev); + +int yaffs_CheckpointInvalidateStream(yaffs_Device *dev); + + +#endif + --- /dev/null +++ linux-2.6.20/fs/yaffs2/yaffs_ecc.c @@ -0,0 +1,331 @@ +/* + * YAFFS: Yet Another Flash File System. A NAND-flash specific file system. + * + * Copyright (C) 2002-2007 Aleph One Ltd. + * for Toby Churchill Ltd and Brightstar Engineering + * + * Created by Charles Manning + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +/* + * This code implements the ECC algorithm used in SmartMedia. + * + * The ECC comprises 22 bits of parity information and is stuffed into 3 bytes. + * The two unused bit are set to 1. + * The ECC can correct single bit errors in a 256-byte page of data. Thus, two such ECC + * blocks are used on a 512-byte NAND page. + * + */ + +/* Table generated by gen-ecc.c + * Using a table means we do not have to calculate p1..p4 and p1'..p4' + * for each byte of data. These are instead provided in a table in bits7..2. + * Bit 0 of each entry indicates whether the entry has an odd or even parity, and therefore + * this bytes influence on the line parity. + */ + +const char *yaffs_ecc_c_version = + "$Id: yaffs_ecc.c,v 1.10 2007/12/13 15:35:17 wookey Exp $"; + +#include "yportenv.h" + +#include "yaffs_ecc.h" + +static const unsigned char column_parity_table[] = { + 0x00, 0x55, 0x59, 0x0c, 0x65, 0x30, 0x3c, 0x69, + 0x69, 0x3c, 0x30, 0x65, 0x0c, 0x59, 0x55, 0x00, + 0x95, 0xc0, 0xcc, 0x99, 0xf0, 0xa5, 0xa9, 0xfc, + 0xfc, 0xa9, 0xa5, 0xf0, 0x99, 0xcc, 0xc0, 0x95, + 0x99, 0xcc, 0xc0, 0x95, 0xfc, 0xa9, 0xa5, 0xf0, + 0xf0, 0xa5, 0xa9, 0xfc, 0x95, 0xc0, 0xcc, 0x99, + 0x0c, 0x59, 0x55, 0x00, 0x69, 0x3c, 0x30, 0x65, + 0x65, 0x30, 0x3c, 0x69, 0x00, 0x55, 0x59, 0x0c, + 0xa5, 0xf0, 0xfc, 0xa9, 0xc0, 0x95, 0x99, 0xcc, + 0xcc, 0x99, 0x95, 0xc0, 0xa9, 0xfc, 0xf0, 0xa5, + 0x30, 0x65, 0x69, 0x3c, 0x55, 0x00, 0x0c, 0x59, + 0x59, 0x0c, 0x00, 0x55, 0x3c, 0x69, 0x65, 0x30, + 0x3c, 0x69, 0x65, 0x30, 0x59, 0x0c, 0x00, 0x55, + 0x55, 0x00, 0x0c, 0x59, 0x30, 0x65, 0x69, 0x3c, + 0xa9, 0xfc, 0xf0, 0xa5, 0xcc, 0x99, 0x95, 0xc0, + 0xc0, 0x95, 0x99, 0xcc, 0xa5, 0xf0, 0xfc, 0xa9, + 0xa9, 0xfc, 0xf0, 0xa5, 0xcc, 0x99, 0x95, 0xc0, + 0xc0, 0x95, 0x99, 0xcc, 0xa5, 0xf0, 0xfc, 0xa9, + 0x3c, 0x69, 0x65, 0x30, 0x59, 0x0c, 0x00, 0x55, + 0x55, 0x00, 0x0c, 0x59, 0x30, 0x65, 0x69, 0x3c, + 0x30, 0x65, 0x69, 0x3c, 0x55, 0x00, 0x0c, 0x59, + 0x59, 0x0c, 0x00, 0x55, 0x3c, 0x69, 0x65, 0x30, + 0xa5, 0xf0, 0xfc, 0xa9, 0xc0, 0x95, 0x99, 0xcc, + 0xcc, 0x99, 0x95, 0xc0, 0xa9, 0xfc, 0xf0, 0xa5, + 0x0c, 0x59, 0x55, 0x00, 0x69, 0x3c, 0x30, 0x65, + 0x65, 0x30, 0x3c, 0x69, 0x00, 0x55, 0x59, 0x0c, + 0x99, 0xcc, 0xc0, 0x95, 0xfc, 0xa9, 0xa5, 0xf0, + 0xf0, 0xa5, 0xa9, 0xfc, 0x95, 0xc0, 0xcc, 0x99, + 0x95, 0xc0, 0xcc, 0x99, 0xf0, 0xa5, 0xa9, 0xfc, + 0xfc, 0xa9, 0xa5, 0xf0, 0x99, 0xcc, 0xc0, 0x95, + 0x00, 0x55, 0x59, 0x0c, 0x65, 0x30, 0x3c, 0x69, + 0x69, 0x3c, 0x30, 0x65, 0x0c, 0x59, 0x55, 0x00, +}; + +/* Count the bits in an unsigned char or a U32 */ + +static int yaffs_CountBits(unsigned char x) +{ + int r = 0; + while (x) { + if (x & 1) + r++; + x >>= 1; + } + return r; +} + +static int yaffs_CountBits32(unsigned x) +{ + int r = 0; + while (x) { + if (x & 1) + r++; + x >>= 1; + } + return r; +} + +/* Calculate the ECC for a 256-byte block of data */ +void yaffs_ECCCalculate(const unsigned char *data, unsigned char *ecc) +{ + unsigned int i; + + unsigned char col_parity = 0; + unsigned char line_parity = 0; + unsigned char line_parity_prime = 0; + unsigned char t; + unsigned char b; + + for (i = 0; i < 256; i++) { + b = column_parity_table[*data++]; + col_parity ^= b; + + if (b & 0x01) // odd number of bits in the byte + { + line_parity ^= i; + line_parity_prime ^= ~i; + } + + } + + ecc[2] = (~col_parity) | 0x03; + + t = 0; + if (line_parity & 0x80) + t |= 0x80; + if (line_parity_prime & 0x80) + t |= 0x40; + if (line_parity & 0x40) + t |= 0x20; + if (line_parity_prime & 0x40) + t |= 0x10; + if (line_parity & 0x20) + t |= 0x08; + if (line_parity_prime & 0x20) + t |= 0x04; + if (line_parity & 0x10) + t |= 0x02; + if (line_parity_prime & 0x10) + t |= 0x01; + ecc[1] = ~t; + + t = 0; + if (line_parity & 0x08) + t |= 0x80; + if (line_parity_prime & 0x08) + t |= 0x40; + if (line_parity & 0x04) + t |= 0x20; + if (line_parity_prime & 0x04) + t |= 0x10; + if (line_parity & 0x02) + t |= 0x08; + if (line_parity_prime & 0x02) + t |= 0x04; + if (line_parity & 0x01) + t |= 0x02; + if (line_parity_prime & 0x01) + t |= 0x01; + ecc[0] = ~t; + +#ifdef CONFIG_YAFFS_ECC_WRONG_ORDER + // Swap the bytes into the wrong order + t = ecc[0]; + ecc[0] = ecc[1]; + ecc[1] = t; +#endif +} + + +/* Correct the ECC on a 256 byte block of data */ + +int yaffs_ECCCorrect(unsigned char *data, unsigned char *read_ecc, + const unsigned char *test_ecc) +{ + unsigned char d0, d1, d2; /* deltas */ + + d0 = read_ecc[0] ^ test_ecc[0]; + d1 = read_ecc[1] ^ test_ecc[1]; + d2 = read_ecc[2] ^ test_ecc[2]; + + if ((d0 | d1 | d2) == 0) + return 0; /* no error */ + + if (((d0 ^ (d0 >> 1)) & 0x55) == 0x55 && + ((d1 ^ (d1 >> 1)) & 0x55) == 0x55 && + ((d2 ^ (d2 >> 1)) & 0x54) == 0x54) { + /* Single bit (recoverable) error in data */ + + unsigned byte; + unsigned bit; + +#ifdef CONFIG_YAFFS_ECC_WRONG_ORDER + // swap the bytes to correct for the wrong order + unsigned char t; + + t = d0; + d0 = d1; + d1 = t; +#endif + + bit = byte = 0; + + if (d1 & 0x80) + byte |= 0x80; + if (d1 & 0x20) + byte |= 0x40; + if (d1 & 0x08) + byte |= 0x20; + if (d1 & 0x02) + byte |= 0x10; + if (d0 & 0x80) + byte |= 0x08; + if (d0 & 0x20) + byte |= 0x04; + if (d0 & 0x08) + byte |= 0x02; + if (d0 & 0x02) + byte |= 0x01; + + if (d2 & 0x80) + bit |= 0x04; + if (d2 & 0x20) + bit |= 0x02; + if (d2 & 0x08) + bit |= 0x01; + + data[byte] ^= (1 << bit); + + return 1; /* Corrected the error */ + } + + if ((yaffs_CountBits(d0) + + yaffs_CountBits(d1) + + yaffs_CountBits(d2)) == 1) { + /* Reccoverable error in ecc */ + + read_ecc[0] = test_ecc[0]; + read_ecc[1] = test_ecc[1]; + read_ecc[2] = test_ecc[2]; + + return 1; /* Corrected the error */ + } + + /* Unrecoverable error */ + + return -1; + +} + + +/* + * ECCxxxOther does ECC calcs on arbitrary n bytes of data + */ +void yaffs_ECCCalculateOther(const unsigned char *data, unsigned nBytes, + yaffs_ECCOther * eccOther) +{ + unsigned int i; + + unsigned char col_parity = 0; + unsigned line_parity = 0; + unsigned line_parity_prime = 0; + unsigned char b; + + for (i = 0; i < nBytes; i++) { + b = column_parity_table[*data++]; + col_parity ^= b; + + if (b & 0x01) { + /* odd number of bits in the byte */ + line_parity ^= i; + line_parity_prime ^= ~i; + } + + } + + eccOther->colParity = (col_parity >> 2) & 0x3f; + eccOther->lineParity = line_parity; + eccOther->lineParityPrime = line_parity_prime; +} + +int yaffs_ECCCorrectOther(unsigned char *data, unsigned nBytes, + yaffs_ECCOther * read_ecc, + const yaffs_ECCOther * test_ecc) +{ + unsigned char cDelta; /* column parity delta */ + unsigned lDelta; /* line parity delta */ + unsigned lDeltaPrime; /* line parity delta */ + unsigned bit; + + cDelta = read_ecc->colParity ^ test_ecc->colParity; + lDelta = read_ecc->lineParity ^ test_ecc->lineParity; + lDeltaPrime = read_ecc->lineParityPrime ^ test_ecc->lineParityPrime; + + if ((cDelta | lDelta | lDeltaPrime) == 0) + return 0; /* no error */ + + if (lDelta == ~lDeltaPrime && + (((cDelta ^ (cDelta >> 1)) & 0x15) == 0x15)) + { + /* Single bit (recoverable) error in data */ + + bit = 0; + + if (cDelta & 0x20) + bit |= 0x04; + if (cDelta & 0x08) + bit |= 0x02; + if (cDelta & 0x02) + bit |= 0x01; + + if(lDelta >= nBytes) + return -1; + + data[lDelta] ^= (1 << bit); + + return 1; /* corrected */ + } + + if ((yaffs_CountBits32(lDelta) + yaffs_CountBits32(lDeltaPrime) + + yaffs_CountBits(cDelta)) == 1) { + /* Reccoverable error in ecc */ + + *read_ecc = *test_ecc; + return 1; /* corrected */ + } + + /* Unrecoverable error */ + + return -1; + +} + --- /dev/null +++ linux-2.6.20/fs/yaffs2/yaffs_ecc.h @@ -0,0 +1,44 @@ +/* + * YAFFS: Yet another Flash File System . A NAND-flash specific file system. + * + * Copyright (C) 2002-2007 Aleph One Ltd. + * for Toby Churchill Ltd and Brightstar Engineering + * + * Created by Charles Manning + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 2.1 as + * published by the Free Software Foundation. + * + * Note: Only YAFFS headers are LGPL, YAFFS C code is covered by GPL. + */ + + /* + * This code implements the ECC algorithm used in SmartMedia. + * + * The ECC comprises 22 bits of parity information and is stuffed into 3 bytes. + * The two unused bit are set to 1. + * The ECC can correct single bit errors in a 256-byte page of data. Thus, two such ECC + * blocks are used on a 512-byte NAND page. + * + */ + +#ifndef __YAFFS_ECC_H__ +#define __YAFFS_ECC_H__ + +typedef struct { + unsigned char colParity; + unsigned lineParity; + unsigned lineParityPrime; +} yaffs_ECCOther; + +void yaffs_ECCCalculate(const unsigned char *data, unsigned char *ecc); +int yaffs_ECCCorrect(unsigned char *data, unsigned char *read_ecc, + const unsigned char *test_ecc); + +void yaffs_ECCCalculateOther(const unsigned char *data, unsigned nBytes, + yaffs_ECCOther * ecc); +int yaffs_ECCCorrectOther(unsigned char *data, unsigned nBytes, + yaffs_ECCOther * read_ecc, + const yaffs_ECCOther * test_ecc); +#endif --- /dev/null +++ linux-2.6.20/fs/yaffs2/yaffs_fs.c @@ -0,0 +1,2297 @@ +/* + * YAFFS: Yet Another Flash File System. A NAND-flash specific file system. + * + * Copyright (C) 2002-2007 Aleph One Ltd. + * for Toby Churchill Ltd and Brightstar Engineering + * + * Created by Charles Manning + * Acknowledgements: + * Luc van OostenRyck for numerous patches. + * Nick Bane for numerous patches. + * Nick Bane for 2.5/2.6 integration. + * Andras Toth for mknod rdev issue. + * Michael Fischer for finding the problem with inode inconsistency. + * Some code bodily lifted from JFFS + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +/* + * + * This is the file system front-end to YAFFS that hooks it up to + * the VFS. + * + * Special notes: + * >> 2.4: sb->u.generic_sbp points to the yaffs_Device associated with + * this superblock + * >> 2.6: sb->s_fs_info points to the yaffs_Device associated with this + * superblock + * >> inode->u.generic_ip points to the associated yaffs_Object. + */ + +const char *yaffs_fs_c_version = + "$Id: yaffs_fs.c,v 1.65 2007/12/13 15:35:17 wookey Exp $"; +extern const char *yaffs_guts_c_version; + +#include +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)) +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) + +#include /* Added NCB 15-8-2003 */ +#include +#define UnlockPage(p) unlock_page(p) +#define Page_Uptodate(page) test_bit(PG_uptodate, &(page)->flags) + +/* FIXME: use sb->s_id instead ? */ +#define yaffs_devname(sb, buf) bdevname(sb->s_bdev, buf) + +#else + +#include +#define BDEVNAME_SIZE 0 +#define yaffs_devname(sb, buf) kdevname(sb->s_dev) + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) +/* added NCB 26/5/2006 for 2.4.25-vrs2-tcl1 kernel */ +#define __user +#endif + +#endif + +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17)) +#define WRITE_SIZE_STR "writesize" +#define WRITE_SIZE(mtd) (mtd)->writesize +#else +#define WRITE_SIZE_STR "oobblock" +#define WRITE_SIZE(mtd) (mtd)->oobblock +#endif + +#include + +#include "yportenv.h" +#include "yaffs_guts.h" + +#include +#include "yaffs_mtdif.h" +#include "yaffs_mtdif1.h" +#include "yaffs_mtdif2.h" + +unsigned int yaffs_traceMask = YAFFS_TRACE_BAD_BLOCKS; +unsigned int yaffs_wr_attempts = YAFFS_WR_ATTEMPTS; + +/* Module Parameters */ +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) +module_param(yaffs_traceMask,uint,0644); +module_param(yaffs_wr_attempts,uint,0644); +#else +MODULE_PARM(yaffs_traceMask,"i"); +MODULE_PARM(yaffs_wr_attempts,"i"); +#endif + +/*#define T(x) printk x */ + +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,18)) +#define yaffs_InodeToObjectLV(iptr) (iptr)->i_private +#else +#define yaffs_InodeToObjectLV(iptr) (iptr)->u.generic_ip +#endif + +#define yaffs_InodeToObject(iptr) ((yaffs_Object *)(yaffs_InodeToObjectLV(iptr))) +#define yaffs_DentryToObject(dptr) yaffs_InodeToObject((dptr)->d_inode) + +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) +#define yaffs_SuperToDevice(sb) ((yaffs_Device *)sb->s_fs_info) +#else +#define yaffs_SuperToDevice(sb) ((yaffs_Device *)sb->u.generic_sbp) +#endif + +static void yaffs_put_super(struct super_block *sb); + +static ssize_t yaffs_file_write(struct file *f, const char *buf, size_t n, + loff_t * pos); + +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17)) +static int yaffs_file_flush(struct file *file, fl_owner_t id); +#else +static int yaffs_file_flush(struct file *file); +#endif + +static int yaffs_sync_object(struct file *file, struct dentry *dentry, + int datasync); + +static int yaffs_readdir(struct file *f, void *dirent, filldir_t filldir); + +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) +static int yaffs_create(struct inode *dir, struct dentry *dentry, int mode, + struct nameidata *n); +static struct dentry *yaffs_lookup(struct inode *dir, struct dentry *dentry, + struct nameidata *n); +#else +static int yaffs_create(struct inode *dir, struct dentry *dentry, int mode); +static struct dentry *yaffs_lookup(struct inode *dir, struct dentry *dentry); +#endif +static int yaffs_link(struct dentry *old_dentry, struct inode *dir, + struct dentry *dentry); +static int yaffs_unlink(struct inode *dir, struct dentry *dentry); +static int yaffs_symlink(struct inode *dir, struct dentry *dentry, + const char *symname); +static int yaffs_mkdir(struct inode *dir, struct dentry *dentry, int mode); + +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) +static int yaffs_mknod(struct inode *dir, struct dentry *dentry, int mode, + dev_t dev); +#else +static int yaffs_mknod(struct inode *dir, struct dentry *dentry, int mode, + int dev); +#endif +static int yaffs_rename(struct inode *old_dir, struct dentry *old_dentry, + struct inode *new_dir, struct dentry *new_dentry); +static int yaffs_setattr(struct dentry *dentry, struct iattr *attr); + +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17)) +static int yaffs_sync_fs(struct super_block *sb, int wait); +static void yaffs_write_super(struct super_block *sb); +#else +static int yaffs_sync_fs(struct super_block *sb); +static int yaffs_write_super(struct super_block *sb); +#endif + +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17)) +static int yaffs_statfs(struct dentry *dentry, struct kstatfs *buf); +#elif (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) +static int yaffs_statfs(struct super_block *sb, struct kstatfs *buf); +#else +static int yaffs_statfs(struct super_block *sb, struct statfs *buf); +#endif +static void yaffs_read_inode(struct inode *inode); + +static void yaffs_put_inode(struct inode *inode); +static void yaffs_delete_inode(struct inode *); +static void yaffs_clear_inode(struct inode *); + +static int yaffs_readpage(struct file *file, struct page *page); +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) +static int yaffs_writepage(struct page *page, struct writeback_control *wbc); +#else +static int yaffs_writepage(struct page *page); +#endif +static int yaffs_prepare_write(struct file *f, struct page *pg, + unsigned offset, unsigned to); +static int yaffs_commit_write(struct file *f, struct page *pg, unsigned offset, + unsigned to); + +static int yaffs_readlink(struct dentry *dentry, char __user * buffer, + int buflen); +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,13)) +static void *yaffs_follow_link(struct dentry *dentry, struct nameidata *nd); +#else +static int yaffs_follow_link(struct dentry *dentry, struct nameidata *nd); +#endif + +static struct address_space_operations yaffs_file_address_operations = { + .readpage = yaffs_readpage, + .writepage = yaffs_writepage, + .prepare_write = yaffs_prepare_write, + .commit_write = yaffs_commit_write, +}; + +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,22)) +static struct file_operations yaffs_file_operations = { + .read = do_sync_read, + .write = do_sync_write, + .aio_read = generic_file_aio_read, + .aio_write = generic_file_aio_write, + .mmap = generic_file_mmap, + .flush = yaffs_file_flush, + .fsync = yaffs_sync_object, + .splice_read = generic_file_splice_read, + .splice_write = generic_file_splice_write, +}; + +#elif (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,18)) + +static struct file_operations yaffs_file_operations = { + .read = do_sync_read, + .write = do_sync_write, + .aio_read = generic_file_aio_read, + .aio_write = generic_file_aio_write, + .mmap = generic_file_mmap, + .flush = yaffs_file_flush, + .fsync = yaffs_sync_object, + .sendfile = generic_file_sendfile, +}; + +#else + +static struct file_operations yaffs_file_operations = { + .read = generic_file_read, + .write = generic_file_write, + .mmap = generic_file_mmap, + .flush = yaffs_file_flush, + .fsync = yaffs_sync_object, +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) + .sendfile = generic_file_sendfile, +#endif +}; +#endif + +static struct inode_operations yaffs_file_inode_operations = { + .setattr = yaffs_setattr, +}; + +static struct inode_operations yaffs_symlink_inode_operations = { + .readlink = yaffs_readlink, + .follow_link = yaffs_follow_link, + .setattr = yaffs_setattr, +}; + +static struct inode_operations yaffs_dir_inode_operations = { + .create = yaffs_create, + .lookup = yaffs_lookup, + .link = yaffs_link, + .unlink = yaffs_unlink, + .symlink = yaffs_symlink, + .mkdir = yaffs_mkdir, + .rmdir = yaffs_unlink, + .mknod = yaffs_mknod, + .rename = yaffs_rename, + .setattr = yaffs_setattr, +}; + +static struct file_operations yaffs_dir_operations = { + .read = generic_read_dir, + .readdir = yaffs_readdir, + .fsync = yaffs_sync_object, +}; + +static struct super_operations yaffs_super_ops = { + .statfs = yaffs_statfs, + .read_inode = yaffs_read_inode, + .put_inode = yaffs_put_inode, + .put_super = yaffs_put_super, + .delete_inode = yaffs_delete_inode, + .clear_inode = yaffs_clear_inode, + .sync_fs = yaffs_sync_fs, + .write_super = yaffs_write_super, +}; + +static void yaffs_GrossLock(yaffs_Device * dev) +{ + T(YAFFS_TRACE_OS, (KERN_DEBUG "yaffs locking\n")); + + down(&dev->grossLock); +} + +static void yaffs_GrossUnlock(yaffs_Device * dev) +{ + T(YAFFS_TRACE_OS, (KERN_DEBUG "yaffs unlocking\n")); + up(&dev->grossLock); + +} + +static int yaffs_readlink(struct dentry *dentry, char __user * buffer, + int buflen) +{ + unsigned char *alias; + int ret; + + yaffs_Device *dev = yaffs_DentryToObject(dentry)->myDev; + + yaffs_GrossLock(dev); + + alias = yaffs_GetSymlinkAlias(yaffs_DentryToObject(dentry)); + + yaffs_GrossUnlock(dev); + + if (!alias) + return -ENOMEM; + + ret = vfs_readlink(dentry, buffer, buflen, alias); + kfree(alias); + return ret; +} + +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,13)) +static void *yaffs_follow_link(struct dentry *dentry, struct nameidata *nd) +#else +static int yaffs_follow_link(struct dentry *dentry, struct nameidata *nd) +#endif +{ + unsigned char *alias; + int ret; + yaffs_Device *dev = yaffs_DentryToObject(dentry)->myDev; + + yaffs_GrossLock(dev); + + alias = yaffs_GetSymlinkAlias(yaffs_DentryToObject(dentry)); + + yaffs_GrossUnlock(dev); + + if (!alias) + { + ret = -ENOMEM; + goto out; + } + + ret = vfs_follow_link(nd, alias); + kfree(alias); +out: +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,13)) + return ERR_PTR (ret); +#else + return ret; +#endif +} + +struct inode *yaffs_get_inode(struct super_block *sb, int mode, int dev, + yaffs_Object * obj); + +/* + * Lookup is used to find objects in the fs + */ +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) + +static struct dentry *yaffs_lookup(struct inode *dir, struct dentry *dentry, + struct nameidata *n) +#else +static struct dentry *yaffs_lookup(struct inode *dir, struct dentry *dentry) +#endif +{ + yaffs_Object *obj; + struct inode *inode = NULL; /* NCB 2.5/2.6 needs NULL here */ + + yaffs_Device *dev = yaffs_InodeToObject(dir)->myDev; + + yaffs_GrossLock(dev); + + T(YAFFS_TRACE_OS, + (KERN_DEBUG "yaffs_lookup for %d:%s\n", + yaffs_InodeToObject(dir)->objectId, dentry->d_name.name)); + + obj = + yaffs_FindObjectByName(yaffs_InodeToObject(dir), + dentry->d_name.name); + + obj = yaffs_GetEquivalentObject(obj); /* in case it was a hardlink */ + + /* Can't hold gross lock when calling yaffs_get_inode() */ + yaffs_GrossUnlock(dev); + + if (obj) { + T(YAFFS_TRACE_OS, + (KERN_DEBUG "yaffs_lookup found %d\n", obj->objectId)); + + inode = yaffs_get_inode(dir->i_sb, obj->yst_mode, 0, obj); + + if (inode) { + T(YAFFS_TRACE_OS, + (KERN_DEBUG "yaffs_loookup dentry \n")); +/* #if 0 asserted by NCB for 2.5/6 compatability - falls through to + * d_add even if NULL inode */ +#if 0 + /*dget(dentry); // try to solve directory bug */ + d_add(dentry, inode); + + /* return dentry; */ + return NULL; +#endif + } + + } else { + T(YAFFS_TRACE_OS, (KERN_DEBUG "yaffs_lookup not found\n")); + + } + +/* added NCB for 2.5/6 compatability - forces add even if inode is + * NULL which creates dentry hash */ + d_add(dentry, inode); + + return NULL; + /* return (ERR_PTR(-EIO)); */ + +} + +/* For now put inode is just for debugging + * Put inode is called when the inode **structure** is put. + */ +static void yaffs_put_inode(struct inode *inode) +{ + T(YAFFS_TRACE_OS, + ("yaffs_put_inode: ino %d, count %d\n", (int)inode->i_ino, + atomic_read(&inode->i_count))); + +} + +/* clear is called to tell the fs to release any per-inode data it holds */ +static void yaffs_clear_inode(struct inode *inode) +{ + yaffs_Object *obj; + yaffs_Device *dev; + + obj = yaffs_InodeToObject(inode); + + T(YAFFS_TRACE_OS, + ("yaffs_clear_inode: ino %d, count %d %s\n", (int)inode->i_ino, + atomic_read(&inode->i_count), + obj ? "object exists" : "null object")); + + if (obj) { + dev = obj->myDev; + yaffs_GrossLock(dev); + + /* Clear the association between the inode and + * the yaffs_Object. + */ + obj->myInode = NULL; + yaffs_InodeToObjectLV(inode) = NULL; + + /* If the object freeing was deferred, then the real + * free happens now. + * This should fix the inode inconsistency problem. + */ + + yaffs_HandleDeferedFree(obj); + + yaffs_GrossUnlock(dev); + } + +} + +/* delete is called when the link count is zero and the inode + * is put (ie. nobody wants to know about it anymore, time to + * delete the file). + * NB Must call clear_inode() + */ +static void yaffs_delete_inode(struct inode *inode) +{ + yaffs_Object *obj = yaffs_InodeToObject(inode); + yaffs_Device *dev; + + T(YAFFS_TRACE_OS, + ("yaffs_delete_inode: ino %d, count %d %s\n", (int)inode->i_ino, + atomic_read(&inode->i_count), + obj ? "object exists" : "null object")); + + if (obj) { + dev = obj->myDev; + yaffs_GrossLock(dev); + yaffs_DeleteFile(obj); + yaffs_GrossUnlock(dev); + } +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,13)) + truncate_inode_pages (&inode->i_data, 0); +#endif + clear_inode(inode); +} + +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17)) +static int yaffs_file_flush(struct file *file, fl_owner_t id) +#else +static int yaffs_file_flush(struct file *file) +#endif +{ + yaffs_Object *obj = yaffs_DentryToObject(file->f_dentry); + + yaffs_Device *dev = obj->myDev; + + T(YAFFS_TRACE_OS, + (KERN_DEBUG "yaffs_file_flush object %d (%s)\n", obj->objectId, + obj->dirty ? "dirty" : "clean")); + + yaffs_GrossLock(dev); + + yaffs_FlushFile(obj, 1); + + yaffs_GrossUnlock(dev); + + return 0; +} + +static int yaffs_readpage_nolock(struct file *f, struct page *pg) +{ + /* Lifted from jffs2 */ + + yaffs_Object *obj; + unsigned char *pg_buf; + int ret; + + yaffs_Device *dev; + + T(YAFFS_TRACE_OS, (KERN_DEBUG "yaffs_readpage at %08x, size %08x\n", + (unsigned)(pg->index << PAGE_CACHE_SHIFT), + (unsigned)PAGE_CACHE_SIZE)); + + obj = yaffs_DentryToObject(f->f_dentry); + + dev = obj->myDev; + +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) + BUG_ON(!PageLocked(pg)); +#else + if (!PageLocked(pg)) + PAGE_BUG(pg); +#endif + + pg_buf = kmap(pg); + /* FIXME: Can kmap fail? */ + + yaffs_GrossLock(dev); + + ret = + yaffs_ReadDataFromFile(obj, pg_buf, pg->index << PAGE_CACHE_SHIFT, + PAGE_CACHE_SIZE); + + yaffs_GrossUnlock(dev); + + if (ret >= 0) + ret = 0; + + if (ret) { + ClearPageUptodate(pg); + SetPageError(pg); + } else { + SetPageUptodate(pg); + ClearPageError(pg); + } + + flush_dcache_page(pg); + kunmap(pg); + + T(YAFFS_TRACE_OS, (KERN_DEBUG "yaffs_readpage done\n")); + return ret; +} + +static int yaffs_readpage_unlock(struct file *f, struct page *pg) +{ + int ret = yaffs_readpage_nolock(f, pg); + UnlockPage(pg); + return ret; +} + +static int yaffs_readpage(struct file *f, struct page *pg) +{ + return yaffs_readpage_unlock(f, pg); +} + +/* writepage inspired by/stolen from smbfs */ + +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) +static int yaffs_writepage(struct page *page, struct writeback_control *wbc) +#else +static int yaffs_writepage(struct page *page) +#endif +{ + struct address_space *mapping = page->mapping; + loff_t offset = (loff_t) page->index << PAGE_CACHE_SHIFT; + struct inode *inode; + unsigned long end_index; + char *buffer; + yaffs_Object *obj; + int nWritten = 0; + unsigned nBytes; + + if (!mapping) + BUG(); + inode = mapping->host; + if (!inode) + BUG(); + + if (offset > inode->i_size) { + T(YAFFS_TRACE_OS, + (KERN_DEBUG + "yaffs_writepage at %08x, inode size = %08x!!!\n", + (unsigned)(page->index << PAGE_CACHE_SHIFT), + (unsigned)inode->i_size)); + T(YAFFS_TRACE_OS, + (KERN_DEBUG " -> don't care!!\n")); + unlock_page(page); + return 0; + } + + end_index = inode->i_size >> PAGE_CACHE_SHIFT; + + /* easy case */ + if (page->index < end_index) { + nBytes = PAGE_CACHE_SIZE; + } else { + nBytes = inode->i_size & (PAGE_CACHE_SIZE - 1); + } + + get_page(page); + + buffer = kmap(page); + + obj = yaffs_InodeToObject(inode); + yaffs_GrossLock(obj->myDev); + + T(YAFFS_TRACE_OS, + (KERN_DEBUG "yaffs_writepage at %08x, size %08x\n", + (unsigned)(page->index << PAGE_CACHE_SHIFT), nBytes)); + T(YAFFS_TRACE_OS, + (KERN_DEBUG "writepag0: obj = %05x, ino = %05x\n", + (int)obj->variant.fileVariant.fileSize, (int)inode->i_size)); + + nWritten = + yaffs_WriteDataToFile(obj, buffer, page->index << PAGE_CACHE_SHIFT, + nBytes, 0); + + T(YAFFS_TRACE_OS, + (KERN_DEBUG "writepag1: obj = %05x, ino = %05x\n", + (int)obj->variant.fileVariant.fileSize, (int)inode->i_size)); + + yaffs_GrossUnlock(obj->myDev); + + kunmap(page); + SetPageUptodate(page); + UnlockPage(page); + put_page(page); + + return (nWritten == nBytes) ? 0 : -ENOSPC; +} + +static int yaffs_prepare_write(struct file *f, struct page *pg, + unsigned offset, unsigned to) +{ + + T(YAFFS_TRACE_OS, (KERN_DEBUG "yaffs_prepair_write\n")); + if (!Page_Uptodate(pg) && (offset || to < PAGE_CACHE_SIZE)) + return yaffs_readpage_nolock(f, pg); + + return 0; + +} + +static int yaffs_commit_write(struct file *f, struct page *pg, unsigned offset, + unsigned to) +{ + + void *addr = page_address(pg) + offset; + loff_t pos = (((loff_t) pg->index) << PAGE_CACHE_SHIFT) + offset; + int nBytes = to - offset; + int nWritten; + + unsigned spos = pos; + unsigned saddr = (unsigned)addr; + + T(YAFFS_TRACE_OS, + (KERN_DEBUG "yaffs_commit_write addr %x pos %x nBytes %d\n", saddr, + spos, nBytes)); + + nWritten = yaffs_file_write(f, addr, nBytes, &pos); + + if (nWritten != nBytes) { + T(YAFFS_TRACE_OS, + (KERN_DEBUG + "yaffs_commit_write not same size nWritten %d nBytes %d\n", + nWritten, nBytes)); + SetPageError(pg); + ClearPageUptodate(pg); + } else { + SetPageUptodate(pg); + } + + T(YAFFS_TRACE_OS, + (KERN_DEBUG "yaffs_commit_write returning %d\n", + nWritten == nBytes ? 0 : nWritten)); + + return nWritten == nBytes ? 0 : nWritten; + +} + +static void yaffs_FillInodeFromObject(struct inode *inode, yaffs_Object * obj) +{ + if (inode && obj) { + + + /* Check mode against the variant type and attempt to repair if broken. */ + __u32 mode = obj->yst_mode; + switch( obj->variantType ){ + case YAFFS_OBJECT_TYPE_FILE : + if( ! S_ISREG(mode) ){ + obj->yst_mode &= ~S_IFMT; + obj->yst_mode |= S_IFREG; + } + + break; + case YAFFS_OBJECT_TYPE_SYMLINK : + if( ! S_ISLNK(mode) ){ + obj->yst_mode &= ~S_IFMT; + obj->yst_mode |= S_IFLNK; + } + + break; + case YAFFS_OBJECT_TYPE_DIRECTORY : + if( ! S_ISDIR(mode) ){ + obj->yst_mode &= ~S_IFMT; + obj->yst_mode |= S_IFDIR; + } + + break; + case YAFFS_OBJECT_TYPE_UNKNOWN : + case YAFFS_OBJECT_TYPE_HARDLINK : + case YAFFS_OBJECT_TYPE_SPECIAL : + default: + /* TODO? */ + break; + } + + inode->i_ino = obj->objectId; + inode->i_mode = obj->yst_mode; + inode->i_uid = obj->yst_uid; + inode->i_gid = obj->yst_gid; +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)) + inode->i_blksize = inode->i_sb->s_blocksize; +#endif +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) + + inode->i_rdev = old_decode_dev(obj->yst_rdev); + inode->i_atime.tv_sec = (time_t) (obj->yst_atime); + inode->i_atime.tv_nsec = 0; + inode->i_mtime.tv_sec = (time_t) obj->yst_mtime; + inode->i_mtime.tv_nsec = 0; + inode->i_ctime.tv_sec = (time_t) obj->yst_ctime; + inode->i_ctime.tv_nsec = 0; +#else + inode->i_rdev = obj->yst_rdev; + inode->i_atime = obj->yst_atime; + inode->i_mtime = obj->yst_mtime; + inode->i_ctime = obj->yst_ctime; +#endif + inode->i_size = yaffs_GetObjectFileLength(obj); + inode->i_blocks = (inode->i_size + 511) >> 9; + + inode->i_nlink = yaffs_GetObjectLinkCount(obj); + + T(YAFFS_TRACE_OS, + (KERN_DEBUG + "yaffs_FillInode mode %x uid %d gid %d size %d count %d\n", + inode->i_mode, inode->i_uid, inode->i_gid, + (int)inode->i_size, atomic_read(&inode->i_count))); + + switch (obj->yst_mode & S_IFMT) { + default: /* fifo, device or socket */ +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) + init_special_inode(inode, obj->yst_mode, + old_decode_dev(obj->yst_rdev)); +#else + init_special_inode(inode, obj->yst_mode, + (dev_t) (obj->yst_rdev)); +#endif + break; + case S_IFREG: /* file */ + inode->i_op = &yaffs_file_inode_operations; + inode->i_fop = &yaffs_file_operations; + inode->i_mapping->a_ops = + &yaffs_file_address_operations; + break; + case S_IFDIR: /* directory */ + inode->i_op = &yaffs_dir_inode_operations; + inode->i_fop = &yaffs_dir_operations; + break; + case S_IFLNK: /* symlink */ + inode->i_op = &yaffs_symlink_inode_operations; + break; + } + + yaffs_InodeToObjectLV(inode) = obj; + + obj->myInode = inode; + + } else { + T(YAFFS_TRACE_OS, + (KERN_DEBUG "yaffs_FileInode invalid parameters\n")); + } + +} + +struct inode *yaffs_get_inode(struct super_block *sb, int mode, int dev, + yaffs_Object * obj) +{ + struct inode *inode; + + if (!sb) { + T(YAFFS_TRACE_OS, + (KERN_DEBUG "yaffs_get_inode for NULL super_block!!\n")); + return NULL; + + } + + if (!obj) { + T(YAFFS_TRACE_OS, + (KERN_DEBUG "yaffs_get_inode for NULL object!!\n")); + return NULL; + + } + + T(YAFFS_TRACE_OS, + (KERN_DEBUG "yaffs_get_inode for object %d\n", obj->objectId)); + + inode = iget(sb, obj->objectId); + + /* NB Side effect: iget calls back to yaffs_read_inode(). */ + /* iget also increments the inode's i_count */ + /* NB You can't be holding grossLock or deadlock will happen! */ + + return inode; +} + +static ssize_t yaffs_file_write(struct file *f, const char *buf, size_t n, + loff_t * pos) +{ + yaffs_Object *obj; + int nWritten, ipos; + struct inode *inode; + yaffs_Device *dev; + + obj = yaffs_DentryToObject(f->f_dentry); + + dev = obj->myDev; + + yaffs_GrossLock(dev); + + inode = f->f_dentry->d_inode; + + if (!S_ISBLK(inode->i_mode) && f->f_flags & O_APPEND) { + ipos = inode->i_size; + } else { + ipos = *pos; + } + + if (!obj) { + T(YAFFS_TRACE_OS, + (KERN_DEBUG "yaffs_file_write: hey obj is null!\n")); + } else { + T(YAFFS_TRACE_OS, + (KERN_DEBUG + "yaffs_file_write about to write writing %d bytes" + "to object %d at %d\n", + n, obj->objectId, ipos)); + } + + nWritten = yaffs_WriteDataToFile(obj, buf, ipos, n, 0); + + T(YAFFS_TRACE_OS, + (KERN_DEBUG "yaffs_file_write writing %d bytes, %d written at %d\n", + n, nWritten, ipos)); + if (nWritten > 0) { + ipos += nWritten; + *pos = ipos; + if (ipos > inode->i_size) { + inode->i_size = ipos; + inode->i_blocks = (ipos + 511) >> 9; + + T(YAFFS_TRACE_OS, + (KERN_DEBUG + "yaffs_file_write size updated to %d bytes, " + "%d blocks\n", + ipos, (int)(inode->i_blocks))); + } + + } + yaffs_GrossUnlock(dev); + return nWritten == 0 ? -ENOSPC : nWritten; +} + +static int yaffs_readdir(struct file *f, void *dirent, filldir_t filldir) +{ + yaffs_Object *obj; + yaffs_Device *dev; + struct inode *inode = f->f_dentry->d_inode; + unsigned long offset, curoffs; + struct list_head *i; + yaffs_Object *l; + + char name[YAFFS_MAX_NAME_LENGTH + 1]; + + obj = yaffs_DentryToObject(f->f_dentry); + dev = obj->myDev; + + yaffs_GrossLock(dev); + + offset = f->f_pos; + + T(YAFFS_TRACE_OS, ("yaffs_readdir: starting at %d\n", (int)offset)); + + if (offset == 0) { + T(YAFFS_TRACE_OS, + (KERN_DEBUG "yaffs_readdir: entry . ino %d \n", + (int)inode->i_ino)); + if (filldir(dirent, ".", 1, offset, inode->i_ino, DT_DIR) + < 0) { + goto out; + } + offset++; + f->f_pos++; + } + if (offset == 1) { + T(YAFFS_TRACE_OS, + (KERN_DEBUG "yaffs_readdir: entry .. ino %d \n", + (int)f->f_dentry->d_parent->d_inode->i_ino)); + if (filldir + (dirent, "..", 2, offset, + f->f_dentry->d_parent->d_inode->i_ino, DT_DIR) < 0) { + goto out; + } + offset++; + f->f_pos++; + } + + curoffs = 1; + + /* If the directory has changed since the open or last call to + readdir, rewind to after the 2 canned entries. */ + + if (f->f_version != inode->i_version) { + offset = 2; + f->f_pos = offset; + f->f_version = inode->i_version; + } + + list_for_each(i, &obj->variant.directoryVariant.children) { + curoffs++; + if (curoffs >= offset) { + l = list_entry(i, yaffs_Object, siblings); + + yaffs_GetObjectName(l, name, + YAFFS_MAX_NAME_LENGTH + 1); + T(YAFFS_TRACE_OS, + (KERN_DEBUG "yaffs_readdir: %s inode %d\n", name, + yaffs_GetObjectInode(l))); + + if (filldir(dirent, + name, + strlen(name), + offset, + yaffs_GetObjectInode(l), + yaffs_GetObjectType(l)) + < 0) { + goto up_and_out; + } + + offset++; + f->f_pos++; + } + } + + up_and_out: + out: + + yaffs_GrossUnlock(dev); + + return 0; +} + +/* + * File creation. Allocate an inode, and we're done.. + */ +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) +static int yaffs_mknod(struct inode *dir, struct dentry *dentry, int mode, + dev_t rdev) +#else +static int yaffs_mknod(struct inode *dir, struct dentry *dentry, int mode, + int rdev) +#endif +{ + struct inode *inode; + + yaffs_Object *obj = NULL; + yaffs_Device *dev; + + yaffs_Object *parent = yaffs_InodeToObject(dir); + + int error = -ENOSPC; + uid_t uid = current->fsuid; + gid_t gid = (dir->i_mode & S_ISGID) ? dir->i_gid : current->fsgid; + + if((dir->i_mode & S_ISGID) && S_ISDIR(mode)) + mode |= S_ISGID; + + if (parent) { + T(YAFFS_TRACE_OS, + (KERN_DEBUG "yaffs_mknod: parent object %d type %d\n", + parent->objectId, parent->variantType)); + } else { + T(YAFFS_TRACE_OS, + (KERN_DEBUG "yaffs_mknod: could not get parent object\n")); + return -EPERM; + } + + T(YAFFS_TRACE_OS, ("yaffs_mknod: making oject for %s, " + "mode %x dev %x\n", + dentry->d_name.name, mode, rdev)); + + dev = parent->myDev; + + yaffs_GrossLock(dev); + + switch (mode & S_IFMT) { + default: + /* Special (socket, fifo, device...) */ + T(YAFFS_TRACE_OS, (KERN_DEBUG + "yaffs_mknod: making special\n")); +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) + obj = + yaffs_MknodSpecial(parent, dentry->d_name.name, mode, uid, + gid, old_encode_dev(rdev)); +#else + obj = + yaffs_MknodSpecial(parent, dentry->d_name.name, mode, uid, + gid, rdev); +#endif + break; + case S_IFREG: /* file */ + T(YAFFS_TRACE_OS, (KERN_DEBUG "yaffs_mknod: making file\n")); + obj = + yaffs_MknodFile(parent, dentry->d_name.name, mode, uid, + gid); + break; + case S_IFDIR: /* directory */ + T(YAFFS_TRACE_OS, + (KERN_DEBUG "yaffs_mknod: making directory\n")); + obj = + yaffs_MknodDirectory(parent, dentry->d_name.name, mode, + uid, gid); + break; + case S_IFLNK: /* symlink */ + T(YAFFS_TRACE_OS, (KERN_DEBUG "yaffs_mknod: making file\n")); + obj = NULL; /* Do we ever get here? */ + break; + } + + /* Can not call yaffs_get_inode() with gross lock held */ + yaffs_GrossUnlock(dev); + + if (obj) { + inode = yaffs_get_inode(dir->i_sb, mode, rdev, obj); + d_instantiate(dentry, inode); + T(YAFFS_TRACE_OS, + (KERN_DEBUG "yaffs_mknod created object %d count = %d\n", + obj->objectId, atomic_read(&inode->i_count))); + error = 0; + } else { + T(YAFFS_TRACE_OS, + (KERN_DEBUG "yaffs_mknod failed making object\n")); + error = -ENOMEM; + } + + return error; +} + +static int yaffs_mkdir(struct inode *dir, struct dentry *dentry, int mode) +{ + int retVal; + T(YAFFS_TRACE_OS, (KERN_DEBUG "yaffs_mkdir\n")); + retVal = yaffs_mknod(dir, dentry, mode | S_IFDIR, 0); +#if 0 + /* attempt to fix dir bug - didn't work */ + if (!retVal) { + dget(dentry); + } +#endif + return retVal; +} + +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) +static int yaffs_create(struct inode *dir, struct dentry *dentry, int mode, + struct nameidata *n) +#else +static int yaffs_create(struct inode *dir, struct dentry *dentry, int mode) +#endif +{ + T(YAFFS_TRACE_OS, (KERN_DEBUG "yaffs_create\n")); + return yaffs_mknod(dir, dentry, mode | S_IFREG, 0); +} + +static int yaffs_unlink(struct inode *dir, struct dentry *dentry) +{ + int retVal; + + yaffs_Device *dev; + + T(YAFFS_TRACE_OS, + (KERN_DEBUG "yaffs_unlink %d:%s\n", (int)(dir->i_ino), + dentry->d_name.name)); + + dev = yaffs_InodeToObject(dir)->myDev; + + yaffs_GrossLock(dev); + + retVal = yaffs_Unlink(yaffs_InodeToObject(dir), dentry->d_name.name); + + if (retVal == YAFFS_OK) { + dentry->d_inode->i_nlink--; + dir->i_version++; + yaffs_GrossUnlock(dev); + mark_inode_dirty(dentry->d_inode); + return 0; + } + yaffs_GrossUnlock(dev); + return -ENOTEMPTY; +} + +/* + * Create a link... + */ +static int yaffs_link(struct dentry *old_dentry, struct inode *dir, + struct dentry *dentry) +{ + struct inode *inode = old_dentry->d_inode; + yaffs_Object *obj = NULL; + yaffs_Object *link = NULL; + yaffs_Device *dev; + + T(YAFFS_TRACE_OS, (KERN_DEBUG "yaffs_link\n")); + + obj = yaffs_InodeToObject(inode); + dev = obj->myDev; + + yaffs_GrossLock(dev); + + if (!S_ISDIR(inode->i_mode)) /* Don't link directories */ + { + link = + yaffs_Link(yaffs_InodeToObject(dir), dentry->d_name.name, + obj); + } + + if (link) { + old_dentry->d_inode->i_nlink = yaffs_GetObjectLinkCount(obj); + d_instantiate(dentry, old_dentry->d_inode); + atomic_inc(&old_dentry->d_inode->i_count); + T(YAFFS_TRACE_OS, + (KERN_DEBUG "yaffs_link link count %d i_count %d\n", + old_dentry->d_inode->i_nlink, + atomic_read(&old_dentry->d_inode->i_count))); + + } + + yaffs_GrossUnlock(dev); + + if (link) { + + return 0; + } + + return -EPERM; +} + +static int yaffs_symlink(struct inode *dir, struct dentry *dentry, + const char *symname) +{ + yaffs_Object *obj; + yaffs_Device *dev; + uid_t uid = current->fsuid; + gid_t gid = (dir->i_mode & S_ISGID) ? dir->i_gid : current->fsgid; + + T(YAFFS_TRACE_OS, (KERN_DEBUG "yaffs_symlink\n")); + + dev = yaffs_InodeToObject(dir)->myDev; + yaffs_GrossLock(dev); + obj = yaffs_MknodSymLink(yaffs_InodeToObject(dir), dentry->d_name.name, + S_IFLNK | S_IRWXUGO, uid, gid, symname); + yaffs_GrossUnlock(dev); + + if (obj) { + + struct inode *inode; + + inode = yaffs_get_inode(dir->i_sb, obj->yst_mode, 0, obj); + d_instantiate(dentry, inode); + T(YAFFS_TRACE_OS, (KERN_DEBUG "symlink created OK\n")); + return 0; + } else { + T(YAFFS_TRACE_OS, (KERN_DEBUG "symlink not created\n")); + + } + + return -ENOMEM; +} + +static int yaffs_sync_object(struct file *file, struct dentry *dentry, + int datasync) +{ + + yaffs_Object *obj; + yaffs_Device *dev; + + obj = yaffs_DentryToObject(dentry); + + dev = obj->myDev; + + T(YAFFS_TRACE_OS, (KERN_DEBUG "yaffs_sync_object\n")); + yaffs_GrossLock(dev); + yaffs_FlushFile(obj, 1); + yaffs_GrossUnlock(dev); + return 0; +} + +/* + * The VFS layer already does all the dentry stuff for rename. + * + * NB: POSIX says you can rename an object over an old object of the same name + */ +static int yaffs_rename(struct inode *old_dir, struct dentry *old_dentry, + struct inode *new_dir, struct dentry *new_dentry) +{ + yaffs_Device *dev; + int retVal = YAFFS_FAIL; + yaffs_Object *target; + + T(YAFFS_TRACE_OS, (KERN_DEBUG "yaffs_rename\n")); + dev = yaffs_InodeToObject(old_dir)->myDev; + + yaffs_GrossLock(dev); + + /* Check if the target is an existing directory that is not empty. */ + target = + yaffs_FindObjectByName(yaffs_InodeToObject(new_dir), + new_dentry->d_name.name); + + + + if (target && + target->variantType == YAFFS_OBJECT_TYPE_DIRECTORY && + !list_empty(&target->variant.directoryVariant.children)) { + + T(YAFFS_TRACE_OS, (KERN_DEBUG "target is non-empty dir\n")); + + retVal = YAFFS_FAIL; + } else { + + /* Now does unlinking internally using shadowing mechanism */ + T(YAFFS_TRACE_OS, (KERN_DEBUG "calling yaffs_RenameObject\n")); + + retVal = + yaffs_RenameObject(yaffs_InodeToObject(old_dir), + old_dentry->d_name.name, + yaffs_InodeToObject(new_dir), + new_dentry->d_name.name); + + } + yaffs_GrossUnlock(dev); + + if (retVal == YAFFS_OK) { + if(target) { + new_dentry->d_inode->i_nlink--; + mark_inode_dirty(new_dentry->d_inode); + } + + return 0; + } else { + return -ENOTEMPTY; + } + +} + +static int yaffs_setattr(struct dentry *dentry, struct iattr *attr) +{ + struct inode *inode = dentry->d_inode; + int error; + yaffs_Device *dev; + + T(YAFFS_TRACE_OS, + (KERN_DEBUG "yaffs_setattr of object %d\n", + yaffs_InodeToObject(inode)->objectId)); + + if ((error = inode_change_ok(inode, attr)) == 0) { + + dev = yaffs_InodeToObject(inode)->myDev; + yaffs_GrossLock(dev); + if (yaffs_SetAttributes(yaffs_InodeToObject(inode), attr) == + YAFFS_OK) { + error = 0; + } else { + error = -EPERM; + } + yaffs_GrossUnlock(dev); + if (!error) + error = inode_setattr(inode, attr); + } + return error; +} + +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17)) +static int yaffs_statfs(struct dentry *dentry, struct kstatfs *buf) +{ + yaffs_Device *dev = yaffs_DentryToObject(dentry)->myDev; + struct super_block *sb = dentry->d_sb; +#elif (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) +static int yaffs_statfs(struct super_block *sb, struct kstatfs *buf) +{ + yaffs_Device *dev = yaffs_SuperToDevice(sb); +#else +static int yaffs_statfs(struct super_block *sb, struct statfs *buf) +{ + yaffs_Device *dev = yaffs_SuperToDevice(sb); +#endif + + T(YAFFS_TRACE_OS, (KERN_DEBUG "yaffs_statfs\n")); + + yaffs_GrossLock(dev); + + buf->f_type = YAFFS_MAGIC; + buf->f_bsize = sb->s_blocksize; + buf->f_namelen = 255; + if (sb->s_blocksize > dev->nDataBytesPerChunk) { + + buf->f_blocks = + (dev->endBlock - dev->startBlock + + 1) * dev->nChunksPerBlock / (sb->s_blocksize / + dev->nDataBytesPerChunk); + buf->f_bfree = + yaffs_GetNumberOfFreeChunks(dev) / (sb->s_blocksize / + dev->nDataBytesPerChunk); + } else { + + buf->f_blocks = + (dev->endBlock - dev->startBlock + + 1) * dev->nChunksPerBlock * (dev->nDataBytesPerChunk / + sb->s_blocksize); + buf->f_bfree = + yaffs_GetNumberOfFreeChunks(dev) * (dev->nDataBytesPerChunk / + sb->s_blocksize); + } + buf->f_files = 0; + buf->f_ffree = 0; + buf->f_bavail = buf->f_bfree; + + yaffs_GrossUnlock(dev); + return 0; +} + + +/** +static int yaffs_do_sync_fs(struct super_block *sb) +{ + + yaffs_Device *dev = yaffs_SuperToDevice(sb); + T(YAFFS_TRACE_OS, (KERN_DEBUG "yaffs_do_sync_fs\n")); + + if(sb->s_dirt) { + yaffs_GrossLock(dev); + + if(dev) + yaffs_CheckpointSave(dev); + + yaffs_GrossUnlock(dev); + + sb->s_dirt = 0; + } + return 0; +} +**/ + +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17)) +static void yaffs_write_super(struct super_block *sb) +#else +static int yaffs_write_super(struct super_block *sb) +#endif +{ + + T(YAFFS_TRACE_OS, (KERN_DEBUG "yaffs_write_super\n")); +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18)) + return 0; /* yaffs_do_sync_fs(sb);*/ +#endif +} + + +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17)) +static int yaffs_sync_fs(struct super_block *sb, int wait) +#else +static int yaffs_sync_fs(struct super_block *sb) +#endif +{ + + T(YAFFS_TRACE_OS, (KERN_DEBUG "yaffs_sync_fs\n")); + + return 0; /* yaffs_do_sync_fs(sb);*/ + +} + + +static void yaffs_read_inode(struct inode *inode) +{ + /* NB This is called as a side effect of other functions, but + * we had to release the lock to prevent deadlocks, so + * need to lock again. + */ + + yaffs_Object *obj; + yaffs_Device *dev = yaffs_SuperToDevice(inode->i_sb); + + T(YAFFS_TRACE_OS, + (KERN_DEBUG "yaffs_read_inode for %d\n", (int)inode->i_ino)); + + yaffs_GrossLock(dev); + + obj = yaffs_FindObjectByNumber(dev, inode->i_ino); + + yaffs_FillInodeFromObject(inode, obj); + + yaffs_GrossUnlock(dev); +} + +static LIST_HEAD(yaffs_dev_list); + +#if 0 // not used +static int yaffs_remount_fs(struct super_block *sb, int *flags, char *data) +{ + yaffs_Device *dev = yaffs_SuperToDevice(sb); + + if( *flags & MS_RDONLY ) { + struct mtd_info *mtd = yaffs_SuperToDevice(sb)->genericDevice; + + T(YAFFS_TRACE_OS, + (KERN_DEBUG "yaffs_remount_fs: %s: RO\n", dev->name )); + + yaffs_GrossLock(dev); + + yaffs_FlushEntireDeviceCache(dev); + + yaffs_CheckpointSave(dev); + + if (mtd->sync) + mtd->sync(mtd); + + yaffs_GrossUnlock(dev); + } + else { + T(YAFFS_TRACE_OS, + (KERN_DEBUG "yaffs_remount_fs: %s: RW\n", dev->name )); + } + + return 0; +} +#endif + +static void yaffs_put_super(struct super_block *sb) +{ + yaffs_Device *dev = yaffs_SuperToDevice(sb); + + T(YAFFS_TRACE_OS, (KERN_DEBUG "yaffs_put_super\n")); + + yaffs_GrossLock(dev); + + yaffs_FlushEntireDeviceCache(dev); + + yaffs_CheckpointSave(dev); + + if (dev->putSuperFunc) { + dev->putSuperFunc(sb); + } + + yaffs_Deinitialise(dev); + + yaffs_GrossUnlock(dev); + + /* we assume this is protected by lock_kernel() in mount/umount */ + list_del(&dev->devList); + + if(dev->spareBuffer){ + YFREE(dev->spareBuffer); + dev->spareBuffer = NULL; + } + + kfree(dev); +} + + +static void yaffs_MTDPutSuper(struct super_block *sb) +{ + + struct mtd_info *mtd = yaffs_SuperToDevice(sb)->genericDevice; + + if (mtd->sync) { + mtd->sync(mtd); + } + + put_mtd_device(mtd); +} + + +static void yaffs_MarkSuperBlockDirty(void *vsb) +{ + struct super_block *sb = (struct super_block *)vsb; + + T(YAFFS_TRACE_OS, (KERN_DEBUG "yaffs_MarkSuperBlockDirty() sb = %p\n",sb)); +// if(sb) +// sb->s_dirt = 1; +} + +typedef struct { + int inband_tags; + int skip_checkpoint_read; + int skip_checkpoint_write; + int no_cache; +} yaffs_options; + +#define MAX_OPT_LEN 20 +static int yaffs_parse_options(yaffs_options *options, const char *options_str) +{ + char cur_opt[MAX_OPT_LEN+1]; + int p; + int error = 0; + + /* Parse through the options which is a comma seperated list */ + + while(options_str && *options_str && !error){ + memset(cur_opt,0,MAX_OPT_LEN+1); + p = 0; + + while(*options_str && *options_str != ','){ + if(p < MAX_OPT_LEN){ + cur_opt[p] = *options_str; + p++; + } + options_str++; + } + + if(!strcmp(cur_opt,"inband-tags")) + options->inband_tags = 1; + else if(!strcmp(cur_opt,"no-cache")) + options->no_cache = 1; + else if(!strcmp(cur_opt,"no-checkpoint-read")) + options->skip_checkpoint_read = 1; + else if(!strcmp(cur_opt,"no-checkpoint-write")) + options->skip_checkpoint_write = 1; + else if(!strcmp(cur_opt,"no-checkpoint")){ + options->skip_checkpoint_read = 1; + options->skip_checkpoint_write = 1; + } else { + printk(KERN_INFO "yaffs: Bad mount option \"%s\"\n",cur_opt); + error = 1; + } + + } + + return error; +} + +static struct super_block *yaffs_internal_read_super(int yaffsVersion, + struct super_block *sb, + void *data, int silent) +{ + int nBlocks; + struct inode *inode = NULL; + struct dentry *root; + yaffs_Device *dev = 0; + char devname_buf[BDEVNAME_SIZE + 1]; + struct mtd_info *mtd; + int err; + char *data_str = (char *)data; + + yaffs_options options; + + sb->s_magic = YAFFS_MAGIC; + sb->s_op = &yaffs_super_ops; + + if (!sb) + printk(KERN_INFO "yaffs: sb is NULL\n"); + else if (!sb->s_dev) + printk(KERN_INFO "yaffs: sb->s_dev is NULL\n"); + else if (!yaffs_devname(sb, devname_buf)) + printk(KERN_INFO "yaffs: devname is NULL\n"); + else + printk(KERN_INFO "yaffs: dev is %d name is \"%s\"\n", + sb->s_dev, + yaffs_devname(sb, devname_buf)); + + if(!data_str) + data_str = ""; + + printk(KERN_INFO "yaffs: passed flags \"%s\"\n",data_str); + + memset(&options,0,sizeof(options)); + + if(yaffs_parse_options(&options,data_str)){ + /* Option parsing failed */ + return NULL; + } + + + sb->s_blocksize = PAGE_CACHE_SIZE; + sb->s_blocksize_bits = PAGE_CACHE_SHIFT; + T(YAFFS_TRACE_OS, ("yaffs_read_super: Using yaffs%d\n", yaffsVersion)); + T(YAFFS_TRACE_OS, + ("yaffs_read_super: block size %d\n", (int)(sb->s_blocksize))); + +#ifdef CONFIG_YAFFS_DISABLE_WRITE_VERIFY + T(YAFFS_TRACE_OS, + ("yaffs: Write verification disabled. All guarantees " + "null and void\n")); +#endif + + T(YAFFS_TRACE_ALWAYS, ("yaffs: Attempting MTD mount on %u.%u, " + "\"%s\"\n", + MAJOR(sb->s_dev), MINOR(sb->s_dev), + yaffs_devname(sb, devname_buf))); + + /* Check it's an mtd device..... */ + if (MAJOR(sb->s_dev) != MTD_BLOCK_MAJOR) { + return NULL; /* This isn't an mtd device */ + } + /* Get the device */ + mtd = get_mtd_device(NULL, MINOR(sb->s_dev)); + if (!mtd) { + T(YAFFS_TRACE_ALWAYS, + ("yaffs: MTD device #%u doesn't appear to exist\n", + MINOR(sb->s_dev))); + return NULL; + } + /* Check it's NAND */ + if (mtd->type != MTD_NANDFLASH) { + T(YAFFS_TRACE_ALWAYS, + ("yaffs: MTD device is not NAND it's type %d\n", mtd->type)); + return NULL; + } + + T(YAFFS_TRACE_OS, (" erase %p\n", mtd->erase)); + T(YAFFS_TRACE_OS, (" read %p\n", mtd->read)); + T(YAFFS_TRACE_OS, (" write %p\n", mtd->write)); + T(YAFFS_TRACE_OS, (" readoob %p\n", mtd->read_oob)); + T(YAFFS_TRACE_OS, (" writeoob %p\n", mtd->write_oob)); + T(YAFFS_TRACE_OS, (" block_isbad %p\n", mtd->block_isbad)); + T(YAFFS_TRACE_OS, (" block_markbad %p\n", mtd->block_markbad)); + T(YAFFS_TRACE_OS, (" %s %d\n", WRITE_SIZE_STR, WRITE_SIZE(mtd))); + T(YAFFS_TRACE_OS, (" oobsize %d\n", mtd->oobsize)); + T(YAFFS_TRACE_OS, (" erasesize %d\n", mtd->erasesize)); + T(YAFFS_TRACE_OS, (" size %d\n", mtd->size)); + +#ifdef CONFIG_YAFFS_AUTO_YAFFS2 + + if (yaffsVersion == 1 && +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17)) + mtd->writesize >= 2048) { +#else + mtd->oobblock >= 2048) { +#endif + T(YAFFS_TRACE_ALWAYS,("yaffs: auto selecting yaffs2\n")); + yaffsVersion = 2; + } + + /* Added NCB 26/5/2006 for completeness */ + if (yaffsVersion == 2 && +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17)) + mtd->writesize == 512) { +#else + mtd->oobblock == 512) { +#endif + T(YAFFS_TRACE_ALWAYS,("yaffs: auto selecting yaffs1\n")); + yaffsVersion = 1; + } + +#endif + + if (yaffsVersion == 2) { + /* Check for version 2 style functions */ + if (!mtd->erase || + !mtd->block_isbad || + !mtd->block_markbad || + !mtd->read || + !mtd->write || +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17)) + !mtd->read_oob || !mtd->write_oob) { +#else + !mtd->write_ecc || + !mtd->read_ecc || !mtd->read_oob || !mtd->write_oob) { +#endif + T(YAFFS_TRACE_ALWAYS, + ("yaffs: MTD device does not support required " + "functions\n"));; + return NULL; + } + +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17)) + if (mtd->writesize < YAFFS_MIN_YAFFS2_CHUNK_SIZE || +#else + if (mtd->oobblock < YAFFS_MIN_YAFFS2_CHUNK_SIZE || +#endif + mtd->oobsize < YAFFS_MIN_YAFFS2_SPARE_SIZE) { + T(YAFFS_TRACE_ALWAYS, + ("yaffs: MTD device does not have the " + "right page sizes\n")); + return NULL; + } + } else { + /* Check for V1 style functions */ + if (!mtd->erase || + !mtd->read || + !mtd->write || +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17)) + !mtd->read_oob || !mtd->write_oob) { +#else + !mtd->write_ecc || + !mtd->read_ecc || !mtd->read_oob || !mtd->write_oob) { +#endif + T(YAFFS_TRACE_ALWAYS, + ("yaffs: MTD device does not support required " + "functions\n"));; + return NULL; + } + + if (WRITE_SIZE(mtd) < YAFFS_BYTES_PER_CHUNK || + mtd->oobsize != YAFFS_BYTES_PER_SPARE) { + T(YAFFS_TRACE_ALWAYS, + ("yaffs: MTD device does not support have the " + "right page sizes\n")); + return NULL; + } + } + + /* OK, so if we got here, we have an MTD that's NAND and looks + * like it has the right capabilities + * Set the yaffs_Device up for mtd + */ + +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) + sb->s_fs_info = dev = kmalloc(sizeof(yaffs_Device), GFP_KERNEL); +#else + sb->u.generic_sbp = dev = kmalloc(sizeof(yaffs_Device), GFP_KERNEL); +#endif + if (!dev) { + /* Deep shit could not allocate device structure */ + T(YAFFS_TRACE_ALWAYS, + ("yaffs_read_super: Failed trying to allocate " + "yaffs_Device. \n")); + return NULL; + } + + memset(dev, 0, sizeof(yaffs_Device)); + dev->genericDevice = mtd; + dev->name = mtd->name; + + /* Set up the memory size parameters.... */ + + nBlocks = mtd->size / (YAFFS_CHUNKS_PER_BLOCK * YAFFS_BYTES_PER_CHUNK); + dev->startBlock = 0; + dev->endBlock = nBlocks - 1; + dev->nChunksPerBlock = YAFFS_CHUNKS_PER_BLOCK; + dev->nDataBytesPerChunk = YAFFS_BYTES_PER_CHUNK; + dev->nReservedBlocks = 5; + dev->nShortOpCaches = (options.no_cache) ? 0 : 10; + + /* ... and the functions. */ + if (yaffsVersion == 2) { + dev->writeChunkWithTagsToNAND = + nandmtd2_WriteChunkWithTagsToNAND; + dev->readChunkWithTagsFromNAND = + nandmtd2_ReadChunkWithTagsFromNAND; + dev->markNANDBlockBad = nandmtd2_MarkNANDBlockBad; + dev->queryNANDBlock = nandmtd2_QueryNANDBlock; + dev->spareBuffer = YMALLOC(mtd->oobsize); + dev->isYaffs2 = 1; +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17)) + dev->nDataBytesPerChunk = mtd->writesize; + dev->nChunksPerBlock = mtd->erasesize / mtd->writesize; +#else + dev->nDataBytesPerChunk = mtd->oobblock; + dev->nChunksPerBlock = mtd->erasesize / mtd->oobblock; +#endif + nBlocks = mtd->size / mtd->erasesize; + + dev->startBlock = 0; + dev->endBlock = nBlocks - 1; + } else { +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17)) + /* use the MTD interface in yaffs_mtdif1.c */ + dev->writeChunkWithTagsToNAND = + nandmtd1_WriteChunkWithTagsToNAND; + dev->readChunkWithTagsFromNAND = + nandmtd1_ReadChunkWithTagsFromNAND; + dev->markNANDBlockBad = nandmtd1_MarkNANDBlockBad; + dev->queryNANDBlock = nandmtd1_QueryNANDBlock; +#else + dev->writeChunkToNAND = nandmtd_WriteChunkToNAND; + dev->readChunkFromNAND = nandmtd_ReadChunkFromNAND; +#endif + dev->isYaffs2 = 0; + } + /* ... and common functions */ + dev->eraseBlockInNAND = nandmtd_EraseBlockInNAND; + dev->initialiseNAND = nandmtd_InitialiseNAND; + + dev->putSuperFunc = yaffs_MTDPutSuper; + + dev->superBlock = (void *)sb; + dev->markSuperBlockDirty = yaffs_MarkSuperBlockDirty; + + +#ifndef CONFIG_YAFFS_DOES_ECC + dev->useNANDECC = 1; +#endif + +#ifdef CONFIG_YAFFS_DISABLE_WIDE_TNODES + dev->wideTnodesDisabled = 1; +#endif + + dev->skipCheckpointRead = options.skip_checkpoint_read; + dev->skipCheckpointWrite = options.skip_checkpoint_write; + + /* we assume this is protected by lock_kernel() in mount/umount */ + list_add_tail(&dev->devList, &yaffs_dev_list); + + init_MUTEX(&dev->grossLock); + + yaffs_GrossLock(dev); + + err = yaffs_GutsInitialise(dev); + + T(YAFFS_TRACE_OS, + ("yaffs_read_super: guts initialised %s\n", + (err == YAFFS_OK) ? "OK" : "FAILED")); + + /* Release lock before yaffs_get_inode() */ + yaffs_GrossUnlock(dev); + + /* Create root inode */ + if (err == YAFFS_OK) + inode = yaffs_get_inode(sb, S_IFDIR | 0755, 0, + yaffs_Root(dev)); + + if (!inode) + return NULL; + + inode->i_op = &yaffs_dir_inode_operations; + inode->i_fop = &yaffs_dir_operations; + + T(YAFFS_TRACE_OS, ("yaffs_read_super: got root inode\n")); + + root = d_alloc_root(inode); + + T(YAFFS_TRACE_OS, ("yaffs_read_super: d_alloc_root done\n")); + + if (!root) { + iput(inode); + return NULL; + } + sb->s_root = root; + + T(YAFFS_TRACE_OS, ("yaffs_read_super: done\n")); + return sb; +} + + +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) +static int yaffs_internal_read_super_mtd(struct super_block *sb, void *data, + int silent) +{ + return yaffs_internal_read_super(1, sb, data, silent) ? 0 : -EINVAL; +} + +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17)) +static int yaffs_read_super(struct file_system_type *fs, + int flags, const char *dev_name, + void *data, struct vfsmount *mnt) +{ + + return get_sb_bdev(fs, flags, dev_name, data, + yaffs_internal_read_super_mtd, mnt); +} +#else +static struct super_block *yaffs_read_super(struct file_system_type *fs, + int flags, const char *dev_name, + void *data) +{ + + return get_sb_bdev(fs, flags, dev_name, data, + yaffs_internal_read_super_mtd); +} +#endif + +static struct file_system_type yaffs_fs_type = { + .owner = THIS_MODULE, + .name = "yaffs", + .get_sb = yaffs_read_super, + .kill_sb = kill_block_super, + .fs_flags = FS_REQUIRES_DEV, +}; +#else +static struct super_block *yaffs_read_super(struct super_block *sb, void *data, + int silent) +{ + return yaffs_internal_read_super(1, sb, data, silent); +} + +static DECLARE_FSTYPE(yaffs_fs_type, "yaffs", yaffs_read_super, + FS_REQUIRES_DEV); +#endif + + +#ifdef CONFIG_YAFFS_YAFFS2 + +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) +static int yaffs2_internal_read_super_mtd(struct super_block *sb, void *data, + int silent) +{ + return yaffs_internal_read_super(2, sb, data, silent) ? 0 : -EINVAL; +} + +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17)) +static int yaffs2_read_super(struct file_system_type *fs, + int flags, const char *dev_name, void *data, + struct vfsmount *mnt) +{ + return get_sb_bdev(fs, flags, dev_name, data, + yaffs2_internal_read_super_mtd, mnt); +} +#else +static struct super_block *yaffs2_read_super(struct file_system_type *fs, + int flags, const char *dev_name, + void *data) +{ + + return get_sb_bdev(fs, flags, dev_name, data, + yaffs2_internal_read_super_mtd); +} +#endif + +static struct file_system_type yaffs2_fs_type = { + .owner = THIS_MODULE, + .name = "yaffs2", + .get_sb = yaffs2_read_super, + .kill_sb = kill_block_super, + .fs_flags = FS_REQUIRES_DEV, +}; +#else +static struct super_block *yaffs2_read_super(struct super_block *sb, + void *data, int silent) +{ + return yaffs_internal_read_super(2, sb, data, silent); +} + +static DECLARE_FSTYPE(yaffs2_fs_type, "yaffs2", yaffs2_read_super, + FS_REQUIRES_DEV); +#endif + +#endif /* CONFIG_YAFFS_YAFFS2 */ + +static struct proc_dir_entry *my_proc_entry; + +static char *yaffs_dump_dev(char *buf, yaffs_Device * dev) +{ + buf += sprintf(buf, "startBlock......... %d\n", dev->startBlock); + buf += sprintf(buf, "endBlock........... %d\n", dev->endBlock); + buf += sprintf(buf, "nDataBytesPerChunk. %d\n", dev->nDataBytesPerChunk); + buf += sprintf(buf, "chunkGroupBits..... %d\n", dev->chunkGroupBits); + buf += sprintf(buf, "chunkGroupSize..... %d\n", dev->chunkGroupSize); + buf += sprintf(buf, "nErasedBlocks...... %d\n", dev->nErasedBlocks); + buf += sprintf(buf, "nReservedBlocks.... %d\n", dev->nReservedBlocks); + buf += sprintf(buf, "blocksInCheckpoint. %d\n", dev->blocksInCheckpoint); + buf += sprintf(buf, "nTnodesCreated..... %d\n", dev->nTnodesCreated); + buf += sprintf(buf, "nFreeTnodes........ %d\n", dev->nFreeTnodes); + buf += sprintf(buf, "nObjectsCreated.... %d\n", dev->nObjectsCreated); + buf += sprintf(buf, "nFreeObjects....... %d\n", dev->nFreeObjects); + buf += sprintf(buf, "nFreeChunks........ %d\n", dev->nFreeChunks); + buf += sprintf(buf, "nPageWrites........ %d\n", dev->nPageWrites); + buf += sprintf(buf, "nPageReads......... %d\n", dev->nPageReads); + buf += sprintf(buf, "nBlockErasures..... %d\n", dev->nBlockErasures); + buf += sprintf(buf, "nGCCopies.......... %d\n", dev->nGCCopies); + buf += + sprintf(buf, "garbageCollections. %d\n", dev->garbageCollections); + buf += + sprintf(buf, "passiveGCs......... %d\n", + dev->passiveGarbageCollections); + buf += sprintf(buf, "nRetriedWrites..... %d\n", dev->nRetriedWrites); + buf += sprintf(buf, "nShortOpCaches..... %d\n", dev->nShortOpCaches); + buf += sprintf(buf, "nRetireBlocks...... %d\n", dev->nRetiredBlocks); + buf += sprintf(buf, "eccFixed........... %d\n", dev->eccFixed); + buf += sprintf(buf, "eccUnfixed......... %d\n", dev->eccUnfixed); + buf += sprintf(buf, "tagsEccFixed....... %d\n", dev->tagsEccFixed); + buf += sprintf(buf, "tagsEccUnfixed..... %d\n", dev->tagsEccUnfixed); + buf += sprintf(buf, "cacheHits.......... %d\n", dev->cacheHits); + buf += sprintf(buf, "nDeletedFiles...... %d\n", dev->nDeletedFiles); + buf += sprintf(buf, "nUnlinkedFiles..... %d\n", dev->nUnlinkedFiles); + buf += + sprintf(buf, "nBackgroudDeletions %d\n", dev->nBackgroundDeletions); + buf += sprintf(buf, "useNANDECC......... %d\n", dev->useNANDECC); + buf += sprintf(buf, "isYaffs2........... %d\n", dev->isYaffs2); + + return buf; +} + +static int yaffs_proc_read(char *page, + char **start, + off_t offset, int count, int *eof, void *data) +{ + struct list_head *item; + char *buf = page; + int step = offset; + int n = 0; + + /* Get proc_file_read() to step 'offset' by one on each sucessive call. + * We use 'offset' (*ppos) to indicate where we are in devList. + * This also assumes the user has posted a read buffer large + * enough to hold the complete output; but that's life in /proc. + */ + + *(int *)start = 1; + + /* Print header first */ + if (step == 0) { + buf += sprintf(buf, "YAFFS built:" __DATE__ " " __TIME__ + "\n%s\n%s\n", yaffs_fs_c_version, + yaffs_guts_c_version); + } + + /* hold lock_kernel while traversing yaffs_dev_list */ + lock_kernel(); + + /* Locate and print the Nth entry. Order N-squared but N is small. */ + list_for_each(item, &yaffs_dev_list) { + yaffs_Device *dev = list_entry(item, yaffs_Device, devList); + if (n < step) { + n++; + continue; + } + buf += sprintf(buf, "\nDevice %d \"%s\"\n", n, dev->name); + buf = yaffs_dump_dev(buf, dev); + break; + } + unlock_kernel(); + + return buf - page < count ? buf - page : count; +} + +/** + * Set the verbosity of the warnings and error messages. + * + * Note that the names can only be a..z or _ with the current code. + */ + +static struct { + char *mask_name; + unsigned mask_bitfield; +} mask_flags[] = { + {"allocate", YAFFS_TRACE_ALLOCATE}, + {"always", YAFFS_TRACE_ALWAYS}, + {"bad_blocks", YAFFS_TRACE_BAD_BLOCKS}, + {"buffers", YAFFS_TRACE_BUFFERS}, + {"bug", YAFFS_TRACE_BUG}, + {"checkpt", YAFFS_TRACE_CHECKPOINT}, + {"deletion", YAFFS_TRACE_DELETION}, + {"erase", YAFFS_TRACE_ERASE}, + {"error", YAFFS_TRACE_ERROR}, + {"gc_detail", YAFFS_TRACE_GC_DETAIL}, + {"gc", YAFFS_TRACE_GC}, + {"mtd", YAFFS_TRACE_MTD}, + {"nandaccess", YAFFS_TRACE_NANDACCESS}, + {"os", YAFFS_TRACE_OS}, + {"scan_debug", YAFFS_TRACE_SCAN_DEBUG}, + {"scan", YAFFS_TRACE_SCAN}, + {"tracing", YAFFS_TRACE_TRACING}, + + {"verify", YAFFS_TRACE_VERIFY}, + {"verify_nand", YAFFS_TRACE_VERIFY_NAND}, + {"verify_full", YAFFS_TRACE_VERIFY_FULL}, + {"verify_all", YAFFS_TRACE_VERIFY_ALL}, + + {"write", YAFFS_TRACE_WRITE}, + {"all", 0xffffffff}, + {"none", 0}, + {NULL, 0}, +}; + +#define MAX_MASK_NAME_LENGTH 40 +static int yaffs_proc_write(struct file *file, const char *buf, + unsigned long count, void *data) +{ + unsigned rg = 0, mask_bitfield; + char *end; + char *mask_name; + const char *x; + char substring[MAX_MASK_NAME_LENGTH+1]; + int i; + int done = 0; + int add, len = 0; + int pos = 0; + + rg = yaffs_traceMask; + + while (!done && (pos < count)) { + done = 1; + while ((pos < count) && isspace(buf[pos])) { + pos++; + } + + switch (buf[pos]) { + case '+': + case '-': + case '=': + add = buf[pos]; + pos++; + break; + + default: + add = ' '; + break; + } + mask_name = NULL; + + mask_bitfield = simple_strtoul(buf + pos, &end, 0); + if (end > buf + pos) { + mask_name = "numeral"; + len = end - (buf + pos); + pos += len; + done = 0; + } else { + for(x = buf + pos, i = 0; + (*x == '_' || (*x >='a' && *x <= 'z')) && + i write_proc = yaffs_proc_write; + my_proc_entry->read_proc = yaffs_proc_read; + my_proc_entry->data = NULL; + } else { + return -ENOMEM; + } + + /* Now add the file system entries */ + + fsinst = fs_to_install; + + while (fsinst->fst && !error) { + error = register_filesystem(fsinst->fst); + if (!error) { + fsinst->installed = 1; + } + fsinst++; + } + + /* Any errors? uninstall */ + if (error) { + fsinst = fs_to_install; + + while (fsinst->fst) { + if (fsinst->installed) { + unregister_filesystem(fsinst->fst); + fsinst->installed = 0; + } + fsinst++; + } + } + + return error; +} + +static void __exit exit_yaffs_fs(void) +{ + + struct file_system_to_install *fsinst; + + T(YAFFS_TRACE_ALWAYS, ("yaffs " __DATE__ " " __TIME__ + " removing. \n")); + + remove_proc_entry("yaffs", &proc_root); + + fsinst = fs_to_install; + + while (fsinst->fst) { + if (fsinst->installed) { + unregister_filesystem(fsinst->fst); + fsinst->installed = 0; + } + fsinst++; + } + +} + +module_init(init_yaffs_fs) +module_exit(exit_yaffs_fs) + +MODULE_DESCRIPTION("YAFFS2 - a NAND specific flash file system"); +MODULE_AUTHOR("Charles Manning, Aleph One Ltd., 2002-2006"); +MODULE_LICENSE("GPL"); --- /dev/null +++ linux-2.6.20/fs/yaffs2/yaffs_guts.c @@ -0,0 +1,7532 @@ +/* + * YAFFS: Yet Another Flash File System. A NAND-flash specific file system. + * + * Copyright (C) 2002-2007 Aleph One Ltd. + * for Toby Churchill Ltd and Brightstar Engineering + * + * Created by Charles Manning + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +const char *yaffs_guts_c_version = + "$Id: yaffs_guts.c,v 1.54 2007/12/13 15:35:17 wookey Exp $"; + +#include "yportenv.h" + +#include "yaffsinterface.h" +#include "yaffs_guts.h" +#include "yaffs_tagsvalidity.h" + +#include "yaffs_tagscompat.h" +#ifndef CONFIG_YAFFS_USE_OWN_SORT +#include "yaffs_qsort.h" +#endif +#include "yaffs_nand.h" + +#include "yaffs_checkptrw.h" + +#include "yaffs_nand.h" +#include "yaffs_packedtags2.h" + + +#ifdef CONFIG_YAFFS_WINCE +void yfsd_LockYAFFS(BOOL fsLockOnly); +void yfsd_UnlockYAFFS(BOOL fsLockOnly); +#endif + +#define YAFFS_PASSIVE_GC_CHUNKS 2 + +#include "yaffs_ecc.h" + + +/* Robustification (if it ever comes about...) */ +static void yaffs_RetireBlock(yaffs_Device * dev, int blockInNAND); +static void yaffs_HandleWriteChunkError(yaffs_Device * dev, int chunkInNAND, int erasedOk); +static void yaffs_HandleWriteChunkOk(yaffs_Device * dev, int chunkInNAND, + const __u8 * data, + const yaffs_ExtendedTags * tags); +static void yaffs_HandleUpdateChunk(yaffs_Device * dev, int chunkInNAND, + const yaffs_ExtendedTags * tags); + +/* Other local prototypes */ +static int yaffs_UnlinkObject( yaffs_Object *obj); +static int yaffs_ObjectHasCachedWriteData(yaffs_Object *obj); + +static void yaffs_HardlinkFixup(yaffs_Device *dev, yaffs_Object *hardList); + +static int yaffs_WriteNewChunkWithTagsToNAND(yaffs_Device * dev, + const __u8 * buffer, + yaffs_ExtendedTags * tags, + int useReserve); +static int yaffs_PutChunkIntoFile(yaffs_Object * in, int chunkInInode, + int chunkInNAND, int inScan); + +static yaffs_Object *yaffs_CreateNewObject(yaffs_Device * dev, int number, + yaffs_ObjectType type); +static void yaffs_AddObjectToDirectory(yaffs_Object * directory, + yaffs_Object * obj); +static int yaffs_UpdateObjectHeader(yaffs_Object * in, const YCHAR * name, + int force, int isShrink, int shadows); +static void yaffs_RemoveObjectFromDirectory(yaffs_Object * obj); +static int yaffs_CheckStructures(void); +static int yaffs_DeleteWorker(yaffs_Object * in, yaffs_Tnode * tn, __u32 level, + int chunkOffset, int *limit); +static int yaffs_DoGenericObjectDeletion(yaffs_Object * in); + +static yaffs_BlockInfo *yaffs_GetBlockInfo(yaffs_Device * dev, int blockNo); + +static __u8 *yaffs_GetTempBuffer(yaffs_Device * dev, int lineNo); +static void yaffs_ReleaseTempBuffer(yaffs_Device * dev, __u8 * buffer, + int lineNo); + +static int yaffs_CheckChunkErased(struct yaffs_DeviceStruct *dev, + int chunkInNAND); + +static int yaffs_UnlinkWorker(yaffs_Object * obj); +static void yaffs_DestroyObject(yaffs_Object * obj); + +static int yaffs_TagsMatch(const yaffs_ExtendedTags * tags, int objectId, + int chunkInObject); + +loff_t yaffs_GetFileSize(yaffs_Object * obj); + +static int yaffs_AllocateChunk(yaffs_Device * dev, int useReserve, yaffs_BlockInfo **blockUsedPtr); + +static void yaffs_VerifyFreeChunks(yaffs_Device * dev); + +static void yaffs_CheckObjectDetailsLoaded(yaffs_Object *in); + +#ifdef YAFFS_PARANOID +static int yaffs_CheckFileSanity(yaffs_Object * in); +#else +#define yaffs_CheckFileSanity(in) +#endif + +static void yaffs_InvalidateWholeChunkCache(yaffs_Object * in); +static void yaffs_InvalidateChunkCache(yaffs_Object * object, int chunkId); + +static void yaffs_InvalidateCheckpoint(yaffs_Device *dev); + +static int yaffs_FindChunkInFile(yaffs_Object * in, int chunkInInode, + yaffs_ExtendedTags * tags); + +static __u32 yaffs_GetChunkGroupBase(yaffs_Device *dev, yaffs_Tnode *tn, unsigned pos); +static yaffs_Tnode *yaffs_FindLevel0Tnode(yaffs_Device * dev, + yaffs_FileStructure * fStruct, + __u32 chunkId); + + +/* Function to calculate chunk and offset */ + +static void yaffs_AddrToChunk(yaffs_Device *dev, loff_t addr, __u32 *chunk, __u32 *offset) +{ + if(dev->chunkShift){ + /* Easy-peasy power of 2 case */ + *chunk = (__u32)(addr >> dev->chunkShift); + *offset = (__u32)(addr & dev->chunkMask); + } + else if(dev->crumbsPerChunk) + { + /* Case where we're using "crumbs" */ + *offset = (__u32)(addr & dev->crumbMask); + addr >>= dev->crumbShift; + *chunk = ((__u32)addr)/dev->crumbsPerChunk; + *offset += ((addr - (*chunk * dev->crumbsPerChunk)) << dev->crumbShift); + } + else + YBUG(); +} + +/* Function to return the number of shifts for a power of 2 greater than or equal + * to the given number + * Note we don't try to cater for all possible numbers and this does not have to + * be hellishly efficient. + */ + +static __u32 ShiftsGE(__u32 x) +{ + int extraBits; + int nShifts; + + nShifts = extraBits = 0; + + while(x>1){ + if(x & 1) extraBits++; + x>>=1; + nShifts++; + } + + if(extraBits) + nShifts++; + + return nShifts; +} + +/* Function to return the number of shifts to get a 1 in bit 0 + */ + +static __u32 ShiftDiv(__u32 x) +{ + int nShifts; + + nShifts = 0; + + if(!x) return 0; + + while( !(x&1)){ + x>>=1; + nShifts++; + } + + return nShifts; +} + + + +/* + * Temporary buffer manipulations. + */ + +static int yaffs_InitialiseTempBuffers(yaffs_Device *dev) +{ + int i; + __u8 *buf = (__u8 *)1; + + memset(dev->tempBuffer,0,sizeof(dev->tempBuffer)); + + for (i = 0; buf && i < YAFFS_N_TEMP_BUFFERS; i++) { + dev->tempBuffer[i].line = 0; /* not in use */ + dev->tempBuffer[i].buffer = buf = + YMALLOC_DMA(dev->nDataBytesPerChunk); + } + + return buf ? YAFFS_OK : YAFFS_FAIL; + +} + +static __u8 *yaffs_GetTempBuffer(yaffs_Device * dev, int lineNo) +{ + int i, j; + for (i = 0; i < YAFFS_N_TEMP_BUFFERS; i++) { + if (dev->tempBuffer[i].line == 0) { + dev->tempBuffer[i].line = lineNo; + if ((i + 1) > dev->maxTemp) { + dev->maxTemp = i + 1; + for (j = 0; j <= i; j++) + dev->tempBuffer[j].maxLine = + dev->tempBuffer[j].line; + } + + return dev->tempBuffer[i].buffer; + } + } + + T(YAFFS_TRACE_BUFFERS, + (TSTR("Out of temp buffers at line %d, other held by lines:"), + lineNo)); + for (i = 0; i < YAFFS_N_TEMP_BUFFERS; i++) { + T(YAFFS_TRACE_BUFFERS, (TSTR(" %d "), dev->tempBuffer[i].line)); + } + T(YAFFS_TRACE_BUFFERS, (TSTR(" " TENDSTR))); + + /* + * If we got here then we have to allocate an unmanaged one + * This is not good. + */ + + dev->unmanagedTempAllocations++; + return YMALLOC(dev->nDataBytesPerChunk); + +} + +static void yaffs_ReleaseTempBuffer(yaffs_Device * dev, __u8 * buffer, + int lineNo) +{ + int i; + for (i = 0; i < YAFFS_N_TEMP_BUFFERS; i++) { + if (dev->tempBuffer[i].buffer == buffer) { + dev->tempBuffer[i].line = 0; + return; + } + } + + if (buffer) { + /* assume it is an unmanaged one. */ + T(YAFFS_TRACE_BUFFERS, + (TSTR("Releasing unmanaged temp buffer in line %d" TENDSTR), + lineNo)); + YFREE(buffer); + dev->unmanagedTempDeallocations++; + } + +} + +/* + * Determine if we have a managed buffer. + */ +int yaffs_IsManagedTempBuffer(yaffs_Device * dev, const __u8 * buffer) +{ + int i; + for (i = 0; i < YAFFS_N_TEMP_BUFFERS; i++) { + if (dev->tempBuffer[i].buffer == buffer) + return 1; + + } + + for (i = 0; i < dev->nShortOpCaches; i++) { + if( dev->srCache[i].data == buffer ) + return 1; + + } + + if (buffer == dev->checkpointBuffer) + return 1; + + T(YAFFS_TRACE_ALWAYS, + (TSTR("yaffs: unmaged buffer detected.\n" TENDSTR))); + return 0; +} + + + +/* + * Chunk bitmap manipulations + */ + +static Y_INLINE __u8 *yaffs_BlockBits(yaffs_Device * dev, int blk) +{ + if (blk < dev->internalStartBlock || blk > dev->internalEndBlock) { + T(YAFFS_TRACE_ERROR, + (TSTR("**>> yaffs: BlockBits block %d is not valid" TENDSTR), + blk)); + YBUG(); + } + return dev->chunkBits + + (dev->chunkBitmapStride * (blk - dev->internalStartBlock)); +} + +static Y_INLINE void yaffs_VerifyChunkBitId(yaffs_Device *dev, int blk, int chunk) +{ + if(blk < dev->internalStartBlock || blk > dev->internalEndBlock || + chunk < 0 || chunk >= dev->nChunksPerBlock) { + T(YAFFS_TRACE_ERROR, + (TSTR("**>> yaffs: Chunk Id (%d:%d) invalid"TENDSTR),blk,chunk)); + YBUG(); + } +} + +static Y_INLINE void yaffs_ClearChunkBits(yaffs_Device * dev, int blk) +{ + __u8 *blkBits = yaffs_BlockBits(dev, blk); + + memset(blkBits, 0, dev->chunkBitmapStride); +} + +static Y_INLINE void yaffs_ClearChunkBit(yaffs_Device * dev, int blk, int chunk) +{ + __u8 *blkBits = yaffs_BlockBits(dev, blk); + + yaffs_VerifyChunkBitId(dev,blk,chunk); + + blkBits[chunk / 8] &= ~(1 << (chunk & 7)); +} + +static Y_INLINE void yaffs_SetChunkBit(yaffs_Device * dev, int blk, int chunk) +{ + __u8 *blkBits = yaffs_BlockBits(dev, blk); + + yaffs_VerifyChunkBitId(dev,blk,chunk); + + blkBits[chunk / 8] |= (1 << (chunk & 7)); +} + +static Y_INLINE int yaffs_CheckChunkBit(yaffs_Device * dev, int blk, int chunk) +{ + __u8 *blkBits = yaffs_BlockBits(dev, blk); + yaffs_VerifyChunkBitId(dev,blk,chunk); + + return (blkBits[chunk / 8] & (1 << (chunk & 7))) ? 1 : 0; +} + +static Y_INLINE int yaffs_StillSomeChunkBits(yaffs_Device * dev, int blk) +{ + __u8 *blkBits = yaffs_BlockBits(dev, blk); + int i; + for (i = 0; i < dev->chunkBitmapStride; i++) { + if (*blkBits) + return 1; + blkBits++; + } + return 0; +} + +static int yaffs_CountChunkBits(yaffs_Device * dev, int blk) +{ + __u8 *blkBits = yaffs_BlockBits(dev, blk); + int i; + int n = 0; + for (i = 0; i < dev->chunkBitmapStride; i++) { + __u8 x = *blkBits; + while(x){ + if(x & 1) + n++; + x >>=1; + } + + blkBits++; + } + return n; +} + +/* + * Verification code + */ + +static int yaffs_SkipVerification(yaffs_Device *dev) +{ + return !(yaffs_traceMask & (YAFFS_TRACE_VERIFY | YAFFS_TRACE_VERIFY_FULL)); +} + +static int yaffs_SkipFullVerification(yaffs_Device *dev) +{ + return !(yaffs_traceMask & (YAFFS_TRACE_VERIFY_FULL)); +} + +static int yaffs_SkipNANDVerification(yaffs_Device *dev) +{ + return !(yaffs_traceMask & (YAFFS_TRACE_VERIFY_NAND)); +} + +static const char * blockStateName[] = { +"Unknown", +"Needs scanning", +"Scanning", +"Empty", +"Allocating", +"Full", +"Dirty", +"Checkpoint", +"Collecting", +"Dead" +}; + +static void yaffs_VerifyBlock(yaffs_Device *dev,yaffs_BlockInfo *bi,int n) +{ + int actuallyUsed; + int inUse; + + if(yaffs_SkipVerification(dev)) + return; + + /* Report illegal runtime states */ + if(bi->blockState <0 || bi->blockState >= YAFFS_NUMBER_OF_BLOCK_STATES) + T(YAFFS_TRACE_VERIFY,(TSTR("Block %d has undefined state %d"TENDSTR),n,bi->blockState)); + + switch(bi->blockState){ + case YAFFS_BLOCK_STATE_UNKNOWN: + case YAFFS_BLOCK_STATE_SCANNING: + case YAFFS_BLOCK_STATE_NEEDS_SCANNING: + T(YAFFS_TRACE_VERIFY,(TSTR("Block %d has bad run-state %s"TENDSTR), + n,blockStateName[bi->blockState])); + } + + /* Check pages in use and soft deletions are legal */ + + actuallyUsed = bi->pagesInUse - bi->softDeletions; + + if(bi->pagesInUse < 0 || bi->pagesInUse > dev->nChunksPerBlock || + bi->softDeletions < 0 || bi->softDeletions > dev->nChunksPerBlock || + actuallyUsed < 0 || actuallyUsed > dev->nChunksPerBlock) + T(YAFFS_TRACE_VERIFY,(TSTR("Block %d has illegal values pagesInUsed %d softDeletions %d"TENDSTR), + n,bi->pagesInUse,bi->softDeletions)); + + + /* Check chunk bitmap legal */ + inUse = yaffs_CountChunkBits(dev,n); + if(inUse != bi->pagesInUse) + T(YAFFS_TRACE_VERIFY,(TSTR("Block %d has inconsistent values pagesInUse %d counted chunk bits %d"TENDSTR), + n,bi->pagesInUse,inUse)); + + /* Check that the sequence number is valid. + * Ten million is legal, but is very unlikely + */ + if(dev->isYaffs2 && + (bi->blockState == YAFFS_BLOCK_STATE_ALLOCATING || bi->blockState == YAFFS_BLOCK_STATE_FULL) && + (bi->sequenceNumber < YAFFS_LOWEST_SEQUENCE_NUMBER || bi->sequenceNumber > 10000000 )) + T(YAFFS_TRACE_VERIFY,(TSTR("Block %d has suspect sequence number of %d"TENDSTR), + n,bi->sequenceNumber)); + +} + +static void yaffs_VerifyCollectedBlock(yaffs_Device *dev,yaffs_BlockInfo *bi,int n) +{ + yaffs_VerifyBlock(dev,bi,n); + + /* After collection the block should be in the erased state */ + /* TODO: This will need to change if we do partial gc */ + + if(bi->blockState != YAFFS_BLOCK_STATE_EMPTY){ + T(YAFFS_TRACE_ERROR,(TSTR("Block %d is in state %d after gc, should be erased"TENDSTR), + n,bi->blockState)); + } +} + +static void yaffs_VerifyBlocks(yaffs_Device *dev) +{ + int i; + int nBlocksPerState[YAFFS_NUMBER_OF_BLOCK_STATES]; + int nIllegalBlockStates = 0; + + + if(yaffs_SkipVerification(dev)) + return; + + memset(nBlocksPerState,0,sizeof(nBlocksPerState)); + + + for(i = dev->internalStartBlock; i <= dev->internalEndBlock; i++){ + yaffs_BlockInfo *bi = yaffs_GetBlockInfo(dev,i); + yaffs_VerifyBlock(dev,bi,i); + + if(bi->blockState >=0 && bi->blockState < YAFFS_NUMBER_OF_BLOCK_STATES) + nBlocksPerState[bi->blockState]++; + else + nIllegalBlockStates++; + + } + + T(YAFFS_TRACE_VERIFY,(TSTR(""TENDSTR))); + T(YAFFS_TRACE_VERIFY,(TSTR("Block summary"TENDSTR))); + + T(YAFFS_TRACE_VERIFY,(TSTR("%d blocks have illegal states"TENDSTR),nIllegalBlockStates)); + if(nBlocksPerState[YAFFS_BLOCK_STATE_ALLOCATING] > 1) + T(YAFFS_TRACE_VERIFY,(TSTR("Too many allocating blocks"TENDSTR))); + + for(i = 0; i < YAFFS_NUMBER_OF_BLOCK_STATES; i++) + T(YAFFS_TRACE_VERIFY, + (TSTR("%s %d blocks"TENDSTR), + blockStateName[i],nBlocksPerState[i])); + + if(dev->blocksInCheckpoint != nBlocksPerState[YAFFS_BLOCK_STATE_CHECKPOINT]) + T(YAFFS_TRACE_VERIFY, + (TSTR("Checkpoint block count wrong dev %d count %d"TENDSTR), + dev->blocksInCheckpoint, nBlocksPerState[YAFFS_BLOCK_STATE_CHECKPOINT])); + + if(dev->nErasedBlocks != nBlocksPerState[YAFFS_BLOCK_STATE_EMPTY]) + T(YAFFS_TRACE_VERIFY, + (TSTR("Erased block count wrong dev %d count %d"TENDSTR), + dev->nErasedBlocks, nBlocksPerState[YAFFS_BLOCK_STATE_EMPTY])); + + if(nBlocksPerState[YAFFS_BLOCK_STATE_COLLECTING] > 1) + T(YAFFS_TRACE_VERIFY, + (TSTR("Too many collecting blocks %d (max is 1)"TENDSTR), + nBlocksPerState[YAFFS_BLOCK_STATE_COLLECTING])); + + T(YAFFS_TRACE_VERIFY,(TSTR(""TENDSTR))); + +} + +/* + * Verify the object header. oh must be valid, but obj and tags may be NULL in which + * case those tests will not be performed. + */ +static void yaffs_VerifyObjectHeader(yaffs_Object *obj, yaffs_ObjectHeader *oh, yaffs_ExtendedTags *tags, int parentCheck) +{ + if(yaffs_SkipVerification(obj->myDev)) + return; + + if(!(tags && obj && oh)){ + T(YAFFS_TRACE_VERIFY, + (TSTR("Verifying object header tags %x obj %x oh %x"TENDSTR), + (__u32)tags,(__u32)obj,(__u32)oh)); + return; + } + + if(oh->type <= YAFFS_OBJECT_TYPE_UNKNOWN || + oh->type > YAFFS_OBJECT_TYPE_MAX) + T(YAFFS_TRACE_VERIFY, + (TSTR("Obj %d header type is illegal value 0x%x"TENDSTR), + tags->objectId, oh->type)); + + if(tags->objectId != obj->objectId) + T(YAFFS_TRACE_VERIFY, + (TSTR("Obj %d header mismatch objectId %d"TENDSTR), + tags->objectId, obj->objectId)); + + + /* + * Check that the object's parent ids match if parentCheck requested. + * + * Tests do not apply to the root object. + */ + + if(parentCheck && tags->objectId > 1 && !obj->parent) + T(YAFFS_TRACE_VERIFY, + (TSTR("Obj %d header mismatch parentId %d obj->parent is NULL"TENDSTR), + tags->objectId, oh->parentObjectId)); + + + if(parentCheck && obj->parent && + oh->parentObjectId != obj->parent->objectId && + (oh->parentObjectId != YAFFS_OBJECTID_UNLINKED || + obj->parent->objectId != YAFFS_OBJECTID_DELETED)) + T(YAFFS_TRACE_VERIFY, + (TSTR("Obj %d header mismatch parentId %d parentObjectId %d"TENDSTR), + tags->objectId, oh->parentObjectId, obj->parent->objectId)); + + + if(tags->objectId > 1 && oh->name[0] == 0) /* Null name */ + T(YAFFS_TRACE_VERIFY, + (TSTR("Obj %d header name is NULL"TENDSTR), + obj->objectId)); + + if(tags->objectId > 1 && ((__u8)(oh->name[0])) == 0xff) /* Trashed name */ + T(YAFFS_TRACE_VERIFY, + (TSTR("Obj %d header name is 0xFF"TENDSTR), + obj->objectId)); +} + + + +static int yaffs_VerifyTnodeWorker(yaffs_Object * obj, yaffs_Tnode * tn, + __u32 level, int chunkOffset) +{ + int i; + yaffs_Device *dev = obj->myDev; + int ok = 1; + int nTnodeBytes = (dev->tnodeWidth * YAFFS_NTNODES_LEVEL0)/8; + + if (tn) { + if (level > 0) { + + for (i = 0; i < YAFFS_NTNODES_INTERNAL && ok; i++){ + if (tn->internal[i]) { + ok = yaffs_VerifyTnodeWorker(obj, + tn->internal[i], + level - 1, + (chunkOffset<objectId; + + chunkOffset <<= YAFFS_TNODES_LEVEL0_BITS; + + for(i = 0; i < YAFFS_NTNODES_LEVEL0; i++){ + __u32 theChunk = yaffs_GetChunkGroupBase(dev,tn,i); + + if(theChunk > 0){ + /* T(~0,(TSTR("verifying (%d:%d) %d"TENDSTR),tags.objectId,tags.chunkId,theChunk)); */ + yaffs_ReadChunkWithTagsFromNAND(dev,theChunk,NULL, &tags); + if(tags.objectId != objectId || tags.chunkId != chunkOffset){ + T(~0,(TSTR("Object %d chunkId %d NAND mismatch chunk %d tags (%d:%d)"TENDSTR), + objectId, chunkOffset, theChunk, + tags.objectId, tags.chunkId)); + } + } + chunkOffset++; + } + } + } + + return ok; + +} + + +static void yaffs_VerifyFile(yaffs_Object *obj) +{ + int requiredTallness; + int actualTallness; + __u32 lastChunk; + __u32 x; + __u32 i; + int ok; + yaffs_Device *dev; + yaffs_ExtendedTags tags; + yaffs_Tnode *tn; + __u32 objectId; + + if(obj && yaffs_SkipVerification(obj->myDev)) + return; + + dev = obj->myDev; + objectId = obj->objectId; + + /* Check file size is consistent with tnode depth */ + lastChunk = obj->variant.fileVariant.fileSize / dev->nDataBytesPerChunk + 1; + x = lastChunk >> YAFFS_TNODES_LEVEL0_BITS; + requiredTallness = 0; + while (x> 0) { + x >>= YAFFS_TNODES_INTERNAL_BITS; + requiredTallness++; + } + + actualTallness = obj->variant.fileVariant.topLevel; + + if(requiredTallness > actualTallness ) + T(YAFFS_TRACE_VERIFY, + (TSTR("Obj %d had tnode tallness %d, needs to be %d"TENDSTR), + obj->objectId,actualTallness, requiredTallness)); + + + /* Check that the chunks in the tnode tree are all correct. + * We do this by scanning through the tnode tree and + * checking the tags for every chunk match. + */ + + if(yaffs_SkipNANDVerification(dev)) + return; + + for(i = 1; i <= lastChunk; i++){ + tn = yaffs_FindLevel0Tnode(dev, &obj->variant.fileVariant,i); + + if (tn) { + __u32 theChunk = yaffs_GetChunkGroupBase(dev,tn,i); + if(theChunk > 0){ + /* T(~0,(TSTR("verifying (%d:%d) %d"TENDSTR),objectId,i,theChunk)); */ + yaffs_ReadChunkWithTagsFromNAND(dev,theChunk,NULL, &tags); + if(tags.objectId != objectId || tags.chunkId != i){ + T(~0,(TSTR("Object %d chunkId %d NAND mismatch chunk %d tags (%d:%d)"TENDSTR), + objectId, i, theChunk, + tags.objectId, tags.chunkId)); + } + } + } + + } + +} + +static void yaffs_VerifyDirectory(yaffs_Object *obj) +{ + if(obj && yaffs_SkipVerification(obj->myDev)) + return; + +} + +static void yaffs_VerifyHardLink(yaffs_Object *obj) +{ + if(obj && yaffs_SkipVerification(obj->myDev)) + return; + + /* Verify sane equivalent object */ +} + +static void yaffs_VerifySymlink(yaffs_Object *obj) +{ + if(obj && yaffs_SkipVerification(obj->myDev)) + return; + + /* Verify symlink string */ +} + +static void yaffs_VerifySpecial(yaffs_Object *obj) +{ + if(obj && yaffs_SkipVerification(obj->myDev)) + return; +} + +static void yaffs_VerifyObject(yaffs_Object *obj) +{ + yaffs_Device *dev; + + __u32 chunkMin; + __u32 chunkMax; + + __u32 chunkIdOk; + __u32 chunkIsLive; + + if(!obj) + return; + + dev = obj->myDev; + + if(yaffs_SkipVerification(dev)) + return; + + /* Check sane object header chunk */ + + chunkMin = dev->internalStartBlock * dev->nChunksPerBlock; + chunkMax = (dev->internalEndBlock+1) * dev->nChunksPerBlock - 1; + + chunkIdOk = (obj->chunkId >= chunkMin && obj->chunkId <= chunkMax); + chunkIsLive = chunkIdOk && + yaffs_CheckChunkBit(dev, + obj->chunkId / dev->nChunksPerBlock, + obj->chunkId % dev->nChunksPerBlock); + if(!obj->fake && + (!chunkIdOk || !chunkIsLive)) { + T(YAFFS_TRACE_VERIFY, + (TSTR("Obj %d has chunkId %d %s %s"TENDSTR), + obj->objectId,obj->chunkId, + chunkIdOk ? "" : ",out of range", + chunkIsLive || !chunkIdOk ? "" : ",marked as deleted")); + } + + if(chunkIdOk && chunkIsLive &&!yaffs_SkipNANDVerification(dev)) { + yaffs_ExtendedTags tags; + yaffs_ObjectHeader *oh; + __u8 *buffer = yaffs_GetTempBuffer(dev,__LINE__); + + oh = (yaffs_ObjectHeader *)buffer; + + yaffs_ReadChunkWithTagsFromNAND(dev, obj->chunkId,buffer, &tags); + + yaffs_VerifyObjectHeader(obj,oh,&tags,1); + + yaffs_ReleaseTempBuffer(dev,buffer,__LINE__); + } + + /* Verify it has a parent */ + if(obj && !obj->fake && + (!obj->parent || obj->parent->myDev != dev)){ + T(YAFFS_TRACE_VERIFY, + (TSTR("Obj %d has parent pointer %p which does not look like an object"TENDSTR), + obj->objectId,obj->parent)); + } + + /* Verify parent is a directory */ + if(obj->parent && obj->parent->variantType != YAFFS_OBJECT_TYPE_DIRECTORY){ + T(YAFFS_TRACE_VERIFY, + (TSTR("Obj %d's parent is not a directory (type %d)"TENDSTR), + obj->objectId,obj->parent->variantType)); + } + + switch(obj->variantType){ + case YAFFS_OBJECT_TYPE_FILE: + yaffs_VerifyFile(obj); + break; + case YAFFS_OBJECT_TYPE_SYMLINK: + yaffs_VerifySymlink(obj); + break; + case YAFFS_OBJECT_TYPE_DIRECTORY: + yaffs_VerifyDirectory(obj); + break; + case YAFFS_OBJECT_TYPE_HARDLINK: + yaffs_VerifyHardLink(obj); + break; + case YAFFS_OBJECT_TYPE_SPECIAL: + yaffs_VerifySpecial(obj); + break; + case YAFFS_OBJECT_TYPE_UNKNOWN: + default: + T(YAFFS_TRACE_VERIFY, + (TSTR("Obj %d has illegaltype %d"TENDSTR), + obj->objectId,obj->variantType)); + break; + } + + +} + +static void yaffs_VerifyObjects(yaffs_Device *dev) +{ + yaffs_Object *obj; + int i; + struct list_head *lh; + + if(yaffs_SkipVerification(dev)) + return; + + /* Iterate through the objects in each hash entry */ + + for(i = 0; i < YAFFS_NOBJECT_BUCKETS; i++){ + list_for_each(lh, &dev->objectBucket[i].list) { + if (lh) { + obj = list_entry(lh, yaffs_Object, hashLink); + yaffs_VerifyObject(obj); + } + } + } + +} + + +/* + * Simple hash function. Needs to have a reasonable spread + */ + +static Y_INLINE int yaffs_HashFunction(int n) +{ + n = abs(n); + return (n % YAFFS_NOBJECT_BUCKETS); +} + +/* + * Access functions to useful fake objects + */ + +yaffs_Object *yaffs_Root(yaffs_Device * dev) +{ + return dev->rootDir; +} + +yaffs_Object *yaffs_LostNFound(yaffs_Device * dev) +{ + return dev->lostNFoundDir; +} + + +/* + * Erased NAND checking functions + */ + +int yaffs_CheckFF(__u8 * buffer, int nBytes) +{ + /* Horrible, slow implementation */ + while (nBytes--) { + if (*buffer != 0xFF) + return 0; + buffer++; + } + return 1; +} + +static int yaffs_CheckChunkErased(struct yaffs_DeviceStruct *dev, + int chunkInNAND) +{ + + int retval = YAFFS_OK; + __u8 *data = yaffs_GetTempBuffer(dev, __LINE__); + yaffs_ExtendedTags tags; + int result; + + result = yaffs_ReadChunkWithTagsFromNAND(dev, chunkInNAND, data, &tags); + + if(tags.eccResult > YAFFS_ECC_RESULT_NO_ERROR) + retval = YAFFS_FAIL; + + + if (!yaffs_CheckFF(data, dev->nDataBytesPerChunk) || tags.chunkUsed) { + T(YAFFS_TRACE_NANDACCESS, + (TSTR("Chunk %d not erased" TENDSTR), chunkInNAND)); + retval = YAFFS_FAIL; + } + + yaffs_ReleaseTempBuffer(dev, data, __LINE__); + + return retval; + +} + +static int yaffs_WriteNewChunkWithTagsToNAND(struct yaffs_DeviceStruct *dev, + const __u8 * data, + yaffs_ExtendedTags * tags, + int useReserve) +{ + int attempts = 0; + int writeOk = 0; + int chunk; + + yaffs_InvalidateCheckpoint(dev); + + do { + yaffs_BlockInfo *bi = 0; + int erasedOk = 0; + + chunk = yaffs_AllocateChunk(dev, useReserve, &bi); + if (chunk < 0) { + /* no space */ + break; + } + + /* First check this chunk is erased, if it needs + * checking. The checking policy (unless forced + * always on) is as follows: + * + * Check the first page we try to write in a block. + * If the check passes then we don't need to check any + * more. If the check fails, we check again... + * If the block has been erased, we don't need to check. + * + * However, if the block has been prioritised for gc, + * then we think there might be something odd about + * this block and stop using it. + * + * Rationale: We should only ever see chunks that have + * not been erased if there was a partially written + * chunk due to power loss. This checking policy should + * catch that case with very few checks and thus save a + * lot of checks that are most likely not needed. + */ + if (bi->gcPrioritise) { + yaffs_DeleteChunk(dev, chunk, 1, __LINE__); + /* try another chunk */ + continue; + } + + /* let's give it a try */ + attempts++; + +#ifdef CONFIG_YAFFS_ALWAYS_CHECK_CHUNK_ERASED + bi->skipErasedCheck = 0; +#endif + if (!bi->skipErasedCheck) { + erasedOk = yaffs_CheckChunkErased(dev, chunk); + if (erasedOk != YAFFS_OK) { + T(YAFFS_TRACE_ERROR, + (TSTR ("**>> yaffs chunk %d was not erased" + TENDSTR), chunk)); + + /* try another chunk */ + continue; + } + bi->skipErasedCheck = 1; + } + + writeOk = yaffs_WriteChunkWithTagsToNAND(dev, chunk, + data, tags); + if (writeOk != YAFFS_OK) { + yaffs_HandleWriteChunkError(dev, chunk, erasedOk); + /* try another chunk */ + continue; + } + + /* Copy the data into the robustification buffer */ + yaffs_HandleWriteChunkOk(dev, chunk, data, tags); + + } while (writeOk != YAFFS_OK && + (yaffs_wr_attempts <= 0 || attempts <= yaffs_wr_attempts)); + + if(!writeOk) + chunk = -1; + + if (attempts > 1) { + T(YAFFS_TRACE_ERROR, + (TSTR("**>> yaffs write required %d attempts" TENDSTR), + attempts)); + + dev->nRetriedWrites += (attempts - 1); + } + + return chunk; +} + +/* + * Block retiring for handling a broken block. + */ + +static void yaffs_RetireBlock(yaffs_Device * dev, int blockInNAND) +{ + yaffs_BlockInfo *bi = yaffs_GetBlockInfo(dev, blockInNAND); + + yaffs_InvalidateCheckpoint(dev); + + yaffs_MarkBlockBad(dev, blockInNAND); + + bi->blockState = YAFFS_BLOCK_STATE_DEAD; + bi->gcPrioritise = 0; + bi->needsRetiring = 0; + + dev->nRetiredBlocks++; +} + +/* + * Functions for robustisizing TODO + * + */ + +static void yaffs_HandleWriteChunkOk(yaffs_Device * dev, int chunkInNAND, + const __u8 * data, + const yaffs_ExtendedTags * tags) +{ +} + +static void yaffs_HandleUpdateChunk(yaffs_Device * dev, int chunkInNAND, + const yaffs_ExtendedTags * tags) +{ +} + +void yaffs_HandleChunkError(yaffs_Device *dev, yaffs_BlockInfo *bi) +{ + if(!bi->gcPrioritise){ + bi->gcPrioritise = 1; + dev->hasPendingPrioritisedGCs = 1; + bi->chunkErrorStrikes ++; + + if(bi->chunkErrorStrikes > 3){ + bi->needsRetiring = 1; /* Too many stikes, so retire this */ + T(YAFFS_TRACE_ALWAYS, (TSTR("yaffs: Block struck out" TENDSTR))); + + } + + } +} + +static void yaffs_HandleWriteChunkError(yaffs_Device * dev, int chunkInNAND, int erasedOk) +{ + + int blockInNAND = chunkInNAND / dev->nChunksPerBlock; + yaffs_BlockInfo *bi = yaffs_GetBlockInfo(dev, blockInNAND); + + yaffs_HandleChunkError(dev,bi); + + + if(erasedOk ) { + /* Was an actual write failure, so mark the block for retirement */ + bi->needsRetiring = 1; + T(YAFFS_TRACE_ERROR | YAFFS_TRACE_BAD_BLOCKS, + (TSTR("**>> Block %d needs retiring" TENDSTR), blockInNAND)); + + + } + + /* Delete the chunk */ + yaffs_DeleteChunk(dev, chunkInNAND, 1, __LINE__); +} + + +/*---------------- Name handling functions ------------*/ + +static __u16 yaffs_CalcNameSum(const YCHAR * name) +{ + __u16 sum = 0; + __u16 i = 1; + + YUCHAR *bname = (YUCHAR *) name; + if (bname) { + while ((*bname) && (i < (YAFFS_MAX_NAME_LENGTH/2))) { + +#ifdef CONFIG_YAFFS_CASE_INSENSITIVE + sum += yaffs_toupper(*bname) * i; +#else + sum += (*bname) * i; +#endif + i++; + bname++; + } + } + return sum; +} + +static void yaffs_SetObjectName(yaffs_Object * obj, const YCHAR * name) +{ +#ifdef CONFIG_YAFFS_SHORT_NAMES_IN_RAM + if (name && yaffs_strlen(name) <= YAFFS_SHORT_NAME_LENGTH) { + yaffs_strcpy(obj->shortName, name); + } else { + obj->shortName[0] = _Y('\0'); + } +#endif + obj->sum = yaffs_CalcNameSum(name); +} + +/*-------------------- TNODES ------------------- + + * List of spare tnodes + * The list is hooked together using the first pointer + * in the tnode. + */ + +/* yaffs_CreateTnodes creates a bunch more tnodes and + * adds them to the tnode free list. + * Don't use this function directly + */ + +static int yaffs_CreateTnodes(yaffs_Device * dev, int nTnodes) +{ + int i; + int tnodeSize; + yaffs_Tnode *newTnodes; + __u8 *mem; + yaffs_Tnode *curr; + yaffs_Tnode *next; + yaffs_TnodeList *tnl; + + if (nTnodes < 1) + return YAFFS_OK; + + /* Calculate the tnode size in bytes for variable width tnode support. + * Must be a multiple of 32-bits */ + tnodeSize = (dev->tnodeWidth * YAFFS_NTNODES_LEVEL0)/8; + + if(tnodeSize < sizeof(yaffs_Tnode)) + tnodeSize = sizeof(yaffs_Tnode); + + + /* make these things */ + + newTnodes = YMALLOC(nTnodes * tnodeSize); + mem = (__u8 *)newTnodes; + + if (!newTnodes) { + T(YAFFS_TRACE_ERROR, + (TSTR("yaffs: Could not allocate Tnodes" TENDSTR))); + return YAFFS_FAIL; + } + + /* Hook them into the free list */ +#if 0 + for (i = 0; i < nTnodes - 1; i++) { + newTnodes[i].internal[0] = &newTnodes[i + 1]; +#ifdef CONFIG_YAFFS_TNODE_LIST_DEBUG + newTnodes[i].internal[YAFFS_NTNODES_INTERNAL] = (void *)1; +#endif + } + + newTnodes[nTnodes - 1].internal[0] = dev->freeTnodes; +#ifdef CONFIG_YAFFS_TNODE_LIST_DEBUG + newTnodes[nTnodes - 1].internal[YAFFS_NTNODES_INTERNAL] = (void *)1; +#endif + dev->freeTnodes = newTnodes; +#else + /* New hookup for wide tnodes */ + for(i = 0; i < nTnodes -1; i++) { + curr = (yaffs_Tnode *) &mem[i * tnodeSize]; + next = (yaffs_Tnode *) &mem[(i+1) * tnodeSize]; + curr->internal[0] = next; + } + + curr = (yaffs_Tnode *) &mem[(nTnodes - 1) * tnodeSize]; + curr->internal[0] = dev->freeTnodes; + dev->freeTnodes = (yaffs_Tnode *)mem; + +#endif + + + dev->nFreeTnodes += nTnodes; + dev->nTnodesCreated += nTnodes; + + /* Now add this bunch of tnodes to a list for freeing up. + * NB If we can't add this to the management list it isn't fatal + * but it just means we can't free this bunch of tnodes later. + */ + + tnl = YMALLOC(sizeof(yaffs_TnodeList)); + if (!tnl) { + T(YAFFS_TRACE_ERROR, + (TSTR + ("yaffs: Could not add tnodes to management list" TENDSTR))); + return YAFFS_FAIL; + + } else { + tnl->tnodes = newTnodes; + tnl->next = dev->allocatedTnodeList; + dev->allocatedTnodeList = tnl; + } + + T(YAFFS_TRACE_ALLOCATE, (TSTR("yaffs: Tnodes added" TENDSTR))); + + return YAFFS_OK; +} + +/* GetTnode gets us a clean tnode. Tries to make allocate more if we run out */ + +static yaffs_Tnode *yaffs_GetTnodeRaw(yaffs_Device * dev) +{ + yaffs_Tnode *tn = NULL; + + /* If there are none left make more */ + if (!dev->freeTnodes) { + yaffs_CreateTnodes(dev, YAFFS_ALLOCATION_NTNODES); + } + + if (dev->freeTnodes) { + tn = dev->freeTnodes; +#ifdef CONFIG_YAFFS_TNODE_LIST_DEBUG + if (tn->internal[YAFFS_NTNODES_INTERNAL] != (void *)1) { + /* Hoosterman, this thing looks like it isn't in the list */ + T(YAFFS_TRACE_ALWAYS, + (TSTR("yaffs: Tnode list bug 1" TENDSTR))); + } +#endif + dev->freeTnodes = dev->freeTnodes->internal[0]; + dev->nFreeTnodes--; + } + + dev->nCheckpointBlocksRequired = 0; /* force recalculation*/ + + return tn; +} + +static yaffs_Tnode *yaffs_GetTnode(yaffs_Device * dev) +{ + yaffs_Tnode *tn = yaffs_GetTnodeRaw(dev); + int tnodeSize = (dev->tnodeWidth * YAFFS_NTNODES_LEVEL0)/8; + + if(tnodeSize < sizeof(yaffs_Tnode)) + tnodeSize = sizeof(yaffs_Tnode); + + if(tn) + memset(tn, 0, tnodeSize); + + return tn; +} + +/* FreeTnode frees up a tnode and puts it back on the free list */ +static void yaffs_FreeTnode(yaffs_Device * dev, yaffs_Tnode * tn) +{ + if (tn) { +#ifdef CONFIG_YAFFS_TNODE_LIST_DEBUG + if (tn->internal[YAFFS_NTNODES_INTERNAL] != 0) { + /* Hoosterman, this thing looks like it is already in the list */ + T(YAFFS_TRACE_ALWAYS, + (TSTR("yaffs: Tnode list bug 2" TENDSTR))); + } + tn->internal[YAFFS_NTNODES_INTERNAL] = (void *)1; +#endif + tn->internal[0] = dev->freeTnodes; + dev->freeTnodes = tn; + dev->nFreeTnodes++; + } + dev->nCheckpointBlocksRequired = 0; /* force recalculation*/ + +} + +static void yaffs_DeinitialiseTnodes(yaffs_Device * dev) +{ + /* Free the list of allocated tnodes */ + yaffs_TnodeList *tmp; + + while (dev->allocatedTnodeList) { + tmp = dev->allocatedTnodeList->next; + + YFREE(dev->allocatedTnodeList->tnodes); + YFREE(dev->allocatedTnodeList); + dev->allocatedTnodeList = tmp; + + } + + dev->freeTnodes = NULL; + dev->nFreeTnodes = 0; +} + +static void yaffs_InitialiseTnodes(yaffs_Device * dev) +{ + dev->allocatedTnodeList = NULL; + dev->freeTnodes = NULL; + dev->nFreeTnodes = 0; + dev->nTnodesCreated = 0; + +} + + +void yaffs_PutLevel0Tnode(yaffs_Device *dev, yaffs_Tnode *tn, unsigned pos, unsigned val) +{ + __u32 *map = (__u32 *)tn; + __u32 bitInMap; + __u32 bitInWord; + __u32 wordInMap; + __u32 mask; + + pos &= YAFFS_TNODES_LEVEL0_MASK; + val >>= dev->chunkGroupBits; + + bitInMap = pos * dev->tnodeWidth; + wordInMap = bitInMap /32; + bitInWord = bitInMap & (32 -1); + + mask = dev->tnodeMask << bitInWord; + + map[wordInMap] &= ~mask; + map[wordInMap] |= (mask & (val << bitInWord)); + + if(dev->tnodeWidth > (32-bitInWord)) { + bitInWord = (32 - bitInWord); + wordInMap++;; + mask = dev->tnodeMask >> (/*dev->tnodeWidth -*/ bitInWord); + map[wordInMap] &= ~mask; + map[wordInMap] |= (mask & (val >> bitInWord)); + } +} + +static __u32 yaffs_GetChunkGroupBase(yaffs_Device *dev, yaffs_Tnode *tn, unsigned pos) +{ + __u32 *map = (__u32 *)tn; + __u32 bitInMap; + __u32 bitInWord; + __u32 wordInMap; + __u32 val; + + pos &= YAFFS_TNODES_LEVEL0_MASK; + + bitInMap = pos * dev->tnodeWidth; + wordInMap = bitInMap /32; + bitInWord = bitInMap & (32 -1); + + val = map[wordInMap] >> bitInWord; + + if(dev->tnodeWidth > (32-bitInWord)) { + bitInWord = (32 - bitInWord); + wordInMap++;; + val |= (map[wordInMap] << bitInWord); + } + + val &= dev->tnodeMask; + val <<= dev->chunkGroupBits; + + return val; +} + +/* ------------------- End of individual tnode manipulation -----------------*/ + +/* ---------Functions to manipulate the look-up tree (made up of tnodes) ------ + * The look up tree is represented by the top tnode and the number of topLevel + * in the tree. 0 means only the level 0 tnode is in the tree. + */ + +/* FindLevel0Tnode finds the level 0 tnode, if one exists. */ +static yaffs_Tnode *yaffs_FindLevel0Tnode(yaffs_Device * dev, + yaffs_FileStructure * fStruct, + __u32 chunkId) +{ + + yaffs_Tnode *tn = fStruct->top; + __u32 i; + int requiredTallness; + int level = fStruct->topLevel; + + /* Check sane level and chunk Id */ + if (level < 0 || level > YAFFS_TNODES_MAX_LEVEL) { + return NULL; + } + + if (chunkId > YAFFS_MAX_CHUNK_ID) { + return NULL; + } + + /* First check we're tall enough (ie enough topLevel) */ + + i = chunkId >> YAFFS_TNODES_LEVEL0_BITS; + requiredTallness = 0; + while (i) { + i >>= YAFFS_TNODES_INTERNAL_BITS; + requiredTallness++; + } + + if (requiredTallness > fStruct->topLevel) { + /* Not tall enough, so we can't find it, return NULL. */ + return NULL; + } + + /* Traverse down to level 0 */ + while (level > 0 && tn) { + tn = tn-> + internal[(chunkId >> + ( YAFFS_TNODES_LEVEL0_BITS + + (level - 1) * + YAFFS_TNODES_INTERNAL_BITS) + ) & + YAFFS_TNODES_INTERNAL_MASK]; + level--; + + } + + return tn; +} + +/* AddOrFindLevel0Tnode finds the level 0 tnode if it exists, otherwise first expands the tree. + * This happens in two steps: + * 1. If the tree isn't tall enough, then make it taller. + * 2. Scan down the tree towards the level 0 tnode adding tnodes if required. + * + * Used when modifying the tree. + * + * If the tn argument is NULL, then a fresh tnode will be added otherwise the specified tn will + * be plugged into the ttree. + */ + +static yaffs_Tnode *yaffs_AddOrFindLevel0Tnode(yaffs_Device * dev, + yaffs_FileStructure * fStruct, + __u32 chunkId, + yaffs_Tnode *passedTn) +{ + + int requiredTallness; + int i; + int l; + yaffs_Tnode *tn; + + __u32 x; + + + /* Check sane level and page Id */ + if (fStruct->topLevel < 0 || fStruct->topLevel > YAFFS_TNODES_MAX_LEVEL) { + return NULL; + } + + if (chunkId > YAFFS_MAX_CHUNK_ID) { + return NULL; + } + + /* First check we're tall enough (ie enough topLevel) */ + + x = chunkId >> YAFFS_TNODES_LEVEL0_BITS; + requiredTallness = 0; + while (x) { + x >>= YAFFS_TNODES_INTERNAL_BITS; + requiredTallness++; + } + + + if (requiredTallness > fStruct->topLevel) { + /* Not tall enough,gotta make the tree taller */ + for (i = fStruct->topLevel; i < requiredTallness; i++) { + + tn = yaffs_GetTnode(dev); + + if (tn) { + tn->internal[0] = fStruct->top; + fStruct->top = tn; + } else { + T(YAFFS_TRACE_ERROR, + (TSTR("yaffs: no more tnodes" TENDSTR))); + } + } + + fStruct->topLevel = requiredTallness; + } + + /* Traverse down to level 0, adding anything we need */ + + l = fStruct->topLevel; + tn = fStruct->top; + + if(l > 0) { + while (l > 0 && tn) { + x = (chunkId >> + ( YAFFS_TNODES_LEVEL0_BITS + + (l - 1) * YAFFS_TNODES_INTERNAL_BITS)) & + YAFFS_TNODES_INTERNAL_MASK; + + + if((l>1) && !tn->internal[x]){ + /* Add missing non-level-zero tnode */ + tn->internal[x] = yaffs_GetTnode(dev); + + } else if(l == 1) { + /* Looking from level 1 at level 0 */ + if (passedTn) { + /* If we already have one, then release it.*/ + if(tn->internal[x]) + yaffs_FreeTnode(dev,tn->internal[x]); + tn->internal[x] = passedTn; + + } else if(!tn->internal[x]) { + /* Don't have one, none passed in */ + tn->internal[x] = yaffs_GetTnode(dev); + } + } + + tn = tn->internal[x]; + l--; + } + } else { + /* top is level 0 */ + if(passedTn) { + memcpy(tn,passedTn,(dev->tnodeWidth * YAFFS_NTNODES_LEVEL0)/8); + yaffs_FreeTnode(dev,passedTn); + } + } + + return tn; +} + +static int yaffs_FindChunkInGroup(yaffs_Device * dev, int theChunk, + yaffs_ExtendedTags * tags, int objectId, + int chunkInInode) +{ + int j; + + for (j = 0; theChunk && j < dev->chunkGroupSize; j++) { + if (yaffs_CheckChunkBit + (dev, theChunk / dev->nChunksPerBlock, + theChunk % dev->nChunksPerBlock)) { + yaffs_ReadChunkWithTagsFromNAND(dev, theChunk, NULL, + tags); + if (yaffs_TagsMatch(tags, objectId, chunkInInode)) { + /* found it; */ + return theChunk; + + } + } + theChunk++; + } + return -1; +} + + +/* DeleteWorker scans backwards through the tnode tree and deletes all the + * chunks and tnodes in the file + * Returns 1 if the tree was deleted. + * Returns 0 if it stopped early due to hitting the limit and the delete is incomplete. + */ + +static int yaffs_DeleteWorker(yaffs_Object * in, yaffs_Tnode * tn, __u32 level, + int chunkOffset, int *limit) +{ + int i; + int chunkInInode; + int theChunk; + yaffs_ExtendedTags tags; + int foundChunk; + yaffs_Device *dev = in->myDev; + + int allDone = 1; + + if (tn) { + if (level > 0) { + + for (i = YAFFS_NTNODES_INTERNAL - 1; allDone && i >= 0; + i--) { + if (tn->internal[i]) { + if (limit && (*limit) < 0) { + allDone = 0; + } else { + allDone = + yaffs_DeleteWorker(in, + tn-> + internal + [i], + level - + 1, + (chunkOffset + << + YAFFS_TNODES_INTERNAL_BITS) + + i, + limit); + } + if (allDone) { + yaffs_FreeTnode(dev, + tn-> + internal[i]); + tn->internal[i] = NULL; + } + } + + } + return (allDone) ? 1 : 0; + } else if (level == 0) { + int hitLimit = 0; + + for (i = YAFFS_NTNODES_LEVEL0 - 1; i >= 0 && !hitLimit; + i--) { + theChunk = yaffs_GetChunkGroupBase(dev,tn,i); + if (theChunk) { + + chunkInInode = + (chunkOffset << + YAFFS_TNODES_LEVEL0_BITS) + i; + + foundChunk = + yaffs_FindChunkInGroup(dev, + theChunk, + &tags, + in->objectId, + chunkInInode); + + if (foundChunk > 0) { + yaffs_DeleteChunk(dev, + foundChunk, 1, + __LINE__); + in->nDataChunks--; + if (limit) { + *limit = *limit - 1; + if (*limit <= 0) { + hitLimit = 1; + } + } + + } + + yaffs_PutLevel0Tnode(dev,tn,i,0); + } + + } + return (i < 0) ? 1 : 0; + + } + + } + + return 1; + +} + +static void yaffs_SoftDeleteChunk(yaffs_Device * dev, int chunk) +{ + + yaffs_BlockInfo *theBlock; + + T(YAFFS_TRACE_DELETION, (TSTR("soft delete chunk %d" TENDSTR), chunk)); + + theBlock = yaffs_GetBlockInfo(dev, chunk / dev->nChunksPerBlock); + if (theBlock) { + theBlock->softDeletions++; + dev->nFreeChunks++; + } +} + +/* SoftDeleteWorker scans backwards through the tnode tree and soft deletes all the chunks in the file. + * All soft deleting does is increment the block's softdelete count and pulls the chunk out + * of the tnode. + * Thus, essentially this is the same as DeleteWorker except that the chunks are soft deleted. + */ + +static int yaffs_SoftDeleteWorker(yaffs_Object * in, yaffs_Tnode * tn, + __u32 level, int chunkOffset) +{ + int i; + int theChunk; + int allDone = 1; + yaffs_Device *dev = in->myDev; + + if (tn) { + if (level > 0) { + + for (i = YAFFS_NTNODES_INTERNAL - 1; allDone && i >= 0; + i--) { + if (tn->internal[i]) { + allDone = + yaffs_SoftDeleteWorker(in, + tn-> + internal[i], + level - 1, + (chunkOffset + << + YAFFS_TNODES_INTERNAL_BITS) + + i); + if (allDone) { + yaffs_FreeTnode(dev, + tn-> + internal[i]); + tn->internal[i] = NULL; + } else { + /* Hoosterman... how could this happen? */ + } + } + } + return (allDone) ? 1 : 0; + } else if (level == 0) { + + for (i = YAFFS_NTNODES_LEVEL0 - 1; i >= 0; i--) { + theChunk = yaffs_GetChunkGroupBase(dev,tn,i); + if (theChunk) { + /* Note this does not find the real chunk, only the chunk group. + * We make an assumption that a chunk group is not larger than + * a block. + */ + yaffs_SoftDeleteChunk(dev, theChunk); + yaffs_PutLevel0Tnode(dev,tn,i,0); + } + + } + return 1; + + } + + } + + return 1; + +} + +static void yaffs_SoftDeleteFile(yaffs_Object * obj) +{ + if (obj->deleted && + obj->variantType == YAFFS_OBJECT_TYPE_FILE && !obj->softDeleted) { + if (obj->nDataChunks <= 0) { + /* Empty file with no duplicate object headers, just delete it immediately */ + yaffs_FreeTnode(obj->myDev, + obj->variant.fileVariant.top); + obj->variant.fileVariant.top = NULL; + T(YAFFS_TRACE_TRACING, + (TSTR("yaffs: Deleting empty file %d" TENDSTR), + obj->objectId)); + yaffs_DoGenericObjectDeletion(obj); + } else { + yaffs_SoftDeleteWorker(obj, + obj->variant.fileVariant.top, + obj->variant.fileVariant. + topLevel, 0); + obj->softDeleted = 1; + } + } +} + +/* Pruning removes any part of the file structure tree that is beyond the + * bounds of the file (ie that does not point to chunks). + * + * A file should only get pruned when its size is reduced. + * + * Before pruning, the chunks must be pulled from the tree and the + * level 0 tnode entries must be zeroed out. + * Could also use this for file deletion, but that's probably better handled + * by a special case. + */ + +static yaffs_Tnode *yaffs_PruneWorker(yaffs_Device * dev, yaffs_Tnode * tn, + __u32 level, int del0) +{ + int i; + int hasData; + + if (tn) { + hasData = 0; + + for (i = 0; i < YAFFS_NTNODES_INTERNAL; i++) { + if (tn->internal[i] && level > 0) { + tn->internal[i] = + yaffs_PruneWorker(dev, tn->internal[i], + level - 1, + (i == 0) ? del0 : 1); + } + + if (tn->internal[i]) { + hasData++; + } + } + + if (hasData == 0 && del0) { + /* Free and return NULL */ + + yaffs_FreeTnode(dev, tn); + tn = NULL; + } + + } + + return tn; + +} + +static int yaffs_PruneFileStructure(yaffs_Device * dev, + yaffs_FileStructure * fStruct) +{ + int i; + int hasData; + int done = 0; + yaffs_Tnode *tn; + + if (fStruct->topLevel > 0) { + fStruct->top = + yaffs_PruneWorker(dev, fStruct->top, fStruct->topLevel, 0); + + /* Now we have a tree with all the non-zero branches NULL but the height + * is the same as it was. + * Let's see if we can trim internal tnodes to shorten the tree. + * We can do this if only the 0th element in the tnode is in use + * (ie all the non-zero are NULL) + */ + + while (fStruct->topLevel && !done) { + tn = fStruct->top; + + hasData = 0; + for (i = 1; i < YAFFS_NTNODES_INTERNAL; i++) { + if (tn->internal[i]) { + hasData++; + } + } + + if (!hasData) { + fStruct->top = tn->internal[0]; + fStruct->topLevel--; + yaffs_FreeTnode(dev, tn); + } else { + done = 1; + } + } + } + + return YAFFS_OK; +} + +/*-------------------- End of File Structure functions.-------------------*/ + +/* yaffs_CreateFreeObjects creates a bunch more objects and + * adds them to the object free list. + */ +static int yaffs_CreateFreeObjects(yaffs_Device * dev, int nObjects) +{ + int i; + yaffs_Object *newObjects; + yaffs_ObjectList *list; + + if (nObjects < 1) + return YAFFS_OK; + + /* make these things */ + newObjects = YMALLOC(nObjects * sizeof(yaffs_Object)); + list = YMALLOC(sizeof(yaffs_ObjectList)); + + if (!newObjects || !list) { + if(newObjects) + YFREE(newObjects); + if(list) + YFREE(list); + T(YAFFS_TRACE_ALLOCATE, + (TSTR("yaffs: Could not allocate more objects" TENDSTR))); + return YAFFS_FAIL; + } + + /* Hook them into the free list */ + for (i = 0; i < nObjects - 1; i++) { + newObjects[i].siblings.next = + (struct list_head *)(&newObjects[i + 1]); + } + + newObjects[nObjects - 1].siblings.next = (void *)dev->freeObjects; + dev->freeObjects = newObjects; + dev->nFreeObjects += nObjects; + dev->nObjectsCreated += nObjects; + + /* Now add this bunch of Objects to a list for freeing up. */ + + list->objects = newObjects; + list->next = dev->allocatedObjectList; + dev->allocatedObjectList = list; + + return YAFFS_OK; +} + + +/* AllocateEmptyObject gets us a clean Object. Tries to make allocate more if we run out */ +static yaffs_Object *yaffs_AllocateEmptyObject(yaffs_Device * dev) +{ + yaffs_Object *tn = NULL; + + /* If there are none left make more */ + if (!dev->freeObjects) { + yaffs_CreateFreeObjects(dev, YAFFS_ALLOCATION_NOBJECTS); + } + + if (dev->freeObjects) { + tn = dev->freeObjects; + dev->freeObjects = + (yaffs_Object *) (dev->freeObjects->siblings.next); + dev->nFreeObjects--; + + /* Now sweeten it up... */ + + memset(tn, 0, sizeof(yaffs_Object)); + tn->myDev = dev; + tn->chunkId = -1; + tn->variantType = YAFFS_OBJECT_TYPE_UNKNOWN; + INIT_LIST_HEAD(&(tn->hardLinks)); + INIT_LIST_HEAD(&(tn->hashLink)); + INIT_LIST_HEAD(&tn->siblings); + + /* Add it to the lost and found directory. + * NB Can't put root or lostNFound in lostNFound so + * check if lostNFound exists first + */ + if (dev->lostNFoundDir) { + yaffs_AddObjectToDirectory(dev->lostNFoundDir, tn); + } + } + + dev->nCheckpointBlocksRequired = 0; /* force recalculation*/ + + return tn; +} + +static yaffs_Object *yaffs_CreateFakeDirectory(yaffs_Device * dev, int number, + __u32 mode) +{ + + yaffs_Object *obj = + yaffs_CreateNewObject(dev, number, YAFFS_OBJECT_TYPE_DIRECTORY); + if (obj) { + obj->fake = 1; /* it is fake so it has no NAND presence... */ + obj->renameAllowed = 0; /* ... and we're not allowed to rename it... */ + obj->unlinkAllowed = 0; /* ... or unlink it */ + obj->deleted = 0; + obj->unlinked = 0; + obj->yst_mode = mode; + obj->myDev = dev; + obj->chunkId = 0; /* Not a valid chunk. */ + } + + return obj; + +} + +static void yaffs_UnhashObject(yaffs_Object * tn) +{ + int bucket; + yaffs_Device *dev = tn->myDev; + + /* If it is still linked into the bucket list, free from the list */ + if (!list_empty(&tn->hashLink)) { + list_del_init(&tn->hashLink); + bucket = yaffs_HashFunction(tn->objectId); + dev->objectBucket[bucket].count--; + } + +} + +/* FreeObject frees up a Object and puts it back on the free list */ +static void yaffs_FreeObject(yaffs_Object * tn) +{ + + yaffs_Device *dev = tn->myDev; + +#ifdef __KERNEL__ + if (tn->myInode) { + /* We're still hooked up to a cached inode. + * Don't delete now, but mark for later deletion + */ + tn->deferedFree = 1; + return; + } +#endif + + yaffs_UnhashObject(tn); + + /* Link into the free list. */ + tn->siblings.next = (struct list_head *)(dev->freeObjects); + dev->freeObjects = tn; + dev->nFreeObjects++; + + dev->nCheckpointBlocksRequired = 0; /* force recalculation*/ + +} + +#ifdef __KERNEL__ + +void yaffs_HandleDeferedFree(yaffs_Object * obj) +{ + if (obj->deferedFree) { + yaffs_FreeObject(obj); + } +} + +#endif + +static void yaffs_DeinitialiseObjects(yaffs_Device * dev) +{ + /* Free the list of allocated Objects */ + + yaffs_ObjectList *tmp; + + while (dev->allocatedObjectList) { + tmp = dev->allocatedObjectList->next; + YFREE(dev->allocatedObjectList->objects); + YFREE(dev->allocatedObjectList); + + dev->allocatedObjectList = tmp; + } + + dev->freeObjects = NULL; + dev->nFreeObjects = 0; +} + +static void yaffs_InitialiseObjects(yaffs_Device * dev) +{ + int i; + + dev->allocatedObjectList = NULL; + dev->freeObjects = NULL; + dev->nFreeObjects = 0; + + for (i = 0; i < YAFFS_NOBJECT_BUCKETS; i++) { + INIT_LIST_HEAD(&dev->objectBucket[i].list); + dev->objectBucket[i].count = 0; + } + +} + +static int yaffs_FindNiceObjectBucket(yaffs_Device * dev) +{ + static int x = 0; + int i; + int l = 999; + int lowest = 999999; + + /* First let's see if we can find one that's empty. */ + + for (i = 0; i < 10 && lowest > 0; i++) { + x++; + x %= YAFFS_NOBJECT_BUCKETS; + if (dev->objectBucket[x].count < lowest) { + lowest = dev->objectBucket[x].count; + l = x; + } + + } + + /* If we didn't find an empty list, then try + * looking a bit further for a short one + */ + + for (i = 0; i < 10 && lowest > 3; i++) { + x++; + x %= YAFFS_NOBJECT_BUCKETS; + if (dev->objectBucket[x].count < lowest) { + lowest = dev->objectBucket[x].count; + l = x; + } + + } + + return l; +} + +static int yaffs_CreateNewObjectNumber(yaffs_Device * dev) +{ + int bucket = yaffs_FindNiceObjectBucket(dev); + + /* Now find an object value that has not already been taken + * by scanning the list. + */ + + int found = 0; + struct list_head *i; + + __u32 n = (__u32) bucket; + + /* yaffs_CheckObjectHashSanity(); */ + + while (!found) { + found = 1; + n += YAFFS_NOBJECT_BUCKETS; + if (1 || dev->objectBucket[bucket].count > 0) { + list_for_each(i, &dev->objectBucket[bucket].list) { + /* If there is already one in the list */ + if (i + && list_entry(i, yaffs_Object, + hashLink)->objectId == n) { + found = 0; + } + } + } + } + + + return n; +} + +static void yaffs_HashObject(yaffs_Object * in) +{ + int bucket = yaffs_HashFunction(in->objectId); + yaffs_Device *dev = in->myDev; + + list_add(&in->hashLink, &dev->objectBucket[bucket].list); + dev->objectBucket[bucket].count++; + +} + +yaffs_Object *yaffs_FindObjectByNumber(yaffs_Device * dev, __u32 number) +{ + int bucket = yaffs_HashFunction(number); + struct list_head *i; + yaffs_Object *in; + + list_for_each(i, &dev->objectBucket[bucket].list) { + /* Look if it is in the list */ + if (i) { + in = list_entry(i, yaffs_Object, hashLink); + if (in->objectId == number) { +#ifdef __KERNEL__ + /* Don't tell the VFS about this one if it is defered free */ + if (in->deferedFree) + return NULL; +#endif + + return in; + } + } + } + + return NULL; +} + +yaffs_Object *yaffs_CreateNewObject(yaffs_Device * dev, int number, + yaffs_ObjectType type) +{ + + yaffs_Object *theObject; + yaffs_Tnode *tn; + + if (number < 0) { + number = yaffs_CreateNewObjectNumber(dev); + } + + theObject = yaffs_AllocateEmptyObject(dev); + if(!theObject) + return NULL; + + if(type == YAFFS_OBJECT_TYPE_FILE){ + tn = yaffs_GetTnode(dev); + if(!tn){ + yaffs_FreeObject(theObject); + return NULL; + } + } + + + + if (theObject) { + theObject->fake = 0; + theObject->renameAllowed = 1; + theObject->unlinkAllowed = 1; + theObject->objectId = number; + yaffs_HashObject(theObject); + theObject->variantType = type; +#ifdef CONFIG_YAFFS_WINCE + yfsd_WinFileTimeNow(theObject->win_atime); + theObject->win_ctime[0] = theObject->win_mtime[0] = + theObject->win_atime[0]; + theObject->win_ctime[1] = theObject->win_mtime[1] = + theObject->win_atime[1]; + +#else + + theObject->yst_atime = theObject->yst_mtime = + theObject->yst_ctime = Y_CURRENT_TIME; +#endif + switch (type) { + case YAFFS_OBJECT_TYPE_FILE: + theObject->variant.fileVariant.fileSize = 0; + theObject->variant.fileVariant.scannedFileSize = 0; + theObject->variant.fileVariant.shrinkSize = 0xFFFFFFFF; /* max __u32 */ + theObject->variant.fileVariant.topLevel = 0; + theObject->variant.fileVariant.top = tn; + break; + case YAFFS_OBJECT_TYPE_DIRECTORY: + INIT_LIST_HEAD(&theObject->variant.directoryVariant. + children); + break; + case YAFFS_OBJECT_TYPE_SYMLINK: + case YAFFS_OBJECT_TYPE_HARDLINK: + case YAFFS_OBJECT_TYPE_SPECIAL: + /* No action required */ + break; + case YAFFS_OBJECT_TYPE_UNKNOWN: + /* todo this should not happen */ + break; + } + } + + return theObject; +} + +static yaffs_Object *yaffs_FindOrCreateObjectByNumber(yaffs_Device * dev, + int number, + yaffs_ObjectType type) +{ + yaffs_Object *theObject = NULL; + + if (number > 0) { + theObject = yaffs_FindObjectByNumber(dev, number); + } + + if (!theObject) { + theObject = yaffs_CreateNewObject(dev, number, type); + } + + return theObject; + +} + + +static YCHAR *yaffs_CloneString(const YCHAR * str) +{ + YCHAR *newStr = NULL; + + if (str && *str) { + newStr = YMALLOC((yaffs_strlen(str) + 1) * sizeof(YCHAR)); + if(newStr) + yaffs_strcpy(newStr, str); + } + + return newStr; + +} + +/* + * Mknod (create) a new object. + * equivalentObject only has meaning for a hard link; + * aliasString only has meaning for a sumlink. + * rdev only has meaning for devices (a subset of special objects) + */ + +static yaffs_Object *yaffs_MknodObject(yaffs_ObjectType type, + yaffs_Object * parent, + const YCHAR * name, + __u32 mode, + __u32 uid, + __u32 gid, + yaffs_Object * equivalentObject, + const YCHAR * aliasString, __u32 rdev) +{ + yaffs_Object *in; + YCHAR *str; + + yaffs_Device *dev = parent->myDev; + + /* Check if the entry exists. If it does then fail the call since we don't want a dup.*/ + if (yaffs_FindObjectByName(parent, name)) { + return NULL; + } + + in = yaffs_CreateNewObject(dev, -1, type); + + if(type == YAFFS_OBJECT_TYPE_SYMLINK){ + str = yaffs_CloneString(aliasString); + if(!str){ + yaffs_FreeObject(in); + return NULL; + } + } + + + + if (in) { + in->chunkId = -1; + in->valid = 1; + in->variantType = type; + + in->yst_mode = mode; + +#ifdef CONFIG_YAFFS_WINCE + yfsd_WinFileTimeNow(in->win_atime); + in->win_ctime[0] = in->win_mtime[0] = in->win_atime[0]; + in->win_ctime[1] = in->win_mtime[1] = in->win_atime[1]; + +#else + in->yst_atime = in->yst_mtime = in->yst_ctime = Y_CURRENT_TIME; + + in->yst_rdev = rdev; + in->yst_uid = uid; + in->yst_gid = gid; +#endif + in->nDataChunks = 0; + + yaffs_SetObjectName(in, name); + in->dirty = 1; + + yaffs_AddObjectToDirectory(parent, in); + + in->myDev = parent->myDev; + + switch (type) { + case YAFFS_OBJECT_TYPE_SYMLINK: + in->variant.symLinkVariant.alias = str; + break; + case YAFFS_OBJECT_TYPE_HARDLINK: + in->variant.hardLinkVariant.equivalentObject = + equivalentObject; + in->variant.hardLinkVariant.equivalentObjectId = + equivalentObject->objectId; + list_add(&in->hardLinks, &equivalentObject->hardLinks); + break; + case YAFFS_OBJECT_TYPE_FILE: + case YAFFS_OBJECT_TYPE_DIRECTORY: + case YAFFS_OBJECT_TYPE_SPECIAL: + case YAFFS_OBJECT_TYPE_UNKNOWN: + /* do nothing */ + break; + } + + if (yaffs_UpdateObjectHeader(in, name, 0, 0, 0) < 0) { + /* Could not create the object header, fail the creation */ + yaffs_DestroyObject(in); + in = NULL; + } + + } + + return in; +} + +yaffs_Object *yaffs_MknodFile(yaffs_Object * parent, const YCHAR * name, + __u32 mode, __u32 uid, __u32 gid) +{ + return yaffs_MknodObject(YAFFS_OBJECT_TYPE_FILE, parent, name, mode, + uid, gid, NULL, NULL, 0); +} + +yaffs_Object *yaffs_MknodDirectory(yaffs_Object * parent, const YCHAR * name, + __u32 mode, __u32 uid, __u32 gid) +{ + return yaffs_MknodObject(YAFFS_OBJECT_TYPE_DIRECTORY, parent, name, + mode, uid, gid, NULL, NULL, 0); +} + +yaffs_Object *yaffs_MknodSpecial(yaffs_Object * parent, const YCHAR * name, + __u32 mode, __u32 uid, __u32 gid, __u32 rdev) +{ + return yaffs_MknodObject(YAFFS_OBJECT_TYPE_SPECIAL, parent, name, mode, + uid, gid, NULL, NULL, rdev); +} + +yaffs_Object *yaffs_MknodSymLink(yaffs_Object * parent, const YCHAR * name, + __u32 mode, __u32 uid, __u32 gid, + const YCHAR * alias) +{ + return yaffs_MknodObject(YAFFS_OBJECT_TYPE_SYMLINK, parent, name, mode, + uid, gid, NULL, alias, 0); +} + +/* yaffs_Link returns the object id of the equivalent object.*/ +yaffs_Object *yaffs_Link(yaffs_Object * parent, const YCHAR * name, + yaffs_Object * equivalentObject) +{ + /* Get the real object in case we were fed a hard link as an equivalent object */ + equivalentObject = yaffs_GetEquivalentObject(equivalentObject); + + if (yaffs_MknodObject + (YAFFS_OBJECT_TYPE_HARDLINK, parent, name, 0, 0, 0, + equivalentObject, NULL, 0)) { + return equivalentObject; + } else { + return NULL; + } + +} + +static int yaffs_ChangeObjectName(yaffs_Object * obj, yaffs_Object * newDir, + const YCHAR * newName, int force, int shadows) +{ + int unlinkOp; + int deleteOp; + + yaffs_Object *existingTarget; + + if (newDir == NULL) { + newDir = obj->parent; /* use the old directory */ + } + + if (newDir->variantType != YAFFS_OBJECT_TYPE_DIRECTORY) { + T(YAFFS_TRACE_ALWAYS, + (TSTR + ("tragendy: yaffs_ChangeObjectName: newDir is not a directory" + TENDSTR))); + YBUG(); + } + + /* TODO: Do we need this different handling for YAFFS2 and YAFFS1?? */ + if (obj->myDev->isYaffs2) { + unlinkOp = (newDir == obj->myDev->unlinkedDir); + } else { + unlinkOp = (newDir == obj->myDev->unlinkedDir + && obj->variantType == YAFFS_OBJECT_TYPE_FILE); + } + + deleteOp = (newDir == obj->myDev->deletedDir); + + existingTarget = yaffs_FindObjectByName(newDir, newName); + + /* If the object is a file going into the unlinked directory, + * then it is OK to just stuff it in since duplicate names are allowed. + * else only proceed if the new name does not exist and if we're putting + * it into a directory. + */ + if ((unlinkOp || + deleteOp || + force || + (shadows > 0) || + !existingTarget) && + newDir->variantType == YAFFS_OBJECT_TYPE_DIRECTORY) { + yaffs_SetObjectName(obj, newName); + obj->dirty = 1; + + yaffs_AddObjectToDirectory(newDir, obj); + + if (unlinkOp) + obj->unlinked = 1; + + /* If it is a deletion then we mark it as a shrink for gc purposes. */ + if (yaffs_UpdateObjectHeader(obj, newName, 0, deleteOp, shadows)>= 0) + return YAFFS_OK; + } + + return YAFFS_FAIL; +} + +int yaffs_RenameObject(yaffs_Object * oldDir, const YCHAR * oldName, + yaffs_Object * newDir, const YCHAR * newName) +{ + yaffs_Object *obj; + yaffs_Object *existingTarget; + int force = 0; + +#ifdef CONFIG_YAFFS_CASE_INSENSITIVE + /* Special case for case insemsitive systems (eg. WinCE). + * While look-up is case insensitive, the name isn't. + * Therefore we might want to change x.txt to X.txt + */ + if (oldDir == newDir && yaffs_strcmp(oldName, newName) == 0) { + force = 1; + } +#endif + + obj = yaffs_FindObjectByName(oldDir, oldName); + /* Check new name to long. */ + if (obj->variantType == YAFFS_OBJECT_TYPE_SYMLINK && + yaffs_strlen(newName) > YAFFS_MAX_ALIAS_LENGTH) + /* ENAMETOOLONG */ + return YAFFS_FAIL; + else if (obj->variantType != YAFFS_OBJECT_TYPE_SYMLINK && + yaffs_strlen(newName) > YAFFS_MAX_NAME_LENGTH) + /* ENAMETOOLONG */ + return YAFFS_FAIL; + + if (obj && obj->renameAllowed) { + + /* Now do the handling for an existing target, if there is one */ + + existingTarget = yaffs_FindObjectByName(newDir, newName); + if (existingTarget && + existingTarget->variantType == YAFFS_OBJECT_TYPE_DIRECTORY && + !list_empty(&existingTarget->variant.directoryVariant.children)) { + /* There is a target that is a non-empty directory, so we fail */ + return YAFFS_FAIL; /* EEXIST or ENOTEMPTY */ + } else if (existingTarget && existingTarget != obj) { + /* Nuke the target first, using shadowing, + * but only if it isn't the same object + */ + yaffs_ChangeObjectName(obj, newDir, newName, force, + existingTarget->objectId); + yaffs_UnlinkObject(existingTarget); + } + + return yaffs_ChangeObjectName(obj, newDir, newName, 1, 0); + } + return YAFFS_FAIL; +} + +/*------------------------- Block Management and Page Allocation ----------------*/ + +static int yaffs_InitialiseBlocks(yaffs_Device * dev) +{ + int nBlocks = dev->internalEndBlock - dev->internalStartBlock + 1; + + dev->blockInfo = NULL; + dev->chunkBits = NULL; + + dev->allocationBlock = -1; /* force it to get a new one */ + + /* If the first allocation strategy fails, thry the alternate one */ + dev->blockInfo = YMALLOC(nBlocks * sizeof(yaffs_BlockInfo)); + if(!dev->blockInfo){ + dev->blockInfo = YMALLOC_ALT(nBlocks * sizeof(yaffs_BlockInfo)); + dev->blockInfoAlt = 1; + } + else + dev->blockInfoAlt = 0; + + if(dev->blockInfo){ + + /* Set up dynamic blockinfo stuff. */ + dev->chunkBitmapStride = (dev->nChunksPerBlock + 7) / 8; /* round up bytes */ + dev->chunkBits = YMALLOC(dev->chunkBitmapStride * nBlocks); + if(!dev->chunkBits){ + dev->chunkBits = YMALLOC_ALT(dev->chunkBitmapStride * nBlocks); + dev->chunkBitsAlt = 1; + } + else + dev->chunkBitsAlt = 0; + } + + if (dev->blockInfo && dev->chunkBits) { + memset(dev->blockInfo, 0, nBlocks * sizeof(yaffs_BlockInfo)); + memset(dev->chunkBits, 0, dev->chunkBitmapStride * nBlocks); + return YAFFS_OK; + } + + return YAFFS_FAIL; + +} + +static void yaffs_DeinitialiseBlocks(yaffs_Device * dev) +{ + if(dev->blockInfoAlt && dev->blockInfo) + YFREE_ALT(dev->blockInfo); + else if(dev->blockInfo) + YFREE(dev->blockInfo); + + dev->blockInfoAlt = 0; + + dev->blockInfo = NULL; + + if(dev->chunkBitsAlt && dev->chunkBits) + YFREE_ALT(dev->chunkBits); + else if(dev->chunkBits) + YFREE(dev->chunkBits); + dev->chunkBitsAlt = 0; + dev->chunkBits = NULL; +} + +static int yaffs_BlockNotDisqualifiedFromGC(yaffs_Device * dev, + yaffs_BlockInfo * bi) +{ + int i; + __u32 seq; + yaffs_BlockInfo *b; + + if (!dev->isYaffs2) + return 1; /* disqualification only applies to yaffs2. */ + + if (!bi->hasShrinkHeader) + return 1; /* can gc */ + + /* Find the oldest dirty sequence number if we don't know it and save it + * so we don't have to keep recomputing it. + */ + if (!dev->oldestDirtySequence) { + seq = dev->sequenceNumber; + + for (i = dev->internalStartBlock; i <= dev->internalEndBlock; + i++) { + b = yaffs_GetBlockInfo(dev, i); + if (b->blockState == YAFFS_BLOCK_STATE_FULL && + (b->pagesInUse - b->softDeletions) < + dev->nChunksPerBlock && b->sequenceNumber < seq) { + seq = b->sequenceNumber; + } + } + dev->oldestDirtySequence = seq; + } + + /* Can't do gc of this block if there are any blocks older than this one that have + * discarded pages. + */ + return (bi->sequenceNumber <= dev->oldestDirtySequence); + +} + +/* FindDiretiestBlock is used to select the dirtiest block (or close enough) + * for garbage collection. + */ + +static int yaffs_FindBlockForGarbageCollection(yaffs_Device * dev, + int aggressive) +{ + + int b = dev->currentDirtyChecker; + + int i; + int iterations; + int dirtiest = -1; + int pagesInUse = 0; + int prioritised=0; + yaffs_BlockInfo *bi; + int pendingPrioritisedExist = 0; + + /* First let's see if we need to grab a prioritised block */ + if(dev->hasPendingPrioritisedGCs){ + for(i = dev->internalStartBlock; i < dev->internalEndBlock && !prioritised; i++){ + + bi = yaffs_GetBlockInfo(dev, i); + //yaffs_VerifyBlock(dev,bi,i); + + if(bi->gcPrioritise) { + pendingPrioritisedExist = 1; + if(bi->blockState == YAFFS_BLOCK_STATE_FULL && + yaffs_BlockNotDisqualifiedFromGC(dev, bi)){ + pagesInUse = (bi->pagesInUse - bi->softDeletions); + dirtiest = i; + prioritised = 1; + aggressive = 1; /* Fool the non-aggressive skip logiv below */ + } + } + } + + if(!pendingPrioritisedExist) /* None found, so we can clear this */ + dev->hasPendingPrioritisedGCs = 0; + } + + /* If we're doing aggressive GC then we are happy to take a less-dirty block, and + * search harder. + * else (we're doing a leasurely gc), then we only bother to do this if the + * block has only a few pages in use. + */ + + dev->nonAggressiveSkip--; + + if (!aggressive && (dev->nonAggressiveSkip > 0)) { + return -1; + } + + if(!prioritised) + pagesInUse = + (aggressive) ? dev->nChunksPerBlock : YAFFS_PASSIVE_GC_CHUNKS + 1; + + if (aggressive) { + iterations = + dev->internalEndBlock - dev->internalStartBlock + 1; + } else { + iterations = + dev->internalEndBlock - dev->internalStartBlock + 1; + iterations = iterations / 16; + if (iterations > 200) { + iterations = 200; + } + } + + for (i = 0; i <= iterations && pagesInUse > 0 && !prioritised; i++) { + b++; + if (b < dev->internalStartBlock || b > dev->internalEndBlock) { + b = dev->internalStartBlock; + } + + if (b < dev->internalStartBlock || b > dev->internalEndBlock) { + T(YAFFS_TRACE_ERROR, + (TSTR("**>> Block %d is not valid" TENDSTR), b)); + YBUG(); + } + + bi = yaffs_GetBlockInfo(dev, b); + +#if 0 + if (bi->blockState == YAFFS_BLOCK_STATE_CHECKPOINT) { + dirtiest = b; + pagesInUse = 0; + } + else +#endif + + if (bi->blockState == YAFFS_BLOCK_STATE_FULL && + (bi->pagesInUse - bi->softDeletions) < pagesInUse && + yaffs_BlockNotDisqualifiedFromGC(dev, bi)) { + dirtiest = b; + pagesInUse = (bi->pagesInUse - bi->softDeletions); + } + } + + dev->currentDirtyChecker = b; + + if (dirtiest > 0) { + T(YAFFS_TRACE_GC, + (TSTR("GC Selected block %d with %d free, prioritised:%d" TENDSTR), dirtiest, + dev->nChunksPerBlock - pagesInUse,prioritised)); + } + + dev->oldestDirtySequence = 0; + + if (dirtiest > 0) { + dev->nonAggressiveSkip = 4; + } + + return dirtiest; +} + +static void yaffs_BlockBecameDirty(yaffs_Device * dev, int blockNo) +{ + yaffs_BlockInfo *bi = yaffs_GetBlockInfo(dev, blockNo); + + int erasedOk = 0; + + /* If the block is still healthy erase it and mark as clean. + * If the block has had a data failure, then retire it. + */ + + T(YAFFS_TRACE_GC | YAFFS_TRACE_ERASE, + (TSTR("yaffs_BlockBecameDirty block %d state %d %s"TENDSTR), + blockNo, bi->blockState, (bi->needsRetiring) ? "needs retiring" : "")); + + bi->blockState = YAFFS_BLOCK_STATE_DIRTY; + + if (!bi->needsRetiring) { + yaffs_InvalidateCheckpoint(dev); + erasedOk = yaffs_EraseBlockInNAND(dev, blockNo); + if (!erasedOk) { + dev->nErasureFailures++; + T(YAFFS_TRACE_ERROR | YAFFS_TRACE_BAD_BLOCKS, + (TSTR("**>> Erasure failed %d" TENDSTR), blockNo)); + } + } + + if (erasedOk && + ((yaffs_traceMask & YAFFS_TRACE_ERASE) || !yaffs_SkipVerification(dev))) { + int i; + for (i = 0; i < dev->nChunksPerBlock; i++) { + if (!yaffs_CheckChunkErased + (dev, blockNo * dev->nChunksPerBlock + i)) { + T(YAFFS_TRACE_ERROR, + (TSTR + (">>Block %d erasure supposedly OK, but chunk %d not erased" + TENDSTR), blockNo, i)); + } + } + } + + if (erasedOk) { + /* Clean it up... */ + bi->blockState = YAFFS_BLOCK_STATE_EMPTY; + dev->nErasedBlocks++; + bi->pagesInUse = 0; + bi->softDeletions = 0; + bi->hasShrinkHeader = 0; + bi->skipErasedCheck = 1; /* This is clean, so no need to check */ + bi->gcPrioritise = 0; + yaffs_ClearChunkBits(dev, blockNo); + + T(YAFFS_TRACE_ERASE, + (TSTR("Erased block %d" TENDSTR), blockNo)); + } else { + dev->nFreeChunks -= dev->nChunksPerBlock; /* We lost a block of free space */ + + yaffs_RetireBlock(dev, blockNo); + T(YAFFS_TRACE_ERROR | YAFFS_TRACE_BAD_BLOCKS, + (TSTR("**>> Block %d retired" TENDSTR), blockNo)); + } +} + +static int yaffs_FindBlockForAllocation(yaffs_Device * dev) +{ + int i; + + yaffs_BlockInfo *bi; + + if (dev->nErasedBlocks < 1) { + /* Hoosterman we've got a problem. + * Can't get space to gc + */ + T(YAFFS_TRACE_ERROR, + (TSTR("yaffs tragedy: no more eraased blocks" TENDSTR))); + + return -1; + } + + /* Find an empty block. */ + + for (i = dev->internalStartBlock; i <= dev->internalEndBlock; i++) { + dev->allocationBlockFinder++; + if (dev->allocationBlockFinder < dev->internalStartBlock + || dev->allocationBlockFinder > dev->internalEndBlock) { + dev->allocationBlockFinder = dev->internalStartBlock; + } + + bi = yaffs_GetBlockInfo(dev, dev->allocationBlockFinder); + + if (bi->blockState == YAFFS_BLOCK_STATE_EMPTY) { + bi->blockState = YAFFS_BLOCK_STATE_ALLOCATING; + dev->sequenceNumber++; + bi->sequenceNumber = dev->sequenceNumber; + dev->nErasedBlocks--; + T(YAFFS_TRACE_ALLOCATE, + (TSTR("Allocated block %d, seq %d, %d left" TENDSTR), + dev->allocationBlockFinder, dev->sequenceNumber, + dev->nErasedBlocks)); + return dev->allocationBlockFinder; + } + } + + T(YAFFS_TRACE_ALWAYS, + (TSTR + ("yaffs tragedy: no more eraased blocks, but there should have been %d" + TENDSTR), dev->nErasedBlocks)); + + return -1; +} + + + +static int yaffs_CalcCheckpointBlocksRequired(yaffs_Device *dev) +{ + if(!dev->nCheckpointBlocksRequired){ + /* Not a valid value so recalculate */ + int nBytes = 0; + int nBlocks; + int devBlocks = (dev->endBlock - dev->startBlock + 1); + int tnodeSize; + + tnodeSize = (dev->tnodeWidth * YAFFS_NTNODES_LEVEL0)/8; + + if(tnodeSize < sizeof(yaffs_Tnode)) + tnodeSize = sizeof(yaffs_Tnode); + + nBytes += sizeof(yaffs_CheckpointValidity); + nBytes += sizeof(yaffs_CheckpointDevice); + nBytes += devBlocks * sizeof(yaffs_BlockInfo); + nBytes += devBlocks * dev->chunkBitmapStride; + nBytes += (sizeof(yaffs_CheckpointObject) + sizeof(__u32)) * (dev->nObjectsCreated - dev->nFreeObjects); + nBytes += (tnodeSize + sizeof(__u32)) * (dev->nTnodesCreated - dev->nFreeTnodes); + nBytes += sizeof(yaffs_CheckpointValidity); + nBytes += sizeof(__u32); /* checksum*/ + + /* Round up and add 2 blocks to allow for some bad blocks, so add 3 */ + + nBlocks = (nBytes/(dev->nDataBytesPerChunk * dev->nChunksPerBlock)) + 3; + + dev->nCheckpointBlocksRequired = nBlocks; + } + + return dev->nCheckpointBlocksRequired; +} + +// Check if there's space to allocate... +// Thinks.... do we need top make this ths same as yaffs_GetFreeChunks()? +static int yaffs_CheckSpaceForAllocation(yaffs_Device * dev) +{ + int reservedChunks; + int reservedBlocks = dev->nReservedBlocks; + int checkpointBlocks; + + checkpointBlocks = yaffs_CalcCheckpointBlocksRequired(dev) - dev->blocksInCheckpoint; + if(checkpointBlocks < 0) + checkpointBlocks = 0; + + reservedChunks = ((reservedBlocks + checkpointBlocks) * dev->nChunksPerBlock); + + return (dev->nFreeChunks > reservedChunks); +} + +static int yaffs_AllocateChunk(yaffs_Device * dev, int useReserve, yaffs_BlockInfo **blockUsedPtr) +{ + int retVal; + yaffs_BlockInfo *bi; + + if (dev->allocationBlock < 0) { + /* Get next block to allocate off */ + dev->allocationBlock = yaffs_FindBlockForAllocation(dev); + dev->allocationPage = 0; + } + + if (!useReserve && !yaffs_CheckSpaceForAllocation(dev)) { + /* Not enough space to allocate unless we're allowed to use the reserve. */ + return -1; + } + + if (dev->nErasedBlocks < dev->nReservedBlocks + && dev->allocationPage == 0) { + T(YAFFS_TRACE_ALLOCATE, (TSTR("Allocating reserve" TENDSTR))); + } + + /* Next page please.... */ + if (dev->allocationBlock >= 0) { + bi = yaffs_GetBlockInfo(dev, dev->allocationBlock); + + retVal = (dev->allocationBlock * dev->nChunksPerBlock) + + dev->allocationPage; + bi->pagesInUse++; + yaffs_SetChunkBit(dev, dev->allocationBlock, + dev->allocationPage); + + dev->allocationPage++; + + dev->nFreeChunks--; + + /* If the block is full set the state to full */ + if (dev->allocationPage >= dev->nChunksPerBlock) { + bi->blockState = YAFFS_BLOCK_STATE_FULL; + dev->allocationBlock = -1; + } + + if(blockUsedPtr) + *blockUsedPtr = bi; + + return retVal; + } + + T(YAFFS_TRACE_ERROR, + (TSTR("!!!!!!!!! Allocator out !!!!!!!!!!!!!!!!!" TENDSTR))); + + return -1; +} + +static int yaffs_GetErasedChunks(yaffs_Device * dev) +{ + int n; + + n = dev->nErasedBlocks * dev->nChunksPerBlock; + + if (dev->allocationBlock > 0) { + n += (dev->nChunksPerBlock - dev->allocationPage); + } + + return n; + +} + +static int yaffs_GarbageCollectBlock(yaffs_Device * dev, int block) +{ + int oldChunk; + int newChunk; + int chunkInBlock; + int markNAND; + int retVal = YAFFS_OK; + int cleanups = 0; + int i; + int isCheckpointBlock; + int matchingChunk; + + int chunksBefore = yaffs_GetErasedChunks(dev); + int chunksAfter; + + yaffs_ExtendedTags tags; + + yaffs_BlockInfo *bi = yaffs_GetBlockInfo(dev, block); + + yaffs_Object *object; + + isCheckpointBlock = (bi->blockState == YAFFS_BLOCK_STATE_CHECKPOINT); + + bi->blockState = YAFFS_BLOCK_STATE_COLLECTING; + + T(YAFFS_TRACE_TRACING, + (TSTR("Collecting block %d, in use %d, shrink %d, " TENDSTR), block, + bi->pagesInUse, bi->hasShrinkHeader)); + + /*yaffs_VerifyFreeChunks(dev); */ + + bi->hasShrinkHeader = 0; /* clear the flag so that the block can erase */ + + /* Take off the number of soft deleted entries because + * they're going to get really deleted during GC. + */ + dev->nFreeChunks -= bi->softDeletions; + + dev->isDoingGC = 1; + + if (isCheckpointBlock || + !yaffs_StillSomeChunkBits(dev, block)) { + T(YAFFS_TRACE_TRACING, + (TSTR + ("Collecting block %d that has no chunks in use" TENDSTR), + block)); + yaffs_BlockBecameDirty(dev, block); + } else { + + __u8 *buffer = yaffs_GetTempBuffer(dev, __LINE__); + + yaffs_VerifyBlock(dev,bi,block); + + for (chunkInBlock = 0, oldChunk = block * dev->nChunksPerBlock; + chunkInBlock < dev->nChunksPerBlock + && yaffs_StillSomeChunkBits(dev, block); + chunkInBlock++, oldChunk++) { + if (yaffs_CheckChunkBit(dev, block, chunkInBlock)) { + + /* This page is in use and might need to be copied off */ + + markNAND = 1; + + yaffs_InitialiseTags(&tags); + + yaffs_ReadChunkWithTagsFromNAND(dev, oldChunk, + buffer, &tags); + + object = + yaffs_FindObjectByNumber(dev, + tags.objectId); + + T(YAFFS_TRACE_GC_DETAIL, + (TSTR + ("Collecting page %d, %d %d %d " TENDSTR), + chunkInBlock, tags.objectId, tags.chunkId, + tags.byteCount)); + + if(object && !yaffs_SkipVerification(dev)){ + if(tags.chunkId == 0) + matchingChunk = object->chunkId; + else if(object->softDeleted) + matchingChunk = oldChunk; /* Defeat the test */ + else + matchingChunk = yaffs_FindChunkInFile(object,tags.chunkId,NULL); + + if(oldChunk != matchingChunk) + T(YAFFS_TRACE_ERROR, + (TSTR("gc: page in gc mismatch: %d %d %d %d"TENDSTR), + oldChunk,matchingChunk,tags.objectId, tags.chunkId)); + + } + + if (!object) { + T(YAFFS_TRACE_ERROR, + (TSTR + ("page %d in gc has no object: %d %d %d " + TENDSTR), oldChunk, + tags.objectId, tags.chunkId, tags.byteCount)); + } + + if (object && object->deleted + && tags.chunkId != 0) { + /* Data chunk in a deleted file, throw it away + * It's a soft deleted data chunk, + * No need to copy this, just forget about it and + * fix up the object. + */ + + object->nDataChunks--; + + if (object->nDataChunks <= 0) { + /* remeber to clean up the object */ + dev->gcCleanupList[cleanups] = + tags.objectId; + cleanups++; + } + markNAND = 0; + } else if (0 + /* Todo object && object->deleted && object->nDataChunks == 0 */ + ) { + /* Deleted object header with no data chunks. + * Can be discarded and the file deleted. + */ + object->chunkId = 0; + yaffs_FreeTnode(object->myDev, + object->variant. + fileVariant.top); + object->variant.fileVariant.top = NULL; + yaffs_DoGenericObjectDeletion(object); + + } else if (object) { + /* It's either a data chunk in a live file or + * an ObjectHeader, so we're interested in it. + * NB Need to keep the ObjectHeaders of deleted files + * until the whole file has been deleted off + */ + tags.serialNumber++; + + dev->nGCCopies++; + + if (tags.chunkId == 0) { + /* It is an object Id, + * We need to nuke the shrinkheader flags first + * We no longer want the shrinkHeader flag since its work is done + * and if it is left in place it will mess up scanning. + * Also, clear out any shadowing stuff + */ + + yaffs_ObjectHeader *oh; + oh = (yaffs_ObjectHeader *)buffer; + oh->isShrink = 0; + oh->shadowsObject = -1; + tags.extraShadows = 0; + tags.extraIsShrinkHeader = 0; + + yaffs_VerifyObjectHeader(object,oh,&tags,1); + } + + newChunk = + yaffs_WriteNewChunkWithTagsToNAND(dev, buffer, &tags, 1); + + if (newChunk < 0) { + retVal = YAFFS_FAIL; + } else { + + /* Ok, now fix up the Tnodes etc. */ + + if (tags.chunkId == 0) { + /* It's a header */ + object->chunkId = newChunk; + object->serial = tags.serialNumber; + } else { + /* It's a data chunk */ + yaffs_PutChunkIntoFile + (object, + tags.chunkId, + newChunk, 0); + } + } + } + + yaffs_DeleteChunk(dev, oldChunk, markNAND, __LINE__); + + } + } + + yaffs_ReleaseTempBuffer(dev, buffer, __LINE__); + + + /* Do any required cleanups */ + for (i = 0; i < cleanups; i++) { + /* Time to delete the file too */ + object = + yaffs_FindObjectByNumber(dev, + dev->gcCleanupList[i]); + if (object) { + yaffs_FreeTnode(dev, + object->variant.fileVariant. + top); + object->variant.fileVariant.top = NULL; + T(YAFFS_TRACE_GC, + (TSTR + ("yaffs: About to finally delete object %d" + TENDSTR), object->objectId)); + yaffs_DoGenericObjectDeletion(object); + object->myDev->nDeletedFiles--; + } + + } + + } + + yaffs_VerifyCollectedBlock(dev,bi,block); + + if (chunksBefore >= (chunksAfter = yaffs_GetErasedChunks(dev))) { + T(YAFFS_TRACE_GC, + (TSTR + ("gc did not increase free chunks before %d after %d" + TENDSTR), chunksBefore, chunksAfter)); + } + + dev->isDoingGC = 0; + + return YAFFS_OK; +} + +/* New garbage collector + * If we're very low on erased blocks then we do aggressive garbage collection + * otherwise we do "leasurely" garbage collection. + * Aggressive gc looks further (whole array) and will accept less dirty blocks. + * Passive gc only inspects smaller areas and will only accept more dirty blocks. + * + * The idea is to help clear out space in a more spread-out manner. + * Dunno if it really does anything useful. + */ +static int yaffs_CheckGarbageCollection(yaffs_Device * dev) +{ + int block; + int aggressive; + int gcOk = YAFFS_OK; + int maxTries = 0; + + int checkpointBlockAdjust; + + if (dev->isDoingGC) { + /* Bail out so we don't get recursive gc */ + return YAFFS_OK; + } + + /* This loop should pass the first time. + * We'll only see looping here if the erase of the collected block fails. + */ + + do { + maxTries++; + + checkpointBlockAdjust = yaffs_CalcCheckpointBlocksRequired(dev) - dev->blocksInCheckpoint; + if(checkpointBlockAdjust < 0) + checkpointBlockAdjust = 0; + + if (dev->nErasedBlocks < (dev->nReservedBlocks + checkpointBlockAdjust + 2)) { + /* We need a block soon...*/ + aggressive = 1; + } else { + /* We're in no hurry */ + aggressive = 0; + } + + block = yaffs_FindBlockForGarbageCollection(dev, aggressive); + + if (block > 0) { + dev->garbageCollections++; + if (!aggressive) { + dev->passiveGarbageCollections++; + } + + T(YAFFS_TRACE_GC, + (TSTR + ("yaffs: GC erasedBlocks %d aggressive %d" TENDSTR), + dev->nErasedBlocks, aggressive)); + + gcOk = yaffs_GarbageCollectBlock(dev, block); + } + + if (dev->nErasedBlocks < (dev->nReservedBlocks) && block > 0) { + T(YAFFS_TRACE_GC, + (TSTR + ("yaffs: GC !!!no reclaim!!! erasedBlocks %d after try %d block %d" + TENDSTR), dev->nErasedBlocks, maxTries, block)); + } + } while ((dev->nErasedBlocks < dev->nReservedBlocks) && (block > 0) + && (maxTries < 2)); + + return aggressive ? gcOk : YAFFS_OK; +} + +/*------------------------- TAGS --------------------------------*/ + +static int yaffs_TagsMatch(const yaffs_ExtendedTags * tags, int objectId, + int chunkInObject) +{ + return (tags->chunkId == chunkInObject && + tags->objectId == objectId && !tags->chunkDeleted) ? 1 : 0; + +} + + +/*-------------------- Data file manipulation -----------------*/ + +static int yaffs_FindChunkInFile(yaffs_Object * in, int chunkInInode, + yaffs_ExtendedTags * tags) +{ + /*Get the Tnode, then get the level 0 offset chunk offset */ + yaffs_Tnode *tn; + int theChunk = -1; + yaffs_ExtendedTags localTags; + int retVal = -1; + + yaffs_Device *dev = in->myDev; + + if (!tags) { + /* Passed a NULL, so use our own tags space */ + tags = &localTags; + } + + tn = yaffs_FindLevel0Tnode(dev, &in->variant.fileVariant, chunkInInode); + + if (tn) { + theChunk = yaffs_GetChunkGroupBase(dev,tn,chunkInInode); + + retVal = + yaffs_FindChunkInGroup(dev, theChunk, tags, in->objectId, + chunkInInode); + } + return retVal; +} + +static int yaffs_FindAndDeleteChunkInFile(yaffs_Object * in, int chunkInInode, + yaffs_ExtendedTags * tags) +{ + /* Get the Tnode, then get the level 0 offset chunk offset */ + yaffs_Tnode *tn; + int theChunk = -1; + yaffs_ExtendedTags localTags; + + yaffs_Device *dev = in->myDev; + int retVal = -1; + + if (!tags) { + /* Passed a NULL, so use our own tags space */ + tags = &localTags; + } + + tn = yaffs_FindLevel0Tnode(dev, &in->variant.fileVariant, chunkInInode); + + if (tn) { + + theChunk = yaffs_GetChunkGroupBase(dev,tn,chunkInInode); + + retVal = + yaffs_FindChunkInGroup(dev, theChunk, tags, in->objectId, + chunkInInode); + + /* Delete the entry in the filestructure (if found) */ + if (retVal != -1) { + yaffs_PutLevel0Tnode(dev,tn,chunkInInode,0); + } + } else { + /*T(("No level 0 found for %d\n", chunkInInode)); */ + } + + if (retVal == -1) { + /* T(("Could not find %d to delete\n",chunkInInode)); */ + } + return retVal; +} + +#ifdef YAFFS_PARANOID + +static int yaffs_CheckFileSanity(yaffs_Object * in) +{ + int chunk; + int nChunks; + int fSize; + int failed = 0; + int objId; + yaffs_Tnode *tn; + yaffs_Tags localTags; + yaffs_Tags *tags = &localTags; + int theChunk; + int chunkDeleted; + + if (in->variantType != YAFFS_OBJECT_TYPE_FILE) { + /* T(("Object not a file\n")); */ + return YAFFS_FAIL; + } + + objId = in->objectId; + fSize = in->variant.fileVariant.fileSize; + nChunks = + (fSize + in->myDev->nDataBytesPerChunk - 1) / in->myDev->nDataBytesPerChunk; + + for (chunk = 1; chunk <= nChunks; chunk++) { + tn = yaffs_FindLevel0Tnode(in->myDev, &in->variant.fileVariant, + chunk); + + if (tn) { + + theChunk = yaffs_GetChunkGroupBase(dev,tn,chunk); + + if (yaffs_CheckChunkBits + (dev, theChunk / dev->nChunksPerBlock, + theChunk % dev->nChunksPerBlock)) { + + yaffs_ReadChunkTagsFromNAND(in->myDev, theChunk, + tags, + &chunkDeleted); + if (yaffs_TagsMatch + (tags, in->objectId, chunk, chunkDeleted)) { + /* found it; */ + + } + } else { + + failed = 1; + } + + } else { + /* T(("No level 0 found for %d\n", chunk)); */ + } + } + + return failed ? YAFFS_FAIL : YAFFS_OK; +} + +#endif + +static int yaffs_PutChunkIntoFile(yaffs_Object * in, int chunkInInode, + int chunkInNAND, int inScan) +{ + /* NB inScan is zero unless scanning. + * For forward scanning, inScan is > 0; + * for backward scanning inScan is < 0 + */ + + yaffs_Tnode *tn; + yaffs_Device *dev = in->myDev; + int existingChunk; + yaffs_ExtendedTags existingTags; + yaffs_ExtendedTags newTags; + unsigned existingSerial, newSerial; + + if (in->variantType != YAFFS_OBJECT_TYPE_FILE) { + /* Just ignore an attempt at putting a chunk into a non-file during scanning + * If it is not during Scanning then something went wrong! + */ + if (!inScan) { + T(YAFFS_TRACE_ERROR, + (TSTR + ("yaffs tragedy:attempt to put data chunk into a non-file" + TENDSTR))); + YBUG(); + } + + yaffs_DeleteChunk(dev, chunkInNAND, 1, __LINE__); + return YAFFS_OK; + } + + tn = yaffs_AddOrFindLevel0Tnode(dev, + &in->variant.fileVariant, + chunkInInode, + NULL); + if (!tn) { + return YAFFS_FAIL; + } + + existingChunk = yaffs_GetChunkGroupBase(dev,tn,chunkInInode); + + if (inScan != 0) { + /* If we're scanning then we need to test for duplicates + * NB This does not need to be efficient since it should only ever + * happen when the power fails during a write, then only one + * chunk should ever be affected. + * + * Correction for YAFFS2: This could happen quite a lot and we need to think about efficiency! TODO + * Update: For backward scanning we don't need to re-read tags so this is quite cheap. + */ + + if (existingChunk != 0) { + /* NB Right now existing chunk will not be real chunkId if the device >= 32MB + * thus we have to do a FindChunkInFile to get the real chunk id. + * + * We have a duplicate now we need to decide which one to use: + * + * Backwards scanning YAFFS2: The old one is what we use, dump the new one. + * Forward scanning YAFFS2: The new one is what we use, dump the old one. + * YAFFS1: Get both sets of tags and compare serial numbers. + */ + + if (inScan > 0) { + /* Only do this for forward scanning */ + yaffs_ReadChunkWithTagsFromNAND(dev, + chunkInNAND, + NULL, &newTags); + + /* Do a proper find */ + existingChunk = + yaffs_FindChunkInFile(in, chunkInInode, + &existingTags); + } + + if (existingChunk <= 0) { + /*Hoosterman - how did this happen? */ + + T(YAFFS_TRACE_ERROR, + (TSTR + ("yaffs tragedy: existing chunk < 0 in scan" + TENDSTR))); + + } + + /* NB The deleted flags should be false, otherwise the chunks will + * not be loaded during a scan + */ + + newSerial = newTags.serialNumber; + existingSerial = existingTags.serialNumber; + + if ((inScan > 0) && + (in->myDev->isYaffs2 || + existingChunk <= 0 || + ((existingSerial + 1) & 3) == newSerial)) { + /* Forward scanning. + * Use new + * Delete the old one and drop through to update the tnode + */ + yaffs_DeleteChunk(dev, existingChunk, 1, + __LINE__); + } else { + /* Backward scanning or we want to use the existing one + * Use existing. + * Delete the new one and return early so that the tnode isn't changed + */ + yaffs_DeleteChunk(dev, chunkInNAND, 1, + __LINE__); + return YAFFS_OK; + } + } + + } + + if (existingChunk == 0) { + in->nDataChunks++; + } + + yaffs_PutLevel0Tnode(dev,tn,chunkInInode,chunkInNAND); + + return YAFFS_OK; +} + +static int yaffs_ReadChunkDataFromObject(yaffs_Object * in, int chunkInInode, + __u8 * buffer) +{ + int chunkInNAND = yaffs_FindChunkInFile(in, chunkInInode, NULL); + + if (chunkInNAND >= 0) { + return yaffs_ReadChunkWithTagsFromNAND(in->myDev, chunkInNAND, + buffer,NULL); + } else { + T(YAFFS_TRACE_NANDACCESS, + (TSTR("Chunk %d not found zero instead" TENDSTR), + chunkInNAND)); + /* get sane (zero) data if you read a hole */ + memset(buffer, 0, in->myDev->nDataBytesPerChunk); + return 0; + } + +} + +void yaffs_DeleteChunk(yaffs_Device * dev, int chunkId, int markNAND, int lyn) +{ + int block; + int page; + yaffs_ExtendedTags tags; + yaffs_BlockInfo *bi; + + if (chunkId <= 0) + return; + + + dev->nDeletions++; + block = chunkId / dev->nChunksPerBlock; + page = chunkId % dev->nChunksPerBlock; + + + if(!yaffs_CheckChunkBit(dev,block,page)) + T(YAFFS_TRACE_VERIFY, + (TSTR("Deleting invalid chunk %d"TENDSTR), + chunkId)); + + bi = yaffs_GetBlockInfo(dev, block); + + T(YAFFS_TRACE_DELETION, + (TSTR("line %d delete of chunk %d" TENDSTR), lyn, chunkId)); + + if (markNAND && + bi->blockState != YAFFS_BLOCK_STATE_COLLECTING && !dev->isYaffs2) { + + yaffs_InitialiseTags(&tags); + + tags.chunkDeleted = 1; + + yaffs_WriteChunkWithTagsToNAND(dev, chunkId, NULL, &tags); + yaffs_HandleUpdateChunk(dev, chunkId, &tags); + } else { + dev->nUnmarkedDeletions++; + } + + /* Pull out of the management area. + * If the whole block became dirty, this will kick off an erasure. + */ + if (bi->blockState == YAFFS_BLOCK_STATE_ALLOCATING || + bi->blockState == YAFFS_BLOCK_STATE_FULL || + bi->blockState == YAFFS_BLOCK_STATE_NEEDS_SCANNING || + bi->blockState == YAFFS_BLOCK_STATE_COLLECTING) { + dev->nFreeChunks++; + + yaffs_ClearChunkBit(dev, block, page); + + bi->pagesInUse--; + + if (bi->pagesInUse == 0 && + !bi->hasShrinkHeader && + bi->blockState != YAFFS_BLOCK_STATE_ALLOCATING && + bi->blockState != YAFFS_BLOCK_STATE_NEEDS_SCANNING) { + yaffs_BlockBecameDirty(dev, block); + } + + } else { + /* T(("Bad news deleting chunk %d\n",chunkId)); */ + } + +} + +static int yaffs_WriteChunkDataToObject(yaffs_Object * in, int chunkInInode, + const __u8 * buffer, int nBytes, + int useReserve) +{ + /* Find old chunk Need to do this to get serial number + * Write new one and patch into tree. + * Invalidate old tags. + */ + + int prevChunkId; + yaffs_ExtendedTags prevTags; + + int newChunkId; + yaffs_ExtendedTags newTags; + + yaffs_Device *dev = in->myDev; + + yaffs_CheckGarbageCollection(dev); + + /* Get the previous chunk at this location in the file if it exists */ + prevChunkId = yaffs_FindChunkInFile(in, chunkInInode, &prevTags); + + /* Set up new tags */ + yaffs_InitialiseTags(&newTags); + + newTags.chunkId = chunkInInode; + newTags.objectId = in->objectId; + newTags.serialNumber = + (prevChunkId >= 0) ? prevTags.serialNumber + 1 : 1; + newTags.byteCount = nBytes; + + newChunkId = + yaffs_WriteNewChunkWithTagsToNAND(dev, buffer, &newTags, + useReserve); + + if (newChunkId >= 0) { + yaffs_PutChunkIntoFile(in, chunkInInode, newChunkId, 0); + + if (prevChunkId >= 0) { + yaffs_DeleteChunk(dev, prevChunkId, 1, __LINE__); + + } + + yaffs_CheckFileSanity(in); + } + return newChunkId; + +} + +/* UpdateObjectHeader updates the header on NAND for an object. + * If name is not NULL, then that new name is used. + */ +int yaffs_UpdateObjectHeader(yaffs_Object * in, const YCHAR * name, int force, + int isShrink, int shadows) +{ + + yaffs_BlockInfo *bi; + + yaffs_Device *dev = in->myDev; + + int prevChunkId; + int retVal = 0; + int result = 0; + + int newChunkId; + yaffs_ExtendedTags newTags; + yaffs_ExtendedTags oldTags; + + __u8 *buffer = NULL; + YCHAR oldName[YAFFS_MAX_NAME_LENGTH + 1]; + + yaffs_ObjectHeader *oh = NULL; + + yaffs_strcpy(oldName,"silly old name"); + + if (!in->fake || force) { + + yaffs_CheckGarbageCollection(dev); + yaffs_CheckObjectDetailsLoaded(in); + + buffer = yaffs_GetTempBuffer(in->myDev, __LINE__); + oh = (yaffs_ObjectHeader *) buffer; + + prevChunkId = in->chunkId; + + if (prevChunkId >= 0) { + result = yaffs_ReadChunkWithTagsFromNAND(dev, prevChunkId, + buffer, &oldTags); + + yaffs_VerifyObjectHeader(in,oh,&oldTags,0); + + memcpy(oldName, oh->name, sizeof(oh->name)); + } + + memset(buffer, 0xFF, dev->nDataBytesPerChunk); + + oh->type = in->variantType; + oh->yst_mode = in->yst_mode; + oh->shadowsObject = shadows; + +#ifdef CONFIG_YAFFS_WINCE + oh->win_atime[0] = in->win_atime[0]; + oh->win_ctime[0] = in->win_ctime[0]; + oh->win_mtime[0] = in->win_mtime[0]; + oh->win_atime[1] = in->win_atime[1]; + oh->win_ctime[1] = in->win_ctime[1]; + oh->win_mtime[1] = in->win_mtime[1]; +#else + oh->yst_uid = in->yst_uid; + oh->yst_gid = in->yst_gid; + oh->yst_atime = in->yst_atime; + oh->yst_mtime = in->yst_mtime; + oh->yst_ctime = in->yst_ctime; + oh->yst_rdev = in->yst_rdev; +#endif + if (in->parent) { + oh->parentObjectId = in->parent->objectId; + } else { + oh->parentObjectId = 0; + } + + if (name && *name) { + memset(oh->name, 0, sizeof(oh->name)); + yaffs_strncpy(oh->name, name, YAFFS_MAX_NAME_LENGTH); + } else if (prevChunkId>=0) { + memcpy(oh->name, oldName, sizeof(oh->name)); + } else { + memset(oh->name, 0, sizeof(oh->name)); + } + + oh->isShrink = isShrink; + + switch (in->variantType) { + case YAFFS_OBJECT_TYPE_UNKNOWN: + /* Should not happen */ + break; + case YAFFS_OBJECT_TYPE_FILE: + oh->fileSize = + (oh->parentObjectId == YAFFS_OBJECTID_DELETED + || oh->parentObjectId == + YAFFS_OBJECTID_UNLINKED) ? 0 : in->variant. + fileVariant.fileSize; + break; + case YAFFS_OBJECT_TYPE_HARDLINK: + oh->equivalentObjectId = + in->variant.hardLinkVariant.equivalentObjectId; + break; + case YAFFS_OBJECT_TYPE_SPECIAL: + /* Do nothing */ + break; + case YAFFS_OBJECT_TYPE_DIRECTORY: + /* Do nothing */ + break; + case YAFFS_OBJECT_TYPE_SYMLINK: + yaffs_strncpy(oh->alias, + in->variant.symLinkVariant.alias, + YAFFS_MAX_ALIAS_LENGTH); + oh->alias[YAFFS_MAX_ALIAS_LENGTH] = 0; + break; + } + + /* Tags */ + yaffs_InitialiseTags(&newTags); + in->serial++; + newTags.chunkId = 0; + newTags.objectId = in->objectId; + newTags.serialNumber = in->serial; + + /* Add extra info for file header */ + + newTags.extraHeaderInfoAvailable = 1; + newTags.extraParentObjectId = oh->parentObjectId; + newTags.extraFileLength = oh->fileSize; + newTags.extraIsShrinkHeader = oh->isShrink; + newTags.extraEquivalentObjectId = oh->equivalentObjectId; + newTags.extraShadows = (oh->shadowsObject > 0) ? 1 : 0; + newTags.extraObjectType = in->variantType; + + yaffs_VerifyObjectHeader(in,oh,&newTags,1); + + /* Create new chunk in NAND */ + newChunkId = + yaffs_WriteNewChunkWithTagsToNAND(dev, buffer, &newTags, + (prevChunkId >= 0) ? 1 : 0); + + if (newChunkId >= 0) { + + in->chunkId = newChunkId; + + if (prevChunkId >= 0) { + yaffs_DeleteChunk(dev, prevChunkId, 1, + __LINE__); + } + + if(!yaffs_ObjectHasCachedWriteData(in)) + in->dirty = 0; + + /* If this was a shrink, then mark the block that the chunk lives on */ + if (isShrink) { + bi = yaffs_GetBlockInfo(in->myDev, + newChunkId /in->myDev-> nChunksPerBlock); + bi->hasShrinkHeader = 1; + } + + } + + retVal = newChunkId; + + } + + if (buffer) + yaffs_ReleaseTempBuffer(dev, buffer, __LINE__); + + return retVal; +} + +/*------------------------ Short Operations Cache ---------------------------------------- + * In many situations where there is no high level buffering (eg WinCE) a lot of + * reads might be short sequential reads, and a lot of writes may be short + * sequential writes. eg. scanning/writing a jpeg file. + * In these cases, a short read/write cache can provide a huge perfomance benefit + * with dumb-as-a-rock code. + * In Linux, the page cache provides read buffering aand the short op cache provides write + * buffering. + * + * There are a limited number (~10) of cache chunks per device so that we don't + * need a very intelligent search. + */ + +static int yaffs_ObjectHasCachedWriteData(yaffs_Object *obj) +{ + yaffs_Device *dev = obj->myDev; + int i; + yaffs_ChunkCache *cache; + int nCaches = obj->myDev->nShortOpCaches; + + for(i = 0; i < nCaches; i++){ + cache = &dev->srCache[i]; + if (cache->object == obj && + cache->dirty) + return 1; + } + + return 0; +} + + +static void yaffs_FlushFilesChunkCache(yaffs_Object * obj) +{ + yaffs_Device *dev = obj->myDev; + int lowest = -99; /* Stop compiler whining. */ + int i; + yaffs_ChunkCache *cache; + int chunkWritten = 0; + int nCaches = obj->myDev->nShortOpCaches; + + if (nCaches > 0) { + do { + cache = NULL; + + /* Find the dirty cache for this object with the lowest chunk id. */ + for (i = 0; i < nCaches; i++) { + if (dev->srCache[i].object == obj && + dev->srCache[i].dirty) { + if (!cache + || dev->srCache[i].chunkId < + lowest) { + cache = &dev->srCache[i]; + lowest = cache->chunkId; + } + } + } + + if (cache && !cache->locked) { + /* Write it out and free it up */ + + chunkWritten = + yaffs_WriteChunkDataToObject(cache->object, + cache->chunkId, + cache->data, + cache->nBytes, + 1); + cache->dirty = 0; + cache->object = NULL; + } + + } while (cache && chunkWritten > 0); + + if (cache) { + /* Hoosterman, disk full while writing cache out. */ + T(YAFFS_TRACE_ERROR, + (TSTR("yaffs tragedy: no space during cache write" TENDSTR))); + + } + } + +} + +/*yaffs_FlushEntireDeviceCache(dev) + * + * + */ + +void yaffs_FlushEntireDeviceCache(yaffs_Device *dev) +{ + yaffs_Object *obj; + int nCaches = dev->nShortOpCaches; + int i; + + /* Find a dirty object in the cache and flush it... + * until there are no further dirty objects. + */ + do { + obj = NULL; + for( i = 0; i < nCaches && !obj; i++) { + if (dev->srCache[i].object && + dev->srCache[i].dirty) + obj = dev->srCache[i].object; + + } + if(obj) + yaffs_FlushFilesChunkCache(obj); + + } while(obj); + +} + + +/* Grab us a cache chunk for use. + * First look for an empty one. + * Then look for the least recently used non-dirty one. + * Then look for the least recently used dirty one...., flush and look again. + */ +static yaffs_ChunkCache *yaffs_GrabChunkCacheWorker(yaffs_Device * dev) +{ + int i; + int usage; + int theOne; + + if (dev->nShortOpCaches > 0) { + for (i = 0; i < dev->nShortOpCaches; i++) { + if (!dev->srCache[i].object) + return &dev->srCache[i]; + } + + return NULL; + + theOne = -1; + usage = 0; /* just to stop the compiler grizzling */ + + for (i = 0; i < dev->nShortOpCaches; i++) { + if (!dev->srCache[i].dirty && + ((dev->srCache[i].lastUse < usage && theOne >= 0) || + theOne < 0)) { + usage = dev->srCache[i].lastUse; + theOne = i; + } + } + + + return theOne >= 0 ? &dev->srCache[theOne] : NULL; + } else { + return NULL; + } + +} + +static yaffs_ChunkCache *yaffs_GrabChunkCache(yaffs_Device * dev) +{ + yaffs_ChunkCache *cache; + yaffs_Object *theObj; + int usage; + int i; + int pushout; + + if (dev->nShortOpCaches > 0) { + /* Try find a non-dirty one... */ + + cache = yaffs_GrabChunkCacheWorker(dev); + + if (!cache) { + /* They were all dirty, find the last recently used object and flush + * its cache, then find again. + * NB what's here is not very accurate, we actually flush the object + * the last recently used page. + */ + + /* With locking we can't assume we can use entry zero */ + + theObj = NULL; + usage = -1; + cache = NULL; + pushout = -1; + + for (i = 0; i < dev->nShortOpCaches; i++) { + if (dev->srCache[i].object && + !dev->srCache[i].locked && + (dev->srCache[i].lastUse < usage || !cache)) + { + usage = dev->srCache[i].lastUse; + theObj = dev->srCache[i].object; + cache = &dev->srCache[i]; + pushout = i; + } + } + + if (!cache || cache->dirty) { + /* Flush and try again */ + yaffs_FlushFilesChunkCache(theObj); + cache = yaffs_GrabChunkCacheWorker(dev); + } + + } + return cache; + } else + return NULL; + +} + +/* Find a cached chunk */ +static yaffs_ChunkCache *yaffs_FindChunkCache(const yaffs_Object * obj, + int chunkId) +{ + yaffs_Device *dev = obj->myDev; + int i; + if (dev->nShortOpCaches > 0) { + for (i = 0; i < dev->nShortOpCaches; i++) { + if (dev->srCache[i].object == obj && + dev->srCache[i].chunkId == chunkId) { + dev->cacheHits++; + + return &dev->srCache[i]; + } + } + } + return NULL; +} + +/* Mark the chunk for the least recently used algorithym */ +static void yaffs_UseChunkCache(yaffs_Device * dev, yaffs_ChunkCache * cache, + int isAWrite) +{ + + if (dev->nShortOpCaches > 0) { + if (dev->srLastUse < 0 || dev->srLastUse > 100000000) { + /* Reset the cache usages */ + int i; + for (i = 1; i < dev->nShortOpCaches; i++) { + dev->srCache[i].lastUse = 0; + } + dev->srLastUse = 0; + } + + dev->srLastUse++; + + cache->lastUse = dev->srLastUse; + + if (isAWrite) { + cache->dirty = 1; + } + } +} + +/* Invalidate a single cache page. + * Do this when a whole page gets written, + * ie the short cache for this page is no longer valid. + */ +static void yaffs_InvalidateChunkCache(yaffs_Object * object, int chunkId) +{ + if (object->myDev->nShortOpCaches > 0) { + yaffs_ChunkCache *cache = yaffs_FindChunkCache(object, chunkId); + + if (cache) { + cache->object = NULL; + } + } +} + +/* Invalidate all the cache pages associated with this object + * Do this whenever ther file is deleted or resized. + */ +static void yaffs_InvalidateWholeChunkCache(yaffs_Object * in) +{ + int i; + yaffs_Device *dev = in->myDev; + + if (dev->nShortOpCaches > 0) { + /* Invalidate it. */ + for (i = 0; i < dev->nShortOpCaches; i++) { + if (dev->srCache[i].object == in) { + dev->srCache[i].object = NULL; + } + } + } +} + +/*--------------------- Checkpointing --------------------*/ + + +static int yaffs_WriteCheckpointValidityMarker(yaffs_Device *dev,int head) +{ + yaffs_CheckpointValidity cp; + + memset(&cp,0,sizeof(cp)); + + cp.structType = sizeof(cp); + cp.magic = YAFFS_MAGIC; + cp.version = YAFFS_CHECKPOINT_VERSION; + cp.head = (head) ? 1 : 0; + + return (yaffs_CheckpointWrite(dev,&cp,sizeof(cp)) == sizeof(cp))? + 1 : 0; +} + +static int yaffs_ReadCheckpointValidityMarker(yaffs_Device *dev, int head) +{ + yaffs_CheckpointValidity cp; + int ok; + + ok = (yaffs_CheckpointRead(dev,&cp,sizeof(cp)) == sizeof(cp)); + + if(ok) + ok = (cp.structType == sizeof(cp)) && + (cp.magic == YAFFS_MAGIC) && + (cp.version == YAFFS_CHECKPOINT_VERSION) && + (cp.head == ((head) ? 1 : 0)); + return ok ? 1 : 0; +} + +static void yaffs_DeviceToCheckpointDevice(yaffs_CheckpointDevice *cp, + yaffs_Device *dev) +{ + cp->nErasedBlocks = dev->nErasedBlocks; + cp->allocationBlock = dev->allocationBlock; + cp->allocationPage = dev->allocationPage; + cp->nFreeChunks = dev->nFreeChunks; + + cp->nDeletedFiles = dev->nDeletedFiles; + cp->nUnlinkedFiles = dev->nUnlinkedFiles; + cp->nBackgroundDeletions = dev->nBackgroundDeletions; + cp->sequenceNumber = dev->sequenceNumber; + cp->oldestDirtySequence = dev->oldestDirtySequence; + +} + +static void yaffs_CheckpointDeviceToDevice(yaffs_Device *dev, + yaffs_CheckpointDevice *cp) +{ + dev->nErasedBlocks = cp->nErasedBlocks; + dev->allocationBlock = cp->allocationBlock; + dev->allocationPage = cp->allocationPage; + dev->nFreeChunks = cp->nFreeChunks; + + dev->nDeletedFiles = cp->nDeletedFiles; + dev->nUnlinkedFiles = cp->nUnlinkedFiles; + dev->nBackgroundDeletions = cp->nBackgroundDeletions; + dev->sequenceNumber = cp->sequenceNumber; + dev->oldestDirtySequence = cp->oldestDirtySequence; +} + + +static int yaffs_WriteCheckpointDevice(yaffs_Device *dev) +{ + yaffs_CheckpointDevice cp; + __u32 nBytes; + __u32 nBlocks = (dev->internalEndBlock - dev->internalStartBlock + 1); + + int ok; + + /* Write device runtime values*/ + yaffs_DeviceToCheckpointDevice(&cp,dev); + cp.structType = sizeof(cp); + + ok = (yaffs_CheckpointWrite(dev,&cp,sizeof(cp)) == sizeof(cp)); + + /* Write block info */ + if(ok) { + nBytes = nBlocks * sizeof(yaffs_BlockInfo); + ok = (yaffs_CheckpointWrite(dev,dev->blockInfo,nBytes) == nBytes); + } + + /* Write chunk bits */ + if(ok) { + nBytes = nBlocks * dev->chunkBitmapStride; + ok = (yaffs_CheckpointWrite(dev,dev->chunkBits,nBytes) == nBytes); + } + return ok ? 1 : 0; + +} + +static int yaffs_ReadCheckpointDevice(yaffs_Device *dev) +{ + yaffs_CheckpointDevice cp; + __u32 nBytes; + __u32 nBlocks = (dev->internalEndBlock - dev->internalStartBlock + 1); + + int ok; + + ok = (yaffs_CheckpointRead(dev,&cp,sizeof(cp)) == sizeof(cp)); + if(!ok) + return 0; + + if(cp.structType != sizeof(cp)) + return 0; + + + yaffs_CheckpointDeviceToDevice(dev,&cp); + + nBytes = nBlocks * sizeof(yaffs_BlockInfo); + + ok = (yaffs_CheckpointRead(dev,dev->blockInfo,nBytes) == nBytes); + + if(!ok) + return 0; + nBytes = nBlocks * dev->chunkBitmapStride; + + ok = (yaffs_CheckpointRead(dev,dev->chunkBits,nBytes) == nBytes); + + return ok ? 1 : 0; +} + +static void yaffs_ObjectToCheckpointObject(yaffs_CheckpointObject *cp, + yaffs_Object *obj) +{ + + cp->objectId = obj->objectId; + cp->parentId = (obj->parent) ? obj->parent->objectId : 0; + cp->chunkId = obj->chunkId; + cp->variantType = obj->variantType; + cp->deleted = obj->deleted; + cp->softDeleted = obj->softDeleted; + cp->unlinked = obj->unlinked; + cp->fake = obj->fake; + cp->renameAllowed = obj->renameAllowed; + cp->unlinkAllowed = obj->unlinkAllowed; + cp->serial = obj->serial; + cp->nDataChunks = obj->nDataChunks; + + if(obj->variantType == YAFFS_OBJECT_TYPE_FILE) + cp->fileSizeOrEquivalentObjectId = obj->variant.fileVariant.fileSize; + else if(obj->variantType == YAFFS_OBJECT_TYPE_HARDLINK) + cp->fileSizeOrEquivalentObjectId = obj->variant.hardLinkVariant.equivalentObjectId; +} + +static void yaffs_CheckpointObjectToObject( yaffs_Object *obj,yaffs_CheckpointObject *cp) +{ + + yaffs_Object *parent; + + obj->objectId = cp->objectId; + + if(cp->parentId) + parent = yaffs_FindOrCreateObjectByNumber( + obj->myDev, + cp->parentId, + YAFFS_OBJECT_TYPE_DIRECTORY); + else + parent = NULL; + + if(parent) + yaffs_AddObjectToDirectory(parent, obj); + + obj->chunkId = cp->chunkId; + obj->variantType = cp->variantType; + obj->deleted = cp->deleted; + obj->softDeleted = cp->softDeleted; + obj->unlinked = cp->unlinked; + obj->fake = cp->fake; + obj->renameAllowed = cp->renameAllowed; + obj->unlinkAllowed = cp->unlinkAllowed; + obj->serial = cp->serial; + obj->nDataChunks = cp->nDataChunks; + + if(obj->variantType == YAFFS_OBJECT_TYPE_FILE) + obj->variant.fileVariant.fileSize = cp->fileSizeOrEquivalentObjectId; + else if(obj->variantType == YAFFS_OBJECT_TYPE_HARDLINK) + obj->variant.hardLinkVariant.equivalentObjectId = cp->fileSizeOrEquivalentObjectId; + + if(obj->objectId >= YAFFS_NOBJECT_BUCKETS) + obj->lazyLoaded = 1; +} + + + +static int yaffs_CheckpointTnodeWorker(yaffs_Object * in, yaffs_Tnode * tn, + __u32 level, int chunkOffset) +{ + int i; + yaffs_Device *dev = in->myDev; + int ok = 1; + int tnodeSize = (dev->tnodeWidth * YAFFS_NTNODES_LEVEL0)/8; + + if(tnodeSize < sizeof(yaffs_Tnode)) + tnodeSize = sizeof(yaffs_Tnode); + + + if (tn) { + if (level > 0) { + + for (i = 0; i < YAFFS_NTNODES_INTERNAL && ok; i++){ + if (tn->internal[i]) { + ok = yaffs_CheckpointTnodeWorker(in, + tn->internal[i], + level - 1, + (chunkOffset<variantType == YAFFS_OBJECT_TYPE_FILE){ + ok = yaffs_CheckpointTnodeWorker(obj, + obj->variant.fileVariant.top, + obj->variant.fileVariant.topLevel, + 0); + if(ok) + ok = (yaffs_CheckpointWrite(obj->myDev,&endMarker,sizeof(endMarker)) == + sizeof(endMarker)); + } + + return ok ? 1 : 0; +} + +static int yaffs_ReadCheckpointTnodes(yaffs_Object *obj) +{ + __u32 baseChunk; + int ok = 1; + yaffs_Device *dev = obj->myDev; + yaffs_FileStructure *fileStructPtr = &obj->variant.fileVariant; + yaffs_Tnode *tn; + int nread = 0; + int tnodeSize = (dev->tnodeWidth * YAFFS_NTNODES_LEVEL0)/8; + + if(tnodeSize < sizeof(yaffs_Tnode)) + tnodeSize = sizeof(yaffs_Tnode); + + ok = (yaffs_CheckpointRead(dev,&baseChunk,sizeof(baseChunk)) == sizeof(baseChunk)); + + while(ok && (~baseChunk)){ + nread++; + /* Read level 0 tnode */ + + + /* printf("read tnode at %d\n",baseChunk); */ + tn = yaffs_GetTnodeRaw(dev); + if(tn) + ok = (yaffs_CheckpointRead(dev,tn,tnodeSize) == tnodeSize); + else + ok = 0; + + if(tn && ok){ + ok = yaffs_AddOrFindLevel0Tnode(dev, + fileStructPtr, + baseChunk, + tn) ? 1 : 0; + + } + + if(ok) + ok = (yaffs_CheckpointRead(dev,&baseChunk,sizeof(baseChunk)) == sizeof(baseChunk)); + + } + + T(YAFFS_TRACE_CHECKPOINT,( + TSTR("Checkpoint read tnodes %d records, last %d. ok %d" TENDSTR), + nread,baseChunk,ok)); + + return ok ? 1 : 0; +} + + +static int yaffs_WriteCheckpointObjects(yaffs_Device *dev) +{ + yaffs_Object *obj; + yaffs_CheckpointObject cp; + int i; + int ok = 1; + struct list_head *lh; + + + /* Iterate through the objects in each hash entry, + * dumping them to the checkpointing stream. + */ + + for(i = 0; ok && i < YAFFS_NOBJECT_BUCKETS; i++){ + list_for_each(lh, &dev->objectBucket[i].list) { + if (lh) { + obj = list_entry(lh, yaffs_Object, hashLink); + if (!obj->deferedFree) { + yaffs_ObjectToCheckpointObject(&cp,obj); + cp.structType = sizeof(cp); + + T(YAFFS_TRACE_CHECKPOINT,( + TSTR("Checkpoint write object %d parent %d type %d chunk %d obj addr %x" TENDSTR), + cp.objectId,cp.parentId,cp.variantType,cp.chunkId,(unsigned) obj)); + + ok = (yaffs_CheckpointWrite(dev,&cp,sizeof(cp)) == sizeof(cp)); + + if(ok && obj->variantType == YAFFS_OBJECT_TYPE_FILE){ + ok = yaffs_WriteCheckpointTnodes(obj); + } + } + } + } + } + + /* Dump end of list */ + memset(&cp,0xFF,sizeof(yaffs_CheckpointObject)); + cp.structType = sizeof(cp); + + if(ok) + ok = (yaffs_CheckpointWrite(dev,&cp,sizeof(cp)) == sizeof(cp)); + + return ok ? 1 : 0; +} + +static int yaffs_ReadCheckpointObjects(yaffs_Device *dev) +{ + yaffs_Object *obj; + yaffs_CheckpointObject cp; + int ok = 1; + int done = 0; + yaffs_Object *hardList = NULL; + + while(ok && !done) { + ok = (yaffs_CheckpointRead(dev,&cp,sizeof(cp)) == sizeof(cp)); + if(cp.structType != sizeof(cp)) { + T(YAFFS_TRACE_CHECKPOINT,(TSTR("struct size %d instead of %d ok %d"TENDSTR), + cp.structType,sizeof(cp),ok)); + ok = 0; + } + + T(YAFFS_TRACE_CHECKPOINT,(TSTR("Checkpoint read object %d parent %d type %d chunk %d " TENDSTR), + cp.objectId,cp.parentId,cp.variantType,cp.chunkId)); + + if(ok && cp.objectId == ~0) + done = 1; + else if(ok){ + obj = yaffs_FindOrCreateObjectByNumber(dev,cp.objectId, cp.variantType); + if(obj) { + yaffs_CheckpointObjectToObject(obj,&cp); + if(obj->variantType == YAFFS_OBJECT_TYPE_FILE) { + ok = yaffs_ReadCheckpointTnodes(obj); + } else if(obj->variantType == YAFFS_OBJECT_TYPE_HARDLINK) { + obj->hardLinks.next = + (struct list_head *) + hardList; + hardList = obj; + } + + } + } + } + + if(ok) + yaffs_HardlinkFixup(dev,hardList); + + return ok ? 1 : 0; +} + +static int yaffs_WriteCheckpointSum(yaffs_Device *dev) +{ + __u32 checkpointSum; + int ok; + + yaffs_GetCheckpointSum(dev,&checkpointSum); + + ok = (yaffs_CheckpointWrite(dev,&checkpointSum,sizeof(checkpointSum)) == sizeof(checkpointSum)); + + if(!ok) + return 0; + + return 1; +} + +static int yaffs_ReadCheckpointSum(yaffs_Device *dev) +{ + __u32 checkpointSum0; + __u32 checkpointSum1; + int ok; + + yaffs_GetCheckpointSum(dev,&checkpointSum0); + + ok = (yaffs_CheckpointRead(dev,&checkpointSum1,sizeof(checkpointSum1)) == sizeof(checkpointSum1)); + + if(!ok) + return 0; + + if(checkpointSum0 != checkpointSum1) + return 0; + + return 1; +} + + +static int yaffs_WriteCheckpointData(yaffs_Device *dev) +{ + + int ok = 1; + + if(dev->skipCheckpointWrite || !dev->isYaffs2){ + T(YAFFS_TRACE_CHECKPOINT,(TSTR("skipping checkpoint write" TENDSTR))); + ok = 0; + } + + if(ok) + ok = yaffs_CheckpointOpen(dev,1); + + if(ok){ + T(YAFFS_TRACE_CHECKPOINT,(TSTR("write checkpoint validity" TENDSTR))); + ok = yaffs_WriteCheckpointValidityMarker(dev,1); + } + if(ok){ + T(YAFFS_TRACE_CHECKPOINT,(TSTR("write checkpoint device" TENDSTR))); + ok = yaffs_WriteCheckpointDevice(dev); + } + if(ok){ + T(YAFFS_TRACE_CHECKPOINT,(TSTR("write checkpoint objects" TENDSTR))); + ok = yaffs_WriteCheckpointObjects(dev); + } + if(ok){ + T(YAFFS_TRACE_CHECKPOINT,(TSTR("write checkpoint validity" TENDSTR))); + ok = yaffs_WriteCheckpointValidityMarker(dev,0); + } + + if(ok){ + ok = yaffs_WriteCheckpointSum(dev); + } + + + if(!yaffs_CheckpointClose(dev)) + ok = 0; + + if(ok) + dev->isCheckpointed = 1; + else + dev->isCheckpointed = 0; + + return dev->isCheckpointed; +} + +static int yaffs_ReadCheckpointData(yaffs_Device *dev) +{ + int ok = 1; + + if(dev->skipCheckpointRead || !dev->isYaffs2){ + T(YAFFS_TRACE_CHECKPOINT,(TSTR("skipping checkpoint read" TENDSTR))); + ok = 0; + } + + if(ok) + ok = yaffs_CheckpointOpen(dev,0); /* open for read */ + + if(ok){ + T(YAFFS_TRACE_CHECKPOINT,(TSTR("read checkpoint validity" TENDSTR))); + ok = yaffs_ReadCheckpointValidityMarker(dev,1); + } + if(ok){ + T(YAFFS_TRACE_CHECKPOINT,(TSTR("read checkpoint device" TENDSTR))); + ok = yaffs_ReadCheckpointDevice(dev); + } + if(ok){ + T(YAFFS_TRACE_CHECKPOINT,(TSTR("read checkpoint objects" TENDSTR))); + ok = yaffs_ReadCheckpointObjects(dev); + } + if(ok){ + T(YAFFS_TRACE_CHECKPOINT,(TSTR("read checkpoint validity" TENDSTR))); + ok = yaffs_ReadCheckpointValidityMarker(dev,0); + } + + if(ok){ + ok = yaffs_ReadCheckpointSum(dev); + T(YAFFS_TRACE_CHECKPOINT,(TSTR("read checkpoint checksum %d" TENDSTR),ok)); + } + + if(!yaffs_CheckpointClose(dev)) + ok = 0; + + if(ok) + dev->isCheckpointed = 1; + else + dev->isCheckpointed = 0; + + return ok ? 1 : 0; + +} + +static void yaffs_InvalidateCheckpoint(yaffs_Device *dev) +{ + if(dev->isCheckpointed || + dev->blocksInCheckpoint > 0){ + dev->isCheckpointed = 0; + yaffs_CheckpointInvalidateStream(dev); + if(dev->superBlock && dev->markSuperBlockDirty) + dev->markSuperBlockDirty(dev->superBlock); + } +} + + +int yaffs_CheckpointSave(yaffs_Device *dev) +{ + + T(YAFFS_TRACE_CHECKPOINT,(TSTR("save entry: isCheckpointed %d"TENDSTR),dev->isCheckpointed)); + + yaffs_VerifyObjects(dev); + yaffs_VerifyBlocks(dev); + yaffs_VerifyFreeChunks(dev); + + if(!dev->isCheckpointed) { + yaffs_InvalidateCheckpoint(dev); + yaffs_WriteCheckpointData(dev); + } + + T(YAFFS_TRACE_ALWAYS,(TSTR("save exit: isCheckpointed %d"TENDSTR),dev->isCheckpointed)); + + return dev->isCheckpointed; +} + +int yaffs_CheckpointRestore(yaffs_Device *dev) +{ + int retval; + T(YAFFS_TRACE_CHECKPOINT,(TSTR("restore entry: isCheckpointed %d"TENDSTR),dev->isCheckpointed)); + + retval = yaffs_ReadCheckpointData(dev); + + if(dev->isCheckpointed){ + yaffs_VerifyObjects(dev); + yaffs_VerifyBlocks(dev); + yaffs_VerifyFreeChunks(dev); + } + + T(YAFFS_TRACE_CHECKPOINT,(TSTR("restore exit: isCheckpointed %d"TENDSTR),dev->isCheckpointed)); + + return retval; +} + +/*--------------------- File read/write ------------------------ + * Read and write have very similar structures. + * In general the read/write has three parts to it + * An incomplete chunk to start with (if the read/write is not chunk-aligned) + * Some complete chunks + * An incomplete chunk to end off with + * + * Curve-balls: the first chunk might also be the last chunk. + */ + +int yaffs_ReadDataFromFile(yaffs_Object * in, __u8 * buffer, loff_t offset, + int nBytes) +{ + + int chunk; + int start; + int nToCopy; + int n = nBytes; + int nDone = 0; + yaffs_ChunkCache *cache; + + yaffs_Device *dev; + + dev = in->myDev; + + while (n > 0) { + //chunk = offset / dev->nDataBytesPerChunk + 1; + //start = offset % dev->nDataBytesPerChunk; + yaffs_AddrToChunk(dev,offset,&chunk,&start); + chunk++; + + /* OK now check for the curveball where the start and end are in + * the same chunk. + */ + if ((start + n) < dev->nDataBytesPerChunk) { + nToCopy = n; + } else { + nToCopy = dev->nDataBytesPerChunk - start; + } + + cache = yaffs_FindChunkCache(in, chunk); + + /* If the chunk is already in the cache or it is less than a whole chunk + * then use the cache (if there is caching) + * else bypass the cache. + */ + if (cache || nToCopy != dev->nDataBytesPerChunk) { + if (dev->nShortOpCaches > 0) { + + /* If we can't find the data in the cache, then load it up. */ + + if (!cache) { + cache = yaffs_GrabChunkCache(in->myDev); + cache->object = in; + cache->chunkId = chunk; + cache->dirty = 0; + cache->locked = 0; + yaffs_ReadChunkDataFromObject(in, chunk, + cache-> + data); + cache->nBytes = 0; + } + + yaffs_UseChunkCache(dev, cache, 0); + + cache->locked = 1; + +#ifdef CONFIG_YAFFS_WINCE + yfsd_UnlockYAFFS(TRUE); +#endif + memcpy(buffer, &cache->data[start], nToCopy); + +#ifdef CONFIG_YAFFS_WINCE + yfsd_LockYAFFS(TRUE); +#endif + cache->locked = 0; + } else { + /* Read into the local buffer then copy..*/ + + __u8 *localBuffer = + yaffs_GetTempBuffer(dev, __LINE__); + yaffs_ReadChunkDataFromObject(in, chunk, + localBuffer); +#ifdef CONFIG_YAFFS_WINCE + yfsd_UnlockYAFFS(TRUE); +#endif + memcpy(buffer, &localBuffer[start], nToCopy); + +#ifdef CONFIG_YAFFS_WINCE + yfsd_LockYAFFS(TRUE); +#endif + yaffs_ReleaseTempBuffer(dev, localBuffer, + __LINE__); + } + + } else { +#ifdef CONFIG_YAFFS_WINCE + __u8 *localBuffer = yaffs_GetTempBuffer(dev, __LINE__); + + /* Under WinCE can't do direct transfer. Need to use a local buffer. + * This is because we otherwise screw up WinCE's memory mapper + */ + yaffs_ReadChunkDataFromObject(in, chunk, localBuffer); + +#ifdef CONFIG_YAFFS_WINCE + yfsd_UnlockYAFFS(TRUE); +#endif + memcpy(buffer, localBuffer, dev->nDataBytesPerChunk); + +#ifdef CONFIG_YAFFS_WINCE + yfsd_LockYAFFS(TRUE); + yaffs_ReleaseTempBuffer(dev, localBuffer, __LINE__); +#endif + +#else + /* A full chunk. Read directly into the supplied buffer. */ + yaffs_ReadChunkDataFromObject(in, chunk, buffer); +#endif + } + + n -= nToCopy; + offset += nToCopy; + buffer += nToCopy; + nDone += nToCopy; + + } + + return nDone; +} + +int yaffs_WriteDataToFile(yaffs_Object * in, const __u8 * buffer, loff_t offset, + int nBytes, int writeThrough) +{ + + int chunk; + int start; + int nToCopy; + int n = nBytes; + int nDone = 0; + int nToWriteBack; + int startOfWrite = offset; + int chunkWritten = 0; + int nBytesRead; + + yaffs_Device *dev; + + dev = in->myDev; + + while (n > 0 && chunkWritten >= 0) { + //chunk = offset / dev->nDataBytesPerChunk + 1; + //start = offset % dev->nDataBytesPerChunk; + yaffs_AddrToChunk(dev,offset,&chunk,&start); + chunk++; + + /* OK now check for the curveball where the start and end are in + * the same chunk. + */ + + if ((start + n) < dev->nDataBytesPerChunk) { + nToCopy = n; + + /* Now folks, to calculate how many bytes to write back.... + * If we're overwriting and not writing to then end of file then + * we need to write back as much as was there before. + */ + + nBytesRead = + in->variant.fileVariant.fileSize - + ((chunk - 1) * dev->nDataBytesPerChunk); + + if (nBytesRead > dev->nDataBytesPerChunk) { + nBytesRead = dev->nDataBytesPerChunk; + } + + nToWriteBack = + (nBytesRead > + (start + n)) ? nBytesRead : (start + n); + + } else { + nToCopy = dev->nDataBytesPerChunk - start; + nToWriteBack = dev->nDataBytesPerChunk; + } + + if (nToCopy != dev->nDataBytesPerChunk) { + /* An incomplete start or end chunk (or maybe both start and end chunk) */ + if (dev->nShortOpCaches > 0) { + yaffs_ChunkCache *cache; + /* If we can't find the data in the cache, then load the cache */ + cache = yaffs_FindChunkCache(in, chunk); + + if (!cache + && yaffs_CheckSpaceForAllocation(in-> + myDev)) { + cache = yaffs_GrabChunkCache(in->myDev); + cache->object = in; + cache->chunkId = chunk; + cache->dirty = 0; + cache->locked = 0; + yaffs_ReadChunkDataFromObject(in, chunk, + cache-> + data); + } + else if(cache && + !cache->dirty && + !yaffs_CheckSpaceForAllocation(in->myDev)){ + /* Drop the cache if it was a read cache item and + * no space check has been made for it. + */ + cache = NULL; + } + + if (cache) { + yaffs_UseChunkCache(dev, cache, 1); + cache->locked = 1; +#ifdef CONFIG_YAFFS_WINCE + yfsd_UnlockYAFFS(TRUE); +#endif + + memcpy(&cache->data[start], buffer, + nToCopy); + +#ifdef CONFIG_YAFFS_WINCE + yfsd_LockYAFFS(TRUE); +#endif + cache->locked = 0; + cache->nBytes = nToWriteBack; + + if (writeThrough) { + chunkWritten = + yaffs_WriteChunkDataToObject + (cache->object, + cache->chunkId, + cache->data, cache->nBytes, + 1); + cache->dirty = 0; + } + + } else { + chunkWritten = -1; /* fail the write */ + } + } else { + /* An incomplete start or end chunk (or maybe both start and end chunk) + * Read into the local buffer then copy, then copy over and write back. + */ + + __u8 *localBuffer = + yaffs_GetTempBuffer(dev, __LINE__); + + yaffs_ReadChunkDataFromObject(in, chunk, + localBuffer); + +#ifdef CONFIG_YAFFS_WINCE + yfsd_UnlockYAFFS(TRUE); +#endif + + memcpy(&localBuffer[start], buffer, nToCopy); + +#ifdef CONFIG_YAFFS_WINCE + yfsd_LockYAFFS(TRUE); +#endif + chunkWritten = + yaffs_WriteChunkDataToObject(in, chunk, + localBuffer, + nToWriteBack, + 0); + + yaffs_ReleaseTempBuffer(dev, localBuffer, + __LINE__); + + } + + } else { + +#ifdef CONFIG_YAFFS_WINCE + /* Under WinCE can't do direct transfer. Need to use a local buffer. + * This is because we otherwise screw up WinCE's memory mapper + */ + __u8 *localBuffer = yaffs_GetTempBuffer(dev, __LINE__); +#ifdef CONFIG_YAFFS_WINCE + yfsd_UnlockYAFFS(TRUE); +#endif + memcpy(localBuffer, buffer, dev->nDataBytesPerChunk); +#ifdef CONFIG_YAFFS_WINCE + yfsd_LockYAFFS(TRUE); +#endif + chunkWritten = + yaffs_WriteChunkDataToObject(in, chunk, localBuffer, + dev->nDataBytesPerChunk, + 0); + yaffs_ReleaseTempBuffer(dev, localBuffer, __LINE__); +#else + /* A full chunk. Write directly from the supplied buffer. */ + chunkWritten = + yaffs_WriteChunkDataToObject(in, chunk, buffer, + dev->nDataBytesPerChunk, + 0); +#endif + /* Since we've overwritten the cached data, we better invalidate it. */ + yaffs_InvalidateChunkCache(in, chunk); + } + + if (chunkWritten >= 0) { + n -= nToCopy; + offset += nToCopy; + buffer += nToCopy; + nDone += nToCopy; + } + + } + + /* Update file object */ + + if ((startOfWrite + nDone) > in->variant.fileVariant.fileSize) { + in->variant.fileVariant.fileSize = (startOfWrite + nDone); + } + + in->dirty = 1; + + return nDone; +} + + +/* ---------------------- File resizing stuff ------------------ */ + +static void yaffs_PruneResizedChunks(yaffs_Object * in, int newSize) +{ + + yaffs_Device *dev = in->myDev; + int oldFileSize = in->variant.fileVariant.fileSize; + + int lastDel = 1 + (oldFileSize - 1) / dev->nDataBytesPerChunk; + + int startDel = 1 + (newSize + dev->nDataBytesPerChunk - 1) / + dev->nDataBytesPerChunk; + int i; + int chunkId; + + /* Delete backwards so that we don't end up with holes if + * power is lost part-way through the operation. + */ + for (i = lastDel; i >= startDel; i--) { + /* NB this could be optimised somewhat, + * eg. could retrieve the tags and write them without + * using yaffs_DeleteChunk + */ + + chunkId = yaffs_FindAndDeleteChunkInFile(in, i, NULL); + if (chunkId > 0) { + if (chunkId < + (dev->internalStartBlock * dev->nChunksPerBlock) + || chunkId >= + ((dev->internalEndBlock + + 1) * dev->nChunksPerBlock)) { + T(YAFFS_TRACE_ALWAYS, + (TSTR("Found daft chunkId %d for %d" TENDSTR), + chunkId, i)); + } else { + in->nDataChunks--; + yaffs_DeleteChunk(dev, chunkId, 1, __LINE__); + } + } + } + +} + +int yaffs_ResizeFile(yaffs_Object * in, loff_t newSize) +{ + + int oldFileSize = in->variant.fileVariant.fileSize; + int newSizeOfPartialChunk; + int newFullChunks; + + yaffs_Device *dev = in->myDev; + + yaffs_AddrToChunk(dev, newSize, &newFullChunks, &newSizeOfPartialChunk); + + yaffs_FlushFilesChunkCache(in); + yaffs_InvalidateWholeChunkCache(in); + + yaffs_CheckGarbageCollection(dev); + + if (in->variantType != YAFFS_OBJECT_TYPE_FILE) { + return yaffs_GetFileSize(in); + } + + if (newSize == oldFileSize) { + return oldFileSize; + } + + if (newSize < oldFileSize) { + + yaffs_PruneResizedChunks(in, newSize); + + if (newSizeOfPartialChunk != 0) { + int lastChunk = 1 + newFullChunks; + + __u8 *localBuffer = yaffs_GetTempBuffer(dev, __LINE__); + + /* Got to read and rewrite the last chunk with its new size and zero pad */ + yaffs_ReadChunkDataFromObject(in, lastChunk, + localBuffer); + + memset(localBuffer + newSizeOfPartialChunk, 0, + dev->nDataBytesPerChunk - newSizeOfPartialChunk); + + yaffs_WriteChunkDataToObject(in, lastChunk, localBuffer, + newSizeOfPartialChunk, 1); + + yaffs_ReleaseTempBuffer(dev, localBuffer, __LINE__); + } + + in->variant.fileVariant.fileSize = newSize; + + yaffs_PruneFileStructure(dev, &in->variant.fileVariant); + } else { + /* newsSize > oldFileSize */ + in->variant.fileVariant.fileSize = newSize; + } + + + + /* Write a new object header. + * show we've shrunk the file, if need be + * Do this only if the file is not in the deleted directories. + */ + if (in->parent->objectId != YAFFS_OBJECTID_UNLINKED && + in->parent->objectId != YAFFS_OBJECTID_DELETED) { + yaffs_UpdateObjectHeader(in, NULL, 0, + (newSize < oldFileSize) ? 1 : 0, 0); + } + + return YAFFS_OK; +} + +loff_t yaffs_GetFileSize(yaffs_Object * obj) +{ + obj = yaffs_GetEquivalentObject(obj); + + switch (obj->variantType) { + case YAFFS_OBJECT_TYPE_FILE: + return obj->variant.fileVariant.fileSize; + case YAFFS_OBJECT_TYPE_SYMLINK: + return yaffs_strlen(obj->variant.symLinkVariant.alias); + default: + return 0; + } +} + + + +int yaffs_FlushFile(yaffs_Object * in, int updateTime) +{ + int retVal; + if (in->dirty) { + yaffs_FlushFilesChunkCache(in); + if (updateTime) { +#ifdef CONFIG_YAFFS_WINCE + yfsd_WinFileTimeNow(in->win_mtime); +#else + + in->yst_mtime = Y_CURRENT_TIME; + +#endif + } + + retVal = + (yaffs_UpdateObjectHeader(in, NULL, 0, 0, 0) >= + 0) ? YAFFS_OK : YAFFS_FAIL; + } else { + retVal = YAFFS_OK; + } + + return retVal; + +} + +static int yaffs_DoGenericObjectDeletion(yaffs_Object * in) +{ + + /* First off, invalidate the file's data in the cache, without flushing. */ + yaffs_InvalidateWholeChunkCache(in); + + if (in->myDev->isYaffs2 && (in->parent != in->myDev->deletedDir)) { + /* Move to the unlinked directory so we have a record that it was deleted. */ + yaffs_ChangeObjectName(in, in->myDev->deletedDir,"deleted", 0, 0); + + } + + yaffs_RemoveObjectFromDirectory(in); + yaffs_DeleteChunk(in->myDev, in->chunkId, 1, __LINE__); + in->chunkId = -1; + + yaffs_FreeObject(in); + return YAFFS_OK; + +} + +/* yaffs_DeleteFile deletes the whole file data + * and the inode associated with the file. + * It does not delete the links associated with the file. + */ +static int yaffs_UnlinkFile(yaffs_Object * in) +{ + + int retVal; + int immediateDeletion = 0; + + if (1) { +#ifdef __KERNEL__ + if (!in->myInode) { + immediateDeletion = 1; + + } +#else + if (in->inUse <= 0) { + immediateDeletion = 1; + + } +#endif + if (immediateDeletion) { + retVal = + yaffs_ChangeObjectName(in, in->myDev->deletedDir, + "deleted", 0, 0); + T(YAFFS_TRACE_TRACING, + (TSTR("yaffs: immediate deletion of file %d" TENDSTR), + in->objectId)); + in->deleted = 1; + in->myDev->nDeletedFiles++; + if (0 && in->myDev->isYaffs2) { + yaffs_ResizeFile(in, 0); + } + yaffs_SoftDeleteFile(in); + } else { + retVal = + yaffs_ChangeObjectName(in, in->myDev->unlinkedDir, + "unlinked", 0, 0); + } + + } + return retVal; +} + +int yaffs_DeleteFile(yaffs_Object * in) +{ + int retVal = YAFFS_OK; + + if (in->nDataChunks > 0) { + /* Use soft deletion if there is data in the file */ + if (!in->unlinked) { + retVal = yaffs_UnlinkFile(in); + } + if (retVal == YAFFS_OK && in->unlinked && !in->deleted) { + in->deleted = 1; + in->myDev->nDeletedFiles++; + yaffs_SoftDeleteFile(in); + } + return in->deleted ? YAFFS_OK : YAFFS_FAIL; + } else { + /* The file has no data chunks so we toss it immediately */ + yaffs_FreeTnode(in->myDev, in->variant.fileVariant.top); + in->variant.fileVariant.top = NULL; + yaffs_DoGenericObjectDeletion(in); + + return YAFFS_OK; + } +} + +static int yaffs_DeleteDirectory(yaffs_Object * in) +{ + /* First check that the directory is empty. */ + if (list_empty(&in->variant.directoryVariant.children)) { + return yaffs_DoGenericObjectDeletion(in); + } + + return YAFFS_FAIL; + +} + +static int yaffs_DeleteSymLink(yaffs_Object * in) +{ + YFREE(in->variant.symLinkVariant.alias); + + return yaffs_DoGenericObjectDeletion(in); +} + +static int yaffs_DeleteHardLink(yaffs_Object * in) +{ + /* remove this hardlink from the list assocaited with the equivalent + * object + */ + list_del(&in->hardLinks); + return yaffs_DoGenericObjectDeletion(in); +} + +static void yaffs_DestroyObject(yaffs_Object * obj) +{ + switch (obj->variantType) { + case YAFFS_OBJECT_TYPE_FILE: + yaffs_DeleteFile(obj); + break; + case YAFFS_OBJECT_TYPE_DIRECTORY: + yaffs_DeleteDirectory(obj); + break; + case YAFFS_OBJECT_TYPE_SYMLINK: + yaffs_DeleteSymLink(obj); + break; + case YAFFS_OBJECT_TYPE_HARDLINK: + yaffs_DeleteHardLink(obj); + break; + case YAFFS_OBJECT_TYPE_SPECIAL: + yaffs_DoGenericObjectDeletion(obj); + break; + case YAFFS_OBJECT_TYPE_UNKNOWN: + break; /* should not happen. */ + } +} + +static int yaffs_UnlinkWorker(yaffs_Object * obj) +{ + + if (obj->variantType == YAFFS_OBJECT_TYPE_HARDLINK) { + return yaffs_DeleteHardLink(obj); + } else if (!list_empty(&obj->hardLinks)) { + /* Curve ball: We're unlinking an object that has a hardlink. + * + * This problem arises because we are not strictly following + * The Linux link/inode model. + * + * We can't really delete the object. + * Instead, we do the following: + * - Select a hardlink. + * - Unhook it from the hard links + * - Unhook it from its parent directory (so that the rename can work) + * - Rename the object to the hardlink's name. + * - Delete the hardlink + */ + + yaffs_Object *hl; + int retVal; + YCHAR name[YAFFS_MAX_NAME_LENGTH + 1]; + + hl = list_entry(obj->hardLinks.next, yaffs_Object, hardLinks); + + list_del_init(&hl->hardLinks); + list_del_init(&hl->siblings); + + yaffs_GetObjectName(hl, name, YAFFS_MAX_NAME_LENGTH + 1); + + retVal = yaffs_ChangeObjectName(obj, hl->parent, name, 0, 0); + + if (retVal == YAFFS_OK) { + retVal = yaffs_DoGenericObjectDeletion(hl); + } + return retVal; + + } else { + switch (obj->variantType) { + case YAFFS_OBJECT_TYPE_FILE: + return yaffs_UnlinkFile(obj); + break; + case YAFFS_OBJECT_TYPE_DIRECTORY: + return yaffs_DeleteDirectory(obj); + break; + case YAFFS_OBJECT_TYPE_SYMLINK: + return yaffs_DeleteSymLink(obj); + break; + case YAFFS_OBJECT_TYPE_SPECIAL: + return yaffs_DoGenericObjectDeletion(obj); + break; + case YAFFS_OBJECT_TYPE_HARDLINK: + case YAFFS_OBJECT_TYPE_UNKNOWN: + default: + return YAFFS_FAIL; + } + } +} + + +static int yaffs_UnlinkObject( yaffs_Object *obj) +{ + + if (obj && obj->unlinkAllowed) { + return yaffs_UnlinkWorker(obj); + } + + return YAFFS_FAIL; + +} +int yaffs_Unlink(yaffs_Object * dir, const YCHAR * name) +{ + yaffs_Object *obj; + + obj = yaffs_FindObjectByName(dir, name); + return yaffs_UnlinkObject(obj); +} + +/*----------------------- Initialisation Scanning ---------------------- */ + +static void yaffs_HandleShadowedObject(yaffs_Device * dev, int objId, + int backwardScanning) +{ + yaffs_Object *obj; + + if (!backwardScanning) { + /* Handle YAFFS1 forward scanning case + * For YAFFS1 we always do the deletion + */ + + } else { + /* Handle YAFFS2 case (backward scanning) + * If the shadowed object exists then ignore. + */ + if (yaffs_FindObjectByNumber(dev, objId)) { + return; + } + } + + /* Let's create it (if it does not exist) assuming it is a file so that it can do shrinking etc. + * We put it in unlinked dir to be cleaned up after the scanning + */ + obj = + yaffs_FindOrCreateObjectByNumber(dev, objId, + YAFFS_OBJECT_TYPE_FILE); + yaffs_AddObjectToDirectory(dev->unlinkedDir, obj); + obj->variant.fileVariant.shrinkSize = 0; + obj->valid = 1; /* So that we don't read any other info for this file */ + +} + +typedef struct { + int seq; + int block; +} yaffs_BlockIndex; + + +static void yaffs_HardlinkFixup(yaffs_Device *dev, yaffs_Object *hardList) +{ + yaffs_Object *hl; + yaffs_Object *in; + + while (hardList) { + hl = hardList; + hardList = (yaffs_Object *) (hardList->hardLinks.next); + + in = yaffs_FindObjectByNumber(dev, + hl->variant.hardLinkVariant. + equivalentObjectId); + + if (in) { + /* Add the hardlink pointers */ + hl->variant.hardLinkVariant.equivalentObject = in; + list_add(&hl->hardLinks, &in->hardLinks); + } else { + /* Todo Need to report/handle this better. + * Got a problem... hardlink to a non-existant object + */ + hl->variant.hardLinkVariant.equivalentObject = NULL; + INIT_LIST_HEAD(&hl->hardLinks); + + } + + } + +} + + + + + +static int ybicmp(const void *a, const void *b){ + register int aseq = ((yaffs_BlockIndex *)a)->seq; + register int bseq = ((yaffs_BlockIndex *)b)->seq; + register int ablock = ((yaffs_BlockIndex *)a)->block; + register int bblock = ((yaffs_BlockIndex *)b)->block; + if( aseq == bseq ) + return ablock - bblock; + else + return aseq - bseq; + +} + +static int yaffs_Scan(yaffs_Device * dev) +{ + yaffs_ExtendedTags tags; + int blk; + int blockIterator; + int startIterator; + int endIterator; + int nBlocksToScan = 0; + int result; + + int chunk; + int c; + int deleted; + yaffs_BlockState state; + yaffs_Object *hardList = NULL; + yaffs_BlockInfo *bi; + int sequenceNumber; + yaffs_ObjectHeader *oh; + yaffs_Object *in; + yaffs_Object *parent; + int nBlocks = dev->internalEndBlock - dev->internalStartBlock + 1; + + int alloc_failed = 0; + + + __u8 *chunkData; + + yaffs_BlockIndex *blockIndex = NULL; + + if (dev->isYaffs2) { + T(YAFFS_TRACE_SCAN, + (TSTR("yaffs_Scan is not for YAFFS2!" TENDSTR))); + return YAFFS_FAIL; + } + + //TODO Throw all the yaffs2 stuuf out of yaffs_Scan since it is only for yaffs1 format. + + T(YAFFS_TRACE_SCAN, + (TSTR("yaffs_Scan starts intstartblk %d intendblk %d..." TENDSTR), + dev->internalStartBlock, dev->internalEndBlock)); + + chunkData = yaffs_GetTempBuffer(dev, __LINE__); + + dev->sequenceNumber = YAFFS_LOWEST_SEQUENCE_NUMBER; + + if (dev->isYaffs2) { + blockIndex = YMALLOC(nBlocks * sizeof(yaffs_BlockIndex)); + if(!blockIndex) + return YAFFS_FAIL; + } + + /* Scan all the blocks to determine their state */ + for (blk = dev->internalStartBlock; blk <= dev->internalEndBlock; blk++) { + bi = yaffs_GetBlockInfo(dev, blk); + yaffs_ClearChunkBits(dev, blk); + bi->pagesInUse = 0; + bi->softDeletions = 0; + + yaffs_QueryInitialBlockState(dev, blk, &state, &sequenceNumber); + + bi->blockState = state; + bi->sequenceNumber = sequenceNumber; + + T(YAFFS_TRACE_SCAN_DEBUG, + (TSTR("Block scanning block %d state %d seq %d" TENDSTR), blk, + state, sequenceNumber)); + + if (state == YAFFS_BLOCK_STATE_DEAD) { + T(YAFFS_TRACE_BAD_BLOCKS, + (TSTR("block %d is bad" TENDSTR), blk)); + } else if (state == YAFFS_BLOCK_STATE_EMPTY) { + T(YAFFS_TRACE_SCAN_DEBUG, + (TSTR("Block empty " TENDSTR))); + dev->nErasedBlocks++; + dev->nFreeChunks += dev->nChunksPerBlock; + } else if (state == YAFFS_BLOCK_STATE_NEEDS_SCANNING) { + + /* Determine the highest sequence number */ + if (dev->isYaffs2 && + sequenceNumber >= YAFFS_LOWEST_SEQUENCE_NUMBER && + sequenceNumber < YAFFS_HIGHEST_SEQUENCE_NUMBER) { + + blockIndex[nBlocksToScan].seq = sequenceNumber; + blockIndex[nBlocksToScan].block = blk; + + nBlocksToScan++; + + if (sequenceNumber >= dev->sequenceNumber) { + dev->sequenceNumber = sequenceNumber; + } + } else if (dev->isYaffs2) { + /* TODO: Nasty sequence number! */ + T(YAFFS_TRACE_SCAN, + (TSTR + ("Block scanning block %d has bad sequence number %d" + TENDSTR), blk, sequenceNumber)); + + } + } + } + + /* Sort the blocks + * Dungy old bubble sort for now... + */ + if (dev->isYaffs2) { + yaffs_BlockIndex temp; + int i; + int j; + + for (i = 0; i < nBlocksToScan; i++) + for (j = i + 1; j < nBlocksToScan; j++) + if (blockIndex[i].seq > blockIndex[j].seq) { + temp = blockIndex[j]; + blockIndex[j] = blockIndex[i]; + blockIndex[i] = temp; + } + } + + /* Now scan the blocks looking at the data. */ + if (dev->isYaffs2) { + startIterator = 0; + endIterator = nBlocksToScan - 1; + T(YAFFS_TRACE_SCAN_DEBUG, + (TSTR("%d blocks to be scanned" TENDSTR), nBlocksToScan)); + } else { + startIterator = dev->internalStartBlock; + endIterator = dev->internalEndBlock; + } + + /* For each block.... */ + for (blockIterator = startIterator; !alloc_failed && blockIterator <= endIterator; + blockIterator++) { + + if (dev->isYaffs2) { + /* get the block to scan in the correct order */ + blk = blockIndex[blockIterator].block; + } else { + blk = blockIterator; + } + + bi = yaffs_GetBlockInfo(dev, blk); + state = bi->blockState; + + deleted = 0; + + /* For each chunk in each block that needs scanning....*/ + for (c = 0; !alloc_failed && c < dev->nChunksPerBlock && + state == YAFFS_BLOCK_STATE_NEEDS_SCANNING; c++) { + /* Read the tags and decide what to do */ + chunk = blk * dev->nChunksPerBlock + c; + + result = yaffs_ReadChunkWithTagsFromNAND(dev, chunk, NULL, + &tags); + + /* Let's have a good look at this chunk... */ + + if (!dev->isYaffs2 && tags.chunkDeleted) { + /* YAFFS1 only... + * A deleted chunk + */ + deleted++; + dev->nFreeChunks++; + /*T((" %d %d deleted\n",blk,c)); */ + } else if (!tags.chunkUsed) { + /* An unassigned chunk in the block + * This means that either the block is empty or + * this is the one being allocated from + */ + + if (c == 0) { + /* We're looking at the first chunk in the block so the block is unused */ + state = YAFFS_BLOCK_STATE_EMPTY; + dev->nErasedBlocks++; + } else { + /* this is the block being allocated from */ + T(YAFFS_TRACE_SCAN, + (TSTR + (" Allocating from %d %d" TENDSTR), + blk, c)); + state = YAFFS_BLOCK_STATE_ALLOCATING; + dev->allocationBlock = blk; + dev->allocationPage = c; + dev->allocationBlockFinder = blk; + /* Set it to here to encourage the allocator to go forth from here. */ + + /* Yaffs2 sanity check: + * This should be the one with the highest sequence number + */ + if (dev->isYaffs2 + && (dev->sequenceNumber != + bi->sequenceNumber)) { + T(YAFFS_TRACE_ALWAYS, + (TSTR + ("yaffs: Allocation block %d was not highest sequence id:" + " block seq = %d, dev seq = %d" + TENDSTR), blk,bi->sequenceNumber,dev->sequenceNumber)); + } + } + + dev->nFreeChunks += (dev->nChunksPerBlock - c); + } else if (tags.chunkId > 0) { + /* chunkId > 0 so it is a data chunk... */ + unsigned int endpos; + + yaffs_SetChunkBit(dev, blk, c); + bi->pagesInUse++; + + in = yaffs_FindOrCreateObjectByNumber(dev, + tags. + objectId, + YAFFS_OBJECT_TYPE_FILE); + /* PutChunkIntoFile checks for a clash (two data chunks with + * the same chunkId). + */ + + if(!in) + alloc_failed = 1; + + if(in){ + if(!yaffs_PutChunkIntoFile(in, tags.chunkId, chunk,1)) + alloc_failed = 1; + } + + endpos = + (tags.chunkId - 1) * dev->nDataBytesPerChunk + + tags.byteCount; + if (in && + in->variantType == YAFFS_OBJECT_TYPE_FILE + && in->variant.fileVariant.scannedFileSize < + endpos) { + in->variant.fileVariant. + scannedFileSize = endpos; + if (!dev->useHeaderFileSize) { + in->variant.fileVariant. + fileSize = + in->variant.fileVariant. + scannedFileSize; + } + + } + /* T((" %d %d data %d %d\n",blk,c,tags.objectId,tags.chunkId)); */ + } else { + /* chunkId == 0, so it is an ObjectHeader. + * Thus, we read in the object header and make the object + */ + yaffs_SetChunkBit(dev, blk, c); + bi->pagesInUse++; + + result = yaffs_ReadChunkWithTagsFromNAND(dev, chunk, + chunkData, + NULL); + + oh = (yaffs_ObjectHeader *) chunkData; + + in = yaffs_FindObjectByNumber(dev, + tags.objectId); + if (in && in->variantType != oh->type) { + /* This should not happen, but somehow + * Wev'e ended up with an objectId that has been reused but not yet + * deleted, and worse still it has changed type. Delete the old object. + */ + + yaffs_DestroyObject(in); + + in = 0; + } + + in = yaffs_FindOrCreateObjectByNumber(dev, + tags. + objectId, + oh->type); + + if(!in) + alloc_failed = 1; + + if (in && oh->shadowsObject > 0) { + yaffs_HandleShadowedObject(dev, + oh-> + shadowsObject, + 0); + } + + if (in && in->valid) { + /* We have already filled this one. We have a duplicate and need to resolve it. */ + + unsigned existingSerial = in->serial; + unsigned newSerial = tags.serialNumber; + + if (dev->isYaffs2 || + ((existingSerial + 1) & 3) == + newSerial) { + /* Use new one - destroy the exisiting one */ + yaffs_DeleteChunk(dev, + in->chunkId, + 1, __LINE__); + in->valid = 0; + } else { + /* Use existing - destroy this one. */ + yaffs_DeleteChunk(dev, chunk, 1, + __LINE__); + } + } + + if (in && !in->valid && + (tags.objectId == YAFFS_OBJECTID_ROOT || + tags.objectId == YAFFS_OBJECTID_LOSTNFOUND)) { + /* We only load some info, don't fiddle with directory structure */ + in->valid = 1; + in->variantType = oh->type; + + in->yst_mode = oh->yst_mode; +#ifdef CONFIG_YAFFS_WINCE + in->win_atime[0] = oh->win_atime[0]; + in->win_ctime[0] = oh->win_ctime[0]; + in->win_mtime[0] = oh->win_mtime[0]; + in->win_atime[1] = oh->win_atime[1]; + in->win_ctime[1] = oh->win_ctime[1]; + in->win_mtime[1] = oh->win_mtime[1]; +#else + in->yst_uid = oh->yst_uid; + in->yst_gid = oh->yst_gid; + in->yst_atime = oh->yst_atime; + in->yst_mtime = oh->yst_mtime; + in->yst_ctime = oh->yst_ctime; + in->yst_rdev = oh->yst_rdev; +#endif + in->chunkId = chunk; + + } else if (in && !in->valid) { + /* we need to load this info */ + + in->valid = 1; + in->variantType = oh->type; + + in->yst_mode = oh->yst_mode; +#ifdef CONFIG_YAFFS_WINCE + in->win_atime[0] = oh->win_atime[0]; + in->win_ctime[0] = oh->win_ctime[0]; + in->win_mtime[0] = oh->win_mtime[0]; + in->win_atime[1] = oh->win_atime[1]; + in->win_ctime[1] = oh->win_ctime[1]; + in->win_mtime[1] = oh->win_mtime[1]; +#else + in->yst_uid = oh->yst_uid; + in->yst_gid = oh->yst_gid; + in->yst_atime = oh->yst_atime; + in->yst_mtime = oh->yst_mtime; + in->yst_ctime = oh->yst_ctime; + in->yst_rdev = oh->yst_rdev; +#endif + in->chunkId = chunk; + + yaffs_SetObjectName(in, oh->name); + in->dirty = 0; + + /* directory stuff... + * hook up to parent + */ + + parent = + yaffs_FindOrCreateObjectByNumber + (dev, oh->parentObjectId, + YAFFS_OBJECT_TYPE_DIRECTORY); + if (parent->variantType == + YAFFS_OBJECT_TYPE_UNKNOWN) { + /* Set up as a directory */ + parent->variantType = + YAFFS_OBJECT_TYPE_DIRECTORY; + INIT_LIST_HEAD(&parent->variant. + directoryVariant. + children); + } else if (parent->variantType != + YAFFS_OBJECT_TYPE_DIRECTORY) + { + /* Hoosterman, another problem.... + * We're trying to use a non-directory as a directory + */ + + T(YAFFS_TRACE_ERROR, + (TSTR + ("yaffs tragedy: attempting to use non-directory as" + " a directory in scan. Put in lost+found." + TENDSTR))); + parent = dev->lostNFoundDir; + } + + yaffs_AddObjectToDirectory(parent, in); + + if (0 && (parent == dev->deletedDir || + parent == dev->unlinkedDir)) { + in->deleted = 1; /* If it is unlinked at start up then it wants deleting */ + dev->nDeletedFiles++; + } + /* Note re hardlinks. + * Since we might scan a hardlink before its equivalent object is scanned + * we put them all in a list. + * After scanning is complete, we should have all the objects, so we run through this + * list and fix up all the chains. + */ + + switch (in->variantType) { + case YAFFS_OBJECT_TYPE_UNKNOWN: + /* Todo got a problem */ + break; + case YAFFS_OBJECT_TYPE_FILE: + if (dev->isYaffs2 + && oh->isShrink) { + /* Prune back the shrunken chunks */ + yaffs_PruneResizedChunks + (in, oh->fileSize); + /* Mark the block as having a shrinkHeader */ + bi->hasShrinkHeader = 1; + } + + if (dev->useHeaderFileSize) + + in->variant.fileVariant. + fileSize = + oh->fileSize; + + break; + case YAFFS_OBJECT_TYPE_HARDLINK: + in->variant.hardLinkVariant. + equivalentObjectId = + oh->equivalentObjectId; + in->hardLinks.next = + (struct list_head *) + hardList; + hardList = in; + break; + case YAFFS_OBJECT_TYPE_DIRECTORY: + /* Do nothing */ + break; + case YAFFS_OBJECT_TYPE_SPECIAL: + /* Do nothing */ + break; + case YAFFS_OBJECT_TYPE_SYMLINK: + in->variant.symLinkVariant.alias = + yaffs_CloneString(oh->alias); + if(!in->variant.symLinkVariant.alias) + alloc_failed = 1; + break; + } + + if (parent == dev->deletedDir) { + yaffs_DestroyObject(in); + bi->hasShrinkHeader = 1; + } + } + } + } + + if (state == YAFFS_BLOCK_STATE_NEEDS_SCANNING) { + /* If we got this far while scanning, then the block is fully allocated.*/ + state = YAFFS_BLOCK_STATE_FULL; + } + + bi->blockState = state; + + /* Now let's see if it was dirty */ + if (bi->pagesInUse == 0 && + !bi->hasShrinkHeader && + bi->blockState == YAFFS_BLOCK_STATE_FULL) { + yaffs_BlockBecameDirty(dev, blk); + } + + } + + if (blockIndex) { + YFREE(blockIndex); + } + + + /* Ok, we've done all the scanning. + * Fix up the hard link chains. + * We should now have scanned all the objects, now it's time to add these + * hardlinks. + */ + + yaffs_HardlinkFixup(dev,hardList); + + /* Handle the unlinked files. Since they were left in an unlinked state we should + * just delete them. + */ + { + struct list_head *i; + struct list_head *n; + + yaffs_Object *l; + /* Soft delete all the unlinked files */ + list_for_each_safe(i, n, + &dev->unlinkedDir->variant.directoryVariant. + children) { + if (i) { + l = list_entry(i, yaffs_Object, siblings); + yaffs_DestroyObject(l); + } + } + } + + yaffs_ReleaseTempBuffer(dev, chunkData, __LINE__); + + if(alloc_failed){ + return YAFFS_FAIL; + } + + T(YAFFS_TRACE_SCAN, (TSTR("yaffs_Scan ends" TENDSTR))); + + + return YAFFS_OK; +} + +static void yaffs_CheckObjectDetailsLoaded(yaffs_Object *in) +{ + __u8 *chunkData; + yaffs_ObjectHeader *oh; + yaffs_Device *dev = in->myDev; + yaffs_ExtendedTags tags; + int result; + int alloc_failed = 0; + + if(!in) + return; + +#if 0 + T(YAFFS_TRACE_SCAN,(TSTR("details for object %d %s loaded" TENDSTR), + in->objectId, + in->lazyLoaded ? "not yet" : "already")); +#endif + + if(in->lazyLoaded){ + in->lazyLoaded = 0; + chunkData = yaffs_GetTempBuffer(dev, __LINE__); + + result = yaffs_ReadChunkWithTagsFromNAND(dev,in->chunkId,chunkData,&tags); + oh = (yaffs_ObjectHeader *) chunkData; + + in->yst_mode = oh->yst_mode; +#ifdef CONFIG_YAFFS_WINCE + in->win_atime[0] = oh->win_atime[0]; + in->win_ctime[0] = oh->win_ctime[0]; + in->win_mtime[0] = oh->win_mtime[0]; + in->win_atime[1] = oh->win_atime[1]; + in->win_ctime[1] = oh->win_ctime[1]; + in->win_mtime[1] = oh->win_mtime[1]; +#else + in->yst_uid = oh->yst_uid; + in->yst_gid = oh->yst_gid; + in->yst_atime = oh->yst_atime; + in->yst_mtime = oh->yst_mtime; + in->yst_ctime = oh->yst_ctime; + in->yst_rdev = oh->yst_rdev; + +#endif + yaffs_SetObjectName(in, oh->name); + + if(in->variantType == YAFFS_OBJECT_TYPE_SYMLINK){ + in->variant.symLinkVariant.alias = + yaffs_CloneString(oh->alias); + if(!in->variant.symLinkVariant.alias) + alloc_failed = 1; /* Not returned to caller */ + } + + yaffs_ReleaseTempBuffer(dev,chunkData, __LINE__); + } +} + +static int yaffs_ScanBackwards(yaffs_Device * dev) +{ + yaffs_ExtendedTags tags; + int blk; + int blockIterator; + int startIterator; + int endIterator; + int nBlocksToScan = 0; + + int chunk; + int result; + int c; + int deleted; + yaffs_BlockState state; + yaffs_Object *hardList = NULL; + yaffs_BlockInfo *bi; + int sequenceNumber; + yaffs_ObjectHeader *oh; + yaffs_Object *in; + yaffs_Object *parent; + int nBlocks = dev->internalEndBlock - dev->internalStartBlock + 1; + int itsUnlinked; + __u8 *chunkData; + + int fileSize; + int isShrink; + int foundChunksInBlock; + int equivalentObjectId; + int alloc_failed = 0; + + + yaffs_BlockIndex *blockIndex = NULL; + int altBlockIndex = 0; + + if (!dev->isYaffs2) { + T(YAFFS_TRACE_SCAN, + (TSTR("yaffs_ScanBackwards is only for YAFFS2!" TENDSTR))); + return YAFFS_FAIL; + } + + T(YAFFS_TRACE_SCAN, + (TSTR + ("yaffs_ScanBackwards starts intstartblk %d intendblk %d..." + TENDSTR), dev->internalStartBlock, dev->internalEndBlock)); + + + dev->sequenceNumber = YAFFS_LOWEST_SEQUENCE_NUMBER; + + blockIndex = YMALLOC(nBlocks * sizeof(yaffs_BlockIndex)); + + if(!blockIndex) { + blockIndex = YMALLOC_ALT(nBlocks * sizeof(yaffs_BlockIndex)); + altBlockIndex = 1; + } + + if(!blockIndex) { + T(YAFFS_TRACE_SCAN, + (TSTR("yaffs_Scan() could not allocate block index!" TENDSTR))); + return YAFFS_FAIL; + } + + dev->blocksInCheckpoint = 0; + + chunkData = yaffs_GetTempBuffer(dev, __LINE__); + + /* Scan all the blocks to determine their state */ + for (blk = dev->internalStartBlock; blk <= dev->internalEndBlock; blk++) { + bi = yaffs_GetBlockInfo(dev, blk); + yaffs_ClearChunkBits(dev, blk); + bi->pagesInUse = 0; + bi->softDeletions = 0; + + yaffs_QueryInitialBlockState(dev, blk, &state, &sequenceNumber); + + bi->blockState = state; + bi->sequenceNumber = sequenceNumber; + + if(bi->sequenceNumber == YAFFS_SEQUENCE_CHECKPOINT_DATA) + bi->blockState = state = YAFFS_BLOCK_STATE_CHECKPOINT; + + T(YAFFS_TRACE_SCAN_DEBUG, + (TSTR("Block scanning block %d state %d seq %d" TENDSTR), blk, + state, sequenceNumber)); + + + if(state == YAFFS_BLOCK_STATE_CHECKPOINT){ + dev->blocksInCheckpoint++; + + } else if (state == YAFFS_BLOCK_STATE_DEAD) { + T(YAFFS_TRACE_BAD_BLOCKS, + (TSTR("block %d is bad" TENDSTR), blk)); + } else if (state == YAFFS_BLOCK_STATE_EMPTY) { + T(YAFFS_TRACE_SCAN_DEBUG, + (TSTR("Block empty " TENDSTR))); + dev->nErasedBlocks++; + dev->nFreeChunks += dev->nChunksPerBlock; + } else if (state == YAFFS_BLOCK_STATE_NEEDS_SCANNING) { + + /* Determine the highest sequence number */ + if (dev->isYaffs2 && + sequenceNumber >= YAFFS_LOWEST_SEQUENCE_NUMBER && + sequenceNumber < YAFFS_HIGHEST_SEQUENCE_NUMBER) { + + blockIndex[nBlocksToScan].seq = sequenceNumber; + blockIndex[nBlocksToScan].block = blk; + + nBlocksToScan++; + + if (sequenceNumber >= dev->sequenceNumber) { + dev->sequenceNumber = sequenceNumber; + } + } else if (dev->isYaffs2) { + /* TODO: Nasty sequence number! */ + T(YAFFS_TRACE_SCAN, + (TSTR + ("Block scanning block %d has bad sequence number %d" + TENDSTR), blk, sequenceNumber)); + + } + } + } + + T(YAFFS_TRACE_SCAN, + (TSTR("%d blocks to be sorted..." TENDSTR), nBlocksToScan)); + + + + YYIELD(); + + /* Sort the blocks */ +#ifndef CONFIG_YAFFS_USE_OWN_SORT + { + /* Use qsort now. */ + yaffs_qsort(blockIndex, nBlocksToScan, sizeof(yaffs_BlockIndex), ybicmp); + } +#else + { + /* Dungy old bubble sort... */ + + yaffs_BlockIndex temp; + int i; + int j; + + for (i = 0; i < nBlocksToScan; i++) + for (j = i + 1; j < nBlocksToScan; j++) + if (blockIndex[i].seq > blockIndex[j].seq) { + temp = blockIndex[j]; + blockIndex[j] = blockIndex[i]; + blockIndex[i] = temp; + } + } +#endif + + YYIELD(); + + T(YAFFS_TRACE_SCAN, (TSTR("...done" TENDSTR))); + + /* Now scan the blocks looking at the data. */ + startIterator = 0; + endIterator = nBlocksToScan - 1; + T(YAFFS_TRACE_SCAN_DEBUG, + (TSTR("%d blocks to be scanned" TENDSTR), nBlocksToScan)); + + /* For each block.... backwards */ + for (blockIterator = endIterator; !alloc_failed && blockIterator >= startIterator; + blockIterator--) { + /* Cooperative multitasking! This loop can run for so + long that watchdog timers expire. */ + YYIELD(); + + /* get the block to scan in the correct order */ + blk = blockIndex[blockIterator].block; + + bi = yaffs_GetBlockInfo(dev, blk); + + + state = bi->blockState; + + deleted = 0; + + /* For each chunk in each block that needs scanning.... */ + foundChunksInBlock = 0; + for (c = dev->nChunksPerBlock - 1; + !alloc_failed && c >= 0 && + (state == YAFFS_BLOCK_STATE_NEEDS_SCANNING || + state == YAFFS_BLOCK_STATE_ALLOCATING); c--) { + /* Scan backwards... + * Read the tags and decide what to do + */ + + chunk = blk * dev->nChunksPerBlock + c; + + result = yaffs_ReadChunkWithTagsFromNAND(dev, chunk, NULL, + &tags); + + /* Let's have a good look at this chunk... */ + + if (!tags.chunkUsed) { + /* An unassigned chunk in the block. + * If there are used chunks after this one, then + * it is a chunk that was skipped due to failing the erased + * check. Just skip it so that it can be deleted. + * But, more typically, We get here when this is an unallocated + * chunk and his means that either the block is empty or + * this is the one being allocated from + */ + + if(foundChunksInBlock) + { + /* This is a chunk that was skipped due to failing the erased check */ + + } else if (c == 0) { + /* We're looking at the first chunk in the block so the block is unused */ + state = YAFFS_BLOCK_STATE_EMPTY; + dev->nErasedBlocks++; + } else { + if (state == YAFFS_BLOCK_STATE_NEEDS_SCANNING || + state == YAFFS_BLOCK_STATE_ALLOCATING) { + if(dev->sequenceNumber == bi->sequenceNumber) { + /* this is the block being allocated from */ + + T(YAFFS_TRACE_SCAN, + (TSTR + (" Allocating from %d %d" + TENDSTR), blk, c)); + + state = YAFFS_BLOCK_STATE_ALLOCATING; + dev->allocationBlock = blk; + dev->allocationPage = c; + dev->allocationBlockFinder = blk; + } + else { + /* This is a partially written block that is not + * the current allocation block. This block must have + * had a write failure, so set up for retirement. + */ + + bi->needsRetiring = 1; + bi->gcPrioritise = 1; + + T(YAFFS_TRACE_ALWAYS, + (TSTR("Partially written block %d being set for retirement" TENDSTR), + blk)); + } + + } + + } + + dev->nFreeChunks++; + + } else if (tags.chunkId > 0) { + /* chunkId > 0 so it is a data chunk... */ + unsigned int endpos; + __u32 chunkBase = + (tags.chunkId - 1) * dev->nDataBytesPerChunk; + + foundChunksInBlock = 1; + + + yaffs_SetChunkBit(dev, blk, c); + bi->pagesInUse++; + + in = yaffs_FindOrCreateObjectByNumber(dev, + tags. + objectId, + YAFFS_OBJECT_TYPE_FILE); + if(!in){ + /* Out of memory */ + alloc_failed = 1; + } + + if (in && + in->variantType == YAFFS_OBJECT_TYPE_FILE + && chunkBase < + in->variant.fileVariant.shrinkSize) { + /* This has not been invalidated by a resize */ + if(!yaffs_PutChunkIntoFile(in, tags.chunkId, + chunk, -1)){ + alloc_failed = 1; + } + + /* File size is calculated by looking at the data chunks if we have not + * seen an object header yet. Stop this practice once we find an object header. + */ + endpos = + (tags.chunkId - + 1) * dev->nDataBytesPerChunk + + tags.byteCount; + + if (!in->valid && /* have not got an object header yet */ + in->variant.fileVariant. + scannedFileSize < endpos) { + in->variant.fileVariant. + scannedFileSize = endpos; + in->variant.fileVariant. + fileSize = + in->variant.fileVariant. + scannedFileSize; + } + + } else if(in) { + /* This chunk has been invalidated by a resize, so delete */ + yaffs_DeleteChunk(dev, chunk, 1, __LINE__); + + } + } else { + /* chunkId == 0, so it is an ObjectHeader. + * Thus, we read in the object header and make the object + */ + foundChunksInBlock = 1; + + yaffs_SetChunkBit(dev, blk, c); + bi->pagesInUse++; + + oh = NULL; + in = NULL; + + if (tags.extraHeaderInfoAvailable) { + in = yaffs_FindOrCreateObjectByNumber + (dev, tags.objectId, + tags.extraObjectType); + } + + if (!in || +#ifdef CONFIG_YAFFS_DISABLE_LAZY_LOAD + !in->valid || +#endif + tags.extraShadows || + (!in->valid && + (tags.objectId == YAFFS_OBJECTID_ROOT || + tags.objectId == YAFFS_OBJECTID_LOSTNFOUND)) + ) { + + /* If we don't have valid info then we need to read the chunk + * TODO In future we can probably defer reading the chunk and + * living with invalid data until needed. + */ + + result = yaffs_ReadChunkWithTagsFromNAND(dev, + chunk, + chunkData, + NULL); + + oh = (yaffs_ObjectHeader *) chunkData; + + if (!in) + in = yaffs_FindOrCreateObjectByNumber(dev, tags.objectId, oh->type); + + } + + if (!in) { + /* TODO Hoosterman we have a problem! */ + T(YAFFS_TRACE_ERROR, + (TSTR + ("yaffs tragedy: Could not make object for object %d " + "at chunk %d during scan" + TENDSTR), tags.objectId, chunk)); + + } + + if (in->valid) { + /* We have already filled this one. + * We have a duplicate that will be discarded, but + * we first have to suck out resize info if it is a file. + */ + + if ((in->variantType == YAFFS_OBJECT_TYPE_FILE) && + ((oh && + oh-> type == YAFFS_OBJECT_TYPE_FILE)|| + (tags.extraHeaderInfoAvailable && + tags.extraObjectType == YAFFS_OBJECT_TYPE_FILE)) + ) { + __u32 thisSize = + (oh) ? oh->fileSize : tags. + extraFileLength; + __u32 parentObjectId = + (oh) ? oh-> + parentObjectId : tags. + extraParentObjectId; + unsigned isShrink = + (oh) ? oh->isShrink : tags. + extraIsShrinkHeader; + + /* If it is deleted (unlinked at start also means deleted) + * we treat the file size as being zeroed at this point. + */ + if (parentObjectId == + YAFFS_OBJECTID_DELETED + || parentObjectId == + YAFFS_OBJECTID_UNLINKED) { + thisSize = 0; + isShrink = 1; + } + + if (isShrink && + in->variant.fileVariant. + shrinkSize > thisSize) { + in->variant.fileVariant. + shrinkSize = + thisSize; + } + + if (isShrink) { + bi->hasShrinkHeader = 1; + } + + } + /* Use existing - destroy this one. */ + yaffs_DeleteChunk(dev, chunk, 1, __LINE__); + + } + + if (!in->valid && + (tags.objectId == YAFFS_OBJECTID_ROOT || + tags.objectId == + YAFFS_OBJECTID_LOSTNFOUND)) { + /* We only load some info, don't fiddle with directory structure */ + in->valid = 1; + + if(oh) { + in->variantType = oh->type; + + in->yst_mode = oh->yst_mode; +#ifdef CONFIG_YAFFS_WINCE + in->win_atime[0] = oh->win_atime[0]; + in->win_ctime[0] = oh->win_ctime[0]; + in->win_mtime[0] = oh->win_mtime[0]; + in->win_atime[1] = oh->win_atime[1]; + in->win_ctime[1] = oh->win_ctime[1]; + in->win_mtime[1] = oh->win_mtime[1]; +#else + in->yst_uid = oh->yst_uid; + in->yst_gid = oh->yst_gid; + in->yst_atime = oh->yst_atime; + in->yst_mtime = oh->yst_mtime; + in->yst_ctime = oh->yst_ctime; + in->yst_rdev = oh->yst_rdev; + +#endif + } else { + in->variantType = tags.extraObjectType; + in->lazyLoaded = 1; + } + + in->chunkId = chunk; + + } else if (!in->valid) { + /* we need to load this info */ + + in->valid = 1; + in->chunkId = chunk; + + if(oh) { + in->variantType = oh->type; + + in->yst_mode = oh->yst_mode; +#ifdef CONFIG_YAFFS_WINCE + in->win_atime[0] = oh->win_atime[0]; + in->win_ctime[0] = oh->win_ctime[0]; + in->win_mtime[0] = oh->win_mtime[0]; + in->win_atime[1] = oh->win_atime[1]; + in->win_ctime[1] = oh->win_ctime[1]; + in->win_mtime[1] = oh->win_mtime[1]; +#else + in->yst_uid = oh->yst_uid; + in->yst_gid = oh->yst_gid; + in->yst_atime = oh->yst_atime; + in->yst_mtime = oh->yst_mtime; + in->yst_ctime = oh->yst_ctime; + in->yst_rdev = oh->yst_rdev; +#endif + + if (oh->shadowsObject > 0) + yaffs_HandleShadowedObject(dev, + oh-> + shadowsObject, + 1); + + + yaffs_SetObjectName(in, oh->name); + parent = + yaffs_FindOrCreateObjectByNumber + (dev, oh->parentObjectId, + YAFFS_OBJECT_TYPE_DIRECTORY); + + fileSize = oh->fileSize; + isShrink = oh->isShrink; + equivalentObjectId = oh->equivalentObjectId; + + } + else { + in->variantType = tags.extraObjectType; + parent = + yaffs_FindOrCreateObjectByNumber + (dev, tags.extraParentObjectId, + YAFFS_OBJECT_TYPE_DIRECTORY); + fileSize = tags.extraFileLength; + isShrink = tags.extraIsShrinkHeader; + equivalentObjectId = tags.extraEquivalentObjectId; + in->lazyLoaded = 1; + + } + in->dirty = 0; + + /* directory stuff... + * hook up to parent + */ + + if (parent->variantType == + YAFFS_OBJECT_TYPE_UNKNOWN) { + /* Set up as a directory */ + parent->variantType = + YAFFS_OBJECT_TYPE_DIRECTORY; + INIT_LIST_HEAD(&parent->variant. + directoryVariant. + children); + } else if (parent->variantType != + YAFFS_OBJECT_TYPE_DIRECTORY) + { + /* Hoosterman, another problem.... + * We're trying to use a non-directory as a directory + */ + + T(YAFFS_TRACE_ERROR, + (TSTR + ("yaffs tragedy: attempting to use non-directory as" + " a directory in scan. Put in lost+found." + TENDSTR))); + parent = dev->lostNFoundDir; + } + + yaffs_AddObjectToDirectory(parent, in); + + itsUnlinked = (parent == dev->deletedDir) || + (parent == dev->unlinkedDir); + + if (isShrink) { + /* Mark the block as having a shrinkHeader */ + bi->hasShrinkHeader = 1; + } + + /* Note re hardlinks. + * Since we might scan a hardlink before its equivalent object is scanned + * we put them all in a list. + * After scanning is complete, we should have all the objects, so we run + * through this list and fix up all the chains. + */ + + switch (in->variantType) { + case YAFFS_OBJECT_TYPE_UNKNOWN: + /* Todo got a problem */ + break; + case YAFFS_OBJECT_TYPE_FILE: + + if (in->variant.fileVariant. + scannedFileSize < fileSize) { + /* This covers the case where the file size is greater + * than where the data is + * This will happen if the file is resized to be larger + * than its current data extents. + */ + in->variant.fileVariant.fileSize = fileSize; + in->variant.fileVariant.scannedFileSize = + in->variant.fileVariant.fileSize; + } + + if (isShrink && + in->variant.fileVariant.shrinkSize > fileSize) { + in->variant.fileVariant.shrinkSize = fileSize; + } + + break; + case YAFFS_OBJECT_TYPE_HARDLINK: + if(!itsUnlinked) { + in->variant.hardLinkVariant.equivalentObjectId = + equivalentObjectId; + in->hardLinks.next = + (struct list_head *) hardList; + hardList = in; + } + break; + case YAFFS_OBJECT_TYPE_DIRECTORY: + /* Do nothing */ + break; + case YAFFS_OBJECT_TYPE_SPECIAL: + /* Do nothing */ + break; + case YAFFS_OBJECT_TYPE_SYMLINK: + if(oh){ + in->variant.symLinkVariant.alias = + yaffs_CloneString(oh-> + alias); + if(!in->variant.symLinkVariant.alias) + alloc_failed = 1; + } + break; + } + + } + + } + + } /* End of scanning for each chunk */ + + if (state == YAFFS_BLOCK_STATE_NEEDS_SCANNING) { + /* If we got this far while scanning, then the block is fully allocated. */ + state = YAFFS_BLOCK_STATE_FULL; + } + + bi->blockState = state; + + /* Now let's see if it was dirty */ + if (bi->pagesInUse == 0 && + !bi->hasShrinkHeader && + bi->blockState == YAFFS_BLOCK_STATE_FULL) { + yaffs_BlockBecameDirty(dev, blk); + } + + } + + if (altBlockIndex) + YFREE_ALT(blockIndex); + else + YFREE(blockIndex); + + /* Ok, we've done all the scanning. + * Fix up the hard link chains. + * We should now have scanned all the objects, now it's time to add these + * hardlinks. + */ + yaffs_HardlinkFixup(dev,hardList); + + + /* + * Sort out state of unlinked and deleted objects. + */ + { + struct list_head *i; + struct list_head *n; + + yaffs_Object *l; + + /* Soft delete all the unlinked files */ + list_for_each_safe(i, n, + &dev->unlinkedDir->variant.directoryVariant. + children) { + if (i) { + l = list_entry(i, yaffs_Object, siblings); + yaffs_DestroyObject(l); + } + } + + /* Soft delete all the deletedDir files */ + list_for_each_safe(i, n, + &dev->deletedDir->variant.directoryVariant. + children) { + if (i) { + l = list_entry(i, yaffs_Object, siblings); + yaffs_DestroyObject(l); + + } + } + } + + yaffs_ReleaseTempBuffer(dev, chunkData, __LINE__); + + if(alloc_failed){ + return YAFFS_FAIL; + } + + T(YAFFS_TRACE_SCAN, (TSTR("yaffs_ScanBackwards ends" TENDSTR))); + + return YAFFS_OK; +} + +/*------------------------------ Directory Functions ----------------------------- */ + +static void yaffs_RemoveObjectFromDirectory(yaffs_Object * obj) +{ + yaffs_Device *dev = obj->myDev; + + if(dev && dev->removeObjectCallback) + dev->removeObjectCallback(obj); + + list_del_init(&obj->siblings); + obj->parent = NULL; +} + + +static void yaffs_AddObjectToDirectory(yaffs_Object * directory, + yaffs_Object * obj) +{ + + if (!directory) { + T(YAFFS_TRACE_ALWAYS, + (TSTR + ("tragedy: Trying to add an object to a null pointer directory" + TENDSTR))); + YBUG(); + } + if (directory->variantType != YAFFS_OBJECT_TYPE_DIRECTORY) { + T(YAFFS_TRACE_ALWAYS, + (TSTR + ("tragedy: Trying to add an object to a non-directory" + TENDSTR))); + YBUG(); + } + + if (obj->siblings.prev == NULL) { + /* Not initialised */ + INIT_LIST_HEAD(&obj->siblings); + + } else if (!list_empty(&obj->siblings)) { + /* If it is holed up somewhere else, un hook it */ + yaffs_RemoveObjectFromDirectory(obj); + } + /* Now add it */ + list_add(&obj->siblings, &directory->variant.directoryVariant.children); + obj->parent = directory; + + if (directory == obj->myDev->unlinkedDir + || directory == obj->myDev->deletedDir) { + obj->unlinked = 1; + obj->myDev->nUnlinkedFiles++; + obj->renameAllowed = 0; + } +} + +yaffs_Object *yaffs_FindObjectByName(yaffs_Object * directory, + const YCHAR * name) +{ + int sum; + + struct list_head *i; + YCHAR buffer[YAFFS_MAX_NAME_LENGTH + 1]; + + yaffs_Object *l; + + if (!name) { + return NULL; + } + + if (!directory) { + T(YAFFS_TRACE_ALWAYS, + (TSTR + ("tragedy: yaffs_FindObjectByName: null pointer directory" + TENDSTR))); + YBUG(); + } + if (directory->variantType != YAFFS_OBJECT_TYPE_DIRECTORY) { + T(YAFFS_TRACE_ALWAYS, + (TSTR + ("tragedy: yaffs_FindObjectByName: non-directory" TENDSTR))); + YBUG(); + } + + sum = yaffs_CalcNameSum(name); + + list_for_each(i, &directory->variant.directoryVariant.children) { + if (i) { + l = list_entry(i, yaffs_Object, siblings); + + yaffs_CheckObjectDetailsLoaded(l); + + /* Special case for lost-n-found */ + if (l->objectId == YAFFS_OBJECTID_LOSTNFOUND) { + if (yaffs_strcmp(name, YAFFS_LOSTNFOUND_NAME) == 0) { + return l; + } + } else if (yaffs_SumCompare(l->sum, sum) || l->chunkId <= 0) + { + /* LostnFound cunk called Objxxx + * Do a real check + */ + yaffs_GetObjectName(l, buffer, + YAFFS_MAX_NAME_LENGTH); + if (yaffs_strncmp(name, buffer,YAFFS_MAX_NAME_LENGTH) == 0) { + return l; + } + + } + } + } + + return NULL; +} + + +#if 0 +int yaffs_ApplyToDirectoryChildren(yaffs_Object * theDir, + int (*fn) (yaffs_Object *)) +{ + struct list_head *i; + yaffs_Object *l; + + if (!theDir) { + T(YAFFS_TRACE_ALWAYS, + (TSTR + ("tragedy: yaffs_FindObjectByName: null pointer directory" + TENDSTR))); + YBUG(); + } + if (theDir->variantType != YAFFS_OBJECT_TYPE_DIRECTORY) { + T(YAFFS_TRACE_ALWAYS, + (TSTR + ("tragedy: yaffs_FindObjectByName: non-directory" TENDSTR))); + YBUG(); + } + + list_for_each(i, &theDir->variant.directoryVariant.children) { + if (i) { + l = list_entry(i, yaffs_Object, siblings); + if (l && !fn(l)) { + return YAFFS_FAIL; + } + } + } + + return YAFFS_OK; + +} +#endif + +/* GetEquivalentObject dereferences any hard links to get to the + * actual object. + */ + +yaffs_Object *yaffs_GetEquivalentObject(yaffs_Object * obj) +{ + if (obj && obj->variantType == YAFFS_OBJECT_TYPE_HARDLINK) { + /* We want the object id of the equivalent object, not this one */ + obj = obj->variant.hardLinkVariant.equivalentObject; + yaffs_CheckObjectDetailsLoaded(obj); + } + return obj; + +} + +int yaffs_GetObjectName(yaffs_Object * obj, YCHAR * name, int buffSize) +{ + memset(name, 0, buffSize * sizeof(YCHAR)); + + yaffs_CheckObjectDetailsLoaded(obj); + + if (obj->objectId == YAFFS_OBJECTID_LOSTNFOUND) { + yaffs_strncpy(name, YAFFS_LOSTNFOUND_NAME, buffSize - 1); + } else if (obj->chunkId <= 0) { + YCHAR locName[20]; + /* make up a name */ + yaffs_sprintf(locName, _Y("%s%d"), YAFFS_LOSTNFOUND_PREFIX, + obj->objectId); + yaffs_strncpy(name, locName, buffSize - 1); + + } +#ifdef CONFIG_YAFFS_SHORT_NAMES_IN_RAM + else if (obj->shortName[0]) { + yaffs_strcpy(name, obj->shortName); + } +#endif + else { + int result; + __u8 *buffer = yaffs_GetTempBuffer(obj->myDev, __LINE__); + + yaffs_ObjectHeader *oh = (yaffs_ObjectHeader *) buffer; + + memset(buffer, 0, obj->myDev->nDataBytesPerChunk); + + if (obj->chunkId >= 0) { + result = yaffs_ReadChunkWithTagsFromNAND(obj->myDev, + obj->chunkId, buffer, + NULL); + } + yaffs_strncpy(name, oh->name, buffSize - 1); + + yaffs_ReleaseTempBuffer(obj->myDev, buffer, __LINE__); + } + + return yaffs_strlen(name); +} + +int yaffs_GetObjectFileLength(yaffs_Object * obj) +{ + + /* Dereference any hard linking */ + obj = yaffs_GetEquivalentObject(obj); + + if (obj->variantType == YAFFS_OBJECT_TYPE_FILE) { + return obj->variant.fileVariant.fileSize; + } + if (obj->variantType == YAFFS_OBJECT_TYPE_SYMLINK) { + return yaffs_strlen(obj->variant.symLinkVariant.alias); + } else { + /* Only a directory should drop through to here */ + return obj->myDev->nDataBytesPerChunk; + } +} + +int yaffs_GetObjectLinkCount(yaffs_Object * obj) +{ + int count = 0; + struct list_head *i; + + if (!obj->unlinked) { + count++; /* the object itself */ + } + list_for_each(i, &obj->hardLinks) { + count++; /* add the hard links; */ + } + return count; + +} + +int yaffs_GetObjectInode(yaffs_Object * obj) +{ + obj = yaffs_GetEquivalentObject(obj); + + return obj->objectId; +} + +unsigned yaffs_GetObjectType(yaffs_Object * obj) +{ + obj = yaffs_GetEquivalentObject(obj); + + switch (obj->variantType) { + case YAFFS_OBJECT_TYPE_FILE: + return DT_REG; + break; + case YAFFS_OBJECT_TYPE_DIRECTORY: + return DT_DIR; + break; + case YAFFS_OBJECT_TYPE_SYMLINK: + return DT_LNK; + break; + case YAFFS_OBJECT_TYPE_HARDLINK: + return DT_REG; + break; + case YAFFS_OBJECT_TYPE_SPECIAL: + if (S_ISFIFO(obj->yst_mode)) + return DT_FIFO; + if (S_ISCHR(obj->yst_mode)) + return DT_CHR; + if (S_ISBLK(obj->yst_mode)) + return DT_BLK; + if (S_ISSOCK(obj->yst_mode)) + return DT_SOCK; + default: + return DT_REG; + break; + } +} + +YCHAR *yaffs_GetSymlinkAlias(yaffs_Object * obj) +{ + obj = yaffs_GetEquivalentObject(obj); + if (obj->variantType == YAFFS_OBJECT_TYPE_SYMLINK) { + return yaffs_CloneString(obj->variant.symLinkVariant.alias); + } else { + return yaffs_CloneString(_Y("")); + } +} + +#ifndef CONFIG_YAFFS_WINCE + +int yaffs_SetAttributes(yaffs_Object * obj, struct iattr *attr) +{ + unsigned int valid = attr->ia_valid; + + if (valid & ATTR_MODE) + obj->yst_mode = attr->ia_mode; + if (valid & ATTR_UID) + obj->yst_uid = attr->ia_uid; + if (valid & ATTR_GID) + obj->yst_gid = attr->ia_gid; + + if (valid & ATTR_ATIME) + obj->yst_atime = Y_TIME_CONVERT(attr->ia_atime); + if (valid & ATTR_CTIME) + obj->yst_ctime = Y_TIME_CONVERT(attr->ia_ctime); + if (valid & ATTR_MTIME) + obj->yst_mtime = Y_TIME_CONVERT(attr->ia_mtime); + + if (valid & ATTR_SIZE) + yaffs_ResizeFile(obj, attr->ia_size); + + yaffs_UpdateObjectHeader(obj, NULL, 1, 0, 0); + + return YAFFS_OK; + +} +int yaffs_GetAttributes(yaffs_Object * obj, struct iattr *attr) +{ + unsigned int valid = 0; + + attr->ia_mode = obj->yst_mode; + valid |= ATTR_MODE; + attr->ia_uid = obj->yst_uid; + valid |= ATTR_UID; + attr->ia_gid = obj->yst_gid; + valid |= ATTR_GID; + + Y_TIME_CONVERT(attr->ia_atime) = obj->yst_atime; + valid |= ATTR_ATIME; + Y_TIME_CONVERT(attr->ia_ctime) = obj->yst_ctime; + valid |= ATTR_CTIME; + Y_TIME_CONVERT(attr->ia_mtime) = obj->yst_mtime; + valid |= ATTR_MTIME; + + attr->ia_size = yaffs_GetFileSize(obj); + valid |= ATTR_SIZE; + + attr->ia_valid = valid; + + return YAFFS_OK; + +} + +#endif + +#if 0 +int yaffs_DumpObject(yaffs_Object * obj) +{ + YCHAR name[257]; + + yaffs_GetObjectName(obj, name, 256); + + T(YAFFS_TRACE_ALWAYS, + (TSTR + ("Object %d, inode %d \"%s\"\n dirty %d valid %d serial %d sum %d" + " chunk %d type %d size %d\n" + TENDSTR), obj->objectId, yaffs_GetObjectInode(obj), name, + obj->dirty, obj->valid, obj->serial, obj->sum, obj->chunkId, + yaffs_GetObjectType(obj), yaffs_GetObjectFileLength(obj))); + + return YAFFS_OK; +} +#endif + +/*---------------------------- Initialisation code -------------------------------------- */ + +static int yaffs_CheckDevFunctions(const yaffs_Device * dev) +{ + + /* Common functions, gotta have */ + if (!dev->eraseBlockInNAND || !dev->initialiseNAND) + return 0; + +#ifdef CONFIG_YAFFS_YAFFS2 + + /* Can use the "with tags" style interface for yaffs1 or yaffs2 */ + if (dev->writeChunkWithTagsToNAND && + dev->readChunkWithTagsFromNAND && + !dev->writeChunkToNAND && + !dev->readChunkFromNAND && + dev->markNANDBlockBad && dev->queryNANDBlock) + return 1; +#endif + + /* Can use the "spare" style interface for yaffs1 */ + if (!dev->isYaffs2 && + !dev->writeChunkWithTagsToNAND && + !dev->readChunkWithTagsFromNAND && + dev->writeChunkToNAND && + dev->readChunkFromNAND && + !dev->markNANDBlockBad && !dev->queryNANDBlock) + return 1; + + return 0; /* bad */ +} + + +static int yaffs_CreateInitialDirectories(yaffs_Device *dev) +{ + /* Initialise the unlinked, deleted, root and lost and found directories */ + + dev->lostNFoundDir = dev->rootDir = NULL; + dev->unlinkedDir = dev->deletedDir = NULL; + + dev->unlinkedDir = + yaffs_CreateFakeDirectory(dev, YAFFS_OBJECTID_UNLINKED, S_IFDIR); + + dev->deletedDir = + yaffs_CreateFakeDirectory(dev, YAFFS_OBJECTID_DELETED, S_IFDIR); + + dev->rootDir = + yaffs_CreateFakeDirectory(dev, YAFFS_OBJECTID_ROOT, + YAFFS_ROOT_MODE | S_IFDIR); + dev->lostNFoundDir = + yaffs_CreateFakeDirectory(dev, YAFFS_OBJECTID_LOSTNFOUND, + YAFFS_LOSTNFOUND_MODE | S_IFDIR); + + if(dev->lostNFoundDir && dev->rootDir && dev->unlinkedDir && dev->deletedDir){ + yaffs_AddObjectToDirectory(dev->rootDir, dev->lostNFoundDir); + return YAFFS_OK; + } + + return YAFFS_FAIL; +} + +int yaffs_GutsInitialise(yaffs_Device * dev) +{ + int init_failed = 0; + unsigned x; + int bits; + + T(YAFFS_TRACE_TRACING, (TSTR("yaffs: yaffs_GutsInitialise()" TENDSTR))); + + /* Check stuff that must be set */ + + if (!dev) { + T(YAFFS_TRACE_ALWAYS, (TSTR("yaffs: Need a device" TENDSTR))); + return YAFFS_FAIL; + } + + dev->internalStartBlock = dev->startBlock; + dev->internalEndBlock = dev->endBlock; + dev->blockOffset = 0; + dev->chunkOffset = 0; + dev->nFreeChunks = 0; + + if (dev->startBlock == 0) { + dev->internalStartBlock = dev->startBlock + 1; + dev->internalEndBlock = dev->endBlock + 1; + dev->blockOffset = 1; + dev->chunkOffset = dev->nChunksPerBlock; + } + + /* Check geometry parameters. */ + + if ((dev->isYaffs2 && dev->nDataBytesPerChunk < 1024) || + (!dev->isYaffs2 && dev->nDataBytesPerChunk != 512) || + dev->nChunksPerBlock < 2 || + dev->nReservedBlocks < 2 || + dev->internalStartBlock <= 0 || + dev->internalEndBlock <= 0 || + dev->internalEndBlock <= (dev->internalStartBlock + dev->nReservedBlocks + 2) // otherwise it is too small + ) { + T(YAFFS_TRACE_ALWAYS, + (TSTR + ("yaffs: NAND geometry problems: chunk size %d, type is yaffs%s " + TENDSTR), dev->nDataBytesPerChunk, dev->isYaffs2 ? "2" : "")); + return YAFFS_FAIL; + } + + if (yaffs_InitialiseNAND(dev) != YAFFS_OK) { + T(YAFFS_TRACE_ALWAYS, + (TSTR("yaffs: InitialiseNAND failed" TENDSTR))); + return YAFFS_FAIL; + } + + /* Got the right mix of functions? */ + if (!yaffs_CheckDevFunctions(dev)) { + /* Function missing */ + T(YAFFS_TRACE_ALWAYS, + (TSTR + ("yaffs: device function(s) missing or wrong\n" TENDSTR))); + + return YAFFS_FAIL; + } + + /* This is really a compilation check. */ + if (!yaffs_CheckStructures()) { + T(YAFFS_TRACE_ALWAYS, + (TSTR("yaffs_CheckStructures failed\n" TENDSTR))); + return YAFFS_FAIL; + } + + if (dev->isMounted) { + T(YAFFS_TRACE_ALWAYS, + (TSTR("yaffs: device already mounted\n" TENDSTR))); + return YAFFS_FAIL; + } + + /* Finished with most checks. One or two more checks happen later on too. */ + + dev->isMounted = 1; + + + + /* OK now calculate a few things for the device */ + + /* + * Calculate all the chunk size manipulation numbers: + */ + /* Start off assuming it is a power of 2 */ + dev->chunkShift = ShiftDiv(dev->nDataBytesPerChunk); + dev->chunkMask = (1<chunkShift) - 1; + + if(dev->nDataBytesPerChunk == (dev->chunkMask + 1)){ + /* Yes it is a power of 2, disable crumbs */ + dev->crumbMask = 0; + dev->crumbShift = 0; + dev->crumbsPerChunk = 0; + } else { + /* Not a power of 2, use crumbs instead */ + dev->crumbShift = ShiftDiv(sizeof(yaffs_PackedTags2TagsPart)); + dev->crumbMask = (1<crumbShift)-1; + dev->crumbsPerChunk = dev->nDataBytesPerChunk/(1 << dev->crumbShift); + dev->chunkShift = 0; + dev->chunkMask = 0; + } + + + /* + * Calculate chunkGroupBits. + * We need to find the next power of 2 > than internalEndBlock + */ + + x = dev->nChunksPerBlock * (dev->internalEndBlock + 1); + + bits = ShiftsGE(x); + + /* Set up tnode width if wide tnodes are enabled. */ + if(!dev->wideTnodesDisabled){ + /* bits must be even so that we end up with 32-bit words */ + if(bits & 1) + bits++; + if(bits < 16) + dev->tnodeWidth = 16; + else + dev->tnodeWidth = bits; + } + else + dev->tnodeWidth = 16; + + dev->tnodeMask = (1<tnodeWidth)-1; + + /* Level0 Tnodes are 16 bits or wider (if wide tnodes are enabled), + * so if the bitwidth of the + * chunk range we're using is greater than 16 we need + * to figure out chunk shift and chunkGroupSize + */ + + if (bits <= dev->tnodeWidth) + dev->chunkGroupBits = 0; + else + dev->chunkGroupBits = bits - dev->tnodeWidth; + + + dev->chunkGroupSize = 1 << dev->chunkGroupBits; + + if (dev->nChunksPerBlock < dev->chunkGroupSize) { + /* We have a problem because the soft delete won't work if + * the chunk group size > chunks per block. + * This can be remedied by using larger "virtual blocks". + */ + T(YAFFS_TRACE_ALWAYS, + (TSTR("yaffs: chunk group too large\n" TENDSTR))); + + return YAFFS_FAIL; + } + + /* OK, we've finished verifying the device, lets continue with initialisation */ + + /* More device initialisation */ + dev->garbageCollections = 0; + dev->passiveGarbageCollections = 0; + dev->currentDirtyChecker = 0; + dev->bufferedBlock = -1; + dev->doingBufferedBlockRewrite = 0; + dev->nDeletedFiles = 0; + dev->nBackgroundDeletions = 0; + dev->nUnlinkedFiles = 0; + dev->eccFixed = 0; + dev->eccUnfixed = 0; + dev->tagsEccFixed = 0; + dev->tagsEccUnfixed = 0; + dev->nErasureFailures = 0; + dev->nErasedBlocks = 0; + dev->isDoingGC = 0; + dev->hasPendingPrioritisedGCs = 1; /* Assume the worst for now, will get fixed on first GC */ + + /* Initialise temporary buffers and caches. */ + if(!yaffs_InitialiseTempBuffers(dev)) + init_failed = 1; + + dev->srCache = NULL; + dev->gcCleanupList = NULL; + + + if (!init_failed && + dev->nShortOpCaches > 0) { + int i; + __u8 *buf; + int srCacheBytes = dev->nShortOpCaches * sizeof(yaffs_ChunkCache); + + if (dev->nShortOpCaches > YAFFS_MAX_SHORT_OP_CACHES) { + dev->nShortOpCaches = YAFFS_MAX_SHORT_OP_CACHES; + } + + buf = dev->srCache = YMALLOC(srCacheBytes); + + if(dev->srCache) + memset(dev->srCache,0,srCacheBytes); + + for (i = 0; i < dev->nShortOpCaches && buf; i++) { + dev->srCache[i].object = NULL; + dev->srCache[i].lastUse = 0; + dev->srCache[i].dirty = 0; + dev->srCache[i].data = buf = YMALLOC_DMA(dev->nDataBytesPerChunk); + } + if(!buf) + init_failed = 1; + + dev->srLastUse = 0; + } + + dev->cacheHits = 0; + + if(!init_failed){ + dev->gcCleanupList = YMALLOC(dev->nChunksPerBlock * sizeof(__u32)); + if(!dev->gcCleanupList) + init_failed = 1; + } + + if (dev->isYaffs2) { + dev->useHeaderFileSize = 1; + } + if(!init_failed && !yaffs_InitialiseBlocks(dev)) + init_failed = 1; + + yaffs_InitialiseTnodes(dev); + yaffs_InitialiseObjects(dev); + + if(!init_failed && !yaffs_CreateInitialDirectories(dev)) + init_failed = 1; + + + if(!init_failed){ + /* Now scan the flash. */ + if (dev->isYaffs2) { + if(yaffs_CheckpointRestore(dev)) { + T(YAFFS_TRACE_ALWAYS, + (TSTR("yaffs: restored from checkpoint" TENDSTR))); + } else { + + /* Clean up the mess caused by an aborted checkpoint load + * and scan backwards. + */ + yaffs_DeinitialiseBlocks(dev); + yaffs_DeinitialiseTnodes(dev); + yaffs_DeinitialiseObjects(dev); + + + dev->nErasedBlocks = 0; + dev->nFreeChunks = 0; + dev->allocationBlock = -1; + dev->allocationPage = -1; + dev->nDeletedFiles = 0; + dev->nUnlinkedFiles = 0; + dev->nBackgroundDeletions = 0; + dev->oldestDirtySequence = 0; + + if(!init_failed && !yaffs_InitialiseBlocks(dev)) + init_failed = 1; + + yaffs_InitialiseTnodes(dev); + yaffs_InitialiseObjects(dev); + + if(!init_failed && !yaffs_CreateInitialDirectories(dev)) + init_failed = 1; + + if(!init_failed && !yaffs_ScanBackwards(dev)) + init_failed = 1; + } + }else + if(!yaffs_Scan(dev)) + init_failed = 1; + } + + if(init_failed){ + /* Clean up the mess */ + T(YAFFS_TRACE_TRACING, + (TSTR("yaffs: yaffs_GutsInitialise() aborted.\n" TENDSTR))); + + yaffs_Deinitialise(dev); + return YAFFS_FAIL; + } + + /* Zero out stats */ + dev->nPageReads = 0; + dev->nPageWrites = 0; + dev->nBlockErasures = 0; + dev->nGCCopies = 0; + dev->nRetriedWrites = 0; + + dev->nRetiredBlocks = 0; + + yaffs_VerifyFreeChunks(dev); + yaffs_VerifyBlocks(dev); + + + T(YAFFS_TRACE_TRACING, + (TSTR("yaffs: yaffs_GutsInitialise() done.\n" TENDSTR))); + return YAFFS_OK; + +} + +void yaffs_Deinitialise(yaffs_Device * dev) +{ + if (dev->isMounted) { + int i; + + yaffs_DeinitialiseBlocks(dev); + yaffs_DeinitialiseTnodes(dev); + yaffs_DeinitialiseObjects(dev); + if (dev->nShortOpCaches > 0 && + dev->srCache) { + + for (i = 0; i < dev->nShortOpCaches; i++) { + if(dev->srCache[i].data) + YFREE(dev->srCache[i].data); + dev->srCache[i].data = NULL; + } + + YFREE(dev->srCache); + dev->srCache = NULL; + } + + YFREE(dev->gcCleanupList); + + for (i = 0; i < YAFFS_N_TEMP_BUFFERS; i++) { + YFREE(dev->tempBuffer[i].buffer); + } + + dev->isMounted = 0; + } + +} + +static int yaffs_CountFreeChunks(yaffs_Device * dev) +{ + int nFree; + int b; + + yaffs_BlockInfo *blk; + + for (nFree = 0, b = dev->internalStartBlock; b <= dev->internalEndBlock; + b++) { + blk = yaffs_GetBlockInfo(dev, b); + + switch (blk->blockState) { + case YAFFS_BLOCK_STATE_EMPTY: + case YAFFS_BLOCK_STATE_ALLOCATING: + case YAFFS_BLOCK_STATE_COLLECTING: + case YAFFS_BLOCK_STATE_FULL: + nFree += + (dev->nChunksPerBlock - blk->pagesInUse + + blk->softDeletions); + break; + default: + break; + } + + } + + return nFree; +} + +int yaffs_GetNumberOfFreeChunks(yaffs_Device * dev) +{ + /* This is what we report to the outside world */ + + int nFree; + int nDirtyCacheChunks; + int blocksForCheckpoint; + +#if 1 + nFree = dev->nFreeChunks; +#else + nFree = yaffs_CountFreeChunks(dev); +#endif + + nFree += dev->nDeletedFiles; + + /* Now count the number of dirty chunks in the cache and subtract those */ + + { + int i; + for (nDirtyCacheChunks = 0, i = 0; i < dev->nShortOpCaches; i++) { + if (dev->srCache[i].dirty) + nDirtyCacheChunks++; + } + } + + nFree -= nDirtyCacheChunks; + + nFree -= ((dev->nReservedBlocks + 1) * dev->nChunksPerBlock); + + /* Now we figure out how much to reserve for the checkpoint and report that... */ + blocksForCheckpoint = yaffs_CalcCheckpointBlocksRequired(dev) - dev->blocksInCheckpoint; + if(blocksForCheckpoint < 0) + blocksForCheckpoint = 0; + + nFree -= (blocksForCheckpoint * dev->nChunksPerBlock); + + if (nFree < 0) + nFree = 0; + + return nFree; + +} + +static int yaffs_freeVerificationFailures; + +static void yaffs_VerifyFreeChunks(yaffs_Device * dev) +{ + int counted; + int difference; + + if(yaffs_SkipVerification(dev)) + return; + + counted = yaffs_CountFreeChunks(dev); + + difference = dev->nFreeChunks - counted; + + if (difference) { + T(YAFFS_TRACE_ALWAYS, + (TSTR("Freechunks verification failure %d %d %d" TENDSTR), + dev->nFreeChunks, counted, difference)); + yaffs_freeVerificationFailures++; + } +} + +/*---------------------------------------- YAFFS test code ----------------------*/ + +#define yaffs_CheckStruct(structure,syze, name) \ + if(sizeof(structure) != syze) \ + { \ + T(YAFFS_TRACE_ALWAYS,(TSTR("%s should be %d but is %d\n" TENDSTR),\ + name,syze,sizeof(structure))); \ + return YAFFS_FAIL; \ + } + +static int yaffs_CheckStructures(void) +{ +/* yaffs_CheckStruct(yaffs_Tags,8,"yaffs_Tags") */ +/* yaffs_CheckStruct(yaffs_TagsUnion,8,"yaffs_TagsUnion") */ +/* yaffs_CheckStruct(yaffs_Spare,16,"yaffs_Spare") */ +#ifndef CONFIG_YAFFS_TNODE_LIST_DEBUG + yaffs_CheckStruct(yaffs_Tnode, 2 * YAFFS_NTNODES_LEVEL0, "yaffs_Tnode") +#endif + yaffs_CheckStruct(yaffs_ObjectHeader, 512, "yaffs_ObjectHeader") + + return YAFFS_OK; +} --- /dev/null +++ linux-2.6.20/fs/yaffs2/yaffs_guts.h @@ -0,0 +1,904 @@ +/* + * YAFFS: Yet another Flash File System . A NAND-flash specific file system. + * + * Copyright (C) 2002-2007 Aleph One Ltd. + * for Toby Churchill Ltd and Brightstar Engineering + * + * Created by Charles Manning + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 2.1 as + * published by the Free Software Foundation. + * + * Note: Only YAFFS headers are LGPL, YAFFS C code is covered by GPL. + */ + +#ifndef __YAFFS_GUTS_H__ +#define __YAFFS_GUTS_H__ + +#include "devextras.h" +#include "yportenv.h" + +#define YAFFS_OK 1 +#define YAFFS_FAIL 0 + +/* Give us a Y=0x59, + * Give us an A=0x41, + * Give us an FF=0xFF + * Give us an S=0x53 + * And what have we got... + */ +#define YAFFS_MAGIC 0x5941FF53 + +#define YAFFS_NTNODES_LEVEL0 16 +#define YAFFS_TNODES_LEVEL0_BITS 4 +#define YAFFS_TNODES_LEVEL0_MASK 0xf + +#define YAFFS_NTNODES_INTERNAL (YAFFS_NTNODES_LEVEL0 / 2) +#define YAFFS_TNODES_INTERNAL_BITS (YAFFS_TNODES_LEVEL0_BITS - 1) +#define YAFFS_TNODES_INTERNAL_MASK 0x7 +#define YAFFS_TNODES_MAX_LEVEL 6 + +#ifndef CONFIG_YAFFS_NO_YAFFS1 +#define YAFFS_BYTES_PER_SPARE 16 +#define YAFFS_BYTES_PER_CHUNK 512 +#define YAFFS_CHUNK_SIZE_SHIFT 9 +#define YAFFS_CHUNKS_PER_BLOCK 32 +#define YAFFS_BYTES_PER_BLOCK (YAFFS_CHUNKS_PER_BLOCK*YAFFS_BYTES_PER_CHUNK) +#endif + +#define YAFFS_MIN_YAFFS2_CHUNK_SIZE 1024 +#define YAFFS_MIN_YAFFS2_SPARE_SIZE 32 + +#define YAFFS_MAX_CHUNK_ID 0x000FFFFF + +#define YAFFS_UNUSED_OBJECT_ID 0x0003FFFF + +#define YAFFS_ALLOCATION_NOBJECTS 100 +#define YAFFS_ALLOCATION_NTNODES 100 +#define YAFFS_ALLOCATION_NLINKS 100 + +#define YAFFS_NOBJECT_BUCKETS 256 + + +#define YAFFS_OBJECT_SPACE 0x40000 + +#define YAFFS_CHECKPOINT_VERSION 3 + +#ifdef CONFIG_YAFFS_UNICODE +#define YAFFS_MAX_NAME_LENGTH 127 +#define YAFFS_MAX_ALIAS_LENGTH 79 +#else +#define YAFFS_MAX_NAME_LENGTH 255 +#define YAFFS_MAX_ALIAS_LENGTH 159 +#endif + +#define YAFFS_SHORT_NAME_LENGTH 15 + +/* Some special object ids for pseudo objects */ +#define YAFFS_OBJECTID_ROOT 1 +#define YAFFS_OBJECTID_LOSTNFOUND 2 +#define YAFFS_OBJECTID_UNLINKED 3 +#define YAFFS_OBJECTID_DELETED 4 + +/* Sseudo object ids for checkpointing */ +#define YAFFS_OBJECTID_SB_HEADER 0x10 +#define YAFFS_OBJECTID_CHECKPOINT_DATA 0x20 +#define YAFFS_SEQUENCE_CHECKPOINT_DATA 0x21 + +/* */ + +#define YAFFS_MAX_SHORT_OP_CACHES 20 + +#define YAFFS_N_TEMP_BUFFERS 4 + +/* We limit the number attempts at sucessfully saving a chunk of data. + * Small-page devices have 32 pages per block; large-page devices have 64. + * Default to something in the order of 5 to 10 blocks worth of chunks. + */ +#define YAFFS_WR_ATTEMPTS (5*64) + +/* Sequence numbers are used in YAFFS2 to determine block allocation order. + * The range is limited slightly to help distinguish bad numbers from good. + * This also allows us to perhaps in the future use special numbers for + * special purposes. + * EFFFFF00 allows the allocation of 8 blocks per second (~1Mbytes) for 15 years, + * and is a larger number than the lifetime of a 2GB device. + */ +#define YAFFS_LOWEST_SEQUENCE_NUMBER 0x00001000 +#define YAFFS_HIGHEST_SEQUENCE_NUMBER 0xEFFFFF00 + +/* ChunkCache is used for short read/write operations.*/ +typedef struct { + struct yaffs_ObjectStruct *object; + int chunkId; + int lastUse; + int dirty; + int nBytes; /* Only valid if the cache is dirty */ + int locked; /* Can't push out or flush while locked. */ +#ifdef CONFIG_YAFFS_YAFFS2 + __u8 *data; +#else + __u8 data[YAFFS_BYTES_PER_CHUNK]; +#endif +} yaffs_ChunkCache; + + + +/* Tags structures in RAM + * NB This uses bitfield. Bitfields should not straddle a u32 boundary otherwise + * the structure size will get blown out. + */ + +#ifndef CONFIG_YAFFS_NO_YAFFS1 +typedef struct { + unsigned chunkId:20; + unsigned serialNumber:2; + unsigned byteCount:10; + unsigned objectId:18; + unsigned ecc:12; + unsigned unusedStuff:2; + +} yaffs_Tags; + +typedef union { + yaffs_Tags asTags; + __u8 asBytes[8]; +} yaffs_TagsUnion; + +#endif + +/* Stuff used for extended tags in YAFFS2 */ + +typedef enum { + YAFFS_ECC_RESULT_UNKNOWN, + YAFFS_ECC_RESULT_NO_ERROR, + YAFFS_ECC_RESULT_FIXED, + YAFFS_ECC_RESULT_UNFIXED +} yaffs_ECCResult; + +typedef enum { + YAFFS_OBJECT_TYPE_UNKNOWN, + YAFFS_OBJECT_TYPE_FILE, + YAFFS_OBJECT_TYPE_SYMLINK, + YAFFS_OBJECT_TYPE_DIRECTORY, + YAFFS_OBJECT_TYPE_HARDLINK, + YAFFS_OBJECT_TYPE_SPECIAL +} yaffs_ObjectType; + +#define YAFFS_OBJECT_TYPE_MAX YAFFS_OBJECT_TYPE_SPECIAL + +typedef struct { + + unsigned validMarker0; + unsigned chunkUsed; /* Status of the chunk: used or unused */ + unsigned objectId; /* If 0 then this is not part of an object (unused) */ + unsigned chunkId; /* If 0 then this is a header, else a data chunk */ + unsigned byteCount; /* Only valid for data chunks */ + + /* The following stuff only has meaning when we read */ + yaffs_ECCResult eccResult; + unsigned blockBad; + + /* YAFFS 1 stuff */ + unsigned chunkDeleted; /* The chunk is marked deleted */ + unsigned serialNumber; /* Yaffs1 2-bit serial number */ + + /* YAFFS2 stuff */ + unsigned sequenceNumber; /* The sequence number of this block */ + + /* Extra info if this is an object header (YAFFS2 only) */ + + unsigned extraHeaderInfoAvailable; /* There is extra info available if this is not zero */ + unsigned extraParentObjectId; /* The parent object */ + unsigned extraIsShrinkHeader; /* Is it a shrink header? */ + unsigned extraShadows; /* Does this shadow another object? */ + + yaffs_ObjectType extraObjectType; /* What object type? */ + + unsigned extraFileLength; /* Length if it is a file */ + unsigned extraEquivalentObjectId; /* Equivalent object Id if it is a hard link */ + + unsigned validMarker1; + +} yaffs_ExtendedTags; + +/* Spare structure for YAFFS1 */ +typedef struct { + __u8 tagByte0; + __u8 tagByte1; + __u8 tagByte2; + __u8 tagByte3; + __u8 pageStatus; /* set to 0 to delete the chunk */ + __u8 blockStatus; + __u8 tagByte4; + __u8 tagByte5; + __u8 ecc1[3]; + __u8 tagByte6; + __u8 tagByte7; + __u8 ecc2[3]; +} yaffs_Spare; + +/*Special structure for passing through to mtd */ +struct yaffs_NANDSpare { + yaffs_Spare spare; + int eccres1; + int eccres2; +}; + +/* Block data in RAM */ + +typedef enum { + YAFFS_BLOCK_STATE_UNKNOWN = 0, + + YAFFS_BLOCK_STATE_SCANNING, + YAFFS_BLOCK_STATE_NEEDS_SCANNING, + /* The block might have something on it (ie it is allocating or full, perhaps empty) + * but it needs to be scanned to determine its true state. + * This state is only valid during yaffs_Scan. + * NB We tolerate empty because the pre-scanner might be incapable of deciding + * However, if this state is returned on a YAFFS2 device, then we expect a sequence number + */ + + YAFFS_BLOCK_STATE_EMPTY, + /* This block is empty */ + + YAFFS_BLOCK_STATE_ALLOCATING, + /* This block is partially allocated. + * At least one page holds valid data. + * This is the one currently being used for page + * allocation. Should never be more than one of these + */ + + YAFFS_BLOCK_STATE_FULL, + /* All the pages in this block have been allocated. + */ + + YAFFS_BLOCK_STATE_DIRTY, + /* All pages have been allocated and deleted. + * Erase me, reuse me. + */ + + YAFFS_BLOCK_STATE_CHECKPOINT, + /* This block is assigned to holding checkpoint data. + */ + + YAFFS_BLOCK_STATE_COLLECTING, + /* This block is being garbage collected */ + + YAFFS_BLOCK_STATE_DEAD + /* This block has failed and is not in use */ +} yaffs_BlockState; + +#define YAFFS_NUMBER_OF_BLOCK_STATES (YAFFS_BLOCK_STATE_DEAD + 1) + + +typedef struct { + + int softDeletions:10; /* number of soft deleted pages */ + int pagesInUse:10; /* number of pages in use */ + unsigned blockState:4; /* One of the above block states. NB use unsigned because enum is sometimes an int */ + __u32 needsRetiring:1; /* Data has failed on this block, need to get valid data off */ + /* and retire the block. */ + __u32 skipErasedCheck: 1; /* If this is set we can skip the erased check on this block */ + __u32 gcPrioritise: 1; /* An ECC check or blank check has failed on this block. + It should be prioritised for GC */ + __u32 chunkErrorStrikes:3; /* How many times we've had ecc etc failures on this block and tried to reuse it */ + +#ifdef CONFIG_YAFFS_YAFFS2 + __u32 hasShrinkHeader:1; /* This block has at least one shrink object header */ + __u32 sequenceNumber; /* block sequence number for yaffs2 */ +#endif + +} yaffs_BlockInfo; + +/* -------------------------- Object structure -------------------------------*/ +/* This is the object structure as stored on NAND */ + +typedef struct { + yaffs_ObjectType type; + + /* Apply to everything */ + int parentObjectId; + __u16 sum__NoLongerUsed; /* checksum of name. No longer used */ + YCHAR name[YAFFS_MAX_NAME_LENGTH + 1]; + + /* The following apply to directories, files, symlinks - not hard links */ + __u32 yst_mode; /* protection */ + +#ifdef CONFIG_YAFFS_WINCE + __u32 notForWinCE[5]; +#else + __u32 yst_uid; + __u32 yst_gid; + __u32 yst_atime; + __u32 yst_mtime; + __u32 yst_ctime; +#endif + + /* File size applies to files only */ + int fileSize; + + /* Equivalent object id applies to hard links only. */ + int equivalentObjectId; + + /* Alias is for symlinks only. */ + YCHAR alias[YAFFS_MAX_ALIAS_LENGTH + 1]; + + __u32 yst_rdev; /* device stuff for block and char devices (major/min) */ + +#ifdef CONFIG_YAFFS_WINCE + __u32 win_ctime[2]; + __u32 win_atime[2]; + __u32 win_mtime[2]; + __u32 roomToGrow[4]; +#else + __u32 roomToGrow[10]; +#endif + + int shadowsObject; /* This object header shadows the specified object if > 0 */ + + /* isShrink applies to object headers written when we shrink the file (ie resize) */ + __u32 isShrink; + +} yaffs_ObjectHeader; + +/*--------------------------- Tnode -------------------------- */ + +union yaffs_Tnode_union { +#ifdef CONFIG_YAFFS_TNODE_LIST_DEBUG + union yaffs_Tnode_union *internal[YAFFS_NTNODES_INTERNAL + 1]; +#else + union yaffs_Tnode_union *internal[YAFFS_NTNODES_INTERNAL]; +#endif +/* __u16 level0[YAFFS_NTNODES_LEVEL0]; */ + +}; + +typedef union yaffs_Tnode_union yaffs_Tnode; + +struct yaffs_TnodeList_struct { + struct yaffs_TnodeList_struct *next; + yaffs_Tnode *tnodes; +}; + +typedef struct yaffs_TnodeList_struct yaffs_TnodeList; + +/*------------------------ Object -----------------------------*/ +/* An object can be one of: + * - a directory (no data, has children links + * - a regular file (data.... not prunes :->). + * - a symlink [symbolic link] (the alias). + * - a hard link + */ + +typedef struct { + __u32 fileSize; + __u32 scannedFileSize; + __u32 shrinkSize; + int topLevel; + yaffs_Tnode *top; +} yaffs_FileStructure; + +typedef struct { + struct list_head children; /* list of child links */ +} yaffs_DirectoryStructure; + +typedef struct { + YCHAR *alias; +} yaffs_SymLinkStructure; + +typedef struct { + struct yaffs_ObjectStruct *equivalentObject; + __u32 equivalentObjectId; +} yaffs_HardLinkStructure; + +typedef union { + yaffs_FileStructure fileVariant; + yaffs_DirectoryStructure directoryVariant; + yaffs_SymLinkStructure symLinkVariant; + yaffs_HardLinkStructure hardLinkVariant; +} yaffs_ObjectVariant; + +struct yaffs_ObjectStruct { + __u8 deleted:1; /* This should only apply to unlinked files. */ + __u8 softDeleted:1; /* it has also been soft deleted */ + __u8 unlinked:1; /* An unlinked file. The file should be in the unlinked directory.*/ + __u8 fake:1; /* A fake object has no presence on NAND. */ + __u8 renameAllowed:1; /* Some objects are not allowed to be renamed. */ + __u8 unlinkAllowed:1; + __u8 dirty:1; /* the object needs to be written to flash */ + __u8 valid:1; /* When the file system is being loaded up, this + * object might be created before the data + * is available (ie. file data records appear before the header). + */ + __u8 lazyLoaded:1; /* This object has been lazy loaded and is missing some detail */ + + __u8 deferedFree:1; /* For Linux kernel. Object is removed from NAND, but is + * still in the inode cache. Free of object is defered. + * until the inode is released. + */ + + __u8 serial; /* serial number of chunk in NAND. Cached here */ + __u16 sum; /* sum of the name to speed searching */ + + struct yaffs_DeviceStruct *myDev; /* The device I'm on */ + + struct list_head hashLink; /* list of objects in this hash bucket */ + + struct list_head hardLinks; /* all the equivalent hard linked objects */ + + /* directory structure stuff */ + /* also used for linking up the free list */ + struct yaffs_ObjectStruct *parent; + struct list_head siblings; + + /* Where's my object header in NAND? */ + int chunkId; + + int nDataChunks; /* Number of data chunks attached to the file. */ + + __u32 objectId; /* the object id value */ + + __u32 yst_mode; + +#ifdef CONFIG_YAFFS_SHORT_NAMES_IN_RAM + YCHAR shortName[YAFFS_SHORT_NAME_LENGTH + 1]; +#endif + +#ifndef __KERNEL__ + __u32 inUse; +#endif + +#ifdef CONFIG_YAFFS_WINCE + __u32 win_ctime[2]; + __u32 win_mtime[2]; + __u32 win_atime[2]; +#else + __u32 yst_uid; + __u32 yst_gid; + __u32 yst_atime; + __u32 yst_mtime; + __u32 yst_ctime; +#endif + + __u32 yst_rdev; + +#ifdef __KERNEL__ + struct inode *myInode; + +#endif + + yaffs_ObjectType variantType; + + yaffs_ObjectVariant variant; + +}; + +typedef struct yaffs_ObjectStruct yaffs_Object; + +struct yaffs_ObjectList_struct { + yaffs_Object *objects; + struct yaffs_ObjectList_struct *next; +}; + +typedef struct yaffs_ObjectList_struct yaffs_ObjectList; + +typedef struct { + struct list_head list; + int count; +} yaffs_ObjectBucket; + + +/* yaffs_CheckpointObject holds the definition of an object as dumped + * by checkpointing. + */ + +typedef struct { + int structType; + __u32 objectId; + __u32 parentId; + int chunkId; + + yaffs_ObjectType variantType:3; + __u8 deleted:1; + __u8 softDeleted:1; + __u8 unlinked:1; + __u8 fake:1; + __u8 renameAllowed:1; + __u8 unlinkAllowed:1; + __u8 serial; + + int nDataChunks; + __u32 fileSizeOrEquivalentObjectId; + +}yaffs_CheckpointObject; + +/*--------------------- Temporary buffers ---------------- + * + * These are chunk-sized working buffers. Each device has a few + */ + +typedef struct { + __u8 *buffer; + int line; /* track from whence this buffer was allocated */ + int maxLine; +} yaffs_TempBuffer; + +/*----------------- Device ---------------------------------*/ + +struct yaffs_DeviceStruct { + struct list_head devList; + const char *name; + + /* Entry parameters set up way early. Yaffs sets up the rest.*/ + int nDataBytesPerChunk; /* Should be a power of 2 >= 512 */ + int nChunksPerBlock; /* does not need to be a power of 2 */ + int nBytesPerSpare; /* spare area size */ + int startBlock; /* Start block we're allowed to use */ + int endBlock; /* End block we're allowed to use */ + int nReservedBlocks; /* We want this tuneable so that we can reduce */ + /* reserved blocks on NOR and RAM. */ + + + /* Stuff used by the shared space checkpointing mechanism */ + /* If this value is zero, then this mechanism is disabled */ + +// int nCheckpointReservedBlocks; /* Blocks to reserve for checkpoint data */ + + + + + int nShortOpCaches; /* If <= 0, then short op caching is disabled, else + * the number of short op caches (don't use too many) + */ + + int useHeaderFileSize; /* Flag to determine if we should use file sizes from the header */ + + int useNANDECC; /* Flag to decide whether or not to use NANDECC */ + + void *genericDevice; /* Pointer to device context + * On an mtd this holds the mtd pointer. + */ + void *superBlock; + + /* NAND access functions (Must be set before calling YAFFS)*/ + + int (*writeChunkToNAND) (struct yaffs_DeviceStruct * dev, + int chunkInNAND, const __u8 * data, + const yaffs_Spare * spare); + int (*readChunkFromNAND) (struct yaffs_DeviceStruct * dev, + int chunkInNAND, __u8 * data, + yaffs_Spare * spare); + int (*eraseBlockInNAND) (struct yaffs_DeviceStruct * dev, + int blockInNAND); + int (*initialiseNAND) (struct yaffs_DeviceStruct * dev); + +#ifdef CONFIG_YAFFS_YAFFS2 + int (*writeChunkWithTagsToNAND) (struct yaffs_DeviceStruct * dev, + int chunkInNAND, const __u8 * data, + const yaffs_ExtendedTags * tags); + int (*readChunkWithTagsFromNAND) (struct yaffs_DeviceStruct * dev, + int chunkInNAND, __u8 * data, + yaffs_ExtendedTags * tags); + int (*markNANDBlockBad) (struct yaffs_DeviceStruct * dev, int blockNo); + int (*queryNANDBlock) (struct yaffs_DeviceStruct * dev, int blockNo, + yaffs_BlockState * state, int *sequenceNumber); +#endif + + int isYaffs2; + + /* The removeObjectCallback function must be supplied by OS flavours that + * need it. The Linux kernel does not use this, but yaffs direct does use + * it to implement the faster readdir + */ + void (*removeObjectCallback)(struct yaffs_ObjectStruct *obj); + + /* Callback to mark the superblock dirsty */ + void (*markSuperBlockDirty)(void * superblock); + + int wideTnodesDisabled; /* Set to disable wide tnodes */ + + + /* End of stuff that must be set before initialisation. */ + + /* Checkpoint control. Can be set before or after initialisation */ + __u8 skipCheckpointRead; + __u8 skipCheckpointWrite; + + /* Runtime parameters. Set up by YAFFS. */ + + __u16 chunkGroupBits; /* 0 for devices <= 32MB. else log2(nchunks) - 16 */ + __u16 chunkGroupSize; /* == 2^^chunkGroupBits */ + + /* Stuff to support wide tnodes */ + __u32 tnodeWidth; + __u32 tnodeMask; + + /* Stuff to support various file offses to chunk/offset translations */ + /* "Crumbs" for nDataBytesPerChunk not being a power of 2 */ + __u32 crumbMask; + __u32 crumbShift; + __u32 crumbsPerChunk; + + /* Straight shifting for nDataBytesPerChunk being a power of 2 */ + __u32 chunkShift; + __u32 chunkMask; + + +#ifdef __KERNEL__ + + struct semaphore sem; /* Semaphore for waiting on erasure.*/ + struct semaphore grossLock; /* Gross locking semaphore */ + __u8 *spareBuffer; /* For mtdif2 use. Don't know the size of the buffer + * at compile time so we have to allocate it. + */ + void (*putSuperFunc) (struct super_block * sb); +#endif + + int isMounted; + + int isCheckpointed; + + + /* Stuff to support block offsetting to support start block zero */ + int internalStartBlock; + int internalEndBlock; + int blockOffset; + int chunkOffset; + + + /* Runtime checkpointing stuff */ + int checkpointPageSequence; /* running sequence number of checkpoint pages */ + int checkpointByteCount; + int checkpointByteOffset; + __u8 *checkpointBuffer; + int checkpointOpenForWrite; + int blocksInCheckpoint; + int checkpointCurrentChunk; + int checkpointCurrentBlock; + int checkpointNextBlock; + int *checkpointBlockList; + int checkpointMaxBlocks; + __u32 checkpointSum; + __u32 checkpointXor; + + int nCheckpointBlocksRequired; /* Number of blocks needed to store current checkpoint set */ + + /* Block Info */ + yaffs_BlockInfo *blockInfo; + __u8 *chunkBits; /* bitmap of chunks in use */ + unsigned blockInfoAlt:1; /* was allocated using alternative strategy */ + unsigned chunkBitsAlt:1; /* was allocated using alternative strategy */ + int chunkBitmapStride; /* Number of bytes of chunkBits per block. + * Must be consistent with nChunksPerBlock. + */ + + int nErasedBlocks; + int allocationBlock; /* Current block being allocated off */ + __u32 allocationPage; + int allocationBlockFinder; /* Used to search for next allocation block */ + + /* Runtime state */ + int nTnodesCreated; + yaffs_Tnode *freeTnodes; + int nFreeTnodes; + yaffs_TnodeList *allocatedTnodeList; + + int isDoingGC; + + int nObjectsCreated; + yaffs_Object *freeObjects; + int nFreeObjects; + + yaffs_ObjectList *allocatedObjectList; + + yaffs_ObjectBucket objectBucket[YAFFS_NOBJECT_BUCKETS]; + + int nFreeChunks; + + int currentDirtyChecker; /* Used to find current dirtiest block */ + + __u32 *gcCleanupList; /* objects to delete at the end of a GC. */ + int nonAggressiveSkip; /* GC state/mode */ + + /* Statistcs */ + int nPageWrites; + int nPageReads; + int nBlockErasures; + int nErasureFailures; + int nGCCopies; + int garbageCollections; + int passiveGarbageCollections; + int nRetriedWrites; + int nRetiredBlocks; + int eccFixed; + int eccUnfixed; + int tagsEccFixed; + int tagsEccUnfixed; + int nDeletions; + int nUnmarkedDeletions; + + int hasPendingPrioritisedGCs; /* We think this device might have pending prioritised gcs */ + + /* Special directories */ + yaffs_Object *rootDir; + yaffs_Object *lostNFoundDir; + + /* Buffer areas for storing data to recover from write failures TODO + * __u8 bufferedData[YAFFS_CHUNKS_PER_BLOCK][YAFFS_BYTES_PER_CHUNK]; + * yaffs_Spare bufferedSpare[YAFFS_CHUNKS_PER_BLOCK]; + */ + + int bufferedBlock; /* Which block is buffered here? */ + int doingBufferedBlockRewrite; + + yaffs_ChunkCache *srCache; + int srLastUse; + + int cacheHits; + + /* Stuff for background deletion and unlinked files.*/ + yaffs_Object *unlinkedDir; /* Directory where unlinked and deleted files live. */ + yaffs_Object *deletedDir; /* Directory where deleted objects are sent to disappear. */ + yaffs_Object *unlinkedDeletion; /* Current file being background deleted.*/ + int nDeletedFiles; /* Count of files awaiting deletion;*/ + int nUnlinkedFiles; /* Count of unlinked files. */ + int nBackgroundDeletions; /* Count of background deletions. */ + + + yaffs_TempBuffer tempBuffer[YAFFS_N_TEMP_BUFFERS]; + int maxTemp; + int unmanagedTempAllocations; + int unmanagedTempDeallocations; + + /* yaffs2 runtime stuff */ + unsigned sequenceNumber; /* Sequence number of currently allocating block */ + unsigned oldestDirtySequence; + +}; + +typedef struct yaffs_DeviceStruct yaffs_Device; + +/* The static layout of block usage etc is stored in the super block header */ +typedef struct { + int StructType; + int version; + int checkpointStartBlock; + int checkpointEndBlock; + int startBlock; + int endBlock; + int rfu[100]; +} yaffs_SuperBlockHeader; + +/* The CheckpointDevice structure holds the device information that changes at runtime and + * must be preserved over unmount/mount cycles. + */ +typedef struct { + int structType; + int nErasedBlocks; + int allocationBlock; /* Current block being allocated off */ + __u32 allocationPage; + int nFreeChunks; + + int nDeletedFiles; /* Count of files awaiting deletion;*/ + int nUnlinkedFiles; /* Count of unlinked files. */ + int nBackgroundDeletions; /* Count of background deletions. */ + + /* yaffs2 runtime stuff */ + unsigned sequenceNumber; /* Sequence number of currently allocating block */ + unsigned oldestDirtySequence; + +} yaffs_CheckpointDevice; + + +typedef struct { + int structType; + __u32 magic; + __u32 version; + __u32 head; +} yaffs_CheckpointValidity; + +/* Function to manipulate block info */ +static Y_INLINE yaffs_BlockInfo *yaffs_GetBlockInfo(yaffs_Device * dev, int blk) +{ + if (blk < dev->internalStartBlock || blk > dev->internalEndBlock) { + T(YAFFS_TRACE_ERROR, + (TSTR + ("**>> yaffs: getBlockInfo block %d is not valid" TENDSTR), + blk)); + YBUG(); + } + return &dev->blockInfo[blk - dev->internalStartBlock]; +} + +/*----------------------- YAFFS Functions -----------------------*/ + +int yaffs_GutsInitialise(yaffs_Device * dev); +void yaffs_Deinitialise(yaffs_Device * dev); + +int yaffs_GetNumberOfFreeChunks(yaffs_Device * dev); + +int yaffs_RenameObject(yaffs_Object * oldDir, const YCHAR * oldName, + yaffs_Object * newDir, const YCHAR * newName); + +int yaffs_Unlink(yaffs_Object * dir, const YCHAR * name); +int yaffs_DeleteFile(yaffs_Object * obj); + +int yaffs_GetObjectName(yaffs_Object * obj, YCHAR * name, int buffSize); +int yaffs_GetObjectFileLength(yaffs_Object * obj); +int yaffs_GetObjectInode(yaffs_Object * obj); +unsigned yaffs_GetObjectType(yaffs_Object * obj); +int yaffs_GetObjectLinkCount(yaffs_Object * obj); + +int yaffs_SetAttributes(yaffs_Object * obj, struct iattr *attr); +int yaffs_GetAttributes(yaffs_Object * obj, struct iattr *attr); + +/* File operations */ +int yaffs_ReadDataFromFile(yaffs_Object * obj, __u8 * buffer, loff_t offset, + int nBytes); +int yaffs_WriteDataToFile(yaffs_Object * obj, const __u8 * buffer, loff_t offset, + int nBytes, int writeThrough); +int yaffs_ResizeFile(yaffs_Object * obj, loff_t newSize); + +yaffs_Object *yaffs_MknodFile(yaffs_Object * parent, const YCHAR * name, + __u32 mode, __u32 uid, __u32 gid); +int yaffs_FlushFile(yaffs_Object * obj, int updateTime); + +/* Flushing and checkpointing */ +void yaffs_FlushEntireDeviceCache(yaffs_Device *dev); + +int yaffs_CheckpointSave(yaffs_Device *dev); +int yaffs_CheckpointRestore(yaffs_Device *dev); + +/* Directory operations */ +yaffs_Object *yaffs_MknodDirectory(yaffs_Object * parent, const YCHAR * name, + __u32 mode, __u32 uid, __u32 gid); +yaffs_Object *yaffs_FindObjectByName(yaffs_Object * theDir, const YCHAR * name); +int yaffs_ApplyToDirectoryChildren(yaffs_Object * theDir, + int (*fn) (yaffs_Object *)); + +yaffs_Object *yaffs_FindObjectByNumber(yaffs_Device * dev, __u32 number); + +/* Link operations */ +yaffs_Object *yaffs_Link(yaffs_Object * parent, const YCHAR * name, + yaffs_Object * equivalentObject); + +yaffs_Object *yaffs_GetEquivalentObject(yaffs_Object * obj); + +/* Symlink operations */ +yaffs_Object *yaffs_MknodSymLink(yaffs_Object * parent, const YCHAR * name, + __u32 mode, __u32 uid, __u32 gid, + const YCHAR * alias); +YCHAR *yaffs_GetSymlinkAlias(yaffs_Object * obj); + +/* Special inodes (fifos, sockets and devices) */ +yaffs_Object *yaffs_MknodSpecial(yaffs_Object * parent, const YCHAR * name, + __u32 mode, __u32 uid, __u32 gid, __u32 rdev); + +/* Special directories */ +yaffs_Object *yaffs_Root(yaffs_Device * dev); +yaffs_Object *yaffs_LostNFound(yaffs_Device * dev); + +#ifdef CONFIG_YAFFS_WINCE +/* CONFIG_YAFFS_WINCE special stuff */ +void yfsd_WinFileTimeNow(__u32 target[2]); +#endif + +#ifdef __KERNEL__ + +void yaffs_HandleDeferedFree(yaffs_Object * obj); +#endif + +/* Debug dump */ +int yaffs_DumpObject(yaffs_Object * obj); + +void yaffs_GutsTest(yaffs_Device * dev); + +/* A few useful functions */ +void yaffs_InitialiseTags(yaffs_ExtendedTags * tags); +void yaffs_DeleteChunk(yaffs_Device * dev, int chunkId, int markNAND, int lyn); +int yaffs_CheckFF(__u8 * buffer, int nBytes); +void yaffs_HandleChunkError(yaffs_Device *dev, yaffs_BlockInfo *bi); + +#endif --- /dev/null +++ linux-2.6.20/fs/yaffs2/yaffs_mtdif.c @@ -0,0 +1,241 @@ +/* + * YAFFS: Yet Another Flash File System. A NAND-flash specific file system. + * + * Copyright (C) 2002-2007 Aleph One Ltd. + * for Toby Churchill Ltd and Brightstar Engineering + * + * Created by Charles Manning + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +const char *yaffs_mtdif_c_version = + "$Id: yaffs_mtdif.c,v 1.21 2007/12/13 15:35:18 wookey Exp $"; + +#include "yportenv.h" + + +#include "yaffs_mtdif.h" + +#include "linux/mtd/mtd.h" +#include "linux/types.h" +#include "linux/time.h" +#include "linux/mtd/nand.h" + +#if (MTD_VERSION_CODE < MTD_VERSION(2,6,18)) +static struct nand_oobinfo yaffs_oobinfo = { + .useecc = 1, + .eccbytes = 6, + .eccpos = {8, 9, 10, 13, 14, 15} +}; + +static struct nand_oobinfo yaffs_noeccinfo = { + .useecc = 0, +}; +#endif + +#if (MTD_VERSION_CODE > MTD_VERSION(2,6,17)) +static inline void translate_spare2oob(const yaffs_Spare *spare, __u8 *oob) +{ + oob[0] = spare->tagByte0; + oob[1] = spare->tagByte1; + oob[2] = spare->tagByte2; + oob[3] = spare->tagByte3; + oob[4] = spare->tagByte4; + oob[5] = spare->tagByte5 & 0x3f; + oob[5] |= spare->blockStatus == 'Y' ? 0: 0x80; + oob[5] |= spare->pageStatus == 0 ? 0: 0x40; + oob[6] = spare->tagByte6; + oob[7] = spare->tagByte7; +} + +static inline void translate_oob2spare(yaffs_Spare *spare, __u8 *oob) +{ + struct yaffs_NANDSpare *nspare = (struct yaffs_NANDSpare *)spare; + spare->tagByte0 = oob[0]; + spare->tagByte1 = oob[1]; + spare->tagByte2 = oob[2]; + spare->tagByte3 = oob[3]; + spare->tagByte4 = oob[4]; + spare->tagByte5 = oob[5] == 0xff ? 0xff : oob[5] & 0x3f; + spare->blockStatus = oob[5] & 0x80 ? 0xff : 'Y'; + spare->pageStatus = oob[5] & 0x40 ? 0xff : 0; + spare->ecc1[0] = spare->ecc1[1] = spare->ecc1[2] = 0xff; + spare->tagByte6 = oob[6]; + spare->tagByte7 = oob[7]; + spare->ecc2[0] = spare->ecc2[1] = spare->ecc2[2] = 0xff; + + nspare->eccres1 = nspare->eccres2 = 0; /* FIXME */ +} +#endif + +int nandmtd_WriteChunkToNAND(yaffs_Device * dev, int chunkInNAND, + const __u8 * data, const yaffs_Spare * spare) +{ + struct mtd_info *mtd = (struct mtd_info *)(dev->genericDevice); +#if (MTD_VERSION_CODE > MTD_VERSION(2,6,17)) + struct mtd_oob_ops ops; +#endif + size_t dummy; + int retval = 0; + + loff_t addr = ((loff_t) chunkInNAND) * dev->nDataBytesPerChunk; +#if (MTD_VERSION_CODE > MTD_VERSION(2,6,17)) + __u8 spareAsBytes[8]; /* OOB */ + + if (data && !spare) + retval = mtd->write(mtd, addr, dev->nDataBytesPerChunk, + &dummy, data); + else if (spare) { + if (dev->useNANDECC) { + translate_spare2oob(spare, spareAsBytes); + ops.mode = MTD_OOB_AUTO; + ops.ooblen = 8; /* temp hack */ + } else { + ops.mode = MTD_OOB_RAW; + ops.ooblen = YAFFS_BYTES_PER_SPARE; + } + ops.len = data ? dev->nDataBytesPerChunk : ops.ooblen; + ops.datbuf = (u8 *)data; + ops.ooboffs = 0; + ops.oobbuf = spareAsBytes; + retval = mtd->write_oob(mtd, addr, &ops); + } +#else + __u8 *spareAsBytes = (__u8 *) spare; + + if (data && spare) { + if (dev->useNANDECC) + retval = + mtd->write_ecc(mtd, addr, dev->nDataBytesPerChunk, + &dummy, data, spareAsBytes, + &yaffs_oobinfo); + else + retval = + mtd->write_ecc(mtd, addr, dev->nDataBytesPerChunk, + &dummy, data, spareAsBytes, + &yaffs_noeccinfo); + } else { + if (data) + retval = + mtd->write(mtd, addr, dev->nDataBytesPerChunk, &dummy, + data); + if (spare) + retval = + mtd->write_oob(mtd, addr, YAFFS_BYTES_PER_SPARE, + &dummy, spareAsBytes); + } +#endif + + if (retval == 0) + return YAFFS_OK; + else + return YAFFS_FAIL; +} + +int nandmtd_ReadChunkFromNAND(yaffs_Device * dev, int chunkInNAND, __u8 * data, + yaffs_Spare * spare) +{ + struct mtd_info *mtd = (struct mtd_info *)(dev->genericDevice); +#if (MTD_VERSION_CODE > MTD_VERSION(2,6,17)) + struct mtd_oob_ops ops; +#endif + size_t dummy; + int retval = 0; + + loff_t addr = ((loff_t) chunkInNAND) * dev->nDataBytesPerChunk; +#if (MTD_VERSION_CODE > MTD_VERSION(2,6,17)) + __u8 spareAsBytes[8]; /* OOB */ + + if (data && !spare) + retval = mtd->read(mtd, addr, dev->nDataBytesPerChunk, + &dummy, data); + else if (spare) { + if (dev->useNANDECC) { + ops.mode = MTD_OOB_AUTO; + ops.ooblen = 8; /* temp hack */ + } else { + ops.mode = MTD_OOB_RAW; + ops.ooblen = YAFFS_BYTES_PER_SPARE; + } + ops.len = data ? dev->nDataBytesPerChunk : ops.ooblen; + ops.datbuf = data; + ops.ooboffs = 0; + ops.oobbuf = spareAsBytes; + retval = mtd->read_oob(mtd, addr, &ops); + if (dev->useNANDECC) + translate_oob2spare(spare, spareAsBytes); + } +#else + __u8 *spareAsBytes = (__u8 *) spare; + + if (data && spare) { + if (dev->useNANDECC) { + /* Careful, this call adds 2 ints */ + /* to the end of the spare data. Calling function */ + /* should allocate enough memory for spare, */ + /* i.e. [YAFFS_BYTES_PER_SPARE+2*sizeof(int)]. */ + retval = + mtd->read_ecc(mtd, addr, dev->nDataBytesPerChunk, + &dummy, data, spareAsBytes, + &yaffs_oobinfo); + } else { + retval = + mtd->read_ecc(mtd, addr, dev->nDataBytesPerChunk, + &dummy, data, spareAsBytes, + &yaffs_noeccinfo); + } + } else { + if (data) + retval = + mtd->read(mtd, addr, dev->nDataBytesPerChunk, &dummy, + data); + if (spare) + retval = + mtd->read_oob(mtd, addr, YAFFS_BYTES_PER_SPARE, + &dummy, spareAsBytes); + } +#endif + + if (retval == 0) + return YAFFS_OK; + else + return YAFFS_FAIL; +} + +int nandmtd_EraseBlockInNAND(yaffs_Device * dev, int blockNumber) +{ + struct mtd_info *mtd = (struct mtd_info *)(dev->genericDevice); + __u32 addr = + ((loff_t) blockNumber) * dev->nDataBytesPerChunk + * dev->nChunksPerBlock; + struct erase_info ei; + int retval = 0; + + ei.mtd = mtd; + ei.addr = addr; + ei.len = dev->nDataBytesPerChunk * dev->nChunksPerBlock; + ei.time = 1000; + ei.retries = 2; + ei.callback = NULL; + ei.priv = (u_long) dev; + + /* Todo finish off the ei if required */ + + sema_init(&dev->sem, 0); + + retval = mtd->erase(mtd, &ei); + + if (retval == 0) + return YAFFS_OK; + else + return YAFFS_FAIL; +} + +int nandmtd_InitialiseNAND(yaffs_Device * dev) +{ + return YAFFS_OK; +} + --- /dev/null +++ linux-2.6.20/fs/yaffs2/yaffs_mtdif.h @@ -0,0 +1,27 @@ +/* + * YAFFS: Yet another Flash File System . A NAND-flash specific file system. + * + * Copyright (C) 2002-2007 Aleph One Ltd. + * for Toby Churchill Ltd and Brightstar Engineering + * + * Created by Charles Manning + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 2.1 as + * published by the Free Software Foundation. + * + * Note: Only YAFFS headers are LGPL, YAFFS C code is covered by GPL. + */ + +#ifndef __YAFFS_MTDIF_H__ +#define __YAFFS_MTDIF_H__ + +#include "yaffs_guts.h" + +int nandmtd_WriteChunkToNAND(yaffs_Device * dev, int chunkInNAND, + const __u8 * data, const yaffs_Spare * spare); +int nandmtd_ReadChunkFromNAND(yaffs_Device * dev, int chunkInNAND, __u8 * data, + yaffs_Spare * spare); +int nandmtd_EraseBlockInNAND(yaffs_Device * dev, int blockNumber); +int nandmtd_InitialiseNAND(yaffs_Device * dev); +#endif --- /dev/null +++ linux-2.6.20/fs/yaffs2/yaffs_mtdif1.c @@ -0,0 +1,369 @@ +/* + * YAFFS: Yet another FFS. A NAND-flash specific file system. + * yaffs_mtdif1.c NAND mtd interface functions for small-page NAND. + * + * Copyright (C) 2002 Aleph One Ltd. + * for Toby Churchill Ltd and Brightstar Engineering + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +/* + * This module provides the interface between yaffs_nand.c and the + * MTD API. This version is used when the MTD interface supports the + * 'mtd_oob_ops' style calls to read_oob and write_oob, circa 2.6.17, + * and we have small-page NAND device. + * + * These functions are invoked via function pointers in yaffs_nand.c. + * This replaces functionality provided by functions in yaffs_mtdif.c + * and the yaffs_TagsCompatability functions in yaffs_tagscompat.c that are + * called in yaffs_mtdif.c when the function pointers are NULL. + * We assume the MTD layer is performing ECC (useNANDECC is true). + */ + +#include "yportenv.h" +#include "yaffs_guts.h" +#include "yaffs_packedtags1.h" +#include "yaffs_tagscompat.h" // for yaffs_CalcTagsECC + +#include "linux/kernel.h" +#include "linux/version.h" +#include "linux/types.h" +#include "linux/mtd/mtd.h" + +/* Don't compile this module if we don't have MTD's mtd_oob_ops interface */ +#if (MTD_VERSION_CODE > MTD_VERSION(2,6,17)) + +const char *yaffs_mtdif1_c_version = "$Id: yaffs_mtdif1.c,v 1.7 2007/12/13 15:35:18 wookey Exp $"; + +#ifndef CONFIG_YAFFS_9BYTE_TAGS +# define YTAG1_SIZE 8 +#else +# define YTAG1_SIZE 9 +#endif + +#if 0 +/* Use the following nand_ecclayout with MTD when using + * CONFIG_YAFFS_9BYTE_TAGS and the older on-NAND tags layout. + * If you have existing Yaffs images and the byte order differs from this, + * adjust 'oobfree' to match your existing Yaffs data. + * + * This nand_ecclayout scatters/gathers to/from the old-yaffs layout with the + * pageStatus byte (at NAND spare offset 4) scattered/gathered from/to + * the 9th byte. + * + * Old-style on-NAND format: T0,T1,T2,T3,P,B,T4,T5,E0,E1,E2,T6,T7,E3,E4,E5 + * We have/need PackedTags1 plus pageStatus: T0,T1,T2,T3,T4,T5,T6,T7,P + * where Tn are the tag bytes, En are MTD's ECC bytes, P is the pageStatus + * byte and B is the small-page bad-block indicator byte. + */ +static struct nand_ecclayout nand_oob_16 = { + .eccbytes = 6, + .eccpos = { 8, 9, 10, 13, 14, 15 }, + .oobavail = 9, + .oobfree = { { 0, 4 }, { 6, 2 }, { 11, 2 }, { 4, 1 } } +}; +#endif + +/* Write a chunk (page) of data to NAND. + * + * Caller always provides ExtendedTags data which are converted to a more + * compact (packed) form for storage in NAND. A mini-ECC runs over the + * contents of the tags meta-data; used to valid the tags when read. + * + * - Pack ExtendedTags to PackedTags1 form + * - Compute mini-ECC for PackedTags1 + * - Write data and packed tags to NAND. + * + * Note: Due to the use of the PackedTags1 meta-data which does not include + * a full sequence number (as found in the larger PackedTags2 form) it is + * necessary for Yaffs to re-write a chunk/page (just once) to mark it as + * discarded and dirty. This is not ideal: newer NAND parts are supposed + * to be written just once. When Yaffs performs this operation, this + * function is called with a NULL data pointer -- calling MTD write_oob + * without data is valid usage (2.6.17). + * + * Any underlying MTD error results in YAFFS_FAIL. + * Returns YAFFS_OK or YAFFS_FAIL. + */ +int nandmtd1_WriteChunkWithTagsToNAND(yaffs_Device *dev, + int chunkInNAND, const __u8 * data, const yaffs_ExtendedTags * etags) +{ + struct mtd_info * mtd = dev->genericDevice; + int chunkBytes = dev->nDataBytesPerChunk; + loff_t addr = ((loff_t)chunkInNAND) * chunkBytes; + struct mtd_oob_ops ops; + yaffs_PackedTags1 pt1; + int retval; + + /* we assume that PackedTags1 and yaffs_Tags are compatible */ + compile_time_assertion(sizeof(yaffs_PackedTags1) == 12); + compile_time_assertion(sizeof(yaffs_Tags) == 8); + + dev->nPageWrites++; + + yaffs_PackTags1(&pt1, etags); + yaffs_CalcTagsECC((yaffs_Tags *)&pt1); + + /* When deleting a chunk, the upper layer provides only skeletal + * etags, one with chunkDeleted set. However, we need to update the + * tags, not erase them completely. So we use the NAND write property + * that only zeroed-bits stick and set tag bytes to all-ones and + * zero just the (not) deleted bit. + */ +#ifndef CONFIG_YAFFS_9BYTE_TAGS + if (etags->chunkDeleted) { + memset(&pt1, 0xff, 8); + /* clear delete status bit to indicate deleted */ + pt1.deleted = 0; + } +#else + ((__u8 *)&pt1)[8] = 0xff; + if (etags->chunkDeleted) { + memset(&pt1, 0xff, 8); + /* zero pageStatus byte to indicate deleted */ + ((__u8 *)&pt1)[8] = 0; + } +#endif + + memset(&ops, 0, sizeof(ops)); + ops.mode = MTD_OOB_AUTO; + ops.len = (data) ? chunkBytes : 0; + ops.ooblen = YTAG1_SIZE; + ops.datbuf = (__u8 *)data; + ops.oobbuf = (__u8 *)&pt1; + + retval = mtd->write_oob(mtd, addr, &ops); + if (retval) { + yaffs_trace(YAFFS_TRACE_MTD, + "write_oob failed, chunk %d, mtd error %d\n", + chunkInNAND, retval); + } + return retval ? YAFFS_FAIL : YAFFS_OK; +} + +/* Return with empty ExtendedTags but add eccResult. + */ +static int rettags(yaffs_ExtendedTags * etags, int eccResult, int retval) +{ + if (etags) { + memset(etags, 0, sizeof(*etags)); + etags->eccResult = eccResult; + } + return retval; +} + +/* Read a chunk (page) from NAND. + * + * Caller expects ExtendedTags data to be usable even on error; that is, + * all members except eccResult and blockBad are zeroed. + * + * - Check ECC results for data (if applicable) + * - Check for blank/erased block (return empty ExtendedTags if blank) + * - Check the PackedTags1 mini-ECC (correct if necessary/possible) + * - Convert PackedTags1 to ExtendedTags + * - Update eccResult and blockBad members to refect state. + * + * Returns YAFFS_OK or YAFFS_FAIL. + */ +int nandmtd1_ReadChunkWithTagsFromNAND(yaffs_Device *dev, + int chunkInNAND, __u8 * data, yaffs_ExtendedTags * etags) +{ + struct mtd_info * mtd = dev->genericDevice; + int chunkBytes = dev->nDataBytesPerChunk; + loff_t addr = ((loff_t)chunkInNAND) * chunkBytes; + int eccres = YAFFS_ECC_RESULT_NO_ERROR; + struct mtd_oob_ops ops; + yaffs_PackedTags1 pt1; + int retval; + int deleted; + + dev->nPageReads++; + + memset(&ops, 0, sizeof(ops)); + ops.mode = MTD_OOB_AUTO; + ops.len = (data) ? chunkBytes : 0; + ops.ooblen = YTAG1_SIZE; + ops.datbuf = data; + ops.oobbuf = (__u8 *)&pt1; + +#if (MTD_VERSION_CODE < MTD_VERSION(2,6,20)) + /* In MTD 2.6.18 to 2.6.19 nand_base.c:nand_do_read_oob() has a bug; + * help it out with ops.len = ops.ooblen when ops.datbuf == NULL. + */ + ops.len = (ops.datbuf) ? ops.len : ops.ooblen; +#endif + /* Read page and oob using MTD. + * Check status and determine ECC result. + */ + retval = mtd->read_oob(mtd, addr, &ops); + if (retval) { + yaffs_trace(YAFFS_TRACE_MTD, + "read_oob failed, chunk %d, mtd error %d\n", + chunkInNAND, retval); + } + + switch (retval) { + case 0: + /* no error */ + break; + + case -EUCLEAN: + /* MTD's ECC fixed the data */ + eccres = YAFFS_ECC_RESULT_FIXED; + dev->eccFixed++; + break; + + case -EBADMSG: + /* MTD's ECC could not fix the data */ + dev->eccUnfixed++; + /* fall into... */ + default: + rettags(etags, YAFFS_ECC_RESULT_UNFIXED, 0); + etags->blockBad = (mtd->block_isbad)(mtd, addr); + return YAFFS_FAIL; + } + + /* Check for a blank/erased chunk. + */ + if (yaffs_CheckFF((__u8 *)&pt1, 8)) { + /* when blank, upper layers want eccResult to be <= NO_ERROR */ + return rettags(etags, YAFFS_ECC_RESULT_NO_ERROR, YAFFS_OK); + } + +#ifndef CONFIG_YAFFS_9BYTE_TAGS + /* Read deleted status (bit) then return it to it's non-deleted + * state before performing tags mini-ECC check. pt1.deleted is + * inverted. + */ + deleted = !pt1.deleted; + pt1.deleted = 1; +#else + deleted = (yaffs_CountBits(((__u8 *)&pt1)[8]) < 7); +#endif + + /* Check the packed tags mini-ECC and correct if necessary/possible. + */ + retval = yaffs_CheckECCOnTags((yaffs_Tags *)&pt1); + switch (retval) { + case 0: + /* no tags error, use MTD result */ + break; + case 1: + /* recovered tags-ECC error */ + dev->tagsEccFixed++; + if (eccres == YAFFS_ECC_RESULT_NO_ERROR) + eccres = YAFFS_ECC_RESULT_FIXED; + break; + default: + /* unrecovered tags-ECC error */ + dev->tagsEccUnfixed++; + return rettags(etags, YAFFS_ECC_RESULT_UNFIXED, YAFFS_FAIL); + } + + /* Unpack the tags to extended form and set ECC result. + * [set shouldBeFF just to keep yaffs_UnpackTags1 happy] + */ + pt1.shouldBeFF = 0xFFFFFFFF; + yaffs_UnpackTags1(etags, &pt1); + etags->eccResult = eccres; + + /* Set deleted state */ + etags->chunkDeleted = deleted; + return YAFFS_OK; +} + +/* Mark a block bad. + * + * This is a persistant state. + * Use of this function should be rare. + * + * Returns YAFFS_OK or YAFFS_FAIL. + */ +int nandmtd1_MarkNANDBlockBad(struct yaffs_DeviceStruct *dev, int blockNo) +{ + struct mtd_info * mtd = dev->genericDevice; + int blocksize = dev->nChunksPerBlock * dev->nDataBytesPerChunk; + int retval; + + yaffs_trace(YAFFS_TRACE_BAD_BLOCKS, "marking block %d bad\n", blockNo); + + retval = mtd->block_markbad(mtd, (loff_t)blocksize * blockNo); + return (retval) ? YAFFS_FAIL : YAFFS_OK; +} + +/* Check any MTD prerequists. + * + * Returns YAFFS_OK or YAFFS_FAIL. + */ +static int nandmtd1_TestPrerequists(struct mtd_info * mtd) +{ + /* 2.6.18 has mtd->ecclayout->oobavail */ + /* 2.6.21 has mtd->ecclayout->oobavail and mtd->oobavail */ + int oobavail = mtd->ecclayout->oobavail; + + if (oobavail < YTAG1_SIZE) { + yaffs_trace(YAFFS_TRACE_ERROR, + "mtd device has only %d bytes for tags, need %d\n", + oobavail, YTAG1_SIZE); + return YAFFS_FAIL; + } + return YAFFS_OK; +} + +/* Query for the current state of a specific block. + * + * Examine the tags of the first chunk of the block and return the state: + * - YAFFS_BLOCK_STATE_DEAD, the block is marked bad + * - YAFFS_BLOCK_STATE_NEEDS_SCANNING, the block is in use + * - YAFFS_BLOCK_STATE_EMPTY, the block is clean + * + * Always returns YAFFS_OK. + */ +int nandmtd1_QueryNANDBlock(struct yaffs_DeviceStruct *dev, int blockNo, + yaffs_BlockState * pState, int *pSequenceNumber) +{ + struct mtd_info * mtd = dev->genericDevice; + int chunkNo = blockNo * dev->nChunksPerBlock; + loff_t addr = (loff_t)chunkNo * dev->nDataBytesPerChunk; + yaffs_ExtendedTags etags; + int state = YAFFS_BLOCK_STATE_DEAD; + int seqnum = 0; + int retval; + + /* We don't yet have a good place to test for MTD config prerequists. + * Do it here as we are called during the initial scan. + */ + if (nandmtd1_TestPrerequists(mtd) != YAFFS_OK) { + return YAFFS_FAIL; + } + + retval = nandmtd1_ReadChunkWithTagsFromNAND(dev, chunkNo, NULL, &etags); + etags.blockBad = (mtd->block_isbad)(mtd, addr); + if (etags.blockBad) { + yaffs_trace(YAFFS_TRACE_BAD_BLOCKS, + "block %d is marked bad\n", blockNo); + state = YAFFS_BLOCK_STATE_DEAD; + } + else if (etags.eccResult != YAFFS_ECC_RESULT_NO_ERROR) { + /* bad tags, need to look more closely */ + state = YAFFS_BLOCK_STATE_NEEDS_SCANNING; + } + else if (etags.chunkUsed) { + state = YAFFS_BLOCK_STATE_NEEDS_SCANNING; + seqnum = etags.sequenceNumber; + } + else { + state = YAFFS_BLOCK_STATE_EMPTY; + } + + *pState = state; + *pSequenceNumber = seqnum; + + /* query always succeeds */ + return YAFFS_OK; +} + +#endif /*MTD_VERSION*/ --- /dev/null +++ linux-2.6.20/fs/yaffs2/yaffs_mtdif1.h @@ -0,0 +1,28 @@ +/* + * YAFFS: Yet another Flash File System. A NAND-flash specific file system. + * + * Copyright (C) 2002-2007 Aleph One Ltd. + * for Toby Churchill Ltd and Brightstar Engineering + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 2.1 as + * published by the Free Software Foundation. + * + * Note: Only YAFFS headers are LGPL, YAFFS C code is covered by GPL. + */ + +#ifndef __YAFFS_MTDIF1_H__ +#define __YAFFS_MTDIF1_H__ + +int nandmtd1_WriteChunkWithTagsToNAND(yaffs_Device * dev, int chunkInNAND, + const __u8 * data, const yaffs_ExtendedTags * tags); + +int nandmtd1_ReadChunkWithTagsFromNAND(yaffs_Device * dev, int chunkInNAND, + __u8 * data, yaffs_ExtendedTags * tags); + +int nandmtd1_MarkNANDBlockBad(struct yaffs_DeviceStruct *dev, int blockNo); + +int nandmtd1_QueryNANDBlock(struct yaffs_DeviceStruct *dev, int blockNo, + yaffs_BlockState * state, int *sequenceNumber); + +#endif --- /dev/null +++ linux-2.6.20/fs/yaffs2/yaffs_mtdif2.c @@ -0,0 +1,232 @@ +/* + * YAFFS: Yet Another Flash File System. A NAND-flash specific file system. + * + * Copyright (C) 2002-2007 Aleph One Ltd. + * for Toby Churchill Ltd and Brightstar Engineering + * + * Created by Charles Manning + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +/* mtd interface for YAFFS2 */ + +const char *yaffs_mtdif2_c_version = + "$Id: yaffs_mtdif2.c,v 1.19 2007/12/13 15:35:18 wookey Exp $"; + +#include "yportenv.h" + + +#include "yaffs_mtdif2.h" + +#include "linux/mtd/mtd.h" +#include "linux/types.h" +#include "linux/time.h" + +#include "yaffs_packedtags2.h" + +int nandmtd2_WriteChunkWithTagsToNAND(yaffs_Device * dev, int chunkInNAND, + const __u8 * data, + const yaffs_ExtendedTags * tags) +{ + struct mtd_info *mtd = (struct mtd_info *)(dev->genericDevice); +#if (MTD_VERSION_CODE > MTD_VERSION(2,6,17)) + struct mtd_oob_ops ops; +#else + size_t dummy; +#endif + int retval = 0; + + loff_t addr = ((loff_t) chunkInNAND) * dev->nDataBytesPerChunk; + + yaffs_PackedTags2 pt; + + T(YAFFS_TRACE_MTD, + (TSTR + ("nandmtd2_WriteChunkWithTagsToNAND chunk %d data %p tags %p" + TENDSTR), chunkInNAND, data, tags)); + +#if (MTD_VERSION_CODE > MTD_VERSION(2,6,17)) + if (tags) + yaffs_PackTags2(&pt, tags); + else + BUG(); /* both tags and data should always be present */ + + if (data) { + ops.mode = MTD_OOB_AUTO; + ops.ooblen = sizeof(pt); + ops.len = dev->nDataBytesPerChunk; + ops.ooboffs = 0; + ops.datbuf = (__u8 *)data; + ops.oobbuf = (void *)&pt; + retval = mtd->write_oob(mtd, addr, &ops); + } else + BUG(); /* both tags and data should always be present */ +#else + if (tags) { + yaffs_PackTags2(&pt, tags); + } + + if (data && tags) { + if (dev->useNANDECC) + retval = + mtd->write_ecc(mtd, addr, dev->nDataBytesPerChunk, + &dummy, data, (__u8 *) & pt, NULL); + else + retval = + mtd->write_ecc(mtd, addr, dev->nDataBytesPerChunk, + &dummy, data, (__u8 *) & pt, NULL); + } else { + if (data) + retval = + mtd->write(mtd, addr, dev->nDataBytesPerChunk, &dummy, + data); + if (tags) + retval = + mtd->write_oob(mtd, addr, mtd->oobsize, &dummy, + (__u8 *) & pt); + + } +#endif + + if (retval == 0) + return YAFFS_OK; + else + return YAFFS_FAIL; +} + +int nandmtd2_ReadChunkWithTagsFromNAND(yaffs_Device * dev, int chunkInNAND, + __u8 * data, yaffs_ExtendedTags * tags) +{ + struct mtd_info *mtd = (struct mtd_info *)(dev->genericDevice); +#if (MTD_VERSION_CODE > MTD_VERSION(2,6,17)) + struct mtd_oob_ops ops; +#endif + size_t dummy; + int retval = 0; + + loff_t addr = ((loff_t) chunkInNAND) * dev->nDataBytesPerChunk; + + yaffs_PackedTags2 pt; + + T(YAFFS_TRACE_MTD, + (TSTR + ("nandmtd2_ReadChunkWithTagsFromNAND chunk %d data %p tags %p" + TENDSTR), chunkInNAND, data, tags)); + +#if (MTD_VERSION_CODE > MTD_VERSION(2,6,17)) + if (data && !tags) + retval = mtd->read(mtd, addr, dev->nDataBytesPerChunk, + &dummy, data); + else if (tags) { + ops.mode = MTD_OOB_AUTO; + ops.ooblen = sizeof(pt); + ops.len = data ? dev->nDataBytesPerChunk : sizeof(pt); + ops.ooboffs = 0; + ops.datbuf = data; + ops.oobbuf = dev->spareBuffer; + retval = mtd->read_oob(mtd, addr, &ops); + } +#else + if (data && tags) { + if (dev->useNANDECC) { + retval = + mtd->read_ecc(mtd, addr, dev->nDataBytesPerChunk, + &dummy, data, dev->spareBuffer, + NULL); + } else { + retval = + mtd->read_ecc(mtd, addr, dev->nDataBytesPerChunk, + &dummy, data, dev->spareBuffer, + NULL); + } + } else { + if (data) + retval = + mtd->read(mtd, addr, dev->nDataBytesPerChunk, &dummy, + data); + if (tags) + retval = + mtd->read_oob(mtd, addr, mtd->oobsize, &dummy, + dev->spareBuffer); + } +#endif + + memcpy(&pt, dev->spareBuffer, sizeof(pt)); + + if (tags) + yaffs_UnpackTags2(tags, &pt); + + if(tags && retval == -EBADMSG && tags->eccResult == YAFFS_ECC_RESULT_NO_ERROR) + tags->eccResult = YAFFS_ECC_RESULT_UNFIXED; + + if (retval == 0) + return YAFFS_OK; + else + return YAFFS_FAIL; +} + +int nandmtd2_MarkNANDBlockBad(struct yaffs_DeviceStruct *dev, int blockNo) +{ + struct mtd_info *mtd = (struct mtd_info *)(dev->genericDevice); + int retval; + T(YAFFS_TRACE_MTD, + (TSTR("nandmtd2_MarkNANDBlockBad %d" TENDSTR), blockNo)); + + retval = + mtd->block_markbad(mtd, + blockNo * dev->nChunksPerBlock * + dev->nDataBytesPerChunk); + + if (retval == 0) + return YAFFS_OK; + else + return YAFFS_FAIL; + +} + +int nandmtd2_QueryNANDBlock(struct yaffs_DeviceStruct *dev, int blockNo, + yaffs_BlockState * state, int *sequenceNumber) +{ + struct mtd_info *mtd = (struct mtd_info *)(dev->genericDevice); + int retval; + + T(YAFFS_TRACE_MTD, + (TSTR("nandmtd2_QueryNANDBlock %d" TENDSTR), blockNo)); + retval = + mtd->block_isbad(mtd, + blockNo * dev->nChunksPerBlock * + dev->nDataBytesPerChunk); + + if (retval) { + T(YAFFS_TRACE_MTD, (TSTR("block is bad" TENDSTR))); + + *state = YAFFS_BLOCK_STATE_DEAD; + *sequenceNumber = 0; + } else { + yaffs_ExtendedTags t; + nandmtd2_ReadChunkWithTagsFromNAND(dev, + blockNo * + dev->nChunksPerBlock, NULL, + &t); + + if (t.chunkUsed) { + *sequenceNumber = t.sequenceNumber; + *state = YAFFS_BLOCK_STATE_NEEDS_SCANNING; + } else { + *sequenceNumber = 0; + *state = YAFFS_BLOCK_STATE_EMPTY; + } + } + T(YAFFS_TRACE_MTD, + (TSTR("block is bad seq %d state %d" TENDSTR), *sequenceNumber, + *state)); + + if (retval == 0) + return YAFFS_OK; + else + return YAFFS_FAIL; +} + --- /dev/null +++ linux-2.6.20/fs/yaffs2/yaffs_mtdif2.h @@ -0,0 +1,29 @@ +/* + * YAFFS: Yet another Flash File System . A NAND-flash specific file system. + * + * Copyright (C) 2002-2007 Aleph One Ltd. + * for Toby Churchill Ltd and Brightstar Engineering + * + * Created by Charles Manning + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 2.1 as + * published by the Free Software Foundation. + * + * Note: Only YAFFS headers are LGPL, YAFFS C code is covered by GPL. + */ + +#ifndef __YAFFS_MTDIF2_H__ +#define __YAFFS_MTDIF2_H__ + +#include "yaffs_guts.h" +int nandmtd2_WriteChunkWithTagsToNAND(yaffs_Device * dev, int chunkInNAND, + const __u8 * data, + const yaffs_ExtendedTags * tags); +int nandmtd2_ReadChunkWithTagsFromNAND(yaffs_Device * dev, int chunkInNAND, + __u8 * data, yaffs_ExtendedTags * tags); +int nandmtd2_MarkNANDBlockBad(struct yaffs_DeviceStruct *dev, int blockNo); +int nandmtd2_QueryNANDBlock(struct yaffs_DeviceStruct *dev, int blockNo, + yaffs_BlockState * state, int *sequenceNumber); + +#endif --- /dev/null +++ linux-2.6.20/fs/yaffs2/yaffs_nand.c @@ -0,0 +1,134 @@ +/* + * YAFFS: Yet Another Flash File System. A NAND-flash specific file system. + * + * Copyright (C) 2002-2007 Aleph One Ltd. + * for Toby Churchill Ltd and Brightstar Engineering + * + * Created by Charles Manning + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +const char *yaffs_nand_c_version = + "$Id: yaffs_nand.c,v 1.8 2007/12/13 15:35:18 wookey Exp $"; + +#include "yaffs_nand.h" +#include "yaffs_tagscompat.h" +#include "yaffs_tagsvalidity.h" + + +int yaffs_ReadChunkWithTagsFromNAND(yaffs_Device * dev, int chunkInNAND, + __u8 * buffer, + yaffs_ExtendedTags * tags) +{ + int result; + yaffs_ExtendedTags localTags; + + int realignedChunkInNAND = chunkInNAND - dev->chunkOffset; + + /* If there are no tags provided, use local tags to get prioritised gc working */ + if(!tags) + tags = &localTags; + + if (dev->readChunkWithTagsFromNAND) + result = dev->readChunkWithTagsFromNAND(dev, realignedChunkInNAND, buffer, + tags); + else + result = yaffs_TagsCompatabilityReadChunkWithTagsFromNAND(dev, + realignedChunkInNAND, + buffer, + tags); + if(tags && + tags->eccResult > YAFFS_ECC_RESULT_NO_ERROR){ + + yaffs_BlockInfo *bi = yaffs_GetBlockInfo(dev, chunkInNAND/dev->nChunksPerBlock); + yaffs_HandleChunkError(dev,bi); + } + + return result; +} + +int yaffs_WriteChunkWithTagsToNAND(yaffs_Device * dev, + int chunkInNAND, + const __u8 * buffer, + yaffs_ExtendedTags * tags) +{ + chunkInNAND -= dev->chunkOffset; + + + if (tags) { + tags->sequenceNumber = dev->sequenceNumber; + tags->chunkUsed = 1; + if (!yaffs_ValidateTags(tags)) { + T(YAFFS_TRACE_ERROR, + (TSTR("Writing uninitialised tags" TENDSTR))); + YBUG(); + } + T(YAFFS_TRACE_WRITE, + (TSTR("Writing chunk %d tags %d %d" TENDSTR), chunkInNAND, + tags->objectId, tags->chunkId)); + } else { + T(YAFFS_TRACE_ERROR, (TSTR("Writing with no tags" TENDSTR))); + YBUG(); + } + + if (dev->writeChunkWithTagsToNAND) + return dev->writeChunkWithTagsToNAND(dev, chunkInNAND, buffer, + tags); + else + return yaffs_TagsCompatabilityWriteChunkWithTagsToNAND(dev, + chunkInNAND, + buffer, + tags); +} + +int yaffs_MarkBlockBad(yaffs_Device * dev, int blockNo) +{ + blockNo -= dev->blockOffset; + +; + if (dev->markNANDBlockBad) + return dev->markNANDBlockBad(dev, blockNo); + else + return yaffs_TagsCompatabilityMarkNANDBlockBad(dev, blockNo); +} + +int yaffs_QueryInitialBlockState(yaffs_Device * dev, + int blockNo, + yaffs_BlockState * state, + unsigned *sequenceNumber) +{ + blockNo -= dev->blockOffset; + + if (dev->queryNANDBlock) + return dev->queryNANDBlock(dev, blockNo, state, sequenceNumber); + else + return yaffs_TagsCompatabilityQueryNANDBlock(dev, blockNo, + state, + sequenceNumber); +} + + +int yaffs_EraseBlockInNAND(struct yaffs_DeviceStruct *dev, + int blockInNAND) +{ + int result; + + blockInNAND -= dev->blockOffset; + + + dev->nBlockErasures++; + result = dev->eraseBlockInNAND(dev, blockInNAND); + + return result; +} + +int yaffs_InitialiseNAND(struct yaffs_DeviceStruct *dev) +{ + return dev->initialiseNAND(dev); +} + + + --- /dev/null +++ linux-2.6.20/fs/yaffs2/yaffs_nand.h @@ -0,0 +1,44 @@ +/* + * YAFFS: Yet another Flash File System . A NAND-flash specific file system. + * + * Copyright (C) 2002-2007 Aleph One Ltd. + * for Toby Churchill Ltd and Brightstar Engineering + * + * Created by Charles Manning + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 2.1 as + * published by the Free Software Foundation. + * + * Note: Only YAFFS headers are LGPL, YAFFS C code is covered by GPL. + */ + +#ifndef __YAFFS_NAND_H__ +#define __YAFFS_NAND_H__ +#include "yaffs_guts.h" + + + +int yaffs_ReadChunkWithTagsFromNAND(yaffs_Device * dev, int chunkInNAND, + __u8 * buffer, + yaffs_ExtendedTags * tags); + +int yaffs_WriteChunkWithTagsToNAND(yaffs_Device * dev, + int chunkInNAND, + const __u8 * buffer, + yaffs_ExtendedTags * tags); + +int yaffs_MarkBlockBad(yaffs_Device * dev, int blockNo); + +int yaffs_QueryInitialBlockState(yaffs_Device * dev, + int blockNo, + yaffs_BlockState * state, + unsigned *sequenceNumber); + +int yaffs_EraseBlockInNAND(struct yaffs_DeviceStruct *dev, + int blockInNAND); + +int yaffs_InitialiseNAND(struct yaffs_DeviceStruct *dev); + +#endif + --- /dev/null +++ linux-2.6.20/fs/yaffs2/yaffs_nandemul2k.h @@ -0,0 +1,39 @@ +/* + * YAFFS: Yet another Flash File System . A NAND-flash specific file system. + * + * Copyright (C) 2002-2007 Aleph One Ltd. + * for Toby Churchill Ltd and Brightstar Engineering + * + * Created by Charles Manning + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 2.1 as + * published by the Free Software Foundation. + * + * Note: Only YAFFS headers are LGPL, YAFFS C code is covered by GPL. + */ + +/* Interface to emulated NAND functions (2k page size) */ + +#ifndef __YAFFS_NANDEMUL2K_H__ +#define __YAFFS_NANDEMUL2K_H__ + +#include "yaffs_guts.h" + +int nandemul2k_WriteChunkWithTagsToNAND(struct yaffs_DeviceStruct *dev, + int chunkInNAND, const __u8 * data, + yaffs_ExtendedTags * tags); +int nandemul2k_ReadChunkWithTagsFromNAND(struct yaffs_DeviceStruct *dev, + int chunkInNAND, __u8 * data, + yaffs_ExtendedTags * tags); +int nandemul2k_MarkNANDBlockBad(struct yaffs_DeviceStruct *dev, int blockNo); +int nandemul2k_QueryNANDBlock(struct yaffs_DeviceStruct *dev, int blockNo, + yaffs_BlockState * state, int *sequenceNumber); +int nandemul2k_EraseBlockInNAND(struct yaffs_DeviceStruct *dev, + int blockInNAND); +int nandemul2k_InitialiseNAND(struct yaffs_DeviceStruct *dev); +int nandemul2k_GetBytesPerChunk(void); +int nandemul2k_GetChunksPerBlock(void); +int nandemul2k_GetNumberOfBlocks(void); + +#endif --- /dev/null +++ linux-2.6.20/fs/yaffs2/yaffs_packedtags1.c @@ -0,0 +1,52 @@ +/* + * YAFFS: Yet Another Flash File System. A NAND-flash specific file system. + * + * Copyright (C) 2002-2007 Aleph One Ltd. + * for Toby Churchill Ltd and Brightstar Engineering + * + * Created by Charles Manning + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include "yaffs_packedtags1.h" +#include "yportenv.h" + +void yaffs_PackTags1(yaffs_PackedTags1 * pt, const yaffs_ExtendedTags * t) +{ + pt->chunkId = t->chunkId; + pt->serialNumber = t->serialNumber; + pt->byteCount = t->byteCount; + pt->objectId = t->objectId; + pt->ecc = 0; + pt->deleted = (t->chunkDeleted) ? 0 : 1; + pt->unusedStuff = 0; + pt->shouldBeFF = 0xFFFFFFFF; + +} + +void yaffs_UnpackTags1(yaffs_ExtendedTags * t, const yaffs_PackedTags1 * pt) +{ + static const __u8 allFF[] = + { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff }; + + if (memcmp(allFF, pt, sizeof(yaffs_PackedTags1))) { + t->blockBad = 0; + if (pt->shouldBeFF != 0xFFFFFFFF) { + t->blockBad = 1; + } + t->chunkUsed = 1; + t->objectId = pt->objectId; + t->chunkId = pt->chunkId; + t->byteCount = pt->byteCount; + t->eccResult = YAFFS_ECC_RESULT_NO_ERROR; + t->chunkDeleted = (pt->deleted) ? 0 : 1; + t->serialNumber = pt->serialNumber; + } else { + memset(t, 0, sizeof(yaffs_ExtendedTags)); + + } +} --- /dev/null +++ linux-2.6.20/fs/yaffs2/yaffs_packedtags1.h @@ -0,0 +1,37 @@ +/* + * YAFFS: Yet another Flash File System . A NAND-flash specific file system. + * + * Copyright (C) 2002-2007 Aleph One Ltd. + * for Toby Churchill Ltd and Brightstar Engineering + * + * Created by Charles Manning + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 2.1 as + * published by the Free Software Foundation. + * + * Note: Only YAFFS headers are LGPL, YAFFS C code is covered by GPL. + */ + +/* This is used to pack YAFFS1 tags, not YAFFS2 tags. */ + +#ifndef __YAFFS_PACKEDTAGS1_H__ +#define __YAFFS_PACKEDTAGS1_H__ + +#include "yaffs_guts.h" + +typedef struct { + unsigned chunkId:20; + unsigned serialNumber:2; + unsigned byteCount:10; + unsigned objectId:18; + unsigned ecc:12; + unsigned deleted:1; + unsigned unusedStuff:1; + unsigned shouldBeFF; + +} yaffs_PackedTags1; + +void yaffs_PackTags1(yaffs_PackedTags1 * pt, const yaffs_ExtendedTags * t); +void yaffs_UnpackTags1(yaffs_ExtendedTags * t, const yaffs_PackedTags1 * pt); +#endif --- /dev/null +++ linux-2.6.20/fs/yaffs2/yaffs_packedtags2.c @@ -0,0 +1,182 @@ +/* + * YAFFS: Yet Another Flash File System. A NAND-flash specific file system. + * + * Copyright (C) 2002-2007 Aleph One Ltd. + * for Toby Churchill Ltd and Brightstar Engineering + * + * Created by Charles Manning + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include "yaffs_packedtags2.h" +#include "yportenv.h" +#include "yaffs_tagsvalidity.h" + +/* This code packs a set of extended tags into a binary structure for + * NAND storage + */ + +/* Some of the information is "extra" struff which can be packed in to + * speed scanning + * This is defined by having the EXTRA_HEADER_INFO_FLAG set. + */ + +/* Extra flags applied to chunkId */ + +#define EXTRA_HEADER_INFO_FLAG 0x80000000 +#define EXTRA_SHRINK_FLAG 0x40000000 +#define EXTRA_SHADOWS_FLAG 0x20000000 +#define EXTRA_SPARE_FLAGS 0x10000000 + +#define ALL_EXTRA_FLAGS 0xF0000000 + +/* Also, the top 4 bits of the object Id are set to the object type. */ +#define EXTRA_OBJECT_TYPE_SHIFT (28) +#define EXTRA_OBJECT_TYPE_MASK ((0x0F) << EXTRA_OBJECT_TYPE_SHIFT) + +static void yaffs_DumpPackedTags2(const yaffs_PackedTags2 * pt) +{ + T(YAFFS_TRACE_MTD, + (TSTR("packed tags obj %d chunk %d byte %d seq %d" TENDSTR), + pt->t.objectId, pt->t.chunkId, pt->t.byteCount, + pt->t.sequenceNumber)); +} + +static void yaffs_DumpTags2(const yaffs_ExtendedTags * t) +{ + T(YAFFS_TRACE_MTD, + (TSTR + ("ext.tags eccres %d blkbad %d chused %d obj %d chunk%d byte " + "%d del %d ser %d seq %d" + TENDSTR), t->eccResult, t->blockBad, t->chunkUsed, t->objectId, + t->chunkId, t->byteCount, t->chunkDeleted, t->serialNumber, + t->sequenceNumber)); + +} + +void yaffs_PackTags2(yaffs_PackedTags2 * pt, const yaffs_ExtendedTags * t) +{ + pt->t.chunkId = t->chunkId; + pt->t.sequenceNumber = t->sequenceNumber; + pt->t.byteCount = t->byteCount; + pt->t.objectId = t->objectId; + + if (t->chunkId == 0 && t->extraHeaderInfoAvailable) { + /* Store the extra header info instead */ + /* We save the parent object in the chunkId */ + pt->t.chunkId = EXTRA_HEADER_INFO_FLAG + | t->extraParentObjectId; + if (t->extraIsShrinkHeader) { + pt->t.chunkId |= EXTRA_SHRINK_FLAG; + } + if (t->extraShadows) { + pt->t.chunkId |= EXTRA_SHADOWS_FLAG; + } + + pt->t.objectId &= ~EXTRA_OBJECT_TYPE_MASK; + pt->t.objectId |= + (t->extraObjectType << EXTRA_OBJECT_TYPE_SHIFT); + + if (t->extraObjectType == YAFFS_OBJECT_TYPE_HARDLINK) { + pt->t.byteCount = t->extraEquivalentObjectId; + } else if (t->extraObjectType == YAFFS_OBJECT_TYPE_FILE) { + pt->t.byteCount = t->extraFileLength; + } else { + pt->t.byteCount = 0; + } + } + + yaffs_DumpPackedTags2(pt); + yaffs_DumpTags2(t); + +#ifndef YAFFS_IGNORE_TAGS_ECC + { + yaffs_ECCCalculateOther((unsigned char *)&pt->t, + sizeof(yaffs_PackedTags2TagsPart), + &pt->ecc); + } +#endif +} + +void yaffs_UnpackTags2(yaffs_ExtendedTags * t, yaffs_PackedTags2 * pt) +{ + + memset(t, 0, sizeof(yaffs_ExtendedTags)); + + yaffs_InitialiseTags(t); + + if (pt->t.sequenceNumber != 0xFFFFFFFF) { + /* Page is in use */ +#ifdef YAFFS_IGNORE_TAGS_ECC + { + t->eccResult = YAFFS_ECC_RESULT_NO_ERROR; + } +#else + { + yaffs_ECCOther ecc; + int result; + yaffs_ECCCalculateOther((unsigned char *)&pt->t, + sizeof + (yaffs_PackedTags2TagsPart), + &ecc); + result = + yaffs_ECCCorrectOther((unsigned char *)&pt->t, + sizeof + (yaffs_PackedTags2TagsPart), + &pt->ecc, &ecc); + switch(result){ + case 0: + t->eccResult = YAFFS_ECC_RESULT_NO_ERROR; + break; + case 1: + t->eccResult = YAFFS_ECC_RESULT_FIXED; + break; + case -1: + t->eccResult = YAFFS_ECC_RESULT_UNFIXED; + break; + default: + t->eccResult = YAFFS_ECC_RESULT_UNKNOWN; + } + } +#endif + t->blockBad = 0; + t->chunkUsed = 1; + t->objectId = pt->t.objectId; + t->chunkId = pt->t.chunkId; + t->byteCount = pt->t.byteCount; + t->chunkDeleted = 0; + t->serialNumber = 0; + t->sequenceNumber = pt->t.sequenceNumber; + + /* Do extra header info stuff */ + + if (pt->t.chunkId & EXTRA_HEADER_INFO_FLAG) { + t->chunkId = 0; + t->byteCount = 0; + + t->extraHeaderInfoAvailable = 1; + t->extraParentObjectId = + pt->t.chunkId & (~(ALL_EXTRA_FLAGS)); + t->extraIsShrinkHeader = + (pt->t.chunkId & EXTRA_SHRINK_FLAG) ? 1 : 0; + t->extraShadows = + (pt->t.chunkId & EXTRA_SHADOWS_FLAG) ? 1 : 0; + t->extraObjectType = + pt->t.objectId >> EXTRA_OBJECT_TYPE_SHIFT; + t->objectId &= ~EXTRA_OBJECT_TYPE_MASK; + + if (t->extraObjectType == YAFFS_OBJECT_TYPE_HARDLINK) { + t->extraEquivalentObjectId = pt->t.byteCount; + } else { + t->extraFileLength = pt->t.byteCount; + } + } + } + + yaffs_DumpPackedTags2(pt); + yaffs_DumpTags2(t); + +} --- /dev/null +++ linux-2.6.20/fs/yaffs2/yaffs_packedtags2.h @@ -0,0 +1,38 @@ +/* + * YAFFS: Yet another Flash File System . A NAND-flash specific file system. + * + * Copyright (C) 2002-2007 Aleph One Ltd. + * for Toby Churchill Ltd and Brightstar Engineering + * + * Created by Charles Manning + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 2.1 as + * published by the Free Software Foundation. + * + * Note: Only YAFFS headers are LGPL, YAFFS C code is covered by GPL. + */ + +/* This is used to pack YAFFS2 tags, not YAFFS1tags. */ + +#ifndef __YAFFS_PACKEDTAGS2_H__ +#define __YAFFS_PACKEDTAGS2_H__ + +#include "yaffs_guts.h" +#include "yaffs_ecc.h" + +typedef struct { + unsigned sequenceNumber; + unsigned objectId; + unsigned chunkId; + unsigned byteCount; +} yaffs_PackedTags2TagsPart; + +typedef struct { + yaffs_PackedTags2TagsPart t; + yaffs_ECCOther ecc; +} yaffs_PackedTags2; + +void yaffs_PackTags2(yaffs_PackedTags2 * pt, const yaffs_ExtendedTags * t); +void yaffs_UnpackTags2(yaffs_ExtendedTags * t, yaffs_PackedTags2 * pt); +#endif --- /dev/null +++ linux-2.6.20/fs/yaffs2/yaffs_qsort.c @@ -0,0 +1,160 @@ +/* + * Copyright (c) 1992, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "yportenv.h" +//#include + +/* + * Qsort routine from Bentley & McIlroy's "Engineering a Sort Function". + */ +#define swapcode(TYPE, parmi, parmj, n) { \ + long i = (n) / sizeof (TYPE); \ + register TYPE *pi = (TYPE *) (parmi); \ + register TYPE *pj = (TYPE *) (parmj); \ + do { \ + register TYPE t = *pi; \ + *pi++ = *pj; \ + *pj++ = t; \ + } while (--i > 0); \ +} + +#define SWAPINIT(a, es) swaptype = ((char *)a - (char *)0) % sizeof(long) || \ + es % sizeof(long) ? 2 : es == sizeof(long)? 0 : 1; + +static __inline void +swapfunc(char *a, char *b, int n, int swaptype) +{ + if (swaptype <= 1) + swapcode(long, a, b, n) + else + swapcode(char, a, b, n) +} + +#define swap(a, b) \ + if (swaptype == 0) { \ + long t = *(long *)(a); \ + *(long *)(a) = *(long *)(b); \ + *(long *)(b) = t; \ + } else \ + swapfunc(a, b, es, swaptype) + +#define vecswap(a, b, n) if ((n) > 0) swapfunc(a, b, n, swaptype) + +static __inline char * +med3(char *a, char *b, char *c, int (*cmp)(const void *, const void *)) +{ + return cmp(a, b) < 0 ? + (cmp(b, c) < 0 ? b : (cmp(a, c) < 0 ? c : a )) + :(cmp(b, c) > 0 ? b : (cmp(a, c) < 0 ? a : c )); +} + +#ifndef min +#define min(a,b) (((a) < (b)) ? (a) : (b)) +#endif + +void +yaffs_qsort(void *aa, size_t n, size_t es, + int (*cmp)(const void *, const void *)) +{ + char *pa, *pb, *pc, *pd, *pl, *pm, *pn; + int d, r, swaptype, swap_cnt; + register char *a = aa; + +loop: SWAPINIT(a, es); + swap_cnt = 0; + if (n < 7) { + for (pm = (char *)a + es; pm < (char *) a + n * es; pm += es) + for (pl = pm; pl > (char *) a && cmp(pl - es, pl) > 0; + pl -= es) + swap(pl, pl - es); + return; + } + pm = (char *)a + (n / 2) * es; + if (n > 7) { + pl = (char *)a; + pn = (char *)a + (n - 1) * es; + if (n > 40) { + d = (n / 8) * es; + pl = med3(pl, pl + d, pl + 2 * d, cmp); + pm = med3(pm - d, pm, pm + d, cmp); + pn = med3(pn - 2 * d, pn - d, pn, cmp); + } + pm = med3(pl, pm, pn, cmp); + } + swap(a, pm); + pa = pb = (char *)a + es; + + pc = pd = (char *)a + (n - 1) * es; + for (;;) { + while (pb <= pc && (r = cmp(pb, a)) <= 0) { + if (r == 0) { + swap_cnt = 1; + swap(pa, pb); + pa += es; + } + pb += es; + } + while (pb <= pc && (r = cmp(pc, a)) >= 0) { + if (r == 0) { + swap_cnt = 1; + swap(pc, pd); + pd -= es; + } + pc -= es; + } + if (pb > pc) + break; + swap(pb, pc); + swap_cnt = 1; + pb += es; + pc -= es; + } + if (swap_cnt == 0) { /* Switch to insertion sort */ + for (pm = (char *) a + es; pm < (char *) a + n * es; pm += es) + for (pl = pm; pl > (char *) a && cmp(pl - es, pl) > 0; + pl -= es) + swap(pl, pl - es); + return; + } + + pn = (char *)a + n * es; + r = min(pa - (char *)a, pb - pa); + vecswap(a, pb - r, r); + r = min((long)(pd - pc), (long)(pn - pd - es)); + vecswap(pb, pn - r, r); + if ((r = pb - pa) > es) + yaffs_qsort(a, r / es, es, cmp); + if ((r = pd - pc) > es) { + /* Iterate rather than recurse to save stack space */ + a = pn - r; + n = r / es; + goto loop; + } +/* yaffs_qsort(pn - r, r / es, es, cmp);*/ +} --- /dev/null +++ linux-2.6.20/fs/yaffs2/yaffs_qsort.h @@ -0,0 +1,23 @@ +/* + * YAFFS: Yet another Flash File System . A NAND-flash specific file system. + * + * Copyright (C) 2002-2007 Aleph One Ltd. + * for Toby Churchill Ltd and Brightstar Engineering + * + * Created by Charles Manning + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 2.1 as + * published by the Free Software Foundation. + * + * Note: Only YAFFS headers are LGPL, YAFFS C code is covered by GPL. + */ + + +#ifndef __YAFFS_QSORT_H__ +#define __YAFFS_QSORT_H__ + +extern void yaffs_qsort (void *const base, size_t total_elems, size_t size, + int (*cmp)(const void *, const void *)); + +#endif --- /dev/null +++ linux-2.6.20/fs/yaffs2/yaffs_tagscompat.c @@ -0,0 +1,530 @@ +/* + * YAFFS: Yet Another Flash File System. A NAND-flash specific file system. + * + * Copyright (C) 2002-2007 Aleph One Ltd. + * for Toby Churchill Ltd and Brightstar Engineering + * + * Created by Charles Manning + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include "yaffs_guts.h" +#include "yaffs_tagscompat.h" +#include "yaffs_ecc.h" + +static void yaffs_HandleReadDataError(yaffs_Device * dev, int chunkInNAND); +#ifdef NOTYET +static void yaffs_CheckWrittenBlock(yaffs_Device * dev, int chunkInNAND); +static void yaffs_HandleWriteChunkOk(yaffs_Device * dev, int chunkInNAND, + const __u8 * data, + const yaffs_Spare * spare); +static void yaffs_HandleUpdateChunk(yaffs_Device * dev, int chunkInNAND, + const yaffs_Spare * spare); +static void yaffs_HandleWriteChunkError(yaffs_Device * dev, int chunkInNAND); +#endif + +static const char yaffs_countBitsTable[256] = { + 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, + 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, + 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, + 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, + 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, + 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8 +}; + +int yaffs_CountBits(__u8 x) +{ + int retVal; + retVal = yaffs_countBitsTable[x]; + return retVal; +} + +/********** Tags ECC calculations *********/ + +void yaffs_CalcECC(const __u8 * data, yaffs_Spare * spare) +{ + yaffs_ECCCalculate(data, spare->ecc1); + yaffs_ECCCalculate(&data[256], spare->ecc2); +} + +void yaffs_CalcTagsECC(yaffs_Tags * tags) +{ + /* Calculate an ecc */ + + unsigned char *b = ((yaffs_TagsUnion *) tags)->asBytes; + unsigned i, j; + unsigned ecc = 0; + unsigned bit = 0; + + tags->ecc = 0; + + for (i = 0; i < 8; i++) { + for (j = 1; j & 0xff; j <<= 1) { + bit++; + if (b[i] & j) { + ecc ^= bit; + } + } + } + + tags->ecc = ecc; + +} + +int yaffs_CheckECCOnTags(yaffs_Tags * tags) +{ + unsigned ecc = tags->ecc; + + yaffs_CalcTagsECC(tags); + + ecc ^= tags->ecc; + + if (ecc && ecc <= 64) { + /* TODO: Handle the failure better. Retire? */ + unsigned char *b = ((yaffs_TagsUnion *) tags)->asBytes; + + ecc--; + + b[ecc / 8] ^= (1 << (ecc & 7)); + + /* Now recvalc the ecc */ + yaffs_CalcTagsECC(tags); + + return 1; /* recovered error */ + } else if (ecc) { + /* Wierd ecc failure value */ + /* TODO Need to do somethiong here */ + return -1; /* unrecovered error */ + } + + return 0; +} + +/********** Tags **********/ + +static void yaffs_LoadTagsIntoSpare(yaffs_Spare * sparePtr, + yaffs_Tags * tagsPtr) +{ + yaffs_TagsUnion *tu = (yaffs_TagsUnion *) tagsPtr; + + yaffs_CalcTagsECC(tagsPtr); + + sparePtr->tagByte0 = tu->asBytes[0]; + sparePtr->tagByte1 = tu->asBytes[1]; + sparePtr->tagByte2 = tu->asBytes[2]; + sparePtr->tagByte3 = tu->asBytes[3]; + sparePtr->tagByte4 = tu->asBytes[4]; + sparePtr->tagByte5 = tu->asBytes[5]; + sparePtr->tagByte6 = tu->asBytes[6]; + sparePtr->tagByte7 = tu->asBytes[7]; +} + +static void yaffs_GetTagsFromSpare(yaffs_Device * dev, yaffs_Spare * sparePtr, + yaffs_Tags * tagsPtr) +{ + yaffs_TagsUnion *tu = (yaffs_TagsUnion *) tagsPtr; + int result; + + tu->asBytes[0] = sparePtr->tagByte0; + tu->asBytes[1] = sparePtr->tagByte1; + tu->asBytes[2] = sparePtr->tagByte2; + tu->asBytes[3] = sparePtr->tagByte3; + tu->asBytes[4] = sparePtr->tagByte4; + tu->asBytes[5] = sparePtr->tagByte5; + tu->asBytes[6] = sparePtr->tagByte6; + tu->asBytes[7] = sparePtr->tagByte7; + + result = yaffs_CheckECCOnTags(tagsPtr); + if (result > 0) { + dev->tagsEccFixed++; + } else if (result < 0) { + dev->tagsEccUnfixed++; + } +} + +static void yaffs_SpareInitialise(yaffs_Spare * spare) +{ + memset(spare, 0xFF, sizeof(yaffs_Spare)); +} + +static int yaffs_WriteChunkToNAND(struct yaffs_DeviceStruct *dev, + int chunkInNAND, const __u8 * data, + yaffs_Spare * spare) +{ + if (chunkInNAND < dev->startBlock * dev->nChunksPerBlock) { + T(YAFFS_TRACE_ERROR, + (TSTR("**>> yaffs chunk %d is not valid" TENDSTR), + chunkInNAND)); + return YAFFS_FAIL; + } + + dev->nPageWrites++; + return dev->writeChunkToNAND(dev, chunkInNAND, data, spare); +} + +static int yaffs_ReadChunkFromNAND(struct yaffs_DeviceStruct *dev, + int chunkInNAND, + __u8 * data, + yaffs_Spare * spare, + yaffs_ECCResult * eccResult, + int doErrorCorrection) +{ + int retVal; + yaffs_Spare localSpare; + + dev->nPageReads++; + + if (!spare && data) { + /* If we don't have a real spare, then we use a local one. */ + /* Need this for the calculation of the ecc */ + spare = &localSpare; + } + + if (!dev->useNANDECC) { + retVal = dev->readChunkFromNAND(dev, chunkInNAND, data, spare); + if (data && doErrorCorrection) { + /* Do ECC correction */ + /* Todo handle any errors */ + int eccResult1, eccResult2; + __u8 calcEcc[3]; + + yaffs_ECCCalculate(data, calcEcc); + eccResult1 = + yaffs_ECCCorrect(data, spare->ecc1, calcEcc); + yaffs_ECCCalculate(&data[256], calcEcc); + eccResult2 = + yaffs_ECCCorrect(&data[256], spare->ecc2, calcEcc); + + if (eccResult1 > 0) { + T(YAFFS_TRACE_ERROR, + (TSTR + ("**>>yaffs ecc error fix performed on chunk %d:0" + TENDSTR), chunkInNAND)); + dev->eccFixed++; + } else if (eccResult1 < 0) { + T(YAFFS_TRACE_ERROR, + (TSTR + ("**>>yaffs ecc error unfixed on chunk %d:0" + TENDSTR), chunkInNAND)); + dev->eccUnfixed++; + } + + if (eccResult2 > 0) { + T(YAFFS_TRACE_ERROR, + (TSTR + ("**>>yaffs ecc error fix performed on chunk %d:1" + TENDSTR), chunkInNAND)); + dev->eccFixed++; + } else if (eccResult2 < 0) { + T(YAFFS_TRACE_ERROR, + (TSTR + ("**>>yaffs ecc error unfixed on chunk %d:1" + TENDSTR), chunkInNAND)); + dev->eccUnfixed++; + } + + if (eccResult1 || eccResult2) { + /* We had a data problem on this page */ + yaffs_HandleReadDataError(dev, chunkInNAND); + } + + if (eccResult1 < 0 || eccResult2 < 0) + *eccResult = YAFFS_ECC_RESULT_UNFIXED; + else if (eccResult1 > 0 || eccResult2 > 0) + *eccResult = YAFFS_ECC_RESULT_FIXED; + else + *eccResult = YAFFS_ECC_RESULT_NO_ERROR; + } + } else { + /* Must allocate enough memory for spare+2*sizeof(int) */ + /* for ecc results from device. */ + struct yaffs_NANDSpare nspare; + retVal = + dev->readChunkFromNAND(dev, chunkInNAND, data, + (yaffs_Spare *) & nspare); + memcpy(spare, &nspare, sizeof(yaffs_Spare)); + if (data && doErrorCorrection) { + if (nspare.eccres1 > 0) { + T(YAFFS_TRACE_ERROR, + (TSTR + ("**>>mtd ecc error fix performed on chunk %d:0" + TENDSTR), chunkInNAND)); + } else if (nspare.eccres1 < 0) { + T(YAFFS_TRACE_ERROR, + (TSTR + ("**>>mtd ecc error unfixed on chunk %d:0" + TENDSTR), chunkInNAND)); + } + + if (nspare.eccres2 > 0) { + T(YAFFS_TRACE_ERROR, + (TSTR + ("**>>mtd ecc error fix performed on chunk %d:1" + TENDSTR), chunkInNAND)); + } else if (nspare.eccres2 < 0) { + T(YAFFS_TRACE_ERROR, + (TSTR + ("**>>mtd ecc error unfixed on chunk %d:1" + TENDSTR), chunkInNAND)); + } + + if (nspare.eccres1 || nspare.eccres2) { + /* We had a data problem on this page */ + yaffs_HandleReadDataError(dev, chunkInNAND); + } + + if (nspare.eccres1 < 0 || nspare.eccres2 < 0) + *eccResult = YAFFS_ECC_RESULT_UNFIXED; + else if (nspare.eccres1 > 0 || nspare.eccres2 > 0) + *eccResult = YAFFS_ECC_RESULT_FIXED; + else + *eccResult = YAFFS_ECC_RESULT_NO_ERROR; + + } + } + return retVal; +} + +#ifdef NOTYET +static int yaffs_CheckChunkErased(struct yaffs_DeviceStruct *dev, + int chunkInNAND) +{ + + static int init = 0; + static __u8 cmpbuf[YAFFS_BYTES_PER_CHUNK]; + static __u8 data[YAFFS_BYTES_PER_CHUNK]; + /* Might as well always allocate the larger size for */ + /* dev->useNANDECC == true; */ + static __u8 spare[sizeof(struct yaffs_NANDSpare)]; + + dev->readChunkFromNAND(dev, chunkInNAND, data, (yaffs_Spare *) spare); + + if (!init) { + memset(cmpbuf, 0xff, YAFFS_BYTES_PER_CHUNK); + init = 1; + } + + if (memcmp(cmpbuf, data, YAFFS_BYTES_PER_CHUNK)) + return YAFFS_FAIL; + if (memcmp(cmpbuf, spare, 16)) + return YAFFS_FAIL; + + return YAFFS_OK; + +} +#endif + +/* + * Functions for robustisizing + */ + +static void yaffs_HandleReadDataError(yaffs_Device * dev, int chunkInNAND) +{ + int blockInNAND = chunkInNAND / dev->nChunksPerBlock; + + /* Mark the block for retirement */ + yaffs_GetBlockInfo(dev, blockInNAND)->needsRetiring = 1; + T(YAFFS_TRACE_ERROR | YAFFS_TRACE_BAD_BLOCKS, + (TSTR("**>>Block %d marked for retirement" TENDSTR), blockInNAND)); + + /* TODO: + * Just do a garbage collection on the affected block + * then retire the block + * NB recursion + */ +} + +#ifdef NOTYET +static void yaffs_CheckWrittenBlock(yaffs_Device * dev, int chunkInNAND) +{ +} + +static void yaffs_HandleWriteChunkOk(yaffs_Device * dev, int chunkInNAND, + const __u8 * data, + const yaffs_Spare * spare) +{ +} + +static void yaffs_HandleUpdateChunk(yaffs_Device * dev, int chunkInNAND, + const yaffs_Spare * spare) +{ +} + +static void yaffs_HandleWriteChunkError(yaffs_Device * dev, int chunkInNAND) +{ + int blockInNAND = chunkInNAND / dev->nChunksPerBlock; + + /* Mark the block for retirement */ + yaffs_GetBlockInfo(dev, blockInNAND)->needsRetiring = 1; + /* Delete the chunk */ + yaffs_DeleteChunk(dev, chunkInNAND, 1, __LINE__); +} + +static int yaffs_VerifyCompare(const __u8 * d0, const __u8 * d1, + const yaffs_Spare * s0, const yaffs_Spare * s1) +{ + + if (memcmp(d0, d1, YAFFS_BYTES_PER_CHUNK) != 0 || + s0->tagByte0 != s1->tagByte0 || + s0->tagByte1 != s1->tagByte1 || + s0->tagByte2 != s1->tagByte2 || + s0->tagByte3 != s1->tagByte3 || + s0->tagByte4 != s1->tagByte4 || + s0->tagByte5 != s1->tagByte5 || + s0->tagByte6 != s1->tagByte6 || + s0->tagByte7 != s1->tagByte7 || + s0->ecc1[0] != s1->ecc1[0] || + s0->ecc1[1] != s1->ecc1[1] || + s0->ecc1[2] != s1->ecc1[2] || + s0->ecc2[0] != s1->ecc2[0] || + s0->ecc2[1] != s1->ecc2[1] || s0->ecc2[2] != s1->ecc2[2]) { + return 0; + } + + return 1; +} +#endif /* NOTYET */ + +int yaffs_TagsCompatabilityWriteChunkWithTagsToNAND(yaffs_Device * dev, + int chunkInNAND, + const __u8 * data, + const yaffs_ExtendedTags * + eTags) +{ + yaffs_Spare spare; + yaffs_Tags tags; + + yaffs_SpareInitialise(&spare); + + if (eTags->chunkDeleted) { + spare.pageStatus = 0; + } else { + tags.objectId = eTags->objectId; + tags.chunkId = eTags->chunkId; + tags.byteCount = eTags->byteCount; + tags.serialNumber = eTags->serialNumber; + + if (!dev->useNANDECC && data) { + yaffs_CalcECC(data, &spare); + } + yaffs_LoadTagsIntoSpare(&spare, &tags); + + } + + return yaffs_WriteChunkToNAND(dev, chunkInNAND, data, &spare); +} + +int yaffs_TagsCompatabilityReadChunkWithTagsFromNAND(yaffs_Device * dev, + int chunkInNAND, + __u8 * data, + yaffs_ExtendedTags * eTags) +{ + + yaffs_Spare spare; + yaffs_Tags tags; + yaffs_ECCResult eccResult; + + static yaffs_Spare spareFF; + static int init; + + if (!init) { + memset(&spareFF, 0xFF, sizeof(spareFF)); + init = 1; + } + + if (yaffs_ReadChunkFromNAND + (dev, chunkInNAND, data, &spare, &eccResult, 1)) { + /* eTags may be NULL */ + if (eTags) { + + int deleted = + (yaffs_CountBits(spare.pageStatus) < 7) ? 1 : 0; + + eTags->chunkDeleted = deleted; + eTags->eccResult = eccResult; + eTags->blockBad = 0; /* We're reading it */ + /* therefore it is not a bad block */ + eTags->chunkUsed = + (memcmp(&spareFF, &spare, sizeof(spareFF)) != + 0) ? 1 : 0; + + if (eTags->chunkUsed) { + yaffs_GetTagsFromSpare(dev, &spare, &tags); + + eTags->objectId = tags.objectId; + eTags->chunkId = tags.chunkId; + eTags->byteCount = tags.byteCount; + eTags->serialNumber = tags.serialNumber; + } + } + + return YAFFS_OK; + } else { + return YAFFS_FAIL; + } +} + +int yaffs_TagsCompatabilityMarkNANDBlockBad(struct yaffs_DeviceStruct *dev, + int blockInNAND) +{ + + yaffs_Spare spare; + + memset(&spare, 0xff, sizeof(yaffs_Spare)); + + spare.blockStatus = 'Y'; + + yaffs_WriteChunkToNAND(dev, blockInNAND * dev->nChunksPerBlock, NULL, + &spare); + yaffs_WriteChunkToNAND(dev, blockInNAND * dev->nChunksPerBlock + 1, + NULL, &spare); + + return YAFFS_OK; + +} + +int yaffs_TagsCompatabilityQueryNANDBlock(struct yaffs_DeviceStruct *dev, + int blockNo, yaffs_BlockState * + state, + int *sequenceNumber) +{ + + yaffs_Spare spare0, spare1; + static yaffs_Spare spareFF; + static int init; + yaffs_ECCResult dummy; + + if (!init) { + memset(&spareFF, 0xFF, sizeof(spareFF)); + init = 1; + } + + *sequenceNumber = 0; + + yaffs_ReadChunkFromNAND(dev, blockNo * dev->nChunksPerBlock, NULL, + &spare0, &dummy, 1); + yaffs_ReadChunkFromNAND(dev, blockNo * dev->nChunksPerBlock + 1, NULL, + &spare1, &dummy, 1); + + if (yaffs_CountBits(spare0.blockStatus & spare1.blockStatus) < 7) + *state = YAFFS_BLOCK_STATE_DEAD; + else if (memcmp(&spareFF, &spare0, sizeof(spareFF)) == 0) + *state = YAFFS_BLOCK_STATE_EMPTY; + else + *state = YAFFS_BLOCK_STATE_NEEDS_SCANNING; + + return YAFFS_OK; +} --- /dev/null +++ linux-2.6.20/fs/yaffs2/yaffs_tagscompat.h @@ -0,0 +1,40 @@ +/* + * YAFFS: Yet another Flash File System . A NAND-flash specific file system. + * + * Copyright (C) 2002-2007 Aleph One Ltd. + * for Toby Churchill Ltd and Brightstar Engineering + * + * Created by Charles Manning + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 2.1 as + * published by the Free Software Foundation. + * + * Note: Only YAFFS headers are LGPL, YAFFS C code is covered by GPL. + */ + +#ifndef __YAFFS_TAGSCOMPAT_H__ +#define __YAFFS_TAGSCOMPAT_H__ + +#include "yaffs_guts.h" +int yaffs_TagsCompatabilityWriteChunkWithTagsToNAND(yaffs_Device * dev, + int chunkInNAND, + const __u8 * data, + const yaffs_ExtendedTags * + tags); +int yaffs_TagsCompatabilityReadChunkWithTagsFromNAND(yaffs_Device * dev, + int chunkInNAND, + __u8 * data, + yaffs_ExtendedTags * + tags); +int yaffs_TagsCompatabilityMarkNANDBlockBad(struct yaffs_DeviceStruct *dev, + int blockNo); +int yaffs_TagsCompatabilityQueryNANDBlock(struct yaffs_DeviceStruct *dev, + int blockNo, yaffs_BlockState * + state, int *sequenceNumber); + +void yaffs_CalcTagsECC(yaffs_Tags * tags); +int yaffs_CheckECCOnTags(yaffs_Tags * tags); +int yaffs_CountBits(__u8 byte); + +#endif --- /dev/null +++ linux-2.6.20/fs/yaffs2/yaffs_tagsvalidity.c @@ -0,0 +1,28 @@ +/* + * YAFFS: Yet Another Flash File System. A NAND-flash specific file system. + * + * Copyright (C) 2002-2007 Aleph One Ltd. + * for Toby Churchill Ltd and Brightstar Engineering + * + * Created by Charles Manning + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include "yaffs_tagsvalidity.h" + +void yaffs_InitialiseTags(yaffs_ExtendedTags * tags) +{ + memset(tags, 0, sizeof(yaffs_ExtendedTags)); + tags->validMarker0 = 0xAAAAAAAA; + tags->validMarker1 = 0x55555555; +} + +int yaffs_ValidateTags(yaffs_ExtendedTags * tags) +{ + return (tags->validMarker0 == 0xAAAAAAAA && + tags->validMarker1 == 0x55555555); + +} --- /dev/null +++ linux-2.6.20/fs/yaffs2/yaffs_tagsvalidity.h @@ -0,0 +1,24 @@ +/* + * YAFFS: Yet another Flash File System . A NAND-flash specific file system. + * + * Copyright (C) 2002-2007 Aleph One Ltd. + * for Toby Churchill Ltd and Brightstar Engineering + * + * Created by Charles Manning + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 2.1 as + * published by the Free Software Foundation. + * + * Note: Only YAFFS headers are LGPL, YAFFS C code is covered by GPL. + */ + + +#ifndef __YAFFS_TAGS_VALIDITY_H__ +#define __YAFFS_TAGS_VALIDITY_H__ + +#include "yaffs_guts.h" + +void yaffs_InitialiseTags(yaffs_ExtendedTags * tags); +int yaffs_ValidateTags(yaffs_ExtendedTags * tags); +#endif --- /dev/null +++ linux-2.6.20/fs/yaffs2/yaffsinterface.h @@ -0,0 +1,21 @@ +/* + * YAFFS: Yet another Flash File System . A NAND-flash specific file system. + * + * Copyright (C) 2002-2007 Aleph One Ltd. + * for Toby Churchill Ltd and Brightstar Engineering + * + * Created by Charles Manning + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 2.1 as + * published by the Free Software Foundation. + * + * Note: Only YAFFS headers are LGPL, YAFFS C code is covered by GPL. + */ + +#ifndef __YAFFSINTERFACE_H__ +#define __YAFFSINTERFACE_H__ + +int yaffs_Initialise(unsigned nBlocks); + +#endif --- /dev/null +++ linux-2.6.20/fs/yaffs2/yportenv.h @@ -0,0 +1,200 @@ +/* + * YAFFS: Yet another Flash File System . A NAND-flash specific file system. + * + * Copyright (C) 2002-2007 Aleph One Ltd. + * for Toby Churchill Ltd and Brightstar Engineering + * + * Created by Charles Manning + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 2.1 as + * published by the Free Software Foundation. + * + * Note: Only YAFFS headers are LGPL, YAFFS C code is covered by GPL. + */ + + +#ifndef __YPORTENV_H__ +#define __YPORTENV_H__ + +/* + * Define the MTD version in terms of Linux Kernel versions + * This allows yaffs to be used independantly of the kernel + * as well as with it. + */ + +#define MTD_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c)) + +#if defined CONFIG_YAFFS_WINCE + +#include "ywinceenv.h" + +#elif defined __KERNEL__ + +#include "moduleconfig.h" + +/* Linux kernel */ + +#include +#define MTD_VERSION_CODE LINUX_VERSION_CODE + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)) +#include +#endif +#include +#include +#include +#include +#include +#include + +#define YCHAR char +#define YUCHAR unsigned char +#define _Y(x) x +#define yaffs_strcpy(a,b) strcpy(a,b) +#define yaffs_strncpy(a,b,c) strncpy(a,b,c) +#define yaffs_strncmp(a,b,c) strncmp(a,b,c) +#define yaffs_strlen(s) strlen(s) +#define yaffs_sprintf sprintf +#define yaffs_toupper(a) toupper(a) + +#define Y_INLINE inline + +#define YAFFS_LOSTNFOUND_NAME "lost+found" +#define YAFFS_LOSTNFOUND_PREFIX "obj" + +/* #define YPRINTF(x) printk x */ +#define YMALLOC(x) kmalloc(x,GFP_KERNEL) +#define YFREE(x) kfree(x) +#define YMALLOC_ALT(x) vmalloc(x) +#define YFREE_ALT(x) vfree(x) +#define YMALLOC_DMA(x) YMALLOC(x) + +// KR - added for use in scan so processes aren't blocked indefinitely. +#define YYIELD() schedule() + +#define YAFFS_ROOT_MODE 0666 +#define YAFFS_LOSTNFOUND_MODE 0666 + +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) +#define Y_CURRENT_TIME CURRENT_TIME.tv_sec +#define Y_TIME_CONVERT(x) (x).tv_sec +#else +#define Y_CURRENT_TIME CURRENT_TIME +#define Y_TIME_CONVERT(x) (x) +#endif + +#define yaffs_SumCompare(x,y) ((x) == (y)) +#define yaffs_strcmp(a,b) strcmp(a,b) + +#define TENDSTR "\n" +#define TSTR(x) KERN_WARNING x +#define TOUT(p) printk p + +#define yaffs_trace(mask, fmt, args...) \ + do { if ((mask) & (yaffs_traceMask|YAFFS_TRACE_ERROR)) \ + printk(KERN_WARNING "yaffs: " fmt, ## args); \ + } while (0) + +#define compile_time_assertion(assertion) \ + ({ int x = __builtin_choose_expr(assertion, 0, (void)0); (void) x; }) + +#elif defined CONFIG_YAFFS_DIRECT + +#define MTD_VERSION_CODE MTD_VERSION(2,6,22) + +/* Direct interface */ +#include "ydirectenv.h" + +#elif defined CONFIG_YAFFS_UTIL + +/* Stuff for YAFFS utilities */ + +#include "stdlib.h" +#include "stdio.h" +#include "string.h" + +#include "devextras.h" + +#define YMALLOC(x) malloc(x) +#define YFREE(x) free(x) +#define YMALLOC_ALT(x) malloc(x) +#define YFREE_ALT(x) free(x) + +#define YCHAR char +#define YUCHAR unsigned char +#define _Y(x) x +#define yaffs_strcpy(a,b) strcpy(a,b) +#define yaffs_strncpy(a,b,c) strncpy(a,b,c) +#define yaffs_strlen(s) strlen(s) +#define yaffs_sprintf sprintf +#define yaffs_toupper(a) toupper(a) + +#define Y_INLINE inline + +/* #define YINFO(s) YPRINTF(( __FILE__ " %d %s\n",__LINE__,s)) */ +/* #define YALERT(s) YINFO(s) */ + +#define TENDSTR "\n" +#define TSTR(x) x +#define TOUT(p) printf p + +#define YAFFS_LOSTNFOUND_NAME "lost+found" +#define YAFFS_LOSTNFOUND_PREFIX "obj" +/* #define YPRINTF(x) printf x */ + +#define YAFFS_ROOT_MODE 0666 +#define YAFFS_LOSTNFOUND_MODE 0666 + +#define yaffs_SumCompare(x,y) ((x) == (y)) +#define yaffs_strcmp(a,b) strcmp(a,b) + +#else +/* Should have specified a configuration type */ +#error Unknown configuration + +#endif + +/* see yaffs_fs.c */ +extern unsigned int yaffs_traceMask; +extern unsigned int yaffs_wr_attempts; + +/* + * Tracing flags. + * The flags masked in YAFFS_TRACE_ALWAYS are always traced. + */ + +#define YAFFS_TRACE_OS 0x00000002 +#define YAFFS_TRACE_ALLOCATE 0x00000004 +#define YAFFS_TRACE_SCAN 0x00000008 +#define YAFFS_TRACE_BAD_BLOCKS 0x00000010 +#define YAFFS_TRACE_ERASE 0x00000020 +#define YAFFS_TRACE_GC 0x00000040 +#define YAFFS_TRACE_WRITE 0x00000080 +#define YAFFS_TRACE_TRACING 0x00000100 +#define YAFFS_TRACE_DELETION 0x00000200 +#define YAFFS_TRACE_BUFFERS 0x00000400 +#define YAFFS_TRACE_NANDACCESS 0x00000800 +#define YAFFS_TRACE_GC_DETAIL 0x00001000 +#define YAFFS_TRACE_SCAN_DEBUG 0x00002000 +#define YAFFS_TRACE_MTD 0x00004000 +#define YAFFS_TRACE_CHECKPOINT 0x00008000 + +#define YAFFS_TRACE_VERIFY 0x00010000 +#define YAFFS_TRACE_VERIFY_NAND 0x00020000 +#define YAFFS_TRACE_VERIFY_FULL 0x00040000 +#define YAFFS_TRACE_VERIFY_ALL 0x000F0000 + + +#define YAFFS_TRACE_ERROR 0x40000000 +#define YAFFS_TRACE_BUG 0x80000000 +#define YAFFS_TRACE_ALWAYS 0xF0000000 + + +#define T(mask,p) do{ if((mask) & (yaffs_traceMask | YAFFS_TRACE_ALWAYS)) TOUT(p);} while(0) + +#ifndef CONFIG_YAFFS_WINCE +#define YBUG() T(YAFFS_TRACE_BUG,(TSTR("==>> yaffs bug: " __FILE__ " %d" TENDSTR),__LINE__)) +#endif + +#endif --- /dev/null +++ linux-2.6.20/include/asm-arm/arch-nomadik/audiocodec.h @@ -0,0 +1,444 @@ +/* include/asm-arm/arch-nomadik/audiocodec.h + * + * Header file for nomadik audiocodec specific data structures, enums + * and private & public functions. + * + * Copyright (C) 2006 STMicroelectronics Pvt. Ltd. + * Author: Abhijit (abhijit.singh@st.com) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifndef _AUDIOCODEC_H_ +#define _AUDIOCODEC_H_ + +/*--------------------------------------------------------------------- + * Includes + *--------------------------------------------------------------------*/ +#include +#include + +/*----------------------------------------------------------------------------- + * New types + *---------------------------------------------------------------------------*/ + +typedef enum { False, True } __attribute__ ((packed)) boolean; + +/*callback funciton pointer type*/ +typedef void (*codec_callback) (void *buff); + +#define RESET -1 +#define DEFAULT -100 + +/* For volume management of stw5094A CODEC */ +#define CODEC_MUTE 0x20 +#define DEFAULT_VOLUME 0x64 +#define DEFAULT_GAIN 0x32 +#define VOL_MAX 0x64 +#define VOL_MIN 0x00 +#define DEFAULT_OUTPUT_DEVICE CODEC_DEST_HEADPHONE +#define DEFAULT_INPUT_DEVICE CODEC_SOURCE_MICROPHONE + +/* duplicate copy of enum from msp.h */ +/* for MSPConfiguration.in_clock_freq parameter to select msp clock freq */ +typedef enum { + + CODEC_MSP_INPUT_FREQ_1MHZ = 1000, + CODEC_MSP_INPUT_FREQ_2MHZ = 2000, + CODEC_MSP_INPUT_FREQ_3MHZ = 3000, + CODEC_MSP_INPUT_FREQ_4MHZ = 4000, + CODEC_MSP_INPUT_FREQ_5MHZ = 5000, + CODEC_MSP_INPUT_FREQ_6MHZ = 6000, + CODEC_MSP_INPUT_FREQ_8MHZ = 8000, + CODEC_MSP_INPUT_FREQ_11MHZ = 11000, + CODEC_MSP_INPUT_FREQ_12MHZ = 12000, + CODEC_MSP_INPUT_FREQ_16MHZ = 16000, + CODEC_MSP_INPUT_FREQ_22MHZ = 22000, + CODEC_MSP_INPUT_FREQ_24MHZ = 24000, + CODEC_MSP_INPUT_FREQ_48MHZ = 48000 + +} codec_msp_in_clock_freq_type; + +/* msp clock source internal/external for srg_clock_sel */ +typedef enum { + CODEC_MSP_APB_CLOCK = 0, + CODEC_MSP_SCK_CLOCK = 2, + CODEC_MSP_SCK_SYNC_CLOCK = 3 +} codec_msp_srg_clock_sel_type; + +/* Data direction */ +typedef enum { + CODEC_DIRECTION_UNKNOWN = 0, /* not known */ + CODEC_DIRECTION_IN = 1, /* recording mode */ + CODEC_DIRECTION_OUT = 2, /* playback mode */ + CODEC_DIRECTION_INOUT = 3 /* both recording and playback simultaneously */ +} t_codec_direction; + +/* Compand Mode */ + +typedef enum { + CODEC_LINEAR = 0, + CODEC_ALAW = 2, + CODEC_MULAW = 4 +} codec_compand_mode; + +/* Error status return by APIs */ + +typedef enum { + CODEC_OK = 0, + CODEC_ERROR = -1, + CODEC_NOT_SUPPORTED = -2, + CODEC_CONFIG_NOTCOHERENT = -3, + CODEC_BAD_VALUE = -4, + CODEC_UNSUPPORTED_FEATURE = -5, + CODEC_INVALID_PARAMETER = -6, + CODEC_CONFIG_NOT_COHERENT = -7, + CODEC_TRANSACTION_ON_I2C_FAILED = -8 +} t_codec_error; + +/* Sample rate supported by Codec */ + +typedef enum { + CODEC_FREQUENCY_DONT_CHANGE = -100, + CODEC_SAMPLING_FREQ_RESET = -1, + CODEC_SAMPLING_FREQ_MINLIMIT = 7, + CODEC_SAMPLING_FREQ_8KHZ = 8, /*default */ + CODEC_SAMPLING_FREQ_11KHZ = 11, + CODEC_SAMPLING_FREQ_12KHZ = 12, + CODEC_SAMPLING_FREQ_16KHZ = 16, + CODEC_SAMPLING_FREQ_22KHZ = 22, + CODEC_SAMPLING_FREQ_24KHZ = 24, + CODEC_SAMPLING_FREQ_32KHZ = 32, + CODEC_SAMPLING_FREQ_44KHZ = 44, + CODEC_SAMPLING_FREQ_48KHZ = 48, + CODEC_SAMPLING_FREQ_64KHZ = 64, /*the frequencies below this line are not supported in stw5094A */ + CODEC_SAMPLING_FREQ_88KHZ = 88, + CODEC_SAMPLING_FREQ_96KHZ = 96, + CODEC_SAMPLING_FREQ_128KHZ = 128, + CODEC_SAMPLING_FREQ_176KHZ = 176, + CODEC_SAMPLING_FREQ_192KHZ = 192, + CODEC_SAMPLING_FREQ_MAXLIMIT = 193 +} t_codec_sample_frequency; + +/* Sample size */ + +typedef enum +{ + CODEC_SIZE_8 = 8, + CODEC_SIZE_16 = 16, /* default */ + CODEC_SIZE_20 = 20, + CODEC_SIZE_24 = 24, + CODEC_SIZE_32 = 32 +} codec_input_bit_length; + +/* tonegenerated waveform shape */ + +typedef enum { + + CODEC_TONE_SQUARE_WAVE = 0x00, + CODEC_TONE_SIN_WAVE = 0x02 +} codec_tone_wave; + +/*tone gain, its negative gain , max is 0 */ + +typedef enum { + + CODEC_TONE_GAIN_0DB = 0, /*default */ + CODEC_TONE_GAIN_3DB, + CODEC_TONE_GAIN_6DB, + CODEC_TONE_GAIN_9DB, + CODEC_TONE_GAIN_12DB, + CODEC_TONE_GAIN_15DB, + CODEC_TONE_GAIN_18DB, + CODEC_TONE_GAIN_21DB, + CODEC_TONE_GAIN_24DB, + CODEC_TONE_GAIN_27DB, + CODEC_TONE_GAIN_30DB, + CODEC_TONE_GAIN_33DB +} codec_tone_gain; + +/*Sidetone gain +------------------*/ +typedef enum +{ + CODEC_SIDETONE_GAIN_12_5DB = 0, /* Default */ + CODEC_SIDETONE_GAIN_13_5DB, + CODEC_SIDETONE_GAIN_14_5DB, + CODEC_SIDETONE_GAIN_16_5DB, + CODEC_SIDETONE_GAIN_17_5DB, + CODEC_SIDETONE_GAIN_18_5DB, + CODEC_SIDETONE_GAIN_19_5DB, + CODEC_SIDETONE_GAIN_20_5DB, + CODEC_SIDETONE_GAIN_21_5DB, + CODEC_SIDETONE_GAIN_22_5DB, + CODEC_SIDETONE_GAIN_23_5DB, + CODEC_SIDETONE_GAIN_24_5DB, + CODEC_SIDETONE_GAIN_25_5DB, + CODEC_SIDETONE_GAIN_26_5DB, + CODEC_SIDETONE_GAIN_27_5DB +} codec_sidetone_gain; + +/* MIC GAIN */ + +typedef enum { + CODEC_MIC_GAIN_DEFAULT = -1, + CODEC_MIC_GAIN_0DB = 0, + CODEC_MIC_GAIN_1_5DB = 1, + CODEC_MIC_GAIN_3DB = 2, + CODEC_MIC_GAIN_4_5DB = 3, + CODEC_MIC_GAIN_6DB = 4, + CODEC_MIC_GAIN_7_5DB = 5, + CODEC_MIC_GAIN_9DB = 6, + CODEC_MIC_GAIN_10_5DB = 7, + CODEC_MIC_GAIN_12DB = 8, + CODEC_MIC_GAIN_13_5DB = 9, + CODEC_MIC_GAIN_15DB = 10, + CODEC_MIC_GAIN_16_5DB = 11, + CODEC_MIC_GAIN_18DB = 12, + CODEC_MIC_GAIN_19_5DB = 13, + CODEC_MIC_GAIN_21DB = 14, + CODEC_MIC_GAIN_22_5DB = 15 +} codec_mic_gain; + +/* Line or Microphone selection */ + +typedef enum +{ + CODEC_SOURCE_RESET = -1, + CODEC_SOURCE_NONE = 0, + CODEC_SOURCE_LINEIN, + CODEC_SOURCE_MICROPHONE, + CODEC_SOURCE_MIC1 = 0x60, /* mic3 is default input mic */ + CODEC_SOURCE_MIC2 = 0xA0, + CODEC_SOURCE_MIC3 = 0xE0 +} t_codec_input_select; + +/* FM INPUT IS FROM FML N FMR OR MIC3, BITS MFM IN CR20. */ + +typedef enum { + CODEC_DEST_RESET = -1, + CODEC_DEST_LOUDSPEAKER, + CODEC_DEST_EARPIECE, + CODEC_DEST_HEADPHONE, + CODEC_DEST_LINEOUT, + CODEC_DEST_NONE = 0x0E, + CODEC_DEST_LSP0 = 0x10, + CODEC_DEST_HP0 = 0x0C, + CODEC_DEST_HP_AND_LSP = 0x1C /* Default */ +} t_codec_output_select; + +/* AUDIOCODEC NUMBER OF CHANNELS */ + +typedef enum { + CODEC_CHANNEL_MONO = 0x00, /* Default */ + CODEC_CHANNEL_STEREO = 0x02 +} t_codec_channel; + +/* audiocodec mode */ + +typedef enum { + CODEC_MODE_NONE, + CODEC_MODE_AUDIO, + CODEC_MODE_TONE, + CODEC_MODE_HIFI, + CODEC_MODE_VOICE, + CODEC_MODE_MANUAL_SETTING +} t_codec_mode; + +/* User client for the Audiocodec */ +typedef enum { + NO_USER = 0, + USER_ALSA = 2, /*To make it equivalent to user id for MSP*/ + USER_SAA, +}t_acodec_user; + +/* DATA FORAMT BIT MASK */ +/* + * Samples are big endian aligned (default). This corresponds to Bit 0 of data format mask. + * Samples are little endian aligned. This corresponds to Bit 0 of data format mask. + * Channel samples are interleaved (default). This corresponds to Bit 1 of data format mask. + * Channel samples are non-interleaved. This corresponds to Bit 1 of data format mask. +*/ +typedef struct { + unsigned endianness:1; + unsigned interleaved:1; + /* rest to be decided */ + +} codec_dfmt; + +/* AUDIOCODEC VOLUME FOR BOTH SPEAKERS */ + +typedef struct { + int lvolume_in; + int rvolume_in; + int lvolume_out; + int rvolume_out; +} codec_volume; + +/*configuration structure for Codec +---------------------------------*/ + +typedef struct { + t_codec_mode codec_mode; + t_codec_direction running_direction; + t_codec_sample_frequency record_frequency; + t_codec_sample_frequency play_frequency; + codec_input_bit_length sample_size; + t_codec_channel codec_channels; + t_codec_input_select codec_input; + codec_volume codec_volume; + t_codec_output_select codec_output; + codec_compand_mode compand_mode; + boolean codec_tone_mode; + boolean sidetone_enable; + codec_sidetone_gain sidetone_gain; + boolean bypass_mode_enable; + codec_tone_gain bypass_mode_gain; + codec_mic_gain input_gain; + __u8 codec_power_state; + __u16 mix_mask; + codec_dfmt codec_data_format; + codec_tone_gain tone_gain; + +} codec_configuration; + +/******************************************************************** +* Chip specific data +********************************************************************/ +#if defined(CONFIG_NOMADIK_STW5094) + +#define MIN_RATE_PLAYBACK 8000 +#define MAX_RATE_PLAYBACK 64000 +#define MIN_RATE_CAPTURE 8000 +#define MAX_RATE_CAPTURE 16000 +#define MAX_ELEM 11 + +#elif defined(CONFIG_NOMADIK_STW5095) + +#define MIN_RATE_PLAYBACK 8000 +#define MAX_RATE_PLAYBACK 96000 +#define MIN_RATE_CAPTURE 8000 +#define MAX_RATE_CAPTURE 96000 +#define MAX_ELEM 13 + +#else +#error "no audiocodec chip ( stw5094/stw5095) selected for nomadik" +#endif + +extern int nmdk_acodec_rates[MAX_ELEM]; + +/******************************************************************** +* Private functions +********************************************************************/ + +int set_volume(int vol); +int set_volume_mic(int vol); +t_codec_error set_ock_frequency(t_codec_sample_frequency frequency); +t_codec_error reset_nomadik_acodec(void); +int calculate_frequency(int freq); +int set_tone_gain(int gain); +int set_sidetone_gain(int gain); + +/********************************************************************** + * Exported Functions +**********************************************************************/ + +t_codec_error nomadik_acodec_setuser(t_acodec_user user); +t_codec_error nomadik_acodec_unsetuser(t_acodec_user user); +t_codec_error nomadik_acodec_enable_audio_mode(t_codec_direction direction, + t_codec_sample_frequency + input_frequency, + t_codec_sample_frequency + output_frequency, + codec_msp_srg_clock_sel_type + mspClockSel, + codec_msp_in_clock_freq_type + mspInClockFreq, t_acodec_user user); + +t_codec_error nomadik_acodec_enable_voice_mode(t_codec_direction direction, + t_codec_sample_frequency + input_frequency, + t_codec_sample_frequency + output_frequency, + codec_msp_srg_clock_sel_type + mspClockSel, + codec_msp_in_clock_freq_type + mspInClockFreq, t_acodec_user user); + +t_codec_error nomadik_acodec_set_frequency(t_codec_direction direction, + t_codec_sample_frequency + input_frequency, + t_codec_sample_frequency + output_frequency, t_acodec_user user); + +t_codec_error nomadik_acodec_get_maxvolume(__u8 * input_max_vol, + __u8 * output_max_vol); + +t_codec_error nomadik_acodec_get_minvolume(__u8 * input_min_vol, + __u8 * output_min_vol); + +t_codec_error nomadik_acodec_set_volume(int input_vol_left, + int input_vol_right, + int output_vol_left, + int output_vol_right, t_acodec_user user); + +t_codec_error nomadik_acodec_get_volume(codec_volume + *codec_volume, t_acodec_user user); + +t_codec_error nomadik_acodec_select_input(t_codec_input_select input_device, t_acodec_user user); +t_codec_error nomadik_acodec_select_output(t_codec_output_select output_device, t_acodec_user user); +t_codec_error nomadik_acodec_powerup(void); +t_codec_error nomadik_acodec_powerdown(__u8 power_level); +t_codec_error nomadik_acodec_set_samplesize(codec_input_bit_length codec_size, t_acodec_user user); +t_codec_error nomadik_acodec_set_no_of_channels(t_codec_channel channel, t_acodec_user user); +t_codec_error nomadik_acodec_set_compand(codec_compand_mode compand_mode, t_acodec_user user); +t_codec_error nomadik_acodec_set_dataformat(codec_dfmt * codec_dfmt, t_acodec_user user); +t_codec_error nomadik_acodec_get_dataformat(codec_dfmt * codec_dfmt, t_acodec_user user); +t_codec_error nomadik_acodec_enable_datapath_errcb(codec_callback * + call_back_fn, + unsigned long *data, t_acodec_user user); + +t_codec_error nomadik_acodec_enable_sidetone(int gain, unsigned long *reserved1, + unsigned long *reserved2, t_acodec_user user); +t_codec_error nomadik_acodec_disable_sidetone(t_acodec_user user); + +t_codec_error nomadik_acodec_enable_bypassmode(t_codec_sample_frequency + analog_frequency, + __u8 codec_in_gain, + boolean mix_with_playback, + unsigned long *reserved1, + unsigned long *reserved2, t_acodec_user user); +/* t_codec_error nomadik_acodec_disable_bypassmode(t_acodec_user user);*/ + +t_codec_error nomadik_acodec_enable_tonegeneratormode(int tone_gain, + __u8 mix_with_record, + __u8 mix_with_playback, + codec_tone_wave waveShape, + unsigned long *reserved2, t_acodec_user user); + +t_codec_error nomadik_acodec_play_singletone(int toneFrequency, t_acodec_user user); +t_codec_error nomadik_acodec_play_dualtone(int freqF1, int freqF2, t_acodec_user user); +t_codec_error nomadik_acodec_stop_tone(t_acodec_user user); +t_codec_error nomadik_acodec_disable_tonegeneratormode(t_acodec_user user); + +t_codec_error nomadik_acodec_get_currentsettings(codec_configuration * + codec_conf, t_acodec_user user); +t_codec_error nomadik_acodec_set_currentsettings(codec_configuration * + codec_conf, t_acodec_user user); + +#endif /* _AUDIOCODEC_H_ */ + +/* End of file audiocodec.h*/ --- /dev/null +++ linux-2.6.20/include/asm-arm/arch-nomadik/bits.h @@ -0,0 +1,61 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +/* DO NOT EDIT!! - this file automatically generated + * from .s file by awk -f s2h.awk + */ +/* Bit field definitions + * Copyright (C) ARM Limited 1998. All rights reserved. + */ + +#ifndef __bits_h +#define __bits_h 1 + +#define BIT0 0x00000001 +#define BIT1 0x00000002 +#define BIT2 0x00000004 +#define BIT3 0x00000008 +#define BIT4 0x00000010 +#define BIT5 0x00000020 +#define BIT6 0x00000040 +#define BIT7 0x00000080 +#define BIT8 0x00000100 +#define BIT9 0x00000200 +#define BIT10 0x00000400 +#define BIT11 0x00000800 +#define BIT12 0x00001000 +#define BIT13 0x00002000 +#define BIT14 0x00004000 +#define BIT15 0x00008000 +#define BIT16 0x00010000 +#define BIT17 0x00020000 +#define BIT18 0x00040000 +#define BIT19 0x00080000 +#define BIT20 0x00100000 +#define BIT21 0x00200000 +#define BIT22 0x00400000 +#define BIT23 0x00800000 +#define BIT24 0x01000000 +#define BIT25 0x02000000 +#define BIT26 0x04000000 +#define BIT27 0x08000000 +#define BIT28 0x10000000 +#define BIT29 0x20000000 +#define BIT30 0x40000000 +#define BIT31 0x80000000 + +#endif + +/* END */ --- /dev/null +++ linux-2.6.20/include/asm-arm/arch-nomadik/debug-macro.S @@ -0,0 +1,38 @@ +/* linux/include/asm-arm/arch-integrator/debug-macro.S + * + * Debugging macro include header + * + * Copyright (C) 1994-1999 Russell King + * Moved from linux/arch/arm/kernel/debug.S by Ben Dooks + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * +*/ + +#include + + .macro addruart,rx + mrc p15, 0, \rx, c1, c0 + tst \rx, #1 @ MMU enabled? + moveq \rx, #0xA0000000 @ physical base address + movne \rx, #0xf0000000 @ virtual base + addne \rx, \rx, #0xA0000000 >> 4 + .endm + + .macro senduart,rd,rx + strb \rd, [\rx, #UART01x_DR] + .endm + + .macro waituart,rd,rx +1001: ldr \rd, [\rx, #0x18] @ UARTFLG + tst \rd, #1 << 5 @ UARTFLGUTXFF - 1 when full + bne 1001b + .endm + + .macro busyuart,rd,rx +1001: ldr \rd, [\rx, #0x18] @ UARTFLG + tst \rd, #1 << 3 @ UARTFLGUBUSY - 1 when busy + bne 1001b + .endm --- /dev/null +++ linux-2.6.20/include/asm-arm/arch-nomadik/debug.h @@ -0,0 +1,148 @@ +/* + * linux/include/asm-arm/arch-nomadik/debug-nomadik.h + * + *----------------------------------------------------------------------- + * Reproduction and Communication of this document is strictly prohibited + * unless specifically authorized in writing by STMicroelectronics + * + * Name: debug-nomadik.h + * + * Description: Nomadik debug message strategy include file + * + * Reference: Documentation/arm/STM-Nomadik/debug_strategy.txt + * + * Author : ST Microelectronics + * + * --------------------------------------------------------------------- + */ + + +#ifndef __INC_DBG_H +#define __INC_DBG_H + +#include "defs.h" + +/* Store a submitter ID, unique for each HCL. */ + +typedef enum { + STD_UNKNOWN_DBG_ID, + STD_APPLI_DBG_ID, + STD_TEST_DBG_ID, + STD_DEBUG_DBG_ID, + STD_UART_DBG_ID, + STD_VIC_DBG_ID, + STD_DMA_DBG_ID, + STD_HA_DBG_ID, + STD_SAA_DBG_ID, + STD_RTC_DBG_ID, + STD_TIMER_DBG_ID, + STD_WATCHDOG_DBG_ID, + STD_I2C_DBG_ID, + STD_CODEC_DBG_ID, + STD_MSP_DBG_ID, + STD_HV_DBG_ID, + STD_SVA_DBG_ID, + STD_FLASH_DBG_ID, + STD_SDRAM_DBG_ID, + STD_GPIO_DBG_ID, + STD_POWER_DBG_ID, + STD_PLL_DBG_ID, + STD_HSI_DBG_ID, + STD_DIF_DBG_ID, + STD_SDMM_DBG_ID, + STD_FIRDA_DBG_ID, + STD_SSP_DBG_ID, + STD_CLCD_DBG_ID, + STD_SRC_DBG_ID, + STD_RTT_DBG_ID, + STD_USB_DBG_ID, + STD_PWL_DBG_ID, + STD_OWM_DBG_ID, + STD_TSP_DBG_ID, + STD_SSM_DBG_ID, + STD_SECR_DBG_ID, + STD_TDES_DBG_ID, + STD_SHA1_DBG_ID, + STD_RNG_DBG_ID +} dbg_id_t; + +/* Define the debug level. */ + +#define STD_DEBUG_LEVEL0 STD_DBGL_OFF +#define STD_DEBUG_LEVEL1 ((uint32)STD_DBGL_PUBLIC_FUNC_IN|(uint32)STD_DBGL_PUBLIC_FUNC_OUT|(uint32)STD_DBGL_ERROR|(uint32)STD_DBGL_WARNING) +#define STD_DEBUG_LEVEL2 ((uint32)STD_DBGL_IN_ARGS|(uint32)STD_DBGL_OUT_ARGS|(uint32)STD_DBGL_RET_CODE) +#define STD_DEBUG_LEVEL3 STD_DBGL_INTERNAL +#define STD_DEBUG_LEVEL4 STD_DBGL_DEV + +typedef enum { + STD_DBGL_OFF = 0, + STD_DBGL_PUBLIC_FUNC_IN = STD_MASK_BIT0, + STD_DBGL_PUBLIC_FUNC_OUT = STD_MASK_BIT1, + STD_DBGL_ERROR = STD_MASK_BIT2, + STD_DBGL_WARNING = STD_MASK_BIT3, + STD_DBGL_IN_ARGS = STD_MASK_BIT4, + STD_DBGL_OUT_ARGS = STD_MASK_BIT5, + STD_DBGL_RET_CODE = STD_MASK_BIT6, + STD_DBGL_INTERNAL = STD_MASK_BIT7, + STD_DBGL_DEV = STD_MASK_BIT8, + STD_DBGL_PRIV_FUNC_IN = STD_MASK_BIT9, + STD_DBGL_PRIV_FUNC_OUT = STD_MASK_BIT10, + STD_DBGL_PRIV_IN_ARGS = STD_MASK_BIT11, + STD_DBGL_PRIV_OUT_ARGS = STD_MASK_BIT12, + STD_DBGL_USER_1 = STD_MASK_BIT13, + STD_DBGL_USER_2 = STD_MASK_BIT14, + STD_DBGL_USER_3 = STD_MASK_BIT15, + STD_DBGL_USER_4 = STD_MASK_BIT16, + STD_DBGL_USER_5 = STD_MASK_BIT17, + STD_DBGL_USER_6 = STD_MASK_BIT18, + STD_DBGL_USER_7 = STD_MASK_BIT19, + STD_DBGL_USER_8 = STD_MASK_BIT20, + STD_DBGL_USER_9 = STD_MASK_BIT21, + STD_DBGL_RESERVED_0 = STD_MASK_BIT22, + STD_DBGL_RESERVED_1 = STD_MASK_BIT23, + STD_DBGL_RESERVED_2 = STD_MASK_BIT24, + STD_DBGL_RESERVED_3 = STD_MASK_BIT25, + STD_DBGL_RESERVED_4 = STD_MASK_BIT26, + STD_DBGL_RESERVED_5 = STD_MASK_BIT27, + STD_DBGL_RESERVED_6 = STD_MASK_BIT28, + STD_DBGL_RESERVED_7 = STD_MASK_BIT29, + STD_DBGL_RESERVED_8 = STD_MASK_BIT30 +} dbg_level_t; + +#ifdef __RELEASE + +#define STD_DBGEXIT(cr) +#define STD_DBGEXIT0(cr) +#define STD_DBGEXIT1(cr,ch,p1) +#define STD_DBGEXIT2(cr,ch,p1,p2) +#define STD_DBGEXIT3(cr,ch,p1,p2,p3) +#define STD_DBGEXIT4(cr,ch,p1,p2,p3,p4) +#define STD_DBGEXIT5(cr,ch,p1,p2,p3,p4,p5) +#define STD_DBGEXIT6(cr,ch,p1,p2,p3,p4,p5,p6) + +#define STD_DBGENTER() +#define STD_DBGENTER0() +#define STD_DBGENTER1(ch,p1) +#define STD_DBGENTER2(ch,p1,p2) +#define STD_DBGENTER3(ch,p1,p2,p3) +#define STD_DBGENTER4(ch,p1,p2,p3,p4) +#define STD_DBGENTER5(ch,p1,p2,p3,p4,p5) +#define STD_DBGENTER6(ch,p1,p2,p3,p4,p5,p6) + +#endif /* __RELEASE */ + +#define nmdk_error(format, arg...) printk(KERN_ERR NMDK_DEBUG_PFX ": " format "\n" , ## arg) +#define nmdk_info(format, arg...) printk(KERN_INFO NMDK_DEBUG_PFX ": " format "\n" , ## arg) +#define nmdk_warn(format, arg...) printk(KERN_WARNING NMDK_DEBUG_PFX ": " format "\n" , ## arg) + +#define nmdk_dbg(format, arg...) (NMDK_DEBUG & 1) ? (printk(NMDK_DBG NMDK_DEBUG_PFX ": " format "\n" , ## arg)) : ({do {} while (0);}) + +#define nmdk_dbg_ftrace(format, arg...) (NMDK_DEBUG & 2) ? (printk(NMDK_DBG NMDK_DEBUG_PFX ": %s() called\n", ( __FUNCTION__ ))) : ({do {} while (0);}) + +#define nmdk_dbg2(format, arg...) (NMDK_DEBUG & 4) ? (printk(NMDK_DBG NMDK_DEBUG_PFX ": " format "\n" , ## arg)) : ({do {} while (0);}) + +#define nmdk_dbg3(format, arg...) (NMDK_DEBUG & 8) ? (printk(NMDK_DBG NMDK_DEBUG_PFX ": " format "\n" , ## arg)) : ({do {} while (0);}) + +#endif /* __INC_DBG_H */ + +/* End of file - debug.h */ --- /dev/null +++ linux-2.6.20/include/asm-arm/arch-nomadik/defs.h @@ -0,0 +1,245 @@ +/* + * include/asm/arch/defs.h + * + * Copyright (C) STMicroelectronics + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef _NOMADIK_DEFS_H +#define _NOMADIK_DEFS_H + +#ifndef __ASSEMBLY__ +/* + * Type definition + */ +#ifndef BITS64 /*to remove conflict with arch/arm/nwfpe/ARM-gcc.h*/ +typedef unsigned char uint8; +typedef signed char sint8; +typedef unsigned short uint16; +typedef signed short sint16; +typedef unsigned long uint32; +typedef signed long sint32; +#endif +typedef unsigned int bitfield; + +#if !defined(FALSE) && !defined(TRUE) +typedef enum { NOMADIK_FALSE, NOMADIK_TRUE } bool_t; +#else +typedef enum { BOOL_FALSE, BOOL_TRUE } bool_t; +#endif + +/* + * Definition of the different kind of addresses manipulated into a system with MMU + * (handle physical AND logical addresses) + */ +typedef uint32 physical_address; +typedef uint32 logical_address; + +/* + * Global frequency enumuration + * Added to avoid frequency conversion function which is required to convert one HCL + * frequency enumuration values to another HCL frequency enumuration values. + */ + +typedef enum { + NOMADIK_FREQ_NOT_SUPPORTED = -1, + NOMADIK_FREQ_8KHZ, + NOMADIK_FREQ_11_25KHZ, + NOMADIK_FREQ_12KHZ, + NOMADIK_FREQ_16KHZ, + NOMADIK_FREQ_22_05KHZ, + NOMADIK_FREQ_22_5KHZ, + NOMADIK_FREQ_24KHZ, + NOMADIK_FREQ_32KHZ, + NOMADIK_FREQ_44KHZ, + NOMADIK_FREQ_44_1KHZ, + NOMADIK_FREQ_48KHZ, + NOMADIK_FREQ_64KHZ, + NOMADIK_FREQ_88KHZ, + NOMADIK_FREQ_88_2KHZ, + NOMADIK_FREQ_96KHZ, + NOMADIK_FREQ_128KHZ, + NOMADIK_FREQ_176_4KHZ, + NOMADIK_FREQ_192KHZ, + NOMADIK_FREQ_1MHZ, + NOMADIK_FREQ_2MHZ, + NOMADIK_FREQ_3MHZ, + NOMADIK_FREQ_4MHZ, + NOMADIK_FREQ_5MHZ, + NOMADIK_FREQ_6MHZ, + NOMADIK_FREQ_8MHZ, + NOMADIK_FREQ_11MHZ, + NOMADIK_FREQ_12MHZ, + NOMADIK_FREQ_16MHZ, + NOMADIK_FREQ_22MHZ, + NOMADIK_FREQ_24MHZ, + NOMADIK_FREQ_48MHZ +} frequency_t; + +typedef struct { + physical_address physical; + logical_address logical; +} system_address_t; + +/* + * Define a type used to manipulate size of various buffers + */ +typedef uint32 size; + +typedef struct { + bitfield minor:8; + bitfield major:8; + bitfield version:16; +} version_t; + +/* + * Keyword definition + */ +#ifndef NULL +#define NULL (0) +#endif + +#define NOMADIK_INTERNAL_ERROR (-8) +#define NOMADIK_NOT_CONFIGURED (-7) +#define NOMADIK_REQUEST_PENDING (-6) +#define NOMADIK_REQUEST_NOT_APPLICABLE (-5) +#define NOMADIK_INVALID_PARAMETER (-4) +#define NOMADIK_UNSUPPORTED_FEATURE (-3) +#define NOMADIK_UNSUPPORTED_HW (-2) +#define NOMADIK_ERROR (-1) +#define NOMADIK_OK ( 0) +#define NOMADIK_INTERNAL_EVENT ( 1) +#define NOMADIK_REMAINING_PENDING_EVENTS ( 2) +#define NOMADIK_REMAINING_FILTER_PENDING_EVENTS ( 3) +#define NOMADIK_NO_MORE_PENDING_EVENT ( 4) +#define NOMADIK_NO_MORE_FILTER_PENDING_EVENT ( 5) +#define NOMADIK_NO_PENDING_EVENT_ERROR ( 7) + +#define NOMADIK_MAX_ERROR_VALUE (-65) + +/* + * Bit setting or clearing + */ +#define NOMADIK_SET_BITS(reg,mask) ((reg) |= (mask)) +#define NOMADIK_CLEAR_BITS(reg,mask) ((reg) &= ~(mask)) +#define NOMADIK_READ_BITS(reg,mask) ((reg) & (mask)) +#define NOMADIK_WRITE_BITS(reg,val,mask) ((reg) = (((reg) & ~(mask)) | ((val) & (mask)))) +#define NOMADIK_READ_REG(reg) (reg) +#define NOMADIK_WRITE_REG(reg,val) ((reg) = (val)) + +/* + * field offset extraction from a structure + */ +#define STD_FIELD_OFFSET(typeName, fieldName) (uint32)(&(((typeName *)0)->fieldName)) +#define NOMADIK_BITFIELD_OFFSET(typeName, fieldName) (uint32)(&(((typeName *)0)->fieldName)) + +/* + * Bit mask definition + */ +#define STD_MASK_NULL8 0x00 +#define STD_MASK_NULL16 0x0000 +#define STD_MASK_NULL32 0x00000000 +#define STD_MASK_ALL8 0xFF +#define STD_MASK_ALL16 0xFFFF +#define STD_MASK_ALL32 0xFFFFFFFF + +#define STD_MASK_BIT0 (1UL<<0) +#define STD_MASK_BIT1 (1UL<<1) +#define STD_MASK_BIT2 (1UL<<2) +#define STD_MASK_BIT3 (1UL<<3) +#define STD_MASK_BIT4 (1UL<<4) +#define STD_MASK_BIT5 (1UL<<5) +#define STD_MASK_BIT6 (1UL<<6) +#define STD_MASK_BIT7 (1UL<<7) +#define STD_MASK_BIT8 (1UL<<8) +#define STD_MASK_BIT9 (1UL<<9) +#define STD_MASK_BIT10 (1UL<<10) +#define STD_MASK_BIT11 (1UL<<11) +#define STD_MASK_BIT12 (1UL<<12) +#define STD_MASK_BIT13 (1UL<<13) +#define STD_MASK_BIT14 (1UL<<14) +#define STD_MASK_BIT15 (1UL<<15) +#define STD_MASK_BIT16 (1UL<<16) +#define STD_MASK_BIT17 (1UL<<17) +#define STD_MASK_BIT18 (1UL<<18) +#define STD_MASK_BIT19 (1UL<<19) +#define STD_MASK_BIT20 (1UL<<20) +#define STD_MASK_BIT21 (1UL<<21) +#define STD_MASK_BIT22 (1UL<<22) +#define STD_MASK_BIT23 (1UL<<23) +#define STD_MASK_BIT24 (1UL<<24) +#define STD_MASK_BIT25 (1UL<<25) +#define STD_MASK_BIT26 (1UL<<26) +#define STD_MASK_BIT27 (1UL<<27) +#define STD_MASK_BIT28 (1UL<<28) +#define STD_MASK_BIT29 (1UL<<29) +#define STD_MASK_BIT30 (1UL<<30) +#define STD_MASK_BIT31 (1UL<<31) + +/* + * quartet shift definition + */ +#define STD_MASK_QUARTET (0xFUL) +#define STD_SHIFT_QUARTET0 0 +#define STD_SHIFT_QUARTET1 4 +#define STD_SHIFT_QUARTET2 8 +#define STD_SHIFT_QUARTET3 12 +#define STD_SHIFT_QUARTET4 16 +#define STD_SHIFT_QUARTET5 20 +#define STD_SHIFT_QUARTET6 24 +#define STD_SHIFT_QUARTET7 28 +#define STD_MASK_QUARTET0 (STD_MASK_QUARTET << STD_SHIFT_QUARTET0) +#define STD_MASK_QUARTET1 (STD_MASK_QUARTET << STD_SHIFT_QUARTET1) +#define STD_MASK_QUARTET2 (STD_MASK_QUARTET << STD_SHIFT_QUARTET2) +#define STD_MASK_QUARTET3 (STD_MASK_QUARTET << STD_SHIFT_QUARTET3) +#define STD_MASK_QUARTET4 (STD_MASK_QUARTET << STD_SHIFT_QUARTET4) +#define STD_MASK_QUARTET5 (STD_MASK_QUARTET << STD_SHIFT_QUARTET5) +#define STD_MASK_QUARTET6 (STD_MASK_QUARTET << STD_SHIFT_QUARTET6) +#define STD_MASK_QUARTET7 (STD_MASK_QUARTET << STD_SHIFT_QUARTET7) + +/* + * Byte shift definition + */ +#define STD_MASK_BYTE (0xFFUL) +#define STD_SHIFT_BYTE0 0 +#define STD_SHIFT_BYTE1 8 +#define STD_SHIFT_BYTE2 16 +#define STD_SHIFT_BYTE3 24 +#define STD_MASK_BYTE0 (STD_MASK_BYTE << STD_SHIFT_BYTE0) +#define STD_MASK_BYTE1 (STD_MASK_BYTE << STD_SHIFT_BYTE1) +#define STD_MASK_BYTE2 (STD_MASK_BYTE << STD_SHIFT_BYTE2) +#define STD_MASK_BYTE3 (STD_MASK_BYTE << STD_SHIFT_BYTE3) + +/* + * Halfword shift definition + */ +#define STD_MASK_HALFWORD (0xFFFFUL) +#define STD_SHIFT_HALFWORD0 0 +#define STD_SHIFT_HALFWORD1 16 +#define STD_MASK_HALFWORD0 (STD_MASK_HALFWORD << STD_SHIFT_HALFWORD0) +#define STD_MASK_HALFWORD1 (STD_MASK_HALFWORD << STD_SHIFT_HALFWORD1) + +/* + * Global constants definition + */ +#define STD_ONE_KB (1024) +#define STD_ONE_MB (STD_ONE_KB * STD_ONE_KB) + +/* + * Address translation macros declaration + */ +#if defined(__PLATFORM_MEK0) || defined(__PLATFORM_MEK1) || defined(__PLATFORM_MEK2) || defined(__PLATFORM_MEK3) || defined(__PLATFORM_MEK4) + +#define ARM_TO_AHB_ADDR(addr) (addr | MASK_BIT31) +#define AHB_TO_ARM_ADDR(addr) (addr & ~MASK_BIT31) +#endif + +#if defined(__PLATFORM_MEVKLITE) || defined(__PLATFORM_MEVKFULL) +#define ARM_TO_AHB_ADDR(addr) (addr) +#define AHB_TO_ARM_ADDR(addr) (addr) +#endif +#endif /*__ASSEMBLY__*/ +#endif --- /dev/null +++ linux-2.6.20/include/asm-arm/arch-nomadik/dma.h @@ -0,0 +1,362 @@ +/* include/asm-arm/arch-nomadik/dma.h + * + * Copyright 2007, STMicroelectronics + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * $Id$ + */ +#ifndef __INC_DMA_H +#define __INC_DMA_H + +#include + +#define MAX_DMA_CHANNELS 32 +/* MAX_DMA_CHANNELS can be increased upto 127 if system needs more channels */ +#define MAX_DMA_LLIS (MAX_DMA_CHANNELS*4096) +/* + * DMA_ALL_MEM_CHANNELS will be used by resume_dma/suspend_dma to flag + * to process all such DMA involing transfer with memory + */ +#define DMA_ALL_MEM_CHANNELS 0xc0 + +/* + * MAX_DMA_LLIS can be increased if you receive + * "unable to find free lli.. rechecking..." message from DMA while in use + */ +#define MAX_DMA_HWCHANNELS 16 /*actual chanels available in SOC*/ +#define MAX_DMA_CHNAME_SIZE 32 /*maximum allowed dmach name size*/ +#ifndef MAX_DMA_ADDRESS +#define MAX_DMA_ADDRESS 0xffffffff +#endif + +#if MAX_DMA_CHANNELS >127 +#error "MAX_DMA_CHANNELS more than 127 not allowed" +#endif + +#ifndef __ASSEMBLY__ +/* + * DMA Channel lli structure + * + * The structure is used to point lli header as well as lli data + * In lli head details of Channel is strored who has allocated it. + * lli head will contain a pointer to h/w llis + * lli data will store actual information which goes directly into + * dma channel h/w registers + * + * First member of union is defined for lli head and second for lli data + */ +struct dmach_lli { + union { + struct dmach_lli * p_lli_qh; + dma_addr_t sadr; + } mem1; + union { + void *dma; + dma_addr_t dadr; + } mem2; + union { + struct dmach_lli *p_lli_hw; + struct dmach_lli *next; + } mem3; + union { + u32 cfg; + u32 cr; + } mem4; +}; + +/* DMA Channel X Hardware Registers Mapping */ +struct dmach_register { + dma_addr_t sadr; + dma_addr_t dadr; + struct dmach_lli *lli; + u32 cr; + u32 cfg; + u32 padding[(0x20 - 0x14) >> 2]; +}; + +/* DMA Controller Hardware Registers Mapping */ +struct dma_register { + u32 mis; /* Interrupt Status register *//*0x000 */ + u32 tcmis; /* Terminal Count It Status register *//*0x004 */ + u32 tcicr; /* TC Interrupt Clear register *//*0x008 */ + u32 emis; /* Error Interrupt Status register *//*0x00C */ + u32 eicr; /* Error Interrupt Clear register *//*0x010 */ + u32 tcris; /* Raw TC It status register *//*0x014 */ + u32 eris; /* Raw Error Interrupt register *//*0x018 */ + u32 echsr; /* Enabled Channels register *//*0x01C */ + u32 sbreq; /* SW Burst Request register *//*0x020 */ + u32 ssreq; /* SW Single Request register *//*0x024 */ + u32 slbreq; /* SW Last Burst Request register *//*0x028 */ + u32 slsreq; /* SW Last Single Request register *//*0x02C */ + u32 cr; /* Configure DMA controller *//*0x030 */ + u32 sync; /* To enable/Disable Sync logic *//*0x034 */ + u32 unused_1[(0x100 - 0x38) >> 2]; + /* DMA Channel Control registers */ + struct dmach_register dmach[8]; + u32 unused_2[(0xFE0 - 0x200) >> 2]; + + u32 pid_0; /* Peripheral id register: bits 7:0 *//*0xFE0 */ + u32 pid_1; /* Peripheral id register: bits 15:8 *//*0xFE4 */ + u32 pid_2; /* Peripheral id register: bits 23:16 *//*0xFE8 */ + u32 pid_3; /* Peripheral id register: bits 31:24 *//*0xFEC */ + u32 pcellid_0; /* PrimeCell id register: bits 7:0 *//*0xFF0 */ + u32 pcellid_1; /* PrimeCell id register: bits 15:8 *//*0xFF4 */ + u32 pcellid_2; /* PrimeCell id register: bits 23:16 *//*0xFF8 */ + u32 pcellid_3; /* PrimeCell id register: bits 31:24 *//*0xFFC */ +}; + +/** + * data structure for default dma peripharal setup + */ +struct dmadev_description { + char * id; + u32 config; + /*u32 usrconfig; for future use*/ +}; + +/** + * data structure for chip specific interface + */ +struct dma_soc_data { + struct dma_struct *dma_chan; + struct irq_desc *dirqdesc; + struct irqchip *dirqchip; + struct dmadev_description *config_tbl; + int config_tbl_size; +}; + +/** + * Figurative constants and enums used ............... + */ +#define NMDK_DMACH_ENABLE 1UL +#define NMDK_DMACH_HALT 1UL<<18 + +typedef enum { + DMA_OK, + DMA_CONFIG_INFO_NOT_PASSED, + DMA_SRC_DEVICE_NOT_CONFIGURED, + DMA_DEST_DEVICE_NOT_CONFIGURED, + DMA_ALLCHANELS_OCCUPIED, + DMA_LAST_ERROR +} t_dma_error; + +enum t_nmdk_dma_state { + NMDK_DMA_FREE, + NMDK_DMA_CONFIGURED, + NMDK_DMA_ENABLED, + NMDK_DMA_SUSPENDED, + NMDK_DMA_RESUMED, + NMDK_DMA_QUED, + NMDK_DMA_TASKLET_SCHEDULED, + NMDK_DMA_TASKLET_PROCESSING, + NMDK_DMA_DISABLED +}; + +/* src or destination DMA Device (peripharal) default setup parameters*/ + +/* Bitwise meaning of config field in the dmadev_description table + * -------------------------------1 DMA_DEV_BSIZE_CONFIGURABLE + * --------------------------11111- src peripharal DMA request line + * ---------------------11111------ dest peripharal DMA request line + * --------------------1----------- DMA_DEV_WIDTH_CONFIGURABLE + * -----------------111------------ SBsize + * --------------111--------------- DBsize + * -----------111------------------ SWidth + * --------111--------------------- DWidth + * -------1------------------------ Src AHB Master 0/1 + * ------1------------------------- Dest AHB Master 0/1 + * -----1-------------------------- SI bit + * ----1--------------------------- DI bit + * ---1---------------------------- Src DMA controller 0 can be used + * --1----------------------------- Src DMA controller 1 can be used + * -1------------------------------ Dest DMA controller 0 can be used + * 1------------------------------- Dest DMA controller 1 can be used + */ + +/* Configures DMA request line field for SRC/DEST dmadev type*/ +#define DMA_REQUEST_LINE(x) x<<1 + +/* + * If this bit is set, tells the configuration that the peripharal can be + * configured ans SrcPeriphal or DestPeripharal dmadevice, otherwise the + * configuration will be fixed type (for src or dest) will be decided by + * t_dma_device enum in the dmadev_description table entry. + */ +#define DMA_DEV_BSIZE_CONFIGURABLE 1UL +#define DMA_DEV_BSIZE_NOT_CONFIGURABLE 0 +#define DMA_DEV_WIDTH_CONFIGURABLE 1UL<<11 +#define DMA_DEV_WIDTH_NOT_CONFIGURABLE 0 +#define DMA_DEV_USER_CONFIGURABLE (DMA_DEV_BSIZE_CONFIGURABLE | DMA_DEV_WIDTH_CONFIGURABLE) + +/* + * The below constants tells thatn the specified DMAController can be + * used for the transfer + */ +#define DMA_DEV_DMAC0_CANBE_USED 1UL<<28 +#define DMA_DEV_DMAC1_CANBE_USED 1UL<<29 +#define DMA_DEV_BOTH_DMACS_CANBE_USED \ + (DMA_DEV_DMAC1_CANBE_USED |DMA_DEV_DMAC0_CANBE_USED) + +/* + * AMH Master 0/1 configuration constants for SRC or DEST periphatal + */ +#define DMA_AHB_M0 0 +#define DMA_AHB_M1 1UL<<24 + +/* + * Address increment bit configuration constants for SRC or DEST periphatal + */ +#define DMA_ADR_INC 1UL<<26 +#define DMA_ADR_NOINC 0 + +/* + * Width configuration constants for SRC or DEST periphatal + */ +#define DMA_WIDTH_BYTE 0 +#define DMA_WIDTH_HALFWORD 1UL<<18 +#define DMA_WIDTH_WORD 2UL<<18 +#define DMA_WIDTH_NA 7UL<<18 + +/* + * Brust size configuration constants for SRC or DEST periphatal + */ +#define DMA_BSIZE_1 0 +#define DMA_BSIZE_4 1UL<<12 +#define DMA_BSIZE_8 2UL<<12 +#define DMA_BSIZE_16 3UL<<12 +#define DMA_BSIZE_32 4UL<<12 +#define DMA_BSIZE_64 5UL<<12 +#define DMA_BSIZE_128 6UL<<12 +#define DMA_BSIZE_256 7UL<<12 + + + +/* ............ Client Driver Interface ...................*/ + +/** + * data structure for client driver interface + */ +struct nmdk_dma_info { + u32 mode; /* operation mode (xfer type/flow cntrl etc)*/ + char * srcdevtype; /* source device type*/ + char * destdevtype; /* desitnation device type*/ + u32 config; /* User programmable dmadev configuration*/ +}; + +/* Mode of operation configuration for dma channel*/ + +/* Bitwise meaning of mode configuration parameter + * ------------------------------11 Transfer type + * -----------------------------100 flow control + * ----------------------------1--- infinite dma xfer request flag + * ---------------------------1---- double buffered dma xfer request flag + * --------------------------1----- to reserve dma pipe request flag + * -------------------------1------ to disable queing on pipes + * --------------------1111-------- to indicate chanel priority request flag + */ + +enum dma_transfer_type { + MEM_TO_MEM = 0, + MEM_TO_PERIPH, + PERIPH_TO_MEM, + PERIPH_TO_PERIPH +}; + +#define FLOW_CNTRL_DMA(x) x +#define FLOW_CNTRL_PERIPH(x) (x==MEM_TO_PERIPH || x==PERIPH_TO_MEM) ? (x|0x04) :x +#define FLOW_CNTRL_SRC_PERIPH(x) (x==PERIPH_TO_PERIPH) ? 0x04 : x +#define FLOW_CNTRL_DEST_PERIPH(x) (x==PERIPH_TO_PERIPH) ? (x|0x04) : x +/*below configuration needs to be ORed with mode during configuration */ +#define DMA_INFINITE_XFER 0x08 /*To configure infinite dma transfer*/ +#define DMA_NOT_INFINITE_XFER 0x00 /*To configure infinite dma transfer*/ +#define DMA_DOUBLE_BUFFERED 0x010 /*To indicate double buffered transfer*/ +#define DMA_SINGLE_BUFFERED 0x000 /*To indicate double buffered transfer*/ +#define DMA_PIPE_RESERVED 0x020 /*To reserve h/w pipe for a channel*/ +#define DMA_PIPE_NOT_RESERVED 0x000 /*To reserve h/w pipe for a channel*/ +#define DMA_QUEUE_ENABLED 0x040 /*To enable queueing for a channel*/ +#define DMA_QUEUE_DISABLED 0x000 /*To disable queueing for a channel*/ + +#define DMA_EXCH_PRIORITY_UNDEFINED 0x0000 +#define DMA_EXCH_PRIORITY_LOW 0x0100 +#define DMA_EXCH_PRIORITY_NORMAL 0x0200 +#define DMA_EXCH_PRIORITY_HIGH 0x0400 +#define DMA_EXCH_PRIORITY_MASK (DMA_EXCH_PRIORITY_LOW | \ + DMA_EXCH_PRIORITY_NORMAL | \ + DMA_EXCH_PRIORITY_HIGH) + +/* User configuration for DMa channel*/ + +/* Bitwise meaning of user config fields + * -------------------------------1 Not useed + * ------------------------------1- src width configured + * -----------------------------1-- src Bsize configured + * --------------------------111--- not used + * -------------------------1------ dest width configured + * ------------------------1------- dest Bsize configured + * --------------------1111-------- not used + * -----------------111------------ Src Bsize + * --------------111--------------- Dest Bsize + * -----------111------------------ Src Width + * --------111--------------------- Dest Width + * 11111111------------------------ Not used + */ + +/** + * __nomadik_dma_usrdevconfig - To configure dma device parameters + * @config :config bitwise value + * @type :src/dest type (0 means src) + */ +extern u32 __nomadik_dma_usrdevconfig(u32 config, int type); + +/* User configurable option over default*/ +#define DMA_DEVCONFIG_SRC(x) __nomadik_dma_usrdevconfig((u32) x, 0) +#define DMA_DEVCONFIG_DEST(x) __nomadik_dma_usrdevconfig((u32) x, 1) +#define DMA_DEVCONFIG_BSIZE(x) (DMA_DEV_BSIZE_CONFIGURABLE | (x & DMA_BSIZE_256)) +#define DMA_DEVCONFIG_WIDTH(x) (DMA_DEV_WIDTH_CONFIGURABLE | (x & DMA_WIDTH_NA)) + +#define DMA_SRC_WIDTH_CONFIGURED 1UL<<1 +#define DMA_SRC_BSIZE_CONFIGURED 1UL<<2 +#define DMA_DEST_WIDTH_CONFIGURED 1UL<<6 +#define DMA_DEST_BSIZE_CONFIGURED 1UL<<7 + + +/* Proprioratory APIs exported by Nomadik DMA driver to service clients drivers better way */ + +/** + * request_available_dma - To Find and allocate available free dma channel and returns the same + */ +extern int request_available_dma(struct nmdk_dma_info * dmach_config_info); +/** + * suspend_dma - To pause current dma channel if transfer on it ongoing + */ +extern void suspend_dma(u32 channel); +/** + * resume_dma - To resume current dma channel if previously paused + */ +extern void resume_dma(u32 channel); +/** + * __set_dma_srcaddr - To set source dma address + */ +#define __set_dma_srcaddr(x,y) __set_dma_addr(x, (void *)y) +/** + * __set_dma_destaddr - To set destination dma address + */ +#define __set_dma_destaddr(x,y) set_dma_speed(x, (int)y) + +#endif /*__ASSEMBLY__*/ +#endif /* __INC_DMA_H */ +/* End of file - dma.h */ + --- /dev/null +++ linux-2.6.20/include/asm-arm/arch-nomadik/entry-macro.S @@ -0,0 +1,210 @@ +/* + * include/asm-arm/arch-integrator/entry-macro.S + * + * Low-level IRQ helper macros for Nomadik platforms + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +#include +#include + + .macro disable_fiq + .endm + + .macro get_irqnr_and_base, irqnr, irqstat, base, tmp +/* FIXME: should not be using soo many LDRs here */ + ldr \base, =IO_ADDRESS(NOMADIK_IC_BASE) +#ifdef VIC_PRIORITY_LOGIC_ENABLED + ldr \irqnr, [\base, #VIC_REG_ISR_VAR] @ get priority interrupt number + cmp \irqnr, #0 + bne 1003f + str \irqnr, [\base, #VIC_REG_ISR_VAR] @ write isr_var if not priority irq +#endif + mov \irqnr, #0 + ldr \irqstat, [\base, #VIC_REG_IRQSR0] @ get masked status +#ifdef VIC_REG_IRQSR1 + cmp \irqstat, #0 + bne 1001f + add \irqnr, \irqnr, #32 + ldr \irqstat, [\base, #VIC_REG_IRQSR1] @ get masked status +#endif +1001: tst \irqstat, #15 + bne 1002f + add \irqnr, \irqnr, #4 + movs \irqstat, \irqstat, lsr #4 + bne 1001b +1002: tst \irqstat, #1 + bne 1003f + add \irqnr, \irqnr, #1 + movs \irqstat, \irqstat, lsr #1 + bne 1002b +1003: /* EQ will be set if no irqs pending */ + .endm + + .macro l2_cache_enable base, tmp + /* enable L2 cache */ +#ifdef CONFIG_NOMADIK_ENABLE_L2CACHE + ldr \base, =NOMADIK_L2CC_BASE + ldr \tmp, =0x01 + str \tmp, [\base, #0x100] +#endif + .endm + + .macro l2_cache_disable base, tmp + /* disables L2 cache */ +#ifdef CONFIG_NOMADIK_ENABLE_L2CACHE + ldr \base, =NOMADIK_L2CC_BASE + ldr \tmp, =0x0 + str \tmp, [\base, #0x100] +#endif + .endm + + .macro l2_cache_configure base, tmp + /* configure L2 Cache Controller */ +#ifdef CONFIG_NOMADIK_ENABLE_L2CACHE + ldr \base, =NOMADIK_L2CC_BASE + ldr \tmp, =0x0 + str \tmp, [\base, #0xf40] @ Write Back forced + ldr \tmp, [\base, #0x104] @ read aux_ctrl_reg + ldr \tmp, =0x00830249 @ Write Allocate + str \tmp, [\base, #0x104] @ write aux_ctrl_reg + ldr \tmp, =0 +@ str \tmp, [\base, #0x77c] @ do not invalidate data in n way + str \tmp, [\base, #0x900] @ do not lock way n on data side + str \tmp, [\base, #0x904] @ do not lock way n on instruction side + str \tmp, [\base, #0x730] @ drain all buffers (WB, EB, WA) + +#endif + .endm + + .macro l2_cache_clean base, tmp + /* clean L2 Cache */ +#ifdef CONFIG_NOMADIK_ENABLE_L2CACHE + ldr \base, =NOMADIK_L2CC_BASE + ldr \tmp, =0xff + str \tmp, [\base, #0x7bc] @ clean data in n way*/ +1004: + ldr \base, =NOMADIK_L2CC_BASE + ldr \tmp, [\base, #0x7bc] + ldr \base, =0 + cmp \tmp, \base + bne 1004b @ loop for completion +#endif + .endm + + .macro l2_cache_lean_and_invalidate base, tmp + /* clean and invalidates L2 Cache */ +#ifdef CONFIG_NOMADIK_ENABLE_L2CACHE + ldr \base, =NOMADIK_L2CC_BASE + ldr \tmp, =0xff + str \tmp, [\base, #0x7fc] @ clean and invalidate data in n way*/ +1005: + ldr \base, =NOMADIK_L2CC_BASE + ldr \tmp, [\base, #0x7fc] + ldr \base, =0 + cmp \tmp, \base + bne 1005b @ loop for completion +#endif + .endm + + .macro l2_cache_invalidate base, tmp + /* invalidates L2 Cache */ +#ifdef CONFIG_NOMADIK_ENABLE_L2CACHE + ldr \base, =NOMADIK_L2CC_BASE + ldr \tmp, =0xff + str \tmp, [\base, #0x77c] @ invalidate data in n way*/ +1006: + ldr \base, =NOMADIK_L2CC_BASE + ldr \tmp, [\base, #0x77c] + ldr \base, =0 + cmp \tmp, \base + bne 1006b @ loop for completion +#endif + .endm + + .macro l2_cache_sync base, tmp + /* invalidates L2 Cache */ +#ifdef CONFIG_NOMADIK_ENABLE_L2CACHE + ldr \base, =NOMADIK_L2CC_BASE + ldr \tmp, =0x0 + str \tmp, [\base, #0x730] @ invalidate data in n way*/ +#endif + .endm + + .macro v_l2_cache_sync base, tmp + /* invalidates L2 Cache */ +#ifdef CONFIG_NOMADIK_ENABLE_L2CACHE + ldr \base, =IO_ADDRESS(NOMADIK_L2CC_BASE) + ldr \tmp, =0x0 + str \tmp, [\base, #0x730] @ invalidate data in n way*/ +#endif + .endm + + .macro v_l2_cache_clean_and_invalidate base, tmp + /* clean and invalidates L2 Cache */ +#ifdef CONFIG_NOMADIK_ENABLE_L2CACHE + ldr \base, =IO_ADDRESS(NOMADIK_L2CC_BASE) + ldr \tmp, =0xff + str \tmp, [\base, #0x7fc] @ clean and invalidate data in n way*/ +2005: + ldr \base, =IO_ADDRESS(NOMADIK_L2CC_BASE) + ldr \tmp, [\base, #0x7fc] + ldr \base, =0 + cmp \tmp, \base + bne 2005b @ loop for completion +#endif + .endm + + .macro v_l2_cache_enable base, tmp + /* enable L2 cache */ +#ifdef CONFIG_NOMADIK_ENABLE_L2CACHE + ldr \base, =IO_ADDRESS(NOMADIK_L2CC_BASE) + ldr \tmp, =0x01 + str \tmp, [\base, #0x100] +#endif + .endm + + .macro v_l2_cache_disable base, tmp + /* disables L2 cache */ +#ifdef CONFIG_NOMADIK_ENABLE_L2CACHE + ldr \base, =IO_ADDRESS(NOMADIK_L2CC_BASE) + ldr \tmp, =0x0 + str \tmp, [\base, #0x100] +#endif + .endm + + .macro v_l2_cache_configure base, tmp + /* configure L2 Cache Controller */ +#ifdef CONFIG_NOMADIK_ENABLE_L2CACHE + ldr \base, =IO_ADDRESS(NOMADIK_L2CC_BASE) + ldr \tmp, =0x0 + str \tmp, [\base, #0xf40] @ Write through forced + ldr \tmp, [\base, #0x104] @ read aux_ctrl_reg + ldr \tmp, =0x0830249 + str \tmp, [\base, #0x104] @ write aux_ctrl_reg + ldr \tmp, =0 + str \tmp, [\base, #0x77c] @ do not invalidate data in n way + str \tmp, [\base, #0x900] @ do not lock way n on data side + str \tmp, [\base, #0x904] @ do not lock way n on instruction side + str \tmp, [\base, #0x730] @ drain all buffers (WB, EB, WA) + +#endif + .endm + + .macro v_l2_cache_invalidate base, tmp + /* invalidates L2 Cache */ +#ifdef CONFIG_NOMADIK_ENABLE_L2CACHE + ldr \base, =IO_ADDRESS(NOMADIK_L2CC_BASE) + ldr \tmp, =0xff + str \tmp, [\base, #0x77c] @ invalidate data in n way*/ +1006: + ldr \base, =NOMADIK_L2CC_BASE + ldr \tmp, [\base, #0x77c] + ldr \base, =0 + cmp \tmp, \base + bne 1006b @ loop for completion +#endif + .endm --- /dev/null +++ linux-2.6.20/include/asm-arm/arch-nomadik/epio.h @@ -0,0 +1,24 @@ +/* + * linux/include/asm-arm/arch-nomadik/epio-nomadik.h + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifndef __ASM_ARM_ARCH_EPIO_H +#define __ASM_ARM_ARCH_EPIO_H + +#include + +#endif /*__ASM_ARM_ARCH_EPIO_H */ --- /dev/null +++ linux-2.6.20/include/asm-arm/arch-nomadik/fsmc.h @@ -0,0 +1,203 @@ +/* include/asm-arm/arch-nomadik/fsmc.h + * + * Copyright 2004, STMicroelectronics, inc + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * $Id$ + */ +#ifndef _NOMADIK_FSMC_H_ +#define _NOMADIK_FSMC_H_ + +#define NMDK_NAND 1 +#define NMDK_ONENAND 2 + +#include +/*----------------------------------------------------------------------------- + FSMC BTRs------Bank timing register + BIT---MASK +-----------------------------------------------------------------------------*/ +#define FSMC_ADDSET 0x0000000F // Start Bit, start condition generated +#define FSMC_ADDHLD 0x000000F0 +#define FSMC_DATAST 0x0000FF00 + +#define FSMC_BUSTURN 0x000F0000 +#define FSMC_CLKDIV 0x00F00000 // Start Bit, start condition generated +#define FSMC_DATLAT 0x0F000000 + +#define FSMC_ADDSET_POS 0 +#define FSMC_ADDHLD_POS 4 +#define FSMC_DATAST_POS 8 + +#define FSMC_BUSTURN_POS 16 +#define FSMC_CLKDIV_POS 20 +#define FSMC_DATLAT_POS 24 + +/*------------------------------------------------------------------------ + FSMC BCRs------Bank control register + BIT---MASK +------------------------------------------------------------------------*/ +#define FSMC_MBKEN STD_MASK_BIT0 +#define FSMC_MUXEN STD_MASK_BIT1 + +#define FSMC_MTYP (STD_MASK_BIT2 | STD_MASK_BIT3) +#define FSMC_MWID (STD_MASK_BIT4 | STD_MASK_BIT5) + +#define FSMC_FRSTLVL STD_MASK_BIT6 +#define FSMC_FRPRLVL STD_MASK_BIT7 +#define FSMC_BURSTEN STD_MASK_BIT8 +#define FSMC_WAITPOL STD_MASK_BIT9 +#define FSMC_WRAPMOD STD_MASK_BIT10 +#define FSMC_WAITCFG STD_MASK_BIT11 +#define FSMC_WREN STD_MASK_BIT12 +#define FSMC_WAITEN STD_MASK_BIT13 + +/*------------------------------------------------------------------------ + BIT POSITION USED while setting bits in register +------------------------------------------------------------------------*/ +#define FSMC_MBKEN_POS 0 +#define FSMC_MUXEN_POS 1 +#define FSMC_MTYP_POS 2 +#define FSMC_MWID_POS 4 +#define FSMC_FRSTLVL_POS 6 +#define FSMC_FRPRLVL_POS 7 +#define FSMC_BURSTEN_POS 8 +#define FSMC_WAITPOL_POS 9 +#define FSMC_WRAPMOD_POS 10 +#define FSMC_WAITCFG_POS 11 +#define FSMC_WREN_POS 12 +#define FSMC_WAITEN_POS 13 + +#define NOMADIK_FSMC_VA IO_ADDRESS(NOMADIK_FSMC_BASE) + +#define FSMC_BCR0 0x00 +#define FSMC_BTR0 0x04 +#define FSMC_BCR1 0x08 +#define FSMC_BTR1 0x0c +#define FSMC_PCR0 0x40 +#define FSMC_PMEM0 0x48 +#define FSMC_PATT0 0x4C +#define FSMC_BTR0 0x04 +#define FSMC_PCR1 0x60 +#define FSMC_PMEM1 0x68 +#define FSMC_PATT1 0x6C + +#define DEFAULT_BCR0_VALUE 0x0000105B +#define DEFAULT_BTR0_VALUE 0x0A200551 + +#define DEFAULT_PCR0_VALUE 0x0000001E +#define DEFAULT_PMEM0_VALUE 0x000D0A00 +#define DEFAULT_PATT0_VALUE 0x00100A00 + +#define FSMC_PUT_BITS(reg,val,shift,mask) ((reg) = (((reg) & ~(mask)) | (((u32)val << shift) & (mask)))) + +typedef enum { + FSMC_BANK0 = 0, + FSMC_BANK1 = 1, + FSMC_BANK2 = 2, + FSMC_BANK3 = 3 +} fsmc_bank_index; + +typedef struct { + uint8 data_latency_phase; + uint8 clk_div; + uint8 bus_turn_phase; + uint8 data_phase; + uint8 addr_hold_phase; + uint8 addr_setup_phase; +} fsmc_sram_nor_tmng; + +/*--------------------------------------------------------------------------- + Error Types +-----------------------------------------------------------------------------*/ + +typedef enum { + FSMC_OK = 0, + FSMC_UNSUPPORTED_HW = -1, + FSMC_INVALID_PARAMETER = -2, + FSMC_UNSUPPORTED_FEATURE = -3, + FSMC_REQUEST_NOT_APPLICABLE = -4, + + FSMC_OPERATION_FAILED = -5, + FSMC_NOR_VPP_INVALID = -6, + FSMC_NOR_BLOCK_LOCKED = -7, + FSMC_NOR_BLOCK_LOCKED_DOWN = -8 +} fsmc_error; + +/*----------------------------------------------------------------------------- + FSMC power management specifc structure. +-----------------------------------------------------------------------------*/ + +typedef enum { + FSMC_STATE_DISABLE = 0, + FSMC_STATE_ENABLE = 1 +} fsmc_state; + +typedef enum { + FSMC_WAIT_ACTIVE_BEFORE_WAIT_STATE = 0, + FSMC_WAIT_ACTIVE_DURING_WAIT_STATE = 1 +} fsmc_wait_tmng_cfg; + +typedef enum { + FSMC_POLARITY_ACTIVE_LOW = 0, + FSMC_POLARITY_ACTIVE_HIGH = 1 +} fsmc_sig_polarity; + +typedef enum { + FSMC_SIG_LOW = 0, + FSMC_SIG_HIGH = 1 +} fsmc_sig_state; + +typedef enum { + FSMC_BUS_8_BIT = 0, + FSMC_BUS_16_BIT = 1, + FSMC_BUS_32_BIT = 2 +} fsmc_bus_width; + +typedef enum { + FSMC_MEM_SRAM_ROM = 0, + FSMC_MEM_NAND_FLASH = 1, + + FSMC_MEM_NOR_FLASH = 2, + FSMC_MEM_PC_CF = 3 +} fsmc_mem_type; + +typedef struct { + fsmc_state wait_enable; + fsmc_state write_enable; + fsmc_wait_tmng_cfg wait_tmng_cfg; + fsmc_state wrapped_burst_mode; + fsmc_sig_polarity wait_sig_polarity; + fsmc_state burst_mode; + fsmc_sig_state flash_write_prot; + fsmc_sig_state flash_reset; + fsmc_bus_width bus_width; + fsmc_mem_type mem_type; + fsmc_state addr_data_muxed; + fsmc_state bank_enable; +} fsmc_sram_nor_ctrl; + +struct fsmc_platform_data{ + int (*init)(void); +}; + + + +fsmc_error nmdkfsmc_set_sram_nor_timing(fsmc_bank_index bank_no, + fsmc_sram_nor_tmng * p_bank_tmng); +fsmc_error nmdkfsmc_set_sram_nor_ctrl(fsmc_bank_index bank_no, + fsmc_sram_nor_ctrl * p_bank_ctrl); + +#endif --- /dev/null +++ linux-2.6.20/include/asm-arm/arch-nomadik/gpio.h @@ -0,0 +1,529 @@ +/* + * linux/include/asm-arm/arch-nomadik/gpio.h + * + * Copyright (C) 1999 ARM Limited + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _NOMADIK_GPIO_h +#define _NOMADIK_GPIO_h + +#include +#include +#include + +#define GPIO_PINS_PER_BLOCK 32 +#define GPIO_BLOCKS_COUNT (GPIO_TOTAL_PINS/GPIO_PINS_PER_BLOCK +1) +#define GPIO_PIN2BLKIRQ(x) (x/GPIO_PINS_PER_BLOCK + IRQ_GPIO0) +#define GPIO_PINIRQ2BLKIRQ(x) (GPIO_PIN_FOR_IRQ(x)/GPIO_PINS_PER_BLOCK + IRQ_GPIO0) + +#define GPIO_ALL_ZERO 0x00000000 +#define GPIO_IRQ_BIT_POSITION_1 (0xAAAAAAAA) +#define GPIO_IRQ_BIT_POSITION_2 (0xCCCCCCCC) +#define GPIO_IRQ_BIT_POSITION_3 (0xF0F0F0F0) +#define GPIO_IRQ_BIT_POSITION_4 (0xFF00FF00) +#define GPIO_IRQ_BIT_POSITION_5 (0xFFFF0000) + +#define GPIO_SHIFT8 0x08 +#define GPIO_SHIFT16 0x10 +#define GPIO_SHIFT24 0x18 +#define GPIO_8BIT_MASK 0xFF +#define GPIO_12BIT_MASK 0xFFF +#define GPIO_16BIT_MASK 0xFFFF +#define GPIO_32BIT_MASK 0xFFFFFFFF +#define GPIO_8BIT_HIGH 0xFF +#define GPIO_8BIT_LOW 0x00 + +#if defined(CONFIG_NOMADIK_NDK15_REV2_MMC) +#define GPIO_MSP0_MASK 0x007E0000 +#define GPIO_SD_CARD_MASK1 0x800000 +#else +#define GPIO_SD_CARD_MASK1 0x0 +#define GPIO_MSP0_MASK 0x00FE0000 +#endif + +struct gpio_register { + uint32 gpio_dat; /* GPIO data register *//*0x000 */ + uint32 gpio_dats; /* GPIO data Set register *//*0x004 */ + uint32 gpio_datc; /* GPIO data Clear register *//*0x008 */ + uint32 gpio_pdis; /* GPIO Pull disable register *//*0x00C */ + uint32 gpio_dir; /* GPIO data direction register *//*0x010 */ + uint32 gpio_dirs; /* GPIO data dir Set register *//*0x014 */ + uint32 gpio_dirc; /* GPIO data dir Clear register *//*0x018 */ + uint32 gpio_slpm; /* GPIO Sleep mode register *//*0x01C */ + uint32 gpio_afsa; /* GPIO AltFun A Select reg *//*0x020 */ + uint32 gpio_afsb; /* GPIO AltFun B Select reg *//*0x024 */ +#if defined(__STN_8815) + uint32 reserved_1[(0x040 - 0x028) >> 2]; /*0x030 */ + uint32 gpio_rimsc; /* GPIO rising edge intr set/clear *//*0x040 */ + uint32 gpio_fimsc; /* GPIO falling edge interrupt set/clear register *//*0x044 */ + uint32 gpio_mis; /* GPIO masked interrupt status register *//*0x048 */ + uint32 gpio_ic; /* GPIO Interrupt Clear register *//*0x04C */ + uint32 gpio_rwimsc; /* GPIO Rising-edge Wakeup IMSC register *//*0x050 */ + uint32 gpio_fwimsc; /* GPIO Falling-edge Wakeup IMSC register *//*0x054 */ + uint32 gpio_wks; /* GPIO Wakeup Status register *//*0x058 */ + uint32 reserved_2[(0x080 - 0x05C) >> 2]; + uint32 gpio_itcr; /* Integration Test control register *//*0x080 */ + uint32 gpio_itop; /* Intergration Test output register *//*0x084 */ + uint32 reserved_3[(0xFE0 - 0x088) >> 2]; +#elif defined(__STN_8810) + uint32 gpio_dben; /* GPIO Debouncing Enable register *//*0x028 */ + uint32 gpio_dbdiv; /* GPIO Debouncing Divider register *//*0x02C */ + uint32 gpio_is; /* GPIO interrupt sense register *//*0x030 */ + uint32 gpio_ibe; /* GPIO Interrupt both edges register *//*0x034 */ + uint32 gpio_iev; /* GPIO interrupt event register *//*0x038 */ + uint32 gpio_imsc; /* GPIO interrupt mask Set Clear register *//*0x03C */ + uint32 gpio_ris; /* GPIO raw interrupt status register *//*0x040 */ + uint32 gpio_mis; /* GPIO masked interrupt status register *//*0x044 */ + uint32 gpio_ic; /* GPIO interrupt clear register *//*0x048 */ + uint32 reserved_1; /*0x04C */ + uint32 gpio_wklev; /* GPIO Wakeup Level register *//*0x050 */ + uint32 gpio_wken; /* GPIO Wakeup Enable register *//*0x054 */ + uint32 reserved_2[(0x080 - 0x058) >> 2]; + uint32 gpio_itcr; /* Integration Test control register *//*0x080 */ + uint32 gpio_itipa_0; /* Intergration Test input register A0 *//*0x084 */ + uint32 gpio_itipb_0; /* Integration Test input register B0 *//*0x088 */ + uint32 gpio_itipc_0; /* Intergration Test input register C0 *//*0x08C */ + uint32 gpio_itipa_1; /* Intergration Test input register A1 *//*0x090 */ + uint32 gpio_itipb_1; /* Integration Test input register B1 *//*0x094 */ + uint32 gpio_itipc_1; /* Intergration Test input register C1 *//*0x098 */ + uint32 reserved_3; + uint32 gpio_itop; /* Integration Test Output register *//*0x0A0 */ + uint32 gpio_itopa; /* Integration Test Output register A *//*0x0A4 */ + uint32 gpio_itopb; /* Integration Test Output register B *//*0x0A8 */ + uint32 gpio_itopc; /* Integration Test Output register C *//*0x0AC */ + uint32 reserved_4[(0xFE0 - 0x0B0) >> 2]; +#endif + uint32 gpio_periph_id_0; /* Peripheral identification register bits 7:0 *//*0xFE0 */ + uint32 gpio_periph_id_1; /* Peripheral identification register bits 15:8 *//*0xFE4 */ + uint32 gpio_periph_id_2; /* Peripheral identification register bits 23:16 *//*0xFE8 */ + uint32 gpio_periph_id_3; /* Peripheral identification register bits 31:24 *//*0xFEC */ + uint32 gpio_pcell_id_0; /* Peripheral identification register bits 7:0 *//*0xFF0 */ + uint32 gpio_pcell_id_1; /* Peripheral identification register bits 15:8 *//*0xFF4 */ + uint32 gpio_pcell_id_2; /* Peripheral identification register bits 23:16 *//*0xFF8 */ + uint32 gpio_pcell_id_3; /* Peripheral identification register bits 31:24 *//*0xFFC */ +}; + +/* Error values returned by functions */ +typedef enum { + GPIO_OK = 0, /* (0) */ + GPIO_UNSUPPORTED_HW = NOMADIK_UNSUPPORTED_HW, /* (-2) */ + GPIO_UNSUPPORTED_FEATURE = NOMADIK_UNSUPPORTED_FEATURE, /* (-3) */ + GPIO_INVALID_PARAMETER = NOMADIK_INVALID_PARAMETER, /* (-4) */ + GPIO_REQUEST_NOT_APPLICABLE = NOMADIK_REQUEST_NOT_APPLICABLE, /* (-5) */ + GPIO_REQUEST_PENDING = NOMADIK_REQUEST_PENDING, /* (-6) */ + GPIO_NOT_CONFIGURED = NOMADIK_NOT_CONFIGURED, /* (-7) */ + GPIO_INTERNAL_ERROR = NOMADIK_INTERNAL_ERROR, /* (-8) */ + GPIO_INTERNAL_EVENT = NOMADIK_INTERNAL_EVENT, + GPIO_REMAINING_EVENT = NOMADIK_REMAINING_PENDING_EVENTS, + GPIO_NO_MORE_PENDING_EVENT = NOMADIK_NO_MORE_PENDING_EVENT, + GPIO_INVALID_CLIENT = -25, + GPIO_INVALID_PIN = -26, + GPIO_PIN_BUSY = -27, + GPIO_PIN_NOT_ALLOCATED = -28, + GPIO_WRONG_CLIENT = -29, + GPIO_UNSUPPORTED_ALTFUNC = -30, + +} gpio_error; + +/*GPIO DEVICE ID */ +typedef enum { + GPIO_DEVICE_ID_0, + GPIO_DEVICE_ID_1, + GPIO_DEVICE_ID_2, + GPIO_DEVICE_ID_3, + GPIO_DEVICE_ID_INVALID +} gpio_device_id; + +/* + * Pin description To be used in SOFTWARE mode: refers to a pin. + */ +typedef enum { + GPIO_PIN_0, + GPIO_PIN_1, + GPIO_PIN_2, + GPIO_PIN_3, + GPIO_PIN_4, + GPIO_PIN_5, + GPIO_PIN_6, + GPIO_PIN_7, + GPIO_PIN_8, + GPIO_PIN_9, + GPIO_PIN_10, + GPIO_PIN_11, + GPIO_PIN_12, + GPIO_PIN_13, + GPIO_PIN_14, + GPIO_PIN_15, + GPIO_PIN_16, + GPIO_PIN_17, + GPIO_PIN_18, + GPIO_PIN_19, + GPIO_PIN_20, + GPIO_PIN_21, + GPIO_PIN_22, + GPIO_PIN_23, + GPIO_PIN_24, + GPIO_PIN_25, + GPIO_PIN_26, + GPIO_PIN_27, + GPIO_PIN_28, + GPIO_PIN_29, + GPIO_PIN_30, + GPIO_PIN_31, + GPIO_PIN_32, + GPIO_PIN_33, + GPIO_PIN_34, + GPIO_PIN_35, + GPIO_PIN_36, + GPIO_PIN_37, + GPIO_PIN_38, + GPIO_PIN_39, + GPIO_PIN_40, + GPIO_PIN_41, + GPIO_PIN_42, + GPIO_PIN_43, + GPIO_PIN_44, + GPIO_PIN_45, + GPIO_PIN_46, + GPIO_PIN_47, + GPIO_PIN_48, + GPIO_PIN_49, + GPIO_PIN_50, + GPIO_PIN_51, + GPIO_PIN_52, + GPIO_PIN_53, + GPIO_PIN_54, + GPIO_PIN_55, + GPIO_PIN_56, + GPIO_PIN_57, + GPIO_PIN_58, + GPIO_PIN_59, + GPIO_PIN_60, + GPIO_PIN_61, + GPIO_PIN_62, + GPIO_PIN_63, + GPIO_PIN_64, + GPIO_PIN_65, + GPIO_PIN_66, + GPIO_PIN_67, + GPIO_PIN_68, + GPIO_PIN_69, + GPIO_PIN_70, + GPIO_PIN_71, + GPIO_PIN_72, + GPIO_PIN_73, + GPIO_PIN_74, + GPIO_PIN_75, + GPIO_PIN_76, + GPIO_PIN_77, + GPIO_PIN_78, + GPIO_PIN_79, + GPIO_PIN_80, + GPIO_PIN_81, + GPIO_PIN_82, + GPIO_PIN_83, + GPIO_PIN_84, + GPIO_PIN_85, + GPIO_PIN_86, + GPIO_PIN_87, + GPIO_PIN_88, + GPIO_PIN_89, + GPIO_PIN_90, + GPIO_PIN_91, + GPIO_PIN_92, + GPIO_PIN_93, + GPIO_PIN_94, + GPIO_PIN_95, + GPIO_PIN_96, + GPIO_PIN_97, + GPIO_PIN_98, + GPIO_PIN_99, + GPIO_PIN_100, + GPIO_PIN_101, + GPIO_PIN_102, + GPIO_PIN_103, + GPIO_PIN_104, + GPIO_PIN_105, + GPIO_PIN_106, + GPIO_PIN_107, + GPIO_PIN_108, + GPIO_PIN_109, + GPIO_PIN_110, + GPIO_PIN_111, + GPIO_PIN_112, + GPIO_PIN_113, + GPIO_PIN_114, + GPIO_PIN_115, + GPIO_PIN_116, + GPIO_PIN_117, + GPIO_PIN_118, + GPIO_PIN_119, + GPIO_PIN_120, + GPIO_PIN_121, + GPIO_PIN_122, + GPIO_PIN_123 +} gpio_pin; + +/* + * Alternate Function: + * refered in altfun_table to pointout particular altfun to be enabled + * when using GPIO_ALT_FUNCTION A/B/C enable/disable operation + */ +typedef enum { + GPIO_ALT_UART_0_MODEM, + GPIO_ALT_UART_0_NO_MODEM, + GPIO_ALT_UART_1, + GPIO_ALT_UART_2, + GPIO_ALT_I2C_0, + GPIO_ALT_I2C_1, + GPIO_ALT_MSP_0, + GPIO_ALT_MSP_1, + GPIO_ALT_MSP_2, + GPIO_ALT_SSP, + GPIO_ALT_MM_CARD, + GPIO_ALT_SD_CARD, + GPIO_ALT_DMA_0, + GPIO_ALT_DMA_1, + GPIO_ALT_HSI0, + GPIO_ALT_CCIR656_INPUT, + GPIO_ALT_CCIR656_OUTPUT, + GPIO_ALT_LCD_PANEL, + GPIO_ALT_MDIF, + GPIO_ALT_SDRAM, + GPIO_ALT_HAMAC_AUDIO_DBG, + GPIO_ALT_HAMAC_VIDEO_DBG, + GPIO_ALT_CLOCK_RESET, + GPIO_ALT_TSP, + GPIO_ALT_IRDA, + GPIO_ALT_USB_MINIMUM, + GPIO_ALT_USB_I2C, + GPIO_ALT_OWM, + GPIO_ALT_PWL, + GPIO_ALT_FSMC, + GPIO_ALT_COMP_FLASH, + GPIO_ALT_SRAM_NOR_FLASH, + GPIO_ALT_FSMC_ADDLINE_0_TO_15, + GPIO_ALT_SCROLL_KEY, + GPIO_ALT_MSHC, + GPIO_ALT_HPI, + GPIO_ALT_USB_OTG, + GPIO_ALT_SDIO, + GPIO_ALT_HSMMC, + GPIO_ALT_FSMC_ADD_DATA_0_TO_25, + GPIO_ALT_HSI1, + GPIO_ALT_NOR, + GPIO_ALT_NAND, + GPIO_ALT_KEYPAD, + GPIO_ALT_VPIP, + GPIO_ALT_CAM, + GPIO_ALT_CCP1, +#ifdef CONFIG_NOMADIK_NHK15 + GPIO_ALT_ETHERNET, + GPIO_ALT_ETM, +#endif +#ifdef CONFIG_MTD_ONENAND + GPIO_ALT_ONENAND, +#endif + GPIO_ALT_FUNMAX /* Add new alt func before this */ +} gpio_alt_function; + +/* GPIO Block Id : + Select a 16-bit or 32-bit block among all the GPIO. */ +typedef enum { + GPIO_BLOCK_32_BITS_0_TO_31, /* GPIO[31:0], Byte 1, 2, 3 & 4 */ + GPIO_BLOCK_32_BITS_32_TO_63, /* GPIO[63:32], Byte 5, 6, 7 & 8 */ + GPIO_BLOCK_32_BITS_64_TO_95, /* GPIO[95:64], Byte 9, 10, 11 & 12 */ + GPIO_BLOCK_32_BITS_96_TO_123, /* GPIO[123:96], Byte 13, 14, 15 & 16 */ + GPIO_BLOCK_16_BITS_0_TO_15, /* GPIO[15:0],Byte 1 & 2 */ + GPIO_BLOCK_16_BITS_8_TO_23, /* GPIO[23:8], Byte 2 & 3 */ + GPIO_BLOCK_16_BITS_16_TO_31, /* GPIO[31:16], Byte 3 & 4 */ + GPIO_BLOCK_16_BITS_24_TO_39, /* GPIO[39:24], Byte 4 & 5 */ + GPIO_BLOCK_16_BITS_32_TO_47, /* GPIO[47:32], Byte 5 & 6 */ + GPIO_BLOCK_16_BITS_40_TO_55, /* GPIO[55:40], Byte 6 & 7 */ + GPIO_BLOCK_16_BITS_48_TO_63, /* GPIO[63:48], Byte 7 & 8 */ + GPIO_BLOCK_16_BITS_56_TO_71, /* GPIO[71:56], Byte 8 & 9 (Not for STn8800) */ + GPIO_BLOCK_16_BITS_64_TO_79, /* GPIO[79:64], Byte 9 & 10 (Not for STn8800) */ + GPIO_BLOCK_16_BITS_72_TO_87, /* GPIO[87:72], Byte 10 & 11(Not for STn8800) */ + GPIO_BLOCK_16_BITS_80_TO_95, /* GPIO[95:80], Byte 11 & 12(Not for STn8800) */ + GPIO_BLOCK_16_BITS_88_TO_103, /* GPIO[103:88], Byte 12 & 13(Not for STn8800) */ + GPIO_BLOCK_16_BITS_96_TO_111, /* GPIO[111:96], Byte 13 & 14(Not for STn8800 & STn8810) */ + GPIO_BLOCK_16_BITS_104_TO_119, /* GPIO[119:104], Byte 14 & 15(Not for STn8800 & STn8810) */ + GPIO_BLOCK_16_BITS_112_TO_123 /* GPIO[123:112], Byte 14 & 15(Not for STn8800 & STn8810) */ +} gpio_block_id; + +/* Defines pin assignment(Software mode or Alternate mode) */ +typedef enum { + GPIO_MODE_LEAVE_UNCHANGED, /* Parameter will be ignored by the function. */ + GPIO_MODE_SOFTWARE, /* Pin connected to GPIO (SW controlled) */ + GPIO_ALTF_A, /* Pin connected to alternate function 1 (HW periph 1) */ + GPIO_ALTF_B, /* Pin connected to alternate function 2 (HW periph 2) */ + GPIO_ALTF_C, /* Pin connected to alternate function 3 (HW periph 3) */ + GPIO_ALTF_FIND, /* Pin connected to alternate function 3 (HW periph 3) */ + GPIO_ALTF_DISABLE /* Pin connected to alternate function 3 (HW periph 3) */ +} gpio_mode; + +/* Defines GPIO pin direction */ +typedef enum { + GPIO_DIR_LEAVE_UNCHANGED, /* Parameter will be ignored by the function. */ + GPIO_DIR_INPUT, /* GPIO set as input */ + GPIO_DIR_OUTPUT /* GPIO set as output */ +} gpio_direction; + +/* Interrupt trigger mode */ +typedef enum { + GPIO_TRIG_LEAVE_UNCHANGED, /* Parameter will be ignored by the function */ + GPIO_TRIG_DISABLE, /* Triggers no IT */ + GPIO_TRIG_RISING_EDGE, /* Triggers an IT on a rising edge */ + GPIO_TRIG_FALLING_EDGE, /* Triggers an IT on a falling edge */ + GPIO_TRIG_BOTH_EDGES, /* Triggers an IT on a rising and a falling edge */ + GPIO_TRIG_HIGH_LEVEL, /* Triggers an IT on a high level */ + GPIO_TRIG_LOW_LEVEL /* Triggers an IT on a low level */ +} gpio_trig; /* Interrupt trigger mode, or disable */ + +/* Debounce logic state */ +typedef enum { + GPIO_DEBOUNCE_UNCHANGED, /* Parameter will be ignored by the function. */ + GPIO_DEBOUNCE_DISABLE, /* Debounce is disabled. */ + GPIO_DEBOUNCE_ENABLE /* Debounce is enabled. */ +} gpio_debounce; + +//TYPEDEF_STRUCT_T_GPIO_REGISTER + +/* Debounce Time explicit value & units */ +typedef enum { + GPIO_DEBOUNCE_TIME_30_MICROSEC, + GPIO_DEBOUNCE_TIME_60_MICROSEC, + GPIO_DEBOUNCE_TIME_120_MICROSEC, + GPIO_DEBOUNCE_TIME_240_MICROSEC, + GPIO_DEBOUNCE_TIME_490_MICROSEC, + GPIO_DEBOUNCE_TIME_980_MICROSEC, + GPIO_DEBOUNCE_TIME_2_MILLISEC, + GPIO_DEBOUNCE_TIME_4_MILLISEC, + GPIO_DEBOUNCE_TIME_8_MILLISEC, + GPIO_DEBOUNCE_TIME_16_MILLISEC, + GPIO_DEBOUNCE_TIME_31_MILLISEC, + GPIO_DEBOUNCE_TIME_62_MILLISEC, + GPIO_DEBOUNCE_TIME_125_MILLISEC, + GPIO_DEBOUNCE_TIME_250_MILLISEC, + GPIO_DEBOUNCE_TIME_500_MILLISEC, + GPIO_DEBOUNCE_TIME_1_SEC +} gpio_debounce_time; + +/* Configuration parameters for one GPIO pin.*/ +typedef struct { + gpio_mode mode; /* Defines mode (SOFTWARE or Alternate). */ + gpio_direction direction; /* Define pin direction (in SOFTWARE mode only). */ + gpio_trig trig; /* Interrupt trigger (in SOFTWARE mode only) */ + gpio_debounce debounce; /* Debounce logic control for pin (in SOFTWARE mode only) */ + gpio_debounce_time debounce_time; /* Debounce time for pin (in SOFTWARE mode only) */ + char *dev_name; /* Name of client driver who owns the gpio pin */ +} gpio_config; + +/* GPIO pin data*/ +typedef enum { + GPIO_DATA_LOW, /* GPIO pin status is low. */ + GPIO_DATA_HIGH /* GPIO pin status is high. */ +} gpio_data; + +/* GPIO behaviour in sleep mode */ +typedef enum { + GPIO_SLEEP_MODE_LEAVE_UNCHANGED, /* Parameter will be ignored by the function. */ + GPIO_SLEEP_MODE_INPUT_DEFAULTVOLT, /* GPIO is an input with pull up/down enabled + when in sleep mode. */ + GPIO_SLEEP_MODE_CONTROLLED_BY_GPIO /* GPIO pin is controlled by GPIO IP. So mode, + direction and data values for GPIO pin in + sleep mode are determined by configuration + set to GPIO pin before entering to sleep mode. */ +} gpio_sleep_mode; + +/* GPIO ability to wake the system up from sleep mode.*/ +typedef enum { + GPIO_WAKE_LEAVE_UNCHANGED, /* Parameter will be ignored by the function. */ + GPIO_WAKE_DISABLE, /* GPIO will not wake the system from sleep mode. */ + GPIO_WAKE_LOW_LEVEL, /* GPIO will wake the system up on a LOW level. */ + GPIO_WAKE_HIGH_LEVEL, /* GPIO will wake the system up on a HIGH level. */ + GPIO_WAKE_RISING_EDGE, /* GPIO will wake the system up on a RISING edge. */ + GPIO_WAKE_FALLING_EDGE, /* GPIO will wake the system up on a FALLING edge. */ + GPIO_WAKE_BOTH_EDGES /* GPIO will wake the system up on both RISING and FALLING edge. */ +} gpio_wake; + +/* Configuration parameters for one GPIO pin in sleep mode.*/ +typedef struct { + gpio_sleep_mode sleep_mode; /* GPIO behaviour in sleep mode. */ + gpio_wake wake; /* GPIO ability to wake up the system. */ +} gpio_sleep_config; + +/*------------------------------------------------------------------------ + * Functions declaration + * refer ./Documentation/arm/STM-Nomadik/gpio_user_guide.txt + *----------------------------------------------------------------------*/ + +extern int nomadik_gpio_setpinconfig(gpio_pin pin_id, gpio_config * pin_config); +extern int nomadik_gpio_resetpinconfig(gpio_pin pin_id, char *dev_name); +extern int nomadik_gpio_writepin(gpio_pin pin_id, gpio_data value, char *dev_name); +extern int nomadik_gpio_readpin(gpio_pin pin_id, gpio_data * value); +extern int nomadik_gpio_readblock(gpio_block_id block_id, uint32 * value, + uint32 mask); +extern int nomadik_gpio_writeblock(gpio_block_id block_id, uint32 value, + uint32 mask, char *dev_name); +extern int nomadik_gpio_altfuncenable(gpio_alt_function altfunc, + char *dev_name); +extern int nomadik_gpio_altfuncdisable(gpio_alt_function altfunc, + char *dev_name); + +extern int nomadik_gpio_wakeupconfig(unsigned int irq, unsigned int flag); +extern void nomadik_gpio_slpmreg_config(gpio_pin pin_id); +struct gpio_altfun_data { + uint16 altfun; + uint16 start; + uint16 end; + bool_t cont; + uint8 type; +}; + +struct gpio_soc { + struct gpio_altfun_data *altfun_tbl; + int sz_altfun_tbl; + void (*irqwake) (struct gpio_register * bnkptr, uint32 mask, + uint32 type); + void (*irqen) (struct gpio_register * bnkptr, uint32 mask, uint32 type); + void (*irqdis) (struct gpio_register * bnkptr, uint32 mask); + void (*rstpin) (struct gpio_register * bnkptr, uint32 mask); + void (*setpin) (struct gpio_register * bnkptr, uint32 mask); + int (*dbounce) (struct gpio_register * bnkptr, uint32 mask, + gpio_debounce debounce, + gpio_debounce_time debounce_time); +}; + +struct gpio_pm_context { + u32 slpm; + u32 rwimsc; + u32 fwimsc; + u32 rimsc; + u32 fimsc; +}; + +/** + * providing this flag during request_irq tells gpio driver that the requested + * interrupt handler to be executed in tasklet's context. + */ +#define SA_GPIOINTR_IN_TASKLET SA_ONSTACK + +/* flag used internally by gpio.c*/ +#define GPIOINTR_TASKLET_ENABLED 0x10000000 + +#endif /* __INC_GPIO_H */ --- /dev/null +++ linux-2.6.20/include/asm-arm/arch-nomadik/hardware.h @@ -0,0 +1,107 @@ +/* + * linux/include/asm-arm/arch-nomadik/hardware.h + * + * This file contains the hardware definitions of the Nomadik. + * + * Copyright (C) 1999 ARM Limited. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * YOU should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifndef __ASM_ARCH_HARDWARE_H +#define __ASM_ARCH_HARDWARE_H + +#include +/*These two includes provide entire info about current target (i.e soc+platform)*/ +#include /*Nomadik chips cutspecific declaration*/ +#include /*Nomadik platform specific declaration*/ + +#define IO_BASE 0xF0000000 /* VA of IO */ +#define IO_SIZE 0x1FF00000 /* VA Size for IO */ +#define IO_START 0x10100000 /* PA of IO */ + +/* + * macro to get at IO space when running virtually + */ +#define IO_ADDRESS(x) ((x) | IO_BASE) + +/* + * Base address defination for Nomadik Onchip IPs common in all versions + */ +#define NOMADIK_BACKUP_RAM 0x80010000 +#define NOMADIK_FSMC_BASE 0x10100000 /* FSMC cnf registers */ +#define NOMADIK_SDRAMC_BASE 0x10110000 /* SDRAMC cnf registers */ +#define NOMADIK_CLCDC_BASE 0x10120000 /* CLCDC cnf registers */ +#define NOMADIK_MDIF_BASE 0x10120000 /* MDIF cnf registers */ +#define NOMADIK_DMA0_BASE 0x10130000 /* DMA0C cnf registers */ +#define NOMADIK_IC_BASE 0x10140000 /* VIC cnf registers */ +#define NOMADIK_DMA1_BASE 0x10150000 /* DMA1C cnf registers */ +#define NOMADIK_SHA1_BASE 0x10190000 /* SHA-1 Processor */ +#define NOMADIK_XTI_BASE 0x101A0000 /* XTI cnf register */ +#define NOMADIK_RNG_BASE 0x101B0000 /* Random number generator */ +#define NOMADIK_SRC_BASE 0x101E0000 /* SRC base */ +#define NOMADIK_WDOG_BASE 0x101E1000 /* Watchdog base */ +#define NOMADIK_MTU0_BASE 0x101E2000 /* MTU0 base */ +#define NOMADIK_MTU1_BASE 0x101E3000 /* MTU1 base */ +#define NOMADIK_GPIO0_BASE 0x101E4000 /* GPIO0 base */ +#define NOMADIK_GPIO1_BASE 0x101E5000 /* GPIO1 base */ +#define NOMADIK_GPIO2_BASE 0x101E6000 /* GPIO2 base */ +#define NOMADIK_RTC_BASE 0x101E8000 /* Real Time Clock base */ +#define NOMADIK_PMU_BASE 0x101E9000 /* Power Management Unit base */ +#define NOMADIK_OWM_BASE 0x101EA000 /* One wire master base */ +#define NOMADIK_SCR_BASE 0x101EF000 /* Secure Control registers base */ +#define NOMADIK_MSP2_BASE 0x101F0000 /* MSP 2 interface */ +#define NOMADIK_MSP1_BASE 0x101F1000 /* MSP 1 interface */ +#define NOMADIK_UART2_BASE 0x101F2000 /* UART 2 interface */ +#define NOMADIK_SSIRx_BASE 0x101F3000 /* SSI 8-ch recieve interface */ +#define NOMADIK_SSITx_BASE 0x101F4000 /* SSI 8-ch txmit interface */ +#define NOMADIK_SDI_BASE 0x101F6000 /* SD-card/MM-Card interface Reg */ +#define NOMADIK_I2C1_BASE 0x101F7000 /* I2C1 interface */ +#define NOMADIK_I2C0_BASE 0x101F8000 /* I2C0 interface */ +#define NOMADIK_MSP0_BASE 0x101F9000 /* MSP 0 interface */ +#define NOMADIK_FIRDA_BASE 0x101FA000 /* FIrDA interface */ +#define NOMADIK_UART1_BASE 0x101FB000 /* UART 1 interface */ +#define NOMADIK_SSP_BASE 0x101FC000 /* SSP interface */ +#define NOMADIK_UART0_BASE 0x101FD000 /* UART 0 interface */ +#define NOMADIK_SGA_BASE 0x101FE000 /* SGA interface */ + +#define NOMADIK_EBROM 0x80000000 /* Embedded boot ROM */ +#define NOMADIK_HAMACV_DMEM_BASE 0xA0100000 /* HAMACV Data Memory Space Start */ +#define NOMADIK_HAMACV_DMEM_END 0xA01FFFFF /* HAMACV Data Memory Space End */ +#define NOMADIK_HAMACA_DMEM 0xA0200000 /* HAMACA Data Memory Space */ +#ifdef CONFIG_MTD_ONENAND +#define NOMADIK_1NAND_BASE 0x30000000 /*ONENAND Base address*/ +#endif + + +/* + * Peripharal IDs/MASK defination for Nomadik Onchip IPs common in all versions + */ +#define SSP_PER_ID 0x01080022 +#define SSP_PER_MASK 0x0fffffff + +/* + * platform specific other constants + */ +#define UART_CONTROL_MASK_RTSFLOW 0x04000 +#define UART_CONTROL_MASK_CTSFLOW 0x08000 + +/* DENC chip related defines */ +#define DENC_MODE_PAL 0 +#define DENC_MODE_NTSC 1 + +#define NOMADIK_MTU0_VA (IO_ADDRESS(NOMADIK_MTU0_BASE)) +#define NOMADIK_MTU1_VA (IO_ADDRESS(NOMADIK_MTU1_BASE)) + +#endif /* __ASM_ARCH_HARDWARE_H */ --- /dev/null +++ linux-2.6.20/include/asm-arm/arch-nomadik/i2c.h @@ -0,0 +1,419 @@ +/* include/asm-arm/arch-nomadik/i2c.h + * + * Copyright 2004, STMicroelectronics, inc + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * $Id$ + */ + +#ifndef I2C_NOMADIC_HEADER +#define I2C_NOMADIC_HEADER + +#include +#include +#include + +#define GEN_MASK(val,mask,sb) ((uint32)((((uint32)val)<<(sb)) & (mask))) + +#define I2C_SET_BIT(reg_name,mask) (writel(readl(reg_name) | mask, (reg_name))) +#define I2C_CLR_BIT(reg_name,mask) (writel(readl(reg_name) & ~(mask), (reg_name))) +#define I2C_WRITE_BIT(reg_name,val,mask) (writel((readl(reg_name) & ~(mask)) | ((val) & (mask)), (reg_name)) +#define I2C_TEST_BIT(reg_name,val) (readl(reg_name) & (val)) +#define I2C_WRITE_REG(reg_name,val) (writel(val, (reg_name))) +#define I2C_READ_REG(reg_name) (readl(reg_name)) +#define I2C_CLEAR STD_MASK_NULL32 + +#define I2C_WRITE_FIELD(reg_name,mask,shift,value) \ + (writel((readl(reg_name) & ~mask) | (value << shift), reg_name)) + +#define I2C_READ_FIELD(reg_name,mask,shift) ((readl(reg_name) & (mask)) >> (shift) ) + +#define I2C_MODULE_NAME "I2C HCL Module" + +/*Peripheral ID s */ +/* Macros for handling the device id */ +#define I2CID_SHIFT 29 +#define GETDEVICE(irqsrc) (((irqsrc >>I2CID_SHIFT ) & 0x01)) + +/* a macro for masking all interrupts */ + +/*----------------------------------------------------------------------------- + Typedefs +-----------------------------------------------------------------------------*/ +typedef __u32 i2c_irq_src_t; /*Combination of various interrupt sources + described by i2c_irq_src_id_t */ + +typedef enum { + I2C_COMMAND_SEND_START, + I2C_COMMAND_SEND_STOP, + I2C_COMMAND_SEND_ACKNOWLEDGE, + I2C_COMMAND_CLEAR_ACKNOWLEDGE, + I2C_COMMAND_SET_TRANSMIT_DMA, + I2C_COMMAND_CLEAR_TRANSMIT_DMA, + I2C_COMMAND_SET_RECEIVE_DMA, + I2C_COMMAND_CLEAR_RECEIVE_DMA +} i2c_command_t; + +typedef enum { + I2C_TRANSMIT_FIFO, + I2C_RECEIVE_FIFO +} i2c_fifo_t; + +typedef enum { + I2C_NO_OPERATION = 0xFF, + I2C_WRITE = 0x00, + I2C_READ = 0x01 +} i2c_operation_t; + +/*----------------------------------------------------------------------------- + Typedefs +-----------------------------------------------------------------------------*/ +typedef enum { + I2C_MAX_STANDARD_SCL = 100000, /* Max clock frequency (Hz) for Standard Mode. */ + I2C_MAX_FAST_SCL = 400000, /* Max clock frequency (Hz) for Fast Mode. */ + I2C_MAX_HIGH_SPEED_SCL = 3400000 /* Max clock frequency (Hz) for HS Mode. */ +} i2c_maxclocks_t; + +typedef enum { + I2C_DDC1, // DDC1 mode. + I2C_DDC2B, // DD2 B mode. + I2C_DDC2AB // DDC2 AB mode (I2C). +} i2c_ddc_mode_t; + +typedef enum { + I2C_NO_REG_INDEX_OP, // Do not send any register index. + I2C_8_BIT_REG_INDEX_OP, // Send a 8-bit register index. + I2C_16_BIT_REG_INDEX_OP // Send a 16-bit register index. +} i2c_reg_op_t; + +typedef __u32 t_i2c_device_context[5]; + +/* this enum valid only for STn 8815 AND STn8820 */ +typedef enum { + I2C_DIGITAL_FILTERS_OFF, + I2C_DIGITAL_FILTERS_1_CLK_SPIKES, + I2C_DIGITAL_FILTERS_2_CLK_SPIKES, + I2C_DIGITAL_FILTERS_4_CLK_SPIKES +} i2c_digital_filter_t; + +typedef enum { + I2C_DISABLE, + I2C_ENABLE +} i2c_control_t; + +typedef enum { + I2C_FREQ_MODE_STANDARD, /* Standard mode. */ + I2C_FREQ_MODE_FAST, /* Fast mode. */ + I2C_FREQ_MODE_HIGH_SPEED +} i2c_freq_mode_t; + +typedef enum { + I2C_BUS_SLAVE_MODE = 0, /* Slave Mode */ + I2C_BUS_MASTER_MODE, /* Master Mode */ + I2C_BUS_MASTER_SLAVE_MODE /* Dual Configuration Mode */ +} i2c_bus_control_mode_t; + +typedef enum { + I2C_NO_GENERAL_CALL_HANDLING, + I2C_SOFTWARE_GENERAL_CALL_HANDLING, + I2C_HARDWARE_GENERAL_CALL_HANDLING +} i2c_general_call_handling_t; + +typedef enum { + I2C_TRANSFER_MODE_POLLING, + I2C_TRANSFER_MODE_INTERRUPT, + I2C_TRANSFER_MODE_DMA +} i2c_transfer_mode_t; + +typedef enum { + I2C_NO_INDEX, /* Current transfer is non-indexed */ + I2C_BYTE_INDEX, /* Current transfer uses 8-bit index */ + I2C_HALF_WORD_LITTLE_ENDIAN, /* Current transfer uses 16-bit index + in little endian mode */ + I2C_HALF_WORD_BIG_ENDIAN /* Current transfer uses 16-bit index + in big endian mode */ +} i2c_index_format_t; + +typedef enum { + I2C_CURRENT_BUS_SLAVE_TRANSMITTER, + I2C_CURRENT_BUS_SLAVE_RECEIVER, + I2C_CURRENT_BUS_MASTER_TRANSMITTER, + I2C_CURRENT_BUS_MASTER_RECEIVER +} i2c_current_bus_configuration_t; + +typedef enum { + I2C_STATUS_SLAVE_MODE, /* Controller is in slave mode. */ + I2C_STATUS_MASTER_MODE, /* Controller is in master mode. */ + I2C_STATUS_MASTER_TRANSMITTER_MODE, /* Controller is in master transmitter mode. */ + I2C_STATUS_MASTER_RECEIVER_MODE, /* Controller is in master receiver mode. */ + I2C_STATUS_SLAVE_TRANSMITTER_MODE, /* Controller is in slave transmitter mode. */ + + I2C_STATUS_SLAVE_RECEIVER_MODE /* Controller is in slave receiver mode */ +} i2c_device_status_t; + +typedef enum { + /*Common to all platforms */ + I2C_NO_EVENT = STD_MASK_BIT0, /* No activity. */ + I2C_TRANSFER_OK_EVENT = STD_MASK_BIT1, /* Transfer operation ended correctly. */ + I2C_CANCEL_EVENT = STD_MASK_BIT2, /* Transfer operation cancelled by the user. */ + I2C_INTERNAL_ERROR_EVENT = STD_MASK_BIT3, /* Internal error happened. */ + I2C_ARBITRATION_LOST_ERROR_EVENT = STD_MASK_BIT4, /* Arbitration Lost happened. */ + + /*Specific to STN_8800, STN_8810 and */ + I2C_AF_ERROR_EVENT = STD_MASK_BIT5, /* Acknowledge Failure happened */ + I2C_BUS_ERROR_EVENT = STD_MASK_BIT6, /* Bus Error happened */ + I2C_START_EVENT = STD_MASK_BIT7, /* START generated */ + I2C_INDEX_TX_EVENT = STD_MASK_BIT8, /* Register index byte transmitted */ + I2C_DATA_TX_EVENT = STD_MASK_BIT9, /* Data byte transmitted */ + I2C_DATA_RX_EVENT = STD_MASK_BIT10, /* Data byte received */ + I2C_WAITING_DATA_RX_EVENT = STD_MASK_BIT11, /* Waiting for a data byte */ + + /*Specific to STN_8815 and STN_8820 */ + I2C_TRANSMIT_FIFO_EMPTY_EVENT = STD_MASK_BIT12, + I2C_TRANSMIT_FIFO_NEARLY_EMPTY_EVENT = STD_MASK_BIT13, + I2C_TRANSMIT_FIFO_FULL_EVENT = STD_MASK_BIT14, + I2C_TRANSMIT_FIFO_OVERRUN_EVENT = STD_MASK_BIT15, + I2C_RECEIVE_FIFO_EMPTY_EVENT = STD_MASK_BIT16, + I2C_RECEIVE_FIFO_NEARLY_FULL_EVENT = STD_MASK_BIT17, + I2C_RECEIVE_FIFO_FULL_EVENT = STD_MASK_BIT18, + I2C_READ_FROM_SLAVE_REQUEST_EVENT = STD_MASK_BIT19, + I2C_READ_FROM_SLAVE_EMPTY_EVENT = STD_MASK_BIT20, + I2C_WRITE_TO_SLAVE_REQUEST_EVENT = STD_MASK_BIT21, + I2C_MASTER_TRANSACTION_DONE_EVENT = STD_MASK_BIT22, + I2C_SLAVE_TRANSACTION_DONE_EVENT = STD_MASK_BIT23, + I2C_ABORT_NACK_ON_ADDRESS_EVENT = STD_MASK_BIT24, + I2C_ABORT_NACK_ON_DATA_EVENT = STD_MASK_BIT25, + I2C_ABORT_ACK_ON_MASTER_CODE_EVENT = STD_MASK_BIT26, + I2C_BUS_ERROR_DETECTED_START_EVENT = STD_MASK_BIT27, + I2C_BUS_ERROR_DETECTED_STOP_EVENT = STD_MASK_BIT28, + I2C_OVERFLOW_EVENT = STD_MASK_BIT29 +} i2c_event_t; /* Inform the I2C HCL user about the last occurred event. */ + +typedef struct { + int id; + i2c_event_t type; /* The active event */ + __u32 transfer_data; /* Number of data bytes actually transferred. */ +} i2c_active_event_t; + +typedef int i2c_irq_status_t; + +struct i2c_controller_config { + /*Device configuration */ + __u32 freq_scl; // The I2C bus SCL clock frequency (Hz). + __u16 own_address; // The controller's slave address. + t_i2c_device_context i2c_device_context; + i2c_digital_filter_t digital_filter_control; + i2c_control_t dma_sync_logic_control; + i2c_control_t start_byte_procedure; + __u8 high_speed_master_code; + __u16 slave_data_setup_time; + bool_t irq_enabled; // True means use interrupts. + + /*Transfer configuration */ + __u32 freq_input; // The controller's input clock frequency (Hz). + i2c_freq_mode_t mode; // Standard or Fast mode. + i2c_operation_t operation; // Write or read. + i2c_bus_control_mode_t bus_control_mode; + i2c_control_t i2c_loopback_mode; + i2c_general_call_handling_t general_call_mode_handling; + i2c_transfer_mode_t index_transfer_mode; + i2c_transfer_mode_t data_transfer_mode; + __u8 i2c_transmit_interrupt_threshold; + __u8 i2c_receive_interrupt_threshold; + __u8 transmit_burst_length; + __u8 receive_burst_length; + __u16 burst_length; + __u16 slave_address; // The slave to talk to. + __u16 register_index; // The index of the slave's registers + i2c_index_format_t index_format; + bool_t multi_operation; + + /*Device Status */ + bool_t enabled; // True means controller is enabled. + __u32 count_data; // The number of bytes to be transferred. + __u32 transfer_data; // Number of transferred data bytes. + __u8 *databuffer; // Pointer to the data buffer. Used in Multi operation. + i2c_current_bus_configuration_t current_bus_config; + i2c_device_status_t status; // The controller's status. + __u8 data; // Used in Single operation. + i2c_active_event_t active_event; // The current active event. + bool_t std; + +}; + +typedef enum { + I2C_NO_PENDING_EVENT_ERROR = NOMADIK_NO_PENDING_EVENT_ERROR, + I2C_NO_MORE_FILTER_PENDING_EVENT = NOMADIK_NO_MORE_FILTER_PENDING_EVENT, + I2C_NO_MORE_PENDING_EVENT = NOMADIK_NO_MORE_PENDING_EVENT, + I2C_REMAINING_FILTER_PENDING_EVENTS = + NOMADIK_REMAINING_FILTER_PENDING_EVENTS, + I2C_REMAINING_PENDING_EVENTS = NOMADIK_REMAINING_PENDING_EVENTS, + I2C_INTERNAL_EVENT = NOMADIK_INTERNAL_EVENT, + I2C_OK = NOMADIK_OK, /* No error */ + I2C_INTERNAL_ERROR = NOMADIK_INTERNAL_ERROR, + I2C_NOT_CONFIGURED = NOMADIK_NOT_CONFIGURED, + I2C_REQUEST_PENDING = NOMADIK_REQUEST_PENDING, + I2C_REQUEST_NOT_APPLICABLE = NOMADIK_REQUEST_NOT_APPLICABLE, + I2C_INVALID_PARAMETER = NOMADIK_INVALID_PARAMETER, + I2C_UNSUPPORTED_FEATURE = NOMADIK_UNSUPPORTED_FEATURE, + I2C_UNSUPPORTED_HW = NOMADIK_UNSUPPORTED_HW, + I2C_HW_FAILED = (NOMADIK_MAX_ERROR_VALUE - 1), /* Generic hardware error */ + I2C_SW_FAILED = (NOMADIK_MAX_ERROR_VALUE - 2), /* Generic software error */ + I2C_CONTROLLER_BUSY = (NOMADIK_MAX_ERROR_VALUE - 3), /* Transfer on going */ + I2C_LINE_FREQ_NOT_SUPPORTED = (NOMADIK_MAX_ERROR_VALUE - 4), /* SCL bus frequency not supported */ + I2C_INPUT_FREQ_NOT_SUPPORTED = (NOMADIK_MAX_ERROR_VALUE - 5), /* Input frequency not supported */ + I2C_DDC_MODE_NOT_SUPPORTED = (NOMADIK_MAX_ERROR_VALUE - 6), /* DDC mode not supported. */ + I2C_SLAVE_ADDRESS_NOT_VALID = (NOMADIK_MAX_ERROR_VALUE - 7), /* Slave address is reserved or not valid. */ + + /*Specific to STN_8800, STN_8810 and STN_8815 */ + I2C_BYTE_TRANSFER_FAILED = (NOMADIK_MAX_ERROR_VALUE - 100), + I2C_ADDRESS_MATCH_FAILED = (NOMADIK_MAX_ERROR_VALUE - 101), + I2C_START_BYTE_FAILED = (NOMADIK_MAX_ERROR_VALUE - 102), + I2C_ACKNOWLEDGE_FAILURE = (NOMADIK_MAX_ERROR_VALUE - 103), + I2C_STOP_FAILED = (NOMADIK_MAX_ERROR_VALUE - 104), + I2C_ARBITRATION_LOST = (NOMADIK_MAX_ERROR_VALUE - 105), + I2C_BUS_ERROR = (NOMADIK_MAX_ERROR_VALUE - 106), + I2C_10_BIT_ADDRESS_FAILED = (NOMADIK_MAX_ERROR_VALUE - 107), + I2C_SCL_FALL_FAILED = (NOMADIK_MAX_ERROR_VALUE - 108), + I2C_END_ADDRESS_FAILED = (NOMADIK_MAX_ERROR_VALUE - 109), + + /*Specific to STN_8820 */ + I2C_TRANSMIT_FIFO_FULL = (NOMADIK_MAX_ERROR_VALUE - 200), + I2C_RECEIVE_FIFO_EMPTY = (NOMADIK_MAX_ERROR_VALUE - 201), + I2C_ACK_FAIL_ON_ADDRESS = (NOMADIK_MAX_ERROR_VALUE - 202), + I2C_ACK_FAIL_ON_DATA = (NOMADIK_MAX_ERROR_VALUE - 203), + I2C_ACK_IN_HS_MODE = (NOMADIK_MAX_ERROR_VALUE - 204), + I2C_BUS_ERROR_DETECTED_START = (NOMADIK_MAX_ERROR_VALUE - 205), + I2C_BUS_ERROR_DETECTED_STOP = (NOMADIK_MAX_ERROR_VALUE - 206), + I2C_OVERFLOW = (NOMADIK_MAX_ERROR_VALUE - 207) +} i2c_error_t; + +typedef struct { + unsigned long baseAddress; /* The controller's logical base address. */ + unsigned long fSCL; /* The I2C bus SCL clock frequency (Hz). */ + unsigned long fIn; /* The controller's input clock frequency (Hz). */ + unsigned long ownAddress; /* The controller's slave address. */ + int id; /* The controller's id. */ + i2c_freq_mode_t mode; /* Standard ,Fast mode or Hs Mode. */ + bool_t enabled; /* True means controller is enabled. */ + i2c_bus_control_mode_t bus_control_mode; + i2c_current_bus_configuration_t current_bus_config; + i2c_general_call_handling_t general_address_enable; +} i2c_info_t; /* Used to provide information to the user. */ + +typedef enum { + /*Common to all platforms */ + I2C_STATE_GENERAL_CALL_DETECTED = STD_MASK_BIT0, + I2C_STATE_ARBITRATION_LOST = STD_MASK_BIT2, + I2C_STATE_BUSY = STD_MASK_BIT12, + + /*Specific to STN_8800, STN_8810 and STN_8815 */ + I2C_STATE_BUS_ERROR = STD_MASK_BIT1, + I2C_STATE_STOP_DETECTION = STD_MASK_BIT3, + I2C_STATE_ACKNOWLEDGE_FAIL = STD_MASK_BIT4, + I2C_STATE_END_OF_ADDRESS = STD_MASK_BIT5, + I2C_STATE_SCL_FALL_DDC_MODE = STD_MASK_BIT7, + I2C_STATE_START_GENERATED = STD_MASK_BIT8, + I2C_STATE_MASTER_SLAVE_MODE = STD_MASK_BIT9, + I2C_STATE_ADDRESS_MATCHED = STD_MASK_BIT10, + I2C_STATE_BYTE_TRANSFER_FINISHED = STD_MASK_BIT11, + I2C_STATE_TRANSMIT_RECEIVE = STD_MASK_BIT13, + I2C_STATE_ADDRESS10 = STD_MASK_BIT14, + I2C_STATE_EVENT_GENERATED = STD_MASK_BIT15, + + /*Specific to STN_8820 */ + I2C_STATE_TRANSFER_COMPLETE = STD_MASK_BIT16, + I2C_STATE_ABORT_NACK_ON_ADDRESS = STD_MASK_BIT17, + I2C_STATE_ABORT_NACK_ON_DATA = STD_MASK_BIT18, + I2C_STATE_ABORT_ACK_ON_MASTER_CODE = STD_MASK_BIT19, + I2C_STATE_BUS_ERROR_DETECTED_START = STD_MASK_BIT20, + I2C_STATE_BUS_ERROR_DETECTED_STOP = STD_MASK_BIT21, + I2C_STATE_OVERFLOW = STD_MASK_BIT22, + I2C_STATE_HARDWARE_GENERAL_CALL = STD_MASK_BIT23 +} i2c_device_states_t; + +#define I2C_STD_MODE I2C_FREQ_MODE_STANDARD + +/*#if defined (__I2C_8810) + #define STD_F_IN_HZ 48000000 +#else + #define STD_F_IN_HZ 99000000 +#endif */ + +#define STD_F_IN_HZ 48000000 +#define STD_SPEED_IN_HZ 100000 +#define STD_SPEED 100 /* Also in KHz */ +#define FAST_SPEED 400 + +#if !defined CONFIG_NOMADIK_NHK15 +/* Client IDs */ +enum { + I2C_MB_CLIENT = 0, + I2C_UI_DB_CLIENT, + I2C_IO_EXP_DB1_CLIENT, + I2C_IO_EXP_DB2_CLIENT, + I2C_CIF_CAM_CLIENT, + I2C_MEM_EXP_CLIENT, + I2C_AUDIO_CODEC_CLIENT, + I2C_FM_TUNER_CLIENT, + I2C_GAS_GAUGE_CLIENT, + I2C_LITEA_CAM_MOD_CLIENT, + I2C0_LOOP_CLIENT, + I2C1_LOOP_CLIENT, + I2C_PP_CAM_CLIENT, + I2C_TOUAREG_CLIENT, +#ifdef CONFIG_NOMADIK_NDK15 + I2C_CPLD_CLIENT, +#endif + I2C_DENC_CLIENT, + I2C_NUM_CLIENTS +}; +#else +enum { + I2C_DENC_CLIENT = 0, + I2C_AUDIO_CODEC_CLIENT, + I2C_FM_TUNER_CLIENT, + I2C_LITEA_CAM_MOD_CLIENT, + I2C_MEMS_CLIENT, + I2C_SIM_CLIENT, + I2C_TOUCH_CLIENT, + I2C_STMPE0_CLIENT, + I2C_STMPE1_CLIENT, + I2C_GAS_GAUGE_CLIENT, + I2C_TOUAREG_CLIENT, + I2C0_LOOP_CLIENT, + I2C1_LOOP_CLIENT, + I2C_PP_CAM_CLIENT, + I2C_NUM_CLIENTS +}; +#endif + +/*** + * Exported functions + ***/ +extern int nomadik_i2c_is_busy(__u32 client_id); + +/* Get the i2c_client struct for a device. Required for calling + * transfer functions */ +extern struct i2c_client *nomadik_i2c_get_client(__u32 client_id); + +/* Transfer functions */ +int nomadik_i2c_read_register(__u32 client_id, + __u8 * data, int index, int count); +int nomadik_i2c_write_register(__u32 client_id, + __u8 * data, int index, int count); + +#endif --- /dev/null +++ linux-2.6.20/include/asm-arm/arch-nomadik/io.h @@ -0,0 +1,37 @@ +/* + * linux/include/asm-arm/arch-nomadik/io.h + * + * Copyright (C) 1999 ARM Limited + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifndef __ASM_ARM_ARCH_IO_H +#define __ASM_ARM_ARCH_IO_H + +#define IO_SPACE_LIMIT 0xffff + +/* + * WARNING: this has to mirror definitions in platform.h + */ +#define PCI_MEMORY_VADDR 0xe8000000 +#define PCI_CONFIG_VADDR 0xec000000 +#define PCI_V3_VADDR 0xed000000 +#define PCI_IO_VADDR 0xee000000 + +#define __io(a) ((void __iomem *)(PCI_IO_VADDR + (a))) +#define __mem_pci(a) (a) +#define __mem_isa(a) ((a) + PCI_MEMORY_VADDR) + +#endif --- /dev/null +++ linux-2.6.20/include/asm-arm/arch-nomadik/irqs.h @@ -0,0 +1,137 @@ +/* + * linux/include/asm-arm/arch-nomadik/irqs.h + * + * Copyright (C) ST Microelectronics + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifndef ASM_ARCH_IRQS_H +#define ASM_ARCH_IRQS_H + +#include +#include + +/* + * Vectroed interrupt Handling:- + * + * These flags can be used while requesting irq (request_irq) to configure + * it for desired priority, using this flags will alter interrupt processing + * and requesting logic as follows. + * + * The interrupt priority is regulated by the hardware. + * The FIQ interrupt has the highest priority, + * followed by irq requested with SA_IRQPRIORITY_0 to SA_IRQPRIORITY_15. + * Standard IRQs requested without priority flag have the lowest priority. + * + * When any interrupt is being serviced, and if higher priority interrupt + * occures it will be serviced first. + * + * interrupt priority can also be enabled, disabled or changed at any moment of + * time for a valid pre-requested interrupt by using API "set_irq_type" + */ +#define SA_NMDK_PRIORITYIRQ (SA_TRIGGER_LOW | SA_TRIGGER_HIGH) +#define SA_IRQPRIORITY_1 (0x00100000 | SA_NMDK_PRIORITYIRQ) +#define SA_IRQPRIORITY_2 (0x00200000 | SA_NMDK_PRIORITYIRQ) +#define SA_IRQPRIORITY_3 (0x00300000 | SA_NMDK_PRIORITYIRQ) +#define SA_IRQPRIORITY_4 (0x00400000 | SA_NMDK_PRIORITYIRQ) +#define SA_IRQPRIORITY_5 (0x00500000 | SA_NMDK_PRIORITYIRQ) +#define SA_IRQPRIORITY_6 (0x00600000 | SA_NMDK_PRIORITYIRQ) +#define SA_IRQPRIORITY_7 (0x00700000 | SA_NMDK_PRIORITYIRQ) +#define SA_IRQPRIORITY_8 (0x00800000 | SA_NMDK_PRIORITYIRQ) +#define SA_IRQPRIORITY_9 (0x00900000 | SA_NMDK_PRIORITYIRQ) +#define SA_IRQPRIORITY_10 (0x00a00000 | SA_NMDK_PRIORITYIRQ) +#define SA_IRQPRIORITY_11 (0x00b00000 | SA_NMDK_PRIORITYIRQ) +#define SA_IRQPRIORITY_12 (0x00c00000 | SA_NMDK_PRIORITYIRQ) +#define SA_IRQPRIORITY_13 (0x00d00000 | SA_NMDK_PRIORITYIRQ) +#define SA_IRQPRIORITY_14 (0x00e00000 | SA_NMDK_PRIORITYIRQ) +#define SA_IRQPRIORITY_15 (0x00f00000 | SA_NMDK_PRIORITYIRQ) +#define SA_IRQPRIORITY_MASK (0x00f00000 | SA_NMDK_PRIORITYIRQ) + +#define VIC_PRIORITY_LOGIC_ENABLED +#define VIC_VECTORED_IRQ_NUM 16 /*maximum available verctored irqs*/ +#define IRQ_PIC_START 0 /*used by entry_macro.S*/ + +/* + * Interrupt numbers generic for all Nomadik Chip cuts + */ +#define IRQ_WATCHDOG 0 +#define IRQ_SOFTINT 1 +#define IRQ_OWM 3 +#define IRQ_MTU0 4 +#define IRQ_MTU1 5 +#define IRQ_GPIO0 6 +#define IRQ_GPIO1 7 +#define IRQ_GPIO2 8 +#define IRQ_RTC_RTT 10 +#define IRQ_SSP 11 +#define IRQ_UART0 12 +#define IRQ_DMA1 13 +#define IRQ_CLCD_MDIF 14 +#define IRQ_DMA0 15 +#define IRQ_PWRFAIL 16 +#define IRQ_UART1 17 +#define IRQ_FIRDA 18 +#define IRQ_MSP0 19 +#define IRQ_I2C0 20 +#define IRQ_I2C1 21 +#define IRQ_SDMMC 22 +#define IRQ_USBOTG 23 +#define IRQ_SVA_IT0 24 +#define IRQ_SVA_IT1 25 +#define IRQ_SAA_IT0 26 +#define IRQ_SAA_IT1 27 +#define IRQ_UART2 28 +#define IRQ_MSP2 31 + +/* + * the macro below decides which IRQs to be configured/enabled + * during nomadik_vic_init*/ +#define IRQ_CONF ( 1ULL< + +/*keypad related Constants*/ +#define KEYPAD_DEBOUNCE_PERIOD 4 /*40Msec */ +#define KEYPAD_RELEASE_PERIOD 11 /*110 Msec, repeate key scan time */ +#define KEYPAD_SCAN_PERIOD 4 /*40Msec for new keypress */ +#define KEYPAD_STATE_DEFAULT 0 +#define KEYPAD_STATE_PRESSED 1 +#define KEYPAD_STATE_PRESSACK 2 +#define KEYPAD_STATE_RELEASED 3 +#define KEYPAD_STATE_RELEASEACK 2 + +#define KPINTR_LKBIT 0 /*bit used for interrupt locking */ + +struct keypad_t; + +struct keypad_device { + int (*init)(struct keypad_t *kp); + int (*exit)(struct keypad_t *kp); + int (*scan)(struct keypad_t *kp); + int (*irqen)(struct keypad_t *kp); + int (*irqdis)(struct keypad_t *kp); + u8 *kcode_tbl; + u8 krow; + u8 kcol; +}; + +/** + * struct keypad_t - keypad data structure used internally by keypad driver + */ +struct keypad_t { + int irq; + int mode; + int key_state[MAX_KPROW][MAX_KPCOL]; + unsigned long lockbits; + gpio_config kpd_gpio_config; + struct input_dev *inp_dev; + void *address_for_data; + struct delayed_work kscan_work; + struct keypad_device *board; +}; + +#endif /*__ASM_ARM_ARCH_KPD_NOMADIK_H*/ --- /dev/null +++ linux-2.6.20/include/asm-arm/arch-nomadik/memory.h @@ -0,0 +1,41 @@ +/* + * linux/include/asm-arm/arch-nomadik/memory.h + * + * Copyright (C) 1999 ARM Limited + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifndef __ASM_ARCH_MEMORY_H +#define __ASM_ARCH_MEMORY_H + +/* + * Physical DRAM offset. + */ +#define PHYS_OFFSET UL(0x00000000) +#define BUS_OFFSET UL(0x00000000) + +/* + * Virtual view <-> DMA view memory address translations + * virt_to_bus: Used to translate the virtual address to an + * address suitable to be passed to set_dma_addr + * bus_to_virt: Used to convert an address for DMA operations + * to an address that the kernel can use. + */ +#define __virt_to_bus(x) (x - PAGE_OFFSET + BUS_OFFSET) +#define __bus_to_virt(x) (x - BUS_OFFSET + PAGE_OFFSET) + +#define CONSISTENT_DMA_SIZE SZ_32M + +#endif --- /dev/null +++ linux-2.6.20/include/asm-arm/arch-nomadik/mmc.h @@ -0,0 +1,234 @@ +/* + * linux/drivers/mmc/nomadik_mmc.h - ARM PrimeCell MMCI PL180 driver + * + * Support for MMC/SD crad on STn8810/8815 (Nomadik) chips. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#define MMCIPOWER 0x000 +#define MCI_PWR_OFF 0x00 +#define MCI_PWR_UP 0x02 +#define MCI_PWR_ON 0x03 +#define MCI_STATE_ENABLE 0x38 +#define MCI_OPEN_DRAIN (1 << 6) +#define MCI_FBCLK_ENABLE (1 << 7) +#define MCI_POWER_IOS_MASK \ + (MCI_PWR_ON | MCI_DIREN_CMD | MCI_DIREN_DAT0 | MCI_DIREN_DAT2 | \ + MCI_DIREN_DAT31 | MCI_DIREN_DAT74 | MCI_OPEN_DRAIN) +#define MCI_DIREN_CMD (1<<3) +#define MCI_DIREN_DAT0 (1<<4) +#define MCI_DIREN_DAT2 (1<<2) +#define MCI_DIREN_DAT31 (1<<5) +#define MCI_DIREN_DAT74 (1<<8) +#define MCI_DIREN_1BIT (MCI_DIREN_CMD|MCI_DIREN_DAT0) +#define MCI_DIREN_4BIT (MCI_DIREN_CMD|MCI_DIREN_DAT0|MCI_DIREN_DAT31) +#define MCI_DIREN_8BIT (MCI_DIREN_CMD|MCI_DIREN_DAT0|MCI_DIREN_DAT31) + +#define MMCICLOCK 0x004 +#define MCI_CLK_ENABLE (1 << 8) +#define MCI_CLK_PWRSAVE (1 << 9) +#define MCI_CLK_BYPASS (1 << 10) +#define MCI_BUS_WIDTH_1 (0 << 11) +#define MCI_BUS_WIDTH_4 (1 << 11) +#define MCI_BUS_WIDTH_8 (2 << 11) + +#define MMCIARGUMENT 0x008 +#define MMCICOMMAND 0x00c +#define MCI_CPSM_RESPONSE (1 << 6) +#define MCI_CPSM_LONGRSP (1 << 7) +#define MCI_CPSM_INTERRUPT (1 << 8) +#define MCI_CPSM_PENDING (1 << 9) +#define MCI_CPSM_ENABLE (1 << 10) + +#define MMCIRESPCMD 0x010 +#define MMCIRESPONSE0 0x014 +#define MMCIRESPONSE1 0x018 +#define MMCIRESPONSE2 0x01c +#define MMCIRESPONSE3 0x020 +#define MMCIDATATIMER 0x024 +#define MMCIDATALENGTH 0x028 +#define MMCIDATACTRL 0x02c +#define MCI_DPSM_ENABLE (1 << 0) +#define MCI_DPSM_DIRECTION (1 << 1) +#define MCI_DPSM_MODE (1 << 2) +#define MCI_DPSM_DMAENABLE (1 << 3) + +#define MMCIDATACNT 0x030 +#define MMCISTATUS 0x034 +#define MCI_CMDCRCFAIL (1 << 0) +#define MCI_DATACRCFAIL (1 << 1) +#define MCI_CMDTIMEOUT (1 << 2) +#define MCI_DATATIMEOUT (1 << 3) +#define MCI_TXUNDERRUN (1 << 4) +#define MCI_RXOVERRUN (1 << 5) +#define MCI_CMDRESPEND (1 << 6) +#define MCI_CMDSENT (1 << 7) +#define MCI_DATAEND (1 << 8) +#define MCI_STBITERR (1 << 9) +#define MCI_DATABLOCKEND (1 << 10) +#define MCI_CMDACTIVE (1 << 11) +#define MCI_TXACTIVE (1 << 12) +#define MCI_RXACTIVE (1 << 13) +#define MCI_TXFIFOHALFEMPTY (1 << 14) +#define MCI_RXFIFOHALFFULL (1 << 15) +#define MCI_TXFIFOFULL (1 << 16) +#define MCI_RXFIFOFULL (1 << 17) +#define MCI_TXFIFOEMPTY (1 << 18) +#define MCI_RXFIFOEMPTY (1 << 19) +#define MCI_TXDATAAVLBL (1 << 20) +#define MCI_RXDATAAVLBL (1 << 21) + +#define MMCICLEAR 0x038 +#define MCI_CMDCRCFAILCLR (1 << 0) +#define MCI_DATACRCFAILCLR (1 << 1) +#define MCI_CMDTIMEOUTCLR (1 << 2) +#define MCI_DATATIMEOUTCLR (1 << 3) +#define MCI_TXUNDERRUNCLR (1 << 4) +#define MCI_RXOVERRUNCLR (1 << 5) +#define MCI_CMDRESPENDCLR (1 << 6) +#define MCI_CMDSENTCLR (1 << 7) +#define MCI_DATAENDCLR (1 << 8) +#define MCI_DATABLOCKENDCLR (1 << 10) + +#define MMCIMASK0 0x03c +#define MCI_CMDCRCFAILMASK (1 << 0) +#define MCI_DATACRCFAILMASK (1 << 1) +#define MCI_CMDTIMEOUTMASK (1 << 2) +#define MCI_DATATIMEOUTMASK (1 << 3) +#define MCI_TXUNDERRUNMASK (1 << 4) +#define MCI_RXOVERRUNMASK (1 << 5) +#define MCI_CMDRESPENDMASK (1 << 6) +#define MCI_CMDSENTMASK (1 << 7) +#define MCI_DATAENDMASK (1 << 8) +#define MCI_DATABLOCKENDMASK (1 << 10) +#define MCI_CMDACTIVEMASK (1 << 11) +#define MCI_TXACTIVEMASK (1 << 12) +#define MCI_RXACTIVEMASK (1 << 13) +#define MCI_TXFIFOHALFEMPTYMASK (1 << 14) +#define MCI_RXFIFOHALFFULLMASK (1 << 15) +#define MCI_TXFIFOFULLMASK (1 << 16) +#define MCI_RXFIFOFULLMASK (1 << 17) +#define MCI_TXFIFOEMPTYMASK (1 << 18) +#define MCI_RXFIFOEMPTYMASK (1 << 19) +#define MCI_TXDATAAVLBLMASK (1 << 20) +#define MCI_RXDATAAVLBLMASK (1 << 21) + +#define MMCIMASK1 0x040 +#define MMCIFIFOCNT 0x048 +#define MMCIFIFO 0x080 /* to 0x0bc */ + +#define MCI_DATA_ERR \ + (MCI_RXOVERRUN | MCI_TXUNDERRUN | MCI_DATATIMEOUT | MCI_DATACRCFAIL | \ + MCI_STBITERR) +#define MCI_IRQENABLE \ + (MCI_CMDCRCFAIL | MCI_DATACRCFAIL | MCI_CMDTIMEOUT | \ + MCI_DATATIMEOUT | MCI_TXUNDERRUN | MCI_RXOVERRUN | \ + MCI_CMDRESPEND | MCI_CMDSENT | MCI_DATABLOCKEND) +#define MCI_DATA_IRQ (MCI_DATA_ERR | MCI_DATAEND) +#define MCI_XFER_IRQ_MASK \ + (MCI_TXFIFOEMPTY | MCI_TXFIFOHALFEMPTY | MCI_RXFIFOHALFFULL | MCI_RXDATAAVLBL) +#define MCI_CMD_IRQ \ + (MCI_CMDCRCFAIL | MCI_CMDTIMEOUT | MCI_CMDRESPEND | MCI_CMDSENT) +#define MCI_XFER_IRQ \ + (MCI_TXFIFOHALFEMPTY | MCI_RXFIFOHALFFULL) + +/* + * The size of the FIFO in bytes. + */ +#define MCI_FIFOSIZE 16 + +#define MCI_FIFOHALFSIZE (MCI_FIFOSIZE / 2) + +#define NR_SG 16 + +#define NO_WAIT_RESPCMD 0 +#define MASK_CMDINDEX 0x3F +#define MASK_CARDSTATE 0x1E00 +#define MASK_DBLOCKSIZE 0xF0 +#define MASK_CARDREADYFORDATA 0x000000100 +#define OCR 0x00ff80000 +#define CLK 48000000 +struct clk; + +#define MAX_BUS_WIDTH 4 +#define CARD_DETECT_GPIO GPIO_PIN_49 + +#define TOUAREG_VMMC_3 (3 << 1) +#define TOUAREG_VMMC_2_85 (2 << 1) +#define TOUAREG_VMMC_1_8 (1 << 1) +#define TOUAREG_VMMC_MASK (3 << 1) +#define TOUAREG_MMC_ENABLE 1 + +#define DEFAULT_VMMC (TOUAREG_VMMC_3 | TOUAREG_MMC_ENABLE) +#define OCR_AVAIL (MMC_VDD_17_18 | MMC_VDD_18_19 | \ + /*MMC_VDD_28_29 |*/ \ + MMC_VDD_29_30 | MMC_VDD_30_31) +#define INVALID_PIPEID (-1) + +struct nomadik_mmci_host { + void __iomem *base; + struct mmc_request *mrq; + struct mmc_command *cmd; + struct mmc_data *data; + struct mmc_host *mmc; + struct clk *clk; + + unsigned int data_xfered; + + spinlock_t lock; + + unsigned int mclk; + unsigned int cclk; + u32 pwr; + struct mmc_platform_data *plat; + u32 vmcc; + + struct timer_list timer; + unsigned int oldstat; + + unsigned int sg_len; + + /* pio stuff */ + struct scatterlist *sg_ptr; + unsigned int sg_off; + unsigned int size; + unsigned int *buffer; + void *dma_done; /* completion data */ + +}; + +/* Define the current mode */ +#define MCI_DMAMODE 0x01 +#define MCI_POLLINGMODE 0x02 +#define MCI_INTERRUPTMODE 0x03 + +#define MCI_ALLINTERRUPTS (0x007FFFFF) + +#define MMCCLRSTATICFLAGS (0x004007FF) + +#define MCI_MAXVOLTTRIAL (200) /* 200 times */ +#define MAX_FREQ (24000000) +#define MAX_DATA (64*512) +#define CLK_MAX 48000000 + +enum card_state { + CARD_STATE_EMPTY = -1, + CARD_STATE_IDLE, + CARD_STATE_READY, + CARD_STATE_IDENT, + CARD_STATE_STBY, + CARD_STATE_TRAN, + CARD_STATE_DATA, + CARD_STATE_RCV, + CARD_STATE_PRG, + CARD_STATE_DIS, +}; + +struct mmc_board { + int (*init) (struct amba_device *dev); + void (*exit) (struct amba_device *dev); +}; + + --- /dev/null +++ linux-2.6.20/include/asm-arm/arch-nomadik/msp-spi.h @@ -0,0 +1,343 @@ +/* + * arch/arm/mach-nomadik/msp-spi.h + * + * Copyright (C) 2007 STMicroelectronics Pvt. Ltd. + * + * Author: Sachin Verma + * + * Description: Header File containing Hardware specific details for + * MSP controller hardware + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + + +#ifndef NOMADIC_MSP_SPI_HEADER +#define NOMADIC_MSP_SPI_HEADER + +# define DEFAULT_MSP_CLK 48000000 +# define MAX_SCKDIV 1023 + +/*####################################################################### + MSP Controller Register Offsets +######################################################################### + */ +#define MSP_DR(r) (r + 0x000) +#define MSP_GCR(r) (r + 0x004) +#define MSP_TCF(r) (r + 0x008) +#define MSP_RCF(r) (r + 0x00C) +#define MSP_SRG(r) (r + 0x010) +#define MSP_FLR(r) (r + 0x014) +#define MSP_DMACR(r) (r + 0x018) +#define MSP_IMSC(r) (r + 0x020) +#define MSP_RIS(r) (r + 0x024) +#define MSP_MIS(r) (r + 0x028) +#define MSP_ICR(r) (r + 0x02C) +#define MSP_MCR(r) (r + 0x030) +#define MSP_RCV(r) (r + 0x034) +#define MSP_RCM(r) (r + 0x038) +#define MSP_TCE0(r) (r + 0x040) +#define MSP_TCE1(r) (r + 0x044) +#define MSP_TCE2(r) (r + 0x048) +#define MSP_TCE3(r) (r + 0x04C) +#define MSP_RCE0(r) (r + 0x060) +#define MSP_RCE1(r) (r + 0x064) +#define MSP_RCE2(r) (r + 0x068) +#define MSP_RCE3(r) (r + 0x06C) +#define MSP_PID0(r) (r + 0xFE0) +#define MSP_PID1(r) (r + 0xFE4) +#define MSP_PID2(r) (r + 0xFE8) +#define MSP_PID3(r) (r + 0xFEC) + +/*####################################################################### + MSP Global Configuration Register - msp_gcr +######################################################################### + */ +#define MSP_GCR_MASK_RXEN ((uint32)(0x1UL << 0)) +#define MSP_GCR_MASK_RFFEN ((uint32)(0x1UL << 1)) +#define MSP_GCR_MASK_RFSPOL ((uint32)(0x1UL << 2)) +#define MSP_GCR_MASK_DCM ((uint32)(0x1UL << 3)) +#define MSP_GCR_MASK_RFSSEL ((uint32)(0x1UL << 4)) +#define MSP_GCR_MASK_RCKPOL ((uint32)(0x1UL << 5)) +#define MSP_GCR_MASK_RCKSEL ((uint32)(0x1UL << 6)) +#define MSP_GCR_MASK_LBM ((uint32)(0x1UL << 7)) +#define MSP_GCR_MASK_TXEN ((uint32)(0x1UL << 8)) +#define MSP_GCR_MASK_TFFEN ((uint32)(0x1UL << 9)) +#define MSP_GCR_MASK_TFSPOL ((uint32)(0x1UL << 10)) +#define MSP_GCR_MASK_TFSSEL ((uint32)(0x3UL << 11)) +#define MSP_GCR_MASK_TCKPOL ((uint32)(0x1UL << 13)) +#define MSP_GCR_MASK_TCKSEL ((uint32)(0x1UL << 14)) +#define MSP_GCR_MASK_TXDDL ((uint32)(0x1UL << 15)) +#define MSP_GCR_MASK_SGEN ((uint32)(0x1UL << 16)) +#define MSP_GCR_MASK_SCKPOL ((uint32)(0x1UL << 17)) +#define MSP_GCR_MASK_SCKSEL ((uint32)(0x3UL << 18)) +#define MSP_GCR_MASK_FGEN ((uint32)(0x1UL << 20)) +#define MSP_GCR_MASK_SPICKM ((uint32)(0x3UL << 21)) +#define MSP_GCR_MASK_SPIBME ((uint32)(0x1UL << 23)) + +/*####################################################################### + MSP Transmit Configuration Register - msp_tcf +######################################################################### + */ +#define MSP_TCF_MASK_TP1ELEN ((uint32)(0x7UL << 0)) +#define MSP_TCF_MASK_TP1FLEN ((uint32)(0x7FUL << 3)) +#define MSP_TCF_MASK_TDTYP ((uint32)(0x3UL << 10)) +#define MSP_TCF_MASK_TENDN ((uint32)(0x1UL << 12)) +#define MSP_TCF_MASK_TDDLY ((uint32)(0x3UL << 13)) +#define MSP_TCF_MASK_TFSIG ((uint32)(0x1UL << 15)) +#define MSP_TCF_MASK_TP2ELEN ((uint32)(0x7UL << 16)) +#define MSP_TCF_MASK_TP2FLEN ((uint32)(0x7FUL << 19)) +#define MSP_TCF_MASK_TP2SM ((uint32)(0x1UL << 26)) +#define MSP_TCF_MASK_TP2EN ((uint32)(0x1UL << 27)) +#define MSP_TCF_MASK_TBSWAP ((uint32)(0x3UL << 28)) + +/*####################################################################### + MSP Receive Configuration Register - msp_rcf +######################################################################### + */ +#define MSP_RCF_MASK_RP1ELEN ((uint32)(0x7UL << 0)) +#define MSP_RCF_MASK_RP1FLEN ((uint32)(0x7FUL << 3)) +#define MSP_RCF_MASK_RDTYP ((uint32)(0x3UL << 10)) +#define MSP_RCF_MASK_RENDN ((uint32)(0x1UL << 12)) +#define MSP_RCF_MASK_RDDLY ((uint32)(0x3UL << 13)) +#define MSP_RCF_MASK_RFSIG ((uint32)(0x1UL << 15)) +#define MSP_RCF_MASK_RP2ELEN ((uint32)(0x7UL << 16)) +#define MSP_RCF_MASK_RP2FLEN ((uint32)(0x7FUL << 19)) +#define MSP_RCF_MASK_RP2SM ((uint32)(0x1UL << 26)) +#define MSP_RCF_MASK_RP2EN ((uint32)(0x1UL << 27)) +#define MSP_RCF_MASK_RBSWAP ((uint32)(0x3UL << 28)) + +/*####################################################################### + MSP Sample Rate Generator Register - msp_srg +######################################################################### + */ +#define MSP_SRG_MASK_SCKDIV ((uint32)(0x3FFUL << 0)) +#define MSP_SRG_MASK_FRWID ((uint32)(0x3FUL << 10)) +#define MSP_SRG_MASK_FRPER ((uint32)(0x1FFFUL << 16)) + +/*####################################################################### + MSP Flag Register - msp_flr +######################################################################### + */ +#define MSP_FLR_MASK_RBUSY ((uint32)(0x1UL << 0)) +#define MSP_FLR_MASK_RFE ((uint32)(0x1UL << 1)) +#define MSP_FLR_MASK_RFU ((uint32)(0x1UL << 2)) +#define MSP_FLR_MASK_TBUSY ((uint32)(0x1UL << 3)) +#define MSP_FLR_MASK_TFE ((uint32)(0x1UL << 4)) +#define MSP_FLR_MASK_TFU ((uint32)(0x1UL << 5)) + +/*####################################################################### + MSP DMA Control Register - msp_dmacr +######################################################################### + */ +#define MSP_DMACR_MASK_RDMAE ((uint32)(0x1UL << 0)) +#define MSP_DMACR_MASK_TDMAE ((uint32)(0x1UL << 1)) + +/*####################################################################### + MSP Interrupt Mask Set/Clear Register - msp_imsc +######################################################################### + */ +#define MSP_IMSC_MASK_RXIM ((uint32)(0x1UL << 0)) +#define MSP_IMSC_MASK_ROEIM ((uint32)(0x1UL << 1)) +#define MSP_IMSC_MASK_RSEIM ((uint32)(0x1UL << 2)) +#define MSP_IMSC_MASK_RFSIM ((uint32)(0x1UL << 3)) +#define MSP_IMSC_MASK_TXIM ((uint32)(0x1UL << 4)) +#define MSP_IMSC_MASK_TUEIM ((uint32)(0x1UL << 5)) +#define MSP_IMSC_MASK_TSEIM ((uint32)(0x1UL << 6)) +#define MSP_IMSC_MASK_TFSIM ((uint32)(0x1UL << 7)) +#define MSP_IMSC_MASK_RFOIM ((uint32)(0x1UL << 8)) +#define MSP_IMSC_MASK_TFOIM ((uint32)(0x1UL << 9)) + +/*####################################################################### + MSP Raw Interrupt status Register - msp_ris +######################################################################### + */ +#define MSP_RIS_MASK_RXRIS ((uint32)(0x1UL << 0)) +#define MSP_RIS_MASK_ROERIS ((uint32)(0x1UL << 1)) +#define MSP_RIS_MASK_RSERIS ((uint32)(0x1UL << 2)) +#define MSP_RIS_MASK_RFSRIS ((uint32)(0x1UL << 3)) +#define MSP_RIS_MASK_TXRIS ((uint32)(0x1UL << 4)) +#define MSP_RIS_MASK_TUERIS ((uint32)(0x1UL << 5)) +#define MSP_RIS_MASK_TSERIS ((uint32)(0x1UL << 6)) +#define MSP_RIS_MASK_TFSRIS ((uint32)(0x1UL << 7)) +#define MSP_RIS_MASK_RFORIS ((uint32)(0x1UL << 8)) +#define MSP_RIS_MASK_TFORIS ((uint32)(0x1UL << 9)) + +/*####################################################################### + MSP Masked Interrupt status Register - msp_mis +######################################################################### + */ +#define MSP_MIS_MASK_RXMIS ((uint32)(0x1UL << 0)) +#define MSP_MIS_MASK_ROEMIS ((uint32)(0x1UL << 1)) +#define MSP_MIS_MASK_RSEMIS ((uint32)(0x1UL << 2)) +#define MSP_MIS_MASK_RFSMIS ((uint32)(0x1UL << 3)) +#define MSP_MIS_MASK_TXMIS ((uint32)(0x1UL << 4)) +#define MSP_MIS_MASK_TUEMIS ((uint32)(0x1UL << 5)) +#define MSP_MIS_MASK_TSEMIS ((uint32)(0x1UL << 6)) +#define MSP_MIS_MASK_TFSMIS ((uint32)(0x1UL << 7)) +#define MSP_MIS_MASK_RFOMIS ((uint32)(0x1UL << 8)) +#define MSP_MIS_MASK_TFOMIS ((uint32)(0x1UL << 9)) + +/*####################################################################### + MSP Interrupt Clear Register - msp_icr +######################################################################### + */ +#define MSP_ICR_MASK_ROEIC ((uint32)(0x1UL << 1)) +#define MSP_ICR_MASK_RSEIC ((uint32)(0x1UL << 2)) +#define MSP_ICR_MASK_RFSIC ((uint32)(0x1UL << 3)) +#define MSP_ICR_MASK_TUEIC ((uint32)(0x1UL << 5)) +#define MSP_ICR_MASK_TSEIC ((uint32)(0x1UL << 6)) +#define MSP_ICR_MASK_TFSIC ((uint32)(0x1UL << 7)) + +/*####################################################################### + MSP Receiver/Transmitter states (Enabled or disabled) +######################################################################### + */ +#define MSP_RECEIVER_DISABLED 0 +#define MSP_RECEIVER_ENABLED 1 +#define MSP_TRANSMITTER_DISABLED 0 +#define MSP_TRANSMITTER_ENABLED 1 +/*####################################################################### + MSP Receiver/Transmitter FIFO constants +######################################################################### + */ +#define MSP_LOOPBACK_DISABLED 0 +#define MSP_LOOPBACK_ENABLED 1 + +#define MSP_TX_FIFO_DISABLED 0 +#define MSP_TX_FIFO_ENABLED 1 +#define MSP_TX_ENDIANESS_MSB 0 +#define MSP_TX_ENDIANESS_LSB 1 + +#define MSP_RX_FIFO_DISABLED 0 +#define MSP_RX_FIFO_ENABLED 1 +#define MSP_RX_ENDIANESS_MSB 0 +#define MSP_RX_ENDIANESS_LSB 1 + + +/*####################################################################### + MSP Controller State constants +######################################################################### + */ +#define MSP_IS_SPI_SLAVE 0 +#define MSP_IS_SPI_MASTER 1 + +#define SPI_BURST_MODE_DISABLE 0 +#define SPI_BURST_MODE_ENABLE 1 + +/*####################################################################### + MSP Phase and Polarity constants +######################################################################### + */ +#define MSP_SPI_PHASE_ZERO_CYCLE_DELAY 0x2 +#define MSP_SPI_PHASE_HALF_CYCLE_DELAY 0x3 + +#define MSP_TX_CLOCK_POL_LOW 0 +#define MSP_TX_CLOCK_POL_HIGH 1 + +/*####################################################################### + MSP SRG and Frame related constants +######################################################################### + */ +#define MSP_FRAME_GEN_DISABLE 0 +#define MSP_FRAME_GEN_ENABLE 1 + +#define MSP_SAMPLE_RATE_GEN_DISABLE 0 +#define MSP_SAMPLE_RATE_GEN_ENABLE 1 + + +#define MSP_CLOCK_INTERNAL 0x0 //48 MHz +#define MSP_CLOCK_EXTERNAL 0x2 //SRG is derived from MSPSCK +#define MSP_CLOCK_EXTERNAL_RESYNC 0x3 //SRG is derived from MSPSCK pin but is resynchronized on MSPRFS (Receive Frame Sync signal) + + +#define MSP_TRANSMIT_DATA_WITHOUT_DELAY 0 +#define MSP_TRANSMIT_DATA_WITH_DELAY 1 + + +/*INT: means frame sync signal provided by frame generator logic in the MSP + EXT: means frame sync signal provided by external pin MSPTFS + */ +#define MSP_TX_FRAME_SYNC_EXT 0x0 +#define MSP_TX_FRAME_SYNC_INT 0x2 /*each time MSP_TDR (Transmit Data Register) is copied to MSP_TSR (Transmit Shift Register).*/ +#define MSP_TX_FRAME_SYNC_INT_CFG 0x3 /*period and width defined by FRPER and FRWID values in MSP_SRG register.*/ + + +#define MSP_TX_FRAME_SYNC_POL_HIGH 0 +#define MSP_TX_FRAME_SYNC_POL_LOW 1 + + +#define MSP_HANDLE_RX_FRAME_SYNC_PULSE 0 +#define MSP_IGNORE_RX_FRAME_SYNC_PULSE 1 + +#define MSP_RX_NO_DATA_DELAY 0x0 +#define MSP_RX_1BIT_DATA_DELAY 0x1 +#define MSP_RX_2BIT_DATA_DELAY 0x2 +#define MSP_RX_3BIT_DATA_DELAY 0x3 + +#define MSP_HANDLE_TX_FRAME_SYNC_PULSE 0 +#define MSP_IGNORE_TX_FRAME_SYNC_PULSE 1 + +#define MSP_TX_NO_DATA_DELAY 0x0 +#define MSP_TX_1BIT_DATA_DELAY 0x1 +#define MSP_TX_2BIT_DATA_DELAY 0x2 +#define MSP_TX_3BIT_DATA_DELAY 0x3 + + +/*####################################################################### + MSP Interrupt related Macros +######################################################################### + */ +#define DISABLE_ALL_MSP_INTERRUPTS 0x0 +#define ENABLE_ALL_MSP_INTERRUPTS 0x333 +#define CLEAR_ALL_MSP_INTERRUPTS 0xEE + +/*####################################################################### + Default MSP Register Values +######################################################################### + */ + +#define DEFAULT_MSP_REG_DMACR 0x00000000 + +#define DEFAULT_MSP_REG_SRG 0x1FFF0000 + +#define DEFAULT_MSP_REG_GCR ( \ + GEN_MASK_BITS(MSP_RECEIVER_DISABLED, MSP_GCR_MASK_RXEN,0) | \ + GEN_MASK_BITS(MSP_RX_FIFO_ENABLED, MSP_GCR_MASK_RFFEN,1) | \ + GEN_MASK_BITS(MSP_LOOPBACK_DISABLED, MSP_GCR_MASK_LBM,7) | \ + GEN_MASK_BITS(MSP_TRANSMITTER_DISABLED, MSP_GCR_MASK_TXEN,8) | \ + GEN_MASK_BITS(MSP_TX_FIFO_ENABLED, MSP_GCR_MASK_TFFEN,9) | \ + GEN_MASK_BITS(MSP_TX_FRAME_SYNC_POL_LOW, MSP_GCR_MASK_TFSPOL,10) | \ + GEN_MASK_BITS(MSP_TX_FRAME_SYNC_INT, MSP_GCR_MASK_TFSSEL,11) | \ + GEN_MASK_BITS(MSP_TX_CLOCK_POL_HIGH, MSP_GCR_MASK_TCKPOL,13) | \ + GEN_MASK_BITS(MSP_IS_SPI_MASTER, MSP_GCR_MASK_TCKSEL,14) | \ + GEN_MASK_BITS(MSP_TRANSMIT_DATA_WITHOUT_DELAY, MSP_GCR_MASK_TXDDL,15) | \ + GEN_MASK_BITS(MSP_SAMPLE_RATE_GEN_ENABLE, MSP_GCR_MASK_SGEN,16) | \ + GEN_MASK_BITS(MSP_CLOCK_INTERNAL, MSP_GCR_MASK_SCKSEL,18) | \ + GEN_MASK_BITS(MSP_FRAME_GEN_ENABLE, MSP_GCR_MASK_FGEN,20) | \ + GEN_MASK_BITS(MSP_SPI_PHASE_ZERO_CYCLE_DELAY, MSP_GCR_MASK_SPICKM,21) | \ + GEN_MASK_BITS(SPI_BURST_MODE_DISABLE, MSP_GCR_MASK_SPIBME,23) \ + ) + +#define DEFAULT_MSP_REG_RCF ( \ + GEN_MASK_BITS(MSP_DATA_BITS_32, MSP_RCF_MASK_RP1ELEN, 0) | \ + GEN_MASK_BITS(MSP_IGNORE_RX_FRAME_SYNC_PULSE, MSP_RCF_MASK_RFSIG, 15) | \ + GEN_MASK_BITS(MSP_RX_1BIT_DATA_DELAY, MSP_RCF_MASK_RDDLY, 13) | \ + GEN_MASK_BITS(MSP_RX_ENDIANESS_LSB, MSP_RCF_MASK_RENDN, 12) \ + ) + +#define DEFAULT_MSP_REG_TCF ( \ + GEN_MASK_BITS(MSP_DATA_BITS_32, MSP_TCF_MASK_TP1ELEN, 0) | \ + GEN_MASK_BITS(MSP_IGNORE_TX_FRAME_SYNC_PULSE, MSP_TCF_MASK_TFSIG, 15) | \ + GEN_MASK_BITS(MSP_TX_1BIT_DATA_DELAY, MSP_TCF_MASK_TDDLY, 13) | \ + GEN_MASK_BITS(MSP_TX_ENDIANESS_LSB, MSP_TCF_MASK_TENDN, 12) \ + ) + +#endif --- /dev/null +++ linux-2.6.20/include/asm-arm/arch-nomadik/msp.h @@ -0,0 +1,322 @@ +/*Copyright 2006, STMicroelectronics + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifndef NOMADIC_MSP_HEADER +#define NOMADIC_MSP_HEADER + +/* Generic config struct. Use the actual values defined below for global + * control register + */ + +struct msp_generic_config { + unsigned int input_clock_freq; + unsigned int rx_clock_sel; + unsigned int tx_clock_sel; + unsigned int srg_clock_sel; + unsigned int rx_endianess; + unsigned int tx_endianess; + unsigned int rx_frame_sync_pol; + unsigned int tx_frame_sync_pol; + unsigned int rx_frame_sync_sel; + unsigned int tx_frame_sync_sel; + unsigned int rx_unexpect_frame_sync; + unsigned int tx_unexpect_frame_sync; + unsigned int rx_fifo_config; + unsigned int tx_fifo_config; + unsigned int spi_clk_mode; + unsigned int spi_burst_mode; +}; +typedef enum { + MSP_REQUEST_NOT_APPLICABLE = -9, + MSP_BAD_PERIHERAL_ID = -8, + MSP_TRANSMISSION_ON_GOING = -7, + MSP_TRANSMIT_FIFO_TIMEOUT = -6, + MSP_FEATURE_NOT_SUPPORTED = -5, + MSP_NON_AUTHORIZED_MODE = -4, + MSP_NO_ACTIVE_IT_ERROR = -3, + MSP_NOT_CONFIGURED = -2, + MSP_PARAMETER_ERROR = -1, + MSP_OK = 0, + MSP_INTERNAL_EVENT = 1, + MSP_REMAINING_PENDING_EVENTS = 2, + MSP_REMAINING_FILTER_PENDING_EVENTS = 3, + MSP_NO_MORE_PENDING_EVENT = 4, + MSP_NO_MORE_FILTER_PENDING_EVENT = 5, + MSP_NO_PENDING_EVENT_ERROR = 7 +} t_msp_error; + +/*** Protocols ***/ +enum { + MSP_I2S_PROTOCOL, + MSP_PCM_PROTOCOL, + MSP_PCM_COMPAND_PROTOCOL, + MSP_AC97_PROTOCOL, + MSP_MASTER_SPI_PROTOCOL, + MSP_SLAVE_SPI_PROTOCOL, + MSP_INVALID_PROTOCOL +}; + +/*** Sample Frequencies ***/ +/* These are no longer required, frequencies in Hz can be used directly */ +enum { + MSP_SAMPLE_FREQ_NOT_SUPPORTED = -1, + MSP_SAMPLE_FREQ_8KHZ = 8000, + MSP_SAMPLE_FREQ_12KHZ = 12000, + MSP_SAMPLE_FREQ_16KHZ = 16000, + MSP_SAMPLE_FREQ_24KHZ = 24000, + MSP_SAMPLE_FREQ_32KHZ = 32000, + MSP_SAMPLE_FREQ_44KHZ = 44000, + MSP_SAMPLE_FREQ_48KHZ = 48000, + MSP_SAMPLE_FREQ_64KHZ = 64000, + MSP_SAMPLE_FREQ_88KHZ = 88000, + MSP_SAMPLE_FREQ_96KHZ = 96000, + MSP_SAMPLE_FREQ_22KHZ = 22000, + MSP_SAMPLE_FREQ_11KHZ = 11000 +}; + +/*** Input Frequencies ***/ +/* These are no longer required, frequencies in Hz can be used directly */ +typedef enum { + + MSP_INPUT_FREQ_1MHZ = 1000, + MSP_INPUT_FREQ_2MHZ = 2000, + MSP_INPUT_FREQ_3MHZ = 3000, + MSP_INPUT_FREQ_4MHZ = 4000, + MSP_INPUT_FREQ_5MHZ = 5000, + MSP_INPUT_FREQ_6MHZ = 6000, + MSP_INPUT_FREQ_8MHZ = 8000, + MSP_INPUT_FREQ_11MHZ = 11000, + MSP_INPUT_FREQ_12MHZ = 12000, + MSP_INPUT_FREQ_16MHZ = 16000, + MSP_INPUT_FREQ_22MHZ = 22000, + MSP_INPUT_FREQ_24MHZ = 24000, + MSP_INPUT_FREQ_48MHZ = 48000 + +} t_msp_in_clock_freq; + +#define MSP_INPUT_FREQ_APB 48000000 + +/*** Stereo mode. Used for APB data accesses as 16 bits accesses (mono), + * 32 bits accesses (stereo). + ***/ +enum +{ + MSP_MONO, + MSP_STEREO +}; + +/* Direction (Transmit/Receive mode) */ +enum { + MSP_TRANSMIT_MODE, + MSP_RECEIVE_MODE, + MSP_BOTH_T_R_MODE +}; + +/* Dma mode should be used for large transfers, + * polling mode should be used for transfers of a few bytes + */ +enum { + MSP_DMA_MODE, + MSP_POLLING_MODE, + MSP_INTERRUPT_MODE +}; + +/* User client for the MSP */ +typedef enum { + MSP_NO_USER = 0, + MSP_USER_SPI, + MSP_USER_ALSA, + MSP_USER_SAA, +}t_msp_user; + +/*Flag structure for MSPx*/ +typedef struct { + struct semaphore lock; + t_msp_user user; +}msp_flag ; + + +/* Transmit and receive configuration register */ +#define MSP_BIG_ENDIAN 0x00000000 +#define MSP_LITTLE_ENDIAN 0x00001000 +#define MSP_UNEXPECTED_FS_ABORT 0x00000000 +#define MSP_UNEXPECTED_FS_IGNORE 0x00008000 +#define MSP_NON_MODE_BIT_MASK 0x00009000 + +/* Global configuration register +--------------------------------*/ +#define RX_ENABLE 0x00000001 +#define RX_FIFO_ENABLE 0x00000002 +#define RX_SYNC_SRG 0x00000010 +#define RX_CLK_POL_RISING 0x00000020 +#define RX_CLK_SEL_SRG 0x00000040 +#define TX_ENABLE 0x00000100 +#define TX_FIFO_ENABLE 0x00000200 +#define TX_SYNC_SRG_PROG 0x00001800 +#define TX_CLK_POL_RISING 0x00002000 +#define TX_CLK_SEL_SRG 0x00004000 +#define TX_EXTRA_DELAY_ENABLE 0x00008000 +#define SRG_ENABLE 0x00010000 +#define FRAME_GEN_ENABLE 0x00100000 +#define SRG_CLK_SEL_APB 0x00000000 +#define RX_FIFO_SYNC_HI 0x00000000 +#define TX_FIFO_SYNC_HI 0x00000000 +#define SPI_CLK_MODE_NORMAL 0x00000000 + +/* SPI Clock Modes enumertion + * SPI clock modes of MSP provides compatibility with + * the SPI protocol.MSP supports 2 SPI transfer formats. + * MSP_ZERO_DELAY_SPI_MODE:MSP transmits data over Tx/Rx + * Lines immediately after MSPTCK/MSPRCK rising/falling edge. + * MSP_HALF_CYCLE_DELY_SPI_MODE:MSP transmits data one-half cycle + * ahead of the rising/falling edge of the MSPTCK + */ +enum { + MSP_NON_SPI_PROTOCOL = 0, + MSP_ZERO_DELAY_SPI_MODE = 2, + MSP_HALF_CYCLE_DELY_SPI_MODE = 3 +}; + +#define MSP_FRAME_SIZE_AUTO -1 + +enum msp_data_size{ + MSP_DATA_SIZE_DEFAULT = -1, + MSP_DATA_SIZE_8BIT, + MSP_DATA_SIZE_10BIT, + MSP_DATA_SIZE_12BIT, + MSP_DATA_SIZE_14BIT, + MSP_DATA_SIZE_16BIT, + MSP_DATA_SIZE_20BIT, + MSP_DATA_SIZE_24BIT, + MSP_DATA_SIZE_32BIT, +}; + +#define MSP_I2S_SIMPLE_CONFIG { \ + MSP_INPUT_FREQ_APB, \ + RX_CLK_SEL_SRG, \ + TX_CLK_SEL_SRG, \ + SRG_CLK_SEL_APB, \ + MSP_BIG_ENDIAN, \ + MSP_BIG_ENDIAN, \ + RX_FIFO_SYNC_LOW, \ + TX_FIFO_SYNC_LOW, \ + RX_SYNC_SRG, \ + TX_SYNC_SRG_PROG, \ + MSP_UNEXPECTED_FS_IGNORE, \ + MSP_UNEXPECTED_FS_IGNORE, \ + RX_FIFO_ENABLE, \ + TX_FIFO_ENABLE, \ + SPI_CLK_MODE_NORMAL, \ + SPI_BURST_MODE_DISABLE \ +} + +#define MSP_PCM_SIMPLE_CONFIG { \ + MSP_INPUT_FREQ_APB, \ + RX_CLK_SEL_SRG, \ + TX_CLK_SEL_SRG, \ + SRG_CLK_SEL_APB, \ + MSP_BIG_ENDIAN, \ + MSP_BIG_ENDIAN, \ + RX_FIFO_SYNC_HI, \ + TX_FIFO_SYNC_HI, \ + RX_SYNC_SRG, \ + TX_SYNC_SRG_AUTO, \ + MSP_UNEXPECTED_FS_IGNORE, \ + MSP_UNEXPECTED_FS_IGNORE, \ + RX_FIFO_ENABLE, \ + TX_FIFO_ENABLE, \ + SPI_CLK_MODE_NORMAL, \ + SPI_BURST_MODE_DISABLE \ +} + +#define MSP_MASTER_SPI_SIMPLE_CONFIG { \ + MSP_INPUT_FREQ_APB, \ + RX_CLK_SEL_SRG, \ + TX_CLK_SEL_SRG, \ + SRG_CLK_SEL_APB, \ + MSP_BIG_ENDIAN, \ + MSP_BIG_ENDIAN, \ + RX_FIFO_SYNC_LOW, \ + TX_FIFO_SYNC_LOW, \ + RX_SYNC_SRG, \ + TX_SYNC_SRG_AUTO, \ + MSP_UNEXPECTED_FS_IGNORE, \ + MSP_UNEXPECTED_FS_IGNORE, \ + RX_FIFO_ENABLE, \ + TX_FIFO_ENABLE, \ + SPI_CLK_MODE_ZERO_DLY, \ + SPI_BURST_MODE_DISABLE \ +} + +#define MSP_SLAVE_SPI_SIMPLE_CONFIG { \ + MSP_INPUT_FREQ_APB, \ + RX_CLK_SEL_EXT, \ + TX_CLK_SEL_EXT, \ + SRG_CLK_SEL_APB, \ + MSP_BIG_ENDIAN, \ + MSP_BIG_ENDIAN, \ + RX_FIFO_SYNC_LOW, \ + TX_FIFO_SYNC_LOW, \ + RX_SYNC_EXT, \ + TX_SYNC_EXT, \ + MSP_UNEXPECTED_FS_IGNORE, \ + MSP_UNEXPECTED_FS_IGNORE, \ + RX_FIFO_ENABLE, \ + TX_FIFO_ENABLE, \ + SPI_CLK_MODE_ZERO_DLY, \ + SPI_BURST_MODE_DISABLE \ +} + +#ifdef __KERNEL__ +/* exported functions */ +#include +int nomadik_msp_configure(int msp, struct msp_generic_config *config, t_msp_user user); +int nomadik_msp_send_data(int msp, void *data, size_t bytes); +int nomadik_msp_receive_data(int msp, void *data, size_t bytes); +int nomadik_msp_transceive_data(int msp, void *txdata, size_t txbytes, + void *rxdata, size_t rxbytes); +int nomadik_msp_enable(int msp, int direction, int work_mode, + int protocol, int frame_freq, int frame_size, + enum msp_data_size data_size, t_msp_user user); +int nomadik_msp_disable(int msp, int direction, t_msp_user user); +void nomadik_msp_flush_input(int msp); +#endif + +/*************************************************************************************** + * + * User space interface starts here. This is intended for testing only. + * + ***************************************************************************************/ +struct msp_user_enable { + int direction; + int work_mode; + int protocol; + int frame_freq; + int frame_size; + enum msp_data_size data_size; +}; + +#include + +#define MSP_IOC_MAGIC 'M' +#define MSP_CONFIGURE _IOW(MSP_IOC_MAGIC, 0, struct msp_generic_config) +#define MSP_ENABLE _IOW(MSP_IOC_MAGIC, 1, struct msp_user_enable) +#define MSP_DISABLE _IOW(MSP_IOC_MAGIC, 2, int) + +#endif --- /dev/null +++ linux-2.6.20/include/asm-arm/arch-nomadik/mtu.h @@ -0,0 +1,90 @@ + /* Header file for Multiple Timer Units. + * mtu.h : Defines for registering & using MTU timers */ + +#ifndef __NOMADIK_MTU_H +#define __NOMADIK_MTU_H +#endif + +#define MTU0_BASE NOMADIK_MTU0_BASE +#define MTU1_BASE NOMADIK_MTU1_BASE + +#define MTU0 IO_ADDRESS ( MTU0_BASE) +#define MTU1 IO_ADDRESS ( MTU1_BASE) + + /* macro to build timer initial names as MTU0_T2 */ +#define MTUx_Ty (x, y) (MTU ## x ## _T ## y) + + /* MTU timer operating modes */ +typedef enum { + MTU_FREE_RUN = 0xffffffbf, + MTU_PERIODIC = 0x00000040, + MTU_ONE_SHOT = 0x00000001 +} mtu_timer_mode_t; + + /* MTU timer names in the MTUx_Ty format where x =0,1 and y =0,1,2,3 */ +typedef enum { + MTU0_T0 = 1, /* since we do a multiplication in macros */ + MTU0_T1, + MTU0_T2, + MTU0_T3, + MTU1_T0, + MTU1_T1, + MTU1_T2, + MTU1_T3 +} mtu_timer_t; + +typedef enum { + MTU_PRESCALE_BY_ONE = 0, + MTU_PRESCALE_BY_SIXTEEN = 4, + MTU_PRESCALE_BY_256 = 8, +} mtu_prescale_t; + +#define MTU_MAX_TIMERS 8 + + /* 8 timer units ctrl registers */ +#define TyLR 0x0000 +#define TyVAL 0x0004 +#define TyCR 0x0008 +#define TyBGLR 0x000C + /* 2 MTU intr registers */ +#define TxIMSC 0x0000 +#define TxRIS 0x0004 +#define TxMIS 0x0008 +#define TxICR 0x000C + + /* macro to generate register address of a timer (0,1,2,3) */ +#define MTU_CTRL_REG(__timer, __register) \ + __timer > 4 ? MTU1 + ((__timer -4) * 0x10) + __register : \ + MTU0 + (__timer * 0x10) + __register + + /* macro to generate interrupt register address of a MTUs(0,1) */ +#define MTU_INTR_REG(__timer, __register) \ + __timer > 4 ? MTU1 + __register : \ + MTU0 + __register + +/* timespec format is not used, rather ktime_t format is better for HR timers. + */ +#include +#include +#include + +struct mtu_struct { + mtu_timer_t timer; + mtu_timer_mode_t mode; + ktime_t interval, bg_interval; + irqreturn_t(*mtu_irq) (mtu_timer_t timer_id); + char *name; +}; + +int __init nomadik_mtu_init(void); +void __exit nomadik_mtu_exit(void); + +int mtu_register_timer(struct mtu_struct *mtu); +int mtu_unregister_timer(struct mtu_struct *mtu); + +unsigned long mtu_get_decrementing_counter_value(unsigned timer); +inline void mtu_bg_load_counter(mtu_timer_t timer, + unsigned long timer_load_register); + +inline unsigned long mtu_intr_reg_readl(unsigned int timer, + unsigned long ctrl_register); --- /dev/null +++ linux-2.6.20/include/asm-arm/arch-nomadik/nandflash.h @@ -0,0 +1,42 @@ +#ifndef NMDK_NMDK_NAND_H +#define NMDK_NMDK_NAND_H +#include +#include + +struct nomadik_nand_platform_data { + struct mtd_partition *parts; + int num_parts; + u32 lp_options; + int eccsize; + int eccsteps; + int badblockpos; + struct nand_bbt_descr *bbt_desc; + struct nand_ecclayout *nand_oob; + int (*init) (void); + int (*exit) (void); + int (*compute_ecc) (struct mtd_info *, const u_char *, u_char *); + void (*hwcontrol) (struct mtd_info *, int, unsigned int); +}; + +struct nomadik_nand_info { + struct nand_chip chip; + struct mtd_info mtd; + void __iomem *cmemd_va; + void __iomem *cmema_va; + void __iomem *cmemc_va; + struct nand_bbt_descr *bbt_desc; +}; + +#define NAND_GPIO GPIO_PIN_28 +#define NAND_FLASH_PROTOFF GPIO_PIN_105 +#define NAND_B0_CMEM_DATA 0x40000000 +#define NAND_B0_CMEM_CMD 0x40800000 +#define NAND_B0_CMEM_ADDR 0x41000000 +#define NAND_B0_AMEM_BASE 0x4C000000 +#define NAND_B0_IOSPACE_BASE 0x4C000000 + +#define DEFAULT_PCR0_VALUE 0x0000001E +#define DEFAULT_PMEM0_VALUE 0x000D0A00 +#define DEFAULT_PATT0_VALUE 0x00100A00 + +#endif /* NMDK_NAND_H */ --- /dev/null +++ linux-2.6.20/include/asm-arm/arch-nomadik/ndk10_devices.h @@ -0,0 +1,160 @@ +/* + * linux/include/asm-arm/arch-nomadik/ndk10_devices.h + * + * Copyright (C) STMicroelectronics + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#ifndef __ASM_ARM_ARCH_NDK10_DEVICES_H +#define __ASM_ARM_ARCH_NDK10_DEVICES_H +#ifndef __ASSEMBLY__ + +#include + +/* CPLD related declaration *********************************************/ +/* the below defination is w.r.to CPLD mapped through FSMC */ +#define NOMADIK_CPLD_BASE 0x36000000 /* CPLD base */ +#define NOMADIK_CPLD_RGPO0_BASE 0x36400000 /* rgpo0 gpo reg 0 on UIB board */ +#define NOMADIK_CPLD_RGPO1_BASE 0x36480000 /* rgpo1 gpo reg 1 on UIB board */ +#define NOMADIK_CPLD_RGPO2_BASE 0x36500000 /* rgpo2 gpo reg 2 on UIB board */ + +/* Bits defination for COB_IDENT register */ +#define COB_REV_BITS 0x0300 /*numeric field */ +#define COB_REV_BITS_POS 8 /*need to roate this much times */ +#define COB_REV_SUBBITS 0x00E0 /*decimal field */ +#define COB_REV_SUBBITS_POS 6 /*need to roate this much times */ +#define CPLD_REV_BITS 0x0018 /*numeric field */ +#define CPLD_REV_BITS_POS 3 /*need to roate this much times */ +#define CPLD_REV_SUBBITS 0x0007 /*decimal field */ + +/* Bits defination for COB_CTL register */ +#define CAM_SHDNnot 0x0800 /*(1)camera module in normal modeld */ +#define CAM_RSTnot 0x0400 /*(1)camera module in normal modeld */ +#define GPIO_EN 0x0200 /*(1)GPIOs Enabled on STn8810 side */ +#define MSP2_SSP_SWAP 0x0100 /*(0)No swap */ +#define MSP2_EN 0x0080 /*(1)MSP2 Enabled on STn8810 side */ +#define SSP_EN 0x0040 /*(1)SSP Enabled on STn8810 side */ +#define UART2NO_SEL 0x0020 /*(1)UART2/0 multiplexer, (0)UART0 selected */ +#define UART_MUX_EN 0x0010 /*(1)will enable UART0/2 multiplexer */ +#define UART1_EN 0x0008 /*(1)UART1 Rs232 Transceiver will be enabled */ +#define SRAM_CFG 0x0004 /*PSRAM configuration register enable */ +#define IR_MODE 0x0002 /*IR transceiver modules SM/Mode pin control */ +#define UIB_LED 0x0001 /*(1) LED on */ +/* Bits defination for Expansion-control-register (EXP_CTRL) */ +#define SPI_CS0not 0x0001 /* */ +#define EXP_3V3_PIO0 SPI_CS0not +#define SPI_CS1not 0x0002 /* */ +#define EXP_3V3_PIO1 SPI_CS1not +#define SPI_CS2not 0x0004 /* */ +#define EXP_3V3_PIO2 SPI_CS2not +#define SPI_CS3not 0x0008 /* */ +#define EXP_3V3_PIO3 SPI_CS3not +#define MASK_MMC_EPIO 0x1000 +/*CPLD related declaration end*/ + +/* + * Macros board specific + */ +#define BOARD_IO_DESC \ + {IO_ADDRESS(NOMADIK_CPLD_RGPO1_BASE), \ + __phys_to_pfn(NOMADIK_CPLD_RGPO1_BASE), SZ_4K, MT_DEVICE} + +/* Ethernet related board specific declaration*************************/ +#define NOMADIK_ETH0_BASE 0x33c00000 /* ETH0 Base */ +#define SMC91111_IRQ GPIO_PIN_45 +#define SMC91111_CLK GPIO_PIN_55 /*clkout for eth*/ + +#define NOMADIK_CPLD_RGPO1_VA IO_ADDRESS(NOMADIK_CPLD_RGPO1_BASE) +#define ETH_DAUGHTER_CARD_RESET 1 + + +/* MMC related board specific declaration*************************/ +#define MMCDETECT_IRQ GPIO_PIN_49 +#define val_volt 7 /*Value to be written at Touareg register */ + +/* Touchpanel related declaration************************************/ +#define TOUCHP_IRQ GPIO_PIN_47 +#define TOUCHP_SSP_CS SPI_CS1not /* EXP_3V3_PIO1 bit of NDK10 */ +#define X_DELTA_MAX 10 /*Max ADC read error limit for Sub- */ +#define Y_DELTA_MAX 16 /*sequent redings */ +#define MAX_12BIT ((1<<12)-1) +#define X_CORR(x, y) (MAX_12BIT - y) +#define Y_CORR(x, y) (MAX_12BIT - x) + +/* Keypad related declaration************************************/ +#define KEYPAD_IRQ GPIO_PIN_40 +#define MAX_KPROW 5 +#define MAX_KPCOL 5 + +/* I2c related board specific declaration************************/ +#define I2C_CLIENT_BUSID13 1 +#define I2C_TOUAREG_ADAPTER 0 +#define I2C_TOUREG_CLIENT_BUSID 1 + +/* Addresses for clients on this board*/ +#define I2C_ADDR_MB 0x50 /* Motherboard*/ +#define I2C_ADDR_UI_DB 0x51 /* UI Daughterboard*/ +#define I2C_ADDR_IO_DB1 0x52 /* I/O Expansion daughter board 1*/ +#define I2C_ADDR_IO_DB2 0x53 /* I/O Expansion daughter board 2*/ +#define I2C_ADDR_CIF_CAM 0x54 /* CCIR-656 ST CIF Camera (Matisse)*/ +#define I2C_ADDR_PP_CAM (0x08>>1) /* pepperpot camera */ +#define I2C_ADDR_MEM_EXP 0x55 /* CCIR-656 ST CIF Camera (Matisse)*/ +#define I2C_ADDR_AC 0x71 /* Audio codec STw5095*/ +#define I2C_ADDR_FM_TUNER 0x62 /* FM Tuner (TDA 7701-Brite)*/ +#define I2C_ADDR_GAS_GAUGE 0x22 /* Gas Gauge (PB700)*/ +#define I2C_ADDR_CAM_MOD 0x45 /* LITEA Camera Module ?*/ +#define I2C0_LP_OWNADDR 0x50 +#define I2C1_LP_OWNADDR 0x60 +#define I2C_ADDR_TOUAREG 0x2D +#define I2C_ADDR_DENC 0x20 + +/* MSP related board specific declaration************************/ +#define MSP_DATA_DELAY MSP_DELAY_1 +#define MSP_TX_CLOCK_EDGE MSP_RISING_EDGE +#define MSP_RX_CLOCK_EDGE MSP_RISING_EDGE + +/*NORflash related board specific declaration*******************/ +#define NMDK_FLASH_BASE 0x30000000 +#define NMDK_FLASH_WINDOW_SIZE 16 * 1024 * 1024 +#define NMDK_FLASH_BUSWIDTH 2 + +#define GET_BANK_WIDTH(val,phys) \ + switch (phys) {\ + case NMDK_FLASH_BASE:\ + val = NMDK_FLASH_BUSWIDTH;\ + break;\ + default:\ + val = NMDK_FLASH_BUSWIDTH;\ + break;\ + } + +/*NANDflash related board specific declaration*******************/ +#define BOARD_SET_NAND_DATA \ + nand_oob->eccbytes = 6; \ + nand_oob->eccpos[0] = 2; \ + nand_oob->eccpos[1] = 3; \ + nand_oob->eccpos[2] = 4; \ + nand_oob->eccpos[3] = 5; \ + nand_oob->eccpos[4] = 6; \ + nand_oob->eccpos[5] = 7; \ + this->badblockpos = 1; + +#define BOARD_SET_NAND_BADBLOCK \ + this->eccsteps = 1; \ + this->badblockpos = 1; + +/*SVA related board specific declaration*******************/ +#define SVA_HCL_INIT_MEM_SIZE SZ_4M + +/* SAA related board specific declaration */ +#define SAA_HCL_INIT_MEM_SIZE SZ_4M + +#ifdef CONFIG_NOMADIK_SAA_INIT_MEM +dma_addr_t saa_get_physical_address(void); +void* saa_get_logical_address(void); +#endif + +#endif /*__ASSEMBLY__*/ +#endif /*__ASM_ARM_ARCH_NDK15_DEVICES_H*/ --- /dev/null +++ linux-2.6.20/include/asm-arm/arch-nomadik/ndk15_devices.h @@ -0,0 +1,248 @@ +/* + * linux/include/asm-arm/arch-nomadik/ndk15_devices.h + * + * Copyright (C) STMicroelectronics + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#ifndef __ASM_ARM_ARCH_NDK15_DEVICES_H +#define __ASM_ARM_ARCH_NDK15_DEVICES_H +#ifndef __ASSEMBLY__ + +#include + +/* + * Macros board specific + */ +#define BOARD_IO_DESC /*nothing to define */ + +/* Ethernet related board specific declaration*************************/ +#define NOMADIK_ETH0_BASE 0x36800000 /* ETH0 Base */ +#define SMC91111_IRQ GPIO_PIN_104 + +/* MMC related board specific declaration*************************/ +#define MMCDETECT_IRQ GPIO_PIN_49 +#define val_volt 7 /*Value to be written at Touareg register */ + +/* Touchpanel related declaration************************************/ +#define TOUCHP_IRQ GPIO_PIN_104 /* PENIRQNO: through CPLD_IT */ +#define TOUCHP_CS0 GPIO_PIN_106 /* Chip select pin0 */ +#define TOUCHP_CS1 GPIO_PIN_105 /* Chip select pin1 + conflicts with NAND_PROT_OFF */ +#define X_DELTA_MAX 2* 10 /*Max ADC read error limit for Sub- */ +#define Y_DELTA_MAX 2 *16 /*sequent redings */ +#define MAX_12BIT ((1<<12)-1) +#define X_CORR(x, y) (y) +#define Y_CORR(x, y) (MAX_12BIT - x) + +/* Keypad related declaration************************************/ +#define KEYPAD_IRQ GPIO_PIN_104 +#define MAX_KPROW 8 +#define MAX_KPCOL 8 + +/* I2c related board specific declaration************************/ +#define I2C_CLIENT_BUSID13 0 +#define I2C_TOUAREG_ADAPTER 1 +#define I2C_TOUREG_CLIENT_BUSID 0 +#define I2C_CPLD_CLIENT_BUSID 0 +/* Addresses for clients on this board*/ +#define I2C_ADDR_MB 0x50 /* Motherboard*/ +#define I2C_ADDR_UI_DB 0x51 /* UI Daughterboard*/ +#define I2C_ADDR_IO_DB1 0x52 /* I/O Expansion daughter board 1*/ +#define I2C_ADDR_IO_DB2 0x53 /* I/O Expansion daughter board 2*/ +#define I2C_ADDR_CIF_CAM 0x54 /* CCIR-656 ST CIF Camera (Matisse)*/ +#define I2C_ADDR_PP_CAM (0x08>>1) /* pepperpot camera */ +#define I2C_ADDR_MEM_EXP 0x55 /* CCIR-656 ST CIF Camera (Matisse)*/ +#define I2C_ADDR_AC 0x1A /* Audio codec STw5095*/ +#define I2C_ADDR_FM_TUNER 0x62 /* FM Tuner (TDA 7701-Brite)*/ +#define I2C_ADDR_GAS_GAUGE 0x22 /* Gas Gauge (PB700)*/ +#define I2C_ADDR_CAM_MOD 0x45 /* LITEA Camera Module ?*/ +#define I2C0_LP_OWNADDR 0x50 +#define I2C1_LP_OWNADDR 0x60 +#define I2C_ADDR_TOUAREG 0x2D +#define I2C_ADDR_CPLD 0x1C /* actual 0x38 and 0x39, considered only 7 msbs */ +#define I2C_ADDR_DENC 0x20 + +/* MSP related board specific declaration************************/ +#define MSP_DATA_DELAY MSP_DELAY_0 +#define MSP_TX_CLOCK_EDGE MSP_FALLING_EDGE +#define MSP_RX_CLOCK_EDGE MSP_FALLING_EDGE + +/*NORflash related board specific declaration*******************/ +#define NMDK_FLASH_BASE 0x30000000 +#define NMDK_FLASH_WINDOW_SIZE 32 * 1024 * 1024 +#define NMDK_FLASH_BUSWIDTH 2 + +#define GET_BANK_WIDTH(val,phys) \ + switch (phys) { \ + case NMDK_FLASH_BASE: \ + val = NMDK_FLASH_BUSWIDTH;\ + break;\ + default:\ + break;\ + } + +/*NANDflash related board specific declaration*******************/ +#define BOARD_SET_NAND_DATA \ + nand_oob->eccbytes = 12; \ + nand_oob->eccpos[0] = 2; \ + nand_oob->eccpos[1] = 3; \ + nand_oob->eccpos[2] = 4; \ + nand_oob->eccpos[3] = 18; \ + nand_oob->eccpos[4] = 19; \ + nand_oob->eccpos[5] = 20; \ + nand_oob->eccpos[6] = 34; \ + nand_oob->eccpos[7] = 35; \ + nand_oob->eccpos[8] = 36; \ + nand_oob->eccpos[9] = 50; \ + nand_oob->eccpos[10] = 51; \ + nand_oob->eccpos[11] = 52; \ + this->badblockpos = 5; + +#define BOARD_SET_NAND_BADBLOCK \ + this->eccsteps = 4; \ + this->badblockpos = 5; + +/*SVA related board specific declaration*******************/ +#define SVA_HCL_INIT_MEM_SIZE SZ_8M + +/* SAA related board specific declaration */ +#define SAA_HCL_INIT_MEM_SIZE SZ_4M + +#ifdef CONFIG_NOMADIK_SAA_INIT_MEM +dma_addr_t saa_get_physical_address(void); +void* saa_get_logical_address(void); +#endif + +/* CPLD/EPIO related declaration************************************/ +/* the below defination is w.r.to CPLD version 2.0.1.0 */ +#define NOMADIK_CPLD_BASE 0x36000000 /* CPLD base */ + +#define COB15_ID 0x00 /* offsets for cpld board registers */ +#define COB15_CTRL 0x02 +#define KEYPAD_DATA 0x04 +#define MSP_CONF 0x06 +#define UART_CONF 0x08 +#define SSP_CONF 0x0A +#define IT_MNGT 0x0C +#define AUX_GPO1 0x20 +#define AUX_GPI1 0x30 + +extern u16 nomadik_epio_read_i2c(int reg); +extern int nomadik_epio_write_i2c(u16 data, int reg); +#define nomadik_epio_read_cob_id() nomadik_epio_read_i2c(COB15_ID) +#define nomadik_epio_read_cob_ctl() nomadik_epio_read_i2c(COB15_CTRL) +#define nomadik_epio_read_keypad() nomadik_epio_read_i2c(KEYPAD_DATA) +#define nomadik_epio_read_msp_conf() nomadik_epio_read_i2c(MSP_CONF) +#define nomadik_epio_read_uart_conf() nomadik_epio_read_i2c(UART_CONF) +#define nomadik_epio_read_ssp_conf() nomadik_epio_read_i2c(SSP_CONF) +#define nomadik_epio_read_it_mngt() nomadik_epio_read_i2c(IT_MNGT) +#define nomadik_epio_read_aux_gpo1() nomadik_epio_read_i2c(AUX_GPO1) +#define nomadik_epio_read_aux_gpi1() nomadik_epio_read_i2c(AUX_GPI1) +#define nomadik_epio_write_cob_ctl(x) nomadik_epio_write_i2c((uint16)x,COB15_CTRL) +#define nomadik_epio_write_keypad(x) nomadik_epio_write_i2c((uint16)x,KEYPAD_DATA) +#define nomadik_epio_write_msp_conf(x) nomadik_epio_write_i2c((uint16)x,MSP_CONF) +#define nomadik_epio_write_uart_conf(x) nomadik_epio_write_i2c((uint16)x,UART_CONF) +#define nomadik_epio_write_ssp_conf(x) nomadik_epio_write_i2c((uint16)x,SSP_CONF) +#define nomadik_epio_write_it_mngt(x) nomadik_epio_write_i2c((u16)x,IT_MNGT) +#define nomadik_epio_write_aux_gpo1(x) nomadik_epio_write_i2c((u16)x,AUX_GPO1) +#define nomadik_epio_write_aux_gpi1(x) nomadik_epio_write_i2c((u16)x,AUX_GPI1) + +/*CPLD Version abstraction constants */ +#define COB_REV_BITS 0x7000 /*numeric field */ +#define COB_REV_BITS_POS 12 /*need to roate this much times */ +#define COB_REV_SUBBITS 0x0000 /*decimal field */ +#define COB_REV_SUBBITS_POS 0 /*need to roate this much times */ +#define CPLD_REV_BITS 0x0FF0 /*numeric field */ +#define CPLD_REV_BITS_POS 4 /*need to roate this much times */ +#define CPLD_REV_SUBBITS 0x000F /*decimal field */ + +/* Bits defination for NDK15_CTRL (COB_CTRL) register */ +#define DBG_TOOLS 0x0004 /*(1)enable debug tools (TODO) */ +#define BIOS_TCHSCR 0x0002 /*(1)touch screen selected */ +#define USER_LED0 0x0001 /*(1)user led0 on */ + +/* Bits defination for MSP_CONF register */ +#define MD_MSP0 0x1000 /*(1) Enable the MSP0 link between Nomadik and peripheral in expansion connector */ +#define MD_MSP1 0x1400 /*(1) Enable the MSP1 link between Nomadik and peripheral in expansion connector */ +#define MD_MSP2 0x1800 /*(1) Enable the MSP2 link between Nomadik and peripheral in expansion connector */ +#define CDC_MSP0 0x0200 /*(1) Enable the MSP0 link between Nomadik and Audio codec */ +#define CDC_MSP1 0x0280 /*(1) Enable the MSP1 link between Nomadik and Audio codec */ +#define CDC_MSP2 0x0300 /*(1) Enable the MSP2 link between Nomadik and Audio codec */ +#define SDIO 0x0040 /*(1)Enable SDIO link between Nomadik and WLAN */ +#define WLAN_MSP0 0x0020 /*(1) Enable the MSP0 link between Nomadik and WLAN */ +#define WLAN_MSP1 0x0028 /*(1) Enable the MSP1 link between Nomadik and WLAN */ +#define WLAN_MSP2 0x0030 /*(1) Enable the MSP2 link between Nomadik and WLAN */ +#define BT_MSP0 0x0004 /*(1) Enable the MSP0 link between Nomadik and Bluetooth */ +#define BT_MSP1 0x0005 /*(1) Enable the MSP1 link between Nomadik and Bluetooth */ +#define BT_MSP2 0x0006 /*(1) Enable the MSP2 link between Nomadik and Bluetooth */ + +/* Bits defination for UART_CONF register */ +#define DBG_UART0 0x0100 /*(1) Enable the UART0 link for the debug RS232 connector */ +#define DBG_UART1 0x0140 /*(1) Enable the UART1 link for the debug RS232 connector */ +#define DBG_UART2 0x0180 /*(1) Enable the UART2 link for the debug RS232 connector */ +#define MD_UART0 0x0020 /*(1) Enable the UART0 link for peripheral in expansion connector (ModemÂ…) */ +#define MD_UART1 0x0028 /*(1) Enable the UART1 link for peripheral in expansion connector (ModemÂ…) */ +#define MD_UART2 0x0030 /*(1) Enable the UART2 link for peripheral in expansion connector (ModemÂ…) */ +#define BT_UART0 0x0004 /*(1) Enable the UART0 link between Nomadik and Bluetooth */ +#define BT_UART1 0x0005 /*(1) Enable the UART1 link between Nomadik and Bluetooth */ +#define BT_UART2 0x0006 /*(1) Enable the UART2 link between Nomadik and Bluetooth */ + +/* Bits defination for SSP_CONF register */ +#define EXP_MSP0 0x0008 /*(1) Enable the MSP0 link between Nomadik and EXP_SSP */ +#define EXP_MSP1 0x0009 /*(1) Enable the MSP1 link between Nomadik and EXP_SSP */ +#define EXP_MSP2 0x000A /*(1) Enable the MSP2 link between Nomadik and EXP_SSP */ +#define EXP_SSP 0x000C /*(1) Enable the SSP link between Nomadik and EXP_SSP */ + +/* Bits defination for IT_MNGT register */ +#define KEYP_MSK 0x8000 /*(1) Mask for the keypad press/release detection */ +#define KEYP_INV 0x4000 /*(1) Select the polarity of the keypad detection to generate an IT for key press and release */ +#define BTW_INV 0x2000 /*(1) Select the polarity of the BTWLAN_REQCLK signal for the interrupt generation */ + +#define EGP_MSK 0x0200 /*(1) Mask for the external expansion GPIO interruption */ +#define TVIT_MSK 0x0100 /*(1) Mask for the TVOUT interruption */ +#define LAN_MSK 0x0080 /*(1) Mask for the Ethernet controller interruption */ +#define CDC_MSK 0x0040 /*(1) Mask for the Codec interruption */ +#define FMIT_MSK 0x0020 /*(1) Mask for the FM radio interruption */ +#define TSIT_MSK 0x0010 /*(1) Mask for the TCHSCR_PENIRQn interruption */ +#define BBIT_MSK 0x0008 /*(1) Mask for the BB-DVBH_INT interruption */ +#define WIRQ_MSK 0x0004 /*(1) Mask for the WLAN_IRQ_SDIO_DAT1 interruption */ +#define RCK_MSK 0x0002 /*(1) Mask for the BTWLAN_REQCLK input signal */ +#define BTHW_MSK 0x0001 /*(1) Mask for the BT_HOST_WAKEUP input signal */ + +/* Bits defination for AUX_GPO1 register */ +#define CMD_VIBR 0x8000 /*(active high) vibrator is powered. */ +#define CDC_CKEN 0x4000 /*(active high) enable the clock 19.2MHz for the Audio codec. */ +#define LAN_RST 0x2000 /*(active high) reset the Ethernet controller. */ +#define DVB_RST 0x1000 /*(active low) reset Modem/DVBH. */ +#define IRDA_SD 0x0800 /*(active high) shutdown the FIRDA controller. */ +#define BL_RST 0x0400 /*(active low) reset the backlight controller. */ +#define DISP2_RST 0x0200 /*(active low) reset sub-display. */ +#define DISP1_RST 0x0100 /*(active low) reset main display. */ +#define UHS_RST 0x0080 /*(active high) reset the high speed USB controller. */ +#define TVO_ECLK 0x0040 /*(active high) enable the clock generation for IMAGIK chip. */ +#define TVO_POR 0x0020 /*(active low) reset the IMAGIK chip. */ +#define TVO_SUSP 0x0010 /*(active low) suspend the video treatment of IMAGIK chip. */ +#define FM_RST 0x0008 /*(active high) reset FM radio. */ +#define WLN_PW 0x0004 /*(active high) enable WLAN. */ +#define BT_RST 0x0002 /*(active low) reset the BT controller. */ +#define BT_WK 0x0001 /*(active high) wakeup BT controller. */ + +/* Bits defination for AUX_GPI1 register */ +#define KEY_PRE 0x8000 /*A key on the keypad is pressed (when 0) */ +#define EXPGPIO_IT 0x0200 /*(active low) Interruption signal from external expansion GPIO controller. */ +#define TVOUT_IT 0x0100 /*(active high) Interruption signal from IMAGIK (reserved for future version). */ +#define LAN3V_INT 0x0080 /*(active high) Interruption signal from Ethernet controller. */ +#define CDC_IT 0x0040 /*(active low) Interruption signal from audio codec. */ +#define FM_INT 0x0020 /*(active low) Interruption signal from FM radio. */ +#define TCHSCR_PENIRQ 0x0010 /*(active low) Interruption signal from touchscreen controller. */ +#define BB_DVBH_INT 0x0008 /*(active high) Interruption signal from modem or DVBH on expansion connector. */ +#define WLAN_IRQ_SDIO_DAT1 0x0004 /*(active high) Interruption signal from WLAN when used with the SPI + interface. */ +#define BTWLAN_REQCLK 0x0002 /*(active high) Request Nomadik CLKOUT1. */ +#define BT_HOST_WAKEUP 0x0001 /*(active high) allows the Nomadik wakeup by the BT controller. */ + +#endif /*__ASSEMBLY__*/ +#endif /*__ASM_ARM_ARCH_NDK15_DEVICES_H*/ --- /dev/null +++ linux-2.6.20/include/asm-arm/arch-nomadik/ndk15c02_devices.h @@ -0,0 +1,169 @@ +/* + * linux/include/asm-arm/arch-nomadik/ndk15c02_devices.h + * + * Copyright (C) STMicroelectronics + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#ifndef __ASM_ARM_ARCH_NDK15C02_DEVICES_H +#define __ASM_ARM_ARCH_NDK15C02_DEVICES_H +#ifndef __ASSEMBLY__ + +#include + +/* + * Macros board specific + */ +#define BOARD_IO_DESC /*nothing to define */ + +/* Ethernet related board specific declaration*************************/ +#define NOMADIK_ETH0_BASE 0x33000000 /* ETH0 Base */ +#define SMC91111_IRQ GPIO_PIN_106 + +/* MMC related board specific declaration*************************/ +#define MMCDETECT_IRQ GPIO_PIN_119 +#define val_volt 7 /*Value to be written at Touareg register */ + +/* Touchpanel related declaration************************************/ +#define TOUCHP_IRQ GPIO_PIN_104 /* PENIRQNO: through CPLD_IT */ +/*#define TOUCHP_CS0 NOT_KNOWN * Chip select pin0 */ +/*#define TOUCHP_CS1 NOT_KNOWN * Chip select pin1 */ +#define X_DELTA_MAX 2* 10 /*Max ADC read error limit for Sub- */ +#define Y_DELTA_MAX 2 *16 /*sequent redings */ +#define MAX_12BIT ((1<<12)-1) +#define X_CORR(x, y) (x) +#define Y_CORR(x, y) (MAX_12BIT - y) + +/* Keypad related declaration************************************/ +#define KEYPAD_IRQ GPIO_PIN_113 +#define MAX_KPROW 8 +#define MAX_KPCOL 8 + +/* I2c related board specific declaration************************/ +#define I2C_CLIENT_BUSID13 0 +#define I2C_TOUAREG_ADAPTER 1 +#define I2C_TOUREG_CLIENT_BUSID 0 +#define I2C_CPLD_CLIENT_BUSID 0 +/* Addresses for clients on this board*/ +#define I2C_ADDR_MB 0x50 /* Motherboard*/ +#define I2C_ADDR_UI_DB 0x51 /* UI Daughterboard*/ +#define I2C_ADDR_IO_DB1 0x52 /* I/O Expansion daughter board 1*/ +#define I2C_ADDR_IO_DB2 0x53 /* I/O Expansion daughter board 2*/ +#define I2C_ADDR_CIF_CAM 0x54 /* CCIR-656 ST CIF Camera (Matisse)*/ +#define I2C_ADDR_PP_CAM (0x08>>1) /* pepperpot camera */ +#define I2C_ADDR_MEM_EXP 0x55 /* CCIR-656 ST CIF Camera (Matisse)*/ +#define I2C_ADDR_AC 0x1A /* Audio codec STw5095*/ +#define I2C_ADDR_FM_TUNER 0x62 /* FM Tuner (TDA 7701-Brite)*/ +#define I2C_ADDR_GAS_GAUGE 0x22 /* Gas Gauge (PB700)*/ +#define I2C_ADDR_CAM_MOD 0x45 /* LITEA Camera Module ?*/ +#define I2C0_LP_OWNADDR 0x50 +#define I2C1_LP_OWNADDR 0x60 +#define I2C_ADDR_TOUAREG 0x2D +#define I2C_ADDR_CPLD 0x1C /* actual 0x38 and 0x39, considered only 7 msbs */ +#define I2C_ADDR_DENC 0x20 + +/* MSP related board specific declaration************************/ +#define MSP_DATA_DELAY MSP_DELAY_0 +#define MSP_TX_CLOCK_EDGE MSP_FALLING_EDGE +#define MSP_RX_CLOCK_EDGE MSP_FALLING_EDGE + +/*NORflash related board specific declaration*******************/ +#define NMDK_FLASH_BASE 0x30000000 +#define NMDK_FLASH_WINDOW_SIZE 32 * 1024 * 1024 +#define NMDK_FLASH_BUSWIDTH 2 + +#define GET_BANK_WIDTH(val,phys) \ + switch (phys) { \ + case NMDK_FLASH_BASE: \ + val = NMDK_FLASH_BUSWIDTH;\ + break;\ + default:\ + break;\ + } + +/*NANDflash related board specific declaration*******************/ +#define BOARD_SET_NAND_DATA \ + nand_oob->eccbytes = 12; \ + nand_oob->eccpos[0] = 2; \ + nand_oob->eccpos[1] = 3; \ + nand_oob->eccpos[2] = 4; \ + nand_oob->eccpos[3] = 18; \ + nand_oob->eccpos[4] = 19; \ + nand_oob->eccpos[5] = 20; \ + nand_oob->eccpos[6] = 34; \ + nand_oob->eccpos[7] = 35; \ + nand_oob->eccpos[8] = 36; \ + nand_oob->eccpos[9] = 50; \ + nand_oob->eccpos[10] = 51; \ + nand_oob->eccpos[11] = 52; \ + this->badblockpos = 5; + +#define BOARD_SET_NAND_BADBLOCK \ + this->eccsteps = 4; \ + this->badblockpos = 5; + +/*SVA related board specific declaration*******************/ +#define SVA_HCL_INIT_MEM_SIZE SZ_4M + +/* CPLD/EPIO related declaration************************************/ +/* the below defination is w.r.to CPLD version 3.0.1.2 */ +#define NOMADIK_CPLD_BASE 0x36000000 /* CPLD base */ + +#define COB15_ID 0x00 /* offsets for cpld board registers */ +#define COB15_CTRL 0x02 +#define KEYPAD_DATA 0x04 +#define MSP_CONF 0x06 +#define UART_CONF 0x08 +#define SSP_CONF 0x0A +#define AUX_GPO1 0x20 +#define AUX_GPO2 0x22 + +extern u16 nomadik_epio_read_i2c(int reg); +extern int nomadik_epio_write_i2c(u16 data, int reg); +#define nomadik_epio_read_cob_id() nomadik_epio_read_i2c(COB15_ID) +#define nomadik_epio_read_cob_ctl() nomadik_epio_read_i2c(COB15_CTRL) +#define nomadik_epio_read_keypad() nomadik_epio_read_i2c(KEYPAD_DATA) +#define nomadik_epio_read_msp_conf() nomadik_epio_read_i2c(MSP_CONF) +#define nomadik_epio_read_uart_conf() nomadik_epio_read_i2c(UART_CONF) +#define nomadik_epio_read_ssp_conf() nomadik_epio_read_i2c(SSP_CONF) +#define nomadik_epio_read_aux_gpo1() nomadik_epio_read_i2c(AUX_GPO1) +#define nomadik_epio_read_aux_gpo2() nomadik_epio_read_i2c(AUX_GPO2) +#define nomadik_epio_write_cob_ctl(x) nomadik_epio_write_i2c((uint16)x,COB15_CTRL) +#define nomadik_epio_write_keypad(x) nomadik_epio_write_i2c((uint16)x,KEYPAD_DATA) +#define nomadik_epio_write_msp_conf(x) nomadik_epio_write_i2c((uint16)x,MSP_CONF) +#define nomadik_epio_write_uart_conf(x) nomadik_epio_write_i2c((uint16)x,UART_CONF) +#define nomadik_epio_write_ssp_conf(x) nomadik_epio_write_i2c((uint16)x,SSP_CONF) +#define nomadik_epio_write_aux_gpo1(x) nomadik_epio_write_i2c((uint16)x,AUX_GPO1) +#define nomadik_epio_write_aux_gpo2(x) nomadik_epio_write_i2c((uint16)x,AUX_GPO2) + +/*CPLD Version abstraction constants */ +#define COB_REV_BITS 0x7000 /*numeric field */ +#define COB_REV_BITS_POS 12 /*need to roate this much times */ +#define COB_REV_SUBBITS 0x0000 /*decimal field */ +#define COB_REV_SUBBITS_POS 0 /*need to roate this much times */ +#define CPLD_REV_BITS 0x0FF0 /*numeric field */ +#define CPLD_REV_BITS_POS 4 /*need to roate this much times */ +#define CPLD_REV_SUBBITS 0x000F /*decimal field */ + +/* Bits defination for NDK15_CTRL (COB_CTRL) register */ +#define CPLD_GPIO34 0x0200 /*(1)CPLD sent CC_PWRDETECTn */ +#define BT_WAKEUP_GPO1 0x0100 /*(1)from AUX_GPO1 CPLD register, bit (0)*/ +#define DEEPSLEEP_CLK_GPIO106 0x00c0 /*(00)from Nomadik GPIO106 */ +#define DEEPSLEEP_CLK_GPIO49 0x0040 /*(01)from Nomadik GPIO49 */ +#define DEEPSLEEP_CLK_GPO1 0x00c0 /*(11)from AUX_GPO1 CPLD register, bit (14)*/ +#define GPIO106_LAN_IT 0x0030 /*(00) fron ethernet controller*/ +#define GPIO106_PWRDET 0x0010 /*(01) fron CC_PWRDETECTn(Charge controller)*/ +#define GPIO106_PM_ITWK 0x0020 /*(10) fron PM_IT_WKUP(Touareg USB insertion)*/ +#define GPIO106_DIS 0x0030 /*(11) High Z*/ +#define HPI_GPIO_DIS 0x000c /*(11) selection for HPI_GPIO disabled*/ +#define BIOS_TCHSCR 0x0002 +#define USER_LED0 0x0001 /*(1)user led0 on */ + +/* Bits defination for UART_CONF register */ +#define DBG_UART4W 0x0200 /*(1) select 4 number of wires on the UART interface*/ +#define DBG_UART0 0x0400 /*(1X00) Enable the UART0 link for the debug RS232 connector */ +#define DBG_UART1 0x0480 /*(1X01) Enable the UART1 link for the debug RS232 connector */ +#define DBG_UART2 0x0580 /*(1X11) Enable the UART2 link for the debug RS232 connector */ +#define MD_UART0 0x0040 /*(1X00) Enable the UART0 link for peripheral in expansion connector (Modem \ No newline at end of file --- /dev/null +++ linux-2.6.20/include/asm-arm/arch-nomadik/nhk15_devices.h @@ -0,0 +1,131 @@ +/* + * linux/include/asm-arm/arch-nomadik/nhk15_devices.h + * + * Copyright (C) STMicroelectronics + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#ifndef __ASM_ARM_ARCH_NHK15_DEVICES_H +#define __ASM_ARM_ARCH_NHK15_DEVICES_H +#ifndef __ASSEMBLY__ + +#include +/* + * Macros board specific + */ +#define BOARD_IO_DESC /*nothing to define */ + +/* Ethernet related board specific declaration*/ +#define NOMADIK_ETH0_BASE 0x34000000 /* ETH0 Base */ +#define SMC91111_IRQ GPIO_PIN_115 /* thro' port expander0*/ + +/* MMC related board specific declaration*/ +#define MMCDETECT_IRQ GPIO_PIN_49 /*EGPIO_PIN_7*/ /*through port expander1*/ +#define val_volt 7 /*Value to be written at Touareg register */ + +/* Touchpanel related declaration*/ +#define TOUCHP_IRQ EGPIO_PIN_6 /* PENIRQNO: through port expander1 */ +#define X_DELTA_MAX 2* 10 /*Max ADC read error limit for Sub- */ +#define Y_DELTA_MAX 2 *16 /*sequent redings */ + +/* Keypad related declaration*/ +#define KEYPAD_IRQ /*TBD*/ +#define MAX_KPROW 8 +#define MAX_KPCOL 8 + +/* I2c related board specific declaration*/ +#define I2C_CLIENT_BUSID13 0 +#define I2C_TOUAREG_ADAPTER 1 +#define I2C_TOUREG_CLIENT_BUSID 0 + +/* Addresses for clients on this board*/ +#define I2C_ADDR_DENC 0x21 /*0x42*/ +#define I2C_ADDR_AC 0x1A /*0x34 Audio codec STw5095*/ +#define I2C_ADDR_FM_TUNER 0x10 /*0x20 FM Tuner (STLC2590)*/ +#define I2C_ADDR_CAM_MOD 0x00 /*LITEA Camera Module ????? */ +#define I2C_ADDR_MEMS 0x1D /*0x3A */ +#define I2C_ADDR_SIM 0x22 /*0x44 0x46 */ +#define I2C_ADDR_TOUCH 0x48 /*0x90*/ +#define I2C_ADDR_STMPE0 0x43 /*0x86*/ +#define I2C_ADDR_STMPE1 0x44 /*0x88*/ +#define I2C_ADDR_GAS_GAUGE 0x70 /*0xE0 Gas Gauge (STw4102)*/ +#define I2C0_LP_OWNADDR 0x50 +#define I2C1_LP_OWNADDR 0x60 +#define I2C_ADDR_POWER 0x2D /*0x5A*/ + +/* MSP related board specific declaration*/ +#define MSP_DATA_DELAY MSP_DELAY_0 +#ifdef CONFIG_DA_MASTER +#define MSP_TX_CLOCK_EDGE MSP_RISING_EDGE +#else +#define MSP_TX_CLOCK_EDGE MSP_FALLING_EDGE +#endif +#define MSP_RX_CLOCK_EDGE MSP_FALLING_EDGE + +/*NORflash related board specific declaration*/ +#define NMDK_FLASH_BASE 0x30000000 +#define NMDK_FLASH_WINDOW_SIZE 32 * 1024 * 1024 +#define NMDK_FLASH_BUSWIDTH 2 + +#define GET_BANK_WIDTH(val,phys) \ + switch (phys) { \ + case NMDK_FLASH_BASE: \ + val = NMDK_FLASH_BUSWIDTH;\ + break;\ + default:\ + break;\ + } + +/*NANDflash related board specific declaration*/ +#define BOARD_SET_NAND_DATA \ + nand_oob->eccbytes = 12; \ + nand_oob->eccpos[0] = 2; \ + nand_oob->eccpos[1] = 3; \ + nand_oob->eccpos[2] = 4; \ + nand_oob->eccpos[3] = 18; \ + nand_oob->eccpos[4] = 19; \ + nand_oob->eccpos[5] = 20; \ + nand_oob->eccpos[6] = 34; \ + nand_oob->eccpos[7] = 35; \ + nand_oob->eccpos[8] = 36; \ + nand_oob->eccpos[9] = 50; \ + nand_oob->eccpos[10] = 51; \ + nand_oob->eccpos[11] = 52; \ + this->badblockpos = 5; + +#define BOARD_SET_NAND_BADBLOCK \ + this->eccsteps = 4; \ + this->badblockpos = 5; + +/*SVA related board specific declaration*/ +#define SVA_HCL_INIT_MEM_SIZE SZ_8M + +/* SAA related board specific declaration*/ +#define SAA_HCL_INIT_MEM_SIZE SZ_4M + +/* Static memort allocations for SAA,SVA and OPENGL */ +#define NOMADIK_MM_STATIC_MEM 1 + +#ifdef NOMADIK_MM_STATIC_MEM +#define NOMADIK_SAA_BASE 0x09A00000 // Base address(0x09A00000) for SAA +#define NOMADIK_SAA_SIZE 0x0600000 +#define NOMADIK_SAA_END (NOMADIK_SAA_BASE + NOMADIK_SAA_SIZE - 1) + +#define NOMADIK_SVA_BASE (NOMADIK_SAA_BASE + NOMADIK_SAA_SIZE) // Base address(0x0A000000) for SVA +#define NOMADIK_SVA_SIZE 0x01200000 +#define NOMADIK_SVA_END (NOMADIK_SVA_BASE + NOMADIK_SVA_SIZE - 1) + +#define NOMADIK_OGL_BASE (NOMADIK_SVA_BASE ) // Base address(0x0A000000) for OpenGL +#define NOMADIK_OGL_SIZE 0x02000000 //size(32MB) of the memory for command fifo + SGA batches + drv memory + draw buffer + fw program + SIZE_DAT24_ZON1 +#define NOMADIK_OGL_END (NOMADIK_OGL_BASE + NOMADIK_OGL_SIZE - 1) +#endif + +#ifdef CONFIG_NOMADIK_SAA_INIT_MEM +dma_addr_t saa_get_physical_address(void); +void* saa_get_logical_address(void); +#endif + +#endif /*__ASSEMBLY__*/ +#endif /*__ASM_ARM_ARCH_NHK15_DEVICES_H*/ --- /dev/null +++ linux-2.6.20/include/asm-arm/arch-nomadik/param.h @@ -0,0 +1,19 @@ +/* + * linux/include/asm-arm/arch-nomadik/param.h + * + * Copyright (C) 1999 ARM Limited + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ --- /dev/null +++ linux-2.6.20/include/asm-arm/arch-nomadik/pexp.h @@ -0,0 +1,355 @@ +/* + * linux/include/asm-arm/arch-nomadik/pexp.h + * + * Copyright (C) STMicroelectronics + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#ifndef __NHK15_PEXP_H +#define __NHK15_PEXP_H +#define PUBLIC + +#include + +#define STMPE_MINOR 21 + +/* IOCTL definitions */ +#define STMPE_IOC_MAGIC 's' +#define STMPE_SET_BACKLIGHT _IOW(STMPE_IOC_MAGIC, 90, int) +#define STMPE_AMP_STAND_BY _IOW(STMPE_IOC_MAGIC, 91, int) +#define STMPE_GG_STAND_BY _IOW(STMPE_IOC_MAGIC, 92, int) /*Gas gauge STw4102 stand by*/ +#define STMPE_GPS_ENABLE _IOW(STMPE_IOC_MAGIC, 93, int) + +#define MAX_STMPE2401_DEVICE 4 /*max number of STMPE2401 device allowed*/ +#define STMPE0 0 +#define STMPE1 1 +#define STMPE2 2 +#define STMPE3 3 + +/*Gpio related define*/ +#define MAX_STMPE2401_GPIO 24 /*max number of STMPE2401 gpio allowed*/ + +#define STMPE2401_GPIO_IN 0 /*directions*/ +#define STMPE2401_GPIO_OUT 1 + +#define STMPE2401_NO_EDGE 0 /*edge setting*/ +#define STMPE2401_FALL_EDGE 1 +#define STMPE2401_RISE_EDGE 2 +#define STMPE2401_BOTH_EDGE 3 + +#define STMPE2401_FLOATING 0 /*pull-up, pull-down*/ +#define STMPE2401_PULL_UP 1 +#define STMPE2401_PULL_DOWN 2 + +#define STMPE2401_PRIMARY_FUNCTION 0 /*alternate functions*/ +#define STMPE2401_ALT_FUNCTION_1 1 +#define STMPE2401_ALT_FUNCTION_2 2 +#define STMPE2401_ALT_FUNCTION_3 3 + + +/*Interrupt related define*/ +#define MAX_STMPE2401_CALLBACK 32 /*24 gpio + 8 other source*/ +#define MAX_STMPE2401_RUNTIME_ERROR 32 /*TBD*/ + +#define STMPE2401_GPIO_IRQ(n) (n) /*ISR bit 8 ISGPIOR bit 0 to 23 ,highest priority (0 to 23)*/ +#define STMPE2401_WAKEUP_IRQ 24 /*ISR bit 0*/ +#define STMPE2401_KEYPAD_IRQ 25 /*ISR bit 1*/ +#define STMPE2401_KEYPAD_OVERFLOW_IRQ 26 /*ISR bit 2,lowest priority*/ +#define STMPE2401_ROTATOR_IRQ 27 /*NOT_SUPPORTED in this version*/ +#define STMPE2401_ROTATOR_OVERFLOW_IRQ 28 /*NOT_SUPPORTED in this version*/ +#define STMPE2401_PWM0_IRQ 29 /*NOT_SUPPORTED in this version*/ +#define STMPE2401_PWM1_IRQ 30 /*NOT_SUPPORTED in this version*/ +#define STMPE2401_PWM2_IRQ 31 /*NOT_SUPPORTED in this version*/ + +#define STMPE2401_ENABLE_INTERRUPT 1 +#define STMPE2401_DISABLE_INTERRUPT 0 + +/*Pwm related define*/ +#define STMPE2401_PWM1 0x01 +#define STMPE2401_PWM2 0x02 +#define STMPE2401_PWM3 0x04 + +#define STMPE2401_PWM1_GPIO EGPIO_PIN_21 +#define STMPE2401_PWM2_GPIO EGPIO_PIN_22 +#define STMPE2401_PWM3_GPIO EGPIO_PIN_23 + +/*keypad related define*/ +#define STMPE2401_SCAN_ON 1 +#define STMPE2401_SCAN_OFF 0 + +#define STMPE2401_MASK_NO_KEY 0x78 /*row=15*/ + +#define STMPE2401_KEY(col,row) (col + (row << 3)) /*macro for key definition*/ + +/* + * Pin description To be used in SOFTWARE mode: refers to a pin. + */ +typedef enum { + EGPIO_PIN_0, + EGPIO_PIN_1, + EGPIO_PIN_2, + EGPIO_PIN_3, + EGPIO_PIN_4, + EGPIO_PIN_5, + EGPIO_PIN_6, + EGPIO_PIN_7, + EGPIO_PIN_8, + EGPIO_PIN_9, + EGPIO_PIN_10, + EGPIO_PIN_11, + EGPIO_PIN_12, + EGPIO_PIN_13, + EGPIO_PIN_14, + EGPIO_PIN_15, + EGPIO_PIN_16, + EGPIO_PIN_17, + EGPIO_PIN_18, + EGPIO_PIN_19, + EGPIO_PIN_20, + EGPIO_PIN_21, + EGPIO_PIN_22, + EGPIO_PIN_23 +} egpio_pin; + +/* STMPE Platform init*/ +struct nomadik_stmpe_platform_data { + int (*init) (void); + int (*exit) (void); +}; + +/*register configuration for GPIO*/ +typedef struct +{ + /*unsigned long Input_Monitor;*/ + unsigned long Output_State; + unsigned long Direction; + unsigned long EdgeDetect; + unsigned long RisingEdge; + unsigned long FallingEdge; + unsigned long PullUp; + unsigned long PullDown; + unsigned long AltFunctionUpper; + unsigned long AltFunctionLower; + +}t_STMPE2401_gpio_config; + + +/*interrupt settings*/ +typedef struct +{ + gpio_pin NdkPin; + gpio_config NdkPinConfig; + + void (*Callback[MAX_STMPE2401_CALLBACK])(void *parameter); + void *CallbackParam[MAX_STMPE2401_CALLBACK]; + + unsigned short ControlReg; + unsigned short EnableReg; + unsigned long GpioMaskReg; + +}t_STMPE2401_interrupt_config; + + +/*pwm settings*/ +typedef struct +{ + unsigned char ControlRegister; + unsigned char PwmValue; + +}t_STMPE2401_pwm_config; + + +/*Keypad configuration*/ +typedef struct +{ + unsigned short columns; //bit-field , 1=column used, 0=column not used + unsigned short rows; //bit-field , 1=row used, 0=row not used + unsigned char nCycles; //number of cycles for key data updating + unsigned char debounce; //de-bounce time (0-128)ms + unsigned char scan; //scan status, ON or OFF + +}t_STMPE2401_key_config; + +typedef struct +{ + unsigned char buttonPressed; //number of button pressed + unsigned char button[2]; //id of buttons, 0 to 77 + unsigned char buttonReleased; //number of button released + unsigned char released[2]; //id of buttons released, 0 to 77 + +}t_STMPE2401_key_status; + +/*general configuration*/ +typedef struct +{ + unsigned short i2c_ID; + unsigned short i2c_address; + unsigned char Syscon; + + t_STMPE2401_gpio_config Gpio; //gpio config + t_STMPE2401_interrupt_config Interrupt; + t_STMPE2401_pwm_config Pwm; + t_STMPE2401_key_config Key; + +} t_STMPE2401_device_config; + +/*general device info*/ +typedef struct +{ + unsigned char chip_ID; + unsigned char version_ID; + +} t_STMPE2401_info; + +typedef struct +{ + unsigned char syscon_data; + +} t_stmpe2401_syscon_ds; + +typedef struct +{ + /*ICR register info*/ + unsigned char icr_msb_data; + unsigned char icr_lsb_data; + + /*IER register info*/ + unsigned char ier_msb_data; + unsigned char ier_lsb_data; + + /*ISR register info*/ + unsigned char isr_msb_data; + unsigned char isr_lsb_data; + + /*IEGPIOR register info*/ + unsigned char iegpior_msb_data; + unsigned char iegpior_csb_data; + unsigned char iegpior_lsb_data; + + /*ISGPIOR register info*/ + unsigned char isgpior_msb_data; + unsigned char isgpior_csb_data; + unsigned char isgpior_lsb_data; + +} t_stmpe2401_interrupt_ds; + +typedef struct +{ + unsigned char pwmcs_data; + unsigned char pwmic0_data; + unsigned char pwmic1_data; + unsigned char pwmic2_data; + +} t_stmpe2401_pwm_ds; + +typedef struct +{ + unsigned char kpc_col_data; + unsigned char kpc_row_msb_data; + unsigned char kpc_row_lsb_data; + unsigned char kpc_ctrl_msb_data; + unsigned char kpc_ctrl_lsb_data; + unsigned char kpc_data_byte0_data; + unsigned char kpc_data_byte1_data; + unsigned char kpc_data_byte2_data; + +}t_stmpe2401_kpc_ds; + +typedef struct +{ + unsigned char gpmr_msb_data; + unsigned char gpmr_csb_data; + unsigned char gpmr_lsb_data; + + unsigned char gpsr_msb_data; + unsigned char gpsr_csb_data; + unsigned char gpsr_lsb_data; + + unsigned char gpcr_msb_data; + unsigned char gpcr_csb_data; + unsigned char gpcr_lsb_data; + + unsigned char gpdr_msb_data; + unsigned char gpdr_csb_data; + unsigned char gpdr_lsb_data; + + unsigned char gpedr_msb_data; + unsigned char gpedr_csb_data; + unsigned char gpedr_lsb_data; + + unsigned char gprer_msb_data; + unsigned char gprer_csb_data; + unsigned char gprer_lsb_data; + + unsigned char gpfer_msb_data; + unsigned char gpfer_csb_data; + unsigned char gpfer_lsb_data; + + unsigned char gppur_msb_data; + unsigned char gppur_csb_data; + unsigned char gppur_lsb_data; + + unsigned char gppdr_msb_data; + unsigned char gppdr_csb_data; + unsigned char gppdr_lsb_data; +// GPIO Alternate Function register + unsigned char gpafr_u_msb_data; + unsigned char gpafr_u_csb_data; + unsigned char gpafr_u_lsb_data; + + unsigned char gpafr_l_msb_data; + unsigned char gpafr_l_csb_data; + unsigned char gpafr_l_lsb_data; + +}t_stmpe2401_gpio_ds; +typedef enum +{ +STMPE2401_OK = 0, +STMPE2401_BAD_PARAMETER = -2, +STMPE2401_FEAT_NOT_SUPPORTED = -3, +STMPE2401_INTERNAL_ERROR = -4, +STMPE2401_TIMEOUT_ERROR = -5, +STMPE2401_INITIALIZATION_ERROR = -6, +STMPE2401_I2C_ERROR = -7, +STMPE2401_ERROR = -8 +} t_STMPE2401_error; + +/*Device initialization functions*/ +PUBLIC t_STMPE2401_error STMPE2401_Init(unsigned char stmpeId); +/*Device info*/ +PUBLIC t_STMPE2401_error STMPE2401_Info(unsigned char stmpeId, t_STMPE2401_info *info ); + +/*GPIO related functions*/ +PUBLIC t_STMPE2401_error STMPE2401_Gpio_Configuration(unsigned char stmpeId, t_STMPE2401_gpio_config* config); +PUBLIC t_STMPE2401_error STMPE2401_Get_Gpio_Configuration(unsigned char stmpeId, t_STMPE2401_gpio_config* config); + +PUBLIC t_STMPE2401_error STMPE2401_SetGpioVal(unsigned char stmpeId, unsigned char PinIndex, unsigned char Value); +PUBLIC t_STMPE2401_error STMPE2401_GetGpioVal(unsigned char stmpeId, unsigned char PinIndex, unsigned char *Value); +PUBLIC t_STMPE2401_error STMPE2401_SetGpioDir(unsigned char stmpeId, unsigned char PinIndex, unsigned char Value); +PUBLIC t_STMPE2401_error STMPE2401_SetGpioEdgeDetect(unsigned char stmpeId, unsigned char PinIndex,unsigned char OffRiseFall ); +PUBLIC t_STMPE2401_error STMPE2401_GetGpioEdgeStatus(unsigned char stmpeId,unsigned long *status ); +PUBLIC t_STMPE2401_error STMPE2401_ClearGpioEdgeStatus(unsigned char stmpeId,unsigned long mask ); +PUBLIC t_STMPE2401_error STMPE2401_SetGpioPull(unsigned char stmpeId, unsigned char PinIndex, unsigned char OffUpDown ); +PUBLIC t_STMPE2401_error STMPE2401_SetGpioAltFunction(unsigned char stmpeId, unsigned char PinIndex, unsigned char Function ); + +/*Pwm related functions*/ +PUBLIC t_STMPE2401_error STMPE2401_PwmInit(unsigned char stmpeId, unsigned char channels); +PUBLIC t_STMPE2401_error STMPE2401_SetPwmIstructions(unsigned char stmpeId, unsigned char channel, unsigned short Istructions[],unsigned char len); +PUBLIC t_STMPE2401_error STMPE2401_SetPwm(unsigned char stmpeId, unsigned char channel, unsigned char Value); + +/*Interrupt related functions*/ +PUBLIC t_STMPE2401_error STMPE2401_Interrupt_Init(unsigned char stmpeId,gpio_pin NdkPin,gpio_config NdkPinConfig); +PUBLIC t_STMPE2401_error STMPE2401_Install_Callback(unsigned char stmpeId, unsigned char HwSource, void (*Callback)(void *parameter), void *CallbackParam); +PUBLIC t_STMPE2401_error STMPE2401_Remove_Callback(unsigned char stmpeId, unsigned char HwSource); +PUBLIC t_STMPE2401_error STMPE2401_InterruptSourceAbilitation(unsigned char stmpeId, unsigned char HwSource, unsigned char Abilitation ); +PUBLIC t_STMPE2401_error STMPE2401_InterruptAbilitation(unsigned char stmpeId, unsigned char Abilitation ); +PUBLIC t_STMPE2401_error STMPE2401_Acknowledge(unsigned char stmpeId, unsigned short irqSource, unsigned long irqGpioSource); +/*keypad related functions*/ +PUBLIC t_STMPE2401_error STMPE2401_Keypad_init(unsigned char stmpeId, t_STMPE2401_key_config Settings); +PUBLIC t_STMPE2401_error STMPE2401_Keypad_scan(unsigned char stmpeId, unsigned char status); +PUBLIC t_STMPE2401_error STMPE2401_Keypressed(unsigned char stmpeId, t_STMPE2401_key_status *keys); + +#endif + --- /dev/null +++ linux-2.6.20/include/asm-arm/arch-nomadik/power.h @@ -0,0 +1,180 @@ + +/* include/asm-arm/arch-nomadik/power.h + * + * Copyright 2004, STMicroelectronics, inc + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * $Id$ + */ + +#ifndef __INC_POWER_H +#define __INC_POWER_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * Undefine/UnComment NMDK_RTT_WAKEUP if wakeup from RTC + * Undefine/UnComment NMDK_RTC_WAKEUP if wakeup from RTT + * wakeup from that device + */ + + +#define NOMADIK_CPUFREQ_MAX 489600 +#define NOMADIK_CPUFREQ_MIN 19200 + +#define NOMADIK_CPUFREQ_TRANS_LATENCY 1000000 ; /* 1 ms, assumed */ + +/* Defines for Backup SRAM */ +#define BACKUP_MAGIC_NUMBER_DFS 0x59BE3A06 +#define BACKUP_MAGIC_NUMBER_DEEP_SLEEP 0x59BE3A06 +#define MAX_ADDRESS_DATA 112 +#define ACTION_WRITE 0x01 +#define ACTION_WRITE_AND 0x02 +#define ACTION_WRITE_OR 0x03 +#define ACTION_READ 0x04 +#define ACTION_POLL 0x05 +#define ACTION_POLL_AND 0x06 +#define ACTION_POLL_OR 0x07 +#define ACTION_WAIT 0x08 + +#define SOFT_SLEEP 0 +#define DEEP_SLEEP 1 + +#define VOLT_1_20 0xa9 +#define VOLT_1_22 0xab +#define VOLT_1_26 0xad +#define VOLT_1_28 0xb1 +#define VOLT_1_34 0xb7 +#define VOLT_1_36 0xb9 +#define VOLT_1_38 0xbb +#define VOLT_1_4 0xbd +#define VOLT_1_45 0xbf + +#define VOLT_1_20_MV 1200 +#define VOLT_1_22_MV 1220 +#define VOLT_1_26_MV 1260 +#define VOLT_1_28_MV 1280 +#define VOLT_1_34_MV 1340 +#define VOLT_1_36_MV 1360 +#define VOLT_1_38_MV 1380 +#define VOLT_1_4_MV 1400 +#define VOLT_1_45_MV 1450 + +typedef struct { + u32 sdmc_cr; /*SDMC control register (0x10110000 + 0x00) */ + u32 sdmc_dyrdcfr; /*Dynamic Read Configuration register (0x10110000 + 0x28) */ + u32 sdmc_dyref; /*Dynamic memory refresh timer (0x10110000 + 0x24) */ + u32 sdmc_gcfr; /*SDMC Global Configuration register (0x10110000 + 0x08 ) */ + u32 sdmc_dyrp; /*Dynamic memory precharge command period (tRP) (0x10110000 + 0x30) */ + u32 sdmc_dyras; /*Dynamic memory precharge period (tRAS) (0x10110000 + 0x34) */ + u32 sdmc_dysrex; /*Dynamic memory Self Refresh Exit time (tSREX) (0x10110000 + 0x38) */ + u32 sdmc_dywr; /*Dynamic memory write recovery time (tWR,tDPL, tRWL or tRDL) (0x10110000 + 0x44) */ + u32 sdmc_dyrc; /*Dynamic memory Active to Active command period= (tRC) (0x10110000 + 0x48) */ + u32 sdmc_dyrfc; /*Dynamic memory Autorefresh period and Autorefresh to Active command period (tRFC) (0x10110000 + 0x4C) */ + u32 sdmc_dyxsr; /*Dynamic memory Exit Self refresh to Active command time (tXSR) (0x10110000 + 0x50) */ + u32 sdmc_dyrrd; /*Dynamic memory Active bank A to Active bank B time (tRRD) (0x10110000 + 0x54) */ + u32 sdmc_dymrd; /*Dynamic memory load mode register to active command time (tMRD) (0x10110000 + 0x58) */ + u32 sdmc_dycdlr; /*Dynamic memory last data-in to new read/write command time (tCDLR) (0x10110000 + 0x5C) */ + u32 sdmc_dyrascas0; /*Dynamic memory RAS and CAS delay, chip select 0 (0x10110000 + 0x104) */ + u32 sdmc_dycfg0; /*Dynamic memory configuration register,chip select 0 (0x10110000 + 0x100) */ + u32 sdmc_dyrascas1; /*Dynamic memory RAS and CAS delay, chip select 1 (0x10110000 + 0x124) */ + u32 sdmc_dycfg1; /*Dynamic memory configuration register,chip select 1 (0x10110000 + 0x120) */ +} t_sdmc_config; + +typedef struct { + u32 freq; + u8 pll1_pdiv; + u8 pll1_nmul; + u8 hclkdiv; + u8 voltage; +} t_freq_config; + +typedef struct { + u32 value; + u32 volt_mv; +} t_volt_config; + +/* BackUp SDRAM structure */ +typedef struct { + /* reg_addr of the code statement where to return */ + u32 jump_addr; + /* Number as defined for the Wakeup boot up sequence */ + u32 magic; + /* reg_addr of the register where modifications needs to be done */ + u32 reg_addr[MAX_ADDRESS_DATA]; + /* data that needs to be written or read from the location */ + u32 data[MAX_ADDRESS_DATA]; + /* action to be taken - read/write */ + u8 action[MAX_ADDRESS_DATA]; + /* indicates the number of valid couple : (address,data,action) */ + u32 Size; +} t_backup_data; + +#ifdef CONFIG_CPU_FREQ_NOMADIK +extern void dfs(u8 pdiv, u8 nmul, u8 hclkdiv, u32 sram_base); +extern void nomadik_halt_memdma(void); +extern void nomadik_resume_memdma(void); + +#endif + +#ifdef CONFIG_NOMADIK_PM + +extern int nomadik_sleep(unsigned int sleep_mode, unsigned int *wakeup_reason); +extern void nomadik_wakeup_enable(void); +extern void nomadik_wakeup_disable(void); +extern void nomadik_deep_sleep(unsigned int sleep_mode, u32 sdram_base, + u32 backup_sram_start); +extern void nomadik_soft_sleep(void); +extern int g_nomadik_sleep_duration; +extern int g_nomadik_sleep_type; +extern int g_nomadik_wakeup_reason; + +extern void nomadik_slow_mode(void); +extern void nomadik_normal_mode(void); + +#endif + +#if defined(CONFIG_CPU_FREQ_NOMADIK) || defined(CONFIG_NOMADIK_PM) + +extern unsigned int nomadik_freq_to_voltage(unsigned int freq); +extern int g_nomadik_voltage; +extern int nomadik_resume_masters(void); +extern int nomadik_halt_masters(void); + +#endif + +#ifdef CONFIG_NOMADIK_PM +extern int nomadik_clock_enable(u32 ); +extern int nomadik_clock_disable(u32 ); +#else +#define nomadik_clock_enable(u32) do{}while(0) +#define nomadik_clock_disable(u32) do{}while(0) +#endif +#endif --- /dev/null +++ linux-2.6.20/include/asm-arm/arch-nomadik/smp.h @@ -0,0 +1,19 @@ +#ifndef ASMARM_ARCH_SMP_H +#define ASMARM_ARCH_SMP_H + +#include + +#include +#include + +#define hard_smp_processor_id() \ + ({ \ + unsigned int cpunum; \ + __asm__("mrc p15, 0, %0, c0, c0, 5" \ + : "=r" (cpunum)); \ + cpunum &= 0x0F; \ + }) + +extern void secondary_scan_irqs(void); + +#endif --- /dev/null +++ linux-2.6.20/include/asm-arm/arch-nomadik/spi.h @@ -0,0 +1,521 @@ +/* + * include/asm-arm/arch-nomadik/spi.h + * + * Copyright (C) 2006 STMicroelectronics Pvt. Ltd. + * + * Author: Sachin Verma + * + * Initial version inspired by: + * linux-2.6.17-rc3-mm1/include/asm-arm/arch-pxa/pxa2xx_spi.h + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + + +/* + * include/asm-arm/arch-nomadik/spi.h + * + * Copyright (C) 2006 STMicroelectronics Pvt. Ltd. + * + * Author: Sachin Verma + * + * Initial version inspired by: + * linux-2.6.17-rc3-mm1/include/asm-arm/arch-pxa/pxa2xx_spi.h + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _SPI_NMDK_H +#define _SPI_NMDK_H + +#include +#include +#include +#include +#include +#include + +#define SPI_WORKQUEUE +/***************************************************************************/ +typedef enum { + MSP_DATA_BITS_8 = 0x00, + MSP_DATA_BITS_10, + MSP_DATA_BITS_12, + MSP_DATA_BITS_14, + MSP_DATA_BITS_16, + MSP_DATA_BITS_20, + MSP_DATA_BITS_24, + MSP_DATA_BITS_32, +} t_msp_data_size; + +typedef enum { + MSP_INTERNAL_CLK = 0x0, /*48 MHz MSP internal clock */ + MSP_EXTERNAL_CLK, /*dedicated external clock source on MSPSCK pin */ +} t_msp_clk_src; + +typedef struct { + t_msp_clk_src clk_src; + uint16 sckdiv; /* value from 0 to 1023 */ + bool_t sckpol; /*Used only when MSPSCK clocks the sample rate generator (SCKSEL = 1Xb): + 0b: The rising edge of MSPSCK clocks the sample rate generator + 1b: The falling edge of MSPSCK clocks the sample rate generator */ +} t_msp_clock_params; + +/** + * SPI Clock Phase : clock phase (Motorola SPI interface only) + */ +typedef enum { + SPI_CLK_ZERO_CYCLE_DELAY = 0x0, /* Receive data on rising edge. */ + SPI_CLK_HALF_CYCLE_DELAY /* Receive data on falling edge. */ +} t_spi_clk_phase; + +/** + * SPI Clock Polarity : Clock polarity (Motorola SPI interface only) + */ +typedef enum { + SPI_CLK_POL_IDLE_LOW, /* Low inactive level */ + SPI_CLK_POL_IDLE_HIGH /* High inactive level */ +} t_spi_clk_pol; + +/***************************************************************************/ + +/** + * whether SSP is in loopback mode or not + */ +typedef enum { + LOOPBACK_DISABLED, + LOOPBACK_ENABLED +} t_spi_loopback; + +/** + * Interfaces allowed for this SSP Controller + * + * + */ +typedef enum { + SPI_INTERFACE_MOTOROLA_SPI, /* Motorola Interface */ + SPI_INTERFACE_TI_SYNC_SERIAL, /* Texas Instrument Synchronous Serial interface */ + SPI_INTERFACE_NATIONAL_MICROWIRE, /* National Semiconductor Microwire interface */ + SPI_INTERFACE_UNIDIRECTIONAL /* Unidirectional interface (STn8810&STn8815 only) */ +} t_spi_interface; + +/** + * Whether SSP is configured as Master or Slave + */ +typedef enum { + SPI_MASTER, + SPI_SLAVE +} t_spi_hierarchy; + +/** + * Clock parameters, to set SSP clock at a desired freq + */ +typedef struct { + uint8 cpsdvsr; /* value from 2 to 254 (even only!) */ + uint8 scr; /* value from 0 to 255 */ +} t_ssp_clock_params; + +/** + * Endianess of FIFO Data + */ +typedef enum { + SPI_FIFO_MSB, + SPI_FIFO_LSB +} t_spi_fifo_endian; + +/** + * Number of bits in one data element + */ +typedef enum { + SSP_DATA_BITS_4 = 0x03, SSP_DATA_BITS_5, SSP_DATA_BITS_6, + SSP_DATA_BITS_7, SSP_DATA_BITS_8, SSP_DATA_BITS_9, + SSP_DATA_BITS_10, SSP_DATA_BITS_11, SSP_DATA_BITS_12, + SSP_DATA_BITS_13, SSP_DATA_BITS_14, SSP_DATA_BITS_15, + SSP_DATA_BITS_16, SSP_DATA_BITS_17, SSP_DATA_BITS_18, + SSP_DATA_BITS_19, SSP_DATA_BITS_20, SSP_DATA_BITS_21, + SSP_DATA_BITS_22, SSP_DATA_BITS_23, SSP_DATA_BITS_24, + SSP_DATA_BITS_25, SSP_DATA_BITS_26, SSP_DATA_BITS_27, + SSP_DATA_BITS_28, SSP_DATA_BITS_29, SSP_DATA_BITS_30, + SSP_DATA_BITS_31, SSP_DATA_BITS_32 +} t_ssp_data_size; + +/** + * SSP mode of operation (Communication modes) + */ +typedef enum { + INTERRUPT_TRANSFER, + POLLING_TRANSFER, + DMA_TRANSFER +} t_spi_mode; + +/** + * Receive FIFO watermark level which triggers IT: Interrupt fires when _N_ or more + * elements in RX FIFO. + */ +typedef enum { + SSP_RX_1_OR_MORE_ELEM, + SSP_RX_4_OR_MORE_ELEM, + SSP_RX_8_OR_MORE_ELEM, + SSP_RX_16_OR_MORE_ELEM, + SSP_RX_32_OR_MORE_ELEM +} t_ssp_rx_level_trig; + +/** + * Transmit FIFO watermark level which triggers (IT Interrupt fires + * when _N_ or more empty locations in TX FIFO) + */ +typedef enum { + SSP_TX_1_OR_MORE_EMPTY_LOC, + SSP_TX_4_OR_MORE_EMPTY_LOC, + SSP_TX_8_OR_MORE_EMPTY_LOC, + SSP_TX_16_OR_MORE_EMPTY_LOC, + SSP_TX_32_OR_MORE_EMPTY_LOC +} t_ssp_tx_level_trig; + +/** + * Microwire Conrol Lengths Command size in microwire format + */ +typedef enum { + SSP_BITS_4 = 0x03, SSP_BITS_5, SSP_BITS_6, + SSP_BITS_7, SSP_BITS_8, SSP_BITS_9, + SSP_BITS_10, SSP_BITS_11, SSP_BITS_12, + SSP_BITS_13, SSP_BITS_14, SSP_BITS_15, + SSP_BITS_16, SSP_BITS_17, SSP_BITS_18, + SSP_BITS_19, SSP_BITS_20, SSP_BITS_21, + SSP_BITS_22, SSP_BITS_23, SSP_BITS_24, + SSP_BITS_25, SSP_BITS_26, SSP_BITS_27, + SSP_BITS_28, SSP_BITS_29, SSP_BITS_30, + SSP_BITS_31, SSP_BITS_32 +} t_ssp_microwire_ctrl_len; + +/** + * Microwire Wait State + */ +typedef enum { + SSP_MWIRE_WAIT_ZERO, /* No wait state inserted after last command bit */ + SSP_MWIRE_WAIT_ONE /* One wait state inserted after last command bit */ +} t_ssp_microwire_wait_state; + +/** + * Microwire : whether Full/Half Duplex + */ +typedef enum { + SSP_MICROWIRE_CHANNEL_FULL_DUPLEX, /* SSPTXD becomes bi-directional, SSPRXD not used */ + SSP_MICROWIRE_CHANNEL_HALF_DUPLEX /* SSPTXD is an output, SSPRXD is an input. */ +} t_ssp_duplex; + +/** + * CHIP select/deselect commands + */ +typedef enum { + SPI_CHIP_SELECT, + SPI_CHIP_DESELECT +} t_spi_chip_select; + +/** + * Type of DMA xfer (between SSP fifo & MEM, or SSP fifo & some device) + */ +typedef enum { + SPI_WITH_MEM, + SPI_WITH_PERIPH +} t_dma_xfer_type; + +/* this macro to be used by clinet driver to ulter the dma characterastic of spi or peripharal device */ +#define NMDK_SPI_DMADEV_CONFIG(x) (0xc0000000 | x) + +/* + * Parameters to configure the characteristics of a dma device + */ +struct nmdk_spi_master_dmadev_config { + u32 config; +}; +struct nmdk_spi_client_dmadev_config { + char *devtype; + u32 config; +}; + +/** + * nmdkspi_dma - DMA configuration for SSP and communicating device + * @rx_dma_id: DMA device ID for Rx fifo of communicating device(-1 if MEM-to-Periph DMA) + * @tx_dma_id: DMA device ID for Tx fifo of communicating device(-1 if MEM-to-Periph DMA) + * @ssp_dma_params: DMA configuration of SSP controller + * @periph_dma_params: DMA configuration of communicating device + * + */ +struct nmdkspi_dma { + u32 rx_dma_mode; + u32 tx_dma_mode; + struct nmdk_spi_master_dmadev_config *rx_master_dmadev_config; + struct nmdk_spi_master_dmadev_config *tx_master_dmadev_config; + struct nmdk_spi_client_dmadev_config *rx_client_dmadev_config; + struct nmdk_spi_client_dmadev_config *tx_client_dmadev_config; +}; + +typedef enum { + MSP_0_CONTROLLER =1, + MSP_1_CONTROLLER, + MSP_2_CONTROLLER, + SSP_CONTROLLER, + MSP_3_CONTROLLER, +} t_spi_controller; + +/* User client for the MSP */ +typedef enum { + SPI_NO_MSP_USER = 0, /*Should have same value as MSP_NO_USER*/ + SPI_USER_MSP, /*Should have same value as MSP_USER_SPI*/ +}t_spi_user; + +/*User flag for MSP*/ +typedef struct { + struct semaphore lock; + t_spi_user user; +}spi_msp_user ; + +/** + * struct nomadik_ssp_master - device.platform_data for SPI controller devices. + * @num_chipselect: chipselects are used to distinguish individual + * SPI slaves, and are numbered from zero to num_chipselects - 1. + * each slave has a chipselect signal, but it's common that not + * every chipselect is connected to a slave. + * @enable_dma: if true enables DMA driven transfers. + */ +struct nmdk_spi_master_cntlr { + u8 num_chipselect; + u8 enable_dma:1; + u32 id; + u32 base_addr; + u32 dma_srcaddr; + char *dma_srcdevtype; + u32 dma_destaddr; + char *dma_destdevtype; + gpio_alt_function gpio_alt_func; + char *device_name; +}; + +struct motorola_spi_proto_params { + t_spi_clk_phase clk_phase; + t_spi_clk_pol clk_pol; + +}; +struct microwire_proto_params { + t_ssp_microwire_ctrl_len ctrl_len; + t_ssp_microwire_wait_state wait_state; + t_ssp_duplex duplex; +}; + +struct msp_controller { + t_msp_data_size data_size; + t_msp_clock_params clk_freq; + bool_t spi_burst_mode_enable; +}; + +struct ssp_controller { + t_ssp_data_size data_size; + t_ssp_rx_level_trig rx_lev_trig; + t_ssp_tx_level_trig tx_lev_trig; + bool_t slave_tx_disable; + t_ssp_clock_params clk_freq; +}; + +/** + * struct ssp_config_chip - spi_board_info.controller_data for SPI slave devices, copied to spi_device.controller_data. + * @lbm: used for test purpose to internally connect RX and TX + * @iface: Interface type(Motorola, TI, Microwire, Universal) + * @hierarchy: sets whether interface is master or slave + * @slave_tx_disable: SSPTXD is disconnected (in slave mode only) + * @clk_freq: Tune freq parameters of SSP(when in master mode) + * @endian_rx: Endianess of Data in Rx FIFO + * @endian_tx: Endianess of Data in Tx FIFO + * @data_size: Width of data element(4 to 32 bits) + * @com_mode: communication mode: polling, Interrupt or DMA + * @rx_lev_trig: Rx FIFO watermark level (for IT & DMA mode) + * @tx_lev_trig: Tx FIFO watermark level (for IT & DMA mode) + * @clk_phase: Motorola SPI interface Clock phase + * @clk_pol: Motorola SPI interface Clock polarity + * @ctrl_len: Microwire interface: Control length + * @wait_state: Microwire interface: Wait state + * @duplex: Microwire interface: Full/Half duplex + * @freq: Freq of operation(will be used if clk_freq is not given) + * @cs_control: function pointer to board-specific function to assert/deassert I/O port to control HW generation of devices chip-select. + * @dma_xfer_type: Type of DMA xfer (Mem-to-periph or Periph-to-Periph) + * @dma_config: DMA configuration for SSP controller and peripheral + * + */ +struct nmdk_spi_config_chip { + t_spi_loopback lbm; + t_spi_interface iface; + t_spi_hierarchy hierarchy; + t_spi_fifo_endian endian_rx; + t_spi_fifo_endian endian_tx; + t_spi_mode com_mode; + + union { + struct msp_controller msp; + struct ssp_controller ssp; + } controller; + union { + struct motorola_spi_proto_params moto; + struct microwire_proto_params micro; + } proto_params; + + u32 freq; + void (*cs_control) (u32 control); + t_dma_xfer_type dma_xfer_type; + struct nmdkspi_dma *dma_config; +}; + +struct driver_data { + struct amba_device *adev; + struct spi_master *master; + struct nmdk_spi_master_cntlr *master_info; + void __iomem *regs; +#ifdef SPI_WORKQUEUE + struct workqueue_struct *workqueue; +#endif + struct work_struct spi_work; + spinlock_t lock; + struct list_head queue; + + int busy; + int run; + + int dma_ongoing; + + struct tasklet_struct pump_transfers; + struct tasklet_struct spi_dma_tasklet; + struct spi_message *cur_msg; + struct spi_transfer *cur_transfer; + struct chip_data *cur_chip; + void *tx; + void *tx_end; + void *rx; + void *rx_end; + spi_msp_user *flag_msp0; + spi_msp_user *flag_msp1; + spi_msp_user *flag_msp2; + void (*write) (struct driver_data * drv_data); + void (*read) (struct driver_data * drv_data); + int (*execute_cmd) (struct driver_data * drv_data, int cmd); + + atomic_t dma_cnt; +}; + +/*CONTROLLER COMMANDS*/ +typedef enum { + DISABLE_CONTROLLER = 0, + ENABLE_CONTROLLER , + DISABLE_ALL_INTERRUPT , + ENABLE_ALL_INTERRUPT , + ENABLE_DMA , + DISABLE_DMA , + FLUSH_FIFO , + RESTORE_STATE , + LOAD_DEFAULT_CONFIG , + CLEAR_ALL_INTERRUPT, +} cntlr_commands; + +/***************************************************************************/ +#define SPI_REG_WRITE_BITS(reg,val,mask,sb) ((reg) = (((reg) & ~(mask)) | (((val)<<(sb)) & (mask)))) +#define GEN_MASK_BITS(val,mask,sb) ((uint32)((((uint32)val)<<(sb)) & (mask))) + +/*####################################################################### + Message State +######################################################################### + */ +#define START_STATE ((void*)0) +#define RUNNING_STATE ((void*)1) +#define DONE_STATE ((void*)2) +#define ERROR_STATE ((void*)-1) + + +struct ssp_regs{ + u32 cr0; + u32 cr1; + u32 dmacr; + u32 cpsr; +}; + +struct msp_regs{ + u32 gcr; + u32 tcf; + u32 rcf; + u32 srg; + u32 dmacr; +}; + +struct spi_dma_info{ + t_dma_xfer_type dma_xfer_type; + dmach_t rx_dmach; + dmach_t tx_dmach; + struct nmdk_dma_info rx_dma_info; + struct nmdk_dma_info tx_dma_info; +}; + +/** + * struct chip_data - To maintain runtime state of SPI Controller for each client chip + * @regs: Union of structure holding registers of SPI Controller + * @chip_id: Chip Id assigned to this client to identify it. + * @n_bytes: how many bytes(power of 2) reqd for a given data width of client + * @rx_dma_id: Rx DMA device Id of client for Peripheral to Peripheral DMA + * @tx_dma_id: Tx DMA device Id of client for Peripheral to Peripheral DMA + * @dma_xfer_type: xfer type of DMA (Mem-to-periph, periph-to-periph) + * @spi_cntlr_dev_params: DMA configuration parameters for SPI controller + * @spi_client_dev_params: DMA configuration parameters for Client peripheral(chip) + * @enable_dma: Whether to enable DMA or not + * @write: function to be used to write when doing xfer for this chip + * @read: function to be used to read when doing xfer for this chip + * @cs_control: chip select callback provided by chip + * @xfer_type: polling/interrupt/dma + * + * Runtime state of the SPI controller, maintained per chip, + * This would be set according to the current message that would be served + */ +struct chip_data { + union{ + struct ssp_regs sspr; + struct msp_regs mspr; + } regs; + u32 chip_id; + u8 n_bytes; + u8 enable_dma; + struct spi_dma_info * dma_info; + void (*write) (struct driver_data * drv_data); + void (*read) (struct driver_data * drv_data); + void (*cs_control) (u32 command); + int xfer_type; +}; + +/* + * Functions declaration + **/ +extern void *next_transfer(struct driver_data *drv_data); +extern void giveback(struct spi_message *message, struct driver_data *drv_data); +extern void null_cs_control(u32 command); +extern int calculate_effective_freq(int freq, t_ssp_clock_params * clk_freq); +extern int process_dma_info(struct nmdk_spi_config_chip *chip_info, + struct chip_data *chip, void * data); +extern int nomadik_spi_transfer(struct spi_device *spi, struct spi_message *msg); +extern void nomadik_spi_cleanup(const struct spi_device *spi); +extern int init_queue(struct driver_data *drv_data); +extern int start_queue(struct driver_data *drv_data); +extern int stop_queue(struct driver_data *drv_data); +extern int destroy_queue(struct driver_data *drv_data); +extern irqreturn_t spi_dma_callback_handler(int irq, void *param); +extern void nomadik_spi_tasklet(unsigned long param); +#endif /* _SPI_NMDK_H */ --- /dev/null +++ linux-2.6.20/include/asm-arm/arch-nomadik/ssp-spi.h @@ -0,0 +1,280 @@ +/* + * arch/arm/mach-nomadik/ssp-spi.h + * + * Copyright (C) 2007 STMicroelectronics Pvt. Ltd. + * + * Author: Sachin Verma + * + * Description: Header File containing Hardware specific details for + * SSP controller hardware + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef NOMADIC_SSP_SPI_HEADER +#define NOMADIC_SSP_SPI_HEADER + +#define DRIVE_TX (0) +#define DO_NOT_DRIVE_TX (1) + + +#define SSP_FIFOSIZE (32) +#define SSP_FIFOWIDTH (32) +#define SSP_PERIPHID0 (0x22) +#define SSP_PERIPHID1 (0x00) +#define SSP_PERIPHID2 (0x08) +#define SSP_PERIPHID3 (0x01) +#define SSP_PCELLID0 (0x0D) +#define SSP_PCELLID1 (0xF0) +#define SSP_PCELLID2 (0x05) +#define SSP_PCELLID3 (0xB1) + +/*####################################################################### + Macros to access SSP Registers with their offsets +######################################################################### +*/ +#define SSP_CR0(r) (r + 0x000) +#define SSP_CR1(r) (r + 0x004) +#define SSP_DR(r) (r + 0x008) +#define SSP_SR(r) (r + 0x00C) +#define SSP_CPSR(r) (r + 0x010) +#define SSP_IMSC(r) (r + 0x014) +#define SSP_RIS(r) (r + 0x018) +#define SSP_MIS(r) (r + 0x01C) +#define SSP_ICR(r) (r + 0x020) +#define SSP_DMACR(r) (r + 0x024) +#define SSP_ITCR(r) (r + 0x080) +#define SSP_ITIP(r) (r + 0x084) +#define SSP_ITOP(r) (r + 0x088) +#define SSP_TDR(r) (r + 0x08C) + +#define SSP_PID0(r) (r + 0xFE0) +#define SSP_PID1(r) (r + 0xFE4) +#define SSP_PID2(r) (r + 0xFE8) +#define SSP_PID3(r) (r + 0xFEC) + +#define SSP_CID0(r) (r + 0xFF0) +#define SSP_CID1(r) (r + 0xFF4) +#define SSP_CID2(r) (r + 0xFF8) +#define SSP_CID3(r) (r + 0xFFC) + +/*####################################################################### + SSP Control Register 0 - SSP_CR0 +######################################################################### +*/ +#define SSP_CR0_MASK_DSS ((uint32)(0x1FUL << 0)) +#define SSP_CR0_MASK_HALFDUP ((uint32)(0x1UL << 5)) +#define SSP_CR0_MASK_SPO ((uint32)(0x1UL << 6)) +#define SSP_CR0_MASK_SPH ((uint32)(0x1UL << 7)) +#define SSP_CR0_MASK_SCR ((uint32)(0xFFUL << 8)) +#define SSP_CR0_MASK_CSS ((uint32)(0x1FUL << 16)) +#define SSP_CR0_MASK_FRF ((uint32)(0x3UL << 21)) + +/*####################################################################### + SSP Control Register 0 - SSP_CR1 +######################################################################### +*/ +#define SSP_CR1_MASK_LBM ((uint32)(0x1UL << 0)) +#define SSP_CR1_MASK_SSE ((uint32)(0x1UL << 1)) +#define SSP_CR1_MASK_MS ((uint32)(0x1UL << 2)) +#define SSP_CR1_MASK_SOD ((uint32)(0x1UL << 3)) +#define SSP_CR1_MASK_RENDN ((uint32)(0x1UL << 4)) +#define SSP_CR1_MASK_TENDN ((uint32)(0x1UL << 5)) +#define SSP_CR1_MASK_MWAIT ((uint32)(0x1UL << 6)) +#define SSP_CR1_MASK_RXIFLSEL ((uint32)(0x7UL << 7)) +#define SSP_CR1_MASK_TXIFLSEL ((uint32)(0x7UL << 10)) + +/*####################################################################### + SSP Data Register - ssp_dr +######################################################################### + */ + +#define SSP_DR_MASK_DATA 0xFFFFFFFF + +/*####################################################################### + SSP Status Register - ssp_sr +######################################################################### + */ + +#define SSP_SR_MASK_TFE ((uint32)(0x1UL << 0)) /* Transmit FIFO empty */ +#define SSP_SR_MASK_TNF ((uint32)(0x1UL << 1)) /* Transmit FIFO not full */ +#define SSP_SR_MASK_RNE ((uint32)(0x1UL << 2)) /* Receive FIFO not empty */ +#define SSP_SR_MASK_RFF ((uint32)(0x1UL << 3)) /* Receive FIFO full */ +#define SSP_SR_MASK_BSY ((uint32)(0x1UL << 4)) /* Busy Flag */ + +/*####################################################################### + SSP Clock Prescale Register - ssp_cpsr +######################################################################### + */ +#define SSP_CPSR_MASK_CPSDVSR ((uint32)(0xFFUL << 0)) /*(0xFF << 0)*/ + +/*####################################################################### + SSP Interrupt Mask Set/Clear Register - ssp_imsc +######################################################################### +*/ +#define SSP_IMSC_MASK_RORIM ((uint32)(0x1UL << 0)) /* Receive Overrun Interrupt mask */ +#define SSP_IMSC_MASK_RTIM ((uint32)(0x1UL << 1)) /* Receive timeout Interrupt mask */ +#define SSP_IMSC_MASK_RXIM ((uint32)(0x1UL << 2)) /* Receive FIFO Interrupt mask */ +#define SSP_IMSC_MASK_TXIM ((uint32)(0x1UL << 3)) /* Transmit FIFO Interrupt mask */ + +/*####################################################################### + SSP Raw Interrupt Status Register - ssp_ris +######################################################################### + */ +#define SSP_RIS_MASK_RORRIS ((uint32)(0x1UL << 0)) /* Receive Overrun Raw Interrupt status */ +#define SSP_RIS_MASK_RTRIS ((uint32)(0x1UL << 1)) /* Receive Timeout Raw Interrupt status */ +#define SSP_RIS_MASK_RXRIS ((uint32)(0x1UL << 2)) /* Receive FIFO Raw Interrupt status */ +#define SSP_RIS_MASK_TXRIS ((uint32)(0x1UL << 3)) /* Transmit FIFO Raw Interrupt status */ + +/*####################################################################### + SSP Masked Interrupt Status Register - ssp_mis +######################################################################### + */ + +#define SSP_MIS_MASK_RORMIS ((uint32)(0x1UL << 0)) /* Receive Overrun Masked Interrupt status */ +#define SSP_MIS_MASK_RTMIS ((uint32)(0x1UL << 1)) /* Receive Timeout Masked Interrupt status */ +#define SSP_MIS_MASK_RXMIS ((uint32)(0x1UL << 2)) /* Receive FIFO Masked Interrupt status */ +#define SSP_MIS_MASK_TXMIS ((uint32)(0x1UL << 3)) /* Transmit FIFO Masked Interrupt status */ + +/*####################################################################### + SSP Interrupt Clear Register - ssp_icr +######################################################################### + */ +#define SSP_ICR_MASK_RORIC ((uint32)(0x1UL << 0)) /* Receive Overrun Raw Clear Interrupt bit */ +#define SSP_ICR_MASK_RTIC ((uint32)(0x1UL << 1)) /* Receive Timeout Clear Interrupt bit */ + +/*####################################################################### + SSP DMA Control Register - ssp_dmacr +######################################################################### + */ +#define SSP_DMACR_MASK_RXDMAE ((uint32)(0x1UL << 0)) /* Receive DMA Enable bit */ +#define SSP_DMACR_MASK_TXDMAE ((uint32)(0x1UL << 1)) /* Transmit DMA Enable bit */ + +/*####################################################################### + SSP Integration Test control Register - ssp_itcr +######################################################################### + */ +#define SSP_ITCR_MASK_ITEN ((uint32)(0x1UL << 0)) +#define SSP_ITCR_MASK_TESTFIFO ((uint32)(0x1UL << 1)) + +/*####################################################################### + SSP Integration Test Input Register - ssp_itip +######################################################################### + */ +#define ITIP_MASK_SSPRXD ((uint32)(0x1UL << 0)) +#define ITIP_MASK_SSPFSSIN ((uint32)(0x1UL << 1)) +#define ITIP_MASK_SSPCLKIN ((uint32)(0x1UL << 2)) +#define ITIP_MASK_RXDMAC ((uint32)(0x1UL << 3)) +#define ITIP_MASK_TXDMAC ((uint32)(0x1UL << 4)) +#define ITIP_MASK_SSPTXDIN ((uint32)(0x1UL << 5)) + +/*####################################################################### + SSP Integration Test output Register - ssp_itop +######################################################################### + */ +#define ITOP_MASK_SSPTXD ((uint32)(0x1UL << 0)) +#define ITOP_MASK_SSPFSSOUT ((uint32)(0x1UL << 1)) +#define ITOP_MASK_SSPCLKOUT ((uint32)(0x1UL << 2)) +#define ITOP_MASK_SSPOEn ((uint32)(0x1UL << 3)) +#define ITOP_MASK_SSPCTLOEn ((uint32)(0x1UL << 4)) +#define ITOP_MASK_RORINTR ((uint32)(0x1UL << 5)) +#define ITOP_MASK_RTINTR ((uint32)(0x1UL << 6)) +#define ITOP_MASK_RXINTR ((uint32)(0x1UL << 7)) +#define ITOP_MASK_TXINTR ((uint32)(0x1UL << 8)) +#define ITOP_MASK_INTR ((uint32)(0x1UL << 9)) +#define ITOP_MASK_RXDMABREQ ((uint32)(0x1UL << 10)) +#define ITOP_MASK_RXDMASREQ ((uint32)(0x1UL << 11)) +#define ITOP_MASK_TXDMABREQ ((uint32)(0x1UL << 12)) +#define ITOP_MASK_TXDMASREQ ((uint32)(0x1UL << 13)) + +/*####################################################################### + SSP Test Data Register - ssp_tdr +######################################################################### + */ +#define TDR_MASK_TESTDATA (0xFFFFFFFF) + +/*####################################################################### + SSP State - Whether Enabled or Disabled +######################################################################### + */ +#define SSP_DISABLED (0) +#define SSP_ENABLED (1) + +/*####################################################################### + SSP DMA State - Whether DMA Enabled or Disabled +######################################################################### + */ +#define SSP_DMA_DISABLED (0) +#define SSP_DMA_ENABLED (1) + +/*####################################################################### + SSP Clock Defaults +######################################################################### + */ + +#define NMDK_SSP_DEFAULT_CLKRATE 0x2 +#define NMDK_SSP_DEFAULT_PRESCALE 0x40 + +/*####################################################################### + SSP Clock Parameter ranges +######################################################################### + */ +#define MIN_CPSDVR 0x02 +#define MAX_CPSDVR 0xFE +#define MIN_SCR 0x00 +#define MAX_SCR 0xFF +/*#define NMDK_SSP_CLOCK_FREQ 24000000*/ +#define NMDK_SSP_CLOCK_FREQ 48000000 + +/*####################################################################### + SSP Interrupt related Macros +######################################################################### + */ +#define DEFAULT_SSP_REG_IMSC 0x0UL +#define DISABLE_ALL_SSP_INTERRUPTS DEFAULT_SSP_REG_IMSC +#define ENABLE_ALL_SSP_INTERRUPTS (~DEFAULT_SSP_REG_IMSC) + +#define CLEAR_ALL_SSP_INTERRUPTS 0x3 + +/*####################################################################### + Default SSP Register Values +######################################################################### + */ +#define DEFAULT_SSP_REG_CR0 ( \ + GEN_MASK_BITS(SSP_DATA_BITS_12, SSP_CR0_MASK_DSS, 0) | \ + GEN_MASK_BITS(SSP_MICROWIRE_CHANNEL_FULL_DUPLEX, SSP_CR0_MASK_HALFDUP, 5) | \ + GEN_MASK_BITS(SPI_CLK_POL_IDLE_LOW, SSP_CR0_MASK_SPO, 6) | \ + GEN_MASK_BITS(SPI_CLK_HALF_CYCLE_DELAY, SSP_CR0_MASK_SPH, 7) |\ + GEN_MASK_BITS(NMDK_SSP_DEFAULT_CLKRATE, SSP_CR0_MASK_SCR, 8) |\ + GEN_MASK_BITS(SSP_BITS_8, SSP_CR0_MASK_CSS, 16) |\ + GEN_MASK_BITS(SPI_INTERFACE_MOTOROLA_SPI, SSP_CR0_MASK_FRF, 21) \ + ) + +#define DEFAULT_SSP_REG_CR1 ( \ + GEN_MASK_BITS(LOOPBACK_DISABLED, SSP_CR1_MASK_LBM, 0) | \ + GEN_MASK_BITS(SSP_DISABLED, SSP_CR1_MASK_SSE, 1) | \ + GEN_MASK_BITS(SPI_MASTER, SSP_CR1_MASK_MS, 2) | \ + GEN_MASK_BITS(DO_NOT_DRIVE_TX, SSP_CR1_MASK_SOD, 3) | \ + GEN_MASK_BITS(SPI_FIFO_MSB, SSP_CR1_MASK_RENDN, 4) | \ + GEN_MASK_BITS(SPI_FIFO_MSB, SSP_CR1_MASK_TENDN, 5) | \ + GEN_MASK_BITS(SSP_MWIRE_WAIT_ZERO, SSP_CR1_MASK_MWAIT, 6) |\ + GEN_MASK_BITS(SSP_RX_1_OR_MORE_ELEM, SSP_CR1_MASK_RXIFLSEL, 7 ) | \ + GEN_MASK_BITS(SSP_TX_1_OR_MORE_EMPTY_LOC, SSP_CR1_MASK_TXIFLSEL, 10 ) \ + ) + +#define DEFAULT_SSP_REG_CPSR (\ + GEN_MASK_BITS(NMDK_SSP_DEFAULT_PRESCALE, SSP_CPSR_MASK_CPSDVSR, 0) \ + ) + +#define DEFAULT_SSP_REG_DMACR (\ + GEN_MASK_BITS(SSP_DMA_DISABLED, SSP_DMACR_MASK_RXDMAE, 0) | \ + GEN_MASK_BITS(SSP_DMA_DISABLED, SSP_DMACR_MASK_TXDMAE, 1) \ + ) +#endif --- /dev/null +++ linux-2.6.20/include/asm-arm/arch-nomadik/stn8810_devices.h @@ -0,0 +1,120 @@ +/* + * include/asm-arm/arch-nomadik/stn8810_devices.h + * + * Copyright (C) STMicroelectronics + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef __stn8810_devices_h +#define __stn8810_devices_h +/* + * To use declaration defined here, add '#include ' in your + * source file, This file is referenced from + */ + +/* + * Base address defination for Onchip IPs (specific to stn8810 all cuts) + */ +#define NOMADIK_TDES_BASE 0x10180000 /* TDES Processor */ +#define NOMADIK_USB_BASE 0x10300000 /* USB-OTG conf reg base */ + +/* + * Chip specific Interrupt numbers + */ +#define IRQ_MSP1 30 +#define IRQ_TDES 2 +#define MAXIRQNUM 31 +#define VIC_VECTORED_IRQ_EN (1UL<<5) /*vectored irq enable bit*/ +/* the macro below decides which IRQs to be configured/enabled during vic_init*/ +#define IRQ_SOC_CONF ( 1ULL<' in your + * source file, This file is referenced from + */ + +/* + * Base address defination for Onchip IPs (specific to stn8815 all cuts) + */ +#define NOMADIK_USB_BASE 0x10170000 /* USB-OTG conf reg base */ +#define NOMADIK_CRYP_BASE 0x10180000 /* Cryptographic processor + configuration/data registers */ +#define NOMADIK_MSHC_BASE 0x101F5000 /* Memory Stick(Pro) Host + Controller Registers */ + +#define NOMADIK_L2CC_BASE 0x10210000 /* L2 Cache controller */ + +/* + * Chip specific Interrupt numbers + */ +#define IRQ_MSP1 62 +#define IRQ_USBM 60 +#define IRQ_SGA_IT 58 +#define IRQ_MEMST 54 +#define IRQ_KP 51 +#define IRQ_SKE 50 +#define IRQ_HPI 49 +#define IRQ_L2CC 48 +#define IRQ_GPIO3 9 +#define IRQ_CRYPTO 2 +#define MAXIRQNUM 63 +#define VIC_VECTORED_IRQ_EN (1UL<<6) /*vectored irq enable bit*/ +/* the macro below decides which IRQs to be configured/enabled during vic_init*/ +#define IRQ_SOC_CONF ( 1ULL< + +/*--------------------------------------------------------------------- + * Define + *--------------------------------------------------------------------*/ + +typedef enum { + CODEC_HWC_INPUT_SRC, + CODEC_HWC_OUTPUT_DEST, + CODEC_HWC_SAMPLE_FREQUENCIES, + CODEC_HWC_DATA_FORMAT, + CODEC_HWC_SIDE_TONE_VOLUME, + CODEC_HWC_DIGITAL_DEEMPHASIS, + CODEC_HWC_USB_CLOCK_MODE, + CODEC_HWC_VARIABLE_INPUT_BIT_LENGTH, + CODEC_HWC_COMPAND_MODES, + CODEC_HWC_BYPASS_MODE, + CODEC_HWC_MIC_BOOST, + CODEC_HWC_HIGH_PASS_FILTER, + CODEC_HWC_MODE_MASTER_SLAVE, + CODEC_HWC_MIC_MUTE, + CODEC_HWC_DAC_SOFT_MUTE, + CODEC_HWC_CLOCK_MODE_SELECTION, + CODEC_HWC_OVERSAMPLING_RATE, + CODEC_HWC_INPUT_MODE, + CODEC_HWC_OUTPUT_MODE, + CODEC_HWC_CODEC_INTERNAL_PLL, + CODEC_HWC_CODEC_INPUT_FREQUENCY +} t_codec_hw_capability; + +/* CODEC_HWC_INPUT_SRC: + Select source to record from. +*/ +#define CODEC_HWC_SRC_LINEIN 0x00000001 +#define CODEC_HWC_SRC_MICROPHONE 0x00000002 + +/* CODEC_HWC_OUTPUT_DEST: + Select destination for play. +*/ +#define CODEC_HWC_DEST_LOUDSPEAKER 0x00000001 +#define CODEC_HWC_DEST_EARPIECE 0x00000002 +#define CODEC_HWC_DEST_HEADPHONE 0x00000004 +#define CODEC_HWC_DEST_LINEOUT 0x00000008 + +/* CODEC_HWC_SAMPLE_FREQUENCIES: + Sample frequencies for play/record. +*/ +#define CODEC_HWC_SAMPLE_FREQY_8KHZ 0x00000001 +#define CODEC_HWC_SAMPLE_FREQY_11_025KHZ 0x00000002 +#define CODEC_HWC_SAMPLE_FREQY_12KHZ 0x00000004 +#define CODEC_HWC_SAMPLE_FREQY_16KHZ 0x00000008 +#define CODEC_HWC_SAMPLE_FREQY_22_05KHZ 0x00000010 +#define CODEC_HWC_SAMPLE_FREQY_22_5KHZ 0x00000020 +#define CODEC_HWC_SAMPLE_FREQY_24KHZ 0x00000040 +#define CODEC_HWC_SAMPLE_FREQY_32KHZ 0x00000080 +#define CODEC_HWC_SAMPLE_FREQY_44KHZ 0x00000100 +#define CODEC_HWC_SAMPLE_FREQY_44_1KHZ 0x00000200 +#define CODEC_HWC_SAMPLE_FREQY_48KHZ 0x00000400 +#define CODEC_HWC_SAMPLE_FREQY_64KHZ 0x00000800 +#define CODEC_HWC_SAMPLE_FREQY_88KHZ 0x00001000 +#define CODEC_HWC_SAMPLE_FREQY_88_2KHZ 0x00002000 +#define CODEC_HWC_SAMPLE_FREQY_96KHZ 0x00004000 + +/* CODEC_HWC_DATA_FORMAT: + Data format to be configured in Audio Codec. +*/ +#define CODEC_HWC_DF_MSB_FIRST_RIGHT_ALIGNED 0x00000001 +#define CODEC_HWC_DF_MSB_FIRST_LEFT_ALIGNED 0x00000002 +#define CODEC_HWC_DF_I2S 0x00000004 +#define CODEC_HWC_DF_DSP_FORMAT 0x00000008 + +/* CODEC_HWC_SIDE_TONE_VOLUME: + Side tone volume to be set. +*/ +#define CODEC_HWC_SIDETONE_VOLUME_NONE 0x00000001 +#define CODEC_HWC_SIDETONE_VOLUME_0DB 0x00000002 +#define CODEC_HWC_SIDETONE_VOLUME_M6DB 0x00000004 +#define CODEC_HWC_SIDETONE_VOLUME_M9DB 0x00000008 +#define CODEC_HWC_SIDETONE_VOLUME_M12DB 0x00000010 + +/* CODEC_HWC_DIGITAL_DEEMPHASIS: + Enumeration is used to select de-emphasis control frequency. +*/ +#define CODEC_HWC_DIGITAL_DEEMPHASIS_DISABLE 0x00000001 +#define CODEC_HWC_DIGITAL_DEEMPHASIS_32KHZ 0x00000002 +#define CODEC_HWC_DIGITAL_DEEMPHASIS_441KHZ 0x00000004 +#define CODEC_HWC_DIGITAL_DEEMPHASIS_48KHZ 0x00000008 + +/* CODEC_HWC_VARIABLE_INPUT_BIT_LENGTH: + Enumeration is used for CODEC clock mode selection (normal/USB). +*/ +#define CODEC_HWC_INPUT_BIT_LENGTH_16_BIT 0x00000001 +#define CODEC_HWC_INPUT_BIT_LENGTH_20_BIT 0x00000002 +#define CODEC_HWC_INPUT_BIT_LENGTH_24_BIT 0x00000004 +#define CODEC_HWC_INPUT_BIT_LENGTH_32_BIT 0x00000008 + +/* CODEC_HWC_COMPAND_MODES: + Companding modes supported by the ADC/DAC. +*/ +#define CODEC_HWC_COMPAND_MODE_LINEAR 0x00000001 +#define CODEC_HWC_COMPAND_MODE_A_LAW 0x00000002 +#define CODEC_HWC_COMPAND_MODE_MU_LAW 0x00000004 + +/* CODEC_HWC_BYPASS_MODE: + Enable/disable bypass mode. +*/ +#define CODEC_HWC_BYPASS_MODE_OFF 0x00000001 +#define CODEC_HWC_BYPASS_MODE_ON 0x00000002 + +/* CODEC_HWC_MIC_BOOST: + Enable/disable MIC Boost by +20db. +*/ +#define CODEC_HWC_MIC_BOOST_OFF 0x00000001 +#define CODEC_HWC_MIC_BOOST_ON 0x00000002 + +/* CODEC_HWC_HIGH_PASS_FILTER: + Enable/disable high filter. +*/ +#define CODEC_HWC_HIGH_PASS_FILTER_OFF 0x00000001 +#define CODEC_HWC_HIGH_PASS_FILTER_ON 0x00000002 + +/* CODEC_HWC_MODE_MASTER_SLAVE: + Select Master/Slave mode. +*/ +#define CODEC_HWC_MODE_MASTER 0x00000001 +#define CODEC_HWC_MODE_SLAVE 0x00000002 + +/* CODEC_HWC_MIC_MUTE: + Enable/disable MIC mute. +*/ +#define CODEC_HWC_MIC_OFF 0x00000001 +#define CODEC_HWC_MIC_ON 0x00000002 + +/* CODEC_HWC_DAC_SOFT_MUTE: + Enable/disable DAC SOFT MUTE +*/ +#define CODEC_HWC_DAC_SOFT_MUTE_OFF 0x00000001 +#define CODEC_HWC_DAC_SOFT_MUTE_ON 0x00000002 + +/* CODEC_HWC_CLOCK_MODE_SELECTION: + Clock mode selection. +*/ +#define CODEC_HWC_CLOCK_MODE_NORMAL 0x00000001 +#define CODEC_HWC_CLOCK_MODE_USB 0x00000002 + +/* CODEC_HWC_OVERSAMPLING_RATE: +*/ +#define CODEC_HWC_BASE_OVERSAMPLING_RATE_256FS 0x00000001 +#define CODEC_HWC_OVERSAMPLING_RATE_384FS 0x00000002 + +/* CODEC_HWC_INPUT_MODE: +*/ +#define CODEC_HWC_INPUT_MODE_HIFI 0x00000001 +#define CODEC_HWC_INPUT_MODE_VOICE 0x00000002 +#define CODEC_HWC_INPUT_MODE_MANUAL 0x00000004 + +/* CODEC_HWC_OUTPUT_MODE: +*/ +#define CODEC_HWC_OUTPUT_MODE_HIFI 0x00000001 +#define CODEC_HWC_OUTPUT_MODE_VOICE 0x00000002 +#define CODEC_HWC_OUTPUT_MODE_MANUAL 0x00000004 + +/* CODEC_HWC_CODEC_INTERNAL_PLL: +*/ +#define CODEC_HWC_CODEC_INTERNAL_PLL_DONNOT_USE 0x00000001 +#define CODEC_HWC_CODEC_INTERNAL_PLL_USE 0x00000002 + +/* CODEC_HWC_CODEC_INPUT_FREQUENCY: + This is pass input frequency to codec in KHz. +*/ +/************************************************************/ + +t_codec_error CODEC_I2CWrite(__u16 add_of_codec_on_i2c, __u8 location, + __u8 * p_data, __u32 count); + +/*--------------------------------------------------------------------------------------------- +* Private Header file for AUDIOCODEC stw5095 +*--------------------------------------------------------------------------------------------- +*/ + +#define CODEC_MASK_ONE_BIT 0x1UL +#define CODEC_MASK_TWO_BITS 0x3UL +#define CODEC_MASK_THREE_BITS 0x7UL +#define CODEC_MASK_FOUR_BITS 0xFUL +#define CODEC_MASK_FIVE_BITS 0x1FUL +#define CODEC_MASK_SIX_BITS 0x3FUL +#define CODEC_MASK_SEVEN_BITS 0x7FUL +#define CODEC_MASK_EIGHT_BITS 0xFFUL + +#define CODEC_WRITE_BITS(reg, val, bit_nb, pos) (reg) = ((__u32) ((((reg) & (~(bit_nb << pos))) | (((val) & bit_nb) << pos)))) + +typedef enum { + CODEC_DEVICE_INTERNAL_PLL_DONNOT_USE, + CODEC_DEVICE_INTERNAL_PLL_USE +} t_codec_device_internal_pll; + +/* STW5095 Registers */ +#define CODEC_STW5095_CR0 0x00 +#define CODEC_STW5095_CR1 0x01 +#define CODEC_STW5095_CR2 0x02 +#define CODEC_STW5095_CR3 0x03 +#define CODEC_STW5095_CR4 0x04 +#define CODEC_STW5095_CR5 0x05 +#define CODEC_STW5095_CR6 0x06 +#define CODEC_STW5095_CR7 0x07 +#define CODEC_STW5095_CR8 0x08 +#define CODEC_STW5095_CR9 0x09 +#define CODEC_STW5095_CR10 0x0A +#define CODEC_STW5095_CR11 0x0B +#define CODEC_STW5095_CR12 0x0C +#define CODEC_STW5095_CR13 0x0D +#define CODEC_STW5095_CR14 0x0E +#define CODEC_STW5095_CR15 0x0F +#define CODEC_STW5095_CR16 0x10 +#define CODEC_STW5095_CR17 0x11 +#define CODEC_STW5095_CR18 0x12 +#define CODEC_STW5095_CR19 0x13 +#define CODEC_STW5095_CR20 0x14 +#define CODEC_STW5095_CR21 0x15 +#define CODEC_STW5095_CR22 0x16 +#define CODEC_STW5095_CR23 0x17 +#define CODEC_STW5095_CR24 0x18 +#define CODEC_STW5095_CR25 0x19 +#define CODEC_STW5095_CR26 0x1A +#define CODEC_STW5095_CR27 0x1B +#define CODEC_STW5095_CR28 0x1C +#define CODEC_STW5095_CR29 0x1D +#define CODEC_STW5095_CR30 0x1E +#define CODEC_STW5095_CR31 0x1F +#define CODEC_STW5095_CR32 0x20 +#define CODEC_STW5095_CR33 0x21 + +/* CR0 */ +#define CODEC_STW5095_CR0_POWERUP 7 +#define CODEC_STW5095_CR0_ENANA 6 +#define CODEC_STW5095_CR0_ENAMCK 5 +#define CODEC_STW5095_CR0_ENOSC 4 +#define CODEC_STW5095_CR0_ENPLL 3 +#define CODEC_STW5095_CR0_ENHSD 2 +#define CODEC_STW5095_CR0_A24V 1 +#define CODEC_STW5095_CR0_D12V 0 + +/* CR1 */ +#define CODEC_STW5095_CR1_ENADCL 7 +#define CODEC_STW5095_CR1_ENADCR 6 +#define CODEC_STW5095_CR1_ENDACL 5 +#define CODEC_STW5095_CR1_ENDACR 4 +#define CODEC_STW5095_CR1_ENMICL 3 +#define CODEC_STW5095_CR1_ENMICR 2 +#define CODEC_STW5095_CR1_ENLINL 1 +#define CODEC_STW5095_CR1_ENLINR 0 + +/* CR2 */ +#define CODEC_STW5095_CR2_ENLOL 7 +#define CODEC_STW5095_CR2_ENLOR 6 +#define CODEC_STW5095_CR2_ENHPL 5 +#define CODEC_STW5095_CR2_ENHPR 4 +#define CODEC_STW5095_CR2_ENHPVCM 3 +#define CODEC_STW5095_CR2_ENLS 2 +#define CODEC_STW5095_CR2_ENMIXL 1 +#define CODEC_STW5095_CR2_ENMIXR 0 + +/* CR3_CR4 */ +#define CODEC_STW5095_CR3_CR4_MICLRA 5 +#define CODEC_STW5095_CR3_CR4_MICLRG 0 + +/* CR5_CR6 */ +#define CODEC_STW5095_CR5_CR6_LINLRG 0 + +/* CR7 */ +#define CODEC_STW5095_CR7_LOG 4 +#define CODEC_STW5095_CR7_LSG 0 + +/* CR8_CR9 */ +#define CODEC_STW5095_CR8_CR9_HPLRG 0 + +/* CR10_CR11 */ +#define CODEC_STW5095_CR10_CR11_DACLRG 0 + +/* CR12_CR13 */ +#define CODEC_STW5095_CR12_CR13_ADCLRG 0 + +/* CR14 */ +#define CODEC_STW5095_CR14_DYNC 7 +#define CODEC_STW5095_CR14_TREBLE 4 +#define CODEC_STW5095_CR14_BASS 0 + +/* CR15 */ +#define CODEC_STW5095_CR15_DA2ADG 0 + +/* CR16 */ +#define CODEC_STW5095_CR16_AD2DAG 0 + +/* CR17 */ +#define CODEC_STW5095_CR17_MBIAS 7 +#define CODEC_STW5095_CR17_MBIASPD 6 +#define CODEC_STW5095_CR17_ADMIC 5 +#define CODEC_STW5095_CR17_ADLIN 4 +#define CODEC_STW5095_CR17_MIXMIC 3 +#define CODEC_STW5095_CR17_MIXLIN 2 +#define CODEC_STW5095_CR17_MIXDAC 1 +#define CODEC_STW5095_CR17_MICLO 0 + +/* CR18 */ +#define CODEC_STW5095_CR18_IN2VCM 6 +#define CODEC_STW5095_CR18_LINMUTE 5 +#define CODEC_STW5095_CR18_LINSEL 3 +#define CODEC_STW5095_CR18_MICMUTE 2 +#define CODEC_STW5095_CR18_MICSEL 0 + +/* CR19 */ +#define CODEC_STW5095_CR19_VCML 6 +#define CODEC_STW5095_CR19_DIFFLO 5 +#define CODEC_STW5095_CR19_MUTELO 4 +#define CODEC_STW5095_CR19_MUTEHP 3 +#define CODEC_STW5095_CR19_LSLIM 2 +#define CODEC_STW5095_CR19_LSSEL 0 + +/* CR20 */ +#define CODEC_STW5095_CR20_DAOCKF_LSB 0 + +/* CR21 */ +#define CODEC_STW5095_CR21_DAOCKF_MSB 0 + +/* CR23 */ +#define CODEC_STW5095_CR23_ADOCKF_LSB 0 + +/* CR24 */ +#define CODEC_STW5095_CR24_ADOCKF_MSB 0 + +/* CR22 */ +#define CODEC_STW5095_CR22_DAMAST 5 +#define CODEC_STW5095_CR22_DAMASTGEN 4 +#define CODEC_STW5095_CR22_ENDAOCK 3 +#define CODEC_STW5095_CR22_DAOCK512 2 +#define CODEC_STW5095_CR22_DAPCMF 0 + +/* CR25 */ +#define CODEC_STW5095_CR25_ADMAST 5 +#define CODEC_STW5095_CR25_ADMASTGEN 4 +#define CODEC_STW5095_CR25_ENADOCK 3 +#define CODEC_STW5095_CR25_ADOCK512 2 +#define CODEC_STW5095_CR25_ADPCMF 0 + +/* CR26 */ +#define CODEC_STW5095_CR26_DACHSW 7 +#define CODEC_STW5095_CR26_DAFORM 4 +#define CODEC_STW5095_CR26_DASPIM 3 +#define CODEC_STW5095_CR26_DAWL 0 + +/* CR27 */ +#define CODEC_STW5095_CR27_ADCHSW 7 +#define CODEC_STW5095_CR27_ADFORM 4 +#define CODEC_STW5095_CR27_ADSPIM 3 +#define CODEC_STW5095_CR27_ADWL 0 + +/* CR28 */ +#define CODEC_STW5095_CR28_AMCKINV 7 +#define CODEC_STW5095_CR28_DACKP 6 +#define CODEC_STW5095_CR28_DASYNCP 5 +#define CODEC_STW5095_CR28_DAMONO 4 +#define CODEC_STW5095_CR28_ADCKP 3 +#define CODEC_STW5095_CR28_ADSYNCP 2 +#define CODEC_STW5095_CR28_ADMONO 1 +#define CODEC_STW5095_CR28_ADHIZ 0 + +/* CR29 */ +#define CODEC_STW5095_CR29_DAVOICE 6 +#define CODEC_STW5095_CR29_DA96K 5 +#define CODEC_STW5095_CR29_RXNH 4 +#define CODEC_STW5095_CR29_ADVOICE 3 +#define CODEC_STW5095_CR29_AD96K 2 +#define CODEC_STW5095_CR29_ADNH 1 +#define CODEC_STW5095_CR29_TXNH 0 + +/* CR30 */ +#define CODEC_STW5095_CR30_SWRES 7 +#define CODEC_STW5095_CR30_AMCKSIN 3 +#define CODEC_STW5095_CR30_CKRANGE 0 + +/* CR31 */ +#define CODEC_STW5095_CR31_VLSHEN 7 +#define CODEC_STW5095_CR31_PUSHBEN 6 +#define CODEC_STW5095_CR31_HSDETEN 5 +#define CODEC_STW5095_CR31_VLSHMSK 4 +#define CODEC_STW5095_CR31_PUSHBMSK 3 +#define CODEC_STW5095_CR31_HSDETMSK 2 +#define CODEC_STW5095_CR31_OVFMSK 1 +#define CODEC_STW5095_CR31_PORMSK 0 + +/* CR32 */ +#define CODEC_STW5095_CR32_VLSH 7 +#define CODEC_STW5095_CR32_PUSHB 6 +#define CODEC_STW5095_CR32_HSDET 5 +#define CODEC_STW5095_CR32_VLSHEV 4 +#define CODEC_STW5095_CR32_PUSHBEV 3 +#define CODEC_STW5095_CR32_HSDETEV 2 +#define CODEC_STW5095_CR32_OVFEV 1 +#define CODEC_STW5095_CR32_POREV 0 + +/* CR33 */ +#define CODEC_STW5095_CR33_SPIOHIZ 5 +#define CODEC_STW5095_CR33_SPIOSEL 3 +#define CODEC_STW5095_CR33_IRQCMOS 2 +#define CODEC_STW5095_CR33_OVFDA 1 +#define CODEC_STW5095_CR33_OVFAD 0 + +/* For SetVolume API*/ +/* MIC3 / FM Preamplifier */ +#define CODEC_STW5095_INPUT_VOLUME_MAX 0 +#define CODEC_STW5095_INPUT_VOLUME_MEDIUM 9 +#define CODEC_STW5095_INPUT_VOLUME_MIN 19 + +/* Headphone */ +#define CODEC_STW5095_OUTPUT_VOLUME_MAX 0 +#define CODEC_STW5095_OUTPUT_VOLUME_MEDIUM 10 +#define CODEC_STW5095_OUTPUT_VOLUME_MIN 20 + +/* LSP */ +#define CODEC_STW5095_LSP_VOLUME_MAX 0 +#define CODEC_STW5095_LSP_VOLUME_MEDIUM 7 +#define CODEC_STW5095_LSP_VOLUME_MIN 15 + +/* LSP */ +#define CODEC_STW5095_LINEOUT_VOLUME_MAX 6 +#define CODEC_STW5095_LINEOUT_VOLUME_MEDIUM 3 +#define CODEC_STW5095_LINEOUT_VOLUME_MIN 0 + +/* MIC1 & MIC2 */ +#define CODEC_STW5095_MIC_VOLUME_MAX 26 +#define CODEC_STW5095_MIC_VOLUME_MEDIUM 14 +#define CODEC_STW5095_MIC_VOLUME_MIN 0 + +/* Line-in */ +#define CODEC_STW5095_LINEIN_VOLUME_MAX 0 +#define CODEC_STW5095_LINEIN_VOLUME_MEDIUM 10 +#define CODEC_STW5095_LINEIN_VOLUME_MIN 19 + +/* CR0 - 7 */ +typedef enum { + CODEC_STW5095_CR0_POWERUP_OFF, + CODEC_STW5095_CR0_POWERUP_ON +} t_codec_stw5095_cr0_powerup; + +/* CR0 - 6 */ +typedef enum { + CODEC_STW5095_CR0_ENANA_OFF, + CODEC_STW5095_CR0_ENANA_ON +} t_codec_stw5095_cr0_enana; + +/* CR0 - 5 */ +typedef enum { + CODEC_STW5095_CR0_ENAMCK_OFF, + CODEC_STW5095_CR0_ENAMCK_ON +} t_codec_stw5095_cr0_enamck; + +/* CR0 - 4 */ +typedef enum { + CODEC_STW5095_CR0_ENOSC_OFF, + CODEC_STW5095_CR0_ENOSC_ON +} t_codec_stw5095_cr0_enosc; + +/* CR0 - 3 */ +typedef enum { + CODEC_STW5095_CR0_ENPLL_OFF, + CODEC_STW5095_CR0_ENPLL_ON +} t_codec_stw5095_cr0_enpll; + +/* CR0 - 2 */ +typedef enum { + CODEC_STW5095_CR0_ENHSD_OFF, + CODEC_STW5095_CR0_ENHSD_ON +} t_codec_stw5095_cr0_enhsd; + +/* CR0 - 1 */ +typedef enum { + CODEC_STW5095_CR0_A24V_27_33V, + CODEC_STW5095_CR0_A24V_24_27V +} t_codec_stw5095_cr0_a24v; + +/* CR0 - 0 */ +typedef enum { + CODEC_STW5095_CR0_D12V_18_VCC, + CODEC_STW5095_CR0_D12V_12_18 +} t_codec_stw5095_cr0_d12v; + +/* CR1 - 7 */ +typedef enum { + CODEC_STW5095_CR1_ENADCL_DISABLED, + CODEC_STW5095_CR1_ENADCL_ENABLED +} t_codec_stw5095_cr1_enadcl; + +/* CR1 - 6 */ +typedef enum { + CODEC_STW5095_CR1_ENADCR_DISABLED, + CODEC_STW5095_CR1_ENADCR_ENABLED +} t_codec_stw5095_cr1_enadcr; + +/* CR1 - 5 */ +typedef enum { + CODEC_STW5095_CR1_ENDACL_DISABLED, + CODEC_STW5095_CR1_ENDACL_ENABLED +} t_codec_stw5095_cr1_endacl; + +/* CR1 - 4 */ +typedef enum { + CODEC_STW5095_CR1_ENDACR_DISABLED, + CODEC_STW5095_CR1_ENDACR_ENABLED +} t_codec_stw5095_cr1_endacr; + +/* CR1 - 3 */ +typedef enum { + CODEC_STW5095_CR1_ENMICL_DISABLED, + CODEC_STW5095_CR1_ENMICL_ENABLED +} t_codec_stw5095_cr1_enmicl; + +/* CR1 - 2 */ +typedef enum { + CODEC_STW5095_CR1_ENMICR_DISABLED, + CODEC_STW5095_CR1_ENMICR_ENABLED +} t_codec_stw5095_cr1_enmicr; + +/* CR1 - 1 */ +typedef enum { + CODEC_STW5095_CR1_ENLINL_DISABLED, + CODEC_STW5095_CR1_ENLINL_ENABLED +} t_codec_stw5095_cr1_enlinl; + +/* CR1 - 0 */ +typedef enum { + CODEC_STW5095_CR1_ENLINR_DISABLED, + CODEC_STW5095_CR1_ENLINR_ENABLED +} t_codec_stw5095_cr1_enlinr; + +/* CR2 - 7 */ +typedef enum { + CODEC_STW5095_CR2_ENLOL_DISABLED, + CODEC_STW5095_CR2_ENLOL_ENABLED +} t_codec_stw5095_cr2_enlol; + +/* CR2 - 6 */ +typedef enum { + CODEC_STW5095_CR2_ENLOR_DISABLED, + CODEC_STW5095_CR2_ENLOR_ENABLED +} t_codec_stw5095_cr2_enlor; + +/* CR2 - 5 */ +typedef enum { + CODEC_STW5095_CR2_ENHPL_DISABLED, + CODEC_STW5095_CR2_ENHPL_ENABLED +} t_codec_stw5095_cr2_enhpl; + +/* CR2 - 4 */ +typedef enum { + CODEC_STW5095_CR2_ENHPR_DISABLED, + CODEC_STW5095_CR2_ENHPR_ENABLED +} t_codec_stw5095_cr2_enhpr; + +/* CR2 - 3 */ +typedef enum { + CODEC_STW5095_CR2_ENHPVCM_DISABLED, + CODEC_STW5095_CR2_ENHPVCM_ENABLED +} t_codec_stw5095_cr2_enhpvcm; + +/* CR2 - 2 */ +typedef enum { + CODEC_STW5095_CR2_ENLS_DISABLED, + CODEC_STW5095_CR2_ENLS_ENABLED +} t_codec_stw5095_cr2_enls; + +/* CR2 - 1 */ +typedef enum { + CODEC_STW5095_CR2_ENMIXL_DISABLED, + CODEC_STW5095_CR2_ENMIXL_ENABLED +} t_codec_stw5095_cr2_enmixl; + +/* CR2 - 0 */ +typedef enum { + CODEC_STW5095_CR2_ENMIXR_DISABLED, + CODEC_STW5095_CR2_ENMIXR_ENABLED +} t_codec_stw5095_cr2_enmixr; + +/* CR3 - 7:5 */ +typedef __u8 t_codec_stw5095_cr3_micla; + +/* CR3 - 4:0 */ +typedef __u8 t_codec_stw5095_cr3_miclg; + +/* CR4 - 7:5 */ +typedef __u8 t_codec_stw5095_cr4_micra; + +/* CR4 - 4:0 */ +typedef __u8 t_codec_stw5095_cr4_micrg; + +/* CR5 - 4:0 */ +typedef __u8 t_codec_stw5095_cr5_linlg; + +/* CR6 - 4:0 */ +typedef __u8 t_codec_stw5095_cr6_linrg; + +/* CR7 - 6:4 */ +typedef __u8 t_codec_stw5095_cr7_log; + +/* CR7 - 3:0 */ +typedef __u8 t_codec_stw5095_cr7_lsg; + +/* CR8 - 4:0 */ +typedef __u8 t_codec_stw5095_cr8_hplg; + +/* CR9 - 4:0 */ +typedef __u8 t_codec_stw5095_cr9_hprg; + +/* CR10 - 5:0 */ +typedef __u8 t_codec_stw5095_cr10_daclg; + +/* CR11 - 5:0 */ +typedef __u8 t_codec_stw5095_cr11_dacrg; + +/* CR12 - 5:0 */ +typedef __u8 t_codec_stw5095_cr12_adclg; + +/* CR13 - 5:0 */ +typedef __u8 t_codec_stw5095_cr13_adcrg; + +/* CR14 - 7 */ +typedef enum { + CODEC_STW5095_CR14_DYNC_DISABLED, + CODEC_STW5095_CR14_DYNC_ENABLED +} t_codec_stw5095_cr14_dync; + +/* CR14 - 6:4 */ +typedef __u8 t_codec_stw5095_cr14_treble; + +/* CR14 - 3:0 */ +typedef __u8 t_codec_stw5095_cr14_bass; + +/* CR15 - 4:0 */ +typedef __u8 t_codec_stw5095_cr15_da2adg; + +/* CR16 - 4:0 */ +typedef __u8 t_codec_stw5095_cr16_ad2dag; + +/* CR17 - 7 */ +typedef enum { + CODEC_STW5095_CR17_MBIAS_DISABLED, + CODEC_STW5095_CR17_MBIAS_ENABLED +} t_codec_stw5095_cr17_mbias; + +/* CR17 - 6 */ +typedef enum { + CODEC_STW5095_CR17_MBIASPD_DISABLED, + CODEC_STW5095_CR17_MBIASPD_ENABLED +} t_codec_stw5095_cr17_mbiaspd; + +/* CR17 - 5 */ +typedef enum { + CODEC_STW5095_CR17_ADMIC_DISABLED, + CODEC_STW5095_CR17_ADMIC_ENABLED +} t_codec_stw5095_cr17_admic; + +/* CR17 - 4 */ +typedef enum { + CODEC_STW5095_CR17_ADLIN_DISABLED, + CODEC_STW5095_CR17_ADLIN_ENABLED +} t_codec_stw5095_cr17_adlin; + +/* CR17 - 3 */ +typedef enum { + CODEC_STW5095_CR17_MIXMIC_DISABLED, + CODEC_STW5095_CR17_MIXMIC_ENABLED +} t_codec_stw5095_cr17_mixmic; + +/* CR17 - 2 */ +typedef enum { + CODEC_STW5095_CR17_MIXLIN_DISABLED, + CODEC_STW5095_CR17_MIXLIN_ENABLED +} t_codec_stw5095_cr17_mixlin; + +/* CR17 - 1 */ +typedef enum { + CODEC_STW5095_CR17_MIXDAC_DISABLED, + CODEC_STW5095_CR17_MIXDAC_ENABLED +} t_codec_stw5095_cr17_mixdac; + +/* CR17 - 0 */ +typedef enum { + CODEC_STW5095_CR17_MICLO_DISABLED, + CODEC_STW5095_CR17_MICLO_ENABLED +} t_codec_stw5095_cr17_miclo; + +/* CR18 - 6 */ +typedef enum { + CODEC_STW5095_CR18_IN2VCM_HIGH_IMPEDANCE_STATE, + CODEC_STW5095_CR18_IN2VCM_COMMON_MODE_VOLTAGE +} t_codec_stw5095_cr18_in2vcm; + +/* CR18 - 5 */ +typedef enum { + CODEC_STW5095_CR18_LINMUTE_DISABLED, + CODEC_STW5095_CR18_LINMUTE_ENABLED +} t_codec_stw5095_cr18_linmute; + +/* CR18 - 4:3 */ +typedef enum { + CODEC_STW5095_CR18_LINSEL_LINEIN, + CODEC_STW5095_CR18_LINSEL_AUX1, + CODEC_STW5095_CR18_LINSEL_AUX2, + CODEC_STW5095_CR18_LINSEL_AUX3 +} t_codec_stw5095_cr18_linsel; + +/* CR18 - 2 */ +typedef enum { + CODEC_STW5095_CR18_MICMUTE_DISABLED, + CODEC_STW5095_CR18_MICMUTE_ENABLED +} t_codec_stw5095_cr18_micmute; + +/* CR18 - 1:0 */ +typedef enum { + CODEC_STW5095_CR18_MICSEL_MIC, + CODEC_STW5095_CR18_MICSEL_AUX1, + CODEC_STW5095_CR18_MICSEL_AUX2, + CODEC_STW5095_CR18_MICSEL_AUX3 +} t_codec_stw5095_cr18_micsel; + +/* CR19 - 7:6 */ +typedef enum { + CODEC_STW5095_CR19_VCML_1_20V, + CODEC_STW5095_CR19_VCML_1_35V, + CODEC_STW5095_CR19_VCML_1_50V, + CODEC_STW5095_CR19_VCML_1_65V +} t_codec_stw5095_cr19_vcml; + +/* CR19 - 5 */ +typedef enum { + CODEC_STW5095_CR19_DIFFLO_SINGLE_ENDED, + CODEC_STW5095_CR19_DIFFLO_DIFFERENTIAL +} t_codec_stw5095_cr19_difflo; + +/* CR19 - 4 */ +typedef enum { + CODEC_STW5095_CR19_MUTELO_NOT_MUTED, + CODEC_STW5095_CR19_MUTELO_MUTED +} t_codec_stw5095_cr19_mutelo; + +/* CR19 - 3 */ +typedef enum { + CODEC_STW5095_CR19_MUTEHP_NOT_MUTED, + CODEC_STW5095_CR19_MUTEHP_MUTED +} t_codec_stw5095_cr19_mutehp; + +/* CR19 - 2 */ +typedef enum { + CODEC_STW5095_CR19_LSLIM_NOT_LIMITED, + CODEC_STW5095_CR19_LSLIM_LIMITED +} t_codec_stw5095_cr19_lslim; + +/* CR19 - 1:0 */ +typedef enum { + CODEC_STW5095_CR19_LSSEL_MUTELOUDSPEAKER_DRIVER, + CODEC_STW5095_CR19_LSSEL_RIGHT_CHANNEL_MIXER, + CODEC_STW5095_CR19_LSSEL_LEFT_CHANNEL_MIXER, + CODEC_STW5095_CR19_LSSEL_MONO_LEFT_PLUS_RIGHT_DIV_2_CHANNEL +} t_codec_stw5095_cr19_lssel; + +/* CR20_CR21 -16*/ +typedef __u16 t_codec_stw5095_cr20_cr21_daockf; + +/* CR23_CR24 -16*/ +typedef __u16 t_codec_stw5095_cr23_cr24_adockf; + +/* CR22 - 5 */ +typedef enum { + CODEC_STW5095_CR22_DAMAST_SLAVE_MODE, + CODEC_STW5095_CR22_DAMAST_MASTER_MODE +} t_codec_stw5095_cr22_damast; + +/* CR22 - 4 */ +typedef enum { + CODEC_STW5095_CR22_DAMASTGEN_DISABLED, + CODEC_STW5095_CR22_DAMASTGEN_ENABLED +} t_codec_stw5095_cr22_damastgen; + +/* CR22 - 3 */ +typedef enum { + CODEC_STW5095_CR22_ENDAOCK_DISABLED, + CODEC_STW5095_CR22_ENDAOCK_ENABLED +} t_codec_stw5095_cr22_endaock; + +/* CR22 - 2 */ +typedef enum { + CODEC_STW5095_CR22_DAOCK512_RATIO_IN_MASTER_MODE_256, + CODEC_STW5095_CR22_DAOCK512_RATIO_IN_MASTER_MODE_512 +} t_codec_stw5095_cr22_daock512; + +/* CR22 - 1:0 */ +typedef enum { + CODEC_STW5095_CR22_DAPCMF_RATIO_IN_PCM_MASTER_MODE_16_OR_32, + CODEC_STW5095_CR22_DAPCMF_RATIO_IN_PCM_MASTER_MODE_64, + CODEC_STW5095_CR22_DAPCMF_RATIO_IN_PCM_MASTER_MODE_128, + CODEC_STW5095_CR22_DAPCMF_RATIO_IN_PCM_MASTER_MODE_256_OR_512 +} t_codec_stw5095_cr22_dapcmf; + +/* CR25 - 5 */ +typedef enum { + CODEC_STW5095_CR25_ADMAST_SLAVE_MODE, + CODEC_STW5095_CR25_ADMAST_MASTER_MODE +} t_codec_stw5095_cr25_admast; + +/* CR25 - 4 */ +typedef enum { + CODEC_STW5095_CR25_ADMASTGEN_DISABLED, + CODEC_STW5095_CR25_ADMASTGEN_ENABLED +} t_codec_stw5095_cr25_admastgen; + +/* CR25 - 3 */ +typedef enum { + CODEC_STW5095_CR25_ENDAOCK_DISABLED, + CODEC_STW5095_CR25_ENDAOCK_ENABLED +} t_codec_stw5095_cr25_endaock; + +/* CR25 - 2 */ +typedef enum { + CODEC_STW5095_CR25_ADOCK512_RATIO_IN_MASTER_MODE_256, + CODEC_STW5095_CR25_ADOCK512_RATIO_IN_MASTER_MODE_512 +} t_codec_stw5095_cr25_adock512; + +/* CR25 - 1:0 */ +typedef enum { + CODEC_STW5095_CR25_ADPCMF_RATIO_IN_PCM_MASTER_MODE_16_OR_32, + CODEC_STW5095_CR25_ADPCMF_RATIO_IN_PCM_MASTER_MODE_64, + CODEC_STW5095_CR25_ADPCMF_RATIO_IN_PCM_MASTER_MODE_128, + CODEC_STW5095_CR25_ADPCMF_RATIO_IN_PCM_MASTER_MODE_256_OR_512 +} t_codec_stw5095_cr25_adpcmf; + +/* CR26 - 7 */ +typedef enum { + CODEC_STW5095_CR26_DACHSW_LEFT_RIGHT_CHANNEL_NOT_EXCAHANGED, + CODEC_STW5095_CR26_DACHSW_LEFT_RIGHT_CHANNEL_EXCAHANGED +} t_codec_stw5095_cr26_dachsw; + +/* CR26 - 6:4 */ +typedef enum { + CODEC_STW5095_CR26_DAFORM_DELAYED_FORMAT_I2S_COMPATIBLE, + CODEC_STW5095_CR26_DAFORM_LEFT_ALIGNED_FORMAT, + CODEC_STW5095_CR26_DAFORM_RIGHT_ALIGNED_FORMAT, + CODEC_STW5095_CR26_DAFORM_DSP_FORMAT, + CODEC_STW5095_CR26_DAFORM_SPI_FORMAT, + CODEC_STW5095_CR26_DAFORM_RESERVED1, + CODEC_STW5095_CR26_DAFORM_RESERVED2, + CODEC_STW5095_CR26_DAFORM_PCM_FORMAT_USES_LEFT_CHANNEL +} t_codec_stw5095_cr26_daform; + +/* CR26 - 3 */ +typedef enum { + CODEC_STW5095_CR26_DASPIM_TWO_WORDS, + CODEC_STW5095_CR26_DASPIM_ONE_WORDS +} t_codec_stw5095_cr26_daspim; + +/* CR26 - 2:0 */ +typedef enum { + CODEC_STW5095_CR26_DAWL_WORD_LENGTH_16, + CODEC_STW5095_CR26_DAWL_WORD_LENGTH_18, + CODEC_STW5095_CR26_DAWL_WORD_LENGTH_20, + CODEC_STW5095_CR26_DAWL_WORD_LENGTH_24, + CODEC_STW5095_CR26_DAWL_WORD_LENGTH_32 +} t_codec_stw5095_cr26_dawl; + +/* CR27 - 7 */ +typedef enum { + CODEC_STW5095_CR27_ADCHSW_LEFT_RIGHT_CHANNEL_NOT_EXCAHANGED, + CODEC_STW5095_CR27_ADCHSW_LEFT_RIGHT_CHANNEL_EXCAHANGED +} t_codec_stw5095_cr27_adchsw; + +/* CR27 - 6:4 */ +typedef enum { + CODEC_STW5095_CR27_ADFORM_DELAYED_FORMAT_I2S_COMPATIBLE, + CODEC_STW5095_CR27_ADFORM_LEFT_ALIGNED_FORMAT, + CODEC_STW5095_CR27_ADFORM_RIGHT_ALIGNED_FORMAT, + CODEC_STW5095_CR27_ADFORM_DSP_FORMAT, + CODEC_STW5095_CR27_ADFORM_SPI_FORMAT, + CODEC_STW5095_CR27_ADFORM_RESERVED1, + CODEC_STW5095_CR27_ADFORM_RESERVED2, + CODEC_STW5095_CR27_ADFORM_PCM_FORMAT_USES_LEFT_CHANNEL +} t_codec_stw5095_cr27_adform; + +/* CR27 - 3 */ +typedef enum { + CODEC_STW5095_CR27_ADSPIM_TWO_WORDS, + CODEC_STW5095_CR27_ADSPIM_ONE_WORDS +} t_codec_stw5095_cr27_adspim; + +/* CR27 - 2:0 */ +typedef enum { + CODEC_STW5095_CR27_ADWL_WORD_LENGTH_16, + CODEC_STW5095_CR27_ADWL_WORD_LENGTH_18, + CODEC_STW5095_CR27_ADWL_WORD_LENGTH_20, + CODEC_STW5095_CR27_ADWL_WORD_LENGTH_24, + CODEC_STW5095_CR27_ADWL_WORD_LENGTH_32 +} t_codec_stw5095_cr27_adwl; + +/* CR28 - 7 */ +typedef enum { + CODEC_STW5095_CR28_AMCKINV_NOT_INVERTED, + CODEC_STW5095_CR28_AMCKINV_INVERTED +} t_codec_stw5095_cr28_amckinv; + +/* CR28 - 6 */ +typedef enum { + CODEC_STW5095_CR28_DACKP_DA_CK_NOT_INVERTED, + CODEC_STW5095_CR28_DACKP_DA_CK_INVERTED +} t_codec_stw5095_cr28_dackp; + +/* CR28 - 5 */ +typedef enum { + CODEC_STW5095_CR28_DASYNCP_NON_DELAYED_FORMAT_OR_DA_SYNC_POLARITY_NOT_INVERTED, + CODEC_STW5095_CR28_DASYNCP_DELAYED_FORMAT_OR_DA_SYNC_POLARITY_INVERTED +} t_codec_stw5095_cr28_dasyncp; + +/* CR28 - 4 */ +typedef enum { + CODEC_STW5095_CR28_DAMONO_STEREO_MODE, + CODEC_STW5095_CR28_DAMONO_MONO_MODE +} t_codec_stw5095_cr28_damono; + +/* CR28 - 3 */ +typedef enum { + CODEC_STW5095_CR28_ADCKP_AD_CK_NOT_INVERTED, + CODEC_STW5095_CR28_ADCKP_AD_CK_INVERTED +} t_codec_stw5095_cr28_adckp; + +/* CR28 - 2 */ +typedef enum { + CODEC_STW5095_CR28_ADSYNCP_NON_DELAYED_FORMAT_OR_AD_SYNC_POLARITY_NOT_INVERTED, + CODEC_STW5095_CR28_ADSYNCP_DELAYED_FORMAT_OR_AD_SYNC_POLARITY_INVERTED +} t_codec_stw5095_cr28_adsyncp; + +/* CR28 - 1 */ +typedef enum { + CODEC_STW5095_CR28_ADMONO_STEREO_MODE, + CODEC_STW5095_CR28_ADMONO_MONO_MODE +} t_codec_stw5095_cr28_admono; + +/* CR28 - 0 */ +typedef enum { + CODEC_STW5095_CR28_ADHIZ_AD_DATA_FORCED_TO_ZERO, + CODEC_STW5095_CR28_ADHIZ_AD_DATA_IN_HIGH_IMPEDANCE +} t_codec_stw5095_cr28_adhiz; + +/* CR29 - 6 */ +typedef enum { + CODEC_STW5095_CR29_DAVOICE_AUDIO_FILTER_ENABLED, + CODEC_STW5095_CR29_DAVOICE_VOICE_RX_FILTER_ENABLED +} t_codec_stw5095_cr29_davoice; + +/* CR29 - 5 */ +typedef enum { + CODEC_STW5095_CR29_DA96K_DATA_RATE_RANGE_8_TO_48KHZ, + CODEC_STW5095_CR29_DA96K_DATA_RATE_RANGE_88_TO_96KHZ +} t_codec_stw5095_cr29_da96k; + +/* CR29 - 4 */ +typedef enum { + CODEC_STW5095_CR29_RXNH_HIGH_PASS_VOICE_FILTER_DISABLED, + CODEC_STW5095_CR29_RXNH_HIGH_PASS_VOICE_FILTER_ENABLED +} t_codec_stw5095_cr29_rxnh; + +/* CR29 - 3 */ +typedef enum { + CODEC_STW5095_CR29_ADVOICE_AUDIO_FILTER_ENABLED, + CODEC_STW5095_CR29_ADVOICE_VOICE_TX_FILTER_ENABLED +} t_codec_stw5095_cr29_advoice; + +/* CR29 - 2 */ +typedef enum { + CODEC_STW5095_CR29_AD96K_DATA_RATE_RANGE_8_TO_48KHZ, + CODEC_STW5095_CR29_AD96K_DATA_RATE_RANGE_88_TO_96KHZ +} t_codec_stw5095_cr29_ad96k; + +/* CR29 - 1 */ +typedef enum { + CODEC_STW5095_CR29_ADNH_AUDIO_DC_FILTER_DISABLED, + CODEC_STW5095_CR29_ADNH_AUDIO_DC_FILTER_ENABLED +} t_codec_stw5095_cr29_adnh; + +/* CR29 - 0 */ +typedef enum { + CODEC_STW5095_CR29_TXNH_HIGH_PASS_VOICE_FILTER_DISABLED, + CODEC_STW5095_CR29_TXNH_HIGH_PASS_VOICE_FILTER_ENABLED +} t_codec_stw5095_cr29_txnh; + +/* CR30 - 7 */ +typedef enum { + CODEC_STW5095_CR30_SWRES_NON_RESET_STATE, + CODEC_STW5095_CR30_SWRES_SOFTWARE_RESET +} t_codec_stw5095_cr30_swres; + +/* CR30 - 3 */ +typedef enum { + CODEC_STW5095_CR30_AMCKSIN_SQUARE_WAVE, + CODEC_STW5095_CR30_AMCKSIN_SINUSOID +} t_codec_stw5095_cr30_amcksin; + +/* CR30 - 2:0 */ +typedef enum { + CODEC_STW5095_CR30_CKRANGE_4_TO_6_MHZ, + CODEC_STW5095_CR30_CKRANGE_6_TO_8_MHZ, + CODEC_STW5095_CR30_CKRANGE_8_TO_12_MHZ, + CODEC_STW5095_CR30_CKRANGE_12_TO_16_MHZ, + CODEC_STW5095_CR30_CKRANGE_16_TO_24_MHZ, + CODEC_STW5095_CR30_CKRANGE_24_TO_32_MHZ, + CODEC_STW5095_CR30_CKRANGE_RESERVED1, + CODEC_STW5095_CR30_CKRANGE_RESERVED2 +} t_codec_stw5095_cr30_ckrange; + +/* CR31 - 7 */ +typedef enum { + CODEC_STW5095_CR31_VLSHEN_MASKED, + CODEC_STW5095_CR31_VLSHEN_ENABLED +} t_codec_stw5095_cr31_vlshen; + +/* CR31 - 6 */ +typedef enum { + CODEC_STW5095_CR31_PUSHBEN_MASKED, + CODEC_STW5095_CR31_PUSHBEN_ENABLED +} t_codec_stw5095_cr31_pushben; + +/* CR31 - 5 */ +typedef enum { + CODEC_STW5095_CR31_HSDETEN_MASKED, + CODEC_STW5095_CR31_HSDETEN_ENABLED +} t_codec_stw5095_cr31_hsdeten; + +/* CR31 - 4 */ +typedef enum { + CODEC_STW5095_CR31_VLSHMSK_MASKED, + CODEC_STW5095_CR31_VLSHMSK_ENABLED +} t_codec_stw5095_cr31_vlshmsk; + +/* CR31 - 3 */ +typedef enum { + CODEC_STW5095_CR31_PUSHBMSK_MASKED, + CODEC_STW5095_CR31_PUSHBMSK_ENABLED +} t_codec_stw5095_cr31_pushbmsk; + +/* CR31 - 2 */ +typedef enum { + CODEC_STW5095_CR31_HSDETMSK_MASKED, + CODEC_STW5095_CR31_HSDETMSK_ENABLED +} t_codec_stw5095_cr31_hsdetmsk; + +/* CR31 - 1 */ +typedef enum { + CODEC_STW5095_CR31_OVFMSK_MASKED, + CODEC_STW5095_CR31_OVFMSK_ENABLED +} t_codec_stw5095_cr31_ovfmsk; + +/* CR31 - 0 */ +typedef enum { + CODEC_STW5095_CR31_PORMSK_MASKED, + CODEC_STW5095_CR31_PORMSK_ENABLED +} t_codec_stw5095_cr31_pormsk; + +/* CR32 - Read only */ +/* CR32 - 7 */ +typedef enum { + CODEC_STW5095_CR32_VLSH_VCCLS_BELOW_4_0V, + CODEC_STW5095_CR32_VLSH_VCCLS_ABOVE_4_2V +} t_codec_stw5095_cr32_vlsh; + +/* CR32 - 6 */ +typedef enum { + CODEC_STW5095_CR32_PUSHB_HEADSET_BUTTON_RELEASED, + CODEC_STW5095_CR32_PUSHB_HEADSET_BUTTON_PRESSED +} t_codec_stw5095_cr32_pushb; + +/* CR32 - 5 */ +typedef enum { + CODEC_STW5095_CR32_HSDET_HEADSET_CONNECTOR_NOT_INSERTED, + CODEC_STW5095_CR32_HSDET_HEADSET_CONNECTOR_INSERTED +} t_codec_stw5095_cr32_hsdet; + +/* CR32 - 4 */ +typedef enum { + CODEC_STW5095_CR32_VLSHEV_VLSH_BIT_NOT_CHANGED, + CODEC_STW5095_CR32_VLSHEV_VLSH_BIT_CHANGED +} t_codec_stw5095_cr32_vlshev; + +/* CR32 - 3 */ +typedef enum { + CODEC_STW5095_CR32_PUSHBEV_HEADSET_BUTTON_STATUS_NOT_CHANGED, + CODEC_STW5095_CR32_PUSHBEV_HEADSET_BUTTON_STATUS_CHANGED +} t_codec_stw5095_cr32_pushbev; + +/* CR32 - 2 */ +typedef enum { + CODEC_STW5095_CR32_HSDETEV_HEADSET_CONNECTOR_STATUS_NOT_CHANGED, + CODEC_STW5095_CR32_HSDETEV_HEADSET_CONNECTOR_STATUS_CHANGED +} t_codec_stw5095_cr32_hsdetev; + +/* CR32 - 1 */ +typedef enum { + CODEC_STW5095_CR32_OVFEV_NO_AUDIO_DATA_OVERFLOW, + CODEC_STW5095_CR32_OVFEV_AUDIO_DATA_OVERFLOW +} t_codec_stw5095_cr32_ovfev; + +/* CR32 - 0 */ +typedef enum { + CODEC_STW5095_CR32_POREV_NOT_RESET_BY_POWER_ON_RESET, + CODEC_STW5095_CR32_POREV_RESET_BY_POWER_ON_RESET +} t_codec_stw5095_cr32_porev; + +/* CR33 - 5 */ +typedef enum { + CODEC_STW5095_CR33_SPIOHIZ_OUT_PIN_SET_TO_ZERO_WHEN_INACTIVE, + CODEC_STW5095_CR33_SPIOHIZ_OUT_PIN_HIGH_IMPEDANCE_WHEN_INACTIVE +} t_codec_stw5095_cr33_spiohiz; + +/* CR33 - 4:3 */ +typedef enum { + CODEC_STW5095_CR33_SPIOSEL_NO_OUTPUT, + CODEC_STW5095_CR33_SPIOSEL_OUTPUT_SENT_TO_IRQ_PIN, + CODEC_STW5095_CR33_SPIOSEL_OUTPUT_SENT_TO_DA_OCK_PIN, + CODEC_STW5095_CR33_SPIOSEL_OUTPUT_SENT_TO_AD_OCK_PIN +} t_codec_stw5095_cr33_spiosel; + +/* CR33 - 2 */ +typedef enum { + CODEC_STW5095_CR33_IRQCMOS_IRQ_PIN_ACTIVE, + CODEC_STW5095_CR33_IRQCMOS_IRQ_PIN_PULL_DOWN +} t_codec_stw5095_cr33_irqcmos; + +/* CR33 - 1 */ +typedef enum { + CODEC_STW5095_CR33_OVFDA_OVERFLOW_IN_DA_PATH, + CODEC_STW5095_CR33_OVFDA_NO_OVERFLOW_IN_DA_PATH +} t_codec_stw5095_cr33_ovfda; + +/* CR33 - 0 */ +typedef enum { + CODEC_STW5095_CR33_OVFAD_OVERFLOW_IN_AD_PATH, + CODEC_STW5095_CR33_OVFAD_NO_OVERFLOW_IN_AD_PATH +} t_codec_stw5095_cr33_ovfad; + +/*configuration structure for Codec*/ +typedef struct { + /* CR0 */ + t_codec_stw5095_cr0_powerup cr0_powerup; + t_codec_stw5095_cr0_enana cr0_enana; + t_codec_stw5095_cr0_enamck cr0_enamck; + t_codec_stw5095_cr0_enosc cr0_enosc; + t_codec_stw5095_cr0_enpll cr0_enpll; + t_codec_stw5095_cr0_enhsd cr0_enhsd; + t_codec_stw5095_cr0_a24v cr0_a24v; + t_codec_stw5095_cr0_d12v cr0_d12v; + + /* CR1 */ + t_codec_stw5095_cr1_enadcl cr1_enadcl; + t_codec_stw5095_cr1_enadcr cr1_enadcr; + t_codec_stw5095_cr1_endacl cr1_endacl; + t_codec_stw5095_cr1_endacr cr1_endacr; + t_codec_stw5095_cr1_enmicl cr1_enmicl; + t_codec_stw5095_cr1_enmicr cr1_enmicr; + t_codec_stw5095_cr1_enlinl cr1_enlinl; + t_codec_stw5095_cr1_enlinr cr1_enlinr; + + /* CR2 */ + t_codec_stw5095_cr2_enlol cr2_enlol; + t_codec_stw5095_cr2_enlor cr2_enlor; + t_codec_stw5095_cr2_enhpl cr2_enhpl; + t_codec_stw5095_cr2_enhpr cr2_enhpr; + t_codec_stw5095_cr2_enhpvcm cr2_enhpvcm; + t_codec_stw5095_cr2_enls cr2_enls; + t_codec_stw5095_cr2_enmixl cr2_enmixl; + t_codec_stw5095_cr2_enmixr cr2_enmixr; + + /* CR3 */ + t_codec_stw5095_cr3_micla cr3_micla; + t_codec_stw5095_cr3_miclg cr3_miclg; + + /* CR4 */ + t_codec_stw5095_cr4_micra cr4_micra; + t_codec_stw5095_cr4_micrg cr4_micrg; + + /* CR5 */ + t_codec_stw5095_cr5_linlg cr5_linlg; + + /* CR6 */ + t_codec_stw5095_cr6_linrg cr6_linrg; + + /* CR7 */ + t_codec_stw5095_cr7_log cr7_log; + t_codec_stw5095_cr7_lsg cr7_lsg; + + /* CR8 */ + t_codec_stw5095_cr8_hplg cr8_hplg; + + /* CR9 */ + t_codec_stw5095_cr9_hprg cr9_hprg; + + /* CR10 */ + t_codec_stw5095_cr10_daclg cr10_daclg; + + /* CR11 */ + t_codec_stw5095_cr11_dacrg cr11_dacrg; + + /* CR12 */ + t_codec_stw5095_cr12_adclg cr12_adclg; + + /* CR13 */ + t_codec_stw5095_cr13_adcrg cr13_adcrg; + + /* CR14 */ + t_codec_stw5095_cr14_dync cr14_dync; + t_codec_stw5095_cr14_treble cr14_treble; + t_codec_stw5095_cr14_bass cr14_bass; + + /* CR15 */ + t_codec_stw5095_cr15_da2adg cr15_da2adg; + + /* CR16 */ + t_codec_stw5095_cr16_ad2dag cr16_ad2dag; + + /* CR17 */ + t_codec_stw5095_cr17_mbias cr17_mbias; + t_codec_stw5095_cr17_mbiaspd cr17_mbiaspd; + t_codec_stw5095_cr17_admic cr17_admic; + t_codec_stw5095_cr17_adlin cr17_adlin; + t_codec_stw5095_cr17_mixmic cr17_mixmic; + t_codec_stw5095_cr17_mixlin cr17_mixlin; + t_codec_stw5095_cr17_mixdac cr17_mixdac; + t_codec_stw5095_cr17_miclo cr17_miclo; + + /* CR18 */ + t_codec_stw5095_cr18_in2vcm cr18_in2vcm; + t_codec_stw5095_cr18_linmute cr18_linmute; + t_codec_stw5095_cr18_linsel cr18_linsel; + t_codec_stw5095_cr18_micmute cr18_micmute; + t_codec_stw5095_cr18_micsel cr18_micsel; + + /* CR19 */ + t_codec_stw5095_cr19_vcml cr19_vcml; + t_codec_stw5095_cr19_difflo cr19_difflo; + t_codec_stw5095_cr19_mutelo cr19_mutelo; + t_codec_stw5095_cr19_mutehp cr19_mutehp; + t_codec_stw5095_cr19_lslim cr19_lslim; + t_codec_stw5095_cr19_lssel cr19_lssel; + + /* CR20_CR21 */ + t_codec_stw5095_cr20_cr21_daockf cr20_cr21_daockf; + + /* CR23_CR24 */ + t_codec_stw5095_cr23_cr24_adockf cr23_cr24_adockf; + + /* CR22 */ + t_codec_stw5095_cr22_damast cr22_damast; + t_codec_stw5095_cr22_damastgen cr22_damastgen; + t_codec_stw5095_cr22_endaock cr22_endaock; + t_codec_stw5095_cr22_daock512 cr22_daock512; + t_codec_stw5095_cr22_dapcmf cr22_dapcmf; + + /* CR25 */ + t_codec_stw5095_cr25_admast cr25_admast; + t_codec_stw5095_cr25_admastgen cr25_admastgen; + t_codec_stw5095_cr25_endaock cr25_endaock; + t_codec_stw5095_cr25_adock512 cr25_adock512; + t_codec_stw5095_cr25_adpcmf cr25_adpcmf; + + /* CR26 */ + t_codec_stw5095_cr26_dachsw cr26_dachsw; + t_codec_stw5095_cr26_daform cr26_daform; + t_codec_stw5095_cr26_daspim cr26_daspim; + t_codec_stw5095_cr26_dawl cr26_dawl; + + /* CR27 */ + t_codec_stw5095_cr27_adchsw cr27_adchsw; + t_codec_stw5095_cr27_adform cr27_adform; + t_codec_stw5095_cr27_adspim cr27_adspim; + t_codec_stw5095_cr27_adwl cr27_adwl; + + /* CR28 */ + t_codec_stw5095_cr28_amckinv cr28_amckinv; + t_codec_stw5095_cr28_dackp cr28_dackp; + t_codec_stw5095_cr28_dasyncp cr28_dasyncp; + t_codec_stw5095_cr28_damono cr28_damono; + t_codec_stw5095_cr28_adckp cr28_adckp; + t_codec_stw5095_cr28_adsyncp cr28_adsyncp; + t_codec_stw5095_cr28_admono cr28_admono; + t_codec_stw5095_cr28_adhiz cr28_adhiz; + + /* CR29 */ + t_codec_stw5095_cr29_davoice cr29_davoice; + t_codec_stw5095_cr29_da96k cr29_da96k; + t_codec_stw5095_cr29_rxnh cr29_rxnh; + t_codec_stw5095_cr29_advoice cr29_advoice; + t_codec_stw5095_cr29_ad96k cr29_ad96k; + t_codec_stw5095_cr29_adnh cr29_adnh; + t_codec_stw5095_cr29_txnh cr29_txnh; + + /* CR30 */ + t_codec_stw5095_cr30_swres cr30_swres; + t_codec_stw5095_cr30_amcksin cr30_amcksin; + t_codec_stw5095_cr30_ckrange cr30_ckrange; + + /* CR31 */ + t_codec_stw5095_cr31_vlshen cr31_vlshen; + t_codec_stw5095_cr31_pushben cr31_pushben; + t_codec_stw5095_cr31_hsdeten cr31_hsdeten; + t_codec_stw5095_cr31_vlshmsk cr31_vlshmsk; + t_codec_stw5095_cr31_pushbmsk cr31_pushbmsk; + t_codec_stw5095_cr31_hsdetmsk cr31_hsdetmsk; + t_codec_stw5095_cr31_ovfmsk cr31_ovfmsk; + t_codec_stw5095_cr31_pormsk cr31_pormsk; + + /* CR32 */ + t_codec_stw5095_cr32_vlsh cr32_vlsh; + t_codec_stw5095_cr32_pushb cr32_pushb; + t_codec_stw5095_cr32_hsdet cr32_hsdet; + t_codec_stw5095_cr32_vlshev cr32_vlshev; + t_codec_stw5095_cr32_pushbev cr32_pushbev; + t_codec_stw5095_cr32_hsdetev cr32_hsdetev; + t_codec_stw5095_cr32_ovfev cr32_ovfev; + t_codec_stw5095_cr32_porev cr32_porev; + + /* CR33 */ + t_codec_stw5095_cr33_spiohiz cr33_spiohiz; + t_codec_stw5095_cr33_spiosel cr33_spiosel; + t_codec_stw5095_cr33_irqcmos cr33_irqcmos; + t_codec_stw5095_cr33_ovfda cr33_ovfda; + t_codec_stw5095_cr33_ovfad cr33_ovfad; +} t_codec_configuration; + +typedef struct { + t_acodec_user cur_user; + __u16 slave_address_of_codec_on_i2c; + t_codec_direction codec_direction; + t_codec_mode codec_mode_in; + t_codec_mode codec_mode_out; + + t_codec_sample_frequency record_sample_frequency; + t_codec_sample_frequency play_sample_frequency; + + t_codec_input_select codec_src; + t_codec_output_select codec_dest; + + __u8 in_left_volume; + __u8 in_right_volume; + __u8 out_left_volume; + __u8 out_right_volume; + + __u8 power_down_level; + + t_codec_device_internal_pll codec_device_internal_pll; + __u32 codec_input_frequency; /* in KHz */ + t_codec_configuration codec_configuration; /* variable size */ +} t_codec_system_context; + +#endif /* _NOMADIK_ACODEC_STW5095_H_ */ --- /dev/null +++ linux-2.6.20/include/asm-arm/arch-nomadik/sva.h @@ -0,0 +1,43 @@ +/*--------------------------------------------------------------------------------------------------*/ +/*© copyright STMicroelectronics, 2007. */ +/* */ +/*This program is free software; you can redistribute it and/or modify it under */ +/*the terms of the GNU General Public License as published by the Free */ +/*Software Foundation; either version 2.1 of the License, or (at your option) */ +/*any later version. */ +/* */ +/*This program is distributed in the hope that it will be useful, but WITHOUT */ +/*ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ +/* the GNU General Public License for more details. */ +/* */ +/*You should have received a copy of the GNU General Public License */ +/*along with this program. If not, see . */ +/*--------------------------------------------------------------------------------------------------*/ + + + +typedef enum { + IRP_CAMERA_SENSOR_CCIR, + IRP_CAMERA_SENSOR_CCP0, + IRP_CAMERA_SENSOR_CCP1, +} irp_sensor_t; + +struct sva_board { + struct clcd_fb *(*get_paneltype) (void); + int (*camera_init) (void); + int (*camera_gpio_init) (void); + void (*camera_deinit) (void); + int (*denc_init) (int); + int (*denc_deinit) (void); + int (*enable_synchro) (void); + void (*disable_synchro) (void); + dma_addr_t init_bus_address; + void *init_logical_address; + int (*sensor_init)(irp_sensor_t sensor); + int (*sensor_gpio_init)(irp_sensor_t sensor); + int (*sensor_gpio_deinit)(irp_sensor_t sensor); + int (*sensor_shutdown)(irp_sensor_t sensor); +}; + + --- /dev/null +++ linux-2.6.20/include/asm-arm/arch-nomadik/system.h @@ -0,0 +1,62 @@ +/* + * linux/include/asm-arm/arch-nomadik/system.h + * + * Copyright (C) 1999 ARM Limited + * Copyright (C) 2000 Deep Blue Solutions Ltd + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifndef __ASM_ARCH_SYSTEM_H +#define __ASM_ARCH_SYSTEM_H + +#include +#include +static inline void arch_idle(void) +{ + /* + * This should do all the clock switching + * and wait for interrupt tricks + */ + cpu_do_idle(); +} + +static inline void arch_reset(char mode) +{ + volatile unsigned long *psrc_cr = + (volatile unsigned long *)IO_ADDRESS(NOMADIK_SRC_BASE); + volatile unsigned long *src_rstsr; + +#if defined (CONFIG_NOMADIK_NHK15) + t_STMPE2401_error retval = STMPE2401_OK; + //fix for soft reboot + retval = STMPE2401_reboot(); + + if(retval != STMPE2401_OK) + { + printk("Couldn't reboot the STMPE0 device\n"); + return; + } +#endif + + src_rstsr = psrc_cr + 6; + + /* + * Writing anything in Reset status register will do the soft reset + */ + + *(src_rstsr) = 1; +} + +#endif --- /dev/null +++ linux-2.6.20/include/asm-arm/arch-nomadik/timex.h @@ -0,0 +1,71 @@ +/* + * linux/include/asm-arm/arch-nomadik/timex.h + * + * Nomadik architecture timex specifications + * + * Copyright (C) 1999 ARM Limited + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __ASM_ARCH_TIMEX_H +#define __ASM_ARCH_TIMEX_H + +#define CLOCK_TICK_RATE (2400000 ) + +typedef volatile struct { + __u32 tmr_imsc; /* @0 */ + __u32 tmr_ris; /* @4 */ + __u32 tmr_mis; /* @8 */ + __u32 tmr_icr; /* @12 */ + + __u32 tmr_load1; /* @16 */ + __u32 tmr_value1; /* @20 */ + __u32 tmr_control1; /* @24 */ + __u32 tmr_bgload1; /* @28 */ + + __u32 tmr_load2; /* @32 */ + __u32 tmr_value2; /* @36 */ + __u32 tmr_control2; /* @40 */ + __u32 tmr_bgload2; /* @44 */ + + __u32 tmr_load3; /* @48 */ + __u32 tmr_value3; /* @52 */ + __u32 tmr_control3; /* @56 */ + __u32 tmr_bgload3; /* @60 */ + + __u32 tmr_load4; /* @64 */ + __u32 tmr_value4; /* @68 */ + __u32 tmr_control4; /* @72 */ + __u32 tmr_bgload4; /* @76 */ + + __u32 tmr_unused1[(3840 - 80) / sizeof(__u32)]; + + __u32 tmr_itcr; /* @3840 */ + __u32 tmr_itop; /* @3844 */ + + __u32 tmr_unused2[(4064 - 3848) / sizeof(__u32)]; + + __u32 tmr_periph_id0; /* @4064 */ + __u32 tmr_periph_id1; /* @4068 */ + __u32 tmr_periph_id2; /* @4072 */ + __u32 tmr_periph_id3; /* @4076 */ + __u32 tmr_pcell0; /* @4080 */ + __u32 tmr_pcell1; /* @4084 */ + __u32 tmr_pcell2; /* @4088 */ + __u32 tmr_pcell3; /* @4092 */ +} +mtu_struct_t; +#endif --- /dev/null +++ linux-2.6.20/include/asm-arm/arch-nomadik/touchp.h @@ -0,0 +1,145 @@ +/* + * linux/include/asm-arm/arch-nomadik/touchp.h + * + * Copyright (C) STMicroelectronics + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/****************************************************************************** + * C STMicroelectronics + *----------------------------------------------------------------------------- + * + * Purpose : Basic definitions for Nomadik Touchpanel Driver + * + *****************************************************************************/ + +#ifndef _TOUCHP_NOMADIK_H +#define _TOUCHP_NOMADIK_H + +#include +#include + +/* Touchpanel Version 4.0.0 */ +#define TOUCHP_VER_X 4 +#define TOUCHP_VER_Y 0 +#define TOUCHP_VER_Z 0 + +#define TPDRVNAME "touchpanel" + +/* Define the readings we are to take per second (default to 50) */ +#define SAMPLES_PER_SECOND 100 +#define POLL_SAMPLES_PER_SECOND 10 /*used to decide touchp poll interval */ +#define INTR_LOCKBIT 0 /*bit used for interrupt locking */ + +/* + * Below constants are responsible for overall touch screen performanence + * These are tuned for touchpannel performanence on NDK10 + */ +#define MAX_TS_DATA 16 /*Size of circular touch event buffer */ +#define SAMP_AVG 4 /*Total number of samples for avg */ +#define NU_AVG_X 40 /*max |x-x_avg| value to consider new reading */ +#define NU_AVG_Y 40 /*max |y-y_avg| value to consider new y reading */ +#define JIT_X 4 /*max allowed jitter in x reading */ +#define JIT_Y 4 /*max allowed jitter in y reading */ +#define SSP_TARGET_FREQ 31250 /*freq in Hz @which SSP to be clocked */ + +#if !defined(FALSE) && !defined(TRUE) +typedef enum { FALSE, TRUE } t_bool; + +#else /* FALSE & TRUE already defined */ +typedef enum { BOOL_FALSE, BOOL_TRUE } t_bool; + +#endif /* !defined(FALSE) && !defined(TRUE) */ + +typedef char t_TP_VERSION[12]; + +struct t_adsContext; + +struct touchp_device { + int (*ssp_init) (struct t_adsContext * p_adsContext); + gpio_error(*gpio_init) (struct t_adsContext * p_adsContext); + gpio_error(*gpio_exit) (struct t_adsContext * p_adsContext); + t_bool(*pdown) (struct t_adsContext * p_adsContext); + void (*pirq_en) (struct t_adsContext * p_adsContext); + void (*pirq_dis) (struct t_adsContext * p_adsContext); + void (*cs_en) (void); + void (*cs_dis) (void); + u8 samples; + u8 pollsamples; +}; + +struct nmdk_tp_evnt { + t_bool p; + unsigned short x; + unsigned short y; +}; + +struct t_adsContext { + int irq; + int mode; + struct fasync_struct *fasync; + struct completion complete; + struct task_struct *rtask; + wait_queue_head_t read_wait; + wait_queue_head_t irq_wait; + unsigned long lockbits; + int tsDataHead; + int tsDataTail; + rwlock_t tsData_lock; + struct spi_master *tp_master; + struct spi_board_info *tp_board_info; + struct spi_device *tp_spi; + struct spi_transfer *tp_xfer; + struct spi_message *tp_msg; + struct touchp_device *board; + u32 ssp_wrbuf[4]; + u32 ssp_rdbuf[4]; + struct work_struct tp_work; + struct input_dev *input; + struct nmdk_tp_evnt old_event; + struct nmdk_tp_evnt new_event; + t_bool debounce_flag; + u16 last_x; + u16 last_y; + u16 x_avg; + u16 y_avg; + u16 x_ret; + u16 y_ret; + u16 x_data_q[SAMP_AVG]; + u16 y_data_q[SAMP_AVG]; + u16 tail; + + +}; + +/* IOCTL definitions */ +#define ADS_784X_IOC_MAGIC 'f' +#define TP_GET_VERSION _IOR(ADS_784X_IOC_MAGIC, 80, t_TP_VERSION) +#define TP_GET_PARMS _IOR(ADS_784X_IOC_MAGIC, 81, t_TP_PARMS) +#define TP_SET_PARMS _IOW(ADS_784X_IOC_MAGIC, 82, t_TP_PARMS) +#define TP_DATA_FLUSH _IO(ADS_784X_IOC_MAGIC, 83) + +/* board specific function declaration */ +extern int nomadik_tp_ssp_board_init(struct t_adsContext *p_adsContext); +extern gpio_error nomadik_tp_gpio_board_init(struct t_adsContext *p_adsContext); +extern gpio_error nomadik_tp_gpio_board_exit(struct t_adsContext *p_adsContext); +extern t_bool nomadik_tp_pen_down(struct t_adsContext *p_adsContext); +extern void nomadik_tp_pen_down_irq_enable(struct t_adsContext *p_adsContext); +extern void nomadik_tp_pen_down_irq_disable(struct t_adsContext *p_adsContext); +extern void nomadik_tp_spi_cs_disable(void); +extern void nomadik_tp_spi_cs_enable(void); + +#endif /* _NOMADIK_TP_h */ --- /dev/null +++ linux-2.6.20/include/asm-arm/arch-nomadik/touchp2003.h @@ -0,0 +1,42 @@ +/* + * linux/include/asm-arm/arch-nomadik/touchp2003.h + * + * Copyright (C) STMicroelectronics + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/****************************************************************************** + * C STMicroelectronics + *----------------------------------------------------------------------------- + * + * Purpose : Basic definitions for Nomadik Touchpanel Driver + * + *****************************************************************************/ + +#ifndef _TOUCHP_NOMADIK_TSC2003_H +#define _TOUCHP_NOMADIK_TSC2003_H + + +struct touchp_tsc2003_device{ + int (*irq_init)(void (*callback)(void* parameter), void * p); + int (*irq_exit)(void); + int (*pirq_en) (void); + int (*pirq_dis)(void); + int (*pirq_ack)(void); + int (*pirq_read_val)(unsigned char * value); +}; + +#endif /* _NOMADIK_TP_h */ --- /dev/null +++ linux-2.6.20/include/asm-arm/arch-nomadik/udc.h @@ -0,0 +1,490 @@ +//#define DEBUG_LEVEL 1 +#undef DEBUG_LEVEL +#ifdef DEBUG_LEVEL +#define DBG(level, format, arg...) \ + do {\ + if ( level <= g_debug_level ) \ + printk(KERN_ERR "%s:%s: " format "\n" , __FILE__, __FUNCTION__ , ## arg); \ + }while(0) +#else + #define DBG(level, format, arg...) do { } while(0) +#endif + + +#define ERR(format, arg...) \ +printk(KERN_ERR "%s:%s: " format "\n" , __FILE__, __FUNCTION__ , ## arg) + +#define WARN(format, arg...) \ + printk(KERN_WARNING "%s:%s: " format "\n" , __FILE__, __FUNCTION__ , ## arg) + +#define INFO(format, arg...) \ + printk(KERN_INFO "%s:%s: " format "\n" , __FILE__, __FUNCTION__ , ## arg) + +#define DMA_ADDR_INVALID (~(dma_addr_t)0) + +#define MUSB_MAX_USB_ENDS 16 + +#define MUSB_END0_FIFOSIZE 64 /* this is non-configurable */ + +#ifndef MUSB_C_NUM_EPS +#define MUSB_C_NUM_EPS ((uint8_t)16) +#endif + +#ifndef MUSB_MAX_END0_PACKET +#define MUSB_MAX_END0_PACKET ((uint16_t)MUSB_END0_FIFOSIZE) +#endif + +#define MUSB_END0_START 0x0 +#define MUSB_END0_OUT 0x2 +#define MUSB_END0_IN 0x4 +#define MUSB_END0_STATUS 0x8 + +#define MUSB_END0_STAGE_SETUP 0x0 +#define MUSB_END0_STAGE_TX 0x2 +#define MUSB_END0_STAGE_RX 0x4 +#define MUSB_END0_STAGE_STATUSIN 0x8 +#define MUSB_END0_STAGE_STATUSOUT 0xf +#define MUSB_END0_STAGE_STALL_BIT 0x10 + + +/* + * MUSBMHDRC Register map + */ + +/* Common USB registers */ + +#define MUSB_O_HDRC_FADDR 0x00 /* 8-bit */ +#define MUSB_O_HDRC_POWER 0x01 /* 8-bit */ + +#define MUSB_O_HDRC_INTRTX 0x02 /* 16-bit */ +#define MUSB_O_HDRC_INTRRX 0x04 +#define MUSB_O_HDRC_INTRTXE 0x06 +#define MUSB_O_HDRC_INTRRXE 0x08 +#define MUSB_O_HDRC_INTRUSB 0x0A /* 8 bit */ +#define MUSB_O_HDRC_INTRUSBE 0x0B /* 8 bit */ +#define MUSB_O_HDRC_FRAME 0x0C +#define MUSB_O_HDRC_INDEX 0x0E /* 8 bit */ +#define MUSB_O_HDRC_TESTMODE 0x0F /* 8 bit */ + + +/* Additional Control Registers */ + +#define MUSB_O_HDRC_DEVCTL 0x60 /* 8 bit */ + +/* These are actually indexed: */ +#define MUSB_O_HDRC_TXFIFOSZ 0x62 /* 8-bit (see masks) */ +#define MUSB_O_HDRC_RXFIFOSZ 0x63 /* 8-bit (see masks) */ +#define MUSB_O_HDRC_TXFIFOADD 0x64 /* 16-bit offset shifted right 3 */ +#define MUSB_O_HDRC_RXFIFOADD 0x66 /* 16-bit offset shifted right 3 */ + + + +#define MUSB_O_HDRC_TOPCONTROL 0x204 /* top control register 16-bit */ + +/* offsets to registers in flat model */ +#define MUSB_O_HDRC_TXMAXP 0x00 +#define MUSB_O_HDRC_TXCSR 0x02 +#define MUSB_O_HDRC_CSR0 MUSB_O_HDRC_TXCSR /* re-used for EP0 */ +#define MUSB_O_HDRC_RXMAXP 0x04 +#define MUSB_O_HDRC_RXCSR 0x06 +#define MUSB_O_HDRC_RXCOUNT 0x08 +#define MUSB_O_HDRC_COUNT0 MUSB_O_HDRC_RXCOUNT /* re-used for EP0 */ +#define MUSB_O_HDRC_TXTYPE 0x0A +#define MUSB_O_HDRC_TYPE0 MUSB_O_HDRC_TXTYPE /* re-used for EP0 */ +#define MUSB_O_HDRC_TXINTERVAL 0x0B +#define MUSB_O_HDRC_NAKLIMIT0 MUSB_O_HDRC_TXINTERVAL /* re-used for EP0 */ +#define MUSB_O_HDRC_RXTYPE 0x0C +#define MUSB_O_HDRC_RXINTERVAL 0x0D +#define MUSB_O_HDRC_FIFOSIZE 0x0F +#define MUSB_O_HDRC_CONFIGDATA MUSB_O_HDRC_FIFOSIZE /* re-used for EP0 */ + +#define MUSB_END_OFFSET(end, offset) (0x100 + (0x10*end) + offset) + +/* "bus control" registers */ +#define MUSB_O_HDRC_TXFUNCADDR 0x00 +#define MUSB_O_HDRC_TXHUBADDR 0x02 +#define MUSB_O_HDRC_TXHUBPORT 0x03 + +#define MUSB_O_HDRC_RXFUNCADDR 0x04 +#define MUSB_O_HDRC_RXHUBADDR 0x06 +#define MUSB_O_HDRC_RXHUBPORT 0x07 + +#define MUSB_BUSCTL_OFFSET(end, offset) (0x80 + (8*end) + offset) + +/* + * MUSBHDRC Register bit masks + */ + +/* POWER */ + +#define MUSB_M_POWER_ISOUPDATE 0x80 +#define MUSB_M_POWER_SOFTCONN 0x40 +#define MUSB_M_POWER_HSENAB 0x20 +#define MUSB_M_POWER_HSMODE 0x10 +#define MUSB_M_POWER_RESET 0x08 +#define MUSB_M_POWER_RESUME 0x04 +#define MUSB_M_POWER_SUSPENDM 0x02 +#define MUSB_M_POWER_ENSUSPEND 0x01 + +/* INTRUSB */ +#define MUSB_M_INTR_SUSPEND 0x01 +#define MUSB_M_INTR_RESUME 0x02 +#define MUSB_M_INTR_RESET 0x04 +#define MUSB_M_INTR_BABBLE 0x04 +#define MUSB_M_INTR_SOF 0x08 +#define MUSB_M_INTR_CONNECT 0x10 +#define MUSB_M_INTR_DISCONNECT 0x20 +#define MUSB_M_INTR_SESSREQ 0x40 +#define MUSB_M_INTR_VBUSERROR 0x80 /* FOR SESSION END */ +#define MUSB_M_INTR_EP0 0x01 /* FOR EP0 INTERRUPT */ + +/* DEVCTL */ +#define MUSB_M_DEVCTL_BDEVICE 0x80 +#define MUSB_M_DEVCTL_FSDEV 0x40 +#define MUSB_M_DEVCTL_LSDEV 0x20 +#define MUSB_M_DEVCTL_VBUS 0x18 +#define MUSB_S_DEVCTL_VBUS 3 +#define MUSB_M_DEVCTL_HM 0x04 +#define MUSB_M_DEVCTL_HR 0x02 +#define MUSB_M_DEVCTL_SESSION 0x01 + +/* TESTMODE */ + +#define MUSB_M_TEST_FORCE_HOST 0x80 +#define MUSB_M_TEST_FIFO_ACCESS 0x40 +#define MUSB_M_TEST_FORCE_FS 0x20 +#define MUSB_M_TEST_FORCE_HS 0x10 +#define MUSB_M_TEST_PACKET 0x08 +#define MUSB_M_TEST_K 0x04 +#define MUSB_M_TEST_J 0x02 +#define MUSB_M_TEST_SE0_NAK 0x01 + +/* allocate for double-packet buffering (effectively doubles assigned _SIZE) */ +#define MUSB_M_FIFOSZ_DPB 0x10 +/* allocation size (8, 16, 32, ... 4096) */ +#define MUSB_M_FIFOSZ_SIZE 0x0f + +/* CSR0 */ +#define MUSB_M_CSR0_FLUSHFIFO 0x0100 +#define MUSB_M_CSR0_TXPKTRDY 0x0002 +#define MUSB_M_CSR0_RXPKTRDY 0x0001 + +/* CSR0 in Peripheral mode */ +#define MUSB_M_CSR0_P_SVDSETUPEND 0x0080 +#define MUSB_M_CSR0_P_SVDRXPKTRDY 0x0040 +#define MUSB_M_CSR0_P_SENDSTALL 0x0020 +#define MUSB_M_CSR0_P_SETUPEND 0x0010 +#define MUSB_M_CSR0_P_DATAEND 0x0008 +#define MUSB_M_CSR0_P_SENTSTALL 0x0004 + +/* CSR0 in Host mode */ +#define MUSB_M_CSR0_H_NO_PING 0x0800 +#define MUSB_M_CSR0_H_WR_DATATOGGLE 0x0400 /* set to allow setting: */ +#define MUSB_M_CSR0_H_DATATOGGLE 0x0200 /* data toggle control */ +#define MUSB_M_CSR0_H_NAKTIMEOUT 0x0080 +#define MUSB_M_CSR0_H_STATUSPKT 0x0040 +#define MUSB_M_CSR0_H_REQPKT 0x0020 +#define MUSB_M_CSR0_H_ERROR 0x0010 +#define MUSB_M_CSR0_H_SETUPPKT 0x0008 +#define MUSB_M_CSR0_H_RXSTALL 0x0004 + +/* TxType/RxType */ +#define MUSB_M_TYPE_SPEED 0xc0 +#define MUSB_S_TYPE_SPEED 6 +#define MUSB_TYPE_SPEED_HIGH 1 +#define MUSB_TYPE_SPEED_FULL 2 +#define MUSB_TYPE_SPEED_LOW 3 +#define MUSB_M_TYPE_PROTO 0x30 +#define MUSB_S_TYPE_PROTO 4 +#define MUSB_M_TYPE_REMOTE_END 0xf + +/* CONFIGDATA */ + +#define MUSB_M_CONFIGDATA_MPRXE 0x80 /* auto bulk pkt combining */ +#define MUSB_M_CONFIGDATA_MPTXE 0x40 /* auto bulk pkt splitting */ +#define MUSB_M_CONFIGDATA_BIGENDIAN 0x20 +#define MUSB_M_CONFIGDATA_HBRXE 0x10 /* HB-ISO for RX */ +#define MUSB_M_CONFIGDATA_HBTXE 0x08 /* HB-ISO for TX */ +#define MUSB_M_CONFIGDATA_DYNFIFO 0x04 /* dynamic FIFO sizing */ +#define MUSB_M_CONFIGDATA_SOFTCONE 0x02 /* SoftConnect */ +#define MUSB_M_CONFIGDATA_UTMIDW 0x01 /* data width 0 => 8bits, 1 => 16bits */ + +/* TXCSR in Peripheral and Host mode */ + +#define MUSB_M_TXCSR_AUTOSET 0x8000 +#define MUSB_M_TXCSR_ISO 0x4000 +#define MUSB_M_TXCSR_MODE 0x2000 +#define MUSB_M_TXCSR_DMAENAB 0x1000 +#define MUSB_M_TXCSR_FRCDATATOG 0x0800 +#define MUSB_M_TXCSR_DMAMODE 0x0400 +#define MUSB_M_TXCSR_CLRDATATOG 0x0040 +#define MUSB_M_TXCSR_FLUSHFIFO 0x0008 +#define MUSB_M_TXCSR_FIFONOTEMPTY 0x0002 +#define MUSB_M_TXCSR_TXPKTRDY 0x0001 + +/* TXCSR in Peripheral mode */ + +#define MUSB_M_TXCSR_P_INCOMPTX 0x0080 +#define MUSB_M_TXCSR_P_SENTSTALL 0x0020 +#define MUSB_M_TXCSR_P_SENDSTALL 0x0010 +#define MUSB_M_TXCSR_P_UNDERRUN 0x0004 + +/* TXCSR in Host mode */ + +#define MUSB_M_TXCSR_H_WR_DATATOGGLE 0x0200 +#define MUSB_M_TXCSR_H_DATATOGGLE 0x0100 +#define MUSB_M_TXCSR_H_NAKTIMEOUT 0x0080 +#define MUSB_M_TXCSR_H_RXSTALL 0x0020 +#define MUSB_M_TXCSR_H_ERROR 0x0004 + +/* RXCSR in Peripheral and Host mode */ + +#define MUSB_M_RXCSR_AUTOCLEAR 0x8000 +#define MUSB_M_RXCSR_DMAENAB 0x2000 +#define MUSB_M_RXCSR_DISNYET 0x1000 +#define MUSB_M_RXCSR_DMAMODE 0x0800 +#define MUSB_M_RXCSR_INCOMPRX 0x0100 +#define MUSB_M_RXCSR_CLRDATATOG 0x0080 +#define MUSB_M_RXCSR_FLUSHFIFO 0x0010 +#define MUSB_M_RXCSR_DATAERROR 0x0008 +#define MUSB_M_RXCSR_FIFOFULL 0x0002 +#define MUSB_M_RXCSR_RXPKTRDY 0x0001 + +/* RXCSR in Peripheral mode */ + +#define MUSB_M_RXCSR_P_ISO 0x4000 +#define MUSB_M_RXCSR_P_SENTSTALL 0x0040 +#define MUSB_M_RXCSR_P_SENDSTALL 0x0020 +#define MUSB_M_RXCSR_P_OVERRUN 0x0004 + +/* RXCSR in Host mode */ + +#define MUSB_M_RXCSR_H_AUTOREQ 0x4000 +#define MUSB_M_RXCSR_H_WR_DATATOGGLE 0x0400 +#define MUSB_M_RXCSR_H_DATATOGGLE 0x0200 +#define MUSB_M_RXCSR_H_RXSTALL 0x0040 +#define MUSB_M_RXCSR_H_REQPKT 0x0020 +#define MUSB_M_RXCSR_H_ERROR 0x0004 + +/* HUBADDR */ +#define MUSB_M_HUBADDR_MULTI_TT 0x80 + + +/* TXCSR in Peripheral and Host mode */ + +#define MUSB_M_TXCSR2_AUTOSET 0x80 +#define MUSB_M_TXCSR2_ISO 0x40 +#define MUSB_M_TXCSR2_MODE 0x20 +#define MUSB_M_TXCSR2_DMAENAB 0x10 +#define MUSB_M_TXCSR2_FRCDATATOG 0x08 +#define MUSB_M_TXCSR2_DMAMODE 0x04 + +#define MUSB_M_TXCSR1_CLRDATATOG 0x40 +#define MUSB_M_TXCSR1_FLUSHFIFO 0x08 +#define MUSB_M_TXCSR1_FIFONOTEMPTY 0x02 +#define MUSB_M_TXCSR1_TXPKTRDY 0x01 + +/* TXCSR in Peripheral mode */ + +#define MUSB_M_TXCSR1_P_INCOMPTX 0x80 +#define MUSB_M_TXCSR1_P_SENTSTALL 0x20 +#define MUSB_M_TXCSR1_P_SENDSTALL 0x10 +#define MUSB_M_TXCSR1_P_UNDERRUN 0x04 + +/* TXCSR in Host mode */ + +#define MUSB_M_TXCSR1_H_NAKTIMEOUT 0x80 +#define MUSB_M_TXCSR1_H_RXSTALL 0x20 +#define MUSB_M_TXCSR1_H_ERROR 0x04 + +/* RXCSR in Peripheral and Host mode */ + +#define MUSB_M_RXCSR2_AUTOCLEAR 0x80 +#define MUSB_M_RXCSR2_DMAENAB 0x20 +#define MUSB_M_RXCSR2_DISNYET 0x10 +#define MUSB_M_RXCSR2_DMAMODE 0x08 +#define MUSB_M_RXCSR2_INCOMPRX 0x01 + +#define MUSB_M_RXCSR1_CLRDATATOG 0x80 +#define MUSB_M_RXCSR1_FLUSHFIFO 0x10 +#define MUSB_M_RXCSR1_DATAERROR 0x08 +#define MUSB_M_RXCSR1_FIFOFULL 0x02 +#define MUSB_M_RXCSR1_RXPKTRDY 0x01 + +/* RXCSR in Peripheral mode */ + +#define MUSB_M_RXCSR2_P_ISO 0x40 +#define MUSB_M_RXCSR1_P_SENTSTALL 0x40 +#define MUSB_M_RXCSR1_P_SENDSTALL 0x20 +#define MUSB_M_RXCSR1_P_OVERRUN 0x04 + +/* RXCSR in Host mode */ + +#define MUSB_M_RXCSR2_H_AUTOREQ 0x40 +#define MUSB_M_RXCSR1_H_RXSTALL 0x40 +#define MUSB_M_RXCSR1_H_REQPKT 0x20 +#define MUSB_M_RXCSR1_H_ERROR 0x04 + +/* Top control register */ +#define MUSB_MODE_ULPI 0x9 +#define MUSB_MODE_SRST 0x4 + + +/* ---------------------------- end point status ------------------------- */ + +#define MUSB_GADGET_EP_ACTIVE 0 +#define MUSB_GADGET_EP_HALTED 1 +#define MUSB_GADGET_EP_DISABLED 2 + +struct nomadik_ep { + spinlock_t lock; + struct usb_ep ep; + struct list_head req_list; + unsigned long irqs; + struct list_head iso; + const struct usb_endpoint_descriptor *desc; + char name[14]; + u16 maxpacket; + u8 bmAttributes; + u8 binactive; + unsigned double_buf:1; + unsigned stopped:1; + unsigned fnf:1; + unsigned has_dma:1; + u8 ackwait; + u8 dma_channel; + u8 is_tx; + u8 end_number; + u16 dma_counter; + int lch; + struct nomadik_udc *udc; + struct timer_list timer; +}; + +struct nomadik_req { + struct usb_request req; + struct list_head completion_list; + u8 is_tx; + u8 end_number; + unsigned dma_bytes; + unsigned mapped:1; +}; + + +#if 0 +struct t_end_info { + struct usb_ep ep; +// struct list_head queue; + struct list_head urb_list; + char name[14]; + u16 maxpacket; + u8 remote_address; + u8 remote_end; + u8 is_tx; + u8 is_stalled; + u8 ready; + u8 type; + u16 request_size; + u16 max_tx_size; + u16 max_rx_size; + struct nomadik_udc *udc; +}; +#endif + + +struct nomadik_udc{ + spinlock_t lock; + char name[32]; + u8 bulk_tx_end; + u8 bulk_rx_end; + u8 end0_stage; + u8 bulk_split; + u8 bulk_combine; + u8 address; + u8 set_address_flag; + u8 set_config_flag; + u8 is_selfpowered; + uint8_t bDeviceState; + uint8_t test_mode_flag; + uint8_t test_mode_value; + uint8_t end_count; + uint32_t end_mask; + + struct nomadik_ep end[MUSB_MAX_USB_ENDS]; + struct usb_gadget gadget; + struct usb_gadget_driver *driver; + void *end0_buffer_ptr; + struct list_head iso; + struct completion *done; + struct device *dev; +} ; + +struct t_udc_end0_buffer { + u8 data[MUSB_END0_FIFOSIZE]; + u16 count; +}; + +struct t_ep_desc{ + u8 type; + u8 dir; + u16 size; + u8 dbe; +} ; + + +#define MUSB_EPD_AUTOCONFIG 0 + +#define MUSB_EPD_T_CNTRL 1 +#define MUSB_EPD_T_ISOC 2 +#define MUSB_EPD_T_BULK 3 +#define MUSB_EPD_T_INTR 4 + +#define MUSB_EPD_D_INOUT 0 +#define MUSB_EPD_D_TX 1 +#define MUSB_EPD_D_RX 2 + +#define MUSB_FIFO_OFFSET(end) (0x20 + (end * 4)) + +#define MUSB_READ8(base_ptr, offset) *((volatile uint8_t*)((unsigned long)base_ptr + offset)) +#define MUSB_READ16(base_ptr, offset) *((volatile uint16_t*)((unsigned long)base_ptr + offset)) +#define MUSB_READ32(base_ptr, offset) *((volatile uint32_t*)((unsigned long)base_ptr + offset)) + + +#undef MUSB_WRITE8 +#define MUSB_WRITE8(base_ptr, offset, data) { \ + DBG(4, "WRITE8(%p, %x, %02x)\n", base_ptr, offset, data); \ + wmb(); \ + *(volatile uint8_t*)((unsigned long)base_ptr + offset) = data; \ + } + +#undef MUSB_WRITE16 +#define MUSB_WRITE16(base_ptr, offset, data) { \ + DBG(4, "WRITE16(%p, %x, %04x)\n", base_ptr, offset, data); \ + wmb(); \ + *(volatile uint16_t*)((unsigned long)base_ptr + offset) = data; \ + } + + +#undef MUSB_WRITE32 +#define MUSB_WRITE32(base_ptr, offset, data) { \ + DBG(4, "WRITE32(%p, %x, %08x)\n", base_ptr, offset, data); \ + wmb(); \ + *(volatile uint32_t*)((unsigned long)base_ptr + offset) = data; \ + } + +#define MUSB_SELECTEND(base_ptr, end) \ + MUSB_WRITE8(base_ptr, MUSB_O_HDRC_INDEX, end) + +#define MUSB_READCSR8(base_ptr, offset, end) \ + MUSB_READ8(base_ptr, (offset + 0x10)) + +#define MUSB_READCSR16(base_ptr, offset, end) \ + MUSB_READ16(base_ptr, (offset + 0x10)) + +#define MUSB_WRITECSR8(base_ptr, offset, end, data) \ + MUSB_WRITE8(base_ptr, (offset + 0x10), data) + +#define MUSB_WRITECSR16(base_ptr, offset, end, data) \ + MUSB_WRITE16(base_ptr, (offset + 0x10), data) + + --- /dev/null +++ linux-2.6.20/include/asm-arm/arch-nomadik/uncompress.h @@ -0,0 +1,71 @@ +/* + * linux/include/asm-arm/arch-nomadik/uncompress.h + * + * Copyright (C) 1999 ARM Limited + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include + +#include +#include +#include +#include + +#define NOMADIK_UART_DR (*(volatile unsigned char *)0x101FD000) +#define NOMADIK_UART_LCRH (*(volatile unsigned char *)0x101FD02c) +#define NOMADIK_UART_CR (*(volatile unsigned char *)0x101FD030) +#define NOMADIK_UART_FR (*(volatile unsigned char *)0x101FD018) + +/* + * This does not append a newline + */ +static void putc(const char s) +{ + /* Do nothing if the UART is not enabled. */ + if (!(NOMADIK_UART_CR & UART01x_CR_UARTEN)) + return; + + while (NOMADIK_UART_FR & UART01x_FR_TXFF) + barrier(); + + NOMADIK_UART_DR = s; + + if (s == '\n') { + while (NOMADIK_UART_FR & UART01x_FR_TXFF) + barrier(); + + NOMADIK_UART_DR = '\r'; + } + while (NOMADIK_UART_FR & UART01x_FR_BUSY) ; +} + +static void flush() +{ +/*FIXME*/ +} + +/* Use arch_decomp_setup() to kludge a default tagged + * parameter list if none exists. + */ +static inline void arch_decomp_setup(void) +{ +} + +/* + * nothing to do + */ +#define arch_decomp_wdog() --- /dev/null +++ linux-2.6.20/include/asm-arm/arch-nomadik/vmalloc.h @@ -0,0 +1,32 @@ +/* + * linux/include/asm-arm/arch-nomadik/vmalloc.h + * + * Copyright (C) 2000 Russell King. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* + * Just any arbitrary offset to the start of the vmalloc VM area: the + * current 8MB value just means that there will be a 8MB "hole" after the + * physical memory until the kernel virtual memory starts. That means that + * any out-of-bounds memory accesses will hopefully be caught. + * The vmalloc() routines leaves a hole of 4kB between each vmalloced + * area for the same reason. ;) + */ +#define VMALLOC_OFFSET (8*1024*1024) +#define VMALLOC_START (((unsigned long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1)) +#define VMALLOC_VMADDR(x) ((unsigned long)(x)) +#define VMALLOC_END (PAGE_OFFSET + 0x10000000) --- /dev/null +++ linux-2.6.20/include/asm-arm/kgdb.h @@ -0,0 +1,91 @@ +/* + * include/asm-arm/kgdb.h + * + * ARM KGDB support + * + * Author: Deepak Saxena + * + * Copyright (C) 2002 MontaVista Software Inc. + * + */ + +#ifndef __ASM_KGDB_H__ +#define __ASM_KGDB_H__ + +#include +#include + + +/* + * GDB assumes that we're a user process being debugged, so + * it will send us an SWI command to write into memory as the + * debug trap. When an SWI occurs, the next instruction addr is + * placed into R14_svc before jumping to the vector trap. + * This doesn't work for kernel debugging as we are already in SVC + * we would loose the kernel's LR, which is a bad thing. This + * is bad thing. + * + * By doing this as an undefined instruction trap, we force a mode + * switch from SVC to UND mode, allowing us to save full kernel state. + * + * We also define a KGDB_COMPILED_BREAK which can be used to compile + * in breakpoints. This is important for things like sysrq-G and for + * the initial breakpoint from trap_init(). + * + * Note to ARM HW designers: Add real trap support like SH && PPC to + * make our lives much much simpler. :) + */ +#define BREAK_INSTR_SIZE 4 +#define GDB_BREAKINST 0xef9f0001 +#define KGDB_BREAKINST 0xe7ffdefe +#define KGDB_COMPILED_BREAK 0xe7ffdeff +#define CACHE_FLUSH_IS_SAFE 1 + +#ifndef __ASSEMBLY__ + +#define BREAKPOINT() asm(".word 0xe7ffdeff") + + +extern void kgdb_handle_bus_error(void); +extern int kgdb_fault_expected; +#endif /* !__ASSEMBLY__ */ + +/* + * From Amit S. Kale: + * + * In the register packet, words 0-15 are R0 to R10, FP, IP, SP, LR, PC. But + * Register 16 isn't cpsr. GDB passes CPSR in word 25. There are 9 words in + * between which are unused. Passing only 26 words to gdb is sufficient. + * GDB can figure out that floating point registers are not passed. + * GDB_MAX_REGS should be 26. + */ +#define GDB_MAX_REGS (26) + +#define KGDB_MAX_NO_CPUS 1 +#define BUFMAX 400 +#define NUMREGBYTES (GDB_MAX_REGS << 2) +#define NUMCRITREGBYTES (32 << 2) + +#define _R0 0 +#define _R1 1 +#define _R2 2 +#define _R3 3 +#define _R4 4 +#define _R5 5 +#define _R6 6 +#define _R7 7 +#define _R8 8 +#define _R9 9 +#define _R10 10 +#define _FP 11 +#define _IP 12 +#define _SP 13 +#define _LR 14 +#define _PC 15 +#define _CPSR (GDB_MAX_REGS - 1) + +/* So that we can denote the end of a frame for tracing, in the simple + * case. */ +#define CFI_END_FRAME(func) __CFI_END_FRAME(_PC,_SP,func) + +#endif /* __ASM_KGDB_H__ */ --- linux-2.6.20.orig/include/asm-arm/system.h +++ linux-2.6.20/include/asm-arm/system.h @@ -343,10 +343,51 @@ static inline unsigned long __xchg(unsig } extern void disable_hlt(void); extern void enable_hlt(void); +#define __HAVE_ARCH_CMPXCHG 1 + +#include + +static inline unsigned long __cmpxchg_u32(volatile int *m, unsigned long old, + unsigned long new) +{ + u32 retval; + unsigned long flags; + + local_irq_save(flags); + retval = *m; + if (retval == old) + *m = new; + local_irq_restore(flags); /* implies memory barrier */ + + return retval; +} + +/* This function doesn't exist, so you'll get a linker error + if something tries to do an invalid cmpxchg(). */ +extern void __cmpxchg_called_with_bad_pointer(void); + +static inline unsigned long __cmpxchg(volatile void * ptr, unsigned long old, + unsigned long new, int size) +{ + switch (size) { + case 4: + return __cmpxchg_u32(ptr, old, new); + } + __cmpxchg_called_with_bad_pointer(); + return old; +} + +#define cmpxchg(ptr,o,n) \ + ({ \ + __typeof__(*(ptr)) _o_ = (o); \ + __typeof__(*(ptr)) _n_ = (n); \ + (__typeof__(*(ptr))) __cmpxchg((ptr), (unsigned long)_o_, \ + (unsigned long)_n_, sizeof(*(ptr))); \ + }) #endif /* __ASSEMBLY__ */ #define arch_align_stack(x) (x) #endif /* __KERNEL__ */ --- /dev/null +++ linux-2.6.20/include/asm-generic/kgdb.h @@ -0,0 +1,34 @@ +/* + * include/asm-generic/kgdb.h + * + * This provides the assembly level information so that KGDB can provide + * a GDB that has been patched with enough information to know to stop + * trying to unwind the function. + * + * Author: Tom Rini + * + * 2005 (c) MontaVista Software, Inc. This file is licensed under the terms + * of the GNU General Public License version 2. This program is licensed + * "as is" without any warranty of any kind, whether express or implied. + */ + +#ifndef __ASM_GENERIC_KGDB_H__ +#define __ASM_GENERIC_KGDB_H__ + +#include +#ifdef __ASSEMBLY__ +#ifdef CONFIG_KGDB +/* This MUST be put at the end of a given assembly function */ +#define __CFI_END_FRAME(pc,sp,func) \ +CAT3(.Lend_,func,:) \ + CFI_preamble(func,pc,0x1,-DATA_ALIGN_FACTOR) \ + CFA_define_reference(sp, 0) \ + CFA_undefine_reg(pc) \ + CFI_postamble() \ + FDE_preamble(func,func,CAT3(.Lend,_,func)) \ + FDE_postamble() +#else +#define __CFI_END_FRAME(pc,sp,fn) +#endif /* CONFIG_KGDB */ +#endif /* __ASSEMBLY__ */ +#endif /* __ASM_GENERIC_KGDB_H__ */ --- linux-2.6.20.orig/include/linux/amba/clcd.h +++ linux-2.6.20/include/linux/amba/clcd.h @@ -51,11 +51,16 @@ #define CNTL_LCDBPP1 (0 << 1) #define CNTL_LCDBPP2 (1 << 1) #define CNTL_LCDBPP4 (2 << 1) #define CNTL_LCDBPP8 (3 << 1) #define CNTL_LCDBPP16 (4 << 1) +#ifdef CONFIG_ARCH_NOMADIK +#define CNTL_LCDBPP16_565 (7 << 1) +#define CNTL_LCDBPP24PACKED (6 << 1) +#else #define CNTL_LCDBPP16_565 (6 << 1) +#endif #define CNTL_LCDBPP24 (5 << 1) #define CNTL_LCDBW (1 << 4) #define CNTL_LCDTFT (1 << 5) #define CNTL_LCDMONO8 (1 << 6) #define CNTL_LCDDUAL (1 << 7) @@ -64,10 +69,17 @@ #define CNTL_BEPO (1 << 10) #define CNTL_LCDPWR (1 << 11) #define CNTL_LCDVCOMP(x) ((x) << 12) #define CNTL_LDMAFIFOTIME (1 << 15) #define CNTL_WATERMARK (1 << 16) +#define CNTL_CDWID_18 (1 << 20 ) +#define CNTL_1XBPP_15 (1 << 17 ) +#ifdef CONFIG_ARCH_NOMADIK +#define CNTL_1XBPP_444 (0 << 17 ) +#define CNTL_1XBPP_565 (2 << 17 ) +#define CNTL_1XBPP_INVALID (3 << 17 ) +#endif struct clcd_panel { struct fb_videomode mode; signed short width; /* width in mm */ signed short height; /* height in mm */ @@ -216,12 +228,24 @@ static inline void clcdfb_decode(struct if ((fb->dev->periphid & 0x000fffff) == 0x00041110) val |= CNTL_LCDBPP16; else if (fb->fb.var.green.length == 5) val |= CNTL_LCDBPP16; else +#ifdef CONFIG_ARCH_NOMADIK + { + val &= ~CNTL_1XBPP_INVALID; + val |= CNTL_1XBPP_565 | CNTL_LCDBPP16; + } +#else val |= CNTL_LCDBPP16_565; +#endif break; +#ifdef CONFIG_ARCH_NOMADIK + case 24: + val |= CNTL_LCDBPP24PACKED; + break; +#endif case 32: val |= CNTL_LCDBPP24; break; } --- /dev/null +++ linux-2.6.20/include/linux/dwarf2-lang.h @@ -0,0 +1,300 @@ +#ifndef DWARF2_LANG +#define DWARF2_LANG + +/* + * This is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2, or (at your option) any later + * version. + */ +/* + * This file defines macros that allow generation of DWARF debug records + * for asm files. This file is platform independent. Register numbers + * (which are about the only thing that is platform dependent) are to be + * supplied by a platform defined file. + */ +/* + * We need this to work for both asm and C. In asm we are using the + * old comment trick to concatenate while C uses the new ANSI thing. + * Here we have concat macro... The multi level thing is to allow and + * macros used in the names to be resolved prior to the cat (at which + * time they are no longer the same string). + */ +#define CAT3(a,b,c) _CAT3(a,b,c) +#define _CAT3(a,b,c) __CAT3(a,b,c) +#ifndef __STDC__ +#define __CAT3(a,b,c) a/**/b/**/c +#else +#define __CAT3(a,b,c) a##b##c +#endif +#ifdef __ASSEMBLY__ +#define IFC(a) +#define IFN_C(a) a +#define NL ; +#define QUOTE_THIS(a) a +#define DWARF_preamble .section .debug_frame,"",%progbits; +#else +#define IFC(a) a +#define IFN_C(a) +#define NL \n\t +#define QUOTE_THIS(a) _QUOTE_THIS(a) +#define _QUOTE_THIS(a) #a +/* Don't let CPP see the " and , \042=" \054=, */ +#define DWARF_preamble .section .debug_frame \054\042\042\054%progbits +#endif + +#ifdef CONFIG_64BIT +#define DATA_ALIGN_FACTOR 8 +#define ADDR_LOC .quad +#else +#define DATA_ALIGN_FACTOR 4 +#define ADDR_LOC .long +#endif + +#include +/* + * This macro starts a debug frame section. The debug_frame describes + * where to find the registers that the enclosing function saved on + * entry. + * + * ORD is use by the label generator and should be the same as what is + * passed to CFI_postamble. + * + * pc, pc register gdb ordinal. + * + * code_align this is the factor used to define locations or regions + * where the given definitions apply. If you use labels to define these + * this should be 1. + * + * data_align this is the factor used to define register offsets. If + * you use struct offset, this should be the size of the register in + * bytes or the negative of that. This is how it is used: you will + * define a register as the reference register, say the stack pointer, + * then you will say where a register is located relative to this + * reference registers value, say 40 for register 3 (the gdb register + * number). The <40> will be multiplied by to define the + * byte offset of the given register (3, in this example). So if your + * <40> is the byte offset and the reference register points at the + * begining, you would want 1 for the data_offset. If <40> was the 40th + * 4-byte element in that structure you would want 4. And if your + * reference register points at the end of the structure you would want + * a negative data_align value(and you would have to do other math as + * well). + */ + +#define CFI_preamble(ORD, pc, code_align, data_align) \ + DWARF_preamble NL \ + .align DATA_ALIGN_FACTOR NL \ + .globl CAT3(frame,_,ORD) NL \ +CAT3(frame,_,ORD): NL \ + .long 7f-6f NL \ +6: \ + .long DW_CIE_ID NL \ + .byte DW_CIE_VERSION NL \ + .byte 0 NL \ + .uleb128 code_align NL \ + .sleb128 data_align NL \ + .byte pc NL + +/* + * After the above macro and prior to the CFI_postamble, you need to + * define the initial state. This starts with defining the reference + * register and, usually the pc. Here are some helper macros: + */ + +#define CFA_define_reference(reg, offset) \ + .byte DW_CFA_def_cfa NL \ + .uleb128 reg NL \ + .uleb128 (offset) NL + +#define CFA_define_offset(reg, offset) \ + .byte (DW_CFA_offset + reg) NL \ + .uleb128 (offset) NL + +#define CFA_restore(reg) \ + .byte (DW_CFA_restore + reg) NL + +#define CFI_postamble() \ + .align DATA_ALIGN_FACTOR NL \ +7: NL \ +.previous NL + +/* + * So now your code pushs stuff on the stack, you need a new location + * and the rules for what to do. This starts a running description of + * the call frame. You need to describe what changes with respect to + * the call registers as the location of the pc moves through the code. + * The following builds an FDE (fram descriptor entry?). Like the + * above, it has a preamble and a postamble. It also is tied to the CFI + * above. + * The preamble macro is tied to the CFI thru the first parameter. The + * second is the code start address and then the code end address+1. + */ +#define FDE_preamble(ORD, initial_address, end_address) \ + DWARF_preamble NL \ + .align DATA_ALIGN_FACTOR NL \ + .long 9f-8f NL \ +8: \ + .long CAT3(frame,_,ORD) NL \ + ADDR_LOC initial_address NL \ + ADDR_LOC (end_address - initial_address) NL + +#define FDE_postamble() \ + .align DATA_ALIGN_FACTOR NL \ +9: NL \ +.previous NL + +/* + * That done, you can now add registers, subtract registers, move the + * reference and even change the reference. You can also define a new + * area of code the info applies to. For discontinuous bits you should + * start a new FDE. You may have as many as you like. + */ + +/* + * To advance the stack address by (0x3f max) + */ + +#define CFA_advance_loc(bytes) \ + .byte DW_CFA_advance_loc+bytes NL + +/* + * This one is good for 0xff or 255 + */ +#define CFA_advance_loc1(bytes) \ + .byte DW_CFA_advance_loc1 NL \ + .byte bytes NL + +#define CFA_undefine_reg(reg) \ + .byte DW_CFA_undefined NL \ + .uleb128 reg NL +/* + * With the above you can define all the register locations. But + * suppose the reference register moves... Takes the new offset NOT an + * increment. This is how esp is tracked if it is not saved. + */ + +#define CFA_define_cfa_offset(offset) \ + .byte DW_CFA_def_cfa_offset NL \ + .uleb128 (offset) NL +/* + * Or suppose you want to use a different reference register... + */ +#define CFA_define_cfa_register(reg) \ + .byte DW_CFA_def_cfa_register NL \ + .uleb128 reg NL + +/* + * If you want to mess with the stack pointer, here is the expression. + * The stack starts empty. + */ +#define CFA_def_cfa_expression \ + .byte DW_CFA_def_cfa_expression NL \ + .uleb128 20f-10f NL \ +10: NL +/* + * This expression is to be used for other regs. The stack starts with the + * stack address. + */ + +#define CFA_expression(reg) \ + .byte DW_CFA_expression NL \ + .uleb128 reg NL \ + .uleb128 20f-10f NL \ +10: NL +/* + * Here we do the expression stuff. You should code the above followed + * by expression OPs followed by CFA_expression_end. + */ + + +#define CFA_expression_end \ +20: NL + +#define CFA_exp_OP_const4s(a) \ + .byte DW_OP_const4s NL \ + .long a NL + +#define CFA_exp_OP_swap .byte DW_OP_swap NL +#define CFA_exp_OP_dup .byte DW_OP_dup NL +#define CFA_exp_OP_drop .byte DW_OP_drop NL +/* + * All these work on the top two elements on the stack, replacing them + * with the result. Top comes first where it matters. True is 1, false 0. + */ +#define CFA_exp_OP_deref .byte DW_OP_deref NL +#define CFA_exp_OP_and .byte DW_OP_and NL +#define CFA_exp_OP_div .byte DW_OP_div NL +#define CFA_exp_OP_minus .byte DW_OP_minus NL +#define CFA_exp_OP_mod .byte DW_OP_mod NL +#define CFA_exp_OP_neg .byte DW_OP_neg NL +#define CFA_exp_OP_plus .byte DW_OP_plus NL +#define CFA_exp_OP_not .byte DW_OP_not NL +#define CFA_exp_OP_or .byte DW_OP_or NL +#define CFA_exp_OP_xor .byte DW_OP_xor NL +#define CFA_exp_OP_le .byte DW_OP_le NL +#define CFA_exp_OP_ge .byte DW_OP_ge NL +#define CFA_exp_OP_eq .byte DW_OP_eq NL +#define CFA_exp_OP_lt .byte DW_OP_lt NL +#define CFA_exp_OP_gt .byte DW_OP_gt NL +#define CFA_exp_OP_ne .byte DW_OP_ne NL +/* + * These take a parameter as noted + */ +/* + * Unconditional skip to loc. loc is a label (loc:) + */ +#define CFA_exp_OP_skip(loc) \ + .byte DW_OP_skip NL \ + .hword loc-.-2 NL +/* + * Conditional skip to loc (TOS != 0, TOS--) (loc is a label) + */ +#define CFA_exp_OP_bra(loc) \ + .byte DW_OP_bra NL \ + .hword loc-.-2 NL + +/* + * TOS += no (an unsigned number) + */ +#define CFA_exp_OP_plus_uconst(no) \ + .byte DW_OP_plus_uconst NL \ + .uleb128 no NL + +/* + * ++TOS = no (a unsigned number) + */ +#define CFA_exp_OP_constu(no) \ + .byte DW_OP_constu NL \ + .uleb128 no NL +/* + * ++TOS = no (a signed number) + */ +#define CFA_exp_OP_consts(no) \ + .byte DW_OP_consts NL \ + .sleb128 no NL +/* + * ++TOS = no (an unsigned byte) + */ +#define CFA_exp_OP_const1u(no) \ + .byte DW_OP_const1u NL \ + .byte no NL + + +/* + * ++TOS = no (a address) + */ +#define CFA_exp_OP_addr(no) \ + .byte DW_OP_addr NL \ + .long no NL + +/* + * Push current frames value for "reg" + offset + * We take advantage of the opcode assignments to make this a litteral reg + * rather than use the DW_OP_bregx opcode. + */ + +#define CFA_exp_OP_breg(reg,offset) \ + .byte DW_OP_breg0+reg NL \ + .sleb128 offset NL +#endif --- /dev/null +++ linux-2.6.20/include/linux/dwarf2.h @@ -0,0 +1,775 @@ +/* Declarations and definitions of codes relating to the DWARF2 symbolic + debugging information format. + Copyright (C) 1992, 1993, 1995, 1996, 1997, 1999, 2000, 2001, 2002, + 2003 Free Software Foundation, Inc. + + Written by Gary Funck (gary@intrepid.com) The Ada Joint Program + Office (AJPO), Florida State Unviversity and Silicon Graphics Inc. + provided support for this effort -- June 21, 1995. + + Derived from the DWARF 1 implementation written by Ron Guilmette + (rfg@netcom.com), November 1990. + + This file is part of GCC. + + GCC is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation; either version 2, or (at your option) any later + version. + + GCC is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU General Public License + along with GCC; see the file COPYING. If not, write to the Free + Software Foundation, 59 Temple Place - Suite 330, Boston, MA + 02111-1307, USA. */ + +/* This file is derived from the DWARF specification (a public document) + Revision 2.0.0 (July 27, 1993) developed by the UNIX International + Programming Languages Special Interest Group (UI/PLSIG) and distributed + by UNIX International. Copies of this specification are available from + UNIX International, 20 Waterview Boulevard, Parsippany, NJ, 07054. + + This file also now contains definitions from the DWARF 3 specification. */ + +/* This file is shared between GCC and GDB, and should not contain + prototypes. */ + +#ifndef _ELF_DWARF2_H +#define _ELF_DWARF2_H + +/* Structure found in the .debug_line section. */ +typedef struct +{ + unsigned char li_length [4]; + unsigned char li_version [2]; + unsigned char li_prologue_length [4]; + unsigned char li_min_insn_length [1]; + unsigned char li_default_is_stmt [1]; + unsigned char li_line_base [1]; + unsigned char li_line_range [1]; + unsigned char li_opcode_base [1]; +} +DWARF2_External_LineInfo; + +typedef struct +{ + unsigned long li_length; + unsigned short li_version; + unsigned int li_prologue_length; + unsigned char li_min_insn_length; + unsigned char li_default_is_stmt; + int li_line_base; + unsigned char li_line_range; + unsigned char li_opcode_base; +} +DWARF2_Internal_LineInfo; + +/* Structure found in .debug_pubnames section. */ +typedef struct +{ + unsigned char pn_length [4]; + unsigned char pn_version [2]; + unsigned char pn_offset [4]; + unsigned char pn_size [4]; +} +DWARF2_External_PubNames; + +typedef struct +{ + unsigned long pn_length; + unsigned short pn_version; + unsigned long pn_offset; + unsigned long pn_size; +} +DWARF2_Internal_PubNames; + +/* Structure found in .debug_info section. */ +typedef struct +{ + unsigned char cu_length [4]; + unsigned char cu_version [2]; + unsigned char cu_abbrev_offset [4]; + unsigned char cu_pointer_size [1]; +} +DWARF2_External_CompUnit; + +typedef struct +{ + unsigned long cu_length; + unsigned short cu_version; + unsigned long cu_abbrev_offset; + unsigned char cu_pointer_size; +} +DWARF2_Internal_CompUnit; + +typedef struct +{ + unsigned char ar_length [4]; + unsigned char ar_version [2]; + unsigned char ar_info_offset [4]; + unsigned char ar_pointer_size [1]; + unsigned char ar_segment_size [1]; +} +DWARF2_External_ARange; + +typedef struct +{ + unsigned long ar_length; + unsigned short ar_version; + unsigned long ar_info_offset; + unsigned char ar_pointer_size; + unsigned char ar_segment_size; +} +DWARF2_Internal_ARange; + + +/* Tag names and codes. */ +enum dwarf_tag + { + DW_TAG_padding = 0x00, + DW_TAG_array_type = 0x01, + DW_TAG_class_type = 0x02, + DW_TAG_entry_point = 0x03, + DW_TAG_enumeration_type = 0x04, + DW_TAG_formal_parameter = 0x05, + DW_TAG_imported_declaration = 0x08, + DW_TAG_label = 0x0a, + DW_TAG_lexical_block = 0x0b, + DW_TAG_member = 0x0d, + DW_TAG_pointer_type = 0x0f, + DW_TAG_reference_type = 0x10, + DW_TAG_compile_unit = 0x11, + DW_TAG_string_type = 0x12, + DW_TAG_structure_type = 0x13, + DW_TAG_subroutine_type = 0x15, + DW_TAG_typedef = 0x16, + DW_TAG_union_type = 0x17, + DW_TAG_unspecified_parameters = 0x18, + DW_TAG_variant = 0x19, + DW_TAG_common_block = 0x1a, + DW_TAG_common_inclusion = 0x1b, + DW_TAG_inheritance = 0x1c, + DW_TAG_inlined_subroutine = 0x1d, + DW_TAG_module = 0x1e, + DW_TAG_ptr_to_member_type = 0x1f, + DW_TAG_set_type = 0x20, + DW_TAG_subrange_type = 0x21, + DW_TAG_with_stmt = 0x22, + DW_TAG_access_declaration = 0x23, + DW_TAG_base_type = 0x24, + DW_TAG_catch_block = 0x25, + DW_TAG_const_type = 0x26, + DW_TAG_constant = 0x27, + DW_TAG_enumerator = 0x28, + DW_TAG_file_type = 0x29, + DW_TAG_friend = 0x2a, + DW_TAG_namelist = 0x2b, + DW_TAG_namelist_item = 0x2c, + DW_TAG_packed_type = 0x2d, + DW_TAG_subprogram = 0x2e, + DW_TAG_template_type_param = 0x2f, + DW_TAG_template_value_param = 0x30, + DW_TAG_thrown_type = 0x31, + DW_TAG_try_block = 0x32, + DW_TAG_variant_part = 0x33, + DW_TAG_variable = 0x34, + DW_TAG_volatile_type = 0x35, + /* DWARF 3. */ + DW_TAG_dwarf_procedure = 0x36, + DW_TAG_restrict_type = 0x37, + DW_TAG_interface_type = 0x38, + DW_TAG_namespace = 0x39, + DW_TAG_imported_module = 0x3a, + DW_TAG_unspecified_type = 0x3b, + DW_TAG_partial_unit = 0x3c, + DW_TAG_imported_unit = 0x3d, + /* SGI/MIPS Extensions. */ + DW_TAG_MIPS_loop = 0x4081, + /* HP extensions. See: ftp://ftp.hp.com/pub/lang/tools/WDB/wdb-4.0.tar.gz . */ + DW_TAG_HP_array_descriptor = 0x4090, + /* GNU extensions. */ + DW_TAG_format_label = 0x4101, /* For FORTRAN 77 and Fortran 90. */ + DW_TAG_function_template = 0x4102, /* For C++. */ + DW_TAG_class_template = 0x4103, /* For C++. */ + DW_TAG_GNU_BINCL = 0x4104, + DW_TAG_GNU_EINCL = 0x4105, + /* Extensions for UPC. See: http://upc.gwu.edu/~upc. */ + DW_TAG_upc_shared_type = 0x8765, + DW_TAG_upc_strict_type = 0x8766, + DW_TAG_upc_relaxed_type = 0x8767, + /* PGI (STMicroelectronics) extensions. No documentation available. */ + DW_TAG_PGI_kanji_type = 0xA000, + DW_TAG_PGI_interface_block = 0xA020 + }; + +#define DW_TAG_lo_user 0x4080 +#define DW_TAG_hi_user 0xffff + +/* Flag that tells whether entry has a child or not. */ +#define DW_children_no 0 +#define DW_children_yes 1 + +/* Form names and codes. */ +enum dwarf_form + { + DW_FORM_addr = 0x01, + DW_FORM_block2 = 0x03, + DW_FORM_block4 = 0x04, + DW_FORM_data2 = 0x05, + DW_FORM_data4 = 0x06, + DW_FORM_data8 = 0x07, + DW_FORM_string = 0x08, + DW_FORM_block = 0x09, + DW_FORM_block1 = 0x0a, + DW_FORM_data1 = 0x0b, + DW_FORM_flag = 0x0c, + DW_FORM_sdata = 0x0d, + DW_FORM_strp = 0x0e, + DW_FORM_udata = 0x0f, + DW_FORM_ref_addr = 0x10, + DW_FORM_ref1 = 0x11, + DW_FORM_ref2 = 0x12, + DW_FORM_ref4 = 0x13, + DW_FORM_ref8 = 0x14, + DW_FORM_ref_udata = 0x15, + DW_FORM_indirect = 0x16 + }; + +/* Attribute names and codes. */ +enum dwarf_attribute + { + DW_AT_sibling = 0x01, + DW_AT_location = 0x02, + DW_AT_name = 0x03, + DW_AT_ordering = 0x09, + DW_AT_subscr_data = 0x0a, + DW_AT_byte_size = 0x0b, + DW_AT_bit_offset = 0x0c, + DW_AT_bit_size = 0x0d, + DW_AT_element_list = 0x0f, + DW_AT_stmt_list = 0x10, + DW_AT_low_pc = 0x11, + DW_AT_high_pc = 0x12, + DW_AT_language = 0x13, + DW_AT_member = 0x14, + DW_AT_discr = 0x15, + DW_AT_discr_value = 0x16, + DW_AT_visibility = 0x17, + DW_AT_import = 0x18, + DW_AT_string_length = 0x19, + DW_AT_common_reference = 0x1a, + DW_AT_comp_dir = 0x1b, + DW_AT_const_value = 0x1c, + DW_AT_containing_type = 0x1d, + DW_AT_default_value = 0x1e, + DW_AT_inline = 0x20, + DW_AT_is_optional = 0x21, + DW_AT_lower_bound = 0x22, + DW_AT_producer = 0x25, + DW_AT_prototyped = 0x27, + DW_AT_return_addr = 0x2a, + DW_AT_start_scope = 0x2c, + DW_AT_stride_size = 0x2e, + DW_AT_upper_bound = 0x2f, + DW_AT_abstract_origin = 0x31, + DW_AT_accessibility = 0x32, + DW_AT_address_class = 0x33, + DW_AT_artificial = 0x34, + DW_AT_base_types = 0x35, + DW_AT_calling_convention = 0x36, + DW_AT_count = 0x37, + DW_AT_data_member_location = 0x38, + DW_AT_decl_column = 0x39, + DW_AT_decl_file = 0x3a, + DW_AT_decl_line = 0x3b, + DW_AT_declaration = 0x3c, + DW_AT_discr_list = 0x3d, + DW_AT_encoding = 0x3e, + DW_AT_external = 0x3f, + DW_AT_frame_base = 0x40, + DW_AT_friend = 0x41, + DW_AT_identifier_case = 0x42, + DW_AT_macro_info = 0x43, + DW_AT_namelist_items = 0x44, + DW_AT_priority = 0x45, + DW_AT_segment = 0x46, + DW_AT_specification = 0x47, + DW_AT_static_link = 0x48, + DW_AT_type = 0x49, + DW_AT_use_location = 0x4a, + DW_AT_variable_parameter = 0x4b, + DW_AT_virtuality = 0x4c, + DW_AT_vtable_elem_location = 0x4d, + /* DWARF 3 values. */ + DW_AT_allocated = 0x4e, + DW_AT_associated = 0x4f, + DW_AT_data_location = 0x50, + DW_AT_stride = 0x51, + DW_AT_entry_pc = 0x52, + DW_AT_use_UTF8 = 0x53, + DW_AT_extension = 0x54, + DW_AT_ranges = 0x55, + DW_AT_trampoline = 0x56, + DW_AT_call_column = 0x57, + DW_AT_call_file = 0x58, + DW_AT_call_line = 0x59, + /* SGI/MIPS extensions. */ + DW_AT_MIPS_fde = 0x2001, + DW_AT_MIPS_loop_begin = 0x2002, + DW_AT_MIPS_tail_loop_begin = 0x2003, + DW_AT_MIPS_epilog_begin = 0x2004, + DW_AT_MIPS_loop_unroll_factor = 0x2005, + DW_AT_MIPS_software_pipeline_depth = 0x2006, + DW_AT_MIPS_linkage_name = 0x2007, + DW_AT_MIPS_stride = 0x2008, + DW_AT_MIPS_abstract_name = 0x2009, + DW_AT_MIPS_clone_origin = 0x200a, + DW_AT_MIPS_has_inlines = 0x200b, + /* HP extensions. */ + DW_AT_HP_block_index = 0x2000, + DW_AT_HP_unmodifiable = 0x2001, /* Same as DW_AT_MIPS_fde. */ + DW_AT_HP_actuals_stmt_list = 0x2010, + DW_AT_HP_proc_per_section = 0x2011, + DW_AT_HP_raw_data_ptr = 0x2012, + DW_AT_HP_pass_by_reference = 0x2013, + DW_AT_HP_opt_level = 0x2014, + DW_AT_HP_prof_version_id = 0x2015, + DW_AT_HP_opt_flags = 0x2016, + DW_AT_HP_cold_region_low_pc = 0x2017, + DW_AT_HP_cold_region_high_pc = 0x2018, + DW_AT_HP_all_variables_modifiable = 0x2019, + DW_AT_HP_linkage_name = 0x201a, + DW_AT_HP_prof_flags = 0x201b, /* In comp unit of procs_info for -g. */ + /* GNU extensions. */ + DW_AT_sf_names = 0x2101, + DW_AT_src_info = 0x2102, + DW_AT_mac_info = 0x2103, + DW_AT_src_coords = 0x2104, + DW_AT_body_begin = 0x2105, + DW_AT_body_end = 0x2106, + DW_AT_GNU_vector = 0x2107, + /* VMS extensions. */ + DW_AT_VMS_rtnbeg_pd_address = 0x2201, + /* UPC extension. */ + DW_AT_upc_threads_scaled = 0x3210, + /* PGI (STMicroelectronics) extensions. */ + DW_AT_PGI_lbase = 0x3a00, + DW_AT_PGI_soffset = 0x3a01, + DW_AT_PGI_lstride = 0x3a02 + }; + +#define DW_AT_lo_user 0x2000 /* Implementation-defined range start. */ +#define DW_AT_hi_user 0x3ff0 /* Implementation-defined range end. */ + +/* Location atom names and codes. */ +enum dwarf_location_atom + { + DW_OP_addr = 0x03, + DW_OP_deref = 0x06, + DW_OP_const1u = 0x08, + DW_OP_const1s = 0x09, + DW_OP_const2u = 0x0a, + DW_OP_const2s = 0x0b, + DW_OP_const4u = 0x0c, + DW_OP_const4s = 0x0d, + DW_OP_const8u = 0x0e, + DW_OP_const8s = 0x0f, + DW_OP_constu = 0x10, + DW_OP_consts = 0x11, + DW_OP_dup = 0x12, + DW_OP_drop = 0x13, + DW_OP_over = 0x14, + DW_OP_pick = 0x15, + DW_OP_swap = 0x16, + DW_OP_rot = 0x17, + DW_OP_xderef = 0x18, + DW_OP_abs = 0x19, + DW_OP_and = 0x1a, + DW_OP_div = 0x1b, + DW_OP_minus = 0x1c, + DW_OP_mod = 0x1d, + DW_OP_mul = 0x1e, + DW_OP_neg = 0x1f, + DW_OP_not = 0x20, + DW_OP_or = 0x21, + DW_OP_plus = 0x22, + DW_OP_plus_uconst = 0x23, + DW_OP_shl = 0x24, + DW_OP_shr = 0x25, + DW_OP_shra = 0x26, + DW_OP_xor = 0x27, + DW_OP_bra = 0x28, + DW_OP_eq = 0x29, + DW_OP_ge = 0x2a, + DW_OP_gt = 0x2b, + DW_OP_le = 0x2c, + DW_OP_lt = 0x2d, + DW_OP_ne = 0x2e, + DW_OP_skip = 0x2f, + DW_OP_lit0 = 0x30, + DW_OP_lit1 = 0x31, + DW_OP_lit2 = 0x32, + DW_OP_lit3 = 0x33, + DW_OP_lit4 = 0x34, + DW_OP_lit5 = 0x35, + DW_OP_lit6 = 0x36, + DW_OP_lit7 = 0x37, + DW_OP_lit8 = 0x38, + DW_OP_lit9 = 0x39, + DW_OP_lit10 = 0x3a, + DW_OP_lit11 = 0x3b, + DW_OP_lit12 = 0x3c, + DW_OP_lit13 = 0x3d, + DW_OP_lit14 = 0x3e, + DW_OP_lit15 = 0x3f, + DW_OP_lit16 = 0x40, + DW_OP_lit17 = 0x41, + DW_OP_lit18 = 0x42, + DW_OP_lit19 = 0x43, + DW_OP_lit20 = 0x44, + DW_OP_lit21 = 0x45, + DW_OP_lit22 = 0x46, + DW_OP_lit23 = 0x47, + DW_OP_lit24 = 0x48, + DW_OP_lit25 = 0x49, + DW_OP_lit26 = 0x4a, + DW_OP_lit27 = 0x4b, + DW_OP_lit28 = 0x4c, + DW_OP_lit29 = 0x4d, + DW_OP_lit30 = 0x4e, + DW_OP_lit31 = 0x4f, + DW_OP_reg0 = 0x50, + DW_OP_reg1 = 0x51, + DW_OP_reg2 = 0x52, + DW_OP_reg3 = 0x53, + DW_OP_reg4 = 0x54, + DW_OP_reg5 = 0x55, + DW_OP_reg6 = 0x56, + DW_OP_reg7 = 0x57, + DW_OP_reg8 = 0x58, + DW_OP_reg9 = 0x59, + DW_OP_reg10 = 0x5a, + DW_OP_reg11 = 0x5b, + DW_OP_reg12 = 0x5c, + DW_OP_reg13 = 0x5d, + DW_OP_reg14 = 0x5e, + DW_OP_reg15 = 0x5f, + DW_OP_reg16 = 0x60, + DW_OP_reg17 = 0x61, + DW_OP_reg18 = 0x62, + DW_OP_reg19 = 0x63, + DW_OP_reg20 = 0x64, + DW_OP_reg21 = 0x65, + DW_OP_reg22 = 0x66, + DW_OP_reg23 = 0x67, + DW_OP_reg24 = 0x68, + DW_OP_reg25 = 0x69, + DW_OP_reg26 = 0x6a, + DW_OP_reg27 = 0x6b, + DW_OP_reg28 = 0x6c, + DW_OP_reg29 = 0x6d, + DW_OP_reg30 = 0x6e, + DW_OP_reg31 = 0x6f, + DW_OP_breg0 = 0x70, + DW_OP_breg1 = 0x71, + DW_OP_breg2 = 0x72, + DW_OP_breg3 = 0x73, + DW_OP_breg4 = 0x74, + DW_OP_breg5 = 0x75, + DW_OP_breg6 = 0x76, + DW_OP_breg7 = 0x77, + DW_OP_breg8 = 0x78, + DW_OP_breg9 = 0x79, + DW_OP_breg10 = 0x7a, + DW_OP_breg11 = 0x7b, + DW_OP_breg12 = 0x7c, + DW_OP_breg13 = 0x7d, + DW_OP_breg14 = 0x7e, + DW_OP_breg15 = 0x7f, + DW_OP_breg16 = 0x80, + DW_OP_breg17 = 0x81, + DW_OP_breg18 = 0x82, + DW_OP_breg19 = 0x83, + DW_OP_breg20 = 0x84, + DW_OP_breg21 = 0x85, + DW_OP_breg22 = 0x86, + DW_OP_breg23 = 0x87, + DW_OP_breg24 = 0x88, + DW_OP_breg25 = 0x89, + DW_OP_breg26 = 0x8a, + DW_OP_breg27 = 0x8b, + DW_OP_breg28 = 0x8c, + DW_OP_breg29 = 0x8d, + DW_OP_breg30 = 0x8e, + DW_OP_breg31 = 0x8f, + DW_OP_regx = 0x90, + DW_OP_fbreg = 0x91, + DW_OP_bregx = 0x92, + DW_OP_piece = 0x93, + DW_OP_deref_size = 0x94, + DW_OP_xderef_size = 0x95, + DW_OP_nop = 0x96, + /* DWARF 3 extensions. */ + DW_OP_push_object_address = 0x97, + DW_OP_call2 = 0x98, + DW_OP_call4 = 0x99, + DW_OP_call_ref = 0x9a, + /* GNU extensions. */ + DW_OP_GNU_push_tls_address = 0xe0, + /* HP extensions. */ + DW_OP_HP_unknown = 0xe0, /* Ouch, the same as GNU_push_tls_address. */ + DW_OP_HP_is_value = 0xe1, + DW_OP_HP_fltconst4 = 0xe2, + DW_OP_HP_fltconst8 = 0xe3, + DW_OP_HP_mod_range = 0xe4, + DW_OP_HP_unmod_range = 0xe5, + DW_OP_HP_tls = 0xe6 + }; + +#define DW_OP_lo_user 0xe0 /* Implementation-defined range start. */ +#define DW_OP_hi_user 0xff /* Implementation-defined range end. */ + +/* Type encodings. */ +enum dwarf_type + { + DW_ATE_void = 0x0, + DW_ATE_address = 0x1, + DW_ATE_boolean = 0x2, + DW_ATE_complex_float = 0x3, + DW_ATE_float = 0x4, + DW_ATE_signed = 0x5, + DW_ATE_signed_char = 0x6, + DW_ATE_unsigned = 0x7, + DW_ATE_unsigned_char = 0x8, + /* DWARF 3. */ + DW_ATE_imaginary_float = 0x9, + /* HP extensions. */ + DW_ATE_HP_float80 = 0x80, /* Floating-point (80 bit). */ + DW_ATE_HP_complex_float80 = 0x81, /* Complex floating-point (80 bit). */ + DW_ATE_HP_float128 = 0x82, /* Floating-point (128 bit). */ + DW_ATE_HP_complex_float128 = 0x83, /* Complex floating-point (128 bit). */ + DW_ATE_HP_floathpintel = 0x84, /* Floating-point (82 bit IA64). */ + DW_ATE_HP_imaginary_float80 = 0x85, + DW_ATE_HP_imaginary_float128 = 0x86 + }; + +#define DW_ATE_lo_user 0x80 +#define DW_ATE_hi_user 0xff + +/* Array ordering names and codes. */ +enum dwarf_array_dim_ordering + { + DW_ORD_row_major = 0, + DW_ORD_col_major = 1 + }; + +/* Access attribute. */ +enum dwarf_access_attribute + { + DW_ACCESS_public = 1, + DW_ACCESS_protected = 2, + DW_ACCESS_private = 3 + }; + +/* Visibility. */ +enum dwarf_visibility_attribute + { + DW_VIS_local = 1, + DW_VIS_exported = 2, + DW_VIS_qualified = 3 + }; + +/* Virtuality. */ +enum dwarf_virtuality_attribute + { + DW_VIRTUALITY_none = 0, + DW_VIRTUALITY_virtual = 1, + DW_VIRTUALITY_pure_virtual = 2 + }; + +/* Case sensitivity. */ +enum dwarf_id_case + { + DW_ID_case_sensitive = 0, + DW_ID_up_case = 1, + DW_ID_down_case = 2, + DW_ID_case_insensitive = 3 + }; + +/* Calling convention. */ +enum dwarf_calling_convention + { + DW_CC_normal = 0x1, + DW_CC_program = 0x2, + DW_CC_nocall = 0x3 + }; + +#define DW_CC_lo_user 0x40 +#define DW_CC_hi_user 0xff + +/* Inline attribute. */ +enum dwarf_inline_attribute + { + DW_INL_not_inlined = 0, + DW_INL_inlined = 1, + DW_INL_declared_not_inlined = 2, + DW_INL_declared_inlined = 3 + }; + +/* Discriminant lists. */ +enum dwarf_discrim_list + { + DW_DSC_label = 0, + DW_DSC_range = 1 + }; + +/* Line number opcodes. */ +enum dwarf_line_number_ops + { + DW_LNS_extended_op = 0, + DW_LNS_copy = 1, + DW_LNS_advance_pc = 2, + DW_LNS_advance_line = 3, + DW_LNS_set_file = 4, + DW_LNS_set_column = 5, + DW_LNS_negate_stmt = 6, + DW_LNS_set_basic_block = 7, + DW_LNS_const_add_pc = 8, + DW_LNS_fixed_advance_pc = 9, + /* DWARF 3. */ + DW_LNS_set_prologue_end = 10, + DW_LNS_set_epilogue_begin = 11, + DW_LNS_set_isa = 12 + }; + +/* Line number extended opcodes. */ +enum dwarf_line_number_x_ops + { + DW_LNE_end_sequence = 1, + DW_LNE_set_address = 2, + DW_LNE_define_file = 3, + /* HP extensions. */ + DW_LNE_HP_negate_is_UV_update = 0x11, + DW_LNE_HP_push_context = 0x12, + DW_LNE_HP_pop_context = 0x13, + DW_LNE_HP_set_file_line_column = 0x14, + DW_LNE_HP_set_routine_name = 0x15, + DW_LNE_HP_set_sequence = 0x16, + DW_LNE_HP_negate_post_semantics = 0x17, + DW_LNE_HP_negate_function_exit = 0x18, + DW_LNE_HP_negate_front_end_logical = 0x19, + DW_LNE_HP_define_proc = 0x20 + }; + +/* Call frame information. */ +enum dwarf_call_frame_info + { + DW_CFA_advance_loc = 0x40, + DW_CFA_offset = 0x80, + DW_CFA_restore = 0xc0, + DW_CFA_nop = 0x00, + DW_CFA_set_loc = 0x01, + DW_CFA_advance_loc1 = 0x02, + DW_CFA_advance_loc2 = 0x03, + DW_CFA_advance_loc4 = 0x04, + DW_CFA_offset_extended = 0x05, + DW_CFA_restore_extended = 0x06, + DW_CFA_undefined = 0x07, + DW_CFA_same_value = 0x08, + DW_CFA_register = 0x09, + DW_CFA_remember_state = 0x0a, + DW_CFA_restore_state = 0x0b, + DW_CFA_def_cfa = 0x0c, + DW_CFA_def_cfa_register = 0x0d, + DW_CFA_def_cfa_offset = 0x0e, + /* DWARF 3. */ + DW_CFA_def_cfa_expression = 0x0f, + DW_CFA_expression = 0x10, + DW_CFA_offset_extended_sf = 0x11, + DW_CFA_def_cfa_sf = 0x12, + DW_CFA_def_cfa_offset_sf = 0x13, + /* SGI/MIPS specific. */ + DW_CFA_MIPS_advance_loc8 = 0x1d, + /* GNU extensions. */ + DW_CFA_GNU_window_save = 0x2d, + DW_CFA_GNU_args_size = 0x2e, + DW_CFA_GNU_negative_offset_extended = 0x2f + }; + +#define DW_CIE_ID 0xffffffff +#define DW_CIE_VERSION 1 + +#define DW_CFA_extended 0 +#define DW_CFA_lo_user 0x1c +#define DW_CFA_hi_user 0x3f + +#define DW_CHILDREN_no 0x00 +#define DW_CHILDREN_yes 0x01 + +#define DW_ADDR_none 0 + +/* Source language names and codes. */ +enum dwarf_source_language + { + DW_LANG_C89 = 0x0001, + DW_LANG_C = 0x0002, + DW_LANG_Ada83 = 0x0003, + DW_LANG_C_plus_plus = 0x0004, + DW_LANG_Cobol74 = 0x0005, + DW_LANG_Cobol85 = 0x0006, + DW_LANG_Fortran77 = 0x0007, + DW_LANG_Fortran90 = 0x0008, + DW_LANG_Pascal83 = 0x0009, + DW_LANG_Modula2 = 0x000a, + DW_LANG_Java = 0x000b, + /* DWARF 3. */ + DW_LANG_C99 = 0x000c, + DW_LANG_Ada95 = 0x000d, + DW_LANG_Fortran95 = 0x000e, + /* MIPS. */ + DW_LANG_Mips_Assembler = 0x8001, + /* UPC. */ + DW_LANG_Upc = 0x8765 + }; + +#define DW_LANG_lo_user 0x8000 /* Implementation-defined range start. */ +#define DW_LANG_hi_user 0xffff /* Implementation-defined range start. */ + +/* Names and codes for macro information. */ +enum dwarf_macinfo_record_type + { + DW_MACINFO_define = 1, + DW_MACINFO_undef = 2, + DW_MACINFO_start_file = 3, + DW_MACINFO_end_file = 4, + DW_MACINFO_vendor_ext = 255 + }; + +/* @@@ For use with GNU frame unwind information. */ + +#define DW_EH_PE_absptr 0x00 +#define DW_EH_PE_omit 0xff + +#define DW_EH_PE_uleb128 0x01 +#define DW_EH_PE_udata2 0x02 +#define DW_EH_PE_udata4 0x03 +#define DW_EH_PE_udata8 0x04 +#define DW_EH_PE_sleb128 0x09 +#define DW_EH_PE_sdata2 0x0A +#define DW_EH_PE_sdata4 0x0B +#define DW_EH_PE_sdata8 0x0C +#define DW_EH_PE_signed 0x08 + +#define DW_EH_PE_pcrel 0x10 +#define DW_EH_PE_textrel 0x20 +#define DW_EH_PE_datarel 0x30 +#define DW_EH_PE_funcrel 0x40 +#define DW_EH_PE_aligned 0x50 + +#define DW_EH_PE_indirect 0x80 + +#endif /* _ELF_DWARF2_H */ --- linux-2.6.20.orig/include/linux/i2c.h +++ linux-2.6.20/include/linux/i2c.h @@ -144,10 +144,13 @@ struct i2c_driver { * function is mainly used for lookup & other admin. functions. */ struct i2c_client { unsigned int flags; /* div., see below */ unsigned short addr; /* chip address - NOTE: 7bit */ +/* id field added in accordance with the 2.4 version of i2c subsystem && all drivers using i2c know device id so removing this needs changes in all drivers */ + + int id; /* addresses are stored in the */ /* _LOWER_ 7 bits */ struct i2c_adapter *adapter; /* the adapter we sit on */ struct i2c_driver *driver; /* and our access routines */ int usage_count; /* How many accesses currently */ @@ -212,12 +215,22 @@ struct i2c_adapter { void *algo_data; /* --- administration stuff. */ int (*client_register)(struct i2c_client *); int (*client_unregister)(struct i2c_client *); + /******ADDED IN consistency with previous i2c subsystem*********/ + void *data; /* private data for the adapter */ + /* some data fields that are used by all types */ + /* these data fields are readonly to the public */ + /* and can be set via the i2c_ioctl call */ + + /* data fields that are valid for all devices */ /* data fields that are valid for all devices */ + struct semaphore lock; + + /******ADDED IN consistency with previous i2c subsystem*********/ u8 level; /* nesting level for lockdep */ struct mutex bus_lock; struct mutex clist_lock; int timeout; --- /dev/null +++ linux-2.6.20/include/linux/kgdb.h @@ -0,0 +1,271 @@ +/* + * include/linux/kgdb.h + * + * This provides the hooks and functions that KGDB needs to share between + * the core, I/O and arch-specific portions. + * + * Author: Amit Kale and + * Tom Rini + * + * 2001-2004 (c) Amit S. Kale and 2003-2005 (c) MontaVista Software, Inc. + * This file is licensed under the terms of the GNU General Public License + * version 2. This program is licensed "as is" without any warranty of any + * kind, whether express or implied. + */ +#ifdef __KERNEL__ +#ifndef _KGDB_H_ +#define _KGDB_H_ + +#include + +#ifdef CONFIG_KGDB +#include +#include +#include +#include + +struct tasklet_struct; +struct pt_regs; +struct task_struct; +struct uart_port; + + +/* To enter the debugger explicitly. */ +extern void breakpoint(void); +extern int kgdb_connected; +extern int kgdb_may_fault; +extern struct tasklet_struct kgdb_tasklet_breakpoint; + +extern atomic_t kgdb_setting_breakpoint; +extern atomic_t cpu_doing_single_step; +extern atomic_t kgdb_sync_softlockup[NR_CPUS]; + +extern struct task_struct *kgdb_usethread, *kgdb_contthread; + +enum kgdb_bptype { + bp_breakpoint = '0', + bp_hardware_breakpoint, + bp_write_watchpoint, + bp_read_watchpoint, + bp_access_watchpoint +}; + +enum kgdb_bpstate { + bp_none = 0, + bp_removed, + bp_set, + bp_active +}; + +struct kgdb_bkpt { + unsigned long bpt_addr; + unsigned char saved_instr[BREAK_INSTR_SIZE]; + enum kgdb_bptype type; + enum kgdb_bpstate state; +}; + +/* The maximum number of KGDB I/O modules that can be loaded */ +#define MAX_KGDB_IO_HANDLERS 3 + +#ifndef MAX_BREAKPOINTS +#define MAX_BREAKPOINTS 1000 +#endif + +#define KGDB_HW_BREAKPOINT 1 + +/* Required functions. */ +/** + * regs_to_gdb_regs - Convert ptrace regs to GDB regs + * @gdb_regs: A pointer to hold the registers in the order GDB wants. + * @regs: The &struct pt_regs of the current process. + * + * Convert the pt_regs in @regs into the format for registers that + * GDB expects, stored in @gdb_regs. + */ +extern void regs_to_gdb_regs(unsigned long *gdb_regs, struct pt_regs *regs); + +/** + * sleeping_regs_to_gdb_regs - Convert ptrace regs to GDB regs + * @gdb_regs: A pointer to hold the registers in the order GDB wants. + * @p: The &struct task_struct of the desired process. + * + * Convert the register values of the sleeping process in @p to + * the format that GDB expects. + * This function is called when kgdb does not have access to the + * &struct pt_regs and therefore it should fill the gdb registers + * @gdb_regs with what has been saved in &struct thread_struct + * thread field during switch_to. + */ +extern void sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, + struct task_struct *p); + +/** + * gdb_regs_to_regs - Convert GDB regs to ptrace regs. + * @gdb_regs: A pointer to hold the registers we've recieved from GDB. + * @regs: A pointer to a &struct pt_regs to hold these values in. + * + * Convert the GDB regs in @gdb_regs into the pt_regs, and store them + * in @regs. + */ +extern void gdb_regs_to_regs(unsigned long *gdb_regs, struct pt_regs *regs); + +/** + * kgdb_arch_handle_exception - Handle architecture specific GDB packets. + * @vector: The error vector of the exception that happened. + * @signo: The signal number of the exception that happened. + * @err_code: The error code of the exception that happened. + * @remcom_in_buffer: The buffer of the packet we have read. + * @remcom_out_buffer: The buffer, of %BUFMAX to write a packet into. + * @regs: The &struct pt_regs of the current process. + * + * This function MUST handle the 'c' and 's' command packets, + * as well packets to set / remove a hardware breakpoint, if used. + * If there are additional packets which the hardware needs to handle, + * they are handled here. The code should return -1 if it wants to + * process more packets, and a %0 or %1 if it wants to exit from the + * kgdb hook. + */ +extern int kgdb_arch_handle_exception(int vector, int signo, int err_code, + char *remcom_in_buffer, + char *remcom_out_buffer, + struct pt_regs *regs); + +#ifndef JMP_REGS_ALIGNMENT +#define JMP_REGS_ALIGNMENT +#endif + +extern unsigned long kgdb_fault_jmp_regs[]; + +/** + * kgdb_fault_setjmp - Store state in case we fault. + * @curr_context: An array to store state into. + * + * Certain functions may try and access memory, and in doing so may + * cause a fault. When this happens, we trap it, restore state to + * this call, and let ourself know that something bad has happened. + */ +extern asmlinkage int kgdb_fault_setjmp(unsigned long *curr_context); + +/** + * kgdb_fault_longjmp - Restore state when we have faulted. + * @curr_context: The previously stored state. + * + * When something bad does happen, this function is called to + * restore the known good state, and set the return value to 1, so + * we know something bad happened. + */ +extern asmlinkage void kgdb_fault_longjmp(unsigned long *curr_context); + +/* Optional functions. */ +extern int kgdb_arch_init(void); +extern void kgdb_disable_hw_debug(struct pt_regs *regs); +extern void kgdb_post_master_code(struct pt_regs *regs, int e_vector, + int err_code); +extern void kgdb_roundup_cpus(unsigned long flags); +extern int kgdb_set_hw_break(unsigned long addr); +extern int kgdb_remove_hw_break(unsigned long addr); +extern void kgdb_remove_all_hw_break(void); +extern void kgdb_correct_hw_break(void); +extern void kgdb_shadowinfo(struct pt_regs *regs, char *buffer, + unsigned threadid); +extern struct task_struct *kgdb_get_shadow_thread(struct pt_regs *regs, + int threadid); +extern struct pt_regs *kgdb_shadow_regs(struct pt_regs *regs, int threadid); +extern int kgdb_validate_break_address(unsigned long addr); +extern int kgdb_arch_set_breakpoint(unsigned long addr, char *saved_instr); +extern int kgdb_arch_remove_breakpoint(unsigned long addr, char *bundle); + +/** + * struct kgdb_arch - Desribe architecture specific values. + * @gdb_bpt_instr: The instruction to trigger a breakpoint. + * @flags: Flags for the breakpoint, currently just %KGDB_HW_BREAKPOINT. + * @shadowth: A value of %1 indicates we shadow information on processes. + * @set_breakpoint: Allow an architecture to specify how to set a software + * breakpoint. + * @remove_breakpoint: Allow an architecture to specify how to remove a + * software breakpoint. + * @set_hw_breakpoint: Allow an architecture to specify how to set a hardware + * breakpoint. + * @remove_hw_breakpoint: Allow an architecture to specify how to remove a + * hardware breakpoint. + * + * The @shadowth flag is an option to shadow information not retrievable by + * gdb otherwise. This is deprecated in favor of a binutils which supports + * CFI macros. + */ +struct kgdb_arch { + unsigned char gdb_bpt_instr[BREAK_INSTR_SIZE]; + unsigned long flags; + unsigned shadowth; + int (*set_breakpoint) (unsigned long, char *); + int (*remove_breakpoint)(unsigned long, char *); + int (*set_hw_breakpoint)(unsigned long, int, enum kgdb_bptype); + int (*remove_hw_breakpoint)(unsigned long, int, enum kgdb_bptype); +}; + +/* Thread reference */ +typedef unsigned char threadref[8]; + +/** + * struct kgdb_io - Desribe the interface for an I/O driver to talk with KGDB. + * @read_char: Pointer to a function that will return one char. + * @write_char: Pointer to a function that will write one char. + * @flush: Pointer to a function that will flush any pending writes. + * @init: Pointer to a function that will initialize the device. + * @late_init: Pointer to a function that will do any setup that has + * other dependencies. + * @pre_exception: Pointer to a function that will do any prep work for + * the I/O driver. + * @post_exception: Pointer to a function that will do any cleanup work + * for the I/O driver. + * + * The @init and @late_init function pointers allow for an I/O driver + * such as a serial driver to fully initialize the port with @init and + * be called very early, yet safely call request_irq() later in the boot + * sequence. + * + * @init is allowed to return a non-0 return value to indicate failure. + * If this is called early on, then KGDB will try again when it would call + * @late_init. If it has failed later in boot as well, the user will be + * notified. + */ +struct kgdb_io { + int (*read_char) (void); + void (*write_char) (u8); + void (*flush) (void); + int (*init) (void); + void (*late_init) (void); + void (*pre_exception) (void); + void (*post_exception) (void); +}; + +extern struct kgdb_io kgdb_io_ops; +extern struct kgdb_arch arch_kgdb_ops; +extern int kgdb_initialized; + +extern int kgdb_register_io_module(struct kgdb_io *local_kgdb_io_ops); +extern void kgdb_unregister_io_module(struct kgdb_io *local_kgdb_io_ops); + +extern void __init kgdb8250_add_port(int i, struct uart_port *serial_req); +extern void __init kgdb8250_add_platform_port(int i, struct plat_serial8250_port *serial_req); + +extern int kgdb_hex2long(char **ptr, long *long_val); +extern char *kgdb_mem2hex(char *mem, char *buf, int count); +extern char *kgdb_hex2mem(char *buf, char *mem, int count); +extern int kgdb_get_mem(char *addr, unsigned char *buf, int count); +extern int kgdb_set_mem(char *addr, unsigned char *buf, int count); + +int kgdb_isremovedbreak(unsigned long addr); +int kgdb_skipexception(int exception, struct pt_regs *regs); + +extern int kgdb_handle_exception(int ex_vector, int signo, int err_code, + struct pt_regs *regs); +extern void kgdb_nmihook(int cpu, void *regs); +extern int debugger_step; +extern atomic_t debugger_active; +#else +/* Stubs for when KGDB is not set. */ +static const atomic_t debugger_active = ATOMIC_INIT(0); +#endif /* CONFIG_KGDB */ +#endif /* _KGDB_H_ */ +#endif /* __KERNEL__ */ --- linux-2.6.20.orig/include/linux/miscdevice.h +++ linux-2.6.20/include/linux/miscdevice.h @@ -10,10 +10,11 @@ #define ATARIMOUSE_MINOR 5 #define SUN_MOUSE_MINOR 6 #define APOLLO_MOUSE_MINOR 7 #define PC110PAD_MINOR 9 /*#define ADB_MOUSE_MINOR 10 FIXME OBSOLETE */ +#define TOUCHP_MINOR 20 /* touch panel as misc device */ #define WATCHDOG_MINOR 130 /* Watchdog timer */ #define TEMP_MINOR 131 /* Temperature Sensor */ #define RTC_MINOR 135 #define EFI_RTC_MINOR 136 /* EFI Time services */ #define SUN_OPENPROM_MINOR 139 --- linux-2.6.20.orig/include/linux/module.h +++ linux-2.6.20/include/linux/module.h @@ -32,10 +32,13 @@ struct kernel_symbol { unsigned long value; const char *name; +#ifdef CONFIG_LKM_HASH + unsigned long hash_value; +#endif }; struct modversion_info { unsigned long crc; @@ -184,21 +187,28 @@ void *__symbol_get_gpl(const char *symbo = (unsigned long) &__crc_##sym; #else #define __CRC_SYMBOL(sym, sec) #endif +#ifdef CONFIG_LKM_HASH +#define MAGIC_HASH_VALUE 0x13121973 +#define KERNEL_SYMBOL_EXTRA_FIELD , MAGIC_HASH_VALUE +#else +#define KERNEL_SYMBOL_EXTRA_FIELD +#endif + /* For every exported symbol, place a struct in the __ksymtab section */ #define __EXPORT_SYMBOL(sym, sec) \ extern typeof(sym) sym; \ __CRC_SYMBOL(sym, sec) \ static const char __kstrtab_##sym[] \ __attribute__((section("__ksymtab_strings"))) \ = MODULE_SYMBOL_PREFIX #sym; \ static const struct kernel_symbol __ksymtab_##sym \ __attribute_used__ \ __attribute__((section("__ksymtab" sec), unused)) \ - = { (unsigned long)&sym, __kstrtab_##sym } + = { (unsigned long)&sym, __kstrtab_##sym KERNEL_SYMBOL_EXTRA_FIELD} #define EXPORT_SYMBOL(sym) \ __EXPORT_SYMBOL(sym, "") #define EXPORT_SYMBOL_GPL(sym) \ @@ -226,12 +236,21 @@ struct module_ref enum module_state { MODULE_STATE_LIVE, MODULE_STATE_COMING, MODULE_STATE_GOING, + MODULE_STATE_GONE, }; +#ifdef CONFIG_KGDB +#define MAX_SECTNAME 31 +struct mod_section { + void *address; + char name[MAX_SECTNAME + 1]; +}; +#endif + /* Similar stuff for section attributes. */ struct module_sect_attr { struct module_attribute mattr; char *name; @@ -255,10 +274,17 @@ struct module struct list_head list; /* Unique handle for this module */ char name[MODULE_NAME_LEN]; +#ifdef CONFIG_KGDB + /* keep kgdb info at the begining so that gdb doesn't have a chance to + * miss out any fields */ + unsigned long num_sections; + struct mod_section *mod_sections; +#endif + /* Sysfs stuff. */ struct module_kobject mkobj; struct module_param_attrs *param_attrs; struct module_attribute *modinfo_attrs; const char *version; --- linux-2.6.20.orig/include/linux/mtd/bbm.h +++ linux-2.6.20/include/linux/mtd/bbm.h @@ -8,10 +8,14 @@ * Kyungmin Park * * Copyright (c) 2000-2005 * Thomas Gleixner * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * */ #ifndef __LINUX_MTD_BBM_H #define __LINUX_MTD_BBM_H /* The maximum number of NAND chips in an array */ @@ -90,10 +94,17 @@ struct nand_bbt_descr { /* * Constants for oob configuration */ #define ONENAND_BADBLOCK_POS 0 +/* + * Bad block scanning errors + */ +#define ONENAND_BBT_READ_ERROR 1 +#define ONENAND_BBT_READ_ECC_ERROR 2 +#define ONENAND_BBT_READ_FATAL_ERROR 4 + /** * struct bbm_info - [GENERIC] Bad Block Table data structure * @bbt_erase_shift: [INTERN] number of address bits in a bbt entry * @badblockpos: [INTERN] position of the bad block marker in the oob area * @options: options for this descriptor --- linux-2.6.20.orig/include/linux/mtd/mtd.h +++ linux-2.6.20/include/linux/mtd/mtd.h @@ -117,10 +117,11 @@ struct mtd_info { u_int32_t writesize; u_int32_t oobsize; // Amount of OOB data per block (e.g. 16) u_int32_t ecctype; u_int32_t eccsize; + u_int32_t oobavail; // Available OOB bytes per block /* * Reuse some of the above unused fields in the case of NOR flash * with configurable programming regions to avoid modifying the * user visible structure layout/size. Only valid when the --- linux-2.6.20.orig/include/linux/mtd/nand.h +++ linux-2.6.20/include/linux/mtd/nand.h @@ -544,56 +544,14 @@ extern int nand_do_read(struct mtd_info size_t * retlen, uint8_t * buf); /* * Constants for oob configuration */ +#if defined (CONFIG_ARCH_NOMADIK) +#define NAND_SMALL_BADBLOCK_POS 1 +#define NAND_LARGE_BADBLOCK_POS 5 +#else #define NAND_SMALL_BADBLOCK_POS 5 #define NAND_LARGE_BADBLOCK_POS 0 - -/** - * struct platform_nand_chip - chip level device structure - * @nr_chips: max. number of chips to scan for - * @chip_offset: chip number offset - * @nr_partitions: number of partitions pointed to by partitions (or zero) - * @partitions: mtd partition list - * @chip_delay: R/B delay value in us - * @options: Option flags, e.g. 16bit buswidth - * @ecclayout: ecc layout info structure - * @priv: hardware controller specific settings - */ -struct platform_nand_chip { - int nr_chips; - int chip_offset; - int nr_partitions; - struct mtd_partition *partitions; - struct nand_ecclayout *ecclayout; - int chip_delay; - unsigned int options; - void *priv; -}; - -/** - * struct platform_nand_ctrl - controller level device structure - * @hwcontrol: platform specific hardware control structure - * @dev_ready: platform specific function to read ready/busy pin - * @select_chip: platform specific chip select function - * @priv: private data to transport driver specific settings - * - * All fields are optional and depend on the hardware driver requirements - */ -struct platform_nand_ctrl { - void (*hwcontrol)(struct mtd_info *mtd, int cmd); - int (*dev_ready)(struct mtd_info *mtd); - void (*select_chip)(struct mtd_info *mtd, int chip); - void *priv; -}; - -/* Some helpers to access the data structures */ -static inline -struct platform_nand_chip *get_platform_nandchip(struct mtd_info *mtd) -{ - struct nand_chip *chip = mtd->priv; - - return chip->priv; -} +#endif #endif /* __LINUX_MTD_NAND_H */ --- linux-2.6.20.orig/include/linux/mtd/onenand.h +++ linux-2.6.20/include/linux/mtd/onenand.h @@ -40,18 +40,14 @@ typedef enum { FL_PM_SUSPENDED, } onenand_state_t; /** * struct onenand_bufferram - OneNAND BufferRAM Data - * @block: block address in BufferRAM - * @page: page address in BufferRAM - * @valid: valid flag + * @blockpage: block & page address in BufferRAM */ struct onenand_bufferram { - int block; - int page; - int valid; + int blockpage; }; /** * struct onenand_chip - OneNAND Private Flash Chip Data * @base: [BOARDSPECIFIC] address to access OneNAND @@ -61,12 +57,12 @@ struct onenand_bufferram { * @verstion_id: [INTERN] version ID * @options: [BOARDSPECIFIC] various chip options. They can * partly be set to inform onenand_scan about * @erase_shift: [INTERN] number of address bits in a block * @page_shift: [INTERN] number of address bits in a page - * @ppb_shift: [INTERN] number of address bits in a pages per block * @page_mask: [INTERN] a page per block mask + * @writesize: [INTERN] a real page size * @bufferram_index: [INTERN] BufferRAM index * @bufferram: [INTERN] BufferRAM info * @readw: [REPLACEABLE] hardware specific function for read short * @writew: [REPLACEABLE] hardware specific function for write short * @command: [REPLACEABLE] hardware specific function for writing @@ -85,11 +81,12 @@ struct onenand_bufferram { * @chip_lock: [INTERN] spinlock used to protect access to this * structure and the chip * @wq: [INTERN] wait queue to sleep on if a OneNAND * operation is in progress * @state: [INTERN] the current state of the OneNAND device - * @page_buf: data buffer + * @page_buf: [INTERN] page main data buffer + * @oob_buf: [INTERN] page oob data buffer * @subpagesize: [INTERN] holds the subpagesize * @ecclayout: [REPLACEABLE] the default ecc placement scheme * @bbm: [REPLACEABLE] pointer to Bad Block Management * @priv: [OPTIONAL] pointer to private chip date */ @@ -101,12 +98,12 @@ struct onenand_chip { unsigned int density_mask; unsigned int options; unsigned int erase_shift; unsigned int page_shift; - unsigned int ppb_shift; /* Pages per block shift */ unsigned int page_mask; + unsigned int writesize; unsigned int bufferram_index; struct onenand_bufferram bufferram[MAX_BUFFERRAM]; int (*command)(struct mtd_info *mtd, int cmd, loff_t address, size_t len); @@ -126,10 +123,11 @@ struct onenand_chip { spinlock_t chip_lock; wait_queue_head_t wq; onenand_state_t state; unsigned char *page_buf; + unsigned char *oob_buf; int subpagesize; struct nand_ecclayout *ecclayout; void *bbm; @@ -142,25 +140,39 @@ struct onenand_chip { */ #define ONENAND_CURRENT_BUFFERRAM(this) (this->bufferram_index) #define ONENAND_NEXT_BUFFERRAM(this) (this->bufferram_index ^ 1) #define ONENAND_SET_NEXT_BUFFERRAM(this) (this->bufferram_index ^= 1) #define ONENAND_SET_PREV_BUFFERRAM(this) (this->bufferram_index ^= 1) +#define ONENAND_SET_BUFFERRAM0(this) (this->bufferram_index = 0) +#define ONENAND_SET_BUFFERRAM1(this) (this->bufferram_index = 1) #define ONENAND_GET_SYS_CFG1(this) \ (this->read_word(this->base + ONENAND_REG_SYS_CFG1)) #define ONENAND_SET_SYS_CFG1(v, this) \ (this->write_word(v, this->base + ONENAND_REG_SYS_CFG1)) +#define ONENAND_IS_DDP(this) \ + (this->device_id & ONENAND_DEVICE_IS_DDP) + +#ifdef CONFIG_MTD_ONENAND_2X_PROGRAM +#define ONENAND_IS_2PLANE(this) \ + (this->options & ONENAND_HAS_2PLANE) +#else +#define ONENAND_IS_2PLANE(this) (0) +#endif + /* Check byte access in OneNAND */ #define ONENAND_CHECK_BYTE_ACCESS(addr) (addr & 0x1) /* * Options bits */ #define ONENAND_HAS_CONT_LOCK (0x0001) #define ONENAND_HAS_UNLOCK_ALL (0x0002) +#define ONENAND_HAS_2PLANE (0x0004) #define ONENAND_PAGEBUF_ALLOC (0x1000) +#define ONENAND_OOBBUF_ALLOC (0x2000) /* * OneNAND Flash Manufacturer ID Codes */ #define ONENAND_MFR_SAMSUNG 0xec @@ -174,5 +186,6 @@ struct onenand_manufacturers { int id; char *name; }; #endif /* __LINUX_MTD_ONENAND_H */ + --- linux-2.6.20.orig/include/linux/mtd/onenand_regs.h +++ linux-2.6.20/include/linux/mtd/onenand_regs.h @@ -71,20 +71,24 @@ #define ONENAND_DEVICE_IS_DEMUX (1 << 2) #define ONENAND_DEVICE_VCC_MASK (0x3) #define ONENAND_DEVICE_DENSITY_512Mb (0x002) #define ONENAND_DEVICE_DENSITY_1Gb (0x003) +#define ONENAND_DEVICE_DENSITY_2Gb (0x004) +#define ONENAND_DEVICE_DENSITY_4Gb (0x005) /* * Version ID Register F002h (R) */ #define ONENAND_VERSION_PROCESS_SHIFT (8) /* - * Start Address 1 F100h (R/W) + * Start Address 1 F100h (R/W) & Start Address 2 F101h (R/W) */ #define ONENAND_DDP_SHIFT (15) +#define ONENAND_DDP_CHIP0 (0) +#define ONENAND_DDP_CHIP1 (1 << ONENAND_DDP_SHIFT) /* * Start Address 8 F107h (R/W) */ #define ONENAND_FPA_MASK (0x3f) @@ -106,10 +110,12 @@ */ #define ONENAND_CMD_READ (0x00) #define ONENAND_CMD_READOOB (0x13) #define ONENAND_CMD_PROG (0x80) #define ONENAND_CMD_PROGOOB (0x1A) +#define ONENAND_CMD_2X_PROG (0x7D) +#define ONENAND_CMD_2X_CACHE_PROG (0x7F) #define ONENAND_CMD_UNLOCK (0x23) #define ONENAND_CMD_LOCK (0x2A) #define ONENAND_CMD_LOCK_TIGHT (0x2C) #define ONENAND_CMD_UNLOCK_ALL (0x27) #define ONENAND_CMD_ERASE (0x94) --- linux-2.6.20.orig/include/linux/netpoll.h +++ linux-2.6.20/include/linux/netpoll.h @@ -14,11 +14,11 @@ struct netpoll { struct net_device *dev; char dev_name[IFNAMSIZ]; const char *name; - void (*rx_hook)(struct netpoll *, int, char *, int); + void (*rx_hook)(struct netpoll *, int, char *, int, struct sk_buff *); u32 local_ip, remote_ip; u16 local_port, remote_port; u8 local_mac[ETH_ALEN], remote_mac[ETH_ALEN]; }; --- linux-2.6.20.orig/include/linux/usb.h +++ linux-2.6.20/include/linux/usb.h @@ -285,11 +285,13 @@ struct usb_bus { * round-robin allocation */ struct usb_devmap devmap; /* device address allocation map */ struct usb_device *root_hub; /* Root hub */ struct list_head bus_list; /* list of busses */ - +#if defined (CONFIG_NOMADIK_NHK15) + void *hcpriv; /* Host Controller private data - FIXME hack !!*/ +#endif int bandwidth_allocated; /* on this bus: how much of the time * reserved for periodic (intr/iso) * requests is used, on average? * Units: microseconds/frame. * Limits: Full/low speed reserve 90%, --- /dev/null +++ linux-2.6.20/include/linux/v4l2-nomadikdefs.h @@ -0,0 +1,12 @@ +/* ST Microelectronic Proprietary + File: v4l2-nomadikdefs.h + Contains custom V4L2 definition +*/ +#include + +#define V4L2_PIX_FMT_YUV420_MB v4l2_fourcc('S','T','M','B') //v4l2_fourcc('Y','U','V','m') /* YUV 420 MacroBlock */ +#define V4L2_PIX_FMT_YUV420_YUMB v4l2_fourcc('Y','U','M','B') /* YUV 420 MacroBlock Buffid Passing */ + +#define V4L2_CID_CROP (V4L2_CID_PRIVATE_BASE+0) +#define V4L2_CID_RESIZE (V4L2_CID_PRIVATE_BASE+1) + --- linux-2.6.20.orig/include/linux/videodev2.h +++ linux-2.6.20/include/linux/videodev2.h @@ -1338,10 +1338,21 @@ struct v4l2_streamparm #if 1 #define VIDIOC_ENUM_FRAMESIZES _IOWR ('V', 74, struct v4l2_frmsizeenum) #define VIDIOC_ENUM_FRAMEINTERVALS _IOWR ('V', 75, struct v4l2_frmivalenum) #endif +/* Added for IQ camera tuning and exposing SVA dynamic config to v4l2 application using private ioctl */ +//#define VIDIOC_COPY_CAM_PARAMS _IOWR ('V', 76, struct nomadik_vpip_param) +#define VIDIOC_SVA_CONFIG _IOWR ('V', BASE_VIDIOC_PRIVATE+0, struct v4l2_control) +#define VIDIOC_COPY_CAM_PARAMS _IOWR ('V', BASE_VIDIOC_PRIVATE+1, struct nomadik_vpip_param) +#define VIDIOC_VPIP_VERSION _IOWR ('V', BASE_VIDIOC_PRIVATE+2, int ) +#define VIDIOC_VPIP_USER_MODE _IOWR ('V', BASE_VIDIOC_PRIVATE+3, vpip_user_mode) +#define VIDIOC_VPIP_SCENE_MODE _IOWR ('V', BASE_VIDIOC_PRIVATE+4, vpip_scene_mode) +#define VIDIOC_VPIP_AUTO_FOCUS _IOWR ('V', BASE_VIDIOC_PRIVATE+5, int) +#define VIDIOC_VPIP_PRESCALE _IOWR ('V', BASE_VIDIOC_PRIVATE+6, int) + + #ifdef __OLD_VIDIOC_ /* for compatibility, will go away some day */ #define VIDIOC_OVERLAY_OLD _IOWR ('V', 14, int) #define VIDIOC_S_PARM_OLD _IOW ('V', 22, struct v4l2_streamparm) #define VIDIOC_S_CTRL_OLD _IOW ('V', 28, struct v4l2_control) --- linux-2.6.20.orig/init/Kconfig +++ linux-2.6.20/init/Kconfig @@ -559,10 +559,25 @@ config KMOD here, some parts of the kernel will be able to load modules automatically: when a part of the kernel needs a module, it runs modprobe with the appropriate arguments, thereby loading the module if it is available. If unsure, say Y. +config LKM_HASH + bool "Enable hash support for fast loading" + depends on MODULES + default n + help + Enable a new feature to extend kernel symbol tables structure + adding a new field for hash values that can be used at module + load time to resolve undefined symbols against kernel and modules + exported ones. This will avoid to perform string comparisons + for each exported symbols by using hash value to discard not matching + symbols. This feature will improve kernel module loading time. + An ad hoc host application will analyse kernel image and kernel modules + once linked, modifying their kernel symbol tables and computing + at build time GNU hash values. + config STOP_MACHINE bool default y depends on (SMP && MODULE_UNLOAD) || HOTPLUG_CPU help --- linux-2.6.20.orig/kernel/Makefile +++ linux-2.6.20/kernel/Makefile @@ -39,10 +39,11 @@ obj-$(CONFIG_CPUSETS) += cpuset.o obj-$(CONFIG_IKCONFIG) += configs.o obj-$(CONFIG_STOP_MACHINE) += stop_machine.o obj-$(CONFIG_AUDIT) += audit.o auditfilter.o obj-$(CONFIG_AUDITSYSCALL) += auditsc.o obj-$(CONFIG_KPROBES) += kprobes.o +obj-$(CONFIG_KGDB) += kgdb.o obj-$(CONFIG_SYSFS) += ksysfs.o obj-$(CONFIG_DETECT_SOFTLOCKUP) += softlockup.o obj-$(CONFIG_GENERIC_HARDIRQS) += irq/ obj-$(CONFIG_SECCOMP) += seccomp.o obj-$(CONFIG_RCU_TORTURE_TEST) += rcutorture.o --- /dev/null +++ linux-2.6.20/kernel/kgdb.c @@ -0,0 +1,1963 @@ +/* + * kernel/kgdb.c + * + * Maintainer: Tom Rini + * + * Copyright (C) 2000-2001 VERITAS Software Corporation. + * Copyright (C) 2002-2004 Timesys Corporation + * Copyright (C) 2003-2004 Amit S. Kale + * Copyright (C) 2004 Pavel Machek + * Copyright (C) 2004-2005 Tom Rini + * Copyright (C) 2004-2006 LinSysSoft Technologies Pvt. Ltd. + * Copyright (C) 2005 Wind River Systems, Inc. + * + * Contributors at various stages not listed above: + * Jason Wessel ( jason.wessel@windriver.com ) + * George Anzinger + * Anurekh Saxena (anurekh.saxena@timesys.com) + * Lake Stevens Instrument Division (Glenn Engel) + * Jim Kingdon, Cygnus Support. + * + * Original KGDB stub: David Grothe , + * Tigran Aivazian + * + * This file is licensed under the terms of the GNU General Public License + * version 2. This program is licensed "as is" without any warranty of any + * kind, whether express or implied. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +extern int pid_max; +extern int pidhash_init_done; + +/* How many times to count all of the waiting CPUs */ +#define ROUNDUP_WAIT 640000 /* Arbitrary, increase if needed. */ +#define BUF_THREAD_ID_SIZE 16 + +/* + * kgdb_initialized with a value of 1 indicates that kgdb is setup and is + * all ready to serve breakpoints and other kernel exceptions. A value of + * -1 indicates that we have tried to initialize early, and need to try + * again later. + */ +int kgdb_initialized; +/* Is a host GDB connected to us? */ +int kgdb_connected; +/* Could we be about to try and access a bad memory location? If so we + * also need to flag this has happend. */ +int kgdb_may_fault; +/* All the KGDB handlers are installed */ +int kgdb_from_module_registered = 0; + +/* We provide a kgdb_io_ops structure that may be overriden. */ +struct kgdb_io __attribute__ ((weak)) kgdb_io_ops; + +static struct kgdb_io kgdb_io_ops_prev[MAX_KGDB_IO_HANDLERS]; +static int kgdb_io_handler_cnt = 0; + +/* Export the following symbols for use with kernel modules */ +EXPORT_SYMBOL(kgdb_io_ops); +EXPORT_SYMBOL(kgdb_tasklet_breakpoint); +EXPORT_SYMBOL(kgdb_connected); +EXPORT_SYMBOL(kgdb_register_io_module); +EXPORT_SYMBOL(kgdb_unregister_io_module); +EXPORT_SYMBOL(debugger_active); + +/* + * Holds information about breakpoints in a kernel. These breakpoints are + * added and removed by gdb. + */ +struct kgdb_bkpt kgdb_break[MAX_BREAKPOINTS]; + +struct kgdb_arch *kgdb_ops = &arch_kgdb_ops; + +static const char hexchars[] = "0123456789abcdef"; + +static spinlock_t slavecpulocks[NR_CPUS]; +static atomic_t procindebug[NR_CPUS]; +atomic_t kgdb_setting_breakpoint; +EXPORT_SYMBOL(kgdb_setting_breakpoint); +struct task_struct *kgdb_usethread, *kgdb_contthread; + +int debugger_step; +atomic_t debugger_active; + +/* Our I/O buffers. */ +static char remcom_in_buffer[BUFMAX]; +static char remcom_out_buffer[BUFMAX]; +/* Storage for the registers, in GDB format. */ +static unsigned long gdb_regs[(NUMREGBYTES + sizeof(unsigned long) - 1) / + sizeof(unsigned long)]; +/* Storage of registers for handling a fault. */ +unsigned long kgdb_fault_jmp_regs[NUMCRITREGBYTES / sizeof(unsigned long)] + JMP_REGS_ALIGNMENT; +static int kgdb_notify_reboot(struct notifier_block *this, + unsigned long code ,void *x); +struct debuggerinfo_struct { + void *debuggerinfo; + struct task_struct *task; +} kgdb_info[NR_CPUS]; + +/* to keep track of the CPU which is doing the single stepping*/ +atomic_t cpu_doing_single_step = ATOMIC_INIT(-1); + +atomic_t kgdb_sync_softlockup[NR_CPUS] = {ATOMIC_INIT(0)}; + +/* reboot notifier block */ +static struct notifier_block kgdb_reboot_notifier = { + .notifier_call = kgdb_notify_reboot, + .next = NULL, + .priority = INT_MAX, +}; + +/** + * kgdb_arch_init - Perform any architecture specific initalization. + * + * RETURN: + * The return value is ignored. + * + * This function will handle the initalization of any architecture + * specific hooks. + */ +int __attribute__ ((weak)) + kgdb_arch_init(void) +{ + return 0; +} + +/** + * kgdb_disable_hw_debug - Disable hardware debugging while we in kgdb. + * @regs: Current &struct pt_regs. + * + * This function will be called if the particular architecture must + * disable hardware debugging while it is processing gdb packets or + * handling exception. + */ +void __attribute__ ((weak)) + kgdb_disable_hw_debug(struct pt_regs *regs) +{ +} + +/* + * Skip an int3 exception when it occurs after a breakpoint has been + * removed. Backtrack eip by 1 since the int3 would have caused it to + * increment by 1. + */ +int __attribute__ ((weak)) + kgdb_skipexception(int exception, struct pt_regs *regs) +{ + return 0; +} + +/** + * kgdb_set_hw_break - Set a hardware breakpoint at @addr. + * @addr: The address to set a hardware breakpoint at. + */ +int __attribute__ ((weak)) + kgdb_set_hw_break(unsigned long addr) +{ + return 0; +} + +/** + * kgdb_remove_hw_break - Remove a hardware breakpoint at @addr. + * @addr: The address to remove a hardware breakpoint from. + */ +int __attribute__ ((weak)) + kgdb_remove_hw_break(unsigned long addr) +{ + return 0; +} + +/** + * kgdb_remove_all_hw_break - Clear all hardware breakpoints. + */ +void __attribute__ ((weak)) + kgdb_remove_all_hw_break(void) +{ +} + +/** + * kgdb_correct_hw_break - Correct hardware breakpoints. + * + * A hook to allow for changes to the hardware breakpoint, called + * after a single step (s) or continue (c) packet, and once we're about + * to let the kernel continue running. + * + * This is used to set the hardware breakpoint registers for all the + * slave cpus on an SMP configuration. This must be called after any + * changes are made to the hardware breakpoints (such as by a single + * step (s) or continue (c) packet. This is only required on + * architectures that support SMP and every processor has its own set + * of breakpoint registers. + */ +void __attribute__ ((weak)) + kgdb_correct_hw_break(void) +{ +} + +/** + * kgdb_post_master_code - Save error vector/code numbers. + * @regs: Original pt_regs. + * @e_vector: Original error vector. + * @err_code: Original error code. + * + * This is needed on architectures which support SMP and KGDB. + * This function is called after all the slave cpus have been put + * to a know spin state and the master CPU has control over KGDB. + */ + +void __attribute__ ((weak)) + kgdb_post_master_code(struct pt_regs *regs, int e_vector, int err_code) +{ +} + +/** + * kgdb_roundup_cpus - Get other CPUs into a holding pattern + * @flags: Current IRQ state + * + * On SMP systems, we need to get the attention of the other CPUs + * and get them be in a known state. This should do what is needed + * to get the other CPUs to call kgdb_wait(). Note that on some arches, + * the NMI approach is not used for rounding up all the CPUs. For example, + * in case of MIPS, smp_call_function() is used to roundup CPUs. In + * this case, we have to make sure that interrupts are enabled before + * calling smp_call_function(). The argument to this function is + * the flags that will be used when restoring the interrupts. There is + * local_irq_save() call before kgdb_roundup_cpus(). + */ +void __attribute__ ((weak)) + kgdb_roundup_cpus(unsigned long flags) +{ +} + +/** + * kgdb_shadowinfo - Get shadowed information on @threadid. + * @regs: The &struct pt_regs of the current process. + * @buffer: A buffer of %BUFMAX size. + * @threadid: The thread id of the shadowed process to get information on. + */ +void __attribute__ ((weak)) + kgdb_shadowinfo(struct pt_regs *regs, char *buffer, unsigned threadid) +{ +} + +/** + * kgdb_get_shadow_thread - Get the shadowed &task_struct of @threadid. + * @regs: The &struct pt_regs of the current thread. + * @threadid: The thread id of the shadowed process to get information on. + * + * RETURN: + * This returns a pointer to the &struct task_struct of the shadowed + * thread, @threadid. + */ +struct task_struct __attribute__ ((weak)) + * kgdb_get_shadow_thread(struct pt_regs *regs, int threadid) +{ + return NULL; +} + +/** + * kgdb_shadow_regs - Return the shadowed registers of @threadid. + * @regs: The &struct pt_regs of the current thread. + * @threadid: The thread id we want the &struct pt_regs for. + * + * RETURN: + * The a pointer to the &struct pt_regs of the shadowed thread @threadid. + */ +struct pt_regs __attribute__ ((weak)) + * kgdb_shadow_regs(struct pt_regs *regs, int threadid) +{ + return NULL; +} + +int __attribute__ ((weak)) + kgdb_validate_break_address(unsigned long addr) +{ + int error = 0; + char tmp_variable[BREAK_INSTR_SIZE]; + error = kgdb_get_mem((char *)addr, tmp_variable, BREAK_INSTR_SIZE); + return error; +} + +int __attribute__ ((weak)) + kgdb_arch_set_breakpoint(unsigned long addr, char *saved_instr) +{ + int error = 0; + if ((error = kgdb_get_mem((char *)addr, + saved_instr, BREAK_INSTR_SIZE)) < 0) + return error; + + if ((error = kgdb_set_mem((char *)addr, kgdb_ops->gdb_bpt_instr, + BREAK_INSTR_SIZE)) < 0) + return error; + return 0; +} + +int __attribute__ ((weak)) + kgdb_arch_remove_breakpoint(unsigned long addr, char *bundle) +{ + + int error = 0; + if ((error =kgdb_set_mem((char *)addr, (char *)bundle, + BREAK_INSTR_SIZE)) < 0) + return error; + return 0; +} + +static int hex(char ch) +{ + if ((ch >= 'a') && (ch <= 'f')) + return (ch - 'a' + 10); + if ((ch >= '0') && (ch <= '9')) + return (ch - '0'); + if ((ch >= 'A') && (ch <= 'F')) + return (ch - 'A' + 10); + return (-1); +} + +/* scan for the sequence $# */ +static void get_packet(char *buffer) +{ + unsigned char checksum; + unsigned char xmitcsum; + int count; + char ch; + if (!kgdb_io_ops.read_char) + return; + do { + /* Spin and wait around for the start character, ignore all + * other characters */ + while ((ch = (kgdb_io_ops.read_char())) != '$') ; + kgdb_connected = 1; + checksum = 0; + xmitcsum = -1; + + count = 0; + + /* now, read until a # or end of buffer is found */ + while (count < (BUFMAX - 1)) { + ch = kgdb_io_ops.read_char(); + if (ch == '#') + break; + checksum = checksum + ch; + buffer[count] = ch; + count = count + 1; + } + buffer[count] = 0; + + if (ch == '#') { + xmitcsum = hex(kgdb_io_ops.read_char()) << 4; + xmitcsum += hex(kgdb_io_ops.read_char()); + + if (checksum != xmitcsum) + /* failed checksum */ + kgdb_io_ops.write_char('-'); + else + /* successful transfer */ + kgdb_io_ops.write_char('+'); + if (kgdb_io_ops.flush) + kgdb_io_ops.flush(); + } + } while (checksum != xmitcsum); +} + +/* + * Send the packet in buffer. + * Check for gdb connection if asked for. + */ +static void put_packet(char *buffer) +{ + unsigned char checksum; + int count; + char ch; + + if (!kgdb_io_ops.write_char) + return; + /* $#. */ + while (1) { + kgdb_io_ops.write_char('$'); + checksum = 0; + count = 0; + + while ((ch = buffer[count])) { + kgdb_io_ops.write_char(ch); + checksum += ch; + count++; + } + + kgdb_io_ops.write_char('#'); + kgdb_io_ops.write_char(hexchars[checksum >> 4]); + kgdb_io_ops.write_char(hexchars[checksum % 16]); + if (kgdb_io_ops.flush) + kgdb_io_ops.flush(); + + /* Now see what we get in reply. */ + ch = kgdb_io_ops.read_char(); + + if (ch == 3) + ch = kgdb_io_ops.read_char(); + + /* If we get an ACK, we are done. */ + if (ch == '+') + return; + + /* If we get the start of another packet, this means + * that GDB is attempting to reconnect. We will NAK + * the packet being sent, and stop trying to send this + * packet. */ + if (ch == '$') { + kgdb_io_ops.write_char('-'); + if (kgdb_io_ops.flush) + kgdb_io_ops.flush(); + return; + } + } +} + +/* + * convert the memory pointed to by mem into hex, placing result in buf + * return a pointer to the last char put in buf (null). May return an error. + */ +char *kgdb_mem2hex(char *mem, char *buf, int count) +{ + kgdb_may_fault = 1; + if ((kgdb_fault_setjmp(kgdb_fault_jmp_regs)) != 0) { + kgdb_may_fault = 0; + return ERR_PTR(-EINVAL); + } + /* Accessing some registers in a single load instruction is + * required to avoid bad side effects for some I/O registers. + */ + if ((count == 2) && (((long)mem & 1) == 0)) { + unsigned short tmp_s = *(unsigned short *)mem; + mem += 2; +#ifdef __BIG_ENDIAN + *buf++ = hexchars[(tmp_s >> 12) & 0xf]; + *buf++ = hexchars[(tmp_s >> 8) & 0xf]; + *buf++ = hexchars[(tmp_s >> 4) & 0xf]; + *buf++ = hexchars[tmp_s & 0xf]; +#else + *buf++ = hexchars[(tmp_s >> 4) & 0xf]; + *buf++ = hexchars[tmp_s & 0xf]; + *buf++ = hexchars[(tmp_s >> 12) & 0xf]; + *buf++ = hexchars[(tmp_s >> 8) & 0xf]; +#endif + } else if ((count == 4) && (((long)mem & 3) == 0)) { + unsigned long tmp_l = *(unsigned int *)mem; + mem += 4; +#ifdef __BIG_ENDIAN + *buf++ = hexchars[(tmp_l >> 28) & 0xf]; + *buf++ = hexchars[(tmp_l >> 24) & 0xf]; + *buf++ = hexchars[(tmp_l >> 20) & 0xf]; + *buf++ = hexchars[(tmp_l >> 16) & 0xf]; + *buf++ = hexchars[(tmp_l >> 12) & 0xf]; + *buf++ = hexchars[(tmp_l >> 8) & 0xf]; + *buf++ = hexchars[(tmp_l >> 4) & 0xf]; + *buf++ = hexchars[tmp_l & 0xf]; +#else + *buf++ = hexchars[(tmp_l >> 4) & 0xf]; + *buf++ = hexchars[tmp_l & 0xf]; + *buf++ = hexchars[(tmp_l >> 12) & 0xf]; + *buf++ = hexchars[(tmp_l >> 8) & 0xf]; + *buf++ = hexchars[(tmp_l >> 20) & 0xf]; + *buf++ = hexchars[(tmp_l >> 16) & 0xf]; + *buf++ = hexchars[(tmp_l >> 28) & 0xf]; + *buf++ = hexchars[(tmp_l >> 24) & 0xf]; +#endif +#ifdef CONFIG_64BIT + } else if ((count == 8) && (((long)mem & 7) == 0)) { + unsigned long long tmp_ll = *(unsigned long long *)mem; + mem += 8; +#ifdef __BIG_ENDIAN + *buf++ = hexchars[(tmp_ll >> 60) & 0xf]; + *buf++ = hexchars[(tmp_ll >> 56) & 0xf]; + *buf++ = hexchars[(tmp_ll >> 52) & 0xf]; + *buf++ = hexchars[(tmp_ll >> 48) & 0xf]; + *buf++ = hexchars[(tmp_ll >> 44) & 0xf]; + *buf++ = hexchars[(tmp_ll >> 40) & 0xf]; + *buf++ = hexchars[(tmp_ll >> 36) & 0xf]; + *buf++ = hexchars[(tmp_ll >> 32) & 0xf]; + *buf++ = hexchars[(tmp_ll >> 28) & 0xf]; + *buf++ = hexchars[(tmp_ll >> 24) & 0xf]; + *buf++ = hexchars[(tmp_ll >> 20) & 0xf]; + *buf++ = hexchars[(tmp_ll >> 16) & 0xf]; + *buf++ = hexchars[(tmp_ll >> 12) & 0xf]; + *buf++ = hexchars[(tmp_ll >> 8) & 0xf]; + *buf++ = hexchars[(tmp_ll >> 4) & 0xf]; + *buf++ = hexchars[tmp_ll & 0xf]; +#else + *buf++ = hexchars[(tmp_ll >> 4) & 0xf]; + *buf++ = hexchars[tmp_ll & 0xf]; + *buf++ = hexchars[(tmp_ll >> 12) & 0xf]; + *buf++ = hexchars[(tmp_ll >> 8) & 0xf]; + *buf++ = hexchars[(tmp_ll >> 20) & 0xf]; + *buf++ = hexchars[(tmp_ll >> 16) & 0xf]; + *buf++ = hexchars[(tmp_ll >> 28) & 0xf]; + *buf++ = hexchars[(tmp_ll >> 24) & 0xf]; + *buf++ = hexchars[(tmp_ll >> 36) & 0xf]; + *buf++ = hexchars[(tmp_ll >> 32) & 0xf]; + *buf++ = hexchars[(tmp_ll >> 44) & 0xf]; + *buf++ = hexchars[(tmp_ll >> 40) & 0xf]; + *buf++ = hexchars[(tmp_ll >> 52) & 0xf]; + *buf++ = hexchars[(tmp_ll >> 48) & 0xf]; + *buf++ = hexchars[(tmp_ll >> 60) & 0xf]; + *buf++ = hexchars[(tmp_ll >> 56) & 0xf]; +#endif +#endif + } else { + while (count-- > 0) { + unsigned char ch = *mem++; + *buf++ = hexchars[ch >> 4]; + *buf++ = hexchars[ch & 0xf]; + } + } + kgdb_may_fault = 0; + *buf = 0; + return (buf); +} + +/* + * Copy the binary array pointed to by buf into mem. Fix $, #, and + * 0x7d escaped with 0x7d. Return a pointer to the character after + * the last byte written. + */ +static char *kgdb_ebin2mem(char *buf, char *mem, int count) +{ + kgdb_may_fault = 1; + if ((kgdb_fault_setjmp(kgdb_fault_jmp_regs)) != 0) { + kgdb_may_fault = 0; + return ERR_PTR(-EINVAL); + } + for (; count > 0; count--, buf++) { + if (*buf == 0x7d) + *mem++ = *(++buf) ^ 0x20; + else + *mem++ = *buf; + } + kgdb_may_fault = 0; + return mem; +} + +/* + * convert the hex array pointed to by buf into binary to be placed in mem + * return a pointer to the character AFTER the last byte written + * May return an error. + */ +char *kgdb_hex2mem(char *buf, char *mem, int count) +{ + kgdb_may_fault = 1; + if ((kgdb_fault_setjmp(kgdb_fault_jmp_regs)) != 0) { + kgdb_may_fault = 0; + return ERR_PTR(-EINVAL); + } + if ((count == 2) && (((long)mem & 1) == 0)) { + unsigned short tmp_s = 0; +#ifdef __BIG_ENDIAN + tmp_s |= hex(*buf++) << 12; + tmp_s |= hex(*buf++) << 8; + tmp_s |= hex(*buf++) << 4; + tmp_s |= hex(*buf++); +#else + tmp_s |= hex(*buf++) << 4; + tmp_s |= hex(*buf++); + tmp_s |= hex(*buf++) << 12; + tmp_s |= hex(*buf++) << 8; +#endif + *(unsigned short *)mem = tmp_s; + mem += 2; + } else if ((count == 4) && (((long)mem & 3) == 0)) { + unsigned long tmp_l = 0; +#ifdef __BIG_ENDIAN + tmp_l |= hex(*buf++) << 28; + tmp_l |= hex(*buf++) << 24; + tmp_l |= hex(*buf++) << 20; + tmp_l |= hex(*buf++) << 16; + tmp_l |= hex(*buf++) << 12; + tmp_l |= hex(*buf++) << 8; + tmp_l |= hex(*buf++) << 4; + tmp_l |= hex(*buf++); +#else + tmp_l |= hex(*buf++) << 4; + tmp_l |= hex(*buf++); + tmp_l |= hex(*buf++) << 12; + tmp_l |= hex(*buf++) << 8; + tmp_l |= hex(*buf++) << 20; + tmp_l |= hex(*buf++) << 16; + tmp_l |= hex(*buf++) << 28; + tmp_l |= hex(*buf++) << 24; +#endif + *(unsigned long *)mem = tmp_l; + mem += 4; + } else { + int i; + for (i = 0; i < count; i++) { + unsigned char ch = hex(*buf++) << 4; + ch |= hex(*buf++); + *mem++ = ch; + } + } + kgdb_may_fault = 0; + return (mem); +} + +/* + * While we find nice hex chars, build a long_val. + * Return number of chars processed. + */ +int kgdb_hex2long(char **ptr, long *long_val) +{ + int hex_val, num = 0; + + *long_val = 0; + + while (**ptr) { + hex_val = hex(**ptr); + if (hex_val >= 0) { + *long_val = (*long_val << 4) | hex_val; + num++; + } else + break; + + (*ptr)++; + } + + return (num); +} + +/* Write memory due to an 'M' or 'X' packet. */ +static char *write_mem_msg(int binary) +{ + char *ptr = &remcom_in_buffer[1]; + unsigned long addr, length; + + if (kgdb_hex2long(&ptr, &addr) > 0 && *(ptr++) == ',' && + kgdb_hex2long(&ptr, &length) > 0 && *(ptr++) == ':') { + if (binary) + ptr = kgdb_ebin2mem(ptr, (char *)addr, length); + else + ptr = kgdb_hex2mem(ptr, (char *)addr, length); + if (CACHE_FLUSH_IS_SAFE) + flush_icache_range(addr, addr + length + 1); + if (IS_ERR(ptr)) + return ptr; + return NULL; + } + + return ERR_PTR(-EINVAL); +} + +static inline char *pack_hex_byte(char *pkt, int byte) +{ + *pkt++ = hexchars[(byte >> 4) & 0xf]; + *pkt++ = hexchars[(byte & 0xf)]; + return pkt; +} + +static inline void error_packet(char *pkt, int error) +{ + error = -error; + pkt[0] = 'E'; + pkt[1] = hexchars[(error / 10)]; + pkt[2] = hexchars[(error % 10)]; + pkt[3] = '\0'; +} + +static char *pack_threadid(char *pkt, threadref * id) +{ + char *limit; + unsigned char *altid; + + altid = (unsigned char *)id; + limit = pkt + BUF_THREAD_ID_SIZE; + while (pkt < limit) + pkt = pack_hex_byte(pkt, *altid++); + + return pkt; +} + +void int_to_threadref(threadref * id, int value) +{ + unsigned char *scan; + int i = 4; + + scan = (unsigned char *)id; + while (i--) + *scan++ = 0; + *scan++ = (value >> 24) & 0xff; + *scan++ = (value >> 16) & 0xff; + *scan++ = (value >> 8) & 0xff; + *scan++ = (value & 0xff); +} + +static struct task_struct *getthread(struct pt_regs *regs, int tid) +{ + if (!pidhash_init_done) + return current; + + if (num_online_cpus() && + (tid >= pid_max + num_online_cpus() + kgdb_ops->shadowth)) + return NULL; + + if (kgdb_ops->shadowth && (tid >= pid_max + num_online_cpus())) + return kgdb_get_shadow_thread(regs, tid - pid_max - + num_online_cpus()); + + if (tid >= pid_max) + return idle_task(tid - pid_max); + + if (!tid) + return NULL; + + return find_task_by_pid(tid); +} + +#ifdef CONFIG_SMP +static void kgdb_wait(struct pt_regs *regs) +{ + unsigned long flags; + int processor; + + local_irq_save(flags); + processor = smp_processor_id(); + kgdb_info[processor].debuggerinfo = regs; + kgdb_info[processor].task = current; + atomic_set(&procindebug[processor], 1); + + /* Wait till master processor goes completely into the debugger. + * FIXME: this looks racy */ + while (!atomic_read(&procindebug[atomic_read(&debugger_active) - 1])) { + int i = 10; /* an arbitrary number */ + + while (--i) + cpu_relax(); + } + + /* Wait till master processor is done with debugging */ + spin_lock(&slavecpulocks[processor]); + + /* This has been taken from x86 kgdb implementation and + * will be needed by architectures that have SMP support + */ + kgdb_correct_hw_break(); + + kgdb_info[processor].debuggerinfo = NULL; + kgdb_info[processor].task = NULL; + + /* Signal the master processor that we are done */ + atomic_set(&procindebug[processor], 0); + spin_unlock(&slavecpulocks[processor]); + local_irq_restore(flags); +} +#endif + +int kgdb_get_mem(char *addr, unsigned char *buf, int count) +{ + kgdb_may_fault = 1; + if ((kgdb_fault_setjmp(kgdb_fault_jmp_regs)) != 0) { + kgdb_may_fault = 0; + return -EINVAL; + } + while (count) { + if ((unsigned long)addr < TASK_SIZE) + return -EINVAL; + *buf++ = *addr++; + count--; + } + kgdb_may_fault = 0; + return 0; +} + +int kgdb_set_mem(char *addr, unsigned char *buf, int count) +{ + kgdb_may_fault = 1; + if ((kgdb_fault_setjmp(kgdb_fault_jmp_regs)) != 0) { + kgdb_may_fault = 0; + return -EINVAL; + } + while (count) { + if ((unsigned long)addr < TASK_SIZE) + return -EINVAL; + *addr++ = *buf++; + count--; + } + kgdb_may_fault = 0; + return 0; +} +int kgdb_activate_sw_breakpoints(void) +{ + int i; + int error = 0; + unsigned long addr; + for (i = 0; i < MAX_BREAKPOINTS; i++) { + if (kgdb_break[i].state != bp_set) + continue; + addr = kgdb_break[i].bpt_addr; + if ((error = kgdb_arch_set_breakpoint(addr, + kgdb_break[i].saved_instr))) + return error; + + if (CACHE_FLUSH_IS_SAFE) { + if (current->mm && addr < TASK_SIZE) + flush_cache_range(current->mm->mmap_cache, + addr, addr + BREAK_INSTR_SIZE); + else + flush_icache_range(addr, addr + + BREAK_INSTR_SIZE); + } + + kgdb_break[i].state = bp_active; + } + return 0; +} + +static int kgdb_set_sw_break(unsigned long addr) +{ + int i, breakno = -1; + int error = 0; + if ((error = kgdb_validate_break_address(addr)) < 0) + return error; + for (i = 0; i < MAX_BREAKPOINTS; i++) { + if ((kgdb_break[i].state == bp_set) && + (kgdb_break[i].bpt_addr == addr)) + return -EEXIST; + } + for (i = 0; i < MAX_BREAKPOINTS; i++) { + if (kgdb_break[i].state == bp_removed && + kgdb_break[i].bpt_addr == addr) { + breakno = i; + break; + } + } + + if (breakno == -1) { + for (i = 0; i < MAX_BREAKPOINTS; i++) { + if (kgdb_break[i].state == bp_none) { + breakno = i; + break; + } + } + } + if (breakno == -1) + return -E2BIG; + + kgdb_break[breakno].state = bp_set; + kgdb_break[breakno].type = bp_breakpoint; + kgdb_break[breakno].bpt_addr = addr; + + return 0; +} + +int kgdb_deactivate_sw_breakpoints(void) +{ + int i; + int error = 0; + unsigned long addr; + for (i = 0; i < MAX_BREAKPOINTS; i++) { + if (kgdb_break[i].state != bp_active) + continue; + addr = kgdb_break[i].bpt_addr; + if ((error = kgdb_arch_remove_breakpoint(addr, + kgdb_break[i].saved_instr))) + return error; + + if (CACHE_FLUSH_IS_SAFE && current->mm && + addr < TASK_SIZE) + flush_cache_range(current->mm->mmap_cache, + addr, addr + BREAK_INSTR_SIZE); + else if (CACHE_FLUSH_IS_SAFE) + flush_icache_range(addr, + addr + BREAK_INSTR_SIZE); + kgdb_break[i].state = bp_set; + } + return 0; +} + +static int kgdb_remove_sw_break(unsigned long addr) +{ + int i; + + for (i = 0; i < MAX_BREAKPOINTS; i++) { + if ((kgdb_break[i].state == bp_set) && + (kgdb_break[i].bpt_addr == addr)) { + kgdb_break[i].state = bp_removed; + return 0; + } + } + return -ENOENT; +} + +int kgdb_isremovedbreak(unsigned long addr) +{ + int i; + for (i = 0; i < MAX_BREAKPOINTS; i++) { + if ((kgdb_break[i].state == bp_removed) && + (kgdb_break[i].bpt_addr == addr)) { + return 1; + } + } + return 0; +} + +int remove_all_break(void) +{ + int i; + int error; + unsigned long addr; + + /* Clear memory breakpoints. */ + for (i = 0; i < MAX_BREAKPOINTS; i++) { + if (kgdb_break[i].state != bp_set) + continue; + addr = kgdb_break[i].bpt_addr; + if ((error = kgdb_arch_remove_breakpoint(addr, + kgdb_break[i].saved_instr))) + return error; + kgdb_break[i].state = bp_removed; + } + + /* Clear hardware breakpoints. */ + kgdb_remove_all_hw_break(); + + return 0; +} + +static inline int shadow_pid(int realpid) +{ + if (realpid) { + return realpid; + } + return pid_max + smp_processor_id(); +} + +static char gdbmsgbuf[BUFMAX + 1]; +static void kgdb_msg_write(const char *s, int len) +{ + int i; + int wcount; + char *bufptr; + + /* 'O'utput */ + gdbmsgbuf[0] = 'O'; + + /* Fill and send buffers... */ + while (len > 0) { + bufptr = gdbmsgbuf + 1; + + /* Calculate how many this time */ + if ((len << 1) > (BUFMAX - 2)) + wcount = (BUFMAX - 2) >> 1; + else + wcount = len; + + /* Pack in hex chars */ + for (i = 0; i < wcount; i++) + bufptr = pack_hex_byte(bufptr, s[i]); + *bufptr = '\0'; + + /* Move up */ + s += wcount; + len -= wcount; + + /* Write packet */ + put_packet(gdbmsgbuf); + } +} + +/* + * This function does all command procesing for interfacing to gdb. + * + * Locking hierarchy: + * interface locks, if any (begin_session) + * kgdb lock (debugger_active) + * + * Note that since we can be in here prior to our cpumask being filled + * out, we err on the side of caution and loop over NR_CPUS instead + * of a for_each_online_cpu. + * + */ +int kgdb_handle_exception(int ex_vector, int signo, int err_code, + struct pt_regs *linux_regs) +{ + unsigned long length, addr; + char *ptr; + unsigned long flags; + unsigned i; + long threadid; + threadref thref; + struct task_struct *thread = NULL; + unsigned procid; + int numshadowth = num_online_cpus() + kgdb_ops->shadowth; + long kgdb_usethreadid = 0; + int error = 0, all_cpus_synced = 0; + struct pt_regs *shadowregs; + int processor = smp_processor_id(); + void *local_debuggerinfo; + + /* Panic on recursive debugger calls. */ + if (atomic_read(&debugger_active) == smp_processor_id() + 1) + return 0; + + acquirelock: + + /* Call the I/O drivers pre_exception routine if the I/O + * driver defined one + */ + if (kgdb_io_ops.pre_exception) + kgdb_io_ops.pre_exception(); + + /* + * Interrupts will be restored by the 'trap return' code, except when + * single stepping. + */ + local_irq_save(flags); + + /* Hold debugger_active */ + procid = smp_processor_id(); + + while (cmpxchg(&atomic_read(&debugger_active), 0, (procid + 1)) != 0) { + int i = 25; /* an arbitrary number */ + + while (--i) + cpu_relax(); + + if (atomic_read(&cpu_doing_single_step) != -1 && + atomic_read(&cpu_doing_single_step) != procid) + udelay(1); + } + + /* + * Don't enter if the last instance of the exception handler wanted to + * come into the debugger again. + */ + if (atomic_read(&cpu_doing_single_step) != -1 && + atomic_read(&cpu_doing_single_step) != procid) { + atomic_set(&debugger_active, 0); + local_irq_restore(flags); + goto acquirelock; + } + + atomic_set(&kgdb_sync_softlockup[smp_processor_id()], 1); + + /* + * Don't enter if we have hit a removed breakpoint. + */ + if (kgdb_skipexception(ex_vector, linux_regs)) + goto kgdb_restore; + + kgdb_info[processor].debuggerinfo = linux_regs; + kgdb_info[processor].task = current; + + kgdb_disable_hw_debug(linux_regs); + + if (!debugger_step || !kgdb_contthread) + for (i = 0; i < NR_CPUS; i++) + spin_lock(&slavecpulocks[i]); + + /* Make sure we get the other CPUs */ + if (!debugger_step || !kgdb_contthread) + kgdb_roundup_cpus(flags); + + /* spin_lock code is good enough as a barrier so we don't + * need one here */ + atomic_set(&procindebug[processor], 1); + + /* Wait a reasonable time for the other CPUs to be notified and + * be waiting for us. Very early on this could be imperfect + * as num_online_cpus() could be 0.*/ + for (i = 0; i < ROUNDUP_WAIT; i++) { + int cpu, num = 0; + for (cpu = 0; cpu < NR_CPUS; cpu++) { + if (atomic_read(&procindebug[cpu])) + num++; + } + if (num >= num_online_cpus()) { + all_cpus_synced = 1; + break; + } + } + + /* Clear the out buffer. */ + memset(remcom_out_buffer, 0, sizeof(remcom_out_buffer)); + + /* Master processor is completely in the debugger */ + kgdb_post_master_code(linux_regs, ex_vector, err_code); + kgdb_deactivate_sw_breakpoints(); + debugger_step = 0; + kgdb_contthread = NULL; + + if (kgdb_connected) { + /* If we're still unable to roundup all of the CPUs, + * send an 'O' packet informing the user again. */ + if (!all_cpus_synced) + kgdb_msg_write("Not all CPUs have been synced for " + "KGDB\n", 39); + /* Reply to host that an exception has occurred */ + ptr = remcom_out_buffer; + *ptr++ = 'T'; + *ptr++ = hexchars[(signo >> 4) % 16]; + *ptr++ = hexchars[signo % 16]; + ptr += strlen(strcpy(ptr, "thread:")); + int_to_threadref(&thref, shadow_pid(current->pid)); + ptr = pack_threadid(ptr, &thref); + *ptr++ = ';'; + + put_packet(remcom_out_buffer); + } + + kgdb_usethread = kgdb_info[processor].task; + kgdb_usethreadid = shadow_pid(kgdb_info[processor].task->pid); + + while (kgdb_io_ops.read_char) { + char *bpt_type; + error = 0; + + /* Clear the out buffer. */ + memset(remcom_out_buffer, 0, sizeof(remcom_out_buffer)); + + get_packet(remcom_in_buffer); + + switch (remcom_in_buffer[0]) { + case '?': + /* We know that this packet is only sent + * during initial connect. So to be safe, + * we clear out our breakpoints now incase + * GDB is reconnecting. */ + remove_all_break(); + /* Also, if we haven't been able to roundup all + * CPUs, send an 'O' packet informing the user + * as much. Only need to do this once. */ + if (!all_cpus_synced) + kgdb_msg_write("Not all CPUs have been " + "synced for KGDB\n", 39); + remcom_out_buffer[0] = 'S'; + remcom_out_buffer[1] = hexchars[signo >> 4]; + remcom_out_buffer[2] = hexchars[signo % 16]; + break; + + case 'g': /* return the value of the CPU registers */ + thread = kgdb_usethread; + + if (!thread) { + thread = kgdb_info[processor].task; + local_debuggerinfo = + kgdb_info[processor].debuggerinfo; + } else { + local_debuggerinfo = NULL; + for (i = 0; i < NR_CPUS; i++) { + /* Try to find the task on some other + * or possibly this node if we do not + * find the matching task then we try + * to approximate the results. + */ + if (thread == kgdb_info[i].task) + local_debuggerinfo = + kgdb_info[i].debuggerinfo; + } + } + + /* All threads that don't have debuggerinfo should be + * in __schedule() sleeping, since all other CPUs + * are in kgdb_wait, and thus have debuggerinfo. */ + if (kgdb_ops->shadowth && + kgdb_usethreadid >= pid_max + num_online_cpus()) { + shadowregs = kgdb_shadow_regs(linux_regs, + kgdb_usethreadid - + pid_max - + num_online_cpus + ()); + if (!shadowregs) { + error_packet(remcom_out_buffer, + -EINVAL); + break; + } + regs_to_gdb_regs(gdb_regs, shadowregs); + } else if (local_debuggerinfo) + regs_to_gdb_regs(gdb_regs, local_debuggerinfo); + else { + /* Pull stuff saved during + * switch_to; nothing else is + * accessible (or even particularly relevant). + * This should be enough for a stack trace. */ + sleeping_thread_to_gdb_regs(gdb_regs, thread); + } + kgdb_mem2hex((char *)gdb_regs, remcom_out_buffer, + NUMREGBYTES); + break; + + /* set the value of the CPU registers - return OK */ + case 'G': + kgdb_hex2mem(&remcom_in_buffer[1], (char *)gdb_regs, + NUMREGBYTES); + + if (kgdb_usethread && kgdb_usethread != current) + error_packet(remcom_out_buffer, -EINVAL); + else { + gdb_regs_to_regs(gdb_regs, linux_regs); + strcpy(remcom_out_buffer, "OK"); + } + break; + + /* mAA..AA,LLLL Read LLLL bytes at address AA..AA */ + case 'm': + ptr = &remcom_in_buffer[1]; + if (kgdb_hex2long(&ptr, &addr) > 0 && *ptr++ == ',' && + kgdb_hex2long(&ptr, &length) > 0) { + if (IS_ERR(ptr = kgdb_mem2hex((char *)addr, + remcom_out_buffer, + length))) + error_packet(remcom_out_buffer, + PTR_ERR(ptr)); + } else + error_packet(remcom_out_buffer, -EINVAL); + break; + + /* MAA..AA,LLLL: Write LLLL bytes at address AA..AA */ + case 'M': + if (IS_ERR(ptr = write_mem_msg(0))) + error_packet(remcom_out_buffer, PTR_ERR(ptr)); + else + strcpy(remcom_out_buffer, "OK"); + break; + /* XAA..AA,LLLL: Write LLLL bytes at address AA..AA */ + case 'X': + if (IS_ERR(ptr = write_mem_msg(1))) + error_packet(remcom_out_buffer, PTR_ERR(ptr)); + else + strcpy(remcom_out_buffer, "OK"); + break; + + /* kill or detach. KGDB should treat this like a + * continue. + */ + case 'D': + if ((error = remove_all_break()) < 0) { + error_packet(remcom_out_buffer, error); + } else { + strcpy(remcom_out_buffer, "OK"); + kgdb_connected = 0; + } + put_packet(remcom_out_buffer); + goto default_handle; + + case 'k': + /* Don't care about error from remove_all_break */ + remove_all_break(); + kgdb_connected = 0; + goto default_handle; + + /* Reboot */ + case 'R': + /* For now, only honor R0 */ + if (strcmp(remcom_in_buffer, "R0") == 0) { + printk(KERN_CRIT "Executing reboot\n"); + strcpy(remcom_out_buffer, "OK"); + put_packet(remcom_out_buffer); + emergency_sync(); + /* Execution should not return from + * machine_restart() + */ + machine_restart(NULL); + kgdb_connected = 0; + goto default_handle; + } + + /* query */ + case 'q': + switch (remcom_in_buffer[1]) { + case 's': + case 'f': + if (memcmp(remcom_in_buffer + 2, "ThreadInfo", + 10)) { + error_packet(remcom_out_buffer, + -EINVAL); + break; + } + + /* + * If we have not yet completed in + * pidhash_init() there isn't much we + * can give back. + */ + if (!pidhash_init_done) { + if (remcom_in_buffer[1] == 'f') + strcpy(remcom_out_buffer, + "m0000000000000001"); + break; + } + + if (remcom_in_buffer[1] == 'f') { + threadid = 1; + } + remcom_out_buffer[0] = 'm'; + ptr = remcom_out_buffer + 1; + for (i = 0; i < 17 && threadid < pid_max + + numshadowth; threadid++) { + thread = getthread(linux_regs, + threadid); + if (thread) { + int_to_threadref(&thref, + threadid); + pack_threadid(ptr, &thref); + ptr += 16; + *(ptr++) = ','; + i++; + } + } + *(--ptr) = '\0'; + break; + + case 'C': + /* Current thread id */ + strcpy(remcom_out_buffer, "QC"); + + threadid = shadow_pid(current->pid); + + int_to_threadref(&thref, threadid); + pack_threadid(remcom_out_buffer + 2, &thref); + break; + case 'T': + if (memcmp(remcom_in_buffer + 1, + "ThreadExtraInfo,", 16)) { + error_packet(remcom_out_buffer, + -EINVAL); + break; + } + threadid = 0; + ptr = remcom_in_buffer + 17; + kgdb_hex2long(&ptr, &threadid); + if (!getthread(linux_regs, threadid)) { + error_packet(remcom_out_buffer, + -EINVAL); + break; + } + if (threadid < pid_max) { + kgdb_mem2hex(getthread(linux_regs, + threadid)->comm, + remcom_out_buffer, 16); + } else if (threadid >= pid_max + + num_online_cpus()) { + kgdb_shadowinfo(linux_regs, + remcom_out_buffer, + threadid - pid_max - + num_online_cpus()); + } else { + static char tmpstr[23 + + BUF_THREAD_ID_SIZE]; + sprintf(tmpstr, "Shadow task %d" + " for pid 0", + (int)(threadid - pid_max)); + kgdb_mem2hex(tmpstr, remcom_out_buffer, + strlen(tmpstr)); + } + break; + } + break; + + /* task related */ + case 'H': + switch (remcom_in_buffer[1]) { + case 'g': + ptr = &remcom_in_buffer[2]; + kgdb_hex2long(&ptr, &threadid); + thread = getthread(linux_regs, threadid); + if (!thread && threadid > 0) { + error_packet(remcom_out_buffer, + -EINVAL); + break; + } + kgdb_usethread = thread; + kgdb_usethreadid = threadid; + strcpy(remcom_out_buffer, "OK"); + break; + + case 'c': + ptr = &remcom_in_buffer[2]; + kgdb_hex2long(&ptr, &threadid); + if (!threadid) { + kgdb_contthread = NULL; + } else { + thread = getthread(linux_regs, + threadid); + if (!thread && threadid > 0) { + error_packet(remcom_out_buffer, + -EINVAL); + break; + } + kgdb_contthread = thread; + } + strcpy(remcom_out_buffer, "OK"); + break; + } + break; + + /* Query thread status */ + case 'T': + ptr = &remcom_in_buffer[1]; + kgdb_hex2long(&ptr, &threadid); + thread = getthread(linux_regs, threadid); + if (thread) + strcpy(remcom_out_buffer, "OK"); + else + error_packet(remcom_out_buffer, -EINVAL); + break; + /* Since GDB-5.3, it's been drafted that '0' is a software + * breakpoint, '1' is a hardware breakpoint, so let's do + * that. + */ + case 'z': + case 'Z': + bpt_type = &remcom_in_buffer[1]; + ptr = &remcom_in_buffer[2]; + + if (kgdb_ops->set_hw_breakpoint && *bpt_type >= '1') { + /* Unsupported */ + if (*bpt_type > '4') + break; + } else if (*bpt_type != '0' && *bpt_type != '1') + /* Unsupported. */ + break; + /* Test if this is a hardware breakpoint, and + * if we support it. */ + if (*bpt_type == '1' && + !kgdb_ops->flags & KGDB_HW_BREAKPOINT) + /* Unsupported. */ + break; + + if (*(ptr++) != ',') { + error_packet(remcom_out_buffer, -EINVAL); + break; + } else if (kgdb_hex2long(&ptr, &addr)) { + if (*(ptr++) != ',' || + !kgdb_hex2long(&ptr, &length)) { + error_packet(remcom_out_buffer, + -EINVAL); + break; + } + } else { + error_packet(remcom_out_buffer, -EINVAL); + break; + } + + if (remcom_in_buffer[0] == 'Z' && *bpt_type == '0') + error = kgdb_set_sw_break(addr); + else if (remcom_in_buffer[0] == 'Z' && *bpt_type == '1') + error = kgdb_set_hw_break(addr); + else if (remcom_in_buffer[0] == 'z' && *bpt_type == '0') + error = kgdb_remove_sw_break(addr); + else if (remcom_in_buffer[0] == 'z' && *bpt_type == '1') + error = kgdb_remove_hw_break(addr); + else if (remcom_in_buffer[0] == 'Z') + error = kgdb_ops->set_hw_breakpoint(addr, + (int)length, + *bpt_type); + else if (remcom_in_buffer[0] == 'z') + error = kgdb_ops->remove_hw_breakpoint(addr, + (int) + length, + *bpt_type); + + if (error == 0) + strcpy(remcom_out_buffer, "OK"); + else + error_packet(remcom_out_buffer, error); + + break; + case 'c': + case 's': + if (kgdb_contthread && kgdb_contthread != current) { + /* Can't switch threads in kgdb */ + error_packet(remcom_out_buffer, -EINVAL); + break; + } + kgdb_activate_sw_breakpoints(); + /* Followthrough to default processing */ + default: + default_handle: + error = kgdb_arch_handle_exception(ex_vector, signo, + err_code, + remcom_in_buffer, + remcom_out_buffer, + linux_regs); + + if (error >= 0 || remcom_in_buffer[0] == 'D' || + remcom_in_buffer[0] == 'k') + goto kgdb_exit; + + } /* switch */ + + /* reply to the request */ + put_packet(remcom_out_buffer); + } + + kgdb_exit: + /* Call the I/O driver's post_exception routine if the I/O + * driver defined one. + */ + if (kgdb_io_ops.post_exception) + kgdb_io_ops.post_exception(); + + kgdb_info[processor].debuggerinfo = NULL; + kgdb_info[processor].task = NULL; + atomic_set(&procindebug[processor], 0); + + if (!debugger_step || !kgdb_contthread) { + for (i = 0; i < NR_CPUS; i++) + spin_unlock(&slavecpulocks[i]); + /* Wait till all the processors have quit + * from the debugger. */ + for (i = 0; i < NR_CPUS; i++) { + while (atomic_read(&procindebug[i])) { + int j = 10; /* an arbitrary number */ + + while (--j) + cpu_relax(); + } + } + } + +#ifdef CONFIG_SMP + /* This delay has a real purpose. The problem is that if you + * are single-stepping, you are sending an NMI to all the + * other processors to stop them. Interrupts come in, but + * don't get handled. Then you let them go just long enough + * to get into their interrupt routines and use up some stack. + * You stop them again, and then do the same thing. After a + * while you blow the stack on the other processors. This + * delay gives some time for interrupts to be cleared out on + * the other processors. + */ + if (debugger_step) + mdelay(2); +#endif +kgdb_restore: + /* Free debugger_active */ + atomic_set(&debugger_active, 0); + local_irq_restore(flags); + + return error; +} + +/* + * GDB places a breakpoint at this function to know dynamically + * loaded objects. It's not defined static so that only one instance with this + * name exists in the kernel. + */ + +int module_event(struct notifier_block *self, unsigned long val, void *data) +{ + return 0; +} + +static struct notifier_block kgdb_module_load_nb = { + .notifier_call = module_event, +}; + +void kgdb_nmihook(int cpu, void *regs) +{ +#ifdef CONFIG_SMP + if (!atomic_read(&procindebug[cpu]) && atomic_read(&debugger_active) != (cpu + 1)) + kgdb_wait((struct pt_regs *)regs); +#endif +} + +/* + * This is called when a panic happens. All we need to do is + * breakpoint(). + */ +static int kgdb_panic_notify(struct notifier_block *self, unsigned long cmd, + void *ptr) +{ + breakpoint(); + + return 0; +} + +static struct notifier_block kgdb_panic_notifier = { + .notifier_call = kgdb_panic_notify, +}; + +/* + * Initialization that needs to be done in either of our entry points. + */ +static void __init kgdb_internal_init(void) +{ + int i; + + /* Initialize our spinlocks. */ + for (i = 0; i < NR_CPUS; i++) + spin_lock_init(&slavecpulocks[i]); + + for (i = 0; i < MAX_BREAKPOINTS; i++) + kgdb_break[i].state = bp_none; + + /* Initialize the I/O handles */ + memset(&kgdb_io_ops_prev, 0, sizeof(kgdb_io_ops_prev)); + + /* We can't do much if this fails */ + register_module_notifier(&kgdb_module_load_nb); + + kgdb_initialized = 1; +} + +static void kgdb_register_for_panic(void) +{ + /* Register for panics(). */ + /* The registration is done in the kgdb_register_for_panic + * routine because KGDB should not try to handle a panic when + * there are no kgdb_io_ops setup. It is assumed that the + * kgdb_io_ops are setup at the time this method is called. + */ + if (!kgdb_from_module_registered) { + atomic_notifier_chain_register(&panic_notifier_list, + &kgdb_panic_notifier); + kgdb_from_module_registered = 1; + } +} + +static void kgdb_unregister_for_panic(void) +{ + /* When this routine is called KGDB should unregister from the + * panic handler and clean up, making sure it is not handling any + * break exceptions at the time. + */ + if (kgdb_from_module_registered) { + kgdb_from_module_registered = 0; + atomic_notifier_chain_unregister(&panic_notifier_list, + &kgdb_panic_notifier); + } +} + +int kgdb_register_io_module(struct kgdb_io *local_kgdb_io_ops) +{ + + if (kgdb_connected) { + printk(KERN_ERR "kgdb: Cannot load I/O module while KGDB " + "connected.\n"); + return -EINVAL; + } + + /* Save the old values so they can be restored */ + if (kgdb_io_handler_cnt >= MAX_KGDB_IO_HANDLERS) { + printk(KERN_ERR "kgdb: No more I/O handles available.\n"); + return -EINVAL; + } + + /* Check to see if there is an existing driver and if so save its + * values. Also check to make sure the same driver was not trying + * to re-register. + */ + if (kgdb_io_ops.read_char != NULL && + kgdb_io_ops.read_char != local_kgdb_io_ops->read_char) { + memcpy(&kgdb_io_ops_prev[kgdb_io_handler_cnt], + &kgdb_io_ops, sizeof(struct kgdb_io)); + kgdb_io_handler_cnt++; + } + + /* Initialize the io values for this module */ + memcpy(&kgdb_io_ops, local_kgdb_io_ops, sizeof(struct kgdb_io)); + + /* Make the call to register kgdb if is not initialized */ + kgdb_register_for_panic(); + + return 0; +} + +void kgdb_unregister_io_module(struct kgdb_io *local_kgdb_io_ops) +{ + int i; + + /* Unregister KGDB if there were no other prior io hooks, else + * restore the io hooks. + */ + if (kgdb_io_handler_cnt > 0 && kgdb_io_ops_prev[0].read_char != NULL) { + /* First check if the hook that is in use is the one being + * removed */ + if (kgdb_io_ops.read_char == local_kgdb_io_ops->read_char) { + /* Set 'i' to the value of where the list should be + * shifed */ + i = kgdb_io_handler_cnt - 1; + memcpy(&kgdb_io_ops, &kgdb_io_ops_prev[i], + sizeof(struct kgdb_io)); + } else { + /* Simple case to remove an entry for an I/O handler + * that is not in use */ + for (i = 0; i < kgdb_io_handler_cnt; i++) { + if (kgdb_io_ops_prev[i].read_char == + local_kgdb_io_ops->read_char) + break; + } + } + + /* Shift all the entries in the handler array so it is + * ordered from oldest to newest. + */ + kgdb_io_handler_cnt--; + for (; i < kgdb_io_handler_cnt; i++) { + memcpy(&kgdb_io_ops_prev[i], &kgdb_io_ops_prev[i + 1], + sizeof(struct kgdb_io)); + } + /* Handle the case if we are on the last element and set it + * to NULL; */ + memset(&kgdb_io_ops_prev[kgdb_io_handler_cnt], 0, + sizeof(struct kgdb_io)); + + if (kgdb_connected) + printk(KERN_ERR "kgdb: WARNING: I/O method changed " + "while kgdb was connected state.\n"); + } else { + /* KGDB is no longer able to communicate out, so + * unregister our hooks and reset state. */ + kgdb_unregister_for_panic(); + if (kgdb_connected) { + printk(KERN_CRIT "kgdb: I/O module was unloaded while " + "a debugging session was running. " + "KGDB will be reset.\n"); + if (remove_all_break() < 0) + printk(KERN_CRIT "kgdb: Reset failed.\n"); + kgdb_connected = 0; + } + memset(&kgdb_io_ops, 0, sizeof(struct kgdb_io)); + } +} + +/* + * There are times we need to call a tasklet to cause a breakpoint + * as calling breakpoint() at that point might be fatal. We have to + * check that the exception stack is setup, as tasklets may be scheduled + * prior to this. When that happens, it is up to the architecture to + * schedule this when it is safe to run. + */ +static void kgdb_tasklet_bpt(unsigned long ing) +{ + breakpoint(); +} + +DECLARE_TASKLET(kgdb_tasklet_breakpoint, kgdb_tasklet_bpt, 0); + +/* + * This function can be called very early, either via early_param() or + * an explicit breakpoint() early on. + */ +static void __init kgdb_early_entry(void) +{ + /* Let the architecture do any setup that it needs to. */ + kgdb_arch_init(); + + /* Now try the I/O. */ + /* For early entry kgdb_io_ops.init must be defined */ + if (!kgdb_io_ops.init || kgdb_io_ops.init()) { + /* Try again later. */ + kgdb_initialized = -1; + return; + } + + /* Finish up. */ + kgdb_internal_init(); + + /* KGDB can assume that if kgdb_io_ops.init was defined that the + * panic registion should be performed at this time. This means + * kgdb_io_ops.init did not come from a kernel module and was + * initialized statically by a built in. + */ + if (kgdb_io_ops.init) + kgdb_register_for_panic(); +} + +/* + * This function will always be invoked to make sure that KGDB will grab + * what it needs to so that if something happens while the system is + * running, KGDB will get involved. If kgdb_early_entry() has already + * been invoked, there is little we need to do. + */ +static int __init kgdb_late_entry(void) +{ + int need_break = 0; + + /* If kgdb_initialized is -1 then we were passed kgdbwait. */ + if (kgdb_initialized == -1) + need_break = 1; + + /* + * If we haven't tried to initialize KGDB yet, we need to call + * kgdb_arch_init before moving onto the I/O. + */ + if (!kgdb_initialized) + kgdb_arch_init(); + + if (kgdb_initialized != 1) { + if (kgdb_io_ops.init && kgdb_io_ops.init()) { + /* When KGDB allows I/O via modules and the core + * I/O init fails KGDB must default to defering the + * I/O setup, and appropriately print an error about + * it. + */ + printk(KERN_ERR "kgdb: Could not setup core I/O " + "for KGDB.\n"); + printk(KERN_INFO "kgdb: Defering I/O setup to kernel " + "module.\n"); + memset(&kgdb_io_ops, 0, sizeof(struct kgdb_io)); + } + + kgdb_internal_init(); + + /* KGDB can assume that if kgdb_io_ops.init was defined that + * panic registion should be performed at this time. This means + * kgdb_io_ops.init did not come from a kernel module and was + * initialized statically by a built in. + */ + if (kgdb_io_ops.init) + kgdb_register_for_panic(); + } + + /* Registering to reboot notifier list*/ + register_reboot_notifier(&kgdb_reboot_notifier); + + /* Now do any late init of the I/O. */ + if (kgdb_io_ops.late_init) + kgdb_io_ops.late_init(); + + if (need_break) { + printk(KERN_CRIT "kgdb: Waiting for connection from remote" + " gdb...\n"); + breakpoint(); + } + + return 0; +} + +late_initcall(kgdb_late_entry); + +/* + * This function will generate a breakpoint exception. It is used at the + * beginning of a program to sync up with a debugger and can be used + * otherwise as a quick means to stop program execution and "break" into + * the debugger. + */ +void breakpoint(void) +{ + if (kgdb_initialized != 1) { + kgdb_early_entry(); + if (kgdb_initialized == 1) + printk(KERN_CRIT "Waiting for connection from remote " + "gdb...\n"); + else { + printk(KERN_CRIT "KGDB cannot initialize I/O yet.\n"); + return; + } + } + + atomic_set(&kgdb_setting_breakpoint, 1); + wmb(); + BREAKPOINT(); + wmb(); + atomic_set(&kgdb_setting_breakpoint, 0); +} + +EXPORT_SYMBOL(breakpoint); + +#ifdef CONFIG_MAGIC_SYSRQ +static void sysrq_handle_gdb(int key, struct pt_regs *pt_regs, + struct tty_struct *tty) +{ + printk("Entering GDB stub\n"); + breakpoint(); +} +static struct sysrq_key_op sysrq_gdb_op = { + .handler = sysrq_handle_gdb, + .help_msg = "Gdb", + .action_msg = "GDB", +}; + +static int gdb_register_sysrq(void) +{ + printk("Registering GDB sysrq handler\n"); + register_sysrq_key('g', &sysrq_gdb_op); + return 0; +} + +module_init(gdb_register_sysrq); +#endif + +static int kgdb_notify_reboot(struct notifier_block *this, + unsigned long code, void *x) +{ + + unsigned long flags; + + /* If we're debugging, or KGDB has not connected, don't try + * and print. */ + if (!kgdb_connected || atomic_read(&debugger_active) != 0) + return 0; + if ((code == SYS_RESTART) || (code == SYS_HALT) || (code == SYS_POWER_OFF)){ + local_irq_save(flags); + put_packet("X00"); + local_irq_restore(flags); + } + return NOTIFY_DONE; +} + +#ifdef CONFIG_KGDB_CONSOLE +void kgdb_console_write(struct console *co, const char *s, unsigned count) +{ + unsigned long flags; + + /* If we're debugging, or KGDB has not connected, don't try + * and print. */ + if (!kgdb_connected || atomic_read(&debugger_active) != 0) + return; + + local_irq_save(flags); + kgdb_msg_write(s, count); + local_irq_restore(flags); +} + +static struct console kgdbcons = { + .name = "kgdb", + .write = kgdb_console_write, + .flags = CON_PRINTBUFFER | CON_ENABLED, +}; +static int __init kgdb_console_init(void) +{ + register_console(&kgdbcons); + return 0; +} + +console_initcall(kgdb_console_init); +#endif + +static int __init opt_kgdb_enter(char *str) +{ + /* We've already done this by an explicit breakpoint() call. */ + if (kgdb_initialized) + return 0; + + /* Call breakpoint() which will take care of init. */ + breakpoint(); + + return 0; +} + +early_param("kgdbwait", opt_kgdb_enter); --- linux-2.6.20.orig/kernel/module.c +++ linux-2.6.20/kernel/module.c @@ -53,19 +53,41 @@ #ifndef ARCH_SHF_SMALL #define ARCH_SHF_SMALL 0 #endif +#undef LKM_LOAD_BENCH +#ifdef LKM_LOAD_BENCH + +#ifdef CONFIG_LKM_HASH +const char lkm_loader[] = "GNU hash"; +#else +const char lkm_loader[] = "Standard"; +#endif + +static inline s64 timeval_to_microsec(const struct timeval *tv) +{ + return ((s64) tv->tv_sec * 1000000L) + tv->tv_usec; +} + +static inline void print_elapsed(const char *module, struct timeval* start, struct timeval* end) { + + printk(KERN_INFO"LKM loader: %s - module: %s - spent %llu microsecs\n", lkm_loader, module,\ + timeval_to_microsec(end) - timeval_to_microsec(start)); +} +#endif + /* If this is set, the section belongs in the init part of the module */ #define INIT_OFFSET_MASK (1UL << (BITS_PER_LONG-1)) /* Protects module list */ static DEFINE_SPINLOCK(modlist_lock); /* List of modules, protected by module_mutex AND modlist_lock */ static DEFINE_MUTEX(module_mutex); static LIST_HEAD(modules); +static DEFINE_MUTEX(notify_mutex); static BLOCKING_NOTIFIER_HEAD(module_notify_list); int register_module_notifier(struct notifier_block * nb) { @@ -143,11 +165,62 @@ extern const unsigned long __start___kcr #define symversion(base, idx) NULL #else #define symversion(base, idx) ((base != NULL) ? ((base) + (idx)) : NULL) #endif -/* lookup symbol in given range of kernel_symbols */ +#ifdef CONFIG_LKM_HASH + +#define HASH_VALUE_PARAM const unsigned long gnu_hash_value, +#define HASH_VALUE_DEF(__name) const unsigned long gnu_hash_value = gnu_hash(__name) +#define HASH_VALUE_ARG gnu_hash_value, + +#define SYMHASH_INDEX_DEF unsigned int symhashindex = 0 +#define SYMHASH_INDEX_ARG symhashindex, +#define SYMHASH_INDEX_PARAM unsigned int symhashindex, +#define SYM_HASH(__sym) gnu_hash(__sym), +#define KSYM_HASH(__sym) __sym.hash_value, + +static unsigned long gnu_hash (const unsigned char *name) +{ + unsigned long h = 5381; + unsigned char c; + for (c = *name; c != '\0'; c = *++name) + h = h * 33 + c; + return h & 0xffffffff; +} + +/* lookup symbol on given range of kernel_symbols */ +static const struct kernel_symbol *lookup_symbol(const char *name, + const unsigned long hash_value, + const struct kernel_symbol *start, + const struct kernel_symbol *stop) +{ + const struct kernel_symbol *ks = start; + + for (; ks < stop; ks++) { + + /* If hash values don't match, we are sure symbols are different, + otherwise we need to explicitely do string comparison. + */ + if((ks->hash_value == hash_value) && (strcmp(ks->name, name) == 0)) + return ks; + } + return NULL; +} + +#else + +#define HASH_VALUE_PARAM +#define HASH_VALUE_DEF(__name) +#define HASH_VALUE_ARG +#define SYMHASH_INDEX_DEF +#define SYMHASH_INDEX_ARG +#define SYMHASH_INDEX_PARAM +#define SYM_HASH(__sym) +#define KSYM_HASH(__sym) + +/* lookup symbol on given range of kernel_symbols */ static const struct kernel_symbol *lookup_symbol(const char *name, const struct kernel_symbol *start, const struct kernel_symbol *stop) { const struct kernel_symbol *ks = start; @@ -155,10 +228,13 @@ static const struct kernel_symbol *looku if (strcmp(ks->name, name) == 0) return ks; return NULL; } +#endif + + static void printk_unused_warning(const char *name) { printk(KERN_WARNING "Symbol %s is marked as UNUSED, " "however this module is using it.\n", name); printk(KERN_WARNING "This symbol will go away in the future.\n"); @@ -167,35 +243,35 @@ static void printk_unused_warning(const "mailinglist together with submitting your code for " "inclusion.\n"); } /* Find a symbol, return value, crc and module which owns it */ -static unsigned long __find_symbol(const char *name, +static unsigned long __find_symbol(const char *name, HASH_VALUE_PARAM struct module **owner, const unsigned long **crc, int gplok) { struct module *mod; const struct kernel_symbol *ks; /* Core kernel first. */ *owner = NULL; - ks = lookup_symbol(name, __start___ksymtab, __stop___ksymtab); + ks = lookup_symbol(name, HASH_VALUE_ARG __start___ksymtab, __stop___ksymtab); if (ks) { *crc = symversion(__start___kcrctab, (ks - __start___ksymtab)); return ks->value; } if (gplok) { - ks = lookup_symbol(name, __start___ksymtab_gpl, + ks = lookup_symbol(name, HASH_VALUE_ARG __start___ksymtab_gpl, __stop___ksymtab_gpl); if (ks) { *crc = symversion(__start___kcrctab_gpl, (ks - __start___ksymtab_gpl)); return ks->value; } } - ks = lookup_symbol(name, __start___ksymtab_gpl_future, + ks = lookup_symbol(name, HASH_VALUE_ARG __start___ksymtab_gpl_future, __stop___ksymtab_gpl_future); if (ks) { if (!gplok) { printk(KERN_WARNING "Symbol %s is being used " "by a non-GPL module, which will not " @@ -208,21 +284,21 @@ static unsigned long __find_symbol(const *crc = symversion(__start___kcrctab_gpl_future, (ks - __start___ksymtab_gpl_future)); return ks->value; } - ks = lookup_symbol(name, __start___ksymtab_unused, + ks = lookup_symbol(name, HASH_VALUE_ARG __start___ksymtab_unused, __stop___ksymtab_unused); if (ks) { printk_unused_warning(name); *crc = symversion(__start___kcrctab_unused, (ks - __start___ksymtab_unused)); return ks->value; } if (gplok) - ks = lookup_symbol(name, __start___ksymtab_unused_gpl, + ks = lookup_symbol(name, HASH_VALUE_ARG __start___ksymtab_unused_gpl, __stop___ksymtab_unused_gpl); if (ks) { printk_unused_warning(name); *crc = symversion(__start___kcrctab_unused_gpl, (ks - __start___ksymtab_unused_gpl)); @@ -230,43 +306,43 @@ static unsigned long __find_symbol(const } /* Now try modules. */ list_for_each_entry(mod, &modules, list) { *owner = mod; - ks = lookup_symbol(name, mod->syms, mod->syms + mod->num_syms); + ks = lookup_symbol(name, HASH_VALUE_ARG mod->syms, mod->syms + mod->num_syms); if (ks) { *crc = symversion(mod->crcs, (ks - mod->syms)); return ks->value; } if (gplok) { - ks = lookup_symbol(name, mod->gpl_syms, + ks = lookup_symbol(name, HASH_VALUE_ARG mod->gpl_syms, mod->gpl_syms + mod->num_gpl_syms); if (ks) { *crc = symversion(mod->gpl_crcs, (ks - mod->gpl_syms)); return ks->value; } } - ks = lookup_symbol(name, mod->unused_syms, mod->unused_syms + mod->num_unused_syms); + ks = lookup_symbol(name, HASH_VALUE_ARG mod->unused_syms, mod->unused_syms + mod->num_unused_syms); if (ks) { printk_unused_warning(name); *crc = symversion(mod->unused_crcs, (ks - mod->unused_syms)); return ks->value; } if (gplok) { - ks = lookup_symbol(name, mod->unused_gpl_syms, + ks = lookup_symbol(name, HASH_VALUE_ARG mod->unused_gpl_syms, mod->unused_gpl_syms + mod->num_unused_gpl_syms); if (ks) { printk_unused_warning(name); *crc = symversion(mod->unused_gpl_crcs, (ks - mod->unused_gpl_syms)); return ks->value; } } - ks = lookup_symbol(name, mod->gpl_future_syms, + ks = lookup_symbol(name, HASH_VALUE_ARG mod->gpl_future_syms, (mod->gpl_future_syms + mod->num_gpl_future_syms)); if (ks) { if (!gplok) { printk(KERN_WARNING "Symbol %s is being used " @@ -704,10 +780,16 @@ sys_delete_module(const char __user *nam /* Stop the machine so refcounts can't move and disable module. */ ret = try_stop_module(mod, flags, &forced); if (ret != 0) goto out; + mutex_lock(¬ify_mutex); + blocking_notifier_call_chain(&module_notify_list, MODULE_STATE_GOING, + mod); + mutex_unlock(¬ify_mutex); + + /* Never wait if forced. */ if (!forced && module_refcount(mod) != 0) wait_for_zero_refcount(mod); /* Final destruction now noone is using it. */ @@ -716,10 +798,15 @@ sys_delete_module(const char __user *nam mod->exit(); mutex_lock(&module_mutex); } free_module(mod); + mutex_lock(¬ify_mutex); + blocking_notifier_call_chain(&module_notify_list, MODULE_STATE_GONE, + NULL); + mutex_unlock(¬ify_mutex); + out: mutex_unlock(&module_mutex); return ret; } @@ -756,11 +843,11 @@ void __symbol_put(const char *symbol) struct module *owner; unsigned long flags; const unsigned long *crc; spin_lock_irqsave(&modlist_lock, flags); - if (!__find_symbol(symbol, &owner, &crc, 1)) + if (!__find_symbol(symbol, SYM_HASH(symbol) &owner, &crc, 1)) BUG(); module_put(owner); spin_unlock_irqrestore(&modlist_lock, flags); } EXPORT_SYMBOL(__symbol_put); @@ -837,10 +924,13 @@ static ssize_t show_initstate(struct mod state = "coming"; break; case MODULE_STATE_GOING: state = "going"; break; + case MODULE_STATE_GONE: + state = "gone"; + break; } return sprintf(buffer, "%s\n", state); } static struct module_attribute initstate = { @@ -903,11 +993,11 @@ static inline int check_modstruct_versio struct module *mod) { const unsigned long *crc; struct module *owner; - if (!__find_symbol("struct_module", &owner, &crc, 1)) + if (!__find_symbol("struct_module", SYM_HASH("struct_module") &owner, &crc, 1)) BUG(); return check_version(sechdrs, versindex, "struct_module", mod, crc); } @@ -944,17 +1034,18 @@ static inline int same_magic(const char /* Resolve a symbol for this module. I.e. if we find one, record usage. Must be holding module_mutex. */ static unsigned long resolve_symbol(Elf_Shdr *sechdrs, unsigned int versindex, const char *name, + HASH_VALUE_PARAM struct module *mod) { struct module *owner; unsigned long ret; const unsigned long *crc; - ret = __find_symbol(name, &owner, &crc, + ret = __find_symbol(name, HASH_VALUE_ARG &owner, &crc, !(mod->taints & TAINT_PROPRIETARY_MODULE)); if (ret) { /* use_module can fail due to OOM, or module unloading */ if (!check_version(sechdrs, versindex, name, mod, crc) || !use_module(mod, owner)) @@ -1190,10 +1281,15 @@ static void free_module(struct module *m unwind_remove_table(mod->unwind_info, 0); /* Arch-specific cleanup. */ module_arch_cleanup(mod); +#ifdef CONFIG_KGDB + /* kgdb info */ + vfree(mod->mod_sections); +#endif + /* Module unload stuff */ module_unload_free(mod); /* This may be NULL, but that's OK */ module_free(mod, mod->module_init); @@ -1213,11 +1309,11 @@ void *__symbol_get(const char *symbol) struct module *owner; unsigned long value, flags; const unsigned long *crc; spin_lock_irqsave(&modlist_lock, flags); - value = __find_symbol(symbol, &owner, &crc, 1); + value = __find_symbol(symbol, SYM_HASH(symbol) &owner, &crc, 1); if (value && !strong_try_module_get(owner)) value = 0; spin_unlock_irqrestore(&modlist_lock, flags); return (void *)value; @@ -1234,18 +1330,18 @@ static int verify_export_symbols(struct unsigned long i, ret = 0; struct module *owner; const unsigned long *crc; for (i = 0; i < mod->num_syms; i++) - if (__find_symbol(mod->syms[i].name, &owner, &crc, 1)) { + if (__find_symbol(mod->syms[i].name, KSYM_HASH(mod->syms[i]) &owner, &crc, 1)) { name = mod->syms[i].name; ret = -ENOEXEC; goto dup; } for (i = 0; i < mod->num_gpl_syms; i++) - if (__find_symbol(mod->gpl_syms[i].name, &owner, &crc, 1)) { + if (__find_symbol(mod->gpl_syms[i].name, KSYM_HASH(mod->gpl_syms[i]) &owner, &crc, 1)) { name = mod->gpl_syms[i].name; ret = -ENOEXEC; goto dup; } @@ -1258,20 +1354,29 @@ dup: } /* Change all symbols so that sh_value encodes the pointer directly. */ static int simplify_symbols(Elf_Shdr *sechdrs, unsigned int symindex, + SYMHASH_INDEX_PARAM const char *strtab, unsigned int versindex, unsigned int pcpuindex, struct module *mod) { Elf_Sym *sym = (void *)sechdrs[symindex].sh_addr; unsigned long secbase; unsigned int i, n = sechdrs[symindex].sh_size / sizeof(Elf_Sym); int ret = 0; +#ifdef CONFIG_LKM_HASH +#define HASH_VALUE hash_values[u++], + unsigned long *hash_values = (void *)sechdrs[symhashindex].sh_addr; + unsigned int u = 0; +#else +#define HASH_VALUE +#endif + for (i = 1; i < n; i++) { switch (sym[i].st_shndx) { case SHN_COMMON: /* We compiled with -fno-common. These are not supposed to happen. */ @@ -1288,11 +1393,11 @@ static int simplify_symbols(Elf_Shdr *se break; case SHN_UNDEF: sym[i].st_value = resolve_symbol(sechdrs, versindex, - strtab + sym[i].st_name, mod); + strtab + sym[i].st_name, HASH_VALUE mod); /* Ok if resolved. */ if (sym[i].st_value != 0) break; /* Ok if weak. */ @@ -1449,17 +1554,43 @@ static void setup_modinfo(struct module infoindex, attr->attr.name)); } } +#ifdef CONFIG_KGDB +int add_modsects (struct module *mod, Elf_Ehdr *hdr, Elf_Shdr *sechdrs, const + char *secstrings) +{ + int i; + + mod->num_sections = hdr->e_shnum - 1; + mod->mod_sections = vmalloc((hdr->e_shnum - 1) * + sizeof(struct mod_section)); + + if (mod->mod_sections == NULL) + return -ENOMEM; + + for (i = 1; i < hdr->e_shnum; i++) { + mod->mod_sections[i - 1].address = (void *)sechdrs[i].sh_addr; + strncpy(mod->mod_sections[i - 1].name, secstrings + + sechdrs[i].sh_name, MAX_SECTNAME); + mod->mod_sections[i - 1].name[MAX_SECTNAME] = '\0'; + } + + return 0; +} +#endif + #ifdef CONFIG_KALLSYMS int is_exported(const char *name, const struct module *mod) { - if (!mod && lookup_symbol(name, __start___ksymtab, __stop___ksymtab)) + HASH_VALUE_DEF(name); + + if (!mod && lookup_symbol(name, HASH_VALUE_ARG __start___ksymtab, __stop___ksymtab)) return 1; else - if (mod && lookup_symbol(name, mod->syms, mod->syms + mod->num_syms)) + if (mod && lookup_symbol(name, HASH_VALUE_ARG mod->syms, mod->syms + mod->num_syms)) return 1; else return 0; } @@ -1541,10 +1672,13 @@ static struct module *load_module(void _ Elf_Shdr *sechdrs; char *secstrings, *args, *modmagic, *strtab = NULL; unsigned int i; unsigned int symindex = 0; unsigned int strindex = 0; +#ifdef CONFIG_LKM_HASH + unsigned int symhashindex = 0; +#endif unsigned int setupindex; unsigned int exindex; unsigned int exportindex; unsigned int modindex; unsigned int obsparmindex; @@ -1563,10 +1697,13 @@ static struct module *load_module(void _ unsigned int unusedgplcrcindex; struct module *mod; long err = 0; void *percpu = NULL, *ptr = NULL; /* Stops spurious gcc warning */ struct exception_table_entry *extable; +#ifdef LKM_LOAD_BENCH + struct timeval start, end; +#endif mm_segment_t old_fs; DEBUGP("load_module: umod=%p, len=%lu, uargs=%p\n", umod, len, uargs); if (len < sizeof(*hdr)) @@ -1635,10 +1772,21 @@ static struct module *load_module(void _ mod->name); err = -ENOEXEC; goto free_hdr; } +#ifdef CONFIG_LKM_HASH + symhashindex = find_sec(hdr, sechdrs, secstrings, ".symtab.hash"); + if (symhashindex == 0) { + printk(KERN_WARNING "%s: module has no hash values for symbols (stripped?)\n", + mod->name); + err = -ENOEXEC; + goto free_hdr; + } +#endif + + /* Optional sections */ exportindex = find_sec(hdr, sechdrs, secstrings, "__ksymtab"); gplindex = find_sec(hdr, sechdrs, secstrings, "__ksymtab_gpl"); gplfutureindex = find_sec(hdr, sechdrs, secstrings, "__ksymtab_gpl_future"); unusedindex = find_sec(hdr, sechdrs, secstrings, "__ksymtab_unused"); @@ -1778,15 +1926,21 @@ static struct module *load_module(void _ /* Set up MODINFO_ATTR fields */ setup_modinfo(mod, sechdrs, infoindex); /* Fix up syms, so that st_value is a pointer to location. */ - err = simplify_symbols(sechdrs, symindex, strtab, versindex, pcpuindex, +#ifdef LKM_LOAD_BENCH + do_gettimeofday(&start); +#endif + err = simplify_symbols(sechdrs, symindex, SYMHASH_INDEX_ARG strtab, versindex, pcpuindex, mod); if (err < 0) goto cleanup; - +#ifdef LKM_LOAD_BENCH + do_gettimeofday(&end); + print_elapsed(mod->name, &start, &end); +#endif /* Set up EXPORTed & EXPORT_GPLed symbols (section 0 is 0 length) */ mod->num_syms = sechdrs[exportindex].sh_size / sizeof(*mod->syms); mod->syms = (void *)sechdrs[exportindex].sh_addr; if (crcindex) mod->crcs = (void *)sechdrs[crcindex].sh_addr; @@ -1860,10 +2014,16 @@ static struct module *load_module(void _ percpu_modcopy(mod->percpu, (void *)sechdrs[pcpuindex].sh_addr, sechdrs[pcpuindex].sh_size); add_kallsyms(mod, sechdrs, symindex, strindex, secstrings); +#ifdef CONFIG_KGDB + err = add_modsects(mod, hdr, sechdrs, secstrings); + if (err < 0) + goto nomodsectinfo; +#endif + err = module_finalize(hdr, sechdrs, mod); if (err < 0) goto cleanup; /* flush the icache in correct context */ @@ -1920,10 +2080,15 @@ static struct module *load_module(void _ return mod; arch_cleanup: module_arch_cleanup(mod); cleanup: + +#ifdef CONFIG_KGDB +nomodsectinfo: + vfree(mod->mod_sections); +#endif module_unload_free(mod); module_free(mod, mod->module_init); free_core: module_free(mod, mod->module_core); free_percpu: @@ -1991,10 +2156,15 @@ sys_init_module(void __user *umod, ret = mod->init(); if (ret < 0) { /* Init routine failed: abort. Try to protect us from buggy refcounters. */ mod->state = MODULE_STATE_GOING; + mutex_lock(¬ify_mutex); + blocking_notifier_call_chain(&module_notify_list, + MODULE_STATE_GOING, + mod); + mutex_unlock(¬ify_mutex); synchronize_sched(); if (mod->unsafe) printk(KERN_ERR "%s: module is now stuck!\n", mod->name); else { --- linux-2.6.20.orig/kernel/pid.c +++ linux-2.6.20/kernel/pid.c @@ -381,12 +381,17 @@ void free_pid_ns(struct kref *kref) } /* * The pid hash table is scaled according to the amount of memory in the * machine. From a minimum of 16 slots up to 4096 slots at one gigabyte or - * more. + * more. KGDB needs to know if this function has been called already, + * since we might have entered KGDB very early. */ +#ifdef CONFIG_KGDB +int pidhash_init_done; +#endif + void __init pidhash_init(void) { int i, pidhash_size; unsigned long megabytes = nr_kernel_pages >> (20 - PAGE_SHIFT); @@ -401,10 +406,14 @@ void __init pidhash_init(void) pid_hash = alloc_bootmem(pidhash_size * sizeof(*(pid_hash))); if (!pid_hash) panic("Could not alloc pidhash!\n"); for (i = 0; i < pidhash_size; i++) INIT_HLIST_HEAD(&pid_hash[i]); + +#ifdef CONFIG_KGDB + pidhash_init_done = 1; +#endif } void __init pidmap_init(void) { init_pid_ns.pidmap[0].page = kzalloc(PAGE_SIZE, GFP_KERNEL); --- linux-2.6.20.orig/kernel/power/main.c +++ linux-2.6.20/kernel/power/main.c @@ -85,11 +85,11 @@ static int suspend_prepare(suspend_state if (pm_ops->prepare) { if ((error = pm_ops->prepare(state))) goto Thaw; } - suspend_console(); + //suspend_console(); if ((error = device_suspend(PMSG_SUSPEND))) { printk(KERN_ERR "Some devices failed to suspend\n"); goto Finish; } return 0; --- linux-2.6.20.orig/kernel/sched.c +++ linux-2.6.20/kernel/sched.c @@ -50,10 +50,11 @@ #include #include #include #include #include +#include #include #include /* @@ -6964,10 +6965,15 @@ void __init sched_init(void) void __might_sleep(char *file, int line) { #ifdef in_atomic static unsigned long prev_jiffy; /* ratelimiting */ +#ifdef CONFIG_KGDB + if (atomic_read(&debugger_active)) + return; +#endif /* CONFIG_KGDB*/ + if ((in_atomic() || irqs_disabled()) && system_state == SYSTEM_RUNNING && !oops_in_progress) { if (time_before(jiffies, prev_jiffy + HZ) && prev_jiffy) return; prev_jiffy = jiffies; --- linux-2.6.20.orig/kernel/softlockup.c +++ linux-2.6.20/kernel/softlockup.c @@ -11,10 +11,11 @@ #include #include #include #include #include +#include static DEFINE_SPINLOCK(print_lock); static DEFINE_PER_CPU(unsigned long, touch_timestamp); static DEFINE_PER_CPU(unsigned long, print_timestamp); @@ -35,10 +36,13 @@ static struct notifier_block panic_block }; void touch_softlockup_watchdog(void) { __raw_get_cpu_var(touch_timestamp) = jiffies; +#ifdef CONFIG_KGDB + atomic_set(&kgdb_sync_softlockup[raw_smp_processor_id()], 0); +#endif } EXPORT_SYMBOL(touch_softlockup_watchdog); /* * This callback runs from the timer interrupt, and checks --- linux-2.6.20.orig/kernel/timer.c +++ linux-2.6.20/kernel/timer.c @@ -31,10 +31,11 @@ #include #include #include #include #include +#include #include #include #include #include @@ -1205,12 +1206,19 @@ static inline void update_times(unsigned * jiffies is defined in the linker script... */ void do_timer(unsigned long ticks) { +#ifdef CONFIG_KGDB + int this_cpu = smp_processor_id(); +#endif /* CONFIG_KGDB*/ jiffies_64 += ticks; update_times(ticks); + +#ifdef CONFIG_KGDB + if(!atomic_read(&kgdb_sync_softlockup[this_cpu])); +#endif } #ifdef __ARCH_WANT_SYS_ALARM /* --- linux-2.6.20.orig/lib/Kconfig.debug +++ linux-2.6.20/lib/Kconfig.debug @@ -427,5 +427,84 @@ config FAIL_MAKE_REQUEST config FAULT_INJECTION_DEBUG_FS bool "Debugfs entries for fault-injection capabilities" depends on FAULT_INJECTION && SYSFS && DEBUG_FS help Enable configuration of fault-injection capabilities via debugfs. + +config WANT_EXTRA_DEBUG_INFORMATION + bool + select DEBUG_INFO + select FRAME_POINTER if X86 + default n + +config KGDB + bool "KGDB: kernel debugging with remote gdb" + select WANT_EXTRA_DEBUG_INFORMATION + depends on DEBUG_KERNEL && (ARM || X86 || MIPS || (SUPERH && !SUPERH64) || IA64 || X86_64 || PPC) + help + If you say Y here, it will be possible to remotely debug the + kernel using gdb. It is strongly suggested that you enable + DEBUG_INFO, and if available on your platform, FRAME_POINTER. + Documentation of kernel debugger available at + http://kgdb.sourceforge.net as well as in DocBook form + in Documentation/DocBook/. If unsure, say N. + +choice + prompt "Method for KGDB communication" + depends on KGDB + default KGDB_ONLY_MODULES + help + There are a number of different ways in which you can communicate + with KGDB. The most common is via serial, with the 8250 driver + (should your hardware have an 8250, or ns1655x style uart). + Another option is to use the NETPOLL framework and UDP, should + your ethernet card support this. Other options may exist. + You can elect to have one core I/O driver that is built into the + kernel for debugging as the kernel is booting, or using only + kernel modules. + +config KGDB_ONLY_MODULES + bool "KGDB: Use only kernel modules for I/O" + depends on MODULES + help + Use only kernel modules to configure KGDB I/O after the + kernel is booted. + +config KGDBOE_NOMODULE + bool "KGDB: On ethernet - in kernel" + select KGDBOE + select NETPOLL + select NETPOLL_TRAP + select NETPOLL_RX + help + Uses the NETPOLL API to communicate with the host GDB via UDP. + In order for this to work, the ethernet interface specified must + support the NETPOLL API, and this must be initialized at boot. + See the documentation for syntax. + +config KGDBOE + tristate "KGDB: On ethernet" if !KGDBOE_NOMODULE + depends on m && KGDB + select NETPOLL + select NETPOLL_TRAP + select NETPOLL_RX + help + Uses the NETPOLL API to communicate with the host GDB via UDP. + In order for this to work, the ethernet interface specified must + support the NETPOLL API, and this must be initialized at boot. + See the documentation for syntax. + +endchoice + +config KGDB_CONSOLE + bool "KGDB: Console messages through gdb" + depends on KGDB + help + If you say Y here, console messages will appear through gdb. + Other consoles such as tty or ttyS will continue to work as usual. + Note, that if you use this in conjunction with KGDB_ETH, if the + ethernet driver runs into an error condition during use with KGDB + it is possible to hit an infinite recusrion, causing the kernel + to crash, and typically reboot. For this reason, it is preferable + to use NETCONSOLE in conjunction with KGDB_ETH instead of + KGDB_CONSOLE. + --- linux-2.6.20.orig/net/core/netpoll.c +++ linux-2.6.20/net/core/netpoll.c @@ -496,11 +496,14 @@ int __netpoll_rx(struct sk_buff *skb) if (np->local_port && np->local_port != ntohs(uh->dest)) goto out; np->rx_hook(np, ntohs(uh->source), (char *)(uh+1), - ulen - sizeof(struct udphdr)); +#ifdef CONFIG_KGDB + ulen - sizeof(struct udphdr), + skb); +#endif /* CONFIG_KGDB*/ kfree_skb(skb); return 1; out: --- linux-2.6.20.orig/net/sunrpc/xprtsock.c +++ linux-2.6.20/net/sunrpc/xprtsock.c @@ -1610,12 +1610,13 @@ struct rpc_xprt *xs_setup_tcp(struct soc xprt->ops = &xs_tcp_ops; if (to) xprt->timeout = *to; - else - xprt_set_timeout(&xprt->timeout, 2, 60 * HZ); + else { + xprt_set_timeout(&xprt->timeout, 7, 60 * HZ); + } xs_format_peer_addresses(xprt); dprintk("RPC: set up transport to address %s\n", xprt->address_strings[RPC_DISPLAY_ALL]); --- linux-2.6.20.orig/scripts/Makefile +++ linux-2.6.20/scripts/Makefile @@ -18,8 +18,9 @@ always := $(hostprogs-y) $(hostprogs-m) # The following hostprogs-y programs are only build on demand hostprogs-y += unifdef subdir-$(CONFIG_MODVERSIONS) += genksyms subdir-y += mod +subdir-$(CONFIG_LKM_HASH) += ksymhash # Let clean descend into subdirs subdir- += basic kconfig package --- linux-2.6.20.orig/scripts/Makefile.modpost +++ linux-2.6.20/scripts/Makefile.modpost @@ -97,13 +97,15 @@ targets += $(modules:.ko=.mod.o) # Step 6), final link of the modules quiet_cmd_ld_ko_o = LD [M] $@ cmd_ld_ko_o = $(LD) $(LDFLAGS) $(LDFLAGS_MODULE) -o $@ \ $(filter-out FORCE,$^) +include $(srctree)/scripts/ksymhash/Makefile $(modules): %.ko :%.o %.mod.o FORCE $(call if_changed,ld_ko_o) + $(rule_ksymhash) targets += $(modules) # Add FORCE to the prequisites of a target to force it to be always rebuilt. --- /dev/null +++ linux-2.6.20/scripts/dwarfh.awk @@ -0,0 +1,19 @@ +BEGIN { + print "#ifndef _ELF_DWARF_H" + print "/* Machine generated from dwarf2.h by scripts/dwarfh.awk */" +} +$2 == "=" { + gsub(/,/, "", $3) + print "#define " $1 "\t " $3 +} +$1 == "#define" { + print $0 + while( index($0,"\\") == length($0)){ + getline + print $0 + } +} +/.*/ {} +END { + print "#endif" +} --- linux-2.6.20.orig/scripts/kconfig/Makefile +++ linux-2.6.20/scripts/kconfig/Makefile @@ -2,26 +2,34 @@ # Kernel configuration targets # These targets are used from top-level makefile PHONY += oldconfig xconfig gconfig menuconfig config silentoldconfig update-po-config -xconfig: $(obj)/qconf +# This veriable will contains list of paths of Makefiles +# which contains machconfig tag in it +MACHCONFIG_PATHS =`find arch/$(ARCH)/ -name Makefile | xargs grep machconfig: | sed 's/Makefile:machconfig://g' | sed 's/Makefile://g'` + +#machconfig is used to resolve any machine specific configuration dependency +machconfig: + @set -e; for i in $(MACHCONFIG_PATHS); do $(MAKE) -C $$i $@; done + +xconfig: $(obj)/qconf machconfig $< arch/$(ARCH)/Kconfig -gconfig: $(obj)/gconf +gconfig: $(obj)/gconf machconfig $< arch/$(ARCH)/Kconfig -menuconfig: $(obj)/mconf +menuconfig: $(obj)/mconf machconfig $< arch/$(ARCH)/Kconfig -config: $(obj)/conf +config: $(obj)/conf machconfig $< arch/$(ARCH)/Kconfig -oldconfig: $(obj)/conf +oldconfig: $(obj)/conf machconfig $< -o arch/$(ARCH)/Kconfig -silentoldconfig: $(obj)/conf +silentoldconfig: $(obj)/conf machconfig $< -s arch/$(ARCH)/Kconfig update-po-config: $(obj)/kxgettext xgettext --default-domain=linux \ --add-comments --keyword=_ --keyword=N_ \ @@ -41,31 +49,31 @@ update-po-config: $(obj)/kxgettext $(Q)rm -f arch/um/Kconfig_arch $(Q)rm -f scripts/kconfig/linux_*.pot scripts/kconfig/config.pot PHONY += randconfig allyesconfig allnoconfig allmodconfig defconfig -randconfig: $(obj)/conf +randconfig: $(obj)/conf machconfig $< -r arch/$(ARCH)/Kconfig -allyesconfig: $(obj)/conf +allyesconfig: $(obj)/conf machconfig $< -y arch/$(ARCH)/Kconfig -allnoconfig: $(obj)/conf +allnoconfig: $(obj)/conf machconfig $< -n arch/$(ARCH)/Kconfig -allmodconfig: $(obj)/conf +allmodconfig: $(obj)/conf machconfig $< -m arch/$(ARCH)/Kconfig -defconfig: $(obj)/conf +defconfig: $(obj)/conf machconfig ifeq ($(KBUILD_DEFCONFIG),) $< -d arch/$(ARCH)/Kconfig else @echo *** Default configuration is based on '$(KBUILD_DEFCONFIG)' $(Q)$< -D arch/$(ARCH)/configs/$(KBUILD_DEFCONFIG) arch/$(ARCH)/Kconfig endif -%_defconfig: $(obj)/conf +%_defconfig: $(obj)/conf machconfig $(Q)$< -D arch/$(ARCH)/configs/$@ arch/$(ARCH)/Kconfig # Help text used by make help help: @echo ' config - Update current config utilising a line-oriented program' --- /dev/null +++ linux-2.6.20/scripts/ksymhash/Makefile @@ -0,0 +1,35 @@ +# Shared between Makefile and Makefile.modpost + +hostprogs-y += ksymhash mk_elfconfig +always := $(hostprogs-y) empty.o + +ksymhash-objs := ksymhash.o elflib.o + +# dependencies on generated files need to be listed explicitly + +$(obj)/ksymhash.o : $(obj)/elflib.o +$(obj)/elflib.o : $(obj)/elfconfig.h + +quiet_cmd_elfconfig = MKELF $@ + cmd_elfconfig = $(obj)/mk_elfconfig $(ARCH) < $< > $@ + +$(obj)/elfconfig.h: $(obj)/empty.o $(obj)/mk_elfconfig FORCE + $(call if_changed,elfconfig) + +targets += elfconfig.h + +# Post-process vmlinux image to populate ksymtabs with GNU hash values + +quiet_cmd_ksymhash = SYMHASH + cmd_ksymhash = scripts/ksymhash/ksymhash + +ifdef CONFIG_LKM_HASH +define rule_ksymhash + $(Q)$(if $($(quiet)cmd_ksymhash), \ + echo ' $($(quiet)cmd_ksymhash) $@' &&) \ + $(cmd_ksymhash) $@ +endef +else +define rule_ksymhash +endef +endif --- /dev/null +++ linux-2.6.20/scripts/ksymhash/elflib.c @@ -0,0 +1,164 @@ +#include "elflib.h" + +void fatal(const char *fmt, ...) +{ + va_list arglist; + + fprintf(stderr, "FATAL: "); + + va_start(arglist, fmt); + vfprintf(stderr, fmt, arglist); + va_end(arglist); + + exit(1); +} + +void *grab_file(const char *filename, unsigned long *size) +{ + struct stat st; + void *map; + int fd; + + fd = open(filename, O_RDWR); + if (fd < 0 || fstat(fd, &st) != 0) + return NULL; + + *size = st.st_size; + map = mmap(NULL, *size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); + close(fd); + + if (map == MAP_FAILED) + return NULL; + return map; +} + +void release_file(void *file, unsigned long size) +{ + munmap(file, size); +} + +static inline void set_ksymtable(struct elf_info *info, enum ksymtab_type type, \ + Elf_Ehdr *hdr, Elf_Shdr *sechdrs, unsigned int secidx, \ + const char *secname) { + + info->ksym_tables[type].start = (struct kernel_symbol *) ((void *) hdr + sechdrs[secidx].sh_offset); + info->ksym_tables[type].stop = (struct kernel_symbol *) ((void *) hdr + sechdrs[secidx].sh_offset + sechdrs[secidx].sh_size); + info->ksym_tables[type].name = strdup(secname); + info->ksym_tables[type].entries = sechdrs[secidx].sh_size / sizeof(struct kernel_symbol); +} + +int parse_elf(struct elf_info *info, const char *filename) +{ + unsigned int i; + Elf_Ehdr *hdr; + Elf_Shdr *sechdrs; + Elf_Sym *sym; + char *lkm_suffix; + + hdr = grab_file(filename, &info->size); + if (!hdr) { + perror(filename); + exit(1); + } + info->hdr = hdr; + if (info->size < sizeof(*hdr)) { + /* file too small, assume this is an empty .o file */ + return 0; + } + /* Is this a valid ELF file? */ + if ((hdr->e_ident[EI_MAG0] != ELFMAG0) || + (hdr->e_ident[EI_MAG1] != ELFMAG1) || + (hdr->e_ident[EI_MAG2] != ELFMAG2) || + (hdr->e_ident[EI_MAG3] != ELFMAG3)) { + /* Not an ELF file - silently ignore it */ + return 0; + } + + /* Check if it is the vmlinux or lkm */ + if((lkm_suffix = strstr(filename,".ko")) && (strlen(lkm_suffix) == 3)) + /* Likely this is a lkm */ + info->is_lkm = 1; + else { + info->is_lkm = 0; + /* Don't care */ + info->base_addr = 0; + } + + /* Fix endianness in ELF header */ + hdr->e_shoff = TO_NATIVE(hdr->e_shoff); + hdr->e_shstrndx = TO_NATIVE(hdr->e_shstrndx); + hdr->e_shnum = TO_NATIVE(hdr->e_shnum); + hdr->e_machine = TO_NATIVE(hdr->e_machine); + hdr->e_type = TO_NATIVE(hdr->e_type); + sechdrs = (void *)hdr + hdr->e_shoff; + info->sechdrs = sechdrs; + + /* Fix endianness in section headers */ + for (i = 0; i < hdr->e_shnum; i++) { + sechdrs[i].sh_type = TO_NATIVE(sechdrs[i].sh_type); + sechdrs[i].sh_offset = TO_NATIVE(sechdrs[i].sh_offset); + sechdrs[i].sh_size = TO_NATIVE(sechdrs[i].sh_size); + sechdrs[i].sh_link = TO_NATIVE(sechdrs[i].sh_link); + sechdrs[i].sh_name = TO_NATIVE(sechdrs[i].sh_name); + sechdrs[i].sh_info = TO_NATIVE(sechdrs[i].sh_info); + sechdrs[i].sh_addr = TO_NATIVE(sechdrs[i].sh_addr); + } + /* Find symbol tables and text section. */ + for (i = 1; i < hdr->e_shnum; i++) { + const char *secstrings + = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset; + const char *secname; + + if (sechdrs[i].sh_offset > info->size) { + fatal("%s is truncated. sechdrs[i].sh_offset=%u > sizeof(*hrd)=%ul\n", filename, (unsigned int)sechdrs[i].sh_offset, sizeof(*hdr)); + return 0; + } + secname = secstrings + sechdrs[i].sh_name; + + if (strcmp(secname, ".text") == 0) + info->base_addr = sechdrs[i].sh_addr - sechdrs[i].sh_offset; + + if (strcmp(secname, "__ksymtab") == 0) + set_ksymtable(info, KSYMTAB, hdr, sechdrs, i, secname); + else if (strcmp(secname, "__ksymtab_unused") == 0) + set_ksymtable(info, KSYMTAB_UNUSED, hdr, sechdrs, i, secname); + else if (strcmp(secname, "__ksymtab_gpl") == 0) + set_ksymtable(info, KSYMTAB_GPL, hdr, sechdrs, i, secname); + else if (strcmp(secname, "__ksymtab_unused_gpl") == 0) + set_ksymtable(info, KSYMTAB_UNUSED_GPL, hdr, sechdrs, i, secname); + else if (strcmp(secname, "__ksymtab_gpl_future") == 0) + set_ksymtable(info, KSYMTAB_GPL_FUTURE, hdr, sechdrs, i, secname); + else if (strcmp(secname, "__ksymtab_strings") == 0) + info->kstrings = (void *)hdr + sechdrs[i].sh_offset; + else if (strcmp(secname, ".symtab.hash") == 0) { + info->symtab_hash.start = (void *)hdr + sechdrs[i].sh_offset; + info->symtab_hash.stop = (void *)hdr + sechdrs[i].sh_offset + sechdrs[i].sh_size; + } + + + if (sechdrs[i].sh_type != SHT_SYMTAB) + continue; + + info->symtab.start = (void *)hdr + sechdrs[i].sh_offset; + info->symtab.stop = (void *)hdr + sechdrs[i].sh_offset + sechdrs[i].sh_size; + info->strtab = (void *)hdr + sechdrs[sechdrs[i].sh_link].sh_offset; + } + if (!info->symtab.start) { + fatal("%s has no symtab?\n", filename); + } + /* Fix endianness in symbols */ + for (sym = info->symtab.start; sym < info->symtab.stop; sym++) { + sym->st_shndx = TO_NATIVE(sym->st_shndx); + sym->st_name = TO_NATIVE(sym->st_name); + sym->st_value = TO_NATIVE(sym->st_value); + sym->st_size = TO_NATIVE(sym->st_size); + } + return 1; +} + +void parse_elf_finish(struct elf_info *info) +{ + release_file(info->hdr, info->size); +} + + --- /dev/null +++ linux-2.6.20/scripts/ksymhash/elflib.h @@ -0,0 +1,142 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + + + +#include "elfconfig.h" + +#if KERNEL_ELFCLASS == ELFCLASS32 + +#define Elf_Ehdr Elf32_Ehdr +#define Elf_Shdr Elf32_Shdr +#define Elf_Sym Elf32_Sym +#define Elf_Addr Elf32_Addr +#define Elf_Section Elf32_Section +#define ELF_ST_BIND ELF32_ST_BIND +#define ELF_ST_TYPE ELF32_ST_TYPE + +#define Elf_Rel Elf32_Rel +#define Elf_Rela Elf32_Rela +#define ELF_R_SYM ELF32_R_SYM +#define ELF_R_TYPE ELF32_R_TYPE + +/* It needs to match sizeof within kernel + * as defined in include/linux/module.h + */ +#define ksym_t uint32_t +#define kstr_t uint32_t +#define ksym_hash_t uint32_t +#else + +#define Elf_Ehdr Elf64_Ehdr +#define Elf_Shdr Elf64_Shdr +#define Elf_Sym Elf64_Sym +#define Elf_Addr Elf64_Addr +#define Elf_Section Elf64_Section +#define ELF_ST_BIND ELF64_ST_BIND +#define ELF_ST_TYPE ELF64_ST_TYPE + +#define Elf_Rel Elf64_Rel +#define Elf_Rela Elf64_Rela +#define ELF_R_SYM ELF64_R_SYM +#define ELF_R_TYPE ELF64_R_TYPE + +/* It needs to match sizeof within kernel + * as defined in include/linux/module.h + */ +#define ksym_t uint64_t +#define kstr_t uint64_t +#define ksym_hash_t uint64_t +#endif + +#if KERNEL_ELFDATA != HOST_ELFDATA + +static inline void __endian(const void *src, void *dest, unsigned int size) +{ + unsigned int i; + for (i = 0; i < size; i++) + ((unsigned char*)dest)[i] = ((unsigned char*)src)[size - i-1]; +} + +#define TO_NATIVE(x) \ +({ \ + typeof(x) __x; \ + __endian(&(x), &(__x), sizeof(__x)); \ + __x; \ +}) + +#else /* endianness matches */ + +#define TO_NATIVE(x) (x) + +#endif + +/* We have no more than 6 kernel symbol tables + __ksymtab + __ksymtab_gpl + __ksymtab_unused + __ksymtab_unused_gpl + __ksymtab_gpl_future + and + __ksymtab_strings +*/ + +enum ksymtab_type { + KSYMTAB = 0, + KSYMTAB_GPL, + KSYMTAB_UNUSED, + KSYMTAB_UNUSED_GPL, + KSYMTAB_GPL_FUTURE, + KSYMTAB_ALL, +}; + +struct kernel_symbol { + ksym_t value; + kstr_t name; + ksym_hash_t hash_value; +}; + +struct kernel_symtab { + const char* name; + struct kernel_symbol * start; + struct kernel_symbol * stop; + unsigned int entries; +}; + +struct elf_info { + unsigned long size; + Elf_Ehdr *hdr; + Elf_Shdr *sechdrs; + + unsigned char is_lkm; + unsigned long base_addr; + unsigned int unresolved; + struct { + Elf_Sym *start; + Elf_Sym *stop; + } symtab; + + struct { + ksym_hash_t *start; + ksym_hash_t *stop; + } symtab_hash; + + struct kernel_symtab ksym_tables[KSYMTAB_ALL]; + const char *strtab; + const char *kstrings; +}; + +void fatal(const char *fmt, ...); +void *grab_file(const char *filename, unsigned long *size); +void release_file(void *file, unsigned long size); +int parse_elf(struct elf_info *info, const char *filename); +void parse_elf_finish(struct elf_info *info); + + --- /dev/null +++ linux-2.6.20/scripts/ksymhash/empty.c @@ -0,0 +1 @@ +/* empty file to figure out endianness / word size */ --- /dev/null +++ linux-2.6.20/scripts/ksymhash/ksymhash.c @@ -0,0 +1,126 @@ +/* + * Copyright STMicroelectronics Ltd (2008) + * + * Author: Carmelo Amoroso + * + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include "elflib.h" + +#define GET_KSTRING(__ksym, __offset) (unsigned char*)(__ksym->name + __offset) + +#undef DEBUG +#ifdef DEBUG +#define debug(__msg...) fprintf(stdout, __msg) +#else +#define debug(__msg...) /* nothing */ +/*#define dump_ksym(__ksym, __kstr) nothing */ +#endif + +#define dump_undef(__undef, __hash) debug("\tUnresolved: %s\thash = 0x%lx\n", __undef, __hash) +#define dump_ksym(__ksym, __kstr) debug("\tExported: %s\thash = 0x%x\n", __kstr, __ksym->hash_value) + +static ksym_hash_t gnu_hash (const unsigned char *name) { + ksym_hash_t h = 5381; + unsigned char c; + for (c = *name; c != '\0'; c = *++name) + h = h * 33 + c; + return h & 0xffffffff; +} + + +static inline void compute_exported_hash(const struct elf_info *elf, enum ksymtab_type tp) { + + struct kernel_symbol * sym; + long s_offset; + + if(elf->is_lkm) { + /* + * ksym->name is an offset with respect to the start of the + * __ksymtab_strings + */ + s_offset = (long) elf->kstrings; + } else { + /* + * In this case, ksym->name is the absolute value of the string into + * the __ksymtab_strings + */ + s_offset = (long)elf->hdr - (long)elf->base_addr; + } + + for(sym = elf->ksym_tables[tp].start; sym < elf->ksym_tables[tp].stop; sym++) { + sym->hash_value = gnu_hash(GET_KSTRING(sym, s_offset)); + dump_ksym(sym, GET_KSTRING(sym, s_offset)); + } +} + +static inline void compute_unresolved_hash(struct elf_info *elf) { + + Elf_Sym *sym; + unsigned int undef = 0; + ksym_hash_t* hash_values = elf->symtab_hash.start; + + if(elf->is_lkm) { + for(sym = elf->symtab.start; sym < elf->symtab.stop; sym++) { + if(sym->st_shndx == SHN_UNDEF) { + /* undefined symbol */ + if (ELF_ST_BIND(sym->st_info) != STB_GLOBAL && + ELF_ST_BIND(sym->st_info) != STB_WEAK) + continue; + else { + /* GLOBAL or WEAK undefined symbols */ + *hash_values = gnu_hash((unsigned char *) (elf->strtab + sym->st_name)); + dump_undef(elf->strtab + sym->st_name, *hash_values); + /* The hash_values array stored into the .symtab.hash section + * is ordered as the undefined symbols of the .symtab + */ + hash_values++; + undef++; + } + } + } + } + elf->unresolved = undef; +} + + +int main(int argc, char **argv) { + + enum ksymtab_type k; + struct elf_info info = { }; + + if (!parse_elf(&info, argv[1])) { + exit(1); + } + + /* Skip __ksymtab_strings and __ksymtab.hash*/ + debug("--------------------------------------------------------------------------------\n"); + for(k=KSYMTAB; k < KSYMTAB_ALL; k++) { + + if(info.ksym_tables[k].name) { + + /* Compute hash value for exported symbols */ + compute_exported_hash(&info, k); + + debug("ktable: %s [exported: %u]\n", + info.ksym_tables[k].name, info.ksym_tables[k].entries); + } + } + debug("--------------------------------------------------------------------------------\n"); + + compute_unresolved_hash(&info); + debug("Module: %s [unresolved: %u]\n", argv[1], info.unresolved); + debug("--------------------------------------------------------------------------------\n"); + + + parse_elf_finish(&info); + return 0; +} --- /dev/null +++ linux-2.6.20/scripts/ksymhash/mk_elfconfig.c @@ -0,0 +1,66 @@ +#include +#include +#include +#include + +int +main(int argc, char **argv) +{ + unsigned char ei[EI_NIDENT]; + union { short s; char c[2]; } endian_test; + + if (argc != 2) { + fprintf(stderr, "Error: no arch\n"); + } + if (fread(ei, 1, EI_NIDENT, stdin) != EI_NIDENT) { + fprintf(stderr, "Error: input truncated\n"); + return 1; + } + if (memcmp(ei, ELFMAG, SELFMAG) != 0) { + fprintf(stderr, "Error: not ELF\n"); + return 1; + } + switch (ei[EI_CLASS]) { + case ELFCLASS32: + printf("#define KERNEL_ELFCLASS ELFCLASS32\n"); + break; + case ELFCLASS64: + printf("#define KERNEL_ELFCLASS ELFCLASS64\n"); + break; + default: + exit(1); + } + switch (ei[EI_DATA]) { + case ELFDATA2LSB: + printf("#define KERNEL_ELFDATA ELFDATA2LSB\n"); + break; + case ELFDATA2MSB: + printf("#define KERNEL_ELFDATA ELFDATA2MSB\n"); + break; + default: + exit(1); + } + + if (sizeof(unsigned long) == 4) { + printf("#define HOST_ELFCLASS ELFCLASS32\n"); + } else if (sizeof(unsigned long) == 8) { + printf("#define HOST_ELFCLASS ELFCLASS64\n"); + } + + endian_test.s = 0x0102; + if (memcmp(endian_test.c, "\x01\x02", 2) == 0) + printf("#define HOST_ELFDATA ELFDATA2MSB\n"); + else if (memcmp(endian_test.c, "\x02\x01", 2) == 0) + printf("#define HOST_ELFDATA ELFDATA2LSB\n"); + else + exit(1); + + if ((strcmp(argv[1], "v850") == 0) || (strcmp(argv[1], "h8300") == 0) + || (strcmp(argv[1], "blackfin") == 0)) + printf("#define MODULE_SYMBOL_PREFIX \"_\"\n"); + else + printf("#define MODULE_SYMBOL_PREFIX \"\"\n"); + + return 0; +} + --- linux-2.6.20.orig/scripts/mod/modpost.c +++ linux-2.6.20/scripts/mod/modpost.c @@ -1309,10 +1309,32 @@ static void add_srcversion(struct buffer buf_printf(b, "MODULE_INFO(srcversion, \"%s\");\n", mod->srcversion); } } +/** + * Record hash_values for unresolved symbols + **/ +static void add_symtab_hash(struct buffer *b, struct module *mod) +{ + struct symbol *s; + + buf_printf(b, "#ifdef CONFIG_LKM_HASH\n"); + buf_printf(b, "static unsigned long __symtab_hash[]\n"); + buf_printf(b, "__attribute_used__\n"); + buf_printf(b, "__attribute__((section(\".symtab.hash\"))) = {\n"); + + for (s = mod->unres; s; s = s->next) { + /* Fill with zero, the order of unresolved symbol is not yet correct + This will create a placeholder for the hash values + */ + buf_printf(b, "\t%#8lx,\n", 0L); + } + buf_printf(b, "};\n"); + buf_printf(b, "#endif\n"); +} + static void write_if_changed(struct buffer *b, const char *fname) { char *tmp; FILE *file; struct stat st; @@ -1500,10 +1522,11 @@ int main(int argc, char **argv) add_header(&buf, mod); err |= add_versions(&buf, mod); add_depends(&buf, mod, modules); add_moddevtable(&buf, mod); add_srcversion(&buf, mod); + add_symtab_hash(&buf, mod); sprintf(fname, "%s.mod.c", mod->name); write_if_changed(&buf, fname); } --- linux-2.6.20.orig/sound/Kconfig +++ linux-2.6.20/sound/Kconfig @@ -1,10 +1,44 @@ # sound/Config.in # menu "Sound" +# added for nomadik audio codec device + +config NOMADIK_ACODEC + tristate "Nomadik audio codec generic module (used both by SAA and ALSA)" + depends on ARCH_NOMADIK && NOMADIK_MSP && I2C_NOMADIK + help + Say Y here if you have a nomadik based device + and want to use its audio codec chip. + + To compile this driver as a module, choose M here: the module + will be called nmdkmod_acodec. + +choice + prompt "audio codec type" + depends on NOMADIK_ACODEC + default NOMADIK_STW5095 + +config NOMADIK_STW5094 + bool "Nomadik stw5094 audio codec" + +config NOMADIK_STW5095 + bool "Nomadik stw5095 audio codec" + +endchoice + +#configure audio codec to provide msp clock and frame sync +config DA_MASTER + bool "Set stw5095 clock as bit clock" + depends on NOMADIK_STW5095 +# default y + help + Say Y here if you wish to use the stw5095's audio clock as + the bit clock instead of the less accurate msp clock. + config SOUND tristate "Sound card support" help If you have a sound card in your computer, i.e. if it can say more than an occasional beep, say Y. Be sure to have all the information @@ -34,10 +68,12 @@ config SOUND source "sound/oss/dmasound/Kconfig" if !M68K + + menu "Advanced Linux Sound Architecture" depends on SOUND!=n config SND tristate "Advanced Linux Sound Architecture" --- linux-2.6.20.orig/sound/Makefile +++ linux-2.6.20/sound/Makefile @@ -1,8 +1,9 @@ # Makefile for the Linux sound card driver # +obj-$(CONFIG_NOMADIK_ACODEC) += nmdkmod_acodec.o obj-$(CONFIG_SOUND) += soundcore.o obj-$(CONFIG_SOUND_PRIME) += sound_firmware.o obj-$(CONFIG_SOUND_PRIME) += oss/ obj-$(CONFIG_DMASOUND) += oss/ obj-$(CONFIG_SND) += core/ i2c/ drivers/ isa/ pci/ ppc/ arm/ synth/ usb/ sparc/ parisc/ pcmcia/ mips/ @@ -13,6 +14,14 @@ obj-$(CONFIG_AC97_BUS) += ac97_bus.o ifeq ($(CONFIG_SND),y) obj-y += last.o endif +ifeq ($(CONFIG_NOMADIK_STW5094),y) +nmdkmod_acodec-objs := nomadik_stw5094.o +endif + +ifeq ($(CONFIG_NOMADIK_STW5095),y) +nmdkmod_acodec-objs := nomadik_stw5095.o +endif + soundcore-objs := sound_core.o --- linux-2.6.20.orig/sound/arm/Kconfig +++ linux-2.6.20/sound/arm/Kconfig @@ -1,10 +1,21 @@ # ALSA ARM drivers menu "ALSA ARM devices" depends on SND!=n && ARM +config SND_NOMADIK_ALSA + tristate "Nomadik alsa support" + depends on SND && NOMADIK_DMA && NOMADIK_ACODEC + select SND_PCM + help + Say Y here if you have a nomadik based device + and want to use alsa for pcm playback and capture. + + To compile this driver as a module, choose M here: the module + will be called nmdkmod_alsa. + config SND_SA11XX_UDA1341 tristate "SA11xx UDA1341TS driver (iPaq H3600)" depends on ARCH_SA1100 && SND && L3 select SND_PCM help --- linux-2.6.20.orig/sound/arm/Makefile +++ linux-2.6.20/sound/arm/Makefile @@ -11,5 +11,8 @@ snd-aaci-objs := aaci.o devdma.o obj-$(CONFIG_SND_PXA2XX_PCM) += snd-pxa2xx-pcm.o snd-pxa2xx-pcm-objs := pxa2xx-pcm.o obj-$(CONFIG_SND_PXA2XX_AC97) += snd-pxa2xx-ac97.o snd-pxa2xx-ac97-objs := pxa2xx-ac97.o + +obj-$(CONFIG_SND_NOMADIK_ALSA) += nmdkmod_alsa.o +nmdkmod_alsa-objs := nomadik_alsa.o devdma.o --- /dev/null +++ linux-2.6.20/sound/arm/nomadik_alsa.c @@ -0,0 +1,1038 @@ +/* sound/arm/nomadik_alsa.c + * + * Contains alsa driver for noamdik + * Author: David Siorpaes, Emanele Placidi, Abhijit Singh + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +/* This include must be defined at this point */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* alsa system */ +#include +#include +#include +#include +#include +#include "nomadik_alsa.h" +#include "devdma.h" +#include + +static struct platform_device *device; +static int active_user = 0; + +static int configure_rate(snd_pcm_substream_t * substream) +{ + nomadik_acodec_chip_t *chip = snd_pcm_substream_chip(substream); + t_codec_sample_frequency sampling_frequency = 0; + t_codec_direction direction = 0; + int stream_id = substream->pstr->stream; + + switch (chip->freq) { + case 8000: + sampling_frequency = CODEC_SAMPLING_FREQ_8KHZ; + break; + case 11000: + sampling_frequency = CODEC_SAMPLING_FREQ_11KHZ; + break; + case 12000: + sampling_frequency = CODEC_SAMPLING_FREQ_12KHZ; + break; + case 16000: + sampling_frequency = CODEC_SAMPLING_FREQ_16KHZ; + break; + case 22000: + case 22050: + sampling_frequency = CODEC_SAMPLING_FREQ_22KHZ; + break; + case 24000: + sampling_frequency = CODEC_SAMPLING_FREQ_24KHZ; + break; + case 32000: + sampling_frequency = CODEC_SAMPLING_FREQ_32KHZ; + break; + case 44000: + case 44100: + sampling_frequency = CODEC_SAMPLING_FREQ_44KHZ; + break; + case 48000: + sampling_frequency = CODEC_SAMPLING_FREQ_48KHZ; + break; + case 64000: + sampling_frequency = CODEC_SAMPLING_FREQ_64KHZ; + break; + case 96000: + sampling_frequency = CODEC_SAMPLING_FREQ_96KHZ; + break; + default: + printk("ALSA:not supported frequnecy\n"); + return -EINVAL; + } + + switch (stream_id) { + case SNDRV_PCM_STREAM_PLAYBACK: + direction = CODEC_DIRECTION_OUT; + break; + case SNDRV_PCM_STREAM_CAPTURE: + direction = CODEC_DIRECTION_IN; + break; + default: + printk("ALSA DRV: wrong pcm stream\n"); + return -EINVAL; + } + + if ((sampling_frequency == CODEC_SAMPLING_FREQ_8KHZ) + || (sampling_frequency == CODEC_SAMPLING_FREQ_16KHZ)) { + DEBUG(7, "abs: enabling audiocodec voice mode\n"); + nomadik_acodec_enable_voice_mode(direction, sampling_frequency, + sampling_frequency, + CODEC_MSP_APB_CLOCK, + CODEC_MSP_INPUT_FREQ_48MHZ, MSP_USER_ALSA); + } else { + DEBUG(7, "abs: enabling audiocodec audio mode\n"); + nomadik_acodec_enable_audio_mode(direction, sampling_frequency, + sampling_frequency, + CODEC_MSP_APB_CLOCK, + CODEC_MSP_INPUT_FREQ_48MHZ, MSP_USER_ALSA); + } + + return 0; +} + +static int configure_dmadev_acodec(snd_pcm_substream_t * substream) +{ + int stream_id = substream->pstr->stream; + nomadik_acodec_chip_t *nomadik_chip = snd_pcm_substream_chip(substream); + struct nmdk_dma_info * alsa_dma_info = (struct nmdk_dma_info * ) + &(nomadik_chip->s[stream_id].pipe_params); + + if (nomadik_chip->s[stream_id].pipeId != -1) { + while(dma_channel_active(nomadik_chip->s[stream_id].pipeId)); + free_dma(nomadik_chip->s[stream_id].pipeId); + } +#if 0 + { + /* exit sucessfully if called through prepare for DMA_WIDTH_HALFWORD and + * it is already configured*/ + if ((nomadik_chip->channels == 1) && + (nomadik_chip->s[stream_id].pipe_params.config == DMA_WIDTH_HALFWORD)) + return 0; + /* exit sucessfully if called through prepare for DMA_WIDTH_WORD and + * it is already configured*/ + if ((nomadik_chip->channels == 1) && + (nomadik_chip->s[stream_id].pipe_params.config == DMA_WIDTH_WORD)) + return 0; + /* check and wait for current dma to finish if in progress*/ + } +#endif + /* configure and allocate a DMA pipe for requested operation(TX or RX)*/ + switch (stream_id) { + case SNDRV_PCM_STREAM_PLAYBACK: + alsa_dma_info->srcdevtype = "mem"; + alsa_dma_info->destdevtype = "msp0tx"; + alsa_dma_info->mode = DMA_QUEUE_ENABLED | FLOW_CNTRL_DMA(MEM_TO_PERIPH); + alsa_dma_info->config = DMA_DEVCONFIG_DEST( + DMA_DEVCONFIG_WIDTH((nomadik_chip->channels == 1) ? + DMA_WIDTH_HALFWORD : DMA_WIDTH_WORD) | + DMA_DEVCONFIG_BSIZE(DMA_BSIZE_1) + ); + break; + case SNDRV_PCM_STREAM_CAPTURE: + alsa_dma_info->srcdevtype = "msp0rx"; + alsa_dma_info->destdevtype = "mem"; + alsa_dma_info->mode = DMA_QUEUE_ENABLED | FLOW_CNTRL_DMA(PERIPH_TO_MEM); + alsa_dma_info->config = DMA_DEVCONFIG_SRC( + DMA_DEVCONFIG_WIDTH((nomadik_chip->channels == 1) ? + DMA_WIDTH_HALFWORD : DMA_WIDTH_WORD) | + DMA_DEVCONFIG_BSIZE(DMA_BSIZE_1) + ); + break; + } + alsa_dma_info->mode |= DMA_EXCH_PRIORITY_NORMAL; + + /* find and request free dma chanel */ + nomadik_chip->s[stream_id].pipeId = request_available_dma(alsa_dma_info); + /* + * Register the callback function + * free_irq will be called by dma layer from the context of free_dma() + */ + request_irq(IRQNO_FOR_DMACH(nomadik_chip->s[stream_id].pipeId), dma_eot_handler, + 0, 0, (void *)&nomadik_chip->s[stream_id]); + + DEBUG(7, "ALSA DRV: pipe: %i configured:\n", + (int)nomadik_chip->s[stream_id].pipeId); + + return 0; +} + +static int vol_p_info(snd_kcontrol_t * kcontrol, snd_ctl_elem_info_t * uinfo) +{ + uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; + uinfo->count = 2; + uinfo->value.integer.min = 0; + uinfo->value.integer.max = 100; + uinfo->value.integer.step = 10; + return 0; +} + +static int vol_p_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * uinfo) +{ + nomadik_acodec_chip_t *chip = + (nomadik_acodec_chip_t *) snd_kcontrol_chip(kcontrol); + uinfo->value.integer.value[0] = chip->output_lvolume; + uinfo->value.integer.value[1] = chip->output_rvolume; + return 0; +} + +static int vol_p_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * uinfo) +{ + nomadik_acodec_chip_t *chip = + (nomadik_acodec_chip_t *) snd_kcontrol_chip(kcontrol); + int changed = 0, error = 0; + + if (chip->output_lvolume != uinfo->value.integer.value[0] + || chip->output_rvolume != uinfo->value.integer.value[1]) { + chip->output_lvolume = uinfo->value.integer.value[0]; + chip->output_rvolume = uinfo->value.integer.value[1]; + + if(chip->output_lvolume > 100) + chip->output_lvolume = 100; + else if(chip->output_lvolume < 0) + chip->output_lvolume = 0; + + if(chip->output_rvolume > 100) + chip->output_rvolume = 100; + else if(chip->output_rvolume < 0) + chip->output_rvolume = 0; + + + error = nomadik_acodec_set_volume(chip->input_lvolume, + chip->input_rvolume, + chip->output_lvolume, + chip->output_rvolume, USER_ALSA); + if (error) { + printk("ALSA: ERROR: set volume for speaker/headphone failed\n"); + return changed; + } + changed = 1; + } + + return changed; +} + +static int vol_c_info(snd_kcontrol_t * kcontrol, snd_ctl_elem_info_t * uinfo) +{ + uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; + uinfo->count = 1; + uinfo->value.integer.min = 0; + uinfo->value.integer.max = 100; + uinfo->value.integer.step = 10; + return 0; +} + +static int vol_c_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * uinfo) +{ + nomadik_acodec_chip_t *chip = + (nomadik_acodec_chip_t *) snd_kcontrol_chip(kcontrol); + uinfo->value.integer.value[0] = chip->input_lvolume; + uinfo->value.integer.value[1] = chip->input_rvolume; + return 0; +} + +static int vol_c_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * uinfo) +{ + nomadik_acodec_chip_t *chip = + (nomadik_acodec_chip_t *) snd_kcontrol_chip(kcontrol); + int changed = 0, error = 0; + + if (chip->input_lvolume != uinfo->value.integer.value[0] + || chip->input_rvolume != uinfo->value.integer.value[1]) { + chip->input_lvolume = uinfo->value.integer.value[0]; + chip->input_rvolume = uinfo->value.integer.value[1]; + + if(chip->input_lvolume > 100) + chip->input_lvolume = 100; + else if(chip->input_lvolume < 0) + chip->input_lvolume = 0; + + if(chip->input_rvolume > 100) + chip->input_rvolume = 100; + else if(chip->input_rvolume < 0) + chip->input_rvolume = 0; + + error = nomadik_acodec_set_volume(chip->input_lvolume, + chip->input_rvolume, + chip->output_lvolume, + chip->output_rvolume, USER_ALSA); + if (error) { + printk("ALSA: ERROR: set volume for mic failed\n"); + return changed; + } + changed = 1; + } + + return changed; +} + +snd_kcontrol_new_t vol_p_nomadik_control = { + .iface = SNDRV_CTL_ELEM_IFACE_PCM, + .device = 0, + .subdevice = 0, + .name = "PCM Playback Volume", + .index = 0, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .private_value = 0xfff, + .info = vol_p_info, + .get = vol_p_get, + .put = vol_p_put +}; + +snd_kcontrol_new_t vol_c_nomadik_control = { + .iface = SNDRV_CTL_ELEM_IFACE_PCM, + .device = 0, + .subdevice = 1, + .name = "PCM Capture Volume", + .index = 0, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .private_value = 0xfff, + .info = vol_c_info, + .get = vol_c_get, + .put = vol_c_put +}; + +static int swt_p_info(snd_kcontrol_t * kcontrol, snd_ctl_elem_info_t * uinfo) +{ + static char *texts[4] = { + "CODEC_DEST_LOUDSPEAKER", "CODEC_DEST_EARPIECE", "CODEC_DEST_HEADPHONE", "CODEC_DEST_LINEOUT" + }; + uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; + uinfo->value.enumerated.items = 4; + if (uinfo->value.enumerated.item > 3) + uinfo->value.enumerated.item = 2; /*CODEC_DEST_HEADPHONE - Default*/ + strcpy(uinfo->value.enumerated.name, + texts[uinfo->value.enumerated.item]); + return 0; +} + +static int swt_p_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * uinfo) +{ + nomadik_acodec_chip_t *chip = + (nomadik_acodec_chip_t *) snd_kcontrol_chip(kcontrol); + uinfo->value.enumerated.item[0] = chip->output_device; + return 0; +} + +static int swt_p_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * uinfo) +{ + nomadik_acodec_chip_t *chip = + (nomadik_acodec_chip_t *) snd_kcontrol_chip(kcontrol); + int changed = 0, error; + + if (chip->output_device != uinfo->value.enumerated.item[0]) { + chip->output_device = uinfo->value.enumerated.item[0]; + error = nomadik_acodec_select_output(chip->output_device, USER_ALSA); + if (error) { + printk("ALSA: ERROR: select output failed\n"); + return changed; + } + changed = 1; + } + return changed; +} + +static int swt_c_info(snd_kcontrol_t * kcontrol, snd_ctl_elem_info_t * uinfo) +{ + static char *texts[3] = { + "CODEC_SOURCE_NONE", "CODEC_SOURCE_LINEIN", "CODEC_SOURCE_MICROPHONE" + }; + uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; + uinfo->value.enumerated.items = 3; + if (uinfo->value.enumerated.item > 2) + uinfo->value.enumerated.item = 2; /*CODEC_SOURCE_MICROPHONE - Default*/ + strcpy(uinfo->value.enumerated.name, + texts[uinfo->value.enumerated.item]); + return 0; +} + +static int swt_c_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * uinfo) +{ + nomadik_acodec_chip_t *chip = + (nomadik_acodec_chip_t *) snd_kcontrol_chip(kcontrol); + uinfo->value.enumerated.item[0] = chip->input_device; + return 0; +} + +static int swt_c_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * uinfo) +{ + nomadik_acodec_chip_t *chip = + (nomadik_acodec_chip_t *) snd_kcontrol_chip(kcontrol); + int changed = 0, error; + + if (chip->input_device != uinfo->value.enumerated.item[0]) { + chip->input_device = uinfo->value.enumerated.item[0]; + error = nomadik_acodec_select_input(chip->input_device, USER_ALSA); + if (error) { + printk("ALSA: ERROR: select input failed\n"); + return changed; + } + changed = 1; + } + return changed; +} + +static snd_kcontrol_new_t swt_p_nomadik_control = { + .iface = SNDRV_CTL_ELEM_IFACE_PCM, + .device = 0, + .subdevice = 0, + .name = "PCM Playback Source", + .index = 0, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .private_value = 0xffff, + .info = swt_p_info, + .get = swt_p_get, + .put = swt_p_put +}; + +static snd_kcontrol_new_t swt_c_nomadik_control = { + .iface = SNDRV_CTL_ELEM_IFACE_PCM, + .device = 0, + .subdevice = 1, + .name = "PCM Capture Source", + .index = 0, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .private_value = 0xffff, + .info = swt_c_info, + .get = swt_c_get, + .put = swt_c_put +}; + +/* Hardware description , this structure (snd_pcm_hardware_t ) + * contains the definitions of the fundamental hardware configuration. + * This configuration will be applied on the runtime structure + */ +static snd_pcm_hardware_t snd_nomadik_playback_hw = { + .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_RESUME | SNDRV_PCM_INFO_PAUSE), + .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_U16_LE | + SNDRV_PCM_FMTBIT_S16_BE | SNDRV_PCM_FMTBIT_U16_BE, + .rates = SNDRV_PCM_RATE_KNOT, + .rate_min = MIN_RATE_PLAYBACK, + .rate_max = MAX_RATE_PLAYBACK, + .channels_min = 1, + .channels_max = 2, + .buffer_bytes_max = NMDK_BUFFER_SIZE, + .period_bytes_min = 128, + .period_bytes_max = 512, + .periods_min = NMDK_BUFFER_SIZE / 512, + .periods_max = NMDK_BUFFER_SIZE / 128 +}; + +static snd_pcm_hardware_t snd_nomadik_capture_hw = { + .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_RESUME | SNDRV_PCM_INFO_PAUSE), + .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_U16_LE | + SNDRV_PCM_FMTBIT_S16_BE | SNDRV_PCM_FMTBIT_U16_BE, + .rates = SNDRV_PCM_RATE_KNOT, + .rate_min = MIN_RATE_CAPTURE, + .rate_max = MAX_RATE_CAPTURE, + .channels_min = 1, + .channels_max = 2, + .buffer_bytes_max = NMDK_BUFFER_SIZE, + .period_bytes_min = 128, + .period_bytes_max = 512, + .periods_min = NMDK_BUFFER_SIZE / 512, + .periods_max = NMDK_BUFFER_SIZE / 128 +}; + +static snd_pcm_hw_constraint_list_t constraints_rate = { + .count = sizeof(nmdk_acodec_rates) / sizeof(nmdk_acodec_rates[0]), + .list = nmdk_acodec_rates, + .mask = 0, +}; + +/** + * snd_nomadik_alsa_pcm_close + * @substream - pointer to the playback/capture substream structure + * + * This routine is used by alsa framework to close a pcm stream . + * Here a dma pipe is disabled and freed. + */ +static int snd_nomadik_alsa_pcm_close(snd_pcm_substream_t * substream) +{ + int stream_id, error = 0; + nomadik_acodec_chip_t *chip = snd_pcm_substream_chip(substream); + + DEBUG(7, "ALSA DRV: in %s\n", __func__); + + stream_id = substream->pstr->stream; + while(dma_channel_active(chip->s[stream_id].pipeId)); + if (chip->s[stream_id].active == 1) + disable_dma(chip->s[stream_id].pipeId); + free_dma(chip->s[stream_id].pipeId); + + /* Disable the MSP0 */ + nomadik_msp_disable(0, MSP_BOTH_T_R_MODE, MSP_USER_ALSA); + + DEBUG(7, "ALSA DRV: pipe: %i closed:\n", + (int)chip->s[stream_id].pipeId); + + /* reset the different variables to default */ + chip->s[stream_id].pipeId = -1; + chip->s[stream_id].active = 0; + chip->s[stream_id].period = 0; + chip->s[stream_id].periods = 0; + chip->s[stream_id].old_offset = 0; + chip->s[stream_id].substream = NULL; + + if(!(--active_user)) + error = nomadik_acodec_unsetuser(USER_ALSA); + + return error; + +} + +/** + * snd_nomadik_alsa_pcm_open + * @substream - pointer to the playback/capture substream structure + * + * This routine is used by alsa framework to open a pcm stream . + * Here a dma pipe is requested and device is configured(default). + */ +static int snd_nomadik_alsa_pcm_open(snd_pcm_substream_t * substream) +{ + int error = 0, stream_id; + nomadik_acodec_chip_t *chip = snd_pcm_substream_chip(substream); + snd_pcm_runtime_t *runtime = substream->runtime; + + DEBUG(7, "ALSA DRV: in %s\n", __func__); + + if(!active_user) + error = nomadik_acodec_setuser(USER_ALSA); + if(error) + return error; + else + active_user++; + + error = + snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, + &constraints_rate); + if (error < 0) { + printk + ("ALSA DRV: error initializing hw sample rate constraint\n"); + return error; + } + + /* configure the default sampling rate for the acodec */ + if ((error = configure_rate(substream))) + return error; + + /* configure the volume settings for the acodec */ + if((error = nomadik_acodec_set_volume(chip->input_lvolume, + chip->input_rvolume, + chip->output_lvolume, + chip->output_rvolume, USER_ALSA))) { + printk("ALSA: ERROR: set volume failed\n"); + return error; + } + + /* Set the hardware configuration */ + stream_id = substream->pstr->stream; + if (stream_id == SNDRV_PCM_STREAM_PLAYBACK) { + runtime->hw = snd_nomadik_playback_hw; + /* configure the output sink for the acodec */ + if ((error = nomadik_acodec_select_output(chip->output_device, USER_ALSA))) { + printk("ALSA: ERROR: select output failed\n"); + return error; + } + } else { + runtime->hw = snd_nomadik_capture_hw; + /* configure the input source for the acodec */ + if ((error = nomadik_acodec_select_input(chip->input_device, USER_ALSA))) { + printk("ALSA: ERROR: select input failed\n"); + return error; + } + } + + chip->s[stream_id].substream = substream; + if (chip->s[stream_id].pipeId == -1) { + /* checks, allocates configures dmach */ + if ((error = configure_dmadev_acodec(substream))) + return error; + } + + DEBUG(7, "ALSA DRV: pipe: %i open:\n", + (int)chip->s[stream_id].pipeId); + + return 0; +} + +/** + * snd_nomadik_alsa_pcm_hw_params + * @substream - pointer to the playback/capture substream structure + * @hw_params - specifies the hw parameters like format/no of channels etc + * + * This routine is used by alsa framework to allocate a dma buffer + * used to transfer the data from user space to kernel space + * + */ +static int snd_nomadik_alsa_pcm_hw_params(snd_pcm_substream_t * substream, + snd_pcm_hw_params_t * hw_params) +{ + return devdma_hw_alloc(NULL, substream, params_buffer_bytes(hw_params)); +} + +/** + * snd_nomadik_alsa_pcm_hw_free + * @substream - pointer to the playback/capture substream structure + * + * This routine is used by alsa framework to deallocate a dma buffer + * allocated berfore by snd_nomadik_alsa_pcm_hw_params + */ +static int snd_nomadik_alsa_pcm_hw_free(snd_pcm_substream_t * substream) +{ + devdma_hw_free(NULL, substream); + return 0; +} + +/** + * snd_nomadik_alsa_pcm_prepare + * @substream - pointer to the playback/capture substream structure + * + * This callback is called whene the pcm is "prepared" Here is possible + * to set the format type ,sample rate ,etc.The callback is called as + * well everytime a recovery after an underrun happens. + */ +static int snd_nomadik_alsa_pcm_prepare(snd_pcm_substream_t * substream) +{ + nomadik_acodec_chip_t *chip = snd_pcm_substream_chip(substream); + snd_pcm_runtime_t *runtime = substream->runtime; + int error; + + DEBUG(7, "ALSA DRV: in %s\n", __func__); + + if (chip->freq != runtime->rate) { + DEBUG(7, "ALSA DRV: freq not same, %d %d\n", chip->freq, + runtime->rate); + chip->freq = runtime->rate; + if ((error = configure_rate(substream))) + return error; + } + + if (chip->channels != runtime->channels) { + DEBUG(7, "ALSA DRV: channels not same, %d %d\n", chip->channels, + runtime->channels); + chip->channels = runtime->channels; + if ((error = configure_dmadev_acodec(substream))) + return error; + } + + return 0; +} + +/** + * snd_nomadik_alsa_pcm_trigger + * @substream - pointer to the playback/capture substream structure + * @cmd - specifies the command : start/stop/pause/resume + * + * This callback is called whene the pcm is started ,stopped or paused + * The action is specified in the second argument, SND_PCM_TRIGGER_XXX in + * . + * This callback is atomic and the interrupts are disabled , so you can't + * call other functions that need interrupts without possible risks + */ +static int snd_nomadik_alsa_pcm_trigger(snd_pcm_substream_t * substream, + int cmd) +{ + int stream_id = substream->pstr->stream; + audio_stream_t *stream = NULL; + nomadik_acodec_chip_t *chip = snd_pcm_substream_chip(substream); + int error = 0; + + DEBUG(7, "ALSA DRV: in %s\n", __func__); + + stream = &chip->s[stream_id]; + + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: + /* Start the pcm engine */ + DEBUG(7, "ALSA DRV: TRIGGER START\n"); + if (stream->active == 0) { + stream->active = 1; + nomadik_alsa_dma_start(stream); + break; + } + printk("ALSA DRV: H/w is busy\n"); + return -EINVAL; + + case SNDRV_PCM_TRIGGER_PAUSE_PUSH: + DEBUG(7, "ALSA DRV: SNDRV_PCM_TRIGGER_PAUSE_PUSH\n"); + if (stream->active == 1) { + suspend_dma(stream->pipeId); + } + break; + case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: + DEBUG(7, "ALSA DRV: SNDRV_PCM_TRIGGER_PAUSE_RELEASE\n"); + if (stream->active == 1) { + resume_dma(stream->pipeId); + } + break; + case SNDRV_PCM_TRIGGER_STOP: + /* Stop the pcm engine */ + DEBUG(7, "ALSA DRV: TRIGGER STOP\n"); + if (stream->active == 1) { + disable_dma(stream->pipeId); /*Vaibhav - Can be modified for error handling*/ + stream->active = 0; + stream->period = 0; + } + break; + default: + printk("ALSA DRV: invalid command in pcm trigger\n"); + return -EINVAL; + } + return error; +} + +/** + * snd_nomadik_alsa_pcm_pointer + * @substream - pointer to the playback/capture substream structure + * + * This callback is called whene the pcm middle layer inquires the current + * hardware position on the buffer .The position is returned in frames + * ranged from 0 to buffer_size -1 + */ +static snd_pcm_uframes_t snd_nomadik_alsa_pcm_pointer(snd_pcm_substream_t * + substream) +{ + unsigned int offset; + nomadik_acodec_chip_t *chip = snd_pcm_substream_chip(substream); + audio_stream_t *stream = &chip->s[substream->pstr->stream]; + snd_pcm_runtime_t *runtime = stream->substream->runtime; + + DEBUG(7, "ALSA DRV: in %s\n", __func__); + + offset = bytes_to_frames(runtime, stream->old_offset); + if (offset < 0 || stream->old_offset < 0) + DEBUG(7, "ALSA DRV: Offset=%i %i\n", offset, + stream->old_offset); + + return offset; +} + +static int snd_nomadik_alsa_pcm_mmap(struct snd_pcm_substream *substream, + struct vm_area_struct *vma) +{ + return devdma_mmap(NULL, substream, vma); +} + +static snd_pcm_ops_t snd_nomadik_alsa_playback_ops = { + .open = snd_nomadik_alsa_pcm_open, + .close = snd_nomadik_alsa_pcm_close, + .ioctl = snd_pcm_lib_ioctl, + .hw_params = snd_nomadik_alsa_pcm_hw_params, + .hw_free = snd_nomadik_alsa_pcm_hw_free, + .prepare = snd_nomadik_alsa_pcm_prepare, + .trigger = snd_nomadik_alsa_pcm_trigger, + .pointer = snd_nomadik_alsa_pcm_pointer, + .mmap = snd_nomadik_alsa_pcm_mmap, +}; + +static snd_pcm_ops_t snd_nomadik_alsa_capture_ops = { + .open = snd_nomadik_alsa_pcm_open, + .close = snd_nomadik_alsa_pcm_close, + .ioctl = snd_pcm_lib_ioctl, + .hw_params = snd_nomadik_alsa_pcm_hw_params, + .hw_free = snd_nomadik_alsa_pcm_hw_free, + .prepare = snd_nomadik_alsa_pcm_prepare, + .trigger = snd_nomadik_alsa_pcm_trigger, + .pointer = snd_nomadik_alsa_pcm_pointer, + .mmap = snd_nomadik_alsa_pcm_mmap, +}; + +/** + * dma_eot_handler + * @data - pointer to structure set in the dma callback handler + * @event - specifies the DMA event: transfer complete/error + * + * This is the PCM tasklet handler linked to a pipe, its role is to tell + * the PCM middler layer whene the buffer position goes across the prescribed + * period size.To inform of this the snd_pcm_period_elapsed is called. + * + * this callback will be called in case of DMA_EVENT_TC only + */ +static irqreturn_t dma_eot_handler(int irq, void *data) +{ + audio_stream_t *stream = data; + + /* snd_pcm_period_elapsed() is _not_ to be protected + */ + DEBUG(7, + "ALSA DRV: One transfer complete.. going to start the next one\n"); + snd_pcm_period_elapsed(stream->substream); + + if (stream->active == 1) { + nomadik_alsa_dma_start(stream); + } + return IRQ_HANDLED; +} + +/** + * nomadik_alsa_dma_start - used to transmit or recive a dma chunk + * @stream - specifies the playback/record stream structure + */ +static void nomadik_alsa_dma_start(audio_stream_t * stream) +{ + unsigned int offset, dma_size, stream_id; + + snd_pcm_substream_t *substream = stream->substream; + snd_pcm_runtime_t *runtime = substream->runtime; + stream_id = substream->pstr->stream; + + if (stream->active) { + dma_size = frames_to_bytes(runtime, runtime->period_size); + offset = dma_size * stream->period; + stream->old_offset = offset; + + if (stream_id == SNDRV_PCM_STREAM_PLAYBACK) { + __set_dma_srcaddr(stream->pipeId, + (dma_addr_t) (runtime->dma_addr + offset)); + __set_dma_destaddr(stream->pipeId, + (dma_addr_t *)NOMADIK_MSP0_BASE); + } else { + __set_dma_destaddr(stream->pipeId, + (dma_addr_t) (runtime->dma_addr + offset)); + __set_dma_srcaddr(stream->pipeId, + (dma_addr_t *)NOMADIK_MSP0_BASE); + } + set_dma_count(stream->pipeId, dma_size); + + DEBUG(7, "ALSA DRV: DMA Transfer started\n"); + DEBUG(7, "ALSA DRV: address = %x size=%d\n", + (runtime->dma_addr + offset), dma_size); + + while(dma_channel_active(stream->pipeId)); + enable_dma(stream->pipeId); + + stream->period++; + stream->period %= runtime->periods; + stream->periods++; + } +} + +static void nomadik_audio_init(nomadik_acodec_chip_t * chip) +{ + /* Setup DMA stuff */ + chip->s[SNDRV_PCM_STREAM_PLAYBACK].id = "nomadik playback"; + chip->s[SNDRV_PCM_STREAM_PLAYBACK].stream_id = + SNDRV_PCM_STREAM_PLAYBACK; + + /* default initialization for playback */ + chip->s[SNDRV_PCM_STREAM_PLAYBACK].pipeId = -1; + chip->s[SNDRV_PCM_STREAM_PLAYBACK].active = 0; + chip->s[SNDRV_PCM_STREAM_PLAYBACK].period = 0; + chip->s[SNDRV_PCM_STREAM_PLAYBACK].periods = 0; + chip->s[SNDRV_PCM_STREAM_PLAYBACK].old_offset = 0; + + chip->s[SNDRV_PCM_STREAM_CAPTURE].id = "nomadik capture"; + chip->s[SNDRV_PCM_STREAM_CAPTURE].stream_id = SNDRV_PCM_STREAM_CAPTURE; + + /* default initialization for capture */ + chip->s[SNDRV_PCM_STREAM_CAPTURE].pipeId = -1; + chip->s[SNDRV_PCM_STREAM_CAPTURE].active = 0; + chip->s[SNDRV_PCM_STREAM_CAPTURE].period = 0; + chip->s[SNDRV_PCM_STREAM_CAPTURE].periods = 0; + chip->s[SNDRV_PCM_STREAM_CAPTURE].old_offset = 0; + + chip->freq = DEFAULT_SAMPLE_RATE; + chip->channels = 1; + chip->input_lvolume = DEFAULT_GAIN; + chip->input_rvolume = DEFAULT_GAIN; + chip->output_lvolume = DEFAULT_VOLUME; + chip->output_rvolume = DEFAULT_VOLUME; + chip->output_device = DEFAULT_OUTPUT_DEVICE; + chip->input_device = DEFAULT_INPUT_DEVICE; +} + +/** + * snd_card_nomadik_alsa_pcm_new - constructor for a new pcm cmponent + * @chip - pointer to chip specific data + * @device - specifies the card number + */ +static int snd_card_nomadik_alsa_pcm_new(nomadik_acodec_chip_t * chip, + int device) +{ + snd_pcm_t *pcm; + int err; + + DEBUG(7, "ALSA DRV: in %s\n", __func__); + + if ((err = snd_pcm_new(chip->card, "nomadik", device, 1, 1, &pcm)) < 0) { + printk("ALSA DRV: error in snd_pcm_new\n"); + return err; + } + + snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, + &snd_nomadik_alsa_playback_ops); + snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, + &snd_nomadik_alsa_capture_ops); + + pcm->private_data = chip; + pcm->info_flags = 0; + chip->pcm = pcm; + strcpy(pcm->name, "nomadik_alsa"); + + nomadik_audio_init(pcm->private_data); + return 0; +} + +static int __init nomadik_alsa_probe(struct platform_device *devptr) +{ + int error; + snd_card_t *card; + nomadik_acodec_chip_t *nomadik_chip; + + /*Set currently active users to 0*/ + active_user = 0; + + card = + snd_card_new(-1, NULL, THIS_MODULE, sizeof(nomadik_acodec_chip_t)); + if (card == NULL) { + printk("ALSA DRV: error in snd_card_new\n"); + return -ENOMEM; + } + + nomadik_chip = (nomadik_acodec_chip_t *) card->private_data; + nomadik_chip->card = card; + + if ((error = snd_card_nomadik_alsa_pcm_new(nomadik_chip, 0)) < 0) { + printk("ALSA DRV: pcm interface can't be initialized\n\n"); + goto nodev; + } + + if ((error = + snd_ctl_add(card, + snd_ctl_new1(&vol_p_nomadik_control, + nomadik_chip))) < 0) { + printk + ("ALSA DRV: error initializing playback volume ctrl interface \n\n"); + goto nodev; + } + + if ((error = + snd_ctl_add(card, + snd_ctl_new1(&vol_c_nomadik_control, + nomadik_chip))) < 0) { + printk + ("ALSA DRV: error initializing capture volume ctrl interface \n\n"); + goto nodev; + } + + if ((error = + snd_ctl_add(card, + snd_ctl_new1(&swt_p_nomadik_control, + nomadik_chip))) < 0) { + printk + ("ALSA DRV: error initializing playback ctrl interface \n\n"); + goto nodev; + } + + if ((error = + snd_ctl_add(card, + snd_ctl_new1(&swt_c_nomadik_control, + nomadik_chip))) < 0) { + printk + ("ALSA DRV: error initializing capture ctrl interface \n\n"); + goto nodev; + } + + strcpy(card->driver, "nomadik_alsa"); + strcpy(card->shortname, "nomadik_alsa driver"); + sprintf(card->longname, "nomadik alsa driver"); + + snd_card_set_dev(card, &devptr->dev); + + if ((error = snd_card_register(card)) == 0) { + printk(KERN_INFO "nomadik audio support running..\n"); + platform_set_drvdata(devptr, card); + return 0; + } + + nodev: + snd_card_free(card); + return error; +} + +static int __devexit noamdik_alsa_remove(struct platform_device *devptr) +{ + snd_card_free(platform_get_drvdata(devptr)); + platform_set_drvdata(devptr, NULL); + printk(KERN_INFO "nomadik audio support stopped\n"); + + /*Set currently active users to 0*/ + active_user = 0; + + return 0; +} + +static struct platform_driver noamdik_alsa_driver = { + .probe = nomadik_alsa_probe, + .remove = __devexit_p(noamdik_alsa_remove), + .driver = { + .name = NOMADIK_ALSA_DRIVER, + }, +}; + +static int __init nomadik_alsa_init(void) +{ + int err; + + if ((err = platform_driver_register(&noamdik_alsa_driver)) < 0) + return err; + device = + platform_device_register_simple(NOMADIK_ALSA_DRIVER, -1, NULL, 0); + if (IS_ERR(device)) { + platform_driver_unregister(&noamdik_alsa_driver); + return PTR_ERR(device); + } + return 0; +} + +static void __exit nomadik_alsa_exit(void) +{ + platform_device_unregister(device); + platform_driver_unregister(&noamdik_alsa_driver); +} + +module_init(nomadik_alsa_init); +module_exit(nomadik_alsa_exit); + +MODULE_AUTHOR("David Siorpaes, Emanele Placidi, Abhijit Singh"); +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Nomadik ALSA driver"); --- /dev/null +++ linux-2.6.20/sound/arm/nomadik_alsa.h @@ -0,0 +1,83 @@ +/* sound/arm/nomadik_alsa.c + * + * Header file for nomadik alsa driver + * Author: David Siorpaes, Emanele Placidi, Abhijit Singh + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifndef _NOMADIK_ALSA_H_ +#define _NOMADIK_ALSA_H_ + +#include +#include + +#define DEFAULT_SAMPLE_RATE 8000 +#define NMDK_BUFFER_SIZE (8*1024) +#define NOMADIK_ALSA_DRIVER "nomadik_alsa" + +/* Debugging stuff */ +#ifndef CONFIG_DEBUG_USER +#define DEBUG_LEVEL 0 +#else +#define DEBUG_LEVEL 10 +#endif + +#if DEBUG_LEVEL > 0 +static int nomadik_acodec_debug = DEBUG_LEVEL; +#define DEBUG(n, args...) do { if (nomadik_acodec_debug>(n)) printk(args); } while (0) +#else +#define DEBUG(n, args...) do { } while (0) +#endif + +/* audio stream definition */ +typedef struct audio_stream_s { + char *id; /* module identifier string */ + int stream_id; /* stream identifier */ + int status; + int active; /* we are using this stream for transfer now */ + int period; /* current transfer period */ + int periods; /* current count of periods registerd in the DMA engine */ + unsigned int old_offset; + snd_pcm_substream_t *substream; + dmach_t pipeId; + unsigned int exchId; + struct nmdk_dma_info pipe_params; + snd_pcm_uframes_t played_frame; +} audio_stream_t; + +/* chip structure definition */ +typedef struct nomadik_acodec_s { + snd_card_t *card; + snd_pcm_t *pcm; + unsigned int freq; + unsigned int channels; + unsigned int input_lvolume; + unsigned int input_rvolume; + unsigned int output_lvolume; + unsigned int output_rvolume; + t_codec_input_select input_device; + t_codec_output_select output_device; + audio_stream_t s[2]; /* playback & capture */ +} nomadik_acodec_chip_t; + +static int configure_rate(snd_pcm_substream_t *); +static int configure_dmadev_acodec(snd_pcm_substream_t * substream); +static irqreturn_t dma_eot_handler(int irq, void *data); +static void nomadik_alsa_dma_start(audio_stream_t * stream); + + +#endif --- /dev/null +++ linux-2.6.20/sound/nomadik_stw5094.c @@ -0,0 +1,2280 @@ +/* sound/nomadik_stw5094.c + * + * Contains STW5094 AudioCodec implementation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +/*----------------------------------------------------------------------------- + * Common Includes + *---------------------------------------------------------------------------*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#define ELEMENT_SIZE 0 +#define FRAME_SIZE -1 +#define MSP_NUM 0 + +/* Debugging stuff */ +#ifndef CONFIG_DEBUG_USER +#define DEBUG_LEVEL 0 +#else +#define DEBUG_LEVEL 10 +#endif + +#if DEBUG_LEVEL > 0 +static int audiocodec_debug = DEBUG_LEVEL; +#define DEBUG(n, args...) do { if (audiocodec_debug>(n)) printk(args); } while (0) +#else +#define DEBUG(n, args...) do { } while (0) +#endif +#define TRACE_ENTER(devname) DEBUG(4, "%s: -> " __FUNCTION__ "()\n", devname); +#define TRACE_EXIT(devname) DEBUG(4, "%s: <- " __FUNCTION__ "()\n", devname); + +/*---------------------------------------------------------------------------- + * global declarations + *---------------------------------------------------------------------------*/ + +codec_configuration *nomadik_acodec_conf, *nomadik_acodec_defaultconf; + +static t_acodec_user g_cur_user = NO_USER; +int nmdk_acodec_rates[] = + { 8000, 11000, 12000, 16000, 22000, 24000, 32000, 44000, 44100, 48000, + 64000 +}; + +/** + * nomadik_acodec_set_user + * + * Set the current user for acodec. + */ + +t_codec_error nomadik_acodec_setuser(t_acodec_user user) +{ + t_codec_error codec_error = CODEC_OK; + + if((g_cur_user == NO_USER) || (g_cur_user == user)) + g_cur_user = user; + else { + printk + ("ERROR : Trying to acces audiocodec already in use by user %d\n", g_cur_user); + return CODEC_ERROR; + } + + return (codec_error); +} + +/** + * nomadik_acodec_unset_user + * + * Unset the current user for acodec. + */ + +t_codec_error nomadik_acodec_unsetuser(t_acodec_user user) +{ + t_codec_error codec_error = CODEC_OK; + + if(g_cur_user != user){ + printk + ("ERROR : Trying to free audiocodec already in use by other user %d\n", g_cur_user); + return CODEC_ERROR; + } + else + g_cur_user = NO_USER; + + return (codec_error); +} + +/** + * nomadik_acodec_init + * + * This is the init function for STW5094 audiocodec driver. */ + +static int __init nomadik_acodec_init(void) +{ + int error; + /* default configuration for audiocodec + -no argument in required in nomadik_acodec_init + */ + DEBUG(1, " Entering nomadik_acodec_init\n"); + + g_cur_user = NO_USER; + + nomadik_acodec_conf = kmalloc(sizeof(codec_configuration), GFP_KERNEL); + if (NULL == nomadik_acodec_conf) { + printk("ERROR : memory not allocted \n"); + return -ENOMEM; + } + memset(nomadik_acodec_conf, 0, sizeof(codec_configuration)); + + nomadik_acodec_defaultconf = + kmalloc(sizeof(codec_configuration), GFP_KERNEL); + if (NULL == nomadik_acodec_defaultconf) { + printk("ERROR : memory not allocated \n"); + return -ENOMEM; + } + + memset(nomadik_acodec_defaultconf, 0, sizeof(codec_configuration)); + + nomadik_acodec_defaultconf->running_direction = CODEC_DIRECTION_INOUT; + nomadik_acodec_defaultconf->record_frequency = CODEC_SAMPLING_FREQ_8KHZ; + nomadik_acodec_defaultconf->play_frequency = CODEC_SAMPLING_FREQ_8KHZ; + nomadik_acodec_defaultconf->sample_size = CODEC_SIZE_16; + nomadik_acodec_defaultconf->codec_input = CODEC_SOURCE_MIC1; + nomadik_acodec_defaultconf->codec_output = CODEC_DEST_HP0; /*CODEC_DEST_HP_AND_LSP; */ + + /* default record volume is 50 and playback volume is 100 on scale of 1-100 */ + nomadik_acodec_defaultconf->codec_volume.lvolume_in = 50; + nomadik_acodec_defaultconf->codec_volume.rvolume_in = 50; + nomadik_acodec_defaultconf->codec_volume.lvolume_out = 100; + nomadik_acodec_defaultconf->codec_volume.rvolume_out = 100; + + nomadik_acodec_defaultconf->codec_mode = CODEC_MODE_NONE; + nomadik_acodec_defaultconf->compand_mode = CODEC_LINEAR; + nomadik_acodec_defaultconf->codec_power_state = ZERO; + nomadik_acodec_defaultconf->sidetone_enable = false; + nomadik_acodec_defaultconf->sidetone_gain = CODEC_SIDETONE_GAIN_12_5DB; + nomadik_acodec_defaultconf->codec_tone_mode = false; + nomadik_acodec_defaultconf->bypass_mode_enable = false; + nomadik_acodec_defaultconf->bypass_mode_gain = CODEC_TONE_GAIN_0DB; + nomadik_acodec_defaultconf->input_gain = CODEC_MIC_GAIN_22_5DB; + nomadik_acodec_defaultconf->mix_mask = false; + nomadik_acodec_defaultconf->tone_gain = CODEC_TONE_GAIN_0DB; + + /*copy the default values in nomadik_acodec_conf */ + *nomadik_acodec_conf = *nomadik_acodec_defaultconf; + + /* GPIO55 alt function to reset clock */ + if ((error = + nomadik_gpio_altfuncenable(GPIO_ALT_CLOCK_RESET, "ACODEC"))) { + printk("error in initializing gpio func FUNC_CLOCKRESET\n"); + return error; + } + + if ((error = nomadik_acodec_powerdown(ONE))) { + printk("error in acodec power down\n"); + return error; + } + + DEBUG(1, " leaving nomadik_acodec_init() \n"); + return 0; +} + +/** + * nomadik_acodec_deinit + * + * exit function for STW5094 audiocodec driver. + */ +static void __exit nomadik_acodec_deinit(void) +{ + int error = 0; + + DEBUG(1, " Entering AUDIOCODEC_DeIni\n"); + + g_cur_user = NO_USER; + //nomadik_msp_disable(MSP_NUM, MSP_BOTH_T_R_MODE); + + /* GPIO55 alt function to reset clock */ + if ((error = + nomadik_gpio_altfuncdisable(GPIO_ALT_CLOCK_RESET, "ACODEC"))) + printk("error in gpio alt func disable : %d\n", error); + + if ((error = reset_nomadik_acodec())) + printk("error in resetting acodec\n"); + + if ((error = nomadik_acodec_powerdown(ZERO))) + printk("error in acodec power down\n"); + + if (nomadik_acodec_conf) + kfree(nomadik_acodec_conf); + if (nomadik_acodec_defaultconf) + kfree(nomadik_acodec_defaultconf); + + DEBUG(1, " leaving AUDIOCODEC_DeIni\n"); +} + +/** +* nomadik_acodec_enable_audio_mode +* +* @direction - direction of data flow (from/to) audiocode +* @input_frequency - record direction +* @output_frequency - playback direction +* @mspClockSel - clock for MSP +* @mspInClockFreq - input clock for MSP +* +* It configures the audiocodec in audio mode. In this case,the I2S +* protocol is used for data exchanges. +*/ + +t_codec_error nomadik_acodec_enable_audio_mode(t_codec_direction direction, + t_codec_sample_frequency + input_frequency, + t_codec_sample_frequency + output_frequency, + codec_msp_srg_clock_sel_type + mspClockSel, + codec_msp_in_clock_freq_type + mspInClockFreq, + t_acodec_user user) +{ + t_codec_error error_status = CODEC_OK; + __u8 data; + t_codec_sample_frequency freq = ZERO; + struct msp_generic_config MSPConfiguration; + + __u8 cr_data[4] = + { ZERO, DB0_BOARD_GAIN, HEADPHONE_MAX_GAIN, HEADPHONE_MAX_GAIN }; + + DEBUG(1, " Entering in nomadik_acodec_enable_audio_mode()\n"); + + if(g_cur_user == NO_USER) { + printk("WARNING : Audiocodec not yet configured by any user\n"); + return (CODEC_ERROR); + } + else if(g_cur_user != user) { + printk + ("ERROR : Trying to acces audiocodec already in use by user %d\n", g_cur_user); + return (CODEC_ERROR); + } + + /* reset audiocodec */ + error_status = reset_nomadik_acodec(); + if (CODEC_OK != error_status) { + printk("ERROR: error in resetting acodec\n"); + return error_status; + } + + switch (direction) { + case CODEC_DIRECTION_INOUT: + if (input_frequency != output_frequency) { + printk + ("ERROR : in inout mode two different frequencies are not supported\n"); + return CODEC_NOT_SUPPORTED; + } else { + freq = input_frequency; + nomadik_acodec_conf->record_frequency = freq; + nomadik_acodec_conf->play_frequency = freq; + } + break; + case CODEC_DIRECTION_IN: + freq = input_frequency; + nomadik_acodec_conf->record_frequency = freq; + break; + case CODEC_DIRECTION_OUT: + freq = output_frequency; + nomadik_acodec_conf->play_frequency = freq; + break; + case CODEC_DIRECTION_UNKNOWN: + default: + printk("Invalid direction\n"); + return CODEC_ERROR; + } + + switch (freq) { + case CODEC_SAMPLING_FREQ_8KHZ: + case CODEC_SAMPLING_FREQ_11KHZ: + case CODEC_SAMPLING_FREQ_12KHZ: + case CODEC_SAMPLING_FREQ_16KHZ: + case CODEC_SAMPLING_FREQ_22KHZ: + case CODEC_SAMPLING_FREQ_24KHZ: + case CODEC_SAMPLING_FREQ_32KHZ: + case CODEC_SAMPLING_FREQ_44KHZ: + case CODEC_SAMPLING_FREQ_48KHZ: + case CODEC_SAMPLING_FREQ_64KHZ: + case CODEC_FREQUENCY_DONT_CHANGE: + break; + case CODEC_SAMPLING_FREQ_88KHZ: + case CODEC_SAMPLING_FREQ_96KHZ: + case CODEC_SAMPLING_FREQ_128KHZ: + case CODEC_SAMPLING_FREQ_176KHZ: + case CODEC_SAMPLING_FREQ_192KHZ: + case CODEC_SAMPLING_FREQ_MINLIMIT: + case CODEC_SAMPLING_FREQ_MAXLIMIT: + case CODEC_SAMPLING_FREQ_RESET: + default: + printk("not supported frequency\n"); + return CODEC_ERROR; + } + + error_status = set_ock_frequency(freq); + if (CODEC_OK != error_status) { + printk("ERROR: failed to set frequency \n"); + return error_status; + } + + /* set i2s protocol */ + data = I2S_POWER_OFF; + error_status = + nomadik_i2c_write_register(I2C_AUDIO_CODEC_CLIENT, &data, CR21, 1); + if (error_status < 0) { + printk("ERROR : error in set i2s power off\n"); + return error_status; + } + /*set output device by default value */ + cr_data[0] = ENABLE_AUDIO_OR_VOICE; + error_status = + nomadik_i2c_write_register(I2C_AUDIO_CODEC_CLIENT, cr_data, CR6, 4); + if (error_status < 0) { + printk(" error in set output device \n"); + return error_status; + } + +/* + error_status = + nomadik_acodec_select_output(nomadik_acodec_defaultconf-> + codec_output, user); + if (error_status < 0) { + printk(" error in selecting output\n"); + return error_status; + } +*/ + + /* enable i2s delayed format */ + data = I2S_AUDIO_IF_FORMAT; + error_status = + nomadik_i2c_write_register(I2C_AUDIO_CODEC_CLIENT, &data, CR16, 1); + if (error_status < 0) { + printk(" error in setting I2S format\n"); + return error_status; + } + + /* put on audio dynamic compression */ + data = 0x20; + error_status = + nomadik_i2c_write_register(I2C_AUDIO_CODEC_CLIENT, &data, CR20, 1); + if (error_status < 0) { + printk(" error in set compression\n"); + return error_status; + } + /* power up i2s after setting done */ + data = I2S_POWER_ON; + error_status = + nomadik_i2c_write_register(I2C_AUDIO_CODEC_CLIENT, &data, CR21, 1); + if (error_status < 0) { + printk(" error in set i2s power on \n"); + return error_status; + } + /* MSP configuration */ + + freq = input_frequency; + + MSPConfiguration.tx_clock_sel = TX_CLK_SEL_SRG; + MSPConfiguration.rx_clock_sel = RX_CLK_SEL_SRG; + + MSPConfiguration.tx_frame_sync_sel = TX_SYNC_SRG_PROG; + MSPConfiguration.rx_frame_sync_sel = RX_SYNC_SRG; + + if (mspInClockFreq == DEFAULT) + MSPConfiguration.input_clock_freq = MSP_INPUT_FREQ_48MHZ; + else + MSPConfiguration.input_clock_freq = mspInClockFreq; + + if (mspClockSel == DEFAULT) + MSPConfiguration.srg_clock_sel = SRG_CLK_SEL_APB; + else + MSPConfiguration.srg_clock_sel = mspClockSel; + + MSPConfiguration.rx_endianess = MSP_BIG_ENDIAN; + MSPConfiguration.tx_endianess = MSP_BIG_ENDIAN; + + MSPConfiguration.rx_frame_sync_pol = RX_FIFO_SYNC_HI; + MSPConfiguration.tx_frame_sync_pol = TX_FIFO_SYNC_HI; + + MSPConfiguration.rx_unexpect_frame_sync = MSP_UNEXPECTED_FS_IGNORE; + MSPConfiguration.tx_unexpect_frame_sync = MSP_UNEXPECTED_FS_IGNORE; + + MSPConfiguration.rx_fifo_config = RX_FIFO_ENABLE; + MSPConfiguration.tx_fifo_config = TX_FIFO_ENABLE; + + MSPConfiguration.spi_clk_mode = SPI_CLK_MODE_NORMAL; + + error_status = nomadik_msp_configure(MSP_NUM, &MSPConfiguration, (t_msp_user)user); + if (error_status) { + printk("error in msp configure\n"); + return error_status; + } + + /* enable msp for both tr and rx mode with dma data transfer. THIS IS NOW DONE SEPARATELY from SAA. */ + error_status = + nomadik_msp_enable(MSP_NUM, MSP_BOTH_T_R_MODE, MSP_DMA_MODE, + MSP_I2S_PROTOCOL, freq, ELEMENT_SIZE, + FRAME_SIZE, (t_msp_user)user); + if (error_status < 0) { + printk("error in msp enable\n"); + return error_status; + } + + /*set the audiocodec volume for both channels */ +/* error_status = + nomadik_acodec_set_volume(nomadik_acodec_defaultconf->codec_volume. + lvolume_in, + nomadik_acodec_defaultconf->codec_volume. + rvolume_in, + nomadik_acodec_defaultconf->codec_volume. + lvolume_out, + nomadik_acodec_defaultconf->codec_volume. + rvolume_out, user); + if (error_status < 0) { + printk("error in set volume\n"); + return error_status; + } +*/ + + nomadik_acodec_conf->codec_mode = CODEC_MODE_AUDIO; + DEBUG(1, "leaving in nomadik_acodec_enable_audio_mode() \n"); + + return CODEC_OK; +} + +/** +* nomadik_acodec_enable_voice_mode +* +* @direction - direction of data flow (from/to) audiocode +* @input_frequency - record direction +* @output_frequency - playback direction +* @mspClockSel - clock for MSP +* @mspInClockFreq - input clock for MSP +* +* It configures the audiocodec in audio mode. In this case,the PCM +* protocol is used for data exchanges. +*/ +t_codec_error nomadik_acodec_enable_voice_mode(t_codec_direction direction, + t_codec_sample_frequency + input_frequency, + t_codec_sample_frequency + output_frequency, + codec_msp_srg_clock_sel_type + mspClockSel, + codec_msp_in_clock_freq_type + mspInClockFreq, + t_acodec_user user) + +{ + struct msp_generic_config MSPConfiguration; + t_codec_error error_status; + t_codec_sample_frequency freq; + __u8 cr_val[2] = { ZERO, ZERO }; + __u8 data = ZERO; + __u8 cr_data[4] = + { ZERO, DB0_BOARD_GAIN, HEADPHONE_MAX_GAIN, HEADPHONE_MAX_GAIN }; + codec_msp_in_clock_freq_type local_mspClockFreq; + + DEBUG(1, "Entering in nomadik_acodec_enable_voice_mode () \n"); + + if(g_cur_user == NO_USER) { + printk("WARNING : Audiocodec not yet configured by any user\n"); + return (CODEC_ERROR); + } + else if(g_cur_user != user) { + printk + ("ERROR : Trying to acces audiocodec already in use by user %d\n", g_cur_user); + return (CODEC_ERROR); + } + + local_mspClockFreq = mspInClockFreq; + + /* reset audiocodec */ + error_status = reset_nomadik_acodec(); + if (CODEC_OK != error_status) { + printk("ERROR: error in resetting acodec\n"); + return error_status; + } + + switch (direction) { + case CODEC_DIRECTION_INOUT: + if (input_frequency != output_frequency) { + printk + ("ERROR : in inout mode two different frequencies are not supported\n"); + return CODEC_NOT_SUPPORTED; + } else { + freq = input_frequency; + nomadik_acodec_conf->record_frequency = freq; + nomadik_acodec_conf->play_frequency = freq; + } + break; + case CODEC_DIRECTION_IN: + freq = input_frequency; + nomadik_acodec_conf->record_frequency = freq; + break; + case CODEC_DIRECTION_OUT: + freq = output_frequency; + nomadik_acodec_conf->play_frequency = freq; + break; + case CODEC_DIRECTION_UNKNOWN: + default: + printk("Invalid direction\n"); + return CODEC_ERROR; + } + + if ((CODEC_SAMPLING_FREQ_8KHZ != freq) + && (CODEC_SAMPLING_FREQ_16KHZ != freq)) { + printk("AUDIOCODEC: ERROR: Frequency not authorized\n"); + return CODEC_NOT_SUPPORTED; + + } + + /* Configure the audio codec for voice mode + set the OCK clock frequency first */ + error_status = set_ock_frequency(freq); + if (CODEC_NOT_SUPPORTED == error_status) { + printk("ERROR:SAA-DRV: unable to set frequency \n"); + return CODEC_NOT_SUPPORTED; + } + + if (CODEC_SAMPLING_FREQ_8KHZ == freq) { + cr_val[0] = PCM_MCLK_2M | PCM_FS_8KHZ; + } else if (CODEC_SAMPLING_FREQ_16KHZ == freq) { + cr_val[0] = PCM_MCLK_2M | PCM_FS_16KHZ; + } + + switch (nomadik_acodec_conf->compand_mode) { + case CODEC_LINEAR: + cr_val[0] |= PCM_FORMAT_PCM; + cr_val[1] = (PCM_ENABLE | PCM_B1); + break; + case CODEC_ALAW: + cr_val[0] |= PCM_FORMAT_ALAW; + cr_val[1] = PCM_ENABLE | PCM_B2; + break; + case CODEC_MULAW: + cr_val[0] |= PCM_FORMAT_MULAW; + cr_val[1] = PCM_ENABLE | PCM_B1; + break; + } + /* power down audiocodec before setting other registers */ + /*nomadik_acodec_powerdown(ONE); */ + + error_status = + nomadik_i2c_write_register(I2C_AUDIO_CODEC_CLIENT, cr_val, CR00, 2); + if (CODEC_OK != error_status) { + printk("ERROR:SAA-DRV: failed in I2c read/write call\n"); + return error_status; + } + + data = + nomadik_acodec_conf->codec_input | nomadik_acodec_conf->input_gain; + + error_status = + nomadik_i2c_write_register(I2C_AUDIO_CODEC_CLIENT, &data, CR4, 1); + + if (CODEC_OK != error_status) { + printk("ERROR:SAA-DRV: failed in I2c read/write call\n"); + return error_status; + } + /*configure output device with default values given in init process */ + + cr_data[0] = ENABLE_AUDIO_OR_VOICE; + error_status = + nomadik_i2c_write_register(I2C_AUDIO_CODEC_CLIENT, cr_data, CR6, 4); + if (error_status < 0) { + printk(" error in set output device \n"); + return error_status; + } + +/* + error_status = + nomadik_acodec_select_output(nomadik_acodec_defaultconf-> + codec_output, user); + if (error_status < 0) { + printk(" error in selecting output\n"); + return error_status; + } +*/ + + /* POWER UP THE AUDIOCODEC */ + /* select MCLK as master clock */ + data = PCM_POWER_ON; + error_status = + nomadik_i2c_write_register(I2C_AUDIO_CODEC_CLIENT, &data, CR21, 1); + if (error_status < 0) { + printk + (" Failed to set MCLK as master clock for voice mode. \n"); + return error_status; + } + + DEBUG(2, "MSP Configuring as MASTER \n"); + + MSPConfiguration.tx_clock_sel = TX_CLK_SEL_SRG; + MSPConfiguration.rx_clock_sel = RX_CLK_SEL_SRG; + + MSPConfiguration.tx_frame_sync_sel = TX_SYNC_SRG_PROG; + MSPConfiguration.rx_frame_sync_sel = RX_SYNC_SRG; + + if (mspInClockFreq == DEFAULT) + MSPConfiguration.input_clock_freq = MSP_INPUT_FREQ_48MHZ; + else + MSPConfiguration.input_clock_freq = mspInClockFreq; + if (mspClockSel == DEFAULT) + MSPConfiguration.srg_clock_sel = SRG_CLK_SEL_APB; + else + MSPConfiguration.srg_clock_sel = mspClockSel; + + MSPConfiguration.rx_endianess = MSP_BIG_ENDIAN; + MSPConfiguration.tx_endianess = MSP_BIG_ENDIAN; + + MSPConfiguration.rx_frame_sync_pol = RX_FIFO_SYNC_HI; + MSPConfiguration.tx_frame_sync_pol = TX_FIFO_SYNC_HI; + + MSPConfiguration.rx_unexpect_frame_sync = MSP_UNEXPECTED_FS_IGNORE; + MSPConfiguration.tx_unexpect_frame_sync = MSP_UNEXPECTED_FS_IGNORE; + + MSPConfiguration.rx_fifo_config = RX_FIFO_ENABLE; + MSPConfiguration.tx_fifo_config = TX_FIFO_ENABLE; + + MSPConfiguration.spi_clk_mode = SPI_CLK_MODE_NORMAL; + MSPConfiguration.spi_burst_mode = 0; + + error_status = nomadik_msp_configure(MSP_NUM, &MSPConfiguration, (t_msp_user)user); + if (error_status) { + printk("error in msp configure\n"); + return error_status; + } + + /* enable msp for both tr and rx mode with dma data transfer. */ + error_status = + nomadik_msp_enable(MSP_NUM, MSP_BOTH_T_R_MODE, MSP_DMA_MODE, + MSP_PCM_PROTOCOL, freq, ELEMENT_SIZE, + FRAME_SIZE, (t_msp_user)user); + if (error_status) { + printk("error in msp enable\n"); + return error_status; + } + + /* set the audiocodec volume for both channels */ +/* error_status = + nomadik_acodec_set_volume(nomadik_acodec_defaultconf->codec_volume. + lvolume_in, + nomadik_acodec_defaultconf->codec_volume. + rvolume_in, + nomadik_acodec_defaultconf->codec_volume. + lvolume_out, + nomadik_acodec_defaultconf->codec_volume. + rvolume_out, user); + if (error_status) { + printk("error in set volume\n"); + return error_status; + } +*/ + + nomadik_acodec_conf->codec_mode = CODEC_MODE_VOICE; + DEBUG(1, "Leaving in nomadik_acodec_enable_voice_mode () \n"); + + return (error_status); +} + +/** + * nomadik_acodec_enable_tonegeneratormode + * @tone_gain - gain in db for tone generated + * @mix_with_record - mixing of tone with recording + * @mix_with_playback - mixing of tone with playback + * @waveShape - wave shape sin/square + * @reserved2 - reserved for future use + * + * It configures the audiocodec in tone mode. if mix with + * or record is TRUE then enable internal tone generator else + * set tone only mode nad disable audio or voice mode. + */ + +t_codec_error nomadik_acodec_enable_tonegeneratormode(int tone_gain, + __u8 mix_with_record, + __u8 mix_with_playback, + codec_tone_wave waveShape, + u_long * reserved2, t_acodec_user user) +{ + + t_codec_error error_status = CODEC_OK; + __u8 data; + int gain; + __u8 cr_val; + __u8 cr_data[4] = + { ZERO, DB0_BOARD_GAIN, HEADPHONE_MAX_GAIN, HEADPHONE_MAX_GAIN }; + + DEBUG(1, " entering in AUDIOCODEC_EnableToneGenerator() \n"); + + error_status = nomadik_acodec_powerdown(ONE); + if (error_status < 0) { + printk(" Failed to powerdown the acodec\n"); + return error_status; + } + + /* if want to mix with Tx path */ + if (ZERO != (mix_with_playback & ONE) + && CODEC_MODE_NONE == nomadik_acodec_conf->codec_mode) { + + cr_val = TONE_ONLY_OFF; + error_status = + nomadik_i2c_write_register(I2C_AUDIO_CODEC_CLIENT, &cr_val, + CR21, 1); + if (error_status < 0) { + printk(" error in set cr21\n"); + return error_status; + } + /* set HP or LSP or both */ + cr_data[0] = ENABLE_AUDIO_OR_VOICE; + error_status = + nomadik_i2c_write_register(I2C_AUDIO_CODEC_CLIENT, cr_data, + CR6, 4); + if (error_status < 0) { + printk(" error in set output device \n"); + return error_status; + } + + error_status = + nomadik_acodec_select_output(nomadik_acodec_conf-> + codec_output, user); + if (error_status < 0) { + printk("Failed to select output\n"); + return error_status; + } + + nomadik_acodec_conf->codec_mode = CODEC_MODE_TONE; + } + /* close RTE */ + error_status = + nomadik_i2c_read_register(I2C_AUDIO_CODEC_CLIENT, &data, CR6, 1); + if (CODEC_OK != error_status) { + printk("ERROR:SAA-DRV: failed in I2c read/write call\n"); + return error_status; + } + + if (ZERO != (mix_with_playback & ONE)) { + data |= MIX_WITH_TX; + } else { + data &= ~MIX_WITH_TX; + } + if (ZERO != (mix_with_playback & TWO)) { + data |= MIX_WITH_TX << ONE; + } else { + data &= ~(MIX_WITH_TX << ONE); + } + error_status = + nomadik_i2c_write_register(I2C_AUDIO_CODEC_CLIENT, &data, CR6, 1); + if (error_status < 0) { + printk(" error in set cr5\n"); + return error_status; + } + + if (RESET == tone_gain) { + gain = set_tone_gain(nomadik_acodec_defaultconf->tone_gain); + data = gain << TONE_GAIN_SHIFT; + } else { + gain = set_tone_gain(tone_gain); + data = gain << TONE_GAIN_SHIFT; + } + data |= waveShape; + /* DE is open or close as required */ + if (THREE == (mix_with_record & THREE)) { + return CODEC_NOT_SUPPORTED; + } /* connect tone to the Tx path to capture tone */ + else if (ZERO != (mix_with_record & ONE)) { + data |= MIX_WITH_TX; + } /* MIC capture is enabled */ + else if (ZERO != (mix_with_record & TWO)) { + data &= ~MIX_WITH_TX; + } + nomadik_acodec_conf->tone_gain = gain; + /* set F1 and F2 in mute before any call to play tone single or dual */ + data &= ~F1_F2_SUMMED; + error_status = + nomadik_i2c_write_register(I2C_AUDIO_CODEC_CLIENT, &data, CR12, 1); + if (error_status < 0) { + printk(" error in set cr12\n"); + return error_status; + } + nomadik_acodec_conf->codec_tone_mode = true; + + error_status = nomadik_acodec_powerup(); + if (error_status < 0) { + printk(" Failed to powerdown the acodec\n"); + return error_status; + } + DEBUG(1, " leaving AUDIOCODEC_EnableToneGenerator() \n"); + return error_status; +} + +/** + * nomadik_acodec_disable_tonegeneratormode + * + * It disables the tonegeneration mode. + */ +t_codec_error nomadik_acodec_disable_tonegeneratormode(t_acodec_user user) +{ + + t_codec_error error_status = CODEC_OK; + __u8 data; + __u8 cr_val; + + DEBUG(1, " entering in AUDIOCODEC_DiableToneGenerator() \n"); + /* if tone only mode is set then set voice mode */ + if (CODEC_MODE_TONE == nomadik_acodec_conf->codec_mode) { + nomadik_i2c_read_register(I2C_AUDIO_CODEC_CLIENT, &cr_val, CR21, + 1); + cr_val &= 0x3F; + error_status = + nomadik_i2c_write_register(I2C_AUDIO_CODEC_CLIENT, &cr_val, + CR21, 1); + if (error_status < 0) { + DEBUG(1, " error in set cr21\n"); + } + nomadik_acodec_conf->codec_mode = CODEC_MODE_NONE; + } + data = ZERO; + error_status = + nomadik_i2c_write_register(I2C_AUDIO_CODEC_CLIENT, &data, CR12, 1); + if (error_status < 0) { + DEBUG(1, " error in set cr12\n"); + + } + error_status = + nomadik_i2c_read_register(I2C_AUDIO_CODEC_CLIENT, &data, CR6, 1); + /* open RTE */ + data &= ~MIX_WITH_TX; + error_status = + nomadik_i2c_write_register(I2C_AUDIO_CODEC_CLIENT, &data, CR6, 1); + if (error_status < 0) { + DEBUG(1, " error in set cr6\n"); + } + nomadik_acodec_conf->codec_tone_mode = false; + DEBUG(1, " leaving AUDIOCODEC_DiableToneGenerator() \n"); + return error_status; +} + +/** + * nomadik_acodec_play_singletone + * @tone_frequency: single frequency to generate tone + * + * It starts the single frequency tone generation + */ +t_codec_error nomadik_acodec_play_singletone(int toneFrequency, t_acodec_user user) +{ + t_codec_error error_status = CODEC_OK; + __u8 data = ZERO; + int value; + __u8 cr_val = ZERO; + + DEBUG(1, " entering in nomadik_acodec_play_singletone() \n"); + /* set freq f1 in CR13 */ + value = calculate_frequency(toneFrequency); + if (CODEC_BAD_VALUE == value) { + printk(" Error : Frequency out of range (0 to 3750)\n"); + return CODEC_NOT_SUPPORTED; + } + data = (__u8) value; + + error_status = + nomadik_i2c_write_register(I2C_AUDIO_CODEC_CLIENT, &data, CR13, 1); + if (error_status < 0) { + DEBUG(1, " error in set cr13\n"); + } + + /* select freq f1 and start tone */ + error_status = + nomadik_i2c_read_register(I2C_AUDIO_CODEC_CLIENT, &cr_val, CR12, 1); + cr_val |= F1_SELECT; + error_status = + nomadik_i2c_write_register(I2C_AUDIO_CODEC_CLIENT, &cr_val, CR12, + 1); + if (error_status < 0) { + DEBUG(1, " error in set cr12\n"); + } + DEBUG(1, " leaving nomadik_acodec_play_singletone() \n"); + + return error_status; + +} + +/** +* nomadik_acodec_play_dualtone +* @freqF1 - frequency f1 to generate tone +* @ferqF2 - frequemcy f2 to generate tone +* +* It starts the DTMF tone generation +*/ +t_codec_error nomadik_acodec_play_dualtone(int freqF1, int freqF2, t_acodec_user user) +{ + t_codec_error error_status = CODEC_OK; + __u8 data = ZERO; + __u8 cr_val = ZERO; + int value; + + DEBUG(1, " entering in nomadik_acodec_play_dualtone() \n"); + /* set freq f1 and f2 in CR13 and CR14 */ + value = calculate_frequency(freqF1); + if (CODEC_BAD_VALUE == value) { + printk(" Error : Frequency out of range (0 to 3750)\n"); + return CODEC_NOT_SUPPORTED; + } + data = (__u8) value; + + error_status = + nomadik_i2c_write_register(I2C_AUDIO_CODEC_CLIENT, &data, CR13, 1); + if (error_status < 0) { + DEBUG(1, " error in set cr13\n"); + } + value = calculate_frequency(freqF2); + if (CODEC_BAD_VALUE == value) { + printk(" Error : Frequency out of range (0 to 3750)\n"); + return CODEC_NOT_SUPPORTED; + } + data = (__u8) value; + + error_status = + nomadik_i2c_write_register(I2C_AUDIO_CODEC_CLIENT, &data, CR14, 1); + if (error_status < 0) { + DEBUG(1, " error in set cr14\n"); + } + /* select freq f1 and F1 both to start tone */ + error_status = + nomadik_i2c_read_register(I2C_AUDIO_CODEC_CLIENT, &cr_val, CR12, 1); + cr_val |= F1_F2_SUMMED; + error_status = + nomadik_i2c_write_register(I2C_AUDIO_CODEC_CLIENT, &cr_val, CR12, + 1); + if (error_status < 0) { + DEBUG(1, " error in set cr12\n"); + } + DEBUG(1, " leaving nomadik_acodec_play_dualtone() \n"); + + return error_status; + +} + +/** +* nomadik_acodec_stop_tone - stops the DTMF or single tone generatio +*/ +t_codec_error nomadik_acodec_stop_tone(t_acodec_user user) +{ + t_codec_error error_status = CODEC_OK; + __u8 cr_val = ZERO; + + DEBUG(1, " entering in nomadik_acodec_stop_tone() \n"); + /* set freq f1 and F1 both in mute mode to stop tone */ + error_status = + nomadik_i2c_read_register(I2C_AUDIO_CODEC_CLIENT, &cr_val, CR12, 1); + + if (CODEC_OK != error_status) { + printk("ERROR:SAA-DRV: failed in I2c read/write call\n"); + return error_status; + } + cr_val &= !(F1_F2_SUMMED); + error_status = + nomadik_i2c_write_register(I2C_AUDIO_CODEC_CLIENT, &cr_val, CR12, + 1); + if (error_status < 0) { + DEBUG(1, " error in set cr12\n"); + } + + DEBUG(1, " Leaving nomadik_acodec_stop_tone() \n"); + return error_status; + +} + +/** +* nomadik_acodec_set_volume - configures the volume level for both speakers +* @in_left_volume - volume for left channel of mic +* @in_right_volume - volume for right channel of mic +* @out_left_volume - volume for left speaker +* @out_right_volume - volume for right speaker +*/ +t_codec_error nomadik_acodec_set_volume(int input_vol_left, + int input_vol_right, + int output_vol_left, + int output_vol_right, t_acodec_user user) +{ + int volume, volumeMicLeft, volumeMicRight; + __u8 data = 0, vol; + t_codec_error error_status = CODEC_OK; + DEBUG(1, " Entering in nomadik_acodec_set_volume()\n"); + + if(g_cur_user == NO_USER) { + printk("WARNING : Audiocodec not yet configured by any user\n"); + return (CODEC_ERROR); + } + else if(g_cur_user != user) { + printk + ("ERROR : Trying to acces audiocodec already in use by user %d\n", g_cur_user); + return (CODEC_ERROR); + } + + /* for mic take the average of the two channels volumes since there is + * not different channel volume settigns. + */ + /* reset the volume to default value */ + if (RESET == input_vol_left || RESET == input_vol_right) { + input_vol_right = DEFAULT_VOLUME; + input_vol_left = DEFAULT_VOLUME; + } + /* mute the input if both chanenls are zero */ + if (ZERO == input_vol_left && ZERO == input_vol_right) { + /*read the default settings for mic and its gain */ + error_status = nomadik_i2c_read_register(I2C_AUDIO_CODEC_CLIENT, + &data, CR4, 1); + if (error_status < 0) { + printk("ERROR : ACODEC: error in read CR4 \n"); + return error_status; + } + /* mute the input if both of the input volume are 0 */ + data &= 0x3f; + error_status = + nomadik_i2c_write_register(I2C_AUDIO_CODEC_CLIENT, &data, + CR4, 1); + if (error_status < 0) { + printk("ERROR : ACODEC: error in write CR4 \n"); + return error_status; + } + } else if (!(DEFAULT == input_vol_left && DEFAULT == input_vol_right)) { + volumeMicLeft = set_volume_mic((int)input_vol_left); + volumeMicRight = set_volume_mic((int)input_vol_right); + volume = (volumeMicLeft + volumeMicRight) / 2; + + if (CODEC_BAD_VALUE == volumeMicRight + || CODEC_BAD_VALUE == volumeMicLeft) { + return CODEC_BAD_VALUE; + } + + if (volumeMicRight != DEFAULT && volumeMicLeft != DEFAULT) { + /*read the default settings for mic and its gain */ + error_status = + nomadik_i2c_read_register(I2C_AUDIO_CODEC_CLIENT, + &data, CR4, 1); + if (CODEC_OK != error_status) { + printk + ("ERROR:SAA-DRV: failed in I2c read/write call\n"); + return error_status; + } + + /* dont change the mic selected. just change the volume clear + * the lower 5 bits and set the volume as lsb 0 to 44.5db + */ + data &= 0xE0; + if (ZERO == (data & 0xC0)) { + data |= nomadik_acodec_conf->codec_input; + } + if (volume >= 14) + volume += 2; + + volume &= 0x0000001f; + volume ^= 0x00000010; + data |= volume; + error_status = + nomadik_i2c_write_register(I2C_AUDIO_CODEC_CLIENT, + &data, CR4, 1); + if (CODEC_OK != error_status) { + printk + ("ERROR:SAA-DRV: failed in I2c read/write call\n"); + return error_status; + } + + nomadik_acodec_conf->codec_volume.lvolume_in = + input_vol_left; + nomadik_acodec_conf->codec_volume.rvolume_in = + input_vol_right; + } + + } + if (RESET == output_vol_left) { + output_vol_left = DEFAULT_VOLUME; + } + if (RESET == output_vol_right) { + output_vol_right = DEFAULT_VOLUME; + } + + if (!(ZERO == output_vol_right && ZERO == output_vol_left)) { + + /* if already output devices are mute then reenable them */ + error_status = + nomadik_i2c_read_register(I2C_AUDIO_CODEC_CLIENT, &data, + CR6, 1); + if (CODEC_OK != error_status) { + printk + ("ERROR:SAA-DRV: failed in I2c read/write call\n"); + return error_status; + } + /* renable otput devices if in mute state */ + data &= ~CODEC_MUTE; + error_status = + nomadik_i2c_write_register(I2C_AUDIO_CODEC_CLIENT, &data, + CR6, 1); + if (CODEC_OK != error_status) { + printk + ("ERROR:SAA-DRV: failed in I2c read/write call\n"); + return error_status; + } + + volume = set_volume((int)output_vol_right); + if (CODEC_BAD_VALUE == volume) { + return CODEC_BAD_VALUE; + } else if (volume != DEFAULT) { + /*set volume for right HP */ + vol = (__u8) volume; + error_status = + nomadik_i2c_write_register(I2C_AUDIO_CODEC_CLIENT, + &vol, CR9, 1); + if (CODEC_OK != error_status) { + printk + ("ERROR:SAA-DRV: failed in I2c read/write call\n"); + return error_status; + } + nomadik_acodec_conf->codec_volume.rvolume_out = + output_vol_right; + } + + volume = set_volume((int)output_vol_left); + + if (CODEC_BAD_VALUE == volume) { + return CODEC_BAD_VALUE; + } else if (volume != DEFAULT) { + /*set volume for left HP */ + vol = (__u8) volume; + error_status = + nomadik_i2c_write_register(I2C_AUDIO_CODEC_CLIENT, + &vol, CR8, 1); + if (CODEC_OK != error_status) { + printk + ("ERROR:SAA-DRV: failed in I2c read/write call\n"); + return error_status; + } + nomadik_acodec_conf->codec_volume.lvolume_out = + output_vol_left; + } + DEBUG(1, " leaving nomadik_acodec_set_volume()\n"); + + return error_status; + } + error_status = + nomadik_i2c_read_register(I2C_AUDIO_CODEC_CLIENT, &data, CR6, 1); + if (CODEC_OK != error_status) { + printk("ERROR:SAA-DRV: failed in I2c read/write call\n"); + return error_status; + } + /* mute the output devices */ + data |= CODEC_MUTE; + error_status = + nomadik_i2c_write_register(I2C_AUDIO_CODEC_CLIENT, &data, CR6, 1); + if (CODEC_OK != error_status) { + printk("ERROR:SAA-DRV: failed in I2c read/write call\n"); + return error_status; + } + return error_status; + +} + +/** +* nomadik_acodec_powerdown +* @flag - level of power down, 0 means complete power down +* +* It sets the codec in power down mode. complete functionality +* will be achieved in power management +*/ +t_codec_error nomadik_acodec_powerdown(__u8 flag) +{ + t_codec_error error_status; + __u8 cr21_val; + /*in current implementation nothing to do with flag */ + + DEBUG(1, " Entering nomadik_acodec_powerdown()\n"); + error_status = + nomadik_i2c_read_register(I2C_AUDIO_CODEC_CLIENT, &cr21_val, CR21, + 1); + if (CODEC_OK != error_status) { + printk("ERROR:SAA-DRV: failed in I2c read/write call\n"); + return error_status; + } + cr21_val &= 0xFE; + + if (ZERO == flag) { + cr21_val = 0x00; + } + error_status = + nomadik_i2c_write_register(I2C_AUDIO_CODEC_CLIENT, &cr21_val, CR21, + 1); + if (CODEC_OK != error_status) { + printk("ERROR:SAA-DRV: failed in I2c read/write call\n"); + return error_status; + } + + DEBUG(1, "leaving nomadik_acodec_powerdown() \n"); + return (error_status); + +} + +/** +* nomadik_acodec_powerup +* +* It sets the codec in power up mode. rest is left for power +* management. +*/ +t_codec_error nomadik_acodec_powerup(void) +{ + t_codec_error error_status; + __u8 cr21_val = ZERO; + + DEBUG(1, " Entering nomadik_acodec_powerup()\n"); + error_status = + nomadik_i2c_read_register(I2C_AUDIO_CODEC_CLIENT, &cr21_val, CR21, + 1); + if (CODEC_OK != error_status) { + printk("ERROR:SAA-DRV: failed in I2c read/write call\n"); + return error_status; + } + cr21_val |= PCM_POWER_ON; + error_status = + nomadik_i2c_write_register(I2C_AUDIO_CODEC_CLIENT, &cr21_val, CR21, + 1); + if (CODEC_OK != error_status) { + printk("ERROR:SAA-DRV: failed in I2c read/write call\n"); + return error_status; + } + + DEBUG(1, " leaving nomadik_acodec_powerup()\n"); + return (error_status); + +} + +/** +* nomadik_acodec_enable_bypassmode +* @analog_frequency +* @fm_gain - outside gain in the received audio signals +* @mix_with_playback - true if user wants to mix tone with audio played back +* @reserved1 - reserved for future use +* @reserved2 - reserved for future use +* +* Enables the bypass mode (Analog IN is routed to analog out. +*/ +t_codec_error nomadik_acodec_enable_bypassmode(t_codec_sample_frequency analog_frequency, __u8 fm_gain, boolean mix_with_playback, + u_long * reserved1, + u_long * reserved2, t_acodec_user user) +{ + t_codec_error error_status = CODEC_OK; + __u8 data; + + DEBUG(1, " Entering nomadik_acodec_enable_bypassmode()\n"); + + if(g_cur_user == NO_USER) { + printk("WARNING : Audiocodec not yet configured by any user\n"); + return (CODEC_ERROR); + } + else if(g_cur_user != user) { + printk + ("ERROR : Trying to acces audiocodec already in use by user %d\n", g_cur_user); + return (CODEC_ERROR); + } + + if (false == mix_with_playback) { + + /* power down the audiocodec */ + data = FM_POWER_OFF; + + error_status = + nomadik_i2c_write_register(I2C_AUDIO_CODEC_CLIENT, &data, + CR21, 1); + if (error_status < 0) { + DEBUG(1, " error in set i2s power off\n"); + } + + /* power up the audiocodec with FM mode */ + data = FM_POWER_ON; + + error_status = + nomadik_i2c_write_register(I2C_AUDIO_CODEC_CLIENT, &data, + CR21, 1); + if (error_status < 0) { + DEBUG(1, " error in set i2s power off\n"); + } + } else { /* dont set audio or voice mode , use existing mode and set CR20 to sum + the fm signals with the output comming from audio or voice */ + error_status = nomadik_acodec_powerup(); + if (error_status < 0) { + printk(" Failed to powerdown the acodec\n"); + return error_status; + } + error_status = + nomadik_i2c_read_register(I2C_AUDIO_CODEC_CLIENT, &data, + CR20, 1); + if (error_status < 0) { + printk("ERROR : in reading CR20 thru I2C \n"); + return CODEC_ERROR; + } + + data |= 0x80; + error_status = + nomadik_i2c_write_register(I2C_AUDIO_CODEC_CLIENT, &data, + CR20, 1); + if (CODEC_OK != error_status) { + printk + ("ERROR:SAA-DRV: failed in I2c read/write call\n"); + return error_status; + } + } + /* set the FM preamplifier gain for left and right channels in CR10 n 11 */ + /* same for both channels */ + data = fm_gain; + + nomadik_i2c_write_register(I2C_AUDIO_CODEC_CLIENT, &data, CR10, 1); + nomadik_i2c_write_register(I2C_AUDIO_CODEC_CLIENT, &data, CR11, 1); + + DEBUG(1, " leaving nomadik_acodec_enable_bypassmode()\n"); + return (error_status); + +} + +/** + * nomadik_acodec_set_samplesize + * @codec_size: sample size in bits + * + * This routine sets the sample size in bits. + */ +t_codec_error nomadik_acodec_set_samplesize(codec_input_bit_length codec_size, t_acodec_user user) +{ + + t_codec_error error_status = CODEC_OK; + __u8 data; + + DEBUG(1, " Entering nomadik_acodec_set_samplesize()\n"); + + if(g_cur_user == NO_USER) { + printk("WARNING : Audiocodec not yet configured by any user\n"); + return (CODEC_ERROR); + } + else if(g_cur_user != user) { + printk + ("ERROR : Trying to acces audiocodec already in use by user %d\n", g_cur_user); + return (CODEC_ERROR); + } + + /* read CR16 for previous setttings */ + error_status = + nomadik_i2c_read_register(I2C_AUDIO_CODEC_CLIENT, &data, CR16, 1); + if (error_status < 0) { + printk("ERROR : in reading CR16 thru I2C \n"); + return CODEC_ERROR; + } + /* set sample size */ + data &= 0xFC; + data |= codec_size; + nomadik_i2c_write_register(I2C_AUDIO_CODEC_CLIENT, &data, CR16, 1); + + DEBUG(1, " leaving nomadik_acodec_set_samplesize()\n"); + + return error_status; +} + +/** + * nomadik_acodec_set_no_of_channels + * @channels: mono or stereo + * + * This routine checks then sets the no of channels configured together + * with mode. + */ +t_codec_error nomadik_acodec_set_no_of_channels(t_codec_channel channels, t_acodec_user user) +{ + + DEBUG(1, " Entering nomadik_acodec_set_no_of_channels()\n"); + + if(g_cur_user == NO_USER) { + printk("WARNING : Audiocodec not yet configured by any user\n"); + return (CODEC_ERROR); + } + else if(g_cur_user != user) { + printk + ("ERROR : Trying to acces audiocodec already in use by user %d\n", g_cur_user); + return (CODEC_ERROR); + } + + if (nomadik_acodec_conf->codec_mode == CODEC_MODE_VOICE + && channels == CODEC_CHANNEL_STEREO) { + printk("ERROR : Stereo mode is not supported in VoiceMode\n"); + return CODEC_NOT_SUPPORTED; + } else if (nomadik_acodec_conf->codec_mode == CODEC_MODE_AUDIO + && channels == CODEC_CHANNEL_MONO) { + printk("ERROR : Mono mode is not supported in Audio mode\n"); + return CODEC_NOT_SUPPORTED; + } + DEBUG(1, " leaving nomadik_acodec_set_no_of_channels()\n"); + return CODEC_OK; +} + +/** + * nomadik_acodec_set_compand + * @compand_mode: Linear, A-law or Mu-Law + * + * This routine sets the Companded mode for audiocodec + */ +t_codec_error nomadik_acodec_set_compand(codec_compand_mode compand_mode, t_acodec_user user) +{ + t_codec_error error_status; + __u8 data; + __u8 cr_val[2] = { 0x00, 0x00 }; + + DEBUG(1, " Entering nomadik_acodec_set_compand()\n"); + + if(g_cur_user == NO_USER) { + printk("WARNING : Audiocodec not yet configured by any user\n"); + return (CODEC_ERROR); + } + else if(g_cur_user != user) { + printk + ("ERROR : Trying to acces audiocodec already in use by user %d\n", g_cur_user); + return (CODEC_ERROR); + } + + if (CODEC_MODE_AUDIO == nomadik_acodec_conf->codec_mode) { + printk + ("ERROR : compand mode is not supported in Audio mode \n"); + return CODEC_ERROR; + } + + /* read CR00 and then set bit CM for compand mode */ + error_status = + nomadik_i2c_read_register(I2C_AUDIO_CODEC_CLIENT, &data, CR00, 1); + if (error_status < 0) { + DEBUG(1, " error in reading CR0 thru I2C \n"); + return CODEC_ERROR; + } + /* set compand mode in CM bit */ + cr_val[0] = data & 0xE3; + if (CODEC_LINEAR == nomadik_acodec_conf->compand_mode) { + cr_val[0] |= PCM_FORMAT_PCM; + cr_val[1] = (PCM_ENABLE | PCM_B1); + + } else if (CODEC_ALAW == nomadik_acodec_conf->compand_mode) { + cr_val[0] |= PCM_FORMAT_ALAW; + cr_val[1] = PCM_ENABLE | PCM_B2; + } else if (CODEC_MULAW == nomadik_acodec_conf->compand_mode) { + cr_val[0] |= PCM_FORMAT_MULAW; + cr_val[1] = PCM_ENABLE | PCM_B1; + } + + error_status = + nomadik_i2c_write_register(I2C_AUDIO_CODEC_CLIENT, cr_val, CR00, 2); + if (error_status < 0) { + printk("ERROR : in writing CR0 thru I2C \n"); + return CODEC_ERROR; + } + + DEBUG(1, " leaving nomadik_acodec_set_compand()\n"); + return error_status; +} + +/** + * nomadik_acodec_enable_datapath_errcb + * + * This routine is not implemented yet + */ +t_codec_error nomadik_acodec_enable_datapath_errcb(codec_callback * + call_back_fn, u_long * data, t_acodec_user user) +{ + return CODEC_OK; +} + +/** + * nomadik_acodec_set_dataformat + * @codec_dfmt: data format bit mask. + * + * This routine sets the dtmf format. + */ +t_codec_error nomadik_acodec_set_dataformat(codec_dfmt * codec_dfmt, t_acodec_user user) +{ + DEBUG(1, " Entering nomadik_acodec_set_dataformat()\n"); + + if(g_cur_user == NO_USER) { + printk("WARNING : Audiocodec not yet configured by any user\n"); + return (CODEC_ERROR); + } + else if(g_cur_user != user) { + printk + ("ERROR : Trying to acces audiocodec already in use by user %d\n", g_cur_user); + return (CODEC_ERROR); + } + + if (NULL == codec_dfmt) { + printk("ERROR : passsing a NULL pointer for codec_dfmt \n"); + return CODEC_ERROR; + } + nomadik_acodec_conf->codec_data_format = *codec_dfmt; + DEBUG(1, " leaving nomadik_acodec_set_dataformat()\n"); + return CODEC_OK; +} + +/** + * nomadik_acodec_get_dataformat + * @codec_dfmt: data format bit mask. + * + * This routine gets the dtmf format as ser earlier . + */ +t_codec_error nomadik_acodec_get_dataformat(codec_dfmt * codec_dfmt, t_acodec_user user) +{ + DEBUG(1, " Entering nomadik_acodec_get_dataformat()\n"); + + if(g_cur_user == NO_USER) { + printk("WARNING : Audiocodec not yet configured by any user\n"); + return (CODEC_ERROR); + } + else if(g_cur_user != user) { + printk + ("ERROR : Trying to acces audiocodec already in use by user %d\n", g_cur_user); + return (CODEC_ERROR); + } + + if (NULL == codec_dfmt) { + return CODEC_ERROR; + } + *codec_dfmt = nomadik_acodec_conf->codec_data_format; + DEBUG(1, " leaving nomadik_acodec_get_dataformat()\n"); + return CODEC_OK; +} + +/** + * nomadik_acodec_enable_sidetone + * @gain - sidetone gain in db + * @reserved1 - reserved for future use only. + * @reserved2 - reserved for future use only. + * + * This routine enables the side tone to be mixed with record + * It is mot implemented yet. + */ +t_codec_error nomadik_acodec_enable_sidetone(int gain, u_long * reserved1, + u_long * reserved2, t_acodec_user user) +{ + t_codec_error error_status = CODEC_OK; + __u8 data; + int sidetone_gain; + DEBUG(1, " Entering nomadik_acodec_enable_sidetone\n"); + + if(g_cur_user == NO_USER) { + printk("WARNING : Audiocodec not yet configured by any user\n"); + return (CODEC_ERROR); + } + else if(g_cur_user != user) { + printk + ("ERROR : Trying to acces audiocodec already in use by user %d\n", g_cur_user); + return (CODEC_ERROR); + } + + nomadik_acodec_powerdown(ONE); + + if (RESET == gain) { + sidetone_gain = + set_sidetone_gain(nomadik_acodec_defaultconf-> + sidetone_gain); + } else { + sidetone_gain = set_sidetone_gain(gain); + } + /* close SI */ + data = SIDETONE_ENABLE | sidetone_gain; + error_status = + nomadik_i2c_write_register(I2C_AUDIO_CODEC_CLIENT, &data, CR5, 1); + if (error_status < 0) { + printk("ERROR : in writing CR5 thru I2C \n"); + return CODEC_ERROR; + } + nomadik_acodec_conf->sidetone_enable = true; + nomadik_acodec_conf->sidetone_gain = sidetone_gain; + + error_status = nomadik_acodec_powerup(); + if (error_status < 0) { + printk(" Failed to powerdown the acodec\n"); + return error_status; + } + DEBUG(1, " leaving nomadik_acodec_enable_sidetone\n"); + return error_status; +} + +/** + * nomadik_acodec_disable_sidetone - diables the side tone + */ +t_codec_error nomadik_acodec_disable_sidetone(t_acodec_user user) +{ + t_codec_error error_status = CODEC_OK; + __u8 data; + DEBUG(1, " Entering nomadik_acodec_disable_sidetone\n"); + if(g_cur_user == NO_USER) { + printk("WARNING : Audiocodec not yet configured by any user\n"); + return (CODEC_ERROR); + } + else if(g_cur_user != user) { + printk + ("ERROR : Trying to acces audiocodec already in use by user %d\n", g_cur_user); + return (CODEC_ERROR); + } + + /* open SI */ + data = ZERO; + error_status = + nomadik_i2c_write_register(I2C_AUDIO_CODEC_CLIENT, &data, CR5, 1); + if (error_status < 0) { + printk("ERROR : in writing CR5 thru I2C \n"); + return CODEC_ERROR; + } + nomadik_acodec_conf->sidetone_enable = false; + DEBUG(1, " leaving nomadik_acodec_disable_sidetone\n"); + return error_status; +} + +/** + * nomadik_acodec_select_input + * @input_device: MIC or linein. + * + * This routine selects the input device mic or linein. + */ +t_codec_error nomadik_acodec_select_input(t_codec_input_select input_device, t_acodec_user user) +{ + + t_codec_error error_status = CODEC_OK; + __u8 data = ZERO; + + DEBUG(1, " Entering nomadik_acodec_select_input\n"); + + if(g_cur_user == NO_USER) { + printk("WARNING : Audiocodec not yet configured by any user\n"); + return (CODEC_ERROR); + } + else if(g_cur_user != user) { + printk + ("ERROR : Trying to acces audiocodec already in use by user %d\n", g_cur_user); + return (CODEC_ERROR); + } + + nomadik_acodec_powerdown(ONE); + /*read first the CR4 */ + error_status = + nomadik_i2c_read_register(I2C_AUDIO_CODEC_CLIENT, &data, CR4, 1); + /* reset the mic selection bits */ + data &= 0x3F; + if (CODEC_SOURCE_RESET == input_device) { + data |= nomadik_acodec_defaultconf->codec_input; + } else { + data |= input_device; + nomadik_acodec_conf->codec_input = input_device; + } + error_status = + nomadik_i2c_write_register(I2C_AUDIO_CODEC_CLIENT, &data, CR4, 1); + if (error_status < 0) { + printk("ERROR : in writing CR5 thru I2C \n"); + return CODEC_ERROR; + } + error_status = nomadik_acodec_powerup(); + if (error_status < 0) { + printk(" Failed to powerdown the acodec\n"); + return error_status; + } + DEBUG(1, " leaving nomadik_acodec_select_input\n"); + return error_status; +} + +/** + * nomadik_acodec_select_output + * @output_device: output device HP/LSP + * + * This routine selects the output device Headphone or loud speaker + */ +t_codec_error nomadik_acodec_select_output(t_codec_output_select output_device, t_acodec_user user) +{ + + t_codec_error error_status = CODEC_OK; + __u8 data = ZERO; + + DEBUG(1, " Entering nomadik_acodec_select_output()\n"); + if(g_cur_user == NO_USER) { + printk("WARNING : Audiocodec not yet configured by any user\n"); + return (CODEC_ERROR); + } + else if(g_cur_user != user) { + printk + ("ERROR : Trying to acces audiocodec already in use by user %d\n", g_cur_user); + return (CODEC_ERROR); + } + + /* nomadik_acodec_powerdown(ONE); */ + error_status = + nomadik_i2c_read_register(I2C_AUDIO_CODEC_CLIENT, &data, CR6, 1); + if (error_status < 0) { + DEBUG(1, " error in reading CR6 thru I2C \n"); + return CODEC_ERROR; + } + // deselect all devices first + data &= ~(CODEC_DEST_NONE << ONE); + if (CODEC_DEST_RESET == output_device) { + data |= nomadik_acodec_defaultconf->codec_output; + } else if (CODEC_DEST_NONE == output_device) { + data &= ~(CODEC_DEST_NONE << ONE); + } else { + data |= output_device; + } + error_status = + nomadik_i2c_write_register(I2C_AUDIO_CODEC_CLIENT, &data, CR6, 1); + if (error_status < 0) { + DEBUG(1, " error in writing CR6 thru I2C \n"); + return CODEC_ERROR; + } + + /* nomadik_acodec_powerup(); */ + DEBUG(1, " leaving nomadik_acodec_select_output()\n"); + return error_status; +} + +/** + * nomadik_acodec_get_minvolume + * @input_min_vol - minimum volume supported by acodec for recording + * @output_min_vol - minimum volume supported by acodec for playback + * + * This routine returns the minimum volume possible for audiocodec */ +t_codec_error nomadik_acodec_get_minvolume(__u8 * input_min_vol, + __u8 * output_min_vol) +{ + /* for stw5094a DAC/ADC chip output volume gain can be with in 0 to 20. + * and input gain can very between 0 to 15. but to make user independent of + * the this range, min value and max value for voume are set as 0 and 100. + * the volume given by user is scaled down to the range available with codec + */ + DEBUG(1, " Entering nomadik_acodec_get_minvolume()\n"); + *input_min_vol = VOL_MIN; + *output_min_vol = VOL_MIN; + + DEBUG(1, " leaving nomadik_acodec_get_minvolume()\n"); + return CODEC_OK; +} + +/** + * nomadik_acodec_get_maxvolume + * @input_max_vol - maximum volume supported by acodec for recording + * @output_max_vol - maximum volume supported by acodec for playback + * + * This routine returns the maximum volume possible for audiocodec + */ +t_codec_error nomadik_acodec_get_maxvolume(__u8 * input_max_vol, + __u8 * output_max_vol) +{ + /* for stw5094a DAC/ADC chip output volume gain can be with in 0 to 20. + *and input gain can very between 0 to 15. but to make user independent of + *the this range, min value and max value for voume are set as 0 and 100. the + *volume given by user is scaled down to the range available with codec + */ + DEBUG(1, " Entering nomadik_acodec_get_maxvolume()\n"); + + *input_max_vol = VOL_MAX_MIC; + *output_max_vol = VOL_MAX; + + DEBUG(1, " leaving nomadik_acodec_get_maxvolume()\n"); + return CODEC_OK; +} + +/* + * nomadik_acodec_set_frequency + * @direction - in/out direction form audiocodec + * @record_sample_frequency - record frequency + * @play_sample_frequency: playback frequency + * + * This routine sets the freuency for audio codec and MSP + */ +t_codec_error nomadik_acodec_set_frequency(t_codec_direction direction, + t_codec_sample_frequency + input_frequency, + t_codec_sample_frequency + output_frequency, t_acodec_user user) +{ + t_codec_sample_frequency freq = ZERO; + t_codec_error error_status = CODEC_OK; + + DEBUG(1, " Entering nomadik_acodec_set_frequency()\n"); + + if(g_cur_user == NO_USER) { + printk("WARNING : Audiocodec not yet configured by any user\n"); + return (CODEC_ERROR); + } + else if(g_cur_user != user) { + printk + ("ERROR : Trying to acces audiocodec already in use by user %d\n", g_cur_user); + return (CODEC_ERROR); + } + + /* reset the frequency to default value if passed as RESET */ + if (CODEC_SAMPLING_FREQ_RESET == input_frequency) { + input_frequency = nomadik_acodec_defaultconf->record_frequency; + } else if (CODEC_FREQUENCY_DONT_CHANGE == input_frequency) { + input_frequency = nomadik_acodec_conf->record_frequency; + } + if (CODEC_SAMPLING_FREQ_RESET == output_frequency) { + output_frequency = nomadik_acodec_defaultconf->play_frequency; + } else if (CODEC_FREQUENCY_DONT_CHANGE == output_frequency) { + output_frequency = nomadik_acodec_conf->play_frequency; + } + + if (CODEC_DIRECTION_INOUT == direction) { + if (input_frequency != output_frequency) { + printk + ("ERROR : in inout mode two different frequencies are not supported\n"); + return CODEC_NOT_SUPPORTED; + } else { + freq = input_frequency; + /* if( CODEC_SAMPLING_FREQ_MINLIMIT freq ) { + input_frequency = output_frequency = CODEC_SAMPLING_FREQ_MINLIMIT + ONE; + return CODEC_BAD_VALUE; + }else if ( CODEC_SAMPLING_FREQ_MAXLIMIT freq ) { + input_frequency = output_frequency = CODEC_SAMPLING_FREQ_MAXLIMIT - ONE; + return CODEC_BAD_VALUE; + } + */ + nomadik_acodec_conf->record_frequency = freq; + nomadik_acodec_conf->play_frequency = freq; + } + } else if (CODEC_DIRECTION_IN == direction) { + freq = input_frequency; + /* if( CODEC_SAMPLING_FREQ_MINLIMIT >= freq ) { + input_frequency = output_frequency = CODEC_SAMPLING_FREQ_MINLIMIT + ONE; + return CODEC_BAD_VALUE; + }else if ( CODEC_SAMPLING_FREQ_MAXLIMIT <= freq ) { + input_frequency = output_frequency = CODEC_SAMPLING_FREQ_MAXLIMIT - ONE; + return CODEC_BAD_VALUE; + } + */ + nomadik_acodec_conf->record_frequency = freq; + } else { + freq = output_frequency; + /* if( CODEC_SAMPLING_FREQ_MINLIMIT >= freq ) { + input_frequency = output_frequency = CODEC_SAMPLING_FREQ_MINLIMIT + ONE; + return CODEC_BAD_VALUE; + }else if ( CODEC_SAMPLING_FREQ_MAXLIMIT <= freq ) { + input_frequency = output_frequency = CODEC_SAMPLING_FREQ_MAXLIMIT - ONE; + return CODEC_BAD_VALUE; + } + */ + nomadik_acodec_conf->play_frequency = freq; + } + + if (CODEC_MODE_VOICE == nomadik_acodec_conf->codec_mode) { + if (freq != CODEC_SAMPLING_FREQ_8KHZ + && freq != CODEC_SAMPLING_FREQ_16KHZ) { + printk + ("ERROR : Voice mode is tested on 8KHZ and 16KHZ only\n \ + try this freq on ur own risk\n"); + } + } + /*Powerdown AudioCode, preserving mode. */ + /* check whether power down and up is really needed. */ + /* Power down the audiocodec before setting the frequency */ + nomadik_acodec_powerdown(ONE); + + error_status = set_ock_frequency(freq); + if (CODEC_NOT_SUPPORTED == error_status) { + printk("ERROR : unable to set frequency \n"); + return error_status; + } + + /*PowerUp AudioCodec */ + error_status = nomadik_acodec_powerup(); + if (error_status < 0) { + printk(" Failed to powerdown the acodec\n"); + return error_status; + } + DEBUG(1, " leaving nomadik_acodec_set_frequency()\n"); + return CODEC_OK; +} + +/** + * nomadik_acodec_get_currentsettings + * + * This routine returns the codec_configuration structure + */ +t_codec_error nomadik_acodec_get_currentsettings(codec_configuration * + codec_conf, t_acodec_user user) +{ + DEBUG(1, " Entering nomadik_acodec_get_currentsettings()\n"); + if(g_cur_user == NO_USER) { + printk("WARNING : Audiocodec not yet configured by any user\n"); + return (CODEC_ERROR); + } + else if(g_cur_user != user) { + printk + ("ERROR : Trying to acces audiocodec already in use by user %d\n", g_cur_user); + return (CODEC_ERROR); + } + + if (NULL == codec_conf) { + printk("ERROR : NULL pointer passed \n"); + return CODEC_ERROR; + } + + *codec_conf = *nomadik_acodec_conf; + DEBUG(1, " leaving nomadik_acodec_get_currentsettings()\n"); + return (CODEC_OK); +} + +/** + * nomadik_acodec_set_currentsettings + * + * This routine sets the codec_configuration structure + */ +t_codec_error nomadik_acodec_set_currentsettings(codec_configuration * + codec_conf, t_acodec_user user) +{ + DEBUG(1, " Entering nomadik_acodec_set_currentsettings()\n"); + + if(g_cur_user == NO_USER) { + printk("WARNING : Audiocodec not yet configured by any user\n"); + return (CODEC_ERROR); + } + else if(g_cur_user != user) { + printk + ("ERROR : Trying to acces audiocodec already in use by user %d\n", g_cur_user); + return (CODEC_ERROR); + } + + *nomadik_acodec_conf = *codec_conf; + DEBUG(1, " leaving nomadik_acodec_set_currentsettings()\n"); + return CODEC_OK; +} + +/******************************************************************************* + * private functions + ******************************************************************************/ + +/* Calculate F1 or F2 from frequency given for DTMF tone generation */ + +int calculate_frequency(int freq) +{ + + __u8 f1; + __u8 base, incr; + + if (freq < 0) { + return CODEC_BAD_VALUE; + } else if (freq < 250) { + base = 0; + incr = (freq * 100) / 250; + + } else if (freq < 750) { + base = 64; + freq -= 250; + incr = (freq * 100) / 500; + + } else if (freq < 1750) { + base = 128; + freq -= 750; + incr = (freq * 100) / 1000; + + } else if (freq <= 3750) { + base = 192; + freq -= 1750; + incr = (freq * 100) / 2000; + + } else + return CODEC_BAD_VALUE; + + f1 = base + (incr * 64) / 100; + + return f1; +} + +/* gain calculation for tone gain */ + +int set_tone_gain(int vol) +{ + int volmax = 0, volmin = 0, volume = 0; + + if (vol < VOL_MIN || vol > VOL_MAX) { + DEBUG(1, " tone gain is out of range , vol = %x \n", vol); + return CODEC_BAD_VALUE; + } + + volmax = CODEC_TONE_GAIN_33DB; + volmin = CODEC_TONE_GAIN_0DB; + + /* since gain is negative */ + volume = VOL_MAX - vol; + volume *= (volmax - volmin); + volume /= 100; + volume += volmin; + + return volume; +} + +/* gain calculation for Side tone gain */ + +int set_sidetone_gain(int vol) +{ + int volmax = 0, volmin = 0, volume = 0; + + if (vol < VOL_MIN || vol > VOL_MAX) { + DEBUG(1, " tone gain is out of range , vol = %x \n", vol); + return CODEC_BAD_VALUE; + } + volmax = CODEC_SIDETONE_GAIN_27_5DB; + volmin = CODEC_SIDETONE_GAIN_12_5DB; + + /*since gain is negative */ + volume = VOL_MAX - vol; + volume *= (volmax - volmin); + volume /= 100; + volume += volmin; + + return volume; +} + +/* volume calculation for setVolume */ + +int set_volume(int vol) +{ + int volmax = 0, volmin = 0, volume = 0; + + if ((vol != DEFAULT && vol < VOL_MIN) || vol > VOL_MAX) { + DEBUG(1, " out volume is out of range , vol = %x \n", vol); + return CODEC_BAD_VALUE; + } + if (DEFAULT == vol) { + return DEFAULT; + } + volmax = CODEC_VOLUME_MAX; + volmin = CODEC_VOLUME_MIN; + + volume = vol; + /* Audiocodec volume range CODEC_VOLUME_MIN..CODEC_VOLUME_MAX */ + volume *= (volmax - volmin); + volume /= 100; + volume += volmin; + + vol = volume; + return vol; +} + +int set_volume_mic(int vol) +{ + __u8 volmax = 0, volmin = 0; + int volume = vol; + + if ((vol != DEFAULT && vol < VOL_MIN) || vol > VOL_MAX) { + return CODEC_BAD_VALUE; + } + if (DEFAULT == vol) { + return DEFAULT; + } + volmax = VOL_MAX_MIC; + volmin = VOL_MIN_MIC; + + volume *= (volmax - volmin); + volume /= 100; + + vol = volume; + + return vol; +} + + /* This routine calculates the OCK clock frequency depending on + sample frequency given by user. + */ +t_codec_error set_ock_frequency(t_codec_sample_frequency frequency) +{ + + t_codec_error error_status = CODEC_OK; + __u8 data; + __u8 cr_val[2]; + /* alot more frequencies also have to supported */ + DEBUG(2, " entered in set_ock_frequency \n"); + switch (frequency) { + + case (CODEC_SAMPLING_FREQ_96KHZ): + /* OCK = 41.856 Mhz */ + cr_val[0] = 0x80; + cr_val[1] = 0xA3; + break; + + case (CODEC_SAMPLING_FREQ_88KHZ): + /* OCK = 38.455 Mhz */ + cr_val[0] = 0x37; + cr_val[1] = 0x96; + break; + + case (CODEC_SAMPLING_FREQ_64KHZ): + /* OCK = 27.904 Mhz */ + cr_val[0] = 0x00; + cr_val[1] = 0x6D; + break; + + case (CODEC_SAMPLING_FREQ_48KHZ): + /* OCK = 20.971 Mhz */ + cr_val[0] = 0xEB; + cr_val[1] = 0x51; + break; + + case (CODEC_SAMPLING_FREQ_44KHZ): + /*OCK= 19.224 Mhz */ + cr_val[0] = 0x18; + cr_val[1] = 0x4B; + break; + + case (CODEC_SAMPLING_FREQ_32KHZ): + /*OCK = 13.981 Mhz */ + cr_val[0] = 0x9D; + cr_val[1] = 0x36; + break; + + case (CODEC_SAMPLING_FREQ_24KHZ): + /*OCK = 10.485 Mhz */ + cr_val[0] = 0xF5; + cr_val[1] = 0x28; + break; + + case (CODEC_SAMPLING_FREQ_22KHZ): + /* OCK = 9.663 MHz */ + cr_val[0] = 0xA1; + cr_val[1] = 0x25; + break; + + case (CODEC_SAMPLING_FREQ_16KHZ): + /*OCK = 6.990 Mhz */ + cr_val[0] = 0x4E; + cr_val[1] = 0x1B; + break; + + case (CODEC_SAMPLING_FREQ_12KHZ): + /*OCK = 5.242 Mhz */ + cr_val[0] = 0x7A; + cr_val[1] = 0x14; + break; + + case (CODEC_SAMPLING_FREQ_11KHZ): + /* OCK = 4.805 Mhz */ + cr_val[0] = 0xC5; + cr_val[1] = 0x12; + break; + + case (CODEC_SAMPLING_FREQ_8KHZ): + /*OCK = 3.495 Mhz */ + cr_val[0] = 0xA7; + cr_val[1] = 0x0D; + break; + + default: + return CODEC_NOT_SUPPORTED; + } + + data = AMCK_19_28_MHZ | VCM_OUTPUT; + error_status = + nomadik_i2c_write_register(I2C_AUDIO_CODEC_CLIENT, &data, CR18, 1); + if (CODEC_OK != error_status) { + printk("ERROR:SAA-DRV: failed in I2c read/write call\n"); + return error_status; + } + data = OCK_ENABLE; + error_status = + nomadik_i2c_write_register(I2C_AUDIO_CODEC_CLIENT, &data, CR17, 1); + if (CODEC_OK != error_status) { + printk("ERROR:SAA-DRV: failed in I2c read/write call\n"); + return error_status; + } + + error_status = nomadik_i2c_write_register(I2C_AUDIO_CODEC_CLIENT, + &cr_val[0], CR2AorCR2B, 1); + if (CODEC_OK != error_status) { + printk("ERROR:SAA-DRV: failed in I2c read/write call\n"); + return error_status; + } + + error_status = nomadik_i2c_write_register(I2C_AUDIO_CODEC_CLIENT, + &cr_val[1], CR3AorCR3B, 1); + if (CODEC_OK != error_status) { + printk("ERROR:SAA-DRV: failed in I2c read/write call\n"); + return error_status; + } + DEBUG(2, " exiting set_ock_frequency \n"); + + return error_status; +} + +/** + * nomadik_acodec_reset + * + * Reset the global variables and clear audiocodec settings to default. + */ +t_codec_error reset_nomadik_acodec(void) +{ + t_codec_error error_status; + __u8 cr21_val; + int i; + DEBUG(1, " Entering reset_nomadik_acodec()\n"); + cr21_val = 0x02; + error_status = + nomadik_i2c_write_register(I2C_AUDIO_CODEC_CLIENT, &cr21_val, CR21, + 1); + if (CODEC_OK != error_status) { + printk("ERROR:SAA-DRV: failed in I2c read/write call\n"); + return error_status; + } + /* wait a short before exit */ + for (i = 0; i < 1000000; i++) { + } + DEBUG(1, " leaving reset_nomadik_acodec()\n"); + return (error_status); +} + +module_init(nomadik_acodec_init); +module_exit(nomadik_acodec_deinit); + +MODULE_AUTHOR("Abhijit Singh"); +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Nomadik stw5094 audiocodec driver"); + +/* exported function by audiocodec */ + +EXPORT_SYMBOL(nmdk_acodec_rates); +EXPORT_SYMBOL(nomadik_acodec_setuser); +EXPORT_SYMBOL(nomadik_acodec_unsetuser); +EXPORT_SYMBOL(nomadik_acodec_enable_audio_mode); +EXPORT_SYMBOL(nomadik_acodec_enable_voice_mode); +EXPORT_SYMBOL(nomadik_acodec_set_frequency); +EXPORT_SYMBOL(nomadik_acodec_get_maxvolume); +EXPORT_SYMBOL(nomadik_acodec_get_minvolume); +EXPORT_SYMBOL(nomadik_acodec_set_volume); +EXPORT_SYMBOL(nomadik_acodec_select_input); +EXPORT_SYMBOL(nomadik_acodec_select_output); +EXPORT_SYMBOL(nomadik_acodec_powerup); +EXPORT_SYMBOL(nomadik_acodec_powerdown); +EXPORT_SYMBOL(nomadik_acodec_set_samplesize); +EXPORT_SYMBOL(nomadik_acodec_set_no_of_channels); +EXPORT_SYMBOL(nomadik_acodec_set_compand); +EXPORT_SYMBOL(nomadik_acodec_set_dataformat); +EXPORT_SYMBOL(nomadik_acodec_get_dataformat); +EXPORT_SYMBOL(nomadik_acodec_enable_datapath_errcb); +EXPORT_SYMBOL(nomadik_acodec_enable_sidetone); +EXPORT_SYMBOL(nomadik_acodec_disable_sidetone); +EXPORT_SYMBOL(nomadik_acodec_enable_bypassmode); +//EXPORT_SYMBOL(nomadik_acodec_disable_bypassmode); +EXPORT_SYMBOL(nomadik_acodec_enable_tonegeneratormode); +EXPORT_SYMBOL(nomadik_acodec_play_singletone); +EXPORT_SYMBOL(nomadik_acodec_play_dualtone); +EXPORT_SYMBOL(nomadik_acodec_stop_tone); +EXPORT_SYMBOL(nomadik_acodec_disable_tonegeneratormode); +EXPORT_SYMBOL(nomadik_acodec_get_currentsettings); +EXPORT_SYMBOL(nomadik_acodec_set_currentsettings); --- /dev/null +++ linux-2.6.20/sound/nomadik_stw5095.c @@ -0,0 +1,3529 @@ +/* sound/nomadik_stw5095.c + * + * Contains STW5095 AudioCodec implementation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +/*----------------------------------------------------------------------------- + * Common Includes + *---------------------------------------------------------------------------*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#define ELEMENT_SIZE 0 +#define FRAME_SIZE -1 +#define MSP_NUM 0 + +/* Debugging stuff */ +#ifndef CONFIG_DEBUG_USER +#define DEBUG_LEVEL 0 +#else +#define DEBUG_LEVEL 10 +#endif + +#if DEBUG_LEVEL > 0 +static int audiocodec_debug = DEBUG_LEVEL; +#define DEBUG(n, args...) do { if (audiocodec_debug>=(n)) printk(args); } while (0) +#else +#define DEBUG(n, args...) do { } while (0) +#endif +#define TRACE_ENTER(devname) DEBUG(4, "%s: -> " __FUNCTION__ "()\n", devname); +#define TRACE_EXIT(devname) DEBUG(4, "%s: <- " __FUNCTION__ "()\n", devname); + +/*---------------------------------------------------------------------------- + * Private functions + *--------------------------------------------------------------------------*/ + +t_codec_error nomadik_acodec_get_hwcapabilities(t_codec_hw_capability + hw_capability, + __u32 * p_supported_features, + __u32 * + p_configurable_features); +t_codec_error nomadik_acodec_set_hwcapabilities(t_codec_hw_capability + hw_capability, __u32 feature); +t_codec_error codec_set_direction(t_codec_direction codec_direction); +t_codec_error codec_stw5095_i2cwrite(__u8 register_address, __u16 data); + +/*---------------------------------------------------------------------------- + * global declarations + *---------------------------------------------------------------------------*/ +t_codec_system_context g_codec_system_context; + +/*--------------------------------------------------------------------------* + * Default Values * + *--------------------------------------------------------------------------*/ + +#define CODEC_DEFAULT_DIRECTION CODEC_DIRECTION_OUT + +#define CODEC_DEFAULT_MODE_IN CODEC_MODE_VOICE +#define CODEC_DEFAULT_MODE_OUT CODEC_MODE_VOICE + +#define CODEC_DEFAULT_RECORD_SAMPLE_FREQUENCY CODEC_SAMPLING_FREQ_8KHZ +#define CODEC_DEFAULT_PLAY_SAMPLE_FREQUENCY CODEC_SAMPLING_FREQ_8KHZ + +#define CODEC_DEFAULT_INPUT_SRC CODEC_SOURCE_MICROPHONE +#define CODEC_DEFAULT_OUTPUT_DEST CODEC_DEST_HEADPHONE + +#define CODEC_DEFAULT_VOLUME_LEFT_IN 100 +#define CODEC_DEFAULT_VOLUME_RIGHT_IN 100 +#define CODEC_DEFAULT_VOLUME_LEFT_OUT 100 +#define CODEC_DEFAULT_VOLUME_RIGHT_OUT 100 + +int nmdk_acodec_rates[] = + { 8000, 11000, 12000, 16000, 22000, 24000, 32000, 44000, 44100, 48000, + 64000, 88000, 96000 +}; + +t_codec_error codec_stw5095_i2cwrite(__u8 register_address, __u16 data) +{ + __u8 data_to_send = (__u8) data; + int error; + + error = + nomadik_i2c_write_register(I2C_AUDIO_CODEC_CLIENT, &data_to_send, + register_address, 1); + if (error) { + printk("AUDIOCODEC : I2C transaction failed on audiocode\n"); + return CODEC_TRANSACTION_ON_I2C_FAILED; + } + + return CODEC_OK; +} + +t_codec_error codec_stw5095_update_cr0(void) +{ + __u32 value = 0x00; + t_codec_configuration *p_codec_configuration = + &g_codec_system_context.codec_configuration; + + CODEC_WRITE_BITS(value, (__u32) p_codec_configuration->cr0_powerup, + CODEC_MASK_ONE_BIT, CODEC_STW5095_CR0_POWERUP); + CODEC_WRITE_BITS(value, (__u32) p_codec_configuration->cr0_enana, + CODEC_MASK_ONE_BIT, CODEC_STW5095_CR0_ENANA); + CODEC_WRITE_BITS(value, (__u32) p_codec_configuration->cr0_enamck, + CODEC_MASK_ONE_BIT, CODEC_STW5095_CR0_ENAMCK); + CODEC_WRITE_BITS(value, (__u32) p_codec_configuration->cr0_enosc, + CODEC_MASK_ONE_BIT, CODEC_STW5095_CR0_ENOSC); + CODEC_WRITE_BITS(value, (__u32) p_codec_configuration->cr0_enpll, + CODEC_MASK_ONE_BIT, CODEC_STW5095_CR0_ENPLL); + CODEC_WRITE_BITS(value, (__u32) p_codec_configuration->cr0_enhsd, + CODEC_MASK_ONE_BIT, CODEC_STW5095_CR0_ENHSD); + CODEC_WRITE_BITS(value, (__u32) p_codec_configuration->cr0_a24v, + CODEC_MASK_ONE_BIT, CODEC_STW5095_CR0_A24V); + CODEC_WRITE_BITS(value, (__u32) p_codec_configuration->cr0_d12v, + CODEC_MASK_ONE_BIT, CODEC_STW5095_CR0_D12V); + + return (codec_stw5095_i2cwrite(CODEC_STW5095_CR0, value)); +} + +t_codec_error codec_stw5095_update_cr1(void) +{ + __u32 value = 0x00; + t_codec_configuration *p_codec_configuration = + &g_codec_system_context.codec_configuration; + + CODEC_WRITE_BITS(value, (__u32) p_codec_configuration->cr1_enadcl, + CODEC_MASK_ONE_BIT, CODEC_STW5095_CR1_ENADCL); + CODEC_WRITE_BITS(value, (__u32) p_codec_configuration->cr1_enadcr, + CODEC_MASK_ONE_BIT, CODEC_STW5095_CR1_ENADCR); + CODEC_WRITE_BITS(value, (__u32) p_codec_configuration->cr1_endacl, + CODEC_MASK_ONE_BIT, CODEC_STW5095_CR1_ENDACL); + CODEC_WRITE_BITS(value, (__u32) p_codec_configuration->cr1_endacr, + CODEC_MASK_ONE_BIT, CODEC_STW5095_CR1_ENDACR); + CODEC_WRITE_BITS(value, (__u32) p_codec_configuration->cr1_enmicl, + CODEC_MASK_ONE_BIT, CODEC_STW5095_CR1_ENMICL); + CODEC_WRITE_BITS(value, (__u32) p_codec_configuration->cr1_enmicr, + CODEC_MASK_ONE_BIT, CODEC_STW5095_CR1_ENMICR); + CODEC_WRITE_BITS(value, (__u32) p_codec_configuration->cr1_enlinl, + CODEC_MASK_ONE_BIT, CODEC_STW5095_CR1_ENLINL); + CODEC_WRITE_BITS(value, (__u32) p_codec_configuration->cr1_enlinr, + CODEC_MASK_ONE_BIT, CODEC_STW5095_CR1_ENLINR); + + return (codec_stw5095_i2cwrite(CODEC_STW5095_CR1, value)); +} + +t_codec_error codec_stw5095_update_cr2(void) +{ + __u32 value = 0x00; + t_codec_configuration *p_codec_configuration = + &g_codec_system_context.codec_configuration; + + CODEC_WRITE_BITS(value, (__u32) p_codec_configuration->cr2_enlol, + CODEC_MASK_ONE_BIT, CODEC_STW5095_CR2_ENLOL); + CODEC_WRITE_BITS(value, (__u32) p_codec_configuration->cr2_enlor, + CODEC_MASK_ONE_BIT, CODEC_STW5095_CR2_ENLOR); + CODEC_WRITE_BITS(value, (__u32) p_codec_configuration->cr2_enhpl, + CODEC_MASK_ONE_BIT, CODEC_STW5095_CR2_ENHPL); + CODEC_WRITE_BITS(value, (__u32) p_codec_configuration->cr2_enhpr, + CODEC_MASK_ONE_BIT, CODEC_STW5095_CR2_ENHPR); + CODEC_WRITE_BITS(value, (__u32) p_codec_configuration->cr2_enhpvcm, + CODEC_MASK_ONE_BIT, CODEC_STW5095_CR2_ENHPVCM); + CODEC_WRITE_BITS(value, (__u32) p_codec_configuration->cr2_enls, + CODEC_MASK_ONE_BIT, CODEC_STW5095_CR2_ENLS); + CODEC_WRITE_BITS(value, (__u32) p_codec_configuration->cr2_enmixl, + CODEC_MASK_ONE_BIT, CODEC_STW5095_CR2_ENMIXL); + CODEC_WRITE_BITS(value, (__u32) p_codec_configuration->cr2_enmixr, + CODEC_MASK_ONE_BIT, CODEC_STW5095_CR2_ENMIXR); + + return (codec_stw5095_i2cwrite(CODEC_STW5095_CR2, value)); +} + +t_codec_error codec_stw5095_update_cr3(void) +{ + __u32 value = 0x00; + t_codec_configuration *p_codec_configuration = + &g_codec_system_context.codec_configuration; + + CODEC_WRITE_BITS(value, (__u32) p_codec_configuration->cr3_micla, + CODEC_MASK_THREE_BITS, CODEC_STW5095_CR3_CR4_MICLRA); + CODEC_WRITE_BITS(value, (__u32) p_codec_configuration->cr3_miclg, + CODEC_MASK_FIVE_BITS, CODEC_STW5095_CR3_CR4_MICLRG); + + return (codec_stw5095_i2cwrite(CODEC_STW5095_CR3, value)); +} + +t_codec_error codec_stw5095_update_cr4(void) +{ + __u32 value = 0x00; + t_codec_configuration *p_codec_configuration = + &g_codec_system_context.codec_configuration; + + CODEC_WRITE_BITS(value, (__u32) p_codec_configuration->cr4_micra, + CODEC_MASK_THREE_BITS, CODEC_STW5095_CR3_CR4_MICLRA); + CODEC_WRITE_BITS(value, (__u32) p_codec_configuration->cr4_micrg, + CODEC_MASK_FIVE_BITS, CODEC_STW5095_CR3_CR4_MICLRG); + + return (codec_stw5095_i2cwrite(CODEC_STW5095_CR4, value)); +} + +t_codec_error codec_stw5095_update_cr5(void) +{ + __u32 value = 0x00; + t_codec_configuration *p_codec_configuration = + &g_codec_system_context.codec_configuration; + + CODEC_WRITE_BITS(value, (__u32) p_codec_configuration->cr5_linlg, + CODEC_MASK_FIVE_BITS, CODEC_STW5095_CR5_CR6_LINLRG); + + return (codec_stw5095_i2cwrite(CODEC_STW5095_CR5, value)); +} + +t_codec_error codec_stw5095_update_cr6(void) +{ + __u32 value = 0x00; + t_codec_configuration *p_codec_configuration = + &g_codec_system_context.codec_configuration; + + CODEC_WRITE_BITS(value, (__u32) p_codec_configuration->cr6_linrg, + CODEC_MASK_FIVE_BITS, CODEC_STW5095_CR5_CR6_LINLRG); + + return (codec_stw5095_i2cwrite(CODEC_STW5095_CR6, value)); +} + +t_codec_error codec_stw5095_update_cr7(void) +{ + __u32 value = 0x00; + t_codec_configuration *p_codec_configuration = + &g_codec_system_context.codec_configuration; + + CODEC_WRITE_BITS(value, (__u32) p_codec_configuration->cr7_log, + CODEC_MASK_THREE_BITS, CODEC_STW5095_CR7_LOG); + CODEC_WRITE_BITS(value, (__u32) p_codec_configuration->cr7_lsg, + CODEC_MASK_FOUR_BITS, CODEC_STW5095_CR7_LSG); + + return (codec_stw5095_i2cwrite(CODEC_STW5095_CR7, value)); +} + +t_codec_error codec_stw5095_update_cr8(void) +{ + __u32 value = 0x00; + t_codec_configuration *p_codec_configuration = + &g_codec_system_context.codec_configuration; + + CODEC_WRITE_BITS(value, (__u32) p_codec_configuration->cr8_hplg, + CODEC_MASK_FIVE_BITS, CODEC_STW5095_CR8_CR9_HPLRG); + + return (codec_stw5095_i2cwrite(CODEC_STW5095_CR8, value)); +} + +t_codec_error codec_stw5095_update_cr9(void) +{ + __u32 value = 0x00; + t_codec_configuration *p_codec_configuration = + &g_codec_system_context.codec_configuration; + + CODEC_WRITE_BITS(value, (__u32) p_codec_configuration->cr9_hprg, + CODEC_MASK_FIVE_BITS, CODEC_STW5095_CR8_CR9_HPLRG); + + return (codec_stw5095_i2cwrite(CODEC_STW5095_CR9, value)); +} + +t_codec_error codec_stw5095_update_cr10(void) +{ + __u32 value = 0x00; + t_codec_configuration *p_codec_configuration = + &g_codec_system_context.codec_configuration; + + CODEC_WRITE_BITS(value, (__u32) p_codec_configuration->cr10_daclg, + CODEC_MASK_SIX_BITS, CODEC_STW5095_CR10_CR11_DACLRG); + + return (codec_stw5095_i2cwrite(CODEC_STW5095_CR10, value)); +} + +t_codec_error codec_stw5095_update_cr11(void) +{ + __u32 value = 0x00; + t_codec_configuration *p_codec_configuration = + &g_codec_system_context.codec_configuration; + + CODEC_WRITE_BITS(value, (__u32) p_codec_configuration->cr11_dacrg, + CODEC_MASK_SIX_BITS, CODEC_STW5095_CR10_CR11_DACLRG); + + return (codec_stw5095_i2cwrite(CODEC_STW5095_CR11, value)); +} + +t_codec_error codec_stw5095_update_cr12(void) +{ + __u32 value = 0x00; + t_codec_configuration *p_codec_configuration = + &g_codec_system_context.codec_configuration; + + CODEC_WRITE_BITS(value, (__u32) p_codec_configuration->cr12_adclg, + CODEC_MASK_SIX_BITS, CODEC_STW5095_CR12_CR13_ADCLRG); + + return (codec_stw5095_i2cwrite(CODEC_STW5095_CR12, value)); +} + +t_codec_error codec_stw5095_update_cr13(void) +{ + __u32 value = 0x00; + t_codec_configuration *p_codec_configuration = + &g_codec_system_context.codec_configuration; + + CODEC_WRITE_BITS(value, (__u32) p_codec_configuration->cr13_adcrg, + CODEC_MASK_SIX_BITS, CODEC_STW5095_CR12_CR13_ADCLRG); + + return (codec_stw5095_i2cwrite(CODEC_STW5095_CR13, value)); +} + +t_codec_error codec_stw5095_update_cr14(void) +{ + __u32 value = 0x00; + t_codec_configuration *p_codec_configuration = + &g_codec_system_context.codec_configuration; + + CODEC_WRITE_BITS(value, (__u32) p_codec_configuration->cr14_dync, + CODEC_MASK_ONE_BIT, CODEC_STW5095_CR14_DYNC); + CODEC_WRITE_BITS(value, (__u32) p_codec_configuration->cr14_treble, + CODEC_MASK_THREE_BITS, CODEC_STW5095_CR14_TREBLE); + CODEC_WRITE_BITS(value, (__u32) p_codec_configuration->cr14_bass, + CODEC_MASK_FOUR_BITS, CODEC_STW5095_CR14_BASS); + + return (codec_stw5095_i2cwrite(CODEC_STW5095_CR14, value)); +} + +t_codec_error codec_stw5095_update_cr15(void) +{ + __u32 value = 0x00; + t_codec_configuration *p_codec_configuration = + &g_codec_system_context.codec_configuration; + + CODEC_WRITE_BITS(value, (__u32) p_codec_configuration->cr15_da2adg, + CODEC_MASK_FIVE_BITS, CODEC_STW5095_CR15_DA2ADG); + + return (codec_stw5095_i2cwrite(CODEC_STW5095_CR15, value)); +} + +t_codec_error codec_stw5095_update_cr16(void) +{ + __u32 value = 0x00; + t_codec_configuration *p_codec_configuration = + &g_codec_system_context.codec_configuration; + + CODEC_WRITE_BITS(value, (__u32) p_codec_configuration->cr16_ad2dag, + CODEC_MASK_FIVE_BITS, CODEC_STW5095_CR16_AD2DAG); + + return (codec_stw5095_i2cwrite(CODEC_STW5095_CR16, value)); +} + +t_codec_error codec_stw5095_update_cr17(void) +{ + __u32 value = 0x00; + t_codec_configuration *p_codec_configuration = + &g_codec_system_context.codec_configuration; + + CODEC_WRITE_BITS(value, (__u32) p_codec_configuration->cr17_mbias, + CODEC_MASK_ONE_BIT, CODEC_STW5095_CR17_MBIAS); + CODEC_WRITE_BITS(value, (__u32) p_codec_configuration->cr17_mbiaspd, + CODEC_MASK_ONE_BIT, CODEC_STW5095_CR17_MBIASPD); + CODEC_WRITE_BITS(value, (__u32) p_codec_configuration->cr17_admic, + CODEC_MASK_ONE_BIT, CODEC_STW5095_CR17_ADMIC); + CODEC_WRITE_BITS(value, (__u32) p_codec_configuration->cr17_adlin, + CODEC_MASK_ONE_BIT, CODEC_STW5095_CR17_ADLIN); + CODEC_WRITE_BITS(value, (__u32) p_codec_configuration->cr17_mixmic, + CODEC_MASK_ONE_BIT, CODEC_STW5095_CR17_MIXMIC); + CODEC_WRITE_BITS(value, (__u32) p_codec_configuration->cr17_mixlin, + CODEC_MASK_ONE_BIT, CODEC_STW5095_CR17_MIXLIN); + CODEC_WRITE_BITS(value, (__u32) p_codec_configuration->cr17_mixdac, + CODEC_MASK_ONE_BIT, CODEC_STW5095_CR17_MIXDAC); + CODEC_WRITE_BITS(value, (__u32) p_codec_configuration->cr17_miclo, + CODEC_MASK_ONE_BIT, CODEC_STW5095_CR17_MICLO); + + return (codec_stw5095_i2cwrite(CODEC_STW5095_CR17, value)); +} + +t_codec_error codec_stw5095_update_cr18(void) +{ + __u32 value = 0x00; + t_codec_configuration *p_codec_configuration = + &g_codec_system_context.codec_configuration; + + CODEC_WRITE_BITS(value, (__u32) p_codec_configuration->cr18_in2vcm, + CODEC_MASK_ONE_BIT, CODEC_STW5095_CR18_IN2VCM); + CODEC_WRITE_BITS(value, (__u32) p_codec_configuration->cr18_linmute, + CODEC_MASK_ONE_BIT, CODEC_STW5095_CR18_LINMUTE); + CODEC_WRITE_BITS(value, (__u32) p_codec_configuration->cr18_linsel, + CODEC_MASK_TWO_BITS, CODEC_STW5095_CR18_LINSEL); + CODEC_WRITE_BITS(value, (__u32) p_codec_configuration->cr18_micmute, + CODEC_MASK_ONE_BIT, CODEC_STW5095_CR18_MICMUTE); + CODEC_WRITE_BITS(value, (__u32) p_codec_configuration->cr18_micsel, + CODEC_MASK_TWO_BITS, CODEC_STW5095_CR18_MICSEL); + + return (codec_stw5095_i2cwrite(CODEC_STW5095_CR18, value)); +} + +t_codec_error codec_stw5095_update_cr19(void) +{ + __u32 value = 0x00; + t_codec_configuration *p_codec_configuration = + &g_codec_system_context.codec_configuration; + + CODEC_WRITE_BITS(value, (__u32) p_codec_configuration->cr19_vcml, + CODEC_MASK_TWO_BITS, CODEC_STW5095_CR19_VCML); + CODEC_WRITE_BITS(value, (__u32) p_codec_configuration->cr19_difflo, + CODEC_MASK_ONE_BIT, CODEC_STW5095_CR19_DIFFLO); + CODEC_WRITE_BITS(value, (__u32) p_codec_configuration->cr19_mutelo, + CODEC_MASK_ONE_BIT, CODEC_STW5095_CR19_MUTELO); + CODEC_WRITE_BITS(value, (__u32) p_codec_configuration->cr19_mutehp, + CODEC_MASK_ONE_BIT, CODEC_STW5095_CR19_MUTEHP); + CODEC_WRITE_BITS(value, (__u32) p_codec_configuration->cr19_lslim, + CODEC_MASK_ONE_BIT, CODEC_STW5095_CR19_LSLIM); + CODEC_WRITE_BITS(value, (__u32) p_codec_configuration->cr19_lssel, + CODEC_MASK_TWO_BITS, CODEC_STW5095_CR19_LSSEL); + + return (codec_stw5095_i2cwrite(CODEC_STW5095_CR19, value)); +} + +t_codec_error codec_stw5095_update_cr20_C21(void) +{ + t_codec_error codec_error = CODEC_OK; + __u32 value = 0x00; + t_codec_configuration *p_codec_configuration = + &g_codec_system_context.codec_configuration; + + CODEC_WRITE_BITS(value, (__u32) p_codec_configuration->cr20_cr21_daockf, + CODEC_MASK_EIGHT_BITS, CODEC_STW5095_CR20_DAOCKF_LSB); + + codec_error = codec_stw5095_i2cwrite(CODEC_STW5095_CR20, value); + if (CODEC_OK != codec_error) + return (codec_error); + + value = 0x00; + + CODEC_WRITE_BITS(value, + (__u32) (p_codec_configuration->cr20_cr21_daockf >> 8), + CODEC_MASK_EIGHT_BITS, CODEC_STW5095_CR21_DAOCKF_MSB); + + codec_error = codec_stw5095_i2cwrite(CODEC_STW5095_CR21, value); + + return (codec_error); +} + +t_codec_error codec_stw5095_update_cr23_C24(void) +{ + t_codec_error codec_error = CODEC_OK; + __u32 value = 0x00; + t_codec_configuration *p_codec_configuration = + &g_codec_system_context.codec_configuration; + + CODEC_WRITE_BITS(value, (__u32) p_codec_configuration->cr23_cr24_adockf, + CODEC_MASK_EIGHT_BITS, CODEC_STW5095_CR23_ADOCKF_LSB); + + codec_error = codec_stw5095_i2cwrite(CODEC_STW5095_CR23, value); + if (CODEC_OK != codec_error) + return (codec_error); + + value = 0x00; + + CODEC_WRITE_BITS(value, + (__u32) (p_codec_configuration->cr23_cr24_adockf >> 8), + CODEC_MASK_EIGHT_BITS, CODEC_STW5095_CR24_ADOCKF_MSB); + + codec_error = codec_stw5095_i2cwrite(CODEC_STW5095_CR24, value); + + return (codec_error); +} + +t_codec_error codec_stw5095_update_cr22(void) +{ + __u32 value = 0x00; + t_codec_configuration *p_codec_configuration = + &g_codec_system_context.codec_configuration; + + CODEC_WRITE_BITS(value, (__u32) p_codec_configuration->cr22_damast, + CODEC_MASK_ONE_BIT, CODEC_STW5095_CR22_DAMAST); + CODEC_WRITE_BITS(value, (__u32) p_codec_configuration->cr22_damastgen, + CODEC_MASK_ONE_BIT, CODEC_STW5095_CR22_DAMASTGEN); + CODEC_WRITE_BITS(value, (__u32) p_codec_configuration->cr22_endaock, + CODEC_MASK_ONE_BIT, CODEC_STW5095_CR22_ENDAOCK); + CODEC_WRITE_BITS(value, (__u32) p_codec_configuration->cr22_daock512, + CODEC_MASK_ONE_BIT, CODEC_STW5095_CR22_DAOCK512); + CODEC_WRITE_BITS(value, (__u32) p_codec_configuration->cr22_dapcmf, + CODEC_MASK_TWO_BITS, CODEC_STW5095_CR22_DAPCMF); + + return (codec_stw5095_i2cwrite(CODEC_STW5095_CR22, value)); +} + +t_codec_error codec_stw5095_update_cr25(void) +{ + __u32 value = 0x00; + t_codec_configuration *p_codec_configuration = + &g_codec_system_context.codec_configuration; + + CODEC_WRITE_BITS(value, (__u32) p_codec_configuration->cr25_admast, + CODEC_MASK_ONE_BIT, CODEC_STW5095_CR25_ADMAST); + CODEC_WRITE_BITS(value, (__u32) p_codec_configuration->cr25_admastgen, + CODEC_MASK_ONE_BIT, CODEC_STW5095_CR25_ADMASTGEN); + CODEC_WRITE_BITS(value, (__u32) p_codec_configuration->cr25_endaock, + CODEC_MASK_ONE_BIT, CODEC_STW5095_CR25_ENADOCK); + CODEC_WRITE_BITS(value, (__u32) p_codec_configuration->cr25_adock512, + CODEC_MASK_ONE_BIT, CODEC_STW5095_CR25_ADOCK512); + CODEC_WRITE_BITS(value, (__u32) p_codec_configuration->cr25_adpcmf, + CODEC_MASK_TWO_BITS, CODEC_STW5095_CR25_ADPCMF); + + return (codec_stw5095_i2cwrite(CODEC_STW5095_CR25, value)); +} + +t_codec_error codec_stw5095_update_cr26(void) +{ + __u32 value = 0x00; + t_codec_configuration *p_codec_configuration = + &g_codec_system_context.codec_configuration; + + CODEC_WRITE_BITS(value, (__u32) p_codec_configuration->cr26_dachsw, + CODEC_MASK_ONE_BIT, CODEC_STW5095_CR26_DACHSW); + CODEC_WRITE_BITS(value, (__u32) p_codec_configuration->cr26_daform, + CODEC_MASK_THREE_BITS, CODEC_STW5095_CR26_DAFORM); + CODEC_WRITE_BITS(value, (__u32) p_codec_configuration->cr26_daspim, + CODEC_MASK_ONE_BIT, CODEC_STW5095_CR26_DASPIM); + CODEC_WRITE_BITS(value, (__u32) p_codec_configuration->cr26_dawl, + CODEC_MASK_THREE_BITS, CODEC_STW5095_CR26_DAWL); + + return (codec_stw5095_i2cwrite(CODEC_STW5095_CR26, value)); +} + +t_codec_error codec_stw5095_update_cr27(void) +{ + __u32 value = 0x00; + t_codec_configuration *p_codec_configuration = + &g_codec_system_context.codec_configuration; + + CODEC_WRITE_BITS(value, (__u32) p_codec_configuration->cr27_adchsw, + CODEC_MASK_ONE_BIT, CODEC_STW5095_CR27_ADCHSW); + CODEC_WRITE_BITS(value, (__u32) p_codec_configuration->cr27_adform, + CODEC_MASK_THREE_BITS, CODEC_STW5095_CR27_ADFORM); + CODEC_WRITE_BITS(value, (__u32) p_codec_configuration->cr27_adspim, + CODEC_MASK_ONE_BIT, CODEC_STW5095_CR27_ADSPIM); + CODEC_WRITE_BITS(value, (__u32) p_codec_configuration->cr27_adwl, + CODEC_MASK_THREE_BITS, CODEC_STW5095_CR27_ADWL); + + return (codec_stw5095_i2cwrite(CODEC_STW5095_CR27, value)); +} + +t_codec_error codec_stw5095_update_cr28(void) +{ + __u32 value = 0x00; + t_codec_configuration *p_codec_configuration = + &g_codec_system_context.codec_configuration; + + CODEC_WRITE_BITS(value, (__u32) p_codec_configuration->cr28_amckinv, + CODEC_MASK_ONE_BIT, CODEC_STW5095_CR28_AMCKINV); + CODEC_WRITE_BITS(value, (__u32) p_codec_configuration->cr28_dackp, + CODEC_MASK_ONE_BIT, CODEC_STW5095_CR28_DACKP); + CODEC_WRITE_BITS(value, (__u32) p_codec_configuration->cr28_dasyncp, + CODEC_MASK_ONE_BIT, CODEC_STW5095_CR28_DASYNCP); + CODEC_WRITE_BITS(value, (__u32) p_codec_configuration->cr28_damono, + CODEC_MASK_ONE_BIT, CODEC_STW5095_CR28_DAMONO); + CODEC_WRITE_BITS(value, (__u32) p_codec_configuration->cr28_adckp, + CODEC_MASK_ONE_BIT, CODEC_STW5095_CR28_ADCKP); + CODEC_WRITE_BITS(value, (__u32) p_codec_configuration->cr28_adsyncp, + CODEC_MASK_ONE_BIT, CODEC_STW5095_CR28_ADSYNCP); + CODEC_WRITE_BITS(value, (__u32) p_codec_configuration->cr28_admono, + CODEC_MASK_ONE_BIT, CODEC_STW5095_CR28_ADMONO); + CODEC_WRITE_BITS(value, (__u32) p_codec_configuration->cr28_adhiz, + CODEC_MASK_ONE_BIT, CODEC_STW5095_CR28_ADHIZ); + + return (codec_stw5095_i2cwrite(CODEC_STW5095_CR28, value)); +} + +t_codec_error codec_stw5095_update_cr29(void) +{ + __u32 value = 0x00; + t_codec_configuration *p_codec_configuration = + &g_codec_system_context.codec_configuration; + + CODEC_WRITE_BITS(value, (__u32) p_codec_configuration->cr29_davoice, + CODEC_MASK_ONE_BIT, CODEC_STW5095_CR29_DAVOICE); + CODEC_WRITE_BITS(value, (__u32) p_codec_configuration->cr29_da96k, + CODEC_MASK_ONE_BIT, CODEC_STW5095_CR29_DA96K); + CODEC_WRITE_BITS(value, (__u32) p_codec_configuration->cr29_rxnh, + CODEC_MASK_ONE_BIT, CODEC_STW5095_CR29_RXNH); + CODEC_WRITE_BITS(value, (__u32) p_codec_configuration->cr29_advoice, + CODEC_MASK_ONE_BIT, CODEC_STW5095_CR29_ADVOICE); + CODEC_WRITE_BITS(value, (__u32) p_codec_configuration->cr29_ad96k, + CODEC_MASK_ONE_BIT, CODEC_STW5095_CR29_AD96K); + CODEC_WRITE_BITS(value, (__u32) p_codec_configuration->cr29_adnh, + CODEC_MASK_ONE_BIT, CODEC_STW5095_CR29_ADNH); + CODEC_WRITE_BITS(value, (__u32) p_codec_configuration->cr29_txnh, + CODEC_MASK_ONE_BIT, CODEC_STW5095_CR29_TXNH); + + return (codec_stw5095_i2cwrite(CODEC_STW5095_CR29, value)); +} + +t_codec_error codec_stw5095_update_cr30(void) +{ + __u32 value = 0x00; + t_codec_configuration *p_codec_configuration = + &g_codec_system_context.codec_configuration; + + CODEC_WRITE_BITS(value, (__u32) p_codec_configuration->cr30_swres, + CODEC_MASK_ONE_BIT, CODEC_STW5095_CR30_SWRES); + CODEC_WRITE_BITS(value, (__u32) p_codec_configuration->cr30_amcksin, + CODEC_MASK_ONE_BIT, CODEC_STW5095_CR30_AMCKSIN); + CODEC_WRITE_BITS(value, (__u32) p_codec_configuration->cr30_ckrange, + CODEC_MASK_THREE_BITS, CODEC_STW5095_CR30_CKRANGE); + + return (codec_stw5095_i2cwrite(CODEC_STW5095_CR30, value)); +} + +t_codec_error codec_stw5095_update_cr31(void) +{ + __u32 value = 0x00; + t_codec_configuration *p_codec_configuration = + &g_codec_system_context.codec_configuration; + + CODEC_WRITE_BITS(value, (__u32) p_codec_configuration->cr31_vlshen, + CODEC_MASK_ONE_BIT, CODEC_STW5095_CR31_VLSHEN); + CODEC_WRITE_BITS(value, (__u32) p_codec_configuration->cr31_pushben, + CODEC_MASK_ONE_BIT, CODEC_STW5095_CR31_PUSHBEN); + CODEC_WRITE_BITS(value, (__u32) p_codec_configuration->cr31_hsdeten, + CODEC_MASK_ONE_BIT, CODEC_STW5095_CR31_HSDETEN); + CODEC_WRITE_BITS(value, (__u32) p_codec_configuration->cr31_vlshmsk, + CODEC_MASK_ONE_BIT, CODEC_STW5095_CR31_VLSHMSK); + CODEC_WRITE_BITS(value, (__u32) p_codec_configuration->cr31_pushbmsk, + CODEC_MASK_ONE_BIT, CODEC_STW5095_CR31_PUSHBMSK); + CODEC_WRITE_BITS(value, (__u32) p_codec_configuration->cr31_hsdetmsk, + CODEC_MASK_ONE_BIT, CODEC_STW5095_CR31_HSDETMSK); + CODEC_WRITE_BITS(value, (__u32) p_codec_configuration->cr31_ovfmsk, + CODEC_MASK_ONE_BIT, CODEC_STW5095_CR31_OVFMSK); + CODEC_WRITE_BITS(value, (__u32) p_codec_configuration->cr31_pormsk, + CODEC_MASK_ONE_BIT, CODEC_STW5095_CR31_PORMSK); + + return (codec_stw5095_i2cwrite(CODEC_STW5095_CR31, value)); +} + +/* CR32 is read only register */ +t_codec_error codec_stw5095_update_cr33(void) +{ + __u32 value = 0x00; + t_codec_configuration *p_codec_configuration = + &g_codec_system_context.codec_configuration; + + CODEC_WRITE_BITS(value, (__u32) p_codec_configuration->cr33_spiohiz, + CODEC_MASK_ONE_BIT, CODEC_STW5095_CR33_SPIOHIZ); + CODEC_WRITE_BITS(value, (__u32) p_codec_configuration->cr33_spiosel, + CODEC_MASK_TWO_BITS, CODEC_STW5095_CR33_SPIOSEL); + CODEC_WRITE_BITS(value, (__u32) p_codec_configuration->cr33_irqcmos, + CODEC_MASK_ONE_BIT, CODEC_STW5095_CR33_IRQCMOS); + CODEC_WRITE_BITS(value, (__u32) p_codec_configuration->cr33_ovfda, + CODEC_MASK_ONE_BIT, CODEC_STW5095_CR33_OVFDA); + CODEC_WRITE_BITS(value, (__u32) p_codec_configuration->cr33_ovfad, + CODEC_MASK_ONE_BIT, CODEC_STW5095_CR33_OVFAD); + + return (codec_stw5095_i2cwrite(CODEC_STW5095_CR33, value)); +} + +t_codec_error codec_stw5095_reset(void) +{ + t_codec_error codec_error = CODEC_OK; + t_codec_configuration *p_codec_configuration = + &g_codec_system_context.codec_configuration; + + p_codec_configuration->cr30_swres = + CODEC_STW5095_CR30_SWRES_SOFTWARE_RESET; + + codec_error = codec_stw5095_update_cr30(); + if (CODEC_OK != codec_error) + return (codec_error); + + p_codec_configuration->cr30_swres = + CODEC_STW5095_CR30_SWRES_NON_RESET_STATE; + + codec_error = codec_stw5095_update_cr30(); + if (CODEC_OK != codec_error) + return (codec_error); + + p_codec_configuration->cr0_powerup = CODEC_STW5095_CR0_POWERUP_OFF; + p_codec_configuration->cr0_enana = CODEC_STW5095_CR0_ENANA_ON; + p_codec_configuration->cr0_enamck = CODEC_STW5095_CR0_ENAMCK_ON; + p_codec_configuration->cr0_enosc = CODEC_STW5095_CR0_ENOSC_OFF; + p_codec_configuration->cr0_enpll = CODEC_STW5095_CR0_ENPLL_ON; +#if defined (CONFIG_NOMADIK_NHK15)/*FIXME - remove it later*/ + p_codec_configuration->cr0_enhsd = CODEC_STW5095_CR0_ENHSD_ON; +#else + p_codec_configuration->cr0_enhsd = CODEC_STW5095_CR0_ENHSD_OFF; +#endif + p_codec_configuration->cr0_a24v = CODEC_STW5095_CR0_A24V_27_33V; + p_codec_configuration->cr0_d12v = CODEC_STW5095_CR0_D12V_12_18; + + codec_error = codec_stw5095_update_cr0(); + if (CODEC_OK != codec_error) + return (codec_error); + + p_codec_configuration->cr1_enadcl = CODEC_STW5095_CR1_ENADCL_ENABLED; + p_codec_configuration->cr1_enadcr = CODEC_STW5095_CR1_ENADCR_ENABLED; + p_codec_configuration->cr1_endacl = CODEC_STW5095_CR1_ENDACL_ENABLED; + p_codec_configuration->cr1_endacr = CODEC_STW5095_CR1_ENDACR_ENABLED; + p_codec_configuration->cr1_enmicl = CODEC_STW5095_CR1_ENMICL_ENABLED; + p_codec_configuration->cr1_enmicr = CODEC_STW5095_CR1_ENMICR_ENABLED; + p_codec_configuration->cr1_enlinl = CODEC_STW5095_CR1_ENLINL_ENABLED; + p_codec_configuration->cr1_enlinr = CODEC_STW5095_CR1_ENLINR_ENABLED; + + codec_error = codec_stw5095_update_cr1(); + if (CODEC_OK != codec_error) + return (codec_error); + + p_codec_configuration->cr2_enlol = CODEC_STW5095_CR2_ENLOL_DISABLED; + p_codec_configuration->cr2_enlor = CODEC_STW5095_CR2_ENLOR_DISABLED; + p_codec_configuration->cr2_enhpl = CODEC_STW5095_CR2_ENHPL_DISABLED; + p_codec_configuration->cr2_enhpr = CODEC_STW5095_CR2_ENHPR_DISABLED; + p_codec_configuration->cr2_enhpvcm = CODEC_STW5095_CR2_ENHPVCM_ENABLED; + p_codec_configuration->cr2_enls = CODEC_STW5095_CR2_ENLS_DISABLED; + p_codec_configuration->cr2_enmixl = CODEC_STW5095_CR2_ENMIXL_DISABLED; + p_codec_configuration->cr2_enmixr = CODEC_STW5095_CR2_ENMIXR_DISABLED; + + p_codec_configuration->cr2_enlol = CODEC_STW5095_CR2_ENLOL_ENABLED; + p_codec_configuration->cr2_enlor = CODEC_STW5095_CR2_ENLOR_ENABLED; + p_codec_configuration->cr2_enhpl = CODEC_STW5095_CR2_ENHPL_ENABLED; + p_codec_configuration->cr2_enhpr = CODEC_STW5095_CR2_ENHPR_ENABLED; + p_codec_configuration->cr2_enhpvcm = CODEC_STW5095_CR2_ENHPVCM_ENABLED; + p_codec_configuration->cr2_enls = CODEC_STW5095_CR2_ENLS_ENABLED; + p_codec_configuration->cr2_enmixl = CODEC_STW5095_CR2_ENMIXL_ENABLED; + p_codec_configuration->cr2_enmixr = CODEC_STW5095_CR2_ENMIXR_ENABLED; + + codec_error = codec_stw5095_update_cr2(); + if (CODEC_OK != codec_error) + return (codec_error); + + p_codec_configuration->cr3_micla = 0; + p_codec_configuration->cr3_miclg = 0x1a; + + codec_error = codec_stw5095_update_cr3(); + if (CODEC_OK != codec_error) + return (codec_error); + + p_codec_configuration->cr4_micra = 0; + p_codec_configuration->cr4_micrg = 0x1a; + + codec_error = codec_stw5095_update_cr4(); + if (CODEC_OK != codec_error) + return (codec_error); + + p_codec_configuration->cr5_linlg = 0; + + codec_error = codec_stw5095_update_cr5(); + if (CODEC_OK != codec_error) + return (codec_error); + + p_codec_configuration->cr6_linrg = 0; + + codec_error = codec_stw5095_update_cr6(); + if (CODEC_OK != codec_error) + return (codec_error); + + p_codec_configuration->cr7_log = 6; + + codec_error = codec_stw5095_update_cr7(); + if (CODEC_OK != codec_error) + return (codec_error); + + p_codec_configuration->cr8_hplg = 0; + + codec_error = codec_stw5095_update_cr8(); + if (CODEC_OK != codec_error) + return (codec_error); + + p_codec_configuration->cr9_hprg = 0; + + codec_error = codec_stw5095_update_cr9(); + if (CODEC_OK != codec_error) + return (codec_error); + + p_codec_configuration->cr10_daclg = 0; + + codec_error = codec_stw5095_update_cr10(); + if (CODEC_OK != codec_error) + return (codec_error); + + p_codec_configuration->cr11_dacrg = 0; + + codec_error = codec_stw5095_update_cr11(); + if (CODEC_OK != codec_error) + return (codec_error); + + p_codec_configuration->cr12_adclg = 8; + + codec_error = codec_stw5095_update_cr12(); + if (CODEC_OK != codec_error) + return (codec_error); + + p_codec_configuration->cr13_adcrg = 8; + + codec_error = codec_stw5095_update_cr13(); + if (CODEC_OK != codec_error) + return (codec_error); + + p_codec_configuration->cr14_dync = CODEC_STW5095_CR14_DYNC_ENABLED; + p_codec_configuration->cr14_treble = 0; + p_codec_configuration->cr14_bass = 0; + + codec_error = codec_stw5095_update_cr14(); + if (CODEC_OK != codec_error) + return (codec_error); + + p_codec_configuration->cr15_da2adg = 0; + + codec_error = codec_stw5095_update_cr15(); + if (CODEC_OK != codec_error) + return (codec_error); + + p_codec_configuration->cr16_ad2dag = 0; + + codec_error = codec_stw5095_update_cr16(); + if (CODEC_OK != codec_error) + return (codec_error); + + p_codec_configuration->cr17_mbias = CODEC_STW5095_CR17_MBIAS_ENABLED; + p_codec_configuration->cr17_mbiaspd = + CODEC_STW5095_CR17_MBIASPD_DISABLED; + p_codec_configuration->cr17_admic = CODEC_STW5095_CR17_ADMIC_DISABLED; + p_codec_configuration->cr17_adlin = CODEC_STW5095_CR17_ADLIN_DISABLED; + p_codec_configuration->cr17_mixmic = CODEC_STW5095_CR17_MIXMIC_DISABLED; + p_codec_configuration->cr17_mixlin = CODEC_STW5095_CR17_MIXLIN_DISABLED; + p_codec_configuration->cr17_mixdac = CODEC_STW5095_CR17_MIXDAC_DISABLED; + p_codec_configuration->cr17_miclo = CODEC_STW5095_CR17_MICLO_DISABLED; + + p_codec_configuration->cr17_mbias = CODEC_STW5095_CR17_MBIAS_ENABLED; + p_codec_configuration->cr17_mbiaspd = + CODEC_STW5095_CR17_MBIASPD_DISABLED; + p_codec_configuration->cr17_admic = CODEC_STW5095_CR17_ADMIC_ENABLED; + p_codec_configuration->cr17_adlin = CODEC_STW5095_CR17_ADLIN_ENABLED; + + p_codec_configuration->cr17_mixmic = CODEC_STW5095_CR17_MIXMIC_DISABLED; + p_codec_configuration->cr17_mixlin = CODEC_STW5095_CR17_MIXLIN_DISABLED; + p_codec_configuration->cr17_mixdac = CODEC_STW5095_CR17_MIXDAC_ENABLED; + p_codec_configuration->cr17_miclo = CODEC_STW5095_CR17_MICLO_ENABLED; + codec_error = codec_stw5095_update_cr17(); + if (CODEC_OK != codec_error) + return (codec_error); + + p_codec_configuration->cr18_in2vcm = + CODEC_STW5095_CR18_IN2VCM_HIGH_IMPEDANCE_STATE; + p_codec_configuration->cr18_linmute = + CODEC_STW5095_CR18_LINMUTE_ENABLED; + p_codec_configuration->cr18_linsel = CODEC_STW5095_CR18_LINSEL_LINEIN; + p_codec_configuration->cr18_micmute = + CODEC_STW5095_CR18_MICMUTE_ENABLED; + p_codec_configuration->cr18_micsel = CODEC_STW5095_CR18_MICSEL_MIC; + + codec_error = codec_stw5095_update_cr18(); + if (CODEC_OK != codec_error) + return (codec_error); + + p_codec_configuration->cr19_vcml = CODEC_STW5095_CR19_VCML_1_35V; + p_codec_configuration->cr19_difflo = + CODEC_STW5095_CR19_DIFFLO_SINGLE_ENDED; + p_codec_configuration->cr19_mutelo = CODEC_STW5095_CR19_MUTELO_MUTED; + p_codec_configuration->cr19_mutehp = CODEC_STW5095_CR19_MUTEHP_MUTED; + p_codec_configuration->cr19_lslim = CODEC_STW5095_CR19_LSLIM_LIMITED; + p_codec_configuration->cr19_lssel = + CODEC_STW5095_CR19_LSSEL_MUTELOUDSPEAKER_DRIVER; + + codec_error = codec_stw5095_update_cr19(); + if (CODEC_OK != codec_error) + return (codec_error); + + p_codec_configuration->cr20_cr21_daockf = 0; + + codec_error = codec_stw5095_update_cr20_C21(); + if (CODEC_OK != codec_error) + return (codec_error); + + p_codec_configuration->cr23_cr24_adockf = 0; + + codec_error = codec_stw5095_update_cr23_C24(); + if (CODEC_OK != codec_error) + return (codec_error); + +#ifdef CONFIG_DA_MASTER + p_codec_configuration->cr22_damast = + CODEC_STW5095_CR22_DAMAST_MASTER_MODE; + p_codec_configuration->cr22_damastgen = + CODEC_STW5095_CR22_DAMASTGEN_ENABLED; +#else + + p_codec_configuration->cr22_damast = + CODEC_STW5095_CR22_DAMAST_SLAVE_MODE; + p_codec_configuration->cr22_damastgen = + CODEC_STW5095_CR22_DAMASTGEN_DISABLED; +#endif + p_codec_configuration->cr22_endaock = + CODEC_STW5095_CR22_ENDAOCK_DISABLED; + p_codec_configuration->cr22_daock512 = + CODEC_STW5095_CR22_DAOCK512_RATIO_IN_MASTER_MODE_256; + p_codec_configuration->cr22_dapcmf = + CODEC_STW5095_CR22_DAPCMF_RATIO_IN_PCM_MASTER_MODE_16_OR_32; + + codec_error = codec_stw5095_update_cr22(); + if (CODEC_OK != codec_error) + return (codec_error); + +#ifdef CONFIG_DA_MASTER + p_codec_configuration->cr25_admast = + CODEC_STW5095_CR25_ADMAST_MASTER_MODE; + p_codec_configuration->cr25_admastgen = + CODEC_STW5095_CR25_ADMASTGEN_ENABLED; +#else + p_codec_configuration->cr25_admast = + CODEC_STW5095_CR25_ADMAST_SLAVE_MODE; + p_codec_configuration->cr25_admastgen = + CODEC_STW5095_CR25_ADMASTGEN_DISABLED; +#endif + p_codec_configuration->cr25_endaock = + CODEC_STW5095_CR25_ENDAOCK_DISABLED; + p_codec_configuration->cr25_adock512 = + CODEC_STW5095_CR25_ADOCK512_RATIO_IN_MASTER_MODE_256; + p_codec_configuration->cr25_adpcmf = + CODEC_STW5095_CR25_ADPCMF_RATIO_IN_PCM_MASTER_MODE_16_OR_32; + + codec_error = codec_stw5095_update_cr25(); + if (CODEC_OK != codec_error) + return (codec_error); + + p_codec_configuration->cr26_dachsw = + CODEC_STW5095_CR26_DACHSW_LEFT_RIGHT_CHANNEL_NOT_EXCAHANGED; + p_codec_configuration->cr26_daform = + CODEC_STW5095_CR26_DAFORM_DELAYED_FORMAT_I2S_COMPATIBLE; + p_codec_configuration->cr26_daspim = + CODEC_STW5095_CR26_DASPIM_TWO_WORDS; + p_codec_configuration->cr26_dawl = + CODEC_STW5095_CR26_DAWL_WORD_LENGTH_16; + + codec_error = codec_stw5095_update_cr26(); + if (CODEC_OK != codec_error) + return (codec_error); + + p_codec_configuration->cr27_adchsw = + CODEC_STW5095_CR27_ADCHSW_LEFT_RIGHT_CHANNEL_NOT_EXCAHANGED; + p_codec_configuration->cr27_adform = + CODEC_STW5095_CR27_ADFORM_DELAYED_FORMAT_I2S_COMPATIBLE; + p_codec_configuration->cr27_adspim = + CODEC_STW5095_CR27_ADSPIM_TWO_WORDS; + p_codec_configuration->cr27_adwl = + CODEC_STW5095_CR27_ADWL_WORD_LENGTH_16; + + codec_error = codec_stw5095_update_cr27(); + if (CODEC_OK != codec_error) + return (codec_error); + + p_codec_configuration->cr28_amckinv = + CODEC_STW5095_CR28_AMCKINV_NOT_INVERTED; + p_codec_configuration->cr28_dackp = + CODEC_STW5095_CR28_DACKP_DA_CK_NOT_INVERTED; + p_codec_configuration->cr28_dasyncp = + CODEC_STW5095_CR28_DASYNCP_DELAYED_FORMAT_OR_DA_SYNC_POLARITY_INVERTED; + p_codec_configuration->cr28_damono = + CODEC_STW5095_CR28_DAMONO_STEREO_MODE; + p_codec_configuration->cr28_adckp = + CODEC_STW5095_CR28_ADCKP_AD_CK_NOT_INVERTED; + p_codec_configuration->cr28_adsyncp = + CODEC_STW5095_CR28_ADSYNCP_DELAYED_FORMAT_OR_AD_SYNC_POLARITY_INVERTED; + p_codec_configuration->cr28_admono = + CODEC_STW5095_CR28_ADMONO_STEREO_MODE; + p_codec_configuration->cr28_adhiz = + CODEC_STW5095_CR28_ADHIZ_AD_DATA_FORCED_TO_ZERO; + + codec_error = codec_stw5095_update_cr28(); + if (CODEC_OK != codec_error) + return (codec_error); + + p_codec_configuration->cr29_davoice = + CODEC_STW5095_CR29_DAVOICE_AUDIO_FILTER_ENABLED; + p_codec_configuration->cr29_da96k = + CODEC_STW5095_CR29_DA96K_DATA_RATE_RANGE_8_TO_48KHZ; + p_codec_configuration->cr29_rxnh = + CODEC_STW5095_CR29_RXNH_HIGH_PASS_VOICE_FILTER_DISABLED; + p_codec_configuration->cr29_advoice = + CODEC_STW5095_CR29_ADVOICE_AUDIO_FILTER_ENABLED; + p_codec_configuration->cr29_ad96k = + CODEC_STW5095_CR29_AD96K_DATA_RATE_RANGE_8_TO_48KHZ; + p_codec_configuration->cr29_adnh = + CODEC_STW5095_CR29_ADNH_AUDIO_DC_FILTER_DISABLED; + p_codec_configuration->cr29_txnh = + CODEC_STW5095_CR29_TXNH_HIGH_PASS_VOICE_FILTER_DISABLED; + + codec_error = codec_stw5095_update_cr29(); + if (CODEC_OK != codec_error) + return (codec_error); + + p_codec_configuration->cr30_swres = + CODEC_STW5095_CR30_SWRES_NON_RESET_STATE; + p_codec_configuration->cr30_amcksin = + CODEC_STW5095_CR30_AMCKSIN_SQUARE_WAVE; + p_codec_configuration->cr30_ckrange = + CODEC_STW5095_CR30_CKRANGE_24_TO_32_MHZ; + + codec_error = codec_stw5095_update_cr30(); + if (CODEC_OK != codec_error) + return (codec_error); + + p_codec_configuration->cr31_vlshen = CODEC_STW5095_CR31_VLSHEN_MASKED; + p_codec_configuration->cr31_pushben = CODEC_STW5095_CR31_PUSHBEN_MASKED; +#if !defined (CONFIG_NOMADIK_NHK15) /*FIXME - remove it later*/ + p_codec_configuration->cr31_hsdeten = CODEC_STW5095_CR31_HSDETEN_MASKED; +#else + p_codec_configuration->cr31_hsdeten = CODEC_STW5095_CR31_HSDETEN_ENABLED; +#endif + p_codec_configuration->cr31_vlshmsk = CODEC_STW5095_CR31_VLSHMSK_MASKED; + p_codec_configuration->cr31_pushbmsk = + CODEC_STW5095_CR31_PUSHBMSK_MASKED; + p_codec_configuration->cr31_hsdetmsk = + CODEC_STW5095_CR31_HSDETMSK_MASKED; + p_codec_configuration->cr31_ovfmsk = CODEC_STW5095_CR31_OVFMSK_MASKED; + p_codec_configuration->cr31_pormsk = CODEC_STW5095_CR31_PORMSK_MASKED; + + codec_error = codec_stw5095_update_cr31(); + if (CODEC_OK != codec_error) + return (codec_error); + + /* CR32 is readonly register */ + p_codec_configuration->cr33_spiohiz = + CODEC_STW5095_CR33_SPIOHIZ_OUT_PIN_HIGH_IMPEDANCE_WHEN_INACTIVE; + p_codec_configuration->cr33_spiosel = + CODEC_STW5095_CR33_SPIOSEL_NO_OUTPUT; + p_codec_configuration->cr33_irqcmos = + CODEC_STW5095_CR33_IRQCMOS_IRQ_PIN_PULL_DOWN; + p_codec_configuration->cr33_ovfda = + CODEC_STW5095_CR33_OVFDA_NO_OVERFLOW_IN_DA_PATH; + p_codec_configuration->cr33_ovfad = + CODEC_STW5095_CR33_OVFAD_NO_OVERFLOW_IN_AD_PATH; + + codec_error = codec_stw5095_update_cr33(); + if (CODEC_OK != codec_error) + return (codec_error); + + p_codec_configuration->cr0_powerup = CODEC_STW5095_CR0_POWERUP_ON; + + codec_error = codec_stw5095_update_cr0(); + if (CODEC_OK != codec_error) + return (codec_error); + + return (codec_error); +} + +__u32 codec_convert_samplefrequency_to_numericvalue(t_codec_sample_frequency + codec_sample_frequency) +{ + __u32 sample_frequency = 0; + + switch (codec_sample_frequency) { + case CODEC_SAMPLING_FREQ_8KHZ: + sample_frequency = 8000; + break; + + case CODEC_SAMPLING_FREQ_11KHZ: + sample_frequency = 11250; + break; + + case CODEC_SAMPLING_FREQ_12KHZ: + sample_frequency = 12000; + break; + + case CODEC_SAMPLING_FREQ_16KHZ: + sample_frequency = 16000; + break; + + case CODEC_SAMPLING_FREQ_22KHZ: + sample_frequency = 22050; + break; + + case CODEC_SAMPLING_FREQ_24KHZ: + sample_frequency = 24000; + break; + + case CODEC_SAMPLING_FREQ_32KHZ: + sample_frequency = 32000; + break; + + case CODEC_SAMPLING_FREQ_44KHZ: + sample_frequency = 44100; + break; + + case CODEC_SAMPLING_FREQ_48KHZ: + sample_frequency = 48000; + break; + + case CODEC_SAMPLING_FREQ_64KHZ: + sample_frequency = 64000; + break; + + case CODEC_SAMPLING_FREQ_88KHZ: + sample_frequency = 88200; + break; + + case CODEC_SAMPLING_FREQ_96KHZ: + sample_frequency = 96000; + break; + + case CODEC_SAMPLING_FREQ_128KHZ: + sample_frequency = 128000; + break; + + case CODEC_SAMPLING_FREQ_192KHZ: + sample_frequency = 192000; + break; + + default: + sample_frequency = 0; + break; + } + + return (sample_frequency); +} + +t_codec_error codec_program_direction(t_codec_direction codec_direction) +{ + t_codec_error codec_error = CODEC_OK; + t_codec_configuration *p_codec_configuration = + &g_codec_system_context.codec_configuration; + + p_codec_configuration = p_codec_configuration; + + if (CODEC_DIRECTION_IN == codec_direction) { + switch (g_codec_system_context.codec_src) { + case CODEC_SOURCE_LINEIN: + p_codec_configuration->cr1_enadcl = + CODEC_STW5095_CR1_ENADCL_ENABLED; + p_codec_configuration->cr1_enadcr = + CODEC_STW5095_CR1_ENADCR_ENABLED; + + p_codec_configuration->cr1_enlinl = + CODEC_STW5095_CR1_ENLINL_ENABLED; + p_codec_configuration->cr1_enlinr = + CODEC_STW5095_CR1_ENLINR_ENABLED; + p_codec_configuration->cr1_enmicl = + CODEC_STW5095_CR1_ENMICL_DISABLED; + p_codec_configuration->cr1_enmicr = + CODEC_STW5095_CR1_ENMICR_DISABLED; + p_codec_configuration->cr17_adlin = + CODEC_STW5095_CR17_ADLIN_ENABLED; + p_codec_configuration->cr17_admic = + CODEC_STW5095_CR17_ADMIC_DISABLED; + p_codec_configuration->cr18_linmute = + CODEC_STW5095_CR18_LINMUTE_DISABLED; + p_codec_configuration->cr18_micmute = + CODEC_STW5095_CR18_MICMUTE_ENABLED; + p_codec_configuration->cr18_linsel = + CODEC_STW5095_CR18_LINSEL_LINEIN; + break; + + case CODEC_SOURCE_MICROPHONE: + p_codec_configuration->cr1_enadcl = + CODEC_STW5095_CR1_ENADCL_ENABLED; + p_codec_configuration->cr1_enadcr = + CODEC_STW5095_CR1_ENADCR_ENABLED; + + p_codec_configuration->cr1_enlinl = + CODEC_STW5095_CR1_ENLINL_DISABLED; + p_codec_configuration->cr1_enlinr = + CODEC_STW5095_CR1_ENLINR_DISABLED; + p_codec_configuration->cr1_enmicl = + CODEC_STW5095_CR1_ENMICL_ENABLED; + p_codec_configuration->cr1_enmicr = + CODEC_STW5095_CR1_ENMICR_ENABLED; + p_codec_configuration->cr17_adlin = + CODEC_STW5095_CR17_ADLIN_DISABLED; + p_codec_configuration->cr17_admic = + CODEC_STW5095_CR17_ADMIC_ENABLED; + p_codec_configuration->cr18_linmute = + CODEC_STW5095_CR18_LINMUTE_DISABLED; //0 + p_codec_configuration->cr18_micmute = + CODEC_STW5095_CR18_MICMUTE_DISABLED; + p_codec_configuration->cr18_micsel = + CODEC_STW5095_CR18_MICSEL_AUX2; + + p_codec_configuration->cr17_mbias = + CODEC_STW5095_CR17_MBIAS_ENABLED; + p_codec_configuration->cr18_linsel= + CODEC_STW5095_CR18_LINSEL_AUX2; //10 + break; + + default: + break; + } + } + + if (CODEC_DIRECTION_OUT == codec_direction) { + switch (g_codec_system_context.codec_dest) { + case CODEC_DEST_LOUDSPEAKER: + p_codec_configuration->cr1_endacl = + CODEC_STW5095_CR1_ENDACL_ENABLED; + p_codec_configuration->cr1_endacr = + CODEC_STW5095_CR1_ENDACR_ENABLED; + p_codec_configuration->cr2_enlol = + CODEC_STW5095_CR2_ENLOL_DISABLED; + p_codec_configuration->cr2_enlor = + CODEC_STW5095_CR2_ENLOR_DISABLED; + p_codec_configuration->cr2_enhpl = + CODEC_STW5095_CR2_ENHPL_DISABLED; + p_codec_configuration->cr2_enhpr = + CODEC_STW5095_CR2_ENHPR_DISABLED; + p_codec_configuration->cr2_enhpvcm = + CODEC_STW5095_CR2_ENHPVCM_ENABLED; + + p_codec_configuration->cr19_mutehp = + CODEC_STW5095_CR19_MUTEHP_MUTED; + + p_codec_configuration->cr2_enls = + CODEC_STW5095_CR2_ENLS_ENABLED; + p_codec_configuration->cr19_lslim = + CODEC_STW5095_CR19_LSLIM_LIMITED; + p_codec_configuration->cr19_lssel = + CODEC_STW5095_CR19_LSSEL_MONO_LEFT_PLUS_RIGHT_DIV_2_CHANNEL; + + p_codec_configuration->cr19_mutelo = + CODEC_STW5095_CR19_MUTELO_MUTED; +#if defined (CONFIG_NOMADIK_NHK15)/*FIXME - remove it later*/ + p_codec_configuration->cr2_enlol = + CODEC_STW5095_CR2_ENLOL_ENABLED; + p_codec_configuration->cr2_enlor = + CODEC_STW5095_CR2_ENLOR_ENABLED; + + p_codec_configuration->cr19_vcml = + CODEC_STW5095_CR19_VCML_1_35V; + p_codec_configuration->cr19_mutelo = + CODEC_STW5095_CR19_MUTEHP_NOT_MUTED; + //CODEC_STW5095_CR19_MUTEHP_MUTED; //org + p_codec_configuration->cr19_lssel = + CODEC_STW5095_CR19_LSSEL_MONO_LEFT_PLUS_RIGHT_DIV_2_CHANNEL; + + p_codec_configuration->cr17_miclo= + CODEC_STW5095_CR17_MICLO_DISABLED; + p_codec_configuration->cr17_mixmic= + CODEC_STW5095_CR17_MIXMIC_DISABLED; +#endif + break; + + case CODEC_DEST_EARPIECE: + p_codec_configuration->cr1_endacl = + CODEC_STW5095_CR1_ENDACL_ENABLED; + p_codec_configuration->cr1_endacr = + CODEC_STW5095_CR1_ENDACR_ENABLED; + p_codec_configuration->cr2_enlol = + CODEC_STW5095_CR2_ENLOL_DISABLED; + p_codec_configuration->cr2_enlor = + CODEC_STW5095_CR2_ENLOR_DISABLED; + p_codec_configuration->cr2_enhpl = + CODEC_STW5095_CR2_ENHPL_DISABLED; + p_codec_configuration->cr2_enhpr = + CODEC_STW5095_CR2_ENHPR_DISABLED; + p_codec_configuration->cr2_enhpvcm = + CODEC_STW5095_CR2_ENHPVCM_ENABLED; + + p_codec_configuration->cr19_mutehp = + CODEC_STW5095_CR19_MUTEHP_MUTED; + + p_codec_configuration->cr2_enls = + CODEC_STW5095_CR2_ENLS_ENABLED; + p_codec_configuration->cr19_lslim = + CODEC_STW5095_CR19_LSLIM_LIMITED; + p_codec_configuration->cr19_lssel = + CODEC_STW5095_CR19_LSSEL_MONO_LEFT_PLUS_RIGHT_DIV_2_CHANNEL; + + p_codec_configuration->cr19_mutelo = + CODEC_STW5095_CR19_MUTELO_MUTED; + break; + + case CODEC_DEST_LINEOUT: + p_codec_configuration->cr1_endacl = + CODEC_STW5095_CR1_ENDACL_ENABLED; + p_codec_configuration->cr1_endacr = + CODEC_STW5095_CR1_ENDACR_ENABLED; + p_codec_configuration->cr2_enlol = + CODEC_STW5095_CR2_ENLOL_ENABLED; + p_codec_configuration->cr2_enlor = + CODEC_STW5095_CR2_ENLOR_ENABLED; + p_codec_configuration->cr2_enhpl = + CODEC_STW5095_CR2_ENHPL_DISABLED; + p_codec_configuration->cr2_enhpr = + CODEC_STW5095_CR2_ENHPR_DISABLED; + p_codec_configuration->cr2_enhpvcm = + CODEC_STW5095_CR2_ENHPVCM_ENABLED; + + p_codec_configuration->cr19_mutehp = + CODEC_STW5095_CR19_MUTEHP_MUTED; + p_codec_configuration->cr19_mutelo = + CODEC_STW5095_CR19_MUTELO_NOT_MUTED; + + p_codec_configuration->cr2_enls = + CODEC_STW5095_CR2_ENLS_DISABLED; + break; + + case CODEC_DEST_HEADPHONE: + p_codec_configuration->cr1_endacl = + CODEC_STW5095_CR1_ENDACL_ENABLED; + p_codec_configuration->cr1_endacr = + CODEC_STW5095_CR1_ENDACR_ENABLED; + p_codec_configuration->cr2_enlol = + CODEC_STW5095_CR2_ENLOL_DISABLED; + p_codec_configuration->cr2_enlor = + CODEC_STW5095_CR2_ENLOR_DISABLED; + p_codec_configuration->cr2_enhpl = + CODEC_STW5095_CR2_ENHPL_ENABLED; + p_codec_configuration->cr2_enhpr = + CODEC_STW5095_CR2_ENHPR_ENABLED; + p_codec_configuration->cr2_enhpvcm = + CODEC_STW5095_CR2_ENHPVCM_ENABLED; + + p_codec_configuration->cr19_mutehp = + CODEC_STW5095_CR19_MUTEHP_NOT_MUTED; + + p_codec_configuration->cr19_mutelo = + CODEC_STW5095_CR19_MUTELO_MUTED; + p_codec_configuration->cr2_enls = + CODEC_STW5095_CR2_ENLS_DISABLED; + break; + + default: + break; + } + } + + return (codec_error); +} + +t_codec_error codec_set_direction(t_codec_direction codec_direction) +{ + t_codec_error codec_error = CODEC_OK; + switch (codec_direction) { + case CODEC_DIRECTION_IN: + codec_error = codec_program_direction(CODEC_DIRECTION_IN); + break; + + case CODEC_DIRECTION_OUT: + codec_error = codec_program_direction(CODEC_DIRECTION_OUT); + break; + + case CODEC_DIRECTION_INOUT: + codec_error = codec_program_direction(CODEC_DIRECTION_IN); + if (CODEC_OK == codec_error) + codec_error = + codec_program_direction(CODEC_DIRECTION_OUT); + break; + + default: + break; + } + + if (codec_error != CODEC_OK) + return (codec_error); + + codec_error = codec_stw5095_update_cr1(); + if (CODEC_OK != codec_error) + return (codec_error); + + codec_error = codec_stw5095_update_cr2(); + if (CODEC_OK != codec_error) + return (codec_error); + + codec_error = codec_stw5095_update_cr17(); + if (CODEC_OK != codec_error) + return (codec_error); + + codec_error = codec_stw5095_update_cr18(); + if (CODEC_OK != codec_error) + return (codec_error); + + codec_error = codec_stw5095_update_cr19(); + if (CODEC_OK != codec_error) + return (codec_error); + + return (codec_error); +} + +t_codec_error codec_set_mode_and_direction(t_codec_direction codec_direction, + t_codec_mode codec_mode_in, + t_codec_mode codec_mode_out) +{ + t_codec_error codec_error = CODEC_OK; + t_codec_configuration *p_codec_configuration = + &g_codec_system_context.codec_configuration; + __u32 supported_features = 0; + __u32 configurable_features = 0; + + if (codec_direction != CODEC_DIRECTION_OUT) { + codec_error = + nomadik_acodec_get_hwcapabilities(CODEC_HWC_INPUT_MODE, + &supported_features, + &configurable_features); + if (CODEC_OK != codec_error) + return (codec_error); + + if (CODEC_MODE_HIFI == codec_mode_in) { + if (!(supported_features & CODEC_HWC_INPUT_MODE_HIFI)) { + codec_error = CODEC_INVALID_PARAMETER; + return (codec_error); + } + } + + if (CODEC_MODE_VOICE == codec_mode_in) { + if (!(supported_features & CODEC_HWC_INPUT_MODE_VOICE)) { + codec_error = CODEC_INVALID_PARAMETER; + return (codec_error); + } + } + } + + if (codec_direction != CODEC_DIRECTION_IN) { + codec_error = + nomadik_acodec_get_hwcapabilities(CODEC_HWC_OUTPUT_MODE, + &supported_features, + &configurable_features); + if (CODEC_OK != codec_error) + return (codec_error); + + if (CODEC_MODE_HIFI == codec_mode_out) { + if (!(supported_features & CODEC_HWC_INPUT_MODE_HIFI)) { + codec_error = CODEC_INVALID_PARAMETER; + return (codec_error); + } + } + + if (CODEC_MODE_VOICE == codec_mode_out) { + if (!(supported_features & CODEC_HWC_INPUT_MODE_VOICE)) { + codec_error = CODEC_INVALID_PARAMETER; + return (codec_error); + } + } + } + + { + t_codec_stw5095_cr0_powerup codec_stw5095_cr0_powerup; + + /* TBD - 5095 */ + if (CODEC_DIRECTION_OUT == codec_direction + || CODEC_DIRECTION_INOUT == codec_direction) { + if (CODEC_MODE_HIFI == codec_mode_out) { + p_codec_configuration->cr26_daform = + CODEC_STW5095_CR26_DAFORM_DELAYED_FORMAT_I2S_COMPATIBLE; + p_codec_configuration->cr28_damono = + CODEC_STW5095_CR28_DAMONO_STEREO_MODE; + } else { + p_codec_configuration->cr26_daform = + CODEC_STW5095_CR26_DAFORM_PCM_FORMAT_USES_LEFT_CHANNEL; + p_codec_configuration->cr28_damono = + CODEC_STW5095_CR28_DAMONO_MONO_MODE; + } + } + + if (CODEC_DIRECTION_IN == codec_direction + || CODEC_DIRECTION_INOUT == codec_direction) { + if (CODEC_MODE_HIFI == codec_mode_in) { + p_codec_configuration->cr27_adform = + CODEC_STW5095_CR27_ADFORM_DELAYED_FORMAT_I2S_COMPATIBLE; + p_codec_configuration->cr28_admono = + CODEC_STW5095_CR28_ADMONO_MONO_MODE; + } else { + p_codec_configuration->cr27_adform = + CODEC_STW5095_CR27_ADFORM_PCM_FORMAT_USES_LEFT_CHANNEL; + p_codec_configuration->cr28_admono = + CODEC_STW5095_CR28_ADMONO_MONO_MODE; + } + } + + codec_stw5095_cr0_powerup = p_codec_configuration->cr0_powerup; + + p_codec_configuration->cr0_powerup = + CODEC_STW5095_CR0_POWERUP_ON; /*nhk15 modification FIXME??*/ + + codec_error = codec_stw5095_update_cr0(); + if (CODEC_OK != codec_error) + return (codec_error); + + codec_error = codec_stw5095_update_cr26(); + if (codec_error != CODEC_OK) + return (codec_error); + + codec_error = codec_stw5095_update_cr27(); + if (codec_error != CODEC_OK) + return (codec_error); + + codec_error = codec_stw5095_update_cr28(); + if (codec_error != CODEC_OK) + return (codec_error); + + p_codec_configuration->cr0_powerup = codec_stw5095_cr0_powerup; + + codec_error = codec_stw5095_update_cr0(); + if (CODEC_OK != codec_error) + return (codec_error); + } + + /* + p_codec_configuration->cr1_enadcl = CODEC_STW5095_CR1_ENADCL_DISABLED; + p_codec_configuration->cr1_enadcr = CODEC_STW5095_CR1_ENADCR_DISABLED; + p_codec_configuration->cr1_endacl = CODEC_STW5095_CR1_ENDACL_DISABLED; + p_codec_configuration->cr1_endacr = CODEC_STW5095_CR1_ENDACR_DISABLED; + + p_codec_configuration->cr2_enls = CODEC_STW5095_CR2_ENLS_DISABLED; + p_codec_configuration->cr2_enlol = CODEC_STW5095_CR2_ENLOL_DISABLED; + p_codec_configuration->cr2_enlor = CODEC_STW5095_CR2_ENLOR_DISABLED; + + p_codec_configuration->cr2_enhpl = CODEC_STW5095_CR2_ENHPL_DISABLED; + p_codec_configuration->cr2_enhpr = CODEC_STW5095_CR2_ENHPR_DISABLED; + p_codec_configuration->cr2_enhpvcm = CODEC_STW5095_CR2_ENHPVCM_DISABLED; + */ + + g_codec_system_context.codec_direction = codec_direction; + g_codec_system_context.codec_mode_in = codec_mode_in; + g_codec_system_context.codec_mode_out = codec_mode_out; + + codec_error = codec_set_direction(codec_direction); + + return (codec_error); +} + +/* +* nomadik_acodec_get_hwcapabilities +* @hw_capability - hardware feature to query. +* @p_supported_features - list of supported features. +* @p_configurable_features: list of configurable features +* +* To query hw capabilities which is supported by underlying hw (codec hw) +* in use. +*/ + +t_codec_error nomadik_acodec_get_hwcapabilities(t_codec_hw_capability + hw_capability, + __u32 * p_supported_features, + __u32 * p_configurable_features) +{ + t_codec_error codec_error = CODEC_OK; + + *p_configurable_features = 0; + *p_supported_features = 0; + + switch (hw_capability) { + case CODEC_HWC_INPUT_SRC: + break; + + case CODEC_HWC_OUTPUT_DEST: + break; + + case CODEC_HWC_SAMPLE_FREQUENCIES: + + *p_supported_features = CODEC_HWC_SAMPLE_FREQY_8KHZ | + CODEC_HWC_SAMPLE_FREQY_11_025KHZ | + CODEC_HWC_SAMPLE_FREQY_12KHZ | + CODEC_HWC_SAMPLE_FREQY_16KHZ | + CODEC_HWC_SAMPLE_FREQY_22_05KHZ | + CODEC_HWC_SAMPLE_FREQY_22_5KHZ | + CODEC_HWC_SAMPLE_FREQY_24KHZ | + CODEC_HWC_SAMPLE_FREQY_32KHZ | + CODEC_HWC_SAMPLE_FREQY_44KHZ | + CODEC_HWC_SAMPLE_FREQY_44_1KHZ | + CODEC_HWC_SAMPLE_FREQY_48KHZ | + CODEC_HWC_SAMPLE_FREQY_64KHZ | + CODEC_HWC_SAMPLE_FREQY_88KHZ | + CODEC_HWC_SAMPLE_FREQY_88_2KHZ | + CODEC_HWC_SAMPLE_FREQY_96KHZ; + *p_configurable_features = *p_supported_features; + break; + + case CODEC_HWC_DATA_FORMAT: + break; + + case CODEC_HWC_SIDE_TONE_VOLUME: + break; + + case CODEC_HWC_DIGITAL_DEEMPHASIS: + break; + + case CODEC_HWC_USB_CLOCK_MODE: + break; + + case CODEC_HWC_VARIABLE_INPUT_BIT_LENGTH: + break; + + case CODEC_HWC_COMPAND_MODES: + *p_supported_features = CODEC_HWC_COMPAND_MODE_LINEAR; + *p_configurable_features = *p_supported_features; + break; + + case CODEC_HWC_BYPASS_MODE: + *p_supported_features = CODEC_HWC_BYPASS_MODE_OFF; + *p_configurable_features = *p_supported_features; + break; + + case CODEC_HWC_MIC_BOOST: + break; + + case CODEC_HWC_HIGH_PASS_FILTER: + break; + + case CODEC_HWC_MODE_MASTER_SLAVE: + break; + + case CODEC_HWC_MIC_MUTE: + break; + + case CODEC_HWC_DAC_SOFT_MUTE: + break; + + case CODEC_HWC_CLOCK_MODE_SELECTION: + break; + + case CODEC_HWC_OVERSAMPLING_RATE: + break; + + case CODEC_HWC_INPUT_MODE: + *p_supported_features = + CODEC_HWC_INPUT_MODE_VOICE | CODEC_HWC_INPUT_MODE_HIFI | + CODEC_HWC_INPUT_MODE_MANUAL; + *p_configurable_features = *p_supported_features; + break; + + case CODEC_HWC_OUTPUT_MODE: + *p_supported_features = + CODEC_HWC_OUTPUT_MODE_HIFI | CODEC_HWC_INPUT_MODE_VOICE | + CODEC_HWC_OUTPUT_MODE_MANUAL; + *p_configurable_features = *p_supported_features; + break; + + case CODEC_HWC_CODEC_INTERNAL_PLL: + *p_supported_features = + CODEC_HWC_CODEC_INTERNAL_PLL_DONNOT_USE | + CODEC_HWC_CODEC_INTERNAL_PLL_USE; + *p_configurable_features = *p_supported_features; + break; + + case CODEC_HWC_CODEC_INPUT_FREQUENCY: + *p_supported_features = 0xFFFFFFFF; + *p_configurable_features = *p_supported_features; + break; + + default: + codec_error = CODEC_INVALID_PARAMETER; + break; + } + + return (codec_error); +} + +/** +* nomadik_acodec_set_hwcapabilities +* @hw_capability - hardware feature to query. +* @feature - feature to be configured. +* +* To set hw capabilities which is supported by underlying hw (codec hw) +* in use. +*/ +t_codec_error nomadik_acodec_set_hwcapabilities(t_codec_hw_capability + hw_capability, __u32 feature) +{ + __u32 supported_features = 0; + __u32 configurable_features = 0; + t_codec_error codec_error = CODEC_OK; + + codec_error = + nomadik_acodec_get_hwcapabilities(hw_capability, + &supported_features, + &configurable_features); + if (codec_error != CODEC_OK) + return (codec_error); + + if (!(supported_features & feature)) { + codec_error = CODEC_UNSUPPORTED_FEATURE; + return (codec_error); + } + + switch (hw_capability) { + case CODEC_HWC_INPUT_SRC: + break; + + case CODEC_HWC_OUTPUT_DEST: + break; + + case CODEC_HWC_SAMPLE_FREQUENCIES: + break; + + case CODEC_HWC_DATA_FORMAT: + break; + + case CODEC_HWC_SIDE_TONE_VOLUME: + break; + + case CODEC_HWC_DIGITAL_DEEMPHASIS: + break; + + case CODEC_HWC_USB_CLOCK_MODE: + break; + + case CODEC_HWC_VARIABLE_INPUT_BIT_LENGTH: + break; + + case CODEC_HWC_COMPAND_MODES: + break; + + case CODEC_HWC_BYPASS_MODE: + codec_error = CODEC_UNSUPPORTED_FEATURE; + break; + + case CODEC_HWC_MIC_BOOST: + break; + + case CODEC_HWC_HIGH_PASS_FILTER: + break; + + case CODEC_HWC_MODE_MASTER_SLAVE: + break; + + case CODEC_HWC_MIC_MUTE: + break; + + case CODEC_HWC_DAC_SOFT_MUTE: + break; + + case CODEC_HWC_CLOCK_MODE_SELECTION: + break; + + case CODEC_HWC_OVERSAMPLING_RATE: + break; + + case CODEC_HWC_INPUT_MODE: + /* + *p_supported_features = CODEC_HWC_INPUT_MODE_HIFI | CODEC_HWC_INPUT_MODE_MANUAL; + *p_configurable_features = *p_supported_features; + */ + break; + + case CODEC_HWC_OUTPUT_MODE: + break; + + case CODEC_HWC_CODEC_INTERNAL_PLL: + if (feature & CODEC_HWC_CODEC_INTERNAL_PLL_DONNOT_USE) + g_codec_system_context.codec_device_internal_pll = + CODEC_DEVICE_INTERNAL_PLL_DONNOT_USE; + else + g_codec_system_context.codec_device_internal_pll = + CODEC_DEVICE_INTERNAL_PLL_USE; + break; + + case CODEC_HWC_CODEC_INPUT_FREQUENCY: + g_codec_system_context.codec_input_frequency = feature; /* input frequency in KHz */ + break; + } + + return (codec_error); +} + +/** +* nomadik_acodec_enable_audio_mode +* +* @direction - direction of data flow (from/to) audiocode * @input_frequency - record direction +* @output_frequency - playback direction +* @mspClockSel - clock for MSP +* @mspInClockFreq - input clock for MSP +* +* It configures the audiocodec in audio mode. In this case,the I2S +* protocol is used for data exchanges. +*/ + +t_codec_error nomadik_acodec_enable_audio_mode(t_codec_direction direction, + t_codec_sample_frequency + input_frequency, + t_codec_sample_frequency + output_frequency, + codec_msp_srg_clock_sel_type + mspClockSel, + codec_msp_in_clock_freq_type + mspInClockFreq, + t_acodec_user user) +{ + t_codec_error error_status = CODEC_OK; + struct msp_generic_config MSPConfiguration; + t_codec_sample_frequency freq; + t_codec_error codec_error; + t_codec_mode codec_in_mode = CODEC_MODE_MANUAL_SETTING; + t_codec_mode codec_out_mode = CODEC_MODE_MANUAL_SETTING; + t_codec_direction codec_direction; + + DEBUG(1, " Entering in nomadik_acodec_enable_audio_mode()\n"); + +#if defined (CONFIG_NOMADIK_NHK15) + { + void codec_hd_amp_init(t_acodec_user user); + codec_hd_amp_init(user); + } +#endif + + if(g_codec_system_context.cur_user == NO_USER) { + printk("WARNING : Audiocodec not yet configured by any user\n"); + return (CODEC_ERROR); + } + else if(g_codec_system_context.cur_user != user) { + printk + ("ERROR : Trying to acces audiocodec already in use by user %d\n", g_codec_system_context.cur_user); + return (CODEC_ERROR); + } + + switch (direction) { + case CODEC_DIRECTION_INOUT: + if (input_frequency != output_frequency) { + printk + ("ERROR : in inout mode two different frequencies are not supported\n"); + return CODEC_NOT_SUPPORTED; + } else { + freq = input_frequency; + } + codec_direction = CODEC_DIRECTION_INOUT; + codec_in_mode = CODEC_MODE_HIFI; + codec_out_mode = CODEC_MODE_HIFI; + break; + case CODEC_DIRECTION_IN: + freq = input_frequency; + codec_direction = CODEC_DIRECTION_IN; + codec_in_mode = CODEC_MODE_HIFI; + break; + case CODEC_DIRECTION_OUT: + freq = output_frequency; + codec_direction = CODEC_DIRECTION_OUT; + codec_out_mode = CODEC_MODE_HIFI; + break; + case CODEC_DIRECTION_UNKNOWN: + default: + printk("Invalid direction\n"); + return CODEC_ERROR; + } + + switch (freq) { + case CODEC_SAMPLING_FREQ_8KHZ: + case CODEC_SAMPLING_FREQ_12KHZ: + case CODEC_SAMPLING_FREQ_16KHZ: + case CODEC_SAMPLING_FREQ_11KHZ: + case CODEC_SAMPLING_FREQ_22KHZ: + case CODEC_SAMPLING_FREQ_24KHZ: + case CODEC_SAMPLING_FREQ_32KHZ: + case CODEC_SAMPLING_FREQ_44KHZ: + case CODEC_SAMPLING_FREQ_48KHZ: + case CODEC_SAMPLING_FREQ_64KHZ: + case CODEC_SAMPLING_FREQ_88KHZ: + case CODEC_SAMPLING_FREQ_96KHZ: + case CODEC_SAMPLING_FREQ_128KHZ: + case CODEC_SAMPLING_FREQ_176KHZ: + case CODEC_SAMPLING_FREQ_192KHZ: + case CODEC_SAMPLING_FREQ_MINLIMIT: + case CODEC_SAMPLING_FREQ_MAXLIMIT: + case CODEC_SAMPLING_FREQ_RESET: + case CODEC_FREQUENCY_DONT_CHANGE: + break; + default: + printk("not supported frequency\n"); + return CODEC_ERROR; + } + + /* MSP configuration */ +#ifdef CONFIG_DA_MASTER + MSPConfiguration.tx_clock_sel = 0; // TCKSEL is input + MSPConfiguration.tx_frame_sync_sel = 0; // FS is an input + MSPConfiguration.rx_clock_sel = 0; + MSPConfiguration.rx_frame_sync_sel = 0; +#else + + MSPConfiguration.tx_clock_sel = TX_CLK_SEL_SRG; + MSPConfiguration.rx_clock_sel = RX_CLK_SEL_SRG; + + MSPConfiguration.tx_frame_sync_sel = TX_SYNC_SRG_PROG; + MSPConfiguration.rx_frame_sync_sel = RX_SYNC_SRG; +#endif + + if (mspInClockFreq == DEFAULT) + MSPConfiguration.input_clock_freq = MSP_INPUT_FREQ_48MHZ; + else + MSPConfiguration.input_clock_freq = mspInClockFreq; + + if (mspClockSel == DEFAULT) + MSPConfiguration.srg_clock_sel = SRG_CLK_SEL_APB; + else + MSPConfiguration.srg_clock_sel = mspClockSel; + + //MSPConfiguration.srg_clock_sel = 0x0008000; + + MSPConfiguration.rx_endianess = MSP_BIG_ENDIAN; + MSPConfiguration.tx_endianess = MSP_BIG_ENDIAN; + + MSPConfiguration.rx_frame_sync_pol = RX_FIFO_SYNC_HI; + MSPConfiguration.tx_frame_sync_pol = TX_FIFO_SYNC_HI; + + MSPConfiguration.rx_unexpect_frame_sync = MSP_UNEXPECTED_FS_IGNORE; + MSPConfiguration.tx_unexpect_frame_sync = MSP_UNEXPECTED_FS_IGNORE; + + MSPConfiguration.rx_fifo_config = RX_FIFO_ENABLE; + MSPConfiguration.tx_fifo_config = TX_FIFO_ENABLE; + + MSPConfiguration.spi_clk_mode = SPI_CLK_MODE_NORMAL; + MSPConfiguration.spi_burst_mode = 0; + + error_status = nomadik_msp_configure(MSP_NUM, &MSPConfiguration, (t_msp_user )user); + if (error_status) { + printk("AUDIUOCODEC : error in msp configure\n"); + return error_status; + } + + /* enable msp for both tr and rx mode with dma data transfer. THIS IS NOW DONE SEPARATELY from SAA. */ + error_status = + nomadik_msp_enable(MSP_NUM, MSP_BOTH_T_R_MODE, MSP_DMA_MODE, + MSP_I2S_PROTOCOL, freq, ELEMENT_SIZE, + FRAME_SIZE, (t_msp_user)user); + if (error_status < 0) { + printk("AUDIOCODEC : error in msp enable, error_status is %d\n", error_status); + return error_status; + } + + codec_error = + codec_set_mode_and_direction(codec_direction, codec_in_mode, + codec_out_mode); + if (CODEC_OK != codec_error) { + printk("AUDIOCODEC: ERROR: set mode and direction failed\n"); + return CODEC_ERROR; + } + + codec_error = nomadik_acodec_set_frequency(direction, freq, freq, user); + if (CODEC_OK != codec_error) { + printk("AUDIOCODEC: ERROR: set sample frequency failed\n"); + return CODEC_ERROR; + } + /* + //each client has to do these configurations + //------------------------------------------- + + codec_error = nomadik_acodec_set_volume(50, 50, 100, 100, user); + if (CODEC_OK != codec_error) { + printk("AUDIOCODEC: ERROR: set volume failed\n"); + return CODEC_ERROR; + } + */ + codec_error = nomadik_acodec_select_input(CODEC_SOURCE_MICROPHONE, user); + if (CODEC_OK != codec_error) { + printk("AUDIOCODEC: ERROR: select input failed\n"); + return CODEC_ERROR; + } +#if !defined(CONFIG_NOMADIK_NHK15) + codec_error = nomadik_acodec_select_output(CODEC_DEST_HEADPHONE,user); + if (CODEC_OK != codec_error) { + printk("AUDIOCODEC: ERROR: select output failed\n"); + return CODEC_ERROR; + } +#else + { + int err; + uint8 byte_value_test; + err = STMPE2401_GetGpioVal(STMPE0,7,&byte_value_test); + switch(byte_value_test) + { + case 1: + codec_error = nomadik_acodec_select_output(CODEC_DEST_HEADPHONE ,user); + if (CODEC_OK != codec_error) { + printk("AUDIOCODEC: ERROR: select output failed\n"); + return CODEC_ERROR; + } + + break; + case 0: + codec_error = nomadik_acodec_select_output(CODEC_DEST_LOUDSPEAKER,user); + if (CODEC_OK != codec_error) { + printk("AUDIOCODEC: ERROR: select output failed\n"); + return CODEC_ERROR; + } + break; + default: + break; + } + } +#endif + DEBUG(1, "leaving in nomadik_acodec_enable_audio_mode() \n"); + + return CODEC_OK; +} + +/** +* nomadik_acodec_enable_voice_mode +* +* @direction - direction of data flow (from/to) audiocode +* @input_frequency - record direction +* @output_frequency - playback direction +* @mspClockSel - clock for MSP +* @mspInClockFreq - input clock for MSP +* +* It configures the audiocodec in audio mode. In this case,the PCM +* protocol is used for data exchanges. +*/ + +t_codec_error nomadik_acodec_enable_voice_mode(t_codec_direction direction, + t_codec_sample_frequency + input_frequency, + t_codec_sample_frequency + output_frequency, + codec_msp_srg_clock_sel_type + mspClockSel, + codec_msp_in_clock_freq_type + mspInClockFreq, + t_acodec_user user) + +{ + struct msp_generic_config MSPConfiguration; + t_codec_error error_status; + t_codec_sample_frequency freq; + t_codec_error codec_error; + t_codec_mode codec_in_mode = CODEC_MODE_MANUAL_SETTING; + t_codec_mode codec_out_mode = CODEC_MODE_MANUAL_SETTING; + t_codec_direction codec_direction; + + DEBUG(1, "Entering in nomadik_acodec_enable_voice_mode () \n"); +#if defined (CONFIG_NOMADIK_NHK15) + { + void codec_hd_amp_init(t_acodec_user user); + codec_hd_amp_init(user); + } +#endif + + if(g_codec_system_context.cur_user == NO_USER) { + printk("WARNING : Audiocodec not yet configured by any user\n"); + return (CODEC_ERROR); + } + else if(g_codec_system_context.cur_user != user) { + printk + ("ERROR : Trying to acces audiocodec already in use by user %d\n", g_codec_system_context.cur_user); + return (CODEC_ERROR); + } + + switch (direction) { + case CODEC_DIRECTION_INOUT: + if (input_frequency != output_frequency) { + printk + ("ERROR : in inout mode two different frequencies are not supported\n"); + return CODEC_NOT_SUPPORTED; + } else { + freq = input_frequency; + } + codec_direction = CODEC_DIRECTION_INOUT; + codec_in_mode = CODEC_MODE_VOICE; + codec_out_mode = CODEC_MODE_VOICE; + break; + case CODEC_DIRECTION_IN: + freq = input_frequency; + codec_direction = CODEC_DIRECTION_IN; + codec_in_mode = CODEC_MODE_VOICE; + break; + case CODEC_DIRECTION_OUT: + freq = output_frequency; + codec_direction = CODEC_DIRECTION_OUT; + codec_out_mode = CODEC_MODE_VOICE; + break; + case CODEC_DIRECTION_UNKNOWN: + default: + printk("Invalid direction\n"); + return CODEC_ERROR; + } + + switch (freq) { + case CODEC_SAMPLING_FREQ_8KHZ: + case CODEC_SAMPLING_FREQ_16KHZ: + break; + case CODEC_SAMPLING_FREQ_11KHZ: + case CODEC_SAMPLING_FREQ_12KHZ: + case CODEC_SAMPLING_FREQ_22KHZ: + case CODEC_SAMPLING_FREQ_24KHZ: + case CODEC_SAMPLING_FREQ_32KHZ: + case CODEC_SAMPLING_FREQ_44KHZ: + case CODEC_SAMPLING_FREQ_48KHZ: + case CODEC_SAMPLING_FREQ_64KHZ: + case CODEC_FREQUENCY_DONT_CHANGE: + case CODEC_SAMPLING_FREQ_88KHZ: + case CODEC_SAMPLING_FREQ_96KHZ: + case CODEC_SAMPLING_FREQ_128KHZ: + case CODEC_SAMPLING_FREQ_176KHZ: + case CODEC_SAMPLING_FREQ_192KHZ: + case CODEC_SAMPLING_FREQ_MINLIMIT: + case CODEC_SAMPLING_FREQ_MAXLIMIT: + case CODEC_SAMPLING_FREQ_RESET: + default: + printk("AUDIOCODEC: not supported frequency\n"); + return CODEC_ERROR; + } + +#ifdef CONFIG_DA_MASTER + DEBUG(2, "MSP Configuring as SLAVE \n"); + MSPConfiguration.tx_clock_sel = 0; // TCKSEL is input + MSPConfiguration.tx_frame_sync_sel = 0; // FS is an input + MSPConfiguration.rx_clock_sel = 0; + MSPConfiguration.rx_frame_sync_sel = 0; +#else + + DEBUG(2, "MSP Configuring as MASTER \n"); + MSPConfiguration.tx_clock_sel = TX_CLK_SEL_SRG; + MSPConfiguration.rx_clock_sel = RX_CLK_SEL_SRG; + + MSPConfiguration.tx_frame_sync_sel = TX_SYNC_SRG_PROG; + MSPConfiguration.rx_frame_sync_sel = RX_SYNC_SRG; +#endif + + if (mspInClockFreq == DEFAULT) + MSPConfiguration.input_clock_freq = MSP_INPUT_FREQ_48MHZ; + else + MSPConfiguration.input_clock_freq = mspInClockFreq; + if (mspClockSel == DEFAULT) + MSPConfiguration.srg_clock_sel = SRG_CLK_SEL_APB; + else + MSPConfiguration.srg_clock_sel = mspClockSel; + + MSPConfiguration.rx_endianess = MSP_BIG_ENDIAN; + MSPConfiguration.tx_endianess = MSP_BIG_ENDIAN; + + MSPConfiguration.rx_frame_sync_pol = RX_FIFO_SYNC_HI; + MSPConfiguration.tx_frame_sync_pol = TX_FIFO_SYNC_HI; + + MSPConfiguration.rx_unexpect_frame_sync = MSP_UNEXPECTED_FS_IGNORE; + MSPConfiguration.tx_unexpect_frame_sync = MSP_UNEXPECTED_FS_IGNORE; + + MSPConfiguration.rx_fifo_config = RX_FIFO_ENABLE; + MSPConfiguration.tx_fifo_config = TX_FIFO_ENABLE; + + MSPConfiguration.spi_clk_mode = SPI_CLK_MODE_NORMAL; + MSPConfiguration.spi_burst_mode = 0; + + error_status = nomadik_msp_configure(MSP_NUM, &MSPConfiguration, (t_msp_user)user); + if (error_status) { + printk("AUDIOCODEC : error in msp configure\n"); + return error_status; + } + + /* enable msp for both tr and rx mode with dma data transfer. */ + error_status = + nomadik_msp_enable(MSP_NUM, MSP_BOTH_T_R_MODE, MSP_DMA_MODE, + MSP_PCM_PROTOCOL, freq, ELEMENT_SIZE, + FRAME_SIZE, (t_msp_user)user); + if (error_status) { + printk("AUDIOCODEC : error in msp enable, error_status is %d\n", error_status); + return error_status; + } + + codec_error = + codec_set_mode_and_direction(codec_direction, codec_in_mode, + codec_out_mode); + if (CODEC_OK != codec_error) { + printk("AUDIOCODEC: ERROR: set mode and direction failed\n"); + return CODEC_ERROR; + } + + codec_error = nomadik_acodec_set_frequency(direction, freq, freq, user); + if (CODEC_OK != codec_error) { + printk("AUDIOCODEC: ERROR: set sample frequency failed\n"); + return CODEC_ERROR; + } + + /* + //each client has to do these configurations + //------------------------------------------- + + codec_error = nomadik_acodec_set_volume(50, 50, 100, 100, user); + if (CODEC_OK != codec_error) { + printk("AUDIOCODEC: ERROR: set volume failed\n"); + return CODEC_ERROR; + } + */ + codec_error = nomadik_acodec_select_input(CODEC_SOURCE_MICROPHONE, user); + if (CODEC_OK != codec_error) { + printk("AUDIOCODEC: ERROR: select input failed\n"); + return CODEC_ERROR; + } +#if !defined(CONFIG_NOMADIK_NHK15) + codec_error = nomadik_acodec_select_output(CODEC_DEST_HEADPHONE,user); + if (CODEC_OK != codec_error) { + printk("AUDIOCODEC: ERROR: select output failed\n"); + return CODEC_ERROR; + } +#else + { + int err; + uint8 byte_value_test; + err = STMPE2401_GetGpioVal(STMPE0,7,&byte_value_test); + switch(byte_value_test) + { + case 1: + codec_error = nomadik_acodec_select_output(CODEC_DEST_HEADPHONE ,user); + if (CODEC_OK != codec_error) { + printk("AUDIOCODEC: ERROR: select output failed\n"); + return CODEC_ERROR; + } + + break; + case 0: + codec_error = nomadik_acodec_select_output(CODEC_DEST_LOUDSPEAKER,user); + if (CODEC_OK != codec_error) { + printk("AUDIOCODEC: ERROR: select output failed\n"); + return CODEC_ERROR; + } + break; + default: + break; + } + } +#endif + DEBUG(1, "Leaving in nomadik_acodec_enable_voice_mode () \n"); + + return (error_status); +} + +/** + * nomadik_acodec_enable_tonegeneratormode + * @tone_gain - gain in db for tone generated + * @mix_with_record - mixing of tone with recording + * @mix_with_playback - mixing of tone with playback + * @waveShape - wave shape sin/square + * @reserved2 - reserved for future use + * + * It configures the audiocodec in tone mode. if mix with + * or record is TRUE then enable internal tone generator else + * set tone only mode nad disable audio or voice mode. + */ + +t_codec_error nomadik_acodec_enable_tonegeneratormode(int tone_gain, + __u8 mix_with_record, + __u8 mix_with_playback, + codec_tone_wave waveShape, + u_long * reserved2, t_acodec_user user) +{ + + t_codec_error error_status = CODEC_OK; + DEBUG(1, " Entering AUDIOCODEC_EnableToneGenerator() \n"); + DEBUG(1, " leaving AUDIOCODEC_EnableToneGenerator() \n"); + return error_status; +} + +/** + * nomadik_acodec_disable_tonegeneratormode + * + * It disables the tonegeneration mode. + */ +t_codec_error nomadik_acodec_disable_tonegeneratormode(t_acodec_user user) +{ + + t_codec_error error_status = CODEC_OK; + + DEBUG(1, " entering in AUDIOCODEC_DiableToneGenerator() \n"); + DEBUG(1, " leaving AUDIOCODEC_DiableToneGenerator() \n"); + return error_status; +} + +/** + * nomadik_acodec_play_singletone + * @tone_frequency: single frequency to generate tone + * + * It starts the single frequency tone generation + */ +t_codec_error nomadik_acodec_play_singletone(int tone_frequency, t_acodec_user user) +{ + t_codec_error error_status = CODEC_OK; + + DEBUG(1, " entering in nomadik_acodec_play_singletone() \n"); + DEBUG(1, " leaving nomadik_acodec_play_singletone() \n"); + + return error_status; + +} + +/** +* nomadik_acodec_play_dualtone +* @freqF1 - frequency f1 to generate tone +* @ferqF2 - frequemcy f2 to generate tone +* +* It starts the DTMF tone generation +*/ +t_codec_error nomadik_acodec_play_dualtone(int freqF1, int freqF2, t_acodec_user user) +{ + t_codec_error error_status = CODEC_OK; + + DEBUG(1, " entering in nomadik_acodec_play_dualtone() \n"); + DEBUG(1, " leaving nomadik_acodec_play_dualtone() \n"); + + return error_status; +} + +/** +* nomadik_acodec_stop_tone - stops the DTMF or single tone generatio +*/ +t_codec_error nomadik_acodec_stop_tone(t_acodec_user user) +{ + t_codec_error error_status = CODEC_OK; + + DEBUG(1, " entering in nomadik_acodec_stop_tone() \n"); + DEBUG(1, " Leaving nomadik_acodec_stop_tone() \n"); + return error_status; +} + +/** + * nomadik_acodec_get_volume - gets the current voulme level + * @codec_volume - struct returning volume for both mic/speaker + */ + +t_codec_error nomadik_acodec_get_volume(codec_volume + *codec_volume, t_acodec_user user) +{ + DEBUG(1, " Entering nomadik_acodec_get_volume()\n"); + + if(g_codec_system_context.cur_user == NO_USER) { + printk("WARNING : Audiocodec not yet configured by any user\n"); + return (CODEC_OK); + } + else if(g_codec_system_context.cur_user != user) { + printk + ("ERROR : Trying to acces audiocodec already in use by user %d\n", g_codec_system_context.cur_user); + return CODEC_ERROR; + } + + codec_volume->lvolume_in = g_codec_system_context.in_left_volume; + codec_volume->rvolume_in = g_codec_system_context.in_right_volume; + codec_volume->lvolume_out = g_codec_system_context.out_left_volume; + codec_volume->rvolume_out = g_codec_system_context.out_right_volume; + DEBUG(1, " leaving nomadik_acodec_get_volume()\n"); + return (CODEC_OK); +} + +/** +* nomadik_acodec_set_volume - configures the volume level for both speakers +* @in_left_volume - volume for left channel of mic +* @in_right_volume - volume for right channel of mic +* @out_left_volume - volume for left speaker +* @out_right_volume - volume for right speaker +*/ +t_codec_error nomadik_acodec_set_volume(int in_left_volume, int in_right_volume, + int out_left_volume, + int out_right_volume, t_acodec_user user) +{ + t_codec_error codec_error = CODEC_OK; + t_codec_configuration *p_codec_configuration = + &g_codec_system_context.codec_configuration; + + DEBUG(1, " Entering in nomadik_acodec_set_volume()\n"); + + if(g_codec_system_context.cur_user == NO_USER) { + printk("WARNING : Audiocodec not yet configured by any user\n"); + return (CODEC_OK); + } + else if(g_codec_system_context.cur_user != user) { + printk + ("ERROR : Trying to acces audiocodec already in use by user %d\n", g_codec_system_context.cur_user); + return CODEC_ERROR; + } + + if (in_left_volume > 100) + in_left_volume = 100; + + if (in_left_volume < 0) + in_left_volume = 0; + + if (in_right_volume > 100) + in_right_volume = 100; + + if (in_right_volume < 0) + in_right_volume = 0; + + if (out_left_volume > 100) + out_left_volume = 100; + + if (out_left_volume < 0) + out_left_volume = 0; + + if (out_right_volume > 100) + out_right_volume = 100; + + if (out_right_volume < 0) + out_right_volume = 0; + + if ((out_left_volume == 0) && (out_right_volume == 0)) { + /*In case vol_out is zero, set MUTELO and MUTE_HP */ + p_codec_configuration->cr19_mutelo = CODEC_STW5095_CR19_MUTELO_MUTED; + p_codec_configuration->cr19_mutehp = CODEC_STW5095_CR19_MUTEHP_MUTED; + } + else if ((out_left_volume > 0) || (out_right_volume > 0)){ + /*In case vol_out is non-zero, unset MUTELO and MUTE_HP */ + p_codec_configuration->cr19_mutelo = CODEC_STW5095_CR19_MUTELO_NOT_MUTED; + p_codec_configuration->cr19_mutehp = CODEC_STW5095_CR19_MUTEHP_NOT_MUTED; + } + + if ((in_left_volume == 0) && (in_right_volume == 0)) { + p_codec_configuration->cr18_linmute = CODEC_STW5095_CR18_LINMUTE_ENABLED; + p_codec_configuration->cr18_micmute = CODEC_STW5095_CR18_MICMUTE_ENABLED; + } + + else if ((in_left_volume > 0) || (in_right_volume > 0)) { + p_codec_configuration->cr18_linmute = CODEC_STW5095_CR18_LINMUTE_DISABLED; + p_codec_configuration->cr18_micmute = CODEC_STW5095_CR18_MICMUTE_DISABLED; + } + g_codec_system_context.in_left_volume = in_left_volume; + g_codec_system_context.in_right_volume = in_right_volume; + g_codec_system_context.out_left_volume = out_left_volume; + g_codec_system_context.out_right_volume = out_right_volume; + + /* Set mininimum volume & mute if volume is zero */ + /* LSP : controlled with left out volume */ + p_codec_configuration->cr7_lsg = + CODEC_STW5095_LSP_VOLUME_MIN + + (out_left_volume * + (CODEC_STW5095_LSP_VOLUME_MAX - + CODEC_STW5095_LSP_VOLUME_MIN)) / 100; + + /* Line-out : controlled with left out volume */ + p_codec_configuration->cr7_log = + CODEC_STW5095_LINEOUT_VOLUME_MIN + + (out_left_volume * + (CODEC_STW5095_LINEOUT_VOLUME_MAX - + CODEC_STW5095_LINEOUT_VOLUME_MIN)) / 100; + + /* Headphone */ + p_codec_configuration->cr8_hplg = + CODEC_STW5095_OUTPUT_VOLUME_MIN + + (out_left_volume * + (CODEC_STW5095_OUTPUT_VOLUME_MAX - + CODEC_STW5095_OUTPUT_VOLUME_MIN)) / 100; + p_codec_configuration->cr9_hprg = + CODEC_STW5095_OUTPUT_VOLUME_MIN + + (out_right_volume * + (CODEC_STW5095_OUTPUT_VOLUME_MAX - + CODEC_STW5095_OUTPUT_VOLUME_MIN)) / 100; + + /* MIC */ + p_codec_configuration->cr3_miclg = + CODEC_STW5095_MIC_VOLUME_MIN + + (in_left_volume * + (CODEC_STW5095_MIC_VOLUME_MAX - + CODEC_STW5095_MIC_VOLUME_MIN)) / 100; + p_codec_configuration->cr4_micrg = + CODEC_STW5095_MIC_VOLUME_MIN + + (in_right_volume * + (CODEC_STW5095_MIC_VOLUME_MAX - + CODEC_STW5095_MIC_VOLUME_MIN)) / 100; + + /* Line-in */ + p_codec_configuration->cr5_linlg = + CODEC_STW5095_LINEIN_VOLUME_MIN + + (in_left_volume * + (CODEC_STW5095_LINEIN_VOLUME_MAX - + CODEC_STW5095_LINEIN_VOLUME_MIN)) / 100; + p_codec_configuration->cr6_linrg = + CODEC_STW5095_LINEIN_VOLUME_MIN + + (in_right_volume * + (CODEC_STW5095_LINEIN_VOLUME_MAX - + CODEC_STW5095_LINEIN_VOLUME_MIN)) / 100; + + codec_error = codec_stw5095_update_cr3(); + if (codec_error != CODEC_OK) + return (codec_error); + + codec_error = codec_stw5095_update_cr4(); + if (codec_error != CODEC_OK) + return (codec_error); + + codec_error = codec_stw5095_update_cr5(); + if (codec_error != CODEC_OK) + return (codec_error); + + codec_error = codec_stw5095_update_cr6(); + if (codec_error != CODEC_OK) + return (codec_error); + + codec_error = codec_stw5095_update_cr7(); + if (codec_error != CODEC_OK) + return (codec_error); + + codec_error = codec_stw5095_update_cr8(); + if (codec_error != CODEC_OK) + return (codec_error); + + codec_error = codec_stw5095_update_cr9(); + if (codec_error != CODEC_OK) + return (codec_error); + + codec_error = codec_stw5095_update_cr19(); + if (CODEC_OK != codec_error) + return (codec_error); + DEBUG(1, " Exiting in nomadik_acodec_set_volume()\n"); + return codec_error; +} + +/** +* nomadik_acodec_powerdown +* @flag - level of power down, 0 means complete power down +* +* It sets the codec in power down mode. complete functionality +* will be achieved in power management +*/ + +t_codec_error nomadik_acodec_powerdown(__u8 flag) +{ + t_codec_error error_status = CODEC_OK; + + g_codec_system_context.codec_configuration.cr0_powerup = + CODEC_STW5095_CR0_POWERUP_OFF; + error_status = codec_stw5095_update_cr0(); + + DEBUG(1, "leaving nomadik_acodec_powerdown() \n"); + return (error_status); +} + +/** +* nomadik_acodec_powerup +* +* It sets the codec in power up mode. rest is left for power +* management. +*/ + +t_codec_error nomadik_acodec_powerup(void) +{ + t_codec_error error_status = CODEC_OK; + + DEBUG(1, " Entering nomadik_acodec_powerup()\n"); + + g_codec_system_context.codec_configuration.cr0_powerup = + CODEC_STW5095_CR0_POWERUP_ON; + error_status = codec_stw5095_update_cr0(); + + DEBUG(1, " leaving nomadik_acodec_powerup()\n"); + return (error_status); +} + +/** +* nomadik_acodec_enable_bypassmode +* @analog_frequency +* @fm_gain - outside gain in the received audio signals +* @mix_with_playback - true if user wants to mix tone with audio played back +* @reserved1 - reserved for future use +* @reserved2 - reserved for future use +* +* Enables the bypass mode (Analog IN is routed to analog out. +*/ +t_codec_error nomadik_acodec_enable_bypassmode(t_codec_sample_frequency analog_frequency, __u8 fm_gain, boolean mix_with_playback, + u_long * reserved1, + u_long * reserved2, t_acodec_user user) +{ + t_codec_error error_status = CODEC_OK; + + DEBUG(1, " Entering nomadik_acodec_enable_bypassmode()\n"); + DEBUG(1, " leaving nomadik_acodec_enable_bypassmode()\n"); + return (error_status); +} + +/** + * nomadik_acodec_set_samplesize + * @codec_size: sample size in bits + * + * This routine sets the sample size in bits. + */ + +t_codec_error nomadik_acodec_set_samplesize(codec_input_bit_length codec_size, t_acodec_user user) +{ + + t_codec_error error_status = CODEC_OK; + + DEBUG(1, " Entering nomadik_acodec_set_samplesize()\n"); + DEBUG(1, " leaving nomadik_acodec_set_samplesize()\n"); + + return error_status; +} + +/** + * nomadik_acodec_set_no_of_channels + * @channels: mono or stereo + * + * This routine checks then sets the no of channels configured together + * with mode. + */ +t_codec_error nomadik_acodec_set_no_of_channels(t_codec_channel channels, t_acodec_user user) +{ + + DEBUG(1, " Entering nomadik_acodec_set_no_of_channels()\n"); + DEBUG(1, " leaving nomadik_acodec_set_no_of_channels()\n"); + return CODEC_OK; +} + +/** + * nomadik_acodec_set_compand + * @compand_mode: Linear, A-law or Mu-Law + * + * This routine sets the Companded mode for audiocodec + */ + +t_codec_error nomadik_acodec_set_compand(codec_compand_mode compand_mode, t_acodec_user user) +{ + t_codec_error error_status = CODEC_OK; + + DEBUG(1, " Entering nomadik_acodec_set_compand()\n"); + DEBUG(1, " leaving nomadik_acodec_set_compand()\n"); + return error_status; +} + +/** + * nomadik_acodec_enable_datapath_errcb + * + * This routine is not implemented yet + */ +t_codec_error nomadik_acodec_enable_datapath_errcb(codec_callback * + call_back_fn, u_long * data, t_acodec_user user) +{ + return CODEC_OK; +} + +/** + * nomadik_acodec_set_dataformat + * @codec_dfmt: data format bit mask. + * + * This routine is mot implemented yet. + */ + +t_codec_error nomadik_acodec_set_dataformat(codec_dfmt * codec_dfmt, t_acodec_user user) +{ + DEBUG(1, " Entering nomadik_acodec_set_dataformat()\n"); + DEBUG(1, " leaving nomadik_acodec_set_dataformat()\n"); + return CODEC_OK; +} + +/** + * nomadik_acodec_get_dataformat + * @codec_dfmt: data format bit mask. + * + * This routine is mot implemented yet. + */ + +t_codec_error nomadik_acodec_get_dataformat(codec_dfmt * codec_dfmt, t_acodec_user user) +{ + DEBUG(1, " Entering nomadik_acodec_get_dataformat()\n"); + DEBUG(1, " leaving nomadik_acodec_get_dataformat()\n"); + return CODEC_OK; +} + +/** + * nomadik_acodec_enable_sidetone + * @gain - sidetone gain in db + * @reserved1 - reserved for future use only. + * @reserved2 - reserved for future use only. + * + * This routine enables the side tone to be mixed with record + * It is mot implemented yet. + */ + +t_codec_error nomadik_acodec_enable_sidetone(int gain, u_long * reserved1, + u_long * reserved2, t_acodec_user user) +{ + t_codec_error error_status = CODEC_OK; + DEBUG(1, " Entering nomadik_acodec_enable_sidetone\n"); + DEBUG(1, " leaving nomadik_acodec_enable_sidetone\n"); + return error_status; +} + +/** + * nomadik_acodec_disable_sidetone - diables the side tone + */ + +t_codec_error nomadik_acodec_disable_sidetone(t_acodec_user user) +{ + t_codec_error error_status = CODEC_OK; + DEBUG(1, " Entering nomadik_acodec_disable_sidetone\n"); + DEBUG(1, " leaving nomadik_acodec_disable_sidetone\n"); + return error_status; +} + +/** + * nomadik_acodec_select_input + * @input_device: MIC or linein. + * + * This routine selects the input device mic or linein. + */ + +t_codec_error nomadik_acodec_select_input(t_codec_input_select input_device, t_acodec_user user) +{ + + t_codec_error error_status = CODEC_OK; + + DEBUG(1, " Entering nomadik_acodec_select_input\n"); + + if(g_codec_system_context.cur_user == NO_USER) { + printk("WARNING : Audiocodec not yet configured by any user\n"); + return (CODEC_OK); + } + else if(g_codec_system_context.cur_user != user) { + printk + ("ERROR : Trying to acces audiocodec already in use by user %d\n", g_codec_system_context.cur_user); + return CODEC_ERROR; + } + + g_codec_system_context.codec_src = input_device; + error_status = codec_set_direction(CODEC_DIRECTION_IN); + + DEBUG(1, " leaving nomadik_acodec_select_input\n"); + return error_status; +} + +/** + * nomadik_acodec_select_output + * @output_device: output device HP/LSP + * + * This routine selects the output device Headphone or loud speaker + */ + +t_codec_error nomadik_acodec_select_output(t_codec_output_select output_device, t_acodec_user user) +{ + + t_codec_error error_status = CODEC_OK; + + DEBUG(1, " Entering nomadik_acodec_select_output()\n"); + + if(g_codec_system_context.cur_user == NO_USER) { + printk("WARNING : Audiocodec not yet configured by any user\n"); + return (CODEC_OK); + } + else if(g_codec_system_context.cur_user != user) { + printk + ("ERROR : Trying to acces audiocodec already in use by user %d\n", g_codec_system_context.cur_user); + return CODEC_ERROR; + } + + g_codec_system_context.codec_dest = output_device; + error_status = codec_set_direction(CODEC_DIRECTION_OUT); + + DEBUG(1, " leaving nomadik_acodec_select_output()\n"); + return error_status; +} + +/** + * nomadik_acodec_get_minvolume + * @input_min_vol - minimum volume supported by acodec for recording + * @output_min_vol - minimum volume supported by acodec for playback + * + * This routine returns the minimum volume possible for audiocodec + */ + +t_codec_error nomadik_acodec_get_minvolume(__u8 * input_min_vol, + __u8 * output_min_vol) +{ + DEBUG(1, " Entering nomadik_acodec_get_minvolume()\n"); + *input_min_vol = VOL_MIN; + *output_min_vol = VOL_MIN; + + DEBUG(1, " leaving nomadik_acodec_get_minvolume()\n"); + return CODEC_OK; +} + +/** + * nomadik_acodec_get_maxvolume + * @input_max_vol - maximum volume supported by acodec for recording + * @output_max_vol - maximum volume supported by acodec for playback + * + * This routine returns the maximum volume possible for audiocodec + */ + +t_codec_error nomadik_acodec_get_maxvolume(__u8 * input_max_vol, + __u8 * output_max_vol) +{ + DEBUG(1, " Entering nomadik_acodec_get_maxvolume()\n"); + + *input_max_vol = VOL_MAX; + *output_max_vol = VOL_MAX; + + DEBUG(1, " leaving nomadik_acodec_get_maxvolume()\n"); + return CODEC_OK; +} + +/* + * nomadik_acodec_set_frequency + * @direction - in/out direction form audiocodec + * @record_sample_frequency - record frequency + * @play_sample_frequency: playback frequency + * + * This routine sets the freuency for audio codec and MSP + */ + +t_codec_error nomadik_acodec_set_frequency(t_codec_direction direction, + t_codec_sample_frequency + record_sample_frequency, + t_codec_sample_frequency + play_sample_frequency, t_acodec_user user) +{ + t_codec_error codec_error = CODEC_OK; + + DEBUG(1, " Entering nomadik_acodec_set_frequency()\n"); + + if(g_codec_system_context.cur_user == NO_USER) { + printk("WARNING : Audiocodec not yet configured by any user\n"); + return (CODEC_OK); + } + else if(g_codec_system_context.cur_user != user) { + printk + ("ERROR : Trying to acces audiocodec already in use by user %d\n", g_codec_system_context.cur_user); + return CODEC_ERROR; + } + + if (g_codec_system_context.codec_direction != CODEC_DIRECTION_IN) + g_codec_system_context.play_sample_frequency = + play_sample_frequency; + else + play_sample_frequency = CODEC_SAMPLING_FREQ_8KHZ; + + if (g_codec_system_context.codec_direction != CODEC_DIRECTION_OUT) + g_codec_system_context.record_sample_frequency = + record_sample_frequency; + else + record_sample_frequency = CODEC_SAMPLING_FREQ_8KHZ; + + if (CODEC_DEVICE_INTERNAL_PLL_DONNOT_USE == + g_codec_system_context.codec_device_internal_pll) { + t_codec_stw5095_cr0_powerup codec_stw5095_cr0_powerup; + t_codec_configuration *p_codec_configuration = + &g_codec_system_context.codec_configuration; + + if (codec_convert_samplefrequency_to_numericvalue + (play_sample_frequency) >= 88000) + g_codec_system_context.codec_configuration.cr29_da96k = + CODEC_STW5095_CR29_DA96K_DATA_RATE_RANGE_88_TO_96KHZ; + else + g_codec_system_context.codec_configuration.cr29_da96k = + CODEC_STW5095_CR29_DA96K_DATA_RATE_RANGE_8_TO_48KHZ; + + if (codec_convert_samplefrequency_to_numericvalue + (record_sample_frequency) >= 88000) + g_codec_system_context.codec_configuration.cr29_ad96k = + CODEC_STW5095_CR29_AD96K_DATA_RATE_RANGE_88_TO_96KHZ; + else + g_codec_system_context.codec_configuration.cr29_ad96k = + CODEC_STW5095_CR29_AD96K_DATA_RATE_RANGE_8_TO_48KHZ; + + { + __u32 msp_input_frequency = 0; /* in KHz */ + __u32 serial_clock_divisor = 0; + __u32 align_value = 32; + + if (CODEC_MODE_HIFI == + g_codec_system_context.codec_mode_out) + align_value = 32; /* CTR */ + else + align_value = 256; + + /* Frequency acceptable within range of 12 - 16 MHz (CR30 - 2:0) */ + serial_clock_divisor = + 32000000 / + (codec_convert_samplefrequency_to_numericvalue + (play_sample_frequency) * align_value); + + msp_input_frequency = + ((codec_convert_samplefrequency_to_numericvalue + (play_sample_frequency)) * align_value * + serial_clock_divisor); + + p_codec_configuration->cr30_ckrange = + CODEC_STW5095_CR30_CKRANGE_4_TO_6_MHZ; + + if (msp_input_frequency >= 6000) + p_codec_configuration->cr30_ckrange = + CODEC_STW5095_CR30_CKRANGE_6_TO_8_MHZ; + + if (msp_input_frequency >= 8000) + p_codec_configuration->cr30_ckrange = + CODEC_STW5095_CR30_CKRANGE_8_TO_12_MHZ; + + if (msp_input_frequency >= 12000) + p_codec_configuration->cr30_ckrange = + CODEC_STW5095_CR30_CKRANGE_12_TO_16_MHZ; + + if (msp_input_frequency >= 16000) + p_codec_configuration->cr30_ckrange = + CODEC_STW5095_CR30_CKRANGE_16_TO_24_MHZ; + + if (msp_input_frequency >= 24000) + p_codec_configuration->cr30_ckrange = + CODEC_STW5095_CR30_CKRANGE_24_TO_32_MHZ; + + /* Workaound for STw5095 : Specs doesn't talk about function of resvered value but it rectifies the problem */ + if (CODEC_SAMPLING_FREQ_8KHZ == record_sample_frequency + && CODEC_MODE_HIFI == + g_codec_system_context.codec_mode_in) + p_codec_configuration->cr30_ckrange = + CODEC_STW5095_CR30_CKRANGE_RESERVED1; + + codec_stw5095_cr0_powerup = + p_codec_configuration->cr0_powerup; + + p_codec_configuration->cr0_powerup = + CODEC_STW5095_CR0_POWERUP_ON; /*nhk15 modification FIXME??*/ + + codec_error = codec_stw5095_update_cr0(); + if (CODEC_OK != codec_error) + return (codec_error); + + codec_error = codec_stw5095_update_cr30(); + + if (CODEC_OK != codec_error) + return (codec_error); + } + + codec_error = codec_stw5095_update_cr29(); + if (codec_error != CODEC_OK) + return (codec_error); + + p_codec_configuration->cr0_powerup = codec_stw5095_cr0_powerup; + + codec_error = codec_stw5095_update_cr0(); + if (CODEC_OK != codec_error) + return (codec_error); + + } else { + t_codec_stw5095_cr0_powerup codec_stw5095_cr0_powerup; + t_codec_configuration *p_codec_configuration = + &g_codec_system_context.codec_configuration; + + if (codec_convert_samplefrequency_to_numericvalue + (play_sample_frequency) >= 88000) + g_codec_system_context.codec_configuration.cr29_da96k = + CODEC_STW5095_CR29_DA96K_DATA_RATE_RANGE_88_TO_96KHZ; + else + g_codec_system_context.codec_configuration.cr29_da96k = + CODEC_STW5095_CR29_DA96K_DATA_RATE_RANGE_8_TO_48KHZ; + + if (codec_convert_samplefrequency_to_numericvalue + (record_sample_frequency) >= 88000) + g_codec_system_context.codec_configuration.cr29_ad96k = + CODEC_STW5095_CR29_AD96K_DATA_RATE_RANGE_88_TO_96KHZ; + else + g_codec_system_context.codec_configuration.cr29_ad96k = + CODEC_STW5095_CR29_AD96K_DATA_RATE_RANGE_8_TO_48KHZ; + + { +#ifdef CONFIG_DA_MASTER + __u32 kfs; + u32 pb_rate = + codec_convert_samplefrequency_to_numericvalue + (play_sample_frequency); + + // KFS = (rate * 2^25)/(AMCK * MCK_COEFF), where AMCK = 19,200,000 + // and MCK_COEFF = 2. A factor of 2^13 can be taken out of the + // calculation because it would overflow as is. + kfs = (pb_rate * 8192) / 9375; + p_codec_configuration->cr30_ckrange = + CODEC_STW5095_CR30_CKRANGE_16_TO_24_MHZ; +#else + __u32 msp_input_frequency = 0; /* in KHz */ + __u32 kfs; + __u32 mck_coeff; + __u32 align_value = 32; + + if (CODEC_MODE_HIFI == + g_codec_system_context.codec_mode_out) + align_value = 32; /* CTR */ + else + align_value = 256; + + msp_input_frequency = + (codec_convert_samplefrequency_to_numericvalue + (play_sample_frequency)) * align_value; + + p_codec_configuration->cr30_ckrange = + CODEC_STW5095_CR30_CKRANGE_4_TO_6_MHZ; + mck_coeff = 16; + + if (g_codec_system_context.codec_input_frequency >= + 6000) { + p_codec_configuration->cr30_ckrange = + CODEC_STW5095_CR30_CKRANGE_6_TO_8_MHZ; + mck_coeff = 12; + } + + if (g_codec_system_context.codec_input_frequency >= + 8000) { + p_codec_configuration->cr30_ckrange = + CODEC_STW5095_CR30_CKRANGE_8_TO_12_MHZ; + mck_coeff = 8; + } + + if (g_codec_system_context.codec_input_frequency >= + 12000) { + p_codec_configuration->cr30_ckrange = + CODEC_STW5095_CR30_CKRANGE_12_TO_16_MHZ; + mck_coeff = 6; + } + + if (g_codec_system_context.codec_input_frequency >= + 16000) { + p_codec_configuration->cr30_ckrange = + CODEC_STW5095_CR30_CKRANGE_16_TO_24_MHZ; + mck_coeff = 4; + } + + if (g_codec_system_context.codec_input_frequency >= + 24000) { + p_codec_configuration->cr30_ckrange = + CODEC_STW5095_CR30_CKRANGE_24_TO_32_MHZ; + mck_coeff = 3; + } +#endif + codec_stw5095_cr0_powerup = + p_codec_configuration->cr0_powerup; + + p_codec_configuration->cr0_powerup = + CODEC_STW5095_CR0_POWERUP_ON; /*nhk15 modification FIXME??*/ +#ifndef CONFIG_DA_MASTER + { + __u32 l_k_ock = msp_input_frequency; + __u32 ncount_readj = 0; + + //maximize l_k_ock + while (1) { + if (l_k_ock & 0x80000000) + break; + + l_k_ock <<= 1; + ncount_readj++; + } + + l_k_ock /= g_codec_system_context. + codec_input_frequency; + while (1) { + if (l_k_ock & 0x80000000) + break; + + l_k_ock <<= 1; + ncount_readj++; + } + + l_k_ock /= 1000; + while (1) { + if (l_k_ock & 0x80000000) + break; + + l_k_ock <<= 1; + ncount_readj++; + } + + l_k_ock /= mck_coeff; + + ncount_readj -= 18; + + while (ncount_readj--) + l_k_ock >>= 1; + + if (l_k_ock >= 0xffff) { + p_codec_configuration->cr22_daock512 = + CODEC_STW5095_CR22_DAOCK512_RATIO_IN_MASTER_MODE_512; + p_codec_configuration->cr25_adock512 = + CODEC_STW5095_CR25_ADOCK512_RATIO_IN_MASTER_MODE_512; + l_k_ock /= 2; + } else { + p_codec_configuration->cr22_daock512 = + CODEC_STW5095_CR22_DAOCK512_RATIO_IN_MASTER_MODE_256; + p_codec_configuration->cr25_adock512 = + CODEC_STW5095_CR25_ADOCK512_RATIO_IN_MASTER_MODE_256; + } + + kfs = l_k_ock; + } +#endif + p_codec_configuration->cr20_cr21_daockf = kfs; + + p_codec_configuration->cr23_cr24_adockf = kfs; + + p_codec_configuration->cr22_endaock = + CODEC_STW5095_CR22_ENDAOCK_ENABLED; + p_codec_configuration->cr25_endaock = + CODEC_STW5095_CR25_ENDAOCK_ENABLED; + + p_codec_configuration->cr22_damastgen = + CODEC_STW5095_CR22_DAMASTGEN_ENABLED; + p_codec_configuration->cr25_admastgen = + CODEC_STW5095_CR25_ADMASTGEN_ENABLED; + + codec_error = codec_stw5095_update_cr20_C21(); + if (CODEC_OK != codec_error) + return (codec_error); + + codec_error = codec_stw5095_update_cr23_C24(); + if (CODEC_OK != codec_error) + return (codec_error); + + codec_error = codec_stw5095_update_cr22(); + if (CODEC_OK != codec_error) + return (codec_error); + + codec_error = codec_stw5095_update_cr25(); + if (CODEC_OK != codec_error) + return (codec_error); + + codec_error = codec_stw5095_update_cr0(); + if (CODEC_OK != codec_error) + return (codec_error); + + codec_error = codec_stw5095_update_cr30(); + + if (CODEC_OK != codec_error) + return (codec_error); + } + + codec_error = codec_stw5095_update_cr29(); + if (codec_error != CODEC_OK) + return (codec_error); + + p_codec_configuration->cr0_powerup = codec_stw5095_cr0_powerup; + + codec_error = codec_stw5095_update_cr0(); + if (CODEC_OK != codec_error) + return (codec_error); + } + + DEBUG(1, " leaving nomadik_acodec_set_frequency()\n"); + return CODEC_OK; +} + +/** + * nomadik_acodec_get_currentsettings + * + * This routine returns the codec_configuration structure + */ + +t_codec_error nomadik_acodec_get_currentsettings(codec_configuration * + codec_conf, t_acodec_user user) +{ + DEBUG(1, " Entering nomadik_acodec_get_currentsettings()\n"); + DEBUG(1, " leaving nomadik_acodec_get_currentsettings()\n"); + return (CODEC_OK); +} + +/** + * nomadik_acodec_set_currentsettings + * + * This routine sets the codec_configuration structure + */ + +t_codec_error nomadik_acodec_set_currentsettings(codec_configuration * + codec_conf, t_acodec_user user) +{ + DEBUG(1, " Entering nomadik_acodec_set_currentsettings()\n"); + DEBUG(1, " leaving nomadik_acodec_set_currentsettings()\n"); + return CODEC_OK; +} + +/** + * nomadik_acodec_reset + * + * Reset the global variables and clear audiocodec settings to default. + */ + +t_codec_error nomadik_acodec_reset(void) +{ + t_codec_error codec_error = CODEC_OK; + t_codec_configuration *p_codec_configuration; + + g_codec_system_context.codec_direction = CODEC_DEFAULT_DIRECTION; + g_codec_system_context.codec_mode_in = CODEC_DEFAULT_MODE_IN; + g_codec_system_context.codec_mode_out = CODEC_DEFAULT_MODE_OUT; + + g_codec_system_context.record_sample_frequency = + CODEC_DEFAULT_RECORD_SAMPLE_FREQUENCY; + g_codec_system_context.play_sample_frequency = + CODEC_DEFAULT_PLAY_SAMPLE_FREQUENCY; + + g_codec_system_context.codec_src = CODEC_DEFAULT_INPUT_SRC; + g_codec_system_context.codec_dest = CODEC_DEFAULT_OUTPUT_DEST; + + g_codec_system_context.in_left_volume = CODEC_DEFAULT_VOLUME_LEFT_IN; + g_codec_system_context.in_right_volume = CODEC_DEFAULT_VOLUME_RIGHT_IN; + g_codec_system_context.out_left_volume = CODEC_DEFAULT_VOLUME_LEFT_OUT; + g_codec_system_context.out_right_volume = + CODEC_DEFAULT_VOLUME_RIGHT_OUT; + + p_codec_configuration = &g_codec_system_context.codec_configuration; + + codec_error = codec_stw5095_reset(); + return (codec_error); +} + +/** + * nomadik_acodec_set_user + * + * Set the current user for acodec. + */ + +t_codec_error nomadik_acodec_setuser(t_acodec_user user) +{ + t_codec_error codec_error = CODEC_OK; + + if((g_codec_system_context.cur_user == NO_USER) || (g_codec_system_context.cur_user == user)){ + g_codec_system_context.cur_user = user; + nomadik_acodec_powerup(); + } + else { + printk + ("ERROR : Trying to acces audiocodec already in use by user %d\n", g_codec_system_context.cur_user); + return CODEC_ERROR; + } + + return (codec_error); +} + +/** + * nomadik_acodec_unset_user + * + * Unset the current user for acodec. + */ + +t_codec_error nomadik_acodec_unsetuser(t_acodec_user user) +{ + t_codec_error codec_error = CODEC_OK; + + if(g_codec_system_context.cur_user != user){ + printk + ("ERROR : Trying to free audiocodec already in use by other user %d\n", g_codec_system_context.cur_user); + return CODEC_ERROR; + } + else { + g_codec_system_context.cur_user = NO_USER; + nomadik_acodec_powerdown(0); + } + + return (codec_error); +} + +#if defined(CONFIG_STMPE_NOMADIK) +static void codec_callback_mic(void *user) +{ + int err,codec_error; + t_acodec_user m; + uint8 byte_value_test; + m = (t_acodec_user) user; + //printk("\n*MiC IS Call back is called\n"); + err = STMPE2401_GetGpioVal(STMPE0,EGPIO_PIN_6,&byte_value_test); + switch(byte_value_test) + { + case 0: + codec_error = nomadik_acodec_select_output(CODEC_SOURCE_MICROPHONE,m); + if (CODEC_OK != codec_error) { + printk("AUDIOCODEC: ERROR: select output failed\n"); + } + + break; + default: + break; + } +} +/* callback function for the audio codec - headset and loud speakers switching + */ +static void codec_callback1(void *user) +{ + int err,codec_error; + uint8 byte_value; + t_acodec_user t; + t = (t_acodec_user) user; + err = STMPE2401_GetGpioVal(STMPE0,EGPIO_PIN_7,&byte_value); + switch(byte_value) { + + case 0: + err = STMPE2401_SetGpioAltFunction(STMPE0,EGPIO_PIN_12,STMPE2401_PRIMARY_FUNCTION); + if (err != STMPE2401_OK) + printk("Couldn't set STMPE%d %d as primary function\n",STMPE1,EGPIO_PIN_12); + err = STMPE2401_SetGpioDir( STMPE0,EGPIO_PIN_12,STMPE2401_GPIO_OUT ); + if (err != STMPE2401_OK) + printk("Couldn't set STMPE EGPIO:%d in Output direction\n", EGPIO_PIN_12); + err = STMPE2401_SetGpioVal( STMPE0, EGPIO_PIN_12, 1); + if (err != STMPE2401_OK) + printk("Couldn't set STMPE GPIO12\n"); + + /*route the codec output via amplifiers*/ + codec_error = nomadik_acodec_select_output(CODEC_DEST_LOUDSPEAKER,t); + if (CODEC_OK != codec_error) { + printk("AUDIOCODEC: ERROR: select output failed\n"); + //return CODEC_ERROR; + } + break; + case 1: + /*disable the amplifiers to save power*/ + err = STMPE2401_SetGpioAltFunction(STMPE0,EGPIO_PIN_12,STMPE2401_PRIMARY_FUNCTION); + if (err != STMPE2401_OK) + printk("Couldn't set STMPE%d %d as primary function\n",STMPE1,EGPIO_PIN_12); + err = STMPE2401_SetGpioDir( STMPE0,EGPIO_PIN_12,STMPE2401_GPIO_OUT ); + if (err != STMPE2401_OK) + printk("Couldn't set STMPE EGPIO:%d in Output direction\n", EGPIO_PIN_12); + err = STMPE2401_SetGpioVal( STMPE0, EGPIO_PIN_12, 0); + if (err != STMPE2401_OK) + printk("Couldn't set STMPE GPIO12\n"); + + /*route the codec output to headset*/ + codec_error = nomadik_acodec_select_output(CODEC_DEST_HEADPHONE,t); + if (CODEC_OK != codec_error) { + printk("AUDIOCODEC: ERROR: select output failed\n"); + //return CODEC_ERROR; + } + break; + } +} +/*initialize the 5095 codec's amplifier */ +void codec_hd_amp_init(t_acodec_user user) +{ + int err = 0; + /*enable the amplifier*/ + err = STMPE2401_SetGpioAltFunction(STMPE0,EGPIO_PIN_12,STMPE2401_PRIMARY_FUNCTION); + if (err != STMPE2401_OK) + printk("Couldn't set STMPE%d %d as primary function\n",STMPE1,EGPIO_PIN_12); + err = STMPE2401_SetGpioDir( STMPE0,EGPIO_PIN_12,STMPE2401_GPIO_OUT ); + if (err != STMPE2401_OK) + printk("Couldn't set STMPE EGPIO:%d in Output direction\n", EGPIO_PIN_12); + err = STMPE2401_SetGpioVal( STMPE0, EGPIO_PIN_12, 1); + if (err != STMPE2401_OK) + printk("Couldn't set STMPE GPIO12\n"); + + /**/ + err = STMPE2401_SetGpioAltFunction(STMPE0,EGPIO_PIN_7,STMPE2401_PRIMARY_FUNCTION); + if (err != STMPE2401_OK) + printk("Couldn't set STMPE0 %d as primary function\n",EGPIO_PIN_7); + + err = STMPE2401_SetGpioDir(STMPE0,EGPIO_PIN_7,STMPE2401_GPIO_IN); + if (err != STMPE2401_OK) + printk("Couldn't set STMPE0 %d as GPIO direction \n",EGPIO_PIN_7); + + /*install the call back handler*/ + err = STMPE2401_Install_Callback(STMPE0, EGPIO_PIN_7 ,codec_callback1,(void*)user); + if (err != STMPE2401_OK) + { + printk("Couldn't setup codec callback\n"); + } + err = STMPE2401_SetGpioEdgeDetect(STMPE0, EGPIO_PIN_7, STMPE2401_BOTH_EDGE); + if (err != STMPE2401_OK) + printk("error in seetting the GPIO edge.\n"); + + err = STMPE2401_ClearGpioEdgeStatus( STMPE0,(0x1<